From 5e601d04015cc5c502053468535f5ac4116cfaa2 Mon Sep 17 00:00:00 2001 From: Yaossg Date: Sat, 18 Jan 2025 21:09:52 +0800 Subject: [PATCH] initial commit --- .gitattributes | 1 + .gitignore | 48 + AUTHORS | 29 + HISAT2-genotype.png | Bin 0 -> 741543 bytes HISAT2_VERSION | 1 + LICENSE | 674 + MANUAL | 1467 ++ MANUAL.markdown | 2437 +++ Makefile | 590 + NEWS | 16 + README.md | 247 + TUTORIAL | 4 + _config.yml | 1 + aligner_bt.cpp | 1772 ++ aligner_bt.h | 947 + aligner_cache.cpp | 181 + aligner_cache.h | 1013 + aligner_driver.cpp | 80 + aligner_driver.h | 247 + aligner_metrics.h | 352 + aligner_report.h | 35 + aligner_result.cpp | 2162 ++ aligner_result.h | 2325 +++ aligner_seed.cpp | 530 + aligner_seed.h | 2922 +++ aligner_seed2.cpp | 1245 ++ aligner_seed2.h | 4291 ++++ aligner_seed_policy.cpp | 916 + aligner_seed_policy.h | 234 + aligner_sw.cpp | 3214 +++ aligner_sw.h | 648 + aligner_sw_common.h | 305 + aligner_sw_driver.cpp | 20 + aligner_sw_driver.h | 2938 +++ aligner_sw_nuc.h | 262 + aligner_swsse.cpp | 88 + aligner_swsse.h | 500 + aligner_swsse_ee_i16.cpp | 1911 ++ aligner_swsse_ee_u8.cpp | 1902 ++ aligner_swsse_loc_i16.cpp | 2272 +++ aligner_swsse_loc_u8.cpp | 2266 +++ alignment_3n.cpp | 193 + alignment_3n.h | 1214 ++ alignment_3n_table.h | 287 + aln_sink.cpp | 785 + aln_sink.h | 4384 ++++ alphabet.cpp | 536 + alphabet.h | 199 + alt.h | 294 + assert_helpers.h | 279 + banded.cpp | 27 + banded.h | 52 + binary_sa_search.h | 102 + bit_packed_array.cpp | 315 + bit_packed_array.h | 105 + bitpack.h | 80 + blockwise_sa.h | 1113 ++ bp_aligner.h | 1237 ++ btypes.h | 48 + ccnt_lut.cpp | 80 + diff_sample.cpp | 117 + diff_sample.h | 1000 + docs/404.html | 9 + docs/Gemfile | 4 + docs/LICENSE | 21 + docs/README.md | 59 + docs/_config.yml | 130 + docs/_data/collaborate.yml | 6 + docs/_data/contributor.yml | 10 + docs/_data/download-binary.yml | 66 + docs/_data/download-index.yml | 81 + docs/_includes/article-footer.html | 5 + docs/_includes/article-header.html | 64 + docs/_includes/disqus.html | 10 + docs/_includes/fb-root.html | 11 + docs/_includes/google-analytics.html | 12 + docs/_includes/icons.html | 161 + docs/_includes/page-url-resolver.html | 7 + docs/_includes/paginator.html | 29 + docs/_includes/share-buttons.html | 22 + docs/_layouts/default.html | 194 + docs/_layouts/page.html | 13 + docs/_layouts/post.html | 19 + docs/_pages/about.md | 9 + docs/_pages/archives-all.html | 20 + docs/_pages/archives.html | 35 + docs/_pages/contributors/chanheepark.md | 12 + docs/_pages/contributors/yunleozhang.md | 12 + docs/_pages/download.md | 61 + docs/_pages/hisat-3n.md | 225 + docs/_pages/hisat2.md | 135 + docs/_pages/howto.md | 78 + docs/_pages/links.md | 17 + docs/_pages/manual.md | 1545 ++ docs/_pages/search.html | 26 + docs/_pages/tags.html | 14 + docs/_posts/2000-01-01-kim.md | 13 + docs/_posts/2000-01-02-salzberg.md | 11 + docs/_posts/2000-01-03-langmead.md | 13 + docs/_posts/2019-07-28-park.md | 10 + docs/_sass/_aside.scss | 66 + docs/_sass/_common.scss | 43 + docs/_sass/_content.scss | 203 + docs/_sass/_footer.scss | 7 + docs/_sass/_header.scss | 47 + docs/_sass/base/_layout.scss | 62 + docs/_sass/base/_reset.scss | 427 + docs/_sass/base/_syntax.scss | 63 + docs/_sass/base/_utilities.scss | 39 + docs/_sass/base/_variables.scss | 24 + docs/assets/css/style.scss | 13 + .../data/HISAT2-first_release-Sept_8_2015.pdf | Bin 0 -> 1950832 bytes docs/assets/img/bioinformatics_utsw_logo.png | Bin 0 -> 30095 bytes docs/assets/img/ccb_jhu_logo_tmp.png | Bin 0 -> 13531 bytes docs/assets/img/ogp.png | Bin 0 -> 312577 bytes docs/assets/js/header-link.js | 8 + docs/assets/js/script.js | 34 + docs/assets/js/search.js | 108 + .../assets/lib/garand-sticky/jquery.sticky.js | 172 + docs/favicon.ico | Bin 0 -> 6518 bytes docs/index.html | 14 + docs/search.json | 16 + docs_jhu/README | 4 + docs_jhu/add.css | 57 + docs_jhu/faq.shtml | 45 + docs_jhu/footer.inc.html | 7 + docs_jhu/index.html | 9 + docs_jhu/index.shtml | 154 + docs_jhu/indexes.txt | 5 + docs_jhu/manual.inc.html | 1262 ++ docs_jhu/manual.shtml | 37 + docs_jhu/sidebar.inc.shtml | 409 + docs_jhu/strip_markdown.pl | 45 + docs_jhu/style.css | 306 + dp_framer.cpp | 910 + dp_framer.h | 261 + ds.cpp | 155 + ds.h | 4397 ++++ edit.cpp | 501 + edit.h | 401 + endian_swap.h | 160 + evaluation/build_indexes.py | 58 + evaluation/generate_reads.py | 162 + evaluation/get_data.py | 102 + evaluation/get_programs.py | 130 + evaluation/real/calculate_read_cost.py | 1675 ++ evaluation/real/init.py | 98 + evaluation/simulation/calculate_read_cost.py | 2834 +++ evaluation/simulation/init.py | 343 + evaluation/tests/CODIS/README | 21 + evaluation/tests/CODIS/genome.fa | 1 + evaluation/tests/CODIS/genome.fa.fai | 1 + evaluation/tests/CODIS/grch38 | 1 + .../CODIS/hisatgenotype_convert_codis.py | 1 + .../CODIS/hisatgenotype_extract_codis_data.py | 1 + .../tests/CODIS/hisatgenotype_extract_vars.py | 1 + evaluation/tests/CODIS/hisatgenotype_locus.py | 1 + evaluation/tests/CODIS/hisatgenotype_modules | 1 + .../tests/CYP/hisatgenotype_extract_vars.py | 1 + evaluation/tests/CYP/hisatgenotype_locus.py | 1 + .../tests/HLA_novel/ILMN_StrandSeq/README | 1 + .../HLA_novel/ILMN_StrandSeq/SraRunInfo.txt | 1 + .../HLA_novel/ILMN_StrandSeq_original/README | 8 + .../ILMN_StrandSeq_original/SraRunInfo.txt | 305 + evaluation/tests/HLA_novel/README | 20 + evaluation/tests/HLA_novel/hisatgenotype.py | 1 + .../HLA_novel/hisatgenotype_build_genome.py | 1 + .../HLA_novel/hisatgenotype_extract_vars.py | 1 + .../tests/HLA_novel/hisatgenotype_locus.py | 1 + .../HLA_novel/hisatgenotype_locus_prev.py | 3210 +++ .../tests/HLA_novel/hisatgenotype_modules | 1 + .../scripts/run_extract_ILMN_HiSeqX.sh | 11 + .../tests/genotype_genome/hisatgenotype.py | 1 + .../hisatgenotype_build_genome.py | 1 + .../hisatgenotype_extract_vars.py | 1 + .../genotype_genome/hisatgenotype_locus.py | 1 + .../genotype_genome/hisatgenotype_modules | 1 + .../genotype_genome/hisatgenotype_prev.py | 1052 + .../paper_sensitivity/sensitivity.py | 140 + .../one_snp_test/evaluate_one_snp_reads.py | 232 + .../one_snp_test/simulate_one_snp_reads.py | 392 + evaluation/tests/repeat/commands | 64 + evaluation/tests/repeat/generate_repeats.py | 212 + evaluation/tests/repeat/test_repeat.py | 131 + evaluation/tests/the_small_example/COMMAND | 2 + evaluation/tests/the_small_example/small.fa | 2 + evaluation/tests/the_small_example/small.snp | 3 + example/index/22_20-21M_snp.1.ht2 | Bin 0 -> 4789374 bytes example/index/22_20-21M_snp.2.ht2 | Bin 0 -> 238700 bytes example/index/22_20-21M_snp.3.ht2 | Bin 0 -> 26 bytes example/index/22_20-21M_snp.4.ht2 | Bin 0 -> 225000 bytes example/index/22_20-21M_snp.5.ht2 | Bin 0 -> 678405 bytes example/index/22_20-21M_snp.6.ht2 | Bin 0 -> 238590 bytes example/index/22_20-21M_snp.7.ht2 | Bin 0 -> 70048 bytes example/index/22_20-21M_snp.8.ht2 | Bin 0 -> 37688 bytes example/reads/reads_1.fa | 2000 ++ example/reads/reads_2.fa | 2000 ++ example/reference/22_20-21M.fa | 16668 ++++++++++++++++ example/reference/22_20-21M.snp | 3502 ++++ extract_exons.py | 1 + extract_splice_sites.py | 1 + fast_mutex.h | 294 + filebuf.h | 718 + formats.h | 57 + gbwt_graph.h | 2797 +++ gfm.cpp | 72 + gfm.h | 6980 +++++++ gp.h | 83 + group_walk.cpp | 20 + group_walk.h | 1624 ++ hgfm.h | 2655 +++ hi_aligner.h | 7006 +++++++ hier_idx_common.h | 43 + hisat-3n | 782 + hisat-3n-build | 148 + hisat2 | 665 + hisat2-build | 95 + hisat2-build-new | 100 + hisat2-inspect | 73 + hisat2.cpp | 4978 +++++ hisat2.sln | 82 + hisat2.xcodeproj/project.pbxproj | 1307 ++ hisat2_build.cpp | 970 + hisat2_build_main.cpp | 70 + hisat2_extract_exons.py | 159 + hisat2_extract_snps_haplotypes_UCSC.py | 578 + hisat2_extract_snps_haplotypes_VCF.py | 923 + hisat2_extract_splice_sites.py | 137 + hisat2_inspect.cpp | 791 + hisat2_main.cpp | 69 + hisat2_read_statistics.py | 236 + hisat2_repeat.cpp | 996 + hisat2_repeat_main.cpp | 70 + hisat2_simulate_reads.py | 971 + hisat2lib/ht2.h | 162 + hisat2lib/ht2_alignment.cpp | 20 + hisat2lib/ht2_handle.h | 47 + hisat2lib/ht2_index.cpp | 80 + hisat2lib/ht2_init.cpp | 248 + hisat2lib/ht2_repeat.cpp | 103 + hisat2lib/java_jni/HT2Module.java | 122 + hisat2lib/java_jni/HT2ModuleExample.java | 82 + hisat2lib/java_jni/Makefile | 72 + hisat2lib/java_jni/ht2module.c | 432 + hisat2lib/pymodule/Makefile | 33 + hisat2lib/pymodule/ht2example.py | 68 + hisat2lib/pymodule/ht2module.c | 333 + hisat2lib/pymodule/setup.py | 33 + hisat_3n_table.cpp | 382 + hisat_bp.cpp | 3885 ++++ ival_list.cpp | 165 + ival_list.h | 299 + li_hla/Makefile | 16 + li_hla/alignments.hpp | 276 + li_hla/defs.h | 19 + li_hla/main.cpp | 484 + limit.cpp | 43 + limit.h | 48 + ls.cpp | 142 + ls.h | 333 + mask.cpp | 36 + mask.h | 79 + mem_ids.h | 35 + mm.h | 51 + msvcc/CodeStubs.vcxproj.filters | 42 + msvcc/CoreDefs.props | 13 + msvcc/SetVersion.vbs | 14 + msvcc/SysDefs.props | 17 + msvcc/codeStubs.vcxproj | 105 + msvcc/codeStubs/getopt.c | 1058 + msvcc/codeStubs/getopt.h | 154 + msvcc/codeStubs/getopt1.c | 180 + msvcc/codeStubs/sys/time.cpp | 57 + msvcc/codeStubs/sys/time.h | 15 + msvcc/codeStubs/unistd.h | 0 msvcc/hisat2-align-l.vcxproj | 121 + msvcc/hisat2-align-l.vcxproj.filters | 25 + msvcc/hisat2-align-s.vcxproj | 124 + msvcc/hisat2-align-s.vcxproj.filters | 25 + msvcc/hisat2-build-l.vcxproj | 119 + msvcc/hisat2-build-l.vcxproj.filters | 28 + msvcc/hisat2-build-s.vcxproj | 122 + msvcc/hisat2-build-s.vcxproj.filters | 28 + msvcc/hisat2-inspect-l.vcxproj | 95 + msvcc/hisat2-inspect-l.vcxproj.filters | 22 + msvcc/hisat2-inspect-s.vcxproj | 95 + msvcc/hisat2-inspect-s.vcxproj.filters | 22 + msvcc/search.vcxproj | 194 + msvcc/search.vcxproj.filters | 336 + msvcc/search64.vcxproj | 196 + msvcc/search64.vcxproj.filters | 348 + msvcc/shared.vcxproj | 142 + msvcc/shared.vcxproj.filters | 111 + msvcc/shared64.vcxproj | 137 + msvcc/shared64.vcxproj.filters | 96 + multikey_qsort.cpp | 20 + multikey_qsort.h | 1237 ++ opts.h | 200 + outq.cpp | 201 + outq.h | 149 + pat.cpp | 1824 ++ pat.h | 1800 ++ pe.cpp | 941 + pe.h | 321 + position_3n.cpp | 393 + position_3n.h | 358 + position_3n_table.h | 549 + presets.cpp | 87 + presets.h | 67 + processor_support.h | 73 + qual.cpp | 85 + qual.h | 236 + radix_sort.h | 297 + random_source.cpp | 128 + random_source.h | 239 + random_util.cpp | 24 + random_util.h | 221 + read.h | 599 + read_qseq.cpp | 304 + ref_coord.cpp | 33 + ref_coord.h | 429 + ref_read.cpp | 454 + ref_read.h | 325 + reference.cpp | 722 + reference.h | 196 + repeat.h | 627 + repeat_builder.cpp | 4771 +++++ repeat_builder.h | 964 + repeat_kmer.h | 606 + rfm.h | 1136 ++ sam.h | 2013 ++ scoring.cpp | 286 + scoring.h | 546 + scripts/convert_quals.pl | 133 + scripts/gen_2b_occ_lookup.pl | 106 + scripts/gen_occ_lookup.pl | 257 + scripts/gen_solqual_lookup.pl | 80 + scripts/infer_fraglen.pl | 132 + scripts/make_a_thaliana_tair.sh | 56 + scripts/make_b_taurus_UMD3.sh | 89 + scripts/make_bdgp6.sh | 60 + scripts/make_bdgp6_tran.sh | 89 + scripts/make_canFam2.sh | 61 + scripts/make_ce10.sh | 43 + scripts/make_dm6.sh | 50 + scripts/make_e_coli.sh | 46 + scripts/make_grch37.sh | 60 + scripts/make_grch37_snp.sh | 83 + scripts/make_grch37_snp_tran.sh | 112 + scripts/make_grch37_snp_tran_ercc.sh | 117 + scripts/make_grch37_tran.sh | 89 + scripts/make_grch38.sh | 60 + scripts/make_grch38_rep.sh | 76 + scripts/make_grch38_snp.sh | 83 + scripts/make_grch38_snp_rep.sh | 99 + scripts/make_grch38_snp_tran.sh | 112 + scripts/make_grch38_snp_tran_ercc.sh | 117 + scripts/make_grch38_tran.sh | 89 + scripts/make_grcm38.sh | 55 + scripts/make_grcm38_snp.sh | 78 + scripts/make_grcm38_snp_tran.sh | 107 + scripts/make_grcm38_tran.sh | 85 + scripts/make_hg19.sh | 54 + scripts/make_hg38.sh | 54 + scripts/make_hg38_allsnp.sh | 75 + scripts/make_hg38_snp.sh | 75 + scripts/make_hg38_snp_tran.sh | 54 + scripts/make_mm10.sh | 54 + scripts/make_mm9.sh | 103 + scripts/make_r64.sh | 60 + scripts/make_r64_tran.sh | 89 + scripts/make_rn4.sh | 96 + scripts/make_rn6.sh | 57 + scripts/make_rnor6.sh | 60 + scripts/make_rnor6_tran.sh | 89 + scripts/make_sc3.sh | 42 + scripts/make_wbcel235.sh | 60 + scripts/make_wbcel235_tran.sh | 89 + scripts/make_zm3_snp_tran_ercc.sh | 110 + scripts/sa.py | 79 + scripts/sim/AlignmentCheck.pm | 859 + scripts/sim/DNA.pm | 287 + scripts/sim/Mutate.pm | 301 + scripts/sim/RandDNA.pm | 191 + scripts/sim/SampleRead.pm | 244 + scripts/sim/Sim.pm | 1052 + scripts/sim/Test.pm | 47 + scripts/sim/contrib/ForkManager.pm | 412 + scripts/sim/run.pl | 135 + scripts/sim/run.sh | 31 + scripts/sim/unit.sh | 23 + scripts/test/DNA.pm | 129 + scripts/test/Read.pm | 178 + scripts/test/args.pl | 134 + scripts/test/simple_tests.pl | 4805 +++++ scripts/test/simple_tests.sh | 27 + scripts/validate_repeat.py | 230 + search_globals.h | 48 + sequence_io.h | 125 + shmem.cpp | 49 + shmem.h | 161 + simple_func.cpp | 93 + simple_func.h | 125 + splice_site.cpp | 850 + splice_site.h | 615 + splice_site_mem.h | 6224 ++++++ splice_site_new.cpp | 1157 ++ spliced_aligner.h | 2054 ++ sse_util.cpp | 33 + sse_util.h | 574 + sstring.cpp | 202 + sstring.h | 3454 ++++ str_util.h | 47 + third_party/cpuid.h | 187 + threading.h | 57 + timer.h | 87 + tinythread.cpp | 320 + tinythread.h | 714 + tokenize.h | 62 + tp.h | 118 + unique.cpp | 66 + unique.h | 531 + util.h | 53 + utility_3n.cpp | 80 + utility_3n.h | 113 + utility_3n_table.h | 327 + word_io.h | 393 + zbox.h | 97 + 428 files changed, 206785 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 HISAT2-genotype.png create mode 100644 HISAT2_VERSION create mode 100644 LICENSE create mode 100644 MANUAL create mode 100644 MANUAL.markdown create mode 100644 Makefile create mode 100644 NEWS create mode 100644 README.md create mode 100644 TUTORIAL create mode 100644 _config.yml create mode 100644 aligner_bt.cpp create mode 100644 aligner_bt.h create mode 100644 aligner_cache.cpp create mode 100644 aligner_cache.h create mode 100644 aligner_driver.cpp create mode 100644 aligner_driver.h create mode 100644 aligner_metrics.h create mode 100644 aligner_report.h create mode 100644 aligner_result.cpp create mode 100644 aligner_result.h create mode 100644 aligner_seed.cpp create mode 100644 aligner_seed.h create mode 100644 aligner_seed2.cpp create mode 100644 aligner_seed2.h create mode 100644 aligner_seed_policy.cpp create mode 100644 aligner_seed_policy.h create mode 100644 aligner_sw.cpp create mode 100644 aligner_sw.h create mode 100644 aligner_sw_common.h create mode 100644 aligner_sw_driver.cpp create mode 100644 aligner_sw_driver.h create mode 100644 aligner_sw_nuc.h create mode 100644 aligner_swsse.cpp create mode 100644 aligner_swsse.h create mode 100644 aligner_swsse_ee_i16.cpp create mode 100644 aligner_swsse_ee_u8.cpp create mode 100644 aligner_swsse_loc_i16.cpp create mode 100644 aligner_swsse_loc_u8.cpp create mode 100644 alignment_3n.cpp create mode 100644 alignment_3n.h create mode 100644 alignment_3n_table.h create mode 100644 aln_sink.cpp create mode 100644 aln_sink.h create mode 100644 alphabet.cpp create mode 100644 alphabet.h create mode 100644 alt.h create mode 100644 assert_helpers.h create mode 100644 banded.cpp create mode 100644 banded.h create mode 100644 binary_sa_search.h create mode 100644 bit_packed_array.cpp create mode 100644 bit_packed_array.h create mode 100644 bitpack.h create mode 100644 blockwise_sa.h create mode 100644 bp_aligner.h create mode 100644 btypes.h create mode 100644 ccnt_lut.cpp create mode 100644 diff_sample.cpp create mode 100644 diff_sample.h create mode 100644 docs/404.html create mode 100644 docs/Gemfile create mode 100644 docs/LICENSE create mode 100644 docs/README.md create mode 100644 docs/_config.yml create mode 100644 docs/_data/collaborate.yml create mode 100644 docs/_data/contributor.yml create mode 100644 docs/_data/download-binary.yml create mode 100644 docs/_data/download-index.yml create mode 100644 docs/_includes/article-footer.html create mode 100644 docs/_includes/article-header.html create mode 100644 docs/_includes/disqus.html create mode 100644 docs/_includes/fb-root.html create mode 100644 docs/_includes/google-analytics.html create mode 100644 docs/_includes/icons.html create mode 100644 docs/_includes/page-url-resolver.html create mode 100644 docs/_includes/paginator.html create mode 100644 docs/_includes/share-buttons.html create mode 100644 docs/_layouts/default.html create mode 100644 docs/_layouts/page.html create mode 100644 docs/_layouts/post.html create mode 100644 docs/_pages/about.md create mode 100644 docs/_pages/archives-all.html create mode 100644 docs/_pages/archives.html create mode 100644 docs/_pages/contributors/chanheepark.md create mode 100644 docs/_pages/contributors/yunleozhang.md create mode 100644 docs/_pages/download.md create mode 100644 docs/_pages/hisat-3n.md create mode 100644 docs/_pages/hisat2.md create mode 100644 docs/_pages/howto.md create mode 100644 docs/_pages/links.md create mode 100644 docs/_pages/manual.md create mode 100644 docs/_pages/search.html create mode 100644 docs/_pages/tags.html create mode 100644 docs/_posts/2000-01-01-kim.md create mode 100644 docs/_posts/2000-01-02-salzberg.md create mode 100644 docs/_posts/2000-01-03-langmead.md create mode 100644 docs/_posts/2019-07-28-park.md create mode 100644 docs/_sass/_aside.scss create mode 100644 docs/_sass/_common.scss create mode 100644 docs/_sass/_content.scss create mode 100644 docs/_sass/_footer.scss create mode 100644 docs/_sass/_header.scss create mode 100644 docs/_sass/base/_layout.scss create mode 100644 docs/_sass/base/_reset.scss create mode 100644 docs/_sass/base/_syntax.scss create mode 100644 docs/_sass/base/_utilities.scss create mode 100644 docs/_sass/base/_variables.scss create mode 100644 docs/assets/css/style.scss create mode 100644 docs/assets/data/HISAT2-first_release-Sept_8_2015.pdf create mode 100644 docs/assets/img/bioinformatics_utsw_logo.png create mode 100644 docs/assets/img/ccb_jhu_logo_tmp.png create mode 100644 docs/assets/img/ogp.png create mode 100644 docs/assets/js/header-link.js create mode 100644 docs/assets/js/script.js create mode 100644 docs/assets/js/search.js create mode 100644 docs/assets/lib/garand-sticky/jquery.sticky.js create mode 100644 docs/favicon.ico create mode 100644 docs/index.html create mode 100644 docs/search.json create mode 100644 docs_jhu/README create mode 100644 docs_jhu/add.css create mode 100644 docs_jhu/faq.shtml create mode 100644 docs_jhu/footer.inc.html create mode 100644 docs_jhu/index.html create mode 100644 docs_jhu/index.shtml create mode 100644 docs_jhu/indexes.txt create mode 100644 docs_jhu/manual.inc.html create mode 100644 docs_jhu/manual.shtml create mode 100644 docs_jhu/sidebar.inc.shtml create mode 100644 docs_jhu/strip_markdown.pl create mode 100644 docs_jhu/style.css create mode 100644 dp_framer.cpp create mode 100644 dp_framer.h create mode 100644 ds.cpp create mode 100644 ds.h create mode 100644 edit.cpp create mode 100644 edit.h create mode 100644 endian_swap.h create mode 100644 evaluation/build_indexes.py create mode 100644 evaluation/generate_reads.py create mode 100644 evaluation/get_data.py create mode 100644 evaluation/get_programs.py create mode 100644 evaluation/real/calculate_read_cost.py create mode 100644 evaluation/real/init.py create mode 100644 evaluation/simulation/calculate_read_cost.py create mode 100644 evaluation/simulation/init.py create mode 100644 evaluation/tests/CODIS/README create mode 100644 evaluation/tests/CODIS/genome.fa create mode 100644 evaluation/tests/CODIS/genome.fa.fai create mode 100644 evaluation/tests/CODIS/grch38 create mode 100644 evaluation/tests/CODIS/hisatgenotype_convert_codis.py create mode 100644 evaluation/tests/CODIS/hisatgenotype_extract_codis_data.py create mode 100644 evaluation/tests/CODIS/hisatgenotype_extract_vars.py create mode 100644 evaluation/tests/CODIS/hisatgenotype_locus.py create mode 100644 evaluation/tests/CODIS/hisatgenotype_modules create mode 100644 evaluation/tests/CYP/hisatgenotype_extract_vars.py create mode 100644 evaluation/tests/CYP/hisatgenotype_locus.py create mode 100644 evaluation/tests/HLA_novel/ILMN_StrandSeq/README create mode 100644 evaluation/tests/HLA_novel/ILMN_StrandSeq/SraRunInfo.txt create mode 100644 evaluation/tests/HLA_novel/ILMN_StrandSeq_original/README create mode 100644 evaluation/tests/HLA_novel/ILMN_StrandSeq_original/SraRunInfo.txt create mode 100644 evaluation/tests/HLA_novel/README create mode 100644 evaluation/tests/HLA_novel/hisatgenotype.py create mode 100644 evaluation/tests/HLA_novel/hisatgenotype_build_genome.py create mode 100644 evaluation/tests/HLA_novel/hisatgenotype_extract_vars.py create mode 100644 evaluation/tests/HLA_novel/hisatgenotype_locus.py create mode 100644 evaluation/tests/HLA_novel/hisatgenotype_locus_prev.py create mode 100644 evaluation/tests/HLA_novel/hisatgenotype_modules create mode 100644 evaluation/tests/HLA_novel/scripts/run_extract_ILMN_HiSeqX.sh create mode 100644 evaluation/tests/genotype_genome/hisatgenotype.py create mode 100644 evaluation/tests/genotype_genome/hisatgenotype_build_genome.py create mode 100644 evaluation/tests/genotype_genome/hisatgenotype_extract_vars.py create mode 100644 evaluation/tests/genotype_genome/hisatgenotype_locus.py create mode 100644 evaluation/tests/genotype_genome/hisatgenotype_modules create mode 100644 evaluation/tests/genotype_genome/hisatgenotype_prev.py create mode 100644 evaluation/tests/genotype_genome/paper_sensitivity/sensitivity.py create mode 100644 evaluation/tests/one_snp_test/evaluate_one_snp_reads.py create mode 100644 evaluation/tests/one_snp_test/simulate_one_snp_reads.py create mode 100644 evaluation/tests/repeat/commands create mode 100644 evaluation/tests/repeat/generate_repeats.py create mode 100644 evaluation/tests/repeat/test_repeat.py create mode 100644 evaluation/tests/the_small_example/COMMAND create mode 100644 evaluation/tests/the_small_example/small.fa create mode 100644 evaluation/tests/the_small_example/small.snp create mode 100644 example/index/22_20-21M_snp.1.ht2 create mode 100644 example/index/22_20-21M_snp.2.ht2 create mode 100644 example/index/22_20-21M_snp.3.ht2 create mode 100644 example/index/22_20-21M_snp.4.ht2 create mode 100644 example/index/22_20-21M_snp.5.ht2 create mode 100644 example/index/22_20-21M_snp.6.ht2 create mode 100644 example/index/22_20-21M_snp.7.ht2 create mode 100644 example/index/22_20-21M_snp.8.ht2 create mode 100644 example/reads/reads_1.fa create mode 100644 example/reads/reads_2.fa create mode 100644 example/reference/22_20-21M.fa create mode 100644 example/reference/22_20-21M.snp create mode 100644 extract_exons.py create mode 100644 extract_splice_sites.py create mode 100644 fast_mutex.h create mode 100644 filebuf.h create mode 100644 formats.h create mode 100644 gbwt_graph.h create mode 100644 gfm.cpp create mode 100644 gfm.h create mode 100644 gp.h create mode 100644 group_walk.cpp create mode 100644 group_walk.h create mode 100644 hgfm.h create mode 100644 hi_aligner.h create mode 100644 hier_idx_common.h create mode 100644 hisat-3n create mode 100644 hisat-3n-build create mode 100644 hisat2 create mode 100644 hisat2-build create mode 100644 hisat2-build-new create mode 100644 hisat2-inspect create mode 100644 hisat2.cpp create mode 100644 hisat2.sln create mode 100644 hisat2.xcodeproj/project.pbxproj create mode 100644 hisat2_build.cpp create mode 100644 hisat2_build_main.cpp create mode 100644 hisat2_extract_exons.py create mode 100644 hisat2_extract_snps_haplotypes_UCSC.py create mode 100644 hisat2_extract_snps_haplotypes_VCF.py create mode 100644 hisat2_extract_splice_sites.py create mode 100644 hisat2_inspect.cpp create mode 100644 hisat2_main.cpp create mode 100644 hisat2_read_statistics.py create mode 100644 hisat2_repeat.cpp create mode 100644 hisat2_repeat_main.cpp create mode 100644 hisat2_simulate_reads.py create mode 100644 hisat2lib/ht2.h create mode 100644 hisat2lib/ht2_alignment.cpp create mode 100644 hisat2lib/ht2_handle.h create mode 100644 hisat2lib/ht2_index.cpp create mode 100644 hisat2lib/ht2_init.cpp create mode 100644 hisat2lib/ht2_repeat.cpp create mode 100644 hisat2lib/java_jni/HT2Module.java create mode 100644 hisat2lib/java_jni/HT2ModuleExample.java create mode 100644 hisat2lib/java_jni/Makefile create mode 100644 hisat2lib/java_jni/ht2module.c create mode 100644 hisat2lib/pymodule/Makefile create mode 100644 hisat2lib/pymodule/ht2example.py create mode 100644 hisat2lib/pymodule/ht2module.c create mode 100644 hisat2lib/pymodule/setup.py create mode 100644 hisat_3n_table.cpp create mode 100644 hisat_bp.cpp create mode 100644 ival_list.cpp create mode 100644 ival_list.h create mode 100644 li_hla/Makefile create mode 100644 li_hla/alignments.hpp create mode 100644 li_hla/defs.h create mode 100644 li_hla/main.cpp create mode 100644 limit.cpp create mode 100644 limit.h create mode 100644 ls.cpp create mode 100644 ls.h create mode 100644 mask.cpp create mode 100644 mask.h create mode 100644 mem_ids.h create mode 100644 mm.h create mode 100644 msvcc/CodeStubs.vcxproj.filters create mode 100644 msvcc/CoreDefs.props create mode 100644 msvcc/SetVersion.vbs create mode 100644 msvcc/SysDefs.props create mode 100644 msvcc/codeStubs.vcxproj create mode 100644 msvcc/codeStubs/getopt.c create mode 100644 msvcc/codeStubs/getopt.h create mode 100644 msvcc/codeStubs/getopt1.c create mode 100644 msvcc/codeStubs/sys/time.cpp create mode 100644 msvcc/codeStubs/sys/time.h create mode 100644 msvcc/codeStubs/unistd.h create mode 100644 msvcc/hisat2-align-l.vcxproj create mode 100644 msvcc/hisat2-align-l.vcxproj.filters create mode 100644 msvcc/hisat2-align-s.vcxproj create mode 100644 msvcc/hisat2-align-s.vcxproj.filters create mode 100644 msvcc/hisat2-build-l.vcxproj create mode 100644 msvcc/hisat2-build-l.vcxproj.filters create mode 100644 msvcc/hisat2-build-s.vcxproj create mode 100644 msvcc/hisat2-build-s.vcxproj.filters create mode 100644 msvcc/hisat2-inspect-l.vcxproj create mode 100644 msvcc/hisat2-inspect-l.vcxproj.filters create mode 100644 msvcc/hisat2-inspect-s.vcxproj create mode 100644 msvcc/hisat2-inspect-s.vcxproj.filters create mode 100644 msvcc/search.vcxproj create mode 100644 msvcc/search.vcxproj.filters create mode 100644 msvcc/search64.vcxproj create mode 100644 msvcc/search64.vcxproj.filters create mode 100644 msvcc/shared.vcxproj create mode 100644 msvcc/shared.vcxproj.filters create mode 100644 msvcc/shared64.vcxproj create mode 100644 msvcc/shared64.vcxproj.filters create mode 100644 multikey_qsort.cpp create mode 100644 multikey_qsort.h create mode 100644 opts.h create mode 100644 outq.cpp create mode 100644 outq.h create mode 100644 pat.cpp create mode 100644 pat.h create mode 100644 pe.cpp create mode 100644 pe.h create mode 100644 position_3n.cpp create mode 100644 position_3n.h create mode 100644 position_3n_table.h create mode 100644 presets.cpp create mode 100644 presets.h create mode 100644 processor_support.h create mode 100644 qual.cpp create mode 100644 qual.h create mode 100644 radix_sort.h create mode 100644 random_source.cpp create mode 100644 random_source.h create mode 100644 random_util.cpp create mode 100644 random_util.h create mode 100644 read.h create mode 100644 read_qseq.cpp create mode 100644 ref_coord.cpp create mode 100644 ref_coord.h create mode 100644 ref_read.cpp create mode 100644 ref_read.h create mode 100644 reference.cpp create mode 100644 reference.h create mode 100644 repeat.h create mode 100644 repeat_builder.cpp create mode 100644 repeat_builder.h create mode 100644 repeat_kmer.h create mode 100644 rfm.h create mode 100644 sam.h create mode 100644 scoring.cpp create mode 100644 scoring.h create mode 100644 scripts/convert_quals.pl create mode 100644 scripts/gen_2b_occ_lookup.pl create mode 100644 scripts/gen_occ_lookup.pl create mode 100644 scripts/gen_solqual_lookup.pl create mode 100644 scripts/infer_fraglen.pl create mode 100644 scripts/make_a_thaliana_tair.sh create mode 100644 scripts/make_b_taurus_UMD3.sh create mode 100644 scripts/make_bdgp6.sh create mode 100644 scripts/make_bdgp6_tran.sh create mode 100644 scripts/make_canFam2.sh create mode 100644 scripts/make_ce10.sh create mode 100644 scripts/make_dm6.sh create mode 100644 scripts/make_e_coli.sh create mode 100644 scripts/make_grch37.sh create mode 100644 scripts/make_grch37_snp.sh create mode 100644 scripts/make_grch37_snp_tran.sh create mode 100644 scripts/make_grch37_snp_tran_ercc.sh create mode 100644 scripts/make_grch37_tran.sh create mode 100644 scripts/make_grch38.sh create mode 100644 scripts/make_grch38_rep.sh create mode 100644 scripts/make_grch38_snp.sh create mode 100644 scripts/make_grch38_snp_rep.sh create mode 100644 scripts/make_grch38_snp_tran.sh create mode 100644 scripts/make_grch38_snp_tran_ercc.sh create mode 100644 scripts/make_grch38_tran.sh create mode 100644 scripts/make_grcm38.sh create mode 100644 scripts/make_grcm38_snp.sh create mode 100644 scripts/make_grcm38_snp_tran.sh create mode 100644 scripts/make_grcm38_tran.sh create mode 100644 scripts/make_hg19.sh create mode 100644 scripts/make_hg38.sh create mode 100644 scripts/make_hg38_allsnp.sh create mode 100644 scripts/make_hg38_snp.sh create mode 100644 scripts/make_hg38_snp_tran.sh create mode 100644 scripts/make_mm10.sh create mode 100644 scripts/make_mm9.sh create mode 100644 scripts/make_r64.sh create mode 100644 scripts/make_r64_tran.sh create mode 100644 scripts/make_rn4.sh create mode 100644 scripts/make_rn6.sh create mode 100644 scripts/make_rnor6.sh create mode 100644 scripts/make_rnor6_tran.sh create mode 100644 scripts/make_sc3.sh create mode 100644 scripts/make_wbcel235.sh create mode 100644 scripts/make_wbcel235_tran.sh create mode 100644 scripts/make_zm3_snp_tran_ercc.sh create mode 100644 scripts/sa.py create mode 100644 scripts/sim/AlignmentCheck.pm create mode 100644 scripts/sim/DNA.pm create mode 100644 scripts/sim/Mutate.pm create mode 100644 scripts/sim/RandDNA.pm create mode 100644 scripts/sim/SampleRead.pm create mode 100644 scripts/sim/Sim.pm create mode 100644 scripts/sim/Test.pm create mode 100644 scripts/sim/contrib/ForkManager.pm create mode 100644 scripts/sim/run.pl create mode 100644 scripts/sim/run.sh create mode 100644 scripts/sim/unit.sh create mode 100644 scripts/test/DNA.pm create mode 100644 scripts/test/Read.pm create mode 100644 scripts/test/args.pl create mode 100644 scripts/test/simple_tests.pl create mode 100644 scripts/test/simple_tests.sh create mode 100644 scripts/validate_repeat.py create mode 100644 search_globals.h create mode 100644 sequence_io.h create mode 100644 shmem.cpp create mode 100644 shmem.h create mode 100644 simple_func.cpp create mode 100644 simple_func.h create mode 100644 splice_site.cpp create mode 100644 splice_site.h create mode 100644 splice_site_mem.h create mode 100644 splice_site_new.cpp create mode 100644 spliced_aligner.h create mode 100644 sse_util.cpp create mode 100644 sse_util.h create mode 100644 sstring.cpp create mode 100644 sstring.h create mode 100644 str_util.h create mode 100644 third_party/cpuid.h create mode 100644 threading.h create mode 100644 timer.h create mode 100644 tinythread.cpp create mode 100644 tinythread.h create mode 100644 tokenize.h create mode 100644 tp.h create mode 100644 unique.cpp create mode 100644 unique.h create mode 100644 util.h create mode 100644 utility_3n.cpp create mode 100644 utility_3n.h create mode 100644 utility_3n_table.h create mode 100644 word_io.h create mode 100644 zbox.h diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8edfb9b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.pbxproj binary merge=union diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7f38173 --- /dev/null +++ b/.gitignore @@ -0,0 +1,48 @@ +*~ +*.dSYM +.DS_Store +tags +*-debug +*-s +*-l +hisat2.xcodeproj/project.xcworkspace +hisat2.xcodeproj/xcuserdata +hisat2.xcodeproj/xcshareddata +*.patch + +build_automaton +build_index +clean_alignment +determinize +gcsa_alignment +gcsa_test +hisat2-repeat + +hisat2_test/*.bt2 +hisat2_test/*.ht2 +hisat2_test/*.sam +hisat2_test/paper_example.malignment.automaton +hisat2_test/paper_example.malignment.backbone +hisat2_test/paper_example.malignment.gcsa +hisat2_test/kim_example*.malignment.automaton +hisat2_test/kim_example*.malignment.backbone +hisat2_test/kim_example*.malignment.gcsa +hisat2_test/genome* +hisat2_test/2* +hisat2_test/snp142* +hisat2_test/testset* + +.idea +.vscode + +.ht2lib-obj* +*.a +*.so +docs/_site +docs/*.lock +docs/.*-cache +*.tar.gz +*.ipynb +*.pyc + +cmake* \ No newline at end of file diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..d22b8b2 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,29 @@ +Ben Langmead wrote Bowtie 2, which is based partially on +Bowtie. Bowtie was written by Ben Langmead and Cole Trapnell. + + Bowtie & Bowtie 2: http://bowtie-bio.sf.net + +A DLL from the pthreads for Win32 library is distributed with the Win32 version +of Bowtie 2. The pthreads for Win32 library and the GnuWin32 package have many +contributors (see their respective web sites). + + pthreads for Win32: http://sourceware.org/pthreads-win32 + GnuWin32: http://gnuwin32.sf.net + +The ForkManager.pm perl module is used in Bowtie 2's random testing framework, +and is included as scripts/sim/contrib/ForkManager.pm. ForkManager.pm is +written by dLux (Szabo, Balazs), with contributions by others. See the perldoc +in ForkManager.pm for the complete list. + +The file ls.h includes an implementation of the Larsson-Sadakane suffix sorting +algorithm. The implementation is by N. Jesper Larsson and was adapted somewhat +for use in Bowtie 2. + +TinyThreads is a portable thread implementation with a fairly compatible subset +of C++11 thread management classes written by Marcus Geelnard. For more info +check http://tinythreadpp.bitsnbites.eu/ + +Various users have kindly supplied patches, bug reports and feature requests +over the years. Many, many thanks go to them. + +September 2011 diff --git a/HISAT2-genotype.png b/HISAT2-genotype.png new file mode 100644 index 0000000000000000000000000000000000000000..1327c4cfe3a0fd4864076f405fd4d11c1042f6dd GIT binary patch literal 741543 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

R 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Ϊ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%0A;`?Ud=L#jT%d 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%0A3UVIMqvgFSYn0JKBm$qZD;H-_sBBPx=-qu96| zV;8-!vNH1HZcgq@G49YeIxjtEAE1wmOm(Es)ZCw`HdG?k+ty(}@>p}~nXqst=!rPW zFv@rYzV?x6vkUp_r%#Lo^YTe?3i#T4!u}NImYVr>7W!yl&#N}v4vHd#6UH>tMynG$ zv`@diH&`+vcx@jdV&mVmcykjDFL@~q>-Kr8V z(r3aC_#{q5TO2tU>({bQI&MTh@@*qwIQDV;31`D3N;`}^p=uTR_#}cO+9_C2b@|$u z(77|HvwmvnK|a%WW?DA}%``j7^Ddqbn;e;P0<@lrC}Y`=#Agu<%d-?cwdC&6aLLTO z=$Wc=Ud5T6=*lKfws!{W8~7{B+-?`| zc&+apfJFM_mQA?Acu&ORtZF!G@iV#M>!faaXc+lvsb;gGO_ZNi_*njG^Bqs}6^@Lq zfD=)|3Cq<)NYDN|VPH&u>%)8&C{pJhSb^Z8T7T5>B(wFjL5)?;V{I8#Pr8G(aSiP@ z<1V%u5HIW)xP>x@B*>*rC_H1MJ8+z(X2Q#-(zdhX$2;Kop{F?LyYDh*w5`%DZXtx& z`bX;1pktvn{_J2rrSY=ikSONlzuPkYuiORl%(zI}5Fc)sNJD^QohOgceEk(5%PGMf z=b&?g^E#cZ2W~|hf?K;`z&m6K+=tl)?$g2W_zvb5X)3`UIO>^`_KZ&C`qQ_yMxc0( z053QjI?{uuuT+tG)Iv05CwBmKItc?E6K?;l990(hv;b^Jw89@bAn+zT{w06pcAl9^ z0KLQVYsI9)Lu#GmN*Hywv7lD$v6}?s9cBoM2e`?u$KSqf3mFE0(vHc@DE=_5l1{dx z4Z5{-ppq*Y$Ca$}{m;PyKW&2l*)OK=yY@W{0xL(N7Yw`i0^~&UMc8!TA`EZda0(Zp*|mNv71A?q?}@W zA^sIzYY9~*NA{)f%p{@-!x2_lPgm2A?RHZo!uComvbRy`jq)q(uv(|_KWD9YlnN`pqCYu zre?G(t0cVQkk^{c0iO8+L*mdb&zI2`+l3!tYCz3rq?|>FHYN1##;UG*;2EPfAHQ+c zzrNuo{x;@*LYF@ZwmtP3t-1#l@oWnTX#E{DF^X0X+zka<)15MI0;xPShc18K81ig{ zCuO44QJax4nCekfyvVPz3Rxo>{8;&=|Bb5G#E7@o5g8*8^^9aK)AgFj#(gI#`qzmr zZ7FVOMGQb%0PD4#vwK;8M*!%GePM_y?#wmZ)dPHoQttsqpAQT{sBXY}v0mNlEwmORu?26)yHnW#G2jefwO8^M2H8+79&&VMxX1mh7XmG( z=RqYB8U_BL|Jj^U;UWsjbFlqBHJ?hWvP%!7nf9$wo3>3zXVu2E%`_Gu)>ykn8aRub zd@cJpS7WzgDfR9~GCf#PVO{-J&P*&r4-fCj3^k9cTY#xq$6m^!^t>P1)NQ&90os$! zZ1^_FrV;vw>O^5ul!FQ@r*k_LsR+N;I(WI@8{3?PBir&W{n$*eGxLrF- zEMzLkYPcX9bfYqf+>%s9 zCMUIDJa4@tFblokq`rK&%J-mQi*)X8#sz1_%f<7cqHJ%I$Y-KLx%}V>u7K>sD?5h+ z11qnCrj==}`)DN{TOeeQz5Mo1fcJlXZ~s2o0|ug+fvuE{bxGqaX9Rc&={qQW&OUzw z|M!7(k@Ocz$&w(D9#(OB1+JQ@0NN*12k2Os0Xtx8Lwi>aXD!QM*e?Pt`oy)I6tu1- ziQ3z+1x~4m4@hbD=Rlu;704&S%U#0!t~kWLfr4&bf|NH4p8v~`5wL=xu?LdE1=W#Ov(-EW zj#K1$s3}b2c6Q^uTPuP`Q-UfCJV)Fr#rcWj{sObM+Co+4p06nwo6~;RXCNE84vVjc z&xR(PtdG-hjs4I%gpw_UJg1LciCZbW|LAo;3LSPrfRg}rZGgJ=0hh=F#;Fw%d={jJ zCVN~pjMZL#Wu3Ma%yBeS;mckS>z+#x6P&fZs(cDeX$dwWG!U2(>Nnj-30a2Y+BPpJ zH!&$0cWv*}X)=Xxt77q&#KI66gM?I%WTj~*HUd#norUx2+0~mvMW)&*^N#R|40ud6 zR+ipO&&slDFF2~NX8Ki4eu2zO`o9yj%13M_<*R3oHcz=w!EMT`_ zfWLO}{M9o%?n5GhIZ~b;g^(qK5kGpW7M>>IF9w4xCy`vP^VTy?6$j3`e1VhNp%AZ# z5OLK}x8Wm|nSx@i-!%DdvI5KMN2nLgnS;fP2?eoJW_k)*mhE>#0h*s!pQ$dCklbjk z^GWo6o%wVoaicA_2o6RfoJ0ls)7hx}?{0jm|<(pjCHYne#_X1mb}|UmG9ilvE``Q8bm|An0NFd)Y~^<50-(eJejE04&-I798JkT7^+N~9t1sb2Bv z0CMEDB=JKDnK-A6mk#T-wb`?UEt9`?C?n(zUk8|en311V@OFcZ`m)u)MwJy`31DKA zg5)Lhvc*>+Hv<$9&=h^u@L<(gNnK%zUh|#am|6jj;X)%uW&2}GOtNfM%W!`As+L{> zG$a;oV%;8P^}I?ca;5P@GjfuE#K&YTZ!-zS?bKxQc|2shCRA|iB_zJOzcmjWmwvSYVr z+qA;ZN&AYLpf{jbx9MBl%Ie8$ZJT@V%lO7n0d^!|1f?h*u&L?+xiR`RE# z^edl>d0LUhzqhbU7+jH}H&InqwFBx;cp_JqzP+-fbCTrIxE|p7T1LkvXgP(1OL#j) z&zam)=D)>&NNF!cEaSkF8P0Uih5AkLCWs~vi$82K6QvRPIG28|3g`qg1rVHAwcbmQ!W88Sn zH=iC=m{{8ss8M~-b!LjZHl}}@Dq3FE=J7|;7q2v1w@2yE2O4Xsj=c^$-A8^iqpmB%LKx=D2yh6loKZx!%1pOTp(P+VT`WfQ6$ja_94onU&&0Z zrv6!J>h-g3p(Cxd?=ysU@A~L2I8N$H%ln5YJ|k29!_myU9b~6wknO>?HzJbQw%OQc zJ2=gViJ6(vt%FC9DaZ<^*w4mZ;(rnL;fDt~L5%}%!no)+tqZWTiBcBW=ej9@-LTbx zj5J2dc{Tx0D;tPGS7GToV3OGl54?8s@I1x0Ja{FABdnDYU13wnjMPtFv(IO~Tw7Ac zG7C#EF6N9hp=?Xw*qOuqdwlbwBc<4uW5V>ZKI6sDYutdKXO_oUo|>m|5IXKaFH`(W zrxi)eCr#%Qdf5YL&`)#l?p?`u03asL=;=9~;fd0`+U|tn+_ep6{Vbq4gkLOpIe-?D zVhp-+T6PMzpK{jrv*B+?zPX$ENc{!?TI&9EZX2yMG9Ax0^X-vr&+`8p(dI(pRw8-V z__|)F9oqpKNqi#S^9zBHfvIG6e#%(sopIT{^&eZ3N$o#xWG%?D>nI zq8u@=kRYkPgt6dp`#sw|o$N$QD_%-KiqgmN>6x<1q1P1l?hjtqgjij$+TdKcsQ;{< zA)(A7f0IUNP`UHs{&`&=E{e|gs0Eu;XBFi%e$JRciA{xet^mT=2VV&SHs1z z%9j$K?nhxsNZL(~PcAh6EM2o4x*C6cOv`2DGw|d6jqO_>(MK1fjqL`F_j6DOgga`T zCRser-0fyzTg7yBnTlHSUEHFaAi9emKpCJ#Np%n|5@3Oh%VJ-DxC!tH zP}O0VHw)#1shd<@N#B&;eG-Wg;7r*o)rXM{+JEX(Vd>Tw%YzOpcs|efs2_ zlF^AyZpEgE5^3wDE+O@*P@uZY`=!@LxY`?*c9NbrV$&S}kxJ>yj=QF;p%AH!prXq% ziQvo6ihoYSs}I}75wb1kvvE~mog9qIqFc{5@Jz`fsqE2RkPl^)vt zS`I-K(t~3k!Hax|Yvr9X3JT;{H$4CdJh)wA2nwKR+1e!6ppJJI;{ZD7=0S z&7g|6xCd4u8V5VVAbli*OG?YEHzMM%X(vW7M9PsYuQ=< ze#Y#Sq7o6^3YS#%dCSfb((X|%_RjXa%FY#`qp+Od2_;?Cq@ySD4acvPD}!dgZtV(Y zeUfxF#9I+wl!D9yUg43r#Z~AgEI>Z6Q6s1)7K-6*>ED8-^K2J(qe{iY{-O`z$l?)w z=tuIYfO?ph6Y74065A8utYonF4YJ;S!uPR0D$U!5XurmeZD&!Seo#WF1>%ipbkT}7 z<2!m#c`hr&LcZVp>4cMX72chM@J5sT9@o}n+TcwA#t7kOV+l2UFHolY>AAE?#2=C5 z_Al+vUc7i|y?1RK%eEfgX&Le4cPA?qBMos@CSmqvd1+|_bdz_puiYX-{{8H`>ITLv5_fsrg&^m*Rh%RO7=TdkSzw_jVAja7;S71EbetjxKnnq0)65l+1(7 zxwe5DQ6zz$Txbmqjj=846*=_ICw>4tgCE#^ z+|tzYnfe~irU9|d&R6gD&OlTnr?piav-5DK%7$tWlqfr?I@o7FcXjw_IBcO;a0u?9 zFEsmq{oI$vfxj3#%8Uro6|jwwa$5e0eGa!y@`J0;Rqg9D29?{Im-8&moX?-Rec`rA z{K60D>oX2b_apPRW$yqPJw82M1wN0SAIuA|*ed_da6>_VejCV87)+Pj$kn&;G3v;8 z4e533QqsdYD!cC=OVxv=>0O7Koj>=H@Y}W3PCRl|8X6qjG_!V$cuhKZ^CIH1oooE#7=qjRYg&+7Wl{LejK)~D&)~}(o%Wp z?fH3#e=^EMT*rGJye@LQ%3(bmX|+8`lg!6=t`(?Z*?}!`wXWtohtb8|pUP>ytyQ^9UL0gBSyDb@!SpRc4 zp%suip#DU-Wo*Be0+;3(Lqrv5z#l}%+(scwEz%1cFFebii^+rbxIH{MRru^8_I4kX z8mWyi9wUW_@>BUkXnq4@5QZOei^4*Z;d`q5apeJO#aQwLyl?zc#>s3Jw5OAyYKlOTuiw;etR4nVEdlsU!@xiZn}jvq>l&Cv#AGAlqt@YxSGb$xA^#Q? z<`f$XOSaQ$=PMlA%HFSXwF=QpWE@2)C zk-3&xfHEE}B(sGCb7`dx&CyBNR#?J=lpgD+&rhWR;}fpt@!*7)q1_jX98b!f4qcxM zr&mg!AyO(QKz#872ZJDgL{s@HAs%hpzj({qjYkYDOdEd*3$*#RJ2}i1Ty>tUtCxLZ zxU$ACWp&G~98;fKq zxK7+!BR#bYI(#ijZIP^j?30?aa%rhR2aBGiJV$kK4}Ww_r)b-OC##NfB=q<>)JNxn ztfuf*K)BI9cV#m?dyeEzYSe%>NWdHK=pa;vb%(>pvHzjW$JakccfU^>a9JC$1;y-c z;D(^oVT*7w;ts4X!uow{s++}*mV=C$H_IJoo1igjT_RtdFX!K7GG4*pOQt&V8Dbvp7(**To$;DZM95ujzuwiD20BcYR zVQ9KUSJ0=G72|6YR$uq0xQFUQcZg5FDj2~p)>Jy%>=2h8ASze^JX)pI=nGE-XTaA~ zcoDzR&AwnKk-_JS^=YG!`sYS2HL<|&iKk8Tq{7&@v%TCCckUKmHapiN9nt$<;yc{c z6n~!+4+6-6Z*_Cv3~+gL0*j8qO{0Zx=*fMrmQNgB-xZJs7U7AagQ(54#c#U4fq_Iw zDMgxUx6~5I7m|b_7G!t|lLR#}Yp}+n+~?BMr6h z;bmS?f+w~^SMp7x~(5elcq*5(jMJGFPoAOE?jYR;TWo|7IeyI-no*^ z{74r7k0tybbo0&L%jZId_|vjZx=>$Gs}2a6MwV#YeRr*IYLT$^r7yH|GW^!H&QKz} zhN@CYAuas9>pcI#Hw9G$5vqv{1UqCU-7!U#eqSStT?c3h8LiXgmLal|*2--S1JuLM zTW~{m^FIB7gpC3l%2LzGvH9~wodZMqfaR8j5upuBZ->06*?5!<_F{@$ONwSTL&d9? z@-IIfcH~@n`p>2qLZ)+Ph{JHK3vx#?+O*l52DX#?p!5%`p{&1D?ji!zL|$VR^}!^# zN?B5V!z46PH>(C-9^ZQI_Pu?L6JQW3>PX&7(Voz=*i%aR|1tKKL2-3ixG*juK#)Li z2qCz;ySs(p8YH;82S{)Ngy8P(?(XjH?%vS!J-jn>rS9DNzF!n_sHRxG_gd>QWn7x0 zL!VnU5dP+TW#LZd>Uied@!L+PA@Y*5Pb)DK93~T$GO&wF9VOqfc8W_)+Yyl-pxA`o zcukc2ZN%XYkPW?I?7#@kpRucx%db$H_woUBVKi=m zu-#fdJ!t847vIunS&niU`Q&h;|Bl~~k}Fi+@bwn)BO~>909MF?-as;Bf)K6Au-G9G z3k#61gU?#;^#J0(8f*@mot8zM@N(Q%BP>kQn>TMhxuN*WBX#tJ{el1mgxnq-u;K6w z7VoDD(kZ2l7=Ldqxq)5f^RkKV8;!1a^^y*GBzdgA2}UKz5+#T)4(Bau9bpdF9h1%H@vlhM=8R*PFeX65Lc5FiT(l{gV z3MO|_xZo1bZtvGe17$04FT4Fja`2Xq-Es|9sjwS8}O z_nG$~O^#iyvno&Ap`~Yoa~TsFZBMnqcCi*nHSlm1^0D3%KkqVBk298)Oz5r)t=>-7 znRM4GK3<-4&j{y^-P`3}(J~yk-UB2@T2t5G|vg=p2$3DLhDpt8YqQ*)71F1#M#?zi_Hfm*@q7I8?wvj zn+bHoa>U{DTa@;7)uhd!Eb%ZTycM&NzhsG3F^@#(x0H%$DOc#z6UgYvi~tUX>;?f0 zmS~}&0itt0;1N~t&w(TZgo?VhKk0%1eZVKyr`NO~LHf`P_i)Ri4MRkjxpu%U4I^M< zcxdPoEK$I5X$>meh=w%rP-1!=s_zOwmYz0a_VsM+Te@}DZpl5psu35gJ4d#j*Oz1c z=NO;D@CVT5!Qtr#c7_(V2CGGuM^17*B{`f5w70LW3`&$+c9T;f+_L2|K&;xCUzjV?rG>ckF~X8% zyt&@iu+Pe6ZXBx5ZYoaMI|yPPD0!MuRm5N^^96>R8vAVt5ha}#Hd9f;HH+)Up*(RjDK_8ZD27S(rpkrXOGW6-;{sQ4ZG=wc%6+Np~Ds}Q8*x>R7-*`FiF2L zZy(8nXGmm)aVfuy+X<&K;uFGYClqtrjep=FmF)x{lH;AG-{;BABJ>UZiYU9Z9j1>e z5z;LGHpIVuV+s2K1s@B{eB^5Y`#a5h{?wPs;#<9tU$>1eg8dy2+UZ{QwZJG%S>pI5 z1%~ht=$kT#`SVc+Mh_{x{h2@Ge0DIY{(OMtXOqKPta+=RM9K2icllewlllAdm(7(g zO+RA4{yIi)9`(`oy#~^`zxiH#o(8Yt+_j&97rxj`P9K2l#o?2gL^DcBH|pFlt!uhf z7vJj4FBez|r92_Dk_CRI-B2aIc{+!Ryy6ZXBs|#3a%R-~kaM<+B1rOF=;dng2qJ=U zv`CKKcL%$oaq4sFxnZK|*)c)8hQ6c?o*g??nDm0Gr!j0(kr*AK zu5o~TSkDKCFYOdourcDq2C$ZLtu7Vg@PUhSJ({8Z5GH3c;O7F6o!H!{%H-Ur{Bb|| z++>qj#6E{pRmG4#5czJ*8aTk!v;!NVtyo{sbUKXB2tUAi7Wte8kTYV5fsP`BQS;kS z9Q9QATaSUH5C;Gc9+FfzsTjs!($6K`=y`TZXx`?ao=6fvfnNd|ma_8Y9R}+^h4i3G zZ$1Jr_XF2f?562>Ldr)71t#F&Z{DO&p{2Z8S<}@q(ea* z>X%Y?$y2f)gB=W*>~vl}*3@Szjk8~`^Q(vp*D$B|iBSOQ+0ic0j` z^?aBS83ncybYB1Rq2Yi-17pxPt^T47O^Y8A$5-LpcP*MYEK7aP+_!8?6fIs8W|tYr z9p1H0zdpM71|Af51?G>1`s?TJ!$H1opjO6t@?LUzq6h1Z2D>$|pJy5=_Y-e@kU z(vVE$L{J|cpqSU3Jte|TOA(Fem=Mlmke=^6@!U%jxcwN{^vmEtw!-ouBn(^_a-NOS z&P5B|lHjFr#>0=imlOFx;?Vd5WVogz&@}23LR0ZBCC))qgrGh)iy15oBAFQ%o=I`(1m6gGg1AK*@mH9? z2J2jSB@4z^s_X|Iy~~~CZnU|Bg$oHRYgVa8^TYFNy1Ed2$y09vyu<^W)R#D623~?$ zoR8E75$=I>qG`b8T4X>ivcw*VqXj^c>xTzUPELOKIlm8(bEd*a%0HC>y4nrk3pKAH zM}WH@ona!75nCk_?405Sm|vhT)i?lMrR@98WBGU>KLly`)sSW?(j>w5JMrujA@}H#Z*DyRFO>?SDgY6f>spkEsy|1zVo}LK+8L)G;05G>&OVO(4 zaw9pN9Ec=e9+zn$pb=8}u8ZNgJTK9jH{tM&cQ76T5FNi05Y{ts?sL!knx8k_wX##r zn-^peLEukH!KZ;Zi&;1XJHLU)$!e~fUM-`-&e$E%kEJDLFw`5wPu8#^-OEK3=#xr- zO;M)UqQAprt46#hTN)LceDon5-Ah4L5XLcR5AJs6`Vy)-z0(opXl`&$@Thzb;-lCp zyCCm`Zq#oUEe^drFueR=uI8(COyGIU3S z3`YM_uQKOcQ^7!(0-$rz#(#)iN7;jvHb9)Khu_qU376BBlCS3A!&pN>x9)E0MKraW zHS?q+f`4&puEc;-*YU{il`fv3o7|n!vvil4U^rDRx_>ctqT=ZOx;N>MJpVu)s!EyL z#vYy_M*#!d#K;8w9$UhOx66QMKSjgkQinH;R`xP zF6I!V1Cpp1@N<%78S-16SK<)eHidj$Ud*{=qpK%fWq4QGCp!>)|SD~T+>`SN;u zcXyYCZ&ox!4R2fmfRnaK6^8-0)7;RIN5H>SuvW8RsDHekQ{Cq(HeD*?1<(y};&a*% zzVd^vVo!pCg5*(aUs8YgJ<`NH9x6E0;Ut-wJrYwotW>d-ju*=R^zv|Kku5Vo%_88=H7ho z1vZYr3`g3E(NXTR_4xbcl(V(eI(^QXx-^TyeUUm|atps?6EO4+)MpjH;1~jopQIE4 z`?sOW!wLVlS8ik&yMS>_J`iv=AYkq$nM5vWc8JN{mXerM} zqe$~&-tIYsHg;fqT~XE|lg*NSs|Mb%P+)$-GD0$GeUG(Kz(p$`Y+a*x419A1KtgiO zQIB~PfHg}UZN&X{3%9s6JH)jBTB8?^KD2tuWI^Jori_iIJ7Tu>OXyrh*>+rCzh(23 zo8VZo>dahf{mba&nA(%1@^RgAG#}iH2dOkTMT}PKNe}Y+%{~4(2v49$c&+vYa5<9rllS62nklLTT=8MsJP4xWno-+^Bdx9dm(bz zctcZ!z1%+}_eA-#qGAb#T(3n{3NXe3V49f{>KO};pY`e%&vC3I=X{TT_`+AbmKOTa z7Ym?d6~86K#j!CV_)5LXpAG>BF^Xq8cgMiFn967Ebr25!)c|=FB!(XiPvT;_Y*|%J z1JxtsEtvaiXlN)WQB#5MQVgHp!zp$e6^}&>=GymhSbqwjoRKB2*#h=YkH4l&G*^PKtri@9aw{O$EC*PH26CWyzy;ag$~-imjqgNz>B(k1wt$$*(JJpx`os zFb;r>6o4{jO;6{%|8qI9X?uR=26xsa(wQUd-&cB>2oxhN$!h=}5KA(F?)xAr0%cdz zgY`k;sbsAQsbpDALb0_m8gw_5eXU6N+o5V@MTZA4OF0B`!?Is};Ad(r=i^$MMMDsZ zG}P2;JRPSw%vS}q|Co(_rGUusx(!75STCpfxX(rG*S;ijO6{;km!i)m^QYsU5+h6g zcnWUd+e5O7n0t>{>)d?1>F%sB!1;t1I1sQ5qUq;fC?Lo*-pg-1uI`HDz(g{=N>PyoaKBP zr3%>wq ztHIE8CX;Qg((fPE^+7El*xW3K_%y`t^@;hVxplI+2}rg%d+<@@jWl1eYYb70u`#MY zN0^_FVK2MG{5Gg zRo*2c?4aAW^{XApKgzqSLCR@Bo`n8*sCa>mi#vU1!ld8s(<;Yo(BWr5a}ebR0(woy z5MLIeDxl#sd@LLT76bYwdO*hXkGJP{$1u=4%_T-{M;V-gtKS$FPJU@mn`O#*HuWW~ zb1Zu=jriT|yx!2G4H48v{~Fx?SyaECh`^?y1C87cSoFzmfGqM;C0@yrySBsCrlY^x z7het)eSe$K^78#cUND6lqP0BOb;X@*Ku=JXx8^5mD1TC)>4V#_J$VqH2P|R3E7CI5 z)z#SyyMFWq*FLoY`d2I~$%+?%%)k2xf3gmsF+0<1sB+60&fWwPfhV7^{_?@iBkqDa zS}Q{?Hm{DVEpw-`v-q^PsCTk@2hoosWp}BpRrKGNVNa1emx~A`#r1nwY(OJe@T*7r zkL9X;4joN*`+gT<$$)e%%#1v*aB1bximj7dWm@${8eM*<`WD@b7%BXgzl7ZZA7Y^HR89i$`OP{SEDabCeWqOe047lf-I2rPVoA`AFIN$ z$d{x^l`FYOvWYM6sPvmd=jLXul6g>Vepecv|JrP z3#^gUm*?&;D?iegj&m%fYsx!q#OUX_PwV9Z3wdUNp|NFd7$6NW<13TR3fE(x?@UTk z5`Ge^StQ#gWka$yPz>sL4uF^w0s46PBdoC5w{PEO04W9B-7hT4p+^9d!>Y-Sba@^* z00g1fHRn?BczZFsXp764PY;*d^yc1@P}Z51d&R$mlF~nKP2!9Lv$>(IXA4k6b>fQF zI{E+V@-Eq{_5QVC{TCqjpA{#xKeKV)1hDu$cvU5B&a++C9|74*(xeqH+U!IpR>vGO z_H+ZD(;8Ebw%)?pGQ}{?o;WUVjtXgju=^ZEL2#T+!zRM(8r2-2Kz4=dfA3@j;b3Fu z;4hUeH#;9o{9~+J7POv4==*$m1N0Z153_!E=H^TArH%|=BcmM2%w(JmyO`K)3itC{ zt}<{D`9$xHcPyINCqczv zmO;so=3^*Zq-DsmCpfnF7ts_Eber|&oO;wvSAz}JZjp`zpF9F=pOisW&gVPAnB@#L zGHt|bv9i(nhFCx0Z;#r=7e#0vMVzM}jX+0i&=Hs0b4ZyYojK0sk&EMhsZ4d$PlRLN zzmCbP)&9N*dRqvEMo|`KC?^o1KSNgVNn6EUv?C@TQTz9)Q6Bv+g!AfO5pLyT6Ze4%8PJI`su>7BDRPFue@X zmgfMED6u5y0Gfdxf^L#1EcI~-37n7D*|C(03XilfZXb-k&669n$(Z;w9fK>l@oVzN zMWXH;BG}ulBj;=Q*Zx&3r;ooZO#bf!N63=Yuj95*HDAU7|sUM7UeR>Kj^{u-CXtfHZ(H2BNQ-uIWr~E|D3$u4ijEJ4NL(Ag%bFbvyB8c_f!@8sk2NEdqG5Jw2Fh250 zup!_pMJmR`>05$rMm39cl}3t9or}ayl`7mPbYoV8`Pc9}3!x<{5f3W^=7`j5xs90vWVsiI%d*Mc{CIjDW=ZNmrvMAzSNki_prX&m*NmDF03Ffv0OCdqfjoNZ-q)}y%#<*?BP6BuCTCiH z$n*78>r1{M*g^yf^va>p2Y&q_z;}-wp{T$Rto|i*yI5^DOcGN5>hun*8xtMc0D4>i z;WHogUSJxl*;tMskkUF+ZKlWr_;0I5)<&L60x(agri-gSyWpyizU5%d=;iY3tT{vc zI&0D&dec)Dw?4gYO}O=$r2lE?{|$Hk2lYgR1Lz9{z=V4$JX*7pB=A0UC91;xc)1YAGGuqTzmGIDoq__ z+78QRINFK`&8CZ!TlKr{MX2v7?u=;P*4{U?vG~z9>BLvp`y5VU>I3w%8oB_|jM^JV zik}4jgPpxGcsXb1{I>%?e{v+?O$uXsL>5y3UOwyk+AFP93T1dKB=xeSjpy?*GOMlQ z%Pp;h?aMYXGefij5-_k{@jpP&-HrjX6Ah1uH;?ho7qGaM(eD_EACbG? zA7dTk5@pHXrW9qyf$!V~x=-}i$PEW#{^w(TNER?YrU1fLG!THVymRUd#!}!SBV+Ys z;b&!GId~29uAI;uUZ^zAEd`9SmP~5kG0e--jgD3qHAWS+Cmvmd)EvQewO%-%YeIl_ z`V@^zn-x|1>)`Q9|zDP+R#dm?NGHsAp$_FNN(5ns9cM zOoKh^-kn!p-$-V_B3kC&Mg9e=6A0vkmX5w!E_1gYH{QlA8$J-z-F}gihH0YAvqPQAeTPqNq#dZA4xtgF`b*1<5CJAW4uA z(oSO|zg~rDXUKRuXV@73r$7nxL%QWWdSV`vT@{ymVcs0AS~TtNe2uB9yjRo03F^Kq zh2V4EbWbgj=>3yg6U&Nv!fWK@r zsXqQzzuJQ$0`IHze&ivs?f_2dIw<|U(?-UalOF9@W%e7_k-_{C25%R&@Q8KPcOB_4 z0QI4urY5dWUQ?`G;F)LkPr@m}pX6W7nEnhQ#PSL0{C_3RmJ@hf&*-4XnpM(QEo|Wa zkR{tlOC#^@ZZ>-#zc=a81vdFQ#(?j$zDR|kPlo=AT%8U}yITpA3(J^R7)* zi}_zL!aq~r>+m-P58Wd7G$D#U30UC7FnqR-C3+QvN011nJ$7>P%+k3vj=+F2o>gB)A3REq1;*{Z%6y`10uJ@q~3A1wEsvIqgl8Y{y)&aHIz z5iGj>Q351ccw92dQx^c{y?x}9!@dI1VK23|i2~mFBiKAV?(!p1=p!D%fF!!BWJ6=5 zXEDyHJ$65w_aom>l!vel0ucvW!WZk3JiIX46jDY6<77+0lb}^9t@ES=VRA&5tgR|7 z&vJL(;7EIX6c+5O4#+Xs+s7?>sP7Rh~biU;1&AYJo+m7D(z5~-B8 zc3^j`wDfzmC{ic5UC)Uk9HA0#>~pbpp}U&&Ag)qcnf9F(rHZ#aXmte)+oJ} zU!zfOggx2vD6|sLDlD_-U@^3m@y9UdK6)25t1yWlZ<1C?M4{AOJBdT3k^0Y`z-@7?;VDU8 z?53jPBZbdnb+bO>18^?q z2cZ5_+!1W0k# zOdB&&7tXHxTylk6qQh){$EeXDOIk16)O=8B|9oqqTxZ z5aHEdR=wHZS3_0*n*W#C^xq@u|La2r5!nPaZ)}^(o*h2F5jqHLJk3R>$96=<))O!% zO6StAr3GI~>1tnJa@p|_wF<^MVrs_gHYHTmNk~S4K@0uX-{?RUzV_@P`8Rsvr;5qFX>K5paTPW-847*qI0N*L5`&(O5zHc#c_IFhzL$p97HV*r8AYp|;e3 zmY|t5H*^&HGbU8~f~+TV-#`O#J&D6a-ow^&3NwR&cjwTXB({8Pc`~H}iT8Wg)9CaW z-ghIJzU}H_!<;j4jsr|g$M|ABV&Y=Q73iQGEr?zU|BEbP9Las6+RHjCeEU|RV<6f= z>L}N@$$pffgXwSY)pWFmHRo9mXGGs{8S{@1y9lrts=_`QQob<}i5xKH9mAUzhk@Xh zl;qs+@epQT50YM323e@yW$WL=1&g0X{(7@c*j<{=Iem-#_@@ z1q&(Lix2rZFHBWesCu#v-dGF6P0^U^b~h6V{1Q$l;vwzHfko_iu>0_t@EB99zhP}d z4di7N6QZ5CN{26&<1g^5HPb2)7SrhZa79?KTI^Us06h@1O>ucgN6S$8YnJnT_7~y0 zVgO$mfAFAEX`7!*PaS*~Y@)<+ZCDNyc!;exFe)eMAHzPeDD^~?O#qYVd6)dTL#j9* zV)sW4A~*(19Iw?9bSUYcU(xY~+ME!Kww~;eqHw*b(jH!ei5l73>j{7PLUk<@T@)@A zlc<@dFxpU+t`Nt+s_u+7YIVEFt5aV{9_nO_192Xe9}&;p$^@k`lLB zC#W^IrX|vpzG$PZZ(n0sfu}$SW==3kUuHWmK}bhQK>Lg(1~`8Z(u6j}`aIz>%2(Co z8RZr~B5?AzCnK;N9VOjC#N1I&an(9{D9X+?BB`;{-Q&GYz3ow-*PBZC_5>dLXOuI>-b!;)#PJCf63lH~4g zyqa!rJ53c)@A_PwaSrPLxOJ&q;Y)WZlN;4s47vWpA2k38?#Q}S|>T`ltl}%Xz>jYl!XoZFvlBjB_qBOatXm|1wr% z5{HL=7YhEF&k@3RqMB${gY!xH*e0j3=rMjzld2NJF+cg6$D*Mhi5@P811*{}fvkMw z+t*8@vo)qzFu6K^tD7@0zB#-*t!U*MaC0n$yF9BlDA9|DQynNM0ZgYrkrYs}fcSk)7 zGi;%#dqQ*fCT{)vQNwftr&OJTk8&C|1$h+5MFF?xdeOp9x5r|&RuiGOvo#LJ&ITbv z&VN3qWun5D;-`=}{J2AjecBRDb!0K`@l#M6#CxI~qd}e@VTPBC&&DSD3v1az@-(ST ze)TE#DfZkZizXdR!l&$0>N-6Bu6;6r33NY{wPLlR{qs+G`NtB=8HlQJ31&8HBgd&S zK1fb?#4HY$r3>?l67+ZLjRKLT3WjNg2J(S+zb88Udd#Cn>jz^Zve8cA`@spHMKsAj zh=ddatLT$4GRz-n@o`Fdlic!FKtX8x4xPv$^(yl7mGM2vUqwmjF}UuxunsCJ$q)CA zA@$;?%X*D?Ua-x_jPuhE8Ui`E=_!BJ@>5diib|a3TTI?+dSRSQv8Qw3T5oRLU%;nx z+0J))6%`idPW=vE7u{-Ewp7$nuuRwY-0rRU=7m0?vdAXVxE}4Pfk;OI#Cn44* z*2FF)Q5fcF`1vBE=OM7N5ab;G)|9#BQ71Z#z|TF0o{X!XHL$>DnW}vdT7E#aIX(&8 zvhx#LF31 z3mbv|d$_aYu`5Kh#s{#HqWHj(3|l(RRYFU|)v!tM=UPK;f|lgHDz%w;KRZsYw$JBO z&N>3`D|b9~wONXRl=_yGZ%vlXSCXf~6ZeghI5HDWNY^2w6zn%W%gN^3b6T$YKb_F_ zI}WO&4!Sy<831?GKlXlCvFF&A&t8(>R6QLs!0vSSu|c_NozQK{yqT)-TbqCFkGiU$ z#s^Njy=9e1$sM!tTkFH|r?`b(oYFkg^h9+Zcm1yWII<9rlSdQRfESChy~@pjg>m8Y z*u6#ifd6*&syaokkHCM?jA%_=k8q;1Iw5Wv<=i%}vithr0T!jeSn`~5N*;Fv#wo&f#`BZkQZ%G+wU7n(6R28Z95tYtK?+saIm z=x7y!W^x+H55A$WrS)-*20aDsNRDFb-N7z--S@+>ri2FNI0jI32KqS7GR6X^;lpn9 zIR>lFXzy_{)4lWB;0iZ%UdRNqzmcd6Nr1a23f%XE_t)H%aVTB#$JynP=!5xfZ7uE|qflBXhtlVZdag zkx0z1J0&)Msa(s|9yUKs`se`;8oZg@;r6EpT16?iPg@PV{!?UCzCs?wAKm19E<&P^ zG%FPE9fF!s+z$D+WZ6M{b1G|N`Od0szJveZcX_%3A|cCXL0M?ituRkQHPImT^0GR601 zjj-ui+bq<2nOv|z@$@Gq$J~DwZU1wy|1THBKi@ORCs$Hd7VhosWwTvt$#ERl)RAGu z#iqC+Vs7y}8lImzXysKpf7ZJJNs8C_jIu1%2!uOIeV9N{{6nw(S&Lq$A)3Q#VFH2O zia(x)mbS1Y+&D?AA_riGf0RDrrjiKI;e$88H>@i4X9j&zrw;Hpu__vck+^w;#y5ct z{gSw@I={v39Pro6`b$w(DpyRj-Or_PG=S(*cZ)0NC-@ig#2@43%h4fupQ^G984LL+ z9AigI+l&q~(4#}yxz|v0)i>dZp%T6AlU+Dadv@+Uc#jjc4-rh$AHu6IHm5@@BPRfP zI?8hKy1t*Sc$Puql5E^*IAgPmBGjrY`~BGwA~E)Nt=aN3k*5%}S=ZU8#R&*|=D@0P zVmtA?H-jiwx5s>oTvE4x7gF7s?!cl7w*g^M_5lB)dLT#~XjueOM!nCb96)Zug>by+ zdyP@ViHwWg^SBA2t2{V~1B_fnN_&4V#R2V8$Gt^%^8{4g?!e~b&D==oU#a%@cEPuV z<*IncYIp~qXgv9NsRYXwwI=fR9c=dnqRQ(6MfTzN_O0Tr_SkE0G3nNOhY6MfeoSYX7`eY-|C15>S*IF0??*HIVUN692iMI4#3o^8{h2Hys9S)SxlF};+!cAFl z_`mKQhPY(HBJ5(aM4_L>icSkK<}QZO7HAkEq2;sxh@%@_u`>rr+&!*pxs#(&N1bmt^XL zt>!2wixgS=QgnTdF~do|rAuHu@y7>C%n6cddxU}u>HjIX~uDdg^vxxv2ihW;ihRp=wqWIm&X1!4H z0B2^fkf%t7b`(QgV!Sj2)SggaF3SAgX*VHG0Z)E?U+B)$*8Q)kg6_oUQSQ4PQHw#` zV)N0W2!Ee}5}!f!{Ap=3LSb=&$6Oi)qK}N))Z4upX%dSgPa7oZ34V823cTTw0*2VL zYV!`uj$JNG+>%r9`uvG{K6koFeD(<6E{3fWe6Qu2B3a`gH%m_zr{7&uH4;mO?}?jm zS3!dFQ{MG_BCL5FFV|tCsgUgZ{fYQ>?&L_mGt#7sqmWS|oB0V-a#Ps<*L(SYA0YnG zMiL;6B(h2d)ae5_8emhu=bF!`e-E|06D*Wx8{}_!KA=8zuY;8;omuyF+cG01BoIxY%7>^BDlk3%f~TM^yF4RzcrTQFr$Ro}mBI_q(Sc108HE z8+$w2q)f&IkSD|*D#(U{3M4RN{6f9zUp}b0B^*K%!E5IQL`+{pIGP|>8jE89V6o!+ ziBQd!N5;_6(L= zm&Bk)gbUmw!`8;edD?0+f<0s{Mg1vk)+PmDkMjiN=x>$Gs&Ksnh!L{mou2zL9Uv97 zNZ-3wd8=aD;;yQ@4dHq2;LXMT;NiSH9TubMEwf4t{rD z+R^;6Cs`lq=XPp(GTGf$FYH2vlkR)x;bSSu2)by$Th9FV({bZm2kFDVoyAtUpPv63 zKC-p=Qfm1d?EM9Y!ai7X7vKpG^K-v@3CM2Bq^9~>&MB}c@-;t$$rg8vCW^(XoRB9i zaG*M7jZY=|{Y&FL_cdoboPXoZ9NZtrK5UgJhQyoA7R&@9eint>w^X2KEi0oF&g=bm zXls(1V@>pigfsmU95wnbJ^8A};c}PIeUr6wO)5yY6i6p~*HD7HszoDF?}Q)z;{~ws ztM0MMD07>4-)To5^FRiVum-vPu$M910Mg3z4Qo_q=Uz=LvdzlR;`esJZ+`1%wHo=n zd?SXpm!e|nZW^+w#&1Ri)>T;K0rJ8c#$VoT6s^V-#tWV3pr`UENI)NNKCw3|^xdSfIhd%dTlb4@jj+o1*S1lV?QiPLo;c# zO1S+1ZyI+?eH{T*uqq>NNtnaMZ*aQPB<;dZ=Ow_(u4O7EqF-$b!RKG*BM+mXo+w^$?|Y!zK2gRrT{Gf- z7;VG92}xNFh+QM^1blf&#u$-d3U0MjIujSn7#Om%C9tI?K>NisVl9#DU7Z)@-Z~>Z z#c4dvM`;C&EdJSYyH>l%!dq6yUk3M19}FWxb#&Flv0~(Pt(?IF1re9#$+lZujW4HA4=n|vgpIjC2Y|brbtO`jn+36`s`$K zCwM*}0@_c082p@HuGL~FTYJ+@$-@1$xd~_Ssr%M;3Bt?@d4Pg_JEG38lqEo96i%EK zS_DE6CvE)!g*3Oi z#;g>_RiDIZqXwYzv&^5^AOlnJ^2YvQ)Ri3kf^G&sstfcW&yQTH8*91$zeR10@lAcq?8FKSpU_1$GdGWSNa0x6G#-&Q$HG}o*36+tv+rX)NL zq@|jT{(Y^_(DF%4@_p&Pi_%UL2jGLd^q174;_h&4#Bh8O{nkCXCdi%d^du#bNC-)7 z`-T3P^#@oT2)KiGYR*@Q1T++%|K{%fuKLa5iTF*AXt^@bAq&i=vL5KW+$NYWKnGH@ zvWkL89=aWc1%HefyX!Y@sa2|4V{f|re|E|L^JbOOh67MRIlvGtUpZTXVu8zjj|T0l zYTk|4|N&z_ms!p9}u zD1;NKj%YYki;H(K-!IY;sQn!(Py?d*Bj$+GQD%gR{8=%@x_?rM`-R6AVw-8XZt}gO z_h`Qsc%s8=r90M|c@Nd=XTAe&HJ$m;&f;_zBKD z7Zp2Sro9h9t9tcdlJ*z&hKsMFOCLKD&>Mqi9!uskRLYA{%=zbcd9tzRQxHff`v*n& ze~i=`hHndV*u=3DzSHgZ?|#ToJZzF@P%0)soZJe+eROlz=Gt~vmtVlStA1MvUDeVi z=lRgcfvw@#TuuMIcq!9*0!6sLLepM|NV5~eE1d3xaGRov3Fn)vMa1;4@yWR7?Wdi{ zalV(O)Da&%#yTeb86PJ*>A5JEd_=PkQ48oqSQn=5-;1Z5lXWI^>%Gth=6&k$a&auP zkIyVDa_>4ngN4dHXzslS{1`kC+}xh{+qI89lIlxR_8j^=O-LYdhbCwNkZajvb9lra z*Dcb!Z8WNjq83mmjgI*CXqj2;0X>cU1%H zQOl{NyUvV;J?1j5F}A_*Pma$VA3mf;+COo`&rI+umghC6YsuI1*M;h%eU%M!L%lm) z{#C}Ejq5yqe!wJMu}+3eczKMB)?a26HBFmE;w1NAo<5(?eHW(7#|c;G(1}ghZ~Mv# zS0T0AIt)=&$hS(m8Y=+;;REjuWdUsj(e2rEs-6dk$m6aOIW9R_w7uav*=ZwFG|(Q2 zsr|9c(!^45OnBC|^$vr``ML9l+}>pXx9#(2e9gSy8s-e~`TTX~(_QTM$zb}WPc;0S)$m`|Gk5Q9?mp9DE zdmXYZcba@~>D%&|5z6Z+80GLHTlXF4ioy~J`XW10>TQYOOHDUbdj@N%uBzBIH>vO0 z2&35ZbEE8G_q{3Ne#gt)y1pzs;l)b_Nm}mxdZKU$p@3XPzpFPk+{?W&A>`%B?11rJ zV6gKjex_FYfi-f2dTGOFG!M5t^ZoyC_{Dz}*MC%-_7EU@Q9@0WYY?Y8uB;(jyBHx+ z!B`|(q>Ac#ZPaHQ(S4M=csGYwZ9XfQuxpB@xr?Pl?WPx2gf0`aXV*|;N$|j(q7LIH zq>Mjw9SHuxqG%$Js!f93jSznbcZHGF>fujMgH9Bk|5ocBY{YrACQur@YT91rzft-% z&|$Ln?qU&COzZA7qcI90B5fXhab50?Y=(xpuxPX$yj8LlV@PHzOHC@&EQ23O25FJP ztbpG(Pz;DeapCKl9tS88-j3#$z(CiPkurTPo0S_b)(M_Hp<8*XS)a9IED5_nxc_q2 z$ADV4TTt-=pSr5EOK2C_u^PQTjDlcLV%Z&D!J7y^fK5h$>BCFEmb4QIX?J-OyA~aU zLKGUvhV;3!mB$Fn<9(Qr{+Y(9jseSfv2hAlc}SWNZd$A}&B4x^FpTF3y~k() zn=6wz*U}q;)iKTx(Ny>zju@i}3^17*Zu<)h`tkvt+`ME8o^QDx_e=t7kugGT?eD-T z~vLQ)bT!MOf_mJJ1!aA7Uk?+2UUrXXOc^lP1&(Z&6kM;z{ zym&UZ7oV5(;tqn4D}#z6W^W#PP@QfMTe%3l(TIEvp!u)YKAWM0O?jgi*79u(x^hf8 z@88&Sl@(?jh7E~QbbNZl4e2hNM*AQnE08t3?dPbguM}4R=92X6p<}C+L2k3G4|T%& zjs%D>+aTA&1);2=uGAxd^rCsHd0Q~EP<1blZSQxnLjKj2Ow%bP1lQza`pq0$(>cUP z3fB?gLNlE%x)RqH%r9o2SGz%#I~C6@lv?Ki0uzWBi{Yv5MkPca#?QI za{i`YC8OdGwQ)p@`DxBMCh;VYAw>U*aZ|=TPoG;wkqU0Bp^>2+jr3$OMZRZ`j@Tj? zZDR1#u<+bHwe5HYoo`_i!A8rtgm)pl%`tEbvGnaCaa!`91}QJp}oC<2?njnY2US zoNQy6&(#F6$Q2Gj&1T%Lc{feI8T)OU>rJYpvgHHbi&YfZ#1(f~4w=f^wfQBatc>BC zUXmLn_~KSyvmS1fjs&nhr;F5!M{Jk(uM+3NJMzWp4R%rlI|MP2EC zY*9QC(f$h&?*q&)r03(^ajrVb=b(+q=L*Qt_1(Tn)UWXyOv%N?vv46Tgwo*v33A7Y z3}qe$wBSH3ot;R8G%16(^{-G!Z|z_qN_dPxK}ZreD#3^u!1e83AAzj8DAWDTI?%gW9_Qo<*e+XwWFmZ#b%m?o-0cqTqQBJ( zY=S%UfU05eALu%USqe1xvbepq;q$}Qfm?Mj(uTS?lffM?E@3%_!^)m@2&0L~w+$VN zVJWm^wkQVoc-I2T<3k*Z_iCC$ib6u^ZtYAE?EE#io#!@A+dBM~l5%Uys&IO21_y9n zqa7=2t|X24Sa)YU*!*eqYjxsTdHkd#d_0uF>24^wQQfQ&`0;_0O4+B-HG}?}b2umS z8eVukLYeVrGhgiUf>eLGGAf*mp>3z2w+udI9U11y#v8_Pwzb-Y`}g_JQN;O_M!2cy zQ0E>rrrJt8`x_)eXoxA>_@TFwf4s1jC7plc5b{jy{nqj@y!za9^MlxF4kM_>L6o9& zdBo>)t4%zinK|p&tf_`8AsUvMVAV?Z_|?KV2ezk0%p-dNkwAoI4hnm|P4+R#3G}A( zwfMY#&E?&2>nGuYZC82aborVOW*dq1Ejj^n_XmI8mvHY;F6k?3%N`#-4vIT1BJ&@X zFt3{L_R;jk%**ZfY00jRj#JXXJ5NN*FXqN8>XaK#aNv;|>z1-dO;B$7tR%%IT8U<) z0yN_Ntx*a>xMX?H^JZKk&#O#KDR6#snz;cq%vcBs(_i3CZ1}DME$^rZKMB;C|AX{` z4(+OJ)1bFg6og^24gZNAsV@@8tN-B+oiPhK@IHsv#-n1=&pBL_<7!Ku0+}WIDoJ(S za)a1uje@cw^4emk+0gV6?b-3|Qxv`kyq9q*&#vl{?G7oAKkG!fR-^x#Pxd909Ne{H z8W*`z_HTWJzum$INftzSoB1uQu?ia_N2%Am%9_$aCNkq=gEAj*k$$RY3`@rDPpqYs z>dIOmx2yGhEBE(?J7>fx%a|VL2ejc#Pm(FQMC}EbjD{1SI}v7*c@s4ev2J|6&&(i*)pLs^sMTRU)GH#dpPWYB6zPbqsIs%?8$ClE=acR$hzw!+4t;D$qr_JeJkNrCYeepk_ zMp>Xib6<4oseoyEXh^$BNSIf0mj78Umofs$4Xj@KINba|s``SSo2e)%^gkGT>!>Kh z_TN{KQlvyc=@gJukd~0{?gpj1d!z-VQ|a!K9#ZMmk;x`+lzaUf<8U-!DDDTsMNj@BixN|`Jn`oUJL z)}~snIs^yBKElP47ur~d6s2I0b021V$n2%2E25lp$uDS-xf)StZ5f%{yum0_{ywmu z6Tq7xAGPp)q|$=F9NF@n3GN;53KS~f*AFb}iY$odS z8yOnPVk2a>?;x@j{^l`ipwGy(hzgdxi<`b6jw`F=we5R{fEpT#kj&T@2tlsC{2jAy z0|`cw^T!>w+)(LU&#Uxz`CYiT%R%5P$;H2OWCBL;(KsCgh>&snAYq2jix?_%r11;J z8A+EwUE}CuU9&<3?|aF`n3Br#f$Z5zO~tqYd0=EDXB_B0A)(_)ud=MvCf3`y&2J-I zwxQ=(Ggn{|wt~S5!9W9_Q`>N}xL)Db0Q2oH^nLU7_{|}9Bnm8}u45wTVPn8XtIGCB zx~?B`yah%rE;8h9j| zIlf>0i^-Pv$YtyBf2wPYhHr_%N%4qt#W%f7nkAT>-SgS z-fMH5xA!1@%#1!nnAHCqQ>XV#(dYP;dT|=Kwc*6fv^-X_nr50dYoJY6*vy`2z`k&;UPk)_3{$ z=&l7cp+v`e`Dw08UynmpLJw0VrP%q>7nkAh!UE0c&a8+0Am#oG#8p4ceuNIclY|9` zGH?|YR}g=P^_(Owxf`Vo7950F@Q)~=r`8%P^u{>^>CIvAxf)A9Z5a>kSf%oHw(RQA zduQAtwC0NUlUdp}Xp9oGB9mdEFy16>j#&Avg=zstutDIROPt)cI>zf{$0+K-t8tp; z)TSDuLlYcBc`uKkW6U zS_mJJF4TB)rFZ`PoB2~Mp~|lx4l2DOLzx=YRc3u%jG(^-Y)Gn0M~*FxUSy*6FpOU~ zZacj=j;<8)QYKZKEV{7gXABP9!O{L^c1Zc~8~gE%FvnxEl8OwUy{? z$;=@p@Nd!JPk6Auklu+oppcwv-rZNBOz7P`ZN|^5g+DtE6J9vQPZ1NP#KKLv92a<| zb0lODjV1!i*VWfJYH3lxViqTKSyIGpiK28#ARVDx(LzFG9zNjQUq(anVfNr3e)qZU zGBcNIrUNpA#nufzpL?!WR}#Z{#l6jE?h6|X=>A+?!S|5*-73nKyG-6}=TO~&;KC}&)TPiX# zTZXPU#<}U3GEt8e$1l1A-jg_+nv1+0O?f_Hc#iCxqqZkK}TMNodgA^z3}A>RGN74O-{i5keP_CbRZ(A)ih-#1`WZb>t;zefsan1QwD93v#aY z$4^b|6`^ii7T;Z(vfScU-R#gxm)Hd`A&cj2)XtQAOOPYNG6ty4>{m`FBlFu4ZQmVL zY_XL-ksb_6@_wYP#_ra05j=IZrYFu)FOKptetkvTdEr^&y>C$B?Kl$m;hBlVw^P^c z{r>svL7ts?)ZVMj7yFftW918#NWW ztGH-O1N+MI=N7{UBm6{7V|jh)s^P^q=ZrY2tCXk$0@}zS0na#Bk^R9EJlnUHp@c7y zr-;g2V1|Rt-VO!lYft%9(adMX36FSX^VXL~5r+}qG6({YVszuLKX>*en`HsjQR zcQ9I``zLmz1N&04O}3{?<$q>gBE<&Y3K5ce2od(;v86t$(rL93J^Su~)RIZLZ3LFK zCncB#_KwwW$8e>XP|#lN(OlXrDJ^wW09EkkJCWS0+`@+ov(Jd4&dc2V2n|(N*GQk3 zdv98E6wvLsBND}jQkoe3r;X#)VS!}`rz6$#c-?jdNaLZvZ97B=|G1ZlWQIVt!>fTD zwbs#B^nM+F;ymOFWih1x(SBcuQ}u#KEZe6^@HGX}^?2MLZRkmH$#aAQ(ZMX=2F`q? zkgp)9iSy6OQwgl>P1)IZ5o197#{aO8={KSr^yB=f{S!@gdqK~#>~nCCSC;L;9`%Af z;?J{|Vg-%LC1J!M8wx4Al_4>oiP7gVFL#RCD7mv?wg)f-?$7o2KQHb7L9UmDMS1)% zq|Ryj=N3i2&E=eucxjeSP-dqJUz9RL7+5Z)8S4qgvBZtd^#< zh%c-DMDy+Su9sN$UZiR|qunbz-hn{D;ycH`gIG>Sr^t;45e#2gKg#73HZ^?WGbT%S zFw*?&wm*Ic-XFnel%Qk@uugU++}R0=@kh>B^&^X=$E!~vu6HOVx+lHAE4AK9qiLQj z^5tp1t3uwDJU(9Jh}doA)kVIu=1C!=Gsd=Dd+IKNj0_{sP;r^CHFw zX}e}6X(BBrcOgyWx{)Q&>T6?v<3E!Ei6-i5!82NKQ}b|IcVx_Qe|a}P&$B}E#(w0O z_-7l^$^ucf?hL_!O4_|(ltRGX<^VI7XOh-^x^{Qa>i+%BX7G;tZ`agP%cb*SPVef$ zIi_4!=E-ME=*&?z9RzAAdP7t<`J_3)l z5i(}}VJ?(L5E?i}^&vl69M~Bdx-`Vz6Z#qW5PFa(>&t6hMffEEWWDwF7pJ%E@oC^? zG2&^j&hQT$5-r<5vG+tsrvWtWQcnyM6zcE;;-&-Z#qLDS&#zH@{3SF18K{4HP)A?j zWwu~iB7dNv)f;vXMZWu`T%h5tt$4RulSkZgKDBs$VLh5}f4};f7_o;QREGI_vH@fd z-k!xlH#GpA_<~cO)>K|!&Y!R7PV$I)A*FktJmWmMh~7%8Jy%2y6w(G;Bu;^^nB_2ZfT>0{RVTU>gxnjP43Z#k#7T4vIhkgfnGA7d<+)n` z@>$=XN1Nu5eE+-i#ORS4kG1DI-7T=0SL2R_r0<|xBRXQiY4i7usuK9f^RaJQs{@Ee z{Ja*qcPz1Y47*Mhcwtg|6o?ER-=(|nKI60>Sx3?B_-=H{m*l$N zA39O838ORedsw17UysM%UF6o2(sa5!e^%)y1q^YExEJ}ohA_M~o21poK1M6>n={LM z9EeumJn^%9@^dBGXU##C4w$gAz2R)XhPj=gFZ|aW_&=}k95%`$;Ayfzo(4X!25g_o zwt8Q!U^5=LO98uL!zu3rfhDicqM_LNfIR{8cOi>*jf2m_9DL*Wm7|JES@x9zeA|t! z_zU}8xKhFYZo9@(cLY7!&t`{dcAExcIZx_#vHewC0mW&sweXf4eI)%xfX38kH?dHv z#vaMAY&NPCiKgZ2#-K(Y@(d*xJEd1xMbT(3mL#`;p;SYsh;NtjpU~O2;mLuC)mTJR zv%qHb!wal2mj_I>sa*fUGjF^12qGSoxY{Lzzo*7LupB4Y>nnGtxRU7#X=d_Ar)snd zfEbeaq;9FBi~l(hIw~tPr?-zOn{o7fEo9tdcC+ESC*|4nCeBv>X%$(!!93n;UGa7g zk1!M_Q|66QxgmO2JCsCZv{wavWe-DnSm*oRBt_=Q%r~sn*^NEsc5XCA2)>cahcjAd z9uYD3PfdD<^e@YXBVpmCamUSJj%sob$Ll4+v%*3Id&SUDuwBbs=LLh%vCjzf%_)BQ z#axjA^+cGXu%jsH5qwE*q2qSeY0K$V>mlsw%_CP9&>!)t5(Lp4P|4F4p$59+@o>2|q27Y#mb(Uq|- z9x^ZN)iL$E*d5uQMBSf+%@?v)FnW_dtieHFGX0>Rog{JO_Q<>iTG+ZYUzPnyi`B#t=+b$XnuT+B4k zd~YV=d5UgvEe)EzXqK;1B`s#?F%#qiiq4)p?M~H1C*XXMLwJzO-;JSm_HMQvXNJ`t zRUy6Hz~=4$P)yT7^0htosU;P9gY}z%?Y=B>7RcRvzSHdl$I)0kPCM0wzxNe^*9>Z} zgm(S|kXmD80vdJoi=B6`{_L=w4kA5jBbQH`kH*mB&F}(d-h;Tzo!esq z?-Y5Re^i;K3#PVyuj$a7Od6&;UH@}%1>)WzxjIEZza$A`d$!;Ea~3Zxn)zy&%?;01 z(Cq&%PR|LVur}|1@B$W#cd`Ppb8gPIRV^(UBT2ZUqIlN7AK=f8NPGg)eiy)5>dd*6 zcn{Jp#A48r0+>pP0G1V9jLf+ctvJUgdfiag<;J z{>l=aOf)&069e+A7GB#?^U(}>VDCNu5my0rvqjABPqJF*uUqh>hy_?C{^kb@C$n=F ztQ2axPMy$<(Y?nYf>%hzkZX4OQ8W^*Ifw`xBH4)g{Rk#+>w88)%I|&+-pTh_gI9>7 zg*~B%>{4QtG-nE*PjQ*C-{H>=&OmPBZrT^W{my)O8Lmnz54l)Ecx%xo6Fom-EpI^$6MMoZ{JG2`Gk?3k~N-zP2N3PzOP}u?4 z29#%6`6@kksRyj)DB+~USf=@D&p^l`$6f5)l=KVCV?5b2mVmF?ieRh zCX5!!aH{3yN{Q|C_vSBnvf=$56%Ji^?Ib^Sw5_-V{CPT?nNV+z=QF#uFPGM-or`Qg zM)nTO@c|96e=u5g^UU%08#QvB+*=I|e&#fB`9(tmb;V6_tCUolcZxbLG_v42vS~%>34C=1-94xyX9^PUtRbb7D(UD z;abpRP(Oi`VMzVXQykn7;;{#&Q>F9@*8_ zH6{%3e%F=NV?C7Yn~KWXFOg}zWNOImOKH14OLTc`Ee(#gkhqMbfxoc|!M6W+mJHyu zIVzS^WRd-xKYG{{Vr1fv2cK1{CnRY|Nt}J75=XtHgbDmES6m-D?J(cE8Mj(= z5T|2Wft9UvuD9}yC)GZd!~ zaJP)k@Vnhje}B)K4t;cO1Mn*`kKk!AV2jN_Lleklzaj@%M9>ou5$TTIx|J!|jRFij zknrC=j%aeZz`J?{%8v%D*MNIO96QAfHcSf;HS_ZFKJ(r6cyxW^+bhbofX$Sj14gkE z0C;rra9HjU!O*oTMD!$Ys$BJqJaSKq`yKfXT9~qDH4phX6*&faYd{AX3it#xF3e{4 zJlyOaO zf62f9)W@~l_CCEc1#xuzVBa%?#cj!9-N+|a@4+ES(o9w5P5lklW~Lua^Xzcc;=E^ro z{B~X4OCdKY1neb!HKqjl2!9nPSc@;CEcGf8*aZ%&;_nZD!VWIE9Cdzptr+L3oBH1@ z5dN1!?ths;)l#8UfcHv-Q(IaD763A3ab6y+h3xk8fazG}2LN7)F~rQwoCkn5`FR=! z>S>hpRHXIM$THdg{{%|sbc4z8=J{G~{;wJda<852pyc;%p}_XsqrZrjLEAOp!(Pl@ z>%DNwd*jYai$OC!W+Yihmsb?5S7iN!ps3VZxGCznWS>Qpmhw9hH|n5GVL}is<@BV5 z{@ovca6B@0dhhf}hfdFXSJxyaTR#J#&%M3HJA_i=_UkX~%zA^t^G6z;fPX0Dvb{Ng z5&Lit&*1$zxbW2{jR^{*R`-w6KSex*Zvutg^Ht1?63~2>(8$-Ifhu3BLnz)Q!fKA4 z_yHGDPyB@h`p+;2#Z70W;gn)vx z&qL62{d^{)#NTHqa_F2Xx!ii}3Ne3&-O*TLdN3~Yd&wK!{l)92Xma#H#5zx&`Ufd} zen}aW)ItGRs3IYK#`6F6Y-2NDS;g=(#_N~J+3u4Ow&9LPt^G;0%?Kaok)`_P5+-e( z;p#e$t2BU8*T&JXztXg=6a0U977S4`ybpQ30JC%x>5hZh#UxJ+RaH^8wrlEi;0?jT z@nr!Cx!wBY^6==|28j6;w92DGgK{(jkCt35=tn>i3*VF9BPZ(J^SW5V`lU zNhzON-iWMq{sm=3Fuos8KC0zH*3EMbc1h}(iZA3}GOsr^V@dN$(<20Da}_qHN>pea z0+PiP3am)fWc&X7s42Xs-|Tk3US;9amv`B2YhnAGZ&(|A%H7jxIRI;orkQ5AJmD+?G%WnB+} z_RG?)yKwthOB!ySso^w5!g1T#-pV^@3frxU!69e9|RMCIMK7Gp>1JUZ9io?(>HDYit+)Z70@9$ar^ZV>)Yx?RqhfpunkG-U{3N8HPmJh}t8d&-o|B$-n4UzZ^Zsss zdnGixe+9Hee@B_9%6vgEPv09}GLcn|$4O8QhlYPpa7#M-1rhp-)C~Q;s9|8qK&Q8^ zMVjWJPI|C|{z}|)%m=mY_}$DQ$_vlYKs34>ru)!K=S$m}FuJ_A8@BL{D3LHy$Tuym z1Wn?440?|b=;6rk%R2${N@p7;`!gI)r-*J)a5PQui$J#-l+mmRJ90`|A7C?pxdo(an-KOnqAb_uznt_4BcDg(H_UBi9otE4yT*I;Tx~c7!ejgQo;Y+cLe2`9)&w2He z?t^_sfaLEmm9-|x{1lVwT(ty!{hbuE(r!27njJ5V^JdMY?tyIiNrxxtC3e6Rh@KZo}$GRi8W2fd~( zYxIf~%mZAcvP+ZfywBBO7uT3($dN{ z8N`_og63@D?Ndm2`lBxx5a!=$tCQb36emvTS}u>q(3X9ud^N4S@-;O`o1S$U{KHvE zski%U2j4q_cd!NH!7vZcq_9Pz{8dp+b@!?My}d!|pbeq}WP*Xx8=r?Ph5KNIydpN4 z@mHI+@bL6OzTY?QNaiO;?u|Zosb7kk-1cSb5rZOhPE+se)$n%4>(VsJ6$g36MrmZ; zZ!u&pC4E8*TO&`qj^!2zwB&!;x4HCP%*oK?(z7?-mKRYhCRN8WCf%1S=yj-0{z`n| z(*?nZ`;4e^vrMilHEwJy7rhbmYIP3YoZ>!ic0#d#B`6qPjVNT0|5Q@a(mg}P!?#8f zNFbW^3hy=h%@bll8{Id=m&%{)wn<9s2^L7=Zl!Mu>gjzgN?P;$s_y`GeMnDyEhNV0 z_ow3ax}J825%2Q`bU(2xy))wbM`Qw{Y5}c&&4JsGjuy|eokt_pSQ^QRpXM3!S%sql zXD?a-A2uh^tlz)m+?HK6n;0jW-H*Ini2(Mk(EYBWWv1_Cw(|&Yp~3v;$nGlTzWSL4 zaf*fH@gAD7DW2f35z{?T>$vhjVO6M`bq_PHMFiAP_k5hMX5O>hEsw`8;u<(MeD<~T zegAQ8vhpz~f0BGX+Zty1I9+j3dfj&7k4`Qn<<_T~D z5gl@CV52It$Hw`~V+a693}VUpZg2EGHxoJi;MX(zCChVdKpQQ zJQ#v>gz_eaE`Rqujzif#p!|yS`xkh-OMjh7uBe2FXnE(4@=Z#+GU(;9Y&>ktGv%1A z^3#DHS-46yvXVaDB$r<*f|BwjQeX9#lcV>>KV)1Hv%B0n3m89MD@i-gP7P4%Geb`Z z-31+@z1H9%H37Q8WOsrZG_x-=c&peNbJV^fhcAa{X3qp#NBR2c;JdylP%*;L_YPcW zAO$rN`&p1}B(hCm|17ePnH1BR-RiM|x-)DJDIy=yW`vik)b@rCw|9duuMjo`Ng?N@ zKZ4cAxp}@hYTI_>GKizR^S;P75Djtf%l_yR83%u0+V;2~nV^y+bqDAE0L_OtaUybO zyKW5O>qJSlYWC%W7n}PvGiv>VEj%m+vol?LuE|by|0?duSPFpb#oR07xjbU*w2|reM@)-h6 z>0T>>OFGTQnD-CWKi`{MahKETT)350)N!+dcc=mG%q!n*eu(8k#X{sgz!3}+1ej10 z0FkeY9*!0mfW8SRBba<79~jE>T!+L6-zc)a(T^(*5VIL!k7X`qSAUoBggjGXBS-k< zRHBFcX@Nt`(%~JxQd9xU{ems{-6)p!Tz>OHrwf;1Kk9K`bc4P9$zTY(O} zO=#kb;Qr$zH~MB|5Dz1Um-IY^PwPxrHrfIeK1)gIrLZmh59uP@xr$PPlkzLa_Z|z{ zXE^U`CAv&M2(~akd7jA*^69J zFeS)W8OHu$Q$#uLK;_NdH$9J6KkPU6win!c6+z#>&pCa(**wWgXPOux*<&LPx5d*O2bL_#ud4tP`8C>G;9h*CPH68ZF&*}=Me-$?FiqI0VoTs*w+dGSON2X=TW@444hBrN`H*TvP4dsxd|<*RfLeQ1V03F*||AB zm1YJ^bK*fNnRaWRlP+{EJYfJ9?2&_&!2Jg(LkiyqdRPmKi|^(OnZ{@dFo3_|UP6T6 zYdEJf-++=sFho>xiJ?imb65r5+3K91@_NZ`;30e2liM#n{0BtpY3FX0drj; z$?ge@a8JhXA`yru_*v?js`8!aYRa>$j5hT;NDq90pcSK~-|UeNc}#tA^b&@XmJ5kgQ>1Ok#qoo}?b&UkfGt zl@JuvLH}t{T*>kd-Qa5?*M4P`uB8QyCCMVzVg#&|LdKYef}%W7u6AmcF!5>SZyAzH z&E9g(+SuC2gOG#ni)ozvs@Ul08IiX-d)5&H{+inPSa+pR4dMljK5fUrKm`4LhDAf9g@^EU@rW5 zWA8+BcuN`?aEOy)-0uPw>BTbS?^+<=Js2onW0!OUJ#;nHcK6@}=_#)!h>%f~${SOhFyOAz^BdxeRyA^gE3-N>dJA_2A2WfZ zJ#3)nDSMqY$MEP(7lzh{>re2`V`4A>+uH@e4zzF!yL?}2hi(GRF{1Wsabk9(Cu_Zs z+kxL-2X_=fxA*`GHnpPp5PU0^x*RfFZ=#;o9YHi0iAp;`0l*=!7IYgOsO~Q+L5U<5ZHGMRvf0|zI6=D-4$?#>k=jez9(*#DEofCzL)Qz%Tm;kIWp z*-+scwvXDsH$6Q~cP6nIC#%z2K5p^XjI;m40R7W9Ubo@ama59y@@M>f0?ZlL1 zvTDI^?|px?eFh#-BN>_&!_i3ONx6>}FK=PtfllEfRkvN($5s*Lgjv@%eOvfsWcb;gLtMoztyq1P+dh>kT z@MA04;zj&ynANJG7X3gQ-T8a3AIkhPqWYSq&}fhl>lR#7O=CPEzD?@tVGCq&e|vGh z2zk&j7!1>{nRxi8mL@rv0*DSG0E^}nJYXX9y~^khGT$SR5%`ElPSBt2JmMrU-v*f` zUdysJiTMqwZ<4vq`ICd-j>No9c^c330rGe{fSEi8BH$+tNQ1rMEpVXZ=`%b`$^;>3 z8qBxAFHi)GkU=KHjZ{GYCQU2d_7%E+K^LP}trnfO_TYLg&&jMFlYH3X%n$AB$1~&R zV+)KaG7K2Is`cq>4SZ6*{+CGn!apjaqcwUc3&4N;c~Z4CHBT>>HxNGK3-cVye(#Cb z5lED;BEuRNBbF1kF7sadmmc=7BgL0)P4efhSatbs34b$Av#uv;73#j?&?k}xtjYq3=-m_!YR}2Vi*0BH<8Ccx zz(GYeB`jk;pat%t1?A^YvG&fisGyQ8TsClQ*=}XVV>R+upn&v3oJ<9*Y6sN?6QzBr1q=yAo4lhtcjf6ix6I9l@z|> z!cCQ-tMJvQ@;uPAR57$Aup(-n3w?f_>m@Ti`x$5zrh>X;+U8~(HHjnhDchJIB7P&x zuV2TPXp7SCPey}lyOX~p6Y2g!_a;fCqQs!=J86B=t=xNdQ8Kj~YUeNEX&bF7cqfBu zk${t*!*zYDLrm%_&=N+tjNDCeo+x3X)l=J4)6WwA6h7yZbn)2cWV_BllQE(smR`SK#&**3$RA z+@Jp)aHnhEO2_oobQ2&nK++97)=(b_P-hDvic&@V7gMTqYxfk0YxFhsDuCFK!>HPo zdByerc>xq`>`*e2J%bVHyWsf(jEUbL?hyA7L_drxmJ_EnWZ;oW^9%;L?%~FeK2GJb z%>f`%DjM$gQnL$-Xh;$2)De^QVRa@K6TjYLQt%JFpINWh!mD%LukC$&Tb1Ku&XoSQ zp0eP-{4{Wi{NmMU1y2PC~Z0mA*|wFVe3xB|uxKGJQ%|ygC<` z2SUi>plXJmN(oDD~@Ywoet zjIS;`6}D$|+EG$oFEBdic|@}|aAUN#m3KWcjVoR4suprM8M7xU$Z)#;2IN*{we0m4 zFAfKARJrW#1#L!qfDUcSd$DY>E}ZY&KUlGlrk_2{TzL8=0mt|IT`Ch^L(C#*n;a37 z-T6pbO5RunB?BY{Qre?q5TCKLwVuaK`N4D{Iez!I z&mQ@xFCWTkaZs2w!k85nC7HQqA|BsnWB(#xWMs-E<19IJt^$9-yeviYKSJQ+oJtqR zzmBAS>}hm2k^LLNDs*{Xi=`Ro0WVf*6dAjG*QK%%hu=TT+V&VdHZp?~T7Kll^vYZ1 zJ9X;3oNFXcK+y6otFC2Jd9ku4pc7)WcpN&p*$U#!=Ue?#iK$6&2x7`QR*5p z6#i7c&0{}9Uu2yws3%mEZW6?KqPnK>3lL;Hl`D?mXs}1!rVf$zP+Bv7>MD0Ly30ch zbTMPF&c{<57=7svdKYsA{X>tCx_NxkZ&UHw+0pt=9($O*worG+tg{Nv@VfOkL+b1x zE`*4jE}YvMF*;>iFfb$mzMi9MF|ptHoN8M3QFifS>Q^rNVuZ7hdq0r%Xa(!Ya*Aldez*ysJg(O(C}s+#kMKZWcx}W=?p(|o(wC`4 z5sb&$c+6;X!6zjtDU|6!lB(ZP3_U5GKBd0Eh+53zr zryq5V%f#cFErN@tq>HYfPqt>6|H0>!1~6J4ypk>-07PGb(eD_E+u`)<&mzj%LLB(Tjkjk@&w_VyXjXJuLOSott3-yBG#6u?w|Hte!u8bg`?$~nin!XIqA zBvd|jADShmBYXP;XR9om*@?i%Hd^x;>FbqxzyhyOjm2q@phl)ULq>V*8 zK6@JGX$Sj>$XFiO=}0fJ*t~twdTK0haM%3{(b`b?rF~%MK+!s%;yU7_ci%e2^SQ|h z#bF)RaQldB@e$%B-{p8Q?woz^O09|hFLG~Ff@!t${ND-9KaLCecwaajmh+Q-i1iYz zMLXd6J>W>^J_gU-34262IK0Ubw#qk{tTA{1SVC6M_ zjkSLOd3e%Xu64|g_8j}E#tVNHabfrV4c@qO6t<~oLEJ4{UZGQIC3jrAh&F-Gp4pyL zo8X_W7q|0aVtgHbp}tC2LY&g++yyQ5cYEKyvvS|w^Au@Hz(alQDJ>yAqf$shSNA$b zPbG9v+6#t({r4k9plV=hJsaUapEHdf-=D8ZtwU}A8@a$}V*W;R=vCd`G;L>)@YDi` z-7%nNA(tx=`3P6ZSn<2F{l#giGPd%{Z0&FGIpFa$0dRLM=6`=x)7NL&b9IG_%4evk zt0xvFSrn$b#d*z5o&t1@XWomp4dVc`i=>>eiB=N80ml z048e|uz>`dYOsg+tZOt7;8tnT{pMMI?mrvAx=3xdX5cN zzcK5-q2ibv3b`+*D1CauR&Yp~Kl!Kc_|=0ur-Q04U3iDhmK^fEQ^)+%mW9(N0gPg* zg-K`b(A#VYp9>qeh6o~j-&5(%y_*dk?|m$9b-l2e z9&qCdpY{KCtpt(T+M82WQkn$JR(I|tC+BPzwj#Hyqil0G@E8DYPMh<9Atf!6X0e

ONFa(LeTB6C;JSvardGmrz7FA1@6UFF>a?(0|h=om!16Q z3Xo+V^A$+Y5i^v6w%6HIm zYV|qs0-J25(}b7kW&EvtCdg6#RvFtjMBG!7Ooh)(im}qELg9kt!9V5j44b68%Xnjf z|KXvM!>*Qt%3*2czQ{WH!|kGMX))JyL{Sb?sQ0-RuE^78avm?G@H-OF#Vw2UM`B}K zC9^jQ&Y7fD@Vt-3?^Fek+1ieppcylsAT{)d;*1H4^waSNWg-@=$ja=?jc?QHIH5p# zUN;gwg31s+l3!1Ml5mz0FmQTvK8?*FV>EbHLK7K=Q)@YtEA1HpLRS;Lrrl;rDPc}5 zPtrXGQ&RWY4+n_6|da?7u`` z6Bn*O8Ia@R{-lXcKGu7)+ArsOb~Me}a{QU^sO4DQ#c72VZUQ4fR;-RGwzkXZSCxdqm%8L z0^AZU0GTka*<;Uf0f2@&@5K`Umnxlh3vmTPaNj>N(GyoH+itC-w?-Sny;UIfx)ez1 zh!N6K!oqS2^X~oZkEVovZV9Gk-L~&@OAc&Z^LR825BRbVpj}@7;zU+8#!zZ9-NT*) zHzaMn0V8pIy;~c=p1&aTb@_GtvK$&Un8`h+b@#5pg^|tWii&(hVLZ8g-{!DhH-utn zq+aGP_;S%;x1lX@uh!I_&Dq3x%)sm~{GU5c);X>g(3AgkJXbc?5rVZZqKZvUR9b^2 znx%!2U^D^#oa-)2)?KLEyi`YjR2|}8b}v7-ie0v#+#GB%kpp}0G@C>qs%w|%Hr2>i zSRU5FT*AE+n7YSY=xWm6PdJ5h>vVadZ3PvwFd;bL{Ha^_T}`+!@K*zzJA0(=t5mIi`c`>x>fg6y`&QvEL6VB|j&^Cn@3JG%-TG zfD$Zd+B-Cc2lxb?31w-@-0F{>wu1AEmWpfCisI7{H!T5oOf~gmzak$(N=ICohK2NI z@WSunvhd241<&XE32tBX9?_oehStYH-4_TEB1N^QaC-C7&EEFUj>Z@H;T_vWr5e9deu5KBg3xKX$Je-P6-Jz z&zTNXwqx85mh$T*Z(lugj4Ai_UQeA7{{k&-;aj|ZrL0(;4y~NYR*r}?jEy;~3tSwo z0!BgYhoTrSH}zePAA0@-_`aV*Ov0a-)F+kvCb1Y=Wp!CmUQ{_cw7pY*yQhmg*Yg@V zKSbDJMJDayW$Gd6JN^<$VNVRF*z`G7n?VKaH#S)eN1OQuFuj^dJmVQC*LNA}+Dc4? zow-XlTb36CzMfFdNx*R?ivh{&u##0O-!A`CXJ6I;#AY ziq&g&v#rr!H*8xfC(Ly-dhtM${SZQ8mj&qM%f8V^mWGrA;ME2fSb4()Fim3R8Wp^= z(O&ZfICFMsc=1*rfs~%C7PugUCgR*nK%HpLKk-;6?yOClq4BFcre>+Z!LI)xV8Ri2 z9VL75Z<`>j3j8eMxstOdSCw+(aWnUtlEm!7Ab0AAwv_dD!sZn!ESIh7hU8~8ycTR6 z#(w`Il#&<561OdyZ5cK`gJbH^qw46ZxFb0l^QSHwF&6QxAR5_rfp6fCQHc_|uY{Ai zf^-)SDfa3{`o-#&z≪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

>e`o~ug>Zk?Nr-k&$F+Dm$==)K6MyXZX!@( zaJQjDVYB}f>w>Spi_k%ena&mumepo(NQwPf)WRo!9!MLf2xqj9L=>LOqyUo%mI8AD zPfw4^ifs_s4s@pZm$2222UqU0|{xQL(_p(_3ICou`UHGxriP__t1#Y&;* z^x}BTpdotY7o~u_YeAu|%5yL;aYewcyJhfsY%)~IvxKd`HfsZkX!Z-*53n@X09==@ z1zkDxW)11RJ@)Xir9_`96sBoVv*W#o>Lx9sKN+7T5oW@Sq-H%^dO%hF8z10DX`Daw ziQn_e9*BiW5U32@O?;bzTh&#X=H<#>fX>dE#}l{qKUwL^u1hv66FH(YQfI(2-~

e0>=uj>N*Zm+5+-($D&uNbnDIavL}E-Q)WJ) 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

yR8$$jZXviPUPQ87mE$Y50Os|8g(qko*pn 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

3x#Ga=Q+BOkV5NJmiTlwY7z+UetM_ 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 + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/MANUAL b/MANUAL new file mode 100644 index 0000000..56eb557 --- /dev/null +++ b/MANUAL @@ -0,0 +1,1467 @@ + +Introduction +============ + +What is HISAT2? +----------------- + +HISAT2 is a fast and sensitive alignment program for mapping next-generation sequencing reads +(whole-genome, transcriptome, and exome sequencing data) against the general human population +(as well as against a single reference genome). Based on [GCSA] (an extension of [BWT] for a graph), we designed and implemented a graph FM index (GFM), +an original approach and its first implementation to the best of our knowledge. +In addition to using one global GFM index that represents general population, +HISAT2 uses a large set of small GFM indexes that collectively cover the whole genome +(each index representing a genomic region of 56 Kbp, with 55,000 indexes needed to cover human population). +These small indexes (called local indexes) combined with several alignment strategies enable effective alignment of sequencing reads. +This new indexing scheme is called Hierarchical Graph FM index (HGFM). +We have developed HISAT 2 based on the [HISAT] and [Bowtie2] implementations. +HISAT2 outputs alignments in [SAM] format, enabling interoperation with a large number of other tools (e.g. [SAMtools], [GATK]) that use SAM. +HISAT2 is distributed under the [GPLv3 license], and it runs on the command line under +Linux, Mac OS X and Windows. + +[HISAT2]: http://ccb.jhu.edu/software/hisat2 +[HISAT]: http://ccb.jhu.edu/software/hisat +[Bowtie2]: http://bowtie-bio.sf.net/bowtie2 +[Bowtie]: http://bowtie-bio.sf.net +[Bowtie1]: http://bowtie-bio.sf.net +[GCSA]: http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=6698337&tag=1 +[Burrows-Wheeler Transform]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[BWT]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[FM Index]: http://en.wikipedia.org/wiki/FM-index +[SAM]: http://samtools.sourceforge.net/SAM1.pdf +[SAMtools]: http://samtools.sourceforge.net +[GATK]: http://www.broadinstitute.org/gsa/wiki/index.php/The_Genome_Analysis_Toolkit +[TopHat2]: http://ccb.jhu.edu/software/tophat +[Cufflinks]: http://cufflinks.cbcb.umd.edu/ +[Crossbow]: http://bowtie-bio.sf.net/crossbow +[Myrna]: http://bowtie-bio.sf.net/myrna +[Bowtie paper]: http://genomebiology.com/2009/10/3/R25 +[GPLv3 license]: http://www.gnu.org/licenses/gpl-3.0.html + +Obtaining HISAT2 +================== + +Download HISAT2 sources and binaries from the Releases sections on the right side. +Binaries are available for Intel architectures (`x86_64`) running Linux, and Mac OS X. + +Building from source +-------------------- + +Building HISAT2 from source requires a GNU-like environment with GCC, GNU Make +and other basics. It should be possible to build HISAT2 on most vanilla Linux +installations or on a Mac installation with [Xcode] installed. HISAT2 can +also be built on Windows using [Cygwin] or [MinGW] (MinGW recommended). For a +MinGW build the choice of what compiler is to be used is important since this +will determine if a 32 or 64 bit code can be successfully compiled using it. If +there is a need to generate both 32 and 64 bit on the same machine then a multilib +MinGW has to be properly installed. [MSYS], the [zlib] library, and depending on +architecture [pthreads] library are also required. We are recommending a 64 bit +build since it has some clear advantages in real life research problems. In order +to simplify the MinGW setup it might be worth investigating popular MinGW personal +builds since these are coming already prepared with most of the toolchains needed. + +First, download the [source package] from the Releases section on the right side. +Unzip the file, change to the unzipped directory, and build the +HISAT2 tools by running GNU `make` (usually with the command `make`, but +sometimes with `gmake`) with no arguments. If building with MinGW, run `make` +from the MSYS environment. + +HISAT2 is using the multithreading software model in order to speed up +execution times on SMP architectures where this is possible. On POSIX +platforms (like linux, Mac OS, etc) it needs the pthread library. Although +it is possible to use pthread library on non-POSIX platform like Windows, due +to performance reasons HISAT2 will try to use Windows native multithreading +if possible. + +For the support of SRA data access in HISAT2, please download and install the [NCBI-NGS] toolkit. +When running `make`, specify additional variables as follow. +`make USE_SRA=1 NCBI_NGS_DIR=/path/to/NCBI-NGS-directory NCBI_VDB_DIR=/path/to/NCBI-NGS-directory`, +where `NCBI_NGS_DIR` and `NCBI_VDB_DIR` will be used in Makefile for -I and -L compilation options. +For example, $(NCBI_NGS_DIR)/include and $(NCBI_NGS_DIR)/lib64 will be used. + +[Cygwin]: http://www.cygwin.com/ +[MinGW]: http://www.mingw.org/ +[MSYS]: http://www.mingw.org/wiki/msys +[zlib]: http://cygwin.com/packages/mingw-zlib/ +[pthreads]: http://sourceware.org/pthreads-win32/ +[GnuWin32]: http://gnuwin32.sf.net/packages/coreutils.htm +[Download]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/ +[sourceforge site]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/ +[source package]: http://ccb.jhu.edu/software/hisat2/downloads/hisat2-2.0.0-beta-source.zip +[Xcode]: http://developer.apple.com/xcode/ +[NCBI-NGS]: https://github.com/ncbi/ngs/wiki/Downloads + +Running HISAT2 +============= + +Adding to PATH +-------------- + +By adding your new HISAT2 directory to your [PATH environment variable], you +ensure that whenever you run `hisat2`, `hisat2-build` or `hisat2-inspect` +from the command line, you will get the version you just installed without +having to specify the entire path. This is recommended for most users. To do +this, follow your operating system's instructions for adding the directory to +your [PATH]. + +If you would like to install HISAT2 by copying the HISAT2 executable files +to an existing directory in your [PATH], make sure that you copy all the +executables, including `hisat2`, `hisat2-align-s`, `hisat2-align-l`, `hisat2-build`, `hisat2-build-s`, `hisat2-build-l`, `hisat2-inspect`, `hisat2-inspect-s` and +`hisat2-inspect-l`. + +[PATH environment variable]: http://en.wikipedia.org/wiki/PATH_(variable) +[PATH]: http://en.wikipedia.org/wiki/PATH_(variable) + +Reporting +--------- + +The reporting mode governs how many alignments HISAT2 looks for, and how to +report them. + +In general, when we say that a read has an alignment, we mean that it has a +[valid alignment]. When we say that a read has multiple alignments, we mean +that it has multiple alignments that are valid and distinct from one another. + +By default, HISAT2 may soft-clip reads near their 5' and 3' ends. Users can control this behavior by setting different penalties for soft-clipping (`--sp`) or by disallowing soft-clipping (`--no-softclip`). + +### Distinct alignments map a read to different places + +Two alignments for the same individual read are "distinct" if they map the same +read to different places. Specifically, we say that two alignments are distinct +if there are no alignment positions where a particular read offset is aligned +opposite a particular reference offset in both alignments with the same +orientation. E.g. if the first alignment is in the forward orientation and +aligns the read character at read offset 10 to the reference character at +chromosome 3, offset 3,445,245, and the second alignment is also in the forward +orientation and also aligns the read character at read offset 10 to the +reference character at chromosome 3, offset 3,445,245, they are not distinct +alignments. + +Two alignments for the same pair are distinct if either the mate 1s in the two +paired-end alignments are distinct or the mate 2s in the two alignments are +distinct or both. + +### Default mode: search for one or more alignments, report each + +HISAT2 searches for up to N distinct, primary alignments for +each read, where N equals the integer specified with the `-k` parameter. +Primary alignments mean alignments whose alignment score is equal or higher than any other alignments. +It is possible that multiple distinct alignments have the same score. +That is, if `-k 2` is specified, HISAT2 will search for at most 2 distinct +alignments. The alignment score for a paired-end alignment equals the sum of the +alignment scores of the individual mates. Each reported read or pair alignment +beyond the first has the SAM 'secondary' bit (which equals 256) set in its FLAGS +field. See the [SAM specification] for details. + +HISAT2 does not "find" alignments in any specific order, so for reads that +have more than N distinct, valid alignments, HISAT2 does not guarantee that +the N alignments reported are the best possible in terms of alignment score. +Still, this mode can be effective and fast in situations where the user cares +more about whether a read aligns (or aligns a certain number of times) than +where exactly it originated. + +[SAM specification]: http://samtools.sourceforge.net/SAM1.pdf + +Alignment summary +------------------ + +When HISAT2 finishes running, it prints messages summarizing what happened. +These messages are printed to the "standard error" ("stderr") filehandle. For +datasets consisting of unpaired reads, the summary might look like this: + + 20000 reads; of these: + 20000 (100.00%) were unpaired; of these: + 1247 (6.24%) aligned 0 times + 18739 (93.69%) aligned exactly 1 time + 14 (0.07%) aligned >1 times + 93.77% overall alignment rate + +For datasets consisting of pairs, the summary might look like this: + + 10000 reads; of these: + 10000 (100.00%) were paired; of these: + 650 (6.50%) aligned concordantly 0 times + 8823 (88.23%) aligned concordantly exactly 1 time + 527 (5.27%) aligned concordantly >1 times + ---- + 650 pairs aligned concordantly 0 times; of these: + 34 (5.23%) aligned discordantly 1 time + ---- + 616 pairs aligned 0 times concordantly or discordantly; of these: + 1232 mates make up the pairs; of these: + 660 (53.57%) aligned 0 times + 571 (46.35%) aligned exactly 1 time + 1 (0.08%) aligned >1 times + 96.70% overall alignment rate + +The indentation indicates how subtotals relate to totals. + +Wrapper +------- + +The `hisat2`, `hisat2-build` and `hisat2-inspect` executables are actually +wrapper scripts that call binary programs as appropriate. The wrappers shield +users from having to distinguish between "small" and "large" index formats, +discussed briefly in the following section. Also, the `hisat2` wrapper +provides some key functionality, like the ability to handle compressed inputs, +and the functionality for `--un`, `--al` and related options. + +It is recommended that you always run the hisat2 wrappers and not run the +binaries directly. + +Small and large indexes +----------------------- + +`hisat2-build` can index reference genomes of any size. For genomes less than +about 4 billion nucleotides in length, `hisat2-build` builds a "small" index +using 32-bit numbers in various parts of the index. When the genome is longer, +`hisat2-build` builds a "large" index using 64-bit numbers. Small indexes are +stored in files with the `.ht2` extension, and large indexes are stored in +files with the `.ht2l` extension. The user need not worry about whether a +particular index is small or large; the wrapper scripts will automatically build +and use the appropriate index. + +Performance tuning +------------------ + +1. If your computer has multiple processors/cores, use `-p` + + The `-p` option causes HISAT2 to launch a specified number of parallel + search threads. Each thread runs on a different processor/core and all + threads find alignments in parallel, increasing alignment throughput by + approximately a multiple of the number of threads (though in practice, + speedup is somewhat worse than linear). + +Command Line +------------ + +### Setting function options + +Some HISAT2 options specify a function rather than an individual number or +setting. In these cases the user specifies three parameters: (a) a function +type `F`, (b) a constant term `B`, and (c) a coefficient `A`. The available +function types are constant (`C`), linear (`L`), square-root (`S`), and natural +log (`G`). The parameters are specified as `F,B,A` - that is, the function type, +the constant term, and the coefficient are separated by commas with no +whitespace. The constant term and coefficient may be negative and/or +floating-point numbers. + +For example, if the function specification is `L,-0.4,-0.6`, then the function +defined is: + + f(x) = -0.4 + -0.6 * x + +If the function specification is `G,1,5.4`, then the function defined is: + + f(x) = 1.0 + 5.4 * ln(x) + +See the documentation for the option in question to learn what the parameter `x` +is for. For example, in the case if the `--score-min` option, the function +`f(x)` sets the minimum alignment score necessary for an alignment to be +considered valid, and `x` is the read length. + +### Usage + + hisat2 [options]* -x {-1 -2 | -U | --sra-acc } [-S ] + +### Main arguments + + -x + +The basename of the index for the reference genome. The basename is the name of +any of the index files up to but not including the final `.1.ht2` / etc. +`hisat2` looks for the specified index first in the current directory, +then in the directory specified in the `HISAT2_INDEXES` environment variable. + + -1 + +Comma-separated list of files containing mate 1s (filename usually includes +`_1`), e.g. `-1 flyA_1.fq,flyB_1.fq`. Sequences specified with this option must +correspond file-for-file and read-for-read with those specified in ``. Reads +may be a mix of different lengths. If `-` is specified, `hisat2` will read the +mate 1s from the "standard in" or "stdin" filehandle. + + -2 + +Comma-separated list of files containing mate 2s (filename usually includes +`_2`), e.g. `-2 flyA_2.fq,flyB_2.fq`. Sequences specified with this option must +correspond file-for-file and read-for-read with those specified in ``. Reads +may be a mix of different lengths. If `-` is specified, `hisat2` will read the +mate 2s from the "standard in" or "stdin" filehandle. + + -U + +Comma-separated list of files containing unpaired reads to be aligned, e.g. +`lane1.fq,lane2.fq,lane3.fq,lane4.fq`. Reads may be a mix of different lengths. +If `-` is specified, `hisat2` gets the reads from the "standard in" or "stdin" +filehandle. + + --sra-acc + +Comma-separated list of SRA accession numbers, e.g. `--sra-acc SRR353653,SRR353654`. +Information about read types is available at http://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi?sp=runinfo&acc=sra-acc&retmode=xml, +where sra-acc is SRA accession number. If users run HISAT2 on a computer cluster, it is recommended to disable SRA-related caching (see the instruction at [SRA-MANUAL]). + +[SRA-MANUAL]: https://github.com/ncbi/sra-tools/wiki/Toolkit-Configuration + + -S + +File to write SAM alignments to. By default, alignments are written to the +"standard out" or "stdout" filehandle (i.e. the console). + +### Options + +#### Input options + + -q + +Reads (specified with ``, ``, ``) are FASTQ files. FASTQ files +usually have extension `.fq` or `.fastq`. FASTQ is the default format. See +also: `--solexa-quals` and `--int-quals`. + + --qseq + +Reads (specified with ``, ``, ``) are QSEQ files. QSEQ files usually +end in `_qseq.txt`. See also: `--solexa-quals` and `--int-quals`. + + -f + +Reads (specified with ``, ``, ``) are FASTA files. FASTA files +usually have extension `.fa`, `.fasta`, `.mfa`, `.fna` or similar. FASTA files +do not have a way of specifying quality values, so when `-f` is set, the result +is as if `--ignore-quals` is also set. + + -r + +Reads (specified with ``, ``, ``) are files with one input sequence +per line, without any other information (no read names, no qualities). When +`-r` is set, the result is as if `--ignore-quals` is also set. + + -c + +The read sequences are given on command line. I.e. ``, `` and +`` are comma-separated lists of reads rather than lists of read files. +There is no way to specify read names or qualities, so `-c` also implies +`--ignore-quals`. + + -s/--skip + +Skip (i.e. do not align) the first `` reads or pairs in the input. + + -u/--qupto + +Align the first `` reads or read pairs from the input (after the +`-s`/`--skip` reads or pairs have been skipped), then stop. Default: no limit. + + -5/--trim5 + +Trim `` bases from 5' (left) end of each read before alignment (default: 0). + + -3/--trim3 + +Trim `` bases from 3' (right) end of each read before alignment (default: +0). + + --phred33 + +Input qualities are ASCII chars equal to the [Phred quality] plus 33. This is +also called the "Phred+33" encoding, which is used by the very latest Illumina +pipelines. + +[Phred quality]: http://en.wikipedia.org/wiki/Phred_quality_score + + --phred64 + +Input qualities are ASCII chars equal to the [Phred quality] plus 64. This is +also called the "Phred+64" encoding. + + --solexa-quals + +Convert input qualities from [Solexa][Phred quality] (which can be negative) to +[Phred][Phred quality] (which can't). This scheme was used in older Illumina GA +Pipeline versions (prior to 1.3). Default: off. + + --int-quals + +Quality values are represented in the read input file as space-separated ASCII +integers, e.g., `40 40 30 40`..., rather than ASCII characters, e.g., `II?I`.... + Integers are treated as being on the [Phred quality] scale unless +`--solexa-quals` is also specified. Default: off. + +#### Alignment options + + --n-ceil + +Sets a function governing the maximum number of ambiguous characters (usually +`N`s and/or `.`s) allowed in a read as a function of read length. For instance, +specifying `-L,0,0.15` sets the N-ceiling function `f` to `f(x) = 0 + 0.15 * x`, +where x is the read length. See also: [setting function options]. Reads +exceeding this ceiling are [filtered out]. Default: `L,0,0.15`. + + --ignore-quals + +When calculating a mismatch penalty, always consider the quality value at the +mismatched position to be the highest possible, regardless of the actual value. +I.e. input is treated as though all quality values are high. This is also the +default behavior when the input doesn't specify quality values (e.g. in `-f`, +`-r`, or `-c` modes). + + --nofw/--norc + +If `--nofw` is specified, `hisat2` will not attempt to align unpaired reads to +the forward (Watson) reference strand. If `--norc` is specified, `hisat2` will +not attempt to align unpaired reads against the reverse-complement (Crick) +reference strand. In paired-end mode, `--nofw` and `--norc` pertain to the +fragments; i.e. specifying `--nofw` causes `hisat2` to explore only those +paired-end configurations corresponding to fragments from the reverse-complement +(Crick) strand. Default: both strands enabled. + +#### Scoring options + + --mp MX,MN + +Sets the maximum (`MX`) and minimum (`MN`) mismatch penalties, both integers. A +number less than or equal to `MX` and greater than or equal to `MN` is +subtracted from the alignment score for each position where a read character +aligns to a reference character, the characters do not match, and neither is an +`N`. If `--ignore-quals` is specified, the number subtracted quals `MX`. +Otherwise, the number subtracted is `MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) )` +where Q is the Phred quality value. Default: `MX` = 6, `MN` = 2. + + --sp MX,MN + +Sets the maximum (`MX`) and minimum (`MN`) penalties for soft-clipping per base, +both integers. A number less than or equal to `MX` and greater than or equal to `MN` is +subtracted from the alignment score for each position. +The number subtracted is `MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) )` +where Q is the Phred quality value. Default: `MX` = 2, `MN` = 1. + + --no-softclip + +Disallow soft-clipping. + + --np + +Sets penalty for positions where the read, reference, or both, contain an +ambiguous character such as `N`. Default: 1. + + --rdg , + +Sets the read gap open (``) and extend (``) penalties. A read gap of +length N gets a penalty of `` + N * ``. Default: 5, 3. + + --rfg , + +Sets the reference gap open (``) and extend (``) penalties. A +reference gap of length N gets a penalty of `` + N * ``. Default: +5, 3. + + --score-min + +Sets a function governing the minimum alignment score needed for an alignment to +be considered "valid" (i.e. good enough to report). This is a function of read +length. For instance, specifying `L,0,-0.6` sets the minimum-score function `f` +to `f(x) = 0 + -0.6 * x`, where `x` is the read length. See also: [setting +function options]. The default is `L,0,-0.2`. + +#### Spliced alignment options + + --pen-cansplice + +Sets the penalty for each pair of canonical splice sites (e.g. GT/AG). Default: 0. + + --pen-noncansplice + +Sets the penalty for each pair of non-canonical splice sites (e.g. non-GT/AG). Default: 12. + + --pen-canintronlen + +Sets the penalty for long introns with canonical splice sites so that alignments with shorter introns are preferred +to those with longer ones. Default: G,-8,1 + + --pen-noncanintronlen + +Sets the penalty for long introns with noncanonical splice sites so that alignments with shorter introns are preferred +to those with longer ones. Default: G,-8,1 + + --min-intronlen + +Sets minimum intron length. Default: 20 + + --max-intronlen + +Sets maximum intron length. Default: 500000 + + --known-splicesite-infile + +With this mode, you can provide a list of known splice sites, which HISAT2 makes use of to align reads with small anchors. +You can create such a list using `python hisat2_extract_splice_sites.py genes.gtf > splicesites.txt`, +where `hisat2_extract_splice_sites.py` is included in the HISAT2 package, `genes.gtf` is a gene annotation file, +and `splicesites.txt` is a list of splice sites with which you provide HISAT2 in this mode. +Note that it is better to use indexes built using annotated transcripts (such as genome_tran or genome_snp_tran), which works better +than using this option. It has no effect to provide splice sites that are already included in the indexes. + + --novel-splicesite-outfile + +In this mode, HISAT2 reports a list of splice sites in the file : + chromosome name `` genomic position of the flanking base on the left side of an intron `` genomic position of the flanking base on the right `` strand (+, -, and .) + '.' indicates an unknown strand for non-canonical splice sites. + + --novel-splicesite-infile + +With this mode, you can provide a list of novel splice sites that were generated from the above option "--novel-splicesite-outfile". + + --no-temp-splicesite + +HISAT2, by default, makes use of splice sites found by earlier reads to align later reads in the same run, +in particular, reads with small anchors (<= 15 bp). +The option disables this default alignment strategy. + + --no-spliced-alignment + +Disable spliced alignment. + + --rna-strandness + +Specify strand-specific information: the default is unstranded. +For single-end reads, use F or R. + 'F' means a read corresponds to a transcript. + 'R' means a read corresponds to the reverse complemented counterpart of a transcript. +For paired-end reads, use either FR or RF. +With this option being used, every read alignment will have an XS attribute tag: + '+' means a read belongs to a transcript on '+' strand of genome. + '-' means a read belongs to a transcript on '-' strand of genome. + +(TopHat has a similar option, --library-type option, where fr-firststrand corresponds to R and RF; fr-secondstrand corresponds to F and FR.) + + --tmo/--transcriptome-mapping-only + +Report only those alignments within known transcripts. + + --dta/--downstream-transcriptome-assembly + +Report alignments tailored for transcript assemblers including StringTie. +With this option, HISAT2 requires longer anchor lengths for de novo discovery of splice sites. +This leads to fewer alignments with short-anchors, +which helps transcript assemblers improve significantly in computation and memory usage. + + --dta-cufflinks + +Report alignments tailored specifically for Cufflinks. In addition to what HISAT2 does with the above option (--dta), +With this option, HISAT2 looks for novel splice sites with three signals (GT/AG, GC/AG, AT/AC), but all user-provided splice sites are used irrespective of their signals. +HISAT2 produces an optional field, XS:A:[+-], for every spliced alignment. + + --no-templatelen-adjustment + +Disables template length adjustment for RNA-seq reads. + +#### Reporting options + + -k + +It searches for at most `` distinct, primary alignments for each read. +Primary alignments mean alignments whose alignment score is equal or higher than any other alignments. +The search terminates when it can't find more distinct valid alignments, or when it +finds ``, whichever happens first. The alignment score for a paired-end +alignment equals the sum of the alignment scores of the individual mates. Each +reported read or pair alignment beyond the first has the SAM 'secondary' bit +(which equals 256) set in its FLAGS field. For reads that have more than +`` distinct, valid alignments, `hisat2` does not guarantee that the +`` alignments reported are the best possible in terms of alignment score. Default: 5 (HFM) or 10 (HGFM) + +Note: HISAT2 is not designed with large values for `-k` in mind, and when +aligning reads to long, repetitive genomes large `-k` can be very, very slow. + + --max-seeds + +HISAT2, like other aligners, uses seed-and-extend approaches. HISAT2 tries to extend seeds to full-length alignments. In HISAT2, --max-seeds is used to control the maximum number of seeds that will be extended. HISAT2 extends up to these many seeds and skips the rest of the seeds. Large values for `--max-seeds` may improve alignment sensitivity, but HISAT2 is not designed with large values for `--max-seeds` in mind, and when aligning reads to long, repetitive genomes large `--max-seeds` can be very, very slow. The default value is the maximum of 5 and the value that comes with`-k`. + + --secondary + +Report secondary alignments. + +#### Paired-end options + + -I/--minins + +The minimum fragment length for valid paired-end alignments.This option is valid only with --no-spliced-alignment. +E.g. if `-I 60` is specified and a paired-end alignment consists of two 20-bp alignments in the +appropriate orientation with a 20-bp gap between them, that alignment is +considered valid (as long as `-X` is also satisfied). A 19-bp gap would not +be valid in that case. If trimming options `-3` or `-5` are also used, the +`-I` constraint is applied with respect to the untrimmed mates. + +The larger the difference between `-I` and `-X`, the slower HISAT2 will +run. This is because larger differences between `-I` and `-X` require that +HISAT2 scan a larger window to determine if a concordant alignment exists. +For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very +efficient. + +Default: 0 (essentially imposing no minimum) + + -X/--maxins + +The maximum fragment length for valid paired-end alignments. This option is valid only with --no-spliced-alignment. +E.g. if `-X 100` is specified and a paired-end alignment consists of two 20-bp alignments in the +proper orientation with a 60-bp gap between them, that alignment is considered +valid (as long as `-I` is also satisfied). A 61-bp gap would not be valid in +that case. If trimming options `-3` or `-5` are also used, the `-X` +constraint is applied with respect to the untrimmed mates, not the trimmed +mates. + +The larger the difference between `-I` and `-X`, the slower HISAT2 will +run. This is because larger differences between `-I` and `-X` require that +HISAT2 scan a larger window to determine if a concordant alignment exists. +For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very +efficient. + +Default: 500. + + --fr/--rf/--ff + +The upstream/downstream mate orientations for a valid paired-end alignment +against the forward reference strand. E.g., if `--fr` is specified and there is +a candidate paired-end alignment where mate 1 appears upstream of the reverse +complement of mate 2 and the fragment length constraints (`-I` and `-X`) are +met, that alignment is valid. Also, if mate 2 appears upstream of the reverse +complement of mate 1 and all other constraints are met, that too is valid. +`--rf` likewise requires that an upstream mate1 be reverse-complemented and a +downstream mate2 be forward-oriented. ` --ff` requires both an upstream mate 1 +and a downstream mate 2 to be forward-oriented. Default: `--fr` (appropriate +for Illumina's Paired-end Sequencing Assay). + + --no-mixed + +By default, when `hisat2` cannot find a concordant or discordant alignment for +a pair, it then tries to find alignments for the individual mates. This option +disables that behavior. + + --no-discordant + +By default, `hisat2` looks for discordant alignments if it cannot find any +concordant alignments. A discordant alignment is an alignment where both mates +align uniquely, but that does not satisfy the paired-end constraints +(`--fr`/`--rf`/`--ff`, `-I`, `-X`). This option disables that behavior. + +#### Output options + + -t/--time + +Print the wall-clock time required to load the index files and align the reads. +This is printed to the "standard error" ("stderr") filehandle. Default: off. + + --un + --un-gz + --un-bz2 + +Write unpaired reads that fail to align to file at ``. These reads +correspond to the SAM records with the FLAGS `0x4` bit set and neither the +`0x40` nor `0x80` bits set. If `--un-gz` is specified, output will be gzip +compressed. If `--un-bz2` is specified, output will be bzip2 compressed. Reads +written in this way will appear exactly as they did in the input file, without +any modification (same sequence, same name, same quality string, same quality +encoding). Reads will not necessarily appear in the same order as they did in +the input. + + --al + --al-gz + --al-bz2 + +Write unpaired reads that align at least once to file at ``. These reads +correspond to the SAM records with the FLAGS `0x4`, `0x40`, and `0x80` bits +unset. If `--al-gz` is specified, output will be gzip compressed. If `--al-bz2` +is specified, output will be bzip2 compressed. Reads written in this way will +appear exactly as they did in the input file, without any modification (same +sequence, same name, same quality string, same quality encoding). Reads will +not necessarily appear in the same order as they did in the input. + + --un-conc + --un-conc-gz + --un-conc-bz2 + +Write paired-end reads that fail to align concordantly to file(s) at ``. +These reads correspond to the SAM records with the FLAGS `0x4` bit set and +either the `0x40` or `0x80` bit set (depending on whether it's mate #1 or #2). +`.1` and `.2` strings are added to the filename to distinguish which file +contains mate #1 and mate #2. If a percent symbol, `%`, is used in ``, +the percent symbol is replaced with `1` or `2` to make the per-mate filenames. +Otherwise, `.1` or `.2` are added before the final dot in `` to make the +per-mate filenames. Reads written in this way will appear exactly as they did +in the input files, without any modification (same sequence, same name, same +quality string, same quality encoding). Reads will not necessarily appear in +the same order as they did in the inputs. + + --al-conc + --al-conc-gz + --al-conc-bz2 + +Write paired-end reads that align concordantly at least once to file(s) at +``. These reads correspond to the SAM records with the FLAGS `0x4` bit +unset and either the `0x40` or `0x80` bit set (depending on whether it's mate #1 +or #2). `.1` and `.2` strings are added to the filename to distinguish which +file contains mate #1 and mate #2. If a percent symbol, `%`, is used in +``, the percent symbol is replaced with `1` or `2` to make the per-mate +filenames. Otherwise, `.1` or `.2` are added before the final dot in `` to +make the per-mate filenames. Reads written in this way will appear exactly as +they did in the input files, without any modification (same sequence, same name, +same quality string, same quality encoding). Reads will not necessarily appear +in the same order as they did in the inputs. + + --quiet + +Print nothing besides alignments and serious errors. + + --summary-file + +Print alignment summary to this file. + + --new-summary + +Print alignment summary in a new style, which is more machine-friendly. + + --met-file + +Write `hisat2` metrics to file ``. Having alignment metric can be useful +for debugging certain problems, especially performance issues. See also: +`--met`. Default: metrics disabled. + + --met-stderr + +Write `hisat2` metrics to the "standard error" ("stderr") filehandle. This is +not mutually exclusive with `--met-file`. Having alignment metric can be +useful for debugging certain problems, especially performance issues. See also: +`--met`. Default: metrics disabled. + + --met + +Write a new `hisat2` metrics record every `` seconds. Only matters if +either `--met-stderr` or `--met-file` are specified. Default: 1. + +#### SAM options + + --no-unal + +Suppress SAM records for reads that failed to align. + + --no-hd + +Suppress SAM header lines (starting with `@`). + + --no-sq + +Suppress `@SQ` SAM header lines. + + --rg-id + +Set the read group ID to ``. This causes the SAM `@RG` header line to be +printed, with `` as the value associated with the `ID:` tag. It also +causes the `RG:Z:` extra field to be attached to each SAM output record, with +value set to ``. + + --rg + +Add `` (usually of the form `TAG:VAL`, e.g. `SM:Pool1`) as a field on the +`@RG` header line. Note: in order for the `@RG` line to appear, `--rg-id` +must also be specified. This is because the `ID` tag is required by the [SAM +Spec][SAM]. Specify `--rg` multiple times to set multiple fields. See the +[SAM Spec][SAM] for details about what fields are legal. + + --remove-chrname + +Remove 'chr' from reference names in alignment (e.g., chr18 to 18) + + --add-chrname + +Add 'chr' to reference names in alignment (e.g., 18 to chr18) + + --omit-sec-seq + +When printing secondary alignments, HISAT2 by default will write out the `SEQ` +and `QUAL` strings. Specifying this option causes HISAT2 to print an asterisk +in those fields instead. + +#### Performance options + + -o/--offrate + +Override the offrate of the index with ``. If `` is greater +than the offrate used to build the index, then some row markings are +discarded when the index is read into memory. This reduces the memory +footprint of the aligner but requires more time to calculate text +offsets. `` must be greater than the value used to build the +index. + + -p/--threads NTHREADS + +Launch `NTHREADS` parallel search threads (default: 1). Threads will run on +separate processors/cores and synchronize when parsing reads and outputting +alignments. Searching for alignments is highly parallel, and speedup is close +to linear. Increasing `-p` increases HISAT2's memory footprint. E.g. when +aligning to a human genome index, increasing `-p` from 1 to 8 increases the +memory footprint by a few hundred megabytes. This option is only available if +`hisat2` is linked with the `pthreads` library (i.e. if `HISAT2_PTHREADS=0` is +not specified at build time). + + --reorder + +Guarantees that output SAM records are printed in an order corresponding to the +order of the reads in the original input file, even when `-p` is set greater +than 1. Specifying `--reorder` and setting `-p` greater than 1 causes HISAT2 +to run somewhat slower and use somewhat more memory then if `--reorder` were +not specified. Has no effect if `-p` is set to 1, since output order will +naturally correspond to input order in that case. + + --mm + +Use memory-mapped I/O to load the index, rather than typical file I/O. +Memory-mapping allows many concurrent `hisat2` processes on the same computer to +share the same memory image of the index (i.e. you pay the memory overhead just +once). This facilitates memory-efficient parallelization of `hisat2` in +situations where using `-p` is not possible or not preferable. + +#### Other options + + --qc-filter + +Filter out reads for which the QSEQ filter field is non-zero. Only has an +effect when read format is `--qseq`. Default: off. + + --seed + +Use `` as the seed for pseudo-random number generator. Default: 0. + + --non-deterministic + +Normally, HISAT2 re-initializes its pseudo-random generator for each read. It +seeds the generator with a number derived from (a) the read name, (b) the +nucleotide sequence, (c) the quality sequence, (d) the value of the `--seed` +option. This means that if two reads are identical (same name, same +nucleotides, same qualities) HISAT2 will find and report the same alignment(s) +for both, even if there was ambiguity. When `--non-deterministic` is specified, +HISAT2 re-initializes its pseudo-random generator for each read using the +current time. This means that HISAT2 will not necessarily report the same +alignment for two identical reads. This is counter-intuitive for some users, +but might be more appropriate in situations where the input consists of many +identical reads. + + --version + +Print version information and quit. + + -h/--help + +Print usage information and quit. + +SAM output +---------- + +Following is a brief description of the [SAM] format as output by `hisat2`. +For more details, see the [SAM format specification][SAM]. + +By default, `hisat2` prints a SAM header with `@HD`, `@SQ` and `@PG` lines. +When one or more `--rg` arguments are specified, `hisat2` will also print +an `@RG` line that includes all user-specified `--rg` tokens separated by +tabs. + +Each subsequent line describes an alignment or, if the read failed to align, a +read. Each line is a collection of at least 12 fields separated by tabs; from +left to right, the fields are: + +1. Name of read that aligned. + + Note that the [SAM specification] disallows whitespace in the read name. + If the read name contains any whitespace characters, HISAT2 will truncate + the name at the first whitespace character. This is similar to the + behavior of other tools. + +2. Sum of all applicable flags. Flags relevant to HISAT2 are: + + 1 + + The read is one of a pair + + 2 + + The alignment is one end of a proper paired-end alignment + + 4 + + The read has no reported alignments + + 8 + + The read is one of a pair and has no reported alignments + + 16 + + The alignment is to the reverse reference strand + + 32 + + The other mate in the paired-end alignment is aligned to the + reverse reference strand + + 64 + + The read is mate 1 in a pair + + 128 + + The read is mate 2 in a pair + + Thus, an unpaired read that aligns to the reverse reference strand + will have flag 16. A paired-end read that aligns and is the first + mate in the pair will have flag 83 (= 64 + 16 + 2 + 1). + +3. Name of reference sequence where alignment occurs + +4. 1-based offset into the forward reference strand where leftmost + character of the alignment occurs + +5. Mapping quality + +6. CIGAR string representation of alignment + +7. Name of reference sequence where mate's alignment occurs. Set to `=` if the +mate's reference sequence is the same as this alignment's, or `*` if there is no +mate. + +8. 1-based offset into the forward reference strand where leftmost character of +the mate's alignment occurs. Offset is 0 if there is no mate. + +9. Inferred fragment length. Size is negative if the mate's alignment occurs +upstream of this alignment. Size is 0 if the mates did not align concordantly. +However, size is non-0 if the mates aligned discordantly to the same +chromosome. + +10. Read sequence (reverse-complemented if aligned to the reverse strand) + +11. ASCII-encoded read qualities (reverse-complemented if the read aligned to +the reverse strand). The encoded quality values are on the [Phred quality] +scale and the encoding is ASCII-offset by 33 (ASCII char `!`), similarly to a +[FASTQ] file. + +12. Optional fields. Fields are tab-separated. `hisat2` outputs zero or more +of these optional fields for each alignment, depending on the type of the +alignment: + + AS:i: + + Alignment score. Can be negative. Only present if SAM record is for + an aligned read. + + ZS:i: + + Alignment score for the best-scoring alignment found other than the + alignment reported. Can be negative. Only present if the SAM record is + for an aligned read and more than one alignment was found for the read. + Note that, when the read is part of a concordantly-aligned pair, this score + could be greater than `AS:i`. + + YS:i: + + Alignment score for opposite mate in the paired-end alignment. Only present + if the SAM record is for a read that aligned as part of a paired-end + alignment. + + XN:i: + + The number of ambiguous bases in the reference covering this alignment. + Only present if SAM record is for an aligned read. + + XM:i: + + The number of mismatches in the alignment. Only present if SAM record is + for an aligned read. + + XO:i: + + The number of gap opens, for both read and reference gaps, in the alignment. + Only present if SAM record is for an aligned read. + + XG:i: + + The number of gap extensions, for both read and reference gaps, in the + alignment. Only present if SAM record is for an aligned read. + + NM:i: + + The edit distance; that is, the minimal number of one-nucleotide edits + (substitutions, insertions and deletions) needed to transform the read + string into the reference string. Only present if SAM record is for an + aligned read. + + YF:Z: + + String indicating reason why the read was filtered out. See also: + [Filtering]. Only appears for reads that were filtered out. + + YT:Z: + + Value of `UU` indicates the read was not part of a pair. Value of `CP` + indicates the read was part of a pair and the pair aligned concordantly. + Value of `DP` indicates the read was part of a pair and the pair aligned + discordantly. Value of `UP` indicates the read was part of a pair but the + pair failed to aligned either concordantly or discordantly. + + MD:Z: + + A string representation of the mismatched reference bases in the alignment. + See [SAM] format specification for details. Only present if SAM record is + for an aligned read. + + XS:A: + + Values of `+` and `-` indicate the read is mapped to transcripts on sense and anti-sense + strands, respectively. Spliced alignments need to have this field, which is required in Cufflinks and StringTie. + We can report this field for the canonical-splice site (GT/AG), but not for non-canonical splice sites. + You can direct HISAT2 not to output such alignments (involving non-canonical splice sites) using "--pen-noncansplice 1000000". + + NH:i: + + The number of mapped locations for the read or the pair. + + Zs:Z: + + When the alignment of a read involves SNPs that are in the index, this option is used to indicate where exactly the read involves the SNPs. + This optional field is similar to the above MD:Z field. + For example, `Zs:Z:1|S|rs3747203,97|S|rs16990981` indicates the second base of the read corresponds to a known SNP (ID: rs3747203). + 97 bases after the third base (the base after the second one), the read at 100th base involves another known SNP (ID: rs16990981). + 'S' indicates a single nucleotide polymorphism. 'D' and 'I' indicate a deletion and an insertion, respectively. + +[SAM format specification]: http://samtools.sf.net/SAM1.pdf +[FASTQ]: http://en.wikipedia.org/wiki/FASTQ_format + +The `hisat2-build` indexer +=========================== + +`hisat2-build` builds a HISAT2 index from a set of DNA sequences. +`hisat2-build` outputs a set of 6 files with suffixes `.1.ht2`, `.2.ht2`, +`.3.ht2`, `.4.ht2`, `.5.ht2`, `.6.ht2`, `.7.ht2`, and `.8.ht2`. In the case of a large +index these suffixes will have a `ht2l` termination. These files together +constitute the index: they are all that is needed to align reads to that +reference. The original sequence FASTA files are no longer used by HISAT2 +once the index is built. + +Use of Karkkainen's [blockwise algorithm] allows `hisat2-build` to trade off +between running time and memory usage. `hisat2-build` has three options +governing how it makes this trade: `-p`/`--packed`, `--bmax`/`--bmaxdivn`, +and `--dcv`. By default, `hisat2-build` will automatically search for the +settings that yield the best running time without exhausting memory. This +behavior can be disabled using the `-a`/`--noauto` option. + +The indexer provides options pertaining to the "shape" of the index, e.g. +`--offrate` governs the fraction of [Burrows-Wheeler] +rows that are "marked" (i.e., the density of the suffix-array sample; see the +original [FM Index] paper for details). All of these options are potentially +profitable trade-offs depending on the application. They have been set to +defaults that are reasonable for most cases according to our experiments. See +[Performance tuning] for details. + +`hisat2-build` can generate either [small or large indexes]. The wrapper +will decide which based on the length of the input genome. If the reference +does not exceed 4 billion characters but a large index is preferred, the user +can specify `--large-index` to force `hisat2-build` to build a large index +instead. + +The HISAT2 index is based on the [FM Index] of Ferragina and Manzini, which in +turn is based on the [Burrows-Wheeler] transform. The algorithm used to build +the index is based on the [blockwise algorithm] of Karkkainen. + +[Blockwise algorithm]: http://portal.acm.org/citation.cfm?id=1314852 +[Burrows-Wheeler]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform + +Command Line +------------ + +Usage: + + hisat2-build [options]* + +### Notes + If you use --snp, --ss, and/or --exon, hisat2-build will need about 200GB RAM for the human genome size as index building involves a graph construction. + Otherwise, you will be able to build an index on your desktop with 8GB RAM. + +### Main arguments + +A comma-separated list of FASTA files containing the reference sequences to be +aligned to, or, if `-c` is specified, the sequences +themselves. E.g., `` might be `chr1.fa,chr2.fa,chrX.fa,chrY.fa`, +or, if `-c` is specified, this might be +`GGTCATCCT,ACGGGTCGT,CCGTTCTATGCGGCTTA`. + +The basename of the index files to write. By default, `hisat2-build` writes +files named `NAME.1.ht2`, `NAME.2.ht2`, `NAME.3.ht2`, `NAME.4.ht2`, +`NAME.5.ht2`, `NAME.6.ht2`, `NAME.7.ht2`, and `NAME.8.ht2` where `NAME` is ``. + +### Options + + -f + +The reference input files (specified as ``) are FASTA files +(usually having extension `.fa`, `.mfa`, `.fna` or similar). + + -c + +The reference sequences are given on the command line. I.e. `` is +a comma-separated list of sequences rather than a list of FASTA files. + + --large-index + +Force `hisat2-build` to build a [large index], even if the reference is less +than ~ 4 billion nucleotides long. + + -a/--noauto + +Disable the default behavior whereby `hisat2-build` automatically selects +values for the `--bmax`, `--dcv` and `--packed` parameters according to +available memory. Instead, user may specify values for those parameters. If +memory is exhausted during indexing, an error message will be printed; it is up +to the user to try new parameters. + + --bmax + +The maximum number of suffixes allowed in a block. Allowing more suffixes per +block makes indexing faster, but increases peak memory usage. Setting this +option overrides any previous setting for `--bmax`, or `--bmaxdivn`. +Default (in terms of the `--bmaxdivn` parameter) is `--bmaxdivn` 4. This is +configured automatically by default; use `-a`/`--noauto` to configure manually. + + --bmaxdivn + +The maximum number of suffixes allowed in a block, expressed as a fraction of +the length of the reference. Setting this option overrides any previous setting +for `--bmax`, or `--bmaxdivn`. Default: `--bmaxdivn` 4. This is +configured automatically by default; use `-a`/`--noauto` to configure manually. + + --dcv + +Use `` as the period for the difference-cover sample. A larger period +yields less memory overhead, but may make suffix sorting slower, especially if +repeats are present. Must be a power of 2 no greater than 4096. Default: 1024. + This is configured automatically by default; use `-a`/`--noauto` to configure +manually. + + --nodc + +Disable use of the difference-cover sample. Suffix sorting becomes +quadratic-time in the worst case (where the worst case is an extremely +repetitive reference). Default: off. + + -r/--noref + +Do not build the `NAME.3.ht2` and `NAME.4.ht2` portions of the index, which +contain a bitpacked version of the reference sequences and are used for +paired-end alignment. + + -3/--justref + +Build only the `NAME.3.ht2` and `NAME.4.ht2` portions of the index, which +contain a bitpacked version of the reference sequences and are used for +paired-end alignment. + + -o/--offrate + +To map alignments back to positions on the reference sequences, it's necessary +to annotate ("mark") some or all of the [Burrows-Wheeler] rows with their +corresponding location on the genome. +`-o`/`--offrate` governs how many rows get marked: +the indexer will mark every 2^`` rows. Marking more rows makes +reference-position lookups faster, but requires more memory to hold the +annotations at runtime. The default is 4 (every 16th row is marked; for human +genome, annotations occupy about 680 megabytes). + + -t/--ftabchars + +The ftab is the lookup table used to calculate an initial [Burrows-Wheeler] +range with respect to the first `` characters of the query. A larger +`` yields a larger lookup table but faster query times. The ftab has size +4^(``+1) bytes. The default setting is 10 (ftab is 4MB). + + --localoffrate + +This option governs how many rows get marked in a local index: +the indexer will mark every 2^`` rows. Marking more rows makes +reference-position lookups faster, but requires more memory to hold the +annotations at runtime. The default is 3 (every 8th row is marked, +this occupies about 16KB per local index). + + --localftabchars + +The local ftab is the lookup table in a local index. +The default setting is 6 (ftab is 8KB per local index). + + -p + +Launch `NTHREADS` parallel build threads (default: 1). + + --snp + +Provide a list of SNPs (in the HISAT2's own format) as follows (five columns). + + SNP ID `` snp type (single, deletion, or insertion) `` chromosome name `` zero-offset based genomic position of a SNP `` alternative base (single), the length of SNP (deletion), or insertion sequence (insertion) + + For example, + rs58784443 single 13 18447947 T + +Use `hisat2_extract_snps_haplotypes_UCSC.py` (in the HISAT2 package) to extract SNPs and haplotypes from a dbSNP file (e.g. http://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/snp144Common.txt.gz). +or `hisat2_extract_snps_haplotypes_VCF.py` to extract SNPs and haplotypes from a VCF file (e.g. ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502/supporting/GRCh38_positions/ALL.chr22.phase3_shapeit2_mvncall_integrated_v3plus_nounphased.rsID.genotypes.GRCh38_dbSNP_no_SVs.vcf.gz). + + --haplotype + +Provide a list of haplotypes (in the HISAT2's own format) as follows (five columns). + + Haplotype ID `` chromosome name `` zero-offset based left coordinate of haplotype `` zero-offset based right coordinate of haplotype `` a comma separated list of SNP ids in the haplotype + + For example, + ht35 13 18446877 18446945 rs12381094,rs12381056,rs192016659,rs538569910 + +See the above option, --snp, about how to extract haplotypes. This option is not required, but haplotype information can keep the index construction from exploding and reduce the index size substantially. + + --ss + +Note this option should be used with the following --exon option. +Provide a list of splice sites (in the HISAT2's own format) as follows (four columns). + + chromosome name `` zero-offset based genomic position of the flanking base on the left side of an intron `` zero-offset based genomic position of the flanking base on the right `` strand + +Use `hisat2_extract_splice_sites.py` (in the HISAT2 package) to extract splice sites from a GTF file. + + --exon + +Note this option should be used with the above --ss option. +Provide a list of exons (in the HISAT2's own format) as follows (three columns). + + chromosome name `` zero-offset based left genomic position of an exon `` zero-offset based right genomic position of an exon + +Use `hisat2_extract_exons.py` (in the HISAT2 package) to extract exons from a GTF file. + + --seed + +Use `` as the seed for pseudo-random number generator. + + --cutoff + +Index only the first `` bases of the reference sequences (cumulative across +sequences) and ignore the rest. + + -q/--quiet + +`hisat2-build` is verbose by default. With this option `hisat2-build` will +print only error messages. + + -h/--help + +Print usage information and quit. + + --version + +Print version information and quit. + +The `hisat2-inspect` index inspector +===================================== + +`hisat2-inspect` extracts information from a HISAT2 index about what kind of +index it is and what reference sequences were used to build it. When run without +any options, the tool will output a FASTA file containing the sequences of the +original references (with all non-`A`/`C`/`G`/`T` characters converted to `N`s). + It can also be used to extract just the reference sequence names using the +`-n`/`--names` option or a more verbose summary using the `-s`/`--summary` +option. + +Command Line +------------ + +Usage: + + hisat2-inspect [options]* + +### Main arguments + +The basename of the index to be inspected. The basename is name of any of the +index files but with the `.X.ht2` suffix omitted. +`hisat2-inspect` first looks in the current directory for the index files, then +in the directory specified in the `HISAT2_INDEXES` environment variable. + +### Options + + -a/--across + +When printing FASTA output, output a newline character every `` bases +(default: 60). + + -n/--names + +Print reference sequence names, one per line, and quit. + + -s/--summary + +Print a summary that includes information about index settings, as well as the +names and lengths of the input sequences. The summary has this format: + + Colorspace <0 or 1> + SA-Sample 1 in + FTab-Chars + Sequence-1 + Sequence-2 + ... + Sequence-N + +Fields are separated by tabs. Colorspace is always set to 0 for HISAT2. + + --snp + +Print SNPs, and quit. + + --ss + +Print splice sites, and quit. + + --ss-all + +Print splice sites including those not in the global index, and quit. + + --exon + +Print exons, and quit. + + -v/--verbose + +Print verbose output (for debugging). + + --version + +Print version information and quit. + + -h/--help + +Print usage information and quit. + +Getting started with HISAT2 +=================================================== + +HISAT2 comes with some example files to get you started. The example files +are not scientifically significant; these files will simply let you start running HISAT2 and +downstream tools right away. + +First follow the manual instructions to [obtain HISAT2]. Set the `HISAT2_HOME` +environment variable to point to the new HISAT2 directory containing the +`hisat2`, `hisat2-build` and `hisat2-inspect` binaries. This is important, +as the `HISAT2_HOME` variable is used in the commands below to refer to that +directory. + +Indexing a reference genome +--------------------------- + +To create an index for the genomic region (1 million bps from the human chromosome 22 between 20,000,000 and 20,999,999) +included with HISAT2, create a new temporary directory (it doesn't matter where), change into that directory, and run: + + $HISAT2_HOME/hisat2-build $HISAT2_HOME/example/reference/22_20-21M.fa --snp $HISAT2_HOME/example/reference/22_20-21M.snp 22_20-21M_snp + +The command should print many lines of output then quit. When the command +completes, the current directory will contain ten new files that all start with +`22_20-21M_snp` and end with `.1.ht2`, `.2.ht2`, `.3.ht2`, `.4.ht2`, `.5.ht2`, `.6.ht2`, +`.7.ht2`, and `.8.ht2`. These files constitute the index - you're done! + +You can use `hisat2-build` to create an index for a set of FASTA files obtained +from any source, including sites such as [UCSC], [NCBI], and [Ensembl]. When +indexing multiple FASTA files, specify all the files using commas to separate +file names. For more details on how to create an index with `hisat2-build`, +see the [manual section on index building]. You may also want to bypass this +process by obtaining a pre-built index. + +[UCSC]: http://genome.ucsc.edu/cgi-bin/hgGateway +[NCBI]: http://www.ncbi.nlm.nih.gov/sites/genome +[Ensembl]: http://www.ensembl.org/ + +Aligning example reads +---------------------- + +Stay in the directory created in the previous step, which now contains the +`22_20-21M` index files. Next, run: + + $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -U $HISAT2_HOME/example/reads/reads_1.fa -S eg1.sam + +This runs the HISAT2 aligner, which aligns a set of unpaired reads to the +genome region using the index generated in the previous step. +The alignment results in SAM format are written to the file `eg1.sam`, and a +short alignment summary is written to the console. (Actually, the summary is +written to the "standard error" or "stderr" filehandle, which is typically +printed to the console.) + +To see the first few lines of the SAM output, run: + + head eg1.sam + +You will see something like this: + + @HD VN:1.0 SO:unsorted + @SQ SN:22:20000001-21000000 LN:1000000 + @PG ID:hisat2 PN:hisat2 VN:2.0.0-beta + 1 0 22:20000001-21000000 397984 255 100M * 0 0 GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1 + 2 16 22:20000001-21000000 398131 255 100M * 0 0 ATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:80A19 YT:Z:UU NH:i:1 Zs:Z:80|S|rs576159895 + 3 16 22:20000001-21000000 398222 255 100M * 0 0 TGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:16A83 YT:Z:UU NH:i:1 Zs:Z:16|S|rs2629364 + 4 16 22:20000001-21000000 398247 255 90M200N10M * 0 0 CAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAACCGCTGCACCAGGAAGTCGATCCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU XS:A:- NH:i:1 + 5 16 22:20000001-21000000 398194 255 100M * 0 0 GGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:17A26A55 YT:Z:UU NH:i:1 Zs:Z:17|S|rs576159895,26|S|rs2629364 + 6 0 22:20000001-21000000 398069 255 100M * 0 0 CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1 + 7 0 22:20000001-21000000 397896 255 100M * 0 0 GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:31G68 YT:Z:UU NH:i:1 Zs:Z:31|S|rs562662261 + 8 0 22:20000001-21000000 398150 255 100M * 0 0 AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:61A26A11 YT:Z:UU NH:i:1 Zs:Z:61|S|rs576159895,26|S|rs2629364 + 9 16 22:20000001-21000000 398329 255 8M200N92M * 0 0 ACCAGGAAGTCGATCCAGATGTAGTGGGGGGTCACTTCGGGGGGACAGGGTTTGGGTTGACTTGCTTCCGAGGCAGCCAGGGGGTCTGCTTCCTTTATCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU XS:A:- NH:i:1 + 10 16 22:20000001-21000000 398184 255 100M * 0 0 CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:27A26A45 YT:Z:UU NH:i:1 Zs:Z:27|S|rs576159895,26|S|rs2629364 + +The first few lines (beginning with `@`) are SAM header lines, and the rest of +the lines are SAM alignments, one line per read or mate. See the [HISAT2 +manual section on SAM output] and the [SAM specification] for details about how +to interpret the SAM file format. + +Paired-end example +------------------ + +To align paired-end reads included with HISAT2, stay in the same directory and +run: + + $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam + +This aligns a set of paired-end reads to the reference genome, with results +written to the file `eg2.sam`. + +Using SAMtools/BCFtools downstream +---------------------------------- + +[SAMtools] is a collection of tools for manipulating and analyzing SAM and BAM +alignment files. [BCFtools] is a collection of tools for calling variants and +manipulating VCF and BCF files, and it is typically distributed with [SAMtools]. +Using these tools together allows you to get from alignments in SAM format to +variant calls in VCF format. This example assumes that `samtools` and +`bcftools` are installed and that the directories containing these binaries are +in your [PATH environment variable]. + +Run the paired-end example: + + $HISAT2_HOME/hisat -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam + +Use `samtools view` to convert the SAM file into a BAM file. BAM is a the +binary format corresponding to the SAM text format. Run: + + samtools view -bS eg2.sam > eg2.bam + +Use `samtools sort` to convert the BAM file to a sorted BAM file. The following command requires samtools version 1.2 or higher. + + samtools sort eg2.bam -o eg2.sorted.bam + +We now have a sorted BAM file called `eg2.sorted.bam`. Sorted BAM is a useful +format because the alignments are (a) compressed, which is convenient for +long-term storage, and (b) sorted, which is convenient for variant discovery. +To generate variant calls in VCF format, run: + + samtools mpileup -uf $HISAT2_HOME/example/reference/22_20-21M.fa eg2.sorted.bam | bcftools view -bvcg - > eg2.raw.bcf + +Then to view the variants, run: + + bcftools view eg2.raw.bcf + +See the official SAMtools guide to [Calling SNPs/INDELs with SAMtools/BCFtools] +for more details and variations on this process. + +[BCFtools]: http://samtools.sourceforge.net/mpileup.shtml +[Calling SNPs/INDELs with SAMtools/BCFtools]: http://samtools.sourceforge.net/mpileup.shtml diff --git a/MANUAL.markdown b/MANUAL.markdown new file mode 100644 index 0000000..a88b0f6 --- /dev/null +++ b/MANUAL.markdown @@ -0,0 +1,2437 @@ + + +Introduction +============ + +What is HISAT2? +----------------- + +HISAT2 is a fast and sensitive alignment program for mapping next-generation sequencing reads +(whole-genome, transcriptome, and exome sequencing data) against the general human population +(as well as against a single reference genome). Based on [GCSA] (an extension of [BWT] for a graph), we designed and implemented a graph FM index (GFM), +an original approach and its first implementation to the best of our knowledge. +In addition to using one global GFM index that represents general population, +HISAT2 uses a large set of small GFM indexes that collectively cover the whole genome +(each index representing a genomic region of 56 Kbp, with 55,000 indexes needed to cover human population). +These small indexes (called local indexes) combined with several alignment strategies enable effective alignment of sequencing reads. +This new indexing scheme is called Hierarchical Graph FM index (HGFM). +We have developed HISAT 2 based on the [HISAT] and [Bowtie2] implementations. +HISAT2 outputs alignments in [SAM] format, enabling interoperation with a large number of other tools (e.g. [SAMtools], [GATK]) that use SAM. +HISAT2 is distributed under the [GPLv3 license], and it runs on the command line under +Linux, Mac OS X and Windows. + +[HISAT2]: http://ccb.jhu.edu/software/hisat2 +[HISAT]: http://ccb.jhu.edu/software/hisat +[Bowtie2]: http://bowtie-bio.sf.net/bowtie2 +[Bowtie]: http://bowtie-bio.sf.net +[Bowtie1]: http://bowtie-bio.sf.net +[GCSA]: http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=6698337&tag=1 +[Burrows-Wheeler Transform]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[BWT]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[FM Index]: http://en.wikipedia.org/wiki/FM-index +[SAM]: http://samtools.sourceforge.net/SAM1.pdf +[SAMtools]: http://samtools.sourceforge.net +[GATK]: http://www.broadinstitute.org/gsa/wiki/index.php/The_Genome_Analysis_Toolkit +[TopHat2]: http://ccb.jhu.edu/software/tophat +[Cufflinks]: http://cufflinks.cbcb.umd.edu/ +[Crossbow]: http://bowtie-bio.sf.net/crossbow +[Myrna]: http://bowtie-bio.sf.net/myrna +[Bowtie paper]: http://genomebiology.com/2009/10/3/R25 +[GPLv3 license]: http://www.gnu.org/licenses/gpl-3.0.html + + +Obtaining HISAT2 +================== + +Download HISAT2 sources and binaries from the Releases sections on the right side. +Binaries are available for Intel architectures (`x86_64`) running Linux, and Mac OS X. + +Building from source +-------------------- + +Building HISAT2 from source requires a GNU-like environment with GCC, GNU Make +and other basics. It should be possible to build HISAT2 on most vanilla Linux +installations or on a Mac installation with [Xcode] installed. HISAT2 can +also be built on Windows using [Cygwin] or [MinGW] (MinGW recommended). For a +MinGW build the choice of what compiler is to be used is important since this +will determine if a 32 or 64 bit code can be successfully compiled using it. If +there is a need to generate both 32 and 64 bit on the same machine then a multilib +MinGW has to be properly installed. [MSYS], the [zlib] library, and depending on +architecture [pthreads] library are also required. We are recommending a 64 bit +build since it has some clear advantages in real life research problems. In order +to simplify the MinGW setup it might be worth investigating popular MinGW personal +builds since these are coming already prepared with most of the toolchains needed. + +First, download the [source package] from the Releases section on the right side. +Unzip the file, change to the unzipped directory, and build the +HISAT2 tools by running GNU `make` (usually with the command `make`, but +sometimes with `gmake`) with no arguments. If building with MinGW, run `make` +from the MSYS environment. + +HISAT2 is using the multithreading software model in order to speed up +execution times on SMP architectures where this is possible. On POSIX +platforms (like linux, Mac OS, etc) it needs the pthread library. Although +it is possible to use pthread library on non-POSIX platform like Windows, due +to performance reasons HISAT2 will try to use Windows native multithreading +if possible. + +For the support of SRA data access in HISAT2, please download and install the [NCBI-NGS] toolkit. +When running `make`, specify additional variables as follow. +`make USE_SRA=1 NCBI_NGS_DIR=/path/to/NCBI-NGS-directory NCBI_VDB_DIR=/path/to/NCBI-NGS-directory`, +where `NCBI_NGS_DIR` and `NCBI_VDB_DIR` will be used in Makefile for -I and -L compilation options. +For example, $(NCBI_NGS_DIR)/include and $(NCBI_NGS_DIR)/lib64 will be used. + +[Cygwin]: http://www.cygwin.com/ +[MinGW]: http://www.mingw.org/ +[MSYS]: http://www.mingw.org/wiki/msys +[zlib]: http://cygwin.com/packages/mingw-zlib/ +[pthreads]: http://sourceware.org/pthreads-win32/ +[GnuWin32]: http://gnuwin32.sf.net/packages/coreutils.htm +[Download]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/ +[sourceforge site]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/ +[source package]: http://ccb.jhu.edu/software/hisat2/downloads/hisat2-2.0.0-beta-source.zip +[Xcode]: http://developer.apple.com/xcode/ +[NCBI-NGS]: https://github.com/ncbi/ngs/wiki/Downloads + +Running HISAT2 +============= + +Adding to PATH +-------------- + +By adding your new HISAT2 directory to your [PATH environment variable], you +ensure that whenever you run `hisat2`, `hisat2-build` or `hisat2-inspect` +from the command line, you will get the version you just installed without +having to specify the entire path. This is recommended for most users. To do +this, follow your operating system's instructions for adding the directory to +your [PATH]. + +If you would like to install HISAT2 by copying the HISAT2 executable files +to an existing directory in your [PATH], make sure that you copy all the +executables, including `hisat2`, `hisat2-align-s`, `hisat2-align-l`, `hisat2-build`, `hisat2-build-s`, `hisat2-build-l`, `hisat2-inspect`, `hisat2-inspect-s` and +`hisat2-inspect-l`. + +[PATH environment variable]: http://en.wikipedia.org/wiki/PATH_(variable) +[PATH]: http://en.wikipedia.org/wiki/PATH_(variable) + +Reporting +--------- + +The reporting mode governs how many alignments HISAT2 looks for, and how to +report them. + +In general, when we say that a read has an alignment, we mean that it has a +[valid alignment]. When we say that a read has multiple alignments, we mean +that it has multiple alignments that are valid and distinct from one another. + +[valid alignment]: #valid-alignments-meet-or-exceed-the-minimum-score-threshold + +By default, HISAT2 may soft-clip reads near their 5' and 3' ends. Users can control this behavior by setting different penalties for soft-clipping ([`--sp`]) or by disallowing soft-clipping ([`--no-softclip`]). + +### Distinct alignments map a read to different places + +Two alignments for the same individual read are "distinct" if they map the same +read to different places. Specifically, we say that two alignments are distinct +if there are no alignment positions where a particular read offset is aligned +opposite a particular reference offset in both alignments with the same +orientation. E.g. if the first alignment is in the forward orientation and +aligns the read character at read offset 10 to the reference character at +chromosome 3, offset 3,445,245, and the second alignment is also in the forward +orientation and also aligns the read character at read offset 10 to the +reference character at chromosome 3, offset 3,445,245, they are not distinct +alignments. + +Two alignments for the same pair are distinct if either the mate 1s in the two +paired-end alignments are distinct or the mate 2s in the two alignments are +distinct or both. + +### Default mode: search for one or more alignments, report each + +HISAT2 searches for up to N distinct, primary alignments for +each read, where N equals the integer specified with the `-k` parameter. +Primary alignments mean alignments whose alignment score is equal or higher than any other alignments. +It is possible that multiple distinct alignments have the same score. +That is, if `-k 2` is specified, HISAT2 will search for at most 2 distinct +alignments. The alignment score for a paired-end alignment equals the sum of the +alignment scores of the individual mates. Each reported read or pair alignment +beyond the first has the SAM 'secondary' bit (which equals 256) set in its FLAGS +field. See the [SAM specification] for details. + +HISAT2 does not "find" alignments in any specific order, so for reads that +have more than N distinct, valid alignments, HISAT2 does not guarantee that +the N alignments reported are the best possible in terms of alignment score. +Still, this mode can be effective and fast in situations where the user cares +more about whether a read aligns (or aligns a certain number of times) than +where exactly it originated. + + +[SAM specification]: http://samtools.sourceforge.net/SAM1.pdf + +Alignment summary +------------------ + +When HISAT2 finishes running, it prints messages summarizing what happened. +These messages are printed to the "standard error" ("stderr") filehandle. For +datasets consisting of unpaired reads, the summary might look like this: + + 20000 reads; of these: + 20000 (100.00%) were unpaired; of these: + 1247 (6.24%) aligned 0 times + 18739 (93.69%) aligned exactly 1 time + 14 (0.07%) aligned >1 times + 93.77% overall alignment rate + +For datasets consisting of pairs, the summary might look like this: + + 10000 reads; of these: + 10000 (100.00%) were paired; of these: + 650 (6.50%) aligned concordantly 0 times + 8823 (88.23%) aligned concordantly exactly 1 time + 527 (5.27%) aligned concordantly >1 times + ---- + 650 pairs aligned concordantly 0 times; of these: + 34 (5.23%) aligned discordantly 1 time + ---- + 616 pairs aligned 0 times concordantly or discordantly; of these: + 1232 mates make up the pairs; of these: + 660 (53.57%) aligned 0 times + 571 (46.35%) aligned exactly 1 time + 1 (0.08%) aligned >1 times + 96.70% overall alignment rate + +The indentation indicates how subtotals relate to totals. + +Wrapper +------- + +The `hisat2`, `hisat2-build` and `hisat2-inspect` executables are actually +wrapper scripts that call binary programs as appropriate. The wrappers shield +users from having to distinguish between "small" and "large" index formats, +discussed briefly in the following section. Also, the `hisat2` wrapper +provides some key functionality, like the ability to handle compressed inputs, +and the functionality for [`--un`], [`--al`] and related options. + +It is recommended that you always run the hisat2 wrappers and not run the +binaries directly. + +Small and large indexes +----------------------- + +`hisat2-build` can index reference genomes of any size. For genomes less than +about 4 billion nucleotides in length, `hisat2-build` builds a "small" index +using 32-bit numbers in various parts of the index. When the genome is longer, +`hisat2-build` builds a "large" index using 64-bit numbers. Small indexes are +stored in files with the `.ht2` extension, and large indexes are stored in +files with the `.ht2l` extension. The user need not worry about whether a +particular index is small or large; the wrapper scripts will automatically build +and use the appropriate index. + +Performance tuning +------------------ + +1. If your computer has multiple processors/cores, use `-p` + + The [`-p`] option causes HISAT2 to launch a specified number of parallel + search threads. Each thread runs on a different processor/core and all + threads find alignments in parallel, increasing alignment throughput by + approximately a multiple of the number of threads (though in practice, + speedup is somewhat worse than linear). + +Command Line +------------ + +### Setting function options + +Some HISAT2 options specify a function rather than an individual number or +setting. In these cases the user specifies three parameters: (a) a function +type `F`, (b) a constant term `B`, and (c) a coefficient `A`. The available +function types are constant (`C`), linear (`L`), square-root (`S`), and natural +log (`G`). The parameters are specified as `F,B,A` - that is, the function type, +the constant term, and the coefficient are separated by commas with no +whitespace. The constant term and coefficient may be negative and/or +floating-point numbers. + +For example, if the function specification is `L,-0.4,-0.6`, then the function +defined is: + + f(x) = -0.4 + -0.6 * x + +If the function specification is `G,1,5.4`, then the function defined is: + + f(x) = 1.0 + 5.4 * ln(x) + +See the documentation for the option in question to learn what the parameter `x` +is for. For example, in the case if the [`--score-min`] option, the function +`f(x)` sets the minimum alignment score necessary for an alignment to be +considered valid, and `x` is the read length. + +### Usage + + hisat2 [options]* -x {-1 -2 | -U | --sra-acc } [-S ] + +### Main arguments + +
+ +[`-x`]: #hisat2-options-x + + -x + + + +The basename of the index for the reference genome. The basename is the name of +any of the index files up to but not including the final `.1.ht2` / etc. +`hisat2` looks for the specified index first in the current directory, +then in the directory specified in the `HISAT2_INDEXES` environment variable. + +
+ +[`-1`]: #hisat2-options-1 + + -1 + + + +Comma-separated list of files containing mate 1s (filename usually includes +`_1`), e.g. `-1 flyA_1.fq,flyB_1.fq`. Sequences specified with this option must +correspond file-for-file and read-for-read with those specified in ``. Reads +may be a mix of different lengths. If `-` is specified, `hisat2` will read the +mate 1s from the "standard in" or "stdin" filehandle. + +
+ +[`-2`]: #hisat2-options-2 + + -2 + + + +Comma-separated list of files containing mate 2s (filename usually includes +`_2`), e.g. `-2 flyA_2.fq,flyB_2.fq`. Sequences specified with this option must +correspond file-for-file and read-for-read with those specified in ``. Reads +may be a mix of different lengths. If `-` is specified, `hisat2` will read the +mate 2s from the "standard in" or "stdin" filehandle. + +
+ +[`-U`]: #hisat2-options-U + + -U + + + +Comma-separated list of files containing unpaired reads to be aligned, e.g. +`lane1.fq,lane2.fq,lane3.fq,lane4.fq`. Reads may be a mix of different lengths. +If `-` is specified, `hisat2` gets the reads from the "standard in" or "stdin" +filehandle. + +
+ +[`--sra-acc`]: #hisat2-options-sra-acc + + --sra-acc + + + +Comma-separated list of SRA accession numbers, e.g. `--sra-acc SRR353653,SRR353654`. +Information about read types is available at http://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi?sp=runinfo&acc=sra-acc&retmode=xml, +where sra-acc is SRA accession number. If users run HISAT2 on a computer cluster, it is recommended to disable SRA-related caching (see the instruction at [SRA-MANUAL]). + +[SRA-MANUAL]: https://github.com/ncbi/sra-tools/wiki/Toolkit-Configuration + +
+ +[`-S`]: #hisat2-options-S + + -S + + + +File to write SAM alignments to. By default, alignments are written to the +"standard out" or "stdout" filehandle (i.e. the console). + +
+ +### Options + +#### Input options + + + + + + + + + + + + + +
+ +[`-q`]: #hisat2-options-q + + -q + + + +Reads (specified with ``, ``, ``) are FASTQ files. FASTQ files +usually have extension `.fq` or `.fastq`. FASTQ is the default format. See +also: [`--solexa-quals`] and [`--int-quals`]. + +
+ +[`--qseq`]: #hisat2-options-qseq + + --qseq + + + +Reads (specified with ``, ``, ``) are QSEQ files. QSEQ files usually +end in `_qseq.txt`. See also: [`--solexa-quals`] and [`--int-quals`]. + +
+ +[`-f`]: #hisat2-options-f + + -f + + + +Reads (specified with ``, ``, ``) are FASTA files. FASTA files +usually have extension `.fa`, `.fasta`, `.mfa`, `.fna` or similar. FASTA files +do not have a way of specifying quality values, so when `-f` is set, the result +is as if `--ignore-quals` is also set. + +
+ +[`-r`]: #hisat2-options-r + + -r + + + +Reads (specified with ``, ``, ``) are files with one input sequence +per line, without any other information (no read names, no qualities). When +`-r` is set, the result is as if `--ignore-quals` is also set. + +
+ +[`-c`]: #hisat2-options-c + + -c + + + +The read sequences are given on command line. I.e. ``, `` and +`` are comma-separated lists of reads rather than lists of read files. +There is no way to specify read names or qualities, so `-c` also implies +`--ignore-quals`. + +
+ +[`-s`/`--skip`]: #hisat2-options-s +[`-s`]: #hisat2-options-s + + -s/--skip + + + +Skip (i.e. do not align) the first `` reads or pairs in the input. + +
+ +[`-u`/`--qupto`]: #hisat2-options-u +[`-u`]: #hisat2-options-u + + -u/--qupto + + + +Align the first `` reads or read pairs from the input (after the +[`-s`/`--skip`] reads or pairs have been skipped), then stop. Default: no limit. + +
+ +[`-5`/`--trim5`]: #hisat2-options-5 +[`-5`]: #hisat2-options-5 + + -5/--trim5 + + + +Trim `` bases from 5' (left) end of each read before alignment (default: 0). + +
+ +[`-3`/`--trim3`]: #hisat2-options-3 +[`-3`]: #hisat2-options-3 + + -3/--trim3 + + + +Trim `` bases from 3' (right) end of each read before alignment (default: +0). + +
+ +[`--phred33`]: #hisat2-options-phred33-quals + + --phred33 + + + +Input qualities are ASCII chars equal to the [Phred quality] plus 33. This is +also called the "Phred+33" encoding, which is used by the very latest Illumina +pipelines. + +[Phred quality]: http://en.wikipedia.org/wiki/Phred_quality_score + +
+ +[`--phred64`]: #hisat2-options-phred64-quals + + --phred64 + + + +Input qualities are ASCII chars equal to the [Phred quality] plus 64. This is +also called the "Phred+64" encoding. + +
+ +[`--solexa-quals`]: #hisat2-options-solexa-quals + + --solexa-quals + + + +Convert input qualities from [Solexa][Phred quality] (which can be negative) to +[Phred][Phred quality] (which can't). This scheme was used in older Illumina GA +Pipeline versions (prior to 1.3). Default: off. + +
+ +[`--int-quals`]: #hisat2-options-int-quals + + --int-quals + + + +Quality values are represented in the read input file as space-separated ASCII +integers, e.g., `40 40 30 40`..., rather than ASCII characters, e.g., `II?I`.... + Integers are treated as being on the [Phred quality] scale unless +[`--solexa-quals`] is also specified. Default: off. + +
+ +#### Alignment options + + + + + + + + +
+ +[`--n-ceil`]: #hisat2-options-n-ceil + + --n-ceil + + + +Sets a function governing the maximum number of ambiguous characters (usually +`N`s and/or `.`s) allowed in a read as a function of read length. For instance, +specifying `-L,0,0.15` sets the N-ceiling function `f` to `f(x) = 0 + 0.15 * x`, +where x is the read length. See also: [setting function options]. Reads +exceeding this ceiling are [filtered out]. Default: `L,0,0.15`. + +[filtered out]: #filtering + +
+ +[`--ignore-quals`]: #hisat2-options-ignore-quals + + --ignore-quals + + + +When calculating a mismatch penalty, always consider the quality value at the +mismatched position to be the highest possible, regardless of the actual value. +I.e. input is treated as though all quality values are high. This is also the +default behavior when the input doesn't specify quality values (e.g. in [`-f`], +[`-r`], or [`-c`] modes). + +
+ +[`--nofw`]: #hisat2-options-nofw + + --nofw/--norc + + + +If `--nofw` is specified, `hisat2` will not attempt to align unpaired reads to +the forward (Watson) reference strand. If `--norc` is specified, `hisat2` will +not attempt to align unpaired reads against the reverse-complement (Crick) +reference strand. In paired-end mode, `--nofw` and `--norc` pertain to the +fragments; i.e. specifying `--nofw` causes `hisat2` to explore only those +paired-end configurations corresponding to fragments from the reverse-complement +(Crick) strand. Default: both strands enabled. + +
+ +#### Scoring options + + + + + + + + + + + +
+ +[`--mp`]: #hisat2-options-mp + + --mp MX,MN + + + +Sets the maximum (`MX`) and minimum (`MN`) mismatch penalties, both integers. A +number less than or equal to `MX` and greater than or equal to `MN` is +subtracted from the alignment score for each position where a read character +aligns to a reference character, the characters do not match, and neither is an +`N`. If [`--ignore-quals`] is specified, the number subtracted quals `MX`. +Otherwise, the number subtracted is `MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) )` +where Q is the Phred quality value. Default: `MX` = 6, `MN` = 2. + +
+ +[`--sp`]: #hisat2-options-sp + + --sp MX,MN + + + +Sets the maximum (`MX`) and minimum (`MN`) penalties for soft-clipping per base, +both integers. A number less than or equal to `MX` and greater than or equal to `MN` is +subtracted from the alignment score for each position. +The number subtracted is `MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) )` +where Q is the Phred quality value. Default: `MX` = 2, `MN` = 1. + +
+ +[`--sp`]: #hisat2-options-no-softclip + + --no-softclip + + + +Disallow soft-clipping. + +
+ +[`--np`]: #hisat2-options-np + + --np + + + +Sets penalty for positions where the read, reference, or both, contain an +ambiguous character such as `N`. Default: 1. + +
+ +[`--rdg`]: #hisat2-options-rdg + + --rdg , + + + +Sets the read gap open (``) and extend (``) penalties. A read gap of +length N gets a penalty of `` + N * ``. Default: 5, 3. + +
+ +[`--rfg`]: #hisat2-options-rfg + + --rfg , + + + +Sets the reference gap open (``) and extend (``) penalties. A +reference gap of length N gets a penalty of `` + N * ``. Default: +5, 3. + +
+ +[`--score-min`]: #hisat2-options-score-min + + --score-min + + + +Sets a function governing the minimum alignment score needed for an alignment to +be considered "valid" (i.e. good enough to report). This is a function of read +length. For instance, specifying `L,0,-0.6` sets the minimum-score function `f` +to `f(x) = 0 + -0.6 * x`, where `x` is the read length. See also: [setting +function options]. The default is `L,0,-0.2`. + +
+ +#### Spliced alignment options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +[`--pen-cansplice`]: #hisat2-options-pen-cansplice + + --pen-cansplice + + + +Sets the penalty for each pair of canonical splice sites (e.g. GT/AG). Default: 0. + +
+ +[`--pen-noncansplice`]: #hisat2-options-pen-noncansplice + + --pen-noncansplice + + + +Sets the penalty for each pair of non-canonical splice sites (e.g. non-GT/AG). Default: 12. + +
+ +[`--pen-canintronlen`]: #hisat2-options-pen-canintronlen + + --pen-canintronlen + + + +Sets the penalty for long introns with canonical splice sites so that alignments with shorter introns are preferred +to those with longer ones. Default: G,-8,1 + +
+ +[`--pen-noncanintronlen`]: #hisat2-options-pen-noncanintronlen + + --pen-noncanintronlen + + + +Sets the penalty for long introns with noncanonical splice sites so that alignments with shorter introns are preferred +to those with longer ones. Default: G,-8,1 + + +
+ +[`--min-intronlen`]: #hisat2-options-min-intronlen + + --min-intronlen + + + +Sets minimum intron length. Default: 20 + +
+ +[`--max-intronlen`]: #hisat2-options-max-intronlen + + --max-intronlen + + + +Sets maximum intron length. Default: 500000 + +
+ +[`--splice-infile`]: #hisat2-options-known-splicesite-infile + + --known-splicesite-infile + + + +With this mode, you can provide a list of known splice sites, which HISAT2 makes use of to align reads with small anchors. +You can create such a list using `python hisat2_extract_splice_sites.py genes.gtf > splicesites.txt`, +where `hisat2_extract_splice_sites.py` is included in the HISAT2 package, `genes.gtf` is a gene annotation file, +and `splicesites.txt` is a list of splice sites with which you provide HISAT2 in this mode. +Note that it is better to use indexes built using annotated transcripts (such as genome_tran or genome_snp_tran), which works better +than using this option. It has no effect to provide splice sites that are already included in the indexes. + +
+ +[`--novel-splicesite-outfile`]: #hisat2-options-novel-splicesite-outfile + + --novel-splicesite-outfile + + + +In this mode, HISAT2 reports a list of splice sites in the file : + chromosome name `` genomic position of the flanking base on the left side of an intron `` genomic position of the flanking base on the right `` strand (+, -, and .) + '.' indicates an unknown strand for non-canonical splice sites. + +
+ +[`--novel-splicesite-infile`]: #hisat2-options-novel-splicesite-infile + + --novel-splicesite-infile + + + +With this mode, you can provide a list of novel splice sites that were generated from the above option "--novel-splicesite-outfile". + +
+ +[`--no-temp-splicesite`]: #hisat2-options-no-temp-splicesite + + --no-temp-splicesite + + + +HISAT2, by default, makes use of splice sites found by earlier reads to align later reads in the same run, +in particular, reads with small anchors (<= 15 bp). +The option disables this default alignment strategy. + +
+ +[`--no-spliced-alignment`]: #hisat2-options-no-spliced-alignment + + --no-spliced-alignment + + + +Disable spliced alignment. + +
+[`--rna-strandness`]: #hisat2-options-rna-strandness + + --rna-strandness + + + +Specify strand-specific information: the default is unstranded. +For single-end reads, use F or R. + 'F' means a read corresponds to a transcript. + 'R' means a read corresponds to the reverse complemented counterpart of a transcript. +For paired-end reads, use either FR or RF. +With this option being used, every read alignment will have an XS attribute tag: + '+' means a read belongs to a transcript on '+' strand of genome. + '-' means a read belongs to a transcript on '-' strand of genome. + +(TopHat has a similar option, --library-type option, where fr-firststrand corresponds to R and RF; fr-secondstrand corresponds to F and FR.) +
+[`--tmo/--transcriptome-mapping-only`]: #hisat2-options-tmo + + --tmo/--transcriptome-mapping-only + + + +Report only those alignments within known transcripts. + +
+[`--dta/--downstream-transcriptome-assembly`]: #hisat2-options-dta + + --dta/--downstream-transcriptome-assembly + + + +Report alignments tailored for transcript assemblers including StringTie. +With this option, HISAT2 requires longer anchor lengths for de novo discovery of splice sites. +This leads to fewer alignments with short-anchors, +which helps transcript assemblers improve significantly in computation and memory usage. + +
+ +Report alignments tailored specifically for Cufflinks. In addition to what HISAT2 does with the above option (--dta), +With this option, HISAT2 looks for novel splice sites with three signals (GT/AG, GC/AG, AT/AC), but all user-provided splice sites are used irrespective of their signals. +HISAT2 produces an optional field, XS:A:[+-], for every spliced alignment. + +
+[`--avoid-pseudogene`]: #hisat2-options-avoid-pseudogene + + --avoid-pseudogene + + + +Try to avoid aligning reads to pseudogenes. Note this option is experimental and needs further investigation. + +
+[`--no-templatelen-adjustment`]: #hisat2-options-no-templatelen-adjustment + + --no-templatelen-adjustment + + + +Disables template length adjustment for RNA-seq reads. + +
+ +#### Reporting options + + + + + + + + +
+ +[`-k`]: #hisat2-options-k + + -k + + + +It searches for at most `` distinct, primary alignments for each read. +Primary alignments mean alignments whose alignment score is equal or higher than any other alignments. +The search terminates when it can't find more distinct valid alignments, or when it +finds ``, whichever happens first. The alignment score for a paired-end +alignment equals the sum of the alignment scores of the individual mates. Each +reported read or pair alignment beyond the first has the SAM 'secondary' bit +(which equals 256) set in its FLAGS field. For reads that have more than +`` distinct, valid alignments, `hisat2` does not guarantee that the +`` alignments reported are the best possible in terms of alignment score. Default: 5 (HFM) or 10 (HGFM) + +Note: HISAT2 is not designed with large values for `-k` in mind, and when +aligning reads to long, repetitive genomes large `-k` can be very, very slow. + +
+ +[`--max-seeds`]: #hisat2-options-max-seeds + + --max-seeds + + + +HISAT2, like other aligners, uses seed-and-extend approaches. HISAT2 tries to extend seeds to full-length alignments. In HISAT2, --max-seeds is used to control the maximum number of seeds that will be extended. HISAT2 extends up to these many seeds and skips the rest of the seeds. Large values for `--max-seeds` may improve alignment sensitivity, but HISAT2 is not designed with large values for `--max-seeds` in mind, and when aligning reads to long, repetitive genomes large `--max-seeds` can be very, very slow. The default value is the maximum of 5 and the value that comes with`-k`. + +
+ +[`--secondary`]: #hisat2-options-secondary + + --secondary + + + +Report secondary alignments. + +
+ +#### Paired-end options + + + + + + + +
+ +[`-I`/`--minins`]: #hisat2-options-I +[`-I`]: #hisat2-options-I + + -I/--minins + + + +The minimum fragment length for valid paired-end alignments.This option is valid only with --no-spliced-alignment. +E.g. if `-I 60` is specified and a paired-end alignment consists of two 20-bp alignments in the +appropriate orientation with a 20-bp gap between them, that alignment is +considered valid (as long as [`-X`] is also satisfied). A 19-bp gap would not +be valid in that case. If trimming options [`-3`] or [`-5`] are also used, the +[`-I`] constraint is applied with respect to the untrimmed mates. + +The larger the difference between [`-I`] and [`-X`], the slower HISAT2 will +run. This is because larger differences between [`-I`] and [`-X`] require that +HISAT2 scan a larger window to determine if a concordant alignment exists. +For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very +efficient. + +Default: 0 (essentially imposing no minimum) + +
+ +[`-X`/`--maxins`]: #hisat2-options-X +[`-X`]: #hisat2-options-X + + -X/--maxins + + + +The maximum fragment length for valid paired-end alignments. This option is valid only with --no-spliced-alignment. +E.g. if `-X 100` is specified and a paired-end alignment consists of two 20-bp alignments in the +proper orientation with a 60-bp gap between them, that alignment is considered +valid (as long as [`-I`] is also satisfied). A 61-bp gap would not be valid in +that case. If trimming options [`-3`] or [`-5`] are also used, the `-X` +constraint is applied with respect to the untrimmed mates, not the trimmed +mates. + +The larger the difference between [`-I`] and [`-X`], the slower HISAT2 will +run. This is because larger differences between [`-I`] and [`-X`] require that +HISAT2 scan a larger window to determine if a concordant alignment exists. +For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very +efficient. + +Default: 500. + +
+ +[`--fr`/`--rf`/`--ff`]: #hisat2-options-fr +[`--fr`]: #hisat2-options-fr +[`--rf`]: #hisat2-options-fr +[`--ff`]: #hisat2-options-fr + + --fr/--rf/--ff + + + +The upstream/downstream mate orientations for a valid paired-end alignment +against the forward reference strand. E.g., if `--fr` is specified and there is +a candidate paired-end alignment where mate 1 appears upstream of the reverse +complement of mate 2 and the fragment length constraints ([`-I`] and [`-X`]) are +met, that alignment is valid. Also, if mate 2 appears upstream of the reverse +complement of mate 1 and all other constraints are met, that too is valid. +`--rf` likewise requires that an upstream mate1 be reverse-complemented and a +downstream mate2 be forward-oriented. ` --ff` requires both an upstream mate 1 +and a downstream mate 2 to be forward-oriented. Default: `--fr` (appropriate +for Illumina's Paired-end Sequencing Assay). + +
+ +[`--no-mixed`]: #hisat2-options-no-mixed + + --no-mixed + + + +By default, when `hisat2` cannot find a concordant or discordant alignment for +a pair, it then tries to find alignments for the individual mates. This option +disables that behavior. + +
+ +[`--no-discordant`]: #hisat2-options-no-discordant + + --no-discordant + + + +By default, `hisat2` looks for discordant alignments if it cannot find any +concordant alignments. A discordant alignment is an alignment where both mates +align uniquely, but that does not satisfy the paired-end constraints +([`--fr`/`--rf`/`--ff`], [`-I`], [`-X`]). This option disables that behavior. + +
+ +#### Output options + + + + + + + + + + + + + + + + + +
+ +[`-t`/`--time`]: #hisat2-options-t +[`-t`]: #hisat2-options-t + + -t/--time + + + +Print the wall-clock time required to load the index files and align the reads. +This is printed to the "standard error" ("stderr") filehandle. Default: off. + +
+ +[`--un`]: #hisat2-options-un +[`--un-gz`]: #hisat2-options-un +[`--un-bz2`]: #hisat2-options-un + + --un + --un-gz + --un-bz2 + + + +Write unpaired reads that fail to align to file at ``. These reads +correspond to the SAM records with the FLAGS `0x4` bit set and neither the +`0x40` nor `0x80` bits set. If `--un-gz` is specified, output will be gzip +compressed. If `--un-bz2` is specified, output will be bzip2 compressed. Reads +written in this way will appear exactly as they did in the input file, without +any modification (same sequence, same name, same quality string, same quality +encoding). Reads will not necessarily appear in the same order as they did in +the input. + +
+ +[`--al`]: #hisat2-options-al +[`--al-gz`]: #hisat2-options-al +[`--al-bz2`]: #hisat2-options-al + + --al + --al-gz + --al-bz2 + + + +Write unpaired reads that align at least once to file at ``. These reads +correspond to the SAM records with the FLAGS `0x4`, `0x40`, and `0x80` bits +unset. If `--al-gz` is specified, output will be gzip compressed. If `--al-bz2` +is specified, output will be bzip2 compressed. Reads written in this way will +appear exactly as they did in the input file, without any modification (same +sequence, same name, same quality string, same quality encoding). Reads will +not necessarily appear in the same order as they did in the input. + +
+ +[`--un-conc`]: #hisat2-options-un-conc +[`--un-conc-gz`]: #hisat2-options-un-conc +[`--un-conc-bz2`]: #hisat2-options-un-conc + + --un-conc + --un-conc-gz + --un-conc-bz2 + + + +Write paired-end reads that fail to align concordantly to file(s) at ``. +These reads correspond to the SAM records with the FLAGS `0x4` bit set and +either the `0x40` or `0x80` bit set (depending on whether it's mate #1 or #2). +`.1` and `.2` strings are added to the filename to distinguish which file +contains mate #1 and mate #2. If a percent symbol, `%`, is used in ``, +the percent symbol is replaced with `1` or `2` to make the per-mate filenames. +Otherwise, `.1` or `.2` are added before the final dot in `` to make the +per-mate filenames. Reads written in this way will appear exactly as they did +in the input files, without any modification (same sequence, same name, same +quality string, same quality encoding). Reads will not necessarily appear in +the same order as they did in the inputs. + +
+ +[`--al-conc`]: #hisat2-options-al-conc +[`--al-conc-gz`]: #hisat2-options-al-conc +[`--al-conc-bz2`]: #hisat2-options-al-conc + + --al-conc + --al-conc-gz + --al-conc-bz2 + + + +Write paired-end reads that align concordantly at least once to file(s) at +``. These reads correspond to the SAM records with the FLAGS `0x4` bit +unset and either the `0x40` or `0x80` bit set (depending on whether it's mate #1 +or #2). `.1` and `.2` strings are added to the filename to distinguish which +file contains mate #1 and mate #2. If a percent symbol, `%`, is used in +``, the percent symbol is replaced with `1` or `2` to make the per-mate +filenames. Otherwise, `.1` or `.2` are added before the final dot in `` to +make the per-mate filenames. Reads written in this way will appear exactly as +they did in the input files, without any modification (same sequence, same name, +same quality string, same quality encoding). Reads will not necessarily appear +in the same order as they did in the inputs. + +
+ +[`--quiet`]: #hisat2-options-quiet + + --quiet + + + +Print nothing besides alignments and serious errors. + +
+ +[`--summary-file`]: #hisat2-options-summary-file + + --summary-file + + + +Print alignment summary to this file. + +
+ +[`--new-summary`]: #hisat2-options-new-summary + + --new-summary + + + +Print alignment summary in a new style, which is more machine-friendly. + +
+ +[`--met-file`]: #hisat2-options-met-file + + --met-file + + + +Write `hisat2` metrics to file ``. Having alignment metric can be useful +for debugging certain problems, especially performance issues. See also: +[`--met`]. Default: metrics disabled. + +
+ +[`--met-stderr`]: #hisat2-options-met-stderr + + --met-stderr + + + +Write `hisat2` metrics to the "standard error" ("stderr") filehandle. This is +not mutually exclusive with [`--met-file`]. Having alignment metric can be +useful for debugging certain problems, especially performance issues. See also: +[`--met`]. Default: metrics disabled. + +
+ +[`--met`]: #hisat2-options-met + + --met + + + +Write a new `hisat2` metrics record every `` seconds. Only matters if +either [`--met-stderr`] or [`--met-file`] are specified. Default: 1. + +
+ +#### SAM options + + + + + + + + + + + + + +
+ +[`--no-unal`]: #hisat2-options-no-unal + + --no-unal + + + +Suppress SAM records for reads that failed to align. + +
+ +[`--no-hd`]: #hisat2-options-no-hd + + --no-hd + + + +Suppress SAM header lines (starting with `@`). + +
+ +[`--no-sq`]: #hisat2-options-no-sq + + --no-sq + + + +Suppress `@SQ` SAM header lines. + +
+ +[`--rg-id`]: #hisat2-options-rg-id + + --rg-id + + + +Set the read group ID to ``. This causes the SAM `@RG` header line to be +printed, with `` as the value associated with the `ID:` tag. It also +causes the `RG:Z:` extra field to be attached to each SAM output record, with +value set to ``. + +
+ +[`--rg`]: #hisat2-options-rg + + --rg + + + +Add `` (usually of the form `TAG:VAL`, e.g. `SM:Pool1`) as a field on the +`@RG` header line. Note: in order for the `@RG` line to appear, [`--rg-id`] +must also be specified. This is because the `ID` tag is required by the [SAM +Spec][SAM]. Specify `--rg` multiple times to set multiple fields. See the +[SAM Spec][SAM] for details about what fields are legal. + + +
+ +[`--remove-chrname`]: #hisat2-remove-chrname + + --remove-chrname + + + +Remove 'chr' from reference names in alignment (e.g., chr18 to 18) + +
+ +[`--add-chrname`]: #hisat2-options-add-chrname + + --add-chrname + + + +Add 'chr' to reference names in alignment (e.g., 18 to chr18) + +
+ +[`--omit-sec-seq`]: #hisat2-options-omit-sec-seq + + --omit-sec-seq + + + +When printing secondary alignments, HISAT2 by default will write out the `SEQ` +and `QUAL` strings. Specifying this option causes HISAT2 to print an asterisk +in those fields instead. + +
+ +#### Performance options + + + + + + +
+ +[`-o`/`--offrate`]: #hisat2-options-o +[`-o`]: #hisat2-options-o +[`--offrate`]: #hisat2-options-o + + -o/--offrate + + + +Override the offrate of the index with ``. If `` is greater +than the offrate used to build the index, then some row markings are +discarded when the index is read into memory. This reduces the memory +footprint of the aligner but requires more time to calculate text +offsets. `` must be greater than the value used to build the +index. + +
+ +[`-p`/`--threads`]: #hisat2-options-p +[`-p`]: #hisat2-options-p + + -p/--threads NTHREADS + + + +Launch `NTHREADS` parallel search threads (default: 1). Threads will run on +separate processors/cores and synchronize when parsing reads and outputting +alignments. Searching for alignments is highly parallel, and speedup is close +to linear. Increasing `-p` increases HISAT2's memory footprint. E.g. when +aligning to a human genome index, increasing `-p` from 1 to 8 increases the +memory footprint by a few hundred megabytes. This option is only available if +`bowtie` is linked with the `pthreads` library (i.e. if `BOWTIE_PTHREADS=0` is +not specified at build time). + +
+ +[`--reorder`]: #hisat2-options-reorder + + --reorder + + + +Guarantees that output SAM records are printed in an order corresponding to the +order of the reads in the original input file, even when [`-p`] is set greater +than 1. Specifying `--reorder` and setting [`-p`] greater than 1 causes HISAT2 +to run somewhat slower and use somewhat more memory then if `--reorder` were +not specified. Has no effect if [`-p`] is set to 1, since output order will +naturally correspond to input order in that case. + +
+ +[`--mm`]: #hisat2-options-mm + + --mm + + + +Use memory-mapped I/O to load the index, rather than typical file I/O. +Memory-mapping allows many concurrent `bowtie` processes on the same computer to +share the same memory image of the index (i.e. you pay the memory overhead just +once). This facilitates memory-efficient parallelization of `bowtie` in +situations where using [`-p`] is not possible or not preferable. + +
+ +#### Other options + + + + + + +
+ +[`--qc-filter`]: #hisat2-options-qc-filter + + --qc-filter + + + +Filter out reads for which the QSEQ filter field is non-zero. Only has an +effect when read format is [`--qseq`]. Default: off. + +
+ +[`--seed`]: #hisat2-options-seed + + --seed + + + +Use `` as the seed for pseudo-random number generator. Default: 0. + +
+ +[`--non-deterministic`]: #hisat2-options-non-deterministic + + --non-deterministic + + + +Normally, HISAT2 re-initializes its pseudo-random generator for each read. It +seeds the generator with a number derived from (a) the read name, (b) the +nucleotide sequence, (c) the quality sequence, (d) the value of the [`--seed`] +option. This means that if two reads are identical (same name, same +nucleotides, same qualities) HISAT2 will find and report the same alignment(s) +for both, even if there was ambiguity. When `--non-deterministic` is specified, +HISAT2 re-initializes its pseudo-random generator for each read using the +current time. This means that HISAT2 will not necessarily report the same +alignment for two identical reads. This is counter-intuitive for some users, +but might be more appropriate in situations where the input consists of many +identical reads. + +
+ +[`--version`]: #hisat2-options-version + + --version + + + +Print version information and quit. + +
+ + -h/--help + + + +Print usage information and quit. + +
+ +SAM output +---------- + +Following is a brief description of the [SAM] format as output by `hisat2`. +For more details, see the [SAM format specification][SAM]. + +By default, `hisat2` prints a SAM header with `@HD`, `@SQ` and `@PG` lines. +When one or more [`--rg`] arguments are specified, `hisat2` will also print +an `@RG` line that includes all user-specified [`--rg`] tokens separated by +tabs. + +Each subsequent line describes an alignment or, if the read failed to align, a +read. Each line is a collection of at least 12 fields separated by tabs; from +left to right, the fields are: + +1. Name of read that aligned. + + Note that the [SAM specification] disallows whitespace in the read name. + If the read name contains any whitespace characters, HISAT2 will truncate + the name at the first whitespace character. This is similar to the + behavior of other tools. + +2. Sum of all applicable flags. Flags relevant to HISAT2 are: + +
+ + 1 + + + + The read is one of a pair + +
+ + 2 + + + + The alignment is one end of a proper paired-end alignment + +
+ + 4 + + + + The read has no reported alignments + +
+ + 8 + + + + The read is one of a pair and has no reported alignments + +
+ + 16 + + + + The alignment is to the reverse reference strand + +
+ + 32 + + + + The other mate in the paired-end alignment is aligned to the + reverse reference strand + +
+ + 64 + + + + The read is mate 1 in a pair + +
+ + 128 + + + + The read is mate 2 in a pair + +
+ + Thus, an unpaired read that aligns to the reverse reference strand + will have flag 16. A paired-end read that aligns and is the first + mate in the pair will have flag 83 (= 64 + 16 + 2 + 1). + +3. Name of reference sequence where alignment occurs + +4. 1-based offset into the forward reference strand where leftmost + character of the alignment occurs + +5. Mapping quality. Mapping quality of HISAT2 + +6. CIGAR string representation of alignment + +7. Name of reference sequence where mate's alignment occurs. Set to `=` if the +mate's reference sequence is the same as this alignment's, or `*` if there is no +mate. + +8. 1-based offset into the forward reference strand where leftmost character of +the mate's alignment occurs. Offset is 0 if there is no mate. + +9. Inferred fragment length. Size is negative if the mate's alignment occurs +upstream of this alignment. Size is 0 if the mates did not align concordantly. +However, size is non-0 if the mates aligned discordantly to the same +chromosome. + +10. Read sequence (reverse-complemented if aligned to the reverse strand) + +11. ASCII-encoded read qualities (reverse-complemented if the read aligned to +the reverse strand). The encoded quality values are on the [Phred quality] +scale and the encoding is ASCII-offset by 33 (ASCII char `!`), similarly to a +[FASTQ] file. + +12. Optional fields. Fields are tab-separated. `hisat2` outputs zero or more +of these optional fields for each alignment, depending on the type of the +alignment: + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + AS:i: + + + + Alignment score. Can be negative. Only present if SAM record is for + an aligned read. + +
+ + ZS:i: + + + Alignment score for the best-scoring alignment found other than the + alignment reported. Can be negative. Only present if the SAM record is + for an aligned read and more than one alignment was found for the read. + Note that, when the read is part of a concordantly-aligned pair, this score + could be greater than [`AS:i`]. + +
+ + YS:i: + + + + Alignment score for opposite mate in the paired-end alignment. Only present + if the SAM record is for a read that aligned as part of a paired-end + alignment. + +
+ + XN:i: + + + + The number of ambiguous bases in the reference covering this alignment. + Only present if SAM record is for an aligned read. + +
+ + XM:i: + + + + The number of mismatches in the alignment. Only present if SAM record is + for an aligned read. + +
+ + XO:i: + + + + The number of gap opens, for both read and reference gaps, in the alignment. + Only present if SAM record is for an aligned read. + +
+ + XG:i: + + + + The number of gap extensions, for both read and reference gaps, in the + alignment. Only present if SAM record is for an aligned read. + +
+ + NM:i: + + + + The edit distance; that is, the minimal number of one-nucleotide edits + (substitutions, insertions and deletions) needed to transform the read + string into the reference string. Only present if SAM record is for an + aligned read. + +
+ + YF:Z: + + + + String indicating reason why the read was filtered out. See also: + [Filtering]. Only appears for reads that were filtered out. + +
+ + YT:Z: + + + + Value of `UU` indicates the read was not part of a pair. Value of `CP` + indicates the read was part of a pair and the pair aligned concordantly. + Value of `DP` indicates the read was part of a pair and the pair aligned + discordantly. Value of `UP` indicates the read was part of a pair but the + pair failed to aligned either concordantly or discordantly. + +
+ + MD:Z: + + + + A string representation of the mismatched reference bases in the alignment. + See [SAM] format specification for details. Only present if SAM record is + for an aligned read. + +
+ + XS:A: + + + + Values of `+` and `-` indicate the read is mapped to transcripts on sense and anti-sense + strands, respectively. Spliced alignments need to have this field, which is required in Cufflinks and StringTie. + We can report this field for the canonical-splice site (GT/AG), but not for non-canonical splice sites. + You can direct HISAT2 not to output such alignments (involving non-canonical splice sites) using "--pen-noncansplice 1000000". + +
+ + NH:i: + + + + The number of mapped locations for the read or the pair. + +
+ + Zs:Z: + + + + When the alignment of a read involves SNPs that are in the index, this option is used to indicate where exactly the read involves the SNPs. + This optional field is similar to the above MD:Z field. + For example, `Zs:Z:1|S|rs3747203,97|S|rs16990981` indicates the second base of the read corresponds to a known SNP (ID: rs3747203). + 97 bases after the third base (the base after the second one), the read at 100th base involves another known SNP (ID: rs16990981). + 'S' indicates a single nucleotide polymorphism. 'D' and 'I' indicate a deletion and an insertion, respectively. +
+ +[SAM format specification]: http://samtools.sf.net/SAM1.pdf +[FASTQ]: http://en.wikipedia.org/wiki/FASTQ_format +[`-S`/`--sam`]: #hisat2-options-S +[`-m`]: #hisat2-options-m + +The `hisat2-build` indexer +=========================== + +`hisat2-build` builds a HISAT2 index from a set of DNA sequences. +`hisat2-build` outputs a set of 6 files with suffixes `.1.ht2`, `.2.ht2`, +`.3.ht2`, `.4.ht2`, `.5.ht2`, `.6.ht2`, `.7.ht2`, and `.8.ht2`. In the case of a large +index these suffixes will have a `ht2l` termination. These files together +constitute the index: they are all that is needed to align reads to that +reference. The original sequence FASTA files are no longer used by HISAT2 +once the index is built. + +Use of Karkkainen's [blockwise algorithm] allows `hisat2-build` to trade off +between running time and memory usage. `hisat2-build` has three options +governing how it makes this trade: [`-p`/`--packed`], [`--bmax`]/[`--bmaxdivn`], +and [`--dcv`]. By default, `hisat2-build` will automatically search for the +settings that yield the best running time without exhausting memory. This +behavior can be disabled using the [`-a`/`--noauto`] option. + +The indexer provides options pertaining to the "shape" of the index, e.g. +[`--offrate`](#hisat2-build-options-o) governs the fraction of [Burrows-Wheeler] +rows that are "marked" (i.e., the density of the suffix-array sample; see the +original [FM Index] paper for details). All of these options are potentially +profitable trade-offs depending on the application. They have been set to +defaults that are reasonable for most cases according to our experiments. See +[Performance tuning] for details. + +`hisat2-build` can generate either [small or large indexes](#small-and-large-indexes). The wrapper +will decide which based on the length of the input genome. If the reference +does not exceed 4 billion characters but a large index is preferred, the user +can specify [`--large-index`] to force `hisat2-build` to build a large index +instead. + +The HISAT2 index is based on the [FM Index] of Ferragina and Manzini, which in +turn is based on the [Burrows-Wheeler] transform. The algorithm used to build +the index is based on the [blockwise algorithm] of Karkkainen. + +[Blockwise algorithm]: http://portal.acm.org/citation.cfm?id=1314852 +[Burrows-Wheeler]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[Performance tuning]: #performance-tuning + +Command Line +------------ + +Usage: + + hisat2-build [options]* + +### Notes + If you use --snp, --ss, and/or --exon, hisat2-build will need about 200GB RAM for the human genome size as index building involves a graph construction. + Otherwise, you will be able to build an index on your desktop with 8GB RAM. + +### Main arguments + +
+ + + + + +A comma-separated list of FASTA files containing the reference sequences to be +aligned to, or, if [`-c`](#hisat2-build-options-c) is specified, the sequences +themselves. E.g., `` might be `chr1.fa,chr2.fa,chrX.fa,chrY.fa`, +or, if [`-c`](#hisat2-build-options-c) is specified, this might be +`GGTCATCCT,ACGGGTCGT,CCGTTCTATGCGGCTTA`. + +
+ + + + + +The basename of the index files to write. By default, `hisat2-build` writes +files named `NAME.1.ht2`, `NAME.2.ht2`, `NAME.3.ht2`, `NAME.4.ht2`, +`NAME.5.ht2`, `NAME.6.ht2`, `NAME.7.ht2`, and `NAME.8.ht2` where `NAME` is ``. + +
+ +### Options + + + +
+ + -f + + + +The reference input files (specified as ``) are FASTA files +(usually having extension `.fa`, `.mfa`, `.fna` or similar). + +
+ + -c + + + +The reference sequences are given on the command line. I.e. `` is +a comma-separated list of sequences rather than a list of FASTA files. + +
+ +[`--large-index`]: #hisat2-build-options-large-index + + --large-index + + + +Force `hisat2-build` to build a [large index](#small-and-large-indexes), even if the reference is less +than ~ 4 billion nucleotides long. + +
+ +[`-a`/`--noauto`]: #hisat2-build-options-a + + -a/--noauto + + + +Disable the default behavior whereby `hisat2-build` automatically selects +values for the [`--bmax`], [`--dcv`] and [`--packed`] parameters according to +available memory. Instead, user may specify values for those parameters. If +memory is exhausted during indexing, an error message will be printed; it is up +to the user to try new parameters. + +
+ +[`--bmax`]: #hisat2-build-options-bmax + + --bmax + + + +The maximum number of suffixes allowed in a block. Allowing more suffixes per +block makes indexing faster, but increases peak memory usage. Setting this +option overrides any previous setting for [`--bmax`], or [`--bmaxdivn`]. +Default (in terms of the [`--bmaxdivn`] parameter) is [`--bmaxdivn`] 4. This is +configured automatically by default; use [`-a`/`--noauto`] to configure manually. + +
+ +[`--bmaxdivn`]: #hisat2-build-options-bmaxdivn + + --bmaxdivn + + + +The maximum number of suffixes allowed in a block, expressed as a fraction of +the length of the reference. Setting this option overrides any previous setting +for [`--bmax`], or [`--bmaxdivn`]. Default: [`--bmaxdivn`] 4. This is +configured automatically by default; use [`-a`/`--noauto`] to configure manually. + +
+ +[`--dcv`]: #hisat2-build-options-dcv + + --dcv + + + +Use `` as the period for the difference-cover sample. A larger period +yields less memory overhead, but may make suffix sorting slower, especially if +repeats are present. Must be a power of 2 no greater than 4096. Default: 1024. + This is configured automatically by default; use [`-a`/`--noauto`] to configure +manually. + +
+ +[`--nodc`]: #hisat2-build-options-nodc + + --nodc + + + +Disable use of the difference-cover sample. Suffix sorting becomes +quadratic-time in the worst case (where the worst case is an extremely +repetitive reference). Default: off. + +
+ + -r/--noref + + + +Do not build the `NAME.3.ht2` and `NAME.4.ht2` portions of the index, which +contain a bitpacked version of the reference sequences and are used for +paired-end alignment. + +
+ + -3/--justref + + + +Build only the `NAME.3.ht2` and `NAME.4.ht2` portions of the index, which +contain a bitpacked version of the reference sequences and are used for +paired-end alignment. + +
+ + -o/--offrate + + + +To map alignments back to positions on the reference sequences, it's necessary +to annotate ("mark") some or all of the [Burrows-Wheeler] rows with their +corresponding location on the genome. +[`-o`/`--offrate`](#hisat2-build-options-o) governs how many rows get marked: +the indexer will mark every 2^`` rows. Marking more rows makes +reference-position lookups faster, but requires more memory to hold the +annotations at runtime. The default is 4 (every 16th row is marked; for human +genome, annotations occupy about 680 megabytes). + +
+ + -t/--ftabchars + + + +The ftab is the lookup table used to calculate an initial [Burrows-Wheeler] +range with respect to the first `` characters of the query. A larger +`` yields a larger lookup table but faster query times. The ftab has size +4^(``+1) bytes. The default setting is 10 (ftab is 4MB). + + +
+ + --localoffrate + + + +This option governs how many rows get marked in a local index: +the indexer will mark every 2^`` rows. Marking more rows makes +reference-position lookups faster, but requires more memory to hold the +annotations at runtime. The default is 3 (every 8th row is marked, +this occupies about 16KB per local index). + +
+ + --localftabchars + + + +The local ftab is the lookup table in a local index. +The default setting is 6 (ftab is 8KB per local index). + +
+ + -p + + + +Launch `NTHREADS` parallel build threads (default: 1). + +
+ + --snp + + + +Provide a list of SNPs (in the HISAT2's own format) as follows (five columns). + + SNP ID `` snp type (single, deletion, or insertion) `` chromosome name `` zero-offset based genomic position of a SNP `` alternative base (single), the length of SNP (deletion), or insertion sequence (insertion) + + For example, + rs58784443 single 13 18447947 T + +Use `hisat2_extract_snps_haplotypes_UCSC.py` (in the HISAT2 package) to extract SNPs and haplotypes from a dbSNP file (e.g. http://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/snp144Common.txt.gz). +or `hisat2_extract_snps_haplotypes_VCF.py` to extract SNPs and haplotypes from a VCF file (e.g. ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502/supporting/GRCh38_positions/ALL.chr22.phase3_shapeit2_mvncall_integrated_v3plus_nounphased.rsID.genotypes.GRCh38_dbSNP_no_SVs.vcf.gz). + +
+ + --haplotype + + + +Provide a list of haplotypes (in the HISAT2's own format) as follows (five columns). + + Haplotype ID `` chromosome name `` zero-offset based left coordinate of haplotype `` zero-offset based right coordinate of haplotype `` a comma separated list of SNP ids in the haplotype + + For example, + ht35 13 18446877 18446945 rs12381094,rs12381056,rs192016659,rs538569910 + +See the above option, --snp, about how to extract haplotypes. This option is not required, but haplotype information can keep the index construction from exploding and reduce the index size substantially. + +
+ + --ss + + + +Note this option should be used with the following --exon option. +Provide a list of splice sites (in the HISAT2's own format) as follows (four columns). + + chromosome name `` zero-offset based genomic position of the flanking base on the left side of an intron `` zero-offset based genomic position of the flanking base on the right `` strand + +Use `hisat2_extract_splice_sites.py` (in the HISAT2 package) to extract splice sites from a GTF file. + +
+ + --exon + + + +Note this option should be used with the above --ss option. +Provide a list of exons (in the HISAT2's own format) as follows (three columns). + + chromosome name `` zero-offset based left genomic position of an exon `` zero-offset based right genomic position of an exon + +Use `hisat2_extract_exons.py` (in the HISAT2 package) to extract exons from a GTF file. + +
+ + --seed + + + +Use `` as the seed for pseudo-random number generator. + +
+ + --cutoff + + + +Index only the first `` bases of the reference sequences (cumulative across +sequences) and ignore the rest. + +
+ + -q/--quiet + + + +`hisat2-build` is verbose by default. With this option `hisat2-build` will +print only error messages. + +
+ + -h/--help + + + +Print usage information and quit. + +
+ + --version + + + +Print version information and quit. + +
+ +The `hisat2-inspect` index inspector +===================================== + +`hisat2-inspect` extracts information from a HISAT2 index about what kind of +index it is and what reference sequences were used to build it. When run without +any options, the tool will output a FASTA file containing the sequences of the +original references (with all non-`A`/`C`/`G`/`T` characters converted to `N`s). + It can also be used to extract just the reference sequence names using the +[`-n`/`--names`] option or a more verbose summary using the [`-s`/`--summary`] +option. + +Command Line +------------ + +Usage: + + hisat2-inspect [options]* + +### Main arguments + +
+ + + + + +The basename of the index to be inspected. The basename is name of any of the +index files but with the `.X.ht2` suffix omitted. +`hisat2-inspect` first looks in the current directory for the index files, then +in the directory specified in the `HISAT2_INDEXES` environment variable. + +
+ +### Options + +
+ + -a/--across + + + +When printing FASTA output, output a newline character every `` bases +(default: 60). + +
+ +[`-n`/`--names`]: #hisat2-inspect-options-n + + -n/--names + + + +Print reference sequence names, one per line, and quit. + +
+ +[`-s`/`--summary`]: #hisat2-inspect-options-s + + -s/--summary + + + +Print a summary that includes information about index settings, as well as the +names and lengths of the input sequences. The summary has this format: + + Colorspace <0 or 1> + SA-Sample 1 in + FTab-Chars + Sequence-1 + Sequence-2 + ... + Sequence-N + +Fields are separated by tabs. Colorspace is always set to 0 for HISAT2. + +
+ +[`--snp`]: #hisat2-inspect-options-snp + + --snp + + + +Print SNPs, and quit. + +
+ +[`--ss`]: #hisat2-inspect-options-ss + + --ss + + + +Print splice sites, and quit. + +
+ +[`--ss-all`]: #hisat2-inspect-options-ss-all + + --ss-all + + + +Print splice sites including those not in the global index, and quit. + +
+ +[`--exon`]: #hisat2-inspect-options-exon + + --exon + + + +Print exons, and quit. + +
+ + -v/--verbose + + + +Print verbose output (for debugging). + +
+ + --version + + + +Print version information and quit. + +
+ + -h/--help + + + +Print usage information and quit. + +
+ +Getting started with HISAT2 +=================================================== + +HISAT2 comes with some example files to get you started. The example files +are not scientifically significant; these files will simply let you start running HISAT2 and +downstream tools right away. + +First follow the manual instructions to [obtain HISAT2]. Set the `HISAT2_HOME` +environment variable to point to the new HISAT2 directory containing the +`hisat2`, `hisat2-build` and `hisat2-inspect` binaries. This is important, +as the `HISAT2_HOME` variable is used in the commands below to refer to that +directory. + +[obtain HISAT2]: #obtaining-hisat2 + +Indexing a reference genome +--------------------------- + +To create an index for the genomic region (1 million bps from the human chromosome 22 between 20,000,000 and 20,999,999) +included with HISAT2, create a new temporary directory (it doesn't matter where), change into that directory, and run: + + $HISAT2_HOME/hisat2-build $HISAT2_HOME/example/reference/22_20-21M.fa --snp $HISAT2_HOME/example/reference/22_20-21M.snp 22_20-21M_snp + +The command should print many lines of output then quit. When the command +completes, the current directory will contain ten new files that all start with +`22_20-21M_snp` and end with `.1.ht2`, `.2.ht2`, `.3.ht2`, `.4.ht2`, `.5.ht2`, `.6.ht2`, +`.7.ht2`, and `.8.ht2`. These files constitute the index - you're done! + +You can use `hisat2-build` to create an index for a set of FASTA files obtained +from any source, including sites such as [UCSC], [NCBI], and [Ensembl]. When +indexing multiple FASTA files, specify all the files using commas to separate +file names. For more details on how to create an index with `hisat2-build`, +see the [manual section on index building]. You may also want to bypass this +process by obtaining a pre-built index. + +[UCSC]: http://genome.ucsc.edu/cgi-bin/hgGateway +[NCBI]: http://www.ncbi.nlm.nih.gov/sites/genome +[Ensembl]: http://www.ensembl.org/ +[manual section on index building]: #the-hisat2-build-indexer +[using a pre-built index]: #using-a-pre-built-index + +Aligning example reads +---------------------- + +Stay in the directory created in the previous step, which now contains the +`22_20-21M` index files. Next, run: + + $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -U $HISAT2_HOME/example/reads/reads_1.fa -S eg1.sam + +This runs the HISAT2 aligner, which aligns a set of unpaired reads to the +genome region using the index generated in the previous step. +The alignment results in SAM format are written to the file `eg1.sam`, and a +short alignment summary is written to the console. (Actually, the summary is +written to the "standard error" or "stderr" filehandle, which is typically +printed to the console.) + +To see the first few lines of the SAM output, run: + + head eg1.sam + +You will see something like this: + + @HD VN:1.0 SO:unsorted + @SQ SN:22:20000001-21000000 LN:1000000 + @PG ID:hisat2 PN:hisat2 VN:2.0.0-beta + 1 0 22:20000001-21000000 397984 255 100M * 0 0 GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1 + 2 16 22:20000001-21000000 398131 255 100M * 0 0 ATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:80A19 YT:Z:UU NH:i:1 Zs:Z:80|S|rs576159895 + 3 16 22:20000001-21000000 398222 255 100M * 0 0 TGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:16A83 YT:Z:UU NH:i:1 Zs:Z:16|S|rs2629364 + 4 16 22:20000001-21000000 398247 255 90M200N10M * 0 0 CAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAACCGCTGCACCAGGAAGTCGATCCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU XS:A:- NH:i:1 + 5 16 22:20000001-21000000 398194 255 100M * 0 0 GGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:17A26A55 YT:Z:UU NH:i:1 Zs:Z:17|S|rs576159895,26|S|rs2629364 + 6 0 22:20000001-21000000 398069 255 100M * 0 0 CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1 + 7 0 22:20000001-21000000 397896 255 100M * 0 0 GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:31G68 YT:Z:UU NH:i:1 Zs:Z:31|S|rs562662261 + 8 0 22:20000001-21000000 398150 255 100M * 0 0 AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:61A26A11 YT:Z:UU NH:i:1 Zs:Z:61|S|rs576159895,26|S|rs2629364 + 9 16 22:20000001-21000000 398329 255 8M200N92M * 0 0 ACCAGGAAGTCGATCCAGATGTAGTGGGGGGTCACTTCGGGGGGACAGGGTTTGGGTTGACTTGCTTCCGAGGCAGCCAGGGGGTCTGCTTCCTTTATCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU XS:A:- NH:i:1 + 10 16 22:20000001-21000000 398184 255 100M * 0 0 CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:27A26A45 YT:Z:UU NH:i:1 Zs:Z:27|S|rs576159895,26|S|rs2629364 + +The first few lines (beginning with `@`) are SAM header lines, and the rest of +the lines are SAM alignments, one line per read or mate. See the [HISAT2 +manual section on SAM output] and the [SAM specification] for details about how +to interpret the SAM file format. + +[HISAT2 manual section on SAM output]: #sam-output + +Paired-end example +------------------ + +To align paired-end reads included with HISAT2, stay in the same directory and +run: + + $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam + +This aligns a set of paired-end reads to the reference genome, with results +written to the file `eg2.sam`. + +Using SAMtools/BCFtools downstream +---------------------------------- + +[SAMtools] is a collection of tools for manipulating and analyzing SAM and BAM +alignment files. [BCFtools] is a collection of tools for calling variants and +manipulating VCF and BCF files, and it is typically distributed with [SAMtools]. +Using these tools together allows you to get from alignments in SAM format to +variant calls in VCF format. This example assumes that `samtools` and +`bcftools` are installed and that the directories containing these binaries are +in your [PATH environment variable]. + +Run the paired-end example: + + $HISAT2_HOME/hisat -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam + +Use `samtools view` to convert the SAM file into a BAM file. BAM is a the +binary format corresponding to the SAM text format. Run: + + samtools view -bS eg2.sam > eg2.bam + +Use `samtools sort` to convert the BAM file to a sorted BAM file. The following command requires samtools version 1.2 or higher. + + samtools sort eg2.bam -o eg2.sorted.bam + +We now have a sorted BAM file called `eg2.sorted.bam`. Sorted BAM is a useful +format because the alignments are (a) compressed, which is convenient for +long-term storage, and (b) sorted, which is convenient for variant discovery. +To generate variant calls in VCF format, run: + + samtools mpileup -uf $HISAT2_HOME/example/reference/22_20-21M.fa eg2.sorted.bam | bcftools view -bvcg - > eg2.raw.bcf + +Then to view the variants, run: + + bcftools view eg2.raw.bcf + +See the official SAMtools guide to [Calling SNPs/INDELs with SAMtools/BCFtools] +for more details and variations on this process. + +[BCFtools]: http://samtools.sourceforge.net/mpileup.shtml +[Calling SNPs/INDELs with SAMtools/BCFtools]: http://samtools.sourceforge.net/mpileup.shtml diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0abfad9 --- /dev/null +++ b/Makefile @@ -0,0 +1,590 @@ +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT. If not, see . +# +# +# Makefile for hisat2-align, hisat2-build, hisat2-inspect +# + +INC = +GCC_PREFIX = $(shell dirname `which gcc`) +GCC_SUFFIX = +CC = $(GCC_PREFIX)/gcc$(GCC_SUFFIX) +CPP = $(GCC_PREFIX)/g++$(GCC_SUFFIX) +CXX = $(CPP) +HEADERS = $(wildcard *.h) +BOWTIE_MM = 1 +BOWTIE_SHARED_MEM = 0 + +# Detect Cygwin or MinGW +WINDOWS = 0 +CYGWIN = 0 +MINGW = 0 +ifneq (,$(findstring CYGWIN,$(shell uname))) + WINDOWS = 1 + CYGWIN = 1 + # POSIX memory-mapped files not currently supported on Windows + BOWTIE_MM = 0 + BOWTIE_SHARED_MEM = 0 +else + ifneq (,$(findstring MINGW,$(shell uname))) + WINDOWS = 1 + MINGW = 1 + # POSIX memory-mapped files not currently supported on Windows + BOWTIE_MM = 0 + BOWTIE_SHARED_MEM = 0 + endif +endif + +MACOS = 0 +ifneq (,$(findstring Darwin,$(shell uname))) + MACOS = 1 +endif + +EXTRA_FLAGS += -DPOPCNT_CAPABILITY -std=c++11 +INC += -I. -I third_party + +MM_DEF = + +ifeq (1,$(BOWTIE_MM)) + MM_DEF = -DBOWTIE_MM +endif + +SHMEM_DEF = + +ifeq (1,$(BOWTIE_SHARED_MEM)) + SHMEM_DEF = -DBOWTIE_SHARED_MEM +endif + +PTHREAD_PKG = +PTHREAD_LIB = + +ifeq (1,$(MINGW)) + PTHREAD_LIB = +else + PTHREAD_LIB = -lpthread +endif + +SEARCH_LIBS = +BUILD_LIBS = +INSPECT_LIBS = + +ifeq (1,$(MINGW)) + BUILD_LIBS = + INSPECT_LIBS = +endif + +USE_SRA = 0 +SRA_DEF = +SRA_LIB = +SERACH_INC = +ifeq (1,$(USE_SRA)) + SRA_DEF = -DUSE_SRA + SRA_LIB = -lncbi-ngs-c++-static -lngs-c++-static -lncbi-vdb-static -ldl + SEARCH_INC += -I$(NCBI_NGS_DIR)/include -I$(NCBI_VDB_DIR)/include + SEARCH_LIBS += -L$(NCBI_NGS_DIR)/lib64 -L$(NCBI_VDB_DIR)/lib64 +endif + +LIBS = $(PTHREAD_LIB) + +HT2LIB_DIR = hisat2lib + +HT2LIB_CPPS = $(HT2LIB_DIR)/ht2_init.cpp \ + $(HT2LIB_DIR)/ht2_repeat.cpp \ + $(HT2LIB_DIR)/ht2_index.cpp + +SHARED_CPPS = ccnt_lut.cpp ref_read.cpp alphabet.cpp shmem.cpp \ + edit.cpp gfm.cpp \ + reference.cpp ds.cpp multikey_qsort.cpp limit.cpp \ + random_source.cpp tinythread.cpp utility_3n.cpp +SEARCH_CPPS = qual.cpp pat.cpp \ + read_qseq.cpp aligner_seed_policy.cpp \ + aligner_seed.cpp \ + aligner_seed2.cpp \ + aligner_sw.cpp \ + aligner_sw_driver.cpp aligner_cache.cpp \ + aligner_result.cpp ref_coord.cpp mask.cpp \ + pe.cpp aln_sink.cpp dp_framer.cpp \ + scoring.cpp presets.cpp unique.cpp \ + simple_func.cpp \ + random_util.cpp \ + aligner_bt.cpp sse_util.cpp \ + aligner_swsse.cpp outq.cpp \ + aligner_swsse_loc_i16.cpp \ + aligner_swsse_ee_i16.cpp \ + aligner_swsse_loc_u8.cpp \ + aligner_swsse_ee_u8.cpp \ + aligner_driver.cpp \ + splice_site.cpp \ + alignment_3n.cpp \ + position_3n.cpp \ + $(HT2LIB_CPPS) + +BUILD_CPPS = diff_sample.cpp + +REPEAT_CPPS = \ + mask.cpp \ + qual.cpp \ + aligner_bt.cpp \ + scoring.cpp \ + simple_func.cpp \ + dp_framer.cpp \ + aligner_result.cpp \ + aligner_sw_driver.cpp \ + aligner_sw.cpp \ + aligner_swsse_ee_i16.cpp \ + aligner_swsse_ee_u8.cpp \ + aligner_swsse_loc_i16.cpp \ + aligner_swsse_loc_u8.cpp \ + aligner_swsse.cpp \ + bit_packed_array.cpp \ + repeat_builder.cpp + +THREE_N_HEADERS = \ + position_3n_table.h \ + alignment_3n_table.h \ + utility_3n_table.h + +HISAT2_CPPS_MAIN = $(SEARCH_CPPS) hisat2_main.cpp +HISAT2_BUILD_CPPS_MAIN = $(BUILD_CPPS) hisat2_build_main.cpp +HISAT2_REPEAT_CPPS_MAIN = $(REPEAT_CPPS) $(BUILD_CPPS) hisat2_repeat_main.cpp + +SEARCH_FRAGMENTS = $(wildcard search_*_phase*.c) +VERSION := $(shell cat HISAT2_VERSION) + +# Convert BITS=?? to a -m flag +BITS=32 +ifeq (x86_64,$(shell uname -m)) +BITS=64 +endif +# msys will always be 32 bit so look at the cpu arch instead. +ifneq (,$(findstring AMD64,$(PROCESSOR_ARCHITEW6432))) + ifeq (1,$(MINGW)) + BITS=64 + endif +endif +BITS_FLAG = + +ifeq (32,$(BITS)) + BITS_FLAG = -m32 +endif + +ifeq (64,$(BITS)) + BITS_FLAG = -m64 +endif +SSE_FLAG=-msse2 + +DEBUG_FLAGS = -O0 -g3 $(BITS_FLAG) $(SSE_FLAG) +DEBUG_DEFS = -DCOMPILER_OPTIONS="\"$(DEBUG_FLAGS) $(EXTRA_FLAGS)\"" +RELEASE_FLAGS = -O3 $(BITS_FLAG) $(SSE_FLAG) -funroll-loops -g3 +RELEASE_DEFS = -DCOMPILER_OPTIONS="\"$(RELEASE_FLAGS) $(EXTRA_FLAGS)\"" +NOASSERT_FLAGS = -DNDEBUG +FILE_FLAGS = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +HT2LIB_FLAGS = -DHISAT2_BUILD_LIB +ifeq (1,$(USE_SRA)) + ifeq (1, $(MACOS)) + SRA_LIB += -stdlib=libc++ + DEBUG_FLAGS += -mmacosx-version-min=10.10 + RELEASE_FLAGS += -mmacosx-version-min=10.10 + endif +endif + + +HISAT2_BIN_LIST = hisat2-build-s \ + hisat2-build-l \ + hisat2-align-s \ + hisat2-align-l \ + hisat2-inspect-s \ + hisat2-inspect-l \ + hisat2-repeat \ + hisat-3n-table + +HISAT2_BIN_LIST_AUX = hisat2-build-s-debug \ + hisat2-build-l-debug \ + hisat2-align-s-debug \ + hisat2-align-l-debug \ + hisat2-inspect-s-debug \ + hisat2-inspect-l-debug \ + hisat2-repeat-debug + +HT2LIB_SRCS = $(SHARED_CPPS) \ + $(HT2LIB_CPPS) + +HT2LIB_OBJS = $(HT2LIB_SRCS:.cpp=.o) + +HT2LIB_DEBUG_OBJS = $(addprefix .ht2lib-obj-debug/,$(HT2LIB_OBJS)) +HT2LIB_RELEASE_OBJS = $(addprefix .ht2lib-obj-release/,$(HT2LIB_OBJS)) +HT2LIB_SHARED_DEBUG_OBJS = $(addprefix .ht2lib-obj-debug-shared/,$(HT2LIB_OBJS)) +HT2LIB_SHARED_RELEASE_OBJS = $(addprefix .ht2lib-obj-release-shared/,$(HT2LIB_OBJS)) + +HT2LIB_PKG_SRC = \ + $(HT2LIB_DIR)/ht2_init.cpp \ + $(HT2LIB_DIR)/ht2_repeat.cpp \ + $(HT2LIB_DIR)/ht2_index.cpp \ + $(HT2LIB_DIR)/ht2.h \ + $(HT2LIB_DIR)/ht2_handle.h \ + $(HT2LIB_DIR)/java_jni/Makefile \ + $(HT2LIB_DIR)/java_jni/ht2module.c \ + $(HT2LIB_DIR)/java_jni/HT2Module.java \ + $(HT2LIB_DIR)/java_jni/HT2ModuleExample.java \ + $(HT2LIB_DIR)/pymodule/Makefile \ + $(HT2LIB_DIR)/pymodule/ht2module.c \ + $(HT2LIB_DIR)/pymodule/setup.py \ + $(HT2LIB_DIR)/pymodule/ht2example.py + + +GENERAL_LIST = $(wildcard scripts/*.sh) \ + $(wildcard scripts/*.pl) \ + $(wildcard *.py) \ + $(wildcard example/index/*.ht2) \ + $(wildcard example/reads/*.fa) \ + example/reference/22_20-21M.fa \ + example/reference/22_20-21M.snp \ + $(PTHREAD_PKG) \ + hisat2 \ + hisat2-build \ + hisat2-inspect \ + AUTHORS \ + LICENSE \ + NEWS \ + MANUAL \ + MANUAL.markdown \ + TUTORIAL \ + HISAT2_VERSION + +ifeq (1,$(WINDOWS)) + HISAT2_BIN_LIST := $(HISAT2_BIN_LIST) hisat2.bat hisat2-build.bat hisat2-inspect.bat +endif + +# This is helpful on Windows under MinGW/MSYS, where Make might go for +# the Windows FIND tool instead. +FIND=$(shell which find) + +SRC_PKG_LIST = $(wildcard *.h) \ + $(wildcard *.hh) \ + $(wildcard *.c) \ + $(wildcard *.cpp) \ + $(HT2LIB_PKG_SRC) \ + Makefile \ + CMakeLists.txt \ + $(GENERAL_LIST) + +BIN_PKG_LIST = $(GENERAL_LIST) + +.PHONY: all allall both both-debug + +all: $(HISAT2_BIN_LIST) + +allall: $(HISAT2_BIN_LIST) $(HISAT2_BIN_LIST_AUX) + +both: hisat2-align-s hisat2-align-l hisat2-build-s hisat2-build-l + +both-debug: hisat2-align-s-debug hisat2-align-l-debug hisat2-build-s-debug hisat2-build-l-debug + +repeat: hisat2-repeat + +repeat-debug: hisat2-repeat-debug + +DEFS :=-fno-strict-aliasing \ + -DHISAT2_VERSION="\"`cat HISAT2_VERSION`\"" \ + -DBUILD_HOST="\"`hostname`\"" \ + -DBUILD_TIME="\"`date`\"" \ + -DCOMPILER_VERSION="\"`$(CXX) -v 2>&1 | tail -1`\"" \ + $(FILE_FLAGS) \ + $(PREF_DEF) \ + $(MM_DEF) \ + $(SHMEM_DEF) + +# +# hisat-bp targets +# + +hisat-bp-bin: hisat_bp.cpp $(SEARCH_CPPS) $(SHARED_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 $(NOASSERT_FLAGS) -Wall \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT_CPPS_MAIN) \ + $(LIBS) $(SEARCH_LIBS) + +hisat-bp-bin-debug: hisat_bp.cpp $(SEARCH_CPPS) $(SHARED_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS) + $(CXX) $(DEBUG_FLAGS) \ + $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -Wall \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT_CPPS_MAIN) \ + $(LIBS) $(SEARCH_LIBS) + +# +# hisat2-repeat targets +# + +hisat2-repeat: hisat2_repeat.cpp $(REPEAT_CPPS) $(SHARED_CPPS) $(HEADERS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DBOWTIE_64BIT_INDEX $(NOASSERT_FLAGS) -Wall \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_REPEAT_CPPS_MAIN) \ + $(LIBS) $(BUILD_LIBS) + +hisat2-repeat-debug: hisat2_repeat.cpp $(REPEAT_CPPS) $(SHARED_CPPS) $(HEADERS) + $(CXX) $(DEBUG_FLAGS) $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DBOWTIE_64BIT_INDEX -Wall \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_REPEAT_CPPS_MAIN) \ + $(LIBS) $(BUILD_LIBS) + + +# +# hisat2-build targets +# + +hisat2-build-s: hisat2_build.cpp $(SHARED_CPPS) $(HEADERS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 $(NOASSERT_FLAGS) -Wall -DMASSIVE_DATA_RLCSA \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_BUILD_CPPS_MAIN) \ + $(LIBS) $(BUILD_LIBS) + +hisat2-build-l: hisat2_build.cpp $(SHARED_CPPS) $(HEADERS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DBOWTIE_64BIT_INDEX $(NOASSERT_FLAGS) -Wall \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_BUILD_CPPS_MAIN) \ + $(LIBS) $(BUILD_LIBS) + +hisat2-build-s-debug: hisat2_build.cpp $(SHARED_CPPS) $(HEADERS) + $(CXX) $(DEBUG_FLAGS) $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -Wall -DMASSIVE_DATA_RLCSA \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_BUILD_CPPS_MAIN) \ + $(LIBS) $(BUILD_LIBS) + +hisat2-build-l-debug: hisat2_build.cpp $(SHARED_CPPS) $(HEADERS) + $(CXX) $(DEBUG_FLAGS) $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DBOWTIE_64BIT_INDEX -Wall \ + $(INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_BUILD_CPPS_MAIN) \ + $(LIBS) $(BUILD_LIBS) + +# +# hisat2 targets +# + +hisat2-align-s: hisat2.cpp $(SEARCH_CPPS) $(SHARED_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) $(SRA_DEF) -DBOWTIE2 $(NOASSERT_FLAGS) -Wall \ + $(INC) $(SEARCH_INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_CPPS_MAIN) \ + $(LIBS) $(SRA_LIB) $(SEARCH_LIBS) + +hisat2-align-l: hisat2.cpp $(SEARCH_CPPS) $(SHARED_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) $(SRA_DEF) -DBOWTIE2 -DBOWTIE_64BIT_INDEX $(NOASSERT_FLAGS) -Wall \ + $(INC) $(SEARCH_INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_CPPS_MAIN) \ + $(LIBS) $(SRA_LIB) $(SEARCH_LIBS) + +hisat2-align-s-debug: hisat2.cpp $(SEARCH_CPPS) $(SHARED_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS) + $(CXX) $(DEBUG_FLAGS) \ + $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) $(SRA_DEF) -DBOWTIE2 -Wall \ + $(INC) $(SEARCH_INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_CPPS_MAIN) \ + $(LIBS) $(SRA_LIB) $(SEARCH_LIBS) + +hisat2-align-l-debug: hisat2.cpp $(SEARCH_CPPS) $(SHARED_CPPS) $(HEADERS) $(SEARCH_FRAGMENTS) + $(CXX) $(DEBUG_FLAGS) \ + $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) $(SRA_DEF) -DBOWTIE2 -DBOWTIE_64BIT_INDEX -Wall \ + $(INC) $(SEARCH_INC) \ + -o $@ $< \ + $(SHARED_CPPS) $(HISAT2_CPPS_MAIN) \ + $(LIBS) $(SRA_LIB) $(SEARCH_LIBS) + +# +# hisat2-inspect targets +# + +hisat2-inspect-s: hisat2_inspect.cpp $(HEADERS) $(SHARED_CPPS) + $(CXX) $(RELEASE_FLAGS) \ + $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DHISAT2_INSPECT_MAIN -Wall \ + $(INC) -I . \ + -o $@ $< \ + $(SHARED_CPPS) \ + $(LIBS) $(INSPECT_LIBS) + +hisat2-inspect-l: hisat2_inspect.cpp $(HEADERS) $(SHARED_CPPS) + $(CXX) $(RELEASE_FLAGS) \ + $(RELEASE_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DBOWTIE_64BIT_INDEX -DHISAT2_INSPECT_MAIN -Wall \ + $(INC) -I . \ + -o $@ $< \ + $(SHARED_CPPS) \ + $(LIBS) $(INSPECT_LIBS) + +hisat2-inspect-s-debug: hisat2_inspect.cpp $(HEADERS) $(SHARED_CPPS) + $(CXX) $(DEBUG_FLAGS) \ + $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DHISAT2_INSPECT_MAIN -Wall \ + $(INC) -I . \ + -o $@ $< \ + $(SHARED_CPPS) \ + $(LIBS) $(INSPECT_LIBS) + +hisat2-inspect-l-debug: hisat2_inspect.cpp $(HEADERS) $(SHARED_CPPS) + $(CXX) $(DEBUG_FLAGS) \ + $(DEBUG_DEFS) $(EXTRA_FLAGS) \ + $(DEFS) -DBOWTIE2 -DBOWTIE_64BIT_INDEX -DHISAT2_INSPECT_MAIN -Wall \ + $(INC) -I . \ + -o $@ $< \ + $(SHARED_CPPS) \ + $(LIBS) $(INSPECT_LIBS) + +# +# hisat-3n-table targets +# + +hisat-3n-table: hisat_3n_table.cpp $(THREE_N_HEADERS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) $(NOASSERT_FLAGS) $(DEFS) -pthread -o $@ $< + +# +# HT2LIB targets +# + +ht2lib: libhisat2lib-debug.a libhisat2lib.a libhisat2lib-debug.so libhisat2lib.so + +libhisat2lib-debug.a: $(HT2LIB_DEBUG_OBJS) + ar rc $@ $(HT2LIB_DEBUG_OBJS) + +libhisat2lib.a: $(HT2LIB_RELEASE_OBJS) + ar rc $@ $(HT2LIB_RELEASE_OBJS) + +libhisat2lib-debug.so: $(HT2LIB_SHARED_DEBUG_OBJS) + $(CXX) $(DEBUG_FLAGS) $(DEBUG_DEFS) $(EXTRA_FLAGS) $(DEFS) $(SRA_DEF) -DBOWTIE2 -Wall $(INC) $(SEARCH_INC) \ + -shared -o $@ $(HT2LIB_SHARED_DEBUG_OBJS) $(LIBS) $(SRA_LIB) $(SEARCH_LIBS) + +libhisat2lib.so: $(HT2LIB_SHARED_RELEASE_OBJS) + $(CXX) $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) $(DEFS) $(SRA_DEF) -DBOWTIE2 $(NOASSERT_FLAGS) -Wall $(INC) $(SEARCH_INC)\ + -shared -o $@ $(HT2LIB_SHARED_RELEASE_OBJS) $(LIBS) $(SRA_LIB) $(SEARCH_LIBS) + +.ht2lib-obj-debug/%.o: %.cpp + @mkdir -p $(dir $@)/$(dir $<) + $(CXX) -fPIC $(DEBUG_FLAGS) $(DEBUG_DEFS) $(EXTRA_FLAGS) $(DEFS) $(SRA_DEF) $(HT2LIB_FLAGS) -DBOWTIE2 -Wall $(INC) $(SEARCH_INC) \ + -c -o $@ $< + +.ht2lib-obj-release/%.o: %.cpp + @mkdir -p $(dir $@)/$(dir $<) + $(CXX) -fPIC $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) $(DEFS) $(SRA_DEF) $(HT2LIB_FLAGS) -DBOWTIE2 $(NOASSERT_FLAGS) -Wall $(INC) $(SEARCH_INC) \ + -c -o $@ $< + +.ht2lib-obj-debug-shared/%.o: %.cpp + @mkdir -p $(dir $@)/$(dir $<) + $(CXX) -fPIC $(DEBUG_FLAGS) $(DEBUG_DEFS) $(EXTRA_FLAGS) $(DEFS) $(SRA_DEF) $(HT2LIB_FLAGS) -DBOWTIE2 -Wall $(INC) $(SEARCH_INC) \ + -c -o $@ $< + +.ht2lib-obj-release-shared/%.o: %.cpp + @mkdir -p $(dir $@)/$(dir $<) + $(CXX) -fPIC $(RELEASE_FLAGS) $(RELEASE_DEFS) $(EXTRA_FLAGS) $(DEFS) $(SRA_DEF) $(HT2LIB_FLAGS) -DBOWTIE2 $(NOASSERT_FLAGS) -Wall $(INC) $(SEARCH_INC) \ + -c -o $@ $< + +# +# repeatexp +# +repeatexp: + g++ -o repeatexp repeatexp.cpp -I hisat2lib libhisat2lib.a + +hisat2: ; + +hisat2.bat: + echo "@echo off" > hisat2.bat + echo "perl %~dp0/hisat2 %*" >> hisat2.bat + +hisat2-build.bat: + echo "@echo off" > hisat2-build.bat + echo "python %~dp0/hisat2-build %*" >> hisat2-build.bat + +hisat2-inspect.bat: + echo "@echo off" > hisat2-inspect.bat + echo "python %~dp0/hisat2-inspect %*" >> hisat2-inspect.bat + + +.PHONY: hisat2-src +hisat2-src: $(SRC_PKG_LIST) + chmod a+x scripts/*.sh scripts/*.pl + mkdir .src.tmp + mkdir .src.tmp/hisat2-$(VERSION) + zip tmp.zip $(SRC_PKG_LIST) + mv tmp.zip .src.tmp/hisat2-$(VERSION) + cd .src.tmp/hisat2-$(VERSION) ; unzip tmp.zip ; rm -f tmp.zip + cd .src.tmp ; zip -r hisat2-$(VERSION)-source.zip hisat2-$(VERSION) + cp .src.tmp/hisat2-$(VERSION)-source.zip . + rm -rf .src.tmp + +.PHONY: hisat2-bin +hisat2-bin: $(BIN_PKG_LIST) $(HISAT2_BIN_LIST) $(HISAT2_BIN_LIST_AUX) + chmod a+x scripts/*.sh scripts/*.pl + rm -rf .bin.tmp + mkdir .bin.tmp + mkdir .bin.tmp/hisat2-$(VERSION) + if [ -f hisat2.exe ] ; then \ + zip tmp.zip $(BIN_PKG_LIST) $(addsuffix .exe,$(HISAT2_BIN_LIST) $(HISAT2_BIN_LIST_AUX)) ; \ + else \ + zip tmp.zip $(BIN_PKG_LIST) $(HISAT2_BIN_LIST) $(HISAT2_BIN_LIST_AUX) ; \ + fi + mv tmp.zip .bin.tmp/hisat2-$(VERSION) + cd .bin.tmp/hisat2-$(VERSION) ; unzip tmp.zip ; rm -f tmp.zip + cd .bin.tmp ; zip -r hisat2-$(VERSION)-$(BITS).zip hisat2-$(VERSION) + cp .bin.tmp/hisat2-$(VERSION)-$(BITS).zip . + rm -rf .bin.tmp + +.PHONY: doc +doc: doc/manual.inc.html MANUAL + +doc/manual.inc.html: MANUAL.markdown + pandoc -T "HISAT2 Manual" -o $@ \ + --from markdown --to HTML --toc $^ + perl -i -ne \ + '$$w=0 if m|^|;print if $$w;$$w=1 if m|^|;' $@ + +MANUAL: MANUAL.markdown + perl doc/strip_markdown.pl < $^ > $@ + +.PHONY: clean +clean: + rm -f $(HISAT2_BIN_LIST) $(HISAT2_BIN_LIST_AUX) \ + $(addsuffix .exe,$(HISAT2_BIN_LIST) $(HISAT2_BIN_LIST_AUX)) \ + hisat2-src.zip hisat2-bin.zip + rm -f core.* .tmp.head + rm -rf *.dSYM + rm -rf .ht2lib-obj* + rm -f libhisat2lib*.a libhisat2lib*.so + + +.PHONY: push-doc +push-doc: doc/manual.inc.html + scp doc/*.*html doc/indexes.txt salz-dmz:/ccb/salz7-data/www/ccb.jhu.edu/html/software/hisat2/ diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..56be177 --- /dev/null +++ b/NEWS @@ -0,0 +1,16 @@ +HISAT 2 NEWS +============= + +HISAT 2 is now available for download from the project website, +http://bowtie-bio.sf.net/bowtie2. 2.0.0-beta is the first version released to +the public and 2.0.7 is the latest version. HISAT 2 is licensed under +the GPLv3 license. See `LICENSE' file for details. + + +Version Release History +======================= + +Version 2.0.0-beta - August XX, 2015 + * Improved multithreading support so that Bowtie 2 now uses native Windows + threads when compiled on Windows and uses a faster mutex. Threading + performance should improve on all platforms. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1278115 --- /dev/null +++ b/README.md @@ -0,0 +1,247 @@ +HISAT-3N +============ + +Overview +----------------- +HISAT-3N (hierarchical indexing for spliced alignment of transcripts - 3 nucleotides) +is an ultrafast and memory-efficient sequence aligner designed for nucleotide conversion +sequencing technologies. HISAT-3N index contains two HISAT2 indexes which require memory small: +for the human genome, it requires 9 GB for standard 3N-index and 10.5 GB for repeat 3N-index. +The repeat 3N-index could be used to align one read to thousands position 3 times faster standard 3N-index. +HISAT-3N is developed based on [HISAT2], +which is particularly optimized for RNA sequencing technology. HISAT-3N support both strand-specific and non-strand reads. +HISAT-3N can be used for any base-converted sequencing reads include [BS-seq], [SLAM-seq], [scBS-seq], [scSLAM-seq], and [TAPS]. +See the [HISAT-3N] website for more information. + +[HISAT2]:https://github.com/DaehwanKimLab/hisat2 +[BS-seq]: https://en.wikipedia.org/wiki/Bisulfite_sequencing +[SLAM-seq]: https://www.nature.com/articles/nmeth.4435 +[scBS-seq]: https://www.nature.com/articles/nmeth.3035 +[scSLAM-seq]: https://www.nature.com/articles/s41586-019-1369-y +[TAPS]: https://www.nature.com/articles/s41587-019-0041-2 +[HISAT-3N]:https://daehwankimlab.github.io/hisat2/hisat-3n + + +Getting started +============ +HISAT-3N requires a 64-bit computer running either Linux or Mac OS X and at least 16 GB of RAM. + +A few notes: + +1. Building the standard 3N index requires 16GB of RAM or less. +2. Building the repeat 3N index requires 256GB of RAM. +3. The alignment process using either the standard or repeat index requires less than 16GB of RAM. +4. [SAMtools] is required to sort SAM files in order to generate a HISAT-3N table. + +Install +------------ + + git clone https://github.com/DaehwanKimLab/hisat2.git hisat-3n + cd hisat-3n + git checkout -b hisat-3n origin/hisat-3n + make + +Build a HISAT-3N index with `hisat-3n-build` +----------- +`hisat-3n-build` builds a 3N-index, which contains two hisat2 indexes, from a set of DNA sequences. For standard 3N-index, +each index contains 16 files with suffix `.3n.*.*.ht2`. +For repeat 3N-index, there are 16 more files in addition to the standard 3N-index, and they have the suffix +`.3n.*.rep.*.ht2`. +These files constitute the hisat-3n index and no other file is needed to alignment reads to the reference. + +* `--base-change ` argument is required for `hisat-3n-build` and `hisat-3n`. + Provide which base is converted in the sequencing process to another base. Please enter + 2 letters separated by ',' for this argument. The first letter(chr1) should be the converted base, the second letter(chr2) should be + the converted to base. For example, during slam-seq, some 'T' is converted to 'C', + please enter `--base-change T,C`. During bisulfite-seq, some 'C' is converted to 'T', please enter `--base-change C,T`. +* Different conversion types may build the same hisat-3n index. Please check the table below for more detail. + Once you build the hisat-3n index with C to T conversion (for example BS-seq). + You can align the T to C conversion reads (for example SLAM-seq reads) with the same index. + + +| Conversion Types | HISAT-3N index suffix | + |:----------------------------------:|:-----------------------------:| +|C -> T
T -> C
A -> G
G -> A|.3n.CT.\*.ht2
.3n.GA.\*.ht2| +|A -> C
C -> A
G -> T
T -> G|.3n.AC.\*.ht2
.3n.TG.\*.ht2| +|A -> T
T -> A |.3n.AT.\*.ht2
.3n.TA.\*.ht2| +|C -> G
G -> C |.3n.CG.\*.ht2
.3n.GC.\*.ht2| + +#### Examples: + # Build the standard HISAT-3N index (with C to T conversion): + hisat-3n-build --base-change C,T genome.fa genome + + # Build the repeat HISAT-3N index (with T to C conversion, require 256 GB memory for human genome index): + hisat-3n-build --base-change T,C --repeat-index genome.fa genome + +It is optional to make the graph index and add SNP or spice site information to the index, to increase the alignment accuracy. +The graph index building may require more memory than the linear index building. +For more detail, please check the [HISAT2 manual]. + +[HISAT2 manual]:https://daehwankimlab.github.io/hisat2/manual/ + +#### Examples: + # Build the standard HISAT-3N index integrated index with SNP information + hisat-3n-build --base-change C,T --snp genome.snp genome.fa genome + + # Build the standard HISAT-3N integrated index with splice site information + hisat-3n-build --base-change C,T --ss genome.ss --exon genome.exon genome.fa genome + + # Build the repeat HISAT-3N index integrated index with SNP information + hisat-3n-build --base-change C,T --repeat-index --snp genome.snp genome.fa genome + + # Build the repeat HISAT-3N integrated index with splice site information + hisat-3n-build --base-change C,T --repeat-index --ss genome.ss --exon genome.exon genome.fa genome + + +Alignment with `hisat-3n` +------------ +After building the HISAT-3N index, you are ready to use `hisat-3n` for alignment. +HISAT-3N has the same set of parameters as in HISAT2 with some additional arguments. Please refer to the [HISAT2 manual] for more details. + +For the human reference genome, HISAT-3N requires about 9GB for alignment with the standard 3N-index and 10.5GB for the repeat 3N-index. + +* `--base-change ` + Specify the nucleotide conversion type (e.g., C to T in bisulfite-sequencing reads). The parameter option is two characters separated by ','. Type the original nucleotide for the first character (nt1) and type the converted nucleotide as the second character (nt2). For example, if performing [SLAM-seq] where some 'T's are converted to 'C's, input `--base-change T,C`. + As another example, if performing bisulfite-seq, where some 'C's are converted to 'T's, please input `--base-change C,T`. + If you want to align non-converted reads to the regular HISAT2 index, then omit this command. + +* `--index/-x ` + Specify the index file basename for HISAT-3N. The basename is the name of the index files up to but not including the suffix `.3n.*.*.ht2` / etc. + For example, if you build your index with basename 'genome' using a HISAT-3N-build, please input `--index genome`. + +* `--directional-mapping` + Make directional mapping. Please use this option only if your sequencing reads are generated from a strand-specific library. + The directional mapping mode is about 2x faster than the standard (non-directional) mapping mode. + +* `--repeat-limit ` + You can set up the number of alignments to be checked for each repeat alignment. You may increase the number to direct hisat-3n + to output more, if a read has multiple mapping locations. We suggest that you limit the repeat number for paired-end read alignment to no more + than 1,000,000. default: 1000. + +* `--unique-only` + Only output uniquely aligned reads. + + +#### Examples: +* Single-end [SLAM-seq] read (T to C conversion) alignment with standard 3N-index: + `hisat-3n --index genome -f -U read.fa -S output.sam --base-change T,C` + +* Paired-end strand-specific bisulfite-seq read (C to T conversion) alignment with repeat 3N-index: + `hisat-3n --index genome -f -1 read_1.fa -2 read_2.fa -S output.sam --base-change C,T --directional-mapping` + +* Single-end TAPS reads (C to T conversion) alignment with repeat 3N-index and only output unique aligned results: + `hisat-3n --index genome -q -U read.fq -S output.sam --base-change C,T --unique` + + + +#### Extra SAM tags generated by HISAT-3N: + +* `Yf:i:`: Number of conversions detected in the read. +* `Zf:i:`: Number of un-converted bases are detected in the read. Yf + Zf = total number of bases which can be converted in the read sequence. +* `YZ:A:
`: The value `+` or `–` indicates the read is mapped to REF-3N (`+`) or REF-RC-3N (`-`), respectively. + +Generate a 3N-conversion-table with `hisat-3n-table` +------------ +### Preparation + +To generate a 3N-conversion-table, users need to sort the `hisat-3n` generated SAM alignment file. + +[SAMtools] is required for this sorting process. + +Use `samtools sort` to convert the SAM file into a sorted SAM file. + + samtools sort output.sam -o output_sorted.sam -O sam + +Generate 3N-conversion-table with `hisat-3n-table`: + +### Usage + hisat-3n-table [options]* --alignments --ref --base-change + +#### Main arguments +* `--alignments ` + SORTED SAM file. Please enter `-` for standard input. + +* `--ref ` + The reference genome file (FASTA format) for generating HISAT-3N index. + +* `--output-name ` + Filename to write 3N-conversion-table (tsv format) to. By default, table is written to the “standard out†or “stdout†filehandle (i.e. the console). + +* `--base-change ` + The base-change rule. User should enter the exact same `--base-change` arguments in hisat-3n. + For example, please enter `--base-change C,T` for bisulfite sequencing reads. + +#### Input options +* `-u/--unique-only` + Only count the unique aligned reads into 3N-conversion-table. + +* `-m/--multiple-only` + Only count the multiple aligned reads into 3N-conversion-table. + +* `-c/--CG-only` + Only count the CpG sites in reference genome. This option is designed for bisulfite sequencing reads. + +* `--added-chrname` + Please add this option if you use `--add-chrname` during `hisat-3n` alignment. + During `hisat-3n` alignment, the prefix "chr" is added in front of chromosome name and shows on SAM output, when user choose `--add-chrname`. + `hisat-3n-table` cannot find the chromosome name on reference because it has an additional "chr" prefix. This option is to help `hisat-3n-table` + find the matching chromosome name on reference file. The 3n-table provides the same chromosome name as SAM file. + +* `--removed-chrname` + Please add this option if you use `--remove-chrname` during `hisat-3n` alignment. + During `hisat-3n` alignment, the prefix "chr" is removed in front of chromosome name and shows on SAM output, when user choose `--remove-chrname`. + `hisat-3n-table` cannot find the chromosome name on reference because it has no "chr" prefix. This option is to help `hisat-3n-table` + find the matching chromosome name on reference file. The 3n-table provides the same chromosome name as SAM file. + +#### Other options: +* `-p/--threads ` + Launch `int` parallel threads (default: 1) for table building. + +* `-h/--help` + Print usage information and quit. + +#### Examples: + # Generate the 3N-conversion-table for bisulfite sequencing data: + hisat-3n-table -p 16 --alignments sorted_alignment_result.sam --ref genome.fa --output-name output.tsv --base-change C,T + + # Generate the 3N-conversion-table for TAPS data and only count base in CpG site and uniquely aligned: + hisat-3n-table -p 16 --alignments sorted_alignment_result.sam --ref genome.fa --output-name output.tsv --base-change C,T --CG-only --unique-only + + # Generate the 3N-conversion-table for bisulfite sequencing data from sorted BAM file: + samtools view -h sorted_alignment_result.bam | hisat-3n-table --ref genome.fa --alignments - --output-name output.tsv --base-change C,T + + # Generate the 3N-conversion-table for bisulfite sequencing data from unsorted BAM file: + samtools sort alignment_result.bam -O sam | hisat-3n-table --ref genome.fa --alignments - --output-name output.tsv --base-change C,T + + +#### Note: +There are 7 columns in the 3N-conversion-table: + +1. `ref`: the chromosome name. +2. `pos`: 1-based position in `ref`. +3. `strand`: '+' for forward strand. '-' for reverse strand. +4. `convertedBaseQualities`: the qualities of the converted bases in read-level measurement. The length of this string is equal to the number of converted bases. +5. `convertedBaseCount`: the number of distinct read positions where converted bases in read-level measurements were found. + this number is equal to the length of convertedBaseQualities. +6. `unconvertedBaseQualities`: the qualities of the unconverted bases in read-level measurement. The length of this string is equal to the number of unconverted bases in read-level measurement. +7. `unconvertedBaseCount`: the number of distinct read positions where unconverted bases in read-level measurements were found. + this number is equal to the length of unconvertedBaseQualities. + +##### Sample 3N-conversion-table: + ref pos strand convertedBaseQualities convertedBaseCount unconvertedBaseQualities unconvertedBaseCount + 1 11874 + FFFFFB + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "aligner_bt.h" +#include "mask.h" + +using namespace std; + +#define CHECK_ROW_COL(rowc, colc) \ + if(rowc >= 0 && colc >= 0) { \ + if(!sawcell_[colc].insert(rowc)) { \ + /* was already in there */ \ + abort = true; \ + return; \ + } \ + assert(local || prob_.cper_->debugCell(rowc, colc, hefc)); \ + } + +/** + * Fill in a triangle of the DP table and backtrace from the given cell to + * a cell in the previous checkpoint, or to the terminal cell. + */ +void BtBranchTracer::triangleFill( + int64_t rw, // row of cell to backtrace from + int64_t cl, // column of cell to backtrace from + int hef, // cell to backtrace from is H (0), E (1), or F (2) + TAlScore targ, // score of cell to backtrace from + TAlScore targ_final, // score of alignment we're looking for + RandomSource& rnd, // pseudo-random generator + int64_t& row_new, // out: row we ended up in after backtrace + int64_t& col_new, // out: column we ended up in after backtrace + int& hef_new, // out: H/E/F after backtrace + TAlScore& targ_new, // out: score up to cell we ended up in + bool& done, // out: finished tracing out an alignment? + bool& abort) // out: aborted b/c cell was seen before? +{ + assert_geq(rw, 0); + assert_geq(cl, 0); + assert_range(0, 2, hef); + assert_lt(rw, (int64_t)prob_.qrylen_); + assert_lt(cl, (int64_t)prob_.reflen_); + assert(prob_.usecp_ && prob_.fill_); + int64_t row = rw, col = cl; + const int64_t colmin = 0; + const int64_t rowmin = 0; + const int64_t colmax = prob_.reflen_ - 1; + const int64_t rowmax = prob_.qrylen_ - 1; + assert_leq(prob_.reflen_, (TRefOff)sawcell_.size()); + assert_leq(col, (int64_t)prob_.cper_->hicol()); + assert_geq(col, (int64_t)prob_.cper_->locol()); + assert_geq(prob_.cper_->per(), 2); + size_t mod = (row + col) & prob_.cper_->lomask(); + assert_lt(mod, prob_.cper_->per()); + // Allocate room for diags + size_t depth = mod+1; + assert_leq(depth, prob_.cper_->per()); + size_t breadth = depth; + tri_.resize(depth); + // Allocate room for each diag + for(size_t i = 0; i < depth; i++) { + tri_[i].resize(breadth - i); + } + bool upperleft = false; + size_t off = (row + col) >> prob_.cper_->perpow2(); + if(off == 0) { + upperleft = true; + } else { + off--; + } + const TAlScore sc_rdo = prob_.sc_->readGapOpen(); + const TAlScore sc_rde = prob_.sc_->readGapExtend(); + const TAlScore sc_rfo = prob_.sc_->refGapOpen(); + const TAlScore sc_rfe = prob_.sc_->refGapExtend(); + const bool local = !prob_.sc_->monotone; + int64_t row_lo = row - (int64_t)mod; + const CpQuad *prev2 = NULL, *prev1 = NULL; + if(!upperleft) { + // Read-only pointer to cells in diagonal -2. Start one row above the + // target row. + prev2 = prob_.cper_->qdiag1sPtr() + (off * prob_.cper_->nrow() + row_lo - 1); + // Read-only pointer to cells in diagonal -1. Start one row above the + // target row + prev1 = prob_.cper_->qdiag2sPtr() + (off * prob_.cper_->nrow() + row_lo - 1); +#ifndef NDEBUG + if(row >= (int64_t)mod) { + size_t rowc = row - mod, colc = col; + if(rowc > 0 && prob_.cper_->isCheckpointed(rowc-1, colc)) { + TAlScore al = prev1[0].sc[0]; + if(al == MIN_I16) al = MIN_I64; + assert_eq(prob_.cper_->scoreTriangle(rowc-1, colc, 0), al); + } + if(rowc > 0 && colc > 0 && prob_.cper_->isCheckpointed(rowc-1, colc-1)) { + TAlScore al = prev2[0].sc[0]; + if(al == MIN_I16) al = MIN_I64; + assert_eq(prob_.cper_->scoreTriangle(rowc-1, colc-1, 0), al); + } + } +#endif + } + // Pointer to cells in current diagonal + // For each diagonal we need to fill in + for(size_t i = 0; i < depth; i++) { + CpQuad * cur = tri_[i].ptr(); + CpQuad * curc = cur; + size_t doff = mod - i; // # diagonals we are away from target diag + //assert_geq(row, (int64_t)doff); + int64_t rowc = row - doff; + int64_t colc = col; + size_t neval = 0; // # cells evaluated in this diag + ASSERT_ONLY(const CpQuad *last = NULL); + // Fill this diagonal from upper right to lower left + for(size_t j = 0; j < breadth; j++) { + if(rowc >= rowmin && rowc <= rowmax && + colc >= colmin && colc <= colmax) + { + neval++; + int64_t fromend = prob_.qrylen_ - rowc - 1; + bool allowGaps = fromend >= prob_.sc_->gapbar && rowc >= prob_.sc_->gapbar; + // Fill this cell + // Some things we might want to calculate about this cell up front: + // 1. How many matches are possible from this cell to the cell in + // row, col, in case this allows us to prune + // Get character from read + int qc = prob_.qry_[rowc]; + // Get quality value from read + int qq = prob_.qual_[rowc]; + assert_geq(qq, 33); + // Get character from reference + int rc = prob_.ref_[colc]; + assert_range(0, 16, rc); + int16_t sc_diag = prob_.sc_->score(qc, rc, qq - 33); + int16_t sc_h_up = MIN_I16; + int16_t sc_f_up = MIN_I16; + int16_t sc_h_lf = MIN_I16; + int16_t sc_e_lf = MIN_I16; + if(allowGaps) { + if(rowc > 0) { + assert(local || prev1[j+0].sc[2] < 0); + if(prev1[j+0].sc[0] > MIN_I16) { + sc_h_up = prev1[j+0].sc[0] - sc_rfo; + if(local) sc_h_up = max(sc_h_up, 0); + } + if(prev1[j+0].sc[2] > MIN_I16) { + sc_f_up = prev1[j+0].sc[2] - sc_rfe; + if(local) sc_f_up = max(sc_f_up, 0); + } +#ifndef NDEBUG + TAlScore hup = prev1[j+0].sc[0]; + TAlScore fup = prev1[j+0].sc[2]; + if(hup == MIN_I16) hup = MIN_I64; + if(fup == MIN_I16) fup = MIN_I64; + if(local) { + hup = max(hup, 0); + fup = max(fup, 0); + } + if(prob_.cper_->isCheckpointed(rowc-1, colc)) { + assert_eq(hup, prob_.cper_->scoreTriangle(rowc-1, colc, 0)); + assert_eq(fup, prob_.cper_->scoreTriangle(rowc-1, colc, 2)); + } +#endif + } + if(colc > 0) { + assert(local || prev1[j+1].sc[1] < 0); + if(prev1[j+1].sc[0] > MIN_I16) { + sc_h_lf = prev1[j+1].sc[0] - sc_rdo; + if(local) sc_h_lf = max(sc_h_lf, 0); + } + if(prev1[j+1].sc[1] > MIN_I16) { + sc_e_lf = prev1[j+1].sc[1] - sc_rde; + if(local) sc_e_lf = max(sc_e_lf, 0); + } +#ifndef NDEBUG + TAlScore hlf = prev1[j+1].sc[0]; + TAlScore elf = prev1[j+1].sc[1]; + if(hlf == MIN_I16) hlf = MIN_I64; + if(elf == MIN_I16) elf = MIN_I64; + if(local) { + hlf = max(hlf, 0); + elf = max(elf, 0); + } + if(prob_.cper_->isCheckpointed(rowc, colc-1)) { + assert_eq(hlf, prob_.cper_->scoreTriangle(rowc, colc-1, 0)); + assert_eq(elf, prob_.cper_->scoreTriangle(rowc, colc-1, 1)); + } +#endif + } + } + assert(rowc <= 1 || colc <= 0 || prev2 != NULL); + int16_t sc_h_dg = ((rowc > 0 && colc > 0) ? prev2[j+0].sc[0] : 0); + if(colc == 0 && rowc > 0 && !local) { + sc_h_dg = MIN_I16; + } + if(sc_h_dg > MIN_I16) { + sc_h_dg += sc_diag; + } + if(local) sc_h_dg = max(sc_h_dg, 0); + // cerr << sc_diag << " " << sc_h_dg << " " << sc_h_up << " " << sc_f_up << " " << sc_h_lf << " " << sc_e_lf << endl; + int mask = 0; + // Calculate best ways into H, E, F cells starting with H. + // Mask bits: + // H: 1=diag, 2=hhoriz, 4=ehoriz, 8=hvert, 16=fvert + // E: 32=hhoriz, 64=ehoriz + // F: 128=hvert, 256=fvert + int16_t sc_best = sc_h_dg; + if(sc_h_dg > MIN_I64) { + mask = 1; + } + if(colc > 0 && sc_h_lf >= sc_best && sc_h_lf > MIN_I64) { + if(sc_h_lf > sc_best) mask = 0; + mask |= 2; + sc_best = sc_h_lf; + } + if(colc > 0 && sc_e_lf >= sc_best && sc_e_lf > MIN_I64) { + if(sc_e_lf > sc_best) mask = 0; + mask |= 4; + sc_best = sc_e_lf; + } + if(rowc > 0 && sc_h_up >= sc_best && sc_h_up > MIN_I64) { + if(sc_h_up > sc_best) mask = 0; + mask |= 8; + sc_best = sc_h_up; + } + if(rowc > 0 && sc_f_up >= sc_best && sc_f_up > MIN_I64) { + if(sc_f_up > sc_best) mask = 0; + mask |= 16; + sc_best = sc_f_up; + } + // Calculate best way into E cell + int16_t sc_e_best = sc_h_lf; + if(colc > 0) { + if(sc_h_lf >= sc_e_lf && sc_h_lf > MIN_I64) { + if(sc_h_lf == sc_e_lf) { + mask |= 64; + } + mask |= 32; + } else if(sc_e_lf > MIN_I64) { + sc_e_best = sc_e_lf; + mask |= 64; + } + } + if(sc_e_best > sc_best) { + sc_best = sc_e_best; + mask &= ~31; // don't go diagonal + } + // Calculate best way into F cell + int16_t sc_f_best = sc_h_up; + if(rowc > 0) { + if(sc_h_up >= sc_f_up && sc_h_up > MIN_I64) { + if(sc_h_up == sc_f_up) { + mask |= 256; + } + mask |= 128; + } else if(sc_f_up > MIN_I64) { + sc_f_best = sc_f_up; + mask |= 256; + } + } + if(sc_f_best > sc_best) { + sc_best = sc_f_best; + mask &= ~127; // don't go horizontal or diagonal + } + // Install results in cur + assert(!prob_.sc_->monotone || sc_best <= 0); + assert(!prob_.sc_->monotone || sc_e_best <= 0); + assert(!prob_.sc_->monotone || sc_f_best <= 0); + curc->sc[0] = sc_best; + assert( local || sc_e_best < 0); + assert( local || sc_f_best < 0); + assert(!local || sc_e_best >= 0 || sc_e_best == MIN_I16); + assert(!local || sc_f_best >= 0 || sc_f_best == MIN_I16); + curc->sc[1] = sc_e_best; + curc->sc[2] = sc_f_best; + curc->sc[3] = mask; + // cerr << curc->sc[0] << " " << curc->sc[1] << " " << curc->sc[2] << " " << curc->sc[3] << endl; + ASSERT_ONLY(last = curc); +#ifndef NDEBUG + if(prob_.cper_->isCheckpointed(rowc, colc)) { + if(local) { + sc_e_best = max(sc_e_best, 0); + sc_f_best = max(sc_f_best, 0); + } + TAlScore sc_best64 = sc_best; if(sc_best == MIN_I16) sc_best64 = MIN_I64; + TAlScore sc_e_best64 = sc_e_best; if(sc_e_best == MIN_I16) sc_e_best64 = MIN_I64; + TAlScore sc_f_best64 = sc_f_best; if(sc_f_best == MIN_I16) sc_f_best64 = MIN_I64; + assert_eq(prob_.cper_->scoreTriangle(rowc, colc, 0), sc_best64); + assert_eq(prob_.cper_->scoreTriangle(rowc, colc, 1), sc_e_best64); + assert_eq(prob_.cper_->scoreTriangle(rowc, colc, 2), sc_f_best64); + } +#endif + } + // Update row, col + assert_lt(rowc, (int64_t)prob_.qrylen_); + rowc++; + colc--; + curc++; + } // for(size_t j = 0; j < breadth; j++) + if(i == depth-1) { + // Final iteration + assert(last != NULL); + assert_eq(1, neval); + assert_neq(0, last->sc[3]); + assert_eq(targ, last->sc[hef]); + } else { + breadth--; + prev2 = prev1 + 1; + prev1 = cur; + } + } // for(size_t i = 0; i < depth; i++) + // + // Now backtrack through the triangle. Abort as soon as we enter a cell + // that was visited by a previous backtrace. + // + int64_t rowc = row, colc = col; + size_t curid; + int hefc = hef; + if(bs_.empty()) { + // Start an initial branch + CHECK_ROW_COL(rowc, colc); + curid = bs_.alloc(); + assert_eq(0, curid); + Edit e; + bs_[curid].init( + prob_, + 0, // parent ID + 0, // penalty + 0, // score_en + rowc, // row + colc, // col + e, // edit + 0, // hef + true, // I am the root + false); // don't try to extend with exact matches + bs_[curid].len_ = 0; + } else { + curid = bs_.size()-1; + } + size_t idx_orig = (row + col) >> prob_.cper_->perpow2(); + while(true) { + // What depth are we? + size_t mod = (rowc + colc) & prob_.cper_->lomask(); + assert_lt(mod, prob_.cper_->per()); + CpQuad * cur = tri_[mod].ptr(); + int64_t row_off = rowc - row_lo - mod; + assert(!local || cur[row_off].sc[0] > 0); + assert_geq(row_off, 0); + int mask = cur[row_off].sc[3]; + assert_gt(mask, 0); + int sel = -1; + // Select what type of move to make, which depends on whether we're + // currently in H, E, F: + if(hefc == 0) { + if( (mask & 1) != 0) { + // diagonal + sel = 0; + } else if((mask & 8) != 0) { + // up to H + sel = 3; + } else if((mask & 16) != 0) { + // up to F + sel = 4; + } else if((mask & 2) != 0) { + // left to H + sel = 1; + } else if((mask & 4) != 0) { + // left to E + sel = 2; + } + } else if(hefc == 1) { + if( (mask & 32) != 0) { + // left to H + sel = 5; + } else if((mask & 64) != 0) { + // left to E + sel = 6; + } + } else { + assert_eq(2, hefc); + if( (mask & 128) != 0) { + // up to H + sel = 7; + } else if((mask & 256) != 0) { + // up to F + sel = 8; + } + } + assert_geq(sel, 0); + // Get character from read + int qc = prob_.qry_[rowc], qq = prob_.qual_[rowc]; + // Get character from reference + int rc = prob_.ref_[colc]; + assert_range(0, 16, rc); + // Now that we know what type of move to make, make it, updating our + // row and column and moving updating the branch. + if(sel == 0) { + assert_geq(rowc, 0); + assert_geq(colc, 0); + TAlScore scd = prob_.sc_->score(qc, rc, qq - 33); + if((rc & (1 << qc)) == 0) { + // Mismatch + size_t id = curid; + // Check if the previous branch was the initial (bottommost) + // branch with no matches. If so, the mismatch should be added + // to the initial branch, instead of starting a new branch. + bool empty = (bs_[curid].len_ == 0 && curid == 0); + if(!empty) { + id = bs_.alloc(); + } + Edit e((int)rowc, mask2dna[rc], "ACGTN"[qc], EDIT_TYPE_MM); + assert_lt(scd, 0); + TAlScore score_en = bs_[curid].score_st_ + scd; + bs_[id].init( + prob_, + curid, // parent ID + -scd, // penalty + score_en, // score_en + rowc, // row + colc, // col + e, // edit + hefc, // hef + empty, // root? + false); // don't try to extend with exact matches + //assert(!local || bs_[id].score_st_ >= 0); + curid = id; + } else { + // Match + bs_[curid].score_st_ += prob_.sc_->match(); + bs_[curid].len_++; + assert_leq((int64_t)bs_[curid].len_, bs_[curid].row_ + 1); + } + rowc--; + colc--; + assert(local || bs_[curid].score_st_ >= targ_final); + hefc = 0; + } else if((sel >= 1 && sel <= 2) || (sel >= 5 && sel <= 6)) { + assert_gt(colc, 0); + // Read gap + size_t id = bs_.alloc(); + Edit e((int)rowc+1, mask2dna[rc], '-', EDIT_TYPE_READ_GAP); + TAlScore gapp = prob_.sc_->readGapOpen(); + if(bs_[curid].len_ == 0 && bs_[curid].e_.inited() && bs_[curid].e_.isReadGap()) { + gapp = prob_.sc_->readGapExtend(); + } + TAlScore score_en = bs_[curid].score_st_ - gapp; + bs_[id].init( + prob_, + curid, // parent ID + gapp, // penalty + score_en, // score_en + rowc, // row + colc-1, // col + e, // edit + hefc, // hef + false, // root? + false); // don't try to extend with exact matches + colc--; + curid = id; + assert( local || bs_[curid].score_st_ >= targ_final); + //assert(!local || bs_[curid].score_st_ >= 0); + if(sel == 1 || sel == 5) { + hefc = 0; + } else { + hefc = 1; + } + } else { + assert_gt(rowc, 0); + // Reference gap + size_t id = bs_.alloc(); + Edit e((int)rowc, '-', "ACGTN"[qc], EDIT_TYPE_REF_GAP); + TAlScore gapp = prob_.sc_->refGapOpen(); + if(bs_[curid].len_ == 0 && bs_[curid].e_.inited() && bs_[curid].e_.isRefGap()) { + gapp = prob_.sc_->refGapExtend(); + } + TAlScore score_en = bs_[curid].score_st_ - gapp; + bs_[id].init( + prob_, + curid, // parent ID + gapp, // penalty + score_en, // score_en + rowc-1, // row + colc, // col + e, // edit + hefc, // hef + false, // root? + false); // don't try to extend with exact matches + rowc--; + curid = id; + //assert(!local || bs_[curid].score_st_ >= 0); + if(sel == 3 || sel == 7) { + hefc = 0; + } else { + hefc = 2; + } + } + CHECK_ROW_COL(rowc, colc); + size_t mod_new = (rowc + colc) & prob_.cper_->lomask(); + size_t idx = (rowc + colc) >> prob_.cper_->perpow2(); + assert_lt(mod_new, prob_.cper_->per()); + int64_t row_off_new = rowc - row_lo - mod_new; + CpQuad * cur_new = NULL; + if(colc >= 0 && rowc >= 0 && idx == idx_orig) { + cur_new = tri_[mod_new].ptr(); + } + bool hit_new_tri = (idx < idx_orig && colc >= 0 && rowc >= 0); + // Check whether we made it to the top row or to a cell with score 0 + if(colc < 0 || rowc < 0 || + (cur_new != NULL && (local && cur_new[row_off_new].sc[0] == 0))) + { + done = true; + assert(bs_[curid].isSolution(prob_)); + addSolution(curid); +#ifndef NDEBUG + // A check to see if any two adjacent branches in the backtrace + // overlap. If they do, the whole alignment will be filtered out + // in trySolution(...) + size_t cur = curid; + if(!bs_[cur].root_) { + size_t next = bs_[cur].parentId_; + while(!bs_[next].root_) { + assert_neq(cur, next); + if(bs_[next].len_ != 0 || bs_[cur].len_ == 0) { + assert(!bs_[cur].overlap(prob_, bs_[next])); + } + cur = next; + next = bs_[cur].parentId_; + } + } +#endif + return; + } + if(hit_new_tri) { + assert(rowc < 0 || colc < 0 || prob_.cper_->isCheckpointed(rowc, colc)); + row_new = rowc; col_new = colc; + hef_new = hefc; + done = false; + if(rowc < 0 || colc < 0) { + assert(local); + targ_new = 0; + } else { + targ_new = prob_.cper_->scoreTriangle(rowc, colc, hefc); + } + if(local && targ_new == 0) { + done = true; + assert(bs_[curid].isSolution(prob_)); + addSolution(curid); + } + assert((row_new >= 0 && col_new >= 0) || done); + return; + } + } + assert(false); +} + +#ifndef NDEBUG +#define DEBUG_CHECK(ss, row, col, hef) { \ + if(prob_.cper_->debug() && row >= 0 && col >= 0) { \ + TAlScore s = ss; \ + if(s == MIN_I16) s = MIN_I64; \ + if(local && s < 0) s = 0; \ + TAlScore deb = prob_.cper_->debugCell(row, col, hef); \ + if(local && deb < 0) deb = 0; \ + assert_eq(s, deb); \ + } \ +} +#else +#define DEBUG_CHECK(ss, row, col, hef) +#endif + + +/** + * Fill in a square of the DP table and backtrace from the given cell to + * a cell in the previous checkpoint, or to the terminal cell. + */ +void BtBranchTracer::squareFill( + int64_t rw, // row of cell to backtrace from + int64_t cl, // column of cell to backtrace from + int hef, // cell to backtrace from is H (0), E (1), or F (2) + TAlScore targ, // score of cell to backtrace from + TAlScore targ_final, // score of alignment we're looking for + RandomSource& rnd, // pseudo-random generator + int64_t& row_new, // out: row we ended up in after backtrace + int64_t& col_new, // out: column we ended up in after backtrace + int& hef_new, // out: H/E/F after backtrace + TAlScore& targ_new, // out: score up to cell we ended up in + bool& done, // out: finished tracing out an alignment? + bool& abort) // out: aborted b/c cell was seen before? +{ + assert_geq(rw, 0); + assert_geq(cl, 0); + assert_range(0, 2, hef); + assert_lt(rw, (int64_t)prob_.qrylen_); + assert_lt(cl, (int64_t)prob_.reflen_); + assert(prob_.usecp_ && prob_.fill_); + const bool is8_ = prob_.cper_->is8_; + int64_t row = rw, col = cl; + assert_leq(prob_.reflen_, (TRefOff)sawcell_.size()); + assert_leq(col, (int64_t)prob_.cper_->hicol()); + assert_geq(col, (int64_t)prob_.cper_->locol()); + assert_geq(prob_.cper_->per(), 2); + size_t xmod = col & prob_.cper_->lomask(); + size_t ymod = row & prob_.cper_->lomask(); + size_t xdiv = col >> prob_.cper_->perpow2(); + size_t ydiv = row >> prob_.cper_->perpow2(); + size_t sq_ncol = xmod+1, sq_nrow = ymod+1; + sq_.resize(sq_ncol * sq_nrow); + bool upper = ydiv == 0; + bool left = xdiv == 0; + const TAlScore sc_rdo = prob_.sc_->readGapOpen(); + const TAlScore sc_rde = prob_.sc_->readGapExtend(); + const TAlScore sc_rfo = prob_.sc_->refGapOpen(); + const TAlScore sc_rfe = prob_.sc_->refGapExtend(); + const bool local = !prob_.sc_->monotone; + const CpQuad *qup = NULL; + const __m128i *qlf = NULL; + size_t per = prob_.cper_->per_; + ASSERT_ONLY(size_t nrow = prob_.cper_->nrow()); + size_t ncol = prob_.cper_->ncol(); + assert_eq(prob_.qrylen_, nrow); + assert_eq(prob_.reflen_, (TRefOff)ncol); + size_t niter = prob_.cper_->niter_; + if(!upper) { + qup = prob_.cper_->qrows_.ptr() + (ncol * (ydiv-1)) + xdiv * per; + } + if(!left) { + // Set up the column pointers to point to the first __m128i word in the + // relevant column + size_t off = (niter << 2) * (xdiv-1); + qlf = prob_.cper_->qcols_.ptr() + off; + } + size_t xedge = xdiv * per; // absolute offset of leftmost cell in square + size_t yedge = ydiv * per; // absolute offset of topmost cell in square + size_t xi = xedge, yi = yedge; // iterators for columns, rows + size_t ii = 0; // iterator into packed square + // Iterate over rows, then over columns + size_t m128mod = yi % prob_.cper_->niter_; + size_t m128div = yi / prob_.cper_->niter_; + int16_t sc_h_dg_lastrow = MIN_I16; + for(size_t i = 0; i <= ymod; i++, yi++) { + assert_lt(yi, nrow); + xi = xedge; + // Handling for first column is done outside the loop + size_t fromend = prob_.qrylen_ - yi - 1; + bool allowGaps = fromend >= (size_t)prob_.sc_->gapbar && yi >= (size_t)prob_.sc_->gapbar; + // Get character, quality from read + int qc = prob_.qry_[yi], qq = prob_.qual_[yi]; + assert_geq(qq, 33); + int16_t sc_h_lf_last = MIN_I16; + int16_t sc_e_lf_last = MIN_I16; + for(size_t j = 0; j <= xmod; j++, xi++) { + assert_lt(xi, ncol); + // Get character from reference + int rc = prob_.ref_[xi]; + assert_range(0, 16, rc); + int16_t sc_diag = prob_.sc_->score(qc, rc, qq - 33); + int16_t sc_h_up = MIN_I16, sc_f_up = MIN_I16, + sc_h_lf = MIN_I16, sc_e_lf = MIN_I16, + sc_h_dg = MIN_I16; + int16_t sc_h_up_c = MIN_I16, sc_f_up_c = MIN_I16, + sc_h_lf_c = MIN_I16, sc_e_lf_c = MIN_I16, + sc_h_dg_c = MIN_I16; + if(yi == 0) { + // If I'm in the first first row or column set it to 0 + sc_h_dg = 0; + } else if(xi == 0) { + // Do nothing; leave it at min + if(local) { + sc_h_dg = 0; + } + } else if(i == 0 && j == 0) { + // Otherwise, if I'm in the upper-left square corner, I can get + // it from the checkpoint + sc_h_dg = qup[-1].sc[0]; + } else if(j == 0) { + // Otherwise, if I'm in the leftmost cell of this row, I can + // get it from sc_h_lf in first column of previous row + sc_h_dg = sc_h_dg_lastrow; + } else { + // Otherwise, I can get it from qup + sc_h_dg = qup[j-1].sc[0]; + } + if(yi > 0 && xi > 0) DEBUG_CHECK(sc_h_dg, yi-1, xi-1, 2); + + // If we're in the leftmost column, calculate sc_h_lf regardless of + // allowGaps. + if(j == 0 && xi > 0) { + // Get values for left neighbors from the checkpoint + if(is8_) { + size_t vecoff = (m128mod << 6) + m128div; + sc_e_lf = ((uint8_t*)(qlf + 0))[vecoff]; + sc_h_lf = ((uint8_t*)(qlf + 2))[vecoff]; + if(local) { + // No adjustment + } else { + if(sc_h_lf == 0) sc_h_lf = MIN_I16; + else sc_h_lf -= 0xff; + if(sc_e_lf == 0) sc_e_lf = MIN_I16; + else sc_e_lf -= 0xff; + } + } else { + size_t vecoff = (m128mod << 5) + m128div; + sc_e_lf = ((int16_t*)(qlf + 0))[vecoff]; + sc_h_lf = ((int16_t*)(qlf + 2))[vecoff]; + if(local) { + sc_h_lf += 0x8000; assert_geq(sc_h_lf, 0); + sc_e_lf += 0x8000; assert_geq(sc_e_lf, 0); + } else { + if(sc_h_lf != MIN_I16) sc_h_lf -= 0x7fff; + if(sc_e_lf != MIN_I16) sc_e_lf -= 0x7fff; + } + } + DEBUG_CHECK(sc_e_lf, yi, xi-1, 0); + DEBUG_CHECK(sc_h_lf, yi, xi-1, 2); + sc_h_dg_lastrow = sc_h_lf; + } + + if(allowGaps) { + if(j == 0 /* at left edge */ && xi > 0 /* not extreme */) { + sc_h_lf_c = sc_h_lf; + sc_e_lf_c = sc_e_lf; + if(sc_h_lf_c != MIN_I16) sc_h_lf_c -= sc_rdo; + if(sc_e_lf_c != MIN_I16) sc_e_lf_c -= sc_rde; + assert_leq(sc_h_lf_c, prob_.cper_->perf_); + assert_leq(sc_e_lf_c, prob_.cper_->perf_); + } else if(xi > 0) { + // Get values for left neighbors from the previous iteration + if(sc_h_lf_last != MIN_I16) { + sc_h_lf = sc_h_lf_last; + sc_h_lf_c = sc_h_lf - sc_rdo; + } + if(sc_e_lf_last != MIN_I16) { + sc_e_lf = sc_e_lf_last; + sc_e_lf_c = sc_e_lf - sc_rde; + } + } + if(yi > 0 /* not extreme */) { + // Get column values + assert(qup != NULL); + assert(local || qup[j].sc[2] < 0); + if(qup[j].sc[0] > MIN_I16) { + DEBUG_CHECK(qup[j].sc[0], yi-1, xi, 2); + sc_h_up = qup[j].sc[0]; + sc_h_up_c = sc_h_up - sc_rfo; + } + if(qup[j].sc[2] > MIN_I16) { + DEBUG_CHECK(qup[j].sc[2], yi-1, xi, 1); + sc_f_up = qup[j].sc[2]; + sc_f_up_c = sc_f_up - sc_rfe; + } + } + if(local) { + sc_h_up_c = max(sc_h_up_c, 0); + sc_f_up_c = max(sc_f_up_c, 0); + sc_h_lf_c = max(sc_h_lf_c, 0); + sc_e_lf_c = max(sc_e_lf_c, 0); + } + } + + if(sc_h_dg > MIN_I16) { + sc_h_dg_c = sc_h_dg + sc_diag; + } + if(local) sc_h_dg_c = max(sc_h_dg_c, 0); + + int mask = 0; + // Calculate best ways into H, E, F cells starting with H. + // Mask bits: + // H: 1=diag, 2=hhoriz, 4=ehoriz, 8=hvert, 16=fvert + // E: 32=hhoriz, 64=ehoriz + // F: 128=hvert, 256=fvert + int16_t sc_best = sc_h_dg_c; + if(sc_h_dg_c > MIN_I64) { + mask = 1; + } + if(xi > 0 && sc_h_lf_c >= sc_best && sc_h_lf_c > MIN_I64) { + if(sc_h_lf_c > sc_best) mask = 0; + mask |= 2; + sc_best = sc_h_lf_c; + } + if(xi > 0 && sc_e_lf_c >= sc_best && sc_e_lf_c > MIN_I64) { + if(sc_e_lf_c > sc_best) mask = 0; + mask |= 4; + sc_best = sc_e_lf_c; + } + if(yi > 0 && sc_h_up_c >= sc_best && sc_h_up_c > MIN_I64) { + if(sc_h_up_c > sc_best) mask = 0; + mask |= 8; + sc_best = sc_h_up_c; + } + if(yi > 0 && sc_f_up_c >= sc_best && sc_f_up_c > MIN_I64) { + if(sc_f_up_c > sc_best) mask = 0; + mask |= 16; + sc_best = sc_f_up_c; + } + // Calculate best way into E cell + int16_t sc_e_best = sc_h_lf_c; + if(xi > 0) { + if(sc_h_lf_c >= sc_e_lf_c && sc_h_lf_c > MIN_I64) { + if(sc_h_lf_c == sc_e_lf_c) { + mask |= 64; + } + mask |= 32; + } else if(sc_e_lf_c > MIN_I64) { + sc_e_best = sc_e_lf_c; + mask |= 64; + } + } + if(sc_e_best > sc_best) { + sc_best = sc_e_best; + mask &= ~31; // don't go diagonal + } + // Calculate best way into F cell + int16_t sc_f_best = sc_h_up_c; + if(yi > 0) { + if(sc_h_up_c >= sc_f_up_c && sc_h_up_c > MIN_I64) { + if(sc_h_up_c == sc_f_up_c) { + mask |= 256; + } + mask |= 128; + } else if(sc_f_up_c > MIN_I64) { + sc_f_best = sc_f_up_c; + mask |= 256; + } + } + if(sc_f_best > sc_best) { + sc_best = sc_f_best; + mask &= ~127; // don't go horizontal or diagonal + } + // Install results in cur + assert( local || sc_best <= 0); + sq_[ii+j].sc[0] = sc_best; + assert( local || sc_e_best < 0); + assert( local || sc_f_best < 0); + assert(!local || sc_e_best >= 0 || sc_e_best == MIN_I16); + assert(!local || sc_f_best >= 0 || sc_f_best == MIN_I16); + sq_[ii+j].sc[1] = sc_e_best; + sq_[ii+j].sc[2] = sc_f_best; + sq_[ii+j].sc[3] = mask; + DEBUG_CHECK(sq_[ii+j].sc[0], yi, xi, 2); // H + DEBUG_CHECK(sq_[ii+j].sc[1], yi, xi, 0); // E + DEBUG_CHECK(sq_[ii+j].sc[2], yi, xi, 1); // F + // Update sc_h_lf_last, sc_e_lf_last + sc_h_lf_last = sc_best; + sc_e_lf_last = sc_e_best; + } + // Update m128mod, m128div + m128mod++; + if(m128mod == prob_.cper_->niter_) { + m128mod = 0; + m128div++; + } + // update qup + ii += sq_ncol; + // dimensions of sq_ + qup = sq_.ptr() + sq_ncol * i; + } + assert_eq(targ, sq_[ymod * sq_ncol + xmod].sc[hef]); + // + // Now backtrack through the triangle. Abort as soon as we enter a cell + // that was visited by a previous backtrace. + // + int64_t rowc = row, colc = col; + size_t curid; + int hefc = hef; + if(bs_.empty()) { + // Start an initial branch + CHECK_ROW_COL(rowc, colc); + curid = bs_.alloc(); + assert_eq(0, curid); + Edit e; + bs_[curid].init( + prob_, + 0, // parent ID + 0, // penalty + 0, // score_en + rowc, // row + colc, // col + e, // edit + 0, // hef + true, // root? + false); // don't try to extend with exact matches + bs_[curid].len_ = 0; + } else { + curid = bs_.size()-1; + } + size_t ymodTimesNcol = ymod * sq_ncol; + while(true) { + // What depth are we? + assert_eq(ymodTimesNcol, ymod * sq_ncol); + CpQuad * cur = sq_.ptr() + ymodTimesNcol + xmod; + int mask = cur->sc[3]; + assert_gt(mask, 0); + int sel = -1; + // Select what type of move to make, which depends on whether we're + // currently in H, E, F: + if(hefc == 0) { + if( (mask & 1) != 0) { + // diagonal + sel = 0; + } else if((mask & 8) != 0) { + // up to H + sel = 3; + } else if((mask & 16) != 0) { + // up to F + sel = 4; + } else if((mask & 2) != 0) { + // left to H + sel = 1; + } else if((mask & 4) != 0) { + // left to E + sel = 2; + } + } else if(hefc == 1) { + if( (mask & 32) != 0) { + // left to H + sel = 5; + } else if((mask & 64) != 0) { + // left to E + sel = 6; + } + } else { + assert_eq(2, hefc); + if( (mask & 128) != 0) { + // up to H + sel = 7; + } else if((mask & 256) != 0) { + // up to F + sel = 8; + } + } + assert_geq(sel, 0); + // Get character from read + int qc = prob_.qry_[rowc], qq = prob_.qual_[rowc]; + // Get character from reference + int rc = prob_.ref_[colc]; + assert_range(0, 16, rc); + bool xexit = false, yexit = false; + // Now that we know what type of move to make, make it, updating our + // row and column and moving updating the branch. + if(sel == 0) { + assert_geq(rowc, 0); + assert_geq(colc, 0); + TAlScore scd = prob_.sc_->score(qc, rc, qq - 33); + if((rc & (1 << qc)) == 0) { + // Mismatch + size_t id = curid; + // Check if the previous branch was the initial (bottommost) + // branch with no matches. If so, the mismatch should be added + // to the initial branch, instead of starting a new branch. + bool empty = (bs_[curid].len_ == 0 && curid == 0); + if(!empty) { + id = bs_.alloc(); + } + Edit e((int)rowc, mask2dna[rc], "ACGTN"[qc], EDIT_TYPE_MM); + assert_lt(scd, 0); + TAlScore score_en = bs_[curid].score_st_ + scd; + bs_[id].init( + prob_, + curid, // parent ID + -scd, // penalty + score_en, // score_en + rowc, // row + colc, // col + e, // edit + hefc, // hef + empty, // root? + false); // don't try to extend with exact matches + curid = id; + //assert(!local || bs_[curid].score_st_ >= 0); + } else { + // Match + bs_[curid].score_st_ += prob_.sc_->match(); + bs_[curid].len_++; + assert_leq((int64_t)bs_[curid].len_, bs_[curid].row_ + 1); + } + if(xmod == 0) xexit = true; + if(ymod == 0) yexit = true; + rowc--; ymod--; ymodTimesNcol -= sq_ncol; + colc--; xmod--; + assert(local || bs_[curid].score_st_ >= targ_final); + hefc = 0; + } else if((sel >= 1 && sel <= 2) || (sel >= 5 && sel <= 6)) { + assert_gt(colc, 0); + // Read gap + size_t id = bs_.alloc(); + Edit e((int)rowc+1, mask2dna[rc], '-', EDIT_TYPE_READ_GAP); + TAlScore gapp = prob_.sc_->readGapOpen(); + if(bs_[curid].len_ == 0 && bs_[curid].e_.inited() && bs_[curid].e_.isReadGap()) { + gapp = prob_.sc_->readGapExtend(); + } + //assert(!local || bs_[curid].score_st_ >= gapp); + TAlScore score_en = bs_[curid].score_st_ - gapp; + bs_[id].init( + prob_, + curid, // parent ID + gapp, // penalty + score_en, // score_en + rowc, // row + colc-1, // col + e, // edit + hefc, // hef + false, // root? + false); // don't try to extend with exact matches + if(xmod == 0) xexit = true; + colc--; xmod--; + curid = id; + assert( local || bs_[curid].score_st_ >= targ_final); + //assert(!local || bs_[curid].score_st_ >= 0); + if(sel == 1 || sel == 5) { + hefc = 0; + } else { + hefc = 1; + } + } else { + assert_gt(rowc, 0); + // Reference gap + size_t id = bs_.alloc(); + Edit e((int)rowc, '-', "ACGTN"[qc], EDIT_TYPE_REF_GAP); + TAlScore gapp = prob_.sc_->refGapOpen(); + if(bs_[curid].len_ == 0 && bs_[curid].e_.inited() && bs_[curid].e_.isRefGap()) { + gapp = prob_.sc_->refGapExtend(); + } + //assert(!local || bs_[curid].score_st_ >= gapp); + TAlScore score_en = bs_[curid].score_st_ - gapp; + bs_[id].init( + prob_, + curid, // parent ID + gapp, // penalty + score_en, // score_en + rowc-1, // row + colc, // col + e, // edit + hefc, // hef + false, // root? + false); // don't try to extend with exact matches + if(ymod == 0) yexit = true; + rowc--; ymod--; ymodTimesNcol -= sq_ncol; + curid = id; + assert( local || bs_[curid].score_st_ >= targ_final); + //assert(!local || bs_[curid].score_st_ >= 0); + if(sel == 3 || sel == 7) { + hefc = 0; + } else { + hefc = 2; + } + } + CHECK_ROW_COL(rowc, colc); + CpQuad * cur_new = NULL; + if(!xexit && !yexit) { + cur_new = sq_.ptr() + ymodTimesNcol + xmod; + } + // Check whether we made it to the top row or to a cell with score 0 + if(colc < 0 || rowc < 0 || + (cur_new != NULL && local && cur_new->sc[0] == 0)) + { + done = true; + assert(bs_[curid].isSolution(prob_)); + addSolution(curid); +#ifndef NDEBUG + // A check to see if any two adjacent branches in the backtrace + // overlap. If they do, the whole alignment will be filtered out + // in trySolution(...) + size_t cur = curid; + if(!bs_[cur].root_) { + size_t next = bs_[cur].parentId_; + while(!bs_[next].root_) { + assert_neq(cur, next); + if(bs_[next].len_ != 0 || bs_[cur].len_ == 0) { + assert(!bs_[cur].overlap(prob_, bs_[next])); + } + cur = next; + next = bs_[cur].parentId_; + } + } +#endif + return; + } + assert(!xexit || hefc == 0 || hefc == 1); + assert(!yexit || hefc == 0 || hefc == 2); + if(xexit || yexit) { + //assert(rowc < 0 || colc < 0 || prob_.cper_->isCheckpointed(rowc, colc)); + row_new = rowc; col_new = colc; + hef_new = hefc; + done = false; + if(rowc < 0 || colc < 0) { + assert(local); + targ_new = 0; + } else { + // TODO: Don't use scoreSquare + targ_new = prob_.cper_->scoreSquare(rowc, colc, hefc); + assert(local || targ_new >= targ); + assert(local || targ_new >= targ_final); + } + if(local && targ_new == 0) { + assert_eq(0, hefc); + done = true; + assert(bs_[curid].isSolution(prob_)); + addSolution(curid); + } + assert((row_new >= 0 && col_new >= 0) || done); + return; + } + } + assert(false); +} + +/** + * Caller gives us score_en, row and col. We figure out score_st and len_ + * by comparing characters from the strings. + * + * If this branch comes after a mismatch, (row, col) describe the cell that the + * mismatch occurs in. len_ is initially set to 1, and the next cell we test + * is the next cell up and to the left (row-1, col-1). + * + * If this branch comes after a read gap, (row, col) describe the leftmost cell + * involved in the gap. len_ is initially set to 0, and the next cell we test + * is the current cell (row, col). + * + * If this branch comes after a reference gap, (row, col) describe the upper + * cell involved in the gap. len_ is initially set to 0, and the next cell we + * test is the current cell (row, col). + */ +void BtBranch::init( + const BtBranchProblem& prob, + size_t parentId, + TAlScore penalty, + TAlScore score_en, + int64_t row, + int64_t col, + Edit e, + int hef, + bool root, + bool extend) +{ + score_en_ = score_en; + penalty_ = penalty; + score_st_ = score_en_; + row_ = row; + col_ = col; + parentId_ = parentId; + e_ = e; + root_ = root; + assert(!root_ || parentId == 0); + assert_lt(row, (int64_t)prob.qrylen_); + assert_lt(col, (int64_t)prob.reflen_); + // First match to check is diagonally above and to the left of the cell + // where the edit occurs + int64_t rowc = row; + int64_t colc = col; + len_ = 0; + if(e.inited() && e.isMismatch()) { + rowc--; colc--; + len_ = 1; + } + int64_t match = prob.sc_->match(); + bool cp = prob.usecp_; + size_t iters = 0; + curtailed_ = false; + if(extend) { + while(rowc >= 0 && colc >= 0) { + int rfm = prob.ref_[colc]; + assert_range(0, 16, rfm); + int rdc = prob.qry_[rowc]; + bool matches = (rfm & (1 << rdc)) != 0; + if(!matches) { + // What's the mismatch penalty? + break; + } + // Get score from checkpointer + score_st_ += match; + if(cp && rowc - 1 >= 0 && colc - 1 >= 0 && + prob.cper_->isCheckpointed(rowc - 1, colc - 1)) + { + // Possibly prune + int16_t cpsc; + cpsc = prob.cper_->scoreTriangle(rowc - 1, colc - 1, hef); + if(cpsc + score_st_ < prob.targ_) { + curtailed_ = true; + break; + } + } + iters++; + rowc--; colc--; + } + } + assert_geq(rowc, -1); + assert_geq(colc, -1); + len_ = (int64_t)row - rowc; + assert_leq((int64_t)len_, row_+1); + assert_leq((int64_t)len_, col_+1); + assert_leq((int64_t)score_st_, (int64_t)prob.qrylen_ * match); +} + +/** + * Given a potential branch to add to the queue, see if we can follow the + * branch a little further first. If it's still valid, or if we reach a + * choice between valid outgoing paths, go ahead and add it to the queue. + */ +void BtBranchTracer::examineBranch( + int64_t row, + int64_t col, + const Edit& e, + TAlScore pen, // penalty associated with edit + TAlScore sc, + size_t parentId) +{ + size_t id = bs_.alloc(); + bs_[id].init(prob_, parentId, pen, sc, row, col, e, 0, false, true); + if(bs_[id].isSolution(prob_)) { + assert(bs_[id].isValid(prob_)); + addSolution(id); + } else { + // Check if this branch is legit + if(bs_[id].isValid(prob_)) { + add(id); + } else { + bs_.pop(); + } + } +} + +/** + * Take all possible ways of leaving the given branch and add them to the + * branch queue. + */ +void BtBranchTracer::addOffshoots(size_t bid) { + BtBranch& b = bs_[bid]; + TAlScore sc = b.score_en_; + int64_t match = prob_.sc_->match(); + int64_t scoreFloor = prob_.sc_->monotone ? MIN_I64 : 0; + bool cp = prob_.usecp_; // Are there are any checkpoints? + ASSERT_ONLY(TAlScore perfectScore = prob_.sc_->perfectScore(prob_.qrylen_)); + assert_leq(prob_.targ_, perfectScore); + // For each cell in the branch + for(size_t i = 0 ; i < b.len_; i++) { + assert_leq((int64_t)i, b.row_+1); + assert_leq((int64_t)i, b.col_+1); + int64_t row = b.row_ - i, col = b.col_ - i; + int64_t bonusLeft = (row + 1) * match; + int64_t fromend = prob_.qrylen_ - row - 1; + bool allowGaps = fromend >= prob_.sc_->gapbar && row >= prob_.sc_->gapbar; + if(allowGaps && row >= 0 && col >= 0) { + if(col > 0) { + // Try a read gap - it's either an extension or an open + bool extend = b.e_.inited() && b.e_.isReadGap() && i == 0; + TAlScore rdgapPen = extend ? + prob_.sc_->readGapExtend() : prob_.sc_->readGapOpen(); + bool prune = false; + assert_gt(rdgapPen, 0); + if(cp && prob_.cper_->isCheckpointed(row, col - 1)) { + // Possibly prune + int16_t cpsc = (int16_t)prob_.cper_->scoreTriangle(row, col - 1, 0); + assert_leq(cpsc, perfectScore); + assert_geq(prob_.sc_->readGapOpen(), prob_.sc_->readGapExtend()); + TAlScore bonus = prob_.sc_->readGapOpen() - prob_.sc_->readGapExtend(); + assert_geq(bonus, 0); + if(cpsc + bonus + sc - rdgapPen < prob_.targ_) { + prune = true; + } + } + if(prune) { + if(extend) { nrdexPrune_++; } else { nrdopPrune_++; } + } else if(sc - rdgapPen >= scoreFloor && sc - rdgapPen + bonusLeft >= prob_.targ_) { + // Yes, we can introduce a read gap here + Edit e((int)row + 1, mask2dna[(int)prob_.ref_[col]], '-', EDIT_TYPE_READ_GAP); + assert(e.isReadGap()); + examineBranch(row, col - 1, e, rdgapPen, sc - rdgapPen, bid); + if(extend) { nrdex_++; } else { nrdop_++; } + } + } + if(row > 0) { + // Try a reference gap - it's either an extension or an open + bool extend = b.e_.inited() && b.e_.isRefGap() && i == 0; + TAlScore rfgapPen = (b.e_.inited() && b.e_.isRefGap()) ? + prob_.sc_->refGapExtend() : prob_.sc_->refGapOpen(); + bool prune = false; + assert_gt(rfgapPen, 0); + if(cp && prob_.cper_->isCheckpointed(row - 1, col)) { + // Possibly prune + int16_t cpsc = (int16_t)prob_.cper_->scoreTriangle(row - 1, col, 0); + assert_leq(cpsc, perfectScore); + assert_geq(prob_.sc_->refGapOpen(), prob_.sc_->refGapExtend()); + TAlScore bonus = prob_.sc_->refGapOpen() - prob_.sc_->refGapExtend(); + assert_geq(bonus, 0); + if(cpsc + bonus + sc - rfgapPen < prob_.targ_) { + prune = true; + } + } + if(prune) { + if(extend) { nrfexPrune_++; } else { nrfopPrune_++; } + } else if(sc - rfgapPen >= scoreFloor && sc - rfgapPen + bonusLeft >= prob_.targ_) { + // Yes, we can introduce a ref gap here + Edit e((int)row, '-', "ACGTN"[(int)prob_.qry_[row]], EDIT_TYPE_REF_GAP); + assert(e.isRefGap()); + examineBranch(row - 1, col, e, rfgapPen, sc - rfgapPen, bid); + if(extend) { nrfex_++; } else { nrfop_++; } + } + } + } + // If we're at the top of the branch but not yet at the top of + // the DP table, a mismatch branch is also possible. + if(i == b.len_ && !b.curtailed_ && row >= 0 && col >= 0) { + int rfm = prob_.ref_[col]; + assert_lt(row, (int64_t)prob_.qrylen_); + int rdc = prob_.qry_[row]; + int rdq = prob_.qual_[row]; + int scdiff = prob_.sc_->score(rdc, rfm, rdq - 33); + assert_lt(scdiff, 0); // at end of branch, so can't match + bool prune = false; + if(cp && row > 0 && col > 0 && prob_.cper_->isCheckpointed(row - 1, col - 1)) { + // Possibly prune + int16_t cpsc = prob_.cper_->scoreTriangle(row - 1, col - 1, 0); + assert_leq(cpsc, perfectScore); + assert_leq(cpsc + scdiff + sc, perfectScore); + if(cpsc + scdiff + sc < prob_.targ_) { + prune = true; + } + } + if(prune) { + nmm_++; + } else { + // Yes, we can introduce a mismatch here + if(sc + scdiff >= scoreFloor && sc + scdiff + bonusLeft >= prob_.targ_) { + Edit e((int)row, mask2dna[rfm], "ACGTN"[rdc], EDIT_TYPE_MM); + bool nmm = (mask2dna[rfm] == 'N' || rdc > 4); + assert_neq(e.chr, e.qchr); + assert_lt(scdiff, 0); + examineBranch(row - 1, col - 1, e, -scdiff, sc + scdiff, bid); + if(nmm) { nnmm_++; } else { nmm_++; } + } + } + } + sc += match; + } +} + +/** + * Sort unsorted branches, merge them with master sorted list. + */ +void BtBranchTracer::flushUnsorted() { + if(unsorted_.empty()) { + return; + } + unsorted_.sort(); + unsorted_.reverse(); +#ifndef NDEBUG + for(size_t i = 1; i < unsorted_.size(); i++) { + assert_leq(bs_[unsorted_[i].second].score_st_, bs_[unsorted_[i-1].second].score_st_); + } +#endif + EList *src2 = sortedSel_ ? &sorted1_ : &sorted2_; + EList *dest = sortedSel_ ? &sorted2_ : &sorted1_; + // Merge src1 and src2 into dest + dest->clear(); + size_t cur1 = 0, cur2 = cur_; + while(cur1 < unsorted_.size() || cur2 < src2->size()) { + // Take from 1 or 2 next? + bool take1 = true; + if(cur1 == unsorted_.size()) { + take1 = false; + } else if(cur2 == src2->size()) { + take1 = true; + } else { + assert_neq(unsorted_[cur1].second, (*src2)[cur2]); + take1 = bs_[unsorted_[cur1].second] < bs_[(*src2)[cur2]]; + } + if(take1) { + dest->push_back(unsorted_[cur1++].second); // Take from list 1 + } else { + dest->push_back((*src2)[cur2++]); // Take from list 2 + } + } + assert_eq(cur1, unsorted_.size()); + assert_eq(cur2, src2->size()); + sortedSel_ = !sortedSel_; + cur_ = 0; + unsorted_.clear(); +} + +/** + * Try all the solutions accumulated so far. Solutions might be rejected + * if they, for instance, overlap a previous solution, have too many Ns, + * fail to overlap a core diagonal, etc. + */ +bool BtBranchTracer::trySolutions( + bool lookForOlap, + SwResult& res, + size_t& off, + size_t& nrej, + RandomSource& rnd, + bool& success) +{ + if(solutions_.size() > 0) { + for(size_t i = 0; i < solutions_.size(); i++) { + int ret = trySolution(solutions_[i], lookForOlap, res, off, nrej, rnd); + if(ret == BT_FOUND) { + success = true; + return true; // there were solutions and one was good + } + } + solutions_.clear(); + success = false; + return true; // there were solutions but none were good + } + return false; // there were no solutions to check +} + +/** + * Given the id of a branch that completes a successful backtrace, turn the + * chain of branches into + */ +int BtBranchTracer::trySolution( + size_t id, + bool lookForOlap, + SwResult& res, + size_t& off, + size_t& nrej, + RandomSource& rnd) +{ + AlnScore score; + BtBranch *br = &bs_[id]; + // 'br' corresponds to the leftmost edit in a right-to-left + // chain of edits. + EList& ned = res.alres.ned(); + const BtBranch *cur = br, *prev = NULL; + size_t ns = 0, nrefns = 0; + size_t ngap = 0; + while(true) { + if(cur->e_.inited()) { + if(cur->e_.isMismatch()) { + if(cur->e_.qchr == 'N' || cur->e_.chr == 'N') { + ns++; + } + } else if(cur->e_.isGap()) { + ngap++; + } + if(cur->e_.chr == 'N') { + nrefns++; + } + ned.push_back(cur->e_); + } + if(cur->root_) { + break; + } + cur = &bs_[cur->parentId_]; + } + if(ns > prob_.nceil_) { + // Alignment has too many Ns in it! + res.reset(); + assert(res.alres.ned().empty()); + nrej++; + return BT_REJECTED_N; + } + // Update 'seenPaths_' + cur = br; + bool rejSeen = false; // set =true if we overlap prev path + bool rejCore = true; // set =true if we don't touch core diag + while(true) { + // Consider row, col, len, then do something + int64_t row = cur->row_, col = cur->col_; + assert_lt(row, (int64_t)prob_.qrylen_); + size_t fromend = prob_.qrylen_ - row - 1; + size_t diag = fromend + col; + // Calculate the diagonal within the *trimmed* rectangle, + // i.e. the rectangle we dealt with in align, gather and + // backtrack. + int64_t diagi = col - row; + // Now adjust to the diagonal within the *untrimmed* + // rectangle by adding on the amount trimmed from the left. + diagi += prob_.rect_->triml; + assert_lt(diag, seenPaths_.size()); + // Does it overlap a core diagonal? + if(diagi >= 0) { + size_t diag = (size_t)diagi; + if(diag >= prob_.rect_->corel && + diag <= prob_.rect_->corer) + { + // Yes it does - it's OK + rejCore = false; + } + } + if(lookForOlap) { + int64_t newlo, newhi; + if(cur->len_ == 0) { + if(prev != NULL && prev->len_ > 0) { + // If there's a gap at the base of a non-0 length branch, the + // gap will appear to overlap the branch if we give it length 1. + newhi = newlo = 0; + } else { + // Read or ref gap with no matches coming off of it + newlo = row; + newhi = row + 1; + } + } else { + // Diagonal with matches + newlo = row - (cur->len_ - 1); + newhi = row + 1; + } + assert_geq(newlo, 0); + assert_geq(newhi, 0); + // Does the diagonal cover cells? + if(newhi > newlo) { + // Check whether there is any overlap with previously traversed + // cells + bool added = false; + const size_t sz = seenPaths_[diag].size(); + for(size_t i = 0; i < sz; i++) { + // Does the new interval overlap this already-seen + // interval? Also of interest: does it abut this + // already-seen interval? If so, we should merge them. + size_t lo = seenPaths_[diag][i].first; + size_t hi = seenPaths_[diag][i].second; + assert_lt(lo, hi); + size_t lo_sm = newlo, hi_sm = newhi; + if(hi - lo < hi_sm - lo_sm) { + swap(lo, lo_sm); + swap(hi, hi_sm); + } + if((lo <= lo_sm && hi > lo_sm) || + (lo < hi_sm && hi >= hi_sm)) + { + // One or both of the shorter interval's end points + // are contained in the longer interval - so they + // overlap. + rejSeen = true; + // Merge them into one longer interval + seenPaths_[diag][i].first = min(lo, lo_sm); + seenPaths_[diag][i].second = max(hi, hi_sm); +#ifndef NDEBUG + for(int64_t ii = seenPaths_[diag][i].first; + ii < (int64_t)seenPaths_[diag][i].second; + ii++) + { + //cerr << "trySolution rejected (" << ii << ", " << (ii + col - row) << ")" << endl; + } +#endif + added = true; + break; + } else if(hi == lo_sm || lo == hi_sm) { + // Merge them into one longer interval + seenPaths_[diag][i].first = min(lo, lo_sm); + seenPaths_[diag][i].second = max(hi, hi_sm); +#ifndef NDEBUG + for(int64_t ii = seenPaths_[diag][i].first; + ii < (int64_t)seenPaths_[diag][i].second; + ii++) + { + //cerr << "trySolution rejected (" << ii << ", " << (ii + col - row) << ")" << endl; + } +#endif + added = true; + // Keep going in case it overlaps one of the other + // intervals + } + } + if(!added) { + seenPaths_[diag].push_back(make_pair(newlo, newhi)); + } + } + } + // After the merging that may have occurred above, it's no + // longer guarnateed that all the overlapping intervals in + // the list have been merged. That's OK though. We'll + // still get correct answers to overlap queries. + if(cur->root_) { + assert_eq(0, cur->parentId_); + break; + } + prev = cur; + cur = &bs_[cur->parentId_]; + } // while(cur->e_.inited()) + if(rejSeen) { + res.reset(); + assert(res.alres.ned().empty()); + nrej++; + return BT_NOT_FOUND; + } + if(rejCore) { + res.reset(); + assert(res.alres.ned().empty()); + nrej++; + return BT_REJECTED_CORE_DIAG; + } + off = br->leftmostCol(); + score.score_ = prob_.targ_; + score.ns_ = ns; + score.gaps_ = ngap; + res.alres.setScore(score); + res.alres.setRefNs(nrefns); + size_t trimBeg = br->uppermostRow(); + size_t trimEnd = prob_.qrylen_ - prob_.row_ - 1; + assert_leq(trimBeg, prob_.qrylen_); + assert_leq(trimEnd, prob_.qrylen_); + TRefOff refoff = off + prob_.refoff_ + prob_.rect_->refl; + res.alres.setShape( + prob_.refid_, // ref id + refoff, // 0-based ref offset + prob_.treflen(), // ref length + prob_.fw_, // aligned to Watson? + prob_.qrylen_, // read length + 0, // read id + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + prob_.fw_ ? trimBeg : trimEnd, // alignment trim 5' end + prob_.fw_ ? trimEnd : trimBeg); // alignment trim 3' end + return BT_FOUND; +} + +/** + * Get the next valid alignment given a backtrace problem. Return false + * if there is no valid solution. Use a backtracking search to find the + * solution. This can be very slow. + */ +bool BtBranchTracer::nextAlignmentBacktrace( + size_t maxiter, + SwResult& res, + size_t& off, + size_t& nrej, + size_t& niter, + RandomSource& rnd) +{ + assert(!empty() || !emptySolution()); + assert(prob_.inited()); + // There's a subtle case where we might fail to backtracing in + // local-alignment mode. The basic fact to remember is that when we're + // backtracing from the highest-scoring cell in the table, we're guaranteed + // to be able to backtrace without ever dipping below 0. But if we're + // backtracing from a cell other than the highest-scoring cell in the + // table, we might dip below 0. Dipping below 0 implies that there's a + // shorted local alignment with a better score. In which case, it's + // perfectly fair for us to abandon any path that dips below the floor, and + // this might result in the queue becoming empty before we finish. + bool result = false; + niter = 0; + while(!empty()) { + if(trySolutions(true, res, off, nrej, rnd, result)) { + return result; + } + if(niter++ >= maxiter) { + break; + } + size_t brid = best(rnd); // put best branch in 'br' + assert(!seen_.contains(brid)); + ASSERT_ONLY(seen_.insert(brid)); +#if 0 + BtBranch *br = &bs_[brid]; + cerr << brid + << ": targ:" << prob_.targ_ + << ", sc:" << br->score_st_ + << ", row:" << br->uppermostRow() + << ", nmm:" << nmm_ + << ", nnmm:" << nnmm_ + << ", nrdop:" << nrdop_ + << ", nrfop:" << nrfop_ + << ", nrdex:" << nrdex_ + << ", nrfex:" << nrfex_ + << ", nrdop_pr: " << nrdopPrune_ + << ", nrfop_pr: " << nrfopPrune_ + << ", nrdex_pr: " << nrdexPrune_ + << ", nrfex_pr: " << nrfexPrune_ + << endl; +#endif + addOffshoots(brid); + } + if(trySolutions(true, res, off, nrej, rnd, result)) { + return result; + } + return false; +} + +/** + * Get the next valid alignment given a backtrace problem. Return false + * if there is no valid solution. Use a triangle-fill backtrace to find + * the solution. This is usually fast (it's O(m + n)). + */ +bool BtBranchTracer::nextAlignmentFill( + size_t maxiter, + SwResult& res, + size_t& off, + size_t& nrej, + size_t& niter, + RandomSource& rnd) +{ + assert(prob_.inited()); + assert(!emptySolution()); + bool result = false; + if(trySolutions(false, res, off, nrej, rnd, result)) { + return result; + } + return false; +} + +/** + * Get the next valid alignment given the backtrace problem. Return false + * if there is no valid solution, e.g., if + */ +bool BtBranchTracer::nextAlignment( + size_t maxiter, + SwResult& res, + size_t& off, + size_t& nrej, + size_t& niter, + RandomSource& rnd) +{ + if(prob_.fill_) { + return nextAlignmentFill( + maxiter, + res, + off, + nrej, + niter, + rnd); + } else { + return nextAlignmentBacktrace( + maxiter, + res, + off, + nrej, + niter, + rnd); + } +} + +#ifdef MAIN_ALIGNER_BT + +#include + +int main(int argc, char **argv) { + size_t off = 0; + RandomSource rnd(77); + BtBranchTracer tr; + Scoring sc = Scoring::base1(); + SwResult res; + tr.init( + "ACGTACGT", // in: read sequence + "IIIIIIII", // in: quality sequence + 8, // in: read sequence length + "ACGTACGT", // in: reference sequence + 8, // in: reference sequence length + 0, // in: reference id + 0, // in: reference offset + true, // in: orientation + sc, // in: scoring scheme + 0, // in: N ceiling + 8, // in: alignment score + 7, // start in this row + 7, // start in this column + rnd); // random gen, to choose among equal paths + size_t nrej = 0; + tr.nextAlignment( + res, + off, + nrej, + rnd); +} + +#endif /*def MAIN_ALIGNER_BT*/ diff --git a/aligner_bt.h b/aligner_bt.h new file mode 100644 index 0000000..8056b7a --- /dev/null +++ b/aligner_bt.h @@ -0,0 +1,947 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_BT_H_ +#define ALIGNER_BT_H_ + +#include +#include +#include "aligner_sw_common.h" +#include "aligner_result.h" +#include "scoring.h" +#include "edit.h" +#include "limit.h" +#include "dp_framer.h" +#include "sse_util.h" + +/* Say we've filled in a DP matrix in a cost-only manner, not saving the scores + * for each of the cells. At the end, we obtain a list of candidate cells and + * we'd like to backtrace from them. The per-cell scores are gone, but we have + * to re-create the correct path somehow. Hopefully we can do this without + * recreating most or al of the score matrix, since this takes too much memory. + * + * Approach 1: Naively refill the matrix. + * + * Just refill the matrix, perhaps backwards starting from the backtrace cell. + * Since this involves recreating all or most of the score matrix, this is not + * a good approach. + * + * Approach 2: Naive backtracking. + * + * Conduct a search through the space of possible backtraces, rooted at the + * candidate cell. To speed things along, we can prioritize paths that have a + * high score and that align more characters from the read. + * + * The approach is simple, but it's neither fast nor memory-efficient in + * general. + * + * Approach 3: Refilling with checkpoints. + * + * Refill the matrix "backwards" starting from the candidate cell, but use + * checkpoints to ensure that only a series of relatively small triangles or + * rectangles need to be refilled. The checkpoints must include elements from + * the H, E and F matrices; not just H. After each refill, we backtrace + * through the refilled area, then discard/reuse the fill memory. I call each + * such fill/backtrace a mini-fill/backtrace. + * + * If there's only one path to be found, then this is O(m+n). But what if + * there are many? And what if we would like to avoid paths that overlap in + * one or more cells? There are two ways we can make this more efficient: + * + * 1. Remember the re-calculated E/F/H values and try to retrieve them + * 2. Keep a record of cells that have already been traversed + * + * Legend: + * + * 1: Candidate cell + * 2: Final cell from first mini-fill/backtrace + * 3: Final cell from second mini-fill/backtrace (third not shown) + * +: Checkpointed cell + * *: Cell filled from first or second mini-fill/backtrace + * -: Unfilled cell + * + * ---++--------++--------++---- + * --++--------++*-------++----- + * -++--(etc)-++**------++------ + * ++--------+3***-----++------- + * +--------++****----++-------- + * --------++*****---++--------+ + * -------++******--++--------++ + * ------++*******-++*-------++- + * -----++********++**------++-- + * ----++********2+***-----++--- + * ---++--------++****----++---- + * --++--------++*****---++----- + * -++--------++*****1--++------ + * ++--------++--------++------- + * + * Approach 4: Backtracking with checkpoints. + * + * Conduct a search through the space of possible backtraces, rooted at the + * candidate cell. Use "checkpoints" to prune. That is, when a backtrace + * moves through a cell with a checkpointed score, consider the score + * accumulated so far and the cell's saved score; abort if those two scores + * add to something less than a valid score. Note we're only checkpointing H + * in this case (possibly; see "subtle point"), not E or F. + * + * Subtle point: checkpoint scores are a result of moving forward through + * the matrix whereas backtracking scores result from moving backward. This + * matters becuase the two paths that meet up at a cell might have both + * factored in a gap open penalty for the same gap, in which case we will + * underestimate the overall score and prune a good path. Here are two ideas + * for how to resolve this: + * + * Idea 1: when we combine the forward and backward scores to find an overall + * score, and our backtrack procedure *just* made a horizontal or vertical + * move, add in a "bonus" equal to the gap open penalty of the appropraite + * type (read gap open for horizontal, ref gap open for vertical). This might + * overcompensate, since + * + * Idea 2: keep the E and F values for the checkpoints around, in addition to + * the H values. When it comes time to combine the score from the forward + * and backward paths, we consider the last move we made in the backward + * backtrace. If it's a read gap (horizontal move), then we calculate the + * overall score as: + * + * max(Score-backward + H-forward, Score-backward + E-forward + read-open) + * + * If it's a reference gap (vertical move), then we calculate the overall + * score as: + * + * max(Score-backward + H-forward, Score-backward + F-forward + ref-open) + * + * What does it mean to abort a backtrack? If we're starting a new branch + * and there is a checkpoing in the bottommost cell of the branch, and the + * overall score is less than the target, then we can simply ignore the + * branch. If the checkpoint occurs in the middle of a string of matches, we + * need to curtail the branch such that it doesn't include the checkpointed + * cell and we won't ever try to enter the checkpointed cell, e.g., on a + * mismatch. + * + * Approaches 3 and 4 seem reasonable, and could be combined. For simplicity, + * we implement only approach 4 for now. + * + * Checkpoint information is propagated from the fill process to the backtracer + * via a + */ + +enum { + BT_NOT_FOUND = 1, // could not obtain the backtrace because it + // overlapped a previous solution + BT_FOUND, // obtained a valid backtrace + BT_REJECTED_N, // backtrace rejected because it had too many Ns + BT_REJECTED_CORE_DIAG // backtrace rejected because it failed to overlap a + // core diagonal +}; + +/** + * Parameters for a matrix of potential backtrace problems to solve. + * Encapsulates information about: + * + * The problem given a particular reference substring: + * + * - The query string (nucleotides and qualities) + * - The reference substring (incl. orientation, offset into overall sequence) + * - Checkpoints (i.e. values of matrix cells) + * - Scoring scheme and other thresholds + * + * The problem given a particular reference substring AND a particular row and + * column from which to backtrace: + * + * - The row and column + * - The target score + */ +class BtBranchProblem { + +public: + + /** + * Create new uninitialized problem. + */ + BtBranchProblem() { reset(); } + + /** + * Initialize a new problem. + */ + void initRef( + const char *qry, // query string (along rows) + const char *qual, // query quality string (along rows) + size_t qrylen, // query string (along rows) length + const char *ref, // reference string (along columns) + TRefOff reflen, // in-rectangle reference string length + TRefOff treflen,// total reference string length + TRefId refid, // reference id + TRefOff refoff, // reference offset + bool fw, // orientation of problem + const DPRect* rect, // dynamic programming rectangle filled out + const Checkpointer* cper, // checkpointer + const Scoring *sc, // scoring scheme + size_t nceil) // max # Ns allowed in alignment + { + qry_ = qry; + qual_ = qual; + qrylen_ = qrylen; + ref_ = ref; + reflen_ = reflen; + treflen_ = treflen; + refid_ = refid; + refoff_ = refoff; + fw_ = fw; + rect_ = rect; + cper_ = cper; + sc_ = sc; + nceil_ = nceil; + } + + /** + * Initialize a new problem. + */ + void initBt( + size_t row, // row + size_t col, // column + bool fill, // use a filling rather than a backtracking strategy + bool usecp, // use checkpoints to short-circuit while backtracking + TAlScore targ) // target score + { + row_ = row; + col_ = col; + targ_ = targ; + fill_ = fill; + usecp_ = usecp; + if(fill) { + assert(usecp_); + } + } + + /** + * Reset to uninitialized state. + */ + void reset() { + qry_ = qual_ = ref_ = NULL; + cper_ = NULL; + rect_ = NULL; + sc_ = NULL; + qrylen_ = reflen_ = treflen_ = refid_ = refoff_ = row_ = col_ = targ_ = nceil_ = 0; + fill_ = fw_ = usecp_ = false; + } + + /** + * Return true iff the BtBranchProblem has been initialized. + */ + bool inited() const { + return qry_ != NULL; + } + +#ifndef NDEBUG + /** + * Sanity-check the problem. + */ + bool repOk() const { + assert_gt(qrylen_, 0); + assert_gt(reflen_, 0); + assert_gt(treflen_, 0); + assert_lt(row_, qrylen_); + assert_lt((TRefOff)col_, reflen_); + return true; + } +#endif + + size_t reflen() const { return reflen_; } + size_t treflen() const { return treflen_; } + +protected: + + const char *qry_; // query string (along rows) + const char *qual_; // query quality string (along rows) + size_t qrylen_; // query string (along rows) length + const char *ref_; // reference string (along columns) + TRefOff reflen_; // in-rectangle reference string length + TRefOff treflen_;// total reference string length + TRefId refid_; // reference id + TRefOff refoff_; // reference offset + bool fw_; // orientation of problem + const DPRect* rect_; // dynamic programming rectangle filled out + size_t row_; // starting row + size_t col_; // starting column + TAlScore targ_; // target score + const Checkpointer *cper_; // checkpointer + bool fill_; // use mini-fills + bool usecp_; // use checkpointing? + const Scoring *sc_; // scoring scheme + size_t nceil_; // max # Ns allowed in alignment + + friend class BtBranch; + friend class BtBranchQ; + friend class BtBranchTracer; +}; + +/** + * Encapsulates a "branch" which is a diagonal of cells (possibly of length 0) + * in the matrix where all the cells are matches. These stretches are linked + * together by edits to form a full backtrace path through the matrix. Lengths + * are measured w/r/t to the number of rows traversed by the path, so a branch + * that represents a read gap extension could have length = 0. + * + * At the end of the day, the full backtrace path is represented as a list of + * BtBranch's where each BtBranch represents a stretch of matching cells (and + * up to one mismatching cell at its bottom extreme) ending in an edit (or in + * the bottommost row, in which case the edit is uninitialized). Each + * BtBranch's row and col fields indicate the bottommost cell involved in the + * diagonal stretch of matches, and the len_ field indicates the length of the + * stretch of matches. Note that the edits themselves also correspond to + * movement through the matrix. + * + * A related issue is how we record which cells have been visited so that we + * never report a pair of paths both traversing the same (row, col) of the + * overall DP matrix. This gets a little tricky because we have to take into + * account the cells covered by *edits* in addition to the cells covered by the + * stretches of matches. For instance: imagine a mismatch. That takes up a + * cell of the DP matrix, but it may or may not be preceded by a string of + * matches. It's hard to imagine how to represent this unless we let the + * mismatch "count toward" the len_ of the branch and let (row, col) refer to + * the cell where the mismatch occurs. + * + * We need BtBranches to "live forever" so that we can make some BtBranches + * parents of others using parent pointers. For this reason, BtBranch's are + * stored in an EFactory object in the BtBranchTracer class. + */ +class BtBranch { + +public: + + BtBranch() { reset(); } + + BtBranch( + const BtBranchProblem& prob, + size_t parentId, + TAlScore penalty, + TAlScore score_en, + int64_t row, + int64_t col, + Edit e, + int hef, + bool root, + bool extend) + { + init(prob, parentId, penalty, score_en, row, col, e, hef, root, extend); + } + + /** + * Reset to uninitialized state. + */ + void reset() { + parentId_ = 0; + score_st_ = score_en_ = len_ = row_ = col_ = 0; + curtailed_ = false; + e_.reset(); + } + + /** + * Caller gives us score_en, row and col. We figure out score_st and len_ + * by comparing characters from the strings. + */ + void init( + const BtBranchProblem& prob, + size_t parentId, + TAlScore penalty, + TAlScore score_en, + int64_t row, + int64_t col, + Edit e, + int hef, + bool root, + bool extend); + + /** + * Return true iff this branch ends in a solution to the backtrace problem. + */ + bool isSolution(const BtBranchProblem& prob) const { + const bool end2end = prob.sc_->monotone; + return score_st_ == prob.targ_ && (!end2end || endsInFirstRow()); + } + + /** + * Return true iff this branch could potentially lead to a valid alignment. + */ + bool isValid(const BtBranchProblem& prob) const { + int64_t scoreFloor = prob.sc_->monotone ? MIN_I64 : 0; + if(score_st_ < scoreFloor) { + // Dipped below the score floor + return false; + } + if(isSolution(prob)) { + // It's a solution, so it's also valid + return true; + } + if((int64_t)len_ > row_) { + // Went all the way to the top row + //assert_leq(score_st_, prob.targ_); + return score_st_ == prob.targ_; + } else { + int64_t match = prob.sc_->match(); + int64_t bonusLeft = (row_ + 1 - len_) * match; + return score_st_ + bonusLeft >= prob.targ_; + } + } + + /** + * Return true iff this branch overlaps with the given branch. + */ + bool overlap(const BtBranchProblem& prob, const BtBranch& bt) const { + // Calculate this branch's diagonal + assert_lt(row_, (int64_t)prob.qrylen_); + size_t fromend = prob.qrylen_ - row_ - 1; + size_t diag = fromend + col_; + int64_t lo = 0, hi = row_ + 1; + if(len_ == 0) { + lo = row_; + } else { + lo = row_ - (len_ - 1); + } + // Calculate other branch's diagonal + assert_lt(bt.row_, (int64_t)prob.qrylen_); + size_t ofromend = prob.qrylen_ - bt.row_ - 1; + size_t odiag = ofromend + bt.col_; + if(diag != odiag) { + return false; + } + int64_t olo = 0, ohi = bt.row_ + 1; + if(bt.len_ == 0) { + olo = bt.row_; + } else { + olo = bt.row_ - (bt.len_ - 1); + } + int64_t losm = olo, hism = ohi; + if(hi - lo < ohi - olo) { + swap(lo, losm); + swap(hi, hism); + } + if((lo <= losm && hi > losm) || (lo < hism && hi >= hism)) { + return true; + } + return false; + } + + /** + * Return true iff this branch is higher priority than the branch 'o'. + */ + bool operator<(const BtBranch& o) const { + // Prioritize uppermost above score + if(uppermostRow() != o.uppermostRow()) { + return uppermostRow() < o.uppermostRow(); + } + if(score_st_ != o.score_st_) return score_st_ > o.score_st_; + if(row_ != o.row_) return row_ < o.row_; + if(col_ != o.col_) return col_ > o.col_; + if(parentId_ != o.parentId_) return parentId_ > o.parentId_; + assert(false); + return false; + } + + /** + * Return true iff the topmost cell involved in this branch is in the top + * row. + */ + bool endsInFirstRow() const { + assert_leq((int64_t)len_, row_ + 1); + return (int64_t)len_ == row_+1; + } + + /** + * Return the uppermost row covered by this branch. + */ + size_t uppermostRow() const { + assert_geq(row_ + 1, (int64_t)len_); + return row_ + 1 - (int64_t)len_; + } + + /** + * Return the leftmost column covered by this branch. + */ + size_t leftmostCol() const { + assert_geq(col_ + 1, (int64_t)len_); + return col_ + 1 - (int64_t)len_; + } + +#ifndef NDEBUG + /** + * Sanity-check this BtBranch. + */ + bool repOk() const { + assert(root_ || e_.inited()); + assert_gt(len_, 0); + assert_geq(col_ + 1, (int64_t)len_); + assert_geq(row_ + 1, (int64_t)len_); + return true; + } +#endif + +protected: + + // ID of the parent branch. + size_t parentId_; + + // Penalty associated with the edit at the bottom of this branch (0 if + // there is no edit) + TAlScore penalty_; + + // Score at the beginning of the branch + TAlScore score_st_; + + // Score at the end of the branch (taking the edit into account) + TAlScore score_en_; + + // Length of the branch. That is, the total number of diagonal cells + // involved in all the matches and in the edit (if any). Should always be + // > 0. + size_t len_; + + // The row of the final (bottommost) cell in the branch. This might be the + // bottommost match if the branch has no associated edit. Otherwise, it's + // the cell occupied by the edit. + int64_t row_; + + // The column of the final (bottommost) cell in the branch. + int64_t col_; + + // The edit at the bottom of the branch. If this is the bottommost branch + // in the alignment and it does not end in an edit, then this remains + // uninitialized. + Edit e_; + + // True iff this is the bottommost branch in the alignment. We can't just + // use row_ to tell us this because local alignments don't necessarily end + // in the last row. + bool root_; + + bool curtailed_; // true -> pruned at a checkpoint where we otherwise + // would have had a match + +friend class BtBranchQ; +friend class BtBranchTracer; + +}; + +/** + * Instantiate and solve best-first branch-based backtraces. + */ +class BtBranchTracer { + +public: + + explicit BtBranchTracer() : + prob_(), bs_(), seenPaths_(DP_CAT), sawcell_(DP_CAT), doTri_() { } + + /** + * Add a branch to the queue. + */ + void add(size_t id) { + assert(!bs_[id].isSolution(prob_)); + unsorted_.push_back(make_pair(bs_[id].score_st_, id)); + } + + /** + * Add a branch to the list of solutions. + */ + void addSolution(size_t id) { + assert(bs_[id].isSolution(prob_)); + solutions_.push_back(id); + } + + /** + * Given a potential branch to add to the queue, see if we can follow the + * branch a little further first. If it's still valid, or if we reach a + * choice between valid outgoing paths, go ahead and add it to the queue. + */ + void examineBranch( + int64_t row, + int64_t col, + const Edit& e, + TAlScore pen, + TAlScore sc, + size_t parentId); + + /** + * Take all possible ways of leaving the given branch and add them to the + * branch queue. + */ + void addOffshoots(size_t bid); + + /** + * Get the best branch and remove it from the priority queue. + */ + size_t best(RandomSource& rnd) { + assert(!empty()); + flushUnsorted(); + assert_gt(sortedSel_ ? sorted1_.size() : sorted2_.size(), cur_); + // Perhaps shuffle everyone who's tied for first? + size_t id = sortedSel_ ? sorted1_[cur_] : sorted2_[cur_]; + cur_++; + return id; + } + + /** + * Return true iff there are no branches left to try. + */ + bool empty() const { + return size() == 0; + } + + /** + * Return the size, i.e. the total number of branches contained. + */ + size_t size() const { + return unsorted_.size() + + (sortedSel_ ? sorted1_.size() : sorted2_.size()) - cur_; + } + + /** + * Return true iff there are no solutions left to try. + */ + bool emptySolution() const { + return sizeSolution() == 0; + } + + /** + * Return the size of the solution set so far. + */ + size_t sizeSolution() const { + return solutions_.size(); + } + + /** + * Sort unsorted branches, merge them with master sorted list. + */ + void flushUnsorted(); + +#ifndef NDEBUG + /** + * Sanity-check the queue. + */ + bool repOk() const { + assert_lt(cur_, (sortedSel_ ? sorted1_.size() : sorted2_.size())); + return true; + } +#endif + + /** + * Initialize the tracer with respect to a new read. This involves + * resetting all the state relating to the set of cells already visited + */ + void initRef( + const char* rd, // in: read sequence + const char* qu, // in: quality sequence + size_t rdlen, // in: read sequence length + const char* rf, // in: reference sequence + size_t rflen, // in: in-rectangle reference sequence length + TRefOff trflen, // in: total reference sequence length + TRefId refid, // in: reference id + TRefOff refoff, // in: reference offset + bool fw, // in: orientation + const DPRect *rect, // in: DP rectangle + const Checkpointer *cper, // in: checkpointer + const Scoring& sc, // in: scoring scheme + size_t nceil) // in: N ceiling + { + prob_.initRef(rd, qu, rdlen, rf, rflen, trflen, refid, refoff, fw, rect, cper, &sc, nceil); + const size_t ndiag = rflen + rdlen - 1; + seenPaths_.resize(ndiag); + for(size_t i = 0; i < ndiag; i++) { + seenPaths_[i].clear(); + } + // clear each of the per-column sets + if(sawcell_.size() < rflen) { + size_t isz = sawcell_.size(); + sawcell_.resize(rflen); + for(size_t i = isz; i < rflen; i++) { + sawcell_[i].setCat(DP_CAT); + } + } + for(size_t i = 0; i < rflen; i++) { + sawcell_[i].setCat(DP_CAT); + sawcell_[i].clear(); // clear the set + } + } + + /** + * Initialize with a new backtrace. + */ + void initBt( + TAlScore escore, // in: alignment score + size_t row, // in: start in this row + size_t col, // in: start in this column + bool fill, // in: use mini-filling? + bool usecp, // in: use checkpointing? + bool doTri, // in: triangle-shaped mini-fills? + RandomSource& rnd) // in: random gen, to choose among equal paths + { + prob_.initBt(row, col, fill, usecp, escore); + Edit e; e.reset(); + unsorted_.clear(); + solutions_.clear(); + sorted1_.clear(); + sorted2_.clear(); + cur_ = 0; + nmm_ = 0; // number of mismatches attempted + nnmm_ = 0; // number of mismatches involving N attempted + nrdop_ = 0; // number of read gap opens attempted + nrfop_ = 0; // number of ref gap opens attempted + nrdex_ = 0; // number of read gap extensions attempted + nrfex_ = 0; // number of ref gap extensions attempted + nmmPrune_ = 0; // number of mismatches attempted + nnmmPrune_ = 0; // number of mismatches involving N attempted + nrdopPrune_ = 0; // number of read gap opens attempted + nrfopPrune_ = 0; // number of ref gap opens attempted + nrdexPrune_ = 0; // number of read gap extensions attempted + nrfexPrune_ = 0; // number of ref gap extensions attempted + row_ = row; + col_ = col; + doTri_ = doTri; + bs_.clear(); + if(!prob_.fill_) { + size_t id = bs_.alloc(); + bs_[id].init( + prob_, + 0, // parent id + 0, // penalty + 0, // starting score + row, // row + col, // column + e, + 0, + true, // this is the root + true); // this should be extend with exact matches + if(bs_[id].isSolution(prob_)) { + addSolution(id); + } else { + add(id); + } + } else { + int64_t row = row_, col = col_; + TAlScore targsc = prob_.targ_; + int hef = 0; + bool done = false, abort = false; + size_t depth = 0; + while(!done && !abort) { + // Accumulate edits as we go. We can do this by adding + // BtBranches to the bs_ structure. Each step of the backtrace + // either involves an edit (thereby starting a new branch) or + // extends the previous branch by one more position. + // + // Note: if the BtBranches are in line, then trySolution can be + // used to populate the SwResult and check for various + // situations where we might reject the alignment (i.e. due to + // a cell having been visited previously). + if(doTri_) { + triangleFill( + row, // row of cell to backtrace from + col, // column of cell to backtrace from + hef, // cell to bt from: H (0), E (1), or F (2) + targsc, // score of cell to backtrace from + prob_.targ_, // score of alignment we're looking for + rnd, // pseudo-random generator + row, // out: row we ended up in after bt + col, // out: column we ended up in after bt + hef, // out: H/E/F after backtrace + targsc, // out: score up to cell we ended up in + done, // out: finished tracing out an alignment? + abort); // out: aborted b/c cell was seen before? + } else { + squareFill( + row, // row of cell to backtrace from + col, // column of cell to backtrace from + hef, // cell to bt from: H (0), E (1), or F (2) + targsc, // score of cell to backtrace from + prob_.targ_, // score of alignment we're looking for + rnd, // pseudo-random generator + row, // out: row we ended up in after bt + col, // out: column we ended up in after bt + hef, // out: H/E/F after backtrace + targsc, // out: score up to cell we ended up in + done, // out: finished tracing out an alignment? + abort); // out: aborted b/c cell was seen before? + } + if(depth >= ndep_.size()) { + ndep_.resize(depth+1); + ndep_[depth] = 1; + } else { + ndep_[depth]++; + } + depth++; + assert((row >= 0 && col >= 0) || done); + } + } + ASSERT_ONLY(seen_.clear()); + } + + /** + * Get the next valid alignment given the backtrace problem. Return false + * if there is no valid solution, e.g., if + */ + bool nextAlignment( + size_t maxiter, + SwResult& res, + size_t& off, + size_t& nrej, + size_t& niter, + RandomSource& rnd); + + /** + * Return true iff this tracer has been initialized + */ + bool inited() const { + return prob_.inited(); + } + + /** + * Return true iff the mini-fills are triangle-shaped. + */ + bool doTri() const { return doTri_; } + + /** + * Fill in a triangle of the DP table and backtrace from the given cell to + * a cell in the previous checkpoint, or to the terminal cell. + */ + void triangleFill( + int64_t rw, // row of cell to backtrace from + int64_t cl, // column of cell to backtrace from + int hef, // cell to backtrace from is H (0), E (1), or F (2) + TAlScore targ, // score of cell to backtrace from + TAlScore targ_final, // score of alignment we're looking for + RandomSource& rnd, // pseudo-random generator + int64_t& row_new, // out: row we ended up in after backtrace + int64_t& col_new, // out: column we ended up in after backtrace + int& hef_new, // out: H/E/F after backtrace + TAlScore& targ_new, // out: score up to cell we ended up in + bool& done, // out: finished tracing out an alignment? + bool& abort); // out: aborted b/c cell was seen before? + + /** + * Fill in a square of the DP table and backtrace from the given cell to + * a cell in the previous checkpoint, or to the terminal cell. + */ + void squareFill( + int64_t rw, // row of cell to backtrace from + int64_t cl, // column of cell to backtrace from + int hef, // cell to backtrace from is H (0), E (1), or F (2) + TAlScore targ, // score of cell to backtrace from + TAlScore targ_final, // score of alignment we're looking for + RandomSource& rnd, // pseudo-random generator + int64_t& row_new, // out: row we ended up in after backtrace + int64_t& col_new, // out: column we ended up in after backtrace + int& hef_new, // out: H/E/F after backtrace + TAlScore& targ_new, // out: score up to cell we ended up in + bool& done, // out: finished tracing out an alignment? + bool& abort); // out: aborted b/c cell was seen before? + +protected: + + /** + * Get the next valid alignment given a backtrace problem. Return false + * if there is no valid solution. Use a backtracking search to find the + * solution. This can be very slow. + */ + bool nextAlignmentBacktrace( + size_t maxiter, + SwResult& res, + size_t& off, + size_t& nrej, + size_t& niter, + RandomSource& rnd); + + /** + * Get the next valid alignment given a backtrace problem. Return false + * if there is no valid solution. Use a triangle-fill backtrace to find + * the solution. This is usually fast (it's O(m + n)). + */ + bool nextAlignmentFill( + size_t maxiter, + SwResult& res, + size_t& off, + size_t& nrej, + size_t& niter, + RandomSource& rnd); + + /** + * Try all the solutions accumulated so far. Solutions might be rejected + * if they, for instance, overlap a previous solution, have too many Ns, + * fail to overlap a core diagonal, etc. + */ + bool trySolutions( + bool lookForOlap, + SwResult& res, + size_t& off, + size_t& nrej, + RandomSource& rnd, + bool& success); + + /** + * See if a given solution branch works as a solution (i.e. doesn't overlap + * another one, have too many Ns, fail to overlap a core diagonal, etc.) + */ + int trySolution( + size_t id, + bool lookForOlap, + SwResult& res, + size_t& off, + size_t& nrej, + RandomSource& rnd); + + BtBranchProblem prob_; // problem configuration + EFactory bs_; // global BtBranch factory + + // already reported alignments going through these diagonal segments + ELList > seenPaths_; + ELSet sawcell_; // cells already backtraced through + + EList > unsorted_; // unsorted list of as-yet-unflished BtBranches + EList sorted1_; // list of BtBranch, sorted by score + EList sorted2_; // list of BtBranch, sorted by score + EList solutions_; // list of solution branches + bool sortedSel_; // true -> 1, false -> 2 + size_t cur_; // cursor into sorted list to start from + + size_t nmm_; // number of mismatches attempted + size_t nnmm_; // number of mismatches involving N attempted + size_t nrdop_; // number of read gap opens attempted + size_t nrfop_; // number of ref gap opens attempted + size_t nrdex_; // number of read gap extensions attempted + size_t nrfex_; // number of ref gap extensions attempted + + size_t nmmPrune_; // + size_t nnmmPrune_; // + size_t nrdopPrune_; // + size_t nrfopPrune_; // + size_t nrdexPrune_; // + size_t nrfexPrune_; // + + size_t row_; // row + size_t col_; // column + + bool doTri_; // true -> fill in triangles; false -> squares + EList sq_; // square to fill when doing mini-fills + ELList tri_; // triangle to fill when doing mini-fills + EList ndep_; // # triangles mini-filled at various depths + +#ifndef NDEBUG + ESet seen_; // seedn branch ids; should never see same twice +#endif +}; + +#endif /*ndef ALIGNER_BT_H_*/ diff --git a/aligner_cache.cpp b/aligner_cache.cpp new file mode 100644 index 0000000..7a8de26 --- /dev/null +++ b/aligner_cache.cpp @@ -0,0 +1,181 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "aligner_cache.h" +#include "tinythread.h" + +#ifdef ALIGNER_CACHE_MAIN + +#include +#include +#include +#include "random_source.h" + +using namespace std; + +enum { + ARG_TESTS = 256 +}; + +static const char *short_opts = "vCt"; +static struct option long_opts[] = { + {(char*)"verbose", no_argument, 0, 'v'}, + {(char*)"tests", no_argument, 0, ARG_TESTS}, +}; + +static void printUsage(ostream& os) { + os << "Usage: sawhi-cache [options]*" << endl; + os << "Options:" << endl; + os << " --tests run unit tests" << endl; + os << " -v/--verbose talkative mode" << endl; +} + +int gVerbose = 0; + +static void add( + RedBlack& t, + Pool& p, + const char *dna) +{ + QKey qk; + qk.init(BTDnaString(dna, true)); + t.add(p, qk, NULL); +} + +/** + * Small tests for the AlignmentCache. + */ +static void aligner_cache_tests() { + RedBlack rb(1024); + Pool p(64 * 1024, 1024); + // Small test + add(rb, p, "ACGTCGATCGT"); + add(rb, p, "ACATCGATCGT"); + add(rb, p, "ACGACGATCGT"); + add(rb, p, "ACGTAGATCGT"); + add(rb, p, "ACGTCAATCGT"); + add(rb, p, "ACGTCGCTCGT"); + add(rb, p, "ACGTCGAACGT"); + assert_eq(7, rb.size()); + rb.clear(); + p.clear(); + // Another small test + add(rb, p, "ACGTCGATCGT"); + add(rb, p, "CCGTCGATCGT"); + add(rb, p, "TCGTCGATCGT"); + add(rb, p, "GCGTCGATCGT"); + add(rb, p, "AAGTCGATCGT"); + assert_eq(5, rb.size()); + rb.clear(); + p.clear(); + // Regression test (attempt to make it smaller) + add(rb, p, "CCTA"); + add(rb, p, "AGAA"); + add(rb, p, "TCTA"); + add(rb, p, "GATC"); + add(rb, p, "CTGC"); + add(rb, p, "TTGC"); + add(rb, p, "GCCG"); + add(rb, p, "GGAT"); + rb.clear(); + p.clear(); + // Regression test + add(rb, p, "CCTA"); + add(rb, p, "AGAA"); + add(rb, p, "TCTA"); + add(rb, p, "GATC"); + add(rb, p, "CTGC"); + add(rb, p, "CATC"); + add(rb, p, "CAAA"); + add(rb, p, "CTAT"); + add(rb, p, "CTCA"); + add(rb, p, "TTGC"); + add(rb, p, "GCCG"); + add(rb, p, "GGAT"); + assert_eq(12, rb.size()); + rb.clear(); + p.clear(); + // Larger random test + EList strs; + char buf[5]; + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 4; j++) { + for(int k = 0; k < 4; k++) { + for(int m = 0; m < 4; m++) { + buf[0] = "ACGT"[i]; + buf[1] = "ACGT"[j]; + buf[2] = "ACGT"[k]; + buf[3] = "ACGT"[m]; + buf[4] = '\0'; + strs.push_back(BTDnaString(buf, true)); + } + } + } + } + // Add all of the 4-mers in several different random orders + RandomSource rand; + for(uint32_t runs = 0; runs < 100; runs++) { + rb.clear(); + p.clear(); + assert_eq(0, rb.size()); + rand.init(runs); + EList used; + used.resize(256); + for(int i = 0; i < 256; i++) used[i] = false; + for(int i = 0; i < 256; i++) { + int r = rand.nextU32() % (256-i); + int unused = 0; + bool added = false; + for(int j = 0; j < 256; j++) { + if(!used[j] && unused == r) { + used[j] = true; + QKey qk; + qk.init(strs[j]); + rb.add(p, qk, NULL); + added = true; + break; + } + if(!used[j]) unused++; + } + assert(added); + } + } +} + +/** + * A way of feeding simply tests to the seed alignment infrastructure. + */ +int main(int argc, char **argv) { + int option_index = 0; + int next_option; + do { + next_option = getopt_long(argc, argv, short_opts, long_opts, &option_index); + switch (next_option) { + case 'v': gVerbose = true; break; + case ARG_TESTS: aligner_cache_tests(); return 0; + case -1: break; + default: { + cerr << "Unknown option: " << (char)next_option << endl; + printUsage(cerr); + exit(1); + } + } + } while(next_option != -1); +} +#endif diff --git a/aligner_cache.h b/aligner_cache.h new file mode 100644 index 0000000..2237071 --- /dev/null +++ b/aligner_cache.h @@ -0,0 +1,1013 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_CACHE_H_ +#define ALIGNER_CACHE_H_ + +/** + * CACHEING + * + * By caching the results of some alignment sub-problems, we hope to + * enable a "fast path" for read alignment whereby answers are mostly + * looked up rather than calculated from scratch. This is particularly + * effective when the input is sorted or otherwise grouped in a way + * that brings together reads with (at least some) seed sequences in + * common. + * + * But the cache is also where results are held, regardless of whether + * the results are maintained & re-used across reads. + * + * The cache consists of two linked potions: + * + * 1. A multimap from seed strings (i.e. read substrings) to reference strings + * that are within some edit distance (roughly speaking). This is the "seed + * multimap". + * + * Key: Read substring (2-bit-per-base encoded + length) + * Value: Set of reference substrings (i.e. keys into the suffix + * array multimap). + * + * 2. A multimap from reference strings to the corresponding elements of the + * suffix array. Elements are filled in with reference-offset info as it's + * calculated. This is the "suffix array multimap" + * + * Key: Reference substring (2-bit-per-base encoded + length) + * Value: (a) top from BWT, (b) length of range, (c) offset of first + * range element in + * + * For both multimaps, we use a combo Red-Black tree and EList. The payload in + * the Red-Black tree nodes points to a range in the EList. + */ + +#include +#include "ds.h" +#include "read.h" +#include "threading.h" +#include "mem_ids.h" +#include "simple_func.h" +#include "btypes.h" + +#define CACHE_PAGE_SZ (16 * 1024) + +typedef PListSlice TSlice; + +/** + * Key for the query multimap: the read substring and its length. + */ +struct QKey { + + /** + * Initialize invalid QKey. + */ + QKey() { reset(); } + + /** + * Initialize QKey from DNA string. + */ + QKey(const BTDnaString& s ASSERT_ONLY(, BTDnaString& tmp)) { + init(s ASSERT_ONLY(, tmp)); + } + + /** + * Initialize QKey from DNA string. Rightmost character is placed in the + * least significant bitpair. + */ + bool init( + const BTDnaString& s + ASSERT_ONLY(, BTDnaString& tmp)) + { + seq = 0; + len = (uint32_t)s.length(); + ASSERT_ONLY(tmp.clear()); + if(len > 32) { + len = 0xffffffff; + return false; // wasn't cacheable + } else { + // Rightmost char of 's' goes in the least significant bitpair + for(size_t i = 0; i < 32 && i < s.length(); i++) { + int c = (int)s.get(i); + assert_range(0, 4, c); + if(c == 4) { + len = 0xffffffff; + return false; + } + seq = (seq << 2) | s.get(i); + } + ASSERT_ONLY(toString(tmp)); + assert(sstr_eq(tmp, s)); + assert_leq(len, 32); + return true; // was cacheable + } + } + + /** + * Convert this key to a DNA string. + */ + void toString(BTDnaString& s) { + s.resize(len); + uint64_t sq = seq; + for(int i = (len)-1; i >= 0; i--) { + s.set((uint32_t)(sq & 3), i); + sq >>= 2; + } + } + + /** + * Return true iff the read substring is cacheable. + */ + bool cacheable() const { return len != 0xffffffff; } + + /** + * Reset to uninitialized state. + */ + void reset() { seq = 0; len = 0xffffffff; } + + /** + * True -> my key is less than the given key. + */ + bool operator<(const QKey& o) const { + return seq < o.seq || (seq == o.seq && len < o.len); + } + + /** + * True -> my key is greater than the given key. + */ + bool operator>(const QKey& o) const { + return !(*this < o || *this == o); + } + + /** + * True -> my key is equal to the given key. + */ + bool operator==(const QKey& o) const { + return seq == o.seq && len == o.len; + } + + + /** + * True -> my key is not equal to the given key. + */ + bool operator!=(const QKey& o) const { + return !(*this == o); + } + +#ifndef NDEBUG + /** + * Check that this is a valid, initialized QKey. + */ + bool repOk() const { + return len != 0xffffffff; + } +#endif + + uint64_t seq; // sequence + uint32_t len; // length of sequence +}; + +template +class AlignmentCache; + +/** + * Payload for the query multimap: a range of elements in the reference + * string list. + */ +template +class QVal { + +public: + + QVal() { reset(); } + + /** + * Return the offset of the first reference substring in the qlist. + */ + index_t offset() const { return i_; } + + /** + * Return the number of reference substrings associated with a read + * substring. + */ + index_t numRanges() const { + assert(valid()); + return rangen_; + } + + /** + * Return the number of elements associated with all associated + * reference substrings. + */ + index_t numElts() const { + assert(valid()); + return eltn_; + } + + /** + * Return true iff the read substring is not associated with any + * reference substrings. + */ + bool empty() const { + assert(valid()); + return numRanges() == 0; + } + + /** + * Return true iff the QVal is valid. + */ + bool valid() const { return rangen_ != (index_t)OFF_MASK; } + + /** + * Reset to invalid state. + */ + void reset() { + i_ = 0; rangen_ = eltn_ = (index_t)OFF_MASK; + } + + /** + * Initialize Qval. + */ + void init(index_t i, index_t ranges, index_t elts) { + i_ = i; rangen_ = ranges; eltn_ = elts; + } + + /** + * Tally another range with given number of elements. + */ + void addRange(index_t numElts) { + rangen_++; + eltn_ += numElts; + } + +#ifndef NDEBUG + /** + * Check that this QVal is internally consistent and consistent + * with the contents of the given cache. + */ + bool repOk(const AlignmentCache& ac) const; +#endif + +protected: + + index_t i_; // idx of first elt in qlist + index_t rangen_; // # ranges (= # associated reference substrings) + index_t eltn_; // # elements (total) +}; + +/** + * Key for the suffix array multimap: the reference substring and its + * length. Same as QKey so I typedef it. + */ +typedef QKey SAKey; + +/** + * Payload for the suffix array multimap: (a) the top element of the + * range in BWT, (b) the offset of the first elt in the salist, (c) + * length of the range. + */ +template +struct SAVal { + + SAVal() : topf(), topb(), i(), len(OFF_MASK) { } + + /** + * Return true iff the SAVal is valid. + */ + bool valid() { return len != (index_t)OFF_MASK; } + +#ifndef NDEBUG + /** + * Check that this SAVal is internally consistent and consistent + * with the contents of the given cache. + */ + bool repOk(const AlignmentCache& ac) const; +#endif + + /** + * Initialize the SAVal. + */ + void init( + index_t tf, + index_t tb, + index_t ii, + index_t ln) + { + topf = tf; + topb = tb; + i = ii; + len = ln; + } + + index_t topf; // top in BWT + index_t topb; // top in BWT' + index_t i; // idx of first elt in salist + index_t len; // length of range +}; + +/** + * One data structure that encapsulates all of the cached information + * associated with a particular reference substring. This is useful + * for summarizing what info should be added to the cache for a partial + * alignment. + */ +template +class SATuple { + +public: + + SATuple() { reset(); }; + + SATuple(SAKey k, index_t tf, index_t tb, TSlice o) { + init(k, tf, tb, o); + } + + void init(SAKey k, index_t tf, index_t tb, TSlice o) { + key = k; topf = tf; topb = tb; offs = o; + } + + /** + * Initialize this SATuple from a subrange of the SATuple 'src'. + */ + void init(const SATuple& src, index_t first, index_t last) { + assert_neq((index_t)OFF_MASK, src.topb); + key = src.key; + topf = (index_t)(src.topf + first); + topb = (index_t)OFF_MASK; // unknown! + offs.init(src.offs, first, last); + } + +#ifndef NDEBUG + /** + * Check that this SATuple is internally consistent and that its + * PListSlice is consistent with its backing PList. + */ + bool repOk() const { + assert(offs.repOk()); + return true; + } +#endif + + /** + * Function for ordering SATuples. This is used when prioritizing which to + * explore first when extending seed hits into full alignments. Smaller + * ranges get higher priority and we use 'top' to break ties, though any + * way of breaking a tie would be fine. + */ + bool operator<(const SATuple& o) const { + if(offs.size() < o.offs.size()) { + return true; + } + if(offs.size() > o.offs.size()) { + return false; + } + return topf < o.topf; + } + bool operator>(const SATuple& o) const { + if(offs.size() < o.offs.size()) { + return false; + } + if(offs.size() > o.offs.size()) { + return true; + } + return topf > o.topf; + } + + bool operator==(const SATuple& o) const { + return key == o.key && topf == o.topf && topb == o.topb && offs == o.offs; + } + + void reset() { topf = topb = (index_t)OFF_MASK; offs.reset(); } + + /** + * Set the length to be at most the original length. + */ + void setLength(index_t nlen) { + assert_leq(nlen, offs.size()); + offs.setLength(nlen); + } + + /** + * Return the number of times this reference substring occurs in the + * reference, which is also the size of the 'offs' TSlice. + */ + index_t size() const { return (index_t)offs.size(); } + + // bot/length of SA range equals offs.size() + SAKey key; // sequence key + index_t topf; // top in BWT index + index_t topb; // top in BWT' index + TSlice offs; // offsets +}; + +/** + * Encapsulate the data structures and routines that constitute a + * particular cache, i.e., a particular stratum of the cache system, + * which might comprise many strata. + * + * Each thread has a "current-read" AlignmentCache which is used to + * build and store subproblem results as alignment is performed. When + * we're finished with a read, we might copy the cached results for + * that read (and perhaps a bundle of other recently-aligned reads) to + * a higher-level "across-read" cache. Higher-level caches may or may + * not be shared among threads. + * + * A cache consists chiefly of two multimaps, each implemented as a + * Red-Black tree map backed by an EList. A 'version' counter is + * incremented every time the cache is cleared. + */ +template +class AlignmentCache { + + typedef RedBlackNode > QNode; + typedef RedBlackNode > SANode; + + typedef PList TQList; + typedef PList TSAList; + +public: + + AlignmentCache( + uint64_t bytes, + bool shared) : + pool_(bytes, CACHE_PAGE_SZ, CA_CAT), + qmap_(CACHE_PAGE_SZ, CA_CAT), + qlist_(CA_CAT), + samap_(CACHE_PAGE_SZ, CA_CAT), + salist_(CA_CAT), + shared_(shared), + mutex_m(), + version_(0) + { + } + + /** + * Given a QVal, populate the given EList of SATuples with records + * describing all of the cached information about the QVal's + * reference substrings. + */ + template + void queryQval( + const QVal& qv, + EList, S>& satups, + index_t& nrange, + index_t& nelt, + bool getLock = true) + { + ThreadSafe ts(lockPtr(), shared_ && getLock); + assert(qv.repOk(*this)); + const index_t refi = qv.offset(); + const index_t reff = refi + qv.numRanges(); + // For each reference sequence sufficiently similar to the + // query sequence in the QKey... + for(index_t i = refi; i < reff; i++) { + // Get corresponding SAKey, containing similar reference + // sequence & length + SAKey sak = qlist_.get(i); + // Shouldn't have identical keys in qlist_ + assert(i == refi || qlist_.get(i) != qlist_.get(i-1)); + // Get corresponding SANode + SANode *n = samap_.lookup(sak); + assert(n != NULL); + const SAVal& sav = n->payload; + assert(sav.repOk(*this)); + if(sav.len > 0) { + nrange++; + satups.expand(); + satups.back().init(sak, sav.topf, sav.topb, TSlice(salist_, sav.i, sav.len)); + nelt += sav.len; +#ifndef NDEBUG + // Shouldn't add consecutive identical entries too satups + if(i > refi) { + const SATuple b1 = satups.back(); + const SATuple b2 = satups[satups.size()-2]; + assert(b1.key != b2.key || b1.topf != b2.topf || b1.offs != b2.offs); + } +#endif + } + } + } + + /** + * Return true iff the cache has no entries in it. + */ + bool empty() const { + bool ret = qmap_.empty(); + assert(!ret || qlist_.empty()); + assert(!ret || samap_.empty()); + assert(!ret || salist_.empty()); + return ret; + } + + /** + * Add a new query key ('qk'), usually a 2-bit encoded substring of + * the read) as the key in a new Red-Black node in the qmap and + * return a pointer to the node's QVal. + * + * The expectation is that the caller is about to set about finding + * associated reference substrings, and that there will be future + * calls to addOnTheFly to add associations to reference substrings + * found. + */ + QVal* add( + const QKey& qk, + bool *added, + bool getLock = true) + { + ThreadSafe ts(lockPtr(), shared_ && getLock); + assert(qk.cacheable()); + QNode *n = qmap_.add(pool(), qk, added); + return (n != NULL ? &n->payload : NULL); + } + + /** + * Add a new association between a read sequnce ('seq') and a + * reference sequence ('') + */ + bool addOnTheFly( + QVal& qv, // qval that points to the range of reference substrings + const SAKey& sak, // the key holding the reference substring + index_t topf, // top range elt in BWT index + index_t botf, // bottom range elt in BWT index + index_t topb, // top range elt in BWT' index + index_t botb, // bottom range elt in BWT' index + bool getLock = true); + + /** + * Clear the cache, i.e. turn it over. All HitGens referring to + * ranges in this cache will become invalid and the corresponding + * reads will have to be re-aligned. + */ + void clear(bool getLock = true) { + ThreadSafe ts(lockPtr(), shared_ && getLock); + pool_.clear(); + qmap_.clear(); + qlist_.clear(); + samap_.clear(); + salist_.clear(); + version_++; + } + + /** + * Return the number of keys in the query multimap. + */ + index_t qNumKeys() const { return (index_t)qmap_.size(); } + + /** + * Return the number of keys in the suffix array multimap. + */ + index_t saNumKeys() const { return (index_t)samap_.size(); } + + /** + * Return the number of elements in the reference substring list. + */ + index_t qSize() const { return (index_t)qlist_.size(); } + + /** + * Return the number of elements in the SA range list. + */ + index_t saSize() const { return (index_t)salist_.size(); } + + /** + * Return the pool. + */ + Pool& pool() { return pool_; } + + /** + * Return the lock object. + */ + MUTEX_T& lock() { + return mutex_m; + } + + /** + * Return a const pointer to the lock object. This allows us to + * write const member functions that grab the lock. + */ + MUTEX_T* lockPtr() const { + return const_cast(&mutex_m); + } + + /** + * Return true iff this cache is shared among threads. + */ + bool shared() const { return shared_; } + + /** + * Return the current "version" of the cache, i.e. the total number + * of times it has turned over since its creation. + */ + uint32_t version() const { return version_; } + +protected: + + Pool pool_; // dispenses memory pages + RedBlack > qmap_; // map from query substrings to reference substrings + TQList qlist_; // list of reference substrings + RedBlack > samap_; // map from reference substrings to SA ranges + TSAList salist_; // list of SA ranges + + bool shared_; // true -> this cache is global + MUTEX_T mutex_m; // mutex used for syncronization in case the the cache is shared. + uint32_t version_; // cache version +}; + +/** + * Interface used to query and update a pair of caches: one thread- + * local and unsynchronized, another shared and synchronized. One or + * both can be NULL. + */ +template +class AlignmentCacheIface { + +public: + + AlignmentCacheIface( + AlignmentCache *current, + AlignmentCache *local, + AlignmentCache *shared) : + qk_(), + qv_(NULL), + cacheable_(false), + rangen_(0), + eltsn_(0), + current_(current), + local_(local), + shared_(shared) + { + assert(current_ != NULL); + } + +#if 0 + /** + * Query the relevant set of caches, looking for a QVal to go with + * the provided QKey. If the QVal is found in a cache other than + * the current-read cache, it is copied into the current-read cache + * first and the QVal pointer for the current-read cache is + * returned. This function never returns a pointer from any cache + * other than the current-read cache. If the QVal could not be + * found in any cache OR if the QVal was found in a cache other + * than the current-read cache but could not be copied into the + * current-read cache, NULL is returned. + */ + QVal* queryCopy(const QKey& qk, bool getLock = true) { + assert(qk.cacheable()); + AlignmentCache* caches[3] = { current_, local_, shared_ }; + for(int i = 0; i < 3; i++) { + if(caches[i] == NULL) continue; + QVal* qv = caches[i]->query(qk, getLock); + if(qv != NULL) { + if(i == 0) return qv; + if(!current_->copy(qk, *qv, *caches[i], getLock)) { + // Exhausted memory in the current cache while + // attempting to copy in the qk + return NULL; + } + QVal* curqv = current_->query(qk, getLock); + assert(curqv != NULL); + return curqv; + } + } + return NULL; + } + + /** + * Query the relevant set of caches, looking for a QVal to go with + * the provided QKey. If a QVal is found and which is non-NULL, + * *which is set to 0 if the qval was found in the current-read + * cache, 1 if it was found in the local across-read cache, and 2 + * if it was found in the shared across-read cache. + */ + inline QVal* query( + const QKey& qk, + AlignmentCache** which, + bool getLock = true) + { + assert(qk.cacheable()); + AlignmentCache* caches[3] = { current_, local_, shared_ }; + for(int i = 0; i < 3; i++) { + if(caches[i] == NULL) continue; + QVal* qv = caches[i]->query(qk, getLock); + if(qv != NULL) { + if(which != NULL) *which = caches[i]; + return qv; + } + } + return NULL; + } +#endif + + /** + * This function is called whenever we start to align a new read or + * read substring. We make key for it and store the key in qk_. + * If the sequence is uncacheable, we don't actually add it to the + * map but the corresponding reference substrings are still added + * to the qlist_. + * + * Returns: + * -1 if out of memory + * 0 if key was found in cache + * 1 if key was not found in cache (and there's enough memory to + * add a new key) + */ + int beginAlign( + const BTDnaString& seq, + const BTString& qual, + QVal& qv, // out: filled in if we find it in the cache + bool getLock = true) + { + assert(repOk()); + qk_.init(seq ASSERT_ONLY(, tmpdnastr_)); + //if(qk_.cacheable() && (qv_ = current_->query(qk_, getLock)) != NULL) { + // // qv_ holds the answer + // assert(qv_->valid()); + // qv = *qv_; + // resetRead(); + // return 1; // found in cache + //} else + if(qk_.cacheable()) { + // Make a QNode for this key and possibly add the QNode to the + // Red-Black map; but if 'seq' isn't cacheable, just create the + // QNode (without adding it to the map). + qv_ = current_->add(qk_, &cacheable_, getLock); + } else { + qv_ = &qvbuf_; + } + if(qv_ == NULL) { + resetRead(); + return -1; // Not in memory + } + qv_->reset(); + return 0; // Need to search for it + } + ASSERT_ONLY(BTDnaString tmpdnastr_); + + /** + * Called when is finished aligning a read (and so is finished + * adding associated reference strings). Returns a copy of the + * final QVal object and resets the alignment state of the + * current-read cache. + * + * Also, if the alignment is cacheable, it commits it to the next + * cache up in the cache hierarchy. + */ + QVal finishAlign(bool getLock = true) { + if(!qv_->valid()) { + qv_->init(0, 0, 0); + } + // Copy this pointer because we're about to reset the qv_ field + // to NULL + QVal* qv = qv_; + // Commit the contents of the current-read cache to the next + // cache up in the hierarchy. + // If qk is cacheable, then it must be in the cache +#if 0 + if(qk_.cacheable()) { + AlignmentCache* caches[3] = { current_, local_, shared_ }; + ASSERT_ONLY(AlignmentCache* which); + ASSERT_ONLY(QVal* qv2 = query(qk_, &which, true)); + assert(qv2 == qv); + assert(which == current_); + for(int i = 1; i < 3; i++) { + if(caches[i] != NULL) { + // Copy this key/value pair to the to the higher + // level cache and, if its memory is exhausted, + // clear the cache and try again. + caches[i]->clearCopy(qk_, *qv_, *current_, getLock); + break; + } + } + } +#endif + // Reset the state in this iface in preparation for the next + // alignment. + resetRead(); + assert(repOk()); + return *qv; + } + + /** + * A call to this member indicates that the caller has finished + * with the last read (if any) and is ready to work on the next. + * This gives the cache a chance to reset some of its state if + * necessary. + */ + void nextRead() { + current_->clear(); + resetRead(); + assert(!aligning()); + } + + /** + * Return true iff we're in the middle of aligning a sequence. + */ + bool aligning() const { + return qv_ != NULL; + } + + /** + * Clears both the local and shared caches. + */ + void clear() { + if(current_ != NULL) current_->clear(); + if(local_ != NULL) local_->clear(); + if(shared_ != NULL) shared_->clear(); + } + + /** + * Add an alignment to the running list of alignments being + * compiled for the current read in the local cache. + */ + bool addOnTheFly( + const BTDnaString& rfseq, // reference sequence close to read seq + index_t topf, // top in BWT index + index_t botf, // bot in BWT index + index_t topb, // top in BWT' index + index_t botb, // bot in BWT' index + bool getLock = true) // true -> lock is not held by caller + { + + assert(aligning()); + assert(repOk()); + ASSERT_ONLY(BTDnaString tmp); + SAKey sak(rfseq ASSERT_ONLY(, tmp)); + //assert(sak.cacheable()); + if(current_->addOnTheFly((*qv_), sak, topf, botf, topb, botb, getLock)) { + rangen_++; + eltsn_ += (botf-topf); + return true; + } + return false; + } + + /** + * Given a QVal, populate the given EList of SATuples with records + * describing all of the cached information about the QVal's + * reference substrings. + */ + template + void queryQval( + const QVal& qv, + EList, S>& satups, + index_t& nrange, + index_t& nelt, + bool getLock = true) + { + current_->queryQval(qv, satups, nrange, nelt, getLock); + } + + /** + * Return a pointer to the current-read cache object. + */ + const AlignmentCache* currentCache() const { return current_; } + + index_t curNumRanges() const { return rangen_; } + index_t curNumElts() const { return eltsn_; } + +#ifndef NDEBUG + /** + * Check that AlignmentCacheIface is internally consistent. + */ + bool repOk() const { + assert(current_ != NULL); + assert_geq(eltsn_, rangen_); + if(qv_ == NULL) { + assert_eq(0, rangen_); + assert_eq(0, eltsn_); + } + return true; + } +#endif + + /** + * Return the alignment cache for the current read. + */ + const AlignmentCache& current() { + return *current_; + } + +protected: + + /** + * Reset fields encoding info about the in-process read. + */ + void resetRead() { + cacheable_ = false; + rangen_ = eltsn_ = 0; + qv_ = NULL; + } + + QKey qk_; // key representation for current read substring + QVal *qv_; // pointer to value representation for current read substring + QVal qvbuf_; // buffer for when key is uncacheable but we need a qv + bool cacheable_; // true iff the read substring currently being aligned is cacheable + + index_t rangen_; // number of ranges since last alignment job began + index_t eltsn_; // number of elements since last alignment job began + + AlignmentCache *current_; // cache dedicated to the current read + AlignmentCache *local_; // local, unsynchronized cache + AlignmentCache *shared_; // shared, synchronized cache +}; + +#ifndef NDEBUG +/** + * Check that this QVal is internally consistent and consistent + * with the contents of the given cache. + */ +template +bool QVal::repOk(const AlignmentCache& ac) const { + if(rangen_ > 0) { + assert_lt(i_, ac.qSize()); + assert_leq(i_ + rangen_, ac.qSize()); + } + assert_geq(eltn_, rangen_); + return true; +} +#endif + +#ifndef NDEBUG +/** + * Check that this SAVal is internally consistent and consistent + * with the contents of the given cache. + */ +template +bool SAVal::repOk(const AlignmentCache& ac) const { + assert(len == 0 || i < ac.saSize()); + assert_leq(i + len, ac.saSize()); + return true; +} +#endif + +/** + * Add a new association between a read sequnce ('seq') and a + * reference sequence ('') + */ +template +bool AlignmentCache::addOnTheFly( + QVal& qv, // qval that points to the range of reference substrings + const SAKey& sak, // the key holding the reference substring + index_t topf, // top range elt in BWT index + index_t botf, // bottom range elt in BWT index + index_t topb, // top range elt in BWT' index + index_t botb, // bottom range elt in BWT' index + bool getLock) +{ + ThreadSafe ts(lockPtr(), shared_ && getLock); + bool added = true; + // If this is the first reference sequence we're associating with + // the query sequence, initialize the QVal. + if(!qv.valid()) { + qv.init((index_t)qlist_.size(), 0, 0); + } + qv.addRange(botf-topf); // update tally for # ranges and # elts + if(!qlist_.add(pool(), sak)) { + return false; // Exhausted pool memory + } +#ifndef NDEBUG + for(index_t i = qv.offset(); i < qlist_.size(); i++) { + if(i > qv.offset()) { + assert(qlist_.get(i) != qlist_.get(i-1)); + } + } +#endif + assert_eq(qv.offset() + qv.numRanges(), qlist_.size()); + SANode *s = samap_.add(pool(), sak, &added); + if(s == NULL) { + return false; // Exhausted pool memory + } + assert(s->key.repOk()); + if(added) { + s->payload.i = (index_t)salist_.size(); + s->payload.len = botf - topf; + s->payload.topf = topf; + s->payload.topb = topb; + for(size_t j = 0; j < (botf-topf); j++) { + if(!salist_.add(pool(), (index_t)0xffffffff)) { + // Change the payload's len field + s->payload.len = (uint32_t)j; + return false; // Exhausted pool memory + } + } + assert(s->payload.repOk(*this)); + } + // Now that we know all allocations have succeeded, we can do a few final + // updates + + return true; +} + +#endif /*ALIGNER_CACHE_H_*/ diff --git a/aligner_driver.cpp b/aligner_driver.cpp new file mode 100644 index 0000000..00703de --- /dev/null +++ b/aligner_driver.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2012, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "aligner_driver.h" + +void AlignerDriverRootSelector::select( + const Read& q, + const Read* qo, + bool nofw, + bool norc, + EList& confs, + EList& roots) +{ + // Calculate interval length for both mates + int interval = rootIval_.f((double)q.length()); + if(qo != NULL) { + // Boost interval length by 20% for paired-end reads + interval = (int)(interval * 1.2 + 0.5); + } + float pri = 0.0f; + for(int fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + if((fw && nofw) || (!fw && norc)) { + continue; + } + // Put down left-to-right roots w/r/t forward and reverse-complement reads + { + bool first = true; + size_t i = 0; + while(first || (i + landing_ <= q.length())) { + confs.expand(); + confs.back().cons.init(landing_, consExp_); + roots.expand(); + roots.back().init( + i, // offset from 5' end + true, // left-to-right? + fw, // fw? + q.length(), // query length + pri); // root priority + i += interval; + first = false; + } + } + // Put down right-to-left roots w/r/t forward and reverse-complement reads + { + bool first = true; + size_t i = 0; + while(first || (i + landing_ <= q.length())) { + confs.expand(); + confs.back().cons.init(landing_, consExp_); + roots.expand(); + roots.back().init( + q.length() - i - 1, // offset from 5' end + false, // left-to-right? + fw, // fw? + q.length(), // query length + pri); // root priority + i += interval; + first = false; + } + } + } +} + diff --git a/aligner_driver.h b/aligner_driver.h new file mode 100644 index 0000000..97f06bf --- /dev/null +++ b/aligner_driver.h @@ -0,0 +1,247 @@ +/* + * Copyright 2012, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* + * aligner_driver.h + * + * REDUNDANT SEED HITS + * + * We say that two seed hits are redundant if they trigger identical + * seed-extend dynamic programming problems. Put another way, they both lie on + * the same diagonal of the overall read/reference dynamic programming matrix. + * Detecting redundant seed hits is simple when the seed hits are ungapped. We + * do this after offset resolution but before the offset is converted to genome + * coordinates (see uses of the seenDiags1_/seenDiags2_ fields for examples). + * + * REDUNDANT ALIGNMENTS + * + * In an unpaired context, we say that two alignments are redundant if they + * share any cells in the global DP table. Roughly speaking, this is like + * saying that two alignments are redundant if any read character aligns to the + * same reference character (same reference sequence, same strand, same offset) + * in both alignments. + * + * In a paired-end context, we say that two paired-end alignments are redundant + * if the mate #1s are redundant and the mate #2s are redundant. + * + * How do we enforce this? In the unpaired context, this is relatively simple: + * the cells from each alignment are checked against a set containing all cells + * from all previous alignments. Given a new alignment, for each cell in the + * new alignment we check whether it is in the set. If there is any overlap, + * the new alignment is rejected as redundant. Otherwise, the new alignment is + * accepted and its cells are added to the set. + * + * Enforcement in a paired context is a little trickier. Consider the + * following approaches: + * + * 1. Skip anchors that are redundant with any previous anchor or opposite + * alignment. This is sufficient to ensure no two concordant alignments + * found are redundant. + * + * 2. Same as scheme 1, but with a "transitive closure" scheme for finding all + * concordant pairs in the vicinity of an anchor. Consider the AB/AC + * scenario from the previous paragraph. If B is the anchor alignment, we + * will find AB but not AC. But under this scheme, once we find AB we then + * let B be a new anchor and immediately look for its opposites. Likewise, + * if we find any opposite, we make them anchors and continue searching. We + * don't stop searching until every opposite is used as an anchor. + * + * 3. Skip anchors that are redundant with any previous anchor alignment (but + * allow anchors that are redundant with previous opposite alignments). + * This isn't sufficient to avoid redundant concordant alignments. To avoid + * redundant concordants, we need an additional procedure that checks each + * new concordant alignment one-by-one against a list of previous concordant + * alignments to see if it is redundant. + * + * We take approach 1. + */ + +#ifndef ALIGNER_DRIVER_H_ +#define ALIGNER_DRIVER_H_ + +#include "aligner_seed2.h" +#include "simple_func.h" +#include "aln_sink.h" + +/** + * Concrete subclass of DescentRootSelector. Puts a root every 'ival' chars, + * where 'ival' is determined by user-specified parameters. A root is filtered + * out if the end of the read is less than 'landing' positions away, in the + * direction of the search. + */ +class AlignerDriverRootSelector : public DescentRootSelector { + +public: + + AlignerDriverRootSelector( + double consExp, + const SimpleFunc& rootIval, + size_t landing) + { + consExp_ = consExp; + rootIval_ = rootIval; + landing_ = landing; + } + + virtual ~AlignerDriverRootSelector() { } + + virtual void select( + const Read& q, // read that we're selecting roots for + const Read* qo, // opposite mate, if applicable + bool nofw, // don't add roots for fw read + bool norc, // don't add roots for rc read + EList& confs, // put DescentConfigs here + EList& roots); // put DescentRoot here + +protected: + + double consExp_; + SimpleFunc rootIval_; + size_t landing_; +}; + +/** + * Return values from extendSeeds and extendSeedsPaired. + */ +enum { + // Candidates were examined exhaustively + ALDRIVER_EXHAUSTED_CANDIDATES = 1, + // The policy does not need us to look any further + ALDRIVER_POLICY_FULFILLED, + // We stopped because we ran up against a limit on how much work we should + // do for one set of seed ranges, e.g. the limit on number of consecutive + // unproductive DP extensions + ALDRIVER_EXCEEDED_LIMIT +}; + +/** + * This class is the glue between a DescentDriver and the dynamic programming + * implementations in Bowtie 2. The DescentDriver is used to find some very + * high-scoring alignments, but is additionally used to rank partial alignments + * so that they can be extended using dynamic programming. + */ +template +class AlignerDriver { + +public: + + AlignerDriver( + double consExp, + const SimpleFunc& rootIval, + size_t landing, + bool veryVerbose, + const SimpleFunc& totsz, + const SimpleFunc& totfmops) : + sel_(consExp, rootIval, landing), + alsel_(), + dr1_(veryVerbose), + dr2_(veryVerbose) + { + totsz_ = totsz; + totfmops_ = totfmops; + } + + /** + * Initialize driver with respect to a new read or pair. + */ + void initRead( + const Read& q1, + bool nofw, + bool norc, + TAlScore minsc, + TAlScore maxpen, + const Read* q2) + { + dr1_.initRead(q1, nofw, norc, minsc, maxpen, q2, &sel_); + red1_.init(q1.length()); + paired_ = false; + if(q2 != NULL) { + dr2_.initRead(*q2, nofw, norc, minsc, maxpen, &q1, &sel_); + red2_.init(q2->length()); + paired_ = true; + } else { + dr2_.reset(); + } + size_t totsz = totsz_.f(q1.length()); + size_t totfmops = totfmops_.f(q1.length()); + stop_.init( + totsz, + 0, + true, + totfmops); + } + + /** + * Start the driver. The driver will begin by conducting a best-first, + * index-assisted search through the space of possible full and partial + * alignments. This search may be followed up with a dynamic programming + * extension step, taking a prioritized set of partial SA ranges found + * during the search and extending each with DP. The process might also be + * iterated, with the search being occasioanally halted so that DPs can be + * tried, then restarted, etc. + */ + int go( + const Scoring& sc, + const GFM& gfmFw, + const GFM& gfmBw, + const BitPairReference& ref, + DescentMetrics& met, + WalkMetrics& wlm, + PerReadMetrics& prm, + RandomSource& rnd, + AlnSinkWrap& sink); + + /** + * Reset state of all DescentDrivers. + */ + void reset() { + dr1_.reset(); + dr2_.reset(); + red1_.reset(); + red2_.reset(); + } + +protected: + + AlignerDriverRootSelector sel_; // selects where roots should go + DescentAlignmentSelector alsel_; // one selector can deal with >1 drivers + DescentDriver dr1_; // driver for mate 1/unpaired reads + DescentDriver dr2_; // driver for paired-end reads + DescentStoppingConditions stop_; // when to pause index-assisted BFS + bool paired_; // current read is paired? + + SimpleFunc totsz_; // memory limit on best-first search data + SimpleFunc totfmops_; // max # FM ops for best-first search + + // For detecting redundant alignments + RedundantAlns red1_; // database of cells used for mate 1 alignments + RedundantAlns red2_; // database of cells used for mate 2 alignments + + // For AlnRes::matchesRef + ASSERT_ONLY(SStringExpandable raw_refbuf_); + ASSERT_ONLY(SStringExpandable raw_destU32_); + ASSERT_ONLY(EList raw_matches_); + ASSERT_ONLY(BTDnaString tmp_rf_); + ASSERT_ONLY(BTDnaString tmp_rdseq_); + ASSERT_ONLY(BTString tmp_qseq_); + ASSERT_ONLY(EList tmp_reflens_); + ASSERT_ONLY(EList tmp_refoffs_); +}; + +#endif /* defined(ALIGNER_DRIVER_H_) */ diff --git a/aligner_metrics.h b/aligner_metrics.h new file mode 100644 index 0000000..c0b0182 --- /dev/null +++ b/aligner_metrics.h @@ -0,0 +1,352 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_METRICS_H_ +#define ALIGNER_METRICS_H_ + +#include +#include +#include "alphabet.h" +#include "timer.h" +#include "sstring.h" + +using namespace std; + +/** + * Borrowed from http://www.johndcook.com/standard_deviation.html, + * which in turn is borrowed from Knuth. + */ +class RunningStat { +public: + RunningStat() : m_n(0), m_tot(0.0) { } + + void clear() { + m_n = 0; + m_tot = 0.0; + } + + void push(float x) { + m_n++; + m_tot += x; + // See Knuth TAOCP vol 2, 3rd edition, page 232 + if (m_n == 1) { + m_oldM = m_newM = x; + m_oldS = 0.0; + } else { + m_newM = m_oldM + (x - m_oldM)/m_n; + m_newS = m_oldS + (x - m_oldM)*(x - m_newM); + // set up for next iteration + m_oldM = m_newM; + m_oldS = m_newS; + } + } + + int num() const { + return m_n; + } + + double tot() const { + return m_tot; + } + + double mean() const { + return (m_n > 0) ? m_newM : 0.0; + } + + double variance() const { + return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 ); + } + + double stddev() const { + return sqrt(variance()); + } + +private: + int m_n; + double m_tot; + double m_oldM, m_newM, m_oldS, m_newS; +}; + +/** + * Encapsulates a set of metrics that we would like an aligner to keep + * track of, so that we can possibly use it to diagnose performance + * issues. + */ +class AlignerMetrics { + +public: + + AlignerMetrics() : + curBacktracks_(0), + curBwtOps_(0), + first_(true), + curIsLowEntropy_(false), + curIsHomoPoly_(false), + curHadRanges_(false), + curNumNs_(0), + reads_(0), + homoReads_(0), + lowEntReads_(0), + hiEntReads_(0), + alignedReads_(0), + unalignedReads_(0), + threeOrMoreNReads_(0), + lessThanThreeNRreads_(0), + bwtOpsPerRead_(), + backtracksPerRead_(), + bwtOpsPerHomoRead_(), + backtracksPerHomoRead_(), + bwtOpsPerLoEntRead_(), + backtracksPerLoEntRead_(), + bwtOpsPerHiEntRead_(), + backtracksPerHiEntRead_(), + bwtOpsPerAlignedRead_(), + backtracksPerAlignedRead_(), + bwtOpsPerUnalignedRead_(), + backtracksPerUnalignedRead_(), + bwtOpsPer0nRead_(), + backtracksPer0nRead_(), + bwtOpsPer1nRead_(), + backtracksPer1nRead_(), + bwtOpsPer2nRead_(), + backtracksPer2nRead_(), + bwtOpsPer3orMoreNRead_(), + backtracksPer3orMoreNRead_(), + timer_(cout, "", false) + { } + + void printSummary() { + if(!first_) { + finishRead(); + } + cout << "AlignerMetrics:" << endl; + cout << " # Reads: " << reads_ << endl; + float hopct = (reads_ > 0) ? (((float)homoReads_)/((float)reads_)) : (0.0f); + hopct *= 100.0f; + cout << " % homo-polymeric: " << (hopct) << endl; + float lopct = (reads_ > 0) ? ((float)lowEntReads_/(float)(reads_)) : (0.0f); + lopct *= 100.0f; + cout << " % low-entropy: " << (lopct) << endl; + float unpct = (reads_ > 0) ? ((float)unalignedReads_/(float)(reads_)) : (0.0f); + unpct *= 100.0f; + cout << " % unaligned: " << (unpct) << endl; + float npct = (reads_ > 0) ? ((float)threeOrMoreNReads_/(float)(reads_)) : (0.0f); + npct *= 100.0f; + cout << " % with 3 or more Ns: " << (npct) << endl; + cout << endl; + cout << " Total BWT ops: avg: " << bwtOpsPerRead_.mean() << ", stddev: " << bwtOpsPerRead_.stddev() << endl; + cout << " Total Backtracks: avg: " << backtracksPerRead_.mean() << ", stddev: " << backtracksPerRead_.stddev() << endl; + time_t elapsed = timer_.elapsed(); + cout << " BWT ops per second: " << (bwtOpsPerRead_.tot()/elapsed) << endl; + cout << " Backtracks per second: " << (backtracksPerRead_.tot()/elapsed) << endl; + cout << endl; + cout << " Homo-poly:" << endl; + cout << " BWT ops: avg: " << bwtOpsPerHomoRead_.mean() << ", stddev: " << bwtOpsPerHomoRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPerHomoRead_.mean() << ", stddev: " << backtracksPerHomoRead_.stddev() << endl; + cout << " Low-entropy:" << endl; + cout << " BWT ops: avg: " << bwtOpsPerLoEntRead_.mean() << ", stddev: " << bwtOpsPerLoEntRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPerLoEntRead_.mean() << ", stddev: " << backtracksPerLoEntRead_.stddev() << endl; + cout << " High-entropy:" << endl; + cout << " BWT ops: avg: " << bwtOpsPerHiEntRead_.mean() << ", stddev: " << bwtOpsPerHiEntRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPerHiEntRead_.mean() << ", stddev: " << backtracksPerHiEntRead_.stddev() << endl; + cout << endl; + cout << " Unaligned:" << endl; + cout << " BWT ops: avg: " << bwtOpsPerUnalignedRead_.mean() << ", stddev: " << bwtOpsPerUnalignedRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPerUnalignedRead_.mean() << ", stddev: " << backtracksPerUnalignedRead_.stddev() << endl; + cout << " Aligned:" << endl; + cout << " BWT ops: avg: " << bwtOpsPerAlignedRead_.mean() << ", stddev: " << bwtOpsPerAlignedRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPerAlignedRead_.mean() << ", stddev: " << backtracksPerAlignedRead_.stddev() << endl; + cout << endl; + cout << " 0 Ns:" << endl; + cout << " BWT ops: avg: " << bwtOpsPer0nRead_.mean() << ", stddev: " << bwtOpsPer0nRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPer0nRead_.mean() << ", stddev: " << backtracksPer0nRead_.stddev() << endl; + cout << " 1 N:" << endl; + cout << " BWT ops: avg: " << bwtOpsPer1nRead_.mean() << ", stddev: " << bwtOpsPer1nRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPer1nRead_.mean() << ", stddev: " << backtracksPer1nRead_.stddev() << endl; + cout << " 2 Ns:" << endl; + cout << " BWT ops: avg: " << bwtOpsPer2nRead_.mean() << ", stddev: " << bwtOpsPer2nRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPer2nRead_.mean() << ", stddev: " << backtracksPer2nRead_.stddev() << endl; + cout << " >2 Ns:" << endl; + cout << " BWT ops: avg: " << bwtOpsPer3orMoreNRead_.mean() << ", stddev: " << bwtOpsPer3orMoreNRead_.stddev() << endl; + cout << " Backtracks: avg: " << backtracksPer3orMoreNRead_.mean() << ", stddev: " << backtracksPer3orMoreNRead_.stddev() << endl; + cout << endl; + } + + /** + * + */ + void nextRead(const BTDnaString& read) { + if(!first_) { + finishRead(); + } + first_ = false; + //float ent = entropyDna5(read); + float ent = 0.0f; + curIsLowEntropy_ = (ent < 0.75f); + curIsHomoPoly_ = (ent < 0.001f); + curHadRanges_ = false; + curBwtOps_ = 0; + curBacktracks_ = 0; + // Count Ns + curNumNs_ = 0; + const size_t len = read.length(); + for(size_t i = 0; i < len; i++) { + if((int)read[i] == 4) curNumNs_++; + } + } + + /** + * + */ + void setReadHasRange() { + curHadRanges_ = true; + } + + /** + * Commit the running statistics for this read to + */ + void finishRead() { + reads_++; + if(curIsHomoPoly_) homoReads_++; + else if(curIsLowEntropy_) lowEntReads_++; + else hiEntReads_++; + if(curHadRanges_) alignedReads_++; + else unalignedReads_++; + bwtOpsPerRead_.push((float)curBwtOps_); + backtracksPerRead_.push((float)curBacktracks_); + // Drill down by entropy + if(curIsHomoPoly_) { + bwtOpsPerHomoRead_.push((float)curBwtOps_); + backtracksPerHomoRead_.push((float)curBacktracks_); + } else if(curIsLowEntropy_) { + bwtOpsPerLoEntRead_.push((float)curBwtOps_); + backtracksPerLoEntRead_.push((float)curBacktracks_); + } else { + bwtOpsPerHiEntRead_.push((float)curBwtOps_); + backtracksPerHiEntRead_.push((float)curBacktracks_); + } + // Drill down by whether it aligned + if(curHadRanges_) { + bwtOpsPerAlignedRead_.push((float)curBwtOps_); + backtracksPerAlignedRead_.push((float)curBacktracks_); + } else { + bwtOpsPerUnalignedRead_.push((float)curBwtOps_); + backtracksPerUnalignedRead_.push((float)curBacktracks_); + } + if(curNumNs_ == 0) { + lessThanThreeNRreads_++; + bwtOpsPer0nRead_.push((float)curBwtOps_); + backtracksPer0nRead_.push((float)curBacktracks_); + } else if(curNumNs_ == 1) { + lessThanThreeNRreads_++; + bwtOpsPer1nRead_.push((float)curBwtOps_); + backtracksPer1nRead_.push((float)curBacktracks_); + } else if(curNumNs_ == 2) { + lessThanThreeNRreads_++; + bwtOpsPer2nRead_.push((float)curBwtOps_); + backtracksPer2nRead_.push((float)curBacktracks_); + } else { + threeOrMoreNReads_++; + bwtOpsPer3orMoreNRead_.push((float)curBwtOps_); + backtracksPer3orMoreNRead_.push((float)curBacktracks_); + } + } + + // Running-total of the number of backtracks and BWT ops for the + // current read + uint32_t curBacktracks_; + uint32_t curBwtOps_; + +protected: + + bool first_; + + // true iff the current read is low entropy + bool curIsLowEntropy_; + // true if current read is all 1 char (or very close) + bool curIsHomoPoly_; + // true iff the current read has had one or more ranges reported + bool curHadRanges_; + // number of Ns in current read + int curNumNs_; + + // # reads + uint32_t reads_; + // # homo-poly reads + uint32_t homoReads_; + // # low-entropy reads + uint32_t lowEntReads_; + // # high-entropy reads + uint32_t hiEntReads_; + // # reads with alignments + uint32_t alignedReads_; + // # reads without alignments + uint32_t unalignedReads_; + // # reads with 3 or more Ns + uint32_t threeOrMoreNReads_; + // # reads with < 3 Ns + uint32_t lessThanThreeNRreads_; + + // Distribution of BWT operations per read + RunningStat bwtOpsPerRead_; + RunningStat backtracksPerRead_; + + // Distribution of BWT operations per homo-poly read + RunningStat bwtOpsPerHomoRead_; + RunningStat backtracksPerHomoRead_; + + // Distribution of BWT operations per low-entropy read + RunningStat bwtOpsPerLoEntRead_; + RunningStat backtracksPerLoEntRead_; + + // Distribution of BWT operations per high-entropy read + RunningStat bwtOpsPerHiEntRead_; + RunningStat backtracksPerHiEntRead_; + + // Distribution of BWT operations per read that "aligned" (for + // which a range was arrived at - range may not have necessarily + // lead to an alignment) + RunningStat bwtOpsPerAlignedRead_; + RunningStat backtracksPerAlignedRead_; + + // Distribution of BWT operations per read that didn't align + RunningStat bwtOpsPerUnalignedRead_; + RunningStat backtracksPerUnalignedRead_; + + // Distribution of BWT operations/backtracks per read with no Ns + RunningStat bwtOpsPer0nRead_; + RunningStat backtracksPer0nRead_; + + // Distribution of BWT operations/backtracks per read with one N + RunningStat bwtOpsPer1nRead_; + RunningStat backtracksPer1nRead_; + + // Distribution of BWT operations/backtracks per read with two Ns + RunningStat bwtOpsPer2nRead_; + RunningStat backtracksPer2nRead_; + + // Distribution of BWT operations/backtracks per read with three or + // more Ns + RunningStat bwtOpsPer3orMoreNRead_; + RunningStat backtracksPer3orMoreNRead_; + + Timer timer_; +}; + +#endif /* ALIGNER_METRICS_H_ */ diff --git a/aligner_report.h b/aligner_report.h new file mode 100644 index 0000000..c5cd8db --- /dev/null +++ b/aligner_report.h @@ -0,0 +1,35 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_REPORT_H_ +#define ALIGNER_REPORT_H_ + +#include "aligner_cache.h" + +class Reporter { +public: + /** + * + */ + bool report(const AlignmentCacheIface& cache, const QVal& qv) { + return true; // don't retry + } +}; + +#endif /*ALIGNER_REPORT_H_*/ diff --git a/aligner_result.cpp b/aligner_result.cpp new file mode 100644 index 0000000..9043a11 --- /dev/null +++ b/aligner_result.cpp @@ -0,0 +1,2162 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "reference.h" +#include "aligner_result.h" +#include "read.h" +#include "edit.h" +#include "sstring.h" +#include "ds.h" +#include "util.h" +#include "alphabet.h" + +using namespace std; + +/** + * Clear all contents. + */ +void AlnRes::reset() { + if(ned_ != NULL) { + assert(aed_ != NULL); + ned_->clear(); + aed_->clear(); + } + score_.invalidate(); + refcoord_.reset(); + refival_.reset(); + shapeSet_ = false; + rdlen_ = 0; + rdid_ = 0; + reflen_ = 0; + rdrows_ = 0; + rdextent_ = 0; + rdexrows_ = 0; + rfextent_ = 0; + refns_ = 0; + type_ = ALN_RES_TYPE_UNPAIRED; + fraglen_ = -1; + trimSoft_ = false; + trim5p_ = 0; + trim3p_ = 0; + pretrimSoft_ = true; + pretrim5p_ = 0; + pretrim3p_ = 0; + seedmms_ = 0; // number of mismatches allowed in seed + seedlen_ = 0; // length of seed + seedival_ = 0; // interval between seeds + minsc_ = 0; // minimum score + nuc5p_ = 0; + nuc3p_ = 0; + fraglenSet_ = false; + num_spliced_ = 0; + assert(!refcoord_.inited()); + assert(!refival_.inited()); +} + +/** + * Set the upstream-most reference offset involved in the alignment, and + * the extent of the alignment (w/r/t the reference) + */ +void AlnRes::setShape( + TRefId id, // id of reference aligned to + TRefOff off, // offset of first aligned char into ref seq + TRefOff reflen, // length of reference sequence aligned to + bool fw, // aligned to Watson strand? + size_t rdlen, // length of read after hard trimming, before soft + TReadId rdid, // read ID + bool pretrimSoft, // whether trimming prior to alignment was soft + size_t pretrim5p, // # poss trimmed form 5p end before alignment + size_t pretrim3p, // # poss trimmed form 3p end before alignment + bool trimSoft, // whether local-alignment trimming was soft + size_t trim5p, // # poss trimmed form 5p end during alignment + size_t trim3p) // # poss trimmed form 3p end during alignment +{ + rdlen_ = rdlen; + rdid_ = rdid; + rdrows_ = rdlen; + refcoord_.init(id, off, fw); + pretrimSoft_ = pretrimSoft; + pretrim5p_ = pretrim5p; + pretrim3p_ = pretrim3p; + trimSoft_ = trimSoft; + trim5p_ = trim5p; + trim3p_ = trim3p; + // Propagate trimming to the edits. We assume that the pos fields of the + // edits are set w/r/t to the rows of the dynamic programming table, and + // haven't taken trimming into account yet. + // + // TODO: The division of labor between the aligner and the AlnRes is not + // clean. Perhaps the trimming and *all* of its side-effects should be + // handled by the aligner. + + // daehwan - check this out - this doesn't seem to work with SAWHI + // size_t trimBeg = fw ? trim5p : trim3p; + size_t trimBeg = trim5p; + if(trimBeg > 0) { + for(size_t i = 0; i < ned_->size(); i++) { + // Shift by trim5p, since edits are w/r/t 5p end + assert_geq((*ned_)[i].pos, trimBeg); + (*ned_)[i].pos -= (uint32_t)trimBeg; + } + } + // Length after all soft trimming and any hard trimming that occurred + // during alignment + rdextent_ = rdlen; + if(pretrimSoft_) { + rdextent_ -= (pretrim5p + pretrim3p); // soft trim + } + rdextent_ -= (trim5p + trim3p); // soft or hard trim from alignment + assert_gt(rdextent_, 0); + rdexrows_ = rdextent_; + calcRefExtent(); + refival_.init(id, off, fw, rfextent_); + reflen_ = reflen; + shapeSet_ = true; +} + +/** + * Initialize new AlnRes. + */ +void AlnRes::init( + size_t rdlen, // # chars after hard trimming + TReadId rdid, // read ID + AlnScore score, // alignment score + const EList* ned, // nucleotide edits + size_t ned_i, // first position to copy + size_t ned_n, // # positions to copy + const EList* aed, // ambiguous base resolutions + size_t aed_i, // first position to copy + size_t aed_n, // # positions to copy + Coord refcoord, // leftmost ref pos of 1st al char + TRefOff reflen, // length of ref aligned to + LinkedEList >* raw_edits, + int seedmms, // # seed mms allowed + int seedlen, // seed length + int seedival, // space between seeds + int64_t minsc, // minimum score for valid aln + int nuc5p, + int nuc3p, + bool pretrimSoft, + size_t pretrim5p, // trimming prior to alignment + size_t pretrim3p, // trimming prior to alignment + bool trimSoft, + size_t trim5p, // trimming from alignment + size_t trim3p, // trimming from alignment + bool repeat) // repeat +{ + assert(raw_edits != NULL); + assert(raw_edits_ == NULL || raw_edits_ == raw_edits); + raw_edits_ = raw_edits; + if(ned_ != NULL) { + assert(aed_ != NULL); + ned_->clear(); + aed_->clear(); + } else if(raw_edits_ != NULL) { + assert(aed_ == NULL); + assert(ned_node_ == NULL && aed_node_ == NULL); + ned_node_ = raw_edits_->new_node(); + aed_node_ = raw_edits_->new_node(); + assert(ned_node_ != NULL && aed_node_ != NULL); + ned_ = &(ned_node_->payload); + aed_ = &(aed_node_->payload); + } + + rdlen_ = rdlen; + rdid_ = rdid; + rdrows_ = rdlen; + score_ = score; + ned_->clear(); + aed_->clear(); + if(ned != NULL) { + for(size_t i = ned_i; i < ned_i + ned_n; i++) { + ned_->push_back((*ned)[i]); + } + } + if(aed != NULL) { + for(size_t i = aed_i; i < aed_i + aed_n; i++) { + aed_->push_back((*aed)[i]); + } + } + refcoord_ = refcoord; + reflen_ = reflen; + seedmms_ = seedmms; + seedlen_ = seedlen; + seedival_ = seedival; + minsc_ = minsc; + nuc5p_ = nuc5p; + nuc3p_ = nuc3p; + pretrimSoft_ = pretrimSoft; + pretrim5p_ = pretrim5p; + pretrim3p_ = pretrim3p; + trimSoft_ = trimSoft; + trim5p_ = trim5p; + trim3p_ = trim3p; + repeat_ = repeat; + rdextent_ = rdlen; // # read characters after any hard trimming + if(pretrimSoft) { + rdextent_ -= (pretrim5p + pretrim3p); + } + if(trimSoft) { + rdextent_ -= (trim5p + trim3p); + } + rdexrows_ = rdextent_; + calcRefExtent(); + setShape( + refcoord.ref(), // id of reference aligned to + refcoord.off(), // offset of first aligned char into ref seq + reflen, // length of reference sequence aligned to + refcoord.fw(), // aligned to Watson strand? + rdlen, // length of read after hard trimming, before soft + rdid, // read ID + pretrimSoft, // whether trimming prior to alignment was soft + pretrim5p, // # poss trimmed form 5p end before alignment + pretrim3p, // # poss trimmed form 3p end before alignment + trimSoft, // whether local-alignment trimming was soft + trim5p, // # poss trimmed form 5p end during alignment + trim3p); // # poss trimmed form 3p end during alignment + shapeSet_ = true; + + num_spliced_ = 0; + for(size_t i = 0; i < ned_->size(); i++) { + if((*ned_)[i].type == EDIT_TYPE_SPL) { + num_spliced_++; + } + } +} + +/** + * Clip given number of characters from the Watson-upstream end of the + * alignment. + */ +void AlnRes::clipLeft(size_t rd_amt, size_t rf_amt) { + assert_geq(rd_amt, 0); + assert_geq(rf_amt, 0); + assert_leq(rd_amt, rdexrows_); + assert_leq(rf_amt, rfextent_); + assert(trimSoft_); + if(fw()) { + trim5p_ += rd_amt; + Edit::clipLo(*ned_, rdexrows_, rd_amt); + Edit::clipLo(*aed_, rdexrows_, rd_amt); + } else { + trim3p_ += rd_amt; + Edit::clipHi(*ned_, rdexrows_, rd_amt); + Edit::clipHi(*aed_, rdexrows_, rd_amt); + } + rdexrows_ -= rd_amt; + rdextent_ -= rd_amt; + rfextent_ -= rf_amt; + refcoord_.adjustOff(rf_amt); + refival_.adjustOff(rf_amt); + // Adjust refns_? +} + +/** + * Clip given number of characters from the Watson-downstream end of the + * alignment. + */ +void AlnRes::clipRight(size_t rd_amt, size_t rf_amt) { + assert_geq(rd_amt, 0); + assert_geq(rf_amt, 0); + assert_leq(rd_amt, rdexrows_); + assert_leq(rf_amt, rfextent_); + assert(trimSoft_); + if(fw()) { + trim3p_ += rd_amt; + Edit::clipHi(*ned_, rdexrows_, rd_amt); + Edit::clipHi(*aed_, rdexrows_, rd_amt); + } else { + trim5p_ += rd_amt; + Edit::clipLo(*ned_, rdexrows_, rd_amt); + Edit::clipLo(*aed_, rdexrows_, rd_amt); + } + rdexrows_ -= rd_amt; + rdextent_ -= rd_amt; + rfextent_ -= rf_amt; + // Adjust refns_? +} + +/** + * Clip away portions of the alignment that are outside the given bounds. + * Clipping is soft if soft == true, hard otherwise. Assuming for now that + * there isn't any other clipping. + * + * Note that all clipping is expressed in terms of read positions. So if there + * are reference gaps in the overhanging portion, we must + */ +void AlnRes::clipOutside(bool soft, TRefOff refi, TRefOff reff) { + // Overhang on LHS + TRefOff left = refcoord_.off(); + if(left < refi) { + size_t rf_amt = (size_t)(refi - left); + size_t rf_i = rf_amt; + size_t nedsz = ned_->size(); + if(!fw()) { + Edit::invertPoss(*ned_, rdexrows_, false); + } + for(size_t i = 0; i < nedsz; i++) { + assert_lt((*ned_)[i].pos, rdexrows_); + if((*ned_)[i].pos > rf_i) break; + if((*ned_)[i].isRefGap()) rf_i++; + } + if(!fw()) { + Edit::invertPoss(*ned_, rdexrows_, false); + } + clipLeft(rf_i, rf_amt); + } + // Overhang on RHS + TRefOff right = refcoord_.off() + refNucExtent(); + if(right > reff) { + size_t rf_amt = (size_t)(right - reff); + size_t rf_i = rf_amt; + size_t nedsz = ned_->size(); + if(fw()) { + Edit::invertPoss(*ned_, rdexrows_, false); + } + for(size_t i = 0; i < nedsz; i++) { + assert_lt((*ned_)[i].pos, rdexrows_); + if((*ned_)[i].pos > rf_i) break; + if((*ned_)[i].isRefGap()) rf_i++; + } + if(fw()) { + Edit::invertPoss(*ned_, rdexrows_, false); + } + clipRight(rf_i, rf_amt); + } +} + +/** + * Return true iff this AlnRes and the given AlnRes overlap. Two AlnRess + * overlap if they share a cell in the overall dynamic programming table: + * i.e. if there exists a read position s.t. that position in both reads + * matches up with the same reference character. E.g., the following + * alignments (drawn schematically as paths through a dynamic programming + * table) are redundant: + * + * a b a b + * \ \ \ \ + * \ \ \ \ + * \ \ \ \ + * ---\ \ \ + * \ ---\--- + * ---\ \ \ + * \ \ \ \ + * \ \ \ \ + * \ \ \ \ + * a b a b + * + * We iterate over each read position that hasn't been hard-trimmed, but + * only overlaps at positions that have also not been soft-trimmed are + * considered. + */ +bool AlnRes::overlap(AlnRes& res) { + if(fw() != res.fw() || refid() != res.refid()) { + // Must be same reference and same strand in order to overlap + return false; + } + TRefOff my_left = refoff(); // my leftmost aligned char + TRefOff other_left = res.refoff(); // other leftmost aligned char + TRefOff my_right = my_left + refExtent(); + TRefOff other_right = other_left + res.refExtent(); + if(my_right < other_left || other_right < my_left) { + // The rectangular hulls of the two alignments don't overlap, so + // they can't overlap at any cell + return false; + } + // Reference and strand are the same and hulls overlap. Now go read + // position by read position testing if any align identically with the + // reference. + + // Edits are ordered and indexed from 5' to 3' to start with. We + // reorder them to go from left to right along the Watson strand. + if(!fw()) { + invertEdits(); + } + if(!res.fw()) { + res.invertEdits(); + } + size_t nedidx = 0, onedidx = 0; + bool olap = false; + // For each row, going left to right along Watson reference strand... + for(size_t i = 0; i < rdexrows_; i++) { + size_t diff = 1; // amount to shift to right for next round + size_t odiff = 1; // amount to shift to right for next round + // Unless there are insertions before the next position, we say + // that there is one cell in this row involved in the alignment + my_right = my_left + 1; + other_right = other_left + 1; + while(nedidx < ned_->size() && (*ned_)[nedidx].pos == i) { + if((*ned_)[nedidx].isRefGap()) { + // Next my_left will be in same column as this round + diff = 0; + } + nedidx++; + } + while(onedidx < res.ned_->size() && (*res.ned_)[onedidx].pos == i) { + if((*res.ned_)[onedidx].isRefGap()) { + // Next my_left will be in same column as this round + odiff = 0; + } + onedidx++; + } + if(i < rdexrows_ - 1) { + // See how many inserts there are before the next read + // character + size_t nedidx_next = nedidx; + size_t onedidx_next = onedidx; + while(nedidx_next < ned_->size() && + (*ned_)[nedidx_next].pos == i+1) + { + if((*ned_)[nedidx_next].isReadGap()) { + my_right++; + } + nedidx_next++; + } + while(onedidx_next < res.ned_->size() && + (*res.ned_)[onedidx_next].pos == i+1) + { + if((*res.ned_)[onedidx_next].isReadGap()) { + other_right++; + } + onedidx_next++; + } + } + // Contained? + olap = + (my_left >= other_left && my_right <= other_right) || + (other_left >= my_left && other_right <= my_right); + // Overlapping but not contained? + if(!olap) { + olap = + (my_left <= other_left && my_right > other_left) || + (other_left <= my_left && other_right > my_left); + } + if(olap) { + break; + } + // How to do adjust my_left and my_right + my_left = my_right + diff - 1; + other_left = other_right + odiff - 1; + } + if(!fw()) { + invertEdits(); + } + if(!res.fw()) { + res.invertEdits(); + } + return olap; +} + +#ifndef NDEBUG + +/** + * Assuming this AlnRes is an alignment for 'rd', check that the alignment and + * 'rd' are compatible with the corresponding reference sequence. + */ +bool AlnRes::matchesRef( + const Read& rd, + const BitPairReference& ref, + BTDnaString& rf, + BTDnaString& rdseq, + BTString& qseq, + SStringExpandable& raw_refbuf, + SStringExpandable& destU32, + EList& matches, + SStringExpandable& raw_refbuf2, + EList& reflens, + EList& refoffs) +{ + assert(!empty()); + assert(repOk()); + assert(refcoord_.inited()); + size_t rdlen = rd.length(); + bool fw = refcoord_.fw(); + if(!fw) { + assert_lt(trim3p_, rdlen); + Edit::invertPoss(const_cast&>(*ned_), rdlen - trim5p_ - trim3p_, false); + } + size_t refallen = 0; + reflens.clear(); refoffs.clear(); + int64_t reflen = 0; + int64_t refoff = refcoord_.off(); + refoffs.push_back((uint32_t)refoff); + size_t eidx = 0; + assert_lt(trim5p_ + trim3p_, rdlen); + for(size_t i = 0; i < rdlen - trim5p_ - trim3p_; i++, reflen++, refoff++) { + while(eidx < ned_->size() && (*ned_)[eidx].pos == i) { + if((*ned_)[eidx].isReadGap()) { + reflen++; + refoff++; + } else if((*ned_)[eidx].isRefGap()) { + reflen--; + refoff--; + } + if((*ned_)[eidx].isSpliced()) { + assert_gt(reflen, 0); + refallen += (uint32_t)reflen; + reflens.push_back((uint32_t)reflen); + reflen = 0; + refoff += (*ned_)[eidx].splLen; + assert_gt(refoff, 0); + refoffs.push_back((uint32_t)refoff); + } + eidx++; + } + } + assert_gt(reflen, 0); + refallen += (uint32_t)reflen; + reflens.push_back((uint32_t)reflen); + assert_gt(reflens.size(), 0); + assert_gt(refoffs.size(), 0); + assert_eq(reflens.size(), refoffs.size()); + if(!fw) { + assert_lt(trim3p_, rdlen); + Edit::invertPoss(const_cast&>(*ned_), rdlen - trim5p_ - trim3p_, false); + } + + // Adjust reference string length according to edits +#ifndef NDEBUG + if(reflens.size() == 1) { + assert_eq(refallen, refNucExtent()); + } +#endif + + assert_geq(refcoord_.ref(), 0); + int nsOnLeft = 0; + if(refcoord_.off() < 0) { + nsOnLeft = -((int)refcoord_.off()); + } + raw_refbuf.resize(refallen); + raw_refbuf.clear(); + raw_refbuf2.clear(); + for(size_t i = 0; i < reflens.size(); i++) { + assert_gt(reflens[i], 0); +#ifndef NDEBUG + if(i > 0) { + assert_gt(refoffs[i], refoffs[i-1]); + } +#endif + raw_refbuf2.resize(reflens[i] + 16); + raw_refbuf2.clear(); + int off = ref.getStretch( + reinterpret_cast(raw_refbuf2.wbuf()), + (size_t)refcoord_.ref(), + (size_t)max(refoffs[i], 0), + reflens[i], + destU32); + assert_leq(off, 16); + raw_refbuf.append(raw_refbuf2.wbuf() + off, reflens[i]); + } + char *refbuf = raw_refbuf.wbuf(); + size_t trim5 = 0, trim3 = 0; + if(trimSoft_) { + trim5 += trim5p_; + trim3 += trim3p_; + } + if(pretrimSoft_) { + trim5 += pretrim5p_; + trim3 += pretrim3p_; + } + rf.clear(); + rdseq.clear(); + rdseq = rd.patFw; + if(!fw) { + rdseq.reverseComp(false); + } + assert_eq(rdrows_, rdseq.length()); + // rdseq is the nucleotide sequence from upstream to downstream on the + // Watson strand. ned_ are the nucleotide edits from upstream to + // downstream. rf contains the reference characters. + assert(Edit::repOk(*ned_, rdseq, fw, trim5, trim3)); + Edit::toRef(rdseq, *ned_, rf, fw, trim5, trim3); + assert_eq(refallen, rf.length()); + matches.clear(); + bool matchesOverall = true; + matches.resize(refallen); + matches.fill(true); + for(size_t i = 0; i < refallen; i++) { + if((int)i < nsOnLeft) { + if((int)rf[i] != 4) { + matches[i] = false; + matchesOverall = false; + } + } else { + if((int)rf[i] != (int)refbuf[i-nsOnLeft]) { + matches[i] = false; + matchesOverall = false; + } + } + } + if(!matchesOverall) { + // Print a friendly message showing the difference between the + // reference sequence obtained with Edit::toRef and the actual + // reference sequence + cerr << endl; + Edit::printQAlignNoCheck( + cerr, + " ", + rdseq, + *ned_); + cerr << " "; + for(size_t i = 0; i < refallen; i++) { + cerr << (matches[i] ? " " : "*"); + } + cerr << endl; + cerr << " "; + for(size_t i = 0; i < refallen-nsOnLeft; i++) { + cerr << "ACGTN"[(int)refbuf[i]]; + } + cerr << endl; + Edit::printQAlign( + cerr, + " ", + rdseq, + *ned_); + cerr << endl; + } + return matchesOverall; +} + +#endif /*ndef NDEBUG*/ + +#define COPY_BUF() { \ + char *bufc = buf; \ + while(*bufc != '\0') { \ + *occ = *bufc; \ + occ++; \ + bufc++; \ + } \ +} + +/** + * Initialized the stacked alignment with respect to a read string, a list of + * edits (expressed left-to-right), and integers indicating how much hard and + * soft trimming has occurred on either end of the read. + * + * s: read sequence + * ed: all relevant edits, including ambiguous nucleotides + * trimLS: # bases soft-trimmed from LHS + * trimLH: # bases hard-trimmed from LHS + * trimRS: # bases soft-trimmed from RHS + * trimRH: # bases hard-trimmed from RHS + */ +void StackedAln::init( + const BTDnaString& s, + const EList& ed, + size_t trimLS, + size_t trimLH, + size_t trimRS, + size_t trimRH) +{ + trimLS_ = trimLS; + trimLH_ = trimLH; + trimRS_ = trimRS; + trimRH_ = trimRH; + ASSERT_ONLY(size_t ln_postsoft = s.length() - trimLS - trimRS); + stackRef_.clear(); + stackRel_.clear(); + stackSNP_.clear(); + stackRead_.clear(); + size_t rdoff = trimLS; + for(size_t i = 0; i < ed.size(); i++) { + assert_lt(ed[i].pos, ln_postsoft); + size_t pos = ed[i].pos + trimLS; + while(rdoff < pos) { + int c = s[rdoff++]; + assert_range(0, 4, c); + stackRef_.push_back("ACGTN"[c]); + stackRel_.push_back('='); + stackSNP_.push_back(false); + stackRead_.push_back("ACGTN"[c]); + } + if(ed[i].isMismatch()) { + int c = s[rdoff++]; + assert_range(0, 4, c); + assert_eq(c, asc2dna[(int)ed[i].qchr]); + assert_neq(c, asc2dna[(int)ed[i].chr]); + stackRef_.push_back(ed[i].chr); + stackRel_.push_back('X'); + stackSNP_.push_back(ed[i].snpID != (uint32_t)INDEX_MAX); + stackRead_.push_back("ACGTN"[c]); + } else if(ed[i].isRefGap()) { + int c = s[rdoff++]; + assert_range(0, 4, c); + assert_eq(c, asc2dna[(int)ed[i].qchr]); + stackRef_.push_back('-'); + stackRel_.push_back('I'); + stackSNP_.push_back(ed[i].snpID != (uint32_t)INDEX_MAX); + stackRead_.push_back("ACGTN"[c]); + } else if(ed[i].isReadGap()) { + stackRef_.push_back(ed[i].chr); + stackRel_.push_back('D'); + stackSNP_.push_back(ed[i].snpID != (uint32_t)INDEX_MAX); + stackRead_.push_back('-'); + } else if(ed[i].isSpliced()) { + stackRef_.push_back('N'); + stackRel_.push_back('N'); + stackSNP_.push_back(false); + stackRead_.push_back('N'); + assert_gt(ed[i].splLen, 0); + stackSkip_.push_back(ed[i].splLen); + } + } + while(rdoff < s.length() - trimRS) { + int c = s[rdoff++]; + assert_range(0, 4, c); + stackRef_.push_back("ACGTN"[c]); + stackRel_.push_back('='); + stackSNP_.push_back(false); + stackRead_.push_back("ACGTN"[c]); + } + inited_ = true; +} + +/** + * Left-align all the gaps. If this changes the alignment and the CIGAR or + * MD:Z strings have already been calculated, this renders them invalid. + * + * We left-align gaps with in the following way: for each gap, we check + * whether the character opposite the rightmost gap character is the same + * as the character opposite the character just to the left of the gap. If + * this is the case, we can slide the gap to the left and make the + * rightmost position previously covered by the gap into a non-gap. + * + * This scheme allows us to push the gap past a mismatch. BWA does seem to + * allow this. It's not clear that Bowtie 2 should, since moving the + * mismatch could cause a mismatch with one base quality to be replaced + * with a mismatch with a different base quality. + */ +void StackedAln::leftAlign(bool pastMms) { + assert(inited_); + bool changed = false; + size_t ln = stackRef_.size(); + // Scan left-to-right + for(size_t i = 0; i < ln; i++) { + int rel = stackRel_[i]; + if(rel != '=' && rel != 'X' && rel != 'N') { + // Neither a match nor a mismatch - must be a gap + assert(rel == 'I' || rel == 'D'); + if(stackSNP_[i]) continue; + size_t glen = 1; + // Scan further right to measure length of gap + for(size_t j = i+1; j < ln; j++) { + if(rel != (int)stackRel_[j]) break; + glen++; + } + // We've identified a gap of type 'rel' (D = deletion or read + // gap, I = insertion or ref gap) with length 'glen'. Now we + // can try to slide it to the left repeatedly. + size_t l = i - 1; + size_t r = l + glen; + EList& gp = ((rel == 'I') ? stackRef_ : stackRead_); + const EList& ngp = ((rel == 'I') ? stackRead_ : stackRef_); + while(l > 0 && ngp[l] == ngp[r]) { + if(stackRel_[l] == 'I' || stackRel_[l] == 'D') break; + assert(stackRel_[l] == '=' || stackRel_[l] == 'X' || stackRel_[l] == 'N'); + assert(stackRel_[r] == 'D' || stackRel_[r] == 'I'); + if(!pastMms && (stackRel_[l] == 'X' || stackRel_[l] == 'N')) { + break; + } + swap(gp[l], gp[r]); + swap(stackRel_[l], stackRel_[r]); + assert_neq('-', gp[r]); + assert_eq('-', gp[l]); + l--; r--; + changed = true; + } + i += (glen-1); + } + } + if(changed) { + cigCalc_ = mdzCalc_ = false; + } +} + +/** + * Build the CIGAR list, if it hasn't already built. Returns true iff it + * was built for the first time. + */ +bool StackedAln::buildCigar(bool xeq) { + assert(inited_); + if(cigCalc_) { + return false; // already done + } + cigOp_.clear(); + cigRun_.clear(); + if(trimLS_ > 0) { + cigOp_.push_back('S'); + cigRun_.push_back(trimLS_); + } + size_t numSkips = 0; + size_t ln = stackRef_.size(); + for(size_t i = 0; i < ln; i++) { + char op = stackRel_[i]; + if(!xeq && (op == 'X' || op == '=')) { + op = 'M'; + } + size_t run; + if(op != 'N') { + run = 1; + for(; i + run < ln; run++) { + char op2 = stackRel_[i + run]; + if(!xeq && (op2 == 'X' || op2 == '=')) { + op2 = 'M'; + } + if(op2 != op) { + break; + } + } + i += (run-1); + } else { + assert_lt(numSkips, stackSkip_.size()); + run = stackSkip_[numSkips]; + numSkips++; + } + cigOp_.push_back(op); + cigRun_.push_back(run); + } + if(trimRS_ > 0) { + cigOp_.push_back('S'); + cigRun_.push_back(trimRS_); + } + cigCalc_ = true; + return true; +} + +/** + * Build the CIGAR list, if it hasn't already built. Returns true iff it + * was built for the first time. + */ +bool StackedAln::buildMdz() { + assert(inited_); + if(mdzCalc_) { + return false; // already done + } + mdzOp_.clear(); + mdzChr_.clear(); + mdzRun_.clear(); + size_t ln = stackRef_.size(); + for(size_t i = 0; i < ln; i++) { + char op = stackRel_[i]; + if(op == '=') { + size_t run = 1; + size_t ninserts = 0; + size_t nskips = 0; + // Skip over matches and insertions (ref gaps) + for(; i+run < ln; run++) { + if(stackRel_[i + run] == '=') { + // do nothing + } else if(stackRel_[i + run] == 'I') { + ninserts++; + } else if(stackRel_[i + run] == 'N') { + nskips++; + } else { + break; + } + } + i += (run - 1); + mdzOp_.push_back('='); // = X or G + mdzChr_.push_back('-'); + mdzRun_.push_back(run - ninserts - nskips); + } else if(op == 'X') { + assert_neq(stackRef_[i], stackRead_[i]); + mdzOp_.push_back('X'); // = X or G + mdzChr_.push_back(stackRef_[i]); + mdzRun_.push_back(1); + } else if(op == 'D') { + assert_neq('-', stackRef_[i]); + mdzOp_.push_back('G'); // = X or G + mdzChr_.push_back(stackRef_[i]); + mdzRun_.push_back(1); + } + } + mdzCalc_ = true; + return true; +} + +/** + * Write a CIGAR representation of the alignment to the given string and/or + * char buffer. + */ +void StackedAln::writeCigar( + BTString* o, // if non-NULL, string to append to + char* occ) const // if non-NULL, character string to append to +{ + const EList& op = cigOp_; + const EList& run = cigRun_; + assert_eq(op.size(), run.size()); + if(o != NULL || occ != NULL) { + char buf[128]; + ASSERT_ONLY(bool printed = false); + for(size_t i = 0; i < op.size(); i++) { + size_t r = run[i]; + if(r > 0) { + itoa10(r, buf); + ASSERT_ONLY(printed = true); + if(o != NULL) { + o->append(buf); + o->append(op[i]); + } + if(occ != NULL) { + COPY_BUF(); + *occ = op[i]; + occ++; + } + } + } + assert(printed); + if(occ != NULL) { + *occ = '\0'; + } + } +} + +void StackedAln::writeCigar(Alignment* o, char* occ) const { + const EList& op = cigOp_; + const EList& run = cigRun_; + assert_eq(op.size(), run.size()); + if(o != NULL || occ != NULL) { + char buf[128]; + ASSERT_ONLY(bool printed = false); + o->cigarSegments.reserve(op.size()); + for(size_t i = 0; i < op.size(); i++) { + size_t r = run[i]; + if(r > 0) { + itoa10(r, buf); + ASSERT_ONLY(printed = true); + if(o != NULL) { + o->cigarString.append(buf); + o->cigarString.append(op[i]); + o->cigarSegments.emplace_back(r, op[i]); + o->cigarLength += r; + } + if(occ != NULL) { + COPY_BUF(); + *occ = op[i]; + occ++; + } + } + } + assert(printed); + if(occ != NULL) { + *occ = '\0'; + } + } +} + +/** + * Write an MD:Z representation of the alignment to the given string and/or + * char buffer. + */ +void StackedAln::writeMdz(BTString* o, char* occ) const { + char buf[128]; + bool mm_last = false; + bool rdgap_last = false; + bool first_print = true; + const EList& op = mdzOp_; + const EList& ch = mdzChr_; + const EList& run = mdzRun_; + for(size_t i = 0; i < op.size(); i++) { + size_t r = run[i]; + if(r > 0) { + if(op[i] == '=') { + // Write run length + itoa10(r, buf); + if(o != NULL) { o->append(buf); } + if(occ != NULL) { COPY_BUF(); } + first_print = false; + mm_last = false; + rdgap_last = false; + } else if(op[i] == 'X') { + if(o != NULL) { + if(rdgap_last || mm_last || first_print) { + o->append('0'); + } + o->append(ch[i]); + } + if(occ != NULL) { + if(rdgap_last || mm_last || first_print) { + *occ = '0'; + occ++; + } + *occ = ch[i]; + occ++; + } + first_print = false; + mm_last = true; + rdgap_last = false; + } else if(op[i] == 'G') { + if(o != NULL) { + if(mm_last || first_print) { + o->append('0'); + } + if(!rdgap_last) { + o->append('^'); + } + o->append(ch[i]); + } + if(occ != NULL) { + if(mm_last || first_print) { + *occ = '0'; occ++; + } + if(!rdgap_last) { + *occ = '^'; occ++; + } + *occ = ch[i]; + occ++; + } + first_print = false; + mm_last = false; + rdgap_last = true; + } + } // if r > 0 + } // for loop over ops + if(mm_last || rdgap_last) { + if(o != NULL) { o->append('0'); } + if(occ != NULL) { *occ = '0'; occ++; } + } + if(occ != NULL) { *occ = '\0'; } +} + +/** + * Print the sequence for the read that aligned using A, C, G and + * T. This will simply print the read sequence (or its reverse + * complement). + */ +void AlnRes::printSeq( + const Read& rd, // read + const BTDnaString* dns, // already-decoded nucleotides + BTString& o) const // buffer to write to +{ + assert(!rd.patFw.empty()); + ASSERT_ONLY(size_t written = 0); + // Print decoded nucleotides + assert(dns != NULL); + size_t len = dns->length(); + size_t st = 0; + size_t en = len; + for(size_t i = st; i < en; i++) { + int c = dns->get(i); + assert_range(0, 3, c); + o.append("ACGT"[c]); + ASSERT_ONLY(written++); + } +#ifndef NDEBUG + for(size_t i = 0; i < ned_->size(); i++) { + if((*ned_)[i].isReadGap()) { + assert_leq((*ned_)[i].pos, dns->length()); + } else { + assert_lt((*ned_)[i].pos, dns->length()); + } + } +#endif +} + +/** + * Print the quality string for the read that aligned. This will simply print + * the read qualities (or their reverse). + */ +void AlnRes::printQuals( + const Read& rd, // read + const BTString* dqs, // already-decoded qualities + BTString& o) const // output stream to write to +{ + assert(dqs != NULL); + size_t len = dqs->length(); + // Print decoded qualities from upstream to downstream Watson + for(size_t i = 1; i < len-1; i++) { + o.append(dqs->get(i)); + } +} + +/** + * Add all of the cells involved in the given alignment to the database. + */ +void RedundantAlns::add(const AlnRes& res) { + assert(!cells_.empty()); + TRefOff left = res.refoff(), right; + const size_t len = res.readExtentRows(); + if(!res.fw()) { + const_cast(res).invertEdits(); + } + const EList& ned = res.ned(); + size_t nedidx = 0; + assert_leq(len, cells_.size()); + // For each row... + for(size_t i = 0; i < len; i++) { + size_t diff = 1; // amount to shift to right for next round + right = left + 1; + while(nedidx < ned.size() && ned[nedidx].pos == i) { + if(ned[nedidx].isRefGap()) { + // Next my_left will be in same column as this round + diff = 0; + } + nedidx++; + } + if(i < len - 1) { + // See how many inserts there are before the next read + // character + size_t nedidx_next = nedidx; + while(nedidx_next < ned.size() && ned[nedidx_next].pos == i+1) + { + if(ned[nedidx_next].isReadGap()) { + right++; + } + nedidx_next++; + } + } + for(TRefOff j = left; j < right; j++) { + // Add to db + RedundantCell c(res.refid(), res.fw(), j, i); + ASSERT_ONLY(bool ret =) cells_[i].insert(c); + assert(ret); + } + left = right + diff - 1; + } + if(!res.fw()) { + const_cast(res).invertEdits(); + } +} + +/** + * Return true iff the given alignment has at least one cell that overlaps + * one of the cells in the database. + */ +bool RedundantAlns::overlap(const AlnRes& res) { + assert(!cells_.empty()); + TRefOff left = res.refoff(), right; + const size_t len = res.readExtentRows(); + if(!res.fw()) { + const_cast(res).invertEdits(); + } + const EList& ned = res.ned(); + size_t nedidx = 0; + // For each row... + bool olap = false; + assert_leq(len, cells_.size()); + for(size_t i = 0; i < len; i++) { + size_t diff = 1; // amount to shift to right for next round + right = left + 1; + while(nedidx < ned.size() && ned[nedidx].pos == i) { + if(ned[nedidx].isRefGap()) { + // Next my_left will be in same column as this round + diff = 0; + } + nedidx++; + } + if(i < len - 1) { + // See how many inserts there are before the next read + // character + size_t nedidx_next = nedidx; + while(nedidx_next < ned.size() && ned[nedidx_next].pos == i+1) + { + if(ned[nedidx_next].isReadGap()) { + right++; + } + nedidx_next++; + } + } + for(TRefOff j = left; j < right; j++) { + // Add to db + RedundantCell c(res.refid(), res.fw(), j, i); + if(cells_[i].contains(c)) { + olap = true; + break; + } + } + if(olap) { + break; + } + left = right + diff - 1; + } + if(!res.fw()) { + const_cast(res).invertEdits(); + } + return olap; +} + +/** + * Given all the paired and unpaired results involving mates #1 and #2, + * calculate best and second-best scores for both mates. These are + * used for future MAPQ calculations. + */ +void AlnSetSumm::init( + const Read* rd1, + const Read* rd2, + const EList* rs1, + const EList* rs2, + const EList* rs1u, + const EList* rs2u, + bool exhausted1, + bool exhausted2, + TRefId orefid, + TRefOff orefoff, + bool repeat) +{ + assert(rd1 != NULL || rd2 != NULL); + assert((rs1 == NULL) == (rs2 == NULL)); + AlnScore best[2], secbest[2], bestPaired, secbestPaired; + size_t szs[2]; + best[0].invalidate(); secbest[0].invalidate(); + best[1].invalidate(); secbest[1].invalidate(); + bestPaired.invalidate(); secbestPaired.invalidate(); + bool paired = (rs1 != NULL && rs2 != NULL); + szs[0] = szs[1] = 0; + TNumAlns numAlns1 = 0, numAlns2 = 0, numAlnsPaired = 0; + if(paired) { + // Paired alignments + assert_eq(rs1->size(), rs2->size()); + szs[0] = szs[1] = rs1->size(); + assert_gt(szs[0], 0); + numAlnsPaired = szs[0]; + for(size_t i = 0; i < rs1->size(); i++) { + AlnScore sc = (*rs1)[i].score() + (*rs2)[i].score(); + if(sc > bestPaired) { + secbestPaired = bestPaired; + bestPaired = sc; + assert(VALID_AL_SCORE(bestPaired)); + } else if(sc > secbestPaired) { + secbestPaired = sc; + assert(VALID_AL_SCORE(bestPaired)); + assert(VALID_AL_SCORE(secbestPaired)); + } + } + } + for(int j = 0; j < 2; j++) { + const EList* rs = (j == 0 ? rs1u : rs2u); + if(rs == NULL) { + continue; + } + assert(rs != NULL); + szs[j] = rs->size(); + if(j == 0) { + numAlns1 = szs[j]; + } else { + numAlns2 = szs[j]; + } + //assert_gt(szs[j], 0); + for(size_t i = 0; i < rs->size(); i++) { + AlnScore sc = (*rs)[i].score(); + if(sc > best[j]) { + secbest[j] = best[j]; + best[j] = sc; + assert(VALID_AL_SCORE(best[j])); + } else if(sc > secbest[j]) { + secbest[j] = sc; + assert(VALID_AL_SCORE(best[j])); + assert(VALID_AL_SCORE(secbest[j])); + } + } + } + if(szs[0] > 0 || szs[1] > 0) { + init( + best[0], + secbest[0], + best[1], + secbest[1], + bestPaired, + secbestPaired, + (szs[0] == 0) ? 0 : (szs[0] - 1), + (szs[1] == 0) ? 0 : (szs[1] - 1), + paired, + exhausted1, + exhausted2, + orefid, + orefoff, + repeat, + numAlns1, + numAlns2, + numAlnsPaired); + } else { + reset(); + orefid_ = orefid; + orefoff_ = orefoff; + repeat_ = repeat; + } +} + +/** + * Print out string representation of YF:i flag for indicating whether and + * why the mate was filtered. + */ +bool AlnFlags::printYF(BTString& o, bool first) const { + const char *flag = ""; + if (!lenfilt_) flag = "LN"; + else if(!nfilt_ ) flag = "NS"; + else if(!scfilt_ ) flag = "SC"; + else if(!qcfilt_ ) flag = "QC"; + if(*flag > 0) { + if(!first) o.append('\t'); + o.append("YF:Z:"); + o.append(flag); + return false; + } + return true; +} + + +/** + * Print out string representation of YM:i flag for indicating with the + * mate per se aligned repetitively. + */ +void AlnFlags::printYM(BTString& o) const { + o.append("YM:i:"); + o.append(maxed() ? '1' : '0'); +} + +/** + * Print out string representation of YM:i flag for indicating with the + * pair containing the mate aligned repetitively. + */ +void AlnFlags::printYP(BTString& o) const { + o.append("YP:i:"); + o.append(maxedPair() ? '1' : '0'); +} + +/** + * Print out string representation of these flags. + */ +void AlnFlags::printYT(BTString& o) const { + o.append("YT:Z:"); + if(alignedConcordant()) { + o.append("CP"); + } else if(alignedDiscordant()) { + o.append("DP"); + } else if(alignedUnpairedMate()) { + o.append("UP"); + } else if(alignedUnpaired()) { + o.append("UU"); + } else { throw 1; } +} + +#ifdef ALIGNER_RESULT_MAIN + +#include "mem_ids.h" + +int main() { + EList op; + EList ch; + EList run; + { + // On top of each other, same length + cerr << "Test case 1, simple overlap 1 ... "; + AlnRes res1; + res1.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, true), + false); + AlnRes res2; + res2.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, true), + false); + assert(res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "10M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "10=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "10M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "10=")); + + char buf3[1024]; + res1.printMD(false, false, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "10")); + res1.printMD(false, true, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "8")); + + char buf4[1024]; + res2.printMD(false, false, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "10")); + res2.printMD(false, true, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "8")); + + cerr << "PASSED" << endl; + } + + { + // On top of each other, different lengths + cerr << "Test case 2, simple overlap 2 ... "; + AlnRes res1; + res1.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, true), + false); + AlnRes res2; + res2.init( + 11, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, true), + false); + assert(res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(11); + ra.add(res1); + assert(ra.overlap(res1)); + assert(ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "10M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "10=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "11M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "11=")); + + char buf3[1024]; + res1.printMD(false, false, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "10")); + res1.printMD(false, true, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "8")); + + char buf4[1024]; + res2.printMD(false, false, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "11")); + res2.printMD(false, true, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "9")); + + cerr << "PASSED" << endl; + } + + { + // Different references + cerr << "Test case 3, simple overlap 3 ... "; + AlnRes res1; + res1.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 1, true), + false); + AlnRes res2; + res2.init( + 11, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, true), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(11); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + cerr << "PASSED" << endl; + } + + { + // Different references + cerr << "Test case 4, simple overlap 4 ... "; + AlnRes res1; + res1.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, true), + false); + AlnRes res2; + res2.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(1, 0, true), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + cerr << "PASSED" << endl; + } + + { + // Different strands + cerr << "Test case 5, simple overlap 5 ... "; + AlnRes res1; + res1.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, true), + false); + AlnRes res2; + res2.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 0, false), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + cerr << "PASSED" << endl; + } + + { + // Different strands + cerr << "Test case 6, simple overlap 6 ... "; + EList ned1(RES_CAT); + ned1.expand(); + // 1 step to the right in the middle of the alignment + ned1.back().init(5, 'A' /*chr*/, '-' /*qchr*/, EDIT_TYPE_READ_GAP); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, false), + false); + AlnRes res2; + res2.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 6, false), + false); + assert(res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M1D5M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=1D5=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "10M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "10=")); + + char buf3[1024]; + res1.printMD(false, false, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "5^A5")); + res1.printMD(false, true, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "4^A4")); + + char buf4[1024]; + res2.printMD(false, false, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "10")); + res2.printMD(false, true, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "8")); + + cerr << "PASSED" << endl; + } + + { + // Different strands + cerr << "Test case 7, simple overlap 7 ... "; + EList ned1(RES_CAT); + // 3 steps to the right in the middle of the alignment + ned1.push_back(Edit(5, 'A', '-', EDIT_TYPE_READ_GAP)); + ned1.push_back(Edit(5, 'C', '-', EDIT_TYPE_READ_GAP)); + ned1.push_back(Edit(5, 'G', '-', EDIT_TYPE_READ_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, false), + false); + AlnRes res2; + res2.init( + 10, + AlnScore(), + NULL, + NULL, + NULL, + Coord(0, 6, false), + false); + assert(res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M3D5M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=3D5=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "10M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "10=")); + + char buf3[1024]; + res1.printMD(false, false, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "5^GCA5")); + res1.printMD(false, true, op, ch, run, NULL, buf3); + assert_eq(0, strcmp(buf3, "4^GCA4")); + + char buf4[1024]; + res2.printMD(false, false, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "10")); + res2.printMD(false, true, op, ch, run, NULL, buf4); + assert_eq(0, strcmp(buf4, "8")); + + cerr << "PASSED" << endl; + } + + { + // Both with horizontal movements; overlap + cerr << "Test case 8, simple overlap 8 ... "; + EList ned1(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned1.push_back(Edit(5, 'A', '-', EDIT_TYPE_READ_GAP)); + ned1.push_back(Edit(5, 'C', '-', EDIT_TYPE_READ_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, false), + false); + EList ned2(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned2.push_back(Edit(5, 'A', '-', EDIT_TYPE_READ_GAP)); + ned2.push_back(Edit(5, 'C', '-', EDIT_TYPE_READ_GAP)); + AlnRes res2; + res2.init( + 10, + AlnScore(), + &ned2, + NULL, + NULL, + Coord(0, 6, false), + false); + assert(res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M2D5M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=2D5=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "5M2D5M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "5=2D5=")); + + cerr << "PASSED" << endl; + } + + { + // Both with horizontal movements; no overlap + cerr << "Test case 9, simple overlap 9 ... "; + EList ned1(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned1.push_back(Edit(6, 'A', '-', EDIT_TYPE_READ_GAP)); + ned1.push_back(Edit(6, 'C', '-', EDIT_TYPE_READ_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, true), + false); + EList ned2(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned2.push_back(Edit(5, 'A', '-', EDIT_TYPE_READ_GAP)); + ned2.push_back(Edit(5, 'C', '-', EDIT_TYPE_READ_GAP)); + AlnRes res2; + res2.init( + 10, + AlnScore(), + &ned2, + NULL, + NULL, + Coord(0, 6, true), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "6M2D4M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "6=2D4=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "5M2D5M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "5=2D5=")); + + cerr << "PASSED" << endl; + } + + { + // Both with horizontal movements; no overlap. Reverse strand. + cerr << "Test case 10, simple overlap 10 ... "; + EList ned1(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned1.push_back(Edit(5, 'A', '-', EDIT_TYPE_READ_GAP)); + ned1.push_back(Edit(5, 'C', '-', EDIT_TYPE_READ_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, false), + false); + EList ned2(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned2.push_back(Edit(6, 'A', '-', EDIT_TYPE_READ_GAP)); + ned2.push_back(Edit(6, 'C', '-', EDIT_TYPE_READ_GAP)); + AlnRes res2; + res2.init( + 10, + AlnScore(), + &ned2, + NULL, + NULL, + Coord(0, 6, false), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M2D5M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=2D5=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "4M2D6M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "4=2D6=")); + + cerr << "PASSED" << endl; + } + + { + // Both with vertical movements; no overlap + cerr << "Test case 11, simple overlap 11 ... "; + EList ned1(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned1.push_back(Edit(5, '-', 'A', EDIT_TYPE_REF_GAP)); + ned1.push_back(Edit(6, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, true), + false); + EList ned2(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned2.push_back(Edit(6, '-', 'A', EDIT_TYPE_REF_GAP)); + ned2.push_back(Edit(7, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res2; + res2.init( + 10, + AlnScore(), + &ned2, + NULL, + NULL, + Coord(0, 6, true), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M2I3M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=2I3=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "6M2I2M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "6=2I2=")); + + cerr << "PASSED" << endl; + } + + { + // Both with vertical movements; no overlap + cerr << "Test case 12, simple overlap 12 ... "; + EList ned1(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned1.push_back(Edit(5, '-', 'A', EDIT_TYPE_REF_GAP)); + ned1.push_back(Edit(6, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, true), + false); + EList ned2(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned2.push_back(Edit(5, '-', 'A', EDIT_TYPE_REF_GAP)); + ned2.push_back(Edit(6, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res2; + res2.init( + 10, + AlnScore(), + &ned2, + NULL, + NULL, + Coord(0, 6, true), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M2I3M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=2I3=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "5M2I3M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "5=2I3=")); + + cerr << "PASSED" << endl; + } + + { + // Both with vertical movements; overlap + cerr << "Test case 13, simple overlap 13 ... "; + EList ned1(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned1.push_back(Edit(5, '-', 'A', EDIT_TYPE_REF_GAP)); + ned1.push_back(Edit(6, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, true), + false); + EList ned2(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned2.push_back(Edit(4, '-', 'A', EDIT_TYPE_REF_GAP)); + ned2.push_back(Edit(5, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res2; + res2.init( + 10, + AlnScore(), + &ned2, + NULL, + NULL, + Coord(0, 6, true), + false); + assert(res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M2I3M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=2I3=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "4M2I4M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "4=2I4=")); + + cerr << "PASSED" << endl; + } + + { + // Not even close + cerr << "Test case 14, simple overlap 14 ... "; + EList ned1(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned1.push_back(Edit(5, '-', 'A', EDIT_TYPE_REF_GAP)); + ned1.push_back(Edit(6, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res1; + res1.init( + 10, + AlnScore(), + &ned1, + NULL, + NULL, + Coord(0, 5, true), + false); + EList ned2(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned2.push_back(Edit(4, '-', 'A', EDIT_TYPE_REF_GAP)); + ned2.push_back(Edit(5, '-', 'C', EDIT_TYPE_REF_GAP)); + AlnRes res2; + res2.init( + 10, + AlnScore(), + &ned2, + NULL, + NULL, + Coord(0, 400, true), + false); + assert(!res1.overlap(res2)); + + // Try again, but using the redundant-alignment database + RedundantAlns ra; + ra.reset(); + ra.init(10); + ra.add(res1); + assert(ra.overlap(res1)); + assert(!ra.overlap(res2)); + + char buf1[1024]; + res1.printCigar(false, false, false, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5M2I3M")); + res1.printCigar(false, false, true, op, run, NULL, buf1); + assert_eq(0, strcmp(buf1, "5=2I3=")); + + char buf2[1024]; + res2.printCigar(false, false, false, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "4M2I4M")); + res2.printCigar(false, false, true, op, run, NULL, buf2); + assert_eq(0, strcmp(buf2, "4=2I4=")); + + cerr << "PASSED" << endl; + } + + { + cerr << "Test case 15, CIGAR string with mismatches ... "; + EList ned(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned.push_back(Edit(0, 'C', 'A', EDIT_TYPE_MM)); + ned.push_back(Edit(4, '-', 'C', EDIT_TYPE_REF_GAP)); + ned.push_back(Edit(6, '-', 'C', EDIT_TYPE_REF_GAP)); + ned.push_back(Edit(7, '-', 'C', EDIT_TYPE_REF_GAP)); + ned.push_back(Edit(9, '-', 'A', EDIT_TYPE_READ_GAP)); + ned.push_back(Edit(9, '-', 'A', EDIT_TYPE_READ_GAP)); + ned.push_back(Edit(9, '-', 'A', EDIT_TYPE_READ_GAP)); + ned.push_back(Edit(9, '-', 'A', EDIT_TYPE_READ_GAP)); + ned.push_back(Edit(10, '-', 'A', EDIT_TYPE_MM)); + AlnRes res; res.init( + 11, + AlnScore(), + &ned, + NULL, + NULL, + Coord(0, 44, true), + false); + char buf[1024]; + res.printCigar(false, false, false, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "4M1I1M2I1M4D2M")); + res.printCigar(false, false, true, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "1X3=1I1=2I1=4D1=1X")); + cerr << "PASSED" << endl; + } + + { + cerr << "Test case 17, Overhang ... "; + EList ned(RES_CAT); + // 2 steps to the right in the middle of the alignment + ned.push_back(Edit(0, 'N', 'A', EDIT_TYPE_MM)); + ned.push_back(Edit(5, 'C', 'A', EDIT_TYPE_MM)); + AlnRes res; res.init( + 10, + AlnScore(), + &ned, + NULL, + NULL, + Coord(0, -1, true), + false); + + char buf[1024]; + res.printCigar(false, false, false, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "10M")); + res.printCigar(false, false, true, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "1X4=1X4=")); + res.printMD(false, false, op, ch, run, NULL, buf); + assert_eq(0, strcmp(buf, "0N4C4")); + + #if 0 + AlnRes res2(res); + // Now soft-clip away the overhang + res2.clipOutside( + true, // soft clip + 0, // ref begins + 40); // ref ends (excl) + res2.printCigar(false, false, false, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "1S9M")); + res2.printCigar(false, false, true, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "4=1X4=")); + res2.printMD(false, false, op, ch, run, NULL, buf); + assert_eq(0, strcmp(buf, "4C4")); + + AlnRes res3 = res; + // Now hard-clip away the overhang + res3.clipOutside( + false, // hard clip + 0, // ref begins + 40); // ref ends (excl) + res3.printCigar(false, false, false, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "9M")); + res3.printCigar(false, false, true, op, run, NULL, buf); + assert_eq(0, strcmp(buf, "4=1X4=")); + res3.printMD(false, false, op, ch, run, NULL, buf); + assert_eq(0, strcmp(buf, "4C4")); + #endif + + cerr << "PASSED" << endl; + } +} + +#endif /*def ALIGNER_RESULT_MAIN*/ diff --git a/aligner_result.h b/aligner_result.h new file mode 100644 index 0000000..745647e --- /dev/null +++ b/aligner_result.h @@ -0,0 +1,2325 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_RESULT_H_ +#define ALIGNER_RESULT_H_ + +#include +#include +#include "mem_ids.h" +#include "ref_coord.h" +#include "read.h" +#include "filebuf.h" +#include "ds.h" +#include "edit.h" +#include "limit.h" +#include "splice_site.h" +#include "alignment_3n.h" + +typedef int64_t TAlScore; + +#define VALID_AL_SCORE(x) ((x).score_ > MIN_I64) +#define VALID_SCORE(x) ((x) > MIN_I64) +#define INVALIDATE_SCORE(x) ((x) = MIN_I64) + +/** + * A generic score object for an alignment. Used for accounting during + * SW and elsewhere. Encapsulates the score, the number of N positions + * and the number gaps in the alignment. + * + * The scale for 'score' is such that a perfect alignment score is 0 + * and a score with non-zero penalty is less than 0. So differences + * between scores work as expected, but interpreting an individual + * score (larger is better) as a penalty (smaller is better) requires + * taking the absolute value. + */ +class AlnScore { + +public: + + /** + * Gapped scores are invalid until proven valid. + */ + inline AlnScore() { + reset(); + invalidate(); + assert(!valid()); + } + + /** + * Gapped scores are invalid until proven valid. + */ + inline AlnScore( + TAlScore score, + TAlScore ns, + TAlScore gaps, + bool repeat = false, + TAlScore splicescore = 0, + bool knownTranscripts = false, + bool nearSpliceSites = false, + int leftTrim = 0, + int rightTrim = 0) { + score_ = score; + ns_ = ns; + gaps_ = gaps; + repeat_ = repeat; + splicescore_ = splicescore; + knownTranscripts_ = knownTranscripts; + nearSpliceSites_ = nearSpliceSites; + leftTrim_ = leftTrim; + rightTrim_ = rightTrim; + hisat2_score_ = calculate_hisat2_score(); + assert(valid()); + } + + /** + * Reset the score. + */ + void reset() { + score_ = hisat2_score_ = ns_ = gaps_ = 0; + repeat_ = false; + splicescore_ = 0; + knownTranscripts_ = false; + nearSpliceSites_ = false; + leftTrim_ = 0; + rightTrim_ = 0; + } + + /** + * Return an invalid SwScore. + */ + inline static AlnScore INVALID() { + AlnScore s; + s.invalidate(); + assert(!s.valid()); + return s; + } + + /** + * Return true iff this score has a valid value. + */ + inline bool valid() const { + return score_ != MIN_I64; + } + + /** + * Make this score invalid (and therefore <= all other scores). + */ + inline void invalidate() { + score_ = MIN_I64; + assert(!valid()); + } + + /** + * Increment the number of gaps. If currently invalid, this makes + * the score valid with gaps == 1. + */ + inline void incNs(int nceil) { + if(++ns_ > nceil) { + invalidate(); + } + assert_lt(ns_, 0x7fffffff); + } + + /** + * Return true iff this score is > score o. + * Note: An "invalid" score is <= all other scores. + */ + inline bool operator>(const AlnScore& o) const { + if(!VALID_AL_SCORE(o)) { + if(!VALID_AL_SCORE(*this)) { + // both invalid + return false; + } else { + // I'm valid, other is invalid + return true; + } + } else if(!VALID_AL_SCORE(*this)) { + // I'm invalid, other is valid + return false; + } + return score_ > o.score_ || (score_ == o.score_ && hisat2_score_ > o.hisat2_score_); + } + + /** + * Scores are equal iff they're bitwise equal. + */ + inline AlnScore& operator=(const AlnScore& o) { + // Profiling shows many cache misses on following lines + gaps_ = o.gaps_; + ns_ = o.ns_; + score_ = o.score_; + repeat_ = o.repeat_; + hisat2_score_ = o.hisat2_score_; + splicescore_ = o.splicescore_; + knownTranscripts_ = o.knownTranscripts_; + nearSpliceSites_ = o.nearSpliceSites_; + leftTrim_ = o.leftTrim_; + rightTrim_ = o.rightTrim_; + assert_lt(ns_, 0x7fffffff); + return *this; + } + + /** + * Scores are equal iff they're bitwise equal. + */ + inline bool operator==(const AlnScore& o) const { + // Profiling shows cache misses on following line + return VALID_AL_SCORE(*this) && VALID_AL_SCORE(o) && score_ == o.score_ && hisat2_score_ == o.hisat2_score_; + } + + /** + * Return true iff the two scores are unequal. + */ + inline bool operator!=(const AlnScore& o) const { + return !(*this == o); + } + + /** + * Return true iff this score is >= score o. + */ + inline bool operator>=(const AlnScore& o) const { + if(!VALID_AL_SCORE(o)) { + if(!VALID_AL_SCORE(*this)) { + // both invalid + return false; + } else { + // I'm valid, other is invalid + return true; + } + } else if(!VALID_AL_SCORE(*this)) { + // I'm invalid, other is valid + return false; + } + return score_ > o.score_ || (score_ == o.score_ && hisat2_score_ >= o.hisat2_score_); + } + + /** + * Return true iff this score is < score o. + */ + inline bool operator<(const AlnScore& o) const { + return !operator>=(o); + } + + /** + * Return true iff this score is <= score o. + */ + inline bool operator<=(const AlnScore& o) const { + return !operator>(o); + } + + /** + * Calculate difference between two SwScores. + */ + inline AlnScore operator-(const AlnScore& o) const { + if(!VALID_AL_SCORE(*this)) return *this; + AlnScore s; + s.gaps_ = gaps_ - o.gaps_; + s.ns_ = ns_; + s.score_ = score_ - o.score_; + s.splicescore_ = splicescore_ - o.splicescore_; + assert_lt(s.ns_, 0x7fffffff); + return s; + } + + /** + * Calculate sum of two SwScores. + */ + inline AlnScore operator+(const AlnScore& o) const { + if(!VALID_AL_SCORE(*this)) return *this; + AlnScore s; + s.gaps_ = gaps_ + o.gaps_; + s.ns_ = ns_; + s.score_ = score_ + o.score_; + s.repeat_ = repeat_ | o.repeat_; + s.splicescore_ = splicescore_ + o.splicescore_; + s.hisat2_score_ = hisat2_score_ + o.hisat2_score_; + s.knownTranscripts_ = knownTranscripts_ | o.knownTranscripts_; + s.nearSpliceSites_ = nearSpliceSites_ | o.nearSpliceSites_; + s.leftTrim_ = leftTrim_ + o.leftTrim_; + s.rightTrim_ = rightTrim_ + o.rightTrim_; + assert_lt(s.ns_, 0x7fffffff); + return s; + } + + /** + * Add given SwScore into this one. + */ + inline AlnScore operator+=(const AlnScore& o) { + if(VALID_AL_SCORE(*this)) { + gaps_ += o.gaps_; + score_ += o.score_; + repeat_ |= o.repeat_; + splicescore_ += o.splicescore_; + hisat2_score_ += o.hisat2_score_; + knownTranscripts_ |= o.knownTranscripts_; + nearSpliceSites_ |= o.nearSpliceSites_; + leftTrim_ += o.leftTrim_; + rightTrim_ += o.rightTrim_; + } + return (*this); + } + + /** + * Subtract given SwScore from this one. + */ + inline AlnScore operator-=(const AlnScore& o) { + if(VALID_AL_SCORE(*this)) { + gaps_ -= o.gaps_; + score_ -= o.score_; + // splicescore_ -= o.splicescore_; + } + return (*this); + } + + /** + * Calculate difference between two SwScores. + */ + inline AlnScore operator-(int o) const { + return (*this) + -o; + } + + /** + * Calculate sum of a SwScore and an integer. + */ + inline AlnScore operator+(int o) const { + if(!VALID_AL_SCORE(*this)) return *this; + AlnScore s; + s.gaps_ = gaps_; + s.ns_ = ns_; + s.score_ = score_ + o; + // s.splicescore_ = splicescore_; + assert_lt(s.ns_, 0x7fffffff); + return s; + } + + TAlScore score() const { return score_; } + TAlScore hisat2_score() const { return hisat2_score_; } + TAlScore penalty() const { return -score_; } + TAlScore gaps() const { return gaps_; } + TAlScore ns() const { return ns_; } + bool repeat() const { return repeat_;} + TAlScore splicescore() const { return splicescore_; } + bool knownTranscripts() const { return knownTranscripts_; } + bool nearSpliceSites() const { return nearSpliceSites_; } + bool trimed() const { return leftTrim_ > 0 || rightTrim_ > 0; } + + TAlScore calculate_hisat2_score() const + { + // TAlScore 32 bits used for score_ + TAlScore score = score_; + if(score > MAX_I32) score = MAX_I32; + else if(score < MIN_I32) score = MIN_I32; + + // Next 4 bits for repeat score + TAlScore repeat_score = 0; + if(repeat_) repeat_score = 1; + + // Next 4 bits for alignments against transcripts + TAlScore transcript_score = 0; + if(knownTranscripts_) transcript_score = 2; + else if(nearSpliceSites_) transcript_score = 1; + + // Next 8 bits for splice site score + TAlScore splicescore = splicescore_ / 100; + if(splicescore > MAX_U8) splicescore = 0; + else splicescore = MAX_U8 - splicescore; + + // Remaining 16 bits (rightmost 16 bits) for sum of left and right trim lengths + TAlScore trim = leftTrim_ + rightTrim_; + if(trim > MAX_U16) trim = 0; + else trim = MAX_U16 - trim; + return (score << 32) | (repeat_score << 28) | (transcript_score << 24) | (splicescore << 16) | trim; + } + + // Score accumulated so far (penalties are subtracted starting at 0) + TAlScore score_; + + // HISAT2 score, which is used internally to distinguish the alignments of RNA-seq reads + TAlScore hisat2_score_; + + // Ns accumulated so far. An N opposite a non-gap counts as 1 N + // (even if it's N-to-N) + TAlScore ns_; + + // # gaps encountered so far, unless that number exceeds the + // target, in which case the score becomes invalid and therefore <= + // all other scores + TAlScore gaps_; + + bool repeat_; + + // splice scores + TAlScore splicescore_; + + // mapped to known transcripts? + bool knownTranscripts_; + + // continuous alignment near (known) splice sites? + bool nearSpliceSites_; + + int leftTrim_; + int rightTrim_; +}; + +enum { + // This alignment is one of a pair of alignments that form a concordant + // alignment for a read + ALN_FLAG_PAIR_CONCORD_MATE1 = 1, + ALN_FLAG_PAIR_CONCORD_MATE2, + + // This alignment is one of a pair of alignments that form a discordant + // alignment for a read + ALN_FLAG_PAIR_DISCORD_MATE1, + ALN_FLAG_PAIR_DISCORD_MATE2, + + // This is an unpaired alignment but the read in question is a pair; + // usually, this happens because the read had no reportable paired-end + // alignments + ALN_FLAG_PAIR_UNPAIRED_MATE1, + ALN_FLAG_PAIR_UNPAIRED_MATE2, + + // This is an unpaired alignment of an unpaired read + ALN_FLAG_PAIR_UNPAIRED +}; + +/** + * Encapsulates some general information about an alignment that doesn't belong + * in AlnRes. Specifically: + * + * 1. Whether the alignment is paired + * 2. If it's paried, whether it's concordant or discordant + * 3. Whether this alignment was found after the paired-end categories were + * maxed out + * 4. Whether the relevant unpaired category was maxed out + */ +class AlnFlags { + +public: + + AlnFlags() { + init( + ALN_FLAG_PAIR_UNPAIRED, + false, // canMax + false, // maxed + false, // maxedPair + false, // nfilt + false, // scfilt + false, // lenfilt + false, // qcfilt + false, // mixedMode + false, // primary + false, // oppAligned + false); // oppFw + } + + AlnFlags( + int pairing, + bool canMax, + bool maxed, + bool maxedPair, + bool nfilt, + bool scfilt, + bool lenfilt, + bool qcfilt, + bool mixedMode, + bool primary, + bool oppAligned, // opposite mate aligned? + bool oppFw) // opposite mate aligned forward? + { + init(pairing, canMax, maxed, maxedPair, nfilt, scfilt, + lenfilt, qcfilt, mixedMode, primary, oppAligned, oppFw); + } + + /** + * Initialize given values for all settings. + */ + void init( + int pairing, + bool canMax, + bool maxed, + bool maxedPair, + bool nfilt, + bool scfilt, + bool lenfilt, + bool qcfilt, + bool mixedMode, + bool primary, + bool oppAligned, + bool oppFw) + { + assert_gt(pairing, 0); + assert_leq(pairing, ALN_FLAG_PAIR_UNPAIRED); + pairing_ = pairing; + canMax_ = canMax; + maxed_ = maxed; + maxedPair_ = maxedPair; + nfilt_ = nfilt; + scfilt_ = scfilt; + lenfilt_ = lenfilt; + qcfilt_ = qcfilt; + mixedMode_ = mixedMode; + primary_ = primary; + oppAligned_ = oppAligned; + } + + /** + * Return true iff this alignment is from a paired-end read. + */ + bool partOfPair() const { + assert_gt(pairing_, 0); + return pairing_ < ALN_FLAG_PAIR_UNPAIRED; + } + +#ifndef NDEBUG + /** + * Check that the flags are internally consistent. + */ + bool repOk() const { + assert(partOfPair() || !maxedPair_); + return true; + } +#endif + + /** + * Print out string representation of YF:i flag for indicating whether and + * why the mate was filtered. + */ + bool printYF(BTString& o, bool first) const; + + /** + * Print out string representation of YM:i flag for indicating with the + * mate per se aligned repetitively. + */ + void printYM(BTString& o) const; + + /** + * Print out string representation of YM:i flag for indicating with the + * pair containing the mate aligned repetitively. + */ + void printYP(BTString& o) const; + + /** + * Print out string representation of these flags. + */ + void printYT(BTString& o) const; + + inline int pairing() const { return pairing_; } + inline bool maxed() const { return maxed_; } + inline bool maxedPair() const { return maxedPair_; } + + /** + * Return true iff the alignment is not the primary alignment; i.e. not the + * first reported alignment for the fragment. + */ + inline bool isPrimary() const { + return primary_; + } + + /** + * Set the primary flag. + */ + void setPrimary(bool primary) { + primary_ = primary; + } + + /** + * Return whether both paired and unpaired alignments are considered for + * pairs & their constituent mates + */ + inline bool isMixedMode() const { + return mixedMode_; + } + + /** + * Return true iff the alignment params are such that it's possible for a + * read to be suppressed for being repetitive. + */ + inline bool canMax() const { + return canMax_; + } + + /** + * Return true iff the alignment was filtered out. + */ + bool filtered() const { + return !nfilt_ || !scfilt_ || !lenfilt_ || !qcfilt_; + } + + /** + * Return true iff the read is mate #1 of a pair, regardless of whether it + * aligned as a pair. + */ + bool readMate1() const { + return pairing_ == ALN_FLAG_PAIR_CONCORD_MATE1 || + pairing_ == ALN_FLAG_PAIR_DISCORD_MATE1 || + pairing_ == ALN_FLAG_PAIR_UNPAIRED_MATE1; + } + + /** + * Return true iff the read is mate #2 of a pair, regardless of whether it + * aligned as a pair. + */ + bool readMate2() const { + return pairing_ == ALN_FLAG_PAIR_CONCORD_MATE2 || + pairing_ == ALN_FLAG_PAIR_DISCORD_MATE2 || + pairing_ == ALN_FLAG_PAIR_UNPAIRED_MATE2; + } + + /** + * Return true iff the read aligned as either mate of a concordant pair. + */ + bool alignedConcordant() const { + return pairing_ == ALN_FLAG_PAIR_CONCORD_MATE1 || + pairing_ == ALN_FLAG_PAIR_CONCORD_MATE2; + } + + /** + * Return true iff the read aligned as either mate of a discordant pair. + */ + bool alignedDiscordant() const { + return pairing_ == ALN_FLAG_PAIR_DISCORD_MATE1 || + pairing_ == ALN_FLAG_PAIR_DISCORD_MATE2; + } + + /** + * Return true iff the read aligned as either mate of a pair, concordant or + * discordant. + */ + bool alignedPaired() const { + return alignedConcordant() || alignedDiscordant(); + } + + /** + * Return true iff the read aligned as an unpaired read. + */ + bool alignedUnpaired() const { + return pairing_ == ALN_FLAG_PAIR_UNPAIRED; + } + + /** + * Return true iff the read aligned as an unpaired mate from a paired read. + */ + bool alignedUnpairedMate() const { + return pairing_ == ALN_FLAG_PAIR_UNPAIRED_MATE1 || + pairing_ == ALN_FLAG_PAIR_UNPAIRED_MATE2; + } + + bool mateAligned() const { + return oppAligned_; + } + +protected: + + // See ALN_FLAG_PAIR_* above + int pairing_; + + // True iff the alignment params are such that it's possible for a read to + // be suppressed for being repetitive + bool canMax_; + + // This alignment is sampled from among many alignments that, taken + // together, cause this mate to align non-uniquely + bool maxed_; + + // The paired-end read of which this mate is part has repetitive concordant + // alignments + bool maxedPair_; + + bool nfilt_; // read/mate filtered b/c proportion of Ns exceeded ceil + bool scfilt_; // read/mate filtered b/c length can't provide min score + bool lenfilt_; // read/mate filtered b/c less than or equal to seed mms + bool qcfilt_; // read/mate filtered by upstream qc + + // Whether both paired and unpaired alignments are considered for pairs & + // their constituent mates + bool mixedMode_; + + // The read is the primary read + bool primary_; + + // True iff the opposite mate aligned + bool oppAligned_; +}; + +static inline ostream& operator<<(ostream& os, const AlnScore& o) { + os << o.score(); + return os; +} + +// Forward declaration +class BitPairReference; + +// A given AlnRes can be one of these three types +enum { + ALN_RES_TYPE_UNPAIRED = 1, // unpaired alignment + ALN_RES_TYPE_UNPAIRED_MATE1, // mate #1 in pair, aligned unpaired + ALN_RES_TYPE_UNPAIRED_MATE2, // mate #2 in pair, aligned unpaired + ALN_RES_TYPE_MATE1, // mate #1 in paired-end alignment + ALN_RES_TYPE_MATE2 // mate #2 in paired-end alignment +}; + +/** + * Seed alignment summary + */ +struct SeedAlSumm { + + SeedAlSumm() { reset(); } + + void reset() { + nonzTot = nonzFw = nonzRc = 0; + nrangeTot = nrangeFw = nrangeRc = 0; + neltTot = neltFw = neltRc = 0; + minNonzRangeFw = minNonzRangeRc = 0; + maxNonzRangeFw = maxNonzRangeRc = 0; + minNonzEltFw = minNonzEltRc = 0; + maxNonzEltFw = maxNonzEltRc = 0; + } + + size_t nonzTot; + size_t nonzFw; + size_t nonzRc; + + size_t nrangeTot; + size_t nrangeFw; + size_t nrangeRc; + + size_t neltTot; + size_t neltFw; + size_t neltRc; + + size_t minNonzRangeFw; + size_t minNonzRangeRc; + + size_t maxNonzRangeFw; + size_t maxNonzRangeRc; + + size_t minNonzEltFw; + size_t minNonzEltRc; + + size_t maxNonzEltFw; + size_t maxNonzEltRc; +}; + +/** + * Encapsulates a stacked alignment, a nice intermediate format for alignments + * from which to left-align gaps, print CIGAR strings, and print MD:Z strings. + */ +class StackedAln { + +public: + + StackedAln() : + stackRef_(RES_CAT), + stackRel_(RES_CAT), + stackSNP_(RES_CAT), + stackRead_(RES_CAT), + stackSkip_(RES_CAT), + cigOp_(RES_CAT), + cigRun_(RES_CAT), + mdzOp_(RES_CAT), + mdzChr_(RES_CAT), + mdzRun_(RES_CAT) + { + reset(); + } + + /** + * Reset to an uninitialized state. + */ + void reset() { + inited_ = false; + trimLS_ = trimLH_ = trimRS_ = trimRH_ = 0; + stackRef_.clear(); + stackRel_.clear(); + stackSNP_.clear(); + stackRead_.clear(); + stackSkip_.clear(); + cigDistMm_ = cigCalc_ = false; + cigOp_.clear(); + cigRun_.clear(); + mdzCalc_ = false; + mdzOp_.clear(); + mdzChr_.clear(); + mdzRun_.clear(); + } + + /** + * Return true iff the stacked alignment has been initialized. + */ + bool inited() const { return inited_; } + + /** + * Initialized the stacked alignment with respect to a read string, a list of + * edits (expressed left-to-right), and integers indicating how much hard and + * soft trimming has occurred on either end of the read. + * + * s: read sequence + * ed: all relevant edits, including ambiguous nucleotides + * trimLS: # bases soft-trimmed from LHS + * trimLH: # bases hard-trimmed from LHS + * trimRS: # bases soft-trimmed from RHS + * trimRH: # bases hard-trimmed from RHS + */ + void init( + const BTDnaString& s, + const EList& ed, + size_t trimLS, + size_t trimLH, + size_t trimRS, + size_t trimRH); + + /** + * Left-align all the gaps. If this changes the alignment and the CIGAR or + * MD:Z strings have already been calculated, this renders them invalid. + * + * We left-align gaps with in the following way: for each gap, we check + * whether the character opposite the rightmost gap character is the same + * as the character opposite the character just to the left of the gap. If + * this is the case, we can slide the gap to the left and make the + * rightmost position previously covered by the gap into a non-gap. + * + * This scheme allows us to push the gap past a mismatch. BWA does seem to + * allow this. It's not clear that Bowtie 2 should, since moving the + * mismatch could cause a mismatch with one base quality to be replaced + * with a mismatch with a different base quality. + */ + void leftAlign(bool pastMms); + + /** + * Build the CIGAR list, if it hasn't already built. Returns true iff it + * was built for the first time. + */ + bool buildCigar(bool xeq); + + /** + * Build the MD:Z list, if it hasn't already built. Returns true iff it + * was built for the first time. + */ + bool buildMdz(); + + /** + * Write a CIGAR representation of the alignment to the given string and/or + * char buffer. + */ + void writeCigar(BTString* o, char* oc) const; + + /** + * Write a CIGAR representation of the alignment to the given string and/or + * char buffer. This function is for HISAT-3N. + */ + void writeCigar(Alignment* o, char* oc) const; + + /** + * Write an MD:Z representation of the alignment to the given string and/or + * char buffer. + */ + void writeMdz(BTString* o, char* oc) const; + + /** + * Check internal consistency. + */ +#ifndef NDEBUG + bool repOk() const { + if(inited_) { + assert_eq(stackRef_.size(), stackRead_.size()); + assert_eq(stackRef_.size(), stackRel_.size()); + } + return true; + } +#endif + +protected: + + bool inited_; // true iff stacked alignment is initialized + + size_t trimLS_; // amount soft-trimmed from the LHS + size_t trimLH_; // amount hard-trimmed from the LHS + size_t trimRS_; // amount soft-trimmed from the RHS + size_t trimRH_; // amount hard-trimmed from the RHS + + EList stackRef_; // reference characters + EList stackRel_; // bars relating reference to read characters + EList stackSNP_; // known SNP? + EList stackRead_; // read characters + EList stackSkip_; + + bool cigDistMm_; // distinguish between =/X, rather than just M + bool cigCalc_; // whether we've calculated CIGAR ops/runs + EList cigOp_; // CIGAR operations + EList cigRun_; // CIGAR run lengths + + bool mdzCalc_; // whether we've calculated MD:Z ops/runs + EList mdzOp_; // MD:Z operations + EList mdzChr_; // MD:Z operations + EList mdzRun_; // MD:Z run lengths +}; + +/** + * Encapsulates an alignment result. The result comprises: + * + * 1. All the nucleotide edits for both mates ('ned'). + * 2. All "edits" where an ambiguous reference char is resolved to an + * unambiguous char ('aed'). + * 3. The score for the alginment, including summary information about the + * number of gaps and Ns involved. + * 4. The reference id, strand, and 0-based offset of the leftmost character + * involved in the alignment. + * 5. Information about trimming prior to alignment and whether it was hard or + * soft. + * 6. Information about trimming during alignment and whether it was hard or + * soft. Local-alignment trimming is usually soft when aligning nucleotide + * reads. + * + * Note that the AlnRes, together with the Read and an AlnSetSumm (*and* the + * opposite mate's AlnRes and Read in the case of a paired-end alignment), + * should contain enough information to print an entire alignment record. + * + * TRIMMING + * + * Accounting for trimming is tricky. Trimming affects: + * + * 1. The values of the trim* and pretrim* fields. + * 2. The offsets of the Edits in the ELists. + * 3. The read extent, if the trimming is soft. + * 4. The read extent and the read sequence and length, if trimming is hard. + * + * Handling 1. is not too difficult. 2., 3., and 4. are handled in setShape(). + */ +class AlnRes { + +public: + + AlnRes() : + // ned_(RES_CAT), + // aed_(RES_CAT) + ned_(NULL), + aed_(NULL), + ned_node_(NULL), + aed_node_(NULL), + raw_edits_(NULL) + { + reset(); + } + + AlnRes(const AlnRes& other) : + ned_(NULL), + aed_(NULL), + ned_node_(NULL), + aed_node_(NULL), + raw_edits_(NULL) + { + shapeSet_ = other.shapeSet_; + rdlen_ = other.rdlen_; + rdid_ = other.rdid_; + rdrows_ = other.rdrows_; + score_ = other.score_; + oscore_ = other.oscore_; + refcoord_ = other.refcoord_; + reflen_ = other.reflen_; + refival_ = other.refival_; + rdextent_ = other.rdextent_; + rdexrows_ = other.rdexrows_; + rfextent_ = other.rfextent_; + seedmms_ = other.seedmms_; + seedlen_ = other.seedlen_; + minsc_ = other.minsc_; + nuc5p_ = other.nuc5p_; + nuc3p_ = other.nuc3p_; + refns_ = other.refns_; + type_ = other.type_; + fraglenSet_ = other.fraglenSet_; + fraglen_ = other.fraglen_; + pretrimSoft_ = other.pretrimSoft_; + pretrim5p_ = other.pretrim5p_; + pretrim3p_ = other.pretrim3p_; + trimSoft_ = other.trimSoft_; + trim5p_ = other.trim5p_; + trim3p_ = other.trim3p_; + repeat_ = other.repeat_; + + num_spliced_ = other.num_spliced_; + raw_edits_ = other.raw_edits_; + if(raw_edits_ != NULL) { + assert(ned_ == NULL && aed_ == NULL); + assert(ned_node_ == NULL && aed_node_ == NULL); + ned_node_ = raw_edits_->new_node(); + aed_node_ = raw_edits_->new_node(); + assert(ned_node_ != NULL && aed_node_ != NULL); + ned_ = &(ned_node_->payload); + aed_ = &(aed_node_->payload); + assert(other.ned_ != NULL && other.aed_ != NULL); + *ned_ = *(other.ned_); + *aed_ = *(other.aed_); + } + } + + AlnRes& operator=(const AlnRes& other) { + if(this == &other) return *this; + shapeSet_ = other.shapeSet_; + rdlen_ = other.rdlen_; + rdid_ = other.rdid_; + rdrows_ = other.rdrows_; + score_ = other.score_; + oscore_ = other.oscore_; + refcoord_ = other.refcoord_; + reflen_ = other.reflen_; + refival_ = other.refival_; + rdextent_ = other.rdextent_; + rdexrows_ = other.rdexrows_; + rfextent_ = other.rfextent_; + seedmms_ = other.seedmms_; + seedlen_ = other.seedlen_; + minsc_ = other.minsc_; + nuc5p_ = other.nuc5p_; + nuc3p_ = other.nuc3p_; + refns_ = other.refns_; + type_ = other.type_; + fraglenSet_ = other.fraglenSet_; + fraglen_ = other.fraglen_; + pretrimSoft_ = other.pretrimSoft_; + pretrim5p_ = other.pretrim5p_; + pretrim3p_ = other.pretrim3p_; + trimSoft_ = other.trimSoft_; + trim5p_ = other.trim5p_; + trim3p_ = other.trim3p_; + repeat_ = other.repeat_; + + num_spliced_ = other.num_spliced_; + assert(raw_edits_ == NULL || raw_edits_ == other.raw_edits_); + raw_edits_ = other.raw_edits_; + if(ned_ != NULL) { + assert(aed_ != NULL); + ned_->clear(); + aed_->clear(); + } else if(raw_edits_ != NULL) { + assert(aed_ == NULL); + assert(ned_node_ == NULL && aed_node_ == NULL); + ned_node_ = raw_edits_->new_node(); + aed_node_ = raw_edits_->new_node(); + assert(ned_node_ != NULL && aed_node_ != NULL); + ned_ = &(ned_node_->payload); + aed_ = &(aed_node_->payload); + } + + if(other.ned_ != NULL) { + assert(other.aed_ != NULL); + *ned_ = *(other.ned_); + *aed_ = *(other.aed_); + } + + return *this; + } + + ~AlnRes() + { +#ifndef NDEBUG + if(ned_node_ == NULL || aed_node_ == NULL) { + assert(ned_node_ == NULL && aed_node_ == NULL); + assert(ned_ == NULL && aed_ == NULL); + assert(raw_edits_ == NULL); + } else { + assert(ned_node_ != NULL && aed_node_ != NULL); + assert(ned_ != NULL && aed_ != NULL); + assert(raw_edits_ != NULL); + } +#endif + if(ned_ != NULL) { + ned_->clear(); aed_->clear(); + raw_edits_->delete_node(ned_node_); + raw_edits_->delete_node(aed_node_); + ned_ = aed_ = NULL; + ned_node_ = aed_node_ = NULL; + raw_edits_ = NULL; + } + } + + /* DK - temporary implementation */ + void init_raw_edits(LinkedEList >* raw_edits) { + if(raw_edits == NULL) + return; + raw_edits_ = raw_edits; + assert(ned_ == NULL && aed_ == NULL); + assert(ned_node_ == NULL && aed_node_ == NULL); + ned_node_ = raw_edits_->new_node(); + aed_node_ = raw_edits_->new_node(); + assert(ned_node_ != NULL && aed_node_ != NULL); + ned_ = &(ned_node_->payload); + aed_ = &(aed_node_->payload); + } + + /** + * Clear all contents. + */ + void reset(); + + /** + * Reverse all edit lists. + */ + void reverseEdits() { + (*ned_).reverse(); + (*aed_).reverse(); + } + + /** + * Invert positions of edits so that they're with respect to the other end + * of the alignment. The assumption is that the .pos fields of the edits + * in the ned_/aed_/ced_ structures are offsets with respect to the first + * aligned character (i.e. after all trimming). + */ + void invertEdits() { + assert(shapeSet_); + assert_gt(rdlen_, 0); + assert_gt(rdrows_, 0); + Edit::invertPoss(*ned_, rdexrows_, false); + Edit::invertPoss(*aed_, rdexrows_, false); + } + + /** + * Return true iff no result has been installed. + */ + bool empty() const { + if(!VALID_AL_SCORE(score_)) { + assert(ned_ == NULL || ned_->empty()); + assert(aed_ == NULL || aed_->empty()); + assert(!refcoord_.inited()); + assert(!refival_.inited()); + return true; + } else { + return false; + } + } + + /** + * Return the identifier for the reference that the alignment + * occurred in. + */ + inline TRefId refid() const { + assert(shapeSet_); + return refcoord_.ref(); + } + + /** + * Return the orientation that the alignment occurred in. + */ + inline int orient() const { + assert(shapeSet_); + return refcoord_.orient(); + } + + /** + * Return the 0-based offset of the alignment into the reference + * sequence it aligned to. + */ + inline TRefOff refoff() const { + assert(shapeSet_); + return refcoord_.off(); + } + + /** + * Set arguments to coordinates for the upstream-most and downstream-most + * reference positions involved in the alignment. + */ + inline void getCoords( + Coord& st, // out: install starting coordinate here + Coord& en, // out: install ending coordinate here + Coord& st2, + Coord& en2) + const + { + assert(shapeSet_); + st.init(refcoord_); + en.init(refcoord_); + en.adjustOff(refExtent() - 1); + Coord right = refcoord_right(); + st2.init(right); + st2.adjustOff(1 - refExtent()); + en2.init(right); + } + + /** + * Set arguments to coordinates for the upstream-most and downstream-most + * reference positions covered by the read taking any read trimming into + * account. I.e. if the upstream-most offset involved in an alignment is + * 40 but the read was hard-trimmed by 5 on that end, the inferred + * upstream-most covered position is 35. + */ + inline void getExtendedCoords( + Coord& st, // out: install starting coordinate here + Coord& en, // out: install ending coordinate here + Coord& st2, + Coord& en2) + const + { + getCoords(st, en, st2, en2); + // Take trimming into account + int64_t trim_st = (fw() ? trim5p_ : trim3p_); + int64_t trim_en = (fw() ? trim3p_ : trim5p_); + trim_st += (fw() ? pretrim5p_ : pretrim3p_); + trim_en += (fw() ? pretrim3p_ : pretrim5p_); + st.adjustOff(-trim_st); + en.adjustOff( trim_en); + st2.adjustOff(-trim_st); + en2.adjustOff( trim_en); + } + + /** + * Set the upstream-most reference offset involved in the alignment, and + * the extent of the alignment (w/r/t the reference) + */ + void setShape( + TRefId id, // id of reference aligned to + TRefOff off, // offset of first aligned char into ref seq + TRefOff reflen, // length of reference sequence aligned to + bool fw, // aligned to Watson strand? + size_t rdlen, // length of read after hard trimming, before soft + TReadId rdid, // read ID + bool pretrimSoft, // whether trimming prior to alignment was soft + size_t pretrim5p, // # poss trimmed form 5p end before alignment + size_t pretrim3p, // # poss trimmed form 3p end before alignment + bool trimSoft, // whether local-alignment trimming was soft + size_t trim5p, // # poss trimmed form 5p end during alignment + size_t trim3p); // # poss trimmed form 3p end during alignment + + /** + * Return true iff the reference chars involved in this alignment result + * are entirely within with given bounds. + */ + bool within( + TRefId id, + TRefOff off, + bool fw, + size_t extent) const + { + if(refcoord_.ref() == id && + refcoord_.off() >= off && + refcoord_.off() + refExtent() <= off + extent && + refcoord_.fw() == fw) + { + return true; + } + return false; + } + + /** + * Set alignment score for this alignment. + */ + void setScore(AlnScore score) { + score_ = score; + } + + /** + * Set the upstream-most and downstream-most nucleotides. + */ + void setNucs(bool fw, int nup, int ndn) { + nuc5p_ = fw ? nup : ndn; + nuc3p_ = fw ? ndn : nup; + } + + /** + * Return the 0-based offset of the leftmost reference position involved in + * the alignment. + */ + const Coord& refcoord() const { + return refcoord_; + } + + /** + * Return the 0-based offset of the leftmost reference position involved in + * the alignment. + */ + const Interval& refival() const { + return refival_; + } + + /** + * Return the 0-based offset of the leftmost reference position involved in + * the alignment. + */ + Coord& refcoord() { + return refcoord_; + } + + /** + * Return the 0-based offset of the rightmost reference position involved in + * the alignment. + */ + Coord refcoord_right() const { + Coord coord_right = refcoord_; + TRefOff right = coord_right.off() + rfextent_ - 1; + for(size_t i = 0; i < ned_->size(); i++) { + const Edit& ed = (*ned_)[i]; + if(ed.type == EDIT_TYPE_SPL) { + right += ed.splLen; + } + } + + coord_right.setOff(right); + return coord_right; + } + + /** + * Return true if this alignment is to the Watson strand. + */ + inline bool fw() const { + return refcoord_.fw(); + } + + AlnScore score() const { return score_; } + AlnScore oscore() const { return oscore_; } + EList& ned() { return *ned_; } + EList& aed() { return *aed_; } + const EList& ned() const { return *ned_; } + const EList& aed() const { return *aed_; } + size_t readExtent() const { return rdextent_; } + size_t readExtentRows() const { return rdexrows_; } + size_t readLength() const { return rdlen_; } + TReadId readID() const { return rdid_; } + bool spliced() const { return num_spliced_ > 0; } + size_t num_spliced() const { return num_spliced_; } + uint8_t spliced_whichsense_transcript() const { + uint8_t whichsense = SPL_UNKNOWN; + if(spliced()) { + for(size_t i = 0; i < ned_->size(); i++) { + const Edit& ed = (*ned_)[i]; + if(ed.type != EDIT_TYPE_SPL) continue; + if(whichsense == SPL_UNKNOWN) { + whichsense = ed.splDir; + } else if(ed.splDir != SPL_UNKNOWN) { + assert_neq(whichsense, SPL_UNKNOWN); + if(whichsense == SPL_FW || whichsense == SPL_SEMI_FW) { + if(ed.splDir != SPL_FW && ed.splDir != SPL_SEMI_FW) { + whichsense = SPL_UNKNOWN; + break; + } + } + if(whichsense == SPL_RC || whichsense == SPL_SEMI_RC) { + if(ed.splDir != SPL_RC && ed.splDir != SPL_SEMI_RC) { + whichsense = SPL_UNKNOWN; + break; + } + } + } + } + } + + return whichsense; + } + + /** + * Return the number of reference nucleotides involved in the alignment + * (i.e. the number of characters in the inclusive range from the first + * matched-up ref char to the last). + */ + size_t refExtent() const { + return rfextent_; + } + + /** + * Return length of reference sequence aligned to. + */ + TRefOff reflen() const { + return reflen_; + } + + /** + * Return the number of reference nucleotides in the alignment (i.e. the + * number of characters in the inclusive range from the first matched-up + * ref char to the last). + */ + size_t refNucExtent() const { + return rfextent_; + } + + /** + * Print the sequence for the read that aligned using A, C, G and + * T. This will simply print the read sequence (or its reverse + * complement). + */ + void printSeq( + const Read& rd, + const BTDnaString* dns, + BTString& o) const; + + /** + * Print the quality string for the read that aligned. This will + * simply print the read qualities (or their reverse). + */ + void printQuals( + const Read& rd, + const BTString* dqs, + BTString& o) const; + + /** + * Print a stacked alignment with the reference on top, query on bottom, + * and lines connecting matched-up positions. + */ + void printStacked( + const Read& rd, + std::ostream& o) const + { + printStacked(refcoord_.fw() ? rd.patFw : rd.patRc, o); + } + + /** + * Print a stacked alignment with the reference on bottom, query on top, + * and lines connecting matched-up positions. + */ + void printStacked( + const BTDnaString& seq, + std::ostream& o) const + { + Edit::printQAlign(o, seq, *ned_); + // Print reference offset below reference string + o << "^" << std::endl; + o << "(" << refcoord_.ref() << "," << refcoord_.off() << ")" << std::endl; + } + +#ifndef NDEBUG + /** + * Check that alignment score is internally consistent. + */ + bool repOk() const { + assert(refcoord_.repOk()); + if(shapeSet_) { + assert_lt(refoff(), reflen_); + } + assert(refival_.repOk()); + assert(VALID_AL_SCORE(score_) || ned_ == NULL || ned_->empty()); + assert(VALID_AL_SCORE(score_) || aed_ == NULL || aed_->empty()); + assert(empty() || refcoord_.inited()); + assert(empty() || refival_.inited()); + assert_geq(rdexrows_, rdextent_); + assert(empty() || rdextent_ > 0); + assert(empty() || rfextent_ > 0); + return true; + } + + /** + * Check that alignment score is internally consistent. + */ + bool repOk(const Read& rd) const { + assert(Edit::repOk(*ned_, refcoord_.fw() ? rd.patFw : rd.patRc, + refcoord_.fw(), trimmed5p(true), trimmed3p(true))); + return repOk(); + } +#endif + +#ifndef NDEBUG + /** + * Assuming this AlnRes is an alignment for 'rd', check that the + * alignment and 'rd' are compatible with the corresponding + * reference sequence. + */ + bool matchesRef( + const Read& rd, + const BitPairReference& ref, + BTDnaString& rf, + BTDnaString& rdseq, + BTString& qseq, + SStringExpandable& raw_refbuf, + SStringExpandable& destU32, + EList& matches, + SStringExpandable& raw_refbuf2, + EList& reflens, + EList& refoffs); +#endif + + /** + * Set information about the alignment parameters that led to this + * alignment. + */ + void setParams( + int seedmms, + int seedlen, + int seedival, + int64_t minsc) + { + seedmms_ = seedmms; + seedlen_ = seedlen; + seedival_ = seedival; + minsc_ = minsc; + } + + // Accessors for alignment parameters + int seedmms() const { return seedmms_; } + int seedlen() const { return seedlen_; } + int seedival() const { return seedival_; } + int64_t minScore() const { return minsc_; } + + /** + * Is the ith row from the 5' end of the DP table one of the ones + * soft-trimmed away by local alignment? + */ + inline bool trimmedRow5p(size_t i) const { + return i < trim5p_ || rdrows_ - i - 1 < trim3p_; + } + + /** + * Is the ith character from the 5' end of read sequence one of the ones + * soft-trimmed away by local alignment? + */ + inline bool trimmedPos5p(size_t i) const { + return i < trim5p_ || rdlen_ - i - 1 < trim3p_; + } + + /** + * Is the ith row from the 5' end of the DP table one of the ones that + * survived local-alignment soft trimming? + */ + inline bool alignedRow5p(size_t i) const { + return !trimmedRow5p(i); + } + + /** + * Is the ith character from the 5' end of the read sequence one of the + * ones that survived local-alignment soft trimming? + */ + inline bool alignedPos5p(size_t i) const { + return !trimmedPos5p(i); + } + + /** + * Return true iff this AlnRes and the given AlnRes overlap. Two AlnRess + * overlap if they share a cell in the overall dynamic programming table: + * i.e. if there exists a read position s.t. that position in both reads + * matches up with the same reference character. E.g., the following + * alignments (drawn schematically as paths through a dynamic programming + * table) are redundant: + * + * a b a b + * \ \ \ \ + * \ \ \ \ + * \ \ \ \ + * ---\ \ \ + * \ ---\--- + * ---\ \ \ + * \ \ \ \ + * \ \ \ \ + * \ \ \ \ + * a b b a + * + * We iterate over each read position that hasn't been hard-trimmed, but + * only overlaps at positions that have also not been soft-trimmed are + * considered. + */ + bool overlap(AlnRes& res); + + /** + * Return true iff this read was unpaired to begin with. + */ + inline bool readUnpaired() const { + assert_gt(type_, 0); + return type_ == ALN_RES_TYPE_UNPAIRED; + } + + /** + * Return true iff this alignment aligned in an unpaired fashion; not part + * of a concordant or discordant pair. + */ + inline bool alignedUnpaired() const { + assert_gt(type_, 0); + return type_ == ALN_RES_TYPE_UNPAIRED || + type_ == ALN_RES_TYPE_UNPAIRED_MATE1 || + type_ == ALN_RES_TYPE_UNPAIRED_MATE2; + } + + /** + * Return true iff this alignment aligned as mate #1 or mate #2 in a pair, + * either concordant or discordant. + */ + inline bool alignedPaired() const { + assert_gt(type_, 0); + return type_ == ALN_RES_TYPE_MATE1 || + type_ == ALN_RES_TYPE_MATE2; + } + + /** + * Return true iff this read started as mate #1 in a pair. + */ + inline bool readMate1() const { + assert_gt(type_, 0); + return type_ == ALN_RES_TYPE_MATE1 || + type_ == ALN_RES_TYPE_UNPAIRED_MATE1; + } + + /** + * Return true iff this read aligned as mate #1 in a concordant or + * discordant pair. + */ + inline bool alignedMate1() const { + assert_gt(type_, 0); + return type_ == ALN_RES_TYPE_MATE1; + } + + /** + * Return true iff this alignment aligned as mate #2 in a pair, either + * concordant or discordant. + */ + inline bool readMate2() const { + assert_gt(type_, 0); + return type_ == ALN_RES_TYPE_MATE2 || + type_ == ALN_RES_TYPE_UNPAIRED_MATE2; + } + + /** + * Return true iff this read aligned as mate #2 in a concordant or + * discordant pair. + */ + inline bool alignedMate2() const { + assert_gt(type_, 0); + return type_ == ALN_RES_TYPE_MATE2; + } + + /** + * Return true iff fragment length is set. + */ + bool isFraglenSet() const { + return fraglenSet_; + } + + /** + * Set whether this alignment is unpaired, or is mate #1 or mate #2 in a + * paired-end alignment. + */ + void setMateParams( + int type, + const AlnRes* omate, // alignment result for the opposite mate + const AlnFlags& flags, // flags for this mate + const SpliceSiteDB* ssdb = NULL, // splice sites + uint64_t threads_rids_mindist = 0, + EList* spliceSites = NULL) + { + assert_gt(type, 0); + type_ = type; + fraglen_ = 0; + if(omate != NULL) { + oscore_ = omate->score_; + // When should we calculate a fragment length here? There are a + // couple reasonable ideas: + // 1. When mates align concordantly + // 2. When both mates align to the same reference string + // BWA seems to do 2., so that's what we'll do here. + bool sameChr = true; + if((sameChr && refcoord_.ref() == omate->refcoord_.ref()) || + flags.alignedConcordant()) + { + setFragmentLength(*omate, ssdb, threads_rids_mindist, spliceSites); + } else { + assert(!isFraglenSet()); + } + } + } + + /** + * Assuming this alignment and the given alignment are at the extreme ends + * of a fragment, return the length of the fragment. We take all clipping, + * both hard and soft, into account here. Any clipping that occurred + * earlier and isn't accounted for within Bowtie2 should be accounted for + * by the user in how they set the maximum and minimum fragment length + * settings. + */ + int64_t setFragmentLength(const AlnRes& omate, + const SpliceSiteDB* ssdb = NULL, // splice sites + uint64_t threads_rids_mindist = 0, + EList* spliceSites = NULL) { + Coord st, en, st2, en2; + Coord ost, oen, ost2, oen2; + assert_eq(refid(), omate.refid()); + getExtendedCoords(st, en, st2, en2); + omate.getExtendedCoords(ost, oen, ost2, oen2); + bool imUpstream = false; + + if(st.off() < ost.off()) { + imUpstream = true; + } else if(st.off() == ost.off()) { + if(st.fw() && ost.fw() && readMate1()) { + imUpstream = true; + } else if(st.fw() && !ost.fw()) { + imUpstream = true; + } else { + imUpstream = false; + } + } else { + imUpstream = false; + } + + TRefOff up, dn, up_right, dn_left; + if(imUpstream) { + up = std::min(st2.off(), ost.off()); + up_right = std::min(en2.off(), oen.off()); + dn_left = std::max(st2.off(), ost.off()); + dn = std::max(en2.off(), oen.off()); + } else { + up = std::min(st.off(), ost2.off()); + up_right = std::min(en.off(), oen2.off()); + dn_left = std::max(st.off(), ost2.off()); + dn = std::max(en.off(), oen2.off()); + } + assert_geq(dn, up); + TRefOff intron_len = 0; + if(ssdb != NULL && + !repeat() && + up_right + 100 < dn_left) { + assert(spliceSites != NULL); + if(spliceSites->size() == 0) { + ssdb->getRightSpliceSites(refid(), up_right, dn_left - up_right, *spliceSites); + } + for(size_t si = 0; si < spliceSites->size(); si++) { + const SpliceSite& ss = (*spliceSites)[si]; + if(!ss._fromfile && ss._readid + threads_rids_mindist > rdid_) continue; + if(ss.left() <= up || ss.right() >= dn) continue; + TRefOff tmp_intron_len = ss.intron_len(); + if(intron_len < tmp_intron_len) { + intron_len = tmp_intron_len; + } + } + } + fraglen_ = 1 + dn - up; + assert_geq(fraglen_, intron_len); + fraglen_ -= intron_len; + if(!imUpstream) { + fraglen_ = -fraglen_; + } + fraglenSet_ = true; + return fraglen_; + } + + /** + * Return fragment length inferred by a paired-end alignment, or -1 if the + * alignment is not part of a pair. + */ + int64_t fragmentLength() const { + assert_gt(type_, 0); + assert(fraglenSet_); + return fraglen_; + } + + /** + * Initialize new AlnRes. + */ + void init( + size_t rdlen, // # chars after hard trimming + TReadId rdid, // read ID + AlnScore score, // alignment score + const EList* ned, // nucleotide edits + size_t ned_i, // first position to copy + size_t ned_n, // # positions to copy + const EList* aed, // ambiguous base resolutions + size_t aed_i, // first position to copy + size_t aed_n, // # positions to copy + Coord refcoord, // leftmost ref pos of 1st al char + TRefOff reflen, // length of the reference + LinkedEList >* raw_edits, + int seedmms = -1,// # seed mms allowed + int seedlen = -1,// seed length + int seedival = -1,// space between seeds + int64_t minsc = -1,// minimum score for valid aln + int nuc5p = -1,// + int nuc3p = -1, + bool pretrimSoft = false, + size_t pretrim5p = 0, // trimming prior to alignment + size_t pretrim3p = 0, // trimming prior to alignment + bool trimSoft = true, + size_t trim5p = 0, // trimming from alignment + size_t trim3p = 0, // trimming from alignment + bool repeat = false); // repeat + + /** + * Return number of bases trimmed from the 5' end. Argument determines + * whether we're counting hard- or soft-trimmed bases. + */ + size_t trimmed5p(bool soft) const { + size_t trim = 0; + if(pretrimSoft_ == soft) trim += pretrim5p_; + if(trimSoft_ == soft) trim += trim5p_; + return trim; + } + + /** + * Return number of bases trimmed from the 3' end. Argument determines + * whether we're counting hard- or soft-trimmed bases. + */ + size_t trimmed3p(bool soft) const { + size_t trim = 0; + if(pretrimSoft_ == soft) trim += pretrim3p_; + if(trimSoft_ == soft) trim += trim3p_; + return trim; + } + + /** + * Return number of bases trimmed from the left end. Argument determines + * whether we're counting hard- or soft-trimmed bases. + */ + size_t trimmedLeft(bool soft) const { + return fw() ? trimmed5p(soft) : trimmed3p(soft); + } + + /** + * Return number of bases trimmed from the right end. Argument determines + * whether we're counting hard- or soft-trimmed bases. + */ + size_t trimmedRight(bool soft) const { + return fw() ? trimmed3p(soft) : trimmed5p(soft); + } + + bool repeat() const { return repeat_; } + + /** + * Set the number of reference Ns covered by the alignment. + */ + void setRefNs(size_t refns) { + refns_ = refns; + } + + /** + * Return the number of reference Ns covered by the alignment. + */ + size_t refNs() const { return refns_; } + + /** + * Clip away portions of the alignment that are outside the given bounds. + * Clipping is soft if soft == true, hard otherwise. + */ + void clipOutside(bool soft, TRefOff refi, TRefOff reff); + + /** + * Soft trim bases from the LHS of the alignment. + */ + void clipLeft(size_t rd_amt, size_t rf_amt); + + /** + * Soft trim bases from the RHS of the alignment. + */ + void clipRight(size_t rd_amt, size_t rf_amt); + + /** + * In debug mode, we put a copy of the decoded nucleotide sequence here. + */ + ASSERT_ONLY(BTDnaString drd); + + /** + * Return true iff this AlnRes should come before the given AlnRes in a + * prioritized list of results. + */ + bool operator<(const AlnRes& o) const { + return score_ > o.score_; + } + + bool operator==(const AlnRes& o) const { + return + shapeSet_ == o.shapeSet_ && + rdlen_ == o.rdlen_ && + rdid_ == o.rdid_ && + rdrows_ == o.rdrows_ && + score_ == o.score_ && + //oscore_ == o.oscore_ && + *ned_ == *(o.ned_) && + *aed_ == *(o.aed_) && + refcoord_ == o.refcoord_ && + reflen_ == o.reflen_ && + refival_ == o.refival_ && + rdextent_ == o.rdextent_ && + rdexrows_ == o.rdexrows_ && + rfextent_ == o.rfextent_ && + seedmms_ == o.seedmms_ && + seedlen_ == o.seedlen_ && + seedival_ == o.seedival_ && + minsc_ == o.minsc_ && + nuc5p_ == o.nuc5p_ && + nuc3p_ == o.nuc3p_ && + refns_ == o.refns_ && + type_ == o.type_ && + fraglen_ == o.fraglen_ && + pretrimSoft_ == o.pretrimSoft_ && + pretrim5p_ == o.pretrim5p_ && + pretrim3p_ == o.pretrim3p_ && + trimSoft_ == o.trimSoft_ && + trim5p_ == o.trim5p_ && + trim3p_ == o.trim3p_ && + repeat_ == o.repeat_ && + num_spliced_ == o.num_spliced_; + } + + /** + * Initialize a StackedAln (stacked alignment) object w/r/t this alignment. + */ + void initStacked(const Read& rd, StackedAln& st) const { + size_t trimLS = trimmed5p(true); + size_t trimLH = trimmed5p(false); + size_t trimRS = trimmed3p(true); + size_t trimRH = trimmed3p(false); + size_t len_trimmed = rd.length() - trimLS - trimRS; + if(!fw()) { + Edit::invertPoss(const_cast&>(*ned_), len_trimmed, false); + swap(trimLS, trimRS); + swap(trimLH, trimRH); + } + st.init( + fw() ? rd.patFw : rd.patRc, + *ned_, trimLS, trimLH, trimRS, trimRH); + if(!fw()) { + Edit::invertPoss(const_cast&>(*ned_), len_trimmed, false); + } + } + +protected: + + /** + * Given that rdextent_ and ned_ are already set, calculate rfextent_. + */ + void calcRefExtent() { + assert_gt(rdextent_, 0); + rfextent_ = rdextent_; + for(size_t i = 0; i < ned_->size(); i++) { + if((*ned_)[i].isRefGap()) rfextent_--; + if((*ned_)[i].isReadGap()) rfextent_++; + } + } + + bool shapeSet_; // true iff setShape() has been called + size_t rdlen_; // length of the original read + TReadId rdid_; // read id + size_t rdrows_; // # rows in alignment problem + AlnScore score_; // best SW score found + AlnScore oscore_; // score of opposite mate + EList* ned_; // base edits + EList* aed_; // ambiguous base resolutions + Coord refcoord_; // ref coordinates (seq idx, offset, orient) + TRefOff reflen_; // reference length + Interval refival_; // ref interval (coord + length) + size_t rdextent_; // number of read chars involved in alignment + size_t rdexrows_; // number of read rows involved in alignment + size_t rfextent_; // number of ref chars involved in alignment + int seedmms_; // number of mismatches allowed in seed + int seedlen_; // length of seed + int seedival_; // interval between seeds + int64_t minsc_; // minimum score + int nuc5p_; // 5'-most decoded base; clipped if excluding end + int nuc3p_; // 3'-most decoded base; clipped if excluding end + size_t refns_; // # of reference Ns overlapped + int type_; // unpaired or mate #1 or mate #2? + bool fraglenSet_; // true iff a fragment length has been inferred + int64_t fraglen_; // inferred fragment length + + // A tricky aspect of trimming is that we have to decide what the units are: + // read positions, reference positions??? We choose read positions here. + // In other words, if an alignment overhangs the end of the reference and + // part of the overhanging portion is a reference gap, we have to make sure + // the trim amount reflects the number of *read characters* to trim + // including the character opposite the reference gap. + + // Nucleotide-sequence trimming + bool pretrimSoft_; // trimming prior to alignment is soft? + size_t pretrim5p_; // # bases trimmed from 5p end prior to alignment + size_t pretrim3p_; // # bases trimmed from 3p end prior to alignment + bool trimSoft_; // trimming by local alignment is soft? + size_t trim5p_; // # bases trimmed from 5p end by local alignment + size_t trim3p_; // # bases trimmed from 3p end by local alignment + bool repeat_; // repeat? + + size_t num_spliced_; + LinkedEListNode >* ned_node_; + LinkedEListNode >* aed_node_; + LinkedEList >* raw_edits_; +}; + +/** + * Unique ID for a cell in the overall DP table. This is a helpful concept + * because of our definition of "redundnant". Two alignments are redundant iff + * they have at least one cell in common in the overall DP table. + */ +struct RedundantCell { + + RedundantCell() { + rfid = 0; + fw = true; + rfoff = 0; + rdoff = 0; + } + + RedundantCell( + TRefId rfid_, + bool fw_, + TRefOff rfoff_, + size_t rdoff_) + { + init(rfid_, fw_, rfoff_, rdoff_); + } + + void init( + TRefId rfid_, + bool fw_, + TRefOff rfoff_, + size_t rdoff_) + { + rfid = rfid_; + fw = fw_; + rfoff = rfoff_; + rdoff = rdoff_; + } + + /** + * Return true iff this RedundantCell is less than the given RedundantCell. + */ + inline bool operator<(const RedundantCell& c) const { + if(rfid < c.rfid) return true; + if(rfid > c.rfid) return false; + if(!fw && c.fw) return true; + if( fw && !c.fw) return false; + if(rfoff < c.rfoff) return true; + if(rfoff > c.rfoff) return false; + return rdoff < c.rdoff; + } + + /** + * Return true iff this RedundantCell is greater than the given + * RedundantCell. + */ + inline bool operator>(const RedundantCell& c) const { + if(rfid > c.rfid) return true; + if(rfid < c.rfid) return false; + if( fw && !c.fw) return true; + if(!fw && c.fw) return false; + if(rfoff > c.rfoff) return true; + if(rfoff < c.rfoff) return false; + return rdoff > c.rdoff; + } + + /** + * Return true iff this RedundantCell is equal to the given RedundantCell. + */ + inline bool operator==(const RedundantCell& c) const { + return + rfid == c.rfid && + fw == c.fw && + rfoff == c.rfoff && + rdoff == c.rdoff; + } + + TRefId rfid; // reference id + bool fw; // orientation + TRefOff rfoff; // column + size_t rdoff; // row +}; + +/** + * Encapsulates data structures and routines allowing client to determine + * whether one alignment is redundant (has a DP cell in common with) with a set + * of others. + * + * Adding cells to and checking cell against this data structure can get rather + * slow when there are many alignments in play. Dividing the burden over + * read-position bins helps some. + */ +class RedundantAlns { + +public: + + RedundantAlns(int cat = DP_CAT) : cells_(cat) { } + + /** + * Empty the cell database. + */ + void reset() { cells_.clear(); } + + /** + * Initialize and set the list of sets to equal the read length. + */ + void init(size_t npos) { + cells_.resize(npos); + for(size_t i = 0; i < npos; i++) { + cells_[i].clear(); + } + } + + /** + * Add all of the cells involved in the given alignment to the database. + */ + void add(const AlnRes& res); + + /** + * Return true iff the given alignment has at least one cell that overlaps + * one of the cells in the database. + */ + bool overlap(const AlnRes& res); + +protected: + + EList > cells_; +}; + +typedef uint64_t TNumAlns; + +/** + * Encapsulates a concise summary of a set of alignment results for a + * given pair or mate. Referring to the fields of this object should + * provide enough information to print output records for the read. + */ +class AlnSetSumm { + +public: + + AlnSetSumm() { reset(); } + + /** + * Given an unpaired read (in either rd1 or rd2) or a read pair + * (mate 1 in rd1, mate 2 in rd2). + */ + explicit AlnSetSumm( + const Read* rd1, + const Read* rd2, + const EList* rs1, + const EList* rs2, + const EList* rs1u, + const EList* rs2u, + bool exhausted1, + bool exhausted2, + TRefId orefid, + TRefOff orefoff, + bool repeat) + { + init(rd1, rd2, rs1, rs2, rs1u, rs2u, exhausted1, exhausted2, + orefid, orefoff, repeat); + } + + explicit AlnSetSumm( + AlnScore best1, + AlnScore secbest1, + AlnScore best2, + AlnScore secbest2, + AlnScore bestPaired, + AlnScore secbestPaired, + TNumAlns other1, + TNumAlns other2, + bool paired, + bool exhausted1, + bool exhausted2, + TRefId orefid, + TRefOff orefoff, + bool repeat, + TNumAlns numAlns1, + TNumAlns numAlns2, + TNumAlns numAlnsPaired) + { + init( + best1, + secbest1, + best2, + secbest2, + bestPaired, + secbestPaired, + other1, + other2, + paired, + exhausted1, + exhausted2, + orefid, + orefoff, + repeat, + numAlns1, + numAlns2, + numAlnsPaired); + } + + /** + * Set to uninitialized state. + */ + void reset() { + best1_.invalidate(); + secbest1_.invalidate(); + best2_.invalidate(); + secbest2_.invalidate(); + bestPaired_.invalidate(); + secbestPaired_.invalidate(); + other1_ = other2_ = 0; + paired_ = false; + exhausted1_ = exhausted2_ = false; + orefid_ = -1; + orefoff_ = -1; + repeat_ = false; + numAlns1_ = numAlns2_= numAlnsPaired_ = 0; + } + + void init( + const Read* rd1, + const Read* rd2, + const EList* rs1, + const EList* rs2, + const EList* rs1u, + const EList* rs2u, + bool exhausted1, + bool exhausted2, + TRefId orefid, + TRefOff orefoff, + bool repeat); + + /** + * Initialize given fields. See constructor for how fields are set. + */ + void init( + AlnScore best1, + AlnScore secbest1, + AlnScore best2, + AlnScore secbest2, + AlnScore bestPaired, + AlnScore secbestPaired, + TNumAlns other1, + TNumAlns other2, + bool paired, + bool exhausted1, + bool exhausted2, + TRefId orefid, + TRefOff orefoff, + bool repeat, + TNumAlns numAlns1, + TNumAlns numAlns2, + TNumAlns numAlnsPaired) + { + best1_ = best1; + secbest1_ = secbest1; + best2_ = best2; + secbest2_ = secbest2; + bestPaired_ = bestPaired; + secbestPaired_ = secbestPaired; + other1_ = other1; + other2_ = other2; + paired_ = paired; + exhausted1_ = exhausted1; + exhausted2_ = exhausted2; + orefid_ = orefid; + orefoff_ = orefoff; + repeat_ = repeat; + numAlns1_ = numAlns1; + numAlns2_ = numAlns2; + numAlnsPaired_ = numAlnsPaired; + assert(repOk()); + } + + /** + * Return true iff there is at least a best alignment + */ + bool empty() const { + assert(repOk()); + return !VALID_AL_SCORE(best1_); + } + +#ifndef NDEBUG + /** + * Check that the summary is internally consistent. + */ + bool repOk() const { + assert(other1_ == 0 || VALID_AL_SCORE(secbest1_)); + assert(other1_ != 0 || !VALID_AL_SCORE(secbest1_)); + assert(other2_ == 0 || VALID_AL_SCORE(secbest2_)); + assert(other2_ != 0 || !VALID_AL_SCORE(secbest2_)); + return true; + } +#endif + + AlnScore best1() const { return best1_; } + AlnScore secbest1() const { return secbest1_; } + AlnScore best2() const { return best2_; } + AlnScore secbest2() const { return secbest2_; } + AlnScore bestPaired() const { return bestPaired_; } + AlnScore secbestPaired() const { return secbestPaired_; } + TNumAlns other1() const { return other1_; } + TNumAlns other2() const { return other2_; } + bool paired() const { return paired_; } + bool exhausted1() const { return exhausted1_; } + bool exhausted2() const { return exhausted2_; } + TRefId orefid() const { return orefid_; } + TRefOff orefoff() const { return orefoff_; } + bool repeat() const { return repeat_; } + + TNumAlns numAlns1() const { return numAlns1_; } + TNumAlns numAlns2() const { return numAlns2_; } + TNumAlns numAlnsPaired() const { return numAlnsPaired_; } + + void numAlns1(TNumAlns numAlns1) { numAlns1_ = numAlns1; } + void numAlns2(TNumAlns numAlns2) { numAlns2_ = numAlns2; } + void numAlnsPaired(TNumAlns numAlnsPaired) { numAlnsPaired_ = numAlnsPaired; } + + /** + * + */ + AlnScore best(bool mate1) const { return mate1 ? best1_ : best2_; } + + bool exhausted(bool mate1) const { + return mate1 ? exhausted1_ : exhausted2_; + } + + /** + * Return the second-best score for the specified mate. If the alignment + * is paired and the specified mate aligns uniquely, return an invalid + * second-best score. This allows us to treat mates separately, so that + * repetitive paired-end alignments don't trump potentially unique unpaired + * alignments. + */ + AlnScore secbestMate(bool mate1) const { + return mate1 ? secbest1_ : secbest2_; + } + + /** + * Return the second-best score for the specified mate. If the alignment + * is paired and the specified mate aligns uniquely, return an invalid + * second-best score. This allows us to treat mates separately, so that + * repetitive paired-end alignments don't trump potentially unique unpaired + * alignments. + */ + AlnScore secbest(bool mate1) const { + if(paired_) { + if(mate1) { + //if(!secbest1_.valid()) { + return secbest1_; + //} + } else { + //if(!secbest2_.valid()) { + return secbest2_; + //} + } + //return secbestPaired_; + } else { + return mate1 ? secbest1_ : secbest2_; + } + } + +protected: + + AlnScore bestPaired_; // best full-alignment score found for this read + AlnScore secbestPaired_; // second-best + AlnScore best1_; // best full-alignment score found for this read + AlnScore secbest1_; // second-best + AlnScore best2_; // best full-alignment score found for this read + AlnScore secbest2_; // second-best + TNumAlns other1_; // # more alignments within N points of second-best + TNumAlns other2_; // # more alignments within N points of second-best + bool paired_; // results are paired + bool exhausted1_; // searched exhaustively for mate 1 alignments? + bool exhausted2_; // searched exhaustively for mate 2 alignments? + TRefId orefid_; + TRefOff orefoff_; + bool repeat_; + + TNumAlns numAlns1_; // number of alignments for mate 1 as singleton or discordantly mapped + TNumAlns numAlns2_; // number of alignments for mate 2 as singleton or discordantly mapped + TNumAlns numAlnsPaired_; // number of concordant pair alignments +}; + +#endif diff --git a/aligner_seed.cpp b/aligner_seed.cpp new file mode 100644 index 0000000..5fe0419 --- /dev/null +++ b/aligner_seed.cpp @@ -0,0 +1,530 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "aligner_cache.h" +#include "aligner_seed.h" +#include "search_globals.h" +#include "gfm.h" + +using namespace std; + +/** + * Construct a constraint with no edits of any kind allowed. + */ +Constraint Constraint::exact() { + Constraint c; + c.edits = c.mms = c.ins = c.dels = c.penalty = 0; + return c; +} + +/** + * Construct a constraint where the only constraint is a total + * penalty constraint. + */ +Constraint Constraint::penaltyBased(int pen) { + Constraint c; + c.penalty = pen; + return c; +} + +/** + * Construct a constraint where the only constraint is a total + * penalty constraint related to the length of the read. + */ +Constraint Constraint::penaltyFuncBased(const SimpleFunc& f) { + Constraint c; + c.penFunc = f; + return c; +} + +/** + * Construct a constraint where the only constraint is a total + * penalty constraint. + */ +Constraint Constraint::mmBased(int mms) { + Constraint c; + c.mms = mms; + c.edits = c.dels = c.ins = 0; + return c; +} + +/** + * Construct a constraint where the only constraint is a total + * penalty constraint. + */ +Constraint Constraint::editBased(int edits) { + Constraint c; + c.edits = edits; + c.dels = c.ins = c.mms = 0; + return c; +} + +// +// Some static methods for constructing some standard SeedPolicies +// + +/** + * Given a read, depth and orientation, extract a seed data structure + * from the read and fill in the steps & zones arrays. The Seed + * contains the sequence and quality values. + */ +bool +Seed::instantiate( + const Read& read, + const BTDnaString& seq, // seed read sequence + const BTString& qual, // seed quality sequence + const Scoring& pens, + int depth, + int seedoffidx, + int seedtypeidx, + bool fw, + InstantiatedSeed& is) const +{ + assert(overall != NULL); + int seedlen = len; + if((int)read.length() < seedlen) { + // Shrink seed length to fit read if necessary + seedlen = (int)read.length(); + } + assert_gt(seedlen, 0); + is.steps.resize(seedlen); + is.zones.resize(seedlen); + // Fill in 'steps' and 'zones' + // + // The 'steps' list indicates which read character should be + // incorporated at each step of the search process. Often we will + // simply proceed from one end to the other, in which case the + // 'steps' list is ascending or descending. In some cases (e.g. + // the 2mm case), we might want to switch directions at least once + // during the search, in which case 'steps' will jump in the + // middle. When an element of the 'steps' list is negative, this + // indicates that the next + // + // The 'zones' list indicates which zone constraint is active at + // each step. Each element of the 'zones' list is a pair; the + // first pair element indicates the applicable zone when + // considering either mismatch or delete (ref gap) events, while + // the second pair element indicates the applicable zone when + // considering insertion (read gap) events. When either pair + // element is a negative number, that indicates that we are about + // to leave the zone for good, at which point we may need to + // evaluate whether we have reached the zone's budget. + // + switch(type) { + case SEED_TYPE_EXACT: { + for(int k = 0; k < seedlen; k++) { + is.steps[k] = -(seedlen - k); + // Zone 0 all the way + is.zones[k].first = is.zones[k].second = 0; + } + break; + } + case SEED_TYPE_LEFT_TO_RIGHT: { + for(int k = 0; k < seedlen; k++) { + is.steps[k] = k+1; + // Zone 0 from 0 up to ceil(len/2), then 1 + is.zones[k].first = is.zones[k].second = ((k < (seedlen+1)/2) ? 0 : 1); + } + // Zone 1 ends at the RHS + is.zones[seedlen-1].first = is.zones[seedlen-1].second = -1; + break; + } + case SEED_TYPE_RIGHT_TO_LEFT: { + for(int k = 0; k < seedlen; k++) { + is.steps[k] = -(seedlen - k); + // Zone 0 from 0 up to floor(len/2), then 1 + is.zones[k].first = ((k < seedlen/2) ? 0 : 1); + // Inserts: Zone 0 from 0 up to ceil(len/2)-1, then 1 + is.zones[k].second = ((k < (seedlen+1)/2+1) ? 0 : 1); + } + is.zones[seedlen-1].first = is.zones[seedlen-1].second = -1; + break; + } + case SEED_TYPE_INSIDE_OUT: { + // Zone 0 from ceil(N/4) up to N-floor(N/4) + int step = 0; + for(int k = (seedlen+3)/4; k < seedlen - (seedlen/4); k++) { + is.zones[step].first = is.zones[step].second = 0; + is.steps[step++] = k+1; + } + // Zone 1 from N-floor(N/4) up + for(int k = seedlen - (seedlen/4); k < seedlen; k++) { + is.zones[step].first = is.zones[step].second = 1; + is.steps[step++] = k+1; + } + // No Zone 1 if seedlen is short (like 2) + //assert_eq(1, is.zones[step-1].first); + is.zones[step-1].first = is.zones[step-1].second = -1; + // Zone 2 from ((seedlen+3)/4)-1 down to 0 + for(int k = ((seedlen+3)/4)-1; k >= 0; k--) { + is.zones[step].first = is.zones[step].second = 2; + is.steps[step++] = -(k+1); + } + assert_eq(2, is.zones[step-1].first); + is.zones[step-1].first = is.zones[step-1].second = -2; + assert_eq(seedlen, step); + break; + } + default: + throw 1; + } + // Instantiate constraints + for(int i = 0; i < 3; i++) { + is.cons[i] = zones[i]; + is.cons[i].instantiate(read.length()); + } + is.overall = *overall; + is.overall.instantiate(read.length()); + // Take a sweep through the seed sequence. Consider where the Ns + // occur and how zones are laid out. Calculate the maximum number + // of positions we can jump over initially (e.g. with the ftab) and + // perhaps set this function's return value to false, indicating + // that the arrangements of Ns prevents the seed from aligning. + bool streak = true; + is.maxjump = 0; + bool ret = true; + bool ltr = (is.steps[0] > 0); // true -> left-to-right + for(size_t i = 0; i < is.steps.size(); i++) { + assert_neq(0, is.steps[i]); + int off = is.steps[i]; + off = abs(off)-1; + Constraint& cons = is.cons[abs(is.zones[i].first)]; + int c = seq[off]; assert_range(0, 4, c); + int q = qual[off]; + if(ltr != (is.steps[i] > 0) || // changed direction + is.zones[i].first != 0 || // changed zone + is.zones[i].second != 0) // changed zone + { + streak = false; + } + if(c == 4) { + // Induced mismatch + if(cons.canN(q, pens)) { + cons.chargeN(q, pens); + } else { + // Seed disqualified due to arrangement of Ns + return false; + } + } + if(streak) is.maxjump++; + } + is.seedoff = depth; + is.seedoffidx = seedoffidx; + is.fw = fw; + is.s = *this; + return ret; +} + +/** + * Return a set consisting of 1 seed encapsulating an exact matching + * strategy. + */ +void +Seed::zeroMmSeeds(int ln, EList& pols, Constraint& oall) { + oall.init(); + // Seed policy 1: left-to-right search + pols.expand(); + pols.back().len = ln; + pols.back().type = SEED_TYPE_EXACT; + pols.back().zones[0] = Constraint::exact(); + pols.back().zones[1] = Constraint::exact(); + pols.back().zones[2] = Constraint::exact(); // not used + pols.back().overall = &oall; +} + +/** + * Return a set of 2 seeds encapsulating a half-and-half 1mm strategy. + */ +void +Seed::oneMmSeeds(int ln, EList& pols, Constraint& oall) { + oall.init(); + // Seed policy 1: left-to-right search + pols.expand(); + pols.back().len = ln; + pols.back().type = SEED_TYPE_LEFT_TO_RIGHT; + pols.back().zones[0] = Constraint::exact(); + pols.back().zones[1] = Constraint::mmBased(1); + pols.back().zones[2] = Constraint::exact(); // not used + pols.back().overall = &oall; + // Seed policy 2: right-to-left search + pols.expand(); + pols.back().len = ln; + pols.back().type = SEED_TYPE_RIGHT_TO_LEFT; + pols.back().zones[0] = Constraint::exact(); + pols.back().zones[1] = Constraint::mmBased(1); + pols.back().zones[1].mmsCeil = 0; + pols.back().zones[2] = Constraint::exact(); // not used + pols.back().overall = &oall; +} + +/** + * Return a set of 3 seeds encapsulating search roots for: + * + * 1. Starting from the left-hand side and searching toward the + * right-hand side allowing 2 mismatches in the right half. + * 2. Starting from the right-hand side and searching toward the + * left-hand side allowing 2 mismatches in the left half. + * 3. Starting (effectively) from the center and searching out toward + * both the left and right-hand sides, allowing one mismatch on + * either side. + * + * This is not exhaustive. There are 2 mismatch cases mised; if you + * imagine the seed as divided into four successive quarters A, B, C + * and D, the cases we miss are when mismatches occur in A and C or B + * and D. + */ +void +Seed::twoMmSeeds(int ln, EList& pols, Constraint& oall) { + oall.init(); + // Seed policy 1: left-to-right search + pols.expand(); + pols.back().len = ln; + pols.back().type = SEED_TYPE_LEFT_TO_RIGHT; + pols.back().zones[0] = Constraint::exact(); + pols.back().zones[1] = Constraint::mmBased(2); + pols.back().zones[2] = Constraint::exact(); // not used + pols.back().overall = &oall; + // Seed policy 2: right-to-left search + pols.expand(); + pols.back().len = ln; + pols.back().type = SEED_TYPE_RIGHT_TO_LEFT; + pols.back().zones[0] = Constraint::exact(); + pols.back().zones[1] = Constraint::mmBased(2); + pols.back().zones[1].mmsCeil = 1; // Must have used at least 1 mismatch + pols.back().zones[2] = Constraint::exact(); // not used + pols.back().overall = &oall; + // Seed policy 3: inside-out search + pols.expand(); + pols.back().len = ln; + pols.back().type = SEED_TYPE_INSIDE_OUT; + pols.back().zones[0] = Constraint::exact(); + pols.back().zones[1] = Constraint::mmBased(1); + pols.back().zones[1].mmsCeil = 0; // Must have used at least 1 mismatch + pols.back().zones[2] = Constraint::mmBased(1); + pols.back().zones[2].mmsCeil = 0; // Must have used at least 1 mismatch + pols.back().overall = &oall; +} + +/** + * Types of actions that can be taken by the SeedAligner. + */ +enum { + SA_ACTION_TYPE_RESET = 1, + SA_ACTION_TYPE_SEARCH_SEED, // 2 + SA_ACTION_TYPE_FTAB, // 3 + SA_ACTION_TYPE_FCHR, // 4 + SA_ACTION_TYPE_MATCH, // 5 + SA_ACTION_TYPE_EDIT // 6 +}; + +#define MIN(x, y) ((x < y) ? x : y) + +#ifdef ALIGNER_SEED_MAIN + +#include +#include + +/** + * Parse an int out of optarg and enforce that it be at least 'lower'; + * if it is less than 'lower', than output the given error message and + * exit with an error and a usage message. + */ +static int parseInt(const char *errmsg, const char *arg) { + long l; + char *endPtr = NULL; + l = strtol(arg, &endPtr, 10); + if (endPtr != NULL) { + return (int32_t)l; + } + cerr << errmsg << endl; + throw 1; + return -1; +} + +enum { + ARG_NOFW = 256, + ARG_NORC, + ARG_MM, + ARG_SHMEM, + ARG_TESTS, + ARG_RANDOM_TESTS, + ARG_SEED +}; + +static const char *short_opts = "vCt"; +static struct option long_opts[] = { + {(char*)"verbose", no_argument, 0, 'v'}, + {(char*)"color", no_argument, 0, 'C'}, + {(char*)"timing", no_argument, 0, 't'}, + {(char*)"nofw", no_argument, 0, ARG_NOFW}, + {(char*)"norc", no_argument, 0, ARG_NORC}, + {(char*)"mm", no_argument, 0, ARG_MM}, + {(char*)"shmem", no_argument, 0, ARG_SHMEM}, + {(char*)"tests", no_argument, 0, ARG_TESTS}, + {(char*)"random", required_argument, 0, ARG_RANDOM_TESTS}, + {(char*)"seed", required_argument, 0, ARG_SEED}, +}; + +static void printUsage(ostream& os) { + os << "Usage: ac [options]* " << endl; + os << "Options:" << endl; + os << " --mm memory-mapped mode" << endl; + os << " --shmem shared memory mode" << endl; + os << " --nofw don't align forward-oriented read" << endl; + os << " --norc don't align reverse-complemented read" << endl; + os << " -t/--timing show timing information" << endl; + os << " -C/--color colorspace mode" << endl; + os << " -v/--verbose talkative mode" << endl; +} + +bool gNorc = false; +bool gNofw = false; +bool gColor = false; +int gVerbose = 0; +int gGapBarrier = 1; +bool gColorExEnds = true; +int gSnpPhred = 30; +bool gReportOverhangs = true; + +extern void aligner_seed_tests(); +extern void aligner_random_seed_tests( + int num_tests, + uint32_t qslo, + uint32_t qshi, + bool color, + uint32_t seed); + +/** + * A way of feeding simply tests to the seed alignment infrastructure. + */ +int main(int argc, char **argv) { + bool useMm = false; + bool useShmem = false; + bool mmSweep = false; + bool noRefNames = false; + bool sanity = false; + bool timing = false; + int option_index = 0; + int seed = 777; + int next_option; + do { + next_option = getopt_long( + argc, argv, short_opts, long_opts, &option_index); + switch (next_option) { + case 'v': gVerbose = true; break; + case 'C': gColor = true; break; + case 't': timing = true; break; + case ARG_NOFW: gNofw = true; break; + case ARG_NORC: gNorc = true; break; + case ARG_MM: useMm = true; break; + case ARG_SHMEM: useShmem = true; break; + case ARG_SEED: seed = parseInt("", optarg); break; + case ARG_TESTS: { + aligner_seed_tests(); + aligner_random_seed_tests( + 100, // num references + 100, // queries per reference lo + 400, // queries per reference hi + false, // true -> generate colorspace reference/reads + 18); // pseudo-random seed + return 0; + } + case ARG_RANDOM_TESTS: { + seed = parseInt("", optarg); + aligner_random_seed_tests( + 100, // num references + 100, // queries per reference lo + 400, // queries per reference hi + false, // true -> generate colorspace reference/reads + seed); // pseudo-random seed + return 0; + } + case -1: break; + default: { + cerr << "Unknown option: " << (char)next_option << endl; + printUsage(cerr); + exit(1); + } + } + } while(next_option != -1); + char *reffn; + if(optind >= argc) { + cerr << "No reference; quitting..." << endl; + return 1; + } + reffn = argv[optind++]; + if(optind >= argc) { + cerr << "No reads; quitting..." << endl; + return 1; + } + string gfmBase(reffn); + BitPairReference ref( + gfmBase, // base path + gColor, // whether we expect it to be colorspace + sanity, // whether to sanity-check reference as it's loaded + NULL, // fasta files to sanity check reference against + NULL, // another way of specifying original sequences + false, // true -> infiles (2 args ago) contains raw seqs + useMm, // use memory mapping to load index? + useShmem, // use shared memory (not memory mapping) + mmSweep, // touch all the pages after memory-mapping the index + gVerbose, // verbose + gVerbose); // verbose but just for startup messages + Timer *t = new Timer(cerr, "Time loading fw index: ", timing); + GFM gfmFw( + gfmBase, + 0, // don't need entireReverse for fw index + true, // index is for the forward direction + -1, // offrate (irrelevant) + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + false, // load SA sample? + true, // load ftab? + true, // load rstarts? + NULL, // reference map, or NULL if none is needed + gVerbose, // whether to be talkative + gVerbose, // talkative during initialization + false, // handle memory exceptions, don't pass them up + sanity); + delete t; + t = new Timer(cerr, "Time loading bw index: ", timing); + GFM gfmBw( + gfmBase + ".rev", + 1, // need entireReverse + false, // index is for the backward direction + -1, // offrate (irrelevant) + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + false, // load SA sample? + true, // load ftab? + false, // load rstarts? + NULL, // reference map, or NULL if none is needed + gVerbose, // whether to be talkative + gVerbose, // talkative during initialization + false, // handle memory exceptions, don't pass them up + sanity); + delete t; + for(int i = optind; i < argc; i++) { + } +} +#endif diff --git a/aligner_seed.h b/aligner_seed.h new file mode 100644 index 0000000..a832fd4 --- /dev/null +++ b/aligner_seed.h @@ -0,0 +1,2922 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_SEED_H_ +#define ALIGNER_SEED_H_ + +#include +#include +#include +#include "qual.h" +#include "ds.h" +#include "sstring.h" +#include "alphabet.h" +#include "edit.h" +#include "read.h" +// Threading is necessary to synchronize the classes that dump +// intermediate alignment results to files. Otherwise, all data herein +// is constant and shared, or per-thread. +#include "threading.h" +#include "aligner_result.h" +#include "aligner_cache.h" +#include "scoring.h" +#include "mem_ids.h" +#include "simple_func.h" +#include "btypes.h" + +/** + * A constraint to apply to an alignment zone, or to an overall + * alignment. + * + * The constraint can put both caps and ceilings on the number and + * types of edits allowed. + */ +struct Constraint { + + Constraint() { init(); } + + /** + * Initialize Constraint to be fully permissive. + */ + void init() { + edits = mms = ins = dels = penalty = editsCeil = mmsCeil = + insCeil = delsCeil = penaltyCeil = MAX_I; + penFunc.reset(); + instantiated = false; + } + + /** + * Return true iff penalities and constraints prevent us from + * adding any edits. + */ + bool mustMatch() { + assert(instantiated); + return (mms == 0 && edits == 0) || + penalty == 0 || + (mms == 0 && dels == 0 && ins == 0); + } + + /** + * Return true iff a mismatch of the given quality is permitted. + */ + bool canMismatch(int q, const Scoring& cm) { + assert(instantiated); + return (mms > 0 || edits > 0) && + penalty >= cm.mm(q); + } + + /** + * Return true iff a mismatch of the given quality is permitted. + */ + bool canN(int q, const Scoring& cm) { + assert(instantiated); + return (mms > 0 || edits > 0) && + penalty >= cm.n(q); + } + + /** + * Return true iff a mismatch of *any* quality (even qual=1) is + * permitted. + */ + bool canMismatch() { + assert(instantiated); + return (mms > 0 || edits > 0) && penalty > 0; + } + + /** + * Return true iff a mismatch of *any* quality (even qual=1) is + * permitted. + */ + bool canN() { + assert(instantiated); + return (mms > 0 || edits > 0); + } + + /** + * Return true iff a deletion of the given extension (0=open, 1=1st + * extension, etc) is permitted. + */ + bool canDelete(int ex, const Scoring& cm) { + assert(instantiated); + return (dels > 0 && edits > 0) && + penalty >= cm.del(ex); + } + + /** + * Return true iff a deletion of any extension is permitted. + */ + bool canDelete() { + assert(instantiated); + return (dels > 0 || edits > 0) && + penalty > 0; + } + + /** + * Return true iff an insertion of the given extension (0=open, + * 1=1st extension, etc) is permitted. + */ + bool canInsert(int ex, const Scoring& cm) { + assert(instantiated); + return (ins > 0 || edits > 0) && + penalty >= cm.ins(ex); + } + + /** + * Return true iff an insertion of any extension is permitted. + */ + bool canInsert() { + assert(instantiated); + return (ins > 0 || edits > 0) && + penalty > 0; + } + + /** + * Return true iff a gap of any extension is permitted + */ + bool canGap() { + assert(instantiated); + return ((ins > 0 || dels > 0) || edits > 0) && penalty > 0; + } + + /** + * Charge a mismatch of the given quality. + */ + void chargeMismatch(int q, const Scoring& cm) { + assert(instantiated); + if(mms == 0) { assert_gt(edits, 0); edits--; } + else mms--; + penalty -= cm.mm(q); + assert_geq(mms, 0); + assert_geq(edits, 0); + assert_geq(penalty, 0); + } + + /** + * Charge an N mismatch of the given quality. + */ + void chargeN(int q, const Scoring& cm) { + assert(instantiated); + if(mms == 0) { assert_gt(edits, 0); edits--; } + else mms--; + penalty -= cm.n(q); + assert_geq(mms, 0); + assert_geq(edits, 0); + assert_geq(penalty, 0); + } + + /** + * Charge a deletion of the given extension. + */ + void chargeDelete(int ex, const Scoring& cm) { + assert(instantiated); + dels--; + edits--; + penalty -= cm.del(ex); + assert_geq(dels, 0); + assert_geq(edits, 0); + assert_geq(penalty, 0); + } + + /** + * Charge an insertion of the given extension. + */ + void chargeInsert(int ex, const Scoring& cm) { + assert(instantiated); + ins--; + edits--; + penalty -= cm.ins(ex); + assert_geq(ins, 0); + assert_geq(edits, 0); + assert_geq(penalty, 0); + } + + /** + * Once the constrained area is completely explored, call this + * function to check whether there were *at least* as many + * dissimilarities as required by the constraint. Bounds like this + * are helpful to resolve instances where two search roots would + * otherwise overlap in what alignments they can find. + */ + bool acceptable() { + assert(instantiated); + return edits <= editsCeil && + mms <= mmsCeil && + ins <= insCeil && + dels <= delsCeil && + penalty <= penaltyCeil; + } + + /** + * Instantiate a constraint w/r/t the read length and the constant + * and linear coefficients for the penalty function. + */ + static int instantiate(size_t rdlen, const SimpleFunc& func) { + return func.f((double)rdlen); + } + + /** + * Instantiate this constraint w/r/t the read length. + */ + void instantiate(size_t rdlen) { + assert(!instantiated); + if(penFunc.initialized()) { + penalty = Constraint::instantiate(rdlen, penFunc); + } + instantiated = true; + } + + int edits; // # edits permitted + int mms; // # mismatches permitted + int ins; // # insertions permitted + int dels; // # deletions permitted + int penalty; // penalty total permitted + int editsCeil; // <= this many edits can be left at the end + int mmsCeil; // <= this many mismatches can be left at the end + int insCeil; // <= this many inserts can be left at the end + int delsCeil; // <= this many deletions can be left at the end + int penaltyCeil;// <= this much leftover penalty can be left at the end + SimpleFunc penFunc;// penalty function; function of read len + bool instantiated; // whether constraint is instantiated w/r/t read len + + // + // Some static methods for constructing some standard Constraints + // + + /** + * Construct a constraint with no edits of any kind allowed. + */ + static Constraint exact(); + + /** + * Construct a constraint where the only constraint is a total + * penalty constraint. + */ + static Constraint penaltyBased(int pen); + + /** + * Construct a constraint where the only constraint is a total + * penalty constraint related to the length of the read. + */ + static Constraint penaltyFuncBased(const SimpleFunc& func); + + /** + * Construct a constraint where the only constraint is a total + * penalty constraint. + */ + static Constraint mmBased(int mms); + + /** + * Construct a constraint where the only constraint is a total + * penalty constraint. + */ + static Constraint editBased(int edits); +}; + +/** + * We divide seed search strategies into three categories: + * + * 1. A left-to-right search where the left half of the read is + * constrained to match exactly and the right half is subject to + * some looser constraint (e.g. 1mm or 2mm) + * 2. Same as 1, but going right to left with the exact matching half + * on the right. + * 3. Inside-out search where the center half of the read is + * constrained to match exactly, and the extreme quarters of the + * read are subject to a looser constraint. + */ +enum { + SEED_TYPE_EXACT = 1, + SEED_TYPE_LEFT_TO_RIGHT, + SEED_TYPE_RIGHT_TO_LEFT, + SEED_TYPE_INSIDE_OUT +}; + +struct InstantiatedSeed; + +/** + * Policy dictating how to size and arrange seeds along the length of + * the read, and what constraints to force on the zones of the seed. + * We assume that seeds are plopped down at regular intervals from the + * 5' to 3' ends, with the first seed flush to the 5' end. + * + * If the read is shorter than a single seed, one seed is used and it + * is shrunk to accommodate the read. + */ +struct Seed { + + int len; // length of a seed + int type; // dictates anchor portion, direction of search + Constraint *overall; // for the overall alignment + + Seed() { init(0, 0, NULL); } + + /** + * Construct and initialize this seed with given length and type. + */ + Seed(int ln, int ty, Constraint* oc) { + init(ln, ty, oc); + } + + /** + * Initialize this seed with given length and type. + */ + void init(int ln, int ty, Constraint* oc) { + len = ln; + type = ty; + overall = oc; + } + + // If the seed is split into halves, we just use zones[0] and + // zones[1]; 0 is the near half and 1 is the far half. If the seed + // is split into thirds (i.e. inside-out) then 0 is the center, 1 + // is the far portion on the left, and 2 is the far portion on the + // right. + Constraint zones[3]; + + /** + * Once the constrained seed is completely explored, call this + * function to check whether there were *at least* as many + * dissimilarities as required by all constraints. Bounds like this + * are helpful to resolve instances where two search roots would + * otherwise overlap in what alignments they can find. + */ + bool acceptable() { + assert(overall != NULL); + return zones[0].acceptable() && + zones[1].acceptable() && + zones[2].acceptable() && + overall->acceptable(); + } + + /** + * Given a read, depth and orientation, extract a seed data structure + * from the read and fill in the steps & zones arrays. The Seed + * contains the sequence and quality values. + */ + bool instantiate( + const Read& read, + const BTDnaString& seq, // already-extracted seed sequence + const BTString& qual, // already-extracted seed quality sequence + const Scoring& pens, + int depth, + int seedoffidx, + int seedtypeidx, + bool fw, + InstantiatedSeed& si) const; + + /** + * Return a list of Seed objects encapsulating + */ + static void mmSeeds( + int mms, + int ln, + EList& pols, + Constraint& oall) + { + if(mms == 0) { + zeroMmSeeds(ln, pols, oall); + } else if(mms == 1) { + oneMmSeeds(ln, pols, oall); + } else if(mms == 2) { + twoMmSeeds(ln, pols, oall); + } else throw 1; + } + + static void zeroMmSeeds(int ln, EList&, Constraint&); + static void oneMmSeeds (int ln, EList&, Constraint&); + static void twoMmSeeds (int ln, EList&, Constraint&); +}; + +/** + * An instantiated seed is a seed (perhaps modified to fit the read) + * plus all data needed to conduct a search of the seed. + */ +struct InstantiatedSeed { + + InstantiatedSeed() : steps(AL_CAT), zones(AL_CAT) { } + + // Steps map. There are as many steps as there are positions in + // the seed. The map is a helpful abstraction because we sometimes + // visit seed positions in an irregular order (e.g. inside-out + // search). + EList steps; + + // Zones map. For each step, records what constraint to charge an + // edit to. The first entry in each pair gives the constraint for + // non-insert edits and the second entry in each pair gives the + // constraint for insert edits. If the value stored is negative, + // this indicates that the zone is "closed out" after this + // position, so zone acceptility should be checked. + EList > zones; + + // Nucleotide sequence covering the seed, extracted from read + BTDnaString *seq; + + // Quality sequence covering the seed, extracted from read + BTString *qual; + + // Initial constraints governing zones 0, 1, 2. We precalculate + // the effect of Ns on these. + Constraint cons[3]; + + // Overall constraint, tailored to the read length. + Constraint overall; + + // Maximum number of positions that the aligner may advance before + // its first step. This lets the aligner know whether it can use + // the ftab or not. + int maxjump; + + // Offset of seed from 5' end of read + int seedoff; + + // Id for seed offset; ids are such that the smallest index is the + // closest to the 5' end and consecutive ids are adjacent (i.e. + // there are no intervening offsets with seeds) + int seedoffidx; + + // Type of seed (left-to-right, etc) + int seedtypeidx; + + // Seed comes from forward-oriented read? + bool fw; + + // Filtered out due to the pattern of Ns present. If true, this + // seed should be ignored by searchAllSeeds(). + bool nfiltered; + + // Seed this was instantiated from + Seed s; + +#ifndef NDEBUG + /** + * Check that InstantiatedSeed is internally consistent. + */ + bool repOk() const { + return true; + } +#endif +}; + +/** + * Simple struct for holding a end-to-end alignments for the read with at most + * 2 edits. + */ +template +struct EEHit { + + EEHit() { reset(); } + + void reset() { + top = bot = 0; + fw = false; + e1.reset(); + e2.reset(); + score = MIN_I64; + } + + void init( + index_t top_, + index_t bot_, + const Edit* e1_, + const Edit* e2_, + bool fw_, + int64_t score_) + { + top = top_; bot = bot_; + if(e1_ != NULL) { + e1 = *e1_; + } else { + e1.reset(); + } + if(e2_ != NULL) { + e2 = *e2_; + } else { + e2.reset(); + } + fw = fw_; + score = score_; + } + + /** + * Return number of mismatches in the alignment. + */ + int mms() const { + if (e2.inited()) return 2; + else if(e1.inited()) return 1; + else return 0; + } + + /** + * Return the number of Ns involved in the alignment. + */ + int ns() const { + int ns = 0; + if(e1.inited() && e1.hasN()) { + ns++; + if(e2.inited() && e2.hasN()) { + ns++; + } + } + return ns; + } + + /** + * Return the number of Ns involved in the alignment. + */ + int refns() const { + int ns = 0; + if(e1.inited() && e1.chr == 'N') { + ns++; + if(e2.inited() && e2.chr == 'N') { + ns++; + } + } + return ns; + } + + /** + * Return true iff there is no hit. + */ + bool empty() const { + return bot <= top; + } + + /** + * Higher score = higher priority. + */ + bool operator<(const EEHit& o) const { + return score > o.score; + } + + /** + * Return the size of the alignments SA range.s + */ + index_t size() const { return bot - top; } + +#ifndef NDEBUG + /** + * Check that hit is sane w/r/t read. + */ + bool repOk(const Read& rd) const { + assert_gt(bot, top); + if(e1.inited()) { + assert_lt(e1.pos, rd.length()); + if(e2.inited()) { + assert_lt(e2.pos, rd.length()); + } + } + return true; + } +#endif + + index_t top; + index_t bot; + Edit e1; + Edit e2; + bool fw; + int64_t score; +}; + +/** + * Data structure for holding all of the seed hits associated with a read. All + * the seed hits for a given read are encapsulated in a single QVal object. A + * QVal refers to a range of values in the qlist, where each qlist value is a + * BW range and a slot to hold the hit's suffix array offset. QVals are kept + * in two lists (hitsFw_ and hitsRc_), one for seeds on the forward read strand, + * one for seeds on the reverse read strand. The list is indexed by read + * offset index (e.g. 0=closest-to-5', 1=second-closest, etc). + * + * An assumption behind this data structure is that all the seeds are found + * first, then downstream analyses try to extend them. In between finding the + * seed hits and extending them, the sort() member function is called, which + * ranks QVals according to the order they should be extended. Right now the + * policy is that QVals with fewer elements (hits) should be tried first. + */ +template +class SeedResults { + +public: + SeedResults() : + seqFw_(AL_CAT), + seqRc_(AL_CAT), + qualFw_(AL_CAT), + qualRc_(AL_CAT), + hitsFw_(AL_CAT), + hitsRc_(AL_CAT), + isFw_(AL_CAT), + isRc_(AL_CAT), + sortedFw_(AL_CAT), + sortedRc_(AL_CAT), + offIdx2off_(AL_CAT), + rankOffs_(AL_CAT), + rankFws_(AL_CAT), + mm1Hit_(AL_CAT) + { + clear(); + } + + /** + * Set the current read. + */ + void nextRead(const Read& read) { + read_ = &read; + } + + /** + * Set the appropriate element of either hitsFw_ or hitsRc_ to the given + * QVal. A QVal encapsulates all the BW ranges for reference substrings + * that are within some distance of the seed string. + */ + void add( + const QVal& qv, // range of ranges in cache + const AlignmentCache& ac, // cache + index_t seedIdx, // seed index (from 5' end) + bool seedFw) // whether seed is from forward read + { + assert(qv.repOk(ac)); + assert(repOk(&ac)); + assert_lt(seedIdx, hitsFw_.size()); + assert_gt(numOffs_, 0); // if this fails, probably failed to call reset + if(qv.empty()) return; + if(seedFw) { + assert(!hitsFw_[seedIdx].valid()); + hitsFw_[seedIdx] = qv; + numEltsFw_ += qv.numElts(); + numRangesFw_ += qv.numRanges(); + if(qv.numRanges() > 0) nonzFw_++; + } else { + assert(!hitsRc_[seedIdx].valid()); + hitsRc_[seedIdx] = qv; + numEltsRc_ += qv.numElts(); + numRangesRc_ += qv.numRanges(); + if(qv.numRanges() > 0) nonzRc_++; + } + numElts_ += qv.numElts(); + numRanges_ += qv.numRanges(); + if(qv.numRanges() > 0) { + nonzTot_++; + } + assert(repOk(&ac)); + } + + /** + * Clear buffered seed hits and state. Set the number of seed + * offsets and the read. + */ + void reset( + const Read& read, + const EList& offIdx2off, + size_t numOffs) + { + assert_gt(numOffs, 0); + clearSeeds(); + numOffs_ = numOffs; + seqFw_.resize(numOffs_); + seqRc_.resize(numOffs_); + qualFw_.resize(numOffs_); + qualRc_.resize(numOffs_); + hitsFw_.resize(numOffs_); + hitsRc_.resize(numOffs_); + isFw_.resize(numOffs_); + isRc_.resize(numOffs_); + sortedFw_.resize(numOffs_); + sortedRc_.resize(numOffs_); + offIdx2off_ = offIdx2off; + for(size_t i = 0; i < numOffs_; i++) { + sortedFw_[i] = sortedRc_[i] = false; + hitsFw_[i].reset(); + hitsRc_[i].reset(); + isFw_[i].clear(); + isRc_[i].clear(); + } + read_ = &read; + sorted_ = false; + } + + /** + * Clear seed-hit state. + */ + void clearSeeds() { + sortedFw_.clear(); + sortedRc_.clear(); + rankOffs_.clear(); + rankFws_.clear(); + offIdx2off_.clear(); + hitsFw_.clear(); + hitsRc_.clear(); + isFw_.clear(); + isRc_.clear(); + seqFw_.clear(); + seqRc_.clear(); + nonzTot_ = 0; + nonzFw_ = 0; + nonzRc_ = 0; + numOffs_ = 0; + numRanges_ = 0; + numElts_ = 0; + numRangesFw_ = 0; + numEltsFw_ = 0; + numRangesRc_ = 0; + numEltsRc_ = 0; + } + + /** + * Clear seed-hit state and end-to-end alignment state. + */ + void clear() { + clearSeeds(); + read_ = NULL; + exactFwHit_.reset(); + exactRcHit_.reset(); + mm1Hit_.clear(); + mm1Sorted_ = false; + mm1Elt_ = 0; + assert(empty()); + } + + /** + * Extract key summaries from this SeedResults and put into 'ssum'. + */ + void toSeedAlSumm(SeedAlSumm& ssum) const { + // Number of positions with at least 1 range + ssum.nonzTot = nonzTot_; + ssum.nonzFw = nonzFw_; + ssum.nonzRc = nonzRc_; + + // Number of ranges + ssum.nrangeTot = numRanges_; + ssum.nrangeFw = numRangesFw_; + ssum.nrangeRc = numRangesRc_; + + // Number of elements + ssum.neltTot = numElts_; + ssum.neltFw = numEltsFw_; + ssum.neltRc = numEltsRc_; + + // Other summaries + ssum.maxNonzRangeFw = ssum.minNonzRangeFw = 0; + ssum.maxNonzRangeRc = ssum.minNonzRangeRc = 0; + ssum.maxNonzEltFw = ssum.minNonzEltFw = 0; + ssum.maxNonzEltRc = ssum.minNonzEltRc = 0; + for(size_t i = 0; i < numOffs_; i++) { + if(hitsFw_[i].valid()) { + if(ssum.minNonzEltFw == 0 || hitsFw_[i].numElts() < ssum.minNonzEltFw) { + ssum.minNonzEltFw = hitsFw_[i].numElts(); + } + if(ssum.maxNonzEltFw == 0 || hitsFw_[i].numElts() > ssum.maxNonzEltFw) { + ssum.maxNonzEltFw = hitsFw_[i].numElts(); + } + if(ssum.minNonzRangeFw == 0 || hitsFw_[i].numRanges() < ssum.minNonzRangeFw) { + ssum.minNonzRangeFw = hitsFw_[i].numRanges(); + } + if(ssum.maxNonzRangeFw == 0 || hitsFw_[i].numRanges() > ssum.maxNonzRangeFw) { + ssum.maxNonzRangeFw = hitsFw_[i].numRanges(); + } + } + if(hitsRc_[i].valid()) { + if(ssum.minNonzEltRc == 0 || hitsRc_[i].numElts() < ssum.minNonzEltRc) { + ssum.minNonzEltRc = hitsRc_[i].numElts(); + } + if(ssum.maxNonzEltRc == 0 || hitsRc_[i].numElts() > ssum.maxNonzEltRc) { + ssum.maxNonzEltRc = hitsRc_[i].numElts(); + } + if(ssum.minNonzRangeRc == 0 || hitsRc_[i].numRanges() < ssum.minNonzRangeRc) { + ssum.minNonzRangeRc = hitsRc_[i].numRanges(); + } + if(ssum.maxNonzRangeRc == 0 || hitsRc_[i].numRanges() > ssum.maxNonzRangeRc) { + ssum.maxNonzRangeRc = hitsRc_[i].numRanges(); + } + } + } + } + + /** + * Return average number of hits per seed. + */ + float averageHitsPerSeed() const { + return (float)numElts_ / (float)nonzTot_; + } + + /** + * Return median of all the non-zero per-seed # hits + */ + float medianHitsPerSeed() const { + EList& median = const_cast&>(tmpMedian_); + median.clear(); + for(size_t i = 0; i < numOffs_; i++) { + if(hitsFw_[i].valid() && hitsFw_[i].numElts() > 0) { + median.push_back(hitsFw_[i].numElts()); + } + if(hitsRc_[i].valid() && hitsRc_[i].numElts() > 0) { + median.push_back(hitsRc_[i].numElts()); + } + } + if(tmpMedian_.empty()) { + return 0.0f; + } + median.sort(); + float med1 = (float)median[tmpMedian_.size() >> 1]; + float med2 = med1; + if((median.size() & 1) == 0) { + med2 = (float)median[(tmpMedian_.size() >> 1) - 1]; + } + return med1 + med2 * 0.5f; + } + + /** + * Return a number that's meant to quantify how hopeful we are that this + * set of seed hits will lead to good alignments. + */ + double uniquenessFactor() const { + double result = 0.0; + for(size_t i = 0; i < numOffs_; i++) { + if(hitsFw_[i].valid()) { + size_t nelt = hitsFw_[i].numElts(); + result += (1.0 / (double)(nelt * nelt)); + } + if(hitsRc_[i].valid()) { + size_t nelt = hitsRc_[i].numElts(); + result += (1.0 / (double)(nelt * nelt)); + } + } + return result; + } + + /** + * Return the number of ranges being held. + */ + index_t numRanges() const { return numRanges_; } + + /** + * Return the number of elements being held. + */ + index_t numElts() const { return numElts_; } + + /** + * Return the number of ranges being held for seeds on the forward + * read strand. + */ + index_t numRangesFw() const { return numRangesFw_; } + + /** + * Return the number of elements being held for seeds on the + * forward read strand. + */ + index_t numEltsFw() const { return numEltsFw_; } + + /** + * Return the number of ranges being held for seeds on the + * reverse-complement read strand. + */ + index_t numRangesRc() const { return numRangesRc_; } + + /** + * Return the number of elements being held for seeds on the + * reverse-complement read strand. + */ + index_t numEltsRc() const { return numEltsRc_; } + + /** + * Given an offset index, return the offset that has that index. + */ + index_t idx2off(size_t off) const { + return offIdx2off_[off]; + } + + /** + * Return true iff there are 0 hits being held. + */ + bool empty() const { return numRanges() == 0; } + + /** + * Get the QVal representing all the reference hits for the given + * orientation and seed offset index. + */ + const QVal& hitsAtOffIdx(bool fw, size_t seedoffidx) const { + assert_lt(seedoffidx, numOffs_); + assert(repOk(NULL)); + return fw ? hitsFw_[seedoffidx] : hitsRc_[seedoffidx]; + } + + /** + * Get the Instantiated seeds for the given orientation and offset. + */ + EList& instantiatedSeeds(bool fw, size_t seedoffidx) { + assert_lt(seedoffidx, numOffs_); + assert(repOk(NULL)); + return fw ? isFw_[seedoffidx] : isRc_[seedoffidx]; + } + + /** + * Return the number of different seed offsets possible. + */ + index_t numOffs() const { return numOffs_; } + + /** + * Return the read from which seeds were extracted, aligned. + */ + const Read& read() const { return *read_; } + +#ifndef NDEBUG + /** + * Check that this SeedResults is internally consistent. + */ + bool repOk( + const AlignmentCache* ac, + bool requireInited = false) const + { + if(requireInited) { + assert(read_ != NULL); + } + if(numOffs_ > 0) { + assert_eq(numOffs_, hitsFw_.size()); + assert_eq(numOffs_, hitsRc_.size()); + assert_leq(numRanges_, numElts_); + assert_leq(nonzTot_, numRanges_); + size_t nonzs = 0; + for(int fw = 0; fw <= 1; fw++) { + const EList >& rrs = (fw ? hitsFw_ : hitsRc_); + for(size_t i = 0; i < numOffs_; i++) { + if(rrs[i].valid()) { + if(rrs[i].numRanges() > 0) nonzs++; + if(ac != NULL) { + assert(rrs[i].repOk(*ac)); + } + } + } + } + assert_eq(nonzs, nonzTot_); + assert(!sorted_ || nonzTot_ == rankFws_.size()); + assert(!sorted_ || nonzTot_ == rankOffs_.size()); + } + return true; + } +#endif + + /** + * Populate rankOffs_ and rankFws_ with the list of QVals that need to be + * examined for this SeedResults, in order. The order is ascending by + * number of elements, so QVals with fewer elements (i.e. seed sequences + * that are more unique) will be tried first and QVals with more elements + * (i.e. seed sequences + */ + void rankSeedHits(RandomSource& rnd) { + while(rankOffs_.size() < nonzTot_) { + index_t minsz = (index_t)0xffffffff; + index_t minidx = 0; + bool minfw = true; + // Rank seed-hit positions in ascending order by number of elements + // in all BW ranges + bool rb = rnd.nextBool(); + assert(rb == 0 || rb == 1); + for(int fwi = 0; fwi <= 1; fwi++) { + bool fw = (fwi == (rb ? 1 : 0)); + EList >& rrs = (fw ? hitsFw_ : hitsRc_); + EList& sorted = (fw ? sortedFw_ : sortedRc_); + index_t i = (rnd.nextU32() % (index_t)numOffs_); + for(index_t ii = 0; ii < numOffs_; ii++) { + if(rrs[i].valid() && // valid QVal + rrs[i].numElts() > 0 && // non-empty + !sorted[i] && // not already sorted + rrs[i].numElts() < minsz) // least elts so far? + { + minsz = rrs[i].numElts(); + minidx = i; + minfw = (fw == 1); + } + if((++i) == numOffs_) { + i = 0; + } + } + } + assert_neq((index_t)0xffffffff, minsz); + if(minfw) { + sortedFw_[minidx] = true; + } else { + sortedRc_[minidx] = true; + } + rankOffs_.push_back(minidx); + rankFws_.push_back(minfw); + } + assert_eq(rankOffs_.size(), rankFws_.size()); + sorted_ = true; + } + + /** + * Return the number of orientation/offsets into the read that have + * at least one seed hit. + */ + size_t nonzeroOffsets() const { + assert(!sorted_ || nonzTot_ == rankFws_.size()); + assert(!sorted_ || nonzTot_ == rankOffs_.size()); + return nonzTot_; + } + + /** + * Return true iff all seeds hit for forward read. + */ + bool allFwSeedsHit() const { + return nonzFw_ == numOffs(); + } + + /** + * Return true iff all seeds hit for revcomp read. + */ + bool allRcSeedsHit() const { + return nonzRc_ == numOffs(); + } + + /** + * Return the minimum number of edits that an end-to-end alignment of the + * fw read could have. Uses knowledge of how many seeds have exact hits + * and how the seeds overlap. + */ + index_t fewestEditsEE(bool fw, int seedlen, int per) const { + assert_gt(seedlen, 0); + assert_gt(per, 0); + index_t nonz = fw ? nonzFw_ : nonzRc_; + if(nonz < numOffs()) { + int maxdepth = (seedlen + per - 1) / per; + int missing = (int)(numOffs() - nonz); + return (missing + maxdepth - 1) / maxdepth; + } else { + // Exact hit is possible (not guaranteed) + return 0; + } + } + + /** + * Return the number of offsets into the forward read that have at + * least one seed hit. + */ + index_t nonzeroOffsetsFw() const { + return nonzFw_; + } + + /** + * Return the number of offsets into the reverse-complement read + * that have at least one seed hit. + */ + index_t nonzeroOffsetsRc() const { + return nonzRc_; + } + + /** + * Return a QVal of seed hits of the given rank 'r'. 'offidx' gets the id + * of the offset from 5' from which it was extracted (0 for the 5-most + * offset, 1 for the next closes to 5', etc). 'off' gets the offset from + * the 5' end. 'fw' gets true iff the seed was extracted from the forward + * read. + */ + const QVal& hitsByRank( + index_t r, // in + index_t& offidx, // out + index_t& off, // out + bool& fw, // out + index_t& seedlen) // out + { + assert(sorted_); + assert_lt(r, nonzTot_); + if(rankFws_[r]) { + fw = true; + offidx = rankOffs_[r]; + assert_lt(offidx, offIdx2off_.size()); + off = offIdx2off_[offidx]; + seedlen = (index_t)seqFw_[rankOffs_[r]].length(); + return hitsFw_[rankOffs_[r]]; + } else { + fw = false; + offidx = rankOffs_[r]; + assert_lt(offidx, offIdx2off_.size()); + off = offIdx2off_[offidx]; + seedlen = (index_t)seqRc_[rankOffs_[r]].length(); + return hitsRc_[rankOffs_[r]]; + } + } + + /** + * Return an EList of seed hits of the given rank. + */ + const BTDnaString& seqByRank(index_t r) { + assert(sorted_); + assert_lt(r, nonzTot_); + return rankFws_[r] ? seqFw_[rankOffs_[r]] : seqRc_[rankOffs_[r]]; + } + + /** + * Return an EList of seed hits of the given rank. + */ + const BTString& qualByRank(index_t r) { + assert(sorted_); + assert_lt(r, nonzTot_); + return rankFws_[r] ? qualFw_[rankOffs_[r]] : qualRc_[rankOffs_[r]]; + } + + /** + * Return the list of extracted seed sequences for seeds on either + * the forward or reverse strand. + */ + EList& seqs(bool fw) { return fw ? seqFw_ : seqRc_; } + + /** + * Return the list of extracted quality sequences for seeds on + * either the forward or reverse strand. + */ + EList& quals(bool fw) { return fw ? qualFw_ : qualRc_; } + + /** + * Return exact end-to-end alignment of fw read. + */ + EEHit exactFwEEHit() const { return exactFwHit_; } + + /** + * Return exact end-to-end alignment of rc read. + */ + EEHit exactRcEEHit() const { return exactRcHit_; } + + /** + * Return const ref to list of 1-mismatch end-to-end alignments. + */ + const EList >& mm1EEHits() const { return mm1Hit_; } + + /** + * Sort the end-to-end 1-mismatch alignments, prioritizing by score (higher + * score = higher priority). + */ + void sort1mmEe(RandomSource& rnd) { + assert(!mm1Sorted_); + mm1Hit_.sort(); + size_t streak = 0; + for(size_t i = 1; i < mm1Hit_.size(); i++) { + if(mm1Hit_[i].score == mm1Hit_[i-1].score) { + if(streak == 0) { streak = 1; } + streak++; + } else { + if(streak > 1) { + assert_geq(i, streak); + mm1Hit_.shufflePortion(i-streak, streak, rnd); + } + streak = 0; + } + } + if(streak > 1) { + mm1Hit_.shufflePortion(mm1Hit_.size() - streak, streak, rnd); + } + mm1Sorted_ = true; + } + + /** + * Add an end-to-end 1-mismatch alignment. + */ + void add1mmEe( + index_t top, + index_t bot, + const Edit* e1, + const Edit* e2, + bool fw, + int64_t score) + { + mm1Hit_.expand(); + mm1Hit_.back().init(top, bot, e1, e2, fw, score); + mm1Elt_ += (bot - top); + } + + /** + * Add an end-to-end exact alignment. + */ + void addExactEeFw( + index_t top, + index_t bot, + const Edit* e1, + const Edit* e2, + bool fw, + int64_t score) + { + exactFwHit_.init(top, bot, e1, e2, fw, score); + } + + /** + * Add an end-to-end exact alignment. + */ + void addExactEeRc( + index_t top, + index_t bot, + const Edit* e1, + const Edit* e2, + bool fw, + int64_t score) + { + exactRcHit_.init(top, bot, e1, e2, fw, score); + } + + /** + * Clear out the end-to-end exact alignments. + */ + void clearExactE2eHits() { + exactFwHit_.reset(); + exactRcHit_.reset(); + } + + /** + * Clear out the end-to-end 1-mismatch alignments. + */ + void clear1mmE2eHits() { + mm1Hit_.clear(); // 1-mismatch end-to-end hits + mm1Elt_ = 0; // number of 1-mismatch hit rows + mm1Sorted_ = false; // true iff we've sorted the mm1Hit_ list + } + + /** + * Return the number of distinct exact and 1-mismatch end-to-end hits + * found. + */ + index_t numE2eHits() const { + return (index_t)(exactFwHit_.size() + exactRcHit_.size() + mm1Elt_); + } + + /** + * Return the number of distinct exact end-to-end hits found. + */ + index_t numExactE2eHits() const { + return (index_t)(exactFwHit_.size() + exactRcHit_.size()); + } + + /** + * Return the number of distinct 1-mismatch end-to-end hits found. + */ + index_t num1mmE2eHits() const { + return mm1Elt_; + } + + /** + * Return the length of the read that yielded the seed hits. + */ + index_t readLength() const { + assert(read_ != NULL); + return read_->length(); + } + +protected: + + // As seed hits and edits are added they're sorted into these + // containers + EList seqFw_; // seqs for seeds from forward read + EList seqRc_; // seqs for seeds from revcomp read + EList qualFw_; // quals for seeds from forward read + EList qualRc_; // quals for seeds from revcomp read + EList > hitsFw_; // hits for forward read + EList > hitsRc_; // hits for revcomp read + EList > isFw_; // hits for forward read + EList > isRc_; // hits for revcomp read + EList sortedFw_; // true iff fw QVal was sorted/ranked + EList sortedRc_; // true iff rc QVal was sorted/ranked + index_t nonzTot_; // # offsets with non-zero size + index_t nonzFw_; // # offsets into fw read with non-0 size + index_t nonzRc_; // # offsets into rc read with non-0 size + index_t numRanges_; // # ranges added + index_t numElts_; // # elements added + index_t numRangesFw_; // # ranges added for fw seeds + index_t numEltsFw_; // # elements added for fw seeds + index_t numRangesRc_; // # ranges added for rc seeds + index_t numEltsRc_; // # elements added for rc seeds + + EList offIdx2off_;// map from offset indexes to offsets from 5' end + + // When the sort routine is called, the seed hits collected so far + // are sorted into another set of containers that allow easy access + // to hits from the lowest-ranked offset (the one with the fewest + // BW elements) to the greatest-ranked offset. Offsets with 0 hits + // are ignored. + EList rankOffs_; // sorted offests of seeds to try + EList rankFws_; // sorted orientations assoc. with rankOffs_ + bool sorted_; // true if sort() called since last reset + + // These fields set once per read + index_t numOffs_; // # different seed offsets possible + const Read* read_; // read from which seeds were extracted + + EEHit exactFwHit_; // end-to-end exact hit for fw read + EEHit exactRcHit_; // end-to-end exact hit for rc read + EList > mm1Hit_; // 1-mismatch end-to-end hits + index_t mm1Elt_; // number of 1-mismatch hit rows + bool mm1Sorted_; // true iff we've sorted the mm1Hit_ list + + EList tmpMedian_; // temporary storage for calculating median +}; + + +// Forward decl +template class Ebwt; +template struct SideLocus; + +/** + * Encapsulates a sumamry of what the searchAllSeeds aligner did. + */ +struct SeedSearchMetrics { + + SeedSearchMetrics() : mutex_m() { + reset(); + } + + /** + * Merge this metrics object with the given object, i.e., sum each + * category. This is the only safe way to update a + * SeedSearchMetrics object shread by multiple threads. + */ + void merge(const SeedSearchMetrics& m, bool getLock = false) { + ThreadSafe ts(&mutex_m, getLock); + seedsearch += m.seedsearch; + possearch += m.possearch; + intrahit += m.intrahit; + interhit += m.interhit; + filteredseed += m.filteredseed; + ooms += m.ooms; + bwops += m.bwops; + bweds += m.bweds; + bestmin0 += m.bestmin0; + bestmin1 += m.bestmin1; + bestmin2 += m.bestmin2; + } + + /** + * Set all counters to 0. + */ + void reset() { + seedsearch = + possearch = + intrahit = + interhit = + filteredseed = + ooms = + bwops = + bweds = + bestmin0 = + bestmin1 = + bestmin2 = 0; + } + + uint64_t seedsearch; // # times we executed strategy in InstantiatedSeed + uint64_t possearch; // # offsets where aligner executed >= 1 strategy + uint64_t intrahit; // # offsets where current-read cache gave answer + uint64_t interhit; // # offsets where across-read cache gave answer + uint64_t filteredseed; // # seed instantiations skipped due to Ns + uint64_t ooms; // out-of-memory errors + uint64_t bwops; // Burrows-Wheeler operations + uint64_t bweds; // Burrows-Wheeler edits + uint64_t bestmin0; // # times the best min # edits was 0 + uint64_t bestmin1; // # times the best min # edits was 1 + uint64_t bestmin2; // # times the best min # edits was 2 + MUTEX_T mutex_m; +}; + +/** + * Given an index and a seeding scheme, searches for seed hits. + */ +template +class SeedAligner { + +public: + + /** + * Initialize with index. + */ + SeedAligner() : edits_(AL_CAT), offIdx2off_(AL_CAT) { } + + /** + * Given a read and a few coordinates that describe a substring of the + * read (or its reverse complement), fill in 'seq' and 'qual' objects + * with the seed sequence and qualities. + */ + void instantiateSeq( + const Read& read, // input read + BTDnaString& seq, // output sequence + BTString& qual, // output qualities + int len, // seed length + int depth, // seed's 0-based offset from 5' end + bool fw) const; // seed's orientation + + /** + * Iterate through the seeds that cover the read and initiate a + * search for each seed. + */ + std::pair instantiateSeeds( + const EList& seeds, // search seeds + index_t off, // offset into read to start extracting + int per, // interval between seeds + const Read& read, // read to align + const Scoring& pens, // scoring scheme + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + AlignmentCacheIface& cache, // holds some seed hits from previous reads + SeedResults& sr, // holds all the seed hits + SeedSearchMetrics& met); // metrics + + /** + * Iterate through the seeds that cover the read and initiate a + * search for each seed. + */ + void searchAllSeeds( + const EList& seeds, // search seeds + const Ebwt* ebwtFw, // BWT index + const Ebwt* ebwtBw, // BWT' index + const Read& read, // read to align + const Scoring& pens, // scoring scheme + AlignmentCacheIface& cache, // local seed alignment cache + SeedResults& hits, // holds all the seed hits + SeedSearchMetrics& met, // metrics + PerReadMetrics& prm); // per-read metrics + + /** + * Sanity-check a partial alignment produced during oneMmSearch. + */ + bool sanityPartial( + const Ebwt* ebwtFw, // BWT index + const Ebwt* ebwtBw, // BWT' index + const BTDnaString& seq, + index_t dep, + index_t len, + bool do1mm, + index_t topfw, + index_t botfw, + index_t topbw, + index_t botbw); + + /** + * Do an exact-matching sweet to establish a lower bound on number of edits + * and to find exact alignments. + */ + size_t exactSweep( + const Ebwt& ebwt, // BWT index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + size_t mineMax, // don't care about edit bounds > this + size_t& mineFw, // minimum # edits for forward read + size_t& mineRc, // minimum # edits for revcomp read + bool repex, // report 0mm hits? + SeedResults& hits, // holds all the seed hits (and exact hit) + SeedSearchMetrics& met); // metrics + + /** + * Search for end-to-end alignments with up to 1 mismatch. + */ + bool oneMmSearch( + const Ebwt* ebwtFw, // BWT index + const Ebwt* ebwtBw, // BWT' index + const Read& read, // read to align + const Scoring& sc, // scoring + int64_t minsc, // minimum score + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + bool local, // 1mm hits must be legal local alignments + bool repex, // report 0mm hits? + bool rep1mm, // report 1mm hits? + SeedResults& hits, // holds all the seed hits (and exact hit) + SeedSearchMetrics& met); // metrics + +protected: + + /** + * Report a seed hit found by searchSeedBi(), but first try to extend it out in + * either direction as far as possible without hitting any edits. This will + * allow us to prioritize the seed hits better later on. Call reportHit() when + * we're done, which actually adds the hit to the cache. Returns result from + * calling reportHit(). + */ + bool extendAndReportHit( + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + index_t len, // length of hit + DoublyLinkedList *prevEdit); // previous edit + + /** + * Report a seed hit found by searchSeedBi() by adding it to the cache. Return + * false if the hit could not be reported because of, e.g., cache exhaustion. + */ + bool reportHit( + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + index_t len, // length of hit + DoublyLinkedList *prevEdit); // previous edit + + /** + * Given an instantiated seed (in s_ and other fields), search + */ + bool searchSeedBi(); + + /** + * Main, recursive implementation of the seed search. + */ + bool searchSeedBi( + int step, // depth into steps_[] array + int depth, // recursion depth + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + SideLocus tloc, // locus for top (perhaps unititialized) + SideLocus bloc, // locus for bot (perhaps unititialized) + Constraint c0, // constraints to enforce in seed zone 0 + Constraint c1, // constraints to enforce in seed zone 1 + Constraint c2, // constraints to enforce in seed zone 2 + Constraint overall, // overall constraints + DoublyLinkedList *prevEdit); // previous edit + + /** + * Get tloc and bloc ready for the next step. + */ + inline void nextLocsBi( + SideLocus& tloc, // top locus + SideLocus& bloc, // bot locus + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + int step); // step to get ready for + + // Following are set in searchAllSeeds then used by searchSeed() + // and other protected members. + const Ebwt* ebwtFw_; // forward index (BWT) + const Ebwt* ebwtBw_; // backward/mirror index (BWT') + const Scoring* sc_; // scoring scheme + const InstantiatedSeed* s_; // current instantiated seed + + const Read* read_; // read whose seeds are currently being aligned + + // The following are set just before a call to searchSeedBi() + const BTDnaString* seq_; // sequence of current seed + const BTString* qual_; // quality string for current seed + index_t off_; // offset of seed currently being searched + bool fw_; // orientation of seed currently being searched + + EList edits_; // temporary place to sort edits + AlignmentCacheIface *ca_; // local alignment cache for seed alignments + EList offIdx2off_; // offset idx to read offset map, set up instantiateSeeds() + uint64_t bwops_; // Burrows-Wheeler operations + uint64_t bwedits_; // Burrows-Wheeler edits + BTDnaString tmprfdnastr_; // used in reportHit + + ASSERT_ONLY(ESet hits_); // Ref hits so far for seed being aligned + BTDnaString tmpdnastr_; +}; + +#define INIT_LOCS(top, bot, tloc, bloc, e) { \ + if(bot - top == 1) { \ + tloc.initFromRow(top, (e).eh(), (e).ebwt()); \ + bloc.invalidate(); \ + } else { \ + SideLocus::initFromTopBot(top, bot, (e).eh(), (e).ebwt(), tloc, bloc); \ + assert(bloc.valid()); \ + } \ +} + +#define SANITY_CHECK_4TUP(t, b, tp, bp) { \ + ASSERT_ONLY(index_t tot = (b[0]-t[0])+(b[1]-t[1])+(b[2]-t[2])+(b[3]-t[3])); \ + ASSERT_ONLY(index_t totp = (bp[0]-tp[0])+(bp[1]-tp[1])+(bp[2]-tp[2])+(bp[3]-tp[3])); \ + assert_eq(tot, totp); \ +} + +/** + * Given a read and a few coordinates that describe a substring of the read (or + * its reverse complement), fill in 'seq' and 'qual' objects with the seed + * sequence and qualities. + * + * The seq field is filled with the sequence as it would align to the Watson + * reference strand. I.e. if fw is false, then the sequence that appears in + * 'seq' is the reverse complement of the raw read substring. + */ +template +void SeedAligner::instantiateSeq( + const Read& read, // input read + BTDnaString& seq, // output sequence + BTString& qual, // output qualities + int len, // seed length + int depth, // seed's 0-based offset from 5' end + bool fw) const // seed's orientation +{ + // Fill in 'seq' and 'qual' + int seedlen = len; + if((int)read.length() < seedlen) seedlen = (int)read.length(); + seq.resize(len); + qual.resize(len); + // If fw is false, we take characters starting at the 3' end of the + // reverse complement of the read. + for(int i = 0; i < len; i++) { + seq.set(read.patFw.windowGetDna(i, fw, read.color, depth, len), i); + qual.set(read.qual.windowGet(i, fw, depth, len), i); + } +} + +/** + * We assume that all seeds are the same length. + * + * For each seed, instantiate the seed, retracting if necessary. + */ +template +pair SeedAligner::instantiateSeeds( + const EList& seeds, // search seeds + index_t off, // offset into read to start extracting + int per, // interval between seeds + const Read& read, // read to align + const Scoring& pens, // scoring scheme + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + AlignmentCacheIface& cache,// holds some seed hits from previous reads + SeedResults& sr, // holds all the seed hits + SeedSearchMetrics& met) // metrics +{ + assert(!seeds.empty()); + assert_gt(read.length(), 0); + // Check whether read has too many Ns + offIdx2off_.clear(); + int len = seeds[0].len; // assume they're all the same length +#ifndef NDEBUG + for(size_t i = 1; i < seeds.size(); i++) { + assert_eq(len, seeds[i].len); + } +#endif + // Calc # seeds within read interval + int nseeds = 1; + if((int)read.length() - (int)off > len) { + nseeds += ((int)read.length() - (int)off - len) / per; + } + for(int i = 0; i < nseeds; i++) { + offIdx2off_.push_back(per * i + (int)off); + } + pair ret; + ret.first = 0; // # seeds that require alignment + ret.second = 0; // # seeds that hit in cache with non-empty results + sr.reset(read, offIdx2off_, nseeds); + assert(sr.repOk(&cache.current(), true)); // require that SeedResult be initialized + // For each seed position + for(int fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + if((fw && nofw) || (!fw && norc)) { + // Skip this orientation b/c user specified --nofw or --norc + continue; + } + // For each seed position + for(int i = 0; i < nseeds; i++) { + int depth = i * per + (int)off; + int seedlen = seeds[0].len; + // Extract the seed sequence at this offset + // If fw == true, we extract the characters from i*per to + // i*(per-1) (exclusive). If fw == false, + instantiateSeq( + read, + sr.seqs(fw)[i], + sr.quals(fw)[i], + std::min((int)seedlen, (int)read.length()), + depth, + fw); + //QKey qk(sr.seqs(fw)[i] ASSERT_ONLY(, tmpdnastr_)); + // For each search strategy + EList& iss = sr.instantiatedSeeds(fw, i); + for(int j = 0; j < (int)seeds.size(); j++) { + iss.expand(); + assert_eq(seedlen, seeds[j].len); + InstantiatedSeed* is = &iss.back(); + if(seeds[j].instantiate( + read, + sr.seqs(fw)[i], + sr.quals(fw)[i], + pens, + depth, + i, + j, + fw, + *is)) + { + // Can we fill this seed hit in from the cache? + ret.first++; + } else { + // Seed may fail to instantiate if there are Ns + // that prevent it from matching + met.filteredseed++; + iss.pop_back(); + } + } + } + } + return ret; +} + +/** + * We assume that all seeds are the same length. + * + * For each seed: + * + * 1. Instantiate all seeds, retracting them if necessary. + * 2. Calculate zone boundaries for each seed + */ +template +void SeedAligner::searchAllSeeds( + const EList& seeds, // search seeds + const Ebwt* ebwtFw, // BWT index + const Ebwt* ebwtBw, // BWT' index + const Read& read, // read to align + const Scoring& pens, // scoring scheme + AlignmentCacheIface& cache, // local cache for seed alignments + SeedResults& sr, // holds all the seed hits + SeedSearchMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics +{ + assert(!seeds.empty()); + assert(ebwtFw != NULL); + assert(ebwtFw->isInMemory()); + assert(sr.repOk(&cache.current())); + ebwtFw_ = ebwtFw; + ebwtBw_ = ebwtBw; + sc_ = &pens; + read_ = &read; + ca_ = &cache; + bwops_ = bwedits_ = 0; + uint64_t possearches = 0, seedsearches = 0, intrahits = 0, interhits = 0, ooms = 0; + // For each instantiated seed + for(int i = 0; i < (int)sr.numOffs(); i++) { + size_t off = sr.idx2off(i); + for(int fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + assert(sr.repOk(&cache.current())); + EList& iss = sr.instantiatedSeeds(fw, i); + if(iss.empty()) { + // Cache hit in an across-read cache + continue; + } + QVal qv; + seq_ = &sr.seqs(fw)[i]; // seed sequence + qual_ = &sr.quals(fw)[i]; // seed qualities + off_ = off; // seed offset (from 5') + fw_ = fw; // seed orientation + // Tell the cache that we've started aligning, so the cache can + // expect a series of on-the-fly updates + int ret = cache.beginAlign(*seq_, *qual_, qv); + ASSERT_ONLY(hits_.clear()); + if(ret == -1) { + // Out of memory when we tried to add key to map + ooms++; + continue; + } + bool abort = false; + if(ret == 0) { + // Not already in cache + assert(cache.aligning()); + possearches++; + for(size_t j = 0; j < iss.size(); j++) { + // Set seq_ and qual_ appropriately, using the seed sequences + // and qualities already installed in SeedResults + assert_eq(fw, iss[j].fw); + assert_eq(i, (int)iss[j].seedoffidx); + s_ = &iss[j]; + // Do the search with respect to seq_, qual_ and s_. + if(!searchSeedBi()) { + // Memory exhausted during search + ooms++; + abort = true; + break; + } + seedsearches++; + assert(cache.aligning()); + } + if(!abort) { + qv = cache.finishAlign(); + } + } else { + // Already in cache + assert_eq(1, ret); + assert(qv.valid()); + intrahits++; + } + assert(abort || !cache.aligning()); + if(qv.valid()) { + sr.add( + qv, // range of ranges in cache + cache.current(), // cache + i, // seed index (from 5' end) + fw); // whether seed is from forward read + } + } + } + prm.nSeedRanges = sr.numRanges(); + prm.nSeedElts = sr.numElts(); + prm.nSeedRangesFw = sr.numRangesFw(); + prm.nSeedRangesRc = sr.numRangesRc(); + prm.nSeedEltsFw = sr.numEltsFw(); + prm.nSeedEltsRc = sr.numEltsRc(); + prm.seedMedian = (uint64_t)(sr.medianHitsPerSeed() + 0.5); + prm.seedMean = (uint64_t)sr.averageHitsPerSeed(); + + prm.nSdFmops += bwops_; + met.seedsearch += seedsearches; + met.possearch += possearches; + met.intrahit += intrahits; + met.interhit += interhits; + met.ooms += ooms; + met.bwops += bwops_; + met.bweds += bwedits_; +} + +template +bool SeedAligner::sanityPartial( + const Ebwt* ebwtFw, // BWT index + const Ebwt* ebwtBw, // BWT' index + const BTDnaString& seq, + index_t dep, + index_t len, + bool do1mm, + index_t topfw, + index_t botfw, + index_t topbw, + index_t botbw) +{ + tmpdnastr_.clear(); + for(size_t i = dep; i < len; i++) { + tmpdnastr_.append(seq[i]); + } + index_t top_fw = 0, bot_fw = 0; + ebwtFw->contains(tmpdnastr_, &top_fw, &bot_fw); + assert_eq(top_fw, topfw); + assert_eq(bot_fw, botfw); + if(do1mm && ebwtBw != NULL) { + tmpdnastr_.reverse(); + index_t top_bw = 0, bot_bw = 0; + ebwtBw->contains(tmpdnastr_, &top_bw, &bot_bw); + assert_eq(top_bw, topbw); + assert_eq(bot_bw, botbw); + } + return true; +} + +/** + * Sweep right-to-left and left-to-right using exact matching. Remember all + * the SA ranges encountered along the way. Report exact matches if there are + * any. Calculate a lower bound on the number of edits in an end-to-end + * alignment. + */ +template +size_t SeedAligner::exactSweep( + const Ebwt& ebwt, // BWT index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + size_t mineMax, // don't care about edit bounds > this + size_t& mineFw, // minimum # edits for forward read + size_t& mineRc, // minimum # edits for revcomp read + bool repex, // report 0mm hits? + SeedResults& hits, // holds all the seed hits (and exact hit) + SeedSearchMetrics& met) // metrics +{ + assert_gt(mineMax, 0); + index_t top = 0, bot = 0; + SideLocus tloc, bloc; + const size_t len = read.length(); + size_t nelt = 0; + for(int fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + if( fw && nofw) continue; + if(!fw && norc) continue; + const BTDnaString& seq = fw ? read.patFw : read.patRc; + assert(!seq.empty()); + int ftabLen = ebwt.eh().ftabChars(); + size_t dep = 0; + size_t nedit = 0; + bool done = false; + while(dep < len && !done) { + top = bot = 0; + size_t left = len - dep; + assert_gt(left, 0); + bool doFtab = ftabLen > 1 && left >= (size_t)ftabLen; + if(doFtab) { + // Does N interfere with use of Ftab? + for(size_t i = 0; i < (size_t)ftabLen; i++) { + int c = seq[len-dep-1-i]; + if(c > 3) { + doFtab = false; + break; + } + } + } + if(doFtab) { + // Use ftab + ebwt.ftabLoHi(seq, len - dep - ftabLen, false, top, bot); + dep += (size_t)ftabLen; + } else { + // Use fchr + int c = seq[len-dep-1]; + if(c < 4) { + top = ebwt.fchr()[c]; + bot = ebwt.fchr()[c+1]; + } + dep++; + } + if(bot <= top) { + nedit++; + if(nedit >= mineMax) { + if(fw) { mineFw = nedit; } else { mineRc = nedit; } + break; + } + continue; + } + INIT_LOCS(top, bot, tloc, bloc, ebwt); + // Keep going + while(dep < len) { + int c = seq[len-dep-1]; + if(c > 3) { + top = bot = 0; + } else { + if(bloc.valid()) { + bwops_ += 2; + top = ebwt.mapLF(tloc, c); + bot = ebwt.mapLF(bloc, c); + } else { + bwops_++; + top = ebwt.mapLF1(top, tloc, c); + if(top == (index_t)OFF_MASK) { + top = bot = 0; + } else { + bot = top+1; + } + } + } + if(bot <= top) { + nedit++; + if(nedit >= mineMax) { + if(fw) { mineFw = nedit; } else { mineRc = nedit; } + done = true; + } + break; + } + INIT_LOCS(top, bot, tloc, bloc, ebwt); + dep++; + } + if(done) { + break; + } + if(dep == len) { + // Set the minimum # edits + if(fw) { mineFw = nedit; } else { mineRc = nedit; } + // Done + if(nedit == 0 && bot > top) { + if(repex) { + // This is an exact hit + int64_t score = len * sc.match(); + if(fw) { + hits.addExactEeFw(top, bot, NULL, NULL, fw, score); + assert(ebwt.contains(seq, NULL, NULL)); + } else { + hits.addExactEeRc(top, bot, NULL, NULL, fw, score); + assert(ebwt.contains(seq, NULL, NULL)); + } + } + nelt += (bot - top); + } + break; + } + dep++; + } + } + return nelt; +} + +/** + * Search for end-to-end exact hit for read. Return true iff one is found. + */ +template +bool SeedAligner::oneMmSearch( + const Ebwt* ebwtFw, // BWT index + const Ebwt* ebwtBw, // BWT' index + const Read& read, // read to align + const Scoring& sc, // scoring + int64_t minsc, // minimum score + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + bool local, // 1mm hits must be legal local alignments + bool repex, // report 0mm hits? + bool rep1mm, // report 1mm hits? + SeedResults& hits, // holds all the seed hits (and exact hit) + SeedSearchMetrics& met) // metrics +{ + assert(!rep1mm || ebwtBw != NULL); + const size_t len = read.length(); + int nceil = sc.nCeil.f((double)len); + size_t ns = read.ns(); + if(ns > 1) { + // Can't align this with <= 1 mismatches + return false; + } else if(ns == 1 && !rep1mm) { + // Can't align this with 0 mismatches + return false; + } + assert_geq(len, 2); + assert(!rep1mm || ebwtBw->eh().ftabChars() == ebwtFw->eh().ftabChars()); +#ifndef NDEBUG + if(ebwtBw != NULL) { + for(int i = 0; i < 4; i++) { + assert_eq(ebwtBw->fchr()[i], ebwtFw->fchr()[i]); + } + } +#endif + size_t halfFw = len >> 1; + size_t halfBw = len >> 1; + if((len & 1) != 0) { + halfBw++; + } + assert_geq(halfFw, 1); + assert_geq(halfBw, 1); + SideLocus tloc, bloc; + index_t t[4], b[4]; // dest BW ranges for BWT + t[0] = t[1] = t[2] = t[3] = 0; + b[0] = b[1] = b[2] = b[3] = 0; + index_t tp[4], bp[4]; // dest BW ranges for BWT' + tp[0] = tp[1] = tp[2] = tp[3] = 0; + bp[0] = bp[1] = bp[2] = bp[3] = 0; + index_t top = 0, bot = 0, topp = 0, botp = 0; + // Align fw read / rc read + bool results = false; + for(int fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + if( fw && nofw) continue; + if(!fw && norc) continue; + // Align going right-to-left, left-to-right + int lim = rep1mm ? 2 : 1; + for(int ebwtfwi = 0; ebwtfwi < lim; ebwtfwi++) { + bool ebwtfw = (ebwtfwi == 0); + const Ebwt* ebwt = (ebwtfw ? ebwtFw : ebwtBw); + const Ebwt* ebwtp = (ebwtfw ? ebwtBw : ebwtFw); + assert(rep1mm || ebwt->fw()); + const BTDnaString& seq = + (fw ? (ebwtfw ? read.patFw : read.patFwRev) : + (ebwtfw ? read.patRc : read.patRcRev)); + assert(!seq.empty()); + const BTString& qual = + (fw ? (ebwtfw ? read.qual : read.qualRev) : + (ebwtfw ? read.qualRev : read.qual)); + int ftabLen = ebwt->eh().ftabChars(); + size_t nea = ebwtfw ? halfFw : halfBw; + // Check if there's an N in the near portion + bool skip = false; + for(size_t dep = 0; dep < nea; dep++) { + if(seq[len-dep-1] > 3) { + skip = true; + break; + } + } + if(skip) { + continue; + } + size_t dep = 0; + // Align near half + if(ftabLen > 1 && (size_t)ftabLen <= nea) { + // Use ftab to jump partway into near half + bool rev = !ebwtfw; + ebwt->ftabLoHi(seq, len - ftabLen, rev, top, bot); + if(rep1mm) { + ebwtp->ftabLoHi(seq, len - ftabLen, rev, topp, botp); + assert_eq(bot - top, botp - topp); + } + if(bot - top == 0) { + continue; + } + int c = seq[len - ftabLen]; + t[c] = top; b[c] = bot; + tp[c] = topp; bp[c] = botp; + dep = ftabLen; + // initialize tloc, bloc?? + } else { + // Use fchr to jump in by 1 pos + int c = seq[len-1]; + assert_range(0, 3, c); + top = topp = tp[c] = ebwt->fchr()[c]; + bot = botp = bp[c] = ebwt->fchr()[c+1]; + if(bot - top == 0) { + continue; + } + dep = 1; + // initialize tloc, bloc?? + } + INIT_LOCS(top, bot, tloc, bloc, *ebwt); + assert(sanityPartial(ebwt, ebwtp, seq, len-dep, len, rep1mm, top, bot, topp, botp)); + bool do_continue = false; + for(; dep < nea; dep++) { + assert_lt(dep, len); + int rdc = seq[len - dep - 1]; + tp[0] = tp[1] = tp[2] = tp[3] = topp; + bp[0] = bp[1] = bp[2] = bp[3] = botp; + if(bloc.valid()) { + bwops_++; + t[0] = t[1] = t[2] = t[3] = b[0] = b[1] = b[2] = b[3] = 0; + ebwt->mapBiLFEx(tloc, bloc, t, b, tp, bp); + SANITY_CHECK_4TUP(t, b, tp, bp); + top = t[rdc]; bot = b[rdc]; + if(bot <= top) { + do_continue = true; + break; + } + topp = tp[rdc]; botp = bp[rdc]; + assert(!rep1mm || bot - top == botp - topp); + } else { + assert_eq(bot, top+1); + assert(!rep1mm || botp == topp+1); + bwops_++; + top = ebwt->mapLF1(top, tloc, rdc); + if(top == (index_t)OFF_MASK) { + do_continue = true; + break; + } + bot = top + 1; + t[rdc] = top; b[rdc] = bot; + tp[rdc] = topp; bp[rdc] = botp; + assert(!rep1mm || b[rdc] - t[rdc] == bp[rdc] - tp[rdc]); + // topp/botp stay the same + } + INIT_LOCS(top, bot, tloc, bloc, *ebwt); + assert(sanityPartial(ebwt, ebwtp, seq, len - dep - 1, len, rep1mm, top, bot, topp, botp)); + } + if(do_continue) { + continue; + } + // Align far half + for(; dep < len; dep++) { + int rdc = seq[len-dep-1]; + int quc = qual[len-dep-1]; + if(rdc > 3 && nceil == 0) { + break; + } + tp[0] = tp[1] = tp[2] = tp[3] = topp; + bp[0] = bp[1] = bp[2] = bp[3] = botp; + int clo = 0, chi = 3; + bool match = true; + if(bloc.valid()) { + bwops_++; + t[0] = t[1] = t[2] = t[3] = b[0] = b[1] = b[2] = b[3] = 0; + ebwt->mapBiLFEx(tloc, bloc, t, b, tp, bp); + SANITY_CHECK_4TUP(t, b, tp, bp); + match = rdc < 4; + top = t[rdc]; bot = b[rdc]; + topp = tp[rdc]; botp = bp[rdc]; + } else { + assert_eq(bot, top+1); + assert(!rep1mm || botp == topp+1); + bwops_++; + clo = ebwt->mapLF1(top, tloc); + match = (clo == rdc); + assert_range(-1, 3, clo); + if(clo < 0) { + break; // Hit the $ + } else { + t[clo] = top; + b[clo] = bot = top + 1; + } + bp[clo] = botp; + tp[clo] = topp; + assert(!rep1mm || bot - top == botp - topp); + assert(!rep1mm || b[clo] - t[clo] == bp[clo] - tp[clo]); + chi = clo; + } + //assert(sanityPartial(ebwt, ebwtp, seq, len - dep - 1, len, rep1mm, top, bot, topp, botp)); + if(rep1mm && (ns == 0 || rdc > 3)) { + for(int j = clo; j <= chi; j++) { + if(j == rdc || b[j] == t[j]) { + // Either matches read or isn't a possibility + continue; + } + // Potential mismatch - next, try + size_t depm = dep + 1; + index_t topm = t[j], botm = b[j]; + index_t topmp = tp[j], botmp = bp[j]; + assert_eq(botm - topm, botmp - topmp); + index_t tm[4], bm[4]; // dest BW ranges for BWT + tm[0] = t[0]; tm[1] = t[1]; + tm[2] = t[2]; tm[3] = t[3]; + bm[0] = b[0]; bm[1] = t[1]; + bm[2] = b[2]; bm[3] = t[3]; + index_t tmp[4], bmp[4]; // dest BW ranges for BWT' + tmp[0] = tp[0]; tmp[1] = tp[1]; + tmp[2] = tp[2]; tmp[3] = tp[3]; + bmp[0] = bp[0]; bmp[1] = tp[1]; + bmp[2] = bp[2]; bmp[3] = tp[3]; + SideLocus tlocm, blocm; + INIT_LOCS(topm, botm, tlocm, blocm, *ebwt); + for(; depm < len; depm++) { + int rdcm = seq[len - depm - 1]; + tmp[0] = tmp[1] = tmp[2] = tmp[3] = topmp; + bmp[0] = bmp[1] = bmp[2] = bmp[3] = botmp; + if(blocm.valid()) { + bwops_++; + tm[0] = tm[1] = tm[2] = tm[3] = + bm[0] = bm[1] = bm[2] = bm[3] = 0; + ebwt->mapBiLFEx(tlocm, blocm, tm, bm, tmp, bmp); + SANITY_CHECK_4TUP(tm, bm, tmp, bmp); + topm = tm[rdcm]; botm = bm[rdcm]; + topmp = tmp[rdcm]; botmp = bmp[rdcm]; + if(botm <= topm) { + break; + } + } else { + assert_eq(botm, topm+1); + assert_eq(botmp, topmp+1); + bwops_++; + topm = ebwt->mapLF1(topm, tlocm, rdcm); + if(topm == (index_t)0xffffffff) { + break; + } + botm = topm + 1; + // topp/botp stay the same + } + INIT_LOCS(topm, botm, tlocm, blocm, *ebwt); + } + if(depm == len) { + // Success; this is a 1MM hit + size_t off5p = dep; // offset from 5' end of read + size_t offstr = dep; // offset into patFw/patRc + if(fw == ebwtfw) { + off5p = len - off5p - 1; + } + if(!ebwtfw) { + offstr = len - offstr - 1; + } + Edit e((uint32_t)off5p, j, rdc, EDIT_TYPE_MM, false); + results = true; + int64_t score = (len - 1) * sc.match(); + // In --local mode, need to double-check that + // end-to-end alignment doesn't violate local + // alignment principles. Specifically, it + // shouldn't to or below 0 anywhere in the middle. + int pen = sc.score(rdc, (int)(1 << j), quc - 33); + score += pen; + bool valid = true; + if(local) { + int64_t locscore_fw = 0, locscore_bw = 0; + for(size_t i = 0; i < len; i++) { + if(i == dep) { + if(locscore_fw + pen <= 0) { + valid = false; + break; + } + locscore_fw += pen; + } else { + locscore_fw += sc.match(); + } + if(len-i-1 == dep) { + if(locscore_bw + pen <= 0) { + valid = false; + break; + } + locscore_bw += pen; + } else { + locscore_bw += sc.match(); + } + } + } + if(valid) { + valid = score >= minsc; + } + if(valid) { +#ifndef NDEBUG + BTDnaString& rf = tmprfdnastr_; + rf.clear(); + edits_.clear(); + edits_.push_back(e); + if(!fw) Edit::invertPoss(edits_, len, false); + Edit::toRef(fw ? read.patFw : read.patRc, edits_, rf); + if(!fw) Edit::invertPoss(edits_, len, false); + assert_eq(len, rf.length()); + for(size_t i = 0; i < len; i++) { + assert_lt((int)rf[i], 4); + } + ASSERT_ONLY(index_t toptmp = 0); + ASSERT_ONLY(index_t bottmp = 0); + assert(ebwtFw->contains(rf, &toptmp, &bottmp)); +#endif + index_t toprep = ebwtfw ? topm : topmp; + index_t botrep = ebwtfw ? botm : botmp; + assert_eq(toprep, toptmp); + assert_eq(botrep, bottmp); + hits.add1mmEe(toprep, botrep, &e, NULL, fw, score); + } + } + } + } + if(bot > top && match) { + assert_lt(rdc, 4); + if(dep == len-1) { + // Success; this is an exact hit + if(ebwtfw && repex) { + if(fw) { + results = true; + int64_t score = len * sc.match(); + hits.addExactEeFw( + ebwtfw ? top : topp, + ebwtfw ? bot : botp, + NULL, NULL, fw, score); + assert(ebwtFw->contains(seq, NULL, NULL)); + } else { + results = true; + int64_t score = len * sc.match(); + hits.addExactEeRc( + ebwtfw ? top : topp, + ebwtfw ? bot : botp, + NULL, NULL, fw, score); + assert(ebwtFw->contains(seq, NULL, NULL)); + } + } + break; // End of far loop + } else { + INIT_LOCS(top, bot, tloc, bloc, *ebwt); + assert(sanityPartial(ebwt, ebwtp, seq, len - dep - 1, len, rep1mm, top, bot, topp, botp)); + } + } else { + break; // End of far loop + } + } // for(; dep < len; dep++) + } // for(int ebwtfw = 0; ebwtfw < 2; ebwtfw++) + } // for(int fw = 0; fw < 2; fw++) + return results; +} + +/** + * Wrapper for initial invcation of searchSeed. + */ +template +bool SeedAligner::searchSeedBi() { + return searchSeedBi( + 0, 0, + 0, 0, 0, 0, + SideLocus(), SideLocus(), + s_->cons[0], s_->cons[1], s_->cons[2], s_->overall, + NULL); +} + +/** + * Get tloc, bloc ready for the next step. If the new range is under + * the ceiling. + */ +template +inline void SeedAligner::nextLocsBi( + SideLocus& tloc, // top locus + SideLocus& bloc, // bot locus + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + int step // step to get ready for +#if 0 + , const SABWOffTrack* prevOt, // previous tracker + SABWOffTrack& ot // current tracker +#endif + ) +{ + assert_gt(botf, 0); + assert(ebwtBw_ == NULL || botb > 0); + assert_geq(step, 0); // next step can't be first one + assert(ebwtBw_ == NULL || botf-topf == botb-topb); + if(step == (int)s_->steps.size()) return; // no more steps! + // Which direction are we going in next? + if(s_->steps[step] > 0) { + // Left to right; use BWT' + if(botb - topb == 1) { + // Already down to 1 row; just init top locus + tloc.initFromRow(topb, ebwtBw_->eh(), ebwtBw_->ebwt()); + bloc.invalidate(); + } else { + SideLocus::initFromTopBot( + topb, botb, ebwtBw_->eh(), ebwtBw_->ebwt(), tloc, bloc); + assert(bloc.valid()); + } + } else { + // Right to left; use BWT + if(botf - topf == 1) { + // Already down to 1 row; just init top locus + tloc.initFromRow(topf, ebwtFw_->eh(), ebwtFw_->ebwt()); + bloc.invalidate(); + } else { + SideLocus::initFromTopBot( + topf, botf, ebwtFw_->eh(), ebwtFw_->ebwt(), tloc, bloc); + assert(bloc.valid()); + } + } + // Check if we should update the tracker with this refinement +#if 0 + if(botf-topf <= BW_OFF_TRACK_CEIL) { + if(ot.size() == 0 && prevOt != NULL && prevOt->size() > 0) { + // Inherit state from the predecessor + ot = *prevOt; + } + bool ltr = s_->steps[step-1] > 0; + int adj = abs(s_->steps[step-1])-1; + const Ebwt* ebwt = ltr ? ebwtBw_ : ebwtFw_; + ot.update( + ltr ? topb : topf, // top + ltr ? botb : botf, // bot + adj, // adj (to be subtracted from offset) + ebwt->offs(), // offs array + ebwt->eh().offRate(), // offrate (sample = every 1 << offrate elts) + NULL // dead + ); + assert_gt(ot.size(), 0); + } +#endif + assert(botf - topf == 1 || bloc.valid()); + assert(botf - topf > 1 || !bloc.valid()); +} + +/** + * Report a seed hit found by searchSeedBi(), but first try to extend it out in + * either direction as far as possible without hitting any edits. This will + * allow us to prioritize the seed hits better later on. Call reportHit() when + * we're done, which actually adds the hit to the cache. Returns result from + * calling reportHit(). + */ +template +bool SeedAligner::extendAndReportHit( + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + index_t len, // length of hit + DoublyLinkedList *prevEdit) // previous edit +{ + index_t nlex = 0, nrex = 0; + index_t t[4], b[4]; + index_t tp[4], bp[4]; + SideLocus tloc, bloc; + if(off_ > 0) { + const Ebwt *ebwt = ebwtFw_; + assert(ebwt != NULL); + // Extend left using forward index + const BTDnaString& seq = fw_ ? read_->patFw : read_->patRc; + // See what we get by extending + index_t top = topf, bot = botf; + t[0] = t[1] = t[2] = t[3] = 0; + b[0] = b[1] = b[2] = b[3] = 0; + tp[0] = tp[1] = tp[2] = tp[3] = topb; + bp[0] = bp[1] = bp[2] = bp[3] = botb; + SideLocus tloc, bloc; + INIT_LOCS(top, bot, tloc, bloc, *ebwt); + for(size_t ii = off_; ii > 0; ii--) { + size_t i = ii-1; + // Get char from read + int rdc = seq.get(i); + // See what we get by extending + if(bloc.valid()) { + bwops_++; + t[0] = t[1] = t[2] = t[3] = + b[0] = b[1] = b[2] = b[3] = 0; + ebwt->mapBiLFEx(tloc, bloc, t, b, tp, bp); + SANITY_CHECK_4TUP(t, b, tp, bp); + int nonz = -1; + bool abort = false; + for(int j = 0; j < 4; j++) { + if(b[i] > t[i]) { + if(nonz >= 0) { + abort = true; + break; + } + nonz = j; + top = t[i]; bot = b[i]; + } + } + if(abort || nonz != rdc) { + break; + } + } else { + assert_eq(bot, top+1); + bwops_++; + int c = ebwt->mapLF1(top, tloc); + if(c != rdc) { + break; + } + bot = top + 1; + } + if(++nlex == 255) { + break; + } + INIT_LOCS(top, bot, tloc, bloc, *ebwt); + } + } + size_t rdlen = read_->length(); + size_t nright = rdlen - off_ - len; + if(nright > 0 && ebwtBw_ != NULL) { + const Ebwt *ebwt = ebwtBw_; + assert(ebwt != NULL); + // Extend right using backward index + const BTDnaString& seq = fw_ ? read_->patFw : read_->patRc; + // See what we get by extending + index_t top = topb, bot = botb; + t[0] = t[1] = t[2] = t[3] = 0; + b[0] = b[1] = b[2] = b[3] = 0; + tp[0] = tp[1] = tp[2] = tp[3] = topb; + bp[0] = bp[1] = bp[2] = bp[3] = botb; + INIT_LOCS(top, bot, tloc, bloc, *ebwt); + for(size_t i = off_ + len; i < rdlen; i++) { + // Get char from read + int rdc = seq.get(i); + // See what we get by extending + if(bloc.valid()) { + bwops_++; + t[0] = t[1] = t[2] = t[3] = + b[0] = b[1] = b[2] = b[3] = 0; + ebwt->mapBiLFEx(tloc, bloc, t, b, tp, bp); + SANITY_CHECK_4TUP(t, b, tp, bp); + int nonz = -1; + bool abort = false; + for(int j = 0; j < 4; j++) { + if(b[i] > t[i]) { + if(nonz >= 0) { + abort = true; + break; + } + nonz = j; + top = t[i]; bot = b[i]; + } + } + if(abort || nonz != rdc) { + break; + } + } else { + assert_eq(bot, top+1); + bwops_++; + int c = ebwt->mapLF1(top, tloc); + if(c != rdc) { + break; + } + bot = top + 1; + } + if(++nrex == 255) { + break; + } + INIT_LOCS(top, bot, tloc, bloc, *ebwt); + } + } + assert_lt(nlex, rdlen); + assert_leq(nlex, off_); + assert_lt(nrex, rdlen); + return reportHit(topf, botf, topb, botb, len, prevEdit); +} + +/** + * Report a seed hit found by searchSeedBi() by adding it to the cache. Return + * false if the hit could not be reported because of, e.g., cache exhaustion. + */ +template +bool SeedAligner::reportHit( + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + index_t len, // length of hit + DoublyLinkedList *prevEdit) // previous edit +{ + // Add information about the seed hit to AlignmentCache. This + // information eventually makes its way back to the SeedResults + // object when we call finishAlign(...). + BTDnaString& rf = tmprfdnastr_; + rf.clear(); + edits_.clear(); + if(prevEdit != NULL) { + prevEdit->toList(edits_); + Edit::sort(edits_); + assert(Edit::repOk(edits_, *seq_)); + Edit::toRef(*seq_, edits_, rf); + } else { + rf = *seq_; + } + // Sanity check: shouldn't add the same hit twice. If this + // happens, it may be because our zone Constraints are not set up + // properly and erroneously return true from acceptable() when they + // should return false in some cases. + assert_eq(hits_.size(), ca_->curNumRanges()); + assert(hits_.insert(rf)); + if(!ca_->addOnTheFly(rf, topf, botf, topb, botb)) { + return false; + } + assert_eq(hits_.size(), ca_->curNumRanges()); +#ifndef NDEBUG + // Sanity check that the topf/botf and topb/botb ranges really + // correspond to the reference sequence aligned to + { + BTDnaString rfr; + index_t tpf, btf, tpb, btb; + tpf = btf = tpb = btb = 0; + assert(ebwtFw_->contains(rf, &tpf, &btf)); + if(ebwtBw_ != NULL) { + rfr = rf; + rfr.reverse(); + assert(ebwtBw_->contains(rfr, &tpb, &btb)); + assert_eq(tpf, topf); + assert_eq(btf, botf); + assert_eq(tpb, topb); + assert_eq(btb, botb); + } + } +#endif + return true; +} + +/** + * Given a seed, search. Assumes zone 0 = no backtracking. + * + * Return a list of Seed hits. + * 1. Edits + * 2. Bidirectional BWT range(s) on either end + */ +template +bool SeedAligner::searchSeedBi( + int step, // depth into steps_[] array + int depth, // recursion depth + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb, // bot in BWT' + SideLocus tloc, // locus for top (perhaps unititialized) + SideLocus bloc, // locus for bot (perhaps unititialized) + Constraint c0, // constraints to enforce in seed zone 0 + Constraint c1, // constraints to enforce in seed zone 1 + Constraint c2, // constraints to enforce in seed zone 2 + Constraint overall, // overall constraints to enforce + DoublyLinkedList *prevEdit // previous edit +#if 0 + , const SABWOffTrack* prevOt // prev off tracker (if tracking started) +#endif + ) +{ + assert(s_ != NULL); + const InstantiatedSeed& s = *s_; + assert_gt(s.steps.size(), 0); + assert(ebwtBw_ == NULL || ebwtBw_->eh().ftabChars() == ebwtFw_->eh().ftabChars()); +#ifndef NDEBUG + for(int i = 0; i < 4; i++) { + assert(ebwtBw_ == NULL || ebwtBw_->fchr()[i] == ebwtFw_->fchr()[i]); + } +#endif + if(step == (int)s.steps.size()) { + // Finished aligning seed + assert(c0.acceptable()); + assert(c1.acceptable()); + assert(c2.acceptable()); + if(!reportHit(topf, botf, topb, botb, seq_->length(), prevEdit)) { + return false; // Memory exhausted + } + return true; + } +#ifndef NDEBUG + if(depth > 0) { + assert(botf - topf == 1 || bloc.valid()); + assert(botf - topf > 1 || !bloc.valid()); + } +#endif + int off; + index_t tp[4], bp[4]; // dest BW ranges for "prime" index + if(step == 0) { + // Just starting + assert(prevEdit == NULL); + assert(!tloc.valid()); + assert(!bloc.valid()); + off = s.steps[0]; + bool ltr = off > 0; + off = abs(off)-1; + // Check whether/how far we can jump using ftab or fchr + int ftabLen = ebwtFw_->eh().ftabChars(); + if(ftabLen > 1 && ftabLen <= s.maxjump) { + if(!ltr) { + assert_geq(off+1, ftabLen-1); + off = off - ftabLen + 1; + } + ebwtFw_->ftabLoHi(*seq_, off, false, topf, botf); +#ifdef NDEBUG + if(botf - topf == 0) return true; +#endif +#ifdef NDEBUG + if(ebwtBw_ != NULL) { + topb = ebwtBw_->ftabHi(*seq_, off); + botb = topb + (botf-topf); + } +#else + if(ebwtBw_ != NULL) { + ebwtBw_->ftabLoHi(*seq_, off, false, topb, botb); + assert_eq(botf-topf, botb-topb); + } + if(botf - topf == 0) return true; +#endif + step += ftabLen; + } else if(s.maxjump > 0) { + // Use fchr + int c = (*seq_)[off]; + assert_range(0, 3, c); + topf = topb = ebwtFw_->fchr()[c]; + botf = botb = ebwtFw_->fchr()[c+1]; + if(botf - topf == 0) return true; + step++; + } else { + assert_eq(0, s.maxjump); + topf = topb = 0; + botf = botb = ebwtFw_->fchr()[4]; + } + if(step == (int)s.steps.size()) { + // Finished aligning seed + assert(c0.acceptable()); + assert(c1.acceptable()); + assert(c2.acceptable()); + if(!reportHit(topf, botf, topb, botb, seq_->length(), prevEdit)) { + return false; // Memory exhausted + } + return true; + } + nextLocsBi(tloc, bloc, topf, botf, topb, botb, step); + assert(tloc.valid()); + } else assert(prevEdit != NULL); + assert(tloc.valid()); + assert(botf - topf == 1 || bloc.valid()); + assert(botf - topf > 1 || !bloc.valid()); + assert_geq(step, 0); + index_t t[4], b[4]; // dest BW ranges + Constraint* zones[3] = { &c0, &c1, &c2 }; + ASSERT_ONLY(index_t lasttot = botf - topf); + for(int i = step; i < (int)s.steps.size(); i++) { + assert_gt(botf, topf); + assert(botf - topf == 1 || bloc.valid()); + assert(botf - topf > 1 || !bloc.valid()); + assert(ebwtBw_ == NULL || botf-topf == botb-topb); + assert(tloc.valid()); + off = s.steps[i]; + bool ltr = off > 0; + const Ebwt* ebwt = ltr ? ebwtBw_ : ebwtFw_; + assert(ebwt != NULL); + if(ltr) { + tp[0] = tp[1] = tp[2] = tp[3] = topf; + bp[0] = bp[1] = bp[2] = bp[3] = botf; + } else { + tp[0] = tp[1] = tp[2] = tp[3] = topb; + bp[0] = bp[1] = bp[2] = bp[3] = botb; + } + t[0] = t[1] = t[2] = t[3] = b[0] = b[1] = b[2] = b[3] = 0; + if(bloc.valid()) { + // Range delimited by tloc/bloc has size >1. If size == 1, + // we use a simpler query (see if(!bloc.valid()) blocks below) + bwops_++; + ebwt->mapBiLFEx(tloc, bloc, t, b, tp, bp); + ASSERT_ONLY(index_t tot = (b[0]-t[0])+(b[1]-t[1])+(b[2]-t[2])+(b[3]-t[3])); + ASSERT_ONLY(index_t totp = (bp[0]-tp[0])+(bp[1]-tp[1])+(bp[2]-tp[2])+(bp[3]-tp[3])); + assert_eq(tot, totp); + assert_leq(tot, lasttot); + ASSERT_ONLY(lasttot = tot); + } + index_t *tf = ltr ? tp : t, *tb = ltr ? t : tp; + index_t *bf = ltr ? bp : b, *bb = ltr ? b : bp; + off = abs(off)-1; + // + bool leaveZone = s.zones[i].first < 0; + //bool leaveZoneIns = zones_[i].second < 0; + Constraint& cons = *zones[abs(s.zones[i].first)]; + Constraint& insCons = *zones[abs(s.zones[i].second)]; + int c = (*seq_)[off]; assert_range(0, 4, c); + int q = (*qual_)[off]; + // Is it legal for us to advance on characters other than 'c'? + if(!(cons.mustMatch() && !overall.mustMatch()) || c == 4) { + // There may be legal edits + bool bail = false; + if(!bloc.valid()) { + // Range delimited by tloc/bloc has size 1 + index_t ntop = ltr ? topb : topf; + bwops_++; + int cc = ebwt->mapLF1(ntop, tloc); + assert_range(-1, 3, cc); + if(cc < 0) bail = true; + else { t[cc] = ntop; b[cc] = ntop+1; } + } + if(!bail) { + if((cons.canMismatch(q, *sc_) && overall.canMismatch(q, *sc_)) || c == 4) { + Constraint oldCons = cons, oldOvCons = overall; + SideLocus oldTloc = tloc, oldBloc = bloc; + if(c != 4) { + cons.chargeMismatch(q, *sc_); + overall.chargeMismatch(q, *sc_); + } + // Can leave the zone as-is + if(!leaveZone || (cons.acceptable() && overall.acceptable())) { + for(int j = 0; j < 4; j++) { + if(j == c || b[j] == t[j]) continue; + // Potential mismatch + nextLocsBi(tloc, bloc, tf[j], bf[j], tb[j], bb[j], i+1); + int loff = off; + if(!ltr) loff = (int)(s.steps.size() - loff - 1); + assert(prevEdit == NULL || prevEdit->next == NULL); + Edit edit(off, j, c, EDIT_TYPE_MM, false); + DoublyLinkedList editl; + editl.payload = edit; + if(prevEdit != NULL) { + prevEdit->next = &editl; + editl.prev = prevEdit; + } + assert(editl.next == NULL); + bwedits_++; + if(!searchSeedBi( + i+1, // depth into steps_[] array + depth+1, // recursion depth + tf[j], // top in BWT + bf[j], // bot in BWT + tb[j], // top in BWT' + bb[j], // bot in BWT' + tloc, // locus for top (perhaps unititialized) + bloc, // locus for bot (perhaps unititialized) + c0, // constraints to enforce in seed zone 0 + c1, // constraints to enforce in seed zone 1 + c2, // constraints to enforce in seed zone 2 + overall, // overall constraints to enforce + &editl)) // latest edit + { + return false; + } + if(prevEdit != NULL) prevEdit->next = NULL; + } + } else { + // Not enough edits to make this path + // non-redundant with other seeds + } + cons = oldCons; + overall = oldOvCons; + tloc = oldTloc; + bloc = oldBloc; + } + if(cons.canGap() && overall.canGap()) { + throw 1; // TODO + int delEx = 0; + if(cons.canDelete(delEx, *sc_) && overall.canDelete(delEx, *sc_)) { + // Try delete + } + int insEx = 0; + if(insCons.canInsert(insEx, *sc_) && overall.canInsert(insEx, *sc_)) { + // Try insert + } + } + } // if(!bail) + } + if(c == 4) { + return true; // couldn't handle the N + } + if(leaveZone && (!cons.acceptable() || !overall.acceptable())) { + // Not enough edits to make this path non-redundant with + // other seeds + return true; + } + if(!bloc.valid()) { + assert(ebwtBw_ == NULL || bp[c] == tp[c]+1); + // Range delimited by tloc/bloc has size 1 + index_t top = ltr ? topb : topf; + bwops_++; + t[c] = ebwt->mapLF1(top, tloc, c); + if(t[c] == (index_t)OFF_MASK) { + return true; + } + assert_geq(t[c], ebwt->fchr()[c]); + assert_lt(t[c], ebwt->fchr()[c+1]); + b[c] = t[c]+1; + assert_gt(b[c], 0); + } + assert(ebwtBw_ == NULL || bf[c]-tf[c] == bb[c]-tb[c]); + assert_leq(bf[c]-tf[c], lasttot); + ASSERT_ONLY(lasttot = bf[c]-tf[c]); + if(b[c] == t[c]) { + return true; + } + topf = tf[c]; botf = bf[c]; + topb = tb[c]; botb = bb[c]; + if(i+1 == (int)s.steps.size()) { + // Finished aligning seed + assert(c0.acceptable()); + assert(c1.acceptable()); + assert(c2.acceptable()); + if(!reportHit(topf, botf, topb, botb, seq_->length(), prevEdit)) { + return false; // Memory exhausted + } + return true; + } + nextLocsBi(tloc, bloc, tf[c], bf[c], tb[c], bb[c], i+1); + } + return true; +} + +#endif /*ALIGNER_SEED_H_*/ diff --git a/aligner_seed2.cpp b/aligner_seed2.cpp new file mode 100644 index 0000000..685fbb0 --- /dev/null +++ b/aligner_seed2.cpp @@ -0,0 +1,1245 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include "aligner_seed2.h" +#include "assert_helpers.h" +#include "gfm.h" + +#ifdef ALIGNER_SEED2_MAIN + +#include +#include "sstring.h" + +using namespace std; + +/** + * A way of feeding simply tests to the seed alignment infrastructure. + */ +int main(int argc, char **argv) { + + EList strs; + // GCTATATAGCGCGCTCGCATCATTTTGTGT + strs.push_back(string("CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA" + "NNNNNNNNNN" + "CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA")); + // GCTATATAGCGCGCTTGCATCATTTTGTGT + // ^ + bool packed = false; + int color = 0; + pair gfms = GFM::fromStrings >( + strs, + packed, + REF_READ_REVERSE, + Ebwt::default_bigEndian, + Ebwt::default_lineRate, + Ebwt::default_offRate, + Ebwt::default_ftabChars, + ".aligner_seed2.cpp.tmp", + Ebwt::default_useBlockwise, + Ebwt::default_bmax, + Ebwt::default_bmaxMultSqrt, + Ebwt::default_bmaxDivN, + Ebwt::default_dcv, + Ebwt::default_seed, + false, // verbose + false, // autoMem + false); // sanity + + gfms.first->loadIntoMemory (-1, true, true, true, true, false); + gfms.second->loadIntoMemory(1, true, true, true, true, false); + + int testnum = 0; + + // Query is longer than ftab and matches exactly twice + for(int rc = 0; rc < 2; rc++) { + for(int i = 0; i < 2; i++) { + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length greater than ftab" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + // Set up the read + BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + if(rc) { + seq.reverseComp(); + qual.reverse(); + } + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + conf.cons.init(GFM::default_ftabChars, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + (i == 0) ? 0 : (seq.length() - 1), // 5' offset into read of root + (i == 0) ? true : false, // left-to-right? + rc == 0, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(2, dr.sink().nelt()); + } + } + + // Query has length euqal to ftab and matches exactly twice + for(int i = 0; i < 2; i++) { + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length equal to ftab" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + // Set up the read + BTDnaString seq ("GCTATATAGC", true); + BTString qual("ABCDEFGHIa"); + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + conf.cons.init(GFM::default_ftabChars, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + (i == 0) ? 0 : (seq.length() - 1), // 5' offset into read of root + (i == 0) ? true : false, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(2, dr.sink().nelt()); + } + + // Query has length less than ftab length and matches exactly twice + for(int i = 0; i < 2; i++) { + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length less than ftab" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + // Set up the read + BTDnaString seq ("GCTATATAG", true); + BTString qual("ABCDEFGHI"); + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + conf.cons.init(GFM::default_ftabChars, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + (i == 0) ? 0 : (seq.length() - 1), // 5' offset into read of root + (i == 0) ? true : false, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(2, dr.sink().nelt()); + } + + // Search root is in the middle of the read, requiring a bounce + for(int i = 0; i < 2; i++) { + cerr << "Test " << (++testnum) << endl; + cerr << " Search root in middle of read" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + // Set up the read + // 012345678901234567890123456789 + BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + TIndexOffU top, bot; + top = bot = 0; + bool ret = gfms.first->contains("GCGCTCGCATCATTTTGTGT", &top, &bot); + cerr << ret << ", " << top << ", " << bot << endl; + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + conf.cons.init(GFM::default_ftabChars, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + (i == 0) ? 10 : (seq.length() - 1 - 10), // 5' offset into read of root + (i == 0) ? true : false, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(2, dr.sink().nelt()); + } + + delete gfms.first; + delete gfms.second; + + strs.clear(); + strs.push_back(string("CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA" + "NNNNNNNNNN" + "CATGTCAGCTATATAGCG")); + gfms = GFM::fromStrings >( + strs, + packed, + REF_READ_REVERSE, + GFM::default_bigEndian, + GFM::default_lineRate, + GFM::default_offRate, + GFM::default_ftabChars, + ".aligner_seed2.cpp.tmp", + GFM::default_useBlockwise, + GFM::default_bmax, + GfM::default_bmaxMultSqrt, + GFM::default_bmaxDivN, + GFM::default_dcv, + GFM::default_seed, + false, // verbose + false, // autoMem + false); // sanity + + gfms.first->loadIntoMemory (-1, true, true, true, true, false); + gfms.second->loadIntoMemory(1, true, true, true, true, false); + + // Query is longer than ftab and matches exactly once. One search root for + // forward read. + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + for(size_t j = 0; j < seq.length(); j++) { + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length greater than ftab and matches exactly once" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + // Set up the read + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + conf.cons.init(GFM::default_ftabChars, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + assert_eq(1, dr.sink().nelt()); + } + } + } + + // Query is longer than ftab and its reverse complement matches exactly + // once. Search roots on forward and reverse-comp reads. + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + BTDnaString seq ("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + for(size_t j = 0; j < seq.length(); j++) { + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length greater than ftab and reverse complement matches exactly once" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + // Set up the read + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + conf.cons.init(GFM::default_ftabChars, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + false, // forward? + 1.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + assert_eq(1, dr.sink().nelt()); + } + } + } + + // Query is longer than ftab and matches exactly once with one mismatch + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA + // |||||||||||||||||||||||||||||| + BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + // 012345678901234567890123456789 + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + for(size_t k = 0; k < orig.length(); k++) { + BTDnaString seq = orig; + seq.set(seq[k] ^ 3, k); + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + size_t kk = k; + //if(rc) { + // kk = seq.length() - k - 1; + //} + if(beg <= kk && end > kk) { + continue; + } + if((j > kk) ? (j - kk <= 2) : (kk - j <= 2)) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length greater than ftab and matches exactly once with 1mm" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(0, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + } + + // Query is longer than ftab and matches exactly once with one N mismatch + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA + // |||||||||||||||||||||||||||||| + BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + // 012345678901234567890123456789 + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + for(size_t k = 0; k < orig.length(); k++) { + BTDnaString seq = orig; + seq.set(4, k); + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + if(beg <= k && end > k) { + continue; + } + if((j > k) ? (j - k <= 2) : (k - j <= 2)) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length greater than ftab and matches exactly once with 1mm" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(0, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(sc.n(40), dr.sink()[0].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + } + + // Throw a bunch of queries with a bunch of Ns in and try to force an assert + { + RandomSource rnd(79); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA + // |||||||||||||||||||||||||||||| + BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + // 012345678901234567890123456789 + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + if(i == 1) { + orig.reverseComp(); + qual.reverse(); + } + for(size_t trials = 0; trials < 100; trials++) { + BTDnaString seq = orig; + size_t ns = 10; + for(size_t k = 0; k < ns; k++) { + size_t pos = rnd.nextU32() % seq.length(); + seq.set(4, pos); + } + + cerr << "Test " << (++testnum) << endl; + cerr << " Query with a bunch of Ns" << endl; + + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(GFM::default_ftabChars, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + for(size_t k = 0; k < ns; k++) { + size_t j = rnd.nextU32() % seq.length(); + bool ltr = (rnd.nextU2() == 0) ? true : false; + bool fw = (rnd.nextU2() == 0) ? true : false; + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + ltr, // left-to-right? + fw, // forward? + 0.0f); // root priority + } + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + } + } + } + + // Query is longer than ftab and matches exactly once with one mismatch + { + RandomSource rnd(77); + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA + // |||||||||||||||||||||||||||||| + BTDnaString orig("GCTATATAGCGCGCTCGCATCATTTTGTGT", true); + // 012345678901234567890123456789 + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIabc"); + // revcomp: ACACAAAATGATGCGAGCGCGCTATATAGC + // revqual: cbaIHGFEDCBAihgfedcbaIHGFEDCBA + bool fwi = (i == 0); + if(!fwi) { + orig.reverseComp(); + } + for(size_t k = 0; k < orig.length(); k++) { + BTDnaString seq = orig; + seq.set(seq[k] ^ 3, k); + cerr << "Test " << (++testnum) << endl; + cerr << " Query with length greater than ftab and matches exactly once with 1mm. Many search roots." << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(0, 1.0); + conf.expol = DESC_EX_NONE; + + // Set up several random search roots + bool onegood = false; + for(size_t y = 0; y < 10; y++) { + size_t j = rnd.nextU32() % seq.length(); + bool ltr = (rnd.nextU2() == 0) ? true : false; + bool fw = (rnd.nextU2() == 0) ? true : false; + dr.addRoot( + conf, // DescentConfig + (TReadOff)j, // 5' offset into read of root + ltr, // left-to-right? + fw, // forward? + (float)((float)y * 1.0f)); // root priority + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if(!ltr) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + bool good = true; + if(fw != fwi) { + good = false; + } + if(beg <= k && end > k) { + good = false; + } + if((j > k) ? (j - k <= 2) : (k - j <= 2)) { + good = false; + } + if(good) { + onegood = true; + } + } + if(!onegood) { + continue; + } + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + + // Query is longer than ftab and matches exactly once with one read gap + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + for(int k = 0; k < 2; k++) { + // Set up the read + // GCTATATAGCGCGCCTGCATCATTTTGTGT + // Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA + // |||||||||||||||/////////////// + BTDnaString seq ("GCTATATAGCGCGCTGCATCATTTTGTGT", true); + // 01234567890123456789012345678 + // 87654321098765432109876543210 + BTString qual("ABCDEFGHIabcdefghiABCDEFGHIab"); + if(k == 1) { + seq.reverseComp(); + qual.reverse(); + } + assert_eq(seq.length(), qual.length()); + // js iterate over offsets from 5' end for the search root + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + if(k == 1) { + beg = seq.length() - beg - 1; + } + size_t end = beg + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + assert_geq(end, beg); + if(beg <= 15 && end >= 15) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query matches once with a read gap of length 1" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + Read q("test", seq.toZBuf(), qual.toZBuf()); + assert(q.repOk()); + dr.initRead(q, -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(0, 0.5); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + k == 0, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(sc.readGapOpen() + 0 * sc.readGapExtend(), dr.sink()[0].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + }} + } + + // Query is longer than ftab and matches exactly once with one read gap of + // length 3 + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + for(int k = 0; k < 2; k++) { + // Set up the read + // GCTATATAGCGCGCGCTCATCATTTTGTGT + // Ref: CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAACCA + // |||||||||||||| ||||||||||||| + BTDnaString seq ("GCTATATAGCGCGC" "CATCATTTTGTGT", true); + // 01234567890123 4567890123456 + // 65432109876543 2109876543210 + BTString qual("ABCDEFGHIabcde" "fghiABCDEFGHI"); + if(k == 1) { + seq.reverseComp(); + qual.reverse(); + } + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + if(k == 1) { + beg = seq.length() - beg - 1; + } + size_t end = beg + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + if(beg <= 14 && end >= 14) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query matches once with a read gap of length 3" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(0, 0.2); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + k == 0, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + // Need to adjust the mismatch penalty up to avoid alignments + // with lots of mismatches. + sc.setMmPen(COST_MODEL_CONSTANT, 6, 6); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(sc.readGapOpen() + 2 * sc.readGapExtend(), dr.sink()[0].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + }} + } + + // Query is longer than ftab and matches exactly once with one reference gap + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCTATATAGCGCGC" "TCGCATCATTTTGTGTGTAAACCA + // |||||||||||||| |||||||||||||||| + BTDnaString seq ("GCTATATAGCGCGCA""TCGCATCATTTTGTGT", true); + // 012345678901234 5678901234567890 + BTString qual("ABCDEFGHIabcdef""ghiABCDEFGHIabcd"); + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + if(beg <= 14 && end >= 14) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query matches once with a reference gap of length 1" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(1, 0.5); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + // Need to adjust the mismatch penalty up to avoid alignments + // with lots of mismatches. + sc.setMmPen(COST_MODEL_CONSTANT, 6, 6); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(sc.refGapOpen() + 0 * sc.refGapExtend(), dr.sink()[0].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + + // Query is longer than ftab and matches exactly once with one reference gap + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCTATATAGCGCGC" "TCGCATCATTTTGTGTGTAAACCA + // |||||||||||||| |||||||||||||||| + BTDnaString seq ("GCTATATAGCGCGCATG""TCGCATCATTTTGTGT", true); + // 01234567890123456 7890123456789012 + BTString qual("ABCDEFGHIabcdefgh""iABCDEFGHIabcdef"); + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + if(beg <= 14 && end >= 14) { + continue; + } + if(beg <= 15 && end >= 15) { + continue; + } + if(beg <= 16 && end >= 16) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query matches once with a reference gap of length 1" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -30, 30); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(1, 0.25); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + // Need to adjust the mismatch penalty up to avoid alignments + // with lots of mismatches. + sc.setMmPen(COST_MODEL_CONSTANT, 6, 6); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(sc.refGapOpen() + 2 * sc.refGapExtend(), dr.sink()[0].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + + // Query is longer than ftab and matches exactly once with one read gap, + // one ref gap, and one mismatch + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCT ATATAGCGCGCT CGCATCATTTTGTGTGTAAACCA + // |||||||||| |||||||||||| |||||| ||||||||||||| + BTDnaString seq ("CATGTCAGCT""GATATAGCGCGCT" "GCATCAATTTGTGTGTAAAC", true); + // 0123456789 0123456789012 34567890123456789012 + BTString qual("ABCDEFGHIa""bcdefghiACDEF" "GHIabcdefghijkABCDEF"); + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + if(beg <= 10 && end >= 10) { + continue; + } + if(beg <= 22 && end >= 22) { + continue; + } + if(beg <= 30 && end >= 30) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query matches once with a read gap of length 1" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -50, 50); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(1, 0.5); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(1, dr.sink().nrange()); + assert_eq(sc.readGapOpen() + sc.refGapOpen() + sc.mm((int)'d' - 33), dr.sink()[0].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(1, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + + delete gfms.first; + delete gfms.second; + + // Ref CATGTCAGCT-ATATAGCGCGCTCGCATCATTTTGTGTGTAAAC + // |||||||||| |||||||||||| |||||| ||||||||||||| + // Rd CATGTCAGCTGATATAGCGCGCT-GCATCAATTTGTGTGTAAAC + strs.clear(); + strs.push_back(string("CATGTCAGCTATATAGCGCGCTCGCATCATTTTGTGTGTAAAC" + "NNNNNNNNNN" + "CATGTCAGCTGATATAGCGCGCTCGCATCATTTTGTGTGTAAAC" // same but without first ref gap + "N" + "CATGTCAGCTATATAGCGCGCTGCATCATTTTGTGTGTAAAC" // same but without first read gap + "N" + "CATGTCAGCTATATAGCGCGCTCGCATCAATTTGTGTGTAAAC" // same but without first mismatch + "N" + "CATGTCAGCTGATATAGCGCGCTGCATCAATTTGTGTGTAAAC" // Exact match for read + )); + gfms = GFM::fromStrings >( + strs, + packed, + REF_READ_REVERSE, + GFM::default_bigEndian, + GFM::default_lineRate, + GFM::default_offRate, + GFM::default_ftabChars, + ".aligner_seed2.cpp.tmp", + GFM::default_useBlockwise, + GFM::default_bmax, + GFM::default_bmaxMultSqrt, + GFM::default_bmaxDivN, + GFM::default_dcv, + GFM::default_seed, + false, // verbose + false, // autoMem + false); // sanity + + gfms.first->loadIntoMemory (color, -1, true, true, true, true, false); + gfms.second->loadIntoMemory(color, 1, true, true, true, true, false); + + // Query is longer than ftab and matches exactly once with one read gap, + // one ref gap, and one mismatch + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCT ATATAGCGCGCT CGCATCATTTTGTGTGTAAACCA + // |||||||||| |||||||||||| |||||| ||||||||||||| + BTDnaString seq ("CATGTCAGCT""GATATAGCGCGCT" "GCATCAATTTGTGTGTAAAC", true); + // 0123456789 0123456789012 34567890123456789012 + BTString qual("ABCDEFGHIa""bcdefghiACDEF" "GHIabcdefghijkABCDEF"); + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + if(beg <= 10 && end >= 10) { + continue; + } + if(beg <= 22 && end >= 22) { + continue; + } + if(beg <= 30 && end >= 30) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query matches once with a read gap of length 1" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -50, 50); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(1, 0.5); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(5, dr.sink().nrange()); + assert_eq(0, dr.sink()[0].pen); + assert_eq(min(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[1].pen); + assert_eq(max(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[2].pen); + assert_eq(sc.readGapOpen() + sc.refGapOpen(), dr.sink()[3].pen); + assert_eq(sc.readGapOpen() + sc.refGapOpen() + sc.mm((int)'d' - 33), dr.sink()[4].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(5, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + + // Query is longer than ftab and matches exactly once with one read gap, + // one ref gap, one mismatch, and one N + { + size_t last_topf = std::numeric_limits::max(); + size_t last_botf = std::numeric_limits::max(); + for(int i = 0; i < 2; i++) { + // Set up the read + // Ref: CATGTCAGCT ATATAGCGCGCT CGCATCATTTTGTGTGTAAACCA + // |||||||||| |||||||||||| |||||| |||||| |||||| + BTDnaString seq ("CATGTCAGCT""GATATAGCGCGCT" "GCATCAATTTGTGNGTAAAC", true); + // 0123456789 0123456789012 34567890123456789012 + BTString qual("ABCDEFGHIa""bcdefghiACDEF" "GHIabcdefghijkABCDEF"); + for(size_t j = 0; j < seq.length(); j++) { + // Assume left-to-right + size_t beg = j; + size_t end = j + GFM::default_ftabChars; + // Mismatch penalty is 3, so we have to skip starting + // points that are within 2 from the mismatch + if((i > 0 && j > 0) || j == seq.length()-1) { + // Right-to-left + if(beg < GFM::default_ftabChars) { + beg = 0; + } else { + beg -= GFM::default_ftabChars; + } + end -= GFM::default_ftabChars; + } + if(beg <= 10 && end >= 10) { + continue; + } + if(beg <= 22 && end >= 22) { + continue; + } + if(beg <= 30 && end >= 30) { + continue; + } + if(beg <= 36 && end >= 36) { + continue; + } + cerr << "Test " << (++testnum) << endl; + cerr << " Query matches with various patterns of gaps, mismatches and Ns" << endl; + DescentMetrics mets; + PerReadMetrics prm; + DescentDriver dr; + + dr.initRead(Read("test", seq.toZBuf(), qual.toZBuf()), -50, 50); + + // Set up the DescentConfig + DescentConfig conf; + // Changed + conf.cons.init(1, 0.5); + conf.expol = DESC_EX_NONE; + + // Set up the search roots + dr.addRoot( + conf, // DescentConfig + j, // 5' offset into read of root + i == 0, // left-to-right? + true, // forward? + 0.0f); // root priority + + // Do the search + Scoring sc = Scoring::base1(); + sc.setNPen(COST_MODEL_CONSTANT, 1); + dr.go(sc, *gfms.first, *gfms.second, mets, prm); + + // Confirm that an exact-matching alignment was found + assert_eq(5, dr.sink().nrange()); + assert_eq(sc.n(40), dr.sink()[0].pen); + assert_eq(sc.n(40) + min(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[1].pen); + assert_eq(sc.n(40) + max(sc.readGapOpen(), sc.refGapOpen()) + sc.mm((int)'d' - 33), dr.sink()[2].pen); + assert_eq(sc.n(40) + sc.readGapOpen() + sc.refGapOpen(), dr.sink()[3].pen); + assert_eq(sc.n(40) + sc.readGapOpen() + sc.refGapOpen() + sc.mm((int)'d' - 33), dr.sink()[4].pen); + assert(last_topf == std::numeric_limits::max() || last_topf == dr.sink()[0].topf); + assert(last_botf == std::numeric_limits::max() || last_botf == dr.sink()[0].botf); + cerr << dr.sink()[0].topf << ", " << dr.sink()[0].botf << endl; + assert_eq(5, dr.sink().nelt()); + last_topf = dr.sink()[0].topf; + last_botf = dr.sink()[0].botf; + } + } + } + + delete gfms.first; + delete gfms.second; + + cerr << "DONE" << endl; +} +#endif + diff --git a/aligner_seed2.h b/aligner_seed2.h new file mode 100644 index 0000000..552f7be --- /dev/null +++ b/aligner_seed2.h @@ -0,0 +1,4291 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_SEED2_H_ +#define ALIGNER_SEED2_H_ + +/** + * The user of the DescentDriver class specifies a collection of search roots. + * Logic for picking these search roots is located elsewhere, not in this + * module. The search roots are annotated with a priority score, which + * + * The heap is a min-heap over pairs, where the first element of each pair is + * the score associated with a descent and the second element of each pair is + * the descent ID. + * + * Weeding out redundant descents is key; otherwise we end up reporting slight + * variations on the same alignment repeatedly, including variations with poor + * scores. What criteria do we use to determine whether two paths are + * redundant? + * + * Here's an example where the same set of read characters have been aligned in + * all three cases: + * + * Alignment 1 (sc = 0): + * Rd: GCTATATAGCGCGCTCGCATCATTTTGTGT + * |||||||||||||||||||||||||||||| + * Rf: GCTATATAGCGCGCTCGCATCATTTTGTGT + * + * Alignment 2 (sc = -22): + * Rd: GCTATATAGCGCGCTCGCATCATTTTGTGT + * ||||||||||||||||||||||| | ||| + * Rf: GCTATATAGCGCGCTCGCATCAT--TTTGT + * + * Alignment 3 (sc = -22): + * Rd: GCTATATAGCGCGCTCGCATCATT--TTGTGT + * |||||||||||||||||||||||| ||||| + * Rf: GCTATATAGCGCGCTCGCATCATTTTGTGTGT + * + * Rf from aln 1: GCTATATAGCGCGCTCGCATCATTTTGTGT + * Rf from aln 2: GCTATATAGCGCGCTCGCATCATTTTGT + * Rf from aln 3: GCTATATAGCGCGCTCGCATCATTTTGTGTGT + * + * Are alignments 2 and 3 redundant with alignment 1? We can't totally say + * without knowing the associated SA ranges. Take alignments 1 and 2. Either + * the SA ranges are the same or the SA range for 2 contains the SA range for + * 1. If they're the same, then alignment 2 is redundant with alignment 1. + * Otherwise, *some* of the elements in the SA range for alignment 2 are not + * redundant. + * + * In that example, the same read characters are aligned in all three + * alignments. Is it possible and profitable to consider scenarios where an + * alignment might be redundant with another alignment + * + * Another question is *when* do we try to detect the redundancy? Before we + * try to extend through the matches, or after. After is easier, but less work + * has been avoided. + * + * What data structure do we query to determine whether there's redundancy? + * The situation is harder when we try to detect overlaps between SA ranges + * rather than identical SA ranges. Maybe: read intervals -> intersection tree -> penalties. + * + * 1. If we're introducing a gap and we could have introduced it deeper in the + * descent with the same effect w/r/t homopolymer length. + * 2. If we have Descent A with penalty B and Descent a with penalty b, and A + * aligns read characters [X, Y] to SA range [Z, W], and B aligns read + * characters [x, y] to SA range [z, w], then A is redundant with B if + * [x, y] is within [X, Y]. + * + * Found an alignment with total penalty = 3 + * GCAATATAGCGCGCTCGCATCATTTTGTGT + * || ||||||||||||||||||||||||||| + * GCTATATAGCGCGCTCGCATCATTTTGTGT + * + * Found an alignment with total penalty = 27 + * gCAATATAGCGCGCTCGCATCATTTTGTGT + * | |||||||||||||||||||||||| + * TATA-TAGCGCGCTCGCATCATTTTGTGT + */ + +#include +#include +#include +#include +#include "assert_helpers.h" +#include "random_util.h" +#include "aligner_result.h" +#include "gfm.h" +#include "simple_func.h" +#include "scoring.h" +#include "edit.h" +#include "read.h" +#include "ds.h" +#include "group_walk.h" +#include "btypes.h" + +typedef size_t TReadOff; +typedef int64_t TScore; +typedef float TRootPri; +typedef size_t TDescentId; +typedef size_t TRootId; + +/** + * enum encapsulating a few different policies for how we might extend descents + * in the direction opposite from their primary direction. + */ +enum { + // Never extened in the direction opposite from the primary. Just go in + // the primary direction until the bounce. + DESC_EX_NONE = 1, + + // When we're finished extending out the matches for a descent, try to + // extend in the opposite direction in a way that extends all branches + // simultaneously. The Descent.nex_ field contains the number of positions + // we were able to extend through in this way. + DESC_EX_FROM_1ST_BRANCH = 2, + + // Each time we add an edge to the summary, extend it in the opposite + // direction. The DescentEdge.nex field contains the number of positions + // we were able to extend through, and this in turn gets propagated to + // Descent.nex_ if and when we branch from the DescentEdge. + DESC_EX_EACH_EDGE = 3 +}; + +/** + * Counters to keep track of how much work is being done. + */ +struct DescentMetrics { + + DescentMetrics() { reset(); } + + void reset() { + bwops = bwops_1 = bwops_bi = recalc = branch = branch_mm = + branch_del = branch_ins = heap_max = descent_max = descentpos_max = + nex = 0; + } + + uint64_t bwops; // # FM Index opbs + uint64_t bwops_1; // # LF1 FM Index opbs + uint64_t bwops_bi; // # BiEx FM Index opbs + uint64_t recalc; // # times outgoing edge summary was recalculated + uint64_t branch; // # times we descended from another descent + uint64_t branch_mm; // # times branch was on a mismatch + uint64_t branch_del; // # times branch was on a deletion + uint64_t branch_ins; // # times branch was on a insertion + uint64_t heap_max; // maximum size of Descent heap + uint64_t descent_max; // maximum size of Descent factory + uint64_t descentpos_max; // maximum size of DescentPos factory + uint64_t nex; // # extensions +}; + +/** + * Priority used to rank which descent we should branch from next. Right now, + * priority is governed by a 4-tuple. From higher to lower priority: + * + * 1. Penalty accumulated so far + * 2. Depth into the search space, including extensions + * 3. Width of the SA range (i.e. uniqueness) + * 4. Root priority + */ +struct DescentPriority { + + DescentPriority() { reset(); } + + DescentPriority( + TScore pen_, + size_t depth_, + TIndexOffU width_, + float rootpri_) + { + pen = pen_; + depth = depth_; + width = width_; + rootpri = rootpri_; + } + + /** + * Initialize new DescentPriority. + */ + void init(TScore pen_, size_t depth_, TIndexOffU width_, float rootpri_) { + pen = pen_; + depth = depth_; + width = width_; + rootpri = rootpri_; + } + + /** + * Reset to uninitialized state. + */ + void reset() { + width = 0; + } + + /** + * Return true iff DescentPriority is initialized. + */ + bool inited() const { + return width > 0; + } + + /** + * Return true iff this priority is prior to given priority. + */ + bool operator<(const DescentPriority& o) const { + assert(inited()); + assert(o.inited()); + // 1st priority: penalty accumulated so far + if(pen < o.pen) return true; + if(pen > o.pen) return false; + // 2nd priority: depth into the search space, including extensions + if(depth > o.depth) return true; + if(depth < o.depth) return false; + // 3rd priority: width of the SA range (i.e. uniqueness) + if(width < o.width) return true; + if(width > o.width) return false; + // 4th priority: root priority + if(rootpri > o.rootpri) return true; + return false; + } + + /** + * Return true iff this priority is prior to or equal to given priority. + */ + bool operator<=(const DescentPriority& o) const { + assert(inited()); + assert(o.inited()); + // 1st priority: penalty accumulated so far + if(pen < o.pen) return true; + if(pen > o.pen) return false; + // 2nd priority: depth into the search space, including extensions + if(depth > o.depth) return true; + if(depth < o.depth) return false; + // 3rd priority: width of the SA range (i.e. uniqueness) + if(width < o.depth) return true; + if(width > o.width) return false; + // 4th priority: root priority + if(rootpri > o.rootpri) return true; + return true; + } + + /** + * Return true iff this priority is prior to or equal to given priority. + */ + bool operator==(const DescentPriority& o) const { + assert(inited()); + assert(o.inited()); + return pen == o.pen && depth == o.depth && width == o.width && rootpri == o.rootpri; + } + + TScore pen; // total penalty accumulated so far + size_t depth; // depth from root of descent + TIndexOffU width; // width of the SA range + float rootpri; // priority of the root +}; + +static inline std::ostream& operator<<( + std::ostream& os, + const DescentPriority& o) +{ + os << "[" << o.pen << ", " << o.depth << ", " << o.width << ", " << o.rootpri << "]"; + return os; +} + +static inline std::ostream& operator<<( + std::ostream& os, + const std::pair& o) +{ + os << "{[" << o.first.pen << ", " << o.first.depth << ", " + << o.first.width << ", " << o.first.rootpri << "], " << o.second << "}"; + return os; +} + +typedef std::pair TDescentPair; + +/** + * Encapsulates the constraints limiting which outgoing edges are permitted. + * Specifically, we constrain the total penalty accumulated so far so that some + * outgoing edges will exceed the limit and be pruned. The limit is set + * according to our "depth" into the search, as measured by the number of read + * characters aligned so far. We divide the depth domain into two pieces, a + * piece close to the root, where the penty is constrained to be 0, and the + * remainder, where the maximum penalty is an interpolation between 0 and the + * maximum penalty + */ +struct DescentConstraints { + + DescentConstraints() { reset(); } + + /** + * Initialize with new constraint function. + */ + DescentConstraints(size_t nzero, double exp) { + init(nzero, exp); + } + + /** + * Initialize with given function. + */ + void init(size_t nzero_, double exp_) { + nzero = nzero_ > 0 ? nzero_ : 1; + exp = exp_; +#ifndef NDEBUG + for(size_t i = 1; i < nzero_ + 5; i++) { + assert_geq(get(i, nzero_ + 10, 100), get(i-1, nzero_ + 10, 100)); + } +#endif + } + + /** + * Reset to uninitialized state. + */ + void reset() { + nzero = 0; + exp = -1.0f; + } + + /** + * Return true iff the DescentConstraints has been initialized. + */ + bool inited() const { + return exp >= 0.0f; + } + + /** + * Get the maximum penalty total for depth 'off'. + */ + inline TScore get(TReadOff off, TReadOff rdlen, TAlScore maxpen) const { + if(off < nzero || nzero >= rdlen) { + return 0; + } + double frac = (double)(off - nzero) / (rdlen - nzero); + if(fabs(exp - 1.0f) > 0.00001) { + if(fabs(exp - 2.0f) < 0.00001) { + frac *= frac; + } else { + frac = pow(frac, exp); + } + } + return (TAlScore)(frac * maxpen + 0.5f); + } + + size_t nzero; + double exp; +}; + +/** + * Encapsulates settings governing how we descent. + */ +struct DescentConfig { + + DescentConfig() { reset(); } + + /** + * Reset the DescentConfig to an uninitialized state. + */ + void reset() { expol = 0; } + + /** + * Return true iff this DescentConfig is initialized. + */ + bool inited() const { return expol != 0; } + + DescentConstraints cons; // constraints + int expol; // extend policy +}; + +/** + * Encapsulates the state of a Descent that allows us to determine whether it + * is redundant with another Descent. Two Descents are redundant if: + * + * 1. Both are aligning the same read orientation (fw or rc) + * 2. Both are growing the alignment in the same direction (left-to-right or + * right-to-left) + * 3. They have aligned exactly the same read characters (which are always + * consecutive in the read) + * 4. The corresponding reference strings are identical + */ +struct DescentRedundancyKey { + + DescentRedundancyKey() { reset(); } + + DescentRedundancyKey( + TReadOff al5pf_, + size_t rflen_, + TIndexOffU topf_, + TIndexOffU botf_) + { + init(al5pf_, rflen_, topf_, botf_); + } + + void reset() { + al5pf = 0; + rflen = 0; + topf = botf = 0; + } + + bool inited() const { return rflen > 0; } + + void init( + TReadOff al5pf_, + size_t rflen_, + TIndexOffU topf_, + TIndexOffU botf_) + { + al5pf = al5pf_; + rflen = rflen_; + topf = topf_; + botf = botf_; + } + + bool operator==(const DescentRedundancyKey& o) const { + return al5pf == o.al5pf && rflen == o.rflen && topf == o.topf && botf == o.botf; + } + + bool operator<(const DescentRedundancyKey& o) const { + if(al5pf < o.al5pf) return true; + if(al5pf > o.al5pf) return false; + if(rflen < o.rflen) return true; + if(rflen > o.rflen) return false; + if(topf < o.topf) return true; + if(topf > o.topf) return false; + return botf < o.botf; + } + + TReadOff al5pf; // 3'-most aligned char, as offset from 5' end + size_t rflen; // number of reference characters involved in alignment + TIndexOffU topf; // top w/r/t forward index + TIndexOffU botf; // bot w/r/t forward index +}; + +/** + * Map from pairs to top, bot, penalty triples. + */ +class DescentRedundancyChecker { + +public: + + DescentRedundancyChecker() { reset(); } + + void clear() { reset(); } + + /** + * Reset to uninitialized state. + */ + void reset() { + bits_.reset(); + inited_ = false; + totsz_ = 0; // total size + totcap_ = 0; // total capacity + } + + const static int NPARTS = 8; + const static int PART_MASK = 7; + const static int NBITS = (1 << 16); + + /** + * Initialize using given read length. + */ + void init(TReadOff rdlen) { + reset(); + // daehwan - for debugging purposes +#if 0 + bits_.resize(NBITS); + maplist_fl_.resize(NPARTS); + maplist_fr_.resize(NPARTS); + maplist_rl_.resize(NPARTS); + maplist_rr_.resize(NPARTS); + for(int i = 0; i < NPARTS; i++) { + maplist_fl_[i].resize(rdlen); + maplist_fr_[i].resize(rdlen); + maplist_rl_[i].resize(rdlen); + maplist_rr_[i].resize(rdlen); + totcap_ += maplist_fl_[i].totalCapacityBytes(); + totcap_ += maplist_fr_[i].totalCapacityBytes(); + totcap_ += maplist_rl_[i].totalCapacityBytes(); + totcap_ += maplist_rr_[i].totalCapacityBytes(); + for(size_t j = 0; j < rdlen; j++) { + maplist_fl_[i][j].clear(); + maplist_fr_[i][j].clear(); + maplist_rl_[i][j].clear(); + maplist_rr_[i][j].clear(); + totcap_ += maplist_fl_[i][j].totalCapacityBytes(); + totcap_ += maplist_fr_[i][j].totalCapacityBytes(); + totcap_ += maplist_rl_[i][j].totalCapacityBytes(); + totcap_ += maplist_rr_[i][j].totalCapacityBytes(); + } + } +#endif + inited_ = true; + } + + /** + * Return true iff the checker is initialized. + */ + bool inited() const { + return inited_; + } + + /** + * Check if this partial alignment is redundant with one that we've already + * explored. + */ + bool check( + bool fw, + bool l2r, + TReadOff al5pi, + TReadOff al5pf, + size_t rflen, + TIndexOffU topf, + TIndexOffU botf, + TScore pen) + { + // daehwan - for debugging purposes + return true; + + assert(inited_); + assert(topf > 0 || botf > 0); + DescentRedundancyKey k(al5pf, rflen, topf, botf); + size_t i = std::numeric_limits::max(); + size_t mask = topf & PART_MASK; + EMap& map = + (fw ? (l2r ? maplist_fl_[mask][al5pi] : maplist_fr_[mask][al5pi]) : + (l2r ? maplist_rl_[mask][al5pi] : maplist_rr_[mask][al5pi])); + size_t key = (topf & 255) | ((botf & 255) << 8); + if(bits_.test(key) && map.containsEx(k, i)) { + // Already contains the key + assert_lt(i, map.size()); + assert_geq(pen, map[i].second); + return false; + } + assert(!map.containsEx(k, i)); + size_t oldsz = map.totalSizeBytes(); + size_t oldcap = map.totalCapacityBytes(); + map.insert(make_pair(k, pen)); + bits_.set(key); + totsz_ += (map.totalSizeBytes() - oldsz); + totcap_ += (map.totalCapacityBytes() - oldcap); + return true; + } + + /** + * Check if this partial alignment is redundant with one that we've already + * explored using the Bw index SA range. + */ + bool contains( + bool fw, + bool l2r, + TReadOff al5pi, + TReadOff al5pf, + size_t rflen, + TIndexOffU topf, + TIndexOffU botf, + TScore pen) + { + // daehwan - for debugging purposes + return false; + + assert(inited_); + size_t key = (topf & 255) | ((botf & 255) << 8); + if(!bits_.test(key)) { + return false; + } + DescentRedundancyKey k(al5pf, rflen, topf, botf); + size_t mask = topf & PART_MASK; + EMap& map = + (fw ? (l2r ? maplist_fl_[mask][al5pi] : maplist_fr_[mask][al5pi]) : + (l2r ? maplist_rl_[mask][al5pi] : maplist_rr_[mask][al5pi])); + return map.contains(k); + } + + /** + * Return the total size of the redundancy map. + */ + size_t totalSizeBytes() const { + return totsz_; + } + + /** + * Return the total capacity of the redundancy map. + */ + size_t totalCapacityBytes() const { + return totcap_; + } + +protected: + + bool inited_; // initialized? + size_t totsz_; // total size + size_t totcap_; // total capacity + + // List of maps. Each entry is a map for all the DescentRedundancyKeys + // with al5pi equal to the offset into the list. + ELList, NPARTS, 100> maplist_fl_; // fw, l2r + ELList, NPARTS, 100> maplist_rl_; // !fw, l2r + ELList, NPARTS, 100> maplist_fr_; // fw, !l2r + ELList, NPARTS, 100> maplist_rr_; // !fw, !l2r + + EBitList<128> bits_; +}; + +/** + * A search root. Consists of an offset from the 5' end read and flags + * indicating (a) whether we're initially heading left-to-right or + * right-to-left, and (b) whether we're examining the read or its reverse + * complement. + * + * A root also comes with a priority ("pri") score indicating how promising it + * is as a root. Promising roots have long stretches of high-quality, + * non-repetitive nucleotides in the first several ply of the search tree. + * Also, roots beginning at the 5' end of the read may receive a higher + * priority. + */ +struct DescentRoot { + + DescentRoot() { reset(); } + + DescentRoot(size_t off5p_, bool l2r_, bool fw_, size_t len, float pri_) { + init(off5p_, l2r_, fw_, len, pri_); + } + + /** + * Reset this DescentRoot to uninitialized state. + */ + void reset() { + off5p = std::numeric_limits::max(); + } + + /** + * Return true iff this DescentRoot is uninitialized. + */ + bool inited() const { + return off5p == std::numeric_limits::max(); + } + + /** + * Initialize a new descent root. + */ + void init(size_t off5p_, bool l2r_, bool fw_, size_t len, float pri_) { + off5p = off5p_; + l2r = l2r_; + fw = fw_; + pri = pri_; + assert_lt(off5p, len); + } + + TReadOff off5p; // root origin offset, expressed as offset from 5' end + bool l2r; // true -> move in left-to-right direction + bool fw; // true -> work with forward read, false -> revcomp + float pri; // priority of seed +}; + +/** + * Set of flags indicating outgoing edges we've tried from a DescentPos. + */ +struct DescentPosFlags { + + DescentPosFlags() { reset(); } + + /** + * Set all flags to 1, indicating all outgoing edges are yet to be + * explored. + */ + void reset() { + mm_a = mm_c = mm_g = mm_t = rdg_a = rdg_c = rdg_g = rdg_t = rfg = 1; + reserved = 0; + } + + /** + * Return true iff all outgoing edges have already been explored. + */ + bool exhausted() const { + return ((uint16_t*)this)[0] == 0; + } + + /** + * Return false iff the specified mismatch has already been explored. + */ + bool mmExplore(int c) { + assert_range(0, 3, c); + if(c == 0) { + return mm_a; + } else if(c == 1) { + return mm_c; + } else if(c == 2) { + return mm_g; + } else { + return mm_t; + } + } + + /** + * Try to explore a mismatch. Return false iff it has already been + * explored. + */ + bool mmSet(int c) { + assert_range(0, 3, c); + if(c == 0) { + bool ret = mm_a; mm_a = 0; return ret; + } else if(c == 1) { + bool ret = mm_c; mm_c = 0; return ret; + } else if(c == 2) { + bool ret = mm_g; mm_g = 0; return ret; + } else { + bool ret = mm_t; mm_t = 0; return ret; + } + } + + /** + * Return false iff specified read gap has already been explored. + */ + bool rdgExplore(int c) { + assert_range(0, 3, c); + if(c == 0) { + return rdg_a; + } else if(c == 1) { + return rdg_c; + } else if(c == 2) { + return rdg_g; + } else { + return rdg_t; + } + } + + /** + * Try to explore a read gap. Return false iff it has already been + * explored. + */ + bool rdgSet(int c) { + assert_range(0, 3, c); + if(c == 0) { + bool ret = rdg_a; rdg_a = 0; return ret; + } else if(c == 1) { + bool ret = rdg_c; rdg_c = 0; return ret; + } else if(c == 2) { + bool ret = rdg_g; rdg_g = 0; return ret; + } else { + bool ret = rdg_t; rdg_t = 0; return ret; + } + } + + /** + * Return false iff the reference gap has already been explored. + */ + bool rfgExplore() { + return rfg; + } + + /** + * Try to explore a reference gap. Return false iff it has already been + * explored. + */ + bool rfgSet() { + bool ret = rfg; rfg = 0; return ret; + } + + uint16_t mm_a : 1; + uint16_t mm_c : 1; + uint16_t mm_g : 1; + uint16_t mm_t : 1; + + uint16_t rdg_a : 1; + uint16_t rdg_c : 1; + uint16_t rdg_g : 1; + uint16_t rdg_t : 1; + + uint16_t rfg : 1; + + uint16_t reserved : 7; +}; + +/** + * FM Index state associated with a single position in a descent. For both the + * forward and backward indexes, it stores the four SA ranges corresponding to + * the four nucleotides. + */ +struct DescentPos { + + /** + * Reset all tops and bots to 0. + */ + void reset() { + topf[0] = topf[1] = topf[2] = topf[3] = 0; + botf[0] = botf[1] = botf[2] = botf[3] = 0; + topb[0] = topb[1] = topb[2] = topb[3] = 0; + botb[0] = botb[1] = botb[2] = botb[3] = 0; + c = -1; + flags.reset(); + } + + /** + * Return true iff DescentPos has been initialized. + */ + bool inited() const { + return c >= 0; + } + +#ifndef NDEBUG + /** + * Check that DescentPos is internally consistent. + */ + bool repOk() const { + assert_range(0, 3, (int)c); + return true; + } +#endif + + TIndexOffU topf[4]; // SA range top indexes in fw index + TIndexOffU botf[4]; // SA range bottom indexes (exclusive) in fw index + TIndexOffU topb[4]; // SA range top indexes in bw index + TIndexOffU botb[4]; // SA range bottom indexes (exclusive) in bw index + char c; // read char that would yield match + DescentPosFlags flags; // flags +}; + +/** + * Encapsulates an edge outgoing from a descent. + */ +struct DescentEdge { + + DescentEdge() { reset(); } + + DescentEdge( + Edit e_, + TReadOff off5p_, + DescentPriority pri_, + size_t posFlag_, + TReadOff nex_ +#ifndef NDEBUG + , + size_t d_, + TIndexOffU topf_, + TIndexOffU botf_, + TIndexOffU topb_, + TIndexOffU botb_ +#endif + ) + { + init(e_, off5p_, pri_, posFlag_ +#ifndef NDEBUG + , d_, topf_, botf_, topb_, botb_ +#endif + ); + } + + /** + * Return true iff edge is initialized. + */ + bool inited() const { return e.inited(); } + + /** + * Reset to uninitialized state. + */ + void reset() { e.reset(); } + + /** + * Initialize DescentEdge given 5' offset, nucleotide, and priority. + */ + void init( + Edit e_, + TReadOff off5p_, + DescentPriority pri_, + size_t posFlag_ +#ifndef NDEBUG + , + size_t d_, + TIndexOffU topf_, + TIndexOffU botf_, + TIndexOffU topb_, + TIndexOffU botb_ +#endif + ) + { + e = e_; + off5p = off5p_; + pri = pri_; + posFlag = posFlag_; +#ifndef NDEBUG + d = d_; + topf = topf_; + botf = botf_; + topb = topb_; + botb = botb_; +#endif + } + + /** + * Update flags to show this edge as visited. + */ + void updateFlags(EFactory& pf) { + if(inited()) { + if(e.isReadGap()) { + assert_neq('-', e.chr); + pf[posFlag].flags.rdgSet(asc2dna[e.chr]); + } else if(e.isRefGap()) { + pf[posFlag].flags.rfgSet(); + } else { + assert_neq('-', e.chr); + pf[posFlag].flags.mmSet(asc2dna[e.chr]); + } + } + } + + /** + * Return true iff this edge has higher priority than the given edge. + */ + bool operator<(const DescentEdge& o) const { + if(inited() && !o.inited()) { + return true; + } else if(!inited()) { + return false; + } + return pri < o.pri; + } + + DescentPriority pri; // priority of the edge + //TReadOff nex; // # extends possible from this edge + size_t posFlag; // depth of DescentPos where flag should be set + + +#ifndef NDEBUG + // This can be recreated by looking at the edit, the paren't descent's + // len_, al5pi_, al5pf_. I have it here so we can sanity check. + size_t d; + TIndexOffU topf, botf, topb, botb; +#endif + + Edit e; + TReadOff off5p; +}; + +/** + * Encapsulates an incomplete summary of the outgoing edges from a descent. We + * don't try to store information about all outgoing edges, because doing so + * will generally be wasteful. We'll typically only try a handful of them per + * descent. + */ +class DescentOutgoing { + +public: + + /** + * Return the best edge and rotate in preparation for next call. + */ + DescentEdge rotate() { + DescentEdge tmp = best1; + assert(!(best2 < tmp)); + best1 = best2; + assert(!(best3 < best2)); + best2 = best3; + assert(!(best4 < best3)); + best3 = best4; + assert(!(best5 < best4)); + best4 = best5; + best5.reset(); + return tmp; + } + + /** + * Given a potental outgoing edge, place it where it belongs in the running + * list of best 5 outgoing edges from this descent. + */ + void update(DescentEdge e) { + if(!best1.inited()) { + best1 = e; + } else if(e < best1) { + best5 = best4; + best4 = best3; + best3 = best2; + best2 = best1; + best1 = e; + } else if(!best2.inited()) { + best2 = e; + } else if(e < best2) { + best5 = best4; + best4 = best3; + best3 = best2; + best2 = e; + } else if(!best3.inited()) { + best3 = e; + } else if(e < best3) { + best5 = best4; + best4 = best3; + best3 = e; + } else if(!best4.inited()) { + best4 = e; + } else if(e < best4) { + best5 = best4; + best4 = e; + } else if(!best5.inited() || e < best5) { + best5 = e; + } + } + + /** + * Clear all the outgoing edges stored here. + */ + void clear() { + best1.reset(); + best2.reset(); + best3.reset(); + best4.reset(); + best5.reset(); + } + + /** + * Return true iff there are no outgoing edges currently represented in + * this summary. There may still be outgoing edges, they just haven't + * been added to the summary. + */ + bool empty() const { + return !best1.inited(); + } + + /** + * Return the DescentPriority of the best outgoing edge. + */ + DescentPriority bestPri() const { + assert(!empty()); + return best1.pri; + } + + DescentEdge best1; // best + DescentEdge best2; // 2nd-best + DescentEdge best3; // 3rd-best + DescentEdge best4; // 4th-best + DescentEdge best5; // 5th-best +}; + +template +class DescentAlignmentSink; + +/** + * Encapsulates a descent through a search tree, along a path of matches. + * Descents that are part of the same alignment form a chain. Two aligments + * adjacent in the chain are connected either by an edit, or by a switch in + * direction. Because a descent might have a different direction from the + * DescentRoot it ultimately came from, it has its own 'l2r' field, which might + * differ from the root's. + */ +template +class Descent { + +public: + + Descent() { reset(); } + + /** + * Initialize a new descent branching from the given descent via the given + * edit. Return false if the Descent has no outgoing edges (and can + * therefore have its memory freed), true otherwise. + */ + bool init( + const Read& q, // query + TRootId rid, // root id + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + TReadOff al5pi, // offset from 5' of 1st aligned char + TReadOff al5pf, // offset from 5' of last aligned char + TIndexOffU topf, // SA range top in FW index + TIndexOffU botf, // SA range bottom in FW index + TIndexOffU topb, // SA range top in BW index + TIndexOffU botb, // SA range bottom in BW index + bool l2r, // direction this descent will go in + size_t descid, // my ID + TDescentId parent, // parent ID + TScore pen, // total penalties so far + const Edit& e, // edit for incoming edge + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentRedundancyChecker& re, // redundancy checker + EFactory& df, // Descent factory + EFactory& pf, // DescentPos factory + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm); // per-read metrics + + /** + * Initialize a new descent beginning at the given root. Return false if + * the Descent has no outgoing edges (and can therefore have its memory + * freed), true otherwise. + */ + bool init( + const Read& q, // query + TRootId rid, // root id + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + size_t descid, // id of this Descent + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentRedundancyChecker& re, // redundancy checker + EFactory& df, // Descent factory + EFactory& pf, // DescentPos factory + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm); // per-read metrics + + /** + * Return true iff this Descent has been initialized. + */ + bool inited() const { + return descid_ != std::numeric_limits::max(); + } + + /** + * Reset to uninitialized state. + */ + void reset() { + lastRecalc_ = true; + descid_ = std::numeric_limits::max(); + } + + /** + * Return true iff this Descent is a search root. + */ + bool root() const { + return parent_ == std::numeric_limits::max(); + } + + /** + * Return the edit. + */ + const Edit& edit() const { + return edit_; + } + + /** + * Return id of parent. + */ + TDescentId parent() const { + return parent_; + } + + /** + * Take the best outgoing edge and follow it. + */ + void followBestOutgoing( + const Read& q, // read + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + DescentRedundancyChecker& re, // redundancy checker + EFactory& df, // factory with Descent + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap of descents + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm); // per-read metrics + + /** + * Return true iff no outgoing edges from this descent remain unexplored. + */ + bool empty() const { return lastRecalc_ && out_.empty(); } + +#ifndef NDEBUG + /** + * Return true iff the Descent is internally consistent. + */ + bool repOk(const Read *q) const { + // A non-root can have an uninitialized edit_ if it is from a bounce + //assert( root() || edit_.inited()); + assert(!root() || !edit_.inited()); + assert_eq(botf_ - topf_, botb_ - topb_); + if(q != NULL) { + assert_leq(len_, q->length()); + } + return true; + } +#endif + + size_t al5pi() const { return al5pi_; } + size_t al5pf() const { return al5pf_; } + bool l2r() const { return l2r_; } + + /** + * Print a stacked representation of this descent and all its parents. Assumes that + */ + void print( + std::ostream* os, + const char *prefix, + const Read& q, + size_t trimLf, + size_t trimRg, + bool fw, + const EList& edits, + size_t ei, + size_t en, + BTDnaString& rf) const; + + /** + * Collect all the edits + */ + void collectEdits( + EList& edits, + const Edit *e, + EFactory& df) + { + // Take just the portion of the read that has aligned up until this + // point + size_t nuninited = 0; + size_t ei = edits.size(); + size_t en = 0; + if(e != NULL && e->inited()) { + edits.push_back(*e); + en++; + } + size_t cur = descid_; + while(cur != std::numeric_limits::max()) { + if(!df[cur].edit().inited()) { + nuninited++; + assert_leq(nuninited, 2); + } else { + edits.push_back(df[cur].edit()); + en++; + } + cur = df[cur].parent(); + } + // Sort just the edits we just added + edits.sortPortion(ei, en); + } + +protected: + + /** + * + */ + bool bounce( + const Read& q, // query string + TIndexOffU topf, // SA range top in fw index + TIndexOffU botf, // SA range bottom in fw index + TIndexOffU topb, // SA range top in bw index + TIndexOffU botb, // SA range bottom in bw index + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + DescentRedundancyChecker& re, // redundancy checker + EFactory& df, // factory with Descent + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap of descents + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm); // per-read metrics + + /** + * Given the forward and backward indexes, and given topf/botf/topb/botb, + * get tloc, bloc ready for the next step. + */ + void nextLocsBi( + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + SideLocus& tloc, // top locus + SideLocus& bloc, // bot locus + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb); // bot in BWT' + + /** + * Advance this descent by following read matches as far as possible. + */ + bool followMatches( + const Read& q, // query string + const Scoring& sc, // scoring scheme + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentRedundancyChecker& re, // redundancy checker + EFactory& df, // Descent factory + EFactory& pf, // DescentPos factory + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm, // per-read metrics + bool& branches, // out: true -> there are > 0 ways to branch + bool& hitEnd, // out: true -> hit read end with non-empty range + bool& done, // out: true -> we made a full alignment + TReadOff& off5p_i, // out: initial 5' offset + TIndexOffU& topf_bounce, // out: top of SA range for fw idx for bounce + TIndexOffU& botf_bounce, // out: bot of SA range for fw idx for bounce + TIndexOffU& topb_bounce, // out: top of SA range for bw idx for bounce + TIndexOffU& botb_bounce); // out: bot of SA range for bw idx for bounce + + /** + * Recalculate our summary of the outgoing edges from this descent. When + * deciding what outgoing edges are legal, we abide by constraints. + * Typically, they limit the total of the penalties accumulated so far, as + * a function of distance from the search root. E.g. a constraint might + * disallow any gaps or mismatches within 20 ply of the search root, then + * allow 1 mismatch within 30 ply, then allow up to 1 mismatch or 1 gap + * within 40 ply, etc. + */ + size_t recalcOutgoing( + const Read& q, // query string + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + DescentRedundancyChecker& re, // redundancy checker + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs, // configs + PerReadMetrics& prm); // per-read metrics + + TRootId rid_; // root id + + TReadOff al5pi_; // lo offset from 5' end of aligned read char + TReadOff al5pf_; // hi offset from 5' end of aligned read char + bool l2r_; // left-to-right? + int gapadd_; // net ref characters additional + TReadOff off5p_i_; // offset we started out at for this descent + + TIndexOffU topf_, botf_; // incoming SA range w/r/t forward index + TIndexOffU topb_, botb_; // incoming SA range w/r/t forward index + + size_t descid_; // ID of this descent + TDescentId parent_; // ID of parent descent + TScore pen_; // total penalties accumulated so far + size_t posid_; // ID of 1st elt of the DescentPos factory w/ + // descent pos info for this descent + size_t len_; // length of stretch of matches + DescentOutgoing out_; // summary of outgoing edges + Edit edit_; // edit joining this descent with parent + bool lastRecalc_; // set by recalcOutgoing if out edges empty +}; + +/** + * An alignment result from a Descent. + */ +struct DescentAlignment { + + DescentAlignment() { reset(); } + + /** + * Reset DescentAlignment to be uninitialized. + */ + void reset() { + topf = botf = 0; + pen = 0; + fw = false; + ei = en = 0; + } + + /** + * Initialize this DescentAlignment. + */ + void init( + TScore pen_, + bool fw_, + TIndexOffU topf_, + TIndexOffU botf_, + size_t ei_, + size_t en_) + { + assert_gt(botf_, topf_); + pen = pen_; + fw = fw_; + topf = topf_; + botf = botf_; + ei = ei_; + en = en_; + } + + /** + * Return true iff DescentAlignment is initialized. + */ + bool inited() const { + return botf > topf; + } + + /** + * Return true iff the alignment is perfect (has no edits) + */ + bool perfect() const { + return pen == 0; + } + + /** + * Return the number of elements in this range. + */ + size_t size() const { + return botf - topf; + } + + TScore pen; // score + + bool fw; // forward or revcomp aligned? + + TIndexOffU topf; // top in forward index + TIndexOffU botf; // bot in forward index + + size_t ei; // First edit in DescentAlignmentSink::edits_ involved in aln + size_t en; // # edits in DescentAlignmentSink::edits_ involved in aln +}; + +/** + * A partial alignment result from a Descent where the reference offset has + * been resolved. + */ +struct DescentPartialResolvedAlignment { + + DescentPartialResolvedAlignment() { reset(); } + + /** + * Reset DescentAlignment to be uninitialized. + */ + void reset() { + topf = botf = 0; + pen = 0; + fw = false; + ei = en = 0; + refcoord.reset(); + } + + /** + * Initialize this DescentAlignment. + */ + void init( + TScore pen_, + bool fw_, + TIndexOffU topf_, + TIndexOffU botf_, + size_t ei_, + size_t en_, + const Coord& refcoord_) + { + assert_gt(botf_, topf_); + pen = pen_; + fw = fw_; + topf = topf_; + botf = botf_; + ei = ei_; + en = en_; + refcoord = refcoord_; + } + + /** + * Return true iff DescentAlignment is initialized. + */ + bool inited() const { + return botf > topf; + } + + /** + * Return the number of elements in this range. + */ + size_t size() const { + return botf - topf; + } + + TScore pen; // score + + bool fw; // forward or revcomp aligned? + + TIndexOffU topf; // top in forward index + TIndexOffU botf; // bot in forward index + + size_t ei; // First edit in DescentAlignmentSink::edits_ involved in aln + size_t en; // # edits in DescentAlignmentSink::edits_ involved in aln + + Coord refcoord; // reference coord of leftmost ref char involved +}; + +/** + * Class that accepts alignments found during descent and maintains the state + * required to dispense them to consumers in an appropriate order. + * + * As for order in which they are dispensed, in order to maintain uniform + * distribution over equal-scoring alignments, a good policy may be not to + * dispense alignments at a given score stratum until *all* alignments at that + * stratum have been accumulated (i.e. until our best-first search has moved on + * to a worse stratum). This also has the advantage that, for each alignment, + * we can also report the number of other alignments in that cost stratum. + * + * A lazier alternative is to assume that the order in which alignments in a + * given stratum arrive is already pseudo-random, which frees us from having to + * wait until the entire stratum has been explored. But there is reason to + * think that this order is not truly pseudo-random, since our root placement + * and root priorities will tend to first lead us to alignments with certain + * patterns of edits. + */ +template +class DescentAlignmentSink { + +public: + + /** + * If this is the final descent in a complete end-to-end alignment, report + * the alignment. + */ + bool reportAlignment( + const Read& q, // query string + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + TIndexOffU topf, // SA range top in forward index + TIndexOffU botf, // SA range bottom in forward index + TIndexOffU topb, // SA range top in backward index + TIndexOffU botb, // SA range bottom in backward index + TDescentId id, // id of leaf Descent + TRootId rid, // id of search root + const Edit& e, // final edit, if needed + TScore pen, // total penalty + EFactory >& df, // factory with Descent + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs); // configs + + /** + * Reset to uninitialized state. + */ + void reset() { + edits_.clear(); + als_.clear(); + lhs_.clear(); + rhs_.clear(); + nelt_ = 0; + bestPen_ = worstPen_ = std::numeric_limits::max(); + } + + /** + * Return the total size occupued by the Descent driver and all its + * constituent parts. + */ + size_t totalSizeBytes() const { + return edits_.totalSizeBytes() + + als_.totalSizeBytes() + + lhs_.totalSizeBytes() + + rhs_.totalSizeBytes() + + sizeof(size_t); + } + + /** + * Return the total capacity of the Descent driver and all its constituent + * parts. + */ + size_t totalCapacityBytes() const { + return edits_.totalCapacityBytes() + + als_.totalCapacityBytes() + + lhs_.totalCapacityBytes() + + rhs_.totalCapacityBytes() + + sizeof(size_t); + } + + /** + * Return the number of SA ranges involved in hits. + */ + size_t nrange() const { + return als_.size(); + } + + /** + * Return the number of SA elements involved in hits. + */ + size_t nelt() const { + return nelt_; + } + + /** + * The caller provides 'i', which is an offset of a particular element in + * one of the SA ranges in the current stratum. This function returns, in + * 'al' and 'off', information about the element in terms of the range it's + * part of and its offset into that range. + */ + void elt(size_t i, DescentAlignment& al, size_t& ri, size_t& off) const { + assert_lt(i, nelt()); + for(size_t j = 0; j < als_.size(); j++) { + if(i < als_[j].size()) { + al = als_[j]; + ri = j; + off = i; + return; + } + i -= als_[j].size(); + } + assert(false); + } + + /** + * Get a particular alignment. + */ + const DescentAlignment& operator[](size_t i) const { + return als_[i]; + } + + /** + * Return true iff (a) we found an alignment since the sink was initialized + * or since the last time advanceStratum() was called, and (b) the penalty + * associated with the current-best task on the heap ('best') is worse + * (higher) than the penalty associated with the alignments found most + * recently (worstPen_). + */ + bool stratumDone(TAlScore bestPen) const { + if(nelt_ > 0 && bestPen > worstPen_) { + return true; + } + return false; + } + + /** + * The alignment consumer calls this to indicate that they are done with + * all the alignments in the current best non-empty stratum. We can + * therefore mark all those alignments as "reported" and start collecting + * results for the next stratum. + */ + void advanceStratum() { + assert_gt(nelt_, 0); + edits_.clear(); + als_.clear(); + // Don't reset lhs_ or rhs_ + nelt_ = 0; + bestPen_ = worstPen_ = std::numeric_limits::max(); + } + +#ifndef NDEBUG + /** + * Check that alignment sink is internally consistent. + */ + bool repOk() const { + assert_geq(nelt_, als_.size()); + for(size_t i = 1; i < als_.size(); i++) { + assert_geq(als_[i].pen, als_[i-1].pen); + } + assert(bestPen_ == std::numeric_limits::max() || worstPen_ >= bestPen_); + return true; + } +#endif + + TAlScore bestPenalty() const { return bestPen_; } + TAlScore worstPenalty() const { return worstPen_; } + + size_t editsSize() const { return edits_.size(); } + size_t alsSize() const { return als_.size(); } + size_t lhsSize() const { return lhs_.size(); } + size_t rhsSize() const { return rhs_.size(); } + + const EList& edits() const { return edits_; } + +protected: + + EList edits_; + EList als_; + ESet > lhs_; + ESet > rhs_; + size_t nelt_; + TAlScore bestPen_; // best (smallest) penalty among as-yet-unreported alns + TAlScore worstPen_; // worst (greatest) penalty among as-yet-unreported alns +#ifndef NDEBUG + BTDnaString tmprfdnastr_; +#endif + +}; + +/** + * Class that aggregates partial alignments taken from a snapshot of the + * DescentDriver heap. + */ +class DescentPartialResolvedAlignmentSink { + +public: + + /** + * Reset to uninitialized state. + */ + void reset() { + edits_.clear(); + als_.clear(); + nelt_ = 0; + bestPen_ = worstPen_ = std::numeric_limits::max(); + } + + /** + * Return the total size occupued by the Descent driver and all its + * constituent parts. + */ + size_t totalSizeBytes() const { + return edits_.totalSizeBytes() + + als_.totalSizeBytes() + + sizeof(size_t); + } + + /** + * Return the total capacity of the Descent driver and all its constituent + * parts. + */ + size_t totalCapacityBytes() const { + return edits_.totalCapacityBytes() + + als_.totalCapacityBytes() + + sizeof(size_t); + } + + /** + * Return the number of SA ranges involved in hits. + */ + size_t nrange() const { + return als_.size(); + } + + /** + * Return the number of SA elements involved in hits. + */ + size_t nelt() const { + return nelt_; + } + + /** + * The caller provides 'i', which is an offset of a particular element in + * one of the SA ranges in the current stratum. This function returns, in + * 'al' and 'off', information about the element in terms of the range it's + * part of and its offset into that range. + */ + void elt(size_t i, DescentPartialResolvedAlignment& al, size_t& ri, size_t& off) const { + assert_lt(i, nelt()); + for(size_t j = 0; j < als_.size(); j++) { + if(i < als_[j].size()) { + al = als_[j]; + ri = j; + off = i; + return; + } + i -= als_[j].size(); + } + assert(false); + } + + /** + * Get a particular alignment. + */ + const DescentPartialResolvedAlignment& operator[](size_t i) const { + return als_[i]; + } + + /** + * Return true iff (a) we found an alignment since the sink was initialized + * or since the last time advanceStratum() was called, and (b) the penalty + * associated with the current-best task on the heap ('best') is worse + * (higher) than the penalty associated with the alignments found most + * recently (worstPen_). + */ + bool stratumDone(TAlScore bestPen) const { + if(nelt_ > 0 && bestPen > worstPen_) { + return true; + } + return false; + } + + /** + * The alignment consumer calls this to indicate that they are done with + * all the alignments in the current best non-empty stratum. We can + * therefore mark all those alignments as "reported" and start collecting + * results for the next stratum. + */ + void advanceStratum() { + assert_gt(nelt_, 0); + edits_.clear(); + als_.clear(); + nelt_ = 0; + bestPen_ = worstPen_ = std::numeric_limits::max(); + } + +#ifndef NDEBUG + /** + * Check that partial alignment sink is internally consistent. + */ + bool repOk() const { + assert_geq(nelt_, als_.size()); + //for(size_t i = 1; i < als_.size(); i++) { + // assert_geq(als_[i].pen, als_[i-1].pen); + //} + assert(bestPen_ == std::numeric_limits::max() || worstPen_ >= bestPen_); + return true; + } +#endif + + TAlScore bestPenalty() const { return bestPen_; } + TAlScore worstPenalty() const { return worstPen_; } + + size_t editsSize() const { return edits_.size(); } + size_t alsSize() const { return als_.size(); } + + const EList& edits() const { return edits_; } + +protected: + + EList edits_; + EList als_; + size_t nelt_; + TAlScore bestPen_; // best (smallest) penalty among as-yet-unreported alns + TAlScore worstPen_; // worst (greatest) penalty among as-yet-unreported alns +}; + +/** + * Abstract parent for classes that select descent roots and descent + * configurations given information about the read. + */ +class DescentRootSelector { + +public: + + virtual ~DescentRootSelector() { } + + virtual void select( + const Read& q, // read that we're selecting roots for + const Read* qo, // opposite mate, if applicable + bool nofw, // don't add roots for fw read + bool norc, // don't add roots for rc read + EList& confs, // put DescentConfigs here + EList& roots) = 0; // put DescentRoot here +}; + +/** + * Encapsulates a set of conditions governing when the DescentDriver should + * stop. + */ +struct DescentStoppingConditions { + + DescentStoppingConditions() { reset(); } + + DescentStoppingConditions( + size_t totsz_, + size_t nfound_, + bool stra_, + size_t nbwop_) + { + init(totsz_, nfound_, stra_, nbwop_); + } + + /** + * Reset to uninitialized state. + */ + void reset() { + totsz = nfound = nbwop = std::numeric_limits::max(); + stra = false; + assert(!inited()); + } + + /** + * Initialize this DescentStoppingConditions. + */ + void init( + size_t totsz_, + size_t nfound_, + bool stra_, + size_t nbwop_) + { + totsz = totsz_; + nfound = nfound_; + stra = stra_; + nbwop = nbwop_; + assert(inited()); + } + + /** + * Return true iff this instance is initialized. + */ + bool inited() const { + return totsz != std::numeric_limits::max(); + } + + size_t totsz; // total size of all the expandable data structures in bytes + size_t nfound; // # alignments found + bool stra; // stop after each non-empty stratum + size_t nbwop; // # Burrows-Wheeler (rank) operations performed +}; + +enum { + DESCENT_DRIVER_ALN = 1, + DESCENT_DRIVER_STRATA = 2, + DESCENT_DRIVER_MEM = 4, + DESCENT_DRIVER_BWOPS = 8, + DESCENT_DRIVER_DONE = 16 +}; + +/** + * Class responsible for advancing all the descents. The initial descents may + * emanate from several different locations in the read. Note that descents + * may become redundant with each other, and should then be eliminated. + */ +template +class DescentDriver { +public: + + DescentDriver(bool veryVerbose) : + veryVerbose_(veryVerbose) + { + reset(); + } + + /** + * Initialize driver with respect to a new read. If a DescentRootSelector + * is specified, then it is used to obtain roots as well. + */ + void initRead( + const Read& q, + bool nofw, + bool norc, + TAlScore minsc, + TAlScore maxpen, + const Read* qu = NULL, + DescentRootSelector *sel = NULL) + { + reset(); + q_ = q; + minsc_ = minsc; + maxpen_ = maxpen; + if(sel != NULL) { + sel->select(q_, qu, nofw, norc, confs_, roots_); + } + re_.init(q.length()); + } + + /** + * Add a new search root, which might (a) prefer to move in a left-to-right + * direction, and might (b) be with respect to the read or its reverse + * complement. + */ + void addRoot( + const DescentConfig& conf, + TReadOff off, + bool l2r, + bool fw, + float pri) + { + confs_.push_back(conf); + assert_lt(off, q_.length()); + if(l2r && off == q_.length()-1) { + l2r = !l2r; + } else if(!l2r && off == 0) { + l2r = !l2r; + } + roots_.push_back(DescentRoot(off, l2r, fw, q_.length(), pri)); + } + + /** + * Clear out the DescentRoots currently configured. + */ + void clearRoots() { + confs_.clear(); + roots_.clear(); + } + + /** + * Clear the Descent driver so that we're ready to re-start seed alignment + * for the current read. + */ + void resetRead() { + df_.clear(); // clear Descents + assert_leq(df_.totalSizeBytes(), 100); + pf_.clear(); // clear DescentPoss + assert_leq(pf_.totalSizeBytes(), 100); + heap_.clear(); // clear Heap + assert_leq(heap_.totalSizeBytes(), 100); + roots_.clear(); // clear roots + assert_leq(roots_.totalSizeBytes(), 100); + confs_.clear(); // clear confs + assert_leq(confs_.totalSizeBytes(), 100); + alsink_.reset(); // clear alignment sink + assert_leq(alsink_.totalSizeBytes(), 100); + re_.reset(); + assert_leq(re_.totalSizeBytes(), 100); + rootsInited_ = 0; // haven't yet created initial descents + curPen_ = 0; // + } + + /** + * Clear the Descent driver so that we're ready to re-start seed alignment + * for the current read. + */ + void reset() { + resetRead(); + } + + /** + * Perform seed alignment. + */ + void go( + const Scoring& sc, // scoring scheme + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentMetrics& met, // metrics + PerReadMetrics& prm); // per-read metrics + + /** + * Perform seed alignment until some stopping condition is satisfied. + */ + int advance( + const DescentStoppingConditions& stopc, // stopping conditions + const Scoring& sc, // scoring scheme + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentMetrics& met, // metrics + PerReadMetrics& prm); // per-read metrics + +#ifndef NDEBUG + /** + * Return true iff this DescentDriver is well formed. Throw an assertion + * otherwise. + */ + bool repOk() const { + return true; + } +#endif + + /** + * Return the number of end-to-end alignments reported. + */ + size_t numAlignments() const { + return alsink_.nelt(); + } + + /** + * Return the associated DescentAlignmentSink object. + */ + const DescentAlignmentSink& sink() const { + return alsink_; + } + + /** + * Return the associated DescentAlignmentSink object. + */ + DescentAlignmentSink& sink() { + return alsink_; + } + + /** + * Return the total size occupued by the Descent driver and all its + * constituent parts. + */ + size_t totalSizeBytes() const { + return df_.totalSizeBytes() + + pf_.totalSizeBytes() + + heap_.totalSizeBytes() + + roots_.totalSizeBytes() + + confs_.totalSizeBytes() + + alsink_.totalSizeBytes() + + re_.totalSizeBytes(); + } + + /** + * Return the total capacity of the Descent driver and all its constituent + * parts. + */ + size_t totalCapacityBytes() const { + return df_.totalCapacityBytes() + + pf_.totalCapacityBytes() + + heap_.totalCapacityBytes() + + roots_.totalCapacityBytes() + + confs_.totalCapacityBytes() + + alsink_.totalCapacityBytes() + + re_.totalCapacityBytes(); + } + + /** + * Return a const ref to the query. + */ + const Read& query() const { + return q_; + } + + /** + * Return the minimum score that must be achieved by an alignment in order + * for it to be considered "valid". + */ + TAlScore minScore() const { + return minsc_; + } + +protected: + + Read q_; // query nucleotide and quality strings + TAlScore minsc_; // minimum score + TAlScore maxpen_; // maximum penalty + EFactory > df_; // factory holding all the Descents, which + // must be referred to by ID + EFactory pf_; // factory holding all the DescentPoss, which + // must be referred to by ID + EList roots_; // search roots + EList confs_; // configuration params for each root + size_t rootsInited_; // # initial Descents already created + EHeap heap_; // priority queue of Descents + DescentAlignmentSink alsink_; // alignment sink + DescentRedundancyChecker re_; // redundancy checker + TAlScore curPen_; // current penalty + bool veryVerbose_; // print lots of partial alignments + + EList tmpedit_; + BTDnaString tmprfdnastr_; +}; + +/** + * Selects alignments to report from a complete non-empty stratum of + * alignments stored in the DescentAlignmentSink. + */ +template +class DescentAlignmentSelector { + +public: + + DescentAlignmentSelector() : gwstate_(GW_CAT) { reset(); } + + /** + * Initialize a new selector w/r/t a DescentAlignmentSink holding a + * non-empty alignment stratum. + */ + void init( + const Read& q, + const DescentAlignmentSink& sink, + const GFM& gfmFw, // forward Bowtie index for walking left + const BitPairReference& ref, // bitpair-encoded reference + RandomSource& rnd, // pseudo-random generator for sampling rows + WalkMetrics& met) + { + // We're going to sample from space of *alignments*, not ranges. So + // when we extract a sample, we'll have to do a little extra work to + // convert it to a coordinate. + rnd_.init( + sink.nelt(), // # elements to choose from + true); // without replacement + offs_.resize(sink.nelt()); + offs_.fill(std::numeric_limits::max()); + sas_.resize(sink.nrange()); + gws_.resize(sink.nrange()); + size_t ei = 0; + for(size_t i = 0; i < sas_.size(); i++) { + size_t en = sink[i].botf - sink[i].topf; + sas_[i].init(sink[i].topf, q.length(), EListSlice(offs_, ei, en)); + gws_[i].init(gfmFw, ref, sas_[i], rnd, met); + ei += en; + } + } + + /** + * Reset the selector. + */ + void reset() { + rnd_.reset(); + } + + /** + * Return true iff the selector is currently initialized. + */ + bool inited() const { + return rnd_.size() > 0; + } + + /** + * Get next alignment and convert it to an AlnRes. + */ + bool next( + const DescentDriver& dr, + const GFM& gfmFw, // forward Bowtie index for walking left + const BitPairReference& ref, // bitpair-encoded reference + RandomSource& rnd, + AlnRes& rs, + WalkMetrics& met, + PerReadMetrics& prm) + { + // Sample one alignment randomly from pool of remaining alignments + size_t ri = (size_t)rnd_.next(rnd); + size_t off = 0; + DescentAlignment al; + size_t rangei = 0; + // Convert random alignment index into a coordinate + dr.sink().elt(ri, al, rangei, off); + assert_lt(off, al.size()); + Coord refcoord; + WalkResult wr; + TIndexOffU tidx = 0, toff = 0, tlen = 0; + gws_[rangei].advanceElement( + (TIndexOffU)off, + gfmFw, // forward Bowtie index for walking left + ref, // bitpair-encoded reference + sas_[rangei], // SA range with offsets + gwstate_, // GroupWalk state; scratch space + wr, // put the result here + met, // metrics + prm); // per-read metrics + assert_neq(OFF_MASK, wr.toff); + bool straddled = false; + gfmFw.joinedToTextOff( + wr.elt.len, + wr.toff, + tidx, + toff, + tlen, + true, // reject straddlers? + straddled); // straddled? + if(tidx == OFF_MASK) { + // The seed hit straddled a reference boundary so the seed + // hit isn't valid + return false; + } + // Coordinate of the seed hit w/r/t the pasted reference string + refcoord.init(tidx, (int64_t)toff, dr.sink()[rangei].fw); + const EList& edits = dr.sink().edits(); + size_t ns = 0, ngap = 0, nrefn = 0; + for(size_t i = al.ei; i < al.ei + al.en; i++) { + if(edits[i].qchr == 'N' || edits[i].chr == 'N') ns++; + if(edits[i].chr == 'N') nrefn++; + if(edits[i].isGap()) ngap++; + } + AlnScore asc( + -dr.sink().bestPenalty(), // numeric score + ns, // # Ns + ngap); // # gaps + rs.init( + dr.query().length(), // # chars after hard trimming + asc, // alignment score + &dr.sink().edits(), // nucleotide edits array + al.ei, // nucleotide edits first pos + al.en, // nucleotide edits last pos + NULL, // ambig base array + 0, // ambig base first pos + 0, // ambig base last pos + refcoord, // coord of leftmost aligned char in ref + tlen, // length of reference aligned to + -1, // # seed mms allowed + -1, // seed length + -1, // seed interval + dr.minScore(), // minimum score for valid alignment + -1, // nuc5p (for colorspace) + -1, // nuc3p (for colorspace) + false, // soft pre-trimming? + 0, // 5p pre-trimming + 0, // 3p pre-trimming + false, // soft trimming? + 0, // 5p trimming + 0); // 3p trimming + rs.setRefNs(nrefn); + return true; + } + + /** + * Return true iff all elements have been reported. + */ + bool done() const { + return rnd_.done(); + } + + /** + * Return the total size occupued by the Descent driver and all its + * constituent parts. + */ + size_t totalSizeBytes() const { + return rnd_.totalSizeBytes() + + offs_.totalSizeBytes() + + sas_.totalSizeBytes() + + gws_.totalSizeBytes(); + } + + /** + * Return the total capacity of the Descent driver and all its constituent + * parts. + */ + size_t totalCapacityBytes() const { + return rnd_.totalCapacityBytes() + + offs_.totalCapacityBytes() + + sas_.totalCapacityBytes() + + gws_.totalCapacityBytes(); + } + +protected: + + Random1toN rnd_; + EList offs_; + EList, index_t> > sas_; + EList, 16> > gws_; + GroupWalkState gwstate_; +}; + +/** + * Selects and prioritizes partial alignments from the heap of the + * DescentDriver. We assume that the heap is no longer changing (i.e. that the + * DescentDriver is done). Usually, the user will then attempt to extend the + * partial alignments into full alignments. This can happen incrementally; + * that is, the user might ask for the partial alignments one "batch" at a + * time, and the selector will only do as much work is necessary to supply each + * requesteded batch. + * + * The actual work done here includes: (a) scanning the heap for high-priority + * partial alignments, (b) setting up the rnd_, offs_, sas_, gws_, and gwstate_ + * fields and resolving offsets of partial alignments, (c) packaging and + * delivering batches of results to the caller. + * + * How to prioritize partial alignments? One idea is to use the same + * penalty-based prioritization used in the heap. This has pros: (a) maintains + * the guarantee that we're visiting alignments in best-to-worst order in + * end-to-end alignment mode, (b) the heap is already prioritized this way, so + * it's easier for us to compile high-priority partial alignments. But the con + * is that it doesn't take depth into account, which could mean that we're + * extending a lot of very short partial alignments first. + * + * A problem we should keep in mind is that some + */ +template +class DescentPartialAlignmentSelector { + +public: + + DescentPartialAlignmentSelector() : gwstate_(GW_CAT) { reset(); } + + /** + * Initialize a new selector w/r/t a read, index and heap of partial + * alignments. + */ + void init( + const Read& q, // read + const EHeap& heap, // the heap w/ the partial alns + TAlScore depthBonus, // use depth when prioritizing + size_t nbatch, // # of alignments in a batch + const GFM& gfmFw, // forward Bowtie index for walk-left + const BitPairReference& ref, // bitpair-encoded reference + RandomSource& rnd, // pseudo-randoms for sampling rows + WalkMetrics& met) // metrics re: offset resolution + { + // Make our internal heap + if(depthBonus > 0) { + heap_.clear(); + for(size_t i = 0; i < heap.size(); i++) { + TDescentPair p = heap[i]; + p.first.pen += depthBonus * p.first.depth; + heap_.insert(p); + } + } else { + heap_ = heap; + } +#if 0 + // We're going to sample from space of *alignments*, not ranges. So + // when we extract a sample, we'll have to do a little extra work to + // convert it to a coordinate. + rnd_.init( + sink.nelt(), // # elements to choose from + true); // without replacement + offs_.resize(sink.nelt()); + offs_.fill(std::numeric_limits::max()); + sas_.resize(sink.nrange()); + gws_.resize(sink.nrange()); + size_t ei = 0; + for(size_t i = 0; i < sas_.size(); i++) { + size_t en = sink[i].botf - sink[i].topf; + sas_[i].init(sink[i].topf, q.length(), EListSlice(offs_, ei, en)); + gws_[i].init(gfmFw, ref, sas_[i], rnd, met); + ei += en; + } +#endif + } + + /** + * + */ + void compileBatch() { + } + + /** + * Reset the selector. + */ + void reset() { + heap_.clear(); + } + + /** + * Return true iff the selector is currently initialized. + */ + bool inited() const { + return !heap_.empty(); + } + + /** + * Get next alignment and convert it to an AlnRes. + */ + bool next( + const DescentDriver& dr, + const GFM& gfmFw, // forward Bowtie index for walking left + const BitPairReference& ref, // bitpair-encoded reference + RandomSource& rnd, + AlnRes& rs, + WalkMetrics& met, + PerReadMetrics& prm) + { + // Sample one alignment randomly from pool of remaining alignments + size_t ri = (size_t)rnd_.next(rnd); + size_t off = 0; + DescentAlignment al; + size_t rangei = 0; + // Convert random alignment index into a coordinate + dr.sink().elt(ri, al, rangei, off); + assert_lt(off, al.size()); + Coord refcoord; + WalkResult wr; + uint32_t tidx = 0, toff = 0, tlen = 0; + gws_[rangei].advanceElement( + (uint32_t)off, + gfmFw, // forward Bowtie index for walking left + ref, // bitpair-encoded reference + sas_[rangei], // SA range with offsets + gwstate_, // GroupWalk state; scratch space + wr, // put the result here + met, // metrics + prm); // per-read metrics + assert_neq(0xffffffff, wr.toff); + bool straddled = false; + gfmFw.joinedToTextOff( + wr.elt.len, + wr.toff, + tidx, + toff, + tlen, + true, // reject straddlers? + straddled); // straddled? + if(tidx == 0xffffffff) { + // The seed hit straddled a reference boundary so the seed + // hit isn't valid + return false; + } + // Coordinate of the seed hit w/r/t the pasted reference string + refcoord.init(tidx, (int64_t)toff, dr.sink()[rangei].fw); + const EList& edits = dr.sink().edits(); + size_t ns = 0, ngap = 0, nrefn = 0; + for(size_t i = al.ei; i < al.ei + al.en; i++) { + if(edits[i].qchr == 'N' || edits[i].chr == 'N') ns++; + if(edits[i].chr == 'N') nrefn++; + if(edits[i].isGap()) ngap++; + } + return true; + } + + /** + * Return true iff all elements have been reported. + */ + bool done() const { + return rnd_.done(); + } + + /** + * Return the total size occupued by the Descent driver and all its + * constituent parts. + */ + size_t totalSizeBytes() const { + return heap_.totalSizeBytes() + + rnd_.totalSizeBytes() + + offs_.totalSizeBytes() + + sas_.totalSizeBytes() + + gws_.totalSizeBytes(); + } + + /** + * Return the total capacity of the Descent driver and all its constituent + * parts. + */ + size_t totalCapacityBytes() const { + return heap_.totalCapacityBytes() + + rnd_.totalCapacityBytes() + + offs_.totalCapacityBytes() + + sas_.totalCapacityBytes() + + gws_.totalCapacityBytes(); + } + +protected: + + // This class's working heap. This might simply be a copy of the original + // heap, or it might be re-prioritized in some way. + EHeap heap_; + + Random1toN rnd_; + EList offs_; + EList, index_t> > sas_; + EList, 16> > gws_; + GroupWalkState gwstate_; +}; + +/** + * Drive the process of descending from all search roots. + */ +template +void DescentDriver::go( + const Scoring& sc, // scoring scheme + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics +{ + assert(q_.repOk()); + // Convert DescentRoots to the initial Descents + for(size_t i = 0; i < roots_.size(); i++) { + size_t dfsz = df_.size(); + size_t pfsz = pf_.size(); + TDescentId id = df_.alloc(); + Edit e_null; + assert(!e_null.inited()); + bool succ = df_[id].init( + q_, // read + i, // root and conf id + sc, // scoring scheme + minsc_, // minimum score + maxpen_, // maximum penalty + id, // new Descent's id + gfmFw, // forward index + gfmBw, // mirror index + re_, // redundancy checker + df_, // Descent factory + pf_, // DescentPos factory + roots_, // DescentRoots + confs_, // DescentConfs + heap_, // heap + alsink_, // alignment sink + met, // metrics + prm); // per-read metrics + if(veryVerbose_) { + bool fw = roots_[i].fw; + tmpedit_.clear(); + df_[id].print( + &cerr, + "", + q_, + 0, + 0, + fw, + tmpedit_, + 0, + tmpedit_.size(), + tmprfdnastr_); + } + if(!succ) { + // Reclaim memory we had used for this descent and its DescentPos info + df_.resize(dfsz); + pf_.resize(pfsz); + } + } + // Advance until some stopping condition + bool stop = heap_.empty(); + while(!stop) { + // Pop off the highest-priority descent. Note that some outgoing edges + // might have since been explored, which could reduce the priority of + // the descent once we . + TDescentPair p = heap_.pop(); + df_.alloc(); df_.pop(); + df_[p.second].followBestOutgoing( + q_, // read + gfmFw, // index over text + gfmBw, // index over reverse text + sc, // scoring scheme + minsc_, // minimum score + maxpen_, // maximum penalty + re_, // redundancy checker + df_, // Descent factory + pf_, // DescentPos factory + roots_, // + confs_, // + heap_, // priority queue for Descents + alsink_, // alignment sink + met, // metrics + prm); // per-read metrics + stop = heap_.empty(); + } +} + +/** + * Perform seed alignment until some stopping condition is satisfied. + */ +template +int DescentDriver::advance( + const DescentStoppingConditions& stopc, // stopping conditions + const Scoring& sc, // scoring scheme + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics +{ + size_t nbwop_i = met.bwops; + while(rootsInited_ < roots_.size()) { + size_t dfsz = df_.size(); + size_t pfsz = pf_.size(); + TDescentId id = df_.alloc(); + Edit e_null; + assert(!e_null.inited()); + bool succ = df_[id].init( + q_, // query + rootsInited_, // root and conf id + sc, // scoring scheme + minsc_, // minimum score + maxpen_, // maximum penalty + id, // new Descent's id + gfmFw, // forward index + gfmBw, // mirror index + re_, // redundancy checker + df_, // Descent factory + pf_, // DescentPos factory + roots_, // DescentRoots + confs_, // DescentConfs + heap_, // heap + alsink_, // alignment sink + met, // metrics + prm); // per-read metrics + if(!succ) { + // Reclaim memory we had used for this descent and its DescentPos info + df_.resize(dfsz); + pf_.resize(pfsz); + } + rootsInited_++; + TAlScore best = std::numeric_limits::max(); + if(!heap_.empty()) { + best = heap_.top().first.pen; + } + if(stopc.nfound > 0 && alsink_.nelt() > stopc.nfound) { + return DESCENT_DRIVER_ALN; + } + if(alsink_.stratumDone(best)) { + return DESCENT_DRIVER_STRATA; + } + if(stopc.nbwop > 0 && (met.bwops - nbwop_i) > stopc.nbwop) { + return DESCENT_DRIVER_BWOPS; + } + if(stopc.totsz > 0 && totalSizeBytes() > stopc.totsz) { + return DESCENT_DRIVER_MEM; + } + } + // Advance until some stopping condition + bool stop = heap_.empty(); + while(!stop) { + // Pop off the highest-priority descent. Note that some outgoing edges + // might have since been explored, which could reduce the priority of + // the descent once we . + TDescentPair p = heap_.pop(); + df_.alloc(); df_.pop(); + df_[p.second].followBestOutgoing( + q_, + gfmFw, + gfmBw, + sc, + minsc_, // minimum score + maxpen_, // maximum penalty + re_, // redundancy checker + df_, // Descent factory + pf_, // DescentPos factory + roots_, + confs_, + heap_, + alsink_, + met, + prm); // per-read metrics + TAlScore best = std::numeric_limits::max(); + if(!heap_.empty()) { + best = heap_.top().first.pen; + } + if(stopc.nfound > 0 && alsink_.nelt() > stopc.nfound) { + return DESCENT_DRIVER_ALN; + } + if(alsink_.stratumDone(best)) { + return DESCENT_DRIVER_STRATA; + } + if(stopc.nbwop > 0 && (met.bwops - nbwop_i) > stopc.nbwop) { + return DESCENT_DRIVER_BWOPS; + } + if(stopc.totsz > 0 && totalSizeBytes() > stopc.totsz) { + return DESCENT_DRIVER_MEM; + } + stop = heap_.empty(); + } + return DESCENT_DRIVER_DONE; +} + +/** + * If this is the final descent in a complete end-to-end alignment, report + * the alignment. + */ +template +bool DescentAlignmentSink::reportAlignment( + const Read& q, // query string + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + TIndexOffU topf, // SA range top in forward index + TIndexOffU botf, // SA range bottom in forward index + TIndexOffU topb, // SA range top in backward index + TIndexOffU botb, // SA range bottom in backward index + TDescentId id, // id of leaf Descent + TRootId rid, // id of search root + const Edit& e, // final edit, if needed + TScore pen, // total penalty + EFactory >& df, // factory with Descent + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs) // configs +{ + TDescentId cur = id; + ASSERT_ONLY(const Descent& desc = df[id]); + const bool fw = rs[rid].fw; + ASSERT_ONLY(size_t len = q.length()); + assert(q.repOk()); + assert_lt(desc.al5pf(), len); + // Adjust al5pi and al5pf to take the final edit into account (if + // there is one) + // Check if this is redundant with a previous reported alignment + Triple lhs(topf, botf, 0); + Triple rhs(topb, botb, q.length()-1); + if(!lhs_.insert(lhs)) { + rhs_.insert(rhs); + return false; // Already there + } + if(!rhs_.insert(rhs)) { + return false; // Already there + } + size_t ei = edits_.size(); + df[cur].collectEdits(edits_, &e, df); + size_t en = edits_.size() - ei; +#ifndef NDEBUG + { + for(size_t i = 1; i < en; i++) { + assert_geq(edits_[ei+i].pos, edits_[ei+i-1].pos); + } + // Now figure out how much we refrained from aligning on either + // side. + size_t trimLf = 0; + size_t trimRg = 0; + BTDnaString& rf = tmprfdnastr_; + rf.clear(); + if(!fw) { + // Edit offsets are w/r/t 5' end, but desc.print wants them w/r/t + // the *left* end of the read sequence that aligned + Edit::invertPoss(edits_, len, ei, en, true); + } + desc.print(NULL, "", q, trimLf, trimRg, fw, edits_, ei, en, rf); + if(!fw) { + // Invert them back to how they were before + Edit::invertPoss(edits_, len, ei, en, true); + } + ASSERT_ONLY(TIndexOffU toptmp = 0); + ASSERT_ONLY(TIndexOffU bottmp = 0); + // Check that the edited string occurs in the reference + if(!gfmFw.contains(rf, &toptmp, &bottmp)) { + std::cerr << rf << std::endl; + assert(false); + } + } +#endif + als_.expand(); + als_.back().init(pen, fw, topf, botf, ei, en); + nelt_ += (botf - topf); + if(bestPen_ == std::numeric_limits::max() || pen < bestPen_) { + bestPen_ = pen; + } + if(worstPen_ == std::numeric_limits::max() || pen > worstPen_) { + worstPen_ = pen; + } + return true; +} + +/** + * Initialize a new descent branching from the given descent via the given + * edit. Return false if the Descent has no outgoing edges (and can + * therefore have its memory freed), true otherwise. + */ +template +bool Descent::init( + const Read& q, // query + TRootId rid, // root id + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + TReadOff al5pi, // offset from 5' of 1st aligned char + TReadOff al5pf, // offset from 5' of last aligned char + TIndexOffU topf, // SA range top in FW index + TIndexOffU botf, // SA range bottom in FW index + TIndexOffU topb, // SA range top in BW index + TIndexOffU botb, // SA range bottom in BW index + bool l2r, // direction this descent will go in + size_t descid, // my ID + TDescentId parent, // parent ID + TScore pen, // total penalties so far + const Edit& e, // edit for incoming edge + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentRedundancyChecker& re, // redundancy checker + EFactory& df, // Descent factory + EFactory& pf, // DescentPos factory + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics +{ + assert(q.repOk()); + rid_ = rid; + al5pi_ = al5pi; + al5pf_ = al5pf; + l2r_ = l2r; + topf_ = topf; + botf_ = botf; + topb_ = topb; + botb_ = botb; + descid_ = descid; + parent_ = parent; + pen_ = pen; + posid_ = std::numeric_limits::max(); + len_ = 0; + out_.clear(); + edit_ = e; + lastRecalc_ = true; + gapadd_ = df[parent].gapadd_; + if(e.inited()) { + if(e.isReadGap()) { + gapadd_++; + } else if(e.isRefGap()) { + gapadd_--; + } + } + bool branches = false, hitEnd = false, done = false; + TIndexOffU topf_new = 0, botf_new = 0, topb_new = 0, botb_new = 0; + off5p_i_ = 0; +#ifndef NDEBUG + size_t depth = al5pf_ - al5pi_ + 1; + TAlScore maxpend = cs[rid_].cons.get(depth, q.length(), maxpen); + assert_geq(maxpend, pen_); // can't have already exceeded max penalty +#endif + bool matchSucc = followMatches( + q, + sc, + gfmFw, + gfmBw, + re, + df, + pf, + rs, + cs, + heap, + alsink, + met, + prm, + branches, + hitEnd, + done, + off5p_i_, + topf_new, + botf_new, + topb_new, + botb_new); + bool bounceSucc = false; + if(matchSucc && hitEnd && !done) { + assert(topf_new > 0 || botf_new > 0); + bounceSucc = bounce( + q, + topf_new, + botf_new, + topb_new, + botb_new, + gfmFw, + gfmBw, + sc, + minsc, // minimum score + maxpen, // maximum penalty + re, + df, + pf, + rs, + cs, + heap, + alsink, + met, // descent metrics + prm); // per-read metrics + } + if(matchSucc) { + // Calculate info about outgoing edges + recalcOutgoing(q, sc, minsc, maxpen, re, pf, rs, cs, prm); + if(!empty()) { + heap.insert(make_pair(out_.bestPri(), descid)); // Add to heap + } + } + return !empty() || bounceSucc; +} + +/** + * Initialize a new descent beginning at the given root. Return false if + * the Descent has no outgoing edges (and can therefore have its memory + * freed), true otherwise. + */ +template +bool Descent::init( + const Read& q, // query + TRootId rid, // root id + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + size_t descid, // id of this Descent + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentRedundancyChecker& re, // redundancy checker + EFactory >& df, // Descent factory + EFactory& pf, // DescentPos factory + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics +{ + rid_ = rid; + al5pi_ = rs[rid].off5p; + al5pf_ = rs[rid].off5p; + assert_lt(al5pi_, q.length()); + assert_lt(al5pf_, q.length()); + l2r_ = rs[rid].l2r; + topf_ = botf_ = topb_ = botb_ = 0; + descid_ = descid; + parent_ = std::numeric_limits::max(); + pen_ = 0; + posid_ = std::numeric_limits::max(); + len_ = 0; + out_.clear(); + edit_.reset(); + lastRecalc_ = true; + gapadd_ = 0; + bool branches = false, hitEnd = false, done = false; + TIndexOffU topf_new = 0, botf_new = 0, topb_new = 0, botb_new = 0; + off5p_i_ = 0; + bool matchSucc = followMatches( + q, + sc, + gfmFw, + gfmBw, + re, + df, + pf, + rs, + cs, + heap, + alsink, + met, + prm, + branches, + hitEnd, + done, + off5p_i_, + topf_new, + botf_new, + topb_new, + botb_new); + bool bounceSucc = false; + if(matchSucc && hitEnd && !done) { + assert(topf_new > 0 || botf_new > 0); + bounceSucc = bounce( + q, + topf_new, + botf_new, + topb_new, + botb_new, + gfmFw, + gfmBw, + sc, + minsc, // minimum score + maxpen, // maximum penalty + re, + df, + pf, + rs, + cs, + heap, + alsink, + met, // descent metrics + prm); // per-read metrics + } + // Calculate info about outgoing edges + assert(empty()); + if(matchSucc) { + recalcOutgoing(q, sc, minsc, maxpen, re, pf, rs, cs, prm); + if(!empty()) { + heap.insert(make_pair(out_.bestPri(), descid)); // Add to heap + } + } + return !empty() || bounceSucc; +} + +/** + * Recalculate our summary of the outgoing edges from this descent. When + * deciding what outgoing edges are legal, we abide by constraints. + * Typically, they limit the total of the penalties accumulated so far, as + * a function of distance from the search root. E.g. a constraint might + * disallow any gaps or mismatches within 20 ply of the search root, then + * allow 1 mismatch within 30 ply, then allow up to 1 mismatch or 1 gap + * within 40 ply, etc. + * + * Return the total number of valid outgoing edges found. + * + * TODO: Eliminate outgoing gap edges that are redundant with others owing to + * the DNA sequence and the fact that we don't care to distinguish among + * "equivalent" homopolymer extensinos and retractions. + */ +template +size_t Descent::recalcOutgoing( + const Read& q, // query string + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + DescentRedundancyChecker& re, // redundancy checker + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs, // configs + PerReadMetrics& prm) // per-read metrics +{ + assert_eq(botf_ - topf_, botb_ - topb_); + assert(out_.empty()); + assert(repOk(&q)); + // Get initial 5' and 3' offsets + bool fw = rs[rid_].fw; + float rootpri = rs[rid_].pri; + bool toward3p = (l2r_ == fw); + size_t off5p = off5p_i_; + assert_geq(al5pf_, al5pi_); + size_t off3p = q.length() - off5p - 1; + // By "depth" we essentially mean the number of characters already aligned + size_t depth, extrai = 0, extraf = 0; + size_t cur5pi = al5pi_, cur5pf = al5pf_; + if(toward3p) { + // Toward 3' + cur5pf = off5p; + depth = off5p - al5pi_; + // Failed to match out to the end? + if(al5pf_ < q.length() - 1) { + extraf = 1; // extra + } + } else { + // Toward 5' + cur5pi = off5p; + depth = al5pf_ - off5p; + if(al5pi_ > 0) { + extrai = 1; + } + } + // Get gap penalties + TScore pen_rdg_ex = sc.readGapExtend(), pen_rfg_ex = sc.refGapExtend(); + TScore pen_rdg_op = sc.readGapOpen(), pen_rfg_op = sc.refGapOpen(); + // Top and bot in the direction of the descent + TIndexOffU top = l2r_ ? topb_ : topf_; + TIndexOffU bot = l2r_ ? botb_ : botf_; + // Top and bot in the opposite direction + TIndexOffU topp = l2r_ ? topf_ : topb_; + TIndexOffU botp = l2r_ ? botf_ : botb_; + assert_eq(botp - topp, bot - top); + DescentEdge edge; + size_t nout = 0; + // Enumerate all outgoing edges, starting at the root and going out + size_t d = posid_; + // At first glance, we might think we should be bounded by al5pi_ and + // al5pf_, but those delimit the positions that matched between reference + // and read. If we hit a position that failed to match as part of + // followMatches, then we also want to evaluate ways of leaving that + // position, which adds one more position to viist. + while(off5p >= al5pi_ - extrai && off5p <= al5pf_ + extraf) { + assert_lt(off5p, q.length()); + assert_lt(off3p, q.length()); + TScore maxpend = cs[rid_].cons.get(depth, q.length(), maxpen); + assert(depth > 0 || maxpend == 0); + assert_geq(maxpend, pen_); // can't have already exceeded max penalty + TScore diff = maxpend - pen_; // room we have left + // Get pointer to SA ranges in the direction of descent + const TIndexOffU *t = l2r_ ? pf[d].topb : pf[d].topf; + const TIndexOffU *b = l2r_ ? pf[d].botb : pf[d].botf; + const TIndexOffU *tp = l2r_ ? pf[d].topf : pf[d].topb; + const TIndexOffU *bp = l2r_ ? pf[d].botf : pf[d].botb; + assert_eq(pf[d].botf - pf[d].topf, pf[d].botb - pf[d].topb); + // What are the read char / quality? + std::pair p = q.get(off5p, fw); + int c = p.first; + assert_range(0, 4, c); + // Only entertain edits if there is at least one type of edit left and + // there is some penalty budget left + if(!pf[d].flags.exhausted() && diff > 0) { + // What would the penalty be if we mismatched at this position? + // This includes the case where the mismatch is for an N in the + // read. + int qq = p.second; + assert_geq(qq, 0); + TScore pen_mm = sc.mm(c, qq); + if(pen_mm <= diff) { + for(int j = 0; j < 4; j++) { + if(j == c) continue; // Match, not mismatch + if(b[j] <= t[j]) { + continue; // No outgoing edge with this nucleotide + } + if(!pf[d].flags.mmExplore(j)) { + continue; // Already been explored + } + TIndexOffU topf = pf[d].topf[j], botf = pf[d].botf[j]; + ASSERT_ONLY(TIndexOffU topb = pf[d].topb[j], botb = pf[d].botb[j]); + if(re.contains(fw, l2r_, cur5pi, cur5pf, cur5pf - cur5pi + 1 + gapadd_, topf, botf, pen_ + pen_mm)) { + prm.nRedSkip++; + continue; // Redundant with a path already explored + } + prm.nRedFail++; + TIndexOffU width = b[j] - t[j]; + Edit edit((uint32_t)off5p, (int)("ACGTN"[j]), (int)("ACGTN"[c]), EDIT_TYPE_MM); + DescentPriority pri(pen_ + pen_mm, depth, width, rootpri); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + assert_eq(botb - topb, botf - topf); + edge.init(edit, off5p, pri, d +#ifndef NDEBUG + , d, topf, botf, topb, botb +#endif + ); + out_.update(edge); + nout++; + } + } + bool gapsAllowed = (off5p >= (size_t)sc.gapbar && off3p >= (size_t)sc.gapbar); + if(gapsAllowed) { + assert_gt(depth, 0); + // An easy redundancy check is: if all ways of proceeding are + // matches, then there's no need to entertain gaps here. + // Shifting the gap one position further downstream is + // guarnteed not to be worse. + size_t totwidth = (b[0] - t[0]) + + (b[1] - t[1]) + + (b[2] - t[2]) + + (b[3] - t[3]); + assert(c > 3 || b[c] - t[c] <= totwidth); + bool allmatch = c < 4 && (totwidth == (b[c] - t[c])); + bool rdex = false, rfex = false; + size_t cur5pi_i = cur5pi, cur5pf_i = cur5pf; + if(toward3p) { + cur5pf_i--; + } else { + cur5pi_i++; + } + if(off5p == off5p_i_ && edit_.inited()) { + // If we're at the root of the descent, and the descent + // branched on a gap, then this could be scored as an + // extension of that gap. + if(pen_rdg_ex <= diff && edit_.isReadGap()) { + // Extension of a read gap + rdex = true; + for(int j = 0; j < 4; j++) { + if(b[j] <= t[j]) { + continue; // No outgoing edge with this nucleotide + } + if(!pf[d].flags.rdgExplore(j)) { + continue; // Already been explored + } + TIndexOffU topf = pf[d].topf[j], botf = pf[d].botf[j]; + ASSERT_ONLY(TIndexOffU topb = pf[d].topb[j], botb = pf[d].botb[j]); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + if(re.contains(fw, l2r_, cur5pi_i, cur5pf_i, cur5pf - cur5pi + 1 + gapadd_, topf, botf, pen_ + pen_rdg_ex)) { + prm.nRedSkip++; + continue; // Redundant with a path already explored + } + prm.nRedFail++; + TIndexOffU width = b[j] - t[j]; + // off5p holds the offset from the 5' of the next + // character we were trying to align when we decided to + // introduce a read gap (before that character). If we + // were walking toward the 5' end, we need to increment + // by 1. + uint32_t off = (uint32_t)off5p + (toward3p ? 0 : 1); + Edit edit(off, (int)("ACGTN"[j]), '-', EDIT_TYPE_READ_GAP); + assert(edit.pos2 != std::numeric_limits::max()); + edit.pos2 = edit_.pos2 + (toward3p ? 1 : -1); + DescentPriority pri(pen_ + pen_rdg_ex, depth, width, rootpri); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + assert_eq(botb - topb, botf - topf); + edge.init(edit, off5p, pri, d +#ifndef NDEBUG + , d, + topf, botf, topb, botb +#endif + ); + out_.update(edge); + nout++; + } + } + if(pen_rfg_ex <= diff && edit_.isRefGap()) { + // Extension of a reference gap + rfex = true; + if(pf[d].flags.rfgExplore()) { + TIndexOffU topf = l2r_ ? topp : top; + TIndexOffU botf = l2r_ ? botp : bot; + ASSERT_ONLY(TIndexOffU topb = l2r_ ? top : topp); + ASSERT_ONLY(TIndexOffU botb = l2r_ ? bot : botp); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + size_t nrefal = cur5pf - cur5pi + gapadd_; + if(!re.contains(fw, l2r_, cur5pi, cur5pf, nrefal, topf, botf, pen_ + pen_rfg_ex)) { + TIndexOffU width = bot - top; + Edit edit((uint32_t)off5p, '-', (int)("ACGTN"[c]), EDIT_TYPE_REF_GAP); + DescentPriority pri(pen_ + pen_rfg_ex, depth, width, rootpri); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + edge.init(edit, off5p, pri, d +#ifndef NDEBUG + // It's a little unclear what the depth ought to be. + // Is it the depth we were at when we did the ref + // gap? I.e. the depth of the flags where rfgExplore() + // returned true? Or is it the depth where we can + // retrieve the appropriate top/bot? We make it the + // latter, might wrap around, indicating we should get + // top/bot from the descent's topf_, ... fields. + , (d == posid_) ? std::numeric_limits::max() : (d - 1), + topf, botf, topb, botb +#endif + ); + out_.update(edge); + nout++; + prm.nRedFail++; + } else { + prm.nRedSkip++; + } + } + } + } + if(!allmatch && pen_rdg_op <= diff && !rdex) { + // Opening a new read gap + for(int j = 0; j < 4; j++) { + if(b[j] <= t[j]) { + continue; // No outgoing edge with this nucleotide + } + if(!pf[d].flags.rdgExplore(j)) { + continue; // Already been explored + } + TIndexOffU topf = pf[d].topf[j], botf = pf[d].botf[j]; + ASSERT_ONLY(TIndexOffU topb = pf[d].topb[j], botb = pf[d].botb[j]); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + if(re.contains(fw, l2r_, cur5pi_i, cur5pf_i, cur5pf - cur5pi + 1 + gapadd_, topf, botf, pen_ + pen_rdg_op)) { + prm.nRedSkip++; + continue; // Redundant with a path already explored + } + prm.nRedFail++; + TIndexOffU width = b[j] - t[j]; + // off5p holds the offset from the 5' of the next + // character we were trying to align when we decided to + // introduce a read gap (before that character). If we + // were walking toward the 5' end, we need to increment + // by 1. + uint32_t off = (uint32_t)off5p + (toward3p ? 0 : 1); + Edit edit(off, (int)("ACGTN"[j]), '-', EDIT_TYPE_READ_GAP); + assert(edit.pos2 != std::numeric_limits::max()); + DescentPriority pri(pen_ + pen_rdg_op, depth, width, rootpri); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + assert_eq(botb - topb, botf - topf); + edge.init(edit, off5p, pri, d +#ifndef NDEBUG + , d, topf, botf, topb, botb +#endif + ); + out_.update(edge); + nout++; + } + } + if(!allmatch && pen_rfg_op <= diff && !rfex) { + // Opening a new reference gap + if(pf[d].flags.rfgExplore()) { + TIndexOffU topf = l2r_ ? topp : top; + TIndexOffU botf = l2r_ ? botp : bot; + ASSERT_ONLY(TIndexOffU topb = l2r_ ? top : topp); + ASSERT_ONLY(TIndexOffU botb = l2r_ ? bot : botp); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + size_t nrefal = cur5pf - cur5pi + gapadd_; + if(!re.contains(fw, l2r_, cur5pi, cur5pf, nrefal, topf, botf, pen_ + pen_rfg_op)) { + TIndexOffU width = bot - top; + Edit edit((uint32_t)off5p, '-', (int)("ACGTN"[c]), EDIT_TYPE_REF_GAP); + DescentPriority pri(pen_ + pen_rfg_op, depth, width, rootpri); + assert(topf != 0 || botf != 0); + assert(topb != 0 || botb != 0); + edge.init(edit, off5p, pri, d +#ifndef NDEBUG + // It's a little unclear what the depth ought to be. + // Is it the depth we were at when we did the ref + // gap? I.e. the depth of the flags where rfgExplore() + // returned true? Or is it the depth where we can + // retrieve the appropriate top/bot? We make it the + // latter, might wrap around, indicating we should get + // top/bot from the descent's topf_, ... fields. + , (d == posid_) ? std::numeric_limits::max() : (d - 1), + topf, botf, topb, botb +#endif + ); + out_.update(edge); + nout++; + prm.nRedFail++; + } else { + prm.nRedSkip++; + } + } + } + } + } + // Update off5p, off3p, depth + d++; + depth++; + assert_leq(depth, al5pf_ - al5pi_ + 2); + if(toward3p) { + if(off3p == 0) { + break; + } + off5p++; + off3p--; + cur5pf++; + } else { + if(off5p == 0) { + break; + } + off3p++; + off5p--; + cur5pi--; + } + // Update top and bot + if(off5p >= al5pi_ - extrai && off5p <= al5pf_ + extraf) { + assert_range(0, 3, c); + top = t[c]; topp = tp[c]; + bot = b[c]; botp = bp[c]; + assert_eq(bot-top, botp-topp); + } + } + lastRecalc_ = (nout <= 5); + out_.best1.updateFlags(pf); + out_.best2.updateFlags(pf); + out_.best3.updateFlags(pf); + out_.best4.updateFlags(pf); + out_.best5.updateFlags(pf); + return nout; +} + +template +void Descent::print( + std::ostream *os, + const char *prefix, + const Read& q, + size_t trimLf, + size_t trimRg, + bool fw, + const EList& edits, + size_t ei, + size_t en, + BTDnaString& rf) const +{ + const BTDnaString& read = fw ? q.patFw : q.patRc; + size_t eidx = ei; + if(os != NULL) { *os << prefix; } + // Print read + for(size_t i = 0; i < read.length(); i++) { + if(i < trimLf || i >= read.length() - trimRg) { + if(os != NULL) { *os << (char)tolower(read.toChar(i)); } + continue; + } + bool del = false, mm = false; + while(eidx < ei + en && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + if(os != NULL) { *os << '-'; } + } else if(edits[eidx].isRefGap()) { + del = true; + assert_eq((int)edits[eidx].qchr, read.toChar(i)); + if(os != NULL) { *os << read.toChar(i); } + } else { + mm = true; + assert(edits[eidx].isMismatch()); + assert_eq((int)edits[eidx].qchr, read.toChar(i)); + if(os != NULL) { *os << (char)edits[eidx].qchr; } + } + eidx++; + } + if(!del && !mm) { + // Print read character + if(os != NULL) { *os << read.toChar(i); } + } + } + if(os != NULL) { + *os << endl; + *os << prefix; + } + eidx = ei; + // Print match bars + for(size_t i = 0; i < read.length(); i++) { + if(i < trimLf || i >= read.length() - trimRg) { + if(os != NULL) { *os << ' '; } + continue; + } + bool del = false, mm = false; + while(eidx < ei + en && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + if(os != NULL) { *os << ' '; } + } else if(edits[eidx].isRefGap()) { + del = true; + if(os != NULL) { *os << ' '; } + } else { + mm = true; + assert(edits[eidx].isMismatch()); + if(os != NULL) { *os << ' '; } + } + eidx++; + } + if(!del && !mm && os != NULL) { *os << '|'; } + } + if(os != NULL) { + *os << endl; + *os << prefix; + } + eidx = ei; + // Print reference + for(size_t i = 0; i < read.length(); i++) { + if(i < trimLf || i >= read.length() - trimRg) { + if(os != NULL) { *os << ' '; } + continue; + } + bool del = false, mm = false; + while(eidx < ei + en && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + rf.appendChar((char)edits[eidx].chr); + if(os != NULL) { *os << (char)edits[eidx].chr; } + } else if(edits[eidx].isRefGap()) { + del = true; + if(os != NULL) { *os << '-'; } + } else { + mm = true; + assert(edits[eidx].isMismatch()); + rf.appendChar((char)edits[eidx].chr); + if(os != NULL) { *os << (char)edits[eidx].chr; } + } + eidx++; + } + if(!del && !mm) { + rf.append(read[i]); + if(os != NULL) { *os << read.toChar(i); } + } + } + if(os != NULL) { *os << endl; } +} + +/** + * Create a new Descent + */ +template +bool Descent::bounce( + const Read& q, // query string + TIndexOffU topf, // SA range top in fw index + TIndexOffU botf, // SA range bottom in fw index + TIndexOffU topb, // SA range top in bw index + TIndexOffU botb, // SA range bottom in bw index + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + DescentRedundancyChecker& re, // redundancy checker + EFactory >& df, // factory with Descent + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap of descents + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics +{ + assert_gt(botf, topf); + assert(al5pi_ == 0 || al5pf_ == q.length()-1); + assert(!(al5pi_ == 0 && al5pf_ == q.length()-1)); + size_t dfsz = df.size(); + size_t pfsz = pf.size(); + TDescentId id = df.alloc(); + Edit e_null; + assert(!e_null.inited()); + // Follow matches + bool succ = df[id].init( + q, // query + rid_, // root id + sc, // scoring scheme + minsc, // minimum score + maxpen, // maximum penalty + al5pi_, // new near-5' extreme + al5pf_, // new far-5' extreme + topf, // SA range top in FW index + botf, // SA range bottom in FW index + topb, // SA range top in BW index + botb, // SA range bottom in BW index + !l2r_, // direction this descent will go in; opposite from parent + id, // my ID + descid_, // parent ID + pen_, // total penalties so far - same as parent + e_null, // edit for incoming edge; uninitialized if bounced + gfmFw, // forward index + gfmBw, // mirror index + re, // redundancy checker + df, // Descent factory + pf, // DescentPos factory + rs, // DescentRoot list + cs, // DescentConfig list + heap, // heap + alsink, // alignment sink + met, // metrics + prm); // per-read metrics + if(!succ) { + // Reclaim memory we had used for this descent and its DescentPos info + df.resize(dfsz); + pf.resize(pfsz); + } + return succ; +} + +/** + * Take the best outgoing edge and place it in the heap. When deciding what + * outgoing edges exist, abide by constraints in DescentConfig. These + * constraints limit total penalty accumulated so far versus distance from + * search root. E.g. a constraint might disallow any gaps or mismatches within + * 20 ply of the root, then allow 1 mismatch within 30 ply, 1 mismatch or 1 gap + * within 40 ply, etc. + */ +template +void Descent::followBestOutgoing( + const Read& q, // query string + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + TAlScore maxpen, // maximum penalty + DescentRedundancyChecker& re, // redundancy checker + EFactory >& df, // factory with Descent + EFactory& pf, // factory with DescentPoss + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap of descents + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics +{ + // We assume this descent has been popped off the heap. We'll re-add it if + // it hasn't been exhausted. + assert(q.repOk()); + assert(!empty()); + assert(!out_.empty()); + while(!out_.empty()) { + DescentPriority best = out_.bestPri(); + DescentEdge e = out_.rotate(); + TReadOff al5pi_new = al5pi_, al5pf_new = al5pf_; + bool fw = rs[rid_].fw; + bool toward3p = (l2r_ == fw); + TReadOff edoff = e.off5p; // 5' offset of edit + assert_leq(edoff, al5pf_ + 1); + assert_geq(edoff + 1, al5pi_); + if(out_.empty()) { + if(!lastRecalc_) { + // This might allocate new Descents + recalcOutgoing(q, sc, minsc, maxpen, re, pf, rs, cs, prm); + if(empty()) { + // Could happen, since some outgoing edges may have become + // redundant in the meantime. + break; + } + } else { + assert(empty()); + } + } + TReadOff doff; // edit's offset into this descent + int chr = asc2dna[e.e.chr]; + // hitEnd is set to true iff this edit pushes us to the extreme 5' or 3' + // end of the alignment + bool hitEnd = false; + // done is set to true iff this edit aligns the only remaining character of + // the read + bool done = false; + if(toward3p) { + // The 3' extreme of the new Descent is further in (away from the 3' + // end) than the parent's. + al5pf_new = doff = edoff; + if(e.e.isReadGap()) { + // We didn't actually consume the read character at 'edoff', so + // retract al5pf_new by one position. This doesn't effect the + // "depth" (doff) of the SA range we took, though. + assert_gt(al5pf_new, 0); + al5pf_new--; + } + assert_lt(al5pf_new, q.length()); + hitEnd = (al5pf_new == q.length() - 1); + done = (hitEnd && al5pi_new == 0); + assert_geq(doff, off5p_i_); + doff = doff - off5p_i_; + assert_leq(doff, len_); + } else { + // The 5' extreme of the new Descent is further in (away from the 5' + // end) than the parent's. + al5pi_new = doff = edoff; + if(e.e.isReadGap()) { + // We didn't actually consume the read character at 'edoff', so + // move al5pi_new closer to the 3' end by one position. This + // doesn't effect the "depth" (doff) of the SA range we took, + // though. + al5pi_new++; + } + hitEnd = (al5pi_new == 0); + done = (hitEnd && al5pf_new == q.length() - 1); + assert_geq(off5p_i_, doff); + doff = off5p_i_ - doff; + assert_leq(doff, len_); + } + // Check if this is redundant with an already-explored path + bool l2r = l2r_; // gets overridden if we bounce + if(!done && hitEnd) { + // Alignment finsihed extending in one direction + l2r = !l2r; + } + size_t dfsz = df.size(); + size_t pfsz = pf.size(); + TIndexOffU topf, botf, topb, botb; + size_t d = posid_ + doff; + if(e.e.isRefGap()) { + d--; // might underflow + if(doff == 0) { + topf = topf_; + botf = botf_; + topb = topb_; + botb = botb_; + d = std::numeric_limits::max(); + assert_eq(botf-topf, botb-topb); + } else { + assert_gt(al5pf_new, 0); + assert_gt(d, 0); + chr = pf[d].c; + assert(pf[d].inited()); + assert_range(0, 3, chr); + topf = pf[d].topf[chr]; + botf = pf[d].botf[chr]; + topb = pf[d].topb[chr]; + botb = pf[d].botb[chr]; + assert_eq(botf-topf, botb-topb); + } + } else { + // A read gap or a mismatch + assert(pf[d].inited()); + topf = pf[d].topf[chr]; + botf = pf[d].botf[chr]; + topb = pf[d].topb[chr]; + botb = pf[d].botb[chr]; + assert_eq(botf-topf, botb-topb); + } + assert_eq(d, e.d); + assert_eq(topf, e.topf); + assert_eq(botf, e.botf); + assert_eq(topb, e.topb); + assert_eq(botb, e.botb); + if(done) { + // Aligned the entire read end-to-end. Presumably there's no need to + // create a new Descent object. We just report the alignment. + alsink.reportAlignment( + q, // query + gfmFw, // forward index + gfmBw, // backward index + topf, // top of SA range in forward index + botf, // bottom of SA range in forward index + topb, // top of SA range in backward index + botb, // bottom of SA range in backward index + descid_, // Descent at the leaf + rid_, // root id + e.e, // extra edit, if necessary + best.pen, // penalty + df, // factory with Descent + pf, // factory with DescentPoss + rs, // roots + cs); // configs + assert(alsink.repOk()); + return; + } + assert(al5pi_new != 0 || al5pf_new != q.length() - 1); + TDescentId id = df.alloc(); + bool succ = df[id].init( + q, // query + rid_, // root id + sc, // scoring scheme + minsc, // minimum score + maxpen, // maximum penalty + al5pi_new, // new near-5' extreme + al5pf_new, // new far-5' extreme + topf, // SA range top in FW index + botf, // SA range bottom in FW index + topb, // SA range top in BW index + botb, // SA range bottom in BW index + l2r, // direction this descent will go in + id, // my ID + descid_, // parent ID + best.pen, // total penalties so far + e.e, // edit for incoming edge; uninitialized if bounced + gfmFw, // forward index + gfmBw, // mirror index + re, // redundancy checker + df, // Descent factory + pf, // DescentPos factory + rs, // DescentRoot list + cs, // DescentConfig list + heap, // heap + alsink, // alignment sink + met, // metrics + prm); // per-read metrics + if(!succ) { + // Reclaim memory we had used for this descent and its DescentPos info + df.resize(dfsz); + pf.resize(pfsz); + } + break; + } + if(!empty()) { + // Re-insert this Descent with its new priority + heap.insert(make_pair(out_.bestPri(), descid_)); + } +} + +/** + * Given the forward and backward indexes, and given topf/botf/topb/botb, get + * tloc, bloc ready for the next step. + */ +template +void Descent::nextLocsBi( + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + SideLocus& tloc, // top locus + SideLocus& bloc, // bot locus + index_t topf, // top in BWT + index_t botf, // bot in BWT + index_t topb, // top in BWT' + index_t botb) // bot in BWT' +{ + assert_gt(botf, 0); + // Which direction are we going in next? + if(l2r_) { + // Left to right; use BWT' + if(botb - topb == 1) { + // Already down to 1 row; just init top locus + tloc.initFromRow(topb, gfmBw.gh(), gfmBw.gfm()); + bloc.invalidate(); + } else { + SideLocus::initFromTopBot( + topb, botb, gfmBw.gh(), gfmBw.gfm(), tloc, bloc); + assert(bloc.valid()); + } + } else { + // Right to left; use BWT + if(botf - topf == 1) { + // Already down to 1 row; just init top locus + tloc.initFromRow(topf, gfmFw.gh(), gfmFw.gfm()); + bloc.invalidate(); + } else { + SideLocus::initFromTopBot( + topf, botf, gfmFw.gh(), gfmFw.gfm(), tloc, bloc); + assert(bloc.valid()); + } + } + // Check if we should update the tracker with this refinement + assert(botf - topf == 1 || bloc.valid()); + assert(botf - topf > 1 || !bloc.valid()); +} + +/** + * Advance this descent by following read matches as far as possible. + * + * This routine doesn't have to consider the whole gamut of constraints on + * which outgoing edges can be followed. If it is a root descent, it does have + * to know how deep the no-edit constraint goes, though, so we can decide + * whether using the ftab would potentially jump over relevant branch points. + * Apart from that, though, we simply proceed as far as it can go by matching + * characters in the query, irrespective of the constraints. + * recalcOutgoing(...) and followBestOutgoing(...) do have to consider these + * constraints, though. + * + * Conceptually, as we make descending steps, we have: + * 1. Before each step, a single range indicating how we departed the previous + * step + * 2. As part of each step, a quad of ranges indicating what range would result + * if we proceeded on an a, c, g ot t + * + * Return true iff it is possible to branch from this descent. If we haven't + * exceeded the no-branch depth. + */ +template +bool Descent::followMatches( + const Read& q, // query string + const Scoring& sc, // scoring scheme + const GFM& gfmFw, // forward index + const GFM& gfmBw, // mirror index + DescentRedundancyChecker& re, // redundancy checker + EFactory >& df, // Descent factory + EFactory& pf, // DescentPos factory + const EList& rs, // roots + const EList& cs, // configs + EHeap& heap, // heap + DescentAlignmentSink& alsink, // alignment sink + DescentMetrics& met, // metrics + PerReadMetrics& prm, // per-read metrics + bool& branches, // out: true -> there are > 0 ways to branch + bool& hitEnd, // out: true -> hit read end with non-empty range + bool& done, // out: true -> we made a full alignment + TReadOff& off5p_i, // out: initial 5' offset + TIndexOffU& topf_bounce, // out: top of SA range for fw idx for bounce + TIndexOffU& botf_bounce, // out: bot of SA range for fw idx for bounce + TIndexOffU& topb_bounce, // out: top of SA range for bw idx for bounce + TIndexOffU& botb_bounce) // out: bot of SA range for bw idx for bounce +{ + // TODO: make these full-fledged parameters + size_t nobranchDepth = 20; + bool stopOnN = true; + assert(q.repOk()); + assert(repOk(&q)); + assert_eq(gfmFw.eh().ftabChars(), gfmBw.gh().ftabChars()); +#ifndef NDEBUG + for(int i = 0; i < 4; i++) { + assert_eq(gfmFw.fchr()[i], gfmBw.fchr()[i]); + } +#endif + SideLocus tloc, bloc; + TIndexOffU topf = topf_, botf = botf_, topb = topb_, botb = botb_; + bool fw = rs[rid_].fw; + bool toward3p; + size_t off5p; + assert_lt(al5pi_, q.length()); + assert_lt(al5pf_, q.length()); + while(true) { + toward3p = (l2r_ == fw); + assert_geq(al5pf_, al5pi_); + assert(al5pi_ != 0 || al5pf_ != q.length() - 1); + if(toward3p) { + if(al5pf_ == q.length()-1) { + l2r_ = !l2r_; + continue; + } + if(al5pi_ == al5pf_ && root()) { + off5p = off5p_i = al5pi_; + } else { + off5p = off5p_i = (al5pf_ + 1); + } + } else { + if(al5pi_ == 0) { + l2r_ = !l2r_; + continue; + } + assert_gt(al5pi_, 0); + if(al5pi_ == al5pf_ && root()) { + off5p = off5p_i = al5pi_; + } else { + off5p = off5p_i = (al5pi_ - 1); + } + } + break; + } + size_t off3p = q.length() - off5p - 1; + assert_lt(off5p, q.length()); + assert_lt(off3p, q.length()); + bool firstPos = true; + assert_eq(0, len_); + + // Number of times pf.alloc() is called. So we can sanity check it. + size_t nalloc = 0; + // Set to true as soon as we encounter a branch point along this descent. + branches = false; + // hitEnd is set to true iff this edit pushes us to the extreme 5' or 3' + // end of the alignment + hitEnd = false; + // done is set to true iff this edit aligns the only remaining character of + // the read + done = false; + if(root()) { + assert_eq(al5pi_, al5pf_); + // Check whether/how far we can jump using ftab + int ftabLen = gfmFw.gh().ftabChars(); + bool ftabFits = true; + if(toward3p && ftabLen + off5p > q.length()) { + ftabFits = false; + } else if(!toward3p && off5p < (size_t)ftabLen) { + ftabFits = false; + } + bool useFtab = ftabLen > 1 && (size_t)ftabLen <= nobranchDepth && ftabFits; + bool ftabFailed = false; + if(useFtab) { + prm.nFtabs++; + // Forward index: right-to-left + size_t off_r2l = fw ? off5p : q.length() - off5p - 1; + if(l2r_) { + // + } else { + assert_geq((int)off_r2l, ftabLen - 1); + off_r2l -= (ftabLen - 1); + } + bool ret = gfmFw.ftabLoHi(fw ? q.patFw : q.patRc, off_r2l, + false, // reverse + topf, botf); + if(!ret) { + // Encountered an N or something else that made it impossible + // to use the ftab + ftabFailed = true; + } else { + if(botf - topf == 0) { + return false; + } + int c_r2l = fw ? q.patFw[off_r2l] : q.patRc[off_r2l]; + // Backward index: left-to-right + size_t off_l2r = fw ? off5p : q.length() - off5p - 1; + if(l2r_) { + // + } else { + assert_geq((int)off_l2r, ftabLen - 1); + off_l2r -= (ftabLen - 1); + } + ASSERT_ONLY(bool ret2 = ) + gfmBw.ftabLoHi(fw ? q.patFw : q.patRc, off_l2r, + false, // don't reverse + topb, botb); + assert(ret == ret2); + int c_l2r = fw ? q.patFw[off_l2r + ftabLen - 1] : + q.patRc[off_l2r + ftabLen - 1]; + assert_eq(botf - topf, botb - topb); + if(toward3p) { + assert_geq((int)off3p, ftabLen - 1); + off5p += ftabLen; off3p -= ftabLen; + } else { + assert_geq((int)off5p, ftabLen - 1); + off5p -= ftabLen; off3p += ftabLen; + } + len_ += ftabLen; + if(toward3p) { + // By convention, al5pf_ and al5pi_ start out equal, so we only + // advance al5pf_ by ftabLen - 1 (not ftabLen) + al5pf_ += (ftabLen - 1); // -1 accounts for inclusive al5pf_ + if(al5pf_ == q.length() - 1) { + hitEnd = true; + done = (al5pi_ == 0); + } + } else { + // By convention, al5pf_ and al5pi_ start out equal, so we only + // advance al5pi_ by ftabLen - 1 (not ftabLen) + al5pi_ -= (ftabLen - 1); + if(al5pi_ == 0) { + hitEnd = true; + done = (al5pf_ == q.length()-1); + } + } + // Allocate DescentPos data structures and leave them empty. We + // jumped over them by doing our lookup in the ftab, so we have no + // info about outgoing edges from them, besides the matching + // outgoing edge from the last pos which is in topf/botf and + // topb/botb. + size_t id = 0; + if(firstPos) { + posid_ = pf.alloc(); + pf[posid_].reset(); + firstPos = false; + for(int i = 1; i < ftabLen; i++) { + id = pf.alloc(); + pf[id].reset(); + } + } else { + for(int i = 0; i < ftabLen; i++) { + id = pf.alloc(); + pf[id].reset(); + } + } + assert_eq(botf-topf, botb-topb); + pf[id].c = l2r_ ? c_l2r : c_r2l; + pf[id].topf[l2r_ ? c_l2r : c_r2l] = topf; + pf[id].botf[l2r_ ? c_l2r : c_r2l] = botf; + pf[id].topb[l2r_ ? c_l2r : c_r2l] = topb; + pf[id].botb[l2r_ ? c_l2r : c_r2l] = botb; + assert(pf[id].inited()); + nalloc += ftabLen; + } + } + if(!useFtab || ftabFailed) { + // Can't use ftab, use fchr instead + int rdc = q.getc(off5p, fw); + // If rdc is N, that's pretty bad! That means we placed a root + // right on an N. The only thing we can reasonably do is to pick a + // nucleotide at random and proceed. + if(rdc > 3) { + return false; + } + assert_range(0, 3, rdc); + topf = topb = gfmFw.fchr()[rdc]; + botf = botb = gfmFw.fchr()[rdc+1]; + if(botf - topf == 0) { + return false; + } + if(toward3p) { + off5p++; off3p--; + } else { + off5p--; off3p++; + } + len_++; + if(toward3p) { + if(al5pf_ == q.length()-1) { + hitEnd = true; + done = (al5pi_ == 0); + } + } else { + if(al5pi_ == 0) { + hitEnd = true; + done = (al5pf_ == q.length()-1); + } + } + // Allocate DescentPos data structure. We could fill it with the + // four ranges from fchr if we wanted to, but that will never be + // relevant. + size_t id = 0; + if(firstPos) { + posid_ = id = pf.alloc(); + firstPos = false; + } else { + id = pf.alloc(); + } + assert_eq(botf-topf, botb-topb); + pf[id].c = rdc; + pf[id].topf[rdc] = topf; + pf[id].botf[rdc] = botf; + pf[id].topb[rdc] = topb; + pf[id].botb[rdc] = botb; + assert(pf[id].inited()); + nalloc++; + } + assert_gt(botf, topf); + assert_eq(botf - topf, botb - topb); + // Check if this is redundant with an already-explored path + if(!re.check(fw, l2r_, al5pi_, al5pf_, al5pf_ - al5pi_ + 1 + gapadd_, + topf, botf, pen_)) + { + prm.nRedSkip++; + return false; + } + prm.nRedFail++; // not pruned by redundancy list + prm.nRedIns++; // inserted into redundancy list + } + if(done) { + Edit eempty; + alsink.reportAlignment( + q, // query + gfmFw, // forward index + gfmBw, // backward index + topf, // top of SA range in forward index + botf, // bottom of SA range in forward index + topb, // top of SA range in backward index + botb, // bottom of SA range in backward index + descid_, // Descent at the leaf + rid_, // root id + eempty, // extra edit, if necessary + pen_, // penalty + df, // factory with Descent + pf, // factory with DescentPoss + rs, // roots + cs); // configs + assert(alsink.repOk()); + return true; + } else if(hitEnd) { + assert(botf > 0 || topf > 0); + assert_gt(botf, topf); + topf_bounce = topf; + botf_bounce = botf; + topb_bounce = topb; + botb_bounce = botb; + return true; // Bounced + } + // We just advanced either ftabLen characters, or 1 character, + // depending on whether we used ftab or fchr. + nextLocsBi(gfmFw, gfmBw, tloc, bloc, topf, botf, topb, botb); + assert(tloc.valid()); + assert(botf - topf == 1 || bloc.valid()); + assert(botf - topf > 1 || !bloc.valid()); + TIndexOffU t[4], b[4]; // dest BW ranges + TIndexOffU tp[4], bp[4]; // dest BW ranges for "prime" index + ASSERT_ONLY(TIndexOff lasttot = botf - topf); + bool fail = false; + while(!fail && !hitEnd) { + assert(!done); + int rdc = q.getc(off5p, fw); + int rdq = q.getq(off5p); + assert_range(0, 4, rdc); + assert_gt(botf, topf); + assert(botf - topf == 1 || bloc.valid()); + assert(botf - topf > 1 || !bloc.valid()); + assert(tloc.valid()); + TIndexOffU width = botf - topf; + bool ltr = l2r_; + const GFM& gfm = ltr ? gfmBw : gfmFw; + t[0] = t[1] = t[2] = t[3] = b[0] = b[1] = b[2] = b[3] = 0; + int only = -1; // if we only get 1 non-empty range, this is the char + size_t nopts = 1; + if(bloc.valid()) { + // Set up initial values for the primes + if(ltr) { + tp[0] = tp[1] = tp[2] = tp[3] = topf; + bp[0] = bp[1] = bp[2] = bp[3] = botf; + } else { + tp[0] = tp[1] = tp[2] = tp[3] = topb; + bp[0] = bp[1] = bp[2] = bp[3] = botb; + } + // Range delimited by tloc/bloc has size >1. If size == 1, + // we use a simpler query (see if(!bloc.valid()) blocks below) + met.bwops++; + met.bwops_bi++; + prm.nSdFmops++; + if(prm.doFmString) { + prm.fmString.add(false, pen_, 1); + } + gfm.mapBiLFEx(tloc, bloc, t, b, tp, bp); + // t, b, tp and bp now filled + ASSERT_ONLY(TIndexOffU tot = (b[0]-t[0])+(b[1]-t[1])+(b[2]-t[2])+(b[3]-t[3])); + ASSERT_ONLY(TIndexOffU totp = (bp[0]-tp[0])+(bp[1]-tp[1])+(bp[2]-tp[2])+(bp[3]-tp[3])); + assert_eq(tot, totp); + assert_leq(tot, lasttot); + ASSERT_ONLY(lasttot = tot); + fail = (rdc > 3 || b[rdc] <= t[rdc]); + size_t nopts = 0; + if(b[0] > t[0]) { nopts++; only = 0; } + if(b[1] > t[1]) { nopts++; only = 1; } + if(b[2] > t[2]) { nopts++; only = 2; } + if(b[3] > t[3]) { nopts++; only = 3; } + if(!fail && b[rdc] - t[rdc] < width) { + branches = true; + } + } else { + tp[0] = tp[1] = tp[2] = tp[3] = bp[0] = bp[1] = bp[2] = bp[3] = 0; + // Range delimited by tloc/bloc has size 1 + TIndexOffU ntop = ltr ? topb : topf; + met.bwops++; + met.bwops_1++; + prm.nSdFmops++; + if(prm.doFmString) { + prm.fmString.add(false, pen_, 1); + } + int cc = gfm.mapLF1(ntop, tloc); + assert_range(-1, 3, cc); + fail = (cc != rdc); + if(fail) { + branches = true; + } + if(cc >= 0) { + only = cc; + t[cc] = ntop; b[cc] = ntop+1; + tp[cc] = ltr ? topf : topb; + bp[cc] = ltr ? botf : botb; + } + } + // Now figure out what to do with our N. + int origRdc = rdc; + if(rdc == 4) { + fail = true; + } else { + topf = ltr ? tp[rdc] : t[rdc]; + botf = ltr ? bp[rdc] : b[rdc]; + topb = ltr ? t[rdc] : tp[rdc]; + botb = ltr ? b[rdc] : bp[rdc]; + assert_eq(botf - topf, botb - topb); + } + // The trouble with !stopOnN is that we don't have a way to store the N + // edits. There could be several per Descent. + if(rdc == 4 && !stopOnN && nopts == 1) { + fail = false; + rdc = only; + int pen = sc.n(rdq); + assert_gt(pen, 0); + pen_ += pen; + } + assert_range(0, 4, origRdc); + assert_range(0, 4, rdc); + // If 'fail' is true, we failed to align this read character. We still + // install the SA ranges into the DescentPos and increment len_ in this + // case. + + // Convert t, tp, b, bp info tf, bf, tb, bb + TIndexOffU *tf = ltr ? tp : t; + TIndexOffU *bf = ltr ? bp : b; + TIndexOffU *tb = ltr ? t : tp; + TIndexOffU *bb = ltr ? b : bp; + // Allocate DescentPos data structure. + if(firstPos) { + posid_ = pf.alloc(); + firstPos = false; + } else { + pf.alloc(); + } + nalloc++; + pf[posid_ + len_].reset(); + pf[posid_ + len_].c = origRdc; + for(size_t i = 0; i < 4; i++) { + pf[posid_ + len_].topf[i] = tf[i]; + pf[posid_ + len_].botf[i] = bf[i]; + pf[posid_ + len_].topb[i] = tb[i]; + pf[posid_ + len_].botb[i] = bb[i]; + assert_eq(pf[posid_ + len_].botf[i] - pf[posid_ + len_].topf[i], + pf[posid_ + len_].botb[i] - pf[posid_ + len_].topb[i]); + } + if(!fail) { + // Check if this is redundant with an already-explored path + size_t al5pf = al5pf_, al5pi = al5pi_; + if(toward3p) { + al5pf++; + } else { + al5pi--; + } + fail = !re.check(fw, l2r_, al5pi, al5pf, + al5pf - al5pi + 1 + gapadd_, topf, botf, pen_); + if(fail) { + prm.nRedSkip++; + } else { + prm.nRedFail++; // not pruned by redundancy list + prm.nRedIns++; // inserted into redundancy list + } + } + if(!fail) { + len_++; + if(toward3p) { + al5pf_++; + off5p++; + off3p--; + if(al5pf_ == q.length() - 1) { + hitEnd = true; + done = (al5pi_ == 0); + } + } else { + assert_gt(al5pi_, 0); + al5pi_--; + off5p--; + off3p++; + if(al5pi_ == 0) { + hitEnd = true; + done = (al5pf_ == q.length() - 1); + } + } + } + if(!fail && !hitEnd) { + nextLocsBi(gfmFw, gfmBw, tloc, bloc, tf[rdc], bf[rdc], tb[rdc], bb[rdc]); + } + } + assert_geq(al5pf_, al5pi_); + assert(!root() || al5pf_ - al5pi_ + 1 == nalloc || al5pf_ - al5pi_ + 2 == nalloc); + assert_geq(pf.size(), nalloc); + if(done) { + Edit eempty; + alsink.reportAlignment( + q, // query + gfmFw, // forward index + gfmBw, // backward index + topf, // top of SA range in forward index + botf, // bottom of SA range in forward index + topb, // top of SA range in backward index + botb, // bottom of SA range in backward index + descid_, // Descent at the leaf + rid_, // root id + eempty, // extra edit, if necessary + pen_, // penalty + df, // factory with Descent + pf, // factory with DescentPoss + rs, // roots + cs); // configs + assert(alsink.repOk()); + return true; + } else if(hitEnd) { + assert(botf > 0 || topf > 0); + assert_gt(botf, topf); + topf_bounce = topf; + botf_bounce = botf; + topb_bounce = topb; + botb_bounce = botb; + return true; // Bounced + } + assert(repOk(&q)); + assert(!hitEnd || topf_bounce > 0 || botf_bounce > 0); + return true; +} + +#endif diff --git a/aligner_seed_policy.cpp b/aligner_seed_policy.cpp new file mode 100644 index 0000000..204e66e --- /dev/null +++ b/aligner_seed_policy.cpp @@ -0,0 +1,916 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include +#include +#include "ds.h" +#include "aligner_seed_policy.h" +#include "mem_ids.h" + +using namespace std; + +static int parseFuncType(const std::string& otype) { + string type = otype; + if(type == "C" || type == "Constant") { + return SIMPLE_FUNC_CONST; + } else if(type == "L" || type == "Linear") { + return SIMPLE_FUNC_LINEAR; + } else if(type == "S" || type == "Sqrt") { + return SIMPLE_FUNC_SQRT; + } else if(type == "G" || type == "Log") { + return SIMPLE_FUNC_LOG; + } + std::cerr << "Error: Bad function type '" << otype.c_str() + << "'. Should be C (constant), L (linear), " + << "S (square root) or G (natural log)." << std::endl; + throw 1; +} + +#define PARSE_FUNC(fv) { \ + if(ctoks.size() >= 1) { \ + fv.setType(parseFuncType(ctoks[0])); \ + } \ + if(ctoks.size() >= 2) { \ + double co; \ + istringstream tmpss(ctoks[1]); \ + tmpss >> co; \ + fv.setConst(co); \ + } \ + if(ctoks.size() >= 3) { \ + double ce; \ + istringstream tmpss(ctoks[2]); \ + tmpss >> ce; \ + fv.setCoeff(ce); \ + } \ + if(ctoks.size() >= 4) { \ + double mn; \ + istringstream tmpss(ctoks[3]); \ + tmpss >> mn; \ + fv.setMin(mn); \ + } \ + if(ctoks.size() >= 5) { \ + double mx; \ + istringstream tmpss(ctoks[4]); \ + tmpss >> mx; \ + fv.setMin(mx); \ + } \ +} + +/** + * Parse alignment policy when provided in this format: + * =;=;=... + * + * And label=value possibilities are: + * + * Bonus for a match + * ----------------- + * + * MA=xx (default: MA=0, or MA=2 if --local is set) + * + * xx = Each position where equal read and reference characters match up + * in the alignment contriubtes this amount to the total score. + * + * Penalty for a mismatch + * ---------------------- + * + * MMP={Cxx|Q|RQ} (default: MMP=C6) + * + * Cxx = Each mismatch costs xx. If MMP=Cxx is specified, quality + * values are ignored when assessing penalities for mismatches. + * Q = Each mismatch incurs a penalty equal to the mismatched base's + * value. + * R = Each mismatch incurs a penalty equal to the mismatched base's + * rounded quality value. Qualities are rounded off to the + * nearest 10, and qualities greater than 30 are rounded to 30. + * + * Penalty for position with N (in either read or reference) + * --------------------------------------------------------- + * + * NP={Cxx|Q|RQ} (default: NP=C1) + * + * Cxx = Each alignment position with an N in either the read or the + * reference costs xx. If NP=Cxx is specified, quality values are + * ignored when assessing penalities for Ns. + * Q = Each alignment position with an N in either the read or the + * reference incurs a penalty equal to the read base's quality + * value. + * R = Each alignment position with an N in either the read or the + * reference incurs a penalty equal to the read base's rounded + * quality value. Qualities are rounded off to the nearest 10, + * and qualities greater than 30 are rounded to 30. + * + * Penalty for a read gap + * ---------------------- + * + * RDG=xx,yy (default: RDG=5,3) + * + * xx = Read gap open penalty. + * yy = Read gap extension penalty. + * + * Total cost incurred by a read gap = xx + (yy * gap length) + * + * Penalty for a reference gap + * --------------------------- + * + * RFG=xx,yy (default: RFG=5,3) + * + * xx = Reference gap open penalty. + * yy = Reference gap extension penalty. + * + * Total cost incurred by a reference gap = xx + (yy * gap length) + * + * Minimum score for valid alignment + * --------------------------------- + * + * MIN=xx,yy (defaults: MIN=-0.6,-0.6, or MIN=0.0,0.66 if --local is set) + * + * xx,yy = For a read of length N, the total score must be at least + * xx + (read length * yy) for the alignment to be valid. The + * total score is the sum of all negative penalties (from + * mismatches and gaps) and all positive bonuses. The minimum + * can be negative (and is by default in global alignment mode). + * + * Score floor for local alignment + * ------------------------------- + * + * FL=xx,yy (defaults: FL=-Infinity,0.0, or FL=0.0,0.0 if --local is set) + * + * xx,yy = If a cell in the dynamic programming table has a score less + * than xx + (read length * yy), then no valid alignment can go + * through it. Defaults are highly recommended. + * + * N ceiling + * --------- + * + * NCEIL=xx,yy (default: NCEIL=0.0,0.15) + * + * xx,yy = For a read of length N, the number of alignment + * positions with an N in either the read or the + * reference cannot exceed + * ceiling = xx + (read length * yy). If the ceiling is + * exceeded, the alignment is considered invalid. + * + * Seeds + * ----- + * + * SEED=mm,len,ival (default: SEED=0,22) + * + * mm = Maximum number of mismatches allowed within a seed. + * Must be >= 0 and <= 2. Note that 2-mismatch mode is + * not fully sensitive; i.e. some 2-mismatch seed + * alignments may be missed. + * len = Length of seed. + * ival = Interval between seeds. If not specified, seed + * interval is determined by IVAL. + * + * Seed interval + * ------------- + * + * IVAL={L|S|C},xx,yy (default: IVAL=S,1.0,0.0) + * + * L = let interval between seeds be a linear function of the + * read length. xx and yy are the constant and linear + * coefficients respectively. In other words, the interval + * equals a * len + b, where len is the read length. + * Intervals less than 1 are rounded up to 1. + * S = let interval between seeds be a function of the sqaure + * root of the read length. xx and yy are the + * coefficients. In other words, the interval equals + * a * sqrt(len) + b, where len is the read length. + * Intervals less than 1 are rounded up to 1. + * C = Like S but uses cube root of length instead of square + * root. + * + * Example 1: + * + * SEED=1,10,5 and read sequence is TGCTATCGTACGATCGTAC: + * + * The following seeds are extracted from the forward + * representation of the read and aligned to the reference + * allowing up to 1 mismatch: + * + * Read: TGCTATCGTACGATCGTACA + * + * Seed 1+: TGCTATCGTA + * Seed 2+: TCGTACGATC + * Seed 3+: CGATCGTACA + * + * ...and the following are extracted from the reverse-complement + * representation of the read and align to the reference allowing + * up to 1 mismatch: + * + * Seed 1-: TACGATAGCA + * Seed 2-: GATCGTACGA + * Seed 3-: TGTACGATCG + * + * Example 2: + * + * SEED=1,20,20 and read sequence is TGCTATCGTACGATC. The seed + * length is 20 but the read is only 15 characters long. In this + * case, Bowtie2 automatically shrinks the seed length to be equal + * to the read length. + * + * Read: TGCTATCGTACGATC + * + * Seed 1+: TGCTATCGTACGATC + * Seed 1-: GATCGTACGATAGCA + * + * Example 3: + * + * SEED=1,10,10 and read sequence is TGCTATCGTACGATC. Only one seed + * fits on the read; a second seed would overhang the end of the read + * by 5 positions. In this case, Bowtie2 extracts one seed. + * + * Read: TGCTATCGTACGATC + * + * Seed 1+: TGCTATCGTA + * Seed 1-: TACGATAGCA + */ +void SeedAlignmentPolicy::parseString( + const std::string& s, + bool local, + bool noisyHpolymer, + bool ignoreQuals, + int& bonusMatchType, + int& bonusMatch, + int& penMmcType, + int& penMmcMax, + int& penMmcMin, + int& penScMax, + int& penScMin, + int& penNType, + int& penN, + int& penRdExConst, + int& penRfExConst, + int& penRdExLinear, + int& penRfExLinear, + SimpleFunc& costMin, + SimpleFunc& nCeil, + bool& nCatPair, + int& multiseedMms, + int& multiseedLen, + SimpleFunc& multiseedIval, + size_t& failStreak, + size_t& seedRounds, + SimpleFunc* penCanIntronLen, + SimpleFunc* penNoncanIntronLen) +{ + + bonusMatchType = local ? DEFAULT_MATCH_BONUS_TYPE_LOCAL : DEFAULT_MATCH_BONUS_TYPE; + bonusMatch = local ? DEFAULT_MATCH_BONUS_LOCAL : DEFAULT_MATCH_BONUS; + penMmcType = ignoreQuals ? DEFAULT_MM_PENALTY_TYPE_IGNORE_QUALS : + DEFAULT_MM_PENALTY_TYPE; + penMmcMax = DEFAULT_MM_PENALTY_MAX; + penMmcMin = DEFAULT_MM_PENALTY_MIN; + penNType = DEFAULT_N_PENALTY_TYPE; + penN = DEFAULT_N_PENALTY; + + penScMax = DEFAULT_SC_PENALTY_MAX; + penScMin = DEFAULT_SC_PENALTY_MIN; + + const double DMAX = std::numeric_limits::max(); + costMin.init( + local ? SIMPLE_FUNC_LOG : SIMPLE_FUNC_LINEAR, + local ? DEFAULT_MIN_CONST_LOCAL : 0.0f, + local ? DEFAULT_MIN_LINEAR_LOCAL : -0.2f); + nCeil.init( + SIMPLE_FUNC_LINEAR, 0.0f, DMAX, + DEFAULT_N_CEIL_CONST, DEFAULT_N_CEIL_LINEAR); + multiseedIval.init( + DEFAULT_IVAL, 1.0f, DMAX, + DEFAULT_IVAL_B, DEFAULT_IVAL_A); + nCatPair = DEFAULT_N_CAT_PAIR; + + if(!noisyHpolymer) { + penRdExConst = DEFAULT_READ_GAP_CONST; + penRdExLinear = DEFAULT_READ_GAP_LINEAR; + penRfExConst = DEFAULT_REF_GAP_CONST; + penRfExLinear = DEFAULT_REF_GAP_LINEAR; + } else { + penRdExConst = DEFAULT_READ_GAP_CONST_BADHPOLY; + penRdExLinear = DEFAULT_READ_GAP_LINEAR_BADHPOLY; + penRfExConst = DEFAULT_REF_GAP_CONST_BADHPOLY; + penRfExLinear = DEFAULT_REF_GAP_LINEAR_BADHPOLY; + } + + multiseedMms = DEFAULT_SEEDMMS; + multiseedLen = DEFAULT_SEEDLEN; + + EList toks(MISC_CAT); + string tok; + istringstream ss(s); + int setting = 0; + // Get each ;-separated token + while(getline(ss, tok, ';')) { + setting++; + EList etoks(MISC_CAT); + string etok; + // Divide into tokens on either side of = + istringstream ess(tok); + while(getline(ess, etok, '=')) { + etoks.push_back(etok); + } + // Must be exactly 1 = + if(etoks.size() != 2) { + cerr << "Error parsing alignment policy setting " << setting + << "; must be bisected by = sign" << endl + << "Policy: " << s.c_str() << endl; + assert(false); throw 1; + } + // LHS is tag, RHS value + string tag = etoks[0], val = etoks[1]; + // Separate value into comma-separated tokens + EList ctoks(MISC_CAT); + string ctok; + istringstream css(val); + while(getline(css, ctok, ',')) { + ctoks.push_back(ctok); + } + if(ctoks.size() == 0) { + cerr << "Error parsing alignment policy setting " << setting + << "; RHS must have at least 1 token" << endl + << "Policy: " << s.c_str() << endl; + assert(false); throw 1; + } + for(size_t i = 0; i < ctoks.size(); i++) { + if(ctoks[i].length() == 0) { + cerr << "Error parsing alignment policy setting " << setting + << "; token " << i+1 << " on RHS had length=0" << endl + << "Policy: " << s.c_str() << endl; + assert(false); throw 1; + } + } + // Bonus for a match + // MA=xx (default: MA=0, or MA=10 if --local is set) + if(tag == "MA") { + if(ctoks.size() != 1) { + cerr << "Error parsing alignment policy setting " << setting + << "; RHS must have 1 token" << endl + << "Policy: " << s.c_str() << endl; + assert(false); throw 1; + } + string tmp = ctoks[0]; + istringstream tmpss(tmp); + tmpss >> bonusMatch; + } + // Scoring for mismatches + // MMP={Cxx|Q|RQ} + // Cxx = constant, where constant is integer xx + // Qxx = equal to quality, scaled + // R = equal to maq-rounded quality value (rounded to nearest + // 10, can't be greater than 30) + else if(tag == "MMP") { + if(ctoks.size() > 3) { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'" + << "; RHS must have at most 3 tokens" << endl + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + if(ctoks[0][0] == 'C') { + string tmp = ctoks[0].substr(1); + // Parse constant penalty + istringstream tmpss(tmp); + tmpss >> penMmcMax; + penMmcMin = penMmcMax; + // Parse constant penalty + penMmcType = COST_MODEL_CONSTANT; + } else if(ctoks[0][0] == 'Q') { + if(ctoks.size() >= 2) { + string tmp = ctoks[1]; + istringstream tmpss(tmp); + tmpss >> penMmcMax; + } else { + penMmcMax = DEFAULT_MM_PENALTY_MAX; + } + if(ctoks.size() >= 3) { + string tmp = ctoks[2]; + istringstream tmpss(tmp); + tmpss >> penMmcMin; + } else { + penMmcMin = DEFAULT_MM_PENALTY_MIN; + } + if(penMmcMin > penMmcMax) { + cerr << "Error: Maximum mismatch penalty (" << penMmcMax + << ") is less than minimum penalty (" << penMmcMin + << endl; + throw 1; + } + // Set type to =quality + penMmcType = COST_MODEL_QUAL; + } else if(ctoks[0][0] == 'R') { + // Set type to=Maq-quality + penMmcType = COST_MODEL_ROUNDED_QUAL; + } else { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'" + << "; RHS must start with C, Q or R" << endl + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + } + else if(tag == "SCP") { + if(ctoks.size() > 3) { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'" + << "; SCP must have at most 3 tokens" << endl + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + istringstream tmpMax(ctoks[1]); + tmpMax >> penScMax; + istringstream tmpMin(ctoks[1]); + tmpMin >> penScMin; + if(penScMin > penScMax) { + cerr << "max (" << penScMax << ") should be >= min (" << penScMin << ")" << endl; + assert(false); throw 1; + } + if(penScMin < 1) { + cerr << "min (" << penScMin << ") should be greater than 0" << endl; + assert(false); throw 1; + } + } + // Scoring for mismatches where read char=N + // NP={Cxx|Q|RQ} + // Cxx = constant, where constant is integer xx + // Q = equal to quality + // R = equal to maq-rounded quality value (rounded to nearest + // 10, can't be greater than 30) + else if(tag == "NP") { + if(ctoks.size() != 1) { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'" + << "; RHS must have 1 token" << endl + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + if(ctoks[0][0] == 'C') { + string tmp = ctoks[0].substr(1); + // Parse constant penalty + istringstream tmpss(tmp); + tmpss >> penN; + // Parse constant penalty + penNType = COST_MODEL_CONSTANT; + } else if(ctoks[0][0] == 'Q') { + // Set type to =quality + penNType = COST_MODEL_QUAL; + } else if(ctoks[0][0] == 'R') { + // Set type to=Maq-quality + penNType = COST_MODEL_ROUNDED_QUAL; + } else { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'" + << "; RHS must start with C, Q or R" << endl + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + } + // Scoring for read gaps + // RDG=xx,yy,zz + // xx = read gap open penalty + // yy = read gap extension penalty constant coefficient + // (defaults to open penalty) + // zz = read gap extension penalty linear coefficient + // (defaults to 0) + else if(tag == "RDG") { + if(ctoks.size() >= 1) { + istringstream tmpss(ctoks[0]); + tmpss >> penRdExConst; + } else { + penRdExConst = noisyHpolymer ? + DEFAULT_READ_GAP_CONST_BADHPOLY : + DEFAULT_READ_GAP_CONST; + } + if(ctoks.size() >= 2) { + istringstream tmpss(ctoks[1]); + tmpss >> penRdExLinear; + } else { + penRdExLinear = noisyHpolymer ? + DEFAULT_READ_GAP_LINEAR_BADHPOLY : + DEFAULT_READ_GAP_LINEAR; + } + } + // Scoring for reference gaps + // RFG=xx,yy,zz + // xx = ref gap open penalty + // yy = ref gap extension penalty constant coefficient + // (defaults to open penalty) + // zz = ref gap extension penalty linear coefficient + // (defaults to 0) + else if(tag == "RFG") { + if(ctoks.size() >= 1) { + istringstream tmpss(ctoks[0]); + tmpss >> penRfExConst; + } else { + penRfExConst = noisyHpolymer ? + DEFAULT_REF_GAP_CONST_BADHPOLY : + DEFAULT_REF_GAP_CONST; + } + if(ctoks.size() >= 2) { + istringstream tmpss(ctoks[1]); + tmpss >> penRfExLinear; + } else { + penRfExLinear = noisyHpolymer ? + DEFAULT_REF_GAP_LINEAR_BADHPOLY : + DEFAULT_REF_GAP_LINEAR; + } + } + // Minimum score as a function of read length + // MIN=xx,yy + // xx = constant coefficient + // yy = linear coefficient + else if(tag == "MIN") { + PARSE_FUNC(costMin); + } + // Per-read N ceiling as a function of read length + // NCEIL=xx,yy + // xx = N ceiling constant coefficient + // yy = N ceiling linear coefficient (set to 0 if unspecified) + else if(tag == "NCEIL") { + PARSE_FUNC(nCeil); + } + /* + * Seeds + * ----- + * + * SEED=mm,len,ival (default: SEED=0,22) + * + * mm = Maximum number of mismatches allowed within a seed. + * Must be >= 0 and <= 2. Note that 2-mismatch mode is + * not fully sensitive; i.e. some 2-mismatch seed + * alignments may be missed. + * len = Length of seed. + * ival = Interval between seeds. If not specified, seed + * interval is determined by IVAL. + */ + else if(tag == "SEED") { + if(ctoks.size() > 2) { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'; RHS must have 1 or 2 tokens, " + << "had " << ctoks.size() << ". " + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + if(ctoks.size() >= 1) { + istringstream tmpss(ctoks[0]); + tmpss >> multiseedMms; + if(multiseedMms > 1) { + cerr << "Error: -N was set to " << multiseedMms << ", but cannot be set greater than 1" << endl; + throw 1; + } + if(multiseedMms < 0) { + cerr << "Error: -N was set to a number less than 0 (" << multiseedMms << ")" << endl; + throw 1; + } + } + if(ctoks.size() >= 2) { + istringstream tmpss(ctoks[1]); + tmpss >> multiseedLen; + } else { + multiseedLen = DEFAULT_SEEDLEN; + } + } + else if(tag == "SEEDLEN") { + if(ctoks.size() > 1) { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'; RHS must have 1 token, " + << "had " << ctoks.size() << ". " + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + if(ctoks.size() >= 1) { + istringstream tmpss(ctoks[0]); + tmpss >> multiseedLen; + } + } + else if(tag == "DPS") { + if(ctoks.size() > 1) { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'; RHS must have 1 token, " + << "had " << ctoks.size() << ". " + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + if(ctoks.size() >= 1) { + istringstream tmpss(ctoks[0]); + tmpss >> failStreak; + } + } + else if(tag == "ROUNDS") { + if(ctoks.size() > 1) { + cerr << "Error parsing alignment policy setting " + << "'" << tag.c_str() << "'; RHS must have 1 token, " + << "had " << ctoks.size() << ". " + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + if(ctoks.size() >= 1) { + istringstream tmpss(ctoks[0]); + tmpss >> seedRounds; + } + } + /* + * Seed interval + * ------------- + * + * IVAL={L|S|C},a,b (default: IVAL=S,1.0,0.0) + * + * L = let interval between seeds be a linear function of the + * read length. xx and yy are the constant and linear + * coefficients respectively. In other words, the interval + * equals a * len + b, where len is the read length. + * Intervals less than 1 are rounded up to 1. + * S = let interval between seeds be a function of the sqaure + * root of the read length. xx and yy are the + * coefficients. In other words, the interval equals + * a * sqrt(len) + b, where len is the read length. + * Intervals less than 1 are rounded up to 1. + * C = Like S but uses cube root of length instead of square + * root. + */ + else if(tag == "IVAL") { + PARSE_FUNC(multiseedIval); + } + else if(tag == "CANINTRONLEN") { + assert(penCanIntronLen != NULL); + PARSE_FUNC((*penCanIntronLen)); + } + else if(tag == "NONCANINTRONLEN") { + assert(penNoncanIntronLen != NULL); + PARSE_FUNC((*penNoncanIntronLen)); + } + else { + // Unknown tag + cerr << "Unexpected alignment policy setting " + << "'" << tag.c_str() << "'" << endl + << "Policy: '" << s.c_str() << "'" << endl; + assert(false); throw 1; + } + } +} + +#ifdef ALIGNER_SEED_POLICY_MAIN +int main() { + + int bonusMatchType; + int bonusMatch; + int penMmcType; + int penMmc; + int penScMax; + int penScMin; + int penNType; + int penN; + int penRdExConst; + int penRfExConst; + int penRdExLinear; + int penRfExLinear; + SimpleFunc costMin; + SimpleFunc costFloor; + SimpleFunc nCeil; + bool nCatPair; + int multiseedMms; + int multiseedLen; + SimpleFunc msIval; + SimpleFunc posfrac; + SimpleFunc rowmult; + uint32_t mhits; + + { + cout << "Case 1: Defaults 1 ... "; + const char *pol = ""; + SeedAlignmentPolicy::parseString( + string(pol), + false, // --local? + false, // noisy homopolymers a la 454? + false, // ignore qualities? + bonusMatchType, + bonusMatch, + penMmcType, + penMmc, + penScMax, + penScMin, + penNType, + penN, + penRdExConst, + penRfExConst, + penRdExLinear, + penRfExLinear, + costMin, + costFloor, + nCeil, + nCatPair, + multiseedMms, + multiseedLen, + msIval, + mhits); + + assert_eq(DEFAULT_MATCH_BONUS_TYPE, bonusMatchType); + assert_eq(DEFAULT_MATCH_BONUS, bonusMatch); + assert_eq(DEFAULT_MM_PENALTY_TYPE, penMmcType); + assert_eq(DEFAULT_MM_PENALTY_MAX, penMmcMax); + assert_eq(DEFAULT_MM_PENALTY_MIN, penMmcMin); + assert_eq(DEFAULT_N_PENALTY_TYPE, penNType); + assert_eq(DEFAULT_N_PENALTY, penN); + assert_eq(DEFAULT_MIN_CONST, costMin.getConst()); + assert_eq(DEFAULT_MIN_LINEAR, costMin.getCoeff()); + assert_eq(DEFAULT_FLOOR_CONST, costFloor.getConst()); + assert_eq(DEFAULT_FLOOR_LINEAR, costFloor.getCoeff()); + assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst()); + assert_eq(DEFAULT_N_CAT_PAIR, nCatPair); + + assert_eq(DEFAULT_READ_GAP_CONST, penRdExConst); + assert_eq(DEFAULT_READ_GAP_LINEAR, penRdExLinear); + assert_eq(DEFAULT_REF_GAP_CONST, penRfExConst); + assert_eq(DEFAULT_REF_GAP_LINEAR, penRfExLinear); + assert_eq(DEFAULT_SEEDMMS, multiseedMms); + assert_eq(DEFAULT_SEEDLEN, multiseedLen); + assert_eq(DEFAULT_IVAL, msIval.getType()); + assert_eq(DEFAULT_IVAL_A, msIval.getCoeff()); + assert_eq(DEFAULT_IVAL_B, msIval.getConst()); + + cout << "PASSED" << endl; + } + + { + cout << "Case 2: Defaults 2 ... "; + const char *pol = ""; + SeedAlignmentPolicy::parseString( + string(pol), + false, // --local? + true, // noisy homopolymers a la 454? + false, // ignore qualities? + bonusMatchType, + bonusMatch, + penMmcType, + penMmc, + + penNType, + penN, + penRdExConst, + penRfExConst, + penRdExLinear, + penRfExLinear, + costMin, + costFloor, + nCeil, + nCatPair, + multiseedMms, + multiseedLen, + msIval, + mhits); + + assert_eq(DEFAULT_MATCH_BONUS_TYPE, bonusMatchType); + assert_eq(DEFAULT_MATCH_BONUS, bonusMatch); + assert_eq(DEFAULT_MM_PENALTY_TYPE, penMmcType); + assert_eq(DEFAULT_MM_PENALTY_MAX, penMmc); + assert_eq(DEFAULT_MM_PENALTY_MIN, penMmc); + assert_eq(DEFAULT_N_PENALTY_TYPE, penNType); + assert_eq(DEFAULT_N_PENALTY, penN); + assert_eq(DEFAULT_MIN_CONST, costMin.getConst()); + assert_eq(DEFAULT_MIN_LINEAR, costMin.getCoeff()); + assert_eq(DEFAULT_FLOOR_CONST, costFloor.getConst()); + assert_eq(DEFAULT_FLOOR_LINEAR, costFloor.getCoeff()); + assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst()); + assert_eq(DEFAULT_N_CAT_PAIR, nCatPair); + + assert_eq(DEFAULT_READ_GAP_CONST_BADHPOLY, penRdExConst); + assert_eq(DEFAULT_READ_GAP_LINEAR_BADHPOLY, penRdExLinear); + assert_eq(DEFAULT_REF_GAP_CONST_BADHPOLY, penRfExConst); + assert_eq(DEFAULT_REF_GAP_LINEAR_BADHPOLY, penRfExLinear); + assert_eq(DEFAULT_SEEDMMS, multiseedMms); + assert_eq(DEFAULT_SEEDLEN, multiseedLen); + assert_eq(DEFAULT_IVAL, msIval.getType()); + assert_eq(DEFAULT_IVAL_A, msIval.getCoeff()); + assert_eq(DEFAULT_IVAL_B, msIval.getConst()); + + cout << "PASSED" << endl; + } + + { + cout << "Case 3: Defaults 3 ... "; + const char *pol = ""; + SeedAlignmentPolicy::parseString( + string(pol), + true, // --local? + false, // noisy homopolymers a la 454? + false, // ignore qualities? + bonusMatchType, + bonusMatch, + penMmcType, + penMmc, + penNType, + penN, + penRdExConst, + penRfExConst, + penRdExLinear, + penRfExLinear, + costMin, + costFloor, + nCeil, + nCatPair, + multiseedMms, + multiseedLen, + msIval, + mhits); + + assert_eq(DEFAULT_MATCH_BONUS_TYPE_LOCAL, bonusMatchType); + assert_eq(DEFAULT_MATCH_BONUS_LOCAL, bonusMatch); + assert_eq(DEFAULT_MM_PENALTY_TYPE, penMmcType); + assert_eq(DEFAULT_MM_PENALTY_MAX, penMmcMax); + assert_eq(DEFAULT_MM_PENALTY_MIN, penMmcMin); + assert_eq(DEFAULT_N_PENALTY_TYPE, penNType); + assert_eq(DEFAULT_N_PENALTY, penN); + assert_eq(DEFAULT_MIN_CONST_LOCAL, costMin.getConst()); + assert_eq(DEFAULT_MIN_LINEAR_LOCAL, costMin.getCoeff()); + assert_eq(DEFAULT_FLOOR_CONST_LOCAL, costFloor.getConst()); + assert_eq(DEFAULT_FLOOR_LINEAR_LOCAL, costFloor.getCoeff()); + assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst()); + assert_eq(DEFAULT_N_CEIL_LINEAR, nCeil.getCoeff()); + assert_eq(DEFAULT_N_CAT_PAIR, nCatPair); + + assert_eq(DEFAULT_READ_GAP_CONST, penRdExConst); + assert_eq(DEFAULT_READ_GAP_LINEAR, penRdExLinear); + assert_eq(DEFAULT_REF_GAP_CONST, penRfExConst); + assert_eq(DEFAULT_REF_GAP_LINEAR, penRfExLinear); + assert_eq(DEFAULT_SEEDMMS, multiseedMms); + assert_eq(DEFAULT_SEEDLEN, multiseedLen); + assert_eq(DEFAULT_IVAL, msIval.getType()); + assert_eq(DEFAULT_IVAL_A, msIval.getCoeff()); + assert_eq(DEFAULT_IVAL_B, msIval.getConst()); + + cout << "PASSED" << endl; + } + + { + cout << "Case 4: Simple string 1 ... "; + const char *pol = "MMP=C44;MA=4;RFG=24,12;FL=C,8;RDG=2;NP=C4;MIN=C,7"; + SeedAlignmentPolicy::parseString( + string(pol), + true, // --local? + false, // noisy homopolymers a la 454? + false, // ignore qualities? + bonusMatchType, + bonusMatch, + penMmcType, + penMmc, + penNType, + penN, + penRdExConst, + penRfExConst, + penRdExLinear, + penRfExLinear, + costMin, + costFloor, + nCeil, + nCatPair, + multiseedMms, + multiseedLen, + msIval, + mhits); + + assert_eq(COST_MODEL_CONSTANT, bonusMatchType); + assert_eq(4, bonusMatch); + assert_eq(COST_MODEL_CONSTANT, penMmcType); + assert_eq(44, penMmc); + assert_eq(COST_MODEL_CONSTANT, penNType); + assert_eq(4.0f, penN); + assert_eq(7, costMin.getConst()); + assert_eq(DEFAULT_MIN_LINEAR_LOCAL, costMin.getCoeff()); + assert_eq(8, costFloor.getConst()); + assert_eq(DEFAULT_FLOOR_LINEAR_LOCAL, costFloor.getCoeff()); + assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst()); + assert_eq(DEFAULT_N_CEIL_LINEAR, nCeil.getCoeff()); + assert_eq(DEFAULT_N_CAT_PAIR, nCatPair); + + assert_eq(2.0f, penRdExConst); + assert_eq(DEFAULT_READ_GAP_LINEAR, penRdExLinear); + assert_eq(24.0f, penRfExConst); + assert_eq(12.0f, penRfExLinear); + assert_eq(DEFAULT_SEEDMMS, multiseedMms); + assert_eq(DEFAULT_SEEDLEN, multiseedLen); + assert_eq(DEFAULT_IVAL, msIval.getType()); + assert_eq(DEFAULT_IVAL_A, msIval.getCoeff()); + assert_eq(DEFAULT_IVAL_B, msIval.getConst()); + + cout << "PASSED" << endl; + } +} +#endif /*def ALIGNER_SEED_POLICY_MAIN*/ diff --git a/aligner_seed_policy.h b/aligner_seed_policy.h new file mode 100644 index 0000000..b8d7fc6 --- /dev/null +++ b/aligner_seed_policy.h @@ -0,0 +1,234 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_SEED_POLICY_H_ +#define ALIGNER_SEED_POLICY_H_ + +#include "scoring.h" +#include "simple_func.h" + +#define DEFAULT_SEEDMMS 0 +#define DEFAULT_SEEDLEN 22 + +#define DEFAULT_IVAL SIMPLE_FUNC_SQRT +#define DEFAULT_IVAL_A 1.15f +#define DEFAULT_IVAL_B 0.0f + +#define DEFAULT_UNGAPPED_HITS 6 + +/** + * Encapsulates the set of all parameters that affect what the + * SeedAligner does with reads. + */ +class SeedAlignmentPolicy { + +public: + + /** + * Parse alignment policy when provided in this format: + * =;=;=... + * + * And label=value possibilities are: + * + * Bonus for a match + * ----------------- + * + * MA=xx (default: MA=0, or MA=2 if --local is set) + * + * xx = Each position where equal read and reference characters match up + * in the alignment contriubtes this amount to the total score. + * + * Penalty for a mismatch + * ---------------------- + * + * MMP={Cxx|Q|RQ} (default: MMP=C6) + * + * Cxx = Each mismatch costs xx. If MMP=Cxx is specified, quality + * values are ignored when assessing penalities for mismatches. + * Q = Each mismatch incurs a penalty equal to the mismatched base's + * value. + * R = Each mismatch incurs a penalty equal to the mismatched base's + * rounded quality value. Qualities are rounded off to the + * nearest 10, and qualities greater than 30 are rounded to 30. + * + * Penalty for position with N (in either read or reference) + * --------------------------------------------------------- + * + * NP={Cxx|Q|RQ} (default: NP=C1) + * + * Cxx = Each alignment position with an N in either the read or the + * reference costs xx. If NP=Cxx is specified, quality values are + * ignored when assessing penalities for Ns. + * Q = Each alignment position with an N in either the read or the + * reference incurs a penalty equal to the read base's quality + * value. + * R = Each alignment position with an N in either the read or the + * reference incurs a penalty equal to the read base's rounded + * quality value. Qualities are rounded off to the nearest 10, + * and qualities greater than 30 are rounded to 30. + * + * Penalty for a read gap + * ---------------------- + * + * RDG=xx,yy (default: RDG=5,3) + * + * xx = Read gap open penalty. + * yy = Read gap extension penalty. + * + * Total cost incurred by a read gap = xx + (yy * gap length) + * + * Penalty for a reference gap + * --------------------------- + * + * RFG=xx,yy (default: RFG=5,3) + * + * xx = Reference gap open penalty. + * yy = Reference gap extension penalty. + * + * Total cost incurred by a reference gap = xx + (yy * gap length) + * + * Minimum score for valid alignment + * --------------------------------- + * + * MIN=xx,yy (defaults: MIN=-0.6,-0.6, or MIN=0.0,0.66 if --local is set) + * + * xx,yy = For a read of length N, the total score must be at least + * xx + (read length * yy) for the alignment to be valid. The + * total score is the sum of all negative penalties (from + * mismatches and gaps) and all positive bonuses. The minimum + * can be negative (and is by default in global alignment mode). + * + * N ceiling + * --------- + * + * NCEIL=xx,yy (default: NCEIL=0.0,0.15) + * + * xx,yy = For a read of length N, the number of alignment + * positions with an N in either the read or the + * reference cannot exceed + * ceiling = xx + (read length * yy). If the ceiling is + * exceeded, the alignment is considered invalid. + * + * Seeds + * ----- + * + * SEED=mm,len,ival (default: SEED=0,22) + * + * mm = Maximum number of mismatches allowed within a seed. + * Must be >= 0 and <= 2. Note that 2-mismatch mode is + * not fully sensitive; i.e. some 2-mismatch seed + * alignments may be missed. + * len = Length of seed. + * ival = Interval between seeds. If not specified, seed + * interval is determined by IVAL. + * + * Seed interval + * ------------- + * + * IVAL={L|S|C},xx,yy (default: IVAL=S,1.0,0.0) + * + * L = let interval between seeds be a linear function of the + * read length. xx and yy are the constant and linear + * coefficients respectively. In other words, the interval + * equals a * len + b, where len is the read length. + * Intervals less than 1 are rounded up to 1. + * S = let interval between seeds be a function of the sqaure + * root of the read length. xx and yy are the + * coefficients. In other words, the interval equals + * a * sqrt(len) + b, where len is the read length. + * Intervals less than 1 are rounded up to 1. + * C = Like S but uses cube root of length instead of square + * root. + * + * Example 1: + * + * SEED=1,10,5 and read sequence is TGCTATCGTACGATCGTAC: + * + * The following seeds are extracted from the forward + * representation of the read and aligned to the reference + * allowing up to 1 mismatch: + * + * Read: TGCTATCGTACGATCGTACA + * + * Seed 1+: TGCTATCGTA + * Seed 2+: TCGTACGATC + * Seed 3+: CGATCGTACA + * + * ...and the following are extracted from the reverse-complement + * representation of the read and align to the reference allowing + * up to 1 mismatch: + * + * Seed 1-: TACGATAGCA + * Seed 2-: GATCGTACGA + * Seed 3-: TGTACGATCG + * + * Example 2: + * + * SEED=1,20,20 and read sequence is TGCTATCGTACGATC. The seed + * length is 20 but the read is only 15 characters long. In this + * case, Bowtie2 automatically shrinks the seed length to be equal + * to the read length. + * + * Read: TGCTATCGTACGATC + * + * Seed 1+: TGCTATCGTACGATC + * Seed 1-: GATCGTACGATAGCA + * + * Example 3: + * + * SEED=1,10,10 and read sequence is TGCTATCGTACGATC. Only one seed + * fits on the read; a second seed would overhang the end of the read + * by 5 positions. In this case, Bowtie2 extracts one seed. + * + * Read: TGCTATCGTACGATC + * + * Seed 1+: TGCTATCGTA + * Seed 1-: TACGATAGCA + */ + static void parseString( + const std::string& s, + bool local, + bool noisyHpolymer, + bool ignoreQuals, + int& bonusMatchType, + int& bonusMatch, + int& penMmcType, + int& penMmcMax, + int& penMmcMin, + int& penScMax, + int& penScMin, + int& penNType, + int& penN, + int& penRdExConst, + int& penRfExConst, + int& penRdExLinear, + int& penRfExLinear, + SimpleFunc& costMin, + SimpleFunc& nCeil, + bool& nCatPair, + int& multiseedMms, + int& multiseedLen, + SimpleFunc& multiseedIval, + size_t& failStreak, + size_t& seedRounds, + SimpleFunc* penCanIntronLen = NULL, + SimpleFunc* penNoncanIntronLen = NULL); +}; + +#endif /*ndef ALIGNER_SEED_POLICY_H_*/ diff --git a/aligner_sw.cpp b/aligner_sw.cpp new file mode 100644 index 0000000..9341a35 --- /dev/null +++ b/aligner_sw.cpp @@ -0,0 +1,3214 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +// -- BTL remove -- +//#include +//#include +// -- -- +#include "aligner_sw.h" +#include "aligner_result.h" +#include "search_globals.h" +#include "scoring.h" +#include "mask.h" + +/** + * Initialize with a new read. + */ +void SwAligner::initRead( + const BTDnaString& rdfw, // forward read sequence + const BTDnaString& rdrc, // revcomp read sequence + const BTString& qufw, // forward read qualities + const BTString& qurc, // reverse read qualities + size_t rdi, // offset of first read char to align + size_t rdf, // offset of last read char to align + const Scoring& sc) // scoring scheme +{ + assert_gt(rdf, rdi); + int nceil = sc.nCeil.f((double)rdfw.length()); + rdfw_ = &rdfw; // read sequence + rdrc_ = &rdrc; // read sequence + qufw_ = &qufw; // read qualities + qurc_ = &qurc; // read qualities + rdi_ = rdi; // offset of first read char to align + rdf_ = rdf; // offset of last read char to align + sc_ = ≻ // scoring scheme + nceil_ = nceil; // max # Ns allowed in ref portion of aln + readSse16_ = false; // true -> sse16 from now on for this read + initedRead_ = true; +#ifndef NO_SSE + sseU8fwBuilt_ = false; // built fw query profile, 8-bit score + sseU8rcBuilt_ = false; // built rc query profile, 8-bit score + sseI16fwBuilt_ = false; // built fw query profile, 16-bit score + sseI16rcBuilt_ = false; // built rc query profile, 16-bit score +#endif +} + +/** + * Initialize with a new alignment problem. + */ +void SwAligner::initRef( + bool fw, // whether to forward or revcomp read is aligning + TRefId refidx, // id of reference aligned against + const DPRect& rect, // DP rectangle + char *rf, // reference sequence + size_t rfi, // offset of first reference char to align to + size_t rff, // offset of last reference char to align to + TRefOff reflen, // length of reference sequence + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + bool enable8, // use 8-bit SSE if possible? + size_t cminlen, // minimum length for using checkpointing scheme + size_t cpow2, // interval b/t checkpointed diags; 1 << this + bool doTri, // triangular mini-fills? + bool extend) // is this a seed extension? +{ + size_t readGaps = sc.maxReadGaps(minsc, rdfw_->length()); + size_t refGaps = sc.maxRefGaps(minsc, rdfw_->length()); + assert_geq(readGaps, 0); + assert_geq(refGaps, 0); + assert_gt(rff, rfi); + rdgap_ = readGaps; // max # gaps in read + rfgap_ = refGaps; // max # gaps in reference + state_ = STATE_INITED; + fw_ = fw; // orientation + rd_ = fw ? rdfw_ : rdrc_; // read sequence + qu_ = fw ? qufw_ : qurc_; // quality sequence + refidx_ = refidx; // id of reference aligned against + rf_ = rf; // reference sequence + rfi_ = rfi; // offset of first reference char to align to + rff_ = rff; // offset of last reference char to align to + reflen_ = reflen; // length of entire reference sequence + rect_ = ▭ // DP rectangle + minsc_ = minsc; // minimum score + cural_ = 0; // idx of next alignment to give out + initedRef_ = true; // indicate we've initialized the ref portion + enable8_ = enable8; // use 8-bit SSE if possible? + extend_ = extend; // true iff this is a seed extension + cperMinlen_ = cminlen; // reads shorter than this won't use checkpointer + cperPerPow2_ = cpow2; // interval b/t checkpointed diags; 1 << this + cperEf_ = true; // whether to checkpoint H, E, and F + cperTri_ = doTri; // triangular mini-fills? + bter_.initRef( + fw_ ? rdfw_->buf() : // in: read sequence + rdrc_->buf(), + fw_ ? qufw_->buf() : // in: quality sequence + qurc_->buf(), + // daehwan + // rd_->length(), // in: read sequence length + rdf_ - rdi_, + rf_ + rfi_, // in: reference sequence + rff_ - rfi_, // in: in-rectangle reference sequence length + reflen, // in: total reference sequence length + refidx_, // in: reference id + rfi_, // in: reference offset + fw_, // in: orientation + rect_, // in: DP rectangle + &cper_, // in: checkpointer + *sc_, // in: scoring scheme + nceil_); // in: N ceiling +} + +/** + * Given a read, an alignment orientation, a range of characters in a referece + * sequence, and a bit-encoded version of the reference, set up and execute the + * corresponding dynamic programming problem. + * + * The caller has already narrowed down the relevant portion of the reference + * using, e.g., the location of a seed hit, or the range of possible fragment + * lengths if we're searching for the opposite mate in a pair. + */ +void SwAligner::initRef( + bool fw, // whether to forward or revcomp read is aligning + TRefId refidx, // reference aligned against + const DPRect& rect, // DP rectangle + const BitPairReference& refs, // Reference strings + TRefOff reflen, // length of reference sequence + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + bool enable8, // use 8-bit SSE if possible? + size_t cminlen, // minimum length for using checkpointing scheme + size_t cpow2, // interval b/t checkpointed diags; 1 << this + bool doTri, // triangular mini-fills? + bool extend, // true iff this is a seed extension + size_t upto, // count the number of Ns up to this offset + size_t& nsUpto) // output: the number of Ns up to 'upto' +{ + TRefOff rfi = rect.refl; + TRefOff rff = rect.refr + 1; + assert_gt(rff, rfi); + // Capture an extra reference character outside the rectangle so that we + // can check matches in the next column over to the right + rff++; + // rflen = full length of the reference substring to consider, including + // overhang off the boundaries of the reference sequence + const size_t rflen = (size_t)(rff - rfi); + // Figure the number of Ns we're going to add to either side + size_t leftNs = + (rfi >= 0 ? 0 : (size_t)std::abs(static_cast(rfi))); + leftNs = min(leftNs, rflen); + size_t rightNs = + (rff <= (TRefOff)reflen ? 0 : (size_t)std::abs(static_cast(rff - reflen))); + rightNs = min(rightNs, rflen); + // rflenInner = length of just the portion that doesn't overhang ref ends + assert_geq(rflen, leftNs + rightNs); + const size_t rflenInner = rflen - (leftNs + rightNs); +#ifndef NDEBUG + bool haveRfbuf2 = false; + EList rfbuf2(rflen); + // This is really slow, so only do it some of the time + if((rand() % 10) == 0) { + TRefOff rfii = rfi; + for(size_t i = 0; i < rflen; i++) { + if(rfii < 0 || (TRefOff)rfii >= reflen) { + rfbuf2.push_back(4); + } else { + rfbuf2.push_back(refs.getBase(refidx, (uint32_t)rfii)); + } + rfii++; + } + haveRfbuf2 = true; + } +#endif + // rfbuf_ = uint32_t list large enough to accommodate both the reference + // sequence and any Ns we might add to either side. + rfwbuf_.resize((rflen + 16) / 4); + int offset = refs.getStretch( + rfwbuf_.ptr(), // buffer to store words in + refidx, // which reference + (rfi < 0) ? 0 : (size_t)rfi, // starting offset (can't be < 0) + rflenInner // length to grab (exclude overhang) + ASSERT_ONLY(, tmp_destU32_));// for BitPairReference::getStretch() + assert_leq(offset, 16); + rf_ = (char*)rfwbuf_.ptr() + offset; + // Shift ref chars away from 0 so we can stick Ns at the beginning + if(leftNs > 0) { + // Slide everyone down + for(size_t i = rflenInner; i > 0; i--) { + rf_[i+leftNs-1] = rf_[i-1]; + } + // Add Ns + for(size_t i = 0; i < leftNs; i++) { + rf_[i] = 4; + } + } + if(rightNs > 0) { + // Add Ns to the end + for(size_t i = 0; i < rightNs; i++) { + rf_[i + leftNs + rflenInner] = 4; + } + } +#ifndef NDEBUG + // Sanity check reference characters + for(size_t i = 0; i < rflen; i++) { + assert(!haveRfbuf2 || rf_[i] == rfbuf2[i]); + assert_range(0, 4, (int)rf_[i]); + } +#endif + // Count Ns and convert reference characters into A/C/G/T masks. Ambiguous + // nucleotides (IUPAC codes) have more than one mask bit set. If a + // reference scanner was provided, use it to opportunistically resolve seed + // hits. + nsUpto = 0; + for(size_t i = 0; i < rflen; i++) { + // rf_[i] gets mask version of refence char, with N=16 + if(i < upto && rf_[i] > 3) { + nsUpto++; + } + rf_[i] = (1 << rf_[i]); + } + // Correct for having captured an extra reference character + rff--; + initRef( + fw, // whether to forward or revcomp read is aligning + refidx, // id of reference aligned against + rect, // DP rectangle + rf_, // reference sequence, wrapped up in BTString object + 0, // use the whole thing + (size_t)(rff - rfi), // ditto + reflen, // reference length + sc, // scoring scheme + minsc, // minimum score + enable8, // use 8-bit SSE if possible? + cminlen, // minimum length for using checkpointing scheme + cpow2, // interval b/t checkpointed diags; 1 << this + doTri, // triangular mini-fills? + extend); // true iff this is a seed extension +} + +/** + * Given a read, an alignment orientation, a range of characters in a referece + * sequence, and a bit-encoded version of the reference, set up and execute the + * corresponding ungapped alignment problem. There can only be one solution. + * + * The caller has already narrowed down the relevant portion of the reference + * using, e.g., the location of a seed hit, or the range of possible fragment + * lengths if we're searching for the opposite mate in a pair. + */ +int SwAligner::ungappedAlign( + const BTDnaString& rd, // read sequence (could be RC) + const BTString& qu, // qual sequence (could be rev) + const Coord& coord, // coordinate aligned to + const BitPairReference& refs, // Reference strings + size_t reflen, // length of reference sequence + const Scoring& sc, // scoring scheme + bool ohang, // allow overhang? + TAlScore minsc, // minimum score + SwResult& res) // put alignment result here +{ + const size_t len = rd.length(); + int nceil = sc.nCeil.f((double)len); + int ns = 0; + TRefOff rfi = coord.off(); + TRefOff rff = rfi + (TRefOff)len; + TRefId refidx = coord.ref(); + assert_gt(rff, rfi); + // Figure the number of Ns we're going to add to either side + size_t leftNs = 0; + if(rfi < 0) { + if(ohang) { + leftNs = (size_t)(-rfi); + } else { + return 0; + } + } + size_t rightNs = 0; + if(rff > (TRefOff)reflen) { + if(ohang) { + rightNs = (size_t)(rff - (TRefOff)reflen); + } else { + return 0; + } + } + if((leftNs + rightNs) > (size_t)nceil) { + return 0; + } + // rflenInner = length of just the portion that doesn't overhang ref ends + assert_geq(len, leftNs + rightNs); + const size_t rflenInner = len - (leftNs + rightNs); +#ifndef NDEBUG + bool haveRfbuf2 = false; + EList rfbuf2(len); + // This is really slow, so only do it some of the time + if((rand() % 10) == 0) { + TRefOff rfii = rfi; + for(size_t i = 0; i < len; i++) { + if(rfii < 0 || (size_t)rfii >= reflen) { + rfbuf2.push_back(4); + } else { + rfbuf2.push_back(refs.getBase(refidx, (uint32_t)rfii)); + } + rfii++; + } + haveRfbuf2 = true; + } +#endif + // rfbuf_ = uint32_t list large enough to accommodate both the reference + // sequence and any Ns we might add to either side. + rfwbuf_.resize((len + 16) / 4); + int offset = refs.getStretch( + rfwbuf_.ptr(), // buffer to store words in + refidx, // which reference + (rfi < 0) ? 0 : (size_t)rfi, // starting offset (can't be < 0) + rflenInner // length to grab (exclude overhang) + ASSERT_ONLY(, tmp_destU32_));// for BitPairReference::getStretch() + assert_leq(offset, 16); + rf_ = (char*)rfwbuf_.ptr() + offset; + // Shift ref chars away from 0 so we can stick Ns at the beginning + if(leftNs > 0) { + // Slide everyone down + for(size_t i = rflenInner; i > 0; i--) { + rf_[i+leftNs-1] = rf_[i-1]; + } + // Add Ns + for(size_t i = 0; i < leftNs; i++) { + rf_[i] = 4; + } + } + if(rightNs > 0) { + // Add Ns to the end + for(size_t i = 0; i < rightNs; i++) { + rf_[i + leftNs + rflenInner] = 4; + } + } +#ifndef NDEBUG + // Sanity check reference characters + for(size_t i = 0; i < len; i++) { + assert(!haveRfbuf2 || rf_[i] == rfbuf2[i]); + assert_range(0, 4, (int)rf_[i]); + } +#endif + // Count Ns and convert reference characters into A/C/G/T masks. Ambiguous + // nucleotides (IUPAC codes) have more than one mask bit set. If a + // reference scanner was provided, use it to opportunistically resolve seed + // hits. + TAlScore score = 0; + res.alres.reset(); + size_t rowi = 0; + size_t rowf = len-1; + if(sc.monotone) { + for(size_t i = 0; i < len; i++) { + // rf_[i] gets mask version of refence char, with N=16 + assert_geq(qu[i], 33); + score += sc.score(rd[i], (int)(1 << rf_[i]), qu[i] - 33, ns); + assert_leq(score, 0); + if(score < minsc || ns > nceil) { + // Fell below threshold + return 0; + } + } + // Got a result! Fill in the rest of the result object. + } else { + // Definitely ways to short-circuit this. E.g. if diff between cur + // score and minsc can't be met by matches. + TAlScore floorsc = 0; + TAlScore scoreMax = floorsc; + size_t lastfloor = 0; + rowi = MAX_SIZE_T; + size_t sols = 0; + for(size_t i = 0; i < len; i++) { + score += sc.score(rd[i], (int)(1 << rf_[i]), qu[i] - 33, ns); + if(score >= minsc && score >= scoreMax) { + scoreMax = score; + rowf = i; + if(rowi != lastfloor) { + rowi = lastfloor; + sols++; + } + } + if(score <= floorsc) { + score = floorsc; + lastfloor = i+1; + } + } + if(ns > nceil || scoreMax < minsc) { + // Too many Ns + return 0; + } + if(sols > 1) { + // >1 distinct solution in this diag; defer to DP aligner + return -1; + } + score = scoreMax; + // Got a result! Fill in the rest of the result object. + } + // Now fill in the edits + res.alres.setScore(AlnScore(score, ns, 0)); + assert_geq(rowf, rowi); + EList& ned = res.alres.ned(); + size_t refns = 0; + ASSERT_ONLY(BTDnaString refstr); + for(size_t i = rowi; i <= rowf; i++) { + ASSERT_ONLY(refstr.append((int)rf_[i])); + if(rf_[i] > 3 || rd[i] != rf_[i]) { + // Add edit + Edit e((int)i, + mask2dna[1 << (int)rf_[i]], + "ACGTN"[(int)rd[i]], + EDIT_TYPE_MM); + ned.push_back(e); + if(rf_[i] > 3) { + refns++; + } + } + } + assert(Edit::repOk(ned, rd)); + bool fw = coord.fw(); + assert_leq(rowf, len-1); + size_t trimEnd = (len-1) - rowf; + res.alres.setShape( + coord.ref(), // ref id + coord.off()+rowi, // 0-based ref offset + reflen, // length of reference sequence aligned to + fw, // aligned to Watson? + len, // read length + 0, // read ID + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + fw ? rowi : trimEnd, // alignment trim 5' end + fw ? trimEnd : rowi); // alignment trim 3' end + res.alres.setRefNs(refns); + assert(res.repOk()); +#ifndef NDEBUG + BTDnaString editstr; + Edit::toRef(rd, ned, editstr, true, rowi, trimEnd); + if(refstr != editstr) { + cerr << "Decoded nucleotides and edits don't match reference:" << endl; + cerr << " score: " << res.alres.score().score() << endl; + cerr << " edits: "; + Edit::print(cerr, ned); + cerr << endl; + cerr << " decoded nucs: " << rd << endl; + cerr << " edited nucs: " << editstr << endl; + cerr << " reference nucs: " << refstr << endl; + assert(0); + } +#endif + if(!fw) { + // All edits are currently w/r/t upstream end; if read aligned to Crick + // strand, invert them to be w/r/t 5' end instead. + res.alres.invertEdits(); + } + return 1; +} + +/** + * Align read 'rd' to reference using read & reference information given + * last time init() was called. + */ +bool SwAligner::align( + RandomSource& rnd, // source of pseudo-randoms + TAlScore& best) // best alignment score observed in DP matrix +{ + assert(initedRef() && initedRead()); + assert_eq(STATE_INITED, state_); + state_ = STATE_ALIGNED; + // Reset solutions lists + btncand_.clear(); + btncanddone_.clear(); + btncanddoneSucc_ = btncanddoneFail_ = 0; + best = std::numeric_limits::min(); + sse8succ_ = sse16succ_ = false; + int flag = 0; + size_t rdlen = rdf_ - rdi_; + bool checkpointed = rdlen >= cperMinlen_; + bool gathered = false; // Did gathering happen along with alignment? + if(sc_->monotone) { + // End-to-end + if(enable8_ && !readSse16_ && minsc_ >= -254) { + // 8-bit end-to-end + if(checkpointed) { + best = alignGatherEE8(flag, false); + if(flag == 0) { + gathered = true; + } + } else { + best = alignNucleotidesEnd2EndSseU8(flag, false); +#ifndef NDEBUG + int flagtmp = 0; + TAlScore besttmp = alignGatherEE8(flagtmp, true); // debug + assert_eq(flagtmp, flag); + assert_eq(besttmp, best); +#endif + } + sse8succ_ = (flag == 0); +#ifndef NDEBUG + { + int flag2 = 0; + TAlScore best2 = alignNucleotidesEnd2EndSseI16(flag2, true); + { + int flagtmp = 0; + TAlScore besttmp = alignGatherEE16(flagtmp, true); + assert_eq(flagtmp, flag2); + assert(flag2 != 0 || best2 == besttmp); + } + assert(flag < 0 || best == best2); + sse16succ_ = (flag2 == 0); + } +#endif /*ndef NDEBUG*/ + } else { + // 16-bit end-to-end + if(checkpointed) { + best = alignGatherEE16(flag, false); + if(flag == 0) { + gathered = true; + } + } else { + best = alignNucleotidesEnd2EndSseI16(flag, false); +#ifndef NDEBUG + int flagtmp = 0; + TAlScore besttmp = alignGatherEE16(flagtmp, true); + assert_eq(flagtmp, flag); + assert_eq(besttmp, best); +#endif + } + sse16succ_ = (flag == 0); + } + } else { + // Local + flag = -2; + if(enable8_ && !readSse16_) { + // 8-bit local + if(checkpointed) { + best = alignGatherLoc8(flag, false); + if(flag == 0) { + gathered = true; + } + } else { + best = alignNucleotidesLocalSseU8(flag, false); +#ifndef NDEBUG + int flagtmp = 0; + TAlScore besttmp = alignGatherLoc8(flagtmp, true); + assert_eq(flag, flagtmp); + assert_eq(best, besttmp); +#endif + } + } + if(flag == -2) { + // 16-bit local + flag = 0; + if(checkpointed) { + best = alignNucleotidesLocalSseI16(flag, false); + best = alignGatherLoc16(flag, false); + if(flag == 0) { + gathered = true; + } + } else { + best = alignNucleotidesLocalSseI16(flag, false); +#ifndef NDEBUG + int flagtmp = 0; + TAlScore besttmp = alignGatherLoc16(flagtmp, true); + assert_eq(flag, flagtmp); + assert_eq(best, besttmp); +#endif + } + sse16succ_ = (flag == 0); + } else { + sse8succ_ = (flag == 0); +#ifndef NDEBUG + int flag2 = 0; + TAlScore best2 = alignNucleotidesLocalSseI16(flag2, true); + { + int flagtmp = 0; + TAlScore besttmp = alignGatherLoc16(flagtmp, true); + assert_eq(flag2, flagtmp); + assert(flag2 != 0 || best2 == besttmp); + } + assert(flag2 < 0 || best == best2); + sse16succ_ = (flag2 == 0); +#endif /*ndef NDEBUG*/ + } + } +#ifndef NDEBUG + if(!checkpointed && (rand() & 15) == 0 && sse8succ_ && sse16succ_) { + SSEData& d8 = fw_ ? sseU8fw_ : sseU8rc_; + SSEData& d16 = fw_ ? sseI16fw_ : sseI16rc_; + assert_eq(d8.mat_.nrow(), d16.mat_.nrow()); + assert_eq(d8.mat_.ncol(), d16.mat_.ncol()); + for(size_t i = 0; i < d8.mat_.nrow(); i++) { + for(size_t j = 0; j < colstop_; j++) { + int h8 = d8.mat_.helt(i, j); + int h16 = d16.mat_.helt(i, j); + int e8 = d8.mat_.eelt(i, j); + int e16 = d16.mat_.eelt(i, j); + int f8 = d8.mat_.felt(i, j); + int f16 = d16.mat_.felt(i, j); + TAlScore h8s = + (sc_->monotone ? (h8 - 0xff ) : h8); + TAlScore h16s = + (sc_->monotone ? (h16 - 0x7fff) : (h16 + 0x8000)); + TAlScore e8s = + (sc_->monotone ? (e8 - 0xff ) : e8); + TAlScore e16s = + (sc_->monotone ? (e16 - 0x7fff) : (e16 + 0x8000)); + TAlScore f8s = + (sc_->monotone ? (f8 - 0xff ) : f8); + TAlScore f16s = + (sc_->monotone ? (f16 - 0x7fff) : (f16 + 0x8000)); + if(h8s < minsc_) { + h8s = minsc_ - 1; + } + if(h16s < minsc_) { + h16s = minsc_ - 1; + } + if(e8s < minsc_) { + e8s = minsc_ - 1; + } + if(e16s < minsc_) { + e16s = minsc_ - 1; + } + if(f8s < minsc_) { + f8s = minsc_ - 1; + } + if(f16s < minsc_) { + f16s = minsc_ - 1; + } + if((h8 != 0 || (int16_t)h16 != (int16_t)0x8000) && h8 > 0) { + assert_eq(h8s, h16s); + } + if((e8 != 0 || (int16_t)e16 != (int16_t)0x8000) && e8 > 0) { + assert_eq(e8s, e16s); + } + if((f8 != 0 || (int16_t)f16 != (int16_t)0x8000) && f8 > 0) { + assert_eq(f8s, f16s); + } + } + } + } +#endif + assert(repOk()); + cural_ = 0; + if(best == MIN_I64 || best < minsc_) { + return false; + } + if(!gathered) { + // Look for solutions using SSE matrix + assert(sse8succ_ || sse16succ_); + if(sc_->monotone) { + if(sse8succ_) { + gatherCellsNucleotidesEnd2EndSseU8(best); +#ifndef NDEBUG + if(sse16succ_) { + cand_tmp_ = btncand_; + gatherCellsNucleotidesEnd2EndSseI16(best); + cand_tmp_.sort(); + btncand_.sort(); + assert(cand_tmp_ == btncand_); + } +#endif /*ndef NDEBUG*/ + } else { + gatherCellsNucleotidesEnd2EndSseI16(best); + } + } else { + if(sse8succ_) { + gatherCellsNucleotidesLocalSseU8(best); +#ifndef NDEBUG + if(sse16succ_) { + cand_tmp_ = btncand_; + gatherCellsNucleotidesLocalSseI16(best); + cand_tmp_.sort(); + btncand_.sort(); + assert(cand_tmp_ == btncand_); + } +#endif /*ndef NDEBUG*/ + } else { + gatherCellsNucleotidesLocalSseI16(best); + } + } + } + if(!btncand_.empty()) { + btncand_.sort(); + } + return !btncand_.empty(); +} + +/** + * Populate the given SwResult with information about the "next best" + * alignment if there is one. If there isn't one, false is returned. Note + * that false might be returned even though a call to done() would have + * returned false. + */ +bool SwAligner::nextAlignment( + SwResult& res, + TAlScore minsc, + RandomSource& rnd) +{ + assert(initedRead() && initedRef()); + assert_eq(STATE_ALIGNED, state_); + assert(repOk()); + if(done()) { + res.reset(); + return false; + } + assert(!done()); + size_t off = 0, nbts = 0; + assert_lt(cural_, btncand_.size()); + assert(res.repOk()); + // For each candidate cell that we should try to backtrack from... + const size_t candsz = btncand_.size(); + size_t SQ = dpRows() >> 4; + if(SQ == 0) SQ = 1; + size_t rdlen = rdf_ - rdi_; + bool checkpointed = rdlen >= cperMinlen_; + while(cural_ < candsz) { + // Doing 'continue' anywhere in here simply causes us to move on to the + // next candidate + if(btncand_[cural_].score < minsc) { + btncand_[cural_].fate = BT_CAND_FATE_FILT_SCORE; + nbtfiltsc_++; cural_++; continue; + } + nbts = 0; + assert(sse8succ_ || sse16succ_); + size_t row = btncand_[cural_].row; + size_t col = btncand_[cural_].col; + assert_lt(row, dpRows()); + assert_lt((TRefOff)col, rff_-rfi_); + if(sse16succ_) { + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + if(!checkpointed && d.mat_.reset_[row] && d.mat_.reportedThrough(row, col)) { + // Skipping this candidate because a previous candidate already + // moved through this cell + btncand_[cural_].fate = BT_CAND_FATE_FILT_START; + //cerr << " skipped becuase starting cell was covered" << endl; + nbtfiltst_++; cural_++; continue; + } + } else if(sse8succ_) { + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + if(!checkpointed && d.mat_.reset_[row] && d.mat_.reportedThrough(row, col)) { + // Skipping this candidate because a previous candidate already + // moved through this cell + btncand_[cural_].fate = BT_CAND_FATE_FILT_START; + //cerr << " skipped becuase starting cell was covered" << endl; + nbtfiltst_++; cural_++; continue; + } + } + if(sc_->monotone) { + bool ret = false; + if(sse8succ_) { + uint32_t reseed = rnd.nextU32() + 1; + rnd.init(reseed); + res.reset(); + if(checkpointed) { + size_t maxiter = MAX_SIZE_T; + size_t niter = 0; + ret = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter, // max # extensions to try + niter, // # extensions tried + rnd); // random gen, to choose among equal paths + } else { + ret = backtraceNucleotidesEnd2EndSseU8( + btncand_[cural_].score, // in: expected score + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + nbts, // out: # backtracks + row, // start in this rectangle row + col, // start in this rectangle column + rnd); // random gen, to choose among equal paths + } +#ifndef NDEBUG + // if(...) statement here should check not whether the primary + // alignment was checkpointed, but whether a checkpointed + // alignment was done at all. + if(!checkpointed) { + SwResult res2; + res2.alres = res.alres; res2.alres.reset(); + size_t maxiter2 = MAX_SIZE_T; + size_t niter2 = 0; + bool ret2 = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res2, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter2, // max # extensions to try + niter2, // # extensions tried + rnd); // random gen, to choose among equal paths + // After the first alignment, there's no guarantee we'll + // get the same answer from both backtrackers because of + // differences in how they handle marking cells as + // reported-through. + assert(cural_ > 0 || !ret || ret == ret2); + assert(cural_ > 0 || !ret || res.alres == res2.alres); + } + if(sse16succ_ && !checkpointed) { + SwResult res2; + res2.alres = res.alres; res2.alres.reset(); + size_t off2, nbts2 = 0; + rnd.init(reseed); + bool ret2 = backtraceNucleotidesEnd2EndSseI16( + btncand_[cural_].score, // in: expected score + res2, // out: store results (edits and scores) here + off2, // out: store diagonal projection of origin + nbts2, // out: # backtracks + row, // start in this rectangle row + col, // start in this rectangle column + rnd); // random gen, to choose among equal paths + assert_eq(ret, ret2); + assert_eq(nbts, nbts2); + assert(!ret || res2.alres.score() == res.alres.score()); +#if 0 + if(!checkpointed && (rand() & 15) == 0) { + // Check that same cells are reported through + SSEData& d8 = fw_ ? sseU8fw_ : sseU8rc_; + SSEData& d16 = fw_ ? sseI16fw_ : sseI16rc_; + for(size_t i = d8.mat_.nrow(); i > 0; i--) { + for(size_t j = 0; j < d8.mat_.ncol(); j++) { + assert_eq(d8.mat_.reportedThrough(i-1, j), + d16.mat_.reportedThrough(i-1, j)); + } + } + } +#endif + } +#endif + rnd.init(reseed+1); // debug/release pseudo-randoms in lock step + } else if(sse16succ_) { + uint32_t reseed = rnd.nextU32() + 1; + res.reset(); + if(checkpointed) { + size_t maxiter = MAX_SIZE_T; + size_t niter = 0; + ret = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter, // max # extensions to try + niter, // # extensions tried + rnd); // random gen, to choose among equal paths + } else { + ret = backtraceNucleotidesEnd2EndSseI16( + btncand_[cural_].score, // in: expected score + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + nbts, // out: # backtracks + row, // start in this rectangle row + col, // start in this rectangle column + rnd); // random gen, to choose among equal paths + } +#ifndef NDEBUG + // if(...) statement here should check not whether the primary + // alignment was checkpointed, but whether a checkpointed + // alignment was done at all. + if(!checkpointed) { + SwResult res2; + size_t maxiter2 = MAX_SIZE_T; + size_t niter2 = 0; + bool ret2 = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res2, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter2, // max # extensions to try + niter2, // # extensions tried + rnd); // random gen, to choose among equal paths + // After the first alignment, there's no guarantee we'll + // get the same answer from both backtrackers because of + // differences in how they handle marking cells as + // reported-through. + assert(cural_ > 0 || !ret || ret == ret2); + assert(cural_ > 0 || !ret || res.alres == res2.alres); + } +#endif + rnd.init(reseed); // debug/release pseudo-randoms in lock step + } + if(ret) { + btncand_[cural_].fate = BT_CAND_FATE_SUCCEEDED; + break; + } else { + btncand_[cural_].fate = BT_CAND_FATE_FAILED; + } + } else { + // Local alignment + // Check if this solution is "dominated" by a prior one. + // Domination is a heuristic designed to eliminate the vast + // majority of valid-but-redundant candidates lying in the + // "penumbra" of a high-scoring alignment. + bool dom = false; + { + size_t donesz = btncanddone_.size(); + const size_t col = btncand_[cural_].col; + const size_t row = btncand_[cural_].row; + for(size_t i = 0; i < donesz; i++) { + assert_gt(btncanddone_[i].fate, 0); + size_t colhi = col, rowhi = row; + size_t rowlo = btncanddone_[i].row; + size_t collo = btncanddone_[i].col; + if(colhi < collo) swap(colhi, collo); + if(rowhi < rowlo) swap(rowhi, rowlo); + if(colhi - collo <= SQ && rowhi - rowlo <= SQ) { + // Skipping this candidate because it's "dominated" by + // a previous candidate + dom = true; + break; + } + } + } + if(dom) { + btncand_[cural_].fate = BT_CAND_FATE_FILT_DOMINATED; + nbtfiltdo_++; + cural_++; + continue; + } + bool ret = false; + if(sse8succ_) { + uint32_t reseed = rnd.nextU32() + 1; + res.reset(); + rnd.init(reseed); + if(checkpointed) { + size_t maxiter = MAX_SIZE_T; + size_t niter = 0; + ret = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter, // max # extensions to try + niter, // # extensions tried + rnd); // random gen, to choose among equal paths + } else { + ret = backtraceNucleotidesLocalSseU8( + btncand_[cural_].score, // in: expected score + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + nbts, // out: # backtracks + row, // start in this rectangle row + col, // start in this rectangle column + rnd); // random gen, to choose among equal paths + } +#ifndef NDEBUG + // if(...) statement here should check not whether the primary + // alignment was checkpointed, but whether a checkpointed + // alignment was done at all. + if(!checkpointed) { + SwResult res2; + size_t maxiter2 = MAX_SIZE_T; + size_t niter2 = 0; + bool ret2 = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res2, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter2, // max # extensions to try + niter2, // # extensions tried + rnd); // random gen, to choose among equal paths + // After the first alignment, there's no guarantee we'll + // get the same answer from both backtrackers because of + // differences in how they handle marking cells as + // reported-through. + assert(cural_ > 0 || !ret || ret == ret2); + assert(cural_ > 0 || !ret || res.alres == res2.alres); + } + if(!checkpointed && sse16succ_) { + SwResult res2; + size_t off2, nbts2 = 0; + rnd.init(reseed); // same b/t backtrace calls + bool ret2 = backtraceNucleotidesLocalSseI16( + btncand_[cural_].score, // in: expected score + res2, // out: store results (edits and scores) here + off2, // out: store diagonal projection of origin + nbts2, // out: # backtracks + row, // start in this rectangle row + col, // start in this rectangle column + rnd); // random gen, to choose among equal paths + assert_eq(ret, ret2); + assert_eq(nbts, nbts2); + assert(!ret || res2.alres.score() == res.alres.score()); +#if 0 + if(!checkpointed && (rand() & 15) == 0) { + // Check that same cells are reported through + SSEData& d8 = fw_ ? sseU8fw_ : sseU8rc_; + SSEData& d16 = fw_ ? sseI16fw_ : sseI16rc_; + for(size_t i = d8.mat_.nrow(); i > 0; i--) { + for(size_t j = 0; j < d8.mat_.ncol(); j++) { + assert_eq(d8.mat_.reportedThrough(i-1, j), + d16.mat_.reportedThrough(i-1, j)); + } + } + } +#endif + } +#endif + rnd.init(reseed+1); // debug/release pseudo-randoms in lock step + } else if(sse16succ_) { + uint32_t reseed = rnd.nextU32() + 1; + res.reset(); + if(checkpointed) { + size_t maxiter = MAX_SIZE_T; + size_t niter = 0; + ret = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter, // max # extensions to try + niter, // # extensions tried + rnd); // random gen, to choose among equal paths + } else { + ret = backtraceNucleotidesLocalSseI16( + btncand_[cural_].score, // in: expected score + res, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + nbts, // out: # backtracks + row, // start in this rectangle row + col, // start in this rectangle column + rnd); // random gen, to choose among equal paths + } +#ifndef NDEBUG + // if(...) statement here should check not whether the primary + // alignment was checkpointed, but whether a checkpointed + // alignment was done at all. + if(!checkpointed) { + SwResult res2; + size_t maxiter2 = MAX_SIZE_T; + size_t niter2 = 0; + bool ret2 = backtrace( + btncand_[cural_].score, // in: expected score + true, // in: use mini-fill? + true, // in: use checkpoints? + res2, // out: store results (edits and scores) here + off, // out: store diagonal projection of origin + row, // start in this rectangle row + col, // start in this rectangle column + maxiter2, // max # extensions to try + niter2, // # extensions tried + rnd); // random gen, to choose among equal paths + // After the first alignment, there's no guarantee we'll + // get the same answer from both backtrackers because of + // differences in how they handle marking cells as + // reported-through. + assert(cural_ > 0 || !ret || ret == ret2); + assert(cural_ > 0 || !ret || res.alres == res2.alres); + } +#endif + rnd.init(reseed); // same b/t backtrace calls + } + if(ret) { + btncand_[cural_].fate = BT_CAND_FATE_SUCCEEDED; + btncanddone_.push_back(btncand_[cural_]); + btncanddoneSucc_++; + assert(res.repOk()); + break; + } else { + btncand_[cural_].fate = BT_CAND_FATE_FAILED; + btncanddone_.push_back(btncand_[cural_]); + btncanddoneFail_++; + } + } + cural_++; + } // while(cural_ < btncand_.size()) + if(cural_ == btncand_.size()) { + assert(res.repOk()); + return false; + } + assert(!res.alres.empty()); + assert(res.repOk()); + if(!fw_) { + // All edits are currently w/r/t upstream end; if read aligned + // to Crick strand, we need to invert them so that they're + // w/r/t the read's 5' end instead. + res.alres.invertEdits(); + } + cural_++; + assert(res.repOk()); + return true; +} + +#ifdef MAIN_ALIGNER_SW + +#include +#include +#include +#include "scoring.h" +#include "aligner_seed_policy.h" + +int gGapBarrier; +int gSnpPhred; +static int bonusMatchType; // how to reward matches +static int bonusMatch; // constant if match bonus is a constant +static int penMmcType; // how to penalize mismatches +static int penMmc; // constant if mm pelanty is a constant +static int penNType; // how to penalize Ns in the read +static int penN; // constant if N pelanty is a constant +static bool nPairCat; // true -> concatenate mates before N filter +static int penRdExConst; // constant coeff for cost of gap in read +static int penRfExConst; // constant coeff for cost of gap in ref +static int penRdExLinear; // linear coeff for cost of gap in read +static int penRfExLinear; // linear coeff for cost of gap in ref +static float costMinConst; // constant coeff for min score w/r/t read len +static float costMinLinear; // linear coeff for min score w/r/t read len +static float costFloorConst; // constant coeff for score floor w/r/t read len +static float costFloorLinear;// linear coeff for score floor w/r/t read len +static float nCeilConst; // constant coeff for N ceiling w/r/t read len +static float nCeilLinear; // linear coeff for N ceiling w/r/t read len +static bool nCatPair; // concat mates before applying N filter? +static int multiseedMms; // mismatches permitted in a multiseed seed +static int multiseedLen; // length of multiseed seeds +static int multiseedIvalType; +static float multiseedIvalA; +static float multiseedIvalB; +static float posmin; +static float posfrac; +static float rowmult; + +enum { + ARG_TESTS = 256 +}; + +static const char *short_opts = "s:m:r:d:i:"; +static struct option long_opts[] = { + {(char*)"snppen", required_argument, 0, 's'}, + {(char*)"misspen", required_argument, 0, 'm'}, + {(char*)"seed", required_argument, 0, 'r'}, + {(char*)"align-policy", no_argument, 0, 'A'}, + {(char*)"test", no_argument, 0, ARG_TESTS}, +}; + +static void printUsage(ostream& os) { + os << "Usage: aligner_sw [options]*" << endl; + os << "Options:" << endl; + os << " -s/--snppen penalty incurred by SNP; used for decoding" + << endl; + os << " -m/--misspen quality to use for read chars" << endl; + os << " -r/-seed seed for pseudo-random generator" << endl; +} + +/** + * Parse a T from a string 's' + */ +template +T parse(const char *s) { + T tmp; + stringstream ss(s); + ss >> tmp; + return tmp; +} + +static EList stbuf, enbuf; +static BTDnaString btread; +static BTString btqual; +static BTString btref; +static BTString btref2; + +static BTDnaString readrc; +static BTString qualrc; + +/** + * Helper function for running a case consisting of a read (sequence + * and quality), a reference string, and an offset that anchors the 0th + * character of the read to a reference position. + */ +static void doTestCase( + SwAligner& al, + const BTDnaString& read, + const BTString& qual, + const BTString& refin, + TRefOff off, + EList *en, + const Scoring& sc, + TAlScore minsc, + SwResult& res, + bool nsInclusive, + bool filterns, + uint32_t seed) +{ + RandomSource rnd(seed); + btref2 = refin; + assert_eq(read.length(), qual.length()); + size_t nrow = read.length(); + TRefOff rfi, rff; + // Calculate the largest possible number of read and reference gaps given + // 'minsc' and 'pens' + size_t maxgaps; + size_t padi, padf; + { + int readGaps = sc.maxReadGaps(minsc, read.length()); + int refGaps = sc.maxRefGaps(minsc, read.length()); + assert_geq(readGaps, 0); + assert_geq(refGaps, 0); + int maxGaps = max(readGaps, refGaps); + padi = 2 * maxGaps; + padf = maxGaps; + maxgaps = (size_t)maxGaps; + } + size_t nceil = (size_t)sc.nCeil.f((double)read.length()); + size_t width = 1 + padi + padf; + rfi = off; + off = 0; + // Pad the beginning of the reference with Ns if necessary + if(rfi < padi) { + size_t beginpad = (size_t)(padi - rfi); + for(size_t i = 0; i < beginpad; i++) { + btref2.insert('N', 0); + off--; + } + rfi = 0; + } else { + rfi -= padi; + } + assert_geq(rfi, 0); + // Pad the end of the reference with Ns if necessary + while(rfi + nrow + padi + padf > btref2.length()) { + btref2.append('N'); + } + rff = rfi + nrow + padi + padf; + // Convert reference string to masks + for(size_t i = 0; i < btref2.length(); i++) { + if(toupper(btref2[i]) == 'N' && !nsInclusive) { + btref2.set(16, i); + } else { + int num = 0; + int alts[] = {4, 4, 4, 4}; + decodeNuc(toupper(btref2[i]), num, alts); + assert_leq(num, 4); + assert_gt(num, 0); + btref2.set(0, i); + for(int j = 0; j < num; j++) { + btref2.set(btref2[i] | (1 << alts[j]), i); + } + } + } + bool fw = true; + uint32_t refidx = 0; + size_t solwidth = width; + if(maxgaps >= solwidth) { + solwidth = 0; + } else { + solwidth -= maxgaps; + } + if(en == NULL) { + enbuf.resize(solwidth); + enbuf.fill(true); + en = &enbuf; + } + assert_geq(rfi, 0); + assert_gt(rff, rfi); + readrc = read; + qualrc = qual; + al.initRead( + read, // read sequence + readrc, + qual, // read qualities + qualrc, + 0, // offset of first character within 'read' to consider + read.length(), // offset of last char (exclusive) in 'read' to consider + floorsc); // local-alignment score floor + al.initRef( + fw, // 'read' is forward version of read? + refidx, // id of reference aligned to + off, // offset of upstream ref char aligned against + btref2.wbuf(), // reference sequence (masks) + rfi, // offset of first char in 'ref' to consider + rff, // offset of last char (exclusive) in 'ref' to consider + width, // # bands to do (width of parallelogram) + solwidth, // # rightmost cols where solns can end + sc, // scoring scheme + minsc, // minimum score for valid alignment + maxgaps, // max of max # read gaps, ref gaps + 0, // amount to truncate on left-hand side + en); // mask indicating which columns we can end in + if(filterns) { + al.filter((int)nceil); + } + al.align(rnd); +} + +/** + * Another interface for running a case. + */ +static void doTestCase2( + SwAligner& al, + const char *read, + const char *qual, + const char *refin, + TRefOff off, + const Scoring& sc, + float costMinConst, + float costMinLinear, + SwResult& res, + bool nsInclusive = false, + bool filterns = false, + uint32_t seed = 0) +{ + btread.install(read, true); + TAlScore minsc = (TAlScore)(Scoring::linearFunc( + btread.length(), + costMinConst, + costMinLinear)); + TAlScore floorsc = (TAlScore)(Scoring::linearFunc( + btread.length(), + costFloorConst, + costFloorLinear)); + btqual.install(qual); + btref.install(refin); + doTestCase( + al, + btread, + btqual, + btref, + off, + NULL, + sc, + minsc, + floorsc, + res, + nsInclusive, + filterns, + seed + ); +} + +/** + * Another interface for running a case. + */ +static void doTestCase3( + SwAligner& al, + const char *read, + const char *qual, + const char *refin, + TRefOff off, + Scoring& sc, + float costMinConst, + float costMinLinear, + float nCeilConst, + float nCeilLinear, + SwResult& res, + bool nsInclusive = false, + bool filterns = false, + uint32_t seed = 0) +{ + btread.install(read, true); + // Calculate the penalty ceiling for the read + TAlScore minsc = (TAlScore)(Scoring::linearFunc( + btread.length(), + costMinConst, + costMinLinear)); + TAlScore floorsc = (TAlScore)(Scoring::linearFunc( + btread.length(), + costFloorConst, + costFloorLinear)); + btqual.install(qual); + btref.install(refin); + sc.nCeil.setType(SIMPLE_FUNC_LINEAR); + sc.nCeil.setConst(costMinConst); + sc.nCeil.setCoeff(costMinLinear); + doTestCase( + al, + btread, + btqual, + btref, + off, + NULL, + sc, + minsc, + floorsc, + res, + nsInclusive, + filterns, + seed + ); +} + +/** + * Another interface for running a case. Like doTestCase3 but caller specifies + * st_ and en_ lists. + */ +static void doTestCase4( + SwAligner& al, + const char *read, + const char *qual, + const char *refin, + TRefOff off, + EList& en, + Scoring& sc, + float costMinConst, + float costMinLinear, + float nCeilConst, + float nCeilLinear, + SwResult& res, + bool nsInclusive = false, + bool filterns = false, + uint32_t seed = 0) +{ + btread.install(read, true); + // Calculate the penalty ceiling for the read + TAlScore minsc = (TAlScore)(Scoring::linearFunc( + btread.length(), + costMinConst, + costMinLinear)); + TAlScore floorsc = (TAlScore)(Scoring::linearFunc( + btread.length(), + costFloorConst, + costFloorLinear)); + btqual.install(qual); + btref.install(refin); + sc.nCeil.setType(SIMPLE_FUNC_LINEAR); + sc.nCeil.setConst(costMinConst); + sc.nCeil.setCoeff(costMinLinear); + doTestCase( + al, + btread, + btqual, + btref, + off, + &en, + sc, + minsc, + floorsc, + res, + nsInclusive, + filterns, + seed + ); +} + +/** + * Do a set of unit tests. + */ +static void doTests() { + bonusMatchType = DEFAULT_MATCH_BONUS_TYPE; + bonusMatch = DEFAULT_MATCH_BONUS; + penMmcType = DEFAULT_MM_PENALTY_TYPE; + penMmc = DEFAULT_MM_PENALTY; + penSnp = DEFAULT_SNP_PENALTY; + penNType = DEFAULT_N_PENALTY_TYPE; + penN = DEFAULT_N_PENALTY; + nPairCat = DEFAULT_N_CAT_PAIR; + penRdExConst = DEFAULT_READ_GAP_CONST; + penRfExConst = DEFAULT_REF_GAP_CONST; + penRdExLinear = DEFAULT_READ_GAP_LINEAR; + penRfExLinear = DEFAULT_REF_GAP_LINEAR; + costMinConst = DEFAULT_MIN_CONST; + costMinLinear = DEFAULT_MIN_LINEAR; + costFloorConst = DEFAULT_FLOOR_CONST; + costFloorLinear = DEFAULT_FLOOR_LINEAR; + nCeilConst = 1.0f; // constant factor in N ceil w/r/t read len + nCeilLinear = 0.1f; // coeff of linear term in N ceil w/r/t read len + multiseedMms = DEFAULT_SEEDMMS; + multiseedLen = DEFAULT_SEEDLEN; + // Set up penalities + Scoring sc( + bonusMatch, + penMmcType, // how to penalize mismatches + 30, // constant if mm pelanty is a constant + 30, // penalty for decoded SNP + costMinConst, // constant factor in N ceiling w/r/t read length + costMinLinear, // coeff of linear term in N ceiling w/r/t read length + costFloorConst, // constant factor in N ceiling w/r/t read length + costFloorLinear, // coeff of linear term in N ceiling w/r/t read length + nCeilConst, // constant factor in N ceiling w/r/t read length + nCeilLinear, // coeff of linear term in N ceiling w/r/t read length + penNType, // how to penalize Ns in the read + penN, // constant if N pelanty is a constant + nPairCat, // true -> concatenate mates before N filtering + 25, // constant coeff for cost of gap in read + 25, // constant coeff for cost of gap in ref + 15, // linear coeff for cost of gap in read + 15, // linear coeff for cost of gap in ref + 1, // # rows at top/bot can only be entered diagonally + -1, // min row idx to backtrace from; -1 = no limit + false // sort results first by row then by score? + ); + // Set up alternative penalities + Scoring sc2( + bonusMatch, + COST_MODEL_QUAL, // how to penalize mismatches + 30, // constant if mm pelanty is a constant + 30, // penalty for decoded SNP + costMinConst, // constant factor in N ceiling w/r/t read length + costMinLinear, // coeff of linear term in N ceiling w/r/t read length + costFloorConst, // constant factor in N ceiling w/r/t read length + costFloorLinear, // coeff of linear term in N ceiling w/r/t read length + 1.0f, // constant factor in N ceiling w/r/t read length + 1.0f, // coeff of linear term in N ceiling w/r/t read length + penNType, // how to penalize Ns in the read + penN, // constant if N pelanty is a constant + nPairCat, // true -> concatenate mates before N filtering + 25, // constant coeff for cost of gap in read + 25, // constant coeff for cost of gap in ref + 15, // linear coeff for cost of gap in read + 15, // linear coeff for cost of gap in ref + 1, // # rows at top/bot can only be entered diagonally + -1, // min row idx to backtrace from; -1 = no limit + false // sort results first by row then by score? + ); + SwResult res; + + // + // Basic nucleotide-space tests + // + cerr << "Running tests..." << endl; + int tests = 1; + bool nIncl = false; + bool nfilter = false; + + SwAligner al; + RandomSource rnd(73); + for(int i = 0; i < 3; i++) { + cerr << " Test " << tests++ << " (nuc space, offset " + << (i*4) << ", exact)..."; + sc.rdGapConst = 40; + sc.rfGapConst = 40; + sc.rdGapLinear = 15; + sc.rfGapLinear = 15; + // A C G T A C G T + // H E F H E F H E F H E F H E F H E F H E F H E F + // A 0 lo lo -30 lo lo -30 lo lo -30 lo lo 0 lo lo -30 lo lo-30 lo lo-30 lo lo + // C -30 lo -55 0 -85 -85 -55 -55 -85 + // G -30 lo -70 -55 -85 -55 0 -100-100 + // T -30 lo -85 -60 -85 -70 -55-100 -55 + // A 0 lo -85 -55 -55 -85 -70 -70 -70 + // C -30 lo -55 0 -85-100 -55 -55 -85 + // G -30 lo -70 -55 -85 -55 0 -100-100 + // T -30 lo -85 -60 -85 -70 -55-100 -55 + doTestCase2( + al, + "ACGTACGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 0); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1mm allowed by minsc)..."; + sc.setMmPen(COST_MODEL_CONSTANT, 30); + //sc.setMatchBonus(10); + doTestCase2( + al, + "ACGTTCGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -30); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1mm allowed by minsc, check qual 1)..."; + doTestCase2( + al, + "ACGTTCGT", // read + "ABCDEFGH", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc2, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + size_t lo, hi; + if(i == 0) { + lo = 0; hi = 1; + } else if(i == 1) { + lo = 1; hi = 2; + } else { + lo = 2; hi = 3; + } + for(size_t j = lo; j < hi; j++) { + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(j*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -36); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + } + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1mm allowed by minsc, check qual 2)..."; + doTestCase2( + al, + "ACGAACGT", // read + "ABCDEFGH", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc2, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -35); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + assert(res.empty()); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1mm allowed by minsc, check qual )..."; + assert(res.empty()); + doTestCase2( + al, + "TCGTACGT", // read + "ABCDEFGH", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc2, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -32); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + assert(res.empty()); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1mm at the beginning, allowed by minsc)..."; + doTestCase2( + al, + "CCGTACGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -30); + assert_eq(res.alres.score().ns(), 0); + assert_eq(1, res.alres.ned().size()); + assert_eq(0, res.alres.aed().size()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 n in read, allowed)..."; + doTestCase3( + al, + "ACGTNCGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + 1.0f, // allow 1 N + 0.0f, // allow 1 N + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -1); + assert_eq(res.alres.score().ns(), 1); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 2 n in read, allowed)..."; + doTestCase3( + al, + "ACGNNCGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + 2.0f, // const coeff for N ceiling + 0.0f, // linear coeff for N ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -2); + assert_eq(res.alres.score().ns(), 2); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 2 n in read, 1 at beginning, allowed)..."; + doTestCase2( + al, + "NCGTNCGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -2); + assert_eq(res.alres.score().ns(), 2); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 n in ref, allowed)..."; + doTestCase2( + al, + "ACGTACGT", // read + "IIIIIIII", // qual + "ACGTNCGTACGTANGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), -1); + assert_eq(res.alres.score().ns(), 1); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1mm disallowed by minsc)..."; + doTestCase2( + al, + "ACGTTCGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -10.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + // Read gap with equal read and ref gap penalties + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", read gap allowed by minsc)..."; + assert(res.empty()); + sc.rfGapConst = 25; + sc.rdGapConst = 25; + sc.rfGapLinear = 15; + sc.rdGapLinear = 15; + doTestCase2( + al, + "ACGTCGT", // read + "IIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -40); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", read gap disallowed by minsc)..."; + sc.rfGapConst = 25; + sc.rdGapConst = 25; + sc.rfGapLinear = 15; + sc.rdGapLinear = 15; + doTestCase2( + al, + "ACGTCGT", // read + "IIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + + cerr << "PASSED" << endl; + // Ref gap with equal read and ref gap penalties + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", ref gap allowed by minsc)..."; + doTestCase2( + al, + "ACGTAACGT", // read + "IIIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -40); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", read gap disallowed by gap barrier)..."; + sc.rfGapConst = 25; + sc.rdGapConst = 25; + sc.rfGapLinear = 15; + sc.rdGapLinear = 15; + sc.gapbar = 4; + doTestCase2( + al, + "ACGTCGT", // read + "IIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + sc.gapbar = 1; + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + + cerr << "PASSED" << endl; + // Ref gap with equal read and ref gap penalties + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", ref gap allowed by minsc, gapbar=3)..."; + sc.gapbar = 3; + doTestCase2( + al, + "ACGTAACGT", // read + "IIIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + sc.gapbar = 1; + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -40); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + // Ref gap with equal read and ref gap penalties + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", ref gap allowed by minsc, gapbar=4)..."; + sc.gapbar = 4; + doTestCase2( + al, + "ACGTAACGT", // read + "IIIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + sc.gapbar = 1; + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -40); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", ref gap disallowed by minsc)..."; + doTestCase2( + al, + "ACGTAACGT", // read + "IIIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + assert(al.done()); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", ref gap disallowed by gap barrier)..."; + sc.gapbar = 5; + doTestCase2( + al, + "ACGTAACGT", // read + "IIIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + sc.gapbar = 1; + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + assert(al.done()); + cerr << "PASSED" << endl; + + // Read gap with one read gap and zero ref gaps allowed + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 read gap, ref gaps disallowed by minsc)..."; + sc.rfGapConst = 35; + sc.rdGapConst = 25; + sc.rfGapLinear = 20; + sc.rdGapLinear = 10; + doTestCase2( + al, + "ACGTCGT", // read + "IIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -35); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", gaps disallowed by minsc)..."; + sc.rfGapConst = 25; + sc.rdGapConst = 25; + sc.rfGapLinear = 10; + sc.rdGapLinear = 10; + doTestCase2( + al, + "ACGTCGT", // read + "IIIIIII", // qual + "ACGTACGTACGTACGT", // ref + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + assert(res.empty()); + cerr << "PASSED" << endl; + + // Ref gap with one ref gap and zero read gaps allowed + sc.rfGapConst = 25; + sc.rdGapConst = 35; + sc.rfGapLinear = 12; + sc.rdGapLinear = 22; + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 ref gap, read gaps disallowed by minsc)..."; + assert(res.empty()); + doTestCase2( + al, + "ACGTAACGT", + "IIIIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -37); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", gaps disallowed by minsc)..."; + doTestCase2( + al, + "ACGTAACGT", + "IIIIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + cerr << "PASSED" << endl; + + // Read gap with one read gap and two ref gaps allowed + sc.rfGapConst = 20; + sc.rdGapConst = 25; + sc.rfGapLinear = 10; + sc.rdGapLinear = 15; + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 read gap, 2 ref gaps allowed by minsc)..."; + doTestCase2( + al, + "ACGTCGT", + "IIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -40); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", gaps disallowed by minsc)..."; + doTestCase2( + al, + "ACGTCGT", + "IIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + cerr << "PASSED" << endl; + + // Ref gap with one ref gap and two read gaps allowed + sc.rfGapConst = 25; + sc.rdGapConst = 11; // if this were 10, we'd have ties + sc.rfGapLinear = 15; + sc.rdGapLinear = 10; + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 ref gap, 2 read gaps allowed by minsc)..."; + doTestCase2( + al, + "ACGTAACGT", + "IIIIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -40); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) << ", gaps disallowed by minsc)..."; + doTestCase2( + al, + "ACGTAACGT", + "IIIIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(res.empty()); + res.reset(); + assert(al.done()); + cerr << "PASSED" << endl; + + // Read gap with two read gaps and two ref gaps allowed + sc.rfGapConst = 15; + sc.rdGapConst = 15; + sc.rfGapLinear = 10; + sc.rdGapLinear = 10; + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 2 ref gaps, 2 read gaps allowed by minsc)..."; + doTestCase3( + al, + "ACGTCGT", + "IIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -40.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + 1.0, // const coeff for N ceiling + 0.0, // linear coeff for N ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + true); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + if(!res.empty()) { + //al.printResultStacked(res, cerr); cerr << endl; + } + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -25); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + // The following alignment is possible when i == 2: + // ACGTACGTACGTACGTN + // A x + // C x + // G x + // T x + // C x + // G x + // T x + assert(i == 2 || res.empty()); + res.reset(); + cerr << "PASSED" << endl; + + sc.rfGapConst = 10; + sc.rdGapConst = 10; + sc.rfGapLinear = 10; + sc.rdGapLinear = 10; + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 ref gap, 1 read gap allowed by minsc)..."; + doTestCase2( + al, + "ACGTCGT", + "IIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -20); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + cerr << "PASSED" << endl; + + // Ref gap with two ref gaps and zero read gaps allowed + sc.rfGapConst = 15; + sc.rdGapConst = 15; + sc.rfGapLinear = 5; + sc.rdGapLinear = 5; + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 2 ref gaps, 2 read gaps allowed by minsc)..."; + // Careful: it might be possible for the read to align with overhang + // instead of with a gap + doTestCase3( + al, + "ACGTAACGT", + "IIIIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -35.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + 1.0f, // needed to avoid overhang alignments + 0.0f, // needed to avoid overhang alignments + res, // result + nIncl, // Ns inclusive (not mismatches) + true); // filter Ns + if(i == 0) { + lo = 0; hi = 1; + } else if(i == 1) { + lo = 1; hi = 2; + } else { + lo = 2; hi = 3; + } + for(size_t j = lo; j < hi; j++) { + al.nextAlignment(res, rnd); + assert(!res.empty()); + //al.printResultStacked(res, cerr); cerr << endl; + assert(res.alres.refoff() == 0 || + res.alres.refoff() == 4 || + res.alres.refoff() == 8); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -20); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + } + al.nextAlignment(res, rnd); + //assert(res.empty()); + //res.reset(); + cerr << "PASSED" << endl; + + sc.rfGapConst = 25; + sc.rdGapConst = 25; + sc.rfGapLinear = 4; + sc.rdGapLinear = 4; + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1 ref gap, 1 read gap allowed by minsc)..."; + doTestCase2( + al, + "ACGTAACGT", + "IIIIIIIII", + "ACGTACGTACGTACGT", + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 1); + assert_eq(res.alres.score().score(), -29); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", short read)..."; + doTestCase2( + al, + "A", + "I", + "AAAAAAAAAAAA", + i*4, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 0); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + cerr << "PASSED" << endl; + + if(i == 0) { + cerr << " Test " << tests++ + << " (nuc space, offset 0, short read & ref)..."; + doTestCase2( + al, + "A", + "I", + "A", + 0, // off + sc, // scoring scheme + -30.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 0); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + cerr << "PASSED" << endl; + } + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", short read, many allowed gaps)..."; + doTestCase2( + al, + "A", + "I", + "AAAAAAAAAAAA", + i*4, // off + sc, // scoring scheme + -150.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 0); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + cerr << "PASSED" << endl; + + if(i == 0) { + cerr << " Test " << tests++ + << " (nuc space, offset 0, short read & ref, " + << "many allowed gaps)..."; + doTestCase2( + al, + "A", + "I", + "A", + 0, // off + sc, // scoring scheme + -150.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 0); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + cerr << "PASSED" << endl; + } + } + + // A test case where a valid alignment with a worse score should be + // accepted over a valid alignment with a better score but too many + // Ns + cerr << " Test " << tests++ << " (N ceiling 1)..."; + sc.mmcostType = COST_MODEL_CONSTANT; + sc.mmcost = 10; + sc.snp = 30; + sc.nCeilConst = 0.0f; + sc.nCeilLinear = 0.0f; + sc.rfGapConst = 10; + sc.rdGapLinear = 10; + sc.rfGapConst = 10; + sc.rfGapLinear = 10; + sc.setNPen(COST_MODEL_CONSTANT, 2); + sc.gapbar = 1; + // No Ns allowed, so this hit should be filtered + doTestCase2( + al, + "ACGTACGT", // read seq + "IIIIIIII", // read quals + "NCGTACGT", // ref seq + 0, // offset + sc, // scoring scheme + -25.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + false, // ns are in inclusive + true, // nfilter + 0); + al.nextAlignment(res, rnd); + assert(res.empty()); + cerr << "PASSED" << endl; + res.reset(); + + // 1 N allowed, so this hit should stand + cerr << " Test " << tests++ << " (N ceiling 2)..."; + doTestCase3( + al, + "ACGTACGT", // read seq + "IIIIIIII", // read quals + "NCGTACGT", // ref seq + 0, // offset + sc, // scoring scheme + -25.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + 1.0f, // constant coefficient for # Ns allowed + 0.0f, // linear coefficient for # Ns allowed + res, // result + false, // ns are in inclusive + false, // nfilter - NOTE: FILTER OFF + 0); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(0, res.alres.score().gaps()); + assert_eq(-2, res.alres.score().score()); + assert_eq(1, res.alres.score().ns()); + cerr << "PASSED" << endl; + res.reset(); + + // 1 N allowed, but we set st_ such that this hit should not stand + for(size_t i = 0; i < 2; i++) { + cerr << " Test " << tests++ << " (N ceiling 2 with st_ override)..."; + EList en; + en.resize(3); en.fill(true); + if(i == 1) { + en[1] = false; + } + sc.rfGapConst = 10; + sc.rdGapLinear = 10; + sc.rfGapConst = 10; + sc.rfGapLinear = 10; + doTestCase4( + al, + "ACGTACGT", // read seq + "IIIIIIII", // read quals + "NCGTACGT", // ref seq + 0, // offset + en, // rectangle columns where solution can end + sc, // scoring scheme + -25.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + 1.0f, // constant coefficient for # Ns allowed + 0.0f, // linear coefficient for # Ns allowed + res, // result + false, // ns are in inclusive + false, // nfilter - NOTE: FILTER OFF + 0); + al.nextAlignment(res, rnd); + if(i > 0) { + assert(res.empty()); + } else { + assert(!res.empty()); + } + cerr << "PASSED" << endl; + res.reset(); + } + + // No Ns allowed, so this hit should be filtered + cerr << " Test " << tests++ << " (N ceiling 3)..."; + sc.nCeilConst = 1.0f; + sc.nCeilLinear = 0.0f; + doTestCase2( + al, + "ACGTACGT", // read seq + "IIIIIIII", // read quals + "NCGTACGT", // ref seq + 0, // offset + sc, // scoring scheme + -25.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + false, // ns are in inclusive + true, // nfilter - NOTE: FILTER ON + 0); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(0, res.alres.score().gaps()); + assert_eq(-2, res.alres.score().score()); + assert_eq(1, res.alres.score().ns()); + cerr << "PASSED" << endl; + res.reset(); + + // No Ns allowed, so this hit should be filtered + cerr << " Test " << tests++ << " (redundant alignment elimination 1)..."; + sc.nCeilConst = 1.0f; + sc.nCeilLinear = 0.0f; + sc.rfGapConst = 25; + sc.rdGapLinear = 15; + sc.rfGapConst = 25; + sc.rfGapLinear = 15; + doTestCase2( + al, + // 1 2 3 4 + // 01234567890123456789012345678901234567890123456 + "AGGCTATGCCTCTGACGCGATATCGGCGCCCACTTCAGAGCTAACCG", + "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII", + "TTTTTTTTAGGCTATGCCTCTGACGCGATATCGGCGCCCACTTCAGAGCTAACCGTTTTTTT", + // 01234567890123456789012345678901234567890123456789012345678901 + // 1 2 3 4 5 6 + 8, // offset + sc, // scoring scheme + -25.0f, // const coeff for cost ceiling + -5.0f, // linear coeff for cost ceiling + res, // result + false, // ns are in inclusive + true, // nfilter - NOTE: FILTER ON + 0); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(8, res.alres.refoff()); + assert_eq(47, res.alres.refExtent()); + assert_eq(0, res.alres.score().gaps()); + assert_eq(0, res.alres.score().score()); + assert_eq(0, res.alres.score().ns()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + cerr << "PASSED" << endl; + res.reset(); + +} + +/** + * Do a set of unit tests for local alignment. + */ +static void doLocalTests() { + bonusMatchType = DEFAULT_MATCH_BONUS_TYPE; + bonusMatch = DEFAULT_MATCH_BONUS_LOCAL; + penMmcType = DEFAULT_MM_PENALTY_TYPE; + penMmc = DEFAULT_MM_PENALTY; + penSnp = DEFAULT_SNP_PENALTY; + penNType = DEFAULT_N_PENALTY_TYPE; + penN = DEFAULT_N_PENALTY; + nPairCat = DEFAULT_N_CAT_PAIR; + penRdExConst = DEFAULT_READ_GAP_CONST; + penRfExConst = DEFAULT_REF_GAP_CONST; + penRdExLinear = DEFAULT_READ_GAP_LINEAR; + penRfExLinear = DEFAULT_REF_GAP_LINEAR; + costMinConst = DEFAULT_MIN_CONST_LOCAL; + costMinLinear = DEFAULT_MIN_LINEAR_LOCAL; + costFloorConst = DEFAULT_FLOOR_CONST_LOCAL; + costFloorLinear = DEFAULT_FLOOR_LINEAR_LOCAL; + nCeilConst = 1.0f; // constant factor in N ceil w/r/t read len + nCeilLinear = 0.1f; // coeff of linear term in N ceil w/r/t read len + multiseedMms = DEFAULT_SEEDMMS; + multiseedLen = DEFAULT_SEEDLEN; + // Set up penalities + Scoring sc( + 10, + penMmcType, // how to penalize mismatches + 30, // constant if mm pelanty is a constant + penSnp, // penalty for decoded SNP + costMinConst, // constant factor in N ceiling w/r/t read length + costMinLinear, // coeff of linear term in N ceiling w/r/t read length + costFloorConst, // constant factor in N ceiling w/r/t read length + costFloorLinear, // coeff of linear term in N ceiling w/r/t read length + nCeilConst, // constant factor in N ceiling w/r/t read length + nCeilLinear, // coeff of linear term in N ceiling w/r/t read length + penNType, // how to penalize Ns in the read + penN, // constant if N pelanty is a constant + nPairCat, // true -> concatenate mates before N filtering + 25, // constant coeff for cost of gap in read + 25, // constant coeff for cost of gap in ref + 15, // linear coeff for cost of gap in read + 15, // linear coeff for cost of gap in ref + 1, // # rows at top/bot can only be entered diagonally + -1, // min row idx to backtrace from; -1 = no limit + false // sort results first by row then by score? + ); + SwResult res; + + // + // Basic nucleotide-space tests + // + cerr << "Running local tests..." << endl; + int tests = 1; + bool nIncl = false; + bool nfilter = false; + + SwAligner al; + RandomSource rnd(73); + for(int i = 0; i < 3; i++) { + cerr << " Test " << tests++ << " (short nuc space, offset " + << (i*4) << ", exact)..."; + sc.rdGapConst = 40; + sc.rfGapConst = 40; + doTestCase2( + al, + "ACGT", // read + "IIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + 0.0f, // const coeff for cost ceiling + 8.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(4, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 40); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + cerr << "PASSED" << endl; + + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + // A C G T A C G T A C G T A C G T + // 0 C + // 1 C x + // 2 G x + // 3 T x + + cerr << " Test " << tests++ << " (short nuc space, offset " + << (i*4) << ", 1mm)..."; + sc.rdGapConst = 40; + sc.rfGapConst = 40; + doTestCase2( + al, + "CCGT", // read + "IIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + 0.0f, // const coeff for cost ceiling + 7.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4+1, res.alres.refoff()); + assert_eq(3, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 30); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (short nuc space, offset " + << (i*4) << ", 1mm)..."; + sc.rdGapConst = 40; + sc.rfGapConst = 40; + doTestCase2( + al, + "ACGA", // read + "IIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + 0.0f, // const coeff for cost ceiling + 7.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(3, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 30); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + cerr << "PASSED" << endl; + + if(i == 0) { + cerr << " Test " << tests++ << " (short nuc space, offset " + << (i*4) << ", 1mm, match bonus=20)..."; + sc.rdGapConst = 40; + sc.rfGapConst = 40; + sc.setMatchBonus(20); + doTestCase2( + al, + "TTGT", // read + "IIII", // qual + "TTGA", // ref in + i*4, // off + sc, // scoring scheme + 25.0f, // const coeff for cost ceiling + 0.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(3, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 60); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + sc.setMatchBonus(10); + cerr << "PASSED" << endl; + } + + cerr << " Test " << tests++ << " (nuc space, offset " + << (i*4) << ", exact)..."; + sc.rdGapConst = 40; + sc.rfGapConst = 40; + doTestCase2( + al, + "ACGTACGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + 0.0f, // const coeff for cost ceiling + 8.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 80); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + assert(res.empty()); + assert(al.done()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (long nuc space, offset " + << (i*8) << ", exact)..."; + sc.rdGapConst = 40; + sc.rfGapConst = 40; + doTestCase2( + al, + "ACGTACGTACGTACGTACGTA", // read + "IIIIIIIIIIIIIIIIIIIII", // qual + "ACGTACGTACGTACGTACGTACGTACGTACGTACGTA", // ref in + // ACGTACGTACGTACGTACGT + // ACGTACGTACGTACGTACGT + // ACGTACGTACGTACGTACGT + i*8, // off + sc, // scoring scheme + 0.0f, // const coeff for cost ceiling + 8.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*8, res.alres.refoff()); + assert_eq(21, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 210); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + //assert(res.empty()); + //assert(al.done()); + res.reset(); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (nuc space, offset " << (i*4) + << ", 1mm allowed by minsc)..."; + doTestCase2( + al, + "ACGTTCGT", // read + "IIIIIIII", // qual + "ACGTACGTACGTACGT", // ref in + i*4, // off + sc, // scoring scheme + 0.0f, // const coeff for cost ceiling + 5.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*4, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 40); + assert_eq(res.alres.score().ns(), 0); + res.reset(); + al.nextAlignment(res, rnd); + //assert(res.empty()); + //assert(al.done()); + cerr << "PASSED" << endl; + + cerr << " Test " << tests++ << " (long nuc space, offset " + << (i*8) << ", 6mm allowed by minsc)..."; + sc.rdGapConst = 50; + sc.rfGapConst = 50; + sc.rdGapLinear = 45; + sc.rfGapLinear = 45; + doTestCase2( + al, + "ACGTACGATGCATCGTACGTA", // read + "IIIIIIIIIIIIIIIIIIIII", // qual + "ACGTACGTACGTACGTACGTACGTACGTACGTACGTA", // ref in + // ACGTACGTACGTACGTACGT + // ACGTACGTACGTACGTACGT + // ACGTACGTACGTACGTACGT + i*8, // off + sc, // scoring scheme + 0.0f, // const coeff for cost ceiling + 1.0f, // linear coeff for cost ceiling + res, // result + nIncl, // Ns inclusive (not mismatches) + nfilter); // filter Ns + assert(!al.done()); + al.nextAlignment(res, rnd); + assert(!res.empty()); + assert_eq(i*8 + 13, res.alres.refoff()); + assert_eq(8, res.alres.refExtent()); + assert_eq(res.alres.score().gaps(), 0); + assert_eq(res.alres.score().score(), 80); + assert_eq(res.alres.score().ns(), 0); + assert(res.alres.ned().empty()); + assert(res.alres.aed().empty()); + res.reset(); + al.nextAlignment(res, rnd); + res.reset(); + cerr << "PASSED" << endl; + } +} + +int main(int argc, char **argv) { + int option_index = 0; + int next_option; + unsigned seed = 0; + gGapBarrier = 1; + gSnpPhred = 30; + bool nsInclusive = false; + bool nfilter = false; + bonusMatchType = DEFAULT_MATCH_BONUS_TYPE; + bonusMatch = DEFAULT_MATCH_BONUS; + penMmcType = DEFAULT_MM_PENALTY_TYPE; + penMmc = DEFAULT_MM_PENALTY; + penSnp = DEFAULT_SNP_PENALTY; + penNType = DEFAULT_N_PENALTY_TYPE; + penN = DEFAULT_N_PENALTY; + penRdExConst = DEFAULT_READ_GAP_CONST; + penRfExConst = DEFAULT_REF_GAP_CONST; + penRdExLinear = DEFAULT_READ_GAP_LINEAR; + penRfExLinear = DEFAULT_REF_GAP_LINEAR; + costMinConst = DEFAULT_MIN_CONST; + costMinLinear = DEFAULT_MIN_LINEAR; + costFloorConst = DEFAULT_FLOOR_CONST; + costFloorLinear = DEFAULT_FLOOR_LINEAR; + nCeilConst = 1.0f; // constant factor in N ceiling w/r/t read length + nCeilLinear = 1.0f; // coeff of linear term in N ceiling w/r/t read length + nCatPair = false; + multiseedMms = DEFAULT_SEEDMMS; + multiseedLen = DEFAULT_SEEDLEN; + multiseedIvalType = DEFAULT_IVAL; + multiseedIvalA = DEFAULT_IVAL_A; + multiseedIvalB = DEFAULT_IVAL_B; + mhits = 1; + do { + next_option = getopt_long(argc, argv, short_opts, long_opts, &option_index); + switch (next_option) { + case 's': gSnpPhred = parse(optarg); break; + case 'r': seed = parse(optarg); break; + case ARG_TESTS: { + doTests(); + cout << "PASSED end-to-ends" << endl; + doLocalTests(); + cout << "PASSED locals" << endl; + return 0; + } + case 'A': { + bool localAlign = false; + bool noisyHpolymer = false; + bool ignoreQuals = false; + SeedAlignmentPolicy::parseString( + optarg, + localAlign, + noisyHpolymer, + ignoreQuals, + bonusMatchType, + bonusMatch, + penMmcType, + penMmc, + penNType, + penN, + penRdExConst, + penRfExConst, + penRdExLinear, + penRfExLinear, + costMinConst, + costMinLinear, + costFloorConst, + costFloorLinear, + nCeilConst, + nCeilLinear, + nCatPair, + multiseedMms, + multiseedLen, + multiseedIvalType, + multiseedIvalA, + multiseedIvalB, + posmin); + break; + } + case -1: break; + default: { + cerr << "Unknown option: " << (char)next_option << endl; + printUsage(cerr); + exit(1); + } + } + } while(next_option != -1); + srand(seed); + if(argc - optind < 4) { + cerr << "Need at least 4 arguments" << endl; + printUsage(cerr); + exit(1); + } + BTDnaString read; + BTString ref, qual; + // Get read + read.installChars(argv[optind]); + // Get qualities + qual.install(argv[optind+1]); + assert_eq(read.length(), qual.length()); + // Get reference + ref.install(argv[optind+2]); + // Get reference offset + size_t off = parse(argv[optind+3]); + // Set up penalities + Scoring sc( + false, // local alignment? + false, // bad homopolymer? + bonusMatchType, + bonusMatch, + penMmcType, // how to penalize mismatches + penMmc, // constant if mm pelanty is a constant + costMinConst, + costMinLinear, + costFloorConst, + costFloorLinear, + nCeilConst, // N ceiling constant coefficient + nCeilLinear, // N ceiling linear coefficient + penNType, // how to penalize Ns in the read + penN, // constant if N pelanty is a constant + nCatPair, // true -> concatenate mates before N filtering + penRdExConst, // constant cost of extending a gap in the read + penRfExConst, // constant cost of extending a gap in the reference + penRdExLinear, // coeff of linear term for cost of gap extension in read + penRfExLinear // coeff of linear term for cost of gap extension in ref + ); + // Calculate the penalty ceiling for the read + TAlScore minsc = Scoring::linearFunc( + read.length(), + costMinConst, + costMinLinear); + TAlScore floorsc = Scoring::linearFunc( + read.length(), + costFloorConst, + costFloorLinear); + SwResult res; + SwAligner al; + doTestCase( + al, + read, + qual, + ref, + off, + NULL, + sc, + minsc, + res, + nsInclusive, + nfilter, + seed); +} +#endif /*MAIN_ALIGNER_SW*/ diff --git a/aligner_sw.h b/aligner_sw.h new file mode 100644 index 0000000..add5c87 --- /dev/null +++ b/aligner_sw.h @@ -0,0 +1,648 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* + * aligner_sw.h + * + * Classes and routines for solving dynamic programming problems in aid of read + * alignment. Goals include the ability to handle: + * + * - Both read alignment, where the query must align end-to-end, and local + * alignment, where we seek a high-scoring alignment that need not involve + * the entire query. + * - Situations where: (a) we've found a seed hit and are trying to extend it + * into a larger hit, (b) we've found an alignment for one mate of a pair and + * are trying to find a nearby alignment for the other mate, (c) we're + * aligning against an entire reference sequence. + * - Caller-specified indicators for what columns of the dynamic programming + * matrix we are allowed to start in or end in. + * + * TODO: + * + * - A slicker way to filter out alignments that violate a ceiling placed on + * the number of Ns permitted in the reference portion of the alignment. + * Right now we accomplish this by masking out ending columns that correspond + * to *ungapped* alignments with too many Ns. This results in false + * positives and false negatives for gapped alignments. The margin of error + * (# of Ns by which we might miscount) is bounded by the number of gaps. + */ + +/** + * |-maxgaps-| + * ***********oooooooooooooooooooooo - + * ***********ooooooooooooooooooooo | + * ***********oooooooooooooooooooo | + * ***********ooooooooooooooooooo | + * ***********oooooooooooooooooo | + * ***********ooooooooooooooooo read len + * ***********oooooooooooooooo | + * ***********ooooooooooooooo | + * ***********oooooooooooooo | + * ***********ooooooooooooo | + * ***********oooooooooooo - + * |-maxgaps-| + * |-readlen-| + * |-------skip--------| + */ + +#ifndef ALIGNER_SW_H_ +#define ALIGNER_SW_H_ + +#define INLINE_CUPS + +#include +#include +#include +#include "threading.h" +#include +#include "aligner_sw_common.h" +#include "aligner_sw_nuc.h" +#include "ds.h" +#include "aligner_seed.h" +#include "reference.h" +#include "random_source.h" +#include "mem_ids.h" +#include "aligner_result.h" +#include "mask.h" +#include "dp_framer.h" +#include "aligner_swsse.h" +#include "aligner_bt.h" + +#define QUAL2(d, f) sc_->mm((int)(*rd_)[rdi_ + d], \ + (int) rf_ [rfi_ + f], \ + (int)(*qu_)[rdi_ + d] - 33) +#define QUAL(d) sc_->mm((int)(*rd_)[rdi_ + d], \ + (int)(*qu_)[rdi_ + d] - 33) +#define N_SNP_PEN(c) (((int)rf_[rfi_ + c] > 15) ? sc_->n(30) : sc_->penSnp) + +/** + * SwAligner + * ========= + * + * Ensapsulates facilities for alignment using dynamic programming. Handles + * alignment of nucleotide reads against known reference nucleotides. + * + * The class is stateful. First the user must call init() to initialize the + * object with details regarding the dynamic programming problem to be solved. + * Next, the user calls align() to fill the dynamic programming matrix and + * calculate summaries describing the solutions. Finally the user calls + * nextAlignment(...), perhaps repeatedly, to populate the SwResult object with + * the next result. Results are dispensend in best-to-worst, left-to-right + * order. + * + * The class expects the read string, quality string, and reference string + * provided by the caller live at least until the user is finished aligning and + * obtaining alignments from this object. + * + * There is a design tradeoff between hiding/exposing details of the genome and + * its strands to the SwAligner. In a sense, a better design is to hide + * details such as the id of the reference sequence aligned to, or whether + * we're aligning the read in its original forward orientation or its reverse + * complement. But this means that any alignment results returned by SwAligner + * have to be extended to include those details before they're useful to the + * caller. We opt for messy but expedient - the reference id and orientation + * of the read are given to SwAligner, remembered, and used to populate + * SwResults. + * + * LOCAL VS GLOBAL + * + * The dynamic programming aligner supports both local and global alignment, + * and one option in between. To implement global alignment, the aligner (a) + * allows negative scores (i.e. doesn't necessarily clamp them up to 0), (b) + * checks in rows other than the last row for acceptable solutions, and (c) + * optionally adds a bonus to the score for matches. + * + * For global alignment, we: + * + * (a) Allow negative scores + * (b) Check only in the last row + * (c) Either add a bonus for matches or not (doesn't matter) + * + * For local alignment, we: + * + * (a) Clamp scores to 0 + * (b) Check in any row for a sufficiently high score + * (c) Add a bonus for matches + * + * An in-between solution is to allow alignments to be curtailed on the + * right-hand side if a better score can be achieved thereby, but not on the + * left. For this, we: + * + * (a) Allow negative scores + * (b) Check in any row for a sufficiently high score + * (c) Either add a bonus for matches or not (doesn't matter) + * + * REDUNDANT ALIGNMENTS + * + * When are two alignments distinct and when are they redundant (not distinct)? + * At one extreme, we might say the best alignment from any given dynamic + * programming problem is redundant with all other alignments from that + # problem. At the other extreme, we might say that any two alignments with + * distinct starting points and edits are distinct. The former is probably too + * conservative for mate-finding DP problems. The latter is certainly too + * permissive, since two alignments that differ only in how gaps are arranged + * should not be considered distinct. + * + * Some in-between solutions are: + * + * (a) If two alignments share an end point on either end, they are redundant. + * Otherwise, they are distinct. + * (b) If two alignments share *both* end points, they are redundant. + * (c) If two alignments share any cells in the DP table, they are redundant. + * (d) 2 alignments are redundant if either end within N poss of each other + * (e) Like (d) but both instead of either + * (f, g) Like d, e, but where N is tied to maxgaps somehow + * + * Why not (a)? One reason is that it's possible for two alignments to have + * different start & end positions but share many cells. Consider alignments 1 + * and 2 below; their end-points are labeled. + * + * 1 2 + * \ \ + * -\ + * \ + * \ + * \ + * -\ + * \ \ + * 1 2 + * + * 1 and 2 are distinct according to (a) but they share many cells in common. + * + * Why not (f, g)? It fixes the problem with (a) above by forcing the + * alignments to be spread so far that they can't possibly share diagonal cells + * in common + */ +class SwAligner { + + typedef std::pair SizeTPair; + + // States that the aligner can be in + enum { + STATE_UNINIT, // init() hasn't been called yet + STATE_INITED, // init() has been called, but not align() + STATE_ALIGNED, // align() has been called + }; + + const static size_t ALPHA_SIZE = 5; + +public: + + explicit SwAligner() : + sseU8fw_(DP_CAT), + sseU8rc_(DP_CAT), + sseI16fw_(DP_CAT), + sseI16rc_(DP_CAT), + state_(STATE_UNINIT), + initedRead_(false), + readSse16_(false), + initedRef_(false), + rfwbuf_(DP_CAT), + btnstack_(DP_CAT), + btcells_(DP_CAT), + btdiag_(), + btncand_(DP_CAT), + btncanddone_(DP_CAT), + btncanddoneSucc_(0), + btncanddoneFail_(0), + cper_(), + cperMinlen_(), + cperPerPow2_(), + cperEf_(), + cperTri_(), + colstop_(0), + lastsolcol_(0), + cural_(0) + ASSERT_ONLY(, cand_tmp_(DP_CAT)) + { } + + /** + * Prepare the dynamic programming driver with a new read and a new scoring + * scheme. + */ + void initRead( + const BTDnaString& rdfw, // read sequence for fw read + const BTDnaString& rdrc, // read sequence for rc read + const BTString& qufw, // read qualities for fw read + const BTString& qurc, // read qualities for rc read + size_t rdi, // offset of first read char to align + size_t rdf, // offset of last read char to align + const Scoring& sc); // scoring scheme + + /** + * Initialize with a new alignment problem. + */ + void initRef( + bool fw, // whether to forward or revcomp read is aligning + TRefId refidx, // id of reference aligned against + const DPRect& rect, // DP rectangle + char *rf, // reference sequence + size_t rfi, // offset of first reference char to align to + size_t rff, // offset of last reference char to align to + TRefOff reflen, // length of reference sequence + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum score + bool enable8, // use 8-bit SSE if possible? + size_t cminlen, // minimum length for using checkpointing scheme + size_t cpow2, // interval b/t checkpointed diags; 1 << this + bool doTri, // triangular mini-fills? + bool extend); // true iff this is a seed extension + + /** + * Given a read, an alignment orientation, a range of characters in a + * referece sequence, and a bit-encoded version of the reference, + * execute the corresponding dynamic programming problem. + * + * Here we expect that the caller has already narrowed down the relevant + * portion of the reference (e.g. using a seed hit) and all we do is + * banded dynamic programming in the vicinity of that portion. This is not + * the function to call if we are trying to solve the whole alignment + * problem with dynamic programming (that is TODO). + * + * Returns true if an alignment was found, false otherwise. + */ + void initRef( + bool fw, // whether to forward or revcomp read aligned + TRefId refidx, // reference aligned against + const DPRect& rect, // DP rectangle + const BitPairReference& refs, // Reference strings + TRefOff reflen, // length of reference sequence + const Scoring& sc, // scoring scheme + TAlScore minsc, // minimum alignment score + bool enable8, // use 8-bit SSE if possible? + size_t cminlen, // minimum length for using checkpointing scheme + size_t cpow2, // interval b/t checkpointed diags; 1 << this + bool doTri, // triangular mini-fills? + bool extend, // true iff this is a seed extension + size_t upto, // count the number of Ns up to this offset + size_t& nsUpto); // output: the number of Ns up to 'upto' + + /** + * Given a read, an alignment orientation, a range of characters in a + * referece sequence, and a bit-encoded version of the reference, set up + * and execute the corresponding ungapped alignment problem. There can + * only be one solution. + * + * The caller has already narrowed down the relevant portion of the + * reference using, e.g., the location of a seed hit, or the range of + * possible fragment lengths if we're searching for the opposite mate in a + * pair. + */ + int ungappedAlign( + const BTDnaString& rd, // read sequence (could be RC) + const BTString& qu, // qual sequence (could be rev) + const Coord& coord, // coordinate aligned to + const BitPairReference& refs, // Reference strings + size_t reflen, // length of reference sequence + const Scoring& sc, // scoring scheme + bool ohang, // allow overhang? + TAlScore minsc, // minimum score + SwResult& res); // put alignment result here + + /** + * Align read 'rd' to reference using read & reference information given + * last time init() was called. Uses dynamic programming. + */ + bool align(RandomSource& rnd, TAlScore& best); + + /** + * Populate the given SwResult with information about the "next best" + * alignment if there is one. If there isn't one, false is returned. Note + * that false might be returned even though a call to done() would have + * returned false. + */ + bool nextAlignment( + SwResult& res, + TAlScore minsc, + RandomSource& rnd); + + /** + * Print out an alignment result as an ASCII DP table. + */ + void printResultStacked( + const SwResult& res, + std::ostream& os) + { + res.alres.printStacked(*rd_, os); + } + + /** + * Return true iff there are no more solution cells to backtace from. + * Note that this may return false in situations where there are actually + * no more solutions, but that hasn't been discovered yet. + */ + bool done() const { + assert(initedRead() && initedRef()); + return cural_ == btncand_.size(); + } + + /** + * Return true iff this SwAligner has been initialized with a read to align. + */ + inline bool initedRef() const { return initedRef_; } + + /** + * Return true iff this SwAligner has been initialized with a reference to + * align against. + */ + inline bool initedRead() const { return initedRead_; } + + /** + * Reset, signaling that we're done with this dynamic programming problem + * and won't be asking for any more alignments. + */ + inline void reset() { initedRef_ = initedRead_ = false; } + +#ifndef NDEBUG + /** + * Check that aligner is internally consistent. + */ + bool repOk() const { + assert_gt(dpRows(), 0); + // Check btncand_ + for(size_t i = 0; i < btncand_.size(); i++) { + assert(btncand_[i].repOk()); + assert_geq(btncand_[i].score, minsc_); + } + return true; + } +#endif + + /** + * Return the number of alignments given out so far by nextAlignment(). + */ + size_t numAlignmentsReported() const { return cural_; } + + /** + * Merge tallies in the counters related to filling the DP table. + */ + void merge( + SSEMetrics& sseU8ExtendMet, + SSEMetrics& sseU8MateMet, + SSEMetrics& sseI16ExtendMet, + SSEMetrics& sseI16MateMet, + uint64_t& nbtfiltst, + uint64_t& nbtfiltsc, + uint64_t& nbtfiltdo) + { + sseU8ExtendMet.merge(sseU8ExtendMet_); + sseU8MateMet.merge(sseU8MateMet_); + sseI16ExtendMet.merge(sseI16ExtendMet_); + sseI16MateMet.merge(sseI16MateMet_); + nbtfiltst += nbtfiltst_; + nbtfiltsc += nbtfiltsc_; + nbtfiltdo += nbtfiltdo_; + } + + /** + * Reset all the counters related to filling in the DP table to 0. + */ + void resetCounters() { + sseU8ExtendMet_.reset(); + sseU8MateMet_.reset(); + sseI16ExtendMet_.reset(); + sseI16MateMet_.reset(); + nbtfiltst_ = nbtfiltsc_ = nbtfiltdo_ = 0; + } + + /** + * Return the size of the DP problem. + */ + size_t size() const { + return dpRows() * (rff_ - rfi_); + } + +protected: + + /** + * Return the number of rows that will be in the dynamic programming table. + */ + inline size_t dpRows() const { + assert(initedRead_); + return rdf_ - rdi_; + } + + /** + * Align nucleotides from read 'rd' to the reference string 'rf' using + * vector instructions. Return the score of the best alignment found, or + * the minimum integer if an alignment could not be found. Flag is set to + * 0 if an alignment is found, -1 if no valid alignment is found, or -2 if + * the score saturated at any point during alignment. + */ + TAlScore alignNucleotidesEnd2EndSseU8( // unsigned 8-bit elements + int& flag, bool debug); + TAlScore alignNucleotidesLocalSseU8( // unsigned 8-bit elements + int& flag, bool debug); + TAlScore alignNucleotidesEnd2EndSseI16( // signed 16-bit elements + int& flag, bool debug); + TAlScore alignNucleotidesLocalSseI16( // signed 16-bit elements + int& flag, bool debug); + + /** + * Aligns by filling a dynamic programming matrix with the SSE-accelerated, + * banded DP approach of Farrar. As it goes, it determines which cells we + * might backtrace from and tallies the best (highest-scoring) N backtrace + * candidate cells per diagonal. Also returns the alignment score of the best + * alignment in the matrix. + * + * This routine does *not* maintain a matrix holding the entire matrix worth of + * scores, nor does it maintain any other dense O(mn) data structure, as this + * would quickly exhaust memory for queries longer than about 10,000 kb. + * Instead, in the fill stage it maintains two columns worth of scores at a + * time (current/previous, or right/left) - these take O(m) space. When + * finished with the current column, it determines which cells from the + * previous column, if any, are candidates we might backtrace from to find a + * full alignment. A candidate cell has a score that rises above the threshold + * and isn't improved upon by a match in the next column. The best N + * candidates per diagonal are stored in a O(m + n) data structure. + */ + TAlScore alignGatherEE8( // unsigned 8-bit elements + int& flag, bool debug); + TAlScore alignGatherLoc8( // unsigned 8-bit elements + int& flag, bool debug); + TAlScore alignGatherEE16( // signed 16-bit elements + int& flag, bool debug); + TAlScore alignGatherLoc16( // signed 16-bit elements + int& flag, bool debug); + + /** + * Build query profile look up tables for the read. The query profile look + * up table is organized as a 1D array indexed by [i][j] where i is the + * reference character in the current DP column (0=A, 1=C, etc), and j is + * the segment of the query we're currently working on. + */ + void buildQueryProfileEnd2EndSseU8(bool fw); + void buildQueryProfileLocalSseU8(bool fw); + + /** + * Build query profile look up tables for the read. The query profile look + * up table is organized as a 1D array indexed by [i][j] where i is the + * reference character in the current DP column (0=A, 1=C, etc), and j is + * the segment of the query we're currently working on. + */ + void buildQueryProfileEnd2EndSseI16(bool fw); + void buildQueryProfileLocalSseI16(bool fw); + + bool gatherCellsNucleotidesLocalSseU8(TAlScore best); + bool gatherCellsNucleotidesEnd2EndSseU8(TAlScore best); + + bool gatherCellsNucleotidesLocalSseI16(TAlScore best); + bool gatherCellsNucleotidesEnd2EndSseI16(TAlScore best); + + bool backtraceNucleotidesLocalSseU8( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this rectangle row + size_t col, // start in this rectangle column + RandomSource& rand); // random gen, to choose among equal paths + + bool backtraceNucleotidesLocalSseI16( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this rectangle row + size_t col, // start in this rectangle column + RandomSource& rand); // random gen, to choose among equal paths + + bool backtraceNucleotidesEnd2EndSseU8( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this rectangle row + size_t col, // start in this rectangle column + RandomSource& rand); // random gen, to choose among equal paths + + bool backtraceNucleotidesEnd2EndSseI16( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this rectangle row + size_t col, // start in this rectangle column + RandomSource& rand); // random gen, to choose among equal paths + + bool backtrace( + TAlScore escore, // in: expected score + bool fill, // in: use mini-fill? + bool usecp, // in: use checkpoints? + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t row, // start in this rectangle row + size_t col, // start in this rectangle column + size_t maxiter,// max # extensions to try + size_t& niter, // # extensions tried + RandomSource& rnd) // random gen, to choose among equal paths + { + bter_.initBt( + escore, // in: alignment score + row, // in: start in this row + col, // in: start in this column + fill, // in: use mini-fill? + usecp, // in: use checkpoints? + cperTri_, // in: triangle-shaped mini-fills? + rnd); // in: random gen, to choose among equal paths + assert(bter_.inited()); + size_t nrej = 0; + if(bter_.emptySolution()) { + return false; + } else { + return bter_.nextAlignment(maxiter, res, off, nrej, niter, rnd); + } + } + + const BTDnaString *rd_; // read sequence + const BTString *qu_; // read qualities + const BTDnaString *rdfw_; // read sequence for fw read + const BTDnaString *rdrc_; // read sequence for rc read + const BTString *qufw_; // read qualities for fw read + const BTString *qurc_; // read qualities for rc read + TReadOff rdi_; // offset of first read char to align + TReadOff rdf_; // offset of last read char to align + bool fw_; // true iff read sequence is original fw read + TRefId refidx_; // id of reference aligned against + TRefOff reflen_; // length of entire reference sequence + const DPRect* rect_; // DP rectangle + char *rf_; // reference sequence + TRefOff rfi_; // offset of first ref char to align to + TRefOff rff_; // offset of last ref char to align to (excl) + size_t rdgap_; // max # gaps in read + size_t rfgap_; // max # gaps in reference + bool enable8_;// enable 8-bit sse + bool extend_; // true iff this is a seed-extend problem + const Scoring *sc_; // penalties for edit types + TAlScore minsc_; // penalty ceiling for valid alignments + int nceil_; // max # Ns allowed in ref portion of aln + + bool sse8succ_; // whether 8-bit worked + bool sse16succ_; // whether 16-bit worked + SSEData sseU8fw_; // buf for fw query, 8-bit score + SSEData sseU8rc_; // buf for rc query, 8-bit score + SSEData sseI16fw_; // buf for fw query, 16-bit score + SSEData sseI16rc_; // buf for rc query, 16-bit score + bool sseU8fwBuilt_; // built fw query profile, 8-bit score + bool sseU8rcBuilt_; // built rc query profile, 8-bit score + bool sseI16fwBuilt_; // built fw query profile, 16-bit score + bool sseI16rcBuilt_; // built rc query profile, 16-bit score + + SSEMetrics sseU8ExtendMet_; + SSEMetrics sseU8MateMet_; + SSEMetrics sseI16ExtendMet_; + SSEMetrics sseI16MateMet_; + + int state_; // state + bool initedRead_; // true iff initialized with initRead + bool readSse16_; // true -> sse16 from now on for read + bool initedRef_; // true iff initialized with initRef + EList rfwbuf_; // buffer for wordized ref stretches + + EList btnstack_; // backtrace stack for nucleotides + EList btcells_; // cells involved in current backtrace + + NBest btdiag_; // per-diagonal backtrace candidates + EList btncand_; // cells we might backtrace from + EList btncanddone_; // candidates that we investigated + size_t btncanddoneSucc_; // # investigated and succeeded + size_t btncanddoneFail_; // # investigated and failed + + BtBranchTracer bter_; // backtracer + + Checkpointer cper_; // structure for saving checkpoint cells + size_t cperMinlen_; // minimum length for using checkpointer + size_t cperPerPow2_; // checkpoint every 1 << perpow2 diags (& next) + bool cperEf_; // store E and F in addition to H? + bool cperTri_; // checkpoint for triangular mini-fills? + + size_t colstop_; // bailed on DP loop after this many cols + size_t lastsolcol_; // last DP col with valid cell + size_t cural_; // index of next alignment to be given + + uint64_t nbtfiltst_; // # candidates filtered b/c starting cell was seen + uint64_t nbtfiltsc_; // # candidates filtered b/c score uninteresting + uint64_t nbtfiltdo_; // # candidates filtered b/c dominated by other cell + + ASSERT_ONLY(SStringExpandable tmp_destU32_); + ASSERT_ONLY(BTDnaString tmp_editstr_, tmp_refstr_); + ASSERT_ONLY(EList cand_tmp_); +}; + +#endif /*ALIGNER_SW_H_*/ diff --git a/aligner_sw_common.h b/aligner_sw_common.h new file mode 100644 index 0000000..639a3c6 --- /dev/null +++ b/aligner_sw_common.h @@ -0,0 +1,305 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_SW_COMMON_H_ +#define ALIGNER_SW_COMMON_H_ + +#include "aligner_result.h" + +/** + * Encapsulates the result of a dynamic programming alignment, including + * colorspace alignments. In our case, the result is a combination of: + * + * 1. All the nucleotide edits + * 2. All the "edits" where an ambiguous reference char is resolved to + * an unambiguous char. + * 3. All the color edits (if applicable) + * 4. All the color miscalls (if applicable). This is a subset of 3. + * 5. The score of the best alginment + * 6. The score of the second-best alignment + * + * Having scores for the best and second-best alignments gives us an + * idea of where gaps may make reassembly beneficial. + */ +struct SwResult { + + SwResult() : + alres(), + sws(0), + swcups(0), + swrows(0), + swskiprows(0), + swskip(0), + swsucc(0), + swfail(0), + swbts(0) + { } + + /** + * Clear all contents. + */ + void reset() { + sws = swcups = swrows = swskiprows = swskip = swsucc = + swfail = swbts = 0; + alres.reset(); + } + + /** + * Reverse all edit lists. + */ + void reverse() { + alres.reverseEdits(); + } + + /** + * Return true iff no result has been installed. + */ + bool empty() const { + return alres.empty(); + } + +#ifndef NDEBUG + /** + * Check that result is internally consistent. + */ + bool repOk() const { + assert(alres.repOk()); + return true; + } + + /** + * Check that result is internally consistent w/r/t read. + */ + bool repOk(const Read& rd) const { + assert(alres.repOk(rd)); + return true; + } +#endif + + AlnRes alres; + uint64_t sws; // # DP problems solved + uint64_t swcups; // # DP cell updates + uint64_t swrows; // # DP row updates + uint64_t swskiprows; // # skipped DP row updates (b/c no valid alignments can go thru row) + uint64_t swskip; // # DP problems skipped by sse filter + uint64_t swsucc; // # DP problems resulting in alignment + uint64_t swfail; // # DP problems not resulting in alignment + uint64_t swbts; // # DP backtrace steps + + int nup; // upstream decoded nucleotide; for colorspace reads + int ndn; // downstream decoded nucleotide; for colorspace reads +}; + +/** + * Encapsulates counters that measure how much work has been done by + * the dynamic programming driver and aligner. + */ +struct SwMetrics { + + SwMetrics() : mutex_m() { + reset(); + } + + void reset() { + sws = swcups = swrows = swskiprows = swskip = swsucc = swfail = swbts = + sws10 = sws5 = sws3 = + rshit = ungapsucc = ungapfail = ungapnodec = 0; + exatts = exranges = exrows = exsucc = exooms = 0; + mm1atts = mm1ranges = mm1rows = mm1succ = mm1ooms = 0; + sdatts = sdranges = sdrows = sdsucc = sdooms = 0; + } + + void init( + uint64_t sws_, + uint64_t sws10_, + uint64_t sws5_, + uint64_t sws3_, + uint64_t swcups_, + uint64_t swrows_, + uint64_t swskiprows_, + uint64_t swskip_, + uint64_t swsucc_, + uint64_t swfail_, + uint64_t swbts_, + uint64_t rshit_, + uint64_t ungapsucc_, + uint64_t ungapfail_, + uint64_t ungapnodec_, + uint64_t exatts_, + uint64_t exranges_, + uint64_t exrows_, + uint64_t exsucc_, + uint64_t exooms_, + uint64_t mm1atts_, + uint64_t mm1ranges_, + uint64_t mm1rows_, + uint64_t mm1succ_, + uint64_t mm1ooms_, + uint64_t sdatts_, + uint64_t sdranges_, + uint64_t sdrows_, + uint64_t sdsucc_, + uint64_t sdooms_) + { + sws = sws_; + sws10 = sws10_; + sws5 = sws5_; + sws3 = sws3_; + swcups = swcups_; + swrows = swrows_; + swskiprows = swskiprows_; + swskip = swskip_; + swsucc = swsucc_; + swfail = swfail_; + swbts = swbts_; + ungapsucc = ungapsucc_; + ungapfail = ungapfail_; + ungapnodec = ungapnodec_; + + // Exact end-to-end attempts + exatts = exatts_; + exranges = exranges_; + exrows = exrows_; + exsucc = exsucc_; + exooms = exooms_; + + // 1-mismatch end-to-end attempts + mm1atts = mm1atts_; + mm1ranges = mm1ranges_; + mm1rows = mm1rows_; + mm1succ = mm1succ_; + mm1ooms = mm1ooms_; + + // Seed attempts + sdatts = sdatts_; + sdranges = sdranges_; + sdrows = sdrows_; + sdsucc = sdsucc_; + sdooms = sdooms_; + } + + /** + * Merge (add) the counters in the given SwResult object into this + * SwMetrics object. + */ + void update(const SwResult& r) { + sws += r.sws; + swcups += r.swcups; + swrows += r.swrows; + swskiprows += r.swskiprows; + swskip += r.swskip; + swsucc += r.swsucc; + swfail += r.swfail; + swbts += r.swbts; + } + + /** + * Merge (add) the counters in the given SwMetrics object into this + * object. This is the only safe way to update a SwMetrics shared + * by multiple threads. + */ + void merge(const SwMetrics& r, bool getLock = false) { + ThreadSafe ts(&mutex_m, getLock); + sws += r.sws; + sws10 += r.sws10; + sws5 += r.sws5; + sws3 += r.sws3; + swcups += r.swcups; + swrows += r.swrows; + swskiprows += r.swskiprows; + swskip += r.swskip; + swsucc += r.swsucc; + swfail += r.swfail; + swbts += r.swbts; + rshit += r.rshit; + ungapsucc += r.ungapsucc; + ungapfail += r.ungapfail; + ungapnodec += r.ungapnodec; + exatts += r.exatts; + exranges += r.exranges; + exrows += r.exrows; + exsucc += r.exsucc; + exooms += r.exooms; + mm1atts += r.mm1atts; + mm1ranges += r.mm1ranges; + mm1rows += r.mm1rows; + mm1succ += r.mm1succ; + mm1ooms += r.mm1ooms; + sdatts += r.sdatts; + sdranges += r.sdranges; + sdrows += r.sdrows; + sdsucc += r.sdsucc; + sdooms += r.sdooms; + } + + void tallyGappedDp(size_t readGaps, size_t refGaps) { + size_t mx = max(readGaps, refGaps); + if(mx < 10) sws10++; + if(mx < 5) sws5++; + if(mx < 3) sws3++; + } + + uint64_t sws; // # DP problems solved + uint64_t sws10; // # DP problems solved where max gaps < 10 + uint64_t sws5; // # DP problems solved where max gaps < 5 + uint64_t sws3; // # DP problems solved where max gaps < 3 + uint64_t swcups; // # DP cell updates + uint64_t swrows; // # DP row updates + uint64_t swskiprows; // # skipped DP rows (b/c no valid alns go thru row) + uint64_t swskip; // # DP problems skipped by sse filter + uint64_t swsucc; // # DP problems resulting in alignment + uint64_t swfail; // # DP problems not resulting in alignment + uint64_t swbts; // # DP backtrace steps + uint64_t rshit; // # DP problems avoided b/c seed hit was redundant + uint64_t ungapsucc; // # DP problems avoided b/c seed hit was redundant + uint64_t ungapfail; // # DP problems avoided b/c seed hit was redundant + uint64_t ungapnodec; // # DP problems avoided b/c seed hit was redundant + + uint64_t exatts; // total # attempts at exact-hit end-to-end aln + uint64_t exranges; // total # ranges returned by exact-hit queries + uint64_t exrows; // total # rows returned by exact-hit queries + uint64_t exsucc; // exact-hit yielded non-empty result + uint64_t exooms; // exact-hit offset memory exhausted + + uint64_t mm1atts; // total # attempts at 1mm end-to-end aln + uint64_t mm1ranges; // total # ranges returned by 1mm-hit queries + uint64_t mm1rows; // total # rows returned by 1mm-hit queries + uint64_t mm1succ; // 1mm-hit yielded non-empty result + uint64_t mm1ooms; // 1mm-hit offset memory exhausted + + uint64_t sdatts; // total # attempts to find seed alignments + uint64_t sdranges; // total # seed-alignment ranges found + uint64_t sdrows; // total # seed-alignment rows found + uint64_t sdsucc; // # times seed alignment yielded >= 1 hit + uint64_t sdooms; // # times an OOM occurred during seed alignment + + MUTEX_T mutex_m; +}; + +// The various ways that one might backtrack from a later cell (either oall, +// rdgap or rfgap) to an earlier cell +enum { + SW_BT_OALL_DIAG, // from oall cell to oall cell + SW_BT_OALL_REF_OPEN, // from oall cell to oall cell + SW_BT_OALL_READ_OPEN, // from oall cell to oall cell + SW_BT_RDGAP_EXTEND, // from rdgap cell to rdgap cell + SW_BT_RFGAP_EXTEND // from rfgap cell to rfgap cell +}; + +#endif /*def ALIGNER_SW_COMMON_H_*/ diff --git a/aligner_sw_driver.cpp b/aligner_sw_driver.cpp new file mode 100644 index 0000000..d0be5f2 --- /dev/null +++ b/aligner_sw_driver.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + + diff --git a/aligner_sw_driver.h b/aligner_sw_driver.h new file mode 100644 index 0000000..075f614 --- /dev/null +++ b/aligner_sw_driver.h @@ -0,0 +1,2938 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* + * aligner_sw_driver.h + * + * REDUNDANT SEED HITS + * + * We say that two seed hits are redundant if they trigger identical + * seed-extend dynamic programming problems. Put another way, they both lie on + * the same diagonal of the overall read/reference dynamic programming matrix. + * Detecting redundant seed hits is simple when the seed hits are ungapped. We + * do this after offset resolution but before the offset is converted to genome + * coordinates (see uses of the seenDiags1_/seenDiags2_ fields for examples). + * + * REDUNDANT ALIGNMENTS + * + * In an unpaired context, we say that two alignments are redundant if they + * share any cells in the global DP table. Roughly speaking, this is like + * saying that two alignments are redundant if any read character aligns to the + * same reference character (same reference sequence, same strand, same offset) + * in both alignments. + * + * In a paired-end context, we say that two paired-end alignments are redundant + * if the mate #1s are redundant and the mate #2s are redundant. + * + * How do we enforce this? In the unpaired context, this is relatively simple: + * the cells from each alignment are checked against a set containing all cells + * from all previous alignments. Given a new alignment, for each cell in the + * new alignment we check whether it is in the set. If there is any overlap, + * the new alignment is rejected as redundant. Otherwise, the new alignment is + * accepted and its cells are added to the set. + * + * Enforcement in a paired context is a little trickier. Consider the + * following approaches: + * + * 1. Skip anchors that are redundant with any previous anchor or opposite + * alignment. This is sufficient to ensure no two concordant alignments + * found are redundant. + * + * 2. Same as scheme 1, but with a "transitive closure" scheme for finding all + * concordant pairs in the vicinity of an anchor. Consider the AB/AC + * scenario from the previous paragraph. If B is the anchor alignment, we + * will find AB but not AC. But under this scheme, once we find AB we then + * let B be a new anchor and immediately look for its opposites. Likewise, + * if we find any opposite, we make them anchors and continue searching. We + * don't stop searching until every opposite is used as an anchor. + * + * 3. Skip anchors that are redundant with any previous anchor alignment (but + * allow anchors that are redundant with previous opposite alignments). + * This isn't sufficient to avoid redundant concordant alignments. To avoid + * redundant concordants, we need an additional procedure that checks each + * new concordant alignment one-by-one against a list of previous concordant + * alignments to see if it is redundant. + * + * We take approach 1. + */ + +#ifndef ALIGNER_SW_DRIVER_H_ +#define ALIGNER_SW_DRIVER_H_ + +#include +// -- BTL remove -- +#include +#include +// -- -- +#include +#include "ds.h" +#include "aligner_seed.h" +#include "aligner_sw.h" +#include "aligner_cache.h" +#include "reference.h" +#include "group_walk.h" +#include "gfm.h" +#include "mem_ids.h" +#include "aln_sink.h" +#include "pe.h" +#include "ival_list.h" +#include "simple_func.h" +#include "random_util.h" +#include "dp_framer.h" + +using namespace std; + +template +struct SeedPos { + + SeedPos() : fw(false), offidx(0), rdoff(0), seedlen(0) { } + + SeedPos( + bool fw_, + index_t offidx_, + index_t rdoff_, + index_t seedlen_) + { + init(fw_, offidx_, rdoff_, seedlen_); + } + + void init( + bool fw_, + index_t offidx_, + index_t rdoff_, + index_t seedlen_) + { + fw = fw_; + offidx = offidx_; + rdoff = rdoff_; + seedlen = seedlen_; + } + + bool operator<(const SeedPos& o) const { + if(offidx < o.offidx) return true; + if(offidx > o.offidx) return false; + if(rdoff < o.rdoff) return true; + if(rdoff > o.rdoff) return false; + if(seedlen < o.seedlen) return true; + if(seedlen > o.seedlen) return false; + if(fw && !o.fw) return true; + if(!fw && o.fw) return false; + return false; + } + + bool operator>(const SeedPos& o) const { + if(offidx < o.offidx) return false; + if(offidx > o.offidx) return true; + if(rdoff < o.rdoff) return false; + if(rdoff > o.rdoff) return true; + if(seedlen < o.seedlen) return false; + if(seedlen > o.seedlen) return true; + if(fw && !o.fw) return false; + if(!fw && o.fw) return true; + return false; + } + + bool operator==(const SeedPos& o) const { + return fw == o.fw && offidx == o.offidx && + rdoff == o.rdoff && seedlen == o.seedlen; + } + + bool fw; + index_t offidx; + index_t rdoff; + index_t seedlen; +}; + +/** + * An SATuple along with the associated seed position. + */ +template +struct SATupleAndPos { + + SATuple sat; // result for this seed hit + SeedPos pos; // seed position that yielded the range this was taken from + index_t origSz; // size of range this was taken from + index_t nlex; // # position we can extend seed hit to left w/o edit + index_t nrex; // # position we can extend seed hit to right w/o edit + + bool operator<(const SATupleAndPos& o) const { + if(sat < o.sat) return true; + if(sat > o.sat) return false; + return pos < o.pos; + } + + bool operator==(const SATupleAndPos& o) const { + return sat == o.sat && pos == o.pos; + } +}; + +/** + * Encapsulates the weighted random sampling scheme we want to use to pick + * which seed hit range to sample a row from. + */ +template +class RowSampler { + +public: + + RowSampler(int cat = 0) : elim_(cat), masses_(cat) { + mass_ = 0.0f; + } + + /** + * Initialze sampler with respect to a range of elements in a list of + * SATupleAndPos's. + */ + void init( + const EList, 16>& salist, + index_t sai, + index_t saf, + bool lensq, // whether to square the numerator, which = extended length + bool szsq) // whether to square denominator, which = + { + assert_gt(saf, sai); + elim_.resize(saf - sai); + elim_.fill(false); + // Initialize mass + mass_ = 0.0f; + masses_.resize(saf - sai); + for(index_t i = sai; i < saf; i++) { + index_t len = salist[i].nlex + salist[i].nrex + 1; // + salist[i].sat.key.len; + double num = (double)len; + if(lensq) { + num *= num; + } + double denom = (double)salist[i].sat.size(); + if(szsq) { + denom *= denom; + } + masses_[i - sai] = num / denom; + mass_ += masses_[i - sai]; + } + } + + /** + * Caller is indicating that the bin at index i is exhausted and we should + * exclude it from our sampling from now on. + */ + void finishedRange(index_t i) { + assert_lt(i, masses_.size()); + elim_[i] = true; + mass_ -= masses_[i]; + } + + /** + * Sample randomly from the mass. + */ + size_t next(RandomSource& rnd) { + // Throw the dart + double rd = rnd.nextFloat() * mass_; + double mass_sofar = 0.0f; + size_t sz = masses_.size(); + size_t last_unelim = std::numeric_limits::max(); + for(size_t i = 0; i < sz; i++) { + if(!elim_[i]) { + last_unelim = i; + mass_sofar += masses_[i]; + if(rd < mass_sofar) { + // This is the one we hit + return i; + } + } + } + assert_neq(std::numeric_limits::max(), last_unelim); + return last_unelim; + } + +protected: + double mass_; // total probability mass to throw darts at + EList elim_; // whether the range is eliminated + EList masses_; // mass of each range +}; + +/** + * Return values from extendSeeds and extendSeedsPaired. + */ +enum { + // All end-to-end and seed hits were examined + // The policy does not need us to look any further + EXTEND_EXHAUSTED_CANDIDATES = 1, + EXTEND_POLICY_FULFILLED, + // We stopped because we reached a point where the only remaining + // alignments of interest have perfect scores, but we already investigated + // perfect alignments + EXTEND_PERFECT_SCORE, + // We stopped because we ran up against a limit on how much work we should + // do for one set of seed ranges, e.g. the limit on number of consecutive + // unproductive DP extensions + EXTEND_EXCEEDED_SOFT_LIMIT, + // We stopped because we ran up against a limit on how much work we should + // do for overall before giving up on a mate + EXTEND_EXCEEDED_HARD_LIMIT +}; + +/** + * Data structure encapsulating a range that's been extended out in two + * directions. + */ +struct ExtendRange { + + void init(size_t off_, size_t len_, size_t sz_) { + off = off_; len = len_; sz = sz_; + } + + size_t off; // offset of extended region + size_t len; // length between extremes of extended region + size_t sz; // # of elements in SA range +}; + +template +class SwDriver { + + typedef PList TSAList; + +public: + + SwDriver(size_t bytes) : + satups_(DP_CAT), + gws_(DP_CAT), + seenDiags1_(DP_CAT), + seenDiags2_(DP_CAT), + redAnchor_(DP_CAT), + redMate1_(DP_CAT), + redMate2_(DP_CAT), + pool_(bytes, CACHE_PAGE_SZ, DP_CAT), + salistEe_(DP_CAT), + gwstate_(GW_CAT) { } + + /** + * Given a collection of SeedHits for a single read, extend seed alignments + * into full alignments. Where possible, try to avoid redundant offset + * lookups and dynamic programming problems. Optionally report alignments + * to a AlnSinkWrap object as they are discovered. + * + * If 'reportImmediately' is true, returns true iff a call to + * mhs->report() returned true (indicating that the reporting + * policy is satisfied and we can stop). Otherwise, returns false. + */ + int extendSeeds( + Read& rd, // read to align + bool mate1, // true iff rd is mate #1 + SeedResults& sh, // seed hits to extend into full alignments + const GFM& gfmFw, // BWT + const GFM* gfmBw, // BWT' + const BitPairReference& ref, // Reference strings + SwAligner& swa, // dynamic programming aligner + const Scoring& sc, // scoring scheme + int seedmms, // # mismatches allowed in seed + int seedlen, // length of seed + int seedival, // interval between seeds + TAlScore& minsc, // minimum score for anchor + int nceil, // maximum # Ns permitted in ref portion + size_t maxhalf, // maximum width on one side of DP table + bool doUngapped, // do ungapped alignment + size_t maxIters, // stop after this many seed-extend loop iters + size_t maxUg, // max # ungapped extends + size_t maxDp, // max # DPs + size_t maxUgStreak, // stop after streak of this many ungap fails + size_t maxDpStreak, // stop after streak of this many dp fails + bool doExtend, // do seed extension + bool enable8, // use 8-bit SSE where possible + size_t cminlen, // use checkpointer if read longer than this + size_t cpow2, // interval between diagonals to checkpoint + bool doTri, // triangular mini-fills + int tighten, // -M score tightening mode + AlignmentCacheIface& ca, // alignment cache for seed hits + RandomSource& rnd, // pseudo-random source + WalkMetrics& wlm, // group walk left metrics + SwMetrics& swmSeed, // DP metrics for seed-extend + PerReadMetrics& prm, // per-read metrics + AlnSinkWrap* mhs, // HitSink for multiseed-style aligner + bool reportImmediately, // whether to report hits immediately to mhs + bool& exhaustive); + + /** + * Given a collection of SeedHits for a read pair, extend seed + * alignments into full alignments and then look for the opposite + * mate using dynamic programming. Where possible, try to avoid + * redundant offset lookups. Optionally report alignments to a + * AlnSinkWrap object as they are discovered. + * + * If 'reportImmediately' is true, returns true iff a call to + * mhs->report() returned true (indicating that the reporting + * policy is satisfied and we can stop). Otherwise, returns false. + */ + int extendSeedsPaired( + Read& rd, // mate to align as anchor + Read& ord, // mate to align as opposite + bool anchor1, // true iff anchor mate is mate1 + bool oppFilt, // true iff opposite mate was filtered out + SeedResults& sh, // seed hits for anchor + const GFM& gfmFw, // BWT + const GFM* gfmBw, // BWT' + const BitPairReference& ref, // Reference strings + SwAligner& swa, // dyn programming aligner for anchor + SwAligner& swao, // dyn programming aligner for opposite + const Scoring& sc, // scoring scheme + const PairedEndPolicy& pepol,// paired-end policy + int seedmms, // # mismatches allowed in seed + int seedlen, // length of seed + int seedival, // interval between seeds + TAlScore& minsc, // minimum score for anchor + TAlScore& ominsc, // minimum score for opposite + int nceil, // max # Ns permitted in ref for anchor + int onceil, // max # Ns permitted in ref for opposite + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + size_t maxhalf, // maximum width on one side of DP table + bool doUngapped, // do ungapped alignment + size_t maxIters, // stop after this many seed-extend loop iters + size_t maxUg, // max # ungapped extends + size_t maxDp, // max # DPs + size_t maxEeStreak, // stop after streak of this many end-to-end fails + size_t maxUgStreak, // stop after streak of this many ungap fails + size_t maxDpStreak, // stop after streak of this many dp fails + size_t maxMateStreak, // stop seed range after N mate-find fails + bool doExtend, // do seed extension + bool enable8, // use 8-bit SSE where possible + size_t cminlen, // use checkpointer if read longer than this + size_t cpow2, // interval between diagonals to checkpoint + bool doTri, // triangular mini-fills + int tighten, // -M score tightening mode + AlignmentCacheIface& cs, // alignment cache for seed hits + RandomSource& rnd, // pseudo-random source + WalkMetrics& wlm, // group walk left metrics + SwMetrics& swmSeed, // DP metrics for seed-extend + SwMetrics& swmMate, // DP metrics for mate finidng + PerReadMetrics& prm, // per-read metrics for anchor + AlnSinkWrap* msink, // AlnSink wrapper for multiseed-style aligner + bool swMateImmediately, // whether to look for mate immediately + bool reportImmediately, // whether to report hits immediately to msink + bool discord, // look for discordant alignments? + bool mixed, // look for unpaired as well as paired alns? + bool& exhaustive); + + /** + * Prepare for a new read. + */ + void nextRead(bool paired, size_t mate1len, size_t mate2len) { + redAnchor_.reset(); + seenDiags1_.reset(); + seenDiags2_.reset(); + seedExRangeFw_[0].clear(); // mate 1 fw + seedExRangeFw_[1].clear(); // mate 2 fw + seedExRangeRc_[0].clear(); // mate 1 rc + seedExRangeRc_[1].clear(); // mate 2 rc + size_t maxlen = mate1len; + if(paired) { + redMate1_.reset(); + redMate1_.init(mate1len); + redMate2_.reset(); + redMate2_.init(mate2len); + if(mate2len > maxlen) { + maxlen = mate2len; + } + } + redAnchor_.init(maxlen); + } + +protected: + + bool eeSaTups( + const Read& rd, // read + SeedResults& sh, // seed hits to extend into full alignments + const GFM& gfm, // BWT + const BitPairReference& ref, // Reference strings + RandomSource& rnd, // pseudo-random generator + WalkMetrics& wlm, // group walk left metrics + SwMetrics& swmSeed, // metrics for seed extensions + index_t& nelt_out, // out: # elements total + index_t maxelts, // max # elts to report + bool all); // report all hits? + + void extend( + const Read& rd, // read + const GFM& gfmFw, // Forward Bowtie index + const GFM* gfmBw, // Backward Bowtie index + index_t topf, // top in fw index + index_t botf, // bot in fw index + index_t topb, // top in bw index + index_t botb, // bot in bw index + bool fw, // seed orientation + index_t off, // seed offset from 5' end + index_t len, // seed length + PerReadMetrics& prm, // per-read metrics + index_t& nlex, // # positions we can extend to left w/o edit + index_t& nrex); // # positions we can extend to right w/o edit + + void prioritizeSATups( + const Read& rd, // read + SeedResults& sh, // seed hits to extend into full alignments + const GFM& gfmFw, // BWT + const GFM* gfmBw, // BWT' + const BitPairReference& ref, // Reference strings + int seedmms, // # seed mismatches allowed + index_t maxelt, // max elts we'll consider + bool doExtend, // extend out seeds + bool lensq, // square extended length + bool szsq, // square SA range size + index_t nsm, // if range as <= nsm elts, it's "small" + AlignmentCacheIface& ca, // alignment cache for seed hits + RandomSource& rnd, // pseudo-random generator + WalkMetrics& wlm, // group walk left metrics + PerReadMetrics& prm, // per-read metrics + index_t& nelt_out, // out: # elements total + bool all); // report all hits? + + Random1toN rand_; // random number generators + EList rands_; // random number generators + EList rands2_; // random number generators + EList, 16> eehits_; // holds end-to-end hits + EList, 16> satpos_; // holds SATuple, SeedPos pairs + EList, 16> satpos2_; // holds SATuple, SeedPos pairs + EList, 16> satups_; // holds SATuples to explore elements from + EList > gws_; // list of GroupWalks; no particular order + EList mateStreaks_; // mate-find fail streaks + RowSampler rowsamp_; // row sampler + + // Ranges that we've extended through when extending seed hits + EList seedExRangeFw_[2]; + EList seedExRangeRc_[2]; + + // Data structures encapsulating the diagonals that have already been used + // to seed alignment for mate 1 and mate 2. + EIvalMergeListBinned seenDiags1_; + EIvalMergeListBinned seenDiags2_; + + // For weeding out redundant alignments + RedundantAlns redAnchor_; // database of cells used for anchor alignments + RedundantAlns redMate1_; // database of cells used for mate 1 alignments + RedundantAlns redMate2_; // database of cells used for mate 2 alignments + + // For holding results for anchor (res_) and opposite (ores_) mates + SwResult resGap_; // temp holder for alignment result + SwResult oresGap_; // temp holder for alignment result, opp mate + SwResult resUngap_; // temp holder for ungapped alignment result + SwResult oresUngap_; // temp holder for ungap. aln. opp mate + SwResult resEe_; // temp holder for ungapped alignment result + SwResult oresEe_; // temp holder for ungap. aln. opp mate + + Pool pool_; // memory pages for salistExact_ + TSAList salistEe_; // PList for offsets for end-to-end hits + GroupWalkState gwstate_; // some per-thread state shared by all GroupWalks + + // For AlnRes::matchesRef: + ASSERT_ONLY(SStringExpandable raw_refbuf_); + ASSERT_ONLY(SStringExpandable raw_destU32_); + ASSERT_ONLY(EList raw_matches_); + ASSERT_ONLY(BTDnaString tmp_rf_); + ASSERT_ONLY(BTDnaString tmp_rdseq_); + ASSERT_ONLY(BTString tmp_qseq_); + ASSERT_ONLY(EList tmp_reflens_); + ASSERT_ONLY(EList tmp_refoffs_); +}; + +#define TIMER_START() \ +struct timeval tv_i, tv_f; \ +struct timezone tz_i, tz_f; \ +size_t total_usecs; \ +gettimeofday(&tv_i, &tz_i) + +#define IF_TIMER_END() \ +gettimeofday(&tv_f, &tz_f); \ +total_usecs = \ +(tv_f.tv_sec - tv_i.tv_sec) * 1000000 + (tv_f.tv_usec - tv_i.tv_usec); \ +if(total_usecs > 300000) + +/* + * aligner_sw_driver.cpp + * + * Routines that drive the alignment process given a collection of seed hits. + * This is generally done in a few stages: extendSeeds visits the set of + * seed-hit BW elements in some order; for each element visited it resolves its + * reference offset; once the reference offset is known, bounds for a dynamic + * programming subproblem are established; if these bounds are distinct from + * the bounds we've already tried, we solve the dynamic programming subproblem + * and report the hit; if the AlnSinkWrap indicates that we can stop, we + * return, otherwise we continue on to the next BW element. + */ + + +/** + * Given end-to-end alignment results stored in the SeedResults structure, set + * up all of our state for resolving and keeping track of reference offsets for + * hits. Order the list of ranges to examine such that all exact end-to-end + * alignments are examined before any 1mm end-to-end alignments. + * + * Note: there might be a lot of hits and a lot of wide ranges to look for + * here. We use 'maxelt'. + */ +template +bool SwDriver::eeSaTups( + const Read& rd, // read + SeedResults& sh, // seed hits to extend into full alignments + const GFM& gfm, // BWT + const BitPairReference& ref, // Reference strings + RandomSource& rnd, // pseudo-random generator + WalkMetrics& wlm, // group walk left metrics + SwMetrics& swmSeed, // metrics for seed extensions + index_t& nelt_out, // out: # elements total + index_t maxelt, // max elts we'll consider + bool all) // report all hits? +{ + assert_eq(0, nelt_out); + gws_.clear(); + rands_.clear(); + satpos_.clear(); + eehits_.clear(); + // First, count up the total number of satpos_, rands_, eehits_, and gws_ + // we're going to tuse + index_t nobj = 0; + if(!sh.exactFwEEHit().empty()) nobj++; + if(!sh.exactRcEEHit().empty()) nobj++; + nobj += sh.mm1EEHits().size(); + nobj = min(nobj, maxelt); + gws_.ensure(nobj); + rands_.ensure(nobj); + satpos_.ensure(nobj); + eehits_.ensure(nobj); + index_t tot = sh.exactFwEEHit().size() + sh.exactRcEEHit().size(); + bool succ = false; + bool firstEe = true; + bool done = false; + if(tot > 0) { + bool fwFirst = true; + // Pick fw / rc to go first in a weighted random fashion +#ifdef BOWTIE_64BIT_INDEX + index_t rn64 = rnd.nextU64(); + index_t rn = rn64 % (uint64_t)tot; +#else + index_t rn32 = rnd.nextU32(); + index_t rn = rn32 % (uint32_t)tot; +#endif + if(rn >= sh.exactFwEEHit().size()) { + fwFirst = false; + } + for(int fwi = 0; fwi < 2 && !done; fwi++) { + bool fw = ((fwi == 0) == fwFirst); + EEHit hit = fw ? sh.exactFwEEHit() : sh.exactRcEEHit(); + if(hit.empty()) { + continue; + } + assert(hit.fw == fw); + if(hit.bot > hit.top) { + // Possibly adjust bot and width if we would have exceeded maxelt + index_t tops[2] = { hit.top, 0 }; + index_t bots[2] = { hit.bot, 0 }; + index_t width = hit.bot - hit.top; + if(nelt_out + width > maxelt) { + index_t trim = (index_t)((nelt_out + width) - maxelt); +#ifdef BOWTIE_64BIT_INDEX + index_t rn = rnd.nextU64() % width; +#else + index_t rn = rnd.nextU32() % width; +#endif + index_t newwidth = width - trim; + if(hit.top + rn + newwidth > hit.bot) { + // Two pieces + tops[0] = hit.top + rn; + bots[0] = hit.bot; + tops[1] = hit.top; + bots[1] = hit.top + newwidth - (bots[0] - tops[0]); + } else { + // One piece + tops[0] = hit.top + rn; + bots[0] = tops[0] + newwidth; + } + assert_leq(bots[0], hit.bot); + assert_leq(bots[1], hit.bot); + assert_geq(bots[0], tops[0]); + assert_geq(bots[1], tops[1]); + assert_eq(newwidth, (bots[0] - tops[0]) + (bots[1] - tops[1])); + } + for(int i = 0; i < 2 && !done; i++) { + if(bots[i] <= tops[i]) break; + index_t width = bots[i] - tops[i]; + index_t top = tops[i]; + // Clear list where resolved offsets are stored + swmSeed.exranges++; + swmSeed.exrows += width; + if(!succ) { + swmSeed.exsucc++; + succ = true; + } + if(firstEe) { + salistEe_.clear(); + pool_.clear(); + firstEe = false; + } + // We have to be careful not to allocate excessive amounts of memory here + TSlice o(salistEe_, (index_t)salistEe_.size(), width); + for(index_t i = 0; i < width; i++) { + if(!salistEe_.add(pool_, (index_t)OFF_MASK)) { + swmSeed.exooms++; + return false; + } + } + assert(!done); + eehits_.push_back(hit); + satpos_.expand(); + satpos_.back().sat.init(SAKey(), top, (index_t)OFF_MASK, o); + satpos_.back().sat.key.seq = MAX_U64; + satpos_.back().sat.key.len = (index_t)rd.length(); + satpos_.back().pos.init(fw, 0, 0, (index_t)rd.length()); + satpos_.back().origSz = width; + rands_.expand(); + rands_.back().init(width, all); + gws_.expand(); + SARangeWithOffs sa; + sa.topf = satpos_.back().sat.topf; + sa.len = satpos_.back().sat.key.len; + sa.offs = satpos_.back().sat.offs; + gws_.back().init( + gfm, // forward Bowtie index + ref, // reference sequences + sa, // SATuple + rnd, // pseudo-random generator + wlm); // metrics + assert(gws_.back().repOk(sa)); + nelt_out += width; + if(nelt_out >= maxelt) { + done = true; + } + } + } + } + } + succ = false; + if(!done && !sh.mm1EEHits().empty()) { + sh.sort1mmEe(rnd); + index_t sz = sh.mm1EEHits().size(); + for(index_t i = 0; i < sz && !done; i++) { + EEHit hit = sh.mm1EEHits()[i]; + assert(hit.repOk(rd)); + assert(!hit.empty()); + // Possibly adjust bot and width if we would have exceeded maxelt + index_t tops[2] = { hit.top, 0 }; + index_t bots[2] = { hit.bot, 0 }; + index_t width = hit.bot - hit.top; + if(nelt_out + width > maxelt) { + index_t trim = (index_t)((nelt_out + width) - maxelt); +#ifdef BOWTIE_64BIT_INDEX + index_t rn = rnd.nextU64() % width; +#else + index_t rn = rnd.nextU32() % width; +#endif + index_t newwidth = width - trim; + if(hit.top + rn + newwidth > hit.bot) { + // Two pieces + tops[0] = hit.top + rn; + bots[0] = hit.bot; + tops[1] = hit.top; + bots[1] = hit.top + newwidth - (bots[0] - tops[0]); + } else { + // One piece + tops[0] = hit.top + rn; + bots[0] = tops[0] + newwidth; + } + assert_leq(bots[0], hit.bot); + assert_leq(bots[1], hit.bot); + assert_geq(bots[0], tops[0]); + assert_geq(bots[1], tops[1]); + assert_eq(newwidth, (bots[0] - tops[0]) + (bots[1] - tops[1])); + } + for(int i = 0; i < 2 && !done; i++) { + if(bots[i] <= tops[i]) break; + index_t width = bots[i] - tops[i]; + index_t top = tops[i]; + // Clear list where resolved offsets are stored + swmSeed.mm1ranges++; + swmSeed.mm1rows += width; + if(!succ) { + swmSeed.mm1succ++; + succ = true; + } + if(firstEe) { + salistEe_.clear(); + pool_.clear(); + firstEe = false; + } + TSlice o(salistEe_, (index_t)salistEe_.size(), width); + for(size_t i = 0; i < width; i++) { + if(!salistEe_.add(pool_, (index_t)OFF_MASK)) { + swmSeed.mm1ooms++; + return false; + } + } + eehits_.push_back(hit); + satpos_.expand(); + satpos_.back().sat.init(SAKey(), top, (index_t)OFF_MASK, o); + satpos_.back().sat.key.seq = MAX_U64; + satpos_.back().sat.key.len = (index_t)rd.length(); + satpos_.back().pos.init(hit.fw, 0, 0, (index_t)rd.length()); + satpos_.back().origSz = width; + rands_.expand(); + rands_.back().init(width, all); + gws_.expand(); + SARangeWithOffs sa; + sa.topf = satpos_.back().sat.topf; + sa.len = satpos_.back().sat.key.len; + sa.offs = satpos_.back().sat.offs; + gws_.back().init( + gfm, // forward Bowtie index + ref, // reference sequences + sa, // SATuple + rnd, // pseudo-random generator + wlm); // metrics + assert(gws_.back().repOk(sa)); + nelt_out += width; + if(nelt_out >= maxelt) { + done = true; + } + } + } + } + return true; +} + +/** + * Extend a seed hit out on either side. Requires that we know the seed hit's + * offset into the read and orientation. Also requires that we know top/bot + * for the seed hit in both the forward and (if we want to extend to the right) + * reverse index. + */ +template +void SwDriver::extend( + const Read& rd, // read + const GFM& gfmFw, // Forward Bowtie index + const GFM* gfmBw, // Backward Bowtie index + index_t topf, // top in fw index + index_t botf, // bot in fw index + index_t topb, // top in bw index + index_t botb, // bot in bw index + bool fw, // seed orientation + index_t off, // seed offset from 5' end + index_t len, // seed length + PerReadMetrics& prm, // per-read metrics + index_t& nlex, // # positions we can extend to left w/o edit + index_t& nrex) // # positions we can extend to right w/o edit +{ + index_t t[4], b[4]; + index_t tp[4], bp[4]; + SideLocus tloc, bloc; + index_t rdlen = (index_t)rd.length(); + index_t lim = fw ? off : rdlen - len - off; + // We're about to add onto the beginning, so reverse it +#ifndef NDEBUG + if(false) { + // TODO: This will sometimes fail even when the extension is legitimate + // This is because contains() comes in from one extreme or the other, + // whereas we started from the inside and worked outwards. This + // affects which Ns are OK and which are not OK. + + // Have to do both because whether we can get through an N depends on + // which direction we're coming in + bool fwContains = gfmFw.contains(tmp_rdseq_); + tmp_rdseq_.reverse(); + bool bwContains = gfmBw != NULL && gfmBw->contains(tmp_rdseq_); + tmp_rdseq_.reverse(); + assert(fwContains || bwContains); + } +#endif + ASSERT_ONLY(tmp_rdseq_.reverse()); + if(lim > 0) { + const GFM *gfm = &gfmFw; + assert(gfm != NULL); + // Extend left using forward index + const BTDnaString& seq = fw ? rd.patFw : rd.patRc; + // See what we get by extending + index_t top = topf, bot = botf; + t[0] = t[1] = t[2] = t[3] = 0; + b[0] = b[1] = b[2] = b[3] = 0; + tp[0] = tp[1] = tp[2] = tp[3] = topb; + bp[0] = bp[1] = bp[2] = bp[3] = botb; + SideLocus tloc, bloc; + INIT_LOCS(top, bot, tloc, bloc, *gfm); + for(index_t ii = 0; ii < lim; ii++) { + // Starting to left of seed (mapBiLFEx(tloc, bloc, t, b, tp, bp); + SANITY_CHECK_4TUP(t, b, tp, bp); + int nonz = -1; + bool abort = false; + size_t origSz = bot - top; + for(int j = 0; j < 4; j++) { + if(b[j] > t[j]) { + if(nonz >= 0) { + abort = true; + break; + } + nonz = j; + top = t[j]; bot = b[j]; + } + } + assert_leq(bot - top, origSz); + if(abort || (nonz != rdc && rdc <= 3) || bot - top < origSz) { + break; + } + } else { + assert_eq(bot, top+1); + prm.nSdFmops++; + int c = gfm->mapLF1(top, tloc); + if(c != rdc && rdc <= 3) { + break; + } + bot = top + 1; + } + ASSERT_ONLY(tmp_rdseq_.append(rdc)); + if(++nlex == 255) { + break; + } + INIT_LOCS(top, bot, tloc, bloc, *gfm); + } + } + // We're about to add onto the end, so re-reverse + ASSERT_ONLY(tmp_rdseq_.reverse()); + lim = fw ? rdlen - len - off : off; + if(lim > 0 && gfmBw != NULL) { + const GFM *gfm = gfmBw; + assert(gfm != NULL); + // Extend right using backward index + const BTDnaString& seq = fw ? rd.patFw : rd.patRc; + // See what we get by extending + index_t top = topb, bot = botb; + t[0] = t[1] = t[2] = t[3] = 0; + b[0] = b[1] = b[2] = b[3] = 0; + tp[0] = tp[1] = tp[2] = tp[3] = topf; + bp[0] = bp[1] = bp[2] = bp[3] = botf; + INIT_LOCS(top, bot, tloc, bloc, *gfm); + for(index_t ii = 0; ii < lim; ii++) { + // Starting to right of seed (mapBiLFEx(tloc, bloc, t, b, tp, bp); + SANITY_CHECK_4TUP(t, b, tp, bp); + int nonz = -1; + bool abort = false; + size_t origSz = bot - top; + for(int j = 0; j < 4; j++) { + if(b[j] > t[j]) { + if(nonz >= 0) { + abort = true; + break; + } + nonz = j; + top = t[j]; bot = b[j]; + } + } + assert_leq(bot - top, origSz); + if(abort || (nonz != rdc && rdc <= 3) || bot - top < origSz) { + break; + } + } else { + assert_eq(bot, top+1); + prm.nSdFmops++; + int c = gfm->mapLF1(top, tloc); + if(c != rdc && rdc <= 3) { + break; + } + bot = top + 1; + } + ASSERT_ONLY(tmp_rdseq_.append(rdc)); + if(++nrex == 255) { + break; + } + INIT_LOCS(top, bot, tloc, bloc, *gfm); + } + } +#ifndef NDEBUG + if(false) { + // TODO: This will sometimes fail even when the extension is legitimate + // This is because contains() comes in from one extreme or the other, + // whereas we started from the inside and worked outwards. This + // affects which Ns are OK and which are not OK. + + // Have to do both because whether we can get through an N depends on + // which direction we're coming in + bool fwContains = gfmFw.contains(tmp_rdseq_); + tmp_rdseq_.reverse(); + bool bwContains = gfmBw != NULL && gfmBw->contains(tmp_rdseq_); + tmp_rdseq_.reverse(); + assert(fwContains || bwContains); + } +#endif + assert_lt(nlex, rdlen); + assert_lt(nrex, rdlen); + return; +} + +/** + * Given seed results, set up all of our state for resolving and keeping + * track of reference offsets for hits. + */ +template +void SwDriver::prioritizeSATups( + const Read& read, // read + SeedResults& sh, // seed hits to extend into full alignments + const GFM& gfmFw, // BWT + const GFM* gfmBw, // BWT + const BitPairReference& ref, // Reference strings + int seedmms, // # mismatches allowed in seed + index_t maxelt, // max elts we'll consider + bool doExtend, // do extension of seed hits? + bool lensq, // square length in weight calculation + bool szsq, // square range size in weight calculation + index_t nsm, // if range as <= nsm elts, it's "small" + AlignmentCacheIface& ca, // alignment cache for seed hits + RandomSource& rnd, // pseudo-random generator + WalkMetrics& wlm, // group walk left metrics + PerReadMetrics& prm, // per-read metrics + index_t& nelt_out, // out: # elements total + bool all) // report all hits? +{ + const index_t nonz = sh.nonzeroOffsets(); // non-zero positions + const int matei = (read.mate <= 1 ? 0 : 1); + satups_.clear(); + gws_.clear(); + rands_.clear(); + rands2_.clear(); + satpos_.clear(); + satpos2_.clear(); + index_t nrange = 0, nelt = 0, nsmall = 0, nsmall_elts = 0; + bool keepWhole = false; + EList, 16>& satpos = keepWhole ? satpos_ : satpos2_; + for(index_t i = 0; i < nonz; i++) { + bool fw = true; + index_t offidx = 0, rdoff = 0, seedlen = 0; + QVal qv = sh.hitsByRank(i, offidx, rdoff, fw, seedlen); + assert(qv.valid()); + assert(!qv.empty()); + assert(qv.repOk(ca.current())); + ca.queryQval(qv, satups_, nrange, nelt); + for(size_t j = 0; j < satups_.size(); j++) { + const index_t sz = satups_[j].size(); + // Check whether this hit occurs inside the extended boundaries of + // another hit we already processed for this read. + if(seedmms == 0) { + // See if we're covered by a previous extended seed hit + EList& range = + fw ? seedExRangeFw_[matei] : seedExRangeRc_[matei]; + bool skip = false; + for(index_t k = 0; k < range.size(); k++) { + index_t p5 = range[k].off; + index_t len = range[k].len; + if(p5 <= rdoff && p5 + len >= (rdoff + seedlen)) { + if(sz <= range[k].sz) { + skip = true; + break; + } + } + } + if(skip) { + assert_gt(nrange, 0); + nrange--; + assert_geq(nelt, sz); + nelt -= sz; + continue; // Skip this seed + } + } + satpos.expand(); + satpos.back().sat = satups_[j]; + satpos.back().origSz = sz; + satpos.back().pos.init(fw, offidx, rdoff, seedlen); + if(sz <= nsm) { + nsmall++; + nsmall_elts += sz; + } + satpos.back().nlex = satpos.back().nrex = 0; +#ifndef NDEBUG + tmp_rdseq_.clear(); + uint64_t key = satpos.back().sat.key.seq; + for(size_t k = 0; k < seedlen; k++) { + int c = (int)(key & 3); + tmp_rdseq_.append(c); + key >>= 2; + } + tmp_rdseq_.reverse(); +#endif + index_t nlex = 0, nrex = 0; + if(doExtend) { + extend( + read, + gfmFw, + gfmBw, + satpos.back().sat.topf, + (index_t)(satpos.back().sat.topf + sz), + satpos.back().sat.topb, + (index_t)(satpos.back().sat.topb + sz), + fw, + rdoff, + seedlen, + prm, + nlex, + nrex); + } + satpos.back().nlex = nlex; + satpos.back().nrex = nrex; + if(seedmms == 0 && (nlex > 0 || nrex > 0)) { + assert_geq(rdoff, (fw ? nlex : nrex)); + index_t p5 = rdoff - (fw ? nlex : nrex); + EList& range = + fw ? seedExRangeFw_[matei] : seedExRangeRc_[matei]; + range.expand(); + range.back().off = p5; + range.back().len = seedlen + nlex + nrex; + range.back().sz = sz; + } + } + satups_.clear(); + } + assert_leq(nsmall, nrange); + nelt_out = nelt; // return the total number of elements + assert_eq(nrange, satpos.size()); + satpos.sort(); + if(keepWhole) { + gws_.ensure(nrange); + rands_.ensure(nrange); + for(index_t i = 0; i < nrange; i++) { + gws_.expand(); + SARangeWithOffs sa; + sa.topf = satpos_.back().sat.topf; + sa.len = satpos_.back().sat.key.len; + sa.offs = satpos_.back().sat.offs; + gws_.back().init( + gfmFw, // forward Bowtie index + ref, // reference sequences + sa, // SA tuples: ref hit, salist range + rnd, // pseudo-random generator + wlm); // metrics + assert(gws_.back().initialized()); + rands_.expand(); + rands_.back().init(satpos_[i].sat.size(), all); + } + return; + } + // Resize satups_ list so that ranges having elements that we might + // possibly explore are present + satpos_.ensure(min(maxelt, nelt)); + gws_.ensure(min(maxelt, nelt)); + rands_.ensure(min(maxelt, nelt)); + rands2_.ensure(min(maxelt, nelt)); + size_t nlarge_elts = nelt - nsmall_elts; + if(maxelt < nelt) { + size_t diff = nelt - maxelt; + if(diff >= nlarge_elts) { + nlarge_elts = 0; + } else { + nlarge_elts -= diff; + } + } + index_t nelt_added = 0; + // Now we have a collection of ranges in satpos2_. Now we want to decide + // how we explore elements from them. The basic idea is that: for very + // small guys, where "very small" means that the size of the range is less + // than or equal to the parameter 'nsz', we explore them in their entirety + // right away. For the rest, we want to select in a way that is (a) + // random, and (b) weighted toward examining elements from the smaller + // ranges more frequently (and first). + // + // 1. do the smalls + for(index_t j = 0; j < nsmall && nelt_added < maxelt; j++) { + satpos_.expand(); + satpos_.back() = satpos2_[j]; + gws_.expand(); + SARangeWithOffs sa; + sa.topf = satpos_.back().sat.topf; + sa.len = satpos_.back().sat.key.len; + sa.offs = satpos_.back().sat.offs; + gws_.back().init( + gfmFw, // forward Bowtie index + ref, // reference sequences + sa, // SA tuples: ref hit, salist range + rnd, // pseudo-random generator + wlm); // metrics + assert(gws_.back().initialized()); + rands_.expand(); + rands_.back().init(satpos_.back().sat.size(), all); + nelt_added += satpos_.back().sat.size(); +#ifndef NDEBUG + for(size_t k = 0; k < satpos_.size()-1; k++) { + assert(!(satpos_[k] == satpos_.back())); + } +#endif + } + if(nelt_added >= maxelt || nsmall == satpos2_.size()) { + nelt_out = nelt_added; + return; + } + // 2. do the non-smalls + // Initialize the row sampler + rowsamp_.init(satpos2_, nsmall, satpos2_.size(), lensq, szsq); + // Initialize the random choosers + rands2_.resize(satpos2_.size()); + for(index_t j = 0; j < satpos2_.size(); j++) { + rands2_[j].reset(); + } + while(nelt_added < maxelt && nelt_added < nelt) { + // Pick a non-small range to sample from + index_t ri = rowsamp_.next(rnd) + nsmall; + assert_geq(ri, nsmall); + assert_lt(ri, satpos2_.size()); + // Initialize random element chooser for that range + if(!rands2_[ri].inited()) { + rands2_[ri].init(satpos2_[ri].sat.size(), all); + assert(!rands2_[ri].done()); + } + assert(!rands2_[ri].done()); + // Choose an element from the range + uint32_t r = rands2_[ri].next(rnd); + if(rands2_[ri].done()) { + // Tell the row sampler this range is done + rowsamp_.finishedRange(ri - nsmall); + } + // Add the element to the satpos_ list + SATuple sat; + TSlice o; + o.init(satpos2_[ri].sat.offs, r, r+1); + sat.init(satpos2_[ri].sat.key, (index_t)(satpos2_[ri].sat.topf + r), (index_t)OFF_MASK, o); + satpos_.expand(); + satpos_.back().sat = sat; + satpos_.back().origSz = satpos2_[ri].origSz; + satpos_.back().pos = satpos2_[ri].pos; + // Initialize GroupWalk object + gws_.expand(); + SARangeWithOffs sa; + sa.topf = sat.topf; + sa.len = sat.key.len; + sa.offs = sat.offs; + gws_.back().init( + gfmFw, // forward Bowtie index + ref, // reference sequences + sa, // SA tuples: ref hit, salist range + rnd, // pseudo-random generator + wlm); // metrics + assert(gws_.back().initialized()); + // Initialize random selector + rands_.expand(); + rands_.back().init(1, all); + nelt_added++; + } + nelt_out = nelt_added; + return; +} + +enum { + FOUND_NONE = 0, + FOUND_EE, + FOUND_UNGAPPED, +}; + +/** + * Given a collection of SeedHits for a single read, extend seed alignments + * into full alignments. Where possible, try to avoid redundant offset lookups + * and dynamic programming wherever possible. Optionally report alignments to + * a AlnSinkWrap object as they are discovered. + * + * If 'reportImmediately' is true, returns true iff a call to msink->report() + * returned true (indicating that the reporting policy is satisfied and we can + * stop). Otherwise, returns false. + */ +template +int SwDriver::extendSeeds( + Read& rd, // read to align + bool mate1, // true iff rd is mate #1 + SeedResults& sh, // seed hits to extend into full alignments + const GFM& gfmFw, // BWT + const GFM* gfmBw, // BWT' + const BitPairReference& ref, // Reference strings + SwAligner& swa, // dynamic programming aligner + const Scoring& sc, // scoring scheme + int seedmms, // # mismatches allowed in seed + int seedlen, // length of seed + int seedival, // interval between seeds + TAlScore& minsc, // minimum score for anchor + int nceil, // maximum # Ns permitted in reference portion + size_t maxhalf, // max width in either direction for DP tables + bool doUngapped, // do ungapped alignment + size_t maxIters, // stop after this many seed-extend loop iters + size_t maxUg, // stop after this many ungaps + size_t maxDp, // stop after this many dps + size_t maxUgStreak, // stop after streak of this many ungap fails + size_t maxDpStreak, // stop after streak of this many dp fails + bool doExtend, // do seed extension + bool enable8, // use 8-bit SSE where possible + size_t cminlen, // use checkpointer if read longer than this + size_t cpow2, // interval between diagonals to checkpoint + bool doTri, // triangular mini-fills? + int tighten, // -M score tightening mode + AlignmentCacheIface& ca, // alignment cache for seed hits + RandomSource& rnd, // pseudo-random source + WalkMetrics& wlm, // group walk left metrics + SwMetrics& swmSeed, // DP metrics for seed-extend + PerReadMetrics& prm, // per-read metrics + AlnSinkWrap* msink, // AlnSink wrapper for multiseed-style aligner + bool reportImmediately, // whether to report hits immediately to msink + bool& exhaustive) // set to true iff we searched all seeds exhaustively +{ + bool all = msink->allHits(); + // typedef std::pair UPair; + + assert(!reportImmediately || msink != NULL); + assert(!reportImmediately || !msink->maxed()); + + assert_geq(nceil, 0); + assert_leq((size_t)nceil, rd.length()); + + // Calculate the largest possible number of read and reference gaps + const index_t rdlen = (index_t)rd.length(); + TAlScore perfectScore = sc.perfectScore(rdlen); + + DynProgFramer dpframe(!gReportOverhangs); + swa.reset(); + + // Initialize a set of GroupWalks, one for each seed. Also, intialize the + // accompanying lists of reference seed hits (satups*) + const index_t nsm = 5; + const index_t nonz = sh.nonzeroOffsets(); // non-zero positions + index_t eeHits = sh.numE2eHits(); + bool eeMode = eeHits > 0; + bool firstEe = true; + bool firstExtend = true; + + // Reset all the counters related to streaks + prm.nEeFail = 0; + prm.nUgFail = 0; + prm.nDpFail = 0; + + index_t nelt = 0, neltLeft = 0; + index_t rows = rdlen; + index_t eltsDone = 0; + // cerr << "===" << endl; + while(true) { + if(eeMode) { + if(firstEe) { + firstEe = false; + eeMode = eeSaTups( + rd, // read + sh, // seed hits to extend into full alignments + gfmFw, // BWT + ref, // Reference strings + rnd, // pseudo-random generator + wlm, // group walk left metrics + swmSeed, // seed-extend metrics + nelt, // out: # elements total + maxIters, // max # to report + all); // report all hits? + assert_eq(gws_.size(), rands_.size()); + assert_eq(gws_.size(), satpos_.size()); + } else { + eeMode = false; + } + } + if(!eeMode) { + if(nonz == 0) { + return EXTEND_EXHAUSTED_CANDIDATES; // No seed hits! Bail. + } + if(minsc == perfectScore) { + return EXTEND_PERFECT_SCORE; // Already found all perfect hits! + } + if(firstExtend) { + nelt = 0; + prioritizeSATups( + rd, // read + sh, // seed hits to extend into full alignments + gfmFw, // BWT + gfmBw, // BWT' + ref, // Reference strings + seedmms, // # seed mismatches allowed + maxIters, // max rows to consider per position + doExtend, // extend out seeds + true, // square extended length + true, // square SA range size + nsm, // smallness threshold + ca, // alignment cache for seed hits + rnd, // pseudo-random generator + wlm, // group walk left metrics + prm, // per-read metrics + nelt, // out: # elements total + all); // report all hits? + assert_eq(gws_.size(), rands_.size()); + assert_eq(gws_.size(), satpos_.size()); + neltLeft = nelt; + firstExtend = false; + } + if(neltLeft == 0) { + // Finished examining gapped candidates + break; + } + } + for(size_t i = 0; i < gws_.size(); i++) { + if(eeMode && eehits_[i].score < minsc) { + return EXTEND_PERFECT_SCORE; + } + bool is_small = satpos_[i].sat.size() < nsm; + bool fw = satpos_[i].pos.fw; + index_t rdoff = satpos_[i].pos.rdoff; + index_t seedhitlen = satpos_[i].pos.seedlen; + if(!fw) { + // 'rdoff' and 'offidx' are with respect to the 5' end of + // the read. Here we convert rdoff to be with respect to + // the upstream (3') end of ther read. + rdoff = (index_t)(rdlen - rdoff - seedhitlen); + } + bool first = true; + // If the range is small, investigate all elements now. If the + // range is large, just investigate one and move on - we might come + // back to this range later. + index_t riter = 0; + while(!rands_[i].done() && (first || is_small || eeMode)) { + assert(!gws_[i].done()); + riter++; + if(minsc == perfectScore) { + if(!eeMode || eehits_[i].score < perfectScore) { + return EXTEND_PERFECT_SCORE; + } + } else if(eeMode && eehits_[i].score < minsc) { + break; + } + if(prm.nExDps >= maxDp || prm.nMateDps >= maxDp) { + return EXTEND_EXCEEDED_HARD_LIMIT; + } + if(prm.nExUgs >= maxUg || prm.nMateUgs >= maxUg) { + return EXTEND_EXCEEDED_HARD_LIMIT; + } + if(prm.nExIters >= maxIters) { + return EXTEND_EXCEEDED_HARD_LIMIT; + } + prm.nExIters++; + first = false; + // Resolve next element offset + WalkResult wr; + uint32_t elt = rands_[i].next(rnd); + //cerr << "elt=" << elt << endl; + SARangeWithOffs sa; + sa.topf = satpos_[i].sat.topf; + sa.len = satpos_[i].sat.key.len; + sa.offs = satpos_[i].sat.offs; + gws_[i].advanceElement((index_t)elt, gfmFw, ref, sa, gwstate_, wr, wlm, prm); + eltsDone++; + if(!eeMode) { + assert_gt(neltLeft, 0); + neltLeft--; + } + assert_neq((index_t)OFF_MASK, wr.toff); + index_t tidx = 0, toff = 0, tlen = 0; + bool straddled = false; + gfmFw.joinedToTextOff( + wr.elt.len, + wr.toff, + tidx, + toff, + tlen, + eeMode, // reject straddlers? + straddled); // did it straddle? + if(tidx == (index_t)OFF_MASK) { + // The seed hit straddled a reference boundary so the seed hit + // isn't valid + continue; + } +#ifndef NDEBUG + if(!eeMode && !straddled) { // Check that seed hit matches reference + uint64_t key = satpos_[i].sat.key.seq; + for(index_t k = 0; k < wr.elt.len; k++) { + int c = ref.getBase(tidx, toff + wr.elt.len - k - 1); + assert_leq(c, 3); + int ck = (int)(key & 3); + key >>= 2; + assert_eq(c, ck); + } + } +#endif + // Find offset of alignment's upstream base assuming net gaps=0 + // between beginning of read and beginning of seed hit + int64_t refoff = (int64_t)toff - rdoff; + // Coordinate of the seed hit w/r/t the pasted reference string + Coord refcoord(tidx, refoff, fw); + if(seenDiags1_.locusPresent(refcoord)) { + // Already handled alignments seeded on this diagonal + prm.nRedundants++; + swmSeed.rshit++; + continue; + } + // Now that we have a seed hit, there are many issues to solve + // before we have a completely framed dynamic programming problem. + // They include: + // + // 1. Setting reference offsets on either side of the seed hit, + // accounting for where the seed occurs in the read + // 2. Adjusting the width of the banded dynamic programming problem + // and adjusting reference bounds to allow for gaps in the + // alignment + // 3. Accounting for the edges of the reference, which can impact + // the width of the DP problem and reference bounds. + // 4. Perhaps filtering the problem down to a smaller problem based + // on what DPs we've already solved for this read + // + // We do #1 here, since it is simple and we have all the seed-hit + // information here. #2 and #3 are handled in the DynProgFramer. + int readGaps = 0, refGaps = 0; + bool ungapped = false; + if(!eeMode) { + readGaps = sc.maxReadGaps(minsc, rdlen); + refGaps = sc.maxRefGaps(minsc, rdlen); + ungapped = (readGaps == 0 && refGaps == 0); + } + int state = FOUND_NONE; + bool found = false; + if(eeMode) { + resEe_.reset(); + resEe_.alres.reset(); + const EEHit& h = eehits_[i]; + assert_leq(h.score, perfectScore); + resEe_.alres.setScore(AlnScore(h.score, h.ns(), 0)); + resEe_.alres.setShape( + refcoord.ref(), // ref id + refcoord.off(), // 0-based ref offset + tlen, // length of reference + fw, // aligned to Watson? + rdlen, // read length + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + 0, // alignment trim 5' end + 0); // alignment trim 3' end + resEe_.alres.setRefNs(h.refns()); + if(h.mms() > 0) { + assert_eq(1, h.mms()); + assert_lt(h.e1.pos, rd.length()); + resEe_.alres.ned().push_back(h.e1); + } + assert(resEe_.repOk(rd)); + state = FOUND_EE; + found = true; + Interval refival(refcoord, 1); + seenDiags1_.add(refival); + } else if(doUngapped && ungapped) { + resUngap_.reset(); + int al = swa.ungappedAlign( + fw ? rd.patFw : rd.patRc, + fw ? rd.qual : rd.qualRev, + refcoord, + ref, + tlen, + sc, + gReportOverhangs, + minsc, + resUngap_); + Interval refival(refcoord, 1); + seenDiags1_.add(refival); + prm.nExUgs++; + if(al == 0) { + prm.nExUgFails++; + prm.nUgFail++; + if(prm.nUgFail >= maxUgStreak) { + return EXTEND_EXCEEDED_SOFT_LIMIT; + } + swmSeed.ungapfail++; + continue; + } else if(al == -1) { + prm.nExUgFails++; + prm.nUgFail++; // count this as failure + if(prm.nUgFail >= maxUgStreak) { + return EXTEND_EXCEEDED_SOFT_LIMIT; + } + swmSeed.ungapnodec++; + } else { + prm.nExUgSuccs++; + prm.nUgLastSucc = prm.nExUgs-1; + if(prm.nUgFail > prm.nUgFailStreak) { + prm.nUgFailStreak = prm.nUgFail; + } + prm.nUgFail = 0; + found = true; + state = FOUND_UNGAPPED; + swmSeed.ungapsucc++; + } + } + int64_t pastedRefoff = (int64_t)wr.toff - rdoff; + DPRect rect; + if(state == FOUND_NONE) { + found = dpframe.frameSeedExtensionRect( + refoff, // ref offset implied by seed hit assuming no gaps + rows, // length of read sequence used in DP table + tlen, // length of reference + readGaps, // max # of read gaps permitted in opp mate alignment + refGaps, // max # of ref gaps permitted in opp mate alignment + (size_t)nceil, // # Ns permitted + maxhalf, // max width in either direction + rect); // DP rectangle + assert(rect.repOk()); + // Add the seed diagonal at least + seenDiags1_.add(Interval(refcoord, 1)); + if(!found) { + continue; + } + } + int64_t leftShift = refoff - rect.refl; + size_t nwindow = 0; + if(toff >= rect.refl) { + nwindow = (size_t)(toff - rect.refl); + } + // NOTE: We might be taking off more than we should because the + // pasted string omits non-A/C/G/T characters, but we included them + // when calculating leftShift. We'll account for this later. + pastedRefoff -= leftShift; + size_t nsInLeftShift = 0; + if(state == FOUND_NONE) { + if(!swa.initedRead()) { + // Initialize the aligner with a new read + swa.initRead( + rd.patFw, // fw version of query + rd.patRc, // rc version of query + rd.qual, // fw version of qualities + rd.qualRev,// rc version of qualities + 0, // off of first char in 'rd' to consider + rdlen, // off of last char (excl) in 'rd' to consider + sc); // scoring scheme + } + swa.initRef( + fw, // whether to align forward or revcomp read + tidx, // reference aligned against + rect, // DP rectangle + ref, // Reference strings + tlen, // length of reference sequence + sc, // scoring scheme + minsc, // minimum score permitted + enable8, // use 8-bit SSE if possible? + cminlen, // minimum length for using checkpointing scheme + cpow2, // interval b/t checkpointed diags; 1 << this + doTri, // triangular mini-fills? + true, // this is a seed extension - not finding a mate + nwindow, + nsInLeftShift); + // Because of how we framed the problem, we can say that we've + // exhaustively scored the seed diagonal as well as maxgaps + // diagonals on either side + Interval refival(tidx, 0, fw, 0); + rect.initIval(refival); + seenDiags1_.add(refival); + // Now fill the dynamic programming matrix and return true iff + // there is at least one valid alignment + TAlScore bestCell = std::numeric_limits::min(); + found = swa.align(rnd, bestCell); + swmSeed.tallyGappedDp(readGaps, refGaps); + prm.nExDps++; + if(!found) { + prm.nExDpFails++; + prm.nDpFail++; + if(prm.nDpFail >= maxDpStreak) { + return EXTEND_EXCEEDED_SOFT_LIMIT; + } + if(bestCell > std::numeric_limits::min() && bestCell > prm.bestLtMinscMate1) { + prm.bestLtMinscMate1 = bestCell; + } + continue; // Look for more anchor alignments + } else { + prm.nExDpSuccs++; + prm.nDpLastSucc = prm.nExDps-1; + if(prm.nDpFail > prm.nDpFailStreak) { + prm.nDpFailStreak = prm.nDpFail; + } + prm.nDpFail = 0; + } + } + bool firstInner = true; + while(true) { + assert(found); + SwResult *res = NULL; + if(state == FOUND_EE) { + if(!firstInner) { + break; + } + res = &resEe_; + } else if(state == FOUND_UNGAPPED) { + if(!firstInner) { + break; + } + res = &resUngap_; + } else { + resGap_.reset(); + assert(resGap_.empty()); + if(swa.done()) { + break; + } + swa.nextAlignment(resGap_, minsc, rnd); + found = !resGap_.empty(); + if(!found) { + break; + } + res = &resGap_; + } + assert(res != NULL); + firstInner = false; + assert(res->alres.matchesRef( + rd, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + raw_refbuf_, + raw_destU32_, + raw_matches_, + tmp_reflens_, + tmp_refoffs_)); + Interval refival(tidx, 0, fw, tlen); + assert_gt(res->alres.refExtent(), 0); + if(gReportOverhangs && + !refival.containsIgnoreOrient(res->alres.refival())) + { + res->alres.clipOutside(true, 0, tlen); + if(res->alres.refExtent() == 0) { + continue; + } + } + assert(gReportOverhangs || + refival.containsIgnoreOrient(res->alres.refival())); + // Did the alignment fall entirely outside the reference? + if(!refival.overlapsIgnoreOrient(res->alres.refival())) { + continue; + } + // Is this alignment redundant with one we've seen previously? + if(redAnchor_.overlap(res->alres)) { + // Redundant with an alignment we found already + continue; + } + redAnchor_.add(res->alres); + // Annotate the AlnRes object with some key parameters + // that were used to obtain the alignment. + res->alres.setParams( + seedmms, // # mismatches allowed in seed + seedlen, // length of seed + seedival, // interval between seeds + minsc); // minimum score for valid alignment + + if(reportImmediately) { + assert(msink != NULL); + assert(res->repOk()); + // Check that alignment accurately reflects the + // reference characters aligned to + assert(res->alres.matchesRef( + rd, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + raw_refbuf_, + raw_destU32_, + raw_matches_, + tmp_reflens_, + tmp_refoffs_)); + // Report an unpaired alignment + assert(!msink->maxed()); + if(msink->report( + 0, + mate1 ? &res->alres : NULL, + mate1 ? NULL : &res->alres)) + { + // Short-circuited because a limit, e.g. -k, -m or + // -M, was exceeded + return EXTEND_POLICY_FULFILLED; + } + if(tighten > 0 && + msink->Mmode() && + msink->hasSecondBestUnp1()) + { + if(tighten == 1) { + if(msink->bestUnp1() >= minsc) { + minsc = msink->bestUnp1(); + if(minsc < perfectScore && + msink->bestUnp1() == msink->secondBestUnp1()) + { + minsc++; + } + } + } else if(tighten == 2) { + if(msink->secondBestUnp1() >= minsc) { + minsc = msink->secondBestUnp1(); + if(minsc < perfectScore) { + minsc++; + } + } + } else { + TAlScore diff = msink->bestUnp1() - msink->secondBestUnp1(); + TAlScore bot = msink->secondBestUnp1() + ((diff*3)/4); + if(bot >= minsc) { + minsc = bot; + if(minsc < perfectScore) { + minsc++; + } + } + } + assert_leq(minsc, perfectScore); + } + } + } + + // At this point we know that we aren't bailing, and will + // continue to resolve seed hits. + + } // while(!gws_[i].done()) + } + } + // Short-circuited because a limit, e.g. -k, -m or -M, was exceeded + return EXTEND_EXHAUSTED_CANDIDATES; +} + +/** + * Given a collection of SeedHits for both mates in a read pair, extend seed + * alignments into full alignments and then look for the opposite mate using + * dynamic programming. Where possible, try to avoid redundant offset lookups. + * Optionally report alignments to a AlnSinkWrap object as they are discovered. + * + * If 'reportImmediately' is true, returns true iff a call to + * msink->report() returned true (indicating that the reporting + * policy is satisfied and we can stop). Otherwise, returns false. + * + * REDUNDANT SEED HITS + * + * See notes at top of aligner_sw_driver.h. + * + * REDUNDANT ALIGNMENTS + * + * See notes at top of aligner_sw_driver.h. + * + * MIXING PAIRED AND UNPAIRED ALIGNMENTS + * + * There are distinct paired-end alignment modes for the cases where (a) the + * user does or does not want to see unpaired alignments for individual mates + * when there are no reportable paired-end alignments involving both mates, and + * (b) the user does or does not want to see discordant paired-end alignments. + * The modes have implications for this function and for the AlnSinkWrap, since + * it affects when we're "done." Also, whether the user has asked us to report + * discordant alignments affects whether and how much searching for unpaired + * alignments we must do (i.e. if there are no paired-end alignments, we must + * at least do -m 1 for both mates). + * + * Mode 1: Just concordant paired-end. Print only concordant paired-end + * alignments. As soon as any limits (-k/-m/-M) are reached, stop. + * + * Mode 2: Concordant and discordant paired-end. If -k/-m/-M limits are + * reached for paired-end alignments, stop. Otherwise, if no paired-end + * alignments are found, align both mates in an unpaired -m 1 fashion. If + * there is exactly one unpaired alignment for each mate, report the + * combination as a discordant alignment. + * + * Mode 3: Concordant paired-end if possible, otherwise unpaired. If -k/-M + * limit is reached for paired-end alignmnts, stop. If -m limit is reached for + * paired-end alignments or no paired-end alignments are found, align both + * mates in an unpaired fashion. All the same settings governing validity and + * reportability in paired-end mode apply here too (-k/-m/-M/etc). + * + * Mode 4: Concordant or discordant paired-end if possible, otherwise unpaired. + * If -k/-M limit is reached for paired-end alignmnts, stop. If -m limit is + * reached for paired-end alignments or no paired-end alignments are found, + * align both mates in an unpaired fashion. If the -m limit was reached, there + * is no need to search for a discordant alignment, and unapired alignment can + * proceed as in Mode 3. If no paired-end alignments were found, then unpaired + * alignment proceeds as in Mode 3 but with this caveat: alignment must be at + * least as thorough as dictated by -m 1 up until the point where + * + * Print paired-end alignments when there are reportable paired-end + * alignments, otherwise report reportable unpaired alignments. If -k limit is + * reached for paired-end alignments, stop. If -m/-M limit is reached for + * paired-end alignments, stop searching for paired-end alignments and look + * only for unpaired alignments. If searching only for unpaired alignments, + * respect -k/-m/-M limits separately for both mates. + * + * The return value from the AlnSinkWrap's report member function must be + * specific enough to distinguish between: + * + * 1. Stop searching for paired-end alignments + * 2. Stop searching for alignments for unpaired alignments for mate #1 + * 3. Stop searching for alignments for unpaired alignments for mate #2 + * 4. Stop searching for any alignments + * + * Note that in Mode 2, options affecting validity and reportability of + * alignments apply . E.g. if -m 1 is specified + * + * WORKFLOW + * + * Our general approach to finding paired and unpaired alignments here + * is as follows: + * + * - For mate in mate1, mate2: + * - For each seed hit in mate: + * - Try to extend it into a full alignment; if we can't, continue + * to the next seed hit + * - Look for alignment for opposite mate; if we can't find one, + * - + * - + * + */ +template +int SwDriver::extendSeedsPaired( + Read& rd, // mate to align as anchor + Read& ord, // mate to align as opposite + bool anchor1, // true iff anchor mate is mate1 + bool oppFilt, // true iff opposite mate was filtered out + SeedResults& sh, // seed hits for anchor + const GFM& gfmFw, // BWT + const GFM* gfmBw, // BWT' + const BitPairReference& ref, // Reference strings + SwAligner& swa, // dynamic programming aligner for anchor + SwAligner& oswa, // dynamic programming aligner for opposite + const Scoring& sc, // scoring scheme + const PairedEndPolicy& pepol,// paired-end policy + int seedmms, // # mismatches allowed in seed + int seedlen, // length of seed + int seedival, // interval between seeds + TAlScore& minsc, // minimum score for valid anchor aln + TAlScore& ominsc, // minimum score for valid opposite aln + int nceil, // max # Ns permitted in ref for anchor + int onceil, // max # Ns permitted in ref for opposite + bool nofw, // don't align forward read + bool norc, // don't align revcomp read + size_t maxhalf, // max width in either direction for DP tables + bool doUngapped, // do ungapped alignment + size_t maxIters, // stop after this many seed-extend loop iters + size_t maxUg, // stop after this many ungaps + size_t maxDp, // stop after this many dps + size_t maxEeStreak, // stop after streak of this many end-to-end fails + size_t maxUgStreak, // stop after streak of this many ungap fails + size_t maxDpStreak, // stop after streak of this many dp fails + size_t maxMateStreak, // stop seed range after N mate-find fails + bool doExtend, // do seed extension + bool enable8, // use 8-bit SSE where possible + size_t cminlen, // use checkpointer if read longer than this + size_t cpow2, // interval between diagonals to checkpoint + bool doTri, // triangular mini-fills? + int tighten, // -M score tightening mode + AlignmentCacheIface& ca, // alignment cache for seed hits + RandomSource& rnd, // pseudo-random source + WalkMetrics& wlm, // group walk left metrics + SwMetrics& swmSeed, // DP metrics for seed-extend + SwMetrics& swmMate, // DP metrics for mate finidng + PerReadMetrics& prm, // per-read metrics + AlnSinkWrap* msink, // AlnSink wrapper for multiseed-style aligner + bool swMateImmediately, // whether to look for mate immediately + bool reportImmediately, // whether to report hits immediately to msink + bool discord, // look for discordant alignments? + bool mixed, // look for unpaired as well as paired alns? + bool& exhaustive) +{ + bool all = msink->allHits(); + // typedef std::pair U32Pair; + + assert(!reportImmediately || msink != NULL); + assert(!reportImmediately || !msink->maxed()); + assert(!msink->state().doneWithMate(anchor1)); + + assert_geq(nceil, 0); + assert_geq(onceil, 0); + assert_leq((size_t)nceil, rd.length()); + assert_leq((size_t)onceil, ord.length()); + + const index_t rdlen = rd.length(); + const index_t ordlen = ord.length(); + const TAlScore perfectScore = sc.perfectScore(rdlen); + const TAlScore operfectScore = sc.perfectScore(ordlen); + + assert_leq(minsc, perfectScore); + assert(oppFilt || ominsc <= operfectScore); + + TAlScore bestPairScore = perfectScore + operfectScore; + if(tighten > 0 && msink->Mmode() && msink->hasSecondBestPair()) { + // Paired-end alignments should have at least this score from now + TAlScore ps; + if(tighten == 1) { + ps = msink->bestPair(); + } else if(tighten == 2) { + ps = msink->secondBestPair(); + } else { + TAlScore diff = msink->bestPair() - msink->secondBestPair(); + ps = msink->secondBestPair() + (diff * 3)/4; + } + if(tighten == 1 && ps < bestPairScore && + msink->bestPair() == msink->secondBestPair()) + { + ps++; + } + if(tighten >= 2 && ps < bestPairScore) { + ps++; + } + // Anchor mate must have score at least 'ps' minus the best possible + // score for the opposite mate. + TAlScore nc = ps - operfectScore; + if(nc > minsc) { + minsc = nc; + } + assert_leq(minsc, perfectScore); + } + + DynProgFramer dpframe(!gReportOverhangs); + swa.reset(); + oswa.reset(); + + // Initialize a set of GroupWalks, one for each seed. Also, intialize the + // accompanying lists of reference seed hits (satups*) + const index_t nsm = 5; + const index_t nonz = sh.nonzeroOffsets(); // non-zero positions + index_t eeHits = sh.numE2eHits(); + bool eeMode = eeHits > 0; + bool firstEe = true; + bool firstExtend = true; + + // Reset all the counters related to streaks + prm.nEeFail = 0; + prm.nUgFail = 0; + prm.nDpFail = 0; + + index_t nelt = 0, neltLeft = 0; + const index_t rows = rdlen; + const index_t orows = ordlen; + index_t eltsDone = 0; + while(true) { + if(eeMode) { + if(firstEe) { + firstEe = false; + eeMode = eeSaTups( + rd, // read + sh, // seed hits to extend into full alignments + gfmFw, // BWT + ref, // Reference strings + rnd, // pseudo-random generator + wlm, // group walk left metrics + swmSeed, // seed-extend metrics + nelt, // out: # elements total + maxIters, // max elts to report + all); // report all hits + assert_eq(gws_.size(), rands_.size()); + assert_eq(gws_.size(), satpos_.size()); + neltLeft = nelt; + // Initialize list that contains the mate-finding failure + // streak for each range + mateStreaks_.resize(gws_.size()); + mateStreaks_.fill(0); + } else { + eeMode = false; + } + } + if(!eeMode) { + if(nonz == 0) { + // No seed hits! Bail. + return EXTEND_EXHAUSTED_CANDIDATES; + } + if(msink->Mmode() && minsc == perfectScore) { + // Already found all perfect hits! + return EXTEND_PERFECT_SCORE; + } + if(firstExtend) { + nelt = 0; + prioritizeSATups( + rd, // read + sh, // seed hits to extend into full alignments + gfmFw, // BWT + gfmBw, // BWT' + ref, // Reference strings + seedmms, // # seed mismatches allowed + maxIters, // max rows to consider per position + doExtend, // extend out seeds + true, // square extended length + true, // square SA range size + nsm, // smallness threshold + ca, // alignment cache for seed hits + rnd, // pseudo-random generator + wlm, // group walk left metrics + prm, // per-read metrics + nelt, // out: # elements total + all); // report all hits? + assert_eq(gws_.size(), rands_.size()); + assert_eq(gws_.size(), satpos_.size()); + neltLeft = nelt; + firstExtend = false; + mateStreaks_.resize(gws_.size()); + mateStreaks_.fill(0); + } + if(neltLeft == 0) { + // Finished examining gapped candidates + break; + } + } + for(index_t i = 0; i < gws_.size(); i++) { + if(eeMode && eehits_[i].score < minsc) { + return EXTEND_PERFECT_SCORE; + } + bool is_small = satpos_[i].sat.size() < nsm; + bool fw = satpos_[i].pos.fw; + index_t rdoff = satpos_[i].pos.rdoff; + index_t seedhitlen = satpos_[i].pos.seedlen; + if(!fw) { + // 'rdoff' and 'offidx' are with respect to the 5' end of + // the read. Here we convert rdoff to be with respect to + // the upstream (3') end of ther read. + rdoff = (index_t)(rdlen - rdoff - seedhitlen); + } + bool first = true; + // If the range is small, investigate all elements now. If the + // range is large, just investigate one and move on - we might come + // back to this range later. + while(!rands_[i].done() && (first || is_small || eeMode)) { + if(minsc == perfectScore) { + if(!eeMode || eehits_[i].score < perfectScore) { + return EXTEND_PERFECT_SCORE; + } + } else if(eeMode && eehits_[i].score < minsc) { + break; + } + if(prm.nExDps >= maxDp || prm.nMateDps >= maxDp) { + return EXTEND_EXCEEDED_HARD_LIMIT; + } + if(prm.nExUgs >= maxUg || prm.nMateUgs >= maxUg) { + return EXTEND_EXCEEDED_HARD_LIMIT; + } + if(prm.nExIters >= maxIters) { + return EXTEND_EXCEEDED_HARD_LIMIT; + } + if(eeMode && prm.nEeFail >= maxEeStreak) { + return EXTEND_EXCEEDED_SOFT_LIMIT; + } + if(!eeMode && prm.nDpFail >= maxDpStreak) { + return EXTEND_EXCEEDED_SOFT_LIMIT; + } + if(!eeMode && prm.nUgFail >= maxUgStreak) { + return EXTEND_EXCEEDED_SOFT_LIMIT; + } + if(mateStreaks_[i] >= maxMateStreak) { + // Don't try this seed range anymore + rands_[i].setDone(); + assert(rands_[i].done()); + break; + } + prm.nExIters++; + first = false; + assert(!gws_[i].done()); + // Resolve next element offset + WalkResult wr; + uint32_t elt = rands_[i].next(rnd); + SARangeWithOffs sa; + sa.topf = satpos_[i].sat.topf; + sa.len = satpos_[i].sat.key.len; + sa.offs = satpos_[i].sat.offs; + gws_[i].advanceElement((index_t)elt, gfmFw, ref, sa, gwstate_, wr, wlm, prm); + eltsDone++; + assert_gt(neltLeft, 0); + neltLeft--; + assert_neq((index_t)OFF_MASK, wr.toff); + index_t tidx = 0, toff = 0, tlen = 0; + bool straddled = false; + gfmFw.joinedToTextOff( + wr.elt.len, + wr.toff, + tidx, + toff, + tlen, + eeMode, // reject straddlers? + straddled); // straddled? + if(tidx == (index_t)OFF_MASK) { + // The seed hit straddled a reference boundary so the seed hit + // isn't valid + continue; + } +#ifndef NDEBUG + if(!eeMode && !straddled) { // Check that seed hit matches reference + uint64_t key = satpos_[i].sat.key.seq; + for(index_t k = 0; k < wr.elt.len; k++) { + int c = ref.getBase(tidx, toff + wr.elt.len - k - 1); + assert_leq(c, 3); + int ck = (int)(key & 3); + key >>= 2; + assert_eq(c, ck); + } + } +#endif + // Find offset of alignment's upstream base assuming net gaps=0 + // between beginning of read and beginning of seed hit + int64_t refoff = (int64_t)toff - rdoff; + EIvalMergeListBinned& seenDiags = anchor1 ? seenDiags1_ : seenDiags2_; + // Coordinate of the seed hit w/r/t the pasted reference string + Coord refcoord(tidx, refoff, fw); + if(seenDiags.locusPresent(refcoord)) { + // Already handled alignments seeded on this diagonal + prm.nRedundants++; + swmSeed.rshit++; + continue; + } + // Now that we have a seed hit, there are many issues to solve + // before we have a completely framed dynamic programming problem. + // They include: + // + // 1. Setting reference offsets on either side of the seed hit, + // accounting for where the seed occurs in the read + // 2. Adjusting the width of the banded dynamic programming problem + // and adjusting reference bounds to allow for gaps in the + // alignment + // 3. Accounting for the edges of the reference, which can impact + // the width of the DP problem and reference bounds. + // 4. Perhaps filtering the problem down to a smaller problem based + // on what DPs we've already solved for this read + // + // We do #1 here, since it is simple and we have all the seed-hit + // information here. #2 and #3 are handled in the DynProgFramer. + int readGaps = 0, refGaps = 0; + bool ungapped = false; + if(!eeMode) { + readGaps = sc.maxReadGaps(minsc, rdlen); + refGaps = sc.maxRefGaps(minsc, rdlen); + ungapped = (readGaps == 0 && refGaps == 0); + } + int state = FOUND_NONE; + bool found = false; + // In unpaired mode, a seed extension is successful if it + // results in a full alignment that meets the minimum score + // threshold. In paired-end mode, a seed extension is + // successful if it results in a *full paired-end* alignment + // that meets the minimum score threshold. + if(eeMode) { + resEe_.reset(); + resEe_.alres.reset(); + const EEHit& h = eehits_[i]; + assert_leq(h.score, perfectScore); + resEe_.alres.setScore(AlnScore(h.score, h.ns(), 0)); + resEe_.alres.setShape( + refcoord.ref(), // ref id + refcoord.off(), // 0-based ref offset + tlen, // reference length + fw, // aligned to Watson? + rdlen, // read length + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + 0, // alignment trim 5' end + 0); // alignment trim 3' end + resEe_.alres.setRefNs(h.refns()); + if(h.mms() > 0) { + assert_eq(1, h.mms()); + assert_lt(h.e1.pos, rd.length()); + resEe_.alres.ned().push_back(h.e1); + } + assert(resEe_.repOk(rd)); + state = FOUND_EE; + found = true; + Interval refival(refcoord, 1); + seenDiags.add(refival); + prm.nExEes++; + prm.nEeFail++; // say it's failed until proven successful + prm.nExEeFails++; + } else if(doUngapped && ungapped) { + resUngap_.reset(); + int al = swa.ungappedAlign( + fw ? rd.patFw : rd.patRc, + fw ? rd.qual : rd.qualRev, + refcoord, + ref, + tlen, + sc, + gReportOverhangs, + minsc, // minimum + resUngap_); + Interval refival(refcoord, 1); + seenDiags.add(refival); + prm.nExUgs++; + prm.nUgFail++; // say it's failed until proven successful + prm.nExUgFails++; + if(al == 0) { + swmSeed.ungapfail++; + continue; + } else if(al == -1) { + swmSeed.ungapnodec++; + } else { + found = true; + state = FOUND_UNGAPPED; + swmSeed.ungapsucc++; + } + } + int64_t pastedRefoff = (int64_t)wr.toff - rdoff; + DPRect rect; + if(state == FOUND_NONE) { + found = dpframe.frameSeedExtensionRect( + refoff, // ref offset implied by seed hit assuming no gaps + rows, // length of read sequence used in DP table + tlen, // length of reference + readGaps, // max # of read gaps permitted in opp mate alignment + refGaps, // max # of ref gaps permitted in opp mate alignment + (size_t)nceil, // # Ns permitted + maxhalf, // max width in either direction + rect); // DP rectangle + assert(rect.repOk()); + // Add the seed diagonal at least + seenDiags.add(Interval(refcoord, 1)); + if(!found) { + continue; + } + } + int64_t leftShift = refoff - rect.refl; + size_t nwindow = 0; + if(toff >= rect.refl) { + nwindow = (size_t)(toff - rect.refl); + } + // NOTE: We might be taking off more than we should because the + // pasted string omits non-A/C/G/T characters, but we included them + // when calculating leftShift. We'll account for this later. + pastedRefoff -= leftShift; + size_t nsInLeftShift = 0; + if(state == FOUND_NONE) { + if(!swa.initedRead()) { + // Initialize the aligner with a new read + swa.initRead( + rd.patFw, // fw version of query + rd.patRc, // rc version of query + rd.qual, // fw version of qualities + rd.qualRev,// rc version of qualities + 0, // off of first char in 'rd' to consider + rdlen, // off of last char (excl) in 'rd' to consider + sc); // scoring scheme + } + swa.initRef( + fw, // whether to align forward or revcomp read + tidx, // reference aligned against + rect, // DP rectangle + ref, // Reference strings + tlen, // length of reference sequence + sc, // scoring scheme + minsc, // minimum score permitted + enable8, // use 8-bit SSE if possible? + cminlen, // minimum length for using checkpointing scheme + cpow2, // interval b/t checkpointed diags; 1 << this + doTri, // triangular mini-fills? + true, // this is a seed extension - not finding a mate + nwindow, + nsInLeftShift); + // Because of how we framed the problem, we can say that we've + // exhaustively scored the seed diagonal as well as maxgaps + // diagonals on either side + Interval refival(tidx, 0, fw, 0); + rect.initIval(refival); + seenDiags.add(refival); + // Now fill the dynamic programming matrix and return true iff + // there is at least one valid alignment + TAlScore bestCell = std::numeric_limits::min(); + found = swa.align(rnd, bestCell); + swmSeed.tallyGappedDp(readGaps, refGaps); + prm.nExDps++; + prm.nDpFail++; // failed until proven successful + prm.nExDpFails++; // failed until proven successful + if(!found) { + TAlScore bestLast = anchor1 ? prm.bestLtMinscMate1 : prm.bestLtMinscMate2; + if(bestCell > std::numeric_limits::min() && bestCell > bestLast) { + if(anchor1) { + prm.bestLtMinscMate1 = bestCell; + } else { + prm.bestLtMinscMate2 = bestCell; + } + } + continue; // Look for more anchor alignments + } + } + bool firstInner = true; + bool foundConcordant = false; + while(true) { + assert(found); + SwResult *res = NULL; + if(state == FOUND_EE) { + if(!firstInner) { + break; + } + res = &resEe_; + assert(res->repOk(rd)); + } else if(state == FOUND_UNGAPPED) { + if(!firstInner) { + break; + } + res = &resUngap_; + assert(res->repOk(rd)); + } else { + resGap_.reset(); + assert(resGap_.empty()); + if(swa.done()) { + break; + } + swa.nextAlignment(resGap_, minsc, rnd); + found = !resGap_.empty(); + if(!found) { + break; + } + res = &resGap_; + assert(res->repOk(rd)); + } + // TODO: If we're just taking anchor alignments out of the + // same rectangle, aren't we getting very similar + // rectangles for the opposite mate each time? Seems like + // we could save some work by detecting this. + assert(res != NULL); + firstInner = false; + assert(res->alres.matchesRef( + rd, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + raw_refbuf_, + raw_destU32_, + raw_matches_, + tmp_reflens_, + tmp_refoffs_)); + Interval refival(tidx, 0, fw, tlen); + assert_gt(res->alres.refExtent(), 0); + if(gReportOverhangs && + !refival.containsIgnoreOrient(res->alres.refival())) + { + res->alres.clipOutside(true, 0, tlen); + if(res->alres.refExtent() == 0) { + continue; + } + } + assert(gReportOverhangs || + refival.containsIgnoreOrient(res->alres.refival())); + // Did the alignment fall entirely outside the reference? + if(!refival.overlapsIgnoreOrient(res->alres.refival())) { + continue; + } + // Is this alignment redundant with one we've seen previously? + if(redAnchor_.overlap(res->alres)) { + continue; + } + redAnchor_.add(res->alres); + // Annotate the AlnRes object with some key parameters + // that were used to obtain the alignment. + res->alres.setParams( + seedmms, // # mismatches allowed in seed + seedlen, // length of seed + seedival, // interval between seeds + minsc); // minimum score for valid alignment + bool foundMate = false; + TRefOff off = res->alres.refoff(); + if( msink->state().doneWithMate(!anchor1) && + !msink->state().doneWithMate( anchor1)) + { + // We're done with the opposite mate but not with the + // anchor mate; don't try to mate up the anchor. + swMateImmediately = false; + } + if(found && swMateImmediately) { + assert(!msink->state().doneWithMate(!anchor1)); + bool oleft = false, ofw = false; + int64_t oll = 0, olr = 0, orl = 0, orr = 0; + assert(!msink->state().done()); + foundMate = !oppFilt; + TAlScore ominsc_cur = ominsc; + //bool oungapped = false; + int oreadGaps = 0, orefGaps = 0; + //int oungappedAlign = -1; // defer + if(foundMate) { + // Adjust ominsc given the alignment score of the + // anchor mate + ominsc_cur = ominsc; + if(tighten > 0 && msink->Mmode() && msink->hasSecondBestPair()) { + // Paired-end alignments should have at least this score from now + TAlScore ps; + if(tighten == 1) { + ps = msink->bestPair(); + } else if(tighten == 2) { + ps = msink->secondBestPair(); + } else { + TAlScore diff = msink->bestPair() - msink->secondBestPair(); + ps = msink->secondBestPair() + (diff * 3)/4; + } + if(tighten == 1 && ps < bestPairScore && + msink->bestPair() == msink->secondBestPair()) + { + ps++; + } + if(tighten >= 2 && ps < bestPairScore) { + ps++; + } + // Anchor mate must have score at least 'ps' minus the best possible + // score for the opposite mate. + TAlScore nc = ps - res->alres.score().score(); + if(nc > ominsc_cur) { + ominsc_cur = nc; + assert_leq(ominsc_cur, operfectScore); + } + } + oreadGaps = sc.maxReadGaps(ominsc_cur, ordlen); + orefGaps = sc.maxRefGaps (ominsc_cur, ordlen); + //oungapped = (oreadGaps == 0 && orefGaps == 0); + // TODO: Something lighter-weight than DP to scan + // for other mate?? + //if(oungapped) { + // oresUngap_.reset(); + // oungappedAlign = oswa.ungappedAlign( + // ofw ? ord.patFw : ord.patRc, + // ofw ? ord.qual : ord.qualRev, + // orefcoord, + // ref, + // otlen, + // sc, + // gReportOverhangs, + // ominsc_cur, + // 0, + // oresUngap_); + //} + foundMate = pepol.otherMate( + anchor1, // anchor mate is mate #1? + fw, // anchor aligned to Watson? + off, // offset of anchor mate + orows + oreadGaps, // max # columns spanned by alignment + tlen, // reference length + anchor1 ? rd.length() : ord.length(), // mate 1 len + anchor1 ? ord.length() : rd.length(), // mate 2 len + oleft, // out: look left for opposite mate? + oll, + olr, + orl, + orr, + ofw); + } + DPRect orect; + if(foundMate) { + foundMate = dpframe.frameFindMateRect( + !oleft, // true iff anchor alignment is to the left + oll, // leftmost Watson off for LHS of opp aln + olr, // rightmost Watson off for LHS of opp aln + orl, // leftmost Watson off for RHS of opp aln + orr, // rightmost Watson off for RHS of opp aln + orows, // length of opposite mate + tlen, // length of reference sequence aligned to + oreadGaps, // max # of read gaps in opp mate aln + orefGaps, // max # of ref gaps in opp mate aln + (size_t)onceil, // max # Ns on opp mate + maxhalf, // max width in either direction + orect); // DP rectangle + assert(!foundMate || orect.refr >= orect.refl); + } + if(foundMate) { + oresGap_.reset(); + assert(oresGap_.empty()); + if(!oswa.initedRead()) { + oswa.initRead( + ord.patFw, // read to align + ord.patRc, // qualities + ord.qual, // read to align + ord.qualRev,// qualities + 0, // off of first char to consider + ordlen, // off of last char (ex) to consider + sc); // scoring scheme + } + // Given the boundaries defined by refi and reff, initilize + // the SwAligner with the dynamic programming problem that + // aligns the read to this reference stretch. + size_t onsInLeftShift = 0; + assert_geq(orect.refr, orect.refl); + oswa.initRef( + ofw, // align forward or revcomp read? + tidx, // reference aligned against + orect, // DP rectangle + ref, // Reference strings + tlen, // length of reference sequence + sc, // scoring scheme + ominsc_cur,// min score for valid alignments + enable8, // use 8-bit SSE if possible? + cminlen, // minimum length for using checkpointing scheme + cpow2, // interval b/t checkpointed diags; 1 << this + doTri, // triangular mini-fills? + false, // this is finding a mate - not seed ext + 0, // nwindow? + onsInLeftShift); + // TODO: Can't we add some diagonals to the + // opposite mate's seenDiags when we fill in the + // opposite mate's DP? Or can we? We might want + // to use this again as an anchor - will that still + // happen? Also, isn't there a problem with + // consistency of the minimum score? Minimum score + // here depends in part on the score of the anchor + // alignment here, but it won't when the current + // opposite becomes the anchor. + + // Because of how we framed the problem, we can say + // that we've exhaustively explored the "core" + // diagonals + //Interval orefival(tidx, 0, ofw, 0); + //orect.initIval(orefival); + //oseenDiags.add(orefival); + + // Now fill the dynamic programming matrix, return true + // iff there is at least one valid alignment + TAlScore bestCell = std::numeric_limits::min(); + foundMate = oswa.align(rnd, bestCell); + prm.nMateDps++; + swmMate.tallyGappedDp(oreadGaps, orefGaps); + if(!foundMate) { + TAlScore bestLast = anchor1 ? prm.bestLtMinscMate2 : prm.bestLtMinscMate1; + if(bestCell > std::numeric_limits::min() && bestCell > bestLast) { + if(anchor1) { + prm.bestLtMinscMate2 = bestCell; + } else { + prm.bestLtMinscMate1 = bestCell; + } + } + } + } + bool didAnchor = false; + do { + oresGap_.reset(); + assert(oresGap_.empty()); + if(foundMate && oswa.done()) { + foundMate = false; + } else if(foundMate) { + oswa.nextAlignment(oresGap_, ominsc_cur, rnd); + foundMate = !oresGap_.empty(); + assert(!foundMate || oresGap_.alres.matchesRef( + ord, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + raw_refbuf_, + raw_destU32_, + raw_matches_, + tmp_reflens_, + tmp_refoffs_)); + } + if(foundMate) { + // Redundant with one we've seen previously? + if(!redAnchor_.overlap(oresGap_.alres)) { + redAnchor_.add(oresGap_.alres); + } + assert_eq(ofw, oresGap_.alres.fw()); + // Annotate the AlnRes object with some key parameters + // that were used to obtain the alignment. + oresGap_.alres.setParams( + seedmms, // # mismatches allowed in seed + seedlen, // length of seed + seedival, // interval between seeds + ominsc); // minimum score for valid alignment + assert_gt(oresGap_.alres.refExtent(), 0); + if(gReportOverhangs && + !refival.containsIgnoreOrient(oresGap_.alres.refival())) + { + oresGap_.alres.clipOutside(true, 0, tlen); + foundMate = oresGap_.alres.refExtent() > 0; + } + if(foundMate && + ((!gReportOverhangs && + !refival.containsIgnoreOrient(oresGap_.alres.refival())) || + !refival.overlapsIgnoreOrient(oresGap_.alres.refival()))) + { + foundMate = false; + } + } + ASSERT_ONLY(TRefId refid); + TRefOff off1, off2; + size_t len1, len2; + bool fw1, fw2; + int pairCl = PE_ALS_DISCORD; + if(foundMate) { + ASSERT_ONLY(refid =) res->alres.refid(); + assert_eq(refid, oresGap_.alres.refid()); + off1 = anchor1 ? off : oresGap_.alres.refoff(); + off2 = anchor1 ? oresGap_.alres.refoff() : off; + len1 = anchor1 ? + res->alres.refExtent() : oresGap_.alres.refExtent(); + len2 = anchor1 ? + oresGap_.alres.refExtent() : res->alres.refExtent(); + fw1 = anchor1 ? res->alres.fw() : oresGap_.alres.fw(); + fw2 = anchor1 ? oresGap_.alres.fw() : res->alres.fw(); + // Check that final mate alignments are consistent with + // paired-end fragment constraints + pairCl = pepol.peClassifyPair( + off1, + len1, + fw1, + off2, + len2, + fw2); + // Instead of trying + //foundMate = pairCl != PE_ALS_DISCORD; + } + if(msink->state().doneConcordant()) { + foundMate = false; + } + if(reportImmediately) { + if(foundMate) { + // Report pair to the AlnSinkWrap + assert(!msink->state().doneConcordant()); + assert(msink != NULL); + assert(res->repOk()); + assert(oresGap_.repOk()); + // Report an unpaired alignment + assert(!msink->maxed()); + assert(!msink->state().done()); + bool doneUnpaired = false; + //if(mixed || discord) { + // Report alignment for mate #1 as an + // unpaired alignment. + if(!anchor1 || !didAnchor) { + if(anchor1) { + didAnchor = true; + } + const AlnRes& r1 = anchor1 ? + res->alres : oresGap_.alres; + if(!redMate1_.overlap(r1)) { + redMate1_.add(r1); + if(msink->report(0, &r1, NULL)) { + doneUnpaired = true; // Short-circuited + } + } + } + // Report alignment for mate #2 as an + // unpaired alignment. + if(anchor1 || !didAnchor) { + if(!anchor1) { + didAnchor = true; + } + const AlnRes& r2 = anchor1 ? + oresGap_.alres : res->alres; + if(!redMate2_.overlap(r2)) { + redMate2_.add(r2); + if(msink->report(0, NULL, &r2)) { + doneUnpaired = true; // Short-circuited + } + } + } + //} // if(mixed || discord) + bool donePaired = false; + if(pairCl != PE_ALS_DISCORD) { + foundConcordant = true; + if(msink->report( + 0, + anchor1 ? &res->alres : &oresGap_.alres, + anchor1 ? &oresGap_.alres : &res->alres)) + { + // Short-circuited because a limit, e.g. + // -k, -m or -M, was exceeded + donePaired = true; + } else { + if(tighten > 0 && msink->Mmode() && msink->hasSecondBestPair()) { + // Paired-end alignments should have at least this score from now + TAlScore ps; + if(tighten == 1) { + ps = msink->bestPair(); + } else if(tighten == 2) { + ps = msink->secondBestPair(); + } else { + TAlScore diff = msink->bestPair() - msink->secondBestPair(); + ps = msink->secondBestPair() + (diff * 3)/4; + } + if(tighten == 1 && ps < bestPairScore && + msink->bestPair() == msink->secondBestPair()) + { + ps++; + } + if(tighten >= 2 && ps < bestPairScore) { + ps++; + } + // Anchor mate must have score at least 'ps' minus the best possible + // score for the opposite mate. + TAlScore nc = ps - operfectScore; + if(nc > minsc) { + minsc = nc; + assert_leq(minsc, perfectScore); + if(minsc > res->alres.score().score()) { + // We're done with this anchor + break; + } + } + assert_leq(minsc, perfectScore); + } + } + } // if(pairCl != PE_ALS_DISCORD) + if(donePaired || doneUnpaired) { + return EXTEND_POLICY_FULFILLED; + } + if(msink->state().doneWithMate(anchor1)) { + // We're now done with the mate that we're + // currently using as our anchor. We're not + // with the read overall. + return EXTEND_POLICY_FULFILLED; + } + } else if((mixed || discord) && !didAnchor) { + didAnchor = true; + // Report unpaired hit for anchor + assert(msink != NULL); + assert(res->repOk()); + // Check that alignment accurately reflects the + // reference characters aligned to + assert(res->alres.matchesRef( + rd, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + raw_refbuf_, + raw_destU32_, + raw_matches_, + tmp_reflens_, + tmp_refoffs_)); + // Report an unpaired alignment + assert(!msink->maxed()); + assert(!msink->state().done()); + // Report alignment for mate #1 as an + // unpaired alignment. + if(!msink->state().doneUnpaired(anchor1)) { + const AlnRes& r = res->alres; + RedundantAlns& red = anchor1 ? redMate1_ : redMate2_; + const AlnRes* r1 = anchor1 ? &res->alres : NULL; + const AlnRes* r2 = anchor1 ? NULL : &res->alres; + if(!red.overlap(r)) { + red.add(r); + if(msink->report(0, r1, r2)) { + return EXTEND_POLICY_FULFILLED; // Short-circuited + } + } + } + if(msink->state().doneWithMate(anchor1)) { + // Done with mate, but not read overall + return EXTEND_POLICY_FULFILLED; + } + } + } + } while(!oresGap_.empty()); + } // if(found && swMateImmediately) + else if(found) { + assert(!msink->state().doneWithMate(anchor1)); + // We found an anchor alignment but did not attempt to find + // an alignment for the opposite mate (probably because + // we're done with it) + if(reportImmediately && (mixed || discord)) { + // Report unpaired hit for anchor + assert(msink != NULL); + assert(res->repOk()); + // Check that alignment accurately reflects the + // reference characters aligned to + assert(res->alres.matchesRef( + rd, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + raw_refbuf_, + raw_destU32_, + raw_matches_, + tmp_reflens_, + tmp_refoffs_)); + // Report an unpaired alignment + assert(!msink->maxed()); + assert(!msink->state().done()); + // Report alignment for mate #1 as an + // unpaired alignment. + if(!msink->state().doneUnpaired(anchor1)) { + const AlnRes& r = res->alres; + RedundantAlns& red = anchor1 ? redMate1_ : redMate2_; + const AlnRes* r1 = anchor1 ? &res->alres : NULL; + const AlnRes* r2 = anchor1 ? NULL : &res->alres; + if(!red.overlap(r)) { + red.add(r); + if(msink->report(0, r1, r2)) { + return EXTEND_POLICY_FULFILLED; // Short-circuited + } + } + } + if(msink->state().doneWithMate(anchor1)) { + // Done with mate, but not read overall + return EXTEND_POLICY_FULFILLED; + } + } + } + } // while(true) + + if(foundConcordant) { + prm.nMateDpSuccs++; + mateStreaks_[i] = 0; + // Register this as a success. Now we need to + // make the streak variables reflect the + // success. + if(state == FOUND_UNGAPPED) { + assert_gt(prm.nUgFail, 0); + assert_gt(prm.nExUgFails, 0); + prm.nExUgFails--; + prm.nExUgSuccs++; + prm.nUgLastSucc = prm.nExUgs-1; + if(prm.nUgFail > prm.nUgFailStreak) { + prm.nUgFailStreak = prm.nUgFail; + } + prm.nUgFail = 0; + } else if(state == FOUND_EE) { + assert_gt(prm.nEeFail, 0); + assert_gt(prm.nExEeFails, 0); + prm.nExEeFails--; + prm.nExEeSuccs++; + prm.nEeLastSucc = prm.nExEes-1; + if(prm.nEeFail > prm.nEeFailStreak) { + prm.nEeFailStreak = prm.nEeFail; + } + prm.nEeFail = 0; + } else { + assert_gt(prm.nDpFail, 0); + assert_gt(prm.nExDpFails, 0); + prm.nExDpFails--; + prm.nExDpSuccs++; + prm.nDpLastSucc = prm.nExDps-1; + if(prm.nDpFail > prm.nDpFailStreak) { + prm.nDpFailStreak = prm.nDpFail; + } + prm.nDpFail = 0; + } + } else { + prm.nMateDpFails++; + mateStreaks_[i]++; + } + // At this point we know that we aren't bailing, and will continue to resolve seed hits. + + } // while(!gw.done()) + } // for(size_t i = 0; i < gws_.size(); i++) + } + return EXTEND_EXHAUSTED_CANDIDATES; +} + +#endif /*ALIGNER_SW_DRIVER_H_*/ diff --git a/aligner_sw_nuc.h b/aligner_sw_nuc.h new file mode 100644 index 0000000..6bec1de --- /dev/null +++ b/aligner_sw_nuc.h @@ -0,0 +1,262 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_SW_NUC_H_ +#define ALIGNER_SW_NUC_H_ + +#include +#include "aligner_sw_common.h" +#include "aligner_result.h" + +/** + * Encapsulates a backtrace stack frame. Includes enough information that we + * can "pop" back up to this frame and choose to make a different backtracking + * decision. The information included is: + * + * 1. The mask at the decision point. When we first move through the mask and + * when we backtrack to it, we're careful to mask out the bit corresponding + * to the path we're taking. When we move through it after removing the + * last bit from the mask, we're careful to pop it from the stack. + * 2. The sizes of the edit lists. When we backtrack, we resize the lists back + * down to these sizes to get rid of any edits introduced since the branch + * point. + */ +struct DpNucFrame { + + /** + * Initialize a new DpNucFrame stack frame. + */ + void init( + size_t nedsz_, + size_t aedsz_, + size_t celsz_, + size_t row_, + size_t col_, + size_t gaps_, + size_t readGaps_, + size_t refGaps_, + AlnScore score_, + int ct_) + { + nedsz = nedsz_; + aedsz = aedsz_; + celsz = celsz_; + row = row_; + col = col_; + gaps = gaps_; + readGaps = readGaps_; + refGaps = refGaps_; + score = score_; + ct = ct_; + } + + size_t nedsz; // size of the nucleotide edit list at branch (before + // adding the branch edit) + size_t aedsz; // size of ambiguous nucleotide edit list at branch + size_t celsz; // size of cell-traversed list at branch + size_t row; // row of cell where branch occurred + size_t col; // column of cell where branch occurred + size_t gaps; // number of gaps before branch occurred + size_t readGaps; // number of read gaps before branch occurred + size_t refGaps; // number of ref gaps before branch occurred + AlnScore score; // score where branch occurred + int ct; // table type (oall, rdgap or rfgap) +}; + +enum { + BT_CAND_FATE_SUCCEEDED = 1, + BT_CAND_FATE_FAILED, + BT_CAND_FATE_FILT_START, // skipped b/c starting cell already explored + BT_CAND_FATE_FILT_DOMINATED, // skipped b/c it was dominated + BT_CAND_FATE_FILT_SCORE // skipped b/c score not interesting anymore +}; + +/** + * Encapsulates a cell that we might want to backtrace from. + */ +struct DpBtCandidate { + + DpBtCandidate() { reset(); } + + DpBtCandidate(size_t row_, size_t col_, TAlScore score_) { + init(row_, col_, score_); + } + + void reset() { init(0, 0, 0); } + + void init(size_t row_, size_t col_, TAlScore score_) { + row = row_; + col = col_; + score = score_; + // 0 = invalid; this should be set later according to what happens + // before / during the backtrace + fate = 0; + } + + /** + * Return true iff this candidate is (heuristically) dominated by the given + * candidate. We say that candidate A dominates candidate B if (a) B is + * somewhere in the N x N square that extends up and to the left of A, + * where N is an arbitrary number like 20, and (b) B's score is <= than + * A's. + */ + inline bool dominatedBy(const DpBtCandidate& o) { + const size_t SQ = 40; + size_t rowhi = row; + size_t rowlo = o.row; + if(rowhi < rowlo) swap(rowhi, rowlo); + size_t colhi = col; + size_t collo = o.col; + if(colhi < collo) swap(colhi, collo); + return (colhi - collo) <= SQ && + (rowhi - rowlo) <= SQ; + } + + /** + * Return true if this candidate is "greater than" (should be considered + * later than) the given candidate. + */ + bool operator>(const DpBtCandidate& o) const { + if(score < o.score) return true; + if(score > o.score) return false; + if(row < o.row ) return true; + if(row > o.row ) return false; + if(col < o.col ) return true; + if(col > o.col ) return false; + return false; + } + + /** + * Return true if this candidate is "less than" (should be considered + * sooner than) the given candidate. + */ + bool operator<(const DpBtCandidate& o) const { + if(score > o.score) return true; + if(score < o.score) return false; + if(row > o.row ) return true; + if(row < o.row ) return false; + if(col > o.col ) return true; + if(col < o.col ) return false; + return false; + } + + /** + * Return true if this candidate equals the given candidate. + */ + bool operator==(const DpBtCandidate& o) const { + return row == o.row && + col == o.col && + score == o.score; + } + bool operator>=(const DpBtCandidate& o) const { return !((*this) < o); } + bool operator<=(const DpBtCandidate& o) const { return !((*this) > o); } + +#ifndef NDEBUG + /** + * Check internal consistency. + */ + bool repOk() const { + assert(VALID_SCORE(score)); + return true; + } +#endif + + size_t row; // cell row + size_t col; // cell column w/r/t LHS of rectangle + TAlScore score; // score fo alignment + int fate; // flag indicating whether we succeeded, failed, skipped +}; + +template +class NBest { + +public: + + NBest() { nelt_ = nbest_ = n_ = 0; } + + bool inited() const { return nelt_ > 0; } + + void init(size_t nelt, size_t nbest) { + nelt_ = nelt; + nbest_ = nbest; + elts_.resize(nelt * nbest); + ncur_.resize(nelt); + ncur_.fill(0); + n_ = 0; + } + + /** + * Add a new result to bin 'elt'. Where it gets prioritized in the list of + * results in that bin depends on the result of operator>. + */ + bool add(size_t elt, const T& o) { + assert_lt(elt, nelt_); + const size_t ncur = ncur_[elt]; + assert_leq(ncur, nbest_); + n_++; + for(size_t i = 0; i < nbest_ && i <= ncur; i++) { + if(o > elts_[nbest_ * elt + i] || i >= ncur) { + // Insert it here + // Move everyone from here on down by one slot + for(int j = (int)ncur; j > (int)i; j--) { + if(j < (int)nbest_) { + elts_[nbest_ * elt + j] = elts_[nbest_ * elt + j - 1]; + } + } + elts_[nbest_ * elt + i] = o; + if(ncur < nbest_) { + ncur_[elt]++; + } + return true; + } + } + return false; + } + + /** + * Return true iff there are no solutions. + */ + bool empty() const { + return n_ == 0; + } + + /** + * Dump all the items in our payload into the given EList. + */ + template + void dump(TList& l) const { + if(empty()) return; + for(size_t i = 0; i < nelt_; i++) { + assert_leq(ncur_[i], nbest_); + for(size_t j = 0; j < ncur_[i]; j++) { + l.push_back(elts_[i * nbest_ + j]); + } + } + } + +protected: + + size_t nelt_; + size_t nbest_; + EList elts_; + EList ncur_; + size_t n_; // total # results added +}; + +#endif /*def ALIGNER_SW_NUC_H_*/ diff --git a/aligner_swsse.cpp b/aligner_swsse.cpp new file mode 100644 index 0000000..d4f7d78 --- /dev/null +++ b/aligner_swsse.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "aligner_sw_common.h" +#include "aligner_swsse.h" + +/** + * Given a number of rows (nrow), a number of columns (ncol), and the + * number of words to fit inside a single __m128i vector, initialize the + * matrix buffer to accomodate the needed configuration of vectors. + */ +void SSEMatrix::init( + size_t nrow, + size_t ncol, + size_t wperv) +{ + nrow_ = nrow; + ncol_ = ncol; + wperv_ = wperv; + nvecPerCol_ = (nrow + (wperv-1)) / wperv; + // The +1 is so that we don't have to special-case the final column; + // instead, we just write off the end of the useful part of the table + // with pvEStore. + try { + matbuf_.resizeNoCopy((ncol+1) * nvecPerCell_ * nvecPerCol_); + } catch(exception& e) { + cerr << "Tried to allocate DP matrix with " << (ncol+1) + << " columns, " << nvecPerCol_ + << " vectors per column, and and " << nvecPerCell_ + << " vectors per cell" << endl; + throw e; + } + assert(wperv_ == 8 || wperv_ == 16); + vecshift_ = (wperv_ == 8) ? 3 : 4; + nvecrow_ = (nrow + (wperv_-1)) >> vecshift_; + nveccol_ = ncol; + colstride_ = nvecPerCol_ * nvecPerCell_; + rowstride_ = nvecPerCell_; + inited_ = true; +} + +/** + * Initialize the matrix of masks and backtracking flags. + */ +void SSEMatrix::initMasks() { + assert_gt(nrow_, 0); + assert_gt(ncol_, 0); + masks_.resize(nrow_); + reset_.resizeNoCopy(nrow_); + reset_.fill(false); +} + +/** + * Given a row, col and matrix (i.e. E, F or H), return the corresponding + * element. + */ +int SSEMatrix::eltSlow(size_t row, size_t col, size_t mat) const { + assert_lt(row, nrow_); + assert_lt(col, ncol_); + assert_leq(mat, 3); + // Move to beginning of column/row + size_t rowelt = row / nvecrow_; + size_t rowvec = row % nvecrow_; + size_t eltvec = (col * colstride_) + (rowvec * rowstride_) + mat; + if(wperv_ == 16) { + return (int)((uint8_t*)(matbuf_.ptr() + eltvec))[rowelt]; + } else { + assert_eq(8, wperv_); + return (int)((int16_t*)(matbuf_.ptr() + eltvec))[rowelt]; + } +} diff --git a/aligner_swsse.h b/aligner_swsse.h new file mode 100644 index 0000000..70d5c6d --- /dev/null +++ b/aligner_swsse.h @@ -0,0 +1,500 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALIGNER_SWSSE_H_ +#define ALIGNER_SWSSE_H_ + +#include "ds.h" +#include "mem_ids.h" +#include "random_source.h" +#include "scoring.h" +#include "mask.h" +#include "sse_util.h" +#include + + +struct SSEMetrics { + + SSEMetrics():mutex_m() { reset(); } + + void clear() { reset(); } + void reset() { + dp = dpsat = dpfail = dpsucc = + col = cell = inner = fixup = + gathsol = bt = btfail = btsucc = btcell = + corerej = nrej = 0; + } + + void merge(const SSEMetrics& o, bool getLock = false) { + ThreadSafe ts(&mutex_m, getLock); + dp += o.dp; + dpsat += o.dpsat; + dpfail += o.dpfail; + dpsucc += o.dpsucc; + col += o.col; + cell += o.cell; + inner += o.inner; + fixup += o.fixup; + gathsol += o.gathsol; + bt += o.bt; + btfail += o.btfail; + btsucc += o.btsucc; + btcell += o.btcell; + corerej += o.corerej; + nrej += o.nrej; + } + + uint64_t dp; // DPs tried + uint64_t dpsat; // DPs saturated + uint64_t dpfail; // DPs failed + uint64_t dpsucc; // DPs succeeded + uint64_t col; // DP columns + uint64_t cell; // DP cells + uint64_t inner; // DP inner loop iters + uint64_t fixup; // DP fixup loop iters + uint64_t gathsol; // DP gather solution cells found + uint64_t bt; // DP backtraces + uint64_t btfail; // DP backtraces failed + uint64_t btsucc; // DP backtraces succeeded + uint64_t btcell; // DP backtrace cells traversed + uint64_t corerej; // DP backtrace core rejections + uint64_t nrej; // DP backtrace N rejections + MUTEX_T mutex_m; +}; + +/** + * Encapsulates matrix information calculated by the SSE aligner. + * + * Matrix memory is laid out as follows: + * + * - Elements (individual cell scores) are packed into __m128i vectors + * - Vectors are packed into quartets, quartet elements correspond to: a vector + * from E, one from F, one from H, and one that's "reserved" + * - Quartets are packed into columns, where the number of quartets is + * determined by the number of query characters divided by the number of + * elements per vector + * + * Regarding the "reserved" element of the vector quartet: we use it for two + * things. First, we use the first column of reserved vectors to stage the + * initial column of H vectors. Second, we use the "reserved" vectors during + * the backtrace procedure to store information about (a) which cells have been + * traversed, (b) whether the cell is "terminal" (in local mode), etc. + */ +struct SSEMatrix { + + // Each matrix element is a quartet of vectors. These constants are used + // to identify members of the quartet. + const static size_t E = 0; + const static size_t F = 1; + const static size_t H = 2; + const static size_t TMP = 3; + + SSEMatrix(int cat = 0) : nvecPerCell_(4), matbuf_(cat) { } + + /** + * Return a pointer to the matrix buffer. + */ + inline __m128i *ptr() { + assert(inited_); + return matbuf_.ptr(); + } + + /** + * Return a pointer to the E vector at the given row and column. Note: + * here row refers to rows of vectors, not rows of elements. + */ + inline __m128i* evec(size_t row, size_t col) { + assert_lt(row, nvecrow_); + assert_lt(col, nveccol_); + size_t elt = row * rowstride() + col * colstride() + E; + assert_lt(elt, matbuf_.size()); + return ptr() + elt; + } + + /** + * Like evec, but it's allowed to ask for a pointer to one column after the + * final one. + */ + inline __m128i* evecUnsafe(size_t row, size_t col) { + assert_lt(row, nvecrow_); + assert_leq(col, nveccol_); + size_t elt = row * rowstride() + col * colstride() + E; + assert_lt(elt, matbuf_.size()); + return ptr() + elt; + } + + /** + * Return a pointer to the F vector at the given row and column. Note: + * here row refers to rows of vectors, not rows of elements. + */ + inline __m128i* fvec(size_t row, size_t col) { + assert_lt(row, nvecrow_); + assert_lt(col, nveccol_); + size_t elt = row * rowstride() + col * colstride() + F; + assert_lt(elt, matbuf_.size()); + return ptr() + elt; + } + + /** + * Return a pointer to the H vector at the given row and column. Note: + * here row refers to rows of vectors, not rows of elements. + */ + inline __m128i* hvec(size_t row, size_t col) { + assert_lt(row, nvecrow_); + assert_lt(col, nveccol_); + size_t elt = row * rowstride() + col * colstride() + H; + assert_lt(elt, matbuf_.size()); + return ptr() + elt; + } + + /** + * Return a pointer to the TMP vector at the given row and column. Note: + * here row refers to rows of vectors, not rows of elements. + */ + inline __m128i* tmpvec(size_t row, size_t col) { + assert_lt(row, nvecrow_); + assert_lt(col, nveccol_); + size_t elt = row * rowstride() + col * colstride() + TMP; + assert_lt(elt, matbuf_.size()); + return ptr() + elt; + } + + /** + * Like tmpvec, but it's allowed to ask for a pointer to one column after + * the final one. + */ + inline __m128i* tmpvecUnsafe(size_t row, size_t col) { + assert_lt(row, nvecrow_); + assert_leq(col, nveccol_); + size_t elt = row * rowstride() + col * colstride() + TMP; + assert_lt(elt, matbuf_.size()); + return ptr() + elt; + } + + /** + * Given a number of rows (nrow), a number of columns (ncol), and the + * number of words to fit inside a single __m128i vector, initialize the + * matrix buffer to accomodate the needed configuration of vectors. + */ + void init( + size_t nrow, + size_t ncol, + size_t wperv); + + /** + * Return the number of __m128i's you need to skip over to get from one + * cell to the cell one column over from it. + */ + inline size_t colstride() const { return colstride_; } + + /** + * Return the number of __m128i's you need to skip over to get from one + * cell to the cell one row down from it. + */ + inline size_t rowstride() const { return rowstride_; } + + /** + * Given a row, col and matrix (i.e. E, F or H), return the corresponding + * element. + */ + int eltSlow(size_t row, size_t col, size_t mat) const; + + /** + * Given a row, col and matrix (i.e. E, F or H), return the corresponding + * element. + */ + inline int elt(size_t row, size_t col, size_t mat) const { + assert(inited_); + assert_lt(row, nrow_); + assert_lt(col, ncol_); + assert_lt(mat, 3); + // Move to beginning of column/row + size_t rowelt = row / nvecrow_; + size_t rowvec = row % nvecrow_; + size_t eltvec = (col * colstride_) + (rowvec * rowstride_) + mat; + assert_lt(eltvec, matbuf_.size()); + if(wperv_ == 16) { + return (int)((uint8_t*)(matbuf_.ptr() + eltvec))[rowelt]; + } else { + assert_eq(8, wperv_); + return (int)((int16_t*)(matbuf_.ptr() + eltvec))[rowelt]; + } + } + + /** + * Return the element in the E matrix at element row, col. + */ + inline int eelt(size_t row, size_t col) const { + return elt(row, col, E); + } + + /** + * Return the element in the F matrix at element row, col. + */ + inline int felt(size_t row, size_t col) const { + return elt(row, col, F); + } + + /** + * Return the element in the H matrix at element row, col. + */ + inline int helt(size_t row, size_t col) const { + return elt(row, col, H); + } + + /** + * Return true iff the given cell has its reportedThru bit set. + */ + inline bool reportedThrough( + size_t row, // current row + size_t col) const // current column + { + return (masks_[row][col] & (1 << 0)) != 0; + } + + /** + * Set the given cell's reportedThru bit. + */ + inline void setReportedThrough( + size_t row, // current row + size_t col) // current column + { + masks_[row][col] |= (1 << 0); + } + + /** + * Return true iff the H mask has been set with a previous call to hMaskSet. + */ + bool isHMaskSet( + size_t row, // current row + size_t col) const; // current column + + /** + * Set the given cell's H mask. This is the mask of remaining legal ways to + * backtrack from the H cell at this coordinate. It's 5 bits long and has + * offset=2 into the 16-bit field. + */ + void hMaskSet( + size_t row, // current row + size_t col, // current column + int mask); + + /** + * Return true iff the E mask has been set with a previous call to eMaskSet. + */ + bool isEMaskSet( + size_t row, // current row + size_t col) const; // current column + + /** + * Set the given cell's E mask. This is the mask of remaining legal ways to + * backtrack from the E cell at this coordinate. It's 2 bits long and has + * offset=8 into the 16-bit field. + */ + void eMaskSet( + size_t row, // current row + size_t col, // current column + int mask); + + /** + * Return true iff the F mask has been set with a previous call to fMaskSet. + */ + bool isFMaskSet( + size_t row, // current row + size_t col) const; // current column + + /** + * Set the given cell's F mask. This is the mask of remaining legal ways to + * backtrack from the F cell at this coordinate. It's 2 bits long and has + * offset=11 into the 16-bit field. + */ + void fMaskSet( + size_t row, // current row + size_t col, // current column + int mask); + + /** + * Analyze a cell in the SSE-filled dynamic programming matrix. Determine & + * memorize ways that we can backtrack from the cell. If there is at least one + * way to backtrack, select one at random and return the selection. + * + * There are a few subtleties to keep in mind regarding which cells can be at + * the end of a backtrace. First of all: cells from which we can backtrack + * should not be at the end of a backtrace. But have to distinguish between + * cells whose masks eventually become 0 (we shouldn't end at those), from + * those whose masks were 0 all along (we can end at those). + */ + void analyzeCell( + size_t row, // current row + size_t col, // current column + size_t ct, // current cell type: E/F/H + int refc, + int readc, + int readq, + const Scoring& sc, // scoring scheme + int64_t offsetsc, // offset to add to each score + RandomSource& rand, // rand gen for choosing among equal options + bool& empty, // out: =true iff no way to backtrace + int& cur, // out: =type of transition + bool& branch, // out: =true iff we chose among >1 options + bool& canMoveThru, // out: =true iff ... + bool& reportedThru); // out: =true iff ... + + /** + * Initialize the matrix of masks and backtracking flags. + */ + void initMasks(); + + /** + * Return the number of rows in the dynamic programming matrix. + */ + size_t nrow() const { + return nrow_; + } + + /** + * Return the number of columns in the dynamic programming matrix. + */ + size_t ncol() const { + return ncol_; + } + + /** + * Prepare a row so we can use it to store masks. + */ + void resetRow(size_t i) { + assert(!reset_[i]); + masks_[i].resizeNoCopy(ncol_); + masks_[i].fillZero(); + reset_[i] = true; + } + + bool inited_; // initialized? + size_t nrow_; // # rows + size_t ncol_; // # columns + size_t nvecrow_; // # vector rows (<= nrow_) + size_t nveccol_; // # vector columns (<= ncol_) + size_t wperv_; // # words per vector + size_t vecshift_; // # bits to shift to divide by words per vec + size_t nvecPerCol_; // # vectors per column + size_t nvecPerCell_; // # vectors per matrix cell (4) + size_t colstride_; // # vectors b/t adjacent cells in same row + size_t rowstride_; // # vectors b/t adjacent cells in same col + EList_m128i matbuf_; // buffer for holding vectors + ELList masks_; // buffer for masks/backtracking flags + EList reset_; // true iff row in masks_ has been reset +}; + +/** + * All the data associated with the query profile and other data needed for SSE + * alignment of a query. + */ +struct SSEData { + SSEData(int cat = 0) : profbuf_(cat), mat_(cat) { } + EList_m128i profbuf_; // buffer for query profile & temp vecs + EList_m128i vecbuf_; // buffer for 2 column vectors (not using mat_) + size_t qprofStride_; // stride for query profile + size_t gbarStride_; // gap barrier for query profile + SSEMatrix mat_; // SSE matrix for holding all E, F, H vectors + size_t maxPen_; // biggest penalty of all + size_t maxBonus_; // biggest bonus of all + size_t lastIter_; // which 128-bit striped word has final row? + size_t lastWord_; // which word within 128-word has final row? + int bias_; // all scores shifted up by this for unsigned +}; + +/** + * Return true iff the H mask has been set with a previous call to hMaskSet. + */ +inline bool SSEMatrix::isHMaskSet( + size_t row, // current row + size_t col) const // current column +{ + return (masks_[row][col] & (1 << 1)) != 0; +} + +/** + * Set the given cell's H mask. This is the mask of remaining legal ways to + * backtrack from the H cell at this coordinate. It's 5 bits long and has + * offset=2 into the 16-bit field. + */ +inline void SSEMatrix::hMaskSet( + size_t row, // current row + size_t col, // current column + int mask) +{ + assert_lt(mask, 32); + masks_[row][col] &= ~(31 << 1); + masks_[row][col] |= (1 << 1 | mask << 2); +} + +/** + * Return true iff the E mask has been set with a previous call to eMaskSet. + */ +inline bool SSEMatrix::isEMaskSet( + size_t row, // current row + size_t col) const // current column +{ + return (masks_[row][col] & (1 << 7)) != 0; +} + +/** + * Set the given cell's E mask. This is the mask of remaining legal ways to + * backtrack from the E cell at this coordinate. It's 2 bits long and has + * offset=8 into the 16-bit field. + */ +inline void SSEMatrix::eMaskSet( + size_t row, // current row + size_t col, // current column + int mask) +{ + assert_lt(mask, 4); + masks_[row][col] &= ~(7 << 7); + masks_[row][col] |= (1 << 7 | mask << 8); +} + +/** + * Return true iff the F mask has been set with a previous call to fMaskSet. + */ +inline bool SSEMatrix::isFMaskSet( + size_t row, // current row + size_t col) const // current column +{ + return (masks_[row][col] & (1 << 10)) != 0; +} + +/** + * Set the given cell's F mask. This is the mask of remaining legal ways to + * backtrack from the F cell at this coordinate. It's 2 bits long and has + * offset=11 into the 16-bit field. + */ +inline void SSEMatrix::fMaskSet( + size_t row, // current row + size_t col, // current column + int mask) +{ + assert_lt(mask, 4); + masks_[row][col] &= ~(7 << 10); + masks_[row][col] |= (1 << 10 | mask << 11); +} + +#define ROWSTRIDE_2COL 4 +#define ROWSTRIDE 4 + +#endif /*ndef ALIGNER_SWSSE_H_*/ diff --git a/aligner_swsse_ee_i16.cpp b/aligner_swsse_ee_i16.cpp new file mode 100644 index 0000000..4a28646 --- /dev/null +++ b/aligner_swsse_ee_i16.cpp @@ -0,0 +1,1911 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/** + * aligner_sw_sse.cpp + * + * Versions of key alignment functions that use vector instructions to + * accelerate dynamic programming. Based chiefly on the striped Smith-Waterman + * paper and implementation by Michael Farrar. See: + * + * Farrar M. Striped Smith-Waterman speeds database searches six times over + * other SIMD implementations. Bioinformatics. 2007 Jan 15;23(2):156-61. + * http://sites.google.com/site/farrarmichael/smith-waterman + * + * While the paper describes an implementation of Smith-Waterman, we extend it + * do end-to-end read alignment as well as local alignment. The change + * required for this is minor: we simply let vmax be the maximum element in the + * score domain rather than the minimum. + * + * The vectorized dynamic programming implementation lacks some features that + * make it hard to adapt to solving the entire dynamic-programming alignment + * problem. For instance: + * + * - It doesn't respect gap barriers on either end of the read + * - It just gives a maximum; not enough information to backtrace without + * redoing some alignment + * - It's a little difficult to handle st_ and en_, especially st_. + * - The query profile mechanism makes handling of ambiguous reference bases a + * little tricky (16 cols in query profile lookup table instead of 5) + * + * Given the drawbacks, it is tempting to use SSE dynamic programming as a + * filter rather than as an aligner per se. Here are a few ideas for how it + * can be extended to handle more of the alignment problem: + * + * - Save calculated scores to a big array as we go. We return to this array + * to find and backtrace from good solutions. + */ + +#include +#include "aligner_sw.h" + +static const size_t NBYTES_PER_REG = 16; +static const size_t NWORDS_PER_REG = 8; +static const size_t NBITS_PER_WORD = 16; +static const size_t NBYTES_PER_WORD = 2; + +// In 16-bit end-to-end mode, we have the option of using signed saturated +// arithmetic. Because we have signed arithmetic, there's no need to add/subtract +// bias when building an applying the query profile. The lowest value we can +// use is 0x8000, and the greatest is 0x7fff. + +typedef int16_t TCScore; + +/** + * Build query profile look up tables for the read. The query profile look + * up table is organized as a 1D array indexed by [i][j] where i is the + * reference character in the current DP column (0=A, 1=C, etc), and j is + * the segment of the query we're currently working on. + */ +void SwAligner::buildQueryProfileEnd2EndSseI16(bool fw) { + bool& done = fw ? sseI16fwBuilt_ : sseI16rcBuilt_; + if(done) { + return; + } + done = true; + const BTDnaString* rd = fw ? rdfw_ : rdrc_; + const BTString* qu = fw ? qufw_ : qurc_; + // daehwan - allows to align a portion of a read, not the whole + // const size_t len = rd->length(); + const size_t len = dpRows(); + const size_t seglen = (len + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; + // How many __m128i's are needed + size_t n128s = + 64 + // slack bytes, for alignment? + (seglen * ALPHA_SIZE) // query profile data + * 2; // & gap barrier data + assert_gt(n128s, 0); + SSEData& d = fw ? sseI16fw_ : sseI16rc_; + d.profbuf_.resizeNoCopy(n128s); + assert(!d.profbuf_.empty()); + d.maxPen_ = d.maxBonus_ = 0; + d.lastIter_ = d.lastWord_ = 0; + d.qprofStride_ = d.gbarStride_ = 2; + d.bias_ = 0; // no bias when words are signed + // For each reference character A, C, G, T, N ... + for(size_t refc = 0; refc < ALPHA_SIZE; refc++) { + // For each segment ... + for(size_t i = 0; i < seglen; i++) { + size_t j = i; + int16_t *qprofWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2)); + int16_t *gbarWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2) + 1); + // For each sub-word (byte) ... + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + int sc = 0; + *gbarWords = 0; + if(j < len) { + int readc = (*rd)[j]; + int readq = (*qu)[j]; + sc = sc_->score(readc, (int)(1 << refc), readq - 33); + size_t j_from_end = len - j - 1; + if(j < (size_t)sc_->gapbar || + j_from_end < (size_t)sc_->gapbar) + { + // Inside the gap barrier + *gbarWords = 0x8000; // add this twice + } + } + if(refc == 0 && j == len-1) { + // Remember which 128-bit word and which smaller word has + // the final row + d.lastIter_ = i; + d.lastWord_ = k; + } + if(sc < 0) { + if((size_t)(-sc) > d.maxPen_) { + d.maxPen_ = (size_t)(-sc); + } + } else { + if((size_t)sc > d.maxBonus_) { + d.maxBonus_ = (size_t)sc; + } + } + *qprofWords = (int16_t)sc; + gbarWords++; + qprofWords++; + j += seglen; // update offset into query + } + } + } +} + +#ifndef NDEBUG +/** + * Return true iff the cell has sane E/F/H values w/r/t its predecessors. + */ +static bool cellOkEnd2EndI16( + SSEData& d, + size_t row, + size_t col, + int refc, + int readc, + int readq, + const Scoring& sc) // scoring scheme +{ + TCScore floorsc = 0x8000; + TCScore ceilsc = MAX_I64; + TAlScore offsetsc = -0x7fff; + TAlScore sc_h_cur = (TAlScore)d.mat_.helt(row, col); + TAlScore sc_e_cur = (TAlScore)d.mat_.eelt(row, col); + TAlScore sc_f_cur = (TAlScore)d.mat_.felt(row, col); + if(sc_h_cur > floorsc) { + sc_h_cur += offsetsc; + } + if(sc_e_cur > floorsc) { + sc_e_cur += offsetsc; + } + if(sc_f_cur > floorsc) { + sc_f_cur += offsetsc; + } + bool gapsAllowed = true; + size_t rowFromEnd = d.mat_.nrow() - row - 1; + if(row < (size_t)sc.gapbar || rowFromEnd < (size_t)sc.gapbar) { + gapsAllowed = false; + } + bool e_left_trans = false, h_left_trans = false; + bool f_up_trans = false, h_up_trans = false; + bool h_diag_trans = false; + if(gapsAllowed) { + TAlScore sc_h_left = floorsc; + TAlScore sc_e_left = floorsc; + TAlScore sc_h_up = floorsc; + TAlScore sc_f_up = floorsc; + if(col > 0 && sc_e_cur > floorsc && sc_e_cur <= ceilsc) { + sc_h_left = d.mat_.helt(row, col-1) + offsetsc; + sc_e_left = d.mat_.eelt(row, col-1) + offsetsc; + e_left_trans = (sc_e_left > floorsc && sc_e_cur == sc_e_left - sc.readGapExtend()); + h_left_trans = (sc_h_left > floorsc && sc_e_cur == sc_h_left - sc.readGapOpen()); + assert(e_left_trans || h_left_trans); + } + if(row > 0 && sc_f_cur > floorsc && sc_f_cur <= ceilsc) { + sc_h_up = d.mat_.helt(row-1, col) + offsetsc; + sc_f_up = d.mat_.felt(row-1, col) + offsetsc; + f_up_trans = (sc_f_up > floorsc && sc_f_cur == sc_f_up - sc.refGapExtend()); + h_up_trans = (sc_h_up > floorsc && sc_f_cur == sc_h_up - sc.refGapOpen()); + assert(f_up_trans || h_up_trans); + } + } else { + assert_geq(floorsc, sc_e_cur); + assert_geq(floorsc, sc_f_cur); + } + if(col > 0 && row > 0 && sc_h_cur > floorsc && sc_h_cur <= ceilsc) { + TAlScore sc_h_upleft = d.mat_.helt(row-1, col-1) + offsetsc; + TAlScore sc_diag = sc.score(readc, (int)refc, readq - 33); + h_diag_trans = sc_h_cur == sc_h_upleft + sc_diag; + } + assert( + sc_h_cur <= floorsc || + e_left_trans || + h_left_trans || + f_up_trans || + h_up_trans || + h_diag_trans || + sc_h_cur > ceilsc || + row == 0 || + col == 0); + return true; +} +#endif /*ndef NDEBUG*/ + +#ifdef NDEBUG + +#define assert_all_eq0(x) +#define assert_all_gt(x, y) +#define assert_all_gt_lo(x) +#define assert_all_lt(x, y) +#define assert_all_lt_hi(x) + +#else + +#define assert_all_eq0(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpeq_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt(x, y) { \ + __m128i tmp = _mm_cmpgt_epi16(x, y); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt_lo(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpgt_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt(x, y) { \ + __m128i tmp = _mm_cmplt_epi16(x, y); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_leq(x, y) { \ + __m128i tmp = _mm_cmpgt_epi16(x, y); \ + assert_eq(0x0000, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt_hi(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_cmpeq_epi16(z, z); \ + z = _mm_srli_epi16(z, 1); \ + tmp = _mm_cmplt_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} +#endif + +/** + * Aligns by filling a dynamic programming matrix with the SSE-accelerated, + * banded DP approach of Farrar. As it goes, it determines which cells we + * might backtrace from and tallies the best (highest-scoring) N backtrace + * candidate cells per diagonal. Also returns the alignment score of the best + * alignment in the matrix. + * + * This routine does *not* maintain a matrix holding the entire matrix worth of + * scores, nor does it maintain any other dense O(mn) data structure, as this + * would quickly exhaust memory for queries longer than about 10,000 kb. + * Instead, in the fill stage it maintains two columns worth of scores at a + * time (current/previous, or right/left) - these take O(m) space. When + * finished with the current column, it determines which cells from the + * previous column, if any, are candidates we might backtrace from to find a + * full alignment. A candidate cell has a score that rises above the threshold + * and isn't improved upon by a match in the next column. The best N + * candidates per diagonal are stored in a O(m + n) data structure. + */ +TAlScore SwAligner::alignGatherEE16(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + if(!debug) met.dp++; + buildQueryProfileEnd2EndSseI16(fw_); + assert(!d.profbuf_.empty()); + + assert_eq(0, d.maxBonus_); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + // Now set up the score vectors. We just need two columns worth, which + // we'll call "left" and "right". + d.vecbuf_.resize(4 * 2 * iter); + d.vecbuf_.zero(); + __m128i *vbuf_l = d.vecbuf_.ptr(); + __m128i *vbuf_r = d.vecbuf_.ptr() + (4 * iter); + + // This is the data structure that holds candidate cells per diagonal. + const size_t ndiags = rff_ - rfi_ + dpRows() - 1; + if(!debug) { + btdiag_.init(ndiags, 2); + } + + // Data structure that holds checkpointed anti-diagonals + TAlScore perfectScore = sc_->perfectScore(dpRows()); + bool checkpoint = true; + bool cpdebug = false; +#ifndef NDEBUG + cpdebug = dpRows() < 1000; +#endif + cper_.init( + dpRows(), // # rows + rff_ - rfi_, // # columns + cperPerPow2_, // checkpoint every 1 << perpow2 diags (& next) + perfectScore, // perfect score (for sanity checks) + false, // matrix cells have 8-bit scores? + cperTri_, // triangular mini-fills? + false, // alignment is local? + cpdebug); // save all cells for debugging? + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i vhilsw = _mm_setzero_si128(); + __m128i vlolsw = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); + __m128i vhd = _mm_setzero_si128(); + __m128i vhdtmp = _mm_setzero_si128(); + __m128i vtmp = _mm_setzero_si128(); + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_I16); + rfgapo = _mm_insert_epi16(rfgapo, sc_->refGapOpen(), 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_I16); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + rfgape = _mm_insert_epi16(rfgape, sc_->refGapExtend(), 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_I16); + rdgapo = _mm_insert_epi16(rdgapo, sc_->readGapOpen(), 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_I16); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + rdgape = _mm_insert_epi16(rdgape, sc_->readGapExtend(), 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + // Set all elts to 0x8000 (min value for signed 16-bit) + vlo = _mm_cmpeq_epi16(vlo, vlo); // all elts = 0xffff + vlo = _mm_slli_epi16(vlo, NBITS_PER_WORD-1); // all elts = 0x8000 + + // Set all elts to 0x7fff (max value for signed 16-bit) + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vhi = _mm_srli_epi16(vhi, 1); // all elts = 0x7fff + + // vlolsw: topmost (least sig) word set to 0x8000, all other words=0 + vlolsw = _mm_shuffle_epi32(vlo, 0); + vlolsw = _mm_srli_si128(vlolsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // vhilsw: topmost (least sig) word set to 0x7fff, all other words=0 + vhilsw = _mm_shuffle_epi32(vhi, 0); + vhilsw = _mm_srli_si128(vhilsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + const size_t colstride = ROWSTRIDE_2COL * iter; + + // Initialize the H and E vectors in the first matrix column + __m128i *pvELeft = vbuf_l + 0; __m128i *pvERight = vbuf_r + 0; + /* __m128i *pvFLeft = vbuf_l + 1; */ __m128i *pvFRight = vbuf_r + 1; + __m128i *pvHLeft = vbuf_l + 2; __m128i *pvHRight = vbuf_r + 2; + + // Maximum score in final row + bool found = false; + TCScore lrmax = MIN_I16; + + for(size_t i = 0; i < iter; i++) { + _mm_store_si128(pvERight, vlo); pvERight += ROWSTRIDE_2COL; + // Could initialize Hs to high or low. If high, cells in the lower + // triangle will have somewhat more legitiate scores, but still won't + // be exhaustively scored. + _mm_store_si128(pvHRight, vlo); pvHRight += ROWSTRIDE_2COL; + } + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + // Swap left and right; vbuf_l is the vector on the left, which we + // generally load from, and vbuf_r is the vector on the right, which we + // generally store to. + swap(vbuf_l, vbuf_r); + pvELeft = vbuf_l + 0; pvERight = vbuf_r + 0; + /* pvFLeft = vbuf_l + 1; */ pvFRight = vbuf_r + 1; + pvHLeft = vbuf_l + 2; pvHRight = vbuf_r + 2; + + // Fetch the appropriate query profile. Note that elements of rf_ must + // be numbers, not masks. + const int refc = (int)rf_[i]; + + // Fetch the appropriate query profile + size_t off = (size_t)firsts5[refc] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Set all cells to low value + vf = _mm_cmpeq_epi16(vf, vf); + vf = _mm_slli_epi16(vf, NBITS_PER_WORD-1); + vf = _mm_or_si128(vf, vlolsw); + + // Load H vector from the final row of the previous column + vh = _mm_load_si128(pvHLeft + colstride - ROWSTRIDE_2COL); + // Shift 2 bytes down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + // Fill topmost (least sig) cell with high value + vh = _mm_or_si128(vh, vhilsw); + + // For each character in the reference text: + size_t j; + for(j = 0; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELeft); + vhd = _mm_load_si128(pvHLeft); + assert_all_lt(ve, vhi); + pvELeft += ROWSTRIDE_2COL; + + // Store cells in F, calculated previously + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epi16(vh, pvScore[0]); + + // Update H, factoring in E and F + vh = _mm_max_epi16(vh, vf); + + // Update vE value + vhdtmp = vhd; + vhd = _mm_subs_epi16(vhd, rdgapo); + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epi16(ve, rdgape); + ve = _mm_max_epi16(ve, vhd); + vh = _mm_max_epi16(vh, ve); + + // Save the new vH values + _mm_store_si128(pvHRight, vh); + pvHRight += ROWSTRIDE_2COL; + vtmp = vh; + assert_all_lt(ve, vhi); + + // Load the next h value + vh = vhdtmp; + pvHLeft += ROWSTRIDE_2COL; + + // Save E values + _mm_store_si128(pvERight, ve); + pvERight += ROWSTRIDE_2COL; + + // Update vf value + vtmp = _mm_subs_epi16(vtmp, rfgapo); + vf = _mm_subs_epi16(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epi16(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFRight -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFRight); + + pvHRight -= colstride; // reset to start of column + vh = _mm_load_si128(pvHRight); + + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0x0000) { + // Store this vf + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Update vh w/r/t new vf + vh = _mm_max_epi16(vh, vf); + + // Save vH values + _mm_store_si128(pvHRight, vh); + pvHRight += ROWSTRIDE_2COL; + + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFRight -= colstride; + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + pvHRight -= colstride; + vh = _mm_load_si128(pvHRight); // load next vh ASAP + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + } else { + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + vh = _mm_load_si128(pvHRight); // load next vh ASAP + } + + // Update F with another gap extension + vf = _mm_subs_epi16(vf, rfgape); + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + + + // Check in the last row for the maximum so far + __m128i *vtmp = vbuf_r + 2 /* H */ + (d.lastIter_ * ROWSTRIDE_2COL); + // Note: we may not want to extract from the final row + TCScore lr = ((TCScore*)(vtmp))[d.lastWord_]; + found = true; + if(lr > lrmax) { + lrmax = lr; + } + + // Now we'd like to know whether the bottommost element of the right + // column is a candidate we might backtrace from. First question is: + // did it exceed the minimum score threshold? + TAlScore score = (TAlScore)(lr - 0x7fff); + if(lr == MIN_I16) { + score = MIN_I64; + } + if(!debug && score >= minsc_) { + DpBtCandidate cand(dpRows() - 1, i - rfi_, score); + btdiag_.add(i - rfi_, cand); + } + + // Save some elements to checkpoints + if(checkpoint) { + + __m128i *pvE = vbuf_r + 0; + __m128i *pvF = vbuf_r + 1; + __m128i *pvH = vbuf_r + 2; + size_t coli = i - rfi_; + if(coli < cper_.locol_) cper_.locol_ = coli; + if(coli > cper_.hicol_) cper_.hicol_ = coli; + + if(cperTri_) { + size_t rc_mod = coli & cper_.lomask_; + assert_lt(rc_mod, cper_.per_); + int64_t row = -(int64_t)rc_mod-1; + int64_t row_mod = row; + int64_t row_div = 0; + size_t idx = coli >> cper_.perpow2_; + size_t idxrow = idx * cper_.nrow_; + assert_eq(4, ROWSTRIDE_2COL); + bool done = false; + while(true) { + row += (cper_.per_ - 2); + row_mod += (cper_.per_ - 2); + for(size_t j = 0; j < 2; j++) { + row++; + row_mod++; + if(row >= 0 && (size_t)row < cper_.nrow_) { + // Update row divided by iter_ and mod iter_ + while(row_mod >= (int64_t)iter) { + row_mod -= (int64_t)iter; + row_div++; + } + size_t delt = idxrow + row; + size_t vecoff = (row_mod << 5) + row_div; + assert_lt(row_div, 8); + int16_t h_sc = ((int16_t*)pvH)[vecoff]; + int16_t e_sc = ((int16_t*)pvE)[vecoff]; + int16_t f_sc = ((int16_t*)pvF)[vecoff]; + if(h_sc != MIN_I16) h_sc -= 0x7fff; + if(e_sc != MIN_I16) e_sc -= 0x7fff; + if(f_sc != MIN_I16) f_sc -= 0x7fff; + assert_leq(h_sc, cper_.perf_); + assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad *qdiags = ((j == 0) ? cper_.qdiag1s_.ptr() : cper_.qdiag2s_.ptr()); + qdiags[delt].sc[0] = h_sc; + qdiags[delt].sc[1] = e_sc; + qdiags[delt].sc[2] = f_sc; + } // if(row >= 0 && row < nrow_) + else if(row >= 0 && (size_t)row >= cper_.nrow_) { + done = true; + break; + } + } // end of loop over anti-diags + if(done) { + break; + } + idx++; + idxrow += cper_.nrow_; + } + } else { + // If this is the first column, take this opportunity to + // pre-calculate the coordinates of the elements we're going to + // checkpoint. + if(coli == 0) { + size_t cpi = cper_.per_-1; + size_t cpimod = cper_.per_-1; + size_t cpidiv = 0; + cper_.commitMap_.clear(); + while(cpi < cper_.nrow_) { + while(cpimod >= iter) { + cpimod -= iter; + cpidiv++; + } + size_t vecoff = (cpimod << 5) + cpidiv; + cper_.commitMap_.push_back(vecoff); + cpi += cper_.per_; + cpimod += cper_.per_; + } + } + // Save all the rows + size_t rowoff = 0; + size_t sz = cper_.commitMap_.size(); + for(size_t i = 0; i < sz; i++, rowoff += cper_.ncol_) { + size_t vecoff = cper_.commitMap_[i]; + int16_t h_sc = ((int16_t*)pvH)[vecoff]; + int16_t e_sc = ((int16_t*)pvE)[vecoff]; + int16_t f_sc = ((int16_t*)pvF)[vecoff]; + if(h_sc != MIN_I16) h_sc -= 0x7fff; + if(e_sc != MIN_I16) e_sc -= 0x7fff; + if(f_sc != MIN_I16) f_sc -= 0x7fff; + assert_leq(h_sc, cper_.perf_); + assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad& dst = cper_.qrows_[rowoff + coli]; + dst.sc[0] = h_sc; + dst.sc[1] = e_sc; + dst.sc[2] = f_sc; + } + // Is this a column we'd like to checkpoint? + if((coli & cper_.lomask_) == cper_.lomask_) { + // Save the column using memcpys + assert_gt(coli, 0); + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = (coli >> cper_.perpow2_) * wordspercol; + __m128i *dst = cper_.qcols_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + if(cper_.debug_) { + // Save the column using memcpys + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = coli * wordspercol; + __m128i *dst = cper_.qcolsD_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + } + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + flag = 0; + + // Did we find a solution? + TAlScore score = MIN_I64; + if(!found) { + flag = -1; // no + if(!debug) met.dpfail++; + return MIN_I64; + } else { + score = (TAlScore)(lrmax - 0x7fff); + if(score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return score; + } + } + + // Could we have saturated? + if(lrmax == MIN_I16) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Now take all the backtrace candidates in the btdaig_ structure and + // dump them into the btncand_ array. They'll be sorted later. + if(!debug) { + btdiag_.dump(btncand_); + assert(!btncand_.empty()); + } + + // Return largest score + if(!debug) met.dpsucc++; + return score; +} + +/** + * Solve the current alignment problem using SSE instructions that operate on 8 + * signed 16-bit values packed into a single 128-bit register. + */ +TAlScore SwAligner::alignNucleotidesEnd2EndSseI16(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + if(!debug) met.dp++; + buildQueryProfileEnd2EndSseI16(fw_); + assert(!d.profbuf_.empty()); + + assert_eq(0, d.maxBonus_); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i vhilsw = _mm_setzero_si128(); + __m128i vlolsw = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); +#if 0 + __m128i vhd = _mm_setzero_si128(); + __m128i vhdtmp = _mm_setzero_si128(); +#endif + __m128i vtmp = _mm_setzero_si128(); + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_I16); + rfgapo = _mm_insert_epi16(rfgapo, sc_->refGapOpen(), 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_I16); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + rfgape = _mm_insert_epi16(rfgape, sc_->refGapExtend(), 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_I16); + rdgapo = _mm_insert_epi16(rdgapo, sc_->readGapOpen(), 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_I16); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + rdgape = _mm_insert_epi16(rdgape, sc_->readGapExtend(), 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + // Set all elts to 0x8000 (min value for signed 16-bit) + vlo = _mm_cmpeq_epi16(vlo, vlo); // all elts = 0xffff + vlo = _mm_slli_epi16(vlo, NBITS_PER_WORD-1); // all elts = 0x8000 + + // Set all elts to 0x7fff (max value for signed 16-bit) + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vhi = _mm_srli_epi16(vhi, 1); // all elts = 0x7fff + + // vlolsw: topmost (least sig) word set to 0x8000, all other words=0 + vlolsw = _mm_shuffle_epi32(vlo, 0); + vlolsw = _mm_srli_si128(vlolsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // vhilsw: topmost (least sig) word set to 0x7fff, all other words=0 + vhilsw = _mm_shuffle_epi32(vhi, 0); + vhilsw = _mm_srli_si128(vhilsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + d.mat_.init(dpRows(), rff_ - rfi_, NWORDS_PER_REG); + const size_t colstride = d.mat_.colstride(); + assert_eq(ROWSTRIDE, colstride / iter); + + // Initialize the H and E vectors in the first matrix column + __m128i *pvHTmp = d.mat_.tmpvec(0, 0); + __m128i *pvETmp = d.mat_.evec(0, 0); + + // Maximum score in final row + bool found = false; + TCScore lrmax = MIN_I16; + + for(size_t i = 0; i < iter; i++) { + _mm_store_si128(pvETmp, vlo); + // Could initialize Hs to high or low. If high, cells in the lower + // triangle will have somewhat more legitiate scores, but still won't + // be exhaustively scored. + _mm_store_si128(pvHTmp, vlo); + pvETmp += ROWSTRIDE; + pvHTmp += ROWSTRIDE; + } + // These are swapped just before the innermost loop + __m128i *pvHStore = d.mat_.hvec(0, 0); + __m128i *pvHLoad = d.mat_.tmpvec(0, 0); + __m128i *pvELoad = d.mat_.evec(0, 0); + __m128i *pvEStore = d.mat_.evecUnsafe(0, 1); + __m128i *pvFStore = d.mat_.fvec(0, 0); + __m128i *pvFTmp = NULL; + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + colstop_ = rff_ - 1; + lastsolcol_ = 0; + + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert(pvFStore == d.mat_.fvec(0, i - rfi_)); + assert(pvHStore == d.mat_.hvec(0, i - rfi_)); + + // Fetch the appropriate query profile. Note that elements of rf_ must + // be numbers, not masks. + const int refc = (int)rf_[i]; + size_t off = (size_t)firsts5[refc] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Set all cells to low value + vf = _mm_cmpeq_epi16(vf, vf); + vf = _mm_slli_epi16(vf, NBITS_PER_WORD-1); + vf = _mm_or_si128(vf, vlolsw); + + // Load H vector from the final row of the previous column + vh = _mm_load_si128(pvHLoad + colstride - ROWSTRIDE); + // Shift 2 bytes down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + // Fill topmost (least sig) cell with high value + vh = _mm_or_si128(vh, vhilsw); + + // For each character in the reference text: + size_t j; + for(j = 0; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELoad); +#if 0 + vhd = _mm_load_si128(pvHLoad); +#endif + assert_all_lt(ve, vhi); + pvELoad += ROWSTRIDE; + + // Store cells in F, calculated previously + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epi16(vh, pvScore[0]); + + // Update H, factoring in E and F + vh = _mm_max_epi16(vh, ve); + vh = _mm_max_epi16(vh, vf); + + // Save the new vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update vE value + vtmp = vh; +#if 0 + vhdtmp = vhd; + vhd = _mm_subs_epi16(vhd, rdgapo); + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epi16(ve, rdgape); + ve = _mm_max_epi16(ve, vhd); +#else + vh = _mm_subs_epi16(vh, rdgapo); + vh = _mm_adds_epi16(vh, pvScore[1]); // veto some read gap opens + vh = _mm_adds_epi16(vh, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epi16(ve, rdgape); + ve = _mm_max_epi16(ve, vh); +#endif + assert_all_lt(ve, vhi); + + // Load the next h value +#if 0 + vh = vhdtmp; +#else + vh = _mm_load_si128(pvHLoad); +#endif + pvHLoad += ROWSTRIDE; + + // Save E values + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + + // Update vf value + vtmp = _mm_subs_epi16(vtmp, rfgapo); + vf = _mm_subs_epi16(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epi16(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFTmp = pvFStore; + pvFStore -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFStore); + + pvHStore -= colstride; // reset to start of column + vh = _mm_load_si128(pvHStore); + +#if 0 +#else + pvEStore -= colstride; // reset to start of column + ve = _mm_load_si128(pvEStore); +#endif + + pvHLoad = pvHStore; // new pvHLoad = pvHStore + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0x0000) { + // Store this vf + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Update vh w/r/t new vf + vh = _mm_max_epi16(vh, vf); + + // Save vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update E in case it can be improved using our new vh +#if 0 +#else + vh = _mm_subs_epi16(vh, rdgapo); + vh = _mm_adds_epi16(vh, *pvScore); // veto some read gap opens + vh = _mm_adds_epi16(vh, *pvScore); // veto some read gap opens + ve = _mm_max_epi16(ve, vh); + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; +#endif + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFStore -= colstride; + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + pvHStore -= colstride; + vh = _mm_load_si128(pvHStore); // load next vh ASAP +#if 0 +#else + pvEStore -= colstride; + ve = _mm_load_si128(pvEStore); // load next ve ASAP +#endif + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + } else { + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + vh = _mm_load_si128(pvHStore); // load next vh ASAP +#if 0 +#else + ve = _mm_load_si128(pvEStore); // load next vh ASAP +#endif + } + + // Update F with another gap extension + vf = _mm_subs_epi16(vf, rfgape); + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + +#ifndef NDEBUG + if((rand() & 15) == 0) { + // This is a work-intensive sanity check; each time we finish filling + // a column, we check that each H, E, and F is sensible. + for(size_t k = 0; k < dpRows(); k++) { + assert(cellOkEnd2EndI16( + d, + k, // row + i - rfi_, // col + refc, // reference mask + (int)(*rd_)[rdi_+k], // read char + (int)(*qu_)[rdi_+k], // read quality + *sc_)); // scoring scheme + } + } +#endif + + __m128i *vtmp = d.mat_.hvec(d.lastIter_, i-rfi_); + // Note: we may not want to extract from the final row + TCScore lr = ((TCScore*)(vtmp))[d.lastWord_]; + found = true; + if(lr > lrmax) { + lrmax = lr; + } + + // pvELoad and pvHLoad are already where they need to be + + // Adjust the load and store vectors here. + pvHStore = pvHLoad + colstride; + pvEStore = pvELoad + colstride; + pvFStore = pvFTmp; + } + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + flag = 0; + + // Did we find a solution? + TAlScore score = MIN_I64; + if(!found) { + flag = -1; // no + if(!debug) met.dpfail++; + return MIN_I64; + } else { + score = (TAlScore)(lrmax - 0x7fff); + if(score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return score; + } + } + + // Could we have saturated? + if(lrmax == MIN_I16) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Return largest score + if(!debug) met.dpsucc++; + return score; +} + +/** + * Given a filled-in DP table, populate the btncand_ list with candidate cells + * that might be at the ends of valid alignments. No need to do this unless + * the maximum score returned by the align*() func is >= the minimum. + * + * Only cells that are exhaustively scored are candidates. Those are the + * cells inside the shape made of o's in this: + * + * |-maxgaps-| + * ********************************* - + * ******************************** | + * ******************************* | + * ****************************** | + * ***************************** | + * **************************** read len + * *************************** | + * ************************** | + * ************************* | + * ************************ | + * ***********oooooooooooo - + * |-maxgaps-| + * |-readlen-| + * |-------skip--------| + * + * And it's possible for the shape to be truncated on the left and right sides. + * + * + */ +bool SwAligner::gatherCellsNucleotidesEnd2EndSseI16(TAlScore best) { + // What's the minimum number of rows that can possibly be spanned by an + // alignment that meets the minimum score requirement? + assert(sse16succ_); + const size_t ncol = rff_ - rfi_; + const size_t nrow = dpRows(); + assert_gt(nrow, 0); + btncand_.clear(); + btncanddone_.clear(); + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + assert(!d.profbuf_.empty()); + const size_t colstride = d.mat_.colstride(); + ASSERT_ONLY(bool sawbest = false); + __m128i *pvH = d.mat_.hvec(d.lastIter_, 0); + for(size_t j = 0; j < ncol; j++) { + TAlScore sc = (TAlScore)(((TCScore*)pvH)[d.lastWord_] - 0x7fff); + assert_leq(sc, best); + ASSERT_ONLY(sawbest = (sawbest || sc == best)); + if(sc >= minsc_) { + // Yes, this is legit + met.gathsol++; + btncand_.expand(); + btncand_.back().init(nrow-1, j, sc); + } + pvH += colstride; + } + assert(sawbest); + if(!btncand_.empty()) { + d.mat_.initMasks(); + } + return !btncand_.empty(); +} + +#define MOVE_VEC_PTR_UP(vec, rowvec, rowelt) { \ + if(rowvec == 0) { \ + rowvec += d.mat_.nvecrow_; \ + vec += d.mat_.colstride_; \ + rowelt--; \ + } \ + rowvec--; \ + vec -= ROWSTRIDE; \ +} + +#define MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt) { vec -= d.mat_.colstride_; } + +#define MOVE_VEC_PTR_UPLEFT(vec, rowvec, rowelt) { \ + MOVE_VEC_PTR_UP(vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt); \ +} + +#define MOVE_ALL_LEFT() { \ + MOVE_VEC_PTR_LEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_LEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UP() { \ + MOVE_VEC_PTR_UP(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UP(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UP(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UPLEFT() { \ + MOVE_VEC_PTR_UPLEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UPLEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UPLEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UPLEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define NEW_ROW_COL(row, col) { \ + rowelt = row / d.mat_.nvecrow_; \ + rowvec = row % d.mat_.nvecrow_; \ + eltvec = (col * d.mat_.colstride_) + (rowvec * ROWSTRIDE); \ + cur_vec = d.mat_.matbuf_.ptr() + eltvec; \ + left_vec = cur_vec; \ + left_rowelt = rowelt; \ + left_rowvec = rowvec; \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + up_vec = cur_vec; \ + up_rowelt = rowelt; \ + up_rowvec = rowvec; \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + upleft_vec = up_vec; \ + upleft_rowelt = up_rowelt; \ + upleft_rowvec = up_rowvec; \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +/** + * Given the dynamic programming table and a cell, trace backwards from the + * cell and install the edits and score/penalty in the appropriate fields + * of res. The RandomSource is used to break ties among equally good ways + * of tracing back. + * + * Whenever we enter a cell, we check whether the read/ref coordinates of + * that cell correspond to a cell we traversed constructing a previous + * alignment. If so, we backtrack to the last decision point, mask out the + * path that led to the previously observed cell, and continue along a + * different path; or, if there are no more paths to try, we give up. + * + * If an alignment is found, 'off' is set to the alignment's upstream-most + * reference character's offset into the chromosome and true is returned. + * Otherwise, false is returned. + */ +bool SwAligner::backtraceNucleotidesEnd2EndSseI16( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this row + size_t col, // start in this column + RandomSource& rnd) // random gen, to choose among equal paths +{ + assert_lt(row, dpRows()); + assert_lt(col, (size_t)(rff_ - rfi_)); + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + met.bt++; + assert(!d.profbuf_.empty()); + assert_lt(row, rd_->length()); + btnstack_.clear(); // empty the backtrack stack + btcells_.clear(); // empty the cells-so-far list + AlnScore score; score.score_ = 0; + score.gaps_ = score.ns_ = 0; + size_t origCol = col; + size_t gaps = 0, readGaps = 0, refGaps = 0; + res.alres.reset(); + EList& ned = res.alres.ned(); + assert(ned.empty()); + assert_gt(dpRows(), row); + size_t trimEnd = dpRows() - row - 1; + size_t trimBeg = 0; + size_t ct = SSEMatrix::H; // cell type + // Row and col in terms of where they fall in the SSE vector matrix + size_t rowelt, rowvec, eltvec; + size_t left_rowelt, up_rowelt, upleft_rowelt; + size_t left_rowvec, up_rowvec, upleft_rowvec; + __m128i *cur_vec, *left_vec, *up_vec, *upleft_vec; + NEW_ROW_COL(row, col); + while((int)row >= 0) { + met.btcell++; + nbts++; + int readc = (*rd_)[rdi_ + row]; + int refm = (int)rf_[rfi_ + col]; + int readq = (*qu_)[row]; + assert_leq(col, origCol); + // Get score in this cell + bool empty = false, reportedThru, canMoveThru, branch = false; + int cur = SSEMatrix::H; + if(!d.mat_.reset_[row]) { + d.mat_.resetRow(row); + } + reportedThru = d.mat_.reportedThrough(row, col); + canMoveThru = true; + if(reportedThru) { + canMoveThru = false; + } else { + empty = false; + if(row > 0) { + assert_gt(row, 0); + size_t rowFromEnd = d.mat_.nrow() - row - 1; + bool gapsAllowed = true; + if(row < (size_t)sc_->gapbar || + rowFromEnd < (size_t)sc_->gapbar) + { + gapsAllowed = false; + } + const TAlScore floorsc = MIN_I64; + const int offsetsc = -0x7fff; + // Move to beginning of column/row + if(ct == SSEMatrix::E) { // AKA rdgap + assert_gt(col, 0); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::E))[rowelt] + offsetsc; + assert(gapsAllowed); + // Currently in the E matrix; incoming transition must come from the + // left. It's either a gap open from the H matrix or a gap extend from + // the E matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell to the left + TAlScore sc_h_left = ((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc; + if(sc_h_left > floorsc && sc_h_left - sc_->readGapOpen() == sc_cur) { + mask |= (1 << 0); + } + // Get E score of cell to the left + TAlScore sc_e_left = ((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc; + if(sc_e_left > floorsc && sc_e_left - sc_->readGapExtend() == sc_cur) { + mask |= (1 << 1); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isEMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 8) & 3; + } + if(mask == 3) { +#if 1 + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later + } else { + // Pick E -> E cell + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 1); // might choose H later + } +#endif + branch = true; + } else if(mask == 2) { + // I chose the E cell + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + assert(!empty || !canMoveThru); + } else if(ct == SSEMatrix::F) { // AKA rfgap + assert_gt(row, 0); + assert(gapsAllowed); + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::F))[rowelt] + offsetsc; + // Currently in the F matrix; incoming transition must come from above. + // It's either a gap open from the H matrix or a gap extend from the F + // matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell above + if(sc_h_up > floorsc && sc_h_up - sc_->refGapOpen() == sc_cur) { + mask |= (1 << 0); + } + // Get F score of cell above + if(sc_f_up > floorsc && sc_f_up - sc_->refGapExtend() == sc_cur) { + mask |= (1 << 1); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isFMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 11) & 3; + } + if(mask == 3) { +#if 1 + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later + } else { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 1); // might choose E later + } +#endif + branch = true; + } else if(mask == 2) { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + assert(!empty || !canMoveThru); + } else { + assert_eq(SSEMatrix::H, ct); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::H))[rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_h_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_e_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_h_upleft = col > 0 ? (((TCScore*)(upleft_vec + SSEMatrix::H))[upleft_rowelt] + offsetsc) : floorsc; + TAlScore sc_diag = sc_->score(readc, refm, readq - 33); + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + if(gapsAllowed) { + if(sc_h_up > floorsc && sc_cur == sc_h_up - sc_->refGapOpen()) { + mask |= (1 << 0); + } + if(sc_h_left > floorsc && sc_cur == sc_h_left - sc_->readGapOpen()) { + mask |= (1 << 1); + } + if(sc_f_up > floorsc && sc_cur == sc_f_up - sc_->refGapExtend()) { + mask |= (1 << 2); + } + if(sc_e_left > floorsc && sc_cur == sc_e_left - sc_->readGapExtend()) { + mask |= (1 << 3); + } + } + if(sc_h_upleft > floorsc && sc_cur == sc_h_upleft + sc_diag) { + mask |= (1 << 4); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isHMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 2) & 31; + } + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + int opts = alts5[mask]; + int select = -1; + if(opts == 1) { + select = firsts5[mask]; + assert_geq(mask, 0); + d.mat_.hMaskSet(row, col, 0); + } else if(opts > 1) { +#if 1 + if( (mask & 16) != 0) { + select = 4; // H diag + } else if((mask & 1) != 0) { + select = 0; // H up + } else if((mask & 4) != 0) { + select = 2; // F up + } else if((mask & 2) != 0) { + select = 1; // H left + } else if((mask & 8) != 0) { + select = 3; // E left + } +#else + select = randFromMask(rnd, mask); +#endif + assert_geq(mask, 0); + mask &= ~(1 << select); + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + d.mat_.hMaskSet(row, col, mask); + branch = true; + } else { /* No way to backtrack! */ } + if(select != -1) { + if(select == 4) { + cur = SW_BT_OALL_DIAG; + } else if(select == 0) { + cur = SW_BT_OALL_REF_OPEN; + } else if(select == 1) { + cur = SW_BT_OALL_READ_OPEN; + } else if(select == 2) { + cur = SW_BT_RFGAP_EXTEND; + } else { + assert_eq(3, select) + cur = SW_BT_RDGAP_EXTEND; + } + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + } + assert(!empty || !canMoveThru || ct == SSEMatrix::H); + } + } + d.mat_.setReportedThrough(row, col); + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + // Cell was involved in a previously-reported alignment? + if(!canMoveThru) { + if(!btnstack_.empty()) { + // Remove all the cells from list back to and including the + // cell where the branch occurred + btcells_.resize(btnstack_.back().celsz); + // Pop record off the top of the stack + ned.resize(btnstack_.back().nedsz); + //aed.resize(btnstack_.back().aedsz); + row = btnstack_.back().row; + col = btnstack_.back().col; + gaps = btnstack_.back().gaps; + readGaps = btnstack_.back().readGaps; + refGaps = btnstack_.back().refGaps; + score = btnstack_.back().score; + ct = btnstack_.back().ct; + btnstack_.pop_back(); + assert(!sc_->monotone || score.score() >= escore); + NEW_ROW_COL(row, col); + continue; + } else { + // No branch points to revisit; just give up + res.reset(); + met.btfail++; // DP backtraces failed + return false; + } + } + assert(!reportedThru); + assert(!sc_->monotone || score.score() >= minsc_); + if(empty || row == 0) { + assert_eq(SSEMatrix::H, ct); + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + // This cell is at the end of a legitimate alignment + trimBeg = row; + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + break; + } + if(branch) { + // Add a frame to the backtrack stack + btnstack_.expand(); + btnstack_.back().init( + ned.size(), + 0, // aed.size() + btcells_.size(), + row, + col, + gaps, + readGaps, + refGaps, + score, + (int)ct); + } + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + switch(cur) { + // Move up and to the left. If the reference nucleotide in the + // source row mismatches the read nucleotide, penalize + // it and add a nucleotide mismatch. + case SW_BT_OALL_DIAG: { + assert_gt(row, 0); assert_gt(col, 0); + // Check for color mismatch + int readC = (*rd_)[row]; + int refNmask = (int)rf_[rfi_+col]; + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + ct = SSEMatrix::H; + if(m != 1) { + Edit e( + (int)row, + mask2dna[refNmask], + "ACGTN"[readC], + EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + int pen = QUAL2(row, col); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= escore); + } else { + // Reward a match + int64_t bonus = sc_->match(30); + score.score_ += bonus; + assert(!sc_->monotone || score.score() >= escore); + } + if(m == -1) { + score.ns_++; + } + row--; col--; + MOVE_ALL_UPLEFT(); + assert(VALID_AL_SCORE(score)); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_OALL_REF_OPEN: + { + assert_gt(row, 0); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::H; + int pen = sc_->refGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_RFGAP_EXTEND: + { + assert_gt(row, 1); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::F; + int pen = sc_->refGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + case SW_BT_OALL_READ_OPEN: + { + assert_gt(col, 0); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::H; + int pen = sc_->readGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + case SW_BT_RDGAP_EXTEND: + { + assert_gt(col, 1); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::E; + int pen = sc_->readGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + default: throw 1; + } + } // while((int)row > 0) + assert_eq(0, trimBeg); + assert_eq(0, trimEnd); + assert_geq(col, 0); + assert_eq(SSEMatrix::H, ct); + // The number of cells in the backtracs should equal the number of read + // bases after trimming plus the number of gaps + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + // Check whether we went through a core diagonal and set 'reported' flag on + // each cell + bool overlappedCoreDiag = false; + for(size_t i = 0; i < btcells_.size(); i++) { + size_t rw = btcells_[i].first; + size_t cl = btcells_[i].second; + // Calculate the diagonal within the *trimmed* rectangle, i.e. the + // rectangle we dealt with in align, gather and backtrack. + int64_t diagi = cl - rw; + // Now adjust to the diagonal within the *untrimmed* rectangle by + // adding on the amount trimmed from the left. + diagi += rect_->triml; + if(diagi >= 0) { + size_t diag = (size_t)diagi; + if(diag >= rect_->corel && diag <= rect_->corer) { + overlappedCoreDiag = true; + break; + } + } + assert(d.mat_.reportedThrough(rw, cl)); + } + if(!overlappedCoreDiag) { + // Must overlap a core diagonal. Otherwise, we run the risk of + // reporting an alignment that overlaps (and trumps) a higher-scoring + // alignment that lies partially outside the dynamic programming + // rectangle. + res.reset(); + met.corerej++; + return false; + } + int readC = (*rd_)[rdi_+row]; // get last char in read + int refNmask = (int)rf_[rfi_+col]; // get last ref char ref involved in aln + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + if(m != 1) { + Edit e((int)row, mask2dna[refNmask], "ACGTN"[readC], EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + score.score_ -= QUAL2(row, col); + assert_geq(score.score(), minsc_); + } else { + score.score_ += sc_->match(30); + } + if(m == -1) { + score.ns_++; + } + if(score.ns_ > nceil_) { + // Alignment has too many Ns in it! + res.reset(); + met.nrej++; + return false; + } + res.reverse(); + assert(Edit::repOk(ned, (*rd_))); + assert_eq(score.score(), escore); + assert_leq(gaps, rdgap_ + rfgap_); + off = col; + assert_lt(col + (size_t)rfi_, (size_t)rff_); + score.gaps_ = gaps; + res.alres.setScore(score); + res.alres.setShape( + refidx_, // ref id + off + rfi_ + rect_->refl, // 0-based ref offset + reflen_, // reference length + fw_, // aligned to Watson? + rdf_ - rdi_, // read length + 0, // read ID + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + fw_ ? trimBeg : trimEnd, // alignment trim 5' end + fw_ ? trimEnd : trimBeg); // alignment trim 3' end + size_t refns = 0; + for(size_t i = col; i <= origCol; i++) { + if((int)rf_[rfi_+i] > 15) { + refns++; + } + } + res.alres.setRefNs(refns); + assert(Edit::repOk(ned, (*rd_), true, trimBeg, trimEnd)); + assert(res.repOk()); +#ifndef NDEBUG + size_t gapsCheck = 0; + for(size_t i = 0; i < ned.size(); i++) { + if(ned[i].isGap()) gapsCheck++; + } + assert_eq(gaps, gapsCheck); + BTDnaString refstr; + for(size_t i = col; i <= origCol; i++) { + refstr.append(firsts5[(int)rf_[rfi_+i]]); + } + BTDnaString editstr; + // daehwan + // Edit::toRef((*rd_), ned, editstr, true, trimBeg, trimEnd); + Edit::toRef((*rd_), ned, editstr, true, trimBeg + rdi_, trimEnd + (rd_->length() - rdf_)); + if(refstr != editstr) { + cerr << "Decoded nucleotides and edits don't match reference:" << endl; + cerr << " score: " << score.score() + << " (" << gaps << " gaps)" << endl; + cerr << " edits: "; + Edit::print(cerr, ned); + cerr << endl; + cerr << " decoded nucs: " << (*rd_) << endl; + cerr << " edited nucs: " << editstr << endl; + cerr << " reference nucs: " << refstr << endl; + assert(0); + } +#endif + met.btsucc++; // DP backtraces succeeded + return true; +} diff --git a/aligner_swsse_ee_u8.cpp b/aligner_swsse_ee_u8.cpp new file mode 100644 index 0000000..8b1fc18 --- /dev/null +++ b/aligner_swsse_ee_u8.cpp @@ -0,0 +1,1902 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/** + * aligner_sw_sse.cpp + * + * Versions of key alignment functions that use vector instructions to + * accelerate dynamic programming. Based chiefly on the striped Smith-Waterman + * paper and implementation by Michael Farrar. See: + * + * Farrar M. Striped Smith-Waterman speeds database searches six times over + * other SIMD implementations. Bioinformatics. 2007 Jan 15;23(2):156-61. + * http://sites.google.com/site/farrarmichael/smith-waterman + * + * While the paper describes an implementation of Smith-Waterman, we extend it + * do end-to-end read alignment as well as local alignment. The change + * required for this is minor: we simply let vmax be the maximum element in the + * score domain rather than the minimum. + * + * The vectorized dynamic programming implementation lacks some features that + * make it hard to adapt to solving the entire dynamic-programming alignment + * problem. For instance: + * + * - It doesn't respect gap barriers on either end of the read + * - It just gives a maximum; not enough information to backtrace without + * redoing some alignment + * - It's a little difficult to handle st_ and en_, especially st_. + * - The query profile mechanism makes handling of ambiguous reference bases a + * little tricky (16 cols in query profile lookup table instead of 5) + * + * Given the drawbacks, it is tempting to use SSE dynamic programming as a + * filter rather than as an aligner per se. Here are a few ideas for how it + * can be extended to handle more of the alignment problem: + * + * - Save calculated scores to a big array as we go. We return to this array + * to find and backtrace from good solutions. + */ + +#include +#include "aligner_sw.h" + +static const size_t NBYTES_PER_REG = 16; +static const size_t NWORDS_PER_REG = 16; +// static const size_t NBITS_PER_WORD = 8; +static const size_t NBYTES_PER_WORD = 1; + +// In end-to-end mode, we start high (255) and go low (0). Factoring in +// a query profile involves unsigned saturating subtraction, so all the +// query profile elements should be expressed as a positive penalty rather +// than a negative score. + +typedef uint8_t TCScore; + +/** + * Build query profile look up tables for the read. The query profile look + * up table is organized as a 1D array indexed by [i][j] where i is the + * reference character in the current DP column (0=A, 1=C, etc), and j is + * the segment of the query we're currently working on. + */ +void SwAligner::buildQueryProfileEnd2EndSseU8(bool fw) { + bool& done = fw ? sseU8fwBuilt_ : sseU8rcBuilt_; + if(done) { + return; + } + done = true; + const BTDnaString* rd = fw ? rdfw_ : rdrc_; + const BTString* qu = fw ? qufw_ : qurc_; + // daehwan - allows to align a portion of a read, not the whole. + // const size_t len = rd->length(); + const size_t len = dpRows(); + const size_t seglen = (len + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; + // How many __m128i's are needed + size_t n128s = + 64 + // slack bytes, for alignment? + (seglen * ALPHA_SIZE) // query profile data + * 2; // & gap barrier data + assert_gt(n128s, 0); + SSEData& d = fw ? sseU8fw_ : sseU8rc_; + d.profbuf_.resizeNoCopy(n128s); + assert(!d.profbuf_.empty()); + d.maxPen_ = d.maxBonus_ = 0; + d.lastIter_ = d.lastWord_ = 0; + d.qprofStride_ = d.gbarStride_ = 2; + d.bias_ = 0; // no bias needed for end-to-end alignment; just use subtraction + // For each reference character A, C, G, T, N ... + for(size_t refc = 0; refc < ALPHA_SIZE; refc++) { + // For each segment ... + for(size_t i = 0; i < seglen; i++) { + size_t j = i; + uint8_t *qprofWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2)); + uint8_t *gbarWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2) + 1); + // For each sub-word (byte) ... + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + int sc = 0; + *gbarWords = 0; + if(j < len) { + int readc = (*rd)[j]; + int readq = (*qu)[j]; + sc = sc_->score(readc, (int)(1 << refc), readq - 33); + // Make score positive, to fit in an unsigned + sc = -sc; + assert_range(0, 255, sc); + size_t j_from_end = len - j - 1; + if(j < (size_t)sc_->gapbar || + j_from_end < (size_t)sc_->gapbar) + { + // Inside the gap barrier + *gbarWords = 0xff; + } + } + if(refc == 0 && j == len-1) { + // Remember which 128-bit word and which smaller word has + // the final row + d.lastIter_ = i; + d.lastWord_ = k; + } + if((size_t)sc > d.maxPen_) { + d.maxPen_ = (size_t)sc; + } + *qprofWords = (uint8_t)sc; + gbarWords++; + qprofWords++; + j += seglen; // update offset into query + } + } + } +} + +#ifndef NDEBUG +/** + * Return true iff the cell has sane E/F/H values w/r/t its predecessors. + */ +static bool cellOkEnd2EndU8( + SSEData& d, + size_t row, + size_t col, + int refc, + int readc, + int readq, + const Scoring& sc) // scoring scheme +{ + TCScore floorsc = 0; + TAlScore ceilsc = MAX_I64; + TAlScore offsetsc = -0xff; + TAlScore sc_h_cur = (TAlScore)d.mat_.helt(row, col); + TAlScore sc_e_cur = (TAlScore)d.mat_.eelt(row, col); + TAlScore sc_f_cur = (TAlScore)d.mat_.felt(row, col); + if(sc_h_cur > floorsc) { + sc_h_cur += offsetsc; + } + if(sc_e_cur > floorsc) { + sc_e_cur += offsetsc; + } + if(sc_f_cur > floorsc) { + sc_f_cur += offsetsc; + } + bool gapsAllowed = true; + size_t rowFromEnd = d.mat_.nrow() - row - 1; + if(row < (size_t)sc.gapbar || rowFromEnd < (size_t)sc.gapbar) { + gapsAllowed = false; + } + bool e_left_trans = false, h_left_trans = false; + bool f_up_trans = false, h_up_trans = false; + bool h_diag_trans = false; + if(gapsAllowed) { + TAlScore sc_h_left = floorsc; + TAlScore sc_e_left = floorsc; + TAlScore sc_h_up = floorsc; + TAlScore sc_f_up = floorsc; + if(col > 0 && sc_e_cur > floorsc && sc_e_cur <= ceilsc) { + sc_h_left = d.mat_.helt(row, col-1) + offsetsc; + sc_e_left = d.mat_.eelt(row, col-1) + offsetsc; + e_left_trans = (sc_e_left > floorsc && sc_e_cur == sc_e_left - sc.readGapExtend()); + h_left_trans = (sc_h_left > floorsc && sc_e_cur == sc_h_left - sc.readGapOpen()); + assert(e_left_trans || h_left_trans); + // Check that we couldn't have got a better E score + assert_geq(sc_e_cur, sc_e_left - sc.readGapExtend()); + assert_geq(sc_e_cur, sc_h_left - sc.readGapOpen()); + } + if(row > 0 && sc_f_cur > floorsc && sc_f_cur <= ceilsc) { + sc_h_up = d.mat_.helt(row-1, col) + offsetsc; + sc_f_up = d.mat_.felt(row-1, col) + offsetsc; + f_up_trans = (sc_f_up > floorsc && sc_f_cur == sc_f_up - sc.refGapExtend()); + h_up_trans = (sc_h_up > floorsc && sc_f_cur == sc_h_up - sc.refGapOpen()); + assert(f_up_trans || h_up_trans); + // Check that we couldn't have got a better F score + assert_geq(sc_f_cur, sc_f_up - sc.refGapExtend()); + assert_geq(sc_f_cur, sc_h_up - sc.refGapOpen()); + } + } else { + assert_geq(floorsc, sc_e_cur); + assert_geq(floorsc, sc_f_cur); + } + if(col > 0 && row > 0 && sc_h_cur > floorsc && sc_h_cur <= ceilsc) { + TAlScore sc_h_upleft = d.mat_.helt(row-1, col-1) + offsetsc; + TAlScore sc_diag = sc.score(readc, (int)refc, readq - 33); + h_diag_trans = sc_h_cur == sc_h_upleft + sc_diag; + } + assert( + sc_h_cur <= floorsc || + e_left_trans || + h_left_trans || + f_up_trans || + h_up_trans || + h_diag_trans || + sc_h_cur > ceilsc || + row == 0 || + col == 0); + return true; +} +#endif /*ndef NDEBUG*/ + +#ifdef NDEBUG + +#define assert_all_eq0(x) +#define assert_all_gt(x, y) +#define assert_all_gt_lo(x) +#define assert_all_lt(x, y) +#define assert_all_lt_hi(x) + +#else + +#define assert_all_eq0(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpeq_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt(x, y) { \ + __m128i tmp = _mm_cmpgt_epu8(x, y); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt_lo(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpgt_epu8(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt(x, y) { \ + __m128i z = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + __m128i tmp = _mm_subs_epu8(y, x); \ + tmp = _mm_cmpeq_epi16(tmp, z); \ + assert_eq(0x0000, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt_hi(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_cmpeq_epu8(z, z); \ + z = _mm_srli_epu8(z, 1); \ + tmp = _mm_cmplt_epu8(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} +#endif + +/** + * Aligns by filling a dynamic programming matrix with the SSE-accelerated, + * banded DP approach of Farrar. As it goes, it determines which cells we + * might backtrace from and tallies the best (highest-scoring) N backtrace + * candidate cells per diagonal. Also returns the alignment score of the best + * alignment in the matrix. + * + * This routine does *not* maintain a matrix holding the entire matrix worth of + * scores, nor does it maintain any other dense O(mn) data structure, as this + * would quickly exhaust memory for queries longer than about 10,000 kb. + * Instead, in the fill stage it maintains two columns worth of scores at a + * time (current/previous, or right/left) - these take O(m) space. When + * finished with the current column, it determines which cells from the + * previous column, if any, are candidates we might backtrace from to find a + * full alignment. A candidate cell has a score that rises above the threshold + * and isn't improved upon by a match in the next column. The best N + * candidates per diagonal are stored in a O(m + n) data structure. + */ +TAlScore SwAligner::alignGatherEE8(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + if(!debug) met.dp++; + buildQueryProfileEnd2EndSseU8(fw_); + assert(!d.profbuf_.empty()); + + assert_eq(0, d.maxBonus_); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + int dup; + + // Now set up the score vectors. We just need two columns worth, which + // we'll call "left" and "right". + d.vecbuf_.resize(4 * 2 * iter); + d.vecbuf_.zero(); + __m128i *vbuf_l = d.vecbuf_.ptr(); + __m128i *vbuf_r = d.vecbuf_.ptr() + (4 * iter); + + // This is the data structure that holds candidate cells per diagonal. + const size_t ndiags = rff_ - rfi_ + dpRows() - 1; + if(!debug) { + btdiag_.init(ndiags, 2); + } + + // Data structure that holds checkpointed anti-diagonals + TAlScore perfectScore = sc_->perfectScore(dpRows()); + bool checkpoint = true; + bool cpdebug = false; +#ifndef NDEBUG + cpdebug = dpRows() < 1000; +#endif + cper_.init( + dpRows(), // # rows + rff_ - rfi_, // # columns + cperPerPow2_, // checkpoint every 1 << perpow2 diags (& next) + perfectScore, // perfect score (for sanity checks) + true, // matrix cells have 8-bit scores? + cperTri_, // triangular mini-fills? + false, // alignment is local? + cpdebug); // save all cells for debugging? + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); + __m128i vhd = _mm_setzero_si128(); + __m128i vhdtmp = _mm_setzero_si128(); + __m128i vtmp = _mm_setzero_si128(); + __m128i vzero = _mm_setzero_si128(); + __m128i vhilsw = _mm_setzero_si128(); + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_U8); + dup = (sc_->refGapOpen() << 8) | (sc_->refGapOpen() & 0x00ff); + rfgapo = _mm_insert_epi16(rfgapo, dup, 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_U8); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + dup = (sc_->refGapExtend() << 8) | (sc_->refGapExtend() & 0x00ff); + rfgape = _mm_insert_epi16(rfgape, dup, 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_U8); + dup = (sc_->readGapOpen() << 8) | (sc_->readGapOpen() & 0x00ff); + rdgapo = _mm_insert_epi16(rdgapo, dup, 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_U8); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + dup = (sc_->readGapExtend() << 8) | (sc_->readGapExtend() & 0x00ff); + rdgape = _mm_insert_epi16(rdgape, dup, 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vlo = _mm_xor_si128(vlo, vlo); // all elts = 0 + + // vhilsw: topmost (least sig) word set to 0x7fff, all other words=0 + vhilsw = _mm_shuffle_epi32(vhi, 0); + vhilsw = _mm_srli_si128(vhilsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + const size_t colstride = ROWSTRIDE_2COL * iter; + + // Initialize the H and E vectors in the first matrix column + __m128i *pvELeft = vbuf_l + 0; __m128i *pvERight = vbuf_r + 0; + /* __m128i *pvFLeft = vbuf_l + 1; */ __m128i *pvFRight = vbuf_r + 1; + __m128i *pvHLeft = vbuf_l + 2; __m128i *pvHRight = vbuf_r + 2; + + // Maximum score in final row + bool found = false; + TCScore lrmax = MIN_U8; + + for(size_t i = 0; i < iter; i++) { + _mm_store_si128(pvERight, vlo); pvERight += ROWSTRIDE_2COL; + // Could initialize Hs to high or low. If high, cells in the lower + // triangle will have somewhat more legitiate scores, but still won't + // be exhaustively scored. + _mm_store_si128(pvHRight, vlo); pvHRight += ROWSTRIDE_2COL; + } + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + // Swap left and right; vbuf_l is the vector on the left, which we + // generally load from, and vbuf_r is the vector on the right, which we + // generally store to. + swap(vbuf_l, vbuf_r); + pvELeft = vbuf_l + 0; pvERight = vbuf_r + 0; + /* pvFLeft = vbuf_l + 1; */ pvFRight = vbuf_r + 1; + pvHLeft = vbuf_l + 2; pvHRight = vbuf_r + 2; + + // Fetch the appropriate query profile. Note that elements of rf_ must + // be numbers, not masks. + const int refc = (int)rf_[i]; + + // Fetch the appropriate query profile + size_t off = (size_t)firsts5[refc] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Set all cells to low value + vf = _mm_xor_si128(vf, vf); + + // Load H vector from the final row of the previous column + vh = _mm_load_si128(pvHLeft + colstride - ROWSTRIDE_2COL); + // Shift 2 bytes down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + // Fill topmost (least sig) cell with high value + vh = _mm_or_si128(vh, vhilsw); + + // For each character in the reference text: + size_t j; + for(j = 0; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELeft); + vhd = _mm_load_si128(pvHLeft); + assert_all_lt(ve, vhi); + pvELeft += ROWSTRIDE_2COL; + + // Store cells in F, calculated previously + vf = _mm_subs_epu8(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Factor in query profile (matches and mismatches) + vh = _mm_subs_epu8(vh, pvScore[0]); + + // Update H, factoring in E and F + vh = _mm_max_epu8(vh, vf); + + // Update vE value + vhdtmp = vhd; + vhd = _mm_subs_epu8(vhd, rdgapo); + vhd = _mm_subs_epu8(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epu8(ve, rdgape); + ve = _mm_max_epu8(ve, vhd); + vh = _mm_max_epu8(vh, ve); + + // Save the new vH values + _mm_store_si128(pvHRight, vh); + pvHRight += ROWSTRIDE_2COL; + vtmp = vh; + assert_all_lt(ve, vhi); + + // Load the next h value + vh = vhdtmp; + pvHLeft += ROWSTRIDE_2COL; + + // Save E values + _mm_store_si128(pvERight, ve); + pvERight += ROWSTRIDE_2COL; + + // Update vf value + vtmp = _mm_subs_epu8(vtmp, rfgapo); + + vf = _mm_subs_epu8(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epu8(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFRight -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFRight); + + pvHRight -= colstride; // reset to start of column + vh = _mm_load_si128(pvHRight); + + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0xffff) { + // Store this vf + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Update vh w/r/t new vf + vh = _mm_max_epu8(vh, vf); + + // Save vH values + _mm_store_si128(pvHRight, vh); + pvHRight += ROWSTRIDE_2COL; + + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFRight -= colstride; + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + pvHRight -= colstride; + vh = _mm_load_si128(pvHRight); // load next vh ASAP + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + } else { + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + vh = _mm_load_si128(pvHRight); // load next vh ASAP + } + + // Update F with another gap extension + vf = _mm_subs_epu8(vf, rfgape); + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + + // Check in the last row for the maximum so far + __m128i *vtmp = vbuf_r + 2 /* H */ + (d.lastIter_ * ROWSTRIDE_2COL); + // Note: we may not want to extract from the final row + TCScore lr = ((TCScore*)(vtmp))[d.lastWord_]; + found = true; + if(lr > lrmax) { + lrmax = lr; + } + + // Now we'd like to know whether the bottommost element of the right + // column is a candidate we might backtrace from. First question is: + // did it exceed the minimum score threshold? + TAlScore score = (TAlScore)(lr - 0xff); + if(lr == MIN_U8) { + score = MIN_I64; + } + if(!debug && score >= minsc_) { + DpBtCandidate cand(dpRows() - 1, i - rfi_, score); + btdiag_.add(i - rfi_, cand); + } + + // Save some elements to checkpoints + if(checkpoint) { + + __m128i *pvE = vbuf_r + 0; + __m128i *pvF = vbuf_r + 1; + __m128i *pvH = vbuf_r + 2; + size_t coli = i - rfi_; + if(coli < cper_.locol_) cper_.locol_ = coli; + if(coli > cper_.hicol_) cper_.hicol_ = coli; + + if(cperTri_) { + size_t rc_mod = coli & cper_.lomask_; + assert_lt(rc_mod, cper_.per_); + int64_t row = -(int64_t)rc_mod-1; + int64_t row_mod = row; + int64_t row_div = 0; + size_t idx = coli >> cper_.perpow2_; + size_t idxrow = idx * cper_.nrow_; + assert_eq(4, ROWSTRIDE_2COL); + bool done = false; + while(true) { + row += (cper_.per_ - 2); + row_mod += (cper_.per_ - 2); + for(size_t j = 0; j < 2; j++) { + row++; + row_mod++; + if(row >= 0 && (size_t)row < cper_.nrow_) { + // Update row divided by iter_ and mod iter_ + while(row_mod >= (int64_t)iter) { + row_mod -= (int64_t)iter; + row_div++; + } + size_t delt = idxrow + row; + size_t vecoff = (row_mod << 6) + row_div; + assert_lt(row_div, 16); + int16_t h_sc = ((uint8_t*)pvH)[vecoff]; + int16_t e_sc = ((uint8_t*)pvE)[vecoff]; + int16_t f_sc = ((uint8_t*)pvF)[vecoff]; + if(h_sc == 0) h_sc = MIN_I16; + else h_sc -= 0xff; + if(e_sc == 0) e_sc = MIN_I16; + else e_sc -= 0xff; + if(f_sc == 0) f_sc = MIN_I16; + else f_sc -= 0xff; + assert_leq(h_sc, cper_.perf_); + assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad *qdiags = ((j == 0) ? cper_.qdiag1s_.ptr() : cper_.qdiag2s_.ptr()); + qdiags[delt].sc[0] = h_sc; + qdiags[delt].sc[1] = e_sc; + qdiags[delt].sc[2] = f_sc; + } // if(row >= 0 && row < nrow_) + else if(row >= 0 && (size_t)row >= cper_.nrow_) { + done = true; + break; + } + } // end of loop over anti-diags + if(done) { + break; + } + idx++; + idxrow += cper_.nrow_; + } + } else { + // If this is the first column, take this opportunity to + // pre-calculate the coordinates of the elements we're going to + // checkpoint. + if(coli == 0) { + size_t cpi = cper_.per_-1; + size_t cpimod = cper_.per_-1; + size_t cpidiv = 0; + cper_.commitMap_.clear(); + while(cpi < cper_.nrow_) { + while(cpimod >= iter) { + cpimod -= iter; + cpidiv++; + } + size_t vecoff = (cpimod << 6) + cpidiv; + cper_.commitMap_.push_back(vecoff); + cpi += cper_.per_; + cpimod += cper_.per_; + } + } + // Save all the rows + size_t rowoff = 0; + size_t sz = cper_.commitMap_.size(); + for(size_t i = 0; i < sz; i++, rowoff += cper_.ncol_) { + size_t vecoff = cper_.commitMap_[i]; + int16_t h_sc = ((uint8_t*)pvH)[vecoff]; + //int16_t e_sc = ((uint8_t*)pvE)[vecoff]; + int16_t f_sc = ((uint8_t*)pvF)[vecoff]; + if(h_sc == 0) h_sc = MIN_I16; + else h_sc -= 0xff; + //if(e_sc == 0) e_sc = MIN_I16; + //else e_sc -= 0xff; + if(f_sc == 0) f_sc = MIN_I16; + else f_sc -= 0xff; + assert_leq(h_sc, cper_.perf_); + //assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad& dst = cper_.qrows_[rowoff + coli]; + dst.sc[0] = h_sc; + //dst.sc[1] = e_sc; + dst.sc[2] = f_sc; + } + // Is this a column we'd like to checkpoint? + if((coli & cper_.lomask_) == cper_.lomask_) { + // Save the column using memcpys + assert_gt(coli, 0); + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = (coli >> cper_.perpow2_) * wordspercol; + __m128i *dst = cper_.qcols_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + if(cper_.debug_) { + // Save the column using memcpys + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = coli * wordspercol; + __m128i *dst = cper_.qcolsD_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + } + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + flag = 0; + + // Did we find a solution? + TAlScore score = MIN_I64; + if(!found) { + flag = -1; // no + if(!debug) met.dpfail++; + return MIN_I64; + } else { + score = (TAlScore)(lrmax - 0xff); + if(score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return score; + } + } + + // Could we have saturated? + if(lrmax == MIN_U8) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Now take all the backtrace candidates in the btdaig_ structure and + // dump them into the btncand_ array. They'll be sorted later. + if(!debug) { + btdiag_.dump(btncand_); + assert(!btncand_.empty()); + } + + // Return largest score + if(!debug) met.dpsucc++; + return score; +} + +/** + * Solve the current alignment problem using SSE instructions that operate on 16 + * unsigned 8-bit values packed into a single 128-bit register. + */ +TAlScore SwAligner::alignNucleotidesEnd2EndSseU8(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + if(!debug) met.dp++; + buildQueryProfileEnd2EndSseU8(fw_); + assert(!d.profbuf_.empty()); + + assert_eq(0, d.maxBonus_); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + int dup; + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); +#if 0 + __m128i vhd = _mm_setzero_si128(); + __m128i vhdtmp = _mm_setzero_si128(); +#endif + __m128i vtmp = _mm_setzero_si128(); + __m128i vzero = _mm_setzero_si128(); + __m128i vhilsw = _mm_setzero_si128(); + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_U8); + dup = (sc_->refGapOpen() << 8) | (sc_->refGapOpen() & 0x00ff); + rfgapo = _mm_insert_epi16(rfgapo, dup, 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_U8); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + dup = (sc_->refGapExtend() << 8) | (sc_->refGapExtend() & 0x00ff); + rfgape = _mm_insert_epi16(rfgape, dup, 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_U8); + dup = (sc_->readGapOpen() << 8) | (sc_->readGapOpen() & 0x00ff); + rdgapo = _mm_insert_epi16(rdgapo, dup, 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_U8); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + dup = (sc_->readGapExtend() << 8) | (sc_->readGapExtend() & 0x00ff); + rdgape = _mm_insert_epi16(rdgape, dup, 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vlo = _mm_xor_si128(vlo, vlo); // all elts = 0 + + // vhilsw: topmost (least sig) word set to 0x7fff, all other words=0 + vhilsw = _mm_shuffle_epi32(vhi, 0); + vhilsw = _mm_srli_si128(vhilsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + d.mat_.init(dpRows(), rff_ - rfi_, NWORDS_PER_REG); + const size_t colstride = d.mat_.colstride(); + //const size_t rowstride = d.mat_.rowstride(); + assert_eq(ROWSTRIDE, colstride / iter); + + // Initialize the H and E vectors in the first matrix column + __m128i *pvHTmp = d.mat_.tmpvec(0, 0); + __m128i *pvETmp = d.mat_.evec(0, 0); + + // Maximum score in final row + bool found = false; + TCScore lrmax = MIN_U8; + + for(size_t i = 0; i < iter; i++) { + _mm_store_si128(pvETmp, vlo); + _mm_store_si128(pvHTmp, vlo); // start high in end-to-end mode + pvETmp += ROWSTRIDE; + pvHTmp += ROWSTRIDE; + } + // These are swapped just before the innermost loop + __m128i *pvHStore = d.mat_.hvec(0, 0); + __m128i *pvHLoad = d.mat_.tmpvec(0, 0); + __m128i *pvELoad = d.mat_.evec(0, 0); + __m128i *pvEStore = d.mat_.evecUnsafe(0, 1); + __m128i *pvFStore = d.mat_.fvec(0, 0); + __m128i *pvFTmp = NULL; + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + colstop_ = rff_ - 1; + lastsolcol_ = 0; + + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert(pvFStore == d.mat_.fvec(0, i - rfi_)); + assert(pvHStore == d.mat_.hvec(0, i - rfi_)); + + // Fetch the appropriate query profile. Note that elements of rf_ must + // be numbers, not masks. + const int refc = (int)rf_[i]; + size_t off = (size_t)firsts5[refc] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Set all cells to low value + vf = _mm_xor_si128(vf, vf); + + // Load H vector from the final row of the previous column + vh = _mm_load_si128(pvHLoad + colstride - ROWSTRIDE); + // Shift 2 bytes down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + // Fill topmost (least sig) cell with high value + vh = _mm_or_si128(vh, vhilsw); + + // For each character in the reference text: + size_t j; + for(j = 0; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELoad); +#if 0 + vhd = _mm_load_si128(pvHLoad); +#endif + assert_all_lt(ve, vhi); + pvELoad += ROWSTRIDE; + + // Store cells in F, calculated previously + vf = _mm_subs_epu8(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Factor in query profile (matches and mismatches) + vh = _mm_subs_epu8(vh, pvScore[0]); + + // Update H, factoring in E and F + vh = _mm_max_epu8(vh, ve); + vh = _mm_max_epu8(vh, vf); + + // Save the new vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update vE value + vtmp = vh; +#if 0 + vhdtmp = vhd; + vhd = _mm_subs_epu8(vhd, rdgapo); + vhd = _mm_subs_epu8(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epu8(ve, rdgape); + ve = _mm_max_epu8(ve, vhd); +#else + vh = _mm_subs_epu8(vh, rdgapo); + vh = _mm_subs_epu8(vh, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epu8(ve, rdgape); + ve = _mm_max_epu8(ve, vh); +#endif + assert_all_lt(ve, vhi); + + // Load the next h value +#if 0 + vh = vhdtmp; +#else + vh = _mm_load_si128(pvHLoad); +#endif + pvHLoad += ROWSTRIDE; + + // Save E values + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + + // Update vf value + vtmp = _mm_subs_epu8(vtmp, rfgapo); + vf = _mm_subs_epu8(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epu8(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFTmp = pvFStore; + pvFStore -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFStore); + + pvHStore -= colstride; // reset to start of column + vh = _mm_load_si128(pvHStore); + +#if 0 +#else + pvEStore -= colstride; // reset to start of column + ve = _mm_load_si128(pvEStore); +#endif + + pvHLoad = pvHStore; // new pvHLoad = pvHStore + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0xffff) { + // Store this vf + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Update vh w/r/t new vf + vh = _mm_max_epu8(vh, vf); + + // Save vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update E in case it can be improved using our new vh +#if 0 +#else + vh = _mm_subs_epu8(vh, rdgapo); + vh = _mm_subs_epu8(vh, *pvScore); // veto some read gap opens + ve = _mm_max_epu8(ve, vh); + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; +#endif + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFStore -= colstride; + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + pvHStore -= colstride; + vh = _mm_load_si128(pvHStore); // load next vh ASAP +#if 0 +#else + pvEStore -= colstride; + ve = _mm_load_si128(pvEStore); // load next ve ASAP +#endif + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + } else { + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + vh = _mm_load_si128(pvHStore); // load next vh ASAP +#if 0 +#else + ve = _mm_load_si128(pvEStore); // load next vh ASAP +#endif + } + + // Update F with another gap extension + vf = _mm_subs_epu8(vf, rfgape); + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + +#ifndef NDEBUG + if(true && (rand() & 15) == 0) { + // This is a work-intensive sanity check; each time we finish filling + // a column, we check that each H, E, and F is sensible. + for(size_t k = 0; k < dpRows(); k++) { + assert(cellOkEnd2EndU8( + d, + k, // row + i - rfi_, // col + refc, // reference mask + (int)(*rd_)[rdi_+k], // read char + (int)(*qu_)[rdi_+k], // read quality + *sc_)); // scoring scheme + } + } +#endif + + __m128i *vtmp = d.mat_.hvec(d.lastIter_, i-rfi_); + // Note: we may not want to extract from the final row + TCScore lr = ((TCScore*)(vtmp))[d.lastWord_]; + found = true; + if(lr > lrmax) { + lrmax = lr; + } + + // pvELoad and pvHLoad are already where they need to be + + // Adjust the load and store vectors here. + pvHStore = pvHLoad + colstride; + pvEStore = pvELoad + colstride; + pvFStore = pvFTmp; + } + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + flag = 0; + + // Did we find a solution? + TAlScore score = MIN_I64; + if(!found) { + flag = -1; // no + if(!debug) met.dpfail++; + return MIN_I64; + } else { + score = (TAlScore)(lrmax - 0xff); + if(score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return score; + } + } + + // Could we have saturated? + if(lrmax == MIN_U8) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Return largest score + if(!debug) met.dpsucc++; + return score; +} + +/** + * Given a filled-in DP table, populate the btncand_ list with candidate cells + * that might be at the ends of valid alignments. No need to do this unless + * the maximum score returned by the align*() func is >= the minimum. + * + * Only cells that are exhaustively scored are candidates. Those are the + * cells inside the shape made of o's in this: + * + * |-maxgaps-| + * ********************************* - + * ******************************** | + * ******************************* | + * ****************************** | + * ***************************** | + * **************************** read len + * *************************** | + * ************************** | + * ************************* | + * ************************ | + * ***********oooooooooooo - + * |-maxgaps-| + * |-readlen-| + * |-------skip--------| + * + * And it's possible for the shape to be truncated on the left and right sides. + * + * + */ +bool SwAligner::gatherCellsNucleotidesEnd2EndSseU8(TAlScore best) { + // What's the minimum number of rows that can possibly be spanned by an + // alignment that meets the minimum score requirement? + assert(sse8succ_); + const size_t ncol = rff_ - rfi_; + const size_t nrow = dpRows(); + assert_gt(nrow, 0); + btncand_.clear(); + btncanddone_.clear(); + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + assert(!d.profbuf_.empty()); + const size_t colstride = d.mat_.colstride(); + ASSERT_ONLY(bool sawbest = false); + __m128i *pvH = d.mat_.hvec(d.lastIter_, 0); + for(size_t j = 0; j < ncol; j++) { + TAlScore sc = (TAlScore)(((TCScore*)pvH)[d.lastWord_] - 0xff); + assert_leq(sc, best); + ASSERT_ONLY(sawbest = (sawbest || sc == best)); + if(sc >= minsc_) { + // Yes, this is legit + met.gathsol++; + btncand_.expand(); + btncand_.back().init(nrow-1, j, sc); + } + pvH += colstride; + } + assert(sawbest); + if(!btncand_.empty()) { + d.mat_.initMasks(); + } + return !btncand_.empty(); +} + +#define MOVE_VEC_PTR_UP(vec, rowvec, rowelt) { \ + if(rowvec == 0) { \ + rowvec += d.mat_.nvecrow_; \ + vec += d.mat_.colstride_; \ + rowelt--; \ + } \ + rowvec--; \ + vec -= ROWSTRIDE; \ +} + +#define MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt) { vec -= d.mat_.colstride_; } + +#define MOVE_VEC_PTR_UPLEFT(vec, rowvec, rowelt) { \ + MOVE_VEC_PTR_UP(vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt); \ +} + +#define MOVE_ALL_LEFT() { \ + MOVE_VEC_PTR_LEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_LEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UP() { \ + MOVE_VEC_PTR_UP(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UP(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UP(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UPLEFT() { \ + MOVE_VEC_PTR_UPLEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UPLEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UPLEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UPLEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define NEW_ROW_COL(row, col) { \ + rowelt = row / d.mat_.nvecrow_; \ + rowvec = row % d.mat_.nvecrow_; \ + eltvec = (col * d.mat_.colstride_) + (rowvec * ROWSTRIDE); \ + cur_vec = d.mat_.matbuf_.ptr() + eltvec; \ + left_vec = cur_vec; \ + left_rowelt = rowelt; \ + left_rowvec = rowvec; \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + up_vec = cur_vec; \ + up_rowelt = rowelt; \ + up_rowvec = rowvec; \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + upleft_vec = up_vec; \ + upleft_rowelt = up_rowelt; \ + upleft_rowvec = up_rowvec; \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +/** + * Given the dynamic programming table and a cell, trace backwards from the + * cell and install the edits and score/penalty in the appropriate fields + * of res. The RandomSource is used to break ties among equally good ways + * of tracing back. + * + * Whenever we enter a cell, we check whether the read/ref coordinates of + * that cell correspond to a cell we traversed constructing a previous + * alignment. If so, we backtrack to the last decision point, mask out the + * path that led to the previously observed cell, and continue along a + * different path; or, if there are no more paths to try, we give up. + * + * If an alignment is found, 'off' is set to the alignment's upstream-most + * reference character's offset into the chromosome and true is returned. + * Otherwise, false is returned. + */ +bool SwAligner::backtraceNucleotidesEnd2EndSseU8( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this row + size_t col, // start in this column + RandomSource& rnd) // random gen, to choose among equal paths +{ + assert_lt(row, dpRows()); + assert_lt(col, (size_t)(rff_ - rfi_)); + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + met.bt++; + assert(!d.profbuf_.empty()); + assert_lt(row, rd_->length()); + btnstack_.clear(); // empty the backtrack stack + btcells_.clear(); // empty the cells-so-far list + AlnScore score; score.score_ = 0; + score.gaps_ = score.ns_ = 0; + size_t origCol = col; + size_t gaps = 0, readGaps = 0, refGaps = 0; + res.alres.reset(); + EList& ned = res.alres.ned(); + assert(ned.empty()); + assert_gt(dpRows(), row); + size_t trimEnd = dpRows() - row - 1; + size_t trimBeg = 0; + size_t ct = SSEMatrix::H; // cell type + // Row and col in terms of where they fall in the SSE vector matrix + size_t rowelt, rowvec, eltvec; + size_t left_rowelt, up_rowelt, upleft_rowelt; + size_t left_rowvec, up_rowvec, upleft_rowvec; + __m128i *cur_vec, *left_vec, *up_vec, *upleft_vec; + NEW_ROW_COL(row, col); + while((int)row >= 0) { + met.btcell++; + nbts++; + int readc = (*rd_)[rdi_ + row]; + int refm = (int)rf_[rfi_ + col]; + int readq = (*qu_)[row]; + assert_leq(col, origCol); + // Get score in this cell + bool empty = false, reportedThru, canMoveThru, branch = false; + int cur = SSEMatrix::H; + if(!d.mat_.reset_[row]) { + d.mat_.resetRow(row); + } + reportedThru = d.mat_.reportedThrough(row, col); + canMoveThru = true; + if(reportedThru) { + canMoveThru = false; + } else { + empty = false; + if(row > 0) { + assert_gt(row, 0); + size_t rowFromEnd = d.mat_.nrow() - row - 1; + bool gapsAllowed = true; + if(row < (size_t)sc_->gapbar || + rowFromEnd < (size_t)sc_->gapbar) + { + gapsAllowed = false; + } + const TAlScore floorsc = MIN_I64; + const int offsetsc = -0xff; + // Move to beginning of column/row + if(ct == SSEMatrix::E) { // AKA rdgap + assert_gt(col, 0); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::E))[rowelt] + offsetsc; + assert(gapsAllowed); + // Currently in the E matrix; incoming transition must come from the + // left. It's either a gap open from the H matrix or a gap extend from + // the E matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell to the left + TAlScore sc_h_left = ((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc; + if(sc_h_left > floorsc && sc_h_left - sc_->readGapOpen() == sc_cur) { + mask |= (1 << 0); + } + // Get E score of cell to the left + TAlScore sc_e_left = ((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc; + if(sc_e_left > floorsc && sc_e_left - sc_->readGapExtend() == sc_cur) { + mask |= (1 << 1); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isEMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 8) & 3; + } + if(mask == 3) { +#if 1 + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later + } else { + // Pick E -> E cell + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 1); // might choose H later + } +#endif + branch = true; + } else if(mask == 2) { + // I chose the E cell + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + assert(!empty || !canMoveThru); + } else if(ct == SSEMatrix::F) { // AKA rfgap + assert_gt(row, 0); + assert(gapsAllowed); + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::F))[rowelt] + offsetsc; + // Currently in the F matrix; incoming transition must come from above. + // It's either a gap open from the H matrix or a gap extend from the F + // matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell above + if(sc_h_up > floorsc && sc_h_up - sc_->refGapOpen() == sc_cur) { + mask |= (1 << 0); + } + // Get F score of cell above + if(sc_f_up > floorsc && sc_f_up - sc_->refGapExtend() == sc_cur) { + mask |= (1 << 1); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isFMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 11) & 3; + } + if(mask == 3) { +#if 1 + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later + } else { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 1); // might choose E later + } +#endif + branch = true; + } else if(mask == 2) { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + assert(!empty || !canMoveThru); + } else { + assert_eq(SSEMatrix::H, ct); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::H))[rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_h_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_e_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_h_upleft = col > 0 ? (((TCScore*)(upleft_vec + SSEMatrix::H))[upleft_rowelt] + offsetsc) : floorsc; + TAlScore sc_diag = sc_->score(readc, refm, readq - 33); + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + if(gapsAllowed) { + if(sc_h_up > floorsc && sc_cur == sc_h_up - sc_->refGapOpen()) { + mask |= (1 << 0); + } + if(sc_h_left > floorsc && sc_cur == sc_h_left - sc_->readGapOpen()) { + mask |= (1 << 1); + } + if(sc_f_up > floorsc && sc_cur == sc_f_up - sc_->refGapExtend()) { + mask |= (1 << 2); + } + if(sc_e_left > floorsc && sc_cur == sc_e_left - sc_->readGapExtend()) { + mask |= (1 << 3); + } + } + if(sc_h_upleft > floorsc && sc_cur == sc_h_upleft + sc_diag) { + mask |= (1 << 4); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isHMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 2) & 31; + } + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + int opts = alts5[mask]; + int select = -1; + if(opts == 1) { + select = firsts5[mask]; + assert_geq(mask, 0); + d.mat_.hMaskSet(row, col, 0); + } else if(opts > 1) { +#if 1 + if( (mask & 16) != 0) { + select = 4; // H diag + } else if((mask & 1) != 0) { + select = 0; // H up + } else if((mask & 4) != 0) { + select = 2; // F up + } else if((mask & 2) != 0) { + select = 1; // H left + } else if((mask & 8) != 0) { + select = 3; // E left + } +#else + select = randFromMask(rnd, mask); +#endif + assert_geq(mask, 0); + mask &= ~(1 << select); + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + d.mat_.hMaskSet(row, col, mask); + branch = true; + } else { /* No way to backtrack! */ } + if(select != -1) { + if(select == 4) { + cur = SW_BT_OALL_DIAG; + } else if(select == 0) { + cur = SW_BT_OALL_REF_OPEN; + } else if(select == 1) { + cur = SW_BT_OALL_READ_OPEN; + } else if(select == 2) { + cur = SW_BT_RFGAP_EXTEND; + } else { + assert_eq(3, select) + cur = SW_BT_RDGAP_EXTEND; + } + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + } + assert(!empty || !canMoveThru || ct == SSEMatrix::H); + } + } + //cerr << "reportedThrough rejected (" << row << ", " << col << ")" << endl; + d.mat_.setReportedThrough(row, col); + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + // Cell was involved in a previously-reported alignment? + if(!canMoveThru) { + if(!btnstack_.empty()) { + // Remove all the cells from list back to and including the + // cell where the branch occurred + btcells_.resize(btnstack_.back().celsz); + // Pop record off the top of the stack + ned.resize(btnstack_.back().nedsz); + //aed.resize(btnstack_.back().aedsz); + row = btnstack_.back().row; + col = btnstack_.back().col; + gaps = btnstack_.back().gaps; + readGaps = btnstack_.back().readGaps; + refGaps = btnstack_.back().refGaps; + score = btnstack_.back().score; + ct = btnstack_.back().ct; + btnstack_.pop_back(); + assert(!sc_->monotone || score.score() >= escore); + NEW_ROW_COL(row, col); + continue; + } else { + // No branch points to revisit; just give up + res.reset(); + met.btfail++; // DP backtraces failed + return false; + } + } + assert(!reportedThru); + assert(!sc_->monotone || score.score() >= minsc_); + if(empty || row == 0) { + assert_eq(SSEMatrix::H, ct); + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + // This cell is at the end of a legitimate alignment + trimBeg = row; + assert_eq(0, trimBeg); + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + break; + } + if(branch) { + // Add a frame to the backtrack stack + btnstack_.expand(); + btnstack_.back().init( + ned.size(), + 0, // aed.size() + btcells_.size(), + row, + col, + gaps, + readGaps, + refGaps, + score, + (int)ct); + } + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + switch(cur) { + // Move up and to the left. If the reference nucleotide in the + // source row mismatches the read nucleotide, penalize + // it and add a nucleotide mismatch. + case SW_BT_OALL_DIAG: { + assert_gt(row, 0); assert_gt(col, 0); + // Check for color mismatch + int readC = (*rd_)[row]; + int refNmask = (int)rf_[rfi_+col]; + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + ct = SSEMatrix::H; + if(m != 1) { + Edit e( + (int)row, + mask2dna[refNmask], + "ACGTN"[readC], + EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + int pen = QUAL2(row, col); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= escore); + } else { + // Reward a match + int64_t bonus = sc_->match(30); + score.score_ += bonus; + assert(!sc_->monotone || score.score() >= escore); + } + if(m == -1) { + score.ns_++; + } + row--; col--; + MOVE_ALL_UPLEFT(); + assert(VALID_AL_SCORE(score)); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_OALL_REF_OPEN: + { + assert_gt(row, 0); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::H; + int pen = sc_->refGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_RFGAP_EXTEND: + { + assert_gt(row, 1); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::F; + int pen = sc_->refGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + case SW_BT_OALL_READ_OPEN: + { + assert_gt(col, 0); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::H; + int pen = sc_->readGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + case SW_BT_RDGAP_EXTEND: + { + assert_gt(col, 1); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::E; + int pen = sc_->readGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + default: throw 1; + } + } // while((int)row > 0) + assert_eq(0, trimBeg); + assert_eq(0, trimEnd); + assert_geq(col, 0); + assert_eq(SSEMatrix::H, ct); + // The number of cells in the backtracs should equal the number of read + // bases after trimming plus the number of gaps + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + // Check whether we went through a core diagonal and set 'reported' flag on + // each cell + bool overlappedCoreDiag = false; + for(size_t i = 0; i < btcells_.size(); i++) { + size_t rw = btcells_[i].first; + size_t cl = btcells_[i].second; + // Calculate the diagonal within the *trimmed* rectangle, i.e. the + // rectangle we dealt with in align, gather and backtrack. + int64_t diagi = cl - rw; + // Now adjust to the diagonal within the *untrimmed* rectangle by + // adding on the amount trimmed from the left. + diagi += rect_->triml; + if(diagi >= 0) { + size_t diag = (size_t)diagi; + if(diag >= rect_->corel && diag <= rect_->corer) { + overlappedCoreDiag = true; + break; + } + } +#ifndef NDEBUG + //assert(!d.mat_.reportedThrough(rw, cl)); + //d.mat_.setReportedThrough(rw, cl); + assert(d.mat_.reportedThrough(rw, cl)); +#endif + } + if(!overlappedCoreDiag) { + // Must overlap a core diagonal. Otherwise, we run the risk of + // reporting an alignment that overlaps (and trumps) a higher-scoring + // alignment that lies partially outside the dynamic programming + // rectangle. + res.reset(); + met.corerej++; + return false; + } + int readC = (*rd_)[rdi_+row]; // get last char in read + int refNmask = (int)rf_[rfi_+col]; // get last ref char ref involved in aln + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + if(m != 1) { + Edit e((int)row, mask2dna[refNmask], "ACGTN"[readC], EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + score.score_ -= QUAL2(row, col); + assert_geq(score.score(), minsc_); + } else { + score.score_ += sc_->match(30); + } + if(m == -1) { + score.ns_++; + } + if(score.ns_ > nceil_) { + // Alignment has too many Ns in it! + res.reset(); + met.nrej++; + return false; + } + res.reverse(); + assert(Edit::repOk(ned, (*rd_))); + assert_eq(score.score(), escore); + assert_leq(gaps, rdgap_ + rfgap_); + off = col; + assert_lt(col + (size_t)rfi_, (size_t)rff_); + score.gaps_ = gaps; + res.alres.setScore(score); + res.alres.setShape( + refidx_, // ref id + off + rfi_ + rect_->refl, // 0-based ref offset + reflen_, // length of entire reference + fw_, // aligned to Watson? + rdf_ - rdi_, // read length + 0, // read ID + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + fw_ ? trimBeg : trimEnd, // alignment trim 5' end + fw_ ? trimEnd : trimBeg); // alignment trim 3' end + size_t refns = 0; + for(size_t i = col; i <= origCol; i++) { + if((int)rf_[rfi_+i] > 15) { + refns++; + } + } + res.alres.setRefNs(refns); + assert(Edit::repOk(ned, (*rd_), true, trimBeg, trimEnd)); + assert(res.repOk()); +#ifndef NDEBUG + size_t gapsCheck = 0; + for(size_t i = 0; i < ned.size(); i++) { + if(ned[i].isGap()) gapsCheck++; + } + assert_eq(gaps, gapsCheck); + BTDnaString refstr; + for(size_t i = col; i <= origCol; i++) { + refstr.append(firsts5[(int)rf_[rfi_+i]]); + } + BTDnaString editstr; + // daehwan + // Edit::toRef((*rd_), ned, editstr, true, trimBeg, trimEnd); + Edit::toRef((*rd_), ned, editstr, true, trimBeg + rdi_, trimEnd + (rd_->length() - rdf_)); + if(refstr != editstr) { + cerr << "Decoded nucleotides and edits don't match reference:" << endl; + cerr << " score: " << score.score() + << " (" << gaps << " gaps)" << endl; + cerr << " edits: "; + Edit::print(cerr, ned); + cerr << endl; + cerr << " decoded nucs: " << (*rd_) << endl; + cerr << " edited nucs: " << editstr << endl; + cerr << " reference nucs: " << refstr << endl; + assert(0); + } +#endif + met.btsucc++; // DP backtraces succeeded + return true; +} diff --git a/aligner_swsse_loc_i16.cpp b/aligner_swsse_loc_i16.cpp new file mode 100644 index 0000000..e4e8fac --- /dev/null +++ b/aligner_swsse_loc_i16.cpp @@ -0,0 +1,2272 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/** + * aligner_sw_sse.cpp + * + * Versions of key alignment functions that use vector instructions to + * accelerate dynamic programming. Based chiefly on the striped Smith-Waterman + * paper and implementation by Michael Farrar. See: + * + * Farrar M. Striped Smith-Waterman speeds database searches six times over + * other SIMD implementations. Bioinformatics. 2007 Jan 15;23(2):156-61. + * http://sites.google.com/site/farrarmichael/smith-waterman + * + * While the paper describes an implementation of Smith-Waterman, we extend it + * do end-to-end read alignment as well as local alignment. The change + * required for this is minor: we simply let vmax be the maximum element in the + * score domain rather than the minimum. + * + * The vectorized dynamic programming implementation lacks some features that + * make it hard to adapt to solving the entire dynamic-programming alignment + * problem. For instance: + * + * - It doesn't respect gap barriers on either end of the read + * - It just gives a maximum; not enough information to backtrace without + * redoing some alignment + * - It's a little difficult to handle st_ and en_, especially st_. + * - The query profile mechanism makes handling of ambiguous reference bases a + * little tricky (16 cols in query profile lookup table instead of 5) + * + * Given the drawbacks, it is tempting to use SSE dynamic programming as a + * filter rather than as an aligner per se. Here are a few ideas for how it + * can be extended to handle more of the alignment problem: + * + * - Save calculated scores to a big array as we go. We return to this array + * to find and backtrace from good solutions. + */ + +#include +#include "aligner_sw.h" + +static const size_t NBYTES_PER_REG = 16; +static const size_t NWORDS_PER_REG = 8; +static const size_t NBITS_PER_WORD = 16; +static const size_t NBYTES_PER_WORD = 2; + +// In 16-bit local mode, we have the option of using signed saturated +// arithmetic. Because we have signed arithmetic, there's no need to +// add/subtract bias when building an applying the query profile. The lowest +// value we can use is 0x8000, greatest is 0x7fff. + +typedef int16_t TCScore; + +/** + * Build query profile look up tables for the read. The query profile look + * up table is organized as a 1D array indexed by [i][j] where i is the + * reference character in the current DP column (0=A, 1=C, etc), and j is + * the segment of the query we're currently working on. + */ +void SwAligner::buildQueryProfileLocalSseI16(bool fw) { + bool& done = fw ? sseI16fwBuilt_ : sseI16rcBuilt_; + if(done) { + return; + } + done = true; + const BTDnaString* rd = fw ? rdfw_ : rdrc_; + const BTString* qu = fw ? qufw_ : qurc_; + const size_t len = rd->length(); + const size_t seglen = (len + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; + // How many __m128i's are needed + size_t n128s = + 64 + // slack bytes, for alignment? + (seglen * ALPHA_SIZE) // query profile data + * 2; // & gap barrier data + assert_gt(n128s, 0); + SSEData& d = fw ? sseI16fw_ : sseI16rc_; + d.profbuf_.resizeNoCopy(n128s); + assert(!d.profbuf_.empty()); + d.maxPen_ = d.maxBonus_ = 0; + d.lastIter_ = d.lastWord_ = 0; + d.qprofStride_ = d.gbarStride_ = 2; + d.bias_ = 0; // no bias when words are signed + // For each reference character A, C, G, T, N ... + for(size_t refc = 0; refc < ALPHA_SIZE; refc++) { + // For each segment ... + for(size_t i = 0; i < seglen; i++) { + size_t j = i; + int16_t *qprofWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2)); + int16_t *gbarWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2) + 1); + // For each sub-word (byte) ... + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + int sc = 0; + *gbarWords = 0; + if(j < len) { + int readc = (*rd)[j]; + int readq = (*qu)[j]; + sc = sc_->score(readc, (int)(1 << refc), readq - 33); + size_t j_from_end = len - j - 1; + if(j < (size_t)sc_->gapbar || + j_from_end < (size_t)sc_->gapbar) + { + // Inside the gap barrier + *gbarWords = 0x8000; // add this twice + } + } + if(refc == 0 && j == len-1) { + // Remember which 128-bit word and which smaller word has + // the final row + d.lastIter_ = i; + d.lastWord_ = k; + } + if(sc < 0) { + if((size_t)(-sc) > d.maxPen_) { + d.maxPen_ = (size_t)(-sc); + } + } else { + if((size_t)sc > d.maxBonus_) { + d.maxBonus_ = (size_t)sc; + } + } + *qprofWords = (int16_t)sc; + gbarWords++; + qprofWords++; + j += seglen; // update offset into query + } + } + } +} + +#ifndef NDEBUG +/** + * Return true iff the cell has sane E/F/H values w/r/t its predecessors. + */ +static bool cellOkLocalI16( + SSEData& d, + size_t row, + size_t col, + int refc, + int readc, + int readq, + const Scoring& sc) // scoring scheme +{ + TCScore floorsc = MIN_I16; + TCScore ceilsc = MIN_I16-1; + TAlScore offsetsc = 0x8000; + TAlScore sc_h_cur = (TAlScore)d.mat_.helt(row, col); + TAlScore sc_e_cur = (TAlScore)d.mat_.eelt(row, col); + TAlScore sc_f_cur = (TAlScore)d.mat_.felt(row, col); + if(sc_h_cur > floorsc) { + sc_h_cur += offsetsc; + } + if(sc_e_cur > floorsc) { + sc_e_cur += offsetsc; + } + if(sc_f_cur > floorsc) { + sc_f_cur += offsetsc; + } + bool gapsAllowed = true; + size_t rowFromEnd = d.mat_.nrow() - row - 1; + if(row < (size_t)sc.gapbar || rowFromEnd < (size_t)sc.gapbar) { + gapsAllowed = false; + } + bool e_left_trans = false, h_left_trans = false; + bool f_up_trans = false, h_up_trans = false; + bool h_diag_trans = false; + if(gapsAllowed) { + TAlScore sc_h_left = floorsc; + TAlScore sc_e_left = floorsc; + TAlScore sc_h_up = floorsc; + TAlScore sc_f_up = floorsc; + if(col > 0 && sc_e_cur > floorsc && sc_e_cur <= ceilsc) { + sc_h_left = d.mat_.helt(row, col-1) + offsetsc; + sc_e_left = d.mat_.eelt(row, col-1) + offsetsc; + e_left_trans = (sc_e_left > floorsc && sc_e_cur == sc_e_left - sc.readGapExtend()); + h_left_trans = (sc_h_left > floorsc && sc_e_cur == sc_h_left - sc.readGapOpen()); + assert(e_left_trans || h_left_trans); + } + if(row > 0 && sc_f_cur > floorsc && sc_f_cur <= ceilsc) { + sc_h_up = d.mat_.helt(row-1, col) + offsetsc; + sc_f_up = d.mat_.felt(row-1, col) + offsetsc; + f_up_trans = (sc_f_up > floorsc && sc_f_cur == sc_f_up - sc.refGapExtend()); + h_up_trans = (sc_h_up > floorsc && sc_f_cur == sc_h_up - sc.refGapOpen()); + assert(f_up_trans || h_up_trans); + } + } else { + assert_geq(floorsc, sc_e_cur); + assert_geq(floorsc, sc_f_cur); + } + if(col > 0 && row > 0 && sc_h_cur > floorsc && sc_h_cur <= ceilsc) { + TAlScore sc_h_upleft = d.mat_.helt(row-1, col-1) + offsetsc; + TAlScore sc_diag = sc.score(readc, (int)refc, readq - 33); + h_diag_trans = sc_h_cur == sc_h_upleft + sc_diag; + } + assert( + sc_h_cur <= floorsc || + e_left_trans || + h_left_trans || + f_up_trans || + h_up_trans || + h_diag_trans || + sc_h_cur > ceilsc || + row == 0 || + col == 0); + return true; +} +#endif /*ndef NDEBUG*/ + +#ifdef NDEBUG + +#define assert_all_eq0(x) +#define assert_all_gt(x, y) +#define assert_all_gt_lo(x) +#define assert_all_lt(x, y) +#define assert_all_lt_hi(x) + +#else + +#define assert_all_eq0(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpeq_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt(x, y) { \ + __m128i tmp = _mm_cmpgt_epi16(x, y); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt_lo(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpgt_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt(x, y) { \ + __m128i tmp = _mm_cmplt_epi16(x, y); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_leq(x, y) { \ + __m128i tmp = _mm_cmpgt_epi16(x, y); \ + assert_eq(0x0000, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt_hi(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_cmpeq_epi16(z, z); \ + z = _mm_srli_epi16(z, 1); \ + tmp = _mm_cmplt_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} +#endif + +/** + * Aligns by filling a dynamic programming matrix with the SSE-accelerated, + * banded DP approach of Farrar. As it goes, it determines which cells we + * might backtrace from and tallies the best (highest-scoring) N backtrace + * candidate cells per diagonal. Also returns the alignment score of the best + * alignment in the matrix. + * + * This routine does *not* maintain a matrix holding the entire matrix worth of + * scores, nor does it maintain any other dense O(mn) data structure, as this + * would quickly exhaust memory for queries longer than about 10,000 kb. + * Instead, in the fill stage it maintains two columns worth of scores at a + * time (current/previous, or right/left) - these take O(m) space. When + * finished with the current column, it determines which cells from the + * previous column, if any, are candidates we might backtrace from to find a + * full alignment. A candidate cell has a score that rises above the threshold + * and isn't improved upon by a match in the next column. The best N + * candidates per diagonal are stored in a O(m + n) data structure. + */ +TAlScore SwAligner::alignGatherLoc16(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert_gt(minsc_, 0); + assert_leq(minsc_, MAX_I16); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + if(!debug) met.dp++; + buildQueryProfileLocalSseI16(fw_); + assert(!d.profbuf_.empty()); + + assert_gt(d.maxBonus_, 0); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + // Now set up the score vectors. We just need two columns worth, which + // we'll call "left" and "right". + d.vecbuf_.resize(ROWSTRIDE_2COL * iter * 2); + d.vecbuf_.zero(); + __m128i *vbuf_l = d.vecbuf_.ptr(); + __m128i *vbuf_r = d.vecbuf_.ptr() + (ROWSTRIDE_2COL * iter); + + // This is the data structure that holds candidate cells per diagonal. + const size_t ndiags = rff_ - rfi_ + dpRows() - 1; + if(!debug) { + btdiag_.init(ndiags, 2); + } + + // Data structure that holds checkpointed anti-diagonals + TAlScore perfectScore = sc_->perfectScore(dpRows()); + bool checkpoint = true; + bool cpdebug = false; +#ifndef NDEBUG + cpdebug = dpRows() < 1000; +#endif + cper_.init( + dpRows(), // # rows + rff_ - rfi_, // # columns + cperPerPow2_, // checkpoint every 1 << perpow2 diags (& next) + perfectScore, // perfect score (for sanity checks) + false, // matrix cells have 8-bit scores? + cperTri_, // triangular mini-fills? + true, // alignment is local? + cpdebug); // save all cells for debugging? + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i vlolsw = _mm_setzero_si128(); + __m128i vmax = _mm_setzero_si128(); + __m128i vcolmax = _mm_setzero_si128(); + __m128i vmaxtmp = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); + __m128i vhd = _mm_setzero_si128(); + __m128i vhdtmp = _mm_setzero_si128(); + __m128i vtmp = _mm_setzero_si128(); + __m128i vzero = _mm_setzero_si128(); + __m128i vminsc = _mm_setzero_si128(); + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_I16); + rfgapo = _mm_insert_epi16(rfgapo, sc_->refGapOpen(), 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_I16); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + rfgape = _mm_insert_epi16(rfgape, sc_->refGapExtend(), 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_I16); + rdgapo = _mm_insert_epi16(rdgapo, sc_->readGapOpen(), 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_I16); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + rdgape = _mm_insert_epi16(rdgape, sc_->readGapExtend(), 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + // Set all elts to minimum score threshold. Actually, to 1 less than the + // threshold so we can use gt instead of geq. + vminsc = _mm_insert_epi16(vminsc, (int)minsc_-1, 0); + vminsc = _mm_shufflelo_epi16(vminsc, 0); + vminsc = _mm_shuffle_epi32(vminsc, 0); + + // Set all elts to 0x8000 (min value for signed 16-bit) + vlo = _mm_cmpeq_epi16(vlo, vlo); // all elts = 0xffff + vlo = _mm_slli_epi16(vlo, NBITS_PER_WORD-1); // all elts = 0x8000 + + // Set all elts to 0x7fff (max value for signed 16-bit) + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vhi = _mm_srli_epi16(vhi, 1); // all elts = 0x7fff + + // Set all elts to 0x8000 (min value for signed 16-bit) + vmax = vlo; + + // vlolsw: topmost (least sig) word set to 0x8000, all other words=0 + vlolsw = _mm_shuffle_epi32(vlo, 0); + vlolsw = _mm_srli_si128(vlolsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + const size_t colstride = ROWSTRIDE_2COL * iter; + + // Initialize the H and E vectors in the first matrix column + __m128i *pvELeft = vbuf_l + 0; __m128i *pvERight = vbuf_r + 0; + //__m128i *pvFLeft = vbuf_l + 1; + __m128i *pvFRight = vbuf_r + 1; + __m128i *pvHLeft = vbuf_l + 2; __m128i *pvHRight = vbuf_r + 2; + + for(size_t i = 0; i < iter; i++) { + // start low in local mode + _mm_store_si128(pvERight, vlo); pvERight += ROWSTRIDE_2COL; + _mm_store_si128(pvHRight, vlo); pvHRight += ROWSTRIDE_2COL; + // Note: right and left are going to be swapped as soon as we enter + // the outer loop below + } + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + TAlScore matchsc = sc_->match(30); + TAlScore leftmax = MIN_I64; + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + size_t off = MAX_SIZE_T, lastoff; + bool bailed = false; + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + // Swap left and right; vbuf_l is the vector on the left, which we + // generally load from, and vbuf_r is the vector on the right, which we + // generally store to. + swap(vbuf_l, vbuf_r); + pvELeft = vbuf_l + 0; pvERight = vbuf_r + 0; + /* pvFLeft = vbuf_l + 1; */ pvFRight = vbuf_r + 1; + pvHLeft = vbuf_l + 2; pvHRight = vbuf_r + 2; + + // Fetch this column's reference mask + const int refm = (int)rf_[i]; + + // Fetch the appropriate query profile + lastoff = off; + off = (size_t)firsts5[refm] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Load H vector from the final row of the previous column. + // ??? perhaps we should calculate the next iter's F instead of the + // current iter's? The way we currently do it, seems like it will + // almost always require at least one fixup loop iter (to recalculate + // this topmost F). + vh = _mm_load_si128(pvHLeft + colstride - ROWSTRIDE_2COL); + + // Set all F cells to low value + vf = _mm_cmpeq_epi16(vf, vf); + vf = _mm_slli_epi16(vf, NBITS_PER_WORD-1); + vf = _mm_or_si128(vf, vlolsw); + // vf now contains the vertical contribution + + // Store cells in F, calculated previously + // No need to veto ref gap extensions, they're all 0x8000s + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Shift down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + // Fill topmost (least sig) cell with low value + vh = _mm_or_si128(vh, vlolsw); + + // We pull out one loop iteration to make it easier to veto values in the top row + + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELeft); + vhd = _mm_load_si128(pvHLeft); + assert_all_lt(ve, vhi); + pvELeft += ROWSTRIDE_2COL; + // ve now contains the horizontal contribution + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epi16(vh, pvScore[0]); + // vh now contains the diagonal contribution + + // Update vE value + vhdtmp = vhd; + vhd = _mm_subs_epi16(vhd, rdgapo); + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epi16(ve, rdgape); + ve = _mm_max_epi16(ve, vhd); + + // Update H, factoring in E and F + vh = _mm_max_epi16(vh, ve); + // F won't change anything! + + vf = vh; + + // Update highest score so far + vcolmax = vh; + + // Save the new vH values + _mm_store_si128(pvHRight, vh); + + assert_all_lt(ve, vhi); + + vh = vhdtmp; + + assert_all_lt(ve, vhi); + pvHRight += ROWSTRIDE_2COL; + pvHLeft += ROWSTRIDE_2COL; + + // Save E values + _mm_store_si128(pvERight, ve); + pvERight += ROWSTRIDE_2COL; + + // Update vf value + vf = _mm_subs_epi16(vf, rfgapo); + assert_all_lt(vf, vhi); + + pvScore += 2; // move on to next query profile + + // For each character in the reference text: + size_t j; + for(j = 1; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELeft); + vhd = _mm_load_si128(pvHLeft); + assert_all_lt(ve, vhi); + pvELeft += ROWSTRIDE_2COL; + + // Store cells in F, calculated previously + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epi16(vh, pvScore[0]); + vh = _mm_max_epi16(vh, vf); + + // Update vE value + vhdtmp = vhd; + vhd = _mm_subs_epi16(vhd, rdgapo); + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + vhd = _mm_adds_epi16(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epi16(ve, rdgape); + ve = _mm_max_epi16(ve, vhd); + + vh = _mm_max_epi16(vh, ve); + vtmp = vh; + + // Update highest score encountered this far + vcolmax = _mm_max_epi16(vcolmax, vh); + + // Save the new vH values + _mm_store_si128(pvHRight, vh); + + vh = vhdtmp; + + assert_all_lt(ve, vhi); + pvHRight += ROWSTRIDE_2COL; + pvHLeft += ROWSTRIDE_2COL; + + // Save E values + _mm_store_si128(pvERight, ve); + pvERight += ROWSTRIDE_2COL; + + // Update vf value + vtmp = _mm_subs_epi16(vtmp, rfgapo); + vf = _mm_subs_epi16(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epi16(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFRight -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFRight); + + pvHRight -= colstride; // reset to start of column + vh = _mm_load_si128(pvHRight); + + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0x0000) { + // Store this vf + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Update vh w/r/t new vf + vh = _mm_max_epi16(vh, vf); + + // Save vH values + _mm_store_si128(pvHRight, vh); + pvHRight += ROWSTRIDE_2COL; + + // Update highest score encountered so far. + vcolmax = _mm_max_epi16(vcolmax, vh); + + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFRight -= colstride; + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + pvHRight -= colstride; + vh = _mm_load_si128(pvHRight); // load next vh ASAP + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + } else { + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + vh = _mm_load_si128(pvHRight); // load next vh ASAP + } + + // Update F with another gap extension + vf = _mm_subs_epi16(vf, rfgape); + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + + // Now we'd like to know exactly which cells in the left column are + // candidates we might backtrace from. First question is: did *any* + // elements in the column exceed the minimum score threshold? + if(!debug && leftmax >= minsc_) { + // Yes. Next question is: which cells are candidates? We have to + // allow matches in the right column to override matches above and + // to the left in the left column. + assert_gt(i - rfi_, 0); + pvHLeft = vbuf_l + 2; + assert_lt(lastoff, MAX_SIZE_T); + pvScore = d.profbuf_.ptr() + lastoff; // even elts = query profile, odd = gap barrier + for(size_t k = 0; k < iter; k++) { + vh = _mm_load_si128(pvHLeft); + vtmp = _mm_cmpgt_epi16(pvScore[0], vzero); + int cmp = _mm_movemask_epi8(vtmp); + if(cmp != 0) { + // At least one candidate in this mask. Now iterate + // through vm/vh to evaluate individual cells. + for(size_t m = 0; m < NWORDS_PER_REG; m++) { + size_t row = k + m * iter; + if(row >= dpRows()) { + break; + } + TAlScore sc = (TAlScore)(((TCScore *)&vh)[m] + 0x8000); + if(sc >= minsc_) { + if(((TCScore *)&vtmp)[m] != 0) { + // Add to data structure holding all candidates + size_t col = i - rfi_ - 1; // -1 b/c prev col + size_t frombot = dpRows() - row - 1; + DpBtCandidate cand(row, col, sc); + btdiag_.add(frombot + col, cand); + } + } + } + } + pvHLeft += ROWSTRIDE_2COL; + pvScore += 2; + } + } + + // Save some elements to checkpoints + if(checkpoint) { + + __m128i *pvE = vbuf_r + 0; + __m128i *pvF = vbuf_r + 1; + __m128i *pvH = vbuf_r + 2; + size_t coli = i - rfi_; + if(coli < cper_.locol_) cper_.locol_ = coli; + if(coli > cper_.hicol_) cper_.hicol_ = coli; + + if(cperTri_) { + size_t rc_mod = coli & cper_.lomask_; + assert_lt(rc_mod, cper_.per_); + int64_t row = -(int64_t)rc_mod-1; + int64_t row_mod = row; + int64_t row_div = 0; + size_t idx = coli >> cper_.perpow2_; + size_t idxrow = idx * cper_.nrow_; + assert_eq(4, ROWSTRIDE_2COL); + bool done = false; + while(true) { + row += (cper_.per_ - 2); + row_mod += (cper_.per_ - 2); + for(size_t j = 0; j < 2; j++) { + row++; + row_mod++; + if(row >= 0 && (size_t)row < cper_.nrow_) { + // Update row divided by iter_ and mod iter_ + while(row_mod >= (int64_t)iter) { + row_mod -= (int64_t)iter; + row_div++; + } + size_t delt = idxrow + row; + size_t vecoff = (row_mod << 5) + row_div; + assert_lt(row_div, 8); + int16_t h_sc = ((int16_t*)pvH)[vecoff]; + int16_t e_sc = ((int16_t*)pvE)[vecoff]; + int16_t f_sc = ((int16_t*)pvF)[vecoff]; + h_sc += 0x8000; assert_geq(h_sc, 0); + e_sc += 0x8000; assert_geq(e_sc, 0); + f_sc += 0x8000; assert_geq(f_sc, 0); + assert_leq(h_sc, cper_.perf_); + assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad *qdiags = ((j == 0) ? cper_.qdiag1s_.ptr() : cper_.qdiag2s_.ptr()); + qdiags[delt].sc[0] = h_sc; + qdiags[delt].sc[1] = e_sc; + qdiags[delt].sc[2] = f_sc; + } // if(row >= 0 && row < nrow_) + else if(row >= 0 && (size_t)row >= cper_.nrow_) { + done = true; + break; + } + } // end of loop over anti-diags + if(done) { + break; + } + idx++; + idxrow += cper_.nrow_; + } + } else { + // If this is the first column, take this opportunity to + // pre-calculate the coordinates of the elements we're going to + // checkpoint. + if(coli == 0) { + size_t cpi = cper_.per_-1; + size_t cpimod = cper_.per_-1; + size_t cpidiv = 0; + cper_.commitMap_.clear(); + while(cpi < cper_.nrow_) { + while(cpimod >= iter) { + cpimod -= iter; + cpidiv++; + } + size_t vecoff = (cpimod << 5) + cpidiv; + cper_.commitMap_.push_back(vecoff); + cpi += cper_.per_; + cpimod += cper_.per_; + } + } + // Save all the rows + size_t rowoff = 0; + size_t sz = cper_.commitMap_.size(); + for(size_t i = 0; i < sz; i++, rowoff += cper_.ncol_) { + size_t vecoff = cper_.commitMap_[i]; + int16_t h_sc = ((int16_t*)pvH)[vecoff]; + //int16_t e_sc = ((int16_t*)pvE)[vecoff]; + int16_t f_sc = ((int16_t*)pvF)[vecoff]; + h_sc += 0x8000; assert_geq(h_sc, 0); + //e_sc += 0x8000; assert_geq(e_sc, 0); + f_sc += 0x8000; assert_geq(f_sc, 0); + assert_leq(h_sc, cper_.perf_); + //assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad& dst = cper_.qrows_[rowoff + coli]; + dst.sc[0] = h_sc; + //dst.sc[1] = e_sc; + dst.sc[2] = f_sc; + } + // Is this a column we'd like to checkpoint? + if((coli & cper_.lomask_) == cper_.lomask_) { + // Save the column using memcpys + assert_gt(coli, 0); + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = (coli >> cper_.perpow2_) * wordspercol; + __m128i *dst = cper_.qcols_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + if(cper_.debug_) { + // Save the column using memcpys + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = coli * wordspercol; + __m128i *dst = cper_.qcolsD_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + + vmax = _mm_max_epi16(vmax, vcolmax); + { + // Get single largest score in this column + vmaxtmp = vcolmax; + vtmp = _mm_srli_si128(vmaxtmp, 8); + vmaxtmp = _mm_max_epi16(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 4); + vmaxtmp = _mm_max_epi16(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 2); + vmaxtmp = _mm_max_epi16(vmaxtmp, vtmp); + int16_t ret = _mm_extract_epi16(vmaxtmp, 0); + TAlScore score = (TAlScore)(ret + 0x8000); + if(ret == MIN_I16) { + score = MIN_I64; + } + + if(score < minsc_) { + size_t ncolleft = rff_ - i - 1; + if(max(score, 0) + (TAlScore)ncolleft * matchsc < minsc_) { + // Bail! There can't possibly be a valid alignment that + // passes through this column. + bailed = true; + break; + } + } + + leftmax = score; + } + } + + lastoff = off; + + // Now we'd like to know exactly which cells in the *rightmost* column are + // candidates we might backtrace from. Did *any* elements exceed the + // minimum score threshold? + if(!debug && !bailed && leftmax >= minsc_) { + // Yes. Next question is: which cells are candidates? We have to + // allow matches in the right column to override matches above and + // to the left in the left column. + pvHLeft = vbuf_r + 2; + assert_lt(lastoff, MAX_SIZE_T); + pvScore = d.profbuf_.ptr() + lastoff; // even elts = query profile, odd = gap barrier + for(size_t k = 0; k < iter; k++) { + vh = _mm_load_si128(pvHLeft); + vtmp = _mm_cmpgt_epi16(pvScore[0], vzero); + int cmp = _mm_movemask_epi8(vtmp); + if(cmp != 0) { + // At least one candidate in this mask. Now iterate + // through vm/vh to evaluate individual cells. + for(size_t m = 0; m < NWORDS_PER_REG; m++) { + size_t row = k + m * iter; + if(row >= dpRows()) { + break; + } + TAlScore sc = (TAlScore)(((TCScore *)&vh)[m] + 0x8000); + if(sc >= minsc_) { + if(((TCScore *)&vtmp)[m] != 0) { + // Add to data structure holding all candidates + size_t col = rff_ - rfi_ - 1; // -1 b/c prev col + size_t frombot = dpRows() - row - 1; + DpBtCandidate cand(row, col, sc); + btdiag_.add(frombot + col, cand); + } + } + } + } + pvHLeft += ROWSTRIDE_2COL; + pvScore += 2; + } + } + + // Find largest score in vmax + vtmp = _mm_srli_si128(vmax, 8); + vmax = _mm_max_epi16(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 4); + vmax = _mm_max_epi16(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 2); + vmax = _mm_max_epi16(vmax, vtmp); + int16_t ret = _mm_extract_epi16(vmax, 0); + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + flag = 0; + + // Did we find a solution? + TAlScore score = MIN_I64; + if(ret == MIN_I16) { + flag = -1; // no + if(!debug) met.dpfail++; + return MIN_I64; + } else { + score = (TAlScore)(ret + 0x8000); + if(score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return score; + } + } + + // Could we have saturated? + if(ret == MAX_I16) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Now take all the backtrace candidates in the btdaig_ structure and + // dump them into the btncand_ array. They'll be sorted later. + if(!debug) { + btdiag_.dump(btncand_); + assert(!btncand_.empty()); + } + + // Return largest score + if(!debug) met.dpsucc++; + return score; +} + +/** + * Solve the current alignment problem using SSE instructions that operate on 8 + * signed 16-bit values packed into a single 128-bit register. + */ +TAlScore SwAligner::alignNucleotidesLocalSseI16(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + if(!debug) met.dp++; + buildQueryProfileLocalSseI16(fw_); + assert(!d.profbuf_.empty()); + + assert_gt(d.maxBonus_, 0); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i vlolsw = _mm_setzero_si128(); + __m128i vmax = _mm_setzero_si128(); + __m128i vcolmax = _mm_setzero_si128(); + __m128i vmaxtmp = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); + __m128i vtmp = _mm_setzero_si128(); + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_I16); + rfgapo = _mm_insert_epi16(rfgapo, sc_->refGapOpen(), 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_I16); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + rfgape = _mm_insert_epi16(rfgape, sc_->refGapExtend(), 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_I16); + rdgapo = _mm_insert_epi16(rdgapo, sc_->readGapOpen(), 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_I16); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + rdgape = _mm_insert_epi16(rdgape, sc_->readGapExtend(), 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + // Set all elts to 0x8000 (min value for signed 16-bit) + vlo = _mm_cmpeq_epi16(vlo, vlo); // all elts = 0xffff + vlo = _mm_slli_epi16(vlo, NBITS_PER_WORD-1); // all elts = 0x8000 + + // Set all elts to 0x7fff (max value for signed 16-bit) + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vhi = _mm_srli_epi16(vhi, 1); // all elts = 0x7fff + + // Set all elts to 0x8000 (min value for signed 16-bit) + vmax = vlo; + + // vlolsw: topmost (least sig) word set to 0x8000, all other words=0 + vlolsw = _mm_shuffle_epi32(vlo, 0); + vlolsw = _mm_srli_si128(vlolsw, NBYTES_PER_REG - NBYTES_PER_WORD); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + d.mat_.init(dpRows(), rff_ - rfi_, NWORDS_PER_REG); + const size_t colstride = d.mat_.colstride(); + //const size_t rowstride = d.mat_.rowstride(); + assert_eq(ROWSTRIDE, colstride / iter); + + // Initialize the H and E vectors in the first matrix column + __m128i *pvHTmp = d.mat_.tmpvec(0, 0); + __m128i *pvETmp = d.mat_.evec(0, 0); + + for(size_t i = 0; i < iter; i++) { + _mm_store_si128(pvETmp, vlo); + _mm_store_si128(pvHTmp, vlo); // start low in local mode + pvETmp += ROWSTRIDE; + pvHTmp += ROWSTRIDE; + } + // These are swapped just before the innermost loop + __m128i *pvHStore = d.mat_.hvec(0, 0); + __m128i *pvHLoad = d.mat_.tmpvec(0, 0); + __m128i *pvELoad = d.mat_.evec(0, 0); + __m128i *pvEStore = d.mat_.evecUnsafe(0, 1); + __m128i *pvFStore = d.mat_.fvec(0, 0); + __m128i *pvFTmp = NULL; + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + TAlScore matchsc = sc_->match(30); + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + colstop_ = rff_ - rfi_; + lastsolcol_ = 0; + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert(pvFStore == d.mat_.fvec(0, i - rfi_)); + assert(pvHStore == d.mat_.hvec(0, i - rfi_)); + + // Fetch this column's reference mask + const int refm = (int)rf_[i]; + + // Fetch the appropriate query profile + size_t off = (size_t)firsts5[refm] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Load H vector from the final row of the previous column + vh = _mm_load_si128(pvHLoad + colstride - ROWSTRIDE); + + // Set all F cells to low value + vf = _mm_cmpeq_epi16(vf, vf); + vf = _mm_slli_epi16(vf, NBITS_PER_WORD-1); + vf = _mm_or_si128(vf, vlolsw); + // vf now contains the vertical contribution + + // Store cells in F, calculated previously + // No need to veto ref gap extensions, they're all 0x8000s + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Shift down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + // Fill topmost (least sig) cell with low value + vh = _mm_or_si128(vh, vlolsw); + + // We pull out one loop iteration to make it easier to veto values in the top row + + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELoad); + assert_all_lt(ve, vhi); + pvELoad += ROWSTRIDE; + // ve now contains the horizontal contribution + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epi16(vh, pvScore[0]); + // vh now contains the diagonal contribution + + // Update H, factoring in E and F + vtmp = _mm_max_epi16(vh, ve); + // F won't change anything! + + vh = vtmp; + + // Update highest score so far + vcolmax = vlo; + vcolmax = _mm_max_epi16(vcolmax, vh); + + // Save the new vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update vE value + vf = vh; + vh = _mm_subs_epi16(vh, rdgapo); + vh = _mm_adds_epi16(vh, pvScore[1]); // veto some read gap opens + vh = _mm_adds_epi16(vh, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epi16(ve, rdgape); + ve = _mm_max_epi16(ve, vh); + assert_all_lt(ve, vhi); + + // Load the next h value + vh = _mm_load_si128(pvHLoad); + pvHLoad += ROWSTRIDE; + + // Save E values + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + + // Update vf value + vf = _mm_subs_epi16(vf, rfgapo); + assert_all_lt(vf, vhi); + + pvScore += 2; // move on to next query profile + + // For each character in the reference text: + size_t j; + for(j = 1; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELoad); + assert_all_lt(ve, vhi); + pvELoad += ROWSTRIDE; + + // Store cells in F, calculated previously + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epi16(vh, pvScore[0]); + + // Update H, factoring in E and F + vh = _mm_max_epi16(vh, ve); + vh = _mm_max_epi16(vh, vf); + + // Update highest score encountered this far + vcolmax = _mm_max_epi16(vcolmax, vh); + + // Save the new vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update vE value + vtmp = vh; + vh = _mm_subs_epi16(vh, rdgapo); + vh = _mm_adds_epi16(vh, pvScore[1]); // veto some read gap opens + vh = _mm_adds_epi16(vh, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epi16(ve, rdgape); + ve = _mm_max_epi16(ve, vh); + assert_all_lt(ve, vhi); + + // Load the next h value + vh = _mm_load_si128(pvHLoad); + pvHLoad += ROWSTRIDE; + + // Save E values + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + + // Update vf value + vtmp = _mm_subs_epi16(vtmp, rfgapo); + vf = _mm_subs_epi16(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epi16(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFTmp = pvFStore; + pvFStore -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFStore); + + pvHStore -= colstride; // reset to start of column + vh = _mm_load_si128(pvHStore); + + pvEStore -= colstride; // reset to start of column + ve = _mm_load_si128(pvEStore); + + pvHLoad = pvHStore; // new pvHLoad = pvHStore + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0x0000) { + // Store this vf + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Update vh w/r/t new vf + vh = _mm_max_epi16(vh, vf); + + // Save vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update highest score encountered this far + vcolmax = _mm_max_epi16(vcolmax, vh); + + // Update E in case it can be improved using our new vh + vh = _mm_subs_epi16(vh, rdgapo); + vh = _mm_adds_epi16(vh, *pvScore); // veto some read gap opens + vh = _mm_adds_epi16(vh, *pvScore); // veto some read gap opens + ve = _mm_max_epi16(ve, vh); + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFStore -= colstride; + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + pvHStore -= colstride; + vh = _mm_load_si128(pvHStore); // load next vh ASAP + pvEStore -= colstride; + ve = _mm_load_si128(pvEStore); // load next ve ASAP + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + vf = _mm_or_si128(vf, vlolsw); + } else { + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + vh = _mm_load_si128(pvHStore); // load next vh ASAP + ve = _mm_load_si128(pvEStore); // load next vh ASAP + } + + // Update F with another gap extension + vf = _mm_subs_epi16(vf, rfgape); + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_adds_epi16(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epi16(vtmp, vf); + vtmp = _mm_cmpgt_epi16(vf, vtmp); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + +#ifndef NDEBUG + if((rand() & 15) == 0) { + // This is a work-intensive sanity check; each time we finish filling + // a column, we check that each H, E, and F is sensible. + for(size_t k = 0; k < dpRows(); k++) { + assert(cellOkLocalI16( + d, + k, // row + i - rfi_, // col + refm, // reference mask + (int)(*rd_)[rdi_+k], // read char + (int)(*qu_)[rdi_+k], // read quality + *sc_)); // scoring scheme + } + } +#endif + + // Store column maximum vector in first element of tmp + vmax = _mm_max_epi16(vmax, vcolmax); + _mm_store_si128(d.mat_.tmpvec(0, i - rfi_), vcolmax); + + { + // Get single largest score in this column + vmaxtmp = vcolmax; + vtmp = _mm_srli_si128(vmaxtmp, 8); + vmaxtmp = _mm_max_epi16(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 4); + vmaxtmp = _mm_max_epi16(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 2); + vmaxtmp = _mm_max_epi16(vmaxtmp, vtmp); + int16_t ret = _mm_extract_epi16(vmaxtmp, 0); + TAlScore score = (TAlScore)(ret + 0x8000); + + if(score < minsc_) { + size_t ncolleft = rff_ - i - 1; + if(score + (TAlScore)ncolleft * matchsc < minsc_) { + // Bail! We're guaranteed not to see a valid alignment in + // the rest of the matrix + colstop_ = (i+1) - rfi_; + break; + } + } else { + lastsolcol_ = i - rfi_; + } + } + + // pvELoad and pvHLoad are already where they need to be + + // Adjust the load and store vectors here. + pvHStore = pvHLoad + colstride; + pvEStore = pvELoad + colstride; + pvFStore = pvFTmp; + } + + // Find largest score in vmax + vtmp = _mm_srli_si128(vmax, 8); + vmax = _mm_max_epi16(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 4); + vmax = _mm_max_epi16(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 2); + vmax = _mm_max_epi16(vmax, vtmp); + int16_t ret = _mm_extract_epi16(vmax, 0); + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + flag = 0; + + // Did we find a solution? + TAlScore score = MIN_I64; + if(ret == MIN_I16) { + flag = -1; // no + if(!debug) met.dpfail++; + return MIN_I64; + } else { + score = (TAlScore)(ret + 0x8000); + if(score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return score; + } + } + + // Could we have saturated? + if(ret == MAX_I16) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Return largest score + if(!debug) met.dpsucc++; + return score; +} + +/** + * Given a filled-in DP table, populate the btncand_ list with candidate cells + * that might be at the ends of valid alignments. No need to do this unless + * the maximum score returned by the align*() func is >= the minimum. + * + * We needn't consider cells that have no chance of reaching any of the core + * diagonals. These are the cells that are more than 'maxgaps' cells away from + * a core diagonal. + * + * We need to be careful to consider that the rectangle might be truncated on + * one or both ends. + * + * The seed extend case looks like this: + * + * |Rectangle| 0: seed diagonal + * **OO0oo---- o: "RHS gap" diagonals + * -**OO0oo--- O: "LHS gap" diagonals + * --**OO0oo-- *: "LHS extra" diagonals + * ---**OO0oo- -: cells that can't possibly be involved in a valid + * ----**OO0oo alignment that overlaps one of the core diagonals + * + * The anchor-to-left case looks like this: + * + * |Anchor| | ---- Rectangle ---- | + * o---------OO0000000000000oo------ 0: mate diagonal (also core diags!) + * -o---------OO0000000000000oo----- o: "RHS gap" diagonals + * --o---------OO0000000000000oo---- O: "LHS gap" diagonals + * ---oo--------OO0000000000000oo--- *: "LHS extra" diagonals + * -----o--------OO0000000000000oo-- -: cells that can't possibly be + * ------o--------OO0000000000000oo- involved in a valid alignment that + * -------o--------OO0000000000000oo overlaps one of the core diagonals + * XXXXXXXXXXXXX + * | RHS Range | + * ^ ^ + * rl rr + * + * The anchor-to-right case looks like this: + * + * ll lr + * v v + * | LHS Range | + * XXXXXXXXXXXXX |Anchor| + * OO0000000000000oo--------o-------- 0: mate diagonal (also core diags!) + * -OO0000000000000oo--------o------- o: "RHS gap" diagonals + * --OO0000000000000oo--------o------ O: "LHS gap" diagonals + * ---OO0000000000000oo--------oo---- *: "LHS extra" diagonals + * ----OO0000000000000oo---------o--- -: cells that can't possibly be + * -----OO0000000000000oo---------o-- involved in a valid alignment that + * ------OO0000000000000oo---------o- overlaps one of the core diagonals + * | ---- Rectangle ---- | + */ +bool SwAligner::gatherCellsNucleotidesLocalSseI16(TAlScore best) { + // What's the minimum number of rows that can possibly be spanned by an + // alignment that meets the minimum score requirement? + assert(sse16succ_); + size_t bonus = (size_t)sc_->match(30); + const size_t ncol = lastsolcol_ + 1; + const size_t nrow = dpRows(); + assert_gt(nrow, 0); + btncand_.clear(); + btncanddone_.clear(); + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + assert(!d.profbuf_.empty()); + //const size_t rowstride = d.mat_.rowstride(); + //const size_t colstride = d.mat_.colstride(); + size_t iter = (dpRows() + (NWORDS_PER_REG - 1)) / NWORDS_PER_REG; + assert_gt(iter, 0); + assert_geq(minsc_, 0); + assert_gt(bonus, 0); + size_t minrow = (size_t)(((minsc_ + bonus - 1) / bonus) - 1); + for(size_t j = 0; j < ncol; j++) { + // Establish the range of rows where a backtrace from the cell in this + // row/col is close enough to one of the core diagonals that it could + // conceivably count + size_t nrow_lo = MIN_SIZE_T; + size_t nrow_hi = nrow; + // First, check if there is a cell in this column with a score + // above the score threshold + __m128i vmax = *d.mat_.tmpvec(0, j); + __m128i vtmp = _mm_srli_si128(vmax, 8); + vmax = _mm_max_epi16(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 4); + vmax = _mm_max_epi16(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 2); + vmax = _mm_max_epi16(vmax, vtmp); + TAlScore score = (TAlScore)((int16_t)_mm_extract_epi16(vmax, 0) + 0x8000); + assert_geq(score, 0); +#ifndef NDEBUG + { + // Start in upper vector row and move down + TAlScore max = 0; + vmax = *d.mat_.tmpvec(0, j); + __m128i *pvH = d.mat_.hvec(0, j); + for(size_t i = 0; i < iter; i++) { + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + TAlScore sc = (TAlScore)(((TCScore*)pvH)[k] + 0x8000); + TAlScore scm = (TAlScore)(((TCScore*)&vmax)[k] + 0x8000); + assert_leq(sc, scm); + if(sc > max) { + max = sc; + } + } + pvH += ROWSTRIDE; + } + assert_eq(max, score); + } +#endif + if(score < minsc_) { + // Scores in column aren't good enough + continue; + } + // Get pointer to first cell in column to examine: + __m128i *pvHorig = d.mat_.hvec(0, j); + __m128i *pvH = pvHorig; + // Get pointer to the vector in the following column that corresponds + // to the cells diagonally down and to the right from the cells in pvH + __m128i *pvHSucc = (j < ncol-1) ? d.mat_.hvec(0, j+1) : NULL; + // Start in upper vector row and move down + for(size_t i = 0; i < iter; i++) { + if(pvHSucc != NULL) { + pvHSucc += ROWSTRIDE; + if(i == iter-1) { + pvHSucc = d.mat_.hvec(0, j+1); + } + } + // Which elements of this vector are exhaustively scored? + size_t rdoff = i; + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + // Is this row, col one that we can potential backtrace from? + // I.e. are we close enough to a core diagonal? + if(rdoff >= nrow_lo && rdoff < nrow_hi) { + // This cell has been exhaustively scored + if(rdoff >= minrow) { + // ... and it could potentially score high enough + TAlScore sc = (TAlScore)(((TCScore*)pvH)[k] + 0x8000); + assert_leq(sc, best); + if(sc >= minsc_) { + // This is a potential solution + bool matchSucc = false; + int readc = (*rd_)[rdoff]; + int refc = rf_[j + rfi_]; + bool match = ((refc & (1 << readc)) != 0); + if(rdoff < dpRows()-1) { + int readcSucc = (*rd_)[rdoff+1]; + int refcSucc = rf_[j + rfi_ + 1]; + assert_range(0, 16, refcSucc); + matchSucc = ((refcSucc & (1 << readcSucc)) != 0); + } + if(match && !matchSucc) { + // Yes, this is legit + met.gathsol++; + btncand_.expand(); + btncand_.back().init(rdoff, j, sc); + } + } + } + } else { + // Already saw every element in the vector that's been + // exhaustively scored + break; + } + rdoff += iter; + } + pvH += ROWSTRIDE; + } + } + if(!btncand_.empty()) { + d.mat_.initMasks(); + } + return !btncand_.empty(); +} + +#define MOVE_VEC_PTR_UP(vec, rowvec, rowelt) { \ + if(rowvec == 0) { \ + rowvec += d.mat_.nvecrow_; \ + vec += d.mat_.colstride_; \ + rowelt--; \ + } \ + rowvec--; \ + vec -= ROWSTRIDE; \ +} + +#define MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt) { vec -= d.mat_.colstride_; } + +#define MOVE_VEC_PTR_UPLEFT(vec, rowvec, rowelt) { \ + MOVE_VEC_PTR_UP(vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt); \ +} + +#define MOVE_ALL_LEFT() { \ + MOVE_VEC_PTR_LEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_LEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UP() { \ + MOVE_VEC_PTR_UP(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UP(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UP(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UPLEFT() { \ + MOVE_VEC_PTR_UPLEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UPLEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UPLEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UPLEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define NEW_ROW_COL(row, col) { \ + rowelt = row / d.mat_.nvecrow_; \ + rowvec = row % d.mat_.nvecrow_; \ + eltvec = (col * d.mat_.colstride_) + (rowvec * ROWSTRIDE); \ + cur_vec = d.mat_.matbuf_.ptr() + eltvec; \ + left_vec = cur_vec; \ + left_rowelt = rowelt; \ + left_rowvec = rowvec; \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + up_vec = cur_vec; \ + up_rowelt = rowelt; \ + up_rowvec = rowvec; \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + upleft_vec = up_vec; \ + upleft_rowelt = up_rowelt; \ + upleft_rowvec = up_rowvec; \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +/** + * Given the dynamic programming table and a cell, trace backwards from the + * cell and install the edits and score/penalty in the appropriate fields of + * res. The RandomSource is used to break ties among equally good ways of + * tracing back. + * + * Whenever we enter a cell, we check if its read/ref coordinates correspond to + * a cell we traversed constructing a previous alignment. If so, we backtrack + * to the last decision point, mask out the path that led to the previously + * observed cell, and continue along a different path. If there are no more + * paths to try, we stop. + * + * If an alignment is found, 'off' is set to the alignment's upstream-most + * reference character's offset and true is returned. Otherwise, false is + * returned. + * + * In local alignment mode, this method is liable to be slow, especially for + * long reads. This is chiefly because if there is one valid solution + * (especially if it is pretty high scoring), then many, many paths shooting + * off that solution's path will also have valid solutions. + */ +bool SwAligner::backtraceNucleotidesLocalSseI16( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this row + size_t col, // start in this column + RandomSource& rnd) // random gen, to choose among equal paths +{ + assert_lt(row, dpRows()); + assert_lt(col, (size_t)(rff_ - rfi_)); + SSEData& d = fw_ ? sseI16fw_ : sseI16rc_; + SSEMetrics& met = extend_ ? sseI16ExtendMet_ : sseI16MateMet_; + met.bt++; + assert(!d.profbuf_.empty()); + assert_lt(row, rd_->length()); + btnstack_.clear(); // empty the backtrack stack + btcells_.clear(); // empty the cells-so-far list + AlnScore score; + score.score_ = score.gaps_ = score.ns_ = 0; + size_t origCol = col; + size_t gaps = 0, readGaps = 0, refGaps = 0; + res.alres.reset(); + EList& ned = res.alres.ned(); + assert(ned.empty()); + assert_gt(dpRows(), row); + size_t trimEnd = dpRows() - row - 1; + size_t trimBeg = 0; + size_t ct = SSEMatrix::H; // cell type + // Row and col in terms of where they fall in the SSE vector matrix + size_t rowelt, rowvec, eltvec; + size_t left_rowelt, up_rowelt, upleft_rowelt; + size_t left_rowvec, up_rowvec, upleft_rowvec; + __m128i *cur_vec, *left_vec, *up_vec, *upleft_vec; + const size_t gbar = sc_->gapbar; + NEW_ROW_COL(row, col); + // If 'backEliminate' is true, then every time we visit a cell, we remove + // edges into the cell. We do this to avoid some of the thrashing around + // that occurs when there are lots of valid candidates in the same DP + // problem. + //const bool backEliminate = true; + while((int)row >= 0) { + // TODO: As soon as we enter a cell, set it as being reported through, + // *and* mark all cells that point into this cell as being reported + // through. This will save us from having to consider quite so many + // candidates. + + met.btcell++; + nbts++; + int readc = (*rd_)[rdi_ + row]; + int refm = (int)rf_[rfi_ + col]; + int readq = (*qu_)[row]; + assert_leq(col, origCol); + // Get score in this cell + bool empty = false, reportedThru, canMoveThru, branch = false; + int cur = SSEMatrix::H; + if(!d.mat_.reset_[row]) { + d.mat_.resetRow(row); + } + reportedThru = d.mat_.reportedThrough(row, col); + canMoveThru = true; + if(reportedThru) { + canMoveThru = false; + } else { + empty = false; + if(row > 0) { + size_t rowFromEnd = d.mat_.nrow() - row - 1; + bool gapsAllowed = !(row < gbar || rowFromEnd < gbar); + const int floorsc = 0; + const int offsetsc = 0x8000; + // Move to beginning of column/row + if(ct == SSEMatrix::E) { // AKA rdgap + assert_gt(col, 0); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::E))[rowelt] + offsetsc; + assert(gapsAllowed); + // Currently in the E matrix; incoming transition must come from the + // left. It's either a gap open from the H matrix or a gap extend from + // the E matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell to the left + TAlScore sc_h_left = ((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc; + if(sc_h_left > floorsc && sc_h_left - sc_->readGapOpen() == sc_cur) { + mask |= (1 << 0); // horiz H -> E move possible + } + // Get E score of cell to the left + TAlScore sc_e_left = ((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc; + if(sc_e_left > floorsc && sc_e_left - sc_->readGapExtend() == sc_cur) { + mask |= (1 << 1); // horiz E -> E move possible + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isEMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 8) & 3; + } + if(mask == 3) { + // Horiz H -> E or horiz E -> E moves possible +#if 1 + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later + } else { + // Pick E -> E cell + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 1); // might choose H later + } +#endif + branch = true; + } else if(mask == 2) { + // Only horiz E -> E move possible, pick it + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + if(!branch) { + // Is this where we can eliminate some incoming paths as well? + } + assert(!empty || !canMoveThru); + } else if(ct == SSEMatrix::F) { // AKA rfgap + assert_gt(row, 0); + assert(gapsAllowed); + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::F))[rowelt] + offsetsc; + // Currently in the F matrix; incoming transition must come from above. + // It's either a gap open from the H matrix or a gap extend from the F + // matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell above + if(sc_h_up > floorsc && sc_h_up - sc_->refGapOpen() == sc_cur) { + mask |= (1 << 0); + } + // Get F score of cell above + if(sc_f_up > floorsc && sc_f_up - sc_->refGapExtend() == sc_cur) { + mask |= (1 << 1); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isFMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 11) & 3; + } + if(mask == 3) { +#if 1 + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later + } else { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 1); // might choose E later + } +#endif + branch = true; + } else if(mask == 2) { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + assert(!empty || !canMoveThru); + } else { + assert_eq(SSEMatrix::H, ct); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::H))[rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_h_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_e_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_h_upleft = col > 0 ? (((TCScore*)(upleft_vec + SSEMatrix::H))[upleft_rowelt] + offsetsc) : floorsc; + TAlScore sc_diag = sc_->score(readc, refm, readq - 33); + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + if(gapsAllowed) { + if(sc_h_up > floorsc && sc_cur == sc_h_up - sc_->refGapOpen()) { + mask |= (1 << 0); + } + if(sc_h_left > floorsc && sc_cur == sc_h_left - sc_->readGapOpen()) { + mask |= (1 << 1); + } + if(sc_f_up > floorsc && sc_cur == sc_f_up - sc_->refGapExtend()) { + mask |= (1 << 2); + } + if(sc_e_left > floorsc && sc_cur == sc_e_left - sc_->readGapExtend()) { + mask |= (1 << 3); + } + } + if(sc_h_upleft > floorsc && sc_cur == sc_h_upleft + sc_diag) { + mask |= (1 << 4); // diagonal is + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isHMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 2) & 31; + } + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + int opts = alts5[mask]; + int select = -1; + if(opts == 1) { + select = firsts5[mask]; + assert_geq(mask, 0); + d.mat_.hMaskSet(row, col, 0); + } else if(opts > 1) { +#if 1 + if( (mask & 16) != 0) { + select = 4; // H diag + } else if((mask & 1) != 0) { + select = 0; // H up + } else if((mask & 4) != 0) { + select = 2; // F up + } else if((mask & 2) != 0) { + select = 1; // H left + } else if((mask & 8) != 0) { + select = 3; // E left + } +#else + select = randFromMask(rnd, mask); +#endif + assert_geq(mask, 0); + mask &= ~(1 << select); + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + d.mat_.hMaskSet(row, col, mask); + branch = true; + } else { /* No way to backtrack! */ } + if(select != -1) { + if(select == 4) { + cur = SW_BT_OALL_DIAG; + } else if(select == 0) { + cur = SW_BT_OALL_REF_OPEN; + } else if(select == 1) { + cur = SW_BT_OALL_READ_OPEN; + } else if(select == 2) { + cur = SW_BT_RFGAP_EXTEND; + } else { + assert_eq(3, select) + cur = SW_BT_RDGAP_EXTEND; + } + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + } + assert(!empty || !canMoveThru || ct == SSEMatrix::H); + } // if(row > 0) + } // else clause of if(reportedThru) + if(!reportedThru) { + d.mat_.setReportedThrough(row, col); + } + assert(d.mat_.reportedThrough(row, col)); + //if(backEliminate && row < d.mat_.nrow()-1) { + // // Possibly pick off neighbors below and to the right if the + // // neighbor's only way of backtracking is through this cell. + //} + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + // Cell was involved in a previously-reported alignment? + if(!canMoveThru) { + if(!btnstack_.empty()) { + // Remove all the cells from list back to and including the + // cell where the branch occurred + btcells_.resize(btnstack_.back().celsz); + // Pop record off the top of the stack + ned.resize(btnstack_.back().nedsz); + //aed.resize(btnstack_.back().aedsz); + row = btnstack_.back().row; + col = btnstack_.back().col; + gaps = btnstack_.back().gaps; + readGaps = btnstack_.back().readGaps; + refGaps = btnstack_.back().refGaps; + score = btnstack_.back().score; + ct = btnstack_.back().ct; + btnstack_.pop_back(); + assert(!sc_->monotone || score.score() >= escore); + NEW_ROW_COL(row, col); + continue; + } else { + // No branch points to revisit; just give up + res.reset(); + met.btfail++; // DP backtraces failed + return false; + } + } + assert(!reportedThru); + assert(!sc_->monotone || score.score() >= minsc_); + if(empty || row == 0) { + assert_eq(SSEMatrix::H, ct); + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + // This cell is at the end of a legitimate alignment + trimBeg = row; + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + break; + } + if(branch) { + // Add a frame to the backtrack stack + btnstack_.expand(); + btnstack_.back().init( + ned.size(), + 0, // aed.size() + btcells_.size(), + row, + col, + gaps, + readGaps, + refGaps, + score, + (int)ct); + } + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + switch(cur) { + // Move up and to the left. If the reference nucleotide in the + // source row mismatches the read nucleotide, penalize + // it and add a nucleotide mismatch. + case SW_BT_OALL_DIAG: { + assert_gt(row, 0); assert_gt(col, 0); + int readC = (*rd_)[row]; + int refNmask = (int)rf_[rfi_+col]; + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + ct = SSEMatrix::H; + if(m != 1) { + Edit e( + (int)row, + mask2dna[refNmask], + "ACGTN"[readC], + EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + int pen = QUAL2(row, col); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= escore); + } else { + // Reward a match + int64_t bonus = sc_->match(30); + score.score_ += bonus; + assert(!sc_->monotone || score.score() >= escore); + } + if(m == -1) { + score.ns_++; + } + row--; col--; + MOVE_ALL_UPLEFT(); + assert(VALID_AL_SCORE(score)); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_OALL_REF_OPEN: + { + assert_gt(row, 0); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::H; + int pen = sc_->refGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_RFGAP_EXTEND: + { + assert_gt(row, 1); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::F; + int pen = sc_->refGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + case SW_BT_OALL_READ_OPEN: + { + assert_gt(col, 0); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::H; + int pen = sc_->readGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + case SW_BT_RDGAP_EXTEND: + { + assert_gt(col, 1); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::E; + int pen = sc_->readGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + default: throw 1; + } + } // while((int)row > 0) + assert_geq(col, 0); + assert_eq(SSEMatrix::H, ct); + // The number of cells in the backtracs should equal the number of read + // bases after trimming plus the number of gaps + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + // Check whether we went through a core diagonal and set 'reported' flag on + // each cell + bool overlappedCoreDiag = false; + for(size_t i = 0; i < btcells_.size(); i++) { + size_t rw = btcells_[i].first; + size_t cl = btcells_[i].second; + // Calculate the diagonal within the *trimmed* rectangle, i.e. the + // rectangle we dealt with in align, gather and backtrack. + int64_t diagi = cl - rw; + // Now adjust to the diagonal within the *untrimmed* rectangle by + // adding on the amount trimmed from the left. + diagi += rect_->triml; + if(diagi >= 0) { + size_t diag = (size_t)diagi; + if(diag >= rect_->corel && diag <= rect_->corer) { + overlappedCoreDiag = true; + break; + } + } +#ifndef NDEBUG + //assert(!d.mat_.reportedThrough(rw, cl)); + //d.mat_.setReportedThrough(rw, cl); + assert(d.mat_.reportedThrough(rw, cl)); +#endif + } + if(!overlappedCoreDiag) { + // Must overlap a core diagonal. Otherwise, we run the risk of + // reporting an alignment that overlaps (and trumps) a higher-scoring + // alignment that lies partially outside the dynamic programming + // rectangle. + res.reset(); + met.corerej++; + return false; + } + int readC = (*rd_)[rdi_+row]; // get last char in read + int refNmask = (int)rf_[rfi_+col]; // get last ref char ref involved in aln + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + if(m != 1) { + Edit e((int)row, mask2dna[refNmask], "ACGTN"[readC], EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + score.score_ -= QUAL2(row, col); + assert_geq(score.score(), minsc_); + } else { + score.score_ += sc_->match(30); + } + if(m == -1) { + score.ns_++; + } + if(score.ns_ > nceil_) { + // Alignment has too many Ns in it! + res.reset(); + met.nrej++; + return false; + } + res.reverse(); + assert(Edit::repOk(ned, (*rd_))); + assert_eq(score.score(), escore); + assert_leq(gaps, rdgap_ + rfgap_); + off = col; + assert_lt(col + (size_t)rfi_, (size_t)rff_); + score.gaps_ = gaps; + res.alres.setScore(score); + res.alres.setShape( + refidx_, // ref id + off + rfi_ + rect_->refl, // 0-based ref offset + reflen_, // reference length + fw_, // aligned to Watson? + rdf_ - rdi_, // read length + 0, // read ID + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + fw_ ? trimBeg : trimEnd, // alignment trim 5' end + fw_ ? trimEnd : trimBeg); // alignment trim 3' end + size_t refns = 0; + for(size_t i = col; i <= origCol; i++) { + if((int)rf_[rfi_+i] > 15) { + refns++; + } + } + res.alres.setRefNs(refns); + assert(Edit::repOk(ned, (*rd_), true, trimBeg, trimEnd)); + assert(res.repOk()); +#ifndef NDEBUG + size_t gapsCheck = 0; + for(size_t i = 0; i < ned.size(); i++) { + if(ned[i].isGap()) gapsCheck++; + } + assert_eq(gaps, gapsCheck); + BTDnaString refstr; + for(size_t i = col; i <= origCol; i++) { + refstr.append(firsts5[(int)rf_[rfi_+i]]); + } + BTDnaString editstr; + Edit::toRef((*rd_), ned, editstr, true, trimBeg, trimEnd); + if(refstr != editstr) { + cerr << "Decoded nucleotides and edits don't match reference:" << endl; + cerr << " score: " << score.score() + << " (" << gaps << " gaps)" << endl; + cerr << " edits: "; + Edit::print(cerr, ned); + cerr << endl; + cerr << " decoded nucs: " << (*rd_) << endl; + cerr << " edited nucs: " << editstr << endl; + cerr << " reference nucs: " << refstr << endl; + assert(0); + } +#endif + met.btsucc++; // DP backtraces succeeded + return true; +} diff --git a/aligner_swsse_loc_u8.cpp b/aligner_swsse_loc_u8.cpp new file mode 100644 index 0000000..673df2d --- /dev/null +++ b/aligner_swsse_loc_u8.cpp @@ -0,0 +1,2266 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/** + * aligner_sw_sse.cpp + * + * Versions of key alignment functions that use vector instructions to + * accelerate dynamic programming. Based chiefly on the striped Smith-Waterman + * paper and implementation by Michael Farrar. See: + * + * Farrar M. Striped Smith-Waterman speeds database searches six times over + * other SIMD implementations. Bioinformatics. 2007 Jan 15;23(2):156-61. + * http://sites.google.com/site/farrarmichael/smith-waterman + * + * While the paper describes an implementation of Smith-Waterman, we extend it + * do end-to-end read alignment as well as local alignment. The change + * required for this is minor: we simply let vmax be the maximum element in the + * score domain rather than the minimum. + * + * The vectorized dynamic programming implementation lacks some features that + * make it hard to adapt to solving the entire dynamic-programming alignment + * problem. For instance: + * + * - It doesn't respect gap barriers on either end of the read + * - It just gives a maximum; not enough information to backtrace without + * redoing some alignment + * - It's a little difficult to handle st_ and en_, especially st_. + * - The query profile mechanism makes handling of ambiguous reference bases a + * little tricky (16 cols in query profile lookup table instead of 5) + * + * Given the drawbacks, it is tempting to use SSE dynamic programming as a + * filter rather than as an aligner per se. Here are a few ideas for how it + * can be extended to handle more of the alignment problem: + * + * - Save calculated scores to a big array as we go. We return to this array + * to find and backtrace from good solutions. + */ + +#include +#include "aligner_sw.h" + +// static const size_t NBYTES_PER_REG = 16; +static const size_t NWORDS_PER_REG = 16; +// static const size_t NBITS_PER_WORD = 8; +static const size_t NBYTES_PER_WORD = 1; + +// In local mode, we start low (0) and go high (255). Factoring in a query +// profile involves unsigned saturating addition. All query profile elements +// should be expressed as a positive number; this is done by adding -min +// where min is the smallest (negative) score in the query profile. + +typedef uint8_t TCScore; + +/** + * Build query profile look up tables for the read. The query profile look + * up table is organized as a 1D array indexed by [i][j] where i is the + * reference character in the current DP column (0=A, 1=C, etc), and j is + * the segment of the query we're currently working on. + */ +void SwAligner::buildQueryProfileLocalSseU8(bool fw) { + bool& done = fw ? sseU8fwBuilt_ : sseU8rcBuilt_; + if(done) { + return; + } + done = true; + const BTDnaString* rd = fw ? rdfw_ : rdrc_; + const BTString* qu = fw ? qufw_ : qurc_; + const size_t len = rd->length(); + const size_t seglen = (len + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; + // How many __m128i's are needed + size_t n128s = + 64 + // slack bytes, for alignment? + (seglen * ALPHA_SIZE) // query profile data + * 2; // & gap barrier data + assert_gt(n128s, 0); + SSEData& d = fw ? sseU8fw_ : sseU8rc_; + d.profbuf_.resizeNoCopy(n128s); + assert(!d.profbuf_.empty()); + d.maxPen_ = d.maxBonus_ = 0; + d.lastIter_ = d.lastWord_ = 0; + d.qprofStride_ = d.gbarStride_ = 2; + d.bias_ = 0; + // Calculate bias + for(size_t refc = 0; refc < ALPHA_SIZE; refc++) { + for(size_t i = 0; i < len; i++) { + int readc = (*rd)[i]; + int readq = (*qu)[i]; + int sc = sc_->score(readc, (int)(1 << refc), readq - 33); + if(sc < 0 && sc < d.bias_) { + d.bias_ = sc; + } + } + } + assert_leq(d.bias_, 0); + d.bias_ = -d.bias_; + // For each reference character A, C, G, T, N ... + for(size_t refc = 0; refc < ALPHA_SIZE; refc++) { + // For each segment ... + for(size_t i = 0; i < seglen; i++) { + size_t j = i; + uint8_t *qprofWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2)); + uint8_t *gbarWords = + reinterpret_cast(d.profbuf_.ptr() + (refc * seglen * 2) + (i * 2) + 1); + // For each sub-word (byte) ... + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + int sc = 0; + *gbarWords = 0; + if(j < len) { + int readc = (*rd)[j]; + int readq = (*qu)[j]; + sc = sc_->score(readc, (int)(1 << refc), readq - 33); + assert_range(0, 255, sc + d.bias_); + size_t j_from_end = len - j - 1; + if(j < (size_t)sc_->gapbar || + j_from_end < (size_t)sc_->gapbar) + { + // Inside the gap barrier + *gbarWords = 0xff; + } + } + if(refc == 0 && j == len-1) { + // Remember which 128-bit word and which smaller word has + // the final row + d.lastIter_ = i; + d.lastWord_ = k; + } + if(sc < 0) { + if((size_t)(-sc) > d.maxPen_) { + d.maxPen_ = (size_t)(-sc); + } + } else { + if((size_t)sc > d.maxBonus_) { + d.maxBonus_ = (size_t)sc; + } + } + *qprofWords = (uint8_t)(sc + d.bias_); + gbarWords++; + qprofWords++; + j += seglen; // update offset into query + } + } + } +} + +#ifndef NDEBUG +/** + * Return true iff the cell has sane E/F/H values w/r/t its predecessors. + */ +static bool cellOkLocalU8( + SSEData& d, + size_t row, + size_t col, + int refc, + int readc, + int readq, + const Scoring& sc) // scoring scheme +{ + TCScore floorsc = 0; + TCScore ceilsc = 255 - d.bias_ - 1; + TAlScore offsetsc = 0; + TAlScore sc_h_cur = (TAlScore)d.mat_.helt(row, col); + TAlScore sc_e_cur = (TAlScore)d.mat_.eelt(row, col); + TAlScore sc_f_cur = (TAlScore)d.mat_.felt(row, col); + if(sc_h_cur > floorsc) { + sc_h_cur += offsetsc; + } + if(sc_e_cur > floorsc) { + sc_e_cur += offsetsc; + } + if(sc_f_cur > floorsc) { + sc_f_cur += offsetsc; + } + bool gapsAllowed = true; + size_t rowFromEnd = d.mat_.nrow() - row - 1; + if(row < (size_t)sc.gapbar || rowFromEnd < (size_t)sc.gapbar) { + gapsAllowed = false; + } + bool e_left_trans = false, h_left_trans = false; + bool f_up_trans = false, h_up_trans = false; + bool h_diag_trans = false; + if(gapsAllowed) { + TAlScore sc_h_left = floorsc; + TAlScore sc_e_left = floorsc; + TAlScore sc_h_up = floorsc; + TAlScore sc_f_up = floorsc; + if(col > 0 && sc_e_cur > floorsc && sc_e_cur <= ceilsc) { + sc_h_left = d.mat_.helt(row, col-1) + offsetsc; + sc_e_left = d.mat_.eelt(row, col-1) + offsetsc; + e_left_trans = (sc_e_left > floorsc && sc_e_cur == sc_e_left - sc.readGapExtend()); + h_left_trans = (sc_h_left > floorsc && sc_e_cur == sc_h_left - sc.readGapOpen()); + assert(e_left_trans || h_left_trans); + } + if(row > 0 && sc_f_cur > floorsc && sc_f_cur <= ceilsc) { + sc_h_up = d.mat_.helt(row-1, col) + offsetsc; + sc_f_up = d.mat_.felt(row-1, col) + offsetsc; + f_up_trans = (sc_f_up > floorsc && sc_f_cur == sc_f_up - sc.refGapExtend()); + h_up_trans = (sc_h_up > floorsc && sc_f_cur == sc_h_up - sc.refGapOpen()); + assert(f_up_trans || h_up_trans); + } + } else { + assert_geq(floorsc, sc_e_cur); + assert_geq(floorsc, sc_f_cur); + } + if(col > 0 && row > 0 && sc_h_cur > floorsc && sc_h_cur <= ceilsc) { + TAlScore sc_h_upleft = d.mat_.helt(row-1, col-1) + offsetsc; + TAlScore sc_diag = sc.score(readc, (int)refc, readq - 33); + h_diag_trans = sc_h_cur == sc_h_upleft + sc_diag; + } + assert( + sc_h_cur <= floorsc || + e_left_trans || + h_left_trans || + f_up_trans || + h_up_trans || + h_diag_trans || + sc_h_cur > ceilsc || + row == 0 || + col == 0); + return true; +} +#endif /*ndef NDEBUG*/ + +#ifdef NDEBUG + +#define assert_all_eq0(x) +#define assert_all_gt(x, y) +#define assert_all_gt_lo(x) +#define assert_all_lt(x, y) +#define assert_all_lt_hi(x) + +#else + +#define assert_all_eq0(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpeq_epi16(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt(x, y) { \ + __m128i tmp = _mm_cmpgt_epu8(x, y); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_gt_lo(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + tmp = _mm_cmpgt_epu8(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt(x, y) { \ + __m128i z = _mm_setzero_si128(); \ + z = _mm_xor_si128(z, z); \ + __m128i tmp = _mm_subs_epu8(y, x); \ + tmp = _mm_cmpeq_epi16(tmp, z); \ + assert_eq(0x0000, _mm_movemask_epi8(tmp)); \ +} + +#define assert_all_lt_hi(x) { \ + __m128i z = _mm_setzero_si128(); \ + __m128i tmp = _mm_setzero_si128(); \ + z = _mm_cmpeq_epu8(z, z); \ + z = _mm_srli_epu8(z, 1); \ + tmp = _mm_cmplt_epu8(x, z); \ + assert_eq(0xffff, _mm_movemask_epi8(tmp)); \ +} +#endif + +/** + * Aligns by filling a dynamic programming matrix with the SSE-accelerated, + * banded DP approach of Farrar. As it goes, it determines which cells we + * might backtrace from and tallies the best (highest-scoring) N backtrace + * candidate cells per diagonal. Also returns the alignment score of the best + * alignment in the matrix. + * + * This routine does *not* maintain a matrix holding the entire matrix worth of + * scores, nor does it maintain any other dense O(mn) data structure, as this + * would quickly exhaust memory for queries longer than about 10,000 kb. + * Instead, in the fill stage it maintains two columns worth of scores at a + * time (current/previous, or right/left) - these take O(m) space. When + * finished with the current column, it determines which cells from the + * previous column, if any, are candidates we might backtrace from to find a + * full alignment. A candidate cell has a score that rises above the threshold + * and isn't improved upon by a match in the next column. The best N + * candidates per diagonal are stored in a O(m + n) data structure. + */ +TAlScore SwAligner::alignGatherLoc8(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert_gt(minsc_, 0); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + if(!debug) met.dp++; + buildQueryProfileLocalSseU8(fw_); + assert(!d.profbuf_.empty()); + assert_gt(d.bias_, 0); + assert_lt(d.bias_, 127); + + assert_gt(d.maxBonus_, 0); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + // Now set up the score vectors. We just need two columns worth, which + // we'll call "left" and "right". + d.vecbuf_.resize(ROWSTRIDE_2COL * iter * 2); + d.vecbuf_.zero(); + __m128i *vbuf_l = d.vecbuf_.ptr(); + __m128i *vbuf_r = d.vecbuf_.ptr() + (ROWSTRIDE_2COL * iter); + + // This is the data structure that holds candidate cells per diagonal. + const size_t ndiags = rff_ - rfi_ + dpRows() - 1; + if(!debug) { + btdiag_.init(ndiags, 2); + } + + // Data structure that holds checkpointed anti-diagonals + TAlScore perfectScore = sc_->perfectScore(dpRows()); + bool checkpoint = true; + bool cpdebug = false; +#ifndef NDEBUG + cpdebug = dpRows() < 1000; +#endif + cper_.init( + dpRows(), // # rows + rff_ - rfi_, // # columns + cperPerPow2_, // checkpoint every 1 << perpow2 diags (& next) + perfectScore, // perfect score (for sanity checks) + true, // matrix cells have 8-bit scores? + cperTri_, // triangular mini-fills? + true, // alignment is local? + cpdebug); // save all cells for debugging? + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i vmax = _mm_setzero_si128(); + __m128i vcolmax = _mm_setzero_si128(); + __m128i vmaxtmp = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); + __m128i vhd = _mm_setzero_si128(); + __m128i vhdtmp = _mm_setzero_si128(); + __m128i vtmp = _mm_setzero_si128(); + __m128i vzero = _mm_setzero_si128(); + __m128i vbias = _mm_setzero_si128(); + __m128i vbiasm1 = _mm_setzero_si128(); + __m128i vminsc = _mm_setzero_si128(); + + int dup; + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_U8); + dup = (sc_->refGapOpen() << 8) | (sc_->refGapOpen() & 0x00ff); + rfgapo = _mm_insert_epi16(rfgapo, dup, 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_U8); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + dup = (sc_->refGapExtend() << 8) | (sc_->refGapExtend() & 0x00ff); + rfgape = _mm_insert_epi16(rfgape, dup, 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_U8); + dup = (sc_->readGapOpen() << 8) | (sc_->readGapOpen() & 0x00ff); + rdgapo = _mm_insert_epi16(rdgapo, dup, 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_U8); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + dup = (sc_->readGapExtend() << 8) | (sc_->readGapExtend() & 0x00ff); + rdgape = _mm_insert_epi16(rdgape, dup, 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + // Set all elts to minimum score threshold. Actually, to 1 less than the + // threshold so we can use gt instead of geq. + dup = (((int)minsc_ - 1) << 8) | (((int)minsc_ - 1) & 0x00ff); + vminsc = _mm_insert_epi16(vminsc, dup, 0); + vminsc = _mm_shufflelo_epi16(vminsc, 0); + vminsc = _mm_shuffle_epi32(vminsc, 0); + + dup = ((d.bias_ - 1) << 8) | ((d.bias_ - 1) & 0x00ff); + vbiasm1 = _mm_insert_epi16(vbiasm1, dup, 0); + vbiasm1 = _mm_shufflelo_epi16(vbiasm1, 0); + vbiasm1 = _mm_shuffle_epi32(vbiasm1, 0); + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vlo = _mm_xor_si128(vlo, vlo); // all elts = 0 + vmax = vlo; + + // Make a vector of bias offsets + dup = (d.bias_ << 8) | (d.bias_ & 0x00ff); + vbias = _mm_insert_epi16(vbias, dup, 0); + vbias = _mm_shufflelo_epi16(vbias, 0); + vbias = _mm_shuffle_epi32(vbias, 0); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + const size_t colstride = ROWSTRIDE_2COL * iter; + + // Initialize the H and E vectors in the first matrix column + __m128i *pvELeft = vbuf_l + 0; __m128i *pvERight = vbuf_r + 0; + /* __m128i *pvFLeft = vbuf_l + 1; */ __m128i *pvFRight = vbuf_r + 1; + __m128i *pvHLeft = vbuf_l + 2; __m128i *pvHRight = vbuf_r + 2; + + for(size_t i = 0; i < iter; i++) { + // start low in local mode + _mm_store_si128(pvERight, vlo); pvERight += ROWSTRIDE_2COL; + _mm_store_si128(pvHRight, vlo); pvHRight += ROWSTRIDE_2COL; + } + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + TAlScore matchsc = sc_->match(30); + TAlScore leftmax = MIN_I64; + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + size_t off = MAX_SIZE_T, lastoff; + bool bailed = false; + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + // Swap left and right; vbuf_l is the vector on the left, which we + // generally load from, and vbuf_r is the vector on the right, which we + // generally store to. + swap(vbuf_l, vbuf_r); + pvELeft = vbuf_l + 0; pvERight = vbuf_r + 0; + /* pvFLeft = vbuf_l + 1; */ pvFRight = vbuf_r + 1; + pvHLeft = vbuf_l + 2; pvHRight = vbuf_r + 2; + + // Fetch this column's reference mask + const int refm = (int)rf_[i]; + + // Fetch the appropriate query profile + lastoff = off; + off = (size_t)firsts5[refm] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Load H vector from the final row of the previous column. + // ??? perhaps we should calculate the next iter's F instead of the + // current iter's? The way we currently do it, seems like it will + // almost always require at least one fixup loop iter (to recalculate + // this topmost F). + vh = _mm_load_si128(pvHLeft + colstride - ROWSTRIDE_2COL); + + // Set all cells to low value + vf = _mm_xor_si128(vf, vf); + // vf now contains the vertical contribution + + // Store cells in F, calculated previously + // No need to veto ref gap extensions, they're all 0x00s + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Shift down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + + // We pull out one loop iteration to make it easier to veto values in the top row + + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELeft); + vhd = _mm_load_si128(pvHLeft); + assert_all_lt(ve, vhi); + pvELeft += ROWSTRIDE_2COL; + // ve now contains the horizontal contribution + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epu8(vh, pvScore[0]); + vh = _mm_subs_epu8(vh, vbias); + // vh now contains the diagonal contribution + + vhdtmp = vhd; + vhd = _mm_subs_epu8(vhd, rdgapo); + vhd = _mm_subs_epu8(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epu8(ve, rdgape); + ve = _mm_max_epu8(ve, vhd); + + vh = _mm_max_epu8(vh, ve); + vf = vh; + + // Update highest score so far + vcolmax = vh; + + // Save the new vH values + _mm_store_si128(pvHRight, vh); + + vh = vhdtmp; + assert_all_lt(ve, vhi); + pvHRight += ROWSTRIDE_2COL; + pvHLeft += ROWSTRIDE_2COL; + + // Save E values + _mm_store_si128(pvERight, ve); + pvERight += ROWSTRIDE_2COL; + + // Update vf value + vf = _mm_subs_epu8(vf, rfgapo); + assert_all_lt(vf, vhi); + + pvScore += 2; // move on to next query profile + + // For each character in the reference text: + size_t j; + for(j = 1; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELeft); + vhd = _mm_load_si128(pvHLeft); + assert_all_lt(ve, vhi); + pvELeft += ROWSTRIDE_2COL; + + // Store cells in F, calculated previously + vf = _mm_subs_epu8(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epu8(vh, pvScore[0]); + vh = _mm_subs_epu8(vh, vbias); + + // Update H, factoring in E and F + vh = _mm_max_epu8(vh, vf); + + vhdtmp = vhd; + vhd = _mm_subs_epu8(vhd, rdgapo); + vhd = _mm_subs_epu8(vhd, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epu8(ve, rdgape); + ve = _mm_max_epu8(ve, vhd); + + vh = _mm_max_epu8(vh, ve); + vtmp = vh; + + // Update highest score encountered this far + vcolmax = _mm_max_epu8(vcolmax, vh); + + // Save the new vH values + _mm_store_si128(pvHRight, vh); + + vh = vhdtmp; + + assert_all_lt(ve, vhi); + pvHRight += ROWSTRIDE_2COL; + pvHLeft += ROWSTRIDE_2COL; + + // Save E values + _mm_store_si128(pvERight, ve); + pvERight += ROWSTRIDE_2COL; + + // Update vf value + vtmp = _mm_subs_epu8(vtmp, rfgapo); + vf = _mm_subs_epu8(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epu8(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFRight -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFRight); + + pvHRight -= colstride; // reset to start of column + vh = _mm_load_si128(pvHRight); + + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + // TODO: We're testing whether F changed. Can't we just assume that F + // did change and instead check whether H changed? Might save us from + // entering the fixup loop. + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0xffff) { + // Store this vf + _mm_store_si128(pvFRight, vf); + pvFRight += ROWSTRIDE_2COL; + + // Update vh w/r/t new vf + vh = _mm_max_epu8(vh, vf); + + // Save vH values + _mm_store_si128(pvHRight, vh); + pvHRight += ROWSTRIDE_2COL; + + // Update highest score encountered so far. + vcolmax = _mm_max_epu8(vcolmax, vh); + + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFRight -= colstride; + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + pvHRight -= colstride; + vh = _mm_load_si128(pvHRight); // load next vh ASAP + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + } else { + vtmp = _mm_load_si128(pvFRight); // load next vf ASAP + vh = _mm_load_si128(pvHRight); // load next vh ASAP + } + + // Update F with another gap extension + vf = _mm_subs_epu8(vf, rfgape); + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + + // Now we'd like to know exactly which cells in the left column are + // candidates we might backtrace from. First question is: did *any* + // elements in the column exceed the minimum score threshold? + if(!debug && leftmax >= minsc_) { + // Yes. Next question is: which cells are candidates? We have to + // allow matches in the right column to override matches above and + // to the left in the left column. + assert_gt(i - rfi_, 0); + pvHLeft = vbuf_l + 2; + assert_lt(lastoff, MAX_SIZE_T); + pvScore = d.profbuf_.ptr() + lastoff; // even elts = query profile, odd = gap barrier + for(size_t k = 0; k < iter; k++) { + vh = _mm_load_si128(pvHLeft); + vtmp = _mm_cmpgt_epi8(pvScore[0], vbiasm1); + int cmp = _mm_movemask_epi8(vtmp); + if(cmp != 0xffff) { + // At least one candidate in this mask. Now iterate + // through vm/vh to evaluate individual cells. + for(size_t m = 0; m < NWORDS_PER_REG; m++) { + size_t row = k + m * iter; + if(row >= dpRows()) { + break; + } + if(((TCScore *)&vtmp)[m] > 0 && ((TCScore *)&vh)[m] >= minsc_) { + TCScore sc = ((TCScore *)&vh)[m]; + assert_geq(sc, minsc_); + // Add to data structure holding all candidates + size_t col = i - rfi_ - 1; // -1 b/c prev col + size_t frombot = dpRows() - row - 1; + DpBtCandidate cand(row, col, sc); + btdiag_.add(frombot + col, cand); + } + } + } + pvHLeft += ROWSTRIDE_2COL; + pvScore += 2; + } + } + + // Save some elements to checkpoints + if(checkpoint) { + + __m128i *pvE = vbuf_r + 0; + __m128i *pvF = vbuf_r + 1; + __m128i *pvH = vbuf_r + 2; + size_t coli = i - rfi_; + if(coli < cper_.locol_) cper_.locol_ = coli; + if(coli > cper_.hicol_) cper_.hicol_ = coli; + if(cperTri_) { + // Checkpoint for triangular mini-fills + size_t rc_mod = coli & cper_.lomask_; + assert_lt(rc_mod, cper_.per_); + int64_t row = -(int64_t)rc_mod-1; + int64_t row_mod = row; + int64_t row_div = 0; + size_t idx = coli >> cper_.perpow2_; + size_t idxrow = idx * cper_.nrow_; + assert_eq(4, ROWSTRIDE_2COL); + bool done = false; + while(true) { + row += (cper_.per_ - 2); + row_mod += (cper_.per_ - 2); + for(size_t j = 0; j < 2; j++) { + row++; + row_mod++; + if(row >= 0 && (size_t)row < cper_.nrow_) { + // Update row divided by iter_ and mod iter_ + while(row_mod >= (int64_t)iter) { + row_mod -= (int64_t)iter; + row_div++; + } + size_t delt = idxrow + row; + size_t vecoff = (row_mod << 6) + row_div; + assert_lt(row_div, 16); + int16_t h_sc = ((uint8_t*)pvH)[vecoff]; + int16_t e_sc = ((uint8_t*)pvE)[vecoff]; + int16_t f_sc = ((uint8_t*)pvF)[vecoff]; + assert_leq(h_sc, cper_.perf_); + assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad *qdiags = ((j == 0) ? cper_.qdiag1s_.ptr() : cper_.qdiag2s_.ptr()); + qdiags[delt].sc[0] = h_sc; + qdiags[delt].sc[1] = e_sc; + qdiags[delt].sc[2] = f_sc; + } // if(row >= 0 && row < nrow_) + else if(row >= 0 && (size_t)row >= cper_.nrow_) { + done = true; + break; + } + } // for(size_t j = 0; j < 2; j++) + if(done) { + break; + } + idx++; + idxrow += cper_.nrow_; + } // while(true) + } else { + // Checkpoint for square mini-fills + + // If this is the first column, take this opportunity to + // pre-calculate the coordinates of the elements we're going to + // checkpoint. + if(coli == 0) { + size_t cpi = cper_.per_-1; + size_t cpimod = cper_.per_-1; + size_t cpidiv = 0; + cper_.commitMap_.clear(); + while(cpi < cper_.nrow_) { + while(cpimod >= iter) { + cpimod -= iter; + cpidiv++; + } + size_t vecoff = (cpimod << 6) + cpidiv; + cper_.commitMap_.push_back(vecoff); + cpi += cper_.per_; + cpimod += cper_.per_; + } + } + // Save all the rows + size_t rowoff = 0; + size_t sz = cper_.commitMap_.size(); + for(size_t i = 0; i < sz; i++, rowoff += cper_.ncol_) { + size_t vecoff = cper_.commitMap_[i]; + int16_t h_sc = ((uint8_t*)pvH)[vecoff]; + //int16_t e_sc = ((uint8_t*)pvE)[vecoff]; + int16_t f_sc = ((uint8_t*)pvF)[vecoff]; + assert_leq(h_sc, cper_.perf_); + //assert_leq(e_sc, cper_.perf_); + assert_leq(f_sc, cper_.perf_); + CpQuad& dst = cper_.qrows_[rowoff + coli]; + dst.sc[0] = h_sc; + //dst.sc[1] = e_sc; + dst.sc[2] = f_sc; + } + // Is this a column we'd like to checkpoint? + if((coli & cper_.lomask_) == cper_.lomask_) { + // Save the column using memcpys + assert_gt(coli, 0); + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = (coli >> cper_.perpow2_) * wordspercol; + __m128i *dst = cper_.qcols_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + if(cper_.debug_) { + // Save the column using memcpys + size_t wordspercol = cper_.niter_ * ROWSTRIDE_2COL; + size_t coloff = coli * wordspercol; + __m128i *dst = cper_.qcolsD_.ptr() + coloff; + memcpy(dst, vbuf_r, sizeof(__m128i) * wordspercol); + } + } + + // Store column maximum vector in first element of tmp + vmax = _mm_max_epu8(vmax, vcolmax); + + { + // Get single largest score in this column + vmaxtmp = vcolmax; + vtmp = _mm_srli_si128(vmaxtmp, 8); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 4); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 2); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 1); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + int score = _mm_extract_epi16(vmaxtmp, 0); + score = score & 0x00ff; + + // Could we have saturated? + if(score + d.bias_ >= 255) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + if(score < minsc_) { + size_t ncolleft = rff_ - i - 1; + if(score + (TAlScore)ncolleft * matchsc < minsc_) { + // Bail! There can't possibly be a valid alignment that + // passes through this column. + bailed = true; + break; + } + } + + leftmax = score; + } + } + + lastoff = off; + + // Now we'd like to know exactly which cells in the *rightmost* column are + // candidates we might backtrace from. Did *any* elements exceed the + // minimum score threshold? + if(!debug && !bailed && leftmax >= minsc_) { + // Yes. Next question is: which cells are candidates? We have to + // allow matches in the right column to override matches above and + // to the left in the left column. + pvHLeft = vbuf_r + 2; + assert_lt(lastoff, MAX_SIZE_T); + pvScore = d.profbuf_.ptr() + lastoff; // even elts = query profile, odd = gap barrier + for(size_t k = 0; k < iter; k++) { + vh = _mm_load_si128(pvHLeft); + vtmp = _mm_cmpgt_epi8(pvScore[0], vbiasm1); + int cmp = _mm_movemask_epi8(vtmp); + if(cmp != 0xffff) { + // At least one candidate in this mask. Now iterate + // through vm/vh to evaluate individual cells. + for(size_t m = 0; m < NWORDS_PER_REG; m++) { + size_t row = k + m * iter; + if(row >= dpRows()) { + break; + } + if(((TCScore *)&vtmp)[m] > 0 && ((TCScore *)&vh)[m] >= minsc_) { + TCScore sc = ((TCScore *)&vh)[m]; + assert_geq(sc, minsc_); + // Add to data structure holding all candidates + size_t col = rff_ - rfi_ - 1; // -1 b/c prev col + size_t frombot = dpRows() - row - 1; + DpBtCandidate cand(row, col, sc); + btdiag_.add(frombot + col, cand); + } + } + } + pvHLeft += ROWSTRIDE_2COL; + pvScore += 2; + } + } + + // Find largest score in vmax + vtmp = _mm_srli_si128(vmax, 8); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 4); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 2); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 1); + vmax = _mm_max_epu8(vmax, vtmp); + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + int score = _mm_extract_epi16(vmax, 0); + score = score & 0x00ff; + + flag = 0; + + // Could we have saturated? + if(score + d.bias_ >= 255) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Did we find a solution? + if(score == MIN_U8 || score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return (TAlScore)score; + } + + // Now take all the backtrace candidates in the btdaig_ structure and + // dump them into the btncand_ array. They'll be sorted later. + if(!debug) { + assert(!btdiag_.empty()); + btdiag_.dump(btncand_); + assert(!btncand_.empty()); + } + + // Return largest score + if(!debug) met.dpsucc++; + return (TAlScore)score; +} + +/** + * Solve the current alignment problem using SSE instructions that operate on 16 + * unsigned 8-bit values packed into a single 128-bit register. + */ +TAlScore SwAligner::alignNucleotidesLocalSseU8(int& flag, bool debug) { + assert_leq(rdf_, rd_->length()); + assert_leq(rdf_, qu_->length()); + assert_lt(rfi_, rff_); + assert_lt(rdi_, rdf_); + assert_eq(rd_->length(), qu_->length()); + assert_geq(sc_->gapbar, 1); + assert(repOk()); +#ifndef NDEBUG + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert_range(0, 16, (int)rf_[i]); + } +#endif + + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + if(!debug) met.dp++; + buildQueryProfileLocalSseU8(fw_); + assert(!d.profbuf_.empty()); + assert_geq(d.bias_, 0); + + assert_gt(d.maxBonus_, 0); + size_t iter = + (dpRows() + (NWORDS_PER_REG-1)) / NWORDS_PER_REG; // iter = segLen + + int dup; + + // Many thanks to Michael Farrar for releasing his striped Smith-Waterman + // implementation: + // + // http://sites.google.com/site/farrarmichael/smith-waterman + // + // Much of the implmentation below is adapted from Michael's code. + + // Set all elts to reference gap open penalty + __m128i rfgapo = _mm_setzero_si128(); + __m128i rfgape = _mm_setzero_si128(); + __m128i rdgapo = _mm_setzero_si128(); + __m128i rdgape = _mm_setzero_si128(); + __m128i vlo = _mm_setzero_si128(); + __m128i vhi = _mm_setzero_si128(); + __m128i vmax = _mm_setzero_si128(); + __m128i vcolmax = _mm_setzero_si128(); + __m128i vmaxtmp = _mm_setzero_si128(); + __m128i ve = _mm_setzero_si128(); + __m128i vf = _mm_setzero_si128(); + __m128i vh = _mm_setzero_si128(); + __m128i vtmp = _mm_setzero_si128(); + __m128i vzero = _mm_setzero_si128(); + __m128i vbias = _mm_setzero_si128(); + + assert_gt(sc_->refGapOpen(), 0); + assert_leq(sc_->refGapOpen(), MAX_U8); + dup = (sc_->refGapOpen() << 8) | (sc_->refGapOpen() & 0x00ff); + rfgapo = _mm_insert_epi16(rfgapo, dup, 0); + rfgapo = _mm_shufflelo_epi16(rfgapo, 0); + rfgapo = _mm_shuffle_epi32(rfgapo, 0); + + // Set all elts to reference gap extension penalty + assert_gt(sc_->refGapExtend(), 0); + assert_leq(sc_->refGapExtend(), MAX_U8); + assert_leq(sc_->refGapExtend(), sc_->refGapOpen()); + dup = (sc_->refGapExtend() << 8) | (sc_->refGapExtend() & 0x00ff); + rfgape = _mm_insert_epi16(rfgape, dup, 0); + rfgape = _mm_shufflelo_epi16(rfgape, 0); + rfgape = _mm_shuffle_epi32(rfgape, 0); + + // Set all elts to read gap open penalty + assert_gt(sc_->readGapOpen(), 0); + assert_leq(sc_->readGapOpen(), MAX_U8); + dup = (sc_->readGapOpen() << 8) | (sc_->readGapOpen() & 0x00ff); + rdgapo = _mm_insert_epi16(rdgapo, dup, 0); + rdgapo = _mm_shufflelo_epi16(rdgapo, 0); + rdgapo = _mm_shuffle_epi32(rdgapo, 0); + + // Set all elts to read gap extension penalty + assert_gt(sc_->readGapExtend(), 0); + assert_leq(sc_->readGapExtend(), MAX_U8); + assert_leq(sc_->readGapExtend(), sc_->readGapOpen()); + dup = (sc_->readGapExtend() << 8) | (sc_->readGapExtend() & 0x00ff); + rdgape = _mm_insert_epi16(rdgape, dup, 0); + rdgape = _mm_shufflelo_epi16(rdgape, 0); + rdgape = _mm_shuffle_epi32(rdgape, 0); + + vhi = _mm_cmpeq_epi16(vhi, vhi); // all elts = 0xffff + vlo = _mm_xor_si128(vlo, vlo); // all elts = 0 + vmax = vlo; + + // Make a vector of bias offsets + dup = (d.bias_ << 8) | (d.bias_ & 0x00ff); + vbias = _mm_insert_epi16(vbias, dup, 0); + vbias = _mm_shufflelo_epi16(vbias, 0); + vbias = _mm_shuffle_epi32(vbias, 0); + + // Points to a long vector of __m128i where each element is a block of + // contiguous cells in the E, F or H matrix. If the index % 3 == 0, then + // the block of cells is from the E matrix. If index % 3 == 1, they're + // from the F matrix. If index % 3 == 2, then they're from the H matrix. + // Blocks of cells are organized in the same interleaved manner as they are + // calculated by the Farrar algorithm. + const __m128i *pvScore; // points into the query profile + + d.mat_.init(dpRows(), rff_ - rfi_, NWORDS_PER_REG); + const size_t colstride = d.mat_.colstride(); + //const size_t rowstride = d.mat_.rowstride(); + assert_eq(ROWSTRIDE, colstride / iter); + + // Initialize the H and E vectors in the first matrix column + __m128i *pvHTmp = d.mat_.tmpvec(0, 0); + __m128i *pvETmp = d.mat_.evec(0, 0); + + for(size_t i = 0; i < iter; i++) { + _mm_store_si128(pvETmp, vlo); + _mm_store_si128(pvHTmp, vlo); // start low in local mode + pvETmp += ROWSTRIDE; + pvHTmp += ROWSTRIDE; + } + // These are swapped just before the innermost loop + __m128i *pvHStore = d.mat_.hvec(0, 0); + __m128i *pvHLoad = d.mat_.tmpvec(0, 0); + __m128i *pvELoad = d.mat_.evec(0, 0); + __m128i *pvEStore = d.mat_.evecUnsafe(0, 1); + __m128i *pvFStore = d.mat_.fvec(0, 0); + __m128i *pvFTmp = NULL; + + assert_gt(sc_->gapbar, 0); + size_t nfixup = 0; + TAlScore matchsc = sc_->match(30); + + // Fill in the table as usual but instead of using the same gap-penalty + // vector for each iteration of the inner loop, load words out of a + // pre-calculated gap vector parallel to the query profile. The pre- + // calculated gap vectors enforce the gap barrier constraint by making it + // infinitely costly to introduce a gap in barrier rows. + // + // AND use a separate loop to fill in the first row of the table, enforcing + // the st_ constraints in the process. This is awkward because it + // separates the processing of the first row from the others and might make + // it difficult to use the first-row results in the next row, but it might + // be the simplest and least disruptive way to deal with the st_ constraint. + + colstop_ = rff_ - rfi_; + lastsolcol_ = 0; + for(size_t i = (size_t)rfi_; i < (size_t)rff_; i++) { + assert(pvFStore == d.mat_.fvec(0, i - rfi_)); + assert(pvHStore == d.mat_.hvec(0, i - rfi_)); + + // Fetch this column's reference mask + const int refm = (int)rf_[i]; + + // Fetch the appropriate query profile + size_t off = (size_t)firsts5[refm] * iter * 2; + pvScore = d.profbuf_.ptr() + off; // even elts = query profile, odd = gap barrier + + // Load H vector from the final row of the previous column + vh = _mm_load_si128(pvHLoad + colstride - ROWSTRIDE); + + // Set all cells to low value + vf = _mm_xor_si128(vf, vf); + + // Store cells in F, calculated previously + // No need to veto ref gap extensions, they're all 0x00s + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Shift down so that topmost (least sig) cell gets 0 + vh = _mm_slli_si128(vh, NBYTES_PER_WORD); + + // We pull out one loop iteration to make it easier to veto values in the top row + + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELoad); + assert_all_lt(ve, vhi); + pvELoad += ROWSTRIDE; + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epu8(vh, pvScore[0]); + vh = _mm_subs_epu8(vh, vbias); + + // Update H, factoring in E and F + vh = _mm_max_epu8(vh, ve); + vh = _mm_max_epu8(vh, vf); + + // Update highest score so far + vcolmax = _mm_xor_si128(vcolmax, vcolmax); + vcolmax = _mm_max_epu8(vcolmax, vh); + + // Save the new vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update vE value + vf = vh; + vh = _mm_subs_epu8(vh, rdgapo); + vh = _mm_subs_epu8(vh, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epu8(ve, rdgape); + ve = _mm_max_epu8(ve, vh); + assert_all_lt(ve, vhi); + + // Load the next h value + vh = _mm_load_si128(pvHLoad); + pvHLoad += ROWSTRIDE; + + // Save E values + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + + // Update vf value + vf = _mm_subs_epu8(vf, rfgapo); + assert_all_lt(vf, vhi); + + pvScore += 2; // move on to next query profile + + // For each character in the reference text: + size_t j; + for(j = 1; j < iter; j++) { + // Load cells from E, calculated previously + ve = _mm_load_si128(pvELoad); + assert_all_lt(ve, vhi); + pvELoad += ROWSTRIDE; + + // Store cells in F, calculated previously + vf = _mm_subs_epu8(vf, pvScore[1]); // veto some ref gap extensions + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Factor in query profile (matches and mismatches) + vh = _mm_adds_epu8(vh, pvScore[0]); + vh = _mm_subs_epu8(vh, vbias); + + // Update H, factoring in E and F + vh = _mm_max_epu8(vh, ve); + vh = _mm_max_epu8(vh, vf); + + // Update highest score encountered this far + vcolmax = _mm_max_epu8(vcolmax, vh); + + // Save the new vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update vE value + vtmp = vh; + vh = _mm_subs_epu8(vh, rdgapo); + vh = _mm_subs_epu8(vh, pvScore[1]); // veto some read gap opens + ve = _mm_subs_epu8(ve, rdgape); + ve = _mm_max_epu8(ve, vh); + assert_all_lt(ve, vhi); + + // Load the next h value + vh = _mm_load_si128(pvHLoad); + pvHLoad += ROWSTRIDE; + + // Save E values + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + + // Update vf value + vtmp = _mm_subs_epu8(vtmp, rfgapo); + vf = _mm_subs_epu8(vf, rfgape); + assert_all_lt(vf, vhi); + vf = _mm_max_epu8(vf, vtmp); + + pvScore += 2; // move on to next query profile / gap veto + } + // pvHStore, pvELoad, pvEStore have all rolled over to the next column + pvFTmp = pvFStore; + pvFStore -= colstride; // reset to start of column + vtmp = _mm_load_si128(pvFStore); + + pvHStore -= colstride; // reset to start of column + vh = _mm_load_si128(pvHStore); + + pvEStore -= colstride; // reset to start of column + ve = _mm_load_si128(pvEStore); + + pvHLoad = pvHStore; // new pvHLoad = pvHStore + pvScore = d.profbuf_.ptr() + off + 1; // reset veto vector + + // vf from last row gets shifted down by one to overlay the first row + // rfgape has already been subtracted from it. + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + int cmp = _mm_movemask_epi8(vtmp); + + // If any element of vtmp is greater than H - gap-open... + j = 0; + while(cmp != 0xffff) { + // Store this vf + _mm_store_si128(pvFStore, vf); + pvFStore += ROWSTRIDE; + + // Update vh w/r/t new vf + vh = _mm_max_epu8(vh, vf); + + // Save vH values + _mm_store_si128(pvHStore, vh); + pvHStore += ROWSTRIDE; + + // Update highest score encountered this far + vcolmax = _mm_max_epu8(vcolmax, vh); + + // Update E in case it can be improved using our new vh + vh = _mm_subs_epu8(vh, rdgapo); + vh = _mm_subs_epu8(vh, *pvScore); // veto some read gap opens + ve = _mm_max_epu8(ve, vh); + _mm_store_si128(pvEStore, ve); + pvEStore += ROWSTRIDE; + pvScore += 2; + + assert_lt(j, iter); + if(++j == iter) { + pvFStore -= colstride; + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + pvHStore -= colstride; + vh = _mm_load_si128(pvHStore); // load next vh ASAP + pvEStore -= colstride; + ve = _mm_load_si128(pvEStore); // load next ve ASAP + pvScore = d.profbuf_.ptr() + off + 1; + j = 0; + vf = _mm_slli_si128(vf, NBYTES_PER_WORD); + } else { + vtmp = _mm_load_si128(pvFStore); // load next vf ASAP + vh = _mm_load_si128(pvHStore); // load next vh ASAP + ve = _mm_load_si128(pvEStore); // load next vh ASAP + } + + // Update F with another gap extension + vf = _mm_subs_epu8(vf, rfgape); + vf = _mm_subs_epu8(vf, *pvScore); // veto some ref gap extensions + vf = _mm_max_epu8(vtmp, vf); + vtmp = _mm_subs_epu8(vf, vtmp); + vtmp = _mm_cmpeq_epi8(vtmp, vzero); + cmp = _mm_movemask_epi8(vtmp); + nfixup++; + } + +#ifndef NDEBUG + if((rand() & 15) == 0) { + // This is a work-intensive sanity check; each time we finish filling + // a column, we check that each H, E, and F is sensible. + for(size_t k = 0; k < dpRows(); k++) { + assert(cellOkLocalU8( + d, + k, // row + i - rfi_, // col + refm, // reference mask + (int)(*rd_)[rdi_+k], // read char + (int)(*qu_)[rdi_+k], // read quality + *sc_)); // scoring scheme + } + } +#endif + + // Store column maximum vector in first element of tmp + vmax = _mm_max_epu8(vmax, vcolmax); + _mm_store_si128(d.mat_.tmpvec(0, i - rfi_), vcolmax); + + { + // Get single largest score in this column + vmaxtmp = vcolmax; + vtmp = _mm_srli_si128(vmaxtmp, 8); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 4); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 2); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + vtmp = _mm_srli_si128(vmaxtmp, 1); + vmaxtmp = _mm_max_epu8(vmaxtmp, vtmp); + int score = _mm_extract_epi16(vmaxtmp, 0); + score = score & 0x00ff; + + // Could we have saturated? + if(score + d.bias_ >= 255) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + if(score < minsc_) { + size_t ncolleft = rff_ - i - 1; + if(score + (TAlScore)ncolleft * matchsc < minsc_) { + // Bail! We're guaranteed not to see a valid alignment in + // the rest of the matrix + colstop_ = (i+1) - rfi_; + break; + } + } else { + lastsolcol_ = i - rfi_; + } + } + + // pvELoad and pvHLoad are already where they need to be + + // Adjust the load and store vectors here. + pvHStore = pvHLoad + colstride; + pvEStore = pvELoad + colstride; + pvFStore = pvFTmp; + } + + // Find largest score in vmax + vtmp = _mm_srli_si128(vmax, 8); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 4); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 2); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 1); + vmax = _mm_max_epu8(vmax, vtmp); + + // Update metrics + if(!debug) { + size_t ninner = (rff_ - rfi_) * iter; + met.col += (rff_ - rfi_); // DP columns + met.cell += (ninner * NWORDS_PER_REG); // DP cells + met.inner += ninner; // DP inner loop iters + met.fixup += nfixup; // DP fixup loop iters + } + + int score = _mm_extract_epi16(vmax, 0); + score = score & 0x00ff; + + flag = 0; + + // Could we have saturated? + if(score + d.bias_ >= 255) { + flag = -2; // yes + if(!debug) met.dpsat++; + return MIN_I64; + } + + // Did we find a solution? + if(score == MIN_U8 || score < minsc_) { + flag = -1; // no + if(!debug) met.dpfail++; + return (TAlScore)score; + } + + // Return largest score + if(!debug) met.dpsucc++; + return (TAlScore)score; +} + +/** + * Given a filled-in DP table, populate the btncand_ list with candidate cells + * that might be at the ends of valid alignments. No need to do this unless + * the maximum score returned by the align*() func is >= the minimum. + * + * We needn't consider cells that have no chance of reaching any of the core + * diagonals. These are the cells that are more than 'maxgaps' cells away from + * a core diagonal. + * + * We need to be careful to consider that the rectangle might be truncated on + * one or both ends. + * + * The seed extend case looks like this: + * + * |Rectangle| 0: seed diagonal + * **OO0oo---- o: "RHS gap" diagonals + * -**OO0oo--- O: "LHS gap" diagonals + * --**OO0oo-- *: "LHS extra" diagonals + * ---**OO0oo- -: cells that can't possibly be involved in a valid + * ----**OO0oo alignment that overlaps one of the core diagonals + * + * The anchor-to-left case looks like this: + * + * |Anchor| | ---- Rectangle ---- | + * o---------OO0000000000000oo------ 0: mate diagonal (also core diags!) + * -o---------OO0000000000000oo----- o: "RHS gap" diagonals + * --o---------OO0000000000000oo---- O: "LHS gap" diagonals + * ---oo--------OO0000000000000oo--- *: "LHS extra" diagonals + * -----o--------OO0000000000000oo-- -: cells that can't possibly be + * ------o--------OO0000000000000oo- involved in a valid alignment that + * -------o--------OO0000000000000oo overlaps one of the core diagonals + * XXXXXXXXXXXXX + * | RHS Range | + * ^ ^ + * rl rr + * + * The anchor-to-right case looks like this: + * + * ll lr + * v v + * | LHS Range | + * XXXXXXXXXXXXX |Anchor| + * OO0000000000000oo--------o-------- 0: mate diagonal (also core diags!) + * -OO0000000000000oo--------o------- o: "RHS gap" diagonals + * --OO0000000000000oo--------o------ O: "LHS gap" diagonals + * ---OO0000000000000oo--------oo---- *: "LHS extra" diagonals + * ----OO0000000000000oo---------o--- -: cells that can't possibly be + * -----OO0000000000000oo---------o-- involved in a valid alignment that + * ------OO0000000000000oo---------o- overlaps one of the core diagonals + * | ---- Rectangle ---- | + */ +bool SwAligner::gatherCellsNucleotidesLocalSseU8(TAlScore best) { + // What's the minimum number of rows that can possibly be spanned by an + // alignment that meets the minimum score requirement? + assert(sse8succ_); + size_t bonus = (size_t)sc_->match(30); + const size_t ncol = lastsolcol_ + 1; + const size_t nrow = dpRows(); + assert_gt(nrow, 0); + btncand_.clear(); + btncanddone_.clear(); + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + assert(!d.profbuf_.empty()); + //const size_t rowstride = d.mat_.rowstride(); + //const size_t colstride = d.mat_.colstride(); + size_t iter = (dpRows() + (NWORDS_PER_REG - 1)) / NWORDS_PER_REG; + assert_gt(iter, 0); + assert_geq(minsc_, 0); + assert_gt(bonus, 0); + size_t minrow = (size_t)(((minsc_ + bonus - 1) / bonus) - 1); + for(size_t j = 0; j < ncol; j++) { + // Establish the range of rows where a backtrace from the cell in this + // row/col is close enough to one of the core diagonals that it could + // conceivably count + size_t nrow_lo = MIN_SIZE_T; + size_t nrow_hi = nrow; + // First, check if there is a cell in this column with a score + // above the score threshold + __m128i vmax = *d.mat_.tmpvec(0, j); + __m128i vtmp = _mm_srli_si128(vmax, 8); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 4); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 2); + vmax = _mm_max_epu8(vmax, vtmp); + vtmp = _mm_srli_si128(vmax, 1); + vmax = _mm_max_epu8(vmax, vtmp); + int score = _mm_extract_epi16(vmax, 0); + score = score & 0x00ff; +#ifndef NDEBUG + { + // Start in upper vector row and move down + TAlScore max = 0; + __m128i *pvH = d.mat_.hvec(0, j); + for(size_t i = 0; i < iter; i++) { + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + TAlScore sc = (TAlScore)((TCScore*)pvH)[k]; + if(sc > max) { + max = sc; + } + } + pvH += ROWSTRIDE; + } + assert_eq(max, score); + } +#endif + if((TAlScore)score < minsc_) { + // Scores in column aren't good enough + continue; + } + // Get pointer to first cell in column to examine: + __m128i *pvHorig = d.mat_.hvec(0, j); + __m128i *pvH = pvHorig; + // Get pointer to the vector in the following column that corresponds + // to the cells diagonally down and to the right from the cells in pvH + __m128i *pvHSucc = (j < ncol-1) ? d.mat_.hvec(0, j+1) : NULL; + // Start in upper vector row and move down + for(size_t i = 0; i < iter; i++) { + if(pvHSucc != NULL) { + pvHSucc += ROWSTRIDE; + if(i == iter-1) { + pvHSucc = d.mat_.hvec(0, j+1); + } + } + // Which elements of this vector are exhaustively scored? + size_t rdoff = i; + for(size_t k = 0; k < NWORDS_PER_REG; k++) { + // Is this row, col one that we can potential backtrace from? + // I.e. are we close enough to a core diagonal? + if(rdoff >= nrow_lo && rdoff < nrow_hi) { + // This cell has been exhaustively scored + if(rdoff >= minrow) { + // ... and it could potentially score high enough + TAlScore sc = (TAlScore)((TCScore*)pvH)[k]; + assert_leq(sc, best); + if(sc >= minsc_) { + // This is a potential solution + bool matchSucc = false; + int readc = (*rd_)[rdoff]; + int refc = rf_[j + rfi_]; + bool match = ((refc & (1 << readc)) != 0); + if(rdoff < dpRows()-1) { + int readcSucc = (*rd_)[rdoff+1]; + int refcSucc = rf_[j + rfi_ + 1]; + assert_range(0, 16, refcSucc); + matchSucc = ((refcSucc & (1 << readcSucc)) != 0); + } + if(match && !matchSucc) { + // Yes, this is legit + met.gathsol++; + btncand_.expand(); + btncand_.back().init(rdoff, j, sc); + } + } + } + } else { + // Already saw every element in the vector that's been + // exhaustively scored + break; + } + rdoff += iter; + } + pvH += ROWSTRIDE; + } + } + if(!btncand_.empty()) { + d.mat_.initMasks(); + } + return !btncand_.empty(); +} + +#define MOVE_VEC_PTR_UP(vec, rowvec, rowelt) { \ + if(rowvec == 0) { \ + rowvec += d.mat_.nvecrow_; \ + vec += d.mat_.colstride_; \ + rowelt--; \ + } \ + rowvec--; \ + vec -= ROWSTRIDE; \ +} + +#define MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt) { vec -= d.mat_.colstride_; } + +#define MOVE_VEC_PTR_UPLEFT(vec, rowvec, rowelt) { \ + MOVE_VEC_PTR_UP(vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(vec, rowvec, rowelt); \ +} + +#define MOVE_ALL_LEFT() { \ + MOVE_VEC_PTR_LEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_LEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UP() { \ + MOVE_VEC_PTR_UP(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UP(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UP(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define MOVE_ALL_UPLEFT() { \ + MOVE_VEC_PTR_UPLEFT(cur_vec, rowvec, rowelt); \ + MOVE_VEC_PTR_UPLEFT(left_vec, left_rowvec, left_rowelt); \ + MOVE_VEC_PTR_UPLEFT(up_vec, up_rowvec, up_rowelt); \ + MOVE_VEC_PTR_UPLEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +#define NEW_ROW_COL(row, col) { \ + rowelt = row / d.mat_.nvecrow_; \ + rowvec = row % d.mat_.nvecrow_; \ + eltvec = (col * d.mat_.colstride_) + (rowvec * ROWSTRIDE); \ + cur_vec = d.mat_.matbuf_.ptr() + eltvec; \ + left_vec = cur_vec; \ + left_rowelt = rowelt; \ + left_rowvec = rowvec; \ + MOVE_VEC_PTR_LEFT(left_vec, left_rowvec, left_rowelt); \ + up_vec = cur_vec; \ + up_rowelt = rowelt; \ + up_rowvec = rowvec; \ + MOVE_VEC_PTR_UP(up_vec, up_rowvec, up_rowelt); \ + upleft_vec = up_vec; \ + upleft_rowelt = up_rowelt; \ + upleft_rowvec = up_rowvec; \ + MOVE_VEC_PTR_LEFT(upleft_vec, upleft_rowvec, upleft_rowelt); \ +} + +/** + * Given the dynamic programming table and a cell, trace backwards from the + * cell and install the edits and score/penalty in the appropriate fields + * of SwResult res, which contains an AlnRes. The RandomSource is used to + * break ties among equally good ways of tracing back. + * + * Upon entering a cell, we check if the read/ref coordinates of the cell + * correspond to a cell we traversed constructing a previous alignment. If so, + * we backtrack to the last decision point, mask out the path that led to the + * previously observed cell, and continue along a different path; or, if there + * are no more paths to try, we give up. + * + * An alignment found is subject to a filtering step designed to remove + * alignments that could spuriously trump a better alignment falling partially + * outside the rectangle. + * + * 1 + * 67890123456 0: seed diagonal + * **OO0oo---- o: right-hand "gap" diagonals: band of 'maxgap' diags + * -**OO0oo--- O: left-hand "gap" diagonals: band of 'maxgap' diags + * --**OO0oo-- *: "extra" diagonals: additional band of 'maxgap' diags + * ---**OO0oo- +: cells not in any of the above + * ----**OO0oo + * |-| + * Gotta touch one of these diags + * + * Basically, the filtering step removes alignments that do not at some point + * touch a cell labeled '0' or 'O' in the diagram above. + * + */ +bool SwAligner::backtraceNucleotidesLocalSseU8( + TAlScore escore, // in: expected score + SwResult& res, // out: store results (edits and scores) here + size_t& off, // out: store diagonal projection of origin + size_t& nbts, // out: # backtracks + size_t row, // start in this row + size_t col, // start in this column + RandomSource& rnd) // random gen, to choose among equal paths +{ + assert_lt(row, dpRows()); + assert_lt(col, (size_t)(rff_ - rfi_)); + SSEData& d = fw_ ? sseU8fw_ : sseU8rc_; + SSEMetrics& met = extend_ ? sseU8ExtendMet_ : sseU8MateMet_; + met.bt++; + assert(!d.profbuf_.empty()); + assert_lt(row, rd_->length()); + btnstack_.clear(); // empty the backtrack stack + btcells_.clear(); // empty the cells-so-far list + AlnScore score; score.score_ = 0; + score.gaps_ = score.ns_ = 0; + size_t origCol = col; + size_t gaps = 0, readGaps = 0, refGaps = 0; + res.alres.reset(); + EList& ned = res.alres.ned(); + assert(ned.empty()); + assert_gt(dpRows(), row); + size_t trimEnd = dpRows() - row - 1; + size_t trimBeg = 0; + size_t ct = SSEMatrix::H; // cell type + // Row and col in terms of where they fall in the SSE vector matrix + size_t rowelt, rowvec, eltvec; + size_t left_rowelt, up_rowelt, upleft_rowelt; + size_t left_rowvec, up_rowvec, upleft_rowvec; + __m128i *cur_vec, *left_vec, *up_vec, *upleft_vec; + NEW_ROW_COL(row, col); + while((int)row >= 0) { + met.btcell++; + nbts++; + int readc = (*rd_)[rdi_ + row]; + int refm = (int)rf_[rfi_ + col]; + int readq = (*qu_)[row]; + assert_leq(col, origCol); + // Get score in this cell + bool empty = false, reportedThru, canMoveThru, branch = false; + int cur = SSEMatrix::H; + if(!d.mat_.reset_[row]) { + d.mat_.resetRow(row); + } + reportedThru = d.mat_.reportedThrough(row, col); + canMoveThru = true; + if(reportedThru) { + canMoveThru = false; + } else { + empty = false; + if(row > 0) { + assert_gt(row, 0); + size_t rowFromEnd = d.mat_.nrow() - row - 1; + bool gapsAllowed = true; + if(row < (size_t)sc_->gapbar || + rowFromEnd < (size_t)sc_->gapbar) + { + gapsAllowed = false; + } + const int floorsc = 0; + const int offsetsc = 0; + // Move to beginning of column/row + if(ct == SSEMatrix::E) { // AKA rdgap + assert_gt(col, 0); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::E))[rowelt] + offsetsc; + assert(gapsAllowed); + // Currently in the E matrix; incoming transition must come from the + // left. It's either a gap open from the H matrix or a gap extend from + // the E matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell to the left + TAlScore sc_h_left = ((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc; + if(sc_h_left > 0 && sc_h_left - sc_->readGapOpen() == sc_cur) { + mask |= (1 << 0); + } + // Get E score of cell to the left + TAlScore sc_e_left = ((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc; + if(sc_e_left > 0 && sc_e_left - sc_->readGapExtend() == sc_cur) { + mask |= (1 << 1); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isEMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 8) & 3; + } + if(mask == 3) { +#if 1 + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // Pick H -> E cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 2); // might choose E later + } else { + // Pick E -> E cell + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 1); // might choose H later + } +#endif + branch = true; + } else if(mask == 2) { + // I chose the E cell + cur = SW_BT_RDGAP_EXTEND; + d.mat_.eMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_READ_OPEN; + d.mat_.eMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + assert(!empty || !canMoveThru); + } else if(ct == SSEMatrix::F) { // AKA rfgap + assert_gt(row, 0); + assert(gapsAllowed); + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::F))[rowelt] + offsetsc; + // Currently in the F matrix; incoming transition must come from above. + // It's either a gap open from the H matrix or a gap extend from the F + // matrix. + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + // Get H score of cell above + if(sc_h_up > floorsc && sc_h_up - sc_->refGapOpen() == sc_cur) { + mask |= (1 << 0); + } + // Get F score of cell above + if(sc_f_up > floorsc && sc_f_up - sc_->refGapExtend() == sc_cur) { + mask |= (1 << 1); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isFMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 11) & 3; + } + if(mask == 3) { +#if 1 + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later +#else + if(rnd.nextU2()) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 2); // might choose E later + } else { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 1); // might choose E later + } +#endif + branch = true; + } else if(mask == 2) { + // I chose the F cell + cur = SW_BT_RFGAP_EXTEND; + d.mat_.fMaskSet(row, col, 0); // done + } else if(mask == 1) { + // I chose the H cell + cur = SW_BT_OALL_REF_OPEN; + d.mat_.fMaskSet(row, col, 0); // done + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + assert(!empty || !canMoveThru); + } else { + assert_eq(SSEMatrix::H, ct); + TAlScore sc_cur = ((TCScore*)(cur_vec + SSEMatrix::H))[rowelt] + offsetsc; + TAlScore sc_f_up = ((TCScore*)(up_vec + SSEMatrix::F))[up_rowelt] + offsetsc; + TAlScore sc_h_up = ((TCScore*)(up_vec + SSEMatrix::H))[up_rowelt] + offsetsc; + TAlScore sc_h_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::H))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_e_left = col > 0 ? (((TCScore*)(left_vec + SSEMatrix::E))[left_rowelt] + offsetsc) : floorsc; + TAlScore sc_h_upleft = col > 0 ? (((TCScore*)(upleft_vec + SSEMatrix::H))[upleft_rowelt] + offsetsc) : floorsc; + TAlScore sc_diag = sc_->score(readc, refm, readq - 33); + // TODO: save and restore origMask as well as mask + int origMask = 0, mask = 0; + if(gapsAllowed) { + if(sc_h_up > floorsc && sc_cur == sc_h_up - sc_->refGapOpen()) { + mask |= (1 << 0); + } + if(sc_h_left > floorsc && sc_cur == sc_h_left - sc_->readGapOpen()) { + mask |= (1 << 1); + } + if(sc_f_up > floorsc && sc_cur == sc_f_up - sc_->refGapExtend()) { + mask |= (1 << 2); + } + if(sc_e_left > floorsc && sc_cur == sc_e_left - sc_->readGapExtend()) { + mask |= (1 << 3); + } + } + if(sc_h_upleft > floorsc && sc_cur == sc_h_upleft + sc_diag) { + mask |= (1 << 4); + } + origMask = mask; + assert(origMask > 0 || sc_cur <= sc_->match()); + if(d.mat_.isHMaskSet(row, col)) { + mask = (d.mat_.masks_[row][col] >> 2) & 31; + } + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + int opts = alts5[mask]; + int select = -1; + if(opts == 1) { + select = firsts5[mask]; + assert_geq(mask, 0); + d.mat_.hMaskSet(row, col, 0); + } else if(opts > 1) { +#if 1 + if( (mask & 16) != 0) { + select = 4; // H diag + } else if((mask & 1) != 0) { + select = 0; // H up + } else if((mask & 4) != 0) { + select = 2; // F up + } else if((mask & 2) != 0) { + select = 1; // H left + } else if((mask & 8) != 0) { + select = 3; // E left + } +#else + select = randFromMask(rnd, mask); +#endif + assert_geq(mask, 0); + mask &= ~(1 << select); + assert(gapsAllowed || mask == (1 << 4) || mask == 0); + d.mat_.hMaskSet(row, col, mask); + branch = true; + } else { /* No way to backtrack! */ } + if(select != -1) { + if(select == 4) { + cur = SW_BT_OALL_DIAG; + } else if(select == 0) { + cur = SW_BT_OALL_REF_OPEN; + } else if(select == 1) { + cur = SW_BT_OALL_READ_OPEN; + } else if(select == 2) { + cur = SW_BT_RFGAP_EXTEND; + } else { + assert_eq(3, select) + cur = SW_BT_RDGAP_EXTEND; + } + } else { + empty = true; + // It's empty, so the only question left is whether we should be + // allowed in terimnate in this cell. If it's got a valid score + // then we *shouldn't* be allowed to terminate here because that + // means it's part of a larger alignment that was already reported. + canMoveThru = (origMask == 0); + } + } + assert(!empty || !canMoveThru || ct == SSEMatrix::H); + } + } + d.mat_.setReportedThrough(row, col); + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + // Cell was involved in a previously-reported alignment? + if(!canMoveThru) { + if(!btnstack_.empty()) { + // Remove all the cells from list back to and including the + // cell where the branch occurred + btcells_.resize(btnstack_.back().celsz); + // Pop record off the top of the stack + ned.resize(btnstack_.back().nedsz); + //aed.resize(btnstack_.back().aedsz); + row = btnstack_.back().row; + col = btnstack_.back().col; + gaps = btnstack_.back().gaps; + readGaps = btnstack_.back().readGaps; + refGaps = btnstack_.back().refGaps; + score = btnstack_.back().score; + ct = btnstack_.back().ct; + btnstack_.pop_back(); + assert(!sc_->monotone || score.score() >= escore); + NEW_ROW_COL(row, col); + continue; + } else { + // No branch points to revisit; just give up + res.reset(); + met.btfail++; // DP backtraces failed + return false; + } + } + assert(!reportedThru); + assert(!sc_->monotone || score.score() >= minsc_); + if(empty || row == 0) { + assert_eq(SSEMatrix::H, ct); + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + // This cell is at the end of a legitimate alignment + trimBeg = row; + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + break; + } + if(branch) { + // Add a frame to the backtrack stack + btnstack_.expand(); + btnstack_.back().init( + ned.size(), + 0, // aed.size() + btcells_.size(), + row, + col, + gaps, + readGaps, + refGaps, + score, + (int)ct); + } + btcells_.expand(); + btcells_.back().first = row; + btcells_.back().second = col; + switch(cur) { + // Move up and to the left. If the reference nucleotide in the + // source row mismatches the read nucleotide, penalize + // it and add a nucleotide mismatch. + case SW_BT_OALL_DIAG: { + assert_gt(row, 0); assert_gt(col, 0); + // Check for color mismatch + int readC = (*rd_)[row]; + int refNmask = (int)rf_[rfi_+col]; + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + ct = SSEMatrix::H; + if(m != 1) { + Edit e( + (int)row, + mask2dna[refNmask], + "ACGTN"[readC], + EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + int pen = QUAL2(row, col); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= escore); + } else { + // Reward a match + int64_t bonus = sc_->match(30); + score.score_ += bonus; + assert(!sc_->monotone || score.score() >= escore); + } + if(m == -1) { + score.ns_++; + } + row--; col--; + MOVE_ALL_UPLEFT(); + assert(VALID_AL_SCORE(score)); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_OALL_REF_OPEN: + { + assert_gt(row, 0); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::H; + int pen = sc_->refGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + // Move up. Add an edit encoding the ref gap. + case SW_BT_RFGAP_EXTEND: + { + assert_gt(row, 1); + Edit e( + (int)row, + '-', + "ACGTN"[(int)(*rd_)[row]], + EDIT_TYPE_REF_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + row--; + ct = SSEMatrix::F; + int pen = sc_->refGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; refGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_UP(); + break; + } + case SW_BT_OALL_READ_OPEN: + { + assert_gt(col, 0); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::H; + int pen = sc_->readGapOpen(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + case SW_BT_RDGAP_EXTEND: + { + assert_gt(col, 1); + Edit e( + (int)row+1, + mask2dna[(int)rf_[rfi_+col]], + '-', + EDIT_TYPE_READ_GAP); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + assert_geq(row, (size_t)sc_->gapbar); + assert_geq((int)(rdf_-rdi_-row-1), sc_->gapbar-1); + col--; + ct = SSEMatrix::E; + int pen = sc_->readGapExtend(); + score.score_ -= pen; + assert(!sc_->monotone || score.score() >= minsc_); + gaps++; readGaps++; + assert_eq(gaps, Edit::numGaps(ned)); + assert_leq(gaps, rdgap_ + rfgap_); + MOVE_ALL_LEFT(); + break; + } + default: throw 1; + } + } // while((int)row > 0) + assert_geq(col, 0); + assert_eq(SSEMatrix::H, ct); + // The number of cells in the backtracs should equal the number of read + // bases after trimming plus the number of gaps + assert_eq(btcells_.size(), dpRows() - trimBeg - trimEnd + readGaps); + // Check whether we went through a core diagonal and set 'reported' flag on + // each cell + bool overlappedCoreDiag = false; + for(size_t i = 0; i < btcells_.size(); i++) { + size_t rw = btcells_[i].first; + size_t cl = btcells_[i].second; + // Calculate the diagonal within the *trimmed* rectangle, i.e. the + // rectangle we dealt with in align, gather and backtrack. + int64_t diagi = cl - rw; + // Now adjust to the diagonal within the *untrimmed* rectangle by + // adding on the amount trimmed from the left. + diagi += rect_->triml; + if(diagi >= 0) { + size_t diag = (size_t)diagi; + if(diag >= rect_->corel && diag <= rect_->corer) { + overlappedCoreDiag = true; + break; + } + } +#ifndef NDEBUG + //assert(!d.mat_.reportedThrough(rw, cl)); + //d.mat_.setReportedThrough(rw, cl); + assert(d.mat_.reportedThrough(rw, cl)); +#endif + } + if(!overlappedCoreDiag) { + // Must overlap a core diagonal. Otherwise, we run the risk of + // reporting an alignment that overlaps (and trumps) a higher-scoring + // alignment that lies partially outside the dynamic programming + // rectangle. + res.reset(); + met.corerej++; + return false; + } + int readC = (*rd_)[rdi_+row]; // get last char in read + int refNmask = (int)rf_[rfi_+col]; // get last ref char ref involved in aln + assert_gt(refNmask, 0); + int m = matchesEx(readC, refNmask); + if(m != 1) { + Edit e((int)row, mask2dna[refNmask], "ACGTN"[readC], EDIT_TYPE_MM); + assert(e.repOk()); + assert(ned.empty() || ned.back().pos >= row); + ned.push_back(e); + score.score_ -= QUAL2(row, col); + assert_geq(score.score(), minsc_); + } else { + score.score_ += sc_->match(30); + } + if(m == -1) { + score.ns_++; + } + if(score.ns_ > nceil_) { + // Alignment has too many Ns in it! + res.reset(); + met.nrej++; + return false; + } + res.reverse(); + assert(Edit::repOk(ned, (*rd_))); + assert_eq(score.score(), escore); + assert_leq(gaps, rdgap_ + rfgap_); + off = col; + assert_lt(col + (size_t)rfi_, (size_t)rff_); + score.gaps_ = gaps; + res.alres.setScore(score); + res.alres.setShape( + refidx_, // ref id + off + rfi_ + rect_->refl, // 0-based ref offset + reflen_, // reference length + fw_, // aligned to Watson? + rdf_ - rdi_, // read length + 0, // read ID + true, // pretrim soft? + 0, // pretrim 5' end + 0, // pretrim 3' end + true, // alignment trim soft? + fw_ ? trimBeg : trimEnd, // alignment trim 5' end + fw_ ? trimEnd : trimBeg); // alignment trim 3' end + size_t refns = 0; + for(size_t i = col; i <= origCol; i++) { + if((int)rf_[rfi_+i] > 15) { + refns++; + } + } + res.alres.setRefNs(refns); + assert(Edit::repOk(ned, (*rd_), true, trimBeg, trimEnd)); + assert(res.repOk()); +#ifndef NDEBUG + size_t gapsCheck = 0; + for(size_t i = 0; i < ned.size(); i++) { + if(ned[i].isGap()) gapsCheck++; + } + assert_eq(gaps, gapsCheck); + BTDnaString refstr; + for(size_t i = col; i <= origCol; i++) { + refstr.append(firsts5[(int)rf_[rfi_+i]]); + } + BTDnaString editstr; + Edit::toRef((*rd_), ned, editstr, true, trimBeg, trimEnd); + if(refstr != editstr) { + cerr << "Decoded nucleotides and edits don't match reference:" << endl; + cerr << " score: " << score.score() + << " (" << gaps << " gaps)" << endl; + cerr << " edits: "; + Edit::print(cerr, ned); + cerr << endl; + cerr << " decoded nucs: " << (*rd_) << endl; + cerr << " edited nucs: " << editstr << endl; + cerr << " reference nucs: " << refstr << endl; + assert(0); + } +#endif + met.btsucc++; // DP backtraces succeeded + return true; +} diff --git a/alignment_3n.cpp b/alignment_3n.cpp new file mode 100644 index 0000000..68b1202 --- /dev/null +++ b/alignment_3n.cpp @@ -0,0 +1,193 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#include "alignment_3n.h" +#include "aln_sink.h" + + +/** + * return true if two location is concordant. + * return false, if there are not concordant or too far (>maxPairDistance). + */ +bool Alignment::isConcordant(long long int location1, bool &forward1, long long int readLength1, long long int location2, bool &forward2, long long int readLength2) { + if (forward1 == forward2) // same direction + { + return false; + } + // adjust the location of the start of the read + if (!forward1) + { + location1 = location1 + readLength1 - 1; + } + if (!forward2) + { + location2 = location2 + readLength2 - 1; + } + // return false if two reads are too far from each other + if (abs(location1-location2) > maxPairDistance) + { + return false; + } + + if (location1 == location2) + { + return true; + } + else if (location1 < location2) + { + if (forward1 && !forward2) + { + return true; + } + } + else + { + if (!forward1 && forward2) + { + return true; + } + } + return false; +} + +/** + * this is the basic function to calculate DNA pair score. + * if the distance between 2 alignments is more than penaltyFreeDistance_DNA, we reduce the score by the distance/100. + * if two alignment is concordant we add concordantScoreBounce to make sure to select the concordant pair as best pair. + */ +int Alignment::calculatePairScore_DNA (long long int &location0, int& AS0, bool& forward0, long long int readLength0, long long int &location1, int &AS1, bool &forward1, long long int readLength1, bool& concordant) { + + int score = ASPenalty*AS0 + ASPenalty*AS1; + int distance = abs(location0 - location1); + if (distance > maxPairDistance) { return numeric_limits::min(); } + if (distance > penaltyFreeDistance_DNA) { score -= distance/distancePenaltyFraction_DNA; } + concordant = isConcordant(location0, forward0, readLength0, location1, forward1, readLength1); + if (concordant) { score += concordantScoreBounce; } + return score; +} + +/** + * this is the basic function to calculate RNA pair score. + * if the distance between 2 alignments is more than penaltyFreeDistance_RNA, we reduce the score by the distance/1000. + * if two alignment is concordant we add concordantScoreBounce to make sure to select the concordant pair as best pair. + */ +int Alignment::calculatePairScore_RNA (long long int &location0, int& XM0, bool& forward0, long long int readLength0, long long int &location1, int &XM1, bool &forward1, long long int readLength1, bool& concordant) { + // this is the basic function to calculate pair score. + // if the distance between 2 alignment is more than 100,000, we reduce the score by the distance/1000. + // if two alignment is concordant we add 500,000 to make sure to select the concordant pair as best pair. + int score = -ASPenalty*XM0 + -ASPenalty*XM1; + int distance = abs(location0 - location1); + if (distance > maxPairDistance) { return numeric_limits::min(); } + if (distance > penaltyFreeDistance_RNA) { score -= distance/distancePenaltyFraction_RNA; } + concordant = isConcordant(location0, forward0, readLength0, location1, forward1, readLength1); + if (concordant) { score += concordantScoreBounce; } + return score; +} + +/** + * calculate the pairScore for a pair of alignment result. Output pair Score and number of pair. + * Do not update their pairScore. + */ +int Alignment::calculatePairScore(Alignment *inputAlignment, int &nPair) { + int pairScore = numeric_limits::min(); + nPair = 0; + if (pairSegment == inputAlignment->pairSegment){ + // when 2 alignment results are from same pair segment, output the lowest score and number of pair equal zero. + pairScore = numeric_limits::min(); + } else if (!mapped && !inputAlignment->mapped) { + // both unmapped. + pairScore = numeric_limits::min()/2 - 1; + } else if (!mapped || !inputAlignment->mapped) { + // one of the segment unmapped. + pairScore = numeric_limits::min()/2; + nPair = 1; + } else if ((!repeat && !inputAlignment->repeat)){ + // both mapped and (both non-repeat or not expand repeat) + bool concordant; + if (DNA) { + pairScore = calculatePairScore_DNA(location, + AS, + forward, + readSequence.length(), + inputAlignment->location, + inputAlignment->AS, + inputAlignment->forward, + inputAlignment->readSequence.length(), + concordant); + } else { + pairScore = calculatePairScore_RNA(location, + XM, + forward, + readSequence.length(), + inputAlignment->location, + inputAlignment->XM, + inputAlignment->forward, + inputAlignment->readSequence.length(), + concordant); + } + setConcordant(concordant); + inputAlignment->setConcordant(concordant); + nPair = 1; + } + return pairScore; +} + +void Alignments::reportStats_single(ReportingMetrics& met) { + + int nAlignment = alignmentPositions.nBestSingle; + if (nAlignment == 0) { + met.nunp_0++; + } else { + met.nunp_uni++; + if (nAlignment == 1) { met.nunp_uni1++; } + else { met.nunp_uni2++; } + } +} + +void Alignments::reportStats_paired(ReportingMetrics& met) { + if (!alignmentPositions.concordantExist) { + met.nconcord_0++; + if (alignmentPositions.nBestPair == 0) { + met.nunp_0_0 += 2; + return; + } + if (alignmentPositions.bestPairScore == numeric_limits::min()/2) { + // one mate is unmapped, one mate is mapped + met.nunp_0_0++; + met.nunp_0_uni++; + if (alignmentPositions.nBestPair == 1) { met.nunp_0_uni1++; } + else { met.nunp_0_uni2++; } + } else { //both mate is mapped + if (alignmentPositions.nBestPair == 1) { + met.ndiscord++; + return; + } + else { + met.nunp_0_uni += 2; + met.nunp_0_uni2 += 2; + } + } + } else { + assert(alignmentPositions.nBestPair > 0); + met.nconcord_uni++; + if (alignmentPositions.nBestPair == 1) { met.nconcord_uni1++; } + else { met.nconcord_uni2++; } + } +} + diff --git a/alignment_3n.h b/alignment_3n.h new file mode 100644 index 0000000..deefede --- /dev/null +++ b/alignment_3n.h @@ -0,0 +1,1214 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#ifndef HISAT2_ALIGNMENT_3N_H +#define HISAT2_ALIGNMENT_3N_H + +#include +#include +#include +#include +#include +#include "sstring.h" +#include "util.h" +#include "hisat2lib/ht2.h" +#include "read.h" +#include "outq.h" +#include "reference.h" +#include +#include +#include "position_3n.h" +#include "utility_3n.h" +#include "simple_func.h" + + +extern char usrInput_convertedFrom; +extern char usrInput_convertedTo; +extern char usrInput_convertedFromComplement; +extern char usrInput_convertedToComplement; +extern SimpleFunc scoreMin; // minimum valid score as function of read len +extern int penMmcMax; // max mm penalty + +extern char hs3N_convertedFrom; +extern char hs3N_convertedTo; +extern char hs3N_convertedFromComplement; +extern char hs3N_convertedToComplement; + +extern vector repeatHandles; +extern struct ht2_index_getrefnames_result *refNameMap; +extern int repeatLimit; +extern bool uniqueOutputOnly; +extern int directional3NMapping; + +using namespace std; + +struct ReportingMetrics; + +/** + * the data structure to store all information of one alignment result. + */ +class Alignment { +public: + // basic information + BTString readName; + int flag; + BTString chromosomeName; + int chromosomeIndex; // the chromosome index to use getStretch() function + long long int location; + BTString MAPQ; + BTString cigarString; + vector cigarSegments; + int cigarLength; // this is the length that read cover genome. + BTString pairToChromosome; + long long int pairToLocation; + long long int pairingDistance; + BTString readSequence; + BTString readQuality; + //tags + int AS; // alignment score + int NH; // number of alignment + int XM; // number of mismatch + int NM; // edit distance + int YS; // mate's AS + BTString MD; + BTString YT; //"UU" for single-end. "CP" for concordant alignment, "DP" for disconcordant alignment, "UP" for else. + // special tags in HISAT-3N + int Yf; // number of conversion. + int Zf; // number of unconverted base. + char YZ; // this tag shows alignment strand: check makeYZ function for the classification rule + // + for REF strand (conversionCount[0] is equal or smaller than conversionCount[1]), + // - for REF-RC strand (conversionCount[1] is smaller) + // unChanged tags + BTString unChangedTags; + BTString passThroughLine; // this is controlled by print_xr_ in SamConfig + + // for pairScore calculation + static const int maxPairDistance = 500000; + static const int penaltyFreeDistance_DNA = 1000; + static const int penaltyFreeDistance_RNA = 100000; + static const int distancePenaltyFraction_DNA = 100; + static const int distancePenaltyFraction_RNA = 1000; + static const int ASPenalty = 100; + static const int concordantScoreBounce = 500000; + + // intermediate variable + bool outputted = false; // whether the alignment is outputted. + bool DNA = false; + int cycle_3N; // indicate which cycle_3N make this alignment result. 0 or 3 for repeatHandles[0], else repeatHandles[1] + bool paired; + bool forward; + bool mapped; + bool concordant; + int64_t MinimumScore; + int pairSegment; // 0 for first segment, 1 for second segment. + struct ht2_repeat_expand_result *repeatResult = nullptr; + int pairScore; // to identify the better pair + bool mateMapped; // to adjust the YT tag + bool repeat; + bool pairToRepeat; + RepeatMappingPositions repeatPositions; // to store the expanded repeat information + int conversionCount[2] = {0}; // there are two type of conversion could happen, save the number of conversion separately. + int unConversionCount[2] = {0}; // save the unconverted base count. + string intToBase = "ACGTN"; + + void initialize() { + readName.clear(); + flag = -1; + chromosomeName.clear(); + chromosomeIndex = -1; + location = 0; + MAPQ.clear(); + cigarString.clear(); + cigarSegments.clear(); + cigarLength = 0; + pairToChromosome.clear(); + pairToLocation = 0; + pairingDistance = 0; + readSequence.clear(); + readQuality.clear(); + + AS = numeric_limits::min(); + NH = 0; + XM = 0; + NM = 0; + YS = 0; + MD.clear(); + YT.clear(); + Yf = 0; + Zf = 0; + unChangedTags.clear(); + + outputted = false; + DNA = false; + cycle_3N = -1; + paired = false; + forward = false; + mapped = false; + concordant = false; + pairSegment = 0; + if (repeatResult != nullptr) { + free(repeatResult); + repeatResult = nullptr; + } + pairScore = numeric_limits::min(); + mateMapped = false; + + repeat = false; + pairToRepeat = false; + repeatPositions.initialize(); + conversionCount[0] = 0; + conversionCount[1] = 0; + unConversionCount[0] = 0; + unConversionCount[1] = 0; + passThroughLine.clear(); + } + + Alignment() { + initialize(); + } + + ~Alignment() { + if (repeatResult != nullptr) free(repeatResult); + } + + /** + * change YS tag for output. + */ + void setYS (Alignment* input) { + YS = input->AS; + } + + void setYS(RepeatMappingPosition* input) { + YS = input->AS; + } + + /** + * change concordant status and flag + */ + void setConcordant(bool concordant_) { + concordant = concordant_; + if (concordant) { + flag |= 2; + } else { + flag &= ~((int)2); + } + } + + /** + * change mateMapped status and flag + */ + void setMateMappingFlag(long long int *mateLocation) { + if (mateLocation == NULL) { return; } + mateMapped = *mateLocation != 0; + if ((flag&8) && mateMapped) flag -= 8; + else if (!(flag&8) && !mateMapped) flag += 8; + } + + /** + * change YT tag base on mateMapped and concordant information. + */ + void setYT() { + if (paired) { + if (!mateMapped) { + YT = "UP"; + return; + } + if (concordant) { YT = "CP"; } + else { YT = "DP"; } + } else { + YT = "UU"; + } + } + + /** + * update NH and MAPQ by number of alignment. + */ + void updateNH(int nAlignment) { + if (!mapped) return; + NH = nAlignment; + if (nAlignment == 0) return; + else if (nAlignment == 1) MAPQ = "60"; + else MAPQ = "1"; + } + + /** + * extract information from flag, change flag to secondary alignment. + */ + void extractFlagInfo() { + paired = (flag & 1) != 0; + forward = (flag & 16) == 0; + if ((flag & 256) == 0) { // change all read to secondary alignment + flag += 256; + } + mapped = (flag & 4) == 0; + if (flag & 128) { + pairSegment = 1; + } else { + pairSegment = 0; // it could be the first pair segment or it is single read. + } + concordant = (flag & 2) != 0; + if (!mapped) { + repeat = false; + } + MinimumScore = scoreMin.f(readSequence.length()); + } + + /** + * calculate the pairScore for a pair of alignment result. Output pair Score and number of pair. + * Do not update their pairScore. + */ + int calculatePairScore(Alignment *inputAlignment, int &nPair); + + /** + * make YZ tag. + * if (no conversion) or (conversion type 0 == conversion type 1) or (directional mapping): + * if the (pairSegment is 0) && (forward) => YZ = REF (+) + * if the (pairSegment is 0) && (reverse) => YZ = REF-RC (-) + * if the (pairSegment is 1) && (forward) => YZ = REF-RC (-) + * if the (pairSegment is 1) && (reverse) => YZ = REF (+) + * if the conversion type 0 is less, the read is mapped to REF (+). + * if the conversion type 1 is less, the read is mapped to REF-RC (-). + */ + void makeYZ(char &YZ_string) { + if (directional3NMapping == 2){ + if (pairSegment == 0 && forward) { + YZ_string = '-'; + } else if (pairSegment == 0 && !forward) { + YZ_string = '+'; + } else if (pairSegment == 1 && forward) { + YZ_string = '+'; + } else if (pairSegment == 1 && !forward) { + YZ_string = '-'; + } + } else if (directional3NMapping == 1 || (conversionCount[0] == 0 && conversionCount[1] == 0) || conversionCount[0] == conversionCount[1]){ + if (pairSegment == 0 && forward) { + YZ_string = '+'; + } else if (pairSegment == 0 && !forward) { + YZ_string = '-'; + } else if (pairSegment == 1 && forward) { + YZ_string = '-'; + } else if (pairSegment == 1 && !forward) { + YZ_string = '+'; + } + } else if (conversionCount[0] >= conversionCount[1]) { + YZ_string = '+'; + } else { + YZ_string = '-'; + } + } + + /** + * make Yf tag, Yf tag is to count the number of conversion in the string. + * use YZ tag to decide which type of conversion is legal conversion. + */ + int makeYf(char YZTag) { + int outYf = -1; + if (YZTag == '+'){ + outYf = conversionCount[0]; + } else if (YZTag == '-'){ + outYf = conversionCount[1]; + } + assert(outYf >= 0); + return outYf; + } + + /** + * make Zf tag, Zf tag is to count the number of un-converted base in the string. + * use YZ tag to decide which type of conversion is legal conversion. + */ + int makeZf(char YZTag) { + int outZf = -1; + if (YZTag == '+'){ + outZf = unConversionCount[0]; + } else if (YZTag == '-'){ + outZf = unConversionCount[1]; + } + assert (outZf >= 0); + return outZf; + } + + /** + * expand the repeat mapping location and construct MD for each location. + * return ture if there is any mapping location pass the filter, else, false. + */ + bool constructRepeatMD(BitPairReference* bitReference, MappingPositions &alignmentPositions) { + + if (!mapped) { + return true; + } + + // expand the repeat locations + ht2_error_t err = ht2_repeat_expand((cycle_3N == 0 || cycle_3N == 3) ? repeatHandles[0] : repeatHandles[1], + chromosomeName.toZBuf(), + location - 1, + readSequence.length(), + &repeatResult); + + BTString chromosomeRepeat; + long long int locationRepeat; + for (int i = 0; i < repeatResult->count; i++) { + struct ht2_position *pos = &repeatResult->positions[i]; + chromosomeRepeat = refNameMap->names[pos->chr_id]; + for (int j = 0; j < chromosomeRepeat.length(); j++) { + if (chromosomeRepeat[j] == ' ') { + chromosomeRepeat.trimEnd(chromosomeRepeat.length() - j); + break; + } + } + locationRepeat = (pos->pos) + 1; + bool genomeForward = pos->direction == 0; + if (!genomeForward) { continue; } // if the repeat mapping direction is different to the designed direction, ignore it. + + // if the mapping location is already exist, continue. + if (alignmentPositions.positionExist(chromosomeRepeat, locationRepeat, pairSegment)){ + continue; + } + + // get reference sequence + ASSERT_ONLY(SStringExpandable destU32); + SStringExpandable raw_refbuf; + raw_refbuf.resize(cigarLength + 16); + raw_refbuf.clear(); + int off = bitReference->getStretch( + reinterpret_cast(raw_refbuf.wbuf()), + (size_t)pos->chr_id, + (size_t)max(locationRepeat-1, 0), + (size_t)cigarLength ASSERT_ONLY(, destU32)); + char* refSeq = raw_refbuf.wbuf() + off; + BTString refSequence; + refSequence.resize(cigarLength); + for (int j = 0; j < cigarLength; j++) { + refSequence.set(intToBase[*(refSeq + j)], j); + } + + // check whether the refSequence is exist. if do, directly append the repeat. + int repeatPositionsIndex; + if (repeatPositions.sequenceExist(refSequence, repeatPositionsIndex)) { + repeatPositions.append(chromosomeRepeat, locationRepeat, repeatPositionsIndex); + continue; + } + + BTString newMD; + int newMismatch = 0; + char repeatYZ; + int repeatYf; + int repeatZf; + if (!constructRepeatMD(refSequence, newMD, newMismatch, repeatYf, repeatZf, repeatYZ)) { + continue; + } + + int newXM = XM + newMismatch; + int newNM = NM + newMismatch; + int newAS = AS - penMmcMax * newMismatch; + if (newAS < MinimumScore) + { + continue; + } + repeatPositions.append(locationRepeat, chromosomeRepeat, refSequence,newAS, newMD, newXM, newNM, repeatYf, repeatZf, repeatYZ); + + // if there are too many mappingPosition exist return. + if (repeatPositions.size() >= repeatLimit || alignmentPositions.size() > repeatLimit) { + return true; + } + } + if (repeatPositions.size() == 0) { + return false; + } else { + return true; + } + } + + /** + * for each repeat mapping position, construct its MD + * return true if the mapping result does not have a lot of mismatch, else return false. + */ + bool constructRepeatMD(BTString &refSeq, BTString &newMD_String, int &newMismatch, int& repeatYf, int& repeatZf, char &repeatYZ) { + char buf[1024]; + + conversionCount[0] = 0; + conversionCount[1] = 0; + unConversionCount[0] = 0; + unConversionCount[1] = 0; + + int readPos = 0; + long long int refPos = 0; + int count = 0; + int newXM = 0; + + char cigarSymbol; + int cigarLen; + for (int i = 0; i < cigarSegments.size(); i++) { + cigarSymbol = cigarSegments[i].getLabel(); + cigarLen = cigarSegments[i].getLen(); + + if (cigarSymbol == 'S') { + readPos += cigarLen; + } else if (cigarSymbol == 'N') { + refPos += cigarLen; + } else if (cigarSymbol == 'M') { + for (int j = 0; j < cigarLen; j++) { + char readChar = readSequence[readPos]; + char refChar = refSeq[refPos]; + if (readChar == refChar) { + if (refChar == usrInput_convertedFrom) + { + unConversionCount[0]++; + } + else if (refChar == usrInput_convertedFromComplement) + { + unConversionCount[1]++; + } + count++; + } else {// mismatch + // output matched count + if (count != 0) { + itoa10(count, buf); + newMD_String.append(buf); + count = 0; + } + // output mismatch + if (!newMD_String.empty() && isalpha(newMD_String[newMD_String.length()-1])) { + newMD_String.append('0'); + } + if ((readChar == usrInput_convertedTo) && (refChar == usrInput_convertedFrom)) { + conversionCount[0]++; + } else if ((readChar == usrInput_convertedToComplement) && (refChar == usrInput_convertedFromComplement)) { + conversionCount[1]++; + } else { + // real mismatch + newXM++; + } + newMD_String.append(refChar); + } + readPos++; + refPos++; + } + } else if (cigarSymbol == 'I') { + readPos += cigarLen; + } else if (cigarSymbol == 'D') { + newMD_String.append('^'); + for (int j = 0; j < cigarLen; j++) { + newMD_String.append(refSeq[refPos]); + refPos++; + } + } + } + + if (count != 0) { + itoa10(count, buf); + newMD_String.append(buf); + } + if (isalpha(newMD_String[0])) { newMD_String.insert('0', 0); } + if (isalpha(newMD_String[newMD_String.length()-1])) { newMD_String.append('0'); } + + makeYZ(repeatYZ); + int badConversion = 0; + // identify the bad conversion number based on repeatYZ; + if (repeatYZ == '+') { + badConversion = conversionCount[1]; + } else { + badConversion = conversionCount[0]; + } + + repeatYf = makeYf(repeatYZ); + repeatZf = makeZf(repeatZf); + + newXM += badConversion; + newMismatch = newXM - XM; + + if (newMismatch < 0){ + newMismatch = 0; + } + + return true; + } + + /** + * for each non-repeat mapping position, construct its MD + * return true if the mapping result does not have a lot of mismatch, else return false. + */ + bool constructMD(BitPairReference* bitReference) { + if (!mapped) { + return true; + } + char buf[1024]; + MD.clear(); + + ASSERT_ONLY(SStringExpandable destU32); + SStringExpandable raw_refbuf; + raw_refbuf.resize(cigarLength + 16); + raw_refbuf.clear(); + int off = bitReference->getStretch( + reinterpret_cast(raw_refbuf.wbuf()), + (size_t)chromosomeIndex, + (size_t)max(location-1, 0), + (size_t)cigarLength ASSERT_ONLY(, destU32)); + char* refSeq = raw_refbuf.wbuf() + off; + + int readPos = 0; + long long int refPos = 0; + int count = 0; + int newXM = 0; + + char cigarSymbol; + int cigarLen; + for (int i = 0; i < cigarSegments.size(); i++) { + cigarSymbol = cigarSegments[i].getLabel(); + cigarLen = cigarSegments[i].getLen(); + if (cigarSymbol == 'S') { + readPos += cigarLen; + } else if (cigarSymbol == 'N') { + refPos += cigarLen; + } else if (cigarSymbol == 'M') { + for (int j = 0; j < cigarLen; j++) { + char readChar = readSequence[readPos]; + char refChar = intToBase[*(refSeq + refPos)]; + if (readChar == refChar) { + if (refChar == usrInput_convertedFrom) + { + unConversionCount[0]++; + } + else if (refChar == usrInput_convertedFromComplement) + { + unConversionCount[1]++; + } + count++; + } else {// mismatch + // output matched count + if (count != 0) { + itoa10(count, buf); + MD.append(buf); + count = 0; + } + // output mismatch + if (!MD.empty() && isalpha(MD[MD.length()-1])) { + MD.append('0'); + } + + if ((readChar == usrInput_convertedTo) && (refChar == usrInput_convertedFrom)) { + conversionCount[0]++; + } else if ((readChar == usrInput_convertedToComplement) && (refChar == usrInput_convertedFromComplement)) { + conversionCount[1]++; + } else { + // real mismatch + newXM++; + } + MD.append(refChar); + } + readPos++; + refPos++; + } + } else if (cigarSymbol == 'I') { + readPos += cigarLen; + } else if (cigarSymbol == 'D') { + if (count != 0) { + itoa10(count, buf); + MD.append(buf); + count = 0; + } + MD.append('^'); + for (int j = 0; j < cigarLen; j++) { + MD.append(intToBase[*(refSeq + refPos)]); + refPos++; + } + } + } + + if (count != 0) { + itoa10(count, buf); + MD.append(buf); + } + if (isalpha(MD[0])) { MD.insert('0', 0); } + if (isalpha(MD[MD.length()-1])) { MD.append('0'); } + + makeYZ(YZ); + int badConversion = 0; + // identify the bad conversion number based on YZ tag; + if (YZ == '+') { + badConversion = conversionCount[1]; + } else { + badConversion = conversionCount[0]; + } + Yf = makeYf(YZ); + Zf = makeZf(YZ); + + newXM += badConversion; + newXM -= XM; + + if (newXM < 0){ + newXM = 0; + } + + + NM += newXM; + XM += newXM; + AS = AS - penMmcMax * newXM; + if (AS < MinimumScore) + { + return false; + } + BTString tmp; + if (pairToRepeat) { + repeatPositions.append(location, chromosomeName, tmp, AS, MD, XM, NM, Yf, Zf, YZ); + } + return true; + } + + /** + * output the tags for non-repeat alignment. + */ + void outputTags(BTString& o) { + char buf[1024]; + if (mapped) { + o.append('\t'); + // AS + assert(AS <= 0); + o.append("AS:i:"); + itoa10(AS, buf); + o.append(buf); + o.append('\t'); + // NH + assert(NH > 0); + o.append("NH:i:"); + itoa10(NH, buf); + o.append(buf); + o.append('\t'); + // XM + assert(XM >= 0); + o.append("XM:i:"); + itoa10(XM, buf); + o.append(buf); + o.append('\t'); + // NM + assert(NM >= 0); + o.append("NM:i:"); + itoa10(NM, buf); + o.append(buf); + o.append('\t'); + // MD + assert(!MD.empty()); + o.append("MD:Z:"); + o.append(MD.toZBuf()); + o.append('\t'); + // YS + if (paired && mateMapped) { + o.append("YS:i:"); + itoa10(YS, buf); + o.append(buf); + o.append('\t'); + } + // YZ + o.append("YZ:A:"); + o.append(YZ); + o.append('\t'); + // Yf + o.append("Yf:i:"); + itoa10(Yf, buf); + o.append(buf); + o.append('\t'); + //Zf + o.append("Zf:i:"); + itoa10(Zf, buf); + o.append(buf); + } + // unchanged Tags + if (!unChangedTags.empty()) { + o.append('\t'); + o.append(unChangedTags.toZBuf()); + } + o.append(passThroughLine.toZBuf()); + } + + /** + * output the tags for repeat alignment. + */ + void outputTags(BTString& o, RepeatMappingPosition* repeatInfo){ + // this function is for repeat alignment output. + char buf[1024]; + o.append('\t'); + // AS + assert(AS <= 0); + o.append("AS:i:"); + itoa10(repeatInfo->AS, buf); + o.append(buf); + o.append('\t'); + // NH + assert(NH > 0); + o.append("NH:i:"); + itoa10(NH, buf); + o.append(buf); + o.append('\t'); + // XM + assert(XM >= 0); + o.append("XM:i:"); + itoa10(repeatInfo->XM, buf); + o.append(buf); + o.append('\t'); + // NM + assert(NM >= 0); + o.append("NM:i:"); + itoa10(repeatInfo->NM, buf); + o.append(buf); + o.append('\t'); + // MD + assert(!MD.empty()); + o.append("MD:Z:"); + o.append(repeatInfo->MD.toZBuf()); + o.append('\t'); + // YS + if (paired) { + o.append("YS:i:"); + itoa10(YS, buf); + o.append(buf); + o.append('\t'); + } + //YT + o.append("YT:Z:"); + o.append(YT.toZBuf()); + o.append('\t'); + // YS + if (paired && mateMapped) { + o.append("YS:i:"); + itoa10(YS, buf); + o.append(buf); + o.append('\t'); + } + // YZ + o.append("YZ:A:"); + o.append(repeatInfo->YZ); + o.append('\t'); + // Yf + o.append("Yf:i:"); + itoa10(repeatInfo->Yf, buf); + o.append(buf); + o.append('\t'); + // Zf + o.append("Zf:i:"); + itoa10(repeatInfo->Zf, buf); + o.append(buf); + + // unchanged Tags + if (!unChangedTags.empty()) { + o.append('\t'); + o.append(unChangedTags.toZBuf()); + } + o.append(passThroughLine.toZBuf()); + } + + /** + * output alignment. this function is for both repeat and non-repeat alignment. + */ + void outputAlignment (BTString& o, RepeatMappingPosition* repeatInfo, long long int* oppoLocation, bool& primaryAlignment) { + + BTString* outputChromosome; + long long int* outputLocation; + + if (repeatInfo == NULL) { + if (outputted) { return; } + outputted = true; + outputChromosome = &chromosomeName; + outputLocation = &location; + } else { + if (repeatInfo->outputted) { return; } + repeatInfo->outputted = true; + outputChromosome = &repeatInfo->repeatChromosome; + outputLocation = &repeatInfo->repeatLocation; + } + + //setMateMappingFlag(oppoLocation); + setYT(); + + char buf[1024]; + // readName + o.append(readName.toZBuf()); + o.append('\t'); + // flag, if it is primary alignment, -256 + assert(flag >=0); + itoa10(flag-primaryAlignment*256, buf); + o.append(buf); + o.append('\t'); + // chromosome + assert(!outputChromosome->empty()); + o.append(outputChromosome->toZBuf()); + o.append('\t'); + // location + assert(*outputLocation >= 0); + itoa10(*outputLocation, buf); + o.append(buf); + o.append('\t'); + + //MAPQ + o.append(MAPQ.toZBuf()); + o.append('\t'); + // cigar + o.append(cigarString.toZBuf()); + o.append('\t'); + // pair to chromosome + if (paired && *oppoLocation!=0) { + o.append("="); + o.append('\t'); + } else { + o.append("*"); + o.append('\t'); + } + // pair to location + if (paired) { + itoa10(*oppoLocation, buf); + o.append(buf); + o.append('\t'); + } else { + o.append('0'); + o.append('\t'); + } + // pairing distance + if (paired) { + itoa10(*oppoLocation - *outputLocation, buf); + o.append(buf); + o.append('\t'); + } else { + o.append('0'); + o.append('\t'); + } + // read sequence + o.append(readSequence.toZBuf()); + o.append('\t'); + // read quality + o.append(readQuality.toZBuf()); + + // make sure there is no '\t' at the beginning of unChangedTags + while (!unChangedTags.empty() && unChangedTags[0] == '\t') { + unChangedTags.remove(0); + } + + // tags + if (repeatInfo == NULL) { + outputTags(o); + o.append('\n'); + } else { + outputTags(o, repeatInfo->flagInfoIndex == -1?repeatInfo:&repeatPositions.positions[repeatInfo->flagInfoIndex]); + o.append('\n'); + } + } + + /** + * return true if two location is concordant. + * return false, if there are not concordant or too far (>maxPairDistance). + */ + static bool isConcordant(long long int location1, bool &forward1, long long int readLength1, long long int location2, bool &forward2, long long int readLength2); + + /** + * this is the basic function to calculate DNA pair score. + * if the distance between 2 alignments is more than penaltyFreeDistance_DNA, we reduce the score by the distance/100. + * if two alignment is concordant we add concordantScoreBounce to make sure to select the concordant pair as best pair. + */ + static int calculatePairScore_DNA (long long int &location0, int& AS0, bool& forward0, long long int readLength0, long long int &location1, int &AS1, bool &forward1, long long int readLength1, bool& concordant); + + /** + * this is the basic function to calculate RNA pair score. + * if the distance between 2 alignments is more than penaltyFreeDistance_RNA, we reduce the score by the distance/1000. + * if two alignment is concordant we add concordantScoreBounce to make sure to select the concordant pair as best pair. + */ + static int calculatePairScore_RNA (long long int &location0, int& XM0, bool& forward0, long long int readLength0, long long int &location1, int &XM1, bool &forward1, long long int readLength1, bool& concordant); +}; + +/** + * the data structure to store, process, and output all Alignment + */ +class Alignments { +public: + vector alignments; // pool to store current alignment result. + vector freeAlignments; // free pointer pool for new alignment result. after output a alignment, return the pointer back to this pool. + + TReadId previousReadID; + MappingPositions alignmentPositions; // the pool to save all alignment position + + BTString readName[2]; // the read name could be different for segment 1 and segment 2. + BTDnaString readSequence[2]; // save the read sequence for output. + BTString qualityScore[2]; // save the quality score for output. + + bool paired; + const int repeatPoolLimit = 20; // this is the maximum number of repeat alignment we allowed. + bool multipleAligned; // check whether we have multiple alignment, it is work unique mode. + + const int maxPairScore = 500000; // maximum pair score, if pairScore == maxPairScore, both math are perfect match and the pairDistance is small. + + BitPairReference* bitReference; // bit pair reference sequence + bool DNA; + int nRepeatAlignment; // count number of repeat alignment we received, for short sequence we could receive a lot of repeat alignment result. + + BTString passThroughLines[2]; + + void initialize() { + alignmentPositions.initialize(); + paired = false; + multipleAligned = false; + nRepeatAlignment = 0; + + for (int i = 0; i < 2; i++) { + readName[i].clear(); + readSequence[i].clear(); + qualityScore[i].clear(); + passThroughLines[i].clear(); + } + for (int i = 0; i < alignments.size(); i++) { + alignments[i]->initialize(); + freeAlignments.push_back(alignments[i]); + } + alignments.clear(); + } + + Alignments(BitPairReference* ref, bool inputDNA): bitReference(ref), DNA(inputDNA) { + initialize(); + } + + ~Alignments() { + while (!freeAlignments.empty()) { + delete freeAlignments.back(); + freeAlignments.pop_back(); + } + for (int i = 0; i < alignments.size(); i++) { + delete alignments[i]; + } + } + + /** + * get sequence for rd. if it already exist, ignore it. + */ + void getSequence(const Read& rd) { + int pairSegment = rd.mate == 0? rd.mate : rd.mate-1; + if (readName[pairSegment].empty()) { readName[pairSegment] = rd.name; } + if (readSequence[pairSegment].empty()) { readSequence[pairSegment] = rd.originalFw; } + if (qualityScore[pairSegment].empty()) { qualityScore[pairSegment] = rd.qual; } + } + + /** + * return true if we want to receive more new alignment. + */ + bool acceptNewAlignment() { + if (uniqueOutputOnly && multipleAligned || + alignmentPositions.nBestSingle >= repeatLimit || + nRepeatAlignment > repeatPoolLimit || + alignmentPositions.nBestPair >= repeatLimit) { + return false; + } + return true; + } + + /** + * return the alignment back to freeAlignment pool. + */ + void returnToFreeAlignments (Alignment*& currentAlignment) { + currentAlignment->initialize(); + freeAlignments.push_back(currentAlignment); + } + + /** + * get a Alignment pointer from freeAlignments, if freeAlignment is empty, make a new Alignment. + */ + void getFreeAlignmentPointer(Alignment*& newAlignment) { + if (!freeAlignments.empty()) { + newAlignment = freeAlignments.back(); + freeAlignments.pop_back(); + } else { + newAlignment = new Alignment(); + } + } + + /** + * receive alignment information from AlnSink3NSam::appendMate() and append it to alignment pool. + */ + void append(Alignment *newAlignment) { + + newAlignment->extractFlagInfo(); + paired = newAlignment->paired; + newAlignment->DNA = DNA; + if (passThroughLines[newAlignment->pairSegment].empty()) { + passThroughLines[newAlignment->pairSegment] = newAlignment->passThroughLine; + } + + // check if the alignment is already exist. if exist, ignore it. + if (!alignmentPositions.append(newAlignment)) { + alignments.push_back(newAlignment); + return; + } + + // construct MD tag and check if the alignment has too many mismatch, if do, ignore it. + if (newAlignment->repeat) { + if (!newAlignment->constructRepeatMD(bitReference, alignmentPositions)) { + alignmentPositions.badAligned(); + alignments.push_back(newAlignment); + return; + } + nRepeatAlignment++; // for each repeat alignment, record it. + } else { + // check mismatch, update tags + if (!newAlignment->constructMD(bitReference)) { + alignmentPositions.badAligned(); + alignments.push_back(newAlignment); + return; + } + } + + // update pair score or AS, for output using. + // if the new alignment has lower paring score or AS than bestPairScore or bestAS, ignore it. + if (paired) { + if (!alignmentPositions.updatePairScore()) { + alignments.push_back(newAlignment); + return; + } + if (alignmentPositions.bestPairScore == maxPairScore && alignmentPositions.nBestPair > 1) { + multipleAligned = true; + } + } else { + if (!alignmentPositions.updateAS()) { + alignments.push_back(newAlignment); + return; + } + if (alignmentPositions.bestAS == 0 && alignmentPositions.nBestSingle > 1) { + multipleAligned = true; + } + } + alignments.push_back(newAlignment); + } + + /** + * if there is no alignment, output unAlignment result. + * this function is important when hisat2 give mapped result, but it does not pass my filter (has too many mismatch). + */ + void outputUnAlignmentRead(BTString& o) { + if (paired) { + for (int i = 0; i < 2; i++) { + assert(!readName[i].empty()); + uint ReadNameLength = readName[i].length(); + if (readName[i].length() > 255) + { + ReadNameLength = 255; + } + for (int j = 0; j < ReadNameLength; j++) + { + if(isspace(readName[i][j])) { + break; + } + o.append(readName[i][j]); + } + o.append("\t"); + + string flag = (i == 0) ? "77" : "141"; + o.append(flag.c_str()); + + o.append("\t*\t0\t0\t*\t*\t0\t0\t"); + o.append(readSequence[i].toZBuf()); + o.append("\t"); + o.append(qualityScore[i].toZBuf()); + o.append("\tYT:Z:UP"); + o.append(passThroughLines[i].toZBuf()); + o.append('\n'); + } + } else { + assert(!readName[0].empty()); + string ReadName = ""; + uint ReadNameLength = readName[0].length(); + if (readName[0].length() > 255) + { + ReadNameLength = 255; + } + for (int j = 0; j < ReadNameLength; j++) + { + if(isspace(readName[0][j])) { + break; + } + o.append(readName[0][j]); + } + o.append("\t4\t*\t0\t0\t*\t*\t0\t0\t"); + o.append(readSequence[0].toZBuf()); + o.append("\t"); + o.append(qualityScore[0].toZBuf()); + o.append("\tYT:Z:UU"); + o.append(passThroughLines[0].toZBuf()); + o.append('\n'); + } + } + + /** + * report alignment statistics for single-end alignment + */ + void reportStats_single(ReportingMetrics& met); + + + /** + * report alignment statistics for paired-end alignment + */ + void reportStats_paired(ReportingMetrics& met); + + /** + * output single-end alignment reuslts + */ + void output_single(BTString& o, + ReportingMetrics& met) { + + reportStats_single(met); + + // output + if (uniqueOutputOnly && (alignmentPositions.nBestSingle != 1 || multipleAligned)) { + // do not output anything + } else if (alignments.empty() || alignmentPositions.nBestSingle == 0) { + // make a unalignment result and output it. + outputUnAlignmentRead(o); + } else { + // output + alignmentPositions.outputSingle(o); + } + } + + /** + * output paired-end alignment reuslts + */ + void output_paired(BTString& o, + ReportingMetrics& met) { + + reportStats_paired(met); + + if ((uniqueOutputOnly && (alignmentPositions.nBestPair != 1 || multipleAligned))) { + // do not report anything + } else if (alignments.empty() || + alignmentPositions.nBestPair == 0 || + alignmentPositions.bestPairScore == numeric_limits::min()) { + // make a unalignment result and output it. + outputUnAlignmentRead(o); + } else { + // output + alignmentPositions.outputPair(o); + } + } + /** + * output function will be redirected to output_single or output_paired + */ + void output(ReportingMetrics& met, + BTString& o) { + + if (paired) { + output_paired(o, met); + } else { + output_single(o,met); + } + initialize(); + } +}; + +#endif //HISAT2_ALIGNMENT_3N_H diff --git a/alignment_3n_table.h b/alignment_3n_table.h new file mode 100644 index 0000000..83715a7 --- /dev/null +++ b/alignment_3n_table.h @@ -0,0 +1,287 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#ifndef ALIGNMENT_3N_TABLE_H +#define ALIGNMENT_3N_TABLE_H + +#include +#include "utility_3n_table.h" + +extern bool uniqueOnly; +extern bool multipleOnly; +extern char convertFrom; +extern char convertTo; +extern char convertFromComplement; +extern char convertToComplement; + +using namespace std; + +/** + * the class to store information from one SAM line + */ +class Alignment { +public: + string chromosome; + long long int location; + long long int mateLocation; + int flag; + bool mapped; + char strand; + string sequence; + string quality; + bool unique; + string mapQ; + int NH; + vector bases; + CIGAR cigarString; + MD_tag MD; + unsigned long long readNameID; + int sequenceCoveredLength; // the sum of number is cigarString; + bool overlap; // if the segment could overlap with the mate segment. + bool paired; + + void initialize() { + chromosome.clear(); + location = -1; + mateLocation = -1; + flag = -1; + mapped = false; + MD.initialize(); + cigarString.initialize(); + sequence.clear(); + quality.clear(); + unique = false; + mapQ.clear(); + NH = -1; + bases.clear(); + readNameID = 0; + sequenceCoveredLength = 0; + overlap = false; + paired = false; + } + + /** + * for start position in input Line, check if it contain the target information. + */ + bool startWith(string* inputLine, int startPosition, string tag){ + for (int i = 0; i < tag.size(); i++){ + if (inputLine->at(startPosition+i) != tag[i]){ + return false; + } + } + return true; + } + + /** + * generate a hash value for readName + */ + void getNameHash(string& readName) { + readNameID = 0; + int a = 63689; + for (size_t i = 0; i < readName.size(); i++) { + readNameID = (readNameID * a) + (int)readName[i]; + } + } + + /** + * extract the information from SAM line to Alignment. + */ + void parseInfo(string* line) { + int startPosition = 0; + int endPosition = 0; + int count = 0; + + while ((endPosition = line->find("\t", startPosition)) != string::npos) { + if (count == 0) { + string readName = line->substr(startPosition, endPosition - startPosition); + getNameHash(readName); + } else if (count == 1) { + flag = stoi(line->substr(startPosition, endPosition - startPosition)); + mapped = (flag & 4) == 0; + paired = (flag & 1) != 0; + } else if (count == 2) { + chromosome = line->substr(startPosition, endPosition - startPosition); + } else if (count == 3) { + location = stoll(line->substr(startPosition, endPosition - startPosition)); + } else if (count == 4) { + mapQ = line->substr(startPosition, endPosition - startPosition); + if (mapQ == "1") { + unique = false; + } else { + unique = true; + } + } else if (count == 5) { + cigarString.loadString(line->substr(startPosition, endPosition - startPosition)); + } else if (count == 7) { + mateLocation = stoll(line->substr(startPosition, endPosition - startPosition)); + } else if (count == 9) { + sequence = line->substr(startPosition, endPosition - startPosition); + } else if (count == 10) { + quality = line->substr(startPosition, endPosition - startPosition); + } else if (count > 10) { + if (startWith(line, startPosition, "MD")) { + MD.loadString(line->substr(startPosition + 5, endPosition - startPosition - 5)); + } else if (startWith(line, startPosition, "NM")) { + NH = stoi(line->substr(startPosition + 5, endPosition - startPosition - 5)); + } else if (startWith(line, startPosition, "YZ")) { + strand = line->at(endPosition-1); + } + } + startPosition = endPosition + 1; + count++; + } + if (startWith(line, startPosition, "MD")) { + MD.loadString(line->substr(startPosition + 5, endPosition - startPosition - 5)); + } else if (startWith(line, startPosition, "NM")) { + NH = stoi(line->substr(startPosition + 5, endPosition - startPosition - 5)); + } else if (startWith(line, startPosition, "YZ")) { + strand = line->at(endPosition-1); + } + } + + /** + * change the overlap = true, if the read is not uniquely mapped or the read segment is overlap to it's mate. + */ + void checkOverlap() { + if (!unique) { + overlap = true; + } else { + if (paired && (location + sequenceCoveredLength >= mateLocation)) { + overlap = true; + } else { + overlap = false; + } + } + } + + + /** + * parse the sam line to alignment information + */ + void parse(string* line) { + initialize(); + parseInfo(line); + if ((uniqueOnly && !unique) || (multipleOnly && unique)) { + return; + } + appendBase(); + } + + /** + * scan all base in read sequence label them if they are qualified. + */ + void appendBase() { + if (!mapped || sequenceCoveredLength > 500000) { // if the read's intron longer than 500,000 ignore this read + return; + } + + bases.reserve(sequence.size()); + for (int i = 0; i < sequence.size(); i++) { + bases.emplace_back(i); + } + int pos = adjustPos(); + + string match; + while (MD.getNextSegment(match)) { + if (isdigit(match.front())) { // the first char of match is digit this is match + int len = stoi(match); + for (int i = 0; i < len; i++) { + while (bases[pos].remove) { + pos++; + } + if ((strand == '+' && sequence[pos] == convertFrom) || + (strand == '-' && sequence[pos] == convertFromComplement)) { + bases[pos].setQual(quality[pos], false); + } else { + bases[pos].remove = true; + } + pos ++; + } + } else if (isalpha(match.front())) { // this is mismatch or conversion + char refBase = match.front(); + // for + strand, it should have C->T change + // for - strand, it should have G->A change + while (bases[pos].remove) { + pos++; + } + + if ((strand == '+' && refBase == convertFrom && sequence[pos] == convertTo) || + (strand == '-' && refBase == convertFromComplement && sequence[pos] == convertToComplement)){ + bases[pos].setQual(quality[pos], true); + } else { + bases[pos].remove = true; + } + pos ++; + } else { // deletion. do nothing. + + } + } + } + + /** + * adjust the reference position in bases + */ + int adjustPos() { + + int readPos = 0; + int returnPos = 0; + int seqLength = sequence.size(); + + char cigarSymbol; + int cigarLen; + sequenceCoveredLength = 0; + + while (cigarString.getNextSegment(cigarLen, cigarSymbol)) { + sequenceCoveredLength += cigarLen; + if (cigarSymbol == 'S') { + if (readPos == 0) { // soft clip is at the begin of the read + returnPos = cigarLen; + for (int i = cigarLen; i < seqLength; i++) { + bases[i].refPos -= cigarLen; + } + } else { // soft clip is at the end of the read + // do nothing + } + readPos += cigarLen; + } else if (cigarSymbol == 'N') { + for (int i = readPos; i < seqLength; i++) { + bases[i].refPos += cigarLen; + } + } else if (cigarSymbol == 'M') { + for (int i = readPos; i < readPos+cigarLen; i++) { + bases[i].remove = false; + } + readPos += cigarLen; + } else if (cigarSymbol == 'I') { + for (int i = readPos + cigarLen; i < seqLength; i++) { + bases[i].refPos -= cigarLen; + } + readPos += cigarLen; + } else if (cigarSymbol == 'D') { + for (int i = readPos; i < seqLength; i++) { + bases[i].refPos += cigarLen; + } + } + } + return returnPos; + } + +}; + +#endif //ALIGNMENT_3N_TABLE_H diff --git a/aln_sink.cpp b/aln_sink.cpp new file mode 100644 index 0000000..b0d4244 --- /dev/null +++ b/aln_sink.cpp @@ -0,0 +1,785 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include "aln_sink.h" +#include "aligner_seed.h" +#include "util.h" + +using namespace std; + + +/** + * Initialize state machine with a new read. The state we start in depends + * on whether it's paired-end or unpaired. + */ +void ReportingState::nextRead(bool paired) { + paired_ = paired; + if(paired) { + state_ = CONCORDANT_PAIRS; + doneConcord_ = false; + doneDiscord_ = p_.discord ? false : true; + doneUnpair1_ = p_.mixed ? false : true; + doneUnpair2_ = p_.mixed ? false : true; + exitConcord_ = ReportingState::EXIT_DID_NOT_EXIT; + exitDiscord_ = p_.discord ? + ReportingState::EXIT_DID_NOT_EXIT : + ReportingState::EXIT_DID_NOT_ENTER; + exitUnpair1_ = p_.mixed ? + ReportingState::EXIT_DID_NOT_EXIT : + ReportingState::EXIT_DID_NOT_ENTER; + exitUnpair2_ = p_.mixed ? + ReportingState::EXIT_DID_NOT_EXIT : + ReportingState::EXIT_DID_NOT_ENTER; + } else { + // Unpaired + state_ = UNPAIRED; + doneConcord_ = true; + doneDiscord_ = true; + doneUnpair1_ = false; + doneUnpair2_ = true; + exitConcord_ = ReportingState::EXIT_DID_NOT_ENTER; // not relevant + exitDiscord_ = ReportingState::EXIT_DID_NOT_ENTER; // not relevant + exitUnpair1_ = ReportingState::EXIT_DID_NOT_EXIT; + exitUnpair2_ = ReportingState::EXIT_DID_NOT_ENTER; // not relevant + } + doneUnpair_ = doneUnpair1_ && doneUnpair2_; + done_ = false; + nconcord_ = ndiscord_ = nunpair1_ = nunpair2_ = 0; + nunpairRepeat1_ = nunpairRepeat2_ = 0; + concordBest_ = getMinScore(); +} + +/** + * Caller uses this member function to indicate that one additional + * concordant alignment has been found. + */ +bool ReportingState::foundConcordant(TAlScore score) { + assert(paired_); + assert_geq(state_, ReportingState::CONCORDANT_PAIRS); + assert(!doneConcord_); + + if(score > concordBest_) { + concordBest_ = score; + nconcord_ = 0; + } + nconcord_++; + + // DK CONCORDANT - debugging purpuses + // areDone(nconcord_, doneConcord_, exitConcord_); + + // No need to search for discordant alignments if there are one or more + // concordant alignments. + doneDiscord_ = true; + exitDiscord_ = ReportingState::EXIT_SHORT_CIRCUIT_TRUMPED; + if(doneConcord_) { + // If we're finished looking for concordant alignments, do we have to + // continue on to search for unpaired alignments? Only if our exit + // from the concordant stage is EXIT_SHORT_CIRCUIT_M. If it's + // EXIT_SHORT_CIRCUIT_k or EXIT_WITH_ALIGNMENTS, we can skip unpaired. + assert_neq(ReportingState::EXIT_NO_ALIGNMENTS, exitConcord_); + if(exitConcord_ != ReportingState::EXIT_SHORT_CIRCUIT_M) { + if(!doneUnpair1_) { + doneUnpair1_ = true; + exitUnpair1_ = ReportingState::EXIT_SHORT_CIRCUIT_TRUMPED; + } + if(!doneUnpair2_) { + doneUnpair2_ = true; + exitUnpair2_ = ReportingState::EXIT_SHORT_CIRCUIT_TRUMPED; + } + } + } + updateDone(); + return done(); +} + +/** + * Caller uses this member function to indicate that one additional unpaired + * mate alignment has been found for the specified mate. + */ +bool ReportingState::foundUnpaired(bool mate1, bool repeat) { + assert_gt(state_, ReportingState::NO_READ); + // Note: it's not right to assert !doneUnpair1_/!doneUnpair2_ here. + // Even if we're done with finding + if(mate1) { + nunpair1_++; + if(repeat) { + nunpairRepeat1_++; + } + // Did we just finish with this mate? + if(!doneUnpair1_) { + areDone(nunpair1_, doneUnpair1_, exitUnpair1_); + if(doneUnpair1_) { + doneUnpair_ = doneUnpair1_ && doneUnpair2_; + updateDone(); + } + } + if(nunpair1_ > 1) { + doneDiscord_ = true; + exitDiscord_ = ReportingState::EXIT_NO_ALIGNMENTS; + } + } else { + nunpair2_++; + if(repeat) { + nunpairRepeat2_++; + } + // Did we just finish with this mate? + if(!doneUnpair2_) { + areDone(nunpair2_, doneUnpair2_, exitUnpair2_); + if(doneUnpair2_) { + doneUnpair_ = doneUnpair1_ && doneUnpair2_; + updateDone(); + } + } + if(nunpair2_ > 1) { + doneDiscord_ = true; + exitDiscord_ = ReportingState::EXIT_NO_ALIGNMENTS; + } + } + return done(); +} + +/** + * Called to indicate that the aligner has finished searching for + * alignments. This gives us a chance to finalize our state. + * + * TODO: Keep track of short-circuiting information. + */ +void ReportingState::finish() { + if(!doneConcord_) { + doneConcord_ = true; + exitConcord_ = + ((nconcord_ > 0) ? + ReportingState::EXIT_WITH_ALIGNMENTS : + ReportingState::EXIT_NO_ALIGNMENTS); + } + assert_gt(exitConcord_, EXIT_DID_NOT_EXIT); + if(!doneUnpair1_) { + doneUnpair1_ = true; + exitUnpair1_ = + ((nunpair1_ > 0) ? + ReportingState::EXIT_WITH_ALIGNMENTS : + ReportingState::EXIT_NO_ALIGNMENTS); + } + assert_gt(exitUnpair1_, EXIT_DID_NOT_EXIT); + if(!doneUnpair2_) { + doneUnpair2_ = true; + exitUnpair2_ = + ((nunpair2_ > 0) ? + ReportingState::EXIT_WITH_ALIGNMENTS : + ReportingState::EXIT_NO_ALIGNMENTS); + } + assert_gt(exitUnpair2_, EXIT_DID_NOT_EXIT); + if(!doneDiscord_) { + // Check if the unpaired alignments should be converted to a single + // discordant paired-end alignment. + assert_eq(0, ndiscord_); + if(nconcord_ == 0 && nunpair1_ == 1 && nunpair2_ == 1) { + convertUnpairedToDiscordant(); + } + doneDiscord_ = true; + exitDiscord_ = + ((ndiscord_ > 0) ? + ReportingState::EXIT_WITH_ALIGNMENTS : + ReportingState::EXIT_NO_ALIGNMENTS); + } + assert(!paired_ || exitDiscord_ > ReportingState::EXIT_DID_NOT_EXIT); + doneUnpair_ = done_ = true; + assert(done()); +} + +/** + * Populate given counters with the number of various kinds of alignments + * to report for this read. Concordant alignments are preferable to (and + * mutually exclusive with) discordant alignments, and paired-end + * alignments are preferable to unpaired alignments. + * + * The caller also needs some additional information for the case where a + * pair or unpaired read aligns repetitively. If the read is paired-end + * and the paired-end has repetitive concordant alignments, that should be + * reported, and 'pairMax' is set to true to indicate this. If the read is + * paired-end, does not have any conordant alignments, but does have + * repetitive alignments for one or both mates, then that should be + * reported, and 'unpair1Max' and 'unpair2Max' are set accordingly. + * + * Note that it's possible in the case of a paired-end read for the read to + * have repetitive concordant alignments, but for one mate to have a unique + * unpaired alignment. + */ +void ReportingState::getReport( + uint64_t& nconcordAln, // # concordant alignments to report + uint64_t& ndiscordAln, // # discordant alignments to report + uint64_t& nunpair1Aln, // # unpaired alignments for mate #1 to report + uint64_t& nunpair2Aln, // # unpaired alignments for mate #2 to report + uint64_t& nunpairRepeat1Aln, // # unpaired alignments for mate #1 to report + uint64_t& nunpairRepeat2Aln, // # unpaired alignments for mate #2 to report + bool& pairMax, // repetitive concordant alignments + bool& unpair1Max, // repetitive alignments for mate #1 + bool& unpair2Max) // repetitive alignments for mate #2 + const +{ + nconcordAln = ndiscordAln = nunpair1Aln = nunpair2Aln = 0; + nunpairRepeat1Aln = nunpairRepeat2Aln = 0; + pairMax = unpair1Max = unpair2Max = false; + assert_gt(p_.khits, 0); + assert_gt(p_.mhits, 0); + if(paired_) { + // Do we have 1 or more concordant alignments to report? + if(exitConcord_ == ReportingState::EXIT_SHORT_CIRCUIT_k) { + // k at random + assert_geq(nconcord_, (uint64_t)p_.khits); + nconcordAln = p_.khits; + return; + } else if(exitConcord_ == ReportingState::EXIT_SHORT_CIRCUIT_M) { + assert(p_.msample); + assert_gt(nconcord_, 0); + pairMax = true; // repetitive concordant alignments + if(p_.mixed) { + unpair1Max = nunpair1_ > (uint64_t)p_.mhits; + unpair2Max = nunpair2_ > (uint64_t)p_.mhits; + } + // Not sure if this is OK + nconcordAln = 1; // 1 at random + return; + } else if(exitConcord_ == ReportingState::EXIT_WITH_ALIGNMENTS) { + assert_gt(nconcord_, 0); + // <= k at random + nconcordAln = min(p_.khits, nconcord_); + } + assert(!p_.mhitsSet() || nconcord_ <= (uint64_t)p_.mhits+1); + + // Do we have a discordant alignment to report? + if(exitDiscord_ == ReportingState::EXIT_WITH_ALIGNMENTS) { + // Report discordant + assert(p_.discord); + ndiscordAln = 1; + return; + } + } + + assert_neq(ReportingState::EXIT_SHORT_CIRCUIT_TRUMPED, exitUnpair1_); + assert_neq(ReportingState::EXIT_SHORT_CIRCUIT_TRUMPED, exitUnpair2_); + + if((paired_ && !p_.mixed) || nunpair1_ + nunpair2_ == 0) { + // Unpaired alignments either not reportable or non-existant + return; + } + + // Do we have 1 or more alignments for mate #1 to report? + if(exitUnpair1_ == ReportingState::EXIT_SHORT_CIRCUIT_k) { + // k at random + assert_geq(nunpair1_, (uint64_t)p_.khits); + nunpair1Aln = p_.khits; + } else if(exitUnpair1_ == ReportingState::EXIT_SHORT_CIRCUIT_M) { + assert(p_.msample); + assert_gt(nunpair1_, 0); + unpair1Max = true; // repetitive alignments for mate #1 + nunpair1Aln = 1; // 1 at random + } else if(exitUnpair1_ == ReportingState::EXIT_WITH_ALIGNMENTS) { + assert_gt(nunpair1_, 0); + // <= k at random + nunpair1Aln = min(nunpair1_, (uint64_t)p_.khits); + } + assert(!p_.mhitsSet() || paired_ || nunpair1_ <= (uint64_t)p_.mhits+1); + if(p_.repeat) nunpairRepeat1Aln = nunpairRepeat1_; + + // Do we have 2 or more alignments for mate #2 to report? + if(exitUnpair2_ == ReportingState::EXIT_SHORT_CIRCUIT_k) { + // k at random + nunpair2Aln = p_.khits; + } else if(exitUnpair2_ == ReportingState::EXIT_SHORT_CIRCUIT_M) { + assert(p_.msample); + assert_gt(nunpair2_, 0); + unpair2Max = true; // repetitive alignments for mate #1 + nunpair2Aln = 1; // 1 at random + } else if(exitUnpair2_ == ReportingState::EXIT_WITH_ALIGNMENTS) { + assert_gt(nunpair2_, 0); + // <= k at random + nunpair2Aln = min(nunpair2_, (uint64_t)p_.khits); + } + assert(!p_.mhitsSet() || paired_ || nunpair2_ <= (uint64_t)p_.mhits+1); + if(p_.repeat) nunpairRepeat2Aln = nunpairRepeat2_; +} + +/** + * Given the number of alignments in a category, check whether we + * short-circuited out of the category. Set the done and exit arguments to + * indicate whether and how we short-circuited. + */ +inline void ReportingState::areDone( + uint64_t cnt, // # alignments in category + bool& done, // out: whether we short-circuited out of category + int& exit) const // out: if done, how we short-circuited (-k? -m? etc) +{ + assert(!done); + // Have we exceeded the -k limit? + assert_gt(p_.khits, 0); + assert_gt(p_.mhits, 0); + if(cnt >= (uint64_t)p_.khits && !p_.mhitsSet()) { + done = true; + exit = ReportingState::EXIT_SHORT_CIRCUIT_k; + } + // Have we exceeded the -m or -M limit? + else if(p_.mhitsSet() && cnt > (uint64_t)p_.mhits) { + done = true; + assert(p_.msample); + exit = ReportingState::EXIT_SHORT_CIRCUIT_M; + } +} + +#ifdef ALN_SINK_MAIN + +#include + +bool testDones( + const ReportingState& st, + bool done1, + bool done2, + bool done3, + bool done4, + bool done5, + bool done6) +{ + assert(st.doneConcordant() == done1); + assert(st.doneDiscordant() == done2); + assert(st.doneUnpaired(true) == done3); + assert(st.doneUnpaired(false) == done4); + assert(st.doneUnpaired() == done5); + assert(st.done() == done6); + assert(st.repOk()); + return true; +} + +int main(void) { + cerr << "Case 1 (simple unpaired 1) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 2, // khits + 0, // mhits + 0, // pengap + false, // msample + false, // discord + false); // mixed + ReportingState st(rp); + st.nextRead(false); // unpaired read + assert(testDones(st, true, true, false, true, false, false)); + st.foundUnpaired(true); + assert(testDones(st, true, true, false, true, false, false)); + st.foundUnpaired(true); + assert(testDones(st, true, true, true, true, true, true)); + st.finish(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(0, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(2, st.numUnpaired1()); + assert_eq(0, st.numUnpaired2()); + assert(st.repOk()); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(0, nconcord); + assert_eq(0, ndiscord); + assert_eq(2, nunpair1); + assert_eq(0, nunpair2); + assert(!pairMax); + assert(!unpair1Max); + assert(!unpair2Max); + } + cerr << "PASSED" << endl; + + cerr << "Case 2 (simple unpaired 1) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 2, // khits + 3, // mhits + 0, // pengap + false, // msample + false, // discord + false); // mixed + ReportingState st(rp); + st.nextRead(false); // unpaired read + assert(testDones(st, true, true, false, true, false, false)); + st.foundUnpaired(true); + assert(testDones(st, true, true, false, true, false, false)); + st.foundUnpaired(true); + assert(testDones(st, true, true, false, true, false, false)); + st.foundUnpaired(true); + assert(testDones(st, true, true, false, true, false, false)); + st.foundUnpaired(true); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(0, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(4, st.numUnpaired1()); + assert_eq(0, st.numUnpaired2()); + st.finish(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(0, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(4, st.numUnpaired1()); + assert_eq(0, st.numUnpaired2()); + assert(st.repOk()); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(0, nconcord); + assert_eq(0, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(!pairMax); + assert(unpair1Max); + assert(!unpair2Max); + } + cerr << "PASSED" << endl; + + cerr << "Case 3 (simple paired 1) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 2, // khits + 3, // mhits + 0, // pengap + false, // msample + false, // discord + false); // mixed + ReportingState st(rp); + st.nextRead(true); // unpaired read + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, true, true, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(4, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(4, st.numUnpaired1()); + assert_eq(4, st.numUnpaired2()); + st.finish(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(4, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(4, st.numUnpaired1()); + assert_eq(4, st.numUnpaired2()); + assert(st.repOk()); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(0, nconcord); + assert_eq(0, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(pairMax); + assert(!unpair1Max); // because !mixed + assert(!unpair2Max); // because !mixed + } + cerr << "PASSED" << endl; + + cerr << "Case 4 (simple paired 2) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 2, // khits + 3, // mhits + 0, // pengap + false, // msample + true, // discord + true); // mixed + ReportingState st(rp); + st.nextRead(true); // unpaired read + assert(testDones(st, false, false, false, false, false, false)); + st.foundUnpaired(true); + assert(testDones(st, false, false, false, false, false, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, false, false, false, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, false, false, false, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, true, false, false, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, false, false, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, false, false, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, false, false, false)); + st.foundUnpaired(false); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, false, true, true, true, true, false)); + st.foundConcordant(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(4, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(4, st.numUnpaired1()); + assert_eq(4, st.numUnpaired2()); + st.finish(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(4, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(4, st.numUnpaired1()); + assert_eq(4, st.numUnpaired2()); + assert(st.repOk()); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(0, nconcord); + assert_eq(0, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(pairMax); + assert(unpair1Max); + assert(unpair2Max); + } + cerr << "PASSED" << endl; + + cerr << "Case 5 (potential discordant after concordant) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 2, // khits + 3, // mhits + 0, // pengap + false, // msample + true, // discord + true); // mixed + ReportingState st(rp); + st.nextRead(true); + assert(testDones(st, false, false, false, false, false, false)); + st.foundUnpaired(true); + st.foundUnpaired(false); + st.foundConcordant(); + assert(testDones(st, false, true, false, false, false, false)); + st.finish(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(1, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(1, st.numUnpaired1()); + assert_eq(1, st.numUnpaired2()); + assert(st.repOk()); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(1, nconcord); + assert_eq(0, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(!pairMax); + assert(!unpair1Max); + assert(!unpair2Max); + } + cerr << "PASSED" << endl; + + cerr << "Case 6 (true discordant) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 2, // khits + 3, // mhits + 0, // pengap + false, // msample + true, // discord + true); // mixed + ReportingState st(rp); + st.nextRead(true); + assert(testDones(st, false, false, false, false, false, false)); + st.foundUnpaired(true); + st.foundUnpaired(false); + assert(testDones(st, false, false, false, false, false, false)); + st.finish(); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(0, st.numConcordant()); + assert_eq(1, st.numDiscordant()); + assert_eq(0, st.numUnpaired1()); + assert_eq(0, st.numUnpaired2()); + assert(st.repOk()); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(0, nconcord); + assert_eq(1, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(!pairMax); + assert(!unpair1Max); + assert(!unpair2Max); + } + cerr << "PASSED" << endl; + + cerr << "Case 7 (unaligned pair & uniquely aligned mate, mixed-mode) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 1, // khits + 1, // mhits + 0, // pengap + false, // msample + true, // discord + true); // mixed + ReportingState st(rp); + st.nextRead(true); // unpaired read + // assert(st.doneConcordant() == done1); + // assert(st.doneDiscordant() == done2); + // assert(st.doneUnpaired(true) == done3); + // assert(st.doneUnpaired(false) == done4); + // assert(st.doneUnpaired() == done5); + // assert(st.done() == done6); + st.foundUnpaired(true); + assert(testDones(st, false, false, false, false, false, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, true, false, false, false)); + assert_eq(0, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(2, st.numUnpaired1()); + assert_eq(0, st.numUnpaired2()); + st.finish(); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(0, nconcord); + assert_eq(0, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(!pairMax); + assert(unpair1Max); + assert(!unpair2Max); + } + cerr << "PASSED" << endl; + + cerr << "Case 8 (unaligned pair & uniquely aligned mate, NOT mixed-mode) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 1, // khits + 1, // mhits + 0, // pengap + false, // msample + true, // discord + false); // mixed + ReportingState st(rp); + st.nextRead(true); // unpaired read + // assert(st.doneConcordant() == done1); + // assert(st.doneDiscordant() == done2); + // assert(st.doneUnpaired(true) == done3); + // assert(st.doneUnpaired(false) == done4); + // assert(st.doneUnpaired() == done5); + // assert(st.done() == done6); + st.foundUnpaired(true); + assert(testDones(st, false, false, true, true, true, false)); + st.foundUnpaired(true); + assert(testDones(st, false, true, true, true, true, false)); + assert_eq(0, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(2, st.numUnpaired1()); + assert_eq(0, st.numUnpaired2()); + st.finish(); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(0, nconcord); + assert_eq(0, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(!pairMax); + assert(!unpair1Max); // not really relevant + assert(!unpair2Max); // not really relevant + } + cerr << "PASSED" << endl; + + cerr << "Case 9 (repetitive pair, only one mate repetitive) ... "; + { + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + ReportingParams rp( + 1, // khits + 1, // mhits + 0, // pengap + true, // msample + true, // discord + true); // mixed + ReportingState st(rp); + st.nextRead(true); // unpaired read + // assert(st.doneConcordant() == done1); + // assert(st.doneDiscordant() == done2); + // assert(st.doneUnpaired(true) == done3); + // assert(st.doneUnpaired(false) == done4); + // assert(st.doneUnpaired() == done5); + // assert(st.done() == done6); + st.foundConcordant(); + assert(st.repOk()); + st.foundUnpaired(true); + assert(st.repOk()); + st.foundUnpaired(false); + assert(st.repOk()); + assert(testDones(st, false, true, false, false, false, false)); + assert(st.repOk()); + st.foundConcordant(); + assert(st.repOk()); + st.foundUnpaired(true); + assert(st.repOk()); + assert(testDones(st, true, true, true, false, false, false)); + assert_eq(2, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(2, st.numUnpaired1()); + assert_eq(1, st.numUnpaired2()); + st.foundUnpaired(false); + assert(st.repOk()); + assert(testDones(st, true, true, true, true, true, true)); + assert_eq(2, st.numConcordant()); + assert_eq(0, st.numDiscordant()); + assert_eq(2, st.numUnpaired1()); + assert_eq(2, st.numUnpaired2()); + st.finish(); + st.getReport(nconcord, ndiscord, nunpair1, nunpair2, + pairMax, unpair1Max, unpair2Max); + assert_eq(1, nconcord); + assert_eq(0, ndiscord); + assert_eq(0, nunpair1); + assert_eq(0, nunpair2); + assert(pairMax); + assert(unpair1Max); // not really relevant + assert(unpair2Max); // not really relevant + } + cerr << "PASSED" << endl; +} + +#endif /*def ALN_SINK_MAIN*/ diff --git a/aln_sink.h b/aln_sink.h new file mode 100644 index 0000000..cf1ac50 --- /dev/null +++ b/aln_sink.h @@ -0,0 +1,4384 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * This file is edited by Yun (Leo) Zhang for HISAT-3N. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALN_SINK_H_ +#define ALN_SINK_H_ + +#include +#include "read.h" +#include "unique.h" +#include "sam.h" +#include "ds.h" +#include "simple_func.h" +#include "outq.h" +#include +#include "alt.h" +#include "splice_site.h" + +static const TAlScore getMinScore() { + return std::numeric_limits::min() / 2; +} + +// Forward decl +template +class SeedResults; + +enum { + OUTPUT_SAM = 1 +}; + +/** + * Metrics summarizing the work done by the reporter and summarizing + * the number of reads that align, that fail to align, and that align + * non-uniquely. + */ +struct ReportingMetrics { + + ReportingMetrics():mutex_m() { + reset(); + } + + void reset() { + init(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + + void init( + uint64_t nread_, + uint64_t npaired_, + uint64_t nunpaired_, + uint64_t nconcord_uni_, + uint64_t nconcord_uni1_, + uint64_t nconcord_uni2_, + uint64_t nconcord_rep_, + uint64_t nconcord_0_, + uint64_t ndiscord_, + uint64_t nunp_0_uni_, + uint64_t nunp_0_uni1_, + uint64_t nunp_0_uni2_, + uint64_t nunp_0_rep_, + uint64_t nunp_0_0_, + uint64_t nunp_rep_uni_, + uint64_t nunp_rep_uni1_, + uint64_t nunp_rep_uni2_, + uint64_t nunp_rep_rep_, + uint64_t nunp_rep_0_, + uint64_t nunp_uni_, + uint64_t nunp_uni1_, + uint64_t nunp_uni2_, + uint64_t nunp_rep_, + uint64_t nunp_0_, + uint64_t sum_best1_, + uint64_t sum_best2_, + uint64_t sum_best_) + { + nread = nread_; + + npaired = npaired_; + nunpaired = nunpaired_; + + nconcord_uni = nconcord_uni_; + nconcord_uni1 = nconcord_uni1_; + nconcord_uni2 = nconcord_uni2_; + nconcord_rep = nconcord_rep_; + nconcord_0 = nconcord_0_; + + ndiscord = ndiscord_; + + nunp_0_uni = nunp_0_uni_; + nunp_0_uni1 = nunp_0_uni1_; + nunp_0_uni2 = nunp_0_uni2_; + nunp_0_rep = nunp_0_rep_; + nunp_0_0 = nunp_0_0_; + + nunp_rep_uni = nunp_rep_uni_; + nunp_rep_uni1 = nunp_rep_uni1_; + nunp_rep_uni2 = nunp_rep_uni2_; + nunp_rep_rep = nunp_rep_rep_; + nunp_rep_0 = nunp_rep_0_; + + nunp_uni = nunp_uni_; + nunp_uni1 = nunp_uni1_; + nunp_uni2 = nunp_uni2_; + nunp_rep = nunp_rep_; + nunp_0 = nunp_0_; + + sum_best1 = sum_best1_; + sum_best2 = sum_best2_; + sum_best = sum_best_; + } + + /** + * Merge (add) the counters in the given ReportingMetrics object + * into this object. This is the only safe way to update a + * ReportingMetrics shared by multiple threads. + */ + void merge(const ReportingMetrics& met, bool getLock = false) { + ThreadSafe ts(&mutex_m, getLock); + nread += met.nread; + + npaired += met.npaired; + nunpaired += met.nunpaired; + + nconcord_uni += met.nconcord_uni; + nconcord_uni1 += met.nconcord_uni1; + nconcord_uni2 += met.nconcord_uni2; + nconcord_rep += met.nconcord_rep; + nconcord_0 += met.nconcord_0; + + ndiscord += met.ndiscord; + + nunp_0_uni += met.nunp_0_uni; + nunp_0_uni1 += met.nunp_0_uni1; + nunp_0_uni2 += met.nunp_0_uni2; + nunp_0_rep += met.nunp_0_rep; + nunp_0_0 += met.nunp_0_0; + + nunp_rep_uni += met.nunp_rep_uni; + nunp_rep_uni1 += met.nunp_rep_uni1; + nunp_rep_uni2 += met.nunp_rep_uni2; + nunp_rep_rep += met.nunp_rep_rep; + nunp_rep_0 += met.nunp_rep_0; + + nunp_uni += met.nunp_uni; + nunp_uni1 += met.nunp_uni1; + nunp_uni2 += met.nunp_uni2; + nunp_rep += met.nunp_rep; + nunp_0 += met.nunp_0; + + sum_best1 += met.sum_best1; + sum_best2 += met.sum_best2; + sum_best += met.sum_best; + } + + uint64_t nread; // # reads + uint64_t npaired; // # pairs + uint64_t nunpaired; // # unpaired reads + + // Paired + + // Concordant + uint64_t nconcord_uni; // # pairs with unique concordant alns + uint64_t nconcord_uni1; // # pairs with exactly 1 concordant alns + uint64_t nconcord_uni2; // # pairs with >1 concordant aln, still unique + uint64_t nconcord_rep; // # pairs with repetitive concordant alns + uint64_t nconcord_0; // # pairs with 0 concordant alns + // Discordant + uint64_t ndiscord; // # pairs with 1 discordant aln + + // Unpaired from failed pairs + uint64_t nunp_0_uni; // # unique from nconcord_0_ - ndiscord_ + uint64_t nunp_0_uni1; // # pairs with exactly 1 concordant alns + uint64_t nunp_0_uni2; // # pairs with >1 concordant aln, still unique + uint64_t nunp_0_rep; // # repetitive from + uint64_t nunp_0_0; // # with 0 alignments + + // Unpaired from repetitive pairs + uint64_t nunp_rep_uni; // # pairs with unique concordant alns + uint64_t nunp_rep_uni1; // # pairs with exactly 1 concordant alns + uint64_t nunp_rep_uni2; // # pairs with >1 concordant aln, still unique + uint64_t nunp_rep_rep; // # pairs with repetitive concordant alns + uint64_t nunp_rep_0; // # pairs with 0 concordant alns + + // Unpaired + + uint64_t nunp_uni; // # unique from nconcord_0_ - ndiscord_ + uint64_t nunp_uni1; // # pairs with exactly 1 concordant alns + uint64_t nunp_uni2; // # pairs with >1 concordant aln, still unique + uint64_t nunp_rep; // # repetitive from + uint64_t nunp_0; // # with 0 alignments + + + uint64_t sum_best1; // Sum of all the best alignment scores + uint64_t sum_best2; // Sum of all the second-best alignment scores + uint64_t sum_best; // Sum of all the best and second-best + + MUTEX_T mutex_m; +}; + +// Type for expression numbers of hits +typedef int64_t THitInt; + +/** + * Parameters affecting reporting of alignments, specifically -k & -a, + * -m & -M. + */ +struct ReportingParams { + + explicit ReportingParams( + THitInt khits_, + THitInt kseeds_, + THitInt mhits_, + THitInt pengap_, + bool msample_, + bool discord_, + bool mixed_, + bool secondary_, + bool localAlign_, + int bowtie2_dp_, + bool sensitive_, + bool repeat_) + + { + init( + khits_, + kseeds_, + mhits_, + pengap_, + msample_, + discord_, + mixed_, + secondary_, + localAlign_, + bowtie2_dp_, + sensitive_, + repeat_); + } + + void init( + THitInt khits_, + THitInt kseeds_, + THitInt mhits_, + THitInt pengap_, + bool msample_, + bool discord_, + bool mixed_, + bool secondary_, + bool localAlign_, + int bowtie2_dp_, + bool sensitive_, + bool repeat_) + { + khits = khits_; // -k (or high if -a) + kseeds = kseeds_; + mhits = ((mhits_ == 0) ? std::numeric_limits::max() : mhits_); + pengap = pengap_; + msample = msample_; + discord = discord_; + mixed = mixed_; + secondary = secondary_; + localAlign = localAlign_; + bowtie2_dp = bowtie2_dp_; + sensitive = sensitive_; + repeat = repeat_; + } + +#ifndef NDEBUG + /** + * Check that reporting parameters are internally consistent. + */ + bool repOk() const { + assert_geq(khits, 1); + assert_geq(mhits, 1); + return true; + } +#endif + + /** + * Return true iff a -m or -M limit was set by the user. + */ + inline bool mhitsSet() const { + return mhits < std::numeric_limits::max(); + } + + /** + * Return a multiplier that indicates how many alignments we might look for + * (max). We can use this to boost parameters like ROWM and POSF + * appropriately. + */ + inline THitInt mult() const { + if(mhitsSet()) { + return mhits+1; + } + return khits; + } + + /** + * Given ROWM, POSF thresholds, boost them according to mult(). + */ + void boostThreshold(SimpleFunc& func) { + THitInt mul = mult(); + assert_gt(mul, 0); + if(mul == std::numeric_limits::max()) { + func.setMin(std::numeric_limits::max()); + } else if(mul > 1) { + func.mult(mul); + } + } + + /** + * Return true iff we are reporting all hits. + */ + bool allHits() const { + return khits == std::numeric_limits::max(); + } + + // Number of alignments to report + THitInt khits; + + // Number of seeds allowed to extend + THitInt kseeds; + + // Read is non-unique if mhits-1 next-best alignments are within + // pengap of the best alignment + THitInt mhits, pengap; + + // true if -M is specified, meaning that if the -M ceiling is + // exceeded, we should report 'khits' alignments chosen at random + // from those found + bool msample; + + // true iff we should seek and report discordant paired-end alignments for + // paired-end reads. + bool discord; + + // true iff we should seek and report unpaired mate alignments when there + // are paired-end alignments for a paired-end read, or if the number of + // paired-end alignments exceeds the -m ceiling. + bool mixed; + + // true iff we allow secondary alignments to be output (secondary alignments + // have lower scores) + bool secondary; + + // true iff we allow local alignment (not implemented yet) + bool localAlign; + + // true iff we allow dynamic alignment + int bowtie2_dp; + + // true iff we allow sensitive alignment + bool sensitive; + + // true iff we output alignments to repeat sequences + bool repeat; +}; + +/** + * A state machine keeping track of the number and type of alignments found so + * far. Its purpose is to inform the caller as to what stage the alignment is + * in and what categories of alignment are still of interest. This information + * should allow the caller to short-circuit some alignment work. Another + * purpose is to tell the AlnSinkWrap how many and what type of alignment to + * report. + * + * TODO: This class does not keep accurate information about what + * short-circuiting took place. If a read is identical to a previous read, + * there should be a way to query this object to determine what work, if any, + * has to be re-done for the new read. + */ +class ReportingState { + +public: + + enum { + NO_READ = 1, // haven't got a read yet + CONCORDANT_PAIRS, // looking for concordant pairs + DISCORDANT_PAIRS, // looking for discordant pairs + UNPAIRED, // looking for unpaired + DONE // finished looking + }; + + // Flags for different ways we can finish out a category of potential + // alignments. + + enum { + EXIT_DID_NOT_EXIT = 1, // haven't finished + EXIT_DID_NOT_ENTER, // never tried search + EXIT_SHORT_CIRCUIT_k, // -k exceeded + EXIT_SHORT_CIRCUIT_M, // -M exceeded + EXIT_SHORT_CIRCUIT_TRUMPED, // made irrelevant + EXIT_CONVERTED_TO_DISCORDANT, // unpair became discord + EXIT_NO_ALIGNMENTS, // none found + EXIT_WITH_ALIGNMENTS // some found + }; + + ReportingState(const ReportingParams& p) : p_(p) { reset(); } + + ReportingState operator=(ReportingState& copySource) { + state_ = copySource.state_; + paired_ = copySource.paired_;; + nconcord_ = copySource.nconcord_; + ndiscord_ = copySource.ndiscord_; + nunpair1_ = copySource.nunpair1_; + nunpair2_ = copySource.nunpair2_; + nunpairRepeat1_ = copySource.nunpairRepeat1_; + nunpairRepeat2_ = copySource.nunpairRepeat2_; + doneConcord_ = copySource.doneConcord_; + doneDiscord_ = copySource.doneDiscord_; + doneUnpair_ = copySource.doneUnpair_; + doneUnpair1_ = copySource.doneUnpair1_; + doneUnpair2_ = copySource.doneUnpair2_; + exitConcord_ = copySource.exitConcord_; + exitDiscord_ = copySource.exitDiscord_; + exitUnpair1_ = copySource.exitUnpair1_; + exitUnpair2_ = copySource.exitUnpair2_; + concordBest_ = copySource.concordBest_; + done_ = copySource.done_; + } + /** + * Set all state to uninitialized defaults. + */ + void reset() { + state_ = ReportingState::NO_READ; + paired_ = false; + nconcord_ = 0; + ndiscord_ = 0; + nunpair1_ = 0; + nunpair2_ = 0; + nunpairRepeat1_ = 0; + nunpairRepeat2_ = 0; + doneConcord_ = false; + doneDiscord_ = false; + doneUnpair_ = false; + doneUnpair1_ = false; + doneUnpair2_ = false; + exitConcord_ = ReportingState::EXIT_DID_NOT_ENTER; + exitDiscord_ = ReportingState::EXIT_DID_NOT_ENTER; + exitUnpair1_ = ReportingState::EXIT_DID_NOT_ENTER; + exitUnpair2_ = ReportingState::EXIT_DID_NOT_ENTER; + concordBest_ = getMinScore(); + done_ = false; + } + + /** + * Return true iff this ReportingState has been initialized with a call to + * nextRead() since the last time reset() was called. + */ + bool inited() const { return state_ != ReportingState::NO_READ; } + + /** + * Initialize state machine with a new read. The state we start in depends + * on whether it's paired-end or unpaired. + */ + void nextRead(bool paired); + + /** + * Caller uses this member function to indicate that one additional + * concordant alignment has been found. + */ + bool foundConcordant(TAlScore score); + + /** + * Caller uses this member function to indicate that one additional + * discordant alignment has been found. + */ + bool foundUnpaired(bool mate1, bool repeat = false); + + /** + * Called to indicate that the aligner has finished searching for + * alignments. This gives us a chance to finalize our state. + * + * TODO: Keep track of short-circuiting information. + */ + void finish(); + + /** + * Populate given counters with the number of various kinds of alignments + * to report for this read. Concordant alignments are preferable to (and + * mutually exclusive with) discordant alignments, and paired-end + * alignments are preferable to unpaired alignments. + * + * The caller also needs some additional information for the case where a + * pair or unpaired read aligns repetitively. If the read is paired-end + * and the paired-end has repetitive concordant alignments, that should be + * reported, and 'pairMax' is set to true to indicate this. If the read is + * paired-end, does not have any conordant alignments, but does have + * repetitive alignments for one or both mates, then that should be + * reported, and 'unpair1Max' and 'unpair2Max' are set accordingly. + * + * Note that it's possible in the case of a paired-end read for the read to + * have repetitive concordant alignments, but for one mate to have a unique + * unpaired alignment. + */ + void getReport( + uint64_t& nconcordAln, // # concordant alignments to report + uint64_t& ndiscordAln, // # discordant alignments to report + uint64_t& nunpair1Aln, // # unpaired alignments for mate #1 to report + uint64_t& nunpair2Aln, // # unpaired alignments for mate #2 to report + uint64_t& nunpairRepeat1Aln, // # unpaired alignments for mate #1 to report + uint64_t& nunpairRepeat2Aln, // # unpaired alignments for mate #2 to report + bool& pairMax, // repetitive concordant alignments + bool& unpair1Max, // repetitive alignments for mate #1 + bool& unpair2Max) // repetitive alignments for mate #2 + const; + + /** + * Return an integer representing the alignment state we're in. + */ + inline int state() const { return state_; } + + /** + * If false, there's no need to solve any more dynamic programming problems + * for finding opposite mates. + */ + inline bool doneConcordant() const { return doneConcord_; } + + /** + * If false, there's no need to seek any more discordant alignment. + */ + inline bool doneDiscordant() const { return doneDiscord_; } + + /** + * If false, there's no need to seek any more unpaired alignments for the + * specified mate. Note: this doesn't necessarily mean we can stop looking + * for alignments for the mate, since this might be necessary for finding + * concordant and discordant alignments. + */ + inline bool doneUnpaired(bool mate1) const { + return mate1 ? doneUnpair1_ : doneUnpair2_; + } + + /** + * If false, no further consideration of the given mate is necessary. It's + * not needed for *any* class of alignment: concordant, discordant or + * unpaired. + */ + inline bool doneWithMate(bool mate1) const { + bool doneUnpair = mate1 ? doneUnpair1_ : doneUnpair2_; + uint64_t nun = mate1 ? nunpair1_ : nunpair2_; + if(!doneUnpair || !doneConcord_) { + return false; // still needed for future concordant/unpaired alns + } + if(!doneDiscord_ && nun == 0) { + return false; // still needed for future discordant alignments + } + return true; // done + } + + /** + * Return true iff there's no need to seek any more unpaired alignments. + */ + inline bool doneUnpaired() const { return doneUnpair_; } + + /** + * Return true iff all alignment stages have been exited. + */ + inline bool done() const { return done_; } + + inline uint64_t numConcordant() const { return nconcord_; } + inline uint64_t numDiscordant() const { return ndiscord_; } + inline uint64_t numUnpaired1() const { return nunpair1_; } + inline uint64_t numUnpaired2() const { return nunpair2_; } + inline uint64_t numUnpairedRepeat1() const { return nunpairRepeat1_; } + inline uint64_t numUnpairedRepeat2() const { return nunpairRepeat2_; } + + inline int exitConcordant() const { return exitConcord_; } + inline int exitDiscordant() const { return exitDiscord_; } + inline int exitUnpaired1() const { return exitUnpair1_; } + inline int exitUnpaired2() const { return exitUnpair2_; } + + inline int64_t concordBest() const { return concordBest_; } + + void addNumUnpaired1() { + nunpair1_++; + } + void addNumUnpaired2() { + nunpair2_++; + } + +#ifndef NDEBUG + /** + * Check that ReportingState is internally consistent. + */ + bool repOk() const { + assert(p_.discord || doneDiscord_); + assert(p_.mixed || !paired_ || doneUnpair_); + assert(doneUnpair_ || !doneUnpair1_ || !doneUnpair2_); + if(p_.mhitsSet()) { + assert_leq(numConcordant(), (uint64_t)p_.mhits+1); + assert_leq(numDiscordant(), (uint64_t)p_.mhits+1); + assert(paired_ || numUnpaired1() <= (uint64_t)p_.mhits+1); + assert(paired_ || numUnpaired2() <= (uint64_t)p_.mhits+1); + } + assert(done() || !doneWithMate(true) || !doneWithMate(false)); + return true; + } +#endif + + /** + * Return ReportingParams object governing this ReportingState. + */ + const ReportingParams& params() const { + return p_; + } + +protected: + + /** + * Update state to reflect situation after converting two unique unpaired + * alignments, one for mate 1 and one for mate 2, into a single discordant + * alignment. + */ + void convertUnpairedToDiscordant() { + assert_eq(1, numUnpaired1()); + assert_eq(1, numUnpaired2()); + assert_eq(0, numDiscordant()); + exitUnpair1_ = exitUnpair2_ = ReportingState::EXIT_CONVERTED_TO_DISCORDANT; + nunpair1_ = nunpair2_ = 0; + nunpairRepeat1_ = nunpairRepeat2_ = 0; + ndiscord_ = 1; + assert_eq(1, numDiscordant()); + } + + /** + * Given the number of alignments in a category, check whether we + * short-circuited out of the category. Set the done and exit arguments to + * indicate whether and how we short-circuited. + */ + inline void areDone( + uint64_t cnt, // # alignments in category + bool& done, // out: whether we short-circuited out of category + int& exit) const; // out: if done, how we short-circuited (-k? -m? etc) + + /** + * Update done_ field to reflect whether we're totally done now. + */ + inline void updateDone() { + doneUnpair_ = doneUnpair1_ && doneUnpair2_; + done_ = doneUnpair_ && doneDiscord_ && doneConcord_; + } + + const ReportingParams& p_; // reporting parameters + int state_; // state we're currently in + bool paired_; // true iff read we're currently handling is paired + uint64_t nconcord_; // # concordants found so far + uint64_t ndiscord_; // # discordants found so far + uint64_t nunpair1_; // # unpaired alignments found so far for mate 1 + uint64_t nunpair2_; // # unpaired alignments found so far for mate 2 + uint64_t nunpairRepeat1_; // # unpaired repeat alignments found so far for mate 1 + uint64_t nunpairRepeat2_; // # unpaired repeat alignments found so far for mate 2 + bool doneConcord_; // true iff we're no longner interested in concordants + bool doneDiscord_; // true iff we're no longner interested in discordants + bool doneUnpair_; // no longner interested in unpaired alns + bool doneUnpair1_; // no longner interested in unpaired alns for mate 1 + bool doneUnpair2_; // no longner interested in unpaired alns for mate 2 + int exitConcord_; // flag indicating how we exited concordant state + int exitDiscord_; // flag indicating how we exited discordant state + int exitUnpair1_; // flag indicating how we exited unpaired 1 state + int exitUnpair2_; // flag indicating how we exited unpaired 2 state + TAlScore concordBest_; // + bool done_; // done with all alignments +}; + +/** + * Global hit sink for hits from the MultiSeed aligner. Encapsulates + * all aspects of the MultiSeed aligner hitsink that are global to all + * threads. This includes aspects relating to: + * + * (a) synchronized access to the output stream + * (b) the policy to be enforced by the per-thread wrapper + * + * TODO: Implement splitting up of alignments into separate files + * according to genomic coordinate. + */ +template +class AlnSink { + + typedef EList StrList; + +public: + + explicit AlnSink( + OutputQueue& oq, + const StrList& refnames, + const StrList& repnames, + bool quiet, + ALTDB* altdb = NULL, + SpliceSiteDB* ssdb = NULL) : + oq_(oq), + refnames_(refnames), + repnames_(repnames), + quiet_(quiet), + altdb_(altdb), + spliceSiteDB_(ssdb) + { } + + /** + * Destroy HitSinkobject; + */ + virtual ~AlnSink() { } + + /** + * Called when the AlnSink is wrapped by a new AlnSinkWrap. This helps us + * keep track of whether the main lock or any of the per-stream locks will + * be contended by multiple threads. + */ + void addWrapper() { numWrappers_++; } + + // for HISAT-3N + virtual void output(int threadId0, ReportingMetrics& met, BTString& o) { + + } + + /** + * Append a single hit to the given output stream. If + * synchronization is required, append() assumes the caller has + * already grabbed the appropriate lock. + */ + virtual void append( + BTString& o, + StackedAln& staln, + size_t threadId, + const Read *rd1, + const Read *rd2, + const TReadId rdid, + AlnRes *rs1, + AlnRes *rs2, + const AlnSetSumm& summ, + const SeedAlSumm& ssm1, + const SeedAlSumm& ssm2, + const AlnFlags* flags1, + const AlnFlags* flags2, + const PerReadMetrics& prm, + const Mapq& mapq, + const Scoring& sc, + bool report2) = 0; + + /*virtual void append( + ReportingMetrics& met, + BTString& o, + StackedAln& staln, + size_t threadId, + const Read *rd1, + const Read *rd2, + const TReadId rdid, + AlnRes *rs1, + AlnRes *rs2, + const AlnSetSumm& summ, + const SeedAlSumm& ssm1, + const SeedAlSumm& ssm2, + const AlnFlags* flags1, + const AlnFlags* flags2, + const PerReadMetrics& prm, + const Mapq& mapq, + const Scoring& sc, + bool report2) = 0;*/ + + + /** + * Report a given batch of hits for the given read or read pair. + * Should be called just once per read pair. Assumes all the + * alignments are paired, split between rs1 and rs2. + * + * The caller hasn't decided which alignments get reported as primary + * or secondary; that's up to the routine. Because the caller might + * want to know this, we use the pri1 and pri2 out arguments to + * convey this. + */ + virtual void reportHits( + BTString& o, // write to this buffer + StackedAln& staln, // StackedAln to write stacked alignment + size_t threadId, // which thread am I? + const Read *rd1, // mate #1 + const Read *rd2, // mate #2 + const TReadId rdid, // read ID + const EList& select1, // random subset of rd1s + const EList* select2, // random subset of rd2s + EList *rs1, // alignments for mate #1 + EList *rs2, // alignments for mate #2 + bool maxed, // true iff -m/-M exceeded + const AlnSetSumm& summ, // summary + const SeedAlSumm& ssm1, // seed alignment summ + const SeedAlSumm& ssm2, // seed alignment summ + const AlnFlags* flags1, // flags for mate #1 + const AlnFlags* flags2, // flags for mate #2 + const PerReadMetrics& prm, // per-read metrics + const Mapq& mapq, // MAPQ generator + const Scoring& sc, // scoring scheme + bool getLock = true) // true iff lock held by caller + { + // There are a few scenarios: + // 1. Read is unpaired, in which case rd2 is NULL + // 2. Read is paired-end and we're reporting concordant alignments + // 3. Read is paired-end and we're reporting discordant alignments + // 4. Read is paired-end and we're reporting unpaired alignments for + // both mates + // 5. Read is paired-end and we're reporting an unpaired alignments for + // just one mate or the other + assert(rd1 != NULL || rd2 != NULL); + assert(rs1 != NULL || rs2 != NULL); + AlnFlags flagscp1, flagscp2; + if(flags1 != NULL) { + flagscp1 = *flags1; + flags1 = &flagscp1; + flagscp1.setPrimary(true); + } + if(flags2 != NULL) { + flagscp2 = *flags2; + flags2 = &flagscp2; + flagscp2.setPrimary(true); + } + if(select2 != NULL) { + // Handle case 5 + assert(rd1 != NULL); assert(flags1 != NULL); + assert(rd2 != NULL); assert(flags2 != NULL); + assert_gt(select1.size(), 0); + assert_gt(select2->size(), 0); + AlnRes* r1pri = ((rs1 != NULL) ? &rs1->get(select1[0]) : NULL); + AlnRes* r2pri = ((rs2 != NULL) ? &rs2->get((*select2)[0]) : NULL); + append(o, staln, threadId, rd1, rd2, rdid, r1pri, r2pri, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, true); + flagscp1.setPrimary(false); + flagscp2.setPrimary(false); + for(size_t i = 1; i < select1.size(); i++) { + AlnRes* r1 = ((rs1 != NULL) ? &rs1->get(select1[i]) : NULL); + append(o, staln, threadId, rd1, rd2, rdid, r1, r2pri, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, false); + } + for(size_t i = 1; i < select2->size(); i++) { + AlnRes* r2 = ((rs2 != NULL) ? &rs2->get((*select2)[i]) : NULL); + append(o, staln, threadId, rd2, rd1, rdid, r2, r1pri, summ, + ssm2, ssm1, flags2, flags1, prm, mapq, sc, false); + } + } else { + // Handle cases 1-4 + for(size_t i = 0; i < select1.size(); i++) { + AlnRes* r1 = ((rs1 != NULL) ? &rs1->get(select1[i]) : NULL); + AlnRes* r2 = ((rs2 != NULL) ? &rs2->get(select1[i]) : NULL); + append(o, staln, threadId, rd1, rd2, rdid, r1, r2, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, true); + if(flags1 != NULL) { + flagscp1.setPrimary(false); + } + if(flags2 != NULL) { + flagscp2.setPrimary(false); + } + } + } + } + + /*virtual void report3NHits( + ReportingMetrics& met, // reporting metrics + BTString& o, // write to this buffer + StackedAln& staln, // StackedAln to write stacked alignment + size_t threadId, // which thread am I? + const Read *rd1, // mate #1 + const Read *rd2, // mate #2 + const TReadId rdid, // read ID + const EList& select1, // random subset of rd1s + const EList* select2, // random subset of rd2s + EList *rs1, // alignments for mate #1 + EList *rs2, // alignments for mate #2 + bool maxed, // true iff -m/-M exceeded + const AlnSetSumm& summ, // summary + const SeedAlSumm& ssm1, // seed alignment summ + const SeedAlSumm& ssm2, // seed alignment summ + const AlnFlags* flags1, // flags for mate #1 + const AlnFlags* flags2, // flags for mate #2 + const PerReadMetrics& prm, // per-read metrics + const Mapq& mapq, // MAPQ generator + const Scoring& sc, // scoring scheme + bool getLock = true) // true iff lock held by caller + { + // There are a few scenarios: + // 1. Read is unpaired, in which case rd2 is NULL + // 2. Read is paired-end and we're reporting concordant alignments + // 3. Read is paired-end and we're reporting discordant alignments + // 4. Read is paired-end and we're reporting unpaired alignments for + // both mates + // 5. Read is paired-end and we're reporting an unpaired alignments for + // just one mate or the other + assert(rd1 != NULL || rd2 != NULL); + assert(rs1 != NULL || rs2 != NULL); + AlnFlags flagscp1, flagscp2; + if(flags1 != NULL) { + flagscp1 = *flags1; + flags1 = &flagscp1; + flagscp1.setPrimary(true); + } + if(flags2 != NULL) { + flagscp2 = *flags2; + flags2 = &flagscp2; + flagscp2.setPrimary(true); + } + if(select2 != NULL) { + // Handle case 5 + assert(rd1 != NULL); assert(flags1 != NULL); + assert(rd2 != NULL); assert(flags2 != NULL); + assert_gt(select1.size(), 0); + assert_gt(select2->size(), 0); + AlnRes* r1pri = ((rs1 != NULL) ? &rs1->get(select1[0]) : NULL); + AlnRes* r2pri = ((rs2 != NULL) ? &rs2->get((*select2)[0]) : NULL); + append(met, o, staln, threadId, rd1, rd2, rdid, r1pri, r2pri, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, true); + flagscp1.setPrimary(false); + flagscp2.setPrimary(false); + for(size_t i = 1; i < select1.size(); i++) { + AlnRes* r1 = ((rs1 != NULL) ? &rs1->get(select1[i]) : NULL); + append(met, o, staln, threadId, rd1, rd2, rdid, r1, r2pri, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, false); + } + for(size_t i = 1; i < select2->size(); i++) { + AlnRes* r2 = ((rs2 != NULL) ? &rs2->get((*select2)[i]) : NULL); + append(met, o, staln, threadId, rd2, rd1, rdid, r2, r1pri, summ, + ssm2, ssm1, flags2, flags1, prm, mapq, sc, false); + } + } else { + // Handle cases 1-4 + for(size_t i = 0; i < select1.size(); i++) { + AlnRes* r1 = ((rs1 != NULL) ? &rs1->get(select1[i]) : NULL); + AlnRes* r2 = ((rs2 != NULL) ? &rs2->get(select1[i]) : NULL); + append(met, o, staln, threadId, rd1, rd2, rdid, r1, r2, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, true); + if(flags1 != NULL) { + flagscp1.setPrimary(false); + } + if(flags2 != NULL) { + flagscp2.setPrimary(false); + } + } + } + }*/ + + /** + * Report an unaligned read. Typically we do nothing, but we might + * want to print a placeholder when output is chained. + */ + virtual void reportUnaligned( + BTString& o, // write to this string + StackedAln& staln, // StackedAln to write stacked alignment + size_t threadId, // which thread am I? + const Read *rd1, // mate #1 + const Read *rd2, // mate #2 + const TReadId rdid, // read ID + const AlnSetSumm& summ, // summary + const SeedAlSumm& ssm1, // seed alignment summary + const SeedAlSumm& ssm2, // seed alignment summary + const AlnFlags* flags1, // flags for mate #1 + const AlnFlags* flags2, // flags for mate #2 + const PerReadMetrics& prm, // per-read metrics + const Mapq& mapq, // MAPQ calculator + const Scoring& sc, // scoring scheme + bool report2, // report alns for both mates? + bool getLock = true) // true iff lock held by caller + { + append(o, staln, threadId, rd1, rd2, rdid, NULL, NULL, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, report2); + } + + + /** + * Print summary of how many reads aligned, failed to align and aligned + * repetitively. Write it to stderr. Optionally write Hadoop counter + * updates. + */ + void printAlSumm( + ostream& out, + const ReportingMetrics& met, + size_t repThresh, // threshold for uniqueness, or max if no thresh + bool discord, // looked for discordant alignments + bool mixed, // looked for unpaired alignments where paired failed? + bool newSummary, // alignment summary in a new style + bool hadoopOut); // output Hadoop counters? + + /** + * Called when all alignments are complete. It is assumed that no + * synchronization is necessary. + */ + void finish( + ostream& out, + size_t repThresh, + bool discord, + bool mixed, + bool newSummary, + bool hadoopOut) + { + // Close output streams + if(!quiet_) { + printAlSumm( + out, + met_, + repThresh, + discord, + mixed, + newSummary, + hadoopOut); + } + } + +#ifndef NDEBUG + /** + * Check that hit sink is internally consistent. + */ + bool repOk() const { return true; } +#endif + + // + // Related to reporting seed hits + // + + /** + * Given a Read and associated, filled-in SeedResults objects, + * print a record summarizing the seed hits. + */ + void reportSeedSummary( + BTString& o, + const Read& rd, + TReadId rdid, + size_t threadId, + const SeedResults& rs, + bool getLock = true); + + /** + * Given a Read, print an empty record (all 0s). + */ + void reportEmptySeedSummary( + BTString& o, + const Read& rd, + TReadId rdid, + size_t threadId, + bool getLock = true); + + /** + * Append a batch of unresolved seed alignment results (i.e. seed + * alignments where all we know is the reference sequence aligned + * to and its SA range, not where it falls in the reference + * sequence) to the given output stream in Bowtie's seed-alignment + * verbose-mode format. + */ + virtual void appendSeedSummary( + BTString& o, + const Read& rd, + const TReadId rdid, + size_t seedsTried, + size_t nonzero, + size_t ranges, + size_t elts, + size_t seedsTriedFw, + size_t nonzeroFw, + size_t rangesFw, + size_t eltsFw, + size_t seedsTriedRc, + size_t nonzeroRc, + size_t rangesRc, + size_t eltsRc); + + /** + * Merge given metrics in with ours by summing all individual metrics. + */ + void mergeMetrics(const ReportingMetrics& met, bool getLock = true) { + met_.merge(met, getLock); + } + + /** + * Return mutable reference to the shared OutputQueue. + */ + OutputQueue& outq() { + return oq_; + } + +protected: + + OutputQueue& oq_; // output queue + int numWrappers_; // # threads owning a wrapper for this HitSink + const StrList& refnames_; // reference names + const StrList& repnames_; // repeat names + bool quiet_; // true -> don't print alignment stats at the end + ReportingMetrics met_; // global repository of reporting metrics + ALTDB* altdb_; + SpliceSiteDB* spliceSiteDB_; // +}; + +/** + * Per-thread hit sink "wrapper" for the MultiSeed aligner. Encapsulates + * aspects of the MultiSeed aligner hit sink that are per-thread. This + * includes aspects relating to: + * + * (a) Enforcement of the reporting policy + * (b) Tallying of results + * (c) Storing of results for the previous read in case this allows us to + * short-circuit some work for the next read (i.e. if it's identical) + * + * PHASED ALIGNMENT ASSUMPTION + * + * We make some assumptions about how alignment proceeds when we try to + * short-circuit work for identical reads. Specifically, we assume that for + * each read the aligner proceeds in a series of stages (or perhaps just one + * stage). In each stage, the aligner either: + * + * (a) Finds no alignments, or + * (b) Finds some alignments and short circuits out of the stage with some + * random reporting involved (e.g. in -k and/or -M modes), or + * (c) Finds all of the alignments in the stage + * + * In the event of (a), the aligner proceeds to the next stage and keeps + * trying; we can skip the stage entirely for the next read if it's identical. + * In the event of (b), or (c), the aligner stops and does not proceed to + * further stages. In the event of (b1), if the next read is identical we + * would like to tell the aligner to start again at the beginning of the stage + * that was short-circuited. + * + * In any event, the rs1_/rs2_/rs1u_/rs2u_ fields contain the alignments found + * in the last alignment stage attempted. + * + * HANDLING REPORTING LIMITS + * + * The user can specify reporting limits, like -k (specifies number of + * alignments to report out of those found) and -M (specifies a ceiling s.t. if + * there are more alignments than the ceiling, read is called repetitive and + * best found is reported). Enforcing these limits is straightforward for + * unpaired alignments: if a new alignment causes us to exceed the -M ceiling, + * we can stop looking. + * + * The case where both paired-end and unpaired alignments are possible is + * trickier. Once we have a number of unpaired alignments that exceeds the + * ceiling, we can stop looking *for unpaired alignments* - but we can't + * necessarily stop looking for paired-end alignments, since there may yet be + * more to find. However, if the input read is not a pair, then we can stop at + * this point. If the input read is a pair and we have a number of paired + * aligments that exceeds the -M ceiling, we can stop looking. + * + * CONCORDANT & DISCORDANT, PAIRED & UNPAIRED + * + * A note on paired-end alignment: Clearly, if an input read is + * paired-end and we find either concordant or discordant paired-end + * alignments for the read, then we would like to tally and report + * those alignments as such (and not as groups of 2 unpaired + * alignments). And if we fail to find any paired-end alignments, but + * we do find some unpaired alignments for one mate or the other, then + * we should clearly tally and report those alignments as unpaired + * alignments (if the user so desires). + * + * The situation is murkier when there are no paired-end alignments, + * but there are unpaired alignments for *both* mates. In this case, + * we might want to pick out zero or more pairs of mates and classify + * those pairs as discordant paired-end alignments. And we might want + * to classify the remaining alignments as unpaired. But how do we + * pick which pairs if any to call discordant? + * + * Because the most obvious use for discordant pairs is for identifying + * large-scale variation, like rearrangements or large indels, we would + * usually like to be conservative about what we call a discordant + * alignment. If there's a good chance that one or the other of the + * two mates has a good alignment to another place on the genome, this + * compromises the evidence for the large-scale variant. For this + * reason, Bowtie 2's policy is: if there are no paired-end alignments + * and there is *exactly one alignment each* for both mates, then the + * two alignments are paired and treated as a discordant paired-end + * alignment. Otherwise, all alignments are treated as unpaired + * alignments. + * + * When both paired and unpaired alignments are discovered by the + * aligner, only the paired alignments are reported by default. This + * is sensible considering relative likelihoods: if a good paired-end + * alignment is found, it is much more likely that the placement of + * the two mates implied by that paired alignment is correct than any + * placement implied by an unpaired alignment. + * + * + */ +template +class AlnSinkWrap { +public: + + AlnSinkWrap( + AlnSink& g, // AlnSink being wrapped + const ReportingParams& rp, // Parameters governing reporting + Mapq& mapq, // Mapq calculator + size_t threadId, // Thread ID + bool secondary = false, // Secondary alignments + const SpliceSiteDB* ssdb = NULL, // splice sites + uint64_t threads_rids_mindist = 0) : // synchronization + g_(g), + rp_(rp), + threadid_(threadId), + mapq_(mapq), + secondary_(secondary), + ssdb_(ssdb), + threads_rids_mindist_(threads_rids_mindist), + init_(false), + maxed1_(false), // read is pair and we maxed out mate 1 unp alns + maxed2_(false), // read is pair and we maxed out mate 2 unp alns + maxedOverall_(false), // alignments found so far exceed -m/-M ceiling + bestPair_(getMinScore()), + best2Pair_(getMinScore()), + bestUnp1_(getMinScore()), + best2Unp1_(getMinScore()), + bestUnp2_(getMinScore()), + best2Unp2_(getMinScore()), + bestUnpRepeat1_(getMinScore()), + best2UnpRepeat1_(getMinScore()), + bestUnpRepeat2_(getMinScore()), + best2UnpRepeat2_(getMinScore()), + bestSplicedPair_(0), + best2SplicedPair_(0), + bestSplicedUnp1_(0), + best2SplicedUnp1_(0), + bestSplicedUnp2_(0), + best2SplicedUnp2_(0), + rd1_(NULL), // mate 1 + rd2_(NULL), // mate 2 + rdid_(std::numeric_limits::max()), // read id + rs1_(), // mate 1 alignments for paired-end alignments + rs2_(), // mate 2 alignments for paired-end alignments + rs1u_(), // mate 1 unpaired alignments + rs2u_(), // mate 2 unpaired alignments + select1_(), // for selecting random subsets for mate 1 + select2_(), // for selecting random subsets for mate 2 + st_(rp) // reporting state - what's left to do? + { + assert(rp_.repOk()); + } + + void resetInit_(){ + init_ = false; + }; + + + /** + * Initialize the wrapper with a new read pair and return an + * integer >= -1 indicating which stage the aligner should start + * at. If -1 is returned, the aligner can skip the read entirely. + * at. If . Checks if the new read pair is identical to the + * previous pair. If it is, then we return the id of the first + * stage to run. + */ + int nextRead( + // One of the other of rd1, rd2 will = NULL if read is unpaired + const Read* rd1, // new mate #1 + const Read* rd2, // new mate #2 + TReadId rdid, // read ID for new pair + bool qualitiesMatter);// aln policy distinguishes b/t quals? + + /** + * Inform global, shared AlnSink object that we're finished with + * this read. The global AlnSink is responsible for updating + * counters, creating the output record, and delivering the record + * to the appropriate output stream. + */ + virtual void finishRead( + const SeedResults *sr1, // seed alignment results for mate 1 + const SeedResults *sr2, // seed alignment results for mate 2 + bool exhaust1, // mate 1 exhausted? + bool exhaust2, // mate 2 exhausted? + bool nfilt1, // mate 1 N-filtered? + bool nfilt2, // mate 2 N-filtered? + bool scfilt1, // mate 1 score-filtered? + bool scfilt2, // mate 2 score-filtered? + bool lenfilt1, // mate 1 length-filtered? + bool lenfilt2, // mate 2 length-filtered? + bool qcfilt1, // mate 1 qc-filtered? + bool qcfilt2, // mate 2 qc-filtered? + bool sortByScore, // prioritize alignments by score + RandomSource& rnd, // pseudo-random generator + ReportingMetrics& met, // reporting metrics + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc, // scoring scheme + bool suppressSeedSummary = true, + bool suppressAlignments = false, + bool templateLenAdjustment = true); + + /*void finish3NRead( + const SeedResults *sr1, // seed alignment results for mate 1 + const SeedResults *sr2, // seed alignment results for mate 2 + bool exhaust1, // mate 1 exhausted? + bool exhaust2, // mate 2 exhausted? + bool nfilt1, // mate 1 N-filtered? + bool nfilt2, // mate 2 N-filtered? + bool scfilt1, // mate 1 score-filtered? + bool scfilt2, // mate 2 score-filtered? + bool lenfilt1, // mate 1 length-filtered? + bool lenfilt2, // mate 2 length-filtered? + bool qcfilt1, // mate 1 qc-filtered? + bool qcfilt2, // mate 2 qc-filtered? + bool sortByScore, // prioritize alignments by score + RandomSource& rnd, // pseudo-random generator + ReportingMetrics& met, // reporting metrics + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc, // scoring scheme + bool suppressSeedSummary = true, + bool suppressAlignments = false, + bool templateLenAdjustment = true);*/ + + + /** + * Called by the aligner when a new unpaired or paired alignment is + * discovered in the given stage. This function checks whether the + * addition of this alignment causes the reporting policy to be + * violated (by meeting or exceeding the limits set by -k, -m, -M), + * in which case true is returned immediately and the aligner is + * short circuited. Otherwise, the alignment is tallied and false + * is returned. + */ + bool report( + int stage, + const AlnRes* rs1, + const AlnRes* rs2, + bool alignMate = false); + +#ifndef NDEBUG + /** + * Check that hit sink wrapper is internally consistent. + */ + bool repOk() const { + assert_eq(rs2_.size(), rs1_.size()); + if(rp_.mhitsSet()) { + assert_gt(rp_.mhits, 0); + assert_leq((int)rs1_.size(), rp_.mhits+1); + assert_leq((int)rs2_.size(), rp_.mhits+1); + assert(readIsPair() || (int)rs1u_.size() <= rp_.mhits+1); + assert(readIsPair() || (int)rs2u_.size() <= rp_.mhits+1); + } + if(init_) { + assert(rd1_ != NULL); + assert_neq(std::numeric_limits::max(), rdid_); + } + //assert_eq(st_.numConcordant() + st_.numDiscordant(), rs1_.size()); + //assert_eq(st_.numUnpaired1(), rs1u_.size()); + //assert_eq(st_.numUnpaired2(), rs2u_.size()); + assert(st_.repOk()); + return true; + } +#endif + + /** + * Return true iff no alignments have been reported to this wrapper + * since the last call to nextRead(). + */ + bool empty() const { + return rs1_.empty() && rs1u_.empty() && rs2u_.empty(); + } + + /** + * Return true iff we have already encountered a number of alignments that + * exceeds the -m/-M ceiling. TODO: how does this distinguish between + * pairs and mates? + */ + bool maxed() const { + return maxedOverall_; + } + + /** + * Return true if the current read is paired. + */ + bool readIsPair() const { + return rd1_ != NULL && rd2_ != NULL; + } + + /** + * Return true iff nextRead() has been called since the last time + * finishRead() was called. + */ + bool inited() const { return init_; } + + /** + * Return a const ref to the ReportingState object associated with the + * AlnSinkWrap. + */ + const ReportingState& state() const { return st_; } + + const ReportingParams& reportingParams() { return rp_;} + + /** + * Return true iff we're in -M mode. + */ + bool Mmode() const { + return rp_.mhitsSet(); + } + + /** + * Return true iff the policy is to report all hits. + */ + bool allHits() const { + return rp_.allHits(); + } + + /** + * Return true iff at least two alignments have been reported so far for an + * unpaired read or mate 1. + */ + bool hasSecondBestUnp1() const { + return best2Unp1_ != getMinScore(); + } + + /** + * Return true iff at least two alignments have been reported so far for + * mate 2. + */ + bool hasSecondBestUnp2() const { + return best2Unp2_ != getMinScore(); + } + + /** + * Return true iff at least two paired-end alignments have been reported so + * far. + */ + bool hasSecondBestPair() const { + return best2Pair_ != getMinScore(); + } + + /** + * Get best score observed so far for an unpaired read or mate 1. + */ + TAlScore bestUnp1() const { + return bestUnp1_; + } + + /** + * Get second-best score observed so far for an unpaired read or mate 1. + */ + TAlScore secondBestUnp1() const { + return best2Unp1_; + } + + /** + * Get best score observed so far for mate 2. + */ + TAlScore bestUnp2() const { + return bestUnp2_; + } + + /** + * Get second-best score observed so far for mate 2. + */ + TAlScore secondBestUnp2() const { + return best2Unp2_; + } + + /** + * Get best score observed so far for an unpaired read or mate 1. + */ + TAlScore bestUnpRepeat1() const { + return bestUnpRepeat1_; + } + + /** + * Get second-best score observed so far for an unpaired read or mate 1. + */ + TAlScore secondBestUnpRepeat1() const { + return best2UnpRepeat1_; + } + + /** + * Get best score observed so far for mate 2. + */ + TAlScore bestUnpRepeat2() const { + return bestUnpRepeat2_; + } + + /** + * Get second-best score observed so far for mate 2. + */ + TAlScore secondBestUnpRepeat2() const { + return best2UnpRepeat2_; + } + + /** + * Get best score observed so far for paired-end read. + */ + TAlScore bestPair() const { + return bestPair_; + } + + /** + * Get second-best score observed so far for paired-end read. + */ + TAlScore secondBestPair() const { + return best2Pair_; + } + + index_t bestSplicedPair() const { + return bestSplicedPair_; + } + + index_t best2SplicedPair() const { + return best2SplicedPair_; + } + + index_t bestSplicedUnp1() const { + return bestSplicedUnp1_; + } + + index_t best2SplicedUnp1() const { + return best2SplicedUnp1_; + } + + index_t bestSplicedUnp2() const { + return bestSplicedUnp2_; + } + + index_t best2SplicedUnp2() const { + return best2SplicedUnp2_; + } + + bool secondary() const { + return secondary_; + } + + /** + * + */ + void getUnp1(const EList*& rs) const { rs = &rs1u_; } + void getUnp2(const EList*& rs) const { rs = &rs2u_; } + void getPair(const EList*& rs1, const EList*& rs2) const { rs1 = &rs1_; rs2 = &rs2_; } + + index_t numUnp1() const { return rs1u_.size(); } + index_t numUnp2() const { return rs2u_.size(); } + index_t numPair() const { assert_eq(rs1_.size(), rs2_.size()); return rs1_.size(); } + + pair numBestUnp(index_t rdi) const { + index_t numGenome = 0, numRepeat = 0; + TAlScore maxScore = getMinScore(); + const EList& rs = (rdi == 0 ? rs1u_ : rs2u_); + for(size_t i = 0; i < rs.size(); i++) { + TAlScore curScore = rs[i].score().score(); + if(curScore > maxScore) { + numGenome = numRepeat = 0; + maxScore = curScore; + } + + if(curScore >= maxScore) { + if(rs[i].repeat()) { + numRepeat++; + } else { + numGenome++; + } + } + } + + return pair(numGenome, numRepeat); + } + + pair numBestPair() const { + index_t numGenome = 0, numRepeat = 0; + TAlScore maxScore = getMinScore(); + assert_eq(rs1_.size(), rs2_.size()); + for(size_t i = 0; i < rs1_.size(); i++) { + TAlScore curScore = rs1_[i].score().score() + rs2_[i].score().score(); + if(curScore > maxScore) { + numGenome = numRepeat = 0; + maxScore = curScore; + } + + if(curScore >= maxScore) { + if(rs1_[i].repeat() || rs2_[i].repeat()) { + assert(rs1_[i].repeat() && rs2_[i].repeat()); + numRepeat++; + } else { + numGenome++; + } + } + } + + return pair(numGenome, numRepeat); + } + +protected: + + /** + * Return true iff the read in rd1/rd2 matches the last read handled, which + * should still be in rd1_/rd2_. + */ + bool sameRead( + const Read* rd1, + const Read* rd2, + bool qualitiesMatter); + + /** + * If there is a configuration of unpaired alignments that fits our + * criteria for there being one or more discordant alignments, then + * shift the discordant alignments over to the rs1_/rs2_ lists, clear the + * rs1u_/rs2u_ lists and return true. Otherwise, return false. + */ + bool prepareDiscordants(); + + /** + * Given that rs is already populated with alignments, consider the + * alignment policy and make random selections where necessary. E.g. if we + * found 10 alignments and the policy is -k 2 -m 20, select 2 alignments at + * random. We "select" an alignment by setting the parallel entry in the + * 'select' list to true. + */ + size_t selectAlnsToReport( + const EList& rs, // alignments to select from + uint64_t num, // number of alignments to select + EList& select, // list to put results in + RandomSource& rnd) + const; + + /** + * rs1 (possibly together with rs2 if reads are paired) are populated with + * alignments. Here we prioritize them according to alignment score, and + * some randomness to break ties. Priorities are returned in the 'select' + * list. + */ + size_t selectByScore( + const EList* rs1, // alignments to select from (mate 1) + const EList* rs2, // alignments to select from (mate 2, or NULL) + uint64_t num, // number of alignments to select + EList& select, // prioritized list to put results in + RandomSource& rnd) + const; + + AlnSink& g_; // global alignment sink + ReportingParams rp_; // reporting parameters: khits, mhits etc + size_t threadid_; // thread ID + Mapq& mapq_; // mapq calculator + bool secondary_; // allow for secondary alignments + const SpliceSiteDB* ssdb_; // splice sites + uint64_t threads_rids_mindist_; // synchronization + bool init_; // whether we're initialized w/ read pair + bool maxed1_; // true iff # unpaired mate-1 alns reported so far exceeded -m/-M + bool maxed2_; // true iff # unpaired mate-2 alns reported so far exceeded -m/-M + bool maxedOverall_; // true iff # paired-end alns reported so far exceeded -m/-M + TAlScore bestPair_; // greatest score so far for paired-end + TAlScore best2Pair_; // second-greatest score so far for paired-end + TAlScore bestUnp1_; // greatest score so far for unpaired/mate1 + TAlScore best2Unp1_; // second-greatest score so far for unpaired/mate1 + TAlScore bestUnp2_; // greatest score so far for mate 2 + TAlScore best2Unp2_; // second-greatest score so far for mate 2 + TAlScore bestUnpRepeat1_; // greatest score so far for repeat unpaired/mate1 + TAlScore best2UnpRepeat1_; // second-greatest score so far for repeat unpaired/mate1 + TAlScore bestUnpRepeat2_; // greatest score so far for repeat mate 2 + TAlScore best2UnpRepeat2_; // second-greatest score so far for repeat mate 2 + index_t bestSplicedPair_; + index_t best2SplicedPair_; + index_t bestSplicedUnp1_; + index_t best2SplicedUnp1_; + index_t bestSplicedUnp2_; + index_t best2SplicedUnp2_; + const Read* rd1_; // mate #1 + const Read* rd2_; // mate #2 + TReadId rdid_; // read ID (potentially used for ordering) + EList rs1_; // paired alignments for mate #1 + EList rs2_; // paired alignments for mate #2 + EList rs1u_; // unpaired alignments for mate #1 + EList rs2u_; // unpaired alignments for mate #2 + EList select1_; // parallel to rs1_/rs2_ - which to report + EList select2_; // parallel to rs1_/rs2_ - which to report + ReportingState st_; // reporting state - what's left to do? + + EList > selectBuf_; + BTString obuf_; + StackedAln staln_; + + EList spliceSites_; + +}; + + +template +class AlnSinkWrap3N : public AlnSinkWrap { + using AlnSinkWrap::obuf_; + using AlnSinkWrap::g_; + using AlnSinkWrap::rdid_; + using AlnSinkWrap::threadid_; + using AlnSinkWrap::rd1_; + using AlnSinkWrap::rd2_; + using AlnSinkWrap::rs1_; + using AlnSinkWrap::rs2_; + using AlnSinkWrap::rs1u_; + using AlnSinkWrap::rs2u_; + using AlnSinkWrap::st_; + using AlnSinkWrap::readIsPair; + using AlnSinkWrap::select1_; + using AlnSinkWrap::select2_; + using AlnSinkWrap::spliceSites_; + using AlnSinkWrap::ssdb_; + using AlnSinkWrap::threads_rids_mindist_; + using AlnSinkWrap::staln_; + using AlnSinkWrap::mapq_; + using AlnSinkWrap::init_; + using AlnSinkWrap::prepareDiscordants; + using AlnSinkWrap::rp_; + using AlnSinkWrap::selectByScore; + using AlnSinkWrap::selectAlnsToReport; + + int lastMappingCycle; + +public: + AlnSinkWrap3N( + AlnSink& g, // AlnSink being wrapped + const ReportingParams& rp, // Parameters governing reporting + Mapq& mapq, // Mapq calculator + size_t threadId, // Thread ID + bool mappingCycles[4], // mapping cycles + bool secondary = false, // Secondary alignments + const SpliceSiteDB* ssdb = NULL, // splice sites + uint64_t threads_rids_mindist = 0) : + AlnSinkWrap( + g, + rp, + mapq, + threadId, + secondary, + ssdb, + threads_rids_mindist) + { + for (int i = 3; i >= 0; i--) + { + if (mappingCycles[i]) + { + lastMappingCycle = i; + break; + } + } + } + + void finishRead( + const SeedResults *sr1, // seed alignment results for mate 1 + const SeedResults *sr2, // seed alignment results for mate 2 + bool exhaust1, // mate 1 exhausted? + bool exhaust2, // mate 2 exhausted? + bool nfilt1, // mate 1 N-filtered? + bool nfilt2, // mate 2 N-filtered? + bool scfilt1, // mate 1 score-filtered? + bool scfilt2, // mate 2 score-filtered? + bool lenfilt1, // mate 1 length-filtered? + bool lenfilt2, // mate 2 length-filtered? + bool qcfilt1, // mate 1 qc-filtered? + bool qcfilt2, // mate 2 qc-filtered? + bool sortByScore, // prioritize alignments by score + RandomSource& rnd, // pseudo-random generator + ReportingMetrics& met, // reporting metrics + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc, // scoring scheme + bool suppressSeedSummary, // = true + bool suppressAlignments, // = false + bool templateLenAdjustment) // = true + { + obuf_.clear(); + OutputQueueMark qqm(g_.outq(), obuf_, rdid_, threadid_); + assert(init_); + if(!suppressSeedSummary) { + if(sr1 != NULL) { + assert(rd1_ != NULL); + // Mate exists and has non-empty SeedResults + g_.reportSeedSummary(obuf_, *rd1_, rdid_, threadid_, *sr1, true); + } else if(rd1_ != NULL) { + // Mate exists but has NULL SeedResults + g_.reportEmptySeedSummary(obuf_, *rd1_, rdid_, true); + } + if(sr2 != NULL) { + assert(rd2_ != NULL); + // Mate exists and has non-empty SeedResults + g_.reportSeedSummary(obuf_, *rd2_, rdid_, threadid_, *sr2, true); + } else if(rd2_ != NULL) { + // Mate exists but has NULL SeedResults + g_.reportEmptySeedSummary(obuf_, *rd2_, rdid_, true); + } + } + if(!suppressAlignments) { + // Ask the ReportingState what to report + st_.finish(); + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + uint64_t nunpairRepeat1 = 0, nunpairRepeat2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + st_.getReport( + nconcord, + ndiscord, + nunpair1, + nunpair2, + nunpairRepeat1, + nunpairRepeat2, + pairMax, + unpair1Max, + unpair2Max); + assert_leq(nconcord, rs1_.size()); + assert_leq(nunpair1, rs1u_.size()); + assert_leq(nunpair2, rs2u_.size()); + assert_leq(ndiscord, 1); + assert_gt(rp_.khits, 0); + assert_gt(rp_.mhits, 0); + assert(!pairMax || rs1_.size() >= (uint64_t)rp_.mhits); + assert(!unpair1Max || rs1u_.size() >= (uint64_t)rp_.mhits); + assert(!unpair2Max || rs2u_.size() >= (uint64_t)rp_.mhits); + + // Report concordant paired-end alignments if possible + if(nconcord > 0) { + AlnSetSumm concordSumm( + rd1_, rd2_, &rs1_, &rs2_, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + + // Possibly select a random subset + size_t off; + if(sortByScore) { + // Sort by score then pick from low to high + off = selectByScore(&rs1_, &rs2_, nconcord, select1_, rnd); + } else { + // Select subset randomly + off = selectAlnsToReport(rs1_, nconcord, select1_, rnd); + } + + concordSumm.numAlnsPaired(select1_.size()); + + assert_lt(off, rs1_.size()); + const AlnRes *rs1 = &rs1_[off]; + const AlnRes *rs2 = &rs2_[off]; + AlnFlags flags1( + ALN_FLAG_PAIR_CONCORD_MATE1, + st_.params().mhitsSet(), + unpair1Max, + pairMax, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + true, // opp aligned + rs2->fw()); // opp fw + AlnFlags flags2( + ALN_FLAG_PAIR_CONCORD_MATE2, + st_.params().mhitsSet(), + unpair2Max, + pairMax, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + false, // primary + true, // opp aligned + rs1->fw()); // opp fw + // Issue: we only set the flags once, but some of the flags might + // vary from pair to pair among the pairs we're reporting. For + // instance, whether a given mate aligns to the forward strand. + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL && sr2 != NULL) { + sr1->toSeedAlSumm(ssm1); + sr2->toSeedAlSumm(ssm2); + } + for(size_t i = 0; i < rs1_.size(); i++) { + spliceSites_.clear(); + if(templateLenAdjustment) { + rs1_[i].setMateParams(ALN_RES_TYPE_MATE1, &rs2_[i], flags1, ssdb_, threads_rids_mindist_, &spliceSites_); + rs2_[i].setMateParams(ALN_RES_TYPE_MATE2, &rs1_[i], flags2, ssdb_, threads_rids_mindist_, &spliceSites_); + } else { + rs1_[i].setMateParams(ALN_RES_TYPE_MATE1, &rs2_[i], flags1); + rs2_[i].setMateParams(ALN_RES_TYPE_MATE2, &rs1_[i], flags2); + } + assert_eq(abs(rs1_[i].fragmentLength()), abs(rs2_[i].fragmentLength())); + } + assert(!select1_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd1_, + rd2_, + rdid_, + select1_, + NULL, + &rs1_, + &rs2_, + pairMax, + concordSumm, + ssm1, + ssm2, + &flags1, + &flags2, + prm, + mapq_, + sc); + + init_ = false; + //g_.outq().finishRead(obuf_, rdid_, threadid_); + if (rd1_->threeN_cycle == lastMappingCycle) { + g_.output(threadid_-1, met, obuf_); + } + return; + } + // Report concordant paired-end alignments if possible + else if(ndiscord > 0) { + ASSERT_ONLY(bool ret =) prepareDiscordants(); + assert(ret); + assert_eq(1, rs1_.size()); + assert_eq(1, rs2_.size()); + AlnSetSumm discordSumm( + rd1_, rd2_, &rs1_, &rs2_, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + const AlnRes *rs1 = &rs1_[0]; + const AlnRes *rs2 = &rs2_[0]; + AlnFlags flags1( + ALN_FLAG_PAIR_DISCORD_MATE1, + st_.params().mhitsSet(), + false, + pairMax, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + true, // opp aligned + rs2->fw()); // opp fw + AlnFlags flags2( + ALN_FLAG_PAIR_DISCORD_MATE2, + st_.params().mhitsSet(), + false, + pairMax, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + false, // primary + true, // opp aligned + rs1->fw()); // opp fw + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + for(size_t i = 0; i < rs1_.size(); i++) { + rs1_[i].setMateParams(ALN_RES_TYPE_MATE1, &rs2_[i], flags1); + rs2_[i].setMateParams(ALN_RES_TYPE_MATE2, &rs1_[i], flags2); + assert(rs1_[i].isFraglenSet() == rs2_[i].isFraglenSet()); + assert(!rs1_[i].isFraglenSet() || abs(rs1_[i].fragmentLength()) == abs(rs2_[i].fragmentLength())); + } + ASSERT_ONLY(size_t off); + if(sortByScore) { + // Sort by score then pick from low to high + ASSERT_ONLY(off =) selectByScore(&rs1_, &rs2_, ndiscord, select1_, rnd); + } else { + // Select subset randomly + ASSERT_ONLY(off =) selectAlnsToReport(rs1_, ndiscord, select1_, rnd); + } + assert_eq(0, off); + assert(!select1_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd1_, + rd2_, + rdid_, + select1_, + NULL, + &rs1_, + &rs2_, + pairMax, + discordSumm, + ssm1, + ssm2, + &flags1, + &flags2, + prm, + mapq_, + sc); + + init_ = false; + //g_.outq().finishRead(obuf_, rdid_, threadid_); + if (rd1_->threeN_cycle == lastMappingCycle) { + g_.output(threadid_-1, met, obuf_); + } + return; + } + // If we're at this point, at least one mate failed to align. + // BTL: That's not true. It could be that there are no concordant + // alignments but both mates have unpaired alignments, with one of + // the mates having more than one. + //assert(nunpair1 == 0 || nunpair2 == 0); + assert(!pairMax); + + const AlnRes *repRs1 = NULL, *repRs2 = NULL; + AlnSetSumm summ1, summ2; + AlnFlags flags1, flags2; + TRefId refid = -1; TRefOff refoff = -1; bool repeat = false; + bool rep1 = rd1_ != NULL && nunpair1 > 0; + bool rep2 = rd2_ != NULL && nunpair2 > 0; + + // This is the preliminary if statement for mate 1 - here we're + // gathering some preliminary information, making it possible to call + // g_.reportHits(...) with information about both mates potentially + if(rep1) { + // Mate 1 aligned at least once + if(rep2) { + summ1.init( + rd1_, rd2_, NULL, NULL, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + } else { + summ1.init( + rd1_, NULL, NULL, NULL, &rs1u_, NULL, + exhaust1, exhaust2, -1, -1, false); + } + size_t off; + if(sortByScore) { + // Sort by score then pick from low to high + off = selectByScore(&rs1u_, NULL, nunpair1, select1_, rnd); + } else { + // Select subset randomly + off = selectAlnsToReport(rs1u_, nunpair1, select1_, rnd); + } + summ1.numAlns1(select1_.size()); + summ2.numAlns1(select1_.size()); + repRs1 = &rs1u_[off]; + } else if(rd1_ != NULL) { + // Mate 1 failed to align - don't do anything yet. First we want + // to collect information on mate 2 in case that factors into the + // summary + assert(!unpair1Max); + } + + if(rep2) { + if(rep1) { + summ2.init( + rd1_, rd2_, NULL, NULL, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + } else { + summ2.init( + NULL, rd2_, NULL, NULL, NULL, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + } + size_t off; + if(sortByScore) { + // Sort by score then pick from low to high + off = selectByScore(&rs2u_, NULL, nunpair2, select2_, rnd); + } else { + // Select subset randomly + off = selectAlnsToReport(rs2u_, nunpair2, select2_, rnd); + } + repRs2 = &rs2u_[off]; + summ1.numAlns2(select2_.size()); + summ2.numAlns2(select2_.size()); + } else if(rd2_ != NULL) { + // Mate 2 failed to align - don't do anything yet. First we want + // to collect information on mate 1 in case that factors into the + // summary + assert(!unpair2Max); + } + + // Now set up flags + if(rep1) { + // Initialize flags. Note: We want to have information about how + // the other mate aligned (if it did) at this point + flags1.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE1 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + unpair1Max, + pairMax, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + repRs2 != NULL, // opp aligned + repRs2 == NULL || repRs2->fw()); // opp fw + for(size_t i = 0; i < rs1u_.size(); i++) { + rs1u_[i].setMateParams(ALN_RES_TYPE_UNPAIRED_MATE1, NULL, flags1); + } + } + if(rep2) { + // Initialize flags. Note: We want to have information about how + // the other mate aligned (if it did) at this point + flags2.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE2 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + unpair2Max, + pairMax, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + true, // primary + repRs1 != NULL, // opp aligned + repRs1 == NULL || repRs1->fw()); // opp fw + for(size_t i = 0; i < rs2u_.size(); i++) { + rs2u_[i].setMateParams(ALN_RES_TYPE_UNPAIRED_MATE2, NULL, flags2); + } + } + + // Now report mate 1 + if(rep1) { + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + assert(!select1_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd1_, + repRs2 != NULL ? rd2_ : NULL, + rdid_, + select1_, + repRs2 != NULL ? &select2_ : NULL, + &rs1u_, + repRs2 != NULL ? &rs2u_ : NULL, + unpair1Max, + summ1, + ssm1, + ssm2, + &flags1, + repRs2 != NULL ? &flags2 : NULL, + prm, + mapq_, + sc); + assert_lt(select1_[0], rs1u_.size()); + refid = rs1u_[select1_[0]].refid(); + refoff = rs1u_[select1_[0]].refoff(); + repeat = rs1u_[select1_[0]].repeat(); + } + + // Now report mate 2 + if(rep2 && !rep1) { + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + assert(!select2_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd2_, + repRs1 != NULL ? rd1_ : NULL, + rdid_, + select2_, + repRs1 != NULL ? &select1_ : NULL, + &rs2u_, + repRs1 != NULL ? &rs1u_ : NULL, + unpair2Max, + summ2, + ssm1, + ssm2, + &flags2, + repRs1 != NULL ? &flags1 : NULL, + prm, + mapq_, + sc); + assert_lt(select2_[0], rs2u_.size()); + refid = rs2u_[select2_[0]].refid(); + refoff = rs2u_[select2_[0]].refoff(); + repeat = rs2u_[select2_[0]].repeat(); + } + + if(rd1_ != NULL && nunpair1 == 0) { + if(nunpair2 > 0) { + assert_neq(-1, refid); + summ1.init( + rd1_, NULL, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, refid, refoff, repeat); + } else { + summ1.init( + rd1_, NULL, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, -1, -1, false); + } + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + flags1.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE1 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + false, + false, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + repRs2 != NULL, // opp aligned + (repRs2 != NULL) ? repRs2->fw() : false); // opp fw + g_.reportUnaligned( + obuf_, // string to write output to + staln_, + threadid_, + rd1_, // read 1 + NULL, // read 2 + rdid_, // read id + summ1, // summ + ssm1, // + ssm2, + &flags1, // flags 1 + NULL, // flags 2 + prm, // per-read metrics + mapq_, // MAPQ calculator + sc, // scoring scheme + true); // get lock? + } + if(rd2_ != NULL && nunpair2 == 0) { + if(nunpair1 > 0) { + assert_neq(-1, refid); + summ2.init( + NULL, rd2_, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, refid, refoff, repeat); + } else { + summ2.init( + NULL, rd2_, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, -1, -1, false); + } + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + flags2.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE2 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + false, + false, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + true, // primary + repRs1 != NULL, // opp aligned + (repRs1 != NULL) ? repRs1->fw() : false); // opp fw + g_.reportUnaligned( + obuf_, // string to write output to + staln_, + threadid_, + rd2_, // read 1 + NULL, // read 2 + rdid_, // read id + summ2, // summ + ssm1, + ssm2, + &flags2, // flags 1 + NULL, // flags 2 + prm, // per-read metrics + mapq_, // MAPQ calculator + sc, // scoring scheme + true); // get lock? + } + } // if(suppress alignments) + init_ = false; + if (rd1_->threeN_cycle == lastMappingCycle) { + g_.output(threadid_-1, met, obuf_); + } + return; + } +}; + +/** + * An AlnSink concrete subclass for printing SAM alignments. The user might + * want to customize SAM output in various ways. We encapsulate all these + * customizations, and some of the key printing routines, in the SamConfig + * class in sam.h/sam.cpp. + */ +template +class AlnSinkSam : public AlnSink { + + typedef EList StrList; + + +public: + + AlnSinkSam( + OutputQueue& oq, // output queue + const SamConfig& samc, // settings & routines for SAM output + const StrList& refnames, // reference names + const StrList& repnames, // repeat names + bool quiet, // don't print alignment summary at end + ALTDB* altdb = NULL, + SpliceSiteDB* ssdb = NULL) : + AlnSink( + oq, + refnames, + repnames, + quiet, + altdb, + ssdb), + samc_(samc) + { } + + virtual ~AlnSinkSam() { } + + /** + * Append a single alignment result, which might be paired or + * unpaired, to the given output stream in Bowtie's verbose-mode + * format. If the alignment is paired-end, print mate1's alignment + * then mate2's alignment. + */ + virtual void append( + BTString& o, // write output to this string + StackedAln& staln, // StackedAln to write stacked alignment + size_t threadId, // which thread am I? + const Read* rd1, // mate #1 + const Read* rd2, // mate #2 + const TReadId rdid, // read ID + AlnRes* rs1, // alignments for mate #1 + AlnRes* rs2, // alignments for mate #2 + const AlnSetSumm& summ, // summary + const SeedAlSumm& ssm1, // seed alignment summary + const SeedAlSumm& ssm2, // seed alignment summary + const AlnFlags* flags1, // flags for mate #1 + const AlnFlags* flags2, // flags for mate #2 + const PerReadMetrics& prm, // per-read metrics + const Mapq& mapq, // MAPQ calculator + const Scoring& sc, // scoring scheme + bool report2) // report alns for both mates + { + assert(rd1 != NULL || rd2 != NULL); + if(rd1 != NULL) { + assert(flags1 != NULL); + appendMate(o, staln, *rd1, rd2, rdid, rs1, rs2, summ, ssm1, ssm2, + *flags1, prm, mapq, sc); + if(rs1 != NULL && rs1->spliced() && this->spliceSiteDB_ != NULL) { + this->spliceSiteDB_->addSpliceSite(*rd1, *rs1); + } + } + if(rd2 != NULL && report2) { + assert(flags2 != NULL); + appendMate(o, staln, *rd2, rd1, rdid, rs2, rs1, summ, ssm2, ssm1, + *flags2, prm, mapq, sc); + if(rs2 != NULL && rs2->spliced() && this->spliceSiteDB_ != NULL) { + this->spliceSiteDB_->addSpliceSite(*rd2, *rs2); + } + } + } + + +protected: + + /** + * Append a single per-mate alignment result to the given output + * stream. If the alignment is part of a pair, information about + * the opposite mate and its alignment are given in rdo/rso. + */ + virtual void appendMate( + BTString& o, + StackedAln& staln, + const Read& rd, + const Read* rdo, + const TReadId rdid, + AlnRes* rs, + AlnRes* rso, + const AlnSetSumm& summ, + const SeedAlSumm& ssm, + const SeedAlSumm& ssmo, + const AlnFlags& flags, + const PerReadMetrics& prm, // per-read metrics + const Mapq& mapq, // MAPQ calculator + const Scoring& sc); // scoring scheme + + const SamConfig& samc_; // settings & routines for SAM output + BTDnaString dseq_; // buffer for decoded read sequence + BTString dqual_; // buffer for decoded quality sequence +}; + +/** + * This is the class similar to AlnSinkSAM. + * AlnSink3NSam will put all the alignment result information into the class Alignment in "alignment_3N.h". + * This class should only be used for HISAT-3N (3N mode for HISAT2). + */ + +template +class AlnSink3NSam : public AlnSink { + +public: + const SamConfig& samc_; // settings & routines for SAM output + BTDnaString dseq_; // buffer for decoded read sequence + BTString dqual_; // buffer for decoded quality sequence + + //using AlnSinkSam::samc_; + typedef EList StrList; + using AlnSink::oq_; + + //int nThreads; + vector alignmentsEachThreads; + + AlnSink3NSam( + OutputQueue& oq, // output queue + const SamConfig& samc, // settings & routines for SAM output + const StrList& refnames, // reference names + const StrList& repnames, // repeat names + bool quiet, // don't print alignment summary at end + int nthreads, + BitPairReference* ref, + bool DNA, + ALTDB* altdb = NULL, + SpliceSiteDB* ssdb = NULL) : + AlnSink( + oq, + refnames, + repnames, + quiet, + altdb, + ssdb), + samc_(samc) + { + for (int i = 0; i < nthreads; i++) { + Alignments* newAlignments = new Alignments(ref, DNA); + alignmentsEachThreads.push_back(newAlignments); + } + } + + ~AlnSink3NSam() { + for (int i = 0; i < alignmentsEachThreads.size(); i++) { + delete alignmentsEachThreads[i]; + } + }; + + virtual void reportUnaligned( + BTString& o, // write to this string + StackedAln& staln, // StackedAln to write stacked alignment + size_t threadId, // which thread am I? + const Read *rd1, // mate #1 + const Read *rd2, // mate #2 + const TReadId rdid, // read ID + const AlnSetSumm& summ, // summary + const SeedAlSumm& ssm1, // seed alignment summary + const SeedAlSumm& ssm2, // seed alignment summary + const AlnFlags* flags1, // flags for mate #1 + const AlnFlags* flags2, // flags for mate #2 + const PerReadMetrics& prm, // per-read metrics + const Mapq& mapq, // MAPQ calculator + const Scoring& sc, // scoring scheme + bool report2, // report alns for both mates? + bool getLock = true) + { + append(o, staln, threadId, rd1, rd2, rdid, NULL, NULL, summ, + ssm1, ssm2, flags1, flags2, prm, mapq, sc, report2); + } + + /** + * output the rest of alignment information in alignmentsEachThreads[threadId0]. + * this function will be used after we receive new alignment result (with different rdid to previous one). + */ + virtual void output(int threadId0, ReportingMetrics& met, BTString& o) { + if (alignmentsEachThreads[threadId0]->readName->empty()) { + return; + } + met.nread++; + if (alignmentsEachThreads[threadId0]->paired) { + met.npaired++; + } else { + met.nunpaired++; + } + alignmentsEachThreads[threadId0]->output(met, o); + } + + /** + * Append a single alignment result, this function is for HSIAT-3N. + */ + void append( + BTString& o, // write output to this string + StackedAln& staln, // StackedAln to write stacked alignment + size_t threadId, // which thread am I? + const Read* rd1, // mate #1 + const Read* rd2, // mate #2 + const TReadId rdid, // read ID + AlnRes* rs1, // alignments for mate #1 + AlnRes* rs2, // alignments for mate #2 + const AlnSetSumm& summ, // summary + const SeedAlSumm& ssm1, // seed alignment summary + const SeedAlSumm& ssm2, // seed alignment summary + const AlnFlags* flags1, // flags for mate #1 + const AlnFlags* flags2, // flags for mate #2 + const PerReadMetrics& prm, // per-read metrics + const Mapq& mapq, // MAPQ calculator + const Scoring& sc, // scoring scheme + bool report2) // report alns for both mates + { + // this function is for HLA alignment result report. + size_t threadId0 = threadId-1; + + assert(rd1 != NULL || rd2 != NULL); + if(rd1 != NULL) { + assert(flags1 != NULL); + appendMate(staln, *rd1, rd2, rdid, rs1, rs2, summ, ssm1, ssm2, + *flags1, prm, mapq, sc, threadId0); + if(rs1 != NULL && rs1->spliced() && this->spliceSiteDB_ != NULL) { + this->spliceSiteDB_->addSpliceSite(*rd1, *rs1); + } + } + if(rd2 != NULL && report2) { + assert(flags2 != NULL); + appendMate(staln, *rd2, rd1, rdid, rs2, rs1, summ, ssm2, ssm1, + *flags2, prm, mapq, sc, threadId0); + if(rs2 != NULL && rs2->spliced() && this->spliceSiteDB_ != NULL) { + this->spliceSiteDB_->addSpliceSite(*rd2, *rs2); + } + } + } + + /** + * Append a single per-mate alignment result to the Alignment class. + * This function is for HISAT-3N. + */ + virtual void appendMate( + //Alignment* newAlignment, + StackedAln& staln, // store stacked alignment struct here + const Read& rd, + const Read* rdo, + const TReadId rdid, + AlnRes* rs, + AlnRes* rso, + const AlnSetSumm& summ, + const SeedAlSumm& ssm, + const SeedAlSumm& ssmo, + const AlnFlags& flags, + const PerReadMetrics& prm, + const Mapq& mapqCalc, + const Scoring& sc, + size_t threadId0) // which thread am I? + { + // check whether we want to recieve this alignment reuslt. + if(rs == NULL && samc_.omitUnalignedReads() || !alignmentsEachThreads[threadId0]->acceptNewAlignment()) { + return; + } + // get the Alignment pointer and append information into it. + Alignment* newAlignment; + alignmentsEachThreads[threadId0]->getFreeAlignmentPointer(newAlignment); + alignmentsEachThreads[threadId0]->getSequence(rd); + newAlignment->cycle_3N = rd.threeN_cycle; + + char buf[1024]; + char mapqInps[1024]; + if(rs != NULL) { + staln.reset(); + rs->initStacked(rd, staln); + staln.leftAlign(false /* not past MMs */); + } + int offAdj = 0; + // QNAME + samc_.printReadName(newAlignment->readName, rd.name, flags.partOfPair()); + // FLAG + int fl = 0; + if(flags.partOfPair()) { + fl |= SAM_FLAG_PAIRED; + if(flags.alignedConcordant()) { + fl |= SAM_FLAG_MAPPED_PAIRED; + } + if(!flags.mateAligned()) { + // Other fragment is unmapped + fl |= SAM_FLAG_MATE_UNMAPPED; + } + fl |= (flags.readMate1() ? + SAM_FLAG_FIRST_IN_PAIR : SAM_FLAG_SECOND_IN_PAIR); + if(flags.mateAligned() && rso != NULL) { + if(!rso->fw()) { + fl |= SAM_FLAG_MATE_STRAND; + } + } + } + if(!flags.isPrimary()) { + fl |= SAM_FLAG_NOT_PRIMARY; + } + if(rs != NULL && !rs->fw()) { + fl |= SAM_FLAG_QUERY_STRAND; + } + if(rs == NULL) { + // Failed to align + fl |= SAM_FLAG_UNMAPPED; + } + newAlignment->flag = fl; + // RNAME + if(rs != NULL) { + samc_.printRefNameFromIndex(newAlignment->chromosomeName, (size_t)rs->refid(), rs->repeat()); + newAlignment->chromosomeIndex = rs->refid(); + if (rs->repeat()) { + newAlignment->repeat = true; + } + } else { + if(summ.orefid() != -1) { + // Opposite mate aligned but this one didn't - print the opposite + // mate's RNAME and POS as is customary + assert(flags.partOfPair()); + samc_.printRefNameFromIndex(newAlignment->chromosomeName, (size_t)summ.orefid(), summ.repeat()); + if (newAlignment->repeat) { + newAlignment->pairToRepeat = true; + } + } else { + // No alignment + newAlignment->chromosomeName = "*"; + } + } + // POS + // Note: POS is *after* soft clipping. I.e. POS points to the + // upstream-most character *involved in the clipped alignment*. + if(rs != NULL) { + newAlignment->location = rs->refoff()+1+offAdj; + } else { + if(summ.orefid() != -1) { + // Opposite mate aligned but this one didn't - print the opposite + // mate's RNAME and POS as is customary + assert(flags.partOfPair()); + newAlignment->location = summ.orefoff()+1+offAdj; + } else { + // No alignment + newAlignment->location = 0; + } + } + // MAPQ + mapqInps[0] = '\0'; + if(rs != NULL) { + itoa10(mapqCalc.mapq( + summ, flags, rd.mate < 2, rd.length(), + rdo == NULL ? 0 : rdo->length(), mapqInps), buf); + newAlignment->MAPQ = buf; + } else { + // No alignment + newAlignment->MAPQ = "0"; + } + // CIGAR + if(rs != NULL) { + staln.buildCigar(false); + staln.writeCigar(newAlignment, NULL); + //newAlignment->getCigarSegement(staln); + } else { + // No alignment + newAlignment->cigarString = "*"; + } + if (rso != NULL) { + if (rso->repeat()) { + newAlignment->pairToRepeat = true; + } + } + // RNEXT + if(rs != NULL && flags.partOfPair()) { + if(rso != NULL && (rs->refid() != rso->refid() || rs->repeat() != rso->repeat())) { + samc_.printRefNameFromIndex(newAlignment->pairToChromosome, (size_t)rso->refid(), rso->repeat()); + } else { + newAlignment->pairToChromosome = "="; + } + } else if(summ.orefid() != -1) { + // The convention if this mate fails to align but the other doesn't is + // to copy the mate's details into here + newAlignment->pairToChromosome = "="; + } else { + newAlignment->pairToChromosome = "*"; + } + // PNEXT + if(rs != NULL && flags.partOfPair()) { + if(rso != NULL) { + newAlignment->pairToLocation = rso->refoff()+1; + } else { + // The convenstion is that if this mate aligns but the opposite + // doesn't, we print this mate's offset here + newAlignment->pairToLocation = rs->refoff()+1; + } + } else if(summ.orefid() != -1) { + // The convention if this mate fails to align but the other doesn't is + // to copy the mate's details into here + newAlignment->pairToLocation = summ.orefoff()+1; + } else { + newAlignment->pairToLocation = 0; + } + // ISIZE + if(rs != NULL && rs->isFraglenSet()) { + newAlignment->pairingDistance = rs->fragmentLength(); + } else { + // No fragment + newAlignment->pairingDistance = 0; + } + // SEQ + if(!flags.isPrimary() && samc_.omitSecondarySeqQual()) { + newAlignment->readSequence = "*"; + } else { + // Print the read + if(rd.patFw.length() == 0) { + newAlignment->readSequence = "*"; + } else { + if(rs == NULL || rs->fw()) { + newAlignment->readSequence = rd.originalFw.toZBuf(); + } else { + newAlignment->readSequence = rd.originalRc.toZBuf(); + } + } + } + // QUAL + if(!flags.isPrimary() && samc_.omitSecondarySeqQual()) { + newAlignment->readQuality = "*"; + } else { + // Print the quals + if(rd.qual.length() == 0) { + newAlignment->readQuality = "*"; + } else { + if(rs == NULL || rs->fw()) { + newAlignment->readQuality = rd.qual.toZBuf(); + } else { + newAlignment->readQuality = rd.qualRev.toZBuf(); + } + } + } + + // Optional fields + // + if(rs != NULL) { + samc_.printAlignedOptFlags( + newAlignment, + true, // first opt flag printed is first overall? + rd, // read + *rs, // individual alignment result + staln, // stacked alignment + flags, // alignment flags + summ, // summary of alignments for this read + ssm, // seed alignment summary + prm, // per-read metrics + sc, // scoring scheme + mapqInps, // inputs to MAPQ calculation + this->altdb_); + } else { + samc_.printEmptyOptFlags( + newAlignment, + true, // first opt flag printed is first overall? + rd, // read + flags, // alignment flags + summ, // summary of alignments for this read + ssm, // seed alignment summary + prm, // per-read metrics + sc); // scoring scheme + } + alignmentsEachThreads[threadId0]->append(newAlignment); + } +}; + + +static inline std::ostream& printPct( + std::ostream& os, + uint64_t num, + uint64_t denom) +{ + double pct = 0.0f; + if(denom != 0) { pct = 100.0 * (double)num / (double)denom; } + os << fixed << setprecision(2) << pct << '%'; + return os; +} + +/** + * Print a friendly summary of: + * + * 1. How many reads were aligned and had one or more alignments + * reported + * 2. How many reads exceeded the -m or -M ceiling and therefore had + * their alignments suppressed or sampled + * 3. How many reads failed to align entirely + * + * Optionally print a series of Hadoop streaming-style counter updates + * with similar information. + */ +template +void AlnSink::printAlSumm( + ostream& out, + const ReportingMetrics& met, + size_t repThresh, // threshold for uniqueness, or max if no thresh + bool discord, // looked for discordant alignments + bool mixed, // looked for unpaired alignments where paired failed? + bool newSummary, // alignment summary in a new style + bool hadoopOut) // output Hadoop counters? +{ + // NOTE: there's a filtering step at the very beginning, so everything + // being reported here is post filtering + + bool canRep = repThresh != MAX_SIZE_T; + if(hadoopOut) { + out << "reporter:counter:HISAT2,Reads processed," << met.nread << endl; + } + uint64_t totread = met.nread; + uint64_t totpair = met.npaired; + uint64_t totunpair = met.nunpaired; + uint64_t tot_al_cand = totunpair + totpair*2; + uint64_t tot_al = (met.nconcord_uni + met.nconcord_rep) * 2 + (met.ndiscord) * 2 + met.nunp_0_uni + met.nunp_0_rep + met.nunp_uni + met.nunp_rep; + assert_leq(tot_al, tot_al_cand); + if(newSummary) { + out << "HISAT2 summary stats:" << endl; + if(totpair > 0) { + uint64_t ncondiscord_0 = met.nconcord_0 - met.ndiscord; + out << "\tTotal pairs: " << totpair << endl; + out << "\t\tAligned concordantly or discordantly 0 time: " << ncondiscord_0 << " ("; printPct(out, ncondiscord_0, met.npaired); out << ")" << endl; + out << "\t\tAligned concordantly 1 time: " << met.nconcord_uni1 << " ("; printPct(out, met.nconcord_uni1, met.npaired); out << ")" << endl; + out << "\t\tAligned concordantly >1 times: " << met.nconcord_uni2 << " ("; printPct(out, met.nconcord_uni2, met.npaired); out << ")" << endl; + out << "\t\tAligned discordantly 1 time: " << met.ndiscord << " ("; printPct(out, met.ndiscord, met.npaired); out << ")" << endl; + + out << "\tTotal unpaired reads: " << ncondiscord_0 * 2 << endl; + out << "\t\tAligned 0 time: " << met.nunp_0_0 << " ("; printPct(out, met.nunp_0_0, ncondiscord_0 * 2); out << ")" << endl; + out << "\t\tAligned 1 time: " << met.nunp_0_uni1 << " ("; printPct(out, met.nunp_0_uni1, ncondiscord_0 * 2); out << ")" << endl; + out << "\t\tAligned >1 times: " << met.nunp_0_uni2 << " ("; printPct(out, met.nunp_0_uni2, ncondiscord_0 * 2); out << ")" << endl; + } else { + out << "\tTotal reads: " << totread << endl; + out << "\t\tAligned 0 time: " << met.nunp_0 << " ("; printPct(out, met.nunp_0, met.nunpaired); out << ")" << endl; + out << "\t\tAligned 1 time: " << met.nunp_uni1 << " ("; printPct(out, met.nunp_uni1, met.nunpaired); out << ")" << endl; + out << "\t\tAligned >1 times: " << met.nunp_uni2 << " ("; printPct(out, met.nunp_uni2, met.nunpaired); out << ")" << endl; + } + out << "\tOverall alignment rate: "; printPct(out, tot_al, tot_al_cand); out << endl; + + } else { + if(totread > 0) { + out << "" << totread << " reads; of these:" << endl; + } else { + assert_eq(0, met.npaired); + assert_eq(0, met.nunpaired); + out << "" << totread << " reads" << endl; + } + if(totpair > 0) { + // Paired output + out << " " << totpair << " ("; + printPct(out, totpair, totread); + out << ") were paired; of these:" << endl; + + // Concordants + out << " " << met.nconcord_0 << " ("; + printPct(out, met.nconcord_0, met.npaired); + out << ") aligned concordantly 0 times" << endl; + if(canRep) { + // Print the number that aligned concordantly exactly once + assert_eq(met.nconcord_uni, met.nconcord_uni1+met.nconcord_uni2); + out << " " << met.nconcord_uni1 << " ("; + printPct(out, met.nconcord_uni1, met.npaired); + out << ") aligned concordantly exactly 1 time" << endl; + + // Print the number that aligned concordantly more than once but + // fewer times than the limit + + out << " " << met.nconcord_uni2+met.nconcord_rep << " ("; + printPct(out, met.nconcord_uni2+met.nconcord_rep, met.npaired); + out << ") aligned concordantly >1 times" << endl; + } else { + // Print the number that aligned concordantly exactly once + assert_eq(met.nconcord_uni, met.nconcord_uni1+met.nconcord_uni2); + out << " " << met.nconcord_uni1 << " ("; + printPct(out, met.nconcord_uni1, met.npaired); + out << ") aligned concordantly exactly 1 time" << endl; + + // Print the number that aligned concordantly more than once + out << " " << met.nconcord_uni2 << " ("; + printPct(out, met.nconcord_uni2, met.npaired); + out << ") aligned concordantly >1 times" << endl; + } + if(discord) { + // TODO: what about discoardant and on separate chromosomes? + + // Bring out the unaligned pair total so we can subtract discordants + out << " ----" << endl; + out << " " << met.nconcord_0 + << " pairs aligned concordantly 0 times; of these:" << endl; + // Discordants + out << " " << met.ndiscord << " ("; + printPct(out, met.ndiscord, met.nconcord_0); + out << ") aligned discordantly 1 time" << endl; + } + uint64_t ncondiscord_0 = met.nconcord_0 - met.ndiscord; + if(mixed) { + // Bring out the unaligned pair total so we can subtract discordants + out << " ----" << endl; + out << " " << ncondiscord_0 + << " pairs aligned 0 times concordantly or discordantly; of these:" << endl; + out << " " << (ncondiscord_0 * 2) << " mates make up the pairs; of these:" << endl; + out << " " << met.nunp_0_0 << " " << "("; + printPct(out, met.nunp_0_0, ncondiscord_0 * 2); + out << ") aligned 0 times" << endl; + if(canRep) { + // Print the number that aligned exactly once + assert_eq(met.nunp_0_uni, met.nunp_0_uni1+met.nunp_0_uni2); + out << " " << met.nunp_0_uni1 << " ("; + printPct(out, met.nunp_0_uni1, ncondiscord_0 * 2); + out << ") aligned exactly 1 time" << endl; + + // Print the number that aligned more than once but fewer times + // than the limit + out << " " << met.nunp_0_uni2+met.nunp_0_rep << " ("; + printPct(out, met.nunp_0_uni2+met.nunp_0_rep, ncondiscord_0 * 2); + out << ") aligned >1 times" << endl; + } else { + // Print the number that aligned exactly once + assert_eq(met.nunp_0_uni, met.nunp_0_uni1+met.nunp_0_uni2); + out << " " << met.nunp_0_uni1 << " ("; + printPct(out, met.nunp_0_uni1, ncondiscord_0 * 2); + out << ") aligned exactly 1 time" << endl; + + // Print the number that aligned more than once but fewer times + // than the limit + out << " " << met.nunp_0_uni2 << " ("; + printPct(out, met.nunp_0_uni2, ncondiscord_0 * 2); + out << ") aligned >1 times" << endl; + } + } + } + if(totunpair > 0) { + // Unpaired output + out << " " << totunpair << " ("; + printPct(out, totunpair, totread); + out << ") were unpaired; of these:" << endl; + + out << " " << met.nunp_0 << " ("; + printPct(out, met.nunp_0, met.nunpaired); + out << ") aligned 0 times" << endl; + if(hadoopOut) { + out << "reporter:counter:HISAT 2,Unpaired reads with 0 alignments," + << met.nunpaired << endl; + } + + if(canRep) { + // Print the number that aligned exactly once + assert_eq(met.nunp_uni, met.nunp_uni1+met.nunp_uni2); + out << " " << met.nunp_uni1 << " ("; + printPct(out, met.nunp_uni1, met.nunpaired); + out << ") aligned exactly 1 time" << endl; + + // Print the number that aligned more than once but fewer times + // than the limit + out << " " << met.nunp_uni2+met.nunp_rep << " ("; + printPct(out, met.nunp_uni2+met.nunp_rep, met.nunpaired); + out << ") aligned >1 times" << endl; + } else { + // Print the number that aligned exactly once + assert_eq(met.nunp_uni, met.nunp_uni1+met.nunp_uni2); + out << " " << met.nunp_uni1 << " ("; + printPct(out, met.nunp_uni1, met.nunpaired); + out << ") aligned exactly 1 time" << endl; + + // Print the number that aligned more than once + out << " " << met.nunp_uni2 << " ("; + printPct(out, met.nunp_uni2, met.nunpaired); + out << ") aligned >1 times" << endl; + } + } + + printPct(out, tot_al, tot_al_cand); + out << " overall alignment rate" << endl; + } +} + +/** + * Return true iff the read in rd1/rd2 matches the last read handled, which + * should still be in rd1_/rd2_. + */ +template +bool AlnSinkWrap::sameRead( + // One of the other of rd1, rd2 will = NULL if read is unpaired + const Read* rd1, // new mate #1 + const Read* rd2, // new mate #2 + bool qualitiesMatter) // aln policy distinguishes b/t quals? +{ + bool same = false; + if(rd1_ != NULL || rd2_ != NULL) { + // This is not the first time the sink was initialized with + // a read. Check if new read/pair is identical to previous + // read/pair + if((rd1_ == NULL) == (rd1 == NULL) && + (rd2_ == NULL) == (rd2 == NULL)) + { + bool m1same = (rd1 == NULL && rd1_ == NULL); + if(!m1same) { + assert(rd1 != NULL); + assert(rd1_ != NULL); + m1same = Read::same( + rd1->patFw, // new seq + rd1->qual, // new quals + rd1_->patFw, // old seq + rd1_->qual, // old quals + qualitiesMatter); + } + if(m1same) { + bool m2same = (rd2 == NULL && rd2_ == NULL); + if(!m2same) { + m2same = Read::same( + rd2->patFw, // new seq + rd2->qual, // new quals + rd2_->patFw, // old seq + rd2_->qual, // old quals + qualitiesMatter); + } + same = m2same; + } + } + } + return same; +} + +/** + * Initialize the wrapper with a new read pair and return an integer >= -1 + * indicating which stage the aligner should start at. If -1 is returned, the + * aligner can skip the read entirely. Checks if the new read pair is + * identical to the previous pair. If it is, then we return the id of the + * first stage to run. + */ +template +int AlnSinkWrap::nextRead( + // One of the other of rd1, rd2 will = NULL if read is unpaired + const Read* rd1, // new mate #1 + const Read* rd2, // new mate #2 + TReadId rdid, // read ID for new pair + bool qualitiesMatter) // aln policy distinguishes b/t quals? +{ + assert(!init_); + assert(rd1 != NULL || rd2 != NULL); + init_ = true; + // Keep copy of new read, so that we can compare it with the + // next one + if(rd1 != NULL) { + rd1_ = rd1; + } else rd1_ = NULL; + if(rd2 != NULL) { + rd2_ = rd2; + } else rd2_ = NULL; + rdid_ = rdid; + // Caller must now align the read + maxed1_ = false; + maxed2_ = false; + maxedOverall_ = false; + bestPair_ = best2Pair_ = + bestUnp1_ = best2Unp1_ = + bestUnp2_ = best2Unp2_ = std::numeric_limits::min(); + bestUnpRepeat1_ = best2UnpRepeat1_ = + bestUnpRepeat2_ = best2UnpRepeat2_ = std::numeric_limits::min(); + bestSplicedPair_ = best2SplicedPair_ = + bestSplicedUnp1_ = best2SplicedUnp1_ = + bestSplicedUnp2_ = best2SplicedUnp2_ = 0; + rs1_.clear(); // clear out paired-end alignments + rs2_.clear(); // clear out paired-end alignments + rs1u_.clear(); // clear out unpaired alignments for mate #1 + rs2u_.clear(); // clear out unpaired alignments for mate #2 + st_.nextRead(readIsPair()); // reset state + assert(empty()); + assert(!maxed()); + // Start from the first stage + return 0; +} + +/** + * Inform global, shared AlnSink object that we're finished with this read. + * The global AlnSink is responsible for updating counters, creating the output + * record, and delivering the record to the appropriate output stream. + * + * What gets reported for a paired-end alignment? + * + * 1. If there are reportable concordant alignments, report those and stop + * 2. If there are reportable discordant alignments, report those and stop + * 3. If unpaired alignments can be reported: + * 3a. Report + # + * Update metrics. Only ambiguity is: what if a pair aligns repetitively and + * one of its mates aligns uniquely? + * + * uint64_t al; // # mates w/ >= 1 reported alignment + * uint64_t unal; // # mates w/ 0 alignments + * uint64_t max; // # mates withheld for exceeding -M/-m ceiling + * uint64_t al_concord; // # pairs w/ >= 1 concordant alignment + * uint64_t al_discord; // # pairs w/ >= 1 discordant alignment + * uint64_t max_concord; // # pairs maxed out + * uint64_t unal_pair; // # pairs where neither mate aligned + */ +template +void AlnSinkWrap::finishRead( + const SeedResults *sr1, // seed alignment results for mate 1 + const SeedResults *sr2, // seed alignment results for mate 2 + bool exhaust1, // mate 1 exhausted? + bool exhaust2, // mate 2 exhausted? + bool nfilt1, // mate 1 N-filtered? + bool nfilt2, // mate 2 N-filtered? + bool scfilt1, // mate 1 score-filtered? + bool scfilt2, // mate 2 score-filtered? + bool lenfilt1, // mate 1 length-filtered? + bool lenfilt2, // mate 2 length-filtered? + bool qcfilt1, // mate 1 qc-filtered? + bool qcfilt2, // mate 2 qc-filtered? + bool sortByScore, // prioritize alignments by score + RandomSource& rnd, // pseudo-random generator + ReportingMetrics& met, // reporting metrics + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc, // scoring scheme + bool suppressSeedSummary, // = true + bool suppressAlignments, // = false + bool templateLenAdjustment) // = true +{ + obuf_.clear(); + OutputQueueMark qqm(g_.outq(), obuf_, rdid_, threadid_); + assert(init_); + if(!suppressSeedSummary) { + if(sr1 != NULL) { + assert(rd1_ != NULL); + // Mate exists and has non-empty SeedResults + g_.reportSeedSummary(obuf_, *rd1_, rdid_, threadid_, *sr1, true); + } else if(rd1_ != NULL) { + // Mate exists but has NULL SeedResults + g_.reportEmptySeedSummary(obuf_, *rd1_, rdid_, true); + } + if(sr2 != NULL) { + assert(rd2_ != NULL); + // Mate exists and has non-empty SeedResults + g_.reportSeedSummary(obuf_, *rd2_, rdid_, threadid_, *sr2, true); + } else if(rd2_ != NULL) { + // Mate exists but has NULL SeedResults + g_.reportEmptySeedSummary(obuf_, *rd2_, rdid_, true); + } + } + if(!suppressAlignments) { + // Ask the ReportingState what to report + st_.finish(); + uint64_t nconcord = 0, ndiscord = 0, nunpair1 = 0, nunpair2 = 0; + uint64_t nunpairRepeat1 = 0, nunpairRepeat2 = 0; + bool pairMax = false, unpair1Max = false, unpair2Max = false; + st_.getReport( + nconcord, + ndiscord, + nunpair1, + nunpair2, + nunpairRepeat1, + nunpairRepeat2, + pairMax, + unpair1Max, + unpair2Max); + assert_leq(nconcord, rs1_.size()); + assert_leq(nunpair1, rs1u_.size()); + assert_leq(nunpair2, rs2u_.size()); + assert_leq(ndiscord, 1); + assert_gt(rp_.khits, 0); + assert_gt(rp_.mhits, 0); + assert(!pairMax || rs1_.size() >= (uint64_t)rp_.mhits); + assert(!unpair1Max || rs1u_.size() >= (uint64_t)rp_.mhits); + assert(!unpair2Max || rs2u_.size() >= (uint64_t)rp_.mhits); + met.nread++; + if(readIsPair()) { + met.npaired++; + } else { + met.nunpaired++; + } + // Report concordant paired-end alignments if possible + if(nconcord > 0) { + AlnSetSumm concordSumm( + rd1_, rd2_, &rs1_, &rs2_, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + + // Possibly select a random subset + size_t off; + if(sortByScore) { + // Sort by score then pick from low to high + off = selectByScore(&rs1_, &rs2_, nconcord, select1_, rnd); + } else { + // Select subset randomly + off = selectAlnsToReport(rs1_, nconcord, select1_, rnd); + } + + concordSumm.numAlnsPaired(select1_.size()); + + assert_lt(off, rs1_.size()); + const AlnRes *rs1 = &rs1_[off]; + const AlnRes *rs2 = &rs2_[off]; + AlnFlags flags1( + ALN_FLAG_PAIR_CONCORD_MATE1, + st_.params().mhitsSet(), + unpair1Max, + pairMax, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + true, // opp aligned + rs2->fw()); // opp fw + AlnFlags flags2( + ALN_FLAG_PAIR_CONCORD_MATE2, + st_.params().mhitsSet(), + unpair2Max, + pairMax, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + false, // primary + true, // opp aligned + rs1->fw()); // opp fw + // Issue: we only set the flags once, but some of the flags might + // vary from pair to pair among the pairs we're reporting. For + // instance, whether a given mate aligns to the forward strand. + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL && sr2 != NULL) { + sr1->toSeedAlSumm(ssm1); + sr2->toSeedAlSumm(ssm2); + } + for(size_t i = 0; i < rs1_.size(); i++) { + spliceSites_.clear(); + if(templateLenAdjustment) { + rs1_[i].setMateParams(ALN_RES_TYPE_MATE1, &rs2_[i], flags1, ssdb_, threads_rids_mindist_, &spliceSites_); + rs2_[i].setMateParams(ALN_RES_TYPE_MATE2, &rs1_[i], flags2, ssdb_, threads_rids_mindist_, &spliceSites_); + } else { + rs1_[i].setMateParams(ALN_RES_TYPE_MATE1, &rs2_[i], flags1); + rs2_[i].setMateParams(ALN_RES_TYPE_MATE2, &rs1_[i], flags2); + } + assert_eq(abs(rs1_[i].fragmentLength()), abs(rs2_[i].fragmentLength())); + } + assert(!select1_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd1_, + rd2_, + rdid_, + select1_, + NULL, + &rs1_, + &rs2_, + pairMax, + concordSumm, + ssm1, + ssm2, + &flags1, + &flags2, + prm, + mapq_, + sc); + if(pairMax) { + met.nconcord_rep++; + } else { + met.nconcord_uni++; + assert(!rs1_.empty()); + if(select1_.size() == 1) { + met.nconcord_uni1++; + } else { + met.nconcord_uni2++; + } + } + init_ = false; + //g_.outq().finishRead(obuf_, rdid_, threadid_); + return; + } + // Report concordant paired-end alignments if possible + else if(ndiscord > 0) { + ASSERT_ONLY(bool ret =) prepareDiscordants(); + assert(ret); + assert_eq(1, rs1_.size()); + assert_eq(1, rs2_.size()); + AlnSetSumm discordSumm( + rd1_, rd2_, &rs1_, &rs2_, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + const AlnRes *rs1 = &rs1_[0]; + const AlnRes *rs2 = &rs2_[0]; + AlnFlags flags1( + ALN_FLAG_PAIR_DISCORD_MATE1, + st_.params().mhitsSet(), + false, + pairMax, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + true, // opp aligned + rs2->fw()); // opp fw + AlnFlags flags2( + ALN_FLAG_PAIR_DISCORD_MATE2, + st_.params().mhitsSet(), + false, + pairMax, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + false, // primary + true, // opp aligned + rs1->fw()); // opp fw + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + for(size_t i = 0; i < rs1_.size(); i++) { + rs1_[i].setMateParams(ALN_RES_TYPE_MATE1, &rs2_[i], flags1); + rs2_[i].setMateParams(ALN_RES_TYPE_MATE2, &rs1_[i], flags2); + assert(rs1_[i].isFraglenSet() == rs2_[i].isFraglenSet()); + assert(!rs1_[i].isFraglenSet() || abs(rs1_[i].fragmentLength()) == abs(rs2_[i].fragmentLength())); + } + ASSERT_ONLY(size_t off); + if(sortByScore) { + // Sort by score then pick from low to high + ASSERT_ONLY(off =) selectByScore(&rs1_, &rs2_, ndiscord, select1_, rnd); + } else { + // Select subset randomly + ASSERT_ONLY(off =) selectAlnsToReport(rs1_, ndiscord, select1_, rnd); + } + assert_eq(0, off); + assert(!select1_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd1_, + rd2_, + rdid_, + select1_, + NULL, + &rs1_, + &rs2_, + pairMax, + discordSumm, + ssm1, + ssm2, + &flags1, + &flags2, + prm, + mapq_, + sc); + met.nconcord_0++; + met.ndiscord++; + init_ = false; + //g_.outq().finishRead(obuf_, rdid_, threadid_); + return; + } + // If we're at this point, at least one mate failed to align. + // BTL: That's not true. It could be that there are no concordant + // alignments but both mates have unpaired alignments, with one of + // the mates having more than one. + //assert(nunpair1 == 0 || nunpair2 == 0); + assert(!pairMax); + + const AlnRes *repRs1 = NULL, *repRs2 = NULL; + AlnSetSumm summ1, summ2; + AlnFlags flags1, flags2; + TRefId refid = -1; TRefOff refoff = -1; bool repeat = false; + bool rep1 = rd1_ != NULL && nunpair1 > 0; + bool rep2 = rd2_ != NULL && nunpair2 > 0; + + // This is the preliminary if statement for mate 1 - here we're + // gathering some preliminary information, making it possible to call + // g_.reportHits(...) with information about both mates potentially + if(rep1) { + // Mate 1 aligned at least once + if(rep2) { + summ1.init( + rd1_, rd2_, NULL, NULL, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + } else { + summ1.init( + rd1_, NULL, NULL, NULL, &rs1u_, NULL, + exhaust1, exhaust2, -1, -1, false); + } + size_t off; + if(sortByScore) { + // Sort by score then pick from low to high + off = selectByScore(&rs1u_, NULL, nunpair1, select1_, rnd); + } else { + // Select subset randomly + off = selectAlnsToReport(rs1u_, nunpair1, select1_, rnd); + } + summ1.numAlns1(select1_.size()); + summ2.numAlns1(select1_.size()); + repRs1 = &rs1u_[off]; + } else if(rd1_ != NULL) { + // Mate 1 failed to align - don't do anything yet. First we want + // to collect information on mate 2 in case that factors into the + // summary + assert(!unpair1Max); + } + + if(rep2) { + if(rep1) { + summ2.init( + rd1_, rd2_, NULL, NULL, &rs1u_, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + } else { + summ2.init( + NULL, rd2_, NULL, NULL, NULL, &rs2u_, + exhaust1, exhaust2, -1, -1, false); + } + size_t off; + if(sortByScore) { + // Sort by score then pick from low to high + off = selectByScore(&rs2u_, NULL, nunpair2, select2_, rnd); + } else { + // Select subset randomly + off = selectAlnsToReport(rs2u_, nunpair2, select2_, rnd); + } + repRs2 = &rs2u_[off]; + summ1.numAlns2(select2_.size()); + summ2.numAlns2(select2_.size()); + } else if(rd2_ != NULL) { + // Mate 2 failed to align - don't do anything yet. First we want + // to collect information on mate 1 in case that factors into the + // summary + assert(!unpair2Max); + } + + // Update counters given that one mate didn't align + if(readIsPair()) { + met.nconcord_0++; + } + if(rd1_ != NULL) { + if(nunpair1 > 0) { + // Update counters + if(readIsPair()) { + if(unpair1Max) met.nunp_0_rep++; + else { + met.nunp_0_uni++; + assert(!rs1u_.empty()); + if(select1_.size() == 1) { + met.nunp_0_uni1++; + } else { + met.nunp_0_uni2++; + } + } + } else { + if(unpair1Max) met.nunp_rep++; + else { + met.nunp_uni++; + assert(!rs1u_.empty()); + if(select1_.size() == 1) { + met.nunp_uni1++; + } else { + met.nunp_uni2++; + } + } + } + } else if(unpair1Max) { + // Update counters + if(readIsPair()) met.nunp_0_rep++; + else met.nunp_rep++; + } else { + // Update counters + if(readIsPair()) met.nunp_0_0++; + else met.nunp_0++; + } + } + if(rd2_ != NULL) { + if(nunpair2 > 0) { + // Update counters + if(readIsPair()) { + if(unpair2Max) met.nunp_0_rep++; + else { + assert(!rs2u_.empty()); + met.nunp_0_uni++; + if(select2_.size() == 1) { + met.nunp_0_uni1++; + } else { + met.nunp_0_uni2++; + } + } + } else { + if(unpair2Max) met.nunp_rep++; + else { + assert(!rs2u_.empty()); + met.nunp_uni++; + if(select2_.size() == 1) { + met.nunp_uni1++; + } else { + met.nunp_uni2++; + } + } + } + } else if(unpair2Max) { + // Update counters + if(readIsPair()) met.nunp_0_rep++; + else met.nunp_rep++; + } else { + // Update counters + if(readIsPair()) met.nunp_0_0++; + else met.nunp_0++; + } + } + + // Now set up flags + if(rep1) { + // Initialize flags. Note: We want to have information about how + // the other mate aligned (if it did) at this point + flags1.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE1 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + unpair1Max, + pairMax, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + repRs2 != NULL, // opp aligned + repRs2 == NULL || repRs2->fw()); // opp fw + for(size_t i = 0; i < rs1u_.size(); i++) { + rs1u_[i].setMateParams(ALN_RES_TYPE_UNPAIRED_MATE1, NULL, flags1); + } + } + if(rep2) { + // Initialize flags. Note: We want to have information about how + // the other mate aligned (if it did) at this point + flags2.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE2 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + unpair2Max, + pairMax, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + true, // primary + repRs1 != NULL, // opp aligned + repRs1 == NULL || repRs1->fw()); // opp fw + for(size_t i = 0; i < rs2u_.size(); i++) { + rs2u_[i].setMateParams(ALN_RES_TYPE_UNPAIRED_MATE2, NULL, flags2); + } + } + + // Now report mate 1 + if(rep1) { + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + assert(!select1_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd1_, + repRs2 != NULL ? rd2_ : NULL, + rdid_, + select1_, + repRs2 != NULL ? &select2_ : NULL, + &rs1u_, + repRs2 != NULL ? &rs2u_ : NULL, + unpair1Max, + summ1, + ssm1, + ssm2, + &flags1, + repRs2 != NULL ? &flags2 : NULL, + prm, + mapq_, + sc); + assert_lt(select1_[0], rs1u_.size()); + refid = rs1u_[select1_[0]].refid(); + refoff = rs1u_[select1_[0]].refoff(); + repeat = rs1u_[select1_[0]].repeat(); + } + + // Now report mate 2 + if(rep2 && !rep1) { + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + assert(!select2_.empty()); + g_.reportHits( + obuf_, + staln_, + threadid_, + rd2_, + repRs1 != NULL ? rd1_ : NULL, + rdid_, + select2_, + repRs1 != NULL ? &select1_ : NULL, + &rs2u_, + repRs1 != NULL ? &rs1u_ : NULL, + unpair2Max, + summ2, + ssm1, + ssm2, + &flags2, + repRs1 != NULL ? &flags1 : NULL, + prm, + mapq_, + sc); + assert_lt(select2_[0], rs2u_.size()); + refid = rs2u_[select2_[0]].refid(); + refoff = rs2u_[select2_[0]].refoff(); + repeat = rs2u_[select2_[0]].repeat(); + } + + if(rd1_ != NULL && nunpair1 == 0) { + if(nunpair2 > 0) { + assert_neq(-1, refid); + summ1.init( + rd1_, NULL, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, refid, refoff, repeat); + } else { + summ1.init( + rd1_, NULL, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, -1, -1, false); + } + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + flags1.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE1 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + false, + false, + nfilt1, + scfilt1, + lenfilt1, + qcfilt1, + st_.params().mixed, + true, // primary + repRs2 != NULL, // opp aligned + (repRs2 != NULL) ? repRs2->fw() : false); // opp fw + g_.reportUnaligned( + obuf_, // string to write output to + staln_, + threadid_, + rd1_, // read 1 + NULL, // read 2 + rdid_, // read id + summ1, // summ + ssm1, // + ssm2, + &flags1, // flags 1 + NULL, // flags 2 + prm, // per-read metrics + mapq_, // MAPQ calculator + sc, // scoring scheme + true); // get lock? + } + if(rd2_ != NULL && nunpair2 == 0) { + if(nunpair1 > 0) { + assert_neq(-1, refid); + summ2.init( + NULL, rd2_, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, refid, refoff, repeat); + } else { + summ2.init( + NULL, rd2_, NULL, NULL, NULL, NULL, + exhaust1, exhaust2, -1, -1, false); + } + SeedAlSumm ssm1, ssm2; + if(sr1 != NULL) sr1->toSeedAlSumm(ssm1); + if(sr2 != NULL) sr2->toSeedAlSumm(ssm2); + flags2.init( + readIsPair() ? + ALN_FLAG_PAIR_UNPAIRED_MATE2 : + ALN_FLAG_PAIR_UNPAIRED, + st_.params().mhitsSet(), + false, + false, + nfilt2, + scfilt2, + lenfilt2, + qcfilt2, + st_.params().mixed, + true, // primary + repRs1 != NULL, // opp aligned + (repRs1 != NULL) ? repRs1->fw() : false); // opp fw + g_.reportUnaligned( + obuf_, // string to write output to + staln_, + threadid_, + rd2_, // read 1 + NULL, // read 2 + rdid_, // read id + summ2, // summ + ssm1, + ssm2, + &flags2, // flags 1 + NULL, // flags 2 + prm, // per-read metrics + mapq_, // MAPQ calculator + sc, // scoring scheme + true); // get lock? + } + } // if(suppress alignments) + init_ = false; + return; +} + + +/** + * Called by the aligner when a new unpaired or paired alignment is + * discovered in the given stage. This function checks whether the + * addition of this alignment causes the reporting policy to be + * violated (by meeting or exceeding the limits set by -k, -m, -M), + * in which case true is returned immediately and the aligner is + * short circuited. Otherwise, the alignment is tallied and false + * is returned. + */ +template +bool AlnSinkWrap::report( + int stage, + const AlnRes* rs1, + const AlnRes* rs2, + bool alignMate) +{ + assert(init_); + assert(rs1 != NULL || rs2 != NULL); + assert(rs1 == NULL || !rs1->empty()); + assert(rs2 == NULL || !rs2->empty()); + assert(rs1 == NULL || rs1->repOk()); + assert(rs2 == NULL || rs2->repOk()); + bool paired = (rs1 != NULL && rs2 != NULL); + bool one = (rs1 != NULL); + const AlnRes* rsa = one ? rs1 : rs2; + const AlnRes* rsb = one ? rs2 : rs1; + + // Tally overall alignment score + TAlScore score = rsa->score().score(); + if(rsb != NULL) score += rsb->score().score(); + index_t num_spliced = (index_t)rsa->num_spliced(); + if(rsb != NULL) num_spliced += (index_t)rsb->num_spliced(); + + if(paired) { + assert(readIsPair()); + st_.foundConcordant(score); + rs1_.push_back(*rs1); + rs2_.push_back(*rs2); + } else { + st_.foundUnpaired(one, rsa->repeat()); + if(one) { + rs1u_.push_back(*rs1); + } else { + rs2u_.push_back(*rs2); + } + } + + // Update best score so far + if(paired) { + if(score > bestPair_) { + best2Pair_ = bestPair_; + bestPair_ = score; + best2SplicedPair_ = bestSplicedPair_; + bestSplicedPair_ = num_spliced; + } else if(score > best2Pair_) { + best2Pair_ = score; + best2SplicedPair_ = num_spliced; + } + } else { + if(one) { + if(score > bestUnp1_) { + best2Unp1_ = bestUnp1_; + bestUnp1_ = score; + best2SplicedUnp1_ = bestSplicedUnp1_; + bestSplicedUnp1_ = num_spliced; + } else if(score > best2Unp1_) { + best2Unp1_ = score; + best2SplicedUnp1_ = num_spliced; + } + if(rs1->repeat()) { + if(score > bestUnpRepeat1_) { + best2UnpRepeat1_ = bestUnpRepeat1_; + bestUnpRepeat1_ = score; + } else if(score > best2UnpRepeat1_) { + best2UnpRepeat1_ = score; + } + } + } else { + if(score > bestUnp2_) { + best2Unp2_ = bestUnp2_; + bestUnp2_ = score; + best2SplicedUnp2_ = bestSplicedUnp2_; + bestSplicedUnp2_ = num_spliced; + } else if(score > best2Unp2_) { + best2Unp2_ = score; + best2SplicedUnp1_ = num_spliced; + } + if(rs2->repeat()) { + if(score > bestUnpRepeat2_) { + best2UnpRepeat2_ = bestUnpRepeat2_; + bestUnpRepeat2_ = score; + } else if(score > best2UnpRepeat2_) { + best2UnpRepeat2_ = score; + } + } + } + } + return st_.done(); +} + +/** + * If there is a configuration of unpaired alignments that fits our + * criteria for there being one or more discordant alignments, then + * shift the discordant alignments over to the rs1_/rs2_ lists, clear the + * rs1u_/rs2u_ lists and return true. Otherwise, return false. + */ +template +bool AlnSinkWrap::prepareDiscordants() { + if(rs1u_.size() == 1 && rs2u_.size() == 1) { + assert(rs1_.empty()); + assert(rs2_.empty()); + rs1_.push_back(rs1u_[0]); + rs2_.push_back(rs2u_[0]); + return true; + } + return false; +} + +/** + * rs1 (possibly together with rs2 if reads are paired) are populated with + * alignments. Here we prioritize them according to alignment score, and + * some randomness to break ties. Priorities are returned in the 'select' + * list. + */ +template +size_t AlnSinkWrap::selectByScore( + const EList* rs1, // alignments to select from (mate 1) + const EList* rs2, // alignments to select from (mate 2, or NULL) + uint64_t num, // number of alignments to select + EList& select, // prioritized list to put results in + RandomSource& rnd) +const +{ + assert(init_); + assert(repOk()); + assert_gt(num, 0); + assert(rs1 != NULL); + size_t sz = rs1->size(); // sz = # alignments found + assert_leq(num, sz); + if(sz < num) { + num = sz; + } + // num = # to select + if(sz < 1) { + return 0; + } + select.resize((size_t)num); + // Use 'selectBuf_' as a temporary list for sorting purposes + EList >& buf = + const_cast >& >(selectBuf_); + buf.resize(sz); + // Sort by score. If reads are pairs, sort by sum of mate scores. + for(size_t i = 0; i < sz; i++) { + buf[i].first = (*rs1)[i].score().hisat2_score(); + if(rs2 != NULL) { + buf[i].first += (*rs2)[i].score().hisat2_score(); + } + buf[i].second = i; // original offset + } + buf.sort(); buf.reverse(); // sort in descending order by score + + // Randomize streaks of alignments that are equal by score + size_t streak = 0; + for(size_t i = 1; i < buf.size(); i++) { + if(buf[i].first == buf[i-1].first) { + if(streak == 0) { streak = 1; } + streak++; + } else { + if(streak > 1) { + assert_geq(i, streak); + buf.shufflePortion(i-streak, streak, rnd); + } + streak = 0; + } + } + if(streak > 1) { + buf.shufflePortion(buf.size() - streak, streak, rnd); + } + + select.clear(); + for(size_t i = 0; i < buf.size(); i++) { + index_t add = buf[i].second; + if(i >= num && !(*rs1)[add].repeat()) { + assert(rs2 == NULL || !(*rs2)[add].repeat()); + break; + } + select.push_back(add); + } + + if(!secondary_) { + assert_geq(buf.size(), select.size()); + for(size_t i = 0; i + 1 < select.size(); i++) { + if(buf[i].first != buf[i+1].first) { + select.resize(i+1); + break; + } + } + } + + // Returns index of the representative alignment, but in 'select' also + // returns the indexes of the next best selected alignments in order by + // score. + return selectBuf_[0].second; +} + +/** + * Given that rs is already populated with alignments, consider the + * alignment policy and make random selections where necessary. E.g. if we + * found 10 alignments and the policy is -k 2 -m 20, select 2 alignments at + * random. We "select" an alignment by setting the parallel entry in the + * 'select' list to true. + * + * Return the "representative" alignment. This is simply the first one + * selected. That will also be what SAM calls the "primary" alignment. + */ +template +size_t AlnSinkWrap::selectAlnsToReport( + const EList& rs, // alignments to select from + uint64_t num, // number of alignments to select + EList& select, // list to put results in + RandomSource& rnd) +const +{ + assert(init_); + assert(repOk()); + assert_gt(num, 0); + size_t sz = rs.size(); + if(sz < num) { + num = sz; + } + if(sz < 1) { + return 0; + } + select.resize((size_t)num); + if(sz == 1) { + assert_eq(1, num); + select[0] = 0; + return 0; + } + // Select a random offset into the list of alignments + uint32_t off = rnd.nextU32() % (uint32_t)sz; + uint32_t offOrig = off; + // Now take elements starting at that offset, wrapping around to 0 if + // necessary. Leave the rest. + for(size_t i = 0; i < num; i++) { + select[i] = off; + off++; + if(off == sz) { + off = 0; + } + } + return offOrig; +} + +#define NOT_SUPPRESSED !suppress_[field++] +#define BEGIN_FIELD { \ +if(firstfield) firstfield = false; \ +else o.append('\t'); \ +} +#define WRITE_TAB { \ +if(firstfield) firstfield = false; \ +else o.append('\t'); \ +} +#define WRITE_NUM(o, x) { \ +itoa10(x, buf); \ +o.append(buf); \ +} + +/** + * Print a seed summary to the first output stream in the outs_ list. + */ +template +void AlnSink::reportSeedSummary( + BTString& o, + const Read& rd, + TReadId rdid, + size_t threadId, + const SeedResults& rs, + bool getLock) +{ + appendSeedSummary( + o, // string to write to + rd, // read + rdid, // read id + rs.numOffs()*2, // # seeds tried + rs.nonzeroOffsets(), // # seeds with non-empty results + rs.numRanges(), // # ranges for all seed hits + rs.numElts(), // # elements for all seed hits + rs.numOffs(), // # seeds tried from fw read + rs.nonzeroOffsetsFw(), // # seeds with non-empty results from fw read + rs.numRangesFw(), // # ranges for seed hits from fw read + rs.numEltsFw(), // # elements for seed hits from fw read + rs.numOffs(), // # seeds tried from rc read + rs.nonzeroOffsetsRc(), // # seeds with non-empty results from fw read + rs.numRangesRc(), // # ranges for seed hits from fw read + rs.numEltsRc()); // # elements for seed hits from fw read +} + +/** + * Print an empty seed summary to the first output stream in the outs_ list. + */ +template +void AlnSink::reportEmptySeedSummary( + BTString& o, + const Read& rd, + TReadId rdid, + size_t threadId, + bool getLock) +{ + appendSeedSummary( + o, // string to append to + rd, // read + rdid, // read id + 0, // # seeds tried + 0, // # seeds with non-empty results + 0, // # ranges for all seed hits + 0, // # elements for all seed hits + 0, // # seeds tried from fw read + 0, // # seeds with non-empty results from fw read + 0, // # ranges for seed hits from fw read + 0, // # elements for seed hits from fw read + 0, // # seeds tried from rc read + 0, // # seeds with non-empty results from fw read + 0, // # ranges for seed hits from fw read + 0); // # elements for seed hits from fw read +} + +/** + * Print the given string. If ws = true, print only up to and not + * including the first space or tab. Useful for printing reference + * names. + */ +template +static inline void printUptoWs( + BTString& s, + const T& str, + bool chopws) +{ + size_t len = str.length(); + for(size_t i = 0; i < len; i++) { + if(!chopws || (str[i] != ' ' && str[i] != '\t')) { + s.append(str[i]); + } else { + break; + } + } +} + +/** + * Append a batch of unresolved seed alignment summary results (i.e. + * seed alignments where all we know is the reference sequence aligned + * to and its SA range, not where it falls in the reference + * sequence) to the given output stream in Bowtie's seed-sumamry + * verbose-mode format. + * + * The seed summary format is: + * + * - One line per read + * - A typical line consists of a set of tab-delimited fields: + * + * 1. Read name + * 2. Total number of seeds extracted from the read + * 3. Total number of seeds that aligned to the reference at + * least once (always <= field 2) + * 4. Total number of distinct BW ranges found in all seed hits + * (always >= field 3) + * 5. Total number of distinct BW elements found in all seed + * hits (always >= field 4) + * 6-9.: Like 2-5. but just for seeds extracted from the + * forward representation of the read + * 10-13.: Like 2-5. but just for seeds extracted from the + * reverse-complement representation of the read + * + * Note that fields 6 and 10 should add to field 2, 7 and 11 + * should add to 3, etc. + * + * - Lines for reads that are filtered out for any reason (e.g. too + * many Ns) have columns 2 through 13 set to 0. + */ +template +void AlnSink::appendSeedSummary( + BTString& o, + const Read& rd, + const TReadId rdid, + size_t seedsTried, + size_t nonzero, + size_t ranges, + size_t elts, + size_t seedsTriedFw, + size_t nonzeroFw, + size_t rangesFw, + size_t eltsFw, + size_t seedsTriedRc, + size_t nonzeroRc, + size_t rangesRc, + size_t eltsRc) +{ + char buf[1024]; + bool firstfield = true; + // + // Read name + // + BEGIN_FIELD; + printUptoWs(o, rd.name, true); + + // + // Total number of seeds tried + // + BEGIN_FIELD; + WRITE_NUM(o, seedsTried); + + // + // Total number of seeds tried where at least one range was found. + // + BEGIN_FIELD; + WRITE_NUM(o, nonzero); + + // + // Total number of ranges found + // + BEGIN_FIELD; + WRITE_NUM(o, ranges); + + // + // Total number of elements found + // + BEGIN_FIELD; + WRITE_NUM(o, elts); + + // + // The same four numbers, but only for seeds extracted from the + // forward read representation. + // + BEGIN_FIELD; + WRITE_NUM(o, seedsTriedFw); + + BEGIN_FIELD; + WRITE_NUM(o, nonzeroFw); + + BEGIN_FIELD; + WRITE_NUM(o, rangesFw); + + BEGIN_FIELD; + WRITE_NUM(o, eltsFw); + + // + // The same four numbers, but only for seeds extracted from the + // reverse complement read representation. + // + BEGIN_FIELD; + WRITE_NUM(o, seedsTriedRc); + + BEGIN_FIELD; + WRITE_NUM(o, nonzeroRc); + + BEGIN_FIELD; + WRITE_NUM(o, rangesRc); + + BEGIN_FIELD; + WRITE_NUM(o, eltsRc); + + o.append('\n'); +} + +/** + * Append a single hit to the given output stream in Bowtie's + * verbose-mode format. + */ +template +void AlnSinkSam::appendMate( + BTString& o, // append to this string + StackedAln& staln, // store stacked alignment struct here + const Read& rd, + const Read* rdo, + const TReadId rdid, + AlnRes* rs, + AlnRes* rso, + const AlnSetSumm& summ, + const SeedAlSumm& ssm, + const SeedAlSumm& ssmo, + const AlnFlags& flags, + const PerReadMetrics& prm, + const Mapq& mapqCalc, + const Scoring& sc) +{ + if(rs == NULL && samc_.omitUnalignedReads()) { + return; + } + char buf[1024]; + char mapqInps[1024]; + if(rs != NULL) { + staln.reset(); + rs->initStacked(rd, staln); + staln.leftAlign(false /* not past MMs */); + } + int offAdj = 0; + // QNAME + samc_.printReadName(o, rd.name, flags.partOfPair()); + o.append('\t'); + // FLAG + int fl = 0; + if(flags.partOfPair()) { + fl |= SAM_FLAG_PAIRED; + if(flags.alignedConcordant()) { + fl |= SAM_FLAG_MAPPED_PAIRED; + } + if(!flags.mateAligned()) { + // Other fragment is unmapped + fl |= SAM_FLAG_MATE_UNMAPPED; + } + fl |= (flags.readMate1() ? + SAM_FLAG_FIRST_IN_PAIR : SAM_FLAG_SECOND_IN_PAIR); + if(flags.mateAligned() && rso != NULL) { + if(!rso->fw()) { + fl |= SAM_FLAG_MATE_STRAND; + } + } + } + if(!flags.isPrimary()) { + fl |= SAM_FLAG_NOT_PRIMARY; + } + if(rs != NULL && !rs->fw()) { + fl |= SAM_FLAG_QUERY_STRAND; + } + if(rs == NULL) { + // Failed to align + fl |= SAM_FLAG_UNMAPPED; + } + itoa10(fl, buf); + o.append(buf); + o.append('\t'); + // RNAME + if(rs != NULL) { + samc_.printRefNameFromIndex(o, (size_t)rs->refid(), rs->repeat()); + o.append('\t'); + } else { + if(summ.orefid() != -1) { + // Opposite mate aligned but this one didn't - print the opposite + // mate's RNAME and POS as is customary + assert(flags.partOfPair()); + samc_.printRefNameFromIndex(o, (size_t)summ.orefid(), summ.repeat()); + } else { + // No alignment + o.append('*'); + } + o.append('\t'); + } + // POS + // Note: POS is *after* soft clipping. I.e. POS points to the + // upstream-most character *involved in the clipped alignment*. + if(rs != NULL) { + itoa10(rs->refoff()+1+offAdj, buf); + o.append(buf); + o.append('\t'); + } else { + if(summ.orefid() != -1) { + // Opposite mate aligned but this one didn't - print the opposite + // mate's RNAME and POS as is customary + assert(flags.partOfPair()); + itoa10(summ.orefoff()+1+offAdj, buf); + o.append(buf); + } else { + // No alignment + o.append('0'); + } + o.append('\t'); + } + // MAPQ + mapqInps[0] = '\0'; + if(rs != NULL) { + itoa10(mapqCalc.mapq( + summ, flags, rd.mate < 2, rd.length(), + rdo == NULL ? 0 : rdo->length(), mapqInps), buf); + o.append(buf); + o.append('\t'); + } else { + // No alignment + o.append("0\t"); + } + // CIGAR + if(rs != NULL) { + staln.buildCigar(false); + staln.writeCigar(&o, NULL); + o.append('\t'); + } else { + // No alignment + o.append("*\t"); + } + // RNEXT + if(rs != NULL && flags.partOfPair()) { + if(rso != NULL && (rs->refid() != rso->refid() || rs->repeat() != rso->repeat())) { + samc_.printRefNameFromIndex(o, (size_t)rso->refid(), rso->repeat()); + o.append('\t'); + } else { + o.append("=\t"); + } + } else if(summ.orefid() != -1) { + // The convention if this mate fails to align but the other doesn't is + // to copy the mate's details into here + o.append("=\t"); + } else { + o.append("*\t"); + } + // PNEXT + if(rs != NULL && flags.partOfPair()) { + if(rso != NULL) { + itoa10(rso->refoff()+1, buf); + o.append(buf); + o.append('\t'); + } else { + // The convenstion is that if this mate aligns but the opposite + // doesn't, we print this mate's offset here + itoa10(rs->refoff()+1, buf); + o.append(buf); + o.append('\t'); + } + } else if(summ.orefid() != -1) { + // The convention if this mate fails to align but the other doesn't is + // to copy the mate's details into here + itoa10(summ.orefoff()+1, buf); + o.append(buf); + o.append('\t'); + } else { + o.append("0\t"); + } + // ISIZE + if(rs != NULL && rs->isFraglenSet()) { + itoa10(rs->fragmentLength(), buf); + o.append(buf); + o.append('\t'); + } else { + // No fragment + o.append("0\t"); + } + // SEQ + if(!flags.isPrimary() && samc_.omitSecondarySeqQual()) { + o.append('*'); + } else { + // Print the read + if(rd.patFw.length() == 0) { + o.append('*'); + } else { + if(rs == NULL || rs->fw()) { + o.append(rd.patFw.toZBuf()); + } else { + o.append(rd.patRc.toZBuf()); + } + } + } + o.append('\t'); + // QUAL + if(!flags.isPrimary() && samc_.omitSecondarySeqQual()) { + o.append('*'); + } else { + // Print the quals + if(rd.qual.length() == 0) { + o.append('*'); + } else { + if(rs == NULL || rs->fw()) { + o.append(rd.qual.toZBuf()); + } else { + o.append(rd.qualRev.toZBuf()); + } + } + } + o.append('\t'); + // + // Optional fields + // + if(rs != NULL) { + samc_.printAlignedOptFlags( + o, // output buffer + true, // first opt flag printed is first overall? + rd, // read + *rs, // individual alignment result + staln, // stacked alignment + flags, // alignment flags + summ, // summary of alignments for this read + ssm, // seed alignment summary + prm, // per-read metrics + sc, // scoring scheme + mapqInps, // inputs to MAPQ calculation + this->altdb_); + } else { + samc_.printEmptyOptFlags( + o, // output buffer + true, // first opt flag printed is first overall? + rd, // read + flags, // alignment flags + summ, // summary of alignments for this read + ssm, // seed alignment summary + prm, // per-read metrics + sc); // scoring scheme + } + o.append('\n'); +} + +#endif /*ndef ALN_SINK_H_*/ diff --git a/alphabet.cpp b/alphabet.cpp new file mode 100644 index 0000000..cb63651 --- /dev/null +++ b/alphabet.cpp @@ -0,0 +1,536 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include +#include "alphabet.h" + +using namespace std; + +/** + * Mapping from ASCII characters to DNA categories: + * + * 0 = invalid - error + * 1 = DNA + * 2 = IUPAC (ambiguous DNA) + * 3 = not an error, but unmatchable; alignments containing this + * character are invalid + */ +uint8_t asc2dnacat[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + /* - */ + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0, 1, 2, 1, 2, 0, 0, 1, 2, 0, 0, 2, 0, 2, 2, 0, + /* A B C D G H K M N */ + /* 80 */ 0, 0, 2, 2, 1, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, + /* R S T V W X Y */ + /* 96 */ 0, 1, 2, 1, 2, 0, 0, 1, 2, 0, 0, 2, 0, 2, 2, 0, + /* a b c d g h k m n */ + /* 112 */ 0, 0, 2, 2, 1, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, + /* r s t v w x y */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// 5-bit pop count +int mask2popcnt[] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5 +}; + +/** + * Mapping from masks to ASCII characters for ambiguous nucleotides. + */ +char mask2dna[] = { + '?', // 0 + 'A', // 1 + 'C', // 2 + 'M', // 3 + 'G', // 4 + 'R', // 5 + 'S', // 6 + 'V', // 7 + 'T', // 8 + 'W', // 9 + 'Y', // 10 + 'H', // 11 + 'K', // 12 + 'D', // 13 + 'B', // 14 + 'N', // 15 (inclusive N) + 'N' // 16 (exclusive N) +}; + +/** + * Mapping from ASCII characters for ambiguous nucleotides into masks: + */ +uint8_t asc2dnamask[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0, 1,14, 2,13, 0, 0, 4,11, 0, 0,12, 0, 3,15, 0, + /* A B C D G H K M N */ + /* 80 */ 0, 0, 5, 6, 8, 0, 7, 9, 0,10, 0, 0, 0, 0, 0, 0, + /* R S T V W Y */ + /* 96 */ 0, 1,14, 2,13, 0, 0, 4,11, 0, 0,12, 0, 3,15, 0, + /* a b c d g h k m n */ + /* 112 */ 0, 0, 5, 6, 8, 0, 7, 9, 0,10, 0, 0, 0, 0, 0, 0, + /* r s t v w y */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/** + * Convert a pair of DNA masks to a color mask + * + * + */ +uint8_t dnamasks2colormask[16][16] = { + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */ + /* 0 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 1 */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + /* 2 */ { 0, 2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15 }, + /* 3 */ { 0, 3, 3, 3, 12, 15, 15, 15, 12, 15, 15, 15, 12, 15, 15, 15 }, + /* 4 */ { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 }, + /* 5 */ { 0, 5, 10, 15, 5, 5, 15, 15, 10, 15, 10, 15, 15, 15, 15, 15 }, + /* 6 */ { 0, 6, 9, 15, 9, 15, 9, 15, 6, 6, 15, 15, 15, 15, 15, 15 }, + /* 7 */ { 0, 7, 11, 15, 13, 15, 15, 15, 14, 15, 15, 15, 15, 15, 15, 15 }, + /* 8 */ { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }, + /* 9 */ { 0, 9, 6, 15, 6, 15, 6, 15, 9, 9, 15, 15, 15, 15, 15, 15 }, + /* 10 */ { 0, 10, 5, 15, 10, 10, 15, 15, 5, 15, 5, 15, 15, 15, 15, 15 }, + /* 11 */ { 0, 11, 7, 15, 14, 15, 15, 15, 13, 15, 15, 15, 15, 15, 15, 15 }, + /* 12 */ { 0, 12, 12, 12, 3, 15, 15, 15, 3, 15, 15, 15, 3, 15, 15, 15 }, + /* 13 */ { 0, 13, 14, 15, 7, 15, 15, 15, 11, 15, 15, 15, 15, 15, 15, 15 }, + /* 14 */ { 0, 14, 13, 15, 11, 15, 15, 15, 7, 15, 15, 15, 15, 15, 15, 15 }, + /* 15 */ { 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 } +}; + +/** + * Mapping from ASCII characters for ambiguous nucleotides into masks: + */ +char asc2dnacomp[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'-', 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0,'T','V','G','H', 0, 0,'C','D', 0, 0,'M', 0,'K','N', 0, + /* A B C D G H K M N */ + /* 80 */ 0, 0,'Y','S','A', 0,'B','W', 0,'R', 0, 0, 0, 0, 0, 0, + /* R S T V W Y */ + /* 96 */ 0,'T','V','G','H', 0, 0,'C','D', 0, 0,'M', 0,'K','N', 0, + /* a b c d g h k m n */ + /* 112 */ 0, 0,'Y','S','A', 0,'B','W', 0,'R', 0, 0, 0, 0, 0, 0, + /* r s t v w y */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** + * Mapping from ASCII characters for ambiguous nucleotides into masks: + */ +char col2dna[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'-','N', 0, + /* - . */ + /* 48 */'A','C','G','T','N', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0 1 2 3 4 */ + /* 64 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 96 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 112 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** + * Mapping from ASCII characters for ambiguous nucleotides into masks: + */ +char dna2col[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'-', 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0,'0', 0,'1', 0, 0, 0,'2', 0, 0, 0, 0, 0, 0,'4', 0, + /* A C G N */ + /* 80 */ 0, 0, 0, 0,'3', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* T */ + /* 92 */ 0,'0', 0,'1', 0, 0, 0,'2', 0, 0, 0, 0, 0, 0,'4', 0, + /* a c g n */ + /* 112 */ 0, 0, 0, 0,'3', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* t */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** + * Mapping from ASCII characters for ambiguous nucleotides into masks: + */ +const char* dna2colstr[] = { + /* 0 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 16 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 32 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "-", "?", "?", + /* 48 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 64 */ "?", "0","1|2|3","1","0|2|3","?", "?", "2","0|1|3","?", "?", "2|3", "?", "0|1", ".", "?", + /* A B C D G H K M N */ + /* 80 */ "?", "?", "0|2","1|2", "3", "?","0|1|2","0|3","?", "1|3", "?", "?", "?", "?", "?", "?", + /* R S T V W Y */ + /* 92 */ "?", "?","1|2|3","1","0|2|3","?", "?", "2","0|1|3","?", "?", "2|3", "?", "0|1", ".", "?", + /* a b c d g h k m n */ + /* 112 */ "?", "0", "0|2","1|2", "3", "?","0|1|2","0|3","?", "1|3", "?", "?", "?", "?", "?", "?", + /* r s t v w y */ + /* 128 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 144 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 160 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 176 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 192 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 208 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 224 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + /* 240 */ "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?" +}; + +/** + * Mapping from ASCII characters to color categories: + * + * 0 = invalid - error + * 1 = valid color + * 2 = IUPAC (ambiguous DNA) - there is no such thing for colors to my + * knowledge + * 3 = not an error, but unmatchable; alignments containing this + * character are invalid + */ +uint8_t asc2colcat[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, + /* - . */ + /* 48 */ 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0 1 2 3 4 */ + /* 64 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 96 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 112 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/** + * Set the category for all IUPAC codes. By default they're in + * category 2 (IUPAC), but sometimes we'd like to put them in category + * 3 (unmatchable), for example. + */ +void setIupacsCat(uint8_t cat) { + assert(cat < 4); + asc2dnacat[(int)'B'] = asc2dnacat[(int)'b'] = + asc2dnacat[(int)'D'] = asc2dnacat[(int)'d'] = + asc2dnacat[(int)'H'] = asc2dnacat[(int)'h'] = + asc2dnacat[(int)'K'] = asc2dnacat[(int)'k'] = + asc2dnacat[(int)'M'] = asc2dnacat[(int)'m'] = + asc2dnacat[(int)'N'] = asc2dnacat[(int)'n'] = + asc2dnacat[(int)'R'] = asc2dnacat[(int)'r'] = + asc2dnacat[(int)'S'] = asc2dnacat[(int)'s'] = + asc2dnacat[(int)'V'] = asc2dnacat[(int)'v'] = + asc2dnacat[(int)'W'] = asc2dnacat[(int)'w'] = + asc2dnacat[(int)'X'] = asc2dnacat[(int)'x'] = + asc2dnacat[(int)'Y'] = asc2dnacat[(int)'y'] = cat; +} + +/// For converting from ASCII to the Dna5 code where A=0, C=1, G=2, +/// T=3, N=4 + + +uint8_t asc2dna[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* A C G N */ + /* 80 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* T */ + /* 96 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* a c g n */ + /* 112 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* t */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +uint8_t asc2dna_3N[2][256] = { + { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* A C G N */ + /* 80 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* T */ + /* 96 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* a c g n */ + /* 112 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* t */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* A C G N */ + /* 80 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* T */ + /* 96 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* a c g n */ + /* 112 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* t */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } +}; + +// this is only used in BASE_CHANGE case +uint8_t asc2dna_1[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* A C G N */ + /* 80 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* T */ + /* 96 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* a c g n */ + /* 112 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* t */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +uint8_t asc2dna_2[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* A C G N */ + /* 80 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* T */ + /* 96 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* a c g n */ + /* 112 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* t */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/// Convert an ascii char representing a base or a color to a 2-bit +/// code: 0=A,0; 1=C,1; 2=G,2; 3=T,3; 4=N,. +uint8_t asc2dnaOrCol[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, + /* - . */ + /* 48 */ 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0 1 2 3 */ + /* 64 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* A C G N */ + /* 80 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* T */ + /* 96 */ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, + /* a c g n */ + /* 112 */ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* t */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/// For converting from ASCII to the Dna5 code where A=0, C=1, G=2, +/// T=3, N=4 +uint8_t asc2col[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, + /* - . */ + /* 48 */ 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0 1 2 3 */ + /* 64 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 96 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 112 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/** + * Convert a nucleotide and a color to the paired nucleotide. Indexed + * first by nucleotide then by color. Note that this is exactly the + * same as the dinuc2color array. + */ +uint8_t nuccol2nuc[5][5] = { + /* B G O R . */ + /* A */ {0, 1, 2, 3, 4}, + /* C */ {1, 0, 3, 2, 4}, + /* G */ {2, 3, 0, 1, 4}, + /* T */ {3, 2, 1, 0, 4}, + /* N */ {4, 4, 4, 4, 4} +}; + +/** + * Convert a pair of nucleotides to a color. + */ +uint8_t dinuc2color[5][5] = { + /* A */ {0, 1, 2, 3, 4}, + /* C */ {1, 0, 3, 2, 4}, + /* G */ {2, 3, 0, 1, 4}, + /* T */ {3, 2, 1, 0, 4}, + /* N */ {4, 4, 4, 4, 4} +}; + +/// Convert bit encoded DNA char to its complement +int dnacomp[5] = { + 3, 2, 1, 0, 4 +}; + +const char *iupacs = "!ACMGRSVTWYHKDBN!acmgrsvtwyhkdbn"; + +char mask2iupac[16] = { + -1, + 'A', // 0001 + 'C', // 0010 + 'M', // 0011 + 'G', // 0100 + 'R', // 0101 + 'S', // 0110 + 'V', // 0111 + 'T', // 1000 + 'W', // 1001 + 'Y', // 1010 + 'H', // 1011 + 'K', // 1100 + 'D', // 1101 + 'B', // 1110 + 'N', // 1111 +}; + +int maskcomp[16] = { + 0, // 0000 (!) -> 0000 (!) + 8, // 0001 (A) -> 1000 (T) + 4, // 0010 (C) -> 0100 (G) + 12, // 0011 (M) -> 1100 (K) + 2, // 0100 (G) -> 0010 (C) + 10, // 0101 (R) -> 1010 (Y) + 6, // 0110 (S) -> 0110 (S) + 14, // 0111 (V) -> 1110 (B) + 1, // 1000 (T) -> 0001 (A) + 9, // 1001 (W) -> 1001 (W) + 5, // 1010 (Y) -> 0101 (R) + 13, // 1011 (H) -> 1101 (D) + 3, // 1100 (K) -> 0011 (M) + 11, // 1101 (D) -> 1011 (H) + 7, // 1110 (B) -> 0111 (V) + 15, // 1111 (N) -> 1111 (N) +}; + diff --git a/alphabet.h b/alphabet.h new file mode 100644 index 0000000..340942e --- /dev/null +++ b/alphabet.h @@ -0,0 +1,199 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ALPHABETS_H_ +#define ALPHABETS_H_ + +#include +#include +#include +#include +#include "assert_helpers.h" + +using namespace std; + +/// Convert an ascii char to a DNA category. Categories are: +/// 0 -> invalid +/// 1 -> unambiguous a, c, g or t +/// 2 -> ambiguous +/// 3 -> unmatchable +extern uint8_t asc2dnacat[]; +/// Convert masks to ambiguous nucleotides +extern char mask2dna[]; +/// Convert ambiguous ASCII nuceleotide to mask +extern uint8_t asc2dnamask[]; +/// Convert mask to # of alternative in the mask +extern int mask2popcnt[]; +/// Convert an ascii char to a 2-bit base: 0=A, 1=C, 2=G, 3=T, 4=N +extern uint8_t asc2dna[]; +/// Convert an ascii char representing a base or a color to a 2-bit +/// code: 0=A,0; 1=C,1; 2=G,2; 3=T,3; 4=N,. +extern uint8_t asc2dnaOrCol[]; +/// Convert a pair of DNA masks to a color mask +extern uint8_t dnamasks2colormask[16][16]; + +/// Convert an ascii char to a color category. Categories are: +/// 0 -> invalid +/// 1 -> unambiguous 0, 1, 2 or 3 +/// 2 -> ambiguous (not applicable for colors) +/// 3 -> unmatchable +extern uint8_t asc2colcat[]; +/// Convert an ascii char to a 2-bit base: 0=A, 1=C, 2=G, 3=T, 4=N +extern uint8_t asc2col[]; +/// Convert an ascii char to its DNA complement, including IUPACs +extern char asc2dnacomp[]; + +/// Convert a pair of 2-bit (and 4=N) encoded DNA bases to a color +extern uint8_t dinuc2color[5][5]; +/// Convert a 2-bit nucleotide (and 4=N) and a color to the +/// corresponding 2-bit nucleotide +extern uint8_t nuccol2nuc[5][5]; +/// Convert a 4-bit mask into an IUPAC code +extern char mask2iupac[16]; + +/// Convert an ascii color to an ascii dna char +extern char col2dna[]; +/// Convert an ascii dna to a color char +extern char dna2col[]; +/// Convert an ascii dna to a color char +extern const char* dna2colstr[]; + +/// Convert bit encoded DNA char to its complement +extern int dnacomp[5]; + +/// String of all DNA and IUPAC characters +extern const char *iupacs; + +/// Map from masks to their reverse-complement masks +extern int maskcomp[16]; + +/** + * Return true iff c is a Dna character. + */ +static inline bool isDna(char c) { + return asc2dnacat[(int)c] > 0; +} + +/** + * Return true iff c is a color character. + */ +static inline bool isColor(char c) { + return asc2colcat[(int)c] > 0; +} + +/** + * Return true iff c is an ambiguous Dna character. + */ +static inline bool isAmbigNuc(char c) { + return asc2dnacat[(int)c] == 2; +} + +/** + * Return true iff c is an ambiguous color character. + */ +static inline bool isAmbigColor(char c) { + return asc2colcat[(int)c] == 2; +} + +/** + * Return true iff c is an ambiguous character. + */ +static inline bool isAmbig(char c, bool color) { + return (color ? asc2colcat[(int)c] : asc2dnacat[(int)c]) == 2; +} + +/** + * Return true iff c is an unambiguous DNA character. + */ +static inline bool isUnambigNuc(char c) { + return asc2dnacat[(int)c] == 1; +} + +/** + * Return the DNA complement of the given ASCII char. + */ +static inline char comp(char c) { + switch(c) { + case 'a': return 't'; + case 'A': return 'T'; + case 'c': return 'g'; + case 'C': return 'G'; + case 'g': return 'c'; + case 'G': return 'C'; + case 't': return 'a'; + case 'T': return 'A'; + default: return c; + } +} + +/** + * Return the reverse complement of a bit-encoded nucleotide. + */ +static inline int compDna(int c) { + assert_leq(c, 4); + return dnacomp[c]; +} + +/** + * Return true iff c is an unambiguous Dna character. + */ +static inline bool isUnambigDna(char c) { + return asc2dnacat[(int)c] == 1; +} + +/** + * Return true iff c is an unambiguous color character (0,1,2,3). + */ +static inline bool isUnambigColor(char c) { + return asc2colcat[(int)c] == 1; +} + +/// Convert a pair of 2-bit (and 4=N) encoded DNA bases to a color +extern uint8_t dinuc2color[5][5]; + +/** + * Decode a not-necessarily-ambiguous nucleotide. + */ +static inline void decodeNuc(char c , int& num, int *alts) { + switch(c) { + case 'A': alts[0] = 0; num = 1; break; + case 'C': alts[0] = 1; num = 1; break; + case 'G': alts[0] = 2; num = 1; break; + case 'T': alts[0] = 3; num = 1; break; + case 'M': alts[0] = 0; alts[1] = 1; num = 2; break; + case 'R': alts[0] = 0; alts[1] = 2; num = 2; break; + case 'W': alts[0] = 0; alts[1] = 3; num = 2; break; + case 'S': alts[0] = 1; alts[1] = 2; num = 2; break; + case 'Y': alts[0] = 1; alts[1] = 3; num = 2; break; + case 'K': alts[0] = 2; alts[1] = 3; num = 2; break; + case 'V': alts[0] = 0; alts[1] = 1; alts[2] = 2; num = 3; break; + case 'H': alts[0] = 0; alts[1] = 1; alts[2] = 3; num = 3; break; + case 'D': alts[0] = 0; alts[1] = 2; alts[2] = 3; num = 3; break; + case 'B': alts[0] = 1; alts[1] = 2; alts[2] = 3; num = 3; break; + case 'N': alts[0] = 0; alts[1] = 1; alts[2] = 2; alts[3] = 3; num = 4; break; + default: { + std::cerr << "Bad IUPAC code: " << c << ", (int: " << (int)c << ")" << std::endl; + throw std::runtime_error(""); + } + } +} + +extern void setIupacsCat(uint8_t cat); + +#endif /*ALPHABETS_H_*/ diff --git a/alt.h b/alt.h new file mode 100644 index 0000000..fa820a7 --- /dev/null +++ b/alt.h @@ -0,0 +1,294 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef ALT_H_ +#define ALT_H_ + +#include +#include +#include +#include "assert_helpers.h" +#include "word_io.h" +#include "mem_ids.h" + +using namespace std; + +enum ALT_TYPE { + ALT_NONE = 0, + ALT_SNP_SGL, // single nucleotide substitution + ALT_SNP_INS, // small insertion wrt reference genome + ALT_SNP_DEL, // small deletion wrt reference genome + ALT_SNP_ALT, // alternative sequence (to be implemented ...) + ALT_SPLICESITE, + ALT_EXON +}; + +template +struct ALT { + ALT() { + reset(); + } + + void reset() { + type = ALT_NONE; + pos = len = 0; + seq = 0; + } + + ALT_TYPE type; + + union { + index_t pos; + index_t left; + }; + + union { + index_t len; + index_t right; + }; + + union { + uint64_t seq; // used to store 32 bp, but it can be used to store a pointer to EList + struct { + union { + bool fw; + bool reversed; + }; + bool excluded; + }; + }; + +public: + // in order to support a sequence longer than 32 bp + + bool snp() const { return type == ALT_SNP_SGL || type == ALT_SNP_DEL || type == ALT_SNP_INS; } + bool splicesite() const { return type == ALT_SPLICESITE; } + bool mismatch() const { return type == ALT_SNP_SGL; } + bool gap() const { return type == ALT_SNP_DEL || type == ALT_SNP_INS || type == ALT_SPLICESITE; } + bool deletion() const { return type == ALT_SNP_DEL; } + bool insertion() const { return type == ALT_SNP_INS; } + bool exon() const { return type == ALT_EXON; } + + bool operator< (const ALT& o) const { + if(pos != o.pos) return pos < o.pos; + if(type != o.type) { + if(type == ALT_NONE || o.type == ALT_NONE) { + return type == ALT_NONE; + } + if(type == ALT_SNP_INS) return true; + else if(o.type == ALT_SNP_INS) return false; + return type < o.type; + } + if(len != o.len) return len < o.len; + if(seq != o.seq) return seq < o.seq; + return false; + } + + bool compatibleWith(const ALT& o) const { + if(pos == o.pos) return false; + + // sort the two SNPs + const ALT& a = (pos < o.pos ? *this : o); + const ALT& b = (pos < o.pos ? o : *this); + + if(a.snp()) { + if(a.type == ALT_SNP_DEL || a.type == ALT_SNP_INS) { + if(b.pos <= a.pos + a.len) { + return false; + } + } + } else if(a.splicesite()) { + if(b.pos <= a.right + 2) { + return false; + } + } else { + assert(false); + } + + return true; + } + + bool isSame(const ALT& o) const { + if(type != o.type) + return false; + if(type == ALT_SNP_SGL) { + return pos == o.pos && seq == o.seq; + } else if(type == ALT_SNP_DEL || type == ALT_SNP_INS || type == ALT_SPLICESITE) { + if(type == ALT_SNP_INS) { + if(seq != o.seq) + return false; + } + if(reversed == o.reversed) { + return pos == o.pos && len == o.len; + } else { + if(reversed) { + return pos - len + 1 == o.pos && len == o.len; + } else { + return pos == o.pos - o.len + 1 && len == o.len; + } + } + } else { + assert(false); + } + return true; + } + +#ifndef NDEBUG + bool repOk() const { + if(type == ALT_SNP_SGL) { + if(len != 1) { + assert(false); + return false; + } + + if(seq > 3) { + assert(false); + return false; + } + } else if(type == ALT_SNP_DEL) { + if(len <= 0) { + assert(false); + return false; + } + if(seq != 0) { + assert(false); + return false; + } + } else if(type == ALT_SNP_INS) { + if(len <= 0) { + assert(false); + return false; + } + } else if(type == ALT_SPLICESITE) { + assert_lt(left, right); + assert_leq(fw, 1); + }else { + assert(false); + return false; + } + return true; + } +#endif + + bool write(ofstream& f_out, bool bigEndian) const { + writeIndex(f_out, pos, bigEndian); + writeU32(f_out, type, bigEndian); + writeIndex(f_out, len, bigEndian); + writeIndex(f_out, seq, bigEndian); + return true; + } + + bool read(ifstream& f_in, bool bigEndian) { + pos = readIndex(f_in, bigEndian); + type = (ALT_TYPE)readU32(f_in, bigEndian); + assert_neq(type, ALT_SNP_ALT); + len = readIndex(f_in, bigEndian); + seq = readIndex(f_in, bigEndian); + return true; + } +}; + + +template +struct Haplotype { + Haplotype() { + reset(); + } + + void reset() { + left = right = 0; + alts.clear(); + } + + index_t left; + index_t right; + EList alts; + + bool operator< (const Haplotype& o) const { + if(left != o.left) return left < o.left; + if(right != o.right) return right < o.right; + return false; + } + + bool write(ofstream& f_out, bool bigEndian) const { + writeIndex(f_out, left, bigEndian); + writeIndex(f_out, right, bigEndian); + writeIndex(f_out, alts.size(), bigEndian); + for(index_t i = 0; i < alts.size(); i++) { + writeIndex(f_out, alts[i], bigEndian); + } + return true; + } + + bool read(ifstream& f_in, bool bigEndian) { + left = readIndex(f_in, bigEndian); + right = readIndex(f_in, bigEndian); + assert_leq(left, right); + index_t num_alts = readIndex(f_in, bigEndian); + alts.resizeExact(num_alts); alts.clear(); + for(index_t i = 0; i < num_alts; i++) { + alts.push_back(readIndex(f_in, bigEndian)); + } + return true; + } +}; + + +template +class ALTDB { +public: + ALTDB() : + _snp(false), + _ss(false), + _exon(false) + {} + + virtual ~ALTDB() {} + + bool hasSNPs() const { return _snp; } + bool hasSpliceSites() const { return _ss; } + bool hasExons() const { return _exon; } + + void setSNPs(bool snp) { _snp = snp; } + void setSpliceSites(bool ss) { _ss = ss; } + void setExons(bool exon) { _exon = exon; } + + EList >& alts() { return _alts; } + EList& altnames() { return _altnames; } + EList >& haplotypes() { return _haplotypes; } + EList& haplotype_maxrights() { return _haplotype_maxrights; } + + const EList >& alts() const { return _alts; } + const EList& altnames() const { return _altnames; } + const EList >& haplotypes() const { return _haplotypes; } + const EList& haplotype_maxrights() const { return _haplotype_maxrights; } + +private: + bool _snp; + bool _ss; + bool _exon; + + EList > _alts; + EList _altnames; + EList > _haplotypes; + EList _haplotype_maxrights; +}; + + +#endif /*ifndef ALT_H_*/ diff --git a/assert_helpers.h b/assert_helpers.h new file mode 100644 index 0000000..688181a --- /dev/null +++ b/assert_helpers.h @@ -0,0 +1,279 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ASSERT_HELPERS_H_ +#define ASSERT_HELPERS_H_ + +#include +#include +#include +#include + +/** + * Assertion for release-enabled assertions + */ +class ReleaseAssertException : public std::runtime_error { +public: + ReleaseAssertException(const std::string& msg = "") : std::runtime_error(msg) {} +}; + +/** + * Macros for release-enabled assertions, and helper macros to make + * all assertion error messages more helpful. + */ +#ifndef NDEBUG +#define ASSERT_ONLY(...) __VA_ARGS__ +#else +#define ASSERT_ONLY(...) +#endif + +#define rt_assert(b) \ + if(!(b)) { \ + std::cout << "rt_assert at " << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(); \ + } +#define rt_assert_msg(b,msg) \ + if(!(b)) { \ + std::cout << msg << " at " << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(msg); \ + } + +#define rt_assert_eq(ex,ac) \ + if(!((ex) == (ac))) { \ + std::cout << "rt_assert_eq: expected (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(); \ + } +#define rt_assert_eq_msg(ex,ac,msg) \ + if(!((ex) == (ac))) { \ + std::cout << "rt_assert_eq: " << msg << ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(msg); \ + } + +#ifndef NDEBUG +#define assert_eq(ex,ac) \ + if(!((ex) == (ac))) { \ + std::cout << "assert_eq: expected (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#define assert_eq_msg(ex,ac,msg) \ + if(!((ex) == (ac))) { \ + std::cout << "assert_eq: " << msg << ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#else +#define assert_eq(ex,ac) +#define assert_eq_msg(ex,ac,msg) +#endif + +#define rt_assert_neq(ex,ac) \ + if(!((ex) != (ac))) { \ + std::cout << "rt_assert_neq: expected not (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(); \ + } +#define rt_assert_neq_msg(ex,ac,msg) \ + if(!((ex) != (ac))) { \ + std::cout << "rt_assert_neq: " << msg << ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(msg); \ + } + +#ifndef NDEBUG +#define assert_neq(ex,ac) \ + if(!((ex) != (ac))) { \ + std::cout << "assert_neq: expected not (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#define assert_neq_msg(ex,ac,msg) \ + if(!((ex) != (ac))) { \ + std::cout << "assert_neq: " << msg << ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#else +#define assert_neq(ex,ac) +#define assert_neq_msg(ex,ac,msg) +#endif + +#define rt_assert_gt(a,b) \ + if(!((a) > (b))) { \ + std::cout << "rt_assert_gt: expected (" << (a) << ") > (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(); \ + } +#define rt_assert_gt_msg(a,b,msg) \ + if(!((a) > (b))) { \ + std::cout << "rt_assert_gt: " << msg << ": (" << (a) << ") > (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(msg); \ + } + +#ifndef NDEBUG +#define assert_gt(a,b) \ + if(!((a) > (b))) { \ + std::cout << "assert_gt: expected (" << (a) << ") > (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#define assert_gt_msg(a,b,msg) \ + if(!((a) > (b))) { \ + std::cout << "assert_gt: " << msg << ": (" << (a) << ") > (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#else +#define assert_gt(a,b) +#define assert_gt_msg(a,b,msg) +#endif + +#define rt_assert_geq(a,b) \ + if(!((a) >= (b))) { \ + std::cout << "rt_assert_geq: expected (" << (a) << ") >= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(); \ + } +#define rt_assert_geq_msg(a,b,msg) \ + if(!((a) >= (b))) { \ + std::cout << "rt_assert_geq: " << msg << ": (" << (a) << ") >= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(msg); \ + } + +#ifndef NDEBUG +#define assert_geq(a,b) \ + if(!((a) >= (b))) { \ + std::cout << "assert_geq: expected (" << (a) << ") >= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#define assert_geq_msg(a,b,msg) \ + if(!((a) >= (b))) { \ + std::cout << "assert_geq: " << msg << ": (" << (a) << ") >= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#else +#define assert_geq(a,b) +#define assert_geq_msg(a,b,msg) +#endif + +#define rt_assert_lt(a,b) \ + if(!(a < b)) { \ + std::cout << "rt_assert_lt: expected (" << a << ") < (" << b << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(); \ + } +#define rt_assert_lt_msg(a,b,msg) \ + if(!(a < b)) { \ + std::cout << "rt_assert_lt: " << msg << ": (" << a << ") < (" << b << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(msg); \ + } + +#ifndef NDEBUG +#define assert_lt(a,b) \ + if(!(a < b)) { \ + std::cout << "assert_lt: expected (" << a << ") < (" << b << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#define assert_lt_msg(a,b,msg) \ + if(!(a < b)) { \ + std::cout << "assert_lt: " << msg << ": (" << a << ") < (" << b << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#else +#define assert_lt(a,b) +#define assert_lt_msg(a,b,msg) +#endif + +#define rt_assert_leq(a,b) \ + if(!((a) <= (b))) { \ + std::cout << "rt_assert_leq: expected (" << (a) << ") <= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(); \ + } +#define rt_assert_leq_msg(a,b,msg) \ + if(!((a) <= (b))) { \ + std::cout << "rt_assert_leq: " << msg << ": (" << (a) << ") <= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + throw ReleaseAssertException(msg); \ + } + +#ifndef NDEBUG +#define assert_leq(a,b) \ + if(!((a) <= (b))) { \ + std::cout << "assert_leq: expected (" << (a) << ") <= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#define assert_leq_msg(a,b,msg) \ + if(!((a) <= (b))) { \ + std::cout << "assert_leq: " << msg << ": (" << (a) << ") <= (" << (b) << ")" << std::endl; \ + std::cout << __FILE__ << ":" << __LINE__ << std::endl; \ + assert(0); \ + } +#else +#define assert_leq(a,b) +#define assert_leq_msg(a,b,msg) +#endif + +#ifndef NDEBUG +#define assert_in(c, s) assert_in2(c, s, __FILE__, __LINE__) +static inline void assert_in2(char c, const char *str, const char *file, int line) { + const char *s = str; + while(*s != '\0') { + if(c == *s) return; + s++; + } + std::cout << "assert_in: (" << c << ") not in (" << str << ")" << std::endl; + std::cout << file << ":" << line << std::endl; + assert(0); +} +#else +#define assert_in(c, s) +#endif + +#ifndef NDEBUG +#define assert_range(b, e, v) assert_range_helper(b, e, v, __FILE__, __LINE__) +template +inline static void assert_range_helper(const T& begin, + const T& end, + const T& val, + const char *file, + int line) +{ + if(val < begin || val > end) { + std::cout << "assert_range: (" << val << ") not in [" + << begin << ", " << end << "]" << std::endl; + std::cout << file << ":" << line << std::endl; + assert(0); + } +} +#else +#define assert_range(b, e, v) +#endif + +#endif /*ASSERT_HELPERS_H_*/ diff --git a/banded.cpp b/banded.cpp new file mode 100644 index 0000000..e88f7ca --- /dev/null +++ b/banded.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "banded.h" + +#ifdef MAIN_BANDED +int main(void) { + +} +#endif diff --git a/banded.h b/banded.h new file mode 100644 index 0000000..37978bc --- /dev/null +++ b/banded.h @@ -0,0 +1,52 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef BANDED_H_ +#define BANDED_H_ + +#include "sse_util.h" + +/** + * Use SSE instructions to quickly find stretches with lots of matches, then + * resolve alignments. + */ +class BandedSseAligner { + +public: + + void init( + int *q, // query, maskized + size_t qi, // query start + size_t qf, // query end + int *r, // reference, maskized + size_t ri, // reference start + size_t rf) // reference end + { + + } + + void nextAlignment() { + } + +protected: + + EList_m128i mat_; +}; + +#endif diff --git a/binary_sa_search.h b/binary_sa_search.h new file mode 100644 index 0000000..4bb6eb7 --- /dev/null +++ b/binary_sa_search.h @@ -0,0 +1,102 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef BINARY_SA_SEARCH_H_ +#define BINARY_SA_SEARCH_H_ + +#include +#include +#include +#include "alphabet.h" +#include "assert_helpers.h" +#include "ds.h" +#include "btypes.h" + +/** + * Do a binary search using the suffix of 'host' beginning at offset + * 'qry' as the query and 'sa' as an already-lexicographically-sorted + * list of suffixes of host. 'sa' may be all suffixes of host or just + * a subset. Returns the index in sa of the smallest suffix of host + * that is larger than qry, or length(sa) if all suffixes of host are + * less than qry. + * + * We use the Manber and Myers optimization of maintaining a pair of + * counters for the longest lcp observed so far on the left- and right- + * hand sides and using the min of the two as a way of skipping over + * characters at the beginning of a new round. + * + * Returns maximum value if the query suffix matches an element of sa. + */ +template inline +TIndexOffU binarySASearch( + const TStr& host, + TIndexOffU qry, + const EList& sa) +{ + TIndexOffU lLcp = 0, rLcp = 0; // greatest observed LCPs on left and right + TIndexOffU l = 0, r = (TIndexOffU)sa.size()+1; // binary-search window + TIndexOffU hostLen = (TIndexOffU)host.length(); + while(true) { + assert_gt(r, l); + TIndexOffU m = (l+r) >> 1; + if(m == l) { + // Binary-search window has closed: we have an answer + if(m > 0 && sa[m-1] == qry) { + return std::numeric_limits::max(); // qry matches + } + assert_leq(m, sa.size()); + return m; // Return index of right-hand suffix + } + assert_gt(m, 0); + TIndexOffU suf = sa[m-1]; + if(suf == qry) { + return std::numeric_limits::max(); // query matches an elt of sa + } + TIndexOffU lcp = min(lLcp, rLcp); +#ifndef NDEBUG + if(sstr_suf_upto_neq(host, qry, host, suf, lcp)) { + assert(0); + } +#endif + // Keep advancing lcp, but stop when query mismatches host or + // when the counter falls off either the query or the suffix + while(suf+lcp < hostLen && qry+lcp < hostLen && host[suf+lcp] == host[qry+lcp]) { + lcp++; + } + // Fell off the end of either the query or the sa elt? + bool fell = (suf+lcp == hostLen || qry+lcp == hostLen); + if((fell && qry+lcp == hostLen) || (!fell && host[suf+lcp] < host[qry+lcp])) { + // Query is greater than sa elt + l = m; // update left bound + lLcp = max(lLcp, lcp); // update left lcp + } + else if((fell && suf+lcp == hostLen) || (!fell && host[suf+lcp] > host[qry+lcp])) { + // Query is less than sa elt + r = m; // update right bound + rLcp = max(rLcp, lcp); // update right lcp + } else { + assert(false); // Must be one or the other! + } + } + // Shouldn't get here + assert(false); + return std::numeric_limits::max(); +} + +#endif /*BINARY_SA_SEARCH_H_*/ diff --git a/bit_packed_array.cpp b/bit_packed_array.cpp new file mode 100644 index 0000000..c1be08f --- /dev/null +++ b/bit_packed_array.cpp @@ -0,0 +1,315 @@ +/* +* Copyright 2018, Chanhee Park and Daehwan Kim +* +* This file is part of HISAT 2. +* +* HISAT 2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* HISAT 2 is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with HISAT 2. If not, see . +*/ + +#include +#include +#include +#include "timer.h" +#include "aligner_sw.h" +#include "aligner_result.h" +#include "scoring.h" +#include "sstring.h" + +#include "bit_packed_array.h" + +TIndexOffU BitPackedArray::get(size_t index) const +{ + assert_lt(index, cur_); + + pair addr = indexToAddress(index); + uint64_t *block = blocks_[addr.first]; + pair pos = columnToPosition(addr.second); + TIndexOffU val = getItem(block, pos.first, pos.second); + + return val; +} + + +#define write_fp(x) fp.write((const char *)&(x), sizeof((x))) + +void BitPackedArray::writeFile(ofstream &fp) +{ + size_t sz = 0; + + write_fp(item_bit_size_); + write_fp(elm_bit_size_); + write_fp(items_per_block_bit_); + write_fp(items_per_block_bit_mask_); + write_fp(items_per_block_); + + write_fp(cur_); + write_fp(sz_); + + write_fp(block_size_); + + // number of blocks + sz = blocks_.size(); + write_fp(sz); + for(size_t i = 0; i < sz; i++) { + fp.write((const char *)blocks_[i], block_size_); + } +} + +void BitPackedArray::writeFile(const char *filename) +{ + ofstream fp(filename, std::ofstream::binary); + writeFile(fp); + fp.close(); +} + +void BitPackedArray::writeFile(const string &filename) +{ + writeFile(filename.c_str()); +} + + +#define read_fp(x) fp.read((char *)&(x), sizeof((x))) + +void BitPackedArray::readFile(ifstream &fp) +{ + size_t val_sz = 0; + + read_fp(val_sz); + init_by_log2(val_sz); + //rt_assert_eq(val_sz, item_bit_size_); + + read_fp(val_sz); + rt_assert_eq(val_sz, elm_bit_size_); + + read_fp(val_sz); + rt_assert_eq(val_sz, items_per_block_bit_); + + read_fp(val_sz); + rt_assert_eq(val_sz, items_per_block_bit_mask_); + + read_fp(val_sz); + rt_assert_eq(val_sz, items_per_block_); + + // skip cur_ + size_t prev_cnt = 0; + read_fp(prev_cnt); + cur_ = 0; + + // skip sz_ + size_t prev_sz = 0; + read_fp(prev_sz); + sz_ = 0; + + // block_size_ + read_fp(val_sz); + rt_assert_eq(val_sz, block_size_); + + // alloc blocks + allocItems(prev_cnt); + rt_assert_eq(prev_sz, sz_); + + // number of blocks + read_fp(val_sz); + rt_assert_eq(val_sz, blocks_.size()); + for(size_t i = 0; i < blocks_.size(); i++) { + fp.read((char *)blocks_[i], block_size_); + } + cur_ = prev_cnt; +} + +void BitPackedArray::readFile(const char *filename) +{ + ifstream fp(filename, std::ifstream::binary); + readFile(fp); + fp.close(); +} + +void BitPackedArray::readFile(const string &filename) +{ + readFile(filename.c_str()); +} + +void BitPackedArray::put(size_t index, TIndexOffU val) +{ + assert_lt(index, cur_); + + pair addr = indexToAddress(index); + uint64_t *block = blocks_[addr.first]; + pair pos = columnToPosition(addr.second); + + setItem(block, pos.first, pos.second, val); +} + +void BitPackedArray::pushBack(TIndexOffU val) +{ + if(cur_ == sz_) { + allocItems(items_per_block_); + } + + put(cur_++, val); + + assert_leq(cur_, sz_); +} + +TIndexOffU BitPackedArray::getItem(uint64_t *block, size_t idx, size_t offset) const +{ + size_t remains = item_bit_size_; + + TIndexOffU val = 0; + + while(remains > 0) { + size_t bits = min(elm_bit_size_ - offset, remains); + uint64_t mask = bitToMask(bits); + + // get value from block + TIndexOffU t = (block[idx] >> offset) & mask; + val = val | (t << (item_bit_size_ - remains)); + + remains -= bits; + offset = 0; + idx++; + } + + return val; +} + +void BitPackedArray::setItem(uint64_t *block, size_t idx, size_t offset, TIndexOffU val) +{ + size_t remains = item_bit_size_; + + while(remains > 0) { + size_t bits = min(elm_bit_size_ - offset, remains); + uint64_t mask = bitToMask(bits); + uint64_t dest_mask = mask << offset; + + // get 'bits' lsb from val + uint64_t t = val & mask; + val >>= bits; + + // save 't' to block[idx] + t <<= offset; + block[idx] &= ~(dest_mask); // clear + block[idx] |= t; + + idx++; + remains -= bits; + offset = 0; + } +} + +pair BitPackedArray::indexToAddress(size_t index) const +{ + pair addr; + + addr.first = index >> items_per_block_bit_; + addr.second = index & items_per_block_bit_mask_; + + return addr; +} + +pair BitPackedArray::columnToPosition(size_t col) const { + pair pos; + + pos.first = (col * item_bit_size_) / elm_bit_size_; + pos.second = (col * item_bit_size_) % elm_bit_size_; + return pos; +} + +void BitPackedArray::expand(size_t count) +{ + if((cur_ + count) > sz_) { + allocItems(count); + } + + cur_ += count; + + assert_leq(cur_, sz_); +} + +void BitPackedArray::allocSize(size_t sz) +{ + size_t num_block = (sz * sizeof(uint64_t) + block_size_ - 1) / block_size_; + + for(size_t i = 0; i < num_block; i++) { + uint64_t *ptr = new uint64_t[block_size_]; + blocks_.push_back(ptr); + sz_ += items_per_block_; + } +} + +void BitPackedArray::allocItems(size_t count) +{ + size_t sz = (count * item_bit_size_ + elm_bit_size_ - 1) / elm_bit_size_; + allocSize(sz); +} + +void BitPackedArray::init_by_log2(size_t ceil_log2) +{ + item_bit_size_ = ceil_log2; + + elm_bit_size_ = sizeof(uint64_t) * 8; + + items_per_block_bit_ = 20; // 1M + items_per_block_ = 1ULL << (items_per_block_bit_); + items_per_block_bit_mask_ = items_per_block_ - 1; + + block_size_ = (items_per_block_ * item_bit_size_ + elm_bit_size_ - 1) / elm_bit_size_ * sizeof(uint64_t); + + cur_ = 0; + sz_ = 0; +} + +void BitPackedArray::init(size_t max_value) +{ + init_by_log2((size_t)ceil(log2(max_value))); +} + +void BitPackedArray::dump() const +{ + cerr << "item_bit_size_: " << item_bit_size_ << endl; + cerr << "block_size_: " << block_size_ << endl; + cerr << "items_per_block_: " << items_per_block_ << endl; + cerr << "cur_: " << cur_ << endl; + cerr << "sz_: " << sz_ << endl; + cerr << "number of blocks: " << blocks_.size() << endl; +} + +size_t BitPackedArray::getMemUsage() const +{ + size_t tot = blocks_.size() * block_size_; + tot += blocks_.totalCapacityBytes(); + return tot; +} + +BitPackedArray::~BitPackedArray() +{ + for(size_t i = 0; i < blocks_.size(); i++) { + uint64_t *ptr = blocks_[i]; + delete [] ptr; + } +} + +void BitPackedArray::reset() +{ + cur_ = 0; + sz_ = 0; + + for(size_t i = 0; i < blocks_.size(); i++) { + uint64_t *ptr = blocks_[i]; + delete [] ptr; + } + + blocks_.clear(); +} + diff --git a/bit_packed_array.h b/bit_packed_array.h new file mode 100644 index 0000000..8350428 --- /dev/null +++ b/bit_packed_array.h @@ -0,0 +1,105 @@ +/* +* Copyright 2018, Chanhee Park and Daehwan Kim +* +* This file is part of HISAT 2. +* +* HISAT 2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* HISAT 2 is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with HISAT 2. If not, see . +*/ + +#ifndef __HISAT2_BIT_PACKED_ARRAY_H +#define __HISAT2_BIT_PACKED_ARRAY_H + +#include +#include +#include +#include +#include "assert_helpers.h" +#include "word_io.h" +#include "mem_ids.h" +#include "ds.h" + +using namespace std; + +class BitPackedArray { +public: + BitPackedArray () {} + ~BitPackedArray(); + + /** + * Return true iff there are no items + * @return + */ + inline bool empty() const { return cur_ == 0; } + inline size_t size() const { return cur_; } + + TIndexOffU get(size_t idx) const; + + inline TIndexOffU operator[](size_t i) const { return get(i); } + void pushBack(TIndexOffU val); + + void init(size_t max_value); + void reset(); + + void writeFile(const char *filename); + void writeFile(const string& filename); + void writeFile(ofstream &fp); + + void readFile(const char *filename); + void readFile(const string& filename); + void readFile(ifstream &fp); + + void dump() const; + + size_t getMemUsage() const; + +private: + void init_by_log2(size_t ceil_log2); + + void put(size_t index, TIndexOffU val); + inline uint64_t bitToMask(size_t bit) const + { + return (uint64_t) ((1ULL << bit) - 1); + } + + TIndexOffU getItem(uint64_t *block, size_t idx, size_t offset) const; + void setItem(uint64_t *block, size_t idx, size_t offset, TIndexOffU val); + + pair indexToAddress(size_t index) const; + pair columnToPosition(size_t col) const; + + + void expand(size_t count = 1); + void allocSize(size_t sz); + void allocItems(size_t count); + + +private: + size_t item_bit_size_; // item bit size(e.g. 33bit) + + size_t elm_bit_size_; // 64bit + size_t items_per_block_bit_; + size_t items_per_block_bit_mask_; + size_t items_per_block_; // number of items in block + + size_t cur_; // current item count + size_t sz_; // maximum item count + + size_t block_size_; // block size in byte + + // List of packed array + EList blocks_; +}; + + +#endif //__HISAT2_BIT_PACKED_ARRAY_H diff --git a/bitpack.h b/bitpack.h new file mode 100644 index 0000000..1504265 --- /dev/null +++ b/bitpack.h @@ -0,0 +1,80 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef BITPACK_H_ +#define BITPACK_H_ + +#include +#include "assert_helpers.h" + +/** + * Routines for marshalling 2-bit values into and out of 8-bit or + * 32-bit hosts + */ + +static inline void pack_2b_in_8b(const int two, uint8_t& eight, const int off) { + assert_lt(two, 4); + assert_lt(off, 4); + eight |= (two << (off*2)); +} + +static inline int unpack_2b_from_8b(const uint8_t eight, const int off) { + assert_lt(off, 4); + return ((eight >> (off*2)) & 0x3); +} + +static inline void pack_2b_in_32b(const int two, uint32_t& thirty2, const int off) { + assert_lt(two, 4); + assert_lt(off, 16); + thirty2 |= (two << (off*2)); +} + +static inline int unpack_2b_from_32b(const uint32_t thirty2, const int off) { + assert_lt(off, 16); + return ((thirty2 >> (off*2)) & 0x3); +} + +/** + * Routines for marshalling 1-bit values into and out of 8-bit or + * 32-bit hosts + */ + +static inline void pack_1b_in_8b(const int one, uint8_t& eight, const int off) { + assert_lt(one, 2); + assert_lt(off, 8); + eight |= (one << off); +} + +static inline int unpack_1b_from_8b(const uint8_t eight, const int off) { + assert_lt(off, 2); + return ((eight >> off) & 0x1); +} + +static inline void pack_1b_in_32b(const int one, uint32_t& thirty2, const int off) { + assert_lt(one, 2); + assert_lt(off, 32); + thirty2 |= (one << off); +} + +static inline int unpack_1b_from_32b(const uint32_t thirty2, const int off) { + assert_lt(off, 32); + return ((thirty2 >> off) & 0x1); +} + +#endif /*BITPACK_H_*/ diff --git a/blockwise_sa.h b/blockwise_sa.h new file mode 100644 index 0000000..22d8749 --- /dev/null +++ b/blockwise_sa.h @@ -0,0 +1,1113 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef BLOCKWISE_SA_H_ +#define BLOCKWISE_SA_H_ + +#include +#include +#include +#include +#include +#include "assert_helpers.h" +#include "diff_sample.h" +#include "multikey_qsort.h" +#include "random_source.h" +#include "binary_sa_search.h" +#include "zbox.h" +#include "alphabet.h" +#include "timer.h" +#include "ds.h" +#include "mem_ids.h" +#include "word_io.h" + +using namespace std; + +// Helpers for printing verbose messages + +#ifndef VMSG_NL +#define VMSG_NL(...) \ +if(this->verbose()) { \ + stringstream tmp; \ + tmp << __VA_ARGS__ << endl; \ + this->verbose(tmp.str()); \ +} +#endif + +#ifndef VMSG +#define VMSG(...) \ +if(this->verbose()) { \ + stringstream tmp; \ + tmp << __VA_ARGS__; \ + this->verbose(tmp.str()); \ +} +#endif + +/** + * Abstract parent class for blockwise suffix-array building schemes. + */ +template +class BlockwiseSA { +public: + BlockwiseSA(const TStr& __text, + TIndexOffU __bucketSz, + bool __sanityCheck = false, + bool __passMemExc = false, + bool __verbose = false, + ostream& __logger = cout) : + _text(__text), + _bucketSz(max(__bucketSz, 2u)), + _sanityCheck(__sanityCheck), + _passMemExc(__passMemExc), + _verbose(__verbose), + _itrBucket(EBWTB_CAT), + _itrBucketPos(OFF_MASK), + _itrPushedBackSuffix(OFF_MASK), + _logger(__logger) + { } + + virtual ~BlockwiseSA() { } + + /** + * Get the next suffix; compute the next bucket if necessary. + */ + virtual TIndexOffU nextSuffix() = 0; + + /** + * Return true iff the next call to nextSuffix will succeed. + */ + bool hasMoreSuffixes() { + if(_itrPushedBackSuffix != OFF_MASK) return true; + try { + _itrPushedBackSuffix = nextSuffix(); + } catch(out_of_range& e) { + assert_eq(OFF_MASK, _itrPushedBackSuffix); + return false; + } + return true; + } + + /** + * Reset the suffix iterator so that the next call to nextSuffix() + * returns the lexicographically-first suffix. + */ + void resetSuffixItr() { + _itrBucket.clear(); + _itrBucketPos = OFF_MASK; + _itrPushedBackSuffix = OFF_MASK; + reset(); + assert(suffixItrIsReset()); + } + + /** + * Returns true iff the next call to nextSuffix() returns the + * lexicographically-first suffix. + */ + bool suffixItrIsReset() { + return _itrBucket.size() == 0 && + _itrBucketPos == OFF_MASK && + _itrPushedBackSuffix == OFF_MASK && + isReset(); + } + + const TStr& text() const { return _text; } + TIndexOffU bucketSz() const { return _bucketSz; } + bool sanityCheck() const { return _sanityCheck; } + bool verbose() const { return _verbose; } + ostream& log() const { return _logger; } + size_t size() const { return _text.length()+1; } + +protected: + /// Reset back to the first block + virtual void reset() = 0; + /// Return true iff reset to the first block + virtual bool isReset() = 0; + + /** + * Grab the next block of sorted suffixes. The block is guaranteed + * to have at most _bucketSz elements. + */ + virtual void nextBlock(int cur_block, int tid = 0) = 0; + /// Return true iff more blocks are available + virtual bool hasMoreBlocks() const = 0; + /// Optionally output a verbose message + void verbose(const string& s) const { + if(this->verbose()) { + this->log() << s.c_str(); + this->log().flush(); + } + } + + const TStr& _text; /// original string + const TIndexOffU _bucketSz; /// target maximum bucket size + const bool _sanityCheck; /// whether to perform sanity checks + const bool _passMemExc; /// true -> pass on memory exceptions + const bool _verbose; /// be talkative + EList _itrBucket; /// current bucket + TIndexOffU _itrBucketPos;/// offset into current bucket + TIndexOffU _itrPushedBackSuffix; /// temporary slot for lookahead + ostream& _logger; /// write log messages here +}; + +/** + * Abstract parent class for a blockwise suffix array builder that + * always doles out blocks in lexicographical order. + */ +template +class InorderBlockwiseSA : public BlockwiseSA { +public: + InorderBlockwiseSA(const TStr& __text, + TIndexOffU __bucketSz, + bool __sanityCheck = false, + bool __passMemExc = false, + bool __verbose = false, + ostream& __logger = cout) : + BlockwiseSA(__text, __bucketSz, __sanityCheck, __passMemExc, __verbose, __logger) + { } +}; + +/** + * Build the SA a block at a time according to the scheme outlined in + * Karkkainen's "Fast BWT" paper. + */ +template +class KarkkainenBlockwiseSA : public InorderBlockwiseSA { +public: + typedef DifferenceCoverSample TDC; + + KarkkainenBlockwiseSA(const TStr& __text, + TIndexOffU __bucketSz, + int __nthreads, + uint32_t __dcV, + uint32_t __seed = 0, + bool __sanityCheck = false, + bool __passMemExc = false, + bool __verbose = false, + string base_fname = "", + ostream& __logger = cout) : + InorderBlockwiseSA(__text, __bucketSz, __sanityCheck, __passMemExc, __verbose, __logger), + _sampleSuffs(EBWTB_CAT), _nthreads(__nthreads), _itrBucketIdx(0), _cur(0), _dcV(__dcV), _dc(EBWTB_CAT), _built(false), _base_fname(base_fname), _bigEndian(currentlyBigEndian()) + { _randomSrc.init(__seed); reset(); } + + ~KarkkainenBlockwiseSA() + { + if(_threads.size() > 0) { + for (size_t tid = 0; tid < _threads.size(); tid++) { + _threads[tid]->join(); + delete _threads[tid]; + } + } + } + + + /** + * Allocate an amount of memory that simulates the peak memory + * usage of the DifferenceCoverSample with the given text and v. + * Throws bad_alloc if it's not going to fit in memory. Returns + * the approximate number of bytes the Cover takes at all times. + */ + static size_t simulateAllocs(const TStr& text, TIndexOffU bucketSz) { + size_t len = text.length(); + // _sampleSuffs and _itrBucket are in memory at the peak + size_t bsz = bucketSz; + size_t sssz = len / max(bucketSz-1, 1); + AutoArray tmp(bsz + sssz + (1024 * 1024 /*out of caution*/), EBWT_CAT); + return bsz; + } + + static void nextBlock_Worker(void *vp) { + pair param = *(pair*)vp; + KarkkainenBlockwiseSA* sa = param.first; + int tid = param.second; + while(true) { + size_t cur = 0; + { + ThreadSafe ts(&sa->_mutex, sa->_nthreads > 1); + cur = sa->_cur; + if(cur > sa->_sampleSuffs.size()) break; + sa->_cur++; + } + sa->nextBlock((int)cur, tid); + // Write suffixes into a file + std::ostringstream number; number << cur; + const string fname = sa->_base_fname + "." + number.str() + ".sa"; + ofstream sa_file(fname.c_str(), ios::binary); + if(!sa_file.good()) { + cerr << "Could not open file for writing a bucket: \"" << fname << "\"" << endl; + throw 1; + } + const EList& bucket = sa->_itrBuckets[tid]; + writeIndex(sa_file, (TIndexOffU)bucket.size(), sa->_bigEndian); + for(size_t i = 0; i < bucket.size(); i++) { + writeIndex(sa_file, bucket[i], sa->_bigEndian); + } + sa_file.close(); + sa->_itrBuckets[tid].clear(); + sa->_done[cur] = true; + } + } + + /** + * Get the next suffix; compute the next bucket if necessary. + */ + virtual TIndexOffU nextSuffix() { + // Launch threads if not + if(this->_nthreads > 1) { + if(_threads.size() == 0) { + _done.resize(_sampleSuffs.size() + 1); + _done.fill(false); + _itrBuckets.resize(this->_nthreads); + for(int tid = 0; tid < this->_nthreads; tid++) { + _tparams.expand(); + _tparams.back().first = this; + _tparams.back().second = tid; + _threads.push_back(new tthread::thread(nextBlock_Worker, (void*)&_tparams.back())); + } + assert_eq(_threads.size(), (size_t)this->_nthreads); + } + } + if(this->_itrPushedBackSuffix != OFF_MASK) { + TIndexOffU tmp = this->_itrPushedBackSuffix; + this->_itrPushedBackSuffix = OFF_MASK; + return tmp; + } + while(this->_itrBucketPos >= this->_itrBucket.size() || + this->_itrBucket.size() == 0) + { + if(!hasMoreBlocks()) { + throw out_of_range("No more suffixes"); + } + if(this->_nthreads == 1) { + nextBlock((int)_cur); + _cur++; + } else { + while(!_done[this->_itrBucketIdx]) { +#if defined(_TTHREAD_WIN32_) + Sleep(1); +#elif defined(_TTHREAD_POSIX_) + const static timespec ts = {0, 1000000}; // 1 millisecond + nanosleep(&ts, NULL); +#endif + } + // Read suffixes from a file + std::ostringstream number; number << this->_itrBucketIdx; + const string fname = _base_fname + "." + number.str() + ".sa"; + ifstream sa_file(fname.c_str(), ios::binary); + if(!sa_file.good()) { + cerr << "Could not open file for reading a bucket: \"" << fname << "\"" << endl; + throw 1; + } + size_t numSAs = readIndex(sa_file, _bigEndian); + this->_itrBucket.resizeExact(numSAs); + for(size_t i = 0; i < numSAs; i++) { + this->_itrBucket[i] = readIndex(sa_file, _bigEndian); + } + sa_file.close(); + std::remove(fname.c_str()); + } + this->_itrBucketIdx++; + this->_itrBucketPos = 0; + } + return this->_itrBucket[this->_itrBucketPos++]; + } + + /// Defined in blockwise_sa.cpp + virtual void nextBlock(int cur_block, int tid = 0); + + /// Defined in blockwise_sa.cpp + virtual void qsort(EList& bucket); + + /// Return true iff more blocks are available + virtual bool hasMoreBlocks() const { + return this->_itrBucketIdx <= _sampleSuffs.size(); + } + + /// Return the difference-cover period + uint32_t dcV() const { return _dcV; } + +protected: + + /** + * Initialize the state of the blockwise suffix sort. If the + * difference cover sample and the sample set have not yet been + * built, build them. Then reset the block cursor to point to + * the first block. + */ + virtual void reset() { + if(!_built) { + build(); + } + assert(_built); + _cur = 0; + } + + /// Return true iff we're about to dole out the first bucket + virtual bool isReset() { + return _cur == 0; + } + +private: + + /** + * Calculate the difference-cover sample and sample suffixes. + */ + void build() { + // Calculate difference-cover sample + assert(_dc.get() == NULL); + if(_dcV != 0) { + _dc.init(new TDC(this->text(), _dcV, this->verbose(), this->sanityCheck())); + _dc.get()->build(this->_nthreads); + } + // Calculate sample suffixes + if(this->bucketSz() <= this->text().length()) { + VMSG_NL("Building samples"); + buildSamples(); + } else { + VMSG_NL("Skipping building samples since text length " << + this->text().length() << " is less than bucket size: " << + this->bucketSz()); + } + _built = true; + } + + /** + * Calculate the lcp between two suffixes using the difference + * cover as a tie-breaker. If the tie-breaker is employed, then + * the calculated lcp may be an underestimate. + * + * Defined in blockwise_sa.cpp + */ + inline bool tieBreakingLcp(TIndexOffU aOff, + TIndexOffU bOff, + TIndexOffU& lcp, + bool& lcpIsSoft); + + /** + * Compare two suffixes using the difference-cover sample. + */ + inline bool suffixCmp(TIndexOffU cmp, + TIndexOffU i, + int64_t& j, + int64_t& k, + bool& kSoft, + const EList& z); + + void buildSamples(); + + EList _sampleSuffs; /// sample suffixes + int _nthreads; /// # of threads + TIndexOffU _itrBucketIdx; + TIndexOffU _cur; /// offset to 1st elt of next block + const uint32_t _dcV; /// difference-cover periodicity + PtrWrap _dc; /// queryable difference-cover data + bool _built; /// whether samples/DC have been built + RandomSource _randomSrc; /// source of pseudo-randoms + + MUTEX_T _mutex; /// synchronization of output message + string _base_fname; /// base file name for storing SA blocks + bool _bigEndian; /// bigEndian? + EList _threads; /// thread list + EList > _tparams; + ELList _itrBuckets; /// buckets + EList _done; /// is a block processed? +}; + +/** + * Qsort the set of suffixes whose offsets are in 'bucket'. + */ +template +inline void KarkkainenBlockwiseSA::qsort(EList& bucket) { + const TStr& t = this->text(); + TIndexOffU *s = bucket.ptr(); + size_t slen = bucket.size(); + TIndexOffU len = (TIndexOffU)t.length(); + if(_dc.get() != NULL) { + // Use the difference cover as a tie-breaker if we have it + VMSG_NL(" (Using difference cover)"); + // Extract the 'host' array because it's faster to work + // with than the EList<> container + const uint8_t *host = (const uint8_t *)t.buf(); + assert(_dc.get() != NULL); + mkeyQSortSufDcU8(t, host, len, s, slen, *_dc.get(), 4, + this->verbose(), this->sanityCheck()); + } else { + VMSG_NL(" (Not using difference cover)"); + // We don't have a difference cover - just do a normal + // suffix sort + mkeyQSortSuf(t, s, slen, 4, + this->verbose(), this->sanityCheck()); + } +} + +/** + * Qsort the set of suffixes whose offsets are in 'bucket'. This + * specialization for packed strings does not attempt to extract and + * operate directly on the host string; the fact that the string is + * packed means that the array cannot be sorted directly. + */ +template<> +inline void KarkkainenBlockwiseSA::qsort( + EList& bucket) +{ + const S2bDnaString& t = this->text(); + TIndexOffU *s = bucket.ptr(); + size_t slen = bucket.size(); + size_t len = t.length(); + if(_dc.get() != NULL) { + // Use the difference cover as a tie-breaker if we have it + VMSG_NL(" (Using difference cover)"); + // Can't use the text's 'host' array because the backing + // store for the packed string is not one-char-per-elt. + mkeyQSortSufDcU8(t, t, len, s, slen, *_dc.get(), 4, + this->verbose(), this->sanityCheck()); + } else { + VMSG_NL(" (Not using difference cover)"); + // We don't have a difference cover - just do a normal + // suffix sort + mkeyQSortSuf(t, s, slen, 4, + this->verbose(), this->sanityCheck()); + } +} + +template +struct BinarySortingParam { + const TStr* t; + const EList* sampleSuffs; + EList bucketSzs; + EList bucketReps; + size_t begin; + size_t end; +}; + +template +static void BinarySorting_worker(void *vp) +{ + BinarySortingParam* param = (BinarySortingParam*)vp; + const TStr& t = *(param->t); + size_t len = t.length(); + const EList& sampleSuffs = *(param->sampleSuffs); + EList& bucketSzs = param->bucketSzs; + EList& bucketReps = param->bucketReps; + ASSERT_ONLY(size_t numBuckets = bucketSzs.size()); + size_t begin = param->begin; + size_t end = param->end; + // Iterate through every suffix in the text, determine which + // bucket it falls into by doing a binary search across the + // sorted list of samples, and increment a counter associated + // with that bucket. Also, keep one representative for each + // bucket so that we can split it later. We loop in ten + // stretches so that we can print out a helpful progress + // message. (This step can take a long time.) + for(TIndexOffU i = (TIndexOffU)begin; i < end && i < len; i++) { + TIndexOffU r = binarySASearch(t, i, sampleSuffs); + if(r == std::numeric_limits::max()) continue; // r was one of the samples + assert_lt(r, numBuckets); + bucketSzs[r]++; + assert_lt(bucketSzs[r], len); + if(bucketReps[r] == OFF_MASK || (i & 100) == 0) { + bucketReps[r] = i; // clobbers previous one, but that's OK + } + } +} + +/** + * Select a set of bucket-delineating sample suffixes such that no + * bucket is greater than the requested upper limit. Some care is + * taken to make each bucket's size close to the limit without + * going over. + */ +template +void KarkkainenBlockwiseSA::buildSamples() { + const TStr& t = this->text(); + TIndexOffU bsz = this->bucketSz()-1; // subtract 1 to leave room for sample + size_t len = this->text().length(); + // Prepare _sampleSuffs array + _sampleSuffs.clear(); + TIndexOffU numSamples = (TIndexOffU)((len/bsz)+1)<<1; // ~len/bsz x 2 + assert_gt(numSamples, 0); + VMSG_NL("Reserving space for " << numSamples << " sample suffixes"); + if(this->_passMemExc) { + _sampleSuffs.resizeExact(numSamples); + // Randomly generate samples. Allow duplicates for now. + VMSG_NL("Generating random suffixes"); + for(size_t i = 0; i < numSamples; i++) { +#ifdef BOWTIE_64BIT_INDEX + _sampleSuffs[i] = (TIndexOffU)(_randomSrc.nextU64() % len); +#else + _sampleSuffs[i] = (TIndexOffU)(_randomSrc.nextU32() % len); +#endif + } + } else { + try { + _sampleSuffs.resizeExact(numSamples); + // Randomly generate samples. Allow duplicates for now. + VMSG_NL("Generating random suffixes"); + for(size_t i = 0; i < numSamples; i++) { +#ifdef BOWTIE_64BIT_INDEX + _sampleSuffs[i] = (TIndexOffU)(_randomSrc.nextU64() % len); +#else + _sampleSuffs[i] = (TIndexOffU)(_randomSrc.nextU32() % len); +#endif + } + } catch(bad_alloc &e) { + if(this->_passMemExc) { + throw e; // rethrow immediately + } else { + cerr << "Could not allocate sample suffix container of " << (numSamples * OFF_SIZE) << " bytes." << endl + << "Please try using a smaller number of blocks by specifying a larger --bmax or" << endl + << "a smaller --bmaxdivn" << endl; + throw 1; + } + } + } + // Remove duplicates; very important to do this before the call to + // mkeyQSortSuf so that it doesn't try to calculate lexicographical + // relationships between very long, identical strings, which takes + // an extremely long time in general, and causes the stack to grow + // linearly with the size of the input + { + Timer timer(cout, "QSorting sample offsets, eliminating duplicates time: ", this->verbose()); + VMSG_NL("QSorting " << _sampleSuffs.size() << " sample offsets, eliminating duplicates"); + _sampleSuffs.sort(); + size_t sslen = _sampleSuffs.size(); + for(size_t i = 0; i < sslen-1; i++) { + if(_sampleSuffs[i] == _sampleSuffs[i+1]) { + _sampleSuffs.erase(i--); + sslen--; + } + } + } + // Multikey quicksort the samples + { + Timer timer(cout, " Multikey QSorting samples time: ", this->verbose()); + VMSG_NL("Multikey QSorting " << _sampleSuffs.size() << " samples"); + this->qsort(_sampleSuffs); + } + // Calculate bucket sizes + VMSG_NL("Calculating bucket sizes"); + int limit = 5; + // Iterate until all buckets are less than + while(--limit >= 0) { + TIndexOffU numBuckets = (TIndexOffU)_sampleSuffs.size()+1; + AutoArray threads(this->_nthreads); + EList > tparams; + for(int tid = 0; tid < this->_nthreads; tid++) { + // Calculate bucket sizes by doing a binary search for each + // suffix and noting where it lands + tparams.expand(); + try { + // Allocate and initialize containers for holding bucket + // sizes and representatives. + tparams.back().bucketSzs.resizeExact(numBuckets); + tparams.back().bucketReps.resizeExact(numBuckets); + tparams.back().bucketSzs.fillZero(); + tparams.back().bucketReps.fill(OFF_MASK); + } catch(bad_alloc &e) { + if(this->_passMemExc) { + throw e; // rethrow immediately + } else { + cerr << "Could not allocate sizes, representatives (" << ((numBuckets*8)>>10) << " KB) for blocks." << endl + << "Please try using a smaller number of blocks by specifying a larger --bmax or a" << endl + << "smaller --bmaxdivn." << endl; + throw 1; + } + } + tparams.back().t = &t; + tparams.back().sampleSuffs = &_sampleSuffs; + tparams.back().begin = (tid == 0 ? 0 : len / this->_nthreads * tid); + tparams.back().end = (tid + 1 == this->_nthreads ? len : len / this->_nthreads * (tid + 1)); + if(this->_nthreads == 1) { + BinarySorting_worker((void*)&tparams.back()); + } else { + threads[tid] = new tthread::thread(BinarySorting_worker, (void*)&tparams.back()); + } + } + + if(this->_nthreads > 1) { + for (int tid = 0; tid < this->_nthreads; tid++) { + threads[tid]->join(); + } + } + + EList& bucketSzs = tparams[0].bucketSzs; + EList& bucketReps = tparams[0].bucketReps; + for(int tid = 1; tid < this->_nthreads; tid++) { + for(size_t j = 0; j < numBuckets; j++) { + bucketSzs[j] += tparams[tid].bucketSzs[j]; + if(bucketReps[j] == OFF_MASK) { + bucketReps[j] = tparams[tid].bucketReps[j]; + } + } + } + // Check for large buckets and mergeable pairs of small buckets + // and split/merge as necessary + TIndexOff added = 0; + TIndexOff merged = 0; + assert_eq(bucketSzs.size(), numBuckets); + assert_eq(bucketReps.size(), numBuckets); + { + Timer timer(cout, " Splitting and merging time: ", this->verbose()); + VMSG_NL("Splitting and merging"); + for(TIndexOffU i = 0; i < numBuckets; i++) { + TIndexOffU mergedSz = bsz + 1; + assert(bucketSzs[(size_t)i] == 0 || bucketReps[(size_t)i] != OFF_MASK); + if(i < numBuckets-1) { + mergedSz = bucketSzs[(size_t)i] + bucketSzs[(size_t)i+1] + 1; + } + // Merge? + if(mergedSz <= bsz) { + bucketSzs[(size_t)i+1] += (bucketSzs[(size_t)i]+1); + // The following may look strange, but it's necessary + // to ensure that the merged bucket has a representative + bucketReps[(size_t)i+1] = _sampleSuffs[(size_t)i+added]; + _sampleSuffs.erase((size_t)i+added); + bucketSzs.erase((size_t)i); + bucketReps.erase((size_t)i); + i--; // might go to -1 but ++ will overflow back to 0 + numBuckets--; + merged++; + assert_eq(numBuckets, _sampleSuffs.size()+1-added); + assert_eq(numBuckets, bucketSzs.size()); + } + // Split? + else if(bucketSzs[(size_t)i] > bsz) { + // Add an additional sample from the bucketReps[] + // set accumulated in the binarySASearch loop; this + // effectively splits the bucket + _sampleSuffs.insert(bucketReps[(size_t)i], (TIndexOffU)(i + (added++))); + } + } + } + if(added == 0) { + //if(this->verbose()) { + // cout << "Final bucket sizes:" << endl; + // cout << " (begin): " << bucketSzs[0] << " (" << (int)(bsz - bucketSzs[0]) << ")" << endl; + // for(uint32_t i = 1; i < numBuckets; i++) { + // cout << " " << bucketSzs[i] << " (" << (int)(bsz - bucketSzs[i]) << ")" << endl; + // } + //} + break; + } + // Otherwise, continue until no more buckets need to be + // split + VMSG_NL("Split " << added << ", merged " << merged << "; iterating..."); + } + // Do *not* force a do-over + // if(limit == 0) { + // VMSG_NL("Iterated too many times; trying again..."); + // buildSamples(); + // } + VMSG_NL("Avg bucket size: " << ((double)(len-_sampleSuffs.size()) / (_sampleSuffs.size()+1)) << " (target: " << bsz << ")"); +} + +/** + * Do a simple LCP calculation on two strings. + */ +template inline +static TIndexOffU suffixLcp(const T& t, TIndexOffU aOff, TIndexOffU bOff) { + TIndexOffU c = 0; + size_t len = t.length(); + assert_leq(aOff, len); + assert_leq(bOff, len); + while(aOff + c < len && bOff + c < len && t[aOff + c] == t[bOff + c]) c++; + return c; +} + +/** + * Calculate the lcp between two suffixes using the difference + * cover as a tie-breaker. If the tie-breaker is employed, then + * the calculated lcp may be an underestimate. If the tie-breaker is + * employed, lcpIsSoft will be set to true (otherwise, false). + */ +template inline +bool KarkkainenBlockwiseSA::tieBreakingLcp(TIndexOffU aOff, + TIndexOffU bOff, + TIndexOffU& lcp, + bool& lcpIsSoft) +{ + const TStr& t = this->text(); + TIndexOffU c = 0; + TIndexOffU tlen = (TIndexOffU)t.length(); + assert_leq(aOff, tlen); + assert_leq(bOff, tlen); + assert(_dc.get() != NULL); + uint32_t dcDist = _dc.get()->tieBreakOff(aOff, bOff); + lcpIsSoft = false; // hard until proven soft + while(c < dcDist && // we haven't hit the tie breaker + c < tlen-aOff && // we haven't fallen off of LHS suffix + c < tlen-bOff && // we haven't fallen off of RHS suffix + t[aOff+c] == t[bOff+c]) // we haven't hit a mismatch + c++; + lcp = c; + if(c == tlen-aOff) { + // Fell off LHS (a), a is greater + return false; + } else if(c == tlen-bOff) { + // Fell off RHS (b), b is greater + return true; + } else if(c == dcDist) { + // Hit a tie-breaker element + lcpIsSoft = true; + assert_neq(dcDist, 0xffffffff); + return _dc.get()->breakTie(aOff+c, bOff+c) < 0; + } else { + assert_neq(t[aOff+c], t[bOff+c]); + return t[aOff+c] < t[bOff+c]; + } +} + +/** + * Lookup a suffix LCP in the given z array; if the element is not + * filled in then calculate it from scratch. + */ +template +static TIndexOffU lookupSuffixZ( + const T& t, + TIndexOffU zOff, + TIndexOffU off, + const EList& z) +{ + if(zOff < z.size()) { + TIndexOffU ret = z[zOff]; + assert_eq(ret, suffixLcp(t, off + zOff, off)); + return ret; + } + assert_leq(off + zOff, t.length()); + return suffixLcp(t, off + zOff, off); +} + +/** + * true -> i < cmp + * false -> i > cmp + */ +template inline +bool KarkkainenBlockwiseSA::suffixCmp( + TIndexOffU cmp, + TIndexOffU i, + int64_t& j, + int64_t& k, + bool& kSoft, + const EList& z) +{ + const TStr& t = this->text(); + TIndexOffU len = (TIndexOffU)t.length(); + // i is not covered by any previous match + TIndexOffU l; + if((int64_t)i > k) { + k = i; // so that i + lHi == kHi + l = 0; // erase any previous l + kSoft = false; + // To be extended + } + // i is covered by a previous match + else /* i <= k */ { + assert_gt((int64_t)i, j); + TIndexOffU zIdx = (TIndexOffU)(i-j); + assert_leq(zIdx, len-cmp); + if(zIdx < _dcV || _dc.get() == NULL) { + // Go as far as the Z-box says + l = lookupSuffixZ(t, zIdx, cmp, z); + if(i + l > len) { + l = len-i; + } + assert_leq(i + l, len); + // Possibly to be extended + } else { + // But we're past the point of no-more-Z-boxes + bool ret = tieBreakingLcp(i, cmp, l, kSoft); + // Sanity-check tie-breaker + if(this->sanityCheck()) { + if(ret) assert(sstr_suf_lt(t, i, t, cmp, false)); + else assert(sstr_suf_gt(t, i, t, cmp, false)); + } + j = i; + k = i + l; + if(this->sanityCheck()) { + if(kSoft) { assert_leq(l, suffixLcp(t, i, cmp)); } + else { assert_eq (l, suffixLcp(t, i, cmp)); } + } + return ret; + } + } + + // Z box extends exactly as far as previous match (or there + // is neither a Z box nor a previous match) + if((int64_t)(i + l) == k) { + // Extend + while(l < len-cmp && k < (int64_t)len && t[(size_t)(cmp+l)] == t[(size_t)k]) { + k++; l++; + } + j = i; // update furthest-extending LHS + kSoft = false; + assert_eq(l, suffixLcp(t, i, cmp)); + } + // Z box extends further than previous match + else if((int64_t)(i + l) > k) { + l = (TIndexOffU)(k - i); // point to just after previous match + j = i; // update furthest-extending LHS + if(kSoft) { + while(l < len-cmp && k < (int64_t)len && t[(size_t)(cmp+l)] == t[(size_t)k]) { + k++; l++; + } + kSoft = false; + assert_eq(l, suffixLcp(t, i, cmp)); + } else assert_eq(l, suffixLcp(t, i, cmp)); + } + + // Check that calculated lcp matches actual lcp + if(this->sanityCheck()) { + if(!kSoft) { + // l should exactly match lcp + assert_eq(l, suffixLcp(t, i, cmp)); + } else { + // l is an underestimate of LCP + assert_leq(l, suffixLcp(t, i, cmp)); + } + } + assert_leq(l+i, len); + assert_leq(l, len-cmp); + + // i and cmp should not be the same suffix + assert(l != len-cmp || i+l != len); + + // Now we're ready to do a comparison on the next char + if(l+i != len && ( + l == len-cmp || // departure from paper algorithm: + // falling off pattern implies + // pattern is *greater* in our case + t[i + l] < t[cmp + l])) + { + // Case 2: Text suffix is less than upper sample suffix +#ifndef NDEBUG + if(this->sanityCheck()) { + assert(sstr_suf_lt(t, i, t, cmp, false)); + } +#endif + return true; // suffix at i is less than suffix at cmp + } + else { + // Case 3: Text suffix is greater than upper sample suffix +#ifndef NDEBUG + if(this->sanityCheck()) { + assert(sstr_suf_gt(t, i, t, cmp, false)); + } +#endif + return false; // suffix at i is less than suffix at cmp + } +} + +/** + * Retrieve the next block. This is the most performance-critical part + * of the blockwise suffix sorting process. + */ +template +void KarkkainenBlockwiseSA::nextBlock(int cur_block, int tid) { +#ifndef NDEBUG + if(this->_nthreads > 1) { + assert_lt(tid, this->_itrBuckets.size()); + } +#endif + EList& bucket = (this->_nthreads > 1 ? this->_itrBuckets[tid] : this->_itrBucket); + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL("Getting block " << (cur_block+1) << " of " << _sampleSuffs.size()+1); + } + assert(_built); + assert_gt(_dcV, 3); + assert_leq(cur_block, _sampleSuffs.size()); + const TStr& t = this->text(); + TIndexOffU len = (TIndexOffU)t.length(); + // Set up the bucket + bucket.clear(); + TIndexOffU lo = OFF_MASK, hi = OFF_MASK; + if(_sampleSuffs.size() == 0) { + // Special case: if _sampleSuffs is 0, then multikey-quicksort + // everything + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL(" No samples; assembling all-inclusive block"); + } + assert_eq(0, cur_block); + try { + if(bucket.capacity() < this->bucketSz()) { + bucket.reserveExact(len+1); + } + bucket.resize(len); + for(TIndexOffU i = 0; i < len; i++) { + bucket[i] = i; + } + } catch(bad_alloc &e) { + if(this->_passMemExc) { + throw e; // rethrow immediately + } else { + cerr << "Could not allocate a master suffix-array block of " << ((len+1) * 4) << " bytes" << endl + << "Please try using a larger number of blocks by specifying a smaller --bmax or" << endl + << "a larger --bmaxdivn" << endl; + throw 1; + } + } + } else { + try { + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL(" Reserving size (" << this->bucketSz() << ") for bucket " << (cur_block+1)); + } + // BTL: Add a +100 fudge factor; there seem to be instances + // where a bucket ends up having one more elt than bucketSz() + if(bucket.size() < this->bucketSz()+100) { + bucket.reserveExact(this->bucketSz()+100); + } + } catch(bad_alloc &e) { + if(this->_passMemExc) { + throw e; // rethrow immediately + } else { + cerr << "Could not allocate a suffix-array block of " << ((this->bucketSz()+1) * 4) << " bytes" << endl; + cerr << "Please try using a larger number of blocks by specifying a smaller --bmax or" << endl + << "a larger --bmaxdivn" << endl; + throw 1; + } + } + // Select upper and lower bounds from _sampleSuffs[] and + // calculate the Z array up to the difference-cover periodicity + // for both. Be careful about first/last buckets. + EList zLo(EBWTB_CAT), zHi(EBWTB_CAT); + assert_geq(cur_block, 0); + assert_leq((size_t)cur_block, _sampleSuffs.size()); + bool first = (cur_block == 0); + bool last = ((size_t)cur_block == _sampleSuffs.size()); + try { + // Timer timer(cout, " Calculating Z arrays time: ", this->verbose()); + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL(" Calculating Z arrays for bucket " << (cur_block+1)); + } + if(!last) { + // Not the last bucket + assert_lt(cur_block, _sampleSuffs.size()); + hi = _sampleSuffs[cur_block]; + zHi.resizeExact(_dcV); + zHi.fillZero(); + assert_eq(zHi[0], 0); + calcZ(t, hi, zHi, this->verbose(), this->sanityCheck()); + } + if(!first) { + // Not the first bucket + assert_gt(cur_block, 0); + assert_leq(cur_block, _sampleSuffs.size()); + lo = _sampleSuffs[cur_block-1]; + zLo.resizeExact(_dcV); + zLo.fillZero(); + assert_gt(_dcV, 3); + assert_eq(zLo[0], 0); + calcZ(t, lo, zLo, this->verbose(), this->sanityCheck()); + } + } catch(bad_alloc &e) { + if(this->_passMemExc) { + throw e; // rethrow immediately + } else { + cerr << "Could not allocate a z-array of " << (_dcV * 4) << " bytes" << endl; + cerr << "Please try using a larger number of blocks by specifying a smaller --bmax or" << endl + << "a larger --bmaxdivn" << endl; + throw 1; + } + } + + // This is the most critical loop in the algorithm; this is where + // we iterate over all suffixes in the text and pick out those that + // fall into the current bucket. + // + // This loop is based on the SMALLERSUFFIXES function outlined on + // p7 of the "Fast BWT" paper + // + int64_t kHi = -1, kLo = -1; + int64_t jHi = -1, jLo = -1; + bool kHiSoft = false, kLoSoft = false; + assert_eq(0, bucket.size()); + { + // Timer timer(cout, " Block accumulator loop time: ", this->verbose()); + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL(" Entering block accumulator loop for bucket " << (cur_block+1) << ":"); + } + TIndexOffU lenDiv10 = (len + 9) / 10; + for(TIndexOffU iten = 0, ten = 0; iten < len; iten += lenDiv10, ten++) { + TIndexOffU itenNext = iten + lenDiv10; + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + if(ten > 0) VMSG_NL(" bucket " << (cur_block+1) << ": " << (ten * 10) << "%"); + } + for(TIndexOffU i = iten; i < itenNext && i < len; i++) { + assert_lt(jLo, (int64_t)i); assert_lt(jHi, (int64_t)i); + // Advance the upper-bound comparison by one character + if(i == hi || i == lo) continue; // equal to one of the bookends + if(hi != OFF_MASK && !suffixCmp(hi, i, jHi, kHi, kHiSoft, zHi)) { + continue; // not in the bucket + } + if(lo != OFF_MASK && suffixCmp(lo, i, jLo, kLo, kLoSoft, zLo)) { + continue; // not in the bucket + } + // In the bucket! - add it + assert_lt(i, len); + try { + bucket.push_back(i); + } catch(bad_alloc &e) { + cerr << "Could not append element to block of " << ((bucket.size()) * OFF_SIZE) << " bytes" << endl; + if(this->_passMemExc) { + throw e; // rethrow immediately + } else { + cerr << "Please try using a larger number of blocks by specifying a smaller --bmax or" << endl + << "a larger --bmaxdivn" << endl; + throw 1; + } + } + // Not necessarily true; we allow overflowing buckets + // since we can't guarantee that a good set of sample + // suffixes can be found in a reasonable amount of time + //assert_lt(bucket.size(), this->bucketSz()); + } + } // end loop over all suffixes of t + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL(" bucket " << (cur_block+1) << ": 100%"); + } + } + } // end else clause of if(_sampleSuffs.size() == 0) + // Sort the bucket + if(bucket.size() > 0) { + Timer timer(cout, " Sorting block time: ", this->verbose()); + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL(" Sorting block of length " << bucket.size() << " for bucket " << (cur_block+1)); + } + this->qsort(bucket); + } + if(hi != OFF_MASK) { + // Not the final bucket; throw in the sample on the RHS + bucket.push_back(hi); + } else { + // Final bucket; throw in $ suffix + bucket.push_back(len); + } + { + ThreadSafe ts(&_mutex, this->_nthreads > 1); + VMSG_NL("Returning block of " << bucket.size() << " for bucket " << (cur_block+1)); + } +} + +#endif /*BLOCKWISE_SA_H_*/ diff --git a/bp_aligner.h b/bp_aligner.h new file mode 100644 index 0000000..15b6836 --- /dev/null +++ b/bp_aligner.h @@ -0,0 +1,1237 @@ +/* + * Copyright 2014, Daehwan Kim + * + * This file is part of HISAT. + * + * HISAT is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT. If not, see . + */ + +#ifndef BP_ALIGNER_H_ +#define BP_ALIGNER_H_ + +#include "hi_aligner.h" + +/** + * With a hierarchical indexing, SplicedAligner provides several alignment strategies + * , which enable effective alignment of RNA-seq reads + */ +template +class BP_Aligner : public HI_Aligner { + +public: + /** + * Initialize with index. + */ + BP_Aligner( + const Ebwt& ebwt, + const EList& refnames, + MUTEX_T* mutex, + uint64_t threads_rids_mindist = 0, + bool no_spliced_alignment = false) : + HI_Aligner(ebwt, + threads_rids_mindist, + no_spliced_alignment), + _refnames(refnames), + _mutex(mutex), + _done(false) + { + } + + ~BP_Aligner() { + } + + /** + * Aligns a read or a pair + * This funcion is called per read or pair + */ + virtual + int go( + const Scoring& sc, + const Ebwt& ebwtFw, + const Ebwt& ebwtBw, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) + { + _done = false; + index_t rdi; + bool fw; + while(this->nextBWT(sc, ebwtFw, ebwtBw, ref, rdi, fw, wlm, prm, him, rnd, sink)) { + // given the partial alignment, try to extend it to full alignments + this->align(sc, ebwtFw, ebwtBw, ref, swa, ssdb, rdi, fw, wlm, prm, swm, him, rnd, sink); + if(_done) break; + } + + return EXTEND_POLICY_FULFILLED; + } + + /** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ + virtual + void hybridSearch( + const Scoring& sc, + const Ebwt& ebwtFw, + const Ebwt& ebwtBw, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink); + + /** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ + virtual + void hybridSearch_recur( + const Scoring& sc, + const Ebwt& ebwtFw, + const Ebwt& ebwtBw, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + const GenomeHit& hit, + index_t hitoff, + index_t hitlen, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink, + index_t dep = 0); + +private: + EList _refnames; + MUTEX_T* _mutex; + bool _done; +}; + +/** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ +template +void BP_Aligner::hybridSearch( + const Scoring& sc, + const Ebwt& ebwtFw, + const Ebwt& ebwtBw, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) +{ + assert_lt(rdi, 2); + assert(this->_rds[rdi] != NULL); + him.localatts++; + + // before further alignment using local search, extend the partial alignments directly + // by comparing with the corresponding genomic sequences + // this extension is performed without any mismatches allowed + for(index_t hi = 0; hi < this->_genomeHits.size(); hi++) { + GenomeHit& genomeHit = this->_genomeHits[hi]; + index_t leftext = (index_t)OFF_MASK, rightext = (index_t)OFF_MASK; + genomeHit.extend(*(this->_rds[rdi]), ref, ssdb, swa, swm, prm, sc, this->_minsc[rdi], rnd, this->_minK_local, leftext, rightext); + } + + // for the candidate alignments, examine the longest (best) one first + this->_genomeHits_done.resize(this->_genomeHits.size()); + this->_genomeHits_done.fill(false); + for(size_t hi = 0; hi < this->_genomeHits.size(); hi++) { + index_t hj = 0; + for(; hj < this->_genomeHits.size(); hj++) { + if(!this->_genomeHits_done[hj]) break; + } + if(hj >= this->_genomeHits.size()) break; + for(index_t hk = hj + 1; hk < this->_genomeHits.size(); hk++) { + if(this->_genomeHits_done[hk]) continue; + GenomeHit& genomeHit_j = this->_genomeHits[hj]; + GenomeHit& genomeHit_k = this->_genomeHits[hk]; + if(genomeHit_k.hitcount() > genomeHit_j.hitcount() || + (genomeHit_k.hitcount() == genomeHit_j.hitcount() && genomeHit_k.len() > genomeHit_j.len())) { + hj = hk; + } + } + + // given a candidate partial alignment, extend it bidirectionally + him.anchoratts++; + GenomeHit& genomeHit = this->_genomeHits[hj]; + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + genomeHit, + genomeHit.rdoff(), + genomeHit.len(), + wlm, + prm, + swm, + him, + rnd, + sink); + this->_genomeHits_done[hj] = true; + if(_done) return; + } +} + + +/** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ +template +void BP_Aligner::hybridSearch_recur( + const Scoring& sc, + const Ebwt& ebwtFw, + const Ebwt& ebwtBw, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + const GenomeHit& hit, + index_t hitoff, + index_t hitlen, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink, + index_t dep) +{ + if(_done) return; + him.localsearchrecur++; + assert_lt(rdi, 2); + assert(this->_rds[rdi] != NULL); + const Read& rd = *(this->_rds[rdi]); + index_t rdlen = rd.length(); + if(hit.score() < this->_minsc[rdi]) return; + + // if it's already examined, just return + if(hitoff == hit.rdoff() - hit.trim5() && hitlen == hit.len() + hit.trim5() + hit.trim3()) { + if(this->isSearched(hit, rdi)) return; + this->addSearched(hit, rdi); + } + + // for effective use of memory allocation and deallocation + if(this->_coords.size() <= dep) { + this->_coords.expand(); + assert_leq(this->_local_genomeHits.size(), dep); + this->_local_genomeHits.expand(); + assert_leq(this->_spliceSites.size(), dep); + this->_spliceSites.expand(); + } + EList& coords = this->_coords[dep]; + EList >& local_genomeHits = this->_local_genomeHits[dep]; + EList& spliceSites = this->_spliceSites[dep]; + + // daehwan - for debugging purposes +#if 0 + cout << rd.name << "\t" + << (hit.fw() ? "+" : "-") << "\t" + << hitoff << "\t" + << hitoff + hitlen << "\t" + << "( " << hit.rdoff() << "\t" + << hit.rdoff() + hit.len() << " )" << "\t" + << hit.refoff() << "\t" + << hit.getRightOff() << "\t" + << hit.score() << "\t" + << "dep: " << dep << "\t"; + Edit::print(cout, hit.edits()); + cout << endl; +#endif + + assert_leq(hitoff + hitlen, rdlen); + // if this is a full alignment, report it + if(hitoff == 0 && hitlen == rdlen) { + if(!this->redundant(sink, rdi, hit)) { + // this->reportHit(sc, ebwtFw, ref, sink, rdi, hit); + return; + } + } else if(hitoff > 0 && (hitoff + hitlen == rdlen || hitoff + hitoff < rdlen - hitlen)) { + // extend the partial alignment in the left direction + index_t fragoff = 0, fraglen = 0, left = 0; + hit.getLeft(fragoff, fraglen, left); + const index_t minMatchLen = this->_minK_local; + // make use of a list of known or novel splice sites to further align the read + if(fraglen >= minMatchLen && left >= minMatchLen && !this->_no_spliced_alignment) { + spliceSites.clear(); + ssdb.getLeftSpliceSites(hit.ref(), left + minMatchLen, minMatchLen * 2, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(!ss._fromfile && ss._readid + this->_thread_rids_mindist > rd.rdid) continue; + if(left + fraglen - 1 < ss.right()) continue; + index_t frag2off = ss.left() - (ss.right() - left); + if(frag2off + 1 < hitoff) continue; + GenomeHit tempHit; + tempHit.init(hit.fw(), + 0, + hitoff, + 0, // trim5 + 0, // trim3 + hit.ref(), + frag2off + 1 - hitoff, + this->_sharedVars); + if(!tempHit.compatibleWith(hit, this->_no_spliced_alignment)) continue; + int64_t minsc = this->_minsc[rdi]; + bool combined = tempHit.combineWith(hit, rd, ref, ssdb, swa, swm, sc, minsc, rnd, this->_minK_local, 1, 1, false); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(combined && tempHit.score() >= minsc) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + + // choose a local index based on the genomic location of the partial alignment + const HierEbwt* hierEbwtFw = (const HierEbwt*)(&ebwtFw); + const LocalEbwt* localEbwtFw = hierEbwtFw->getLocalEbwt(hit.ref(), hit.refoff()); + assert_leq(localEbwtFw->_localOffset, hit.refoff()); + bool success = false, first = true; + index_t count = 0; + // consider at most two local indexes + index_t max_count = 2; + int64_t prev_score = hit.score(); + local_genomeHits.clear(); + while(!success && count++ < max_count) { + if(him.localindexatts >= this->max_localindexatts) return; + if(first) { + first = false; + } else { + localEbwtFw = hierEbwtFw->prevLocalEbwt(localEbwtFw); + if(localEbwtFw == NULL || localEbwtFw->empty()) break; + } + // local index search + index_t extlen = 0; + local_index_t top = (local_index_t)OFF_MASK, bot = (local_index_t)OFF_MASK; + index_t extoff = hitoff - 1; + if(extoff > 0) extoff -= 1; + if(extoff < minAnchorLen) { + extoff = minAnchorLen; + } + index_t nelt = (index_t)OFF_MASK; + index_t max_nelt = std::max(5, extlen); + bool no_extension = false; + bool uniqueStop; + // daehwan - for debugging purposes + // index_t minUniqueLen = this->_minK_local; + index_t minUniqueLen = (index_t)OFF_MASK; + for(; extoff < rdlen; extoff++) { + extlen = 0; + // daehwan - for debugging purposes + // uniqueStop = true; + uniqueStop = false; + him.localindexatts++; + nelt = this->localEbwtSearch( + localEbwtFw, // BWT index + NULL, // BWT index + rd, // read to align + sc, // scoring scheme + hit.fw(), + false, // searchfw, + extoff, + extlen, + top, + bot, + rnd, + uniqueStop, + minUniqueLen); + if(extoff + 1 - extlen >= hitoff) { + no_extension = true; + break; + } + if(nelt <= max_nelt) break; + } + assert_leq(top, bot); + assert_eq(nelt, (index_t)(bot - top)); + assert_leq(extlen, extoff + 1); + if(nelt > 0 && + nelt <= max_nelt && + extlen >= minAnchorLen && + !no_extension) { + assert_leq(nelt, max_nelt); + coords.clear(); + bool straddled = false; + // get genomic locations for this local search + this->getGenomeCoords_local( + *localEbwtFw, + ref, + rnd, + top, + bot, + hit.fw(), + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled? + straddled); + assert_leq(coords.size(), nelt); + coords.sort(); + for(int ri = coords.size() - 1; ri >= 0; ri--) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + coord.ref(), + coord.off(), + this->_sharedVars); + + // daehwan - for debugging purposes + if(coord.ref() == hit.ref() && + coord.off() > hit.refoff() && + coord.off() < hit.refoff() + 64000) { + index_t leftext = (index_t)OFF_MASK, rightext = (index_t)0; + index_t mm = 1; + tempHit.extend( + rd, + ref, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + this->_minK_local, + leftext, + rightext, + mm); + +#if 0 + cout << endl; + cout << rd.rdid << "\t" << rd.name << endl; + cout << "\ttype: " << 1 << endl; + cout << "\t" << hit.ref() << endl; + cout << "\t\ttempHit " << (tempHit.fw() ? "+" : "-") << "\t" << tempHit.refoff() << "\t" << tempHit.rdoff() << "\t" << tempHit.len() << "\t" << tempHit.score() << endl; + cout << "\t\tanchHit " << (hit.fw() ? "+" : "-") << "\t" << hit.refoff() << "\t" << hit.rdoff() << "\t" << hit.len() << "\t" << hit.score() << endl; + + spliceSites.clear(); + ssdb.getRightSpliceSites(hit.ref(), hit.refoff() - minMatchLen, minMatchLen * 2, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(ss.right() > tempHit.refoff()) { + index_t dist = ss.right() - 1 - (tempHit.refoff() + tempHit.len() - 1); + cout << rd.rdid << "s\t\t\t" << ss.left() + 1 << "\t" << ss.right() - 1 << "\t" << (ss.fw() ? "+" : "-") << "\t" << dist << endl; + } + } + + spliceSites.clear(); + ssdb.getLeftSpliceSites(tempHit.ref(), tempHit.getRightOff() + minMatchLen, minMatchLen * 2, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(ss.left() < hit.refoff()) { + index_t dist = hit.refoff() - (ss.left() + 1); + cout << rd.rdid << "s\t\t\t" << ss.left() + 1 << "\t" << ss.right() - 1 << "\t" << (ss.fw() ? "+" : "-") << "\t" << dist << endl; + } + } + + if(tempHit.rdoff() + tempHit.len() + 1 >= hit.rdoff()) return; +#else + assert_lt(hit.ref(), _refnames.size()); + { + ThreadSafe t(const_cast(_mutex), true); + cout << rd.name << "\t" + << _refnames[hit.ref()] << "\t" + << (tempHit.fw() ? "+" : "-") << "\t" << tempHit.refoff() << "\t" << tempHit.rdoff() << "\t" << tempHit.len() << "\t" << tempHit.score() << "\t" + << (hit.fw() ? "+" : "-") << "\t" << hit.refoff() << "\t" << hit.rdoff() << "\t" << hit.len() << "\t" << hit.score() + << endl; + } + _done = true; + return; +#endif + } + + // check if the partial alignment is compatible with the new alignment using the local index + if(!tempHit.compatibleWith(hit, this->_no_spliced_alignment)) { + if(count == 1) continue; + else break; + } + if(uniqueStop) { + assert_eq(coords.size(), 1); + index_t leftext = (index_t)OFF_MASK, rightext = (index_t)0; + tempHit.extend(rd, ref, ssdb, swa, swm, prm, sc, this->_minsc[rdi], rnd, this->_minK_local, leftext, rightext); + } + // combine the partial alignment and the new alignment + int64_t minsc = this->_minsc[rdi]; + bool combined = tempHit.combineWith(hit, rd, ref, ssdb, swa, swm, sc, minsc, rnd, this->_minK_local); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(combined && tempHit.score() >= minsc) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + if(tempHit.score() >= prev_score - sc.mmpMax) { + // extend the new partial alignment recursively + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } else { + local_genomeHits.push_back(tempHit); + } + } + } + } + int64_t minsc = (rdi == 0 ? sink.bestUnp1() : sink.bestUnp2()); + if(minsc >= prev_score - sc.mmpMax) success = true; + if(!success && (count == max_count || hierEbwtFw->prevLocalEbwt(localEbwtFw) == NULL)) { + for(index_t ti = 0; ti < local_genomeHits.size(); ti++) { + GenomeHit& tempHit = local_genomeHits[ti]; + int64_t minsc = this->_minsc[rdi]; + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(tempHit.score() >= minsc) { + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + } // while(!success && count++ < 2) + + if(!success) { + if(hitoff > this->_minK) { + index_t extlen = 0; + index_t top = (index_t)OFF_MASK, bot = (index_t)OFF_MASK; + index_t extoff = hitoff - 1; + bool uniqueStop = true; + // perform global search for long introns + index_t nelt = this->globalEbwtSearch( + ebwtFw, // BWT index + rd, // read to align + sc, // scoring scheme + hit.fw(), + extoff, + extlen, + top, + bot, + rnd, + uniqueStop); + if(nelt <= 5 && extlen >= this->_minK) { + coords.clear(); + bool straddled = false; + this->getGenomeCoords( + ebwtFw, + ref, + rnd, + top, + bot, + hit.fw(), + bot - top, + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled? + straddled); + assert_leq(coords.size(), nelt); + coords.sort(); + for(int ri = coords.size() - 1; ri >= 0; ri--) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + coord.ref(), + coord.off(), + this->_sharedVars); + if(!tempHit.compatibleWith(hit, this->_no_spliced_alignment)) continue; + if(uniqueStop) { + assert_eq(coords.size(), 1); + index_t leftext = (index_t)OFF_MASK, rightext = (index_t)0; + tempHit.extend(rd, ref, ssdb, swa, swm, prm, sc, this->_minsc[rdi], rnd, this->_minK_local, leftext, rightext); + } + int64_t minsc = this->_minsc[rdi]; + bool combined = tempHit.combineWith(hit, rd, ref, ssdb, swa, swm, sc, minsc, rnd, this->_minK_local); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(combined && tempHit.score() >= minsc) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + } + GenomeHit tempHit = hit; + if(tempHit.rdoff() <= 5) { + index_t trim5 = tempHit.rdoff(); + tempHit.trim5(trim5); + assert_leq(tempHit.len() + tempHit.trim5() + tempHit.trim3(), rdlen); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + 0, + tempHit.len() + tempHit.trim5() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + return; + } + // extend the partial alignment directly comparing with the corresponding genomic sequence + // with mismatches or a gap allowed + int64_t minsc = this->_minsc[rdi]; + assert_geq(tempHit.score(), minsc); + index_t mm = (tempHit.score() - minsc) / sc.mmpMax; + index_t leftext = (index_t)OFF_MASK, rightext = (index_t)0; + index_t num_mismatch_allowed = 1; + if(hitoff <= this->_minK_local) { + num_mismatch_allowed = min(tempHit.rdoff(), mm); + } + him.localextatts++; + tempHit.extend(rd, ref, ssdb, swa, swm, prm, sc, this->_minsc[rdi], rnd, this->_minK_local, leftext, rightext, num_mismatch_allowed); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(tempHit.score() >= minsc && leftext >= min(this->_minK_local, hit.rdoff())) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } else if(hitoff > this->_minK_local) { + // skip some bases of a read + index_t jumplen = hitoff > this->_minK ? this->_minK : this->_minK_local; + assert_leq(hitoff, hit.rdoff()); + int64_t expected_score = hit.score() - (hit.rdoff() - hitoff) / jumplen * sc.mmpMax - sc.mmpMax; + if(expected_score >= minsc) { + assert_lt(hitlen + jumplen, rdlen); + assert_eq(hit.trim5(), 0); + assert_leq(hitoff + hitlen, rdlen); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + hit, + hitoff - jumplen, + hitlen + jumplen, + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + } else { + // extend the partial alignment in the right direction + assert_lt(hitoff + hitlen, rdlen); + index_t fragoff = 0, fraglen = 0, right = 0; + hit.getRight(fragoff, fraglen, right); + const index_t minMatchLen = this->_minK_local; + // make use of a list of known or novel splice sites to further align the read + if(fraglen >= minMatchLen && !this->_no_spliced_alignment) { + spliceSites.clear(); + assert_gt(fraglen, 0); + ssdb.getRightSpliceSites(hit.ref(), right + fraglen - minMatchLen, minMatchLen * 2, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(!ss._fromfile && ss._readid + this->_thread_rids_mindist > rd.rdid) continue; + if(right > ss.left()) continue; + index_t frag2off = ss.right() - ss.left() + right + fraglen - 1; + GenomeHit tempHit; + tempHit.init(hit.fw(), + fragoff + fraglen, + rdlen - fragoff - fraglen, + 0, // trim5 + 0, // trim3 + hit.ref(), + frag2off, + this->_sharedVars); + if(!hit.compatibleWith(tempHit, this->_no_spliced_alignment)) continue; + GenomeHit combinedHit = hit; + int64_t minsc = this->_minsc[rdi]; + bool combined = combinedHit.combineWith(tempHit, rd, ref, ssdb, swa, swm, sc, minsc, rnd, this->_minK_local, 1, 1, false); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(combined && combinedHit.score() >= minsc) { + assert_leq(combinedHit.trim5(), combinedHit.rdoff()); + assert_eq(combinedHit.rdoff() + combinedHit.len(), rdlen); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + combinedHit, + combinedHit.rdoff() - combinedHit.trim5(), + combinedHit.len() + combinedHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + + // choose a local index based on the genomic location of the partial alignment + const HierEbwt* hierEbwtFw = (const HierEbwt*)(&ebwtFw); + const LocalEbwt* localEbwtFw = hierEbwtFw->getLocalEbwt(hit.ref(), hit.refoff()); + bool success = false, first = true; + index_t count = 0; + index_t max_count = 2; + int64_t prev_score = hit.score(); + local_genomeHits.clear(); + while(!success && count++ < max_count) { + if(him.localindexatts >= this->max_localindexatts) return; + if(first) { + first = false; + } else { + localEbwtFw = hierEbwtFw->nextLocalEbwt(localEbwtFw); + if(localEbwtFw == NULL || localEbwtFw->empty()) break; + } + // local index search + index_t extlen = 0; + local_index_t top = (local_index_t)OFF_MASK, bot = (local_index_t)OFF_MASK; + // daehwan - for debugging purposes + // index_t extoff = hitoff + hitlen + this->_minK_local; + index_t extoff = hitoff + hitlen + this->_minK_local * 3; + if(extoff + 1 < rdlen) extoff += 1; + if(extoff >= rdlen) { + extoff = rdlen - 1; + } + index_t nelt = (index_t)OFF_MASK; + index_t max_nelt = std::max(5, extlen); + bool no_extension = false; + bool uniqueStop; + // daehwan - for debugging purposes + // index_t minUniqueLen = this->_minK_local; + index_t minUniqueLen = (index_t)OFF_MASK; + index_t maxHitLen = max(extoff + 1 - hitoff - hitlen, this->_minK_local); + for(; maxHitLen < extoff + 1 && extoff < rdlen;) { + extlen = 0; + uniqueStop = false; + him.localindexatts++; + nelt = this->localEbwtSearch( + localEbwtFw, // BWT index + NULL, // BWT index + rd, // read to align + sc, // scoring scheme + hit.fw(), + false, // searchfw, + extoff, + extlen, + top, + bot, + rnd, + uniqueStop, + minUniqueLen, + maxHitLen); + if(extoff < hitoff + hitlen) { + no_extension = true; + break; + } + if(nelt <= max_nelt) break; + if(extoff + 1 < rdlen) extoff++; + else { + if(extlen < maxHitLen) break; + else maxHitLen++; + } + } + assert_leq(top, bot); + assert_eq(nelt, (index_t)(bot - top)); + assert_leq(extlen, extoff + 1); + assert_leq(extoff, rdlen); + if(nelt > 0 && + nelt <= max_nelt && + extlen >= minAnchorLen && + !no_extension) { + assert_leq(nelt, max_nelt); + coords.clear(); + bool straddled = false; + // get genomic locations for this local search + this->getGenomeCoords_local( + *localEbwtFw, + ref, + rnd, + top, + bot, + hit.fw(), + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled? + straddled); + assert_leq(coords.size(), nelt); + coords.sort(); + for(index_t ri = 0; ri < coords.size(); ri++) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + coord.ref(), + coord.off(), + this->_sharedVars); + + // daehwan - for debugging purposes + if(coord.ref() == hit.ref() && + coord.off() < hit.refoff() && + coord.off() + 64000 > hit.refoff()) { + index_t leftext = (index_t)0, rightext = (index_t)OFF_MASK; + index_t mm = 1; + tempHit.extend( + rd, + ref, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + this->_minK_local, + leftext, + rightext, + mm); + +#if 0 + cout << endl; + cout << rd.rdid << "\t" << rd.name << endl; + cout << "\ttype: " << 2 << endl; + cout << "\t" << hit.ref() << endl; + cout << "\t\ttempHit " << (tempHit.fw() ? "+" : "-") << "\t" << tempHit.refoff() << "\t" << tempHit.rdoff() << "\t" << tempHit.len() << "\t" << tempHit.score() << endl; + cout << "\t\tanchHit " << (hit.fw() ? "+" : "-") << "\t" << hit.refoff() << "\t" << hit.rdoff() << "\t" << hit.len() << "\t" << hit.score() << endl; + + spliceSites.clear(); + ssdb.getRightSpliceSites(tempHit.ref(), tempHit.refoff() - minMatchLen, minMatchLen * 2, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(ss.right() > hit.getRightOff()) { + index_t dist = ss.right() - 1 - hit.getRightOff(); + cout << rd.rdid << "s\t\t\t" << ss.left() + 1 << "\t" << ss.right() - 1 << "\t" << (ss.fw() ? "+" : "-") << "\t" << dist << endl; + } + } + + spliceSites.clear(); + ssdb.getLeftSpliceSites(hit.ref(), hit.getRightOff() + minMatchLen, minMatchLen * 2, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(ss.left() < tempHit.refoff()) { + index_t dist = tempHit.refoff() - (ss.left() + 1); + cout << rd.rdid << "s\t\t\t" << ss.left() + 1 << "\t" << ss.right() - 1 << "\t" << (ss.fw() ? "+" : "-") << "\t" << dist << endl; + } + } + + if(hit.rdoff() + hit.len() - 1 <= tempHit.rdoff()) return; +#else + assert_lt(hit.ref(), _refnames.size()); + { + ThreadSafe t(const_cast(_mutex), true); + cout << rd.name << "\t" + << _refnames[hit.ref()] << "\t" + << (hit.fw() ? "+" : "-") << "\t" << hit.refoff() << "\t" << hit.rdoff() << "\t" << hit.len() << "\t" << hit.score() << "\t" + << (tempHit.fw() ? "+" : "-") << "\t" << tempHit.refoff() << "\t" << tempHit.rdoff() << "\t" << tempHit.len() << "\t" << tempHit.score() + << endl; + } + _done = true; + return; + +#endif + } + + // check if the partial alignment is compatible with the new alignment using the local index + if(!hit.compatibleWith(tempHit, this->_no_spliced_alignment)) { + if(count == 1) continue; + else break; + } + index_t leftext = (index_t)0, rightext = (index_t)OFF_MASK; + tempHit.extend(rd, ref, ssdb, swa, swm, prm, sc, this->_minsc[rdi], rnd, this->_minK_local, leftext, rightext); + GenomeHit combinedHit = hit; + int64_t minsc = this->_minsc[rdi]; + // combine the partial alignment and the new alignment + bool combined = combinedHit.combineWith(tempHit, rd, ref, ssdb, swa, swm, sc, minsc, rnd, this->_minK_local); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(combined && combinedHit.score() >= minsc) { + assert_leq(combinedHit.trim5(), combinedHit.rdoff()); + if(combinedHit.score() >= prev_score - sc.mmpMax) { + // extend the new partial alignment recursively + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + combinedHit, + combinedHit.rdoff() - combinedHit.trim5(), + combinedHit.len() + combinedHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } else { + local_genomeHits.push_back(combinedHit); + } + } + } + } + int64_t minsc = (rdi == 0 ? sink.bestUnp1() : sink.bestUnp2()); + if(minsc >= prev_score - sc.mmpMax) success = true; + if(!success && (count == max_count || hierEbwtFw->nextLocalEbwt(localEbwtFw) == NULL) ) { + for(index_t ti = 0; ti < local_genomeHits.size(); ti++) { + GenomeHit& tempHit = local_genomeHits[ti]; + int64_t minsc = this->_minsc[rdi]; + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(tempHit.score() >= minsc) { + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff() - tempHit.trim5(), + tempHit.len() + tempHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + } // while(!success && count++ < 2) + + if(!success) { + // perform global search for long introns + if(hitoff + hitlen + this->_minK + 1 < rdlen) { + index_t extlen = 0; + index_t top = (index_t)OFF_MASK, bot = (index_t)OFF_MASK; + index_t extoff = hitoff + hitlen + this->_minK + 1; + bool uniqueStop = true; + index_t nelt = this->globalEbwtSearch( + ebwtFw, // BWT index + rd, // read to align + sc, // scoring scheme + hit.fw(), + extoff, + extlen, + top, + bot, + rnd, + uniqueStop); + if(nelt <= 5 && extlen >= this->_minK) { + coords.clear(); + bool straddled = false; + this->getGenomeCoords( + ebwtFw, + ref, + rnd, + top, + bot, + hit.fw(), + bot - top, + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled + straddled); + assert_leq(coords.size(), nelt); + coords.sort(); + for(index_t ri = 0; ri < coords.size(); ri++) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + coord.ref(), + coord.off(), + this->_sharedVars); + if(!hit.compatibleWith(tempHit, this->_no_spliced_alignment)) continue; + index_t leftext = (index_t)0, rightext = (index_t)OFF_MASK; + tempHit.extend(rd, ref, ssdb, swa, swm, prm, sc, this->_minsc[rdi], rnd, this->_minK_local, leftext, rightext); + GenomeHit combinedHit = hit; + int64_t minsc = this->_minsc[rdi]; + bool combined = combinedHit.combineWith(tempHit, rd, ref, ssdb, swa, swm, sc, minsc, rnd, this->_minK_local); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(combined && combinedHit.score() >= minsc) { + assert_leq(combinedHit.trim5(), combinedHit.rdoff()); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + combinedHit, + combinedHit.rdoff() - combinedHit.trim5(), + combinedHit.len() + combinedHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + } + GenomeHit tempHit = hit; + assert(tempHit.trim5() == 0 || hitoff == 0); + if(rdlen - hitoff - tempHit.len() - tempHit.trim5() <= 5) { + index_t trim3 = rdlen - hitoff - tempHit.len() - tempHit.trim5(); + tempHit.trim3(trim3); + assert_leq(tempHit.trim5(), tempHit.rdoff()); + assert_leq(tempHit.len() + tempHit.trim5() + tempHit.trim3(), rdlen); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff() - tempHit.trim5(), + tempHit.len() + tempHit.trim5() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + return; + } + // extend the partial alignment directly comparing with the corresponding genomic sequence + // with mismatches or a gap allowed + int64_t minsc = this->_minsc[rdi]; + assert_geq(tempHit.score(), minsc); + index_t leftext = (index_t)0, rightext = (index_t)OFF_MASK; + index_t mm = (tempHit.score() - minsc) / sc.mmpMax; + index_t num_mismatch_allowed = 1; + if(rdlen - hitoff - hitlen <= this->_minK_local) { + num_mismatch_allowed = min(rdlen - tempHit.rdoff() - tempHit.len(), mm); + } + him.localextatts++; + tempHit.extend(rd, ref, ssdb, swa, swm, prm, sc, this->_minsc[rdi], rnd, this->_minK_local, leftext, rightext, num_mismatch_allowed); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + if(tempHit.score() >= minsc && rightext >= min(this->_minK_local, rdlen - hit.len() - hit.rdoff())) { + assert_eq(tempHit.trim3(), 0); + assert_leq(tempHit.trim5(), tempHit.rdoff()); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff() - tempHit.trim5(), + tempHit.len() + tempHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } else if(hitoff + hitlen + this->_minK_local < rdlen) { + // skip some bases of a read + index_t jumplen = hitoff + hitlen + this->_minK < rdlen ? this->_minK : this->_minK_local; + assert_lt(hitoff + hitlen + jumplen, rdlen); + assert_leq(hit.len(), hitlen); + int64_t expected_score = hit.score() - (hitlen - hit.len()) / jumplen * sc.mmpMax - sc.mmpMax; + if(expected_score >= minsc) { + assert_eq(hit.trim3(), 0); + hybridSearch_recur( + sc, + ebwtFw, + ebwtBw, + ref, + swa, + ssdb, + rdi, + hit, + hitoff, + hitlen + jumplen, + wlm, + prm, + swm, + him, + rnd, + sink, + dep + 1); + } + } + } + } +} + +#endif /*BP_ALIGNER_H_*/ diff --git a/btypes.h b/btypes.h new file mode 100644 index 0000000..d82ed44 --- /dev/null +++ b/btypes.h @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + + +#ifndef BOWTIE_INDEX_TYPES_H +#define BOWTIE_INDEX_TYPES_H + +#ifdef BOWTIE_64BIT_INDEX +#define OFF_MASK 0xffffffffffffffff +#define OFF_LEN_MASK 0xc000000000000000 +#define LS_SIZE 0x100000000000000 +#define OFF_SIZE 8 +#define INDEX_MAX 0xffffffffffffffff + +typedef uint64_t TIndexOffU; +typedef int64_t TIndexOff; + +#else +#define OFF_MASK 0xffffffff +#define OFF_LEN_MASK 0xc0000000 +#define LS_SIZE 0x10000000 +#define OFF_SIZE 4 +#define INDEX_MAX 0xffffffff + +typedef uint32_t TIndexOffU; +typedef int TIndexOff; + +#endif /* BOWTIE_64BIT_INDEX */ + +extern const std::string gfm_ext; + +#endif /* BOWTIE_INDEX_TYPES_H */ diff --git a/ccnt_lut.cpp b/ccnt_lut.cpp new file mode 100644 index 0000000..bcac83c --- /dev/null +++ b/ccnt_lut.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include + +/* Generated by gen_lookup_tables.pl */ + +uint8_t cCntLUT_4[4][4][256]; +uint8_t cCntLUT_4_rev[4][4][256]; +uint8_t cCntBIT[8][256]; + +int countCnt(int by, int c, uint8_t str) { + int count = 0; + if(by == 0) by = 4; + while(by-- > 0) { + int c2 = str & 3; + str >>= 2; + if(c == c2) count++; + } + + return count; +} + +int countCnt_rev(int by, int c, uint8_t str) { + int count = 0; + if(by == 0) by = 4; + while(by-- > 0) { + int c2 = (str >> 6) & 3; + str <<= 2; + if(c == c2) count++; + } + + return count; +} + +void initializeCntLut() { + for(int by = 0; by < 4; by++) { + for(int c = 0; c < 4; c++) { + for(int str = 0; str < 256; str++) { + cCntLUT_4[by][c][str] = countCnt(by, c, str); + cCntLUT_4_rev[by][c][str] = countCnt_rev(by, c, str); + } + } + } +} + +int countBit(int b, uint8_t str) { + int count = 0; + if(b == 0) b = 8; + while(b-- > 0) { + if(str & 0x1) count++; + str >>= 1; + } + + return count; +} + +void initializeCntBit() { + for(int b = 0; b < 8; b++) { + for(int str = 0; str < 256; str++) { + cCntBIT[b][str] = countBit(b, str); + } + } +} diff --git a/diff_sample.cpp b/diff_sample.cpp new file mode 100644 index 0000000..b722702 --- /dev/null +++ b/diff_sample.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "diff_sample.h" + +struct sampleEntry clDCs[16]; +bool clDCs_calced = false; /// have clDCs been calculated? + +/** + * Entries 4-57 are transcribed from page 6 of Luk and Wong's paper + * "Two New Quorum Based Algorithms for Distributed Mutual Exclusion", + * which is also used and cited in the Burkhardt and Karkkainen's + * papers on difference covers for sorting. These samples are optimal + * according to Luk and Wong. + * + * All other entries are generated via the exhaustive algorithm in + * calcExhaustiveDC(). + * + * The 0 is stored at the end of the sample as an end-of-list marker, + * but 0 is also an element of each. + * + * Note that every difference cover has a 0 and a 1. Intuitively, + * any optimal difference cover sample can be oriented (i.e. rotated) + * such that it includes 0 and 1 as elements. + * + * All samples in this list have been verified to be complete covers. + * + * A value of 0xffffffff in the first column indicates that there is no + * sample for that value of v. We do not keep samples for values of v + * less than 3, since they are trivial (and the caller probably didn't + * mean to ask for it). + */ +uint32_t dc0to64[65][10] = { + {0xffffffff}, // 0 + {0xffffffff}, // 1 + {0xffffffff}, // 2 + {1, 0}, // 3 + {1, 2, 0}, // 4 + {1, 2, 0}, // 5 + {1, 3, 0}, // 6 + {1, 3, 0}, // 7 + {1, 2, 4, 0}, // 8 + {1, 2, 4, 0}, // 9 + {1, 2, 5, 0}, // 10 + {1, 2, 5, 0}, // 11 + {1, 3, 7, 0}, // 12 + {1, 3, 9, 0}, // 13 + {1, 2, 3, 7, 0}, // 14 + {1, 2, 3, 7, 0}, // 15 + {1, 2, 5, 8, 0}, // 16 + {1, 2, 4, 12, 0}, // 17 + {1, 2, 5, 11, 0}, // 18 + {1, 2, 6, 9, 0}, // 19 + {1, 2, 3, 6, 10, 0}, // 20 + {1, 4, 14, 16, 0}, // 21 + {1, 2, 3, 7, 11, 0}, // 22 + {1, 2, 3, 7, 11, 0}, // 23 + {1, 2, 3, 7, 15, 0}, // 24 + {1, 2, 3, 8, 12, 0}, // 25 + {1, 2, 5, 9, 15, 0}, // 26 + {1, 2, 5, 13, 22, 0}, // 27 + {1, 4, 15, 20, 22, 0}, // 28 + {1, 2, 3, 4, 9, 14, 0}, // 29 + {1, 2, 3, 4, 9, 19, 0}, // 30 + {1, 3, 8, 12, 18, 0}, // 31 + {1, 2, 3, 7, 11, 19, 0}, // 32 + {1, 2, 3, 6, 16, 27, 0}, // 33 + {1, 2, 3, 7, 12, 20, 0}, // 34 + {1, 2, 3, 8, 12, 21, 0}, // 35 + {1, 2, 5, 12, 14, 20, 0}, // 36 + {1, 2, 4, 10, 15, 22, 0}, // 37 + {1, 2, 3, 4, 8, 14, 23, 0}, // 38 + {1, 2, 4, 13, 18, 33, 0}, // 39 + {1, 2, 3, 4, 9, 14, 24, 0}, // 40 + {1, 2, 3, 4, 9, 15, 25, 0}, // 41 + {1, 2, 3, 4, 9, 15, 25, 0}, // 42 + {1, 2, 3, 4, 10, 15, 26, 0}, // 43 + {1, 2, 3, 6, 16, 27, 38, 0}, // 44 + {1, 2, 3, 5, 12, 18, 26, 0}, // 45 + {1, 2, 3, 6, 18, 25, 38, 0}, // 46 + {1, 2, 3, 5, 16, 22, 40, 0}, // 47 + {1, 2, 5, 9, 20, 26, 36, 0}, // 48 + {1, 2, 5, 24, 33, 36, 44, 0}, // 49 + {1, 3, 8, 17, 28, 32, 38, 0}, // 50 + {1, 2, 5, 11, 18, 30, 38, 0}, // 51 + {1, 2, 3, 4, 6, 14, 21, 30, 0}, // 52 + {1, 2, 3, 4, 7, 21, 29, 44, 0}, // 53 + {1, 2, 3, 4, 9, 15, 21, 31, 0}, // 54 + {1, 2, 3, 4, 6, 19, 26, 47, 0}, // 55 + {1, 2, 3, 4, 11, 16, 33, 39, 0}, // 56 + {1, 3, 13, 32, 36, 43, 52, 0}, // 57 + + // Generated by calcExhaustiveDC() + {1, 2, 3, 7, 21, 33, 37, 50, 0}, // 58 + {1, 2, 3, 6, 13, 21, 35, 44, 0}, // 59 + {1, 2, 4, 9, 15, 25, 30, 42, 0}, // 60 + {1, 2, 3, 7, 15, 25, 36, 45, 0}, // 61 + {1, 2, 4, 10, 32, 39, 46, 51, 0}, // 62 + {1, 2, 6, 8, 20, 38, 41, 54, 0}, // 63 + {1, 2, 5, 14, 16, 34, 42, 59, 0} // 64 +}; diff --git a/diff_sample.h b/diff_sample.h new file mode 100644 index 0000000..dda8e09 --- /dev/null +++ b/diff_sample.h @@ -0,0 +1,1000 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef DIFF_SAMPLE_H_ +#define DIFF_SAMPLE_H_ + +#include +#include +#include "assert_helpers.h" +#include "multikey_qsort.h" +#include "timer.h" +#include "ds.h" +#include "mem_ids.h" +#include "ls.h" +#include "btypes.h" + +using namespace std; + +#ifndef VMSG_NL +#define VMSG_NL(...) \ +if(this->verbose()) { \ + stringstream tmp; \ + tmp << __VA_ARGS__ << endl; \ + this->verbose(tmp.str()); \ +} +#endif + +#ifndef VMSG +#define VMSG(...) \ +if(this->verbose()) { \ + stringstream tmp; \ + tmp << __VA_ARGS__; \ + this->verbose(tmp.str()); \ +} +#endif + +/** + * Routines for calculating, sanity-checking, and dispensing difference + * cover samples to clients. + */ + +/** + * + */ +struct sampleEntry { + uint32_t maxV; + uint32_t numSamples; + uint32_t samples[128]; +}; + +/// Array of Colbourn and Ling calculated difference covers up to +/// r = 16 (maxV = 5953) +extern struct sampleEntry clDCs[16]; +extern bool clDCs_calced; /// have clDCs been calculated? + +/** + * Check that the given difference cover 'ds' actually covers all + * differences for a periodicity of v. + */ +template +static bool dcRepOk(T v, EList& ds) { + // diffs[] records all the differences observed + AutoArray covered(v, EBWT_CAT); + for(T i = 1; i < v; i++) { + covered[i] = false; + } + for(T di = T(); di < ds.size(); di++) { + for(T dj = di+1; dj < ds.size(); dj++) { + assert_lt(ds[di], ds[dj]); + T d1 = (ds[dj] - ds[di]); + T d2 = (ds[di] + v - ds[dj]); + assert_lt(d1, v); + assert_lt(d2, v); + covered[d1] = true; + covered[d2] = true; + } + } + bool ok = true; + for(T i = 1; i < v; i++) { + if(covered[i] == false) { + ok = false; + break; + } + } + return ok; +} + +/** + * Return true iff each element of ts (with length 'limit') is greater + * than the last. + */ +template +static bool increasing(T* ts, size_t limit) { + for(size_t i = 0; i < limit-1; i++) { + if(ts[i+1] <= ts[i]) return false; + } + return true; +} + +/** + * Return true iff the given difference cover covers difference 'diff' + * mod 'v'. + */ +template +static inline bool hasDifference(T *ds, T d, T v, T diff) { + // diffs[] records all the differences observed + for(T di = T(); di < d; di++) { + for(T dj = di+1; dj < d; dj++) { + assert_lt(ds[di], ds[dj]); + T d1 = (ds[dj] - ds[di]); + T d2 = (ds[di] + v - ds[dj]); + assert_lt(d1, v); + assert_lt(d2, v); + if(d1 == diff || d2 == diff) return true; + } + } + return false; +} + +/** + * Exhaustively calculate optimal difference cover samples for v = 4, + * 8, 16, 32, 64, 128, 256 and store results in p2DCs[] + */ +template +void calcExhaustiveDC(T i, bool verbose = false, bool sanityCheck = false) { + T v = i; + AutoArray diffs(v, EBWT_CAT); + // v is the target period + T ld = (T)ceil(sqrt(v)); + // ud is the upper bound on |D| + T ud = v / 2; + // for all possible |D|s + bool ok = true; + T *ds = NULL; + T d; + for(d = ld; d <= ud+1; d++) { + // for all possible |D| samples + AutoArray ds(d, EBWT_CAT); + for(T j = 0; j < d; j++) { + ds[j] = j; + } + assert(increasing(ds, d)); + while(true) { + // reset diffs[] + for(T t = 1; t < v; t++) { + diffs[t] = false; + } + T diffCnt = 0; + // diffs[] records all the differences observed + for(T di = 0; di < d; di++) { + for(T dj = di+1; dj < d; dj++) { + assert_lt(ds[di], ds[dj]); + T d1 = (ds[dj] - ds[di]); + T d2 = (ds[di] + v - ds[dj]); + assert_lt(d1, v); + assert_lt(d2, v); + assert_gt(d1, 0); + assert_gt(d2, 0); + if(!diffs[d1]) { diffCnt++; diffs[d1] = true; } + if(!diffs[d2]) { diffCnt++; diffs[d2] = true; } + } + } + // Do we observe all possible differences (except 0) + ok = diffCnt == v-1; + if(ok) { + // Yes, all differences are covered + break; + } else { + // Advance ds + // (Following is commented out because it turns out + // it's slow) + // Find a missing difference + //uint32_t missing = 0xffffffff; + //for(uint32_t t = 1; t < v; t++) { + // if(diffs[t] == false) { + // missing = diffs[t]; + // break; + // } + //} + //assert_neq(missing, 0xffffffff); + assert(increasing(ds, d)); + bool advanced = false; + bool keepGoing = false; + do { + keepGoing = false; + for(T bd = d-1; bd > 1; bd--) { + T dif = (d-1)-bd; + if(ds[bd] < v-1-dif) { + ds[bd]++; + assert_neq(0, ds[bd]); + // Reset subsequent ones + for(T bdi = bd+1; bdi < d; bdi++) { + assert_eq(0, ds[bdi]); + ds[bdi] = ds[bdi-1]+1; + assert_gt(ds[bdi], ds[bdi-1]); + } + assert(increasing(ds, d)); + // (Following is commented out because + // it turns out it's slow) + // See if the new DC has the missing value + //if(!hasDifference(ds, d, v, missing)) { + // keepGoing = true; + // break; + //} + advanced = true; + break; + } else { + ds[bd] = 0; + // keep going + } + } + } while(keepGoing); + // No solution for this |D| + if(!advanced) break; + assert(increasing(ds, d)); + } + } // next sample assignment + if(ok) { + break; + } + } // next |D| + assert(ok); + cout << "Did exhaustive v=" << v << " |D|=" << d << endl; + cout << " "; + for(T i = 0; i < d; i++) { + cout << ds[i]; + if(i < d-1) cout << ","; + } + cout << endl; +} + +/** + * Routune for calculating the elements of clDCs up to r = 16 using the + * technique of Colbourn and Ling. + * + * See http://citeseer.ist.psu.edu/211575.html + */ +template +void calcColbournAndLingDCs(bool verbose = false, bool sanityCheck = false) { + for(T r = 0; r < 16; r++) { + T maxv = 24*r*r + 36*r + 13; // Corollary 2.3 + T numsamp = 6*r + 4; + clDCs[r].maxV = maxv; + clDCs[r].numSamples = numsamp; + memset(clDCs[r].samples, 0, 4 * 128); + T i; + // clDCs[r].samples[0] = 0; + // Fill in the 1^r part of the B series + for(i = 1; i < r+1; i++) { + clDCs[r].samples[i] = clDCs[r].samples[i-1] + 1; + } + // Fill in the (r + 1)^1 part + clDCs[r].samples[r+1] = clDCs[r].samples[r] + r + 1; + // Fill in the (2r + 1)^r part + for(i = r+2; i < r+2+r; i++) { + clDCs[r].samples[i] = clDCs[r].samples[i-1] + 2*r + 1; + } + // Fill in the (4r + 3)^(2r + 1) part + for(i = r+2+r; i < r+2+r+2*r+1; i++) { + clDCs[r].samples[i] = clDCs[r].samples[i-1] + 4*r + 3; + } + // Fill in the (2r + 2)^(r + 1) part + for(i = r+2+r+2*r+1; i < r+2+r+2*r+1+r+1; i++) { + clDCs[r].samples[i] = clDCs[r].samples[i-1] + 2*r + 2; + } + // Fill in the last 1^r part + for(i = r+2+r+2*r+1+r+1; i < r+2+r+2*r+1+r+1+r; i++) { + clDCs[r].samples[i] = clDCs[r].samples[i-1] + 1; + } + assert_eq(i, numsamp); + assert_lt(i, 128); + if(sanityCheck) { + // diffs[] records all the differences observed + AutoArray diffs(maxv, EBWT_CAT); + for(T i = 0; i < numsamp; i++) { + for(T j = i+1; j < numsamp; j++) { + T d1 = (clDCs[r].samples[j] - clDCs[r].samples[i]); + T d2 = (clDCs[r].samples[i] + maxv - clDCs[r].samples[j]); + assert_lt(d1, maxv); + assert_lt(d2, maxv); + diffs[d1] = true; + diffs[d2] = true; + } + } + // Should have observed all possible differences (except 0) + for(T i = 1; i < maxv; i++) { + if(diffs[i] == false) cout << r << ", " << i << endl; + assert(diffs[i] == true); + } + } + } + clDCs_calced = true; +} + +/** + * A precalculated list of difference covers. + */ +extern uint32_t dc0to64[65][10]; + +/** + * Get a difference cover for the requested periodicity v. + */ +template +static EList getDiffCover( + T v, + bool verbose = false, + bool sanityCheck = false) +{ + assert_gt(v, 2); + EList ret; + ret.clear(); + // Can we look it up in our hardcoded array? + if(v <= 64 && dc0to64[v][0] == 0xffffffff) { + if(verbose) cout << "v in hardcoded area, but hardcoded entry was all-fs" << endl; + return ret; + } else if(v <= 64) { + ret.push_back(0); + for(size_t i = 0; i < 10; i++) { + if(dc0to64[v][i] == 0) break; + ret.push_back(dc0to64[v][i]); + } + if(sanityCheck) assert(dcRepOk(v, ret)); + return ret; + } + + // Can we look it up in our calcColbournAndLingDCs array? + if(!clDCs_calced) { + calcColbournAndLingDCs(verbose, sanityCheck); + assert(clDCs_calced); + } + for(size_t i = 0; i < 16; i++) { + if(v <= clDCs[i].maxV) { + for(size_t j = 0; j < clDCs[i].numSamples; j++) { + T s = clDCs[i].samples[j]; + if(s >= v) { + s %= v; + for(size_t k = 0; k < ret.size(); k++) { + if(s == ret[k]) break; + if(s < ret[k]) { + ret.insert(s, k); + break; + } + } + } else { + ret.push_back(s % v); + } + } + if(sanityCheck) assert(dcRepOk(v, ret)); + return ret; + } + } + cerr << "Error: Could not find a difference cover sample for v=" << v << endl; + throw 1; +} + +/** + * Calculate and return a delta map based on the given difference cover + * and periodicity v. + */ +template +static EList getDeltaMap(T v, const EList& dc) { + // Declare anchor-map-related items + EList amap; + size_t amapEnts = 1; + amap.resizeExact((size_t)v); + amap.fill(0xffffffff); + amap[0] = 0; + // Print out difference cover (and optionally calculate + // anchor map) + for(size_t i = 0; i < dc.size(); i++) { + for(size_t j = i+1; j < dc.size(); j++) { + assert_gt(dc[j], dc[i]); + T diffLeft = dc[j] - dc[i]; + T diffRight = dc[i] + v - dc[j]; + assert_lt(diffLeft, v); + assert_lt(diffRight, v); + if(amap[diffLeft] == 0xffffffff) { + amap[diffLeft] = dc[i]; + amapEnts++; + } + if(amap[diffRight] == 0xffffffff) { + amap[diffRight] = dc[j]; + amapEnts++; + } + } + } + return amap; +} + +/** + * Return population count (count of all bits set to 1) of i. + */ +template +static unsigned int popCount(T i) { + unsigned int cnt = 0; + for(size_t j = 0; j < sizeof(T)*8; j++) { + if(i & 1) cnt++; + i >>= 1; + } + return cnt; +} + +/** + * Calculate log-base-2 of i + */ +template +static unsigned int myLog2(T i) { + assert_eq(1, popCount(i)); // must be power of 2 + for(size_t j = 0; j < sizeof(T)*8; j++) { + if(i & 1) return (int)j; + i >>= 1; + } + assert(false); + return 0xffffffff; +} + +/** + * + */ +template +class DifferenceCoverSample { +public: + + DifferenceCoverSample(const TStr& __text, + uint32_t __v, + bool __verbose = false, + bool __sanity = false, + ostream& __logger = cout) : + _text(__text), + _v(__v), + _verbose(__verbose), + _sanity(__sanity), + _ds(getDiffCover(_v, _verbose, _sanity)), + _dmap(getDeltaMap(_v, _ds)), + _d((uint32_t)_ds.size()), + _doffs(), + _isaPrime(), + _dInv(), + _log2v(myLog2(_v)), + _vmask(OFF_MASK << _log2v), + _logger(__logger) + { + assert_gt(_d, 0); + assert_eq(1, popCount(_v)); // must be power of 2 + // Build map from d's to idx's + _dInv.resizeExact((size_t)v()); + _dInv.fill(0xffffffff); + uint32_t lim = (uint32_t)_ds.size(); + for(uint32_t i = 0; i < lim; i++) { + _dInv[_ds[i]] = i; + } + } + + /** + * Allocate an amount of memory that simulates the peak memory + * usage of the DifferenceCoverSample with the given text and v. + * Throws bad_alloc if it's not going to fit in memory. Returns + * the approximate number of bytes the Cover takes at all times. + */ + static size_t simulateAllocs(const TStr& text, uint32_t v) { + EList ds(getDiffCover(v, false /*verbose*/, false /*sanity*/)); + size_t len = text.length(); + size_t sPrimeSz = (len / v) * ds.size(); + // sPrime, sPrimeOrder, _isaPrime all exist in memory at + // once and that's the peak + AutoArray aa(sPrimeSz * 3 + (1024 * 1024 /*out of caution*/), EBWT_CAT); + return sPrimeSz * 4; // sPrime array + } + + uint32_t v() const { return _v; } + uint32_t log2v() const { return _log2v; } + uint32_t vmask() const { return _vmask; } + uint32_t modv(TIndexOffU i) const { return (uint32_t)(i & ~_vmask); } + TIndexOffU divv(TIndexOffU i) const { return i >> _log2v; } + uint32_t d() const { return _d; } + bool verbose() const { return _verbose; } + bool sanityCheck() const { return _sanity; } + const TStr& text() const { return _text; } + const EList& ds() const { return _ds; } + const EList& dmap() const { return _dmap; } + ostream& log() const { return _logger; } + + void build(int nthreads); + uint32_t tieBreakOff(TIndexOffU i, TIndexOffU j) const; + int64_t breakTie(TIndexOffU i, TIndexOffU j) const; + bool isCovered(TIndexOffU i) const; + TIndexOffU rank(TIndexOffU i) const; + + /** + * Print out the suffix array such that every sample offset has its + * rank filled in and every non-sample offset is shown as '-'. + */ + void print(ostream& out) { + for(size_t i = 0; i < _text.length(); i++) { + if(isCovered(i)) { + out << rank(i); + } else { + out << "-"; + } + if(i < _text.length()-1) { + out << ","; + } + } + out << endl; + } + +private: + + void doBuiltSanityCheck() const; + void buildSPrime(EList& sPrime, size_t padding); + + bool built() const { + return _isaPrime.size() > 0; + } + + void verbose(const string& s) const { + if(this->verbose()) { + this->log() << s.c_str(); + this->log().flush(); + } + } + + const TStr& _text; // text to sample + uint32_t _v; // periodicity of sample + bool _verbose; // + bool _sanity; // + EList _ds; // samples: idx -> d + EList _dmap; // delta map + uint32_t _d; // |D| - size of sample + EList _doffs; // offsets into sPrime/isaPrime for each d idx + EList _isaPrime; // ISA' array + EList _dInv; // Map from d -> idx + uint32_t _log2v; + TIndexOffU _vmask; + ostream& _logger; +}; + +/** + * Sanity-check the difference cover by first inverting _isaPrime then + * checking that each successive suffix really is less than the next. + */ +template +void DifferenceCoverSample::doBuiltSanityCheck() const { + uint32_t v = this->v(); + assert(built()); + VMSG_NL(" Doing sanity check"); + TIndexOffU added = 0; + EList sorted; + sorted.resizeExact(_isaPrime.size()); + sorted.fill(OFF_MASK); + for(size_t di = 0; di < this->d(); di++) { + uint32_t d = _ds[di]; + size_t i = 0; + for(size_t doi = _doffs[di]; doi < _doffs[di+1]; doi++, i++) { + assert_eq(OFF_MASK, sorted[_isaPrime[doi]]); + // Maps the offset of the suffix to its rank + sorted[_isaPrime[doi]] = (TIndexOffU)(v*i + d); + added++; + } + } + assert_eq(added, _isaPrime.size()); +#ifndef NDEBUG + for(size_t i = 0; i < sorted.size()-1; i++) { + assert(sstr_suf_lt(this->text(), sorted[i], this->text(), sorted[i+1], false)); + } +#endif +} + +/** + * Build the s' array by sampling suffixes (suffix offsets, actually) + * from t according to the difference-cover sample and pack them into + * an array of machine words in the order dictated by the "mu" mapping + * described in Burkhardt. + * + * Also builds _doffs map. + */ +template +void DifferenceCoverSample::buildSPrime( + EList& sPrime, + size_t padding) +{ + const TStr& t = this->text(); + const EList& ds = this->ds(); + TIndexOffU tlen = (TIndexOffU)t.length(); + uint32_t v = this->v(); + uint32_t d = this->d(); + assert_gt(v, 2); + assert_lt(d, v); + // Record where each d section should begin in sPrime + TIndexOffU tlenDivV = this->divv(tlen); + uint32_t tlenModV = this->modv(tlen); + TIndexOffU sPrimeSz = 0; + assert(_doffs.empty()); + _doffs.resizeExact((size_t)d+1); + for(uint32_t di = 0; di < d; di++) { + // mu mapping + TIndexOffU sz = tlenDivV + ((ds[di] <= tlenModV) ? 1 : 0); + assert_geq(sz, 0); + _doffs[di] = sPrimeSz; + sPrimeSz += sz; + } + _doffs[d] = sPrimeSz; +#ifndef NDEBUG + if(tlenDivV > 0) { + for(size_t i = 0; i < d; i++) { + assert_gt(_doffs[i+1], _doffs[i]); + TIndexOffU diff = _doffs[i+1] - _doffs[i]; + assert(diff == tlenDivV || diff == tlenDivV+1); + } + } +#endif + assert_eq(_doffs.size(), d+1); + // Size sPrime appropriately + sPrime.resizeExact((size_t)sPrimeSz + padding); + sPrime.fill(OFF_MASK); + // Slot suffixes from text into sPrime according to the mu + // mapping; where the mapping would leave a blank, insert a 0 + TIndexOffU added = 0; + TIndexOffU i = 0; + for(uint64_t ti = 0; ti <= tlen; ti += v) { + for(uint32_t di = 0; di < d; di++) { + TIndexOffU tti = (TIndexOffU)ti + (TIndexOffU)ds[di]; + if(tti > tlen) break; + TIndexOffU spi = _doffs[di] + i; + assert_lt(spi, _doffs[di+1]); + assert_leq(tti, tlen); + assert_lt(spi, sPrimeSz); + assert_eq(OFF_MASK, sPrime[spi]); + sPrime[spi] = tti; added++; + } + i++; + } + assert_eq(added, sPrimeSz); +} + +/** + * Return true iff suffixes with offsets suf1 and suf2 out of host + * string 'host' are identical up to depth 'v'. + */ +template +static inline bool suffixSameUpTo( + const TStr& host, + TIndexOffU suf1, + TIndexOffU suf2, + TIndexOffU v) +{ + for(TIndexOffU i = 0; i < v; i++) { + bool endSuf1 = suf1+i >= host.length(); + bool endSuf2 = suf2+i >= host.length(); + if((endSuf1 && !endSuf2) || (!endSuf1 && endSuf2)) return false; + if(endSuf1 && endSuf2) return true; + if(host[suf1+i] != host[suf2+i]) return false; + } + return true; +} + +template +struct VSortingParam { + DifferenceCoverSample* dcs; + TIndexOffU* sPrimeArr; + size_t sPrimeSz; + TIndexOffU* sPrimeOrderArr; + size_t depth; + const EList* boundaries; + size_t* cur; + MUTEX_T* mutex; +}; + +template +static void VSorting_worker(void *vp) +{ + VSortingParam* param = (VSortingParam*)vp; + DifferenceCoverSample* dcs = param->dcs; + const TStr& host = dcs->text(); + const size_t hlen = host.length(); + uint32_t v = dcs->v(); + while(true) { + size_t cur = 0; + { + ThreadSafe ts(param->mutex, true); + cur = *(param->cur); + (*param->cur)++; + } + if(cur >= param->boundaries->size()) return; + size_t begin = (cur == 0 ? 0 : (*param->boundaries)[cur-1]); + size_t end = (*param->boundaries)[cur]; + assert_leq(begin, end); + if(end - begin <= 1) continue; + mkeyQSortSuf2( + host, + hlen, + param->sPrimeArr, + param->sPrimeSz, + param->sPrimeOrderArr, + 4, + begin, + end, + param->depth, + v); + } +} + +/** + * Calculates a ranking of all suffixes in the sample and stores them, + * packed according to the mu mapping, in _isaPrime. + */ +template +void DifferenceCoverSample::build(int nthreads) { + // Local names for relevant types + VMSG_NL("Building DifferenceCoverSample"); + // Local names for relevant data + const TStr& t = this->text(); + uint32_t v = this->v(); + assert_gt(v, 2); + // Build s' + EList sPrime; + // Need to allocate 2 extra elements at the end of the sPrime and _isaPrime + // arrays. One element that's less than all others, and another that acts + // as needed padding for the Larsson-Sadakane sorting code. + size_t padding = 1; + VMSG_NL(" Building sPrime"); + buildSPrime(sPrime, padding); + size_t sPrimeSz = sPrime.size() - padding; + assert_gt(sPrime.size(), padding); + assert_leq(sPrime.size(), t.length() + padding + 1); + TIndexOffU nextRank = 0; + { + VMSG_NL(" Building sPrimeOrder"); + EList sPrimeOrder; + sPrimeOrder.resizeExact(sPrimeSz); + for(TIndexOffU i = 0; i < sPrimeSz; i++) { + sPrimeOrder[i] = i; + } + // sPrime now holds suffix-offsets for DC samples. + { + Timer timer(cout, " V-Sorting samples time: ", this->verbose()); + VMSG_NL(" V-Sorting samples"); + // Extract backing-store array from sPrime and sPrimeOrder; + // the mkeyQSortSuf2 routine works on the array for maximum + // efficiency + TIndexOffU *sPrimeArr = (TIndexOffU*)sPrime.ptr(); + assert_eq(sPrimeArr[0], sPrime[0]); + assert_eq(sPrimeArr[sPrimeSz-1], sPrime[sPrimeSz-1]); + TIndexOffU *sPrimeOrderArr = (TIndexOffU*)sPrimeOrder.ptr(); + assert_eq(sPrimeOrderArr[0], sPrimeOrder[0]); + assert_eq(sPrimeOrderArr[sPrimeSz-1], sPrimeOrder[sPrimeSz-1]); + // Sort sample suffixes up to the vth character using a + // multikey quicksort. Sort time is proportional to the + // number of samples times v. It isn't quadratic. + // sPrimeOrder is passed in as a swapping partner for + // sPrimeArr, i.e., every time the multikey qsort swaps + // elements in sPrime, it swaps the same elements in + // sPrimeOrder too. This allows us to easily reconstruct + // what the sort did. + if(nthreads == 1) { + mkeyQSortSuf2(t, sPrimeArr, sPrimeSz, sPrimeOrderArr, 4, + this->verbose(), this->sanityCheck(), v); + } else { + int query_depth = 0; + int tmp_nthreads = nthreads; + while(tmp_nthreads > 0) { + query_depth++; + tmp_nthreads >>= 1; + } + EList boundaries; // bucket boundaries for parallelization + TIndexOffU *sOrig = NULL; + if(this->sanityCheck()) { + sOrig = new TIndexOffU[sPrimeSz]; + memcpy(sOrig, sPrimeArr, OFF_SIZE * sPrimeSz); + } + mkeyQSortSuf2(t, sPrimeArr, sPrimeSz, sPrimeOrderArr, 4, + this->verbose(), false, query_depth, &boundaries); + if(boundaries.size() > 0) { + AutoArray threads(nthreads); + EList > tparams; + size_t cur = 0; + MUTEX_T mutex; + for(int tid = 0; tid < nthreads; tid++) { + // Calculate bucket sizes by doing a binary search for each + // suffix and noting where it lands + tparams.expand(); + tparams.back().dcs = this; + tparams.back().sPrimeArr = sPrimeArr; + tparams.back().sPrimeSz = sPrimeSz; + tparams.back().sPrimeOrderArr = sPrimeOrderArr; + tparams.back().depth = query_depth; + tparams.back().boundaries = &boundaries; + tparams.back().cur = &cur; + tparams.back().mutex = &mutex; + threads[tid] = new tthread::thread(VSorting_worker, (void*)&tparams.back()); + } + for (int tid = 0; tid < nthreads; tid++) { + threads[tid]->join(); + } + } + if(this->sanityCheck()) { + sanityCheckOrderedSufs(t, t.length(), sPrimeArr, sPrimeSz, v); + for(size_t i = 0; i < sPrimeSz; i++) { + assert_eq(sPrimeArr[i], sOrig[sPrimeOrderArr[i]]); + } + delete[] sOrig; + } + } + // Make sure sPrime and sPrimeOrder are consistent with + // their respective backing-store arrays + assert_eq(sPrimeArr[0], sPrime[0]); + assert_eq(sPrimeArr[sPrimeSz-1], sPrime[sPrimeSz-1]); + assert_eq(sPrimeOrderArr[0], sPrimeOrder[0]); + assert_eq(sPrimeOrderArr[sPrimeSz-1], sPrimeOrder[sPrimeSz-1]); + } + // Now assign the ranking implied by the sorted sPrime/sPrimeOrder + // arrays back into sPrime. + VMSG_NL(" Allocating rank array"); + _isaPrime.resizeExact(sPrime.size()); + ASSERT_ONLY(_isaPrime.fill(OFF_MASK)); + assert_gt(_isaPrime.size(), 0); + { + Timer timer(cout, " Ranking v-sort output time: ", this->verbose()); + VMSG_NL(" Ranking v-sort output"); + for(size_t i = 0; i < sPrimeSz-1; i++) { + // Place the appropriate ranking + _isaPrime[sPrimeOrder[i]] = nextRank; + // If sPrime[i] and sPrime[i+1] are identical up to v, then we + // should give the next suffix the same rank + if(!suffixSameUpTo(t, sPrime[i], sPrime[i+1], v)) nextRank++; + } + _isaPrime[sPrimeOrder[sPrimeSz-1]] = nextRank; // finish off +#ifndef NDEBUG + for(size_t i = 0; i < sPrimeSz; i++) { + assert_neq(OFF_MASK, _isaPrime[i]); + assert_lt(_isaPrime[i], sPrimeSz); + } +#endif + } + // sPrimeOrder is destroyed + // All the information we need is now in _isaPrime + } + _isaPrime[_isaPrime.size()-1] = (TIndexOffU)sPrimeSz; + sPrime[sPrime.size()-1] = (TIndexOffU)sPrimeSz; + // _isaPrime[_isaPrime.size()-1] and sPrime[sPrime.size()-1] are just + // spacer for the Larsson-Sadakane routine to use + { + Timer timer(cout, " Invoking Larsson-Sadakane on ranks time: ", this->verbose()); + VMSG_NL(" Invoking Larsson-Sadakane on ranks"); + if(sPrime.size() >= LS_SIZE) { + cerr << "Error; sPrime array has so many elements that it can't be converted to a signed array without overflow." << endl; + throw 1; + } + LarssonSadakane ls; + ls.suffixsort( + (TIndexOff*)_isaPrime.ptr(), + (TIndexOff*)sPrime.ptr(), + (TIndexOff)sPrimeSz, + (TIndexOff)sPrime.size(), + 0); + } + // chop off final character of _isaPrime + _isaPrime.resizeExact(sPrimeSz); + for(size_t i = 0; i < _isaPrime.size(); i++) { + _isaPrime[i]--; + } +#ifndef NDEBUG + for(size_t i = 0; i < sPrimeSz-1; i++) { + assert_lt(_isaPrime[i], sPrimeSz); + assert(i == 0 || _isaPrime[i] != _isaPrime[i-1]); + } +#endif + VMSG_NL(" Sanity-checking and returning"); + if(this->sanityCheck()) doBuiltSanityCheck(); +} + +/** + * Return true iff index i within the text is covered by the difference + * cover sample. Allow i to be off the end of the text; simplifies + * logic elsewhere. + */ +template +bool DifferenceCoverSample::isCovered(TIndexOffU i) const { + assert(built()); + uint32_t modi = this->modv(i); + assert_lt(modi, _dInv.size()); + return _dInv[modi] != 0xffffffff; +} + +/** + * Given a text offset that's covered, return its lexicographical rank + * among the sample suffixes. + */ +template +TIndexOffU DifferenceCoverSample::rank(TIndexOffU i) const { + assert(built()); + assert_lt(i, this->text().length()); + uint32_t imodv = this->modv(i); + assert_neq(0xffffffff, _dInv[imodv]); // must be in the sample + TIndexOffU ioff = this->divv(i); + assert_lt(ioff, _doffs[_dInv[imodv]+1] - _doffs[_dInv[imodv]]); + TIndexOffU isaIIdx = _doffs[_dInv[imodv]] + ioff; + assert_lt(isaIIdx, _isaPrime.size()); + TIndexOffU isaPrimeI = _isaPrime[isaIIdx]; + assert_leq(isaPrimeI, _isaPrime.size()); + return isaPrimeI; +} + +/** + * Return: < 0 if suffix i is lexicographically less than suffix j; > 0 + * if suffix j is lexicographically greater. + */ +template +int64_t DifferenceCoverSample::breakTie(TIndexOffU i, TIndexOffU j) const { + assert(built()); + assert_neq(i, j); + assert_lt(i, this->text().length()); + assert_lt(j, this->text().length()); + uint32_t imodv = this->modv(i); + uint32_t jmodv = this->modv(j); + assert_neq(0xffffffff, _dInv[imodv]); // must be in the sample + assert_neq(0xffffffff, _dInv[jmodv]); // must be in the sample + uint32_t dimodv = _dInv[imodv]; + uint32_t djmodv = _dInv[jmodv]; + TIndexOffU ioff = this->divv(i); + TIndexOffU joff = this->divv(j); + assert_lt(dimodv+1, _doffs.size()); + assert_lt(djmodv+1, _doffs.size()); + // assert_lt: expected (32024) < (0) + assert_lt(ioff, _doffs[dimodv+1] - _doffs[dimodv]); + assert_lt(joff, _doffs[djmodv+1] - _doffs[djmodv]); + TIndexOffU isaIIdx = _doffs[dimodv] + ioff; + TIndexOffU isaJIdx = _doffs[djmodv] + joff; + assert_lt(isaIIdx, _isaPrime.size()); + assert_lt(isaJIdx, _isaPrime.size()); + assert_neq(isaIIdx, isaJIdx); // ranks must be unique + TIndexOffU isaPrimeI = _isaPrime[isaIIdx]; + TIndexOffU isaPrimeJ = _isaPrime[isaJIdx]; + assert_neq(isaPrimeI, isaPrimeJ); // ranks must be unique + assert_leq(isaPrimeI, _isaPrime.size()); + assert_leq(isaPrimeJ, _isaPrime.size()); + return (int64_t)isaPrimeI - (int64_t)isaPrimeJ; +} + +/** + * Given i, j, return the number of additional characters that need to + * be compared before the difference cover can break the tie. + */ +template +uint32_t DifferenceCoverSample::tieBreakOff(TIndexOffU i, TIndexOffU j) const { + const TStr& t = this->text(); + const EList& dmap = this->dmap(); + assert(built()); + // It's actually convenient to allow this, but we're permitted to + // return nonsense in that case + if(t[i] != t[j]) return 0xffffffff; + //assert_eq(t[i], t[j]); // if they're unequal, there's no tie to break + uint32_t v = this->v(); + assert_neq(i, j); + assert_lt(i, t.length()); + assert_lt(j, t.length()); + uint32_t imod = this->modv(i); + uint32_t jmod = this->modv(j); + uint32_t diffLeft = (jmod >= imod)? (jmod - imod) : (jmod + v - imod); + uint32_t diffRight = (imod >= jmod)? (imod - jmod) : (imod + v - jmod); + assert_lt(diffLeft, dmap.size()); + assert_lt(diffRight, dmap.size()); + uint32_t destLeft = dmap[diffLeft]; // offset where i needs to be + uint32_t destRight = dmap[diffRight]; // offset where i needs to be + assert(isCovered(destLeft)); + assert(isCovered(destLeft+diffLeft)); + assert(isCovered(destRight)); + assert(isCovered(destRight+diffRight)); + assert_lt(destLeft, v); + assert_lt(destRight, v); + uint32_t deltaLeft = (destLeft >= imod)? (destLeft - imod) : (destLeft + v - imod); + if(deltaLeft == v) deltaLeft = 0; + uint32_t deltaRight = (destRight >= jmod)? (destRight - jmod) : (destRight + v - jmod); + if(deltaRight == v) deltaRight = 0; + assert_lt(deltaLeft, v); + assert_lt(deltaRight, v); + assert(isCovered(i+deltaLeft)); + assert(isCovered(j+deltaLeft)); + assert(isCovered(i+deltaRight)); + assert(isCovered(j+deltaRight)); + return min(deltaLeft, deltaRight); +} + +#endif /*DIFF_SAMPLE_H_*/ diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 0000000..18ceadc --- /dev/null +++ b/docs/404.html @@ -0,0 +1,9 @@ +--- +layout: page +title: 404 Not Found +permalink: 404.html +hide: true +share: false +--- + +Sorry, the requested page wasn't found on the server. diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 0000000..f42cd81 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' +gem 'github-pages' +gem 'jekyll-feed' +gem 'jemoji' diff --git a/docs/LICENSE b/docs/LICENSE new file mode 100644 index 0000000..08e721b --- /dev/null +++ b/docs/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Rohan Chandra + +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. \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..19db668 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,59 @@ +# jekyll-ttskch-theme + +A simple and customizable theme for Jekyll. + +> This theme was renamed from _jekyll-**qck**-theme_ to _jekyll-**tch**-theme_ at 2016.06.02. +> And renamed again from _jekyll-**tch**-theme_ to _jekyll-**ttskch**-theme_ at 2016.09.23. + +## Screen shot + +![image](https://cloud.githubusercontent.com/assets/4360663/18776176/62611b38-81a2-11e6-875b-86a66aa8f15c.png) + +## Features + +* A lot of Markdown features (also GitHub Flavored Markdown) +* `:emoji:` ready :+1: +* Easy color-scheme customization +* Tags list page +* Monthly Archives page +* Search feature without any Jekyll plugins +* `` tag feature +* Anchor links for each headings +* Sticky side nav +* Responsive +* OGP ready +* Share buttons ready + +## Getting started + +1. [Fork me](https://github.com/ttskch/jekyll-ttskch-theme/fork) +2. Rename the repository from `jekyll-ttskch-theme` to `{username}.github.io` ([learn more](https://pages.github.com/)) +3. Modify `_config.yml` +4. Modify `_sass/base/_variables.scss` if you need to change colors or font sizes +5. Add new posts into `_posts/` :smiley: + +## Demo + +You can see live demo at below: + +* https://ttskch.github.io/jekyll-ttskch-theme/ + +## Thanks for using :wink: + +* http://ttskch.github.io +* http://sitaramshelke.github.io +* http://jffourmond.github.io +* http://vbflash8.github.io +* http://luqitao.github.io +* http://harusametime.github.io +* http://gitzxon.github.io +* http://hutsonlu.github.io +* http://k0-1.github.io +* http://anthonygore.github.io +* http://getjsdojo.github.io +* http://georgezhuo.github.io +* http://neontapir.github.io +* https://sasukeh.github.io +* https://blog.guilhermegarnier.com + +Please PR if you want to add your blog. diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..6b96528 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,130 @@ +# +# Basic settings. +# +url: http://DaehwanKimLab.github.io +baseurl: /hisat2 +title: HISAT2 +description: graph-based alignment of next generation sequencing reads to a population of genomes +avatar: /assets/img/ogp.png +# favicon: /favicon.ico +favicon: /assets/img/ogp.png +# language: ja +language: en + +# +# Icons +# +icons: + rss: true + email: + github: DaehwanKimLab + bitbucket: + twitter: + facebook: + google_plus: + tumblr: + behance: + dribbble: + flickr: + instagram: + linkedin: # full URL + pinterest: + reddit: + soundcloud: + stack_exchange: # full URL + steam: + wordpress: + youtube: + +# +# default for front matter +# +defaults: + - + scope: + path: "" + values: + category: "main" + + + +# +# Prettify url. +# +permalink: pretty + +# +# Scripts. +# +google_analytics: # e.g. UA-000000-01 +disqus: + +# +# Localizations. +# +str_next: Next +str_prev: Prev +str_read_more: Read more... +str_search: Search +str_recent_posts: Recent posts +str_show_all_posts: Show all posts + +# +# Recent posts. +# +recent_posts_num: 10 + +# +# Pagination. +# +paginate: 10 +paginate_path: page/:num + +# +# Social. +# +share_buttons: + twitter: true + facebook: false # needs ogp.fb.app_id + hatena: false +ogp: + image_url: //ttskch.github.io/jekyll-ttskch-theme/assets/img/ogp.png + fb: + admin: # facebook admin id + app_id: # facebook application id + +# +# Plugins. +# +gems: + - jekyll-paginate + - jekyll-feed + - jemoji + +# +# Styles: see "_sass/base/_variables.scss" +# + +# +# !! Danger zone !! +# + +include: ["_pages"] + +markdown: kramdown +kramdown: + input: GFM + syntax_highlighter: rouge + +excerpt_separator: + +sass: + sass_dir: _sass + style: :compressed # or :expanded + +exclude: + - Gemfile + - Gemfile.lock + - LICENSE + - README.md + - vendor diff --git a/docs/_data/collaborate.yml b/docs/_data/collaborate.yml new file mode 100644 index 0000000..2aef647 --- /dev/null +++ b/docs/_data/collaborate.yml @@ -0,0 +1,6 @@ +- name: Lyda Hill Department of Bioinformatics, The University of Texas Southwestern Medical Center + url: https://www.utsouthwestern.edu/departments/bioinformatics + logo: /assets/img/bioinformatics_utsw_logo.png +- name: Center for Computational Biologoy, Johns Hopkins University + url: http://ccb.jhu.edu + logo: /assets/img/ccb_jhu_logo_tmp.png \ No newline at end of file diff --git a/docs/_data/contributor.yml b/docs/_data/contributor.yml new file mode 100644 index 0000000..ef84e12 --- /dev/null +++ b/docs/_data/contributor.yml @@ -0,0 +1,10 @@ +- name: Chanhee Park + url: /chanhee.park/ +- name: Ben Langmead + url: http://www.langmead-lab.org/ +- name: Yun (Leo) Zhang + url: /leo.zhang/ +- name: Steven Salzberg + url: https://salzberg-lab.org/in-the-news/about-me/ +- name: Daehwan Kim + url: https://kim-lab.org/daehwan-kim-principal-investigator/ diff --git a/docs/_data/download-binary.yml b/docs/_data/download-binary.yml new file mode 100644 index 0000000..eaf5caf --- /dev/null +++ b/docs/_data/download-binary.yml @@ -0,0 +1,66 @@ +latest_version: 2.2.1,2.2.0,2.1.0 +release: + - version: 2.2.1 + date: 7/24/2020 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/fE9QCsX3NH4QwBi/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/zMgEtnF6LjnjFrr/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/oTtGWbWjaxsQ2Ho/download + - version: 2.2.0 + date: 2/6/2020 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-220-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-220-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-220-Linux_x86_64/download + - version: 2.1.0 + date: 6/8/2017 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-210-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-210-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-210-Linux_x86_64/download + Windows: http://www.di.fc.ul.pt/~afalcao/hisat2_windows.html + - version: 2.0.5 + date: 11/4/2016 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-205-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-205-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-205-Linux_x86_64/download + - version: 2.0.4 + date: 5/18/2016 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-204-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-204-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-204-Linux_x86_64/download + - version: 2.0.3-beta + date: 3/28/2016 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-203-beta-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-203-beta-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-203-beta-Linux_x86_64/download + - version: 2.0.2-beta + date: 3/17/2016 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-202-beta-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-202-beta-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-202-beta-Linux_x86_64/download + - version: 2.0.1-beta + date: 11/19/2015 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-201-beta-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-201-beta-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-201-beta-Linux_x86_64/download + - version: 2.0.0-beta + date: 9/8/2015 + name: HISAT2 + artifacts: + Source: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-200-beta-source/download + OSX_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-200-beta-OSX_x86_64/download + Linux_x86_64: https://cloud.biohpc.swmed.edu/index.php/s/hisat2-200-beta-Linux_x86_64/download diff --git a/docs/_data/download-index.yml b/docs/_data/download-index.yml new file mode 100644 index 0000000..ad1f1dd --- /dev/null +++ b/docs/_data/download-index.yml @@ -0,0 +1,81 @@ +- organism: H. sapiens + data: + GRCh38: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/grch38_genome.tar.gz + genome_snp: + url: https://genome-idx.s3.amazonaws.com/hisat/grch38_snp.tar.gz + genome_tran: + url: https://genome-idx.s3.amazonaws.com/hisat/grch38_tran.tar.gz + genome_snp_tran: + url: https://genome-idx.s3.amazonaws.com/hisat/grch38_snptran.tar.gz + genome_rep(above 2.2.0): + url: https://genome-idx.s3.amazonaws.com/hisat/grch38_rep.tar.gz + genome_snp_rep(above 2.2.0): + url: https://genome-idx.s3.amazonaws.com/hisat/grch38_snprep.tar.gz + UCSC hg38: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/hg38_genome.tar.gz + genome_tran: + url: https://genome-idx.s3.amazonaws.com/hisat/hg38_tran.tar.gz + GRCh37: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/grch37_genome.tar.gz + genome_snp: + url: https://genome-idx.s3.amazonaws.com/hisat/grch37_snp.tar.gz + genome_tran: + url: https://genome-idx.s3.amazonaws.com/hisat/grch37_tran.tar.gz + genome_snp_tran: + url: https://genome-idx.s3.amazonaws.com/hisat/grch37_snptran.tar.gz + UCSC hg19: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/hg19_genome.tar.gz +- organism: M. musculus + data: + GRCm38: + genome: + url: https://cloud.biohpc.swmed.edu/index.php/s/grcm38/download + genome_snp: + url: https://cloud.biohpc.swmed.edu/index.php/s/grcm38_snp/download + genome_tran: + url: https://cloud.biohpc.swmed.edu/index.php/s/grcm38_tran/download + genome_snp_tran: + url: https://cloud.biohpc.swmed.edu/index.php/s/grcm38_snp_tran/download + UCSC mm10: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/mm10_genome.tar.gz +- organism: R. norvegicus + data: + UCSC rn6: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/rn6_genome.tar.gz +- organism: D. melanogaster + data: + BDGP6: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/bdgp6.tar.gz + genome_tran: + url: https://genome-idx.s3.amazonaws.com/hisat/bdgp6_tran.tar.gz + UCSC dm6: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/dm6.tar.gz +- organism: C. elegans + data: + WBcel235: + genome: + url: https://genome-idx.s3.amazonaws.com/hisat/wbcel235.tar.gz + genome_tran: + url: https://genome-idx.s3.amazonaws.com/hisat/wbcel235_tran.tar.gz + UCSC ce10: + genome: + url: https://cloud.biohpc.swmed.edu/index.php/s/bbynxoY2TPpRNQb/download +- organism: S. cerevisiae + data: + R64-1-1: + genome: + url: https://cloud.biohpc.swmed.edu/index.php/s/JRSoKHD5cHfpCFE/download + genome_tran: + url: https://cloud.biohpc.swmed.edu/index.php/s/akeiMrGGtt5KoJY/download + UCSC sacCer3: + genome: + url: https://cloud.biohpc.swmed.edu/index.php/s/Gsq4goLW4TDAz4E/download diff --git a/docs/_includes/article-footer.html b/docs/_includes/article-footer.html new file mode 100644 index 0000000..cc9607b --- /dev/null +++ b/docs/_includes/article-footer.html @@ -0,0 +1,5 @@ +

diff --git a/docs/_includes/article-header.html b/docs/_includes/article-header.html new file mode 100644 index 0000000..d876fb0 --- /dev/null +++ b/docs/_includes/article-header.html @@ -0,0 +1,64 @@ +{% assign page = include.page %} + +
+
+

+ {% if include.link %} + {{ page.title }} + {% else %} + {{ page.title }} + {% endif %} +

+ +
    + {% assign tags_num = (page.tags | size) %} + {% if tags_num > 0 %} +
  • + {% endif %} + {% for tag in page.tags %} +
  • + #{{ tag }} +
  • + {% endfor %} +
+ +
+
    + {% if page.date %} +
  • + + {{ page.date | date: "%Y-%m-%d" }} +
  • + {% endif %} + + {% if page.author %} +
  • + + + {{ page.author }} + +
  • + {% if page.icons %} +
  • +
      + {% include icons.html icons=page.icons %} +
    +
  • + {% endif %} + {% endif %} +
+
+
+ + {% if site.share_buttons and include.share != false %} +
+ {% include share-buttons.html page=page %} +
+ {% endif %} + + {% if include.eye_catch != false and page.eye_catch %} +

+ +

+ {% endif %} +
diff --git a/docs/_includes/disqus.html b/docs/_includes/disqus.html new file mode 100644 index 0000000..097f452 --- /dev/null +++ b/docs/_includes/disqus.html @@ -0,0 +1,10 @@ +
+ + diff --git a/docs/_includes/fb-root.html b/docs/_includes/fb-root.html new file mode 100644 index 0000000..6375220 --- /dev/null +++ b/docs/_includes/fb-root.html @@ -0,0 +1,11 @@ + +{% if site.share_buttons.facebook %} +
+ +{% endif %} diff --git a/docs/_includes/google-analytics.html b/docs/_includes/google-analytics.html new file mode 100644 index 0000000..fa7f0e2 --- /dev/null +++ b/docs/_includes/google-analytics.html @@ -0,0 +1,12 @@ + +{% if site.google_analytics %} + +{% endif %} diff --git a/docs/_includes/icons.html b/docs/_includes/icons.html new file mode 100644 index 0000000..dbec897 --- /dev/null +++ b/docs/_includes/icons.html @@ -0,0 +1,161 @@ +{% assign icons = include.icons %} + +{% if icons.rss %} +
  • + + + +
  • +{% endif %} + +{% if icons.email %} +
  • + + + +
  • +{% endif %} + +{% if icons.github %} +
  • + + + +
  • +{% endif %} + +{% if icons.bitbucket %} +
  • + + + +
  • +{% endif %} + +{% if icons.twitter %} +
  • + + + +
  • +{% endif %} + +{% if icons.facebook %} +
  • + + + +
  • +{% endif %} + +{% if icons.google_plus %} +
  • + + + +
  • +{% endif %} + +{% if icons.tumblr %} +
  • + + + +
  • +{% endif %} + +{% if icons.behance %} +
  • + + + +
  • +{% endif %} + +{% if icons.dribbble %} +
  • + + + +
  • +{% endif %} + +{% if icons.flickr %} +
  • + + + +
  • +{% endif %} + +{% if icons.instagram %} +
  • + + + +
  • +{% endif %} + +{% if icons.linkedin %} +
  • + + + +
  • +{% endif %} + +{% if icons.pinterest %} +
  • + + + +
  • +{% endif %} + +{% if icons.reddit %} +
  • + + + +
  • +{% endif %} + +{% if icons.soundcloud %} +
  • + + + +
  • +{% endif %} + +{% if icons.stack_exchange %} +
  • + + + +
  • +{% endif %} + +{% if icons.steam %} +
  • + + + +
  • +{% endif %} + +{% if icons.wordpress %} +
  • + + + +
  • +{% endif %} + +{% if icons.youtube %} +
  • + + + +
  • +{% endif %} diff --git a/docs/_includes/page-url-resolver.html b/docs/_includes/page-url-resolver.html new file mode 100644 index 0000000..f89f26d --- /dev/null +++ b/docs/_includes/page-url-resolver.html @@ -0,0 +1,7 @@ +{% assign page = include.page %} + +{% if page.canonical %} +{% assign url = page.canonical | prepend: site.baseurl | prepend: site.url %} +{% else %} +{% assign url = page.url | replace: 'index.html', '' | prepend: site.baseurl | prepend: site.url %} +{% endif %} diff --git a/docs/_includes/paginator.html b/docs/_includes/paginator.html new file mode 100644 index 0000000..7e736f2 --- /dev/null +++ b/docs/_includes/paginator.html @@ -0,0 +1,29 @@ +{% if paginator.total_pages > 1 %} + +{% endif %} diff --git a/docs/_includes/share-buttons.html b/docs/_includes/share-buttons.html new file mode 100644 index 0000000..0bdd9de --- /dev/null +++ b/docs/_includes/share-buttons.html @@ -0,0 +1,22 @@ +{% include page-url-resolver.html page=include.page %} +{% assign title = include.page.title | append: ' | ' | append: site.title %} +
    +
    + {% if site.share_buttons.twitter %} +
    + + +
    + {% endif %} + {% if site.share_buttons.facebook %} +
    +
    +
    + {% endif %} + {% if site.share_buttons.hatena %} +
    + ã“ã®ã‚¨ãƒ³ãƒˆãƒªãƒ¼ã‚’ã¯ã¦ãªãƒ–ックマークã«è¿½åŠ  +
    + {% endif %} +
    +
    diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 0000000..dbf5ab5 --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,194 @@ + + + + {% capture title %}{% if page.title %}{{ page.title }} | {% endif %}{{ site.title }}{% endcapture %} + + {% include page-url-resolver.html page=page %} + + {% if page.excerpt %} + {% assign description = page.excerpt | strip_html | strip_newlines | truncate: 160 %} + {% else %} + {% assign description = site.description %} + {% endif %} + + + + + + {{ title }} + + + + + + + + {% if page.eye_catch %} + {% assign ogp_image_url = page.eye_catch %} + {% else %} + {% assign ogp_image_url = site.ogp.image_url %} + {% endif %} + + + + + + + + + + + + + + + + + + + + +
    +
    + {{ content }} +
    + + +
    + + + + + + + +{% if page.id %} + +{% endif %} + +{% if page.permalink == '/search/' %} + +{% endif %} + +{% include fb-root.html %} +{% include google-analytics.html %} + + + diff --git a/docs/_layouts/page.html b/docs/_layouts/page.html new file mode 100644 index 0000000..e718aa0 --- /dev/null +++ b/docs/_layouts/page.html @@ -0,0 +1,13 @@ +--- +layout: default +--- + +
    +
    + {% include article-header.html page=page link=false share=page.share %} +
    + {{ content }} +
    + {% include article-footer.html page=page share=page.share %} +
    +
    diff --git a/docs/_layouts/post.html b/docs/_layouts/post.html new file mode 100644 index 0000000..bccaf31 --- /dev/null +++ b/docs/_layouts/post.html @@ -0,0 +1,19 @@ +--- +layout: default +--- + +
    +
    + {% include article-header.html page=page link=false share=page.share %} +
    + {{ content }} +
    + {% include article-footer.html page=page share=page.share %} +
    +
    + +{% if site.disqus %} +
    + {% include disqus.html %} +
    +{% endif %} diff --git a/docs/_pages/about.md b/docs/_pages/about.md new file mode 100644 index 0000000..0ab9f26 --- /dev/null +++ b/docs/_pages/about.md @@ -0,0 +1,9 @@ +--- +layout: page +title: About +permalink: /about/ +order: 2 +share: false +--- + +**HISAT2** is a fast and sensitive alignment program for mapping next-generation sequencing reads (both DNA and RNA) to a population of human genomes as well as to a single reference genome. Based on an extension of BWT for graphs ([Sirén et al. 2014](http://dl.acm.org/citation.cfm?id=2674828)), we designed and implemented a graph FM index (GFM), an original approach and its first implementation. In addition to using one global GFM index that represents a population of human genomes, HISAT2 uses a large set of small GFM indexes that collectively cover the whole genome. These small indexes (called local indexes), combined with several alignment strategies, enable rapid and accurate alignment of sequencing reads. This new indexing scheme is called a Hierarchical Graph FM index (HGFM). diff --git a/docs/_pages/archives-all.html b/docs/_pages/archives-all.html new file mode 100644 index 0000000..f3f0e5e --- /dev/null +++ b/docs/_pages/archives-all.html @@ -0,0 +1,20 @@ +--- +layout: page +title: All Posts +permalink: /archives/all/ +hide: true +share: false +--- + +
    +
    + + {% for post in site.posts %} +
    +
    + {% include article-header.html page=post link=true share=false eye_catch=false %} +
    +
    +
    + {% endfor %} +
    diff --git a/docs/_pages/archives.html b/docs/_pages/archives.html new file mode 100644 index 0000000..5ebb486 --- /dev/null +++ b/docs/_pages/archives.html @@ -0,0 +1,35 @@ +--- +layout: page +title: Archives +permalink: /archives/ +order: 3 +share: false +hide: true +--- + +{% for post in site.posts %} + {% unless post.next %} +

    {{ post.date | date: '%Y' }}

    +
      + {% else %} + {% assign year = post.date | date: '%Y' %} + {% assign next_year = post.next.date | date: '%Y' %} + {% if year != next_year %} +
    +

    {{ post.date | date: '%Y' }}

    +
      + {% endif %} + {% endunless %} + + {% assign month = post.date | date: '%m' %} + {% assign next_month = post.next.date | date: '%m' %} + {% if year != next_year or month != next_month %} +
    • {{ post.date | date: '%Y/%m' }}
    • + {% endif %} +{% endfor %} + +{% if site.posts %} +
    +{% endif %} + +{{ site.str_show_all_posts }} diff --git a/docs/_pages/contributors/chanheepark.md b/docs/_pages/contributors/chanheepark.md new file mode 100644 index 0000000..6201910 --- /dev/null +++ b/docs/_pages/contributors/chanheepark.md @@ -0,0 +1,12 @@ +--- +layout: page +title: Chanhee Park +permalink: /chanhee.park/ +order: 1 +share: false +category: contributor +--- + +Chanhee Park is a Scientific Software Engineer in the Kim Lab at UTSW responsible for maintaining and improving HISAT2. + +[Linkedin](https://www.linkedin.com/in/chanhee-park-97677297/) diff --git a/docs/_pages/contributors/yunleozhang.md b/docs/_pages/contributors/yunleozhang.md new file mode 100644 index 0000000..15d57d0 --- /dev/null +++ b/docs/_pages/contributors/yunleozhang.md @@ -0,0 +1,12 @@ +--- +layout: page +title: Yun (Leo) Zhang +permalink: /leo.zhang/ +order: 1 +share: false +category: contributor +--- + +Yun (Leo) is a biomedical engineering graduate student at UT Southwestern Medical Center. His main research includes developing advance alignment tools. + +[Linkedin](https://www.linkedin.com/in/zhang-yun-a9565891/) diff --git a/docs/_pages/download.md b/docs/_pages/download.md new file mode 100644 index 0000000..672e3bf --- /dev/null +++ b/docs/_pages/download.md @@ -0,0 +1,61 @@ +--- +layout: page +title: Download +permalink: /download/ +order: 5 +share: false +--- + +Please cite: +>Kim, D., Paggi, J.M., Park, C. _et al._ Graph-based genome alignment and genotyping with HISAT2 and HISAT-genotype. _Nat Biotechnol_ **37**, 907–915 (2019). + +- TOC +{:toc} + +## Index +HISAT2 indexes are hosted on AWS (Amazon Web Services), thanks to the AWS Public Datasets program. Click this [link](https://registry.opendata.aws/jhu-indexes/) for more details. + +{% for item in site.data.download-index %} +### {{ item.organism }} + {% for data in item.data %} +
  • {{ data[0] }}
  • + +{% for genome in data[1] %} + + + +{% endfor %} +
    {{ genome[0] }} + {% for url in genome[1] %} + {{ url[1] }}
    + {% endfor %} +
    +{% endfor %} +{% endfor %} + + + genome: HISAT2 index for reference + genome_snp: HISAT2 Graph index for reference plus SNPs + genome_tran: HISAT2 Graph index for reference plus transcripts + genome_snp_tran: HISAT2 Graph index for reference plus SNPs and transcripts + + +## Binaries +{: binaries } + +{% assign targets = site.data.download-binary.latest_version | split: "," %} +{% for release in site.data.download-binary.release %} +{% assign version = release['version'] %} +{% if targets contains version or targets == null %} +{% assign name = release['name'] %} +### Version: {{name}} {{version}} + + +{% for artifact in release['artifacts'] %} +{% assign type = artifact[0] %} + +{% endfor %} +
    Release Date: {{release['date']}}
    {{type}}{{artifact[1]}}
    +{% endif %} +{% endfor %} + diff --git a/docs/_pages/hisat-3n.md b/docs/_pages/hisat-3n.md new file mode 100644 index 0000000..c0ebd65 --- /dev/null +++ b/docs/_pages/hisat-3n.md @@ -0,0 +1,225 @@ +--- +layout: page +title: HISAT-3N +permalink: /hisat-3n/ +order: 4 +share: false +--- + +HISAT-3N +============ + +Overview +----------------- +**HISAT-3N** (hierarchical indexing for spliced alignment of transcripts - 3 nucleotides) +is designed for nucleotide conversion sequencing technologies and implemented based on HISAT2. +There are two strategies for HISAT-3N to align nuleotide conversion sequencing reads: *standard mode* and *repeat mode*. +The standard mode align reads with standard-3N index only, so it is fast and require small memory (~9GB for human genome alignment). +The repeat mode align reads with both standard-3N index and repeat-3N index, then output 1,000 alignment result (the output number can be adjust by `--repeat-limit`). +The repeat mode can align nucleotide conversion reads more accurately, +and it is only 10% slower than the standard mode with tiny more memory (repeat mode use about ~10.5GB) usage than standard mode. + +HISAT-3N is developed based on [HISAT2], which is particularly optimized for RNA sequencing technology. +HISAT-3N can be used for any base-converted sequencing reads include [BS-seq], [SLAM-seq], [TAB-seq], [oxBS-seq], [TAPS], [scBS-seq], and [scSLAM-seq],. + +[HISAT2]:https://github.com/DaehwanKimLab/hisat2 +[BS-seq]: https://en.wikipedia.org/wiki/Bisulfite_sequencing +[SLAM-seq]: https://www.nature.com/articles/nmeth.4435 +[scBS-seq]: https://www.nature.com/articles/nmeth.3035 +[scSLAM-seq]: https://www.nature.com/articles/s41586-019-1369-y +[TAPS]: https://www.nature.com/articles/s41587-019-0041-2 +[TAB-seq]: https://doi.org/10.1016/j.cell.2012.04.027 +[oxBS-seq]: https://science.sciencemag.org/content/336/6083/934 + + +Getting started +============ +HISAT-3N requires a 64-bit computer running either Linux or Mac OS X and at least 16 GB of RAM. + +A few notes: + +1. The repeat 3N index building process requires 256 GB of RAM. +2. The standard 3N index building requires no more than 16 GB of RAM. +3. The alignment process with either standard or repeat index requires no more than 16 GB of RAM. +4. [SAMtools] is required to sort SAM file for hisat-3n-table. + +Install +------------ + + git clone https://github.com/DaehwanKimLab/hisat2.git + cd hisat2 + git checkout -b hisat-3n origin/hisat-3n + make + + +Make sure that you are in the `hisat-3n` branch + + +Build a 3N index with `hisat-3n-build` +----------- +`hisat-3n-build` builds a 3N-index, which contains two hisat2 indexes, from a set of DNA sequences. For standard 3N-index, +each index contains 16 files with suffix `.3n.*.*.ht2`. +For repeat 3N-index, there are 16 more files in addition to the standard 3N-index, and they have the suffix +`.3n.*.rep.*.ht2`. +These files constitute the hisat-3n index and no other file is needed to alignment reads to the reference. + +* Example for standard HISAT-3N index building: +`hisat-3n-build genome.fa genome` + +* Example for repeat HISAT-3N index building (require 256 GB memory): +`hisat-3n-build --repeat-index genome.fa genome` + +It is optional to make the graph index and add SNP or spicing site information to the index, to increase the alignment accuracy. +for more detail, please check the [HISAT2 manual]. + +[HISAT2 manual]:https://daehwankimlab.github.io/hisat2/manual/ + + # Standard HISAT-3N integrated index with SNP information + hisat-3n-build --exons genome.exon genome.fa genome + + # Standard HISAT-3N integrated index with splicing site information + hisat-3n-build --ss genome.ss genome.fa genome + + # Repeat HISAT-3N integrated index with SNP information + hisat-3n-build --repeat-index --exons genome.exon genome.fa genome + + # Repeat HISAT-3N integrated index with splicing site information + hisat-3n-build --repeat-index --ss genome.ss genome.fa genome + +Alignment with `hisat-3n` +------------ +After we build the HISAT-3N index, you are ready to use `hisat-3n` for alignment. +HISAT-3N uses the HISAT2 argument but has some extra arguments. Please check [HISAT2 manual] for more detail. + +For human genome reference, HISAT-3N requires about 9GB for alignment with standard 3N-index and 10.5 GB for repeat 3N-index. + +* `--base-change ` + Provide which base is converted in the sequencing process to another base. Please enter + 2 letters separated by ',' for this argument. The first letter(chr1) should be the converted base, the second letter(chr2) should be + the converted to base. For example, during slam-seq, some 'T' is converted to 'C', + please enter `--base-change T,C`. During bisulfite-seq, some 'C' is converted to 'T', please enter `--base-change C,T`. + If you want to align non-converted reads to the regular HISAT2 index, do not use this option. + +* `--index/-x ` + The index for HISAT-3N. The basename is the name of the index files up to but not including the suffix `.3n.*.*.ht2` / etc. + For example, you build your index with basename 'genome' by HISAT-3N-build, please enter `--index genome`. + +* `--repeat-limit ` + You can set up the number of alignment will be check for each repeat alignment. You may increase the number to let hisat-3n + output more, if a read has multiple mapping. We suggest the repeat limit number for paired-end reads alignment is no more + than 1,000,000. default: 1000. + +* `--unique-only` + Only output uniquely aligned reads. + +#### Examples: +* Single-end slam-seq reads (T to C conversion) alignment with standard 3N-index: +`hisat-3n --index genome -f -U read.fa -S alignment_result.sam --base-change T,C` + +* Paired-end bisulfite-seq reads (C to T conversion) alignment with repeat 3N-index: +`hisat-3n --index genome -f -1 read_1.fa -2 read_2.fa -S alignment_result.sam --base-change C,T` + +* Single-end TAPS reads (have C to T conversion) alignment with repeat 3N-index and only output unique aligned result: +`hisat-3n --index genome -q -U read.fq -S alignment_result.sam --base-change C,T --unique` + + + +#### Extra SAM tags generated by HISAT-3N: + +* `Yf:i:`: Number of conversions are detected in the read. + +* `YZ:A:`: The value `+` or `–` indicate the read is mapped to REF-3N (`+`) or REF-RC-3N (`-`). + +Generate a 3N-conversion-table with `hisat-3n-table` +------------ +### Preparation + +To generate 3N-conversion-table, users need to sort the SAM file which generated by `hisat-3n`. +[SAMtools] is required for this sorting process. + +Use `samtools sort` to convert the SAM file to a sorted SAM file. + + samtools sort alignment_result.sam -o sorted_alignment_result.sam -O sam + +Generate 3N-conversion-table with `hisat-3n-table`: + +### Usage + hisat-3n-table [options]* --alignments --ref --output-name --base-change + +#### Main arguments +* `--alignments ` + SORTED SAM file. Please enter `-` for standard input. + +* `--ref ` + The reference genome file (FASTA format) for generating HISAT-3N index. + +* `--output-name ` + Filename to write 3N-conversion-table (tsv format) to. + +* `--base-change ` + The base-change rule. User should enter the exact same `--base-change` arguments in hisat-3n. + For example, please enter `--base-change C,T` for bisulfite sequencing reads. + +#### Input options +* `-u/--unique-only` + Only count the unique aligned reads into 3N-conversion-table. + +* `-m/--multiple-only` + Only count the multiple aligned reads into 3N-conversion-table. + +* `-c/--CG-only` + Only count the CpG island in reference genome. This option is designed for bisulfite sequencing reads. + +* `-p/--threads ` + Launch `int` parallel threads (default: 1) for table building. + +* `-h/--help` + Print usage information and quit. + + +#### Examples: +* Generate 3N conversion table for bisulfite sequencing data: +`hisat-3n-table -p 16 --alignments sorted_alignment_result.sam --ref genome.fa --output-name output.tsv --base-change C,T` + +* Generate 3N-conversion-table for TAPS data and only count base in CpG island and uniquely aligned: +`hisat-3n-table -p 16 --alignments sorted_alignment_result.sam --ref genome.fa --output-name output.tsv --base-change C,T --CG-only --unique-only` + +* Generate 3N conversion table for bisulfite sequencing data from sorted BAM file: +`samtools view -h sorted_alignment_result.bam | hisat-3n-table --ref genome.fa --alignments - --output-name output.tsv --base-change C,T` + +* Generate 3N conversion table for bisulfite sequencing data from unsorted BAM file: + `samtools sort alignment_result.bam -O sam | hisat-3n-table --ref genome.fa --alignments - --output-name output.tsv --base-change C,T` + + +#### Note: +There are 7 columns in the 3N-conversion-table: + +1. `ref`: the chromosome name. +2. `pos`: 1-based position in ref. +3. `strand`: '+' for forward strand. '-' for reverse strand. +4. `convertedBaseQualities`: the qualities for converted base in read-level measurement. Length of this string is equal to +the number of converted Base in read-level measurement. +5. `convertedBaseCount`: number of distinct read positions where converted base in read-level measurements were found. +this number should equal to the length of convertedBaseQualities. +6. `unconvertedBaseQualities`: the qualities for unconverted base in read-level measurement. Length of this string is equal to +the number of unconverted Base in read-level measurement. +7. `unconvertedBaseCount`: number of distinct read positions where unconverted base in read-level measurements were found. +this number should equal to the length of unconvertedBaseQualities. + +##### Sample 3N-conversion-table: + ref pos strand convertedBaseQualities convertedBaseCount unconvertedBaseQualities unconvertedBaseCount + 1 11874 + FFFFFB5 locations and >100 locations, respectively. Attempting to report all alignments would likely consume a prohibitive amount of disk space. In order to address this issue, our repeat indexing and alignment approach directly aligns reads to repeat sequences, resulting in one repeat alignment per read. HISAT2 provides application programming interfaces (API) for C++, Python, and JAVA that rapidly retrieve genomic locations from repeat alignments for use in downstream analyses. +Other minor bug fixes are also included as follows: + +* Fixed occasional sign (+ or -) issues of template lengths in SAM file +* Fixed duplicate read alignments in SAM file +* Skip a splice site if exon's last base or first base is ambiguous (N) + + +### Index files are moved to a different location. 8/30/2019 + +Due to a high volume of index downloads, we have moved HISAT2 index files to a different location in order to provide faster download speed. If you use wget or curl to download index files, then you may need to use the following commands to get the correct file name. +* `wget --content-disposition` *download_link* +* `curl -OJ` *download_link* + + +### [The HISAT2 paper](https://www.nature.com/articles/s41587-019-0201-4) is out in *Nature Biotechnology*. 8/2/2019 + + +### HISAT 2.1.0 release 6/8/2017 + +* This major version includes the first release of HISAT-genotype, which currently performs HLA typing, + DNA fingerprinting analysis, and CYP typing on whole genome sequencing (WGS) reads. + We plan to extend the system so that it can analyze not just a few genes, but a whole human genome. + Please refer to [the HISAT-genotype website](https://daehwankimlab.github.io/hisat-genotype) for more details. +* HISAT2 can be directly compiled and executed on Windows system using Visual Studio, thanks to [Nigel Dyer](http://www2.warwick.ac.uk/fac/sci/systemsbiology/staff/dyer/). +* Implemented `--new-summary` option to output a new style of alignment summary, which is easier to parse for programming purposes. +* Implemented `--summary-file` option to output alignment summary to a file in addition to the terminal (e.g. stderr). +* Fixed discrepancy in HISAT2’s alignment summary. +* Implemented `--no-templatelen-adjustment` option to disable automatic template length adjustment for RNA-seq reads. + + +### HISAT2 2.0.5 release 11/4/2016 +Version 2.0.5 is a minor release with the following changes. +* Due to a policy change (HTTP to HTTPS) in using SRA data (`--sra-option`), users are strongly encouraged to use this version. As of 11/9/2016, NCBI will begin a permanent redirect to HTTPS, which means the previous versions of HISAT2 no longer works with `--sra-acc` option soon. +* Implemented `-I` and `-X` options for specifying minimum and maximum fragment lengths. The options are valid only when used with `--no-spliced-alignment`, which is used for the alignment of DNA-seq reads. +* Fixed some cases where reads with SNPs on their 5' ends were not properly aligned. +* Implemented `--no-softclip` option to disable soft-clipping. +* Implemented `--max-seeds` to specify the maximum number of seeds that HISAT2 will try to extend to full-length alignments (see [the manual] for details). + + +### [HISAT, StringTie and Ballgown protocol](http://www.nature.com/nprot/journal/v11/n9/full/nprot.2016.095.html) published at Nature Protocols 8/11/2016 + + +### HISAT2 2.0.4 Windows binary available [here](http://www.di.fc.ul.pt/~afalcao/hisat2_windows.html), thanks to [Andre Osorio Falcao](http://www.di.fc.ul.pt/~afalcao/) 5/24/2016 + + +### HISAT2 2.0.4 release 5/18/2016 +Version 2.0.4 is a minor release with the following changes. +* Improved template length estimation (the 9th column of the SAM format) of RNA-seq reads by taking introns into account. +* Introduced two options, `--remove-chrname` and `--add-chrname`, to remove "chr" from reference names or add "chr" to reference names in the alignment output, respectively (the 3rd column of the SAM format). +* Changed the maximum of mapping quality (the 5th column of the SAM format) from 255 to 60. Note that 255 is an undefined value according to the SAM manual and some programs would not work with this value (255) properly. +* Fixed NH (number of hits) in the alignment output. +* HISAT2 allows indels of any length pertaining to minimum alignment score (previously, the maximum length of indels was 3 bp). +* Fixed several cases that alignment goes beyond reference sequences. +* Fixed reporting duplicate alignments. + + +### HISAT2 2.0.3-beta release 3/28/2016 +Version 2.0.3-beta is a minor release with the following changes. +* Fixed graph index building when using both SNPs and transcripts. As a result, genome_snp_tran indexes here on the HISAT2 website have been rebuilt. +* Included some missing files needed to follow the small test example (see [the manual] for details). + + +### HISAT2 2.0.2-beta release 3/17/2016 +**Note (3/19/2016):** this version is slightly updated to handle reporting splice sites with the correct chromosome names. +Version 2.0.2-beta is a major release with the following changes. +* Memory mappaped IO (`--mm` option) works now. +* Building linear index can be now done using multi-threads. +* Changed the minimum score for alignment in keeping with read lengths, so it's now `--score-min L,0.0,-0.2`, meaning a minimum score of -20 for 100-bp reads and -30 for 150-bp reads. +* Fixed a bug that the same read was written into a file multiple times when `--un-conc` was used. +* Fixed another bug that caused reads to map beyond reference sequences. +* Introduced `--haplotype` option in the hisat2-build (index building), which is used with `--snp` option together to incorporate those SNP combinations present in the human population. This option also prevents graph construction from exploding due to exponential combinations of SNPs in small genomic regions. +* Provided a new python script to extract SNPs and haplotypes from VCF files, hisat2_extract_snps_haplotypes_VCF.py +* Changed several python script names as follows< + * *extract_splice_sites.py* to *hisat2_extract_splice_sites.py* + * *extract_exons.py* to *hisat2_extract_exons.py* + * *extract_snps.py* to *hisat2_extract_snps_haplotypes_UCSC.py* + + +### HISAT2 2.0.1-beta release 11/19/2015 +Version 2.0.1-beta is a maintenance release with the following changes. +* Fixed a bug that caused reads to map beyond reference sequences. +* Fixed a deadlock issue that happened very rarely. +* Fixed a bug that led to illegal memory access when reading SNP information. +* Fixed a system-specific bug related to popcount instruction. + + +### HISAT2 2.0.0-beta release 9/8/2015 - first release +We extended the BWT/FM index to incorporate genomic differences among individuals into the reference genome, while keeping memory requirements low enough to fit the entire index onto a desktop computer. Using this novel Hierarchical Graph FM index (HGFM) approach, we built a new alignment system, HISAT2, with an index that incorporates ~12.3M common SNPs from the dbSNP database. HISAT2 provides greater alignment accuracy for reads containing SNPs. +* HISAT2's index size for the human reference genome and 12.3 million common SNPs is 6.2GB (the memory footprint of HISAT2 is 6.7GB). The SNPs consist of 11 million single nucleotide polymorphisms, 728,000 deletions, and 555,000 insertions. The insertions and deletions used in this index are small (usually <20bp). +* HISAT2 comes with several index types: + * Hierarchical FM index (HFM) for a reference genome (index base: genome) + * Hierarchical Graph FM index (HGFM) for a reference genome plus SNPs (index base: genome_snp) + * Hierarchical Graph FM index (HGFM) for a reference genome plus transcripts (index base: genome_tran) + * Hierarchical Graph FM index (HGFM) for a reference genome plus SNPs and transcripts (index base: genome_snp_tran) +* HISAT2 is a successor to both [HISAT](http://ccb.jhu.edu/software/hisat) and [TopHat2](http://ccb.jhu.edu/software/tophat). We recommend that HISAT and TopHat2 users switch to HISAT2. + * HISAT2 can be considered an enhanced version of HISAT with many improvements and bug fixes. The alignment speed and memory requirements of HISAT2 are virtually the same as those of HISAT when using the HFM index (genome). + * When using graph-based indexes (HGFM), the runtime of HISAT2 is slightly slower than HISAT (30~80% additional CPU time). + * HISAT2 allows for mapping reads directly against transcripts, similar to that of TopHat2 (use genome_tran or genome_snp_tran). +* When reads contain SNPs, the SNP information is provided as an optional field in the SAM output of HISAT2 (e.g., **Zs:Z:1|S|rs3747203,97|S|rs16990981** - see [the manual] for details). This feature enables fast and sensitive genotyping in downstream analyses. Note that there is no alignment penalty for mismatches, insertions, and deletions if they correspond to known SNPs. +* HISAT2 provides options for transcript assemblers (e.g., StringTie and Cufflinks) to work better with the alignment from HISAT2 (see options such as `--dta` and `--dta-cufflinks`). +* Some slides about HISAT2 are found [here]({{ '/assets/data/HISAT2-first_release-Sept_8_2015.pdf' | prepend: site.baseurl }}) and we are preparing detailed documention. +* We plan to incorporate a larger set of SNPs and structural variations (SV) into this index (e.g., long insertions/deletions, inversions, and translocations). + +[the manual]: {{ site.baseurl }}{% link _pages/manual.md %} + +### The HISAT2 source code is available in a [public GitHub repository](https://github.com/DaehwanKimLab/hisat2) (5/30/2015). + + diff --git a/docs/_pages/howto.md b/docs/_pages/howto.md new file mode 100644 index 0000000..3fc968d --- /dev/null +++ b/docs/_pages/howto.md @@ -0,0 +1,78 @@ +--- +layout: page +title: HowTo +permalink: /howto/ +order: 6 +share: false +--- + +## HOWTO +{: .no_toc} + +- TOC +{:toc} + +### Building indexes +Depend on your purpose, you have to download reference sequence, gene annotation and SNP files. +We also provides scripts to build indexes. [Download]({{ site.baseurl }}{% link _pages/download.md %}) + +#### Prepare data +1. Download reference +``` +$ wget ftp://ftp.ensembl.org/pub/release-84/fasta/homo_sapiens/dna/Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz +$ gzip -d Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz +$ mv Homo_sapiens.GRCh38.dna.primary_assembly.fa genome.fa +``` + +1. Download GTF and make exon, splicesite file. + If you want to build HFM index, you can skip this step. +``` +$ wget ftp://ftp.ensembl.org/pub/release-84/gtf/homo_sapiens/Homo_sapiens.GRCh38.84.gtf.gz +$ gzip -d Homo_sapiens.GRCh38.84.gtf.gz +$ mv Homo_sapiens.GRCh38.84.gtf genome.gtf +$ hisat2_extract_splice_sites.py genome.gtf > genome.ss +$ hisat2_extract_exons.py genome.gtf > genome.exon +``` + +1. Download SNP + If you want to build HFM index, you can skip this step. +``` +$ wget http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/snp144Common.txt.gz +$ gzip -d snp144Common.txt.gz +``` + + Convert chromosome names of UCSC Database to Ensembl Annotation +``` +$ awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' snp144Common.txt > snp144Common.txt.ensembl +``` + + make SNPs and haplotype file +``` +$ hisat2_extract_snps_haplotypes_UCSC.py genome.fa snp144Common.txt.ensembl genome +``` + +#### Build HFM index +It takes about 20 minutes(depend on HW spec) to build index, and requires at least 6GB memory. +``` +$ hisat2-build -p 16 genome.fa genome +``` + +#### Build HGFM index with SNPs +``` +$ hisat2-build -p 16 --snp genome.snp --haplotype genome.haplotype genome.fa genome_snp +``` + +#### Build HGFM index with transcripts +It takes about 1 hour(depend on HW spec) to build index, and requires at least 160GB memory. +``` +$ hisat2-build -p 16 --exon genome.exon --ss genome.ss genome.fa genome_tran +``` + +#### Build HGFM index with SNPs and transcripts + +``` +$ hisat2-build -p 16 --snp genome.snp --haplotype genome.haplotype --exon genome.exon --ss genome.ss genome.fa genome_snp_tran +``` + + + diff --git a/docs/_pages/links.md b/docs/_pages/links.md new file mode 100644 index 0000000..94a5e8c --- /dev/null +++ b/docs/_pages/links.md @@ -0,0 +1,17 @@ +--- +layout: page +title: Links +permalink: /links/ +order: 7 +share: false +--- + +* KimLab - + * github - +* hisat-genotype - + * github for hisat-genotype - + +* Lyda Hill Department of Bioinformatics at UT Southwestern Medical Center - + +* Center for Computational Biology at Johns Hopkins University - + diff --git a/docs/_pages/manual.md b/docs/_pages/manual.md new file mode 100644 index 0000000..edb7c47 --- /dev/null +++ b/docs/_pages/manual.md @@ -0,0 +1,1545 @@ +--- +layout: page +title: Manual +permalink: /manual/ +order: 3 +share: false +--- + +Introduction +============ + +What is HISAT2? +----------------- + +HISAT2 is a fast and sensitive alignment program for mapping next-generation sequencing reads +(whole-genome, transcriptome, and exome sequencing data) against the general human population +(as well as against a single reference genome). Based on [GCSA] (an extension of [BWT] for a graph), we designed and implemented a graph FM index (GFM), +an original approach and its first implementation to the best of our knowledge. +In addition to using one global GFM index that represents general population, +HISAT2 uses a large set of small GFM indexes that collectively cover the whole genome +(each index representing a genomic region of 56 Kbp, with 55,000 indexes needed to cover human population). +These small indexes (called local indexes) combined with several alignment strategies enable effective alignment of sequencing reads. +This new indexing scheme is called Hierarchical Graph FM index (HGFM). +We have developed HISAT 2 based on the [HISAT] and [Bowtie2] implementations. +HISAT2 outputs alignments in [SAM] format, enabling interoperation with a large number of other tools (e.g. [SAMtools], [GATK]) that use SAM. +HISAT2 is distributed under the [GPLv3 license], and it runs on the command line under +Linux, Mac OS X and Windows. + +[HISAT2]: https://daehwankimlab.github.io/hisat2 +[HISAT]: http://ccb.jhu.edu/software/hisat +[Bowtie2]: http://bowtie-bio.sf.net/bowtie2 +[Bowtie]: http://bowtie-bio.sf.net +[Bowtie1]: http://bowtie-bio.sf.net +[GCSA]: http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=6698337&tag=1 +[Burrows-Wheeler Transform]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[BWT]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[FM Index]: http://en.wikipedia.org/wiki/FM-index +[SAM]: http://samtools.sourceforge.net/SAM1.pdf +[SAMtools]: http://samtools.sourceforge.net +[GATK]: http://www.broadinstitute.org/gsa/wiki/index.php/The_Genome_Analysis_Toolkit +[TopHat2]: http://ccb.jhu.edu/software/tophat +[Cufflinks]: http://cufflinks.cbcb.umd.edu/ +[Crossbow]: http://bowtie-bio.sf.net/crossbow +[Myrna]: http://bowtie-bio.sf.net/myrna +[Bowtie paper]: http://genomebiology.com/2009/10/3/R25 +[GPLv3 license]: http://www.gnu.org/licenses/gpl-3.0.html + + +Obtaining HISAT2 +================== + +Download HISAT2 sources and binaries from the Releases sections on the right side. +Binaries are available for Intel architectures (`x86_64`) running Linux, and Mac OS X. + +Building from source +-------------------- + +Building HISAT2 from source requires a GNU-like environment with GCC, GNU Make +and other basics. It should be possible to build HISAT2 on most vanilla Linux +installations or on a Mac installation with [Xcode] installed. HISAT2 can +also be built on Windows using [Cygwin] or [MinGW] (MinGW recommended). For a +MinGW build the choice of what compiler is to be used is important since this +will determine if a 32 or 64 bit code can be successfully compiled using it. If +there is a need to generate both 32 and 64 bit on the same machine then a multilib +MinGW has to be properly installed. [MSYS], the [zlib] library, and depending on +architecture [pthreads] library are also required. We are recommending a 64 bit +build since it has some clear advantages in real life research problems. In order +to simplify the MinGW setup it might be worth investigating popular MinGW personal +builds since these are coming already prepared with most of the toolchains needed. + +First, download the [source package] from the Download section on the right side. +Unzip the file, change to the unzipped directory, and build the +HISAT2 tools by running GNU `make` (usually with the command `make`, but +sometimes with `gmake`) with no arguments. If building with MinGW, run `make` +from the MSYS environment. + +HISAT2 is using the multithreading software model in order to speed up +execution times on SMP architectures where this is possible. On POSIX +platforms (like linux, Mac OS, etc) it needs the pthread library. Although +it is possible to use pthread library on non-POSIX platform like Windows, due +to performance reasons HISAT2 will try to use Windows native multithreading +if possible. + +For the support of SRA data access in HISAT2, please download and install the [NCBI-NGS] toolkit. +When running `make`, specify additional variables as follow. +`make USE_SRA=1 NCBI_NGS_DIR=/path/to/NCBI-NGS-directory NCBI_VDB_DIR=/path/to/NCBI-NGS-directory`, +where `NCBI_NGS_DIR` and `NCBI_VDB_DIR` will be used in Makefile for `-I` and `-L` compilation options. +For example, `$(NCBI_NGS_DIR)/include` and `$(NCBI_NGS_DIR)/lib64` will be used. + +[Cygwin]: http://www.cygwin.com/ +[MinGW]: http://www.mingw.org/ +[MSYS]: http://www.mingw.org/wiki/msys +[zlib]: http://cygwin.com/packages/mingw-zlib/ +[pthreads]: http://sourceware.org/pthreads-win32/ +[GnuWin32]: http://gnuwin32.sf.net/packages/coreutils.htm +[Download]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/ +[sourceforge site]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/ +[source package]: {{ site.baseurl }}{% link _pages/download.md %} +[Xcode]: http://developer.apple.com/xcode/ +[NCBI-NGS]: https://github.com/ncbi/ngs/wiki/Downloads + +Running HISAT2 +============= + +Adding to PATH +-------------- + +By adding your new HISAT2 directory to your [PATH environment variable], you +ensure that whenever you run `hisat2`, `hisat2-build` or `hisat2-inspect` +from the command line, you will get the version you just installed without +having to specify the entire path. This is recommended for most users. To do +this, follow your operating system's instructions for adding the directory to +your [PATH]. + +If you would like to install HISAT2 by copying the HISAT2 executable files +to an existing directory in your [PATH], make sure that you copy all the +executables, including `hisat2`, `hisat2-align-s`, `hisat2-align-l`, `hisat2-build`, `hisat2-build-s`, `hisat2-build-l`, `hisat2-inspect`, `hisat2-inspect-s` and +`hisat2-inspect-l`. + +[PATH environment variable]: http://en.wikipedia.org/wiki/PATH_(variable) +[PATH]: http://en.wikipedia.org/wiki/PATH_(variable) + +Reporting +--------- + +The reporting mode governs how many alignments HISAT2 looks for, and how to +report them. + +In general, when we say that a read has an alignment, we mean that it has a +[valid alignment]. When we say that a read has multiple alignments, we mean +that it has multiple alignments that are valid and distinct from one another. + +[valid alignment]: #valid-alignments-meet-or-exceed-the-minimum-score-threshold + +By default, HISAT2 may soft-clip reads near their 5' and 3' ends. Users can control this behavior by setting different penalties for soft-clipping ([`--sp`]) or by disallowing soft-clipping ([`--no-softclip`]). + +### Distinct alignments map a read to different places + +Two alignments for the same individual read are "distinct" if they map the same +read to different places. Specifically, we say that two alignments are distinct +if there are no alignment positions where a particular read offset is aligned +opposite a particular reference offset in both alignments with the same +orientation. E.g. if the first alignment is in the forward orientation and +aligns the read character at read offset 10 to the reference character at +chromosome 3, offset 3,445,245, and the second alignment is also in the forward +orientation and also aligns the read character at read offset 10 to the +reference character at chromosome 3, offset 3,445,245, they are not distinct +alignments. + +Two alignments for the same pair are distinct if either the mate 1s in the two +paired-end alignments are distinct or the mate 2s in the two alignments are +distinct or both. + +### Default mode: search for one or more alignments, report each + +HISAT2 searches for up to N distinct, primary alignments for +each read, where N equals the integer specified with the `-k` parameter. +Primary alignments mean alignments whose alignment score is equal or higher than any other alignments. +It is possible that multiple distinct alignments have the same score. +That is, if `-k 2` is specified, HISAT2 will search for at most 2 distinct +alignments. The alignment score for a paired-end alignment equals the sum of the +alignment scores of the individual mates. Each reported read or pair alignment +beyond the first has the SAM 'secondary' bit (which equals 256) set in its FLAGS +field. See the [SAM specification] for details. + +HISAT2 does not "find" alignments in any specific order, so for reads that +have more than N distinct, valid alignments, HISAT2 does not guarantee that +the N alignments reported are the best possible in terms of alignment score. +Still, this mode can be effective and fast in situations where the user cares +more about whether a read aligns (or aligns a certain number of times) than +where exactly it originated. + + +[SAM specification]: http://samtools.sourceforge.net/SAM1.pdf + +Alignment summary +------------------ + +When HISAT2 finishes running, it prints messages summarizing what happened. +These messages are printed to the "standard error" ("stderr") filehandle. For +datasets consisting of unpaired reads, the summary might look like this: + + 20000 reads; of these: + 20000 (100.00%) were unpaired; of these: + 1247 (6.24%) aligned 0 times + 18739 (93.69%) aligned exactly 1 time + 14 (0.07%) aligned >1 times + 93.77% overall alignment rate + +For datasets consisting of pairs, the summary might look like this: + + 10000 reads; of these: + 10000 (100.00%) were paired; of these: + 650 (6.50%) aligned concordantly 0 times + 8823 (88.23%) aligned concordantly exactly 1 time + 527 (5.27%) aligned concordantly >1 times + ---- + 650 pairs aligned concordantly 0 times; of these: + 34 (5.23%) aligned discordantly 1 time + ---- + 616 pairs aligned 0 times concordantly or discordantly; of these: + 1232 mates make up the pairs; of these: + 660 (53.57%) aligned 0 times + 571 (46.35%) aligned exactly 1 time + 1 (0.08%) aligned >1 times + 96.70% overall alignment rate + +The indentation indicates how subtotals relate to totals. + +Wrapper +------- + +The `hisat2`, `hisat2-build` and `hisat2-inspect` executables are actually +wrapper scripts that call binary programs as appropriate. The wrappers shield +users from having to distinguish between "small" and "large" index formats, +discussed briefly in the following section. Also, the `hisat2` wrapper +provides some key functionality, like the ability to handle compressed inputs, +and the functionality for [`--un`], [`--al`] and related options. + +It is recommended that you always run the hisat2 wrappers and not run the +binaries directly. + +Small and large indexes +----------------------- + +`hisat2-build` can index reference genomes of any size. For genomes less than +about 4 billion nucleotides in length, `hisat2-build` builds a "small" index +using 32-bit numbers in various parts of the index. When the genome is longer, +`hisat2-build` builds a "large" index using 64-bit numbers. Small indexes are +stored in files with the `.ht2` extension, and large indexes are stored in +files with the `.ht2l` extension. The user need not worry about whether a +particular index is small or large; the wrapper scripts will automatically build +and use the appropriate index. + +Performance tuning +------------------ + +1. If your computer has multiple processors/cores, use `-p` + The [`-p`] option causes HISAT2 to launch a specified number of parallel + search threads. Each thread runs on a different processor/core and all + threads find alignments in parallel, increasing alignment throughput by + approximately a multiple of the number of threads (though in practice, + speedup is somewhat worse than linear). + +Command Line +------------ + +### Setting function options + +Some HISAT2 options specify a function rather than an individual number or +setting. In these cases the user specifies three parameters: (a) a function +type `F`, (b) a constant term `B`, and (c) a coefficient `A`. The available +function types are constant (`C`), linear (`L`), square-root (`S`), and natural +log (`G`). The parameters are specified as `F,B,A` - that is, the function type, +the constant term, and the coefficient are separated by commas with no +whitespace. The constant term and coefficient may be negative and/or +floating-point numbers. + +For example, if the function specification is `L,-0.4,-0.6`, then the function +defined is: + + f(x) = -0.4 + -0.6 * x + +If the function specification is `G,1,5.4`, then the function defined is: + + f(x) = 1.0 + 5.4 * ln(x) + +See the documentation for the option in question to learn what the parameter `x` +is for. For example, in the case if the [`--score-min`] option, the function +`f(x)` sets the minimum alignment score necessary for an alignment to be +considered valid, and `x` is the read length. + +### Usage + + hisat2 [options]* -x {-1 -2 | -U | --sra-acc } [-S ] + +### Main arguments + +* `-x ` + The basename of the index for the reference genome. The basename is the name of + any of the index files up to but not including the final `.1.ht2` / etc. + `hisat2` looks for the specified index first in the current directory, + then in the directory specified in the `HISAT2_INDEXES` environment variable. +{: #hisat2-options-x} +[`-x`]: #hisat2-options-x + +* `-1 ` + Comma-separated list of files containing mate 1s (filename usually includes + `_1`), e.g. `-1 flyA_1.fq,flyB_1.fq`. Sequences specified with this option must + correspond file-for-file and read-for-read with those specified in ``. Reads + may be a mix of different lengths. If `-` is specified, `hisat2` will read the + mate 1s from the "standard in" or "stdin" filehandle. +{: #hisat2-options-1} +[`-1`]: #hisat2-options-1 + +* `-2 ` + Comma-separated list of files containing mate 2s (filename usually includes + `_2`), e.g. `-2 flyA_2.fq,flyB_2.fq`. Sequences specified with this option must + correspond file-for-file and read-for-read with those specified in ``. Reads + may be a mix of different lengths. If `-` is specified, `hisat2` will read the + mate 2s from the "standard in" or "stdin" filehandle. +{: #hisat2-options-2} +[`-2`]: #hisat2-options-2 + +* `-U ` + Comma-separated list of files containing unpaired reads to be aligned, e.g. + `lane1.fq,lane2.fq,lane3.fq,lane4.fq`. Reads may be a mix of different lengths. + If `-` is specified, `hisat2` gets the reads from the "standard in" or "stdin" + filehandle. +{: #hisat2-options-U} +[`-U`]: #hisat2-options-U + +* `--sra-acc ` + Comma-separated list of SRA accession numbers, e.g. `--sra-acc SRR353653,SRR353654`. + Information about read types is available at http://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi?sp=runinfo&acc=sra-acc&retmode=xml, + where sra-acc is SRA accession number. If users run HISAT2 on a computer cluster, it is recommended to disable SRA-related caching (see the instruction at [SRA-MANUAL]). +{: #hisat2-options-sra-acc} +[`--sra-acc`]: #hisat2-options-sra-acc +[SRA-MANUAL]: https://github.com/ncbi/sra-tools/wiki/Toolkit-Configuration + +* `-S ` + File to write SAM alignments to. By default, alignments are written to the + "standard out" or "stdout" filehandle (i.e. the console). +{: #hisat2-options-S} +[`-S`]: #hisat2-options-S + +### Options + +#### Input options + +* `-q` + Reads (specified with ``, ``, ``) are FASTQ files. FASTQ files + usually have extension `.fq` or `.fastq`. FASTQ is the default format. See + also: [`--solexa-quals`] and [`--int-quals`]. +{: #hisat2-options-q} +[`-q`]: #hisat2-options-q + +* `--qseq` + Reads (specified with ``, ``, ``) are QSEQ files. QSEQ files usually + end in `_qseq.txt`. See also: [`--solexa-quals`] and [`--int-quals`]. +{: #hisat2-options-qseq} +[`--qseq`]: #hisat2-options-qseq + +* `-f` + Reads (specified with ``, ``, ``) are FASTA files. FASTA files + usually have extension `.fa`, `.fasta`, `.mfa`, `.fna` or similar. FASTA files + do not have a way of specifying quality values, so when `-f` is set, the result + is as if `--ignore-quals` is also set. +{: #hisat2-options-f} +[`-f`]: #hisat2-options-f + +* `-r` + Reads (specified with ``, ``, ``) are files with one input sequence + per line, without any other information (no read names, no qualities). When + `-r` is set, the result is as if `--ignore-quals` is also set. +{: #hisat2-options-r} +[`-r`]: #hisat2-options-r + +* `-c` + The read sequences are given on command line. I.e. ``, `` and + `` are comma-separated lists of reads rather than lists of read files. + There is no way to specify read names or qualities, so `-c` also implies + `--ignore-quals`. +{: #hisat2-options-c} +[`-c`]: #hisat2-options-c + +* `-s/--skip ` + Skip (i.e. do not align) the first `` reads or pairs in the input. +{: #hisat2-options-s} +[`-s`/`--skip`]: #hisat2-options-s +[`-s`]: #hisat2-options-s + +* `-u/--upto ` + Align the first `` reads or read pairs from the input (after the + [`-s`/`--skip`] reads or pairs have been skipped), then stop. Default: no limit. +{: #hisat2-options-u} +[`-u`/`--qupto`]: #hisat2-options-u +[`-u`]: #hisat2-options-u + +* `-5/--trim5 ` + Trim `` bases from 5' (left) end of each read before alignment (default: 0). +{: #hisat2-options-5} +[`-5`/`--trim5`]: #hisat2-options-5 +[`-5`]: #hisat2-options-5 + +* `-3/--trim3 ` + Trim `` bases from 3' (right) end of each read before alignment (default: 0). +{: #hisat2-options-3} +[`-3`/`--trim3`]: #hisat2-options-3 +[`-3`]: #hisat2-options-3 + +* `--phred33` + Input qualities are ASCII chars equal to the [Phred quality] plus 33. This is + also called the "Phred+33" encoding, which is used by the very latest Illumina + pipelines. +{: #hisat2-options-phred33-quals} +[`--phred33`]: #hisat2-options-phred33-quals +[Phred quality]: http://en.wikipedia.org/wiki/Phred_quality_score + +* `--phred64` + Input qualities are ASCII chars equal to the [Phred quality] plus 64. This is + also called the "Phred+64" encoding. +{: #hisat2-options-phred64-quals} +[`--phred64`]: #hisat2-options-phred64-quals + +* `--solexa-quals` + Convert input qualities from [Solexa][Phred quality] (which can be negative) to + [Phred][Phred quality] (which can't). This scheme was used in older Illumina GA + Pipeline versions (prior to 1.3). Default: off. +{: #hisat2-options-solexa-quals} +[`--solexa-quals`]: #hisat2-options-solexa-quals + +* `--int-quals` + Quality values are represented in the read input file as space-separated ASCII + integers, e.g., `40 40 30 40`..., rather than ASCII characters, e.g., `II?I`.... + Integers are treated as being on the [Phred quality] scale unless + [`--solexa-quals`] is also specified. Default: off. +{: #hisat2-options-int-quals} +[`--int-quals`]: #hisat2-options-int-quals + +#### Alignment options + +* `--n-ceil ` + Sets a function governing the maximum number of ambiguous characters (usually + `N`s and/or `.`s) allowed in a read as a function of read length. For instance, + specifying `-L,0,0.15` sets the N-ceiling function `f` to `f(x) = 0 + 0.15 * x`, + where x is the read length. See also: [setting function options]. Reads + exceeding this ceiling are [filtered out]. Default: `L,0,0.15`. +{: #hisat2-options-n-ceil} +[`--n-ceil`]: #hisat2-options-n-ceil +[filtered out]: #filtering + +* `--ignore-quals` + When calculating a mismatch penalty, always consider the quality value at the + mismatched position to be the highest possible, regardless of the actual value. + I.e. input is treated as though all quality values are high. This is also the + default behavior when the input doesn't specify quality values (e.g. in [`-f`], + [`-r`], or [`-c`] modes). +{: #hisat2-options-ignore-quals} +[`--ignore-quals`]: #hisat2-options-ignore-quals + +* `--nofw/--norc` + If `--nofw` is specified, `hisat2` will not attempt to align unpaired reads to + the forward (Watson) reference strand. If `--norc` is specified, `hisat2` will + not attempt to align unpaired reads against the reverse-complement (Crick) + reference strand. In paired-end mode, `--nofw` and `--norc` pertain to the + fragments; i.e. specifying `--nofw` causes `hisat2` to explore only those + paired-end configurations corresponding to fragments from the reverse-complement + (Crick) strand. Default: both strands enabled. +{: #hisat2-options-nofw} +[`--nofw`]: #hisat2-options-nofw + +#### Scoring options + +* `--mp MX,MN` + Sets the maximum (`MX`) and minimum (`MN`) mismatch penalties, both integers. A + number less than or equal to `MX` and greater than or equal to `MN` is + subtracted from the alignment score for each position where a read character + aligns to a reference character, the characters do not match, and neither is an + `N`. If [`--ignore-quals`] is specified, the number subtracted quals `MX`. + Otherwise, the number subtracted is `MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) )` + where Q is the Phred quality value. Default: `MX` = 6, `MN` = 2. +{: #hisat2-options-mp} +[`--mp`]: #hisat2-options-mp + +* `--sp MX,MN` + Sets the maximum (`MX`) and minimum (`MN`) penalties for soft-clipping per base, + both integers. A number less than or equal to `MX` and greater than or equal to `MN` is + subtracted from the alignment score for each position. + The number subtracted is `MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) )` + where Q is the Phred quality value. Default: `MX` = 2, `MN` = 1. +{: #hisat2-options-sp} +[`--sp`]: #hisat2-options-sp + +* `--no-softclip` + Disallow soft-clipping. +{: #hisat2-options-no-softclip} +[`--sp`]: #hisat2-options-no-softclip + +* `--np ` + Sets penalty for positions where the read, reference, or both, contain an + ambiguous character such as `N`. Default: 1. +{: #hisat2-options-np} +[`--np`]: #hisat2-options-np + +* `--rdg ,` + Sets the read gap open (``) and extend (``) penalties. A read gap of + length N gets a penalty of `` + N * ``. Default: 5, 3. +{: #hisat2-options-rdg} +[`--rdg`]: #hisat2-options-rdg + +* `--rfg ,` + Sets the reference gap open (``) and extend (``) penalties. A + reference gap of length N gets a penalty of `` + N * ``. Default: + 5, 3. +{: #hisat2-options-rfg} +[`--rfg`]: #hisat2-options-rfg + +* `--score-min ` + Sets a function governing the minimum alignment score needed for an alignment to + be considered "valid" (i.e. good enough to report). This is a function of read + length. For instance, specifying `L,0,-0.6` sets the minimum-score function `f` + to `f(x) = 0 + -0.6 * x`, where `x` is the read length. See also: [setting function options]. The default is `L,0,-0.2`. +{: #hisat2-options-score-min} +[`--score-min`]: #hisat2-options-score-min + +#### Spliced alignment options + +* `--pen-cansplice ` + Sets the penalty for each pair of canonical splice sites (e.g. GT/AG). Default: 0. +{: #hisat2-options-pen-cansplice} +[`--pen-cansplice`]: #hisat2-options-pen-cansplice + +* `--pen-noncansplice ` + Sets the penalty for each pair of non-canonical splice sites (e.g. non-GT/AG). Default: 12. +{: #hisat2-options-pen-noncansplice} +[`--pen-noncansplice`]: #hisat2-options-pen-noncansplice + +* `--pen-canintronlen ` + Sets the penalty for long introns with canonical splice sites so that alignments with shorter introns are preferred + to those with longer ones. Default: G,-8,1 +{: #hisat2-options-pen-canintronlen} +[`--pen-canintronlen`]: #hisat2-options-pen-canintronlen + +* `--pen-noncanintronlen ` + Sets the penalty for long introns with noncanonical splice sites so that alignments with shorter introns are preferred + to those with longer ones. Default: G,-8,1 +{: #hisat2-options-pen-noncanintronlen} +[`--pen-noncanintronlen`]: #hisat2-options-pen-noncanintronlen + +* `--min-intronlen ` + Sets minimum intron length. Default: 20 +{: #hisat2-options-min-intronlen} +[`--min-intronlen`]: #hisat2-options-min-intronlen + +* `--max-intronlen ` + Sets maximum intron length. Default: 500000 +{: #hisat2-options-max-intronlen} +[`--max-intronlen`]: #hisat2-options-max-intronlen + +* `--known-splicesite-infile ` + With this mode, you can provide a list of known splice sites, which HISAT2 makes use of to align reads with small anchors. + You can create such a list using `python hisat2_extract_splice_sites.py genes.gtf > splicesites.txt`, + where `hisat2_extract_splice_sites.py` is included in the HISAT2 package, `genes.gtf` is a gene annotation file, + and `splicesites.txt` is a list of splice sites with which you provide HISAT2 in this mode. + Note that it is better to use indexes built using annotated transcripts (such as genome_tran or genome_snp_tran), which works better + than using this option. It has no effect to provide splice sites that are already included in the indexes. +{: #hisat2-options-known-splicesite-infile} +[`--splice-infile`]: #hisat2-options-known-splicesite-infile + +* `--novel-splicesite-outfile ` + In this mode, HISAT2 reports a list of splice sites in the file : + > chromosome name `` genomic position of the flanking base on the left side of an intron `` genomic position of the flanking base on the right `` strand (+, -, and .) + + '.' indicates an unknown strand for non-canonical splice sites. +{: #hisat2-options-novel-splicesite-outfile} +[`--novel-splicesite-outfile`]: #hisat2-options-novel-splicesite-outfile + +* `--novel-splicesite-infile ` + With this mode, you can provide a list of novel splice sites that were generated from the above option "--novel-splicesite-outfile". +{: #hisat2-options-novel-splicesite-infile} +[`--novel-splicesite-infile`]: #hisat2-options-novel-splicesite-infile + +* `--no-temp-splicesite` + HISAT2, by default, makes use of splice sites found by earlier reads to align later reads in the same run, + in particular, reads with small anchors (<= 15 bp). + The option disables this default alignment strategy. +{: #hisat2-options-no-temp-splicesite} +[`--no-temp-splicesite`]: #hisat2-options-no-temp-splicesite + +* `--no-spliced-alignment` + Disable spliced alignment. +{: #hisat2-options-no-spliced-alignment} +[`--no-spliced-alignment`]: #hisat2-options-no-spliced-alignment + +* `--rna-strandness ` + Specify strand-specific information: the default is unstranded. + For single-end reads, use F or R. + >'F' means a read corresponds to a transcript. + >'R' means a read corresponds to the reverse complemented counterpart of a transcript. + + For paired-end reads, use either FR or RF. + With this option being used, every read alignment will have an XS attribute tag: + >'+' means a read belongs to a transcript on '+' strand of genome. + >'-' means a read belongs to a transcript on '-' strand of genome. + + (TopHat has a similar option, --library-type option, where fr-firststrand corresponds to R and RF; fr-secondstrand corresponds to F and FR.) +{: #hisat2-options-rna-strandness} +[`--rna-strandness`]: #hisat2-options-rna-strandness + +* `--tmo/--transcriptome-mapping-only` + Report only those alignments within known transcripts. +{: #hisat2-options-tmo} +[`--tmo/--transcriptome-mapping-only`]: #hisat2-options-tmo + +* `--dta/--downstream-transcriptome-assembly` + Report alignments tailored for transcript assemblers including StringTie. + With this option, HISAT2 requires longer anchor lengths for de novo discovery of splice sites. + This leads to fewer alignments with short-anchors, + which helps transcript assemblers improve significantly in computation and memory usage. +{: #hisat2-options-dta} +[`--dta/--downstream-transcriptome-assembly`]: #hisat2-options-dta + +* `--dta-cufflinks` + Report alignments tailored specifically for Cufflinks. In addition to what HISAT2 does with the above option (--dta), + With this option, HISAT2 looks for novel splice sites with three signals (GT/AG, GC/AG, AT/AC), but all user-provided splice sites are used irrespective of their signals. + HISAT2 produces an optional field, XS:A:[+-], for every spliced alignment. +{: #hisat2-options-dta-cufflinks} +[`--dta-cufflinks`]: #hisat2-options-dta-cufflinks + +* `--avoid-pseudogene` + Try to avoid aligning reads to pseudogenes. Note this option is experimental and needs further investigation. +{: #hisat2-options-avoid-pseudogene} +[`--avoid-pseudogene`]: #hisat2-options-avoid-pseudogene + +* `--no-templatelen-adjustment` + Disables template length adjustment for RNA-seq reads. +{: #hisat2-options-no-templatelen-adjustment} +[`--no-templatelen-adjustment`]: #hisat2-options-no-templatelen-adjustment + +#### Reporting options + +* `-k ` + It searches for at most `` distinct, primary alignments for each read. + Primary alignments mean alignments whose alignment score is equal to or higher than any other alignments. + The search terminates when it cannot find more distinct valid alignments, or when it + finds ``, whichever happens first. The alignment score for a paired-end + alignment equals the sum of the alignment scores of the individual mates. Each + reported read or pair alignment beyond the first has the SAM 'secondary' bit + (which equals 256) set in its FLAGS field. For reads that have more than + `` distinct, valid alignments, **hisat2** does not guarantee that the + `` alignments reported are the best possible in terms of alignment score. Default: 5 (linear index) or 10 (graph index). +

    + Note: HISAT2 is not designed with large values for `-k` in mind, and when + aligning reads to long, repetitive genomes, large `-k` could make alignment much slower. +{: #hisat2-options-k} +[`-k`]: #hisat2-options-k + +* `--max-seeds ` + HISAT2, like other aligners, uses seed-and-extend approaches. HISAT2 tries to extend seeds to full-length alignments. In HISAT2, `--max-seeds` is used to control the maximum number of seeds that will be extended. For DNA-read alignment ([`--no-spliced-alignment`]), HISAT2 extends up to these many seeds and skips the rest of the seeds. For RNA-read alignment, HISAT2 skips extending seeds and reports no alignments if the number of seeds is larger than the number specified with the option, to be compatible with previous versions of HISAT2. Large values for `--max-seeds` may improve alignment sensitivity, but HISAT2 is not designed with large values for `--max-seeds` in mind, and when aligning reads to long, repetitive genomes, large `--max-seeds` could make alignment much slower. The default value is the maximum of 5 and the value that comes with `-k` times 2. +{: #hisat2-options-max-seeds} +[`--max-seeds`]: #hisat2-options-max-seeds + +* `-a/--all` + HISAT2 reports all alignments it can find. Using the option is equivalent to using both [`--max-seeds`] and [`-k`] with the maximum value that a 64-bit signed integer can represent (9,223,372,036,854,775,807). +{: #hisat2-options-a} +[`-a`/`--all`]: #hisat2-options-a +[`-a`]: #hisat2-options-a + + +* `--secondary` + Report secondary alignments. +{: #hisat2-options-secondary} +[`--secondary`]: #hisat2-options-secondary + +#### Paired-end options + +* `-I/--minins ` + The minimum fragment length for valid paired-end alignments.This option is valid only with [`--no-spliced-alignment`]. + E.g. if `-I 60` is specified and a paired-end alignment consists of two 20-bp alignments in the + appropriate orientation with a 20-bp gap between them, that alignment is + considered valid (as long as [`-X`] is also satisfied). A 19-bp gap would not + be valid in that case. If trimming options [`-3`] or [`-5`] are also used, the + [`-I`] constraint is applied with respect to the untrimmed mates. +

    + The larger the difference between [`-I`] and [`-X`], the slower HISAT2 will + run. This is because larger differences between [`-I`] and [`-X`] require that + HISAT2 scan a larger window to determine if a concordant alignment exists. + For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very + efficient. +

    + Default: 0 (essentially imposing no minimum) +{: #hisat2-options-I} +[`-I`/`--minins`]: #hisat2-options-I +[`-I`]: #hisat2-options-I + +* `-X/--maxins ` + The maximum fragment length for valid paired-end alignments. This option is valid only with [`--no-spliced-alignment`]. + E.g. if `-X 100` is specified and a paired-end alignment consists of two 20-bp alignments in the + proper orientation with a 60-bp gap between them, that alignment is considered + valid (as long as [`-I`] is also satisfied). A 61-bp gap would not be valid in + that case. If trimming options [`-3`] or [`-5`] are also used, the `-X` + constraint is applied with respect to the untrimmed mates, not the trimmed + mates. +

    + The larger the difference between [`-I`] and [`-X`], the slower HISAT2 will + run. This is because larger differences between [`-I`] and [`-X`] require that + HISAT2 scan a larger window to determine if a concordant alignment exists. + For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very + efficient. +

    + Default: 500. +{: #hisat2-options-X} +[`-X`/`--maxins`]: #hisat2-options-X +[`-X`]: #hisat2-options-X + +* `--fr/--rf/--ff` + The upstream/downstream mate orientations for a valid paired-end alignment + against the forward reference strand. E.g., if `--fr` is specified and there is + a candidate paired-end alignment where mate 1 appears upstream of the reverse + complement of mate 2 and the fragment length constraints ([`-I`] and [`-X`]) are + met, that alignment is valid. Also, if mate 2 appears upstream of the reverse + complement of mate 1 and all other constraints are met, that too is valid. + `--rf` likewise requires that an upstream mate1 be reverse-complemented and a + downstream mate2 be forward-oriented. `--ff` requires both an upstream mate 1 + and a downstream mate 2 to be forward-oriented. Default: `--fr` (appropriate + for Illumina's Paired-end Sequencing Assay). +{: #hisat2-options-fr} +[`--fr/--rf/--ff`]: #hisat2-options-fr +[`--fr`]: #hisat2-options-fr +[`--rf`]: #hisat2-options-fr +[`--ff`]: #hisat2-options-fr + +* `--no-mixed` + By default, when `hisat2` cannot find a concordant or discordant alignment for + a pair, it then tries to find alignments for the individual mates. This option + disables that behavior. +{: #hisat2-options-no-mixed} +[`--no-mixed`]: #hisat2-options-no-mixed + +* `--no-discordant` + By default, `hisat2` looks for discordant alignments if it cannot find any + concordant alignments. A discordant alignment is an alignment where both mates + align uniquely, but that does not satisfy the paired-end constraints + ([`--fr/--rf/--ff`], [`-I`], [`-X`]). This option disables that behavior. +{: #hisat2-options-no-discordant} +[`--no-discordant`]: #hisat2-options-no-discordant + +#### Output options + +* `-t/--time` + Print the wall-clock time required to load the index files and align the reads. + This is printed to the "standard error" ("stderr") filehandle. Default: off. +{: #hisat2-options-t} +[`-t`/`--time`]: #hisat2-options-t +[`-t`]: #hisat2-options-t + +* `--un `, `--un-gz `, `--un-bz2 ` + Write unpaired reads that fail to align to file at ``. These reads + correspond to the SAM records with the FLAGS `0x4` bit set and neither the + `0x40` nor `0x80` bits set. If `--un-gz` is specified, output will be gzip + compressed. If `--un-bz2` is specified, output will be bzip2 compressed. Reads + written in this way will appear exactly as they did in the input file, without + any modification (same sequence, same name, same quality string, same quality + encoding). Reads will not necessarily appear in the same order as they did in + the input. +{: #hisat2-options-un} +[`--un`]: #hisat2-options-un +[`--un-gz`]: #hisat2-options-un +[`--un-bz2`]: #hisat2-options-un + +* `--al `, `--al-gz `, `--al-bz2 ` + Write unpaired reads that align at least once to file at ``. These reads + correspond to the SAM records with the FLAGS `0x4`, `0x40`, and `0x80` bits + unset. If `--al-gz` is specified, output will be gzip compressed. If `--al-bz2` + is specified, output will be bzip2 compressed. Reads written in this way will + appear exactly as they did in the input file, without any modification (same + sequence, same name, same quality string, same quality encoding). Reads will + not necessarily appear in the same order as they did in the input. +{: #hisat2-options-al} +[`--al`]: #hisat2-options-al +[`--al-gz`]: #hisat2-options-al +[`--al-bz2`]: #hisat2-options-al + +* `--un-conc `, `--un-conc-gz `, `--un-conc-bz2 ` + Write paired-end reads that fail to align concordantly to file(s) at ``. + These reads correspond to the SAM records with the FLAGS `0x4` bit set and + either the `0x40` or `0x80` bit set (depending on whether it's mate #1 or #2). + `.1` and `.2` strings are added to the filename to distinguish which file + contains mate #1 and mate #2. If a percent symbol, `%`, is used in ``, + the percent symbol is replaced with `1` or `2` to make the per-mate filenames. + Otherwise, `.1` or `.2` are added before the final dot in `` to make the + per-mate filenames. Reads written in this way will appear exactly as they did + in the input files, without any modification (same sequence, same name, same + quality string, same quality encoding). Reads will not necessarily appear in + the same order as they did in the inputs. +{: #hisat2-options-un-conc} +[`--un-conc`]: #hisat2-options-un-conc +[`--un-conc-gz`]: #hisat2-options-un-conc +[`--un-conc-bz2`]: #hisat2-options-un-conc + +* `--al-conc `, `--al-conc-gz `, `--al-conc-bz2 ` + Write paired-end reads that align concordantly at least once to file(s) at + ``. These reads correspond to the SAM records with the FLAGS `0x4` bit + unset and either the `0x40` or `0x80` bit set (depending on whether it's mate #1 + or #2). `.1` and `.2` strings are added to the filename to distinguish which + file contains mate #1 and mate #2. If a percent symbol, `%`, is used in + ``, the percent symbol is replaced with `1` or `2` to make the per-mate + filenames. Otherwise, `.1` or `.2` are added before the final dot in `` to + make the per-mate filenames. Reads written in this way will appear exactly as + they did in the input files, without any modification (same sequence, same name, + same quality string, same quality encoding). Reads will not necessarily appear + in the same order as they did in the inputs. +{: #hisat2-options-al-conc} +[`--al-conc`]: #hisat2-options-al-conc +[`--al-conc-gz`]: #hisat2-options-al-conc +[`--al-conc-bz2`]: #hisat2-options-al-conc + +* `--quiet` + Print nothing besides alignments and serious errors. +{: #hisat2-options-quiet} +[`--quiet`]: #hisat2-options-quiet + +* `--summary-file` + Print alignment summary to this file. +{: #hisat2-options-summary-file} +[`--summary-file`]: #hisat2-options-summary-file + +* `--new-summary` + Print alignment summary in a new style, which is more machine-friendly. +{: #hisat2-options-new-summary} +[`--new-summary`]: #hisat2-options-new-summary + +* `--met-file ` + Write `hisat2` metrics to file ``. Having alignment metric can be useful + for debugging certain problems, especially performance issues. See also: + [`--met`]. Default: metrics disabled. +{: #hisat2-options-met-file} +[`--met-file`]: #hisat2-options-met-file + +* `--met-stderr` + Write `hisat2` metrics to the "standard error" ("stderr") filehandle. This is + not mutually exclusive with [`--met-file`]. Having alignment metric can be + useful for debugging certain problems, especially performance issues. See also: + [`--met`]. Default: metrics disabled. +{: #hisat2-options-met-stderr} +[`--met-stderr`]: #hisat2-options-met-stderr + +* `--met ` + Write a new `hisat2` metrics record every `` seconds. Only matters if + either [`--met-stderr`] or [`--met-file`] are specified. Default: 1. +{: #hisat2-options-met} +[`--met`]: #hisat2-options-met + +#### SAM options + +* `--no-unal` + Suppress SAM records for reads that failed to align. +{: #hisat2-options-no-unal} +[`--no-unal`]: #hisat2-options-no-unal + +* `--no-hd` + Suppress SAM header lines (starting with `@`). +{: #hisat2-options-no-hd} +[`--no-hd`]: #hisat2-options-no-hd + +* `--no-sq` + Suppress `@SQ` SAM header lines. +{: #hisat2-options-no-sq} +[`--no-sq`]: #hisat2-options-no-sq + +* `--rg-id ` + Set the read group ID to ``. This causes the SAM `@RG` header line to be + printed, with `` as the value associated with the `ID:` tag. It also + causes the `RG:Z:` extra field to be attached to each SAM output record, with + value set to ``. +{: #hisat2-options-rg-id} +[`--rg-id`]: #hisat2-options-rg-id + +* `--rg ` + Add `` (usually of the form `TAG:VAL`, e.g. `SM:Pool1`) as a field on the + `@RG` header line. Note: in order for the `@RG` line to appear, [`--rg-id`] + must also be specified. This is because the `ID` tag is required by the [SAM + Spec][SAM]. Specify `--rg` multiple times to set multiple fields. See the + [SAM Spec][SAM] for details about what fields are legal. +{: #hisat2-options-rg} +[`--rg`]: #hisat2-options-rg + +* `--remove-chrname` + Remove 'chr' from reference names in alignment (e.g., chr18 to 18) +{: #hisat2-remove-chrname} +[`--remove-chrname`]: #hisat2-remove-chrname + +* `--add-chrname` + Add 'chr' to reference names in alignment (e.g., 18 to chr18) +{: #hisat2-options-add-chrname} +[`--add-chrname`]: #hisat2-options-add-chrname + +* `--omit-sec-seq` + When printing secondary alignments, HISAT2 by default will write out the `SEQ` + and `QUAL` strings. Specifying this option causes HISAT2 to print an asterisk + in those fields instead. +{: #hisat2-options-omit-sec-seq} +[`--omit-sec-seq`]: #hisat2-options-omit-sec-seq + +#### Performance options + +* `-o/--offrate ` + Override the offrate of the index with ``. If `` is greater + than the offrate used to build the index, then some row markings are + discarded when the index is read into memory. This reduces the memory + footprint of the aligner but requires more time to calculate text + offsets. `` must be greater than the value used to build the + index. +{: #hisat2-options-o} +[`-o`/`--offrate`]: #hisat2-options-o +[`-o`]: #hisat2-options-o +[`--offrate`]: #hisat2-options-o + +* `-p/--threads NTHREADS` + Launch `NTHREADS` parallel search threads (default: 1). Threads will run on + separate processors/cores and synchronize when parsing reads and outputting + alignments. Searching for alignments is highly parallel, and speedup is close + to linear. Increasing `-p` increases HISAT2's memory footprint. E.g. when + aligning to a human genome index, increasing `-p` from 1 to 8 increases the + memory footprint by a few hundred megabytes. This option is only available if + HISAT2 is linked with the `pthreads` library. +{: #hisat2-options-p} +[`-p`/`--threads`]: #hisat2-options-p +[`-p`]: #hisat2-options-p + +* `--reorder` + Guarantees that output SAM records are printed in an order corresponding to the + order of the reads in the original input file, even when [`-p`] is set greater + than 1. Specifying `--reorder` and setting [`-p`] greater than 1 causes HISAT2 + to run somewhat slower and use somewhat more memory then if `--reorder` were + not specified. Has no effect if [`-p`] is set to 1, since output order will + naturally correspond to input order in that case. +{: #hisat2-options-reorder} +[`--reorder`]: #hisat2-options-reorder + +* `--mm` + Use memory-mapped I/O to load the index, rather than typical file I/O. + Memory-mapping allows many concurrent `bowtie` processes on the same computer to + share the same memory image of the index (i.e. you pay the memory overhead just + once). This facilitates memory-efficient parallelization of `bowtie` in + situations where using [`-p`] is not possible or not preferable. +{: #hisat2-options-mm} +[`--mm`]: #hisat2-options-mm + +#### Other options + +* `--qc-filter` + Filter out reads for which the QSEQ filter field is non-zero. Only has an + effect when read format is [`--qseq`]. Default: off. +{: #hisat2-options-qc-filter} +[`--qc-filter`]: #hisat2-options-qc-filter + +* `--seed ` + Use `` as the seed for pseudo-random number generator. Default: 0. +{: #hisat2-options-seed} +[`--seed`]: #hisat2-options-seed + +* `--non-deterministic` + Normally, HISAT2 re-initializes its pseudo-random generator for each read. It + seeds the generator with a number derived from (a) the read name, (b) the + nucleotide sequence, (c) the quality sequence, (d) the value of the [`--seed`] + option. This means that if two reads are identical (same name, same + nucleotides, same qualities) HISAT2 will find and report the same alignment(s) + for both, even if there was ambiguity. When `--non-deterministic` is specified, + HISAT2 re-initializes its pseudo-random generator for each read using the + current time. This means that HISAT2 will not necessarily report the same + alignment for two identical reads. This is counter-intuitive for some users, + but might be more appropriate in situations where the input consists of many + identical reads. +{: #hisat2-options-non-deterministic} +[`--non-deterministic`]: #hisat2-options-non-deterministic + +* `--version` + Print version information and quit. +{: #hisat2-options-version} +[`--version`]: #hisat2-options-version + +* `-h/--help` + Print usage information and quit. +{: #hisat2-options-h} +[`-h`]: #hisat2-options-h + +SAM output +---------- + +Following is a brief description of the [SAM] format as output by `hisat2`. +For more details, see the [SAM format specification][SAM]. + +By default, `hisat2` prints a SAM header with `@HD`, `@SQ` and `@PG` lines. +When one or more [`--rg`] arguments are specified, `hisat2` will also print +an `@RG` line that includes all user-specified [`--rg`] tokens separated by +tabs. + +Each subsequent line describes an alignment or, if the read failed to align, a +read. Each line is a collection of at least 12 fields separated by tabs; from +left to right, the fields are: + + +1. Name of read that aligned. + Note that the [SAM specification] disallows whitespace in the read name. + If the read name contains any whitespace characters, HISAT2 will truncate + the name at the first whitespace character. This is similar to the + behavior of other tools. +2. Sum of all applicable flags. + Flags relevant to HISAT2 are + * 1: The read is one of a pair + * 2: The alignment is one end of a proper paired-end alignment + * 4: The read has no reported alignments + * 8: The read is one of a pair and has no reported alignments + * 16: The alignment is to the reverse reference strand + * 32: The other mate in the paired-end alignment is aligned to the reverse reference strand + * 64: The read is mate 1 in a pair + * 128: The read is mate 2 in a pair + ^ + Thus, an unpaired read that aligns to the reverse reference strand + will have flag 16. A paired-end read that aligns and is the first + mate in the pair will have flag 83 (= 64 + 16 + 2 + 1). +3. Name of reference sequence where alignment occurs +4. 1-based offset into the forward reference strand where leftmost + character of the alignment occurs +5. Mapping quality. Mapping quality of HISAT2 +6. CIGAR string representation of alignment +7. Name of reference sequence where mate's alignment occurs. Set to `=` if the +mate's reference sequence is the same as this alignment's, or `*` if there is no +mate. +8. 1-based offset into the forward reference strand where leftmost character of +the mate's alignment occurs. Offset is 0 if there is no mate. +9. Inferred fragment length. Size is negative if the mate's alignment occurs +upstream of this alignment. Size is 0 if the mates did not align concordantly. +However, size is non-0 if the mates aligned discordantly to the same +chromosome. +10. Read sequence (reverse-complemented if aligned to the reverse strand) +11. ASCII-encoded read qualities (reverse-complemented if the read aligned to +the reverse strand). The encoded quality values are on the [Phred quality] +scale and the encoding is ASCII-offset by 33 (ASCII char `!`), similarly to a +[FASTQ] file. +12. Optional fields. Fields are tab-separated. `hisat2` outputs zero or more +of these optional fields for each alignment, depending on the type of the +alignment: + * {: #hisat2-opt-fields-as} `AS:i:` : Alignment score. Can be negative. Only present if SAM record is for + an aligned read. + * {: #hisat2-opt-fields-xs} `ZS:i:` : Alignment score for the best-scoring alignment found other than the + alignment reported. Can be negative. Only present if the SAM record is + for an aligned read and more than one alignment was found for the read. + Note that, when the read is part of a concordantly-aligned pair, this score + could be greater than [`AS:i`]. + * {: #hisat2-opt-fields-ys} `YS:i:` : Alignment score for opposite mate in the paired-end alignment. Only present + if the SAM record is for a read that aligned as part of a paired-end + alignment. + * {: #hisat2-opt-fields-xn} `XN:i:` : The number of ambiguous bases in the reference covering this alignment. + Only present if SAM record is for an aligned read. + * {: #hisat2-opt-fields-xm} `XM:i:` : The number of mismatches in the alignment. Only present if SAM record is + for an aligned read. + * {: #hisat2-opt-fields-xo} `XO:i:` : The number of gap opens, for both read and reference gaps, in the alignment. + Only present if SAM record is for an aligned read. + * {: #hisat2-opt-fields-xg} `XG:i:` : The number of gap extensions, for both read and reference gaps, in the + alignment. Only present if SAM record is for an aligned read. + * {: #hisat2-opt-fields-nm} `NM:i:` : The edit distance; that is, the minimal number of one-nucleotide edits + (substitutions, insertions and deletions) needed to transform the read + string into the reference string. Only present if SAM record is for an + aligned read. + * {: #hisat2-opt-fields-yf} `YF:Z:` : String indicating reason why the read was filtered out. See also: + [Filtering]. Only appears for reads that were filtered out. + * {: #hisat2-opt-fields-yt} `YT:Z:` : Value of `UU` indicates the read was not part of a pair. Value of `CP` + indicates the read was part of a pair and the pair aligned concordantly. + Value of `DP` indicates the read was part of a pair and the pair aligned + discordantly. Value of `UP` indicates the read was part of a pair but the + pair failed to aligned either concordantly or discordantly. + * {: #hisat2-opt-fields-md} `MD:Z:` : A string representation of the mismatched reference bases in the alignment. + See [SAM] format specification for details. Only present if SAM record is + for an aligned read. + * {: #hisat2-opt-fields-xs} `XS:A:` : Values of `+` and `-` indicate the read is mapped to transcripts on sense and anti-sense + strands, respectively. Spliced alignments need to have this field, which is required in Cufflinks and StringTie. + We can report this field for the canonical-splice site (GT/AG), but not for non-canonical splice sites. + You can direct HISAT2 not to output such alignments (involving non-canonical splice sites) using "--pen-noncansplice 1000000". + * {: #hisat2-opt-fields-nh} `NH:i:` : The number of mapped locations for the read or the pair. + * {: #hisat2-opt-fields-Zs} `Zs:Z:` : When the alignment of a read involves SNPs that are in the index, this option is used to indicate where exactly the read involves the SNPs. + This optional field is similar to the above MD:Z field. + For example, `Zs:Z:1|S|rs3747203,97|S|rs16990981` indicates the second base of the read corresponds to a known SNP (ID: rs3747203). + 97 bases after the third base (the base after the second one), the read at 100th base involves another known SNP (ID: rs16990981). + 'S' indicates a single nucleotide polymorphism. 'D' and 'I' indicate a deletion and an insertion, respectively. + +[SAM format specification]: http://samtools.sf.net/SAM1.pdf +[FASTQ]: http://en.wikipedia.org/wiki/FASTQ_format +[`-S`/`--sam`]: #hisat2-options-S +[`-m`]: #hisat2-options-m +[`AS:i`]: #hisat2-opt-fields-as +[`ZS:i`]: #hisat2-opt-fields-xs +[`YS:i`]: #hisat2-opt-fields-ys +[`XN:i`]: #hisat2-opt-fields-xn +[`XM:i`]: #hisat2-opt-fields-xm +[`XO:i`]: #hisat2-opt-fields-xo +[`XG:i`]: #hisat2-opt-fields-xg +[`NM:i`]: #hisat2-opt-fields-nm +[`YF:Z`]: #hisat2-opt-fields-yf +[`YT:Z`]: #hisat2-opt-fields-yt +[`MD:Z`]: #hisat2-opt-fields-md +[`XS:A`]: #hisat2-opt-fields-xs +[`NH:i`]: #hisat2-opt-fields-nh +[`Zs:Z`]: #hisat2-opt-fields-Zs + +The `hisat2-build` indexer +=========================== + +`hisat2-build` builds a HISAT2 index from a set of DNA sequences. +`hisat2-build` outputs a set of 6 files with suffixes `.1.ht2`, `.2.ht2`, +`.3.ht2`, `.4.ht2`, `.5.ht2`, `.6.ht2`, `.7.ht2`, and `.8.ht2`. In the case of a large +index these suffixes will have a `ht2l` termination. These files together +constitute the index: they are all that is needed to align reads to that +reference. The original sequence FASTA files are no longer used by HISAT2 +once the index is built. + +Use of Karkkainen's [blockwise algorithm] allows `hisat2-build` to trade off +between running time and memory usage. `hisat2-build` has three options +governing how it makes this trade: [`-p`/`--packed`], [`--bmax`]/[`--bmaxdivn`], +and [`--dcv`]. By default, `hisat2-build` will automatically search for the +settings that yield the best running time without exhausting memory. This +behavior can be disabled using the [`-a`/`--noauto`] option. + +The indexer provides options pertaining to the "shape" of the index, e.g. +[`--offrate`](#hisat2-build-options-o) governs the fraction of [Burrows-Wheeler] +rows that are "marked" (i.e., the density of the suffix-array sample; see the +original [FM Index] paper for details). All of these options are potentially +profitable trade-offs depending on the application. They have been set to +defaults that are reasonable for most cases according to our experiments. See +[Performance tuning] for details. + +`hisat2-build` can generate either [small or large indexes](#small-and-large-indexes). The wrapper +will decide which based on the length of the input genome. If the reference +does not exceed 4 billion characters but a large index is preferred, the user +can specify [`--large-index`] to force `hisat2-build` to build a large index +instead. + +The HISAT2 index is based on the [FM Index] of Ferragina and Manzini, which in +turn is based on the [Burrows-Wheeler] transform. The algorithm used to build +the index is based on the [blockwise algorithm] of Karkkainen. + +[Blockwise algorithm]: http://portal.acm.org/citation.cfm?id=1314852 +[Burrows-Wheeler]: http://en.wikipedia.org/wiki/Burrows-Wheeler_transform +[Performance tuning]: #performance-tuning + +Command Line +------------ + +Usage: + + hisat2-build [options]* + +### Notes + If you use --snp, --ss, and/or --exon, hisat2-build will need about 200GB RAM for the human genome size as index building involves a graph construction. + Otherwise, you will be able to build an index on your desktop with 8GB RAM. + +### Main arguments + +* `` + A comma-separated list of FASTA files containing the reference sequences to be + aligned to, or, if [`-c`](#hisat2-build-options-c) is specified, the sequences + themselves. E.g., `` might be `chr1.fa,chr2.fa,chrX.fa,chrY.fa`, + or, if [`-c`](#hisat2-build-options-c) is specified, this might be + `GGTCATCCT,ACGGGTCGT,CCGTTCTATGCGGCTTA`. +{: #hisat2-build-options-ref} + +* `` + The basename of the index files to write. By default, `hisat2-build` writes + files named `NAME.1.ht2`, `NAME.2.ht2`, `NAME.3.ht2`, `NAME.4.ht2`, + `NAME.5.ht2`, `NAME.6.ht2`, `NAME.7.ht2`, and `NAME.8.ht2` where `NAME` is ``. +{: #hisat2-build-options-base} + +### Options + +* `-f` + The reference input files (specified as ``) are FASTA files + (usually having extension `.fa`, `.mfa`, `.fna` or similar). +{: #hisat2-build-options-f} + +* `-c` + The reference sequences are given on the command line. I.e. `` is + a comma-separated list of sequences rather than a list of FASTA files. +{: #hisat2-build-options-c} + +* `--large-index` + Force `hisat2-build` to build a [large index](#small-and-large-indexes), even if the reference is less + than ~ 4 billion nucleotides long. +{: #hisat2-build-options-large-index} +[`--large-index`]: #hisat2-build-options-large-index + +* `-a/--noauto` + Disable the default behavior whereby `hisat2-build` automatically selects + values for the [`--bmax`], [`--dcv`] and [`--packed`] parameters according to + available memory. Instead, user may specify values for those parameters. If + memory is exhausted during indexing, an error message will be printed; it is up + to the user to try new parameters. +{: #hisat2-build-options-a} +[`-a`/`--noauto`]: #hisat2-build-options-a + +* `--bmax ` + The maximum number of suffixes allowed in a block. Allowing more suffixes per + block makes indexing faster, but increases peak memory usage. Setting this + option overrides any previous setting for [`--bmax`], or [`--bmaxdivn`]. + Default (in terms of the [`--bmaxdivn`] parameter) is [`--bmaxdivn`] 4. This is + configured automatically by default; use [`-a`/`--noauto`] to configure manually. +{: #hisat2-build-options-bmax} +[`--bmax`]: #hisat2-build-options-bmax + +* `--bmaxdivn ` + The maximum number of suffixes allowed in a block, expressed as a fraction of + the length of the reference. Setting this option overrides any previous setting + for [`--bmax`], or [`--bmaxdivn`]. Default: [`--bmaxdivn`] 4. This is + configured automatically by default; use [`-a`/`--noauto`] to configure manually. +{: #hisat2-build-options-bmaxdivn} +[`--bmaxdivn`]: #hisat2-build-options-bmaxdivn + +* `--dcv ` + Use `` as the period for the difference-cover sample. A larger period + yields less memory overhead, but may make suffix sorting slower, especially if + repeats are present. Must be a power of 2 no greater than 4096. Default: 1024. + This is configured automatically by default; use [`-a`/`--noauto`] to configure + manually. +{: #hisat2-build-options-dcv} +[`--dcv`]: #hisat2-build-options-dcv + +* `--nodc` + Disable use of the difference-cover sample. Suffix sorting becomes + quadratic-time in the worst case (where the worst case is an extremely + repetitive reference). Default: off. +{: #hisat2-build-options-nodc} +[`--nodc`]: #hisat2-build-options-nodc + +* `-r/--noref` + Do not build the `NAME.3.ht2` and `NAME.4.ht2` portions of the index, which + contain a bitpacked version of the reference sequences and are used for + paired-end alignment. +{: #hisat2-build-options-r} + +* `-3/--justref` + Build only the `NAME.3.ht2` and `NAME.4.ht2` portions of the index, which + contain a bitpacked version of the reference sequences and are used for + paired-end alignment. +{: #hisat2-build-options-3} + +* `-o/--offrate ` + To map alignments back to positions on the reference sequences, it's necessary + to annotate ("mark") some or all of the [Burrows-Wheeler] rows with their + corresponding location on the genome. + [`-o`/`--offrate`](#hisat2-build-options-o) governs how many rows get marked: + the indexer will mark every 2^`` rows. Marking more rows makes + reference-position lookups faster, but requires more memory to hold the + annotations at runtime. The default is 4 (every 16th row is marked; for human + genome, annotations occupy about 680 megabytes). +{: #hisat2-build-options-o} + +* `-t/--ftabchars ` + The ftab is the lookup table used to calculate an initial [Burrows-Wheeler] + range with respect to the first `` characters of the query. A larger + `` yields a larger lookup table but faster query times. The ftab has size + 4^(``+1) bytes. The default setting is 10 (ftab is 4MB). +{: #hisat2-build-options-t} + +* `--localoffrate ` + This option governs how many rows get marked in a local index: + the indexer will mark every 2^`` rows. Marking more rows makes + reference-position lookups faster, but requires more memory to hold the + annotations at runtime. The default is 3 (every 8th row is marked, + this occupies about 16KB per local index). +{: #hisat2-build-options-localoffrate} + +* `--localftabchars ` + The local ftab is the lookup table in a local index. + The default setting is 6 (ftab is 8KB per local index). +{: #hisat2-build-options-localftabchars} + +* `-p ` + Launch `NTHREADS` parallel build threads (default: 1). +{: #hisat2-build-options-p} + +* `--snp ` + Provide a list of SNPs (in the HISAT2's own format) as follows (five columns). + + SNP ID snp type (single, deletion, or insertion) chromosome name zero-offset based genomic position of a SNP alternative base (single), the length of SNP (deletion), or insertion sequence (insertion) + + For example, + + rs58784443 single 13 18447947 T + + Use `hisat2_extract_snps_haplotypes_UCSC.py` (in the HISAT2 package) to extract SNPs and haplotypes from a dbSNP file (e.g. http://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/snp144Common.txt.gz). + or `hisat2_extract_snps_haplotypes_VCF.py` to extract SNPs and haplotypes from a VCF file (e.g. ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502/supporting/GRCh38_positions/ALL.chr22.phase3_shapeit2_mvncall_integrated_v3plus_nounphased.rsID.genotypes.GRCh38_dbSNP_no_SVs.vcf.gz). +{: #hisat2-build-options-snp} + +* `--haplotype ` + Provide a list of haplotypes (in the HISAT2's own format) as follows (five columns). + + Haplotype ID chromosome name zero-offset based left coordinate of haplotype zero-offset based right coordinate of haplotype a comma separated list of SNP ids in the haplotype + + For example, + + ht35 13 18446877 18446945 rs12381094,rs12381056,rs192016659,rs538569910 + + See the above option, --snp, about how to extract haplotypes. This option is not required, but haplotype information can keep the index construction from exploding and reduce the index size substantially. +{: #hisat2-build-options-haplotype} + +* `--ss ` + Note this option should be used with the following [`--exon`](#hisat2-build-options-exon) option. + Provide a list of splice sites (in the HISAT2's own format) as follows (four columns). + + chromosome name zero-offset based genomic position of the flanking base on the left side of an intron zero-offset based genomic position of the flanking base on the right strand + + Use `hisat2_extract_splice_sites.py` (in the HISAT2 package) to extract splice sites from a GTF file. +{: #hisat2-build-options-ss} + +* `--exon ` + Note this option should be used with the above [`--ss`](#hisat2-build-options-ss) option. + Provide a list of exons (in the HISAT2's own format) as follows (three columns). + + chromosome name zero-offset based left genomic position of an exon zero-offset based right genomic position of an exon + + Use `hisat2_extract_exons.py` (in the HISAT2 package) to extract exons from a GTF file. +{: #hisat2-build-options-exon} + +* `--seed ` + Use `` as the seed for pseudo-random number generator. +{: #hisat2-build-options-seed} + +* `--cutoff ` + Index only the first `` bases of the reference sequences (cumulative across + sequences) and ignore the rest. +{: #hisat2-build-options-cutoff} + +* `-q/--quiet` + `hisat2-build` is verbose by default. With this option `hisat2-build` will + print only error messages. +{: #hisat2-build-options-q} + +* `-h/--help` + Print usage information and quit. +{: #hisat2-build-options-h} + +* `--version` + Print version information and quit. +{: #hisat2-build-options-version} + +The `hisat2-inspect` index inspector +===================================== + +`hisat2-inspect` extracts information from a HISAT2 index about what kind of +index it is and what reference sequences were used to build it. When run without +any options, the tool will output a FASTA file containing the sequences of the +original references (with all non-`A`/`C`/`G`/`T` characters converted to `N`s). + It can also be used to extract just the reference sequence names using the +[`-n`/`--names`] option or a more verbose summary using the [`-s`/`--summary`] +option. + +Command Line +------------ + +Usage: + + hisat2-inspect [options]* + +### Main arguments + +* `` + The basename of the index to be inspected. The basename is name of any of the + index files but with the `.X.ht2` suffix omitted. + `hisat2-inspect` first looks in the current directory for the index files, then + in the directory specified in the `HISAT2_INDEXES` environment variable. +{: #hisat2-inspect-options-base} + +### Options + +* `-a/--across ` + When printing FASTA output, output a newline character every `` bases + (default: 60). +{: #hisat2-inspect-options-a} + +* `-n/--names` + Print reference sequence names, one per line, and quit. +{: #hisat2-inspect-options-n} +[`-n`/`--names`]: #hisat2-inspect-options-n + +* `-s/--summary` + Print a summary that includes information about index settings, as well as the + names and lengths of the input sequences. The summary has this format: + + Colorspace <0 or 1> + SA-Sample 1 in + FTab-Chars + Sequence-1 + Sequence-2 + ... + Sequence-N + + Fields are separated by tabs. Colorspace is always set to 0 for HISAT2. +{: #hisat2-inspect-options-s} +[`-s`/`--summary`]: #hisat2-inspect-options-s + +* `--snp` + Print SNPs, and quit. +{: #hisat2-inspect-options-snp} +[`--snp`]: #hisat2-inspect-options-snp + +* `--ss` + Print splice sites, and quit. +{: #hisat2-inspect-options-ss} +[`--ss`]: #hisat2-inspect-options-ss + +* `--ss-all` + Print splice sites including those not in the global index, and quit. +{: #hisat2-inspect-options-ss-all} +[`--ss-all`]: #hisat2-inspect-options-ss-all + +* `--exon` + Print exons, and quit. +{: #hisat2-inspect-options-exon} +[`--exon`]: #hisat2-inspect-options-exon + +* `-v/--verbose` + Print verbose output (for debugging). + +* `--version` + Print version information and quit. + +* `-h/--help` + Print usage information and quit. + + +Getting started with HISAT2 +=================================================== + +HISAT2 comes with some example files to get you started. The example files +are not scientifically significant; these files will simply let you start running HISAT2 and +downstream tools right away. + +First follow the manual instructions to [obtain HISAT2]. Set the `HISAT2_HOME` +environment variable to point to the new HISAT2 directory containing the +`hisat2`, `hisat2-build` and `hisat2-inspect` binaries. This is important, +as the `HISAT2_HOME` variable is used in the commands below to refer to that +directory. + +[obtain HISAT2]: #obtaining-hisat2 + +Indexing a reference genome +--------------------------- + +To create an index for the genomic region (1 million bps from the human chromosome 22 between 20,000,000 and 20,999,999) +included with HISAT2, create a new temporary directory (it doesn't matter where), change into that directory, and run: + + $HISAT2_HOME/hisat2-build $HISAT2_HOME/example/reference/22_20-21M.fa --snp $HISAT2_HOME/example/reference/22_20-21M.snp 22_20-21M_snp + +The command should print many lines of output then quit. When the command +completes, the current directory will contain ten new files that all start with +`22_20-21M_snp` and end with `.1.ht2`, `.2.ht2`, `.3.ht2`, `.4.ht2`, `.5.ht2`, `.6.ht2`, +`.7.ht2`, and `.8.ht2`. These files constitute the index - you're done! + +You can use `hisat2-build` to create an index for a set of FASTA files obtained +from any source, including sites such as [UCSC], [NCBI], and [Ensembl]. When +indexing multiple FASTA files, specify all the files using commas to separate +file names. For more details on how to create an index with `hisat2-build`, +see the [manual section on index building]. You may also want to bypass this +process by obtaining a pre-built index. + +[UCSC]: http://genome.ucsc.edu/cgi-bin/hgGateway +[NCBI]: http://www.ncbi.nlm.nih.gov/sites/genome +[Ensembl]: http://www.ensembl.org/ +[manual section on index building]: #the-hisat2-build-indexer +[using a pre-built index]: #using-a-pre-built-index + +Aligning example reads +---------------------- + +Stay in the directory created in the previous step, which now contains the +`22_20-21M` index files. Next, run: + + $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -U $HISAT2_HOME/example/reads/reads_1.fa -S eg1.sam + +This runs the HISAT2 aligner, which aligns a set of unpaired reads to the +genome region using the index generated in the previous step. +The alignment results in SAM format are written to the file `eg1.sam`, and a +short alignment summary is written to the console. (Actually, the summary is +written to the `"standard error"` or `"stderr"` filehandle, which is typically +printed to the console.) + +To see the first few lines of the SAM output, run: + + head eg1.sam + +You will see something like this: + + @HD VN:1.0 SO:unsorted + @SQ SN:22:20000001-21000000 LN:1000000 + @PG ID:hisat2 PN:hisat2 VN:2.0.0-beta + 1 0 22:20000001-21000000 397984 255 100M * 0 0 GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1 + 2 16 22:20000001-21000000 398131 255 100M * 0 0 ATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:80A19 YT:Z:UU NH:i:1 Zs:Z:80|S|rs576159895 + 3 16 22:20000001-21000000 398222 255 100M * 0 0 TGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:16A83 YT:Z:UU NH:i:1 Zs:Z:16|S|rs2629364 + 4 16 22:20000001-21000000 398247 255 90M200N10M * 0 0 CAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAACCGCTGCACCAGGAAGTCGATCCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU XS:A:- NH:i:1 + 5 16 22:20000001-21000000 398194 255 100M * 0 0 GGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:17A26A55 YT:Z:UU NH:i:1 Zs:Z:17|S|rs576159895,26|S|rs2629364 + 6 0 22:20000001-21000000 398069 255 100M * 0 0 CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU NH:i:1 + 7 0 22:20000001-21000000 397896 255 100M * 0 0 GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:31G68 YT:Z:UU NH:i:1 Zs:Z:31|S|rs562662261 + 8 0 22:20000001-21000000 398150 255 100M * 0 0 AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:61A26A11 YT:Z:UU NH:i:1 Zs:Z:61|S|rs576159895,26|S|rs2629364 + 9 16 22:20000001-21000000 398329 255 8M200N92M * 0 0 ACCAGGAAGTCGATCCAGATGTAGTGGGGGGTCACTTCGGGGGGACAGGGTTTGGGTTGACTTGCTTCCGAGGCAGCCAGGGGGTCTGCTTCCTTTATCT IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:100 YT:Z:UU XS:A:- NH:i:1 + 10 16 22:20000001-21000000 398184 255 100M * 0 0 CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII AS:i:0 XN:i:0 XM:i:0 XO:i:0 XG:i:0 NM:i:0 MD:Z:27A26A45 YT:Z:UU NH:i:1 Zs:Z:27|S|rs576159895,26|S|rs2629364 + +The first few lines (beginning with `@`) are SAM header lines, and the rest of +the lines are SAM alignments, one line per read or mate. See the [HISAT2 +manual section on SAM output] and the [SAM specification] for details about how +to interpret the SAM file format. + +[HISAT2 manual section on SAM output]: #sam-output + +Paired-end example +------------------ + +To align paired-end reads included with HISAT2, stay in the same directory and +run: + + $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam + +This aligns a set of paired-end reads to the reference genome, with results +written to the file `eg2.sam`. + +Using SAMtools/BCFtools downstream +---------------------------------- + +[SAMtools] is a collection of tools for manipulating and analyzing SAM and BAM +alignment files. [BCFtools] is a collection of tools for calling variants and +manipulating VCF and BCF files, and it is typically distributed with [SAMtools]. +Using these tools together allows you to get from alignments in SAM format to +variant calls in VCF format. This example assumes that `samtools` and +`bcftools` are installed and that the directories containing these binaries are +in your [PATH environment variable]. + +Run the paired-end example: + + $HISAT2_HOME/hisat -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam + +Use `samtools view` to convert the SAM file into a BAM file. BAM is a the +binary format corresponding to the SAM text format. Run: + + samtools view -bS eg2.sam > eg2.bam + +Use `samtools sort` to convert the BAM file to a sorted BAM file. The following command requires samtools version 1.2 or higher. + + samtools sort eg2.bam -o eg2.sorted.bam + +We now have a sorted BAM file called `eg2.sorted.bam`. Sorted BAM is a useful +format because the alignments are (a) compressed, which is convenient for +long-term storage, and (b) sorted, which is convenient for variant discovery. +To generate variant calls in VCF format, run: + + samtools mpileup -uf $HISAT2_HOME/example/reference/22_20-21M.fa eg2.sorted.bam | bcftools view -bvcg - > eg2.raw.bcf + +Then to view the variants, run: + + bcftools view eg2.raw.bcf + +See the official SAMtools guide to [Calling SNPs/INDELs with SAMtools/BCFtools] +for more details and variations on this process. + +[BCFtools]: http://samtools.sourceforge.net/mpileup.shtml +[Calling SNPs/INDELs with SAMtools/BCFtools]: http://samtools.sourceforge.net/mpileup.shtml diff --git a/docs/_pages/search.html b/docs/_pages/search.html new file mode 100644 index 0000000..d964f54 --- /dev/null +++ b/docs/_pages/search.html @@ -0,0 +1,26 @@ +--- +layout: page +title: Search Results +permalink: /search/ +hide: true +share: false +--- + + + +

    diff --git a/docs/_pages/tags.html b/docs/_pages/tags.html new file mode 100644 index 0000000..8329577 --- /dev/null +++ b/docs/_pages/tags.html @@ -0,0 +1,14 @@ +--- +layout: page +title: Tags +permalink: /tags/ +order: 2 +share: false +hide: true +--- + + diff --git a/docs/_posts/2000-01-01-kim.md b/docs/_posts/2000-01-01-kim.md new file mode 100644 index 0000000..fd77605 --- /dev/null +++ b/docs/_posts/2000-01-01-kim.md @@ -0,0 +1,13 @@ +--- +layout: post +title: Daehwan Kim +tags: daehwankim +eye_catch: https://avatars0.githubusercontent.com/u/28678667?s=460&v=4 +--- + +Daehwan Kim is an Assistant Professor at UT Southwestern and was the original designer who layed much of the ground work for HISAT-genotype. + +[Webpage](https://kim-lab.org/daehwan-kim-principal-investigator/) + + + diff --git a/docs/_posts/2000-01-02-salzberg.md b/docs/_posts/2000-01-02-salzberg.md new file mode 100644 index 0000000..71f5117 --- /dev/null +++ b/docs/_posts/2000-01-02-salzberg.md @@ -0,0 +1,11 @@ +--- +layout: post +title: Steven Salzberg +tags: stevensalzberg +eye_catch: https://avatars0.githubusercontent.com/u/28678667?s=460&v=4 +--- + +Steven Salzberg is the Bloomberg Distinguished Professor of Biomedical Engineering, Computer Science, and Biostatistics at Johns Hopkins University, where I’m also Director of the Center for Computational Biology. + +[Webpage](https://salzberg-lab.org/in-the-news/about-me/) + diff --git a/docs/_posts/2000-01-03-langmead.md b/docs/_posts/2000-01-03-langmead.md new file mode 100644 index 0000000..0099a97 --- /dev/null +++ b/docs/_posts/2000-01-03-langmead.md @@ -0,0 +1,13 @@ +--- +layout: post +title: Ben Langmead +tags: benlangmead +eye_catch: https://avatars0.githubusercontent.com/u/28678667?s=460&v=4 +--- + +Ben Langmead is an Associate Professor of Computer Science at Johns Hopkins University. + +[Webpage](http://www.langmead-lab.org/) + + + diff --git a/docs/_posts/2019-07-28-park.md b/docs/_posts/2019-07-28-park.md new file mode 100644 index 0000000..a5f6c02 --- /dev/null +++ b/docs/_posts/2019-07-28-park.md @@ -0,0 +1,10 @@ +--- +layout: post +title: Chanhee Park +tags: chanheepark +eye_catch: https://avatars0.githubusercontent.com/u/28678667?s=460&v=4 +--- + +Chanhee Park is a Scientific Software Engineer in the Kim Lab at UTSW responsible for maintaining and improving HISAT2, the core of HISAT-genotype. + +[Linkedin](https://www.linkedin.com/in/chanhee-park-97677297/) diff --git a/docs/_sass/_aside.scss b/docs/_sass/_aside.scss new file mode 100644 index 0000000..d82fea3 --- /dev/null +++ b/docs/_sass/_aside.scss @@ -0,0 +1,66 @@ +.site-aside { + font-size: 0.95em; + padding-top: $margin; + padding-bottom: $margin; + + @media screen and (max-width: $mobile-width) { + border-top: 3px solid $brand-color; + } + + h2 { + font-size: 1.2em; + line-height: 1.3; + margin: 1em 0; + } + + .block { + margin-bottom: $margin; + h2 { + margin: 0; + } + } + + #search { + box-sizing: border-box; + width: 100%; + } + + ol, ul { + margin: 1.5em 0; + list-style: none; + line-height: 1.2em; + li { + border-bottom: 1px solid $border-color; + &:first-child { + border-top: 1px solid $border-color; + } + a, span { + padding: 0.5em 0.3em; + display: block; + width: 100%; + } + &:last-child { + margin-bottom: 0; + } + } + } + + ul.icons { + @extend .clearfix; + list-style: none; + li { + border: none; + font-size: 1.8em; + margin-bottom: 0; + float: left; + a { + padding: 0; + } + } + } + + a.publication { + padding: 0; + display: inline; + } +} diff --git a/docs/_sass/_common.scss b/docs/_sass/_common.scss new file mode 100644 index 0000000..9d1ed21 --- /dev/null +++ b/docs/_sass/_common.scss @@ -0,0 +1,43 @@ +html { + background: $background-color; +} + +body { + color: $text-color; + font-family: $font-family; + font-size: $font-size; + word-wrap: break-word; +} + +a { + color: $link-color; + text-decoration: none; + &:hover { + opacity: .8; + text-decoration: underline; + } +} + +hr { + border: 0; + border-top: 1px solid $border-color; + border-bottom: 1px solid #fff; + margin: 1em 0; + &.with-margin { + margin: $margin 0; + } + &.with-no-margin { + margin: 0; + } +} + +input, select, textarea { + border-radius: 0.3em; + border: 1px solid $border-color; + display: inline-block; + padding: 0.5em 0.75em; +} + +iframe, img, embed, object, video { + max-width: 100%; +} diff --git a/docs/_sass/_content.scss b/docs/_sass/_content.scss new file mode 100644 index 0000000..b028d5d --- /dev/null +++ b/docs/_sass/_content.scss @@ -0,0 +1,203 @@ +.site-content { + h1, h2, h3, h4, h5, h6 { + line-height: 1.3; + margin: 1em 0; + .header-link { + margin-left: 0.2em; + color: $link-color; + opacity: 0; + } + &:hover .header-link { + opacity: 1; + } + } + + h1 { + font-size: 2.3em; + } + + h2 { + font-size: 1.9em; + } + + blockquote { + border-left: 5px solid #ddd; + color: $blockquote-color; + padding: 0.5em 1em; + p:first-child { + margin-top: 0; + } + p:last-child { + margin-bottom: 0; + } + } + + table { + width: 100%; + border-collapse: collapse; + td, th { + padding: 0.5em 1em; + border: 1px solid $border-color; + text-align: left; + } + } + + p, ol, ul, dl, table, blockquote, kbd, pre, samp { + margin: 1.5em 0; + } + + ul, ol { + padding-left: 1em; + ul, ol { + margin: 0; + } + } + + ul, ol { + &.inline { + @extend .clearfix; + list-style: none; + padding-left: 0; + li { + float: left; + margin-right: 1em; + &:last-child { + margin-right: 0; + } + } + } + } + + ul { + margin-left: 0.5em; + } + + dt { + font-weight: bold; + } + + dd { + margin-left: 2em; + } + + p, ol, ul, dl { + line-height: 1.5; + } + + ol, ul { + list-style-position: outside; + } + + code { + font-family: $code-font-family; + font-size: $code-font-size; + margin: 0 1px; + padding: 0 1px; + background-color: rgba(#ddd, .1); + } + + pre { + border: 1px solid #ccc; + background-color: rgba(#ddd, .1); + overflow: auto; + padding: 10px 15px; + line-height: 1em; + border-radius: 3px; + code { + margin: 0; + padding: 0; + word-wrap: normal; + white-space: pre; + border: none; + background: transparent; + } + } + + .article-wrapper { + @extend .clearfix; + margin: $margin 0; + } + + article { + width: 100%; + float: left; + header { + margin-bottom: $margin; + .panel { + padding: 1em 1.5em; + background-color: rgba($page-title-color, .2); + h1 { + margin: 0; + &, a { + color: $page-title-color; + } + } + ul.meta, ul.tags { + list-style: none; + margin: 0; + padding: 0; + li { + display: inline-block; + color: rgba($text-color, .5); + font-size: 0.95em; + margin-right: 0.5em; + &:last-child { + margin-right: 0; + } + } + } + ul.meta { + float: right; + } + ul.icons { + margin: 0; + padding: 0; + li { + margin-right: 0; + } + } + } + } + p:last-child { + margin-bottom: 0; + } + footer { + margin-top: $margin; + } + .footnotes { + font-size: 0.9em; + } + } + + .comments { + margin-bottom: $margin; + } + + .pagination { + margin: $margin 0; + padding: 0 10%; + text-align: center; + .btn:first-child { + margin-right: 1em; + } + } + + #search-results { + .article-wrapper { + margin: 1em 0; + } + article header { + margin-bottom: 0; + .panel { + padding: 0; + background-color: $background-color; + h1 { + font-size: 1.5em; + a.tag { + font-size: 0.7em; + } + } + } + } + } +} diff --git a/docs/_sass/_footer.scss b/docs/_sass/_footer.scss new file mode 100644 index 0000000..f0d18e0 --- /dev/null +++ b/docs/_sass/_footer.scss @@ -0,0 +1,7 @@ +.site-footer { + border-top: 3px solid $brand-color; + padding: $margin/2 0; + color: lighten($text-color, 30%); + text-align: center; + font-size: 0.9em; +} diff --git a/docs/_sass/_header.scss b/docs/_sass/_header.scss new file mode 100644 index 0000000..392366b --- /dev/null +++ b/docs/_sass/_header.scss @@ -0,0 +1,47 @@ +.site-header { + font-size: 2em; + padding: 0.7em 0; + background-color: $brand-color; + border-top: 3px solid rgba(#000, .5); + @media screen and (max-width: $mobile-width) { + text-align: center; + } + + .avatar { + height: 3em; + width: 3em; + border: 3px solid rgba(#fff, .7); + border-radius: 1.5em; + margin-right: 0.8em; + float: left; + @media screen and (max-width: $mobile-width) { + float: none; + margin-right: 0; + } + } + + h1 { + font-size: 1em; + line-height: 1em; + margin: 0; + .title { + display: inline-block; + color: $site-title-color; + font-weight: bold; + margin-top: 0.5em; + &.slim { + margin-top: 0; + } + @media screen and (max-width: $mobile-width) { + margin-top: 0; + } + } + .description { + margin: 0; + font-size: 0.6em; + line-height: 1em; + margin-top: 0.5em; + color: lighten($site-title-color, 20%); + } + } +} diff --git a/docs/_sass/base/_layout.scss b/docs/_sass/base/_layout.scss new file mode 100644 index 0000000..94767d3 --- /dev/null +++ b/docs/_sass/base/_layout.scss @@ -0,0 +1,62 @@ +$site-max-width: 1200px; +$mobile-width: 800px; +$side-padding: 10px; + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +.site-header { + width: 100%; + .inner { + width: $site-max-width; + margin: 0 auto; + @media screen and (max-width: $site-max-width) { + width: 100%; + padding: 0 $side-padding; + } + } +} + +.site-container { + @extend .clearfix; + width: $site-max-width; + margin: 0 auto; + @media screen and (max-width: $site-max-width) { + width: 100%; + padding: 0 $side-padding; + } + @media screen and (max-width: $mobile-width) { + padding: 0; + } +} + +.site-content { + width: 70%; + float: left; + @media screen and (max-width: $mobile-width) { + width: 100%; + padding: 0 $side-padding; + } +} + +.site-aside { + padding-left: 50px; + width: 30%; + float: left; + @media screen and (max-width: $mobile-width) { + width: 100%; + padding: 0 $side-padding; + } + .inner { + } +} + +.site-footer { + width: 100%; + .inner { + padding: 0 $side-padding; + } +} diff --git a/docs/_sass/base/_reset.scss b/docs/_sass/base/_reset.scss new file mode 100644 index 0000000..458eea1 --- /dev/null +++ b/docs/_sass/base/_reset.scss @@ -0,0 +1,427 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} diff --git a/docs/_sass/base/_syntax.scss b/docs/_sass/base/_syntax.scss new file mode 100644 index 0000000..39cdb79 --- /dev/null +++ b/docs/_sass/base/_syntax.scss @@ -0,0 +1,63 @@ +// from https://github.com/mojombo/tpw/blob/master/css/syntax.css +// see also https://jekyllrb.com/docs/templates/#stylesheets-for-syntax-highlighting + +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/docs/_sass/base/_utilities.scss b/docs/_sass/base/_utilities.scss new file mode 100644 index 0000000..f7fde26 --- /dev/null +++ b/docs/_sass/base/_utilities.scss @@ -0,0 +1,39 @@ +// button. +.btn { + border-radius: 0.3em; + border: 1px solid; + display: inline-block; + padding: 0.5em 0.75em; +} +a.btn:hover { + background: $link-color; + color: $background-color; + text-decoration: none; +} + +// margin. +.margin { + margin: $margin 0 !important; +} +.margin-top { + margin-top: $margin !important; +} +.margin-bottom { + margin-bottom: $margin !important; +} + +// state. +.disabled { + opacity: 0.7; +} + +// clearfix. +.clearfix { + &:before, &:after { + content: " "; + display: table; + } + &:after { + clear: both; + } +} diff --git a/docs/_sass/base/_variables.scss b/docs/_sass/base/_variables.scss new file mode 100644 index 0000000..19eb550 --- /dev/null +++ b/docs/_sass/base/_variables.scss @@ -0,0 +1,24 @@ +// typography. +$font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; +$font-size: 16px; + +// source code typography. +$code-font-family: "Courier New", Courier, monospace, fixed; +$code-font-size: 0.9em; + +// vertical margin. +$margin: 50px; + +// brand color. +$brand-color: #003c6e; + +// other major colors. +$site-title-color: rgba(#fff, .9); +$page-title-color: $brand-color; +$background-color: #fff; +$border-color: rgba(#000, .25); + +// typography colors. +$text-color: #383838; +$link-color: lighten($brand-color, 15%); +$blockquote-color: #777; diff --git a/docs/assets/css/style.scss b/docs/assets/css/style.scss new file mode 100644 index 0000000..c681659 --- /dev/null +++ b/docs/assets/css/style.scss @@ -0,0 +1,13 @@ +--- +--- + +@import 'base/_reset'; +@import 'base/_syntax'; +@import 'base/_variables'; +@import 'base/_layout'; +@import 'base/_utilities'; +@import '_common'; +@import '_header'; +@import '_footer'; +@import '_aside'; +@import '_content'; diff --git a/docs/assets/data/HISAT2-first_release-Sept_8_2015.pdf b/docs/assets/data/HISAT2-first_release-Sept_8_2015.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d9ba746f4652cb820525da9599c818f710b8e11e GIT binary patch literal 1950832 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 SK=S5*>$O0o%>1HNE$H{6IsUUv}^kx1yd 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 bfLm31q5MS*bDb`5FixRdl)G4mk8PC3_DH< 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 Y-OtmoVR3C7{O7Djes( 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ⅆu}x#;G5ip0wUc9tEbJ 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≷u4 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±xLL}M8(I!9^%dT&w<71snr^Kca$Bn_ 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%0An?vjsxs8b?Y4}nomC&ZyVQ? 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

    +PjtPpl!)7d7)`%4} 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⁡`Z!fL-#t(UAUv3_~)u<>U{O~mr}C!$%~JatrtlM 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

    RUaw_jOZ43H+l~ZV)vlT}_ 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

    {&#KMe_~!qEKozp+Irke5CQ=N?L_DU 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 O_17ux!C2An5F|5U&qQaf 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

    1y44= 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

    w=%n)=%@2BZ*~V| zb1>PXmt`vXR1=;2u9NB6E${+DM(amPnJ4qCtF~`Lj0I4=FaY}B#Wwas21O^ zJ+}-D^KMnD`iLv{fv( zw`X_|X|d!!a}zhCx?@ptX=PbjXJ6Eau5*k`a~|xFsjv;=@fTHG2?q2K#?ESVjGz!p z?O@vGq)inuH0#6UUEZF~y1Nr{lS!U$03AWKRtb!bjt!$MxX^k#K{tH@_!D%u`s*H9 zk_q-%&k;xNk9T;Bgl zcu8WTwKCAd*NGt!-TiHAz{1gurmRkZ2eA~S@YWF-TufH`7`f-#O@xXFqFLN1UHFR< znIPSe{!5e$RfxOhlkfv~SuInMl9N=KrG^CPj>z~Q3-|T;GjoTV`<899uVXovFjNT; zn4*5!jLUo{g{NJ^Fh&hHKK|<=K!c$5&$jJ~{U4~dl^GAPVPjS{SD<=MF$9-6_4J1mFV%^w?y@ZQvDhrQ+$1+}=%1)UPntpot}{U&gaR|{bg=voQN2|Ta_5E#qT}k_ zeh&p8pDww&LeJM*<@YWk`=>R?CtWCxAgFSX1Fp6^apT<*gV()pvKKP zMLQ|7&E;oj^!;M3+sWri`p5@b-lS4J9ujpqgY%BiC)QvrEV$yi2@<&@ir~{34R`5b zmNau%$u-e`Y{CWZREQxp(m`O^p(~1stoVkk?l*_fKgM$D8q}g4 zt4L>Lt9#{@iEXVUa9~AE;;+p%;$t4~5#wpPWS!%8;LUcSl~X8o%EK)`%YA-v#q+7E zV#HT-+H#LoiSk<*233vEHjchNzrN06-uzUvLd%}PTJ*<`P%wpq!l#5(nbK)$~?ZaW@S2t~$c@VF)Z?(pSdbW6~Hr{%mJR7|ci<sz?g9-FSCg%dYEwYM-33S|{~K^od( zxFF5t`xa`-9O~7M2-QRD{q;<9$!h+RNKFJ!Jc`vmGhO;y@>>GYWHD{ekQN9{D?!J% zlYFcZw@|L}+Yf=6W^yFH*z50gMLiP5!BXlAt9HZGn-tPbvBMWXnVp1`IrPQ|QYq25 ze7{OG{t{V!d?$`E8Jl>rJ4Wyljp44y;@*%rE`XK^er2m?o`=_^fa$ z_s^elLIp+d8cFgR!h?x6*fWb6z%mzCXKz!(wA&quz{1R~e!_mU|2FMdS^&=~sy1h)~qZNzAZ08jf>Ebk~zk zl$^HwzzCME8sV{utP%c1jB_jAJGkcQA6FyfpbH{w@c1SgMD23~uPTmapZhFgT#3_VpDz=F(mM>m( zG>Mz5;1}NNU9u(+-8>fVQKI{2%53x*I2GO|&DXQ8`WQa4^6o4)oq?qlWID&WmbxkdWvDii8k8_wp%)VRR@>g zl`Zv~k(l#r&5KH_uKH=keAo&w zRWWfOnZtHJuap=ifb|6ey?XL<@LxR$@Gw=))qIh*f-ES$R!3A6C?fkK1{V~58}LjD zYTUeX{%plfwHSREzB~K1P*&qCVuT~M7blZP%T>fZBE5F@t6}-*th3Hpu5xW*Y>C20 z4B+DZ7Tf}<;J$Eq^H5+ovm87xzwU0ICz(LW@>cc9L~CDa7-+Hw(*soS1fSf$=)fty z4o@u~jY#=wKRw^Ry6`V^86Pu<$Dcl_@1Br`eqQ5r`3IIPT)w`)vn^`xcPC)|5O?iE zuqV`E;l+Ht8e50Ps2$ND`7->t*M!I5kI75RiOExx+*;ZxM5lg^8$&IVO<*?V#JwC{ zaWfhn->*(rA9+^xHHi|R$zXn?RN`3v^lZra$$za<2jfj`&L65gZf_8-+Mm|fjxVQ# z)5@j^b1vg9*@(_f)!6x5B5Ug=->~OA4=9aaMDUe=~>Dxom8T;_o>B{M_ok`$r#*STu0eFTg)Lg zFU|(Pg`_P9=@6tXb(kO<@A#b-;8W=sjl91|=GRSmimM3SFJ0tgVr)Ey97Du{&2TJI zkfrVJw~bt<6z8;oH_Pj%Kfib=Xkj}!Dh;gb%#_Q#QOi zvR*U#%lZ!etJM52QTPw3$;|vudj4bi#%|`sZZ7WT#Ec@=Zmvq^E~1Y1PL2-d4sOK2 z-V)Y!z{`N2f3FiWH+3{KCl(NZa|I?g8Qa5ofnMZU>*8uJhZiVNDO5(qkQS1L%7qjn zAjQGaa_!p5$-M#q(Vlhw3Yd^KI&Z^xCGG-T>^}OPzKCyXnCgJHf?hi?4$zz+`E7NG z&r|J&SM|3MMO2jhf-cz`|I_rx83QR07(xG6yt8JV_uB=k_xtdE$NqC>P-4hwMsV=Z zpSal1w+DAy9KT0v4PMb%K3JI8_;#J*st=sv5Rei5UJ$AoKgb@>d|-l3j)IGlnU8+# z?=LRi-!CpM?(c`W+L>7ml&^`NVs0g!Tp#~foXlOmDmc1*>&?%iIXa#NLEFX*91o}x z-frms{A6J}&AwrPBKtLmt?9;%uXo)=g)eIO*#=iC;BSWQfc+Vk_t5f3-gJw;uPMr>o{h_9*tZQmXs7JMja_{?BICnP} zhD^P!diEz>``X`wn+lyt3C|Uy5q&G*1HZJh8`MPfqb%AzkP;MmkF@fd_kKHA)3-6P z3fPIVOZUFR$5nzOE$cC<*AnF#=xzKl+0e@?IM=+34hng_6}0GAK{a|vl%J7Ymhm0M z;xxSKH{RIN&ug`T#5)bdfVEsqhMk$0Y23X00#z*%h=_WCh814MU@RANlT(>+PD1RL(Z_*_;#7_2I4 zq;Z5tT5>;eCNMZ;RqlQ|dO86tc-W3yR&)W&%Ib1?moHL2C7Y*uf$V4x!d*n* zn393KDu$w%-ml(HKY&#(t3=Wd0gr`f52H`rzfuo9D0iDT0Jw!-brw7q@OArNS7bL_ z#MGCNi`s0%_vdTf`t?5oag8X_Z=)`VCyS8p3U^lnp1+M_--6%!e*Gv$BI@a2|Fm8`Gm#MEq$KM9cZ+ zj51*{oCwJwU<+2?3yBbTCq`{x^ zARTzCJyqA(Une4EtE2ayhwqh*dGQP#+$C$#uV~-XXzFu>a$mohWSO{MNu8;sFAjfP z9E=-qXK3Aa;PV|krS!iH8V=XYeqWD#usjltZk<~Dym?_ykp19i|@(*RLd7_ZD>9Rfq)8pEKOi)?BpVA+QSf?7oJ{DGFRm zQmT;_NT74C5XCfpb5u_~o{Yo`;L-c4POB^v9H+@SmlgOcuf--M#Lc}Fd6g@PWXp(J zXPNXXmTTsTGRY^?#BB9ZK6qEllx03j&b>GRX`;T4o>lx1zjjoH-mYmGiMVgQA{c5s zk^c%HIAKbfe$Du{^Da~3?lLVrL95Et%V&S}Z46^sA+$>WeMX604X!kmwNHpVi~gI( zW8$>dt43Dwqa%ZY4)6Nec#_wa#VdmHbQzaR2n}3%qV3CYGy+e-bbnv-1jcVk@jRld zWzJst!V3G7FtkGJD(D#?^U_ z$uxC=-<$Jvqv^aTM!v-EU8SU?3fBi9`WezdHjL`x4Nyh4^8`CF23ewQ6R`>&?YABYArAK zFYGQAtM_6mc0V!=a^5DHyrNFL3p0Af!)Qd=qkTE0YACe?^>e;*%#)}E{5m_EKvN5J zm5ackf4Q~)*9;vbuL>&cic0^SDhs$`pJ~gj?mvWq#Au2Qj%laz#JxRz&A0_pBQKgq zUUxWV*)UTx3MMJL3=6CSCGkyOnTewX;@DHFcrWtEQ@jz_V= zqpl@ijDI)k3;>T|YpnJQ{LwBtQMna~VeGTS?Z8fpXG`rrw&*~uT4s@C668{Nx#22P z`cfBj%fA*qDo;q#JL0Qw@~+2&dru~BpXK4Irk)B><%(wdX~L9UDrJjZq%eb8Hm{&a z!Y_X0c%-?v6VCmuZ$l}JwmyR-&?(bikpE0yE9Qr)EhH+9L}ktTrpLT?j4{!NTND$$ zMXFn$Ekc=NMHL5syF5A1K6sc6~`chu+ z@42kx(hXD@F&kojex8*&yZQ=Kl8BQ?&pxmi?DSBIW1p_ge(V^^d9>0N|DzQ58SX7w zmCO9Ttw8a;0+ljcnqjrXaw64oh-&C}P`PJv9>ij&UKH~r!hE;<@4cvHPo5pl(5KQ# zKSeth(qc_9Jj#d`Uo@hdGJjGs@p~VE?^vPXinFsnBC994Q2L9Mc36*2nIDzL<2~8c zRxpcuZ)D0vdV}{PN4IDe4{UO{MLW`;&dLUmD5a8|ivGcV}Gw?`Q_jM9%lRbl^ps`qe?xBdKHtg*`bS{Ax}CI{wsyq#F&9VKVxrRYnkPUZ8OIMfyI4 z#ovd%U%5KvSbF*4H!*v3@l^vOxy;v`7daPi>wts@Gi<;f@kJ}20}}7V-1vnun*R8} z{lOZ;q4J3jyTAi_I_xQ)*aT|zQfaB?n@dG$&V{e+TZ_#C;p4~{lDEbM$IAw>@P z4gFM}+!@~d=nKZ_gmu#SR<+zd$+U!t%V^2RE$?r*eBQKSs_41_Zn-!-wqTeu%Xq%@ zkMk4>X8pRFg51f^I=bD4=Fy_%ZB z?zmM1@|bMK)$7#e9@p0w#r`)==}A~yFS@%U`NZO%_86O(2(VA?wawtH`(6}wBaad5%G6s3g*AVV>Bx5k z;ezeXZ;TG#G7Cv(n_cA|@x{c86v5c#6XW^IsW?=75tc)(xR{WOSq>H+Rh|OBU-=r{ zDl2#;q4!K18{~fr_3)HeXih*W*w4}`5(qy+LT`~QtUfSzV9}MvSc8nI?mspn+}Ntq zj&=#aeHpfQY{D>a`d!DSjup)VSwS+hNPFiB|GLOWA>8?(hH8UQtY5fx$K^S?dU7c- zdc5g?h#V`#O0%rktt9`YI517Bo7$UFL4q7n)mGIihHK>9K+riN!!(WR)gOIkrgGtG zwqmymEe(tv9{{0*BavL3cI^CC*r~d@IcBaJZO(?Se|26}E*MgoZl;;R&$Q!~m1^}s zbJOK$kfp!Jb};@fMpCrnPS&_rfKpkd1SUSmDn55lFV)hct~XQrBO^5XxRT+GldzN@ z`zAh0g^qzbIZGx}beNW7bVam~oAoT~?gi^hMhJ=}A8d2O0fxc^`i-~WM94B()a6=c)`LgRu0NLR19k6I1%)1Ze^v^!FlY-3jf0WO z!l0w~sLHzjWIe*P53yilFtEh3XXS&eNTGWBcuXLxESl+)NfA}R2L|Sh++pXnh^gKj zC>d??#(Lj-qWk0K-Ke4$DM$;1&TUI2iKrC)uoxRcn;@SY0oFPw;z-V2ec&63KL2B_ zl!t4nnGdDt5Jx9^EI0#hf5Cn#rF@S@PFr5^^C#h5W!!VWbcvbeL3tk~w=1kjnZz6! zlS&G1X(ig1ic!=ox6b7wOB-A!)tciXKV>VGTwmxqQRcVK9S_lbivXSXdhhDSXdrN* zCY-(Tm%48p%yFdRG|HKT!>OiPs3U@q051RWQ@|b-Np*U~%HXJva=6~DkSr5~SYsPs zJZcI?Qj8haL9q!=JVl}0Ps&p13eg-9^f_;r7;VDcG?u1azqA7Ve7BxB`S#2lt-DB& z7?cgVT1%B^D{LAbPS$w&$^_+J#1BNVhq}x{0aU_HV^o6QFd3n-GtKy9V&(f`zsmA| z9_JTPrc-0dr`?FLq(?9NuvoD>u8{Jr9c;?H z^+-L&#G@(uvmHfU?qyn&N2?MPf6Q6lsPnrN3UW)X2l{R;^zX-4D+jRyw0D9-RS01h z@sdfbm>eVR`rl$%ZzgV1sZ12y=4s3NV$Fi#suw9MQV~MVO7}WHDG`dtlxWq!m-0Pz zC}b7@l*QRJTX3Oy?Kz8PQzqU*$gv>)0erJ)2w31Tq)c#njko|~4j8x8S6pLTQ zazkkbS21_mx%&Co&(>b_N?e4d=sJXD5Wl{LLmm1P`t;=#S7!v^DIIcLSx56~-{~l% zu~jFQqj3Kr3Qv-onR#3_hW5lcv*%ZeuE#Sz(-KFs?Snuzl%lyO{LI(uG?@^g znzA|*B>F@ZIELaw@gg6W6f#9e&`Pw^f$QfMPnzuAcP(;`TKQV~+4W5ZP+}P14IW;R zNI0^;b1)74iIhwt7qUqyr(^ETp_9*?v05msg7(=JBWg@yV#zB>HhSiF^YgX^rzlV` zvD48>8a*AlO$_?fSg_5Cd4neK@{^}i9q1%d*|RZXZ+v_la0F}z!G!P3G1Jh-sgZNJ z&<%+~TuG@EEq1AKaB4p$++^;{=jywkK8q1W3t%c@=ckJW58c3jc4{LOE0|SIKFSn1 ziWTcW?QzTYNp)!rs!L%5188@6MtFu#2NsTuV1ULPrfhuB6eud`YL$|f?|x=(spXd* zWeP3HV|QpXQ)U4w1?+5Shy^k~iIpzA@LlFhK6D{u>b=J&r1oNpP%Fm2ZB@-MAt2}1lEYz0=62)-4hyBL^v7}W4=x@ut)1Z?@~Tle zj-K&i8+uoJg-}%E^L~W6zW`%T<6*|q*>K3$+le;%9l$($f9>;$w|DSf3nupk8;37Zv1H#`X-*M|kSXx zxV?Y-1!fsD0`i;tAj<|&@++koPC4T$GtgLABN#>w{wkc3(5V?;E$zC^S~@63qp!j? ztK|-lIY-`(1&+~p;bwk;3}p)(!b7G?hAQ}}t3ydZ{tKa5qLM;CxI~mSG_XneS8CcR zZGlGRimo(Mq9%*+lL7;wVU3sGeX;WFWah|PEHzOs4|-fM(Q4){kZl+(1cUrAA_GFo zNu5OH04GMIDcU8S!Q{Rc5jco5v)%Ywd1t7yOfX6L72R#TJubhXUwgGGCe;zX?|dKG zH$cSgGa+*O!G*y%P=ZJoydn|ldp3E+Rp}BqUWn8y0doh&nMUDL^Yj2J6R|9(u4VA7 zmad{Poyei2ie#Q|h3;q8#r1^|uezr2b$vr;+xoN%tw`h#3{fi;60x{&dt-G1&cAR3 zOf;?{vIbPN3M=|4v{Ih)r%`2bN`;Y|iIB(n^vdu$1WJT^YUk`;H*nLVyEqu>1RA`9 zd=z~i)si6#rp>b}p#&zEbS!jn|4PU*spS5$ff+C{4jvlIT4b@zidRL5G#lmk>*MQ? zJo(d(R!|=YMYhJe7$BwHH4x8&ZXw+)+Jb1;qLAV^*blB0(BKrxxP(w4CN*>f&Kb+* zq2!$aOp)YjM6S~TObD3oJJ znwF4RI|g7R$)%=HDmpYAL{PA#a*UipO+AOJHGiI?6Cs>s4X}edS*yVv18zVMGz@}6?ayEjfU9cON-qa z;(wr9WH*7^J=@pMuRZ265hXG)>LoI&B1ynyzezojmf_v_w`UfVdI=p-M-+eO4IFw- z`q8R&5xKw~xd;k`7@OPN%0e*=8Ud&(hjl_r0f)g?o}7%?d%ALuID38Rj)uk29wcT6 z^$ScwUKti784VkCD0vZDG}JN{x22-tn zvHBHPxCiK~vx@Fc5JbcHV(A|X>l`vh`O|-Ne}2UfYo}l(2^zs^I=zj|;az+#+)H0L zzQH~W`n+|2Z8!F{!>&O52l!17wEKNbzn4GCpjRm>_7rK@u6_jmM#LXb=j+0>$T zch)u1dHT^wc78Q47yhm=n{j&_F+(0WFT?KTP5sz~2g;~5DH3#qaAl6T7&r1&fYvs}~i4@kpRaySCZt2&01?!aR%BOQon}utv8+eaAL_&y~{_ymlWh+@wvw5-*mFGjMOQfG>yqDigY9^WGij^fI zY)0Mr4DI3jr?~9p`wpKRR+}Y5TQikGHiaJF9czIA<_vG4OQ80AbxNdfdev5T-80Do z@nnwxam;IlqAIBubsY*tu5<+b9^59#8^!AXx1R^XU0P|qH(w8Fa7IInexAQ&{k=W0 z2Jrn_`3-Rjc$@|&ZyO90p%n!`J9$BLu_EnC*|Tb6E*;`CH$8eY9`O29Ni*3WaYe`} zJq&D~sQ#mnW?<5XGare6v8O7dn^5-6Ct=<#iG$Ky9R`QR*Y!6m0F0OG@Tq?9Nv zYvt4G?YVu9%rbxNz8>rHMYo5pphyip0{6S23R8Yjw>L1?r?u#KuCV|bLzStP1;6I; zHc2=~#C|kuWilM(~{%1XM$|6qtff`w(gsMh8OL5hh7Y9ZH{8>0qaT)B&FsSV?+{WL{Wcm7fns0A=3>3e2Oh@7^G81 z;19M3y~Ag-3N5_?{7WzZ7D$}?uUgW+HLztX$_51ouE!_%U+qcPY>AHF6@ftGaKD-V zeUA7a1OGqf2p$g3|4F{!X8$kJh}`V|tu!Lb|HBa+$nf|-o<{T*$J3b~`9bvulRH5X z6+!|n{YVgD|_M*Ms zI2FR{?f96U_h-^`7u5`iBos2@CS36tb}E$Q&5R5jVn61;hNp~v`{Aszurw}YRDmTh zu(_3$wAoW!f`WqV?Ce0Rrtl0cR&IW?Yyx7+M($sfeIL7=bl~d9RH|U)U}Sl(-rbwK z+S*Qh22Abim$zO$hSy|6K%*l<*S5%6RP#e-|8d7h5G-{$6$L)3oXE(8h=>4@AI{EW z$9hli;DM>B#w-|c;X~Ec)rm6Z?wkY<%v~4r=*8l6tRqoXXzE!QqNMwlmWT=tBD!E? zU~r*mH9nR2D`r&Ci?wNq1WHsn}_9y9BIw)^n8A~S2cDggbWa=}44 z8$_|RIJ%JJBx^DhqCZ@1`IE=44qRS+3jqvQS7~ykf>PG)8S87>1|HK&aY&dffs{Z; z73nY8r`0k^Rd_gz0|-{sWWd@6RgrI?*VFj>J9K!eT&r&N;`w87vDq-}-b;l~LpLF^ z&vE%5sW1r>1I_EdaHVqUlIrkEayF}dXcQHXUSzP0sOU7PXgC_S!>)5y9ND!V?+*_x z^Sr?KE3Hp5J;Q&QEXN8gfwVKDd3V%E@n75bFcH;`!bArY-!Vcb_}Bu}*&qRfuo)PX zB4`pI5CHDwUMFLY75E>eyUDV%XK+|NG|VCgO$Uwq$>3f9O*3oCVv+c`Bxl z*gRCn7`B=g-%V08TId^2gR-Kj6HHd43J-(T03;beMlKoQCd4Lm`eHX+9#4E#uU!2q z@sE?AwWA+{kzqBpp^Stfg+5+OTQV^qdp!tlOpBk-fn&Wqw>cWVWCL+TLLnj1R6;Ck zIz8`&?)LD0bTnJ3HUXv+8Y^R3yz;u@iU(xf&^GvK^0z8{bE@e%$cSL zDte2#DjNzdAG6=*-RaP!PHzT*y0O?qLYivYME8LathDK^c~;HS6LR&VnJDGhG9_g} z1yyJz_Kd$_Ts=7Aq!>J8o^^$>ind;+eq)JFu8oGM`d>jxTJ)6A`H2{xUwr-jT`hm8 zX&A%jn>&DYUwX8)k~a|rVCOOA$jF}QwQ>&N z=MADdnm8SQ{!rWh!?Law(_QBu5d>dae7qzaPd$-abPFwsmf1WDQq5op>3~ZfsnYFm zfqj2@xd|x!(l|C3?j~}YM))I_-_fy!moJj)*@2ZFT#!0_kPzOwZ~2a33k3=Pc=ld{ zplYDBkYEZSHh2VD?U#dcI~+kRvm8@hJ#jxT)!Nb7c7YS2Mji{lmzCGb-z#K8pF5WR zME{tKWs?RP9j)At!qnR|R}qpj&OJbpLPA19Ml9+&=6ZSG+^kd{?0Umhv}nVnbQWGZ zDP@(YMgR7>@VB3nm6N@F$M7z^C`$9OLe#p@k`z&8(tu@RmH~fINU;Bp%-=$zwa!uF7O3fo5hbP7-4wf*v6k-o^+aMCL3F7R$?8s$ zfne0oB_W^RxPcN9AP^jLK7&H=T=^M+gx#J6i=(|XgSNhKcX#y;c83#-=sRLeV){u@ zS!tw<1aPqM*_c|`Kgw&%8t6zt+qoeZ={O{1MO8o`l~B-|5mGQHg5wiZocc%cctA*h zy*Xb}Zx-%ZWV?zPR_3Z6cKCe}q|??CY5x^HsmhRsA_FZ3U;?}a|D}+Xj-&F3%F9WD zjhPqs_dGmO_qG{1b7w90*zyu=(-9D~PS>?`fmG5n$x0Z?bx7lh=}aXTpP6{KHzcnr z*w@sHYW~_Tf;OPw876%Mmm{udA>3H=reof4wsHgl_Jiytb}((>RBw z62{W`?+`6N4yuEWsYV>7BczaYb>=%XcavqJy)KE(Dy{L6+*)-3JVPBrbG)nu?K(iM zI@Is8WdCSraj`h1=}xV^)jQ|ox35$5xY*tf;J9;k_vdcUjj9g?Pr;gwv9Gw&X8owv z9(xxLRAhcx;_^H%*U~gJa?<~}arzlMasD{e>r2JhBETdw!8IaYh`FTKv*>uAQDdC! zng<~BTC04gE zUFSD^B)x^Y`2qzA1nd{aLlx-S@U-s=98Bg!&{X8lr}7^3gc@oFF667TDd7-cE4>?w zFMBkEX)Kc(S@@0!U3{?;5>TLpU@11%LiyfqZ&AKUOBbYJAkEy)22G zurBZTHUGAcOhJM5dcWn=1mN%e^+5wB4vKC#3JuvZ4jo_{wzv0Y@;ALiIEjf_H6})J zn(uS=@^0*v5jpX%Ob&dZXPIkHzOr<%JkvmFJr?pk*q3xm0n^d`%E9EID$vKPr2%R_ z{4aApk>dGGW-4^BFfE>D0w#q0`I{W2=p&ZE2HfRa34^cT-9Jp0g`6!yig+ zTmZu%{j9IAR$ARjNsnK=`tpG=?F&vSZ%2VzvwB-8`NP zwuaO2o&**&SeSH)RqmeKmclIVuAr^*zOx!=7!@bDhLDU-Kh{8*>?$|4ndDq&ed50? zVkEtfSP<4nYuRUvPL*FG!$Qr9I9^QS%(iy#iior9Ln(Jmg#)%!*{8cy2I8LDiYDOa zg9W{w<8Lz?By?@qKwEt2P1-Q!j_bmJ<~kO9#2(x|SL;&S%s`)Sv{*vrPT_Q{5CUE5Q0J0R3puP(>D^CnQrpBHo=uq* ztFYtamE+sfFW(HI=07}em5AqJE{f)u@Y&jswqbC=M)b{CdcsgiC)Fy)AUs~=^i10C zqYtC8OPTxWqrJhPrF_F~QC<;JiEfVzi01w=iWlH44k1_tl8eQ9geSvpw_$=UW8*dp zIWG0n_q4FE^Xivz<6$goXDVBdih zMnkGW@DUrUhav=h-XrW}N;m8xVATwVc?iwP#fG8jk+gLF|lOs`9K(DV|i z_CP(rSet}oFQ5n2`dX=r8>E|-+B@uI9dKNt@U-Qv(pHcHra807#eCw#XW14WcfX#R z<}0oa=NeN-AkV6|;kB7@&OM_Ni_9Mx#NVt{-IT!Su9KSL0tmrEM;ag3P|Kr1;l-KR z0FR7}sWB(e9elQggc$AUi2Ja!25@x#Lg!` z)W~HpX%?@{n2eE$m6~ENd!K8!ErO3zKwg^d}7C+-eoC=;|Daq)tnmnwvJm^7qwEuZ^bmek@5*>=>MQs_`sP z8cG%Tr1+7QlbBP8>Ci+;7jX3#f9CE{Sn99wS&OS%blEu#=hv`+zcDh1>t$j6bR}AS zUF54vyI+sw1X47C=(^T65%HKj^H{1M*{B_hgPAt)Dm!3|U?Xex*514%(+({AQS*F} zVIt#4Wnma0p756_2*6%Tvvg;9-9dm!i5c5Ac!avpni~<8CK#tSC!75uK8Gkl)Ac|UO#)K8Kv=+eE zC-=&@C&o3Nwr2EM$BeMP+DKufALLgw6Rsj^Q3xZ};9mTlYaIan&F_^qu!fjt(ZWzY zj{*ZrQ>9vw7yp7UIgyf95kQ3( zJ+fp{2!lH-)_9I811>PMR%@u0XCVex)KtI*)!2s$jMy*#*~Eb>X4pT7Ut^ZsPlRih zWzuqFH~2iVGJ}YFo?Z;j!70aD=Vy#rHuG!3kMuUZY)66;u@0=q<_tGa+T=>yV=yK0}$E+7&{uMGT4C7s4P* z`asahlt3u7D56EvV$iYfpK(GY`B)IaWk%nj10WdW&TsQv335I5D~kAi#jEb++u0t0 zie<|%y*f<7N6h0amVv*r7(?0s6lBrT1#JE7JhbdgR#8Q&uq*V{#|=DH)Z}6r`~Bu( zKIC{(dWEyErMj7Kk2@9l*m5}Q&cXQn?~j(@Zzlh6OKc0Ryda`l@mWY8DPAEKCQ7<$ zC=e?dIF}=4O>t4jO->+tpH7ID?L)O!p1p5XhqVXGjW@=BRt+l;oNHqXq z1RI$k-0+==bO5K^Z!{&x6QeuiQq#x=KyyM^Mnu0J82s(B_Z=i&yOFCU6#`C4+E;g4--vGyh%Q zaOSJzZ=)E;9a>rTRlYgLE<3zFOG@2|-^W8RrO?Dt+&Hjmi)uTGR}frOcK%t>m5~Zz zQ7)xMS3f*Ec32QWw5@e#Ply<-Hwb6O)hZun)|Dr4@!~;&Q z!0FpU;xAw3&6L{Nwd418KSKgX857O?k(76PzeR9Y5h0lL$NZQV0u|S!c-)zebO=r>30CR)nZ$Lh*r}79c+j zhY*B5(xK%-B4wS?;%SHYWLGy}=q{T;`60~gHcb!$t8oAIc>xFtx-9&-Fr_o3IoPi#IysJEw{5r@DCk6NoFRCT!?JoBS%bx zjf;wFi-XH!{85oKtX*N~H$};R>fbpw35fTi(X39G3w+teh4O0gK>xv=;XKf!P?K!M zYO%7x0!;}UE~8yG9OL};@9hYw4ei#O%mRV{qZ=!VfBd`7HlVy_Gr@N}CYngCMM;&5 zn~F|N3p_uRilK9WEKG+Dht9;z-xj~I6%u-6iUR>GHFU2Fc&8L&M5~N6Sej%Ew3|*+ z*=sYz5zn47VI+7uX1oqETeL(NVU8->LSWC5u;uniQvvLhP*9#itE#S6(&?BXUa*~y zUengA#K+Bpq~udmlIF`v2|WNxg2^t>Qzeb#Tk(^Wt${e33?e@rq8e&(rLdabCb_` zrkLw3yruN7?LH>@s_!quU*9v^5dVqNw!(Z67eq2-{uf~Oe?rv%negIbWBZ?IHWvra ze^C^}!TaA3`S|}|?!a_S8$l6|i+RV7+wdmHQ{3vu*Z0iPNftzssZ2S$-<_Y8Y>;nV zNiq4DvhsW;8H=QGR6j-_Etnca8H@sI#{WF99oc{X`fY8VKde~zgnyl8>`78*7vt5zw(=ZP^2acmbD?dP;ollLKA;E!51wz2>nwE?4THu6xFJ$c zmvwg=ZBi{Qyty}iLR}|XAohYQCYpndY%_Bl>st29oIovvl5Qqd)>;Xjc7kPBK}UQl$)7yEPlwZsQuT7}80N0o zDT;dOt4t8Rp5BX3e!0?5e%P>1V^y-FtPI>T)nAWpcB)3u_72pj0rWgL*XM1F&3`=^ zCT{n8u8<8fU&NUlsEJ8KZ*#^%DeNg^IXA4fiIhjVw((^4rUnZlT#|OnE!G#`aYhPg zvJS6NvVV_(%O8!ph_(krH;W<{mXMvGn@{ax1`P0!WH8crWGox#1yY?!g%lE+J2f(z zN)t{&f>TH&IS|Ad(Jyh;g07f*3P4CpF2=&E15mr)!j4H|yV~iy#f>QQ+6-f{Fgkfi z&?uPgIQT=tM}PlL7Ecq~l<${sSk(+!G!3k3NsJLUnpYf6QYHdRAT8pDEh@=kz?Au# zCX7WWbuzPS?m9oYMeEC$!s;=H@}4gS$~WWH?|>#g;`Y;ah3ZO?suJ!UwbOg;APD|G zM-d^rhwl!`S4DfSFm5<1yn)B>?;MD`p(*O%g?mZE1;OsI3wgOtRe?)1wRB_2^}jDnp)4j$n5MKy1i~u4&U;`?@&lD z*FVkDgv1qDkt_dzz~&W^4my;~fS{BVzOagzV7H080d4||(`E&IFYwDnubec~*k zYnEiOgrmCksu+pXW&Cr|iV(sXUe)6KYZ!B=q9;Y7nmq^dv`pBIq@D9mlN}4%@fFZ8&*1cu-Sl zcl!zHOY0NNV?-Ds2M$lIr}ArQkffE#utzIxM=0X_z9}vI%~6IRu^0mPsp95=s|}KC zZsWmXV;2H<uB#B}L#@{gQ&Mq4pBsxKJ@JHi zBbG`s+xB_dEcmTdbQTNA**Gx)bWIN3b-^9LcvEfhl;Te{Lo{P6%J~Vs9_m4n3<2UE3)Ge%`uNayh!44B4(Th5uR7) zBoyu+3`2Ji992&ghQXq)!ikZ$%Zl+$mrQ;DbD^?MJBL=m2-f^h5Vu8{#l|Gyt#T~_jI~SF5E;K#Q9X%ZbmXNBoo4-vzn$P z_GTEeJVP>M+kM_A_%g{d^W9L7c59tB@Ah~V-4MMC9wO~u24~>nr9~5XY1ig$ew*zt zT?3O?&RrO9$oNIIu$p5Pd}=lpb+9xE+$-qk4f6br_{rI1@bw|=+r@%X^T~dk8|V)e z2Y|VoDO8mCe+3i%n1TKv8*3m{|9jlU^`F7if5csEY%Kq`4m&6Bf59T)lF0?A|k8Le$YCQ=GdS*Bc(M}SFc}2d%Vw5R1_YM3RBTn zD(v@?sf&m8i~hMk_l9HtMtr{uU(Uil z|Iha&b~4IX00hy1R5^HRaPZL35V?R)@0YgEgLF7_7jr&I)%WG|7qXvwpp0n5g7_dP zp(!{EH8oW5tQA{sUe=Ul^hnh4#iUJZ4xVz{lZJ>*H5mr3Mg|1TnTbGw85kaXMb7$# zNBI1yOXnt0{POwZtFK}Fx^*+oBgtbP3lYHy0h<_9Kzsx)P_XaRwLw%rLkt5U zzAHn47dx^aDM2QyEP(aYIUOV2HAB4p z8+$~xQlCldCPh9}LExk*kKjU7^%^l1A<{iWE*Z7(Pe#K0;q4nZiZX+en~Sj;Ln{5^ znnmxdm7ziF+NDx?bougS3*MqHnK3uv=@u>xY?8Vy8o6fTNK@B4QZ4ACS+*`?V?P&Tn#-as0h zxIbu>3Uy8@bXv^kJK|nY0ql6e6K-7DGuY9GE}goYvp{!9#^Yqs=9HV2ViT&Uxh$1p{n^sU5-+&){xl;pB=1b@A@9*K^(gMm}zvu2B8VqCj7F)hI zoNf*Y1Aso=X(2ZJ0(?S&W_mM_mr9OKieRQf0HhNX0;v0#V|>Bw!{hb) z{Z0F8HuM%;q-{Q$&Mg{JSQ(rph9By-feFUyRSRb{&07JS5^!W9lh9QrJPJq9!hQ64 z#M^mSKZ1R@thj&M1Mq3b5|m<4k~U9oA;}xf`Lt*>WTZBQ)FsH0U`0jPh$(Y~4Tbvr zzkP(e9S+1C@i1r--J4UMkauJObDf)qx6tIb>QqJy;?k2=zWkw4G7{>h5-?z7A~m^$ zJl|`6z`p#!;=f*yfu=7jBkRvFKD961TG~WWVj1nm@msP~rEnmOLc$-a1z!5Kyd6nS z7FLxl1L*TIAM0W!v*^>jNr<3gI~-vSK~9D#8(|Jh8+q}I!T%4jzE3c>t`D3XO@~=< zyFw^E1?(E2&>Nl$Pojue` zql3bhO^Lnn788o05rKvWy`Y=E4h?~my?tiobsyTzIbxx2akGc20Qf{kMCB!5A+@TK zQXKxwzb5&LI;%`iPb2B*3 znXF_OI3TtE*_jb|mcgA)J=SWgt1XLF`g&>>s}^laRlEL{n}L=eLb&cNZ(1g@US1NP zC?`M=DqX_iK{s2(KfoYrM$!!&5@8-z=X(%R|Dha7nWSh&n8Vt{$}+angiEP zJD_uRxoV|38)`H}FH-exYkSb4ic))g5_|sY=9iN|E;OYTY>KALhD-0ISWlBHOBhi1H7(#+g;Ao){U46RXh`8f10wy`*tYOY@0qwchWC4eQVM+Lpvfag zcaUb4`i*c#Xele*tEmwaQnCnHB zQ>T?nuJzYfT%zg`Q!dAIB*;?*Z7AM6wz zO`}3luo}dd1APH+WlJc@ic2I|lLTP>9Mso?LM2)~fP(KLQqHQ0z^QqCx~8T8y^fA1 zTyn^qf?=)<>!E8n*uQPLf;td(Da1JrL4aUJ#uTV`hpcQQS@wZT32Mzql9+I|$aYFY zgb3+Nls@F46ag^3;D2vX41H;^1o;sTKeYOBhisql;`lozCbDKMiUURVNUpV-Dbl+9 z07I8di;Q-lqdg(((WWv%p4xPmgk7vKGX{-JCISXl1a8)@qeqT^t&qlq3|hE#O)$`k z&gc&dcL=+vg1QU;9|#@i0olj45b90+=QRXcd9fnhW>oUO5mL-s=Oq*mVJkEuyWLXA zq0n7w!=Tz~g>zQ(EbU33dL|0|DcW+yCVjy!^q3&DXb;6J6-x!=12A++Ihj2=J{U${ zwZ1eaYvi1{ygj5%WtQQ#N<7JIa40Nnj#iQINUC^lda=5%V24<+ph=$_aKb@^iE$Z; z4Tana5#N-MWixOJlG^i5J$kN#nHgxlvH-DxLToWrx+8Yk6nxR5O(P15I!@O92{s@4 z!PnR4G0A6K@?3x#8N5OR6@-&H)mSFQHx}h+%GEMj=@Df~h!4D10nPhrL% zkL}|c&#&-hZZHr;gKlFPG)O2^GFIZUIOvzT+G8nlKwc2uLnooWqYoXoi~Y3ZH8k4I zm^k5HDIvK*Sk%=KR;BDPC?yqXS^4PuVvsMaE}5LVlT~O!3X31+ArNB7prv4HE^9TG`;iQ#u}ND5QU1?}(N$*1 z!k(|im13=9Hl_;eJPo&wOr7hq?$2jvzlU|35@sU zt=>|pqL+d$5adLTgj`Mnb-G1U0L~nPk-ui&>3OJVG&VuC3?Po&7Ks(pBhtr3`dtlc zzSX7_brePjQgiM%Oq2X%iyrd7bhgg6(WxcM$z$C0-C4@lN8WasSqhIF-Y%s=M-H0w zloKIVdbfEg$8y~g<}>GsORIu;H%%(khUE*X+NkO}Csc(n5q)xw?G*T0-naQFc}>NX zSZ?5X)@v}EBO|sIO_O3H*$?$i9hR zy?CvkLfF|cggupVwn=(Gk=bFV6p;?ITXcex49{#Fm4!b2P;CUP93gTYOo3z~iaADQ z9sLVo#A*~67lBR@9EpsKIT!l2g5Y!9O-rpQw|fq_tv!6RvG6) zTghve;v}u=s`ZL-^FzUZ6nZc}=0_c%Yhl=F^fa>E1D|&@DaUvZ>AdaiE6(vy<6D@L zxV4H8i1RsEi2cz2mE<;p2D8ktbU@6_0GPaUr#W&dwf>Jav8mf3E7FdS#9m zQH+2?V0`ga1iHI#Y18}HM~BoZ=frA8{zl|si4>>v_vt*glM9spA6T_++*AX)i^fci z3#A4KoY(YEvu5%H2Clbc13^+uhVmf~AU(HhS^0{AcqE^Ral`S}Hr5-DY zo0>N6+Q6HRn5V)P5Z;`U+MEz0+bK!!J1wXzdwwt-cQ+i7HAdzD#w9+wt83~UJJH7|^qk8ieEKtA2&l)dg zKck-(TB)ktx$-8V0IbsG-17IC` z);|2_v(Sz|k=2PugArMI+J&TW$`n)EeZs;uRG)t&2a$=F&*F*$uTB_aN?|CIK;hyM&d9F#M-L%6`raSE_uoGhvJkKHWrEiDc;Os>fd|9! zpcHT@y|iQFjt?L~iqgW@>rI3ibnFKz5&P!Ty*mD)Lt9{FTNqiK5+kiBe|+dtiTJq+ zJVW5;tBX|&d2~{6j+6#f8W`?!xwE}L4Y5N|$r~C4;8~_T`HkxGeoPAbDHSgyRZAxY7a@(LJ zIN1;2qIcY47D-wG-Kk%v^m2Qk@ZCY__BubInkd^$Z zCx=p}8|du?c8Nn?p{4X#e)48)nq5kU(8PFu;?)_j&*^-eK~a1^ z$T62=P?k^0wkHk8hU*^Eid+)r@{vQjA#vTOJH}T#cjLI~wXiB5QTV7>YSpY1i7F3I z5pNS=ace+891g0SErA$ahOFrG{|1~LsM^4SJ-HWFsJYgh~gZ3mNH0Hd<G zorEo1+2`$!>TYe{jYvH!;5BO@O0I1~L~vz|=o*R1i5%DP=6zcsgr~< z3;N0{v5VnuZt#BSqbm=7wGy>vuYIb`Jv^RkD%d_9QXXD49kTjVm)}Osr-gPlz3QQD zDww#ZMZ^HB*6g=RD#ql9x+8nAj@hG{Es-6`EOd6yShR*IHGEp6HB>PtGDgY4NR_X+ z-Rtg1l_S9<@ED|P<{}m0%^z@YM5&2vw*0AUffF48Q$)*bBrI*^Wz&T)G@*d>Xi?=^ z)?+uo3{)#lDanYTgE)7UaQAl?;X}hM$>s9g02T&aeED!oq(bLy0N;_&19vMYP9&x` zuSbToCs(3uaGvzJBONB?Q|Ip$i9fyIwPQ_(!_MEXPp>d4(_iA61#IG|BRIxH(5^w*wwC#e;PHJ5T5Fj1pDEQXzbx(Q96sX~KC8gvSl zXIjRSMOD^Xd}cS)3uR+S)~4JKaQLbdU=wI+f?qBA#puC;X?Up?f%H zYO2)p0Y+brB1wp~br8ks7{{ty-NQ(ig-o1v@_8R+L7~b(Q~Wt1D#H_KClyX;Rj+>yH@^4BnPG*4ajSArUIU}3%WVa8>b`{) zxh15)E>K-^9I7eREccA;sL_f(Urcqdkc1}d$i5j=@6{r0sj|hJC|MOQN*R|_G%}4) zr_(Fk=p5{R5sn9z80k?AaE?nHQle-?!AvbW8@OT3gF&dz6xS_@j8oYY^lbL}fS?F) za+$n)5xF|56DP$7&@I>alGEsSQ6L@U+07_ZiALHL)}#7rL0B&&*Fz^TKMx^Xn}xfR=G~+!9faV zyB57u7+JVjJpn&bi#S>#HAbEiGPSZ6Dk7IXxFTS%kGn7G-8A<2H$(V3j6uZq zdc-I7Q0UYuMoyf{ma-Nua4KfIaUFSn-*Lk=3vx`o-=Qb0M7;WU1u=%|um1R0){JltgDmFS~H6DI}u>ze?R zKo>ox`RaBV(bSQySB6Xb3h%9%7Fkq{>64svjb!;j)5oPe|qeh~%K&mv&Q3*eXb`HLh z={!z7!u+H6r5qoHlmO@T_{$}Dn!cN~R5g1BhR+(3*NKfPMg1X}LsXW{)pt^kkl*Su z{)|593(sP161tHHLhzkjyH_Qr*eBJ+>CVf;2D%b9z8@qt+uiXfrjbZYbe45o`Pv}5 z%N${D#^shw*~W!(o6jC7vQ!*=#C%79_Qath9JDXzrjNuyKI8m@Lwj-4ZwtII`3O|yuLK@vDOs+`|E3XOVbH6Yggc?;}3;SU@n80EOZsPRfP+&#qwc&&JyY8_#$0G2hNv z!Y!sH8vfNhi1Lw=Z5k?C949g@Olk=yIw1HwX4lHwI{<`^>e`|AdB;xQucNwt1_{F| zr6q&w{!v4wHZ&<@G3L;lxny!AN&1UH7yD$)VX)|j|~UHT0CE#{__60S$DMe zD;$qk<#5+RNsmNF0xv@WyZZ5Sf4&(kS>NM)#N0_^Ov=xL{SSZZY2@>(sUDSKahY#4mTSpYSQU>#|>Lvc#v8v)i(;{V0mTLwkaZ0o|fyA3k9yUPHB!vKT3``|vf zyL;pA&fxCSxXa+~?t{bacb|Lqx$&L%$G0QyK5?V|RAg6GXJ=-uUb)tKp68;T?n`a{ z<8P?XB(m+yG|1EBh8{j0`V$gwYK?J7?gsLqYb5G39pbZ?X{|gK+77%Gxnkn5KeZ;P z7qdKQF>m=4U5r|k$x8$S$wKqvQ8w<}e7SRw+9#y5_e{7x!xN}eQd82@=7o~frYbny zj>uk?Ye{~4n`FmS0xzO=Hd;v}(ntK>2_Ymh5}%q}KT_kWN^fce-n_C8Rbmv|_twg@ zX&#Pyk0dD{i+Z~7>f*F+1EI`+RI9y|CE%@4osEmdgg^L(!N}0GCddylyY47Ji0XMR zQ3NKV7rGGC8zWk*H5L;hFn(`8#NC;>Nj!x!wr?bm6&3R4Qm-~zk}n*)dv>>HuHOPk z|AJ1#>&lT>*6`dvWA5~G{jv$a(UBAo_PFj+5zac3DZY@JTe>;@wTI8`+N)^BvRPX_ zTB|4(wkUVeq8r~jo9Z4^2X8h_BG}M46kv-)_ddMabw?)t_<{tw4NoOl=>-* z$x?O*89aH{yX2aiAE2Q_4dn_NC@Fl!JUME_Aw4<#j^@6>Clphr#qPLnOhTYv2MU^F zm-yAckj};XEWZ()%j1Jb`$-6qUyZ`Q3dRu8_5Anr^?&4~|4LtTb8-F?1kcI!H#`}f zT>mfgWGpNF#gidkM@?ZUC4>XNRYT4O;xO??Ck;3|?f8h436!gk;`ClDt9x#L&U-J< zd~UmZ*3m`piUbc`_aem*Yungu2<%T04j9vUk&%nYKM%;yTwF|P6{4XQuV)xqg&e9y z@*Z~1M+|~Ub5nF2i69)Vqqt#!^ve3YBY@Q(Ubk9t?87(BS*?xZ9s&^x_rrg;;EU8f z2&-F)-XDwJ35xEQ53rZi`O&GVG#GHikM7+(j{Hz|m5@}Yj1eHp>jzh9?da8@`%w6m zZi>uq+NeZVxJxRFBWLpEGZuO2yZK3%5{NG&iwQ)jtX7~ULjc}99FTGEUW)>I1W$F7 zRAOsqplO#{3sVgeYP=#pb9OK*;~6246PV|F+je71Gcsi(LT-yzdR7CtkGeZS|4MSn zVB+@d2bq2yL(?xgF&;v%*n9H3Q6 zV0RG8;F!?V6`&nS{-+urtLaxav%1~3q3!M#4&U9nR;-&+mn(4q!UP>5FU)%V58fd% ztqTOQpHjz=UZxmLFRQ1LGPeaU*%dO!K1n6v>soQ7O&p}A$!=8X%L}qAzID6^*CtRq zsk3M^dt32*HZ(Oy*3)WyFqWhj6&34o92aj+9 z_JR#;Ia#~dMLx5~y<*i5p?Wnmu~#^Vsh>!l%(dC25OpZ6Lda>gu<7p%Wc}Lrte<&T zUG5qMyWuTYQ}&NUS*}VZbix7zZ6cvD4^F|vL+LSqTXiJQcWyEG)1v4ga}C!%F)8>I8v zCp&Jt;trisXnLcgIvmIYy5I4Cqxq9Uh(d+HA)(`vv4|Oj_55eUD>M03WVK+xV>mLb zL9%?qQpu*szPYdIoB(c;$eEB8(*l$w}bJecv zdOwN3?fy2u!5B?Vp{<} z9a^E$%qpc3BjpTT##NN?HV{-D=YifNtq)BU> zx?rQnu_riRJLXf6;^!enTsLiF#-GD4wRtt;Bj$(a1w3CUq#8owpZVghlC8P5nWIoG z27i-owExC$_u6A2e3j8TP9_iwZTlb^*=|MZyh}thI!-MAK%{> z2|N~)x!5Jh02fR@nf_2Ux!!=(evkqwx5W26D~4(9q-vWr?@~>St*(}ZeYRmGaGk*} zX18YL!BR~Eb{XU4dd6W*#ETR%_6B-}_NCRUaCis)NYxf(im|(_zVBThHu*UfCZ6QR zp5jbBTHeM3H4HDVNiZo;B@{Hksn+LxVLyZRX_`jsWbhB_{ppJ~;OT%oRH=}a4M~OJ}9*>tZ6bW(Kh+>h6PR`D5h`$Ewx+{fo$DFRrB~FbK z%-V)_JWprEC1+uX3bpwZcqXtYwXa}VJa-IbgtD^o@+ukj;xn);vKnGwmgcs#Y|SR@ zlKu{E$hec$MS*XBY5M_7vB2FFH(icxGI4s!db&;?<4|_FlmF}Zsg4DYbY?FaBvgkE zyDSW;7gP2sYDgJO+Qnfp^~G^#`t}r`mBL7noj5ZL&6#fu5IBWN$p^ zM9PY9+$yA$UlO&>6fvxztc4A&gxti|POy->JBu2&bVY%QMGuqA2&(S41sIdFA|Yxo z4)s$0dPbiaEMERSwxUWEyAkRF9!U~WfAlTB-eqsF?MPl2+QiYtZHT0K_~}`NfEb#8 zO18K3UZkR3TX1GpZwj(5xf1131RWunD&tt}ZFzvqN@1Kf63CiywKq7B`A zwp_f4-z~HXtF)qr!X{V61tSKTNs`DgnrhoyUuN;y#8AnMTa2jFpU@75X|B}rpeUcj z?g2tFeA0ZCh5;WcXkixSp?+o0dmxl9lr#Em6J%71e6?h+GNuq zi=5+Pr$I`yrPU3STq%Ny&-1!@T=|B=4vm}*zOf#)IM?}Krq73GW~7DH6*!2g_s^QTxdiC@K`|3;N z;KW_B2-ZxZ2ZM!e=Fjvwd>dk)9q14ic}{LaGp$@|ga+{H3GjQT8EKG3)Wr}UP&)f$ zS5;B0y)M*Sal{O}^t29gDCneoysO+k$m~XJ2F<1OlC+aaVqiNu!wPT@fHV^|zm=??H!OMxHsBAyy zwSuXk5kOmfc-yX1e=8Ik^{2LMj3L}DR5#gO(0d$N`EBlXx~1niM>%DwiCZ;qNxv=`=OPONE~U%DN^N7{<9j z$A85~+1!cn!hH*$DeyBe+yW<|VmF*b6ipwLB;0%WqGd90;&XrVe*N%rS{4$kDJ@C@ z%-7aFmYn7ks>p}TIWR~U69Ch^jR+y+jmE_^T5X>tVvPdN;h3fpsHR{VqD2s67}G zV8f_-KP1b;g;60H9B=ERu3Qi@^DR*5{gS5iNmvdVYFp6m{y?V19;*&%aWjA*EFO!s zVtTTJb6-|GX`IuigX~q;Tg#bL*I5_|T163=`DyrYxRo3b7xZSBuIp@m5`WStEbZo>^0@07;LlB3kuVZwZqIPlXqa z-?zBMq7o!>AF3+H-~G=~?SOb$-`={^c0$26$HQ_pu6n&^`BaOA2f-#d|n?P-!FY0tTv!k1btp# z&!2j0d?to`-)W()4tsmIX9j<|*LibM z?88Cd*jkmUW=?{>RVdQ#*OB)<9#{MJ5*Q2w7GM@h*zwkD*qqgBP0Dyg-|QWMb-hEt z<#`(j|+Tt_u^w&4*7}toDaI z4JCy5c~vt$zaQ-{IG5>^sf_L`k)}jEo=Gf>Y)^f?;vl=$$gB4tOEapPv2<-)muq*{ zX4DDMHA|l>`07uijQ_cJ{$BRbmWN25YImk)vs@SGtwwlzXV%+syV(7~!>^d38*knC zHFHCdf5$yF_9fbg&R~(A2G* z$#)#>{+IpRvD4GjvD*{FwX$MSPY86)YmHy^uuSw>*Zp%KXXxc+b!=|8P+JyuWX3ZN z7cUPvMxl5mgDG2obJMr8yA#5w#1XINbnhju9bB=PgO}Oy{@wcN=Fj`-;tL;1%<6vP zrUY8iRAlD#h55S+i+&ZUK$KQd;Z%N6$0OdR%RBEVG2D5yK6mH?#6WY(!ds0y;X|fH zY1`T7K5Am2uR%Iy_a)LcHNhh2wU2e_sJ6F?&6?hhG~QY!)-!w}$Cj=)a80jdVN+w8 z-P!H-_(^qNht~#hl7^GbjK-=TK-zK*+7m&aLpo`g;DDI($)I$29W6ES&KY~Z0rjhFjTQVbqP~MnI?ZicxM9+m_k`gIk;2@8x)eWVCs5za$wtpC31c4 z4&G$ai?cvf6a0ktRV@E89-9_R@!c&rIeWVDxp(SV+U$lVWasq6XP%DATkTvRQIL*t zZR%}VtZr8P9J)#CA4cYcyyG{)snGEE1dD{7u}mZf58Zd?RRsc01* zu&>&PP_U6tK9vVM*FW^Dg(ox4-ljR`>qJV9JCG}NPYko2Zt94yd-j;MfSSqOq~cq+ zcIa`Q&e?FDV2%lF^)xCsmLw<=&{NpuaLT7<6QJQNlxOhd$f_zY zO({A6)5X;nnA>p@FvkJ-Wb7pc*J@hSyzD$>5NT=V@z$?X;j-?qeb?1|ME9TEA?1$M z=o6M3FvW}=DBS#&!n1oNG@qJfcwyQ_WDp#DG)}HK8`VEqeuM@pMOnM!UXKdiBs`Ld zr#T*t%_%NJ3#+ZrGK)$aZt1IF=W2<^6gIPn9+sQC<1rmk)9QapC=nwO>r4A%cjJ^m zY5@sOkk3KyjPoGgHs6uKI3Q%AgU9tfCGRJu%UNNCH&UKV9^cPkrfNI%u*3$6T<{lMCT@=`ss2g9puTgOr0k%;rLJ5%x1Y1hx;Y-=FuvVBx6golQfT6S}&N zW6(nLQ}9%&;09E#)`E!6PM62Q$Pf%g0)cp8KfX7Ah{2Vwaeg1>Hp3|81mVV!2mv}p z?5kh5_f(6Pi8nt?Mf0UA62jdok1)C`Z_qhBNMv@wlC%mI;Gw1Rez#>zx3(z!+1f7w zdclp8>^=C!T&ifCiPmoVJqXXHWr3BEC;3IwLNG zgKKC)Mvvr? zzD`mwhK1Gcv^Z>2)BcQ86*v>BAij~XaUUe2=5(c^-{uW*kH^Rob7>3PcQ8yl7GT!* z5(+KWsS08JOlV~5M~Qrv#v|Q5u)A43C6-kvE#qj9nl>&&t#kYLp-ekv)_IO|C&CmB z8vY|>iW~ajV+C@ZaR}{VXG;Ayt^Me0mig$?)Zie+D~N z%^b%TKjenv2Jh`HrY!7Q52Lj)JZHgSe-TPnPQ=feLCW#)@}Cx`z@hfn2mP__SAS3P zC|DCR~RB3@fvvh4>*ONr(T4qS*TD4?yflfMd~bdsEjZky;QQ zBS>C5OYZ}vM{<)pYw|#0rq`zs0#e|>$X0~Mo$F*HxsLUt)twuztUo1-Zl;ZA&0mrX zz`S6qP59^}(sDtZd#TNU^PMW6+=~D#oLWBeWh7U(Tke}zTs~cst?11)IHxZ@WKyF! zovUuAjq_!yJTd&@$uazM*WqExCz#l)a2yK1@t{sq&Kv|!YYF6_8SP1~J!6IhEX&U2 zi{d)9a!$S;ZZpuP4*t_uyE`;qaAKWt@C0~1?jmat_6L9d#<-kzbv#sPSf-S7S;yZz zLKQh%IVkl7tjRxS9}mpS+eeFkT!O`Ln{9_raIQ?QIojSvByfMtHGW)ClR)ku_PfcC zok|1F8QVmNWl{4H;4nx1wJrgbOc1|I@ybS>NDf*ZW!T6CJg^?91sKIosEbnu6N9?H zW@bMii0q}rstcU7q4dSO=3}&HyL+;~!RZ{&jB+mC=zBi2EcgxvEPSQrhl#o2VBbPu zB0_D8wj{+wY&#$3)ONk$78zblyFhzB%$NjY(u35=kOiZ{MZFsCtpM)6IXNv_s8rX7 z*F3zA=jQ3u+vKxQ-8vso-cJ?aT~?v_K?uaez=;lD`E5+eBW+rF>o;pMe_{(q>>e|nEeoQJ zXO!4(wu_?aa~V=Cnjx6MFj?1DoP-p(q0Ma5VoHgG-rGfexLtN)!@uL3$gsRV0YOT> z*qC-|IfziL(aH0Oq-8eoF)4XvJ=H?xZA4t5^Rumd^_wW38^NV}?bWTGvz(^~R>+WH z-0@aXfl(0KeL+}+lXbD9K&D2W*{)AwK@>sXvK;Z^h56;vJtTpb-pt)7T^sk^m~G(D zMI(wAV%VZim71M-3=1FdS7EMgDTQp?Mb6nqY@K#^=<3;4>lKc zD1nOQT-9D+I~Wbgyb%#)G9&k+%Mh$cLy7&>?&mK>h&gKC7lSKwxB$gv>24etD3APd zd{@Ww(qDjEQ;fH%P5a@rVWRc@#8ZZ%rpE1o8F8a4UTjB(BG5lMj#bETTH!(igau6j zYjUCM5u|jC+W^9I7!o$Fh-@8WUh1HwIAL7dRI~|VdaHGb&cvz0E#>aTbH{AHGZzA? zj&X@Vxe7H}C@-;u^FfmOZPz_f5()w}ZP&R?E|aa@1#$*SRdP^K_#074KM3#<1=Fcl z0vbU}q|q6E;^kO(w-+$Y1wH{)g0vLvK-w5bC<3yXns;|zv32oHSf!c$m;v?(Ydl0{{e}H%J?G> zb*>swo&22Uy>)w;*xYROHxna=xK0nEBYp-$H{{)EB;Z8QGLtqEVcitcP2Cm2?vi+_ zF?{YbE=am+YUX>N^t)pkG>u+{b|wYg;~(br=tmADL(@WD-Mo18^sD?vfo?(K?j70I zj8iT|>^JuyAtgqmit9*Tmv?fcS~a#1oQqH~=5(Yv7@v=)Lw9eqgF(F#jaSKLZ~hsT41yh}soN!ivEnGfL>85H4zBoZ zmFoGTup^>798C8rd3|bivl63{xmfOO{vgI(Z~+pRD7{H~_T#Lau%odWYs8tlEO&Oi zEp#P^Q+4@;x&(E1_%LtDek^!0s?~_Xh}_yLc_JbeM3=!sOYKNLOA)J~uAnwNu^hIV z{{v%!*$#!91z}f#L-0D|E=Q~|xMed096<_8nHWve&~R75*;Gsm(Y}}Sz$7(HMT?Rt zE`Wh8_&wHvhU(3XOi3!K#Y8&U;Yc7}CpzeU38Yj3sa*A`2q)fAzrLZ$IIt;j!hxpk zSD?yiLVen+4BlZT49k!exl$jx%IPd>c;A$@3rq5c4HzbXKg$wkHyWejwGQ|~x-Mvc~SfAXnPM(KtN zbdH#}*@YqBmcu!IV^~v3`cV|j{JL~6#I5eRV|L=Wl*M39$|Vx7D<$ET+*MZt;ay(q zhMB>wIwOwTA~P0C@JgYV8etv3%ZuJthEPSexm27{jvu_Vp;HV*bZVQ;n&x0RbqvZV z*YUI$hS>jnhb9e4X-hYq$#|MkPC=|rC0O4`>;Z(cWx-gwiLE%KkpDuKcg)6^7uxd# zW?OEFjR_jC-w$WZ@i&OhMyC~rK`SEA_}0rQ8Rh0biW;YN69^u>w+AtkTOPKH>1su8 zSFe{0v9ll|Wf~f}$6h29 zdW$z0@$?b{pzu)}s+UrM`+R3iQX_a1F6ZVSxDj~*CKq>6py`G zLAecKZBCe+hQ!mQ*s43}HVC?^e)oYQABX$VHFt^{vV@5g=Q5WoupU|&CKzzq#Omjd zPS+mz741dvB|-unaWhn7JK&LgTDL(ccViJJW*6!urtjDwryznGC&{w`|9 z@-IcrK+u0?$sZPG<{-K6{{blwP1kfG+>mu4G_k0FLCT%kmLUyn<8np(0BToZdW@IBx6Mq>JjInDUQUln4o}Ub1&c~zUV(gh{NK%diC?>R6 zSUiIX2$_VyDKF&`x4eG7Di76cXQlnhYDKLkL& z!tFb?(W=1#XP-vB3yR8Z#!IU}F4*uue_t?N$(-madPU!(kA1+d1{(l;BnH5T<*3u5&fY%9_uLzyN~gN$Cc2hP3CSklK2ZlO&N>W?Ko zD-Qt)IoB=n#WWIewg}M|_H6oigD}h?wOTSEof52+h)B-p5!ibwWltO)+W4#IDD2wC zoCFWrKPZhh?&@i|&=jSsK-B^p7Z0%GXU&5;#HIUA99Og|nuJG)#;!cCJ>!PWnjMzs z2=Kue@-lfyy@bp|zEPpt*4z5G{wMp}vk4n;T#Q)oVZ~J+!!Y~H zC;QA?0qiI`pl9RiV)k{xefzlwtG72W3sEIkQ2Zsxo=m%vb3Rn=5S={>wo#G(2c}Zb zx14fQ)3V6zKu5Bl+T|)%k7a7o&1ohS!x?WG$_wNB#hShfF_cL%T%kGE5>kVE^n#uj zAXWIGKV)ODzX~Pqctdhd&BYMHeSRaZC@Ww|LYJ3t?Cu8p;Wj|Bf<ITk#GJ0@v{#|tg=f6_jzy`7r|Jz)!gLv8g z-9h&BRhM!Ww2;U+G!Y&+IBntH{CUx;wyL3({ue=2>IT)^&h>U~cJ7+TMI_D2aT$!R zj0|5(X$!#)5dphKt(#euqTFPv{d9zca&&20(sTq%aVRNr-rY=ssDyMH%2Amy2SROo z-H1=$;3QM+U*)i1Y%)%@DCt^`iwT?ny(BUGtGVjm#1+F0VLPo=qHcZWx#(je@)hTz zXN|fvWNr(MS@V66RYS0RGN;sIGxjN>Kl>mf;MWKE)UFZz$#}A7L!Is(^b_I`Y7%}~GnW`oF6hbcKaNJQ#pxE`(#zHwZX>&ajj&F1Px3z!XVFUp z4pUKw&~B44AH;hRa8}^IAu6FY5NmL@e4+TM`+nwc3R2TO#pU3}UG>FKOnBIY9^YMF zKXvHG0AOMvDo3|$8wClQBNYRU_=xWNZfrI>(rTy#h z#pWBXDtD_0*asN2Y5^SxAvGu|!LJH|Y~8Elit) z$*Z%ua`2DSH@^3btGB;d?f+QAf30>-cCNoZ{>SOx<&-%8wVV>@h566r&dSa9Z(r`Z zX0G@n7>x{$lV4!r#p2L}NhqL1{NTu7pFTd~t4`pNX3t`#dSBW$v&&GqvS+S!HoJ6X z*MAXxJm!Ur_V@z)BM~J&bU%5qz+LX_P{Ruizoj^Ok770;ZIH2B3Z z+C!yp7;xa<^G;AIFWCz{?lR z-J7R%X?H@Ozb`ewMD`Ozi3RAD0DES016G_QGN^ICQy2+1Pn7;J=jw?&nLzR7NSY`n z6A0BDirWIq=siK9tiE}&=HIHTq2Ng^lE~mrZ>7b)Evs3L2rxEb%UzQJ$@sK6xvGy# zbdvCd)L7i%fCx@XRVtbn9l8mrA=x|p*ZAYDTmMX#u2Ddu0AkX@BOL2rc3MY8K^ob` zqD&!Fbn)6Gs-=zDE76WzXQpQPMlSU&eQA!n$NR1Bu7vkB?21w@w_?@wRVf=|yWUI( zjd&Vqr5$UwCctec59B)d;42IvQ`*&5c32=z|W8rIS=y9tc#HY1d zeec|xb7C|Fgd_V>heP7(kY&BDcNA}&Sci-kCaL2sbtH1!szwzt%L%oFUVB!5ESSql#tZTVtLmhdoW8)kq)Q{aBm6z0PQ%y zs_Dnm6FjE#%}QT_f72zX51E}--Fa(ZtA_0X6pkrHmwdTvl^CsW&-_9dc>J{rY;cYh zw~nILsbb|{PNbmrO&ww8icIY~z*^rRtXULU!xfnE!q#+1nui492@GD=>~Jm>*w8lp zi-jfk4#E#Ea$woVZM(rfOOYWZB4tVeTFSbk>{%(7P~ya%V?S%xa zRt+Th8+{3MWDi`k6}J68Y|Bz8g3(%X&UfY5-sOuwu9mqLBNcRG8S5wtDBi%Ecq;3m zL}$RGp+=u6{4yH-oy_>83zC}q3Mzb!;0$IB zo)YpIWnLOaiSuQ;5HFrBgjiYQ{P+bWb1h6N&=GSGt2;dR5{wd(bJM>%{mWlpk|0)N zl6wpqO))@-zRXBXLISuqtVcUi3DtyyWNWzeqU+Wu?o1*2eh8-O6`{4$Gof26JkBOx#zm#E9ik_+?(N2x7Y;9NGe_7af6I37Gm-W0Wy+giA{8hw)(R8 z@VvDqV4K^%x@Iszx_An?J>vW@!&^LFx2&`?!thU#Ad6jN6M;*}nf7c){S>JH z!R1}-?hqKwr53!PhO7Tf7ai93$AeehS){NXilD7fW{yvvA|Hm#m^8Hpj%46>_qsp< zeIcx^j%Z6iB?vdK8?g})moAQFA^OkEo8Mn8_C3L_rWv|=KwMX>n#Qgg0D432e^$GD zVk5d`x?Eeh-SnBvTXEVKO0ZShKMEJHr*7W`uI_$i_7d=ANf^elnzFkQjesG=)wPpv zG~yycdG_A9<+n}ge?B*WE2PMp*|~ZYjW=iTF{MyS(Gl?gd-!N`W94o|t z-*%`qr#N!uV+ffWfT)P--MI_iJ+3(QdOzr(!5T}FXy?vkEHVu=F=u^YD(Sy4?o?vJ z2@2i+xwx#tzvsMFhV7u>KqMr66QaBbY?p3S6J*9mop3pH=FlavNw|?0gY`_R`67V# zhc|XYLex#8N~@Johq|AL;H)Yl0@4~^Mr!2MrgOpPq9gOu`h}G*2sQJ2`YQ=6GOTmA zE_3l^piecuK*jAEh~uPHtVc>mH2X_WF{f7N3_}Cc0|+*udHwz_KqPN=yMJJp*J~|g zKlWq|dI>%eai6)a-aB$Z$f8Yu&>OYS_t9ZasjpTSjGP(!=rQ0#g0uzK!L4o@z#YIq z2C*8%{_|KFix%$HeaS=2OPP5b zAewa1>u)=Jxd3|o9Pn^x^+=_YLim6ym@I>uV2CUOUx-!sFyH4uD3abkRl=eH(VHFb zCEXXBZK2v+n;G9!tfjpwI%rubeD(Kbvp*G8(Ah~NjclsB0}jQH%SSUXL~kBcH}>2W z+sbc>2jX76lepdW5`UHddvAIB(BF8!^650`esLAJdAZlu)9N|r6J7N}j4|$`m&^tC z7dgvAJ?f17#!$qpB4kYkn=Nw@BalmM`i-(FW8eA_f-&Ep`Hgg19a9qLWXcYJY95h? zF$NrJVeYtKMpRU%yM#GYw3#Dt_MEV& zg%R8F*saGVn2V{F`*H|%7Q)sQmh4)E7f^(i=EO#X($d{^h95R3l2JaliwGrZD2!Ks#S-ouO%A-5qcU+@AF};OIPWLB3q<}eK?r5v(ii#cRM`Yne{YJ|H zfs)ZQ@^W{b_3R|_U29WbqaVd$_6+3%6@1+<*(*)LD*)x!NBmES*mQNk1=BXEHmlP#2 z@e=NTaOF~u%e!8tQ|tC3(=4p3PGXmQ4va-a-`#iP$KlFMzO4`^59MkIGXCA zjgZ21q!|mhRoJuO_h09m0I>OJvBaCC$fj5qw+%Sz%~dmP7b+|S$jsB#o%yh(c!FO9 zRC6Z=!ns0EP{oa}p-6XXC5I0kG@yT*@CZ5x5sYaQZYc04O?*NSC&NN$m7&8?IZwdL zK1pc-a7E^a5IGh}S8cdaiWGoK-`T=*zX^oDAi&nAQI-gT;DOrfKE6UhKGnBso}&XC zp+F=Q>>rSJ5OzO9m5L+|z4_B7!&tJSV9vEj@$7p=JIASpEh&^Okg0C>EoFli9N%Z` z1O!9As=d<@(9>*abgd9hEUvC+!?mAVa#^d_p)U;9r)+45ScX@#VqTuGwT5 z%(7%E4@lXj%1EY}e*r99*uPTrfpl4YoGMyVALN%KqI;b>1%2Mh`VJkM)9)pH_-D;@~@^I=7!hR_6)W{JG1x`Sr~+JVdFksQ!OF^uxlgusi(YZXM4F{ypUK ze&*%!K7u>D`hGBS!q%6h&!;&%mX~?C)Uy5f3tR;LL{~%T+`dOWWuIwhYDaexyWy0q zU=X^A{Nr`&GJ&kwEj0Q82=li}QxtGfp%=Z;bET%fMfw4H7efkI(IxtY4;vG{KW62| zI$cQj5~TotiO&M1JC`jR!>2twtCDU@0sYkza$9b}Sg%GhAqh7@980M4 zfeN2rH7>^R%cKlijIp7`%jn9niXm?Sd>`7jlhv+w*5_mkL-CyXO~}cIU|NH8zAfn4 zwcvcgS9KU4$kpqo=l^a-xH$i^4gUxs@v!{orkd-^-;wcu`IpG}IsZ#qmW}n_PYSDR zp}sSU(^(ZTKFR>_W1|a*V!WluB_RnE{rC{PnJkl*3}8L&5@)X1&@MyuCOuwgykx3- zC{r$>`*Li$6N&SJNYo_tD}*TR3)cMG7LtZM z$W#^m$BthJ)i6=YpfawhNzUhY?A^TuVnK?5j!?)x7BGPIV??MxpXUAm^3l`^-G`tC zc6kypy_i-s&A)$s{J5cV1w=hhRlSA{Rg){AxL(l##x{$=(t&Q{;k|*S zcoSw_k~dBEIgsXNpM?WMdrpuB*q@B9nVgUL*a>33DC)3fXM+&dm5DcH->dtrw+4{x z`56!2&5ISvl5Wew77cfRNMWU|0gKH=E0@v&*ngIu{6q3VDI0_ZkIr=YkaaFShQ!pw zTQVPI4|A^aC$V85ItL4_D~*G?O+)%ZyVx`^dPk%XCLd=4i+Cl=l+%^a{)WtIpfJ$JRL(x=Q>uIghqOXt)DUtkkSIo=(YR2kQ@E5j zos+uUmQz?;UrSqt<)8)OyHm+AuvZE=1T;ipf%1|gHNyg0QDs`5mV;G^~0h|XHud{DII|8YNj+XbiCvI z#nT!`*=wL>pm6fFHp9~F^`=crE;QOx?yvr%$&`O|XplB|WCL(N4Fb|tP96TV=`rTO zsyHmmuZsiPs+_5BLG$2ta+}|hAcb5!b`O(#@203@sg#oD=y_MSV*UG8Dg_g`o~Bau z(4b-0T=CSRJSpZD=HS48eqoOxWBJ?$ZqB?$^UFYKS=y6d-)0jHpE?4u&~RE<#u@~&Namw`E{Aj492?twZ`AiK>buM+wlvlWBwC|u5Z4fH z3M6PcpxJjF5oIjD=UwNuP#oFo>FiGza@i5*5ZhIJ68LLs@}50ia?)1Y2}3Cf`*Mp)mmh))B6L;Jh!D2|D_TlA|206DG4PVD-LEF zM_v~NOP!_6DpQJ)TXF?fNE8?>{0b)Y zChVYDoe9rwoGN8F4NfJV7an0{)Zz%UEA<;Ua)Ok#Oz=?|bhGe0i+3cIcpwUdY=i?I z4ip+7;I7I*i6^^*=9jq=#}Ub}OGJhk@P}GAZK?{AnG(ej*euUqGt9#N3l$2GKMe)^ zp@{~zOIv8?KqWo|K>ceZt)f!9fN87(P@WNE^WkqoM)&-1zS!&@1t`KRq*0P?M(5~N5uFm~Um8WEz@CKcw*pVds2*nrW7 z&bS0X%3Z11=D(hUOV5PNTXr|enczV@A&9@JmTBD*pv#q*_o2RvZQ&Uk9EU2v|b zA54U{Nl6PGyK#?r9;+H?{z0JO*P>qI9vz2c83Y+=$xWqEIIGeYRE3HjNr!G$+MqvO zlw-;YgoCCT;GDFy-t_Syn!zP{=gCPs`K7e8%?Rc)*y=2_4yGNLoL&gH^uJ7$S_Wyt z@kI()ZSmD6HE1qeslSdGjvv?Mku?JY{0_bjwlHwHg#Xn~*QL^(-+5~O zQbZ5hfIe_adb4pX&{_VpxiA<3u!!B*{aFoPzA1u!JZk?~8=4~|0&%xBrzjK=#g(*_&RtAi{HqVlepnHN7iI)VLUAIqW0D_`T^#jmui*3;+D}GZB}- z9Rl6gayF#t)38i<2kxq%kRhcM){r29*fOApR0K(2KMXxoL{JsUY>wvDDuI?$jcKLK zCS9)Z41FXn$XwNkLy_5mUMit5hq9gb*FmOMsqLH57^dw&wA~1TcAu*-Fe4?p<5fZt z){3iJf_4|G`&`LQY0zSQ+10ji;5V%Qs4SFse&U5-g;`_?51Ok-k9H|GylK^znAS|^ELODH(pn;dnfc8|+oZ@6P~=&XgM9DbyWAA$ljs{g zDg;Ap?1a+kI6lt+Z%Y@wN|V2fm_0l^>2Tp8w-DZ7?p&p~Aeco1XI=L}5g2R2-z!bo<02(HU-5J_14QaR zw#a$*phzrdf>LW^XmrC~R!eQzj&efbWB=)Fc4_NQ5vAFGNTDAsX zdKd=7k2+q(;o`kmIdK*sY^-R$j%1I7NS_h0x&g^VJer}})F8t9mwikhT_V?b_viyW zR&4bS<-gKkDpZziLq^a)1jC$B0sVPez!_u>Ok}pJhj~4GwMBpVTQA2ELJ8*u+Z$7; z{oeYx?2UFTcq_@rgk!FqwPn`r4*VT-kM9h=c(H4@rmEk*kZ19;qP}<{_E|TJ(^;>f z`lQn0w!lZ-Og8J&c?GZ4%4_N7f~NAJ_)Ga@I+x&ytMl)9_nEHpfAcLLDVi@3|-~^E{uqges zHK;8P#;EDR9SGo~CCL@{A>!KASF*62G{W(h86n`DsZ)ky%B^2gW%LgaK_p=imoMgt zbyo*G?%OEqVGzvo<&7_~1=m611hFA+I9(HC#zO$Qfpjt@iUX9v`m4HX)As)2#*BMu zP#N!Zv%A#vFad4#Wiey{C71*Q1R*dA=gd5epz9fQ9bXZu5IklSg||5?P2S> z<%%yf>k%y0K{}&aMwV{9W?sXxJp}MKh6PU{NCHkXBbAe;g-fJ}6K8fTFMg9i&A;B} z?rmS%;0pQs3Gl|l^g|p?KW-bkqqn7OXO{Whm*t9>K$%AEZ?;?i*hKxc-C}2BY~kcJ`?C=mGD^#jP0O?iZsIQpkKHG6orXB~`^Q&e{Copgt|u>6Z? zMYgFl;_d@I5q5d_zl4kztVkuu*OcOZ6O_KK>(GPH#?(xgX*o|`sShwBlD}@WZ2O}( zkWKs3Q^eyNdxteii!Jd~ZTF8};q5_`Kq_8=)hgs>!Y*i}ZwE&oJdR zW4$>~cCb{fCpFhy9w<2mEfV#|zlZ`bWptJcSD2)Q)4$+5kCZ_R`un#tdOi-E~BRZoA6@owxAtXO%_{9fK<6)`-c z_ccg~slG4GFWs?M3(Rk^F~q;`^>+AC|Xb%}qv zPhjTyt@L)<@SwR=j+<8VJ8;C>#$+41nG}&1-p6Bd!gqSuean4Ud6 zfsV1fwW@qKLxi$!bml_HIBXBv5M4ikyrti8n@Eri<%iwIAD3mOI|J^jGr`{@L(D46 z*Uu-Awm7WLl4@+a><-7RMZ=^k%c014GG2kik-&?dcFNxVp;{AY0&h@6Ws0Cf8T@Ow zy~B0IXFF+&??uGdaZ!glFs!GjKW&C1iHmN$ympC(Tfslz{66<;L3H_bF*N=)o}A&{ zz|Cvb>i*4E{@4EeXDhR_{U;oO9r$l5C+xugQRU=+TUul#Fhc`Hc1Sl)6o3*h>xSYe zP5Jq0?0lNnl9XY~tbZrtShVa}dI+g!R@@?$=)V&3O2 zuR%K&Jcoa7JXrDXi9Zp@MYxx({D9c^Imw3p!R)&ffm9=P@) zSsCp#+BG*DYg3CzR-A{nhkj;AXfnO5$;JU8_2OO+f89-=m!6BYzjl7C@kdd~7tey& zA-Pv8(zdG*nxHX~vkkgS-(AB|s*xS4VnJG?wnGd8U@(d^PM%0W?qqA}n?39FEScqRmnwg>dU~JTLm3+urQ4-p9=M^k z4Sq3A7PRw(&L2ris&)9IcgZKBoVvC!Mpm<;@;{6dXp9Yt?b2+Ki}x6i)tn8Nt)19s z<4LS)LYno2rz(~SkX}ihT+-w3C7bWM3P^GKYJv)ub2hhPMNLXc5oWfxF-SRMI$71r zlTE!1TQ`Ve+s4_GaTA8$P|7(rKA)cNR0f+Ue!fl-&zeDMrk87Ebh-pq@MI$)YJULz zP>v36-rrRyCKJO&&f+q|QMHv99P+^2Rw!cRw0*a^G4d*K9d1nOxj#5kZW6=yEBx_m zqqz<#>RNB>H*PeFE`<(HQ3QW-C<6xl*NKqVjsUQAqXQC$4%&Uv(n9xEfUUUFG9Tk* zKAA6ToJO*-{q71i`(b%3yEg3^Si8{3x#;Lqq+dz6VB^LYso@{u`z@%K*8y` z#J8ByL2OIa=0F>5yH5XMAgJ`cka!JT!gavQwGlrh+dvDfRcl(Pm8KrQz+`2?J^#v)!|&sGKZ3 z%D1K>e-O(_;3*~8GwFnC(K1vEM(^@s5Kuxio8LILOlr-u;a^14p_fttur=&~09i(< zJGw{uAEW%5y85&6qPuaaan(XDToLw+-6wr?zWG<>TxxO*6N-3fAW$*6;l~h+^zemb z6?nhTE~3J*1o~i&KteB-lEdfV02;AJX-g=K{>h=1{aiy#T292XdGY0I&wKcNBJs|P zCrxy5FPZ{Bx|pxGLm^3LnOJ4+WRb{lBl}}trsIiMrbFV-kev}W^U}zwNzw8TL_Ccz z-IxZ!c}7)WL=>5_fV54bP#6#C!?ER>rMRs?=b3ibqUYOhv)QapktO zy3axz>dzJ#wA*!R7x>C*ei9~=Tt?DG^nrl?l0@py{UvgG2R=1>MM1P{CU9DiJH$DUk5G0E&4yuNp?7tCY?wt&V% zLYK{R2}yms0Fp!V8LRf-Kso5~1>*iHsEvhva)Tq8>Nx?OFri(`6?C|0d9;G{BQvk8-D}}Qb@2Ml zh#&$=kMBXuMXuo(7`PjH{cTC%(hCeTMwqK6t^6gBoJ4Ct#dXxlabl~wVTF*JB>sS! zJ{^*%rT(4Mq)C2=Zpm^o;Jy*U%MBzE&70voHTE4vc{so*%G3Q$#E z?>@J`IS+y&!E6VNgMJ3tfA;~ye7QBW?W4rgOJw=+EYP}>iCDb@WB&Q>PB;VN{P*QF z!d?FJl0W#_9k5#6jL`6(3-{F84makBnb!}s6$_kI7L`S*Rv zq5ap{;s5_u%`Z=NEltb;?&N-sG2(51X4qkJ;voM(8D=V~$-#o6tIuy=!m%@2R)@O{&@u3DaO zd}r2L&+T<4AYg+6K|DS`g0zSz7oh_^`xIob;UEQJAc)iUUV_=C8V#zR<(-N6+x?;x z5U_iN@)d|7dV70!cXwxJXK!zBM@L6bPfu}ECqntvQn8Nse?TPJAKR+&7h0l(jsyn& z#vBGk3GX&*=Ej#hdUIxYGtj7R|jsW%6wnjK~x?7A~ug^7e-aAca;|47O0>R-A zMhp>{+u^{0y0I1ekBJ|1x>O-jjZ&$Ii@p0?OY8N`yG*m@4oP8NBPjN7P{ZZ(ULgf4 zlx~zL%7oG&7m7sQ@q@b%qnqOr6`IsBj0&gHI9X92yvM>7j8W_%?-V$ikW~#(1n6K; zT@QC3Ukg&yZ?OKuhXOk#DpmM7St{1W#SdcnD>jW<7mqmV<(^v91&{4#w0HHIJP=01 z#xcAq4T8AYKPzo}m*K_#?v1E$Ij51q`h$ddeMvCpxN>diRr~q+Ix=A+g!b)xTUcoSasFb3s5i-t^PNiy5j6r47&`DCeZ%P>=#xRT2A7R+l#s&qeoo^QAoR8ABDq z1_OiumNKx$r=!Ju*n7R+6$JNa0+8T_U|9n?qiuZtnbk?yJAlh~WC#1qu z93qcV2O@xZSPR7!Me*NXJS|mE$-DPWI#Sqdc-Nu`Vg-mSo_`4w1fWZyOT<3pdH!~X zL2_MTw20QELhlVg**^)6rPhx&Z<>;i{gO_Ca>1j9I2fDlhnR5N>2*?upLHpH0#@JYnMbFrD{coN5{>pzh62!N9PqAcE(-5S8V33hs0Mr9L8E~THew4VqoIg!o027(Phox zleN&k2@@Ze&|zEngXrBVtQs@}4R{pL1wc{39ggFL+Ct8%a~8`M5)+MWz9mZ+es!@G zYvaa>9)t9jG8)imFEA9yiH|5yTowwMIGamw)K_bDAeB!)i&wy{m})p zBOi{|4!c~nmGyp7agzXP!c69FHRO`yi5Q+Wgs8SU0@WUSM$O!ONVnlGUWIDL# zKARVRVt+%%;0sT^uBEn)#>SQiG=wjbn44iG_pissqsoTDHmX@|Z=7=N@XdfmAFxZ4h88Px8NMBG0&FM?>eUkWPiczPvr*xIT z-Rmo_=I;*YX97Qe3(_fKh~!Ghu*9ADJ%=UB0iRUB$nET@9AV-S#N1=&aN`N{0=AcT ztUNY@_{uOw$#9~;pzR9rE?tW^LTS?dK~?=j5_;jm)WEJ^%sv0cgcv(toqxNdqz~WU zVc{-UWMlN#L3-J6%XibEi4!MBM{%v-KDWUoMWhkdpu#rBtnO-5~hi^)1Sp;YzPegBwq0 z%Q}9zG8ETv!pGN(IBrw(?*32GRMGAX@3HY*{iVQ}hMp3~IM)no=N&Kohq?^~JniI# zLLCTsNoFaBDV*3;1R6W z2R>W?M59fc4NzkA@G`6uLjI2qvjf^jncfpAZ->`=$P3j`s4xZn8BK9wCHey-BX8fU zP-)P3sM{zjqI##~&yA^wp~eu^W=1uRi=PUdf&22CeqB5p`pDjuTGXklLr7`n1iU7O z*~%RrsNUKadyq^ilLi?I z_zxhKFgg>7=E!iqI(1g@^YCT0Zgx1+i^4mkcOE9x_D}QSZRp%_O*0)q!!kbyp|kT$ znMqzJ;$&C3>@53z(u*$Xa?wyWtNxqpdiaXLRds8l&wAI6hGrU?_{17zAlJ44rd+ey z`MUO4PF6Z|&(Ei`qczYW!lqv$z2@;Q6Iaw zqFD-eW!S#@kfiW;5c$dC4T?gIzce*jZRhBa+l+T0=EH5_Tw~(~we{((l`-UTjYVeF z)?*m)+&su3*q(s$N2G<6D*R2`H6E0|b4}R8-QBaLKpp^SObn&SlWR7K0;zWC*tUdU<% zOf_lV3|z_X{pOo5d7Fi62WN&Q=n+thC$lola>5bUnG7 z-wXEyI5Bxr1yr=LbHY|0>fm83&dq(tR$!TOQs5AnwNILjC&1#ZtT!9;ey3GtmBDXN znzkVWTght)PMkI!KR2vEBeUAG#LKrsPcY+bySiKMpM81B93M9yWKH_YqOvM``+%w4 z-VnrIlNiojiF4nbS|5_Vt>4YQ;oaG5*u7nc`C(;1UeQ%xd`IrdZO=j~j^eTSQuHur zDvcDH&!QdT8oCod>>2n1BAOcq$hJRa){ZhM!oWis&;FIMrnQ+eS_F@EK>`CfN5}}_ zIaf_XMTuQ@fBm-ZKO@}FD?vxf+6g~)wkG)RLW~h^30-rO1+hmV83v4kxVG;@QkBQO z(sgo0oF$9>K%FD9gBOFkpa7hIp5FXhE!CsewdW-08ilXH{9hCd705Nd8RQyeD^GM2{SKQye_nBsfCmMR z2S_#pB}(vrI_iMclNm(*y?g>A;rOxRJ&A!(pUqrs=^Vj?`;h=6*ZfjR!vm5_5W8U{ zA<$0+i-U~L7EVlVBc9+!t~)S}u4x`K*yN7I+7FdI2?kwR34Dpvj5Wi{ke*giRbSAB zK)$8Iof&?gIC$3VNRSqN*JfC&YZOZlfg$9{1s_?Nu@uIxG95+eb4#mYPNxo(hzHS` zatWYS=CRqX>5oc9GvmEQ`5WJ3j2fQ7-`g;8;92ae(|@u!8S3l`O9*1a?kn8;Ib7@? zOei~|Y`Bav7mCde0Y_sy6rC=Z4Al9CzYhBSkRUS&{rXty)T+erlIrm?fc|e1 zF;GgZ6t>&O_>7+6LM9c?to`9yl}f|pqyfKvx{Bycl+RWA71;Z{W{$30L>l*D$z30k z{4*OEL~@g|Iui?*o@lLrPGGnHcLYc54dZowm7W@-!Nh6oGn*xOsTLO=gr6{gsANQH zoO-uwkZZlj8j``UuMA_z9j^AZJPMGzswm8TGJs?Pk{!T(V?rqFoFu*yqp>q=J2JwKcLwNZMEmA2+NA+zt;L%diN$O!Alv=S+pn3I=^1w{~1OVnt{3{npWU;h=9> z7)uU7QHE_P%vzfW?o**eDupSQE&x0DL#+$L)dGLC0-BK3D<{g`KXID*NGif$HS|Y+ zURbX|pdmLuMJTXHDziv0DTvMup22nG_6QzZ`4l)|*$WPKGOeRD|FwW`0|F_yie!L0 zb>mX^VUr00iIj}2k^Pj|77D8C4R!Ks*gfg%Es) ztfynRCUY)r>!DuZOzHJ|Bm-2fi54gGUZsKC-LPj+icpIE zN)=2z#FrQm2<#${eemfMc*djB?`H#sy7!*V27JBi)v*1mr~s}+8NG#=B10GKla`DS zDVS*h=(y~;dt+l`+Eh{EwD@#$y=jJYL72v)*q!Y!@(EufkZJo6aM7MLob@c%A{bIp z6+N&#vVL@AJdUhRBU@3rK<2Yt0}*000Xkh4DBKy?OK$Oro}YidyXwXTrZ)vu5JaRa zp3o!^1PHbKrtFkeeser1fst>oYwA6wHS1tP=8LE?F$06?_8;NNmfs!lB4Q9VV?Svi z5dikNxr`$ynT^W;4lRJ(ULl$ zxhcI?xLd@i2$3xlF}bO)hJb*j&jrII@?4zEn*_p_g*#C57&t)twMH7s9A+{^P?(oF zbQP`b;mN~9j+CW=1AjU9>Tni&qnfB-Ki zogu&3!f0~0ad(3tA*dU+Mv{w{$N)ql(|`?E&$inrJm_$NR*NVWd^o^Fjmdf2`*aEy+w#X@GeiZW2vKr1Cir68CN7>7 zEu9n%xQUJ=Of?*}H;nPQMTYvlU^mo5g~pPbgG;PydoOe`gdwrH@TcUj-xESK*rva9 zUg&gzY2<@cW=}=Tt|wd1{wg&k;0)C8d&qAa9zTw@JiPtbI?tD`Iy%bVJw^XjX-w?? z4C?LzMSwDk{O^_7|0uWqQ<-IBVfrsn$5$WszpEWHvHg#zIRE7`@xMUD$@mXznt*eX zwO|y4SLR?@0Znv_m40kcG8E0jcYPBs84^+!tRD+83tNb)x^KzK`X8O6H_yPWS^rP? zYphzmG7zVB^qgMLT9`m`>fktXK?ty%yZ{3T$r*$(r(uIH=?jTnjts15BMv>3Z<1oc ziFwz+h=43f@lsLKKgc}QTa%lIN z$L4M#VjR82Xp>306xwhqtO=djX_IUc@YmOqzu=}u!xEWaYLE+^LPBi|B{`XvWaMC$ zudlEPGwpel6ISJO7Z1=9$A4RYsV&Hy!pRdQKuU0x;I2sBHSssuyyAd1+5UufpO9Kq z2)chgyI+)n8Mu9z+;(Jk&Qgcqn6$a&IG(?&jdRdo_479pp;!FV?(N}rI93?tf8cb< z!@sVJiJCF2@Jb7kP^-kDX|<_6*V3j{38>L(xhr+uqWji|>YXJcpRCnUoO)nYzd~wI zuSu_;?NzBH#V@O7_t$nvG|a379@dP^Hk#$ypp7^bZCr*DmqN}uNxEIJsuLZX z6=i}2nU1HIhy@eL?ex|WDoa_!gIO9w*|E&*Dg(SWt8?1!ab4M=LyeMz*eF0qIIv17Ly zu#rjpBm6mjlw2AZNjSDIoorR9CN5B^R+)60o>m2cY<&nm0uzarR1+^@TGz5J53%pG zB12;si~&lurY{?ZAd$~0sK)j_E-;v0Ra)2W+41Mc)J&9E9P1c-LIo8+N-k9$`8Azv zr#oy%AXOaZvT7VBA<24G@LLPfMe+|p{){{e6aO&pfr~^rP7V-RcQ9(=ZpkYCYIJ-u z^DREUXVLU?as<97zAtjkP2PUezX=Tg+U@@Y1`d}0j0^0{|0XW5Gyjj`!v8iz#L_)a z1Lao(USwU6O=LK6AiPz|<>%+np;|!1h>3rJ`QbS9=80Ui)_U3N=|-8C-`h-OOu)Y% zp9J8@3oqHm`i%@-pWspYKQNM_htnq3uv53LRLeVbA8fu~Jy<@#)C206znTW^P(dkf z&Cq1+de!{cF=F{7E8m4siFkeVvE?c9IMSm-6fKv|X$=#)fLMdOE;Mq3`GRERIQL=s zwH%2iqN*6084)#SLD||Uu3gg3hRn(6vdYOT!6cb8#RYbyv;JY$^AER$E7TE z{Cgncd!-fW&O^2IvKi4Y9a_SX4y@VKtp^@arYI27TaAdOVsSt5z@&PPEtr*Mhmd=L z*S5CbDfFy;emu<(#n47spc&gP2AKCaEZdIf)Sx?l$qQYB5Q(lh zV3t#D7PTSJhV1BM!XkE(A~a=7ysRT9o@-w`Y}tnoNW< zo^ND^W!TO`4?0uY5Q<(@RjG4!7pKZn0bE-4+Pl@eF8Vy3?K~K5s(2zM&3QNt<1KCL zCdFe9?ORV!#R4pORxM)=_1sxsq>QKr96$q-1e1y8px=ax`dZ(!7azGqfTQiK;;uij z;-I1)gnv7ap8Q0($rtfTa-fUa$pYsp3LYhu9)(DPSHphY{|_fo=HGbLAQ$~^Tw$KW zC|M*Cxw}DZ>R}}kdd79a$UDciG)|XDz&AJyAZ1>`8mJLZ&h7VCjmUMBOj7Gd=1KX1 zTmn+zJdFro!y8*dBL}H^8}Luqzj>KGGrZtIxJwI z5!uW<6w7qzF&xEN5iGk+2aPzs6?ouyAz7tE4POUb=y<4NGfLmXb)j6}CfC;h`R!B? z`#^GAoWvJc(xNZ8?`7H|m}J5+Brm@-S5*P(YV~jkA9H_P9-bdju@>c87u3t!#lv4W ztk_bfev4PTCE`*OrWvAP5^q1Mu&a+LGVj7sTF%oZNo5|7igUVr^I&XJVoD`QX?SE=%D>_NDZfaDl_EoS5=0TB zA|AfY3TYH{wlhwcu*;+V45{+@(lfBpjrRyzbZpn_L}L^Z@mghdo9=B$JV< z4K#eZ>$K;tceM)3)bSo-z}%9oi3M1n(Ck|S3N=%JyVg*fD+XTVA{DF=!1_E5HpIAo zniwNCpM-kO&?$?9HHz732cXlzO4voN4#CXui6OLQmb8VK-t+RSC0g-1cP}n@(@#JI zMLm^PSWhpRKnPT%NopZpblzXnYALk|r?+p1oOBu-DHKsccPf)ZirpvEvhX99Ml%=S zRSduZ3yV3l>j7BDr7nj+c$YcDT^kODm~c}IX5EAa3y@)4FtDBOj_ASi_8b!G+Be|l zR|=U+tRgl|7GkTC>>`QXIoJE@;`uitzd$IgjdGn>u;~fOO6H>apgM2D>*ScoDLV>| z6-!v$G|;=)EmgOhq0-VOmz!D7RI>XxS{N;q^Uap&~8Yd7?OX?((D#2_AYMfZ{2XC}} zXK(NiQ}B=cewOsQZRygT@yygKZPHQDY;|6m)~CCu0;NSR1CPIiC!qsU{Y z$qYXJR{lqiFs_hs(uWl*@{8#I=)jZ7h$)Rghk3W+vCMFkID-P+84xQE;**|*BF{hH zYHZ%JX|oBeS*b{!{G;tHF%+_960INCsAPP7f7`log^ay?)m+UeA0#H32+8m4I`|~2 z$*$eEa%=0ylMQs>x!g*rHyoQcySGEuA?!DWgpG1Ge*&klLT?7}UCw5$FR|t^A5%7`PCXBdjQtsQ-AS@Cr2E6>3 z^=+Hh2%wtQCam~QmZESi64vk81YRjpm}v;Sx%8{ltPv{I#-8UdRiahSonN6?Q|7Z4 zj#m;(_jruE9gEP~mTH{J)-+mOblTC!!Z0R0Y}~$-XNCv6Em+UpGh#!Ff;}IL4nzZt z6jUa#)e1Ll8dtF`8Z#auO-<&hN+5L;Jl8YG7zb78&C#WcEDgI^rA5h#OPS)kI%SY0 z#F+3I#W2_kPjF<8wWL(@{!yaHCX1#BF4WLTF@*%*UiOfIgLm)Yv75s}|M6@ffg&OU zBSZyr+E7(1ZHdA9_aiBeb21hX^Qt818w=GCaM%PN6cC$8t-f5z)O-n(?O(@jw~lU? z!M#58rzJ|n_X8cg3pCL7;P}6XlK+Sg|2n8}{MSL{`@h4ofBzq0*}v5J{$FU>|6Tzj zIWCwE0yP|)v^>}rA_$%|nz#+@3+waRHSCg4AE@=^t($&&by%JEFLT|8qNy3cfgiKO zIX1th5B$DUaI?LiER?T%3pTW4i$HLY4l!EaA5ElQG_zO5#S1fmstyex`q)h%l~fFI zWMG&vvQdD7-6Gj&q`oQ}w1R3EX%yk)`^w^ClK8Eq*Dy>b63Ta>*2BcV#sowxbd1kI zV&vH}nra!qlw_$vve3&^-fNVZ1+b%`2q_?bvlEu+8UtXkDJsN=%kGp9kiFwg<5BLR z$+DZ?tNLa91Ss~>?_@ATGejH}@(UxzI8(e2SN&7Dn0XG0yD|BMY z+J+x+R&O->>j}gMm~nVqHd-w`_m}GL^D$sP=?_Hsl4(-0w+7v~aFLC>a1lNdUPT^- z(p)fLN(@9=wp!&D`lY~eCzUqg#fj%?T{yntUMkgiY0u#tDrs%;j5(XA#M@WDnxOe*xJi2gg1}D9FQ}Q zu?blHT@?rWR#0^vGY#b$BJ(AS8uCRBFQGL7za!=p&U>^P|*1mL`ZGFZ4=zhuF zoXtjevpHwzA7PcW1t&fnmom52`NyqePDQrKDEHX+8I$k&C}w<_(b*ZvV=5YJ_L}~e zLzcTs6T)r$J~;9)EWS8=uBXjdlEUxn5}+3Zf?xDS23q6^yXsGoG~epAGWBzta|o4R zZoD|l)VEOMCY>r(eDip*!ItwxW$xg(SLPTRW$Hu$syWF7?K#r*F-*z=M^E`_u^BmT)Br46lqgwIZh0h3 z8@B{T_<@lCou(qV;Cnyly@9~P2-s(f4b16}H4Q?+gpNou4^!BA4dk`PZ3MxVlmky> z0b+zViYe!FLn@C(0|s_~SCA)NsK+1fsi*llutA)|?CA!q*Y)}BXSsV{%r>kJYTwlV z9zxjv6&U^%LfHQ^8DVGtr>ybMO&%U%Mj2B(a~BI@_J7&$DiJe^S=zXmI(=Pj3|&k` zOpWbLOo{pU;GA8YObu<}JU|<>)~bwK9KW<*(9cLCjKM24kNRvWpc06&aOA-sLjc{I z7WqTRlO{-#di-1ZCKxRRjo)k^JlKI`@1#-1MzwPL$P?@n$g*n9JAf;R}b1JE=pQw>_UFN zduASXo-7@#+s&0ZF~#V}-TVA;UEl%NwNhp4P+4e!AEvna+Z6y$xSRC(biFqg_WAMb z_wn`KH{8qC>&K>JsEXS9DUP_sX8zt@ z^Gpl#G%4xx)NE@!VNa)plz5sPU4k1uE^-E`@rBFz6|LsFxGVS{XzN8Pa>>~Li6UK*=KRx_q9tf@gdhwtwmkLzmFSvx%~o;$Rk7bM@q26N2bbKU*C z`x#FMlKWiRcXf0bm_!tbE%&~0J5x-!@A7xcIGFT*A-$KT#-e?60lzQSS&mSmK^Gv) zce`lm$e{;1{ zY~#^4)E|Yvy^llq&cEfTW9FY6eY7L=!R5#}%t6gz$ecC&Do#1M!s3(ZD`*tPrr%IF zwfcDkP=suT>cGuROON<|X|$KVXR|RA#JQ-$zFJvxe1|A=Z`AI}nG;0anEAv!CB1M| zlF5|Wb0qpUpH3&w?VU9lZvMyc6cg=HmR|~S{yZP!Uk}8}Q!%YSw@|xoZ&@bI*lWgP{?8?=u(L=dj<|X2ecG}NxBrD+w zq2OhBvu8zb#ogiIohhGwRr{anqO?5eYQss0xH_xPXrp!g0^(6YE(6&o!rWO#N63~( zjLut4$2j`$mwm`!@#9w6oug55=EfuauE^&5eB*uD`X#gO?v6q9o zu1cBReNIw*l9iD_8m62H$GXeJwPz>7SB|U+=^T-MKk~=bpl|k!?43JnT)Z-Bvcb;2 zwl;1SRKdog3q7U6m<;!I0@4w)wq%&zjxfuJ%V}tq2oYE8Y=n0MNyIuzjd4b0pQaT0 zUuBXyTn4|Yf`?h$R3upf3`YY}5gpUzjbDow>$SNlxl8NatKn8_;y78Wp!G%RM-hmF zFn8`0W!lH)K3f_Ag_=dBYX#y=_I<1@j2G>QHG(f0W`&C+gT8o_HVXIQ-k7_Wdbdd$5=Mu zRl0_8ugg5ueCKo`wmupy#Rqby;88QZ8$K|X*+M@!8c>EXXQCt}MIReY5VC0J5=2=$ z_A;Bxkj>|8o~jWBqzMB+a}ML*S1AcsDxK5s!#qsH87s?&c?Zba29UK(pX~Pm!|(Ks zp|jQP3w3{lY^0qiTP8b2NqR2kV#qc_2u4{aG$@|bGTfcv?@mOBpwWX5c=FjC=n76t z!0Yh8b;c@MFs5ZDa46Op6nArU9J#7TD*F!lS8IzwKw)mU$*e7h?P6Dw9{DT}Sv2TK zWlJHSyC?W;Ek23*tkr!OSg+qwUS4+kS zjQ(JrjKysFlU}%XY`_U0{PNB+&vLaA=23ac8jHwAZZ5-B_=@-7Gz6XgHn-WS&)kXe z&+&{X5gUC%3Cl_&1%S|TeW635jA-80j`n(d93>*%?P|^Kts5tOFUacifwb76wEYHc zAAP!NZN?9P+XM=wr*t(=F`c?$O<3B#OO&MBnEvp-wwXVY8Qtlwm*?H z%WJ<9wb!c`yg^&7^MZNVBu)lf#!id*Z}5QXHR69h4MmX=yQ-3uxoL&n0SL^57dE&#x|Sw92mns_&p37br~tBy+EJ# z{VwuBA(gv-*@}b8{XTM;;bIZHj8PAZ8?wkV(NXb5M=pSQQ>nREscrtBNQ_~|^7JNI zGxtG~EeFPP7kO&{rk4!?AnN_II^wx12tVST6l4bf2Du1|oet6$<-aT06D4{;{i zM`gIO`I{W;{Ul=%Oxl__Wu=pwc^3Q4U8F<;W{FKQFV5ihY9~aRx&klMaK8DaZFKxr zI>ZUvyfL7dY`>w!R`P9@D($S3Xe-HKe0+01PfTI?@HGG1qq?7mXfK-G=}={AaOx_f zpw1B)`8f@|fe8a}<+gwLXYz@OW{w}bWJmxTsfxqs_Kwz}<8N4#=>{9#*+C|g93Gvg z@^LKKst}Mph`h+upk1zCHy_jrDyNt>Iu4r(xeV^%Oo{iV;#1>p<=U(C8Yg#%2wtY` zsx4{YzN&5a)k(DPZM`;7IjIjei{zW%>I^UU!3fph@AKdDc~$IWqSMrOMW`|SWk42j zE`>^&i{sDUA)<4f@2AV<SGhpyx+Er=Mjk`f1J+rYb{M2kFTy$FAKG+&rTX@{@I5> zNwL{PT?Zp^-v1M^jXj2Xz!43DJ|jh3R8Wq*>7=xV zhWh@fG~L=;QmXen+;I$vPp@uz^H-#q_D|_{+Yt!2(PTmcw>$6b8K>*#R(bt4jl#UG zu~QeSv_eDB6A&|0Xk5a9r!O8XxXCv2!!8`=6XsRt^M~kCO(G>2NkLfrZxLgY<2VBY z66%R%i0TRB-4shgI?a8SjL&uk-N+)2RpZEA`~5#U+DfZ$XR|v6RuQP0d}6TA1t2(f z;yO5(HFj+GA@Rr%0giW6q*b}v(OJ}~_ITU_Vt&}Sp2h|?Mp1~Pk#liFh>%}@<1v@J zMhPqpx}jBl==JsWSG9WR0GjKj7&1ZX=)9H-PV2qbKxM+8gjhdAf0U(g4;0!^W(dU! z52<+zjm@_@BcXMfP7046adejpW2Rp=iY}tw9_>`YLeCb7^n(7(LMebmEC5B>z@ZG4 zu|Sx8NpRy{T+dO#%8+UwcTj9B3$2CrmkzgdU%hkrh412l6=PS!Av#^| z-dwPAklu(h3eF*-N^baNOBlqukH=QQM}G;V|UsHsK%#2;QTIj~?UG_I?`OWX{oU`ab!Ye)*IuWP>HoLpr| zk;CzTdo&gAgG(7F9W){vH=tOmOu8Cn&jGC4pH^5CS< zPQ~nTJQ|ePge$S1O0)=A=iakE#xvb%lkzaR-C1YY4>&v8OxDnUiPg{rZwAPTLj1u_ zECK>FW+eu?Aa5RzeUnCQ+-Z`s*rdH<6d1h@G)_DfB5RW#qXR}F)(9*!Jhk(kMlr0I z2K&>%@#M%DY<^+M=Vj=X!=1xQy0s`1U?F=m!Uo6q{fw26`FtO=~a_29p_P@A0)V>pnGm z>`olHyIG8*=6K^$(V*#yOC&_8$A!NsNuN`2A$b^&w+h!}*#4F|AkU2wl0chDA)CKN z;#7G#cVU1&B>f8-L*MU1UKM3zzfCzRLna%fdZ2<~HO^+jDFzjBA5X}RYKRNlR?%h} z4j`Z5k{BEN%~XgaTU#ny$=ps(Cp#X`Raq*laj1x@%1q$Pe7Sb4Yc~lvEu=4KPths6 z^q4M#+Ou7)*Z@=_5Xp+QcsrDwYf+B@g7{G@i+{{M($84I?gZ;c3#MaRevSgz!>7^H z4S8n-W;M{i1I}`{0LlS^6#deIE*oG2$nWI_txG+n#a?pMC>rw_`FaM|m}VGuAHN|! zcVK#HaV|_nR!#0{q&$a$;=l_V#Rsg?gIP^}ncJ`n*@pkXDw9zQF}(@HmkG1Im8bGU zArdlDcA_bbBN;?FSMAB*ALDiLv|`DK>t_#9j!)8r7eLKmCK>E3hCEK1G%dS?E`*DE zyc|_5ODTe8E{N0DX|UFslvjn|b$aHrXw=S2aE@FS3;S z-Wc3D_-up1ouawi0M7R&|7^$CUTx1HeCnap*+HKHLdTo?f-HBB5cWrH7;s@i&BE z#yMSkTYeTMPde=hih!jo#wd=sbx%uCCQIs88RczPaiY_W*mULxql?iOW_7?7jt7!g z92{m*CNG`;aH_cHh8d8^YnjUjYg8zILO1Kh@Xw2co{ljrD(`he#enBHDdCPd4NVDZ z=ETTn(X=E{hJDiP6D>NO-qKbJO0cFGld^?M@L1r&(qIeztqR;qK)$9y!aAsrQg?(S zw;#Mb?&>RNkM-3_=E_cot2|_-y4D5mEda0t!tzQ?tP^v0JJU_}Rhw(U43UOWd(%@* z84Km=Z*{b*Y=E@G=8ACS&6E?=z?(E4*^q=Al9<+6Ju#L4XT!GQZtW>GDxfu6%}bUc z6%aQ$tDlt&|BN=9V1`vy+9>pPN)IV#(d@<`UUp$ZWJ@;U8|xv$En{7mMr51(!Bqb1 zm4vrGRIAgvN#_5s_Z4teZri?ew{$K-Iv2G-q(QnRq&uVpqy(fJ>5}f0Qb0<&MM}CG zL{dr+cnjR>K3?y8hrRc?_uTuo{C>i>))(^|<3Gk6bJQeP+;?9zl(s*VGewJ)B7xq+ zB^#7SH1Dm+X3B^rBb7Kc?;56(2;pl`kQbPV%B!$e^dNsWN7(;D$sIY@@D_KCgPn6s zf%?1Gaf#L%JTk^YMvV-;3Ne}3sy?eMm~7BbTPEVBByj~AH>(Ca8oY!(i4PJT28N{I zqRLC3QF(f}?D$9ka#HTyHp_^+H(x>*mC1_oD3Mw+?xP!gbdx6QlTbv2y;i?3sJ_(| zOq7mY3NNDJ^22o8lp=cOj-zfNMlPG|8pS2qx!;op7iA_hY$)h;b&Z~pw9)UPMkzbq z)k5rL*9b|4dp+NCC+gEGoxBc!4x(0N$iQ`J|MpC};67qjO$0-nO^%~&f-o~BzxjR? zX4JEE(#gAk$R2zl^Pvddnjr`2PFkF{=Z4#v5yUO8Un1NBWjveW0ln!odlqTp>pEM| zl)2=mL=ensk=L-HG6o}}e9Z_l z?*6CDkI$6*Ot{{KITo1KYZ2co88=~m`{FbAn$l^^YZdKJ9%mCJB|NH?4r3;Sc-w_V z(ZnVoG3@B*ZYqBp9^0K$nTKP_kE08<^KjG7_Z6gWZ>Q;tm+wz2?prEvy@FexKDrb6 zAsjV?T$iAVafd@swOb=SJjogXM%-~y+zvm!5g(r!lG%ig@EJ^U0r5&YtwvoFx>tc# zvz{eS{YKMx@-8L$OPT;~j5IV5iV~@STHKW%zzFnZD#{g`bDz=0Af!)@7$PGaFuPzvU zYK!4vBD{?lgmjj-FAFAn?Gbwc)&q?5(aWVRUE-1|>ro`46;Le?pt|*ec!K{z25}o()MJ|{CT>U2GjvRq+_K7C(?PRP!+)VF zavb%9;{o&SyS?HK%=t7E2s6FzR60_EXXKqrpL@Ry`80(zFpqC{1J0oey zIge6j;)}ASH6i8DE!$%cuvT|3o=BU8*FVgD{9ZV|XQS;l^Ns*`MaA`%1zY`A)DQA#mc^wgh5Nl!p+fpjJH48o04HK9RwGE0X1Mq&v?r0kFo zLrjhbdQefYfFS3fj3TGOrNU%81j|?V)Xi00wdvJro%{x4*O=euI>5izP!brA$6BF% zL>DPeC~8;p0U{!pfkzH5>bAcvL^g+v%-|`+{F~Yo@(TlHzW1WmZ|=Wha4mu0+x1Ow z>1FH&_P5dD9td6J%3&UN zMcGlaDmJEzS6m!}O1EZlL#hL>p!sIWYwpoU8Qqdo<{w1*FU8vKvasvzVbVSko&6LA z%T4}4Q>Dfc_hiLM#iIn;mdh4BI)V5tz^hc#Z21cveLP!16CVC>dzi(mr|*MniMbzk znJhvSe1P*0?s>t`;5DFakco${-(c*0-zkAOqV3(LV;@~2+mM&$!~=(5O-t95(t{d$ zyrsKsQgw>V#~KIBY=+NFRW7LZBNgdHR2J{ojcyP3j2XLlEkDb69eb=Yu%!KgeJ4() zF8b6?O@owN4OP;V5$_Qq8{h52;R0d82y|ke6E5lrrnoVtkO%8Hq3oNFsVCS)!TY;` zXrc<|+Nd(|LbXTwkQ=h_LUh?o_3o#kmyIoZJfH8}A9X`DFs!k+T_A{yRKP4GIo9IE za?75~qk)Se17&@d!#Xw5j*FH@r(TcD$+rn8OO-Ag!%epEYq1!)^Mu~X53rV#1#Bhm z3Bpy<;HR)r1oA&URwMp+5i@&SboyMX{5-q|Xf91J2904tw>a zsw_~VCV}s5u~?LfvBFX1xH~PqY-eae1xaD2svC?ODu*R;O;%J=Q zrdv{CF?ZT*6QkYVWCi3IF4=OK>^U-oLVz2}T)T_G{)5r?C6lz^b@Xkp(<0PTzF_vw z#Ixn$!_mk%CS6QqMY>iqlkK4e*+?~`y8VrUuAXs9WF)2anHQ|EcEabH+Pvgby+$XQ z9{hAMXV}qZc7|Z(G$Tv~6xHy}*JM)Fb5RtN&zwwn`Cxth6A2@3Z6==jh;_5nC0g0o zG>=W>mfFMl3U{4H2n)($m;l))3l)a05;)aq4Xd$21=Q=%u5wEx$GiiL5ncP4dxfMd zI~0=*wX5&4_ujaACX>3t-y@u4l3`hY6g>&^I7S*c!D_=3;@odNNUVreMoA#=85ZgYREMm=W%auW#`G|q#M zmyD%psH-~ogcG5A>Ww{V;>ssf0NKMP>ml5jmi)y{YeC|f@RNJ;xCyy96INwdKn!!& zd+1nN%o1}pU_x)b#Xn!Dzo$Dy+2|Q(*85(&0!QX}t4tcP5F?g~OweOLBB$Egn`$HZ zomAsJstQ7ar)W41OF3;=q8y$<+VyeC-voRu?OpwO!HKpq#&aS;TSyHU?0 zlsjKhdVH)AVi~dGb1L8%GhV79U#Usvvq4IIWq*gRlgV9{TkwM|#uHupQw31qxh$*V z*`4r&PM%^%Rhs=B$J0kb%rm7G*aq#7y2ym8!0B)?s*ItU#nZd`d&WQ8*LM zuwi(35M83w!t*ec*LtcdGJ&~vuvz8ggLOgRo(Q)auvx0#h}PlYy1(%%c*+Kz@APW4 z4|!Nq^N;v-4Y+*zH_^3X7gPi(60Ew;3D^;1>000SviBV8odm+~K|k;#zVjvPo}^2{ zd(vLG3rOXr=@IihKV*Y*vn9O-y=@MkwJGb zB=#v~fZz`2%0j#?g3b$BT>a$|%l#~g`AFDzME${|Gy#MKoSdN%f}2gI5`=wsVC^w# za@DCy)9;q!aSY(UT>?JDh~QvLf6-8 zzr|1$>}(8`jU51*;D?He16WjyogDxyl2+gW2>!zU`6bKfUB$y zB_!~lY=Ez$;^zm)V8H{sK0`$X2w=M!iV}DX02Xz50}ErruU|=8v2k$$xOuL&m;t{Y z_z+AA&~?W{@cph1*};cb>1V%v%LM?j{WzJ68+`2*?Y@2s0-p^0-N`)QlYbi;_*NkB zox$6Xemfc5-jo~s(YHe|IYHOuHNQQG75v<k8!ov%j)0)Go8>$hvcZ5zSa z_}>q~NiN*iDRaM#3Vbd5k5PfZqhkNvsK9T;{<}9~2aoD^CxdBwo!tNRR$QFmJO6kt zcxOovxHBtw7}ulX;s9U!yBFjEpZwzx#0h@Tk88QWtOEUbE+_b8?jNJ#0^(?eWWUP9 zPqYNxs0%0%jLUDCQ^2c+zBeJ}Z`}SjCFWnwoxgAR7ef7iD>0ikn;<;j{Yr$t3g(rx za7SM7=3)F4{ssE*e=A7- zey_hZ$zN+Z{Eeu;5%oU=QS+!Me%imDAg`vqYa5q~mF>Hcd%d*#d4^=W$$|k0UMzl_ zA;GJ=8`-$OExZ2M1jz<@y0{O;RARF7wIQ!cw_>Xb+U%nLl_u}kdx5WMLf3G+2a9+K?Lg`oRT>+AV z^LusDSKrZ3Ct8YCE19oo&-SC% zZ{xC!Sl+)wKgn%gj z?>!-S^*2F;>HU%`*R;Oo3JCapmcDkP{>&BNjkv-A?g{^GZz+zO`Srk+#D79eesJag zi)s3gD)S~D)^nC$BI26QSIlQ;{jo*SwIBT_L~w&0&i}lef<4>c0dYg$&D{the~}sYFPydiM&5tzJctJkozV14{9dE- zdd~TgH1jp%;%EG_-^Azyf|EXeSe?L|;rB1{7XFRj|9ZviOn@&<_e-E%!{-W9>^$EU z<=0%EpMb`FqxM&SVs&%fF$bLe^FMNRb4{cx%CY@!b#t8y^%FTk>^Cw^c)@%LBe z>;6Sn>VJyAuc-P7e_wOIf5IQ=W{ur{7izg_-27`o_`kL7`S%+APp{FPprLKueyI|# zfp!f^_V2qxf2}|G36k7kgZ!V5^|1Y}g(nbPH*pj5{aaDOA6pK6&tfH8fciU&^)Iey z_=_~;AE~f7frd^p{1t@10`nTepdVJ{bt0Is1#u z_osVuki`B&T)!5v{R}Ujo51TIW}F*_!@pJI{V{lbH^R3*LjE1g`ftSC z|62md@a=vXJ>$NH+7k*sm4MKVyRXkIo!yoHq**eyeK#lbHCs;_fEX#x5Kj zvcNA9a?ST^gaE&%+I=l@{~00Rg7$x2Yy624^>3{U{un^Mn->2KCF<7{x+2@}OVqDB z1pGux5ZK!K=V=M#087}nz#cf^@kSc>PdQ6}tgHSG$p2R^NjP(!C^5EtpH^SJTN{#()cKxl+yHIlf#YyPht zOMXTY@J2`i=Tm;yRyT86@O18hGQ`yjAH z{>Q9DaG#$WOd>yLb^T}&gTx|g>}YOie9unb>RDmBD7wJd zEW4>m>CEMqwY3w;c^a=q+4-5V&bf;TkyB{F<@nN2nlk?b)C=@@S*pf2PcJWgNS*UL zN?jA07y~Z?=Ga9qeSx13&$~LqvkYBB?c8G6yvg$=Br)g&-FZb0!M{&YJj20jq5)#tv z=O?J=F)P5m22IUMLEe6EkenDM9tL;9Y{G4Lr}8ia5EG6T@1$?eS(Q3HFF_r>xfvwN zM;h`%EUSotp%>E@$xBfX5{is_9h661K$1h8DKxZ^ReqRs5fbv`7)?0wxrX{P8x!RA zMKtkp_32q=?ETML%t_srIo!$xVau)*Xre_>w6AEL-E?3(^(brERI)@r;WbW|%y}Gd zpLew#Oe?t+sh4mkoe}q$yc`^#DjIuOX_2Ee%M|MvJmtrS;T5q6%@={*2E7HSpe3&G zvh);(jlq<2bYFXFr;T+t)o-NFU@P6-&Teum)gU=J*?~7@Y02>{e}tD0G)|MlixKPO zhrVl>8@0Ko?(mog3oSBi-QP?_FcKx#HpTQ}8S3K+lORD#vUaE`1ANNMqRmaBXAeV* zii&!BdqYA#eR|3636*1r!OJ&2hsQS{|L9H{baI#xMO9TT%8VJuFmtfDx%e6ZTr|nt zxmwA_3=5ffUj4$MaD%&}yOYypddJ<)nVFfbEvwQoN@`#&h9F_T(93eQA|+l}{g{6zsWHwpQx#K|8g(^N&`>%J7s}(>+lk*A&sKVFgCYuE zkr0`_o&gTn#O=9?rK+CP@sfEQiJo)Zn~9Ecl8lg{kp`Bq^En}k3KRuHLdU11G9FL$ z@soWqJ|mD8-kYc8%A@JD>Vh-t!A9*C#RTuS-7Le)%4Xg?F3_x=KF#OZP1fH5xQ!a< zc52H()P_AkOkiY}*k=UQ48xjc5LS`=3pqTi(2>WAuV(aqc2Q&nU`IJQ;a2s zqN%oQZiS|=5f=np@ZOopbO~KRY=|rdUn9ybB>SG|U4o{)UO8HPGOp1F8DjyIA^Jy3lkL6%x$kOSTz|fHyvye3!$$I4FUjHC@sjR31(l6T+nS*wedRlQy!H>~X1eUptW+O?Y^P0(eU{ zp|;~t{e2gtym0X@+HNgf?c@|vG7=7p6$6ill;m0_xhWDX6nI1iioIX-7?o!Qwso|0 z3Lame#+BbKHnAzsZ?8ZN;SLM*?ON-fMh^m1`~UALu886!7|A>#tCwOAw_@<}JW z%P%@|t1O?WrKv|eW5|-kNzVDs_?Bb;yLa#U`&pQ6&+KnIi5gM)cEKaLLca5~W;Eh2 zQ1I51d!`vI4Xnb_Nk~de6~?Axly5x^;P3S4>3ZFZ_h9O6eBoh(|Kwc|2*k%{S^4bQ zWG4iyQo5)pgab4VB>IX7FOr-f!Zl zQx9{d#CNO6Q{(zA{K^Hd>NJ_v=tmx)rW5wLD_GD8&r>=}1lXc*@#d;L*vMjQ)+-3e z3AHsR<0{PgqH1U5qF4r~X7z_-`53@&_$Bm?>6eg5GsZ~uP8}*oD&>N{J_lEZ=9`X^Hz zd-rbjjeOqN)6Y_R3ne`uuw)nN9^-o^vZ8;!lD+@PZHQ+pF)^im0}h>cb@hwK=r;5j==g1A#dPL89Upv zill%xLCZ124uidfXcXZq+l{Yvq2Q{IKQpV9iWnyYBuq{7Qy2dz4!hRH2Z|*R$Xmh( zk+#v1OGaX0_IZYP+|u!O9$iGFHDySe;~F4V)I%!W+%~UhNSI6{J-jxtI_ETw40|v71)c)+r*#ir6-K;AyRCJ!$$dqFlzG) zF`905SaX$g>?9JeEFN{+kOt?u^ZEKTDb?yrgk`<;V<3${^al{Y<|^5cR>{`}hkP_5 z&`@h1nCbic$e#NadcUmvIMa*zQx<~(MN3gm#z4Y*AoAxXl{`oMx=<+Xt2PAF5^#1#n21z?6%!ZfnfB*_z*ulUWOny{p2VOc_kdPrxQhAMT_^ zbCz>p(X@o$Zjf_%Yp#cq+)x5eFTyZ+o4`&Z%*F^QXYvBGd|E)t0<-+f(dP`O*^(7< zoV649J1-ty4hjTQ`xGGZzntYO-@LYNNpPeP!oft2?QM_?jfy z^J4H}`3O2CK0O?dfAzvZ@5gCjXUQW+`I;m%3?kQ(BN?ki$NhM)$p2cXRC(dB!^j}HU-BObIKWfLQ?1qQC@rsKJai_>V$ z>N(iwbw3DTskq&VxPG+1TvnSRmk&+8^y;&2lb_u}L2xhLv$evAo-F!wVO1dr?bNCd zIa)~Y!k=`im4k2jXB=(pz{h3+HxP?0}ELmZFLtCBltn_Cvy>1%G(G; zq{l`+%3}#dia2V25r?E|o9?~UeTxS}Dg#8me(zC>GP4a=YZ+AA0%CEl6S{gK{jG>; z=BFO@JKf#)9@E6@=xU-dm36>tDJ--58uyeUF+>LUR<}vna6%RsF&Hd#-^&{*-ogda z-CtTV9w}fhiLvA9Zm^L9Dlu}r#E^|Yl2`Z;hLbGmM?=<7^eOtNSx3ymP2ud-{5?o+ znAWJLD}GIPacDNVIkg`a_};4dpnrV&P8ileQQdhmbP>i*QdCi^peKeCpE7P1mk@XA z5!B>(30X6}zEb3piNS(7d+;rlEoBpXlJ?kInZ)3Xml8xFtSsh(C=HhHVK_o?v>wST zE{IQ)5q}UwxUXN>vG%&MQ7v*&>V7Vx4gy{ShH!^>hY|a$3I7pc^=3bVjg-5pCU%|O z!G4NVocv0+Iu@n0bL$C(Qh*H@*3qH(e5iRky41%yn%*WXnk6*nGv*}}Gq(shpw$p6NI zX|F*ybmZa;Qy~%gMb7>Tbrp?GXf%2bt^u1xON7%CrCgbI4vSc&a)^GMF41;-F^=5E zTitLI{$YqJ@=&9&>p-O2=@<8)L)}%3lr*$tP0H^g-ZI>=o5NqDe2Gwn|Urpt8HC9j_@`|`L8Nx;; z>N`>V_aWr?Mmo+zF?g9wM(g5PiY#Iyfyei?hWQchSq@Lyu`nSzjKO8q!TPq5zfqUb znsXhQJA0hnqV1db*_I=buBRKmzdOQiC0iySk{rLAwbqlUTr^%nlTVE^eemL)5mYTC zu{vMu%B-2Bo}-nX6LQQ8{jx?soxLv>EcC^F$#!SB6y;&X#0V+cnPwuH62+KO%(;39 zaQ0XYuB^C1zr7PK@@GqNz7^G8cML0{)pHLAD*$C+;0)9FoUrBUvqzSQQ=v#hFIxTf zSB-fvEUFZen}%1{v_d76^aTAKIWjRn6&=0d`oOtDhu3?aI~XPCiX|v$Ipw*H+YA6n z`XImEv|fXGhyGE_kDP;_^KM8qx79uM_Wj!yW?EYAUs0GUemM7YnIQAqE@ z?iXL=D!mqA3f!YWi*8ij<(`VoqCljueJA=EK<+w7JPlIgWv5>s#v z)gTim;bxb-ukX7%wt%b4^!qg?kz0Fqi`==}L_5C*+iA&nckG$W|mP z)(XiaR+-OZ@)thz$*J>G8rl=8j0io+qp?(18|?&cc;|?YoupI0r7ej$wYr~YDb+zJ zv&t*~;?O~bZH1QqqhwPF>iY;i@4+zX4l-!tS?Fx%=sI1% z4_nMML;wXqW7^zVzH~gOiLqU+AVuFoOfGj&e^!q~?|DC{=}qH@k1I=D0S50Y%$RFm zM;Z4(yiDxIla8HCjmUT^&ZlMo+1%#JF3664xFfi$@LhWWDCaMrpi@(TwSMeTksPHj}G)0GZrqol(hbe#iHiQ-0?m zL8_hWHmW?&Zn}-n0o8!}$IxxukG7C3wx&o#7f@g`QL47h|Q(w>mwkzOV!913ATxM3CM zRJ&oj{x}#Y1X;vvE1zv^#R3DBo}3m{10Gh9tW?nX^1)*(n~8S{DMAO;%!GoVUk3=Rma)r2uhuV^)_mP78J zUEgd>A4DL^A%cq?z*MfW26rSU8lM#gKXnI=V4Wotj+u6wbTxGUz8M_REwomt-TXM1 zp-Q2PH3+b3AjasyBoA))C|{_WQk(lw)Tmz(`2;4#A;#qarBWEtGO-4K88!}${?Sy3 z+u@VT&8K=9J^|2psz2uMVr;!$~Q zcbYBF+32ycrAy*9H$4@#OHm?_Occ}y#SisXZ+vMI#b4klL>Dm#AyL2IjAP5*iaP62 zKg7DqJjU}uqpERBcz8#-t@$RCmkF{RcR4|xRi+%8TXNNF1HCUuT&LygMl6+lTJsaF zd{pJ0H1#yDYgszBlQ8c{ooPOwQ_r#{j{Cu%rR_|-zAQF8%WEE6I+CXp7bxwN4WDwwRJUPiXxwxm2=E}*LqV-uc6`KBDd430in1$es=EQ^$R?&!=s_IB+}|bin3W9*QdivRXQ-E zQ_?#&uG6C-O|DNi&i^kryGT2m8eMI>WOgX5apI-9XiC0CqvO4;S`V|Fdk7`p$U_iQYbvl>6waf!^{ zW`?!_9Z2-(kS9qtuR_*@?^N%JTGOYcTYLiNva$j`&9)q=?^HdZ%{(oEq^R%}jq45a zd;;Ar{o(VmQaJQsqrJH%1@APgFWHidAp!;fK06K7a`%8HmAVhYEXdt?c4D#kO!gcu zE;4Ehx{GHm8yrr3*t`u*4%gt%&d-SOs|g=>4;-nx)2<8$1RJa(gt`MVnh{80k5tuju^A^wu?iSLy5NwFopc_Srd8q%4$mT{|8dCQ#2 zi+zfiH0^Sk!9`f`dP|LbE-$07LNSml76#XM2EVh$OXN&^W$rWQfr@HYd?c7O4Q%IJ!{DD zJe=FyaTnoCj>Q`3aLjmIV*GiI45ORdy50E7%Lz->15);|LA^;XD~m}kAD;<#x45?g zRdbzhLm)eecD6dd;JoJF((_eKXp_|o);X|jU4eKuAOL4Z^n51cA;>L5)S7@xV#8tF zo!*pLej#`oo>i&!<;(i*c@gT1FR~9|Q1r^Go~Y^j#CSM-@Z0Pv@2y2wRN{gXsuC@# z>Uu(S4sGp$NmSP;B()%wKYP3Doa`*FuwdTuGy3a!#45Kicc!L3D_*xJ^f^H3ZPRa zir%b_&QXpYEPYbhD7XVtVw&>`o-Qnf6s!7tw7>C#rzh&x+{V5#dMCO4xNppC9`hG# zS_Q%bz;F;R-ffvS2|d#|28&c|_}NA#mji)n%O&T*j6#`g2Rl}c}x zrW7fc@!TR+PAmfhj}-g-K55lS29AT2uW)?00$>g!L@a)QPLhr$17M&jo~J^q5~RTT zkP#ckvUfekLSR2%<4Fd<&~S)O_UkFad6`EcusjH`1VkZnHAt{fsQ%>A@9DBtFp!8} zrTKj|v;oV$bnO*|4E_to7LysD5#B0e94$tIxkYNdu z&Wwao7W=H44%0-2#A;TSxD~NJ*SF_^or6@$g2Zj(+cmGsfpz|+e2qGnMZ*)V1nh1^@WO; z%;d3bnJy5_^Hy+fB7n6P_5!F3(-pe5sDWQHR8}m{K_w_!)XfBYIXen|kThWoXHD+* z^&R}-sxc~g#datjgm+P4h7-Wza8>fcTDs8$t(MchFGx@#9i@b2tdLxjGv>Wb2gZQn z3jnAwiTY{(FkN=c>+Zm#CAO^elTi!a^ITz}WU8TY*KAKQt`P?$t|t!BkMNMNbL_UU zKN_#I`g5MzMg_9ylJj0YpiQ$*U^!C-%L*c4FHhw`Iz5r&PiP3RkV!Im3TlvkB-7JIpXk6Wrd^%D%m8$R6)L}y z?9;oi!TQSHF1mctq-r>zA( zPd4|;<_d~&-{!RvR$Rb-c=o!cTYWr`S8Qz0h!@uns#=l)RxpQ`x7Jw^o2wx_A2NTKY(0PM$nv3f3gNMfg{I$tFa^t$X zN_mxzI}LLS8`PQ*w1vvFFdq-=SQL~youVWV6|#p7&MT)j`R*EhuIY{`>#7pW<30{^ zte&#orMsgcD5i_?-W;i{;c;q_kxGHf1R_zAU>@FvQr3()ckeV!5H>3!7dQ4^3?a+b z8eu6REG&gf^Z*_9o>5QOTD-~1Gx>?2(0etvhc>Kg1}#RU6+ZX4hzmi=r4Nr=)m*$U zUM=Mzgu%&Q&-G+VWf~)_w8QO@1F2v!rAL)zfcYDKXu$@{iS&i6Hb{Xk#UE=z>99Px zZc)XNB2)2Fe*HZjoMmi)f%umNvO`nnbFmGMQj)2_UJq#J!uHZJS@s zbz%DymEPQoRi#25%NLMD6klu02(3qYC0Hi5v}dNSUSQhZ$>|6>F{lh5AT}B&RZ$lS{v#IwzoZ{UksYP zr+3L{&TvyOcX0I)D!nh@%~=pI-&qB398Q=rXi)h)j8`yPR*ka9LA06;zWT9RqI!TIWp5b5g{C@jFCki4wHvaw;VMO_9Mi*h`o&7 z%x)a>)7#L>GK8f18;JuLI9wU09^xhjP8G(ta|Y8qq2oBq+ACA;y$yvH&6o|D*s+fA zroI|3dc$adK4*m@EP^L8^gOx0Lpx?Q#t;06`(Nxh{;_IvqD>$8Ap^dOqyZ49qq)!feLCrp|?!875e=$zh^J-a%AkBSeV za}xC{gdh6{7_H{9-g5+z9uZM6eW)Cab0kk^v!6RnXjlhC#T3B;uTUh!^K{DB|tnGYnJTkH`Ae&(R3|;xUZP z1#@4%PGh&_P!l{lo};y5gEMCt72vC|w zaqp!o`BF|po-l_!B5@+k^M;6&?E8v@l1*RKJ(S-*duPPy;OL79VJL_@gpi1njM(LD zu3bCiT%leynwFZpH#ENbB$!HXUF&Y7jLl)ktgjKC`6GeKR7dKfE-fR?p_%M|y>C3LDx!BtWgEcDv^9M=XsddzMB#ZWj zXs4a*jovtyuq7ZSM=o?rhNN>KeIDHD5}br|eGs0?0q}WW#S&>#ruJ^v+6;c!VBI{S zG83?s)&(+8_>dJzCIX+|b9_~|&W=o)|WBO-5 zfl!*_PWF0r?#gc&&pKl2$;l^phE=_twkMx%ByKP*kPmPdA9@wRe@Az4uNYE@8AhuR zJ-1yU0m7KIMbN+05@z$_Ldb%zki)h27S$1e0I2`~M4!)h=7{hwc$43+KV+_=08fcf zqO|FdX@#q*E1>YH3*82 z$<|A7pjIocoY;6_-GM6Kc>Xp;o{hb%$rRP$9yzSXg|J7}=%Tu!tdM)rQk znK87nJ+ZDuy&f$F5X*-!t@{U<{luG}jRwp|8CHgBUK|Va_qK_UCfQDqbdhE--o|*! zr1GH;U2@RcsrIfThjy_OE6^rtfzP5L;n{>o^{{odd>^FQ0_VFG8F@np^xWAG&shB? z?}d|~-BU8)OLdc5>+M66ds*FNyYDi+!&TJ&(H=;e_M8xHLZ|NNofb>#BQL(Exo}%6&Cr6tb{c=nsdIV-{7I=vf$lGnD z-Ca>ssib?CvAA>lZlC?qV<}CV?xiU4x+Phn9K&BaYq&l9E?k6h3#8^JHQQUc1!LEHcjBI%ibmwL z7RcVEbBIkMU7C06EFZT*7W(kdk0Zp=y~qD7&DV9{LwM#Huh5-rRL2- zgyOXWn)GBV82RebQEY?C2k$x*IG_7wZuf?`NgSf`!AH_npJsJC@Md8QZy3F|iDe&? ze?2o38JuHFuV(J(>H{fF4(FqjcfUKYq^PgFNBW`NNtR5BdI2Y`*bAk%Y>EOXp1thj zC-iic%^#5XXcFIQGRNm()J$tqr-Z_#7Q-!^HKxB)%;9{XJ*!7W7}9wQn}Rf4j8cfq zr891x9497sh>+1SeroAZ5vjCut3q>rMHjsV{z=(8yx@Q^laLW{refTeis5>BpBPm~ z>~42igsJA`;VVQIzftrJolNH=6pgG`r*n-Gb;K3^`Wj<9Zs_8ZHW48QvrqxFJWvSFgQ5?J>A zXSWf5++%D`;PcGcd8t5px_R}~W$}!4fUcde!kG?+=-#eICN07fYnV}HQYsBa0qMvb zAKC#7KK6k%^ol~FIOCTUjKc#ep9Mv1AuOxc)f{>c!-cx&L8qx!7J~DH`gJ0W3&dF* zEK(|p%Nm5RB?XccV+d0zw406*arcKGYfn|lYNrHK*`oM~J3oPAwN;Q2;Hf+hB=o;< z-FR+K>XJ*p2Z<21>MM5VZS@pTo|634eatglZqMSn?$5k)WXHy?XbQ0!>(A-uFps<~ zPt5N!zMpf_o7ciMU!JOcE4Jv!LchxP(0|2)sI;%9YnbX8R6jM^F>%rXOjnY=PVU1n zdH6SLJXHk@_0?U}08bY)dC7U6agh|V$1F9~}i+9wq@3&G3sUG$&Esdrb#&4n!0RWn!!CaE6vfT7_pZ6Y-ZN48iX4W-E z2vijk6g78@s9qw0kXgAmBlz_>l)-Fyx^?*ieLJYo+8!8eWxqIOnvj!+1N_5meq zhimHI=A){xjB65*YG+D7vxX%1ddMgC?C6M)4Z^t23&)mrsvJH7mdl*r`4_VWU8*SW z?8IlCnIuIC%M#t@8o9l6jxMz6mYkNpcVZ%<@h!4H@=;P&G%X@<^Flh($n@IZAA3CP z5bu$ki%D>+)(Bz8Z4Yr?jNr|*Hgo(#^n3WH&nUd5`<7{fy%6!6VsU2S^Gc7K>nsgC zGBrG67W|+D%%^ho(Xq4d=z@R(gH{4EK-NI|PmE~pQ}Z9^1}NAB_Izk_gT0qF!#eO} zEn~aoWnKqu)-Y$1>;>vAZr-aMLZN6-=1f8AmZ<5NdiDhlN=Q&LiYhvLS84VWzkS;0 zen3K6MD}s<*$mXV2TzkS!t(ut)}70>)1XP6_QT^%vKJ`Dzx`l9UqWc)nlJo9TV1Q5 zE4{??yUhMyZ4v;w(Ix@^p-aTSSX(8VYZ6Xj`StTW3Wf&K0|3z!FM)xco?Rc?=CN-@ zC!bwjwrLkRI{BEqcG-@9#Wz8wqOi1aTwFNYP^5Z(IF@!8&_o6$K)!p7J}U2FeDOvM z?$XVs!JGZ5+Qnip!op0QpPyJI?!h5=?jJyj!E5AaVewp;X;~cF@9B9`f}_!^C9Q5m zsRt8mka;T+56X_Dt?YGuMeQ5?a!Uh^GOn`Gv9YnyQB^fH*f52`2+zRX1O{TH)(`$8 z+tZVi9g{6~HOX>$t@_ndmZ}Vc5Xgxbh{hCxv>5vXw)Kx5dA2U@KW{JJI^2O1(Q4MS zb>ha@J#&9UQaZNeXcLW`KOX2S3KO_kUbgGqG3Do#ul}GC#8(%oP7y1WH(a0sOq8Ko zgoiI5znInG04KYLkSXwqE@A_M;SV5*WdOncQ5~ATkUWgV#ZxoQ>ZkeYygYRA@^Vr+ zLwk?P6}r~!?*&X)Qm05kA*Ulmd8P^G@&UpL2*s1@+3=rUo?GuVw6DzdV;6;eQmvb@ z)=x>}PBIM>Z_v5(LY00c8mnyCK0r{I0?LSce#(m{DKmDJ>GP=daGnI9j}| zP+>dyL03n6PRmdm{7*+m3kB}nqjYNHmF8OCOLl!F>d0wDt`w;@!?QtKv$35|u2t0% ztu1denj=tpXk8d+F>s|HI@)k(@{>)=Snq6?ZqYpL@riHfr$V z>t_ZkPzDk~cOH(2HIA8c5#m@$q<-tjUJDrhOLG4OBQ8eS{CyjUA?4H9F6 z#9YX*W%UsxZcQrch17p9-`fd`WGDco{kodCsxOQ)TTTQgS9Grt^wuB|h)D{E7A*3L zjdVtkVCKjrOO?(G)&X<&(4{KHFRiHjFL<6ey4VPy`z`UUNh@Jug zcE{($G6@=k!Sp#~Y}G<<+6y*Hr1s{1J|2(cRmml(Ll&J#1(r%1dcwCkgrQT2V7j2T zNiZX8_(I*W#=GyO8AvB4gtm$Hlu>sld^?T5+g%x$>4tIs$>$k#S|d3yr@7uslPRV- z1`^jtr%t0ZWshPOz=xSlEYe5%b#0T!;IvfpKq2=s?E&_=;^Zr zk=%Av7{5nH%Zmk>`N`Q!WHwoU@5B~fLkq1o5F;~C%+YBY!|$`iu7dT*2Q=#a5fdj* z_!pa-Nl8fywjjc=j-~G9qa(C_;%s4RLd@Hd8pJO-IPjk{^YhKlJqu71Rb*NL2Dt}9 zB^qdt`ATkQPTE(qJnxBrXu8J4@8ZOpVqHD9c?|CpBAp2tkC_MtBLaqaA9es%CrT(C z@~RxF*jl|RGpP_ZSlv|A)D^3Xi1Ok_5$= z!V)u;l!6kKn3(PQ2<1TpE_qhPK9+QxWQXx0`XrTRXMVugi z`tb9i#Pot)@y1OnQlSvTe7&kT&af~6mW(Mv!mAL>$~ghXy1j;WT}I(5FZ&r@Pkj*L z7;Ky{wC);qAV5EU^f2~jc=i;rDnu@L6df&C28?wE>8W6hg)gWhCK`RNFf2#=lXYv( z9g7KwU?TvG`cVTTYzRBL+c0ygqlHBAM8#tw?&ag-fdwwaL*TTwIG#z;`RCboOO7px z#cmEA!x9&xVx#fm;eteHRx~(qu3qKp*2D{5o}Pc-pbZO)9AmHU{dB;uoXWT2i>vM~oK8=w~B#sshj%key zDe~ae9f^$Kmm6)>?RSB_xzM!=6?WW>bWHx^1}2O!lu@wsxzpv_X93R}sn0?v)PlC5 zSOv=X<>%Lzy}r^dKO!v*nB8bom~8*gbebd@h~R<4_05%Nyuv$*2aL%;d15{U`QX7+ zQxqZc-P%g~pI>x;$2;{}zM$(oAH%uM0|X&N#utYIaPi!xD*s%fkPZ#nL)TFP1Dh(} zLjfnWNXamy$cY13q1}~Tb4z*%n0=U$WaR$+I(3QQb(L?tCgWNQe;P z_j*?BzkqeyYdZ@c@$0f*raElUjT{|$ZdI$Dt-|iv0o^vIFDI9+iWB${8!lNRX;p_$ zz5_k6KH{Xcbtd*6eIxk|h9?2f@33uWCNK0D_iQD}RqWA-Md1Sn%8_%;sg(`Ym%n~R zOT9R;p66ua5d^suc9LeKZC(43%aN+p+dzLC7zFvi@F?CdzHJTdD=RF&8gCFEFQHOX z(NT9jKgU<$WPS1|e#dN%8qy??L9d4{y{bX{-6$@Hb{7Ull%i6(mZv1nd~6Tzuk->* zWXHB(o^)p(cWq&fS{`jitDYOxQnzzI_D35ECP9tq6;(YtQ!J#@TwFohW2Lw;u{z7BR|Aqf<9S!1Q

    qO6Ms9vkAu8)tjFWY7c+ch$_zRpO$I1oAVTBxGW#!%U%{+}m|61k-x%A^o?5k?KFo>~J zBeP}gqOc?eotFhc^a-wp`3d02&*WtBN>Sv(dvG?L_|58tK}%p$2;(Ud9BzeK#9~7b zhblI=k^xX*kn;Hg8FA&6eI1f%ru(`G{W)Xkvs?-R@laL>yNn{@1VthPePNiF;|~vs z(GyqCDO@IUC^JT#v*+5;?m^s@PWC0%4S3}u^Oj5pP5MrGkW`rg^k@Kvp&8`jowU{} zbQJs%DV&-3Gy}|hf4hsIJ<%c$TowMZE2)A#NVpSC(`pvA?lpOC_7HYNdc7<_uS$hg zVS~0J{w|p^i_=6H?F7wyc&AwK%^fG%^{Fjt|Ltn=9Bz~`oSAti-YGLLsk|JT9Hawe z;=nhL#+h6IhBrs9MFZR+;tm>FblhP%v(_L8iBOb2WE8IY?1K?OCfd}A8~L6cbbfdN z>M7^k=}}TpsX#2UKCur}H!`Ohf=myI*PsFEcf?X~7N=(1Z}578p#t~%kQQO!g}vVu z;m2pYsi0Gi_Z$DX2)t32UHL)e?->t;aV1l$6WJ?Z4r3w@9*2zj#iGsTMl1cXNDL25 zW4qfKQyuhTyEBde4`tJf06$_Io(E$;;kRo~II(pLe-_$099=E$yFjY%R1|gen;|Do z7uewO>xDu2A%YeK>s3fUM2TCr4eSX)wCvO$Pt}Ly_YMOuW^>~vKy7p58M3?Cyv=(Ab^!Y2kO-89+*qR zXms*Y&cqD)#()r5b2GN2F}0Ox_DVinm2PuL#{N7P4-bt>l^W;~^5sI){7t5Kh%-(F zXv6~P{O-+kp0zM0v}N6n^97b5eq+5oSR4+-cxbJqRtDcMDyCE@+r5YOxV>4=Yn)^d zmy7wxt4LAT2|^%5d5%pB-!8In5iM}poBcxe@IuKGiWrv09h{H}j|1s6kZ)V?>t4Ph zLrd9jV?nD?&2)`AoDN2$zXHhE)b2Fv)n>ltPNEhl5fI?*k`z2sQK>c#F=C0A1ntg8 z^s^6+Pq+mHFr2&9MV&2{@^pOvSNiW;*ORF;Dz#Ojox4|$830%s;bPm}={&KX_k!IC zZ&;2P9}0&R4V!1Cl_oXa=-$Hu2Perh4_jX}RN%1q)(CP*VR4LtQuvNxmMb zMP5I_C#^^0z?wgXF;sXJKpJPOk0Fuwo{J<$o>;F-`1`j|a-PIq1XH$O>$Bt9PW?9kakUqRtglEULz{}KfLIA4j~nh6pr`6~;H zP7H}oVnahB)dGT4VF$M(Acg=NE+s`^Jf3GN5DFx@lG#TIbCkCIzyKM0K~UC(0fJVI zV)$S}q>SH~;KEY~rSLIdrIiOl1&F!dcTIDf4UrVD>%jIJd|YHSD@{m~S5)^I8uJpv z5C`PoSg>Y8j5fK-1m$x41ODtn!mH&1qhPXz%A(TtsB-mNERxS~Cf~~#ba7R35$yF$ z26T4!_8_vy$vbR23yG=$Xc;;D?f3>x{`i2=FpAj-DDB4kco!3^V}tRf5Oh9rG`JK% zuSW|mV#d%&F6@*1R-Rt2T-|gBJ_i6OXlBNuz(yf?ofnCaJ?OPOZ9aZf113Y=4S)vF zbfZC6-Ao9#rNlxvjW<<)qCh_I80XbbN72#`saw-8+Q1`BC}#$7Y%_-Z^tBj2f*3eK z4uy}h@5afk&rMqSx#qYyMcJ;`;{~b@EE)S9jkXKZ9g2v{k^R!jpc{gYJZc^-h=*f} zwddy?qVP(b!K@$bVVV$_rmLU(H|iLySB^dx@Y=H-qgbT@?S1ToZD{6i^G{p}%15vV zqD2nukxbGf&DBoh-ou=dU8}>R_U1AH_6kD;|5U+3%)x!d!!(te<|$%CX!}Mvoc`x< zX+`|LajiW%Uvr>fN#2eet>LjC_FeK%Lb-clL?2&1j3E#X76$vBA0Y#l5^zv^Lf=A5 zzXrpmoBL-dKVrnRT|Wjyi`s>-dNH|m&yT6jnI#+qaOi;G9WZ~tFdP*SVAc)@ty-4c zWCr1yQeKFAPwwBXIeQ=h3GyM*K#&|7X0E*C>(wDrV2ohVjQQ(ypa^$*31I{Uijp@B;BQ22ikSFqxlXL)N=+&Iqy!v{hQAR9`n>aJf$jGfQj5!-qG z62Bcjy&-bZhFZIdV*da;aPmZo?TtT%eZz2}&z-wo-6 zkMZEB8$=YL`6KmDl|fRycd>fi|L39pCVxbXbK3IsS&~VNiW@QZy_NFzNt*PP&{bzn zh9us7U`OGR$o}c-qCFzbLO`-G?F)Cz1)cOiI6GT|LXd_gTh(<0og0ECp!jv@{D)}L zU$N2=L<>XSPTfgl?kF|&fZVzJ4r#m$&V$ zmnUmB99g2x3c6YlI7SxVjHr-Z_16uV3YC$ZU@uRJCq%aF^Iv^pjJmCVDwuJQa2rg{ zYB{l{x|j0_E2pNOnh)-r=C2wwrFXcZU%eZ>;(1^%IV-9DE>u}x5n*wU>7Z3h6y0{& zCZA=tc~o%rPThv;ECt9_V$A86sJC^LDIJGPs1A&2QMsHu`n!wjtAImiZ(JaR7={~h zWUu5JJH80KG|ga7^w<^5?d7R<{4gz$DbQ#gKdMuAD0kv;cEMr4b;px{-k_texKP8d z0{6XULyNJR&Yw}^N~d1ux+kBa?)duq>SD@%m^7wI4jNL(dsNvyv$?r#y9BT*nj3v5 z7i*gfUL2Rs*dklPV&}OCc5b$NcL@zS$=KR(s6Cw)f6FSSEe(8lRmXsgzyVe!0 zHu){Qp5H#&0}S&_g2-!0Vw4LL);qSAgFD?QrSd53JY=$4Eh)Wx(Y+h2%DO>iIw9lG zPUTM6RJz;(x1O1t$3hc=+hTO!%3_=BT-vW{N}a}7Nsimmbj0v~5!EsWKF&d$-GQ%n zYqT#4LzF6DVt(2~Jrh^XlvH-g0&bA_-v+sb`eu=gk1eiRRBqwqwQ-vgz~ zwZA=efPrSh7$^n!hz3bcH2g-D$^3DrWu8+yQL}pd6JZfF&e#x;7?|NSC2}PIfl?3V zulE&RM>4`F_zN8pi435vo>-_Zz(|+2gvkrTnPUsdkARgQ{GJkyilCgQ3`8ymjgVjL z&F+sl-hW^W;}h-&u2p{nOSZv=_lxJw&R}4ywtUk&ZMkcbdXlb6it~s7ZIEW9sw-%8b2e2KSdx}6Rn`7 z4`dFfkVMTXNF|&`JnFU}{~P*%C&!Y|C=u{&u)QA$CDjZdiI87^@-uIgmC55;B9m6K zLoW!D`fWrxMwEbMtX-XK_&u3_RqcR$3*JAX0IR5{7p?p#Lr#ys}Ev=NV1P3>pE z7^hMlnlWYnpDLwW3n1l{82_&HyFccrw+BeI4P4fv5Tv~ zfP555CY!(*iDd3Bxd<$}Pv|3XjHrD8I6}IT0ZUF*h?3EagUPV#=#*(T2X{CWR$q7H(}6`?))Hx48Kn?=cT_POn}Q_8`~00>wV24LqHm)jCJ1OirPHR+)e!i_y7NUtQYMWO z)tE`DSr3-!Q0Ix0oL$;8>9&v0=)yCL@hBUmOW@`48%gJ2@)c>*0r5v~5ygpV+XD|M z9CJ_CZ!ij;F9%R?0Ne#DcUI$LT)C4Ff4)w#_|D;RO~gkey7L7JyOhQVU>CBcPYiBX zAE;p`Pxqr?ToH=SQOemfB8lG4@9^V|_R3 zh4FTg|5Lq@Jhi}^K~!7cDJXipZC<6+(N?77H4c8tDnrx!Y1V3|U6~^G+Xo6gg*Vznt`v*zQ6W^!gRGD~g))hHKrunECS=8`3F_1@#FM98%>{WbJ@SFd%I1LWRJsS;g zFx=z3y?bDu9kBFMyOy^jwd;d-nI3%c)XmFZZ@Q}sT2u7+yyB)A+ewEIz07+G+_N9A zWu%j(o!nj73X7)O!IO)&1fgvqHn&%OT)WOS8a(&;xmQU)AE}?)*@^>q?HF(Jlro^P zzOC(3G37Um(-gRx=I$g*EA+KHYID3lg3Wfy)Jqo!^~UC5#ovsnOqA!p;oZI<+#C+0 z|E_-ezw8cwGO+%KKN=g`KbC|4TmAH3;q?D61hg;3-~Zke2PR&e|8GlJl*-w&vx%K7w2e^J{&x(|7g!!cy2FRTO91?1Y4N9 z_oCg8BVW1UMDg563oq!$o0CW!ns9tSfYigB&zJW*&}7mcZ%ht?c^EV=6`~>MFlBV`rn%Gb_W(Qd87U|rP5xY=@ttjKZkTx= zQu-bw7d*~U-`Zxb&gPV)L0Ml$rY#c$490^PS4V+h@<=h;<29kEHS?Oy4wn7&3j8J($U$2 z!!c|(qD02GLg58GnWMSRbu-F z=$0V7Q9UdQ`z#~A(z;8((7+H}A$c?ien1f8nv06vRBqvl4_2_|)I&fa&~*dU7Z0G< zWvSUjcyvH}@f*YybblM;zHM=keuI9^8QRO4{@z+}4gd{W*R62}m?1cb)oj1%Wkcjv zR8*T#9R zIt#{LKOU=<(84G4gSQ3|k)tsKe=DY%1p@W}%}HmSFf>KVy&GVVIO-i+OUCg<<~sOQ zwpUlS6mhxYcny!HsCE&2{Bg<72!332qlZqOe;>|6~*Sp@3OJx=Yt5*z77D=rY8K(t?-io`vJST z)I=05G961!pENy=hcR}u3pZ3ZPO8+;0xc(k0$NNGKqQuCjisVyo6BBOYwIG$h{#Sb zPF_>oO}yi+@PiJlN2=cMrLxcq?707L^_~ zb}Vt^**&D|^z-bkAb%^Zkr0n>`{9|}3lS0UKiaz>v=6xOgk9gii%0(inSUY=JM(`S z5wU&k5BlH3(U(d6e?e2>f3nMCVEXTmM_T5t`4Y$z`Sz+>(=Gkn440BxsLVL2EvV~q zKmY!XZ9j!V2fNcx``L7bcPiMO;Z*v^`;U@ps+P8SF)<&Szon57X`D7*sFS|Ew(i#Y z`ugVPx)!nq@?51%$(CV=9)ct&rq)ELdPHv_P7qzI@wK14e727)Yj!(VrBbPK3rG(sYFFrnXAO}{s zFyW;(3j}&R8yRLt=K`+vmq5YGJr>do$O7cLAKxA4&jSRCxj*BIUj;c1t={MKxw^K$ zTB{tDNg^@QIH9{j-b(!(QtXRFrG}JnJK|4w1#R80q(*q|U{JFlA^I&FH(=}XFG zcq!wm(qo6=xD!M{d#k(S$XzUXlY=n3`PMP5=^F)l26ti~=7iE(2Y)Ls|@#TS~!Y2>V!rcR|_xIb+5t@|9l^SJo87iI0 zE5nu7p&;$b)bV35vG2p~b&i#q}vX)v6 zT_&vm9C$60R4R!f)5!SdU$17;vaI1Ze{#e{Xyu3Qub)D(+aerM+k9=YT!ytT5~w#7 zb=buAu55n$xC9d$Fg<#@(b_YtTRtZO+60RWGnSx^y(Fw%bUkU_777IDmAJF(T0d=V z(fjh1Yp_Vrmh`^hAAqx8$t*L2JbZNQVJPa9iB*0gI_Q9~>)N;=&pi>um#dScm6G!F zt+->4us8qxe2^5P%8ZXvxOu@Jc8A`_0|p0>NPkV}s5Yzb{3D>0udKLZiHq#iNX$9z z4wdc*NbVOwUsjVf2jm=bpoMT&q9Q5e*mo71RF88c2G$k!I$Xl>U=VXcvkx(#P<-84 z*=Ot{*XK=ASt^>NxGiIQABu4TgI2zB=u*XO?J_=O00yuLO$U-)lr1mUPifEQhv5Fr z(3m@L;K-G0!d@vrfj|57U1DI&olNl}O5TU!T1&1R)Z_inq|QIn)u}2t&q{UF|7@~6 zyz97?@>5bnUME(oLOP=0Cz7H{<4)Qt(&d|!_X(BX&Fd|+*x&Ox9WUexS3^;E*f$$NuGy|5zYyt+5kwp{v3m3T*3n192P>6V*ux0UPps#r4>d#)1d z%ELD)`?7&TGqZ7-E#upmbtJEdtKxkcn8Hjtq$@syMajZds}2~1A9V+ zQEq?GQ;qV7zn=Se!T$Dkq0ke7gPgX2xp#6Wb|&5X|k@ zdb$;@EfHQcMZ$>a=C5BrUq&rW*#a~20l-3~HD*rycGl4ssZ;T<%f(5N@6OnDN7|ORtCwS`brk8DAQ0i-xw29zEdlkr|^Q1~nqN>>v;XU?HGcdjE6o=J<|YXu_WU*m(`1 zMPCo;W?l{Ciyak0aQ85&$CN#BxQrF@Vt^?(4xN=`uv@UZSONJqK>v=V%xhYIVm57# zMj&W26M%5Zt;HAgV{jx(n^qNC)0SoZv6*3~)J4;#UWX8>l!G?)+-ufW`I>-a-M77b zk0gXO!C$)k#bCmIE%723=N&f-c~2keNlxuA=U&T$!RJbu35m{|xnYK`SPvr>hC-=F z7cX`>Il&cc@HZ`Mu8-F8di>VNp&D&ubc!f8Ah2;!t_;2W=~zNkF-+)`r5#s8=MyDnjgR?P|* zq(|97{<(oG7ZG{i=3au^oOfsEF3)wrlzXd!3yn6+PSQ>6pJNj)ZJgEC&6(c=aYuX` zK=|r~$UbHX1WdR@E2+E)BYb(m#nZIP~TDkbz{|2#9vYVy{CjUn1fsi^Q)EhN@_*PGhfip=&HO~dG zr6D!2GcLj`;*b1!S`VeTK=#2J_&k;mLMFZV41SBs>@JpZ|C>zgU-{KP znHVD@ucv#SG@lVe)^qSNLx(4b{vY^Ci%-zd$KtT?iC@bs>nmzrGus z&7j6;QuNiEp{h;`Ql&w2p`LH+m4DyU7x(=~z!Ra#k)#OHxai&WZoB`_1E0DC&!tOZ z1)G8&`Zcl|=O>|sS9vw;emObyCJTkUxn4*M(-VhxkVA_G3_0=HTMVchZfF;ye(*Mw zVfkd@`Q3DX2A-0x@-#XJ5-?Tk^2;;IsVv3!+0|ZV#ddLHEuIhY=&F=A8t_f`*i!N+ zsr6w=b?F1H5ay$0)hI(QY+QSMx{$nV4bAJG6XI{8MK)d*GY($gj)}SeRU@a#$FJr}BMps4?1h;W&?0NR*pX7v|Zx}SMsjr1cD0%0oXj6B+ zBEsdj?V_d*J0dLrS#-h!t0Lw)XanrL*|)n2DXCnDc-F$?kElMKf%(~K{+4|k6zqVp zugy$}=UOTY2Ts>NjJx}vv1nA8&cAi5OUz|G%{R<+z z>xg4xM46!`*~Hh*=klqh;=*aGRq8rnQPb3Zk*HoJBMkJrDV@z6NIc~$s_XksB?cJ-$u2WXIG%LNU^**jC3 zfgDP#*;ZIewW@>i=OybKI;R-j5*=QCWt;_pv7jg$fpE~n$=stdBy@(Q4})Rm3j@AE zlWDm-nHQ2W?lZ%l(87vos%0`E7dR>?F&Yv@qD8NCjuihhR5^Ljx=^xA6pW>G0ukWK ztqLn|@f#-D>`f^y@jXJk4kZi|th_39oRLO0$?!2da%L%3_$hL0tem(jZtp8Dfso?2 z7-8n1yQ0EB@;dRsjqFL}509$gL07q#K}d&Au<@Oq+HhYJ;3Td`{`2Y*VnnRv@uMCz zc{k0nD~i7{NGxKX7i!@<+Ips0Rcam^8AX%`b5K(7$uqy(HBfoV#93{>wC7}#|I+=G z@iN~%*hA_|#yA34F5+BXEERZuN{SeNemWl_5`iH&?Q4zKDYCKE1*&dg>F~7~>|FCW zBTiEORLzBZNNjVs$SR*?5z2jv=>xc0LUB-UYn(ifm@w8@)jW&3ARtgD=<>sHwCWim zO6l1($7WTFBkYvU;@pv!2eaMk_2wml51{S+Jflj$$VkDr_ok+ zW*We@WOr$zf(-yx8Vl<<;ewP1~o>VZ7OZA0moS(9ewLpxF?` zS;BM**H?=<^Qe++#;PORt}>w{nwUW;W`cTO_=c3XY%S^f_RI8DOkG>9 zcF@H=8ck0r*4G!ldq{DD1#7zSyCpe}irccFUB0nE->$KSzW;e;xz6$2CbYW1F#UHc z??21wKPxW-3;TasWU>A`OqTWk$C#|@lEbbBasy^u97vuY$tXLioyOMRzcp))xtEFX z*&EH8Mea3YI}M&59s#;KDQal{*`9eRuRUVB3dT1-1>VtN2zE|RQCyRFclf7N&mKhd zzBcEpQj_$;+xvE+G$)WLifPI()5GvUwCh%~<~OWS4;7S`iyqV@Huq+TT@y{eMH5}1 zDf6bMSg)m+n+Hy4Q~ z-&tXZ$%3iwS`7G&6+>t$tS&$AtX!Dq$uYX?@eAyG4fnB39ES7Ud|2^CYtty{5}O#F zxSwB(;t$@+)hg@LI+}{&v(U~-FwG5nIk)d%A(*MwTg|zM*rUaSL!A;_dm#9x60oq4 zFJ_SLoB(e{vb?KM^Ocy?+6nNxFuX$$q8%CMd{p0tiiGY)Yr65%9fy;#VHIP4aK3eO zn*a(!RiR(b9O_3c=b&=Jh@j*1{!Hs2j|P6he6e+|1qul4LsMu&eQ^abSO zqf!Z+4JU)m<&w-g!y(YHid7&+m~@t1hqa)RDfx@VYNsopC*+^JRYhqVc4as3_CZrB zWyyt-jNR4|gSqS7V25XwuISHbS1p;Jw>1e0mlbY?lLn?@-Ukp-9lR^y(ZR$qDvFC3oz-6Y@XWM+WPC|>+9Pg zYkgS|hSve%x8MQqS94rVsOuK}{9zvqZ-p?yc4SoCBf^12d(PS6?e~|W&aDd(z1%I% zB-?9BuOuT4`omZNzxeFp>&3x>odd%Z7sdy1mz%d%><>#j7o;OGS-M9PJj4fA*Lu-b zJf1+N4-R>k8%7Z9#gRrRB1Iq9$`K1b_3#d?p1~GOL=8?47hp+H29ULM{Yb3$W(3S3 z+?k|JXAx%tW#7_`b9;n8*qGeIjC1jr=lYiBnC5FGld~X~aS0k{{XQET`h2R75uFE_ zSjtL%vht#U0_YRVP_ExV0N_0fSBD)i@-%hVua@;L{?wWPs0<+PHt+=e<|^835@IC>AtRp~7&J{3xcyGp_JndWqXsTqqpM zr-geV!PD<72>JN~JXU9nLt@l5__aEURVIAcHLK%4)#?v4^!p4Y4abW83mku&vc%P7 zPuZ)?+L%HMC?~t4vW1YqPgx6%#HTlVE;t3UL3#@PGBwBZXsQ}!OJp-4Nm#y&g`zDa ziUJDYi9d>SPQR6WZ>f+JlwaN*o|R46YpFV``6<1_JGY!pA#tlC&y1gEPK78e{$4ML zqI#*4;OZHH#0I!PBCDttU^l3M46TwFwS zQpPr>PG&@G?Ej@oO-cK6%=L>GAd;Z$0_k zTy-JDYZnl=Z*6^MyMi=WrfXHjjTtYIfQL@+!zF*wxhePm=_grK>Qpb4C&OHFzMZpf zIX@^C%bi7;L=F@#fv}+<{Hdt0{3Bsm$F5D=HjpbnD#Wy(D~WCqxNrau@g=LvUx_SV zEs#ppNFGXu79R9L8!7WWpEz{c3B#2hCvwZtCsaJL<294`Rl5tyimGE_Y+w%Q1na0i zyiB#)XH*%g?Jr9*^**5iG3#Tw+CIqgJe24*t>W(__>(rjzC!u1B2|4jd0c$fTCF0L z3LbJ&olKn{80^SalX~wrWi!83zdSj{XmHqxSQ39G0p~TUFH&y>=WSUdj1$1Ea1yDL zXcjp;blOzJLb#0*zV*!x7{ZrGL|@u1TPiy~vC6~`gQh4#USr54XMW7MEn6qeHuJ;} z`wtx+&K?}bXx{X(%EGB;qra@mQN zm^D-$%AC`Phn%^19?qq-+PC8HCk=5;_7B#m|3`*zw~BSF$=HGg&&iDgeT^lq46GW;Mhsh~w|UUbrnU{2jpxV!?2Lqz&Q-prS=i5Xa5;ib?HrafykA+{_gZUjL0)Pw~Xs|LtA!>cY>OE;NA%T7(}aV1giw8?5Qz7b{8V z%JBm`p(#~p%&xlXTj*#_lqFr=z~}8p2|t=opzhSkB7zw+z1r#a_?LSA)bSgg-sm8kVlvA)JGyfGr1jqz=g;C$5;G#ln>an3P!pEK0ewUQ)#idmb*vXKU2|^J8 zMePqErtNQ9g;9j@4^70YLPRFguTv)>h6a!(XY{RLv*;j#1LFMfhRL4jM2Vjv?sh21 z>Kl;D#gjELYj!ex0daiyP>Z3ygS5uLZ92mc>?ktFolvc!Ktt}Jcpd}NL_9(wSdIyf zWC3zE`Q~@my)L(y7^1e65u!xuG=U<9Wv>}Ph@i^*qx3YG)&8SHH?XF!P?4JW@0)R8 zbtvG8og?Axi}xUbZsHJb&cqQo;OvMbntt;R&O(N`KkW~sKXOb%(1;eXE3{FjLVu4W zoV~J>fikkFl(D71oG@Zs%lZ_n^IOwl`$fRMR~^R&6UTM1mo;TvpC%PR>TKDK$A}o~ zimQTUo;JXoR>>0D_lGrg&9iTyKH22&1qq7}{QB>G)Moyip$pV^GtJOG8)jVR)1P)V z%HU>S+S_Mcuuy`YdnB&mRwqT^GtGM#Ct`%ZV2IOJO84h#&B$onW}14oqqolLG9N%L zli1QslsW4AaHG}-c40RYM&<<{Yj0->K&(@1ZX}mV*Su&Cex4{X{&6j|-mPsDLms3( zG>_E~US$$#qw~rcJ%ktDlqhm2(y(lQq@cg^!L#Wm%(^3nVK{BX{W1g8qPoC0&lKQ^ zER&161hw~cB2q}`M;KrXwy50Pu3WKdTFw5nW7IUrJzP#5qCQ@DFkr!cBsC_9v+bp(W(lMwB$vW!7kYg~+g6+aTd0wN9?t(X>P{8XS z_IzlDEdIf1B!tY_0t@1^uvqc3ma8sfZX3$x!5s`503zdGgu8F&)#d zNI2v=j9sR;59W*kZyJ;1`M8H~nMR-5FK~GvzGYqJnb|Li`z+HvZ$f3kq5ZyTrq&l% z%Cu>gmgrWXFO6gC^jo}LynTj|?}%c;7S+}XFzqhBC%qdT1Ij^X{?8c(zN7Eatl_L2 zP{-|sH{>@WLm=6yOq*nz$5^>{34@vaxcJ~sIZ%S@LCA`Y5>+ z==>Cr$x>2bsWGw)bcWxuRpW(lMl?qx=(~X*)V+| zei!_FDRJ@T%AQPHcH$t=Q@(W9M))SxM4_aK{zLzMJvC{B@(Zi)ztd@ zQXrQq!d9ok?%D&Rg-2ulr4pFX%O5zfa|11ihpBIXhY1J8HTfaw8S^kCCqS)gaZg^c zapLgvXX>2Ifv$^_2K<+M9Ho**b`OkkM-+f62%%RpKWHZ8erK)HX#YV4Cj{zhQ9;M; z4pX-w`U=v}>{@~m7{N2IK`@9%>B76Xt(ZFJJAo2$GbOnJEAT9b=8}8X2Px@B*eyo* zeuVW5-;2b#_;1R|f8{*?0&*D`*#9~IPoItD-vPNS|E2Wk|7{?5#pP5C_1?N(Lf|bR zh!1tuwLMz)>tVXI5jxhnNPws8)EM4r&!Ae_@MuKT`0tXEArGN#6n{|&0u;CZTjw)} zxah>_PClMl zZ1lvHo;6*LV66zoiCk-{VZiO^ytqlqFE#kAO_n z>-+{FwZ^`gGFebd76Rw%y$}kzkzq%40-#Do+SSe5`($*vIZ0nqZ31#&RY+ZZ$ypgg z7*=Q`CH)i6SGQqXv&k{!yag%g`R6dOtduC= zWUbK0-IrG>z9JmlPp_%8GVu51Djd^{v3SD61ML9D8i~WhO&Tf*nHx_Ie;2=+?N`EQ z#|y@mF4>BSZXNpMSxiGi9DQh_>k`@-!8&NckR~UDt3pF=Mf}H!mFlgzS&+R+5HIgf zc+VI)eD~piRmg9xP<8{25=}|+CIoyEVugnyNabWEsOMEoQqwTfq)KZISNskg6q9dc z^#)gU#k||dp(`#9U~vr~VfZA4A7_%8(1I>mKkr|w1VJc0f2G6w2!y6VM=`6Oc!L>r z!6N_4q~~lW03tz?fOn_oa`127YyWuy$U*oGe}hO@`-zuf>qf(Wn19-R2i{HoJcKsjt}htg7jdi6tB})u3~r`monmvWuKUDe-NA+V zhQrefN#gXYz$|fazF*u^h4NyNsLX8ecxF?6^;s-Yxn_lO@G}g#-R|TW)zvCtW7F!m zuyMC>yWON9vdwq8g;RC?Yw_uF~n>+f8jVsNl65 z!?7LH|Xd`I``VYUk3f)Ifw?R107z;|<=gF}7&AM9mnZQT=bWRpNzE3yt zl6|<--KVa&y*L{>^5xmo;Ydq{l-3~_loTiVEEbLr_`nqHYa0FxCWhJ*Mi36dzos9H zvX0~M4w}E+t1Bvl1r6B1w)<|`M2LwV4CkjSDyS*M3C1Ahz*E&TMg!~3G8`jgIp3(L z9^p6)yg(qO4fNH)kPOHE_KewnQLKX`kqsK%Oi-4`dgy9K9#hT!h*&tdaen`F+UW@T2YQuWmPKEH%*axt8~t5+TT-s2&* z!(;Q@oYa}yg6|W{cfvke%_G8ECEPtYdBM4LLnXN%$rHlAYKRwtNV;Bu?LEZC ze|ZRHS*y&QvX;qajH_z{xW^f{)~ENFWbZyK62Kqy4t>;Yw-bIA0)Wy4t2v~ zr&Xc!avP+;9<(1&(e@#%A%|gpUPTl^?z+AI1^9UEM_vjdpefnOyB1E-$_Z+U=!TOs z_&iZcmE|uMi{EN~LrxRhaAcT5gK6K_f{JKAb zmUEM>YNmvR&2UlDcxk|kXS@a%B#${$O~t>0F*+H1`*iKIlYMkVhD0G=*b8BRU>ka7 zR&F1d@v+C)uairW|7FeaWqe`H8{#*`I+7EXJ6oGg*LgIpUF6`_M{RCP-=z|n0kJW1 zyZO@lt%=JL80Rzb4)=EMem5nihfM6gx$%(&{CH~;Tz?Ghri6+C@Kap=^W@_O@QSzN z^UD7pCR_i`p#Iln>;Ljd=lDF1t7VdY}W~;lQC*`1~MO{r`P{ z)O~Xg9OY%_m6P25zLjRHx5*@w9cwb#Ib*Pq6{{b!xwWt`-PC8}W;Yl`H|PcI`9SHP zHs?>1x1BI%C5@7P;B!IWHs`ORmhr!Br&RukSmFlbp(BE(1S6iTcnLN-0?0+N{qyJ$ z<+nen0-|Z_f||95uUmia7E+BB@2GUG!|7`;`enMEa0kW{d_quI;_hcPua|?}E|nV&=-ubHnj0voU$!N$da? z*@1lcc)tFDYL|Cjaibz|Fvoabbop?9T_{imdxuKKoxe!tP&1uzOy3-jCPZ6w>dHTM zHxG1aB^D%IorMylD>XYHyTs!yt*n{6C*f8$G50B^BNIx@10-Y9vb3y=UrZI8@CSZD z)!>JZFh2e1FGPl)O=uLD<2QNSYPJ_-UF(x>=9c9H1ql+&%=&&XLqI`MKr!7Yg^(mn zYwA60AdzfpM4{p0I=SqZT6X60rkKgeuJuvZuA~=`UJsOJQvel1IK?Co{^8dMqeE2G zU%c3ITUtkzd1Q|Z*d9n0h3J8&otulvn6KOS2CQr;Wk&-9W25o-^3pe7)shAS@<-8- zJEoMlYFeo$03y?_{$Byh?2K@YLJ#WyX|uWMg}6;&|j zi6qqG^7%$l>W<&4^@Jj()KhL0*P$Fy*#hdhGiw)Jhjg1oaOA zEgk6MKf<)?)fGw;(_d5D`OEP35;JjHEmg zZC*|RDdlv)e(x26BU4YqrxN>I&lF2NW#)z8l;i_?J`H+&Xn88Mb_MZE7qqYyjWO*A zWWXor*yWDXeE1*^i5L)%oC*^49O6y5fek73D2^k4n<)g+SC`7Fudww3UrnvVjVTT2 zaWR^B;q>PMU@BQO6V(aX>f}ESKMxJEj8~`T8P2C_M@5&g?{j2_(u}dwO_%dKH@&fJ zDW!|3$7Qb4(Ra(<6d$mN1SE}M?m5A*g+{HFv5qlIHn5bM3hsT^7B?1u6P+PfnO`eR zZg*(FqJG0vs>SLQ$et;7d%2dik`iF}r1DG)6CLIt7j2x1_`_vus>PF6h~UGd4Botb z>Q)!6-2spaAK`!)0Wq3{JY$DR|Mi=#dC6CwUcGiwW$Un5x=P(iq#ce%d7)j}1}5F< zQq=L3O@4OC-2H|Nq~4}%Clp>oYZ|%4qSmh@MFEqNU2-I%5;4TcSgN)%zlLJ#x}5Iw zziZ^dS|Zb#$xq9X=Z>IF8tAn~9w>A~jk4KJZzFq2h;xX;(y;PRk9Lc%e^N%H+jGsk zq>=ni@x9&r$byl&GuK`Gi9qS4s1|$Q5xGJ^%q!2V&v3%q;uTbvNvHboTLhurNe2&O zA1CQsE5B1?Mj>4l=bu9I+zaP#*#3bFAlk};c}3;&!~EafEuDo7 zmSZZMlC0@!blqzSk0?|e;WR25JJnLm{qaS560@qy-s$7$xez8AhM6j~zl*Gz_*P=r zLJ1;;W@ms|@Xb#E0F;u2Ie7mF&}YY1P$u z?tU77SIC>1!(Ye*_Wqe;QlJtMYrr##q%DKl@Z>~6tfTbBV_5w$SfNl>-?+8 z9x4H+_|Y{I{4akId8qGeN*=5+BwHb4r3OWX<)i)BJdddD3b;Shi8lGX-_3r&)Ww8J z#fr7idM5R01J=M2^C>#FzSrAwd7OC!pq+DO1&`F>`NOci%4Ur&U>5X;(}2d{kNJ)-68WagssL%_`m{fpUVEQQ(VbQ{}b2&q;t6PY0nKb*nnT9C=Np+ecHAWgkd2o>0 z1X?%iAZtB`h~T|dc83mPT?mI`7_L`SCi9r@Z1eJ}#0HeEi8Kj~%ym>!5sg zc|_kR@laC!KY#xp9%!%7o^MBt|6!)|@AT(?&6LXV;GB ze}1Nv>Go|~7VD20HoCDM?2^fbn(^1AL@yjWkFF0qxAHP9k;Fd8bAf^jnU5ZGMb?|$ zw7hG%;Xq9H9~)R8J=@ylGtLN= z^8L@=%I_^b+jcsw#OfkKQb!5HO}uNm)hj=C6ovXbWsPchJN$&ZBc3Ng-pyBJU9E&2 z14k&qq9WO&ru<;QfP>T1vqv8PY#K=x*hjzRx}^ecYEtF7V3TWk)lZtA6zS=gdO&dT z?b8D@m3QXA5gP56QrE?U`a=%-=-%w5i_5_6BY9qod)?HZiSIm5&+%{W)^^z{GCRc##|2uRT`RGNM_->=gCv|(ZdiC3WHedxDz(JH&1cuq#2vvINe z$;*2w`}68IG6t8ll8fH4!|aG#w1q0R%mEzvb@j3a3+n7>R~D~pQCst_Kl%@nbpwO$ z`Rc>PqNIE?w6wR9_ZdC!uU=s9dNrGbSV5H40;L+guzRW6LW`THQuR(57#(%*LzJ_H z^h|S~{5hz%1$*i2)hVL907=^$-?xSX=a&|(k%3p@>0*5!V49D4V_Rmi1q)H(Z6ACG ziv#7$Nu^Eo&8@~zAdjq2Dt|*!gz)zLR_V%xOBU(*7jo|zw787*V^lM_J7=G%3-$|g zuWK>eK-3~6AL7#sl#l?$eE*}_yo23+j9~@a7G#s~e}dBqosRb`qYtA_xp+OVGG2<; z&G|{|EenaKGQzOj19rn6KIc09o+pi_-SIBh8oLy;H5bYWU=F^IDW0|ec={c?AF_V9 zY+|odh^YT@Yr=ahAh7!t{GAq+c5yqZeBYSsj!KY@63E<*4mS~t&dc;aknhBvBjJB} zP7%dr^z4W2(~qyaa%L-p#0oy;a@FWbY|7tHs`#|2kJa8%dbwlmuky!f6P)QWnkI;p zkDzrJTvIuW3N;4L@*IcU4x@Bb#(sxB^U)dm6D!z~%OwgAv))ge|#m*{OnC`*BF_ z->JDE%o5R_zAzOxpmU2djhO>o3Nmqkn0V8Krf1n(31`=7r2b-nG7c+F7H@y1HONKW-KUt-@T=6 ziSyPyJfj5{!SdEUZiIQfuCW!&K04tOzw$*0&Cyn92xTw-!*i_TjfyLNa)vgaOWm1a zx+*Apm*!Y+hA4SWw%*D$Xw_~8ehP9=>=}Dji5JGCZ>G}YMaD*6Xtf>aCAgbwC)WED zd>gEsB3(e(mAvN3<)Yw9z&c)C z{I!zu<~fxiY;!K%xSGSmMegpJ+oU%fH4t-o2sIK+t^FVwq^^1}e>n4t$YPLum0$MP zI*d~{FPFhYR4Lva7Wh)9xSbuU<`PPB_7e(;A5rU69yiTYO&*?F^m)+1F{$3NOC?IR zx4{cchsw>ebs=-*_W|C{H>n67B$$QZHg5lY@}lO@hyN^T`UX>tK?E`saf2=Qihu25#ulrbE&8*vM#@D-{LN zt}mReW_OW*#APbvOBmDXPpA@I$TE&}M|`bHaDHN68ETU<tVeX z|7A_CO7>aPElEj;@3i?HTt0%jFk8lF^|nzW|B1y7hnSpff!3iv{-nig7Crf>gft1$ zIeZ~W3(mS8@EsuyE6Ao9JH1E#_HIY_k78F=TXFRD-)xpsuEcKPg4h;@?Ya+I+WU7< z2^5Q=)pcioINQFP9Y=8%ui!PeBK816D6fn;^-9H}c4NkriiMBNW^Ct1p8f$4hxECw zLhjHXKD3_h3#1=h(d@07x7~*93_H<8P`Y>}Ft0CU<+d5}tT1bJ<@rq6@F!o`R6FwU zp8Cef(_^5x6RV2;{`%fO6e9RV+xu|8N`vW}-Kr4(e0t?NU}SWm`ui#4<_Xdj8;SGx z@#UR90TQQfsTS41LYI;kyTPPlbN?Rmhn{DKB#Zo~TlxIC^IJG0bCg_)Y}-H8$36sT z9&64KB#zw&U-RFU+yCqvkVt-@eq#oB%?|}J0G(c-iTk$x+0D#lHcN1q&AzaWcp5e4 z_g@QfT74&*;zR5Bz=%=ks`Cs&)cRBc>j{yrXFg_H_XPD!?~O)+`<|`r@_yf%+ShrS z^CncBpz?6^PIF#I^!F0NjrPGWw(^{A0!2|*n2l&^`WiK8$+G)iAbb<)^6DMc199;5 zV-PCiq0D8tI|ze!(j}?7$=%S(knB|#wIcGB$@PqjK2!U=>q99P?$4S#IZivMw^oX8 zw8_n=Ddtug`&E~~(!uBHr^x}dH%xf?E#bi5q}lrHSJ%$vrzmD0l~-mf|Lf5oU7E6^ z*B`KsP47vyFAk@+DDet>Lp_x6lSPY*tvaZrJg$v!!$l;!n{feVU#+axnBZfG`M(Dk z&!Re94)xT1;%u}@36Mg~suZdH0ng*QySao-^u1~HpAzPQOZ5T7{0^5^;Zc<OBWtq^N>p(g)pFS$6%zF!0Uz<_HHgq+VEqlJnV zIObNNPiERw`$SHk)MwnjGoMUwj6LFV zd4}oo>Uo#U5sgzuN}`V4E)+|*v%-Sb@-=o*Ou zc(VEfp^jw;I){W;1kC+sQ7fP9w`&>!$42&t|AVX^V=3gX|z1`j94e=RmR|3fkp*MEnz z#LD%5%d$NG;~|1zn?Q=CnV`0|vR_i@i6X)h!f=pjaVpAiX7-Im|A0%{Tz(}WXy`PZ zH9YHZ{XX$Dr!Aw-UdA{umh7+E@P29V#(0$2#Pj1qe|$4LLGigK>Da{y5_-3~;CDp75;X+NlH?yhvv0}!W`Z3=g>=LP1_0J@3E_!2`3CnIG96fC3W+*;l0u2>WaY2!bTXRXU~p zT6!x&lQ6!2{Un;J%$O`YU`Xy#L$>6wf@dbEU?oYgt&cds1Z53C=^r9=+Pb%T&I#LO zl0k<7L5SvR(5Ij=%xQti3G5kCQlBfF!D*)!s)(hbK3*m^78C(yks*jUa3f_XDz#gf z_FZPU}~y_OL{nti1^}oiY85 zcLgv*10#l@k0GLy)XW3eU;WN9(6IHbQK#5UDR=HfdqQ2DCCjOkM1keE>0h}c7$ z=jZS5TU%QgV6chi{OnHOnM70a+6@mbZCDtTKO6oG*kPBH6H5x;FP?vBzZC2#tQk8% zt?V0UhYk?F^uJ3xiD(h@@%C;$=ekkpGWucqg_9Ho=E=z-oj*AU-rs}|K#VR`rA!eu ze-+k^j{6q|o7_+tAFx%fwIR8%z|5=^P?s+{cJT|HCSHUN9S(Urh+msjPv49SQw|U< zTWSB7289l~7hMN{Bx2wTqVxPP@OpWE`eCXrr^h7)wKu|{?e>{We2jkp3{pM8Vs=;UB;+{UZli(MCSIl%Lg)auP!4Y7)aeE$s zwi+SW#lNQaK(rcxSJ{eZNwMe*PA`Z?p`#*R5gJM-`JYa950jEs|$lk)P>(b0$qq*a)#%zHkmIc?9u z23{c(9-4SfA;q}RwWE7-(=SVgh12ICLz@QS610|Q47bQx;c#I)b8H|adN%|BXy@#{ zd~w&hrg*Ts`}o*gNs9A#q~$GkvW4HQ1>PDRp((v(0OzH3kZe_s7#sDZQc({Y!|%|Q z;QAljLMliI3(i}+~mddGP9c4U;`;Z^|kH>xQ%f7=SvGKm4myzfbh^O0s3@^ zG3t2{^AsEy$`J^uN!;X@r(OvG!$VvENsbXC@j$Usp>xPrn4 zW<*MdZ=DKYD3pDhPE{0&&X8Tj(zg`6{UXg#d^i8Qt~b>PV*``%JtWDmEq#)0F5a+V z(qqz!9KMlP%E!LkOp}w+`LHIcBd+_ucp#Aa#qp^$$`)_kSB*EFxaa4=I7sWCKTS*| z=Gv6642LaEN4^9JQ;68;)K+>lQNAoWyfwRck26Ary+Q;MeZCVRb!j3TlzEXh2P=t2 z%)}J`FqC|OaKf?S8{555^nN#Vfa6*^*@9WdC@qxXK_#}EQOhb}I&bANG0KG|w0H^0 zFlBNm@f-YAZ5?5feiZ@n9A7v@j=-%45!`Ut+ZuTiMmm7Q+bko2l0xY*kA__-W~&JW zJpB_lM_bMDt<6Q@^<4h>QWAQPAT%PcY2aW}wU`$mW=B0Aj(91+n4%GH9X3j#*Ov*1 zRO3qlgg^Erh7i#ck{i}`UAJcZ6~!pF%N1li-FUtdWi}F(Fgw~Kz|Km@o)6{L+=b)i z6ipuE5O*AU7UaJInf=WiAB0YTiIv{Z4F%=e@!mx6^R$Ubn)5aHO}lWet+~a6m=X$z zOh6BVVC?I(e1V8ILfMH&gBoMm7uI29LNJm8qC>(MP)5d;1pNunlip-p*71`rQx+1G zSOnIg&JJ;-!^mG0zw65i{jm>DbI&rOvDF*iIaq4Uh%Fr2*G zmHj={Sr?>_Gmiqq9Spv#Skf10G90iCbK5Aq>MroQn!ADQ>4>$6aJzQ9+&vto%j{m~sxtz!9VgRtYg$~k zpWGk(=^-)0#jgP)j%Y4iDRj^II1~wyK`s#DU@y1cqV|U%vGl;6{98qAiS^^&y36t%I4%W4-4R77(gfRQJ3*9xLlkTnii15)h6n6g{ z8CnWHZ>P;AfOxA0Il2rPmP3-yh4o00kt2M<-u=_&(akpmVhWL)zO%U_nYwtTK`~dT z{rXDtpu_JRC#z|%9SrX$-vWlm;`_kB5D}V4;^8Vrwe^i(F5l-wd2yGoZMfA_aQE?9 zFGvAOcSAJ{L@Qy2C-TM=M@iD>Rg;Rxh4K{06qe<3kp$2~dI?#F-wu(9WWOmgU8E|| zVW|wy{b);9IzO|@i*r$t5qB68*E=U#Z(l{5{LJ?@t)1`k=4+K_e7*Pd{#>s!Oe5-@ z(nsZA@ErVcVB7_>Fa$3X;j9GGw8-8NL@~MM<`$|lHtHGwNu;&;6q~p*X8ccK0%4v& z%oRx>J;6P}AO}Jw^Q2448ZTm!?%+u8DRx%Dhh=C@D@TZ#W%CmQWuIVK)Z@!Tbv7A% zapf0>g^2S90^}IqAtIpCqntP;nV`(i(LFTkh^Q>y>M;3E!419NYB*l&H(zX?n$QiJ zPyNy#uZ`KIFpL1Y*6An zz5L`=gEJpL)n{MQqS2^9175V(tW;Jeb5`~XCXbWd<(cV4cKOLO>?kFJ8?>?Jl$fq< zJv{Ra+Sw4b#D;#}#!m60G|s5eQHa$PGH`>3uSNb<`#vfFm&*(;N=%J*zx=40_D zkL5^It_heljo;L?Qcuojk=aZvhrnapE*nsKGar2G@v~!bJKT!@$;F$imTh?k=%D@v zEj}I#Ae|kpYsjeEvEXbBN|qln-u_yVXRr+lwx&Z*BN4WI^t)|wp3dW(vF?-4i`!gU zmOpvqF)gWv6C6ZDa|{v9pgcv&3KD9nYRy zM%#!5-O8~eTR^j?@`s8|IxOd)T>~7Pf#10+esd6eRUIOmO@Zo0(!|x8G@6@v1*-NQ zT(~lupEBx)Sd{HDaPY%}N%s<`)sdge3_9q7<*o}6gXLOVv7Xf?vs5nH$h7aZlC(w1 z(*lPG3^&chS>T`@-C5yK10am*)lg1MxV54DhU^f&_o-zw2uGTOuQI_q?f^GA|BIoW ztZ@;;`Sm%f8XI1s_ZB<19MM2u5zQIF5_PP9w7}Mtxih;+&|-WZ0jAd=JY-tYT!s>p zW6?&J^g?CLVj=wKkTa|DQ(sh*)aAzm0}kZQ^PN-yBGZp(wo^6a3qZQm6t5^T)a!S? zwm;_Og!2ho^^mZvGlW&XCH(&06~!+-b3cmRQdiL6S1mmoO{tTlHBwWUkz+Y=;L^`> zqQ0!E)fWTKF#E~7+m1qXMCtrlE}h^KI+L{W3q$U@#SmZy=M4CgEr?=K8;W06%GuP` z5T7}xE^R8!ETyr>lFifl?;Hti#I_s7s!4vQu?R@$e}a<2xQbR5yTXTtM^$`w(74cY zjYJgRL+6Pu$r5m0$!RL6Ec;G+aJt|KgUD3uc6r*AZ^YE}uMTV$MJ~vT zJ^lzeWSaqelYPK9Iq51-3cmTG6RsDRLmVY6(ecY#Eu{_P!rJFLal0^OQ!zWDyam*8 z=S^0z41y9-E7QbcY1SZNzZkf7N0*T7mURO2NR-#LN#eNHlI0w#Uv~R>VWVO`e!JC{gZRE`;XO>MQzB%K_I^g<* zYJ{6#06s@AaF6-2z~mA6*xE8pdJK+RurP?vpN%4cpu}i?|Men6N^%@UMax296)|?S zBl2HEUkx^I6hpmCBWNw3k`l|13Uz_`%noYd&Wk2T-RcQt;mfU_c*#_MtFen+M0yrT z4=oI)a6MGfDRX|{lr%FhneknTT|{a4(MV~-7d(!vZHlafp%D&1P6(!oG2m7Ej?4zQ z*U9Jjn|9o|iht#N)N4`a8JA^!e1hja)v%qKRbIH29o; zyHYd&LOMVSO~FW zqYdAP1$@Bhh*2LjJk6z=?;HkXeEP*xan-Cl_AWP<0 zb?xtpxvuRcEC_696Y!nDhE>Z|P94EV!lBe+N4@T53?gJY`ng<&mF`ugD;p@_!Jbu5 zfpH8&vd(Esrz6nPtqp^Q_XiV^20$srnfzGBilew%mQDe2IJb*!y2nEZ$vy1$dggBKyGHj%g}#RJbe){1`qJ zb{8t+%jL-r>(py3(X@Qwa2@KTl;@;O<83V|$XIHYzq?Z6ZVx8Us0`a7eG)@E;jsK; zhhPS;N?U*I_}14eu6oM2$VIs%`LTahSEl+N3EgFjiNzAeN#)Yb02wgJx{Rm?Bj0GK z!JOS=C&L}O6^~LphAIz*o~2Z;_|AZZ1tZ9!0aQ-Z^Uw2RxnxMY9bh!e>~rr8=%e00 z?Uts!E%{RU@MKAopCa_SIs}q$>-Aqj#4KgOMhk%$>pz*E_vFls6eHU;Ku$@mgPtF! z0JHbTsrZwXkYS2w0%5>J!b5PRG{zYTB%uXz`-F_%m;kLIhCs!jK?ZfSn^L4GHaNfK z>&wI%*2VSQ3=yjmEd-fV(cL0ZC7;D*^O3Zpq-g zNCQUkF_<~N9`Q^gIVmsIri%e9=_QmNMb(zGZYwD((@oZV0SWU@qWA>nV$+-W&6YYb zjU$W)bTJ4}P)nOFl*N#ZhAkFE1Na&h(ak77nn>Kw%w3X>b6vx`zXXCnSTV}eVppkQ zg9X*S2A7*G#b%2aYy?eG&t zGR5umlrw@809;j;2YEMn8Z_3eT$IVBdH(OYbXLDis0VE5Q0vI|8uP79>)XOz!_C`Z zrh}*O2U&Xfv9Vlh$MR$FIy3lsfMdb^)&N~T_7#kOzEkLUq{BB1TLQT7qZD5U0=ba9 zXoSIBr`}`K=MHO2_Mt(CX={M9*yA^>U{k(hvgDlNq0|^S%aDukV4y*Ak_;!S;Xq5_7Pz{g?X``+pK_+5cODE$F`l zTQIr$e>$Z*LsN`m7&FMMs0{}jCQf3>Btb$LS0&C%O+>;@BDC`3riFBa5ar< zDr5p4$(m@p94jq}fcEvQNpEL?cCbFE0}2POvT(#Gj1@h4F(}R0JU5TY~Y@ z+M^F5j3Oc;$^g^C#>b;j`gq+0iK4fsSOWc#Vf0^V5{9kTmuodD=FiToiT+GXM2|OG zv)B?Ygx>tHjvnn`0T+FB11+d8PMV!Cf<(VRZ!2fPgpFuH(2tucEdW^F zoeK&y{D$uj5h`v3e;HYCb)(oDO! zGQiNE9)strYd4RtJ<8mOh@!r^;{LLQ>eXE7mCkLmU~lEOcd(GXx3?$JHOtLR_2AOP zCB!&K)nS}oQTa9g^C&0G(oc^bjIaT$QYTI+L}69f+}X1`W~OSmfUUc`@o}&pg*kg` zTN}|vlugLnz9#4K5=*7eQ2(?_$?zW-Lw*DKVx^de9fRt0q06Q5U)&73`FP5)I)q`&=;6dvsBBWOTP0lIGj+*i zk*jf_(edA%o?l;I{jcbE`2L)X-r74Y(b2r3))~yPhwq&8YKQ#eN`Y>S4k7swuyfG+c*RSCmR@Mw{ky@CuvUNGs0@AJeDwxSI(`^O z*6aY{NEFQh09OD3E3OQHx-1rapBc;+>Jm~4uKYrOsQnown?b)vn+0+JR;3qS#@xX{ zy_72#Ae;lgI|T~#M@JNi(d&Buyi+aY)4r>^gIcq(8}ZQ$enWN=D4ntVVWH^XRwD3Z9KHYmZNVfqMRcsDD&ozdYC-!|Xp zV@+zRT82uA|wXCLu)1zdal{Mjy4~wRzn!QKEO}mY}`XPCmv3PBj+a zKGH6gPwW{tM^;FrVikA~5<}CedKUF%sJ$9|NTIFxG05u>hJu8F(l&V6IQhw!>0CZ%#d&<^Ua4N0 zs1y?uPafkn`e?l*b+q9#XxIpDH?Tiq%QTU2N(*Bvont(iP^#Lbzy0KzARV0Xp?}U& z$sB#s&GpjJkxZ$RHskeX8sA7!0z7&3Y-`KyXZCMweqlv13}>SmS39a-kgu5Y?7|uS zeWCGV^A@a|2=53n6w!VBddy}*LQ0KUF=FIYfP@I}ULL6B!ybrDpual`ntgv4()@c45#*PnpbJir2UA$r0%u$)SU4D;%pt%S&V z-l3DyXUdWb)37UUltnPcmvy;iU&+@l7T;lnp@KaO%^Cs36R`UWB2tV-%Hfu$-qr{D zZ5-S+KcKgd9@#CPIhPhLH8xcyf1V9CfCY`!ovpnY|6V4ECe!Pj{E4CVNH@51fk2f{ zgi_${4Hr!r8pjQU1$NgUK?O4Z{@&QwIA*GfsIuR`xCkPgUr03_6>w#pjKnSe0J^Lb zL}%-Y;}5e8KqVf0BJ*hi9yJm*+|+$x$;OEWf!aw;<4BOzBZ451z52|>ujaccnB=C2 z8O4~1BuO*k&C+J~=Q4|s4Y)NE>AC;LRKeqQIOn^2yGM>_(33_4`g>Os8KOh;0$?yy z9~n#Q8l%aBoV`T^P*;knlVNtb`v%;&QW@u;o6sgVe9DHEbec6iy(vc2x@Ifls60}+ zLj$1%{~Gl43_~CziXgB<;dCaJHZVWpTQkPMl64!=IH%)=FgvTBBh$`)8zWG_uazgG z^`9w8mJ7=76KAYdlKAC(OioM~T;vz7i}p7D(~a2G%sZZ!)v@>}sz5Gkbb4nrh9|OS z6_vSl{CLS;Fo731oHhDe4E<09RfaZ6JYLfMRSxBCErS8GBi@hFm+Ke3x(Aqro5eEP zDI}y|1OMjSp*><2&%*z@Dr(3%d|V&=BiG;%F!~Gg0&r`)mtQzBnTJeIz)1|57cwAg z2J%kdBQPL6uVP-Ft25-pL4t4hP&Chr8xv+nee3wN|0{!kPOz|4HRRYyMWQDcJW!`h9DN_6J zRv9gP&|@1VULAt#I-E)~pct_GF#a&b$QK!0(d@1QY>Hrq_AN!GW`mL1#h8A~5KZhP zmAeF4IK_`+K#sn*ceY{`-$4ts5bC$ZyE2&Xq$4kz2Y_EhGj2H`+*O%ochd1%;ZOIs z?eo~!s;pUfF>LW>6}Ti37>!JA>n4IS-Fa)?OBgJk$mcgTUk8emJUy<$<1{YAw|<`3 z;4>n{s}h~94{WBZ38^I-P>TgZA}`dH&;Ov=USb)Qu}@=6CAw`^JH_mPD4B;Qrdo9K z{R92G-N4nO{k^-h+2F{klP+0;sBn>7_P4N`%X3O5O!ycei7jWrmYnfsDH<&&59zzU&Snnv2f7mb5oBkifaD&EVVRt+{52Xcsof4@eijH+XVG zi9Dk9iR5Z=T#l;`q3?71xZkjE6u^?4=NIGvy-Xd?hE>}9ejhFgnv%GGy0O!K6N;2G7T z+uUVK(LcZ@6*ccWF1o~5iP7KL8+yetV5+S19yiI|kEH6tDu}Mqk(9nRGP&MzsSWX5 zJ<9pMmP*L3(h)ZJ9BFZOjrzysM*DB(p_JV+Oazh& z4zMQtQ#H{Ci2X5&2G}f*qoWLsiY4m^oQgGf5K-_W4BjV-thX*yH?nZiV<{xWkTdWi zO?|a3ujy3vPdiAmdgpensu#VTMwj?jnaUklb@R~f6;5XcQZ?z--23rEs^nqniEj8i zL#w4J5!_IZUMH8E=FaXZKuOZcFRBx3^Gq$zHwurH3Fv@-WAABwTN?wLYi z_6rHw-wSjDjTVOiV$_toDMm%S6BWX#JPOwZ9PK{y7J4@;AMZ)1W!#4v=E(zZyQqbW zqojzbCVBmu!{}m$I_ZWf*~ak$>6{-j`D~lA$W+POQ)?hC+<;NyJ7|0vJ zZ>!psJI@CR2d9%k~= ztOKhT7|mtv!MzS@4}!MQ2(HrAkf$OS$<5whgU=mm?-3l|k2Y2!qB}Ck_)~@Eq_|q^ zBC18Z-{?j18Q!iv!cKFRU6X@r>{BxAXDSv(K}j5H9Oq0+BKF>ElfS)-Tv7W+g5PO@ z(0pi9Tq=+-glPIJ`Fp^mNHMf#ce}pW?{K^*syqCWPn?MpHfL%$Tl34Bz z;96EOz#X11F1?9#>MGc}n)o7(4 z-d!uq-SkW#aNnP1Drdr{+fGt6B(5ZpW>Ykn<{dJl6S=9vW|EK*GnN|VevvgtXPpcZ z|ESKsMkL;wx;#G-Q{BW{}BAe$pb$41<0)GW@iFq)=)CEFfnohGJpMP z==ARq8EXSG@QH6fjKOYl{~yND|Gbu~ zsSL{J97OzTFbYSvL)frg15RM+POn~kUri$TXZLMzKTaPQ3fh$ zq7!K7wy)2(c_D?q^CI^Zmfv)L`3BzkMr@~J7&&V!%kWy*IFH#{P5zxP7fDWrX#MJH z&?umNKKWAkSv0nrjtT)mRFY`Z#CKx+ou40~W(x`(ssU4ePM(X&SpZ_f!v=;qFKuer zcgks0Nmksh>rNY07XoM~%yklcCUHV&f?rkQKUfBp$a$X+<-!$uQx=3S4Ieg|kOv_w zbcDNFr=akjD1xzE)~`$z_ESkp18ffsR6AVltb>^w9M1aB!w! zBG^FbLNSznMk}#KO1^U;)Y*kV?Sli9crQlK=jJ$>n&%#8FU%3~$47uKxCGm2wnfn6 zBU;i#Q4u=F?q(pad3Fe8$DCl0YmA|T=DI1wv7^yTpy7HAGMeS7qeOdkf#f0x@S@Fr zu>0~9)Om%}_3?gt=n2WC*=VUU?Zg0KE6KEds5?g?ei_71N@MvSm~A);m4>|scL)$- z8<)#r_>UT6p*`1i&#oSwYmnV(;k(S7b+TBnJf7lq+Y-X>fK`yfEa=kI!;tE2+jpJ_ z%u{+Pgj~20nEa{39J+v0L?291jrf(}MJ2xI2PW+&Eq9+*LkiGO(3xo@)bAxZEA#qY z>*jm*czjtZ2=weJ3#vYUfjfD$9Nb0U|aCVN-|U887~S+KpeyfUs6xR%pDvOsXDG3p<82> zof7d>$y5|>Ug(ctElEGK3_=q3_Bh#-v?_7pFw(J~)}vF{VW`Co=)||BjgeD|qbt z-zjpe|38=s=zQ~7S;T0lWKt|gh|=y)hwuh@?N_@H$#WfJ~kY2C>m?t2yc(>VeD zmw@%Ye|HMAPjwgIRbrDF$`YpYeMjp9E9ouF?(zOSuPdJw{n42qG&6H8%F^s$g^ME( zQug%p{OpX3n3(uFNa*z93<`BlB_L;UMTnnw+FY?vE}w^ocXdOJ3?F8o=c-iEmOX92 zgq7fycYL~sv|BmJ3>`a!mUpLR{K&!M(V>l)vrfdrv!*SdDarG#(Zeo}ZD|c`{)HPu zi+SbBNO;{=A$d04*&2FvcQUaaH*fqP5x*o_s$HczviF5N0pL~vH@;O>c8XQMC^Y@O zV_Lpt`uzU6*?mpDG8M69Y&l;*Ei8~KkA+w4NY(?C21YCHfyqq|83Tcn?#>lVao}sZ zln6ZZBUWy0AMgJYhzb6<;c~f&zjNQPUm0@1si@f%HABbJ-P`QLK}yQOMNAW3zNz3T zy9KH~{;|wlHQ&piS)*{Pp!T{zM|;QHg^1_uKQ+ z&fSse{3mf8`W;w`pCA33fP?R|C&dfklOOMIC&k_VZn-pFv4&J%%qML+yWU>kUW7iL z-fmFZ^`m~3&`aSXB`|26PS|#Jy+L6^Mf_kObH-N<8Q3aa!eV~Fb(s{RV${v9q8-;B zs*>tbo)(7E&CzwmN_xN6)xUaqm|Pevx2MFaS6TR?R^ZSfJr|6J#yl3W(dFIFuN{5- zqw6k`w>kZIVErnMBepb#iA)!rvIa@t-iM{4$P;&MI%}kC9$_J3_->~>G)_+_>mub% zw%2HW=2sb^?oeF1t&(jPdMP$#*Lvs1XZOO?6{oT?M8$bG3x`433yQm!&vS|mYIZDz z4w3B76cbaTrSxfy*h)l}(0wsE zVT}DrA-Txw!@r>t={l)~M`^x!?poT`%}!DC_;ml~ysl;tDJ@rdyeVq2nK}mgt+e9S zpm5sW?yF-=SU(g;*jzJVr7Uk+_Io1c%%70EB7v~EtRlf>6Myl*rB)|&UNgG9%5Qf4 zTYZF!bMF7c+gnA&(M3^%xVyVH?%sIg5*l|4?(QBmxVyV1xVyVsaDoOWNU#uK`Wv6M z{(1NxW>&xST3z?_xm9&;ow{eAy@xCr6vDmoJAYa1u&=Y{=&`yrtf;G89GQ+>CYbiO zZ+b2zO?ib#@n~&~VqCHRt3EgBB#|{CY>zEyK*eX{07T2n(bA|@8ySAP$&0eqOp&)9 zgE!o?HSLcyV%UnXBM{VVv54Ll|1=KWzw1M!a2KQ^dL@a+rieXLRpJo?BX)sT%D!Bk z^9aGOU{ml97=G0#S*^K0h8~BO*VGbq3YPoP&@})ptPHCy^GUu;5vN#MYkD_xI$|;+ zY=y~jz&C!FhZ%t5p1TUbE`iU(oiF-Bc%c`r94$`+RM1*PF$7koPQhbDmxXB-O#j8t zi1I@LiceNG`%DV19m6yu;ny-M%VMl*2xSu>IJlnY&PD6NAy${zRR0=@vz1W!jlVXh zFmGhCyurfIQ=@-~#ioqr1;-q3>2~t(_RfdTHX2+xWn=0khw4biRG*Lg<{x}TA?{tA zp%-pj+>Xdu8w)yajFZ!3C)9rcR=S{;$e^Ou;F08XeUZfu&MTIto8wEQfxzb zO48kHO271%j&@nQo;dtkc{plbVS_mX>$?=O`<>?5{q=+b)5r;36X3qI#8EE!?SZsb zf5Ef>SBS_5l^kiMqX@iXgZS_p7WE)Xep+Z%S<*4&Xcre)gE-cbrATjC@@%SmPc%M~ zsIbg$@{&O?h6`q@U|cp$p4!+P%LlrtosIrQNjg+Ee&yN?@<~29-75ugG%V^RL^hlG z>Xd?rLi=GLS6X?E=&nIjqkBN)GQeV~p%fqsh z{>DvGfqQKHH&tTdCU5Cg8jazADe)HEdG{ritFGg+pEV@<-|&;ouiQxmF)8n0 zw|t*PD{dWiTc3!KDX1~kJpsz>qg9-(V)V3{MC>8U>KhCIYpt1yr;t$iW2LJ_Hyrf- z$c732(lE`lo6xuelffkE@ycaMjifR}X{aOhKG2?P$GSE-m*^oi58xuG=e@rxKxQzI z>#Df~M2>kguO+TWtQlhMa2aB)vTT&J%TAJFi%32Q z(4aK7RnKL*Dvs0E#f5yI`H2g^=+Gz3*n83wj$9!YXV#4i`$SLu_95{qL0Vb)C_{8IGar<#3|Q1AuKK)&?=`Q^a_qi~Zi zVb?~=YIz5Uor;MXp)dx{VY8&OtBCG1X9t&Q+Il_-_aw_q+3;R^G2&vDj4p05Ppww= zflAaDNQ3)l%d=*x^R+XQ8?MX}#qEAH8~V;|*%iFWJM40^FgXzU@i5n#3yyOC ztVfs3h8C@hubi?`pi%E2uY$Ajt9Hq#`IIcwC)I`Ux>s0Car1OiJLuOq&oB;H3YRDd<2zwr!JmF~wMl+e&+ zUSb#3aKBLRxCMnJSfqyBz{!$-hQo8A4P+h%oLjB*SUxzG3^Uoh?)?a&jA2cL-0?+WTf`ZH3r`hkkL8LEyJk@I=m%h5>(J{()3?hDPdxsg}wc2uHKZCkPa&!2wL5Q zpfvROMy5F(198I7efaa%Alg!`75+R*abl^4DL$Xq>@3uv1QNXlGKwPBu^+qybf8VV zwkiH)4k>hK#P0GH{8%H}W<^P{iF%Tll9w|;N;|~Vfd_O`_H=mV7B|WJ9kOI$00NI{ zG#gaAZ6{gySp81ltOV^cm$Q@}NRCm$6+(jG1AQbXVf5iqe%$A_{I0-;>wVq#<8ny9 ziI)Sp%FpXEHaRwF6n%CL0#Sx-;0HE4X*HBJ2~zULP8MC{>FiF0!^o?ii9tGD>p*#b zLK^Y>bMf&emNFTX%->|Gv0VxZ7au=2sxAb~RS+u|+ck;p8o)QDO<9RuduMsJbg2RG zLhl`G%z}Q8x))GV>K4fK`S#UTJOB z&5*~s(nXtOX2hI@S7H(`liVAlE9TO+_SG)Jf}QZmb8{Lfw_dJFH@R?*2$GgL3znsug!^*gy>r#Of;{>DCR`D zrqH!CKI^t!`)h*PhiF)^xXBKl7``%cPQD#dy{Fam)td`|iU?O7R^vJ-N^Cbo5&5rAOr3f<< zo`rQ(F9IY<1iu7(M>XFgxfno5X_2#1k5J3~XP?uYb?2v6hSr2Une7B)K(c1>4{BeN zzk4N}ZYa$70)(l?LQQOk! z5dnwt)VYI8Qws9y$sA`^nB>i+`@_&^s4bdy->nau0Lg9*>yi1aA zB=W3zkzQ~d4X*p%Ix7rtxCWtRD9DEJjZSaXxYf(M4wq3ai;Qd5RJG2ECr4GFwm!P} zxw?M<$|IFx3QzGa@$&V>Br2kV$^n5c<0HI&9wjoxE{G-7lC85DOea<0aJ^jz5eKl! zA%KTc50)w3XdEAHPu%E$)(9t0a6F74b9p2n@kA~LGbuD>rA#Bmwh7qqb8J)58fdM| ziGxRBftM@aV7>d3l|gg_F?lGsw!%!YT{`-0*j#ex+SD@`HG_i2|FBCoX(VH}Zi8^GcH_PO4f=<#{scef4b138l-3%^xfq16j(-&ZYsbT}L z!{GxJ$06GRk4Cgjn}RevDVS3)sc2tU=yP2d4v%W+=q*Pc$Omn6Rg#&8c(iRwiXLv1 zLF7Q%--;6!=`$llw-7>u?xGlktOz2r&jl6gRv-EalDF7LX!7ng4KX%!Z;tWpB4C_i z%UNUq(4nAH8MSkF2Ez>xFctqrOLLK036@?68v6e-yR$g*;%aTFHV=1;Rz`=w(c zwqHdWlraWKx*Tj52^Y&YHls)Q$A`kf#^E4H00)>QkaVT#Ki3V?W?@_4z(i?fCo$d1 zx{qJc{T)HT;q~LhDcoQLU`3&VLNq0OT|Ll@I58k30OR3|+UN4|lVnRKRN9;CMd22> zPXd|uuKikU4JyI7g~Z6jP=8rM8YCq`_cal}0NXc-BXzkops0o37Cq*ykYxj);H()P zV7~ftK@=v_MbuZ!KLX?(c11q2u}#oG@CPu(RO>EQ!K@A#nd6jkP>})En>Jxs4N>-r z=qX>1GH__M4}5%sLcy$+!%n4npJe|zZCOj1-S5(2G!P-d4DIbXh*1syT~ zMRiIP;m*^rMKwE@PG6_#d1qm8@iaWvDiup*m zM;9C9=e5KyA0|-jNqa}qut-F(rIP^|>_8)mdU2uz9JC1a*4^_zU(Jc&kPr8f@n5gZ zsV3Mr=$w+sAcQq&xk!Fw1cw`Ell#^OBbgj=aI@GQPa503+Lgk>%NOXfp~0LkoJb*9 z#YqsJ$78$RjWcxFRALB;gAW7}9hVerl1Zhw60-s4FcgFVSZEX1iHY%MGAUXj1=I8F z^p4uKa=|#Yubp7R4JX@(Bu^pXkvJkFJOeIZl#xx7q*UXRT&bGNYTL@7bvvF8-057kF?_%J>V4Vefx`xOwgl&q%wTt05#87G~tXPJW0V+s$JWH!AgnFBp zDh6H?nurQ@pdosA93-+UL8_6B105x`4(G@%j*Ighs|QQd+0_r$wChEhJ6o|58q}xC zn$DtSvTzO+zHc+c2*L~AzZG7Vc!s?4%?!&M0gXL9T?C9+r0ev8oMIy(A~22A!C8q4 zq!DO_lB$yKe>NNrVmnUZ|2zxj&_-D+}iZ5mRUnCSUT;oP??qcSl2+0f9~7#pf+a7XkA z3Sz<}nQB;$Qyv(MMOLT+>9@kcYE@5Yl^85eXSyX$HtB|Jf^FSCIQ?^aC((BK2)@9E zf`Sf(x|Z*iK#-srMj$;kb&Nrqi_=j@fNso-A4Ec+x%5soQg=!EbQz#b1wvQEjvvGx zle5VLc2aQ+M7$zGp+RGZWKn%OAV)z9i-Ub&QXk_}H{brv`^`jJ1TD28#YmFWkY0=p zCvG%k>@)^%OC!KH9Y$T%Bw_$1%+qtg{k0_?Cx}p-1WV$U-bH%=q9RncsZj^+%Mh&c0D5fn7pU+JsCGE4 zLL*WdnIF1o{;|Smha;qLx^HT-Q9U6_DW+6p6xYslWP4bxZq%rja6RnZmRrHPwj<=P zM6vjA-;si$@Zd<{$oEpGUmQdLWXvv6K7dnqVaF4C?rE@WKu)sMuK~F)<(mp5)U3O< z(gPsgfmWFPhX|QlC@sTgR@pEo(g4O^OITljN`-Ttw~}Ph-D!{j+hC&jIQH@{37fnX zp(coWdbyDr5Q?DG4B7WFN+s%-Yji#>!0+#QCTpF0R_2%|%(KBtjt!m05D5Q~kjZHU zYAGPQ$cFA66Z=tNT|=1N>)AO7?yG}~)!@mwCv^ex0S%Hw4T>~yzU4#`?Gf0LTxHnt zi^O9Ba<^6ji!G;*g^NNV1Bb9tQ1n`xEP@%M(1WQd(BbzmaWI;su&5cu+EI}P zQP1-w0z5ntQdOAuIs&)Fp*lLPkTOOfPsHC|`td>&N%IxZQoz0Y4l@2bMDphW<<9bO ztd=79pYM~zeOJbI=+;?^uBJi;2k(P0p(eo7C!s5PP*pH0OhnPo3oA%GKZh+u44ASY zQ=3chbYoCvjTpdp>8{7g4)2>R{C?`nSMG*KvP*ZX&YHJenv`b6!T2kIfD^HSL==T_ ziMf>sJ1Egj7O*|~Ygk2ps%5l#&2AOtx?l5uZ3h-gj~Xx8#|qi=5^~UnpaK>OZ3hv) zLW@nxcFqPQ*+`7KTT^mCh&7}d;WGTsJebp!_TJ4Gk+6`S1C25Nm{?=QfkJp)1Ed{% z5Ql#dAEN}vi$kFXBx^^?{n!x`HxescyBK`y&chIvaB<@2LeL+C4+)(?s0gERp^~S< z38*H*yg3YCQOq253v%MmRg$HGA~|iTGzl$&aSc%`TG1px3nfQG5UrZAmKHKJfx7-I zg_J~sff)=P24$^VT13Q;MD)XCVR`i5e~!MCSPaEQN4G zzW;x$@s)4wP1A|_w=RfRdn+HxiFry2 zHEJ?;GZf2XQ9J+j>+j)6Ve_!N7^!iL03%)CF8}Hmt1_P9M;!e9dw!0U5X_Xu+^S!? zsLo6hFAKrqBIPYOp=B$UE|bPVAl*u(1A*}fz1rZta0e3}h*S=z!4*bjthTF=13{|s zH+4|1(-nfOMwO@Rx8;j&bcElhX(oG*V}}hyL~Z1otF4OmEuGF%$+{xR@=J`-BZtFp z`SX@sHfd`H-?(I#4R+d-eIUZ^8B@H9)w&ZE6vJYbdX<~LTgS((>gFEL*QuRuhn=fI z#cG?iR<(cdFnt{n9_F_8s8!Eq>h{drHvKLhUSUbffBx>{|CC+z({zck9TO(Z>fvij z`N^D#NcNmf+L^`5m)aA`F!pAGy!d;5A2BVzt=Yheze|NP1k?EOO@=dLz1mE~ZU!yP z)H$0b_cDd&`TGtpox2N+7xSZKALDh zZvc*gFI!0t1h?hjp~_d&zUDaaF%cxG%RTaK*r~Hpl_y-HS3eqn!L|NCPAPP|cjzP>k>)kSJVvTc_bq8K)t*^snVP)_?H zp(}B4G7HJodo-6!=S_8?Mtr5YTh|6X8ubI4EWuLxu3AdUI>!>ad$w-qNe-wT@b~BJWhiB)|^7oT7Ct3W<9khgqdz6CUEP}VOaEQWfaTo}d$F zkwSF4LCW+o8qQum5b*!A*iibZ6l=kpRzY_uv8_6GGj{3hc&}G&Qi#itOhm^#YC_8iyLL*0EkxL7`1sb(x#Qq|XIJK6L-93Vnk2fkR%dzNpf@SzD@;&fB4pV4 zLr1<>tXd@j$<;xq^e4$b-*#=o*D52WMSTJnqjH!+rAce1TqI}# zG735!&Dz7VXsDA!{5W>CnpY^nB&^qa=6xFx1o-Z4&OTxg;W&1$3trL|yN9~EG8IKS z>5x>ao7&1oO8J1l_|jFsQAWb;3K0B9oRy9L!25eW0$^?4RO8=Ggc=^H#av{o} zTNtE#LeW(#Z-;E0-A$V?Z?6Jk!^798ma=+|2+o8krLROZaj}*MM z@VTgs{#EGZ&)~HI53QArDoEoyTk{3Gn%$F(tWTFsTr)fc>bx24Kj_W+z$b_ z&f$b5$ZZVo7KE)o4ye|A!L#KN?5n`L#%G&E2la7_K&{yGk z(joNh49P`jj(tb~)AihZfQ`}}v|T=;2jz^W4=|8ZI2txSHI>s8kOlL<9~wOgF`1Xw zqoVV41VDlKhgThY?JgDH8~-Dr<pNUrdc@$-8uR z&E{n;X?_GC-rtx&(X@d~1AntGPda=o{-#*-I3hWiSsWk7)z?a|cLoWPH z>+z^ywxraCPtkz_NQ>41eC1y z6j6rF8#owD>!}s=^ z;xkiAH(>B{RF#!a?$4l9!kTDBgoOpO=NXa$pd#;r*J$Q8OyumHMRHB0!mta#1YDzE z$L5v$FzA;P-%-mPKsU0ZJ-@CAx_^%2TG$u}Zjc7Xx$4FLbU?MPjvH6Pz~Duna%zjH z1=hbUA}#C@5p6c7{0pD*@@m>4mAppOwAsG2DBd7PYbbVgYkGg&{mp&yx5!rYv7;1; z%zMRuJfbZ<^;o-d&6mEC+O&~`XDD^_TJo^<6~V?ZgY2EF*!TF@qV7kKzas%|#{!XH zc6E#KXOgOgEEoP*hCF7z%_~{x)K#D$aomahe60{S@8ixfHH19V-j`o5jS7r$d=fk{ zDc_~(ta*P+btbYr%&x@vWS#~wGwY4WBFn4>Zecq;$m|Hy_0}fDnd|u8yWsbMJ zSNU4sYpR2EwDfK_lN1d({cmpZsZ^bJwb%G~`Py5~SC_U|R1J(C#*+L3&Mr5~@PkjF zt2W1eBwQD0)+FlGv{!!XEie9cMN0H}sjzX}0Y0W43V;IQYkfjPO9U$^D}%vc<+wzQ z2hVoC6-})k?vfaee9_bvn6#>?oUzB1iKEMZX8hefJ$Xj@GiBq5-3Avwv*qb(vqc}* zAzt3r95@=;|CaYNwKTW4CS03){H5>ZWLDH%-G!rY-YD)kzkxEM6I`LQvn~j1?dbFO zar5#D3JUV_Yw7P45nftWH?Wi*C7coCXoTVI-TYOs*txosI-R@K{q+0ywG+F_(;6YY zdab7xeuWwx!9qbo?LcfMXK!2IWO?o3ba!N8p-W&uN4L_mWq+1@`p|>E@DO zJAka6;H@1dFPG(Xf+Ktb4L&TqUjJlN$VLCXy;^>a?cM$Z@_#efTJ!gKxtx4PQ7x$< z?fz=5^Te_H<*uS~FraBZ)Hk5_@*amJ*ytdprt8Pb^UyC>6F;2N1c6`UeymxUy5jyq zeK0{P9Qp341v$GXuhU^#BUQ3vjMHkjTFvvZ^-$`XT8^JM+ypPc)_&rBK|R7-Mg`~X zL|OsIm)Rru3wWzsz}}uP!)pdnFU0X&o6^f8iG!MrFd3bJ!Z?!L&*Es)j9!Rlen#;> zWbuuJ{b_9B%VO=$$rLq88eqfv@*e0JM4fQIo$19X>I?a^+QJh}|6FZ;R3E(Ept`fp z#TilRwT3xZ^mH{n{BZlDB>(5kXZF|cM<`U%i}&j0*{xxy1wu(|y@ld^W{6glmYSJ6 zt*UP5SEw{B!B`Q)18kzSJe@llWN~*!E8g-e$QW=>t&;@>$9EGs8I7Gl36GG!;i6s?pG*o8D5!NJ-T$jh)H=qCR%HIDVMQ$gSe!3@~&e}^jI-7XTdFQ&Yq?1E8bijLxWjvh0Ae-`WO z7uhzF~GsU{Q29$4`GqkhBoh!r!tf^b&I#}}fyMku~P2YRLE9j10;p(5%6 z+-?1;y36N+u;ZXL+~7}r@U>PSYK>qI-8*ZC?{g7tr)WV&6i$}Q!=mizxhLs{%Wm&5 zt~~4Rk`US*ij^ElfjpwRFu3B*!+f>2i)ycMK zzCO7BFbn%fLpF^I$ib}}Sx+r|Y$x^VA)$w@9uJALtd1Sj94IS@j4NIkpjH9xd!54U z<8&U*a^r3kydXkzgZVu;nluYHrYSn9x4krPZ(p>cvA>(;0u8jRd3Q2ZU+SzQX?B03YxVN zz?$?NL-liefA4wHVer3*T^{artmEg5;0{mGh7zGpKFpIaXTeEB!lUs89#$WkPIQax z8X0AgoZC8@G}?Oi0U(q6ikx_&z1ve;=X`xiZWg*JY=w*uEZ7$O_pm(7rXQ9*b7bOe z-wSQIhi3$B?eqJbWUC8tYzg(-R%9`#vlQWUGJBHiXf__xqjjbK8*c=2SCQp=_zm2! zIgJXsid6=mL`1S7+3&5B#NXMI%{=CT`LmwCnLiKTO+gm(V}@EN*p+W6Tq1zG+wAhz z{47ue_PK?(BbR8(xlK)AY&RZSRoMgU)3{-9O-;rAL!$EhN!z34$n+=GtlLwcDAoIk zBceN`w0wR>Zyy}v{*!22W9y$cM}}U3PtOOxjAccx(DFcow{sZ$nJ4rJT?V8ssiDy6 z4SALyNp~ZP&3)yigkReyq=P&ONpFJ!hU2`wqY3P6ty=n<;Su@SQZq$GkWsPrt2=um zad%^gC=}fUtp~7GXkRiDcW=LHT!AN!5HyGUGTx-fZU9MZeAJ+LCDWlTQL#+r`>n)< z8!A;BzIx@SGoP>>lH%`cto{Kg1OwMsai~1CyUD9!RUup- z>H#?HgUvX0Z#DI_W?$y+M}~q8e7N^ye9UP2#l$!DhNB|k=-32RNY*#f|MRL+op5jD zx51z6Q&i1DU6AP~pwJ!{sF9X%cxy{{P6@qI)h-8=&L$Ymk#`pk+drjYZ~c33-GjcH zUF4V$VF;I@C(?laZZ+c1I+T|Y@E{vR$L^>nR^|HdfwX|b#_mcfx$^jd{50b zjjrnGn5|t7w)@cQle@q7&zq4MNhkA6k^|K9SK!TbT*P%T zzx(uS1P%o=gamv^g+}pbpRFpg@yVE&j>#J#yf{XVEVMf(HCRmG5j*BrB{bajDd^cb zz6}TUbpeORipnLJ8MizX4EOK+7AA40m6W_~P!Yx`S;Ta1!RmJH48d6O1v_Swl>8xfbVCYxC+=+Fx%F!CKf?5Flk^P8GO9Vx;WjiwG z40j`aRAU-a=uhFq6SFr3!n~uODTDqVc;TmWZ#S|Mk>qCZ2Kg|1Ar|!AJMwB3n0T*a z&Yjqj{9Rd$gPwQE+7|Q00eBhT((tD|`&@ z{Nmu%0)9)WKS_RG`k$j?`*QWWtU|&O&*&2Z#N#X|D1vf)5c?)qm zYsFKSmsgb8^43jc*HkKQZB!ibu_CTLhra3G?#=%kei~cG&FCWQ0}vFPdLbPG^^y)< zPL@(RcuHLj4{&{igg3XO#l-}delFL&O#Z1R8&C*}r&cB@ScqGO__Ajag5e!~rf{iz z5n8$vpDuH^vQu}Tf1B3x!}7)kkKr1YM+7};tJZ-g?yw9cQn;{y=B~`^$;I0}M97`C zoiprB_)fF*KL7ZZJGkP1+qfYE-5~XVBA?Q~kq{Yl;oHe1w#KF#s8nIniGJTSBPFT>gV>+|4zR=Vgr?5?1 zjW7u|Q$TMIATMiF4gb5NY1_S1rueq)3t%~aeP{og{s8wpba(E@ zm=IZ&y9nJ|?BhC*G4$S_rH8B#p$By8*!gB=;J_Gp?rq1`OB3i4!x4Jx)^e;eXhkL7 za}`)r{r69t&YZFSJ_^wFfc?|40iQ50JlWN+X4Wx1{B62!@~3NEv0}1*X#*-R0kM^} z<8k3FOm@TTlXrO-<@}vcjjyk)+wH@R4B?d=KT8l%eYiCeYC3p>T-_KQ2Uku_oGW7w zz54b#hc%x69so_7E~FEYJ!zEJ5q>~U!a!stXPn&8+4-ezMfbq<(6hy%(SD8inp_&a z19Uen{6jQQ;XW-~LzloXk2{`Y7MzH#@Ty5V#&CGnxukK^RdNt6+O7X1ixK7PSW2;zHt9(%Z`==6IyGqf^4F#6E-qc;Hl zOILK2$nJBm(y(fF;%ipXbVNm;^a6To&+U3#S4D|DRb1BEfr|i-1NzvNtYk)tL4~I0 zhtab|iXEp6r?usf>*(S9^2#Qv7~al3KzILl&U_$OlzE-Iv3KA&AOTjzX@1V%h(cLJ z1~Ct-z@m-xny`I%5{C48Dvln3p;0Ibm&BExAx#-)1T$e#XtcMEQF-RzI|@Jq-f29Q znSWcej0V=;7#;9imoWUllAKJJsium z2X+pPc4VV+DsC9?q|2fn)upRqgGqV$FlV%UQZvti;n}z8s65)zr;p$Bv16|#DLn;B zn@~YHs4muzeBPW{88hn=Ca=L!V8+peY0S57z{%dXf)!qvMaE`nFMOvfKhWAUCog4G zA>rxHN%$HXRaw}~D+V`4$+190`Ipyx0<*P8liK*#U>v+#6iN(L%(^^9cp(s4)Z5rNc}x{BUK+Ok|x3U%R$RP?gFjGvVOP^XrlS znM8^T|Hu+1&AN=z_`=bqS4Nn*IOlW__Xa2!tb|G3){2bBPo{TTakVd(vdyuOq2i_f zT1snjJhIcZaBg-GPA+^agyFRgBeuP@t2;So-lUN?a*0-H9jrX`X(E%JuWQq}2rhL31~fyz9f19TkWR z(YdT&m(9g<#jgY{C*$1*MIuGJzS3uaLwGF-R!@1uo1IZ?+;Ul7Hp_TjUkP75mrSP& zBXdB#b%+XiqR@|*GnenYHZg(yA)L0z*XhVt!S{k`;L;FY$E%@Ji!xep5`DV{1CNos zM)7JR9Z>Y(tC5p!&{sP8o;e2B%Z*Mjf&FOgTi$!rIAuh%QR*|JDd+)PqXeVzv4BJiL=e)< zqybwy@v!xVm)#$DBqRGgyf8bsa4@p-bSW z=CxfL37Pw8jimq{wUtE6+~dtGAamCqM_C>@YcD;r{i!OQfubilxw5jfnP5ic(dpZg zk@ZVNsihOELavO-frD$gb9vS>HGe#56vO^se&4oc`B)WM%f@%TCMsgD2& zoN(*UjBc7T5sscNMF398#xZ540lTqiQiF-{vWlwPQM)}Ekxe{-xi}6VIje67-_xE6 zaMUCX%^qb(0Tht~BY)WF$De2C)FU8o^lc}cvve#P&`OKzfWXuWmrAfAE{f9GFzWX? z7v|gMf6j%E00rF`pdr;KlWIK?_QG-pjL~3RdRh84eYbW2ju1K1mGenbAjwTQ)4_7R;hq0?0->es)+n&LFVji&#FZ0$&3pi1Okp zzT~IjKrqMZCeBm}7f{wN(h6h=w$%&~O*l<}4bm_&(S$A!pP4`4RQG7612=tMQ5f7< zm)Si#k2vtR>DbHM1+1bzrJ~7-E*$aoFRy1r^2(_q3O54Rm$IrQ!_>a+ajB=h;g|6} z09NV%hDJOT4X!MY!~{-iK0(`(#bPRu!;tI_D8|yqofeg$8c8!3;t^@)!G|%DdI2B; z(1@n0Rx&7&jz@RmqK*v8P~~jI+oK{hRlwx!gb|U*;tl>bJBhAZ$OL{8<0F^MaiOua zH8xvT73V*f*XS)gi>o*gU;FZ!4U{X9w{v3crei!#4bM?WOQ;EN81ah6h-_);{YJpB zvE`rF04O!YHf0W;d?iB=a#-TxQ_JC8Ts$pvGJ`A`$ikko%l)%TL;Zw<@(=P}N)y<4 zlVN~sg2gf~S-NM^=B0HwE1(SWRf^E|BJx-VD5E2JC@dqf=?{|9_N}Opi6~Zjg}lR3 z;OFeKnKPWAv5(it56N8| zw|d_AF+6>sit+mxzF-v1Nsb{*e=ma465rqn=fdoNj{4BZ#A6r%Rj`S`AO3cC9}yy7 zZ;%C?U0t6~o`3&gJd(fnf&;j=Gb;RPKgPGB;{uk1S8#)v*guu)9#qqZoTVnXQ_z2< z_W;LcZ`e94QS(XU=*JS}^TEA{|M~LR43sP=CX#93GZ_h&7ENiH#VAs^l5G{z<&k2u>6!;>Kf4md9>Z1F1z}|N20Zi`v@hWkSR;!-)yrK-&THB0nOe zsIp3=Wu-e^ml?n)Vn@c7;N1hq)q&H+RydjFe0wm@6zP-0yfJmiVwDfUmoM6VlRQGD zXU^n5I80pv^qSYVpM7EM86xCGdu{6|lf=Qgc#YN%WGV*RE;rE}4 z2Ro&djMEPoWpwZ8+v;aa8w!^zN<%dFjxDM@IOQ!<_B=t{h)OU(8!4njSJn3R4%3!NhATMwj7S`f z+Jw{*3{IRSpF~k3`wCM6@X|cmaR4t3M{0Mh3M|12%F6V8bwN8WOP&D+r$V4Ujc>lPd*a1M>UzK3rPHXU#Fz5LY`aNS_S=V%y&drsG_iB z1F_(ULow8%(x?HnA&g~6xVdI!eP64ug!UL!lJ7vwbqW${OpJs30QTz9Ns9XA@@4ZM zKMhi{?!v3TmB#1xuB$~4Srk_TMUm&Rssx_=qyi=|vghOyN(4da$p8-qIg%MpBk)utwGb+Q6|(4HGf_eJ7k34rS;ur0k6FK4vHx+HhGH z)QRANen2uLtDO(a)V(Fc6SH_HOHK$^YWCbMAR!E|91{j|Zl%Fr(97nOL^+zZPp`7}L8y<4kJltLRs~!?-=E8EH5A87vHID9O~kBM93L4wAlYZ6O$|1Fg}m&5VNmGv9w=&gB+590Q^Dg=^4tQigIJ z3F%~Zi4Cx*-93_LL^rU(MUqrV+;HIw5-HToYEa4QY2j+v38DM5A<`+KRRFz7QZiMu zD{xwyfZ&({Ly|1hKo4BvJ*(~C|Ao1?3W}uZ+IDewXK?qy26uO8pmBGY!QI_qaCdi? z!5s#d!QI_;aQORq_KtY}gZJb+_;&25lZvjW?98f^S}WJOuSKmX-LI&T1}{)08aFlF zU4F*CE(BL#($a4(JItgMpx%o@D2qBIwM`~4IDA6^1}{P;8bgMv{EZO1o}<2XW-ahU zK}5w%?37w2A(_$*vN)(~W(NQ-&+0j_t0It)iq{=NwS)*Km(P;U_KuZ{0A5i8^%&cDuv(7A{`joLa@$?C41XS>5TtOY%7F_>aDTI%mBJCi={C@X#yyLmgj?jH`|dQe<)Gkx53=KA*2NYsz|k$)<^ z^yo@c4HiiC$7^QNtAJr-fVC2Ej3$cvWoF=!6!$rVnzTWMsj3;@T$qg#;j!q^BM&kA zgkU6RXs!x^G-V#V(CZ@rak0ayf>Ccq&og3_B{=o}&$8>;8b(^5;T$O*H$!)k2Q27N zP7J0jvV9^j=4!w|jxmC-ZuupbL{*`JM0M9{08z3}f)c*U)A4$LAyvQgPPc!&H2A!8 z1TKaiPAe%br5p_*pb|3$a4O6UCWn`1;S#rX;QB)u7d)?^EZVr=2pVt*gj1&FlrW#$ zxNklM2{V6&Mg0jy=*9cvf}{sWD&zMlU?^pz_u&EuQ4F0-e6S;nNc+}7ODVj6M+CLY z(|mQk4$@a7xp=y%&7^A*sFHmHY^qb4np9YoU?N{UDEHJ;Ix+EZQK-;uOBC|*I9oem zbVtr0SAX<-IKn?G4NaVfHsJ8AGL&??why8z;z{4!2xO`Jjz8y^?ZwH`!+7X_%k-6k zbNkX``a_ZINP#&*!Hb4Vn1&Z-h*Ma`mrBo%7*To_5h}+~&(Mg(rzLoTVNi{>5gc)m zMU?X~Gk63w*4+ygAJ+HihJU{#GFawq^L=8x()$9jS44d)H1wM;R)gdZNvUx30!Ecg zoRsw2`5RJSc#LE?C82WkVga6VEWcC}r~f>9pty{v;_W3)9A$wit-xQ^53XDaWsXUK z!aIVnRJU71rxExX>9!MoxppPIRCnAArvkBufH!V$@xWu#IyQIwNhCOEq;jlk2Jsb% zLF?Al=m9uzD@%Vo322#i8B~lYuu&OX-*K8z;K|nDVZ0xrcs)Bwj@|}e*REaZb?SN7 zvEOgNb@6 z?%@RcQ8~&sF`F(niKh6m13n?0K~5{j0AAR9m`nyKx;M0?y!d zfgv)l8$gDxE1NM5AokwDN#oiq-#3|;4_swX;=wsUJkHH zRcaa52?CXkgE1S(aTg@NhERh^i2;I%Cq=WSAs7&2)**=f-ftg&`1RTKKnNqqk9zS( zbPs+|q|@Az82$bXJ8Ggx9j1Qy-1>M}<9dp%1@rw74H*{yAlWI}9-w8piT%8}n)>J$ za)92|3v}Q2;zmDtas@_k?eX~-s{}KuLZ+PQB8BMG#Y&`!7h2;2evXmVE z6In`jmj9$Qv9hxM?}tKKiD{26hIH`#;btf(fMY9^M<8cYVuM2oze7_1X^;rr)HGL4 zfq(PiYvVfcFA*FhliYE*@QGCQs(!l}zIw>)wS(w^f1_qOh5C4#{xP4siR$q-jrPt_ zx0xQ5`#bd`j)W(2tB52qKzhKVc4>Lr^Yeo!{^xGuy8*EiYEnOFEkL`8Hu2fc*v?4e z7~Ule`tV6n} zBpZaGNKV0$0YQFCMi^!0@aMapwzjsuzLr+~ihBKGow|n2_+rRPxrU;AVL?e!fu_?w zr8WdLfSiI9f@DUkaczkRrPRq};J~p%;GdM?htXS4&PAKW=M&T`11n{Eb!vJAggjar zLv1i>2`l92EQ0;Lhv)Zz?ZZQL+J7*`AWHGCE|BriOcZ7PtoH-71>t~o@Hs0McDWq>HL!VQKkI--I+IW)Z9taqe|D@j|<1S zR$D)F5GqAEph`%cM0ql*08Z8k0ScRn4Wi)P8OHfG#JC>#Rik1dC`h{+M7*fW_?LaU zuUZcR-?{EC%$o`^j389Y=8N9s|5aaFBqI14yF{|Qjv!^c#@Aa!i;X}<287H$+%c-$ z5ai_*6y)LI5fHdA%rXB0~V8D0qa_~_cBeu;@T0ES2^di_>8*9_1cSDW`c`yPZiu?0a)PR3_NQ1||C)*-TbB^Gq zfg1{9#CE%xXK(BthCRylNPg77DI=njPhX`J%$jV-4_?i0A2zr5EUeI8u-Yd zZMy*Q)YF?*LQ!p;voZQ)Y$ORcKyaIA8-gBDJ_H#<#h7?8)dD1k@cs&HSFOqwzJT?- ztjgdJbuB`?%dx!&$c*j>i39Lh5*EPp$u4fSy zoYcmu%q{I2Qz=e=W&FB!uGr$oPADg=H6&XtV&pQ-TwBJVzCD+ylH9jVMYm`7v7 zoxG2KE8?CjQl?sSYgkuLN82g!LIa=gYuWj|+L1Bc)Pzoowd)Lm#NMcLO>oWvbyejL zbex)icPj3YF(|4mBz!B$ZLx1|ZY?b>w~lbNQBM#jr>D2KyKm>M%CZvtm4!Fjv%Nzq zO*K_K`PG)*%!y%5+UHu@S}MVzHQkY8P(y5m3EwEm$%*sYxP^qST%Q9w=K99%I^l$P zcm%(bEXt)n9sa&uA6%Z<5&^aXqS&2Miq*o_Xqo`wlYd!@U7Vs)ijBIeM5^fv0*k)U zIu;~JN4)UBl5LY^6uMTrxQFxc{`Bn9uOu=A;fNhsdvf7CE~41Q{KnNDY8)1KcOy4W zkV9J%tt=5kq^&kKk^4_E7s2R*u!OA?1IsDmR;$GzAc*qlQX@kkZ1E2pR^+LFHuv=8 zuCD!*YUzwQcsBC8*cfOwY_9Ggtr4f!;I*{WCTIG~7;s0JqJpg~a{*t@a9obaQ9lt5 zpHzWON}eb0DU`e_cS()mu%5ITGgR!`dX%=BK3PCe{BO*%A)2WHxW5CGNT=sx91f)O^!1l zw(^CjD&@glyPhKKK4q3ad=i)p8azqEjyH77@3wm&!q)c0C3914zQ8AG?agR}Vy6+UiuKK>q_?jjA((hiUt*+~5g6hw7tZV1lCG=o;N zQs{zuILp~XeIKmlMF%hiCXPHK%1>dxy28_zHZMx`+;{r z&LC0@ELO%(eiS3QsQolw-&C5??qf)=ZJw^NC7J2;Y}JfB*O_0G>CmdgYIyCS9mqqi zqpb?@I36qO6#@2qjJ^j;ks@3FZa74_IQ${Can=z_&RqSqFGQuY{Wyn^p&4%$L^ zgsy81p+mkyHYFYx1Sv-kjl{4}oSdv3`*7A46*jlVJSzIoLo4eBCShv7RZRxAuqP{JV$*nAW>>+w72{>!7O5UboFV$_sx%Iq( z5u%Mjfx!2u7thX~E`B~+b;Q?*;}W+4+eYofV09&Jv6m#@(}BR=-_%DM>pQ>@2(f`w z*VvWN*Rwm-iS&|)@wQ)`+(HAgSlV`~+NY1g0SY?jAKAL^KqzYH=VwfJmso;>b6e-R zJzc$qiN4?cvTt(ji%RcAD0f`LDG(5uI-AR~DcTzZVun@2XN`s0WX+8S&^6Ew@0}jn zes5%*)aE!#o%IuatjzI}B7*CNO=P*zFr172h!*Ift)b6LpN%90_B+&PgA;+1&CO9M ze(!l-<1L>^?3fi#pG}vKG_|raVZNTXZ0=LlKl1g?4QH+6*~;puXD#oO5bC8decoY8 zrezLwg}V{alqdF5Wmi7NZf$xY;O>V|aAdNh$t9!kEj^a>5?_6dL783qcqsOGy4vh< z(Ot*7_9ocFY~;S{RX73GJ2-k+{CX=5`=R)0V^bA}8+CIbQ}Gzx+=^90#iJsZ`epct z>)dem&LN_czue4Fr``~Rl0~*l1HDL-5Vo=Xo%k$ahp(q@SerL{lFI00@D?MstOA1~N^MAEy>^=+Y%wWF!qk`GJ zi2WK062&^ltxzB=FVCEf#C^n)T6hn4-0T|iq-3mS%BRBYPJ4@_nthgql={B(c&Ko~ zY>y>uI4Np8S5LV)rBRq}=S41{xx1IgE~4;cT*abV2BC2!jSMlM7YWMhxpUw+ z>V0gfe;Tfxt>flXe8guGEeg@{ny4xs6V&5Co-~@6 zl5@>L-Sh41W|D7fS8#X3jY6u;PV<3;B`^a^x!xe6Mt+Sq89FSk;k0;=97@}>Un3S9 z;VV^b>?0R$X;`wnH{$b`0l`Zf=>wguFL~eS@>DpMqr}kG+QAWLD;80W(Al!#eG(1W ztRX&^FR<-oOWk^ZIQ(_#q-A4uprFr~t@t9p62}dt`NlQC5)fG%uP#szccSIRAz+JB zNLaq1>%7`*{GIQZoLT!>%1P-DEc_J$4KTW z@`Tu#GBt3|?6FmA^rocgXJ@F#x=!*AY1&6D7Uf^sp@<;Y1`6K5UoM(& zh*aEfLr@h}p1Y-|b16AFy#Y+-PE$(S&BnaMx4h~zJ)xOPOWT&x{nGPLvM@9ekO{|> zX|MRK&0}cZmJvegWBe!43-OXW& z+0qzhTe00rBAYZuF-X$#QA5d^<8wdsx1wbShtp9U!q5?n>JvgReKZ*}VA4(urD2m4 z727+2%K4J4`<-UrX%*)v^p%=n4FijEcgMR&5r8EsO!@3436^7;qO6SZJ7k27D7(nm z7B~h|NP)#*cJtY;rsVb&pP};{L&H~ySh71k%LB;?K;dw*#Eg+!hKV%^C&5kufVhsf zgsV6&HixO8zTqP8I3YVUe( z>51vIJV-JX9;7kWatSV&f}^Bl2UC*jkilEhr>`zdj7}pM1TPoHnA@!#p9x-&io)zp zWmDIjD&CFH8xH90OE*$#4(=VS>0e@wRvL5!LnX&b&j)S&PmEwMI+YR zj_j)Zk)h`q9kKNw4$J#>TQN$on&4q6pdLP2Yu}5k%N;N;_5Jggb@%&`h+$o&rhUgU zBwGOKA~iXdTBvc8&_6AV^P|b4j2@pzV>7V@y2|AaZJAOLfD$9VMtXX_6?l!oZ}A7h zi235~GMW(^rgh+!s~BRk<7CctU@PB5zyai`AAzCdp!%UpOGm?fE8IZyDNRhIrPqgE zsh&teZo|p&f@M?Hi@IbtL+|JRW^uu@Lolql6PoSh*yQNwBsAaQg@Cj-j^aldFqkV^ zuh}meNd6=pO3n_E?pF$NjfOJv#236(&hj;R$V{9@M37k-orK zf}TTc=YIzl71Mazc;3qWWb^T2f95cdF~l22{@qv?8{r%0;Sf;FhNb3DZY)Mgj>bb? z#V@7|nFm7;z$GK-Ovs4``YXX0}%3u&i~4W2Yg& z*g1xi7zLP8B9kdABqib`eHG-S`Ce{!qZ$}lMasAwWprH%e~&k-f|HMDH5$zP8)0&^ z)}S!`>a`q?IXkVzgFMRshorskkGs4$3}xeWunY<1Lyh;Z*km}lF*HT%8;*YRq+kg+ z541=e8gHo|ii(F0HfbM~M#4F6(XZbqtF7YD<2rkTl`K`Ngh$3^k}0KTA{ET63<`h2 zRg+5+-p%;1S8hFeeYhAX7$R17YyO%#5n_$QpYDGA`y(3W8&%Oa`jN3{F|;VZMtzAn zm2OE{IjvyH1RP&bih*m5gZaeXhXC=OohR+9w2UK$vdlmNHxxpp%2*+i6$CPEWljSe zokhRFx(o8dud|S(9wJQ=s)drG7l3bMl4QuYU|R!12*!^NzWVEwG~uD8M=hkQ;NFp8KZ$#=n!$or3n^xZl*Ag9piGexZc*v_=gr(ax&q)S%C$U}Wak)jqI5 z#+~j9$R}hL^|#_VfQA@w0$H{${1}b`B>=~-JxalVB2iLuHJ!BAK6zr%vVU7aIgk}M zM4YZXS{S}Jae~dBO}PA+l2X1rEfcFz$I}6B>=()sZ*sBWPyMY^J5#7oAI)z*_TFSi z2H#13Z_wYhK*gt{(}KH?^oZf4qU;&tq>9s+xlAaCms-#4qOS2KQVi~V(i@@^`YVJp zSFE3o5Sd};jd%+)V&~J61w_M{f^9ZVG-O38iVh|XuDk0>i)l70YnX=UbzW+PcC>z` zawJ^Mt-|M`R%LVSL$C^FgGWjOzENOJMhj#6hfT1VcCfA>r<;wWMY5V8fF=PnxH6zC z;vQNwy*EdlxRJ4%?&FXO^hEebb|fbT7L}+n8x|D>fb;~6Kf=|dfq;EH4z{Q;5f2VD zuW1I&*6SB`q&*Il?A*iKUhT|dyY`#AId{-##05+@`@^x(s4Y%pZ=6Sh33$mgt2hLA}-t%mv@|G z|8&1$+FYf$$#L|{YT$!>u;$jz}6%G`4Qh*-Sp`Bd2E3LqoB{^aUs^!qRV>wkUH z|M;&tI9dKfRpR<@?rX09iTj%M8_$0-`Tsv~U+Y+ z#mSh$SY3U7Qe0(KP?~;kxGXMr>`Hzygr%4_&n=p|RPCS_@=d$=3=GKa%uJCGzDHa` ziIwz(fuh%hv$Ak=i`7`$*m!=Bi$JhiUD@EP1L^)`3^~@J)?t}~Q~R4XuMowU5Kr#Z ztyRH#bvV|b&26iks<3QFQ6|T z?ka|g>&ONkkVtL`pknd#0cKCVR!uJC^{i~mY@jkyCFDZ@!o3+A;h)m0>D{b0jg6CckaIox6QG7&cvYGF{m~PY?8(-ubC}R8jq5 z$(zf({Oj49_q0Xdu{?Yl{Ba8bRH3NNeS?mH(YHIN(N>=+ngQEtdxD3Z?;r-rY7mUg7UkNJBf(m@6m z%~7jjV8g&ttHMCZlq!@^(j%eBmmt9ET@dBjMyf$o9 z%0~8vY-Yl7&a0-f1^wH-repr3CrzVC;vszjqe6G6ypQ~ zFU4-0-z98tZO1WRLu6SK)MHHT;j&)dk{k7G zP5r=z?{lA#eE!g;ak-tRpE~Y*Q@nEW@Jd3^)Mv<@GjRxZhH464GCgF?ONS#dU99rl(;|CN41x#1>^+wXszJ?_ZFyAo02xGuijRyhKMr>% zyu4ePwI+Q(#2+)q-EcbE+vF_R9zVMT{28k5XU|cno#66N)X+LtTDNL6a&A|KVON!@ zecYU|QFGg8KB-secVupE zh-g!-|L6Rf>uNQ^<1T6*0)KLt>u~*Cvy4-&yLaD++F|)3QDBcWfl&A+A))Z}Rq>KKh=-s-)XSc?O8qx`agu=2JL+ARIunG1ftn#-N7n~UD<8uT)!(uH zr)0FwJq@4>eBq5z_fBHN9I}oitQjxDv5k-+H+(qqJsEFO!d*eH$#2sk__P>8*VZ&v zZ{IXt9P?dzD(rT8KEJ?1XEL~_d)S^1*|nv0a^=i9^xOg1m_L2cPL+ahFb5y3?tcN! z3WT&h%7aES?=!LHyN}D%{RVOLKi{CAr!l*y)Yn#vKlCFaHo6KNo`22%Ypq*Jnx27uznq$09e3WY|HJt8JfBlizx!Ei)N0!FR~e! z!W$`tl92X6nD`8G-ttd)O5eJ6s6@7iTyKCBAV~dy4BZ$da!^SFhz__o-NUYtG8#=v zN^%j$Mh9Me|0}D^y*$fQ`lLx;F;(L%jt#!xF-pzjkCAYTDKmC^qY9QR7T>L{So9>j z<|&fckW;oxAu#$VuI#dpE|Hu-_jMLi*=PtV;Z{PDqN0qr=0MfDmpU z5}EHex*y`$75tjWzqLIhaTfwMkdtE)=;_9bX~YENMc@l$RZsF}@6y}ui^?dK7x2dz z)C%r94H*SAZVC%zl~1;*1<(Gmr{w zaQ>QAjm-Tu8xZ*2-!rXkj3V!zfe7yVh=ix?&73+f6o5zb+gF`Y#m(N`FyCUx;-fl9 zHKmeb&68K-VojZsZQz4$enBz{eZ}A{qST3u|A{)UyR4G91ijj+Y#6CP2*;;&aj9_f zuURq~rG~>?MB0Yf(1zLkGi$P~fJs#Ov5XT68PwP8$_@18?fkCoJVj)N$`ja}*~Glr zN@uvdCuvYwpQT81s135Pe+B>#`{V+2YNjtDWEHKlpf;V#!XnVeR#1MW8 zqBip=4hjrZVI(=B0~A*{15Td%Khd#PY$Jol3iAL!=v}w%6Vf?9sHD~nEE>S zFd*ZiB^~P_0uAG$=}qW7D2ZK~J5as1Aq)j}YQ#fs zbkulLu&|U)BChQLaUP)dwSp}xwK9~6DpOTDGxn9s71NmD`a@s=B>0K?@6iKy83f>Y zF@*lifvdYfM5->R7Rbqu4bHI!H6yD|&8p_fs-I}~ItG&cTZ|l|%#D~5EbG`5I#!DD zz%2*z7+0NpahdZ34iuIKhz75%#tSpY<8N#$ys$%jCG<@jLuuGLCQp+9&|DT=ge18F zBfr(JUV4sPrVS8PDM^kQwdUPr5;&2dx^s>$1w$yNQH87^Rt;3f5g@8tkMdVx%%1a@ zUi1r*S&^kDs?F}h6E1Ht*x-feLNP6<5c-1ZwO&jUh?U4TSj$C-ETO@e+mJr;MPaOH z_RljO%2ot;a`lpGF!?L41ojuE#yXJtE?C~B76HJ_a8Qh`EKydf@DW^&#N*5;P!3DY zZAiNmHLuryZ1s%pmf}^T!WpR3_0a+@k-+BZ_$B+%wo#sDJ^c&73=2LC2oxzU)coPn zp-@L{?*Lxrzmum}5?e8;2rGP(k^_}PSt0wNPJlzaw|EncTt=U<4H^cmK@U^aFg2m( zZGUB=!ahPN&2-;2%DK+Wj3PK|8`9wtsLjxZrfYwG0UvU_NDLQ!V3rv(OzL6){-`}* z+<4CAQ$-W1axQ8pPEExKGzJwi6nCHSo7vmNpbD7NNO$R(21aq?B=+VwZKi2l>rNOD zob?buT2W9wyz7K6!m9UrUuq{Oo=lT9vL6`&3xQB{l>3pkaK-8iB3byprcG~^7Szc` z*Ai22>4cN;OHgM{_73QFL(}s5?DKSVcKJ#BkpL)t1D0KQol+@dyLK4MSp0#&>>L_f zL#_xo!Kfnw|AING8~}g1EERd_7Bp5wE(tMXGRPJ0;)_`_qYAB4IQW&>#E8V-_*a_u zWF2e}#HBtOckB>3+4{EwKK}vWvr#D9X-MEYWhQmzjcdSjnMT!sfJ-E zo30}cqHSL$SkC1d=$sc<>qI-|#zO@ip%9?f`S914arm|IUaBDhiUExhowend?R=j) zt`RppK2{WAY-<}xosqI!iq;3x>J#DR)x&M!j-H7OH=9?ig1~AUXJW;+i<~7NLF>#w zRMdqnL-P%S7Ejw|vkCQ%=N6LgcLDPcCi1&01sF~CYav51C&d3^OZ{sg{bNh9vvPC) zbN!!lZf=(UqHfI1`ae=PX8DgT#s0sKsMWI)`!bH9V2lM04Yh&}g=MNCE(|bDlyJ2l z2U$`r6`tmXMNV6)HTT|WA9?jAX^E;s6Fhngld&W(Gx#(3Px>&v4L4o5&-;~-MFuR} zYc!ubZXdkHs{sM6-FLjXo;G03cV4)^uZS*s$pK!W?>+;YHLix>svTah)Qup{Hffd8 z&6{2i67YSKomjI9q_W-ms6)XjUh#KQ9VDh;$_kPNv!vJwpbr`~c5B}lmI{;n8GL=D zly|y4a`5oFjuK_1L=XWDzRs={(-p8CF>S?eV(g;<VHU~L5d}a+-hweBnc1! zLnYb-P=4WYAR)4Z#D<0~Bc_K6q&%a%zB)NYOXc!Pcn+3VFhy`@hL zcaNQbQOFByYG@a|vHo~rizsWl9_(vkBk>p*9T(k^6)PjHCj4l;cd1WH1w?4D#i`pH z!2NdOI#3aWMu(cr0|)YTP-nh=b5N^Ds#QggRX{8Q5M*9#TDIHkbag3)a0HEkJ%-%r z)_ZCgl?jviiNg4d*9IbSXzTVxRj$2i7snxV*yP1Y6oN#6EE+ue%S9h{^0lQyH`JN( zMDf2rW}C@9KJe!8N&x$z*(mw=Z54M@TTm554`!k0|F+8LY7kWa)+57r)Eab>pg$ZT zkOAoeyWU;$f|vabk%}wF`}C;MwG+aiFEul09m;QVgkip2FfW~hs0o}BL(c1Oa?GW+ zyIkA&n%53T93@3no@QAByt?%3967%=eS(0 zjsI~iBom&l8e{1(HmKeekk9=$cy7qkjhh%!qm7;93v+%05d_>W9&o~@Q78kfLg#0m zr~_e7#V^>zlc#cz%%71h-13BB7$Mpg+}Sa&lWchyHV%{ygrME&t{dmjGPZ=97o4!` z&o0_cT$XCbmdVmlBmf5HcvWS$2t@3}COv8di{IfKRq(@0+DZ6T@cr@|CC|?sJFd#FTSb z#}@%JFfbn&=G(!6odp#(P)=T!HZ)F<53vVrE}A!FWF@itWcBhUTehn92S-Yl0c%)H znn9eyGU(z!^?czw(#u z90CVMa_4}!rtH9jXw4{!s6A0+-~IQ1p!Iht*!k|Sc z)YJ8;42WprE;BZDh<*$ay0Yt4d(4kRvvM$X@P^#QyF$bOy*E*+n4RuxSmpd7bZurM zD`;qVjA3EyJe7&yI!{pQNo`)BX9RatAqJ@S7#gCJgRl-rd2q>w>|~|bn8VW81rSkU z=Ayu^{UC02Km-S7k~$zRZm>Q&5_CU33RD~dMyq2qJq(02IusCs0W(c~S=}K-&ikpA z3|PQ~B52FF-`0NIW(u@)7+jDub;wE?svk@?b%0usWAQ)4c8JdV7{QU!?1BQ6^QQ*N zT6P5kqvf=DQf3j_$fGDK^b5jGQq->)S4QOxv84cAP;&?wV)dk~X$9ORO&B)RwAFPw zu<9`fuMnfI<_=Klpf2-B*Q7Rsv6a9O|B&F~z$gVU?FuelsNkjsnmP=o!^;q=iipZE zxN{fYV1$2nIY=7>)n~*rB0-&j9>%a*lMwv@gQr?kM6_Lpu1s8wI*l8}SZCKp&Hq!UDPh-L$NX%6jbq zL%tGnu^MtWP0Is9;y2;~TDtPG;Hi5p@fm@)DbjI>Xr$j6O^G=kBICX=5|E%oyO28oNzm1rq*9koYsA)%h0|_?l z+h!-bkqX*_YE;w|sP38!ss)xhb3jvq_DV4??yiwo12@De6`Js}V3qS3qg_6jyh!uI zA%lFS7;JL`1H&+VP4G7Z*6CvBvnmG(oMBWihhJ?yrgSk2IZ?-fa8se=6HqX53^C{_ z(m-zq#zNx<3~Ttc-46^2Lb(lIES_h?5mz!MBg&X!b=SIE>jO;~XmrY`#s^P$0o&Hy zGzma7XgsB<6FSJ3sZR`Y-ksL&rWHu5WnEk`$MfU~Si(n|%Z&*lSk*$n{hA)uW zMaZcAWxy7R4#W5%!}{*tWMoEf zb-=J^87Btk>@5Tai{hrkSGkAiswaX^O(em7HYxKDCnzqhuUX>#olG(L#6SNu7Z^q$ zqzY`ZgU1o#x33{1%%DT&p2t*tcyp(u3|tKv;P_ecGxT|T=JYy;`gUfhbiPL;UisG} zaU=**;9<(cGOoe?g=D8hDS7E;Lno;dhu`@-yP{)qS2 z+DfxEXXQaJR4cF~Oc;L$Z`>qxcyGh-=`FyJGKFrvIcL#~))D5>b*A8=BU7Fq1L?_U zwwd3ybimb;ZF{9kcFg4IFRHaYrwJ`#gyeL$;FJk&`MN^$AA(7J(C7$7aDFXYE5mXe zbwAJ2qy2)MoAadW%3b03V2$A|pJt=@dGahlpE&C4v+tPtoO$ch$d^?klup;PtM4Zuax1OXXhZ6yOup^q;JAQO4X{?1HTK1s^W$J&NvH8y+G@LTqtJ_daF z=^9@rVy;Evj%v%Ct=y6oC-J4M{a8k9wli(vOS1_#_pQWsS@Ca^+RtyxrbtqCWJIoe zH|3%YV2j?I_^4sGW;rj}>eWe6*}XSx_E@ojk&A#Sr+Xtz9M&k&N6~KHy&KJ8E2b%q(!2T)tTHhG)pGXI-5msag}I z1B%F;D!nLwiwVSFEqH$G70#4PfBtFt33Dk5pqdLKxxUh12J0X+s^w<5@D@Hm($iJ_ zNy2VCcLVewuFT$;qEbsE!*v1ut1(RoBF#KLt@aUg%sYtUWsUr;EOHxg0>Q zf??b4h3-Y_yx)YrBRR(QTXZuY&P=OzZ;zuAXpIpskbm$5TE~Y@f6{AL&(}|n5W5Ep?)O}^Gzey zi8ErGQfPZmz8p(VH$7HV@okC}h$mu!`NtnK!Dq$q0dj7`RN!w&!Hp?>_LQ|pk?LsF zojsT!J)YOXypNB0<-nd0e8|AgNQxA<_ZKAh>>1&T%d{cXAE7YCPg}k?AK9w!Dd(5{<@~u8| z|BJ2nuL1Y3t;hcD|FZS|+rAn1|7hQg6{LFo|0-a!{*waozf7{xv~ntt#mW|!z%es` zLKo2zhr0Xp+u&;fH^Y)=QN6;{h3iQkecj4-E551U4vb=|>irm!-G)$G z1Z4!dbt*_}8<&Caz9dhZzh_Nvs3`UbKnfVu9ODm-LUFhGh9oI(h1Gce@)%>j*L*=wvV1Z z?27u1l*KGDv?^((k2S<2lzqFal9I}gLTDpF{TIWxJE$N#E#Sw%1`Q9=_#9K+ z!h!QOlUeWJBcM7Ut7x^u#Fs9LpXYq1H0)kizgFUlZK!-vI9}{`cn>^0GYPFjnd6R_ zy%%L|-JXiKn@*Ati8FQb8mX*3 zdv4`e^p4FH{lf)dBJ1I7k$O6y+OYc;al|ctKs}LX6@Si{Zom%bl8;7k9r z%IrFA?MVMBp=_e(YbAKU8^Em})~P*MdaElT(Ei)0;s~R7O?Nh#7Mx728RvE}_n~$w zYgr1KO#HnGKu@%yl_cr}XRI<+oZu z?8&aAG`hq>nc_l{Rh*vBAX$Q5_UerEA7i+e+MfeUWv{PXq;fV2Q^FN7K8Sjlj&!m_ z<26TkqXcb93c$ft(yR0m5{cLQBJaP|RSByij%|w%>e>a`($cOYHD-z{*t!1k2%nd8 z3Yl`S%I^|CeJ+QO0#g-)1P#!`^DAp5a&XP|)Ja{?zAnp4K&t)N<0=bi*g#{$HS##{ zzPGVql4&?RH^v$XM4*(6ri#r+fL!pIH-uik4h6)lVs>6Q)WwPZHO~mmDXy%DDd9F@ z8lF<850GB3Kr#Uj8_TRP1$EULShet%GZ=j6) zA;F~(6q@PLIQb*#N7c(}aApMXqcc1`ZCH8x6+Gjkz^W_%T9$(==ScLzOG7@4J2;T> zm>}mhfq+aK;ak5$OoIF9+>?9s9OmyRr!Sr*ak4MrNelm1d0nsw;DO}QiZ2a{pl38a<>^V3r`btr7K_LjBfPQ4NA5m423Zsf+}vyxV%5Qq;`PBwf~h*92N+1~RoD&`T%5;KY%jR6MH$||%V zIar+V|1pD_O*iJwAqh5ug1r$K2F5$v$2QDzrR}rivK@8c#)x1Q_j6LXXtu|Gt6@II z7^ov$deBX^Wi^%Q)tgii&M2giw?cZVq#+iqUrV|CD=>ZEysV?mP@yO{Ab|X568FJ6 z%k;$P$nvqw(CfYsr)=9s?Ii!ZuY~6LRMc!Fj%`Rvm1J)wOLW+9njY)=UU%q2p?35;^B}DS4xMCK_&zC3td9I@+w*KiAz1^(p_9s@+p>=Dw?jQBX zo*0#|4@)!~zplLUz82J6Ooq@Q+G@3M5)2oKdm{FKeL-J%UwfPmuEFh++X?Jo+F)@> zehTgE8hQgx^j($t;BrMH48dW)^=W)glH{>SL`grE3PsdxHSS99wC(@e2t9m!MY-(t zu5(@U8s~ia+w%muo`17uz&EHQbaWUX1pW3QQ1JHtbq*yF;y=e{2gE11jXsXWe_MI~ zSx*01d09Dm{BV=E6+c;ITcc7pohH~DYK@M@pm&5XHsTW7h~stf03~9oPc${V&|*(am-u*77Bkz{z~@%w6~9CweGlQ*puV2<--g3A<`wE`ouS3X z#XSm_14Hy^pRsiD>;kdr#t7|Yg7jJGBacy3pV2=T73(f$y_FpzEeSAZS6BI-H(_Nqy@Cdejj4j$F^0`RotUh^Ft^ z*+1^h!?>{IirCy%vL@muH;e7;$VFl&iy#}gfq=>;5H8+1yPG+MLG8Iv<*TWkiAXB+ z$SyrU+_k8ME0pm`ze(4^rSn0IV#l*?x01fcg(MS6vZS3u7{+7lYA|6%cWb~WNl*`KjazHaF+24_>}U*0`C z{Dh$NuMJwSKf`7X*4M6D7&Hr+b8G$(Sa%;2J>i?%%}>{@1%z!AX`BlUNRVDU03-Z}z8R&wTTlm4tmV_wCVR6QHVb-0k{F?yL)LUBEY8sl-q_Ql!!{(Tyoj6; z2p6mno3+bjn@paMbGc05~0=o&>PU^&7pr~`j)PgEq&iFtF^62-u0pPJ^A$o z<)c!_B3c8aqff)WvhI^3p0DZq-MMcnh&VYB3j<)+=+L8AnGywk7{_dTb>-xCB7Q#m z;|M>yxBmCjOV*|#_m^0MEknwLaz2)bhu?S2aP&CyWlQefBgJ-@`*F3lHMM*7(zM(4 znX%qJh7x3= zb2f?`2S7E18_ZinHYN+r0Um8wU^n%l~lh&5VrLkr_Mp%3N#Cn0u@-$8g~GLVe<)li=Ft z1l^d%JRT0!uecegpTutJ{rctjV!Q&Gv*4;SpO%!SL7oQXRS;=)8@&y$Jk1dWTZ_EL z24I)k=ll&Uvn92z#(I?xyQFca_Cc6|-)}NQ_*_bz%o-s)YVc!xFk3b)R60j}#_8_t z%lzWNb;*TkMivYd+3Ut9k&5l^(@4=`mu^Ji(5(1q1CaVL>~->)FwByY*z@fIUkYiE{mE}FtZ2gDPTS*DC^H@ z(UcQ0dWxQJ9~c1ybL3c@QV29$JQxEv_}yXHw4|den}39=0oAA?Q39bHI2-M1R{Y1E zs2U`=BQ)R0H34MaL4mx)D{^@{*d7&NC~7nxt>6#7%}g)J&CmT05fn<6uf#MQ0f!XN zSiNJ_k`Q?eW;fEdLS68upuz!RU^EPZ31EBHTeg+IKVG0s@<3D42n)`1VW$J)dl-s@ z6nqt@nF0$Fm`FLZH-%)kz(6YOstY8`!KA=3O3%ik!2H7MFNIJw3+TCF-o7qVU8X}v) z6bJ9~+=xujPsH}7ArU=P%NQAFYG&PVWO%L%wWW)I6k*~&)B@Hl;{u>xHjj9GfU{ZjT>KOTy$UgA#ZhF^~7>brT z9iA3tBH;xPTd>rwgt$@AC9uN9VAk4SEAGdq>TbUf|%L`E??1Yl04CWwQ9nW%C&IB$IqD!8yFP2f-J=1BjB6@k((f4jbV`&F-PtZwjM z&z)}-gLm}q-!KWhcsF(N!&Kr$`L69DT*W0+p3^mS;}-$?fkgugxx4Pl0MNz!S=N4F z4vtbP(hRGO0v3x>mq%gZF3}1vw(5K(l%$4DoN5CMw$9gH(GV|;ayZ^YjaT{(8Uua* zMAGtS>awiCFA~`#=;looFAb%Med;a^`Q@#s6;@MQMX76x&@_0k<;#8Ur)D}Xs*PNd zRkq|z)W#r8GgDSR{p#A$=_VLh%0j~;5AD1&0)ee-bIo8$c>}4_KQ~mgwwo`W{Ov3{ zQs+%>vGaFZafHU2bcKeS<(BQjP%lgZYvd29h22vbn5F8x50i;5Men_Lg@qYSgvZZS zc8-pV94{3Gw1qfR+<(`vx`KzeV&?vap(bxJloSvX>o$E9TVc%Mj>KY2OPBglr_J|} z>acZe&-%|_$e?c5Rxdr9tG^5Ul3sL`N9N|S8s$w4ja8)KLe9Qdg>kE(H(rj<|AX>m zG6KgzVfDn_{wS(R-c%j_`_@ZMV*Iyi_Bt`qAAHL9dsH-n>r}GNuO@tI4F)?r-I~v6W<^hP)t*eM{I-6_0 zSfN)x521n5FuX>hmcSzOqE5Jm6FCX%Ib!F`bahA5n_#7#rs zH6ySdcHxI&d({es!4(kf%%=}BV;C(jJ%>QhTSn6+!(G2I43btv5<@QKPk$Cmf8k2K z$Tw!pHyksW$&LX1X}FQiOS5eQJvoF1M&LM`4I3b#SC{~=jXc2iQ&I6Fpn`X&`{rAa z0CwhaSv}zYJ_XBq1kJBC>i$(E|EIqoCp-H;AO927T-+T0Dv&wVn~ zYPOpy?kdWl+cF1*3=uRm(ik!{xDa--l0-x{+*8-}H~AK~kNHf`{dzgPdi3v3zm-0Y zCO@Y(FSD!5`R$hi^4=-?mDfE}eE@I#-yY9~?X?pLuv|W~t*Vxyu#Ev`x zpD&gld8XKmJ+SZIMdjc89)f<_FKsOi4ILdF1C1>$FX+Dv4S_WS9)dA<+3#MDC~o@p z?#c(-rc4Lxw3e2ZG&D6e+`*+7FCw#d?kC|R1R3cnb!@V#=o@tz%AB0$4V%}kaa(}$ zDckc^oq_Wlrt>!9-3={m`djxOAw{)%4Tu2R4;??Jud2Mvy~Yp0I%<9hAu2)@P+j0tFTc+q&?#1OJ z(kc}cxjf<-Q)qP$9sg+29XLsbL9WW-y!b7Mziges(f)8* zY(ka8(>N=;M9^&Cw94Vgit()UbkwCzgYt`)FH4MYXG4K`>1f~Ca$eyeYBpdUIS$Jl z_=TXz_QUombbr)@Cqr&%|JH(w4;SvO)3yx$4Pu4%&`7{7eX=;wi`h~1n!e0H^io{f zMuoL+lK!zePk>Q}!^f*t2cXU8;^XAy<>ch#owt$8pXMEXV`o z#)pFd_|o4oMCQ>+ILK8X8v`?Rx*D29+7`Kb8ykXrzFx_XH#hcver}S!GeP(#MAy$i zTR?7qfI5lY*x(w)tyM^Cg)60PG%S!9E87GAsQmJF`Mx}TeSf~5w&LgK_jwknt#h;HB)!Rl0C{TcClOxqD30enPAq^t$W)rFsI2kV=z z+(_G{Az#LO*j-Z!_Jc7(WgE+yNM2kgjaiNRDqlo7;US;lcEh0|+%Y_690e{${BbUI z+uOe@YkzfDw&dlJk0~z(w{6?7m#6d@LfpbzP&(o)W({V!SCG zYpxp@)3(2o}_If_?evXX7P(D2^c`%jfXzF9O#f=t;{}2~K&X9^JV&in=O@h1&*slp zq{h!8cQY}LPM&pU2!EJbPIg_!QLu)!dKYNXrPMIndpoLBj)GgbwH1D19e_b{>T_xB z7dJ`Acb8z4*i|!7Ahl_X(wb$tm|E_RzlU-3d#+k--+__VzWgM~*w{Y4QheIExuMde z0{O6hTK=Qo_kIgJ%a8xK{wO0Lo0G#a9+^6It=-r<`{*)g zw7#*n`snT>&@G4r1tGdC#fA|@nb-sA&7e=Gu22pZw%0#v;^{!`h>C0UYoWS;y0 z@Q%6V$EEFe^omjzC!5E(n)(O*!~W-GqtR5!zA&N;mZ|S{A-y>YtbSUmriNxMvt6xL z#me99m6}m>pf8TWXUM=^3v0%VF+BfvN0ndMu5CfYfp|ve3o=&lI^vwczAf!tSkLQ? zceB0=-SyBJi!o=PCKN2wh8XrYf%j?Rc*8e*X5v*qiZmS7PxA4iE?1V4MqUd)YO?5& zafyAs%#+uECg0K1rzJl%8q?*2`53ZHUpq;00d7TgBd8Q~+z$P%QEedkkncDnz*qKd zO(DE+t@Eoz-lr{V7A|k*#$sH>90SdP8X`fjPgXn^9JH-yCay$v+kzP(ndY>0HMg-P zyGc2Hq!-W%y~>9~Ze*!arU=4%K}$iqV8Fg!-#x_~2W%PLetseX`U()2I?U~u&b-T- z+xV|(`u-ng*eBv1;0zn*xbe6vT|!)K&5CD9Z|i30^_O#y6>U%8TLU^z*R~!Z`et~%)GE{fyhiK->@9Br;J*PG1^n0z3U`0P zmy<{8X>ULf9id(Ai$;`f{uVxglREI#qmM0y3XztnJ9islWQ67D5aZw5Skg>?p`-fF z^|IR7R6ljt7q%&$}L0yl6tGp?XTgaPt==ylIv|_oO56VrH{k0aEY5pb$ zXIKe$6t}5e!<)L))2D(t5h-z9!;hY>?up*v7GZeD)gr z(f0k`7&{rrut1xvlW#map?q6Bdlgrj#<`-A!CY@8D7d93?-^r6aps_t_WJPX_YIHw z6>7lR7=i4Y zdqKfNEG3e>iDSu`lQpPh)DXWR^m#ZK9)zaPQPLs_eEn)5V$u;Nkb%IW@#>^7@ z@KO~co+3VmV&>-V!`;)*kSEx?&BNbLj#$skRmX}Z@?bHU(wz-;p(g;-JR^glpK~`K zXSNiq>b@PFSh=aJ$jv@B4pS_z>JyXsv$P>w1vU?<7lf&RCP6I7Mn)FY*WIHI{b@>& zsz+`N?VZP)(wS6v$n^a`MUI_L9G#&P9m>)SfF(oI99KW9*A7tPfaP@4r#hKlG11Zn zt>uPZ8ceTb7E3nEA=F-U_MV#Gw3;vZHaQJ7uH0DH5}j*?55uvi&}whC-1 za%6ZK_@5Wou##lV8(IMljG<5WjavtAz$Ep$-!HK>SL%p@5{(=}vheS9Ek>Ig@MTdJ z`JTwwhCUukBiFAS^eaGbND&nd^})Mf2AdK4<4IEonHh8>f`YnnIwflMUZ9LIPOtVh zN>7WD@E*pzE&A37jMsTx^}6FlM-5(%NRK=4k(|Hd$XOBY=@1kzYSsjo`*5mb+@ZLC zp*_7qmx$<>%{E z`xU-HXIi+jqC1aZCLm`adLZ7wHth7+JBW{xQF8uFsEEj^Y8_f!)J5Mu$ft+u$6Nf0 zng5fqVr3&CD2c&~SYPbO42qLu@il8n_=ee8LW{B5uD0JTxCSFZyQ+Ir52UqtYP&e7 zhisGCPv1PW(R99@(y&s{(kKlPH*5cAePOKj?5k-PLU;Gr)KZjsFu=v9e@Up7{9al0 z$q@ka61QXC+1kl8XF>nq{s!UDVZ=yX*84IkU}owNzD))>w(GYoBEbj4VMSPYm15aO zBv+}tY@fYw@CyFv(}-QzR88nUu~wdfpjw-Mb|bpE6q38mGGry6fa)HUxi#_RhqS5~ zcR_TLqY-5y5tirksqXZYEwX?5Holj+iLa2BX@0z?xTBZRY?|Bs2LXgdHY{%`n_tzF z;E%Wo?RGv5y=~|O2Z#8Pm$Pqi~AuY2;XqYK9`pvl!>jU}82y9K*V z6dpoO1~f)jf1_{6oXN}G*T)NkP;|M|XoPN94s*_O5cm?yN<;4`d8EdPa2wZFaP6j! zn%Y$yIgc+2A0@gqIrAZow#|m4i=ha!%7CcI+!>c3R1HH}tE@L^arRD;L#4albIC#2 zqL2Zl_pCf~>P{S$?50}3o{+b1mY~?Z1IK{m8ha<1{D3)kRdN0sd%Vt2HmpFqKUtWTI;H4+%j|ZZYmu&rtI(>${VENp_2ix?X@8Wq^=)@ttSJ z*U9H3%+R#`d3b?a!ZA$;bzwvE-}D-9wQTNec{fc2?-h3>=LtDhnYoUFH%VrU@)^fn z6{O+h5yi5fc`aGPNto0!!LVriy+fH9Z2>qPS?8M42+D!+2xn%qx&`^TCCDK#0`3;c zJx9O#>if5?-xVWi-9+gM{FU(0{1%j+Qg!=g@(h)6g>l2uj5zq&yl11zSU+-_fq=fdp*>rQROV0 zQ}I$mEd8MOvP?a}_dj~3sVUO0{D+dz+_VE=1B@{YwK~&R@<^;{(9yH6X!=19*HxsI8 zLA?WEy(W^f1(s*U%IB$v@XwF|YKo!1r;E(}BpYKo&2NpQ!Y6(k7`V3i?D9Le<8!Wz zN%w~!Ozu@uHY!xsU>{iJg7#vcrdtcS!r5ax_>N&n-;V;g{Y!`TPCB(XkJmx*u{aY#xgOwrBvHt`39 zvzaf?W>@A9>X2SZ$=DPx)r4g2L}nKTmS%zb5`+5@qHPZ z8H0~5bZ@nU^YmwR?#C!zaDE&g8UHD54a7V=_3G}mN?+}2yEJri<h2pl#GI&m0ICs;UBVOJsm}+{hiaEw5rmUq5j*c53Qx+=mx~(hH6%-xT%6 zwGPaeFp>rA?HnEqsVuz3t-xwtvj41q9EE0$TA5?%faGDTWT!MrS6x8a-3wM{#dl^H ze5)s1J%|!$73p&xC|{3(?yL#_Qg4ydwdfCvqVe&6(clnP(T|wKfBMR3{}#W=v$Qoc zY8Bi!dxXjSCr(kVUUE-^#ku!&L2b$dFple$IBD!0jr1&1ZIy9Cqv$!|oFZ{zx#b3f zP*YdNuHg0MX!Z~_#}>ewEFZrB*&0~q<;JuuwDDBYb)t{+G)jrRZo5C{BVZ36xKcaflST-_m{x=dVGZ$>Ku z0!;I)X#|sYei}10UF=R|BzOv129PI?m~Mg(41{_1@!%5a_Wlt9J>d60rkHyV@#@WI zWRnrHj#}U7kI$=JtTypl1GNWm1LfPB?J1v#xysTFLWd(V^+nvL>`otRJvTKvy=#u$ zw9_VUt{yV4%k+_TOxbN0_n^r+!gP8z<2(=q{E$@nxJE?G-0>U&VRvYU@pe=y9mdRe ziI5$6msVy!wyuW-#Xm+Ftrnthu$vs8c@3`9gfWQHfGM(f3Xhsi5Se-pZvZv|^%ikS z3@gu@QybD+O&F-KN9zu#z0E*g`D&DAO+?nSUma(Pn=PrT>=3u=0(Vu6_wj;vIf6e?Na$2JM?e@M3~&)!e`mMl9Qd!=0>28m3H#3O*SMcHQ`C_4)OF zb%Ly+zc8LnWdHqFh~Ymt;6E@S8~6W&4F44$ll$M|W3qGnH~7y1IR0PeW9ph~vUFnj zsEy6=N@;o`pAu1tpF&Z|`+R>BwjRrk!lk-Z3SY6dx=p^aXr~8XDkw~4m?R1Msi|Ts zVRHck_<%Y2WvXrgJyX-uw+?4je(QuJ?Lfw}pH21iP38%f4LX$&vpG%I`cI)VY&`t^ zOgxnkLyu{jISt&fG0d406hS||gweV3<%?L;EC1Pk2D4{FhHS9Jt_OGow_IQZ#nS9e zF*JB4ZTetC>9$=`@XNCzSj=NrF!*udz`tf=NXRDq&CTf#=keavBJoAH{{epjPwCRQ z&%1AN4`%#Fj)&lBEt+dL_WG)rzE}FuZ1_-}#xF@x+{d-NM$ZCXLy;4`TsAC% zU@M*jbtaWs<8O)Xgd!#fy|F`BVu)3d^5`(ALQ-z(YiO=P!+TZTp;@~+E!jz5so_MG zL7|eJ+ZAqe1QCBnj<6ilO2@2R>*A$LX0vo=O#vkr=xvtg@$DZk&0<(w1|k5Lc##n9 zy;6ncghh1^_5`}dU-$Str`P>qg`q?Q&2XLxLz7C|>T!5}6g3VWB_T;7w}@w-uh%W* zuS;nCtFyhnnMV;QZm5bmk%QNA9v`EbXn9R-0bAl9J~;F7L+=+ML_1xo$6;HX&QYUA zPXgtT82FMuDqc+bon1gpF!cBGP$jLNZXND=-3&lKaF&r^yn#cLnR$aEjLt2abnH(0 zhQj8~`cGb6+VvQR7H)>TL^@_J6g9IpZ9DPYEU;C*JL}qrleZ89n)u~cxD)_YF~|gdFWVH*R*ruJoZ**riAP z;7@P{=Qn(Q`kIQfT&a9n8>dXMrqZ){x^^}+PLhEtQFJQ44BD^E)X3$$0n3>Ul{R(j z(7oOk1hdA5sYxilb9kx)U$f{7&D|L+c6{jA0%n8eh^q4lPggUd3L*Xsqp(g_3sp6h zqUl8y_yV@J!@?|Q+D<-{PgE135(k_(bTw^2b;u{&v!tHQY3K(batb9vJvVgMlnK-n zzTQWbo>ZT^^KdUs&RdLT7*ve%Y~G?2*)SV;N%Y4A6X~C+4Q?q$!9a?1CzUpZPm-~1 zsx@u{*Z*xwN&xNy3~+cf-)nYD2V89MH1s|O!g}uujx2?bji(0KrbSgcQ6`o{rzYZ^ z6-$P?PeSBRyjop-Ozi8BhX|4@&1-QYg|(3ib+8Hs{_Xtl;c_KDQ_(;DgtTnI#drSA zKk5IHHBC#Cv#$&&t>w^#DA8c6l6wRZ4~hy}s!-oN1vnIFPE)g&Zj+}h7?8fR?m*WF z_E)z;J)%^NkEm* zIqjv>1jZ=R+|DQ_s?9N%>QW7gcK0jEfZHV&C;HJIN(Y728Pf#MWl8w;T~3FOkgZg8 z5FNa&`$kIQ=jRzBev(O(BO-ZtWjvj8lh=GEtIY)f7GuPoTW(Jb_07`AH~N;64?S}- zet<6pY?v>k^dYgG|D^f;LVjYCB)T68=S@z4KsFYQ@@{1^?*lJjL_EG-?6y_P*^%AE;8pV+x9$mwKBaO4@rZHn z$Da|r=+i3~0gJTxSy?2atijUZlxT>TZ-Mb{Qj`}qyW z+5k={xO?U2D#xtxVil48{oDw5I-IuPh`-BH!S`H+(Ssh?v1Rum>xl-3jwMUh&k(9y zpI@;YJ&>rjotf}n&yzYOx)?YF&vaW`CP@`TI+Ux+M-yg^n|u95h$Z3uMAkcej@!~ z(Da9ceE6|sue9s!)~wxKky<>P5OVzLykMtUC-Sl159&^B48Cf4_+{Cq+gTN1!?6wk zPZ?+Yxv-W1RIyEKslWR$)r{k>zn5Dg^a#S|wWaC2%wTzPCv6#PIk}RiA=n zB;GWZMb{=}n!+g(QW5z7_4x4Ha*K=o{T6b)+hQ~~;@kNOP6yx@A)Y85DZL>S=+70u^|MW%vUSygwwy4H&g2+yT_TSZs|h6=#JXv!74TCJU%mvIA$r*a%+;imN&Y9BNw;w3d=^H3{2s`4CZ%Y<-}g)rJ=c!B4x`1Y7J z$xVX!1&b$GNaZ}bwsA%fB)aX3U^58Sw_^50{GsD{^ca6d%xe8TSM$H&E)iKE6K!$` zswXuj9`Ym2u2C^Dkc5}R1MgsC`kwmvFMiK_rwn|P#UKwZ6GHb;zCe~-{xCQT`{soE zfZQlPn)p}s;eWD*0o)Ld|JqXK{8!u%&VPp+!ovAK>O&@g=H35teVF5+sk4ePus*;= z3l&L4^g9}ag*pfhgais?%GikV`rR)=vvIl=lWp|JY2%g-JlQcKZZv+U;IC`mY`v83 zuebUyq!-a0!~lJArbpk;vu`eC{bz!{g@v#Jaz7sB;rICMEva4i2eePJnFzJKiRse+<5=0*~ zCKN*l5(-}KPk~1!jI;v;)2qZ)M;J4>2N@y8k|9&Zn$h3iUsTlJFGoYL>cm?SRc}m( zrb=*uTNp!(l?<+B?d3)U6&Q{JN@Ri%SJ&#@Wv@$@Dg(&rj*cpaJb%!f{+w*3`gmN; zyJN%=$2D^i!BYh>@vV2^*C3%qkO?1z7pPTbtNm(xvn+C0vTo8jK0dy5g*-2uw`DI6 zQFC86%=ixen=HIe5T^-7GASAfF7NDMIT$EH4BtHb*Kh!_Cy+|2PzJ$#5(8OR*V(Jn z_xtYd?Ck9A?G57m>FMaLZk=y*$Tepv1Y5T_8WQ?Z72($4dWMTARvyz5OeDdl&z}Ki zxa1C6IbIAB&mR~GYUk?e>+5TGcNh6wdg*?Ce-mIx@6gxX*v6$HhlaEO>q&iB+Yx9q z%cVs1&OA4A6eo+`W04&IuBybiFo7A86&9EEdN zJ2$U%#jMmLMR~ z=`UHfF4>sxB2|gCH#7XoAKeV3=Cvz%+WvC$cKG^Lr>+35*Ob729S>D4dNiY^xr_%w zmWmX>mU#(#(-RSLCsYeidy9SJj{%0A6c&!3zx~_Bl>nQPb{v-Vvnc(+F6Qhpf`SC4 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

    L`59wqzEOuhH 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 <>N3sRzm z`iBII(0f5dn7FjVYI1D^48bcR2^bLEGQelc>^yaP%TJ+tlAe!y> zDew1wCh40FJOJ*O$HhBQkrN7bgo1)0ew$O4VM*FLf_gpW8Z$whx<3=F8jbr}h6Bbj z#^WV{h0ayx?D2Kk(~fF$cIHsRsy{qYIm1Zdrfo$>6Vh9~7hQrmA-zR&%q{V~T53i( zlQ_*t6PGXI01QRM(bU5DQV&u*Gq0r-ZIv=2ipx7Aa|$WDZ8fKLta94|^ULW}(l>gF zUkUOpX%NMv-Wo+v)GyQ$-Mu3TcvKzDrx-)S#g698QX4#w0%J`-4y!N&daJv;q3qn; z?gXx$`DX=S+HNj|^e3vDhzwR5U&D#~I()1Z4gN>lqJsQ@tcj0I`=^lkcNF}a#KO$X z`Y%|DnfaeWCi8!yxbT12K__J?F;f~j%$+`HLW6%Y5 z%D!YBe4~gTMr;L7*zRKxP(gtj);kB%2LpkwAgHJ;<1bvDCJ}@)Lb*A?6jb$oVAf4% z$uSm6y(dE=xFIDawB`c=~n5leDg=Kwq5P~hbd zOinviVb@{Uv0fwMdmWe2t61bX4#MM?T$Bn|);e(S*MneshKnlq@`Lg53`z)D+;TR$ zb$IuWS$FZ-%6`Z+j55Nhg$U;b*VO9q^-m;I3+woXp+-O))0&M&_?8!{8MOU&&P_(_O~$8xK?X@@jDy;6(mEoZ}bAzrK=%_ zRXbe%?}o={z3`03@)|B^PptQ{9qs;nNFiLv4|5gabJW7&eiJ>7@zw({w`SO{G<@0` zNl}1Tqs{t!i(zLi*MXV6|A)7C49+Ba_eEn{6Wf^Bwr$&-*l+BKZA@&N6Jw%@lZkEf zeRJ~P_g0-B*W4Y`!t3a+S1xgNY%H3b3Q{1tbn+x=bU12hjfM&o z(d;^5xDo{AF&krRT;S%zVa`T;pdFHO9f`j6jv6w1E<4ICcuL~pGNf+b22mk<5_dapfw8MfN3L9nvH<&3Tr-3{J>t#xU2BA`1r_=Vbl9qHoD#$Xz2G$73xHsTCaV#Sl|hIXD$f6 zYj5xWbbj}k8b}ZR&!-8}$9sV<=&_prpXRLpnuh*AnRK@QF_X^zf09Y(`oCQKlXj($ zMx%sd|EC}K{0~eAL;my=Royd`fX~4NW^+z7vJw(fg0#D;shaKm&@%RC@c-UEbAz`i zKsyEq{#2sE0q0PpK^p)V!ChN{!K>%U{acAWZ-I;FUm?dgl-D3{GoAQj=-^|WqcF%I z0E`j_i4r4?Op}~gl0?3sAUw?u#qa1QE1j>hS)1iq%sBg)b(1;^!+7?ow-yEKjHgq4hmF{{SN7S6JK6nL+hKo$h-`{QV&xV&o-o;!Cb?3jB*12QU_e`1? zUv%t~PsbxX^6ogP4J#G*#W(|N!#!T3h1m+r{5Nuz!;w+1dTFJ$p{9c4q8LNP105xe zybApBZ%MT-@?KAfg3}pAAPK}OCgp&16*0K2H5>ohNL0PXn7Wd?BUp?y=)E9ZZW0vcP{!=3DWNPM#N$$aOeoiP5j^KPi zv@w_5`pFP?w%V?#Ya$goIZ=rCR%Hq6ISKu@ApC_nxB_fXQM zHlCGjyaOFaYnYVjMKO6aEj9%Gg#L`vyMsK5Cg+kTasiwb4}O19c$g=vtOiiW1Gx7O z`Mf$&f9S5OK$J^CvF}2oYeA{QsUe|02@0O?74v<>mJ!4C6mJM=IAy=F>FG8qv&faB z#5`aqP)$ckiP=qCuLnXunf7sTTGSH3RBUF~2zCh-+IG~}(4MTr*m`h3aB3*+rqldX zno8QGl4Msvgz-m-qIwKamzbmLxLFS{)hUGQpxZ_*=3%l^a8MWWcMwg7v$ptST6D9` zGMYOWX}4Ew3E@#T*^r!r+kgP6q`n~S zgtyy=e=THjjg}{-$e7W5(xv+BtM=GUnu=7uaa;vA;S%F}CumP$W(jM@VPX^2bk9kQ zv2nba=`rUdD`_K9RM~aa*>C&R0`*vN7$VTTLHf*+5P%wZafsQ!&b?~jG%vtl7^8`8 zKQhd-aqtAv0&S<)=iQ=0VKGqP^3%-d!2h#-<^==5gv|ZFw7r}x+}vF)O&$Mt@b+JG z-hah(EWH2C6_NFSL`SgxpP(cDd#RC?i}(Kqft_3)Z7U5a+3gQRGL!@xTnOdF#FsDF zc=Z`x1Zgh&UdmA(`y=>Y$MSlwm`=?tulHFJGAI}*n7-KoV~p+3-t7-$7|cG<5#x3b zS7B#2X7tt7l@lD!AZ5DDuo?P57kU@imq2pTqy<|glxaZ9i7`G(#V|&eSg9Jl1;%ad z07MlfTd7|4Qbn4p#d!wk&Djv=iv<6duVmuOE6f68UUBnxKS0tfOU}A!-2o?5iZ0ae zrMCaf3uYfVwHjHgeB-hO|8LAjM`V;-5i4&GC}`GpzS1d_QG`mQ=5UZMv{=HbR(_c-l>N2gqURM$Pwm2opvM!{3=FVeial+Z`jswk zW6x3C#oa}mKRKgRt~n$4=D=5)>X`?fOwrBF^E>FQcf&`rDehrHj7$T(%Dr;!^7&sP zBSS!w3Y?~|G@L3j%ys>U#wxsp>K`xiSzkXEO^2rl5}+sNw|l+TzwEK&%}j|<8YCqN z-xIN2@vkdWBoEdKXnUTdQf`A1EsK`bohyFCpZ%-i$}^ zBfBU&Rss(KW*MBVz7XsonYQ)UOs4eM)1BJnXm46=KnfC6R?`gbbjQz-8G*RDhi$mL#5qQ%|P7#gs5vXxr-ypTDqp?Ixu@Jjv zqZz5|M}NY1gqTvc!Vn?su!gn&Xb2!DFF`b&q)+mbS*X@pkz7Aolg3&-Mpkg(kieNb zBN+sc>jJf+U5y9fO-tle0-VxCv@WxpDtj=8uD&D+{MjrxgBcmqY&lKe#bi{_oA_D{ z;;f7tnZu&a3T9{QSg$xw(f|n`KeigUjBwA%tcx&QpxKwZgc0hxzs0zT$&81z3iHX|K&3ra zqg|z>B^dkkL);-`Bu)G|3>IjvaMAQ>hnihEjqyAuf$o4ExN6aFpt9-6FfY>~z}Wti5ZdI@P?WN9uge_Oo_&6FT#&8!2U zsb%dMIp2>dmyicQGY*Q6ow3-Zx>mY7(>Hu^{(*2fW@1xcn#3=nw3>E#6L<;(@h|Xo zt7oX5L&Zips(z?acHa+NZ+tOP-$0HMDr&q2nkDl_#C*Mj4$o2xl2(gh)tl{J$rf7e zsxpG!msX)hV>7?zE3SikC{X!AAf8&kyk*Q9jR?7Nejg&zxGr&TKCP#X^J~1YI;`AH zL~UO-Y_wtOGJcsBRYw?Xw2wB&+kdfzAG`yEK1a~uB1$G4P9KTd)RhZ|rbGCuHD}66 zD2haa^2UzueGTGktFx!P?+U@4o4+J1hxcxW50ezE?@FcoSg7B@^y53cP8bTgFIw$J zjurSi^QegdaS@PCIjYUqfg)7{Fit;U%`2zfK!eQHU2!3@CZ%+Id99*z5rs1pR)VY2FCtzhX**bbYGVj2pf2rimlh0Im@}7JV zgy`v|6}#rWdfuYXlATwnT8-5lJ-0hVP#B`f(M*&4{jc7aZ1ZO*E|TzQN^>Eu&eW^> z2P>gV^Fvo&yA+*Y%Qj?z2nYH*$?oq(g80!Cl3{ng9Oj*;ys{Wm`(C|i>qR>5DQ}L8 z_VYLz^L87^ieGZQOqu>)Y)*F}V*^6@s3kjOUXMEvYvm(+cYifDisfw7$8j8a1=7g`g|cwZ z3932b&h-2I(!_qT`i#_OS$)NTW^^0!T{$t3c-wilkmud}sEfe6E&iW<=ZTL-WWeUy zIWXfhNZB78TUZLZ?&UVD1gZ|I?uC5-@GDUpLi+=6M_6r~A(#P#bVEXSkT!q~fO$#4 zx|7?95r+JbM)09>87Tk-}#bZOut%}`B)t_lBNpn6Fc);FY1@+k`BGGpxlT*7xp86=I2@; zXLS*kWD)CnZ;_2amYlF5??R;oInERBpk!Aw7VuSkT+QyMR>lemQuvT|yb3MuP1gnW z7I1K_DF{I+Pt*2+I(Fu&5X~eK3iFp-d?dc3GbtIO3Eh`zpHlq_K^-AWsZzD*@00o6 zf$?qYojF?;^6M?3(bw3g6Oz@|cF=k3w&`7c zzN6T;58O}>PvgsU5Pe)pvAb(ARsWp#KM9!xXzx=eIjRCHRnh~5;sm4 zQID*CM`XR`ZhyYK_Jcl1gaMx)!1MM`;OqPG(kr&@#kYd@Z;+M zVF0KfwDIZx`bzS7e>?@c27n?X|ABufgc-B1)pt#p`SqD?c?+P_3Y<|SJ!9v z;eUGgWETDm?E3%#??3H7K4-1oZ?{2yhQMvWr}HNu_T%Nl8wk96i+j5U06*TJ?^n)O z3fc<*eg6V`d;NQW9|@mtuL(Z`fWY^+N6_2vuPl7;*QG#r_x*u=J%Eq9VdLLDfgsSw z{rk+2`^V$$?fq>1Ho(|O;kH0{JMi=M@%VXaY_{E)836oG%XWWY?84DJ2!{gNKN)!mpHo2suDF3@^8KLn1bwF0Sz z`>%x=LC<4f6pny*An1Jm{0nG0Ydrk=sMh|Ruwo1VeE?sdEW?eRYcCJ)9}idFH#TMy zg!}*f>o?M$DA?}r4+Mg~@=32>rC(=&o!_fBO`@{B@7G9|8tvZS-=0@8u>1W#e4ELc zoSB*XL4lyg;uT}#>jHbf&zFzK*SqJjsf}%8XOgm&>-)zoT4LZ!4iruMHuG0?B4u+b zL$eQ4P`A&&@5A@iv6=b0AJpgg?Z95XUKq4`|304U!oCmt&&DC#8&lWq zE5_HA(B5D7IOC|_=G{Z?>Gm0TxiYq$K*G%I{PW@V>6w}8>vbF=UENt13jCxtfm<-e zR0ay+?fIQOtl+dYC=;;0z9(e#V?EbvHa7?(-Tvh2?ZIC`v3ozy?E__h`PTT#zx%u8 z8(#)h00Md_A7&F2ZVxYEb10Hl9^Wlu3hFtYdU=QH;`cJ8`Bhavzre5DJcK%iJ$y>wJQe?i!3kZXH zSQsL@+azEDK@A4voq+&h9eSQuad}2};6J0haYS?K_nY$Di`Nxr>Zdn^s~~a50+N<} z2F!BNe(td;=lkGDVP}q$8R4_z3K#^1$+ZCL=ZtR^ANvW5E${XXH^we!voyIcz+>VM zli@I1N0>avz8?QTHA6+?2{zNdk5}N?wX-k?1ac?s$2^*PIyuSYq!jvizi$V8-rrx7 zWZMRxkG*6=g!Lqyw+1wPGB1-jD6@k@-hcW6Ck_^i22Z!QwYIUYYn{elpHc6fBT%1M zW+H#rd~%YO*%~WN?1B1JUzu0g0}2>F1Hm4sO?0I?=E2}fLz({^ndcusFZaAZlhiXC z=Na7$ zWp6o~eZh|+{N9mya#;$bRwBOM003AdrZ=z{pSfAW8;7<#-Y}k7Q z3ZTnFJ_*+{8nR+oe|||TK5k*%%&7hQ#68|8I+}mFCt@zV{V5KA z&v$wLe1zw8P)kK(z$*9s?tE#WBq(WqoUuA&3MYasH04Olx#x)Kfr9i9-5E|mS$F3 zKp?MrY&n%@???bJzUk)ay5{xXk^W|+e!zux(sesxMF4{PbHgPOC0%*c*!jAk-zbor zFU}g%KLAV@_x{!TpM%-k-XK~+5Vk6=CycR_4{#6&qOP-o9?75S7wMfn#hpSaKz<(d z=t%_Evuk!$%x}fuZ_jvu(eh14 z&H|@4(_1&nc|@+KfOB#c12|TDyr0ikY71Eeg;zC=k)a5l16R*`{}xRm@9q#9mg!1Zm(Te#eAgfIXCz#W zgoAek+~SjZMjRh zzUlDqTt-4Y;kP8z-!nKPHJ6vj1DF-i1HqJ&Xo}A(-o_;1D2~Xgracip=;1o|qvo$A z=+hH}voW8=tOg#_S4*DG0hx=|O0eOSv9T$HeN1F>o57;lA;0%#69o&$M%%GAql0nl zM2=~xUsWQ#4C1a{r_w_NuVB@h1D3scM`a`t?0>OCp zvOph_`4?jKUcbw*0c+pC5|I0K^PkK{64W7R?#jjfp5LJaAUWTcn| z@rQwdo3WbNW*)o=P}FDf@y5tGM9|B%Jy!p2m^V&{5<7HIR~j5##fy^% z`HSiuv1CNksqi%}m3GVSkaQRDIKWgI=JWY7#kyz#@Q?RK`s_Lx`PH6=TnW!>51^~t z6#4_&O^~53cFo=|R@*@!!U;a?`S!Fh!fTJJ?QUb@E@-`MEa!V$0_qLj27cMlo?}L} z326>w5m!su&_6+2@briQ;r#n+=_EJ4v9mr@SVT&bjj^20astreBqHBU`}O|kN8WXZ1Tu!EXV}jjfw8 z;$Xn57a_pNIIsbwoC9HCDo7W0kZ%EHt3&5z01-PVF6Hl2wip3Qu8SCaYIZU-_0w}& zxzKK}oPlnTjRmWSA9iREBg{@Am2(+&{g)qAxuS+fi(&uB28QJ6_vhu9oElmR!Emq) ztX+k;@=GFZz4F-wgHv-6H$}{%yuSYCpU4Thml7_x75unO4ur5gF-2?(Oc{mX@{W~v zW~k~iMMBc$w`}4xP$MI>>b8v)$Z22R>B2qWC=R8YjXn`B z8-}cz0FpeI6B!DVM41|iRB%hVo%ciukgPtain>=|A{C?H{_vNC)L_%A#>T9bQ0E7C za(F4`A$X~9Yi1WTrYDxr#uC8pwsRUKd1bFd zrD50RyKbR5Y|kC*!^w;{O7}0x{Ru`si*xh!%;#)2Kb;49b!pWyFmE_+YaiQLQ?8D1 zWq^aWg@Z8v*7LT3&#YRlYueA}?`jFw2IndtGPWw6KX zIu5#UP<-6Ra2I{(Zyv)Y{u&&5hqw<8LV{R6bm%vOb8CTfr&CreC>5tMpOdzzA9~{5 z9sa)0F_y`p2-y1fGCSm%MZ&guM)^yD+QC@NNi`>F><}Q*)~vNQzTFRww~@NQ_(y?2 z9-~3AG8k^ymcm;0b&x^Ebf;u2eZaV122#dFM<+m2OrZ!_fq5dci%IY6!4VhELkvMnY%w`+O6pQiuhs?~4;n7urKd}(- zdQ7&mL$2~lkGsZkzJ`$FVPA(6Ht>r4f zi32#IVs0dv>kpg1A<8S7KwpTyg`(vp!iEACfb=~=RL;r5O;2|o5VEry3sdR;eg#3qGnhuKv1{=|^lKsZ_JGv^@E|N5@__sSb7qIm} z`j13MJu1#9azGEzBtyYgw)UBdipMQTi4(cF0L@AlYo4wrQ-;ov=H+(LR;6^eLO>@U zbT~#MbIj0=bLFTviI-{qyEkw_d;@r}7^zqW=Ubw!&_cf@F%V_;DZJBX`%Up{-HKVC zA$m*5d#hZ4z*mZYG-JUeT7sP9)Y=qCNdL1gJC-Kp+U+j5w1)L}VzN+76vyQ-H` zPv)ok9o)c$tHK(YT}M!2a@`tmtBy>)b?$!P8+LNkW0WQh)!HT-{S714z*vG-S8c=d za}Y;eQg?gtna{M24dn`#f=^!Pqm#G`z`U;`DT%xsxT1N6~G?KHHz zVah%w;_;*#*`OkW3%%lBEUd@$J36FR=dPKU2YLD}sRn)Da^g?jb-XQ$!=Oo3W+}s* zU%qIh$oZq5pn@lH0r?>ECGKi+xR#{R(7B`a(J;Oa@FFNTCyMd@L&8Jk=}+Fq03 zTFMAj#tL`IareXvfDCA4Dpmf{pIpInBP@3C1mi@Nba=y+tQI7R_7tdyY z~I0;h&=4N)93V8j!0;U3OJEsGV-=IR|sU-aa5W<+KmAs2vG3B`SJ)hAe6VB zbw1zyCR=VjU8E1MVk-pOSEr&gkTxf(&%OSaG-`Smfzsp?42nGisbO0Np_4wfb&%ob zPD^>cv1>Gxn0%0IO&tw5ta|l|b_OpW9KN=N=*iGq<2-Y;5R_Kv^g$LR&rTQAW*B+; zH7lJ@l``%^1%Tg2VyLnODw=aow;sATjlK)~Mn)A)CI*LkC9C9Aceq_FJ<#}$mL_)4 zV1L3%x^Wp*aUyHtJAmSJ#ZMn~L2`n(`7O`90XAGSXFIxB@W7B7j~RINO{$dahWcu` zxduFQGWkA5#pYN{&r_Zt2wPn#MXpLUa82azr5{O?J3qdcnp#|KmY@`jWsxLCT)j1u zi`8Y1WgQJ<{v-E!${RZ&-a`%7oGBmP1z2~lErYvjf6!H$QBT|7{%#ci_#2uxm;&~LbZg>P_XQvfg2DJ64xTeS*p ziRG+%c5HOFukvbV&zeef@bcg|y(aakN5u196g>7ZFn( z8Ep@s3?~U0^Z#xN$~P9`aRx{+eBbN$?%V6&z?psNVDv5XU@A_LpjY|+x65Ok_PB7k zfFwcSMgN9!<$Lr)0L0%L-{=LD)W&F6d|s65jz>s^3lW0AA0^#F(t=%y*ywW2aT9S2 z=;{7`dPd;ojYitS9j(4B_aBRwRiVTR(%=sn7~xCopDAc>X#i1V(ftzUse<%&ub6VC zO)V+;282bLpE87Nlj~D5H`BF0=k~zwZW}J_u-3a64>eNph^In==Y)PzqR4N@?2>c1 z!R$%*nOcWmVA-9uGcL5?{agz!!57)_+>L@V9Zm6yX>ec?>(m5~s9PE0<;GWYyE_~k zNM6L;gST+@hd>;+M1Ugln%rvI)%c4=x>Pc2mpPaps54g-#U!!lhrXf`24@0>x@WhIEx^`{|$gdd_C5D?o z`sdR-J$7!YiNvou)kt3H;0c}^JWhaXPQtYf68F`51ch?n69q_)h0TxPMzdAN3Poh+ zIAXUb-~DUydOgONUlmU4$~Y=0*$^=(+D-#a7b#NsmZ`NNptr4n-fP#FY7+L7j$OOd zrWkJJmYeVKPaVk2V7ptZr21l4#dhgHGy40yEUx~={VxSo9{9nezt)ze4nVgwG2XgS z*i69z!o9QhCT@Zi@`Au!7}o+{plTr9anJFlExe3OwZp)KJR50B`cgv5woWo)9%Y+O z+kw_p-*n~29$}wyG?S&U9NS@-QoNlQG6fFPmiKH^5{hbj+Q0U6Mu@Au?X|Vb*ka2e zCuXdwT*eW4rq=bJp}hgCfzvseZk+8_yMos0g4VnHN12FTSEb9uOtntLMisa2M9&1|Yl6szw}44UO|6#p1B90aVQ7ONwI2=fEaDaduy2?nj}&S`q*yqyQo!|H$H%v0|N zVAUuvtLL6aiV3gEh}-mW%D+$3aT{S(CeLSFaqA&$o|)LOE?Mn>K`;uf4-ugl2o-`t#QC z9fBdMRu8&LnIt6X;hh2y5BRucUD3*g*6u0$1ItEdw4ZwV$T zv|EdYYvxbqr^D{3IGSA+j$+Kt{Gc9eCL^U?xz4iNtmA6}OO49pO?aW@aLfus#799knWF{;_8%M7swM?VM+I8q}ZC#xb=pEJJf?)_uv{{YGfM6SU4D9WllKgt%qaSciQhr1{E{kRhbtrzhb9W>-d3Q?Uo3b0C6C{B`YWFi~#n9(rh z0cx76v334Wj=Xq?#K{V)AQaIlfnVb66-QwYXyQ4AE$?IHL2PRNc#6<@+&@7xO>vwfM0nP2Dt&X_zXSee$;-%&6#ww61y1X3Rv zKNaNF;&CMIS(~hDVixoa%m4!UCXTj{$=RAtjQDt66XV^gAJb6*ls24F5umMQL5Og^ zupMJra&+Bqr)iu8hbbk7y0ShQu$%@KUsz$@nrmK-Bv%ZlX|z}NNJ23svAJRIHomMv zoSl|V-_O5SJ`FRZbszEB7T<$N@rw99&!P_O%}q%%N2PME2o#UbWX($+w)iT40uo5M zAg}VK(#9f5X0yI)mo(5~%g#hlD)|f-H8GyKThB6=b|^`NxR=O+S>TSYOIF%fSCp99 z6`*`5Egh!P)~O?a%HP%O!?v26z-M*Ki&BzT6S8NB2Vxc1q31`)Hki1Tu_#UGhWqna z-*i1#XSk*0XumHcZLB&*EYq05avecSCvE>ceu&}CwW{Y(xc(=v+p=L)`e#aoPCNqDMLc(Gr(@kZ=%=}h%2la1CWqq?{42l0}sJlPpPD=eDp>m82_2O{Y^Qy^$bHu8214Q{ai8F`|Bla zXCrrCwI4aZIGqJ9Xtl?&$WCmtWDI34Z0-WNA;p^WROiCYYEjHrZP;E_uYR`i<;=Ud zlX}e->+2$%p!npsL6ojXq|tyot@+B2N`rEOPe?dfdv8{Q+{am?m;&`(Ov1#v1F4xm}+>gfkJS{?m`g^gBEnbL2?}j#y zpRJ+hpp_Wg@2tcsVp1nU)U&-FhJ>8!slKtBhKIc10sk<$)~@}7aH6xg;n&-xrl~-P zen9541I&)StW{xX=7CiyNwb~U%nEXrK_qw9O4tj6f$KPBY8Z3A<&Q+S?&IOtZ|`PC z+qVH3)^7hS%VfMi^bp&u1a|LETTL;LLmSVvNju zhQ>|amj?lk&o1yso4(;Ew~A|j>8F(Y+hklbwI;bIk`#+&X1t7LsH0nJGIHmi*H=x} zFu3L((^GO8qL-z9wkqsX8syq$NFN;c9Wq?3Rl3G(|KQeWVlL@q7ws;~%8Xc@?8AjG z`e!7nGMYzzKgC^rLb0wlE-;qKxQ{k7CGPLWel>v8-O_}0QaekPAkro1Ptl=Wrf{qq zGsjeP8tsu3b%H0}q04@xMZn3AuDyb$>1R;Y*oHKxnf$C)dydRBa)yb3RHw^E1G)1EF zkYLRKYeCc%RXKlbnRKRFUG@yldHB)5CTm)(v6PMHKvnxRW%@OmRE92}Khmn^woP)k zxHrF!BYsYKx<>-K)rWVV%Vz5k1dsR0Db8a$aJ|! z%ZV=91w~H%eP|dPM@)#HsvEfqXnPgUYXA zyl&Iw5nkVx04=PAp>L?OE+FXqe|fV?1zfbNZ&`fwk8xM*IQII>PX5uFOw_*>u16N+ z{@wStEam67@;zmGvSOF{ybU!*Od8TL$ZbqAau1?;Itck75`NU{W>HhxP_4_kq-1a6 zuF6`su&%$EYK~}*E=nb3YfIS2&Q#Z)gFl-8v5mv|Hvs7V;nf#QXrLu;CqT9sw{0_p z_hl@;nil=*@X2!p(mVTCZMggb#MXDOV(7)wp%9+#Ma_tBjS&^!x6#)Q7GrHy1_M`d z!}~ne*S?VB#4~fuBep%B4>j^VyLUue5b=3=MoHWZ;u+FL%UZdcz`k%dni0cD^5}n( z#V;FF#aN$*Dh<6qwPY=sj3ByhGw|7IoVj&u{fjf5Rt+A31l85X%fUdwW!r)$V*<KK%-iocq50HQ`=+RiR|`F>r=xxgivnJFgNrCW(Ug&VL-*yCi5oK|9A?j1KXFED zzKwK^Xil?L8s(l`wzN$9cDlMSztevi&Bv0}3BxzGvsFfTR>|UDJ>x_?9WZe`p1nMV z?C3+4x82#$Q7xPe{sVRAA(Ey&`Bc#jPxQCQ`nK zLP&b~uA;L4lk&w-9DSHLhT2(?9w7n2JPf)gH!3Ha<`w%2pK#nyvSTeK;khu@YP&b) zah;8QJqH&$-rO`BcUZQi=Gb>))TgAq@$N*QR(;LVR585cr({bvoh}fyUGC}(Qk+il zdb$geLYhQuRj0)r6(R3Ay~oH@gMhqc3$x7n&x>#6Nd8M$YUh_2feYI1oP3`Hdza>` z1Fd>LbxzOk$Vb~+Snx?%&Zw=M)ojE|0tSc;S^X1T^rgZkM>xwa?nCZm`6My{#KbtihmMI(p`ZFEC>HXu)w@J#pOE)NV> zHtjPP1!m;yx^bj8vzI&zV{{ojRhAGfwW^F5S6S+kmAf;e)SM(r-%)m#{+15J)>3yb z(K*Tt=cC&Eaya@i%tJ8>W|Jkj{9cL^rl%w0F*c&ZM6$%n-`1K4ZU4aKa1Lw(yCI;J zDd=c$6eDvBahY)WB#GMe6Yb~5zSnYfyHVSByh8y^4ABp+60y75*hWGudeW!#P@_1@ zmCb5VbS3lPlSOs$8`#=df^~fw-?RyvM+g=#B7QP${9=E2gBMpt-I_(I!Wx%zdQ*PU zDL3IJ>0LMc(vZvr!INOlXu5Pd_MYjnWoVUN=^i|DpBdVXhLwVcvsjiH+O-Dl-pq5V z63Jd!r{5Ve%VTXl9CI>FcDERjI*R*m4{J$U;h$SmFI>NK%D7`@W_7QD8xJsZe$wrY zt3LU0O>mFSLYv_=a?k>ADuFdgHp1<_uQg86^Jf0B6-gZp!NJ|;XQV6g!{?1Jdp3|b zEiEC`Bai&n!Q;Q;t7F@_lQUq+q5d*EbtTbiJ;1!H!E{(+0Cq#E|DO3?<~0yQc^Sbt zYrX^~tqDx-sxI}=!A%2tpnYnPPFG{Sxb}?@?H-$uu0nAUy>us7^&SZWt^lBDWH>Ls zxvN*2V@BS>RWHReG=0H{W9aS2NyC+?9BWwBU$N@C^eYK8*P`UK`niH0Tfbn57I#EM zrv16n|BgM>cf)j}mT0f6uZGK0lh^y9vD%>*UYucE-8UA@jJNjAbek2z=0z2E?Gw8T zmJ*N}Zl~vVmrcfmsh@aq9i7F<6qd>*_bWW1be`uR1(~mzvypQbgbna!JF#4|;5KC* z_-}vEK%(|2rhl8vCW-hOV0&l3Vo;JyeUdslE z4Kh#T-^na|{WF)@_~pb#RD;P@z=v(BSp4bNfPkH~urVgv)ix|!S1I43zw$3aHS0*! ziryV1wpe#-PGIL3wDN z?E&1oI2#2URDC52>EM6-eG+UJ(qjl~?F)=f}EVmHF*Dz=ReBxteQbSwxZ8?om zD{auAg)wDJwhFS>?W)9Mrk0TN)9#B0l%-xW>A(bdeN4r}_7a6F5Jn7M%U-fP2pBZ+RKn00&!6F*Fi0@n~L8@CSOur9+^^ zlra}39`RmvDXqUdS4~t4%w9#=5Tpyez7a<+mNaa=cGF6!`O2!J5US)h+Ad7#M7*VI zm~)l{-GdW-E<4I9HmPq{lM7`3JC8!Oa>HPp^MiG1{}IliOa=k3OEsX_&X3Ut^}ikXZ~G6l8AR>`_zre9(pf zNH1x@+yZ<}AT35l$)-6UM*)idubpOHV`MGDn!C=x0}&c%s24wQcXnM<5r{g1sX9Il zClm-Hb&~a4yP)5%+6bNW>DZlLns-@(&p>t8AaJu#nEWg4cb%8 zi~0{elAk=mWkj9YCX2h6G<-|wp*GQhj050zG(MX4&cgH2T&>GY?}=G)p%(k0QTT8m zw&$eFaqQ$05H{w0mq+drcTx0Pnbz3?@MlS7EDFbei!oxxZqyxWcW-<8Zg{re;BVxYrjD-9pXBlG8z9B?c2`-xrDLP6hkUB2J`W+g-TdFbOV zzm!-X$;{*!50PTweHhY$A^P!OgnSGDq&1&-6&2u|a>ByOZ z<3F(WeXPhpuZunpLD@@K{-J33xC}+*{Ajk>;{M~J8IBe&9fyuBRuIm}i4pw1G~9y^=;$r_BkU+CjmJNRtC4s$mNhI7d?jaT zz4!QMG4D$qejz=rNEfmBul)6jtgBp^&rUG+8(w)fRHH13wXW0V{e-d3+NOg;H)z7R z_qT5DO4TQsf4|R+0ueVS^AmLEhLEB>_=SE`@Cp%gmu5Qe$SHRK7f7l`ZUhjY*xB_ZbcoCXtL0OM>hbRkUSpBa% z3AY%we}`RX>7BBqVs`FqUa^L5Qd>va+uEp}T+RVHW8D*R9JM!^&fHIXgr7EoQ6|hQ ze{&N3gEZ)#8yhLPkLY~a?@pmbtzkc5FwN(p?hXn|0D$`%3ha|5L9kW zBE?&Pah9w`#Cl(~PlI>&C znySdQDrY=h;B6%&cMO4KVu{5c1u7{wRnyeH=hj{_AxzdJC#gX+y7HO^rnX}j#ZRj= zf!=AAgw85%SfvSfpwf%u9}&$ZaUEyub35!C+XnB>Pv@e~!>$~;yIa>}{Q5{{Bu#y~ zIkCrppmQnO$z9iL_kPw3br^csE;PTUUZ(0nHMQwoVbW3=n#As5j3&ZJc!D?pvSwPd2Eu4LU<_``ii3ajU|E;z z)yvo$9@hG(M(awQHWn)wk;jPqu(|PB5f5WY8qlkp`kkXu(EW zt)|0gUn_{|McVhEyEUgZdH;;!(*J6 zP`6N#aQ9vSkcfL{I8L|+yC^h$C^s>R%8G!(9^_2#q}%GW)I~CYVO>%MoMC4uITlER zXmQ~^)&(M)hIH7`nk2}#Du=_JTvL~I*9)nd9rn3=!YhFK?jtU0<-J)j_J{D`HOUGA zxr&Gc$kpRDvG%)J%E-qyyWem}FE0hxD2P;~C~Qk`Wmf`1R$6#@4WgFKr_on^+a1(< znmF^@4AwB_?!L(PW`u*4N#d24Rq`N>o}{G6cdbK{SU;&p_?Jq9xm{)3gShh@>RzI0 zp$ZMVouOB+KGsY6)d#a%7hYS1LKEnG9_(#z2qIqbw{1wt;N&1fb-oFROGLK_$-=)U zcaHu<(|OIl#~i1biG(6C2&|XyZZ>O|BTNSNF!}S!FYDo^;Szolej)lq2Dk!Ji~}L4e*;nbtxV z$R>$3K|_jt6gIFsLg-xqeyBY%x}qzNoNs9D%uzhv@#7WeK&;q8*Gqz9cGw;k-Z<&w zw;csDCuWXUUSeaR12bTOHkezJr0=AKbOVTM!nZpze2oX$swl^BxmN_v2Mbb`BF`b% z{yhj`_h5nRjRl+*!Z{v(b7R5UK?aUqM@daJ^yhh40|d2Usl zrA)9EcPVtoNf_bhdR3!S6-%6wa2CIdr<#$UghQ?L@wbnJeDEUVnFp` zy5~9Z%8Ph3m32+>faGwn*F>lFg1SpN=_TDZeQvPHlyP0a%U8kI_SiMNWmMUXewz_c z&y%sOM}#hZmXa|e(!N5#3V3H5y~#JNm&JPY#^`4*1dWDl9auTJ69Ni;y-2&$@gl`tD+HMCV`mrO7pAV4lbAQ40}@i#bg%pBWz9FEoh=Ka z%H>?QE@3XK0FxK1soEB2ws!EaUlpj33r$%?1-hd;`NwS<8NUlLtdM=)0)kvxBjR^~7fUT0CnS6r63#}6l4mut9ci}# z#-ng$35X=sTdo7w$mI7($~AkCvL2{JTgQaq+~W^H$)yDVeV=z~EI2!VD5KR|g=`!Nbi0VaA)#r>T_A9}K#sd`tO=o^U>Vn8LyPi<6e6_)g9V7*) z^Y&N`I1TjQ!rSc;_RMih!b=LTi49*bI(#1|E8o;7wuIxma_nlCT;vY6^3?N~l*UA( z^RY>3gT4LeLBw(gE9XgvHCWZjsyC>%rcm$%!)O=d%i5!fTN7%tB#FWi0&`7$#;K#Q z(aVpO!ETw#zR#M()N^T=!QD=yh6NHmh9sQEcZGQzzV8V6d}P|djm&)eX2@z02#9># zw(LWB=N<)fS09nd0`FUuGh7%H&-asd4SSK@-0K>7#UFOE>J5;88@j&l}%+=C-p+sX*NQT~n-H+cMso3s|X`))w z_}+P26+t+F?(aci@FGdOzrv+-uUf%oY|3e=;~9GMm}u6`=n#r|a-vT*QEGk0sp;Ei zmVo!+v7TDCRP+sr?lEU}BN0&`r5FD+6_I&x7{0?*BK2g-j!~g{b(?t+HEIp!G|182 z{<`7DOf>aPmF+LUy^#d7(=1tXT)EH36-L}hg4*g=nlP{v440YWqNu`@Ta}@12?*Pz z7%Q}d@OlZzPFCdiJScN=50>7#vA$`7f*Ysqu{^^TN|)o){&3TNwj;g6sriak36Yf> zE2{5yt|spHw!@L%rj=#R-xrw_)9FRFHx|B?8fnU}ZANC05ok&&uZauR&`ZI0HjF-Q zTYiGFrSIhiOSfoJ)ww0OLYb{Cj;^53Y>es*pjyzS2l8zBM!=aGnC+n-kUKl($UQ@32}q7ytBv z$Pu_U^*z#VO4Uo|=9y1CTX9d5_;LFao-YHV$!*Me9qT4V4dqO>Chv)zCX}we$BM+a zaske{TIsuyrGDZ|xY;o@Z`oi?q<)g3w0Ful+3B8a%2G0Vp)otI3IH)SO#-5mr!hk; zO<~H`B^}h@Dx8Nzg2%Z%P5I+3fijgI)})3yeW|pWC)5Po$BdM2?XXh@Bd1lIFT?3-zt!qe+l;WAS)}Zklk|d$1bmjU}|4ZVCKla@NaGL%*V=ftcq3=w_Ur zwjn;}5srj)Zb6e6ed;FlCa`g2t^|pvw=U^{0)9=srnj+BsA;oM5dplWl1>R{mm{wU z_-z*|>u)~$)fUNN96M9nACc(x-aIw;@-q<}UOg=&AjPGB})*~jk&DU#!N$*QQ; zY#T{3X_{pZ4!@P-)fcn`{2c^*YGw-juWs>#T1&ne{|bjwAY#( zXw2M5l4ixKn#8-e?$VDnJZ~+f66d?-&9+Dyjd3S9rKwQO?s6$FAi|9RyFMNM!ZnCvAR+-yWzB8Lk}AB$RKY=KU)Oqez6WGxwudh zY28>3ZmfZQK6M5j3tQ_j#Jh*d@NI7!X+kn?^-iTYfEE{*O`&H4L5wU@4esK zV?JUV>RrsvS{a1%mE5N)FuQd*%cy4Z5)y6r%H8`-I87|Hv9MKYgVkyht!FIJTw|?C z{;dt6B3&Hb@RC>8WRFi1&CcH|H=|-o&l!DYQ&U%??FX=*1o3_3MY%~+C7n8PyMjgM zUuJvmP<$aB?c6mztg-8Bl6;O)2Fm&ELB`+D>u8c5=@`2;$*pZh(u%;N6=dVw^^%y` zvb5kv&B!^7JQR!Bb-lROL3{}ssN5nz;zCy0^==t9qw}1*V1IZ4?A25OyG7Uq*xZA? zUArdk`SwUyb3J9E*diTwV)DB6Qvcx*H@w2{Cg+T?+q>*;{Clnhmq_# zUfQpltf^|Mq39;ZJs}q|r1EN`beY+7|L+0@=@bZ$lW4N(v`rR9rhtRfWX_FMqNyL> z($rf}jb(L?wHduFKT;z*1gu>k*Mu*&E*Tnu^$ic*u1Th&-}KUp+sz%~sWMfuLMfKA zd79)sW&RSE(;O~JA+fQZQyL#alu9ehtOcbDAYiqYc0(=p5`jD&^^@<>gf4cbRVFd| zjV*es$Q>n5Nw1dU0X>RHG)eAWIQ(Xqwfrfcec{QFRvUg+y#D+kaG<8Qp`uZ51lgOefn= z6dL2)gp@nAExXM3Y*~`eK}|Q0xVDXsnynY63DVml=6Jt!!nkpVbh40tXXsx{*nvr} z{4TA+ztAn$yfpC&^{U=CoCMxifGHbLs!E@((yR|JyaSV(%;EY)t@Ql{l4egZiU{)P zvmGh5`JP>$Ia5X6Mpdg(K(-EyYa2MI+6k{*L=qzc$xSG`A@h;2)Y^tn!bdK6`k>S> zc;%_8IPSqx%WY8F2(jCP=+(wj(Ie$VN<#+1Rel(Lf>(4ifCpXD7-fT4OrW7~K2hH~ zNhNh)MSn(5e3?vo!~^jS0?e9#^qSaTzr3c&3ka!c_XFm#N)qiR5bD=eua3}}PbDo^ zRYm$#6RQj21wPqMLm6oG7?Pnz6SD)n30WT(oQ8NcY;;cvkt5i$*w!61pY2#%soKu& zbW|OKT5GbzNei>*mA5YC?ltY#An!r2wOxxsQT;v0$!&|=(t>hP-qqu{B7)yaWlMKr zR83Z82ndd!Cgtz5;1ZSL0|1qPoNU}4o;xpRxL^>gk#{5-VJKf@fn7hn3kRjrd4^6* zI?m5D^eD+mFrHCP$CVW$v|j{#k&F0yk8b@jMjB zu1j@A&)0-+)+D;ZpSC$na@JL~tJH6ib7D*sd_LKDiqruasFh)X!0 z(kEeM!xL1fHvJe2_7jga-DL;0Ic@=_YAQ+ASf~}iZ}nB(Hlt0z!)B!QbH~b9l(yfs z)^wLsC8{Ae$gb&Ll$RWmr;76m1{qw#i>Mx92|b60ih|5b_O)Kcsr4%JC)Cl@+rDc; z1fHdeSgwg9d6vp;Z}k|vAHMXH1(?7UEDFhi(H7Cie~s1cOWU5jBn?}a1e`!(QpNe^ zk;^XQD#^a9E=fYQ*9nz@)b#xz84jpLDwpAxMF6%5 z>eXqp$f0Yy=eRpZ%znBG!%qPeaKto~r+hUgk z#uPMh_4O*vH;#)+3e?ubAw~k?xQn}_$=HU9a!q&HIwAvCwkjLiVNe_vlxVtbzb29O zvGd5}vfI)&3|%c>FExj4hm_TI6LUrIiKdq(`^DCp&Y6qu(cXau-gb+hpB72!rPQ+- z)zRp4+GX*>;l4gZ>n9sJG=)=%lET{XobeU`(K^`1Dr8R(c&&JFlHhYDE?Fwu-jQ*k zlQR!&+rbo;u>>@yUR`i|l)>DCl@gvkN<~c0-KjaX%*AhAN*2e5^3?pNMfe*p(vOG; z&Q6338iC!qWG-ed9GYX?x|qo%;W=F7n(j`c9a^dnQIxh{2FHiMtAsZc>CR;PfaDTL zTJHU)ZX)4;$uuC`+SAU{(=cd9R;uto4@k_1lwKKXGkllPi&PTC;&p&RQRiv0|2-%egE#MuMV2#9{)8jjgU)k@!P`lY z1{;+=x2}p4PcINLnPQ}9&Bme}+cw{h*KGB^Bbb=o&cSP@N|b(lwTnvP+x6=B)=NzD zj8$cRO%=YMUYE~vaJXWLVP%nfm6ISL?;sn!9W&%-W%!1J+~L&HwGw{u>7}sU@P=H* z!^ICkxE6Wdem2nPU~tRwVX0VNLOoVKHKSD@DO76zfzve4X&6{kMt*O2Jx*s{D#B z7XY|TLR8UXfvh;cr@DuE&@3dK1q%zKO`Uy}%jk*H0#Qxu5FNFxiC;YZ7P{^B?~2h! zhy=4MM@g@7KSOJSE_|tez?Fq~>aIgPQ76?JLkTLj8#=%dcdC8RY%_{emzdKcs%lx? zFgX+{X}3;pX-JZ8i%-&CC4yg>#;eoK=?b@yvI4^N-LGOA%N0An{+GRilbf(o@twU= z!r}yfvP6ilSKp3G5F%rd(8Sf-){Rv)bfJS@*!gcE6l7}@w27>{P_<^3#|P5CZGlf?d%_q%7l?p#XBB+jpe&_p|$96->R)A;j;+Z z)0^dfW73#E{z>lCsBdQ5IoDiIAS?+27UQ6lFl6~>pT%ZXDkl);I75qfkciPLPm<>j z>7P=?{Eb)k)v@6I9(Qp0Uh*7pPKp1Kc!0>btP@9ewo7@T4x?Xdrw9-}jC0FomB5Q3TNB zL^k`v^2CX$_CFF15Q~9{h^DK|7v1=bnc73zQJkyO}gxUBG1|s~6 z@b)+dT$!1(XPP!|8 zSEHuum^mGi0?oo(Idgv;Vm*72v8bG&;KNyuY)(n1a;4Uj z=lCc3Lz2E95M?>;t&wR4=Up=rwC6Mbq5SkWKo7j`X|XQ-jo%g5-ZxGD0hkWe)fO&; z!tbLg|74_>(Cy1Ql9LSyoY_ag$KKUmT%l3^rCer-ed(=r6l-9?hU|9L1xEkGAH=PG z)uyZg^0A&g3dLd)R2~LR7=qHi>*6JbyTT1GOHE=CZF~RlzIX&ptTZkHk+B)TAmQM%Y z8OOHCon}+-KX8An{LY-Kbmsla2bUy(?P*y7=g$RKTcGQkhtn$#@df{g^0AYDaC)fx z^#h#@2(M$#FvIT?M2`6yap~nWByTKi#1CLb)?qJJSQ<{c?>cr>>z9|B5%(p!j0o20F5H)mw}laUjiovqnqbi&qagn{D@w&N^9<=x zQ+E%>-~HHq-y#*)U*mp5TSuPI(A&7+$9j-Y*k#D`Q&mV&+CU4gG$Fa6CsqVKtNPp5 z#4fZVB9l5RmO#k4 zIms3#^Cve)!#4JS&n9F(-WMW!FMh@}OsqfFBe75Z2AZXpO|0+``Gd zY?mcX2qz~gU=2HaTotHmW9-P&r>?vyZ|rm}p+mWO`gxQ6=s2U!-_6A$eKu)7QV*1C z`(eeQ7`X2qM|s%hA$a&`nNqAv8`g-8v;O^Pd6;-TG3Lb0Jbhn`|5B7dfI zOOlyq5c2`4xY>XFQ#8Ldb7U6$%-*$w9fr4yrW1`R$Z^=w1F_I)9N4eWtg*K)*m1io z<<9tRs8>=t{WT7u67c3+uw?I?PQ zVCj2-u z5K(iJ20~4ey*eb0?3*xHTCmbA`#u@n0a|VA78!HQsOY6V9^!(AM4++f3m6@QclqoQ z262+W;vm!I&h}WNOm84yBDc9By^>)(`qtBH$=2gitnd*ORlEB~SjMY3P+5~I<@c

    uVQfVkG7k?U(kRWGD$z)&cY-PrOESQp&1)2*yyzB*R`@k9K z@3%Z$@=e=}xno{+{U29UNejhbB&P(f6gr7&@E%?=xkajMn?+9tPp5C?uAb9HKjRuS z?c1>bsO*))^K`DVw6>>l^%7d5M?2^?*xFFL-Mhg8^6^h&K2Z9lon9 z;>WgC5XivfeI>9{Ue7-AH>xDNz9YlcEsjM<58zMsa~@rV2q{+MUu%5{A$;c-C&zL6a4dlmE@{7jwdy5#VRosSn zF=Oh>CLjppIxnf~)6Q)b!8@WVCL%avK98$BARGP4V9r%z+Z1l{iyB?A_QX~MG0UvV8X5X5AE+$j zuTizu1M3Jd`+dGlaQD58=Z+D{X!Lr+x75{eGR|0eJ#UtP%GT6I6m7nRA^nPey#1gT ze8>qXNTPS>JE!!J0(`0bIj-$)t&YQQVJj69j9bLFB$mpe8jy)^Jl6`QB^^zTBj(9Z z3rb3L;I_&9ciCGkkG2&iEA_#N2nm@Xp$bp^99(wwsD=s@b(0D}Tpj!!P7vZy#14{R z|4!8V2R&}*-_%r+r28NJ#G1AJD-E@Iu0V;nFIZeOBgl?v)L0(#MC4k$wZHx76Kk~X zPN$dS5gGX#Z##dl2zpt&Mk#5>ct_D^xp_msH72n%wriI#0CN_&cxm|Cn@I(*Adh=z z27(_i));H^I9JNA-C3|ra`1Rs8!<{@7&eKO2Em5^ecV16Xu%NcxEQtom`(PxTje62 z><0TTL-~W}7vVm;bPLCNFwES*CUI>h#gYp_;*U6We~X?AndGnQ_F%=Tx zF2rVq-)-@keiur;_Q@FRLvj@LhhsI$vHorwBlCV~M}!OpwrBAUci}gGWJaaD&fvv6 z4jBA_yhopX?6bi52XctIKEQyHIq7~HDI8qsmMr#>8xbLY=$7W?_|1;5)yXzLypj&kI{Qat$<@cqr=^v=4XS^l&<>yt1B)@ zK&Bei$%eD-QW-5%=3)H#WDhwfN6^pA^pB6fOv5@K(Q~EYJ0LeR$ky5g3Y25k0Gms{ zxPw`O?owWCwv+MuGdz^Wle_W)$JP(OnDHAOEGT~BO0sy9g>LKJs)=v%MOC!F8`YCM zt`TFueo`xGa2oHRo_^w1JjRIrvAlo6m zPdkJpfUU>f@QT^5rz!zgvJFpoKrSt z2xfha7Y_c*A*n#|KSZJ1&&-uOS~SzzVQz&oXkqlOOne)&YJQ2@^0g{$-;Xni9az_s zlieQg9+HQZapSvd!esMp8oP>f;8NyXverT!!FSVcvPwsw3g5ijRT{WPKBC5dv4!Ts zRts13<0fc@W9767kV=WkA0=g$i~EolruM8*ls|AN&n$E}t5XG_XTEd`!1nbe<3&Sj z2)}M~t)*E-CfwIHC-kA+%?iNc&h5DC79B>YK&O`Sajqg88^uihC${ffCyV_(pKzcPpNj5<~2H-M82N#Qd3X)(ya3u<%k-Qv>r5(uD@3f5QHiM(}vy6 z2u(B|f^5XyXOIJ{NH^KYMs#_NV5=!p_gka%5@pW=|2r>YHtnhuhwR>BR?s90u>eh( zD5NqluFWjj=`S~;tj4TaS+sQjJl&-M z-ZWr$hM|CE#5+SmznQ@fEB zYrI7%10snYLT$XRvgDPvYj0H#RI5ooM#Q&vIgKdP6fZ^Bhs)p;lvmdrC+cAeNwoEY zQk~m17TH@2he+{ngRWTLvQdr_ufYMhaM3#HKrU!_nk&n+aL{tpB)`XGe}TKkQiUg6 zAQBbUDA=OAQx@c08jV9N+&}5a6b0yVXhWo}QD9#5B|F&rH7AOS)!C$gp?{qbN7<-~ z-E{Rg7~kW}eILIsC3D)tvTiTtjgVeHrkfj(`t3E5XGG{0ZWKyif*VAl{B4hZ<9IiT zJBJI^IV45M??&EuCxdLl%@JgLt-Q6zqk(tUU~`t1>%P1h3SXMuVz`;e;#MfNYJ1G6 z3+G+DR6av*r(t^S>Ss-(MtTWig3|SKNiqw^-|x-0YxGHm1l#*6?DIzCNrzC_i7nkZ zcU#3`isQcRic7g2=b*#kjp%i!DJc5KmhO}lspc1WfVA-$vCp-(Amv?nbE}koU_0!E z`@Gb!Y{h*tgCdG{o)NtWa-2i>5z1nzg^v2)N{O~vfYL)N@FysU4v$Y(#|lfa2rUcL3!$yPct zd1t5h-BWot(E!z_1e9fQ^Rk5y_iD_VD*m<{fcrSd3?>8UTfbfo_+BF+m=}#<>LWow z6ryV)(tK6NB^m-+<(j#;$L(qCTMtV>mzKYs2!{j+*prLTkMDq|%SZ!|Z&Twx4|>=wRBR|~$oLiR#M zvlzAnC&2UiDe>kgduxWppX#|KITvM1yO(y;biul#67`Po?{S2a$LVv?T}L@|l%yE# zmQ25Q$La~CyE!IH&NYAAD>lOZjVTts>>bnsD72V?`^QHZfSaKbMmg6+zY*PLE1acx z<*ZNjxQ>8bBd!&krh45#&42PcLEN)S4)n&v?sH5V6OtD7%1$pkca4@AO7+bWG4c4f zs0!z6Ot2RJxSkjU0kcCR9`52NQw7Ik001?<56V)@PN@_i7`PF(l<-ePYPCm#sF z+1(b48+K$0qiR;CF3z@^)ejbM*}cY8=UrUL0{TMG^Eif@LrdLR{`0t4Cmp5RMLGmb zY&Iiiuq1h5jkk1oqLIQN2H*VO!$ov8_A8g)6LI+0s9Z`M(>H?A*hJ#FlMom4Gy(jQ zAX~cROf1PwAIJQNx7)u11_ipZPd6eJHM6*y0PYyNdDMwY1cmg^h`@E4K}9IRvv05Y z?`Xqx(6AA`yie*Rq!4)UMV3lL&ZjYX-X~$95h|q_d@<*J5>h2{mkfV`bC0sHCueU& z*(e8b`U|uog_U1&6wkwuJ2-YJ-76K((&Z*3P%FRe2E+3>O)b0NxbgI7=Lk8$5QoGM zUwtPoeIX+uhKTb#O^h*rrc>y0!jQG(>+8vDe1jcq0aQkW$tdv2QVw?9+#4{fx=vmC zT4-q94Uz94nY(7$np6qDi69ToitJlS)MAft#1!%rAkzh@=V&286+sy_4)As@Z1T@` z4UMevc7sGAd)5e{VAOYG1j&e%tWC3{Mf;W^ag~y#fA^%c8G=Jf&d=jarxO+Lwby5M z4xbEuC|~2@&ymSdSf2f$)Jq7Yzy1!BYIKa>W-tFXdSa_?QcTbNGhK6ATXmGepZ@Zm z%Xuo{^zOrHhG){JmBIY$8a)MhnG<$Z9oCrcsTc}cD#=hbjk7W#V6O?^Wt_VN(dckm z-N@@LrWy8Y4C7R3x=G+T6Px14u3#vax%~0ij>hiquG-eEfoB?gAQ3X!`|g5=GP~ z)XL6|8FMDR=`uaHvy|V$?-JJ2Q(6zy{^;`iH`Lm$>61BJoL#j_k(Hu}#A6?;y<>n4 z%W;UkyFYm&7FW>=Bf3%YI4xpXUPGO*1An&2e#L5C&@HF`Z)2B7x>^e>r)!Q@e#J>y zI=005-G02S0W-RBt15k`2*v%gRWiG=$Sr*Le5z3jx&Yjcw!kD_WxxpaouZgQdftNY zO}I9rcLG&`DpKO0Ppswy$`H_B*s{FwCR+Bno@Dt5gAQzq?oDBo*N7huKAmP+%{%X? z8*4Wr{`^?D|n6PEjySS$mb@-!X*~5fL#~O8qQ8 zByXK+GS)fYNO=-)J*mk9wUnoK_$Q&tDlsLrO~ypAYb4o!dlp4DrpOX-o{)9b!Qv5#!9we# zR1B5qszZRMX`IUUh!<3@;QTDfM}~r`d^2f3OY+^X__bVe@yO|BB14kh?5m*h9GpFm zcd&}?g`Ik}z7mTTQH}bJSUC!MT09Dd`J26MRtxChT*f%o*y6oFUYx=(nA7(*#l@X0 z#a1ePPP1!xvo>i`mUyRGwrOgEDi>%4qHO*$n zbXb%4vbot3H+1_cDvOrWrw;X`Ny6K(G+1x9ojCTbWroG3yZCV;7M0EC+k!g`-;IKc zHmM*`_N$W=wkX_)rD?}=5b`|$P{sNC^*+7&M5*cQU8VecH0YNc+1W0m-gxSMF{19h z@yO2#-5BKqf5?Sd*0UFip)>_^R5G4DgSpvUw;I1gH5MNq>K>=1mJMmyHs=)@*NntV z&$3&2#*s{O5Lx5N5IHl6@!a59kh1aEpd>jSF_>D(Q5eD9++|#oc5Z%&bBfD96CylBw(RxzpQxa$fq3wB}8NBgm zYRjr_IQ*O#aMQd43giv06PMIN5xZ^B7(3xB^w_z@^s(x1zF@k+ zs;Hu5#le-Z42IcU^_GY4@__}AjY)~W5l6WXbP+2ZHqnVyENH#Eeo{z(`T&`RQ|zPT zISBNWz}e${SU0A*E%wUh8tr!Y%`nhQ_w;(RMriOnTuq}@I*NZ?PbDtW38rULM8@8! zm3^0iD0FHPDdt72>|fgFFIuBi|KIB50E{($5q44wrAcP8x$(Z9^N*zF#tRp0O-bs8_%Q(*ZG z!UDQ6m0n!+$g_A>nD+z$Lhwgn#0emonW{y7uTp58ddu#W&{<}UKNfwoAk2*<&#AZ* zRzXc;HzdB79yWInu1h(c_2jwbUTK@uaTIKDsImL;dgfII!z@|MpaBj)Ik5aY66`(` z^r9D2RQ|n}rap})N`3r?#$FAy8^-e;0lLV98uvJ5L%^TMt!+YcW}`J|6K`-OI=;^N z-fm!c7j=4^X7q?7)7ULUlEk5H@mV@j7`VH)0^!a`%cj93ODbvf@0g%%nl2N^+@>2W zv=2q<$-|7pY$C*C+cXVF_AH(UGB@=84#lBOiFyYSralgcq;ZJO5th-RDOO+G>?Zq< z5?0DOcREVqpwbt2bQ;kgZd*({RJ;ROI&~u6vX=AWlda1Zuqm9iGa%3eIpD`bg z=q;X0_OwMeh-j!WrOR%Wj)Ix74~kGK{4r9ERW$7!ggT$uSy$wi26hkf-^!lGG81-Q zx<@1yUiKL>8r($gnLPoYMij<{H8%S1D*3rEyHwqL>mJ@~7fz=eB;wc`@rgH70xAsN zCMf~9FpaX&(O*2QVBc==DPHalqI_^*fvohvt+Aq8+AQq8B42YmJPYc!TtxW$aRfIW zLJ4|xaQ!TzhO78&h0t%&fB9As%QG_{U2YsLjy#-71C)7G5K+qX8BwTS@alxn%SX@I z>Rh4}Wzc@-&3)q#ktodc5rhO?TF3RH%Fl6?j0598*h?&YYuA8E8KP`jW zVD`Jwe8qOsQ`Y?m0@0!GyEIsR=@uhFQO(Qa!pSE-2HUQtv_dp_@AFzAnY{M~lGyx_ zwkIK<@f<J7N{{*{%$W~ zo=O}(J44>dI0a>Gw;KojFKCNB+I5WJTkT{|c4x&c2`=lA4lxR;X^u+8jC&)BD5D?f z8pir;Q7zccG^#VxtJ5*;dTt9zC^&h2x?)c#Qbr$sBejY+>BFB{pXKlWXe z|4=AzfT~ZB*533jcHEL&h-fH@s7qe2Q6N3_bJJ%Sc8w=&w?#^^uW4C!OYar>?Bp8R zj3&3Ku9vN_EQ=9EILs3+-jf9)gQBF{E!>2x%d*NU>rgqK@AnsB+7YyHpx?+Ai|HQEFj=c;cG)_|h?^k^^`SsuF5V zBioC79Eg2r>g|$84|ytN=iOaYGkohd4>U&X#WzCu7J)laabE8$7H6IGaty&ov536x zX@iUw^|WY-7{2-um-l>1q^d&|>YNqeqDkk6h@*n;AqtWQ}tx%eD`G*V*O5Auw zfuXYG`TgRNS0;Bu+D;IzyZ)sqrB;+HdHak;;p-#x`Cgka&fB@-KG~E<`1a-XFppK* zI~9SatMMRIy%2c9=h7Sm6#-2HiOj-=*z|`HyUw+Z304Nf@Gg~nMs(Q31hl^kTwRay z&yFbc{yyP8ItT0BVip~KQ#AkK+^Dgx8c(DGhpu*MR0DW&dNL8m1^r{+f3qMer-R2$ z#AQ47J7EOH<26bjd|SaKC!LA60|o(YQN)YB*Ap%ICMyC^x9^0tU9LG0Qb9b;mirNm zoDD!xZpy=b_W9fA3*@DqEM1V`=ueHwk*-k@^`?K_ojNlPQ={uB-#!p89@Q6j6oNdn zD_+|=@P zu`ixv^g_Ub?IQyO<5X*uynT{$Ib-1IcC>^oQn6Hr82)aM?uEQ>C}eiaVR!3jiIAiY zwnyfRCoKJDS8uc+o20Q6^fsxcC$@35+r0-9-I9zno#Jzfh)*-i@T3UIpDN!by^Q3v z>|FklnLQJ6N||5v&wr0iwwd~vh^rvDQ^UK`(^YlMo)G3~1gqe%M&|R4DRK>S&F1dI z1g9TeL&ykZ8p5gXMu89`;2WjkzIRlWy<_9e$7?60EV+q#rRd3^o4cDucH|8BYx?0V zEy!_bbQprrXPd;dQ)g=)e?-@JvYLoS0M-dvu7gr)f)enqO=@E4&5hSv`jkuhL*2|k zl&tGE)6LSpp7MAe;UPL*aO_;Yw=IBv`t8;tspCErVat&_xf`rp*}vpmBlYThpy>CZ ziE)?e`Qcj=RZ4a~8Uq6R4!)l)LX$$vF8-G>`ChuHWfFox{Hw>kx7}Uq{8?Y$B>rKC zs8}s636%^RnlDAOhbf%s?GYNg%lJj)rCXM|!V@Z&_HH`I^=MJaoH;g=Frn`SQI0IR z+d5F@#zX{UlX1<;C@YuR0wisV;rzpYuyX`RlY5pAOVZSvDGm&S`OZU7Ng>1<5v?JS zCIU2`P`eVr$&rPVquc%RQ}-SpueG(rAyA_i$Yw@GkIVXqGpptd>NNIR zwl^QFfAl$0(hbHv!9Vxo0Jt{_s>L2X4Vt;fDls`lBIqQS42%l&o)=+wI~{xF6x=68}bvJbkH=my^DMY6TEe9_#Ss3m-1LVdhGF=$Q2o3mvz#nBMY_( zI!0+!>tZ6ONAg%JEL%F>vBLm6tc~)!DfXQZ7v7gIwsciaKIv>sNW=j2q=Gc_Sr8PT zjmZgo=ji3*ueP&l+Tu%lB|DOHu$T9yusSf|1iIDfr?%XhZ zhtVeG_)Ez3F^liYl66Ezh?w4QYm+80jYp#eu;LjKvgcBJeTTv9B+=lNNVU^uUoVL|R)=&B(k!veoe9ww4O3iA+ zcb|DZ(HU#YptnB!6CdbV>40Y+e4e)Yb=Tl|w$EyAedfAb5E8QWYt3a}&LdW0dY+X( zI|CD(458dVsj7MFqc~}}Huv(LH7~8*n!8K(>=*HEb@ChcsvSC~Fj)%(xbrQb$Sz5DCH)7StI~f#*JbRN<$!KH{aKfiwH}bc) z*zTRJ)x(AL!;w$t`K#v~1rGOBq#%zjCqFRP2Sezx6zc*ZZJ7I=hn+*G_UmTxvp&Rp z(5MZaJl%u3!*@}z9R95t=Uc5@8_Ig)$#!6cok!4f@)HoQl&Vb~=gyZpF4v?D%{tvH zF_^u9<`f*?FMhOE=*q ziTa)`DZF{*gC9HSjp3V@JwG~>{|&=DN;RJGcGZ`hMY6o+jR$t~Oc0}YbFU4Fj#Oxq zPk3Z142f8UEaY+P%cowO!1WnVjVB3+j9p&rBt?RYxKwH|hTBEnF2}14;GOjPYSb(S z6DQkymT#D)@=s!-YlE&iL$}W0;>{{EGH#@;49ixByspTu&Hrv^1?fSvwsMy@p48DS zUp0cwJZ-(--RWlAM|b2GFuNq6boM=-T1k;oUXdK{*^Kd?mA!iA5dX)y^h3%{dIJ0N z2uLUXch6d0vu8vbPpv+`G~EK=)Q#3rpM&ACPlzUu<6afaf$s%VU|8fFuw7 zD!t9xq6*LHM!JXU0$F*h$**aLxV_u*IBV{hhBvSH3{XpmK zR|LsHvtA}HJG%W|0N;6t6z*N*epw5`rjh9Hy-O@%(>2`W5??%|mzd^q*AEpv-GF4{ z%lb)z-B}Wq^KH%Dc7EpN_BV&>3-r1DGMUN1y*w6u>)UN-=L=MYXHQ!-Jk|jzSn9PE z+pmqUyic8|CBctt!=GE)bmMGA;hnElN z!L82Urp@31*S_&^fLou?^f}40brqBMO38zp2tG?~4rX^>3zC_=3-;PvE;%&lRn2jf za-R>*srTCl4MKCchg*yMMcG8K1S1a(P)@!hi7qXD>vLAcDB3{US*81i%O7Yfv3lcS zhtGJWcdrf3B|V|IPfvzv-iP(%+FW;7FH2K7-fks8?<*YIx?bAqL|<3k%VAk@Cu!;X zJqVu*V~dsSv{995B!^k`{R;PQ^k(%lvbKl>9zU8%(}mZ<#&oh2p~TPjD= z`7yvF6%GL#GVRn)$7_lSJG_d{s-!?>Ov1EdeJXi^P&|+6PuXqtPw@BX(a1JCga>St zottkR$fEZYN00ta9(C6%lrRq?pe0$6xd5sYKL%tH3$f=$Woo8Bf<9|YYO%U7fTxK8 zrZzxh<`+0p9;A+Lq)G_|PHL6B{qzRnR;nyesCQ|(Uv9_k5B)Q}G1$cpd@whBrd=M3 z=m<|RE-%`c`=$W5r?4Av_x$Ykt$8=Up zeptV@6TO+;pi*%vlEx=qX{J8M52N?-uXCmNNsp}CWeLKTlh zQEK|i8XTbA9Z^|hW(^?fU`h}wMN4hRx>e`J>lwXj!d^n6`3ZQ`sx$cT*wScut&F+cbcESf^2tSI!P}esdy@!g6wz?q(QI%va!<_L z8#~UTwLeCEMo3(;QjrKwe?#RDVqTfC-DX&$(J+m{po=|q*22DHe zSOO6NsPZ5~Q@x&$0~!Tadkd82+GN`?$F<*R;9mBd7T@3^sh|-$XNY3Yg$f<(2=~0T zxiU&@$Uydy==rULSObZ1h&=s88PAzl|0M9^jM|D62&WxG;_PL90Q71aK9)0|F~pC? z*Hw0r7)`(Bune!*-9h-wF4H{y<)D>UoRig}wr{jDuB>k=TAN~_?1$9U`IerTwFQ?B zPqAFcCXyCQx9gxLEAs$8liT$wsiiN%13t;%pXkBSzO{s63L30~W&znt!2|kac(Aue(GqBw`Ps{A`Q#qw?>{c|SVn)+?JE;8orKzT!> z$?Ds?CUC5VSO)!_F=(x|8Z`c(9RZBRPRd5sT5);z1x$jIOX*}S@N8cHKyxa>XMccr zW?WL-a|zC|0z-2itLKO~8C%*E&2hr0ja{!bWd!nYR^b3tqsa`fpTblmA(~O~b|Nh? zA2^k7Ao|P$yEmrm@3h|hH%Pk* z{y5f+@4%}Y7YRBtF1_TC01~Wnq!E(=@_Jp(NHnX#15OAKP#jBWjM-Wr%kA(?9 z$muWj4M|lsbg+m;l%B_w8H=gxYPk+h6$xT5)WCNxa1TifM;(`yKHz~C38$n~Cr$tl zvzz^vIr(PJMp8)0rf4UmHz!hL0lv+*c|1R&&g%^& zm!)TRKxi$yh}_mlGBkP9H6uhaM_Ir)Dsk0JL->v;J77oe3x~dy%l!@|cAk-X)to{c%cZ zhpd8*Uo^&BXvr0t%7K}m@F^PrmBYZJ8&b{R^C%chpLDHO3aMy?O~X0Yxkz#NOKt3l z7n>REM1&6l;&YBa+Y+of6>@0eKlTd_5%K6+lWFZ~q>o|2p(Pa&*&%=o_R>gJGy_MF z(9Z0fQv@iMaj7v2KEWg4DVvMD<=UC{morZO4HNTT!IX|n)x== z>;>VaJBOBhM#o^l*E7Iang(ACYLzp;Tzv0(?e@GdYzIV)+8^g^&lzWmKiqF+>vn(a zceS^KfwGh7Po}MLHsPmZZz%bRl|giB1v)>G9Z{0-S=xPmjUe6^B$9O`XE5`V&6{(p zriq4}Z>h0ru3U**49$K|yfFH0%IQRz6~%OnsIJ)$g=Rb}QpI=@-03f1J30i8+t>Uf zU(HCOiP7!2B)E|sfe2n+*Gru_2lzQOrd#sq-kRG$s0b z`ZN9NLI9SUnE8qO*AMrp`7do!^kS5d+{ghuN;a}Koa`@BdRUwxY>a`!&C8f?DfD_$ z0;S@-LsI}!E95@viLyX`=0{E)SSoGi*Z2HN0|oY5;jr!{SrXKm{s6*ej2vRBJTxZ{ z;%I+K3se`NiAaYpj`r$#wA`p5Yt%^c>issskLch;WhW~|TyZ>S#(`%}Ge2e{@2X^e z!jI$qp@j$eR#t9wKN_zzyy8F--x(tgR=-u@;|gK>8DA zvtEw!ctmh;($bkre2QH!#M(2>DUh0-{wU<0%bdG8tF#Z;n=b|6s}1aJ@`#x+>o&QK z>^JNc?up}!|H2*%{&ZB`4!T3*&Q3dOz0!;}^$Wh0vR&?RDQYF9n%06PX)(S9B?H~e zj0J&G=_aTxxv;B{Ev>Jj)P^-3?kPO3Hcc#KFc5v2oKNPQlEC>kdCFQ-i%y|)I4`hC z*GCHS2wkH#%21*Bjw{ua6)}aeT}y!GEc2#R0?k+(}Lxq>fr!=y!j_VHJCLsjsrJQ zs#NTff_%&Em>)=B_(8a#Iqox)oThsGkeq$)jB_2aI>RBg(cN9A1wu)GByFPZu~c)0 zlq78_U|^OrPS?W%FzNIcG|)K{*Zzp>A6T@+IWuPlU_4v7Zfd&isF6YCv23FYf*S`d zp~ZG&4C;TPXo&;KoMwI|IJzo^+`( z--8~r(6*xli}`pU6x~QJbJD0G8f`v14ooi1Mf}NKahn)2^TTgAb)-~GuHFEjQtGDq zl`%<-07XEe8XWjc&0}VwjB0n6{%PC~4dmJ{gQ|C(q1Xo$9wEV0;*V7VZK*Pu39ca|}x9DVoQtdC1kwgH{Al&IM zSFhu7rErsAcMR?E(`w0^jM>nrj+|yXnPMJIrCy0wXJw8$+dJ)?l6akJG;&jKXnf(= zCNz3;=gcL{m!eAjIq5&ZB|`C8h0p=TJYUk3L9BlQ7Uo0Idx%<^{3f^x=R!D+w(Pc%5+*zQ`J!ft5Q!30mHsF~sKFnIz>G z+l&TkkKBn-!C6^FYU)N({97XyDc*AmIy<2N_SL8anLe5R60*qN5{!(WRls@Bv#1#{ z-8HoM*QhCT+TRah#ppMZ;y?EQ=S!+7x)zC4ERA)WQF+a4)eT@38C6Zu#4zBuJj!Cn z$j-)|FqjBrwHyr9g&o6@p^-91gC|1^zrz7eJ$2I6iW7?MWVN|HGpnWb*?bfban>rP zUc79=3Snl(94irv^d?I?)glygO8n9rahiMzGnEG$%?qg5{^7JB9W)wcBr!gC>~{LGyox8nZkxO3HPF^w1HdzRh?G(^YMCllUr&F@ z#dN-0fJKwc0DmMiPAT8;&Yv3L<$(fCgUkfn;gZY`+*tfemD&q)k@W$4XAB6cI$G}T z*haMgPP}hZ6FgO3Jeb^PvX9A_GG@4J_Ubj#AN@aZf_O=64VhAmTXY{t(>Ceu;x-qO~xQ5l1CwwOJovDLo< zr<+krDN6A^?8!|V{z2sz> zC+ei^HigqOJJMaGlA5ALNJ^Aob|cU=5aIMD;h0DanuEQo?d>Kjqc~}g^k-RVM@A`5 zxr2O*1~!GG$t?|1NpV~2#iMFBkAucTjg$(f2ml3LRr%~FjalC{wt0VO9byUVt(Ugn=Vom~gFZ=@M5h$C}x31alJ z!)${6R)N8wx*YKO8H|QJ#PYy!wN(xiU_SGsCo0W67?GTrUsOSO1<_;8v=av?B9fZi z6AeHn8k2TbH`WDB@*?|2p|TRwAD5%{l{DDm_Lm@Y^$0cV&r8dxBrl9B8#*+3jh>=J zRHm9hI6n6-@PPFNuBRO%TC8I|dlIZ7b;tIS4OuT&!dC{Yb569QF*!6M+x|r7R$c%= znlxi5?-_4_EQ!mszc`Q85NJvpx?WWoD}VUdh?FyTs+9OQlvu{aA=+-{4A^wv^kUbS zW(L{ILvlIY>rk2U+awApKVIz|%s@GcKsiM@c(DuhCyX zxHH?iMCDfZp{1&bv?LKRQ38l5am3KTov~qPiHC-JH2t8lL`=}EElKym=s6LCvY1#^ zH_z(ISfH_`O(ut)r-zF(5|tqtX@}3_gQ7_! zbS~lZocw6GN=p^(oFbZrO~|)V_Ol;Od}E|&OuqXK`%7bu zvTqO{Ff;4TRh`l*oYO8Y8X~$jj3y)F!E!A$*muB9rFc#b>ax@uoIm55kGF(d<&$-f}s(LogXif+i*E^ruG*RD5w)rv_llXsPnYTZH%@H zS{)rq0*Z~DErI-zvq1OgGG08GzqFj`%&!N3;=-E+zx+}d*6 zH#L#Lg}l@0kIm~|@&~EO{g#RbL3&ENTvFZ{!2n26fy`~)jWxV?0{f9okY{n6cc z8n%qjiAEoVFVSst%Oa2OXoshS^VlE(oz^g-0kgxuxMqC=GeWoWB7$08~$uWgXzyq9@?EHz@1w@5xUA zOV5^#IWokh;lqW0JeftfykvR~4>0%Wz966A4zv^H)?5lO^W(+tn+IrEnEo`EX`T5w z-a+b#bZ$J#ffDKN7_pWkLwQ&u@sfz2Ji+W+%A6uEKHw;Be|<(TGlwmCP;PW z2hAp4pCbd#&N}?L=Pi0+y#}>AjlYN(o6G1cI-EAOUS@)L&iq6_f{xMfWqE}KwX;w% znVm71>mYy8A0h4K3-HptRNn$>ZGWi(u}8sMdoH=T^#&a2Nc8lVaDLWClQ3FKi;teU zh=nbNOaMKxB~bFz3J6JLFVl`PJ7)`8>A6JOe7ANYe%T|MQ#Ug|T426~FONKP0fNzJ zqg+tlxo`tI2HBmMyZ)lr%sIibi7$u7YL(_3EuZBwd!|_r5?MDUdh&iO zbuRzS{8CuZ{wVjwE_7b;ERWs}@BC=vX-C+nqK>M_9^sY35u3jK@efOL8W)3+*m^_> zR~+jr4!Yl_!0XJJ!`E+VzoTDd%Bsf`X}jj)R7CC*wOX$b(?-7}3wzE-GVWck=*h(T z;^FLE=-vJ0;@obl-1E)1?m;_hGaQ5679T!FfwoZTY zV;RG#K4(>ep}La_)$;Iw4B>Npw#l<++{R<202B7V_*WhzO|cP;@Hv@Nu_xO0?4|t* zuRt$}f@|NVU3`kupP99t!?;*439@M?Vs>;`$|54Wu00=I5)~X@7EN&K@Xx6=m*l%n zd_X(rC^Vc}KO-Jz`b((!;48G&GeF=l?)YrZhy6%9Mt9Rbq_O9xxH8?#LU{-%kqXxnWK;GOspv_RBk!p2 zQf9R@W-JPyMiA$;%e{osoc+}}a;5VvNk6k=WM&NEiHYW#3y-{GI2>oSLT0f%^mQfZ+C56VvPIMEP}NdgKpKe5L|&C%$bmHNK8ns%u{x-2}-YnSx)WMZPXiWqW5 zTFvhEC;pT95#X(#)=s2xXb{rwxNzXKlj)dDS+*I9wGMD$GcjlioKPU!!zsY0Gv=pl z6|+|GSoW4#JiZn`o~{awhTQ08G8~C(p)v0(7g8b7b1EGYCK~Q>tCnUa%TbO{e4apY z7-?3^3eSv1#10PdujMj7jd|PtL12 z5|W(tGAy1VPR8iSvh9l%qX{v8XD7wpQxALyIn9iPEvuC%bzpIN6IX~eP8yFVwC&)U zjw%p*G&AEK)EKya$vl5Ib4w;@^{8NNPfH5fj~xf5qO1AmDL$JK=&|Ys3XM1{4eW{x zIQC+sGrPvkjFIO|kN+;!(UlQVn5f_K4f|XUPuKKjwV*z~gREfa=1}Pztcvb384z~A zB{prxqu;%dYl4H!89bo1ryU6o4nn)^5MQ{lDE3-1aQ2KPWScT)A=;HkdYpDhe?t0G zQw9n8rt8gh^^s-&3|H9=n|tgtE7=-{B(C?CTAq38gDhx(->z4_v}c1`Nq)+|B%5kq z_-It`tOFz;TCPAW{}K(&xbkr)zH6B@i~V30=&I>Y!9g`p@^OiVGd5Gl|Ahv!>XIhjE;0mk4G1Iv_Zqk2Q zM{Y^&{9p#{%$eiLA#8s^Vm+snH{H85o6v8QdY>^!>+F!+8_nJQ2nsG=c!*&5d<*6T zZBo3kSVQAjSAu}yBYmlh45}jZK*2~K&qs8D1j)S}%|}0ujkVaV4i`_#JuSLL`blto z#*laHDYsQ7GxKADtCv{zlM~`4k40cY?dE*Tfh>}VeK`?gLRU>HTPPqr{aI8`AkXyZ zv_y1z0;RrBHiiCZt$reDDg)|=spTG zC_$Y5SljMT!fC6Q#lRb{iuwkar#~#HjR5t}sc)53<|6+L8cl!7BNCf(mO<08FVLIQ zLPPRnwjvGE20CMN)P9PN&bO`8%eO$z+9n97_r=hnzuFG&8J*5=-zA&a+vtdg998JZI*;=av6B;+NpO^m!0ONh;LUn8o$UTKt;6bS2^Nhi+)wjS} z4%^ZqxA_*IH{K#*OA0(%4wI9YX(x0VNkgM!hF3smZJ1~k1Ued*8K_M}gU>bIb`=0&>=11sJUu() z5A2^8>!~=`d#1nS((EKJnLD(zOA2OabjFU$1I-Akvo^Lahh!g1BlWXZa10*vazA%V zyUxyP*A>TO~cIm2zF#D@pP(S`b!9MXjg8XfHWp80|a{P z`~=WriETUeG~Ba+_BL~2=T>{mz%=JeCYaToOV1jYR+5^o{}LNY`>>t)T83k{#;I7eF0l6|vpfH0pv zJfIZwT9LI;nWTSdq^|9V($=||U3E(e&ez(f{;1VAXz>^4TTXG$3k9{fGWAS68R3{j z(Pwtav1S$U(RyJB$(Uy*Y{^#UQAKvh2})Vk*6#Bui|Ek=EV~=jY;IfSTcG8vHaII3 zS^4foR?2(9CnYPJ_e~Vn8pwr`kbO}lHDkrlXu0Olb%|O-82Q%8+!|{vZp{T6P(JHd zE#E2@vV&7IJDd~avbPL5urd8{t7GY5R59wF(gdc}nd3^*t)pwO(5dUU*ta(ja>XXP z3tKH|zh#GFo0C(4$7YNusK`K|#>g@w6j>nynsGb38yT#e$79*c`BqpxRY3R-$_@WW zA(Wc=@m9B5oRM(GOLMEQR?-OvPdjHDzLm@g)yCQ(u#0yAS_>r@6(76;m$`2HS?|&%ol=_L6DZ`(Z3Z&?jDj$qf4RMEBxu zU?Wd2Gf56^XQ#pJ?jOPNRW0>h7%=KI+F}%X@qk7Q!|(d z1y`I}uWd?|n{)3xQ=5v2x*N`aBepG`94jHPCmazTXU7G; z_O$VTTjfkIrx>w(k?azG!h1|0(MwAvG;^U3_C$j(w0hd%#okAfW|=(_6g&G%3Y|*4 z7kFDlM#t;gro3w8d9j@f)U^5w@SvG8KfGUkC|fuu ziyC1u%0K&Wz4)BF+hcW-W#J9rAE#h_DeLBW49%=(kD?uGO?VbtxkSK$j<#b^_oN0X z7klIu^?2Sqlw_RAnvL0*QG9S3B6CUFb>;^;LaNr0GWe}9x8?QglGNM`u|RdIckw0R z&y~qUE-Gv8q|g#wFP*{XvPXnYinx0T8QE1%o6|9zr``BInO$CMpYxp9NhOFk$%~!d zgc^Is**9^N>5cB|Ne}^FOp)7CbUg{juw&P989k9N9)JMG*xdxElAA}9Mj7c7j%pk- zsCVlV_<^}srN3OGUM|x>B+|-~1Kjx~&7BB>zY8YLDVJMoUO#*~_1b(X5=7&0v;5a} zu+C6q#%MI9>ji$627^vM!+DOK$QZd6G92Z8wSFl&=;&)ewXse#n>qXwzk|QB-rNw_ zaoL3AThNk9oVld9GP|3(uZ@X0O!PQWc;YwnBSEtc>|5K*Bk3(Ahsc4S{S`-UtzT5M z&}zqUjP0dy`JJ2N5NC(SGX~hX7@W|6KbbQ_wedP<5*xw;2JL7Uo+>_*X0?1EN#~bZ z{n}IkZLj^zxDHl4enD<-*VtYf8HUKW49eP*LZ_T8Q93shrawhRl`DA?!O-asGOsO9 zPGCB+_TGGEJwNYySqu0#6wLs3efH}^6Jhp{_cxVs%lp55SkpZ;k2tjr|2 zV(kq;=hviF3Y|t%kwMy({D2w$H0@MT)WZTr8M38K^nqe_)JDGfHLO@x!E`MSvd5xu z&Ln%fzN39lY$W62-CDa`1DTbjvVFM1*P(?oXKPr?p^T0nk}+aNciiH>(j+eiLvaS- zxo{qQU9>Qj?RL@;VjQ}=p0tM`G8Z;@Z@kj|tv5m=D|4<~HDuY^&e0wD<}1*zSzF|6 z`6nq^J(8^B-kl^5;vShxD(bht)F6f8TF0(J-9qJzt#xZ=X6HEMW(4~ySUob}Jepm& zg4^TCv-^a!T%n0hf3~kD2t42^raw_YaG|@KFhysAmdZ$6vM=R3?G7$=zPSL}QPIdh z8l#)DJiUoW_`M$6FN__jfGHU;TtcG-wl|5;XaTgOF1DRsN|Q;PyML*<<5By$B;5n+ z(+-e{RzW-71^X%4I^S}6wm*O}nhRFs)Kn{Lr^aAtJoHMfIWg1ikA)hXfR;i+H%}E+ZpDTZbIiUaaX3ef1nT`iw>B+>yNlxo?G#`GtF zFel9!cA80xEEl<&afxAcLjWlRvNXY#P!M*1V1sy*Xlhxux1^v^z=1)*ISq{zpa~Ms z+~^WEJ-sOQ?W7DZRdlgK{Jx409lhbB(2 z{iT$m-%5&1)|q!9tTXLw=g!25uPy_XZFlTL??qU^Dgc#p3w4Q`uJouBi@A7e7Bph;I&cn3vSzBSm`E*UpbW5RgRM+{jG;0Y20Y;m1eMH`;KW8);3Cf5=Ir9sU&-s>8UMxi%bKkD*RGno#|K132 z41&ZWX^i&VszD3ZOMk7bnK7uAa0Ol)uYjiYUwRW>*_t!7<%+Buwq zq{J$mAp64<QE$f+8A;Y>A-Ai0p_SS2|%>@x<#x7Nl#izhLN#`MziSqE`jOoQQK zGfohQXq_`Z-dZg#caap%xU~DysE(aW@}q087}fpEPzsoPS2jl{TfX` zFvnUE8@9OXCAOn6_>Gi8=Lf@*NW6lk0Mw^{SE}mM}fg5LjqDa;1#&;B_UH1*|l?v@WNv4|037=Dqbk^aET6;pzfA4yMS`w?3 z%^0o_S9%%edFPZ&M@Xotz7hM%xm#M$ZAMjHv@griY;$6GrAMddrKdy{sk?X(^X=a9 zLSvps>OFvfqv0~IZxI?RJ^Gfar19t5#Kt?WVOJvM!=Z=lZZO|Si}U9sWZcN`gk_<;6P*1 zu9=Gic;;NxlJzP;S??guNl&W667K)3mn)Wdy>T#ilJsy z6Zvt@F6+k|Cb>yOPmWz+f$2hVs&^lqDH?+eBq2P%a>JR(ozlz~Fj~(_27@f)I~{UP zn$XH%IpE|PAu*HkgqfUdo`8Dv;~!{xX}g4zD^q*|ntN!>ea{9OU$*<0 z3}LzKfC-9DJAOfB1&v}TuON%55EigBN;waUPn{eZfo(f@WISiI$Z~jZ#gnm5^^4eT zWXd~1<8vnL$|`0ZSatdXYO47flrFv#vIR8SAIvhCFEyWy)8>lD-YP)D%8rri&XpD+ zwOF?BPuy(R26EtYWEqs08yyyz*XtrxwEN(|EL@(mH1?;K5=X^2Iv2g{@2J_{(UE2f z*F|y@EQb!WwuE`B=@V3MbpsmhU)>^|m+Wub2?q2`qVXVxCT2MMVOGr?D0$2yVlxIY z>9^6J6X}PDjGS);i#FqfmbdfmN5VF9vaDR>Dstbz$jBd&oH(Lzgt_MIib3V3Rof-) zHsi7wl~bB(t({fmMJD?jAT%BzT5idNrbuF5Tca^p`tX!PMLgOc5HK>%VezEf(vn+j zJDWN4bG27w$T<%T-}5Ghg)jCJFy)WVxA1$lhBHBRFO7o{IR(KsJCOv_L<<6YCNq>o zl&DJ9OPB927Uj9I%0^7|=vOMhXw#0o?EF$C99d&zgaymLxs#0&A)c9-Ku>R!-{43f zGk2A<+EiAIv`8Qg*2=3h^NORRA)3}zn80Z8n9SXAN?mcIFh@p3WIg6>gLV~4-qxxkfLbE@60#mYD3(crd(_O6*2Cs8>frIIfflQR# zw^lM5$0wvJk|8N~Xspgil`PogIh_({tLr7Nr$3JFtiz^_HBN%pj%Rmiyg>#cT=uAA zIH}_&BrAxUs!4z{|b(uQ^p>lJho5o%UjXaR2NDiGiv} zPws0Dl3{Wvnd~hcvK7{1G?l`@kik2rlu)5%E==a!?PsJjuJzg{xw+{tZhd5cw%eOI z3K)d6x?aM%r#XcV)sW!MR(7W#0$}NYg0{(=>xj(!BroYq&lrI7D%hS|fcU<}E)fhCi^B4ZnSQG6hs*pp+ zu;Xhb=qYD6<2t*8+yZ0yp83|<-TtQXAnQ$}bM{vThtCl?aNKu(ferOxxE|}HVpaUE z^e67R>jh**3DaLn;I=Lt)$&iA$r%q%jj|}fDt9jfNap-8{S&*eea8~9_fA4& z1NxgdT#Ah*!$WLrXL*{qLQe--a(0HMZlQ=W-;KNV0@ZD zI7@zFzD@aYIGlRXc`1){I850w>4bwZIFn=RgW*>LGYh=L^q2C&;b$TPjW1&H)sA}Z zi3HlN{`e}@R7sgko*TjtvIvhE{cC>Q{F$>8w;BTi7HuMp^acCh_44=aBS}^(Pxp0g zi2@XNs8~4sOE_-kY(5Z)TTRYkLzPTKN=xX|`TFXkvDk7U1P%WwhDaW&j8hW+7xsgp{T~6Riyb z%N+4pt*m7ASt9?7#;70XCvyQJ78&CAWC1upkmdBpjjes<=xt0P&t=T{rZF9Z8RK|~ zETn3=(um>cI3RDU9e6Bw7b{Rl3{u7wB0;Pl5f4`0NDCrg}%Z&V+)9YC@3 zv#HgEf(sn0nR9>NAUn>_nYgBae`>iy(a4HK?pQF;7xbIe z#u(a(m0egN-$r?A|lC=G2L2 z4Ay34kMzixIembLNp-D~wv%s7CH35fO`)t)&~JH`gCC97mwtUq^Nn02d09_@Dm-Y} zGVCKB3$rj+Grwd-hn7g>jGJq2k$EoK!7-BU&RS+O4HLc8fr%5c9_F4Z$e_2SNOlLOeZXdYYB$MLaE<8T(0=_k#aa8U;O>lp={)4jjsY5ML0s0m7UD3i?gaZoYiMQT_RCDFr;KXcJ&dBu z-E{3hi)sbFRcf4b@+gHfyS`eL-EmaryxUA_F!qAHY~B+MdhfS(WllFQTJE*0#g?f7 zLKD;JT<~e?HGs8n;G0*4KMrPf3L50=+Y|wFZig#sijqA+%P+~zYKeH}f|fMev}?89 z_o1==hZbM6G$K9g1ye|k13@+S%+hE8Nk@puo-c_OdDAMXzV;7zIoUsjW@{TW04{U) zEptmEd3&oy$+r~bcyh3LZqSs*%h?g?W#wC`hOuVxry4UrOOU*4Wx4GriUPm=k_}DN zDIpU@F*7@=EeHe+7TJ~N?m}lLF*M$Htb+LXw`m8o?YD#|dMxgfucyCOW1?8}u0LwF zt&)|h$0DH+3zc=nZ=Wygz;$*M`B?Kr&SB8+(k|w=BPf!gmr>xY;T#iKn~KI**P<{0 zoW-tzDZOaPP;l&$Fq*y+bne`YIKMWHYX+rZv`YeY+5s5RoN)^Gwt?Cj0Ih3CRZr0e znr-T+0wxm!HgQU5FqF))d~s zb>qeA)nV!yL`x=qho%4}tuSm>Z*SxaGLPt)(NRtGb_9vn)gZa)kSLON?C*Yy>G3#h zh_4TgBIu~l)$T;X@go6Y|8OLk`07E)hokej04$E)sF&IQl&$pqkV#@xzTsfKPAJO& z+s+oxOp^ECnV4xfC(Jo0)rjnHbeZ@9A8vZ1!D|_~69>!iC40|KdWQv_lWc$4+4Sds z<6WtTr+>R&+>^O&i573I?GnJLgprpbS6@2Fv;JH^NwozUBXMX#f#oN+c4D;%&_>&V zFncN}*scteT#d&>(RkU}_%l0W`QbTF9J6_2U*uVh=!^jN?5MdR-&Jrp*3tqM&BUs3 zv)VZmfK#K(XeZ}y_*C3vwSekcJ&L;-C^TH&Z@RHkW&! zZ$W|Tqom3w1C_@RMcB!sMG~Cpj~1;}cAnva`8N5|_6K3DKF5|~Ro|wTXW9{s?rv(z zCQ8$ylEmNe*ty+yCS4t+&P;M)zGdd;TT(dDA<9Caro0jvS*#M5y}FSy+ALC`M|>n> zuy->C=^C74P`lYN^1x|jh-Q?B>w04>s~tFr$5t`EPKQ00EZKW6(h@*K=K>Ec4ySbC zkc`W7TAgRgeOV_?!e)IaI9t>Hh|_v8G2v>uSe97`WrgOgT|I(CqAX_p?!#fj8HXs2+xGDHQlP?bO7 z`;qaeW!iu|2Zzu6QiIxP7@CdgUgnVzHZpQ03P0W>TKsG}oo-{Wvmf%BiBx56(9`e_ zjiQ@&Oj`Gn^aVZjTXt#Z*P7_8gJm9@%X|XWhM%dW^AsEdtU9zI#P*RJCq!b{mr^y(a=T2guHOiVVGki-wndc|qx zMq^xVJjfVv?`FOHJ9;Q*KNq2dY*Og2cbkBt3?6CIGRu zKURD=BJ7WI{WkYwroTj)v$Gt12XMwEpw;xL1RTu=5yW3ef4M-l?EsZ(T#D-I4;K?x z(Jo43`twP5R{6&@Kef-pm$-Vn4l}3*a^|n~+Qjs-Ke5^`#x7r0v)WJNmnLY{$g%y(O^Egv&olKB zXt7MwE^pblKbhl|WqcZ(8L+xs;gyX)=V8`0X=0e@ka=5`U7@~Qd9XkUS70Q zGpQ`0$;UMoX{j+< zS*b5x-i2eMxe9v9Cr@sy49M`oMn*_|m z1l{xm0XgdHr#~Dhwh(1dEKxqOV`@*bGUsOEq={1T5a|`i(R8L=^KX%|c-K2WhPx5E zL|?{-V2M(N6-l9$7yF3OpygYky2)yb+oUQrW29tYxW|v8cTl*{!x1?3tc!4jxyX#BHc1W1YJwKUfWx(bTp z^hanK@3R%O=Cq4QRq|x4Cn5l)M4x44DUR7Wa~taoGEYY<=f^MS-10A1KL+(w*EnTc zb8G}*vvMzcG<>1g$Y|E9!eF9%L1SZaQy#J7f{<)ktjKesmz89ExUY@`k359e0mrzl0q#k z?*zo@l*~^qWo~^01kpX&Z;{6{KQWWq+mw+^wk+t1E^9mLW%f~Ugw881;+^%<$jJ_7 zjH|W*Ex()-?L!TWeV_)wrOugV9NV9;3%TgG9LDNZiXo^5mt))}mjPTTh{&lT+k2Y| zO;{qlf`>Lz2&ZFe_7NP~ND)n!cmR(;aKACWFe2i#Ik{-O))@mx=}yA^0PlR82N-8< z4tQ-dkOZX+O@gwXr9(i2RwDCS02%@aQaKMs`G<+*hoCh<0gZ>qgwf_C@FlORwS}J z#K+;Z3{B*zrvOZ0pO$91T?Hq5Vg&Kb#y4b%;K^yn(hm1viHU143$dD=33qKcYBi(d z;DN1NVQfI(u7Z}BEKedQyD}(cP&UUf(Z}?c=Uqlx!iuF?(Ch{rC8pGNoYPqw#W$ye z$`q;YoaNS9uctr$Pc670N^TQHs%rDQ8$gjLU3M*iZ@;A>XNLk^b_{mA$QVGh9WzEM zv)Z2xAD^_z>>@+Dkgb_^9G9Xjd4auYkh?+V+;PPdt6k8=uVyZ|G0|zW+t??!H1Smeyk^+2uNNdTQcWQSDQISlhH-E9pfso_#`4*|u-k0zkDd8_R!h0bjS zHNw?SRYY~QAuua)X}-1wexG(pVur#CZLZmQ{zI9TO*jw005iL|1{V)t7JcVtC}a*iqQrIE_{ zq%-Q#2^g_>OG_L$yGGWhK7<9gy`8ZQUnC;U0|iF%;M?(#v76oRsBGz;SqK)FBSA)= zN&@vxG6y-^f>(>uO(j|W%vh{v^#XjvJIJ|6x_0yePlfcgKZa+x$KK&UX?Q>DkS?@q zr6q0CwYgu_S|a^{AhY9=vx6!n7Wod{4ayz@&$wXfmqR??s_z`$%XEz1;xt)i=O=kHeyA`bRWLL`oq9Q`eqY4Qf7D<0$X4!2 zpe^+mNu$trZGuXqG<;6TcE`ZK>U|n<>&|R1?a=upO1JHj==UWcK2-w%C+>w3R6BFS zyEz%G@%)w?mlo(K-x;jcW%A&(Wlp3;tbRARy^TEP=E|-W?;35U-{iZy7YcmHO1~xW z-N$4YCt?$zG5IO9$X@yrX_&~eD2;x)kG#>rk7#sk7f;<8b68?~N=?s697I(Ad>OOS}Xn5x~w3e&kb! zvbr3jc+{cfMoQ!>vHkHr!8FElXrjw=9@vkG{Sadga5f{MxQF z<)1x=Xz}R7H}+#H&Iq9(O?ScWPJS$j--#T`IdOeD7u$vpzEtF}6n3_83N&i5D~;E& zy@5tEDz8I4qoYdr)qCP;P{NrV0p`cd2-HAVAudN7PJfMLlk^nbt@Mjgh$)i?M-I}O zZ^a+$<1^v8pAe3coaFz8Afl~QDcqO zD8$0P=}%a;_B?*+*i|NFW6utv1Z=-`cIg7WVO0@>1*T4coPaX4U3+s7VEU{~3}_`x z=6Ld^b$VvC$*UBBpsktbOvVleGEAKM?*Qhg@?lDvI( zmnt1w0cAxSWr-)l-HhXVCtl`73?!FQ2mW<3iZ+@DG66`NhAOxlk?RO90CJ z)$)o-p6nm98qeOBeA!tohtrqgC=|2Y^N+raTyPLqd!{g;QOu;1$3skr6z%*bf}@o8fI9}MnH{n%I28^+a)Zkhbin1I(0d~*ssZpgGlrPP_XY#l`sm{L z`Fm~?M4SCia(qUR3bMD^Z|7q5N&<$niUi5#1PN45rqfY^)yj9+mrQls_y|MeZ_a9Y zSMxfaX>Q$JwC3(DJ2DY5OWoXG1d~2%e~AN3e}aav zLhhl&m`q>wCEAJrZeOB_MH&K@;#1R?OS`og2_{Zei9nvMt$ZfBa5m^)`F5i zK0dEF2dcd>Kh9!SkeA3tn+p-r0nz4aY340Vib)8uCxr^%*-;Bebnh6;78hpEcP2(eEk#ntdhByARI&o_4POTDTSk%_`{V z(I{M1oG@xiRc3B<+ei~lHBsVRFySTU>~IYS--$-$-cKZ_ZsN>1Ir{PhsvM7-tHwF( zsMfGn6d)l@SuNLR>dPR*Qsf%SzX$f6Y^?J=0sA5c4)(IH8$%#5n;mlG7iAGuacg zy@N!;lm-XPG*vDn!Oj1+02 zt=A)j$`LMydBltIl+cgI6ef@N(Q8bN>STHo*-E)F9!JW^8+q>Mt#wSvn}wJ8whCYa|;;RNM3Jd zB8``m0g4GAI-8-1y|q7Dmb02&gTSZS427Wyjz%LHZAWSPw&SKMvi&9L|5ar#55!eM z%{@*@#~{evA+Au4a(0qc8_!HJ*R>9ctNTG8SqD#8JH~#-70Ia^;ZEB==E%3hDr#7> zl&WNUjw4LM4MZc6U2YO+cB8{mq7?${7CT5WlXhFc2kY2zOGnE!wf3i4me15N_!*rZ zcY{slSZfzIxa|OyAD30a{$;61Na{k+4~>` zG^L4Aw!1KwVU0BBhxlqU$XDF;u!0D=A70K77xefoUg*EtZgdgtkWXfD=(VA{W}aEI?auZu@g#rTfUl@O_D} zc6`Da16tiZOKm{+md4`gcD^}%U4zs&_1hu1Pu(6<;s9mJj7WR~YvuVVhomb*GyR+l zg+3gXoE9{)+;%|}JAu7^k-U?06`RBkk!(Tp(;mdpQO2mw)uLocqw}yHEmX=uy}{&k6*=^*N%qHxJlEqhFKcjI9f%tGBs{l23KR;2__H< ziKB$Z3iVs8B`obv=&(YN5)2W}utj%s(LFgrr=|0w_j?Q=Xkr_MuHA+j#rE<-Mb=A1 zX1x%(I*wc+Ys9BUBPO@eQKYq{sTyKR`>D!;nMxw}BWEF5 z1w^#pk}`)mc24*Vv$9-nMSyLWOQyO-?$t zJOT-JGSFThr>rV5r;!5A_dtS_JVFzlir7JSEx}`owNrr;XUa6OT`Q-cok|P*k9(3~ z#-J-J%n$@+8ykcMwRCBzCjUy}8jZT??xv8%7+o5>KJ6T0`my7tL?g@P7f}3F1@X!{ zF27*Swf-zUVR<%u-&uP5BdGl)G*yObi8f9#zt@7m%S&bPoS|0Z)`aW`4SM;v>ICZf^x z=B~z99ANDLvsni(wLTBh$-~Q4f$cd6oQY9E<^=6j=+!Z79M0|vqhxzU@M&JG!ZTBj z$wdr**3maQcdrq#b|0?L?ogBAidYB^>zs*MIGz9i{H1 z`qBps=3l(a^Hr*VzI~A*`bu(HOZyXP`av`PaNO=czy9g<-~9_6{Nt-$^B=*tkskk7 z-v5_ejsb;$q5SpFFV|nEabht}oL=62{QjT+^cqDRbM+e6o|5?KhCvbI5V)~ZYMATVdV6)B0KKV-puc}XlK2T{w^M* zByGmcT|&+%9yr_-dFFic>R!j6UjNO%c>O{VS|MU;9|3;g?`B(q& zPrv-b|NZ~`zyI5xU;pX=quV4Pre4JYu!hYnU4^yRCptehl1Wg=A1nlSQ!=L-%NYa-~^6&n`*RQ|)2Q9zr zqP~0m55GJXzCuC*KNN@+oR_EIT$^>ieQy3ow41qS^I!1f1HrjA>$J1_5t3}yHSU9U z&F|N=H{V_Y@oaYl=hs4Fe!n3k&a#_E-@pFH*RNmy{p;U^$$$6vn4An)ln-``FvE&3 zg7mHy`0w@a|L!{d3GJu_=$`*!4)Gz~LV0*eWHd>zPIgOwz@ykYHT9R*gkuoCPlH4K z^CzeY+!M#l?X-3FgpraWeNr*|qB=H!-{&bzkKEa_uf%TIo~XiW)CcXF_2+2%Gtpi3 z>!an9+L4X&2MKOLG9zLi9|h@d_Hr%aPu1ae>zf>julqm8;UE1WM;3uuVai8)a*lq= zvHNfS_&R&^&C4HicBbu5uP&q|p%YS8-4uo-@X1<|LcGGU%&qG-@pEM ze{@bCIv;#Vu02YgT7K#j6Tbdx=Kd2@szJDP{`vU*KmX|^RSkgX_pfo3#S(waab^q~ zl(=Y)&_^_32r<XOzdd@1PB+Z6sN^!e&m_+i(pdnz^%bI(^_|8?4aI*+Emmi#+KBb>hW=zNRz z*NVnlF}Szs>hIpoYuE?rooJ-DOPKFw*J3{+-D6(ORy5Mvdm0fcV*5bL4|Bgzn_vAd z4u#YLtGMc=BJ ze?`NEix#-dM+->0X$cl3Civ&qGkVnWMN|C|fG--?tBJdoM~la@KS8}mz1v26pE=)D z!g*1DTdNa?TqvkM6AAq;n{aFO*LPZ-^8Hw=|1a;f`daSPgC`d9@)4AOuhu!7Dl_Vx zSWW)huOk)y+kdwie|nWyqlaO@pd~S|NQjg`tMV=y0r`NI)FFrwxI5qKkS!IGfaot?wHHDapYqPE~PH{DMk{T zPripFEpAKhIH_+6r*uXkGgPfpG`^}eYrjK?*>rqbJ?>>J2&wui(^^ji5ZAH)o zSj4yf!qjsAiOS1Gi}@Ye-42a{5!(6s4b7bll>py>lks69n9X?M-}+3u|O*EIdz<6eAu%Z0t=q@Ardr7P&ZsI#FpHPh-CRJFGH$ovbi6$}d>%;H= zndtpjCTBp=6Veh-4b`#roJrLMdn1!RN>_(`c&;xX>@(?)`eH}TIO6I0eM z2l{MRq@7BZ4~Yf5sV5HWp!_uafJUK%?y04Dv@6`stqJj%jyu48D3S~?XmWb0)TOb)NrYpj9Xwn6_ z*Cu=Rn&%&sDrS#U0j}2IYNkWAT*2cvEzNFP603&zEt+5-^OCa2``h@Y`|TO_LAqxA z8Ctr#R{Lmo(RSEO@1pTk&y?TO%D=xJ!zXE-&`dSFO-!AtcU(nv^QTuaI7mUt=D_hE z4vrUv5r3ikV;X3((eNsg8r+ct;XFU%Ge7<_ar}cBM?_x!S`m4>_0!#(ZGQ0kvtsku ztE=7aY5MysMdZ!aKf1fN{xR%DdrbKQ+5^kK{6-w!@%(*Q{#QE_VS!l%m~+Q2dMwv` zQh#-U`Jdj9DGfmss`Wb&V(6_YjU8@4&0Q`8fL*Y45lgX}tP>V&G(Pt!xQBiH9@ z0lBU>z?VFUra!Ux8T(0DKrg$ut@QRQnvJ{HeHy+YKE}OTzMKiZY55@jrpnK$lVch6 z$&+m?^;2P+6dtGnu>-#f#{bJt#ckBL<~5Tqi`!7fsWKi57O=lxuijTSk$=a(KLL=6 zi`3)2=0`!)_asZ~s!3E5y?=Bq`3+7razhW+^Tsq?t^yC`7<>A-Rr&E-LxIo7&k3>sG0MxXyxEPL-VWV ztg?>+PjFe>hIliqDHxHCQrdB;{Yk=p64(=u0rts9#$H^&{v=_4XZU7tr|`{V)ki{J z{%Q%y?%mQb{k_@co7<0e*ACpYd#7&N?r8eEB=g?od(NMy-Rr&kyJ`2hH|?JDN3>5V z{@(-aAN?-R2H59CncNqridEv}s(+8K$b8BJA5^ALkt~4{ZdZjRvf6-ogX28H!~{+U z2aCV`d~m#YtAb~S#Xf$DBE_cwuReIOfAqD=c3+&)Zb}31nd;T%9mQUim6fm4^K|3jbexjNntk3YCNGNv#fe$DbRw zzYorEg!+YT^56ZhVl(u2@++6?tjF9%kdS@EYwXqsG?y^c5%T~aF&tOH;ZF65hh_(E zT3l=espk55THN2niJtA^I`;>w?_r0eRbEm7Q7AuE5<)}K^7oAIX4hh`&hGW!W8SoT zz8}&4nQ@s(p*AjqXF>4!q1_^Kwbdz!IVCg>G&}NxCIIB-Atj$DIb@|0GPtIF+Ubv;pH&aSpAH|yM&mofoA{XGMcf*iw){;+ zA1xy#Iyx|!(a&pou@{$=KLGB3`B>Al&#pBcO`n+TRXBMC72jFq8p5 z?8M2nvJ@wV_eJX74AQ<8llQWZD12T#sQO!E-iybZZGW~qB6G9*Y&&)Ofyk_Qyy@@S z(d6t$DsR$?M^*hN#N*ArUtiwqzsEeZ=iCmh9?6RM|DUS<9`Eq6sy??ja(OryTv#BF z>>UuF{O5y8%3E~vp1QcYfPZ@+=^J^EzQ6i?P&dwfBYFDrBih91pZyIAZ{+40`9bp# zN}lTW!*B`F$0%I0KCSd-QoHWO{_XEcZFt_-587jXH+70`RE}u-o9bTZoOfK+DNJf& zpI7&v1opqYQ}^7AAoCzD?;L-b!e=VaC9ij1&tI>9e-WmEMq1jQw-HqElaRcTDfLGI zEs6F0fFx3>99hlew8DD$n#;gze0+G3TswA$1}pDYACdTgy)E%*C1^PxULz_BUXrl9 z0%O6Wcp+kv>HnJRG|R-UMc!ZDqz;)6Z_+i_cO-rNv-G@qUxD?jR?}|E@TGkiC1v^vfi1Pe{fA|4#$zZ&rMXRJ=U)``V*hb}kY4fb=U7U^6b}Umr4V zq~fjYTq1Cdc<=2>h07?Pl!~|eeRX#4_ci2_o)f!Uow@!F^-k|>5dP)M$|rxd855!b zDczNl2?GOMl6NPchb}(lryClgS)zr0NCYutJnxUS8{B=9Nc)l=X!w(q1K{tD7J@@~ zFFV>z5sj41bhAiFn_Y^Iy{7qS74>)4dB~>qhJ3^KC;2huPmt+!p7UplYI5PjRd8sE zK$b|CXjgPq^gvb#{OyXII*}dG4XacJ{?A`93-mhq7;9nDFf9X}H zk4xVZAuWDSY}KO>u37ZDlk2FLMt_IgN2Bx8J>A41@?-+3|EAe}_oSSQFH`H6e{o_p z5AgnSFaGT77s|<-{n~He?DgsI&HjH{PTtDSY}lLr?v4EtInmv(Y11Ai0Tz-Z{TA`ds3c7?+wBXEI_5)$BaU zkLi6x?$-QPaip13k;2wQ)q4QFM|cO_-z)MPo4-@!|MuU$*W`oE{RkY*Rcvn4t}9Fo ztd*a?#tZWw_2zMj!;%p8{XWos zk9YQFVlu8MdOBF3*LlzTxw$7a5qO5-nLKKpD_B@)z8=;;Lz9_$_Cxg1xpj;%Ee!PO{=>;!hw4=PbP>Q&vNI{1C<)ZPX z#B97qe0SublRN~>Bs(B`zd=Y2Z5Dfe(aFwu&C`-S(o?@o5{K|2xsy!Gd) zLbovl>JEaiB-JEt-noM{w+Rm!JM&9) zS9kmOYgC`Lg@R$_{djSALj~kPPR|!~G!6IfHtS64qCMt*cl99N>-^=N@D4ZSQ5Dvg zu`CUPp=3_&g7t{`{T!xUaK+u~=l$!y{UBxZ-+xAGU-CX-ewFW%qFj?+(h)WMaUWW# z#U+lChF;X*h+LFkgh!n%`*+jw+YheF=erf!n{rFhOgycSl~nR05%vwfy^+)<-=Z}_;X#7*d*rXOlMLm9 z_;ShWlscZaBZ-c}J84C^#y;|jb|jX(Rq(^~r^IH|i*jVv^e$SbG>f}CdlDa`zE!v% z$ZXyy^|VK1;RBid?zd(3Kl_}_<~c#Zm=Rj_MyVydX&{BSSsh)OX?5xJaq2|n$-D%m zbWNu75PkuhMNHjOxJXJXGx2`TjiLr~~S}Q^FkXw%LX(hsuA1OdNJzW$+n&I-4;@0M|6&;q8-ysm5!)Jb5y5#Qe}j-dLp01*XnxH!Gk)Uth{!PuNEyh#CJlP5Zonsm6s%|AGAwG zg$%Ejl2i|jdL-0s`N12vDm@zTlFsbJQ#y^7jMrP~dN^<){BO}4rPizSt1xeD`lN<`Z23DS`XwUjYW)$&IS^s| zTLFzLa%hivKScDb@J2IVVD0nFuID&Le@b+=V)k~T-WFQ_UMI?BMeo|?b0CovoBy$23R&mO@G;ycB3ha)M7InqUOsz-cs`2HLF9rXMXkctMz@k!M}Uk^(6Mf2zts@u;-_jhV?dNq} zDD}|H-21lGBQ#>~3yD|D1m^)qz7B^+lcjLRg*Cn1ud74z>UCz$;GB*wLLL&#Xg<4W zbaNuAS4Upj$s?+MG4CF3DfuqWRVQ_5_q?y3c6IU$Gv4no|95X^IqOL|;CXm=rFQ+O zC9Zgh)U5NL3hG>k%u^XFv2~@Ebld;9QcE1&3Mh=MHtZ8^dwEkwO?95w61y-jO{1OMD`gMA` zDXu|fynJ_BdCkDnif&==oP547l*oey`)>Wj?O(T-#~#n(}f1tphsAbbTMM% zOI=Xl(-BpZx>V|8>PI~Xx$JUoBk~0*HE){u<%J+&@m$qZZ;}Du{WcVM#-_ZP;uXXH z_@U=p(Z2$Ujo0Um+ljRLQKA!^aottivD{9TPF#JjW_a{Y+JeY?SDK|toy?vu8 z{hvUwaEO2Pl zxd5>S>sm8I$@!fduOJ2N%2IioJqjcjEI74%`ApOAhb)IvZsTXlGrs!*Klo~6H@Mnq zdi5p6hi&H<6*|wh`|^2ia3*6kUUTND%qLsuwPb43lNv7A_6Zfj;AxC{loxsAArS zKr3kln~>|_*?pll6vaPO+rL?#{3|Ser`gu2P)6O;WL?f_Y!Vv8XCwhBo!_}Rq ztE=8kFDArA<~uCS6>lsxoyd%B*lEJau3`7>CKoO8+HIh`-#qd7YNrXV&x0b`p)b~<&=QQPKer%~eFjmk^%lKkRsGDWnCOc!-x%v6g&5%@){~qOZ z#gE=>I_u}Dw#@O~bKuqGHh%OojX+hNNi^H!L;GKN1t z@{@OLHOo$vlRBIVjNCqRaR;vfkNh@0ges01& zSXaNV!G1yP_wFK=z?zQWD|z?S!}m|DQe?X11uIwdw;&o&fpG^{cbkWB1C@rew$)ph zf`t>o_#{lRgPWb0hy@LCMq2C~?`5!4BlA#n+B|1{f%6CP_W>2BXp&3xsXDv(evicO zZv&NQhT;KKI?G3@GxK}=)e{k9URZ+cZAc*dq*0u{00$rVlUps(;c&JeAK?u;z)4-? z;OF;BD8-*%p#Z-lNcqr1`Smp}-V1}}XgXvq@lO0A+=dKbvC#7SgMMEiFAcFSJWwak zPwM6OVNzP^zBr0Ek_7kw5ijz(5?_Pd+n@PCCl8Cdfm&Z66M760^>&O^Uwc2KOeyJ|6fkwk(g@at0 z!agv~9<#jIT83{R;W z`AMM`zm*{f%IgV@cSvnukQBb3$w6a|7%o1o-y()Md+*Xulc?rPUR(*29m!niDRu)8 zuvWiwQezZbEY^)@`b$!31S78FtJjF#PS-D5epAPIFSeWPQ<`XUx#4g4lSEjyD8H*J z_)K%e)!T19ii`CQY<@6lex4{nwmj?d5+Imzy?hHGr(Uhk*77uulkYB6`b$_`jVXnbR2w4~nzWxi)E|Ss z@Yqk~#>VT>3ClvZh>! zVVRq8K)O_+TLJm)3=glSQGT>KVrxRlFou*LKg)DIkniEgzMSU4WSK<2k?p62d|Lbf zOxk*fgtR-rJuRtG4r}!r`;K4Etux(UHPT78EGG>V!;&AqeQ}M`*1_3mo@?-nOACH^oTzX${1B*r8(pI$m1utB9(&l|Ip@c7^+y5a2ct$$>BgFDBXmQf z^|$o|b*U8W;Exgc0vns1!}sDRl`W(18KtsYH%UX%EPf!|lx59?senQUp5!xzRdNYw zBywELoKv7UA=>DBQDJy44nCSlYAS6M7YC`9EfO73END!~vYEaRaZvF~M{yeMm2W{g z<9+`^->YTlxPGhDX;FNhAF2cVA}ux_n)lBj6wTLl(7RY*3|A3J8qlmA3qbw;@bXiX zM4c*n84I8yzebcFrOK`;AE)!FPd`BzL5|c4d|;7T<^3nSksYVaJhj z&dyLze#?w5uCB2!*v2*~`l6evL|}bVVD^3>)BGw0f&G*q#X_v{C(?qGOb(&TdooUL zwvCzyObX50b~IIJ92zGezh)3VS9$q8X><6R-SB^d!_&^LSQBg_O5$p5wkSVLh?VA& zU#RDHAkoVGO)b9&3s82{{7AA%v60|q4x(l_pADiOU5!elCbYb75cCruQ>;zF#cCVC z@4rF(ZN|mruSbgteCMa8e9A=IzZkz!zZ5<5f!T^VaHKymkzbvQZ{+0IrD`pHld`bC zP2m&q$j>4&nt9qcG69GI-wi4FNjINlYAX72_R@}+J3frC!sl3t()?(jX$tS=A?7yo zqbroSPt_*qH*!Knkp(u1rx^`e8Zl?53=4qO@Wy^e>HAeY2RiYreCo$Eqf2=vsTQv| z&2Mv3Ac`%BZdbwT8I4}cT{%Z8obx6ajPTu$FAfuSIWnQ;)CTBa4i`3KkPQh#mK*}X z;Wi^Ac)@~@lIS3<__H``tjAMN_{+arWM zd?LZP=uC(dm~fAA@Uzhv8UjlW+h6T@-8YJup2@cw;&wcgxW5epkS`~>?_LKb_3SX? zeteTDgT!V8hbTWB#^L4uU`Y-;8rRZ~iN)K}E(?Q@6f1ruqN7v?n@ZwI_S5_tcFcd8 zdHkoJS{JuzXgqkI#xmw{_;A>nj9KG|xk+qGW>}FMdOMIHcjK~HKQian*5l9f*(soc z7iuwzi3L@bJZAz{^UFNykJ%xHJ74;gjKxD`Jy^Zc9Nkop+Fx7Ii^O=7AASV=s86ws z&V-n-CT2(e=$~v4O^}0>h)lpl#TdGG0fbE(4~? zuM=lw;I-{8r@W|512DD$<*||(*N>-}16qEBZ#D=F!TF!TP|9n+jiF|`9Y!OyHz8ngT7#zwU#Fd(DKI}t;KzQ0VKRnTl$8hkJIJ$)Zxu3p ziz0r9TWMs80Fww_%vqtEAEcylWqJHq9B5D5rX6LZW1x#ck$MZw59G1r@RCxrvk`1H zGxi;<1rxRr-I|#xGP5)NeM`nH1wT4VCE%V3#=wF887&99CXs>2J2Ma>_VpJ$Wag+* ze8Yl(hsuNZzujZZkJv+jU6daSb^7)12B`l#lch@`DzyBnX#;;LN9m?AWW@=cFJGkJ zI&)-tMxak4t@#;JjOiGDs@U1J_}cto9JiHn`sO9Sg~^JQarB0M3Kqer0#`SwMYH&u zkl&bLKm3!3kM9|QS$lpR-T8e95~Mae4?q13CFlL~;F{VJ*CI@`G=bwo18itBz|+Cp zlY~cbqF)5nTU}u~Ro9@QpM_mjEpkg6=H-3TyKBc*Qe?JnP#2=vcvU#&p|=#gfP~>2 zVWVaN$eEU7La;-KQZ53MjumvY#cXm4VJh^Vhz!7e$trYTVRj9g$iU5%E`?Asynq-3vjDv- zI$^ImH!#NdejHTBhWvI7fehdJSxre)Xd>MMZ?R?&Y{Cq){lJ?cbx%^+i22gt$yP(P ztlE&iCvq>Mq8z2s(F5K5Txxzoc(H+#8^@9ZQV8E;njb$8hQ%skJgl^0=IW;x9E#&L zBX9v?8vJ%O!I`B}`BZ{xl^1SMT){G2xfQd(zu`6o)3%)_p~Ffn)!i63 zUpO_~C3fLzmzlr#`BbWBR2f7S@p&b5jPaaRJ}FW85zPCNoyAWT~l@Q^*iW_y|prygL2iL38f4%epGkc2ZM5q$WRt6>0lBM3C4yk=|}fMu}Tbf*+1`v69JU2SO* z@V2A)qKoovTq8?kRXj_z?Z|8PACRW6jg@v{sMr#()vKKNgNCP-CNz1%*;(_W`Z5>R zH%cMx_=5pxSe6^NWwYB8R0@X#mmRPi{$yrNi&rK8NEqi^+|5?zC!C4w&|GAWq$I3I z4|jgza8afDb2_3^(;qXQCFS8%gAMIRetN!*yL`rAL!wII>jd+rKVi1-_|!bYYyn5pA5$4g%D2LG@y5kOj(mRN5aXM6UJr?Qp+(JfT#^zshUU2JQRAa=D7l|JrYMVi3oV$wz2F^T&wR^! ziZ3RH(9)^46Z48Ylehw5oo|72s}(MVB<4%LZYqh{4VYtT{dMuo#Lp-VT;>|V*y%05 z6ux`LMkR6@8i+Fc2++;!`n=2RqwC<^Qd$-&=-m94Yw*4BZ<5*NF*rwdj7m-Op~@#9 z2k!(WINg|C9*a8!W@*Q}s5B)nneRknV4?I6i`Q^D_Q7tICNL{%OJDYgu4p@2D?P~^ zM6={e86}3L(E9Kwk0HeMw5N%Kl#}0c+N@o;g!>kBmT!NI`;c~VQvD$`ujPlWkhE9q zOX2$U{7Y=Yke#oP3#&61co+hy5h@6Vm`9b^4y$(LJzg4v0!0DAc> zEW4dw8`q>#fX`An?(|6}5LD=A9Ep0?M7EMqbbhRth1mHeh!-g_G%n)gL2$*8mdfFj zp0rYVQ@g=_NxiV7-33+R-JdZyGcZ~J)%i2zw_j=)Wa`&9<`MhUCl=ycZ)Wum&-p!d z#?k39I!|#l3C`^oZhk!XR~(VZ0ZWT_H%<&%aD`TMG5Z4WG7aYAR~-7$LK9zb|bPDo-%@}gUTG@(dN{PGASd-Dm}>6~#C z2>NXeKZXf#+A}6{?HdO=@ZB&S0Bz80DmAiI7HiV7juJp~* zR!9$w!29alx2F5g{Ibs&aPkl5nb>|w(5?sBShq{l7( z&Zj)72u7zK5U-Troy>1j3rXoer{dc0*=c~AFfGYG8V$%~FxDj)#}$!L{u#~Do^NOJ zQhf7?ub%(wV@V}JU~W2d+|%wLfXbOrj$45R=mMk=MS$Y~_m=~5uW~@;!N>$l+q?Gi zGz{FHEZ}jS=66!&C)*(tqs6z|hm|Jc(U`xT^)}uu`bY~ux^b?yO^!x9H=oq~X|a-Q z(u8+#;ncZtlEdXA0;SfCClCg$u~Bv~W@mZON-9anvE^Z^(KN^=cOYnH>1eb6(qMFU zV92vD675+-oMLuQhBiVN#oCO>P9aF4`W5ShZRh;})6`N%Qe@z^vmX*Z>q9b*y}KC3 z7oime+8szm$j1RTvH}De3;j4+ME?h+zr~!lDwCSg1Uay)J|ode1cvRzTvQ$ ze0=rNa=C26SEdFpR;U*>6N&VRx_Et_#DYV@s zN_Ha4Y@=_!Qkq49zJ*AdkLS{tB(rBFR?h$N{SfJBB>DUrT4rBj7$R6korctk<_7tk zC8%^B^a^GBWp2-JFv{dIDVMR+3)jws8jQAtwava;E=QOraTUJBNY&_g^ngQ zzX_uf18}aY%sAJNB4dR4V7I5|5P14)oQA=~-MTV1aCvJKbKZT`HyA(z|NL{K015Y{ z(9CFV{(`(jg^~!Ij=Ku7_ECbJqdiQD9c)zlRjr$mX-#Rxajn-_Q=MqSKN2Dz@cbDN zeb%uU$6ehhiP`CgJlN`7mAfk#*%=%0t+~{ey{QP%@SQ+;<@CdD8IEa|Rr4$ z9K{t^{4LclTY9LBp|q9GihU5+JqtS~RM4(;GJNVLIqkV6Jdb-ui9}7IYJK(ytVEoK_H@9h^GfXW&Ip?7}yK;a(Vk=BQ3r6Ait z?XGNLdAQaE-NTkv2YpV4VPSGeCUBUxZpVsp9&rlktM$i_FWt9sj>q(m8wCvAs`3)M zSE(L6$IE^<@@cd{v?c(~9s)h|CamIt_I!w_!abUKJE0A+hO0}=c2d}oh5Towr9YH_8pmP7 zWmcH|dNFPdS-_U#)~W$+9N};?%1s&O$2sUwv0B_vyTZ;YTY*b`PLb8W*a$9Rx7rD1 zT6)1Lq#WiH00br6+p)~yA^=!Gr@tn5RhTphmPE>9F!=Dzw-XnUd*+nFcen03KPr$7 zYu=8fUBX{nN;&PDPn{=-NvV}>-m~;7TT+JXMKspR4mZyJo`fmF6v!y0Y419(S?Py= zaW;-&=}dp?)9IcB2&i&*A=VSgpy1qDA(U`Mb7^NeZb|`n99)NPo;_e80$9;lt;+)R zlf$f4G;S0@Hs+TF^Z$0V>ZV`%B4>_*9I|oGHvP z7qUL_SQ>=rb=DemPQyg=WNz~@w8;*9YcHLjhhd^0t-`(CRU$qagKD1+fM!$No+Toy z5HgoI&@JY07YkudE@ZnCXU{q*npk!^TV%Z;qXYzVmL59}l+uo63afA&tz-}BaXXaZ z#_7^1%F)F`G49SpD8o5&mX!n2Q5PGg!%^p-KSilr>@LLGd|g^55@nq`Ew=@Kk9Vb_ z+5p^#2ag8Gj(1#$Rd+JzTV&~eoa-f*C1Sh`m(~in#TMHMJhQ6@sA{6ickreXi0wrf zvFZTI?+c3=jbh7NVL5X*TR!MCv_5zm+LPXl`Bt!l-J{rzh~KkpMdnZ&5JlgbZ2T;W zyf^i7;>;Zrk5$_Bn#|G#&Xl;_6f$-u9YpjZi{o`F(#OXVzK`OQr zS0ZhJr-ZS6&>0(7>Le`mby~;BPA4eVr8OJJi5H3%gs@LH4%SEzC{b18TeB2|e^w%P zt{ca9ly9aSDwkW8cgX2e4WH_NC$RGbfg+Up+iYfb`^F(HJudcxvz>F|{cJ+LdKrGA zygsW|$cSVLiE`79M-Dq{5Bf?Py%jt}CF}RAxIP&X6OmSD6~ug!-mgI>bASYgw-t1b zb>+#7rS3^N4Cg$7+C2+u`RZ!i5XxcZLN0gZq~%whEh&`GG$``e`P~(_6690*rWo%G z;6F3vz9_nJ<0dOTZ|zH$tp1}3M!NFE-MTx!H#8_S-jxtOKjFdd-zg~F%d4x6gSaS0 zf1^Z%g%tg2^4NgG@Dm-eJFNR80=iW8BOwLw^OWgg)tI z>`T>}ZGXH~6}p0GMQ01KNC`CC3eX2homR?3@@CG;TUcRdkcp%-YqhAZv7MMVyJsAu zf1^YnT?ss{!|*t)D7L_v{jMK*C)LX6IJyvsHp!p1$zFqxIu4W^{Nu*0_~#`X-rqIt z#^m2fb>qmyMKi9Z+y2dbqUvYm01Gi`<6O^0R*qfnq4^}^p5L#ZBq4=FdHIucK*7b= z3<6L+NvQ*{C><#3J^pC~bBCYSFdL0HS{Zsw1BS@i-8MXz_cou*=#!{2Rojc&vvcfh zP$(_2hIEur^yZUGk43VGGEPZ5SX^PkYd*QVy9-{AYqJxs*v*ck90Y%^%|&A9(|>OO z*oj_`QWp>Bad-JN%_?-^aY_h;LHbF+dI^y9)n!%3slS@Jx;0!@Wj?zL5T1=eD=lJw zzzZSoCaXD2SW7pE>5{V^&>Y1F#rInQUJY3Qh~k@#NeTHvx#*>wMk6WNCjTQa+xffr zrO2R2d8ly{tzH;6D`gP~-n0B|*+X`BpnbHJ1AFs=wLV-5;Z*LnJ5>;-C3z<_+*Rx5 z1l}2zT-2E3{!dOM!Q5RpK`EA1L#bV`=P>^yhhWvPSDO!ye)>ePf?|H7oe*7D?T9!QHieSLU(?EY46RO`-9{IX1Gk)T3P%`GQX^>^GlwuC58yJ+EdBKmB(#&^x^Xh2eJw3gby%{c$CSE+|ZC&BihIhc2py`R7`qN@Jy+Ktowor{LUx z-JOh~W+_QAwZg)2jx(KL(Tlw9q*MG&n=}py+vb+cS8N=*k~GU3O%j>eNim4eE}vA0 zG#9UHyed<9Yk(;kh#U*nZhsUNt!69+?`$RIE!NlAM0D->)+j}US6S4b`{NorI%Naa zkIPaWXuYGv2wwzC$veki%m=O?vgtL6C28tZ!?f{P_`6`UW+8kT4}_Btu{GQ+4>}1I zum$oohJ~Eta=}mjU5c>!#ywf>uG4Zt4A9X4_6)r=R=v76n~Adlg1_+ZP8-Nfe}L4= z2HPFTMjzK^CI`M%ZK}Bf2FG=_*+u=cxn#nhO@IgVvx)n8#p5~uJ+Q14C(ysU0n`|S z8rC?-$2WenLa&B3di=)mb4%K~jxvOkNWedLc;tjcIi7^d#6zF*& z%jf+x<`IzRt;j7yXf_D)p-?T_HMx))qWWqSXxAl~k$iC!JzKM$`Gl756z=X$AuTu9 zgX{Qz_X?evcsBv$R2S9gw_4Hkuq?M-EN@p%PpgN|M^A~AlRorKtn_Ce0`^G33(K^pHgJI}L$lEp+$2cf8TVBI-f z1HRPA2$wxRb5)C-gx55&)80FBaimDs|hPO)}r(ybH9d-AVqu z=&XRs!T^cQJo4-#Tq3 z1w6i-n3I*99^c{Mg}r!qZmB1Q3Eel%4kYii><~+&!BKGf*?^jgir7mB0nRrce;aG@ zzmI@STX+>piFFe$PR(XDNUS4#B9T?#;xH z!5HQu1;@FHTEs=`D(g*6$E6@hwxbjvoAqcR{+fA<-S6~@^D<(8{3QtXWZ0ee7Oak0 zeE{U^p5>Xd`55gd<;-2h< znO3b*HQtpFO~Y(EzHh%!8Ow%u5EBe>Px3TnDe55wLhjidCd;ey`S1J4ao9THOu{BT z6=t$AzlU3%^r%3V-TNi2quJweGTxN}_+85GLi_Ce4EtEO@b-tZw+2tVR2P2ov|vH= zRsFiVFv|Vl34O!t&4*=pj04>Dr#*1BV@4yZ=cg;n=9;_$%TzvoR&z-lO1Fq3wr4T1 zu4l<^JHU!|0#W6o^vNeZlL~P~AWly=p!u`_#29b}XG))pQ?)X7NXf_&lXqIqC!Z2v z;D&EpZQsAhh}1QBqweKe{or)!a33kIaT-5e1}1KIvddvjG#Ko#AbiH>B*$j`NmD)O z>IHv$Q?Zkki7k6&-?(#fK^$i9C8%T03{S%jp8OL|7I2DgSQygm5jP^RJP#03MPK;e)=(&az>n1;<3|$`Sj7M71f^H5i*SQEPJ?6r*+-X zcBgVVqZ_R^X_~JR#CFy?FZmXxoY?lHDyu#A&Ke0GrG>H@t40CYUffX&$?w*ljQ@<^@L_^Sbq zdpy3>?;2=xw_op3?+9i?%*VT2otvP`(i_!_vv)Gvo8cg!1#-7LhB%d@$szM`ph{$j zwp`U`r8EL~AL1{(1>-WF^j<<9lLalRnRE-N=P0E_d%bZs6wc-rNgnHlIa{HZ)Uy_> zSMGY!=pTbvf9Zwr%ZUOkRZQ`?7v?UuwqHusS@m}Ls);PtR%N`r}?yRmTDqDfQ+cwT~Gsio;*r$&>)C%-kr58VWk#NMW7NOr3U zd$1`+;{V&X$Lpv*67x=Dk!ZzDPi4AuB-4*WwUu@_B-8Jrb95;zQZl@`*m!zqE;ZP_ zOykN*w)LR$@O|x|5G5ffC3Y}V{P&0Dz>zqB+x^clCexwjVgz{$0TJta?Sj=0p}#cW-1?ikJ)Y(5{YfN4M>CJ zHjzNro2jPfag+|PG7J{m6R*ID1FqvjN$#Y!1Q+?*7H}p@f&^dRC@HMm4iW)M-!vnc zf(;VkYi@5vq+Xeb$&A9jPT^0i$flQC*zP4xdM7=;Q;EHFiWJ({TP`0*6*reKFS{ds zp-2}eY#l=08DYZru?q3u8zs-(O&40TKAjN?@v*UyiiO)fUp=nEr3b*7#s0ZbHk;!| zl8k+%OhmjdQE;1Jg|iSynwxKW6}22T5-@O^AnBWnnjNEs?d~SoB1tSpD~?Yw+FvX> zlHhgM;cx8Ik(l)O)y9TD3oyk3&gefxeWSFt-Y7HN8HMDmx?`&%s4s4m1YounNoj2N z*gFoOT5~b%2@?o*gq$(D}NiM@nH@m)w|o3h@)Cu+dNTX zl3DcaN_W%L050!cS2D=5plu7Y`pu<&ur@J4s9by(@P@xcP2JCNl$TCRctILUwgQEK+?^dvNL7WUH#-t;a5e6OmYfJI?A; zd-n`3xd(+4d(lKx2(WD~L2ogw2Ne&-dE0{aku)z!D{T~*C<60l7mM;%RB#RbBFXh{ z#o${I45^}U4+2s6;Mk%dPabIrKXcK8wUMxMm$O3p#7%nlJO+IdYV1MWnd#R|VgDmp zl3_F#xjxOnLEgIEYfYJlm2v`xV~%CO$vw!Z-CVrleTk=fZ}|?R0H+w8cT#eABJ;+-9VLj*N67M?vnESn~&vAM)Fr!Im4ymz&- zTIZ)YIZ9!sHnYk3xdjnOoYXk)faj~399-&zf<0a;&P%wR8|fdDQgn7W!SvggFyDpI>Ug_P$&~3^-lP^-8nFjS;5->Q zf~H3jVI03;**j2`iCNv+M305?_?)ikOX<8(kkEFo&FNWGP}zZ4RMv;N-SlOjIwPkb zs5nwSgD#d2zArqnC^Ap3LnabJ*eFna-nu5XLlGtQXO#q!w5m}#;(6a!wh>+`E1TcVH$QGNmYKvC9rZVEU#HUy#mC6R#(i;gq+tyb#qmz z+JS2D+HHgVE2tYq5q4~MyWA%&P}|-aOA2xG<^nYLb&GmXmr_N725*$C#~`;3EjVIZ zmBlW4>V;9hcqF2*=s-Y1!Hz_B5=`kjt49(;q(M-#+de`W&MsDt`WysYip{-2%FP{4 zVn(DA;{#tdJkPm_K{6U5Xi@a$DnYmP0Kl_?gor7_~Z-Q7q}LxPqNC<{uWdC`2k3 zb&FaPDgEYhWAm|a50;H2V#X~Sepo{w%#*b%BDnlJ>ywW0WSAgr>9Jy8vg|VIEF8c> z;uw-GJ)C&HQKFJ~<(xxFY;_+uMPTGJ{EQ1Hx2Z8@P7^+8?cMZbKftbJ(g=^1U+r?0AB)>x-BE$ z8rQdpBwvz}2$n@cn`=66?;5Vy?mfs}Z=>QGX@ikU>UJDf7aTlNul$U}t^H|p#gPP? zumCd~Rk39xfOXb3Cv~bsn+fPf0j|4NfJB_Nxt8$5W--CV@otBxw0quD7~O*b^F^-^ z4{;v}Bp3^sWLBuT>b9Nyg&t;lYK(&?akVzI`_dqx7iqP7Kyh9`F{R8V;RcmBtj$#t z;~r#sCa193DIEBUwoPymgA|0>m-dcS?==CJYGp(=7m1zygRx+^jgm>6KC>T8)kso# zRT3o~Q~Vmm z$r`0Duzi6;awtt-0&));eIV0y9`KNPs2{#dqb|QqR;fNy9is`y9Vh{PqhxU=0Q@hJ z+bH?csRBH`VliY<)@%Es;`5t%=^;;B!ISN)C}n44>H?!yWQ=DLbBGX|$dU6I=V=Se z)?G8~_q9l#kwkPtj%091wMr^+yTYTBdM=J$V<4;JpW9U}uL((SEuKvRHOytj0O-8A zcpK(D5>GlIQSH0zg7v%w)?BLgE3t`aS)d!0scl~cxo12DCh$Yk7l+Q?a1!U(I_X)# z+7-uBFufObn!Xogx>)@(7i(!7siyi7!B(V$GgVrH$VQ~uv0a)v(;P0+^XJfzI!JRVvaB7ZH_*g)dr%YZ zv9Mo6xVglBLxIAYr)R}O^FZqRu4r@Vz&cLAd?!qDk6=@0Bzk9|#o?r$6sG+j>Dtwh z9Cl|+$L~67@}BBRT3+-6^Kk*&s^sHr31r~hN20SPS2z6AB$Wy-M~=k(?|wS{fPl;Q zit-+lw3s5ux8B#nfk0?;8&#$F^X-cDze5x3^Ldh_M2T(`J1i@pBv^Y1>5_V+eNC@I zBLy%L9h!{@^3Ij065qSVbuN)Xl8Ou9;vNKkhxk=^IpZT0_#2Z~kMBif%a(CT*4Y@E z=Nl#^zYbP_ucb;OdB1ba6D|tO3Ioa2kN;NnwReU)iuiIlDWr%3izH$cMkdCSjYsNh824Zw}|n)^V}Kj zaMi5v@P{B7LI=gvgwBzYd4aU@-C5!8~l*@NQ1 z$xVo9Sr2&)P%FOz<-k>)FcY{#b7&VsA=Qu2zSI>jDxkq)>W;G{#HI(U7tvtkllrSO zZ4@wmn<#s;6?x&)Ac>vxQ4Y<4Z7z0xa+4YQkHaHM0+%TVV_=SrVt($7RO8H@VBu;f z?w9N}syJ~9sZKDX|DLi7x=BD=F(v@ z-&vhxB_npSCh>UBfFERlFvv|0vhnAmw3%|Js!(y#%~jwx7P=P!SaT`2 z@H`wEm>-)N8R5q^TCFW*2TW7FxaFOkah_Dyu@P&;xD!hx=SWh^)6KAB2+iDFaWHxA z(??)fY}So1TTe0AThmvRmQ~s)vXKTMy;LITS1Mj68q&^98B$L^fi+E9sfD>B5W+eJD&bt8CtGO~zNowCHS{fIL2;TI|IJF7E z;A$Q;4@AR>N-e-}oTq_{-xMG!IBYJ0mdQrq|95Oa`)vXYyA`#va3$@FonG|G(nF#n zF@>`wb@s|LvAy`yTQ-w!EDa>1w$%Q+iIL2F5!ynD;kN4?$Y>Aky$I&mAC2n6roJtCu;om zRfldOZo}}!crUzM5Q#)uj|5TOib0~AOJq@aD5{|ClL_G^|KEY!?4nP4(@PtXz>y`< zn7Go|)fY)ze5iU-oxE@JaG~8IMCE>(oaud!k(}(aoH_Tr2YWj#5ZMQeoTIsF=-Y8f zFClC$Murl5(ETePZ4?k0%n}kI9!WNOS7u|7%|_ATfH^(Qlx(i5n(>rzhVnN`m^9&4 zSz;zf8X~kWvVPfeOeoFXit<}SIQ0nGSEGb9LnTPP6A2>OVf=caM3{~%?G=yq#brqkMdCLWz6a#x`dxn?Tk&%_jglbDit}_-VUk*q z6P`tC@y#Xm7B&{euv%jw%RPsK6inV+Wk=e*ZiFib!OrJdP&0>mvfipCC0bX5ClE)n@ziNI_2xlGVylN}y=<9)d6pC%KKs$Q{1Rr}lS zMMd&Acwa7bsbjA3`m?HL@X_rHN}kuFc!Yju4FAq>NS6pGH%crrlK|rQh{2JpZE_cU zC)6#ypjGaJNxfY$3DbVrrE5`PKG=q?j876DHIpglTWW!$CnJg4CN~sa1}M%GyuDcl zh)B@igG|JXak0e-Ng%Ptu6To)6fxFTtU!k#>9qi)7j5Ud zTp(w0yJA~I;z+WlVI@H#+n79*rXBbLBkGeKDKNjuYw<|}g?id6B83_zNFqCDY%bCX zow@uP`p&H5qDnE}716qpfV*PP0?lg;2qrNsWE5u8k+!+O z?r;)P;nyC_m~DEVb5V=F7_hBDnUlB|rS@tYkbcT)q1bbC7x8DbP)JjUk>XshR}^;> zg^XuPQ520k3WyN2(!CR^Y1^>U%x#ncJrp^vw>k`DW(d_a+&sNJ6-BKvLG%<$;rmOh z7Ke8f4e5;mLBAaqhM|z5#d@C7hHXD<(Ch+Gpd4c9pkn_!X({a}OyZps6cZURl{w%& z1=ct-2KE`FN6F8j6y5Kn946ZYvT}>Z4N@nYfg(rpp6a^|D8zhnOQL(%Kcg@wDqUjy{jt+t$`MWMPVH9x(Xdm}8$ zt6v*Kxq2$^o8+O0n9R&1vXeXMRi7X!Te`Kl#5k`4dkI})s}Tf$2n*}CdCZ8Lxt5<} z7~y`AGkAL(%Yn3(>z_kS{Hbr0lEpUWOh0sS~(q`kM(1<9U z@Y_$}7z#CiS`g2hc{b-x>O}6n64T-+^B9lwl0@*v?WZgx3WGY7ZcNRLC@{z1N)+)| zUpAw>$1yope-qXKB6sgxU@|6oEH>E8JYc6NXT7B8aG*pniiq>1m;dWr$@$YS$4N3Z z++SWh(d~r#>>tF6GMNV=IG~-hDo9V&S85XECro|`ME(hQFh^u$#b$u_uL6kg;cJQwJ`R9xZet*+*pl>ns4veO!c?3z3fgm$iiPG+f)2T zKe7{^Iq8Lx=_$J)5I%{j@5mRG*ai{7ofPML%Hk^}nMd^FyGARt-tEvXPMm=8oOc(l zo#vy28txQT?tKw1U4BmqYI}++Uyx(w{0vIvr_&4eh-{E*!PilQzt%v>iq9fB6*nx7 zlIXkDp$yp~6nW6o3-jWJCKb%TlM>^di$Ik6ai>h2ovAfdHQS!$RcH|k-k&xRUbcml zR|>u{5-j$kgeU?&irevPKJ@O=>Kn{finU(Q7bTxm*bRK&Q@wD3QdD;w6N=Kt%IN3i zJtZV_ihRR5+M)KZ7KPbA5Q8a)a%esd_$+Yh(TNG}z8Pr8AorpuDa^(SG-f zLaP0KVg5p%o-U&>zPCf29LYwp&66?RuIxqK4_8+4RM8g-nAx74lpEhX^mWY}Q3`rU zD$c!`cV_Nh{CK)t>ApS7$UXa`9xm48tLA&R!@3fTsdRCYAb=t3%%lweNdn76lIl02 z596~%<1;fV$i0(F1a?vm?b+VC1R7I{>~65I#<{4Igv-sNI_542v>eNww6{-Crz7zzyd6@V_M+~qwb;%SGx@JbVn$@Zf7$8oIGVLRmZ@{H~jrWiLI z{UJ2%;G0L%XMnXa#RrgquDrYD-Y;?Xs)bLYDna<7oTF%J+-8&cSoRwg> z)3Z@1V`KR0<-m+#^+*e?kjvbiQn-x~wme%Wwog{Y&HVSxL%7=ysQ)aaox(^c#F~xj zq=iW+r1;%nb&Z~CgU4rXl>7lWhP)lF3lgQ+;nwOEGbasEzmxh?`(c6~`l@(13Sqn3 zAsX~S0*QvbwS)x5WN=qIvqRV(eq1+vMVRD6(S>%0E%zA7t`c}Mx8Efy^cP>%F@J%8F-m5I+HNgP`>cQ2^f z4inlaK-=@n-~r7?A@g?%aacOYb$-5y`N^NUE)|KJ2f^yfQJnXquq#o1YMjDcw_H{A zS)0JMwV)TU>rTqxlPGGY9{=Vks)77O?kByha{OV7!xZtks&`M7D?_2DDBYl->GPG~ zPxnrsEom3d?saW})ls&~~f-eMrGh--<%-xc7%`AwDqFnb*%9rt;?dI9T{V@uK zIW0g5M{&6M=W#3ujv|Ng^C=SGdzm24&!@8ZEIZ%$o&r_dbI|{^o3HEMg%146%?vC? zA;qhA+cRj`QzYX%SFjI-qkf3mn6#Vd{p1FrFprA`kMB-V+&cp)e0yur9~8Q|GEHmU z7-x>f(z*-k$5wepVEvbMc0v&F`e0ooTte0L}0%&)(90YeCM|0<1J4y)nI8sHOqqd{3p7v=@iInM*s1<|Shf4Ki`< zu)yg%7f|fWkpP-3#+y0sAU}w??=A$bI0k?S2=1it4~}v0_kIE%_Fois;L|T?tC?Yy z@7}9tp}=4d3A6LE;N@R8bGJhUjUgQVa{G~}Fi)%}q2mvDV66`Jp#nX>jR|p_?PadS zI}*8KhP#W}7@UhZl}~COIYE}hI#AfdBy?mH+3&kk?$|y&1hO8Vc_8|UB8WUb=aX>0 zp7RgM2=dyY(|o9@B)Bh@GBz*w#pgm5Fxl?*_CrOY0A1hA`J^B>hQB>Sm{BTqKjct! zv1(|>I)Nm0+$Z_&4$z-&0LEXl?)3AhdabiDl6eHJ|5_pee5QsgimVNi$ zTVSol5k2o&!wKnyk?`gAEX--oyw&rk0ivGbtv-xIe4HId;-219Qobnle!e?hHv|eN z{_fOZe6G>)o4H<_C`{(bGY3dRK-7Ac?xbL){cwWe=y6`l(I^73?YRGO#8y>}OKdOd|@FS}xiG>-MT_7Xd# zjg3+C`y>iGn@5WI=`x|suHqo>-$_fBqttfuIJP%6Q8=e>KXl(1mi)tqctsL;?#~+c ztsq}h6$srsp!Os5@Dy3OBz}}~det_rTpT4WlIG7&+}X*ATgFM5z>{8wXr3aBvygyK zw$3#|y6-88jVMIw$>FfR;;kgJnTutxlVsY&mme#Mi$7k7N%nWkz3vi4is9|2JT^*+ zijU$FoRr>^*?Y=k#yIbXav8NKocFVAbjja}9In`GKg7=|*2(gsHV1NcTe$ZWj1g@) z7o+^)gp$+daiKqF4!ok^a)qo#ZM_1nUd;-=9SYbQWJPN;Hj5v|?x-lUkl+vk>Qk+6^J^i>LN#0uSc%5!`=pVQWY)Wk2 zQ?7TEVEm&L1?V}j!#6Wi)I1D9kzFU1b#$ktWZ1LqM^&Ny;Nf>tdDPC{FCE>?6;hff z$aqhc-|!W15W_zOdz4&K@AjMSmj@-sc{zJ33*I>xi} z{2z_WHHCWGvp~bDC^AgPF?kz$C2Ex&xjPMQk0J?mw?i9Q#GiyHlpxzfgo`@1$B-o2M%K_w`cCQ)v3zU0zY%r|U#?k|Tg&Vb%gf<$*xX~JgKH1_;EG$0p)0y;kVAt%;?=fU;UQ}TxMV!+S8 zmmZ6viQr)^7@fsNkxhT|B+)1i&o1sxW&E329p;lLVq%pml(BDwF z$~T5BaHoJBRR|BZk__TDDO>gGc#N5C)9mG{34h0<^Wo@4oq35qLUKJ zb||M`oI8pT(@FW_kCIC^Mv9P++896(1xvn6j=iOW>$x3QwsYB@c^2oxU-WttdnzoX|;yAWrJyne6uzJB;E+pB1G?an-@7+>OEUW+oj^ zbLl>5LjlyDB*+`O9fIn}?W_}(+ z@YKyyitz0R(|bzlq&;`i3=K*K`<;R-C1Y$v`J2rQEaEdj0@Oar^nwZeVl$uYk%tY!NVxxT1hRwtYQXp@>dX=S7+q~)y+vPI#UKK=lP zqX1~9DOoi05UcI5lVXgu#6-O1?XWx;3MB9_34_|6Y4TT7Q27zZWw+}u7&r2jzJOmT z^qqns=_#ehZ-OG)Tm69`@ayHH^@LJ1KkIJXw@)3_*?p5xui>uM0wR zHT3xHPzt4|>R+>GcPf%eqNwfXD}}J#yB-*qdQY)LJ(Zb$XO~jOADP^*jxS00Pkx6a zU-fZ}3cDQ<*@xaSDm$hkmFM3nV65h`^XD&AzVc|)oo%_3(#rP3zJ8rfmT`lU9C@wH zL*U$CjRxQCth)S!+?jX90jCdL{4#eBV=y zZ>ziOmqTMaF2;bUCI0L*Kby5c~v}aM|vq)+!B-{U$ zHF~!rnAt>52Bf)yw6f$Xh?@<$?Njh8k1eJOt8L`~mIR)y@u+_v;V* zwcFk;3l)8HzY=t|u9FII_p1><@jSx@EgSRR#cE7g3%nxhPfzDZQLOp6;bj-Uiy#)B zUbH&1)699#cM5{p%n*h1Z9fXBoq}bt=27^@C<4-}6stFGhdkTQF;GQgmIc43>Zu^+ z;+waYE+b#62WgAZcT&c{uM1%O7Zd4d8V||TcP_xbr}mch?MLpSwPcze&WsCwwV?>& zS!^)_FNH#%9yh?iZjhJxq=i&;JH0k}2rW3)erWspm+MIE9Yz$ky~Ukg-bu@DMNwMTY$4j0zos@e&z8yMJ2~5KXZff zQ>+XM=<>#_Pc-Y}x!q})xS2`#ix6wHZ01V8-%~~XC_=Eud5)t!*PZ&#US8L4j&R}6 z&eyfuQ(Wak@9JskAVz)_UU3e;g%WbPQ)Kp{02imH1Y7KZDuRDpWh^^aHJ0xwp?j3l zVs9RpK1y#!-boWu6mjMAm3X>S)PQpq0Jsp@8N(QV6ox*E65_iZ7W>am+WP0w@WrYq zk_C?&08IR;W#M~D_AE;E{&D)_g zN%yYQ_WUUoo+PNOzD%Hm?amIAd@?V8-Cc0qA2-?(2vsa>CD>OGv9_u1^IL*`2Byw>mbJC&}8-kya0YeDg3)QB)v53KNe) z=JUCoR5_-Z$^3U;AaFBRka+xIW63Jj{4l>Yvr+Ov!sA<=g6y|^Dz`sM-H*$pe7DRv zwI7c9<@8)8941(SH|{CmU)+rXFdRl=s7Wo#Pg$+^rPcL9JsuLAJtdp@q_f9Sa;z{Nr^Gq zL5@FSep($Q6w|*kVRaOC{<1551|$B6vCAGb51~y~fuv`V=$m{?8N#oEK#8+{oZr_A zD#*$=>8$v&YNb&(M)3Fe+*=IBSmWWt5`gvt8h>#dqr%gpR4Tgt2)~@GH_M*2$rQN@ z8N6;_duCV3q0m+p@KM5HC^eH$dV7PS9lGWh^#?baxwPZkA)wsMw)i|OeNDm@Ig5LC zr$oIyvp&zR_N^X#W;nV0TfGz;id5Vubyc6E^uo>?Bfxc1iLDpiFz`D?Rm6ApN>)9^ zNWC3$3#1ol{wl>1;oYFtJ0mEjL}8Jh^wzl(Mat!^E(jQf;rN~^qr|4lv%ULbdhMC%T?EugNu-lP z2_M?&^rO(lyVF|o@uv=xmnjAM(u*2pp3K{zt{N1<_3=mBPq?lon1`%1`*(x2yoAu4 zOCLvezP^-a>v+U4q6g~bu%lVx4M>*WVMs_ z>Q$7?)*B`N>AUjn z*9YsiC#$_JdQwM|v(FV-pPmBbS=!2_pG5Uqc@&I48^w)=jTJ0E4+4tBA0fqZJDn6i ztuCzp`XPJqrZMi(*m0h8Z47hw?yG>ZF>(cuhm~aeMLQ1QjiKqy^Y^Tpv{5(6ZdWVY z%-U@?MhN>+ilvQ_DY*)iszcJtA(W52r@)#hH6=a@or}V1J!vrkSrsrYd(cViWJ9S8 z^PbX3*6MEd`Q@tGtxgSIZ3~1=669n*Y{RB!k$NTOc|GteESjHwb^}bwe_`ZTbqxfx z9~%84M0Pq$i}2xI1zEURfi?4Y=c3B-8Txw>eVO`pn9e4>aZAsl5{qtTI&$_kVk-6e9II`x#VV& zsO(*0Bq%nv*#W)vMm3Uaya%DWK1iWFC7gVtRJ;7jVJVeP=P{|zHo)9odK8JPYjVb` z=xd`W+>xB?X5wP|KEB{o^pSP&7tytMmy1_>Eny_S&l}Z9T-EK0aqA-=NPSn}Mu9lK z-WwphxZGSI?&gB`XH;8w9|<*z-MAII?d{7e1#kLl8@|?Rlr(xap{VPPau?2WLD+DR)Ad zv0(!w_+zYLai>&Bah`x=&>m0iu8%Mw4WzUy!AxHQMq1CnNYM6f(b8}F@|ZheS?xOx zjM(RbYRHva*;a|YSJ%x2uRWp?%e-|7?g^``QW;Uv;}LnHG~p1=--u<%lk zxu2V9F7|ki1|c15t0l7bpayQz>{=x~(h$?Dfc-`qpe?552-0uyo&9Arjs#b4ro>`* z*tfj;nu1Y9@*5?oIf++%xI7|jN2xbg9f9w`Zo28g(zh#)@QnidCd;Psm9F*$c+KXU zOC2dI!ZI=7TahKZD+3=FD?=5K*Y-sdzfoeQalV58*i0+>IK8=;(*;|Vl=kJ81pa*< zqDXOC&B>Gij9UcF#o8CcHBX4d#_p~GrBkTdi~H7vQGoNY85*16XQ2*ydr*dP(v?-b z1C?hRqeH(l2l51jgtd`02}QLDKy9X9gml3*l7+@EsrzLpkf4X{ONH?|bMg?N{C@)*J1u0*QmB*B9HO0iLlz-@s|>uW{MPMnXYeDo|cc9gbn@;afifyK&? z&5-i#ozkr6YE+)H6Ed17;7l!xWcoh7v;Zs*=$meazz5k-(`v=saheAwnA4^wqsj#6`=K8(H})fO5m? z3`s;1yLda#%t!U02AS_c?^$hnC6+~tM(K)8Qk!8f5(vaZiJ_6Inr9g6>X;15iRvoZ zRt57jK~-+g3igUtUyAB06$g>bl^Uy7D2P$odk{iPEc>XzK@>dMM_iHkiW?<|LNnY- zjheBBaN4_>Scli40Ilw@I+|Nd38gG>J#Uui7SfpCFSnyJYz<+Lx0@Jo2qI-`icHBn! z@4;<_ntWorV%CQzD>X6)@v44`33#ck6H12u)By70S-L}3=LDQN@rfof&&CkYZGw`_ zqDo6%lOPP1{xs};1ymi$wl)NJcXxuj1PJaH+}+*XAwY0~1eYMeEhI>A4{pKT9fCXj z2WIX~?#CACnT zZQ(;8`+lWO!B24El`?@!WqW&=rL#MXN27MSUf2!mr@=iAq{0VSt10ivkOGtnksqH^ z<%p7BGhqr=8`aljOZsIE0$xzq+9w2JlSG&dS0wY0`jo|Y|Bl&cL`+_U+mxDe*d zThC}V3)-Q|H*n6V_^tAM#-1ndSyUUQBrf;plgP#MYVb{*)s(Nx-* zh}keUn2V^>j~G9TVK!|SLxAYn;V;fx1d1_LiVAQI98bCMp4{(pzvOD(uyq&VUICAl+}CP4?u;IB@Raei&-cxqw7Vn}tP35=wtx?qGzz=jKg#Vx|b z8EXw#M|6=SY=@v(=hYHb%jZyAkAkRLOUrRvYg0ktAnK*` zg~3D9#MHq`tYNJ-$@k65Gi@Dz#JGT@bHW4<^|yq|gc~iI$LlezsnB1p?3Ihy{h$+@ zef{&L>7gb?gJ23gIw;fKo!$}x75KOIgB|R0q#kf$lflTb3Zf(OY?9)AhNbYSI(#V| zq+cbS0DE0ii#hG_;`(OP6WgBJJ>KOuy1}+T#F9>~nM1Df_K;eY(HqLc%%bl6bp%Y) zR}VX4WRH9NFR$uKLbnbkmEWAQix9g}#5Htkg0flQ#zVftg)AQ-`5bR48oog!@igg{ zrO4CPD$xGcH!vtdTng&&khz$#YjJ$BS(Rp@+xx@8ljQ=}dE@zlo-b;}+X-BF9?Nge z2tOkZZS{92G}6|Ms*JrR9A}5VPnn+;Sgp}kGIIf`Qo_Xw3Et$Z%>fCDbJ1Z?!XG+g zoqNrV*!Up}zDcluq}`@;{$(xm_+3>kXj2|n+;}6T#?+@?n&j?AQ!rp~)hhb6H{>=g zD}tw)IZ+99JxW-7d0cvB=F;;POqg_=wY`gek<0tzu{KSVa{W#OhG+yQ zF^d<3h@T>yL&j<#p%j}0N6$b$`qI-6Dd#TI7X$L_U=s4@$niii*sMV$&uaDOqYffZ zSNYXF@_|YVspj32CpWlp5qmI0Ch&v|Zrk-|;sfwvJsPg}U&K^Kb-#%x8$Hj&?Yz(~ zcU^v`V2+dQ7>WKkHSW^gj4lV<0TT5f8aeTqCu)$ab@ge5xD`P0u)i9 zAIj2*3+|Tx<>Is40Y!{LX*EM}9sg|4)tcPClDrCyxGZGUPj}OK19SnKYv{xUcT!_S z&*W0V;@N!?V=;KS)#kU)FJZQwOHo0RYSQG6?BoeNc|nApoYzr1i%wD?eYnc8i2o?A zq9szT^!(gk;OeQ%5V?IM1yV8@dazhxBW${m2MY;o}GfzKCldJGba_L@f88=u_GR$j;xsCkk;eG9mQ8tGRb=gCz= zMCI>4Z5^J&#|d+L$Lr6NyPGUUv>xL@lDazhq1`rvsrGTrg>sLFSIhv?Od@*oACMLl z$th5h6(GFHEC>|a$i$-6ks=d5wQI6PQkgOtHKg>;4HFG8)p?7R*Eor!aEvci%LPJ* zK>0d#zGl;k7Wn|R-oJ*3|WUYWl=_Xc&igE4yOIW#Ncu2`00p%6QY5Y~C@`8OD^ZW{7d(66zL9>?xv4-qRnN1k z=$TD^y7fP^B!6gT~+W6^|ZP7GpeJ)akp zr--}c43}fsQ4qLeAt<@|Bu+zIaL~#%F@bz&)uKpOE{u^cUC>&x!&EtxkGjZD2j*kf z{DPc?sp)9n4!iSi`wQ_~m-^RqzBH(&P76ezi;aM@`4HcQDtq_sf&UO+q zFcZLw{HFG^%SoB9YLwQ^*>cwVp>4$!-CBdDxP3JC_TC?U=`UHP?iG&>mMhxsM_A#i z$8p%U#AhN|lRAFg6W;+fezH9#(9~sWH)JG&dE&76VXkAhWhsD8I%On@61k%c@V*mg zuTkg%yw@{XFFva*m;NdbACGHfTHFI4k#d2wW5c1id&`cICn?%nYxM}g^^oXqZZ0}D z;H#ABIE7l9?5#s`SI?)CC35o&$RZ=pFIXVxV9wqzI?46n>hjQkls+lEW|JE}sp-j~ z2@YQ1o*ei*osJ4vv9w#IARI5HP?K=CjA;EhQHbjwpi}lQzlG)~E)Ak`RbHy+sRLtnYul z__0shc2Dp}XG>zyo_4Qk|E0C@w%N94ZOpcBc`emz#Ox95xQ{cLr^Ti7^z$K}H}B`U-i)>|VvWlht1oiF1{QKWQc~@Z z@?A(2n&~>`*k#iV7i(EhUA4hLT9g)~XnIjYeS$pLIDRMY zIV9+P)EJhfnFU&o@*W?e7i!0-OqIcNUbBiRM<#@@rQ~x+|H!DX3Jp5q&}|N?bt9&x za1h!qhtvDixSpPYr+#S@rtsI$TW5rM9=;mY)TlTXnnOyeaTpx)@1oGyF?<{n^zJBn z!!I-wBrk=8n4BuUG>Z7#5RbX=;?Ail`fe>!;$HMTU84)~mFmFXpM1H~uHoymWV-fp z)O`KQ_N61D&`1SZ6nv5%WbfEM84Cp|pPMuVNlTL*YpM)AGRJdEZIBR3T=DYx{nsxU zBi!7yUfN3TD9O|^PJ>7K0iE2wqZ?HW5X!bZ7*}9WMeP;UyCerJyd*MwTMTJI&&t-H zS#_>)JOZS0E|`dd*2> z_<*iz<<%=L5-+WOJSYffLTkf2h>)dua-f;F-lSjm#g=2ah7@_&dZFp|AkqEAs-c!t z<)ajNsJwH@&k3izNcY)14dR;S@;z=zU*z_6M6G$vKn5A4Rl#-FGG6$_y`ZdNlC)Ie|ec0df) zv{SiH(;79OM>9!0S%rn10`p*P2A!BhTzii{H%pB_=Y4ZUd7>#`9G)(UnBM2MvP~OB z>-qLG*689&=Jy&VwH!EwjkO%9;^uP%FwA~7jNMhx>+t416HsrW6g4{WUxwy|sTaeW zx$ZJ)eJT|in&BBe<)QpMjn%#1b0;F+V_m9Un&ip2J&-8%sy&GKs|dcXJUyMdWsoAw zqzDhqD^m7G=8;h^Vb*ur++>~#@>Bapr4}KK4ORVIh~y>l0>*bkK{zl6&YjR=v1P^U zhhf<|(fV;;LK*GXsWVPLxRMG}Cf1zh?5Gfa2|Sx4=4K4rE-2b`X9zsT+_=Qgp67z? zeilqR465pAh_AokUWB@)UY)Mo6>I#y#?$`teV2=XrwitKU5c@a4V_z)5%ms@v3hdY z(n3+cSom~}?|q&tS(=TG;i`B<@|M4#8)TOZ#@n1Qk?kX$lb|osUFTF{)nioGu@HOA z8$Pahl=SK2ce4D%$F-0cY6iYgR}jWkOq0)G?0wr*skh4EF0sq z(a%VuI|HVG&Y#aS^!JVj{B^1?sUnDXD!uI113+9IYR#hknl0(l?VFSp7oFbHe(iob z7f{^6#?Kd=_SW8d58v_5Zp?d}gu+e`Hq0Pm8}3z=`j}6GG3-GSXA$Sg#m8pP>`zT4 zs)AkCII%JqMCi)gFc7@Etgs>l_(_Q*%pcJGcfaVV1%h3cr4$K?AP8KV*yviNQvo9? zHh9E&a|7q=xwyj-M5mIf=gl+05f|)Z5-om0d6EHwZar{o(-31Bdlj1QB0!dui*j1- z$Akl>lIlf0{H!Uxw$Ojh|lPa@@1{K=XZrj7LbSpJZgMM}g|j!%M5 z2+?1oMRBm`z*}3EdcQsqd%o?U0R~>}@l^e3W||yqV=CB4wTG(SNFcrL_<9V`RJ>fK zEckUveoFe}EEcP7tyxl}q>^N-eCAC4@Xf+tw!f}Q2bI4*pp#iHpfBQG46Bk6z zlj!E+lC#mK=A^}j@yh|m5h!z~NY1=cF_d++vm5iw0{VXMXh=amFKBx9(Y+CqlRanl zC`W^uuhqhX!jKM`A{BHo-PJ$_fhw<+W?<*a&forofVwGuQdOwPsf6LytURMq+sGrv zHF!RHfzl%}OF_Cdw@VlpQ#G#%we3vbsDuBifb!Mum0q!frX?PXOAfUTCE411z6rRs zlWYz}fuY2()pZYn3^;I`L;e*ML3UvKb*M-h0&z^g62jG4N0Ib)@7>-+N3A!smkH@v zwa4MS7WScMACV@7*4XsExv+ZM`+cPW<7;FJ_=Ozyy!Kg^y#su|q$r{H)n(dsShFwD zzCLGU+_Y@a?}-O0T-_b(B7~Z^p^M%F^;M)bfto8v<|4`DGTf!t96K}GQRJ-j;~a)_hNIqpf!D(U9DM846P{73&f53f25;Cz7?1$5^(h^;2tRZ4m3 zw0>}<@6@V}cPkV1)9Ua+l@{`S&jASl2M5MMwVFn%>_wi!0=>YPSMnXP~!9eFp>5+Kn+ zv#s^Q#l#oWCzt5hN+gMyN7}W1K3Iiz!0&ld;+zpmkr#5>ub()0R?%?FC6^wOpYw76jefPhKi+rXisbl@eYS!~3eI3_Pkt~;Iv z)TM~Sdp4p#l}{VQ!1e|j^oAWayOokV*(Wk%VUy;ZSEYOPTi4b$ROzGEJktQV|H_La ze0b1G`BjZwMt6;Dy-3$2yJn|5e{^WPimG0RP8MibgEyizikXJAXU#^@igtzv?D=!V zDt48!RGV|l-Pq=*wtWRQi*y7NGUlppj22nkzqHkCZC!SQfN48Mhw``~nj*}Q)&;wG zT;KDkMp|CSFh1w`u;$eUaR#d5Jb~#vP>Uc@Ut%1)&wroD6Yuxz99%~U>80A5oO77b zXY$;vcPKXOqCznx3@24XlHeP9Ye|E;(IXa`_AfTf=$P#FI7h-nw_oCLta<>|I+LNt zE<&>U7`(4lc#`yHg)4ZG49Gxpwy)MC>6k}k&qeD9x5>r>r$bEUz0?Iw z{a#xAC=Vw{RQ$)e$ey%W1It~h=glr#^59ETF1FapyAqQ3GEMCXt&tbvErX4{yS`D~ zT+Mfh6epau_D7Y>k$j~iO0SQm#MEB(BG(1)92m6g*34jBrUjY7E>b7sH*?+)vMJ=g z(r7*dCf@MK>fB3jc>#{v-GzN|okiOL4c|DY;+DE!j>9dXazI7k(EMqwEHs_&T)Esk zfgf&=AV?met!HD87J>cHULj|5+gfYe>4IqKt7{YPx$>%FNHlN@E+vPqZ-)K4}Ho z_7K+0q2}wB`T}KGB>xo?7Y40Z*w64u$gw3|+wF$pKt*6(1pQHuXo+^HY*%Q9 z+a}(-(Wv{cKKDBWJ~w+hJ~vBU1m2fzQ9idRDoftdZnt6#VsMeS7Z^70?mY4xynRdOx*4>Gk6m!nnR!G- z#10tr3ZaVf<;*65&xsBN_$TjpjYH=CRLi-1<15pq<_}F&3g^9YIW3Xu@SukdcrL_r+pdd554FH+c_f$bv3U2AsJKXH!tB5doMwoV1ypYQ^c;nAu?8(AAV zINBTOSv_po=$k_`GP7_JG7vs&aPeaA;O zJ~DxjUd7B1a5&(`=*5i8OiUk$$qHx?fPVJ2HkNvhM$nG-P5|0|M~`0{sUWTAU;(%g z=dU*{VCLxX!pL6G#>&>l`hnsc0J4}_0xAN0Khz{-WME@x1ZX|`kVF6i{w>peMCbuGMh5n8M)b(hAJAlH`JY1b zS9Jf+q4|i=4`@DG_z!5Z{p!fPLok+r)Y#%OkPazmsQ=%HjuNvHdE)exF|g zNWZ@YO%6b;`_3)>yO_xWP!o^BVgZP+KR}FcVhWn~uMkte zJOx|`aM|nM#`F=V2lN;jzcaQ+nf@cDKVxi+91Pz;WoP+GFaB>e)qf=dzJUtv^Vfm; zzi%u5e|z|UhmW6)t_{Y&Amszm9_Yuy{2eJD`-(r1lJjRs$@ZNv{mEVv3!p#z2MqmN z1b}D%OE}rQ&{2RvDse!0!x7g3qNNwuGisDS?UAHegQ zjsG>h(En!m`v1Ztzv5yZ>;5(q9-r>RGiTyt{l)fUN?48}vsYAI*=2?HlNisjMGC{~7aR{2q0VpNz49{M^5>zuy;Q|4QNV z?_$WGoO=4dZ1jIT|K@kl43v=YFDU##%LlTuuzwdp9<#4MP?+s!GH;B4jP2hY2RrM} z$wWX3`A?zne?rLb@^OEHwatQq3qbxh#U5$%Kqf#E{hOD3Oz8hWG1i|+NB)E8WBIvm zKOpJ{kH1Ut{lmD!PlCzx zhZNs81^t)gQ1HRQB~*VK%twHJ0P}Gu=?5@5e+EoO!0^%EogY9Oe4ml}cZqTqrhluN zeqa3lkMsMVaef(ozWM8?(G8qC*}G7wX!6@v_JiAVm^}XftW1J-;MD+4wC=i`B;BO_WeV~^=HG#zg2zz zRZRYtIDkX=OA;{;-ozV_aOLGgxoM-R@r0hQ>bN)aQo9Pe9oNti+ zm3_hgB8mNo(=V8QCmkQ>YW#pH=YN}~KR3&Qh4~Muo&R-AA94Bt)5rNPKVS+-{rwNc zB<4RPdj1oW{?8;-{&h@xB-;Z8{~;zlPQ3b&m_K9ejDX2t|824Kx4D7;dVKizsc|UT zzbq*IXW02qNMQV<0r|}|1Nq4RcA)3@TcBrQ{VvcyP6+&wr$5tc{3H1c=0BvJ{`c}3 z9DmC{exJ|yWm3jJgUQ11Ge*z!Pjf=P&6zL-DB&)sC z9!3eZmxqFHZb0uWWEb;5Nn4pIwsrKwtOZn^MM_>!cEk%D?j)42qFM&Z=Z>3xSQgKg zD~f~W?`|o1QONqNp~aLXx&8I9=}?9#D^+gvYPg08gPNstumTO|E?byfnG%dxq%ZZ@ zv+S{@!z+*$W;;~a3)wm6F#aL|GYrZWqD3m(y4$ytZp2CTsDjWa#^PvhI>5=)NNQa^z*0kl|rY4 zJ{yc#yewQR&PmZ~5o(;>Jpn&oHXX8>ux7GrYRgxGikk#3eO}?-x~1Q6&5$ld&@tr5 zggvVS6O!4RBS?mk^F~2tVy1rBGWV7tiS~`GzG*Jl87K(Y{9(ETb>F6a&X#sGU-iOCX_hHA@KllsX%^z?wUd#9z8{v?DcnLr%fY zS=-&cXDZ7#uzlJ%Yly~{yE3|3OlNYMy~c9aYHxqdD`maPve*&qUU|riXP3U+3&+93 zw&Aiw26sn>;ByomD168t?j5WtzsN|R!aW0S8gRy?%SDHdM$bx*E8lAF4|B9R0(_wC zz*rXX?z3Ldl5kruXUok0;VK6SD znwlm~?VNShnq$l`=!6mD!W*X$-!hC?@5;o`3r**+DNACeCkBQP&CRQRGDKw)JI9wd zFMyz9T)AMXK!BSTHco4BU9+aO99}CnCnT~KuOcr2S&!^J!F=rnw309I_5}xSq!972 zDGPd7$J^uMV;FgTYReT>ZuBsbRulfFiM?`6#G~qN7c<``{c+nbMGLDjho+dC2Q3_Q zd}K+I6!8+dqe)WaFl+X;+>RefcGvBvq{!1gNs$8)K!JJT2ai#Te;w058Y)PDu7%CV z#1!qc^DBHosi~ub5w<$=G+qL5;*&XnF?PK&`KJjI>>WFR<%tu-b;#)lvR_yF3Xw#5 zZ(W(OH6E~7)L1P~``W2~R4;*N#f~tJO>&$b!YgQl;o5U98ngUjF*YM{`A)T_$7nPG z(v_uM;#tuO*8s6N>S>dvrm-BPr9O4JeK$whDS4B1te$6HOduTQ_g9uTVByd z)p8hvEKB*#^P!w-42CC{#Ds9Lf2bRjnbg=^^UsvaYpJK5eZ}1Ho~;&VPo8T8Q>Ui7 z57s?H-F=Z|yw40Kg3lp01^WCJsE-!#U#Zp|_PtJ7k0DIEMN$z?s%#1L?@Blb49Ts< z(VU<^BK9GJn0%oL!($u>S5sevWXqR(tG4`HV9MLz4JwCSSvtByeKGuMIdAdcL1Hc_ zytQhg$tV&wSsK@y>ihn>?PFZ$S84)_?YE$#S6wLAbwZham__`$wo*P(jQTzSgE2huLZ-?14(`3r1%|lqC`Y^Jtj(L_ zZq-*oI0)4|_uPG42!hy)`AbmLn%jX;n;CF8uZcF-Lb*L7@wlbY!Bd<(F{C4mlfll2PLv*WPUf@V#FH9z z8=eT`o|2XeJGO=JJ*aDw=WSf|+V$=JTr^F{#zd?d`euhO>B=lz0)mm)<9a(Cz-|Kd z;4BI(|lCO)F9n26vn~ysIu=WEtg-D6M&(wdms;Ic10?E zd7@;8?a|uf*3jXG4JlkxYn*I@uF4pWbv3&R!r$Cf_rk}X=WGpAy`F;CPfIZjV-db7=##o%_;vc#tx^b-~Z5*?QLJ&FhC4-E~+RV$M zj3E>`q@@>Trs+DoT~-ZxC$>tE1;HZDI4gljCcYm}TI}|QJOt?^CR0^A8cmwLPgL!l znJJE0|L`gy=Lujny!_2K4Gugs1XPfogB2`p{qjTCgOU&|9VP5n<8WugONfGG;>kv4 z$d^^*hp^EIS!Obd#af6&l!M1v#oOzXUxarxprfPSy2*W<{TltGin8auwM@d!#+s^7 zB)R>UXzOzOWE9lV!}DNL;j=7rfH>Kk$PLvJ#1>ZAl^BugI&HH>XrNGYtDpB?D0Nzn z$ZD}p){rc;wzle;+N&p&C_3JN8>%R3>j}Qn&fH{y4Xc+^MB}cur0+@TEgN*e;w)^2 zH*aiyN@4b9Ma2SmU0NBIORVttbi~l_qZ%An)#f51Qjp#fZze=eS;5(Y?c*8R;PpIfpZ~ zImM~F=hRUd;r05;X4-7Cf^zIe%PA|#r*}xhyV&UIZ=};i>na%c_?N7>KEyPJ+2_C$ z5*s+59s)uG+nWp^Cp%lGkUWUCxh{XZXh%7Vf+CjL$lPNnSQt@rl!6rEGgvq1(D(OKuO;tQ<%=_?^_1UgW!Fg%Oiy)4ay*q*$c-*7 zaCVA)LNY(yAzc9@syTA-r9{hSZAFsVxS_)T!!!L);Xa9|xFhQq}+j~bLWm=iFA-vkrbcfs_Hl;dke*$h)v|^8nA)&!^hT(o%8X~ zYSF5HycLWQO0UJ@biU?k^O(g@o$OkAg7`^8DU~VbRc8eMIE@L!1e}>X%WK?0IsS22 zL6w}b&su9nOIF-Z!6O;e-heiOH8m7`h-hQ%Yi9hk%n4qS{=}Lqm>D)wt_EKQ+{Kn# z1ehxx%gOYh+cmP$f&Pvhx3%u-&h*Y$S@+k^qOc$D(0hfc-|`ucZs5UZaIkWGa~Y3w z>3--40p7U#{b@O-f11ko7rTs9GZkz}#2^&4U@sjoA#}NDX;fgjxc>52l;->Q_ax^f z=~zM_>9e@T$+OI-ElawsU!@wxw6wJLs%?_ZWcfUv;AAwPRyWtuyX%~y z#DK$JlpnsN+#px}OcOt2fnd?VyJ>L6c@i{NZ%H{@*WuFt^{uOaLWjX{^q>_4jlQ#_ zyVfz|f)jXUKi(^H`Kj4MC<3klqfv-!{-}P-p{HHYU_0UHdA#n4)Nw^0r#Uf-(&A;K z6e@gs3v&#fs!OxUawJiwv6q(GTuh!S9cS6wW1dd;gRcp}DhEt0g&Bomr~q2%I@lHz zaA#Gg{VWs$*B`iYH(6|^Q)2^AuRFQ+=vk<>awt=vhsad<+b?W2AXtyZ%3S5sdg*Yr#mWP zT&Yyr^AW~_Wj4HSlQTQZcC!|5nB}6Ni?`&ndy_sc6dEcS;PKMUd*8LSc{eunQDE<| ztz%y@o8pSp#{{u96}~l-ZhL=HZpCEkyzNoWIKI>dJ(o62LPbuIRIoQ0)3Dnj zNLn}r(2)7ZY1M_W-nGMElqCII8(a>ov!toGHQM zRJ4pLmXdK;zsdte4_(i(M24WSCB^0;WJMo1s()ELzkSkOlG=Kj(SJ<+u{3iOb}6_b zuwy>-JX4z9j2RO)u+298rOW59k&yHm5IO~#1&V`1r}Aa&$tvt~OBYLKese0UOu;$_ z6|du83@ezRi)F&+#rj8G7#<*L`?n_%AB4DqA(i!frQ1%3Fs^hOv(Dbjb?}(jL-3I@ ze!)QhCBoY%U!<~Q-PRB3l`SC{fx<=|#}fBCPmqh8PRkC^LFvrSDMY~1*SoH$VOOTK z{tT%2SdAwAF@rmon)*9k$Y@JX@m#eN@$HxA<{Od+S~?4e+SM~V^oJrVhlWhT6TOyf z9-cy?kl17wZ>^2zMzN&O>rze;@S9&xk+c&Y6D>y}38aI5o`rZm?2++x{Wy%M+CDJ$G`}l3>6z| za3Xj_O_5mU4V7k=S$F)*9|J{Jx)s-7y;UAud=Z|vX8{f^gM~sxCN><5OiV(`H~D@? zn6~)i`KA9DP?P(UrQ4T~VOZ~-)f3tvLTq25iPA-H$L(p8lJyiEwPDQAmhN>&144Mw zGXp5t7g&tel1B2(9kfUbq3zMkuktYMlM+J`v*Nkyi49nXy=y1P$8GWvfzgv*wuL~w z=`Tyv4oM_WM}bu$%MoHBR%j%ISHh{MVU)DH?p1lQ7eTN38g{e*rbR!u-7HDIJlsFV z%}{cgg_LRZ>y6u&tIZ9qG>68P3V8u3EJkGgV&isAIf-mTV@i!9<{askSwdrbmfobq zDx`tvv(j~BO6T`Z@U)#%Q$*?kmBP(Tyxy{SW@935B=+8`ieeW}=Tti@SzbnTj!u#E z-ndCu;IK-?&qcwg7UIaQ@f(x#mYJsH_FCpj2x4k;9HuJ_DE-D=ky&KP7jq3@MxMf7JXtb=6{C)(uC ztApxa&>O=(ek{{lTey2u^E&!M;Bc-qsfVx0PK&7wja>%Ly%mDuW6|?74%3!_mR0Zj zz0>A0BQ{JaYrh>>=jH&U`a8HCrI@~wBk6x+6 zB4}_A=ABn3bU3zK$!+#QGaAT_ygKIW_AHqb6yfiHIo-2k!#lO1gANYOsB6Vy_90fW zo;?Yol(4H9_G%g}#wP$x^UpHrvvo$qDKEHD%a#uF#2;^{Yp@=dVP?!2*&sa?DWb+4 zM5SW=QhcGha#Zi0%mZ0xMNWpmX5eMoJmAieKCmV$nahMg9WQfSD@DBQP%b#z#29tA z#QV0b5j~h4Q@DUGZQyIUdz2wTA>`<%4tOXjS}IOFS4wsCwIyIjR&LV(Hh#gb8U*?%hY(1ofZD4USfNxN+zw?#FdW%9-2 z4Uav>noPN~uhY6FwucK5xgGE2xyl=T3K?6EUwVF>EAAyZ_5Rpj*1sU=V>J=(Ii^v+ ztIzBeaXD+Wo8C6<6a$!(vNYENhHpq)-agt}@ z=*i}Yr38t3Q*EasXhd3jve&O?Q5Ab-Qx2aka~8P{WYG7`ExkRA*#~vw^5;bv%t^UE zKNkzlf0Gc0mm`ADabj?X0;7&26Fqi26yH7EnwrWwNpS`O6I#VfZZvc5gwAnN?-~#y z*+LXdSyWg0RNp3#j*MJ2AIduVjnzb4h|SKIm!3!@Z_sqxyyd@GDZKNu=$SF%0;fS` zQmc-#gI6k+Xak{1euHYWtb+7XvlJ*rI6XH+RT!P);qN2A@S>N$jI>tBKYi9?1kS_{1$!8o?}MH@W!}!3Cg-x>3W|8|aP_gvMZC zeXpzA)|e2>jq=}9em#kgRTK~vTymf7s^W$i+K>_?@pATFK&f!zo>*DA^whkj3Ikbi zur0XdAxyAaO{8!j6Y5DnGGT6IRqHtOLghygvNp%?f|-- zI!&FTg^Sjvg|m;8&z9-3!1zg!HEMo3&=vfg$H(R7?IV z2P0DnET0PG8hyI6oAz!FD9S`GyVe#CN@P`jwahzuFmK?DOXK0+a9Y3kp$DhM$?9P+1MGoWuS*UmD0uc-+SF3Z?} zCWEi;n4joqYHDk1-%14F>7-^5h`@cuNKj#_6?l6S@$SXvwfEElw+$bP?}b;XlLT^y zw;i9|cBjbXjpfHfW0}&{dl0_Y%pKE7p;a#0`_gazQB_JLO~eiIB!kztcw9>(&H5nX z03&%~<-JC@x-UA-Nyf2cl7z{7k6VPdU0t8MXAC$nzt)zBL@aL$=x+GVd*%*l&e-ge z94eBha5?oFk9M1G4pj2oHa#<67W)wCN%|HQLffIQ~0O9_W)Fn)@6 zHg!U^In;Uu&R`+6e=SroMKHJ?wiYs@{~WL3i@mIO9X}b$K=DvAcZ*>yb1I!mnGJ*m}9oPS-i@G*xw4cZL8tAWaTOGZIAK3G&FH@{#PUfGUxUPV6YwYMmbLMjM(2}}_ z`~21(_l+Rfr4vGkyaj_A-}~v;dvK9gT;@-1&Z_2m%{g&gb}sW5>|S`MX*%pdx2NOG zEg3#bAs9oq{c_Q@9FP5aL0hGFO}}N=lnoDII^J@1+*=HPB~a7K@q#4D{y3KxGcwW~ z&^=+(DSfe1b`3#XM(AS4gwM={4gV?4oe1klok&N~6rW^ut?-1+h9RALBDqBQ`qlUr zU(Bv9OB%i0c3CEtVRY4m*OsHLN{MlUx)?8*rg6#FdQCCr;8n>DD~>kF^$VA|>+V9#rT@Q>&wG5&ijZVEW0P2XH&o_UPKpJ?DPjv3%H$ zM4KdKbkt#9$(4G<=TqNAXOeAQq~2#F-%YwpjUOc<;D-||o)-sID$tA!8rZ38=jwUK zw|JL$1~hdl8)8{8??<#Lnd|4qxK&*=xTQ*p>)D(Jwr_1S>l~{c$W+vqEnq z5pg%IU&)mwGr`!uS9=IS(!F7x0)d^>m3V*)H-E`(J()1NRj$!5k|qI9MkSCm2+0zc zw+Rcraw^wv$fSX%?ZfeUBY?bbPJ{^S%mY`s63W?x1^Yz(V+sxHDmsKTd@+UX*4JBIqaI=P-f14IWnU?=vOpL(TNo;&7OGmCu#TC*bwlW zxT=(Xf*sfx&bQ)X{4kKGuX!_LyMeIlAo$ui8uD16d2pNoW5y*QRPwgP7mQ_@0m$XZ z%=YHu8F$#p;Y0lb%Pk&aTT#AR_nv6r>JUS3LF4NAXu(y?-ibCTI>@@HUXgqVU*F&p zXzUL1HqPW!7~LB}`c%;pr*_dT`+30U6TDxL1ZS5O<)Nkrf9})}!^Z#zBB^5oj)Z{A zyswoDvLT?JHXv{g9jgwv%q)GGM6kU{T^d}>Nhsz0K8?^{di12Tu-?J|@ysYBza&b9 zwX5gSWjnX2MZ%V$GtSH4i>et)Vdxt{4KiWC)6LYn>r#9>KNmco+F}MRNat8l0U>RI zX`Oj$JTYgm&CCMT#%82f6IivIsfPX}Db^oNPzCb|OCQgwIS-%cNQbctx5j?vQ#ipV zaPcePVK|wR{qwE^LGPGhn|wQW)H?+-Sz)nE1E+NZC3a!ulEI|SFzw&=PVzXzx1Nne z7giFbTZDK#k?`O%qdTF4y*-hVNZM+dKB{ov&z`a`;+=Xby_ORPXZ67gtRc%rULsS^ zICMREcpWU4+A??8HWhAWjYTPTM0RL#?8HSGp9>bD0yBwsk@vP%;fko!Pvq@Jc7pj? z$R`FN(XRsF2$$tNC8J zuXgA_Og?P2l@De2%ddf45Mrn7uhEA+nMMOKc5kySV(CH)P{W6mo}DAr#9@kRnZhN5 zyJwO(sMFtNV39Kzwmj7rw9#aIkvv~X6oX<~N*#m&yu+Z$TNhl)Fw0-5RpIif4e>2+ zoqjY1e``6Uo@pRMjn2W06z7Xv$fhDsLqSOmZV)#FW9Rgj?)Pt+_$QybUpP zsua^8S)dVt0@la9DViiQpWrL<>zz=388mJ|m@+uP6U<_Pz_tdhFWrO}1W(=z?I+ZM z?c}njz_lJ4!3@#_U;@mNGsN-~z76kW94#RDmfwBx%JLOL%gvINha8EGjREGXNuF`= zQP(QfR##Cc%+h%905gb&#E7LNzc?9*kX44X^&0)J9G@>yk4OoL0;d^B;h)U(fNV}B z9x)j5XSaOWj>@atLQMA;C(n%wBJwk?)%S93+^ShUTeh6A7NUiFqRLW>xdNi=nEEyrpCghp*5s zexG6XX+LSr$4|F+lG%_+k*L8-=-3V&%`8?}r(b#St)c@_`+m1j@V3{+s><^shPc==`ZlWkp70Wt=*(yOHMap7pFaw*7xo_v#dIL<0;+iKYgkVWkn0iBcTQSe8|L&QJjw0Yhc6sAlP*w8BMl~ zQL6;>y{sMbqt|Q$j%3_*i94&}%2U^QsA&YiZn>08qaYhUpmo7jgVE&oO=82kvM*CV zKqO<%mf#hUXF<)Scn)P|M-#yk!9HXIK0viJatZ$?bpJ;<{wLnR!TA?Cp6yQx;J@sx z0M#7-&tv!h?d{l=lmbbNQyNH3V{8;rEX|~*_m2}w+k$nzbx6)QC#0tWs*&MVT(`F? zBmEArzs!&JlDW1=!1~;Ni;Di;?&kFZ+W+yDmv_l~;38N31O48f7miFn(4IFQvNB$u zm`e>sp`oCxqGEVf3S;9Zx(27zs3wQ(9E+TYGNu&72hS}Cv6$41?90y6`@)0n5X z?Cq*OQp!~5Z^#y}tWQz|A?i!B$!=S$8jWit(hZ%|V-3TNyZbyp5k871-99c&0gH4O zDZ3`?Ox?%VsL)8uarn)C-UJXw2=;31Rlpj>K1=M7eI}?1AF(1Y@k+Zzp$F1kw% zC5E~J2z<0(H@VTDPIftZvb3B6i;VM(RW&h8){%ZMbHojQVILmRtT)k&ohQlb~PgU0?uNnzWCzy8Z-Dfa0)$Yd5 z`hM1yPuRs$R+mlY`n2sSw$&z97E2evT+<6P^axlH-sCC zm%hwMISv-7qj{>OIXm}v5_0|0a#)!&jQ1w{(4gt$@d^+n&P3p5;PDoR_A5~3aW6Q4 zPgMa=u!O|LkMN=_=xx#0UOf~D_mv=5P^0&AAph*!o!M&m#5S*;F(7NpC9z6V(WkIb z;ybpPY2Uk1P&o`lna{@oQ&V$ ztBmAjtbnSns-6Y;;xJ)v%bie&E>xO-;Dg{(XH|(16V5RcqOrX?jc9U-wo`3zIs@au z3V|bMALL0XP+sCC6Xki{yHy*>c5P!*2z_ln_=7xKjw8IWv+B6LVw5*ZB(68!I=`kf zM+6+bV9x%PDRPcYMtPk6eel!eSI@3q3nf#y?ZP{=zZ-BN?~qLy0>YD5pe%!eGG&4Z~h>dF!|DA7M6&LCea}o~&VfLt7exc1170}-zbmV}8EZA$XqV&@ zJ|wnoi<0;O_{*rq_+EripaL$qN@`Af9G9FLm)6RtajT85wd)f6NvRmcK->=Jz0c?26sIJckPPvTp}sF zi9FXp$Y_)ay^qQ~4l3B6eJo1h`@J%;x5(-s>TI%`9%?8wg9M71@3IRQV4;Y5 z#2o^af?uQxEylX3;x4KKi`F1mG*lz|8D47U)<^wkP5tI%>P{h&QW+;HvRKNVi3r4X z?+)#!3egFqsB_0Id85rHLKf-Ick%?Not=5u5K=&;e%6hR%}v{-lRMXrSQ}LCUpX`$ zHTi(Zd0AT^;2X!dd~k3uvfb>r${eCyyZLg79DP zg!ivItR>dJ41IfVEr7E|oZwU+kqwG*X43g~aeEK?o*TaN#;r2EBa~6S>jlBH@Pqe| z5&fD;*ADo%R6p`4nin7nL56{h*KPx>hi;NFEi;1akyU(&BPpcT;qK2jgint>*P-qoB^hu3AEC_RmH>PRRS)`fN z3NPtmdHIpg4(8V=V}e|kC1Fc*Z1eRp=~K_y=Lg@t&VdBybt;w|(Fa)oN zBxFEz%>bXFw(~gcX#V}|FoQr&55N*2Smc)}ae&m?`_jt_lk=3kKf4aCg z=5ejqnat9Mi$lwo$y5XD2h0u9&E5vr9J%iTR zclCSRp4+Py3-~X~#dyT7QHV_YTZj3F5B$?%G6RX$|D`q#6fpZcuZDS;Aw@STdbsoh2+sKR@;Qlwb2%Gxe>Uo?*D8LrH5#; zSam%obVusa%iY?)^F-!@t|9DLCZR1t@ZQQ?`Z-7iI;RAO*wjB<6ebZ%&AzM^v(p$r!;?_Fu%Ymx~4`D5p%MY(Xk&GQYX~1 zbK4DEb!@Q{A-~k#y__sZtQxKxl=9e{to*tQO=^j&en0eiCT*3Yx)`u6bVL_$xfn0J z&ZdBGx?gp_zS6dTc}$D;oUmjdx;)I2UgzsV+9>V$Kwb0w$ccTa4)g98H5u+4NhTHZ z_8-A4?XNR(G?7FlHgFs)XF5&O!BzSJou=bJgTO)n4#3r&>7l7$HA zxyx4K>i73mx&0)7W;TXGf*oc~!NGwicqcn}kqkDL;ul=x=WMmY_gC2onXS(i->#3i z6lRc_rU4(Sygu1IZ}=~&^%^wlR(ERH21mKtf(!1`Rz33-drI|^ajLBoCd$m0`dljS zmBg&IS{PlHAKgG|LgmSt?q2x{Bzgpqrr^R$-KK91*3FW7x^o5*e5WPqWd)ZiD8x|4 z&WY1YEO_6v{?jwr%(4k3a%}lK%&=A`FG>YB<3fiui!V_=R6j*G|0gRkBFT>#3(k~L z_2b&0E0u$55VM7{&5Gn2^n|Su)Gyiv(6iOQ1AeeZJ&U=$Pck0=T77r~KS=L4QqH9l zU9jR^D=8@Df9M`7PE&SyD-c|a>}+xkbK1m?-u!k#sOyE6hv%x_YlV4x#zW}Z@pYGC zqnQyEQ7NHLcTxTeuJ`a^oN2S{eJkG7 z{qxTfp9iM2VO4y-uAA(F_Nknpuqjg^88#b(mBlM-a`xW47R0JUeDWQoZ)b=LeAFUU;mw6AH2@<3l$&7*y33Uq4K~#DGZSLpI|>4#kTK z1Ubd7-ZO~2Ul`+*qFA&q!%w3uw*|vwWj~?-keD?MJdvi6Y$8*_ zWqHEPG}o?y1xi4iqNsRey5R?P2xKKk`LN|J8@FZ(PIgFqB%MuY3Z*zIR$J%AbANe% zVKV}mTyz747>Ok_4P>${ZgAub5A4@(SsF5bC<%3)WS3eX zj@Tcc2hO~2V(Q|s3g773Qv;e2gaN9yU(tS0i-mLm1Vb0U2`NV38_)|ZT7{^+;Al(Z zLWrhV)<{+0?2%?M21#NT(goWiS7T~A4pR3k3735iVq(rf(Z!|UMOEQ8L4m}aw=xL_ zfW<`7WtHWbpwJ|ksEC^xe@4eFLMRyj!pw}9NG6_)A{@GyBD5O`pa{Mt(o%&2C`zFf zp8m)HwvScVh~gF;7L3xRs|Y0}j2kSE zji!P&NDZI=$2dmHqtQga(a|)d;X}|n13L(xZ&?HDlO7H?4i5b4kn`IS$aJHXRGe&4 zM8zh+zm^`s;=F@XF{|3fBR`?x=5Onuw+lV$pljhRyQ-5-fM-$78j{J3OdC8FmlZ_- zLZ#23gjD8vN#vr*=xlI}g%txl1Ygcy2(l&Xw&GP8Oo{mu|)p zGylZ`LzfPs!ZHq?Mfr>LVR}?&?vilv8_JFUqlG6uou@~s35o_KNC#k)8F{?0Ae3ka z3bzZKhFy+vk(VhfGF7P8k;j{uoW>&=5F2B1NQbv+sELAEDE!t$Fjf_`1a)hLHg*=C zhjwn9oo~pOkuQY{A9Yk?^ zqcSkN3SsOtA%c!Nh|LQj*)#Xoieds^D?8JeP3Z@ePJWVVotg912LA)lx)Z|gem+N0*Dm&R#o@J(Fl?z8~m=Sb_iRwWyaw`7$rB}~z zWyW%IR*DHIi7b-E8MQe1t zJRcd#wz}hu4>g)Ke5$Yv`-+!MRJCFs?W99vi|odbF(aiTJ^aDR2#NYLm5RNgbw;X| zCi7-khAmDj?EUmx+j|-1;?;5Y>NH@K+rA#96ri>FNBo|4l?;VaP$Tp5N`+PlOjWh$ z8}~ILl|8U^N{{mQj*!jU-Xn}mFiTxoLp&Y!FWXfW=h9R$_6Wj0vRY2uUdgm2*eahyc<#LeBu{w}R!Mu&*z(6JQW8Q)*X{_y$P!Sj1+R4#6X1`4 zj6xjlJL1z`vr8U(NYYQnPYPQvllS(}>2`r|lMmTlBDtF2DqUa^h+kv7qn-Qm_3YcIeOB^S0E& zPRor}0~yVA9(~2%Qp4R-&dQDI>1?gZcOGS8g<9q{hq7&g837t#u(_dcTK4*xCOoU& z*Q1PY=qr-qw>24EqYHAwRHfLam-#;i4D%OMO$1%DYD=JVXR@C=n|4mTILKl z7Mnr}!`-#VUz~cvKCs9nmXqNO{$> zclVldbEYKpDaH)eVPlWl+7ai5=2K-1G#V|reKElKxWOA9@`tBXGgYpdTtYb( zhBzhS=2Q$aZNXs0Y{ePmS-6Hs)$E$3z6e0Ra2sl_-`S+Qb02r{1pbVPql(7oTn%Gg ztEiFo5edAPTJ$DmjHUrN#Xh;M+LLm? zS!XcaovyLDCF64z>Ok$&+7^-p&zLzIe|jbUBb}()L`@&9uR;I z0f0bA2alidCT$Teb6vzd+g z->ZGJ>`I@v;f&1`W;sUOj5 z`&fpwxju0*b82*&+#5o6DPzr>^ydc0P7BCAZSBox^pPa_Kt_7>I8yd`xVYcU^-^xv&w6dGme!F6Z%$38-M&0KlkSS4e zX4`5`pQh=VMq+TKj$Ox&Ej^!YabA{CDGZM|SRub%_u1#ig!i|&vO@6C}kb82%2 z=7|^VBCr2V5x%b+rh7N(h zV0soYCXQoBCp(g6M!TPxis@7buNychCKxv>maEDP%nO17jnjYq9;iu94F~Yu+`i79xve&V z=~YYDxf?HKp5-Wlt#}2!TQz0+QV=zMGNX4eIwu*=Efy8Yu1X^PyGh2Y)R6#RhK<>@#(cbHq)t^ zTf9lG+z>Fc4;`7hcPByDtf3wJ${F;)hd&od-||UC0~8B6iaC@|e7W>y(0k1WV-DD@ zlyyvy`(I-Q?HUXv;H`i3B6!{0<;ln`F4(6jD^Bkut_7~nJ#>BNdXwpNY{8QGhyxkR zuUzB~EpE9GFHh5yrR>R`g1rW8(H~YkRZ6-e9*FCH0^Q96+N)LKpJs>Vze` zc`~NKRqtdlL9d?B{e)|WUNm=;x6(aU+$jnMXSw-t{w&#P$AsfA<-ozlQxr#(`w_>+ zRhy-od^9@Xli^L>@;v+wg)X2LJjj~iptx;Zvv!Pn-*RSI0ux1bih}{-l~i}}&@u7# zhel^-5MF3D1mtk{a_8BD-D)uzonEh=rRz|zPmeZj|4u?SEL=k|)WCbU-zweD+H3v6 zn^XJ7iTa)kH`<>&pEaSs^w!KY3V|AKo^ASd_1H}B>=Dh^ajfQ$gc8&iKAEr|g`X$~4;)g~PMR!aePg?j*Z=4A+Y{Kt+-S0vS`w<1$k^_JG#5v1j;oAMbKCi-R~pcq{z2 zZ$Ul{#w&(9dv;f^oxt%=)qq4DEI;M>&mfeAwmjD95VxSYvO+;x4?7s7b`26QHx`@P zb*^2W=F;holgu}Hjn;H9H`ca*QcKZ+=V zBokN*IvJ$43=RbD*XH?~9nkTo`WHw&Y4VQA2L^hE!E$lB?psm_A!5mm*372V0Y9>U z68D9D7o~3O*AAC!Nr68+-1Mg5Wu^N*Zr7UDK8`EHE{PE6%Zlh0@Wz|1WcyZ8Z;2qW zoN!)QV=*cK$L=Gm*c(bf@M4IGY@)$lI9{V>fDH@$j#--B`)&PGklCpXz%sx)vgnCc z1fU^t94}8r*<`U81)@HJ-cT^=9zT_#R_&N9%uP(a5DS40#XhXz%n#4(aNYL=f+6X3 zV@;Vu1%cJz1$M0LucXuIxnjj>M{G4o3&#osf~92FKStCQh`uW{{6Yshg3BhyOOSE#K*ALVW{9v3P4zolyjwb*| zE-`fFs}o@RV`P4oS zAbmJDDmgt4Xp%(RnZ;{1ym)Yr+twI+E<9(aNS{h+!sMuQR7eQAA_jMqpt2>4okA=t zqi$jq!nn-OscxtZr)w~sj#L6eod&;h%-Hvyd{5l(N!oU}gKIiLbGsB9s@uBR(ivVEH|crlMJ|GjJV&K{{k(Wb}H>c#y3DMhgS9m z3{9Ze0pW#i{;~)qYKH zHR@CsBbJd!I44*o=R>(>QSHo<26$pWq{ANzCT-M!5RgN0x=zU=cR)<|UN z(2ysmseicIob4Mas(sp2kXwjS$iBfO#D}}1l!zqFv)T5{43AmYfj8M9FaCS;G9E+o zWgD4iGkiA;_ND2D9WSNoBm88;a{fZP`WMEMDDv9!27rl^DA`xLO5h9f|KE=IMOb&& z{gl-ZcD**MLW{uk+~gQmi&*!3KLx&5e_G4#4gHyTLeu6s^6@}5 zuljXve#IrZsNhT3ssW>#60Md(P1vB^fWtv6E3H<#){fVsV|1T6*h23nPswE$3gN3Q zWbN54T9tk;WvbF4 zvNWD*Z?DL7zkk|UhEtxitgH>R#Od6>r^G($n)y5+v;XLGEw|ODMvIzr-pPcP8?qx4 z8a3f7bl4t3o~<@w(k8TJ+`IV*+AhpHI2^Yn3?+Il%99&K+T?j%2j?!X!fH(LUb?dI zfiD^XJi_5?nFu(zhblO)|E#PfQu56Ykt%go zHBzql!!>KZg#0@71GNh#;yDo*p=JbpfO)_F`jh?t&x#^{2Iqf->?|Byf7NODN9m$} zjpYA7r?CAmQ06S`R;3YSEl;{HRvV19Q|O5svcG?P;BWbO_=m3z)3puY zI&N;HXyE*1k9N53xxY_J<$LX5?&ngGK)_lT27`iUrL=0xAecG#bfp>! zEZc2y+H1<;wjD}9h_)8A)Yt|Z2$ybjhMEx&-HQ$iVd+4vI)rejEHZuowpKzZl|31< zSZFi$pd8dxGTUo7OmaeN#O!^~E;bh%fP5;o#R*$K!PC|DaGyY@axXuL^-y%v1y?uD z`%>0|i(fQX^r}0HvHc0Z6yW@M{KLlXT)S>NXj~B?M?QR<)LPG|_L|p;xwpbrIb)Z) z>4mkE+&OY<&W1cx?ONnIcy0&Yt_T=)vs**QX|tb;Gi=k0Jrc0RR4<-S9z8b{Y>3j< zW;I(}#_mKSsYf_oZr+|eb?!}IHaM}vG!_#pGMj&MKHe63dv)^b#aXF~wQ|;)6=5A> zpbdq=zO#poJwkYr2UBu-K;$2#q^i7t9*zl7Kj1sTj>C4^E(>XqKm6v0S${z^Pa%Z* zB0Cf}hE){DVSj$Z6_!GoTHfnvsKiEyC;ukT2U^d}7X5X(cRw?wSH&HZD`R{PZ;!GM zhnl-K!w0!PT_aCrIk?a%)RZXZ#&apVHZE>zYUyo$7c^aVcsueO!eYUds_gb9?t)mh zOkdcn^~OUy?m!opi+hQ}X^&eJDvB8JbaHd^yN{DY_1!sLgEgCpo*fav)2mZ&Y87_G zCSeyxJ`Yhkf|6GwtS@eL9z9{K2y5I)37*^c(<31Vb~;1RmsXWf30Z`@;38=(zOU^t z-{j4k2QjX>G@Wtu=dWc2E79F!C}46eaVEvQpgaj&!T9sFKlE~kZJ|B9+I#qk1f8hx z16JPW&3W@~H`}Jb+F+wS<;EIh(KiWl5mWUaN^Bs6-Y9(Ue%*j?KJZQtDb-9VmdfZW4!c1_!ajQF6f(4F_O?0&;GFSqK;bd)R-@vvm45$8T?ab_e!n&S zg{$Z%Gwv87TZyzA@BJIBwsR{&sfe=ZE5+!!ji&=(?w*pZ;KFtJBWFZ+>qlGQY*Jts zL3>SM%Ruuu+0yPp4Eto!i-VeNT@b2^s&V}VPQ~;XcxUGF)SQFmlA6(5^QW+J(>u8+7;S_LQS^YNf|B7mqbo+Rx8GBZJ@wFzzR^o%=CPQw1u1fAllmV88n@e$+G7{b`p1W?NJ$l~#X(3;*J? z{%}KoI43U7zgWI(f9k3Ji^~FPl>DD(-TsT7>wg%0(6vzC8O1uYO%?*hgv1aP6Bok} z6~r~pIS>LSoC!Eim5*j^Elfx4bR|De!yoG|>L`1TMI{g|a+(zL7Ix%))9p-DF|s<_6s>RS(JnV%n_nfSk9Y!FKAt zX$k7=Xzg!3WzAPdOhm|&J&BHm_{_)exO`7fiQBx{2 zl-3#r;axM}BU=tL@!jvR8)i^BU8h@-y1_i;)r#Q_1>QXyhy9%<#5)5y>mZuS05x9=HB$u z=|IDrP5bzyer^ey8+3f?E1=&zNb)TNN*Bso!wV;Fw%yW|YX9nsQKGbQaSmwp( zvZDz99H;1dQ&Bkuh}$fq=r81!o@99k1V&Z3fH`zfz5^ViiSUdZm_x2194qnpTT#I& zuAdtJ?@hgj4gJ!mvG?P!oE7G#x3^MHn85;>UTlW6e|y8`J!k3*sPm?3azoViAMo*c zd0oVl-M_dPYr?O`@`gn62c@+|m8B2-8YuZ8Sc~z%62*_&jR6g4N4C)n4rX2!cnG<2nMi2=BGNntl^A*XC=@->1 z?h_^Ff!*jG^Piv=xhvmxUunD_;=QFybC)dAtr_$y*uCtlYhmzBow!fgX$F^c*asex z+?2!MCrr=TaXZ}U&5%&-UWdn+Ir30`T0(SF{Qr69hK8ro#C|UmNiXR5i$A| zPky5Y8(L@gC4tfOqxbu>7(xj&Qt8RK+jfsmrLHctaJ?wEK82fIbtOh1JMjZvvGp|r z8iI~4?D`X9XU?2ahpHj7*v(1z+2yi_K@wP5{$byGU-zAQmJFvV6@m#Z?lPh_4d%QH{y1V z^O%FDa#xeu9)fMI=r*1OeE#LT1JBpJs3xo}+b8^h(GhHg>b+p_g0+eSN+|)wG^5nh zT<90Z>D`qdrXHQ~GbU!YQ3e)Prv~Sfg$PPRJnXy9Yi`po;+?`f;rV0Zs&eX_UEn&! z+wClW!$8bUtMz@-&7LbADGP*N|3cwQ;e9=bj4>%@8)x#y-G}^z{yP@j1hzaD-tK;W zG+tY|OGTULB>`_uL&uNQo(INPD!f7)s&2`OWgXBMPO@CP+O;3wU$NU?&ujCh8445z z_ff_xDl&%-(5_+6SHs68p4T_K7ad>_OMIE_iLHbNykohO*WMVL?0siki6;pS4H9}582j3WY@-Zd<*?@n{lag6Z$%JqxS+o>d(f9zDyuhaJ@p^2+B zg|Us28(07jr=C#0GaBp@!c$fv1*E{sZx`Y>ijW;Sn|TJa9Z+Nj{S|BetLEkmVJUt? zG~BxmgW39RZ^!BHpTEhIS>2Y0wu*|nh5EYhsAEJv5j1bIIHR>4d86fMiRGs$WQmHu zaYn2;^LxN``A}leWTL|skiftfv*#-Khtf6--^fvfBzij*^tNA}pyw)96)6sviegyv z=Ju#5Q=>xa>S4fCj`_N$S35jf!tLF_CP{jKFa6BEboeNsfcY6?Mb{TIyr9?C5cPX9 zhP0R-MJfoO&M-j&ygftMf`26(ED$jd07p-)T1EoL&UpP;M%rPeSO&a+&Thmsn=18g z5;`P4_8G>CG+c2(-lQaky-`e=B4&v2bU1ZusZ|~aZ^UjMECvnwu&fxUz#`jc3@Sp= zU1n5B0yd0cOUy`)FEntH7SUq-0qgmT#cKJ&{BH=NMA&S>;woj)!o>v!H)IOICHcaz zQh)?#g%l13IGAQkj8P4Y%jvvbcw|Qt3>s9(S$a70JdQg?%wb?Jo{EyeunPR6G8Th$ z_;bH2)p-DVMFybT>e+aQv#(sV_6r34p^zQ-Fr=>|$l`##R|ob55w18n5KIj&4LD#~ zu>>O>GYJ} z;irb-3MG<0sHwDK47f$@x*&&pQmkY!)Qm*oh^zS8S0;2wh}=YBP`tU(I2^WCx4b!6 zYPQWobVf2yGSb|6{vTWUE#Y!f`Mb}bl8LoG8<4}93yZ-K=4HdIwHOfZoEpdmi7yip z?TUNwpzbHd5Xz2!dVuv9^_5nk=FaA?V_E&m0QVRy{rTH|QUswaxn-S034XRbA)Dch z)F&%|AYk%f!`{36uR?h@q;*!r5zGJYfV66_e&VL@<9)ymYmu z;XCqYP%M(NP0e8YAD&KS*Nz0*uH1ipJq)x1Q-?h6fL z6|I0$_~G#29ecV`H6SSY?)20^NoAK+BL87UsakKOv_P8_j+$l1nY#zne8KW_<}wn1 zM34uhRGCbhF7?LZA7h|N#=vVa#?0%&bQ*z4`a(vV-v{sHogZeMpXS$%+&_t}-Iwc+ zO=%pXRK$vl0U3CZGOxr-Eo zfstq{e85ohARg-8b>G^e-?Zxkz-X|>H2n_o`xR8i2_>B`+eE7b5#!Nj<1`vRs zU;x52gDu(2WmD>TdLe)02nR&Qz+MMZi0x|*eS0~n!nTS1aTfvv!;}J{z4B^`Hgt$- z*b@Hpo8CkHL?>Z^KLSZ70$nrtQu@Q%nX{xmB;QRPALF z(T{yrTT0`GUVe$o9J%F6Q!jD6VDP-N9eBwzc0s7Ac^prWZzFwm+uGXImm4Zi=dz>Z z93QM-2lDJ54i*oLXU4iKizcd**<%SRHS;#*t_UFo0t?Q)2GjS~e24V-)Y^*9>d z+bprAZySzO{5LzfY=170{#Z7#0&C0tal#+3nc4oV@AI##secOq`l~nw^B<+N|5{A_ zM`$~0Bd+)o2pIH^!z&Lyn-92=i4rmeS}1tqA;r4RG;)mw*p)iWh_p8?xJ<5H_039knQOLDPW9MX&47VJ zU`c#tOgs;^SaA+#^zSvT3P9nE${;jVU48Ibn#cT1dQF!c0}5jw2+UbnM-QhWAvV%AE3{cwWQpZYU%p?E*AWdM z$kO>8x1_wbak@``3~k(-OPPuv%ANlz5;J9;ElwA;t%N2DEDo@>Y#N}J*CxfsFt)r) za*1v*<|pf~wso-HSz{CgC(9z4IIQ36Uj+dL%fLc|vzU4^k5zx6QIcGj?KwYdJ2sh$yY zcy;fP=YxU;^eMcX?m>%_fE1i#|33RYbns$>>m`ex9nOMCmppl+3ul}ZF0LqFo9p-H z-cyZXfKzI5dNR*}nd4Qb#7=ArlDkO?Mq}P?n3396i>97BEZrty2o6(ubocw_ck^wU z*lAHo80~%y41LIuv>^y}>FUeN>MwN*j7P&PjsZvAA#R5++d_x}GC2CvgQzA063y6q zXW#V>7#gb*P>$gl=5`H!!A7cs@YbhY9wp3GwBf7U&Zx?K3#sc*Mb9$<+hCe;*J zAb}`?t9iZWtS)BxX?=`a%jwiSjZBEWvnrcZco4+CS9pHy+k5v0i2ErvNYzO%l>Lq> zRn3q~b_PZaw!09!4_Mu;iTNlpn>)8Rk6~7!qsC&}#I~MhV*L(0C#WtAf;bhVaXy_$ zvb#oE`ySOD6QjYd1sPY}L-zNGX@g=L_(9j#qC@eWy=ArSA1@%Q;zEdgrvhwZcoNL= z1SN*njUeo;n_~8bdh=c15{b03n$W0#^w;DBa4LZ^e~{@htbI;8))Jf+Oe#wPZkVsV z;&FDX+v#g+R5TemrvU*_wmQe!aNwZQ+dsxa@%LO-$um#MvzCLa*qVRCVRDji8Y-!{ z1eI0tBJw3!lqVt?u@Z9$Ez&ba&mkoI%s0c29!e*Rry>GAxO?vW{Z7Dfq)mcJNo>V< z?oI|4m9+; zIcM?Or%XuVPcr3$xBDV+yWEq|Nx$rLuYV4A`lr24VLsxUOL+DFt!w-*oQau<^M7LF ze^+IZjp^S3n*JY*#{ax)Owmlu5JU+f#AX)~RAgTJlS9fJcDy-}bmk;Qpku$<1|2w28fQE75yDV$7XAQ8G8uDggTS;w&DI zA(rq1f!xzV&`*GZ+H}%^U`!E$>=wM&HxUSMCl*so%?cixfWxGrAyCz*3^2_n4}<2X zLVVBNPZ|Ar)zWQLHOTelgd7wh4RET|^vXFlH~eK6QtlQc4?Nz<(8hMI!Sp+=zMc}%a@xdO$Srv#I=eoiDlWp!1MU6b^%W-_K9#%r^f3E*s0 zLJ)~;u)501^D+3Cs;Z)~G!4clKH^AQ?1{S`kr?Lfd!;6G-y+N;?K6LQ&W^c@2Y_&Z z{k~alnTUY|!y9%a(z2RQ0`7!3!f}EM-O#QLRp{b9*PMjlt{slmOY0DR@`twp5m%%$ z2Y)G{nWaYfjnMM#q#K5=Shas03=&VXYjepYq1Zx?u*UAgs`%+GagT>|X^B(uC$7BikC`Kp+9g z$|HY$e0q1SNr)oAxK0m5g(GW>#{llAV5hXiG#oqobm->OYDL1hc;`SkV-7zFe_N`k zu*it5ot41lBkZxY5fX$5)x8X)W=Kt}%B%F32BU}FSZXGT5uc8uWcoHePJlIbwF5WQ zFix)WgB@B?92K;LERaMp%?3wJ!!D1jwBF8Dk_Cy2Xq>XHq?dHtM~R*h##=_)70n(y zfRt&YFZu_a@q{yhjQ*AEi_K3oe%xhbONQZ!nt|wn`%J}ioZFxE{Yohm`47>zLjFP) zlk`~dDYj$NrLVR6ic&CV2$P9q743XVd1}` zwf_iZFxyR?Oa?v74Kg9iX;K>NlQfhNOQQ4U#fR8NMGi^c1Ci-WewW!Xa?2IS+wc0a znxmSGw>ue@h~5^IN4b!u}n6PC8u=K{*qF=KVGL2`$urXBHe z72WA?qxgeO1cUG($isVZ#ae}PCy3arU3#SeTFkOH=OfWJX`n)wwd>H}xNTzwg4RL| z$yrbBE*vmB!O7z_z~E3A3*oVgAycYUX&BPrgT6z}QVz+E+A~$Qn9;a=SC?+rCCz!% zYNebAd=t$F7&} z&}0N+&@Ez>7-Vl+pPi2ztdjePBzfn(rskf$ zdZ22Lmlpc|CdGBencq4s<&KukXWIXWS~l(aL*~eN*+PXjSW+E7dt0`c zC!@BxV<~FcwnHnrV?p+Z$vjMwtz!u5!iIaBhtG=>s+ZS#r>tj_^$!~~I=;l}J1WN2 z7J-kB@Hdaunv%C69hF1|GQWuS@Vck+PshA)sL*IGsD?MnQu7`dWJsTm$@=$86U%O> zMF}M5#eydkC;$h5aL)L$D45J#>4M2Z6bBLjHY&S7vS_vh>5gCl1DUliO$2wG@Q(md zUD4%N6*L#3kZ|yS_X3=Qc`Rrr1i7o2eJ-)qE*6Cx z8T2WPKh$Wc7k>!!30O*O*LIwlHtJQUEoI#}wWY)&(fA1H3`YtH7yXw{zR`k za^}ut)L&dBH2)yrq4oZwq|T+Y_W~C?5#mer@muvKLs?0xic-hGh;Z@7@qO>}TWOy? zTRMII@~zY9;ZE)9oh5T-bZAhiFR{LBtV>6=cvF02D?PVR^1LGuntTvTY70{;)&lpc z;?PxS#GCEVB_l?{d%{Dl`WulWFcHykK1;9X{e;66@o*eTpEF0& zgk{B=!A+l9?f48>G9WOyVQ4lY)ozLL<|=QsDw+8Dq3yISWuyr0s&2|+v0R>^DAX2X zmOYPkb-i1Vnjk{7uzpqax%+k*S3VX0GL8I*;QGj^R+D~zHo~0_FDA=k+n##MX?4Q0 zsZI~^@T?7R5^ZW8@6fJe8^?hXTY8Ek9MM?5xNFrl%bYW8Nsr;a zn`pW`Co0yep3y_ zGqfG_`7&aOQsoz|u9=<7Q1mBDGfr(nUpcN_CsDoejgT(+N?5IYw&NSQ;^$0Trg@~D zd`RRytJ}-un3AZNcO0~!x2<7vXhw-$P!2XU3;R(MomMPy+SRj zG9DaWYytuaxP_Qf&>77V(6@yTo}Lc|DrkCU3?#HGG%gHV5QuSLuMrt?i4**~Q2H)l z&cWc5`i>)t^4cu*xuU$EV%Nkw2@>FQ_VM-nM=>qC7Qk_LjUGJWp7^iPemYXtp)h_x zkp^xiQmY@)qhJA^P9c-9$MrT69@;b}$xFky3bP_ke4z5-Q4-c1Mu+TH2EgdA2>!8#tR)&g#^!#JMYc~U{LNI z{JBjg9W0_w43XlCo&a4g5}S%A>*PX`L&3#u`_nscO$z_oZ4bB?w?;N50Ep$mhr}ojlq~j zaNM7bioHvs)Aru!FVQI@IAyAv4kzd*(*q=Zi&D@Le6)qv_AfNr{Z>Q=!3BF5_8Hrj zwPCp94tPUo5?EzsyhcN!sBeRf{x9O*Ix5bk*&D?nxCGY_+}+*XHMqMC?(Xg(kf6cc zT|;npcXxOACdoeE`|f-8TKB$xoO2o0nt8gP>8|dssi(TS>R0+3@t#D$87hF~Yza$9 zqSiA~qI)0XZz918P-_|mYsm0RfYd#wx7TXj9v@COPNGl*j{@{l zDG^ct-;N<_>V(%ja?P+-gnm2DZNSEpucz;<9S*=#)L8j_%*pz+Es!BZ=>ag2$GVCv zvbJX6t~Hu6zF+{tKNg!=OUND9*z*v_mTCHFz$9~c1fzP#*E>MZ9F}E!NUGAW6yxrU-YB3v80rY#2 zucGAr0B*z`wUUgu6pExyrW=}XmyE_(=-U(c>l36M`KeZxIfDavvS}iW1jOqS#4C~; zrZ?6K>$h^ZYai^^4lw?&~Ei9}~b_ywQV;r@QoZ53hz7Oqb?`UYL zL2xPx2+MN0JE3cs+q;8y!|Yf)yTaqJQ5&lNQkKb&k~Fo&4=bL-_)3byiwNlr?NS06 z(BJ>~V6{|zc1<9LTI58QzNK58R+FeP@2g*PYR#xJUQ%D?GG;)N+(MzFN;Q`u{auL; zgK400t*(L?4!m*iQd}wca>P6Lp|gc0{ibEmgv@8V{)~zj?y=cq&HHnI@)^P6itbyQ z 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 Ix4*po588@(ApigX literal 0 HcmV?d00001 diff --git a/docs/assets/img/bioinformatics_utsw_logo.png b/docs/assets/img/bioinformatics_utsw_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..65a0f9649ed389588a2b970a11799362513aa7bb GIT binary patch literal 30095 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 z zRc+av@%vDKxZf}X=^-7uwGn*w*qsbl9MM|!GpCh{-a_t>a1tD&w{atA!C%&-(1G|t zELm}lz&IgXK0`rf&=AbOiA^)tr@0b4&c0RgeqR)%v#c6YG#qG)dHQ=Ke-!mr_dp2j zQAlX6N1q5aMzMYi2X94m+WI+_=c~V$E-Jw^2ZaXhgB-tm27hZeGSpWlQp?5kJ#GM$ zA70zGl$){~u6aSN-w}}14i7n!DD@p`{n`VCxthO?+}+x}iFCyJ&Ynb6_WDgFUXT~{ zE6KXSRHBO-MgpwJ?eQTFCoLV&J8;}*l5T8Wa=P<60X*ywpIZE*7$bF+&G@Fm5h>5} z)60E{$4AfIWEXXt210gXf7i4j5z0o+p_CjhI>*dzUTiiL7ojA(QTmLL&Fci(2txs> zo8sTpZS|ExWZRi~!t<5+Be=FQCKSJm3Vzs^qzVah_I;cwLagi?`+Z=9BX%0`N3j&g z;v>fhYq^LNc8HSRS0fL-59};2d}0`idHRhNmoUO5<^mG9`0)kLDkqSw0gqMhCvQ() zIt}b56GKBIf)NZfLLYxu(9zR5iK=VkazkkyicBCW2d(cNE#J4R35`aXe_L}BztHw3 zx4*W9>UQ6p+B}|?JvRjU;ZLeFO?J2%Afn}kafSM&k}PhS>9u)kII0qBfMUPv5=8a9 zt(Af!sB5mg13q(oC`VWd;n&Ui%A*zdJMzRl9WbE~%n!|d4JwPQe)@7l#E98mS6mh? z-r!ADU*SMY%$>Bn#%}&3tsG-n}*jN+(V3I_qNMGw}GJUhOtOwAGhn(Cb#P zaX+3>aMeo4ax;E<}5*VF^wV23tkw#FM3m z2AzYC68TiV+x#C-?y$qq)4cTxV=^r5gvGmgzR2h1f&J7l;#Gd2s4o~2LtWeyZHgkC z^pwMQSH)mXewq7ugs1>2Y<#aY0_mfa7jyZlH4NQ$+A4BSCo(k_!`v~Vt9e$*J$4Z* zGcT7%RJuHL@EjA8Gm5bIJ*G|@aqa2iM$VMw0CCPQI6kZ7YLN7o9Cn%$uZC)E3-|;` z{9+l|?aGk_6-K1~U6|_aKh~CVbbV2+P~6hYJStazak4XykDNBL0_~CdQugN%n1$dG zXX>D{?j71oWoBU6?#Hvs?LMNhboA3Os*<_3;#X1{miawh{J!?sZUXNG{hZTV3T$sv zK1(gKQXk)IM|OOjZBv4G4f@8MbEa%;|1>eL#%kA+!t-$ep;U*bHz0MyY%gpKJT+f3eQKG)_ftDPnEE)+m25 z^gzwsV&g@@{`mLN{eHZB+KpfKk1Ck?v#r2;NuTo>fLQ$m<4pKryEsdwx-I}odA5pYBxFJ?8U0i^qTCqnFec7q3H@q#e;2NtD>`JzG(of z|IXQr99!LG-OIEed?n)+*}voSMNO(}>1Dj>B8kAjNS%23P1-o`nflXqzb#F%n#!oc zR8#>>A`2Yb_Mf>?6}BMDh9Ox{g!#b6qn_|}_1#Q$YkipZfVebR!bfFF^{?(?U)Cxz z%GLbld%PZRm&OH{<#O1MsFg2FSs!I=4Iq+rDB|h{U?ud zrE&6lOQvGOu;nt9?+V}agef54D_OBt5D_c+2Z&I5HtJ}LzjYf)KXB)8HYy&Bar|E;ZM1FeG^s!&@35aQYNTpue+>09cvS$NlJdOE&_hAInP z&(2_SumEn@-Ty6Hd2±+i?$IJ>4|c3idMy62KQl>k5U{sQ06_nIzm-!4|KtbDH( zWdCiZNAe^+H$JThq*)Lo3&S4Gnp(i!J+%0x0uE(uR_jIZur1y%GsL2-oTwUjUjNP}4 z7rN0R5}&gARV$Tr)?54;_C|FnYT%IPok`$cW9pa#Ah;Y9hnZCs*fz*f#*pRTd|h z_W)S!io%&|qE0!p=4PZAeqFCW=G|Wo7~`QATkHR{?f^gbA$sY)6CAR>6dj0$osjdg}QYpcnFhsnJ_2T^v{s+ zV-lKU4n5IMNV`zqDP|nFJcN7t#Z2=&V`4t7Wwp1Nh`$S5_;`6r#+8m+O4p^%0|V)d zxW2bC#;a!IuMs$b!52GjFA1Nn`^fwrMrD)?GU<|V^>c$+`h3*048sAE27<{c(sYaz znp3A8I{+~s(0e^EawL{PAu)tH&H9u?A%KxS)U#Y)GGAx1?9?V;$ zN{f6cEw*8@R+5FR)rom6q&0eW>-at13K@buV~3{*gNeGZm7W2Z?2IDsQ{@lN2`^*PCm`(0c^I2Wr z{CN-F{EMy@y^bkXG*KI|pG48iPM9$n^o%bFOv+#W5%FX3?s~w!5{2}s(s+(yT9kL5smuw!$~}L zX2_*J65t;(>mPZ$>04wQ^tT(Zc;0Wu9O{kULddbG+%n zBqcH{fBV4-+_7`j^ezQaW4`y z8fEb%SR*omsh(1lQj#|9QXPd=_aOB9U)88w9jkc%UJVj#=c@%AU5YnL%}w8S4Mj&C zV{lzeCQgGkvCN_)F^>A7FHf;h$C9y}XPY#|+VYZC^=4%q<$o61lVF=@Xx{1Md_7?Gi>~T{-_9%xIw4KYvlQ|Al0bTM2=)< z!Iw2Z-F>-2yg*^fBsJZDIC~PY)3ZCW-!T$x_z|rhpVjUc?1}b%K*aEiZ?l)yEO>#0 zX|nExg_*H2lLn=b$)e>^I4bpH2jh%eJ!0ukKX_+N2N1n|UpvPgQA`;KO%CJ;LVn<0-@L8E!dW9HP!?Ip*UFKKAjd@lqk|{Uy3dS@33W;xa&p5{x%;_pl zhqpbx_~DYhg`UNJ8sOb`sIpd)ZfLDYiNTI^-rIV&BFr~%h=fuCiL`MStTG!ABG0x3 z&foUmzGE9;tMFgcx-J%L)?M*emX}5EG@;Y}VNptFb@pd{#U6%EGe6aPd)eZ@AkZ?@ zJ3eWBG%=r?UC@X#$w{)$l77Q1B>}W`Jsgtt(nSikF+@w*VCP6J3A{fCSs^F2K_}D)!9Bh17=pD{fAv)p;pXEXgD;zm$ zjXLM=pKr|hrWKvOdz1IA#S8HwsqZX6GM58V9={*aP6px37Q){=)-YIdmlr|mUl)0+ z@EvKaMc(35fPTwN6qaP_lO`YGYDN*x_Z?JE~m)b3mcErf93b1#?Va~IC0HnF79Teq3OfRi5QUo3_H}j?v#l}Yh{-Mq|63AnQgrT5U zfG0;3YQQwHu^J0Dja_vvEahhTNb6ty#nHMp%ce9_2Kx2v)>^AC`+mLIVwTk) zMfyX%P2lgwwB1!v7zm!eJ+@Cf8f`JS%co0XyGLrxGXOZH48*Xk38LgbuW^9~D;?`k zj^2(6BcYe&aMrwL5;BI^Uu@Zwn(Je%hUS<~zB9EZSilj(C75c$9oOsrP=%>7NlzSx zA0cC-Alpz@9iXiPK_LR;vZE|ebp5l(>O7{;){$G{?WsJa-~^1qii10Te669E@43Yd zksuJw0z8+PTSnV=$w#$RZSuU&y2xvlfm)X{Hxsvk>j1k;5$#h5kU6pe z&RVE>W>iR3cPuPm1Qop{;+t<2es!LWRc-o}47qy%0An+F&09CSf&a>ZQ59 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 F{{eB~ibenc literal 0 HcmV?d00001 diff --git a/docs/assets/img/ccb_jhu_logo_tmp.png b/docs/assets/img/ccb_jhu_logo_tmp.png new file mode 100644 index 0000000000000000000000000000000000000000..783a88b3d1e96bd157ca42f8d3a5144493e2e2e3 GIT binary patch literal 13531 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 z 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%0Dp9aLEwC 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%0DLZ3-*xds$?7(eGsz%Si6c*&S}{=l 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⪻!*-H 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

    J8T^0yRfe5vEYO{gv0k}JR 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 r@X}<@#ei_t)Llit|eML7S8% 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 literal 0 HcmV?d00001 diff --git a/docs/assets/js/header-link.js b/docs/assets/js/header-link.js new file mode 100644 index 0000000..8d500fe --- /dev/null +++ b/docs/assets/js/header-link.js @@ -0,0 +1,8 @@ +$(function () { + $("h1, h2, h3, h4, h5, h6").each(function () { + var id = $(this).attr("id"); + if (id) { + $(this).append($("").addClass("header-link").attr("href", "#" + id).html('')); + } + }); +}); diff --git a/docs/assets/js/script.js b/docs/assets/js/script.js new file mode 100644 index 0000000..753da9b --- /dev/null +++ b/docs/assets/js/script.js @@ -0,0 +1,34 @@ +$(function () { + // focus on search input with '/' key. + $("body").on("keyup", function (e) { + e.stopPropagation(); + var slashKeys = [47, 111, 191]; + if (slashKeys.some(function (value) { return e.keyCode == value })) { + $("#search").focus(); + } + }); + + // add `target="_blank"` into all outer links. + var host = document.location.host; + $("a[href]").each(function() { + var re = new RegExp(host, "g"); + if ($(this).attr("href").match(/\/\//) && !$(this).attr("href").match(re)) { + $(this).attr("target", "_blank"); + } + }); + + // center and linkable all images. + var $images = $("article img:not(.emoji, .eye-catch)"); + $images.closest("p").css("text-align", "center"); + $images.each(function () { + var imgUrl = $(this).attr("src"); + var $a = $("").attr("href", imgUrl).attr("target", "_blank"); + $(this).wrap($a); + }); + + // stick aside. + var topSpacing = $(".site-aside").css("padding-top").replace(/px/, ""); + $(".site-aside .sticky").sticky({ + topSpacing: parseInt(topSpacing) + }); +}); diff --git a/docs/assets/js/search.js b/docs/assets/js/search.js new file mode 100644 index 0000000..47688e0 --- /dev/null +++ b/docs/assets/js/search.js @@ -0,0 +1,108 @@ +$(function () { + var query = getQuery(["q", "t", "a", "d"]); + + var targets; + switch (query.key) { + case "t": + targets = ["tags"]; + break; + case "a": + targets = ["author"]; + break; + case "d": + targets = ["date"]; + break; + case "q": + default: + targets = ["title", "tags", "author", "url", "date", "content"]; + break; + } + showPosts(query.words, targets); + + if (query.key == "q") { + $("#search").val(query.query).focus(); + } +}); + +function getQuery(keys) +{ + var query = ""; + var key = ""; + var words = []; + + keys.forEach(function (queryKey) { + var regex = RegExp("[?&]" + queryKey + "=([^&]+)", 'i'); + var matched; + if (matched = window.location.search.match(regex)) { + query = decodeURIComponent(matched[1]).replace(/( | |\+)+/g, ' '); + words = query.split(' '); + key = queryKey; + return false; // break; + } + return true; // continue; + }); + + return { query: query, key: key, words: words }; +} + +function showPosts(words, targets) +{ + var getJson = function () { + + var dfd = $.Deferred(); + $.ajax({ + url: baseurl + "/search.json", + dataType: "json", + timeout: 3000, // 3 sec + success: function (posts) { + var matchedPosts = []; + posts.forEach(function (post) { + + // concatenate target fields as a string. + var searchee = ""; + for (var i = 0; i < targets.length; i++) { + var target = post[targets[i]]; + var targetString = ""; + if (target instanceof Array) { + for (var j = 0; j < target.length; j++) { + targetString += target[j]; + } + } else if (typeof target == "object") { + for (key in target) { + targetString += target[key]; + } + } else { + targetString = target; + } + searchee += targetString; + } + + // matching. + var matched = true; + words.forEach(function (word) { + var regex = new RegExp(word, 'i'); + if (searchee.match(regex) == null) { + matched = false; + return false; // break; + } + return true; // continue; + }); + + if (matched) { + matchedPosts.push(post); + } + }); + + dfd.resolve(matchedPosts); + } + }); + + return dfd.promise(); + }; + + getJson().then(function (matchedPosts) { + matchedPosts.forEach(function (post) { + $("#search-results").find("#" + post.id).show(); + }); + }); +} diff --git a/docs/assets/lib/garand-sticky/jquery.sticky.js b/docs/assets/lib/garand-sticky/jquery.sticky.js new file mode 100644 index 0000000..7417c47 --- /dev/null +++ b/docs/assets/lib/garand-sticky/jquery.sticky.js @@ -0,0 +1,172 @@ +// Sticky Plugin v1.0.0 for jQuery +// ============= +// Author: Anthony Garand +// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk) +// Improvements by Leonardo C. Daronco (daronco) +// Created: 2/14/2011 +// Date: 2/12/2012 +// Website: http://labs.anthonygarand.com/sticky +// Description: Makes an element on the page stick on the screen as you scroll +// It will only set the 'top' and 'position' of your element, you +// might need to adjust the width in some cases. + +(function($) { + var defaults = { + topSpacing: 0, + bottomSpacing: 0, + className: 'is-sticky', + wrapperClassName: 'sticky-wrapper', + center: false, + getWidthFrom: '', + responsiveWidth: false + }, + $window = $(window), + $document = $(document), + sticked = [], + windowHeight = $window.height(), + scroller = function() { + var scrollTop = $window.scrollTop(), + documentHeight = $document.height(), + dwh = documentHeight - windowHeight, + extra = (scrollTop > dwh) ? dwh - scrollTop : 0; + + for (var i = 0; i < sticked.length; i++) { + var s = sticked[i], + elementTop = s.stickyWrapper.offset().top, + etse = elementTop - s.topSpacing - extra; + + if (scrollTop <= etse) { + if (s.currentTop !== null) { + s.stickyElement + .css('width', '') + .css('position', '') + .css('top', ''); + s.stickyElement.trigger('sticky-end', [s]).parent().removeClass(s.className); + s.currentTop = null; + } + } + else { + var newTop = documentHeight - s.stickyElement.outerHeight() + - s.topSpacing - s.bottomSpacing - scrollTop - extra; + if (newTop < 0) { + newTop = newTop + s.topSpacing; + } else { + newTop = s.topSpacing; + } + if (s.currentTop != newTop) { + s.stickyElement + .css('width', s.stickyElement.width()) + .css('position', 'fixed') + .css('top', newTop); + + if (typeof s.getWidthFrom !== 'undefined') { + s.stickyElement.css('width', $(s.getWidthFrom).width()); + } + + s.stickyElement.trigger('sticky-start', [s]).parent().addClass(s.className); + s.currentTop = newTop; + } + } + } + }, + resizer = function() { + windowHeight = $window.height(); + + for (var i = 0; i < sticked.length; i++) { + var s = sticked[i]; + if (typeof s.getWidthFrom !== 'undefined' && s.responsiveWidth === true) { + s.stickyElement.css('width', $(s.getWidthFrom).width()); + } + } + }, + methods = { + init: function(options) { + var o = $.extend({}, defaults, options); + return this.each(function() { + var stickyElement = $(this); + + var stickyId = stickyElement.attr('id'); + var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName + var wrapper = $('

    ') + .attr('id', stickyId + '-sticky-wrapper') + .addClass(o.wrapperClassName); + stickyElement.wrapAll(wrapper); + + if (o.center) { + stickyElement.parent().css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"}); + } + + if (stickyElement.css("float") == "right") { + stickyElement.css({"float":"none"}).parent().css({"float":"right"}); + } + + var stickyWrapper = stickyElement.parent(); + stickyWrapper.css('height', stickyElement.outerHeight()); + sticked.push({ + topSpacing: o.topSpacing, + bottomSpacing: o.bottomSpacing, + stickyElement: stickyElement, + currentTop: null, + stickyWrapper: stickyWrapper, + className: o.className, + getWidthFrom: o.getWidthFrom, + responsiveWidth: o.responsiveWidth + }); + }); + }, + update: scroller, + unstick: function(options) { + return this.each(function() { + var unstickyElement = $(this); + + var removeIdx = -1; + for (var i = 0; i < sticked.length; i++) + { + if (sticked[i].stickyElement.get(0) == unstickyElement.get(0)) + { + removeIdx = i; + } + } + if(removeIdx != -1) + { + sticked.splice(removeIdx,1); + unstickyElement.unwrap(); + unstickyElement.removeAttr('style'); + } + }); + } + }; + + // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer): + if (window.addEventListener) { + window.addEventListener('scroll', scroller, false); + window.addEventListener('resize', resizer, false); + } else if (window.attachEvent) { + window.attachEvent('onscroll', scroller); + window.attachEvent('onresize', resizer); + } + + $.fn.sticky = function(method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method ) { + return methods.init.apply( this, arguments ); + } else { + $.error('Method ' + method + ' does not exist on jQuery.sticky'); + } + }; + + $.fn.unstick = function(method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method ) { + return methods.unstick.apply( this, arguments ); + } else { + $.error('Method ' + method + ' does not exist on jQuery.sticky'); + } + + }; + $(function() { + setTimeout(scroller, 0); + }); +})(jQuery); diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..133f0ca35428bf551b9e37376997c1b681f44cad GIT binary patch literal 6518 zcmeH~KWrRD6vp>1XB|TKf7ixoz@b1XKnf)MM_{F(LQo?`fG`NCCGT zi=t9gj#{mVelFTQ6-C!YQ8YJ~jgu(4AKz|#q>$0|(?t>fVZU}eelCvVFB*+T$8wv^ zX1m=^KEnT$`SSWCNnVTNWP^5!_)eEIJ3W2XrW*V&JAco_zXI+zgsw(UrTbr<*cs#K zbdnEz5ZyNvo0@80U$55>G#bqnIIguEo@HOF)k^h^gJ*eFaq{*w>&;Ef^QBVhRJmN< zq@9K5Hp5q|)p>j;4QoBM-Vnz#Zzaj}CfE(8>0+(czSD4FU$3|C;5mLaJT<&Y``(Qo z2r=Q9=eW=1{{Y`vjhTbr$t{QZIpZ>zKZFsMb}qvo&&kbop>;gNp98<1+2@(dUAX|~ zr2cEb{FPzWSy%7KR?~ZOsktT^^Oi5H-jj_xozCkSs78OKBha{{v2rZm-Z4B&@@WlH z!!4w}L~M<9_MMvM2;adaP|&LsdD- z1#^%*?T_vLO03Dp;QPg|S@vmohWGdt^SNM8!tpo>=^pJR4l(qN;u${nTxMU6zG1{A z&LOgCI6KEy4a=GM8FTq8x{tu~JV{p!;t8MMIMg#2tKuGn&HS_Etr?E}{`8RizHpI# zR>K;A**?%eg9^|0xoK0!Ckly^wm>Z}Fo*Zz3eUG5L#G+)^B?$f(mF8hd1afG}!mNxOXZR~sI z`Wqy+tkV%?eOg6ap4)6`6Z_i6zUTcs&HR*rCQSXzDZ-euxIksp< zATDv{=p1DaEQfxLIr|^|xAeu8ry*_5%O~< z{tuTG3)ihUjL-Md^xV{Q*vDn_-VS6rRd^Q2Innher`b>6@{L|mlTGY&7CWI_aOpi= z99wyl!(Ll9m^K{8d@f`5NAf-`{a^26!)#$PY~TLIcT8HLepbWY?Pv|F#p2>ddvBh$ z`H1iTFKWoN_nS^pPYpMczixGp+lxz_MVeu(duGOmz+T#}zObynL*bqXwTi~wxrmqH yx;Sbb%0+kia-X@V4)%5e-vW1*CBNTP6METxOqP_R+#;??Y%&9r8JNs~X5er7V8d(x literal 0 HcmV?d00001 diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..a15e38d --- /dev/null +++ b/docs/index.html @@ -0,0 +1,14 @@ +--- +layout: default +--- + +{% assign pages = site.pages | where: "title", "Main" %} +
    +
    +
    + {{ pages[0].content }} +
    +
    +
    + + diff --git a/docs/search.json b/docs/search.json new file mode 100644 index 0000000..3070feb --- /dev/null +++ b/docs/search.json @@ -0,0 +1,16 @@ +--- +--- + +[ +{% for post in site.posts %} +{ +"id": {{ post.id | replace: '/', '-' | jsonify }}, +"title": {{ post.title | jsonify }}, +"author": {{ post.author | jsonify }}, +"tags": [{% for tag in post.tags%}{{ tag | jsonify }}{% unless forloop.last %}, {% endunless %}{% endfor %}], +"url": {{ post.url | jsonify }}, +"date": {{ post.date | date: '%Y-%m-%d' | jsonify }}, +"content": {{ post.content | strip_html | strip_newlines | jsonify }} +}{% unless forloop.last %}, {% endunless %} +{% endfor %} +] diff --git a/docs_jhu/README b/docs_jhu/README new file mode 100644 index 0000000..ed048dd --- /dev/null +++ b/docs_jhu/README @@ -0,0 +1,4 @@ +To populate this directory, change to the hisat2 directory and type +'make doc'. You must have pandoc installed: + + http://johnmacfarlane.net/pandoc/ diff --git a/docs_jhu/add.css b/docs_jhu/add.css new file mode 100644 index 0000000..849f79d --- /dev/null +++ b/docs_jhu/add.css @@ -0,0 +1,57 @@ +.pageStyle #leftside { + color: #666; +} + +.pageStyle #leftside a { + color: #0066B3; + text-decoration: none; +} + +.pageStyle #leftside h1 { + background: none; + margin: 0 0 10px; + padding: 10px 0; + font: bold 1.9em Arial,Verdana,sans-serif; +} + +.pageStyle #leftside h2 { + background: none; + margin: 0 0 10px; + padding: 10px 0; + font: bold 1.2em Arial,Verdana,sans-serif; +} +.pageStyle #leftside h3 { + background: none; + margin: 0 0 10px 5px; + padding: 10px 0; + font: 1.2em Arial,Verdana,sans-serif; +} + +.pageStyle #leftside table { + margin: 15px 0 0; +} + +.pageStyle #leftside td { + vertical-align: top; +} + +.pageStyle #leftside p { color:#444; } + + +.pageStyle #leftside td p { + margin-left:15px; +} + +.pageStyle #leftside h4 { + margin: 0px 15px 10px 10px; + padding: 10px 0px; + font: 1.1em Arial,Verdana,sans-serif; + background: none; +} + +.pageStyle #leftside ul { margin:0; padding-left:0; list-style-type: circle; } +.pageStyle #leftside #TOC ul { margin:0; padding-left:0; list-style-type: none; } +.pageStyle #leftside li { color:#444; margin-left:14px; } +.pageStyle #leftside #TOC li { margin-left:0; } +.pageStyle #leftside #TOC li li { margin-left:14px; } +.pageStyle #leftside p { padding: 0; margin:0 0 10px; } diff --git a/docs_jhu/faq.shtml b/docs_jhu/faq.shtml new file mode 100644 index 0000000..51ef428 --- /dev/null +++ b/docs_jhu/faq.shtml @@ -0,0 +1,45 @@ + + + + + +
    +
    +
    + +
    +
    +

    Frequently Asked Questions


    +
    +
      + + +
    +
    +
    +
    + + + + + + + + + diff --git a/docs_jhu/footer.inc.html b/docs_jhu/footer.inc.html new file mode 100644 index 0000000..8520a2d --- /dev/null +++ b/docs_jhu/footer.inc.html @@ -0,0 +1,7 @@ + diff --git a/docs_jhu/index.html b/docs_jhu/index.html new file mode 100644 index 0000000..23db360 --- /dev/null +++ b/docs_jhu/index.html @@ -0,0 +1,9 @@ + + + + HISAT2 (under construction) + + +

    + + diff --git a/docs_jhu/index.shtml b/docs_jhu/index.shtml new file mode 100644 index 0000000..07892a9 --- /dev/null +++ b/docs_jhu/index.shtml @@ -0,0 +1,154 @@ + + + + + +
    +
    + + + +
    +HISAT2 is a fast and sensitive alignment program for mapping next-generation sequencing reads (both DNA and RNA) to a population of human genomes (as well as to a single reference genome). Based on an extension of BWT for graphs [Sirén et al. 2014], we designed and implemented a graph FM index (GFM), an original approach and its first implementation to the best of our knowledge. In addition to using one global GFM index that represents a population of human genomes, HISAT2 uses a large set of small GFM indexes that collectively cover the whole genome (each index representing a genomic region of 56 Kbp, with 55,000 indexes needed to cover the human population). These small indexes (called local indexes), combined with several alignment strategies, enable rapid and accurate alignment of sequencing reads. This new indexing scheme is called a Hierarchical Graph FM index (HGFM). +
    +
    + Open Source Software +
    +
    +
    +
    + +
    +
    +

    HISAT2 2.1.0 release 6/8/2017

    +
    +
    + +

    HISAT2 2.0.5 release 11/4/2016

    + Version 2.0.5 is a minor release with the following changes. +
      +
    • Due to a policy change (HTTP to HTTPS) in using SRA data (`--sra-option`), users are strongly encouraged to use this version. As of 11/9/2016, NCBI will begin a permanent redirect to HTTPS, which means the previous versions of HISAT2 no longer works with `--sra-acc` option soon.
    • +
    • Implemented -I and -X options for specifying minimum and maximum fragment lengths. The options are valid only when used with --no-spliced-alignment, which is used for the alignment of DNA-seq reads.
    • +
    • Fixed some cases where reads with SNPs on their 5' ends were not properly aligned.
    • +
    • Implemented --no-softclip option to disable soft-clipping.
    • +
    • Implemented --max-seeds to specify the maximum number of seeds that HISAT2 will try to extend to full-length alignments (see the manual for details).
    • +
    +
    + +

    HISAT, StringTie and Ballgown protocol published at Nature Protocols 8/11/2016

    + +

    HISAT2 2.0.4 Windows binary available here, thanks to Andre Osorio Falcao 5/24/2016

    + +

    HISAT2 2.0.4 release 5/18/2016

    + Version 2.0.4 is a minor release with the following changes. +
      +
    • Improved template length estimation (the 9th column of the SAM format) of RNA-seq reads by taking introns into account.
    • +
    • Introduced two options, --remove-chrname and --add-chrname, to remove "chr" from reference names or add "chr" to reference names in the alignment output, respectively (the 3rd column of the SAM format).
    • +
    • Changed the maximum of mapping quality (the 5th column of the SAM format) from 255 to 60. Note that 255 is an undefined value according to the SAM manual and some programs would not work with this value (255) properly.
    • +
    • Fixed NH (number of hits) in the alignment output.
    • +
    • HISAT2 allows indels of any length pertaining to minimum alignment score (previously, the maximum length of indels was 3 bp).
    • +
    • Fixed several cases that alignment goes beyond reference sequences.
    • +
    • Fixed reporting duplicate alignments.
    • +
    +
    + +

    HISAT2 2.0.3-beta release 3/28/2016

    + Version 2.0.3-beta is a minor release with the following changes. +
      +
    • Fixed graph index building when using both SNPs and transcripts. As a result, genome_snp_tran indexes here on the HISAT2 website have been rebuilt.
    • +
    • Included some missing files needed to follow the small test example (see the manual for details).
    • +
    +
    + +

    HISAT2 2.0.2-beta release 3/17/2016

    + Note (3/19/2016): this version is slightly updated to handle reporting splice sites with the correct chromosome names.
    + Version 2.0.2-beta is a major release with the following changes. +
      +
    • Memory mappaped IO (--mm option) works now.
    • +
    • Building linear index can be now done using multi-threads.
    • +
    • Changed the minimum score for alignment in keeping with read lengths, so it's now --score-min L,0.0,-0.2, meaning a minimum score of -20 for 100-bp reads and -30 for 150-bp reads.
    • +
    • Fixed a bug that the same read was written into a file multiple times when --un-conc was used.
    • +
    • Fixed another bug that caused reads to map beyond reference sequences.
    • +
    • Introduced --haplotype option in the hisat2-build (index building), which is used with --snp option together to incorporate those SNP combinations present in the human population. This option also prevents graph construction from exploding due to exponential combinations of SNPs in small genomic regions.
    • +
    • Provided a new python script to extract SNPs and haplotypes from VCF files, hisat2_extract_snps_haplotypes_VCF.py
    • +
    • Changed several python script names as follows
    • +
        +
      1. extract_splice_sites.py to hisat2_extract_splice_sites.py
      2. +
      3. extract_exons.py to hisat2_extract_exons.py
      4. +
      5. extract_snps.py to hisat2_extract_snps_haplotypes_UCSC.py
      6. +
      +
    +
    + +

    HISAT2 2.0.1-beta release 11/19/2015

    + Version 2.0.1-beta is a maintenance release with the following changes. +
      +
    • Fixed a bug that caused reads to map beyond reference sequences.
    • +
    • Fixed a deadlock issue that happened very rarely.
    • +
    • Fixed a bug that led to illegal memory access when reading SNP information.
    • +
    • Fixed a system-specific bug related to popcount instruction.
    • +
    +
    +

    HISAT2 2.0.0-beta release 9/8/2015 - first release

    + We extended the BWT/FM index to incorporate genomic differences among individuals into the reference genome, while keeping memory requirements low enough to fit the entire index onto a desktop computer. Using this novel Hierarchical Graph FM index (HGFM) approach, we built a new alignment system, HISAT2, with an index that incorporates ~12.3M common SNPs from the dbSNP database. HISAT2 provides greater alignment accuracy for reads containing SNPs. +
      +
    • + HISAT2's index size for the human reference genome and 12.3 million common SNPs is 6.2GB (the memory footprint of HISAT2 is 6.7GB). The SNPs consist of 11 million single nucleotide polymorphisms, 728,000 deletions, and 555,000 insertions. The insertions and deletions used in this index are small (usually <20bp). +
    • +
    • + HISAT2 comes with several index types: +
        +
      1. Hierarchical FM index (HFM) for a reference genome (index base: genome)
      2. +
      3. Hierarchical Graph FM index (HGFM) for a reference genome plus SNPs (index base: genome_snp)
      4. +
      5. Hierarchical Graph FM index (HGFM) for a reference genome plus transcripts (index base: genome_tran)
      6. +
      7. Hierarchical Graph FM index (HGFM) for a reference genome plus SNPs and transcripts (index base: genome_snp_tran)
      8. +
      +
    • +
    • + HISAT2 is a successor to both HISAT and TopHat2. We recommend that HISAT and TopHat2 users switch to HISAT2. +
        +
      1. HISAT2 can be considered an enhanced version of HISAT with many improvements and bug fixes. The alignment speed and memory requirements of HISAT2 are virtually the same as those of HISAT when using the HFM index (genome).
      2. +
      3. When using graph-based indexes (HGFM), the runtime of HISAT2 is slightly slower than HISAT (30~80% additional CPU time). +
      4. HISAT2 allows for mapping reads directly against transcripts, similar to that of TopHat2 (use genome_tran or genome_snp_tran).
      5. +
      +
    • +
    • + When reads contain SNPs, the SNP information is provided as an optional field in the SAM output of HISAT2 (e.g., Zs:Z:1|S|rs3747203,97|S|rs16990981 - see the manual for details). This feature enables fast and sensitive genotyping in downstream analyses. Note that there is no alignment penalty for mismatches, insertions, and deletions if they correspond to known SNPs. +
    • +
    • + HISAT2 provides options for transcript assemblers (e.g., StringTie and Cufflinks) to work better with the alignment from HISAT2 (see options such as --dta and --dta-cufflinks). +
    • +
    • + Some slides about HISAT2 are found here and we are preparing detailed documention. +
    • +
    • + We plan to incorporate a larger set of SNPs and structural variations (SV) into this index (e.g., long insertions/deletions, inversions, and translocations). +
    • +
    +
    +

    The HISAT2 source code is available in a public GitHub repository (5/30/2015).

    +
    +
    +
    + + + + + + + + + diff --git a/docs_jhu/indexes.txt b/docs_jhu/indexes.txt new file mode 100644 index 0000000..727288e --- /dev/null +++ b/docs_jhu/indexes.txt @@ -0,0 +1,5 @@ +Each of the HISAT2 indexes available here on the website comes with a shell script (e.g. make_grch38.sh) that provides instructions (or shell commands) for downloading a reference sequence, gene annotations, and SNPs, and building a HISAT2 index. You can use the script to build the same HISAT2 index we provide. + +HISAT2 indexes named genome_tran or genome_snp_tran use Ensembl gene annotations, which include many more transcripts than RefSeq annotations, due to the inclusion of annotations as predicted by software. + +The HISAT2 indexes for the human genome include only primary assembly. If you choose to include alternative sequences introduced in GRCh38 and build your own HISAT2 indexes, then please be aware that those alternative sequences are nearly identical to the primary assembly in GRCh38 and as a result some reads may map to many more locations compared to when using the primary assembly only. HISAT2 often skips those multi-mapped reads if the number of potential locations is more than the value specified by the -k option. You may want to use a higher value for the -k option to resolve the issue. diff --git a/docs_jhu/manual.inc.html b/docs_jhu/manual.inc.html new file mode 100644 index 0000000..13b48dc --- /dev/null +++ b/docs_jhu/manual.inc.html @@ -0,0 +1,1262 @@ + + + +

    Introduction

    +

    What is HISAT2?

    +

    HISAT2 is a fast and sensitive alignment program for mapping next-generation sequencing reads (whole-genome, transcriptome, and exome sequencing data) against the general human population (as well as against a single reference genome). Based on GCSA (an extension of BWT for a graph), we designed and implemented a graph FM index (GFM), an original approach and its first implementation to the best of our knowledge. In addition to using one global GFM index that represents general population, HISAT2 uses a large set of small GFM indexes that collectively cover the whole genome (each index representing a genomic region of 56 Kbp, with 55,000 indexes needed to cover human population). These small indexes (called local indexes) combined with several alignment strategies enable effective alignment of sequencing reads. This new indexing scheme is called Hierarchical Graph FM index (HGFM). We have developed HISAT 2 based on the HISAT and Bowtie2 implementations. HISAT2 outputs alignments in SAM format, enabling interoperation with a large number of other tools (e.g. SAMtools, GATK) that use SAM. HISAT2 is distributed under the GPLv3 license, and it runs on the command line under Linux, Mac OS X and Windows.

    +

    Obtaining HISAT2

    +

    Download HISAT2 sources and binaries from the Releases sections on the right side. Binaries are available for Intel architectures (x86_64) running Linux, and Mac OS X.

    +

    Building from source

    +

    Building HISAT2 from source requires a GNU-like environment with GCC, GNU Make and other basics. It should be possible to build HISAT2 on most vanilla Linux installations or on a Mac installation with Xcode installed. HISAT2 can also be built on Windows using Cygwin or MinGW (MinGW recommended). For a MinGW build the choice of what compiler is to be used is important since this will determine if a 32 or 64 bit code can be successfully compiled using it. If there is a need to generate both 32 and 64 bit on the same machine then a multilib MinGW has to be properly installed. MSYS, the zlib library, and depending on architecture pthreads library are also required. We are recommending a 64 bit build since it has some clear advantages in real life research problems. In order to simplify the MinGW setup it might be worth investigating popular MinGW personal builds since these are coming already prepared with most of the toolchains needed.

    +

    First, download the source package from the Releases section on the right side. Unzip the file, change to the unzipped directory, and build the HISAT2 tools by running GNU make (usually with the command make, but sometimes with gmake) with no arguments. If building with MinGW, run make from the MSYS environment.

    +

    HISAT2 is using the multithreading software model in order to speed up execution times on SMP architectures where this is possible. On POSIX platforms (like linux, Mac OS, etc) it needs the pthread library. Although it is possible to use pthread library on non-POSIX platform like Windows, due to performance reasons HISAT2 will try to use Windows native multithreading if possible.

    +

    For the support of SRA data access in HISAT2, please download and install the NCBI-NGS toolkit. When running make, specify additional variables as follow. make USE_SRA=1 NCBI_NGS_DIR=/path/to/NCBI-NGS-directory NCBI_VDB_DIR=/path/to/NCBI-NGS-directory, where NCBI_NGS_DIR and NCBI_VDB_DIR will be used in Makefile for -I and -L compilation options. For example, $(NCBI_NGS_DIR)/include and $(NCBI_NGS_DIR)/lib64 will be used.

    +

    Running HISAT2

    +

    Adding to PATH

    +

    By adding your new HISAT2 directory to your PATH environment variable, you ensure that whenever you run hisat2, hisat2-build or hisat2-inspect from the command line, you will get the version you just installed without having to specify the entire path. This is recommended for most users. To do this, follow your operating system's instructions for adding the directory to your PATH.

    +

    If you would like to install HISAT2 by copying the HISAT2 executable files to an existing directory in your PATH, make sure that you copy all the executables, including hisat2, hisat2-align-s, hisat2-align-l, hisat2-build, hisat2-build-s, hisat2-build-l, hisat2-inspect, hisat2-inspect-s and hisat2-inspect-l.

    +

    Reporting

    +

    The reporting mode governs how many alignments HISAT2 looks for, and how to report them.

    +

    In general, when we say that a read has an alignment, we mean that it has a valid alignment. When we say that a read has multiple alignments, we mean that it has multiple alignments that are valid and distinct from one another.

    +

    By default, HISAT2 may soft-clip reads near their 5' and 3' ends. Users can control this behavior by setting different penalties for soft-clipping (--sp) or by disallowing soft-clipping ([--no-softclip]).

    +

    Distinct alignments map a read to different places

    +

    Two alignments for the same individual read are "distinct" if they map the same read to different places. Specifically, we say that two alignments are distinct if there are no alignment positions where a particular read offset is aligned opposite a particular reference offset in both alignments with the same orientation. E.g. if the first alignment is in the forward orientation and aligns the read character at read offset 10 to the reference character at chromosome 3, offset 3,445,245, and the second alignment is also in the forward orientation and also aligns the read character at read offset 10 to the reference character at chromosome 3, offset 3,445,245, they are not distinct alignments.

    +

    Two alignments for the same pair are distinct if either the mate 1s in the two paired-end alignments are distinct or the mate 2s in the two alignments are distinct or both.

    +

    Default mode: search for one or more alignments, report each

    +

    HISAT2 searches for up to N distinct, primary alignments for each read, where N equals the integer specified with the -k parameter. Primary alignments mean alignments whose alignment score is equal or higher than any other alignments. It is possible that multiple distinct alignments have the same score. That is, if -k 2 is specified, HISAT2 will search for at most 2 distinct alignments. The alignment score for a paired-end alignment equals the sum of the alignment scores of the individual mates. Each reported read or pair alignment beyond the first has the SAM 'secondary' bit (which equals 256) set in its FLAGS field. See the SAM specification for details.

    +

    HISAT2 does not "find" alignments in any specific order, so for reads that have more than N distinct, valid alignments, HISAT2 does not guarantee that the N alignments reported are the best possible in terms of alignment score. Still, this mode can be effective and fast in situations where the user cares more about whether a read aligns (or aligns a certain number of times) than where exactly it originated.

    +

    Alignment summary

    +

    When HISAT2 finishes running, it prints messages summarizing what happened. These messages are printed to the "standard error" ("stderr") filehandle. For datasets consisting of unpaired reads, the summary might look like this:

    +
    20000 reads; of these:
    +  20000 (100.00%) were unpaired; of these:
    +    1247 (6.24%) aligned 0 times
    +    18739 (93.69%) aligned exactly 1 time
    +    14 (0.07%) aligned >1 times
    +93.77% overall alignment rate
    +

    For datasets consisting of pairs, the summary might look like this:

    +
    10000 reads; of these:
    +  10000 (100.00%) were paired; of these:
    +    650 (6.50%) aligned concordantly 0 times
    +    8823 (88.23%) aligned concordantly exactly 1 time
    +    527 (5.27%) aligned concordantly >1 times
    +    ----
    +    650 pairs aligned concordantly 0 times; of these:
    +      34 (5.23%) aligned discordantly 1 time
    +    ----
    +    616 pairs aligned 0 times concordantly or discordantly; of these:
    +      1232 mates make up the pairs; of these:
    +        660 (53.57%) aligned 0 times
    +        571 (46.35%) aligned exactly 1 time
    +        1 (0.08%) aligned >1 times
    +96.70% overall alignment rate
    +

    The indentation indicates how subtotals relate to totals.

    +

    Wrapper

    +

    The hisat2, hisat2-build and hisat2-inspect executables are actually wrapper scripts that call binary programs as appropriate. The wrappers shield users from having to distinguish between "small" and "large" index formats, discussed briefly in the following section. Also, the hisat2 wrapper provides some key functionality, like the ability to handle compressed inputs, and the functionality for --un, --al and related options.

    +

    It is recommended that you always run the hisat2 wrappers and not run the binaries directly.

    +

    Small and large indexes

    +

    hisat2-build can index reference genomes of any size. For genomes less than about 4 billion nucleotides in length, hisat2-build builds a "small" index using 32-bit numbers in various parts of the index. When the genome is longer, hisat2-build builds a "large" index using 64-bit numbers. Small indexes are stored in files with the .ht2 extension, and large indexes are stored in files with the .ht2l extension. The user need not worry about whether a particular index is small or large; the wrapper scripts will automatically build and use the appropriate index.

    +

    Performance tuning

    +
      +
    1. If your computer has multiple processors/cores, use -p

      +

      The -p option causes HISAT2 to launch a specified number of parallel search threads. Each thread runs on a different processor/core and all threads find alignments in parallel, increasing alignment throughput by approximately a multiple of the number of threads (though in practice, speedup is somewhat worse than linear).

    2. +
    +

    Command Line

    +

    Setting function options

    +

    Some HISAT2 options specify a function rather than an individual number or setting. In these cases the user specifies three parameters: (a) a function type F, (b) a constant term B, and (c) a coefficient A. The available function types are constant (C), linear (L), square-root (S), and natural log (G). The parameters are specified as F,B,A - that is, the function type, the constant term, and the coefficient are separated by commas with no whitespace. The constant term and coefficient may be negative and/or floating-point numbers.

    +

    For example, if the function specification is L,-0.4,-0.6, then the function defined is:

    +
    f(x) = -0.4 + -0.6 * x
    +

    If the function specification is G,1,5.4, then the function defined is:

    +
    f(x) = 1.0 + 5.4 * ln(x)
    +

    See the documentation for the option in question to learn what the parameter x is for. For example, in the case if the --score-min option, the function f(x) sets the minimum alignment score necessary for an alignment to be considered valid, and x is the read length.

    +

    Usage

    +
    hisat2 [options]* -x <hisat2-idx> {-1 <m1> -2 <m2> | -U <r> | --sra-acc <SRA accession number>} [-S <hit>]
    +

    Main arguments

    +
    + +
    -x <hisat2-idx>
    +
    + +

    The basename of the index for the reference genome. The basename is the name of any of the index files up to but not including the final .1.ht2 / etc. hisat2 looks for the specified index first in the current directory, then in the directory specified in the HISAT2_INDEXES environment variable.

    +
    + +
    -1 <m1>
    +
    + +

    Comma-separated list of files containing mate 1s (filename usually includes _1), e.g. -1 flyA_1.fq,flyB_1.fq. Sequences specified with this option must correspond file-for-file and read-for-read with those specified in <m2>. Reads may be a mix of different lengths. If - is specified, hisat2 will read the mate 1s from the "standard in" or "stdin" filehandle.

    +
    + +
    -2 <m2>
    +
    + +

    Comma-separated list of files containing mate 2s (filename usually includes _2), e.g. -2 flyA_2.fq,flyB_2.fq. Sequences specified with this option must correspond file-for-file and read-for-read with those specified in <m1>. Reads may be a mix of different lengths. If - is specified, hisat2 will read the mate 2s from the "standard in" or "stdin" filehandle.

    +
    + +
    -U <r>
    +
    + +

    Comma-separated list of files containing unpaired reads to be aligned, e.g. lane1.fq,lane2.fq,lane3.fq,lane4.fq. Reads may be a mix of different lengths. If - is specified, hisat2 gets the reads from the "standard in" or "stdin" filehandle.

    +
    + +
    --sra-acc <SRA accession number>
    +
    + +

    Comma-separated list of SRA accession numbers, e.g. --sra-acc SRR353653,SRR353654. Information about read types is available at http://trace.ncbi.nlm.nih.gov/Traces/sra/sra.cgi?sp=runinfo&acc=sra-acc&retmode=xml, where sra-acc is SRA accession number. If users run HISAT2 on a computer cluster, it is recommended to disable SRA-related caching (see the instruction at SRA-MANUAL).

    +
    + +
    -S <hit>
    +
    + +

    File to write SAM alignments to. By default, alignments are written to the "standard out" or "stdout" filehandle (i.e. the console).

    +
    + +

    Options

    +

    Input options

    + + + + + + + + + + + + +
    + +
    -q
    +
    + +

    Reads (specified with <m1>, <m2>, <s>) are FASTQ files. FASTQ files usually have extension .fq or .fastq. FASTQ is the default format. See also: --solexa-quals and --int-quals.

    +
    + +
    --qseq
    +
    + +

    Reads (specified with <m1>, <m2>, <s>) are QSEQ files. QSEQ files usually end in _qseq.txt. See also: --solexa-quals and --int-quals.

    +
    + +
    -f
    +
    + +

    Reads (specified with <m1>, <m2>, <s>) are FASTA files. FASTA files usually have extension .fa, .fasta, .mfa, .fna or similar. FASTA files do not have a way of specifying quality values, so when -f is set, the result is as if --ignore-quals is also set.

    +
    + +
    -r
    +
    + +

    Reads (specified with <m1>, <m2>, <s>) are files with one input sequence per line, without any other information (no read names, no qualities). When -r is set, the result is as if --ignore-quals is also set.

    +
    + +
    -c
    +
    + +

    The read sequences are given on command line. I.e. <m1>, <m2> and <singles> are comma-separated lists of reads rather than lists of read files. There is no way to specify read names or qualities, so -c also implies --ignore-quals.

    +
    + +
    -s/--skip <int>
    +
    + +

    Skip (i.e. do not align) the first <int> reads or pairs in the input.

    +
    + +
    -u/--qupto <int>
    +
    + +

    Align the first <int> reads or read pairs from the input (after the -s/--skip reads or pairs have been skipped), then stop. Default: no limit.

    +
    + +
    -5/--trim5 <int>
    +
    + +

    Trim <int> bases from 5' (left) end of each read before alignment (default: 0).

    +
    + +
    -3/--trim3 <int>
    +
    + +

    Trim <int> bases from 3' (right) end of each read before alignment (default: 0).

    +
    + +
    --phred33
    +
    + +

    Input qualities are ASCII chars equal to the Phred quality plus 33. This is also called the "Phred+33" encoding, which is used by the very latest Illumina pipelines.

    +
    + +
    --phred64
    +
    + +

    Input qualities are ASCII chars equal to the Phred quality plus 64. This is also called the "Phred+64" encoding.

    +
    + +
    --solexa-quals
    +
    + +

    Convert input qualities from Solexa (which can be negative) to Phred (which can't). This scheme was used in older Illumina GA Pipeline versions (prior to 1.3). Default: off.

    +
    + +
    --int-quals
    +
    + +

    Quality values are represented in the read input file as space-separated ASCII integers, e.g., 40 40 30 40..., rather than ASCII characters, e.g., II?I.... Integers are treated as being on the Phred quality scale unless --solexa-quals is also specified. Default: off.

    +
    + +

    Alignment options

    + + + + + + + +
    + +
    --n-ceil <func>
    +
    + +

    Sets a function governing the maximum number of ambiguous characters (usually Ns and/or .s) allowed in a read as a function of read length. For instance, specifying -L,0,0.15 sets the N-ceiling function f to f(x) = 0 + 0.15 * x, where x is the read length. See also: [setting function options]. Reads exceeding this ceiling are filtered out. Default: L,0,0.15.

    +
    + +
    --ignore-quals
    +
    + +

    When calculating a mismatch penalty, always consider the quality value at the mismatched position to be the highest possible, regardless of the actual value. I.e. input is treated as though all quality values are high. This is also the default behavior when the input doesn't specify quality values (e.g. in -f, -r, or -c modes).

    +
    + +
    --nofw/--norc
    +
    + +

    If --nofw is specified, hisat2 will not attempt to align unpaired reads to the forward (Watson) reference strand. If --norc is specified, hisat2 will not attempt to align unpaired reads against the reverse-complement (Crick) reference strand. In paired-end mode, --nofw and --norc pertain to the fragments; i.e. specifying --nofw causes hisat2 to explore only those paired-end configurations corresponding to fragments from the reverse-complement (Crick) strand. Default: both strands enabled.

    +
    + +

    Scoring options

    + + + + + + + + + + +
    + +
    --mp MX,MN
    +
    + +

    Sets the maximum (MX) and minimum (MN) mismatch penalties, both integers. A number less than or equal to MX and greater than or equal to MN is subtracted from the alignment score for each position where a read character aligns to a reference character, the characters do not match, and neither is an N. If --ignore-quals is specified, the number subtracted quals MX. Otherwise, the number subtracted is MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) ) where Q is the Phred quality value. Default: MX = 6, MN = 2.

    +
    + +
    --sp MX,MN
    +
    + +

    Sets the maximum (MX) and minimum (MN) penalties for soft-clipping per base, both integers. A number less than or equal to MX and greater than or equal to MN is subtracted from the alignment score for each position. The number subtracted is MN + floor( (MX-MN)(MIN(Q, 40.0)/40.0) ) where Q is the Phred quality value. Default: MX = 2, MN = 1.

    +
    + +
    --no-softclip
    +
    + +

    Disallow soft-clipping.

    +
    + +
    --np <int>
    +
    + +

    Sets penalty for positions where the read, reference, or both, contain an ambiguous character such as N. Default: 1.

    +
    + +
    --rdg <int1>,<int2>
    +
    + +

    Sets the read gap open (<int1>) and extend (<int2>) penalties. A read gap of length N gets a penalty of <int1> + N * <int2>. Default: 5, 3.

    +
    + +
    --rfg <int1>,<int2>
    +
    + +

    Sets the reference gap open (<int1>) and extend (<int2>) penalties. A reference gap of length N gets a penalty of <int1> + N * <int2>. Default: 5, 3.

    +
    + +
    --score-min <func>
    +
    + +

    Sets a function governing the minimum alignment score needed for an alignment to be considered "valid" (i.e. good enough to report). This is a function of read length. For instance, specifying L,0,-0.6 sets the minimum-score function f to f(x) = 0 + -0.6 * x, where x is the read length. See also: [setting function options]. The default is L,0,-0.2.

    +
    + +

    Spliced alignment options

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    --pen-cansplice <int>
    +
    + +

    Sets the penalty for each pair of canonical splice sites (e.g. GT/AG). Default: 0.

    +
    + +
    --pen-noncansplice <int>
    +
    + +

    Sets the penalty for each pair of non-canonical splice sites (e.g. non-GT/AG). Default: 12.

    +
    + +
    --pen-canintronlen <func>
    +
    + +

    Sets the penalty for long introns with canonical splice sites so that alignments with shorter introns are preferred to those with longer ones. Default: G,-8,1

    +
    + +
    --pen-noncanintronlen <func>
    +
    + +

    Sets the penalty for long introns with noncanonical splice sites so that alignments with shorter introns are preferred to those with longer ones. Default: G,-8,1

    +
    + +
    --min-intronlen <int>
    +
    + +

    Sets minimum intron length. Default: 20

    +
    + +
    --max-intronlen <int>
    +
    + +

    Sets maximum intron length. Default: 500000

    +
    + +
    --known-splicesite-infile <path>
    +
    + +

    With this mode, you can provide a list of known splice sites, which HISAT2 makes use of to align reads with small anchors.
    You can create such a list using python hisat2_extract_splice_sites.py genes.gtf > splicesites.txt, where hisat2_extract_splice_sites.py is included in the HISAT2 package, genes.gtf is a gene annotation file, and splicesites.txt is a list of splice sites with which you provide HISAT2 in this mode. Note that it is better to use indexes built using annotated transcripts (such as genome_tran or genome_snp_tran), which works better than using this option. It has no effect to provide splice sites that are already included in the indexes.

    +
    + +
    --novel-splicesite-outfile <path>
    +
    + +

    In this mode, HISAT2 reports a list of splice sites in the file :
    chromosome name <tab> genomic position of the flanking base on the left side of an intron <tab> genomic position of the flanking base on the right <tab> strand (+, -, and .) '.' indicates an unknown strand for non-canonical splice sites.

    +
    + +
    --novel-splicesite-infile <path>
    +
    + +

    With this mode, you can provide a list of novel splice sites that were generated from the above option "--novel-splicesite-outfile".

    +
    + +
    --no-temp-splicesite
    +
    + +

    HISAT2, by default, makes use of splice sites found by earlier reads to align later reads in the same run, in particular, reads with small anchors (<= 15 bp).
    The option disables this default alignment strategy.

    +
    + +
    --no-spliced-alignment
    +
    + +

    Disable spliced alignment.

    +
    +
    --rna-strandness <string>
    +
    + +

    Specify strand-specific information: the default is unstranded.
    For single-end reads, use F or R. 'F' means a read corresponds to a transcript. 'R' means a read corresponds to the reverse complemented counterpart of a transcript. For paired-end reads, use either FR or RF.
    With this option being used, every read alignment will have an XS attribute tag: '+' means a read belongs to a transcript on '+' strand of genome. '-' means a read belongs to a transcript on '-' strand of genome.

    +(TopHat has a similar option, --library-type option, where fr-firststrand corresponds to R and RF; fr-secondstrand corresponds to F and FR.) +
    +
    --tmo/--transcriptome-mapping-only
    +
    + +

    Report only those alignments within known transcripts.

    +
    +
    --dta/--downstream-transcriptome-assembly
    +
    + +

    Report alignments tailored for transcript assemblers including StringTie. With this option, HISAT2 requires longer anchor lengths for de novo discovery of splice sites. This leads to fewer alignments with short-anchors, which helps transcript assemblers improve significantly in computation and memory usage.

    +
    + +

    Report alignments tailored specifically for Cufflinks. In addition to what HISAT2 does with the above option (--dta), With this option, HISAT2 looks for novel splice sites with three signals (GT/AG, GC/AG, AT/AC), but all user-provided splice sites are used irrespective of their signals. HISAT2 produces an optional field, XS:A:[+-], for every spliced alignment.

    +
    +
    --no-templatelen-adjustment
    +
    + +

    Disables template length adjustment for RNA-seq reads.

    +
    + +

    Reporting options

    + + + + + + + +
    + +
    -k <int>
    +
    + +

    It searches for at most <int> distinct, primary alignments for each read. Primary alignments mean alignments whose alignment score is equal or higher than any other alignments. The search terminates when it can't find more distinct valid alignments, or when it finds <int>, whichever happens first. The alignment score for a paired-end alignment equals the sum of the alignment scores of the individual mates. Each reported read or pair alignment beyond the first has the SAM 'secondary' bit (which equals 256) set in its FLAGS field. For reads that have more than <int> distinct, valid alignments, hisat2 does not guarantee that the <int> alignments reported are the best possible in terms of alignment score. Default: 5 (HFM) or 10 (HGFM)

    +

    Note: HISAT2 is not designed with large values for -k in mind, and when aligning reads to long, repetitive genomes large -k can be very, very slow.

    +
    + +
    --max-seeds <int>
    +
    + +

    HISAT2, like other aligners, uses seed-and-extend approaches. HISAT2 tries to extend seeds to full-length alignments. In HISAT2, --max-seeds is used to control the maximum number of seeds that will be extended. HISAT2 extends up to these many seeds and skips the rest of the seeds. Large values for --max-seeds may improve alignment sensitivity, but HISAT2 is not designed with large values for --max-seeds in mind, and when aligning reads to long, repetitive genomes large --max-seeds can be very, very slow. The default value is the maximum of 5 and the value that comes with-k.

    +
    + +
    --secondary
    +
    + +

    Report secondary alignments.

    +
    + +

    Paired-end options

    + + + + + + +
    + +
    -I/--minins <int>
    +
    + +

    The minimum fragment length for valid paired-end alignments.This option is valid only with --no-spliced-alignment. E.g. if -I 60 is specified and a paired-end alignment consists of two 20-bp alignments in the appropriate orientation with a 20-bp gap between them, that alignment is considered valid (as long as -X is also satisfied). A 19-bp gap would not be valid in that case. If trimming options -3 or -5 are also used, the -I constraint is applied with respect to the untrimmed mates.

    +

    The larger the difference between -I and -X, the slower HISAT2 will run. This is because larger differences between -I and -X require that HISAT2 scan a larger window to determine if a concordant alignment exists. For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very efficient.

    +

    Default: 0 (essentially imposing no minimum)

    +
    + +
    -X/--maxins <int>
    +
    + +

    The maximum fragment length for valid paired-end alignments. This option is valid only with --no-spliced-alignment. E.g. if -X 100 is specified and a paired-end alignment consists of two 20-bp alignments in the proper orientation with a 60-bp gap between them, that alignment is considered valid (as long as -I is also satisfied). A 61-bp gap would not be valid in that case. If trimming options -3 or -5 are also used, the -X constraint is applied with respect to the untrimmed mates, not the trimmed mates.

    +

    The larger the difference between -I and -X, the slower HISAT2 will run. This is because larger differences between -I and -X require that HISAT2 scan a larger window to determine if a concordant alignment exists. For typical fragment length ranges (200 to 400 nucleotides), HISAT2 is very efficient.

    +

    Default: 500.

    +
    + +
    --fr/--rf/--ff
    +
    + +

    The upstream/downstream mate orientations for a valid paired-end alignment against the forward reference strand. E.g., if --fr is specified and there is a candidate paired-end alignment where mate 1 appears upstream of the reverse complement of mate 2 and the fragment length constraints (-I and -X) are met, that alignment is valid. Also, if mate 2 appears upstream of the reverse complement of mate 1 and all other constraints are met, that too is valid. --rf likewise requires that an upstream mate1 be reverse-complemented and a downstream mate2 be forward-oriented. --ff requires both an upstream mate 1 and a downstream mate 2 to be forward-oriented. Default: --fr (appropriate for Illumina's Paired-end Sequencing Assay).

    +
    + +
    --no-mixed
    +
    + +

    By default, when hisat2 cannot find a concordant or discordant alignment for a pair, it then tries to find alignments for the individual mates. This option disables that behavior.

    +
    + +
    --no-discordant
    +
    + +

    By default, hisat2 looks for discordant alignments if it cannot find any concordant alignments. A discordant alignment is an alignment where both mates align uniquely, but that does not satisfy the paired-end constraints (--fr/--rf/--ff, -I, -X). This option disables that behavior.

    +
    + +

    Output options

    + + + + + + + + + + + + + + + + +
    + +
    -t/--time
    +
    + +

    Print the wall-clock time required to load the index files and align the reads. This is printed to the "standard error" ("stderr") filehandle. Default: off.

    +
    + +
    --un <path>
    +--un-gz <path>
    +--un-bz2 <path>
    +
    + +

    Write unpaired reads that fail to align to file at <path>. These reads correspond to the SAM records with the FLAGS 0x4 bit set and neither the 0x40 nor 0x80 bits set. If --un-gz is specified, output will be gzip compressed. If --un-bz2 is specified, output will be bzip2 compressed. Reads written in this way will appear exactly as they did in the input file, without any modification (same sequence, same name, same quality string, same quality encoding). Reads will not necessarily appear in the same order as they did in the input.

    +
    + +
    --al <path>
    +--al-gz <path>
    +--al-bz2 <path>
    +
    + +

    Write unpaired reads that align at least once to file at <path>. These reads correspond to the SAM records with the FLAGS 0x4, 0x40, and 0x80 bits unset. If --al-gz is specified, output will be gzip compressed. If --al-bz2 is specified, output will be bzip2 compressed. Reads written in this way will appear exactly as they did in the input file, without any modification (same sequence, same name, same quality string, same quality encoding). Reads will not necessarily appear in the same order as they did in the input.

    +
    + +
    --un-conc <path>
    +--un-conc-gz <path>
    +--un-conc-bz2 <path>
    +
    + +

    Write paired-end reads that fail to align concordantly to file(s) at <path>. These reads correspond to the SAM records with the FLAGS 0x4 bit set and either the 0x40 or 0x80 bit set (depending on whether it's mate #1 or #2). .1 and .2 strings are added to the filename to distinguish which file contains mate #1 and mate #2. If a percent symbol, %, is used in <path>, the percent symbol is replaced with 1 or 2 to make the per-mate filenames. Otherwise, .1 or .2 are added before the final dot in <path> to make the per-mate filenames. Reads written in this way will appear exactly as they did in the input files, without any modification (same sequence, same name, same quality string, same quality encoding). Reads will not necessarily appear in the same order as they did in the inputs.

    +
    + +
    --al-conc <path>
    +--al-conc-gz <path>
    +--al-conc-bz2 <path>
    +
    + +

    Write paired-end reads that align concordantly at least once to file(s) at <path>. These reads correspond to the SAM records with the FLAGS 0x4 bit unset and either the 0x40 or 0x80 bit set (depending on whether it's mate #1 or #2). .1 and .2 strings are added to the filename to distinguish which file contains mate #1 and mate #2. If a percent symbol, %, is used in <path>, the percent symbol is replaced with 1 or 2 to make the per-mate filenames. Otherwise, .1 or .2 are added before the final dot in <path> to make the per-mate filenames. Reads written in this way will appear exactly as they did in the input files, without any modification (same sequence, same name, same quality string, same quality encoding). Reads will not necessarily appear in the same order as they did in the inputs.

    +
    + +
    --quiet
    +
    + +

    Print nothing besides alignments and serious errors.

    +
    + +
    --summary-file
    +
    + +

    Print alignment summary to this file.

    +
    + +
    --new-summary
    +
    + +

    Print alignment summary in a new style, which is more machine-friendly.

    +
    + +
    --met-file <path>
    +
    + +

    Write hisat2 metrics to file <path>. Having alignment metric can be useful for debugging certain problems, especially performance issues. See also: --met. Default: metrics disabled.

    +
    + +
    --met-stderr
    +
    + +

    Write hisat2 metrics to the "standard error" ("stderr") filehandle. This is not mutually exclusive with --met-file. Having alignment metric can be useful for debugging certain problems, especially performance issues. See also: --met. Default: metrics disabled.

    +
    + +
    --met <int>
    +
    + +

    Write a new hisat2 metrics record every <int> seconds. Only matters if either --met-stderr or --met-file are specified. Default: 1.

    +
    + +

    SAM options

    + + + + + + + + + + + + +
    + +
    --no-unal
    +
    + +

    Suppress SAM records for reads that failed to align.

    +
    + +
    --no-hd
    +
    + +

    Suppress SAM header lines (starting with @).

    +
    + +
    --no-sq
    +
    + +

    Suppress @SQ SAM header lines.

    +
    + +
    --rg-id <text>
    +
    + +

    Set the read group ID to <text>. This causes the SAM @RG header line to be printed, with <text> as the value associated with the ID: tag. It also causes the RG:Z: extra field to be attached to each SAM output record, with value set to <text>.

    +
    + +
    --rg <text>
    +
    + +

    Add <text> (usually of the form TAG:VAL, e.g. SM:Pool1) as a field on the @RG header line. Note: in order for the @RG line to appear, --rg-id must also be specified. This is because the ID tag is required by the SAM Spec. Specify --rg multiple times to set multiple fields. See the SAM Spec for details about what fields are legal.

    +
    + +
    --remove-chrname
    +
    + +

    Remove 'chr' from reference names in alignment (e.g., chr18 to 18)

    +
    + +
    --add-chrname
    +
    + +

    Add 'chr' to reference names in alignment (e.g., 18 to chr18)

    +
    + +
    --omit-sec-seq
    +
    + +

    When printing secondary alignments, HISAT2 by default will write out the SEQ and QUAL strings. Specifying this option causes HISAT2 to print an asterisk in those fields instead.

    +
    + +

    Performance options

    + + + + + +
    + +
    -o/--offrate <int>
    +
    + +

    Override the offrate of the index with <int>. If <int> is greater than the offrate used to build the index, then some row markings are discarded when the index is read into memory. This reduces the memory footprint of the aligner but requires more time to calculate text offsets. <int> must be greater than the value used to build the index.

    +
    + +
    -p/--threads NTHREADS
    +
    + +

    Launch NTHREADS parallel search threads (default: 1). Threads will run on separate processors/cores and synchronize when parsing reads and outputting alignments. Searching for alignments is highly parallel, and speedup is close to linear. Increasing -p increases HISAT2's memory footprint. E.g. when aligning to a human genome index, increasing -p from 1 to 8 increases the memory footprint by a few hundred megabytes. This option is only available if bowtie is linked with the pthreads library (i.e. if BOWTIE_PTHREADS=0 is not specified at build time).

    +
    + +
    --reorder
    +
    + +

    Guarantees that output SAM records are printed in an order corresponding to the order of the reads in the original input file, even when -p is set greater than 1. Specifying --reorder and setting -p greater than 1 causes HISAT2 to run somewhat slower and use somewhat more memory then if --reorder were not specified. Has no effect if -p is set to 1, since output order will naturally correspond to input order in that case.

    +
    + +
    --mm
    +
    + +

    Use memory-mapped I/O to load the index, rather than typical file I/O. Memory-mapping allows many concurrent bowtie processes on the same computer to share the same memory image of the index (i.e. you pay the memory overhead just once). This facilitates memory-efficient parallelization of bowtie in situations where using -p is not possible or not preferable.

    +
    + +

    Other options

    + + + + + +
    + +
    --qc-filter
    +
    + +

    Filter out reads for which the QSEQ filter field is non-zero. Only has an effect when read format is --qseq. Default: off.

    +
    + +
    --seed <int>
    +
    + +

    Use <int> as the seed for pseudo-random number generator. Default: 0.

    +
    + +
    --non-deterministic
    +
    + +

    Normally, HISAT2 re-initializes its pseudo-random generator for each read. It seeds the generator with a number derived from (a) the read name, (b) the nucleotide sequence, (c) the quality sequence, (d) the value of the --seed option. This means that if two reads are identical (same name, same nucleotides, same qualities) HISAT2 will find and report the same alignment(s) for both, even if there was ambiguity. When --non-deterministic is specified, HISAT2 re-initializes its pseudo-random generator for each read using the current time. This means that HISAT2 will not necessarily report the same alignment for two identical reads. This is counter-intuitive for some users, but might be more appropriate in situations where the input consists of many identical reads.

    +
    + +
    --version
    +
    + +

    Print version information and quit.

    +
    + +
    -h/--help
    +
    + +

    Print usage information and quit.

    +
    + +

    SAM output

    +

    Following is a brief description of the SAM format as output by hisat2. For more details, see the SAM format specification.

    +

    By default, hisat2 prints a SAM header with @HD, @SQ and @PG lines. When one or more --rg arguments are specified, hisat2 will also print an @RG line that includes all user-specified --rg tokens separated by tabs.

    +

    Each subsequent line describes an alignment or, if the read failed to align, a read. Each line is a collection of at least 12 fields separated by tabs; from left to right, the fields are:

    +
      +
    1. Name of read that aligned.

      +

      Note that the SAM specification disallows whitespace in the read name. If the read name contains any whitespace characters, HISAT2 will truncate the name at the first whitespace character. This is similar to the behavior of other tools.

    2. +
    3. Sum of all applicable flags. Flags relevant to HISAT2 are:

      +
      + +
      1
      +
      + +

      The read is one of a pair

      +
      + +
      2
      +
      + +

      The alignment is one end of a proper paired-end alignment

      +
      + +
      4
      +
      + +

      The read has no reported alignments

      +
      + +
      8
      +
      + +

      The read is one of a pair and has no reported alignments

      +
      + +
      16
      +
      + +

      The alignment is to the reverse reference strand

      +
      + +
      32
      +
      + +

      The other mate in the paired-end alignment is aligned to the reverse reference strand

      +
      + +
      64
      +
      + +

      The read is mate 1 in a pair

      +
      + +
      128
      +
      + +

      The read is mate 2 in a pair

      +
      + +

      Thus, an unpaired read that aligns to the reverse reference strand will have flag 16. A paired-end read that aligns and is the first mate in the pair will have flag 83 (= 64 + 16 + 2 + 1).

    4. +
    5. Name of reference sequence where alignment occurs

    6. +
    7. 1-based offset into the forward reference strand where leftmost character of the alignment occurs

    8. +
    9. Mapping quality

    10. +
    11. CIGAR string representation of alignment

    12. +
    13. Name of reference sequence where mate's alignment occurs. Set to = if the mate's reference sequence is the same as this alignment's, or * if there is no mate.

    14. +
    15. 1-based offset into the forward reference strand where leftmost character of the mate's alignment occurs. Offset is 0 if there is no mate.

    16. +
    17. Inferred fragment length. Size is negative if the mate's alignment occurs upstream of this alignment. Size is 0 if the mates did not align concordantly. However, size is non-0 if the mates aligned discordantly to the same chromosome.

    18. +
    19. Read sequence (reverse-complemented if aligned to the reverse strand)

    20. +
    21. ASCII-encoded read qualities (reverse-complemented if the read aligned to the reverse strand). The encoded quality values are on the Phred quality scale and the encoding is ASCII-offset by 33 (ASCII char !), similarly to a FASTQ file.

    22. +
    23. Optional fields. Fields are tab-separated. hisat2 outputs zero or more of these optional fields for each alignment, depending on the type of the alignment:

      + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      AS:i:<N>
      +
      + +

      Alignment score. Can be negative. Only present if SAM record is for an aligned read.

      +
      + +
      ZS:i:<N>
      +
      +

      Alignment score for the best-scoring alignment found other than the alignment reported. Can be negative. Only present if the SAM record is for an aligned read and more than one alignment was found for the read. Note that, when the read is part of a concordantly-aligned pair, this score could be greater than [AS:i].

      +
      + +
      YS:i:<N>
      +
      + +

      Alignment score for opposite mate in the paired-end alignment. Only present if the SAM record is for a read that aligned as part of a paired-end alignment.

      +
      + +
      XN:i:<N>
      +
      + +

      The number of ambiguous bases in the reference covering this alignment. Only present if SAM record is for an aligned read.

      +
      + +
      XM:i:<N>
      +
      + +

      The number of mismatches in the alignment. Only present if SAM record is for an aligned read.

      +
      + +
      XO:i:<N>
      +
      + +

      The number of gap opens, for both read and reference gaps, in the alignment. Only present if SAM record is for an aligned read.

      +
      + +
      XG:i:<N>
      +
      + +

      The number of gap extensions, for both read and reference gaps, in the alignment. Only present if SAM record is for an aligned read.

      +
      + +
      NM:i:<N>
      +
      + +

      The edit distance; that is, the minimal number of one-nucleotide edits (substitutions, insertions and deletions) needed to transform the read string into the reference string. Only present if SAM record is for an aligned read.

      +
      + +
      YF:Z:<S>
      +
      + +

      String indicating reason why the read was filtered out. See also: [Filtering]. Only appears for reads that were filtered out.

      +
      + +
      YT:Z:<S>
      +
      + +

      Value of UU indicates the read was not part of a pair. Value of CP indicates the read was part of a pair and the pair aligned concordantly. Value of DP indicates the read was part of a pair and the pair aligned discordantly. Value of UP indicates the read was part of a pair but the pair failed to aligned either concordantly or discordantly.

      +
      + +
      MD:Z:<S>
      +
      + +

      A string representation of the mismatched reference bases in the alignment. See SAM format specification for details. Only present if SAM record is for an aligned read.

      +
      + +
      XS:A:<A>
      +
      + +

      Values of + and - indicate the read is mapped to transcripts on sense and anti-sense strands, respectively. Spliced alignments need to have this field, which is required in Cufflinks and StringTie.
      We can report this field for the canonical-splice site (GT/AG), but not for non-canonical splice sites. You can direct HISAT2 not to output such alignments (involving non-canonical splice sites) using "--pen-noncansplice 1000000".

      +
      + +
      NH:i:<N>
      +
      + +

      The number of mapped locations for the read or the pair.

      +
      + +
      Zs:Z:<S>
      +
      + +When the alignment of a read involves SNPs that are in the index, this option is used to indicate where exactly the read involves the SNPs. This optional field is similar to the above MD:Z field. For example, Zs:Z:1|S|rs3747203,97|S|rs16990981 indicates the second base of the read corresponds to a known SNP (ID: rs3747203). 97 bases after the third base (the base after the second one), the read at 100th base involves another known SNP (ID: rs16990981). 'S' indicates a single nucleotide polymorphism. 'D' and 'I' indicate a deletion and an insertion, respectively. +
      +
    24. +
    +

    The hisat2-build indexer

    +

    hisat2-build builds a HISAT2 index from a set of DNA sequences. hisat2-build outputs a set of 6 files with suffixes .1.ht2, .2.ht2, .3.ht2, .4.ht2, .5.ht2, .6.ht2, .7.ht2, and .8.ht2. In the case of a large index these suffixes will have a ht2l termination. These files together constitute the index: they are all that is needed to align reads to that reference. The original sequence FASTA files are no longer used by HISAT2 once the index is built.

    +

    Use of Karkkainen's blockwise algorithm allows hisat2-build to trade off between running time and memory usage. hisat2-build has three options governing how it makes this trade: [-p/--packed], --bmax/--bmaxdivn, and --dcv. By default, hisat2-build will automatically search for the settings that yield the best running time without exhausting memory. This behavior can be disabled using the -a/--noauto option.

    +

    The indexer provides options pertaining to the "shape" of the index, e.g. --offrate governs the fraction of Burrows-Wheeler rows that are "marked" (i.e., the density of the suffix-array sample; see the original FM Index paper for details). All of these options are potentially profitable trade-offs depending on the application. They have been set to defaults that are reasonable for most cases according to our experiments. See Performance tuning for details.

    +

    hisat2-build can generate either small or large indexes. The wrapper will decide which based on the length of the input genome. If the reference does not exceed 4 billion characters but a large index is preferred, the user can specify --large-index to force hisat2-build to build a large index instead.

    +

    The HISAT2 index is based on the FM Index of Ferragina and Manzini, which in turn is based on the Burrows-Wheeler transform. The algorithm used to build the index is based on the blockwise algorithm of Karkkainen.

    +

    Command Line

    +

    Usage:

    +
    hisat2-build [options]* <reference_in> <ht2_base>
    +

    Notes

    +
    If you use --snp, --ss, and/or --exon, hisat2-build will need about 200GB RAM for the human genome size as index building involves a graph construction. 
    +Otherwise, you will be able to build an index on your desktop with 8GB RAM.
    +

    Main arguments

    +
    + +
    <reference_in>
    +
    + +

    A comma-separated list of FASTA files containing the reference sequences to be aligned to, or, if -c is specified, the sequences themselves. E.g., <reference_in> might be chr1.fa,chr2.fa,chrX.fa,chrY.fa, or, if -c is specified, this might be GGTCATCCT,ACGGGTCGT,CCGTTCTATGCGGCTTA.

    +
    + +
    <ht2_base>
    +
    + +

    The basename of the index files to write. By default, hisat2-build writes files named NAME.1.ht2, NAME.2.ht2, NAME.3.ht2, NAME.4.ht2, NAME.5.ht2, NAME.6.ht2, NAME.7.ht2, and NAME.8.ht2 where NAME is <ht2_base>.

    +
    + +

    Options

    + + + + +
    + +
    -f
    +
    + +

    The reference input files (specified as <reference_in>) are FASTA files (usually having extension .fa, .mfa, .fna or similar).

    +
    + +
    -c
    +
    + +

    The reference sequences are given on the command line. I.e. <reference_in> is a comma-separated list of sequences rather than a list of FASTA files.

    +
    + +
    --large-index
    +
    + +

    Force hisat2-build to build a large index, even if the reference is less than ~ 4 billion nucleotides long.

    +
    + +
    -a/--noauto
    +
    + +

    Disable the default behavior whereby hisat2-build automatically selects values for the --bmax, --dcv and [--packed] parameters according to available memory. Instead, user may specify values for those parameters. If memory is exhausted during indexing, an error message will be printed; it is up to the user to try new parameters.

    +
    + +
    --bmax <int>
    +
    + +

    The maximum number of suffixes allowed in a block. Allowing more suffixes per block makes indexing faster, but increases peak memory usage. Setting this option overrides any previous setting for --bmax, or --bmaxdivn. Default (in terms of the --bmaxdivn parameter) is --bmaxdivn 4. This is configured automatically by default; use -a/--noauto to configure manually.

    +
    + +
    --bmaxdivn <int>
    +
    + +

    The maximum number of suffixes allowed in a block, expressed as a fraction of the length of the reference. Setting this option overrides any previous setting for --bmax, or --bmaxdivn. Default: --bmaxdivn 4. This is configured automatically by default; use -a/--noauto to configure manually.

    +
    + +
    --dcv <int>
    +
    + +

    Use <int> as the period for the difference-cover sample. A larger period yields less memory overhead, but may make suffix sorting slower, especially if repeats are present. Must be a power of 2 no greater than 4096. Default: 1024. This is configured automatically by default; use -a/--noauto to configure manually.

    +
    + +
    --nodc
    +
    + +

    Disable use of the difference-cover sample. Suffix sorting becomes quadratic-time in the worst case (where the worst case is an extremely repetitive reference). Default: off.

    +
    + +
    -r/--noref
    +
    + +

    Do not build the NAME.3.ht2 and NAME.4.ht2 portions of the index, which contain a bitpacked version of the reference sequences and are used for paired-end alignment.

    +
    + +
    -3/--justref
    +
    + +

    Build only the NAME.3.ht2 and NAME.4.ht2 portions of the index, which contain a bitpacked version of the reference sequences and are used for paired-end alignment.

    +
    + +
    -o/--offrate <int>
    +
    + +

    To map alignments back to positions on the reference sequences, it's necessary to annotate ("mark") some or all of the Burrows-Wheeler rows with their corresponding location on the genome. -o/--offrate governs how many rows get marked: the indexer will mark every 2^<int> rows. Marking more rows makes reference-position lookups faster, but requires more memory to hold the annotations at runtime. The default is 4 (every 16th row is marked; for human genome, annotations occupy about 680 megabytes).

    +
    + +
    -t/--ftabchars <int>
    +
    + +

    The ftab is the lookup table used to calculate an initial Burrows-Wheeler range with respect to the first <int> characters of the query. A larger <int> yields a larger lookup table but faster query times. The ftab has size 4^(<int>+1) bytes. The default setting is 10 (ftab is 4MB).

    +
    + +
    --localoffrate <int>
    +
    + +

    This option governs how many rows get marked in a local index: the indexer will mark every 2^<int> rows. Marking more rows makes reference-position lookups faster, but requires more memory to hold the annotations at runtime. The default is 3 (every 8th row is marked, this occupies about 16KB per local index).

    +
    + +
    --localftabchars <int>
    +
    + +

    The local ftab is the lookup table in a local index. The default setting is 6 (ftab is 8KB per local index).

    +
    + +
    -p <int>
    +
    + +

    Launch NTHREADS parallel build threads (default: 1).

    +
    + +
    --snp <path>
    +
    + +

    Provide a list of SNPs (in the HISAT2's own format) as follows (five columns).

    +

    SNP ID <tab> snp type (single, deletion, or insertion) <tab> chromosome name <tab> zero-offset based genomic position of a SNP <tab> alternative base (single), the length of SNP (deletion), or insertion sequence (insertion)

    +

    For example, rs58784443 single 13 18447947 T

    +

    Use hisat2_extract_snps_haplotypes_UCSC.py (in the HISAT2 package) to extract SNPs and haplotypes from a dbSNP file (e.g. http://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/snp144Common.txt.gz). or hisat2_extract_snps_haplotypes_VCF.py to extract SNPs and haplotypes from a VCF file (e.g. ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502/supporting/GRCh38_positions/ALL.chr22.phase3_shapeit2_mvncall_integrated_v3plus_nounphased.rsID.genotypes.GRCh38_dbSNP_no_SVs.vcf.gz).

    +
    + +
    --haplotype <path>
    +
    + +

    Provide a list of haplotypes (in the HISAT2's own format) as follows (five columns).

    +

    Haplotype ID <tab> chromosome name <tab> zero-offset based left coordinate of haplotype <tab> zero-offset based right coordinate of haplotype <tab> a comma separated list of SNP ids in the haplotype

    +

    For example, ht35 13 18446877 18446945 rs12381094,rs12381056,rs192016659,rs538569910

    +

    See the above option, --snp, about how to extract haplotypes. This option is not required, but haplotype information can keep the index construction from exploding and reduce the index size substantially.

    +
    + +
    --ss <path>
    +
    + +

    Note this option should be used with the following --exon option. Provide a list of splice sites (in the HISAT2's own format) as follows (four columns).

    +

    chromosome name <tab> zero-offset based genomic position of the flanking base on the left side of an intron <tab> zero-offset based genomic position of the flanking base on the right <tab> strand

    +

    Use hisat2_extract_splice_sites.py (in the HISAT2 package) to extract splice sites from a GTF file.

    +
    + +
    --exon <path>
    +
    + +

    Note this option should be used with the above --ss option. Provide a list of exons (in the HISAT2's own format) as follows (three columns).

    +

    chromosome name <tab> zero-offset based left genomic position of an exon <tab> zero-offset based right genomic position of an exon

    +

    Use hisat2_extract_exons.py (in the HISAT2 package) to extract exons from a GTF file.

    +
    + +
    --seed <int>
    +
    + +

    Use <int> as the seed for pseudo-random number generator.

    +
    + +
    --cutoff <int>
    +
    + +

    Index only the first <int> bases of the reference sequences (cumulative across sequences) and ignore the rest.

    +
    + +
    -q/--quiet
    +
    + +

    hisat2-build is verbose by default. With this option hisat2-build will print only error messages.

    +
    + +
    -h/--help
    +
    + +

    Print usage information and quit.

    +
    + +
    --version
    +
    + +

    Print version information and quit.

    +
    + +

    The hisat2-inspect index inspector

    +

    hisat2-inspect extracts information from a HISAT2 index about what kind of index it is and what reference sequences were used to build it. When run without any options, the tool will output a FASTA file containing the sequences of the original references (with all non-A/C/G/T characters converted to Ns). It can also be used to extract just the reference sequence names using the -n/--names option or a more verbose summary using the -s/--summary option.

    +

    Command Line

    +

    Usage:

    +
    hisat2-inspect [options]* <ht2_base>
    +

    Main arguments

    +
    + +
    <ht2_base>
    +
    + +

    The basename of the index to be inspected. The basename is name of any of the index files but with the .X.ht2 suffix omitted. hisat2-inspect first looks in the current directory for the index files, then in the directory specified in the HISAT2_INDEXES environment variable.

    +
    + +

    Options

    +
    + +
    -a/--across <int>
    +
    + +

    When printing FASTA output, output a newline character every <int> bases (default: 60).

    +
    + +
    -n/--names
    +
    + +

    Print reference sequence names, one per line, and quit.

    +
    + +
    -s/--summary
    +
    + +

    Print a summary that includes information about index settings, as well as the names and lengths of the input sequences. The summary has this format:

    +
    Colorspace  <0 or 1>
    +SA-Sample   1 in <sample>
    +FTab-Chars  <chars>
    +Sequence-1  <name>  <len>
    +Sequence-2  <name>  <len>
    +...
    +Sequence-N  <name>  <len>
    +

    Fields are separated by tabs. Colorspace is always set to 0 for HISAT2.

    +
    + +
    --snp
    +
    + +

    Print SNPs, and quit.

    +
    + +
    --ss
    +
    + +

    Print splice sites, and quit.

    +
    + +
    --ss-all
    +
    + +

    Print splice sites including those not in the global index, and quit.

    +
    + +
    --exon
    +
    + +

    Print exons, and quit.

    +
    + +
    -v/--verbose
    +
    + +

    Print verbose output (for debugging).

    +
    + +
    --version
    +
    + +

    Print version information and quit.

    +
    + +
    -h/--help
    +
    + +

    Print usage information and quit.

    +
    + +

    Getting started with HISAT2

    +

    HISAT2 comes with some example files to get you started. The example files are not scientifically significant; these files will simply let you start running HISAT2 and downstream tools right away.

    +

    First follow the manual instructions to obtain HISAT2. Set the HISAT2_HOME environment variable to point to the new HISAT2 directory containing the hisat2, hisat2-build and hisat2-inspect binaries. This is important, as the HISAT2_HOME variable is used in the commands below to refer to that directory.

    +

    Indexing a reference genome

    +

    To create an index for the genomic region (1 million bps from the human chromosome 22 between 20,000,000 and 20,999,999) included with HISAT2, create a new temporary directory (it doesn't matter where), change into that directory, and run:

    +
    $HISAT2_HOME/hisat2-build $HISAT2_HOME/example/reference/22_20-21M.fa --snp $HISAT2_HOME/example/reference/22_20-21M.snp 22_20-21M_snp
    +

    The command should print many lines of output then quit. When the command completes, the current directory will contain ten new files that all start with 22_20-21M_snp and end with .1.ht2, .2.ht2, .3.ht2, .4.ht2, .5.ht2, .6.ht2, .7.ht2, and .8.ht2. These files constitute the index - you're done!

    +

    You can use hisat2-build to create an index for a set of FASTA files obtained from any source, including sites such as UCSC, NCBI, and Ensembl. When indexing multiple FASTA files, specify all the files using commas to separate file names. For more details on how to create an index with hisat2-build, see the manual section on index building. You may also want to bypass this process by obtaining a pre-built index.

    +

    Aligning example reads

    +

    Stay in the directory created in the previous step, which now contains the 22_20-21M index files. Next, run:

    +
    $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -U $HISAT2_HOME/example/reads/reads_1.fa -S eg1.sam
    +

    This runs the HISAT2 aligner, which aligns a set of unpaired reads to the genome region using the index generated in the previous step. The alignment results in SAM format are written to the file eg1.sam, and a short alignment summary is written to the console. (Actually, the summary is written to the "standard error" or "stderr" filehandle, which is typically printed to the console.)

    +

    To see the first few lines of the SAM output, run:

    +
    head eg1.sam
    +

    You will see something like this:

    +
    @HD     VN:1.0  SO:unsorted
    +@SQ     SN:22:20000001-21000000 LN:1000000
    +@PG     ID:hisat2       PN:hisat2       VN:2.0.0-beta
    +1       0       22:20000001-21000000    397984  255     100M    *       0       0       GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:100        YT:Z:UU NH:i:1
    +2       16      22:20000001-21000000    398131  255     100M    *       0       0       ATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCT    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:80A19      YT:Z:UU NH:i:1  Zs:Z:80|S|rs576159895
    +3       16      22:20000001-21000000    398222  255     100M    *       0       0       TGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAA    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:16A83      YT:Z:UU NH:i:1  Zs:Z:16|S|rs2629364
    +4       16      22:20000001-21000000    398247  255     90M200N10M      *       0       0       CAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAACCGCTGCACCAGGAAGTCGATCCAG    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:100        YT:Z:UU XS:A:-  NH:i:1
    +5       16      22:20000001-21000000    398194  255     100M    *       0       0       GGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCACTTGGT    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:17A26A55   YT:Z:UU NH:i:1  Zs:Z:17|S|rs576159895,26|S|rs2629364
    +6       0       22:20000001-21000000    398069  255     100M    *       0       0       CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:100        YT:Z:UU NH:i:1
    +7       0       22:20000001-21000000    397896  255     100M    *       0       0       GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:31G68      YT:Z:UU NH:i:1  Zs:Z:31|S|rs562662261
    +8       0       22:20000001-21000000    398150  255     100M    *       0       0       AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:61A26A11   YT:Z:UU NH:i:1  Zs:Z:61|S|rs576159895,26|S|rs2629364
    +9       16      22:20000001-21000000    398329  255     8M200N92M       *       0       0       ACCAGGAAGTCGATCCAGATGTAGTGGGGGGTCACTTCGGGGGGACAGGGTTTGGGTTGACTTGCTTCCGAGGCAGCCAGGGGGTCTGCTTCCTTTATCT    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:100        YT:Z:UU XS:A:-  NH:i:1
    +10      16      22:20000001-21000000    398184  255     100M    *       0       0       CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC    IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    AS:i:0  XN:i:0  XM:i:0  XO:i:0  XG:i:0  NM:i:0  MD:Z:27A26A45   YT:Z:UU NH:i:1  Zs:Z:27|S|rs576159895,26|S|rs2629364
    +

    The first few lines (beginning with @) are SAM header lines, and the rest of the lines are SAM alignments, one line per read or mate. See the HISAT2 manual section on SAM output and the SAM specification for details about how to interpret the SAM file format.

    +

    Paired-end example

    +

    To align paired-end reads included with HISAT2, stay in the same directory and run:

    +
    $HISAT2_HOME/hisat2 -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam
    +

    This aligns a set of paired-end reads to the reference genome, with results written to the file eg2.sam.

    +

    Using SAMtools/BCFtools downstream

    +

    SAMtools is a collection of tools for manipulating and analyzing SAM and BAM alignment files. BCFtools is a collection of tools for calling variants and manipulating VCF and BCF files, and it is typically distributed with SAMtools. Using these tools together allows you to get from alignments in SAM format to variant calls in VCF format. This example assumes that samtools and bcftools are installed and that the directories containing these binaries are in your PATH environment variable.

    +

    Run the paired-end example:

    +
    $HISAT2_HOME/hisat -f -x $HISAT2_HOME/example/index/22_20-21M_snp -1 $HISAT2_HOME/example/reads/reads_1.fa -2 $HISAT2_HOME/example/reads/reads_2.fa -S eg2.sam
    +

    Use samtools view to convert the SAM file into a BAM file. BAM is a the binary format corresponding to the SAM text format. Run:

    +
    samtools view -bS eg2.sam > eg2.bam
    +

    Use samtools sort to convert the BAM file to a sorted BAM file. The following command requires samtools version 1.2 or higher.

    +
    samtools sort eg2.bam -o eg2.sorted.bam
    +

    We now have a sorted BAM file called eg2.sorted.bam. Sorted BAM is a useful format because the alignments are (a) compressed, which is convenient for long-term storage, and (b) sorted, which is convenient for variant discovery. To generate variant calls in VCF format, run:

    +
    samtools mpileup -uf $HISAT2_HOME/example/reference/22_20-21M.fa eg2.sorted.bam | bcftools view -bvcg - > eg2.raw.bcf
    +

    Then to view the variants, run:

    +
    bcftools view eg2.raw.bcf
    +

    See the official SAMtools guide to Calling SNPs/INDELs with SAMtools/BCFtools for more details and variations on this process.

    diff --git a/docs_jhu/manual.shtml b/docs_jhu/manual.shtml new file mode 100644 index 0000000..73d5209 --- /dev/null +++ b/docs_jhu/manual.shtml @@ -0,0 +1,37 @@ + + + + + +
    +
    + +
    + + + + +
    + + +
    +

    Table of Contents

    + +
    +
    +
    + + + + + + + + + diff --git a/docs_jhu/sidebar.inc.shtml b/docs_jhu/sidebar.inc.shtml new file mode 100644 index 0000000..069393e --- /dev/null +++ b/docs_jhu/sidebar.inc.shtml @@ -0,0 +1,409 @@ +

    Site Map

    +
    + +
    + +

    News and Updates

    +
    +
      + + +
      New releases and related tools will be announced through the Bowtie + mailing list.
      +
    +
    + +

    Getting Help

    +
    +
      + + +
      + + Please use hisat2.genomics@gmail.com for + private communications only. Please do not email technical questions to HISAT2 contributors directly.
      +
    +
    + +

    Releases

    +
    + +Please cite:

    Kim D, Langmead B and Salzberg SL. HISAT: a fast spliced aligner with low memory requirements. Nature Methods 2015

    +
    + +

    Indexes (see note)

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + H. sapiens, GRCh38 +
    + genome + + 3.9 GB +
    + genome_snp + + 4.6 GB +
    + genome_tran + + 4.1 GB +
    + genome_snp_tran + + 4.6 GB +
    + H. sapiens, UCSC hg38 +
    + genome + + 4.1 GB +
    + H. sapiens, UCSC hg38 and Refseq gene annotations referred to in the Nature Protocol paper +
    + genome_tran + + 4.2 GB +
    + H. sapiens, GRCh37 +
    + genome + + 3.9 GB +
    + genome_snp + + 4.5 GB +
    + genome_tran + + 4.0 GB +
    + genome_snp_tran + + 4.5 GB +
    + H. sapiens, UCSC hg19 +
    + genome + + 3.9 GB +
    + M. musculus, GRCm38 +
    + genome + + 3.7 GB +
    + genome_snp + + 4.0 GB +
    + genome_tran + + 3.7 GB +
    + genome_snp_tran + + 4.0 GB +
    + M. musculus, UCSC mm10 +
    + genome + + 3.5 GB +
    + R. norvegicus, UCSC rn6 +
    + genome + + 3.7 GB +
    + D. melanogaster, BDGP6 +
    + genome + + 0.2 GB +
    + genome_tran + + 0.2 GB +
    + D. melanogaster, UCSC dm6 +
    + genome + + 0.2 GB +
    + C. elegans, WBcel235 +
    + genome + + 0.1 GB +
    + genome_tran + + 0.1 GB +
    + C. elegans, UCSC ce10 +
    + genome + + 0.1 GB +
    + S. cerevisiae, R64-1-1 +
    + genome + + 0.01 GB +
    + genome_tran + + 0.01 GB +
    + S. cerevisiae, UCSC sacCer3 +
    + genome + + 0.01 GB +
    +
    + * genome: HFM index for reference +
    + * genome_snp: HGFM index for reference plus SNPs +
    + * genome_tran: HGFM index for reference plus transcripts +
    + * genome_snp_tran: HGFM index for reference plus SNPs and transcripts +
    + more indexes +
    +
    + +

    Related Tools

    +
    +
      +
    • HISAT-genotype: Next-generation analysis of human genomes
    • +
    • HISAT: Fast and sensitive spliced alignment
    • +
    • Bowtie2: Ultrafast read alignment
    • +
    • TopHat2: Spliced read mapper for RNA-Seq
    • +
    • Cufflinks: Isoform assembly and quantitation for RNA-Seq
    • +
    • StringTie: Transcript assembly and quantification for RNA-Seq
    • +
    +
    + +

    Publications

    + + +

    Contributors

    + + +

    Links

    + diff --git a/docs_jhu/strip_markdown.pl b/docs_jhu/strip_markdown.pl new file mode 100644 index 0000000..0ecc595 --- /dev/null +++ b/docs_jhu/strip_markdown.pl @@ -0,0 +1,45 @@ +#!/usr/bin/perl -w + +## +# strip_markdown.pl +# +# Used to convert MANUAL.markdown to MANUAL. Leaves all manual content, but +# strips away some of the clutter that makes it hard to read the markdown. +# + +use strict; +use warnings; + +my $lastBlank = 0; + +while(<>) { + # Skip comments + next if /^\s*/; + # Skip internal links + next if /\[.*\]: #/; + # Skip HTML + next if /^\s?\s?\s?<.*>\s*$/; + # Skip HTML + next if /^\s*\s*$/; + # Strip [`...`] + s/\[`/`/g; + s/`\]/`/g; + # Strip [#...] + #s/\[#[^\]]*\]//g; + # Strip (#...) + s/\(#[^\)]*\)//g; + # Turn hashes into spaces + #s/^####/ /; + #s/^###/ /; + if(/^\s*$/) { + next if $lastBlank; + $lastBlank = 1; + } else { + $lastBlank = 0; + } + print $_; +} diff --git a/docs_jhu/style.css b/docs_jhu/style.css new file mode 100644 index 0000000..b4014e1 --- /dev/null +++ b/docs_jhu/style.css @@ -0,0 +1,306 @@ +/* +Stylesheet for the free sNews15_1 template +from http://www.free-css-templates.com +*/ + +/* Reset all margins and paddings for browsers */ +* { + padding: 0; + margin: 0; +} + +body { + font: .8em Verdana, Arial, Sans-Serif; + line-height: 1.6em; + margin: 0; + /* background-image: url(../images/bg.jpg); */ + /* background-repeat: repeat */ +} + +#wrap { margin: 0 auto; width: 95% } + +/* TOP HEADER -------- */ +#top { + margin: 0 auto; + padding: 0; + background:#1E6BAC url(../images/ccbstrip.jpg) repeat-x top; + height: 141px; +} +#top h1 { padding: 10px 0 0 25px; color: #FFF; font-size: 240%; background: transparent;} +#top h2 { padding: 0px 0 0 25px; color: #bbb; font-size: 100%; background: transparent;} +#top .padding { padding-top: 5px; } +/* +#top .lefts { + background: transparent url(../images/topl.jpg) no-repeat left; + height: 81px; +} +#top .rights { + background: transparent url(../images/topr.jpg) no-repeat right; + float: right; + height: 81px; + width: 18px; +} +*/ +/* SEARCH BOX AND BUTTON ----------*/ +#search { float: right; padding: 10px 25px 0 0; } + +#search input.text { + border: 1px solid #eee; + display: inline; + margin-top: 5px; + width: 120px; + height: 12px; + font-size: 10px; + } + #search input.searchbutton { + border: 0; + background: transparent; + color: #FFF; + cursor: pointer; + font: bold 0.8em Arial, Arial, Sans-Serif + } + +#subheader { + clear: both; + border-top: 1px dotted #888; + border-bottom: 1px dotted #888; + background: #eaeaea; + color: #505050; + padding: 1em; + margin: 15px 0px 10px 0px; + +} +#subheader a { text-decoration: none; /* border-bottom: 1px dashed #0066B3; */ } + + +/* TOP MENU ---------- */ +#topmenu { margin: 0px 8px 0 8px; + padding: 0; + background: url(../images/menu.jpg) repeat-x top; + height: 30px; + +} +#topmenu .lefts { + background: url(../images/menul.jpg) no-repeat left; + height: 30px; + padding-left: 0px; +} +#topmenu .rights { + background: url(../images/menur.jpg) no-repeat right; + float: right; + height: 30px; + width: 8px; +} +#topmenu li a { + color: #FFF; + text-align: left; + padding-left: 10px; + padding-right: 15px; + text-decoration: none; + background: transparent; + font-weight: bold +} +#topmenu li { padding: 0px; + float: left; + margin: 0; + font-size: 11px; + line-height: 30px; + white-space: nowrap; + /* list-style-type: none; */ + width: auto; + background: url(../images/sep.gif) no-repeat top right + +} + +#main { background: #FFF; margin: 25px 0 15px 0; color: #666; } + +#main #rightside { + width: 300px; + float: right; + background: #FFF; + margin-right: 0px; + color: #555; + +} + +#main #rightside .box { + background: #efefef; + margin-bottom: 10px; + padding: 5px; + color: #555; +} + +#main #rightside h2 { + font: bold 1.0em Arial, Arial, Sans-Serif; + background: #CDCDCD url(../images/greyc.gif) no-repeat top right; + height: 18px; + padding: 3px; + color: #666; +} + +/* LEFT SIDE - ARTICLES AREA -------- */ +#leftside { + padding-left: 8px; + color: #555; + background: #FFF; + margin-right: 255px; + margin-left: 0px; + +} + +#manual { + margin-right: 305px; + margin-left: 0px; + width: auto; +} + +#leftside h1 { padding: 15px 0 10px 0 } +#leftside h2 { padding: 15px 0 10px 0; color: #555; text-indent: 17px; background: #FFF url(../images/head.gif) no-repeat left; } +#leftside h3 { padding: 15px 0 10px 0; font-size: 100%; margin-left: 5px; text-indent: 17px; background: #FFF url(../images/head.gif) no-repeat left; } +#leftside ul { margin-left: 24px; padding-left 24px; list-style-type: circle } +#leftside li { } +#leftside p { padding: 0px 0 10px 0 } + +#footer { + clear: both; + background: #FFF url(../images/footer.jpg) repeat-x; + height: 46px; + margin-left: 0px; + margin-right: 0px; + font-size: 75%; + color: #666; +} +#footer p { padding: 5px } +#footer .rside { float: right; display: inline; padding: 5px; text-align: right} + +#toc ol { list-style: roman } + +a { color: #0066B3; background: inherit; text-decoration: none } +h1 { font: bold 1.9em Arial, Arial, Sans-Serif } +h2 { font: bold 1.2em Arial, Arial, Sans-Serif; padding: 0; margin: 0 } +ul { padding: 0; margin: 0; list-style-type: none } +li { } +ol { margin-left: 24px; + padding-left 24px; + list-style: decimal } +/* blockquote { margin-left: 35px; font-family: "Courier New", Courier, monospace; } */ +blockquote { margin-left: 35px; font-family: "Courier New", Courier; } +tt { font-family: "Courier New", Courier, monospace; } +.date { border-top: 1px solid #e5e5e5; text-align: right; margin-bottom: 25px; margin-top: 5px;} +#main #leftside .date a, #main #rightside a { border: 0; text-decoration: none; } + +.comment .date { text-align: left; border: 0;} + + +#breadcrumbs { + float: left; + padding-left: 8px; + padding-top: 0px; + font: bold .8em Arial, Arial, Sans-Serif; + color: #666; + width: 100%; + height: 25px; + margin-top: 10px; + margin-bottom: 10px; + clear: both; +} + + + +#leftside #txt {width: 100%; height: 10em; padding: 3px 3px 3px 6px; margin-left:0em;} +#leftside textarea { border: 1px solid #bbb; width: 100%; } + + +/* SNEWS */ +#main #leftside fieldset { float: left; width: 100%; border: 1px solid #ccc; padding: 10px 8px; margin: 0 10px 8px 0; background: #FFF; color: #000; } +#main #leftside fieldset p { width: 100%; } +#main input { padding: 3px; margin: 0; border: 1px solid #bbb } +/*p { margin-top: 5px; }*/ +p { margin-top: 10px; } +/*input.search { border: 1px solid #ccc; padding: 4px; width: 160px; }*/ +.comment { background: #FFF; color: #808080; padding: 10px; margin: 0 0 10px 0; border-top: 1px solid #ccc; } +.commentsbox { background: #FFF; color: #808080; padding: 10px; margin: 0 0 10px 0; border-top: 1px solid #ccc; } + + +#box-table-a +{ + font-family: .8em Verdana, Arial, Sans-Serif; + /*font-size: 12px;*/ + margin: 45px; + width: 600px; + text-align: left; + border-collapse: collapse; +} +#box-table-a th +{ + font-size: 13px; + font-weight: normal; + padding: 8px; + background: #b9c9fe; + border-top: 4px solid #aabcfe; + border-bottom: 1px solid #fff; + color: #039; +} +#box-table-a td +{ + padding: 8px; + background: #e8edff; + border-bottom: 2px solid #fff; + color: #669; + border-top: 2px solid transparent; +} +#box-table-a tr:hover td +{ + background: #d0dafd; + color: #339; +} + + +#box-table-b +{ + font-family: .8em Verdana, Arial, Sans-Serif; + /*font-size: 12px;*/ + margin: 45px; + width: 480px; + text-align: center; + border-collapse: collapse; + border-top: 7px solid #9baff1; + border-bottom: 7px solid #9baff1; +} +#box-table-b th +{ + font-size: 13px; + font-weight: normal; + padding: 8px; + background: #e8edff; + border-right: 1px solid #9baff1; + border-left: 1px solid #9baff1; + color: #039; +} +#box-table-b td +{ + padding: 8px; + background: #e8edff; + border-right: 1px solid #aabcfe; + border-left: 1px solid #aabcfe; + color: #669; +} + +#manual h1 { margin: 0 15px 10px 15px; padding: 10px 0 10px 0; font: bold 1.9em Arial, Arial, Sans-Serif } +#manual h2 { margin: 0 15px 10px 15px; padding: 10px 0 10px 0; font: bold 1.2em Arial, Arial, Sans-Serif } +#manual h3 { margin: 0 15px 10px 20px; padding: 10px 0 10px 0; font: 1.2em Arial, Arial, Sans-Serif } +#manual h4 { margin: 0 15px 10px 25px; padding: 10px 0 10px 0; font: 1.1em Arial, Arial, Sans-Serif } +#manual p { margin: 0 15px 10px 15px; color: #444 } +#manual table { margin-top: 15px } +#manual ul { margin: 0 15px 10px 15px; padding: 0; margin: 0 } +#manual pre { margin: 0 15px 15px 25px } +#manual li { margin: 0 15px 1px 15px; color: #444 } +#manual ol { margin-left: 24px; padding-left 24px; list-style: decimal } +#manual td { vertical-align: top; } +#manual blockquote { margin-left: 35px; font-family: "Courier New", Courier; } +#manual tt { font: .8em; font-family: "Courier New", Courier; } +#manual code { font: .8em; font-family: "Courier New", Courier; } +#manual .date { border-top: 1px solid #e5e5e5; text-align: right; margin-bottom: 25px; margin-top: 5px;} +#manual .date a, #main #rightside a { border: 0; text-decoration: none; } +#manual .date a, #main #rightside a { border: 0; text-decoration: none; } +#manual td { vertical-align: top; } diff --git a/dp_framer.cpp b/dp_framer.cpp new file mode 100644 index 0000000..d7e359a --- /dev/null +++ b/dp_framer.cpp @@ -0,0 +1,910 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "dp_framer.h" + +using namespace std; + +/** + * Set up variables that describe the shape of a dynamic programming matrix to + * be filled in. The matrix is built around the diagonal containing the seed + * hit: the "seed diagonal". The N diagonals to the right of the seed diagonal + * are the "RHS gap" diagonals, where N is the maximum number of read or + * reference gaps permitted (whichever is larger). The N diagonals to the left + * of the seed diagonal are the "LHS gap" diagonals. + * + * The way the rectangle is currently formulated, there are another N diagonals + * to the left of the "LHS gap" diagonals called the "LHS extra diagonals". It + * might also be possible to split the "extra diagonals" into two subsets and + * place them both to the left of the LHS gap diagonals and to the right of the + * RHS gap diagonals. + * + * The purpose of arranging and these groupings of diagonals is that a subset + * of them, the "core diagonals", can now be considered "covered." By + * "covered" I mean that any alignment that overlaps a cell in any of the core + * diagonals cannot possibly overlap another, higher-scoring alignment that + * falls partially outside the rectangle. + * + * Say the read is 5 characters long, the maximum number of read or ref gaps is + * 2, and the seed hit puts the main diagonal at offset 10 in the reference. + * The larger rectangle explored looks like this: + * + * off=10, maxgap=2 + * + * Ref 1 + * off: 67890123456 0: seed diagonal + * **OO0oo++---- o: "RHS gap" diagonals + * -**OO0oo++--- O: "LHS gap" diagonals + * --**OO0oo++-- *: "LHS extra" diagonals + * ---**OO0oo++- +: "RHS extra" diagonals + * ----**OO0oo++ -: cells that can't possibly be involved in a valid + * alignment that overlaps one of the core diagonals + * + * The "core diagonals" are marked with 0's, O's or o's. + * + * A caveat is that, for performance reasons, we place an upper limit on N - + * the maximum number of read or reference gaps. It is constrained to be no + * greater than 'maxgap'. This means that in some situations, we may report an + * alignment that spuriously trumps a better alignment that falls partially + * outside the rectangle. Also, we may fail to find a valid alignment with + * more than 'maxgap' gaps. + * + * Another issue is trimming: if the seed hit is sufficiently close to one or + * both ends of the reference sequence, and either (a) overhang is not + * permitted, or (b) the number of Ns permitted is less than the number of + * columns that overhang the reference, then we want to exclude the trimmed + * columns from the rectangle. + * + * We need to return enough information so that downstream routines can fully + * understand the shape of the rectangle, which diagonals are which (esp. which + * are the "core" diagonals, since we needn't examine any more seed hits from + * those columns in the future), and how the rectangle is trimmed. The + * information returned should be compatible with the sort of information + * returned by the routines that set up rectangles for mate finding. + */ +bool DynProgFramer::frameSeedExtensionRect( + int64_t off, // ref offset implied by seed hit assuming no gaps + size_t rdlen, // length of read sequence used in DP table (so len + // of +1 nucleotide sequence for colorspace reads) + int64_t reflen, // length of reference sequence aligned to + size_t maxrdgap, // max # of read gaps permitted in opp mate alignment + size_t maxrfgap, // max # of ref gaps permitted in opp mate alignment + int64_t maxns, // # Ns permitted + size_t maxhalf, // max width in either direction + DPRect& rect) // out: DP rectangle +{ + assert_gt(rdlen, 0); + assert_gt(reflen, 0); + // Set N, the maximum number of reference or read gaps permitted, whichever + // is larger. Also, enforce ceiling: can't be larger than 'maxhalf'. + size_t maxgap = max(maxrdgap, maxrfgap); + maxgap = min(maxgap, maxhalf); + // Leave room for "LHS gap" and "LHS extra" diagonals + int64_t refl = off - 2 * maxgap; // inclusive + // Leave room for "RHS gap" and "RHS extra" diagonals + int64_t refr = off + (rdlen - 1) + 2 * maxgap; // inclusive + size_t triml = 0, trimr = 0; + // Check if we have to trim to fit the extents of the reference + if(trimToRef_) { + maxns = 0; // no leeway + } else if(maxns == (int64_t)rdlen) { + maxns--; + } + // Trim from RHS of rectangle + if(refr >= reflen + maxns) { + trimr = (size_t)(refr - (reflen + maxns - 1)); + } + // Trim from LHS of rectangle + if(refl < -maxns) { + triml = (size_t)(-refl) - (size_t)maxns; + } + rect.refl_pretrim = refl; + rect.refr_pretrim = refr; + rect.refl = refl + triml; + rect.refr = refr - trimr; + rect.triml = triml; + rect.trimr = trimr; + rect.maxgap = maxgap; + // Remember which diagonals are "core" as offsets from the LHS of the + // untrimmed rectangle + rect.corel = maxgap; + rect.corer = rect.corel + 2 * maxgap; // inclusive + assert(rect.repOk()); + return !rect.entirelyTrimmed(); +} + +/** + * Set up variables that describe the shape of a dynamic programming matrix to + * be filled in. The matrix is built around the diagonals that terminate in + * the range of columns where the RHS of the opposite mate must fall in order + * to satisfy the fragment-length constraint. These are the "mate" diagonals + * and they also happen to be the "core" diagonals in this case. + * + * The N diagonals to the right of the mate diagonals are the "RHS gap" + * diagonals, where N is the maximum number of read or reference gaps permitted + * (whichever is larger). The N diagonals to the left of the mate diagonals + * are the "LHS gap" diagonals. + * + * The purpose of arranging and these groupings of diagonals is that a subset + * of them, the "core diagonals", can now be considered "covered." By + * "covered" I mean that any alignment that overlaps a cell in any of the core + * diagonals cannot possibly overlap another, higher-scoring alignment that + * falls partially outside the rectangle. + * + * |Anchor| + * o---------OO0000000000000oo------ 0: mate diagonal (also core diags!) + * -o---------OO0000000000000oo----- o: "RHS gap" diagonals + * --o---------OO0000000000000oo---- O: "LHS gap" diagonals + * ---oo--------OO0000000000000oo--- *: "LHS extra" diagonals + * -----o--------OO0000000000000oo-- -: cells that can't possibly be + * ------o--------OO0000000000000oo- involved in a valid alignment that + * -------o--------OO0000000000000oo overlaps one of the core diagonals + * XXXXXXXXXXXXX + * | RHS Range | + * ^ ^ + * rl rr + * + * The "core diagonals" are marked with 0s. + * + * A caveat is that, for performance reasons, we place an upper limit on N - + * the maximum number of read or reference gaps. It is constrained to be no + * greater than 'maxgap'. This means that in some situations, we may report an + * alignment that spuriously trumps a better alignment that falls partially + * outside the rectangle. Also, we may fail to find a valid alignment with + * more than 'maxgap' gaps. + * + * Another issue is trimming: if the seed hit is sufficiently close to one or + * both ends of the reference sequence, and either (a) overhang is not + * permitted, or (b) the number of Ns permitted is less than the number of + * columns that overhang the reference, then we want to exclude the trimmed + * columns from the rectangle. + */ +bool DynProgFramer::frameFindMateAnchorLeftRect( + int64_t ll, // leftmost Watson off for LHS of opp alignment + int64_t lr, // rightmost Watson off for LHS of opp alignment + int64_t rl, // leftmost Watson off for RHS of opp alignment + int64_t rr, // rightmost Watson off for RHS of opp alignment + size_t rdlen, // length of opposite mate + int64_t reflen, // length of reference sequence aligned to + size_t maxrdgap, // max # of read gaps permitted in opp mate alignment + size_t maxrfgap, // max # of ref gaps permitted in opp mate alignment + int64_t maxns, // max # ns permitted in the alignment + size_t maxhalf, // max width in either direction + DPRect& rect) // out: DP rectangle + const +{ + assert_geq(lr, ll); // LHS rightmost must be >= LHS leftmost + assert_geq(rr, rl); // RHS rightmost must be >= RHS leftmost + assert_geq(rr, lr); // RHS rightmost must be >= LHS rightmost + assert_geq(rl, ll); // RHS leftmost must be >= LHS leftmost + assert_gt(rdlen, 0); + assert_gt(reflen, 0); + size_t triml = 0, trimr = 0; + size_t maxgap = max(maxrdgap, maxrfgap); + maxgap = max(maxgap, maxhalf); + // Amount of padding we have to add to account for the fact that alignments + // ending between en_left/en_right might start in various columns in the + // first row + int64_t pad_left = maxgap; + int64_t pad_right = maxgap; + int64_t en_left = rl; + int64_t en_right = rr; + int64_t st_left = en_left - (rdlen-1); + ASSERT_ONLY(int64_t st_right = en_right - (rdlen-1)); + int64_t en_right_pad = en_right + pad_right; + ASSERT_ONLY(int64_t en_left_pad = en_left - pad_left); + ASSERT_ONLY(int64_t st_right_pad = st_right + pad_right); + int64_t st_left_pad = st_left - pad_left; + assert_leq(st_left, en_left); + assert_geq(en_right, st_right); + assert_leq(st_left_pad, en_left_pad); + assert_geq(en_right_pad, st_right_pad); + int64_t refl = st_left_pad; + int64_t refr = en_right_pad; + if(trimToRef_) { + maxns = 0; + } else if(maxns == (int64_t)rdlen) { + maxns--; + } + // Trim from the RHS of the rectangle? + if(refr >= reflen + maxns) { + trimr = (size_t)(refr - (reflen + maxns - 1)); + } + // Trim from the LHS of the rectangle? + if(refl < -maxns) { + triml = (size_t)(-refl) - (size_t)maxns; + } + size_t width = (size_t)(refr - refl + 1); + rect.refl_pretrim = refl; + rect.refr_pretrim = refr; + rect.refl = refl + triml; + rect.refr = refr - trimr; + rect.triml = triml; + rect.trimr = trimr; + rect.maxgap = maxgap; + rect.corel = maxgap; + rect.corer = width - maxgap - 1; // inclusive + assert(rect.repOk()); + return !rect.entirelyTrimmed(); +} + +/** + * Set up variables that describe the shape of a dynamic programming matrix to + * be filled in. The matrix is built around the diagonals that begin in the + * range of columns where the LHS of the opposite mate must fall in order to + * satisfy the fragment-length constraint. These are the "mate" diagonals and + * they also happen to be the "core" diagonals in this case. + * + * The N diagonals to the right of the mate diagonals are the "RHS gap" + * diagonals, where N is the maximum number of read or reference gaps permitted + * (whichever is larger). The N diagonals to the left of the mate diagonals + * are the "LHS gap" diagonals. + * + * The purpose of arranging and these groupings of diagonals is that a subset + * of them, the "core diagonals", can now be considered "covered." By + * "covered" I mean that any alignment that overlaps a cell in any of the core + * diagonals cannot possibly overlap another, higher-scoring alignment that + * falls partially outside the rectangle. + * + * ll lr + * v v + * | LHS Range | + * XXXXXXXXXXXXX |Anchor| + * OO0000000000000oo--------o-------- 0: mate diagonal (also core diags!) + * -OO0000000000000oo--------o------- o: "RHS gap" diagonals + * --OO0000000000000oo--------o------ O: "LHS gap" diagonals + * ---OO0000000000000oo--------oo---- *: "LHS extra" diagonals + * ----OO0000000000000oo---------o--- -: cells that can't possibly be + * -----OO0000000000000oo---------o-- involved in a valid alignment that + * ------OO0000000000000oo---------o- overlaps one of the core diagonals + * + * The "core diagonals" are marked with 0s. + * + * A caveat is that, for performance reasons, we place an upper limit on N - + * the maximum number of read or reference gaps. It is constrained to be no + * greater than 'maxgap'. This means that in some situations, we may report an + * alignment that spuriously trumps a better alignment that falls partially + * outside the rectangle. Also, we may fail to find a valid alignment with + * more than 'maxgap' gaps. + * + * Another issue is trimming: if the seed hit is sufficiently close to one or + * both ends of the reference sequence, and either (a) overhang is not + * permitted, or (b) the number of Ns permitted is less than the number of + * columns that overhang the reference, then we want to exclude the trimmed + * columns from the rectangle. + */ +bool DynProgFramer::frameFindMateAnchorRightRect( + int64_t ll, // leftmost Watson off for LHS of opp alignment + int64_t lr, // rightmost Watson off for LHS of opp alignment + int64_t rl, // leftmost Watson off for RHS of opp alignment + int64_t rr, // rightmost Watson off for RHS of opp alignment + size_t rdlen, // length of opposite mate + int64_t reflen, // length of reference sequence aligned to + size_t maxrdgap, // max # of read gaps permitted in opp mate alignment + size_t maxrfgap, // max # of ref gaps permitted in opp mate alignment + int64_t maxns, // max # ns permitted in the alignment + size_t maxhalf, // max width in either direction + DPRect& rect) // out: DP rectangle + const +{ + assert_geq(lr, ll); + assert_geq(rr, rl); + assert_geq(rr, lr); + assert_geq(rl, ll); + assert_gt(rdlen, 0); + assert_gt(reflen, 0); + size_t triml = 0, trimr = 0; + size_t maxgap = max(maxrdgap, maxrfgap); + maxgap = max(maxgap, maxhalf); + int64_t pad_left = maxgap; + int64_t pad_right = maxgap; + int64_t st_left = ll; + int64_t st_right = lr; + ASSERT_ONLY(int64_t en_left = st_left + (rdlen-1)); + int64_t en_right = st_right + (rdlen-1); + int64_t en_right_pad = en_right + pad_right; + ASSERT_ONLY(int64_t en_left_pad = en_left - pad_left); + ASSERT_ONLY(int64_t st_right_pad = st_right + pad_right); + int64_t st_left_pad = st_left - pad_left; + assert_leq(st_left, en_left); + assert_geq(en_right, st_right); + assert_leq(st_left_pad, en_left_pad); + assert_geq(en_right_pad, st_right_pad); + // We have enough info to deduce where the boundaries of our rectangle + // should be. Finalize the boundaries, ignoring reference trimming for now + int64_t refl = st_left_pad; + int64_t refr = en_right_pad; + if(trimToRef_) { + maxns = 0; + } else if(maxns == (int64_t)rdlen) { + maxns--; + } + // Trim from the RHS of the rectangle? + if(refr >= reflen + maxns) { + trimr = (size_t)(refr - (reflen + maxns - 1)); + } + // Trim from the LHS of the rectangle? + if(refl < -maxns) { + triml = (size_t)(-refl) - (size_t)maxns; + } + size_t width = (size_t)(refr - refl + 1); + rect.refl_pretrim = refl; + rect.refr_pretrim = refr; + rect.refl = refl + triml; + rect.refr = refr - trimr; + rect.triml = triml; + rect.trimr = trimr; + rect.maxgap = maxgap; + rect.corel = maxgap; + rect.corer = width - maxgap - 1; // inclusive + assert(rect.repOk()); + return !rect.entirelyTrimmed(); +} + +#ifdef MAIN_DP_FRAMER + +#include + +static void testCaseFindMateAnchorLeft( + const char *testName, + bool trimToRef, + int64_t ll, + int64_t lr, + int64_t rl, + int64_t rr, + size_t rdlen, + size_t reflen, + size_t maxrdgap, + size_t maxrfgap, + size_t ex_width, + size_t ex_solwidth, + size_t ex_trimup, + size_t ex_trimdn, + int64_t ex_refl, + int64_t ex_refr, + const char *ex_st, // string of '0'/'1' chars + const char *ex_en) // string of '0'/'1' chars +{ + cerr << testName << "..."; + DynProgFramer fr(trimToRef); + size_t width, solwidth; + int64_t refl, refr; + EList st, en; + size_t trimup, trimdn; + size_t maxhalf = 500; + size_t maxgaps = 0; + fr.frameFindMateAnchorLeft( + ll, // leftmost Watson off for LHS of opp alignment + lr, // rightmost Watson off for LHS of opp alignment + rl, // leftmost Watson off for RHS of opp alignment + rr, // rightmost Watson off for RHS of opp alignment + rdlen, // length of opposite mate + reflen, // length of reference sequence aligned to + maxrdgap, // max # of read gaps permitted in opp mate alignment + maxrfgap, // max # of ref gaps permitted in opp mate alignment + maxns, // max # Ns permitted + maxhalf, // max width in either direction + width, // out: calculated width stored here + maxgaps, // out: max # gaps + trimup, // out: number of bases trimmed from upstream end + trimdn, // out: number of bases trimmed from downstream end + refl, // out: ref pos of upper LHS of parallelogram + refr, // out: ref pos of lower RHS of parallelogram + st, // out: legal starting columns stored here + en); // out: legal ending columns stored here + assert_eq(ex_width, width); + assert_eq(ex_solwidth, solwidth); + assert_eq(ex_trimup, trimup); + assert_eq(ex_trimdn, trimdn); + assert_eq(ex_refl, refl); + assert_eq(ex_refr, refr); + for(size_t i = 0; i < width; i++) { + assert_eq((ex_st[i] == '1'), st[i]); + assert_eq((ex_en[i] == '1'), en[i]); + } + cerr << "PASSED" << endl; +} + +static void testCaseFindMateAnchorRight( + const char *testName, + bool trimToRef, + int64_t ll, + int64_t lr, + int64_t rl, + int64_t rr, + size_t rdlen, + size_t reflen, + size_t maxrdgap, + size_t maxrfgap, + size_t ex_width, + size_t ex_solwidth, + size_t ex_trimup, + size_t ex_trimdn, + int64_t ex_refl, + int64_t ex_refr, + const char *ex_st, // string of '0'/'1' chars + const char *ex_en) // string of '0'/'1' chars +{ + cerr << testName << "..."; + DynProgFramer fr(trimToRef); + size_t width, solwidth; + size_t maxgaps; + int64_t refl, refr; + EList st, en; + size_t trimup, trimdn; + size_t maxhalf = 500; + fr.frameFindMateAnchorRight( + ll, // leftmost Watson off for LHS of opp alignment + lr, // rightmost Watson off for LHS of opp alignment + rl, // leftmost Watson off for RHS of opp alignment + rr, // rightmost Watson off for RHS of opp alignment + rdlen, // length of opposite mate + reflen, // length of reference sequence aligned to + maxrdgap, // max # of read gaps permitted in opp mate alignment + maxrfgap, // max # of ref gaps permitted in opp mate alignment + maxns, // max # Ns permitted + maxhalf, // max width in either direction + width, // out: calculated width stored here + maxgaps, // out: calcualted max # gaps + trimup, // out: number of bases trimmed from upstream end + trimdn, // out: number of bases trimmed from downstream end + refl, // out: ref pos of upper LHS of parallelogram + refr, // out: ref pos of lower RHS of parallelogram + st, // out: legal starting columns stored here + en); // out: legal ending columns stored here + assert_eq(ex_width, width); + assert_eq(ex_trimup, trimup); + assert_eq(ex_trimdn, trimdn); + assert_eq(ex_refl, refl); + assert_eq(ex_refr, refr); + for(size_t i = 0; i < width; i++) { + assert_eq((ex_st[i] == '1'), st[i]); + assert_eq((ex_en[i] == '1'), en[i]); + } + cerr << "PASSED" << endl; +} + +int main(void) { + + /////////////////////////// + // + // ANCHOR ON THE LEFT + // + /////////////////////////// + + // ------------- + // o o + // o o + // o o + // o o + // <<<------->>> + // 012345678901234567890 + // 0 1 2 + testCaseFindMateAnchorLeft( + "FindMateAnchorLeft1", + false, // trim to reference + 3, // left offset of upper parallelogram extent + 15, // right offset of upper parallelogram extent + 10, // left offset of lower parallelogram extent + 16, // right offset of lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 3, // max # of read gaps permitted in opp mate alignment + 3, // max # of ref gaps permitted in opp mate alignment + 13, // expected width + 0, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 3, // ref offset of upstream column + 19, // ref offset of downstream column + "1111111111111", // expected starting bools + "0001111111000"); // expected ending bools + + // ******* + // <<===----- + // o o + // o o + // o o + // o o + // <<=----->> + // ******* + // 012345678901234567890 + // 0 1 2 + testCaseFindMateAnchorLeft( + "FindMateAnchorLeft2", + false, // trim to reference + 9, // left offset of left upper parallelogram extent + 14, // right offset of left upper parallelogram extent + 10, // left offset of left lower parallelogram extent + 15, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 7, // expected width + 3, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 7, // ref offset of upstream column + 17, // ref offset of downstream column + "0011111", // expected starting bools + "1111100"); // expected ending bools + + // ******* + // <<===--->> + // o o + // o o + // o o + // o o + // o o + // <<=----->> + // ******* + // 01234567890123456xxxx + // 0 1 2 + testCaseFindMateAnchorLeft( + "FindMateAnchorLeft3", + true, // trim to reference + 9, // left offset of left upper parallelogram extent + 14, // right offset of left upper parallelogram extent + 10, // left offset of left lower parallelogram extent + 15, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 17, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 7, // expected width + 3, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 7, // ref offset of upstream column + 17, // ref offset of downstream column + "0011111", // expected starting bools + "1111100"); // expected ending bools + + // ****** + // <<===----- + // o o + // o o + // o o + // o o + // <<=----=>> + // ****** + // 012345678901234xxxxxx + // 0 1 2 + testCaseFindMateAnchorLeft( + "FindMateAnchorLeft4", + true, // trim to reference + 9, // left offset of left upper parallelogram extent + 14, // right offset of left upper parallelogram extent + 10, // left offset of left lower parallelogram extent + 15, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 15, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 6, // expected width + 3, // expected # bases trimmed from upstream end + 1, // expected # bases trimmed from downstream end + 7, // ref offset of upstream column + 16, // ref offset of downstream column + "001111", // expected starting bools + "111100"); // expected ending bools + + // -1 0 2 + // xxxxxxxxxx012345678xx + // + // ******* + // <<===----- + // o o + // o o + // o o + // o o + // o o + // <<=----->> + // ******* + // + // xxxxxxxxxx012345678xx + // -1 0 2 + testCaseFindMateAnchorLeft( + "FindMateAnchorLeft5", + true, // trim to reference + 1, // left offset of left upper parallelogram extent + 7, // right offset of left upper parallelogram extent + 2, // left offset of left lower parallelogram extent + 7, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 9, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 7, // expected width + 3, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + -1, // ref offset of upstream column + 9, // ref offset of downstream column + "0011111", // expected starting bools + "1111100"); // expected ending bools + + // <<<<==-===>> + // o o + // o o + // o o + // o o + // <<<<------>> + // ****** + // 012345678901234567890 + // 0 1 2 + testCaseFindMateAnchorLeft( + "FindMateAnchorLeft6", + false, // trim to reference + 8, // left offset of left upper parallelogram extent + 8, // right offset of left upper parallelogram extent + 10, // left offset of left lower parallelogram extent + 15, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 4, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 6, // expected width + 4, // expected # bases trimmed from upstream end + 2, // expected # bases trimmed from downstream end + 6, // ref offset of upstream column + 15, // ref offset of downstream column + "001000", // expected starting bools + "111111"); // expected ending bools + + /////////////////////////// + // + // ANCHOR ON THE RIGHT + // + /////////////////////////// + + // <<<------->>> + // o o + // o o + // o o + // o o + // <<<------->>> + // 012345678901234567890123456789 + // 0 1 2 + testCaseFindMateAnchorRight( + "FindMateAnchorRight1", + false, // trim to reference + 10, // left offset of left upper parallelogram extent + 16, // right offset of left upper parallelogram extent + 11, // left offset of left lower parallelogram extent + 23, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 3, // max # of read gaps permitted in opp mate alignment + 3, // max # of ref gaps permitted in opp mate alignment + 13, // expected width + 0, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 7, // ref offset of upstream column + 23, // ref offset of downstream column + "0001111111000", // expected starting bools + "1111111111111"); // expected ending bools + + // 0 1 2 + // 012345678901234567890 + // ******* + // <<------>> + // o o + // o o + // o o + // o o + // <<===--->> + // ******* + // 012345678901234567890 + // 0 1 2 + testCaseFindMateAnchorRight( + "FindMateAnchorRight2", + false, // trim to reference + 6, // left offset of left upper parallelogram extent + 11, // right offset of left upper parallelogram extent + 13, // left offset of left lower parallelogram extent + 18, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 7, // expected width + 3, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 7, // ref offset of upstream column + 17, // ref offset of downstream column + "1111100", // expected starting bools + "0011111"); // expected ending bools + + // Reference trimming takes off the left_pad of the left mate + // + // ******* + // <<------>> + // o o + // o o + // o o + // o o + // o o + // <<===--->> + // ******* + // 0123456789012345678901234567890 + // -1 0 1 2 + testCaseFindMateAnchorRight( + "FindMateAnchorRight3", + true, // trim to reference + 0, // left offset of left upper parallelogram extent + 5, // right offset of left upper parallelogram extent + 7, // left offset of left lower parallelogram extent + 11, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 7, // expected width + 3, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 1, // ref offset of upstream column + 11, // ref offset of downstream column + "1111100", // expected starting bools + "0011111"); // expected ending bools + + // Reference trimming takes off the leftmost 5 positions of the left mate, + // and takes 1 from the right mate + // + // ***** + // <<------>> + // o o + // o o + // o o + // o o + // o o + // <<===--->> + // ***** + // 0987654321012345678901234567890 + // -1 0 1 2 + testCaseFindMateAnchorRight( + "FindMateAnchorRight4", + true, // trim to reference + -3, // left offset of left upper parallelogram extent + 2, // right offset of left upper parallelogram extent + 4, // left offset of left lower parallelogram extent + 10, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 5, // expected width + 5, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 0, // ref offset of upstream column + 8, // ref offset of downstream column + "11100", // expected starting bools + "11111"); // expected ending bools + + // Reference trimming takes off the leftmost 5 positions of the left mate, + // and takes 1 from the left of the right mate. Also, it takes 2 from the + // right of the right mate. + // + // *** + // <<------>> + // o o + // o o + // o o + // o o + // o o + // <<===--->> + // *** + // 0987654321012345678901234567890 + // -1 0 1 2 + testCaseFindMateAnchorRight( + "FindMateAnchorRight5", + true, // trim to reference + -3, // left offset of left upper parallelogram extent + 2, // right offset of left upper parallelogram extent + 4, // left offset of left lower parallelogram extent + 10, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 7, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 3, // expected width + 5, // expected # bases trimmed from upstream end + 2, // expected # bases trimmed from downstream end + 0, // ref offset of upstream column + 6, // ref offset of downstream column + "111", // expected starting bools + "111"); // expected ending bools + + // ****** + // <<------>>>> + // o o + // o o + // o o + // o o + // <<====-=>>>> + // ****** + // 012345678901234567890 + // 0 1 2 + testCaseFindMateAnchorRight( + "FindMateAnchorRight6", + false, // trim to reference + 6, // left offset of left upper parallelogram extent + 11, // right offset of left upper parallelogram extent + 14, // left offset of left lower parallelogram extent + 14, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 4, // max # of read gaps permitted in opp mate alignment + 2, // max # of ref gaps permitted in opp mate alignment + 6, // expected width + 2, // expected # bases trimmed from upstream end + 4, // expected # bases trimmed from downstream end + 6, // ref offset of upstream column + 15, // ref offset of downstream column + "111111", // expected starting bools + "000010"); // expected ending bools + + // **** + // <<<<==---->> + // o o + // o o + // o o + // o o + // o o + // <<<<====-=>> + // **** + // 012345678901234567890 + // 0 1 2 + testCaseFindMateAnchorRight( + "FindMateAnchorRight7", + false, // trim to reference + 6, // left offset of left upper parallelogram extent + 11, // right offset of left upper parallelogram extent + 14, // left offset of left lower parallelogram extent + 14, // right offset of left lower parallelogram extent + 5, // length of opposite mate + 30, // length of reference sequence aligned to + 2, // max # of read gaps permitted in opp mate alignment + 4, // max # of ref gaps permitted in opp mate alignment + 4, // expected width + 6, // expected # bases trimmed from upstream end + 2, // expected # bases trimmed from downstream end + 8, // ref offset of upstream column + 15, // ref offset of downstream column + "1111", // expected starting bools + "0010"); // expected ending bools + + testCaseFindMateAnchorRight( + "FindMateAnchorRight8", + true, // trim to reference + -37, // left offset of left upper parallelogram extent + 13, // right offset of left upper parallelogram extent + -37, // left offset of left lower parallelogram extent + 52, // right offset of left lower parallelogram extent + 10, // length of opposite mate + 53, // length of reference sequence aligned to + 0, // max # of read gaps permitted in opp mate alignment + 0, // max # of ref gaps permitted in opp mate alignment + 14, // expected width + 37, // expected # bases trimmed from upstream end + 0, // expected # bases trimmed from downstream end + 0, // ref offset of upstream column + 22, // ref offset of downstream column + "11111111111111", // expected starting bools + "11111111111111");// expected ending bools +} + +#endif /*def MAIN_DP_FRAMER*/ diff --git a/dp_framer.h b/dp_framer.h new file mode 100644 index 0000000..4209f41 --- /dev/null +++ b/dp_framer.h @@ -0,0 +1,261 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* + * dp_framer.h + * + * Classes and routines for framing dynamic programming problems. There are 2 + * basic types of dynamic programming problems solved in Bowtie 2: + * + * 1. Seed extension: we found a seed hit using Burrows-Wheeler techniques and + * now we would like to extend it into a full alignment by doing dynamic + * programming in the vicinity of the seed hit. + * + * 2. Mate finding: we would a full alignment for one mate in a pair and now we + * would like to extend it into a full alignment by doing dynamic + * programming in the area prescribed by the maximum and minimum fragment + * lengths. + * + * By "framing" the dynamic programming problem, we mean that all of the + * following DP inputs are calculated: + * + * 1. The width of the parallelogram/rectangle to explore. + * 2. The 0-based offset of the reference position associated with the leftmost + * diagnomal/column in the parallelogram/rectangle to explore + * 3. An EList of length=width encoding which columns the alignment may + * start in + * 4. An EList of length=width encoding which columns the alignment may + * end in + */ + +#ifndef DP_FRAMER_H_ +#define DP_FRAMER_H_ + +#include +#include "ds.h" +#include "ref_coord.h" + +/** + * Describes a dynamic programming rectangle. + * + * Only knows about reference offsets, not reference sequences. + */ +struct DPRect { + + DPRect(int cat = 0) /*: st(cat), en(cat)*/ { + refl = refr = triml = trimr = corel = corer = 0; + } + + int64_t refl; // leftmost ref offset involved post trimming (incl) + int64_t refr; // rightmost ref offset involved post trimming (incl) + + int64_t refl_pretrim; // leftmost ref offset involved pre trimming (incl) + int64_t refr_pretrim; // rightmost ref offset involved pre trimming (incl) + + size_t triml; // positions trimmed from LHS + size_t trimr; // positions trimmed from RHS + + // If "core" diagonals are specified, then any alignment reported has to + // overlap one of the core diagonals. This is to avoid the situation where + // an alignment is reported that overlaps a better-scoring alignment that + // falls partially outside the rectangle. This is used in both seed + // extensions and in mate finding. Filtering based on the core diagonals + // should happen in the backtrace routine. I.e. it should simply never + // return an alignment that doesn't overlap a core diagonal, even if there + // is such an alignment and it's valid. + + size_t corel; // offset of column where leftmost "core" diagonal starts + size_t corer; // offset of column where rightmost "core" diagonal starts + // [corel, corer] is an inclusive range and offsets are with respect to the + // original, untrimmed rectangle. + + size_t maxgap; // max # gaps - width of the gap bands + + /** + * Return true iff the combined effect of triml and trimr is to trim away + * the entire rectangle. + */ + bool entirelyTrimmed() const { + bool tr = refr < refl; + ASSERT_ONLY(size_t width = (size_t)(refr_pretrim - refl_pretrim + 1)); + assert(tr == (width <= triml + trimr)); + return tr; + } + +#ifndef NDEBUG + bool repOk() const { + assert_geq(corer, corel); + return true; + } +#endif + + /** + * Set the given interval to the range of diagonals that are "covered" by + * this dynamic programming problem. + */ + void initIval(Interval& iv) { + iv.setOff(refl_pretrim + (int64_t)corel); + iv.setLen(corer - corel + 1); + } +}; + +/** + * Encapsulates routines for calculating parameters for the various types of + * dynamic programming problems solved in Bowtie2. + */ +class DynProgFramer { + +public: + + DynProgFramer(bool trimToRef) : trimToRef_(trimToRef) { } + + /** + * Similar to frameSeedExtensionParallelogram but we're being somewhat more + * inclusive in order to ensure all characters aling the "width" in the last + * row are exhaustively scored. + */ + bool frameSeedExtensionRect( + int64_t off, // ref offset implied by seed hit assuming no gaps + size_t rdlen, // length of read sequence used in DP table (so len + // of +1 nucleotide sequence for colorspace reads) + int64_t reflen, // length of reference sequence aligned to + size_t maxrdgap, // max # of read gaps permitted in opp mate alignment + size_t maxrfgap, // max # of ref gaps permitted in opp mate alignment + int64_t maxns, // # Ns permitted + size_t maxhalf, // max width in either direction + DPRect& rect); // out: DP rectangle + + /** + * Given information about an anchor mate hit, and information deduced by + * PairedEndPolicy about where the opposite mate can begin and start given + * the fragment length range, return parameters for the dynamic programming + * problem to solve. + */ + bool frameFindMateRect( + bool anchorLeft, // true iff anchor alignment is to the left + int64_t ll, // leftmost Watson off for LHS of opp alignment + int64_t lr, // rightmost Watson off for LHS of opp alignment + int64_t rl, // leftmost Watson off for RHS of opp alignment + int64_t rr, // rightmost Watson off for RHS of opp alignment + size_t rdlen, // length of opposite mate + int64_t reflen, // length of reference sequence aligned to + size_t maxrdgap, // max # of read gaps permitted in opp mate alignment + size_t maxrfgap, // max # of ref gaps permitted in opp mate alignment + int64_t maxns, // max # Ns permitted + size_t maxhalf, // max width in either direction + DPRect& rect) // out: DP rectangle + const + { + if(anchorLeft) { + return frameFindMateAnchorLeftRect( + ll, + lr, + rl, + rr, + rdlen, + reflen, + maxrdgap, + maxrfgap, + maxns, + maxhalf, + rect); + } else { + return frameFindMateAnchorRightRect( + ll, + lr, + rl, + rr, + rdlen, + reflen, + maxrdgap, + maxrfgap, + maxns, + maxhalf, + rect); + } + } + + /** + * Given information about an anchor mate hit, and information deduced by + * PairedEndPolicy about where the opposite mate can begin and start given + * the fragment length range, return parameters for the dynamic programming + * problem to solve. + */ + bool frameFindMateAnchorLeftRect( + int64_t ll, // leftmost Watson off for LHS of opp alignment + int64_t lr, // rightmost Watson off for LHS of opp alignment + int64_t rl, // leftmost Watson off for RHS of opp alignment + int64_t rr, // rightmost Watson off for RHS of opp alignment + size_t rdlen, // length of opposite mate + int64_t reflen, // length of reference sequence aligned to + size_t maxrdgap, // max # of read gaps permitted in opp mate alignment + size_t maxrfgap, // max # of ref gaps permitted in opp mate alignment + int64_t maxns, // max # Ns permitted in alignment + size_t maxhalf, // max width in either direction + DPRect& rect) // out: DP rectangle + const; + + /** + * Given information about an anchor mate hit, and information deduced by + * PairedEndPolicy about where the opposite mate can begin and start given + * the fragment length range, return parameters for the dynamic programming + * problem to solve. + */ + bool frameFindMateAnchorRightRect( + int64_t ll, // leftmost Watson off for LHS of opp alignment + int64_t lr, // rightmost Watson off for LHS of opp alignment + int64_t rl, // leftmost Watson off for RHS of opp alignment + int64_t rr, // rightmost Watson off for RHS of opp alignment + size_t rdlen, // length of opposite mate + int64_t reflen, // length of reference sequence aligned to + size_t maxrdgap, // max # of read gaps permitted in opp mate alignment + size_t maxrfgap, // max # of ref gaps permitted in opp mate alignment + int64_t maxns, // max # Ns permitted in alignment + size_t maxhalf, // max width in either direction + DPRect& rect) // out: DP rectangle + const; + +protected: + + /** + * Trim the given parallelogram width and reference window so that neither + * overhangs the beginning or end of the reference. Return true if width + * is still > 0 after trimming, otherwise return false. + */ + void trimToRef( + size_t reflen, // in: length of reference sequence aligned to + int64_t& refl, // in/out: ref pos of upper LHS of parallelogram + int64_t& refr, // in/out: ref pos of lower RHS of parallelogram + size_t& trimup, // out: number of bases trimmed from upstream end + size_t& trimdn) // out: number of bases trimmed from downstream end + { + if(refl < 0) { + trimup = (size_t)(-refl); + //refl = 0; + } + if(refr >= (int64_t)reflen) { + trimdn = (size_t)(refr - reflen + 1); + //refr = (int64_t)reflen-1; + } + } + + bool trimToRef_; +}; + +#endif /*ndef DP_FRAMER_H_*/ diff --git a/ds.cpp b/ds.cpp new file mode 100644 index 0000000..35bdaac --- /dev/null +++ b/ds.cpp @@ -0,0 +1,155 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "ds.h" + +extern MemoryTally gMemTally; + +/** + * Tally a memory allocation of size amt bytes. + */ +void MemoryTally::add(int cat, uint64_t amt) { + ThreadSafe ts(&mutex_m); + tots_[cat] += amt; + tot_ += amt; + if(tots_[cat] > peaks_[cat]) { + peaks_[cat] = tots_[cat]; + } + if(tot_ > peak_) { + peak_ = tot_; + } +} + +/** + * Tally a memory free of size amt bytes. + */ +void MemoryTally::del(int cat, uint64_t amt) { + ThreadSafe ts(&mutex_m); + assert_geq(tots_[cat], amt); + assert_geq(tot_, amt); + tots_[cat] -= amt; + tot_ -= amt; +} + +#ifdef MAIN_DS + +#include +#include "random_source.h" + +using namespace std; + +int main(void) { + cerr << "Test EHeap 1..."; + { + EHeap h; + h.insert(0.5f); // 1 + h.insert(0.6f); // 2 + h.insert(0.25f); // 3 + h.insert(0.75f); // 4 + h.insert(0.1f); // 5 + h.insert(0.9f); // 6 + h.insert(0.4f); // 7 + assert_eq(7, h.size()); + if(h.pop() != 0.1f) { + throw 1; + } + assert_eq(6, h.size()); + if(h.pop() != 0.25f) { + throw 1; + } + assert_eq(5, h.size()); + if(h.pop() != 0.4f) { + throw 1; + } + assert_eq(4, h.size()); + if(h.pop() != 0.5f) { + throw 1; + } + assert_eq(3, h.size()); + if(h.pop() != 0.6f) { + throw 1; + } + assert_eq(2, h.size()); + if(h.pop() != 0.75f) { + throw 1; + } + assert_eq(1, h.size()); + if(h.pop() != 0.9f) { + throw 1; + } + assert_eq(0, h.size()); + assert(h.empty()); + } + cerr << "PASSED" << endl; + + cerr << "Test EHeap 2..."; + { + EHeap h; + RandomSource rnd(12); + size_t lim = 2000; + while(h.size() < lim) { + h.insert(rnd.nextU32()); + } + size_t last = std::numeric_limits::max(); + bool first = true; + while(!h.empty()) { + size_t p = h.pop(); + assert(first || p >= last); + last = p; + first = false; + } + } + cerr << "PASSED" << endl; + + cerr << "Test EBitList 1..."; + { + EBitList<128> l; + assert_eq(0, l.size()); + assert_eq(std::numeric_limits::max(), l.max()); + + assert(!l.test(0)); + assert(!l.test(1)); + assert(!l.test(10)); + + for(int i = 0; i < 3; i++) { + l.set(10); + assert(!l.test(0)); + assert(!l.test(1)); + assert(!l.test(9)); + assert(l.test(10)); + assert(!l.test(11)); + } + + assert_eq(10, l.max()); + l.clear(); + assert(!l.test(10)); + assert_eq(std::numeric_limits::max(), l.max()); + + RandomSource rnd(12); + size_t lim = 2000; + for(size_t i = 0; i < lim; i++) { + uint32_t ri = rnd.nextU32() % 10000; + l.set(ri); + assert(l.test(ri)); + } + } + cerr << "PASSED" << endl; +} + +#endif /*def MAIN_SSTRING*/ diff --git a/ds.h b/ds.h new file mode 100644 index 0000000..dce3054 --- /dev/null +++ b/ds.h @@ -0,0 +1,4397 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef DS_H_ +#define DS_H_ + +#include +#include +#include +#include +#include +#include +#include "assert_helpers.h" +#include "threading.h" +#include "random_source.h" +#include "btypes.h" +//added by Joe Paggi to implement EList.push_back_array +#include + +/** + * Tally how much memory is allocated to certain + */ +class MemoryTally { + +public: + + MemoryTally() : tot_(0), peak_(0) { + memset(tots_, 0, 256 * sizeof(uint64_t)); + memset(peaks_, 0, 256 * sizeof(uint64_t)); + } + + /** + * Tally a memory allocation of size amt bytes. + */ + void add(int cat, uint64_t amt); + + /** + * Tally a memory free of size amt bytes. + */ + void del(int cat, uint64_t amt); + + /** + * Return the total amount of memory allocated. + */ + uint64_t total() { return tot_; } + + /** + * Return the total amount of memory allocated in a particular + * category. + */ + uint64_t total(int cat) { return tots_[cat]; } + + /** + * Return the peak amount of memory allocated. + */ + uint64_t peak() { return peak_; } + + /** + * Return the peak amount of memory allocated in a particular + * category. + */ + uint64_t peak(int cat) { return peaks_[cat]; } + +#ifndef NDEBUG + /** + * Check that memory tallies are internally consistent; + */ + bool repOk() const { + uint64_t tot = 0; + for(int i = 0; i < 256; i++) { + assert_leq(tots_[i], peaks_[i]); + tot += tots_[i]; + } + assert_eq(tot, tot_); + return true; + } +#endif + +protected: + + MUTEX_T mutex_m; + uint64_t tots_[256]; + uint64_t tot_; + uint64_t peaks_[256]; + uint64_t peak_; +}; + +extern MemoryTally gMemTally; + +/** + * A simple fixed-length array of type T, automatically freed in the + * destructor. + */ +template +class AutoArray { +public: + + AutoArray(size_t sz, int cat = 0) : cat_(cat) { + t_ = NULL; + t_ = new T[sz]; + gMemTally.add(cat_, sz); + memset(t_, 0, sz * sizeof(T)); + sz_ = sz; + } + + ~AutoArray() { + if(t_ != NULL) { + delete[] t_; + gMemTally.del(cat_, sz_); + } + } + + T& operator[](size_t sz) { + return t_[sz]; + } + + const T& operator[](size_t sz) const { + return t_[sz]; + } + + size_t size() const { return sz_; } + +private: + int cat_; + T *t_; + size_t sz_; +}; + +/** + * A wrapper for a non-array pointer that associates it with a memory + * category for tracking purposes and calls delete on it when the + * PtrWrap is destroyed. + */ +template +class PtrWrap { +public: + + explicit PtrWrap( + T* p, + bool freeable = true, + int cat = 0) : + cat_(cat), + p_(NULL) + { + init(p, freeable); + } + + explicit PtrWrap(int cat = 0) : + cat_(cat), + p_(NULL) + { + reset(); + } + + void reset() { + free(); + init(NULL); + } + + ~PtrWrap() { free(); } + + void init(T* p, bool freeable = true) { + assert(p_ == NULL); + p_ = p; + freeable_ = freeable; + if(p != NULL && freeable_) { + gMemTally.add(cat_, sizeof(T)); + } + } + + void free() { + if(p_ != NULL) { + if(freeable_) { + delete p_; + gMemTally.del(cat_, sizeof(T)); + } + p_ = NULL; + } + } + + inline T* get() { return p_; } + inline const T* get() const { return p_; } + +private: + int cat_; + T *p_; + bool freeable_; +}; + +/** + * A wrapper for an array pointer that associates it with a memory + * category for tracking purposes and calls delete[] on it when the + * PtrWrap is destroyed. + */ +template +class APtrWrap { +public: + + explicit APtrWrap( + T* p, + size_t sz, + bool freeable = true, + int cat = 0) : + cat_(cat), + p_(NULL) + { + init(p, sz, freeable); + } + + explicit APtrWrap(int cat = 0) : + cat_(cat), + p_(NULL) + { + reset(); + } + + void reset() { + free(); + init(NULL, 0); + } + + ~APtrWrap() { free(); } + + void init(T* p, size_t sz, bool freeable = true) { + assert(p_ == NULL); + p_ = p; + sz_ = sz; + freeable_ = freeable; + if(p != NULL && freeable_) { + gMemTally.add(cat_, sizeof(T) * sz_); + } + } + + void free() { + if(p_ != NULL) { + if(freeable_) { + delete[] p_; + gMemTally.del(cat_, sizeof(T) * sz_); + } + p_ = NULL; + } + } + + inline T* get() { return p_; } + inline const T* get() const { return p_; } + +private: + int cat_; + T *p_; + bool freeable_; + size_t sz_; +}; + +/** + * An EList is an expandable list with these features: + * + * - Payload type is a template parameter T. + * - Initial size can be specified at construction time, otherwise + * default of 128 is used. + * - When allocated initially or when expanding, the new[] operator is + * used, which in turn calls the default constructor for T. + * - All copies (e.g. assignment of a const T& to an EList element, + * or during expansion) use operator=. + * - When the EList is resized to a smaller size (or cleared, which + * is like resizing to size 0), the underlying containing is not + * reshaped. Thus, EListss never release memory before + * destruction. + * + * And these requirements: + * + * - Payload type T must have a default constructor. + * + * For efficiency reasons, ELists should not be declared on the stack + * in often-called worker functions. Best practice is to declare + * ELists at a relatively stable layer of the stack (such that it + * rarely bounces in and out of scope) and let the worker function use + * it and *expand* it only as needed. The effect is that only + * relatively few allocations and copies will be incurred, and they'll + * occur toward the beginning of the computation before stabilizing at + * a "high water mark" for the remainder of the computation. + * + * A word about multidimensional lists. One way to achieve a + * multidimensional lists is to nest ELists. This works, but it often + * involves a lot more calls to the default constructor and to + * operator=, especially when the outermost EList needs expanding, than + * some of the alternatives. One alternative is use a most specialized + * container that still uses ELists but knows to use xfer instead of + * operator= when T=EList. + * + * The 'cat_' fiends encodes a category. This makes it possible to + * distinguish between object subgroups in the global memory tally. + * + * Memory allocation is lazy. Allocation is only triggered when the + * user calls push_back, expand, resize, or another function that + * increases the size of the list. This saves memory and also makes it + * easier to deal with nested ELists, since the default constructor + * doesn't set anything in stone. + */ +template +class EList { + +public: + + /** + * Allocate initial default of S elements. + */ + explicit EList() : + cat_(0), allocCat_(-1), list_(NULL), sz_(S), cur_(0) { } + + /** + * Allocate initial default of S elements. + */ + explicit EList(int cat) : + cat_(cat), allocCat_(-1), list_(NULL), sz_(S), cur_(0) + { + assert_geq(cat, 0); + } + + /** + * Initially allocate given number of elements; should be > 0. + */ + explicit EList(size_t isz, int cat = 0) : + cat_(cat), allocCat_(-1), list_(NULL), sz_(isz), cur_(0) + { + assert_geq(cat, 0); + } + + /** + * Copy from another EList using operator=. + */ + EList(const EList& o) : + cat_(0), allocCat_(-1), list_(NULL), sz_(0), cur_(0) + { + *this = o; + } + + /** + * Copy from another EList using operator=. + */ + explicit EList(const EList& o, int cat) : + cat_(cat), allocCat_(-1), list_(NULL), sz_(0), cur_(0) + { + *this = o; + assert_geq(cat, 0); + } + + /** + * Destructor. + */ + ~EList() { free(); } + + /** + * Make this object into a copy of o by allocat + */ + EList& operator=(const EList& o) { + assert_eq(cat_, o.cat()); + if(o.cur_ == 0) { + // Nothing to copy + cur_ = 0; + return *this; + } + if(list_ == NULL) { + // cat_ should already be set + lazyInit(); + } + if(sz_ < o.cur_) expandNoCopy(o.cur_ + 1); + assert_geq(sz_, o.cur_); + cur_ = o.cur_; + for(size_t i = 0; i < cur_; i++) { + list_[i] = o.list_[i]; + } + return *this; + } + + /** + * Transfer the guts of another EList into this one without using + * operator=, etc. We have to set EList o's list_ field to NULL to + * avoid o's destructor from deleting list_ out from under us. + */ + void xfer(EList& o) { + // What does it mean to transfer to a different-category list? + assert_eq(cat_, o.cat()); + // Can only transfer into an empty object + free(); + allocCat_ = cat_; + list_ = o.list_; + sz_ = o.sz_; + cur_ = o.cur_; + o.list_ = NULL; + o.sz_ = o.cur_ = 0; + o.allocCat_ = -1; + } + //Added by Joe + void swap(EList& o) { + assert_eq(cat_, o.cat()); + T* temp_l = list_; + size_t temp_sz = sz_; + size_t temp_cur = cur_; + list_ = o.list_; + sz_ = o.sz_; + cur_ = o.cur_; + o.list_ = temp_l; + o.sz_ = temp_sz; + o.cur_ = temp_cur; + } + + /** + * Return number of elements. + */ + inline size_t size() const { return cur_; } + + /** + * Return number of elements allocated. + */ + inline size_t capacity() const { return sz_; } + + /** + * Return the total size in bytes occupied by this list. + */ + size_t totalSizeBytes() const { + return 2 * sizeof(int) + + 2 * sizeof(size_t) + + cur_ * sizeof(T); + } + + /** + * Return the total capacity in bytes occupied by this list. + */ + size_t totalCapacityBytes() const { + return 2 * sizeof(int) + + 2 * sizeof(size_t) + + sz_ * sizeof(T); + } + + /** + * Ensure that there is sufficient capacity to expand to include + * 'thresh' more elements without having to expand. + */ + inline void ensure(size_t thresh) { + if(list_ == NULL) lazyInit(); + expandCopy(cur_ + thresh); + } + + /** + * Ensure that there is sufficient capacity to include 'newsz' elements. + * If there isn't enough capacity right now, expand capacity to exactly + * equal 'newsz'. + */ + inline void reserveExact(size_t newsz) { + if(list_ == NULL) lazyInitExact(newsz); + expandCopyExact(newsz); + } + + /** + * Return true iff there are no elements. + */ + inline bool empty() const { return cur_ == 0; } + + /** + * Return true iff list hasn't been initialized yet. + */ + inline bool null() const { return list_ == NULL; } + + /** + * Add an element to the back and immediately initialize it via + * operator=. + */ + void push_back(const T& el) { + if(list_ == NULL) lazyInit(); + if(cur_ == sz_) expandCopy(sz_+1); + list_[cur_++] = el; + } + + void nullify() { + free(); + } + + + /** + * Add an element to the back. No intialization is done. + */ + void expand() { + if(list_ == NULL) lazyInit(); + if(cur_ == sz_) expandCopy(sz_+1); + cur_++; + } + + /** + * Add an element to the back. No intialization is done. + */ + void fill(size_t begin, size_t end, const T& v) { + assert_leq(begin, end); + assert_leq(end, cur_); + for(size_t i = begin; i < end; i++) { + list_[i] = v; + } + } + + /** + * Add an element to the back. No intialization is done. + */ + void fill(const T& v) { + for(size_t i = 0; i < cur_; i++) { + list_[i] = v; + } + } + + /** + * Set all bits in specified range of elements in list array to 0. + */ + void fillZero(size_t begin, size_t end) { + assert_leq(begin, end); + memset(&list_[begin], 0, sizeof(T) * (end-begin)); + } + + /** + * Set all bits in the list array to 0. + */ + void fillZero() { + memset(list_, 0, sizeof(T) * cur_); + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resizeNoCopy(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) expandNoCopy(sz); + cur_ = sz; + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resizeNoCopyExact(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) expandNoCopyExact(sz); + cur_ = sz; + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resize(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) { + expandCopy(sz); + } + cur_ = sz; + } + + /** + * If size is less than requested size, resize up to exactly sz and set + * cur_ to requested sz. + */ + void resizeExact(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInitExact(sz); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) expandCopyExact(sz); + cur_ = sz; + } + + /** + * Erase element at offset idx. + */ + void erase(size_t idx) { + assert_lt(idx, cur_); + for(size_t i = idx; i < cur_-1; i++) { + list_[i] = list_[i+1]; + } + cur_--; + } + + /** + * Erase range of elements starting at offset idx and going for len. + */ + void erase(size_t idx, size_t len) { + assert_geq(len, 0); + if(len == 0) { + return; + } + assert_lt(idx, cur_); + for(size_t i = idx; i < cur_-len; i++) { + list_[i] = list_[i+len]; + } + cur_ -= len; + } + + /** + * Insert value 'el' at offset 'idx' + */ + void insert(const T& el, size_t idx) { + if(list_ == NULL) lazyInit(); + assert_leq(idx, cur_); + if(cur_ == sz_) expandCopy(sz_+1); + for(size_t i = cur_; i > idx; i--) { + list_[i] = list_[i-1]; + } + list_[idx] = el; + cur_++; + } + + /** + * Insert contents of list 'l' at offset 'idx' + */ + void insert(const EList& l, size_t idx) { + if(list_ == NULL) lazyInit(); + assert_lt(idx, cur_); + if(l.cur_ == 0) return; + if(cur_ + l.cur_ > sz_) expandCopy(cur_ + l.cur_); + for(size_t i = cur_ + l.cur_ - 1; i > idx + (l.cur_ - 1); i--) { + list_[i] = list_[i - l.cur_]; + } + for(size_t i = 0; i < l.cur_; i++) { + list_[i+idx] = l.list_[i]; + } + cur_ += l.cur_; + } + + /** + * push first l_size objects of T array l to top of stack + * added by Joe Paggi + */ + void push_back_array(const T* l, size_t l_size) { + if(list_ == NULL) lazyInit(); + if(l_size == 0) return; + if(cur_ + l_size > sz_) expandCopy(cur_ + l_size); + size_t bytes = l_size * sizeof(T); + std::memcpy(list_ + cur_, l, bytes); + cur_ += l_size; + } + + /** + * Remove an element from the top of the stack. + */ + void pop_back() { + assert_gt(cur_, 0); + cur_--; + } + + /** + * Make the stack empty. + */ + void clear() { + cur_ = 0; // re-use stack memory + // Don't clear heap; re-use it + } + + /** + * Get the element on the top of the stack. + */ + inline T& back() { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Reverse list elements. + */ + void reverse() { + if(cur_ > 1) { + size_t n = cur_ >> 1; + for(size_t i = 0; i < n; i++) { + T tmp = list_[i]; + list_[i] = list_[cur_ - i - 1]; + list_[cur_ - i - 1] = tmp; + } + } + } + + /** + * Get the element on the top of the stack, const version. + */ + inline const T& back() const { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Get the frontmost element (bottom of stack). + */ + inline T& front() { + assert_gt(cur_, 0); + return list_[0]; + } + + /** + * Get the element on the bottom of the stack, const version. + */ + inline const T& front() const { return front(); } + + inline T* begin() { + assert_gt(cur_, 0); + return &list_[0]; + } + + inline const T* begin() const { return begin(); } + + inline T* end() { return begin() + cur_; } + inline const T* end() const { return begin() + cur_; } + + /** + * Return true iff this list and list o contain the same elements in the + * same order according to type T's operator==. + */ + bool operator==(const EList& o) const { + if(size() != o.size()) { + return false; + } + for(size_t i = 0; i < size(); i++) { + if(!(get(i) == o.get(i))) { + return false; + } + } + return true; + } + + /** + * Return true iff this list contains all of the elements in o according to + * type T's operator==. + */ + bool isSuperset(const EList& o) const { + if(o.size() > size()) { + // This can't be a superset if the other set contains more elts + return false; + } + // For each element in o + for(size_t i = 0; i < o.size(); i++) { + bool inthis = false; + // Check if it's in this + for(size_t j = 0; j < size(); j++) { + if(o[i] == (*this)[j]) { + inthis = true; + break; + } + } + if(!inthis) { + return false; + } + } + return true; + } + + /** + * Return a reference to the ith element. + */ + inline T& operator[](size_t i) { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline const T& operator[](size_t i) const { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline T& get(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. + */ + inline const T& get(size_t i) const { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + T& getSlow(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + const T& getSlow(size_t i) const { + return operator[](i); + } + + /** + * Sort some of the contents. + */ + void sortPortion(size_t begin, size_t num) { + assert_leq(begin+num, cur_); + if(num < 2) return; + std::sort(list_ + begin, list_ + begin + num); + } + + /** + * Shuffle a portion of the list. + */ + void shufflePortion(size_t begin, size_t num, RandomSource& rnd) { + assert_leq(begin+num, cur_); + if(num < 2) return; + size_t left = num; + for(size_t i = begin; i < begin + num - 1; i++) { + uint32_t rndi = rnd.nextU32() % left; + if(rndi > 0) { + std::swap(list_[i], list_[i + rndi]); + } + left--; + } + } + + /** + * Sort contents + */ + void sort() { + sortPortion(0, cur_); + } + + /** + * Return true iff every element is < its successor. Only operator< is + * used. + */ + bool sorted() const { + for(size_t i = 1; i < cur_; i++) { + if(!(list_[i-1] < list_[i])) { + return false; + } + } + return true; + } + + /** + * Delete element at position 'idx'; slide subsequent chars up. + */ + void remove(size_t idx) { + assert_lt(idx, cur_); + assert_gt(cur_, 0); + for(size_t i = idx; i < cur_-1; i++) { + list_[i] = list_[i+1]; + } + cur_--; + } + + /** + * Return a pointer to the beginning of the buffer. + */ + T *ptr() { return list_; } + + /** + * Return a const pointer to the beginning of the buffer. + */ + const T *ptr() const { return list_; } + + /** + * Set the memory category for this object. + */ + void setCat(int cat) { + // What does it mean to set the category after the list_ is + // already allocated? + assert(null()); + assert_gt(cat, 0); cat_ = cat; + } + + /** + * Return memory category. + */ + int cat() const { return cat_; } + + /** + * Perform a binary search for the first element that is not less + * than 'el'. Return cur_ if all elements are less than el. + */ + size_t bsearchLoBound(const T& el) const { + size_t hi = cur_; + size_t lo = 0; + while(true) { + if(lo == hi) { + return lo; + } + size_t mid = lo + ((hi-lo)>>1); + assert_neq(mid, hi); + if(list_[mid] < el) { + if(lo == mid) { + return hi; + } + lo = mid; + } else { + hi = mid; + } + } + } + +private: + + /** + * Initialize memory for EList. + */ + void lazyInit() { + assert(list_ == NULL); + list_ = alloc(sz_); + } + + /** + * Initialize exactly the prescribed number of elements for EList. + */ + void lazyInitExact(size_t sz) { + assert_gt(sz, 0); + assert(list_ == NULL); + sz_ = sz; + list_ = alloc(sz); + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + T *alloc(size_t sz) { + T* tmp = new T[sz]; + assert(tmp != NULL); + gMemTally.add(cat_, sz); + allocCat_ = cat_; + return tmp; + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + void free() { + if(list_ != NULL) { + assert_neq(-1, allocCat_); + assert_eq(allocCat_, cat_); + delete[] list_; + gMemTally.del(cat_, sz_); + list_ = NULL; + sz_ = cur_ = 0; + } + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. Size + * increases quadratically with number of expansions. Copy old contents + * into new buffer using operator=. + */ + void expandCopy(size_t thresh) { + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + expandCopyExact(newsz); + } + + /** + * Expand the list_ buffer until it has exactly 'newsz' elements. Copy + * old contents into new buffer using operator=. + */ + void expandCopyExact(size_t newsz) { + if(newsz <= sz_) return; + T* tmp = alloc(newsz); + assert(tmp != NULL); + size_t cur = cur_; + if(list_ != NULL) { + for(size_t i = 0; i < cur_; i++) { + // Note: operator= is used + tmp[i] = list_[i]; + } + free(); + } + list_ = tmp; + sz_ = newsz; + cur_ = cur; + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Size increases quadratically with number of expansions. Don't copy old + * contents into the new buffer. + */ + void expandNoCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + expandNoCopyExact(newsz); + } + + /** + * Expand the list_ buffer until it has exactly 'newsz' elements. Don't + * copy old contents into the new buffer. + */ + void expandNoCopyExact(size_t newsz) { + assert(list_ != NULL); + assert_gt(newsz, 0); + free(); + T* tmp = alloc(newsz); + assert(tmp != NULL); + list_ = tmp; + sz_ = newsz; + assert_gt(sz_, 0); + } + + int cat_; // memory category, for accounting purposes + int allocCat_; // category at time of allocation + T *list_; // list pointer, returned from new[] + size_t sz_; // capacity + size_t cur_; // occupancy (AKA size) +}; + +/** + * An ELList is an expandable list of lists with these features: + * + * - Payload type of the inner list is a template parameter T. + * - Initial size can be specified at construction time, otherwise + * default of 128 is used. + * - When allocated initially or when expanding, the new[] operator is + * used, which in turn calls the default constructor for EList. + * - Upon expansion, instead of copies, xfer is used. + * - When the ELList is resized to a smaller size (or cleared, + * which is like resizing to size 0), the underlying containing is + * not reshaped. Thus, ELListss never release memory before + * destruction. + * + * And these requirements: + * + * - Payload type T must have a default constructor. + * + */ +template +class ELList { + +public: + + /** + * Allocate initial default of 128 elements. + */ + explicit ELList(int cat = 0) : + cat_(cat), list_(NULL), sz_(S2), cur_(0) + { + assert_geq(cat, 0); + } + + /** + * Initially allocate given number of elements; should be > 0. + */ + explicit ELList(size_t isz, int cat = 0) : + cat_(cat), list_(NULL), sz_(isz), cur_(0) + { + assert_gt(isz, 0); + assert_geq(cat, 0); + } + + /** + * Copy from another ELList using operator=. + */ + ELList(const ELList& o) : + cat_(0), list_(NULL), sz_(0), cur_(0) + { + *this = o; + } + + /** + * Copy from another ELList using operator=. + */ + explicit ELList(const ELList& o, int cat) : + cat_(cat), list_(NULL), sz_(0), cur_(0) + { + *this = o; + assert_geq(cat, 0); + } + + /** + * Destructor. + */ + ~ELList() { free(); } + + /** + * Make this object into a copy of o by allocating enough memory to + * fit the number of elements in o (note: the number of elements + * may be substantially less than the memory allocated in o) and + * using operator= to copy them over. + */ + ELList& operator=(const ELList& o) { + assert_eq(cat_, o.cat()); + if(list_ == NULL) { + lazyInit(); + } + if(o.cur_ == 0) { + cur_ = 0; + return *this; + } + if(sz_ < o.cur_) expandNoCopy(o.cur_ + 1); + assert_geq(sz_, o.cur_); + cur_ = o.cur_; + for(size_t i = 0; i < cur_; i++) { + // Note: using operator=, not xfer + assert_eq(list_[i].cat(), o.list_[i].cat()); + list_[i] = o.list_[i]; + } + return *this; + } + + /** + * Transfer the guts of another EList into this one without using + * operator=, etc. We have to set EList o's list_ field to NULL to + * avoid o's destructor from deleting list_ out from under us. + */ + void xfer(ELList& o) { + assert_eq(cat_, o.cat()); + list_ = o.list_; // list_ is an array of ELists + sz_ = o.sz_; + cur_ = o.cur_; + o.list_ = NULL; + o.sz_ = o.cur_ = 0; + } + + /** + * Return number of elements. + */ + inline size_t size() const { return cur_; } + + /** + * Return true iff there are no elements. + */ + inline bool empty() const { return cur_ == 0; } + + /** + * Return true iff list hasn't been initialized yet. + */ + inline bool null() const { return list_ == NULL; } + + /** + * Add an element to the back. No intialization is done. + */ + void expand() { + if(list_ == NULL) lazyInit(); + if(cur_ == sz_) expandCopy(sz_+1); + cur_++; + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resize(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) { + expandCopy(sz); + } + cur_ = sz; + } + + /** + * Make the stack empty. + */ + void clear() { + cur_ = 0; // re-use stack memory + // Don't clear heap; re-use it + } + + /** + * Get the element on the top of the stack. + */ + inline EList& back() { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Get the element on the top of the stack, const version. + */ + inline const EList& back() const { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Get the frontmost element (bottom of stack). + */ + inline EList& front() { + assert_gt(cur_, 0); + return list_[0]; + } + + /** + * Get the element on the bottom of the stack, const version. + */ + inline const EList& front() const { return front(); } + + /** + * Return a reference to the ith element. + */ + inline EList& operator[](size_t i) { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline const EList& operator[](size_t i) const { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline EList& get(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. + */ + inline const EList& get(size_t i) const { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + EList& getSlow(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + const EList& getSlow(size_t i) const { + return operator[](i); + } + + /** + * Return a pointer to the beginning of the buffer. + */ + EList *ptr() { return list_; } + + /** + * Set the memory category for this object and all children. + */ + void setCat(int cat) { + assert_gt(cat, 0); + cat_ = cat; + if(cat_ != 0) { + for(size_t i = 0; i < sz_; i++) { + assert(list_[i].null()); + list_[i].setCat(cat_); + } + } + } + + /** + * Return memory category. + */ + int cat() const { return cat_; } + +protected: + + /** + * Initialize memory for EList. + */ + void lazyInit() { + assert(list_ == NULL); + list_ = alloc(sz_); + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + EList *alloc(size_t sz) { + assert_gt(sz, 0); + EList *tmp = new EList[sz]; + gMemTally.add(cat_, sz); + if(cat_ != 0) { + for(size_t i = 0; i < sz; i++) { + assert(tmp[i].ptr() == NULL); + tmp[i].setCat(cat_); + } + } + return tmp; + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + void free() { + if(list_ != NULL) { + delete[] list_; + gMemTally.del(cat_, sz_); + list_ = NULL; + } + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. Copy old contents into new buffer + * using operator=. + */ + void expandCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + EList* tmp = alloc(newsz); + if(list_ != NULL) { + for(size_t i = 0; i < cur_; i++) { + assert_eq(cat_, tmp[i].cat()); + tmp[i].xfer(list_[i]); + assert_eq(cat_, tmp[i].cat()); + } + free(); + } + list_ = tmp; + sz_ = newsz; + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. Don't copy old contents over. + */ + void expandNoCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + free(); + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + EList* tmp = alloc(newsz); + list_ = tmp; + sz_ = newsz; + assert_gt(sz_, 0); + } + + int cat_; // memory category, for accounting purposes + EList *list_; // list pointer, returned from new[] + size_t sz_; // capacity + size_t cur_; // occupancy (AKA size) + +}; + +/** + * An ELLList is an expandable list of expandable lists with these + * features: + * + * - Payload type of the innermost list is a template parameter T. + * - Initial size can be specified at construction time, otherwise + * default of 128 is used. + * - When allocated initially or when expanding, the new[] operator is + * used, which in turn calls the default constructor for ELList. + * - Upon expansion, instead of copies, xfer is used. + * - When the ELLList is resized to a smaller size (or cleared, + * which is like resizing to size 0), the underlying containing is + * not reshaped. Thus, ELLListss never release memory before + * destruction. + * + * And these requirements: + * + * - Payload type T must have a default constructor. + * + */ +template +class ELLList { + +public: + + /** + * Allocate initial default of 128 elements. + */ + explicit ELLList(int cat = 0) : + cat_(cat), list_(NULL), sz_(S3), cur_(0) + { + assert_geq(cat, 0); + } + + /** + * Initially allocate given number of elements; should be > 0. + */ + explicit ELLList(size_t isz, int cat = 0) : + cat_(cat), list_(NULL), sz_(isz), cur_(0) + { + assert_geq(cat, 0); + assert_gt(isz, 0); + } + + /** + * Copy from another ELLList using operator=. + */ + ELLList(const ELLList& o) : + cat_(0), list_(NULL), sz_(0), cur_(0) + { + *this = o; + } + + /** + * Copy from another ELLList using operator=. + */ + explicit ELLList(const ELLList& o, int cat) : + cat_(cat), list_(NULL), sz_(0), cur_(0) + { + *this = o; + assert_geq(cat, 0); + } + + /** + * Destructor. + */ + ~ELLList() { free(); } + + /** + * Make this object into a copy of o by allocating enough memory to + * fit the number of elements in o (note: the number of elements + * may be substantially less than the memory allocated in o) and + * using operator= to copy them over. + */ + ELLList& operator=(const ELLList& o) { + assert_eq(cat_, o.cat()); + if(list_ == NULL) lazyInit(); + if(o.cur_ == 0) { + cur_ = 0; + return *this; + } + if(sz_ < o.cur_) expandNoCopy(o.cur_ + 1); + assert_geq(sz_, o.cur_); + cur_ = o.cur_; + for(size_t i = 0; i < cur_; i++) { + // Note: using operator=, not xfer + assert_eq(list_[i].cat(), o.list_[i].cat()); + list_[i] = o.list_[i]; + } + return *this; + } + + /** + * Transfer the guts of another EList into this one without using + * operator=, etc. We have to set EList o's list_ field to NULL to + * avoid o's destructor from deleting list_ out from under us. + */ + void xfer(ELLList& o) { + assert_eq(cat_, o.cat()); + list_ = o.list_; // list_ is an array of ELists + sz_ = o.sz_; + cur_ = o.cur_; + o.list_ = NULL; + o.sz_ = o.cur_ = 0; + } + + /** + * Return number of elements. + */ + inline size_t size() const { return cur_; } + + /** + * Return true iff there are no elements. + */ + inline bool empty() const { return cur_ == 0; } + + /** + * Return true iff list hasn't been initialized yet. + */ + inline bool null() const { return list_ == NULL; } + + /** + * Add an element to the back. No intialization is done. + */ + void expand() { + if(list_ == NULL) lazyInit(); + if(cur_ == sz_) expandCopy(sz_+1); + cur_++; + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resize(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) expandCopy(sz); + cur_ = sz; + } + + /** + * Make the stack empty. + */ + void clear() { + cur_ = 0; // re-use stack memory + // Don't clear heap; re-use it + } + + /** + * Get the element on the top of the stack. + */ + inline ELList& back() { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Get the element on the top of the stack, const version. + */ + inline const ELList& back() const { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Get the frontmost element (bottom of stack). + */ + inline ELList& front() { + assert_gt(cur_, 0); + return list_[0]; + } + + /** + * Get the element on the bottom of the stack, const version. + */ + inline const ELList& front() const { return front(); } + + /** + * Return a reference to the ith element. + */ + inline ELList& operator[](size_t i) { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline const ELList& operator[](size_t i) const { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline ELList& get(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. + */ + inline const ELList& get(size_t i) const { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + ELList& getSlow(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + const ELList& getSlow(size_t i) const { + return operator[](i); + } + + /** + * Return a pointer to the beginning of the buffer. + */ + ELList *ptr() { return list_; } + + /** + * Set the memory category for this object and all children. + */ + void setCat(int cat) { + assert_gt(cat, 0); + cat_ = cat; + if(cat_ != 0) { + for(size_t i = 0; i < sz_; i++) { + assert(list_[i].null()); + list_[i].setCat(cat_); + } + } + } + + /** + * Return memory category. + */ + int cat() const { return cat_; } + +protected: + + /** + * Initialize memory for EList. + */ + void lazyInit() { + assert(null()); + list_ = alloc(sz_); + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + ELList *alloc(size_t sz) { + assert_gt(sz, 0); + ELList *tmp = new ELList[sz]; + gMemTally.add(cat_, sz); + if(cat_ != 0) { + for(size_t i = 0; i < sz; i++) { + assert(tmp[i].ptr() == NULL); + tmp[i].setCat(cat_); + } + } + return tmp; + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + void free() { + if(list_ != NULL) { + delete[] list_; + gMemTally.del(cat_, sz_); + list_ = NULL; + } + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. Copy old contents into new buffer + * using operator=. + */ + void expandCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + ELList* tmp = alloc(newsz); + if(list_ != NULL) { + for(size_t i = 0; i < cur_; i++) { + assert_eq(cat_, tmp[i].cat()); + tmp[i].xfer(list_[i]); + assert_eq(cat_, tmp[i].cat()); + } + free(); + } + list_ = tmp; + sz_ = newsz; + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. Don't copy old contents over. + */ + void expandNoCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + free(); + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + ELList* tmp = alloc(newsz); + list_ = tmp; + sz_ = newsz; + assert_gt(sz_, 0); + } + + int cat_; // memory category, for accounting purposes + ELList *list_; // list pointer, returned from new[] + size_t sz_; // capacity + size_t cur_; // occupancy (AKA size) + +}; + +/** + * Expandable set using a heap-allocated sorted array. + * + * Note that the copy constructor and operator= routines perform + * shallow copies (w/ memcpy). + */ +template +class ESet { +public: + + /** + * Allocate initial default of 128 elements. + */ + ESet(int cat = 0) : + cat_(cat), + list_(NULL), + sz_(0), + cur_(0) + { + if(sz_ > 0) { + list_ = alloc(sz_); + } + } + + /** + * Initially allocate given number of elements; should be > 0. + */ + ESet(size_t isz, int cat = 0) : + cat_(cat), + list_(NULL), + sz_(isz), + cur_(0) + { + assert_gt(isz, 0); + if(sz_ > 0) { + list_ = alloc(sz_); + } + } + + /** + * Copy from another ESet. + */ + ESet(const ESet& o, int cat = 0) : + cat_(cat), list_(NULL) + { + assert_eq(cat_, o.cat()); + *this = o; + } + + /** + * Destructor. + */ + ~ESet() { free(); } + + /** + * Copy contents of given ESet into this ESet. + */ + ESet& operator=(const ESet& o) { + assert_eq(cat_, o.cat()); + sz_ = o.sz_; + cur_ = o.cur_; + free(); + if(sz_ > 0) { + list_ = alloc(sz_); + memcpy(list_, o.list_, cur_ * sizeof(T)); + } else { + list_ = NULL; + } + return *this; + } + + /** + * Return number of elements. + */ + size_t size() const { return cur_; } + + /** + * Return the total size in bytes occupied by this set. + */ + size_t totalSizeBytes() const { + return sizeof(int) + cur_ * sizeof(T) + 2 * sizeof(size_t); + } + + /** + * Return the total capacity in bytes occupied by this set. + */ + size_t totalCapacityBytes() const { + return sizeof(int) + sz_ * sizeof(T) + 2 * sizeof(size_t); + } + + /** + * Return true iff there are no elements. + */ + bool empty() const { return cur_ == 0; } + + /** + * Return true iff list isn't initialized yet. + */ + bool null() const { return list_ == NULL; } + + /** + * Insert a new element into the set in sorted order. + */ + bool insert(const T& el) { + size_t i = 0; + if(cur_ == 0) { + insert(el, 0); + return true; + } + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + if(i < cur_ && list_[i] == el) return false; + insert(el, i); + return true; + } + + /** + * Return true iff this set contains 'el'. + */ + bool contains(const T& el) const { + if(cur_ == 0) { + return false; + } + else if(cur_ == 1) { + return el == list_[0]; + } + size_t i; + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + return i != cur_ && list_[i] == el; + } + + /** + * Remove element from set. + */ + void remove(const T& el) { + size_t i; + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + assert(i != cur_ && list_[i] == el); + erase(i); + } + + /** + * Get + */ + T& get(const T& el) { + size_t i; + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + assert(i != cur_ && list_[i] == el); + return list_[i]; + } + + const T& get(const T& el) const { + size_t i; + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + assert(i != cur_ && list_[i] == el); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline T& operator[](size_t i) { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline const T& operator[](size_t i) const { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resize(size_t sz) { + if(sz <= cur_) return; + if(sz_ < sz) expandCopy(sz); + } + + /** + * Clear set without deallocating (or setting) anything. + */ + void clear() { cur_ = 0; } + + /** + * Return memory category. + */ + int cat() const { return cat_; } + + /** + * Set the memory category for this object. + */ + void setCat(int cat) { + cat_ = cat; + } + + /** + * Transfer the guts of another EList into this one without using + * operator=, etc. We have to set EList o's list_ field to NULL to + * avoid o's destructor from deleting list_ out from under us. + */ + void xfer(ESet& o) { + // What does it mean to transfer to a different-category list? + assert_eq(cat_, o.cat()); + // Can only transfer into an empty object + free(); + list_ = o.list_; + sz_ = o.sz_; + cur_ = o.cur_; + o.list_ = NULL; + o.sz_ = o.cur_ = 0; + } + + /** + * Return a pointer to the beginning of the buffer. + */ + T *ptr() { return list_; } + + /** + * Return a const pointer to the beginning of the buffer. + */ + const T *ptr() const { return list_; } + +private: + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + T *alloc(size_t sz) { + assert_gt(sz, 0); + T *tmp = new T[sz]; + gMemTally.add(cat_, sz); + return tmp; + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + void free() { + if(list_ != NULL) { + delete[] list_; + gMemTally.del(cat_, sz_); + list_ = NULL; + } + } + + /** + * Simple linear scan that returns the index of the first element + * of list_ that is not less than el, or cur_ if all elements are + * less than el. + */ + size_t scanLoBound(const T& el) const { + for(size_t i = 0; i < cur_; i++) { + if(!(list_[i] < el)) { + // Shouldn't be equal + return i; + } + } + return cur_; + } + + /** + * Perform a binary search for the first element that is not less + * than 'el'. Return cur_ if all elements are less than el. + */ + size_t bsearchLoBound(const T& el) const { + size_t hi = cur_; + size_t lo = 0; + while(true) { + if(lo == hi) { +#ifndef NDEBUG + if((rand() % 10) == 0) { + assert_eq(lo, scanLoBound(el)); + } +#endif + return lo; + } + size_t mid = lo + ((hi-lo)>>1); + assert_neq(mid, hi); + if(list_[mid] < el) { + if(lo == mid) { +#ifndef NDEBUG + if((rand() % 10) == 0) { + assert_eq(hi, scanLoBound(el)); + } +#endif + return hi; + } + lo = mid; + } else { + hi = mid; + } + } + } + + /** + * Return true if sorted, assert otherwise. + */ + bool sorted() const { + if(cur_ <= 1) return true; +#ifndef NDEBUG + if((rand() % 20) == 0) { + for(size_t i = 0; i < cur_-1; i++) { + assert(list_[i] < list_[i+1]); + } + } +#endif + return true; + } + + /** + * Insert value 'el' at offset 'idx'. It's OK to insert at cur_, + * which is equivalent to appending. + */ + void insert(const T& el, size_t idx) { + assert_leq(idx, cur_); + if(cur_ == sz_) { + expandCopy(sz_+1); + assert(sorted()); + } + for(size_t i = cur_; i > idx; i--) { + list_[i] = list_[i-1]; + } + list_[idx] = el; + cur_++; + assert(sorted()); + } + + /** + * Erase element at offset idx. + */ + void erase(size_t idx) { + assert_lt(idx, cur_); + for(size_t i = idx; i < cur_-1; i++) { + list_[i] = list_[i+1]; + } + cur_--; + assert(sorted()); + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. + */ + void expandCopy(size_t thresh) { + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) { + newsz *= 2; + } + T* tmp = alloc(newsz); + for(size_t i = 0; i < cur_; i++) { + tmp[i] = list_[i]; + } + free(); + list_ = tmp; + sz_ = newsz; + } + + int cat_; // memory category, for accounting purposes + T *list_; // list pointer, returned from new[] + size_t sz_; // capacity + size_t cur_; // occupancy (AKA size) +}; + +template +class ELSet { + +public: + + /** + * Allocate initial default of 128 elements. + */ + explicit ELSet(int cat = 0) : + cat_(cat), list_(NULL), sz_(S), cur_(0) + { + assert_geq(cat, 0); + } + + /** + * Initially allocate given number of elements; should be > 0. + */ + explicit ELSet(size_t isz, int cat = 0) : + cat_(cat), list_(NULL), sz_(isz), cur_(0) + { + assert_gt(isz, 0); + assert_geq(cat, 0); + } + + /** + * Copy from another ELList using operator=. + */ + ELSet(const ELSet& o) : + cat_(0), list_(NULL), sz_(0), cur_(0) + { + *this = o; + } + + /** + * Copy from another ELList using operator=. + */ + explicit ELSet(const ELSet& o, int cat) : + cat_(cat), list_(NULL), sz_(0), cur_(0) + { + *this = o; + assert_geq(cat, 0); + } + + /** + * Destructor. + */ + ~ELSet() { free(); } + + /** + * Make this object into a copy of o by allocating enough memory to + * fit the number of elements in o (note: the number of elements + * may be substantially less than the memory allocated in o) and + * using operator= to copy them over. + */ + ELSet& operator=(const ELSet& o) { + assert_eq(cat_, o.cat()); + if(list_ == NULL) { + lazyInit(); + } + if(o.cur_ == 0) { + cur_ = 0; + return *this; + } + if(sz_ < o.cur_) expandNoCopy(o.cur_ + 1); + assert_geq(sz_, o.cur_); + cur_ = o.cur_; + for(size_t i = 0; i < cur_; i++) { + // Note: using operator=, not xfer + assert_eq(list_[i].cat(), o.list_[i].cat()); + list_[i] = o.list_[i]; + } + return *this; + } + + /** + * Transfer the guts of another ESet into this one without using + * operator=, etc. We have to set ESet o's list_ field to NULL to + * avoid o's destructor from deleting list_ out from under us. + */ + void xfer(ELSet& o) { + assert_eq(cat_, o.cat()); + list_ = o.list_; // list_ is an array of ESets + sz_ = o.sz_; + cur_ = o.cur_; + o.list_ = NULL; + o.sz_ = o.cur_ = 0; + } + + /** + * Return number of elements. + */ + inline size_t size() const { return cur_; } + + /** + * Return true iff there are no elements. + */ + inline bool empty() const { return cur_ == 0; } + + /** + * Return true iff list hasn't been initialized yet. + */ + inline bool null() const { return list_ == NULL; } + + /** + * Add an element to the back. No intialization is done. + */ + void expand() { + if(list_ == NULL) lazyInit(); + if(cur_ == sz_) expandCopy(sz_+1); + cur_++; + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resize(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) { + expandCopy(sz); + } + cur_ = sz; + } + + /** + * Make the stack empty. + */ + void clear() { + cur_ = 0; // re-use stack memory + // Don't clear heap; re-use it + } + + /** + * Get the element on the top of the stack. + */ + inline ESet& back() { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Get the element on the top of the stack, const version. + */ + inline const ESet& back() const { + assert_gt(cur_, 0); + return list_[cur_-1]; + } + + /** + * Get the frontmost element (bottom of stack). + */ + inline ESet& front() { + assert_gt(cur_, 0); + return list_[0]; + } + + /** + * Get the element on the bottom of the stack, const version. + */ + inline const ESet& front() const { return front(); } + + /** + * Return a reference to the ith element. + */ + inline ESet& operator[](size_t i) { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline const ESet& operator[](size_t i) const { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline ESet& get(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. + */ + inline const ESet& get(size_t i) const { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + ESet& getSlow(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. This version is not + * inlined, which guarantees we can use it from the debugger. + */ + const ESet& getSlow(size_t i) const { + return operator[](i); + } + + /** + * Return a pointer to the beginning of the buffer. + */ + ESet *ptr() { return list_; } + + /** + * Return a const pointer to the beginning of the buffer. + */ + const ESet *ptr() const { return list_; } + + /** + * Set the memory category for this object and all children. + */ + void setCat(int cat) { + assert_gt(cat, 0); + cat_ = cat; + if(cat_ != 0) { + for(size_t i = 0; i < sz_; i++) { + assert(list_[i].null()); + list_[i].setCat(cat_); + } + } + } + + /** + * Return memory category. + */ + int cat() const { return cat_; } + +protected: + + /** + * Initialize memory for ELSet. + */ + void lazyInit() { + assert(list_ == NULL); + list_ = alloc(sz_); + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + ESet *alloc(size_t sz) { + assert_gt(sz, 0); + ESet *tmp = new ESet[sz]; + gMemTally.add(cat_, sz); + if(cat_ != 0) { + for(size_t i = 0; i < sz; i++) { + assert(tmp[i].ptr() == NULL); + tmp[i].setCat(cat_); + } + } + return tmp; + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + void free() { + if(list_ != NULL) { + delete[] list_; + gMemTally.del(cat_, sz_); + list_ = NULL; + } + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. Copy old contents into new buffer + * using operator=. + */ + void expandCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + ESet* tmp = alloc(newsz); + if(list_ != NULL) { + for(size_t i = 0; i < cur_; i++) { + assert_eq(cat_, tmp[i].cat()); + tmp[i].xfer(list_[i]); + assert_eq(cat_, tmp[i].cat()); + } + free(); + } + list_ = tmp; + sz_ = newsz; + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. Don't copy old contents over. + */ + void expandNoCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + free(); + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + ESet* tmp = alloc(newsz); + list_ = tmp; + sz_ = newsz; + assert_gt(sz_, 0); + } + + int cat_; // memory category, for accounting purposes + ESet *list_; // list pointer, returned from new[] + size_t sz_; // capacity + size_t cur_; // occupancy (AKA size) + +}; + +/** + * Expandable map using a heap-allocated sorted array. + * + * Note that the copy constructor and operator= routines perform + * shallow copies (w/ memcpy). + */ +template +class EMap { + +public: + + /** + * Allocate initial default of 128 elements. + */ + EMap(int cat = 0) : + cat_(cat), + list_(NULL), + sz_(128), + cur_(0) + { + list_ = alloc(sz_); + } + + /** + * Initially allocate given number of elements; should be > 0. + */ + EMap(size_t isz, int cat = 0) : + cat_(cat), + list_(NULL), + sz_(isz), + cur_(0) + { + assert_gt(isz, 0); + list_ = alloc(sz_); + } + + /** + * Copy from another ESet. + */ + EMap(const EMap& o) : list_(NULL) { + *this = o; + } + + /** + * Destructor. + */ + ~EMap() { free(); } + + /** + * Copy contents of given ESet into this ESet. + */ + EMap& operator=(const EMap& o) { + sz_ = o.sz_; + cur_ = o.cur_; + free(); + list_ = alloc(sz_); + memcpy(list_, o.list_, cur_ * sizeof(std::pair)); + return *this; + } + + /** + * Return number of elements. + */ + size_t size() const { return cur_; } + + /** + * Return the total size in bytes occupied by this map. + */ + size_t totalSizeBytes() const { + return sizeof(int) + + 2 * sizeof(size_t) + + cur_ * sizeof(std::pair); + } + + /** + * Return the total capacity in bytes occupied by this map. + */ + size_t totalCapacityBytes() const { + return sizeof(int) + + 2 * sizeof(size_t) + + sz_ * sizeof(std::pair); + } + + /** + * Return true iff there are no elements. + */ + bool empty() const { return cur_ == 0; } + + /** + * Insert a new element into the set in sorted order. + */ + bool insert(const std::pair& el) { + size_t i = 0; + if(cur_ == 0) { + insert(el, 0); + return true; + } + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el.first); + } else { + // Binary search + i = bsearchLoBound(el.first); + } + if(list_[i] == el) return false; // already there + insert(el, i); + return true; // not already there + } + + /** + * Return true iff this set contains 'el'. + */ + bool contains(const K& el) const { + if(cur_ == 0) return false; + else if(cur_ == 1) return el == list_[0].first; + size_t i; + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + return i != cur_ && list_[i].first == el; + } + + /** + * Return true iff this set contains 'el'. + */ + bool containsEx(const K& el, size_t& i) const { + if(cur_ == 0) return false; + else if(cur_ == 1) { + i = 0; + return el == list_[0].first; + } + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + return i != cur_ && list_[i].first == el; + } + + /** + * Remove element from set. + */ + void remove(const K& el) { + size_t i; + if(cur_ < 16) { + // Linear scan + i = scanLoBound(el); + } else { + // Binary search + i = bsearchLoBound(el); + } + assert(i != cur_ && list_[i].first == el); + erase(i); + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resize(size_t sz) { + if(sz <= cur_) return; + if(sz_ < sz) expandCopy(sz); + } + + /** + * Get the ith key, value pair in the map. + */ + const std::pair& get(size_t i) const { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Get the ith key, value pair in the map. + */ + const std::pair& operator[](size_t i) const { + return get(i); + } + + /** + * Clear set without deallocating (or setting) anything. + */ + void clear() { cur_ = 0; } + +private: + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + std::pair *alloc(size_t sz) { + assert_gt(sz, 0); + std::pair *tmp = new std::pair[sz]; + gMemTally.add(cat_, sz); + return tmp; + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + void free() { + if(list_ != NULL) { + delete[] list_; + gMemTally.del(cat_, sz_); + list_ = NULL; + } + } + + /** + * Simple linear scan that returns the index of the first element + * of list_ that is not less than el, or cur_ if all elements are + * less than el. + */ + size_t scanLoBound(const K& el) const { + for(size_t i = 0; i < cur_; i++) { + if(!(list_[i].first < el)) { + // Shouldn't be equal + return i; + } + } + return cur_; + } + + /** + * Perform a binary search for the first element that is not less + * than 'el'. Return cur_ if all elements are less than el. + */ + size_t bsearchLoBound(const K& el) const { + size_t hi = cur_; + size_t lo = 0; + while(true) { + if(lo == hi) { +#ifndef NDEBUG + if((rand() % 10) == 0) { + assert_eq(lo, scanLoBound(el)); + } +#endif + return lo; + } + size_t mid = lo + ((hi-lo)>>1); + assert_neq(mid, hi); + if(list_[mid].first < el) { + if(lo == mid) { +#ifndef NDEBUG + if((rand() % 10) == 0) { + assert_eq(hi, scanLoBound(el)); + } +#endif + return hi; + } + lo = mid; + } else { + hi = mid; + } + } + } + + /** + * Return true if sorted, assert otherwise. + */ + bool sorted() const { + if(cur_ <= 1) return true; +#ifndef NDEBUG + for(size_t i = 0; i < cur_-1; i++) { + assert(!(list_[i] == list_[i+1])); + assert(list_[i] < list_[i+1]); + } +#endif + return true; + } + + /** + * Insert value 'el' at offset 'idx'. It's OK to insert at cur_, + * which is equivalent to appending. + */ + void insert(const std::pair& el, size_t idx) { + assert_leq(idx, cur_); + if(cur_ == sz_) { + expandCopy(sz_+1); + } + for(size_t i = cur_; i > idx; i--) { + list_[i] = list_[i-1]; + } + list_[idx] = el; + assert(idx == cur_ || list_[idx] < list_[idx+1]); + cur_++; + assert(sorted()); + } + + /** + * Erase element at offset idx. + */ + void erase(size_t idx) { + assert_lt(idx, cur_); + for(size_t i = idx; i < cur_-1; i++) { + list_[i] = list_[i+1]; + } + cur_--; + assert(sorted()); + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Expansions are quadratic. + */ + void expandCopy(size_t thresh) { + if(thresh <= sz_) return; + size_t newsz = sz_ * 2; + while(newsz < thresh) newsz *= 2; + std::pair* tmp = alloc(newsz); + for(size_t i = 0; i < cur_; i++) { + tmp[i] = list_[i]; + } + free(); + list_ = tmp; + sz_ = newsz; + } + + int cat_; // memory category, for accounting purposes + std::pair *list_; // list pointer, returned from new[] + size_t sz_; // capacity + size_t cur_; // occupancy (AKA size) +}; + +/** + * A class that allows callers to create objects that are referred to by ID. + * Objects should not be referred to via pointers or references, since they + * are stored in an expandable buffer that might be resized and thereby moved + * to another address. + */ +template +class EFactory { + +public: + + explicit EFactory(size_t isz, int cat = 0) : l_(isz, cat) { } + + explicit EFactory(int cat = 0) : l_(cat) { } + + /** + * Clear the list. + */ + void clear() { + l_.clear(); + } + + /** + * Add one additional item to the list and return its ID. + */ + size_t alloc() { + l_.expand(); + return l_.size()-1; + } + + /** + * Return the number of items in the list. + */ + size_t size() const { + return l_.size(); + } + + /** + * Return the number of items in the factory. + */ + size_t totalSizeBytes() const { + return l_.totalSizeBytes(); + } + + /** + * Return the total capacity in bytes occupied by this factory. + */ + size_t totalCapacityBytes() const { + return l_.totalCapacityBytes(); + } + + /** + * Resize the list. + */ + void resize(size_t sz) { + l_.resize(sz); + } + + /** + * Return true iff the list is empty. + */ + bool empty() const { + return size() == 0; + } + + /** + * Shrink the list such that the topmost (most recently allocated) element + * is removed. + */ + void pop() { + l_.resize(l_.size()-1); + } + + /** + * Return mutable list item at offset 'off' + */ + T& operator[](size_t off) { + return l_[off]; + } + + /** + * Return immutable list item at offset 'off' + */ + const T& operator[](size_t off) const { + return l_[off]; + } + +protected: + + EList l_; +}; + +/** + * An expandable bit vector based on EList + */ +template +class EBitList { + +public: + + explicit EBitList(size_t isz, int cat = 0) : l_(isz, cat) { reset(); } + + explicit EBitList(int cat = 0) : l_(cat) { reset(); } + + /** + * Reset to empty state. + */ + void clear() { + reset(); + } + + /** + * Reset to empty state. + */ + void reset() { + l_.clear(); + max_ = std::numeric_limits::max(); + } + + /** + * Set a bit. + */ + void set(size_t off) { + resize(off); + l_[off >> 3] |= (1 << (off & 7)); + if(off > max_ || max_ == std::numeric_limits::max()) { + max_ = off; + } + } + + /** + * Return mutable list item at offset 'off' + */ + bool test(size_t off) const { + if((size_t)(off >> 3) >= l_.size()) { + return false; + } + return (l_[off >> 3] & (1 << (off & 7))) != 0; + } + + /** + * Return size of the underlying byte array. + */ + size_t size() const { + return l_.size(); + } + + /** + * Resize to accomodate at least the given number of bits. + */ + void resize(size_t off) { + if((size_t)(off >> 3) >= l_.size()) { + size_t oldsz = l_.size(); + l_.resize((off >> 3) + 1); + for(size_t i = oldsz; i < l_.size(); i++) { + l_[i] = 0; + } + } + } + + /** + * Return max set bit. + */ + size_t max() const { + return max_; + } + +protected: + + EList l_; + size_t max_; +}; + +/** + * Implements a min-heap. + */ +template +class EHeap { +public: + + /** + * Add the element to the next available leaf position and percolate up. + */ + void insert(T o) { + size_t pos = l_.size(); + l_.push_back(o); + while(pos > 0) { + size_t parent = (pos-1) >> 1; + if(l_[pos] < l_[parent]) { + T tmp(l_[pos]); + l_[pos] = l_[parent]; + l_[parent] = tmp; + pos = parent; + } else break; + } + assert(repOk()); + } + + /** + * Return the topmost element. + */ + T top() { + assert_gt(l_.size(), 0); + return l_[0]; + } + + /** + * Remove the topmost element. + */ + T pop() { + assert_gt(l_.size(), 0); + T ret = l_[0]; + l_[0] = l_[l_.size()-1]; + l_.resize(l_.size()-1); + size_t cur = 0; + while(true) { + size_t c1 = ((cur+1) << 1) - 1; + size_t c2 = c1 + 1; + if(c2 < l_.size()) { + if(l_[c1] < l_[cur] && l_[c1] <= l_[c2]) { + T tmp(l_[c1]); + l_[c1] = l_[cur]; + l_[cur] = tmp; + cur = c1; + } else if(l_[c2] < l_[cur]) { + T tmp(l_[c2]); + l_[c2] = l_[cur]; + l_[cur] = tmp; + cur = c2; + } else { + break; + } + } else if(c1 < l_.size()) { + if(l_[c1] < l_[cur]) { + T tmp(l_[c1]); + l_[c1] = l_[cur]; + l_[cur] = tmp; + cur = c1; + } else { + break; + } + } else { + break; + } + } + assert(repOk()); + return ret; + } + + /** + * Return number of elements in the heap. + */ + size_t size() const { + return l_.size(); + } + + /** + * Return the total size in bytes occupied by this heap. + */ + size_t totalSizeBytes() const { + return l_.totalSizeBytes(); + } + + /** + * Return the total capacity in bytes occupied by this heap. + */ + size_t totalCapacityBytes() const { + return l_.totalCapacityBytes(); + } + + /** + * Return true when heap is empty. + */ + bool empty() const { + return l_.empty(); + } + + /** + * Return element at offset i. + */ + const T& operator[](size_t i) const { + return l_[i]; + } + +#ifndef NDEBUG + /** + * Check that heap property holds. + */ + bool repOk() const { + if(empty()) return true; + return repOkNode(0); + } + + /** + * Check that heap property holds at and below this node. + */ + bool repOkNode(size_t cur) const { + size_t c1 = ((cur+1) << 1) - 1; + size_t c2 = c1 + 1; + if(c1 < l_.size()) { + assert_leq(l_[cur], l_[c1]); + } + if(c2 < l_.size()) { + assert_leq(l_[cur], l_[c2]); + } + if(c2 < l_.size()) { + return repOkNode(c1) && repOkNode(c2); + } else if(c1 < l_.size()) { + return repOkNode(c1); + } + return true; + } +#endif + + /** + * Clear the heap so that it's empty. + */ + void clear() { + l_.clear(); + } + +protected: + + EList l_; +}; + +/** + * Dispenses pages of memory for all the lists in the cache, including + * the sequence-to-range map, the range list, the edits list, and the + * offsets list. All lists contend for the same pool of memory. + */ +class Pool { +public: + Pool( + uint64_t bytes, + uint32_t pagesz, + int cat = 0) : + cat_(cat), + cur_(0), + bytes_(bytes), + pagesz_(pagesz), + pages_(cat) + { + for(size_t i = 0; i < ((bytes+pagesz-1)/pagesz); i++) { + pages_.push_back(new uint8_t[pagesz]); + gMemTally.add(cat, pagesz); + assert(pages_.back() != NULL); + } + assert(repOk()); + } + + /** + * Free each page. + */ + ~Pool() { + for(size_t i = 0; i < pages_.size(); i++) { + assert(pages_[i] != NULL); + delete[] pages_[i]; + gMemTally.del(cat_, pagesz_); + } + } + + /** + * Allocate one page, or return NULL if no pages are left. + */ + uint8_t * alloc() { + assert(repOk()); + if(cur_ == pages_.size()) return NULL; + return pages_[cur_++]; + } + + bool full() { return cur_ == pages_.size(); } + + /** + * Clear the pool so that no pages are considered allocated. + */ + void clear() { + cur_ = 0; + assert(repOk()); + } + + /** + * Reset the Pool to be as though + */ + void free() { + // Currently a no-op because the only freeing method supported + // now is to clear the entire pool + } + +#ifndef NDEBUG + /** + * Check that pool is internally consistent. + */ + bool repOk() const { + assert_leq(cur_, pages_.size()); + assert(!pages_.empty()); + assert_gt(bytes_, 0); + assert_gt(pagesz_, 0); + return true; + } +#endif + +public: + int cat_; // memory category, for accounting purposes + uint32_t cur_; // next page to hand out + const uint64_t bytes_; // total bytes in the pool + const uint32_t pagesz_; // size of a single page + EList pages_; // the pages themselves +}; + +/** + * An expandable list backed by a pool. + */ +template +class PList { + +#define PLIST_PER_PAGE (S / sizeof(T)) + +public: + /** + * Initialize the current-edit pointer to 0 and set the number of + * edits per memory page. + */ + PList(int cat = 0) : + cur_(0), + curPage_(0), + pages_(cat) { } + + /** + * Add 1 object to the list. + */ + bool add(Pool& p, const T& o) { + assert(repOk()); + if(!ensure(p, 1)) return false; + if(cur_ == PLIST_PER_PAGE) { + cur_ = 0; + curPage_++; + } + assert_lt(curPage_, pages_.size()); + assert(repOk()); + assert_lt(cur_, PLIST_PER_PAGE); + pages_[curPage_][cur_++] = o; + return true; + } + + /** + * Add a list of objects to the list. + */ + bool add(Pool& p, const EList& os) { + if(!ensure(p, os.size())) return false; + for(size_t i = 0; i < os.size(); i++) { + if(cur_ == PLIST_PER_PAGE) { + cur_ = 0; + curPage_++; + } + assert_lt(curPage_, pages_.size()); + assert(repOk()); + assert_lt(cur_, PLIST_PER_PAGE); + pages_[curPage_][cur_++] = os[i]; + } + return true; + } + + /** + * Add a list of objects to the list. + */ + bool copy( + Pool& p, + const PList& src, + size_t i, + size_t len) + { + if(!ensure(p, src.size())) return false; + for(size_t i = 0; i < src.size(); i++) { + if(cur_ == PLIST_PER_PAGE) { + cur_ = 0; + curPage_++; + } + assert_lt(curPage_, pages_.size()); + assert(repOk()); + assert_lt(cur_, PLIST_PER_PAGE); + pages_[curPage_][cur_++] = src[i]; + } + return true; + } + + /** + * Add 'num' objects, all equal to 'o' to the list. + */ + bool addFill(Pool& p, size_t num, const T& o) { + if(!ensure(p, num)) return false; + for(size_t i = 0; i < num; i++) { + if(cur_ == PLIST_PER_PAGE) { + cur_ = 0; + curPage_++; + } + assert_lt(curPage_, pages_.size()); + assert(repOk()); + assert_lt(cur_, PLIST_PER_PAGE); + pages_[curPage_][cur_++] = o; + } + return true; + } + + /** + * Free all pages associated with the list. + */ + void clear() { + pages_.clear(); + cur_ = curPage_ = 0; + } + +#ifndef NDEBUG + /** + * Check that list is internally consistent. + */ + bool repOk() const { + assert(pages_.size() == 0 || curPage_ < pages_.size()); + assert_leq(cur_, PLIST_PER_PAGE); + return true; + } +#endif + + /** + * Return the number of elements in the list. + */ + size_t size() const { + return curPage_ * PLIST_PER_PAGE + cur_; + } + + /** + * Return true iff the PList has no elements. + */ + bool empty() const { + return size() == 0; + } + + /** + * Get the ith element added to the list. + */ + inline const T& getConst(size_t i) const { + assert_lt(i, size()); + size_t page = i / PLIST_PER_PAGE; + size_t elt = i % PLIST_PER_PAGE; + return pages_[page][elt]; + } + + /** + * Get the ith element added to the list. + */ + inline T& get(size_t i) { + assert_lt(i, size()); + size_t page = i / PLIST_PER_PAGE; + size_t elt = i % PLIST_PER_PAGE; + assert_lt(page, pages_.size()); + assert(page < pages_.size()-1 || elt < cur_); + return pages_[page][elt]; + } + + /** + * Get the most recently added element. + */ + inline T& back() { + size_t page = (size()-1) / PLIST_PER_PAGE; + size_t elt = (size()-1) % PLIST_PER_PAGE; + assert_lt(page, pages_.size()); + assert(page < pages_.size()-1 || elt < cur_); + return pages_[page][elt]; + } + + /** + * Get const version of the most recently added element. + */ + inline const T& back() const { + size_t page = (size()-1) / PLIST_PER_PAGE; + size_t elt = (size()-1) % PLIST_PER_PAGE; + assert_lt(page, pages_.size()); + assert(page < pages_.size()-1 || elt < cur_); + return pages_[page][elt]; + } + + /** + * Get the element most recently added to the list. + */ + T& last() { + assert(!pages_.empty()); + assert_gt(PLIST_PER_PAGE, 0); + if(cur_ == 0) { + assert_gt(pages_.size(), 1); + return pages_[pages_.size()-2][PLIST_PER_PAGE-1]; + } else { + return pages_.back()[cur_-1]; + } + } + + /** + * Return true iff 'num' additional objects will fit in the pages + * allocated to the list. If more pages are needed, they are + * added if possible. + */ + bool ensure(Pool& p, size_t num) { + assert(repOk()); + if(num == 0) return true; + // Allocation of the first page + if(pages_.size() == 0) { + if(expand(p) == NULL) { + return false; + } + assert_eq(1, pages_.size()); + } + size_t cur = cur_; + size_t curPage = curPage_; + while(cur + num > PLIST_PER_PAGE) { + assert_lt(curPage, pages_.size()); + if(curPage == pages_.size()-1 && expand(p) == NULL) { + return false; + } + num -= (PLIST_PER_PAGE - cur); + cur = 0; + curPage++; + } + return true; + } + +protected: + + /** + * Expand our page supply by 1 + */ + T* expand(Pool& p) { + T* newpage = (T*)p.alloc(); + if(newpage == NULL) { + return NULL; + } + pages_.push_back(newpage); + return pages_.back(); + } + + size_t cur_; // current elt within page + size_t curPage_; // current page + EList pages_; // the pages +}; + +/** + * A slice of an EList. + */ +template +class EListSlice { + +public: + EListSlice() : + i_(0), + len_(0), + list_() + { } + + EListSlice( + EList& list, + size_t i, + size_t len) : + i_(i), + len_(len), + list_(&list) + { } + + /** + * Initialize from a piece of another PListSlice. + */ + void init(const EListSlice& sl, size_t first, size_t last) { + assert_gt(last, first); + assert_leq(last - first, sl.len_); + i_ = sl.i_ + first; + len_ = last - first; + list_ = sl.list_; + } + + /** + * Reset state to be empty. + */ + void reset() { + i_ = len_ = 0; + list_ = NULL; + } + + /** + * Get the ith element of the slice. + */ + inline const T& get(size_t i) const { + assert(valid()); + assert_lt(i, len_); + return list_->get(i + i_); + } + + /** + * Get the ith element of the slice. + */ + inline T& get(size_t i) { + assert(valid()); + assert_lt(i, len_); + return list_->get(i + i_); + } + + /** + * Return a reference to the ith element. + */ + inline T& operator[](size_t i) { + assert(valid()); + assert_lt(i, len_); + return list_->get(i + i_); + } + + /** + * Return a reference to the ith element. + */ + inline const T& operator[](size_t i) const { + assert(valid()); + assert_lt(i, len_); + return list_->get(i + i_); + } + + /** + * Return true iff this slice is initialized. + */ + bool valid() const { + return len_ != 0; + } + + /** + * Return number of elements in the slice. + */ + size_t size() const { + return len_; + } + +#ifndef NDEBUG + /** + * Ensure that the PListSlice is internally consistent and + * consistent with the backing PList. + */ + bool repOk() const { + assert_leq(i_ + len_, list_->size()); + return true; + } +#endif + + /** + * Return true iff this slice refers to the same slice of the same + * list as the given slice. + */ + bool operator==(const EListSlice& sl) const { + return i_ == sl.i_ && len_ == sl.len_ && list_ == sl.list_; + } + + /** + * Return false iff this slice refers to the same slice of the same + * list as the given slice. + */ + bool operator!=(const EListSlice& sl) const { + return !(*this == sl); + } + + /** + * Set the length. This could leave things inconsistent (e.g. could + * include elements that fall off the end of list_). + */ + void setLength(size_t nlen) { + len_ = (uint32_t)nlen; + } + +protected: + size_t i_; + size_t len_; + EList* list_; +}; + +/** + * A slice of a PList. + */ +template +class PListSlice { + +public: + PListSlice() : + i_(0), + len_(0), + list_() + { } + + PListSlice( + PList& list, + TIndexOffU i, + TIndexOffU len) : + i_(i), + len_(len), + list_(&list) + { } + + /** + * Initialize from a piece of another PListSlice. + */ + void init(const PListSlice& sl, size_t first, size_t last) { + assert_gt(last, first); + assert_leq(last - first, sl.len_); + i_ = (uint32_t)(sl.i_ + first); + len_ = (uint32_t)(last - first); + list_ = sl.list_; + } + + /** + * Reset state to be empty. + */ + void reset() { + i_ = len_ = 0; + list_ = NULL; + } + + /** + * Get the ith element of the slice. + */ + inline const T& get(size_t i) const { + assert(valid()); + assert_lt(i, len_); + return list_->get(i+i_); + } + + /** + * Get the ith element of the slice. + */ + inline T& get(size_t i) { + assert(valid()); + assert_lt(i, len_); + return list_->get(i+i_); + } + + /** + * Return a reference to the ith element. + */ + inline T& operator[](size_t i) { + assert(valid()); + assert_lt(i, len_); + return list_->get(i+i_); + } + + /** + * Return a reference to the ith element. + */ + inline const T& operator[](size_t i) const { + assert(valid()); + assert_lt(i, len_); + return list_->get(i+i_); + } + + /** + * Return true iff this slice is initialized. + */ + bool valid() const { + return len_ != 0; + } + + /** + * Return number of elements in the slice. + */ + size_t size() const { + return len_; + } + +#ifndef NDEBUG + /** + * Ensure that the PListSlice is internally consistent and + * consistent with the backing PList. + */ + bool repOk() const { + assert_leq(i_ + len_, list_->size()); + return true; + } +#endif + + /** + * Return true iff this slice refers to the same slice of the same + * list as the given slice. + */ + bool operator==(const PListSlice& sl) const { + return i_ == sl.i_ && len_ == sl.len_ && list_ == sl.list_; + } + + /** + * Return false iff this slice refers to the same slice of the same + * list as the given slice. + */ + bool operator!=(const PListSlice& sl) const { + return !(*this == sl); + } + + /** + * Set the length. This could leave things inconsistent (e.g. could + * include elements that fall off the end of list_). + */ + void setLength(size_t nlen) { + len_ = (uint32_t)nlen; + } + +protected: + uint32_t i_; + uint32_t len_; + PList* list_; +}; + +/** + * A Red-Black tree node. Links to parent & left and right children. + * Key and Payload are of types K and P. Node total ordering is based + * on K's total ordering. K must implement <, == and > operators. + */ +template // K=key, P=payload +class RedBlackNode { + + typedef RedBlackNode TNode; + +public: + TNode *parent; // parent + TNode *left; // left child + TNode *right; // right child + bool red; // true -> red, false -> black + K key; // key, for ordering + P payload; // payload (i.e. value) + + /** + * Return the parent of this node's parent, or NULL if none exists. + */ + RedBlackNode *grandparent() { + return parent != NULL ? parent->parent : NULL; + } + + /** + * Return the sibling of this node's parent, or NULL if none exists. + */ + RedBlackNode *uncle() { + if(parent == NULL) return NULL; // no parent + if(parent->parent == NULL) return NULL; // parent has no siblings + return (parent->parent->left == parent) ? parent->parent->right : parent->parent->left; + } + + /** + * Return true iff this node is its parent's left child. + */ + bool isLeftChild() const { assert(parent != NULL); return parent->left == this; } + + /** + * Return true iff this node is its parent's right child. + */ + bool isRightChild() const { assert(parent != NULL); return parent->right == this; } + + /** + * Return true iff this node is its parent's right child. + */ + void replaceChild(RedBlackNode* ol, RedBlackNode* nw) { + if(left == ol) { + left = nw; + } else { + assert(right == ol); + right = nw; + } + } + + /** + * Return the number of non-null children this node has. + */ + int numChildren() const { + return ((left != NULL) ? 1 : 0) + ((right != NULL) ? 1 : 0); + } + +#ifndef NDEBUG + /** + * Check that node is internally consistent. + */ + bool repOk() const { + if(parent != NULL) { + assert(parent->left == this || parent->right == this); + } + return true; + } +#endif + + /** + * True -> my key is less than than the given node's key. + */ + bool operator<(const TNode& o) const { return key < o.key; } + + /** + * True -> my key is greater than the given node's key. + */ + bool operator>(const TNode& o) const { return key > o.key; } + + /** + * True -> my key equals the given node's key. + */ + bool operator==(const TNode& o) const { return key == o.key; } + + /** + * True -> my key is less than the given key. + */ + bool operator<(const K& okey) const { return key < okey; } + + /** + * True -> my key is greater than the given key. + */ + bool operator>(const K& okey) const { return key > okey; } + + /** + * True -> my key is equal to the given key. + */ + bool operator==(const K& okey) const { return key == okey; } +}; + +/** + * A Red-Black tree that associates keys (of type K) with payloads (of + * type P). Red-Black trees are self-balancing and guarantee that the + * tree as always "balanced" to a factor of 2, i.e., the longest + * root-to-leaf path is never more than twice as long as the shortest + * root-to-leaf path. + */ +template // K=key, P=payload +class RedBlack { + + typedef RedBlackNode TNode; + +public: + /** + * Initialize the current-edit pointer to 0 and set the number of + * edits per memory page. + */ + RedBlack(uint32_t pageSz, int cat = 0) : + perPage_(pageSz/sizeof(TNode)), pages_(cat) { clear(); } + + /** + * Given a DNA string, find the red-black node corresponding to it, + * if one exists. + */ + inline TNode* lookup(const K& key) const { + TNode* cur = root_; + while(cur != NULL) { + if((*cur) == key) return cur; + if((*cur) < key) { + cur = cur->right; + } else { + cur = cur->left; + } + } + return NULL; + } + + /** + * Add a new key as a node in the red-black tree. + */ + TNode* add( + Pool& p, // in: pool for memory pages + const K& key, // in: key to insert + bool* added) // if true, assert is thrown if key exists + { + // Look for key; if it's not there, get its parent + TNode* cur = root_; + assert(root_ == NULL || !root_->red); + TNode* parent = NULL; + bool leftChild = true; + while(cur != NULL) { + if((*cur) == key) { + // Found it; break out of loop with cur != NULL + break; + } + parent = cur; + if((*cur) < key) { + if((cur = cur->right) == NULL) { + // Fell off the bottom of the tree as the right + // child of parent 'lastCur' + leftChild = false; + } + } else { + if((cur = cur->left) == NULL) { + // Fell off the bottom of the tree as the left + // child of parent 'lastCur' + leftChild = true; + } + } + } + if(cur != NULL) { + // Found an entry; assert if we weren't supposed to + if(added != NULL) *added = false; + } else { + assert(root_ == NULL || !root_->red); + if(!addNode(p, cur)) { + // Exhausted memory + return NULL; + } + assert(cur != NULL); + assert(cur != root_); + assert(cur != parent); + // Initialize new node + cur->key = key; + cur->left = cur->right = NULL; + cur->red = true; // red until proven black + keys_++; + if(added != NULL) *added = true; + // Put it where we know it should go + addNode(cur, parent, leftChild); + } + return cur; // return the added or found node + } + +#ifndef NDEBUG + /** + * Check that list is internally consistent. + */ + bool repOk() const { + assert(curPage_ == 0 || curPage_ < pages_.size()); + assert_leq(cur_, perPage_); + assert(root_ == NULL || !root_->red); + return true; + } +#endif + + /** + * Clear all state. + */ + void clear() { + cur_ = curPage_ = 0; + root_ = NULL; + keys_ = 0; + intenseRepOkCnt_ = 0; + pages_.clear(); + } + + /** + * Return number of keys added. + */ + size_t size() const { + return keys_; + } + + /** + * Return true iff there are no keys in the map. + */ + bool empty() const { + return keys_ == 0; + } + + /** + * Add another node and return a pointer to it in 'node'. A new + * page is allocated if necessary. If the allocation fails, false + * is returned. + */ + bool addNode(Pool& p, TNode*& node) { + assert_leq(cur_, perPage_); + assert(repOk()); + assert(this != NULL); + // Allocation of the first page + if(pages_.size() == 0) { + if(addPage(p) == NULL) { + node = NULL; + return false; + } + assert_eq(1, pages_.size()); + } + if(cur_ == perPage_) { + assert_lt(curPage_, pages_.size()); + if(curPage_ == pages_.size()-1 && addPage(p) == NULL) { + return false; + } + cur_ = 0; + curPage_++; + } + assert_lt(cur_, perPage_); + assert_lt(curPage_, pages_.size()); + node = &pages_[curPage_][cur_]; + assert(node != NULL); + cur_++; + return true; + } + + const TNode* root() const { return root_; } + +protected: + +#ifndef NDEBUG + /** + * Check specifically that the red-black invariants are satistfied. + */ + bool redBlackRepOk(TNode* n) { + if(n == NULL) return true; + if(++intenseRepOkCnt_ < 500) return true; + intenseRepOkCnt_ = 0; + int minNodes = -1; // min # nodes along any n->leaf path + int maxNodes = -1; // max # nodes along any n->leaf path + // The number of black nodes along paths from n to leaf + // (must be same for all paths) + int blackConst = -1; + size_t nodesTot = 0; + redBlackRepOk( + n, + 1, /* 1 node so far */ + n->red ? 0 : 1, /* black nodes so far */ + blackConst, + minNodes, + maxNodes, + nodesTot); + if(n == root_) { + assert_eq(nodesTot, keys_); + } + assert_gt(minNodes, 0); + assert_gt(maxNodes, 0); + assert_leq(maxNodes, 2*minNodes); + return true; + } + + /** + * Check specifically that the red-black invariants are satistfied. + */ + bool redBlackRepOk( + TNode* n, + int nodes, + int black, + int& blackConst, + int& minNodes, + int& maxNodes, + size_t& nodesTot) const + { + assert_gt(black, 0); + nodesTot++; // account for leaf node + if(n->left == NULL) { + if(blackConst == -1) blackConst = black; + assert_eq(black, blackConst); + if(nodes+1 > maxNodes) maxNodes = nodes+1; + if(nodes+1 < minNodes || minNodes == -1) minNodes = nodes+1; + } else { + if(n->red) assert(!n->left->red); // Red can't be child of a red + redBlackRepOk( + n->left, // next node + nodes + 1, // # nodes so far on path + black + (n->left->red ? 0 : 1), // # black so far on path + blackConst, // invariant # black nodes on root->leaf path + minNodes, // min root->leaf len so far + maxNodes, // max root->leaf len so far + nodesTot); // tot nodes so far + } + if(n->right == NULL) { + if(blackConst == -1) blackConst = black; + assert_eq(black, blackConst); + if(nodes+1 > maxNodes) maxNodes = nodes+1; + if(nodes+1 < minNodes || minNodes == -1) minNodes = nodes+1; + } else { + if(n->red) assert(!n->right->red); // Red can't be child of a red + redBlackRepOk( + n->right, // next node + nodes + 1, // # nodes so far on path + black + (n->right->red ? 0 : 1), // # black so far on path + blackConst, // invariant # black nodes on root->leaf path + minNodes, // min root->leaf len so far + maxNodes, // max root->leaf len so far + nodesTot); // tot nodes so far + } + return true; + } +#endif + + /** + * Rotate to the left such that n is replaced by its right child + * w/r/t n's current parent. + */ + void leftRotate(TNode* n) { + TNode* r = n->right; + assert(n->repOk()); + assert(r->repOk()); + n->right = r->left; + if(n->right != NULL) { + n->right->parent = n; + assert(n->right->repOk()); + } + r->parent = n->parent; + n->parent = r; + r->left = n; + if(r->parent != NULL) { + r->parent->replaceChild(n, r); + } + if(root_ == n) root_ = r; + assert(!root_->red); + assert(n->repOk()); + assert(r->repOk()); + } + + /** + * Rotate to the right such that n is replaced by its left child + * w/r/t n's current parent. n moves down to the right and loses + * its left child, while its former left child moves up and gains a + * right child. + */ + void rightRotate(TNode* n) { + TNode* r = n->left; + assert(n->repOk()); + assert(r->repOk()); + n->left = r->right; + if(n->left != NULL) { + n->left->parent = n; + assert(n->left->repOk()); + } + r->parent = n->parent; + n->parent = r; + r->right = n; + if(r->parent != NULL) { + r->parent->replaceChild(n, r); + } + if(root_ == n) root_ = r; + assert(!root_->red); + assert(n->repOk()); + assert(r->repOk()); + } + + /** + * Add a node to the red-black tree, maintaining the red-black + * invariants. + */ + void addNode(TNode* n, TNode* parent, bool leftChild) { + assert(n != NULL); + if(parent == NULL) { + // Case 1: inserted at root + root_ = n; + root_->red = false; // root must be black + n->parent = NULL; + assert(redBlackRepOk(root_)); + assert(n->repOk()); + } else { + assert(!root_->red); + // Add new node to tree + if(leftChild) { + assert(parent->left == NULL); + parent->left = n; + } else { + assert(parent->right == NULL); + parent->right = n; + } + n->parent = parent; + int thru = 0; + while(true) { + thru++; + parent = n->parent; + if(parent != NULL) assert(parent->repOk()); + if(parent == NULL && n->red) { + n->red = false; + } + if(parent == NULL || !parent->red) { + assert(redBlackRepOk(root_)); + break; + } + TNode* uncle = n->uncle(); + TNode* gparent = n->grandparent(); + assert(gparent != NULL); // if parent is red, grandparent must exist + bool uncleRed = (uncle != NULL ? uncle->red : false); + if(uncleRed) { + // Parent is red, uncle is red; recursive case + assert(uncle != NULL); + parent->red = uncle->red = false; + gparent->red = true; + n = gparent; + continue; + } else { + if(parent->isLeftChild()) { + // Parent is red, uncle is black, parent is + // left child + if(!n->isLeftChild()) { + n = parent; + leftRotate(n); + } + n = n->parent; + n->red = false; + n->parent->red = true; + rightRotate(n->parent); + assert(redBlackRepOk(n)); + assert(redBlackRepOk(root_)); + } else { + // Parent is red, uncle is black, parent is + // right child. + if(!n->isRightChild()) { + n = parent; + rightRotate(n); + } + n = n->parent; + n->red = false; + n->parent->red = true; + leftRotate(n->parent); + assert(redBlackRepOk(n)); + assert(redBlackRepOk(root_)); + } + } + break; + } + } + assert(redBlackRepOk(root_)); + } + + /** + * Expand our page supply by 1 + */ + TNode* addPage(Pool& p) { + TNode *n = (TNode *)p.alloc(); + if(n != NULL) { + pages_.push_back(n); + } + return n; + } + + size_t keys_; // number of keys so far + size_t cur_; // current elt within page + size_t curPage_; // current page + const size_t perPage_; // # edits fitting in a page + TNode* root_; // root node + EList pages_; // the pages + int intenseRepOkCnt_; // counter for the computationally intensive repOk function +}; + +/** + * For assembling doubly-linked lists of Edits. + */ +template +struct DoublyLinkedList { + + DoublyLinkedList() : payload(), prev(NULL), next(NULL) { } + + /** + * Add all elements in the doubly-linked list to the provided EList. + */ + void toList(EList& l) { + // Add this and all subsequent elements + DoublyLinkedList *cur = this; + while(cur != NULL) { + l.push_back(cur->payload); + cur = cur->next; + } + // Add all previous elements + cur = prev; + while(cur != NULL) { + l.push_back(cur->payload); + cur = cur->prev; + } + } + + T payload; + DoublyLinkedList *prev; + DoublyLinkedList *next; +}; + +template +struct Pair { + T1 a; + T2 b; + + Pair() : a(), b() { } + + Pair( + const T1& a_, + const T2& b_) { a = a_; b = b_; } + + bool operator==(const Pair& o) const { + return a == o.a && b == o.b; + } + + bool operator<(const Pair& o) const { + if(a < o.a) return true; + if(a > o.a) return false; + if(b < o.b) return true; + return false; + } +}; + +template +struct Triple { + T1 a; + T2 b; + T3 c; + + Triple() : a(), b(), c() { } + + Triple( + const T1& a_, + const T2& b_, + const T3& c_) { a = a_; b = b_; c = c_; } + + bool operator==(const Triple& o) const { + return a == o.a && b == o.b && c == o.c; + } + + bool operator<(const Triple& o) const { + if(a < o.a) return true; + if(a > o.a) return false; + if(b < o.b) return true; + if(b > o.b) return false; + if(c < o.c) return true; + return false; + } +}; + +template +struct Quad { + + Quad() : a(), b(), c(), d() { } + + Quad( + const T1& a_, + const T2& b_, + const T3& c_, + const T4& d_) { a = a_; b = b_; c = c_; d = d_; } + + Quad( + const T1& a_, + const T1& b_, + const T1& c_, + const T1& d_) + { + init(a_, b_, c_, d_); + } + + void init( + const T1& a_, + const T1& b_, + const T1& c_, + const T1& d_) + { + a = a_; b = b_; c = c_; d = d_; + } + + bool operator==(const Quad& o) const { + return a == o.a && b == o.b && c == o.c && d == o.d; + } + + bool operator<(const Quad& o) const { + if(a < o.a) return true; + if(a > o.a) return false; + if(b < o.b) return true; + if(b > o.b) return false; + if(c < o.c) return true; + if(c > o.c) return false; + if(d < o.d) return true; + return false; + } + + T1 a; + T2 b; + T3 c; + T4 d; +}; + +/** + * For assembling doubly-linked lists of EList. + */ +template +struct LinkedEListNode { + + LinkedEListNode() : payload(), next(NULL) { } + + T payload; + LinkedEListNode *next; +}; + +/** + * For assembling doubly-linked lists of EList. + */ +template +struct LinkedEList { + + LinkedEList() : head(NULL) { + ASSERT_ONLY(num_allocated = 0); + ASSERT_ONLY(num_new_node = 0); + ASSERT_ONLY(num_delete_node = 0); + } + + ~LinkedEList() { + ASSERT_ONLY(size_t num_deallocated = 0); + while(head != NULL) { + LinkedEListNode* next = head->next; + delete head; + ASSERT_ONLY(num_deallocated++); + head = next; + } + // daehwan - for debugging purposes + // assert_eq(num_allocated, num_deallocated); + } + + LinkedEListNode* new_node() { + ASSERT_ONLY(num_new_node++); + LinkedEListNode *result = NULL; + if(head == NULL) { + head = new LinkedEListNode(); + head-> next = NULL; + ASSERT_ONLY(num_allocated++); + } + assert(head != NULL); + result = head; + head = head->next; + assert(result != NULL); + return result; + } + + void delete_node(LinkedEListNode *node) { + ASSERT_ONLY(num_delete_node++); + assert(node != NULL); + // check if this is already deleted. +#ifndef NDEBUG + LinkedEListNode *temp = head; + while(temp != NULL) { + assert(temp != node); + temp = temp->next; + } +#endif + node->next = head; + head = node; + } + + LinkedEListNode *head; + + ASSERT_ONLY(size_t num_allocated); + ASSERT_ONLY(size_t num_new_node); + ASSERT_ONLY(size_t num_delete_node); +}; + + +#endif /* DS_H_ */ diff --git a/edit.cpp b/edit.cpp new file mode 100644 index 0000000..1187bad --- /dev/null +++ b/edit.cpp @@ -0,0 +1,501 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "edit.h" + +using namespace std; + +/** + * Print a single edit to a std::ostream. Format is + * (pos):(ref chr)>(read chr). Where 'pos' is an offset from the 5' + * end of the read, and the ref and read chrs are expressed w/r/t the + * Watson strand. + */ +ostream& operator<< (ostream& os, const Edit& e) { + if(e.type != EDIT_TYPE_SPL) { + os << e.pos << ":" << (char)e.chr << ">" << (char)e.qchr; + } else { + os << e.pos << ":" << e.splLen; + } + + return os; +} + +/** + * Print a list of edits to a std::ostream, separated by commas. + */ +void Edit::print(ostream& os, const EList& edits, char delim) { + for(size_t i = 0; i < edits.size(); i++) { + os << edits[i]; + if(i < edits.size()-1) os << delim; + } +} + +void Edit::complement(EList &edits) +{ + for(size_t i = 0; i < edits.size(); i++) { + Edit& e = edits[i]; + + if(e.type != EDIT_TYPE_SPL) { + assert_in(e.chr, "ACMGRSVTWYHKDBN-"); + assert_in(e.qchr, "ACGTN-"); + + e.chr = asc2dnacomp[e.chr]; + e.qchr = asc2dnacomp[e.qchr]; + } + } +} + +/** + * Flip all the edits.pos fields so that they're with respect to + * the other end of the read (of length 'sz'). + */ +void Edit::invertPoss( + EList& edits, + size_t sz, + size_t ei, + size_t en, + bool sort) +{ + // Invert elements + size_t ii = 0; + for(size_t i = ei; i < ei + en/2; i++) { + Edit tmp = edits[i]; + edits[i] = edits[ei + en - ii - 1]; + edits[ei + en - ii - 1] = tmp; + ii++; + } + for(size_t i = ei; i < ei + en; i++) { + assert(edits[i].pos < sz || + (edits[i].isReadGap() && edits[i].pos == sz)); + // Adjust pos + if(edits[i].isReadGap() || edits[i].isSpliced()) { + edits[i].pos = (uint32_t)(sz - edits[i].pos); + } else { + edits[i].pos = (uint32_t)(sz - edits[i].pos - 1); + } + // Adjust pos2 + if(edits[i].isReadGap()) { + int64_t pos2diff = (int64_t)(uint64_t)edits[i].pos2 - (int64_t)((uint64_t)std::numeric_limits::max() >> 1); + int64_t pos2new = (int64_t)(uint64_t)edits[i].pos2 - 2*pos2diff; + assert(pos2diff == 0 || (uint32_t)pos2new != (std::numeric_limits::max() >> 1)); + edits[i].pos2 = (uint32_t)pos2new; + } + } + if(sort) { + // Edits might not necessarily be in same order after inversion + edits.sortPortion(ei, en); +#ifndef NDEBUG + for(size_t i = ei + 1; i < ei + en; i++) { + assert_geq(edits[i].pos, edits[i-1].pos); + } +#endif + } +} + +/** + * For now, we pretend that the alignment is in the forward orientation + * and that the Edits are listed from left- to right-hand side. + */ +void Edit::printQAlign( + std::ostream& os, + const BTDnaString& read, + const EList& edits) +{ + printQAlign(os, "", read, edits); +} + +/** + * For now, we pretend that the alignment is in the forward orientation + * and that the Edits are listed from left- to right-hand side. + */ +void Edit::printQAlignNoCheck( + std::ostream& os, + const BTDnaString& read, + const EList& edits) +{ + printQAlignNoCheck(os, "", read, edits); +} + +/** + * For now, we pretend that the alignment is in the forward orientation + * and that the Edits are listed from left- to right-hand side. + */ +void Edit::printQAlign( + std::ostream& os, + const char *prefix, + const BTDnaString& read, + const EList& edits) +{ + size_t eidx = 0; + os << prefix; + // Print read + for(size_t i = 0; i < read.length(); i++) { + bool del = false, mm = false; + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + os << '-'; + } else if(edits[eidx].isRefGap()) { + del = true; + assert_eq((int)edits[eidx].qchr, read.toChar(i)); + os << read.toChar(i); + } else { + mm = true; + assert(edits[eidx].isMismatch()); + assert_eq((int)edits[eidx].qchr, read.toChar(i)); + os << (char)edits[eidx].qchr; + } + eidx++; + } + if(!del && !mm) os << read.toChar(i); + } + os << endl; + os << prefix; + eidx = 0; + // Print match bars + for(size_t i = 0; i < read.length(); i++) { + bool del = false, mm = false; + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + os << ' '; + } else if(edits[eidx].isRefGap()) { + del = true; + os << ' '; + } else { + mm = true; + assert(edits[eidx].isMismatch()); + os << ' '; + } + eidx++; + } + if(!del && !mm) os << '|'; + } + os << endl; + os << prefix; + eidx = 0; + // Print reference + for(size_t i = 0; i < read.length(); i++) { + bool del = false, mm = false; + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + os << (char)edits[eidx].chr; + } else if(edits[eidx].isRefGap()) { + del = true; + os << '-'; + } else { + mm = true; + assert(edits[eidx].isMismatch()); + os << (char)edits[eidx].chr; + } + eidx++; + } + if(!del && !mm) os << read.toChar(i); + } + os << endl; +} + +/** + * For now, we pretend that the alignment is in the forward orientation + * and that the Edits are listed from left- to right-hand side. + */ +void Edit::printQAlignNoCheck( + std::ostream& os, + const char *prefix, + const BTDnaString& read, + const EList& edits) +{ + size_t eidx = 0; + os << prefix; + // Print read + for(size_t i = 0; i < read.length(); i++) { + bool del = false, mm = false; + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + os << '-'; + } else if(edits[eidx].isRefGap()) { + del = true; + os << read.toChar(i); + } else { + mm = true; + os << (char)edits[eidx].qchr; + } + eidx++; + } + if(!del && !mm) os << read.toChar(i); + } + os << endl; + os << prefix; + eidx = 0; + // Print match bars + for(size_t i = 0; i < read.length(); i++) { + bool del = false, mm = false; + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + os << ' '; + } else if(edits[eidx].isRefGap()) { + del = true; + os << ' '; + } else { + mm = true; + os << ' '; + } + eidx++; + } + if(!del && !mm) os << '|'; + } + os << endl; + os << prefix; + eidx = 0; + // Print reference + for(size_t i = 0; i < read.length(); i++) { + bool del = false, mm = false; + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + os << (char)edits[eidx].chr; + } else if(edits[eidx].isRefGap()) { + del = true; + os << '-'; + } else { + mm = true; + os << (char)edits[eidx].chr; + } + eidx++; + } + if(!del && !mm) os << read.toChar(i); + } + os << endl; +} + +/** + * Sort the edits in the provided list. + */ +void Edit::sort(EList& edits) { + edits.sort(); // simple! +} + +/** + * Given a read string and some edits, generate and append the corresponding + * reference string to 'ref'. If read aligned to the Watson strand, the caller + * should pass the original read sequence and original edits. If a read + * aligned to the Crick strand, the caller should pass the reverse complement + * of the read and a version of the edits list that has had Edit:invertPoss + * called on it to cause edits to be listed in 3'-to-5' order. + */ +void Edit::toRef( + const BTDnaString& read, + const EList& edits, + BTDnaString& ref, + bool fw, + size_t trim5, + size_t trim3) +{ + // edits should be sorted + size_t eidx = 0; + // Print reference + const size_t rdlen = read.length(); + size_t trimBeg = fw ? trim5 : trim3; + size_t trimEnd = fw ? trim3 : trim5; + assert(Edit::repOk(edits, read, fw, trim5, trim3)); + if(!fw) { + invertPoss(const_cast&>(edits), read.length()-trimBeg-trimEnd, false); + } + for(size_t i = 0; i < rdlen; i++) { + ASSERT_ONLY(int c = read[i]); + assert_range(0, 4, c); + bool del = false, mm = false; + bool append = i >= trimBeg && rdlen - i - 1 >= trimEnd; + bool appendIns = i >= trimBeg && rdlen - i >= trimEnd; + while(eidx < edits.size() && edits[eidx].pos+trimBeg == i) { + if(edits[eidx].isReadGap()) { + // Inserted characters come before the position's + // character + if(appendIns) { + ref.appendChar((char)edits[eidx].chr); + } + } else if(edits[eidx].isRefGap()) { + assert_eq("ACGTN"[c], edits[eidx].qchr); + del = true; + } else if(edits[eidx].isMismatch()){ + mm = true; + assert(edits[eidx].qchr != edits[eidx].chr || edits[eidx].qchr == 'N'); + assert_eq("ACGTN"[c], edits[eidx].qchr); + if(append) { + ref.appendChar((char)edits[eidx].chr); + } + } + eidx++; + } + if(!del && !mm) { + if(append) { + ref.append(read[i]); + } + } + } + if(trimEnd == 0) { + while(eidx < edits.size()) { + assert_gt(rdlen, edits[eidx].pos); + if(edits[eidx].isReadGap()) { + ref.appendChar((char)edits[eidx].chr); + } + eidx++; + } + } + if(!fw) { + invertPoss(const_cast&>(edits), read.length()-trimBeg-trimEnd, false); + } +} + +#ifndef NDEBUG +/** + * Check that the edit is internally consistent. + */ +bool Edit::repOk() const { + assert(inited()); + // Ref and read characters cannot be the same unless they're both Ns + if(type != EDIT_TYPE_SPL) { + assert(qchr != chr || qchr == 'N'); + // Type must match characters + assert(isRefGap() || chr != '-'); + assert(isReadGap() || qchr != '-'); + assert(!isMismatch() || (qchr != '-' && chr != '-')); + } else { + assert_gt(splLen, 0); + } + return true; +} + +/** + * Given a list of edits and a DNA string representing the query + * sequence, check that the edits are consistent with respect to the + * query. + */ +bool Edit::repOk( + const EList& edits, + const BTDnaString& s, + bool fw, + size_t trimBeg, + size_t trimEnd) +{ + if(!fw) { + invertPoss(const_cast&>(edits), s.length()-trimBeg-trimEnd, false); + swap(trimBeg, trimEnd); + } + for(size_t i = 0; i < edits.size(); i++) { + const Edit& e = edits[i]; + size_t pos = e.pos; + if(i > 0) { + assert_geq(pos, edits[i-1].pos); + } + bool del = false, mm = false; + while(i < edits.size() && edits[i].pos == pos) { + const Edit& ee = edits[i]; + assert_lt(ee.pos, s.length()); + if(ee.type != EDIT_TYPE_SPL) { + if(ee.qchr != '-') { + assert(ee.isRefGap() || ee.isMismatch()); + //assert_eq((int)ee.qchr, s.toChar(ee.pos+trimBeg)); + } + } + if(ee.isMismatch()) { + assert(!mm); + mm = true; + assert(!del); + } else if(ee.isReadGap()) { + assert(!mm); + } else if(ee.isRefGap()) { + assert(!mm); + assert(!del); + del = true; + } else if(ee.isSpliced()) { + + } + i++; + } + } + if(!fw) { + invertPoss(const_cast&>(edits), s.length()-trimBeg-trimEnd, false); + } + return true; +} +#endif + +/** + * Merge second argument into the first. Assume both are sorted to + * begin with. + */ +void Edit::merge(EList& dst, const EList& src) { + size_t di = 0, si = 0; + while(di < dst.size()) { + if(src[si].pos < dst[di].pos) { + dst.insert(src[si], di); + si++; di++; + } else if(src[si].pos == dst[di].pos) { + // There can be two inserts at a given position, but we + // can't merge them because there's no way to know their + // order + assert(src[si].isReadGap() != dst[di].isReadGap()); + if(src[si].isReadGap()) { + dst.insert(src[si], di); + si++; di++; + } else if(dst[di].isReadGap()) { + di++; + } + } + } + while(si < src.size()) dst.push_back(src[si++]); +} + +/** + * Clip off some of the low-numbered positions. + */ +void Edit::clipLo(EList& ed, size_t len, size_t amt) { + size_t nrm = 0; + for(size_t i = 0; i < ed.size(); i++) { + assert_lt(ed[i].pos, len); + if(ed[i].pos < amt) { + nrm++; + } else { + // Shift everyone else up + ed[i].pos -= (uint32_t)amt; + } + } + ed.erase(0, nrm); +} + +/** + * Clip off some of the high-numbered positions. + */ +void Edit::clipHi(EList& ed, size_t len, size_t amt) { + assert_leq(amt, len); + size_t max = len - amt; + size_t nrm = 0; + for(size_t i = 0; i < ed.size(); i++) { + size_t ii = ed.size() - i - 1; + assert_lt(ed[ii].pos, len); + if(ed[ii].pos > max) { + nrm++; + } else if(ed[ii].pos == max && !ed[ii].isReadGap()) { + nrm++; + } else { + break; + } + } + ed.resize(ed.size() - nrm); +} diff --git a/edit.h b/edit.h new file mode 100644 index 0000000..c5ae2e8 --- /dev/null +++ b/edit.h @@ -0,0 +1,401 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef EDIT_H_ +#define EDIT_H_ + +#include +#include +#include +#include "assert_helpers.h" +#include "filebuf.h" +#include "sstring.h" +#include "ds.h" +#include "splice_site.h" + +/** + * 3 types of edits; mismatch (substitution), insertion in the + * reference, deletion in the reference. + */ +enum { + EDIT_TYPE_READ_GAP = 1, + EDIT_TYPE_REF_GAP, + EDIT_TYPE_MM, + EDIT_TYPE_SNP, + EDIT_TYPE_SPL, // splicing of pre-messenger RNAs into messenger RNAs +}; + +/** + * Encapsulates an edit between the read sequence and the reference sequence. + * We obey a few conventions when populating its fields. The fields are: + * + * uint8_t chr; // reference character involved (for subst and ins) + * uint8_t qchr; // read character involved (for subst and del) + * uint8_t type; // 1 -> mm, 2 -> SNP, 3 -> ins, 4 -> del + * uint32_t pos; // position w/r/t search root + * + * One convention is that pos is always an offset w/r/t the 5' end of the read. + * + * Another is that chr and qchr are expressed in terms of the nucleotides on + * the forward version of the read. So if we're aligning the reverse + * complement of the read, and an A in the reverse complement mismatches a C in + * the reference, chr should be G and qchr should be T. + */ +struct Edit { + + Edit() { reset(); } + + Edit( + uint32_t po, + int ch, + int qc, + int ty, + bool chrs = true, + uint32_t snp = std::numeric_limits::max()) + { + init(po, ch, qc, ty, chrs, snp); + } + + Edit( + uint32_t po, + int ch, + int qc, + int ty, + uint32_t sl, + uint8_t sdir, + bool knowns, + bool chrs = true) + { + init(po, ch, qc, ty, sl, sdir, knowns, chrs); + } + + /** + * Reset Edit to uninitialized state. + */ + void reset() { + pos = pos2 = std::numeric_limits::max(); + chr = qchr = type = 0; + splLen = 0; + splDir = SPL_UNKNOWN; + knownSpl = false; + snpID = std::numeric_limits::max(); + } + + /** + * Return true iff the Edit is initialized. + */ + bool inited() const { + return pos != std::numeric_limits::max(); + } + + /** + * Initialize a new Edit. + */ + void init( + uint32_t po, + int ch, + int qc, + int ty, + bool chrs = true, + uint32_t snp = std::numeric_limits::max()) + { + chr = ch; + qchr = qc; + type = ty; + splLen = 0; + splDir = SPL_UNKNOWN; + pos = po; + if(qc == '-') { + // Read gap + pos2 = std::numeric_limits::max() >> 1; + } else { + pos2 = std::numeric_limits::max(); + } + snpID = snp; + if(!chrs) { + assert_range(0, 4, (int)chr); + assert_range(0, 4, (int)qchr); + chr = "ACGTN"[chr]; + qchr = "ACGTN"[qchr]; + } +#ifndef NDEBUG + if(type != EDIT_TYPE_SPL) { + assert_in(chr, "ACMGRSVTWYHKDBN-"); + assert_in(qchr, "ACGTN-"); + assert(chr != qchr || chr == 'N'); + } +#endif + assert(inited()); + } + + /** + * Initialize a new Edit. + */ + void init( + uint32_t po, + int ch, + int qc, + int ty, + uint32_t sl, + uint32_t sdir, + bool knowns, + bool chrs = true) + { + assert_eq(ty, EDIT_TYPE_SPL); + init(po, ch, qc, ty, chrs); + splLen = sl; + splDir = sdir; + knownSpl = knowns; + } + + /** + * Return true iff one part of the edit or the other has an 'N'. + */ + bool hasN() const { + assert(inited()); + return chr == 'N' || qchr == 'N'; + } + + /** + * Edit less-than overload. + */ + int operator< (const Edit &rhs) const { + assert(inited()); + if(pos < rhs.pos) return 1; + if(pos > rhs.pos) return 0; + if(pos2 < rhs.pos2) return 1; + if(pos2 > rhs.pos2) return 0; + if(type < rhs.type) return 1; + if(type > rhs.type) return 0; + if(chr < rhs.chr) return 1; + if(chr > rhs.chr) return 0; + return (qchr < rhs.qchr)? 1 : 0; + } + + /** + * Edit equals overload. + */ + int operator== (const Edit &rhs) const { + assert(inited()); + if(type != rhs.type) + return false; + if(pos != rhs.pos) + return false; + if(type != EDIT_TYPE_SPL) { + return chr == rhs.chr && qchr == rhs.qchr; + } else { + return pos2 == rhs.pos2 && + splLen == rhs.splLen && + splDir == rhs.splDir /* && + knownSpl == rhs.knownSpl */; + } + } + + /** + * Return true iff this Edit is an initialized insertion. + */ + bool isReadGap() const { + assert(inited()); + return type == EDIT_TYPE_READ_GAP; + } + + /** + * Return true iff this Edit is an initialized deletion. + */ + bool isRefGap() const { + assert(inited()); + return type == EDIT_TYPE_REF_GAP; + } + + /** + * Return true if this Edit is either an initialized deletion or an + * initialized insertion. + */ + bool isGap() const { + assert(inited()); + return (type == EDIT_TYPE_REF_GAP || type == EDIT_TYPE_READ_GAP); + } + + bool isSpliced() const { + assert(inited()); + return type == EDIT_TYPE_SPL; + } + + /** + * Return the number of gaps in the given edit list. + */ + static size_t numGaps(const EList& es) { + size_t gaps = 0; + for(size_t i = 0; i < es.size(); i++) { + if(es[i].isGap()) gaps++; + } + return gaps; + } + + /** + * Return true iff this Edit is an initialized mismatch. + */ + bool isMismatch() const { + assert(inited()); + return type == EDIT_TYPE_MM; + } + + /** + * Sort the edits in the provided list. + */ + static void sort(EList& edits); + + /** + * Flip all the edits.pos fields so that they're with respect to + * the other end of the read (of length 'sz'). + */ + static void invertPoss( + EList& edits, + size_t sz, + size_t ei, + size_t en, + bool sort = false); + + /** + * Flip all the edits.pos fields so that they're with respect to + * the other end of the read (of length 'sz'). + */ + static void invertPoss(EList& edits, size_t sz, bool sort = false) { + invertPoss(edits, sz, 0, edits.size(), sort); + } + + static void complement(EList& edits); + + /** + * Clip off some of the low-numbered positions. + */ + static void clipLo(EList& edits, size_t len, size_t amt); + + /** + * Clip off some of the high-numbered positions. + */ + static void clipHi(EList& edits, size_t len, size_t amt); + + /** + * Given a read string and some edits, generate and append the + * corresponding reference string to 'ref'. + */ + static void toRef( + const BTDnaString& read, + const EList& edits, + BTDnaString& ref, + bool fw = true, + size_t trim5 = 0, + size_t trim3 = 0); + + /** + * Given a string and its edits with respect to some other string, + * print the alignment between the strings with the strings stacked + * vertically, with vertical bars denoting matches. + */ + static void printQAlign( + std::ostream& os, + const BTDnaString& read, + const EList& edits); + + /** + * Given a string and its edits with respect to some other string, + * print the alignment between the strings with the strings stacked + * vertically, with vertical bars denoting matches. Add 'prefix' + * before each line of output. + */ + static void printQAlign( + std::ostream& os, + const char *prefix, + const BTDnaString& read, + const EList& edits); + + /** + * Given a string and its edits with respect to some other string, + * print the alignment between the strings with the strings stacked + * vertically, with vertical bars denoting matches. + */ + static void printQAlignNoCheck( + std::ostream& os, + const BTDnaString& read, + const EList& edits); + + /** + * Given a string and its edits with respect to some other string, + * print the alignment between the strings with the strings stacked + * vertically, with vertical bars denoting matches. Add 'prefix' + * before each line of output. + */ + static void printQAlignNoCheck( + std::ostream& os, + const char *prefix, + const BTDnaString& read, + const EList& edits); + +#ifndef NDEBUG + bool repOk() const; + + /** + * Given a list of edits and a DNA string representing the query + * sequence, check that the edits are consistent with respect to the + * query. + */ + static bool repOk( + const EList& edits, + const BTDnaString& s, + bool fw = true, + size_t trim5 = 0, + size_t trim3 = 0); +#endif + + uint8_t chr; // reference character involved (for subst and ins) + uint8_t qchr; // read character involved (for subst and del) + uint8_t type; // 1 -> mm, 2 -> SNP, 3 -> ins, 4 -> del + uint32_t pos; // position w/r/t search root + uint32_t pos2; // Second int to take into account when sorting. Useful for + // sorting read gap edits that are all part of the same long + // gap. + + uint32_t splLen; // skip over the genome due to an intron + uint8_t splDir; + bool knownSpl; + + int64_t donor_seq; + int64_t acceptor_seq; + + uint32_t snpID; // snp ID + + friend std::ostream& operator<< (std::ostream& os, const Edit& e); + + /** + * Print a comma-separated list of Edits to given output stream. + */ + static void print( + std::ostream& os, + const EList& edits, + char delim = '\t'); + + /** + * Merge second argument into the first. Assume both are sorted to + * begin with. + */ + static void merge(EList& dst, const EList& src); +}; + +#endif /* EDIT_H_ */ diff --git a/endian_swap.h b/endian_swap.h new file mode 100644 index 0000000..762f274 --- /dev/null +++ b/endian_swap.h @@ -0,0 +1,160 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ENDIAN_SWAP_H +#define ENDIAN_SWAP_H + +#include +#include + +/** + * Return true iff the machine running this program is big-endian. + */ +static inline bool currentlyBigEndian() { + static uint8_t endianCheck[] = {1, 0, 0, 0}; + return *((uint32_t*)endianCheck) != 1; +} + +/** + * Return copy of uint32_t argument with byte order reversed. + */ +static inline uint16_t endianSwapU16(uint16_t u) { + uint16_t tmp = 0; + tmp |= ((u >> 8) & (0xff << 0)); + tmp |= ((u << 8) & (0xff << 8)); + return tmp; +} + +/** + * Return copy of uint32_t argument with byte order reversed. + */ +static inline uint32_t endianSwapU32(uint32_t u) { + uint32_t tmp = 0; + tmp |= ((u >> 24) & (0xff << 0)); + tmp |= ((u >> 8) & (0xff << 8)); + tmp |= ((u << 8) & (0xff << 16)); + tmp |= ((u << 24) & (0xff << 24)); + return tmp; +} + +/** + * Return copy of uint64_t argument with byte order reversed. + */ +static inline uint64_t endianSwapU64(uint64_t u) { + uint64_t tmp = 0; + tmp |= ((u >> 56) & (0xffull << 0)); + tmp |= ((u >> 40) & (0xffull << 8)); + tmp |= ((u >> 24) & (0xffull << 16)); + tmp |= ((u >> 8) & (0xffull << 24)); + tmp |= ((u << 8) & (0xffull << 32)); + tmp |= ((u << 24) & (0xffull << 40)); + tmp |= ((u << 40) & (0xffull << 48)); + tmp |= ((u << 56) & (0xffull << 56)); + return tmp; +} + +/** + * Return copy of uint_t argument with byte order reversed. + */ +template +static inline index_t endianSwapIndex(index_t u) { + if(sizeof(index_t) == 8) { + return (index_t)endianSwapU64(u); + } else if(sizeof(index_t) == 4) { + return endianSwapU32((uint32_t)u); + } else { + return endianSwapU16(u); + } +} + +/** + * Return copy of int16_t argument with byte order reversed. + */ +static inline int16_t endianSwapI16(int16_t i) { + int16_t tmp = 0; + tmp |= ((i >> 8) & (0xff << 0)); + tmp |= ((i << 8) & (0xff << 8)); + return tmp; +} + +/** + * Convert uint16_t argument to the specified endianness. It's assumed + * that u currently has the endianness of the current machine. + */ +static inline uint16_t endianizeU16(uint16_t u, bool toBig) { + if(toBig == currentlyBigEndian()) { + return u; + } + return endianSwapU16(u); +} + +/** + * Convert int16_t argument to the specified endianness. It's assumed + * that u currently has the endianness of the current machine. + */ +static inline int16_t endianizeI16(int16_t i, bool toBig) { + if(toBig == currentlyBigEndian()) { + return i; + } + return endianSwapI16(i); +} + +/** + * Return copy of int32_t argument with byte order reversed. + */ +static inline int32_t endianSwapI32(int32_t i) { + int32_t tmp = 0; + tmp |= ((i >> 24) & (0xff << 0)); + tmp |= ((i >> 8) & (0xff << 8)); + tmp |= ((i << 8) & (0xff << 16)); + tmp |= ((i << 24) & (0xff << 24)); + return tmp; +} + +/** + * Convert uint32_t argument to the specified endianness. It's assumed + * that u currently has the endianness of the current machine. + */ +static inline uint32_t endianizeU32(uint32_t u, bool toBig) { + if(toBig == currentlyBigEndian()) { + return u; + } + return endianSwapU32(u); +} + +/** + * Convert int32_t argument to the specified endianness. It's assumed + * that u currently has the endianness of the current machine. + */ +static inline int32_t endianizeI32(int32_t i, bool toBig) { + if(toBig == currentlyBigEndian()) { + return i; + } + return endianSwapI32(i); +} + +template +index_t endianizeIndex(index_t u, bool toBig) { + if(toBig == currentlyBigEndian()) { + return u; + } + return endianSwapIndex(u); +} + +#endif diff --git a/evaluation/build_indexes.py b/evaluation/build_indexes.py new file mode 100644 index 0000000..95bd109 --- /dev/null +++ b/evaluation/build_indexes.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python + +import sys, os +use_message = ''' +''' + +# GRCh38 release 84 +def build_indexes(): + # Build indexes + if not os.path.exists("indexes"): + os.mkdir("indexes") + os.chdir("indexes") + aligners = ["HISAT2", "HISAT", "Bowtie", "STAR", "GSNAP", "BWA", "minimap2"] + genomes = ["22_20-21M", "22", "genome"] + for genome in genomes: + for aligner in aligners: + if genome == "genome": + dir = aligner + else: + dir = aligner + "_" + genome + if os.path.exists(dir): + continue + os.mkdir(dir) + os.chdir(dir) + if aligner == "HISAT2": + cmd = "../../aligners/bin/hisat2-build ../../data/%s.fa %s" % (genome, genome) + cmd = cmd + "; ../../aligners/bin/hisat2-build -p 4 ../../data/%s.fa --snp ../../data/%s.snp --haplotype ../../data/%s.haplotype %s_snp" % (genome, genome, genome, genome) + cmd = cmd + "; ../../aligners/bin/hisat2-build -p 4 ../../data/%s.fa --ss ../../data/%s.ss --exon ../../data/%s.exon %s_tran" % (genome, genome, genome, genome) + cmd = cmd + "; ../../aligners/bin/hisat2-build -p 4 ../../data/%s.fa --snp ../../data/%s.snp --haplotype ../../data/%s.haplotype --ss ../../data/%s.ss --exon ../../data/%s.exon %s_snp_tran" % (genome, genome, genome, genome, genome, genome) + elif aligner == "HISAT": + cmd = "../../aligners/bin/hisat-build ../../data/%s.fa %s" % (genome, genome) + cmd = cmd + "; ../../aligners/bin/tophat -G ../../data/%s.gtf --transcriptome-index=gtf %s; rm -rf tophat_out" % (genome, genome) + elif aligner == "Bowtie": + cmd = "../../aligners/bin/bowtie-build ../../data/%s.fa %s" % (genome, genome) + elif aligner == "Bowtie2": + cmd = "../../aligners/bin/bowtie2-build --threads 6 ../../data/%s.fa %s" % (genome, genome) + elif aligner == "STAR": + cmd = "../../aligners/bin/STAR --runMode genomeGenerate --genomeDir . --genomeFastaFiles ../../data/%s.fa" % (genome) + cmd = cmd + "; mkdir gtf; ../../aligners/bin/STAR --runMode genomeGenerate --genomeDir gtf --genomeFastaFiles ../../data/%s.fa --sjdbGTFfile ../../data/%s.gtf --sjdbOverhang 99 --runThreadN 4" % (genome, genome) + elif aligner == "GSNAP": + cmd = "../../aligners/bin/gmap_build -B ../../aligners/bin -D . -d %s ../../data/%s.fa" % (genome, genome) + elif aligner == "BWA": + cmd = "../../aligners/bin/bwa index -p %s.fa ../../data/%s.fa" % (genome, genome) + elif aligner == "minimap2": + cmd = "../../aligners/bin/minimap2 -x sr -d %s.mmi ../../data/%s.fa" % (genome, genome) + elif aligner == "VG": + assert False + else: + assert False + print >> sys.stderr, cmd + os.system(cmd) + os.chdir("..") + + os.chdir("..") + + +if __name__ == "__main__": + build_indexes() diff --git a/evaluation/generate_reads.py b/evaluation/generate_reads.py new file mode 100644 index 0000000..eed84d6 --- /dev/null +++ b/evaluation/generate_reads.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python + +import sys, os, random +from argparse import ArgumentParser, FileType +from multiprocessing import Process + +def shuffle_reads(read_fname, random_list): + reads = [] + read_file = open(read_fname) + for line in read_file: + if line[0] == ">": + reads.append([]) + reads[-1].append(line[:-1]) + read_file.close() + + read_fname_out = read_fname + ".shuffle" + read_file_out = open(read_fname_out, "w") + assert len(random_list) == len(reads) + for i in random_list: + read = reads[random_list[i]] + print >> read_file_out, "\n".join(read) + read_file_out.close() + + +def shuffle_pairs(read1_fname, read2_fname): + read1_file = open(read1_fname) + num_reads = 0 + for line in read1_file: + if line[0] == ">": + num_reads += 1 + read1_file.close() + + random_list = [i for i in range(num_reads)] + random.shuffle(random_list) + + shuffle_reads(read1_fname, random_list) + shuffle_reads(read2_fname, random_list) + + +def simulate_reads(): + if not os.path.exists("reads"): + os.mkdir("reads") + os.chdir("reads") + if not os.path.exists("simulation"): + os.mkdir("simulation") + os.chdir("simulation") + + _rna, _mismatch, _snp, _constant = True, True, True, True + _dna = not _rna + datasets = [ + ["22", 1000000, _dna, not _snp, not _mismatch, _constant], + ["22", 1000000, _dna, not _snp, _mismatch, _constant], + ["22", 1000000, _dna, _snp, not _mismatch, _constant], + ["22", 1000000, _dna, _snp, _mismatch, _constant], + ["22", 1000000, _rna, not _snp, not _mismatch, not _constant], + ["22", 1000000, _rna, not _snp, not _mismatch, _constant], + ["22", 1000000, _rna, not _snp, _mismatch, not _constant], + ["22", 1000000, _rna, not _snp, _mismatch, _constant], + ["22", 1000000, _rna, _snp, not _mismatch, not _constant], + ["22", 1000000, _rna, _snp, not _mismatch, _constant], + ["22", 1000000, _rna, _snp, _mismatch, not _constant], + ["22", 1000000, _rna, _snp, _mismatch, _constant], + # ["22_20-21M", 1000000, _rna, not _snp, not _mismatch, not _constant], + # ["22_20-21M", 1000000, _rna, _snp, not _mismatch, _constant], + ["genome", 10000000, _dna, not _snp, not _mismatch, _constant], + ["genome", 10000000, _dna, _snp, not _mismatch, _constant], + ["genome", 10000000, _dna, _snp, _mismatch, _constant], + ["genome", 10000000, _rna, not _snp, not _mismatch, not _constant], + ["genome", 10000000, _rna, _snp, not _mismatch, not _constant], + ["genome", 10000000, _rna, _snp, _mismatch, not _constant], + ] + + data_dir_base = "../../../data" + + def generate_reads(cmd): + print >> sys.stderr, cmd + os.system(cmd) + + random.seed(0) + print >> sys.stderr, "shuffle reads sim_1.fa and sim_2.fa" + shuffle_pairs("sim_1.fa", "sim_2.fa") + shuffle_reads_cmd = " mv sim_1.fa.shuffle sim_1.fa" + shuffle_reads_cmd += "; mv sim_2.fa.shuffle sim_2.fa" + os.system(shuffle_reads_cmd) + + + pid_list = [] + + for genome, numreads, rna, snp, mismatch, constant in datasets: + if rna: + molecule = "RNA" + else: + molecule = "DNA" + if numreads >= 1000000: + dirname = "%dM_%s" % (numreads / 1000000, molecule) + else: + dirname = "%dk_%s" % (numreads / 1000, molecule) + + if mismatch: + dirname += "_mismatch" + if snp: + dirname += "_snp" + if rna and constant: + dirname += "_constant" + dirname += "_reads" + dirname += ("_" + genome) + if os.path.exists(dirname): + continue + os.mkdir(dirname) + os.chdir(dirname) + genome_fname = data_dir_base + "/%s.fa" % (genome) + + if rna: + gtf_fname = data_dir_base + "/%s.gtf" % (genome) + else: + gtf_fname = "/dev/null" + + if snp: + snp_fname = data_dir_base + "/%s.snp" % (genome) + else: + snp_fname = "/dev/null" + + cmd_add = "" + if not rna: + cmd_add += "--dna " + if mismatch: + cmd_add += "--error-rate 0.2 " + if rna and constant: + cmd_add += "--expr-profile constant " + cmd = "../../../aligners/bin/hisat2_simulate_reads.py --sanity-check %s --num-fragment %d %s %s %s sim" % \ + (cmd_add, numreads, genome_fname, gtf_fname, snp_fname) + + """ + print >> sys.stderr, cmd + os.system(cmd) + + random.seed(0) + print >> sys.stderr, "shuffle reads sim_1.fa and sim_2.fa" + shuffle_pairs("sim_1.fa", "sim_2.fa") + shuffle_reads_cmd = " mv sim_1.fa.shuffle sim_1.fa" + shuffle_reads_cmd += "; mv sim_2.fa.shuffle sim_2.fa" + os.system(shuffle_reads_cmd) + """ + #generate_reads(cmd) + p = Process(target=generate_reads, args=(cmd,)) + p.start() + pid_list.append(p) + + os.chdir("..") + + os.chdir("..") + + # wait + for p in pid_list: + p.join() + + +if __name__ == "__main__": + parser = ArgumentParser( + description='Generate reads using simulate_reads.py in HISAT2') + args = parser.parse_args() + simulate_reads() diff --git a/evaluation/get_data.py b/evaluation/get_data.py new file mode 100644 index 0000000..3e49e95 --- /dev/null +++ b/evaluation/get_data.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python + +import sys, os +from argparse import ArgumentParser, FileType + +def get_data(small = False): + data_root = "http://www.ccb.jhu.edu/software/hisat2/downloads/evaluation" + + # Download the reference human genome, SNPs, and gene annotations + if not os.path.exists("data"): + os.mkdir("data") + os.chdir("data") + genome_files = ["genome.fa", "genome.fa.fai", "genome.gtf", "snpCommon.txt", "genome.snp", "genome.ss", "genome.exon"] + small_genome_files = ["22.fa", "22.fa.fai", "22.gtf", "22.snp", "22.ss", "22.exon", \ + "22_20-21M.fa", "22_20-21M.fa.fai", "22_20-21M.gtf", "22_20-21M.snp", "22_20-21M.ss", "22_20-21M.exon"] + files = [] + if not small: + files += genome_files + files += small_genome_files + for file in files: + if os.path.exists(file): + continue + wget_cmd = "wget %s/data/%s" % (data_root, file) + print >> sys.stderr, wget_cmd + os.system(wget_cmd) + os.chdir("..") + + # Download indexes + if not os.path.exists("indexes"): + os.mkdir("indexes") + os.chdir("indexes") + aligners = ["HISAT2", "HISAT", "Bowtie", "STAR", "GSNAP"] + for genome in ["genome", "22", "22_20-21M"]: + if small and genome == "genome": + continue + for aligner in aligners: + if genome == "genome": + aligner_dir = aligner + else: + aligner_dir = aligner + "_" + genome + if os.path.exists(aligner_dir): + continue + cmd = "wget %s/indexes/%s.tar.gz; tar xvzf %s.tar.gz; rm %s.tar.gz" % \ + (data_root, aligner_dir, aligner_dir, aligner_dir) + print >> sys.stderr, cmd + os.system(cmd) + os.chdir("..") + + # Download simulated and real reads + if not os.path.exists("reads"): + os.mkdir("reads") + os.chdir("reads") + for type in ["simulation", "real"]: + if small and type == "real": + continue + if not os.path.exists(type): + os.mkdir(type) + os.chdir(type) + if type == "simulation": + files = ["1M_DNA_reads_22", + "1M_DNA_mismatch_reads_22", + "1M_DNA_snp_reads_22", + "1M_DNA_mismatch_snp_reads_22", + "1M_RNA_reads_22", + "1M_RNA_constant_reads_22", + "1M_RNA_mismatch_reads_22", + "1M_RNA_snp_reads_22", + "1M_RNA_mismatch_snp_reads_22", + "1M_RNA_reads_22_20-21M", + "20M_DNA_reads_genome", + "20M_DNA_snp_reads_genome", + "20M_RNA_reads_genome", + "20M_RNA_snp_reads_genome"] + else: + files = ["108M_RNA_wgEncodeCshlLongRnaSeq", + "62M_RNA_SRR353653", + "80M_DNA_SRR345300", + "5M_DNA_NA12878D"] + for file in files: + if small and file.find("20M") != -1: + continue + if os.path.exists(file): + continue + cmd = "wget %s/reads/%s/%s.tar.gz; tar xvzf %s.tar.gz; rm %s.tar.gz" % \ + (data_root, type, file, file, file) + print >> sys.stderr, cmd + os.system(cmd) + os.chdir("..") + + os.chdir("..") + + +if __name__ == "__main__": + parser = ArgumentParser( + description='Get reference genome, annotations, and indexes') + parser.add_argument('-s', '--small', + dest='small', + action='store_true', + default=False, + help='small testset') + args = parser.parse_args() + get_data(args.small) diff --git a/evaluation/get_programs.py b/evaluation/get_programs.py new file mode 100644 index 0000000..5d497c6 --- /dev/null +++ b/evaluation/get_programs.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python + +import sys, os +use_message = ''' +''' + +def get_aligners(): + mac = (sys.platform == "darwin") + if not os.path.exists("aligners"): + os.mkdir("aligners") + os.chdir("aligners") + if not os.path.exists("bin"): + os.mkdir("bin") + programs = ["HISAT", "Bowtie2", "Bowtie", "TopHat2", "STAR", "GSNAP", "BWA", "StringTie", "Cufflinks", "minimap2"] + for program in programs: + if program == "HISAT": + dir = "hisat-0.1.6-beta" + if os.path.exists(dir): + continue + fname = dir + "-source.zip" + url = "http://www.ccb.jhu.edu/software/hisat/downloads" + bins = "hisat-align-s hisat-build-s hisat-inspect-s" + installs = bins + " hisat hisat-build hisat-inspect" + cmd = "wget %s/%s; unzip %s; cd %s; make %s; cp %s ../bin; cd .." % \ + (url, fname, fname, dir, bins, installs) + elif program == "Bowtie2": + dir = "bowtie2-2.3.4.3" + if os.path.exists(dir): + continue + fname = dir + "-source.zip" + url = "http://sourceforge.net/projects/bowtie-bio/files/bowtie2/2.3.4.3" + bins = "bowtie2-align-s bowtie2-build-s bowtie2-inspect-s" + installs = bins + " bowtie2 bowtie2-build bowtie2-inspect" + cmd = "wget %s/%s; unzip %s; cd %s; make NO_TBB=1 %s; cp %s ../bin; cd .." % \ + (url, fname, fname, dir, bins, installs) + elif program == "Bowtie": + dir = "bowtie-1.1.2" + if os.path.exists(dir): + continue + fname = dir + "-src.zip" + url = "http://sourceforge.net/projects/bowtie-bio/files/bowtie/1.1.2" + bins = "bowtie-align-s bowtie-build-s bowtie-inspect-s" + installs = bins + " bowtie bowtie-build bowtie-inspect" + cmd = "wget %s/%s; unzip %s; cd %s; make %s; cp %s ../bin; cd .." % \ + (url, fname, fname, dir, bins, installs) + elif program == "minimap2": + dir = "minimap2-2.12" + if os.path.exists(dir): + continue + fname = dir + ".tar.bz2" + #https://github.com/lh3/minimap2/releases/download/v2.12/minimap2-2.12.tar.bz2 + url = "https://github.com/lh3/minimap2/releases/download/v2.12" + bins = "minimap2" + cmd = "wget %s/%s; tar jxvf %s; cd %s; make ; cp %s ../bin; cd .." % \ + (url, fname, fname, dir,bins) + elif program == "TopHat2": + if mac: + dir = "tophat-2.1.0.OSX_x86_64" + else: + dir = "tophat-2.1.0.Linux_x86_64" + if os.path.exists(dir): + continue + fname = dir + ".tar.gz" + url = "http://ccb.jhu.edu/software/tophat/downloads" + installs = "gtf_juncs juncs_db prep_reads segment_juncs tophat tophat_reports sra_to_solid samtools_0.1.18 map2gtf fix_map_ordering bam_merge long_spanning_reads sam_juncs gtf_to_fasta bam2fastx" + cmd = "wget %s/%s; tar xvzf %s; cd %s; cp %s ../bin; cd .." % \ + (url, fname, fname, dir, installs) + elif program == "STAR": + dir = "2.5.2b" + if os.path.exists("STAR-" + dir): + continue + fname = dir + ".tar.gz" + url = "https://github.com/alexdobin/STAR/archive" + if mac: + add_cmd = "awk '{if($1 ~ /^CXX/) {print \"CXX =/opt/local/bin/g++-mp-4.8\";} else {print;}}' Makefile > Makefile.tmp; mv Makefile.tmp Makefile" + make_arg = "STARforMac" + cmd = "wget %s/%s; tar xvzf %s; cd STAR-%s/source; %s; make; make %s; cp STAR ../../bin; cd ../.." % \ + (url, fname, fname, dir, add_cmd, make_arg) + else: + cmd = "wget %s/%s; tar xvzf %s; cd STAR-%s/source; make; cp STAR ../../bin; cd ../.." % \ + (url, fname, fname, dir) + elif program == "GSNAP": + dir = "gmap-2015-07-23" + dir2 = "gmap-gsnap-2015-07-23" + if os.path.exists(dir): + continue + fname = dir2 + ".tar.gz" + url = "http://research-pub.gene.com/gmap/src" + installs = "gmap gmapl get-genome gmapindex iit_store iit_get iit_dump gsnap gsnapl uniqscan uniqscanl snpindex cmetindex atoiindex sam_sort ../util/*" + cmd = "wget %s/%s; tar xvzf %s; cd %s; ./configure; make; cd src; cp %s ../../bin; cd ../.." % \ + (url, fname, fname, dir, installs) + elif program == "BWA": + dir = "bwa-0.7.17" + if os.path.exists(dir): + continue + url = "http://sourceforge.net/projects/bio-bwa/files/%s.tar.bz2" % (dir) + installs = "bwa" + cmd = "wget %s; tar xvjf %s.tar.bz2; cd %s; make; cp %s ../bin/; cd .." % (url, dir, dir, installs) + elif program == "StringTie": + dir = "stringtie-1.0.4" + url = "http://ccb.jhu.edu/software/stringtie/dl" + bins = "stringtie" + cmd = "wget %s/%s.tar.gz; tar xvzf %s.tar.gz; cd %s; make release; cp %s ../bin; cd .." % \ + (url, dir, dir, dir, bins) + elif program == "Cufflinks": + cmd = "" + elif program == "vg": + version = "v1.13.0" + dir = program + "-" + version + url = "https://github.com/vgteam/vg/releases/download/%s" % (version) + cmd = "wget %s/%s.tar.gz; tar zxvf %s.tar.gz; cd %s" % (url, dir, dir, dir) + cmd += "; source ./source_me.sh; make; cp bin/%s ../bin; cd .." % (program) + else: + assert False + print >> sys.stderr, cmd + os.system(cmd) + + files = ["hisat2", "hisat2-align-s", "hisat2-build", "hisat2-build-s", "hisat2-inspect", "hisat2-inspect-s", "extract_splice_sites.py", "hisat2_extract_snps_haplotypes_UCSC.py", "hisat2_simulate_reads.py"] + os.chdir("bin") + for file in files: + if os.path.exists(file): + continue + os.system("ln -s ../../../%s %s" % (file, file)) + os.chdir("..") + + os.chdir("..") + + +if __name__ == "__main__": + get_aligners() diff --git a/evaluation/real/calculate_read_cost.py b/evaluation/real/calculate_read_cost.py new file mode 100644 index 0000000..82899e0 --- /dev/null +++ b/evaluation/real/calculate_read_cost.py @@ -0,0 +1,1675 @@ +#!/usr/bin/env python + +import sys, os, subprocess, signal +import multiprocessing +import platform +import string +import re +from datetime import datetime, date, time +from collections import defaultdict +from argparse import ArgumentParser, FileType + +osx_mode = False +if sys.platform == 'darwin': + osx_mode = True + +MAX_EDIT = 21 +signal.signal(signal.SIGPIPE, signal.SIG_DFL) + +cigar_re = re.compile('\d+\w') + +""" +""" +def parse_mem_usage(resource): + if osx_mode: + resource = resource.strip().split('\n') + for line in resource: + if line.find('maximum resident set size') != -1: + return int(line.split()[0]) / 1024 + else: + resource = resource.split(' ') + for line in resource: + idx = line.find('maxresident') + if idx != -1: + return line[:idx] + + return '0' + + +""" +""" +def reverse_complement(seq): + result = "" + for nt in seq: + base = nt + if nt == 'A': + base = 'T' + elif nt == 'a': + base = 't' + elif nt == 'C': + base = 'G' + elif nt == 'c': + base = 'g' + elif nt == 'G': + base = 'C' + elif nt == 'g': + base = 'c' + elif nt == 'T': + base = 'A' + elif nt == 't': + base = 'a' + + result = base + result + + return result + + +""" +""" +def read_genome(genome_filename): + chr_dic = {} + genome_file = open(genome_filename, "r") + + chr_name, sequence = "", "" + for line in genome_file: + if line[0] == ">": + if chr_name and sequence: + chr_dic[chr_name] = sequence + + chr_name = line[1:-1].split()[0] + sequence = "" + else: + sequence += line[:-1] + + if chr_name and sequence: + chr_dic[chr_name] = sequence + + genome_file.close() + + print >> sys.stderr, "genome is loaded" + + return chr_dic + + +""" +""" +def read_snp(snp_filename): + snps = defaultdict(list) + snp_file = open(snp_filename, 'r') + + for line in snp_file: + line = line.strip() + if not line or line.startswith('#'): + continue + try: + snpID, type, chr, pos, data = line.split('\t') + except ValueError: + continue + + assert type in ["single", "deletion", "insertion"] + if type == "deletion": + data = int(data) + snps[chr].append([snpID, type, int(pos), data]) + + print >> sys.stderr, "snp is loaded" + + return snps + + +""" +""" +def extract_splice_sites(gtf_fname): + trans = {} + + gtf_file = open(gtf_fname) + # Parse valid exon lines from the GTF file into a dict by transcript_id + for line in gtf_file: + line = line.strip() + if not line or line.startswith('#'): + continue + if '#' in line: + line = line.split('#')[0].strip() + + try: + chrom, source, feature, left, right, score, \ + strand, frame, values = line.split('\t') + except ValueError: + continue + left, right = int(left), int(right) + + if feature != 'exon' or left >= right: + continue + + values_dict = {} + for attr in values.split(';')[:-1]: + attr, _, val = attr.strip().partition(' ') + values_dict[attr] = val.strip('"') + + if 'gene_id' not in values_dict or \ + 'transcript_id' not in values_dict: + continue + + transcript_id = values_dict['transcript_id'] + if transcript_id not in trans: + trans[transcript_id] = [chrom, strand, [[left, right]]] + else: + trans[transcript_id][2].append([left, right]) + + gtf_file.close() + + # Sort exons and merge where separating introns are <=5 bps + for tran, [chrom, strand, exons] in trans.items(): + exons.sort() + tmp_exons = [exons[0]] + for i in range(1, len(exons)): + if exons[i][0] - tmp_exons[-1][1] <= 5: + tmp_exons[-1][1] = exons[i][1] + else: + tmp_exons.append(exons[i]) + trans[tran] = [chrom, strand, tmp_exons] + + # Calculate and print the unique junctions + junctions = set() + for chrom, strand, exons in trans.values(): + for i in range(1, len(exons)): + junctions.add(to_junction_str([chrom, exons[i-1][1], exons[i][0]])) + + return junctions + + +def to_junction_str(junction): + return "%s-%d-%d" % (junction[0], junction[1], junction[2]) + + +def to_junction(junction_str): + chr, left, right = junction_str.split("-") + return [chr, int(left), int(right)] + + +def junction_cmp(a, b): + if a[0] != b[0]: + if a[0] < b[0]: + return -1 + else: + return 1 + + if a[1] != b[1]: + if a[1] < b[1]: + return -1 + else: + return 1 + + if a[2] != b[2]: + if a[2] < b[2]: + return -1 + else: + return 1 + + return 0 + + +# chr and pos are assumed to be integers +def get_junctions(chr, pos, cigar_str, min_anchor_len = 0, read_len = 100): + junctions = [] + right_pos = pos + cigars = cigar_re.findall(cigar_str) + cigars = [[int(cigars[i][:-1]), cigars[i][-1]] for i in range(len(cigars))] + + left_anchor_lens = [] + cur_left_anchor_len = 0 + for i in range(len(cigars)): + length, cigar_op = cigars[i] + if cigar_op in "MI": + cur_left_anchor_len += length + elif cigar_op == "N": + assert cur_left_anchor_len > 0 + left_anchor_lens.append(cur_left_anchor_len) + cur_left_anchor_len = 0 + + for i in range(len(cigars)): + length, cigar_op = cigars[i] + if cigar_op == "N": + left, right = right_pos - 1, right_pos + length + + if i > 0 and cigars[i-1][1] in "ID": + if cigars[i-1][1] == "I": + left += cigars[i-1][0] + else: + left -= cigars[i-1][0] + if i + 1 < len(cigars) and cigars[i+1][1] in "ID": + if cigars[i+1][1] == "I": + right -= cigars[i+1][0] + else: + right += cigars[i+1][0] + + junction_idx = len(junctions) + assert junction_idx < len(left_anchor_lens) + left_anchor_len = left_anchor_lens[junction_idx] + assert left_anchor_len > 0 and left_anchor_len < read_len + right_anchor_len = read_len - left_anchor_len + if left_anchor_len >= min_anchor_len and right_anchor_len >= min_anchor_len: + junctions.append([chr, left, right]) + + if cigar_op in "MND": + right_pos += length + + return junctions + + +def get_right(pos, cigars): + right_pos = pos + cigars = cigar_re.findall(cigars) + for cigar in cigars: + length = int(cigar[:-1]) + cigar_op = cigar[-1] + if cigar_op in "MDN": + right_pos += length + + return right_pos + +def get_cigar_chars(cigars): + cigars = cigar_re.findall(cigars) + cigar_chars = "" + for cigar in cigars: + cigar_op = cigar[-1] + cigar_chars += cigar_op + + return cigar_chars + +def get_cigar_chars_MN(cigars): + cigars = cigar_re.findall(cigars) + cigar_chars = "" + for cigar in cigars: + cigar_op = cigar[-1] + if cigar_op in "MN": + if cigar_chars == "" or cigar_chars[-1] != cigar_op: + cigar_chars += cigar_op + + return cigar_chars + +def is_non_canonical_junction_read(chr_dic, chr, left, cigars, canonical_junctions = [["GT", "AG"], ["GC", "AG"], ["AT", "AC"]]): + pos = left + for cigar in cigar_re.findall(cigars): + cigar_op = cigar[-1] + cigar_len = int(cigar[:-1]) + + if cigar_op in 'MD': + pos += cigar_len + elif cigar_op == 'N': + right = pos + cigar_len + + donor = chr_dic[chr][pos-1:pos+1] + acceptor = chr_dic[chr][right-3:right-1] + + rev_donor = reverse_complement(acceptor) + rev_acceptor = reverse_complement(donor) + + # print donor, acceptor + # print rev_donor, rev_acceptor + + if [donor, acceptor] not in canonical_junctions and [rev_donor, rev_acceptor] not in canonical_junctions: + return True + + pos = right + + return False + +def is_canonical_junction(chr_dic, junction): + chr, left, right = junction + donor = chr_dic[chr][left:left+2] + acceptor = chr_dic[chr][right-3:right-1] + rev_donor = reverse_complement(acceptor) + rev_acceptor = reverse_complement(donor) + + if (donor == "GT" and acceptor == "AG") or \ + (rev_donor == "GT" and rev_acceptor == "AG"): + return True + + return False + +def is_junction_read(chr_dic, gtf_junctions, chr, pos, cigar_str): + result_junctions = [] + junctions = get_junctions(chr, pos, cigar_str, 0, 101) + for junction in junctions: + junction_str = to_junction_str(junction) + is_gtf_junction = False + def find_in_gtf_junctions(gtf_junctions, junction): + l, u = 0, len(gtf_junctions) + while l < u: + m = (l + u) / 2 + assert m >= 0 and m < len(gtf_junctions) + cmp_result = junction_cmp(junction, gtf_junctions[m]) + if cmp_result == 0: + return m + elif cmp_result < 0: + u = m + else: + l = m + 1 + + return l + + # allow small (<= 5bp) discrepancy for non-canonical splice sites. + relaxed_junction_dist = 5 + chr, left, right = junction + gtf_index = find_in_gtf_junctions(gtf_junctions, [chr, left - relaxed_junction_dist, right - relaxed_junction_dist]) + if gtf_index >= 0: + i = gtf_index + while i < len(gtf_junctions): + chr2, left2, right2 = gtf_junctions[i] + if chr2 > chr or \ + left2 - left > relaxed_junction_dist or \ + right2 - right > relaxed_junction_dist: + break + + if abs(left - left2) <= relaxed_junction_dist and left - left2 == right - right2: + canonical = is_canonical_junction(chr_dic, gtf_junctions[i]) + if left == left2 or not canonical: + is_gtf_junction = True + break + + i += 1 + + result_junctions.append([junction_str, is_gtf_junction]) + + is_gtf_junction_read = False + if len(result_junctions) > 0: + is_gtf_junction_read = True + for junction_str, is_gtf_junction in result_junctions: + if not is_gtf_junction: + is_gtf_junction_read = False + break + + return result_junctions, len(result_junctions) > 0, is_gtf_junction_read + + +def is_junction_pair(chr_dic, gtf_junctions, chr, pos, cigar_str, mate_chr, mate_pos, mate_cigar_str): + junctions, junction_read, gtf_junction_read = is_junction_read(chr_dic, gtf_junctions, chr, pos, cigar_str) + mate_junctions, mate_junction_read, mate_gtf_junction_read = is_junction_read(chr_dic, gtf_junctions, mate_chr, mate_pos, mate_cigar_str) + junctions += mate_junctions + junction_pair = len(junctions) > 0 + if junction_pair: + gtf_junction_pair = True + if junction_read and not gtf_junction_read: + gtf_junction_pair = False + if mate_junction_read and not mate_gtf_junction_read: + gtf_junction_pair = False + else: + gtf_junction_pair = False + + return junctions, junction_pair, gtf_junction_pair + +""" +""" +def getSNPs(chr_snps, left, right): + low, high = 0, len(chr_snps) + while low < high: + mid = (low + high) / 2 + snpID, type, pos, data = chr_snps[mid] + if pos < left: + low = mid + 1 + else: + high = mid - 1 + + snps = [] + for i in xrange(low, len(chr_snps)): + snp = chr_snps[i] + snpID, type, pos, data = snp + pos2 = pos + if type == "deletion": + pos2 += data + if pos2 >= right: + break + if pos >= left: + if len(snps) > 0: + _, prev_type, prev_pos, prev_data = snps[-1] + assert prev_pos <= pos + prev_pos2 = prev_pos + if prev_type == "deletion": + prev_pos2 += prev_data + if pos <= prev_pos2: + continue + snps.append(snp) + + return snps + +""" +""" +def check_snps(snps, check_type, ref_pos, read_seq): + found = False + + for snp in snps: + snp_type, snp_pos, snp_data = snp[1:4] + + if snp_type == check_type: + if snp_type == 'single': + if snp_pos == ref_pos and snp_data[0] == read_seq[0]: + found = True + break + elif snp_type == 'insertion': + if snp_pos == ref_pos and snp_data == read_seq: + found = True + break + + elif snp_type == 'deletion': + # snp_data and read_seq are length of sequence deleted + if snp_pos == ref_pos and int(snp_data) == int(read_seq): + found = True + break + + return found + + +def extract_reads_and_pairs(chr_dic, sam_filename, read_filename, pair_filename, unmapped_read_1_fq_name, unmapped_read_2_fq_name, snps_dict = None): + temp_read_filename, temp_pair_filename = read_filename + ".temp", pair_filename + ".temp" + temp_read_file, temp_pair_file = open(temp_read_filename, "w"), open(temp_pair_filename, "w") + + unmapped_read_1_fq, unmapped_read_2_fq = open(unmapped_read_1_fq_name, "w"), open(unmapped_read_2_fq_name, "w") + hisat2 = read_filename.find("hisat2") != -1 or pair_filename.find("hisat2") != -1 + vg = read_filename.find("vg") != -1 or pair_filename.find("vg") != -1 + + read_dic = {} + prev_read_id, prev_read_seq = "", "" + sam_file = open(sam_filename, "r") + for line in sam_file: + if line[0] == "@": + continue + + fields = line[:-1].split() + read_id, flag, chr, pos, mapQ, cigar_str, mate_chr, mate_pos, template_len, read_seq, read_qual = fields[:11] + if 'H' in cigar_str: + continue + + flag, pos, mate_pos = int(flag), int(pos), int(mate_pos) + if read_seq == "*" and prev_read_id == read_id: + read_seq = prev_read_seq + read_seq = read_seq.upper() + if read_seq == "" or read_seq == "*": + continue + + if flag & 0x04 != 0 or \ + chr == "*" or \ + cigar_str == "*": + """ + if flag & 0x80 != 0: + print >> unmapped_read_2_fq, "@%s\n%s\n+%s\n%s" % (read_id, read_seq, read_id, read_qual) + else: + print >> unmapped_read_1_fq, "@%s\n%s\n+%s\n%s" % (read_id, read_seq, read_id, read_qual) + """ + continue + + if mate_chr == '=': + mate_chr = chr + + if len(read_id) >= 3 and read_id[-2] == "/": + read_id = read_id[:-2] + + if read_id.find("seq.") == 0: + read_id = read_id[4:] + + if read_id != prev_read_id: + read_dic = {} + + HISAT2_XM, HISAT2_NM = 0, 0 + if hisat2: + for field in fields[11:]: + if field[:5] == "XM:i:": + HISAT2_XM = int(field[5:]) + elif field[:5] == "NM:i:": + HISAT2_NM = int(field[5:]) + + prev_read_id = read_id + prev_read_seq = read_seq + + if snps_dict != None and chr in snps_dict: + chr_snps = snps_dict[chr] + else: + chr_snps = [] + + snps = None + + XM, gap = 0, 0 + read_pos, right_pos = 0, pos - 1, + junction_read = False + + cigars = cigar_re.findall(cigar_str) + for i in range(len(cigars)): + cigar = cigars[i] + length = int(cigar[:-1]) + cigar_op = cigar[-1] + + if cigar_op == "S": + if i != 0 and i != len(cigars) - 1: + print >> sys.stderr, "S is located at %dth out of %d %s" % (i+1, len(cigars), cigar_str) + + if cigar_op in "MS": + ref_pos = right_pos + if cigar_op == "S" and i == 0: + ref_seq = chr_dic[chr][right_pos-length:right_pos] + ref_pos = right_pos - length + else: + ref_seq = chr_dic[chr][right_pos:right_pos+length] + + ref_seq = ref_seq.upper() + if length == len(ref_seq): + for j in range(length): + if ref_seq[j] != "N" and read_seq[read_pos+j] != ref_seq[j]: + if snps_dict == None: + XM += 1 + else: + if snps == None: + snps = getSNPs(chr_snps, pos - 1, pos + len(read_seq)) + + found_snp = check_snps(snps, 'single', ref_pos + j, read_seq[read_pos + j]) + if not found_snp: + XM += 1 + + if hisat2 and cigar_op == "S": + HISAT2_XM += 1 + HISAT2_NM += 1 + else: + XM += length + + if cigar_op in "I": + if snps == None: + snps = getSNPs(chr_snps, pos - 1, pos + len(read_seq)) + found_snp = check_snps(snps, 'insertion', right_pos, read_seq[read_pos:read_pos + length]) + if not found_snp: + gap += length + + if cigar_op in "D": + if snps == None: + snps = getSNPs(chr_snps, pos - 1, pos + len(read_seq)) + found_snp = check_snps(snps, 'deletion', right_pos, length) + if not found_snp: + gap += length + + if cigar_op in "MND": + right_pos += length + + if cigar_op in "MIS": + read_pos += length + + if cigar_op == "N": + junction_read = True + + NM = XM + gap + if hisat2: + XM, NM = HISAT2_XM, HISAT2_NM + if NM < MAX_EDIT: + print >> temp_read_file, "%s\t%d\t%s\t%s\t%s\tXM:i:%d\tNM:i:%d" % \ + (read_id, flag, chr, pos, cigar_str, XM, NM) + + found = False + me = "%s\t%s\t%d" % (read_id, chr, pos) + partner = "%s\t%s\t%d" % (read_id, mate_chr, mate_pos) + if partner in read_dic: + maps = read_dic[partner] + for map in maps: + if map[0] == me: + mate_flag, mate_cigar_str, mate_XM, mate_NM = map[1:] + if mate_pos > pos: + flag, chr, pos, cigar_str, XM, NM, mate_flag, mate_chr_str, mate_pos, mate_cigar_str, mate_XM, mate_NM = \ + mate_flag, mate_chr, mate_pos, mate_cigar_str, mate_XM, mate_NM, flag, chr, pos, cigar_str, XM, NM + + print >> temp_pair_file, "%s\t%d\t%s\t%d\t%s\tXM:i:%d\tNM:i:%d\t%d\t%s\t%d\t%s\tXM:i:%d\tNM:i:%d" % \ + (read_id, mate_flag, mate_chr, mate_pos, mate_cigar_str, mate_XM, mate_NM, flag, chr, pos, cigar_str, XM, NM) + found = True + break + + if not found: + if not me in read_dic: + read_dic[me] = [] + + read_dic[me].append([partner, flag, cigar_str, XM, NM]) + + sam_file.close() + + temp_read_file.close() + temp_pair_file.close() + + unmapped_read_1_fq.close() + unmapped_read_2_fq.close() + + + sort = False + if vg: + sort = True + + if sort: + command = "sort %s | uniq > %s; rm %s" % (temp_read_filename, read_filename, temp_read_filename) + os.system(command) + + command = "sort %s | uniq > %s; rm %s" % (temp_pair_filename, pair_filename, temp_pair_filename) + os.system(command) + else: + command = "mv %s %s; mv %s %s" % (temp_read_filename, read_filename, temp_pair_filename, pair_filename) + os.system(command) + + +def remove_redundant_junctions(junctions): + temp_junctions = [] + for junction in junctions: + temp_junctions.append(to_junction(junction)) + junctions = sorted(list(temp_junctions), cmp=junction_cmp) + temp_junctions = [] + for can_junction in junctions: + if len(temp_junctions) <= 0: + temp_junctions.append(can_junction) + else: + chr, left, right = temp_junctions[-1] + chr2, left2, right2 = can_junction + if chr == chr2 and \ + abs(left - left2) == abs(right - right2) and \ + abs(left - left2) <= 10: + continue + temp_junctions.append(can_junction) + junctions = set() + for junction in temp_junctions: + junctions.add(to_junction_str(junction)) + + return junctions + + + +def read_stat(read_filename, gtf_junctions, chr_dic = None, debug = False): + read_stat = [[0, 0, 0] for i in range(MAX_EDIT)] + temp_junctions = [set() for i in range(MAX_EDIT)] + temp_gtf_junctions = [set() for i in range(MAX_EDIT)] + + alignment = [] + prev_read_id = "" + read_file = open(read_filename, "r") + for line in read_file: + read_id, flag, chr, pos, cigar_str, XM, NM = line[:-1].split() + flag, pos = int(flag), int(pos) + XM, NM = int(XM[5:]), int(NM[5:]) + + read_junctions, junction_read, gtf_junction_read = \ + is_junction_read(chr_dic, gtf_junctions, chr, pos, cigar_str) + + if junction_read: + for junction_str, is_gtf_junction in read_junctions: + if NM < len(temp_junctions): + temp_junctions[NM].add(junction_str) + + if is_gtf_junction: + temp_gtf_junctions[NM].add(junction_str) + + if read_id != prev_read_id: + if prev_read_id != "": + NM2, junction_read2, gtf_junction_read2 = alignment + if NM2 < len(read_stat): + read_stat[NM2][0] += 1 + + if junction_read2: + read_stat[NM2][1] += 1 + + if gtf_junction_read2: + read_stat[NM2][2] += 1 + + alignment = [] + + prev_read_id = read_id + + if not alignment: + alignment = [NM, junction_read, gtf_junction_read] + elif alignment[0] > NM or \ + (alignment[0] == NM and not alignment[2] and junction_read): + alignment = [NM, junction_read, gtf_junction_read] + + read_file.close() + + for i in range(len(read_stat)): + temp_junctions[i] = remove_redundant_junctions(temp_junctions[i]) + temp_gtf_junctions[i] = remove_redundant_junctions(temp_gtf_junctions[i]) + + for i in range(len(read_stat)): + read_stat[i].append(len(temp_junctions[i])) + read_stat[i].append(len(temp_gtf_junctions[i])) + + if alignment: + NM2, junction_read2, gtf_junction_read2 = alignment + if NM2 < len(read_stat): + read_stat[NM2][0] += 1 + + if junction_read2: + read_stat[NM2][1] += 1 + + if gtf_junction_read2: + read_stat[NM2][2] += 1 + + return read_stat + + +def cal_read_len(cigar_str): + length = 0 + leftmost_softclip = 0 + rightmost_softclip = 0 + cigars = cigar_re.findall(cigar_str) + + for i in range(len(cigars)): + cigar = cigars[i] + cigar_length = int(cigar[:-1]) + cigar_op = cigar[-1] + + if cigar_op in "MIS": + length += cigar_length + + if (i == 0) and (cigar_op == "S"): + leftmost_softclip = cigar_length + if (i == (len(cigars) - 1)) and (cigar_op == "S"): + rightmost_softclip = cigar_length + + return length, leftmost_softclip, rightmost_softclip + +def is_concordantly(read_id, flag, chr, pos, cigar_str, XM, NM, mate_flag, mate_chr, mate_pos, mate_cigar_str, mate_XM, mate_NM): + concord_length = 1000 + segment_length = sys.maxint + + pairs = {} + pairs[0] = [flag, chr, pos, cigar_str, XM, NM] + pairs[1] = [mate_flag, mate_chr, mate_pos, mate_cigar_str, mate_XM, mate_NM] + + if chr != mate_chr: + return False, segment_length + if (flag & 0x10 == 0x10) or (mate_flag & 0x10 == 0): + return False, segment_length + + assert pos <= mate_pos + + left = pairs[0] + right = pairs[1] + + left_start = left[2] + left_len, _, _ = cal_read_len(left[3]) # cigar + + right_start = right[2] + right_len, _, right_soft = cal_read_len(right[3]) + + segment_length = (right_start + right_len) - left_start - right_soft + assert segment_length >= 0 + + if segment_length > concord_length: + return False, segment_length + + return True, segment_length + +def pair_stat(pair_filename, gtf_junctions, chr_dic): + # pair_stat = NM, junction_pair, gtf_junction, concordant_alignment] + pair_stat = [[0, 0, 0, 0] for i in range(MAX_EDIT)] + dis_pair_stat = [0 for i in range(MAX_EDIT)] + temp_junctions = [set() for i in range(MAX_EDIT)] + temp_gtf_junctions = [set() for i in range(MAX_EDIT)] + + alignment, dis_alignments = [], [] + prev_read_id = "" + con_file = open(pair_filename + ".con", "w") + discon_file = open(pair_filename + ".discon", "w") + pair_file = open(pair_filename, "r") + for line in pair_file: + read_id, flag, chr, pos, cigar_str, XM, NM, mate_flag, mate_chr, mate_pos, mate_cigar_str, mate_XM, mate_NM = line[:-1].split() + flag, pos, XM, NM, mate_flag, mate_pos, mate_XM, mate_NM = \ + int(flag), int(pos), int(XM[5:]), int(NM[5:]), int(mate_flag), int(mate_pos), int(mate_XM[5:]), int(mate_NM[5:]) + + pair_XM = XM + mate_XM + pair_NM = NM + mate_NM + + pair_junctions, junction_pair, gtf_junction_pair = \ + is_junction_pair(chr_dic, gtf_junctions, chr, pos, cigar_str, mate_chr, mate_pos, mate_cigar_str) + + # check concordantly + concord_align, segment_len = is_concordantly(read_id, flag, chr, pos, cigar_str, XM, NM, mate_flag, mate_chr, mate_pos, mate_cigar_str, mate_XM, mate_NM) + print >> (con_file if concord_align else discon_file), line.strip(), ('none', 'first')[(flag & 0x40 == 0x40)], ('none', 'last')[(mate_flag & 0x80 == 0x80)], segment_len + + if junction_pair: + for junction_str, is_gtf_junction in pair_junctions: + if pair_NM < len(temp_junctions): + temp_junctions[pair_NM].add(junction_str) + + if is_gtf_junction: + temp_gtf_junctions[pair_NM].add(junction_str) + + if read_id != prev_read_id: + if prev_read_id != "": + NM2, junction_read2, gtf_junction_read2, concord_align2 = alignment + if NM2 < len(pair_stat): + pair_stat[NM2][0] += 1 + + if junction_read2: + pair_stat[NM2][1] += 1 + if gtf_junction_read2: + pair_stat[NM2][2] += 1 + if concord_align2: + pair_stat[NM2][3] += 1 + + for NM2 in dis_alignments: + if NM2 < len(dis_pair_stat): + dis_pair_stat[NM2] += 1 + + alignment = [] + dis_alignment = [] + + prev_read_id = read_id + + if not alignment: + alignment = [pair_NM, junction_pair, gtf_junction_pair, concord_align] + elif alignment[0] > pair_NM or \ + (alignment[0] == pair_NM and not alignment[2] and junction_pair): + alignment = [pair_NM, junction_pair, gtf_junction_pair, concord_align] + + if mate_chr != chr or ((flag & 0x10) != 0 or (mate_flag & 0x10) == 0): + if len(dis_alignments) == 0: + dis_alignments = [pair_NM] + elif dis_alignments[0] > pair_NM: + dis_alignments = [pair_NM] + + pair_file.close() + con_file.close() + discon_file.close() + + # process last line + if alignment: + NM2, junction_read2, gtf_junction_read2, concord_align2 = alignment + if NM2 < len(pair_stat): + pair_stat[NM2][0] += 1 + + if junction_read2: + pair_stat[NM2][1] += 1 + if gtf_junction_read2: + pair_stat[NM2][2] += 1 + + if concord_align2: + pair_stat[NM2][3] += 1 + + assert len(dis_alignments) <= 1 + for NM2 in dis_alignments: + if NM2 < len(dis_pair_stat): + dis_pair_stat[NM2] += 1 + + for i in range(len(pair_stat)): + temp_junctions[i] = remove_redundant_junctions(temp_junctions[i]) + temp_gtf_junctions[i] = remove_redundant_junctions(temp_gtf_junctions[i]) + + for i in range(len(pair_stat)): + pair_stat[i].append(len(temp_junctions[i])) + pair_stat[i].append(len(temp_gtf_junctions[i])) + + return pair_stat, dis_pair_stat + + +def sql_execute(sql_db, sql_query): + sql_cmd = [ + "sqlite3", sql_db, + "-separator", "\t", + "%s;" % sql_query + ] + # print >> sys.stderr, sql_cmd + sql_process = subprocess.Popen(sql_cmd, stdout=subprocess.PIPE) + output = sql_process.communicate()[0][:-1] + return output + + +def create_sql_db(sql_db): + if os.path.exists(sql_db): + print >> sys.stderr, sql_db, "already exists!" + return + + columns = [ + ["id", "integer primary key autoincrement"], + ["reads", "text"], + ["genome", "text"], + ["end_type", "text"], + ["aligner", "text"], + ["version", "test"], + ["use_annotation", "text"], + ["edit_distance", "integer"], + ["mapped_reads", "integer"], + ["junction_reads", "integer"], + ["gtf_junction_reads", "integer"], + ["junctions", "integer"], + ["gtf_junctions", "integer"], + ["runtime", "real"], + ["host", "text"], + ["created", "text"], + ["cmd", "text"] + ] + + sql_create_table = "CREATE TABLE Mappings (" + for i in range(len(columns)): + name, type = columns[i] + if i != 0: + sql_create_table += ", " + sql_create_table += ("%s %s" % (name, type)) + sql_create_table += ");" + sql_execute(sql_db, sql_create_table) + + +def write_analysis_data(sql_db, database_name, paired): + if not os.path.exists(sql_db): + return + + if paired: + paired = "paired" + else: + paired = "single" + + aligners = [] + sql_aligners = "SELECT aligner FROM Mappings WHERE end_type = '%s' GROUP BY aligner" % (paired) + output = sql_execute(sql_db, sql_aligners) + aligners = output.split() + + database_fname = database_name + "_" + paired + ".analysis" + database_file = open(database_fname, "w") + + print >> database_file, "aligner\tuse_annotation\tend_type\tedit_distance\tmapped_reads\tjunction_reads\tgtf_junction_reads\tjunctions\tgtf_junctions\truntime" + for aligner in aligners: + for edit_distance in range(MAX_EDIT): + sql_row = "SELECT aligner, use_annotation, end_type, edit_distance, mapped_reads, junction_reads, gtf_junction_reads, junctions, gtf_junctions, runtime FROM Mappings" + sql_row += " WHERE reads = '%s' and aligner = '%s' and edit_distance = %d and end_type = '%s' ORDER BY created DESC LIMIT 1" % (database_name, aligner, edit_distance, paired) + output = sql_execute(sql_db, sql_row) + if output: + print >> database_file, output + + database_file.close() + + +def calculate_read_cost(single_end, + paired_end, + test_aligners, + fresh, + runtime_only, + verbose): + sql_db_name = "analysis.db" + if not os.path.exists(sql_db_name): + create_sql_db(sql_db_name) + + full_workdir = os.getcwd() + workdir = full_workdir.split("/")[-1] + + num_cpus = multiprocessing.cpu_count() + if num_cpus > 8: + num_threads = min(8, num_cpus) + desktop = False + else: + num_threads = min(3, num_cpus) + desktop = True + + verbose = False + sql_write = True + is_large_file = False + gz_file = False + if os.path.exists("1.fq.gz"): + gz_file = True + if os.path.getsize("1.fq.gz") > (1024 * 1024 * 1024): + is_large_file = True + + elif os.path.exists("1.fq"): + gz_file = False + if os.path.getsize("1.fq") > (2 * 1024 * 1024 * 1024): + is_large_file = True + + else: + assert(False) + + + aligners = [ + # ["hisat2", "", "", "", ""], + # ["hisat2", "", "", "", "--sensitive"], + # ["hisat2", "", "", "", "--very-sensitive"], + # ["hisat2", "", "", "", "-k 50 --score-min C,-50,0"], + # ["hisat2", "", "snp", "", ""], + # ["hisat2", "", "snp", "", "--sensitive"], + # ["hisat2", "", "snp", "", "-k 50"], + # ["hisat2", "", "", "205", ""], + # ["hisat2", "", "snp", "205", ""], + # ["hisat2", "", "snp_tran", "205", ""], + # ["hisat2", "", "tran", "", ""], + # ["hisat2", "x1", "snp", "", ""], + # ["hisat2", "x1", "", "", ""], + # ["hisat2", "x2", "", "", ""], + # ["hisat2", "", "tran", "", ""], + # ["hisat2", "", "snp_tran", "204", ""], + # ["hisat2", "", "snp_tran", "", ""], + # ["hisat2", "", "", "210", ""], + ["hisat2", "", "rep", "", ""], + # ["hisat2", "", "rep", "", "--read-lengths 101"], + # ["hisat2", "", "rep", "", "--sensitive"], + # ["hisat2", "", "rep-100-300", "", ""], + # ["hisat2", "", "rep-101-300", "", "--sensitive"], + # ["hisat2", "", "rep-101-300", "", "-k 10 --score-min C,-50,0"], + # ["hisat2", "", "rep-150-300", "", ""], + # ["tophat2", "", "", "", ""], + # ["bowtie", "", "", "", ""], + ["bowtie2", "", "", "", ""], + # ["bowtie2", "", "", "", "-k 10"], + ["bwa", "mem", "", "", ""], + # ["bwa", "mem", "", "", "-a"], + # ["bwa", "sw", "", "", ""], + # ["star", "", "", "", ""], + # ["star", "x2", "", "", ""], + # ["vg", "", "", "", ""], + # ["vg", "", "", "", "-M 10"], + # ["vg", "", "snp", "", ""], + # ["vg", "", "snp", "", "-M 10"], + # ["minimap2", "", "", "", ""], + ] + + # sql_write = False + verbose = True + debug = False + + genome = "genome" + cwd = os.getcwd() + RNA = (cwd.find("RNA") != -1) + + chr_dic = read_genome("../../../data/" + genome + ".fa") + snp_dic = read_snp("../../../data/" + genome + ".snp") + gtf_junction_strs = extract_splice_sites("../../../data/" + genome + ".gtf") + gene = "no" + gtf_junctions = [] + for junction_str in gtf_junction_strs: + junction = to_junction(junction_str) + gtf_junctions.append(junction) + gtf_junctions = sorted(gtf_junctions, cmp=junction_cmp) + + print >> sys.stderr, "aligner\tuse_annotation\tend_type\tedit_distance\tmapped_reads\tjunction_reads\tgtf_junction_reads\tjunctions\tgtf_junctions\truntime" + + for paired in [False, True]: + if not paired and not single_end: + continue + if paired and not paired_end: + continue + + type_read1_fname = "1.fq" + if gz_file: + type_read1_fname += ".gz" + + if paired: + type_read2_fname = "2.fq" + if gz_file: + type_read2_fname += ".gz" + + else: + type_read2_fname = "" + + aligner_bin_base = "../../../../aligners/bin" + def get_aligner_version(aligner): + version = "" + if aligner == "hisat2" or \ + aligner == "hisat" or \ + aligner == "bowtie" or \ + aligner == "bowtie2": + if version: + cmd = ["%s/%s_%s/%s" % (aligner_bin_base, aligner, version, aligner)] + else: + cmd = ["%s/%s" % (aligner_bin_base, aligner)] + cmd += ["--version"] + cmd_process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + version = cmd_process.communicate()[0][:-1].split("\n")[0] + version = version.split()[-1] + elif aligner == "tophat2": + cmd = ["%s/tophat" % (aligner_bin_base)] + cmd += ["--version"] + cmd_process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + version = cmd_process.communicate()[0][:-1].split()[-1] + elif aligner in ["star", "starx2"]: + version = "2.4.2a" + elif aligner == "gsnap": + cmd = ["%s/gsnap" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[0] + version = version.split()[2] + elif aligner == "bwa": + if version: + cmd = ["%s/bwa_%s/bwa" % (aligner_bin_base, version)] + else: + cmd = ["%s/bwa" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[2] + version = version.split()[1] + elif aligner == "vg": + cmd = ["%s/vg" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[0] + version = version.split()[5] + elif aligner == "minimap2": + cmd = ["%s/minimap2" % (aligner_bin_base)] + cmd += ["--version"] + cmd_process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + version = cmd_process.communicate()[0][:-1].split("\n")[0] + + return version + + index_base = "../../../../indexes" + index_add = "" + if genome != "genome": + index_add = "_" + genome + def get_aligner_cmd(RNA, aligner, type, index_type, version, options, read1_fname, read2_fname, out_fname, cmd_idx = 0): + cmd = ["/usr/bin/time"] + if osx_mode: + cmd += ['-l'] + if aligner == "hisat2": + if version: + cmd += ["%s/hisat2_%s/hisat2" % (aligner_bin_base, version)] + else: + cmd += ["%s/hisat2" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + + # cmd += ["-k", "5"] + # cmd += ["--score-min", "C,-18"] + + # daehwan - for debugging purposes + # cmd += ["--score-min", "C,-50"] + # cmd += ["--pen-cansplice", "0"] + # cmd += ["--pen-noncansplice", "12"] + # cmd += ["--pen-intronlen", "G,-8,1"] + # cmd += ["--metrics", "1", + # "--metrics-file", "metrics.out"] + + if version == "204": + cmd += ["--sp", "2,1"] + + if not RNA: + cmd += ["--no-spliced-alignment"] + + if type in ["x1", "x2"]: + cmd += ["--no-temp-splicesite"] + + # DK - for debugging purposes + # cmd += ["--dta"] + """ + if index_type == "tran": + cmd += ["--no-anchorstop"] + cmd += ["-k", "100"] + """ + + if options != "": + cmd += options.split(' ') + + if type == "x2": + if cmd_idx == 0: + cmd += ["--novel-splicesite-outfile"] + else: + cmd += ["--novel-splicesite-infile"] + cmd += ["splicesites.txt"] + + # "--novel-splicesite-infile", + # "../splicesites.txt", + # "--rna-strandness", + # "FR", + if version: + index_cmd = "%s/HISAT2_%s%s/" % (index_base, version, index_add) + genome + else: + index_cmd = "%s/HISAT2%s/" % (index_base, index_add) + genome + if index_type: + index_cmd += ("_" + index_type) + cmd += [index_cmd] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += ["-U", read1_fname] + elif aligner == "hisat": + cmd += ["%s/hisat" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + # cmd += ["-k", "5"] + # cmd += ["--score-min", "C,-18"] + if version != "": + version = int(version) + else: + version = sys.maxint + + if not RNA: + cmd += ["--no-spliced-alignment"] + + if type in ["x1", "x2"] or not RNA: + cmd += ["--no-temp-splicesite"] + + """ + cmd += ["--rdg", "100,100", + "--rfg", "100,100"] + """ + + if type == "x2": + if cmd_idx == 0: + cmd += ["--novel-splicesite-outfile"] + else: + cmd += ["--novel-splicesite-infile"] + cmd += ["splicesites.txt"] + + # "--novel-splicesite-infile", + # "../splicesites.txt", + # "--rna-strandness", + # "FR", + cmd += ["%s/HISAT%s/" % (index_base, index_add) + genome] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "tophat2": + cmd += ["%s/tophat" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["--read-edit-dist", "3"] + cmd += ["--no-sort-bam"] + cmd += ["--read-realign-edit-dist", "0"] + cmd += ["--keep-tmp", + "%s/HISAT%s/" % (index_base, index_add) + genome, + read1_fname] + if paired: + cmd += [read2_fname] + elif aligner == "star": + cmd += ["%s/STAR" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["--runThreadN", str(num_threads)] + if type == "x2" and cmd_idx == 1: + cmd += ["--genomeDir", "."] + else: + cmd += ["--genomeDir", "%s/STAR%s" % (index_base, index_add)] + if desktop: + cmd += ["--genomeLoad", "NoSharedMemory"] + else: + cmd += ["--genomeLoad", "LoadAndKeep"] + if type == "x2": + if cmd_idx == 1: + cmd += ["--alignSJDBoverhangMin", "1"] + cmd += ["--readFilesIn", + read1_fname] + if paired: + cmd += [read2_fname] + if paired: + cmd += ["--outFilterMismatchNmax", "6"] + else: + cmd += ["--outFilterMismatchNmax", "3"] + elif aligner == "bowtie": + cmd += ["%s/bowtie" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["--sam", + "-k", "10"] + cmd += ["-n", "3"] + if paired: + cmd += ["-X", "500"] + cmd += ["%s/Bowtie%s/" % (index_base, index_add) + genome] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "bowtie2": + if version: + cmd += ["%s/bowtie2_%s/bowtie2" % (aligner_bin_base, version)] + else: + cmd += ["%s/bowtie2" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + #cmd += ["-k", "10"] + #cmd += ["--score-min", "C,-18"] + cmd += ["-X", "1000"] + + if options: + cmd += options.split(' ') + + if version: + cmd += ["-x %s/Bowtie2_%s%s/" % (index_base, version, index_add) + genome] + else: + cmd += ["-x %s/Bowtie2%s/" % (index_base, index_add) + genome] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "gsnap": + cmd += ["%s/gsnap" % (aligner_bin_base), + "-A", + "sam"] + if num_threads > 1: + cmd += ["-t", str(num_threads)] + cmd += ["--max-mismatches=3", + "-D", "%s/GSNAP%s" % (index_base, index_add), + "-N", "1", + "-d", genome, + read1_fname] + if paired: + cmd += [read2_fname] + elif aligner == "bwa": + if version: + cmd += ["%s/bwa_%s/bwa" % (aligner_bin_base, version)] + else: + cmd += ["%s/bwa" % (aligner_bin_base)] + if type in ["mem", "aln"]: + cmd += [type] + elif type == "sw": + cmd += ["bwa" + type] + if num_threads > 1: + cmd += ["-t", str(num_threads)] + if options: + cmd += options.split(' ') + if version: + cmd += ["%s/BWA_%s%s/%s.fa" % (index_base, version, index_add, genome)] + else: + cmd += ["%s/BWA%s/%s.fa" % (index_base, index_add, genome)] + cmd += [read1_fname] + if paired: + cmd += [read2_fname] + elif aligner == "vg": + # vg map -d 22 -t 6 -M 10 -f ../sim-1.fa -f ../sim-2.fa --surject-to sam > result.sam + cmd += ["%s/vg" % (aligner_bin_base)] + cmd += ["map"] + cmd += ["-t", str(num_threads)] + cmd += ["--surject-to", "sam"] + index_cmd = "%s/VG%s/" % (index_base, index_add) + genome + if index_type: + index_cmd += ("_" + index_type) + + if options: + cmd += options.split(' ') + + cmd += ["-d", index_cmd] + + cmd += ["-f", read1_fname] + if paired: + cmd += ["-f", read2_fname] + + elif aligner == "minimap2": + # minimap2 -a -x sr 22.mmi sim_1.fa sim_2.fa > result.sam + cmd += ["%s/minimap2" % (aligner_bin_base)] + cmd += ["-a"] + cmd += ["-x", "sr"] + index_cmd = "%s/minimap2%s/" % (index_base, index_add) + genome + if index_type: + index_cmd += ("_" + index_type) + index_cmd += ".mmi" + cmd += [index_cmd] + cmd += [read1_fname] + if paired: + cmd += [read2_fname] + else: + assert False + + return cmd + + for aligner, type, index_type, version, options in aligners: + skip = False + if len(test_aligners) > 0: + skip = True + for test_aligner in test_aligners: + if aligner == test_aligner: + skip = False + if skip: + continue + + aligner_name = aligner + type + version + if (aligner == "hisat2" or aligner == "vg") and index_type != "": + aligner_name += ("_" + index_type) + + if options != "": + option_name = options.replace(' ', '').replace('-', '').replace(',', '') + aligner_name = aligner_name + '_' + option_name + if paired: + aligner_dir = aligner_name + "_paired" + else: + aligner_dir = aligner_name + "_single" + + if fresh and os.path.exists(aligner_dir): + os.system("rm -rf %s" % aligner_dir) + + if not os.path.exists(aligner_dir): + os.mkdir(aligner_dir) + os.chdir(aligner_dir) + + out_fname = "accepted.sam" + aligner_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../" + type_read1_fname, "../" + type_read2_fname, out_fname) + duration = 0.1 + mem_usage = '' + if not os.path.exists(out_fname): + if not os.path.exists("../one.fq") or not os.path.exists("../two.fq"): + if gz_file: + os.system("gzip -cd ../1.fq.gz | head -400 > ../one.fq") + os.system("gzip -cd ../2.fq.gz | head -400 > ../two.fq") + else: + os.system("head -400 ../1.fq > ../one.fq") + os.system("head -400 ../2.fq > ../two.fq") + + # dummy commands for caching index + loading_time = 0 + if aligner not in ["tophat2"]: + for i in range(3): + dummy_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../one.fq", "../two.fq", "/dev/null") + start_time = datetime.now() + if verbose: + print >> sys.stderr, start_time, "\t", " ".join(dummy_cmd) + if aligner in ["hisat2", "hisat", "bowtie", "bowtie2", "gsnap", "bwa"]: + proc = subprocess.Popen(dummy_cmd, stdout=open("/dev/null", "w"), stderr=subprocess.PIPE) + else: + proc = subprocess.Popen(dummy_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc.communicate() + finish_time = datetime.now() + duration = finish_time - start_time + duration = duration.total_seconds() + if verbose: + print >> sys.stderr, finish_time, "duration:", duration + loading_time = duration + + # align all reads + if paired: + sweep_read_cmd = "cat ../%s ../%s > /dev/null" % (type_read1_fname, type_read2_fname) + else: + sweep_read_cmd = "cat ../%s > /dev/null" % (type_read1_fname) + print >> sys.stderr, datetime.now(), "\t", sweep_read_cmd + os.system(sweep_read_cmd) + + skip_alignment = False + if paired and aligner == "olego" and os.path.exists(out_fname + "1"): + skip_alignment = True + + if not skip_alignment: + aligner_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../" + type_read1_fname, "../" + type_read2_fname, out_fname) + start_time = datetime.now() + if verbose: + print >> sys.stderr, start_time, "\t", " ".join(aligner_cmd) + if aligner in ["hisat2", "hisat", "bowtie", "bowtie2", "gsnap", "bwa", "vg", "minimap2"]: + proc = subprocess.Popen(aligner_cmd, stdout=open(out_fname, "w"), stderr=subprocess.PIPE) + else: + proc = subprocess.Popen(aligner_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + _, mem_usage = proc.communicate() + mem_usage = parse_mem_usage(mem_usage) + finish_time = datetime.now() + duration = finish_time - start_time + duration = duration.total_seconds() - loading_time + if duration < 0.1: + duration = 0.1 + if verbose: + print >> sys.stderr, finish_time, "duration:", duration + + if verbose: + print >> sys.stderr, finish_time, "Memory Usage: %dMB" % (int(mem_usage) / 1024) + + if debug and aligner == "hisat" and type == "x1": + os.system("cat metrics.out") + print >> sys.stderr, "\ttime: %.4f" % (duration) + # break + + if aligner == "star" and type in ["", "gtf"]: + os.system("mv Aligned.out.sam %s" % out_fname) + elif aligner in ["hisat2", "hisat"] and type == "x2": + aligner_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../" + type_read1_fname, "../" + type_read2_fname, out_fname, 1) + if verbose: + print >> sys.stderr, start_time, "\t", " ".join(aligner_cmd) + start_time = datetime.now() + proc = subprocess.Popen(aligner_cmd, stdout=open(out_fname, "w"), stderr=subprocess.PIPE) + proc.communicate() + finish_time = datetime.now() + duration += (finish_time - start_time).total_seconds() + duration -= loading_time + if duration < 0.1: + duration = 0.1 + if verbose: + print >> sys.stderr, finish_time, "duration:", duration + elif aligner == "star" and type == "x2": + assert os.path.exists("SJ.out.tab") + os.system("awk 'BEGIN {OFS=\"\t\"; strChar[0]=\".\"; strChar[1]=\"+\"; strChar[2]=\"-\";} {if($5>0){print $1,$2,$3,strChar[$4]}}' SJ.out.tab > SJ.out.tab.Pass1.sjdb") + for file in os.listdir("."): + if file in ["SJ.out.tab.Pass1.sjdb", "genome.fa"]: + continue + os.remove(file) + star_index_cmd = "STAR --genomeDir ./ --runMode genomeGenerate --genomeFastaFiles ../../../../data/genome.fa --sjdbFileChrStartEnd SJ.out.tab.Pass1.sjdb --sjdbOverhang 100 --runThreadN %d" % (num_threads) + print >> sys.stderr, "\t", datetime.now(), star_index_cmd + os.system(star_index_cmd) + if verbose: + print >> sys.stderr, "\t", datetime.now(), " ".join(dummy_cmd) + proc = subprocess.Popen(dummy_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc.communicate() + if verbose: + print >> sys.stderr, "\t", datetime.now(), "finished" + aligner_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../" + type_read1_fname, "../" + type_read2_fname, out_fname, 1) + start_time = datetime.now() + if verbose: + print >> sys.stderr, "\t", start_time, " ".join(aligner_cmd) + proc = subprocess.Popen(aligner_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc.communicate() + finish_time = datetime.now() + duration += (finish_time - start_time).total_seconds() + duration -= loading_time + if duration < 0.1: + duration = 0.1 + if verbose: + print >> sys.stderr, "\t", finish_time, "finished:", duration + os.system("mv Aligned.out.sam %s" % out_fname) + elif aligner == "tophat2": + os.system("samtools sort -n tophat_out/accepted_hits.bam accepted_hits; samtools view -h accepted_hits.bam > %s" % out_fname) + elif aligner == "vg": + index_name = '%s/VG%s/' % (index_base, index_add) + genome + if index_type: + index_name += ('_' + index_type) + + os.system("echo %s %s %f >> runtime" % (str(datetime.now()), aligner, duration)) + + if aligner in ["star", "tophat2", "gsnap"]: + os.system("tar cvzf %s.tar.gz %s &> /dev/null" % (out_fname, out_fname)) + + if runtime_only: + os.chdir("..") + continue + + suffix = aligner + read_sam, pair_sam = suffix + ".read.sam", suffix + ".pair.sam" + unmapped_read_1_fq, unmapped_read_2_fq = suffix + ".unmapped.1.fq", suffix + ".unmapped.2.fq" + if not os.path.exists(read_sam) or not os.path.exists(pair_sam): + if index_type == 'snp': + extract_reads_and_pairs(chr_dic, out_fname, read_sam, pair_sam, unmapped_read_1_fq, unmapped_read_2_fq, snp_dic) + else: + extract_reads_and_pairs(chr_dic, out_fname, read_sam, pair_sam, unmapped_read_1_fq, unmapped_read_2_fq) + + + + out = '' + if gz_file: + out = subprocess.check_output("gzip -cd ../%s | wc -l" % type_read1_fname, shell=True) + else: + out = subprocess.check_output("wc -l ../%s" % type_read1_fname, shell=True) + + numreads = int(out.split()[0]) / 4 + + done_filename = suffix + ".done" + if not os.path.exists(done_filename): + done_file = open(done_filename, "w") + if paired: + sum = [0, 0, 0, 0, 0, 0] # mappep_read, junction_read, gtf_junction_reads, concord_mapped_read, num_junctions, num_gtf_junctions + dis_sum = 0 + stat, dis_stat = pair_stat(pair_sam, gtf_junctions, chr_dic) + output = "" + for i in range(len(stat)): + for j in range(len(sum)): + sum[j] += stat[i][j] + + dis_sum += dis_stat[i] + mapped_reads, junction_reads, gtf_junction_reads, concord_mapped_read, num_junctions, num_gtf_junctions = sum + output += "%s\t%s\tpaired\t%d\t%d\t%.2f%%\t%d\t%d\t%d\t%d\t%f\t%d\t%d\t%.2f%%\n" % \ + (aligner_name, gene, i, mapped_reads, float(mapped_reads) * 100.0 / numreads, junction_reads, gtf_junction_reads, num_junctions, num_gtf_junctions, duration, (numreads / max(1.0, duration)), concord_mapped_read, float(concord_mapped_read) * 100.0 / numreads) + + if sql_write and os.path.exists("../" + sql_db_name): + sql_insert = "INSERT INTO \"Mappings\" VALUES(NULL, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %f, '%s', datetime('now', 'localtime'), '%s');" % \ + (workdir, genome, "paired", aligner_name, get_aligner_version(aligner), "no", i, mapped_reads, junction_reads, gtf_junction_reads, num_junctions, num_gtf_junctions, duration, platform.node(), " ".join(aligner_cmd)) + sql_execute("../" + sql_db_name, sql_insert) + + + print >> sys.stderr, output, + print >> done_file, output + else: + sum = [0, 0, 0, 0, 0] + stat = read_stat(read_sam, gtf_junctions, chr_dic) + output = "" + for i in range(len(stat)): + for j in range(len(sum)): + sum[j] += stat[i][j] + + mapped_reads, junction_reads, gtf_junction_reads, num_junctions, num_gtf_junctions = sum + output += "%s\t%s\tsingle\t%d\t%d\t%.2f%%\t%d\t%d\t%d\t%d\t%f\t%d\n" % \ + (aligner_name, gene, i, mapped_reads, float(mapped_reads) * 100.0 / numreads, junction_reads, gtf_junction_reads, num_junctions, num_gtf_junctions, duration, (numreads / max(1.0, duration))) + + if sql_write and os.path.exists("../" + sql_db_name): + sql_insert = "INSERT INTO \"Mappings\" VALUES(NULL, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %f, '%s', datetime('now', 'localtime'), '%s');" % \ + (workdir, genome, "single", aligner_name, get_aligner_version(aligner), "no", i, mapped_reads, junction_reads, gtf_junction_reads, num_junctions, num_gtf_junctions, duration, platform.node(), " ".join(aligner_cmd)) + sql_execute("../" + sql_db_name, sql_insert) + + print >> sys.stderr, output, + print >> done_file, output + + done_file.close() + + + os.chdir("..") + + if os.path.exists(sql_db_name): + write_analysis_data(sql_db_name, workdir, paired) + + + +if __name__ == "__main__": + parser = ArgumentParser( + description='test HISAT2, and compare HISAT2 with other popular aligners such as TopHat2, STAR, Bowtie1/2, GSNAP, BWA-mem, etc.') + parser.add_argument('--single-end', + dest='paired_end', + action='store_false', + help='run single-end only') + parser.add_argument('--paired-end', + dest='single_end', + action='store_false', + help='run paired_end only') + parser.add_argument('--aligner-list', + dest='aligner_list', + type=str, + default="", + help='comma-separated list of aligners (e.g. hisat2,bowtie2,bwa') + parser.add_argument('--fresh', + dest='fresh', + action='store_true', + help='delete existing alignment related directories (e.g. hisat2_single)') + parser.add_argument('--runtime-only', + dest='runtime_only', + action='store_true', + help='run programs without evaluation') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + + args = parser.parse_args() + + aligners = [] + for aligner in args.aligner_list.split(','): + if aligner == "": + continue + aligners.append(aligner) + + calculate_read_cost(args.single_end, + args.paired_end, + aligners, + args.fresh, + args.runtime_only, + args.verbose) + diff --git a/evaluation/real/init.py b/evaluation/real/init.py new file mode 100644 index 0000000..e8b8b57 --- /dev/null +++ b/evaluation/real/init.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python + +import sys, os, signal +import string, re + +signal.signal(signal.SIGPIPE, signal.SIG_DFL) +use_message = ''' +''' + +osx_mode = False +if sys.platform == 'darwin': + osx_mode = True + +def make_cat_cmd(gzmode, read_dir_base, read_dir, fq_name, num_read): + cmd = [] + if gzmode: + if osx_mode: + cmd += ["gzcat"] + else: + cmd += ["zcat"] + else: + cmd += ["cat"] + + cmd += ["../../%s%s/%s" % (read_dir_base, read_dir, fq_name)] + cmd += ["|", "head", "-n", "%d" % (num_read * 4)] + + if gzmode: + cmd += ["|", "gzip"] + + cmd += [">", fq_name] + return ' '.join(cmd) + + +def init(): + read_dir_base = "../reads/real/" + read_dirs = os.listdir(read_dir_base) + for read_dir in read_dirs: + if os.path.exists(read_dir): + continue + + gz_file = False + fq_1_name = '1.fq' + fq_2_name = '2.fq' + if os.path.exists(read_dir_base + read_dir + "/1.fq.gz") and \ + os.path.exists(read_dir_base + read_dir + "/2.fq.gz"): + gz_file = True + fq_1_name = '1.fq.gz' + fq_2_name = '2.fq.gz' + else: + if not os.path.exists(read_dir_base + read_dir + "/1.fq") or \ + not os.path.exists(read_dir_base + read_dir + "/1.fq"): + continue + + print >> sys.stderr, "Processing", read_dir, "..." + + os.mkdir(read_dir) + os.chdir(read_dir) + + RNA = (read_dir.find("RNA") != -1) + tests = [ + ["1M", 1000000], + #["5M", 5000000], + ["10M", 10000000], + #["20M", 20000000], + ["whole", 0], + ] + + for dir_name, num_reads in tests: + if os.path.exists(dir_name): + continue + + os.mkdir(dir_name) + os.chdir(dir_name) + + if dir_name == "whole": + ln_cmd = "ln -s ../../%s%s/%s ." % (read_dir_base, read_dir, fq_1_name) + print >> sys.stderr, ln_cmd + os.system(ln_cmd) + ln_cmd = "ln -s ../../%s%s/%s ." % (read_dir_base, read_dir, fq_2_name) + print >> sys.stderr, ln_cmd + os.system(ln_cmd) + else: + cmd = make_cat_cmd(gz_file, read_dir_base, read_dir, fq_1_name, num_reads) + print >> sys.stderr, cmd + os.system(cmd) + + cmd = make_cat_cmd(gz_file, read_dir_base, read_dir, fq_2_name, num_reads) + print >> sys.stderr, cmd + os.system(cmd) + + os.system("ln -s ../../calculate_read_cost.py .") + os.chdir("..") + + os.chdir("..") + + +if __name__ == "__main__": + init() diff --git a/evaluation/simulation/calculate_read_cost.py b/evaluation/simulation/calculate_read_cost.py new file mode 100644 index 0000000..4b7b726 --- /dev/null +++ b/evaluation/simulation/calculate_read_cost.py @@ -0,0 +1,2834 @@ +#!/usr/bin/env python + +import sys, os, subprocess +import multiprocessing +import string, re +import platform +from datetime import datetime, date, time +import copy +from argparse import ArgumentParser, FileType +from multiprocessing import Process +import bisect + +mp_mode = False +mp_num = 1 + +cigar_re = re.compile('\d+\w') + +osx_mode = False +if sys.platform == 'darwin': + osx_mode = True + +""" +""" +def parse_mem_usage(resource): + if osx_mode: + resource = resource.strip().split('\n') + for line in resource: + if line.find('maximum resident set size') != -1: + return int(line.split()[0]) / 1024 + else: + resource = resource.split(' ') + for line in resource: + idx = line.find('maxresident') + if idx != -1: + return line[:idx] + + return '0' + + +""" +""" +def reverse_complement(seq): + result = "" + for nt in seq: + base = nt + if nt == 'A': + base = 'T' + elif nt == 'a': + base = 't' + elif nt == 'C': + base = 'G' + elif nt == 'c': + base = 'g' + elif nt == 'G': + base = 'C' + elif nt == 'g': + base = 'c' + elif nt == 'T': + base = 'A' + elif nt == 't': + base = 'a' + + result = base + result + + return result + + +""" +RepeatDB +""" + +class RepeatAllele: + def __init__(self): + self.repeat_name = '' + self.allele_idx = 0 + self.repeat_pos = 0 + self.repeat_length = 0 + self.positions = [] + return + + def __repr__(self): + return '[' + ','.join([str(self.repeat_name), str(self.allele_idx), str(self.repeat_pos), str(self.repeat_length), str(len(self.positions))]) + ']' + + def add_position(self, chr, pos, strand): + self.positions.append([chr, pos, strand]) + + + def __lt__(self, other): + if self.repeat_pos < other.repeat_pos: + return True + elif self.repeat_pos == other.repeat_pos: + return self.repeat_length < other.repeat_length + else: + return False + +class Repeat: + def __init__(self): + self.repeat_name = '' + self.repeat_length = 0 + self.repeat_pos = 0 + self.allele = [] + return + + def add_allele(self, allele_idx, repeatAllele): + #self.allele[allele_idx] = repeatAllele + self.allele.append(repeatAllele) + + def allele_sort(self): + self.allele = sorted(self.allele) + +def cmp_repeatmap(a, b): + if a[0] < b[0]: + return -1 + elif a[0] == b[0]: + return 0 + else: + return 1 + +def read_len_cigar(cigar_str): + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + + read_len = 0 + for cigar in cigars: + cigar_op, length = cigar + if cigar_op in "MISH": + read_len += int(length) + + return read_len + +def read_repeatdb(repeat_filename): + repeat_db = {} + + if os.path.exists(repeat_filename): + + for line in open(repeat_filename, 'r'): + + if line[0] == '>': + line = line.strip()[1:] + name, rptRefName, pos, rep_len, _, _ = line.split()[:6] + pos = int(pos) + rep_len = int(rep_len) + rptName, allele_idx = name.split('*')[0:2] + allele_idx = int(allele_idx) + + repeatAllele = RepeatAllele() + repeatAllele.repeat_name = rptName + repeatAllele.allele_idx = allele_idx + repeatAllele.repeat_pos = pos + repeatAllele.repeat_length = rep_len + + if rptRefName not in repeat_db: + # new rptRefName + repeat_db[rptRefName] = {} + + if rptName not in repeat_db[rptRefName]: + # new rptName + assert allele_idx == 0 + repeat_db[rptRefName][rptName] = Repeat() + repeat_db[rptRefName][rptName].repeat_name = rptName + + repeat_db[rptRefName][rptName].add_allele(allele_idx, repeatAllele) + + else: + coords = line.split() + for coord in coords: + chr, pos, strand = coord.split(':') + pos = int(pos) + + repeat_db[rptRefName][rptName].allele[allele_idx].add_position(chr, pos, strand) + + else: + print >> sys.stderr, 'Cannot open file', repeat_filename + + + print >> sys.stderr, 'Build repeatMap' + repeat_map = {} + for rptRefName, repeats in repeat_db.items(): + #print 'Processing', rptRefName + repeat_pos_list = [] + + for repeatName, repeat in repeats.items(): + #print 'Common Allele:', repeatName, repeat.repeat_name + repeat_left = sys.maxint + repeat_right = 0 + + #for allele_id, repeatAllele in repeat.allele.items(): + for repeatAllele in repeat.allele: + left = repeatAllele.repeat_pos + right = left + repeatAllele.repeat_length + if left < repeat_left: + repeat_left = left + if right > repeat_right: + repeat_right = right + + repeat.repeat_pos = repeat_left + repeat.repeat_length = repeat_right - repeat_left + + #print repeat.allele + #repeat.allele_sort() + #print repeat.allele + + #print repeat_left, repeat_right + + repeat_pos_list.append((repeat_right, repeatName)) + + repeat_map[rptRefName] = sorted(repeat_pos_list, cmp=cmp_repeatmap) + #print repeat_map[rptRefName] + + return repeat_db, repeat_map + + +def find_leftmost_pos(rmap, left): + pos = bisect.bisect_left(rmap, (left, None)) + #print pos + + if pos == len(rmap): + return pos + + if rmap[pos][0] == left: + while pos < len(rmap): + if rmap[pos][0] != left: + break + pos += 1 + + return pos + +def repeat_to_genome_pos(repeat_db, repeat_map, rptRefName, pos, cigar_str = ''): + assert rptRefName in repeat_db + readlen = read_len_cigar(cigar_str) + #readlen = 101 + + # pos in sam-result. pos is 1-based + left = pos - 1 + right = left + readlen + + repeats = repeat_db[rptRefName] + rmap = repeat_map[rptRefName] + + #print len(rmap) + #print rmap + + i = find_leftmost_pos(rmap, left) + if i >= len(rmap): + print >> sys.stderr, 'Value Error' + return + + if right > rmap[i][0]: + print >> sys.stderr, 'Not repeat' + return + + repeat = repeats[rmap[i][1]] + + #print 'Allele Size:', len(repeat.allele) + #print repeat.allele + for allele in repeat.allele: + rpos = allele.repeat_pos + rlen = allele.repeat_length + + if (left >= rpos) and (right <= rpos + rlen): + offset = left - rpos + for genome_pos in allele.positions: + print genome_pos[0], genome_pos[1] + offset + 1, genome_pos[2], genome_pos[1] + +""" +""" +def read_genome(genome_filename): + chr_dic = {} + genome_file = open(genome_filename, "r") + + chr_name, sequence = "", "" + for line in genome_file: + if line[0] == ">": + if chr_name and sequence: + chr_dic[chr_name] = sequence + + chr_name = line[1:-1].split()[0] + sequence = "" + else: + sequence += line[:-1] + + if chr_name and sequence: + chr_dic[chr_name] = sequence + + genome_file.close() + + print >> sys.stderr, "genome is loaded" + + return chr_dic + + +""" +""" +def extract_splice_sites(gtf_fname): + trans = {} + + gtf_file = open(gtf_fname) + # Parse valid exon lines from the GTF file into a dict by transcript_id + for line in gtf_file: + line = line.strip() + if not line or line.startswith('#'): + continue + if '#' in line: + line = line.split('#')[0].strip() + + try: + chrom, source, feature, left, right, score, \ + strand, frame, values = line.split('\t') + except ValueError: + continue + left, right = int(left), int(right) + + if feature != 'exon' or left >= right: + continue + + values_dict = {} + for attr in values.split(';')[:-1]: + attr, _, val = attr.strip().partition(' ') + values_dict[attr] = val.strip('"') + + if 'gene_id' not in values_dict or \ + 'transcript_id' not in values_dict: + continue + + transcript_id = values_dict['transcript_id'] + if transcript_id not in trans: + trans[transcript_id] = [chrom, strand, [[left, right]]] + else: + trans[transcript_id][2].append([left, right]) + + gtf_file.close() + + # Sort exons and merge where separating introns are <=5 bps + for tran, [chrom, strand, exons] in trans.items(): + exons.sort() + tmp_exons = [exons[0]] + for i in range(1, len(exons)): + if exons[i][0] - tmp_exons[-1][1] <= 5: + tmp_exons[-1][1] = exons[i][1] + else: + tmp_exons.append(exons[i]) + trans[tran] = [chrom, strand, tmp_exons] + + # Calculate and print the unique junctions + junctions = set() + for chrom, strand, exons in trans.values(): + for i in range(1, len(exons)): + junctions.add(to_junction_str([chrom, exons[i-1][1], exons[i][0]])) + + return junctions + +""" +""" +def read_repeat_info(repeat_filename): + repeat_info, repeat_dic = {}, {} + repeat_pos = {} + if os.path.exists(repeat_filename): + for line in open(repeat_filename): + if line[0] == ">": + line = line.strip()[1:] + allele, rep, pos, rep_len, _, _ = line.split()[:6] + pos, rep_len = int(pos), int(rep_len) + common_allele = allele.split('*')[0] + + if rep not in repeat_info: + repeat_info[rep] = [] + repeat_dic[rep] = {} + repeat_pos[rep] = {} + + repeat_info[rep].append([allele, pos, rep_len]) + if allele not in repeat_dic[rep]: + repeat_dic[rep][allele] = [] + repeat_pos[rep][allele] = set() + else: + coords = line.split() + for coord in coords: + chr, pos, strand = coord.split(':') + pos = int(pos) + if pos in repeat_pos[rep][allele]: + continue + repeat_dic[rep][allele].append([chr, pos, strand]) + repeat_pos[rep][allele].add(pos) + + for rep, repeats in repeat_info.items(): + def my_cmp(a, b): + if a[1] < b[1]: + return -1 + elif a[1] == b[1]: + return a[2] - b[2] + else: + return 1 + repeat_info[rep] = sorted(repeat_info[rep], cmp=my_cmp) + + return repeat_info, repeat_dic + + +""" +""" +def find_repeat(repeat_info, pos): + if len(repeat_info) <= 0: + return -1 + + l, r = 0, len(repeat_info) + while l < r: + m = (l + r) / 2 + _, rep_pos, rep_len, _ = repeat_info[m] + if rep_pos <= pos and pos < rep_pos + rep_len: + return m + elif pos < rep_pos: + r = m + else: + l = m + 1 + + return -1 + +def reverse_cigar(cigar_str): + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + cigars[::-1] + + read_len = 0 + cigar_str = "" + for cigar in cigars: + cigar_op, length = cigar + cigar_str += ("%d%s" % (length, cigar_op)) + if cigar_op in "MISH": + read_len += int(length) + + return read_len, cigar_str + + + +def to_junction_str(junction): + return "%s-%d-%d" % (junction[0], junction[1], junction[2]) + + +def to_junction(junction_str): + fields = junction_str.split("-") + if len(fields) > 3: + chr, left, right = "-".join(fields[:-2]), fields[-2], fields[-1] + else: + assert len(fields) == 3 + chr, left, right = fields + + return [chr, int(left), int(right)] + + +""" +""" +def junction_cmp(a, b): + if a[0] != b[0]: + if a[0] < b[0]: + return -1 + else: + return 1 + + if a[1] != b[1]: + if a[1] < b[1]: + return -1 + else: + return 1 + + if a[2] != b[2]: + if a[2] < b[2]: + return -1 + else: + return 1 + + return 0 + + +""" +# chr and pos are assumed to be integers +""" +def get_junctions(chr, pos, cigar_str, min_anchor_len = 0, read_len = 100): + junctions = [] + right_pos = pos + cigars = cigar_re.findall(cigar_str) + cigars = [[int(cigars[i][:-1]), cigars[i][-1]] for i in range(len(cigars))] + + left_anchor_lens = [] + cur_left_anchor_len = 0 + for i in range(len(cigars)): + length, cigar_op = cigars[i] + if cigar_op in "MI": + cur_left_anchor_len += length + elif cigar_op == "N": + assert cur_left_anchor_len > 0 + left_anchor_lens.append(cur_left_anchor_len) + cur_left_anchor_len = 0 + + for i in range(len(cigars)): + length, cigar_op = cigars[i] + if cigar_op == "N": + left, right = right_pos - 1, right_pos + length + + if i > 0 and cigars[i-1][1] in "ID": + if cigars[i-1][1] == "I": + left += cigars[i-1][0] + else: + left -= cigars[i-1][0] + if i + 1 < len(cigars) and cigars[i+1][1] in "ID": + if cigars[i+1][1] == "I": + right -= cigars[i+1][0] + else: + right += cigars[i+1][0] + + junction_idx = len(junctions) + assert junction_idx < len(left_anchor_lens) + left_anchor_len = left_anchor_lens[junction_idx] + assert left_anchor_len > 0 and left_anchor_len < read_len + right_anchor_len = read_len - left_anchor_len + if left_anchor_len >= min_anchor_len and right_anchor_len >= min_anchor_len: + junctions.append([chr, left, right]) + + if cigar_op in "MND": + right_pos += length + + return junctions + +def get_right(pos, cigars): + right_pos = pos + cigars = cigar_re.findall(cigars) + for cigar in cigars: + length = int(cigar[:-1]) + cigar_op = cigar[-1] + if cigar_op in "MDN": + right_pos += length + + return right_pos + +def get_cigar_chars(cigars): + cigars = cigar_re.findall(cigars) + cigar_chars = "" + for cigar in cigars: + cigar_op = cigar[-1] + cigar_chars += cigar_op + + return cigar_chars + + +""" +""" +def get_cigar_chars_MN(cigars): + cigars = cigar_re.findall(cigars) + cigar_chars = "" + for cigar in cigars: + cigar_op = cigar[-1] + if cigar_op in "MN": + if cigar_chars == "" or cigar_chars[-1] != cigar_op: + cigar_chars += cigar_op + + return cigar_chars + + +""" +""" +def is_small_anchor_junction_read(cigars): + cigar_list = [] + for cigar in cigar_re.findall(cigars): + cigar_op = cigar[-1] + cigar_len = int(cigar[:-1]) + cigar_list.append([cigar_op, cigar_len]) + + if len(cigar_list) < 3: + return False + + if cigar_list[0][0] != 'M' or cigar_list[-1][0] != 'M': + return False + + if cigar_list[0][1] > 10 and cigar_list[-1][1] > 10: + return False + + if cigar_list[1][0] != 'N' or cigar_list[-2][0] != 'N': + return False + + return True + + +""" +""" +def is_canonical_junction(chr_dic, junction): + chr, left, right = junction + donor = chr_dic[chr][left:left+2] + acceptor = chr_dic[chr][right-3:right-1] + rev_donor = reverse_complement(acceptor) + rev_acceptor = reverse_complement(donor) + + if (donor == "GT" and acceptor == "AG") or \ + (rev_donor == "GT" and rev_acceptor == "AG"): + return True + + return False + + +""" +""" +def is_small_exon_junction_read(cigars, min_exon_len = 23): + cigars = cigar_re.findall(cigars) + for i in range(1, len(cigars) - 1): + cigar = cigars[i] + cigar_op = cigar[-1] + cigar_len = int(cigar[:-1]) + + prev_op = cigars[i-1][-1] + next_op = cigars[i+1][-1] + + if prev_op == 'N' and cigar_op == 'M' and next_op == 'N': + if cigar_len <= min_exon_len: + return True + + return False + + +""" +""" +""" +def repeat_to_genome_alignment(repeat_info, repeat_dic, rep, pos, cigar_str = ""): + assert rep in repeat_info + left = pos - 1 # convert 1-based offset to zero-based + + repeats = repeat_info[rep] + l, r = 0, len(repeats) + while l < r: + m = (l + r) / 2 + rep_allele, rpos, rlen = repeats[m] + if left >= rpos and left < rpos + rlen: + while m > 0: + rep_allele, rpos, rlen = repeats[m-1] + if left < rpos: + break + m -= 1 + break + if left < rpos: + r = m + else: + l = m + 1 + + alignments = [] + while m < len(repeats): + rep_allele, rpos, rlen = repeats[m] + if left >= rpos + rlen: + m += 1 + continue + + if left < rpos: + break + + assert rep_allele in repeat_dic[rep] + coords = repeat_dic[rep][rep_allele] + assert len(coords) > 0 + for coord in coords: + cchr, cpos, cstrand = coord + adj_left = left - rpos + if cstrand == '+': + rep_left = cpos + adj_left + rep_cigar_str = cigar_str + else: + if cigar_str: + read_len, rep_cigar_str = reverse_cigar(cigar_str) + else: + read_len, rep_cigar_str = 0, "" + rc_adj_left = rlen - adj_left - read_len; + rep_left = cpos + rc_adj_left + + alignments.append([cchr, rep_left + 1, rep_cigar_str]) + m += 1 + + return alignments +""" +def repeat_to_genome_alignment(repeat_db, repeat_map, rptRefName, pos, cigar_str = ''): + assert rptRefName in repeat_db + readlen = read_len_cigar(cigar_str) + #readlen = 101 + + # pos in sam-result. pos is 1-based + left = pos - 1 + right = left + readlen + + repeats = repeat_db[rptRefName] + rmap = repeat_map[rptRefName] + + #print len(rmap) + #print rmap + + alignments = [] + + i = find_leftmost_pos(rmap, left) + if i >= len(rmap): + print >> sys.stderr, 'Value Error' + return alignments + + if right > rmap[i][0]: + print >> sys.stderr, 'Not repeat' + return alignments + + repeat = repeats[rmap[i][1]] + + #print 'Allele Size:', len(repeat.allele) + #print repeat.allele + for allele in repeat.allele: + rpos = allele.repeat_pos + rlen = allele.repeat_length + + if (left >= rpos) and (right <= rpos + rlen): + offset = left - rpos + for coord in allele.positions: + cchr, cpos, cstrand = coord + if cstrand == '+': + rep_left = cpos + offset + rep_cigar_str = cigar_str + else: + if cigar_str: + rep_read_len, rep_cigar_str = reverse_cigar(cigar_str) + else: + rep_read_len, rep_cigar_str = 0, "" + + rc_offset = rlen - offset - rep_read_len + rep_left = cpos + rc_offset + + alignments.append([cchr, rep_left + 1, rep_cigar_str]) + #print genome_pos[0], genome_pos[1] + offset + 1, genome_pos[2], genome_pos[1] + + return alignments + + +""" +""" +def extract_single(infilename, + outfilename, + chr_dic, + aligner, + version, + repeat_db, + repeat_map, + debug_dic, + hash_idx): + infile = open(infilename) + if hash_idx == -1: + outfile = open(outfilename, "w") + else: + outfile = open(outfilename + "." + str(hash_idx), "w") + + prev_read_id = "" + num_reads, num_aligned_reads, num_ualigned_reads = 0, 0, 0 + prev_NM, prev_NH, NH_real = 0, 0, 0 + + for line in infile: + if line[0] == '@': + continue + + cols = line[:-1].split() + read_id, flag, chr, pos, mapQ, cigar_str = cols[:6] + read_seq = cols[9] + if len(read_id) >= 3 and read_id[-2] == "/": + read_id = read_id[:-2] + + if read_id.find("seq.") == 0: + read_id = read_id[4:] + + if aligner == "gsnap": + chr = chr.replace("_", ":") + + if hash_idx != -1: + hashval = hash(read_id) + if hashval % mp_num != hash_idx: + continue + + if read_id != prev_read_id: + num_reads += 1 + + flag, pos, mapQ = int(flag), int(pos), int(mapQ) + if flag & 0x4 != 0 or \ + 'H' in cigar_str: + prev_read_id = read_id + continue + + NH, NM, XA = "", sys.maxint, [] + for i in range(11, len(cols)): + col = cols[i] + # "nM" from STAR + if col.startswith("NM") or col.startswith("nM"): + NM = int(col[5:]) + elif col.startswith("NH"): + NH = col + elif col.startswith("XA"): + XA = col[5:].split(';')[:-1] + if NH != "": + NH = int(NH[5:]) + if aligner == "hisat2": + if prev_read_id == read_id: + assert prev_NH == NH + if NH == 1 or mapQ == 60: + assert NH == 1 and mapQ == 60 + + if read_id != prev_read_id: + num_aligned_reads += 1 + if aligner == "hisat2" and \ + NH == 1: + num_ualigned_reads += 1 + else: + # In case of Bowtie2, only consier the best alignments + if aligner in ["bowtie2", "bwa", "vg"]: + if NM > prev_NM: + continue + + def adjust_alignment(chr, pos, cigar_str): + NM_real = 0 + read_pos, right_pos = 0, pos - 1 + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + for i in range(len(cigars)): + cigar_op, length = cigars[i] + if cigar_op == "S": + assert i == 0 or i == len(cigars) - 1 + if i == 0: + assert cigars[i+1][0] == "M" + ref_seq = chr_dic[chr][right_pos-length:right_pos] + else: + assert cigars[i-1][0] == "M" + ref_seq = chr_dic[chr][right_pos:right_pos+length] + + ref_seq = ref_seq.upper() + if length == len(ref_seq): + for j in range(length): + if ref_seq[j] != "N" and read_seq[read_pos+j] != ref_seq[j]: + NM_real += 1 + else: + NM_real += length + if cigar_op in "MND": + right_pos += length + if cigar_op in "MIS": + read_pos += length + + if cigars[0][0] == "S": + assert cigars[1][0] == "M" + pos -= cigars[0][1] + cigars[1][1] += cigars[0][1] + cigars = cigars[1:] + if cigars[-1][0] == "S": + assert cigars[-2][0] == "M" + cigars[-2][1] += cigars[-1][1] + cigars = cigars[:-1] + + cigar_str = "" + for cigar in cigars: + cigar_op, length = cigar + cigar_str += ("%d%s" % (length, cigar_op)) + + return pos, cigar_str, NM_real + + + alignments = [[chr, pos, cigar_str]] + if aligner == "bwa" and len(XA) > 0: + for alignment in XA: + alt_chr, alt_pos, alt_cigar_str, alt_NM = alignment.split(',') + alt_pos, alt_NM = abs(int(alt_pos)), int(alt_NM) + if alt_NM > NM: + break + alignments.append([alt_chr, alt_pos, alt_cigar_str]) + + # Convert repeat alignments to genome alignments + if aligner == "hisat2" and chr.startswith("rep") and len(repeat_map) > 0: + alignments = repeat_to_genome_alignment(repeat_db, repeat_map, chr, pos, cigar_str) + + for i, alignment in enumerate(alignments): + chr, pos, cigar_str = alignment + pos, cigar_str, NM_real = adjust_alignment(chr, pos, cigar_str) + p_str = "%s\t%s\t%d\t%s\tNM:i:%d" % (read_id, chr, pos, cigar_str, NM_real) + print >> outfile, p_str + + if aligner == "hisat2": + if prev_read_id != read_id: + if prev_read_id != "": + assert prev_NH == NH_real + NH_real = 1 + else: + NH_real += 1 + prev_NH = NH + prev_NM = NM + prev_read_id = read_id + + if aligner == "hisat2": + if prev_read_id != "": + assert prev_NH == NH_real + + outfile.close() + infile.close() + + # Sanity check for HISAT2's alignment summary + if aligner == "hisat2" and os.path.exists(infilename + ".summary") and (not mp_mode): + hisat2_reads, hisat2_0aligned_reads, hisat2_ualigned_reads, hisat2_maligned_reads = 0, 0, 0, 0 + for line in open(infilename + ".summary"): + line = line.strip() + if line.startswith("HISAT2 summary") or \ + line.startswith("Overall"): + continue + category, num = line.split(':') + num = num.strip() + num = int(num.split(' ')[0]) + if category.startswith("Total reads"): + hisat2_reads = num + elif category.startswith("Aligned 0 time"): + hisat2_0aligned_reads = num + elif category.startswith("Aligned 1 time"): + hisat2_ualigned_reads = num + else: + assert category.startswith("Aligned >1 time") + assert hisat2_reads == hisat2_0aligned_reads + hisat2_ualigned_reads + num + + hisat2_aligned_reads = hisat2_reads - hisat2_0aligned_reads + + assert hisat2_reads == num_reads + assert hisat2_aligned_reads == num_aligned_reads + assert hisat2_ualigned_reads == num_ualigned_reads + + +""" +""" +def extract_pair(infilename, + outfilename, + chr_dic, + RNA, + aligner, + version, + repeat_db, + repeat_map, + debug_dic, + hash_idx): + read_dic = {} + pair_reported = set() + + infile = open(infilename) + if hash_idx == -1: + outfile = open(outfilename, "w") + else: + outfile = open(outfilename + "." + str(hash_idx), "w") + + num_pairs, num_conc_aligned_pairs, num_conc_ualigned_pairs, num_disc_aligned_pairs = 0, 0, 0, 0 + num_aligned_reads, num_ualigned_reads = 0, 0 + + prev_read_id, pair_list = "", set() + prev_NM = sys.maxint + prev_NH1, prev_NH2 = 0, 0 + NH1_real, NH2_real = 0, 0 + + for line in infile: + if line[0] == '@': + continue + + cols = line[:-1].split() + read_id, flag, chr1, pos1, mapQ, cigar1_str, chr2, pos2 = cols[:8] + read_seq = cols[9] + if len(read_id) >= 3 and read_id[-2] == "/": + read_id = read_id[:-2] + + if read_id.find("seq.") == 0: + read_id = read_id[4:] + + if hash_idx != -1: + hashval = hash(read_id) + if hashval % mp_num != hash_idx: + continue + + if aligner == "gsnap": + chr1 = chr1.replace("_", ":") + chr2 = chr2.replace("_", ":") + + if read_id != prev_read_id: + num_pairs += 1 + pair_list = set() + prev_NM = sys.maxint + + flag = int(flag) + canonical_pos1, canonical_pos2 = int(pos1), int(pos2) + left_read = (flag & 0x40 != 0) + pos1 = canonical_pos1 + mapQ = int(mapQ) + if flag & 0x4 != 0 or \ + 'H' in cigar1_str: + prev_read_id, is_prev_read_left = read_id, left_read + continue + + concordant = (flag & 0x2 != 0) + NH, NM1, YT, XA = sys.maxint, sys.maxint, "", [] + for i in range(11, len(cols)): + col = cols[i] + # "nM" from STAR + if col.startswith("NM") or col.startswith("nM"): + NM1 = int(col[5:]) + elif col.startswith("NH"): + NH = int(col[5:]) + elif col.startswith("YT"): + YT = col[5:] + elif col.startswith("XA"): + XA = col[5:].split(';')[:-1] + + if aligner == "hisat2": + if prev_read_id == read_id: + if left_read: + assert prev_NH1 == 0 or prev_NH1 == NH + else: + assert prev_NH2 == 0 or prev_NH2 == NH + if NH == 1 or mapQ == 60: + assert NH == 1 and mapQ == 60 + + unpaired = (flag & 0x8 != 0) or (YT in ["UU", "UP"]) + if unpaired: + if left_read not in pair_list: + pair_list.add(left_read) + num_aligned_reads += 1 + if aligner == "hisat2" and NH == 1: + num_ualigned_reads += 1 + assert mapQ == 60 + else: + if read_id != prev_read_id: + if concordant: + num_conc_aligned_pairs += 1 + if aligner == "hisat2" and NH == 1: + num_conc_ualigned_pairs += 1 + else: + if aligner == "hisat2": + assert YT == "DP" + num_disc_aligned_pairs += 1 + + if chr2 == '*': + continue + + def adjust_alignment(chr, pos, cigar_str): + NM_real = 0 + read_pos, right_pos = 0, pos - 1 + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + for i in range(len(cigars)): + cigar_op, length = cigars[i] + if cigar_op == "S": + assert i == 0 or i == len(cigars) - 1 + if i == 0: + assert cigars[i+1][0] == "M" + ref_seq = chr_dic[chr1][right_pos-length:right_pos] + else: + assert cigars[i-1][0] == "M" + ref_seq = chr_dic[chr1][right_pos:right_pos+length] + + ref_seq = ref_seq.upper() + if length == len(ref_seq): + for j in range(length): + if ref_seq[j] != "N" and read_seq[read_pos+j] != ref_seq[j]: + NM_real += 1 + else: + NM_real += length + if cigar_op in "MND": + right_pos += length + if cigar_op in "MIS": + read_pos += length + + if cigars[0][0] == "S": + assert cigars[1][0] == "M" + pos -= cigars[0][1] + cigars[1][1] += cigars[0][1] + cigars = cigars[1:] + if cigars[-1][0] == "S": + assert cigars[-2][0] == "M" + cigars[-2][1] += cigars[-1][1] + cigars = cigars[:-1] + + cigar_str = "" + for cigar in cigars: + cigar_op, length = cigar + cigar_str += ("%d%s" % (length, cigar_op)) + + return pos, cigar_str, NM_real + + alignments = [[chr1, pos1, cigar1_str]] + if aligner == "bwa" and len(XA) > 0: + for alignment in XA: + alt_chr, alt_pos, alt_cigar_str, alt_NM = alignment.split(',') + alt_pos, alt_NM = abs(int(alt_pos)), int(alt_NM) + if alt_NM > NM1: + break + alignments.append([alt_chr, alt_pos, alt_cigar_str]) + + # Convert repeat alignments to genome alignments + if aligner == "hisat2" and (chr1.startswith("rep") or chr2.startswith("rep")) and len(repeat_map) > 0: + if chr1.startswith("rep"): + alignments = repeat_to_genome_alignment(repeat_db, repeat_map, chr1, pos1, cigar1_str) + if chr2.startswith("rep") or (chr1.startswith("rep") and chr2 == "="): + chr_tmp = chr1 if chr2 == "=" else chr2 + alignments2 = repeat_to_genome_alignment(repeat_db, repeat_map, chr_tmp, int(pos2)) + else: + alignments2 = [[chr2, int(pos2)]] + + selected_alignments = [] + for alignment in alignments: + _chr1, _pos1 = alignment[:2] + add = False + for alignment2 in alignments2: + _chr2, _pos2 = alignment2[:2] + if _chr1 == _chr2 and abs(_pos1 - _pos2) <= 1000: + add = True + break + if add: + selected_alignments.append(alignment) + + alignments = selected_alignments + + for i, alignment in enumerate(alignments): + chr1, pos1, cigar1_str = alignment + pos1, cigar_str, NM_real = adjust_alignment(chr1, pos1, cigar1_str) + chr2 = chr1 + + if aligner == "bwa": + me = "%s\t%s" % (read_id, chr1) + partner = "%s\t%s" % (read_id, chr2) + else: + me = "%s\t%s\t%d" % (read_id, chr1, canonical_pos1) + partner = "%s\t%s\t%d" % (read_id, chr2, canonical_pos2) + if partner in read_dic: + maps = read_dic[partner] + + for map in maps: + if (map[0] == me) or len(maps) == 1: + cigar2_str, NM2, pos2 = map[1:4] + + if aligner == "bwa": + if abs(pos1 - pos2) >= 1000: + continue + + if aligner in ["bowtie2", "bwa"]: + if NM1 + NM2 > prev_NM: + continue + else: + prev_NM = NM1 + NM2 + + if chr1 != chr2: + continue + + # DK - debugging purposes + if RNA: + if aligner in ["bowtie2", "bwa"] and abs(pos1 - pos2) > 1000: + continue + else: + if abs(pos1 - pos2) > 1000: + continue + + if int(pos2) > int(pos1): + p_str = "%s\t%s\t%d\t%s\t%s\t%d\t%s\tNM:i:%d\tNM:i:%d" % \ + (read_id, chr1, pos1, cigar_str, chr2, pos2, cigar2_str, NM1, NM2) + else: + p_str = "%s\t%s\t%d\t%s\t%s\t%d\t%s\tNM:i:%d\tNM:i:%d" % \ + (read_id, chr2, pos2, cigar2_str, chr1, pos1, cigar_str, NM2, NM1) + + if p_str not in pair_reported: + pair_reported.add(p_str) + print >> outfile, p_str + + + + if not me in read_dic: + read_dic[me] = [] + + read_dic[me].append([partner, cigar_str, NM1, pos1]) + + if aligner == "hisat2": + if prev_read_id != read_id: + if prev_read_id != "": + assert prev_NH1 == NH1_real + assert prev_NH2 == NH2_real + prev_NH1, prev_NH2 = 0, 0 + if left_read: + NH1_real, NH2_real = 1, 0 + else: + NH1_real, NH2_real = 0, 1 + else: + if left_read: + NH1_real += 1 + else: + NH2_real += 1 + if left_read: + prev_NH1 = NH + else: + prev_NH2 = NH + prev_read_id = read_id + + if aligner == "hisat2": + if prev_read_id != "": + assert prev_NH1 == NH1_real + assert prev_NH2 == NH2_real + + outfile.close() + infile.close() + + # Sanity check for HISAT2's alignment summary + if aligner == "hisat2" and os.path.exists(infilename + ".summary") and (not mp_mode): + hisat2_pairs, hisat2_0aligned_pairs, hisat2_conc_ualigned_pairs, hisat2_conc_maligned_pairs, hisat2_disc_aligned_pairs = 0, 0, 0, 0, 0 + hisat2_reads, hisat2_0aligned_reads, hisat2_ualigned_reads, hisat2_maligned_reads = 0, 0, 0, 0 + + for line in open(infilename + ".summary"): + line = line.strip() + if line.startswith("HISAT2 summary") or \ + line.startswith("Overall"): + continue + category, num = line.split(':') + num = num.strip() + num = int(num.split(' ')[0]) + if category.startswith("Total pairs"): + hisat2_pairs = num + elif category.startswith("Aligned concordantly or discordantly 0 time"): + hisat2_0aligned_pairs = num + elif category.startswith("Aligned concordantly 1 time"): + hisat2_conc_ualigned_pairs = num + elif category.startswith("Aligned concordantly >1 time"): + hisat2_conc_maligned_pairs = num + elif category.startswith("Aligned discordantly"): + hisat2_disc_aligned_pairs = num + assert hisat2_pairs == hisat2_0aligned_pairs + hisat2_conc_ualigned_pairs + hisat2_conc_maligned_pairs + hisat2_disc_aligned_pairs + elif category.startswith("Total unpaired reads"): + hisat2_reads = num + assert hisat2_reads == hisat2_0aligned_pairs * 2 + elif category.startswith("Aligned 0 time"): + hisat2_0aligned_reads = num + elif category.startswith("Aligned 1 time"): + hisat2_ualigned_reads = num + else: + assert category.startswith("Aligned >1 times") + hisat2_maligned_reads = num + assert hisat2_reads == hisat2_0aligned_reads + hisat2_ualigned_reads + hisat2_maligned_reads + + assert hisat2_pairs == num_pairs + assert hisat2_conc_ualigned_pairs == num_conc_ualigned_pairs + assert hisat2_conc_maligned_pairs == num_conc_aligned_pairs - num_conc_ualigned_pairs + assert hisat2_disc_aligned_pairs == num_disc_aligned_pairs + assert hisat2_ualigned_reads == num_ualigned_reads + assert hisat2_maligned_reads == num_aligned_reads - num_ualigned_reads + + +""" +""" +def is_junction_read(junctions_dic, chr, pos, cigar_str): + result_junctions = [] + junctions = get_junctions(chr, pos, cigar_str) + for junction in junctions: + junction_str = to_junction_str(junction) + result_junctions.append([junction_str, junction_str in junctions_dic]) + + return result_junctions + + +""" +""" +def is_junction_pair(junctions_dic, chr, pos, cigar_str, mate_chr, mate_pos, mate_cigar_str): + junctions = is_junction_read(junctions_dic, chr, pos, cigar_str) + mate_junctions = is_junction_read(junctions_dic, mate_chr, mate_pos, mate_cigar_str) + junctions += mate_junctions + return junctions + + +""" +""" +def find_in_gtf_junctions(chr_dic, gtf_junctions, junction, relax_dist = 5): + def find_in_gtf_junctions(gtf_junctions, junction): + l, u = 0, len(gtf_junctions) + while l < u: + m = (l + u) / 2 + assert m >= 0 and m < len(gtf_junctions) + cmp_result = junction_cmp(junction, gtf_junctions[m]) + if cmp_result == 0: + return m + elif cmp_result < 0: + u = m + else: + l = m + 1 + + return l + + chr, left, right = junction + gtf_index = find_in_gtf_junctions(gtf_junctions, [chr, left - relax_dist, right - relax_dist]) + + if gtf_index >= 0: + i = gtf_index + while i < len(gtf_junctions): + chr2, left2, right2 = gtf_junctions[i] + if chr2 > chr or \ + left2 - left > relax_dist or \ + right2 - right > relax_dist: + break + + if abs(left - left2) <= relax_dist and left - left2 == right - right2: + test_small = ":" in chr + if is_canonical_junction(chr_dic, gtf_junctions[i]): + if left == left2: + return i + else: + return -1 + else: + return i + i += 1 + + return -1 + + +def singleInMaps(chr, pos, pos2, cigar, NM, maps): + for i in range(len(maps)): + if chr != maps[i][0]: + continue + if (pos == maps[i][1] or pos2 == maps[i][2]): + return True, i + return False, -1 + + + +""" +""" +def compare_single_sam(RNA, + reference_sam, + query_sam, + mapped_fname, + chr_dic, + gtf_junctions, + gtf_junctions_set, + ex_gtf_junctions, + aligner): + aligned, multi_aligned = 0, 0 + db_dic, db_junction_dic = {}, {} + mapped_file = open(mapped_fname, "w") + first_mapped_file = open(mapped_fname + ".first", "w") + file = open(reference_sam, "r") + junction_read_dic = {} + for line in file: + if line.startswith('@'): + continue + + read_name, chr, pos, cigar, NM = line[:-1].split() + pos, NM = int(pos), int(NM[5:]) + + if read_name.find("seq.") == 0: + read_name = read_name[4:] + + if len(read_name) > 2 and read_name[-2] == '/': + read_name = read_name[:-2] + + multi_aligned += 1 + if read_name not in db_dic: + db_dic[read_name] = [] + aligned += 1 + + pos2 = get_right(pos, cigar) + db_dic[read_name].append([chr, pos, pos2, cigar, NM]) + + read_junctions = is_junction_read(gtf_junctions_set, chr, pos, cigar) + if len(read_junctions) > 0: + if read_name not in db_junction_dic: + db_junction_dic[read_name] = [] + + for junction_str, is_gtf_junction in read_junctions: + db_junction_dic[read_name].append([junction_str, is_gtf_junction]) + + if junction_str not in junction_read_dic: + junction_read_dic[junction_str] = [] + junction_read_dic[junction_str].append(line[:-1]) + + file.close() + + temp_junctions, temp_gtf_junctions = set(), set() + for read_name, can_junctions in db_junction_dic.items(): + if len(can_junctions) <= 0: + continue + + # DK - for debugging purposes + # 1. select the best candidate among spliced alignments if multiple + + def pickup_junction(can_junctions): + junctions = [can_junctions[0]] + for i in range(1, len(can_junctions)): + def get_intron_len(can_junction): + chr, left, right = to_junction(can_junction) + return right - left - 1 + + intron, intron_cmp = get_intron_len(junctions[0][0]), get_intron_len(can_junctions[i][0]) + + if intron > intron_cmp: + junctions = [can_junctions[i]] + elif intron == intron_cmp: + junctions.append(can_junctions[i]) + + return junctions + + # can_junctions = pickup_junction(can_junctions) + + for can_junction in can_junctions: + found_junction_str = None + junction_str, is_gtf_junction = can_junction + if is_gtf_junction: + found_junction_str = junction_str + + if not found_junction_str: + junction = to_junction(junction_str) + gtf_index = find_in_gtf_junctions(chr_dic, gtf_junctions, junction) + + if gtf_index >= 0: + is_gtf_junction = True + found_junction_str = to_junction_str(gtf_junctions[gtf_index]) + + if found_junction_str: + temp_gtf_junctions.add(found_junction_str) + temp_junctions.add(found_junction_str) + else: + if junction_str not in temp_junctions: + None + # assert junction_str in junction_read_dic + # DK - for debugging purposes + """ + if len(junction_read_dic[junction_str]) <= 2: + canonical = is_canonical_junction(chr_dic, to_junction(junction_str)) + if not canonical: + print >> sys.stdout, read_name, junction_str, len(junction_read_dic[junction_str]), can_junctions + for line in junction_read_dic[junction_str]: + print >> sys.stdout, "\t", line + """ + temp_junctions.add(junction_str) + + + temp2_junctions = [] + for junction in temp_junctions: + temp2_junctions.append(to_junction(junction)) + temp_junctions = sorted(list(temp2_junctions), cmp=junction_cmp) + temp2_junctions = [] + for can_junction in temp_junctions: + if len(temp2_junctions) <= 0: + temp2_junctions.append(can_junction) + else: + chr, left, right = temp2_junctions[-1] + chr2, left2, right2 = can_junction + if chr == chr2 and \ + abs(left - left2) == abs(right - right2) and \ + abs(left - left2) <= 10 and \ + not to_junction_str(can_junction) in temp_gtf_junctions: + continue + temp2_junctions.append(can_junction) + + temp_junctions = set() + for junction in temp2_junctions: + temp_junctions.add(to_junction_str(junction)) + + file = open(query_sam) + mapped, unmapped, unique_mapped, first_mapped, mapping_point = 0, 0, 0, 0, 0.0 + snp_mapped, snp_unmapped, snp_unique_mapped, snp_first_mapped = 0, 0, 0, 0 + for line in file: + if line.startswith('@'): + continue + fields = line[:-1].split() + read_name, chr, pos, cigar = fields[:4] + trans_id, NM, Zs = None, None, None + for field in fields[4:]: + if field.startswith("TI"): + trans_id = field[5:] + elif field.startswith("NM"): + NM = int(field[5:]) + elif field.startswith("Zs"): + Zs = field[5:] + snp_included = (Zs != None) + + pos = int(pos) + pos2 = get_right(pos, cigar) + if read_name not in db_dic: + unmapped += 1 + if snp_included: + snp_unmapped += 1 + continue + + maps = db_dic[read_name] + found = False + found_at_first = False + + if (aligner == "hisat-TLA" and RNA): + found, index = singleInMaps(chr, pos, pos2, cigar, NM, maps) + if found: + if index == 0: + found_at_first = True + + else: + if [chr, pos, pos2, cigar, NM] in maps: + found = True + if maps.index([chr, pos, pos2, cigar, NM]) == 0: + found_at_first = True + + # DK - debugging purposes + if False and len(maps) > 0 and maps[0][-1] < NM: + found = True + + if not found: + for idx, map in enumerate(maps): + if chr == map[0] and \ + pos == map[1] and \ + pos2 == map[2] and \ + get_cigar_chars(cigar) == get_cigar_chars(map[3]): + + read_junctions = is_junction_read(gtf_junctions_set, map[0], map[1], map[3]) + if True: + found_list = [False for i in range(len(read_junctions))] + for j in range(len(read_junctions)): + junction_str, is_gtf_junction = read_junctions[j] + junction = to_junction(junction_str) + gtf_index = find_in_gtf_junctions(chr_dic, gtf_junctions, junction) + if gtf_index >= 0: + found_list[j] = True + found = not (False in found_list) + else: + found = False + + if found: + if idx == 0: + found_at_first = True + break + + if found: + print >> mapped_file, read_name + mapped += 1 + if snp_included: + snp_mapped += 1 + if len(maps) == 1: + unique_mapped += 1 + if snp_included: + snp_unique_mapped += 1 + if found_at_first: + print >> first_mapped_file, read_name + first_mapped += 1 + if snp_included: + snp_first_mapped += 1 + mapping_point += (1.0 / len(maps)) + else: + unmapped += 1 + if snp_included: + snp_unmapped += 1 + + file.close() + mapped_file.close() + first_mapped_file.close() + + # DK - for debugging purposes + false_can_junctions, false_noncan_junctions = 0, 0 + for junction_str in temp_junctions: + if junction_str in temp_gtf_junctions: + continue + if junction_str in ex_gtf_junctions: + continue + if is_canonical_junction(chr_dic, to_junction(junction_str)): + false_can_junctions += 1 + else: + false_noncan_junctions += 1 + print >> sys.stderr, "\t\t\tfalse junctions: %d (canonical), %d (non-canonical)" % (false_can_junctions, false_noncan_junctions) + + return mapped, unique_mapped, first_mapped, unmapped, aligned, multi_aligned, \ + snp_mapped, snp_unique_mapped, snp_first_mapped, snp_unmapped, \ + len(temp_junctions), len(temp_gtf_junctions), mapping_point + + + +def pairedInMaps(chr, pos, pos_right, cigar, pos2, pos2_right, cigar2, NM, NM2, maps): + for i in range(len(maps)): + if chr != maps[i][0]: + continue; + if (pos == maps[i][1] or pos_right == maps[i][2]) and (pos2 == maps[i][4] or pos2_right == maps[i][5]): + return True, i + return False, -1 +""" +""" +def compare_paired_sam(RNA, + reference_sam, + query_sam, + mapped_fname, + chr_dic, + gtf_junctions, + gtf_junctions_set, + ex_gtf_junctions, + aligner): + aligned, multi_aligned = 0, 0 + db_dic, db_junction_dic, junction_pair_dic = {}, {}, {} + mapped_file = open(mapped_fname, "w") + uniq_mapped_file = open(mapped_fname + '.uniq', "w") + first_mapped_file = open(mapped_fname + '.first', "w") + file = open(reference_sam, "r") + for line in file: + if line[0] == '@': + continue + read_name, chr, pos, cigar, chr2, pos2, cigar2, NM, NM2 = line[:-1].split() + pos, pos2 = int(pos), int(pos2) + NM, NM2 = int(NM[5:]), int(NM2[5:]) + + if read_name.find("seq.") == 0: + read_name = read_name[4:] + + if len(read_name) > 2 and read_name[-2] == '/': + read_name = read_name[:-2] + + multi_aligned += 1 + if read_name not in db_dic: + db_dic[read_name] = [] + aligned += 1 + + pos_right, pos2_right = get_right(pos, cigar), get_right(pos2, cigar2) + db_dic[read_name].append([chr, pos, pos_right, cigar, pos2, pos2_right, cigar2, NM, NM2]) + + + pair_junctions = is_junction_pair(gtf_junctions_set, chr, pos, cigar, chr2, pos2, cigar2) + if len(pair_junctions) > 0: + if read_name not in db_junction_dic: + db_junction_dic[read_name] = [] + + for junction_str, is_gtf_junction in pair_junctions: + db_junction_dic[read_name].append([junction_str, is_gtf_junction]) + + # DK - for debugging purposes + if junction_str not in junction_pair_dic: + junction_pair_dic[junction_str] = [] + junction_pair_dic[junction_str].append(line[:-1]) + + file.close() + + temp_junctions, temp_gtf_junctions = set(), set() + for read_name, can_junctions in db_junction_dic.items(): + if len(can_junctions) <= 0: + continue + + # DK - for debugging purposes + # 1. select the best candidate among spliced alignments if multiple + + def pickup_junction(can_junctions): + junctions = [can_junctions[0]] + for i in range(1, len(can_junctions)): + def get_intron_len(can_junction): + chr, left, right = to_junction(can_junction) + return right - left - 1 + + intron, intron_cmp = get_intron_len(junctions[0][0]), get_intron_len(can_junctions[i][0]) + + if intron > intron_cmp: + junctions = [can_junctions[i]] + elif intron == intron_cmp: + junctions.append(can_junctions[i]) + + return junctions + + # can_junctions = pickup_junction(can_junctions) + + for can_junction in can_junctions: + found_junction_str = None + junction_str, is_gtf_junction = can_junction + + # DK - for debugging purposes + assert junction_str in junction_pair_dic + if len(junction_pair_dic[junction_str]) <= 5: + continue + + if is_gtf_junction: + found_junction_str = junction_str + + if not found_junction_str: + junction = to_junction(junction_str) + gtf_index = find_in_gtf_junctions(chr_dic, gtf_junctions, junction) + + if gtf_index >= 0: + is_gtf_junction = True + found_junction_str = to_junction_str(gtf_junctions[gtf_index]) + + if found_junction_str: + temp_gtf_junctions.add(found_junction_str) + temp_junctions.add(found_junction_str) + else: + if junction_str not in temp_junctions: + None + # assert junction_str in junction_read_dic + # print >> sys.stdout, read_name, junction_str, len(junction_read_dic[junction_str]) + # for line in junction_read_dic[junction_str]: + # print >> sys.stdout, "\t", line + + temp_junctions.add(junction_str) + + # DK - for debugging purposes + filter_junction_db = {} + + temp2_junctions = [] + for junction in temp_junctions: + temp2_junctions.append(to_junction(junction)) + temp_junctions = sorted(list(temp2_junctions), cmp=junction_cmp) + temp2_junctions = [] + for can_junction in temp_junctions: + if len(temp2_junctions) <= 0: + temp2_junctions.append(can_junction) + + # DK - for debugging purposes + # assert to_junction_str(can_junction) in junction_pair_dic + # filter_junction_db[to_junction_str(can_junction)] = len(junction_pair_dic[to_junction_str(can_junction)]) + else: + chr, left, right = temp2_junctions[-1] + chr2, left2, right2 = can_junction + if chr == chr2 and \ + abs(left - left2) == abs(right - right2) and \ + abs(left - left2) <= 10 and \ + not to_junction_str(can_junction) in temp_gtf_junctions: + + # DK - for debugging purposes + # assert to_junction_str(temp2_junctions[-1]) in junction_pair_dic + # assert to_junction_str(temp2_junctions[-1]) in filter_junction_dic + # filter_junction_db[to_junction_str(temp2_junctions[-1])] += len(junction_pair_dic[to_junction_str(temp2_junctions[-1])]) + + continue + + temp2_junctions.append(can_junction) + + # DK - for debugging purposes + # assert to_junction_str(can_junction) in junction_pair_dic + # filter_junction_db[to_junction_str(can_junction)] = len(junction_pair_dic[to_junction_str(can_junction)]) + + temp_junctions = set() + for junction in temp2_junctions: + # DK - for debugging purposes + # assert to_junction_str(junction) in filter_junction_dic + # if filter_junction_dic[to_junction_str(junction)] <= 5: + # continue + + temp_junctions.add(to_junction_str(junction)) + + file = open(query_sam) + mapped, unique_mapped, first_mapped, unmapped, mapping_point = 0, 0, 0, 0, 0.0 + snp_mapped, snp_unique_mapped, snp_first_mapped, snp_unmapped = 0, 0, 0, 0 + for line in file: + if line.startswith('@'): + continue + + fields = line[:-1].split() + read_name, chr, pos, cigar, chr2, pos2, cigar2 = fields[:7] + trains_id, NM, NM2, Zs, Zs2 = None, None, None, None, None + for field in fields[7:]: + if field.startswith("TI"): + trans_id = field[5:] + elif field.startswith("NM"): + if NM == None: + NM = int(field[5:]) + else: + NM2 = int(field[5:]) + elif field.startswith("Zs"): + if Zs == None: + Zs = field[5:] + else: + Zs2 = field[5:] + snp_included = (Zs != None or Zs2 != None) + + pos, pos2 = int(pos), int(pos2) + pos_right, pos2_right = get_right(pos, cigar), get_right(pos2, cigar2) + + if read_name not in db_dic: + unmapped += 1 + if snp_included: + snp_unmapped += 1 + continue + + maps = db_dic[read_name] + + found = False + found_at_first = False + + + if (aligner == "hisat-TLA" and RNA) : + found, index = pairedInMaps(chr, pos, pos_right, cigar, pos2, pos2_right, cigar2, NM, NM2, maps) + if (found): + if (index == 0): + found_at_first = True + else: + if [chr, pos, pos_right, cigar, pos2, pos2_right, cigar2, NM, NM2] in maps: + found = True + if maps.index([chr, pos, pos_right, cigar, pos2, pos2_right, cigar2, NM, NM2]) == 0: + found_at_first = True + + # DK - debugging purposes + if False and len(maps) > 0 and maps[0][-1] + maps[0][-2] < NM + NM2: + found = True + + if not found: + for idx, map in enumerate(maps): + if chr == map[0] and \ + pos == map[1] and \ + pos_right == map[2] and \ + get_cigar_chars(cigar) == get_cigar_chars(map[3]) and \ + pos2 == map[4] and \ + pos2_right == map[5] and \ + get_cigar_chars(cigar2) == get_cigar_chars(map[6]): + + pair_junctions = is_junction_pair(gtf_junctions_set, map[0], map[1], map[3], map[0], map[4], map[6]) + if True: + found_list = [False for i in range(len(pair_junctions))] + for j in range(len(pair_junctions)): + junction_str, is_gtf_junction = pair_junctions[j] + junction = to_junction(junction_str) + gtf_index = find_in_gtf_junctions(chr_dic, gtf_junctions, junction) + if gtf_index >= 0: + found_list[j] = True + found = not (False in found_list) + else: + found = False + + if found: + if idx == 0: + found_at_first = True + break + + if found: + print >> mapped_file, read_name + mapped += 1 + if snp_included: + snp_mapped += 1 + if len(maps) == 1: + unique_mapped += 1 + print >> uniq_mapped_file, read_name + if snp_included: + snp_unique_mapped += 1 + if found_at_first: + print >> first_mapped_file, read_name + first_mapped += 1 + if snp_included: + snp_first_mapped += 1 + + mapping_point += (1.0 / len(maps)) + else: + unmapped += 1 + if snp_included: + snp_unmapped += 1 + + file.close() + mapped_file.close() + uniq_mapped_file.close() + first_mapped_file.close() + + # DK - for debugging purposes + false_can_junctions, false_noncan_junctions = 0, 0 + for junction_str in temp_junctions: + if junction_str in temp_gtf_junctions: + continue + if is_canonical_junction(chr_dic, to_junction(junction_str)): + false_can_junctions += 1 + else: + false_noncan_junctions += 1 + print >> sys.stderr, "\t\t\tfalse junctions: %d (canonical), %d (non-canonical)" % (false_can_junctions, false_noncan_junctions) + + + return mapped, unique_mapped, first_mapped, unmapped, aligned, multi_aligned, \ + snp_mapped, snp_unique_mapped, snp_first_mapped, snp_unmapped, \ + len(temp_junctions), len(temp_gtf_junctions), mapping_point + + +""" +""" +def extract_mapped_unmapped(read_fname, mapped_id_fname, mapped_fname, unmapped_fname, read2_fname = "", mapped2_fname = "", unmapped2_fname = ""): + mapped_ids = set() + mapped_id_file = open(mapped_id_fname) + for line in mapped_id_file: + read_id = int(line[:-1]) + mapped_ids.add(read_id) + + mapped_id_file.close() + + def write_reads(read_fname, mapped_fname, unmapped_fname): + mapped_file = open(mapped_fname, "w") + unmapped_file = open(unmapped_fname, "w") + read_file = open(read_fname) + write = False + for line in read_file: + if line[0] == "@": + read_id = int(line[1:-1]) + write = read_id in mapped_ids + + if write: + print >> mapped_file, line[:-1] + else: + print >> unmapped_file, line[:-1] + + read_file.close() + mapped_file.close() + unmapped_file.close() + + write_reads(read_fname, mapped_fname, unmapped_fname) + if read2_fname != "": + assert mapped2_fname != "" + assert unmapped2_fname != "" + write_reads(read2_fname, mapped2_fname, unmapped2_fname) + + +""" +""" +def sql_execute(sql_db, sql_query): + sql_cmd = [ + "sqlite3", sql_db, + "-separator", "\t", + "%s;" % sql_query + ] + # print >> sys.stderr, sql_cmd + sql_process = subprocess.Popen(sql_cmd, stdout=subprocess.PIPE) + output = sql_process.communicate()[0][:-1] + return output + + +""" +""" +def create_sql_db(sql_db): + if os.path.exists(sql_db): + print >> sys.stderr, sql_db, "already exists!" + return + + columns = [ + ["id", "integer primary key autoincrement"], + ["genome", "text"], + ["head", "text"], + ["end_type", "text"], + ["type", "text"], + ["aligner", "text"], + ["version", "text"], + ["num_reads", "integer"], + ["mapped_reads", "integer"], + ["unique_mapped_reads", "integer"], + ["unmapped_reads", "integer"], + ["mapping_point", "real"], + ["snp_mapped_reads", "integer"], + ["snp_unique_mapped_reads", "integer"], + ["snp_unmapped_reads", "integer"], + ["time", "real"], + ["mem", "integer"], + ["true_gtf_junctions", "integer"], + ["temp_junctions", "integer"], + ["temp_gtf_junctions", "integer"], + ["host", "text"], + ["created", "text"], + ["cmd", "text"] + ] + + sql_create_table = "CREATE TABLE ReadCosts (" + for i in range(len(columns)): + name, type = columns[i] + if i != 0: + sql_create_table += ", " + sql_create_table += ("%s %s" % (name, type)) + sql_create_table += ");" + sql_execute(sql_db, sql_create_table) + + +""" +""" +def write_analysis_data(sql_db, genome_name, database_name): + if not os.path.exists(sql_db): + return + + aligners = [] + sql_aligners = "SELECT aligner FROM ReadCosts GROUP BY aligner" + output = sql_execute(sql_db, sql_aligners) + aligners = output.split() + + can_read_types = ["all", "M", "2M_gt_15", "2M_8_15", "2M_1_7", "gt_2M"] + tmp_read_types = [] + sql_types = "SELECT type FROM ReadCosts GROUP BY type" + output = sql_execute(sql_db, sql_types) + tmp_read_types = output.split() + + read_types = [] + for read_type in can_read_types: + if read_type in tmp_read_types: + read_types.append(read_type) + + for paired in [False, True]: + database_fname = genome_name + "_" + database_name + if paired: + end_type = "paired" + database_fname += "_paired" + else: + end_type = "single" + database_fname += "_single" + database_fname += ".analysis" + database_file = open(database_fname, "w") + print >> database_file, "end_type\ttype\taligner\tnum_reads\ttime\tmem\tmapped_reads\tunique_mapped_reads\tunmapped_reads\tmapping_point\ttrue_gtf_junctions\ttemp_junctions\ttemp_gtf_junctions" + for aligner in aligners: + for read_type in read_types: + sql_row = "SELECT end_type, type, aligner, num_reads, time, mem, mapped_reads, unique_mapped_reads, unmapped_reads, mapping_point, snp_mapped_reads, snp_unique_mapped_reads, snp_unmapped_reads, true_gtf_junctions, temp_junctions, temp_gtf_junctions FROM ReadCosts" + sql_row += " WHERE genome = '%s' and head = '%s' and aligner = '%s' and type = '%s' and end_type = '%s' ORDER BY created DESC LIMIT 1" % (genome_name, database_name, aligner, read_type, end_type) + output = sql_execute(sql_db, sql_row) + if output: + print >> database_file, output + + database_file.close() + + +""" +""" +def calculate_read_cost(single_end, + paired_end, + test_aligners, + fresh, + runtime_only, + baseChange, + verbose): + sql_db_name = "analysis.db" + if not os.path.exists(sql_db_name): + create_sql_db(sql_db_name) + + num_cpus = multiprocessing.cpu_count() + if num_cpus > 10: + num_threads = min(10, num_cpus) + desktop = False + else: + #num_threads = min(4, num_cpus) + num_threads = num_cpus - 1 + desktop = True + + data_base = "sim" + test_large_index = False + verbose = False + sql_write = True + readtypes = ["all", "M", "2M_gt_15", "2M_8_15", "2M_1_7", "gt_2M"] + + aligners = [ + # [aligner, two_step, index_type, aligner_version, addition_options] + # ["hisat", "", "", "", ""], + # ["hisat2", "", "", "204", ""], + # ["hisat2", "", "", "210", ""], + # ["hisat2", "", "snp", "203b", ""], + # ["hisat2", "", "snp", "210", ""], + # ["hisat2", "", "tran", "210", ""], + # ["hisat2", "", "snp_tran", "210", ""], + # ["hisat2", "", "", "210", ""], + ["hisat2", "", "", "", ""], + #["hisat2", "", "rep", "", ""], + # ["hisat2", "", "rep-100-300", "", ""], + # ["hisat2", "", "rep_mm", "", ""], + # ["hisat2", "", "", "", "--sensitive"], + # ["hisat2", "", "rep", "", "--sensitive"], + # ["hisat2", "", "", "", "--very-sensitive"], + # ["hisat2", "", "snp", "", ""], + # ["hisat2", "", "snp", "", "--sensitive"], + # ["hisat2", "", "snp_noht", "", ""], + # ["hisat2", "x2", "", "", ""], + # ["hisat2", "x1", "tran", "", ""], + # ["hisat2", "", "tran", "", ""], + # ["hisat2", "", "snp_tran", "", ""], + # ["hisat2", "x1", "snp_tran", "", ""], + # ["hisat2", "x1", "snp_tran_ercc", "", ""], + # ["tophat2", "gtfonly", "", "", ""], + # ["tophat2", "gtf", "", "", ""], + #["star", "", "", "", ""], + # ["star", "x2", "", "", ""], + # ["star", "gtf", "", "", ""], + # ["bowtie", "", "", "", ""], + #["bowtie2", "", "", "", ""], + # ["bowtie2", "", "", "", "-k 10"], + # ["bowtie2", "", "", "", "-k 1000 --extends 2000"], + # ["gsnap", "", "", "", ""], + # ["bwa", "mem", "", "", ""], + #["bwa", "mem", "", "", "-a"], + # ["hisat2", "", "snp", "", ""], + # ["hisat2", "", "tran", "", ""], + # ["hisat2", "", "snp_tran", "", ""], + # ["vg", "", "", "", ""], + # ["vg", "", "", "", "-M 10"], + # ["vg", "", "snp", "", ""], + # ["vg", "", "snp", "", "-M 10"], + # ["minimap2", "", "", "", ""], + ["hisat-TLA", "", "", "", ""], + ] + readtypes = ["all"] + verbose = True + debug = False + # sql_write = False + + cwd = os.getcwd() + if len(cwd.split("reads_")) > 1: + genome = cwd.split("reads_")[1].split("_")[0] + else: + genome = "genome" + RNA = (cwd.find("RNA") != -1) + + test_small = (genome != "genome") + + if runtime_only: + verbose = True + + chr_dic = read_genome("../../data/%s.fa" % genome) + gtf_junctions = extract_splice_sites("../../data/%s.gtf" % genome) + repeat_db, repeat_map = read_repeatdb("../../data/%s_rep.rep.info" % genome) + align_stat = [] + for paired in [False, True]: + if not paired and not single_end: + continue + if paired and not paired_end: + continue + for readtype in readtypes: + if paired: + base_fname = data_base + "_paired" + type_sam_fname = base_fname + "_" + readtype + ".sam" + type_read1_fname = base_fname + "_1_" + readtype + ".fa" + type_read2_fname = base_fname + "_2_" + readtype + ".fa" + type_junction_fname = base_fname + "_" + readtype + ".junc" + else: + base_fname = data_base + "_single" + type_sam_fname = base_fname + "_" + readtype + ".sam" + type_read1_fname = base_fname + "_" + readtype + ".fa" + type_read2_fname = "" + type_junction_fname = base_fname + "_" + readtype + ".junc" + + assert os.path.exists(type_sam_fname) and os.path.exists(type_junction_fname) + numreads = 0 + type_sam_file = open(type_sam_fname) + for line in type_sam_file: + numreads += 1 + type_sam_file.close() + if numreads <= 0: + continue + print >> sys.stderr, "%s\t%d" % (readtype, numreads) + + junctions, junctions_set = [], set() + type_junction_file = open(type_junction_fname) + for line in type_junction_file: + chr, left, right = line[:-1].split() + left, right = int(left), int(right) + junctions.append([chr, left, right]) + junctions_set.add(to_junction_str([chr, left, right])) + + type_junction_file.close() + + aligner_bin_base = "../../../aligners/bin" + def get_aligner_version(aligner, version): + version = "" + if aligner == "hisat2" or \ + aligner == "hisat" or \ + aligner == "bowtie" or \ + aligner == "bowtie2": + if version: + cmd = ["%s/%s_%s/%s" % (aligner_bin_base, aligner, version, aligner)] + else: + cmd = ["%s/%s" % (aligner_bin_base, aligner)] + cmd += ["--version"] + cmd_process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + version = cmd_process.communicate()[0][:-1].split("\n")[0] + version = version.split()[-1] + elif aligner == "tophat2": + cmd = ["%s/tophat" % (aligner_bin_base)] + cmd += ["--version"] + cmd_process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + version = cmd_process.communicate()[0][:-1].split()[-1] + elif aligner in ["star", "starx2"]: + version = "2.4.2a" + elif aligner == "gsnap": + cmd = ["%s/gsnap" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[0] + version = version.split()[2] + elif aligner == "bwa": + if version: + cmd = ["%s/bwa_%s/bwa" % (aligner_bin_base, version)] + else: + cmd = ["%s/bwa" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[2] + version = version.split()[1] + elif aligner == "vg": + cmd = ["%s/vg" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[0] + version = version.split()[5] + elif aligner == "minimap2": + cmd = ["%s/minimap2" % (aligner_bin_base)] + cmd += ["--version"] + cmd_process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + version = cmd_process.communicate()[0][:-1].split("\n")[0] + + return version + + index_base = "../../../indexes" + index_add = "" + if genome != "genome": + index_add = "_" + genome + def get_aligner_cmd(RNA, aligner, type, index_type, version, options, read1_fname, read2_fname, out_fname, cmd_idx = 0): + cmd = ["/usr/bin/time"] + if osx_mode: + cmd += ['-l'] + if aligner == "hisat2": + if version: + cmd += ["%s/hisat2_%s/hisat2" % (aligner_bin_base, version)] + else: + cmd += ["%s/hisat2" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["-f"] + # cmd += ["-k", "100"] + # cmd += ["--max-seeds", "100"] + # cmd += ["--score-min", "C,-100"] + # cmd += ["--pen-cansplice", "0"] + # cmd += ["--pen-noncansplice", "12"] + # cmd += ["--pen-intronlen", "G,-8,1"] + # cmd += ["--metrics", "1", + # "--metrics-file", "metrics.out"] + + if not RNA: + cmd += ["--no-spliced-alignment"] + + if type in ["x1", "x2"]: + cmd += ["--no-temp-splicesite"] + + # cmd += ["--no-anchorstop"] + if version == "" or \ + (version != "" and int(version) >= 210): + cmd += ["--new-summary", + "--summary-file", out_fname + ".summary"] + + if version == "" or int(version) >= 220: + cmd += ["--repeat"] + + # cmd += ["--dta"] + # cmd += ["--dta-cufflinks"] + + if options != "": + cmd += options.split(' ') + + if type == "x2": + if cmd_idx == 0: + cmd += ["--novel-splicesite-outfile"] + else: + cmd += ["--novel-splicesite-infile"] + cmd += ["splicesites.txt"] + + # "--novel-splicesite-infile", + # "../splicesites.txt", + # "--rna-strandness", + # "FR", + if version: + index_cmd = "%s/HISAT2_%s%s/" % (index_base, version, index_add) + genome + else: + index_cmd = "%s/HISAT2%s/" % (index_base, index_add) + genome + if index_type: + index_cmd += ("_" + index_type) + cmd += [index_cmd] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + + elif aligner == "hisat-TLA": + + if version: + cmd += ["%s/hisat2_%s/hisat2" % (aligner_bin_base, version)] + else: + cmd += ["%s/hisat2" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["-f"] + if not RNA: + cmd += ["--no-spliced-alignment"] + if type in ["x1", "x2"]: + cmd += ["--no-temp-splicesite"] + if version == "" or \ + (version != "" and int(version) >= 210): + cmd += ["--new-summary", + "--summary-file", out_fname + ".summary"] + if version == "" or int(version) >= 220: + cmd += ["--repeat"] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += ["-U", read1_fname] + + cmd += ["--TLA"] + cmd += ["--base-change"] + cmd += [baseChange] + cmd += ["--expand-repeat"] + + index1_cmd = "%s/HISAT2%s/" % (index_base, index_add) + genome + '_' + baseChange + if index_type: + index1_cmd += ("_" + index_type) + cmd += ["--index1"] + cmd += [index1_cmd] + + index2_cmd = "%s/HISAT2%s/" % (index_base, index_add) + genome + '_' + reverse_complement(baseChange[0]) + reverse_complement(baseChange[1]) + if index_type: + index2_cmd += ("_" + index_type) + cmd += ["--index2"] + cmd += [index2_cmd] + + cmd += ["--reference"] + cmd += ["../../../data/%s.fa" % genome] + + + + elif aligner == "hisat": + cmd += ["%s/hisat" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["-f"] + # cmd += ["-k", "5"] + # cmd += ["--score-min", "C,-18"] + if version != "": + version = int(version) + else: + version = sys.maxint + + if not RNA: + cmd += ["--no-spliced-alignment"] + + if type in ["x1", "x2"]: + cmd += ["--no-temp-splicesite"] + + """ + cmd += ["--rdg", "100,100", + "--rfg", "100,100"] + """ + + if type == "x2": + if cmd_idx == 0: + cmd += ["--novel-splicesite-outfile"] + else: + cmd += ["--novel-splicesite-infile"] + cmd += ["splicesites.txt"] + + # "--novel-splicesite-infile", + # "../splicesites.txt", + # "--rna-strandness", + # "FR", + cmd += ["%s/HISAT%s/" % (index_base, index_add) + genome] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "tophat2": + cmd += ["%s/tophat" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + if type.find("gtf") != -1: + cmd += ["--transcriptome-index=%s/HISAT%s/gtf/%s" % (index_base, index_add, genome)] + if type == "gtfonly": + cmd += ["--transcriptome-only"] + cmd += ["--read-edit-dist", "3"] + cmd += ["--no-sort-bam"] + cmd += ["--read-realign-edit-dist", "0"] + cmd += ["--keep-tmp", + "%s/HISAT%s/" % (index_base, index_add) + genome, + read1_fname] + if paired: + cmd += [read2_fname] + elif aligner == "star": + cmd += ["%s/STAR" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["--runThreadN", str(num_threads)] + cmd += ["--genomeDir"] + if cmd_idx == 0: + if type == "gtf": + cmd += ["%s/STAR%s/gtf" % (index_base, index_add)] + else: + cmd += ["%s/STAR%s" % (index_base, index_add)] + else: + assert cmd_idx == 1 + cmd += ["."] + + if desktop: + cmd += ["--genomeLoad", "NoSharedMemory"] + else: + cmd += ["--genomeLoad", "LoadAndKeep"] + if type == "x2": + if cmd_idx == 1: + cmd += ["--alignSJDBoverhangMin", "1"] + cmd += ["--readFilesIn", + read1_fname] + if paired: + cmd += [read2_fname] + if paired: + cmd += ["--outFilterMismatchNmax", "6"] + else: + cmd += ["--outFilterMismatchNmax", "3"] + elif aligner == "bowtie": + cmd += ["%s/bowtie" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["-f", + "--sam", + "-k", "10"] + cmd += ["-n", "3"] + if paired: + cmd += ["-X", "500"] + cmd += ["%s/Bowtie%s/" % (index_base, index_add) + genome] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "bowtie2": + if version: + cmd += ["%s/bowtie2_%s/bowtie2" % (aligner_bin_base, version)] + else: + cmd += ["%s/bowtie2" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["-f"] + if options != "": + cmd += options.split(' ') + if version: + cmd += ["-x %s/Bowtie2_%s%s/" % (index_base, version, index_add) + genome] + else: + cmd += ["-x %s/Bowtie2%s/" % (index_base, index_add) + genome] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "gsnap": + cmd += ["%s/gsnap" % (aligner_bin_base), + "-A", + "sam"] + if num_threads > 1: + cmd += ["-t", str(num_threads)] + cmd += ["--max-mismatches=3", + "-D", "%s/GSNAP%s" % (index_base, index_add), + "-N", "1", + "-d", genome, + read1_fname] + if paired: + cmd += [read2_fname] + elif aligner == "bwa": + if version: + cmd += ["%s/bwa_%s/bwa" % (aligner_bin_base, version)] + else: + cmd += ["%s/bwa" % (aligner_bin_base)] + if type in ["mem", "aln"]: + cmd += [type] + elif type == "sw": + cmd += ["bwa" + type] + if num_threads > 1: + cmd += ["-t", str(num_threads)] + if options != "": + cmd += options.split(' ') + # if paired: + # cmd += ["-T", "60"] + if version: + cmd += ["%s/BWA_%s%s/%s.fa" % (index_base, version, index_add, genome)] + else: + cmd += ["%s/BWA%s/%s.fa" % (index_base, index_add, genome)] + cmd += [read1_fname] + if paired: + cmd += [read2_fname] + elif aligner == "vg": + # vg map -d 22 -t 6 -M 10 -f ../sim-1.fa -f ../sim-2.fa > result.sam.gam + cmd += ["%s/vg" % (aligner_bin_base)] + cmd += ["map"] + cmd += ["-t", str(num_threads)] + cmd += ["--surject-to", "sam"] + index_cmd = "%s/VG%s/" % (index_base, index_add) + genome + if index_type: + index_cmd += ("_" + index_type) + + if options != "": + cmd += options.split(' ') + + cmd += ["-d", index_cmd] + + cmd += ["-f", read1_fname] + if paired: + cmd += ["-f", read2_fname] + elif aligner == "minimap2": + # minimap2 -a -x sr 22.mmi sim_1.fa sim_2.fa > result.sam + cmd += ["%s/minimap2" % (aligner_bin_base)] + cmd += ["-a"] + cmd += ["-x", "sr"] + index_cmd = "%s/minimap2%s/" % (index_base, index_add) + genome + if index_type: + index_cmd += ("_" + index_type) + index_cmd += ".mmi" + cmd += [index_cmd] + cmd += [read1_fname] + if paired: + cmd += [read2_fname] + else: + assert False + + return cmd + + for aligner, type, index_type, version, options in aligners: + skip = False + if len(test_aligners) > 0: + skip = True + for test_aligner in test_aligners: + if aligner == test_aligner: + skip = False + if skip: + continue + + aligner_name = aligner + type + if version != "": + aligner_name += ("_%s" % version) + if aligner == "hisat2" and index_type != "": + aligner_name += ("_" + index_type) + if aligner == "vg" and index_type != "": + aligner_name += ("_" + index_type) + + two_step = (aligner == "tophat2" or type == "x2" or (aligner in ["hisat2", "hisat"] and type == "")) + if RNA and readtype != "M": + if aligner in ["bowtie", "bowtie2", "bwa"]: + continue + if readtype != "all": + if two_step: + continue + if not RNA and readtype != "all": + continue + + print >> sys.stderr, "\t%s\t%s" % (aligner_name, str(datetime.now())) + if options != "": + option_name = options.replace(' ', '').replace('-', '').replace(',', '') + aligner_name = aligner_name + '_' + option_name + if paired: + aligner_dir = aligner_name + "_paired" + else: + aligner_dir = aligner_name + "_single" + + if fresh and os.path.exists(aligner_dir): + os.system("rm -rf %s" % aligner_dir) + + if not os.path.exists(aligner_dir): + os.mkdir(aligner_dir) + + os.chdir(aligner_dir) + + out_fname = base_fname + "_" + readtype + ".sam" + out_fname2 = out_fname + "2" + duration = -1.0 + mem_usage = '0' + if not os.path.exists(out_fname): + if not os.path.exists("../one.fa") or not os.path.exists("../two.fa"): + os.system("head -400 ../%s_1.fa > ../one.fa" % (data_base)) + os.system("head -400 ../%s_2.fa > ../two.fa" % (data_base)) + + if runtime_only: + out_fname = "/dev/null" + out_fname2 = "/dev/null" + + if not two_step: + align_stat.append([readtype, aligner_name]) + + # dummy commands for caching index and simulated reads + loading_time = 0 + if aligner != "tophat2": + for i in range(3): + dummy_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../one.fa", "../two.fa", "/dev/null") + start_time = datetime.now() + if verbose: + print >> sys.stderr, start_time, "\t", " ".join(dummy_cmd) + if aligner in ["hisat2", "hisat", "bowtie", "bowtie2", "gsnap", "bwa"]: + proc = subprocess.Popen(dummy_cmd, stdout=open("/dev/null", "w"), stderr=subprocess.PIPE) + else: + proc = subprocess.Popen(dummy_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc.communicate() + finish_time = datetime.now() + duration = finish_time - start_time + duration = duration.total_seconds() + if verbose: + print >> sys.stderr, finish_time, "duration:", duration + loading_time = duration + + # Align all reads + aligner_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../" + type_read1_fname, "../" + type_read2_fname, out_fname) + start_time = datetime.now() + if verbose: + print >> sys.stderr, "\t", start_time, " ".join(aligner_cmd) + if aligner in ["hisat2", "hisat", "bowtie", "bowtie2", "gsnap", "bwa", "vg", "minimap2", "hisat-TLA"]: + proc = subprocess.Popen(aligner_cmd, stdout=open(out_fname, "w"), stderr=subprocess.PIPE) + else: + proc = subprocess.Popen(aligner_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + _, mem_usage = proc.communicate() + mem_usage = parse_mem_usage(mem_usage) + finish_time = datetime.now() + duration = finish_time - start_time + duration = duration.total_seconds() - loading_time + if duration < 0.1: + duration = 0.1 + if verbose: + print >> sys.stderr, "\t", finish_time, "finished:", duration + + if debug and aligner == "hisat2": + os.system("cat metrics.out") + print >> sys.stderr, "\ttime: %.4f" % (duration) + + if aligner == "star" and type in ["", "gtf"]: + os.system("mv Aligned.out.sam %s" % out_fname) + elif aligner in ["hisat2", "hisat"] and type == "x2": + aligner_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../" + type_read1_fname, "../" + type_read2_fname, out_fname, 1) + start_time = datetime.now() + if verbose: + print >> sys.stderr, "\t", start_time, " ".join(aligner_cmd) + proc = subprocess.Popen(aligner_cmd, stdout=open(out_fname, "w"), stderr=subprocess.PIPE) + proc.communicate() + finish_time = datetime.now() + duration += (finish_time - start_time).total_seconds() + duration -= loading_time + if duration < 0.1: + duration = 0.1 + if verbose: + print >> sys.stderr, "\t", finish_time, "finished:", duration + elif aligner == "star" and type == "x2": + assert os.path.exists("SJ.out.tab") + os.system("awk 'BEGIN {OFS=\"\t\"; strChar[0]=\".\"; strChar[1]=\"+\"; strChar[2]=\"-\";} {if($5>0){print $1,$2,$3,strChar[$4]}}' SJ.out.tab > SJ.out.tab.Pass1.sjdb") + for file in os.listdir("."): + if file in ["SJ.out.tab.Pass1.sjdb", "genome.fa"]: + continue + os.remove(file) + star_index_cmd = "%s/STAR --genomeDir ./ --runMode genomeGenerate --genomeFastaFiles ../../../data/%s.fa --sjdbFileChrStartEnd SJ.out.tab.Pass1.sjdb --sjdbOverhang 99 --runThreadN %d" % (aligner_bin_base, genome, num_threads) + if verbose: + print >> sys.stderr, "\t", datetime.now(), star_index_cmd + os.system(star_index_cmd) + if verbose: + print >> sys.stderr, "\t", datetime.now(), " ".join(dummy_cmd) + proc = subprocess.Popen(dummy_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc.communicate() + if verbose: + print >> sys.stderr, "\t", datetime.now(), "finished" + aligner_cmd = get_aligner_cmd(RNA, aligner, type, index_type, version, options, "../" + type_read1_fname, "../" + type_read2_fname, out_fname, 1) + start_time = datetime.now() + if verbose: + print >> sys.stderr, "\t", start_time, " ".join(aligner_cmd) + proc = subprocess.Popen(aligner_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc.communicate() + finish_time = datetime.now() + duration += (finish_time - start_time).total_seconds() + duration -= loading_time + if duration < 0.1: + duration = 0.1 + if verbose: + print >> sys.stderr, "\t", finish_time, "finished:", duration + os.system("mv Aligned.out.sam %s" % out_fname) + elif aligner == "tophat2": + os.system("samtools sort -n tophat_out/accepted_hits.bam accepted_hits; samtools view -h accepted_hits.bam > %s" % out_fname) + elif aligner == "vg": + index_name = "%s/VG%s/" % (index_base, index_add) + genome + if index_type: + index_name += ("_" + index_type) + + if aligner in ["gsnap", "tophat2"]: + os.system("tar cvzf %s.tar.gz %s &> /dev/null" % (out_fname, out_fname)) + + if runtime_only: + print >> sys.stderr, "\t\t\tMemory Usage: %dMB" % (int(mem_usage) / 1024) + os.chdir("..") + continue + + if not os.path.exists(out_fname2): + debug_dic = {} + pid_list = [] + if paired: + if mp_mode: + for i in xrange(mp_num): + p = Process(target=extract_pair, args=(out_fname, out_fname2, chr_dic, RNA, aligner, version, repeat_db, repeat_map, debug_dic, i)) + pid_list.append(p) + p.start() + + for p in pid_list: + p.join() + + # merge + os.system("mv %s %s" % (out_fname2 + ".0", out_fname2)) + for i in xrange(1, mp_num): + os.system("cat %s >> %s" % (out_fname2 + "." + str(i), out_fname2)) + os.system("rm %s" % (out_fname2 + "." + str(i))) + + else: + extract_pair(out_fname, out_fname2, chr_dic, RNA, aligner, version, repeat_db, repeat_map, debug_dic, -1) + + + else: + if mp_mode: + # Prepare queues + for i in xrange(mp_num): + p = Process(target=extract_single, args=(out_fname, out_fname2, chr_dic, aligner, version, repeat_db, repeat_map, debug_dic, i)) + pid_list.append(p) + p.start() + + # wait + for p in pid_list: + p.join() + + # merge + os.system("mv %s %s" % (out_fname2 + ".0", out_fname2)) + for i in xrange(1, mp_num): + os.system("cat %s >> %s" % (out_fname2 + "." + str(i), out_fname2)) + os.system("rm %s" % (out_fname2 + "." + str(i))) + + else: + extract_single(out_fname, out_fname2, chr_dic, aligner, version, repeat_db, repeat_map, debug_dic, -1) + + for readtype2 in readtypes: + if not two_step and readtype != readtype2: + continue + + type_sam_fname2 = base_fname + "_" + readtype2 + ".sam" + if os.path.exists(type_sam_fname2 + ".done"): + continue + + if paired: + type_read_fname2 = base_fname + "_1_" + readtype2 + ".fa" + else: + type_read_fname2 = base_fname + "_" + readtype2 + ".fa" + mapped_id_fname = base_fname + "_" + readtype2 + ".read_id" + if paired: + mapped, unique_mapped, first_mapped, unmapped, aligned, multi_aligned, \ + snp_mapped, snp_unique_mapped, snp_first_mapped, snp_unmapped, \ + temp_junctions, temp_gtf_junctions, mapping_point \ + = compare_paired_sam(RNA, out_fname2, "../" + type_sam_fname2, mapped_id_fname, chr_dic, junctions, junctions_set, gtf_junctions, aligner) + else: + mapped, unique_mapped, first_mapped, unmapped, aligned, multi_aligned, \ + snp_mapped, snp_unique_mapped, snp_first_mapped, snp_unmapped, \ + temp_junctions, temp_gtf_junctions, mapping_point \ + = compare_single_sam(RNA, out_fname2, "../" + type_sam_fname2, mapped_id_fname, chr_dic, junctions, junctions_set, gtf_junctions, aligner) + proc = subprocess.Popen(["wc", "-l", "../" + type_read_fname2], stdout=subprocess.PIPE) + out = proc.communicate()[0] + numreads = int(out.split()[0]) / 2 + assert mapped + unmapped == numreads + + if two_step: + print >> sys.stderr, "\t\t%s" % readtype2 + print >> sys.stderr, "\t\taligned: %d, multi aligned: %d" % (aligned, multi_aligned) + print >> sys.stderr, "\t\tcorrectly mapped: %d (%.2f%%) mapping_point: %.2f" % (mapped, float(mapped) * 100.0 / numreads, mapping_point * 100.0 / numreads) + print >> sys.stderr, "\t\tcorrectly mapped at first: %d (%.2f%%)" % (first_mapped, float(first_mapped) * 100.0 / numreads) + print >> sys.stderr, "\t\tuniquely and correctly mapped: %d (%.2f%%)" % (unique_mapped, float(unique_mapped) * 100.0 / numreads) + snp_numreads = snp_mapped + snp_unmapped + if snp_numreads > 0: + print >> sys.stderr, "\t\t\t\tSNP: reads: %d" % (snp_numreads) + print >> sys.stderr, "\t\t\t\tSNP: correctly mapped: %d (%.2f%%)" % (snp_mapped, float(snp_mapped) * 100.0 / snp_numreads) + print >> sys.stderr, "\t\t\t\tSNP: correctly mapped at first: %d (%.2f%%)" % (snp_first_mapped, float(snp_first_mapped) * 100.0 / snp_numreads) + print >> sys.stderr, "\t\t\t\tSNP: uniquely and correctly mapped: %d (%.2f%%)" % (snp_unique_mapped, float(snp_unique_mapped) * 100.0 / snp_numreads) + if readtype == readtype2: + print >> sys.stderr, "\t\t\t%d reads per sec (all)" % (numreads / max(1.0, duration)) + if RNA: + print >> sys.stderr, "\t\tjunc. sensitivity %d / %d (%.2f%%), junc. accuracy: %d / %d (%.2f%%)" % \ + (temp_gtf_junctions, len(junctions), float(temp_gtf_junctions) * 100.0 / max(1, len(junctions)), \ + temp_gtf_junctions, temp_junctions, float(temp_gtf_junctions) * 100.0 / max(1, temp_junctions)) + + print >> sys.stderr, "\t\t\tMemory Usage: %dMB" % (int(mem_usage) / 1024) + + if duration > 0.0: + if sql_write and os.path.exists("../" + sql_db_name): + if paired: + end_type = "paired" + else: + end_type = "single" + + mem_used = int(mem_usage) / 1024 + sql_insert = "INSERT INTO \"ReadCosts\" VALUES(NULL, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %f, %f, %d, %d, %d, %d, %d, %d, %d, '%s', datetime('now', 'localtime'), '%s');" % \ + (genome, data_base, end_type, readtype2, aligner_name, get_aligner_version(aligner, version), numreads, mapped, unique_mapped, unmapped, mapping_point, snp_mapped, snp_unique_mapped, snp_unmapped, duration, mem_used, len(junctions), temp_junctions, temp_gtf_junctions, platform.node(), " ".join(aligner_cmd)) + sql_execute("../" + sql_db_name, sql_insert) + + if two_step: + align_stat.append([readtype2, aligner_name, numreads, duration, mem_used, mapped, unique_mapped, unmapped, mapping_point, snp_mapped, snp_unique_mapped, snp_unmapped, len(junctions), temp_junctions, temp_gtf_junctions]) + else: + align_stat[-1].extend([numreads, duration, mem_used, mapped, unique_mapped, unmapped, mapping_point, snp_mapped, snp_unique_mapped, snp_unmapped, len(junctions), temp_junctions, temp_gtf_junctions]) + + os.system("touch %s.done" % type_sam_fname2) + + os.chdir("..") + + print >> sys.stdout, "\t".join(["type", "aligner", "all", "all_time", "mem", "mapped", "unique_mapped", "unmapped", "mapping point", "snp_mapped", "snp_unique_mapped", "snp_unmapped", "true_gtf_junctions", "temp_junctions", "temp_gtf_junctions"]) + for line in align_stat: + outstr = "" + for item in line: + if outstr != "": + outstr += "\t" + outstr += str(item) + print >> sys.stdout, outstr + + if os.path.exists(sql_db_name): + write_analysis_data(sql_db_name, genome, data_base) + + + +""" +""" +if __name__ == "__main__": + parser = ArgumentParser( + description='test HISAT2, and compare HISAT2 with other popular aligners such as TopHat2, STAR, Bowtie1/2, GSNAP, BWA-mem, etc.') + parser.add_argument('--single-end', + dest='paired_end', + action='store_false', + help='run single-end only') + parser.add_argument('--paired-end', + dest='single_end', + action='store_false', + help='run paired_end only') + parser.add_argument('--aligner-list', + dest='aligner_list', + type=str, + default="", + help='comma-separated list of aligners (e.g. hisat2,bowtie2,bwa') + parser.add_argument('--fresh', + dest='fresh', + action='store_true', + help='delete existing alignment related directories (e.g. hisat2_single)') + parser.add_argument('--runtime-only', '--runtime', + dest='runtime_only', + action='store_true', + help='run programs without evaluation') + parser.add_argument('-p', '--multi-process', + dest='mp_num', + action='store', + type=int, + default=1, + help='Use multiple process mode') + parser.add_argument('--base-change', + dest='baseChange', + type=str, + default="", + help='base change for Hisat-TLA') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + + args = parser.parse_args() + + aligners = [] + for aligner in args.aligner_list.split(','): + if aligner == "": + continue + aligners.append(aligner) + + mp_num = args.mp_num + mp_mode = (mp_num > 1) + + calculate_read_cost(args.single_end, + args.paired_end, + aligners, + args.fresh, + args.runtime_only, + args.baseChange, + args.verbose) diff --git a/evaluation/simulation/init.py b/evaluation/simulation/init.py new file mode 100644 index 0000000..aa7b3f8 --- /dev/null +++ b/evaluation/simulation/init.py @@ -0,0 +1,343 @@ +#!/usr/bin/env python + +import sys, os +import string, re + +use_message = ''' +''' + +def extract_pair(RNA): + read_dic = {} + pair_reported = set() + + out_file = open("sim_paired.sam", "w") + hits_file = open("sim.sam") + for line in hits_file: + if line.startswith('@'): + continue + + fields = line[:-1].split() + read_id, flag, chr1, pos1, mapQ, cigar1, chr2, pos2 = fields[:8] + + flag = int(flag) + assert flag & 0x4 == 0 + pos1, pos2 = int(pos1), int(pos2) + + TI, NM1, Zs1 = "", "", "" + for field in fields[11:]: + if field.startswith("TI"): + TI = "\t" + field + elif field.startswith("NM"): + NM1 = "\t" + field + elif field.startswith("Zs"): + Zs1 = "\t" + field + assert NM1 != "" + assert chr1 == chr2 + + me = "%s\t%s\t%d" % (read_id, chr1, pos1) + partner = "%s\t%s\t%d" % (read_id, chr2, pos2) + if partner in read_dic: + maps = read_dic[partner] + for map in maps: + if map[0] == me: + cigar2, NM2, Zs2 = map[1:4] + if int(pos2) > int(pos1): + p_str = "%s\t%s\t%d\t%s\t%s\t%d\t%s%s%s%s%s%s" % \ + (read_id, chr1, pos1, cigar1, chr2, pos2, cigar2, TI, NM1, NM2, Zs1, Zs2) + else: + p_str = "%s\t%s\t%d\t%s\t%s\t%d\t%s%s%s%s%s%s" % \ + (read_id, chr2, pos2, cigar2, chr1, pos1, cigar1, TI, NM2, NM1, Zs2, Zs1) + + if p_str not in pair_reported: + pair_reported.add(p_str) + print >> out_file, p_str + + if not me in read_dic: + read_dic[me] = [] + + read_dic[me].append([partner, cigar1, NM1, Zs1]) + + + hits_file.close() + out_file.close() + + +def init_reads(read_dir, RNA): + sim1_file = open("sim_1.sam", 'w') + sim2_file = open("sim_2.sam", 'w') + + for line in open("sim.sam"): + if line.startswith('@'): + continue + + fields = line[:-1].split('\t') + read_id, flag, chr, pos, _, cigar = fields[:6] + left_read = int(flag) < 128 + + NM, TI, Zs = "", "", "" + for field in fields: + if field.startswith("NM"): + NM = "\t" + field + elif field.startswith("TI"): + TI = "\t" + field + elif field.startswith("Zs"): + Zs = "\t" + field + + print >> (sim1_file if left_read else sim2_file), \ + "%s\t%s\t%s\t%s%s%s%s" % (read_id, chr, pos, cigar, TI, NM, Zs) + + sim1_file.close() + sim2_file.close() + extract_pair(RNA) + + +def to_junction_str(junction): + return "%s-%d-%d" % (junction[0], junction[1], junction[2]) + +def to_junction(junction_str): + fields = junction_str.split("-") + if len(fields) > 3: + chr, left, right = "-".join(fields[:-2]), fields[-2], fields[-1] + else: + assert len(fields) == 3 + chr, left, right = fields + + return [chr, int(left), int(right)] + +def junction_cmp(a, b): + if a[0] != b[0]: + if a[0] < b[0]: + return -1 + else: + return 1 + + if a[1] != b[1]: + if a[1] < b[1]: + return -1 + else: + return 1 + + if a[2] != b[2]: + if a[2] < b[2]: + return -1 + else: + return 1 + + return 0 + +def classify_reads(RNA): + if RNA: + readtypes = ["all", "M", "2M_gt_15", "2M_8_15", "2M_1_7", "gt_2M"] + else: + readtypes = ["all" ,"M"] + + readtype_order = {} + for i in range(len(readtypes)): + readtype = readtypes[i] + assert readtype not in readtype_order + readtype_order[readtype] = i + + for paired in [False, True]: + for readtype in readtypes: + if paired: + base_fname = "sim_paired" + type_sam_fname = base_fname + "_" + readtype + ".sam" + type_read1_fname = base_fname + "_1_" + readtype + ".fa" + type_read2_fname = base_fname + "_2_" + readtype + ".fa" + type_junction_fname = base_fname + "_" + readtype + ".junc" + else: + base_fname = "sim_single" + type_sam_fname = base_fname + "_" + readtype + ".sam" + type_read1_fname = base_fname + "_" + readtype + ".fa" + type_read2_fname = "" + type_junction_fname = base_fname + "_" + readtype + ".junc" + + if os.path.exists(type_sam_fname) and \ + os.path.exists(type_junction_fname): + continue + + read_ids = set() + junctions = [] + type_sam_file = open(type_sam_fname, "w") + if paired: + sam_file = open("sim_paired.sam") + else: + sam_file = open("sim_1.sam") + + cigar_re = re.compile('\d+\w') + def get_read_type(cigar): + cigars = cigar_re.findall(cigar) + + def get_cigar_chars_MN(cigars): + cigars = cigar_re.findall(cigars) + cigar_chars = "" + for cigar in cigars: + cigar_op = cigar[-1] + if cigar_op in "MN": + if cigar_chars == "" or cigar_chars[-1] != cigar_op: + cigar_chars += cigar_op + + return cigar_chars + + cigar_str = get_cigar_chars_MN(cigar) + if cigar_str == "M": + return cigar_str + elif cigar_str == "MNM": + assert len(cigars) >= 3 + left_anchor = 0 + for ci in range(len(cigars)): + c = cigars[ci][-1] + c_len = int(cigars[ci][:-1]) + if c in "MI": + left_anchor += c_len + else: + break + assert left_anchor > 0 + right_anchor = 0 + for ci in reversed(range(len(cigars))): + c = cigars[ci][-1] + c_len = int(cigars[ci][:-1]) + if c in "MI": + right_anchor += c_len + else: + break + assert right_anchor > 0 + min_anchor = min(left_anchor, right_anchor) + if min_anchor > 15: + return "2M_gt_15" + elif min_anchor >= 8 and min_anchor <= 15: + return "2M_8_15" + elif min_anchor >= 1 and min_anchor <= 7: + return "2M_1_7" + else: + assert False + else: + assert cigar_str not in ["M", "MNM"] + return "gt_2M" + + # chr and pos are assumed to be integers + def get_junctions(chr, pos, cigar_str): + junctions = [] + right_pos = pos + cigars = cigar_re.findall(cigar_str) + cigars = [[int(cigars[i][:-1]), cigars[i][-1]] for i in range(len(cigars))] + for i in range(len(cigars)): + length, cigar_op = cigars[i] + if cigar_op == "N": + left, right = right_pos - 1, right_pos + length + + if i > 0 and cigars[i-1][1] in "ID": + if cigars[i-1][1] == "I": + left += cigars[i-1][0] + else: + left -= cigars[i-1][0] + if i + 1 < len(cigars) and cigars[i+1][1] in "ID": + if cigars[i+1][1] == "I": + right -= cigars[i+1][0] + else: + right += cigars[i+1][0] + + junctions.append([chr, left, right]) + + if cigar_op in "MND": + right_pos += length + + return junctions + + for line in sam_file: + fields = line[:-1].split() + if paired: + read_id, chr, pos, cigar, chr2, pos2, cigar2 = fields[:7] + else: + read_id, chr, pos, cigar = fields[:4] + + read_id = int(read_id) + readtype2 = get_read_type(cigar) + if paired: + readtype3 = get_read_type(cigar2) + assert readtype2 in readtype_order + assert readtype3 in readtype_order + if readtype_order[readtype2] < readtype_order[readtype3]: + readtype2 = readtype3 + + if readtype == "all" or readtype == readtype2: + read_ids.add(read_id) + print >> type_sam_file, line[:-1] + junctions += get_junctions(chr, int(pos), cigar) + if paired: + junctions += get_junctions(chr2, int(pos2), cigar2) + + sam_file.close() + type_sam_file.close() + + # make this set non-redundant + junction_set = set() + for junction in junctions: + junction_set.add(to_junction_str(junction)) + + junctions = [] + for junction_str in junction_set: + junctions.append(to_junction(junction_str)) + + # sort the list of junctions + junctions = sorted(junctions, cmp=junction_cmp) + + # write the junctions into a file + type_junction_file = open(type_junction_fname, "w") + for junction in junctions: + print >> type_junction_file, "%s\t%d\t%d" % (junction[0], junction[1], junction[2]) + type_junction_file.close() + + def write_reads(read_fname, type_read_fname): + type_read_file = open(type_read_fname, "w") + read_file = open(read_fname) + + write = False + for line in read_file: + if line[0] == ">": + read_id = int(line[1:-1]) + write = read_id in read_ids + + if write: + print >> type_read_file, line[:-1] + + read_file.close() + type_read_file.close() + + if paired: + write_reads("sim_1.fa", type_read1_fname) + write_reads("sim_2.fa", type_read2_fname) + else: + write_reads("sim_1.fa", type_read1_fname) + + +def init(): + read_dir_base = "../reads/simulation/" + read_dirs = os.listdir(read_dir_base) + for read_dir in read_dirs: + if os.path.exists(read_dir): + continue + + if not os.path.exists(read_dir_base + read_dir + "/sim.sam") or \ + not os.path.exists(read_dir_base + read_dir + "/sim_1.fa") or \ + not os.path.exists(read_dir_base + read_dir + "/sim_2.fa"): + continue + + print >> sys.stderr, "Processing", read_dir, "..." + + os.mkdir(read_dir) + os.chdir(read_dir) + os.system("ln -s ../%s%s/* ." % (read_dir_base, read_dir)) + os.system("ln -s sim_1.fa 1.fa") + os.system("ln -s sim_2.fa 2.fa") + + RNA = (read_dir.find("RNA") != -1) + init_reads(read_dir, RNA) + classify_reads(RNA) + os.system("ln -s ../calculate_read_cost.py .") + + os.chdir("..") + + +if __name__ == "__main__": + init() diff --git a/evaluation/tests/CODIS/README b/evaluation/tests/CODIS/README new file mode 100644 index 0000000..eac41f7 --- /dev/null +++ b/evaluation/tests/CODIS/README @@ -0,0 +1,21 @@ +To extract HLA alleles and variants + + ./hisatgenotype_extract_vars.py --base codis --inter-gap 30 --intra-gap 50 --min-var-freq 0.1 + ./hisatgenotype_extract_vars.py --base hla --locus-list A --inter-gap 30 --intra-gap 50 --min-var-freq 0.1 + + +To build genotype genome + + ./hisatgenotype_build_genome.py genome.fa genotype_genome -p 3 --verbose + + +For DNA fingerprinting + ./hisatgenotype_locus.py --verbose --base codis --locus-list D13S317 --fragment-len 200 --no-assembly --debug paired + + + +To run HISAT-genotype + ./hisatgenotype_locus.py --base hla --locus-list A --simulate-interval 10 --perbase-errorrate 0.3 --perbase-snprate 0.1 --num-editdist 2 --debug paired + + for i in `ls -l ILMN/NA128*1.fq.gz | awk '{print $NF}' | cut -d'/' -f2 | cut -d'.' -f1`; do echo $i; ./hisatgenotype_locus.py --locus-list A --aligner-list hisat2.graph --num-editdist 2 --reads ILMN/$i.extracted.1.fq.gz,ILMN/$i.extracted.2.fq.gz --assembly-base assembly_graph_$i 2> $i.tmp; done + diff --git a/evaluation/tests/CODIS/genome.fa b/evaluation/tests/CODIS/genome.fa new file mode 100644 index 0000000..56c0aad --- /dev/null +++ b/evaluation/tests/CODIS/genome.fa @@ -0,0 +1 @@ +../HLA_novel/genome.fa \ No newline at end of file diff --git a/evaluation/tests/CODIS/genome.fa.fai b/evaluation/tests/CODIS/genome.fa.fai new file mode 100644 index 0000000..b332dba --- /dev/null +++ b/evaluation/tests/CODIS/genome.fa.fai @@ -0,0 +1 @@ +../HLA_novel/genome.fa.fai \ No newline at end of file diff --git a/evaluation/tests/CODIS/grch38 b/evaluation/tests/CODIS/grch38 new file mode 100644 index 0000000..ebe18e1 --- /dev/null +++ b/evaluation/tests/CODIS/grch38 @@ -0,0 +1 @@ +../HLA_novel/grch38 \ No newline at end of file diff --git a/evaluation/tests/CODIS/hisatgenotype_convert_codis.py b/evaluation/tests/CODIS/hisatgenotype_convert_codis.py new file mode 100644 index 0000000..99ea92b --- /dev/null +++ b/evaluation/tests/CODIS/hisatgenotype_convert_codis.py @@ -0,0 +1 @@ +hisatgenotype_modules/hisatgenotype_convert_codis.py \ No newline at end of file diff --git a/evaluation/tests/CODIS/hisatgenotype_extract_codis_data.py b/evaluation/tests/CODIS/hisatgenotype_extract_codis_data.py new file mode 100644 index 0000000..b586a7b --- /dev/null +++ b/evaluation/tests/CODIS/hisatgenotype_extract_codis_data.py @@ -0,0 +1 @@ +hisatgenotype_modules/hisatgenotype_extract_codis_data.py \ No newline at end of file diff --git a/evaluation/tests/CODIS/hisatgenotype_extract_vars.py b/evaluation/tests/CODIS/hisatgenotype_extract_vars.py new file mode 100644 index 0000000..6d113b3 --- /dev/null +++ b/evaluation/tests/CODIS/hisatgenotype_extract_vars.py @@ -0,0 +1 @@ +../../../hisatgenotype_extract_vars.py \ No newline at end of file diff --git a/evaluation/tests/CODIS/hisatgenotype_locus.py b/evaluation/tests/CODIS/hisatgenotype_locus.py new file mode 100644 index 0000000..c6bcacb --- /dev/null +++ b/evaluation/tests/CODIS/hisatgenotype_locus.py @@ -0,0 +1 @@ +../../../hisatgenotype_locus.py \ No newline at end of file diff --git a/evaluation/tests/CODIS/hisatgenotype_modules b/evaluation/tests/CODIS/hisatgenotype_modules new file mode 100644 index 0000000..018d309 --- /dev/null +++ b/evaluation/tests/CODIS/hisatgenotype_modules @@ -0,0 +1 @@ +../../../hisatgenotype_modules \ No newline at end of file diff --git a/evaluation/tests/CYP/hisatgenotype_extract_vars.py b/evaluation/tests/CYP/hisatgenotype_extract_vars.py new file mode 100644 index 0000000..6d113b3 --- /dev/null +++ b/evaluation/tests/CYP/hisatgenotype_extract_vars.py @@ -0,0 +1 @@ +../../../hisatgenotype_extract_vars.py \ No newline at end of file diff --git a/evaluation/tests/CYP/hisatgenotype_locus.py b/evaluation/tests/CYP/hisatgenotype_locus.py new file mode 100644 index 0000000..c6bcacb --- /dev/null +++ b/evaluation/tests/CYP/hisatgenotype_locus.py @@ -0,0 +1 @@ +../../../hisatgenotype_locus.py \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/ILMN_StrandSeq/README b/evaluation/tests/HLA_novel/ILMN_StrandSeq/README new file mode 100644 index 0000000..7121782 --- /dev/null +++ b/evaluation/tests/HLA_novel/ILMN_StrandSeq/README @@ -0,0 +1 @@ +../ILMN_StrandSeq_original/README \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/ILMN_StrandSeq/SraRunInfo.txt b/evaluation/tests/HLA_novel/ILMN_StrandSeq/SraRunInfo.txt new file mode 100644 index 0000000..9b3f785 --- /dev/null +++ b/evaluation/tests/HLA_novel/ILMN_StrandSeq/SraRunInfo.txt @@ -0,0 +1 @@ +../ILMN_StrandSeq_original/SraRunInfo.txt \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/ILMN_StrandSeq_original/README b/evaluation/tests/HLA_novel/ILMN_StrandSeq_original/README new file mode 100644 index 0000000..c2cc2b1 --- /dev/null +++ b/evaluation/tests/HLA_novel/ILMN_StrandSeq_original/README @@ -0,0 +1,8 @@ +Download SRA reads in the FASTQ format + for i in `awk '{if(NR != 1) print $4}' SraRunInfo.txt`; do fastq-dump --gzip $i; done + + +for i in `ls *.gz`; do echo $i; ../../../../hisat2 --no-hd -x ../hla.graph -U $i --max-altstried 64 2> /dev/null | grep "A\*B" >> temp; done + +scripts/get_haplotype_ILMN_StrandSeq.py ILMN_StrandSeq/SraRunInfo.txt ILMN_StrandSeq/temp + diff --git a/evaluation/tests/HLA_novel/ILMN_StrandSeq_original/SraRunInfo.txt b/evaluation/tests/HLA_novel/ILMN_StrandSeq_original/SraRunInfo.txt new file mode 100644 index 0000000..1b4a860 --- /dev/null +++ b/evaluation/tests/HLA_novel/ILMN_StrandSeq_original/SraRunInfo.txt @@ -0,0 +1,305 @@ +Run spots bases download_path SampleName Sex +ERR1429624 454580 23183580 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429624 NA12892 female +ERR1429625 1164337 59381187 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429625 NA12892 female +ERR1429626 446404 22766604 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429626 NA12892 female +ERR1429627 1178769 60117219 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429627 NA12892 female +ERR1429628 422539 21549489 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429628 NA12892 female +ERR1429629 1158071 59061621 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429629 NA12892 female +ERR1429630 1033423 52704573 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429630 NA12892 female +ERR1429631 661547 33738897 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429631 NA12892 female +ERR1429632 764557 38992407 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429632 NA12892 female +ERR1429633 654774 33393474 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429633 NA12892 female +ERR1429634 653700 33338700 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429634 NA12892 female +ERR1429635 387115 19742865 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429635 NA12892 female +ERR1429636 602942 30750042 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429636 NA12892 female +ERR1429637 416442 21238542 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429637 NA12892 female +ERR1429638 361789 18451239 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429638 NA12892 female +ERR1429639 445019 22695969 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429639 NA12892 female +ERR1429640 655382 33424482 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429640 NA12892 female +ERR1429641 502098 25606998 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429641 NA12892 female +ERR1429642 442140 22549140 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429642 NA12892 female +ERR1429643 589718 30075618 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429643 NA12892 female +ERR1429644 336049 17138499 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429644 NA12892 female +ERR1429645 369398 18839298 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429645 NA12892 female +ERR1429646 575850 29368350 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429646 NA12892 female +ERR1429647 413988 21113388 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429647 NA12892 female +ERR1429648 687172 35045772 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429648 NA12892 female +ERR1429649 675486 34449786 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429649 NA12892 female +ERR1429650 683774 34872474 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429650 NA12892 female +ERR1429651 527860 26920860 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429651 NA12892 female +ERR1429652 363994 18563694 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429652 NA12892 female +ERR1429653 485829 24777279 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429653 NA12892 female +ERR1429654 404689 20639139 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429654 NA12892 female +ERR1429655 628956 32076756 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429655 NA12892 female +ERR1429656 443843 22635993 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429656 NA12892 female +ERR1429657 507127 25863477 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429657 NA12892 female +ERR1429658 548507 27973857 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429658 NA12892 female +ERR1429659 682499 34807449 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429659 NA12892 female +ERR1429660 414572 21143172 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429660 NA12892 female +ERR1429661 425025 21676275 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429661 NA12892 female +ERR1429662 371171 18929721 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429662 NA12892 female +ERR1429663 1092760 55730760 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429663 NA12892 female +ERR1429664 651261 33214311 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429664 NA12892 female +ERR1429665 643455 32816205 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429665 NA12892 female +ERR1429666 657058 33509958 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429666 NA12892 female +ERR1429667 527528 26903928 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429667 NA12892 female +ERR1429668 941433 48013083 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429668 NA12892 female +ERR1429669 635537 32412387 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429669 NA12892 female +ERR1429670 493285 25157535 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429670 NA12892 female +ERR1429671 1280258 65293158 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429671 NA12892 female +ERR1429672 1765271 90028821 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429672 NA12892 female +ERR1429673 936702 47771802 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429673 NA12892 female +ERR1429674 876200 44686200 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429674 NA12892 female +ERR1429675 1407029 71758479 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429675 NA12892 female +ERR1429676 1703380 86872380 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429676 NA12892 female +ERR1429677 1207785 61597035 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429677 NA12892 female +ERR1429678 1061830 54153330 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429678 NA12892 female +ERR1429679 1669149 85126599 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429679 NA12892 female +ERR1429680 1476448 75298848 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429680 NA12892 female +ERR1429681 1020002 52020102 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429681 NA12892 female +ERR1429682 1356679 69190629 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429682 NA12892 female +ERR1429683 915946 46713246 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429683 NA12892 female +ERR1429684 1045332 53311932 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429684 NA12892 female +ERR1429685 1525162 77783262 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429685 NA12892 female +ERR1429686 471194 24030894 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429686 NA12892 female +ERR1429687 1491856 76084656 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429687 NA12892 female +ERR1429688 824709 42060159 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429688 NA12892 female +ERR1429689 1112300 56727300 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429689 NA12892 female +ERR1429690 874610 44605110 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429690 NA12892 female +ERR1429691 697710 35583210 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429691 NA12892 female +ERR1429692 582636 29714436 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429692 NA12892 female +ERR1429693 761870 38855370 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429693 NA12892 female +ERR1429694 616775 31455525 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429694 NA12892 female +ERR1429695 680648 34713048 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429695 NA12892 female +ERR1429696 557253 28419903 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429696 NA12892 female +ERR1429697 456232 23267832 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429697 NA12892 female +ERR1429698 1494318 76210218 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429698 NA12892 female +ERR1429699 738330 37654830 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429699 NA12892 female +ERR1429700 1328177 67737027 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429700 NA12892 female +ERR1429701 741532 37818132 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429701 NA12892 female +ERR1429702 1061965 54160215 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429702 NA12892 female +ERR1429703 378981 19328031 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429703 NA12892 female +ERR1429704 1117620 56998620 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429704 NA12892 female +ERR1429705 1124119 57330069 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429705 NA12892 female +ERR1429706 1339802 68329902 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429706 NA12892 female +ERR1429707 2385699 121670649 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429707 NA12892 female +ERR1429708 833880 42527880 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429708 NA12892 female +ERR1429709 745854 38038554 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429709 NA12892 female +ERR1429710 753263 38416413 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429710 NA12892 female +ERR1429711 535518 27311418 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429711 NA12892 female +ERR1429712 1299967 66298317 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429712 NA12892 female +ERR1429713 899645 45881895 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429713 NA12892 female +ERR1429714 739975 37738725 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429714 NA12892 female +ERR1429715 1477561 75355611 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429715 NA12892 female +ERR1429716 1411260 71974260 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429716 NA12892 female +ERR1429717 1461893 74556543 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429717 NA12892 female +ERR1429718 1167396 59537196 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429718 NA12892 female +ERR1429719 455539 23232489 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429719 NA12892 female +ERR1429720 691972 35290572 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429720 NA12892 female +ERR1429721 1767814 90158514 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429721 NA12892 female +ERR1429722 1089325 55555575 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429722 NA12892 female +ERR1429723 1241483 63315633 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429723 NA12892 female +ERR1429524 714521 36440571 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429524 NA12892 female +ERR1429525 512294 26126994 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429525 NA12892 female +ERR1429526 600138 30607038 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429526 NA12892 female +ERR1429527 1026295 52341045 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429527 NA12892 female +ERR1429528 485027 24736377 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429528 NA12892 female +ERR1429529 610595 31140345 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429529 NA12892 female +ERR1429530 634235 32345985 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429530 NA12892 female +ERR1429531 588103 29993253 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429531 NA12892 female +ERR1429532 2161798 110251698 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429532 NA12892 female +ERR1429533 2008655 102441405 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429533 NA12892 female +ERR1429534 2299802 117289902 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429534 NA12892 female +ERR1429535 1667191 85026741 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429535 NA12892 female +ERR1429536 1515614 77296314 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429536 NA12892 female +ERR1429537 1800878 91844778 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429537 NA12892 female +ERR1429538 1883585 96062835 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429538 NA12892 female +ERR1429539 1390662 70923762 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429539 NA12892 female +ERR1429540 1636297 83451147 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429540 NA12892 female +ERR1429541 1547471 78921021 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429541 NA12892 female +ERR1429542 1306043 66608193 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429542 NA12892 female +ERR1429543 1545983 78845133 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429543 NA12892 female +ERR1429544 1346888 68691288 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429544 NA12892 female +ERR1429545 1672037 85273887 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429545 NA12892 female +ERR1429546 1182992 60332592 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429546 NA12892 female +ERR1429547 1110020 56611020 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429547 NA12892 female +ERR1429548 673901 34368951 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429548 NA12892 female +ERR1429549 418115 21323865 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429549 NA12892 female +ERR1429550 700872 35744472 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429550 NA12892 female +ERR1429551 839395 42809145 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429551 NA12892 female +ERR1429552 574017 29274867 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429552 NA12892 female +ERR1429553 1022930 52169430 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429553 NA12892 female +ERR1429554 770504 39295704 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429554 NA12892 female +ERR1429555 589137 30045987 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429555 NA12892 female +ERR1429556 621838 31713738 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429556 NA12892 female +ERR1429557 573305 29238555 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429557 NA12892 female +ERR1429558 711033 36262683 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429558 NA12892 female +ERR1429559 664808 33905208 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429559 NA12892 female +ERR1429560 531349 27098799 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429560 NA12892 female +ERR1429561 892253 45504903 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429561 NA12892 female +ERR1429562 687951 35085501 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429562 NA12892 female +ERR1429563 624558 31852458 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429563 NA12892 female +ERR1429564 781236 39843036 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429564 NA12892 female +ERR1429565 1372521 69998571 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429565 NA12892 female +ERR1429566 1218765 62157015 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429566 NA12892 female +ERR1429567 675274 34438974 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429567 NA12892 female +ERR1429568 560720 28596720 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429568 NA12892 female +ERR1429569 664298 33879198 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429569 NA12892 female +ERR1429570 572222 29183322 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429570 NA12892 female +ERR1429571 1350359 68868309 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429571 NA12892 female +ERR1429572 1309402 66779502 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429572 NA12892 female +ERR1429573 1088377 55507227 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429573 NA12892 female +ERR1429574 1047059 53400009 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429574 NA12892 female +ERR1429575 529587 27008937 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429575 NA12892 female +ERR1429576 1169107 59624457 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429576 NA12892 female +ERR1429577 699355 35667105 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429577 NA12892 female +ERR1429578 698973 35647623 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429578 NA12892 female +ERR1429579 567632 28949232 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429579 NA12892 female +ERR1429580 880930 44927430 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429580 NA12892 female +ERR1429581 682353 34800003 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429581 NA12892 female +ERR1429582 800198 40810098 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429582 NA12892 female +ERR1429583 564119 28770069 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429583 NA12892 female +ERR1429584 765306 39030606 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429584 NA12892 female +ERR1429585 690339 35207289 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429585 NA12892 female +ERR1429586 559619 28540569 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429586 NA12892 female +ERR1429587 922910 47068410 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429587 NA12892 female +ERR1429588 467525 23843775 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429588 NA12892 female +ERR1429589 638329 32554779 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429589 NA12892 female +ERR1429590 690814 35231514 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429590 NA12892 female +ERR1429591 477979 24376929 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429591 NA12892 female +ERR1429592 560344 28577544 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429592 NA12892 female +ERR1429593 784251 39996801 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429593 NA12892 female +ERR1429594 747178 38106078 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429594 NA12892 female +ERR1429595 827661 42210711 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429595 NA12892 female +ERR1429596 950714 48486414 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429596 NA12892 female +ERR1429597 5235515 267011265 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429597 NA12892 female +ERR1429598 939966 47938266 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429598 NA12892 female +ERR1429599 546226 27857526 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429599 NA12892 female +ERR1429600 463247 23625597 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429600 NA12892 female +ERR1429601 1024726 52261026 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429601 NA12892 female +ERR1429602 1465503 74740653 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429602 NA12892 female +ERR1429603 1174942 59922042 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429603 NA12892 female +ERR1429604 921930 47018430 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429604 NA12892 female +ERR1429605 1074963 54823113 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429605 NA12892 female +ERR1429606 970622 49501722 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429606 NA12892 female +ERR1429607 796770 40635270 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429607 NA12892 female +ERR1429608 884429 45105879 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429608 NA12892 female +ERR1429609 1034885 52779135 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429609 NA12892 female +ERR1429610 579267 29542617 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429610 NA12892 female +ERR1429611 497651 25380201 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429611 NA12892 female +ERR1429612 538377 27457227 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429612 NA12892 female +ERR1429613 1005381 51274431 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429613 NA12892 female +ERR1429614 987462 50360562 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429614 NA12892 female +ERR1429615 456782 23295882 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429615 NA12892 female +ERR1429616 674193 34383843 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429616 NA12892 female +ERR1429617 953023 48604173 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429617 NA12892 female +ERR1429618 617758 31505658 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429618 NA12892 female +ERR1429619 598055 30500805 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429619 NA12892 female +ERR1429620 597972 30496572 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429620 NA12892 female +ERR1429621 456116 23261916 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429621 NA12892 female +ERR1429622 997159 50855109 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429622 NA12892 female +ERR1429623 505516 25781316 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429623 NA12892 female +ERR1429043 605410 30875910 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429043 NA12878 female +ERR1429044 464531 23691081 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429044 NA12878 female +ERR1429045 548098 27952998 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429045 NA12878 female +ERR1429046 516069 26319519 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429046 NA12878 female +ERR1429047 494917 25240767 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429047 NA12878 female +ERR1429048 324250 16536750 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429048 NA12878 female +ERR1429049 377454 19250154 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429049 NA12878 female +ERR1429050 439003 22389153 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429050 NA12878 female +ERR1429051 527178 26886078 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429051 NA12878 female +ERR1429052 445298 22710198 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429052 NA12878 female +ERR1429053 466364 23784564 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429053 NA12878 female +ERR1429054 417270 21280770 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429054 NA12878 female +ERR1429055 408573 20837223 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429055 NA12878 female +ERR1429056 350813 17891463 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429056 NA12878 female +ERR1429057 532542 27159642 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429057 NA12878 female +ERR1429058 547294 27911994 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429058 NA12878 female +ERR1429059 289030 14740530 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429059 NA12878 female +ERR1429060 471157 24029007 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429060 NA12878 female +ERR1429061 493958 25191858 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429061 NA12878 female +ERR1429062 362477 18486327 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429062 NA12878 female +ERR1429063 267605 13647855 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429063 NA12878 female +ERR1429064 277873 14171523 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429064 NA12878 female +ERR1429065 384164 19592364 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429065 NA12878 female +ERR1429066 360900 18405900 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429066 NA12878 female +ERR1429067 470448 23992848 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429067 NA12878 female +ERR1429068 529681 27013731 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429068 NA12878 female +ERR1429069 352233 17963883 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429069 NA12878 female +ERR1429070 571067 29124417 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429070 NA12878 female +ERR1429071 504820 25745820 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429071 NA12878 female +ERR1429072 309267 15772617 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429072 NA12878 female +ERR1429073 425635 21707385 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429073 NA12878 female +ERR1429074 454845 23197095 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429074 NA12878 female +ERR1429075 202007 10302357 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429075 NA12878 female +ERR1429076 612703 31247853 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429076 NA12878 female +ERR1429077 590290 30104790 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429077 NA12878 female +ERR1429078 447433 22819083 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429078 NA12878 female +ERR1429079 338973 17287623 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429079 NA12878 female +ERR1429080 487364 24855564 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429080 NA12878 female +ERR1429081 545881 27839931 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429081 NA12878 female +ERR1429082 522177 26631027 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429082 NA12878 female +ERR1429083 475914 24271614 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429083 NA12878 female +ERR1429084 587003 29937153 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429084 NA12878 female +ERR1429085 587009 29937459 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429085 NA12878 female +ERR1429086 547645 27929895 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429086 NA12878 female +ERR1429087 459050 23411550 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429087 NA12878 female +ERR1429088 270489 13794939 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429088 NA12878 female +ERR1429089 547181 27906231 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429089 NA12878 female +ERR1429282 478706 24414006 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429282 NA12891 male +ERR1429283 1604643 81836793 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429283 NA12891 male +ERR1429284 1102261 56215311 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429284 NA12891 male +ERR1429285 1337037 68188887 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429285 NA12891 male +ERR1429286 845172 43103772 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429286 NA12891 male +ERR1429287 1255934 64052634 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429287 NA12891 male +ERR1429288 781311 39846861 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429288 NA12891 male +ERR1429289 784261 39997311 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429289 NA12891 male +ERR1429290 1464639 74696589 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429290 NA12891 male +ERR1429291 1111003 56661153 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429291 NA12891 male +ERR1429292 887204 45247404 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429292 NA12891 male +ERR1429293 873622 44554722 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429293 NA12891 male +ERR1429294 1517391 77386941 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429294 NA12891 male +ERR1429295 604847 30847197 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429295 NA12891 male +ERR1429296 1096055 55898805 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429296 NA12891 male +ERR1429297 1766588 90095988 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429297 NA12891 male +ERR1429298 1133125 57789375 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429298 NA12891 male +ERR1429299 880106 44885406 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429299 NA12891 male +ERR1429300 870455 44393205 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429300 NA12891 male +ERR1429301 655374 33424074 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429301 NA12891 male +ERR1429302 530794 27070494 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429302 NA12891 male +ERR1429303 1647372 84015972 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429303 NA12891 male +ERR1429304 1012403 51632553 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429304 NA12891 male +ERR1429305 1291017 65841867 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429305 NA12891 male +ERR1429306 1929309 98394759 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429306 NA12891 male +ERR1429307 1388340 70805340 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429307 NA12891 male +ERR1429308 952677 48586527 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429308 NA12891 male +ERR1429309 637678 32521578 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429309 NA12891 male +ERR1429310 1689586 86168886 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429310 NA12891 male +ERR1429311 1351050 68903550 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429311 NA12891 male +ERR1429312 1926500 98251500 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429312 NA12891 male +ERR1429313 1127035 57478785 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429313 NA12891 male +ERR1429314 902921 46048971 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429314 NA12891 male +ERR1429315 1343658 68526558 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429315 NA12891 male +ERR1429316 592152 30199752 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429316 NA12891 male +ERR1429317 799753 40787403 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429317 NA12891 male +ERR1429318 1604259 81817209 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429318 NA12891 male +ERR1429319 772620 39403620 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429319 NA12891 male +ERR1429320 948191 48357741 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429320 NA12891 male +ERR1429321 1149341 58616391 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429321 NA12891 male +ERR1429322 2440295 124455045 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429322 NA12891 male +ERR1429323 644880 32888880 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429323 NA12891 male +ERR1429324 1591841 81183891 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429324 NA12891 male +ERR1429325 746939 38093889 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429325 NA12891 male +ERR1429515 742596 37872396 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429515 NA12892 female +ERR1429516 441081 22495131 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429516 NA12892 female +ERR1429517 627119 31983069 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429517 NA12892 female +ERR1429518 963073 49116723 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429518 NA12892 female +ERR1429519 1062118 54168018 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429519 NA12892 female +ERR1429520 359069 18312519 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429520 NA12892 female +ERR1429521 780080 39784080 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429521 NA12892 female +ERR1429522 1223012 62373612 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429522 NA12892 female +ERR1429523 525746 26813046 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429523 NA12892 female +ERR1429039 459819 23450769 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429039 NA12878 female +ERR1429040 602524 30728724 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429040 NA12878 female +ERR1429041 337658 17220558 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429041 NA12878 female +ERR1429042 632741 32269791 https://sra-download.ncbi.nlm.nih.gov/srapub/ERR1429042 NA12878 female \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/README b/evaluation/tests/HLA_novel/README new file mode 100644 index 0000000..e9e4b8b --- /dev/null +++ b/evaluation/tests/HLA_novel/README @@ -0,0 +1,20 @@ + hisatgenotype_locus.py --aligner-list hisat2.graph --base hla --locus-list A --num-editdist 2 --assembly -1 ILMN/NA12892.extracted.1.fq.gz -2 ILMN/NA12892.extracted.2.fq.gz + + for i in `ls -l CP_80/LP*1.fq.gz | awk '{print $NF}' | cut -d'/' -f2 | cut -d'.' -f1`; do echo $i; ./hisatgenotype_locus.py --locus-list A --num-editdist 2 --assembly --reads CP_80/$i.extracted.1.fq.gz,CP_80/$i.extracted.2.fq.gz --assembly-base assembly_graph_$i 2> $i.tmp; done + + hisatgenotype_locus_samples.py -p 3 -v --max-sample 400 --region-list hla.A --read-dir CP_400 --out-dir test_A > cp_400_A.txt + hisatgenotype_scripts/compare_HLA_Omixon.py cp_400_A.txt ../CAAPA/omixon_caapa_hla.txt + + hisatgenotype_locus.py --aligner-list hisat2.graph --locus-list A --num-editdist 2 --assembly -1 CP_80/LP6005106-DNA_H02.extracted.fq.1.gz -2 CP_80/LP6005106-DNA_H02.extracted.fq.2.gz --display-alleles A*23:17,A*02:02:01:01 + + hisatgenotype_extract_reads.py --base-fname genotype_genome --reference-type genome --read-dir ILMN_12062016 --out-dir ILMN + + hisat2 --no-hd -x genotype_genome -c CAGCTGGGATGTGGAGTGGTGTGAGGAGTGGCCACAGGGGAGCAGAGGAGGTGGCAGAAGCCGGAGGTAAAGGTGTCTTAAA + + +On MARCC - https://www.marcc.jhu.edu/getting-started/basic + +sbatch script-name +squeue -u dkim136@jhu.edu +scancel job-id +sinfo diff --git a/evaluation/tests/HLA_novel/hisatgenotype.py b/evaluation/tests/HLA_novel/hisatgenotype.py new file mode 100644 index 0000000..fad5906 --- /dev/null +++ b/evaluation/tests/HLA_novel/hisatgenotype.py @@ -0,0 +1 @@ +../../../hisatgenotype.py \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/hisatgenotype_build_genome.py b/evaluation/tests/HLA_novel/hisatgenotype_build_genome.py new file mode 100644 index 0000000..9d3572a --- /dev/null +++ b/evaluation/tests/HLA_novel/hisatgenotype_build_genome.py @@ -0,0 +1 @@ +../../../hisatgenotype_build_genome.py \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/hisatgenotype_extract_vars.py b/evaluation/tests/HLA_novel/hisatgenotype_extract_vars.py new file mode 100644 index 0000000..6d113b3 --- /dev/null +++ b/evaluation/tests/HLA_novel/hisatgenotype_extract_vars.py @@ -0,0 +1 @@ +../../../hisatgenotype_extract_vars.py \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/hisatgenotype_locus.py b/evaluation/tests/HLA_novel/hisatgenotype_locus.py new file mode 100644 index 0000000..c6bcacb --- /dev/null +++ b/evaluation/tests/HLA_novel/hisatgenotype_locus.py @@ -0,0 +1 @@ +../../../hisatgenotype_locus.py \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/hisatgenotype_locus_prev.py b/evaluation/tests/HLA_novel/hisatgenotype_locus_prev.py new file mode 100644 index 0000000..3daa365 --- /dev/null +++ b/evaluation/tests/HLA_novel/hisatgenotype_locus_prev.py @@ -0,0 +1,3210 @@ +#!/usr/bin/env python +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + + +import sys, os, subprocess, re +import inspect, random +import math +from datetime import datetime, date, time +from argparse import ArgumentParser, FileType +from copy import deepcopy +from hisatgenotype_modules import typing_common, Gene_typing, assembly_graph + + + +""" +Align reads, and sort the alignments into a BAM file +""" +def align_reads(ex_path, + aligner, + simulation, + base_fname, + index_type, + read_fname, + fastq, + threads, + out_fname, + verbose): + if aligner == "hisat2": + hisat2 = os.path.join(ex_path, "hisat2") + # DK - debugging purpose + # aligner_cmd = [hisat2, "--mm"] + aligner_cmd = ["/Users/infphilo/work/hisat2/hisat2", "--mm"] + if not simulation: + aligner_cmd += ["--no-unal"] + DNA = True + if DNA: + aligner_cmd += ["--no-spliced-alignment"] # no spliced alignment + aligner_cmd += ["-X", "1000"] # max fragment length + if index_type == "linear": + aligner_cmd += ["-k", "10"] + else: + aligner_cmd += ["--max-altstried", "64"] + # DK - debugging purposes + aligner_cmd += ["--haplotype"] + if base_fname == "codis": + aligner_cmd += ["--enable-codis"] + aligner_cmd += ["-x", "%s.%s" % (base_fname, index_type)] + elif aligner == "bowtie2": + aligner_cmd = [aligner, + "--no-unal", + "-k", "10", + "-x", base_fname] + else: + assert False + assert len(read_fname) in [1,2] + aligner_cmd += ["-p", str(threads)] + if not fastq: + aligner_cmd += ["-f"] + if len(read_fname) == 1: + aligner_cmd += ["-U", read_fname[0]] + else: + aligner_cmd += ["-1", "%s" % read_fname[0], + "-2", "%s" % read_fname[1]] + if verbose >= 1: + print >> sys.stderr, ' '.join(aligner_cmd) + align_proc = subprocess.Popen(aligner_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + sambam_cmd = ["samtools", + "view", + "-bS", + "-"] + sambam_proc = subprocess.Popen(sambam_cmd, + stdin=align_proc.stdout, + stdout=open(out_fname + ".unsorted", 'w'), + stderr=open("/dev/null", 'w')) + sambam_proc.communicate() + if index_type == "graph": + bamsort_cmd = ["samtools", + "sort", + out_fname + ".unsorted", + "-o", out_fname] + bamsort_proc = subprocess.Popen(bamsort_cmd, + stderr=open("/dev/null", 'w')) + bamsort_proc.communicate() + + bamindex_cmd = ["samtools", + "index", + out_fname] + bamindex_proc = subprocess.Popen(bamindex_cmd, + stderr=open("/dev/null", 'w')) + bamindex_proc.communicate() + + os.system("rm %s" % (out_fname + ".unsorted")) + + +""" +""" +def normalize(prob): + total = sum(prob.values()) + for allele, mass in prob.items(): + prob[allele] = mass / total + + +""" +""" +def prob_diff(prob1, prob2): + diff = 0.0 + for allele in prob1.keys(): + if allele in prob2: + diff += abs(prob1[allele] - prob2[allele]) + else: + diff += prob1[allele] + return diff + + +""" +""" +def Gene_prob_cmp(a, b): + if a[1] != b[1]: + if a[1] < b[1]: + return 1 + else: + return -1 + assert a[0] != b[0] + if a[0] < b[0]: + return -1 + else: + return 1 + + +""" +""" +def single_abundance(Gene_cmpt, + Gene_length): + def normalize2(prob, length): + total = 0 + for allele, mass in prob.items(): + assert allele in length + total += (mass / length[allele]) + for allele, mass in prob.items(): + assert allele in length + prob[allele] = mass / length[allele] / total + + Gene_prob, Gene_prob_next = {}, {} + for cmpt, count in Gene_cmpt.items(): + alleles = cmpt.split('-') + for allele in alleles: + if allele not in Gene_prob: + Gene_prob[allele] = 0.0 + Gene_prob[allele] += (float(count) / len(alleles)) + + normalize(Gene_prob) + def next_prob(Gene_cmpt, Gene_prob, Gene_length): + Gene_prob_next = {} + for cmpt, count in Gene_cmpt.items(): + alleles = cmpt.split('-') + alleles_prob = 0.0 + for allele in alleles: + if allele not in Gene_prob: + continue + alleles_prob += Gene_prob[allele] + if alleles_prob <= 0.0: + continue + for allele in alleles: + if allele not in Gene_prob: + continue + if allele not in Gene_prob_next: + Gene_prob_next[allele] = 0.0 + Gene_prob_next[allele] += (float(count) * Gene_prob[allele] / alleles_prob) + normalize(Gene_prob_next) + return Gene_prob_next + + + fast_EM = True + diff, iter = 1.0, 0 + while diff > 0.0001 and iter < 1000: + Gene_prob_next = next_prob(Gene_cmpt, Gene_prob, Gene_length) + if fast_EM: + # Accelerated version of EM - SQUAREM iteration + # Varadhan, R. & Roland, C. Scand. J. Stat. 35, 335-353 (2008) + # Also, this algorithm is used in Sailfish - http://www.nature.com/nbt/journal/v32/n5/full/nbt.2862.html + Gene_prob_next2 = next_prob(Gene_cmpt, Gene_prob_next, Gene_length) + sum_squared_r, sum_squared_v = 0.0, 0.0 + p_r, p_v = {}, {} + for a in Gene_prob.keys(): + p_r[a] = Gene_prob_next[a] - Gene_prob[a] + sum_squared_r += (p_r[a] * p_r[a]) + p_v[a] = Gene_prob_next2[a] - Gene_prob_next[a] - p_r[a] + sum_squared_v += (p_v[a] * p_v[a]) + if sum_squared_v > 0.0: + gamma = -math.sqrt(sum_squared_r / sum_squared_v) + for a in Gene_prob.keys(): + Gene_prob_next2[a] = max(0.0, Gene_prob[a] - 2 * gamma * p_r[a] + gamma * gamma * p_v[a]); + Gene_prob_next = next_prob(Gene_cmpt, Gene_prob_next2, Gene_length) + + diff = prob_diff(Gene_prob, Gene_prob_next) + Gene_prob = Gene_prob_next + + # Accelerate convergence + if iter >= 10: + Gene_prob2 = {} + avg_prob = sum(Gene_prob.values()) / len(Gene_prob) + for allele, prob in Gene_prob.items(): + if prob >= 0.005 or prob > avg_prob: + Gene_prob2[allele] = prob + Gene_prob = Gene_prob2 + + # DK - debugging purposes + if iter % 10 == 0 and False: + print "iter", iter + for allele, prob in Gene_prob.items(): + if prob >= 0.01: + print >> sys.stderr, "\t", iter, allele, prob, str(datetime.now()) + + iter += 1 + + """ + for allele, prob in Gene_prob.items(): + allele_len = Gene_length[allele] + Gene_prob[allele] /= float(allele_len) + """ + + # normalize(Gene_prob) + normalize2(Gene_prob, Gene_length) + Gene_prob = [[allele, prob] for allele, prob in Gene_prob.items()] + Gene_prob = sorted(Gene_prob, cmp=Gene_prob_cmp) + return Gene_prob + + +""" +""" +def lower_bound(Var_list, pos): + low, high = 0, len(Var_list) + while low < high: + m = (low + high) / 2 + m_pos = Var_list[m][0] + if m_pos < pos: + low = m + 1 + elif m_pos > pos: + high = m + else: + assert m_pos == pos + while m > 0: + if Var_list[m-1][0] < pos: + break + m -= 1 + return m + return low + + +""" + var: ['single', 3300, 'G'] + exons: [[301, 373], [504, 822], [1084, 1417], [2019, 2301], [2404, 2520], [2965, 2997], [3140, 3187], [3357, 3361]] +""" +def var_in_exon(var, exons): + exonic = False + var_type, var_left, var_data = var + var_right = var_left + if var_type == "deletion": + var_right = var_left + int(var_data) - 1 + for exon_left, exon_right in exons: + if var_left >= exon_left and var_right <= exon_right: + return True + return False + + +""" +Report variant IDs whose var is within exonic regions +""" +def get_exonic_vars(Vars, exons): + vars = set() + for var_id, var in Vars.items(): + var_type, var_left, var_data = var + var_right = var_left + if var_type == "deletion": + var_right = var_left + int(var_data) - 1 + for exon_left, exon_right in exons: + if var_left >= exon_left and var_right <= exon_right: + vars.add(var_id) + + return vars + + +""" +Get representative alleles among those that share the same exonic sequences +""" +def get_rep_alleles(Links, exon_vars): + allele_vars = {} + for var, alleles in Links.items(): + if var not in exon_vars: + continue + for allele in alleles: + if allele not in allele_vars: + allele_vars[allele] = set() + allele_vars[allele].add(var) + + allele_groups = {} + for allele, vars in allele_vars.items(): + vars = '-'.join(vars) + if vars not in allele_groups: + allele_groups[vars] = [] + allele_groups[vars].append(allele) + + allele_reps = {} # allele representatives + allele_rep_groups = {} # allele groups by allele representatives + for allele_members in allele_groups.values(): + assert len(allele_members) > 0 + allele_rep = allele_members[0] + allele_rep_groups[allele_rep] = allele_members + for allele_member in allele_members: + assert allele_member not in allele_reps + allele_reps[allele_member] = allele_rep + + return allele_reps, allele_rep_groups + + +""" +Identify alternative alignments +""" +def get_alternatives(ref_seq, Vars, Var_list, verbose): + # Check deletions' alternatives + def get_alternatives_recur(ref_seq, + Vars, + Var_list, + Alts, + var_id, + del_len, + other_del_len, + left, + alt_list, + var_j, + latest_pos, + debug = False): + def add_alt(Alts, alt_list, var_id, j_id): + if j_id.isdigit(): + if var_id not in Alts: + Alts[var_id] = [["1"]] + else: + if Alts[var_id][-1][-1].isdigit(): + Alts[var_id][-1][-1] = str(int(Alts[var_id][-1][-1]) + 1) + else: + Alts[var_id][-1].append("1") + else: + if var_id not in Alts: + Alts[var_id] = [[j_id]] + else: + if Alts[var_id][-1][-1].isdigit(): + Alts[var_id][-1][-1] = j_id + else: + Alts[var_id][-1].append(j_id) + Alts[var_id][-1].append("0") + + if not j_id.isdigit(): + alt_list.append(j_id) + alts = '-'.join(alt_list) + if alts not in Alts: + Alts[alts] = [[var_id]] + else: + Alts[alts].append([var_id]) + + if del_len == other_del_len: + return + + var_type, var_pos, var_data = Vars[var_id] + if left: # Look in left direction + if var_j < 0: + return + j_pos, j_id = Var_list[var_j] + alt_del = [] + if var_id != j_id and j_pos < var_pos + del_len: + prev_latest_pos = latest_pos + # Check bases between SNPs + while latest_pos - max(0, del_len - other_del_len) > 0: + if ref_seq[latest_pos - 1] != ref_seq[latest_pos - 1 - del_len + other_del_len]: + break + latest_pos -= 1 + add_alt(Alts, alt_list, var_id, str(latest_pos)) + if latest_pos - 1 > j_pos: + return + j_type, _, j_data = Vars[j_id] + if j_type == "deletion": + j_del_len = int(j_data) + if j_type == "single" and j_pos == latest_pos - 1: + j_cmp_pos = j_pos - del_len + other_del_len + if debug: + print Vars[j_id] + print j_pos, ref_seq[j_pos] + print j_cmp_pos, ref_seq[j_cmp_pos] + if j_data == ref_seq[j_cmp_pos]: + add_alt(Alts, alt_list, var_id, j_id) + latest_pos = j_pos + elif j_type == "deletion" and j_pos + j_del_len - 1 == prev_latest_pos - 1: + alt_list2 = alt_list[:] + [j_id] + latest_pos2 = j_pos + alt_del = [alt_list2, latest_pos2] + + get_alternatives_recur(ref_seq, + Vars, + Var_list, + Alts, + var_id, + del_len, + other_del_len, + left, + alt_list, + var_j - 1, + latest_pos, + debug) + + if alt_del: + alt_list2, latest_pos2 = alt_del + if var_id not in Alts: + Alts[var_id] = [alt_list2[:]] + else: + Alts[var_id].append(alt_list2[:]) + alt_idx = len(Alts[var_id]) - 1 + get_alternatives_recur(ref_seq, + Vars, + Var_list, + Alts, + var_id, + del_len, + other_del_len + j_del_len, + left, + alt_list2, + var_j - 1, + latest_pos2, + debug) + # Remove this Deletion if not supported by additional bases? + assert alt_idx < len(Alts[var_id]) + if Alts[var_id][alt_idx][-1] == j_id: + Alts[var_id] = Alts[var_id][:alt_idx] + Alts[var_id][alt_idx+1:] + + else: # Look in right direction + if var_j >= len(Var_list): + return + j_pos, j_id = Var_list[var_j] + alt_del = [] + if var_id != j_id and j_pos >= var_pos: + # Check bases between SNPs + prev_latest_pos = latest_pos + while latest_pos + 1 + max(0, del_len - other_del_len) < len(ref_seq): + if ref_seq[latest_pos + 1] != ref_seq[latest_pos + 1 + del_len - other_del_len]: + break + + # DK - debugging purposes + if debug: + pos2_ = latest_pos + 1 + del_len - other_del_len + print "DK: latest_pos:", latest_pos + 1, pos2_ + print "DK: var_pos:", var_pos, "del_len:", del_len, "other_del_len:", other_del_len + print "DK:", ref_seq[latest_pos + 1], ref_seq[pos2_] + + latest_pos += 1 + add_alt(Alts, alt_list, var_id, str(latest_pos)) + + if latest_pos + 1 < j_pos: + return + + j_type, _, j_data = Vars[j_id] + if j_type == "single" and j_pos == latest_pos + 1: + j_cmp_pos = j_pos + del_len - other_del_len + if debug: + print Vars[j_id] + print j_pos, ref_seq[j_pos] + print j_cmp_pos, ref_seq[j_cmp_pos] + + if j_data == ref_seq[j_cmp_pos]: + add_alt(Alts, alt_list, var_id, j_id) + latest_pos = j_pos + elif j_type == "deletion" and j_pos == prev_latest_pos + 1: + j_del_len = int(j_data) + alt_list2 = alt_list[:] + [j_id] + latest_pos2 = j_pos + j_del_len - 1 + alt_del = [alt_list2, latest_pos2] + + get_alternatives_recur(ref_seq, + Vars, + Var_list, + Alts, + var_id, + del_len, + other_del_len, + left, + alt_list, + var_j + 1, + latest_pos, + debug) + + if alt_del: + alt_list2, latest_pos2 = alt_del + if var_id not in Alts: + Alts[var_id] = [alt_list2[:]] + else: + Alts[var_id].append(alt_list2[:]) + alt_idx = len(Alts[var_id]) - 1 + get_alternatives_recur(ref_seq, + Vars, + Var_list, + Alts, + var_id, + del_len, + other_del_len + j_del_len, + left, + alt_list2, + var_j + 1, + latest_pos2, + debug) + + # Remove this Deletion if not supported by additional bases? + assert alt_idx < len(Alts[var_id]) + if Alts[var_id][alt_idx][-1] == j_id: + Alts[var_id] = Alts[var_id][:alt_idx] + Alts[var_id][alt_idx+1:] + + # Check deletions' alternatives + Alts_left, Alts_right = {}, {} + for var_i, var_id in Var_list: + var_type, var_pos, var_data = var = Vars[var_id] + if var_type != "deletion" or var_pos == 0: + continue + del_len = int(var_data) + if var_pos + del_len >= len(ref_seq): + assert var_pos + del_len == len(ref_seq) + continue + debug = (var_id == "hv454a") + if debug: + print Vars[var_id] + + alt_list = [] + var_j = lower_bound(Var_list, var_pos + del_len - 1) + latest_pos = var_pos + del_len + if var_j < len(Var_list): + get_alternatives_recur(ref_seq, + Vars, + Var_list, + Alts_left, + var_id, + del_len, + 0, + True, # left + alt_list, + var_j, + latest_pos, + debug) + alt_list = [] + var_j = lower_bound(Var_list, var_pos) + latest_pos = var_pos - 1 + assert var_j >= 0 + get_alternatives_recur(ref_seq, + Vars, + Var_list, + Alts_right, + var_id, + del_len, + 0, + False, # right + alt_list, + var_j, + latest_pos, + debug) + + if debug: + print "DK :-)" + sys.exit(1) + + def assert_print_alts(Alts, dir): + def get_seq_pos(alt_list): + seq = "" + seq_left, seq_right = -1, -1 + for i in range(len(alt_list)): + alt = alt_list[i] + if alt.isdigit(): + assert i + 1 == len(alt_list) + if dir == "left": + if i == 0: + seq = alt + break + + alt = int(alt) + seq = ref_seq[seq_left-alt+1:seq_left+1] + seq + seq_left -= alt + else: + alt = int(alt) + seq += ref_seq[seq_right:seq_right+alt] + seq_right += alt + break + + var_type, var_pos, var_data = Vars[alt] + if dir == "left" and var_type == "deletion": + var_pos = var_pos + int(var_data) - 1 + + if i == 0: + if dir == "left": + seq_left, seq_right = var_pos, var_pos + else: + seq_left, seq_right = var_pos, var_pos + + if dir == "left": + assert seq_left >= var_pos + if i > 0: + seq = ref_seq[var_pos+1:seq_left+1] + seq + if var_type == "single": + seq = var_data + seq + seq_left = var_pos - 1 + elif var_type == "deletion": + seq_left = var_pos - int(var_data) + else: + assert var_type == "insertion" + seq = var_data + seq + else: + assert seq_right <= var_pos + if i > 0: + seq += ref_seq[seq_right:var_pos] + if var_type == "single": + seq += var_data + seq_right = var_pos + 1 + elif var_type == "deletion": + seq_right = var_pos + int(var_data) + else: + assert var_type == "insertion" + seq += var_data + + return seq, seq_left, seq_right + + for alt_list1, alt_list2 in Alts.items(): + if verbose >= 2: print >> sys.stderr, "\t", dir, ":", alt_list1, alt_list2 + out_str = "\t\t" + alt_list1 = alt_list1.split('-') + for i in range(len(alt_list1)): + alt = alt_list1[i] + var_type, var_pos, var_data = Vars[alt] + out_str += ("%s-%d-%s" % (var_type, var_pos, var_data)) + if i + 1 < len(alt_list1): + out_str += " " + + for i in range(len(alt_list2)): + alt_list3 = alt_list2[i] + out_str += "\t[" + for j in range(len(alt_list3)): + alt = alt_list3[j] + if alt.isdigit(): + out_str += alt + else: + var_type, var_pos, var_data = Vars[alt] + out_str += ("%s-%d-%s" % (var_type, var_pos, var_data)) + if j + 1 < len(alt_list3): + out_str += ", " + out_str += "]" + if verbose >= 2: print >> sys.stderr, out_str + + for i in range(len(alt_list2)): + alt_list3 = alt_list2[i] + seq1, seq1_left, seq1_right = get_seq_pos(alt_list1) + seq2, seq2_left, seq2_right = get_seq_pos(alt_list3) + if seq1.isdigit(): + assert not seq2.isdigit() + seq1_left, seq1_right = seq2_right - int(seq1), seq2_right + seq1 = ref_seq[seq1_left+1:seq1_right+1] + elif seq2.isdigit(): + seq2_left, seq2_right = seq1_right - int(seq2), seq1_right + seq2 = ref_seq[seq2_left+1:seq2_right+1] + + if dir == "left": + if seq1_right < seq2_right: + seq1 += ref_seq[seq1_right+1:seq2_right+1] + elif seq2_right < seq1_right: + seq2 += ref_seq[seq2_right+1:seq1_right+1] + else: + if seq1_left < seq2_left: + seq2 = ref_seq[seq1_left:seq2_left] + seq2 + elif seq2_left < seq1_left: + seq1 = ref_seq[seq2_left:seq1_left] + seq1 + seq1_len, seq2_len = len(seq1), len(seq2) + if seq1_len != seq2_len: + len_diff = abs(seq1_len - seq2_len) + if dir == "left": + if seq1_len < seq2_len: + seq1 = ref_seq[seq1_left-len_diff+1:seq1_left+1] + seq1 + else: + seq2 = ref_seq[seq2_left-len_diff+1:seq2_left+1] + seq2 + else: + if seq1_len < seq2_len: + seq1 += ref_seq[seq1_right:seq1_right+len_diff] + else: + seq2 += ref_seq[seq2_right:seq2_right+len_diff] + if verbose >= 3: + print >> sys.stderr, "\t\t", alt_list1, alt_list3 + print >> sys.stderr, "\t\t\t", seq1, seq1_left, seq1_right + print >> sys.stderr, "\t\t\t", seq2, seq2_left, seq2_right + assert seq1 == seq2 + + assert_print_alts(Alts_left, "left") + assert_print_alts(Alts_right, "right") + + return Alts_left, Alts_right + + +""" +Identify ambigious differences that may account for other alleles, + given a list of differences (cmp_list) between a read and a potential allele +""" +def identify_ambigious_diffs(Vars, + Alts_left, + Alts_right, + cmp_list, + verbose, + debug = False): + cmp_left, cmp_right = 0, len(cmp_list) - 1 + + i = 0 + while i < len(cmp_list): + cmp_i = cmp_list[i] + type, pos, length = cmp_i[:3] + # Check alternative alignments + if type in ["mismatch", "deletion"]: + var_id = cmp_i[3] + if var_id == "unknown": + i += 1 + continue + + # Left direction + id_str = var_id + total_del_len = length if type == "deletion" else 0 + for j in reversed(range(0, i)): + cmp_j = cmp_list[j] + j_type, j_pos, j_len = cmp_j[:3] + if j_type != "match": + if len(cmp_j) < 4: + continue + j_var_id = cmp_j[3] + id_str += ("-%s" % j_var_id) + if j_type == "deletion": + total_del_len += j_len + last_type, last_pos, last_len = cmp_list[0][:3] + assert last_type in ["match", "mismatch"] + left_pos = last_pos + total_del_len + if id_str in Alts_left: + orig_alts = id_str.split('-') + alts_list = Alts_left[id_str] + for alts in alts_list: + if alts[-1].isdigit(): + assert type == "deletion" + assert len(orig_alts) == 1 + alts_id_str = '-'.join(alts[:-1]) + alt_left_pos = pos + alt_total_del_len = 0 + for alt in alts[:-1]: + assert alt in Vars + alt_type, alt_pos, alt_data = Vars[alt] + alt_left_pos = alt_pos - 1 + if alt_type == "deletion": + alt_total_del_len += int(alt_data) + alt_left_pos = alt_left_pos + alt_total_del_len - int(alts[-1]) + 1 + else: + alts_id_str = '-'.join(alts) + assert alts_id_str in Alts_left + for back_alts in Alts_left[alts_id_str]: + back_id_str = '-'.join(back_alts) + if back_id_str.find(id_str) != 0: + continue + assert len(orig_alts) < len(back_alts) + assert back_alts[-1].isdigit() + alt_left_pos = pos + alt_total_del_len = 0 + for alt in back_alts[:len(orig_alts) + 1]: + if alt.isdigit(): + alt_left_pos = alt_left_pos - int(alt) + 1 + else: + assert alt in Vars + alt_type, alt_pos, alt_data = Vars[alt] + alt_left_pos = alt_pos - 1 + if alt_type == "deletion": + alt_total_del_len += int(alt_data) + alt_left_pos += alt_total_del_len + if left_pos >= alt_left_pos: + if verbose >= 2: + print "LEFT:", cmp_list + print "\t", type, "id_str:", id_str, "=>", alts_id_str, "=>", back_alts, "left_pos:", left_pos, "alt_left_pos:", alt_left_pos + cmp_left = i + 1 + break + + # DK - debugging purposes + if debug: + print "DK: var_id:", var_id + print "DK: cmp_list:", cmp_list + print "DK: cmp_right:", cmp_right + # sys.exit(1) + + # Right direction + if cmp_right + 1 == len(cmp_list): + id_str = var_id + total_del_len = length if type == "deletion" else 0 + for j in range(i + 1, len(cmp_list)): + cmp_j = cmp_list[j] + j_type, j_pos, j_len = cmp_j[:3] + if j_type != "match": + if len(cmp_j) < 4: + continue + j_var_id = cmp_j[3] + id_str += ("-%s" % j_var_id) + if j_type == "deletion": + total_del_len += j_len + last_type, last_pos, last_len = cmp_list[-1][:3] + assert last_type in ["match", "mismatch"] + right_pos = last_pos + last_len - 1 - total_del_len + + # DK - debugging purposes + if debug: + print "DK: id_str:", id_str + + if id_str in Alts_right: + orig_alts = id_str.split('-') + alts_list = Alts_right[id_str] + for alts in alts_list: + if alts[-1].isdigit(): + assert type == "deletion" + assert len(orig_alts) == 1 + alts_id_str = '-'.join(alts[:-1]) + alt_right_pos = pos + alt_total_del_len = 0 + for alt in alts[:-1]: + assert alt in Vars + alt_type, alt_pos, alt_data = Vars[alt] + alt_right_pos = alt_pos + if alt_type == "single": + alt_right_pos += 1 + else: + assert alt_type == "deletion" + alt_del_len = int(alt_data) + alt_right_pos += alt_del_len + alt_total_del_len += alt_del_len + alt_right_pos = alt_right_pos - alt_total_del_len + int(alts[-1]) - 1 + else: + alts_id_str = '-'.join(alts) + assert alts_id_str in Alts_right + for back_alts in Alts_right[alts_id_str]: + back_id_str = '-'.join(back_alts) + if back_id_str.find(id_str) != 0: + continue + assert len(orig_alts) < len(back_alts) + assert back_alts[-1].isdigit() + alt_right_pos = pos + alt_total_del_len = 0 + for alt in back_alts[:len(orig_alts) + 1]: + if alt.isdigit(): + alt_right_pos = alt_right_pos + int(alt) - 1 + else: + assert alt in Vars + alt_type, alt_pos, alt_data = Vars[alt] + alt_right_pos = alt_pos + if alt_type == "single": + alt_right_pos += 1 + else: + assert alt_type == "deletion" + alt_del_len = int(alt_data) + alt_right_pos += alt_del_len + alt_total_del_len += alt_del_len + alt_right_pos -= alt_total_del_len + + if right_pos <= alt_right_pos: + if verbose >= 2: + print "RIGHT:", cmp_list + print "\t", type, "id_str:", id_str, "=>", alts_id_str, "right_pos:", right_pos, "alt_right_pos:", alt_right_pos + cmp_right = i - 1 + break + i += 1 + + return cmp_left, cmp_right + + +""" +Example, + gene_name, allele_name (input): A, A*32:01:01 + allele (output): single-136-G-hv47,deletion-285-1-hv57, ... ,single-3473-T-hv1756,deletion-3495-1-hv1763,single-3613-C-hv1799 +""" +def get_allele(gene_name, allele_name, Vars, Var_list, Links): + allele_haplotype = [] + for _var_pos, _var_id in Var_list[gene_name]: + if allele_name in Links[_var_id]: + _var = Vars[gene_name][_var_id] + allele_haplotype.append("%s-%d-%s-%s" % (_var[0], _var[1], _var[2], _var_id)) + allele_haplotype = ','.join(allele_haplotype) + return allele_haplotype + + +""" +HISAT-genotype's mpileup +""" +def get_mpileup(alignview_cmd, + ref_seq, + base_locus, + vars, + allow_discordant): + ref_seq_len = len(ref_seq) + mpileup = [] + for i in range(ref_seq_len): + mpileup.append([[], {}]) + + proc = subprocess.Popen(alignview_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + prev_pos = -1 + cigar_re = re.compile('\d+\w') + for line in proc.stdout: + line = line.strip() + cols = line.split() + read_id, flag, _, pos, _, cigar_str = cols[:6] + read_seq = cols[9] + flag, pos = int(flag), int(pos) + # Unalined? + if flag & 0x4 != 0: + continue + pos -= (base_locus + 1) + if pos < 0: + continue + + # Concordantly mapped? + if flag & 0x2 != 0: + concordant = True + else: + concordant = False + + if not allow_discordant and not concordant: + continue + + read_pos, left_pos = 0, pos + right_pos = left_pos + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + for i in range(len(cigars)): + cigar_op, length = cigars[i] + if cigar_op in "MD": + for j in range(length): + if cigar_op == 'M': + read_nt = read_seq[read_pos + j] + else: + read_nt = 'D' + if read_nt not in mpileup[right_pos + j][1]: + mpileup[right_pos + j][1][read_nt] = 1 + else: + mpileup[right_pos + j][1][read_nt] += 1 + + if cigar_op in "MND": + right_pos += length + + if cigar_op in "MIS": + read_pos += length + + # Choose representative bases or 'D' + for i in range(len(mpileup)): + nt_dic = mpileup[i][1] + num_nt = sum(nt_dic.values()) + nt_set = [] + if num_nt >= 20: + for nt, count in nt_dic.items(): + if nt not in "ACGT": + continue + if count >= num_nt * 0.2 or count >= 7: + nt_set.append(nt) + mpileup[i][0] = nt_set + + # Sort variants + var_list = [[] for i in range(len(mpileup))] + for var_id, value in vars.items(): + var_type, var_pos, var_data = value + assert var_pos < len(var_list) + var_list[var_pos].append([var_id, var_type, var_data]) + + # Assign known or unknown variants + skip_i, prev_del_var_id = -1, "" + for i in range(len(mpileup)): + nt_dic = mpileup[i][1] + ref_nt = ref_seq[i] + new_nt_dic = {} + for nt, count in nt_dic.items(): + var_id = "" + if nt == 'D': + if i <= skip_i: + assert prev_del_var_id != "" + var_id = prev_del_var_id + else: + for var_id_, var_type, var_data in var_list[i]: + if var_type != "deletion": + continue + del_len = int(var_data) + del_exist = True + for j in range(i + 1, i + del_len): + assert j < len(mpileup) + nt_dic2 = mpileup[j][1] + if 'D' not in nt_dic2: + del_exist = False + break + if del_exist: + var_id = var_id_ + prev_del_var_id = var_id + skip_i = i + del_len - 1 + break + elif nt != 'N' and nt != ref_nt: + assert nt in "ACGT" + id = "unknown" + for var_id_, var_type, var_data in var_list[i]: + if var_type != "single": + continue + if nt == var_data: + var_id = var_id_ + break + new_nt_dic[nt] = [count, var_id] + + mpileup[i][1] = new_nt_dic + + return mpileup + + +""" +""" +def error_correct(ref_seq, + read_seq, + read_pos, + mpileup, + Vars, + Var_list, + cmp_list, + debug = False): + if debug: + print cmp_list + print read_seq + + i = 0 + while i < len(cmp_list): + type, left, length = cmp_list[i][:3] + assert length > 0 + if type == "match": + middle_cmp_list = [] + last_j = 0 + for j in range(length): + read_bp, ref_bp = read_seq[read_pos + j], ref_seq[left + j] + assert left + j < len(mpileup) + nt_set = mpileup[left + j][0] + if len(nt_set) > 0 and read_bp not in nt_set: + read_bp = 'N' if len(nt_set) > 1 else nt_set[0] + read_seq = read_seq[:read_pos + j] + read_bp + read_seq[read_pos + j + 1:] + assert read_bp != ref_bp + new_cmp = ["mismatch", left + j, 1, "unknown"] + if read_bp != 'N': + var_idx = lower_bound(Var_list, left + j) + while var_idx < len(Var_list): + var_pos, var_id = Var_list[var_idx] + if var_pos > left + j: + break + if var_pos == left + j: + var_type, _, var_data = Vars[var_id] + if var_type == "single" and read_bp == var_data: + new_cmp[3] = var_id + break + var_idx += 1 + if j > last_j: + middle_cmp_list.append(["match", left + last_j, j- last_j]) + middle_cmp_list.append(new_cmp) + last_j = j + 1 + if last_j < length: + middle_cmp_list.append(["match", left + last_j, length - last_j]) + + assert len(middle_cmp_list) > 0 + cmp_list = cmp_list[:i] + middle_cmp_list + cmp_list[i+1:] + i += (len(middle_cmp_list) - 1) + else: + assert type == "mismatch" + read_bp, ref_bp = read_seq[read_pos], ref_seq[left] + assert left < len(mpileup) + nt_set = mpileup[left][0] + + if debug: + print left, read_bp, ref_bp, mpileup[left] + + if len(nt_set) > 0 and read_bp not in nt_set: + read_bp = 'N' if len(nt_set) > 1 else nt_set[0] + read_seq = read_seq[:read_pos] + read_bp + read_seq[read_pos+1:] + if read_bp == 'N': + cmp_list[i][3] = "unknown" + elif read_bp == ref_bp: + cmp_list[i] = ["match", left, 1] + else: + cmp_list[i][3] = "unknown" + var_idx = lower_bound(Var_list, left) + while var_idx < len(Var_list): + var_pos, var_id = Var_list[var_idx] + if var_pos > left: + break + if var_pos == left: + var_type, _, var_data = Vars[var_id] + if var_type == "single" and read_bp == var_data: + cmp_list[i][3] = var_id + break + var_idx += 1 + + if debug: + print left, read_bp, ref_bp, mpileup[left] + print cmp_list[i] + + read_pos += length + i += 1 + + # Combine matches + i = 0 + while i < len(cmp_list): + type, left, length = cmp_list[i][:3] + if type == "match" and i + 1 < len(cmp_list): + type2, left2, length2 = cmp_list[i+1][:3] + if type2 == "match": + cmp_list[i] = [type, left, length + length2] + cmp_list = cmp_list[:i+1] + cmp_list[i+2:] + continue + i += 1 + + if debug: + print cmp_list + print read_seq + + return cmp_list, read_seq + + +""" +Use Stranded-seq reads to resolve assembly ambiguity +""" +def stranded_seq_alignment(genome_name, + sra_run_info, + ex_path, + ref_allele): + read_dir = sra_run_info.split('/')[:-1] + read_dir = '/'.join(read_dir) + runs = [] + for line in open(sra_run_info): + line = line.strip() + fields = line.split('\t') + genome_name_, run = fields[4], fields[0] + if genome_name == genome_name_: + runs.append(run) + + run_alignments = [] + for run in runs: + read_fname, out_fname = "%s/%s.extracted.fq.gz" % (read_dir, run), "%s/%s.bam" % (read_dir, run) + align_reads(ex_path, + "hisat2", + False, # simulation? + "hla", + "graph", + [read_fname], + True, # fastq? + 1, # number of threads + out_fname, + False) # verbose? + + # Read alignments + alignview_cmd = ["samtools", + "view", + out_fname] + base_locus = 0 + alignview_cmd += [ref_allele] + alignview_proc = subprocess.Popen(alignview_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + plus, minus = [], [] + # Cigar regular expression + cigar_re = re.compile('\d+\w') + pos_added = set() + for line in alignview_proc.stdout: + line = line.strip() + fields = line.split('\t') + read_id, flag, ref, pos, _, cigar_str = fields[:6] + flag = int(flag) + assert run == read_id.split('.')[0] + + if flag & 0x4 != 0: + continue + + Zs = "" + for i in range(11, len(fields)): + field = fields[i] + if field.startswith("Zs"): + Zs = field[5:] + + vars = [] + if Zs != "": + for var in Zs.split(','): + _, _, var = var.split('|') + vars.append(var) + + left_pos = int(pos) - 1 + if left_pos in pos_added: + continue + pos_added.add(left_pos) + right_pos = left_pos + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + for i in range(len(cigars)): + cigar_op, length = cigars[i] + if cigar_op in "MND": + right_pos += length + + entry = [left_pos, right_pos, vars] + if flag & 0x10 == 0: + plus.append(entry) + else: + minus.append(entry) + + if len(plus) > 0 and len(minus) > 0: + if len(plus) > 1 or len(minus) > 1: + run_alignments.append([run, plus, minus]) + + return run_alignments + + +""" +""" +def typing(ex_path, + simulation, + base_fname, + locus_list, + partial, + partial_alleles, + refGenes, + Genes, + Gene_names, + Gene_lengths, + refGene_loci, + Vars, + Var_list, + Links, + aligners, + num_editdist, + assembly, + output_base, + error_correction, + allow_discordant, + display_alleles, + stranded_seq, + fastq, + read_fname, + alignment_fname, + num_frag_list, + threads, + best_alleles, + verbose): + if simulation: + test_passed = {} + report_file = open(output_base + ".report", 'w') + for aligner, index_type in aligners: + for f_ in [sys.stderr, report_file]: + if index_type == "graph": + print >> f_, "\n\t\t%s %s" % (aligner, index_type) + else: + print >> f_, "\n\t\t%s %s" % (aligner, index_type) + + remove_alignment_file = False + if alignment_fname == "": + # Align reads, and sort the alignments into a BAM file + remove_alignment_file = True + if simulation: + alignment_fname = "%s_output.bam" % base_fname + else: + alignment_fname = read_fname[0].split('/')[-1] + alignment_fname = alignment_fname.split('.')[0] + ".bam" + + align_reads(ex_path, + aligner, + simulation, + base_fname, + index_type, + read_fname, + fastq, + threads, + alignment_fname, + verbose) + + for test_Gene_names in locus_list: + if simulation: + gene = test_Gene_names[0].split('*')[0] + else: + gene = test_Gene_names + ref_allele = refGenes[gene] + ref_seq = Genes[gene][ref_allele] + ref_exons = refGene_loci[gene][-1] + + novel_var_count = 0 + gene_vars, gene_var_list = deepcopy(Vars[gene]), deepcopy(Var_list[gene]) + var_count = {} + def add_novel_var(gene_vars, + gene_var_list, + novel_var_count, + var_type, + var_pos, + var_data): + var_idx = lower_bound(gene_var_list, var_pos) + while var_idx < len(gene_var_list): + pos_, id_ = gene_var_list[var_idx] + if pos_ > var_pos: + break + if pos_ == var_pos: + type_, _, data_ = gene_vars[id_] + assert type_ != var_type or data_ != var_data + if type_ != var_type: + if var_type == "insertion": + break + elif var_type == "single" and type_ == "deletion": + break + else: + if var_data < data_: + break + var_idx += 1 + var_id = "nv%d" % novel_var_count + assert var_id not in gene_vars + gene_vars[var_id] = [var_type, var_pos, var_data] + gene_var_list.insert(var_idx, [var_pos, var_id]) + return var_id, novel_var_count + 1 + + if not os.path.exists(alignment_fname + ".bai"): + os.system("samtools index %s" % alignment_fname) + # Read alignments + alignview_cmd = ["samtools", + "view", + alignment_fname] + base_locus = 0 + if index_type == "graph": + alignview_cmd += [ref_allele] + mpileup = get_mpileup(alignview_cmd, + ref_seq, + base_locus, + gene_vars, + allow_discordant) + + bamview_proc = subprocess.Popen(alignview_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + sort_read_cmd = ["sort", "-k", "1,1", "-s"] # -s for stable sorting + alignview_proc = subprocess.Popen(sort_read_cmd, + stdin=bamview_proc.stdout, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + else: + alignview_proc = subprocess.Popen(alignview_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + # List of nodes that represent alleles + allele_vars = {} + for var_id, allele_list in Links.items(): + for allele_id in allele_list: + if allele_id not in Genes[gene]: + continue + if allele_id not in allele_vars: + allele_vars[allele_id] = [var_id] + else: + allele_vars[allele_id].append(var_id) + + # Extract variants that are within exons + exon_vars = get_exonic_vars(gene_vars, ref_exons) + + # Store nodes that represent alleles + allele_nodes = {} + def create_allele_node(allele_name): + if allele_name in allele_nodes: + return allele_nodes[allele_name] + if allele_name in allele_vars: + var_ids = allele_vars[allele_name] + else: + var_ids = [] + seq = list(ref_seq) # sequence that node represents + var = ["" for i in range(len(ref_seq))] # how sequence is related to backbone + for var_id in var_ids: + assert var_id in gene_vars + var_type, var_pos, var_data = gene_vars[var_id] + assert var_pos >= 0 and var_pos < len(ref_seq) + if var_type == "single": + seq[var_pos] = var_data + var[var_pos] = var_id + elif var_type == "deletion": + del_len = int(var_data) + assert var_pos + del_len <= len(ref_seq) + seq[var_pos:var_pos + del_len] = ['D'] * del_len + var[var_pos:var_pos + del_len] = [var_id] * del_len + else: + # DK - to be implemented for insertions + assert var_type == "insertion" + None + + qual = ' ' * len(seq) + allele_node = assembly_graph.Node(allele_name, + 0, + seq, + qual, + var, + ref_seq, + gene_vars, + mpileup, + simulation) + allele_nodes[allele_name] = allele_node + return allele_node + + true_allele_nodes = {} + if simulation: + for allele_name in test_Gene_names: + true_allele_nodes[allele_name] = create_allele_node(allele_name) + + display_allele_nodes = {} + for display_allele in display_alleles: + display_allele_nodes[display_allele] = create_allele_node(display_allele) + + # Assembly graph + asm_graph = assembly_graph.Graph(ref_seq, + gene_vars, + ref_exons, + partial_alleles, + true_allele_nodes, + {}, # predicted_allele_nodes, which is empty for now + display_allele_nodes, + simulation) + + # Choose allele representives from those that share the same exonic sequences + allele_reps, allele_rep_groups = get_rep_alleles(Links, exon_vars) + allele_rep_set = set(allele_reps.values()) + + # For checking alternative alignments near the ends of alignments + Alts_left, Alts_right = get_alternatives(ref_seq, gene_vars, gene_var_list, verbose) + + # Count alleles + Gene_counts, Gene_cmpt = {}, {} + Gene_gen_counts, Gene_gen_cmpt = {}, {} + num_reads, total_read_len = 0, 0 + + # For debugging purposes + debug_allele_names = set(test_Gene_names) if simulation and verbose >= 2 else set() + + # Read information + prev_read_id = None + prev_right_pos = 0 + prev_lines = [] + left_read_ids, right_read_ids = set(), set() + if index_type == "graph": + # nodes for reads + read_nodes = [] + read_vars_list = [] + + # Cigar regular expression + cigar_re = re.compile('\d+\w') + for line in alignview_proc.stdout: + line = line.strip() + cols = line.split() + read_id, flag, chr, pos, mapQ, cigar_str = cols[:6] + node_read_id = orig_read_id = read_id + if simulation: + read_id = read_id.split('|')[0] + read_seq, read_qual = cols[9], cols[10] + total_read_len += len(read_seq) + flag, pos = int(flag), int(pos) + pos -= (base_locus + 1) + if pos < 0: + continue + + # Unalined? + if flag & 0x4 != 0: + if simulation and verbose >= 2: + print "Unaligned" + print "\t", line + continue + + # Concordantly mapped? + if flag & 0x2 != 0: + concordant = True + else: + concordant = False + + NM, Zs, MD, NH = "", "", "", "" + for i in range(11, len(cols)): + col = cols[i] + if col.startswith("Zs"): + Zs = col[5:] + elif col.startswith("MD"): + MD = col[5:] + elif col.startswith("NM"): + NM = int(col[5:]) + elif col.startswith("NH"): + NH = int(col[5:]) + + if NM > num_editdist: + continue + + # Only consider unique alignment + if NH > 1: + continue + + # Concordantly aligned mate pairs + if not allow_discordant and not concordant: + continue + + # Left read? + if flag & 0x40 != 0: + if read_id in left_read_ids: + continue + left_read_ids.add(read_id) + if not simulation: + node_read_id += '|L' + else: # Right read? + assert flag & 0x80 != 0 + if read_id in right_read_ids: + continue + right_read_ids.add(read_id) + if not simulation: + node_read_id += '|R' + + if Zs: + Zs = Zs.split(',') + + assert MD != "" + MD_str_pos, MD_len = 0, 0 + Zs_pos, Zs_i = 0, 0 + for _i in range(len(Zs)): + Zs[_i] = Zs[_i].split('|') + Zs[_i][0] = int(Zs[_i][0]) + if Zs_i < len(Zs): + Zs_pos += Zs[Zs_i][0] + read_pos, left_pos = 0, pos + right_pos = left_pos + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + cmp_list = [] + + likely_misalignment = False + + # Extract variants w.r.t backbone from CIGAR string + softclip = [0, 0] + for i in range(len(cigars)): + cigar_op, length = cigars[i] + if cigar_op == 'M': + first = True + MD_len_used = 0 + cmp_list_i = len(cmp_list) + while True: + if not first or MD_len == 0: + if MD[MD_str_pos].isdigit(): + num = int(MD[MD_str_pos]) + MD_str_pos += 1 + while MD_str_pos < len(MD): + if MD[MD_str_pos].isdigit(): + num = num * 10 + int(MD[MD_str_pos]) + MD_str_pos += 1 + else: + break + MD_len += num + # Insertion or full match followed + if MD_len >= length: + MD_len -= length + if length > MD_len_used: + cmp_list.append(["match", right_pos + MD_len_used, length - MD_len_used]) + break + first = False + read_base = read_seq[read_pos + MD_len] + MD_ref_base = MD[MD_str_pos] + MD_str_pos += 1 + assert MD_ref_base in "ACGT" + if MD_len > MD_len_used: + cmp_list.append(["match", right_pos + MD_len_used, MD_len - MD_len_used]) + + _var_id = "unknown" + if read_pos + MD_len == Zs_pos and Zs_i < len(Zs): + assert Zs[Zs_i][1] == 'S' + _var_id = Zs[Zs_i][2] + Zs_i += 1 + Zs_pos += 1 + if Zs_i < len(Zs): + Zs_pos += Zs[Zs_i][0] + else: + # Search for a known (yet not indexed) variant or a novel variant + ref_pos = right_pos + MD_len + var_idx = lower_bound(gene_var_list, ref_pos) + while var_idx < len(gene_var_list): + var_pos, var_id = gene_var_list[var_idx] + if var_pos > ref_pos: + break + if var_pos == ref_pos: + var_type, _, var_data = gene_vars[var_id] + if var_type == "single" and var_data == read_base: + _var_id = var_id + break + var_idx += 1 + + cmp_list.append(["mismatch", right_pos + MD_len, 1, _var_id]) + MD_len_used = MD_len + 1 + MD_len += 1 + # Full match + if MD_len == length: + MD_len = 0 + break + + # Correction for sequencing errors and update for cmp_list + if error_correction: + assert cmp_list_i < len(cmp_list) + new_cmp_list, read_seq = error_correct(ref_seq, + read_seq, + read_pos, + mpileup, + gene_vars, + gene_var_list, + cmp_list[cmp_list_i:], + node_read_id == "#HSQ1008:176:D0UYCACXX:4:1304:19006:96208|R") + cmp_list = cmp_list[:cmp_list_i] + new_cmp_list + + elif cigar_op == 'I': + _var_id = "unknown" + if read_pos == Zs_pos and Zs_i < len(Zs): + assert Zs[Zs_i][1] == 'I' + _var_id = Zs[Zs_i][2] + Zs_i += 1 + if Zs_i < len(Zs): + Zs_pos += Zs[Zs_i][0] + else: + # Search for a known (yet not indexed) variant or a novel variant + var_idx = lower_bound(gene_var_list, right_pos) + while var_idx < len(gene_var_list): + var_pos, var_id = gene_var_list[var_idx] + if var_pos > right_pos: + break + if var_pos == right_pos: + var_type, _, var_data = gene_vars[var_id] + if var_type == "insertion" and len(var_data) == length: + _var_id = var_id + break + var_idx += 1 + cmp_list.append(["insertion", right_pos, length, _var_id]) + if 'N' in read_seq[read_pos:read_pos+length]: + likely_misalignment = True + + elif cigar_op == 'D': + if MD[MD_str_pos] == '0': + MD_str_pos += 1 + assert MD[MD_str_pos] == '^' + MD_str_pos += 1 + while MD_str_pos < len(MD): + if not MD[MD_str_pos] in "ACGT": + break + MD_str_pos += 1 + _var_id = "unknown" + if read_pos == Zs_pos and \ + Zs_i < len(Zs) and \ + Zs[Zs_i][1] == 'D': + _var_id = Zs[Zs_i][2] + Zs_i += 1 + if Zs_i < len(Zs): + Zs_pos += Zs[Zs_i][0] + else: + # Search for a known (yet not indexed) variant or a novel variant + var_idx = lower_bound(gene_var_list, right_pos) + while var_idx < len(gene_var_list): + var_pos, var_id = gene_var_list[var_idx] + if var_pos > right_pos: + break + if var_pos == right_pos: + var_type, _, var_data = gene_vars[var_id] + if var_type == "deletion" and int(var_data) == length: + _var_id = var_id + break + var_idx += 1 + + cmp_list.append(["deletion", right_pos, length, _var_id]) + + # Check if this deletion is artificial alignment + assert right_pos < mpileup + del_count, nt_count = 0, 0 + for nt, value in mpileup[right_pos][1].items(): + count = value[0] + if nt == 'D': + del_count += count + else: + nt_count += count + # DK - debugging purposes + if del_count * 6 < nt_count: # and nt_count >= 15: + likely_misalignment = True + + elif cigar_op == 'S': + if i == 0: + softclip[0] = length + Zs_pos += length + else: + assert i + 1 == len(cigars) + softclip[1] = length + else: + assert cigar_op == 'N' + assert False + cmp_list.append(["intron", right_pos, length]) + + if cigar_op in "MND": + right_pos += length + + if cigar_op in "MIS": + read_pos += length + + # Remove softclip in cigar and modify read_seq and read_qual accordingly + if sum(softclip) > 0: + if softclip[0] > 0: + cigars = cigars[1:] + read_seq = read_seq[softclip[0]:] + read_qual = read_qual[softclip[0]:] + if softclip[1] > 0: + cigars = cigars[:-1] + read_seq = read_seq[:-softclip[1]] + read_qual = read_qual[:-softclip[1]] + + cigar_str = "" + for type, length in cigars: + cigar_str += str(length) + cigar_str += type + + if right_pos > len(ref_seq): + continue + + if likely_misalignment: + continue + + # Add novel variants + read_pos = 0 + for cmp_i in range(len(cmp_list)): + type_, pos_, length_ = cmp_list[cmp_i][:3] + if type_ != "match": + var_id_ = cmp_list[cmp_i][3] + if var_id_ == "unknown": + add = True + if type_ == "mismatch": + data_ = read_seq[read_pos] + if data_ == 'N': + add = False + elif type_ == "deletion": + data_ = str(length_) + else: + assert type_ == "insertion" + data_ = read_seq[read_pos:read_pos + length_] + if add: + var_id, novel_var_count = add_novel_var(gene_vars, + gene_var_list, + novel_var_count, + type_ if type_ != "mismatch" else "single", + pos_, + data_) + cmp_list[cmp_i][3] = var_id + if var_id not in var_count: + var_count[var_id] = 1 + else: + var_count[var_id] += 1 + + if type_ != "deletion": + read_pos += length_ + + # Count the number of reads aligned uniquely with some constraints + num_reads += 1 + + def add_stat(Gene_cmpt, Gene_counts, Gene_count_per_read, include_alleles = set()): + max_count = max(Gene_count_per_read.values()) + cur_cmpt = set() + for allele, count in Gene_count_per_read.items(): + if count < max_count: + continue + + if len(include_alleles) > 0 and allele not in include_alleles: + continue + + cur_cmpt.add(allele) + if allele not in Gene_counts: + Gene_counts[allele] = 1 + else: + Gene_counts[allele] += 1 + + if len(cur_cmpt) == 0: + return "" + + # DK - for debugging purposes + alleles = ["", ""] + # alleles = ["A*24:36N", "A*24:359N"] + allele1_found, allele2_found = False, False + if alleles[0] != "": + for allele, count in Gene_count_per_read.items(): + if count < max_count: + continue + if allele == alleles[0]: + allele1_found = True + elif allele == alleles[1]: + allele2_found = True + if allele1_found != allele2_found: + print alleles[0], Gene_count_per_read[alleles[0]] + print alleles[1], Gene_count_per_read[alleles[1]] + if allele1_found: + print ("%s\tread_id %s - %d vs. %d]" % (alleles[0], prev_read_id, max_count, Gene_count_per_read[alleles[1]])) + else: + print ("%s\tread_id %s - %d vs. %d]" % (alleles[1], prev_read_id, max_count, Gene_count_per_read[alleles[0]])) + print read_seq + + cur_cmpt = sorted(list(cur_cmpt)) + cur_cmpt = '-'.join(cur_cmpt) + if not cur_cmpt in Gene_cmpt: + Gene_cmpt[cur_cmpt] = 1 + else: + Gene_cmpt[cur_cmpt] += 1 + + return cur_cmpt + + if read_id != prev_read_id: + if prev_read_id != None: + + # DK - debugging purpose + debug_allele_id = "A*24:355" + assert debug_allele_id in Gene_count_per_read + debug_max_read_count = max(Gene_count_per_read.values()) + debug_read_count = Gene_count_per_read[debug_allele_id] + if debug_read_count == debug_max_read_count and \ + Gene_count_per_read["A*24:02:01:02L"] < debug_max_read_count and \ + Gene_count_per_read["A*01:01:01:01"] < debug_max_read_count: + print prev_read_id + None + + if prev_read_id == "HSQ1008:175:C0JVFACXX:7:1208:5604:41201": + None + """ + for line in prev_lines: + print line + print Gene_count_per_read[debug_allele_id], max(Gene_count_per_read.values()) + print Gene_gen_count_per_read[debug_allele_id], max(Gene_gen_count_per_read.values()) + + for allele_id, count in Gene_count_per_read.items(): + if count == debug_max_read_count: + print "allele max:", allele_id, count + """ + + if base_fname == "hla": + cur_cmpt = add_stat(Gene_cmpt, Gene_counts, Gene_count_per_read, allele_rep_set) + add_stat(Gene_gen_cmpt, Gene_gen_counts, Gene_gen_count_per_read) + for read_id_, read_node in read_nodes: + asm_graph.add_node(read_id_, + read_node, + simulation) + read_nodes, read_var_list = [], [] + if simulation and \ + verbose >= 2 and \ + base_fname == "hla": + cur_cmpt = cur_cmpt.split('-') + if not(set(cur_cmpt) & set(test_Gene_names)): + print "%s are chosen instead of %s" % ('-'.join(cur_cmpt), '-'.join(test_Gene_names)) + for prev_line in prev_lines: + print "\t", prev_line + + prev_lines = [] + + Gene_count_per_read, Gene_gen_count_per_read = {}, {} + for Gene_name in Gene_names[gene]: + if Gene_name.find("BACKBONE") != -1: + continue + Gene_count_per_read[Gene_name] = 0 + Gene_gen_count_per_read[Gene_name] = 0 + + prev_lines.append(line) + + def add_count(count_per_read, var_id, add): + alleles = Links[var_id] + if verbose >= 2: + if add > 0 and not (set(alleles) & debug_allele_names): + print "Add:", add, debug_allele_names, "-", var_id + print "\t", line + print "\t", alleles + if add < 0 and set(alleles) & debug_allele_names: + print "Add:", add, debug_allele_names, "-", var_id + print "\t", line + + for allele in alleles: + count_per_read[allele] += add + + # Decide which allele(s) a read most likely came from + for var_id, data in gene_vars.items(): + if var_id == "unknown" or var_id.startswith("nv"): + continue + var_type, var_pos, var_data = data + if var_type != "deletion": + continue + if left_pos >= var_pos and right_pos <= var_pos + int(var_data): + if var_id in exon_vars: + add_count(Gene_count_per_read, var_id, -1) + add_count(Gene_gen_count_per_read, var_id, -1) + + # Node + read_node_pos, read_node_seq, read_node_qual, read_node_var = -1, [], [], [] + read_vars = [] + + # Positive and negative evidence + positive_vars, negative_vars = set(), set() + + # Sanity check - read length, cigar string, and MD string + ref_pos, read_pos, cmp_cigar_str, cmp_MD = left_pos, 0, "", "" + cigar_match_len, MD_match_len = 0, 0 + + cmp_list_left, cmp_list_right = identify_ambigious_diffs(gene_vars, + Alts_left, + Alts_right, + cmp_list, + verbose, + orig_read_id == "a45|L_441_89M8D11M_89|D|hv1,7|S|hv15") # debug? + + # DK - debugging purposes + DK_debug = False + if orig_read_id == "a46|L_451_88M12D12M_88|D|hv2": + DK_debug = True + print line + print cmp_list + print "positive vars:", positive_vars + print "negative vars:", negative_vars + print "cmp_list[%d, %d]" % (cmp_list_left, cmp_list_right) + + # Deletions at 5' and 3' ends + for var_id, data in gene_vars.items(): + var_type, var_pos, var_data = data + if var_type != "deletion": + continue + if left_pos >= var_pos and right_pos <= var_pos + int(var_data): + negative_vars.add(var_id) + + cmp_i = 0 + while cmp_i < len(cmp_list): + cmp = cmp_list[cmp_i] + type, length = cmp[0], cmp[2] + # Disable the following sanity check due to error correction + # if num_editdist == 0 and type in ["mismatch", "deletion", "insertion"]: + # assert cmp[3] != "unknown" + + if type in ["match", "mismatch"]: + if read_node_pos < 0: + read_node_pos = ref_pos + + if type == "match": + read_node_seq += list(read_seq[read_pos:read_pos+length]) + read_node_qual += list(read_qual[read_pos:read_pos+length]) + read_node_var += ([''] * length) + + var_idx = lower_bound(gene_var_list, ref_pos) + while var_idx < len(gene_var_list): + var_pos, var_id = gene_var_list[var_idx] + if ref_pos + length <= var_pos: + break + if ref_pos <= var_pos: + var_type, _, var_data = gene_vars[var_id] + if var_type == "insertion": + if ref_pos < var_pos and ref_pos + length > var_pos + len(var_data): + negative_vars.add(var_id) + elif var_type == "deletion": + del_len = int(var_data) + if ref_pos < var_pos and ref_pos + length > var_pos + del_len: + if base_fname == "codis": + cmp_left, cmp_right = left_pos, right_pos + else: + cmp_left, cmp_right = cmp[1], cmp[1] + cmp[2] + + # Check if this might be one of the two tandem repeats (the same left coordinate) + test1_seq1 = ref_seq[cmp_left:cmp_right] + test1_seq2 = ref_seq[cmp_left:var_pos] + ref_seq[var_pos + del_len:cmp_right + del_len] + # Check if this happens due to small repeats (the same right coordinate - e.g. 19 times of TTTC in DQA1*05:05:01:02) + cmp_left -= read_pos + cmp_right += (len(read_seq) - read_pos - cmp[2]) + test2_seq1 = ref_seq[cmp_left+int(var_data):cmp_right] + test2_seq2 = ref_seq[cmp_left:var_pos] + ref_seq[var_pos+int(var_data):cmp_right] + + if test1_seq1 != test1_seq2 and test2_seq1 != test2_seq2: + negative_vars.add(var_id) + else: + negative_vars.add(var_id) + var_idx += 1 + read_pos += length + ref_pos += length + cigar_match_len += length + MD_match_len += length + elif type == "mismatch": + var_id = cmp[3] + read_base, qual = read_seq[read_pos], read_qual[read_pos] + read_node_seq += [read_base] + read_node_qual += [qual] + read_node_var.append(var_id) + if var_id != "unknown": + if cmp_i >= cmp_list_left and cmp_i <= cmp_list_right: + positive_vars.add(var_id) + + if read_id == "HSQ1008:175:C0JVFACXX:6:2207:13481:60924" and False: + print "add positive var:", var_id + print "\tcmp_list:", cmp_list_left, cmp_list_right, cmp_list + + + cmp_MD += ("%d%s" % (MD_match_len, ref_seq[ref_pos])) + MD_match_len = 0 + cigar_match_len += 1 + read_pos += 1 + ref_pos += 1 + elif type == "insertion": + var_id = cmp[3] + ins_len = length + ins_seq = read_seq[read_pos:read_pos+ins_len] + if var_id != "unknown" or not var_id.startswith("nv"): + if cmp_i >= cmp_list_left and cmp_i <= cmp_list_right: + # Require at least 5bp match before and after a deletion + if read_pos >= 5 and read_pos + 5 <= len(read_seq): + positive_vars.add(var_id) + read_node_seq += ["I%s" % nt for nt in ins_seq] + read_node_qual += list(read_qual[read_pos:read_pos+ins_len]) + read_node_var += ([var_id] * ins_len) + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cigar_match_len = 0 + read_pos += length + cmp_cigar_str += ("%dI" % length) + elif type == "deletion": + var_id = cmp[3] + alt_match = False + del_len = length + read_node_seq += (['D'] * del_len) + read_node_qual += ([''] * del_len) + if var_id != "unknown" or not var_id.statswith("nv"): + if cmp_i >= cmp_list_left and cmp_i <= cmp_list_right: + # Require at least 5bp match before and after a deletion + if read_pos >= 5 and read_pos + 5 <= len(read_seq): + positive_vars.add(var_id) + + if len(read_node_seq) > len(read_node_var): + assert len(read_node_seq) == len(read_node_var) + del_len + read_node_var += ([var_id] * del_len) + + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cigar_match_len = 0 + cmp_MD += ("%d" % MD_match_len) + MD_match_len = 0 + cmp_cigar_str += ("%dD" % length) + cmp_MD += ("^%s" % ref_seq[ref_pos:ref_pos+length]) + ref_pos += length + else: + assert type == "intron" + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cigar_match_len = 0 + cmp_cigar_str += ("%dN" % length) + ref_pos += length + + cmp_i += 1 + + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cmp_MD += ("%d" % MD_match_len) + # Sanity check + if read_pos != len(read_seq) or \ + cmp_cigar_str != cigar_str: + # cmp_MD != MD: # Disabled due to error correction + print >> sys.stderr, "Error:", cigar_str, MD + print >> sys.stderr, "\tcomputed:", cmp_cigar_str, cmp_MD + print >> sys.stderr, "\tcmp list:", cmp_list + assert False + + # DK - debugging purposes + if DK_debug: + print "positive:", positive_vars + print "negative:", negative_vars + + # Node + if assembly: + read_nodes.append([node_read_id, + assembly_graph.Node(node_read_id, + read_node_pos, + read_node_seq, + read_node_qual, + read_node_var, + ref_seq, + gene_vars, + mpileup, + simulation)]) + + for positive_var in positive_vars: + if positive_var == "unknown" or positive_var.startswith("nv"): + continue + if positive_var in exon_vars: + add_count(Gene_count_per_read, positive_var, 1) + add_count(Gene_gen_count_per_read, positive_var, 1) + + if read_id == "HSQ1008:175:C0JVFACXX:6:2207:13481:60924" and False: + print "positive_vars:", positive_vars + print "negative_vars:", negative_vars + + + for negative_var in negative_vars: + if negative_var == "unknown" or negative_var.startswith("nv"): + continue + if negative_var in exon_vars: + add_count(Gene_count_per_read, negative_var, -1) + add_count(Gene_gen_count_per_read, negative_var, -1) + + prev_read_id = read_id + prev_right_pos = right_pos + + if num_reads <= 0: + continue + + for f_ in [sys.stderr, report_file]: + print >> f_, "\t\t\tNumber of reads aligned: %d" % num_reads + + if prev_read_id != None: + if base_fname == "hla": + add_stat(Gene_cmpt, Gene_counts, Gene_count_per_read, allele_rep_set) + add_stat(Gene_gen_cmpt, Gene_gen_counts, Gene_gen_count_per_read) + for read_id_, read_node in read_nodes: + asm_graph.add_node(read_id_, + read_node, + simulation) + read_nodes, read_var_list = [], [] + + else: + assert index_type == "linear" + def add_alleles(alleles): + if not allele in Gene_counts: + Gene_counts[allele] = 1 + else: + Gene_counts[allele] += 1 + + cur_cmpt = sorted(list(alleles)) + cur_cmpt = '-'.join(cur_cmpt) + if not cur_cmpt in Gene_cmpt: + Gene_cmpt[cur_cmpt] = 1 + else: + Gene_cmpt[cur_cmpt] += 1 + + prev_read_id, prev_AS = None, None + alleles = set() + for line in alignview_proc.stdout: + cols = line[:-1].split() + read_id, flag, allele = cols[:3] + flag = int(flag) + if flag & 0x4 != 0: + continue + if not allele.startswith(gene): + continue + if allele.find("BACKBONE") != -1: + continue + + AS = None + for i in range(11, len(cols)): + col = cols[i] + if col.startswith("AS"): + AS = int(col[5:]) + assert AS != None + if read_id != prev_read_id: + if alleles: + if aligner == "hisat2" or \ + (aligner == "bowtie2" and len(alleles) < 10): + add_alleles(alleles) + alleles = set() + prev_AS = None + if prev_AS != None and AS < prev_AS: + continue + prev_read_id = read_id + prev_AS = AS + alleles.add(allele) + + if alleles: + add_alleles(alleles) + + if base_fname != "hla": + Gene_counts = Gene_gen_counts + Gene_counts = [[allele, count] for allele, count in Gene_counts.items()] + def Gene_count_cmp(a, b): + if a[1] != b[1]: + return b[1] - a[1] + assert a[0] != b[0] + if a[0] < b[0]: + return -1 + else: + return 1 + Gene_counts = sorted(Gene_counts, cmp=Gene_count_cmp) + for count_i in range(len(Gene_counts)): + count = Gene_counts[count_i] + if simulation: + found = False + for test_Gene_name in test_Gene_names: + if count[0] == test_Gene_name: + for f_ in [sys.stderr, report_file]: + print >> f_, "\t\t\t*** %d ranked %s (count: %d)" % (count_i + 1, test_Gene_name, count[1]) + found = True + """ + if count_i > 0 and Gene_counts[0][1] > count[1]: + print >> sys.stderr, "Warning: %s ranked first (count: %d)" % (Gene_counts[0][0], Gene_counts[0][1]) + assert False + else: + test_passed += 1 + """ + if count_i < 5 and not found: + for f_ in [sys.stderr, report_file]: + print >> f_, "\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1]) + else: + for f_ in [sys.stderr, report_file]: + print >> f_, "\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1]) + if count_i >= 9: + break + for f_ in [sys.stderr, report_file]: + print >> f_ + + # Calculate the abundance of representative alleles on exonic sequences + if base_fname == "hla": + # Incorporate non representative alleles (full length alleles) + Gene_prob = single_abundance(Gene_cmpt, Gene_lengths[gene]) + gen_alleles = set() + gen_prob_sum = 0.0 + for prob_i in range(len(Gene_prob)): + allele, prob = Gene_prob[prob_i][:2] + if prob_i >= 10 and prob < 0.03: + break + if allele in partial_alleles: + continue + + gen_prob_sum += prob + for allele2 in allele_rep_groups[allele]: + gen_alleles.add(allele2) + + if len(gen_alleles) > 0: + Gene_gen_cmpt2 = {} + for cmpt, value in Gene_gen_cmpt.items(): + cmpt2 = [] + for allele in cmpt.split('-'): + if allele in gen_alleles: + cmpt2.append(allele) + if len(cmpt2) == 0: + continue + cmpt2 = '-'.join(cmpt2) + if cmpt2 not in Gene_gen_cmpt2: + Gene_gen_cmpt2[cmpt2] = value + else: + Gene_gen_cmpt2[cmpt2] += value + Gene_gen_cmpt = Gene_gen_cmpt2 + Gene_gen_prob = single_abundance(Gene_gen_cmpt, Gene_lengths[gene]) + + Gene_combined_prob = {} + for allele, prob in Gene_prob: + assert allele not in Gene_combined_prob + if allele in gen_alleles: + Gene_combined_prob[allele] = 0.0 + else: + Gene_combined_prob[allele] = prob + for allele, prob in Gene_gen_prob: + Gene_combined_prob[allele] = prob * gen_prob_sum + Gene_prob = [[allele, prob] for allele, prob in Gene_combined_prob.items()] + Gene_prob = sorted(Gene_prob, cmp=Gene_prob_cmp) + else: + Gene_prob = single_abundance(Gene_gen_cmpt, Gene_lengths[gene]) + + if index_type == "graph" and assembly: + allele_node_order = [] + predicted_allele_nodes = {} + for allele_name, prob in Gene_prob: + if prob < 0.1: # abundance of 10% + break + predicted_allele_nodes[allele_name] = create_allele_node(allele_name) + allele_node_order.append([allele_name, prob]) + if len(predicted_allele_nodes) >= 2: + break + asm_graph.predicted_allele_nodes = predicted_allele_nodes + asm_graph.allele_node_order = allele_node_order + + # Start drawing assembly graph + asm_graph.begin_draw(output_base) + + # Draw assembly graph + begin_y = asm_graph.draw(0, "Initial graph") + begin_y += 200 + + # Apply De Bruijn graph + asm_graph.guided_DeBruijn() + + # Draw assembly graph + begin_y = asm_graph.draw(begin_y, "Asssembly") + begin_y += 200 + + # Stranded-seq read analysis + if len(stranded_seq) == 2: + run_alignments = stranded_seq_alignment(stranded_seq[0], + stranded_seq[1], + ex_path, + ref_allele) + + def get_best_alleles(left, right, vars): + max_alleles, max_common = [], -sys.maxint + for allele_name, allele_node in predicted_allele_nodes.items(): + tmp_vars = allele_node.get_var_ids(left, right) + tmp_common = len(set(vars) & set(tmp_vars)) + tmp_common -= len(set(vars) | set(tmp_vars)) + if max_common < tmp_common: + max_common = tmp_common + max_alleles = [[allele_name, max_common]] + elif max_common == tmp_common: + max_alleles.append([allele_name, max_common]) + return max_alleles + + for run, plus, minus in run_alignments: + print run + print "\tplus:" + for left, right, vars in plus: + print "\t\t", left, right, vars, get_best_alleles(left, right, vars) + print "\tminus:" + for left, right, vars in minus: + print "\t\t", left, right, vars, get_best_alleles(left, right, vars) + + assert False + + + # DK - debugging purposes + # """ + + # Draw assembly graph + asm_graph.nodes = asm_graph.nodes2 + asm_graph.to_node, asm_graph.from_node = {}, {} + begin_y = asm_graph.draw(begin_y, "Assembly with known alleles") + + # """ + + # End drawing assembly graph + asm_graph.end_draw() + + # Compare two alleles + if simulation and len(test_Gene_names) == 2: + allele_name1, allele_name2 = test_Gene_names + print >> sys.stderr, allele_name1, "vs.", allele_name2 + asm_graph.print_node_comparison(asm_graph.true_allele_nodes) + + def compare_alleles(vars1, vars2, print_output = True): + skip = True + var_i, var_j = 0, 0 + exon_i = 0 + mismatches = 0 + while var_i < len(vars1) and var_j < len(vars2): + cmp_var_id, node_var_id = vars1[var_i], vars2[var_j] + cmp_var, node_var = gene_vars[cmp_var_id], gene_vars[node_var_id] + + min_pos = min(cmp_var[1], node_var[1]) + cmp_var_in_exon, node_var_in_exon = False, False + while exon_i < len(ref_exons): + exon_left, exon_right = ref_exons[exon_i] + if min_pos <= exon_right: + if cmp_var[1] >= exon_left and cmp_var[1] <= exon_right: + cmp_var_in_exon = True + else: + cmp_var_in_exon = False + if node_var[1] >= exon_left and node_var[1] <= exon_right: + node_var_in_exon = True + else: + node_var_in_exon = False + break + exon_i += 1 + + if cmp_var_id == node_var_id: + skip = False + if print_output: + if cmp_var_in_exon: + print >> sys.stderr, "\033[94mexon%d\033[00m" % (exon_i + 1), + print >> sys.stderr, cmp_var_id, cmp_var, "\t\t\t", mpileup[cmp_var[1]] + var_i += 1; var_j += 1 + continue + if cmp_var[1] <= node_var[1]: + if not skip: + if (var_i > 0 and var_i + 1 < len(vars1)) or cmp_var[0] != "deletion": + if print_output: + if cmp_var_in_exon: + for f_ in [sys.stderr, report_file]: + print >> f_, "\033[94mexon%d\033[00m" % (exon_i + 1), + for f_ in [sys.stderr, report_file]: + print >> f_, "***", cmp_var_id, cmp_var, "==", "\t\t\t", mpileup[cmp_var[1]] + mismatches += 1 + var_i += 1 + else: + if print_output: + if node_var_in_exon: + for f_ in [sys.stderr, report_file]: + print >> f_, "\033[94mexon%d\033[00m" % (exon_i + 1), + for f_ in [sys.stderr, report_file]: + print >> f_, "*** ==", node_var_id, node_var, "\t\t\t", mpileup[node_var[1]] + mismatches += 1 + var_j += 1 + + return mismatches + + tmp_nodes = asm_graph.nodes + print >> sys.stderr, "Number of tmp nodes:", len(tmp_nodes) + count = 0 + for id, node in tmp_nodes.items(): + count += 1 + if count > 10: + break + node_vars = node.get_var_ids() + node.print_info(); print >> sys.stderr + if node.id in asm_graph.to_node: + for id2, at in asm_graph.to_node[node.id]: + print >> sys.stderr, "\tat %d ==> %s" % (at, id2) + + if simulation: + cmp_Gene_names = test_Gene_names + else: + cmp_Gene_names = [allele_name for allele_name, _ in allele_node_order] + + alleles, cmp_vars, max_common = [], [], -sys.maxint + for cmp_Gene_name in cmp_Gene_names: + tmp_vars = allele_nodes[cmp_Gene_name].get_var_ids(node.left, node.right) + tmp_common = len(set(node_vars) & set(tmp_vars)) + tmp_common -= len(set(node_vars) | set(tmp_vars)) + if max_common < tmp_common: + max_common = tmp_common + alleles = [[cmp_Gene_name, tmp_vars]] + elif max_common == tmp_common: + alleles.append([cmp_Gene_name, tmp_vars]) + + for allele_name, cmp_vars in alleles: + for f_ in [sys.stderr, report_file]: + print >> f_, "vs.", allele_name + compare_alleles(cmp_vars, node_vars) + + print >> sys.stderr + print >> sys.stderr + + + # Identify alleles that perfectly or closesly match assembled alleles + for node_name, node in asm_graph.nodes.items(): + vars = set(node.get_var_ids()) + + max_allele_names, max_common = [], -sys.maxint + for allele_name, vars2 in allele_vars.items(): + vars2 = set(vars2) + tmp_common = len(vars & vars2) - len(vars | vars2) + if tmp_common > max_common: + max_common = tmp_common + max_allele_names = [allele_name] + elif tmp_common == max_common: + max_allele_names.append(allele_name) + + for f_ in [sys.stderr, report_file]: + print >> f_, "Genomic:", node_name + node_vars = node.get_var_ids() + min_mismatches = sys.maxint + for max_allele_name in max_allele_names: + cmp_vars = allele_vars[max_allele_name] + cmp_vars = sorted(cmp_vars, cmp=lambda a, b: int(a[2:]) - int(b[2:])) + print_output = False + tmp_mismatches = compare_alleles(cmp_vars, node_vars, print_output) + print >> f_, "\t\t%s:" % max_allele_name, max_common, tmp_mismatches + if tmp_mismatches < min_mismatches: + min_mismatches = tmp_mismatches + if min_mismatches > 0: + print >> f_, "Novel allele" + else: + print >> f_, "Known allele" + + """ + allele_exon_vars = {} + for allele_name, vars in allele_vars.items(): + allele_exon_vars[allele_name] = set(vars) & exon_vars + + for node_name, node in asm_graph.nodes.items(): + vars = [] + for left, right in ref_exons: + vars += node.get_var_ids(left, right) + vars = set(vars) & exon_vars + + max_allele_names, max_common = [], -sys.maxint + for allele_name, vars2 in allele_exon_vars.items(): + tmp_common = len(vars & vars2) - len(vars | vars2) + if tmp_common > max_common: + max_common = tmp_common + max_allele_names = [allele_name] + elif tmp_common == max_common: + max_allele_names.append(allele_name) + + for f_ in [sys.stderr, report_file]: + print >> f_, "Exonic:", node_name + for max_allele_name in max_allele_names: + print >> f_, "\t\t%s:" % max_allele_name, max_common + """ + + success = [False for i in range(len(test_Gene_names))] + found_list = [False for i in range(len(test_Gene_names))] + for prob_i in range(len(Gene_prob)): + prob = Gene_prob[prob_i] + found = False + _allele_rep = prob[0] + """ + if partial and exonic_only: + _fields = _allele_rep.split(':') + if len(_fields) == 4: + _allele_rep = ':'.join(_fields[:-1]) + """ + + if simulation: + for name_i in range(len(test_Gene_names)): + test_Gene_name = test_Gene_names[name_i] + if prob[0] == test_Gene_name: + rank_i = prob_i + while rank_i > 0: + if prob == Gene_prob[rank_i - 1][1]: + rank_i -= 1 + else: + break + for f_ in [sys.stderr, report_file]: + print >> f_, "\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, test_Gene_name, prob[1] * 100.0) + if rank_i < len(success): + success[rank_i] = True + found_list[name_i] = True + found = True + # DK - for debugging purposes + if not False in found_list and prob_i >= 10: + break + if not found: + for f_ in [sys.stderr, report_file]: + print >> f_, "\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, _allele_rep, prob[1] * 100.0) + if best_alleles and prob_i < 2: + for f_ in [sys.stderr, report_file]: + print >> f_, "SingleModel %s (abundance: %.2f%%)" % (_allele_rep, prob[1] * 100.0) + if not simulation and prob_i >= 9: + break + if prob_i >= 19: + break + print >> sys.stderr + + if simulation and not False in success: + aligner_type = "%s %s" % (aligner, index_type) + if not aligner_type in test_passed: + test_passed[aligner_type] = 1 + else: + test_passed[aligner_type] += 1 + + if remove_alignment_file and not simulation: + os.system("rm %s*" % (alignment_fname)) + + report_file.close() + if simulation: + return test_passed + + +""" +""" +def read_Gene_alleles(fname, Genes): + for line in open(fname): + if line.startswith(">"): + Gene_name = line.strip().split()[0][1:] + Gene_gene = Gene_name.split('*')[0] + if not Gene_gene in Genes: + Genes[Gene_gene] = {} + if not Gene_name in Genes[Gene_gene]: + Genes[Gene_gene][Gene_name] = "" + else: + Genes[Gene_gene][Gene_name] += line.strip() + return Genes + + +""" +""" +def read_Gene_vars(fname): + Vars, Var_list = {}, {} + for line in open(fname): + var_id, var_type, allele, pos, data = line.strip().split('\t') + pos = int(pos) + gene = allele.split('*')[0] + if not gene in Vars: + Vars[gene] = {} + assert not gene in Var_list + Var_list[gene] = [] + + assert not var_id in Vars[gene] + left = 0 + Vars[gene][var_id] = [var_type, pos - left, data] + Var_list[gene].append([pos - left, var_id]) + + for gene, in_var_list in Var_list.items(): + Var_list[gene] = sorted(in_var_list) + + return Vars, Var_list + + +""" +""" +def read_Gene_links(fname): + Links = {} + for line in open(fname): + var_id, alleles = line.strip().split('\t') + alleles = alleles.split() + assert not var_id in Links + Links[var_id] = alleles + + return Links + + +""" +""" +def construct_allele_seq(backbone_seq, var_ids, Vars): + allele_seq = list(backbone_seq) + for id in var_ids: + assert id in Vars + type, pos, data = Vars[id] + assert pos < len(allele_seq) + if type == "single": + assert allele_seq[pos] != data + allele_seq[pos] = data + else: + assert type == "deletion" + del_len = int(data) + assert pos + del_len <= len(allele_seq) + for i in range(pos, pos + del_len): + allele_seq[i] = '.' + + allele_seq = ''.join(allele_seq) + allele_seq = allele_seq.replace('.', '') + return allele_seq + + +""" +""" +def test_Gene_genotyping(base_fname, + locus_list, + partial, + aligners, + read_fname, + alignment_fname, + threads, + simulate_interval, + read_len, + fragment_len, + best_alleles, + num_editdist, + perbase_errorrate, + perbase_snprate, + skip_fragment_regions, + assembly, + output_base, + error_correction, + discordant, + display_alleles, + stranded_seq, + verbose, + debug_instr): + # Current script directory + curr_script = os.path.realpath(inspect.getsourcefile(test_Gene_genotyping)) + ex_path = os.path.dirname(curr_script) + + # Clone a git repository, IMGTHLA + if not os.path.exists("IMGTHLA"): + Gene_typing.clone_IMGTHLA_database() + + if not os.path.exists("hisatgenotype_db"): + typing_common.clone_hisatgenotype_database() + + simulation = (read_fname == [] and alignment_fname == "") + + # Download human genome and HISAT2 index + HISAT2_fnames = ["grch38", + "genome.fa", + "genome.fa.fai"] + if not typing_common.check_files(HISAT2_fnames): + typing_common.download_genome_and_index() + + # Check if the pre-existing files (hla*) are compatible with the current parameter setting + if os.path.exists("%s.ref" % base_fname): + left = 0 + Gene_genes = [] + BACKBONE = False + for line in open("%s.ref" % base_fname): + Gene_name = line.strip().split()[0] + if Gene_name.find("BACKBONE") != -1: + BACKBONE = True + Gene_gene = Gene_name.split('*')[0] + Gene_genes.append(Gene_gene) + delete_hla_files = False + if not BACKBONE: + delete_hla_files = True + if len(locus_list) == 0: + locus_list = Gene_genes + if not set(locus_list).issubset(set(Gene_genes)): + delete_hla_files = True + if delete_hla_files: + os.system("rm %s*" % base_fname) + + # Extract HLA variants, backbone sequence, and other sequeces + Gene_fnames = [base_fname + "_backbone.fa", + base_fname + "_sequences.fa", + base_fname + ".ref", + base_fname + ".snp", + base_fname + ".index.snp", + base_fname + ".haplotype", + base_fname + ".link"] + + if verbose >= 1: + print >> sys.stderr, Gene_fnames + + if not typing_common.check_files(Gene_fnames): + extract_hla_script = os.path.join(ex_path, "hisatgenotype_extract_vars.py") + extract_cmd = [extract_hla_script] + if len(locus_list) > 0: + extract_cmd += ["--locus-list", ','.join(locus_list)] + + extract_cmd += ["--base", base_fname] + + if not partial: + extract_cmd += ["--no-partial"] + extract_cmd += ["--inter-gap", "30", + "--intra-gap", "50"] + + # DK - debugging purposes + extract_cmd += ["--min-var-freq", "0.1"] + + if base_fname == "codis": + extract_cmd += ["--leftshift"] + + # DK - debugging purposes + # extract_cmd += ["--ext-seq", "300"] + if verbose >= 1: + print >> sys.stderr, "\tRunning:", ' '.join(extract_cmd) + proc = subprocess.Popen(extract_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w')) + proc.communicate() + + if not typing_common.check_files(Gene_fnames): + print >> sys.stderr, "Error: hisatgenotype_extract_vars failed!" + sys.exit(1) + + for aligner, index_type in aligners: + if aligner == "hisat2": + # Build HISAT2 graph indexes based on the above information + if index_type == "graph": + Gene_hisat2_graph_index_fnames = ["%s.graph.%d.ht2" % (base_fname, i+1) for i in range(8)] + if not typing_common.check_files(Gene_hisat2_graph_index_fnames): + hisat2_build = os.path.join(ex_path, "hisat2-build") + build_cmd = [hisat2_build, + "-p", str(threads), + "--snp", "%s.index.snp" % base_fname, + "--haplotype", "%s.haplotype" % base_fname, + "%s_backbone.fa" % base_fname, + "%s.graph" % base_fname] + if verbose >= 1: + print >> sys.stderr, "\tRunning:", ' '.join(build_cmd) + proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w')) + proc.communicate() + if not typing_common.check_files(Gene_hisat2_graph_index_fnames): + print >> sys.stderr, "Error: indexing HLA failed! Perhaps, you may have forgotten to build hisat2 executables?" + sys.exit(1) + # Build HISAT2 linear indexes based on the above information + else: + assert index_type == "linear" + Gene_hisat2_linear_index_fnames = ["%s.linear.%d.ht2" % (base_fname, i+1) for i in range(8)] + if not typing_common.check_files(Gene_hisat2_linear_index_fnames): + hisat2_build = os.path.join(ex_path, "hisat2-build") + build_cmd = [hisat2_build, + "%s_backbone.fa,%s_sequences.fa" % (base_fname, base_fname), + "%s.linear" % base_fname] + proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w'), stderr=open("/dev/null", 'w')) + proc.communicate() + if not typing_common.check_files(Gene_hisat2_linear_index_fnames): + print >> sys.stderr, "Error: indexing HLA failed!" + sys.exit(1) + else: + assert aligner == "bowtie2" and index_type == "linear" + # Build Bowtie2 indexes based on the above information + Gene_bowtie2_index_fnames = ["%s.%d.bt2" % (base_fname, i+1) for i in range(4)] + Gene_bowtie2_index_fnames += ["%s.rev.%d.bt2" % (base_fname, i+1) for i in range(2)] + if not typing_common.check_files(Gene_bowtie2_index_fnames): + build_cmd = ["bowtie2-build", + "%s_backbone.fa,%s_sequences.fa" % (base_fname, base_fname), + base_fname] + proc = subprocess.Popen(build_cmd, stdout=open("/dev/null", 'w')) + proc.communicate() + if not typing_common.check_files(Gene_bowtie2_index_fnames): + print >> sys.stderr, "Error: indexing HLA failed!" + sys.exit(1) + + # Read partial alleles from hla.data (temporary) + partial_alleles = set() + for line in open("IMGTHLA/hla.dat"): + if not line.startswith("DE"): + continue + allele_name = line.split()[1][:-1] + if allele_name.startswith("HLA-"): + allele_name = allele_name[4:] + gene = allele_name.split('*')[0] + if line.find("partial") != -1: + partial_alleles.add(allele_name) + + # Read HLA alleles (names and sequences) + refGenes, refGene_loci = {}, {} + for line in open("%s.ref" % base_fname): + Gene_name, chr, left, right, length, exon_str, strand = line.strip().split() + Gene_gene = Gene_name.split('*')[0] + assert not Gene_gene in refGenes + refGenes[Gene_gene] = Gene_name + left, right = int(left), int(right) + exons = [] + for exon in exon_str.split(','): + exon_left, exon_right = exon.split('-') + exons.append([int(exon_left), int(exon_right)]) + refGene_loci[Gene_gene] = [Gene_name, chr, left, right, exons] + Genes = {} + if len(locus_list) == 0: + locus_list = refGene_loci.keys() + + read_Gene_alleles(base_fname + "_backbone.fa", Genes) + read_Gene_alleles(base_fname + "_sequences.fa", Genes) + + # HLA gene alleles + Gene_names = {} + for Gene_gene, data in Genes.items(): + Gene_names[Gene_gene] = list(data.keys()) + + # HLA gene allele lengths + Gene_lengths = {} + for Gene_gene, Gene_alleles in Genes.items(): + Gene_lengths[Gene_gene] = {} + for allele_name, seq in Gene_alleles.items(): + Gene_lengths[Gene_gene][allele_name] = len(seq) + + # Read HLA variants, and link information + Vars, Var_list = read_Gene_vars("%s.snp" % base_fname) + Links = read_Gene_links("%s.link" % base_fname) + # Test HLA typing + test_list = [] + if simulation: + basic_test, pair_test = True, False + if debug_instr: + if "basic_test" in debug_instr: + basic_test, pair_test = True, False + else: + basic_test, pair_test = False, True + + test_passed = {} + test_list = [] + genes = list(set(locus_list) & set(Gene_names.keys())) + if basic_test: + for gene in genes: + Gene_gene_alleles = Gene_names[gene] + for Gene_name in Gene_gene_alleles: + if Gene_name.find("BACKBONE") != -1: + continue + test_list.append([[Gene_name]]) + if pair_test: + test_size = 500 + allele_count = 2 + for test_i in range(test_size): + test_pairs = [] + for gene in genes: + Gene_gene_alleles = [] + + for allele in Gene_names[gene]: + if allele.find("BACKBONE") != -1: + continue + + if "full" in debug: + if allele in partial_alleles: + continue + + Gene_gene_alleles.append(allele) + nums = [i for i in range(len(Gene_gene_alleles))] + random.shuffle(nums) + test_pairs.append(sorted([Gene_gene_alleles[nums[i]] for i in range(allele_count)])) + test_list.append(test_pairs) + + if "test_list" in debug_instr: + test_list = [[debug_instr["test_list"].split('-')]] + + for test_i in range(len(test_list)): + if "test_id" in debug_instr: + test_ids = debug_instr["test_id"].split('-') + if str(test_i + 1) not in test_ids: + continue + + print >> sys.stderr, "Test %d" % (test_i + 1), str(datetime.now()) + test_locus_list = test_list[test_i] + num_frag_list = typing_common.simulate_reads(Genes, + base_fname, + test_locus_list, + Vars, + Links, + simulate_interval, + read_len, + fragment_len, + perbase_errorrate, + perbase_snprate, + skip_fragment_regions) + + assert len(num_frag_list) == len(test_locus_list) + for i_ in range(len(test_locus_list)): + test_Gene_names = test_locus_list[i_] + num_frag_list_i = num_frag_list[i_] + assert len(num_frag_list_i) == len(test_Gene_names) + for j_ in range(len(test_Gene_names)): + test_Gene_name = test_Gene_names[j_] + gene = test_Gene_name.split('*')[0] + test_Gene_seq = Genes[gene][test_Gene_name] + seq_type = "partial" if test_Gene_name in partial_alleles else "full" + print >> sys.stderr, "\t%s - %d bp (%s sequence, %d pairs)" % (test_Gene_name, len(test_Gene_seq), seq_type, num_frag_list_i[j_]) + + if "single-end" in debug_instr: + read_fname = ["%s_input_1.fa" % base_fname] + else: + read_fname = ["%s_input_1.fa" % base_fname, "%s_input_2.fa" % base_fname] + + fastq = False + tmp_test_passed = typing(ex_path, + simulation, + base_fname, + test_locus_list, + partial, + partial_alleles, + refGenes, + Genes, + Gene_names, + Gene_lengths, + refGene_loci, + Vars, + Var_list, + Links, + aligners, + num_editdist, + assembly, + output_base, + error_correction, + discordant, + display_alleles, + stranded_seq, + fastq, + read_fname, + alignment_fname, + num_frag_list, + threads, + best_alleles, + verbose) + + for aligner_type, passed in tmp_test_passed.items(): + if aligner_type in test_passed: + test_passed[aligner_type] += passed + else: + test_passed[aligner_type] = passed + + print >> sys.stderr, "\t\tPassed so far: %d/%d (%.2f%%)" % (test_passed[aligner_type], test_i + 1, (test_passed[aligner_type] * 100.0 / (test_i + 1))) + + + for aligner_type, passed in test_passed.items(): + print >> sys.stderr, "%s:\t%d/%d passed (%.2f%%)" % (aligner_type, passed, len(test_list), passed * 100.0 / len(test_list)) + + else: # With real reads or BAMs + print >> sys.stderr, "\t", ' '.join(locus_list) + fastq = True + typing(ex_path, + simulation, + base_fname, + locus_list, + partial, + partial_alleles, + refGenes, + Genes, + Gene_names, + Gene_lengths, + refGene_loci, + Vars, + Var_list, + Links, + aligners, + num_editdist, + assembly, + output_base, + error_correction, + discordant, + display_alleles, + stranded_seq, + fastq, + read_fname, + alignment_fname, + [], + threads, + best_alleles, + verbose) + + +""" +""" +if __name__ == '__main__': + parser = ArgumentParser( + description='test HLA genotyping') + parser.add_argument("--base", "--base-fname", + dest="base_fname", + type=str, + default="hla", + help="base filename for backbone HLA sequence, HLA variants, and HLA linking info (default: hla)") + parser.add_argument("--locus-list", + dest="locus_list", + type=str, + default="", + help="A comma-separated list of HLA genes (default: empty, all HLA genes in IMGT/HLA database)") + parser.add_argument('--no-partial', + dest='partial', + action='store_false', + help='Include partial alleles (e.g. A_nuc.fasta)') + parser.add_argument("--aligner-list", + dest="aligners", + type=str, + default="hisat2.graph", + help="A comma-separated list of aligners such as hisat2.graph,hisat2.linear,bowtie2.linear (default: hisat2.graph)") + parser.add_argument("--reads", + dest="read_fname", + type=str, + default="", + help="Fastq read file name") + parser.add_argument("--alignment", + dest="alignment_fname", + type=str, + default="", + help="BAM file name") + parser.add_argument("-p", "--threads", + dest="threads", + type=int, + default=1, + help="Number of threads") + parser.add_argument("--simulate-interval", + dest="simulate_interval", + type=int, + default=10, + help="Reads simulated at every these base pairs (default: 10)") + parser.add_argument("--read-len", + dest="read_len", + type=int, + default=100, + help="Length of simulated reads (default: 100)") + parser.add_argument("--fragment-len", + dest="fragment_len", + type=int, + default=350, + help="Length of fragments (default: 350)") + parser.add_argument("--best-alleles", + dest="best_alleles", + action='store_true', + help="") + parser.add_argument("--random-seed", + dest="random_seed", + type=int, + default=1, + help="A seeding number for randomness (default: 1)") + parser.add_argument("--num-editdist", + dest="num_editdist", + type=int, + default=0, + help="Maximum number of mismatches per read alignment to be considered (default: 0)") + parser.add_argument("--perbase-errorrate", + dest="perbase_errorrate", + type=float, + default=0.0, + help="Per basepair error rate in percentage when simulating reads (default: 0.0)") + parser.add_argument("--perbase-snprate", + dest="perbase_snprate", + type=float, + default=0.0, + help="Per basepair SNP rate in percentage when simulating reads (default: 0.0)") + parser.add_argument("--skip-fragment-regions", + dest="skip_fragment_regions", + type=str, + default="", + help="A comma-separated list of regions from which no reads originate, e.g., 500-600,1200-1400 (default: None).") + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + parser.add_argument('--verbose-level', + dest='verbose_level', + type=int, + default=0, + help='also print some statistics to stderr (default: 0)') + parser.add_argument("--debug", + dest="debug", + type=str, + default="", + help="e.g., test_id:10,read_id:10000,basic_test") + parser.add_argument("--output-base", "--assembly-base", + dest="output_base", + type=str, + default="assembly_graph", + help="base file name (default: assembly_graph)") + parser.add_argument("--no-assembly", + dest="assembly", + action="store_false", + help="Perform assembly") + parser.add_argument("--no-error-correction", + dest="error_correction", + action="store_false", + help="Correct sequencing errors") + parser.add_argument("--discordant", + dest="discordant", + action="store_true", + help="Allow discordantly mapped pairs or singletons") + parser.add_argument("--display-alleles", + dest="display_alleles", + type=str, + default="", + help="A comma-separated list of alleles to display in HTML (default: empty)") + parser.add_argument("--stranded-seq", + dest="stranded_seq", + type=str, + default="", + help="Stranded-seq data (e.g.,: NA12892,ILMN_StrandSeq/SraRunInfo.txt") + + args = parser.parse_args() + if args.locus_list == "": + locus_list = [] + else: + locus_list = args.locus_list.split(',') + if args.aligners == "": + print >> sys.stderr, "Error: --aligners must be non-empty." + sys.exit(1) + args.aligners = args.aligners.split(',') + for i in range(len(args.aligners)): + args.aligners[i] = args.aligners[i].split('.') + if args.read_fname: + args.read_fname = args.read_fname.split(',') + else: + args.read_fname = [] + if args.alignment_fname != "" and \ + not os.path.exists(args.alignment_fname): + print >> sys.stderr, "Error: %s doesn't exist." % args.alignment_fname + sys.exit(1) + + if args.verbose and args.verbose_level == 0: + args.verbose_level = 1 + + debug = {} + if args.debug != "": + for item in args.debug.split(','): + if ':' in item: + fields = item.split(':') + assert len(fields) >= 2 + key, value = fields[0], ':'.join(fields[1:]) + debug[key] = value + else: + debug[item] = 1 + + if not args.partial: + print >> sys.stderr, "Warning: --no-partial will be no longer supported!" + + if args.read_len * 2 > args.fragment_len: + print >> sys.stderr, "Warning: fragment might be too short (%d)" % (args.fragment_len) + + skip_fragment_regions = [] + if args.skip_fragment_regions != "": + prev_left, prev_right = -1, -1 + for region in args.skip_fragment_regions.split(','): + left, right = region.split('-') + left, right = int(left), int(right) + assert left < right + assert prev_right < left + prev_left, prev_right = left, right + skip_fragment_regions.append([left, right]) + + if args.display_alleles == "": + display_alleles = [] + else: + display_alleles = args.display_alleles.split(',') + + if args.stranded_seq != "": + stranded_seq = args.stranded_seq.split(',') + if len(stranded_seq) != 2: + print >> sys.stderr, "Error: --stranded-seq is incorrectly specified" + sys.exit(1) + else: + stranded_seq = [] + + random.seed(args.random_seed) + test_Gene_genotyping(args.base_fname, + locus_list, + args.partial, + args.aligners, + args.read_fname, + args.alignment_fname, + args.threads, + args.simulate_interval, + args.read_len, + args.fragment_len, + args.best_alleles, + args.num_editdist, + args.perbase_errorrate, + args.perbase_snprate, + skip_fragment_regions, + args.assembly, + args.output_base, + args.error_correction, + args.discordant, + display_alleles, + stranded_seq, + args.verbose_level, + debug) + diff --git a/evaluation/tests/HLA_novel/hisatgenotype_modules b/evaluation/tests/HLA_novel/hisatgenotype_modules new file mode 100644 index 0000000..018d309 --- /dev/null +++ b/evaluation/tests/HLA_novel/hisatgenotype_modules @@ -0,0 +1 @@ +../../../hisatgenotype_modules \ No newline at end of file diff --git a/evaluation/tests/HLA_novel/scripts/run_extract_ILMN_HiSeqX.sh b/evaluation/tests/HLA_novel/scripts/run_extract_ILMN_HiSeqX.sh new file mode 100644 index 0000000..21186e0 --- /dev/null +++ b/evaluation/tests/HLA_novel/scripts/run_extract_ILMN_HiSeqX.sh @@ -0,0 +1,11 @@ +#!/bin/bash -l +#SBATCH --job-name=infphio.HLA.ILMN.extract.genome +#SBATCH --nodes=1 +#SBATCH --cpus-per-task=8 +#SBATCH --mem=80G +#SBATCH --partition=shared +#SBATCH --time=166:0:0 +#SBATCH --workdir=/home-1/dkim136@jhu.edu/infphilo/hisat2/evaluation/tests/HLA_novel + +/home-1/dkim136@jhu.edu/infphilo/hisat2/evaluation/tests/HLA_novel/scripts/extract_reads.py --base-fname genotype_genome --reference-type genome --read-dir /home-1/dkim136@jhu.edu/ssalzbe1/users/infphilo/ILMN_HiSeqX --out-dir ILMN_HiSeqX -p 8 + diff --git a/evaluation/tests/genotype_genome/hisatgenotype.py b/evaluation/tests/genotype_genome/hisatgenotype.py new file mode 100644 index 0000000..fad5906 --- /dev/null +++ b/evaluation/tests/genotype_genome/hisatgenotype.py @@ -0,0 +1 @@ +../../../hisatgenotype.py \ No newline at end of file diff --git a/evaluation/tests/genotype_genome/hisatgenotype_build_genome.py b/evaluation/tests/genotype_genome/hisatgenotype_build_genome.py new file mode 100644 index 0000000..9d3572a --- /dev/null +++ b/evaluation/tests/genotype_genome/hisatgenotype_build_genome.py @@ -0,0 +1 @@ +../../../hisatgenotype_build_genome.py \ No newline at end of file diff --git a/evaluation/tests/genotype_genome/hisatgenotype_extract_vars.py b/evaluation/tests/genotype_genome/hisatgenotype_extract_vars.py new file mode 100644 index 0000000..6d113b3 --- /dev/null +++ b/evaluation/tests/genotype_genome/hisatgenotype_extract_vars.py @@ -0,0 +1 @@ +../../../hisatgenotype_extract_vars.py \ No newline at end of file diff --git a/evaluation/tests/genotype_genome/hisatgenotype_locus.py b/evaluation/tests/genotype_genome/hisatgenotype_locus.py new file mode 100644 index 0000000..c6bcacb --- /dev/null +++ b/evaluation/tests/genotype_genome/hisatgenotype_locus.py @@ -0,0 +1 @@ +../../../hisatgenotype_locus.py \ No newline at end of file diff --git a/evaluation/tests/genotype_genome/hisatgenotype_modules b/evaluation/tests/genotype_genome/hisatgenotype_modules new file mode 100644 index 0000000..018d309 --- /dev/null +++ b/evaluation/tests/genotype_genome/hisatgenotype_modules @@ -0,0 +1 @@ +../../../hisatgenotype_modules \ No newline at end of file diff --git a/evaluation/tests/genotype_genome/hisatgenotype_prev.py b/evaluation/tests/genotype_genome/hisatgenotype_prev.py new file mode 100644 index 0000000..3e7bf0c --- /dev/null +++ b/evaluation/tests/genotype_genome/hisatgenotype_prev.py @@ -0,0 +1,1052 @@ +#!/usr/bin/env python + +# +# Copyright 2016, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + + +import sys, os, subprocess, re +import inspect, random +import math +from argparse import ArgumentParser, FileType +import hisatgenotype_typing_common as typing_common + + +""" +Align reads, and sort the alignments into a BAM file +""" +def align_reads(base_fname, + read_fnames, + fastq, + threads, + verbose): + aligner_cmd = ["hisat2", + "--no-unal", + "-p", str(threads)] + # aligner_cmd += ["--mm"] + aligner_cmd += ["-x", "%s" % base_fname] + + assert len(read_fnames) > 0 + if not fastq: + aligner_cmd += ["-f"] + single = len(read_fnames) == 1 + if single: + aligner_cmd += ["-U", read_fnames[0]] + else: + aligner_cmd += ["-1", read_fnames[0], + "-2", read_fnames[1]] + + print >> sys.stderr, "Aligning %s to %s ..." % (' '.join(read_fnames), base_fname) + if verbose: + print >> sys.stderr, "\t%s" % (' '.join(aligner_cmd)) + + align_proc = subprocess.Popen(aligner_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + sambam_cmd = ["samtools", + "view", + "-bS", + "-"] + sambam_proc = subprocess.Popen(sambam_cmd, + stdin=align_proc.stdout, + stdout=open("hla_output_unsorted.bam", 'w'), + stderr=open("/dev/null", 'w')) + sambam_proc.communicate() + + print >> sys.stderr, "Sorting %s ..." % "TBD" + bamsort_cmd = ["samtools", + "sort", + "--threads", str(threads), + "hla_output_unsorted.bam"] + bamsort_proc = subprocess.Popen(bamsort_cmd, + stdout=open("hla_output.bam", 'w'), + stderr=open("/dev/null", 'w')) + bamsort_proc.communicate() + + print >> sys.stderr, "Indexing %s ..." % "TBD" + + bamindex_cmd = ["samtools", + "index", + "hla_output.bam"] + bamindex_proc = subprocess.Popen(bamindex_cmd, + stderr=open("/dev/null", 'w')) + bamindex_proc.communicate() + + os.remove("hla_output_unsorted.bam") + + + +""" +""" +def genotype(base_fname, + fastq, + read_fnames, + threads, + num_mismatch, + verbose, + daehwan_debug): + # Load genomic sequences + chr_dic, chr_names, chr_full_names = typing_common.read_genome(open("%s.fa" % base_fname)) + + # variants, backbone sequence, and other sequeces + genotype_fnames = ["%s.fa" % base_fname, + "%s.gene" % base_fname, + "%s.snp" % base_fname, + "%s.index.snp" % base_fname, + "%s.haplotype" % base_fname, + "%s.link" % base_fname, + "%s.coord" % base_fname, + "%s.clnsig" % base_fname] + # hisat2 graph index files + genotype_fnames += ["%s.%d.ht2" % (base_fname, i+1) for i in range(8)] + if not typing_common.check_files(genotype_fnames): + print >> sys.stderr, "Error: some of the following files are missing!" + for fname in genotype_fnames: + print >> sys.stderr, "\t%s" % fname + sys.exit(1) + + # Align reads, and sort the alignments into a BAM file + align_reads(base_fname, + read_fnames, + fastq, + threads, + verbose) + + # Read HLA alleles (names and sequences) + genes, gene_loci, gene_seqs = {}, {}, {} + for line in open("%s.gene" % base_fname): + family, allele_name, chr, left, right = line.strip().split() + gene_name = "%s-%s" % (family, allele_name.split('*')[0]) + assert gene_name not in genes + genes[gene_name] = allele_name + left, right = int(left), int(right) + """ + exons = [] + for exon in exon_str.split(','): + exon_left, exon_right = exon.split('-') + exons.append([int(exon_left), int(exon_right)]) + """ + gene_loci[gene_name] = [allele_name, chr, left, right] + assert chr in chr_dic + chr_seq = chr_dic[chr] + assert left < right + assert right < len(chr_seq) + gene_seqs[gene_name] = chr_dic[chr][left:right+1] + + # Read link information + Links, var_genes, allele_vars = {}, {}, {} + for line in open("%s.link" % base_fname): + var_id, alleles = line.strip().split('\t') + alleles = alleles.split() + assert not var_id in Links + Links[var_id] = alleles + for allele in alleles: + if allele not in allele_vars: + allele_vars[allele] = set() + allele_vars[allele].add(var_id) + gene_name = "HLA-%s" % (allele.split('*')[0]) + var_genes[var_id] = gene_name + + # gene alleles + allele_names = {} + for gene_name in genes.keys(): + if gene_name not in allele_names: + allele_names[gene_name] = [] + gene_name2 = gene_name.split('-')[1] + for allele_name in allele_vars.keys(): + allele_name1 = allele_name.split('*')[0] + if gene_name2 == allele_name1: + allele_names[gene_name].append(allele_name) + + + # Read HLA variants, and link information + Vars, Var_list = {}, {} + for line in open("%s.snp" % base_fname): + var_id, var_type, chr, pos, data = line.strip().split('\t') + pos = int(pos) + + # daehwan - for debugging purposes + if var_id not in var_genes: + continue + + assert var_id in var_genes + gene_name = var_genes[var_id] + if not gene_name in Vars: + Vars[gene_name] = {} + assert not gene_name in Var_list + Var_list[gene_name] = [] + + assert not var_id in Vars[gene_name] + Vars[gene_name][var_id] = [var_type, pos, data] + Var_list[gene_name].append([pos, var_id]) + + for gene_name, in_var_list in Var_list.items(): + Var_list[gene_name] = sorted(in_var_list) + def lower_bound(Var_list, pos): + low, high = 0, len(Var_list) + while low < high: + m = (low + high) / 2 + m_pos = Var_list[m][0] + if m_pos < pos: + low = m + 1 + elif m_pos > pos: + high = m + else: + assert m_pos == pos + while m > 0: + if Var_list[m-1][0] < pos: + break + m -= 1 + return m + return low + + + # HLA gene allele lengths + """ + HLA_lengths = {} + for HLA_gene, HLA_alleles in HLAs.items(): + HLA_lengths[HLA_gene] = {} + for allele_name, seq in HLA_alleles.items(): + HLA_lengths[HLA_gene][allele_name] = len(seq) + """ + + # Cigar regular expression + cigar_re = re.compile('\d+\w') + + test_list = [[sorted(genes.keys())]] + for test_i in range(len(test_list)): + test_HLA_list = test_list[test_i] + for test_HLA_names in test_HLA_list: + print >> sys.stderr, "\t%s" % (test_HLA_names) + for gene in test_HLA_names: + ref_allele = genes[gene] + ref_seq = gene_seqs[gene] + # ref_exons = refHLA_loci[gene][-1] + + # Read alignments + alignview_cmd = ["samtools", + "view"] + alignview_cmd += ["hla_output.bam"] + base_locus = 0 + _, chr, left, right = gene_loci[gene] + base_locus = left + alignview_cmd += ["%s:%d-%d" % (chr, left + 1, right + 1)] + + bamview_proc = subprocess.Popen(alignview_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + sort_read_cmd = ["sort", "-k", "1", "-n"] + alignview_proc = subprocess.Popen(sort_read_cmd, + stdin=bamview_proc.stdout, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + # Count alleles + HLA_counts, HLA_cmpt = {}, {} + coverage = [0 for i in range(len(ref_seq) + 1)] + num_reads, total_read_len = 0, 0 + prev_read_id = None + prev_exon = False + for line in alignview_proc.stdout: + cols = line.strip().split() + read_id, flag, chr, pos, mapQ, cigar_str = cols[:6] + origin_read_id = read_id + if read_id.find('|') != -1: + tmp_read_id = read_id.split('|')[0] + try: + read_id = int(tmp_read_id) + except ValueError: + None + + read_seq, qual = cols[9], cols[10] + num_reads += 1 + total_read_len += len(read_seq) + flag, pos = int(flag), int(pos) + pos -= 1 + if pos < 0: + continue + + if flag & 0x4 != 0: + continue + + NM, Zs, MD = "", "", "" + for i in range(11, len(cols)): + col = cols[i] + if col.startswith("Zs"): + Zs = col[5:] + elif col.startswith("MD"): + MD = col[5:] + elif col.startswith("NM"): + NM = int(col[5:]) + + if NM > num_mismatch: + continue + + # daehwan - for debugging purposes + debug = False + if read_id in ["2339"] and False: + debug = True + print "read_id: %s)" % read_id, pos, cigar_str, "NM:", NM, MD, Zs + print " ", read_seq + + vars = [] + if Zs: + vars = Zs.split(',') + + assert MD != "" + MD_str_pos, MD_len = 0, 0 + read_pos, left_pos = 0, pos + right_pos = left_pos + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + cmp_list = [] + for i in range(len(cigars)): + cigar_op, length = cigars[i] + if cigar_op == 'M': + first = True + MD_len_used = 0 + while True: + if not first or MD_len == 0: + if MD[MD_str_pos].isdigit(): + num = int(MD[MD_str_pos]) + MD_str_pos += 1 + while MD_str_pos < len(MD): + if MD[MD_str_pos].isdigit(): + num = num * 10 + int(MD[MD_str_pos]) + MD_str_pos += 1 + else: + break + MD_len += num + # Insertion or full match followed + if MD_len >= length: + MD_len -= length + cmp_list.append(["match", right_pos + MD_len_used, length - MD_len_used]) + break + first = False + read_base = read_seq[read_pos + MD_len] + MD_ref_base = MD[MD_str_pos] + MD_str_pos += 1 + assert MD_ref_base in "ACGT" + cmp_list.append(["match", right_pos + MD_len_used, MD_len - MD_len_used]) + cmp_list.append(["mismatch", right_pos + MD_len, 1]) + MD_len_used = MD_len + 1 + MD_len += 1 + # Full match + if MD_len == length: + MD_len = 0 + break + elif cigar_op == 'I': + cmp_list.append(["insertion", right_pos, length]) + elif cigar_op == 'D': + if MD[MD_str_pos] == '0': + MD_str_pos += 1 + assert MD[MD_str_pos] == '^' + MD_str_pos += 1 + while MD_str_pos < len(MD): + if not MD[MD_str_pos] in "ACGT": + break + MD_str_pos += 1 + cmp_list.append(["deletion", right_pos, length]) + elif cigar_op == 'S': + cmp_list.append(["soft", right_pos, length]) + else: + assert cigar_op == 'N' + cmp_list.append(["intron", right_pos, length]) + + if cigar_op in "MND": + right_pos += length + + if cigar_op in "MIS": + read_pos += length + + """ + exon = False + for exon in ref_exons: + exon_left, exon_right = exon + if right_pos <= exon_left or pos > exon_right: + continue + else: + exon = True + break + """ + + if left_pos < base_locus or \ + right_pos - base_locus > len(ref_seq): + continue + + def add_stat(HLA_cmpt, HLA_counts, HLA_count_per_read, exon = True): + max_count = max(HLA_count_per_read.values()) + cur_cmpt = set() + for allele, count in HLA_count_per_read.items(): + if count < max_count: + continue + """ + if allele in exclude_allele_list: + continue + """ + cur_cmpt.add(allele) + if not allele in HLA_counts: + HLA_counts[allele] = 1 + else: + HLA_counts[allele] += 1 + + if len(cur_cmpt) == 0: + return + + # daehwan - for debugging purposes + alleles = ["", ""] + # alleles = ["B*40:304", "B*40:02:01"] + allele1_found, allele2_found = False, False + for allele, count in HLA_count_per_read.items(): + if count < max_count: + continue + if allele == alleles[0]: + allele1_found = True + elif allele == alleles[1]: + allele2_found = True + if allele1_found != allele2_found: + print alleles[0], HLA_count_per_read[alleles[0]] + print alleles[1], HLA_count_per_read[alleles[1]] + if allele1_found: + print ("%s\tread_id %s - %d vs. %d]" % (alleles[0], prev_read_id, max_count, HLA_count_per_read[alleles[1]])) + else: + print ("%s\tread_id %s - %d vs. %d]" % (alleles[1], prev_read_id, max_count, HLA_count_per_read[alleles[0]])) + print read_seq + + cur_cmpt = sorted(list(cur_cmpt)) + cur_cmpt = '-'.join(cur_cmpt) + add = 1 + """ + if partial and not exon: + add *= 0.2 + """ + if not cur_cmpt in HLA_cmpt: + HLA_cmpt[cur_cmpt] = add + else: + HLA_cmpt[cur_cmpt] += add + + if read_id != prev_read_id: + if prev_read_id != None: + add_stat(HLA_cmpt, HLA_counts, HLA_count_per_read, prev_exon) + + HLA_count_per_read = {} + for HLA_name in allele_names[gene]: + if HLA_name.find("BACKBONE") != -1: + continue + HLA_count_per_read[HLA_name] = 0 + + def add_count(var_id, add): + assert var_id in Links + alleles = Links[var_id] + for allele in alleles: + if allele.find("BACKBONE") != -1: + continue + HLA_count_per_read[allele] += add + # daehwan - for debugging purposes + if debug: + if allele in ["DQA1*05:05:01:01", "DQA1*05:05:01:02"]: + print allele, add, var_id + + # Decide which allele(s) a read most likely came from + # also sanity check - read length, cigar string, and MD string + for var_id, data in Vars[gene].items(): + var_type, var_pos, var_data = data + if var_type != "deletion": + continue + if left_pos >= var_pos and right_pos <= var_pos + int(var_data): + add_count(var_id, -1) + ref_pos, read_pos, cmp_cigar_str, cmp_MD = left_pos, 0, "", "" + cigar_match_len, MD_match_len = 0, 0 + for cmp in cmp_list: + type = cmp[0] + length = cmp[2] + if type == "match": + var_idx = lower_bound(Var_list[gene], ref_pos) + while var_idx < len(Var_list[gene]): + var_pos, var_id = Var_list[gene][var_idx] + if ref_pos + length <= var_pos: + break + if ref_pos <= var_pos: + var_type, _, var_data = Vars[gene][var_id] + if var_type == "insertion": + if ref_pos < var_pos and ref_pos + length > var_pos + len(var_data): + add_count(var_id, -1) + # daehwan - for debugging purposes + if debug: + print cmp, var_id, Links[var_id] + elif var_type == "deletion": + del_len = int(var_data) + if ref_pos < var_pos and ref_pos + length > var_pos + del_len: + # daehwan - for debugging purposes + if debug: + print cmp, var_id, Links[var_id], -1, Vars[gene][var_id] + # Check if this might be one of the two tandem repeats (the same left coordinate) + cmp_left, cmp_right = cmp[1], cmp[1] + cmp[2] + test1_seq1 = ref_seq[cmp_left-base_locus:cmp_right-base_locus] + test1_seq2 = ref_seq[cmp_left-base_locus:var_pos-base_locus] + ref_seq[var_pos + del_len - base_locus:cmp_right + del_len - base_locus] + # Check if this happens due to small repeats (the same right coordinate - e.g. 19 times of TTTC in DQA1*05:05:01:02) + cmp_left -= read_pos + cmp_right += (len(read_seq) - read_pos - cmp[2]) + test2_seq1 = ref_seq[cmp_left+int(var_data)-base_locus:cmp_right-base_locus] + test2_seq2 = ref_seq[cmp_left-base_locus:var_pos-base_locus] + ref_seq[var_pos+int(var_data)-base_locus:cmp_right-base_locus] + if test1_seq1 != test1_seq2 and test2_seq1 != test2_seq2: + add_count(var_id, -1) + else: + if debug: + print cmp, var_id, Links[var_id], -1 + add_count(var_id, -1) + var_idx += 1 + + read_pos += length + ref_pos += length + cigar_match_len += length + MD_match_len += length + elif type == "mismatch": + read_base = read_seq[read_pos] + var_idx = lower_bound(Var_list[gene], ref_pos) + while var_idx < len(Var_list[gene]): + var_pos, var_id = Var_list[gene][var_idx] + if ref_pos < var_pos: + break + if ref_pos == var_pos: + var_type, _, var_data = Vars[gene][var_id] + if var_type == "single": + if var_data == read_base: + # daehwan - for debugging purposes + if debug: + print cmp, var_id, 1, var_data, read_base, Links[var_id] + + # daehwan - for debugging purposes + if False: + read_qual = ord(qual[read_pos]) + add_count(var_id, (read_qual - 60) / 60.0) + else: + add_count(var_id, 1) + # daehwan - check out if this routine is appropriate + # else: + # add_count(var_id, -1) + var_idx += 1 + cmp_MD += ("%d%s" % (MD_match_len, ref_seq[ref_pos-base_locus])) + MD_match_len = 0 + cigar_match_len += 1 + read_pos += 1 + ref_pos += 1 + elif type == "insertion": + ins_seq = read_seq[read_pos:read_pos+length] + var_idx = lower_bound(Var_list[gene], ref_pos) + # daehwan - for debugging purposes + if debug: + print left_pos, cigar_str, MD, vars + print ref_pos, ins_seq, Var_list[gene][var_idx], Vars[gene][Var_list[gene][var_idx][1]] + # sys.exit(1) + while var_idx < len(Var_list[gene]): + var_pos, var_id = Var_list[gene][var_idx] + if ref_pos < var_pos: + break + if ref_pos == var_pos: + var_type, _, var_data = Vars[gene][var_id] + if var_type == "insertion": + if var_data == ins_seq: + # daehwan - for debugging purposes + if debug: + print cmp, var_id, 1, Links[var_id] + add_count(var_id, 1) + var_idx += 1 + + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cigar_match_len = 0 + read_pos += length + cmp_cigar_str += ("%dI" % length) + elif type == "deletion": + del_len = length + # Deletions can be shifted bidirectionally + temp_ref_pos = ref_pos + while temp_ref_pos > 0: + last_bp = ref_seq[temp_ref_pos + del_len - 1 - base_locus] + prev_bp = ref_seq[temp_ref_pos - 1 - base_locus] + if last_bp != prev_bp: + break + temp_ref_pos -= 1 + var_idx = lower_bound(Var_list[gene], temp_ref_pos) + while var_idx < len(Var_list[gene]): + var_pos, var_id = Var_list[gene][var_idx] + if temp_ref_pos < var_pos: + first_bp = ref_seq[temp_ref_pos - base_locus] + next_bp = ref_seq[temp_ref_pos + del_len - base_locus] + if first_bp == next_bp: + temp_ref_pos += 1 + continue + else: + break + if temp_ref_pos == var_pos: + var_type, _, var_data = Vars[gene][var_id] + if var_type == "deletion": + var_len = int(var_data) + if var_len == length: + if debug: + print cmp, var_id, 1, Links[var_id] + print ref_seq[var_pos - 10-base_locus:var_pos-base_locus], ref_seq[var_pos-base_locus:var_pos+int(var_data)-base_locus], ref_seq[var_pos+int(var_data)-base_locus:var_pos+int(var_data)+10-base_locus] + add_count(var_id, 1) + var_idx += 1 + + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cigar_match_len = 0 + cmp_MD += ("%d" % MD_match_len) + MD_match_len = 0 + cmp_cigar_str += ("%dD" % length) + cmp_MD += ("^%s" % ref_seq[ref_pos-base_locus:ref_pos+length-base_locus]) + ref_pos += length + elif type == "soft": + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cigar_match_len = 0 + read_pos += length + cmp_cigar_str += ("%dS" % length) + else: + assert type == "intron" + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cigar_match_len = 0 + cmp_cigar_str += ("%dN" % length) + ref_pos += length + if cigar_match_len > 0: + cmp_cigar_str += ("%dM" % cigar_match_len) + cmp_MD += ("%d" % MD_match_len) + if read_pos != len(read_seq) or \ + cmp_cigar_str != cigar_str or \ + cmp_MD != MD: + print >> sys.stderr, "Error:", cigar_str, MD + print >> sys.stderr, "\tcomputed:", cmp_cigar_str, cmp_MD + print >> sys.stderr, "\tcmp list:", cmp_list + assert False + + prev_read_id = read_id + # prev_exon = exon + + if num_reads <= 0: + continue + + if prev_read_id != None: + add_stat(HLA_cmpt, HLA_counts, HLA_count_per_read) + + HLA_counts = [[allele, count] for allele, count in HLA_counts.items()] + def HLA_count_cmp(a, b): + if a[1] != b[1]: + return b[1] - a[1] + assert a[0] != b[0] + if a[0] < b[0]: + return -1 + else: + return 1 + HLA_counts = sorted(HLA_counts, cmp=HLA_count_cmp) + for count_i in range(len(HLA_counts)): + count = HLA_counts[count_i] + print >> sys.stderr, "\t\t\t\t%d %s (count: %d)" % (count_i + 1, count[0], count[1]) + if count_i >= 9: + break + print >> sys.stderr + + def normalize(prob): + total = sum(prob.values()) + for allele, mass in prob.items(): + prob[allele] = mass / total + + def normalize2(prob, length): + total = 0 + for allele, mass in prob.items(): + assert allele in length + total += (mass / length[allele]) + for allele, mass in prob.items(): + assert allele in length + prob[allele] = mass / length[allele] / total + + def prob_diff(prob1, prob2): + diff = 0.0 + for allele in prob1.keys(): + if allele in prob2: + diff += abs(prob1[allele] - prob2[allele]) + else: + diff += prob1[allele] + return diff + + def HLA_prob_cmp(a, b): + if a[1] != b[1]: + if a[1] < b[1]: + return 1 + else: + return -1 + assert a[0] != b[0] + if a[0] < b[0]: + return -1 + else: + return 1 + + HLA_prob, HLA_prob_next = {}, {} + for cmpt, count in HLA_cmpt.items(): + alleles = cmpt.split('-') + for allele in alleles: + if allele not in HLA_prob: + HLA_prob[allele] = 0.0 + HLA_prob[allele] += (float(count) / len(alleles)) + + """ + assert gene in HLA_lengths + HLA_length = HLA_lengths[gene] + """ + HLA_length = {} + + # normalize2(HLA_prob, HLA_length) + normalize(HLA_prob) + def next_prob(HLA_cmpt, HLA_prob, HLA_length): + HLA_prob_next = {} + for cmpt, count in HLA_cmpt.items(): + alleles = cmpt.split('-') + alleles_prob = 0.0 + for allele in alleles: + assert allele in HLA_prob + alleles_prob += HLA_prob[allele] + for allele in alleles: + if allele not in HLA_prob_next: + HLA_prob_next[allele] = 0.0 + HLA_prob_next[allele] += (float(count) * HLA_prob[allele] / alleles_prob) + # normalize2(HLA_prob_next, HLA_length) + normalize(HLA_prob_next) + return HLA_prob_next + + diff, iter = 1.0, 0 + while diff > 0.0001 and iter < 1000: + HLA_prob_next = next_prob(HLA_cmpt, HLA_prob, HLA_length) + diff = prob_diff(HLA_prob, HLA_prob_next) + HLA_prob = HLA_prob_next + iter += 1 + + """ + for allele, prob in HLA_prob.items(): + allele_len = len(HLAs[gene][allele]) + HLA_prob[allele] /= float(allele_len) + normalize(HLA_prob) + """ + HLA_prob = [[allele, prob] for allele, prob in HLA_prob.items()] + + HLA_prob = sorted(HLA_prob, cmp=HLA_prob_cmp) + success = [False for i in range(len(test_HLA_names))] + found_list = [False for i in range(len(test_HLA_names))] + for prob_i in range(len(HLA_prob)): + prob = HLA_prob[prob_i] + print >> sys.stderr, "\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, prob[0], prob[1] * 100.0) + if prob_i >= 9: + break + print >> sys.stderr + + """ + if len(test_HLA_names) == 2: + HLA_prob, HLA_prob_next = {}, {} + for cmpt, count in HLA_cmpt.items(): + alleles = cmpt.split('-') + for allele1 in alleles: + for allele2 in HLA_names[gene]: + if allele1 < allele2: + allele_pair = "%s-%s" % (allele1, allele2) + else: + allele_pair = "%s-%s" % (allele2, allele1) + if not allele_pair in HLA_prob: + HLA_prob[allele_pair] = 0.0 + HLA_prob[allele_pair] += (float(count) / len(alleles)) + + if len(HLA_prob) <= 0: + continue + + # Choose top allele pairs + def choose_top_alleles(HLA_prob): + HLA_prob_list = [[allele_pair, prob] for allele_pair, prob in HLA_prob.items()] + HLA_prob_list = sorted(HLA_prob_list, cmp=HLA_prob_cmp) + HLA_prob = {} + best_prob = HLA_prob_list[0][1] + for i in range(len(HLA_prob_list)): + allele_pair, prob = HLA_prob_list[i] + if prob * 2 <= best_prob: + break + HLA_prob[allele_pair] = prob + normalize(HLA_prob) + return HLA_prob + HLA_prob = choose_top_alleles(HLA_prob) + + def next_prob(HLA_cmpt, HLA_prob): + HLA_prob_next = {} + for cmpt, count in HLA_cmpt.items(): + alleles = cmpt.split('-') + prob = 0.0 + for allele in alleles: + for allele_pair in HLA_prob.keys(): + if allele in allele_pair: + prob += HLA_prob[allele_pair] + for allele in alleles: + for allele_pair in HLA_prob.keys(): + if not allele in allele_pair: + continue + if allele_pair not in HLA_prob_next: + HLA_prob_next[allele_pair] = 0.0 + HLA_prob_next[allele_pair] += (float(count) * HLA_prob[allele_pair] / prob) + normalize(HLA_prob_next) + return HLA_prob_next + + diff, iter = 1.0, 0 + while diff > 0.0001 and iter < 1000: + HLA_prob_next = next_prob(HLA_cmpt, HLA_prob) + diff = prob_diff(HLA_prob, HLA_prob_next) + HLA_prob = HLA_prob_next + HLA_prob = choose_top_alleles(HLA_prob) + iter += 1 + + HLA_prob = [[allele_pair, prob] for allele_pair, prob in HLA_prob.items()] + HLA_prob = sorted(HLA_prob, cmp=HLA_prob_cmp) + + success = [False] + for prob_i in range(len(HLA_prob)): + allele_pair, prob = HLA_prob[prob_i] + allele1, allele2 = allele_pair.split('-') + if best_alleles and prob_i < 1: + print >> sys.stdout, "PairModel %s (abundance: %.2f%%)" % (allele_pair, prob * 100.0) + if simulation: + if allele1 in test_HLA_names and allele2 in test_HLA_names: + rank_i = prob_i + while rank_i > 0: + if HLA_prob[rank_i-1][1] == prob: + rank_i -= 1 + else: + break + print >> sys.stderr, "\t\t\t*** %d ranked %s (abundance: %.2f%%)" % (rank_i + 1, allele_pair, prob * 100.0) + if rank_i == 0: + success[0] = True + break + print >> sys.stderr, "\t\t\t\t%d ranked %s (abundance: %.2f%%)" % (prob_i + 1, allele_pair, prob * 100.0) + if not simulation and prob_i >= 9: + break + print >> sys.stderr + """ + + # Read variants with clinical significance + clnsigs = {} + for line in open("%s.clnsig" % base_fname): + var_id, var_gene, var_clnsig = line.strip().split('\t') + clnsigs[var_id] = [var_gene, var_clnsig] + + vars, Var_list = {}, {} + for line in open("%s.snp" % base_fname): + var_id, type, chr, left, data = line.strip().split() + if var_id not in clnsigs: + continue + left = int(left) + if type == "deletion": + data = int(data) + vars[var_id] = [chr, left, type, data] + if chr not in Var_list: + Var_list[chr] = [] + Var_list[chr].append([left, var_id]) + + var_counts = {} + + # Read alignments + alignview_cmd = ["samtools", + "view", + "hla_output.bam"] + bamview_proc = subprocess.Popen(alignview_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + for line in bamview_proc.stdout: + cols = line.strip().split() + read_id, flag, chr, pos, mapQ, cigar_str = cols[:6] + read_seq, qual = cols[9], cols[10] + flag, pos = int(flag), int(pos) + pos -= 1 + if pos < 0: + continue + + if flag & 0x4 != 0: + continue + + if chr not in Var_list: + continue + + assert chr in chr_dic + chr_seq = chr_dic[chr] + + NM, Zs, MD, NH = "", "", "", "" + for i in range(11, len(cols)): + col = cols[i] + if col.startswith("Zs"): + Zs = col[5:] + elif col.startswith("MD"): + MD = col[5:] + elif col.startswith("NM"): + NM = int(col[5:]) + elif col.startswith("NH"): + NH = int(col[5:]) + + assert NH != "" + NH = int(NH) + if NH > 1: + continue + + if NM > num_mismatch: + continue + + read_vars = [] + if Zs: + read_vars = Zs.split(',') + for read_var in read_vars: + _, _, var_id = read_var.split('|') + if var_id not in clnsigs: + continue + if var_id not in var_counts: + var_counts[var_id] = [1, 0] + else: + var_counts[var_id][0] += 1 + + assert MD != "" + MD_str_pos, MD_len = 0, 0 + read_pos, left_pos = 0, pos + right_pos = left_pos + cigars = cigar_re.findall(cigar_str) + cigars = [[cigar[-1], int(cigar[:-1])] for cigar in cigars] + cmp_list = [] + for i in range(len(cigars)): + cigar_op, length = cigars[i] + if cigar_op == 'M': + chr_var_list = Var_list[chr] + var_idx = lower_bound(chr_var_list, right_pos) + while var_idx < len(chr_var_list): + var_pos, var_id = chr_var_list[var_idx] + if var_pos >= right_pos + length: + break + if var_pos >= right_pos: + assert var_id in vars + _, _, var_type, var_data = vars[var_id] + contradict = False + if var_type == "single": + contradict = (read_seq[read_pos + var_pos - right_pos] == chr_seq[var_pos]) + elif var_type == "insertion": + contradict = (right_pos < var_pos) + else: + contradict = True + if contradict: + if var_id not in var_counts: + var_counts[var_id] = [0, 1] + else: + var_counts[var_id][1] += 1 + + var_idx += 1 + + if cigar_op in "MND": + right_pos += length + + if cigar_op in "MIS": + read_pos += length + + for var_id, counts in var_counts.items(): + if counts[0] < 2: # or counts[0] * 3 < counts[1]: + continue + assert var_id in vars + var_chr, var_left, var_type, var_data = vars[var_id] + assert var_id in clnsigs + var_gene, var_clnsig = clnsigs[var_id] + print >> sys.stderr, "\t\t\t%s %s: %s:%d %s %s (%s): %d-%d" % \ + (var_gene, var_id, var_chr, var_left, var_type, var_data, var_clnsig, counts[0], counts[1]) + + + +""" +""" +if __name__ == '__main__': + parser = ArgumentParser( + description='HISAT2 genotyping') + parser.add_argument("--base", "--base-name", + dest="base_fname", + type=str, + default="genotype_genome", + help="base filename for genotype genome") + parser.add_argument('-f', + dest='fastq', + action='store_false', + help='FASTA file') + parser.add_argument("-U", + dest="read_fname_U", + type=str, + default="", + help="filename for single-end reads") + parser.add_argument("-1", + dest="read_fname_1", + type=str, + default="", + help="filename for paired-end reads") + parser.add_argument("-2", + dest="read_fname_2", + type=str, + default="", + help="filename for paired-end reads") + parser.add_argument("-p", "--threads", + dest="threads", + type=int, + default=1, + help="Number of threads") + parser.add_argument("--num-editdist", + dest="num_editdist", + type=int, + default=2, + help="Maximum number of mismatches per read alignment to be considered (default: 2)") + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + parser.add_argument("--daehwan-debug", + dest="daehwan_debug", + type=str, + default="", + help="e.g., test_id:10,read_id:10000,basic_test") + + args = parser.parse_args() + daehwan_debug = {} + if args.daehwan_debug != "": + for item in args.daehwan_debug.split(','): + if ':' in item: + key, value = item.split(':') + daehwan_debug[key] = value + else: + daehwan_debug[item] = 1 + + if args.read_fname_U != "": + read_fnames = [args.read_fname_U] + else: + if args.read_fname_1 == "" or args.read_fname_2 == "": + print >> sys.stderr, "Error: please specify read file names correctly: -U or -1 and -2" + sys.exit(1) + read_fnames = [args.read_fname_1, args.read_fname_2] + + random.seed(1) + genotype(args.base_fname, + args.fastq, + read_fnames, + args.threads, + args.num_editdist, + args.verbose, + daehwan_debug) diff --git a/evaluation/tests/genotype_genome/paper_sensitivity/sensitivity.py b/evaluation/tests/genotype_genome/paper_sensitivity/sensitivity.py new file mode 100644 index 0000000..527d5d7 --- /dev/null +++ b/evaluation/tests/genotype_genome/paper_sensitivity/sensitivity.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +# +# Copyright 2017, Daehwan Kim +# +# This file is part of HISAT-genotype. +# +# HISAT-genotype is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT-genotype is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT-genotype. If not, see . +# + + +import sys, os, subprocess, re, resource +import inspect +import random +import glob +from argparse import ArgumentParser, FileType + + +""" +""" +if __name__ == '__main__': + aligners = [["hisat2", "graph"], ["hisat2", "linear"], ["bowtie2", "linear"]] + genes = ["A", "B", "C", "DQA1", "DQB1", "DRB1"] + + samples = ["NA12878", "LP6005041-DNA_A01", "LP6005045-DNA_D07"] + for sample in samples: + for aligner, type in aligners: + sample_dir = "%s_%s" % (sample, aligner) + if aligner == "hisat2": + sample_dir += (".%s" % type) + if not os.path.exists(sample_dir): + continue + + fq_fnames = glob.glob("%s/*.fq.gz" % sample_dir) + assert len(fq_fnames) == 2 + + regions, region_loci, region_count, region_read1_count, region_read2_count = {}, {}, {}, {}, {} + for line in open("%s.locus" % ("genotype_genome" if type == "graph" else "genotype_genome.linear")): + family, allele_name, chr, left, right = line.strip().split()[:5] + + # DK - debugging purposes + if family != "HLA": + continue + + region_name = "%s-%s" % (family, allele_name.split('*')[0]) + assert region_name not in regions + regions[region_name] = allele_name + left, right = int(left), int(right) + if chr not in region_loci: + region_loci[chr] = {} + region_loci[chr][region_name] = [allele_name, chr, left, right] + + + aligner_cmd = [aligner] + aligner_cmd += ["-x", "genotype_genome" if type == "graph" else "genotype_genome.linear"] + if aligner == "hisat2": + aligner_cmd += ["--no-spliced-alignment"] + aligner_cmd += ["-X", "1000"] + aligner_cmd += ["-1", fq_fnames[0], + "-2", fq_fnames[1]] + # print >> sys.stderr, "Running:", ' '.join(aligner_cmd) + print sample, aligner, type + align_proc = subprocess.Popen(aligner_cmd, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + prev_read_name, extract, read1_extract, read2_extract, read1_first, read2_first = "", set(), set(), set(), True, True + for line in align_proc.stdout: + if line.startswith('@'): + continue + line = line.strip() + cols = line.split() + read_name, flag, chr, pos, mapQ, cigar, _, _, _, read, qual = cols[:11] + flag, pos = int(flag), int(pos) - 1 + strand = '-' if flag & 0x10 else '+' + AS, XS, NH = "", "", "" + for i in range(11, len(cols)): + col = cols[i] + if col.startswith("AS"): + AS = int(col[5:]) + elif col.startswith("XS"): + XS = int(col[5:]) + elif col.startswith("NH"): + NH = int(col[5:]) + + if read_name != prev_read_name: + for region in extract: + if region not in region_count: + region_count[region] = 0 + region_count[region] += 1 + + for region in read1_extract: + if region not in region_read1_count: + region_read1_count[region] = 0 + region_read1_count[region] += 1 + + for region in read2_extract: + if region not in region_read2_count: + region_read2_count[region] = 0 + region_read2_count[region] += 1 + + prev_read_name, extract, read1_extract, read2_extract, read1_first, read2_first = "", set(), set(), set(), True, True + + if ((aligner == "hisat2" and NH == 1) or (aligner == "bowtie2" and AS > XS and read1_first if flag & 0x40 else read2_first)): + if chr in region_loci: + for region, loci in region_loci[chr].items(): + _, _, loci_left, loci_right = loci + # there might be a different candidate region for each of left and right reads + if pos >= loci_left and pos < loci_right: + extract.add(region) + if flag & 0x40: + read1_extract.add(region) + else: + read2_extract.add(region) + break + + if flag & 0x40: # left read + read1_first = False + else: + assert flag & 0x80 # right read + read2_first = False + + prev_read_name = read_name + + for gene in genes: + gene = "HLA-" + gene + if gene not in region_count: + continue + print "\t%s pair: %d, left+right: %d" % (gene, region_count[gene], region_read1_count[gene] + region_read2_count[gene]) + diff --git a/evaluation/tests/one_snp_test/evaluate_one_snp_reads.py b/evaluation/tests/one_snp_test/evaluate_one_snp_reads.py new file mode 100644 index 0000000..3809a68 --- /dev/null +++ b/evaluation/tests/one_snp_test/evaluate_one_snp_reads.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python + +import sys, os, subprocess +import multiprocessing +import string, re +import platform +from datetime import datetime, date, time +import copy +from argparse import ArgumentParser, FileType + + +""" +""" +def evaluate(read_fname, + verbose): + aligners = [ + ["hisat2", "", "", ""], + ["hisat2", "", "snp", ""], + ["bowtie2", "", "", ""], + ] + num_threads = 3 + + cwd = os.getcwd() + genome = "genome" + align_stat = [] + # for paired in [False, True]: + for paired in [False]: + base_fname = "common_snp_reads" + type_sam_fname = base_fname + ".sam" + type_read1_fname = base_fname + "_1.fa" + type_read2_fname = base_fname + "_2.fa" + + type_read1_fname = read_fname + + def get_aligner_version(aligner, version): + version = "" + if aligner == "hisat2" or \ + aligner == "bowtie2": + if version: + cmd = ["%s_%s/%s" % (aligner, version, aligner)] + else: + cmd = ["%s/%s" % (aligner_bin_base, aligner)] + cmd += ["--version"] + cmd_process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + version = cmd_process.communicate()[0][:-1].split("\n")[0] + version = version.split()[-1] + elif aligner == "star": + version = "2.4.2a" + elif aligner == "gsnap": + cmd = ["%s/gsnap" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[0] + version = version.split()[2] + elif aligner == "bwa": + cmd = ["%s/bwa" % (aligner_bin_base)] + cmd_process = subprocess.Popen(cmd, stderr=subprocess.PIPE) + version = cmd_process.communicate()[1][:-1].split("\n")[2] + version = version.split()[1] + + return version + + def get_aligner_cmd(aligner, type, index_type, version, read1_fname, read2_fname, out_fname, cmd_idx = 0): + cmd = [] + if aligner == "hisat2": + cmd = ["hisat2"] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["-f"] + cmd += ["--no-spliced-alignment"] + if index_type: + index_cmd = "../grch38_snp_hisat2/genome_snp" + else: + index_cmd = "../grch38_hisat2/genome" + cmd += [index_cmd] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "star": + cmd = ["%s/STAR" % (aligner_bin_base)] + if num_threads > 1: + cmd += ["--runThreadN", str(num_threads)] + cmd += ["--genomeDir"] + if cmd_idx == 0: + if type == "gtf": + cmd += ["%s/STAR%s/gtf" % (index_base, index_add)] + else: + cmd += ["%s/STAR%s" % (index_base, index_add)] + else: + assert cmd_idx == 1 + cmd += ["."] + + if desktop: + cmd += ["--genomeLoad", "NoSharedMemory"] + else: + cmd += ["--genomeLoad", "LoadAndKeep"] + if type == "x2": + if cmd_idx == 1: + cmd += ["--alignSJDBoverhangMin", "1"] + cmd += ["--readFilesIn", + read1_fname] + if paired: + cmd += [read2_fname] + if paired: + cmd += ["--outFilterMismatchNmax", "6"] + else: + cmd += ["--outFilterMismatchNmax", "3"] + elif aligner == "bowtie2": + cmd = ["bowtie2"] + if num_threads > 1: + cmd += ["-p", str(num_threads)] + cmd += ["-f"] + cmd += ["-x ../grch38_bowtie2/genome"] + if paired: + cmd += ["-1", read1_fname, + "-2", read2_fname] + else: + cmd += [read1_fname] + elif aligner == "gsnap": + cmd = ["%s/gsnap" % (aligner_bin_base), + "-A", + "sam"] + if num_threads > 1: + cmd += ["-t", str(num_threads)] + cmd += ["--max-mismatches=3", + "-D", "%s/GSNAP%s" % (index_base, index_add), + "-N", "1", + "-d", genome, + read1_fname] + if paired: + cmd += [read2_fname] + elif aligner == "bwa": + cmd = ["%s/bwa" % (aligner_bin_base)] + if type in ["mem", "aln"]: + cmd += [type] + elif type == "sw": + cmd += ["bwa" + type] + if num_threads > 1: + cmd += ["-t", str(num_threads)] + cmd += ["%s/BWA%s/%s.fa" % (index_base, index_add, genome)] + cmd += [read1_fname] + if paired: + cmd += [read2_fname] + else: + assert False + + return cmd + + for aligner, type, index_type, version in aligners: + aligner_name = aligner + type + if version != "": + aligner_name += ("_%s" % version) + if aligner == "hisat2" and index_type != "": + aligner_name += ("_" + index_type) + two_step = (aligner == "tophat2" or type == "x2" or (aligner in ["hisat2", "hisat"] and type == "")) + print >> sys.stderr, "\t%s\t%s" % (aligner_name, str(datetime.now())) + if paired: + aligner_dir = aligner_name + "_paired" + else: + aligner_dir = aligner_name + "_single" + if not os.path.exists(aligner_dir): + os.mkdir(aligner_dir) + os.chdir(aligner_dir) + + out_fname = base_fname + ".sam" + duration = -1.0 + + # Align all reads + aligner_cmd = get_aligner_cmd(aligner, type, index_type, version, "../" + type_read1_fname, "../" + type_read2_fname, out_fname) + start_time = datetime.now() + if verbose: + print >> sys.stderr, "\t", start_time, " ".join(aligner_cmd) + if aligner in ["hisat2", "hisat", "bowtie", "bowtie2", "gsnap", "bwa"]: + proc = subprocess.Popen(aligner_cmd, stdout=open(out_fname, "w"), stderr=subprocess.PIPE) + else: + proc = subprocess.Popen(aligner_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc.communicate() + finish_time = datetime.now() + duration = finish_time - start_time + duration = duration.total_seconds() + if verbose: + print >> sys.stderr, "\t", finish_time, "finished:", duration + + assert os.path.exists(out_fname) + correct_reads, correct_multi_reads, num_reads = 0, 0, 0 + prev_read_id = None + for line in open(out_fname): + if line.startswith('@'): + continue + read_id, flag, chr, pos, mapQ, cigar = line.split()[:6] + if chr.startswith("chr"): + chr = chr[3:] + pos = int(pos) - 1 + true_chr, true_pos, true_cigar = read_id.split('_')[1:4] + true_pos = int(true_pos) + + if read_id != prev_read_id: + num_reads += 1 + + if true_chr == chr and pos == true_pos and cigar == true_cigar: + correct_multi_reads += 1 + if prev_read_id != read_id: + correct_reads += 1 + + prev_read_id = read_id + + print >> sys.stderr, "\tfirst: %d / %d (%.2f%%)" % (correct_reads, num_reads, float(correct_reads)/num_reads*100) + print >> sys.stderr, "\tall: %d / %d (%.2f%%)" % (correct_multi_reads, num_reads, float(correct_multi_reads)/num_reads*100) + + os.chdir("..") + + +""" +""" +if __name__ == "__main__": + parser = ArgumentParser( + description='test HISAT2, and compare HISAT2 with other popular aligners such as TopHat2, STAR, Bowtie1/2, GSNAP, BWA-mem, etc.') + parser.add_argument('read_fname', + nargs='?', + type=str, + help='input read file') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + + args = parser.parse_args() + evaluate(args.read_fname, + args.verbose) + + diff --git a/evaluation/tests/one_snp_test/simulate_one_snp_reads.py b/evaluation/tests/one_snp_test/simulate_one_snp_reads.py new file mode 100644 index 0000000..178cb06 --- /dev/null +++ b/evaluation/tests/one_snp_test/simulate_one_snp_reads.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +import sys, math, random, re +from collections import defaultdict, Counter +from argparse import ArgumentParser, FileType + + +""" +""" +def reverse_complement(seq): + result = "" + for nt in seq: + base = nt + if nt == 'A': + base = 'T' + elif nt == 'a': + base = 't' + elif nt == 'C': + base = 'G' + elif nt == 'c': + base = 'g' + elif nt == 'G': + base = 'C' + elif nt == 'g': + base = 'c' + elif nt == 'T': + base = 'A' + elif nt == 't': + base = 'a' + + result = base + result + + return result + + +""" +""" +def read_genome(genome_file): + chr_dic = {} + + chr_name, sequence = "", "" + for line in genome_file: + if line[0] == ">": + if chr_name and sequence: + chr_dic[chr_name] = sequence + chr_name = line.strip().split()[0][1:] + sequence = "" + else: + sequence += line[:-1] + + if chr_name and sequence: + chr_dic[chr_name] = sequence + + return chr_dic + + +""" +""" +def read_snp(snp_file): + snps = defaultdict(list) + for line in snp_file: + line = line.strip() + if not line or line.startswith('#'): + continue + try: + snpID, type, chr, pos, data = line.split('\t') + chr = chr.split()[0] + except ValueError: + continue + + assert type in ["single", "deletion", "insertion"] + if type == "deletion": + data = int(data) + snps[chr].append([snpID, type, int(pos), data]) + + return snps + + +""" +""" +def getSamAlignment(chr_seq, read_len, snp): + snp_id, snp_type, snp_pos, snp_data = snp + + # Define MD, XM, NM, Zs, read_seq + read_seq, MD, Zs = "", "", "" + left_read_len = read_len / 2 + pos = snp_pos - left_read_len + assert pos >= 0 + if snp_type == "single": + cigar_str = "100M" + read_seq = chr_seq[pos:pos+left_read_len] + snp_data + chr_seq[pos+left_read_len+1:pos+read_len] + MD = "%d%s%d" % (left_read_len, chr_seq[pos+left_read_len], read_len - left_read_len - 1) + Zs = "%d|S|%s" % (left_read_len, snp_id) + elif snp_type == "deletion": + del_len = int(snp_data) + cigar_str = "%dM%dD%dM" % (left_read_len, del_len, read_len - left_read_len) + read_seq = chr_seq[pos:pos+left_read_len] + chr_seq[pos+left_read_len+del_len:pos+read_len+del_len] + MD = "%d^%s%d" % (left_read_len, chr_seq[pos+left_read_len:pos+left_read_len+del_len], read_len - left_read_len) + Zs = "%d|D|%s" % (left_read_len, snp_id) + else: + assert snp_type == "insertion" + ins_len = len(snp_data) + assert ins_len < read_len + cigar_str = "%dM%dI%dM" % (left_read_len, ins_len, read_len - left_read_len - ins_len) + read_seq = chr_seq[pos:pos+left_read_len] + snp_data + chr_seq[pos+left_read_len:pos+read_len-ins_len] + MD = "%d" % (read_len - ins_len) + Zs = "%d|I|%s" % (left_read_len, snp_id) + + if len(read_seq) != read_len: + print >> sys.stderr, "read length differs:", len(read_seq), "vs.", read_len + print >> sys.stderr, pos, cigar_str, MD, Zs + assert False + + ref_read_seq = chr_seq[pos:pos+read_len] + return pos, cigar_str, MD, Zs, read_seq, ref_read_seq + + +""" +""" +cigar_re = re.compile('\d+\w') +def samRepOk(genome_seq, read_seq, chr, pos, cigar, MD, Zs): + assert chr in genome_seq + chr_seq = genome_seq[chr] + assert pos < len(chr_seq) + + # Calculate XM and NM based on Cigar and Zs + cigars = cigar_re.findall(cigar) + cigars = [[int(cigars[i][:-1]), cigars[i][-1]] for i in range(len(cigars))] + ref_pos, read_pos = pos, 0 + ann_ref_seq, ann_ref_rel, ann_read_seq, ann_read_rel = [], [], [], [] + for i in range(len(cigars)): + cigar_len, cigar_op = cigars[i] + if cigar_op == "M": + partial_ref_seq = chr_seq[ref_pos:ref_pos+cigar_len] + partial_read_seq = read_seq[read_pos:read_pos+cigar_len] + assert len(partial_ref_seq) == len(partial_read_seq) + ann_ref_seq += list(partial_ref_seq) + ann_read_seq += list(partial_read_seq) + for j in range(len(partial_ref_seq)): + if partial_ref_seq[j] == partial_read_seq[j]: + ann_ref_rel.append("=") + ann_read_rel.append("=") + else: + ann_ref_rel.append("X") + ann_read_rel.append("X") + ref_pos += cigar_len + read_pos += cigar_len + elif cigar_op == "D": + partial_ref_seq = chr_seq[ref_pos:ref_pos+cigar_len] + ann_ref_rel += list(partial_ref_seq) + ann_ref_seq += list(partial_ref_seq) + ann_read_rel += (["-"] * cigar_len) + ann_read_seq += (["-"] * cigar_len) + ref_pos += cigar_len + elif cigar_op == "I": + partial_read_seq = read_seq[read_pos:read_pos+cigar_len] + ann_ref_rel += (["-"] * cigar_len) + ann_ref_seq += (["-"] * cigar_len) + ann_read_rel += list(partial_read_seq) + ann_read_seq += list(partial_read_seq) + read_pos += cigar_len + elif cigar_op == "N": + ref_pos += cigar_len + else: + assert False + + assert len(ann_ref_seq) == len(ann_read_seq) + assert len(ann_ref_seq) == len(ann_ref_rel) + assert len(ann_ref_seq) == len(ann_read_rel) + ann_Zs_seq = ["0" for i in range(len(ann_ref_seq))] + + Zss, Zs_i, snp_pos_add = [], 0, 0 + if Zs != "": + Zss = Zs.split(',') + Zss = [zs.split('|') for zs in Zss] + + ann_read_pos = 0 + for zs in Zss: + zs_pos, zs_type, zs_id = zs + zs_pos = int(zs_pos) + for i in range(zs_pos): + while ann_read_rel[ann_read_pos] == '-': + ann_read_pos += 1 + ann_read_pos += 1 + if zs_type == "S": + ann_Zs_seq[ann_read_pos] = "1" + ann_read_pos += 1 + elif zs_type == "D": + while ann_read_rel[ann_read_pos] == '-': + ann_Zs_seq[ann_read_pos] = "1" + ann_read_pos += 1 + elif zs_type == "I": + while ann_ref_rel[ann_read_pos] == '-': + ann_Zs_seq[ann_read_pos] = "1" + ann_read_pos += 1 + else: + assert False + + tMD, tXM, tNM = "", 0, 0 + match_len = 0 + i = 0 + while i < len(ann_ref_seq): + if ann_ref_rel[i] == "=": + assert ann_read_rel[i] == "=" + match_len += 1 + i += 1 + continue + assert ann_read_rel[i] != "=" + if ann_ref_rel[i] == "X" and ann_read_rel[i] == "X": + if match_len > 0: + tMD += ("{}".format(match_len)) + match_len = 0 + tMD += ann_ref_seq[i] + if ann_Zs_seq[i] == "0": + tXM += 1 + tNM += 1 + i += 1 + else: + assert ann_ref_rel[i] == "-" or ann_read_rel[i] == "-" + if ann_ref_rel[i] == '-': + while ann_ref_rel[i] == '-': + if ann_Zs_seq[i] == "0": + tNM += 1 + i += 1 + else: + assert ann_read_rel[i] == '-' + del_seq = "" + while ann_read_rel[i] == '-': + del_seq += ann_ref_seq[i] + if ann_Zs_seq[i] == "0": + tNM += 1 + i += 1 + if match_len > 0: + tMD += ("{}".format(match_len)) + match_len = 0 + tMD += ("^{}".format(del_seq)) + + if match_len > 0: + tMD += ("{}".format(match_len)) + + if tMD != MD: + print >> sys.stderr, chr, pos, cigar, MD, Zs + print >> sys.stderr, tMD + assert False + + +""" +""" +def simulate_reads(genome_file, snp_file, base_fname, \ + paired_end, read_len, frag_len, \ + num_frag, sanity_check, verbose): + if read_len > frag_len: + frag_len = read_len + + genome_seq = read_genome(genome_file) + snps = read_snp(snp_file) + chr_ids = genome_seq.keys() + + sam_file = open(base_fname + ".sam", "w") + + # Write SAM header + print >> sam_file, "@HD\tVN:1.0\tSO:unsorted" + for chr in genome_seq.keys(): + print >> sam_file, "@SQ\tSN:%s\tLN:%d" % (chr, len(genome_seq[chr])) + + read_file = open(base_fname + "_snp_1.fa", "w") + ref_read_file = open(base_fname + "_ref_1.fa", "w") + if paired_end: + read2_file = open(base_fname + "_snp_2.fa", "w") + ref_read2_file = open(base_fname + "_ref_2.fa", "w") + + cur_read_id = 1 + for chr in snps: + assert chr in genome_seq + chr_seq = genome_seq[chr] + chr_len = len(chr_seq) + if chr in snps: + chr_snps = snps[chr] + else: + chr_snps = [] + for snp in chr_snps: + # SAM specification (v1.4) + # http://samtools.sourceforge.net/ + flag, flag2 = 99, 163 # 83, 147 + pos, cigar_str, MD, Zs, read_seq, ref_read_seq = getSamAlignment(chr_seq, read_len, snp) + # pos2, cigar2_str, MD2, Zs2, read2_seq = getSamAlignment(chr_seq, frag_pos+frag_len-read_len, read_len, snp) + if sanity_check: + samRepOk(genome_seq, read_seq, chr, pos, cigar_str, MD, Zs) + # samRepOk(genome_seq, read2_seq, chr, pos2, cigar2_str, MD2, Zs2) + + if Zs != "": + Zs = ("\tZs:Z:{}".format(Zs)) + # if Zs2 != "": + # Zs2 = ("\tZs:Z:{}".format(Zs2)) + + read_id_str = "{}_{}_{}_{}".format(cur_read_id, chr, pos, cigar_str) + print >> read_file, ">{}".format(read_id_str) + print >> read_file, read_seq + print >> sam_file, "{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:0\tNM:i:0\tMD:Z:{}{}".format(read_id_str, flag, chr, pos + 1, cigar_str, chr, pos + 1, read_seq, MD, Zs) + + print >> ref_read_file, ">{}_{}_{}_100M".format(cur_read_id, chr, pos) + print >> ref_read_file, ref_read_seq + """ + if paired_end: + print >> read2_file, ">{}".format(cur_read_id) + print >> read2_file, reverse_complement(read2_seq) + print >> sam_file, "{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:0\tNM:i:0\tMD:Z:{}{}".format(cur_read_id, flag2, chr, pos2 + 1, cigar2_str, chr, pos + 1, read2_seq, MD2, Zs2) + """ + + cur_read_id += 1 + + sam_file.close() + read_file.close() + ref_read_file.close() + if paired_end: + read2_file.close() + ref_read2_file.close() + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Simulate reads from GENOME (fasta) and GTF files') + parser.add_argument('genome_file', + nargs='?', + type=FileType('r'), + help='input GENOME file') + parser.add_argument('snp_file', + nargs='?', + type=FileType('r'), + help='input SNP file') + parser.add_argument('base_fname', + nargs='?', + type=str, + help='output base filename') + parser.add_argument('--paired-end', + dest='paired_end', + action='store_true', + help='single-end reads (default: paired-end reads)') + parser.add_argument('-r', '--read-length', + dest='read_len', + action='store', + type=int, + default=100, + help='read length (default: 100)') + parser.add_argument('-f', '--fragment-length', + dest='frag_len', + action='store', + type=int, + default=250, + help='fragment length (default: 250)') + parser.add_argument('-n', '--num-fragment', + dest='num_frag', + action='store', + type=int, + default=1000000, + help='number of fragments (default: 1000000)') + parser.add_argument('--sanity-check', + dest='sanity_check', + action='store_true', + help='sanity check') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + parser.add_argument('--version', + action='version', + version='%(prog)s 2.1.0') + args = parser.parse_args() + if not args.genome_file or not args.snp_file: + parser.print_help() + exit(1) + simulate_reads(args.genome_file, args.snp_file, args.base_fname, \ + args.paired_end, args.read_len, args.frag_len, \ + args.num_frag, args.sanity_check, args.verbose) diff --git a/evaluation/tests/repeat/commands b/evaluation/tests/repeat/commands new file mode 100644 index 0000000..db6a962 --- /dev/null +++ b/evaluation/tests/repeat/commands @@ -0,0 +1,64 @@ +date; time bowtie2 -X 800 --extends 1000 --score-min C,0 -p 3 -x 20 -f -1 1.fa -2 2.fa > bowtie2.sam + +date; time hisat2 --no-spliced-alignment --score-min C,0 -X 800 -p 3 -x 20 -f -1 1.fa -2 2.fa > hisat2.sam + + + +# Chromosome 22 + +/usr/bin/time -l hisat2-repeat -p 3 --save-sa --load-sa --repeat-length 51-300,76-300,100-300,101-300,151-300 --repeat-count 5 22.fa 22_rep + +/usr/bin/time -l hisat2-build -p 3 22.fa --repeat-ref 22_rep.rep.fa --repeat-info 22_rep.rep.info 22_rep + +hisat2_simulate_reads.py --dna --num-fragment 1000000 --repeat-info 22_rep.rep.info 22.fa /dev/null /dev/null sim + +hisat2_simulate_reads.py --dna --num-fragment 1000000 --error-rate 0.2 --repeat-info 22_rep.rep.info 22.fa /dev/null /dev/null sim + +cp 22_rep.rep.info ../../data/ +cp 22_rep*ht2 ../../indexes/HISAT2_22 + + + +# 3-base +/usr/bin/time -l hisat2-repeat -p 30 --save-sa --load-sa --repeat-length 26-100,51-100 --repeat-count 5 genome.fa genome_rep +/usr/bin/time -l hisat2-build -p 30 genome.fa --repeat-ref genome_rep-26-100.rep.fa --repeat-info genome_rep-26-100.rep.info genome_rep + + + + + +# Human genome + +/usr/bin/time -l hisat2-repeat -p 3 --save-sa --load-sa --repeat-length 100-300,101-300 --repeat-count 5 genome.fa genome_rep + +/usr/bin/time -l hisat2-build -p 3 genome.fa --repeat-ref genome_rep.rep.fa --repeat-info genome_rep.rep.info genome_rep + +/usr/bin/time -l hisat2-repeat -p 3 --save-sa --load-sa --repeat-edit 0 --repeat-length 101--300 --repeat-count 5 genome.fa genome_rep-101-300 + +/usr/bin/time -l hisat2-build -p 3 genome.fa --repeat-ref genome_rep-101-300.rep.fa --repeat-info genome_rep-101-300.rep.info genome_rep-101-300 + +hisat2_simulate_reads.py --dna --num-fragment 1000 --repeat-info genome_rep.rep.info genome.fa /dev/null /dev/null sim + +hisat2_simulate_reads.py --dna --num-fragment 1000 --error-rate 0.2 --repeat-info genome_rep.rep.info genome.fa /dev/null /dev/null sim + +hisat2_simulate_reads.py --dna --num-fragment 10000 --repeat-info genome_rep.rep.info genome.fa /dev/null /dev/null sim + +hisat2_simulate_reads.py --dna --num-fragment 10000 --error-rate 0.2 --repeat-info genome_rep.rep.info genome.fa /dev/null /dev/null sim + +hisat2_simulate_reads.py --dna --num-fragment 10000000 --repeat-info genome_rep.rep.info genome.fa /dev/null /dev/null sim + +hisat2_simulate_reads.py --dna --num-fragment 10000000 --error-rate 0.2 --repeat-info genome_rep.rep.info genome.fa /dev/null /dev/null sim + +cp genome_rep.rep.info ../../data/ +cp genome_rep.*ht2 ../../indexes/HISAT2 + + + + +# Bisulfite-treated sequencing + +/usr/bin/time -l hisat2-repeat -p 3 --repeat-length 100 --repeat-count 2 --repeat-edit 0 --forward-only --CGtoTG 22.fa 22_rep + +/usr/bin/time -l hisat2-repeat -p 3 --repeat-length 200 --repeat-count 2 --repeat-edit 0 --forward-only --CGtoTG genome.fa genome_rep + + diff --git a/evaluation/tests/repeat/generate_repeats.py b/evaluation/tests/repeat/generate_repeats.py new file mode 100644 index 0000000..2227245 --- /dev/null +++ b/evaluation/tests/repeat/generate_repeats.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python + +import sys +import struct + +chr_name = "20" + +chr_seq = "" +for line in open("%s.fa" % chr_name): + if line.startswith('>'): + continue + line = line.strip() + line = line.replace('N', '') + chr_seq += line +chr_seq += '$' + +chr_sa = [] +f = open("%s.sa" % chr_name, "rb") +while True: + fourbytes = f.read(4) + if fourbytes == "": + break + + num = struct.unpack('I', fourbytes)[0] + chr_sa.append(num) + + if len(chr_sa) % 5000000 == 0: + print len(chr_sa) +f.close() + +assert chr_sa[0] + 1 == len(chr_sa) +chr_sa = chr_sa[1:] +assert len(chr_seq) == len(chr_sa) + +# for i, num in enumerate(chr_sa): +# print "%10d\t%s\t%d" % (i, chr_seq[num:num+100], num) + +seq_len = 100 +i = 0 +repeats = [] +while i < len(chr_sa) - 1: + pos = chr_sa[i] + base_seq = chr_seq[pos:pos+seq_len] + for j in xrange(i+1, len(chr_sa)): + pos2 = chr_sa[j] + cmp_seq = chr_seq[pos2:pos2+seq_len] + if base_seq != cmp_seq: + break + + if j - i >= 200: + repeats.append([base_seq, sorted(chr_sa[i:j])]) + + i = j + + if i % 5000000 == 0: + print i + +found = False +print len(repeats), "repeats" +deleted = set() +for i in xrange(len(repeats) - 1): + for j in xrange(i + 1, len(repeats)): + if j in deleted: + continue + + num_close, num_close2 = 0, 0 + pos_seq, pos_set = repeats[i] + pos_seq2, pos_set2 = repeats[j] + + k1, k2 = 0, 0 + while k1 < len(pos_set) and k2 < len(pos_set2): + _pos, _pos2 = pos_set[k1], pos_set2[k2] + if abs(_pos - _pos2) < 300: + num_close += 1 + if abs(_pos - _pos2) < 1100: + num_close2 += 1 + if _pos <= _pos2: + k1 += 1 + else: + k2 += 1 + + if num_close > min(len(pos_set), len(pos_set2)) * 0.95: + deleted.add(j) + + if num_close == 1 and num_close2 < 5: + found = True + print pos_set + print pos_set2 + print pos_seq + print pos_seq2 + + file1 = open("1.fa", "w") + file2 = open("2.fa", "w") + + pos_seq2_rc = list(pos_seq2) + pos_seq2_rc = pos_seq2_rc[::-1] + for k in xrange(seq_len): + nt = pos_seq2_rc[k] + if nt == 'A': + nt = 'T' + elif nt == 'C': + nt = 'G' + elif nt == 'G': + nt = 'C' + else: + assert nt == 'T' + nt = 'A' + pos_seq2_rc[k] = nt + pos_seq2_rc = ''.join(pos_seq2_rc) + + for k in xrange(1000000): + print >> file1, ">%d" % k + print >> file2, ">%d" % k + print >> file1, pos_seq + print >> file2, pos_seq2_rc + + file1.close() + file2.close() + + break + if found: + break + + print i + +chr_seq = "" +for line in open("%s.fa" % chr_name): + if line.startswith('>'): + continue + line = line.strip() + chr_seq += line + +N_ranges = [] +prev_nt = None +for i in xrange(len(chr_seq)): + nt = chr_seq[i] + if nt == 'N': + if prev_nt != 'N': + N_ranges.append([i, i]) # inclusive + else: + assert len(N_ranges) > 0 + N_ranges[-1][1] = i + prev_nt = nt + +to_joined_list = [] +for N_start, N_end in N_ranges: + if len(to_joined_list) == 0: + if N_start > 0: + to_joined_list.append([0, 0]) + else: + to_joined_list.append([N_end + 1, 0]) + else: + N_size = N_end - N_start + 1 + to = N_end + 1 - to_joined_list[-1][0] + to_joined_list[-1][1] - N_size + assert to > to_joined_list[-1][1] + to_joined_list.append([N_end + 1, to]) + +to_genome_list = [[y, x] for x, y in to_joined_list] + +N_ranges_tmp = [] +for i in xrange(len(to_genome_list)): + to_genome = to_genome_list[i] + if i == 0: + if to_genome[1] > 0: + N_ranges_tmp.append([0, to_genome[1] - 1]) + else: + to_genome_before = to_genome_list[i-1] + N_ranges_tmp.append([to_genome_before[1] + to_genome[0] - to_genome_before[0], to_genome[1] - 1]) + +assert N_ranges == N_ranges_tmp + +file = open("%s_rep.info" % chr_name, "w") +def print_rep_info(rep_name, rep_pos, rep_len, pos_set, pos_seq): + print >> file, ">%s*0\trep\t%d\t%d\t%d\t0" % (rep_name, rep_pos, rep_len, len(pos_set)) + for i in xrange(0, len(pos_set), 10): + output = "" + for j in range(i, i + 10): + if j >= len(pos_set): + break + if j > i: + output += " " + + def convert(pos): + for i in xrange(len(to_genome_list)): + if i + 1 == len(to_genome_list) or (pos >= to_genome_list[i][0] and pos < to_genome_list[i+1][0]): + return pos - to_genome_list[i][0] + to_genome_list[i][1] + + assert False + + pos = convert(pos_set[j]) + assert chr_seq[pos:pos+seq_len] == pos_seq + output += ("%s:%d:+" % (chr_name, pos)) + print >> file, output +print_rep_info("rep1", 0, seq_len, pos_set, pos_seq) +print_rep_info("rep2", seq_len, seq_len, pos_set2, pos_seq2) +file.close() + +chr_seq = chr_seq.replace(pos_seq, 'N' * seq_len) +chr_seq = chr_seq.replace(pos_seq2, 'N' * seq_len) +file = open("%s_mask.fa" % chr_name, "w") +print >> file, ">%s_mask" % chr_name +for i in xrange(0, len(chr_seq), 60): + print >> file, chr_seq[i:i+60] +file.close() + +file = open("%s_rep.fa" % chr_name, "w") +rep_seq = pos_seq + pos_seq2 +print >> file, ">rep" +for i in xrange(0, len(rep_seq), 60): + print >> file, rep_seq[i:i+60] +file.close() + diff --git a/evaluation/tests/repeat/test_repeat.py b/evaluation/tests/repeat/test_repeat.py new file mode 100644 index 0000000..cd10009 --- /dev/null +++ b/evaluation/tests/repeat/test_repeat.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +import sys, os, subprocess, random +from argparse import ArgumentParser, FileType + +""" +""" +def reverse_complement(seq): + result = "" + for nt in seq: + base = nt + if nt == 'A': + base = 'T' + elif nt == 'a': + base = 't' + elif nt == 'C': + base = 'G' + elif nt == 'c': + base = 'g' + elif nt == 'G': + base = 'C' + elif nt == 'g': + base = 'c' + elif nt == 'T': + base = 'A' + elif nt == 't': + base = 'a' + + result = base + result + + return result + + +""" +""" +def read_genome(genome_filename): + chr_dic = {} + genome_file = open(genome_filename, "r") + + chr_name, sequence = "", "" + for line in genome_file: + if line[0] == ">": + if chr_name and sequence: + chr_dic[chr_name] = sequence + + chr_name = line[1:-1].split()[0] + sequence = "" + else: + sequence += line[:-1] + + if chr_name and sequence: + chr_dic[chr_name] = sequence + + genome_file.close() + + print >> sys.stderr, "genome is loaded" + + return chr_dic + + +""" +""" +def generate_random_seq(seq_len): + assert seq_len > 0 + random_seq = "" + for i in xrange(seq_len): + random_seq += "ACGT"[random.randint(0, 3)] + return random_seq + + +""" +""" +def test_repeat(verbose): + random.seed(1) + + backbone_seq = generate_random_seq(500) + mm_seq = backbone_seq[:] + mm_seq = mm_seq[:50] + ("A" if mm_seq[50] != "A" else "C") + mm_seq[51:] + mm_seq2 = backbone_seq[:] + mm_seq2 = mm_seq2[:450] + ("A" if mm_seq2[450] != "A" else "C") + mm_seq2[451:] + del_seq = backbone_seq[:] + del_seq = del_seq[:50] + del_seq[52:150] + del_seq[152:] + del_seq2 = backbone_seq[:] + del_seq2 = del_seq2[:350] + del_seq2[352:450] + del_seq2[452:] + indel_seq = backbone_seq[:] + indel_seq = indel_seq[:30] + indel_seq[32:130] + "AAA" + indel_seq[130:] + indel_seq2 = backbone_seq[:] + indel_seq2 = indel_seq2[:30] + "AAA" + indel_seq2[30:130] + indel_seq2[132:] + + seqs = [ + # dummy_seq, + ["bb01", backbone_seq], + ["bb02", backbone_seq], + ["bb03", backbone_seq], + ["bb04", backbone_seq], + ["bb05", backbone_seq], + ["mm01", mm_seq], + ["mm02", mm_seq], + ["dd01", del_seq], + ["dd02", del_seq], + ["dd03", del_seq2], + ["dd04", del_seq2], + ["id01", indel_seq], + ["id02", indel_seq], + ["id03", indel_seq], + ["id04", indel_seq], + ["id05", indel_seq], + ["id06", indel_seq], + ["id07", indel_seq2], + ] + + for id, seq in seqs: + print ">%s" % id + print generate_random_seq(20) + print seq + print generate_random_seq(20) + + +""" +""" +if __name__ == "__main__": + parser = ArgumentParser( + description='') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + + args = parser.parse_args() + test_repeat(args.verbose) + + diff --git a/evaluation/tests/the_small_example/COMMAND b/evaluation/tests/the_small_example/COMMAND new file mode 100644 index 0000000..1723cfb --- /dev/null +++ b/evaluation/tests/the_small_example/COMMAND @@ -0,0 +1,2 @@ +../../../hisat2-build --offrate 0 --ftabchars 1 --snp small.snp small.fa small +../../../hisat2 -x small -c GCTAG diff --git a/evaluation/tests/the_small_example/small.fa b/evaluation/tests/the_small_example/small.fa new file mode 100644 index 0000000..e9219f3 --- /dev/null +++ b/evaluation/tests/the_small_example/small.fa @@ -0,0 +1,2 @@ +>small +GAGCTG diff --git a/evaluation/tests/the_small_example/small.snp b/evaluation/tests/the_small_example/small.snp new file mode 100644 index 0000000..aab0624 --- /dev/null +++ b/evaluation/tests/the_small_example/small.snp @@ -0,0 +1,3 @@ +snp1 single small 1 T +snp2 deletion small 4 1 +snp3 insertion small 5 A diff --git a/example/index/22_20-21M_snp.1.ht2 b/example/index/22_20-21M_snp.1.ht2 new file mode 100644 index 0000000000000000000000000000000000000000..47f7462000fa0b9d33d8ccb2125efe59fa48c229 GIT binary patch literal 4789374 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

    1{>1kZC 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

    4#Y{$ERzd40if*3dhf6RK+ zKY{N6e>00lUihH)1YiEM6<&Kb{59>=3}G@EV{+p9jii8nNp)TIESZN@LPBIVhe8$V z$L39cfZNjl+|}4Dz_!OWxDWpbd>i;a@V9aFR`X*9#3$~yG3DsXmd%hEeqLZC2)NUr zJb%r`&kUW!6+2dPPK3A%y5-#1VPiq3I}iEKI{t$Z3n|1~_{u#Mh^O%Pz&{56b%Vvn z*+fcUgWJ(zBHdAw{JFn8{ayL^!d`T%LW@y05GVQ;f5fJh9(dz}Hc{)c?Q4 zUDL9Dgnu3}FctoY4XFPFKOg?Y(79G6qwP#p(oaNIRScUfy=`}jJ96E^W7~PJ1F~gS z0vxA^0ZQ`}sa>w74|6N-f8^uKraT+dPM(FX{!Sr+5Cd!B)8W5|ubhSBUzYKn2fv2= zn{m1PgipqxMFwa84&bJaovbZpQ9Y^GwxuwZJFL*p`(=k_P>OwuRQ#lh+4lY4omhtO zML6~&1|;wgz}LfZXafABN`DS5XNTPD?XuCp!;hTwyuA7nw_kC#P8YVbk$EjE<^{jm8~!!;9Qe!OuU?lZ(Y`89P;tDTwC;V9 z;{HcdcS?i?#l2^hja%hor^42!sT`wCjJaBSr8M<+YX5AeaO)3lvpZax=@t}10o&j+ z{9Zf-A{zcq_%wIgBgJaxeI}nn_f_j@7-`y5$e7Sxbked3*R1uUjhFld}8m!*Dup06bZ{EXh~qvn|B9xs*aG% z)IIWvy7*U~dbo-Blubdo!*gZbK$XkvB@&bV#PJSS@&^+hz>h%;u;CwouY}{kBlxod zjH>>UG%UwKze@gy37vr?lPhn9(bUO5$Z$GdQfVN;*YM%raDe7ZpI2CnMFnY7rU5SAMbv}dD!cbOOq!| z8!%#A_`58jby@oh@WZj2t?~Q`F>n2tHD=|OBVF>6YUbYZWWsTnY)+GlzNlD zkk{%`b59qirwHxBSFng@x1SdF?a9eoQV}(r&TMM`^Fy!o#NU_T`4hH5KK$46^+y~| zgTFDepCnlLJk%!hII*s{SGB2OuY1lu;YK@y?{Cu>ed-{0i=8R?{Dbr2uz3Nae3kkI z1T6M#op;;e7Te;Jyi&kG8lFGFuYo_^1Lc44m%-nw7ExY3+5h_1=#W%NmVE1086W}@ zwIa3{x};#R-$t*B9a9Smg`Wj~hkW~^GmuE8 z;q?L%T}g1jU;~45k_dw%i2p4b{rjkRI6=dp$rTIPO=;`?=P3j=x9> zu>~<;4qpI&Jbs55__+oD&g|N2r8xfBI#2%1ya!3)@s4*47KD5J>KMN#^Tw8!Uj9q0 zr^W1v8NpewTQs!CCxg^>%b$LB2;M_S*)L*X4g7TY68OjE>mQe5FygvIqA_}aSpKF1 z^>|&^IbNB1h4jx$&iC3@Cpy7>m#X+^Z1r6eQ_;WmUQ*7SHEq}K=VNRc6ha;YVerf0 zSHmxbKedbR(b?~|KCR46=Q5N%?j$W>7WOsOC3_GOfxgC&d7Q-BII9&>hQnKi>nPLF zmA`E-S@1<`5o14HfKfJh_6`36d<{>uzed{SJlek)s}~BMP0qTY6=5Ousq^b|zoIxc ztKeYirrUS!#gLJ69+@3|7Ew*$F?G_khzVE4gLK-$EpLOfS}x3&!O!r|AqM`1YY(4? zR3CoKG5cPrN0ttVRPOTNsLu7S$^Klsp?jw?tjb)|SASa8%)%HMhx^*!?%CnpOh~L{Q5c{TkgV7pKdDoZkuV{Cn+hROWe~D zPJ5Dy2Xp@!k!PC`mHwMb(VR1urqZ=tP6SNS>N)&OEBo8vx6<%0tK2lcF*FaeQ2!Y* zUZ0Sp$Xegs-?!0j=8wXRFl07(3 z@wOm;=HQ#t^Y4%Q<&DzsNg?{C4cWxFi|R(=dK$6jM$d7+Cx#~WR&SQ=PkXT}W%8M( zEu|2(@FU2}&gZNg=@ zvUx*_VWKEk>CU|F#KX_6&i{OQ_N_X8({Nc+j|v;*Pl$ona2LVfjdTWl;#So!+fyZq zMDMH|q8IbszsAZVHWFJ#T{jNcNaRFhO4jwgZtN30KD7Zo*sNRQ})cI_IqAu^P3vySh@ZciU$Od}nPx zv-|axQH#Vx&#oIvi6i;%{oX3HI{tK69M@tY66{d-05Px&z6gE^{80FB)5OODZCxL_ zi8N*pAT+{5M%3CQm?$k+AEM&L!>2jxEUIOb$ENJ_Jy_*tRALa6T}t$5v8tULsM%;w zA$~&)l*7LPzXARQ_--f4+^8;z-Mv(W7Z(k+JR}&e;JfSSm@%h{_jM!QBzjkq^kpj6 zDIr!@YU22Pw`NW|w}JN39g+E_cHEXv zW2c60l8v=Z^_3YaZkU-Z`)%|1?4~@M(z2$WuW76Ozj1Oo{3yi0LHMiT2f(MnM=Pv1 z|GvJRlO?lILdB}to9iDPjfgQ7Q0LnCthsggoZ0L-Rqv0T(|o2qLulgu$xtHHY_|N(#Na78UUIHa0Bu0F7Su&i+_C3%6@oh8$pZ{&(YtN45sDFP%zpt$58XZyqGooE3&(v#wIt69Q-*!hg>~^vD0))^qV=viU_>{#50-Smm^wh zp~di*%aOA07jF z?`kuO$oJ(m56!aib6(n*a7Yg`>$Dh2Y)`aLXxVkfYdz0f_=$*tboe3g=fZcC`?-rq zKAXBbVmqz-t7B}k#OmCt1Mi&4hLs<=0n%<)yO!(i%i75kou~KA6il+x>fx)_zjfX} z9R9jHo_C@U8xaG4!`Ik^@?ZGd;2*CdJ(pZQRe$HcqK^f6aA&S|vd}}5B~Uru*C>#; z(SrQfZ6^Pp{t>dF#Aed9y96V!KIRxSSd z)lS<7WOgnTf{JZ0go8SHGHZQ#1NQU*p%bf~3RD zJ-oiXM4Yg1&@|n>FM#FooCmSeE7`sDY?{O7<6du$3rFkd9)pZ45rT#`T(-} z%l$`IOM>5WuuVPe2Kav<1{~qf*o^%T+hHmE^)|*~^T-^U3Qxx-e@TzIe%$)$R+Tgz z=3h2N^ZcSDeHXoE3)gUc9_(^bSLBUUVf{-mIFZyXa&!4_A9rmnUiSkcugUj&e`=IV4{3`gos7;1EPf4O`2x~I` z_O1cH2M#f&56!4eA3?-!!#ycW4;65y`FM;Uj)AXThsX~m7`s!5cknCVpMW0?U-fe1 z{jaNmLDL)VB(b~Ym3|vLE^di&dNdkL=qd(ajH(egI?1|r`XmcE)Bah$*#hvJ^`lp9 z74E$d11cJbefY{)j^Xe}8M2(Lq7F*x0=5^QpD<52^YXd!DF&(Q;&hDYL(o3E*U;gJmbPwSNAqFPFuY?~6e>{BqTXnS51q;yj#)~a) z;zN?O49+EUf&Sx&YxFK`_i8f+S;MkfK=Mrav;Mq1n)76n+BdfBTVG?(x81+xXbd&T zPOL`xCt|=EzV;S{#yD_=FQnFzQ}6Mar1|3MsyvcjUTSVHFj+~?r$^#9r&seyDNEi$ zuCZf~9JRLx@hn}iKzX^hdpf&Bsk&Fz63&_& zCwJcVd9|Nc-95E8Fz&F@(TE|QO0wL~>uL@Mxi^G%f@_-P+Y=G%wG=eArVxSf75RAf zi8KLzf~DsrvNE+Y^H=k9y1h6kVw+yInM17E6@etyN8oS5KW1upXOM#B%;&N=Qkf}K zez4~MT7TVjDEoz<0e3EZBcxB@Yoyuh=zT6cw|up#vXj;LHA`mVjOep=ynY(@<)uw$ z$eVY%{x)Vyq#KiLqsgCC6;cmnqTd>&Gj zEBFQ^z9}a)rPAlkdFEwI&Ixr7FL8Etxc2(h>jU*=PLmd$BC>RR7A6h}nBHseJZkEz z5i^YB?XOyeTC-a*eoMD$==^%ry+aIi*Hj>i;U9)S3x44)7O9!niP+K_2oq+TlhbkF*_E~PyXESBu-t>j@?&-S5Z>Bgo=`izpjuNt}R z_HSyj%GCMRE!v;`sLosSCE)N-_ZQoM1Ai&}TKMtsBP5Prj&}044T)^?`&CD8>}*J% zv%{)n9;-4=tMr5@tw?im!lTl}V3s(~cH?JRR`Yy2+i&PWAxhvMh93rh4ANWh|1mpt zE+)XfuArJONE{uyOySzH+5r#V%p9lm_nndIF6N|cc4EUWFSe|2wIm|qo$Nxi$6(m+&>RR5T)u1`F{XGX37o^X*iBnM`&Mz7JyH5!^cX7m)sT74LxS=`SAD#l_mcOF3Y~QLuAHy z&3KA2OJ0s3N&BTtd97@D7m0EIx!d4{`ge!{68>uV7pE?j5xk*WFZNa(@LOiAglk+H&sbqdh-1!5 zb9Pwu;ifU=nP}|(Ujmi4f*Q#fS59*#H1_o)N{t^6sNFCryB5cmw!}XA*x=Rm(xz{${ zBqR$3Pb6s7GR+XBz`}Bvd6^1&kvTl6SQ(2plEk`Wbf_p#s z%i!v6$2k~j0Q_Z(;{q}1j8Q1`iqa!$joe=!q3spt6mOLTN*=M zd}=zIlO5#l*9S$mKfL^_X}s@j$;*D_qx=&wupjO+_)z)w%!z14Weh0$keOY8l~ zUbJx2Sbx17J?;?8qEX_*vlb4=GfQ;pR_3L<7x1!7-{O13&9iRLYCgTG{~de*V&Ed& zDEOz5-h+S5^Ph0x+#rG3wc)26f3=;d``GPqbVGz?f~jO4K7Ps->ic`~49xxS|EvAM z&6r82YmAO+%JaXZmwa*VLkuWrKf$7OC#8d_m3e4hQc3z`(H<9XNq?( zupHC-Ar7pjdVdNx>`cnUnK)J(_aTV^@sa>Zg-fgi=N)vZEH|#UM(ENXOYKkPY(w1- zY=ix9E#O-qoe01BkFwb_@2ygp92lIP^#1DA@X;=+Dzkmq#tQkOZmySqjf>W!pS-`y zn_M?NC$CQxoq+Yb1}Ch_`ezC370;=WCBxQea~xf7TkXR&klXRoLDXjpSiM zQ5y4f@rKRK^ZnY-Z)aSKQTO2U5Ccm6QT_~n9MUNG#sNp(C0`pZ9huT6tbc#*uOn8o zrkxf|)1B4(!@l0!8#MjfTBesI{wvG{9}kRN=d6$@c>ba@*u!;)e+KDu_%&Y(IjMP%s()jc)R%kvJd#<_X!YGx!@S1m zx@2@OQ0O&~U@2`{cJ3U__u|`&AF^6|t%v#T{6OZrQ2qpeGu(&ppCDDZf$|UWDX!7p zzpoFs9`yRQ?d;jA*0Qk{w5mNG-Hta5x-xcu!^M!yhVI)(lq$)rDu*-kHZP2?Xzg`k zxJGj~-am#II0jdLC(54&;5rO`8Q;QTLfnQ2-}2yR@C_CE^wG&MdbHZtQpeyibTgWs1V%^&X{ zLkwua^?*-DdISFJ)A}_E?^5q3-Y?dz8s{N$vEqpZN#`==muA=VXFtC&TS3Wzy(s_V zd;xaGyzb8jZkUtR4Cr+4jsTqd5d)TRytv_C2P>2i>J@az%(X1MwAuOgj- zCw~Jx)$FG{Q}QMX5>`n6F7+Y9BMUsf6?pjU^`>>#xkNdC;-~rdBAoe%K!Cf@O@1vG&}`JlX8ozjQG;rb3v^9Glvk z9pTyI-TG3Z?qSGQLAAAVXm;IXnf#Gi+wS|uZaYo(0saBRKp9+T_ycrs4+h`o*?fNP z2c3WAr<7F;u#=9;q@jgXg7H^j88|B}@XCLhIb zIsWoK9D5K0YH$z3Uxf5BeBww*_g|=EH0Y}zuKM#zgNNrZ(RI$6>2sg%n%KpW`7Gh$ zLct7)$ELTkvArg$2hT8&kwIk3oI5uZx*zR75d->g8{qShzK8#IolIfI!JTB~<)A(n zq;o@-mX{<4ZgU*Uc)7A+VGV8eMlFh=_QwMv16h`_uTL-YsGfcAv=p;i4z?NkGTrq6 z>fXa&3U|tGT!SMWeiQG&Ie6pq%{R9wPd|5?|7+e=@>)Zj2C1U%TRWbj{$^W(Vh!ap z|IFl5<388)+O~P{+l74@Cz`H*+DJbdF(r^f+(Zln!(9*m7E(5Ri{;LdI!Z(4YszE? z#Lj*TO3N3G(BUfB#s0%KpGhfx@JIdX^EDIy{Oi-wT4~mD?x503XZHTc>1dit5QT_D z3_O4v3I8S12>2n9ZGZdGq{1$hH z%3<`&x$yk#$T#n@KUaBi>K}c&)jMCQ+$_Gp@uT#>)m}=!{1ZbYN~+qa|J=9?ExgtP z;$W0NAqJ+vt%XlVs&$JXYPZxJDo`ALcE^6Dfrl>Mx#4ZR=)i$>w=2(D(vlMcdmK4_ zyVx=Ev%Qy|y~OA+gTl{Py6@-jf8)2-@%^=fD1Sl>tbsesANxMi-{F@Ut=E}9~ZmzuJvp7Z{^z$|vgh!< z5Cdw1@a!ADJS~S`vf@uhtYH2GHBHY9{cDBMeHb);Wke+1-bPSuI(;|ukfY=kxyDxB zF7?Z6g5~f3YX2v0O|}@$5K@Twh=K8NM+KnnB~q>1c>eq4c#kHqjTeGalE;%D{~J3g zLlQqnfL;~SR^h=NQvIA!uTix1|JU~q{6kUq3o$SsZUlTsq%+_r%#+T1DP?d<&VTGR zM{n~0p`8&KGeqI+!kY}zo}s*o_Ht&q!#dttCTs^414)Y4>^({`CB4f0!an>7V(;X)`zWheI?vuAH-3KzPgHv z5*0~o0ICT~5`PG_Gf^Ij2H_}wLJaJLy9a(4Qcw5>$Pl-h29pMS5NR*-BPTM7T!%5v z@9a13-{hqmm?Q1h`&7Tp%YPP9v)Rg(9+@|=fb)O7f1(clF2ukIxL4r6MY;=qj!4;Z zrCa%0oAg?B6IBuENzPOFjlbH~p&(})>cX-noixwOXYc~nvK@Gwi8I)SD>?n!S;h87 zecu-`^?C%_ed1`GUJ>1$b5uW+rTOi!kQME`Qphk}M@yalcwd!EbX zPan~36X_Lp{5jFrZ;14Mg~jWXs)Ym*ZEzpT1%dv7rRW>m7RzR;_1hGN+ft7xj-VZZh8IF zc468b<9wJxyoWy&ZV3ECNPFBt`4_h;$sJiAl5pR~;!(ghiFR}baq0O~ubhjDMxms> zh9F0>fo<-zWV`Atk?>%SC#&7|KUu9+ev1(`QzOy#88KiEHxK@Eq@&@J=eW{jzT047 zxO<2=-a){q)X_J z=2R0$F1cP@A4_iZjIy$0YA2=$;ZLcm= zI7MMd-=AM1{ByVU$(ehPNq8Bb>GaK;QtQ{UqW)OVT1y{f6n5*(Cnt-;Ei&%p05ulB zJz_uwzx!7B`{93tPct#xc19|p?fW$)tJ}wIDFQ)SUO1`1l$Mq+U#jf;JHIg7$u(Y5 zwn}%w0~;CN{i?NLRwv08vz5bNjTo2;|4;a5;ZMlL`_Eq`IBm55bpPK5t=|Vow&kv1 z>mLxWeD|4a@j2G zpH8jt_n8`(byz&!eT5k4gWp{O-y41veCeWH!|Dt4SVi}@mMd&6;`aBAOD@)1>z7b` z?vPy?@AU+U_MQN-wP;KFsE3uK8G`av3)?;Zf9KlotAW1-F<=9~3cd)wN*?N;Z^}HM zj*p5j)m*bEE1GMa7|Ef|3fUzN>UMpK^6@9{jL&(~uWr?^zb?DXEhu2^oUK##)8k)z zOK>Ft?LQC$p76&6Vj19%hwpWL5$6Ht&{?{x>hQxOmi^B7HOh{ZZl2Y}mq&l@^lW&& z>uIM~UQ!LG70lIC-OzC=R)+sq`=iiAwEsX1M8S80KXNGIAO6Pr-llmvcShEy&>7^) zLxaNmWmuim%qX;?{Z=#}DQsPCbdJ*LW9HRfb}9nVssX|?e=d02-unG)oU<71Kj7!U zPlL~f?+@S1@LyWqjXc$R?*0D|=DV?@&hxb*Bg4Ztxl-8D3-zKtg5r6{7uZ$wPqKUE zu1&5yx_WV^>R-2Bp2-rl|3D19gx>&vFZ>Mn4dMYp6aCLyJ*?=7{+TWZ6C?>*qYk~g zbhH;i*mN<7HHeK>OiYx-CMND4d}NH{b1_LOw9dOT!(Ef`>;o~-1KWLG5Z*llzY_kN zY(iBDdtloRkA3iX5}!Iz>~Jf#cdBUq{eL zZ4C~c&CY=8VQl>H+Hx?{cN{$TiB@5<}H1&r*LXfRk;A{lBY z;`Y8{H9_^I@~FYd7E_(953Z}V3=R_w8#TCV{$-KZ+F^cA=-~_EJ8L$d&m$S{AA=tR ze?NRP_`kq6@!lWX`?>k@cTT?x9i2l14mmJ%lw+334~qCW;nyF5=-t#KPur`1(f&nu zvjs3qLHQG6@GAWC@CER7;S*w`H-G+qv+wYGQoQ#|qB;`yS8=fhi6;je_y@!qNG=SJ zh;##b`YDyy3rXd%3pSF*&CCDGni1{wemgs8q@w%@F|Zi!L-?nVj)5EEDlxqlneVNV78 zm56~|aFv4uj=_RLbTRux%Lyu4(1b*PP<6 z`!IiZBlTQ|vpubfY&%4LFyZuZ)W1gzgu`D9-vs_H`1vApl03UKypO#y?^e&adRdw5 zzRYtFtG5SxY`QnTHGeICG}Vs8n;=(5ijq&fOtxF$+{k480K+8tPs5jeudB5C1Y#dC zAcmg~e+~Q-@Z&X>y3^?{n_?6;^roNp{;UxoaF+6zw$w-Casys6@w7$SJJV<0ql1!dCO**e;xjnJwXw9<{ndltjMf5+77gVj3tX9LV z2Zd=ALIW|N4}Vq&>Y&1pgCAa8;;;6M$)`| z=&_ddrXOis9$o(6S1RB9WJx)*;<8l5uDUZ^n|Y?3M%xd>z)|=Y;pf5s2;ZJ8;Y+`i zEJ{hzGb@!{NGBC}g2gL$oRTV+hYKdNE6q3qPq6#s4--xB-OzuPW8T-yzwcaav}Pl| zo*BCRiLx)mz@P9Z2~hVB{s1ZJpBaBl8sZlfv7%~bQcAoboB3w8zW$wsPBnbfUBmlN znMJI58~Dqf0N=S*3eTN65!$>$Cf8>63Ck%jzC`Y~8dCejH^NmOH6a#N6*!?QI}PqHMg?Z0$Pe&1y3~F@r+r zAqIZIdOv`_7`_{Pv-n~!Tc#J2QFu6zef51+Qe;#$>s_=oBDk6p`fRb!=6y%R_gMQ6 zosJ(x*2+fN7hf&pw#mG`5v>-%GZXth{L%3BgsA%jKLkD{+d9|6X>idyopd6KGrss; zwA0lHE#(cGs*-@Ml1x>J?{0&DBNE?O-`%Ru<;9;zRAbw4INmjG<{w0a*VT6rf+=Zw({F0GtW}397;9V*GxH_ zyB)7@$5S%SQiutNfl~Ml@U!8o7ZAiBxgTf~!}*?{wylB2 z^Ff=F!q)@O*O_gy@ct3_Bj6u^Ki&ZEfrCGQu{kJMfJW#XCcENzm21qM@al$xZXcP( zic51sE_qIURpTLY*i2@)OU-=J38T%@&{M7atX9Kq2IafO@N5ck1TnAxei8ho@MGW) zUDR!gMD_*!jjYb;_JgI3QvZU@%!^Qp;`jHNRI2&axvHBRif8@4UOCrG&^JW zHb5sv)WBbj7;uMg5Qg^G@N?la7-@wK&K%}JvesISV`1Dor{B3nS|>JhJR@ZLqNM}# zs_9~Vs{Pa{D~hhY9Z+Drxq`HB#kKt9J2(bhJCE`w#K3;|p777XuZM3F%8T$;2oL(K z88lE3TF;Zxd4i*2jxO?sz2@ z8`y^{q}kB)BiHh(?fEzyYwe$?NAc0Zw#^U|#`fLH~?3lgY%XogNvjUwQgvXCq z^5QNycUw#)rwt=nHViy}1&EH{__tGky5*q$Jz}5-_WQr!Z-k!>U!d=&xa|45XCV)A z$ys(fAscvJ{%!+s9Ux_S(FKh)!`Y<#%7pydS>?1_|D%I%6MS2?`|uYb1}4F8fS(Hg zC48zp+wbrFl#-!?%;wK?r}8+v;=^jlCrfRu>C1N7N)K>2q-{ZPPQ1T5?^~w-q38Hz zyn7ijun4|i1kQi(yWB(jA5Ov{D~DyI^z8z=#O}qImlZu(zN5QoY^t^{rZEI{TgrDO zSJvCjVm#wsIPg3%!o|`&;Xknarj4}i3d(-qJHl5vgy%o-b>Jr_&Oi9PCtHu_P4Zj~ z&alnxGU#ORg$%3E$;B^82Avsoc>K=(#i9(RJKfSWe?-mNlAk>PZ@F|>fX2@9Duwt9 zF}M}J1$_NcCP%m0)Nx`uC`AqFDhOW?ENuY~U!X724C&UEmpIp$a^db`?bXRfe8 zu-{ZrO3-K$Qu>lrf5<&b?(ZzA^u%KRWOKRVQ8^uUDHr z8+mvClK%uE`-e~m6A#?L`$ypag5&NP_z&Qh!1v9*Ei3;1-~9We=H3;x#xn{ZV{hZ% zzee@5H!jIyT$GU~*stc@Qw{%i!jb>(9h`44rA24|H@^LV7<7kU1pgWQUyJbm?NK!q ze)@D{f6lZ8W67~oRLAl-yv$rY2_!lD+-B_z=h3u8`uS_`c;5(TIj$;MXlmP;`XArz zulN6BZ=&o4G2jpX1N;y0li;V59LAUXyRXN$YN>qCT|ko8aPKGoUt?D&MIygX^J)JD z1pMz}n?CuOLE#pKa6t@6;G0L{+&3C^z~D#X*eB1HC%~V^PD*ktUGOzRR04d;OCqg; z%)EAYT}Qr%EOJ_Q!k%4F-tO_Y4ccnN9r%+G14-~3;2Xk!3_r==D>CtIuPIA-zpX1# zwibEomy>k*$i(s2RzH@AyHshd4(x4a)!l|I(6yv%;$7HmK`6gf-klkYxsAGCh=EM_ z`=U?=1HTr&xSWw2$l|Ym8axRlx3Xy;qRKRh6dNj&_ z;2XmiaL9iSZeWV2^oypKXgjZ&dQ}$Lk!1C5^JC%L)-Fmi^H8FQHI!eL zdUs3*0K+Nh0PSR=b(M+dseC#+FZ$Fi!mG7c+MTP8JJ{v6hd1aW!e257D0ob^=m$fs) z$-5|jLJY9s8y`X01Nm!QTS^3H)pB2eyd4Hja5Da11$= zymhaD$?Fn?)C|%Ur-=mx?malF|ygy7ep@4kyF2ACpCO<>Y!=4U@Ri4qaxR)U$Od z)zlssKy9b~ce91*pm$IK?)?!1A@IA$pbg$w?0@$Og7t!f@u= zwZxecwD?(vMQ{ns^OKgVwLSV4qS-yLsE$++}Nl2$n=d4qGvCb7$3 zcBrrSlk3lB8~r;k%Pz$G9}oi<;77rK3*R0-ozwJvfh8ztlwS$sz)$KRb?4D&=vBu* zCdPBD7M)DiA7d`9U^UCO)4hTB@cvu)h44SYA3YAo0r+GEiTD?MN)V(-k|bi0#7y20 znk5kk$@p@CKK)gH4sEp!&sDn1+eKTkp2zc(dID{KC4aCq%Zl*+Tg2cK_=jWB{tx~> z_$%%8949TId$AVn=3Q7MW}Wa|wdcV~y2{cb+%>$M*Obi9K1y zEG*;mYh+~@hwai>N=rAaZ{7Z*-L>Yo9t+j#)=>?uUOJKDURCG{gHjxgd;Z z`hgdb=@(whtPM|a+gtbOk%%cty>+b~izJoFpqG`fWilSWA zQU4w>Fa&-&{8IS8Jizv^#yr@fw>h&)g|?g4QP*wQLHCNR@Nhl6f^(W}vHEla%Zpd9 zagO^+ErJ%TG4xM`$i`fowC}_Z`ywCU`6v9b@Rj3m{2z}pSorRo_;4ND@C1=|OhI@? zaA>*6B%Hc#A*takPG=pye ze+K*m@R_SK!fjoXCZ%7{_oJm=ly&`l<3-lT$M)f_lWx0t+6LF1aZiho#O#PIIpaJg zHs$&!u@LS5+UtJ&gBX?K-Ul%tzwe2Lza9Pw_~{`!YnQ3!?sk`_sdrN($wW0QZbf10=pr_=>;1*)6WY^Tk82SbnAp1v*WQQ$Px!as-+})E zzF(wi!P5iU5`j2_eoNan*tYyHd0n{G{oLH=;mprK;Irk2AzT534)j{$&90ZVI{$x{ z%33c(v*9xMGY|to@cW5y?>zx^kV;VgQb?m)lEu~=x2`&V-t??p)Lqv!hRrAsFT4GE z?DH;b$$G(yb*sNV zM&&2Ct~-QXdz$JN`&@}%C8x3)z0Uu!dW>s-#NZ?NqvLV>gC7Fl#k0SeJM&PFd5Q6- zojB##)UKs|2|Ol^8(FlIR?A`9r28@bSOQZYL22Ep>Ls$0(9WaH<{a__-~UDo{DSMw zHSlxcUxHuXFZ%Tz6vpBl-Dm!8c%B659IQone4$vtOIR8?WL?UR}uvLHU#(`T%B zf2!hIQ|m!rvn^|uePbK+7Q+~5DkhVUe+PddVqgILyYQ8N!}kZ^8z+pY-?ZjJ)tQQg zLQzC|K{u7UItBOYhAq4WCwmY5Jp1r34`k6g3#qe6`kQ{XcfxKHGjD%&z65^9oBZo+ zUy|&nX#0m4mrJuUkqGQGVLts+3mTvCV#9LSD|G_2=xZj?`a1hQP*t@{4OOY+5SI67;=;7(4<0IDCKj z$Kg*Vj*V3@JLvtj&Z8TegtiVwb~8^}?bF`TAT`!%e)ybF_)pJYO@EF49}okV;TOVB zhkplt%h2^*mq|pr=2&@2q>=yr8?U-5nLIVry%0QDZ+Z7ed+YagCze{uY0LXAR#W=H zX8!IZ${V!(Lkz6NdG}}d_u&`7ryf(gN?jFt)HYoxerkVD-@tcW)~BA4jOh1dL&Yt& zchDz$QQmEknc1rf6tThjn_VvFr4)4k z>GuD+jf8C%alpUm{{bw$HzA#~h6V3dKg3+#cUKC9zaBsQpj(KVQP1h8Wld{}B9J@a3N4{SPs`;2nu$ zREf`~!=q}9G_D?{6ht2ik4u~2xOl3>Xa?0gS3vq38D>ew*zZX6)ZY=~_onT7eJ?HU zFyUM|?tLN#;^5zgUju&{{J@MC@m-8v`*k6{>|nHZI1Q%zS|S|LHS7Hi5ejQ#hWTH_ zc9IQ~*B%a1AH2Ck(QUJ}Z8I%td?CBv;{D(7v*C9masD|2b>Pp@CECN(m)$f?y@*=r#FMKd*jeJ7}O^K_#=|Gee<9yl|QW=XYdwpP1=Y=|(*y)Q*qazyF z7ik0h-HeZk=7i>yF5Qu(sQ;-`*5p1zff+$2`#GD(g|2z8m#EU-1^k_>H3phW_%X^gz9wiTlkuYfy3~# z;NOIQ6MjCkE_k1xoznUpxcJlqtJ4n~E@!G4dU>1D8tl_M`oEGt`~mkr;lF~v1pZ?917D#1 zPg2tJsh|2#-VCmLQtVg#BFemH-46D`!R>jB_KP{Hqo<&Wqv@%j9%hpK>_;+F> ze820lzdJ>0_7V3#5rbN|?y!dM2!Aeov}o~_)o|s|*N@a6d9Cu9IAr*qI?X3!k<&Sj zZ)_}@yr_HaiA@vmKNQ!;u3H~&%&`5g()jhh=(jTnCw@ZR7h-?~KL&mTd_R5#qa^K|1ze?Kh-a@FdP}*aS3Uk08YgW0~2d-YQlWI7enpb`7KkfhO z;jcgp9EG0^Uv3tzKjA-JCgpepX@9bJPr>`RV<-Qn_-<$sdqKdw$f_+p|1D4YjVF}4 z+#K%g@@EaRH+@&uu9$1e->%-*G2$@!H9u$_Frfl%#BKa`u>5=7HsZkw7)|P^oD;5z7zZ&|DZ8rLvVnJBK6Q40h3j_vq8v> z;4y6DR1fQH9(=}oqh)N2Qlpfq5H@4f{b`iX2CKYW)f3xnn$D!o$0^iwC1{9&Iq+Y= zKL(!$Us!I{yDW^^BU5URXJplk5=ds8r_-oY@<$UIjD3o4o=qmH!)+P60!<~>p8oz$ zo2>p@`{x4qYKQ?d_`~AS{t^Bj_-9NHjC!8Fx-Kr3(KuLk;=;y1G5$3TVpXjPc9Dym zY5%yp)Jd6LT^Sz~vpkxoez)?slS*N-wkuHue+T^a@Rety4=(t_%d^*aAw+Mru9qE? zXp8gvH^!`7HpNe2Y~M@l{Y)Kt@4(+;<{tZC%HOp6IsNxf)VxQ^H(UIsL?>7$C#J4- zc=iM_cm)1F_zU3=e}(7YC^rW7>2pr8cnODd@r;4iQsbWb_o$b2OpCS-b(6brXVB+M z?v+L}%`}UrWF6NzJ!*A#;|1;gU(4y%qwXCscny9Qd?x&L@Toz2Qv(fBOF8408_wyy z+tgFIX=vdTBkHG2BS!d=WZZWTSn!uVs-erJhxj|qe}BEp=5AY2_Lcq0pwfW%FCYdQ z;P*;kjKp=18TAR z4qDnT^Dd3Ije1dO7@%w!Xz-CrEi&b16|cr6K=M{43&Z?Qk)JF_dSh3jD`H?7{4n_M z;1|HxU1PB>-YO$$m;OkOskY8!AA|hg`V}{D9GL{~h7+yev*f|bsz&`~%ms^`=1{k& zAN07A+o|6=l8vOWHTxy?mlV%_!`}+O9{#{N_=I1dw0mq`O7RDF#XAJ@16({AB_zpZ zG?>RQ_j|wh`mmiapX!nQ(wseW*9)B&qpdFOlyEwh{WbsnP!LL`41z*LA_lqeS0~~g z9Q<*`1d)_6j&1HP5}fa=q&=?w&-9SnaW&iSI2hWD^-&pO!8G2hvIO_#9?{1W`TSs< zhuI$gZ_gjA%Tb7}h=C0FyWun8d%%~SdthLNOCp*&0{D_8S;uW(GY`|KaqnHC(~_PE z?@}Aq$0z7mt-V^e>}&jCrG7TF*&?;@7a;~-z|VxA0RI&H0lBuK4~rk?}!+fph&-7Wi=*~|A;vv&CZHDi0ON09|{w{f{sl0$BPj*$I{UABAY z!6CE@f^MiuDd3mkt68v%i)`sOm7s@PfdAZv+wMA z`;+mvi~K=G@Ytaios#93#Dfh>l3qsvZCN_wU9LpUTT4mCAbxWaNPIp?eKT6nj zr4WgT!P)R#;2(xRrUdQpSSn%$b&yI?sIl+G-O;!O?0)U!ENxXkp9>Lx9ACL}MO}22 z^-JQ_&^Kiht2X)&>y`J+>D=k`IM6cdJPL(iBL-yk4r%a(@Ylod7P-03+D8yf^K={J zw7+;^ZV9hGK6dE5cOT`Y$DOU|GhfM_&J5glcC5{bg7XVm+Mg2|QUA_vDHjQGyIk8T zZPI^qqY!Hl1HSOz!tXW@$6xq9Pc-_tFu8`Gf&+$m3l1%*kn&6GrRgpI^FN(zwEXYZ z)3~Sbha(0O;Ey_swrB8D;mc-ibhHS{EfKoy+ekOfd&MyiHCTRm;$#25L_@hssjy?gYO4_Km3$So78!qoXhuITzDuVN;Q8ccT%V#$JjjhDDOy$q*VKkE=dnv zRB|>nvS!b5YhEsOg%8@_cSdzKu60?~_Mi|)5QFl#?!5~CA^g+uS3DV+ZT4pG@Y+bP z1cg}j*l~Nhd#U@5z;4i&R5(yq|79!7erVz^h5dhO@8=PzW=`z)1KF@Q2Jt z9}Mun6xzH(;;-48P3PD=K~C_XIwg7*O*cQ*EhqJCu1oGmwavd&|MRt=mXG)F|3nNd zhu{4i>R#YadxPiS*JtN8zIRoU_O>DO1<@M$oQS78;;h~oac+sFN4>b}VGfmQ+V&bl zCH2FVB!X^>8MbZOA9S{-Yav?`I5)WZJB6r+Zw!Atd@uNk@YRZszrLV?J8lL}RGqRe ze6u?V1$n2qJY4JS&i_-2r+_g$>?bGdsErjeNzlDJ;niC3uc!R}pb&QvgD&uy@UOyu z37?D$$9Ek`s>jKHP)w|yTOjn_gvKzr1+H$^DPZAeJC}H!Kl7g&=2#2I! zX#e`{j(KBG3K5JL%z%F!ej|MOQZ#?e-5o#_1c=D)=!lja!ASLHu*&d$baHN_UQp3@?*D#w zshTDby(z>T#DEn3zwocXUkd*BhwytK1{R{;qaOY=OCq+3j|4j-Z)Qr;#&u zH>N)r_@IR9YRljiy?0f+ba%$ZV;29Z|D%XL*!J*E;14>FwwLg?!RIhvo<3pXSzM*6 zn>*a~M6j~6$*O*2c@Qr%$7rg3VQ80>@<6Fsz{w9hU*9WgUV$IlZ02vH3_r9s`zN-v z26KN2fvtThga9$<27e{|?hA1b3jUYkWF_Sd2sn1EUt^f?!qX{}_3K~sHaxuCucX@O zU}2oG_2WYvz**!5jsz{S%&78GV}UTi0z2MAo%;?FNc2zzSGI8bTv8V zJf(U)hvFV@l_JzjqE;Dcdt5k^I&Ozl>)@x#G`h`B<$u;%%pF_iH#DS&m9+i!Pv=X} zyhCl7s?Z&GEvr81{ z{B=diE20?@mYQ{yl*Y^{clMgSEqc~cXlp{;n(RE455Es$KmxxJek6Py_!{gx(}pj3 zyzp`N5t)xK?zsABY{oW8u6MK-%aYR7{MJDW<08gdrj~(-DN-|El(%)&;Cr!OgrAb_ z7DO-r=b!NVq26Kc1++ni?+)LzRFvgmPxmX~tuv{O>Ed+KWYQzU{*&s4B)XSi$HdNxFlwTM+#DJS3g*by4Tn2v^dVg#{IT$};d=(D8m+XA<6V#H$1_`-eamNKiY<=)PIjWW#a5>Z*|d@C z;^_^1wY&w{ckKMpL-IN2uit+Y^pmUJ)@2zukV33P3><+!H3|2g;lGD3E?wa)btpLI zkub(8B+kT!F|B~p-NbEI-7M3(snaiuX=avkc20gNyC=q^Eo|f!T^nUo)mrM0QtWmU zOW_Ye48*~AfgcTjP#HlidzO$VR0$qlcZ#u7{~EP;*~AIfuc~gZ>P5=ovHa}qG}CKF zdlN71c{k>_0TqG*;QtN(416(sD*PpZ({|+L^XTRt zCeAB;)<2_`3=DL03V5cN$;rGs?03Gpzk}%3!~jjNLC=l%C7iq@X6K2&A%9`S0c8r2 ziWvL=zZ`zwMW_RWpX?uL(|!ID@=^KpK+lTC>O<-u^{&YMEuF}^eCffH&_z#`rL6mcqJX+ z_S&>&L231;!oCe_Ui$5EAD(Mg5a2TXn2UGSW5rAx1EuN^>VVnI7aiN*{Zb5$9gK4? z#DG40WB6|H8{oStQzs~&ralfZD&A%_{!O%M;-huTb}~$S0v@Yex|1miIXok8O_*s` z(#zZ^AqMurKLP&~{3-vU{p;?n;<}lCM|*@le8~0`mIv3> zJ+H7%ke-hVPMu=oWX*F~Se-T9#Czc7=W~5k63%ZiSo@#a-`*NRAwI)D1-}ITQ}`zE z-KpXG2I=2^IJ(=1vO|f5S-HF3=n6|NFFjcFn|8+Q=gup+D?Fn9`Q1&YG(q2@?#wjv zgd)?`MYosE7Co}vk{e0&fMGMKWZ5bu z>D%?X1;*d{KOZw|IEAo64D?04&r$e$;P)!W^XFDVQTjBqN%M!M?y}2Ii|mu#7%O4@(QoStzFN?7BHPbBc3AiPG_$^oPVan-|Rb&kh@;t3&gdX9ql4EI$BO zA}G7kAg~tZ_7iHxGg8zK_-Y4;CGl0*+Ht8?Pc53TX!AJ@rf`1gg`b9i{vjqLX z!JjO3kKDfO#{Qgd$@~Na~UY&&f}J2fQl({pOiJ&Kmp6{lz`vzc%#gm{Wy` z{}f#Rw*McY%xU@~OLRK8j-n7zh{4D3&EV7F7sK!IQu1!l%h}_?8>z!<%*0k{31yT^ z8tXz%9uVCxvzeVc_rMeB%Qq)oB1!LCu@5hFJDt40WBZ>@y^bSSjHVDf5QD#?-suqh zzu*shOAwz9U33h}EPtaJSC}@%Q`oS0LEeZ_>(Zk15*pVmDDL-h_30=H+sLiwBHtLd zQDZ9-Cxq+VZY^8*HQ8>Xvsf{D?VT$qaFl!d z4sPq?e&_ z+h{el>w@=71XsCbQHj+yGIv)duRmN6eoA-oWS`S7>E{{UaH0`H&cGnjQcu{xn_tafTu z`0j({Zz9s;?s38s79YG=+7FY* zQHZsOf$pgHIu2h`8})ziYn+bFU%{;8dIYH)dTX^kStJT}IHfkDCzWSdRu%FrD}_Zn zF?FqSO#*AD(xi_PspkDSVVlj`9{E9z7?1i-#K2_u>F^K1cY{A@jfRI=v9fx$#CTsY z)ybJ=<=l|$W3L+hh7po(KIZf}mT`*WCT`r`c!hzQb>K|3&-*^UI_!b3BA! z0e=PjI`}u?pNC)lS)g`JGN*d3Yg(F$<<96{N)|P9cHd49&OF4hKUZXVl=F{%qNRKM z2}wextvmT_YFgFX4y3R{z9rjsLWDZ%KM{jg@E50{?_C|VgM+^Q#dB)#8|8MKHEX3E7f~^`9;xJ-x zH+)COi)WwuA-XhI+N$HV8k48_4Y@Ao{@9B+Rt|8hJ&T80@T%#_U z={~Xj(xrWVla5MlQ?@MmOX0BSPYSUfG58w35Bvl0=fQs|d}0t+b<~(gJh7zJnMF?> z5&Lqd?S6IbK>OQASMyl%wR+?*a(0rQBs~4NlZMJF?*8jCw9ToFEGv}?oBn?954-OK z)PEud2B6+80scMsTj7r=4^{BqX{W939$6SGsbU*(bL>^EqZlLkD;}3rR{2*+=CgCJ zx>nH>-;hD^hUw9LY2Wrg^F6iA_?PhO;A_Hv27lNxJbw+J6?b#E@9Ie!4Vr0tM>DN_ zE{0aIY(fJS=4iRETU2UvdS0SQKt^P3;T`(K$T<~tNB?lhS=m%<$0%%LwNHNedM->v z{U>6O0beB@ZIIw+!M8q=t0D1=@2ws-=1PMwGUxe{q?b=OU(<_?m{3*B8a3|9+aLy4 zeeQ|4x)B@wEBku}?!2|Jefgc`gx`$ZJBdQ@5QDOM-=*-+z^{kDiCd^>LAMo<4cfG~ zJEh5PM^9Qa=$7Y(r2I`)>1)?RP`l;j3&A7d$1x@~_N5fwI-r+G5RT)>XItQWRfTJ?lMr zJU7SAMOHTZ3-GIdg;nr>Lku*)zYqT~`~&cvOUI<9zghz_F(>aQMY8zCk)1T1_sGp>Ev^lZf{=bU0o$tm}3Xuz674^PS`1jxo;g=}s z7TdadBr|TDt7MyL>v1NY2(KyF;42!PGwX(kT2N|hlGh+%QB6Gy7Wy%+FCNP8<OizgxP-JReTw8(lCo_3ZHeO;qu=1Rnd_eQ|RH z&YD3Xv=IY);HSg4hwluZNj0WEj^GDY>TnkQDcG9oN=x^)S24 zQu6v*salTmpAh((`r3+1M$8CvGdi#5kz*BY<@dp*ALBNsm@4~j*)33O>PMrV!2bvS z-|$z#uY!LTekfD2N!zNY-Z0xGCic2Kooqp|w`1I^Cq|5I{KNXr%dRLYj$UZCw1yK@ z@6AaN8b>63Yq2wI?9^2lMOn>IuAev+wb7P>(siQ%oUX$b~oA5;PPDrB+?J!ig#6X7$%~`kE zIQAn3|G<5RH}JQ>uZJI{5KXGyanFA~?u(0{t#ErLERH#a58+AOtig(Kk6evjBPr**@C|# zysi*R*+^+I_Oy<-W-b zos08N!~hNc9Qb2b$Ps$*#~B#6i75{g)exSlgm( z74?~1S(Q778E=?NUAE8Et=QUypHm_0DZ{1n{x`n5ts7q4en~FR!@Up0U>bZ5{J-F5 z!FR%A9r{#lb7k&fQ`>cm3bS0I78&T8N6oO)O}l?MRcD@asEt4;ljcixTU3*z;%X8# zQ79|9Lfo_!I__rMqiu3W=i~enF_;a%n-J&T@JrwuYnwB;W7U)_PD*G=R`d6!*LoD} zG@g@ZbfRB^?vi?MN^Al>MElJvDd)h#yY=FXp$jLgG#C5JIR1nA0t#V@7%Yds0e&fb zg-^Ku@VQGPf8E*cfv&NP6*0$X_SC4A7dfWqwE{j-qs3)9tig(L1=K1|k(Ao_2Y;ZN zyP=gqv;WJVY^ijbCWV-Q7#M*2E@AM8uf#PNe8oGa>z`kf8!^~}nrX1>e~IhGg3d@=mG`w;wbv+qErmu?tPj@cl^_3A@0A!p8@}0 z_%!&o@P)4~)%wOYm@?nrkVeNJ1$|LxHBL=PDkG_oOf8j^L*V|;|F;G+*eblVK=ZgW<5pQ(v zW;yAQmdDJth9r=Zo3yUg4FTN}d(jTqv*eNrKc70GG^XRaea*MVekU`W(!%*CV(>5c zCh)Joe*(X&&5kj#gH=`}7GKiue?6EH?_4_L%I#QzL{V=~Qm+l4i%8OB>C=g$`dfIh z_v#35?~k~b{H6Go=o5d#wXT25q#cWJ{~a-y1V0ph9envpeE*CoJAAJs#p^xxCu3dC z>e(7U*VdbS%$H0uly39eopfkL*2M#}wlK-Op3WkU15NEEvs+7{KS{J*jHQcl{)rfT z4L=+Hf>k*Gg>OfHHU8lO+}&HV!?03qPKKlF=xk>}5;fnd!k=2TcH{!@y2hvOoYx+! zn6@H&u~d2^QTP+K)5(fUQ1^fs=&yx(k1J?<2!93qXDJUZ(a)DSS)bxcwO31f8jNSS zX6PR>QM&kUT&~_N=N)UZ*Eg6`OK4%C*}E-0T!Q*B%{v8tGO`%{6Zq=zt>N?G`@-L~ zz+}t78guh5i|(vcy*SKv;B6DR1#kXsT$A|VO@X0WXg*_U$s^j!v;+J>4h2f#*(?X$ z|8)M7w3I@`A_jHgpNIbt{&o2LwF(BlPRf7TX^QXjn}*hT7Gn2Ml=Pgw>E{?i5T1gzXE>u z)p-69{$rY(>)RqrJ>k6F%tp00>i08)GL>toJkRQ7?yJv;m;!{gRl+1t$#oFXiI zMd!n-mRZN&KVs{?DxvX`VV~nViF!Mj%e>VlrhI>D23Ir(i+{M=rl!kqOFPfYp_(P6Z>U0!DmuDuY0 z%i-I>FNg01|L}&?XnI|j&%6)02}jdYat_XotFk$#@|i8zE_X2UeRv|R{CI7|9TP4` zJ*QXBw7M!Ne~!)HN*;EyN$?9+_*VS+m=gH+5raJVSK)iXe+6H$ zmMfTZCoVqOH=>a?EG4XvJhCHAgME9A&7GKw3VVBtIw6B ze!2eYxP$-6vedzU3f~j{1^9gUHSmk1i`44g7tD+aS@Orx*oT+q#ua2#oo|#|w6^H9 zr%&Kh(f-Gk?z_|dlV)h#WgcT~V&3&_)BgGgsIdLCyHpBs8ZpR&{|JO@p|6I;Op9HA9V|2ID!)e9M@|3gC?SNf%XRz0^67T zO|Ip_2vfw(Q-f&~!W}Vq75=Cjxb|3w_g}$hMstQRM~{APKEpoWddMu(o9c_GUi!@S zIy`PED@J5ZQlb>Jm{una)0o!2=1GBp&dN#6Ww!tPPT+l=$<_$x9*Dsw@HfJ@gdYi? zG-B%5^5|B!7F@Lam1LVeD-mg&h+5%8+S`;St?QQfgcWBIa4<49&)!~FKz)^M#%F~=CcJ;XpQ{8ad1@H64>Aq8Z#tj%%YIV-$_2?HznbINXiKfxWT`h_!V zbz<#kwkAmeYPszqK7W8n$4{=q`TzH5>6h=}>k@RQ&g5yrx|o=SrI>B(Yif~wt?I*-S3J&n2-lQ2{HI5 z{F(4K8loNoeq4w;B$Bk)`=uXPS+$pJ;PClJeH8PH&X1>BUA5|KJ|<*<+2^-WNzrfh zfB%+g8*<-Hm5qsEpzQ%-a0Ps4_(J$Z9iIPWo$V#LVMMiwsgPUuqgX zAMXohtUF5`UsbZvxqFClxH>VGzQxH*eyyNc_}(s{vpu7W35B2{1})$h!mo!v2>xG+ zmo0-G^lj-p)9c~P6XkoTFISx$+Rr+4O>_`{Pb`hhx6*$q_OpwfSIXywmlV7rNByVs z-(~A5#2CaN2mY{Ixc;Kzdw^fSR9$|=ckniq!K|pm%Z)gfIo7nw1tX(5Cze_j%f1Ma zhZEk>^tjHPZc?C;Yf61K?s4<_w|oklQh6=;P7(u6Da1$k7vXP&zX!e{d{36dQ>B{$ z=k(Gf)}s&s>Fbk)&}$jgky0nTzC4=9insi5mL&gE|J$$OUqcLv;9rA(9=;R&W(hBP zYECwP@)AhjKnC4NS(T&6p(&o+Xy|9mD{sF!(d`SYyW3im@j?pS3S3NF0$w-jfc$$-y zi+64roi5*6^|7fQd@xlgE33ar=y0j2SeE=h2l@sIF$FQ$M;p)I!0%>+b0GM#U#<`x z3}rXP8b@U)hnujkRL2UVA4z$VohzKpf^&IP*O~62n>5iYD3$u!T1J1ZotGtlX&7%o zA>^A~$9^~>Jl^jmn0Q~t5r^8a!!q0|37Cz+;>Y(5+fNvXZ%ZXd(mhdS~z`u7`$FnSD zhjw(3U*LmB#!iA`@AuM{HHdYo#yUD?H2UqVb%7x!6L=kp{-x~S8!1EtVsHce)$pU> zuZGVnNcLsYT(?Crxq;DpxK#ac!A4hxj)R1w9b!K|kjCw2%cUN+KCU+w_krGqO(oSt zA-@E6m?>lvoI&D|1R1-!B2+IS!#G%;Yi8;Sn6D=g~`L2QnifbC3#f7&RS|YLuuXq z^$TifmeCAFhOvohfPS>=3SDKxrb0U$e8gX+=D=)d*FvUI+S7_cynufd{(kr=@Snq{ zQXbnXGpni5YIH-2y@)rSpRc~37eXzh8fj@8s!+LMfeh_J4mFR<7;kx0{_{kghzX#Y znXl^4KMLW;BL-i={|9~<{6_ejXpdK-tL0EyM8qY#rr)>hH;yjHw3pdBEuvZ^Ti4oE zqEkkJx2bm=H<-@I;&3|C*k4BqJDZ4c@zxZ=12HIvc0bGh#yKcmj!4M673EV z9yWOX12NbS{x$e(;cLKG-?93)>={8U zMocx$crH!JKP-yj_?`3LR=ueWSp~63$=L5N1tz`iLJMR1^4xPo{>(xTjk-JuvY1tRA+I~G;Syh&pyFl2;U8U zK72FyixsURe5l32B$=FBER43A^^n6ZIAwY-1Jx~o@sZAIA}93yT*Kl8yr#X%$yvbBF&CM>_-e*!0&w@zd`t1_%#-eNi2gjeu#Ra zx4rtPd`6sAv<+45prI-?bpa*WjpxM5-$1kWUav!Cx>I|*FZwMk{};G#W;wi>LKq+e!psd~B9r%Bkpba#9*#>9u6<)=CImIJ! zImBVoqpf7Ua+9Py|Ma`rA=-g7om{4w=hJP5%qRiUITh^Q|mp z>Zi4>#r}G#5q=h8P}c5nHvEh5`@=u0et1_Ujb3$OlXK~@kt2$q-$+d5Kh_VCq$p6|QYW#V|_j` zL|F~#Mm#j~r=|&nMpfo5g?=v~Y@X1%gWkFo_r4K>bK$Ez#51t)!{IY`aqp&wg?Iqwl<@`sq6HSA=Tn8tIvA0?*E&a=1=Tw zWMXGK!G+r>L>I)scKCGoZ1`F5s~oE(;cI4C7yB-#ms3RdmV;)5n!c-+7Vdgr6!mcC zoxpPg=5k6^say32#rrfCU3&lQOn#^L{F`@l&CAl^v*&i4f5JZjp9}vCd?|eX!qufC zDum*gdiKADS-!T3MW@&~e8t$RL?@c-m3b-+6}NZPgk@D6i;6YS@4un$isE1II~4s3 z*+yv*{0PKg2K*=RpTb`##aC0}yFQ%L<$|GS?&PQ_ zy7Mxlpxr}#*Ksc5MF6*Gc_sUVzaX}mrD^uW9TZ{wM)v46&1gmRoxOfpPPOLeXBS(lg#B^{;KDY`vc?&8KZwBv@FU^dz|V)DTGey6+><|L zbB?uDw%XKKup@%}H&h{&InyV3TlN0be>N_lDNbl)mv&igF*8Y%rO63yQ|vD%N4QXk zBKX$upTLiW--D1Nc6@%R97rZDe67BmjJt1LiOc=zMO$+pa=Tw<$Bvi(tgXt8i;d%5 z;O`$aaa_Q|=}QjWoAu-DlKc-3xQ%rWqJ3)%C;F13@cgl`$>{8NE@gMZW2bOs zC+dC?gDLRm!k=P>cF6D}$vwyFsGpup4=+A&$VUEg-IBGMMFSfc9xge~X1?qNug%Tr z>(KmRI@^$H>fZ3EK`Ph16QSLxx^}rQdy8YPIR8WpK7r4Iza4%Y{3VK)DWMf?ldis> ziAY0lRRfi0F7Igk*kOjYewzCjax`kiE^^8I@C(5gUmf+_J(O`lv9x{hKg_i($_6(I zp@JBc!cTx74F3&$i4j$m{dd%Yp1yO8IfrkYBy|u0v|Q%)_nPtR35SEhpREg@7@UeF z55$r-#W!rp596NwP?So=olT$QP9aL+Per@W3iuD;_mM*zJn~wm$iEAQQCUM;QM z*_O+GWV$JjSssaq3g+Gnih zA9fO6tXww1Dd6C^_?#li;JKXKII<;igW8V?u0X9DbpsI3WMT5x`!BLp6n0R)pPkRf zy+8Oh@OwPQx#tEPgXD1?T0q_zhRVkz#-TvDyZiY@tmw0Pix2np-DAUwdo3|?PAR9d zll)8fl=btJ(#sW$-K%czmn;!im?a628N`0TR3PQ`PeSBlX6*e~A|NG_({vP~wycoV8 zVsHukMeyIlp9kL~Oh@qAAYOr!KG$JGtS`yxF-Yn05T^@sYfe|Z3UrYQFIK0_c}#t3 zeqFQD#a#14rhEN^pHQ7nKC>IwUWmcN@U7viTc93Vw*G6(KO1%#u!bN;5XQC4N$DZe zL#wt7*6F%q;A&P1C(<=fTF1tV6htWXM%b)^5N%$M# z^Wjso$}+8IM2|UO9`C2-rQneIoBCMY2w%N2l|G&p{p=0>*C{*M?`Do#J;UJUZuhm` z+|_l*J1PFBqxAQp?gKGc06z!5H~b3t2mLOMZu+*nAGqATWCG!Q{jHK|b{6yCc1F_O ztbL14*2dI2?Pdw;&ew3`$ic@)pRC>24imP^eaY0ZJB+N8j@pOwPxw91?p9HRd+_l4 zbip>L+V%mjSKCe*WV*rn{Ylo`HRA=`zv!HiJyZ^sb03vyvc|im8FAM-YOek)m?kp5 zSD&=KL*YNqVuw)yKNK;j3x5gxdib;9i#Rv680Rx8spJ5QKxwUs*mRp>j#7OrdB?Zu zwj8cYTLuNBqHvx1bMVU?Uw@)ayDOnLg|J5q+QZ)uf5t|{A$;6*h$MYwC99LN7tb^g zK|bWbJqMd}>ew@pq(W>2!;n|`tf_R_g~tCe9QL6Q^ALl(;m5;21Ah;E$G7tZH!DqN ze7*c_^e}3a4y!bm2M1O`?8T|Nmp%WwTB^Kp_g@pM_rq-vjoe);J=RG30QxV3n zya#z8oK%k;0cG3)o)Y0{G?(YgqaPklvQoxXn};rppjIrUDL%!mQ51;XZyl~R#qAd5 zM~8$52XX%$G58YxHu&Q$(FO~?lVOQKa>TU!2-CE>A(+3!>H2VLL1Qvq)mAt?N4#yp zZ}ET8(``EE~+dy3K} zfrt07NrqYXG3X9K9&b4zOx6}G_FrYJ!OJMz7-p+hNOz_$pJM2z65ej5n=|bgyD9n**tPiwQD_FO(^cR{P?aEmMAWmF_(6C*W%4xBId049eQwTf?8o z#5oZB#vE54K2^ki$C14)s90)B13Aa4Pj$YyKoh;KzbgSw@5;#RZ!#o+e^}Bu>w6-)auV7ZcKdl=g zzqJ4DQ2bA`dyk_38^qvk_{ND=oK=7kI2Raa!$jq`D8>`%{g9qpgdJ^_`Kw9Z? zN$oJ-5$gEPC!WJQ0!ZJ;aq{XBq?UyAI@yegn-d*Ag&p$9iVcsU{~P$F@QvZGfqxAC z6<6n2@A0-Ov8xlfyzv95qM0*djAH}ByIq_SOW3-_HcnI%H5BNrI57F0%5J$oa7NhN zXWX~QkH(DhqYyXn8&E>KcPIEM@Dt!S4Gp2yq=BB|i$)wO8_hr7f7hSt`}=2QfdPNi z#R~UjRU!jHrj@CBp-VQax}a)ltCP~2{5Dl5ZZqy9{6NGY1AYwrYWTO{%lB#URloko zW-z~2xh5uqq;1i)_~85EkZH}{#5C#|)~KvK8!MfYVn(qR?woPTFIQZ-%d}0g?UHT6 zz1?_O=88Ys9wP?#!_SAWZjF23-B1@-s~t4Rv~X~!R$98FNYkuGMf7VLxpTPloP>~N z^q2Q1RX5DAsjn_7KAn>!eIWE@eQ-4Srf}JaAK{pM{5XY}ju=dY-!~t}9r!chyR8|h z&41uosIiy+wD!ZOEZ+Dcnj+OZb3(4$^7F$gEL`-33*(-LIld(oLQkZ9P~W9h`=8o> zTLw^wu86@~@R!5q!*_@8PcLxd`;VeJ@2xBvL$Vlt(GUJ%NyLed zd!pTaDtrwa?0eux8D=EgT|1B!QZP??oMqd`n7?wO+lDAIMZ4tmso76gJgq-Ux@C)p z)*n>~u2#+4wbbEhVl#)6fR=&XlIlG182)y|;2QX4@R{)Ce#5qKrke!0C4C}GgF_{= ztU2+yigKsmp|t2tXsl0buphd(bo*!usCVH$fWoFMzi;}tkvoa z%Fv?1ZJy(zy9__0x%zCU_1|sK>P}{GK7nT+5Q9hITf)zU?*e~_rTn`~ABT%m${C#E z;by;Oz6`fk4)1!5)op#W-<(omtyz!F9Qy}}T8%ef2*Wsv1G-eo?teE8jo;k>6;0>- z&GX4Vb-1|y4qpiWB>dlOvHycV;9|U6o_^1LoZ?Imli_mH2fucFP+zn9Ms;4kQ$Um!`cQU)uaMmA3F}C1)dByYh{x`Hm}*RXe@Gkp92sdpo*sH|QupMC zOYBFDYf=7>^-m2(>>~z8!=DBJ5d2{HBeXBvzPja%>i(*^M^c=I7i`GyW72a9C6K1- ztXali<2U7I>`%NkaFpj$wpqU(_Nd6lU~Fh^Sx?x+99$? z6Sf=EX@(Jk=a1n#z)yq!FZ@4x;8`rFOAVBQ)(@@@?mANekQ7Lbi-;Noa&3_VF8tfnN=OI1BwC!dGxguuj(!E1O<0 zDtBg!FZDe7md(F0=Qr&zXXgFfg3$Ci<~M!Ro;(+56-x}A>yP@LIY@0O^m_?*`w6lT zZh(IjF?buk>QmG`!4HBj+H#`c_L*bnIXVHZ2k%J-R;julVx25ZF|tI;i7&fTpyvjF~8ACw|(iqmb({*=Z_JCW$-t_-vU1ezUC>Pb;nqy`>DYUZ8eeg z1k*#aa?ElWucOBJm{=&`o!cJT9?X<~GM?lV6yCu^Vj45{}KFH#E@`2e~cLH zy%znCz>k98RRQ}!Tk0{_fBc*+6f3pqL0vx^SuvSjK|}sxJAIA|t3At0aW#!LN;q$F zzxVBd35Mk{<9ClMXkFvZPdbFHGqj}aBhdE<{0Z+2S9Ee$(u|PEm-Hh{0{}-Qk+b@aD;zlOFG z+oY?{M^T9Rh`|*2!;8@N4gM?my``wnt-PD^d6|ai+G4>tGIA|_PT86e{)P~AVt@b0u?Xyzp$Qbnhjo-jPeLQ~x|If|n0|EYpZF{LZ zom6r&J~62wb8h7B@mnXQpUvAGl9Pv4DJ(y_;D&+XiE}j5o|PXJs{$huUm48qSoW{v z-^1UD7@P~g4!$+~0e_$k;>R`XwunmeBKDV03o0EKXV_~_qT{sRtRuwHncTI{@{PDN z!u!pAU_P+_$wyA^x6LTJ|7rIty%LLO-w=az_-n-IgBHFPe8xG?x^6}Gsg56|`a0GV zb9!B<$qsoi;Uq1TBz;Eq%wl`+{|p>tncG-kRd<0ZDC0;}(EmTXWtGJ(sUIi&1QfjY z8~yLVKLYp*YUh#KXYIboda3!e<@OvmH#?fnbnm`T zPp5TDi(6dL&vTOMUg3|a_EW#kY(Y|pH}FH@-+@oDNBb}ME^)jf@hM;Lw=3}&7R6qN zA$;TPe928h=I=2v2ufeUjQ8&KV!>46_I%v^O5=5V^2yPxJ@B(!UDFKH;_%zYZ{QAm z%5xll;g`UFv+YRg*;p$5k%xR-&fvHkRfTHL?f8O-#Wp=IMa4(cCk;<$MKR2Z3yLEA_P}z?Sft^`+C0+u^gyT>(UJZ%>#mTL_sHJhqCkoO`fQ+Twew6iX6e%=M~mA^nN0? zpBxd7x=+O5F!(3nYdWA0eE3hXl#kOa@o7Lb7JBAD>Kg<6z| z_ILOV7{KrS0(~#R{~LZuiKXqFZCR802Ylfyg_wpId=CGAoZSgL)cOAh@S#kl`xsKITZiu5RojW8qLgF4GiDf~ zW-yYjAxfh*71eebGNq8ge1+{$ORLeA&h2gpX}Tz^PDh0Kzs5}|zyJ5Kna}sw&-45J z&gcC-KHtyxGh+B5@R!3^COe(P3 ztDKcD@Cz=s``{LSG=aTLt_AAy=F|&N>q8mXx8iUn*y>soB(wQDw*Z<@X?|#}Wa3vY<9-|Br z@Q=eEyB768@ZZ|aGcGloZ3488W8>+IteJj*-Wq9Zu-v2-ubcO#fd~f)Yy6qQ+Iysn6JGN_Cq`2^4 z`Ab*l0&m?Vw~}giCcIAMxxdoZeshd?SipL_DP!Y}{jPzzs!n(shL!=|IIW$}73UFq z@DIS(e2MFC_;=xla^e#hqTp3}9Pxp~t&he{dG=2KV)t-`Rj{=i-&i>9L{x-+kgD+& z85I-}6{Ww6)YNZ>`0iwbzwrAXh=Bz7^Wj&+@7xD5s82?vMvN;<(sdxPHYDv{d&p9C+Z9+QvxgaJrE{4?fkJ=U$$43jDRCWKc!!(1& zo=$3&aR*1_@Ry+s_MoHg3;sL!BjKO+pDo;7beFNN#&C@zStQv)!o-oytyR6uzgJi44B&n!>LK!rHzaPHEdfW%Yw`W!g4>~X% zZOtpKZA(sVP`G$RJ)g8{Z`^-{T0_HKbo9Mh26L1$QQ0P*(@7T&;eeN6T4mhsNb3L; zTtNL3{0;Ck;QtPP1N{0n_TDs6j7Q{M%3XB`jc$p&ZwN|&1EYqYc;GtCPw5`eTg-ZGsG82w~XWM-Q%|8zDoB`L)#<7z$y4^ z;pf7C2*0>&e(kNpq72)KCjCO?$-!snn2-h+P<{;&;*zrMH@Q2e^Gh;}45lq?f`&JDgL&nu}6 zjc44I=&P})Z)54|l;Z~!Z(Y*-!uE@t%8D-TIi!#KpNeu zy)0h;;HcMdAXc_x$4{M(pje!#|!rb<=U@^ES_?-?&iXT9@+=)}pnpR4z-$voFMe9{g4C z@54`oFYx*B_ZPt(vG?5@(}omMI0K^2{Pys`vLmT7lFj@g3OKSi(2jp_rcn+@F~+Lm z)T=i^hHKj9-I4L3m(cbfF~Ed>0)7_(uD#$_f5|v9uV<0c$}ne#ms{C|B42&i<0GCa zXT4L->X}efout+G^D@R}mz<%0@h;@8TN=%GyWSD6d71jlq4)4zQ3f}|e*)hSzD_?p z2NO@&|M9LjW%;0pcwXjlw-Y&L9zP4&l`P48&w+W)|JfSmbcn?Xsjzhhw_-Zv8CkX2kt=4MaW%R#{GI$04Z1`#L z55ea=t#b6jCH%Day&q!o$aW=e8Vg1!#gTvfdd9kw~%tFH~$;|x=keeM6)2xDRfo_`_+x-(G!0DpuR z+TO!AT!`MbW0T!CJx$^$O{0|Z3_ZPv#Vp56x!RjwUEfEOGc#xXahP5!3>1>L!jzw` zPE)qJ{uDND>kmF_;IBs+oD5&%HJ-b`pV1$6p|=ayYYa&(ws~+dH{5$#c(zP~1Suj2V9%HR_Cv*7QAzZrgI z?(}X!x1Mg<=T5BQ=YJVF?nD36o)ev)PB&t|_ISvVIh0myo%4DIf6~y!!S|o^jyBCI zar?Ia?Wv80Fyb1Xf1(Vohrbs7W%w!ZUqs8-rk~fJl*P$CBYu%)Yg1||rz@y__rv*X zgPyZvsz=GJ%RI{*l}8JsqqIVoowE$JRD7HI?$kBc(e@1fVfZBcGWeD7S=iswNuJ!t z<5z#xeX7Be%xTj_3aGoq!b~Mwy=xaz;KS}uY zoW?1}H_-nwV&DS&xA4b!1Q9s2Qan6*L$PZKBl^BgSvr&9{zQ*Xy^U-nQat z{$5-kkyqU4FFFA|!+Qpk=A(Prif=dO`M-Sjy@|R%l)=~VN4!DY!FPo3J6hH~Vy4G# zazt)eNg7{zGS(D0&l^Ua>C3tExcyddusi+T7`v(f&vFztDBd zzJza$GN{eOyKnISfxij=4cGjbXYqJkWtn3jUb>$#GC`fBd z63M^ZYr`)2h>NuOuNN*~_qb`JI-ICb9=wO=pYX@PzX*Rm{IOc-2O!XqH~*|4SNzXf zUj8EoRaHpi@a*i9Uz>JgQi1XfEB4{bO&`;G{)iQRwLpc^={}x+A_f@n-@_New}Y?i zz2J$i#`UNJHji}jx5^JhRxtzO6_OCy3iO4QW< z;aAGn6Y7daT`8RW0DX@k23EnR6`>9U{t5Wxo*~Dy-Vq@>`fqxubrG+&wi0d}vN(TX zV*g6fO)I(Z&wV}9WFmErD1tB{CI&@V=y$OGsqsokR=-v?@Lf>`kHhD}{|x_%%5NA( z3x*y!U$k_0fN^YCl*R5)V$Zhak5Tbzb6$O_+i)_9?L$U?y`62QG?*=> zzPt4hzdeUCcoTjMd;?!xgTd!$h;$eai38}~hv3bjn+_BWSUp}8=5>yc%c|oYVyy)` zU3?toMY4ACI0K!FYJ#0RdjH+1*B=DJ9-;jm%3v*gIs8EQowafQO|p4|e2T1T%V{1H z=8WNPzi*mrTsc7VFS3nDY-m8@~fA=qgA3 zCwy%do;?)f*bjds{GzBHvr0zUXKygx@~Qryu4v45x_H!}IEgR8Jz3X77#TD6WE{y7 z@x_e`{4bx=Gg1GE7?=-#AN;rQjo|BClN=>hO_gv(w9sv=ve4AB6*uv|KVC_R#0QIb z!{iZKI-EilfzC-hC5pXa+JoA0g$>hNY<2UJU9wRBi89E7e+K^aO}GYx-_5|(DTg{g zM&4_H@oZOGU;ZlEfRT*-Ru8&(v2$Z3CZQs;3QhxijB4}@MGXVfFBV}n4-TALeGyl@MsCmP-4uy zvEZYDJj^tIlVbq-e8M0n!nhQ-Oyw&%Tc^7QZCMlYKO{_Y(ElQ0;4J*>@K3{k0Y7Yz zX&1>whBzqTPPnUG@*L5H%n>ot5cUG@taGAYO+x%FiD`IIx^8&i=X$9wh0@snT?em$ z>i5BbT-{$iBD!FG7&3cu54#2$RrzQ^DwN?Cen9JkE0JF#Gy$2QGG z9>ZjiE#Wr$oC6Wd)zVqf%_lCKr#H)@XO#w!4GOU|B_@<{FnD*iZWL>shb~rEE;I{uIbJUKWyFNerb!BYaCuPzP#QGC%n}z;G)_vo z7;r!D6lpP-q5rS*-|pw=dmg?6{8ISE@JH&P{hO(kc8_t#^m;y-%9U=f=1aWuSB#%Q zXX)5k=$Q_%3}(y~1yqJQd5q?BNehEM!VDA3Le-`<6|6Sf*=n?;dCcww`u|1@Y=>|5 z4t-y4LI3OU`}@TFY%$irh>~gjni1{5K5*a)%{)pZmHIB`E*K|IiFF=i9q#DiUhWua z#N#GNU8N!aHRt+Os;(rq41mTZ#=S(}Z-{{;_{ZTdfWHd9O%UUlH`JK{_1m z(fbKWjQls;?T1Q6zr%b4RR5;C10yp_-_^|Fy=9n?Ju51(;U9r#{2C zM;UwwzZm{*_&ebz`wZCQFhWx5R-^G(-{E^de^M$uC$NXyM3=-{@-v){Fr_?E6hmYs z*CH5#*nBJW##Gus*0cmG8tUWTHJo(Yem_@V;kPeP2EV|c`X0|7;77v0U~k6g%7{rM zmgl`u(w@f!ky`jijt%f7dg?C-;4+w%9u=eArs`N(9T7~tlIQIxYI^_m8~eHCDZg$t z8rNB>Lkf8yZ1Q}|RN?g8LSXV7Ytl0<*W+X(N~e|DBrh$(wsXmt-;Rz3ZTQrLJs z5KYk^VIbi$#-4WAYqwOVPU_1O;_+Ib_4#N3Y zVowmRj50-2PVX)>tw}?I)imMP@P2Wf!kZTT9}*gGG$<=j22a5E{ebHp_#@$46AaN- z!sLG8fnb8`vza4`K0w$l$_k}h+0f~kVJ^Jn)X5w2T;)f$&a>2Iq>b1{SRei$*rr7@ z;s1g%cnW?M{3Q4c_~8sIj(wKE=J|P^NTeMQqk{*)WD(7c?UjWmjYJvY#2`{FBde{g zm=XFUZ(ET5qg_pz{ttrGadf)c?yTwtq zQETxjtWPf}#&?ex7~+6BmrpqF!9NbaM>?+OFV8kKL~jr8@qB77?J#z`h{Zim`fQIm z!QSDfFFg`9I+(DI+JBfACS}I+JKpF?p|b0bQdl zOK)su`g_&OSgN6u>NcZp7;R2U^N)GnaC~B_7GmYNHme(cvb=s!?f8og>Bf(?Vb?fa zSpeS%WiS=K6MPAL%3$=vkX?C%3|QoajW!HjVQod1%kdLy+8E{1-BcxzFgxJLq6@0! z0bH&CqmL5)M5b*IuT4&SiR2Pod!P)CbHw)!{|bCv_#P?(_caEz0W49u&P5hCCi|+? z=F#Qy&wgFg#}P##RbrAfSw0NwBARL|+7b3KupOg*otoCHb-CR27WY5!XT$GNiav

    FWkG0`aHl*R|PeXBFC? z%zTHoABX{a_^aV-ZAIM|dzfVioJ;zK~uqsh|8`Vm+YmTpC zt!6vvK59SjcIQ-KPQwXk?0fY8i5O7z`?4SYV)z{RN+oT!^A{VpSn~{qZIoDS8=_9} zk18VZ(sf8N^}2+o$@L15tfk_j>#kB(J|?9fH>6z;GukVFW$?{W220@Ig6{|a2z)I! z2{(YQ+D>|!9(0{=hQ~V?P;6f}m8JR2vR%n}m>TMp{B-`jx&{8nKa?^&|3MjC z4L=|LP577L3pz1JD;&5}m1CUHNP*4Qqf(3p7>Yayxp4{+BG@=!bxfkWYn7Dk!eeb@ z42f`~F&O_NttyDM_u!8}8T5t!1%4)ct}gyX?U05r5`*amtS}!Rk5N+(hnUf$$3^oG z5w{L$_j==3?&v(P+XB_DXgHu5HtiPGdI(j2z8!Unx>*f>j+Nv72mTTG%gWIP?sxS6 z4BuNRJi7U|a)_DaUB)E3$NW*BGNrfg?AtqAIa3m6S2{GziExWK`!v+P>oHq;3El17 zPo3JHe_JxG)~)3Xj|#m1h8Xw@{%-hl;opT{{V#)E7Q1p}$%epgaarbrT&^;7UqzJ{ zRwuo1e66Edw*9$vQMI;hjJ+f&@#BHoOF>$(<}LI6cDhA~G#vlte#ZR|V&FOa8}QxX zcOQbj0B*V6zVW$$kxFN9h=?tbsXqlx>OzUc@qT)d-*1L~o#Y?)X_j@%Iowa52xHj% z{n7gU>u;M)Q(GT+8YcIs#IYYSKy^a9=L+=u0Dlhr+=avQ6~PgjzVoL04V}!{^OP>% zzViS}w%~z9(dvIz=E5J3GB^kRO!x};eE90) zwhyO9%qw$`sX8cDF1GL7Pv^IQKj-xg41A&%)mIXlvOH$#uFM&)&3)*>!=+}6wCr-e z_5M$5tZuCJ`8Tc#ZI9vG!(RoTvK{q+@IPvsZx7KQACrDO(=aE)YNO;-WRbtKHTU_z zShmsI&O}MCqw-$t0*8U0%~O~;h4ZJMv*LXN``)CwrW)Q~@a_|0AQ*le{CV(Sz)wI0 z-0acp>!Q4~R!@l?F~3ATGq4Ct<;$eb{-LbCrgxgo2Vy_PBjuQiS86z?8hPw;>=5uUPsSuNa)Yl z8t9-$ow1rBeC?M{T2#A@G#VYl@7saj|57x=4XFV&X#b8F_ym9KXFP+0KL&nWo`&^j zGJYQJIxwg@U=kN`^q!8U;7%{S{<4RLMxxglnq3#ZqEMoWOt-7GI=i)&DqD{>kG+Kd z3(DX?XWW0l?-79dKltO$JgRGSUsuUkdx0cKagJW>D(k34Cs|h=UAeyR0^MfohlTvA zcJm%LBxqde#YcaRtR4w}dLK*agzYV@Ee5T5u-mTMVeU|IW)u;5+hjZ;- z8r!Mab18*W!fIIh=BKRolTnomIS#uHN2HFUpIr0c=wbVfE%I%fY&hDqoh(!OD>W#0 z;qQT;3_lgV0RC=&ozaI8n#l zofUhNDx3Qub9DT#7F=95HYi{s;J#@DIUvI%c|+5b?PQ=QiY*>!y}6 zGsU`@KMgu!yqu*?XC2+VZA{3Gll_e6tTEj|yk4orHX}Sa^?r-PT)RhotP9ozFYF6- z)Tk6!#K6E6YLwBH=>KB}${zg3^uJ<5CG^`G;vj}ocvoV9>B^WDHdii)S2??cOmI5Z zSHjj!Jjh}l<7=RUCQ+8IhpEpux4+dyVT+Zk-#ahi|BNy?8~#@KcJQymkL9N@!uRvY z7~36E4ufS&c!`eer7^=ZttH2D=@nleYx9J*t*8!;oKdGzl<@80KZY-Y{~CV5-K^Wn ztXM)U3k-9#omQyJ4R+YbVfisk%ihWM>dKQxo34tFabcAlE>iPiJ{N5uc4c;uY*iM2 z??k2CMGUyW*RDd{FZ}t#a39=>NZ^H~E=>qxOG&k`zydz+g}0brm0C>7#p}2p;}{p> zqxk=bNOVZmICRKwQv$6!Qz^#~1FC+rN+zVLA@rTHG zGo~-$P#rElq%3K=<7_T#&8cs%kg(SJ1qqTR#B*YCzCZ! zL_{_OWo?b}J^a}yg9`X>;M>8!17AGJQp%XXVHIy%S2QoYJkQP|#_|J?%iFQ?hA|-( zKQVjMKa_B>&bTG!k;9Do(g^?Cx{bj9@|i-VQaYmys;$KHmoK;nhu>>B>OlCjQwpP&79bYeen`A3ZP4rVeaVEGmil?yzAs{4WN=4HRtWud) zG@l>0ozG*o$hJ)qMZRUJM;TO&A`>O6E0q$37_fwY1^#FFbod-5kulI?gm_cg@!Syg zS?>6O6=M5%UvJJ~W3?$!56T{0xLRqw0c(@MX9Q0otHcCR_x?>QSOwG#&0F85_$x_Tj-apR}jE zyj3(GxroKsC=$pHYP5L%h!AMGy{$(YSE}ywBm7w?gWm8R;4g=N3%=0B>R7^Mzk^<8 zbJ#@qAhR$gomN0_Rx(nj?mEqy7KaXCNq#0dNL3XS9ILuWh-mu&u$6-mS=$M!@qaX_ z6it-D5cn71AA6ZFS7SkH+czW>*FDg;}1jF2I5s5_OC4PVvoon{T%zQON20&PGSJ(^6rKI64N zhx2>q(SG?kUS>^zCC;!_}p;5mXWdB&GF3LYgyLu(wuj) zB6oS>IQPg)Iu53(9NHLmO_~eIYkH+hUL3r?N?&Q(^FuLDa9MAIbC=AvStAZjt$_anb7Nh<4 zPpu9Gpj+-7ejk*5#K1oI``~Yb|4ij$sKjFiZ@XzRfx?AWVd29spU)p>a41tr+}Riu zmiqj-b42Xn{daB~{v{=Iqq1Wcc&WCk`AFBajo(eo=u4$+K@5b${{;UQ{4)6K?AhbZ zV|;Yu970afHFmo!k76@YpF1&=&EKrATr%a+A3?cRkBj{(vi_y$gb;~g37O>+z6&)R z5nFD%YWZ&csFbBBgMYy{QlkCsZXAP0s=j|!*Fw}Q=Ao0_&WhAEBFVGli5WNJ+=Dkx z3y|NiFby?Nj_i3TXj!q+A*wsYJIjMO@dF>T8w)`5lG*ToLK%Dt|9ANF;9IDC-y5mV zEpHe^#l`SfY3^~p6!<3ez>_})QQ`(g;GM%beR9``Z7d|&u$;3ucD<2)uO9UEvQJy;ZXsORqkDMphz9sWHcX6yB$7uFnI zx8=V2aVEV>2vO-Tj=LpIu#93D|uLCcWYSTHP-vQ$3oi0Zhus<9j5-Pe|h-}2Gdle{?~$-(wA+r?$GE0 z8kG`=82AHzUy3?q$R5N$e5aY82d5hhbkoe360Eh6cDn!eV#Dl+aW=|?A!2Etdj)i} zS&K}GV;AyM#>7;&kPe=-hnR8Qu*%Z5|L@q{>L2MGy&3E0DvASBim#)S9B2l-^CKgLia^{}f|LhTi z_I~z7ZJH?H4#BH?79@(c5@<*}sMamkcrHGp4I93y-^UdAr{T|nufE@<+b~PjQK;2W z*DNZ3&n>RZY1IX0&d_a{2WZ1nIHlQ)uE8C6|E^JOUej#@sg%oz0Ve#uYU-4y@Y(PK z1=eMesfTZ8{~CTMT5CjvuQbM5^mOOgX;(2`q zb$!<7n}rss76-@1q?Hbpau6}F0semYU*NBWA3^f%DE_DTb=5B-fNclmh1OG2Z?=Fs zo*X)eN?DE=I1K+PeDl3{2OhpsD~1^8K7OT|giMZ)CfB_z^Rx7rjYhV0XBu3DTNPeU z6En;hS93xH_FAGm^as=-wM~S4fIkIgFdF_H_@Cj&z!#{#c1MD#y6_jtb6C=#>J+Qs ze?xnnPh3Hol|7e~o-%jy!fA??T^YYSxi~iA?ZXcFtq)CK(g)-I8~z3Ozp1NJ#{Pl# zaN$>Z4-#c)Tq&72Xh0mdzNcZnzSZzG(-~8ArrXZ3*S4zAj(eCi+BdoOp8ZME*>XZ) zN9&(j6hfKu5B!4DZN$J`_+jwv;r|C;RpX}L@Q;i_EtsnHi9X+fEuz|``dj&J-MZB( zk&JWQaRyZp$CV1D((!bMw!h6n_PSKc5yZe3_;UCW@cZbg+JC4X5=uy;15VL)nQHj6PzEjGkLjdNSpuH}|GsdMSuSVvuQ72WTpzC7sO9$OHrqZ| zUO3J&`O;^A)k!rgd()WTU0mlKVCtBSnYK^MV(8KTvHeGVLA*JXO6i6&D1`3{e<%EH z@GYlARlejAvw8bpFOCf5YIRPH+jlUy#6ME%9&O6a46;mdJt?)mZ||P3HtezZ5i4ZD zz~QQGtIxIZ=+bs;Ta61;Gcwl9)7gy``5}Gk~3QD-ABBGBxJ)Y#mxHEJcfSo22V-DkT;%Pze7W z{3`et;d6%t{e`xlzGP9|&kc}x*iQ~RL`LbmlH{*PlYg@8j&kqz2i0nL%)c78D>b5u z2oiDd-9h+`xid%L-WM^@(+%&Rc2=j%-H(2F;QyK88Rn$%TZKh}(lX!eK|;_x^XKV@ z&M-woq~ZQafit+G7^y@%_TJP_M~IN&Cg2-yCO?7yC*T8S1HpGj#@o(Frg8}-Q*U=#+)U$i<+6&)?{|)iKB3(EURmAy zeOdEk(XY|=r{uyPfHLR+KN|jP_}Zh<7VGJgn`?RuUasCl{knwnY~u2Lwa2`iWC;u_ z?qKO!dVp8|Wm^+3zCE{ZZ}e8`snVYJ`u@4Cg`#MY{%$gU6qWJ{{toyh@HG$M{uBP{ zd-Sp6G#{IFTT?b(ec7>6Wnd!br#`QK8)z`^A5Djm!jEG#))wsQUdA+cHVl{%evxVR ztfBpZ5Cx;-!zMh~J&PES!5^-nPMHJ$cleXuq;-FkKT&ryJIDX&vaBtJIfJW;qT{Bn z_^|qkLbhw9^0&*MKK1|Dd&*r^)3-~a1y9;2pW)lW_k@26 zev6^i$S~ZOq@%67QBT8B@T4qj}ZdoDuQTyLEXI|Bcyi@9qp;D|712g%! z_J@BMekuH)I}I>7DpPJ)e`tSc|5Pg?#cb2|hoi4W zCL%IPvg~j^6B#ybmn!#;48`z=p$y)DzYqRN_&vrT{@-eIIkWfs&2{!i9 z>GqX$PhHuV>uYbu^67-t4ZHwadwlF)+b_Ex`*a)KptR=+>t=lW=yYK$>OSCqhMx{! z0pAS1(kbo)sV|wdPqlGz%GJl;JHWe+hh(j9G{;cFg59W4CgLDnj{X~3DT?ov=SLG{Z^7#UkPL4Pc! zL?Ee8Hv4rc)gua1DWvufnN!K@>sORb~1U}#U+pK_+bCx{6MnEZQ@RSvZ$^M z^7Sc4$6aU6EY1k8_z%6$PnsZ5$9{5-Ax&4vIpFP?iXBsU?1|RF-_&oUprkb{|Q_ zH}=1?(+G6Q9B9Q-BlHALux3jT@oPU$`AA13{$)=5(ONATL-e#MIU zrBy?V95gpXB#?hruJLL<|90&*B7ePmsV(mCCPoL-Zm-!4)& zL-@_ve@?~qCwwpXd*CO*A36^2KTx`>GB>K0QOj4vYSik-54!d~{sSe>A@)KKy{P5W zmASODBHcyZliBRsXXa=B+4J4dZvqV$Te5G@RBrtl*Pn=iO!)EepTM6FzgnrVb6=cx z*EjD)K|)hY&-(3E{kx~fxb z;b+5NH_4PjF_Q#T<^DT=)~1XB(c674{$wMq+?|Vzo5Q!Yq8j_&y!xeu^&j<%rWsHv zFW{en9}NE}{2JB%uN&%`bkztyo%BLG4awBE8-+F5{mLfCONV<_7fy~>uJ_ZAZ9G1Z zU-y65xGqg%qul(tXBw5Fih;ZE|Ae0mf3rUJzgQMF@f?Hfw>LE&Uq#)(SDobfoH9lA zQsF2mUt;!7P^PS~y0&eO`>>b)RD?F?`gKb2^`yEfoat1GKVsk|{9Ew9z|Vpok^VS( zGf{KmZNBGgN&i6>(xReZzp>q>kyJ;Q6DBJI$5$t5mM$W%Rh1n%&o{e4_Q`qLboOtD zYMk6E6ej#er7S}XRKhQV&k02x{CK?oyiHa8f&ZEY-xz@?E@2X~vSAO|@Z@Q6rnx{u2@V|W4z#oD#IBYfU|GTMEqTw6BuPW<*ZpZ5nxi0g|9Q-y7 zXX(WoU1AkWt_+c_lU3<0Pth+Yf-N^iEUn#C5z08+JvjYs)rIf6EzSWgm%BZKN_h)^ z9{i>7yB@}U0Q}z_m3{KL&Sygnp0i|x&`{&EQ=3r%xp zj8R<$N$DTFvawp-#z}dLR*Zinnk7TMGOSNzXpFR z{EP6n{w)yLjW;5+oYZytI}&GydIe8E$0LkI%xjvr2&>&xZTb$wyR(({S_`@MmfPo- zNj@~6TEB6$X+f%zipKFdv#AtS3`pUR(p0DX3I8R0BAHFR5KUTQD4)6I!lzHE74q}R ztOt(WPY&*aP1hWlRbi~jV&s*rEL^1%MA*B3=v{KWG0z`<<~1+Ta}JfFih;-QH^RRQ zzwZRJ0dNgYe5_Z!&?>-T?}ge;Pq|FOM=wOrjuqCoaw$p1r;;;S1~vrOvCwJ6GRAK+ zd_P|nHRsworKlT~wVv28_5^+v{7U#T__grO;Ya=Q*jB#pTI^}Z4TKp(l0PPnM_)iF zj<2^r@Yaf;ji%?*J@d9^x@2tLdgJQ;G1=!<9Gkq8CR|ZP>>%TOP0^dm&4t zB*Ie(-A691uK(K5Uu}D1VevIY-8W)jI(!HCeE5;@Q@^YbWk~d@OZ%6_o0KUmyZsrB z_usrj&K8N5Y5ccwjf-(w@C8CJ^www}{#bO}`FmBT-Tb5+7)vIUIQS^e z%A8BDHEvSN?0=ZnHO96h2E5^afqx5rr-^8P^huhpO*y}mvOW3dzb#Ix*W9|8KUULQ zRVy!-vjv=ipOy1Iml+BjCk7AB%Ca%W?YFX%1&E+~VC;ZN?N zPU$ShZ~wtxp8r9rGyY#n;3$8iVU*>osqdfI5+8)D_gnw%`DRqD`Y>FRSuQ#`e{I5) z{(tD7+5X7TD5DivH=_7@Qky9k=Ar!&{A=(9@W;X51YbGVQA*bAA83?rtmITHmWjBI zKH38*KizZdb@s!8@bF8oIA1t|U4A(yqzOwc*3Ze$I7n@i_4h{`wtx40Jo`Wl3|)hJ ze)yK~qu@Ji6FZWcMBmbq_&c6CNB?Bj5M?`mVKe3Pi45T_V!d!UX{GMJztbK`Uw@*T z!G~k_nerB3;}NiVw<|E|8|9L1LZz%n3@m~F9KJXFC-6nfl)WDvr5~a8IJIqGz^deF zmmGzaR-D@SrMnN#B>#KoZU1@yQekaqAAcJAM9+7Ji45V@;_PBgB9Y{0Tkr z`~iOVNjL}dw?41_Yy8;6H093o=f?g%@8H#4Vo8+t@-f!8iayTtW*S}_`?~?}rbPEa z3?oA`UR_z;(d&=Kb*tM)mGJwZ3?{%|0sjvCdGHHNx3Zm-JliSs{qne6g>wA5L{om; zOp^YS`uN$MD-A!^KD||`mO4i*qE{c0Ie8{Y{$fsJ#y|R0s1|65)*B1Z_78q8{6FCL zJA!fuUu&}xa&7<$?%b#KM6r^~IsFcl! zfnVXjgTEbqA$$c^RoHMbuMjrmEmSBggsK)pUtS0MXDHpKd=|B|KLxZjCC+n8qVr8=W`Zbuy}DJD^H&JsqV;yn=B5~J58Cj z-?~IOCb-KVVs~bixA2wHd)Z`QiaPKcan|07sGCzM15pOIz@G~LBz!r1Z_yAYW5na( zpMNqHMqF8>O?aNE+BJ8p$Fg6mcLwYx9K2Oe!c7TNyPKxP%%v%tSnIM|#(x7RY>#c4 z{s8_P_`&eG@UOt1KLziB`Z5j?r=-G+wOr%*d>&p#G8vS)8$Se`6CrgEl9K#n#kNct z-T7|J^kgqnlK>5=eri*usze9(fn+h--XI44f`1WyA^f%Q=_z7*aN4K+wc}-4N z2Cl>XFZ?9<`S6GOIO0QA22aamrQaz3KVFG*%cztL!~hq5*FNf$h43d# zMf;x&YL=(QA!pwUvVZ{7)GQxS$>C`dwc%ogj>mWnJIBSiEjre4V~(HduKS{XtbM&i zpe2hD*XcVNOeYbwP6F>nt4-|(j#L)+h`?XS!G9O`0yRjD9` zz{)M==4(9x&s+Rb#C`4&x#5*MrgzE^Ey&uWXyDq3^>4>PC43E(!AtNTzz>CA4xi&w z9xn(TK|e)QA6T73uekj-`r;>{-BG`(N2mA{|64L=lja)jF$?Dp%-nKJA#}9<6u8r> z1DpHRA~$Ss{R#gO{7!w;oV-|MT)zdhkgZHwt*I<7wv1E1lW!2bol75so0 z?(7dH7p3x_S=%l@XN$rMLa+muC0x8L9Ijh#m%8Mpt}QW6#>6w~p^hN?PRl zon)JD$CaSsx8LymYdz{6;M>6$!e?Jl8_DoE5*B*iXbUlI6uP?`BN^wGS`%YIOV^%K zB2cwMs%s3Ux+4)W@1sT1SI58atVPqT=?olu5Cikz--CYuej0q$Q+H;Qfy`-`P(KLJ z5rRmSl*bAPd8G^gnCSzzHJwZS?keu#=0=6l)fl~Ecj;q)G24-=fEde`_I{D zlUq$3;!^#}lyhSZAe!aJ(R-tm9XXdo^)^;h zwUDhFrbKiZ@@(g+rc7HUWUa>9j>OqgDW?zvKJaJsSEu|3|L0%u43Lc5H2K%C8%6F9 z&YYOG_G8VXLiz^nE#p0O-fBolf08$P5`MGrymr60TgM8;nv?l?Z&tL;yCdU1EGlIy zV&Dq=b@2N{pzOit7w1u)O>nCGa|Jie-6VDgBiTvh$%x%?ZlQMo(|yaa#V*e7Iz11E z5Rxxkh9gsMdiGOu`D;_gzqcOdY%0YHG4LLK6nrN9o$&G2G0HU|Wt*abrSS?fYdJSS zN$=)3_gvw@L7Ch0Z#i;G`z|aR9=cFqRU+?AdxY1bzUMU0YZ?7Y#|9kt z;O~Wh3jR=z#kjRcYg|f_#%3skd_#g6ul2@`)(lTJT}U`)5&>5EvkyYBc)$zlrNv2u=G@BABYGy zVCoF$dh}Y^(3P(lg2y&;dPyEZ^fl#dI36kF$A7E;J7H_>>#+;=R7yHxU_a9H$&7o5EBL>{zcc!URxXVey{aJ0xI5qw-p4DGk~3YB z6BG4uGAzPBk}S7d^oYzqF559_O)~Ar+Sg0iJD~k1VqiCX7W~QZJ>W-$JL|fbZjxW2 zi8J332YE4taXdZQUA=xqcFdY1lMZqxOyBH6SU5WguzDEem4+Q{chf35COV@1Ct~0P z{9yS0@WbFwOY=`-tnsZm>vx7C&%^Cjur!FYN;w^O2=71DmM>EX<&|?3&*$8`@yE<} zI?+nml`WgU-a1Tad;AmDFZHfr;cECw_m8Ck z#STfm)r~wl6E)r?7QF}9$3}IvUF$f6W_RN<`)=70-mNyr{|2DNhpa`qF?n-2+J7Pj z6!6Du;rSzcO#@sDD2^8r2Jfs3TrvlJl2=Xk&D;9ZCGQYZypDFm$S2G}ckk`PR@d=D zpyjRXzA~mai$Cr|W1j7O%395+9}9EB^LNC6x&Zx8!dH(%*@It!PCg&yb4&xXrV~WA ziQxY8_l`~+27#ANg4qPqhvQZG)C+CX7j#hZ)WKHB^vkT5Qrh-TU;yw8dRe%x9=(PY05H0}P(W1#p@ zo7ZadIyO@A+X_7UMhqChpQWu%SqeW2zO8r7uX-QPFo`*j?Hm^DltvZjOz*Z&eT(NH zQFg+mEFD6fkz{;-NxHXW(s4?k*%ZpKjtieCTCESw5(PH&1k`wZum65qdy3Yh7|Vj64gUcA ztMH@XcbSIYqW3(XR-uKifE`vIUu(kpGi%%~FK*E3^NHstMrVk^*godc^>jVPk>NUX zy$;albY1Cd-0nO6U!g4~#BiyUIK;qcFVwlf{}X;+_;D%DTMB9B z8T?-cs#6N!{|4V;V~JMS!Rw;}wdo;g0oS&=Zf)#(YYIiwZDpllSIW^WQJ+x-WkR%2 z-(iy>A(GoDHpk*{s}R#0lomf&Iz=AgwOW!b=Yj!iKXZ3cKFb_!i;J| zih>qpOJlA(^w+*2<4$X@rW0Ha!%EdFUshck(f{A|ueK|dqKz0xho1s}HvHZ2RcD>n zgQ&$Q&5aPy2<8b>f|)+qsNyjv;J(Z>ukEF$tZ|1Z8WUfCzJdQ5ejfbcI_eZ>_Zje@94Jj&swbeB3tp&XeN<$ZlSpB5ly}*lOqs(oqN-p)@{!MO^c?u zQ7PvU1OLIl3f~?6W%w27=~}=Nltr7?5OR|cE$a*XjL3Ix=c>!@4 z#-hZx2Y26o4%4)KOxEtK39AtMh=Jko^#-H<0schzRtEF}fjrY*>K+)%2`AP{ycq$C zzwiGdTEB_*(;a&!9xuW^TjcV{PRCVe2hq*Y%%}bSm)e%g7Ay0v8h#o4dGI&D?;4Hk zQ23YJn5JGLA6oe6SB!&>+^}gW0WJ(y@qG_Q1w$$2`juT9?(3zImz9_0Wn5e%T3b@N zrEO1aiWW}0$=e>d_dpCRho1@mXZX9|JL_^k#te_c-|(w`&eTtm zh;{VCmzd=oi-<{N#Ad2Q8g$hlaAyiUi{&?A@J=%aTOi#3;6$re923;Bu$Py7iW+ z9+I>iT8}l(c?$ml{B-!Q;dho`-@~6vygofrE|({8nMK`42rdv>t1U$3hiq6OF@%*1 z!;K)ukzzvXT)OY@^uvGjSc25{Vdi4BvQ&I%PV1fB1(hJxaf@ zLd(qk-W;(EQ=dXC^-v4+Vq5JGjSKIq!?lgP6e3O$r@Bd_QYB~q@&9c#fl_xFFPV;!@UU>&#G{C4S<6h$Gn{_0L?|0IhfTS7XBjun`0H z@J9^A{RjL4_{q$8S3A#&>KyL45Kf_5_)_l}U)ngCJd|MiSx91g(7j&}$1^uEk0mdD z5knk{B-}VHpMQMiG)-u=W0cAd@Snl=hwll$cZ?dP-weF}do|P}#MN<5G{eU+KiT&S zYuUjWB?U~b0Wap^mf>E$qwVJ8iybOfR-983*-AS$!7D9lGTJ6KwVlvBe%TA}zas_? z!oLCE6uuGs#1vnTvXCs|F)L?d)bJY4swy%#j2KX!`&QKzD+L|@f3@-xo z9VbFEjbgopy)cm-%Jd*5B+H#Ps%`&ktuHj&@mFlbwJ&0z0KPH&X!yzSFK9b*MUuU- z;f@#NLrr59oU*zMge|kFP}S`S%W!wD482w(>|p&<%N&$S10S?~KnzfPu+QONho1vK z{}Gc$n3NIMBl+@K`3lCVlE>_#n6NE!nE`_p`Iiw#Z2b+QfTX;};SAXVkU7 zsHhKu)`(KI+TY$CR9`CP9egT$1^g`dD`%n(NEQ8hd)3q~x!aMm4}Y{|@{1$a@ZB!` zZ4#tt!Xo#+xR*fc{=V(b;XLxa`^?a=5W_-TlNvG9Kxu1@I|i{~)#iAQyH z%%-CKU7p8;+ZBZA`43wza!F%G`mjY8LS85xmla5B|IT6kTfB_zF;PA$o0s1qu+2g- zo6!CaF|ZN-diX!XKLOt%&sKEak;>c=CSuQ#o$nu7Rp}6ZzErO76BCkl@k>#nng=@n zrTM!s^F!ZsV#YWu_s(gPb%#d1HlzI=V&EYBf8o2pzXgB#07p4d&T^)0?-5o|A*8)= z_g(v(7s}1_vdR9!oJJ7I4i-+F$R%ak54ZgK?{}{7>c0E7tI~WBTHuHGKM(^X{DC9T z{tCX@EVTcr@m5kr16j+ey^n=*M5d)2VWwww^0}c#hu`jG);tyXh^mM=NBVinF8Cdi zcjQXD?K;$t)3)H+AASaWKK#Goo2q=Jrx}s;+VuEmi{KRBFTsQI-8^ zmtQ&S*5Vpbj7#Ag;SGaOUIpP*bR?!hXjRa^w`Ww#=fnROF_;ZM5q>WGWAMek#BG^L zRQ_hOy*^<=xtmEbxQsUeyvU z2BGqt5cN-pfw%BK!PkkybufIr_d=~DM%ru|NA6}NHY36r{|dR>a8?(>EBrc#Sh?V& zmZz`&LL3$`pcYtlY;2Kni=|KU%Vjrgm(0nX1R!ssGT zB6U&Q3^oasj@)Ip<&n&**-itrhUuXWSJ8H%_QqR$L#(ZM{}?f#3;zs!CVVsabwfjy zgJpPbOgLkXGnaMPBiVAkJXSJbIVaf7i{+9|%QqQyXOP5($;mG4X#H!ewHmt({VyQ~ zet};L-vfRW{8_o)*6Djq)P0Djc*=FqPOJ1qjqkF@bfVX=6K){`KF~Wa_27LF+#gMp zaX135D5qDO{V!|9v^(+zeh&Q2@E452^Edcus{P+ENHYC$t{5{23vZhA25V5*Qe1fw zG(w)49=j}@Bm%a&x)QS$pQkW4k89EYNJ~!Ga-?ng-L2md`-p)^_$T0>gI@su;GBr+ zKVE0s9}1Jv7yY`)23J+Gq;~-o%As5Q$|e}fo@e9Q9fy&-%1N6=7c(wAb@|*j?-t{V z7U|Z>Bir%p3o(!eUt3R|k^^6T4*I~oewk}1D*J2tW2Mr*A&3nd|JNE-lr>Bg)=jKX zR`hO|(6~^?KKTKte?kmAhHnVJ2L3Ae6}Jr{$p7Q)PT-;V|382aLia6QN_Xkd@zs5o zipo8^cC~aZS)pr*Vs)tKE=$OfT)RRSqFCKG9hQ)`OQBrVl4I@vwUslf-+v$9ul>wt zrq6R`cHVP*<};tEl}_3d=T`UroVk-s z$lbW7?rX`{I;)(e$_%M=jvBGXki4tyH27(y3z^ue&-pF4ap#Xw9rvUD34V_qxc-7a z9=-{DEv9`ye4ioaQ>Un!dsPf}??}zc4m7FEBYFJ~b3g5(4jwc=dB@39!pbdcIN5aG z$SH*(&JEJ_^_U6d7MuJ*Ry%(kd!H%O`>KE)fRgbrYfN|9KnW9l*6WV!!~t+DNoNfu99mYW7By z?5<;G*;8ebv89ly6-(7)MaO-*-Q$Zy5_2_@nvgm-HK#a%jeJ9?0zdf7536 z%B>&C*f5cgRGRQ^VjL%eSovb-o3)F$q*Rr;H^zABCR znF9`@{t12r{GOxaiAwlx@T-#t7P1*au|L~nj7^srPmd<>U!4>`SL?Q3hiUHe`H9_z zERG;M$iybn+}=?;K`3@w@~0h8L<+&)&{W`Cv*Mh*u-(Pvz-0seW7_%6m7bNZ1?tOW-~KW zy#2O!3N&;P@eJAjT`;=SruT;thYl+dYY_wTJF(w~ZwcQBzS>kx%>;=wXjX<<4_ z)Zza(TAuKSzYBgC^MI3^>fD7od1JZiThgisTyf1SBy3S zOGwiC#D{zerH%8S`h{=C)@Mq`9Yx=thymGq*LJ{v06z}Ctd4OBdFL7TQUT?fnW33+ zfOe9%RhTy|lk0UibNnxQy}PgEmDQtr1JzZhyGiE`5y7>|VjrUMDOMDrpca`fs^7 z@})$=Xruj;pskttng8&Z5)p(L*bINx81(-Wh3#(v?gd=SG~IkTmZ^5m!?KVi@Lfe5 zc&CexemNHB4>Ko!CCsM zdO*QYC$U`05gOTHRLAh4k@6uOBX@W7)Yz@jf9O!{pUt0J8Vya|Ti8DbXPiXa6U0CP zd@=l7_~>Gl;GId0WNH}a7H-~okINv+Y<#swpxF<<v>bB=g*e{hy_xRZ{7 zX=#M^(H$qwc%I;EcwOLoMjr8F==3S|=BIG#4oa!iUqv3@fe-pKrEm z+$(ZrrN?=P9d&n4FZLOyNXa5lch42-|q7PB{Z1@Tr-_D&miwa~P|siH5ld*5@8QSQEpYZusMW3}0tF$7Qk&`$9R?Z8E; zf@7z7+~)0{ek@)qJKW}TA^i+L9x*r(z8icJehvKb92FD`YLh^^cQRjHxaOo;lx5v)2l@`99{hj0|NmpQn#{vBUz~p;25jM9g1-yC z<|14JX1>wMP1km_82nMXPVoFFzj$LDXZ4Z2O4gEBASi?UmGfAc%TByL2m)6#DiH`P3kcQ7pPWEFE`&39{!;*Iy|l`jN; z^xN1J#-GOdC;V#ortpWyp#Ky2MZtO-*SyTQ$NY{ktKht-jM3Qgol zCT2}2kGC`JiyISMlDP>p)mZAkr)CA?{1Y+o5&j|gTJR&`%WiSYZg?=r?@q?D?%x?~ z2tri{$31Z`opu;nw;QREp`*eUGAuAn`t82f*^TEv*tgaR>gVCl$KcLql!&MB72FX2 z@Xg>qgwH1_hdcX84tUeaFfYe2i&1PMex>^zbEn%UdoZWsj0UO&5vKQe-mqJNIBMh zg36;_!=HSU7IjT9p1Ly8vFeWdi$nRFhfeN9RC(*r!Wx&qEw`2Ym=Gmm6Jp>$`1jz) z!0)4t{r}rx>XEOKin^YP9#-@2ge&8&%I=u)VrM>!AAYrH%f4`V)2SDEl=ZwH{BZ8_91TsqJ?Yd$`piK03jdhyVn4rqdv=o#{Hwl`NtOXi3|zK9&ZBJa z{I!qiZ-uwWnAc)hHmDwkdSm!}_^aWchVKbqnp{CXw^$tR!JOru$yiyEn`PE-jGE_Y zg_TOnDDOWV%pPwWCjWFRd6V>|Q?{}e-w70cX{GqTWZ?-h_|b^L$MA#T=fO{apLlIB z&vJ<382#^y`W$!ex+g0rg@BU%iYHnC`QQ&8f4Fl@2 z=6m@1++W{<=EEuBsQX0>l*9iFzv~6u`-3mo$gIgt5(K!?*FAfH_Yd8uf5_@b7gYT4 z$ok&NX0mwb0i#GGB(lx^-+qd+{Xh#GIfo;Zh~Vgh zFQu&4S?fRXdOq#5e8_c&{d{e&sLP(dcmNVFWMYlpr#`%Qq$tde+_<`ctMSwM-~O(O z#Q7&;U>N+d@Wt@Q!ynmiTmH4+fFbu)Xe0eB+jTdOnL1yEzo~G^+Kt;|hUr%CSAGg%~PHrUp{I3CV@;p@RSgKu;Z*CFtE{1>iFJbECzvEqWa zdtR`hi>DsbsMFZ^R1g-!4=Iv$Lf4VU*NtB5Js z!j}BF#l6BjVNYlo zK96dBSo+>8CHup*`R6ws`hT_mniGv@&)|QD{|G)CzUopO|KqHq`kRvc!K^-KYa$gM z^|^bN=6!4Z0j0hCS+u8T7iX3AHZ8iGI%)}v7Z61$cw?nnKH_KnLz9JTD~Xj92!Gpg7{^~KYW=`YPJ~@Of=S?=*HA&C!c5gn1$y>XVee-C9%glL2 zYUg&5DmRts{im4qD>pWiJO8*XPL|)+@A4A9H)6m5{!;iw@a^HdP|^;3*At%2UsaW9 zpoqJH^MBqFlqKEN2{ckc^KW98&dqrW!Kc~gRxb;U6`T8lw#a6aor}fupNIh$`1|1x zx{Uk3@MRyjWeV+6m2bLH9BqYz@*TYuR_S#4+V?*fc5Th1>I3~hGmg_XGwgQTUR_At zY-?2M-K^k$9N2jtZSN5SW$-V+*Mgq}U+k}L7Ll>FPn{KI>O3dX2e)fVVOEr9&`~NmH=%NxKginV* zaSHlBfIoEE&-MSKol)@liTUmOKAjL5xlf4}Rv0n;bVvCuG(B=ts9)r&FBUHD?`e)E zv2s4`O#b^f@yAqx`f1DHham=^z^B6xgg+g=HhqY{R=-J%?4v5n?f6&xMwt3(k=L$- z7!JA4(BGI6plGS5%MuQ$dBA2~7~ii@WsL7iOWCzmi&b79X7ya-_pdR6OKAI!7#O-2 z`ycpe@QvUXEFDea`NC8qxegO2{`W+or<{E1{OT;;Vok5G=PZ8>D^9kx|FgkX!A|$| z$*ba=gle;gjfMYv>d0j!Vi96sDg2l4JI0|M4178_vg@wU6UAi#WS@Q%>J7Vy8R2(m z2Zp=bO3JJ41HNRl_U_#<*vG?@#y;vJ|F&S_}k&9!2fhjw5RH}!o9>V&pFvFt@qEfkMUKzxmj0i`?fNA zs->`d^xXOWQCUkb`bd~2nIoj7DxYO1SPkXYm;cvq_!kg^H{tuj7s408*B)Uqe}SYl zE=KrPz;@3bu=ZOgau46(wgR!&YHi;K4|lY$kuEBg8(sT6Vvx4o>}MiZrdwN9<2Kpy z>L2&-6Y%^eVxS0q27LK=IYM0r_adKA-Z;YK9oV~B=*m@P4-X#;vsjJMTq?`fQ zn9Qb7AIiVrXj^-4)}&Mya_{G-8#MY&)^uZLtEr$X*!Lp_2D#(DgBG5Df^P~xkZ*0_ zxnq@&p?Qz^7`v!_3ukp5!+jQ&Wi_E&-;P$o+3XfYcJL>a-b$9ove5b;0<>&uv!>IX5XnzNP9sD!!1K`KPuaQ2r=-qqm<)gI@$c4gOpBm(1E&n|TLH@RLXObh7E?Wj{ z&(FQ=H!>{4*Vpe@Ti0KlR``aj*YJ-Z26*r%Ohx;@1iXJi7w12j3HfL4v%QNKF!wPo z$Fp4wNn=CG*k|_i3`}Z2a7Kw}3(El=G;2wNe z_}cKb;2S%(Cn8eV)ROqHGDk1t3yElf^V_V!zR3wavD=P!Ja8C@*>&v#@3znn*!A05-?NmiS>RBD`pcaOoBz#lse?O)-0 z!4JH8YWMhv68-o-=Ea8tEo|47nC^%ojU4YD-K%0iH~)1(!j@H2ab;IYvQItJ_Cc?H zipKBZ0wp31G1z|}o$)SVwt3uHwY{Hop{u~!s(lcD{F44 z@7qDP*OivO%1pbH-dO6NQ=BHF#qa|WgJa66iwzmJVaF`)e zQkyHZXU-5@zxrOjGsAeuT%AN|meUe*I%)D`E!DV5vHzUBor=1D#J~*rdeh~JA@D~p zNBsvcs#09JV6ZJ?gMB3$7)w7qu=u9r6RA6wjQdP-#e*H}=LhqaC9n74-rip%=Eqhq zJt;$ftd4)yrBd#7C1MU@zy$tz_>17v;CuN~Z6&#*f&%N%3^r{0n$WF`UH!h>Qyj$( z#TFB~QL~w%+$yaFf{(J5!)CKj>YBH4|3UD_xnbTw-&=?QTli)0+3*A58}8^a@B@Qx ztvh-8KFX`$6(8R5v^~_KbWL_$S1nQ8^o~W0B2qhO=$Mj1IRz6_%6C4?w<+|m>tX6m z#2$P%__{OD{s4Y1eCzvkJ(CA-dHhr1nqIfY3g(hlw%#m8>6kpb#H0JOyr1`^k2mM8 z7;{i;cEo`;MkCCUKeDO+uW6-QsDDBXCc-}q|2h0h_NOzy!Z1WwY@P+RMm7n!5zaQddv(h3Y8wX#&cR>tf zz)y!iI1$gju0a3Oez%Jm<;=6(vG=Z7E-dUCNy%Gk&f7b|h1?ZXo)9#bZj+xdBIZQT zF5gs6mOlToFpp;;`qMIVexHdSlZW3%{S#t941e@YynhM44t(>q8AiziP8P>~)x6ewY>^rD` zLJaiXkKY`=8+;D@#}7>hhlg$#(kPBcIW_!e0{hcnbh1giQfFIou9m({-Zz7!{%J34 z_6HemOD?Y)Gr~Xn=krIcoP}_j;G!mJS#r@`)cwPs2LB@bMEEiAcb7Ot<&9bAlIJj! zXa0i5KG|3K!i@IO&NObWA$QC+Z__bD?E2cpX%|yXq)zXHY;Ld26aOmuUpM_9llQ!b z`=5wGBlu$Y#qdAF4>d3PWMpT_wmeuf;PBbuL%-jt-ghm~xucMy$kvP23KQ@x#f!@P zz7!?dM8`x>PP`COI{)%p{i>fSPK&Yc;O|2WZi2sfmOL>u3D1G7lp}hNlBf`2G@EG> z(l5kz3e%C!G-vzfm1TT#OsrYs=V!4rV~FQ&1*X9mPpz1R(dO4yxp}rIx^b{2DjQRS z(+GSn-N(KUF>nO_4)`14FNd%2!e|TIZ~T4%g-;JS)p4z<_kFPsZ`Fj$p|)ykrn$_t z8l5LxKfsA(bf1?KUN&r_lQbkzR$i0OZ(Bl1laW7?IKu3DfNMX*KpgxV@I&FV;rqu) zzux3-QF)S8kl#7z=DRCqoBE9LUJ`PBp=F850^2#xtGKKYbpt}AluKM+xPhnkd zS$vb>=6eM};~2e%IRAv74PR+C-v0qV1b#I?)<~3Nss3&0%g1Cw zfw|%SvGnL~gH6o79OQ?56q_@j)Lmg)Jlnpyn(bT>K@oWc#LiqpEBMB+7`bvOc}%ri zK+|$X4Fip-hOCA}sk8+CVZ`82_@3}r!dKQqAKcQ9Sz}#mrI*e0l6P`>d`4>0c~bTs zIxb6Yl${re`(N2Rxa+dhyess0?VcUCqnh8B72CLHZ9tH~>KFYQZn0IQJjSzUh=JMg zpTKvAKM($K?nh^>8NB#3E29ikHeYp&!2_NTlgF~AvW4Ea3(ZZ)oLCJjbbdXSk`afu zpym(o{ki{X%Kk(8P#XH4K@3pf_nU+MkKo(FXIslBhxv`*+woL1yffENa<^n0XLmPW zAokBpk1Pl`i`_k1N~N$>m}YmKU)b^Yl`PQtf7L&mr=#y>_%`sjz*oA437WYtn>l86Cf~{2S7%EMpZ}x&xgPw5)ep+P8{x*3v=+V(V(=V%rMdFN5%^Ew zr!ApIt)U7%Rrm+7(cxVL8b81I8j$KgvX_GKHR^}>4VWz2>vy;fnZFX8<{1y4qW%*x za1H)S_&M+;@MVR@u()9h`8GVd6YV`=PSTVqzPHbs)RGF`{bNUxPkE+16$ZJ*^~Dz6 z)%-pin0d`hZZ;%4mu~*~wMX)QhI_Awf!pxS;qOaE{OQZuUu$#O#b)kmOPDKIiKP#g z8fLoiuhUBS%fdbTjmUfLWgSCz*>`kWoG#e~4M0h+@47#(zZwxiWAYCvo9AfziWm^V zkAeRT{t)r>>{8&#`UAToagX~Ni;yskIJ5Ow!>B~M0l1Vd1&+BM-YjSw914-|^kL9b99p0}2 z6EvjSO4P3?$xHZ~5d-t!pMdWL{~-JYIH6Eh@zs;Cj=5oCb!8fI@^R~Wcuf@j=KP_6q4-Wd89j&q+Rk|%w>9+QAIUjgZ^LFe><{p{~a-4 z4}TN~*|2iG?%iXvk^HsGkW=eWLNZ=1?x$ z{vrmRz`q3l27EL46&qMldrmo9)68aVp5S72mRs%`eN?f(@n!OI$L>Z^bNobHGqVJ5 zrqJNSHs6xVXDNnGSpTBNlK+wt{2EVxiT7{AFMzMO2=Cv5?+O1-g>>+xyi=p>rQVvB zj|s)4;;5cuyyg{q7Y3$<*|I;B zu3YOkyPt+Jw4YH(#m71OentTI|F!>r^a}Uh5ChZUpNFq-9oK>Isoi{TUE5qJ4DH~O z=|d$0HjE?<2d-uE*1Wa%dCD;1`yGGvG@oSkj~}u3#nTVrDzX*wZ%bTXMJo6)d4LG- zzD5k_z#qIA&!58YW{7QIG)`zitVoiaWuBr`+y&HnrT zry2ZfVAdPdJtGF~;In1Re*@3Kz;`iRwQoU>)7IJCZG1Z2G2O?3$B$W37?)V=r{YW| zs@Trf;QGf~8jzu9t^4b2v|VfEEo`m)KjaBy<2t>?z85j*1pf{E-S8L7mjBWWzka6X zwuvFu_3QY{@G4%C(Av>>Gc#dV_KCIX{rY99Wb(pTro+rEIc#gI)~vrp;7j;ch=Jqq zr)tX+ci^vsudPAnKhDeE#qcrP%jYdEI+B#Lo}aRV)CsoSt0(j(Jrmrcvy8$oMma^i zs%Av)rTWm=t@(e;JNFKCFNlFi_>S<0+(g?`_&?8f*d#fU#ynHB*vp8=_cJpjqnu(g zJ^8H2ADf4t3VNmt*&+%-1vS%<{D0m5-1#2w|3C}~;HSd3g&!*OT}a^>*FFZ>BQ&Vo zxBqFM5xt_sd0)7a7~~SuZ@G}md=_iRXEbAW+3oG-Lh%ET& z@JB7d`49Yy@I87et9@Ea%VtDN5`(mbd7s#n#Q0cS8&cIuTgSC>y^3~mxWG7&U*p3d zPak;~5s~kk+=lHzU>`nbW7X8fRKuz3?abn{ zzYST<3-CPPzwL4MIy$9m5selR?_Hu8!!4lx_j|0jwdArMpnshy7Q=T$3|7Ir#1QJ^ZQg{rDw;@#~ZVUiR>zCU_XqofG?h zpp3lY&82YT*Ow&qV=b3+O|RP)iml+PGmC1m*g8<}uh@?XaADXaC=V6j-9w0h$?)yq zpNDS%UxPAtQAweH!i{T*W9pQaB-@4MRH~k)PBJEqD>cwC0zqdAj^g_IU4!$n@%kZn~!OzJx zwA9M?4`+GjNImD3X7@RfZ55SqYRR*W`uwyhtnc;bqe7B_4q3P7F%LVntp96^ZnE~J zmDTWfBL~=1*JG<4KE_BYfQfIf^D{?*uiqB zweR(?#1FyYE)Hw0`4-zW+XDY|S$gji?!O}jLg62Se+B+G_(?_@5w<_um?~+pEX+oz z$_{d}S8k|`pnDr;tf3LMp|&M!~$uedNXw z+tEiVSu#iMSN|W)$Yukr&A^6Yw7r5ags-I|Pb`K%8Gavs_NM^4YT&KMf)DOR?o0|r zoNJ(C#*KEJL7|4_(Z$@H59V2Z*2nRlRD9I=Yn{>ltF20x7IKrhno*)eq#_2z@OQ&^ zhi?KO?_Q=Et>MWkdx~(hIl-s;1ePmit9Ihb@uHjzKIugy)IxNa-huwe0%$ zfBtkTRU(ce29*w>&I!H{z9akvG;HAk2RBYvv5J1+O$pfUm!lhZogDOTm$f9$W{&gy zd46$NC+W-9|j7Oekb!pP_A_uvE0%4#=@s zi7&Oplq7Av0J)u{(`K4u>-wK_UCVL*9lj3yK=_Z~=fNNGQ8@6!d8(t;=A0OZ1iSa# za@EJDLhclMkqX&cgI*V%wo!R^CZ<|oxWGx7e5w$&rP_+~XQ}nE`d@JW9WiJJ{}X)0 zdw34P1n=TGLMhCjt^A;~yw?N@M}=@pm)lsEe0aI@W@f3a-eU0>7a!T~z!3in(NhsB zg~Wfo{%&m!)W72XJ7Vw{{0Ym^{tNz0__D%(`>=oJP=6ail9$aJ+aI*%w3Sx|-wrVt z2mb_o6Zp&qpH4x=51Bn!`tWR0@cGf|3cgC^-)a=jXG-^$&U$BFOIdz(K-^o+DO72W z!c>K}j6db4e#7&}h=F+cW-H_g3Vdt$vd=P(6?+7kaeLR!GrF$1i|$V3d;3*WECk95 z5?#l{oD4JP;_!A=_K#F0k1Mi#mvS1M`r5UIjJ6ZU#7ab0#K0T)LGWGRpM_8P(f`kn z740tjD`b<{=OV%6b0|ZrKhdmjXEE|(hx2v$`lHcsC_S2XyltiJF{>+-h*$8tAI5eM zKOBA@{4R^4>o}8@6!uw6P}cc)*u}Pds#Mxtr4${`Ej1#qbo9PYpMEJLZs5L;&Q@sn zK*;^$uD9i!OsYiP4`NUqzUfN5e-eHb{7QkePPX3=NJZ&BSQX4~S@vIsKgq_+eaE}65QBQ~J>Y+Vzm!BBK;HGb z*#d4+r@1*pwnSD3%&6YDg)2>)YN*0+i(&Ea?poX@vQO_&@=c{=%{FOyRt`xI{fpOh zbi*z&9sUZ$02BTl_(SjGIYjt=DOXsE)!ejR9A}p-n%d`@1!jt0twfs~z2lT}$ImW3 znzz;0a+S)h_C672x#3Q>8K+m9H3j~hZs4VXRZ7GF#DFJ!1wDC!4*x!UNq`DxNo5Dy zfZ4tg%#mzAx_N=-!<$ixMC8hBm&a17h5wa-4X<1iNF8%^>bNqq_06Ek0k_4B*;b?N zBm5}%OW}LKSEL{o9#~h|S(HUhzhW$%axU3*Pv}xBwi;fFCYdLdT1X{>8MTi&Ux(>N zSH2RGiPp~@C5+bAKc@xv+u-aPockaKZ^L(m9}C|czQo?YR3elZWr?odc$E~P zwxJ3VXmO=Fd*#)ox?Tx+A2W6C?8>4@6G%3r$@ceGwqZWH)Z*S3V(>NmOYonDK0j}q3)r9BqJ|hB$e(Hn#X0;-Caa~V=s4A%P~4iSX!M-3aDh&kNyvT zgMVcFmWzUZee&Sb5QAUgtLe)V1@OPauiZc<^RjCcY{f>~Ro2BXeQ20pv}B6z^|$GR zRv-N~!QAIikhN-*>aN|nQ>?~}*m>8^WVug$ng7doj0AOWhykS|xbF$S>jT_>rQ-d= zL+BgzgRD}*J`IV9s^;5_J+n6{vTL8+4jp!#&M>*ZxAf5HUQ&azv3w&^oEss3?|w@E zpY^}Z_q~l9dK)vvsYCq}{E6_R;LnH8hF@3m>3ny;B5lnT9v5zwT;glI4OnqFtg1uO z%#SA7q_bX7q0oQO3Y>sz6cwKEU6R#hj;ncF=Ra-G$QDQqrKo>G3^L%qfbR+a4E%je zIl0twab17s#ioXI27k-*GiEQIkyR55_7z(u_b29SSDdxoB^H{;vq#Y9CU}jZ9KPG= zNCb`PKc|Ke%7hPM&=r1H19{>J{0#VGLg)CZ@VMri?Nm+ji=;uGtHOo)W{b61W|G+JOfW8$YSDuWi;BfLXV+RLVg&frC`Jl_&@UgLHWJ2pdc=L^- z>73k_QzoV%1|Go=gFhSoFjFjlk3X4` zr?u9{Ds8=Ak<$a;F@e6Dvox}Pmiwz>qY2W=JpJ5FVuY8xGNFVRD24wDzB7Cpe6Nrl zAFTTaEIz<@7Fm22c#&ovBTMQ|l9p9>o+u9#G3Ws*meCiuIjpCX+3Fi|7V;BvdNtk4 z{yrB?W~fPWoq{rv0l)K6EVrRNkqmz?eB)zo<~+ad2~#_F7Ea?T#n)u(CX8G})-9## z_=?9GXbw@yS|zM-ZPRwOUYa_PyI(rTSIg^k;^^@2aZSr@EiGy#lc%Ii^h68S03fWMyQPkDK!JTXWA+YSX+%ZSt> zUdHqR-&78oWrd|o)yaEnKwIf^?-mRyh>^d^xr6wxj0OH50x`{piBF$D99OkDp0ZJ17&bh`~(t|12F z;0M94f#1UnZ9&}CTq+~X6c$XcJiknV_$=IY zcgdu0mj?~2UR~PhpWP-Cj_#sN97GJ3z)y!iC=I_q{Cm>PRhxQOb`uGU(^fubmsF+L4RwoLv!-nGod@OSuTh{3_f zW%VAY|AX%j-)!rSB~uTvx*kgx)OK!P#8r^kKMQ!L$&C#=W6YTJ&Ha|QhI_oRSxT0D z#*?Evs#(^CNq?$;YxG7ndd16>P&coqTNJqPD>#q#XIlsi9=(j%P$|Umf z_2`Sc($*P7*V(F^+cDs9-sn;9gCo{-c1S;28@Ek*t+i!tbuZK;8q(oUMhpx-fqG~7 z6!@wPT#Mf8c`ox)-~C$hg?!JU@@IETKC!1UE_!iqug~}UZfPs`WY3811GlKzdXGB) zsW4GRxSwm%n%|fwYD_js1@=-V=QJs{)uf=6T-)Bt#1r_N;6HG1_r?y(?a*x9i24qwpPDA}`t0y|GEW0eLOCM#z9x-?y{sQ>@p5WLA zzeH)&w-UWgUkiCDulWXs6;*ty@5AH5I?m~u_2Ti~wuNdHROk1aH+7hlLhZwcO1+9G zqBe*Y+0ExJ5B@yF;CJ{(;A_JlVJ=6!zj5zG{E5q9btA*W{mj-6-^4_Jxa_#uRe2OH zNw3--r1PzKuxD;Jjmec=_w=E2tD-Ajwt#-0pN6PwoHANfndpibP&tV#}0n?2*q=oQO;3{Suf1E9UfN|b}5)0a;ijNXAKUEGhFkJV2w(W%>suXV<2Bopo ze^2e~t4!pEw`j>T?~h z9t^#{D|^OW7AI1zm)|27S5!9q{*8Lu*PZp#tn8;uL?Z^5!?%K80zVbLw~4$)$o^iD zmK8f)1Rq99zvq`QC)?M|N}{{m-qv5hTcDzI_+fR?{T0uwVmnf~1-H#-?yfKMfB9DH zuS~cg1~J+A~#XR+_bFl%u-K+ zSbKHN@Prz8^=1Aq-zfud{)rek4}Xa% z_J8mV;h(mDU7m1U`AJI33HenIE^E$Lm~^i!%7Vh9B&u{;k+|7=tDm8j@AiBi=gqFs z4v9(aYNxV)xL^MlT`D~?5a*xpi{WpAp9+5ue5*H7sjvO3%Op98>KG@~O$_y=pHHEL z+tA7Ev&ri&pW37%RCUc2zjHWk8I&;gRh4Dgo z7cTDDY(H^G$2IYhbi1`1Cx}0vvGypk-`AwrKPClD#@4|%LkyDeXVK&dQ~0A-qYnDN z9o+FJ$E7clSSU?$XRkhN^I*%yJi$la6!y`{D>7dEck*yw=MdW@fy*o_Qs{23O|NSu z{+mF}lA?y8$AfYHi5S=n-x+=|d=h?@qifMu0gW!DkiuxG!27?jNWblSKdlrwB#&4} z&F94J54B}mn0$|MpBwr94d+c!$Q)}iFMIO#$47R`z_A#aT-!T6LW?t6TXPS&+z-u(f=s?D)?gK+@xAV zj^0i|b@|ykQ4E{g&s18T&K9CNLeF%&c#TjxX=RpqSag1pib46ZePRWZztw-Vkbe$# z9;QreKn!-{;=U_AG>DF)gM&whoQhQHcOaU7O2d56?sH}@ z_1k49Wd`oz%~}?G{%*Kw2_BBF2b!E-)@QZ({R;kc#K1)OF7U(Q2f$y@tp;~M-3G3* z=ru1<)w$Oj+JR4js!ETiEGm7OA1d89@8(OnQrT{Wb9Ma}wfD9b=eZ3PApi73{G20B z%y4C*Jz`)Z{3!U};K#vFcKZBsyTbU5CZ=A!>y}Gu7Cqmt^xRG88yn@k%0k%Q;5gO8 z-%@(vmU6_My;Zq z4kZKEMh!C^HTt!v$L)38Qepp-3?B!Zm`OGjoCkN@9jOQYz_d9^f21-Iff#%Uf1nwj ze}X>|zQ%?yGaqVnsZFKHRFyZ6cYf5GQ6-k>P4`iwbP2VvF#EpKvO}q%*8D>kV#^QA}^V_V7yX zT%ug>mf)#rID6G}uDIFrXFpcPKm0j1Mw$2sUk|>@Dm;HAMEj?8*#B@I7r(vATC$0^ zXhf_imQnm&El15aJglyp&HdM^of4j9rw2JqRUf^6sX_8-idc0_3H6_!KWTaeutr0f zNI(p3f^Q0c8vM=h4L+WtInHsF(k-%wI@hqxte#eo)+@~!nP`{5mfZst{`}9!&?1g> zWYg?@Z>?&5aRses|H_>>R+-p`805nDg3p2<4WDb>`vg61kJ;>*%otOKVd!2fy180O|l6fPm+hc3nPkkfemURBsDp<|)||Hzsj~8yuk4~J^kAK(wSr?@C91mLl1#GrMCX>VFBP;{BdrW> znV?MEK@2W{e+z#1Ow_}|FOV#J7HBT?>3QREyQ$pEQ(TW(hQ)YGMcNzJ@_Qt2pg2|y zt4nb$3%cZMx9wS^i}BX!_W#5ASL2LmYbq1oh{28U<;`*b7k&tQrslUnoph(J@n!L( z#7N~R%ZZgzcHSn+TUOq=pjl(D#tc=I=Bd7?l02h2&6m^G-yJOMj(y#)Rgl~2U9U#9 zG1YgXGGU1rJO+Ord^Y@-@OPPpPg)Tkne48`#lOc?cR|yE@t@5 z3*s`wB1g467V|1oMNAF!Xe_nORKrii`87!a{Hch+EAXA*N5JpPME#R=@ZGatc!m#N zpQ20StPKWG$*L_%OA`=9dyTsbWu|&%8B;glfHy>BHt`C z4qz=x_vc<2yfE`sw+_0CtQr=rCEUvP-kr@flkdCF+})MJdQRQ)r`j^gv0U3Qi(+RBg-f?}3hRrD2Bpf)_VAoqTe(LfYTB+HqNq`Ad#k8{ zzYsCVgdYe0Bz$A|5@Kh1X< zC%JWofAFr_?hmB?(Ho84zoldw>_aVOq6cCi0=@`-GW^5vFWE@zqI!O`w^+G)bmi3t zE4|OJ5*!%pDF5VDHuE??KyTY>t4yj#T48Fx@U&EtDv@$Zr~Ohnzv+VCavCyDPgN#f z!_R@=el^H_A@@hw(~)6Oeh zWjQC`yX4xTZr|1_&(`aH=cVH*GRUrL*cKn@*lV#KONHLuiUnB>3-$LzLjca6u1s(c zgKEBb<`zB)e<^&g^FAbJ+N%HbZF1uNle#fX1!|Xr9holn0p80qn09LgIlUvL1B9+m zsC6$Co(&$wbak|q?Iv} zf%9r@qzNcNHD>d|Z)~sgQnlo*7L#_dif1w^I+e{ECf`u{KP2jB;3a%D#K1cE9oEPb z=iuLi-|o>FL%E=|1+z>kC6A12ITn(5rH@5rj~zQ*9QIrTR(|N@GBKH6W6}*55S)R|1tcb8*mM}mJ}A2h4(&FJTH`Q@d;o-~8J6t;b%Jo-G9C)8KZ$EnxPkK3Iq+lQkIhEiAAGm^vSq~Z-UiysE5bgEO3Ut?+D&ynYk9TR^YQa51}U>V z_wmOJx}`s~K>c#7_di-$a8c9w>NiK3pdkjW{P4TOUkE=IzH!ZBN3}CHWaq0dYa(k@ zq!+hmyVHV(r*`Ku zT@>3H#KbB-|5vl=bXVr$-UIw9_(Rsp6G8Bmtx*@Y^>OF%H!F9zr9D{}oE`aKM{lD z{BhqC{v-Hv;SboW5ogi=O6cU-=UAah4(r_$m8KPa_u0`m&VpSgSP{5gkd?i3!l+x+ zX>{K&A+?5Q22AYV?!-P5?=bwl{Bl!E_SHM3GzkFL&`Mg81cWFDioP8C$ zE$`>h?i9ORp!+sC>1?^1ZsiIEGG ziS>xV?eMR{pO}ODF!1So=h{B=r54YNs*~5a_A_NK&CO32DVC~FjC?R<#{+59`@<`k zV(E_R=K%_{E3XSL-JSBU_g|aMLIwQ)5QBd3tKhGJ-jZ4qpx8>0LrIM^ zc68mIS#vG!u(#8*hDLRh&R05c^XNK`xN^vi+`HdsQ$$~Dwl@~sO4K!uY?ive5a*wW zft&Ehtdl1W!l%K{G}e}U^{IPZfE_i5Q<*C5l_eF4PCokDeOjI9>$kid&Yaphsl=&N zDw0Uj4@FEFD|Kvg{v&FJ$OamYct|&yJ>NxWe+T~qd?WZ*;Gc(&mmJp}wYfCijhL>k zpgyymLI^SL-Z=GCb+?J?8~ljWZf<+9V|wJ42U>ipq9gg@2>Z9!*u@~lldm^?yF|l)K*8_WI z_o|-webBHevE!ypnp*dWX#cskv)hBT9|gAcN6=*Jluc9jb8Su2#{Eyk;5PU>;eUnC zfZy>m5m|IVLH+#L&PU46ml5Z86Gv+W(_`AV8$zT7&wVt}?NHi5H{xbp8eeo^6e`=f-xxWUV!|#9?m>7We zXYftor@^1Rv43X;&1Hmw+px|Z4}?63@{qsOvG)FpG{HTh{ddiwli$rLQ}6thxFMfg z7n|hf_V8?a`__d&=Y}j*CSJfl2LBlRlkg?*L+~oZvj=YuJ74Se@Mx5Dn!?p1=|_+5 zo}Py$$`8klEproeY~QIaxNJj#Li?kgzi2+_)c*XRrPjx8S*A=xA_hOhKL!6j{3#o; z4~9!4mRd;WXVN3*!Lj@7X;$C51)96wx963ejm>%QHUH{7yMxN+}HB*sRil7 zg1-ue-RP!Xl05t275UC(HS^M{ZcH25S$ey%%)hHmrj;do>Z1M=F?a<2S@=5e!{Jx1 z$i4a?U4)v|bm^ygmDkb*JI}t<4AFdDDaM{;-p(@o+tRZgGc_)DD(F^yv|H-ebXiv8 zN7R`7E!E`c@D9EzVlWMU6#Q-Q6>PEmeIHdvT^f36;z!+gqo*jy54(7MZr9+C3TNcI zci$;3eIibM_jO!tQ5L7m=*PQf?bb*N`F!y==N~dIEyunOekJ@w_}=iH;m^8uQQ#S( zz@K@#v)i6W2Z@?%T{nFnD}N(bUR}N{6+P20yGOVkYF`i%sXXx$v0Khl{=kptdFshZ z*$H;jeQy1TCf^*S_pVST;t_-MgYf<>_>bTx!EawWZfyIBDfa|!MDWGk!3qjx*A5V? zrxWYOrgW{jmj2ewL+bgcR(YJDu2aYJM7N@0SN1e1`QMYqE0qa%#9$cwC-B?np&ual zf~eUA#M`gw9lI&SeAB2sR58;{gHN;{7Cf3LJMdB?rR($2uax)~)r$_@dvH%7xc!Yz zo|pbzZJctX9`1c225aGGz@H0$s2$oOk5A%9@4`+x6tFzMR)2~pkJYnFXU+mpUiJuAvN^n&X_}3g6~Y|I zv>_np_hNG!o73!f9yLDa!|^=N;hgv9e9q^5&N*6=kBNW#@ZUe@5uYOlzkz=Y{@Cwv z?EyZMC?*ccO7&@bOJgcj@0lZ`&ZMjjd>8%YstrZ$d==LuBnZjZUZE!<_1MJ?{^9Z8 zuG920e?i+jVvt;i>mKlDz#lmu&w%ly2y&%8*dQpYHdBK8!XY(Vr!L?&mBtig9m9RQ zJ0?(?Q+&OFVH_P&@e2u^cwja6;+E#t`_cA;7<>!43HV>YUkpE< z5-TcO%yDK|W}zvvF~ZiDD5VYcqGLZ-6O{$YSc}QVFwIkO8&w5WYKgP!Gxz3;TjPOK z9fW@gV&Doxk3YN>{cz!HqTw~Bh)7t+_*TSkwQ^Q|pQg)B?k)aBBx>U&qQM49)Xv|v z*R)Wf?krvzHH_9cdbWSp!1@2$nCZbhVn6(c;b*Y^e}d0@0cB7$-g>??I z!6Yz^?9vDb4WZbkk+qp9Gipmg%Z9{+QWJ~aKtOq6|y!4Keb z|Bm-B!G8e0U*VTASVX{JlT+hmyST-QPfAo&0YCN&sal^_7H}svw*)zzasFQaHwu5a z#<<8cbpMlz3;Y5&MofDMbx*|LxA3oozZd>8_$Ka`BqKvsm7J8acos)l`o3G;a$CNQ zx?WLhsnNSEJ+qBw4>J{KRFQ(rbN%a;O||w+F!*n(f2!`Uu6#I;xC1db$%t|n{_p_G zVfY!kk;=$r0fEyMU2)C4t3^_0-}!wy`=G-&yov=_u@OVxI zsc$KMgnt=g@GtPi@TKsjFQWdZlCAP@>a;vv#44?Kd(spcxSz1o34cQKbQ4|J+0|Wr z&tCMkGGum2qotgltk*Z=!FbMi?ljvT$s=0fzYhQR@Lz;)grD(n`AQ;5r(#_UVrl;! z=a2s9Z$Etam9jb|l?T^5xjOCYu)2d()u}!;;+&~}=fBv_`0qTLM_3Vq7Wh-(o8hP7 zZ&q{N;z=g`D3?BwzQgF8*WShDrHkWDVR=Eas;#zKRktE;Ya3aom37eu_e%@DKkOf} zy5Y`Q@w3V7`uAo(^ce2{Kn(r>|5f+__~c8dgMUTuuXz2bhmX+vpLq4u8C|;d7hA;> zYtOWnf3Dfmvc*FgmN=W;aW#*6x%CGBo{oYUHKTf^irz%;XU>N2&FcLW{WXuc7cqFn zdOZIE{=^@K5pTeki#S?;g-ELRiluc9C#8>-L`>YIMC{PH%3};EV@}W=tZwjx^<P~wI8#eAN}|fr?9H!t*`3;WeB)wE zX?4YJik0|k7U5>E@h~l&Plp12kFh!K(PI1m_QCgf9ua}R0RDFPE8ufp#x>Y7g0HM( zO^z`>V)IzzGJHBBvgl(qdTmjujkm3X;D&1mB`r=rUYV+Niw=F?skRQ(TL+GwXKeKo zxc3P$*aY7LzXkqX@Z07F?3)?N!l=wmD>8bSg-z;BmE7BS5$>Fu%jem4U8>fsbr<&Srq?yecLsf_Ktk%(k(2E)^dn%833^Dj1`~&c( z!QTTvbC21)OuNh^;wCHKq{s1?vT-G5iWG8LTw$9<=?X@|6D*v1X0)?On~Wa3tL>yf z(A}<5aS?2`&^|kGXQA$c7}UWJz}Lec_6puba1Uw!OmVfTvoTJXjaB1|JLGY#hca7P z3PB9-gJYPgFST&fv@7n>yzWe@+0L%T{iRRu+`B(328<0FISl_a{Jroa@Q=Zl!5=Qv zYW_`e+kIA#fn4bhJh_r#Oqx!JQ?yhQHW*2-GQ%zKG>a@I7E|EXhysc)FDCxZDWW$2 z4gK#BgI8=on>+l%HpD-CRbryu#Eu2`1m_8MtIYvMsU)NLEGkUj7$Z(Ls_#2oMfvKR zPE+OvZ>lP$QqCSGx?udd2d#JS=v%Y%h?R)JC*fz{zX_j$@9`+Nh8zapHqsZjmaqR} z))H^D(&YHaCk@@vqH-EGQ|~yoePk9GsrzpUl@fazivp^?LiOy-`&YI<)$8_t{^@D7 zy(0!K@Y(-h5ZmFm!SB?y#*?D-2K7rsq=h}Mtn*o;*F1t{pbk+MeTekiN}hS?og!Z1 zHlIgo@a(8(KDXQ4JJ0U@uy5pS;yfXE&EIkT9Wi(e{x$G(YB) z$hVu6qx9u_H}Kr2lWpc=r9m6_lZ{oZdv5%JnA$A%kwjrF@NuWHW;HaFpLjiVgBYwa~U@J$9~KD)|jGHLW}CQ92DcNn(_ zPIe`Wtel%JmoVho6YQ3mC91HxnJ6-hU*}Pc81ng(InvO{>VM+?W5nP(_Ys?g5d8b#KLmdte2$a0kV@M}WTLaPz)Irrh*Wr6Mys`&obyFvKCEPvt2#Ks z2B)FOC}OZXm@bjO;lk3;-%94>5qBa6Z#3baC-^n+Gw_QiwKWuXkSl_b%KUxHI;|yw zhUQBHb(VkU>sP!v(O%$@-ri!Jq+*1O$DA6R9;j2w$wLbl&Ly7BBQ8e_&W8Ua{Lw$* z*!vpZ#m$aWJ|&8}h*hDr3QPv3Aip-%)*|7U4y<4iy9)0y-KL9kA_m*xzXpF3{14#Iooh*ll0~LGouMun zn*G=NBbl&(>M#hka!aW4dYi7Zu1IRucI=?|j-AX7TgoZfHrT(I@fYXj5sMLn6E@*D zhyOGD@8NIp`7@PzPoX~A#tYB8awWs#BNMywCF?Yy^eL)QFaJd~G0Ij7IKe|{ci2;v z@unMd>));CFLDPg*6q*X*pC?eBm58H-|;h^L;E`7zo1@GH2MxY)>OUR;`qqJR5O(s zzMU;!R9nGibyVIQMN>ULz+7yi_4co#v~g`aPK$;d`Zq&Q8GN=R?#Ukgd>(NfVo(eJ z6ZnhaKLKA&++M*aY?P##NSejLj54sIIKkky#8sg-X4>rZa%%$2jF-b9nW70oWt%+I zFmFixS2Ba}Pr&~Mz8(Ij@IQesaToqz_ogQhRDO#=j&|vuVVFs2U@g?AiwzA^_2D0w zte7k>-r(=tQ)f+UFG!uO^9()=Ip*aNpP>vODfGXA-vPf3{+QIxxa_m<6G@G7fnsHq zGO61!o-?(o?V!P5qT(tW2|==VnYusI&haHZ{$Sz!OO>5+(R|ds5Q94SJK>KHp&$Mm zxc<(-fkdZa3r8}HZbC&-8kWGmoyerNCKx;0LdKw<_I%Yyr|UG0v{&7H^9FZSLBHhg zPYy^`WXJmV2aNpr1=KwdgDLop@c#&Z8hm~riS}fVKvL{xNWHX@v|q+pV)pgJp#diqW1RGH<8aRJ_7qB9u}x z2J#m**6MjFk7!02un&GK{9(sX|M?f{UzsFd9!$m}D+J;eC8u-N*Jfh7d9nQk{j6hJkcn=DPZF{2h95HNPl%`sBiHo zt5@=fa>U?2;2(qk9{hLUbI4?7nbb~s1f1^8(DNroC~JASC zU+0%zG1|W`q*V;L07b9n5mLn98u$tLpTpk|KW5=2r98r=TB{u|9KaC9 zVjhv)=lz9^Qpg^P6v@eD23jm>m$iLClp2*hk=O4H>PL%)`uzvyrOvq|HunuY{{}G_ zf}an6GyGckBSq$7K070J7|bGK+0Qb)$S>9?-&U7fSCRKNk55vg5|x^K7HgC-+!SVa zD&`A4Tbkoh(R#zI{X`iIO-OTKrFFte5@N;s9NV49EVS6wRk}N-(~;7- zq-bPCW&5?6#&ha_XSoaRm*2u~h3|p?NBB$OKL|hM7JOpxRSNwENhymsykyOp^%?Cj zEuKe9vQ!8SeSf9rhM zh4TNk5bd9c!9UpW%pv$!wWA*<{MRd5pBQhk))r7|7SkFk6;zx(91-Xmz&Ls8Kx@~- zr|7vASGq1cx0mmU zFDYC=x`>y@lT!_$ohs`zO+a(YG={%MC+dv4v`wRL`PO0DKH&OS?ym37U50__tKLTc zPsHF6_^aX1gD+i(?H`m+A(LgM(uy~Hs*PKhgq7BosBZa^FSIp=cl90Gq{y9^VKPxn zMzQKS_Ef3xxbmF%OP#Iiv<@V5myA9J|2X{dc3g9Xza9Py@QJ;(yM!_3)om;y;nwRd zjC{6J>(GP%14%)_fDKUi5ermN3Wx5j0UCU%lUmw@0RG<%iMkWLnP`d@cbK; z0guAp0e{qSJck!PCA5b11{F_5*(lRjLSau0Sb$?eoe<@{OIO5A^p7+eqk3;2J7|2cfN$6^o_Ec1M^(U=lTW~|ylN<=lwxj~`U+wfT= zO@z|AMRd&?#w?ZH@U~&p-A;LWK>eflCpbqQbcp`jqCDbp#Nbt1aQ_4RPv9SbKQ8?_ zV?unNn`dc`h1l4?PikrNGPi_#T}E9f)yco3YbIxElEkP3^$A^vnBkd9yL+v^L~q7< zJ}Z!4tjZ(Ah{31fAA)}jKKm`)|3uH$y>6;3yAAh2{`Ud;sYjpM&*i=(@^HhZn`ySa zP~}n+9;TjbeACX@%<44yqnh)s@_G2~Y=%0INW!u<`^yB>64@OZ2jW>2H@@9xF}b`Swk1 z?zqC%nf%HfYaAA2daR^=Q;=d8jM`P_;s1Z#|M}uOxc?Y2_;>hM!Ec6t!`nC)NhQdA z`8N{JM{I((&EXNFN|STi{3Cwvm($VXaq$hh@9E^F1@&Q0Oej!H8>VIzw^in>)}- z)GB*8qZBIrL4wFk3F?RfHm9K6Zy6u>|7w5x9{zs#>Ke5B!+#L|9{7tM>03EGltOVl zU~w){ZdGX}wN$#*$%Ay6sh%!L+h(((?iwFesIo5C^tJzXuWjEEe!wqr&WKfmx+ltj z|G~c<{s-_`71{cSJ*}W6U$sg138OA~rg8WgYSTVX=?D>vYcj6wY&>otDdpvs+vPS* z&Cx}t%|u&CH~FjXz|B+cc^% zUZ&qvyt3UHeTBEYc#eYOaO#tOsXeFtqt6@A*ElD)Z!5*%x557z{zCZc;U9y~yCxq0 zc!Z*$c4F-A#U~?Q)>%w}L$zhx-SLHmNkcK4h22xhGD&&MWzm!Q5$8SnkRWIN7nzLG z?y5Y(fiht7r`h{%7(_e#E0m~<`P8;cEJB7&HKV!YUXHTkw8M9D+w7(t@74%25kqi! zsVyidoSG=xOe@!?*P4A2M&KgR0h3j~mq#o@3@(Dd8a{af*Z$y3lxn3_N@zOrDY3Gc zF6h)%($Qh~rxo;>I!aMoYU*;kqx1clE;@4rnY5SFbNyq$-0A*nJzDI+h&y)Tf$WMvw_>c^}OtWO86Q0QTUf_!~MVTo8dpT2*>|at;9ZK z*BBnXh+?&`G6&cSTZfIXhszX7Rb`o6TvK&l)va-B@zG`NzTwRYMl|Z{6Z-^rU)K2& zEz9x<7s`OU;eP{P5Xb!&@OAg_in!j+qdHE;CMco(^5&Oiw5RL^I!V`*G4nCI_S5!s zC%v=e1@$(bpiU&&BRrqce;Ryl6>06i(f1cISOq@-e-`|&;g1Qo5F_T;J*!I`>xB2L|e@!=M>ez_TSe2rO8S5XZEDdys$iv zcmgrl4F4GXMewC6l>g7&rd&)BRQByA7aGbpbbs6ZjeL9^~1?LFWQxoK)XK>H_R@O}6< zz@GxYHv9XBrL^Qaf=HN6L0+grK;S%V$3!vpvs;ktYN3Tbk&`5UP^zSUzQ7^11jwX#YeE618~e82tJ0kHAm)=v2e24p;S8vY&eQh3q3)Nc@MINB2<7tDd~< zB?VpIjDe%kSd*F{%LsR-+rF@v*Y z8M9vaI~C8_(Q&}DPvt919B|U;A+Bo+{6DJhb-&I@J->N(WgslG7Ulft8J<}9_guXwBL8cS;UBG`0{uKD? z_!3t~hciLC$67N~&0|FK?}GV?N`-T?xo(F!Nm6f-`nrjNaH+*yxRXk;D1z?k|I!gVeHYigSEU!In`3g@ zJ!)cj$`R$XGqloV! z$_XOHucl4xivkBt^zvHNKM{k!t3#hx_*(e+@1XuupmR6UKUhNMwrNeG`y6hUCTXBt zKTTjM?4n4OFQl7WFrS*G>>ycGhu(b?k&q4*e}lB%(bnDseTP1en1~p>AO1G@U%-C} zzHmxLr}Wf&BpeCPHN!7c?GYs@|K-tX+y+1O$Z?|6l)xA24TpM-BZ5PfLTERms(pyHJzOCJ+oug`DRo|ZTp$_g&AY18*r z`RaqysDz_VMr&LNUb)J39_WJE_pQ$(ZbA(1fd2#h@uzVgB7C2&nMo%yu{5*OZKf(j zM8dX7x6wqcq9}vNOqms;DlJ(>qfTHT@g_i#l`@+y2%YE437_EE)9}0C$KcO}-vU1v zts?#YX63VHag)NH5SUTJ?yh8$S}JIA-Z7Pu9%`DyA-nKOW>Xl8A)*ZDAugC5g}(=7 zz{H)n{|5dc_`{YW{{0cNfMK(8#XRFOFI~2l5PM|mYc^}DBo2|2yCSIDm`6O17}UbQ8p1=l;gMd zr*o41nSH6JOnHP1F}M#t5B`_%YvC{asq2Hs9)9Y;!>Bh!=#vSLed>|Ki!YzbK6UNL z6I7&WbYbMX=x0-!{8Ml{sO_)eFH87mXF3qP@Zp!1Y|10Jh{5qLoO8oZ!9Nb4(bAdv zKECywInvvDs;i0aOK_C6)`b}2R6^M#6%WE55RvHzWvmnjy$;M+Basl&fIt8_jm62=ltQR z*4KYNP_gN?iuqy#%k{2_q^NW%UOn;SZ${NuZ{`Zh`sbZf*{$f$9V)fn3>z_c1peFb zUxEKW_(h(!w`~vnT>8|N8TH~@DMfQY8K1KFhzkRrKa~?4cF*qH*2mW#Rcf%L)V&VL| zD`TXtc!Vb@WE3(um0Cjsb<~viT|#46zE+{tXxD2EjLK~)nayTP&mqYn^#Lc~t>;W~ zg*A@|!`}qI3I26y><94QJ)YoLQ&jDz+gDXLDeI4a3=nU2ocZuAtXN}jsg zRb;CBQkn3x+J+M&iRp#53}tI7;8ImXAr%)sE2SUYl1JQt7}Uehz<(P4eekurs?;&1 z6W!{FjNentkt&lOWs6@=1_MSFQOscR#pwI$m`G9M{HNaP>hwM_;bPu@jYozIT*~Vl zIQGMDgU>EU{R{s4+4a9~Cw<>k3;pq1zb8cPe>RfShI!n^o|hdb_Ddh$cURu)j%4!n znXP9ckE|c?>5OgmDU~g0^^DyKA!Cxuww#LD`Fl+M+?MBot9MR$Gx%$7O&+lVWxyQx3ix9( zIRC9gTO3~&Ye~E7-bp-NPky_X7N zZk-ENF7u0B2dMbhr?#`JONO?j1KdLtFjFWq;yH)Q>*QZOC-j z*YNcy1DfD3hELLX{xSSBsmbw`g_R6Ku)MM^KU&qG@TvS!@!q3a6V-5IwZ<% zjV)YTR%4i9`x0#JMsuQV(?!0 z8{k{ue+6H%vZb;k^JlZ4ujbMdbl&(5T6~b8pG!@uX!Jf}skTyWiRy}bbbpeB<7Y~L zsBg$L>3V0q7FPi-whDHqGmjXF7_5N59X{U3OK{#p9XKIYXp0pd>DltzosnXmZbP}B znTSSGo|3%eJ?%~Im)a_z0*h*U_1@3y7r#DSUWd9D{7>OG!kV z{5ZQ)$@yZL%SAt+M~G+S+4&b`Z-T~|3NL$6=)6PgdA?eQbunu!?eyCu$vJf!km$3&`~9_qkleb6>WI3N{6TpyD#j9Uus(@?5f+O9FJEv(ava5r^VGLrV4t>!+<&;JywC&nawCVrQ`Q6lB6Xvn5epVaXAlYLurwBD=A{#R$ zF0#h?F`1On>aEG3J9owxnZDkQd;j3S2R{jaD*Q*`D@PwDCDpsvyR!4?J)Be^{hD@l zv_=%W<_nWn7JTl+X7(ogdNzer}M>>bWo`Q9%Ee|Ev&fil1gpF5X9=-@AhZ`N*9 z#1e`G%_Q0UYBet@FX$?C+SXAXmw9Qu-%uovhO4+|%1XmE(o9DIMUowPgXeuQBzFAj^D9S!RE>|;8&LS<9v8`HE=XJUFaTU~MqchS{#&Xzg_!A&_v z(d^Auj+d69?6}AQdqVHd@Zo3Zdx#jk>T}dP;g4b98H~#if3XG4+S2Ty6@%XHjV0F| z{HB^Hoe}3NLL&ctbXZ=| zU=VLs3Nv1sjwRDg#%PDTOjKD;pB$4)-u|&`(CYV#=cM{~Pu4CxdlF^9kMO6#{|f%F zf1~_Q#%dL}p831Oz9RLoZfk;>&^R=^^wNbWbW-OshQ2s{<7T^5yS!+T zueYQgsI?9p9Xxgr{s$-n#(aTyp1|iZ8N`$D6}=O7(cyZv&)y~V&oJ0TraiR3s%@pJ zQY`tqprBDvtg79BTVRughf8M__5PFJ^111A-1~tTydVDG;ok#)E&Q;GqU=jbq^^{$ zk>D!XyufrV!$;1ml!XNM6xtV%+HuqLs#GKW%7&+>LS};TXPmKO8@H%JbM8# zxETIC`0v0!4gU+(HLJ;FXMk=k(%8m&PrS|BR39fFvoex}1s1pHu?kb=!nN`OG<|kB zg<^wn&i=v`)bFIOOO6VC{57E zPx2+Db@xzlQ+vmiI;D>^)YdY#vq;z2NL1@pS4%Zo8K~AiuKy6zm(`c(pNbyah_*NQ zY50rbONOHl27Hz%LQkuenwE8Hjoh@^c1*&^Z?{z@&Qu22MN3D9O-q7aeU*US)RL@b zTEs?ygt|L(-EuX}c~WAF_q1EgP~-wFIT;je~o3r@=z0{$B|7DOl5O+l5+G`V5* zp1XcrNV`vDE-j&tunrQDNLhY;QzN%@eDFGF#=mKxe{o}VyYc*QlmQFiuY|uF{@3tz zFYn7&x-yRk=Tnb8I&fWai8xe?0IvBr!bt(9D_H z&L3Fov*k-g_X6Z}N*%H|tn%Uc--yAj@GbC%U4nP;uE0Bx&JL|TpU-cisO}d|JoJz5 zjQx+{kuZNe^Hv8j`wD$*0*UUxpNFzw&t~tjd&jyL4qw$F0>)~hL z#rD%Qn;R|eEzRYVmjrIkcePZl9$r;#36qpdYI2H7Yn$05Z>dF2K3L80)u-M0EC%~L z#Cfw@@y*T6xc&*h75<0t?|}ag_+vdWW2$jFLwaaK`lQ@i+fgjqu!k+aUi&Up*~-}T zQoXiz%~kT!SlaS23*sK`%dA12>(CuPn*oO zRw}7;b80E4_1b!NVMtAu*8NiC<{0@}l`~>e`QGC<=~I;YJHK)^lPYX%%JqBFy+_$| zzv<1{3;!*Y0T03d6n-cC2KXGj-Ko8HO`?bhpywqnGE!8b#pFC0po}U5rEM{hB2ImE zo$X(L$?gx2w$A)kaq;b6XIDPE4C`9({yD_pyYTDb&$txtAcvo-(S3A#Q_YO8+<5=N z=MB7!`)(Gcr!u97{5#R&=$Ap ze~a5Y?H~4{?hpS*_?_^>@aMrVqdp$_gT`u|#t0U7Z^fQXnf>J|djBno+idPWSFobB z>*dVZ^PgYe=KcSkrZ4*+?*Bj;FlslhIXsW+KY5JqcagpP^{3{~Prv@`u}9XYgq)0O zai`$$%(v*{L2GqQU3pksUDjdHK4T4IUflMBwmYpY(_Ojq9grTd=MVUX{sDd!%7A?M zm%*P8|E3Sn{<?~asG0;t>eVrbt<=V(vl+M%4ZqHmdX02U+sT1)B)iB zuW|ne{MGRP0)GztcKFkuRui`RMSu;t}Om!;Ws-_3>{nunI8mF`NZ ziZm36t)xZTy>Pkf+L}9ZfwXWxo_~WfU=RF%!ru>{^&eadqgHm$)5#`Hp{ncFQd`&= z+Vt!b2R=UY>Zyk}2{$wM@1IHEKxsyVHS1UrlA_p_o|B5-w*SZBe~2>RQXlF+@QX(< zh!XhMW#~--r>(?zWx=-Q2vwKbArscrMV8oSB~R}7A+n8pn$FnhT8c6|Q3s<;lt@c; zucrH)m2EvICnv-EO&;+q%77c;uY&&p{72yXD9Y0P1Ko%JIN=Y2_&O()z@>h}7NW(DT2EvxCMsoU_oHa=ySvTGddy3gtzmC34rl*KNd zeEU8748L067-GS0`xgE0;J*pK4(mUjgFbNZM+i*wOfy<|H#&cc)KiD{g`8G_%n)`Z z_m(%bAV=P$AgtPg5as-&YNA%6GbVXv?0KyhvC0D`8F2{jK0z5^gWnAQ8Th>aqA!jz zS=lf*IjQyy%4T1#WsvO18C$W5t99z_u10Fbf)1;&=-BLnqpL}BtH6*Mqc`^S|LXq{ zDsne`#Q?Q$#C-_<>nH<$fPWDF=kRZbzua9C&Lj`ENkr3Qv}Jq9d_$7CUVn*Ds1I8@ zqZ8`f+y+~d;LsQB@f#0~*to65uCE<<{i&~n?X!kVP=`_WA_lK$LY)u(^<1=p!LPT> zU$uO%xp_i)O>M#H2|qk`Vr^){v!h>4FYTxo>N`jav(`a(yk@2xl*YE}y^rTpoQ~Wh zV}GN~kZfP(Ti?M(49YR`~yMlz5HaW^(QD5Ls{P5Z7wFg)2>J0l`*%DJHcR zi%3QBmsMFx+8vp2QN55-9kTY#v_FyaE96vq`oE`V9Ko?4{%i2Z%)_}q{A2I~1yz~M zw!&H3`Ay$xhp{&pgABiDUL@ScUSe{Zlj7s*4W^)xN~#zvO2GT8wC3=JrI>AR;g`GV zb88Il9J)I>;d|8mQ3mXQe>MEeN8%Z{D^V9*XH&^EhNnN7{a9vAy~lUs;c#i8AR5Gj zt~$)xf?qaMrnt=(_7zr_vNs*9sxvNBpqVl|^e#e9YT(jzPu2S;3SW&fpaVV${{{Hd z;GgEyl2tBkSjxQar8mqIJACp@J6|p;7fQ*$};S_vdG=dBg)K1I9I@&INxD{I}tUj16L@klGr__t*Z!)m-{qNV3QLvcr2l5CZVsIM# zyWwBUL;V~6{KL`bSKs8nnr64`Cn>6pM-X@J8L`k7#-rXJ?mF=5t1};N-Cwak`)f1P zUEkqGmVtYJKi88wdn_27P5qciuvI&PDH_Cud z;4g*01pbroKV3+(n-=Pd>hJO(LX81bzR0mfQT*H6DcTcQA>@e%yxsHM-_35>Ow=k@@{7rh0YiLTs1f72IlvSRh-Q{2>&UR0jxb}|Arrf z-vmE`8=Gj^f|;)#^2~hezj4;-Nk(EPrFEIvwao`!ea7Drev^KioL3VzY)gvG*2KNq zU5f@egIBzNzspYO?g>=W(LACMF(`qbhW`K`Z2+rqEk5aM+dPN4W|=eYXQ#UqbtBVF zrj)w)LD~Yyh~FiHpwtatZa5j%_8*5p88MsLUhMn>)-{*UB2E3eeFj)`v?C0 z@F&b?5G&!|1)oI;*&4Q%Ma*H;l1eIEI`gvZMBw=i^VP_wG1Y z%WO)xDr;`{R?|PTz|9(Q>Uz7n__`ioAgkJ&w%x>{Mf}w9}_WGBy1)L@dUEqss zQBHkfjOMkKT1krho1&#NQE_|qG1_aET8c{t9{;+53;hB;OK{cCc=rm*fc^0Af=`Y@ z{U1J))-ulQshYFY`*!Bk{f!C0av!*oulx};YZ=etMuA1U6iy=xxudJ96Q-g ztl3+Xw1w~S^X#=7eSAiN&0IXcD1NxUAiiCpQ4oINkoVv9s^|N3hH(Ee%79zp{~P`y z_;;;F`?re9=N!^n%^BX7WHjoj$(K?|zx?R}=kZvnib0#pY;VR!i$a^+(Sv?(r}ZA& zEYtan-2B0N#(T#Qdx*hT;C}?)1%EkwYr@l%h>%s%gnNvcvh4E)nT(TE*Cv}=r~KI*cqmct!0G0sHB?Hr?vK_auRFlitJeT zpKPLM5JzC63}}UKhd&GcWgiVA%JnRh$-p**G*p|ll$$9YmAw$76cnp1meN?rB+C2} z)$wC3^L_NaE$QNxxuu@&<8OZq_6isN?1KLi%7AP9DD&Yrz@Gx&jXowGLgLA)7$ivs zpGc`qg~iC%G)mmSz|Ow}0z}-QI5-+tL1sGT?dmb?}Fe z#`!<|?&by)b+FcIb%l>Jl$JtEw$RTG`fNgrMD~o#l|A=E#xUgc&hwnl{*t#pb#|f; zkLMAi5rYTe?}9%WzP{VX+)2vk4|c>#yN+r~8?O#I>T8xU9{)6KePrgwa%q^+5be5p zB-{Sc0fnqERZFz>%<@b{jz4&J&-tn+`D_R3{_x}Qzl8rSd@KAyYoNioEF7sf*jF|v z>`Ak~)+c`Ir<=KkmD&hrvLpD9SbB$2wD#2Q*jLxd;IeGCp) zUVh9kkg+`_gwTR3WWRNA(=;cBz7Hq^X2Flae-ZwKk8v#UHO)WRM9U}I{kyf{lJ9Gi zc7|D2`Ml9(JwyG%y`es4`NLd=BE3{x7_obZ&XR!Zy&S$ZCw;->VfZsp23X)H;5*^p z55K`%Ul=e2;<0dnY|5z=6*D%L=)&2ihU{+9GlWNK!&e83_%BC%1qsX1A@{%D<801C z3|Kbv3G_Wi3?79);spkA3jP}S)C!I%${g-^p9r8OzzooU#sJrq;R^W+p1J@l;|eG( zl!0$a1tx@vskf*iqtAW*Qbms1cU@vY9=#xrXFtFn^*{7`h5yv$4B~(Ak9TPAC_wW{ zxO~(-r+p^2z?_MPk8$feizQr-o9_zT<9W{4A+zT(1mupfolKQJ)LO( zL>Vw0{lu1K&yEiD(fwm};kq8$KT!sJ311Aq z9RAecn$ zp_pIGt2>2fU!n|Pe}$NXzYe|~zRz0F!n>w`=&T{|=sPKk$!urW;(asp?BdQ$XNu5# zcSp=Ct}U|MQZcE6u5(1l)k9M5A#?jP-}?papYY4!Pl5k6{2$>*)x`{#rc>K6jWN=0 z7I-I-aou8_zil^jLY}fRq~yihj!?zgLke|*zsQqcAs*Ib>z(Vb7P`F?;`50v)IU)M zSmFN>e%|jG#4T%4{2a(Sx980E*OO-phQb8upC|*8@b8EJ2ly|;uc=_>B@BMk&UJ0gqu9HSHZk~g zIOfgwD;Qw~Gs35{&p%L${eZFu9R9C^bn8&lWZ*xGGT_dAxbF!5TkyBQ&rVy0|DWzi z$%^gY2NW@bPTl5sW}df=T_%gN1%`6Fl1n%wNurKjQWOwnUMw9v|K9D;v#Qy@t=UNi z6cc++qyC99U;+GR;ID?CuSffD%;MbDX6~rZG~pjooOTm)UWTrs*oJ%k^y9COU@1(L zG3JoyM&a2|0@JAK`b=eZ<~c(z-+kT- zz<(1y=StLp;Zs{EYMpAOkTP8AA)5a#yovbEN7hE_G(FAGqy|SJQk?WwQYTu?3*NZ5 zPNf{Y{=FssxvQPCXl3a?sW^j&kq51@s*aR;ojXQtH;}@d*$zmidUk*TdA%dtGkE?Y%7C}v{~LZ2 z{JeEoe<4rE^x%GUN$Qo`v}RW_!Q@iH8e>M8Ni*8#cha`rIp7oZm{z=qr8~#n{r95( zd=LK)lmYedKZegAi}o-0)jz&TN>lo*_kKlmc|aT z$S7n`RmsM)5xx}ucKGb#YrV|&j{7yy!l=`1 z7mzDWRz!Sn{dLNlX6GEGqQ>or%j$(;^PbM1ei=09fzJ8Hlyn~MIm9zi_T&5m{u1~p z`1Fy^uKmAHJECpw4E=M(b6uI1dr#~PCdqKZUga=09E&8j$F~LY>sgWEl|f2p%20~_ z#cLgk8xZ&16JWBxpc}gbWxzD}_3*v$A2kdkT;o~N?1=|K$bMoG_NpmULu2)!?q|Uc z_sqy%^VXpnW{UlIo5(ORpd`j@3}1ZzH$+75E;(Tsy3wNym=E6%pSX%aIN%Gojf8;T zurb0(9(e01_ta*mY{Hz3x@GP3lNq-$g9r#3r7HM%P{?f-_9Jaz8+4fQMZ zJ&GDU#vNw;+Jn)wTPt5$s0s4u< zf8a|zExK`@#SMQ9&bN1ZUvCYQI~5=HMZ_r>z5Pzy=U)bV(?z@RlBsJ^1~9%s|Bn~Z z{~G={BkJO{d=}k)D4C?OLwC>F|9!S_>s+wlKjraD>+V_{tW;g&;9H)2$sIjW&t~$A z)fc34zs&ii-earn#d|Au~4nLrL(5kqbx0N<`Plma#cJ;Gf#*$N#)U@u0ITb zhZ>Pw!XmUN1Jv-B!2b^Z)$4KpjecsVu2X1iA)Zrk)AQU@8s1fBoatoE8he;1C}r~g z%=KxlD_lhNJL#fSLeShI@O00=cgH@9wGM^mR zZfGOjO{_V3bpx?z`Fc`dv==gpWrYgD7PBhtGa~be2EFgr7x1Krl}wrHj-1(^Kbf=b zvlH!uPofMMe*o=2@E?W$9(>8v<4ZfMZ)tCKmqfN~4~RD=6#8O&zO2;kYU2=lJ8w!G zpgoLSa%+tBEM&3(=!>+@K|Y54zwzX|^P@SX5ykW8wjKxncqTBlEO z#-x>UeX^0$)>g65Z}}ooRVd$^*_yu2wNRJh3O3UEksmuc2OnqqV*DI5C*u_si`b1a zU?=?T@SETd`vmQ8WXpd)-a4$X&{f2@&7Ju_=FGDvofP%Gm})Dn-To1S6VIr< z{D*#AQ{OVM{iWZ?`2pO00HmZB~12@A)s*+ub{Rn$8wR=NqtO zm*Yul&!7y*KZxhrCZTNFcK`QPphG)m%#f6;x|QB#!^?USd!w z)0=(n=Z!oT@e0a-58+=2|1B~4*Pv1g zUfRcPvy_zY;V)t(^|AJx^{+S=8kpnmJq+nvn)<32mG zo6jOfqYRKA!t2?TNDGL=BR>f0Hzd|)y-PB4StM$I_LwD5A zd|r}wf^p_Xs`>^rQRU9RC;jV1;D@7F#1HTvhp&L&0>2BsFN`YQ$GE^byisFdxZ5(; zZ`vK5bP>I~oo`YKl=X#azteugSl6K>l{~YQWb3~;*Z=jLxtFnsEhqz4!G9P&e?0m? zZ^Zt$p4joEc!gY}HoWT;RN9@2_QKkzLA34;n_lU4Jbi{E6IkuWr464_`Lu?S_rKKQS~zYqSiSzq50_lA^qQz#;r=191U`T`IH9=s7?jxoE{r|L9vPudvZ=NxA* zegPI-!6IBJ1FGP^4}ZJ>_h6Y23khW=W%T_gY2)R`X#0FFuVHNEr^L7*#Yj_Byt+v% zrbPAJ?|f7N5iNSjHjO!1bn$Bcl=u9OMO32~{k{ zuD+5*Jc%;ks_)SM4ZZ{ZJou+7@Su+aSDvbHJEX5Ll%y+RFcoe$XBH zapJx*+$PQN(~PgVwSiRJJ#fz1eSL71Y`_%VUq;{;q71kb{+IAi!rua4ryvND#bwnW zkbO^2iQrNgH^9wnqX^9~MXH3YXQLJnXl~lNF=(Yo^pItwz2*UPzsM2SSQc>xz6yQ> z{*@CML>j(BO$z=*aXX8a`7-sk!`q5^irX%AI!nJVauz7Z*?6@cPf1OYdgGZoeksMM z#KpR1G=%^5VcAtIVh_roL-0G{-v@v4CiH(*Qh|77=aHznNbrKhRizyEjEI2Q3S%7FYM=<@*oJ@_xdcO=)+ zu7=Dym!1fC4;OBnI*mHO|8E3S0*VwixKmd+!pLCwinOu)RB!G4Vz|# zY$@7*jV=7=_CnhRX-E+ou)7Z!$z6^?=`{S?PzLOPKN9|MA)dhpKjPKncrLQ|GJ3h< zZTckLbnpfvR>fRZ6KqQ&WV~gWbvI?zFVH~jeU*lxnsS*G|UpGt;H?p0OFolHtHV^}96a2VZ>-q}#9 z>pA_r;1bxPZx82GMy_Au5hf9lU3rLSZRyBCu7c)L*JnEk)173tL`G1_<4L}q1{|E4M zGo51&(_dxw;2frNBSv6~1DRdD>ovK-l~s5Finds|GiY#(Ke(8T#p%hiP?~!`UdMT& z2BZ9m7+`=O3!fcABOcJ=`B##Zl5*Z$a@@vnyz+&7c{4{<`o2l3R*`6lY{H4Cgir~% z*!7a?aKq zJw^pv%gyF>`ixzXfR=dV_y+DznT?9;(vVqHS_(@;Ik;W7cNXKECf(DKj>@ZMo*&p}%#>_6%VV z74Rp*pAP?_p)}$U{Jb<#kk0L4SyTPF8mEyioiaug=f^8}xfOET<|}C^f|52C!-g6| zl-_A{!ZuLanrpkE_5r795*D>FxnU`nfoo0%u@L^p@Lz%dgbuNYA?53KldS9XR5Y#k zp|L?KO=+>QYNB;2neL<@E0?QtN{22VXbC=^oNr-Q4-JyFQ}1)+#SqkgA_km-|0(>n z@Lz^M*7RP1U*~JeWv2wK>&E{yB|4JH713s=Xg<$YWL1ZO$Jf~TzJlBqF zyVm&6n+l!wcC!RV9vO=ACt^TI8Op!#e}lgSz92h;eC&Phz+^q)5mIT4g~4G;g?w>n zG9ji_rTDdab*{T1^_apNT38uMED~Lo#j26r`Sw7&J)-@j=CQxwKZzJH8U7mh1E0b( z*n#cOnJV{$gyv4p^d`rW8d|lNFp5IQir!RYQAz$RGBWmdq=F%<5L<0ZjV~#9C%?x^ zO423KKGE8K^x#t{f5K0LzY+es@O$h`)3HJrEsEdZsuA3)b{0C>Co^P*PzPU(?0)Ut6>5;kSmP?28z{ zy^Lp`;r{~vYxoQM1QkTHdMvsvGtt$Kd_}p*#YvS$Mv>W7UfLfi8vE_@CDU@s^?F>O zkjqFOQ_N`UhoTMBRlI96xp9!s!?h=3z*6`&_&4Ae!RK33=`)_L9ehFfZe$FbKqG{d zhxObNN4l_7eW@~9b|lmgTln)yx7}y2GZa(HXO-rdJLcV5A5q_VQgezIekfwVe)uQg zi-%#;>d_ZLj>%~_cY`zbLfy=K_gArO?r|(b;Rw|I!M_UsGW;d*r@|jzx;@#LBpAb2oej+i77lWGO1*j+M|zoY zs`~RDtfZ=Hw|19yf#XXa<2lt*YS=RprUBXQY+kL_TS0ddx*piZXAnh*L7Z~bxqN~8 zclhhz=kja}DOtX7o>s(FJ-tco44WA-oGUBeRVXjzI}^zrq~7%O9bT$eQB%RC$2y1a zdRf`E&^cAoCTX64L2N?|co+WT@N41!0>7%p9pYjJ?y{05ZKdUDo2EL0wCdJ5YU-Ci zZo5(JDEa)tA${sg$^B_6zcx%m(i)$|Ym;;1pv2lSC2&Bs`NW1Yh(yGIt?)zPPaTf> zKln+rg$k#o#Oc=_u$JB|(S+FsU5@lJjiolebi_!xj-Bg|K5IMhOU{Vf%TD_0o~8z8 zH3jQ>Yjf@`-)*qFgRQ00zE7k4i5PGUeiVEIe69i4pT*|dh8*u~z5kf?re~+keWu~g z&Yg?G@{37kb<)d0&U{hKJ{z}KD`oK6tcg`7c~W6Z&4T2v(>QR?Abbfv12Lch{v`M} z;C~7~O|Ga;GNy3#3JtA<(c_7|v~Xi(?Flk8u0+c^&Jx(F1qBPlGwaOX$aDDetM(I= z>3=JKH7{g#7_NQckFLObm*5ZMp$!szmN&nYDi}8~DJlexy+IPbYiG}(fB5KA`a}J11wG)z328S6-Vl_2pW_hW9gz%nFHxpkE zXAnye0}SxLgr5Qbg)BUOk=rxX>8&)5IUIZ2wqfhHsg?ToA2<1486$Udl>B;1Bb1Wn z=Xd>Bc%xESJ+>-V>0Gk18{(eHPd&pRUP25ghrbqnCHz$QwTG4E+y0zVrE>oCi8eja zoG1|(gLun1!Tr5f(t5-no|jXVP_s-YyR#jx5 zCAIe*f9~QK_%(t-T!SAAKMVc__z&zu|1%mqQz*x|O(dseB46C{V3!%qztJr0wVXaK za@WPw>`=bm>Zm`(B*IF|Yc1A^>2349-{J2g8N@-vptyhW zNmcCS5Q=VNOh{9^>e0%jzP>gP#hMEd_J-yf&HFjsc3P~DMly(Xhyg#qKL&paA8kP4 zV@7*pnXx5TJC$E6j-@6Z_LQBJ7@QA9*KW}W__fQt)WLLPL-eRK!GZtg?#F(2sKbD@ z{rIS78AJkNfE9iz{LkS31HZP~eY0GUjhG{!1`xn|5GhJ_tXKK zVdD3!60$OjFQx5|a7K{wLQj(8x}FiamYR~kUgI1+(zz@}sjQyHs+EK_W!(6;wSd#(QtzJKzW2MdsX_R`s-t3eM8iNb?=*)$bCv&`koHGN(>>AcB@1 z%hjjM5oCl-#*Hys6oFT8rqNw3c{YAqTiaN)OK-elY)-LL)b7y?A|Em6dH6jS%UHFV^{EI(b;KzfmLKanciNa*8b_mUQhQLakF)3Cp65 zsa5}v{zn?97sfD%_YebOuHyYC@KfOP;akrseYppDN`6URPF{pnK29OC1{cm9>#iC> zrcLw*XYfdFWd!eA=~YSEx==o8%42Hu&p(W*V7XZMLQCQe|Y;n`GPAGcpasRYiF8$`jDpz>&MVF*R7AYC2(##Lz9eb|40YUh6@Ofv<%hz8}6E)jTa9eZ>QeIo#PSC0SD%W^y`QMJ}yxlqD!-MOj4b zrBnksxN*)l+1}4!V_7ABEQ6Sb7%(0Fc=$f}O9Q@Egxa4+nGDkXuG6nBsnAqtzVw*N zMA2fwaUMV4{A5i-iU}HIf~Iif|C~h=Z>1{^4amre&i*2 zRm{7Y{tpAS@R^7K2jEYI{~P=>@GEPH99tmR(23QyJY~L~XBsaUmK|Ddd~;v&wVK$7 z*dUQk&sRO3D^qjNize!eX@-Ai8#j5o*?twH?j8PZ_#eUNgrN@jXY_ylxd^W{Hbv#C zjLQB|HoOD6N2L21Oe8j@2Y)Ge2Kf2UV)1Wwk5Kwz4dkx|nw<1R-!2Z3+LF^EjW zpg0HmKZXB3{7Co(rT^?v2yBD>_1D;GY-(PwY?F45FKnUBF)lo1V-cnBj!x;}HEARJ zEu0fOV}w+zOFz(wlypkzlrZ}_Tzex1Y=XZGz7GBz_%-Seo{?s*z8#m8m}b17opUhi zi!S|is38Z zSHdUZN1UXD-&Y@?WVMD*KD1^gp}DcuVhhQ>ZoLuxxF^Jb9>eW+w$_bc$0P*a=FcDSufiX8 z9nXKk{~Z2=1E~KGt&kNK)et!~H)=|Y9LH2Fnr4xkKbu%3)r3VJIu+#ht|RhwX~hCo zVsv4adaz0ssIL8=KdR?Z|A`nh1O6ZIjqtyMpR3roG;5H~xs(hdSS-F-koyBEa{uWX zH&!%-URF4|KoM1;-PqtxOOMRUmZfl4|HxU;4wtl!*_-QHTT@zx7QMhAk`M!S!M_Cm zHheRDUP??%9?cbPA{;I{-aohV>#Q4MUEZt9!2=Yf*4Q+{~!2c!)Zhf{GnV$2>Yff$sL5pf6)8`x7_gwoDy133xPgQ znm)ZgjI%nOU1Z;sBhKZy9x)XybPYJ)`U<9NK%(r~FJ z6BWLC@7BQ02Tg{_vz@KYt~Z2TDWsX1`r5oFYP#+PyLG?oybOV974ZLoKNddyOZ0vB z49bA;;{;do1tHPFxYJQa1ux7}`0}gh46UhX5A(WFvhC`kL3kolR<^4&L>85dZNtx^ zy1D+bcZS=fJjweuCLa8dmK_^g@4AT}Zf?S?-H{@?I_gkQh=&;p%kQ8}BI zQ^dN-w5U85ay@D~6+0OC$@5c}1x1%HDCob$Wj>{>R@au8Vy%Jt@B9APo9B#=L){l* zz+dnM@JB}A9t`}fw4EE0s_5JT%hihQ22%vZ&HFmmSYmszCY{gDxeytviWQdbi;i`v z6PG_ZS2n+#wFOBPLO#!3zduhC zTM&EGpR)3RAhkB7LZ3$0l8@PFgL~7WV#v(in@#DxgH8Pk?|bDjqon!r^(K5j{22Ig z@Jr#(fX~ZuYIGmRY^BGV`z>0#<|I#6tS6ZJ(=`mzsxld_7sghxvV}quS6{U^uSlKj zBb}}NPju7ppsqP2w++mBui)H+7_=1rH24oi;u#qDl*vTWv&=6RWL9%orfkzWy^POr z6p&%w+>}*Q22_2(k1i6Mbor!+_=X^5KOG>yHgvQ8*zR3!`o`JQUd6RHVo)~x58%&( zUjpB0d|J=X6C``~IIi1s4S81;j6!pnCgN!(QKm>`?j_BJJ_I}2KBaVqb%nOUrkZWw zcjMnPdDdifF@P9w75*3SkHM$luV9L$99vp85pE_$ha)wq`Yetqw#<8*bD<~c2(_q4 z?=PeV@4q3oDR4ljNWb3E4(fiD+szg}g+W9i20U4bI#>7)kE9V}4q^K{Xy!7fKv3p0 z>~UHY){WNww_UD0VOW2UdkPDE{gAFmv9QKnRPU#}g}D)gtl$6Z_$OY&zK<9%9ljj? zXYl93uV)l5K&v-nnBG}x4&xUVM4<_yA@=>r*4Pzk;XbbQirjpx+$m$+5{Inv2XTte zRpBb+-#(H~GyDesEd2HGzk$CWeja?^9XjidE77uzH}27OVYe9NRsKa2+@YC!OycQN zPKE~x5P3qc*F7N8CoIXUO!BoUQ(&6C6Vy$j^1rD6L=4J@zYTsZ{9sdK{ZDfib#1q+ z6^Csdb@M{oJ=$K&uPzI6cf9}Aei7Opb8VMx!BhtEC1OAg{4Ds~XK@U`7yVOXUPhFB zp2T&qob~Iu4}bPbeqr3)TUGl|9$m#xSyW>Q((W_uXuQa=;!SK+J)<$-)}mEgrrTlh z>kQ%r!~j411Mmg#hnUe9MFj498@4&tTfF#h8^HJ}abpdC|Kc-LUEM8gh0~=fQxJ!( zsIsPnN6KRx7bP%rw^$bw`n`d=PsD%`H}KvI_;cWY37_=KsHn=wQl1~7QiA^wb$*oH zT|uK8_2tVdvqj3F+Xb=pJp_#5E= z1K&qgYx$N4HN84jEQk~`$Xv14>Zbmtg%E31HGNqpt+{#M*$Y+f2^4-N=stlU4WU*$N#;=mR+QE zLH?V-Af_S)+=5SAg7g0EAtXSeB{3c7MK@{k~8mmp)sctBS1}bd@?!Z&n+>tZhf` zaW1HVUkzUl|8e-a@F&C9D$lM^H9mKbvkR@MlpSbw!);dpZ!DDK4q?;uR`!9E0#Tep{u9b!sdsg{7=q&{KFT zJe<8jS+%o(pCFWyNsfpK-bAWug$}pIRbnAeHF;RG_J=_0VstU|!3?zjL<|Ua z_aL5wKOl-m91d)M6<=r`*4zUrR#ZDe;H>bdJh{;tts{uc?x8FZiw=zcnvb3tX&Q9@ zq-iaF*}HJMOB(q$+J7PjJO}?(`19c3hM$Hju0rmddZ%IoQxk+LhC0e{^v_$j3uMbx z4KW3|k-k;wPMsv-mVK6F@!`=qXrn`}s`5 z#_5+l>d({(m3gK<`CgWBv~Wy;OFpRjl|e=3wNY;Bcfu4yMQS3mh-!{%1hTX?XWO!S zHIH`tRd)t{31ZNC_zU5Ojln%g_~LCGseVKvTfWfjuPLT^ECud3CLvPGoP?UUVPB}T zW^Xp<>KrNWN~DJ@8q75p_4$9*zwdbm?LQHN{(!#<{>Sk5z}Jz27CZt1%EC4=i%qml|zSx z`g~7S{_i%t2JdO3-4#GJI-_Pebj#<23>(~g71ZY7Ji8=j__4Q*Ds*N!-{p9a0d~d zKOoY0GQ6k^JxwuuEK(9;OV-hYu7{3wheY@DCpkLSzjdU#98aE&XAcpBIRD_87x>Rc zqx@$>SyUH|SI~3hy-Br;Z%R%x& zh(g5dLg_v1hTAEW$< z81yRqo=dU+!++ox)W3&H-4S%tB=@o{8z@J4ivuShcMwC-dx4%LFfcc z#`1V3$R<=p=w;Qxku;Z7k;=`@G@@1J9>3YhXH+;R`ofbt^*_=U@9qbP{DeUaMhqx| z{|Nlu@Dt$^5yZk<6vw{u*@fICRDHwkkyCzN{44R=>BUbxv+zv3q~_f_is4nPrE?3; z%H&_3pHpaJKG5tnuOwFP-#-$1BHDk#f3Oy9&f)(9e>;48FBY+)^!H0;!87R+-)PBT z@mNQ&NpRElw&?1f`7`!rP34{IAy-gKMdKQTY>Tp9bA?ub?+}+b+$LWEPw0IuceD;d>GzGPVwZENijDLaP_P=}{n$IA-@ZW}?37;m$J5b=C zN@j#h>BKlT{{UMxS8U@eL{xUZKu+?Fsz{z!^PfH@VX)Ge5~Q7Cw1lVTD2D}o-ogFX zMG0(*zu^}m25o|W3I1UC59Z_fpOKu9u+$gVj+67|1UX$qb=gM8vN`%0tHYGyLS{~t z@wCP-w8|B_Os6ix#PyXPU7gh44^&*-k!F@E!2y!5709FzYs#SyR<` z|GHP~3De!;>1&ctkpe}nhFZ(pVDfD!;ihP|h0qvM@20u*KeD$v(K4#*kG<>U#?-GD zqW%*x=+RrK^MijF{sQ=XUudZ&bXJ~-epV%Sq-1GLyZ%_kr(d4bUP{GGhBNk2D}cx&sTW)xqyDiqETIyq-LmjLNBt*a zKr;L%;Ln7A3I0${4XKSTmGSd4qf@S`atFBxZ=N}bAT2@#lQUdOlZR+Xd6J6Ht=G*Z9g#Ro22>83;4?KeBZ!|QiYCTJnoVBSeuZUZL){eR| zM{tFTwwa2NGFeQ3oKQBSj0hi5TYhzzmd``^7bT^(3vnOAM;77U4`R@u+dYWU@ay15 z!T*h~%~TDMm&l~sR~==`_=9vtx75g0%h!rHcruY-e5lpvJci5sB6U@Y#`*Cr6ZgL2 zZ^vNx-4|&4gBbJ`{IT$3pQ90P!^bOL(^0;W<6q+)NA*huk<#*wssjJs0pktMB9fz6f`zgw0f@GWUO(&g~) z@C|_&1pia`hv3tGMfu-yE=(~&@QPIGcS&v9^`7cncKrve0<*lVeDp}xlO^x`Ok4>W zR2^hHxogr5b8PVAm7VMVx)j?d{=xx}Je&C!WGf|?+l80*+9;DDiI3j*BEp~6wa@u}#u}(EzhV$m5CbaV zC&Pac{+IA0B5$)rPG^!Lyk@D~GuSCE8X;oPq0*`y~mHNQW5_*HLed8jZ~bel}8 zao7?*Ro;)-ah?~J;ocKsK$HjXzk-n7@v1{%_ug#2aNO&Rs^~GBzcFenRylG$TW{;$(hnA!K3I9v@d*B~| z?}pz`9((%qrxFR}&Z~AO<<=Ko2zjlxkl1#oK0Hk)E9Fwrbc;;E3JR6`a&mL36u*zG8hVJPRogxI>xrUi_w0-iqWRCKTb>gSK#?0#Go?x zPWVqek2VnSb$wPbcNU6zpPc`XtoL>=PhS=(h|L=89It+5$;H9qUwbDhQWvRm7wB@_ z!99vsc#CSCS?!sB8$%$lQ`DN34B{=sphxeZ|CeQW_YC|J_**BeixJCyHpKAj=Z4R) zOMIp;f^%L+pBqz>@wfT&>X4S9!1s6mCU!M_>M8~?95Ems{-f{}@c(lRbs-VY{6_cX zdm5q#9$q`3nqyL2tMQ)y+=Rnzuwck>2Xxo!~S5%j2 zTnPi$y{LbHp9cRY_|fnwS8ZB~dtqLM_k&P!TuQ1V$P{;MD9!SiwC_-FVNCC==n(!M zdJnNTXPI!Oy5!BcdVX$~z`rEcz(0lb(JNKUW8`bBCmJbx2hiGKyu)aoltFAk461^E z82*1=!1G7&Q%j231>skm)lygaZxmOH_R!S^eti7(@}7R0lEz0N03SMmUMQ|T@8GlZ zF1s8}SvQ_#Iw)O@Hl2tztw#S#h(Ql}(f%C%B=`dgaR14)HRwP>U$TB@+JX@BdM$6> z@<(n_jztE%5cSr|gu&?8X(qL#K{7*fL-O6qiz}~vDPGy6v^l}qn+~)#DV-K%wha9* zAqFghe-r)+_+#NW&M0v|eoV`tS#{Yu5q-S3@D1$cxA30D=9eNap1I_7!V;a*AK3fx z>6AHjzAL&h&DuQk$Rq~Q3o&2~eBN?g|HD_pM}3!K=OLPfG$logvbmc>a#KH_6J-fv z;?46mo$*&|))312ZgiSIPp?*eE|v50Lp`1S?owJ8tJfOTeZ$`dUk?8;{7djl)%&b| zL+n*au4KTYr+tI1VFgq^$K#OaS=Yy~dgq8zY%#ZjY@uvY#g0l7CF{SK*$ipugbnfKPi7eNY_7voHz8G3V=t6T@N)Ii3spYPKi!<>wqprWXh7%Nan` z9F20sX62}+R7T>CfLF;@j>#VB?2vVK(<7*uIh(QDDasM0sDERNe=MzpTmzQtp zt+y7uKYUnC(qY}W-oY=gTA=WZaSU_{qYp7RlKUNT>O&Q^`HG<)8duX?|9L%nlx;t{fR#~3Ao5~l5H z*f@^pP;6O5Zla34hDen4YRUS4`F?2~?tLK!Y=(akz8U`MfUj{$!+GHbhVo@we_iQ> z$2N?pt_f#aqH~4{cu9ij*fBN+{n{M4B&CdEoOq1+qoBO0{;ho!ZfGiWwqK&wy|0cM zn9LyT@Xx__!Kc53{=W(X?;la7R2ZqSQH7zW*b3SKLi_qCC7a6cs|=Cn4?H(+gXx#g zV;Fu@wW;Kw>`lXPK09krd*$v}>kra86qwk!q*vkZMGP9@L(G9c4*pp9Dcf%Ja%@aX z<iq=+(QZ|bEkmpT-{JQ$R z8`Hb_^JWUl9*6M7rpWo?}ri2${enfQBf)wu6fQDsh3gwp5E`@yD;}C zL$jQ9d43pna>Ud#{K=D)>tH2jC~e->S_SCf|;eTEgO6 z86SQ%@ASEkLMvY4eDy?v|KdBh@bam@pIdom)|3wiSrX#kjkx&q-!DD+NH^Xe!up+_yY}$+yI~E;qUlV#M|R`rN<`@@7}StPLg1-%_f+e#vpiz0k_}}T#4szC*c`j_{Q4V zqVnuYhRnQaYM%5PV}|07;hZmiSyA)x)}NjvW8}|Gw5Cyom&A`a#e!2b)xo4~Gh$ki z`yU#!5jOlFKc2sU|2q88Vzh-Q(uQsm`xwVvG)CD(Ca?4oUsEJgjj&~%94swT*<^B$ zz*_r{xcb8K+EN#_Kxe%A|G567s6OAI?g=qy0{pMxe+&Nu_@z4MeCfjQN`C69(bcKa ztk`o!`@JRJ4K6a}?3DNiq|=HfKUeCbgfUe@>wozBY!kAD7w@&!l5Qsc1^+w5pf&Kn zfqx2qCj2q~_ztIxugc`eb%lTYMXSpbxNTKYg3Hvp@W=LQh_X}6Fk7f-&V+_l>F$+1 z=4ZQ$M~~@-xSQPh_;6F2O}O`r7-WU7h2J|4*PrmEZi~gTAV=gau9>|jdS{xF<`6M# zm8m+JBUa5;Z=ED%8u@C5A}vasZ{BQ30(hqQ*)9DPQgZ%lIwY}ii}XKU{4gSp+()PUzImnwVUjvmZd)ZK z?9|GdcGv$q+b>MFV-vo`^KbA)6n=B~a`>OZx6R!lIzBwq8l8cc@Nma&nElJU!nJf= z8g;UCevn0Bs&ewYj+^ws$u_MPTyZ@OK~v9fV&E|B;vR4lwv5#BT3$J~z>(OS`2vOEl~KdW|pFG{3RhS5v_{2>vIggreHvLv@h5rpE$bi1w)3a$nYU#smg~Ux3}QZFP!;@o_#eOz zDM9(?8PSMWMpvW}HS*|UQ-rtfF}K-ps#=#MO&Ua|d8{vuxf5mmr6yt{pLE@-%X0Y{ ztgeI>soU?hThRUkG3YS@egCh*yMN%%gCCnxUE&H=&Uv$DzQ!4n_C$K3o&3S{Kw(D;2(r94P0Il z3|h~?*Btg%*%wdr8_3rS()DP9W0LcuP52IcQuIslA_6`ScZSA)cB zVdBqRI~~6lFGt5Iy7^ygw%zUUI2a^%=V}}}md+qnAO>-I;MqI)7vT>n?Lo|3ISaWi zo*BqLe$T9g_<#CG-^@6nQ^d!Ae_Q)QSgyBM!q3;=cs=3t5Ajd#_^wy^s$>0;^LhMp zw>{oE$K1PqI z=WWWk>WoPLS^N2SlU=JGaxe$EWa~`&*M=_-nb$t&`y2akJIbGk0b}96A;J5%Uq$^Z z{EKvB+0mPo-xidy=vRDEYm_=hSbE^5%dlM1DP>SOJGgI3!j(eqO(TD=>cnWmAGf?E zsCO+}yG$1Si1H`=kKiZ6p94P~{wY`5w;ucA^!@_{ht3_0lYVsC)@N=|dc3EK^PH(a^U|6e>ePM_<2ksYY_PunMlUU znRpa9jv0BVQ@;>>Fah zZ1~mi)8S8m&&yf!!&djI-fr!mp7oijh7;y;^$IiN73oc#`DC)0@6s2gkq&mXBO=PL z9+ESeI$Hm5Tc>%rm7CJVR3uH>h4LqS8T>dYjVORW4}Mldu)wRKRh?Q<71N+d_{>xz z^B*hDGR1vvOU<}GDX)@kQ_DP4X4RroN*3o%&!g_xjrK;O-5%F|OEfKlr0J{a?;sU} z$U_X;5C0wb{ifg?1V7nex0=3WS7havFJ#e`PCAh_nqzpHDpl@fIt!&G`N6@jhCl79 z47S#-{%7!?`wh<@Xp%Y7gR`gpvg;`pTc)ai5pSK<=j<5Z;WK0B70IruWfOFi$#ZcQ zmC#UM_j_HNmN#v)Z#!&lJJM1UpxBN67Z8IM!rubl0)ILDz`TQN8@n_s?RfM`s5?GN zJWs9X$M~tgd8(&($;Tv%v%4w(G<5$1U{{&>6WSlcSHjPM?}7g-eCA(lQb$P@zFG@| zc?Hjzqz(|z&#UYk@-8Dn$RA3j=J(tgn(opzz~7D-R1d!p{`>IP!zX#BVJO|0$hD*@Ie9h5nZ)NYL-8oU z2$Hrl@ERHp8XQQ8Kr<-m7l$WZuB|xI?&s}1V(;=uDB6SmzYv37?TKqI_=n-|hF=^K zZ(n(9iDXv%>9j%|1~QYY7qKe%Ti(nWJBK<1&Ln0iK_m|WANVkdhSS87E`iPq(k^A2 z2KOEjgZ99`1pmSR;`$$cLmhQ7{?_R;HdP@(>|ZJ2Nw3<3iM-51HCjoMkY-!`3wa@5 zIg<0J>^K?cA_^<@PagLkhT@nRM;x2`_9GP*D+ zTvh&0b>6S9)DcUETL(`)q-1h7l^GuhLH7^hNiU}j&2P#Y`~Cm$IR}3+V$fdrU&6l# zeQJnfT-VjSt*!ZoBWNwyaM~Tl`<&@@AN0%qlMx~*HtP+CUxJ&eGl64m; zY>Yp5H*8nS(0)Tm0;5_To_|9Os)D~6e!r=B1{Xf7Af|`BY%bemd@V0DIrUj$W7Ye@ z4DQ;rTJrtk!kTc?VO3#N(NSA2^XtTr-8D&@$*uBc(%N{@iNEbWUB?2+S9?+Sh#0`{ zMI+Sk--6Hl1La?D>`7j#_FXSmWo_E&l6lk)^Nu-LqIKg@@x9L=kI{@ZXBExS)u!Jl zn@iQBMSiD`y;Dkag0*GBL_O|3!(Ryh0Q}wXN5Pj1Rx^C{w2F$@S*}crh+Hl7g-B1H zbW0tnSz208Qyw`W=Iu`ji^rnnWcM33e@k^{7wtb<6miQyr|&@qwEsX1+7JH-{HyRk zhkvI;ew}_{^9y0yu8w=UZxCtQxZ#R5rpQNAY9`b!iJ!UT>G{jK`s{UvVtEdo?I{z5 z|9q(_^OijuW9@(MPIe&SI{cN0LAT+bfiHNSMrh#A($F(h8>Sv{3HAu61l07+T9U9N zk9r_!@`jn>mG;B^N15Yw`ONj@qP@SHOY&aMsr6M*l)c%w54d^GLs^Kuh(Y1K(eEDo z+3>HxKlT1IqXr1KiiW=;^*?zoEY!po2z8~}>$g+KM9Z8dg*=k1=bo*X5S&3gC5vzL zGOF%<{oAr=&2GzA>OQ=G3o+;|_#rYH@g02OX>5O9u4b#MUZK<}Npp_Ak8##KL zd)ly~u<3-)CJZZ+Z!bEh%~Ke~Wv@vachQzS@B7=1_g`n@+86$2_>u6h!JiGksrRk$ z;BcaPiH;sN`_*$*)#}2`h$&SQ+#l0fbM}0oCN+JspS>E~hY+$u?$*Ca8W*7H zfNQfibh%i99K3%EG3WyP=irCGfj9u4=j<8&g=A#|m0)+re|TCy_#=gP4lP|zZu4rZ zoF@Le-!L3!<-e2iU}B9lg$NJg2|4$yXzEg@?Dg)&+LH~wwu zbc`2j;{|V8&);t1eIK<$vu0PXz~n$zWdu45Z(IM;akbkA9;jcUi$G<)MMX8M4A*i)!}e+lgWLG_HpA`8-;$;YclVFJM)duP81yUr8u-)T?}HzfHqwz- zW~e8YS5_E`B-HxU!Q~aw`Zy2ADHjhsXcnzYsa6}9)jSRSI9prwgeD#$DffcPKDmZ{GRa!7X!S9byn85rZCKqTfmQN8wL`@4M_y zN>yZ64ol6WtRi(RuOx)IRpR0Ds|Fs1eR+wO;E#n&yS-1eG@(S;kTA82|1MwgozwIVG` zXKxv3{O081+7B`45BQ1jSHpksEZRcx!fLikgR}W5M+c>rReFM}4^gvyR1OZSh$n+w z@>6zxMDg|rx|OGYh4R<3UyoL|k8y33ZkDKV4mbSyh(W!BaNPwz7ycXYYY%R?u>ATw zaZyYalU2o_3mu-qLbONrgiWR@Ope&fDjz8})LakJ8KQH7qa7;2`}d50k~YiJcF=Yh zeXk-0jf4L^{9EvUf=}0Esn`T3ZyA~Q-)~xKq5|J&=v{fi9L_%9Kubw1C>JQF^=Hx6 z=uKM`iEZ<}-{FlG2GJKWXc7FK@M9BD4+TF^wchyAkn?$}_Z+-Bt?`|(1*1M)^P_x^ zVt(4eAbt;}{`;+;Jhs;{AQ=xS6taTv*Tj5*Gmtef|GQQ^`v5-^ei{5_@caJNgP0>F za*2uP4*{3BtntL~0`drv9A@jAQz>=!9Wt^PIcFm`OPI`9q*=XIH9onpba~&d@Bajl z#!uIKL70s}Xc2=>!M_9l8vHQ$+VW7+IFY&VibM0kFtDH0l-@Bs+1wEUKlb=Qk{7?b-kqToUXIs1XC@8*OrLO=Lo+VyHPqQ< z{d0#Uuyz=yw&$V#9Wm%{_~YPjfWHHNv1$(YokP>E&iz>{*uLQig=J~G)@CmgOYTq+qPZROzIXjg)7*3O(f20&kiIlxI{eG<^Wd-l(thNY z{jG$VGe@(ZN}jLers_zM?bgKvUnYONi`&DiPdK^q`jE_C14liwY{srNFZ`4@J+K4Z zJ+U?y2JKCZwdt$*>c3?K-_b`<_k(O@88%Hj|e-kli8~iHxzrcSH{FXrzx zkux*KO3GB%PfQ=gG>uu5xb!RMAm`T^mv_z`;gECBXBfAh;v+)|{@)sjTl+B;b;Ax z>}A#kIah*vXm0h;KXi4~-WILpyJDsPX{n6<>nzVwWlyi&T9#JCJI+v-t1pX!Q^#YXr z5Q83MvK@#};;P-kP*{D~N}7yb$OZ@~||i!kFO zhu$R9CK?8&U){p~A@<_MUw6rcsZPDY5hqIKpSGO;dW?zhCNVV`_-2lWq4 zQqvN&9d1hL>hA}|IQPQ0!@mt*1^);5JXg>1y=0iuN%o+WCV?-_;H;>~TticnWL)6R zzx-+A5j>yu!g)=-yuRo6-)G_w?JEC&OB;OxZQl@s=)t)5TZ?OtnYadkPd;nRZrZP` zPm*u0)BGBDNz1jA(QI37GA*rO{Be)04@qKWfrzOuhJ9 zNjAFT5tJl$mH)q`orOOhF=z(-Somk*2VX$@>-{%rt8xpmxxaPE6LG>dU7xIzWj-KO zuN}a>7NF_7NgX=)} z*-2@?F00u_m7ZT3@mgla4-1z0Gu4wk=ZD=sclz|qmGQUgPtQD^q}S_$$}*BOQ^`T~ zCmP%TNt&{iG-uy5*7mR8-gb=o@+9g%;qQXK1pZ$5GvG^T7OG;?nt`S6B_oE_c?N3- zI)V}tW=}cj4^OR}@ae}T8J1*5n%KyCbonO{JQ1x=c~)7QjN8<(v`OtE0zUs6gU}-e zS>bEpyWwwvAJ>z9Dlfao!Idv(q%P02q-VZJ5UWTO^!WN4DcCbjO6;Agz>(1UX(Kfc zT019oNO|}a>OT>KJn)ahA2AEh|G{s~warl2xi?ksqdV9jQB~=b;%J4H)T_|LqH`uB_Y{VUfU^sYPm`|T5`d{Z9J z*e`ndm;CqGikLDNRa266GTHO}R}LvTh1As2H(uA087WL(OSY{SqLP-RrtdEHiuHfs z-FNU4;8(&w1^+SliQCZyF8^AEe2PWuZ+Zkau=0(Y0DqWre^sAjtK8b^>iSxxb*`!w z{ZQH4Xm`V-$(mn_z!*feP4y2t*Tl7yShR_iC+12Re<=Uf>7B?65>DHi*>K^ znNB>WsdTx^l9CHaNkQ`}{ZC)p&oYQR&3;HS+J3>m1wVMG!&61CdFAx!#qoi5XYp@N z67OP5ZQ=}W)iK>31OJYk$Kk7)T9QYG%cN31m)m&#*F}iC=km<|i$NSm3=GHmPlf*h zeEy|C|IEt7zsWh5FNtOdo;&bSK0WoME{FU%E@Tb6!7-OoItDFWytXibXYw(IAWJ*nv(0Y*DAljXq z)}J`YxQdQ(=3~nw(8Jlj2nTaq_sZQV_Kv0C2hXGK88PTE{I&2IvvCa$zc!CL$)Bq^ z=S*ElXZ97d@w#6dD^Mri_z7dLu@Njz^BBH-gmg{ZUFE(9+*BF-(TG8H@OQ$W0)HF) zkkYwf1d*m=WStFWRkMqGu!zSSx#oHY3`;fMB0)VP@kBMDG!!9BwmLj@GjEbcD+*A?0-1`fI>XkG^ z7MksED3Zzf2R#u&w?g2gC97UvD%A&9^};=&ZiwdOuD8zQOXzRMHj@3~PVg2F!+=t_TDvfzE$$vll zU#CTU!j8H>#2^{`0{EN{5dYy9$&@}eM@nRihpYIbgYo_iGQG^Hs?$fjZ40(aSf1L2 zr|ZlVld55buck?h3Hj(toicBq(0W>IlYRsK1jHaC{0s0C;Qs_)U%Ygzc#VijNDB-e z);>kd2!G+&Y^(nl{XR+7=O!hCfxa14Jf+H+m8^93mzv1*9~!f5Xslao73{5pT@B@y zq5O#$MEnPBkKu2C?|}cilA|P@a#gxhA*MMCYl0sU$4SJWW_qS%8_CST-Wd2e6=sw7 ze8n>Uws4_!MOXR%TiS-pIQPIG2mcQI%kUpA>p|=!wN~>SsfLufmA3`D$;HwsCcdJm zo*)mn_DdeCsB!Gcu;$#m{Aa&6ZVgPHRgQBnV&H7}jP-c;>W63t2)}9l@VDYXHK{DT zX4OsAIm?#It9_LDWxN`g)Z#_Jq()BD$Wihjcgb*8zBkwP)UXN$u^KTb3H|{1dGMFQ zk0Z~a$cO%rr813D{zbNhQyte&npkKVMe59_4j7`1#h1h6VZ*|#mb$357E5j}*%<%3 zR_>7s|G$Vq8Sn?ekNXJq@bH=923gjK+oJOA{kNHWsg71i%LkX$x%rXK+;C$~iJ(YH zW^;%Tb*x!GkX@ca^1Y(_DsXjNlF}>ae-<(5JbWH}5`I2>%JrCl7yPdN>mWsiXabo> zBR%x`Qi9r%bkV2rZ}}%3ZchF{~fkd9>EL06RyH zVyb|i=#6|?Cf`Ly=}A)xkH-@w-C1%~Hn(i>J($junt!da*Un4Lvr-*nZG@^p{ZltM1$&=l5h8WpCvQWd7=^wXdbB74BJD%HH zQETg9>rmsSVLQ=&Up8DMM`?1c5R2dr~T042jaZs z-fHW)PZ-w8d9QR-9)AS>A9`wGwx?giChx_I?VTqfaMy?J`F0+Ky zb46TKf_zbfu9##sWqM(b4fVVo3fUbNqjTX@vcie}zYqhzg8x1IOYkG%e{9MXS5$1Q z@|H_E^(CC2j-bFxMkg(OGL{g?Woubt!^c7F-3l2OPf1TPkoBo&+q{3Nb@duILx-hk zw`nH3aQ_`Ks1Uve{;*GQ4<5eaiz>b0>rJDxIR2Z3+JBTi46KsXy84uzm-)_mrIkLF zql*jIY>HLq8Y-z*@_F_4*nDfdobQe_FHP%0wGC8*E7A83Vo=Z{c?Jkx&Ecz$z=9VC33lhvY0NJ&FTMg|LyMb zv>T{~KMFDEdHBcS?}L8|zCZ4n#M`5;m6z?x)TxRJ?FP}bLn$1`pls9D$VB(h9S&WR z&1#I9zR$-N^ZNUk>m)M*zrCbg=3R~0+b8~V1LaS|pylu{!uP=MSAqMl>a+?$d99SM zD&hH$8aNAN`MXve=Gbb3E0V6E^+odkadtoONtOE_z>i=GY=T#-YuX=VW(X5-E1hf& zuXb-<^=7v+yWL8!{j*tS|4YpwD@B;hw9>Q;!9VPPfXtL&0&QJgY;Io5o7c=CGeelL zSn6cR`F+@5HaD~1c_}>S9QM2q=g;>%JkN8^xoup~IC5d=Fg?>r23(ESqA9)hz2B^i za3`1KgD}dU@J;Y9!v9kN`d`BLYZ7U7h5sE`6OFs8<3$>Q+GuD|TX>7JN4`$0%3q!8JVh>SKy1;)$TNAPn0>7(+f{VMho=~w5TIwctv zuO7U=p#2>&=neP}!hZ(-{bz9fv()H#q4wl=Z_O)d^wveGoVu*EsVMu+_C~73X;$K4 ze^ZE3S)!EBViq_If;FsLllOlqyjtiz1*;_`4sMB}?;Csz{O93shQAJeIL(y*zEfJn z)wwe*F^(6HU3%FlQInUl2uq2X3^5G?Yb0E096NtdjoZ*tUmfIfuB*dk&&7!pG&2Yi zG4K@pci^9bpL`bS-Bq>fw*=nB|K3P_Zm}mI%Cll>ZNw`nc4iJ0J->6 z@l8v0zMOLn3wse5t-pFw$CS=F-^0HdG3X=sdiZlf>o(d&S0o4V^F+Wz5x1K$Rp^%Abbf{));_C!z+S19;~^JYhx zK{t?h)>;}Ix!On?bV7l_oUHv*J@p?_oL&B_Lyd)V|$QmR7FMQ8{}n8b+oT_)0-nsTXjnN zZ^{AI|3Ps+xjgr`;M#Y@pg|+i*9E?0G46p3-(Arn3cB;^3Mgr5kW%Mms*1_hr?kF} zIT4kMF;b@6*|_=Sd0FXb#W%XQMQMf^{wIIB`uly4Np;D|g~^wmLw(!mO_x#jMhv{8JG^qRZ+&VV@@{Dnf*@JB}- z5B$3dRgWnd_bs%D?a*# zEHCpuv?gJf2OQ+jZ#@xmPgpC z?+LyKKIi8FL{Q`Zmdxcg*N1tRgpmsBo1+=D=u{bZM#at(%@Lzk8ZNQyD>jF8C3~v$ zMHcm`oK3O5_Oev5)tx%lmUfT5g8FyFAU^#2;j@?E9vJW~x)YB+e&4Yt51dQXKJ8v) zVU?YagmxH8Ny~b)wK`cXX`=>LHj=!9Pc|04YK z0P4R?l+t301?mK!D(Y#~l@v}sa;9eK>t zBkHwNt*K>=RNdV%@-)FDK12*`fxiy^)K}2|2R@l)X*6f^42iO=mPWa8+#31vog_nB z6R>CwJ**9f)fT-pAzS7*s|-bSGQ(hCy_=nyf1l~LGk(uG*#nrw(}+P6Z$awnOHRU1XWP;Mi8jIu=G%Ggvf$l}TjinG~TV$2;|LOZRaRHyU& zq$SE2CM=V)ugbi0LLVEZbJln8X^259;gj&yui`qyq%XI6m4=hyoBn-S8l~>qW%fli zvQKPVw`=T?w@&=&NTV&-Y?*&K;BXX+3fW}Eq8cMBnP>MAR@h14-JO!|ncP8V5=Y^G z34b5_dib<+0|>n+pOjABA`or8*_NKMaA)QQWu!cNLH_5r3!T-$=~Q*;L96R&eWt7S za!yo?|>Yv~ryAoxUT@E_K_(E~6aidFE zCcNE8TWPOA14z?Xi<||xBEi#9H9;ghOA_>JiK+8a1NC2SU=m9ZgKoYJ?GEr)!hZ*T z=O7J@GrujXhxU6$HHF^e?EMdK{MMDEXXpk zYHK*?f=#5hHL zkA0HPBpir=ufU%GKlu#a*WgDiR&OLwUvd1$)!a*psCuuJ6mSWXnnwSXa&n9 zGoLosyDE3`9id_&F^rLV_Uq5+nC;Zn9%b<1|P!@VzP4-5#ketq|bmkXO2!h^f5%jqi)7_O}Dk@t0uoPvJ|el{2V z&fwqk7S2KN4NLP>kt+W2h%x--`JgI4th^$n^o==od!r+m;d`K@#i2RKHf=S_f|c0` zp&=TX;JHq+$H&Y=nZzN)z<_>RTyYj{EggAGbx@IO>#K_=&qYF1? zg|A#nWG|R$5A$@gEv>seY-0_tRhTtAe9cYY&&(BnU=kY<154n40slYn)6S#)aauFC zsWM{Rznnn{ORH-wGpQzLT_TO0;c+D>QOw;MXlMu~EQ0x$$SWoB-Tv>!ww)*YVG29G zboT+-aTq=@46z?E=pg(`_&2_d-#_q+gO)MNoWZZ7H>gjldUI~<3r8*yU&G%DBHO9he)u}7iojTGh-F|XxpLpAFYQy46W5j?1>VN%Q+OAutEScxH@7LCMn>M6&<;NjPt{s%ovGql++SLeBR4eI$NlN&hs+}vvq zYi~mN6ERQ=pSBj~pm)&!8vd##Tg}}vGZ6@FpY93?gr5cdBFds4=XhHm<1Cq$b7N`Z zx%aTW(UMkotFiDX^;n|t-M`QM{@?Sc zANSq!S^XQAul(=A_q)H7QSr$5W1V^S^*ww18cSK01bjAP(7o{Qh97}HB{G0;l4cx` z=!-A0RR&w@Fa2D9Zc?J~ay+0-G^$(kw>qR8oBb~taYcN4pvoyAxV+uHe}APYSh9Zh zgu^44#7X#%!hZq&%}Y@a48MCgB9=}W{O$x^UX?W1;J1HM_RHTl&zA+@j3q|wBH7K3N}I_c#kE-uQ7pWRH$Xzl_uQS#v1jR`53tvy#Uq)-GQ_}h z@QdNEfPY&P`kxxix-V-JzEj1qGkk*Kj0Y?txq+jSs|1$Xh&iu7_OwehZ(Y%@FDrv@ zmZ~D6SM90g|6WRRwC^RGGKxveL<}00f%aec-@<=Gj_npPyt^3SD{Cfn!@urEd9>%~xY> zJ6-+N)4QkC!w1yzUYvi!|eMFNuI zo7v@8w2po3b)?2{TGh~O@8{IlZS|G1+=lWeV&H!G9{8WZ&%?72bCi3m=f>1GyKJG# ztp>SM*0k-2%vpPo(&+@z#N(e+gxnuo;8w61p5{8r5pL9bvU=v<&jFYEA)E+T-p(Xc zh=J$ee*?b}z5>2T{&Rv&as!6Fp)9SCGL|0_%Obivmc%M!mB9=bB`%?AE&fo>r0j3^ z)Ka@i?ZeT%GQ@A3k^ollTW>P{tUXd*CPU!CeF2rH|6h9D=LYN=c%MD-KA~ zeA7!TS(WsnoJ+H0Hrn)zWf>*LqKa7l&oa7$ptu6cOerYd-G{XNC{to!(;C~ALIrw=V@_;g=ADa8JLLf}17t`ca z4k1u-p@wZph z#k%eq>bp|yiM2c?u^ut-fjd$5hyTZSX~cK%4>cw(NX#@jCn9Op@#tZ9rss#IV6<+p zR3grm2$b1ot!qLttC)H@mXDLQoR7OkcV%7JmHN%Z6B#IbBL;o~KMwyX_(Php{(sgu z*e#N{vDN2mvPv5j+9HY6xXLh*yPL)1OQcGR;<47Wv=RK;1ye{}`FsssG~{Zm=l<7g z)wg|IG=@n`Kn(f`K3#)rAK}k|pQSfsJYRuJZq?T6pirtE7HJgGG!dIgQyKLBa$8M9 zc1cUHc#SQ@EBiXPOrgCivHG{`|F2#^DgmEB43dmR+XMU`;lB@m>gdEY^CnF=s4@ze z^89IJZLzDyP<&2Vet@zzQ;nh`8)-ku`e8|=Y3BO8N@cJ@Qj(H=&x0H@+$l3tlXZ78 zi6ih|f=hLB-b}p zS>i>P*Qd_Ky4h(WXN!u7ZCufYFT^7|Wb+UFQJ#bab?`Qx-hHRjXJ8h<{GmZr>5 zkc#4gH1nkwkFc_G1<`@`ku;CDCZmu3ABFv~U5m;dhq5nX&}Z=PgFmAX`yYH?ZAA`I zET>2hEvlA8>3`6=tLBuQ$}(Cu5JQ8RhN90s0ynW*x!WWu&bRXHvfMSD{qK@_U(fv@ z+m@jo{z>@1z@H6&E&MY0&k4#ST%n~p&rUeV*m0gEN5Lj!q&&!Ri(V) z2W`pZlSLl0bp(~$id!M5iZuTvvzvpy#G7WiD=jc5Qg$Rw5{ z2Cjnt9Q@nlh`|>I5Ra9}{~GgGiKmpP?A8~^cnxVLH^hE$D|e*NEfm(7EHbN$C8X!o z@uG?na+NDzOPIQ{{T+#iGg1CT3_1+|P56()Pd*DXuSQxd*t@o|wpx%Mq1gd|#79+>K#GPKDAIUGK#c64w2*<~e zRnlwn0*Qg;&I)+&uYq$=x)rwYvE0 zhNfLbCNV)@MKtCK`j$JVUUf=poAI;+^`D4=Lj|b&gue#11x#ZdON?K#n3v?a)*v2p;b<{msL^Dd;eLw z$tv8FIYZTzcSp>*dJpXS1QP9YX<4ZMgzto31s^v;CT_cg@~^l-$;eQZ-7#D&te4y= zAMYhp;X&pNCciezQ%UCLjvmvrh%!tGw&21i&mQ-nFB9LU=6=2Dqwo(R2DZXK1%DR& zneg*HA<|K82)peIIGjr*#Er+$)yn zc*Xy!$W}F_75mnt(FPHk^!Vp@1=*`c&Ppk6^y~MSk=#tL-pwSQK@5BoehmHz_y^$| z+4ke*Y=dqYmkcWJHI1-cu9-?y73o7OZF+rh)^euSaFXGM8EgAR>-(J3wk>X)$Ry~9LF`QQJA}Uw{^*tg#5zhn zd1>*c=}JW_Yk-Et!;XzaLXqHQC91M5Jd)Vda(ANIc-$3gJ)%*kDOT$8t=EV@?j8$} zx;SUxABF#S_~YT1!JiF3M|npj*%)?E7CCQr_{bWAvx2okXX2^l^hp&N^5|=~Oc~r= zN7bI{fn4WE*(B6`A_jg0KLn~kADySAliJ-S!K*3+>ve@Hu>y?aiW>Q0~N}F0iUjAcZR-#eqUOP zbU;{dxVYrCXv||ahF=zyb^6KoYsa4MPd+@ENlZZuEQ9|D{7LX_@QrP~Oxl_iyIzu4 zd#TPz!Xzsw%BbFz?0BN!M=jF$BuaEi#p+f6(QRBSHAafqj~H|T{`2tPh5s}BhDgOa zNejQs-1_as#An4qcXf_-@osv$)}C(v+#j1E;{*k|Jt9B7LTT8OlR=2KDbfD*`-cng zeegLV+;<*6=Y8A*i5)dm^uVQ6p8A zYbNAIUc{SExs?&~+97nC#V5RI_Ld2B(sKr?A*$|YlNa_Ndyj0$L;E{opdS7T_@BXl z6@He(I?*AQyBm}yiHGjxC|#Bl<7*83*V3D@bK&P)v5DTgrOGIA(HuN0(ZFwE^l1O- z?R1P^RT_W#UerAx1|EgK3VsOw0r+go^4gJf#x{-CXAIlZ8}b=JwKlJ&CNnQ*LA1D>zrEm&>VeOJ%xK%WB~aO+>5Cimt)*npNL5 z{w@4+#J~jnkKile&wHEtH1ce-QxhnvplMq@<*JIZuOrT?sM@~RIDZytHVid|$LmFMiD|42?Xo(f zJZD-U_4jYr_iIa}mU?>5p{7k`5(31aa`<1ue-Qqt)&WFxLs-DVS%uH8aJBDe+{_~K zZ=QV(6)jt$Wo(uk4%Zea{(0>u#FXW59lI)WD z1R7~rSs|g9yrh*XYtzDVwpX;Sinms&39@Tz`q<&F=D+VXY2STJVl!gkM)(czZ&afF zAO0}<0V2~;v*Rp3TeCh~XKV2!jHe}y4>@S+zx}QDmx{?mAYLZHZPC7`heAi_QPo9u z&+<xz-IV=g+CqsN%(Jku|l07tLnZz+1wPWA&+xSa$&i^Fhpaln(Z+7471fX zpK(5`NnfTT%)( ze$_K+jov3V2^W(2t~_C>Gc&u6RpBfp>qh2Fbv6YrvN5-d?zOvhO}{EpNWC}%buWm4 z^WeV%|9|l3!e>NZ)}COcH70bs_8HDPgLS6OJJe3Ew~A6M_h~sSp0z?H$dHq1Tq})y z0EN}eBeAQp@2}A{<%791nZ%8VK}PuR!XK@|Z&3KE)m6hCFR?T_Qj%t&3uun4X1hL( z9@I`PjS2V#N|H5@@&0C%fEikXB&>d;*s>=j+v`rI&tekE82B@MCH&>^zkt8USZp|m z{uNcZT2V%HfSuE7Ayp`G3rJl|KnesXpCerqJ|oL*%2Z3)c1ziHul3Z0`w{+L#6aQQ zxb6!6kMO^PPny}$d!tNkNaE*_N6_JrR6%UJ^8|~;O>k(MTJ_~xX{dHv4*!N=>*Uhh z%|#up{q?E&|5keU-pL6^AApS*_&$6+{IB5O1)sDf zf9;eS#?k3P9myou=tvchl&e%)2}8k8ZU#Qdz$cQo2PNeWylA`qwuR_=x#o76J)234 zK@2K`Z-$?ZK0veJ8~6s+NP(QhhBnl(jbdu{z4?BBG%uq1M&Z(ilr`Bc5x+}e(ktol z5WO|Hhg;ea|GV76>sbY(A4K~n{GZ_4;2(nj5d5XFCjUB?!OY$!V3iK{>f~C_P;U#} zTH!0tGUxBHu^0k}n4eK;54UWyk!fRuRl(~i|9351XCey!YsA1i?x7KO__v`Auo!;a z$`C|zS;vLLR5BxJ;vL9~*PUrC#Z!+MuBsApsK7)kXMCvTj(mKdEx5HxSCK}BJM--E z-q+f%@BYNsf5-J7h=I?+{|f#q@a^#Tm4qjJsbKQc`Jt&Y7QL8f+M&!;3Q85~H5&6O zi__RBHS4lE#-XQdnulM z81+wxfv4gB06*CV$Dy$QImv^;>ii0k*r2K6i&{(ax2s|jg_1{e6K0-)Mj8b?7G;b2 zYU_US7-Bn}jGy|s{=U99**@MedD0`Oe?knJFcEzp;3wNa?u9>k(1Z7EaU1GxIUTyN zEMH!l_0LOBUOG1C-8u8-6#n_ickAaKYdZb%yGD!M_w&J^=a#ZMc0&&*LS5<+0QxQ( zT%rcg!EaCai{VG%yWzhApTa{nf*H|4?l%r7D{GFo1f6o0HgSb)?Kcj`!2x~*{jU-(+Yz;*DmKESqzZ-?)w@v4jBfup*m zs~))*4_KP_)w1v3x^S%i#~|N^0ywjPcuJd2d@7iNE zbm5%|!=p^%WyHV=_sb}x%QCH^7VO*j;ZGIDS`*aa&MfOO z;hH;rVJFk?`_j4Se}@?OGyHeqPlx{q{GNXhF3lAS_8G6Fed`Wus%^At(!(>z$MJ$z z6)Bj`X!JL6@%y4$Ds+$x=)z4aeVq8`2wz6!n${$B^6 zFA^E2xaeb)e7uUBpk-RqYV~q=tRX~$+PG}JL3ldXCi1=Y?vP8_CGTDu{;>c;{y_oL}4?h{MBGCO+Zi%<)w>tfjX{M zGTJqCiC;oosmrZh&&pi+bSaf9kPg z&6D0bTz_oN9W~#-F=x(|!t94Pa<$xbZMn+2^X}LV$>-75C#SZ(Boisa{3lTVgcw)^ z-wpqH_>-`W^W+sodhC(-^1-v$3X{MGPRz?Ug91m5)e*7Q)5Z)}Z>8mGUl2o5f}1Wi;A=M!js!eywJ& z(LqZqjOWs-@?ykD0c&VR$MM(qao*pu?U;xDcZh*S@Nb2GKemCCj(SjXb5*F&Kifph z)v@v=`*ZTzTAXemzH-n!gtqKmr|7{LvrbYODxu^0OF3z^YWp*;HT})``0a-nSPNeO ze-->!;TIGKJSKZ_B|G*xBi?dgW7F51lKpyHEhmE0OlM2uS*ph2r+*va6J|;_j^EQM z>>lkrUvy9DO8wLEeNyH$l{6x^fZIY zlsUiDSY7F;EpnSwZeB~+-e4@77&A$_GVMQ6-+R{03z)<=h=FtA{|SC0{Pck+iwBe^ z>ZI)C6PJ?%jhlSPBq7gk$>nDpRvNynQW8syQ{5sWlBP3cHO@|MosPWwINbW({ivVe zZ$b<#fjUZ=IJ^32;*k zB$J~UlE07eqG(SbZRi2j_ZaJEq@G&!43n6M82D%SPr$Ci|Bdi7fwH&F% z@v+aL{t5o;@SnwZPydicIN>iOKhdhBtX!UaxxUVrkkuA>WL5Dzx8B3rr;;zEwj2Gq zw(JI9bHR}evEQ&dl9BH00)9v0BK+-$fp++d;QtLiaRd6n3N7T(3XYt`@g#_dHzeb! zi#3#`(yeEFB|bu>lL49~JzGy>iDfuxTn`7I$9G2zyafLZ z_#5E=3I1{I-jRzojHQhbWWPga7U4n`H^R|)Kb zU|Zf-A8PffW?S0bJ>}ztOkx^hV16F1yM=!g{`>Hoc9BXqDKKF#m)ahyn$5_uf919webI3_ky4V8EfHCy;8 zR~65B`Fzj2d!_D&?i99Ha@UJYVm4yntMCuNp9_C8{J-*#A3c#1Eulin#aLda~;s9dc9r?Ka4u0N7 z8Zia_kfFJ+yJa8obVeO*V?;Eu#G99sPx8Le`gYQ_nd>YpMw6$mV9{fjeP(pQ&GeHm zj(2oq-E#%^@;XObJ1XZw@QV=x=fS7r+#`p-0={xeMos)tw_K(1Q6f)GSq5FRY}va3&i zzkb?b3X}6Nq@MmL)hlTKL<|hW9}EA6P3ZptpZJ33Oz>Trn1GsDz&I!s8Ir{?l)&0v z38jbL)asOJ3x-H+Mgi(z4Fa~RJ^O3EUbR-9c$JBJE;5N3GSt1opAJ8bfjTe-@A%{l z_a6p?gT@wHlTYez87`1Z$mxk9_+t3+jND>foYHQM%{Hp$#|?)#ChMl1j@KTj&31$inX@MkY|awAnK7zb zw2f(bO)9i`Wt|6FeK+Oq`$uQ@2dGx~8xaFf!Ji5LEc}1LcV_rbKf~vUtH~H?6`FY4 zNSeXrl<`+qt<2gzN+7f}WtW7exyUp_bhTDR7ihJkWGUJHRbxo+BnJ>SI_D{sXQuvGEyWpoWQU9Y{KmQ(+f23M$<=H6r{sK1Ige5BRNt2nj zeQnlp@5?N$ewcOSB{Fzo&%KI+M?L)jZIkO$XS!2HTBp3lB>oFu_9q(gI{Y8ubKwiQ z_+Im8PQAypyxB5Ppi1apE7KV#Re7BbekF~WmLb*=ripx0@gJ05@dO61d5}%nop0x^ z*b(FkyXW+7ml^Ul`W_($D&Vhy&)tmkFZ^eWs%_qH<^DR}Qzn0-fVp`KF1#c0IIa?k zsN5;{HqUtKpZz7X;Vf*%GY|o7>@DdU<3^OhZJ)>04OMV!naQdD|gM`QwHMs+Ql;kEId6=#bk~0r_DQ8o{Jbk2hQ9(aFb4l8_;L8} z!#DGVmfbPV=Afn4@E$?^5*bHtOm7ls(Mtwr+U~*Nr80Q5fk-pPo}AG)R3j{lrkl{ye{XY)f^*aF*9{uqOV$ z(G!e{ic*0glb)+Ja4miR{^$+%8eh8t*MA@ez5stL{7>N@gU{pUkUHGm-_%I*%z($6^)7yX_XIhQ31EwlHqOQ zq%J^P`ZxD}iW13D|A`oU!+ogtg)jLG{ZQcVIQySSUTAZ(&Yp|b2cJ_$C8$TrQN@e< z`u*76(^m$g36K7!7qJ_soW1)OV|RSJYDxN?kbtj743xr`!G9ZmA$*Cve7R?PZQL!> z2H$TD3ePpPQeyE6wxpxMBYEOWUy}913)#{!k8EpyGEBe7HD(-H$t3=X82BXo2b0?$ z{w4Un04ckRJ&O8@lEn$}3PKk1-I}qM&3G?I8nO;d7?mz#AlE4~1ahmxGIw5Udg&tP zHJE;9X%%RDK@2DzK;T=U$Q%7o@k-juk%U*sAymK5RI3;47@k_U`T<)YKM>)X z?`*v!ubJOiIpFNR$GL+DS4QIte(qPLKU`_}YWBXMf)#t>o8^+C-u3@be|ra<@*b0@ zMhwn_zZ|}7EBYbAzmvFIrzo+eiKA$)JH4o8dF3Qd!{xZ1yM5%eCLLDUFYNFG)%UYZJ*`;*@EY9J6y`qEq?VT=Vnf|V1 z635}I;C}=EG59yJaSzfKd5+cUD>wL?Yr~dt5tHR$ML@LldFP;DaL4oI0YXw2IUErU-2| z!;~30HfnjWXh7hrbnhKkw&{N@Gla!!P8I06{1X&+^wd~%B zbMM#`w;F0≦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Ǻ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

    A|%*AijpX^uJZVo%v%Pxqr_n%uPiqU5pSlpQe) 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

    ~m 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%0DnL~VlHDrAt*$V=l_Jc2 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

    ybMzu^;4VVNefj_o@fcx9w&@=k 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≫O=!-!ZCPt8>F$FWR0E@5`%drBh#3phJcHtO~ z;~K8x2JYY^GN^z`hHCWcsExX)hlXf` zCin%dL>scb=s=n}GIz3cX6}X_hMx4^=!5EaSX?CQk*8w;k>v&UKUr$TjDmU+%epvD-Xmg@*UO=;`jEk13SeoayO3PEaDC3 z_Y#p1iA8cU4YDE|@}q+2P4+>548&kDoE(jbn2H%#jAdAdJ>n2~4!7|PNr&(=Em9-B zB_netWI=XOfGmhYD25V-()4nugj%RA8k23&4&5*iDsG6I z zDp?IR4L{TCiw309P&6W&VwPbxeU4#1U0Hy|VgBQsl-`jR54Vg2ShcVt6```uWhJ9uZN!v4d_ZEG)9xps44GmCVnB6 z)@WmBM>n-+?ri8n?~Oj9FF61MF&Im*0xKP?Vz)-DB~9y@O&gfCjdW!bw&G9xCAO2M zoy^KE7rWUjd&PcIIczz?d{i7Kl@mCH(>RNBIB&VctX-yG!8KgR4cry?NaYb88=lbJ zJmu_p0KDKC?IqpxirJet+)>`*BmTiBL$DG2+Cc;-zj5&``;a0Osf0yDOJrs@Q8`nh z8KTo;h?t};9=rG=A*m&%C&7@+p}uHJ{({!%fF9_NAsB|y7=zz10aGy-OR)}r z;x8N!2gyS?jN`b9dw7l);w7oP!dtw<2l3TN{`qDIK@W-VL?|*W!XW};<2(NSkA!4W zq(f%p5&6kNC@hMSB~b?DQ4y6;1=Udx4KPQ{BNt#H7GX8EU@NxaB+eqlsQ(B_Dq#^0 zQ4t48kQ`}{6*-X)#YGviGFqW4=3*Y^V=0zng;-0j$7bxnF6^^RF1=;5T+|CUNFuGJDe$W`9lP z8EqQf%?!?LGubJ#d@!3k${fpF=6U$TgZZ497BDZtGO>bGR$>*_TGlbI7aPcc+Q_q} zP0RtYndi0`w$hb9z4(iBZ5v(NMOSud_?r9%-y#%3Ba9beIS-6*JZ}omY>L2ai^NWgOt(d0XNt<~ zNi@!*yNJO)AY$^IlkeHbGQ_4Uab3h?pU{wqoe4?6E%;(%t8rKc4ZvbFQ`bSE=rkuJk$gW=0m| zM?n-4g~?)el;BJ$DN2)NT~Lm@hVt|ZCKZ`0nN()3B5IH|HMQuqQCHL_4GrjxG;Z|9 zq6yg)toi(DdBkjhF6tJqz%<1%Mg#8uMDHTKGN+`vuT#vS7`H_Wi^%PRZti8&;U(DbFwwM!2^9nUvdBjVh~1PyqH6JVi8ti6;@-N zW)poU_QJp+{R-(#~ZxIXMDkT1ewNP3mby7S3-!8 zWN3u7Asl;M6lNuc6Jl~FmL?889^#uMW=?LBg4tOqxob~4&NGV4q>>#ukP~@K@-iC= z&No}k>_y{m&6V7CT`;n?&6-fPx^`nE#6o-|MGB-t24q8a

    ?xyvT<_D1xFWhLR|QvYPUAr2;CV5~`s( zYM=oc!cDX!JE9wUpcndL0ES`|CSfY(V>wo17j}#N8$15mUq=mAHtH1R@cc z45^S>la`)NWFRvllgL5lMFA8=X;eZ3O*48cbP%1%F6fHx=%MLJ_ds9t*9@Q!#9$1^ zXfcVLj#=#3O*VRV zlbp=CkspObQL;Enq6{ja5~`yX>Z75i5nXXJac6FVmZBBe8f`>dvI9Dz6S@lzQrCxB z>5G9Ff?*hrv0^+qRm>ojS(pn?EWko6!eWgVeW_SRDl4!W-dKnAViUOq+rCa>cLZfow)@8Uil;R&9J=cMuiFYyYm@fM%NcT)L*UkEb$ zFG0x=A}kpW;YB1;iHslc>>E4Xcjh1XiQgi~9Dc4taD+l=gwcehE8!3x z5fBlPMHJF3D!b?+CTWOGk7FSoJ0+n=OqwNOm()TscFBtXll}x+Nf(%pVy=V4pZZ9>gIW#u1#r z8Jx#O%_aJEaf7^xTjDl(&*VO{FCJ(f(x2fuUWzy5TYM0oNaYK@;U|7+e$#`_abxoO@qXk-_EjpkJx{7Y3(i6Slfqr5jIT%AQOpGQcV3L?d&Jc6Rd02v#*of`e zi$ge!BRGmheHagX%HV>}hl$+viqFZh9=p8WkSLXaU53ZW5BL?9!gtSCH%1e*Kx?!?2Xsa^(UbHL{m6kBju99o#*pJN0TVS-=(8{z zb1_dWA{S$sSV1bQY*@qI7H`g!wPGE)9viR`o3T}FC+*q6x!F#31|Pa3`?;eW#33BU z5pk5%9b+~er=JifN#&F{O)6(_7Uyst7sVCwDz1qej0_(3Yc7Vu|8gcPC3&>}3UgwsT%E0GXcL?sO|>9G+<#3kb)0TLk@ zQXnnTnWSgVh^)vavXePAdFV=B6hsje)0Ci>MR`pHdPP*xRHauJwaL1uC+d?{8nACD z8j)^rx6p*0p&8xKlHLYw?dZr^XVH!9E_#qkPvJrK#Q+R48O*E<6T?YmBt}^n&2Ees zOHRRb%n)6n8>Sd3*@i_P%CAsoR8oWWU~$7S3XFUha?iO`Gw5|#{)h=`0B zNQ9(Fg|x^ja+0M{4mD68?a&*8F&v{Y1=BDCGcgOZF$Z2^8MzJ{u?5@34ss`UV~=JZ zeLoI}gXAI2VY+fubBwN>z)76KS)9Wa%{98=CjAcXi-+V3@tXW7zL4MW8^IRyy+jxh zo>U@;$fOb-u@D<^OyV*d;?d)agk&NlK{BKeX~?w5h^)via*(-@TNEIRq72;73T@FD zUC{%*ga_FVgD?amFdE}A0h2IGc#_Mp2|KY@_>hNiSR5gb;uucgthhv8!43H0sdz@d z6mQ7)_#u9i5xn?k9bzFqGN33*pd?D8lBh~HMo09(AdJKqOvQA}!vc6=8MfjWPT{mT zLn>!+8P{+JcX1z&G*9U-#T!z2hYtw4gs&eF5gYN576nieWl$aU&`9G>H#DIuP0<3a zEVO3VMzke6q7yo!2YR88rZ3&lj~Ot=VE|njj3HteIUFM}5~IXua=ghzW@VCQ zGTktRKFxvYoX^5s&3yVIEY>WcFU2yf#YWU#%Ab4Sj`rw)?&yJDmp@1k!mPL8AL>sh2XY@pG7xdw-mA>o^ z{phah&ojyZI|gz#7(@MNIL|q2BzFy?>0`uL(lCxbUNezCNlYfEh^eG9-Nci5Ar=cS za*1X+UAKaHrG-`Ol+~KG^!3<)P1vm2LN{!s8@AC6+vz*RPExmvS=p=cq3_2Lag02H zlQ?a1hFLj>3*sVq30H6(x5OP%xhH%{!$bO0JDzik=><64DKc=!s2|FegPa zO$xdp6EO(l92QJpl@pw}{~&0Gid zEHq%}CfvzpXn_vsh)(E?p6H7K7$^pj$`FjeL`=eT%)N>6lb3J>SK*5Xc!byZDt?f^5Of7US0V($B0M4>3ZfwfVk0q9 zBfZE#WjVz3!D1*9ah?Z!DHt2{>qAS@QJ8q9zhODxx7K5+ezcB9%x_ z8Zyw8EXawxD1^eI2w4=xQ3hpE9u-g(HBcLMP**e{4esvSNYqS;ZNToA+i@u~X5JNB&!!ZWqF$L2w z12ZvK%p(;~3k%sT5=%*CxmZCe>#-5rH9P3Lum^jwPaGhR;5bg=6fWTkuH!x)<0)R^ zHQwR_K50JFzu*Uci6CqEvjc)5I6`Vd(Zh&{WE4b40wmHTr6)rwq|s!cXV&DU7ZAnB z;wULfk)=f$vK%U*DypL<>Y^Up(H8B{0bSsMAsB{{7>CIwQ<Hs-?&d?2K=@)PjmrO1*D_3w8H*g#G;H!B^e}u;tp0Rs@ zmv}ASlJD_B^NIcysn+rLHd>%1TB9wxq6d1S5BiG%^bmL_tcVMLMKMF62c%O(A*_loA!lN~nrDs0Vj6MN70p zNAy5X^hRF{62r+c7>}u#h1r-ZJjn%Ef;Cu=E!Zx6NW*^m0UW|foW~{H!Bf1&C;ULD z4g9-KL_!>tMrAaD8(N?PI-(Q0pc{Ik5Bi}$hG8VeVj`wt7G`5HmSQDBZRGom$Vh-> zNP+aoi6W?iI;aabG)GIcLJ#!A2u#F6c)?q&CpTgncHjgq;U;buf;jj#xhsECH> zh=Bx1ge01z^khhhOvsEZa6>zEMK27&7%agmtj7-c;3$sc9IoLG9^n<<;61)0~IArPzcW*oR{{j?1`)Teyw8@WnHH z#y9*BzsMk4{t}!FfpCa~Xh?vhNQUG{g>=Y(>>?+b2l+&PvLK3}n1zz;N~1igq6QkE ziD*H#6s<|6EjppA=ti!^R`}p3PT>qL;}-7YJwD?*ek0^o{`rk?h=52UCz%fgP!NSs z6lGCfR3NKps?n7is3~fZbx>DRpKjKGo#HN ziWrE6*ocF;h>wIwj10&ma*(-@AB9j1#ZeNaP#R@W0o73p_2G`DXp44ekB*w2^!^xz z;bJs72GcPQp76p7tidMi75m7;IHoyHKZ!FqhYPrZ8@Pohc!k&E9r*=c@lE_7m7gZR znS*Tqe?jSnko53~h)9TvXd)IF+d?9CNsv^NjGjWIBvTg*M-@ZuAFs4cMHAP z^+sPC`mygX29U}?F^Dt_p({f%Of!P6jKnB0h8$-yp4l*gu1q$W!mLciYzy<)89eD` z3)wBk5-i0ktj8v7)@-Nm#4hZ^F`N)5$x}Fk^SF#FxQbi24`0ng`eV%#`cpg?uSl~u z?3B0SJ^4ZNk^U9m5PTOuk02z%AUt9s7GfhF5+D(hAr;ah19BlR3ZWFrh_Ylkloz$h z`X&vS8)_QS-Gn=7XiRS+nvu=X0xi)I-9#_a14A%Ej3UQiBBoiG&dx7p@SI^bU72Tt zC;J5^3z>C`m$kPRn$gZG(>Z>Lwj@-oygAUj$Wb<*&hQiM2sQF zV=87~Hs)bI7Qzcl#7a_G4R5iQT!-~y6S*1NumiiXN9-eY2bh&ZIEE8AiBmX(bGVEv z;wpJv+$DYS5RdUhJSCOqn)h_&BR+|*r0zTOPZ4AfKii35WN3sD5y_Z{hXhE1q#_xq zq(*vVMsDOoA(TNmR6u1^71hZGXaqNnJH0WQpedS(mSiimMqAO2?0}Bwj4r~19E#x> zg^8GsC0K?PSOsrvz(%o|+=}hkiCx%_LpXs8xQNT*3V9XRaT~sPi0Al#Px!9+L05hv z*j|2KMr1@sOvFWeq(Ek5MP3v^X;eTJQIBkhrf7!dXn~e!i|(Qq>4AY5iV+xvu^5Mm zCX<+_VmfAsndB_Y!CcJ4e6fIBh~-#=b=ZbI*oR}96LjSyPUD=oKwiadahLSPLp;Mv ze8ErrMi3wV`Gg3Ff~X=Isl-8ik%&x;WFk448flObS&&tejjm+ZavHBnpCBkQ998fx6>N)t3g zbF@S&v_X4xKsR(Z>A~C!eK5dD1G#6*V9t~wVmLVxqc9HRF$q&K12ZuTbFe_Oh`tzJ zCQF%@Sy;|)1y*7e)?ouSVVl@NTG`2dFMPy)@}M|O9v3IbQ{ptKoWWU~$3e zZE=^phlhBC$0kphmFJq5^jCO|w|H;zky-hIANYx&`}lcLgd!t~D5N1OU5SS1h=aI@ zhxkY+5|M@^^rRvMnNp-B(;)*gAv3awtYi+6lgx$O$cus~jAEiBsgy!FR74d~m8>Re zlC@C>^-v!T(FksEM`JWWQ#3Pa&a7+6thCa!rYmhs+A_PM9rq3G=~go@ zBdv62uj|RI^wN0H`=TEP*f5B_GS~$}xob9zoibdEAa$de$7sgVl?h@ZIT=$lQ|X3j z^ck3mSvJgOugulVr<-}QQx=GY>x0~57_VCU9&z^A`f&*ZpR8MUegc9Q+3aT->xJGL54zG<^dkp|fuvy&T^a18q1;o3n~Y>u zMq!K?OFA-+JG$}A$^RCb7+q>sq~X63LrN*a#Q zkK?4~6y2WFoClV(yxYoo_7@zu$hp}Sc4k-EDc8hx(#j3?_T1w9HtvYKq;gN(Cw(nE zVy8S7Pe|pdg=g%nykM_;$*jDx@S2_SMtmU6KC(0W#Ln=Uu6)sarGGd1$@~kyMUVsh ztYZ?4SqUyekVU?rvWQAXM@$imG{m7NL}Db-B&F+;F&mQ8Q;Jk%YNSPaWDr?M zT{dPV2XZ2}$V(Owg~-C1BJ`ptfs!aC%8=!4sK{Qa_7=odiVRXX?x+5dGGfIpnCy1$}VLE+=W+r_$=7{;^ z0ES8YUQY^L0bjuB!kIUZ9m9WyXX%pvD$=FyeK z@WKkL!fLG1c+=Nn9oAzLwqYms-~bNd7|!A{?u!THV>}hl$d`DF_xP>}dWgSg5EkJ? zcrp@VBc6y)CO|?YLK2abRFYXp&d!jMo(}1e0XdKp1yBg(PzBXc9ko#xZW?#GmB#Fq zW@uqUOZKfr8`98@?nry?bPyfMPUwuTq8n-GL05XAH#|)GFq`#b*B=8h*uoHY%5aPl zV@Tat=82djrjS!H4Kpwso>+usSSxmrhMn|X*o#9rj>9ycG$xzc(1N|v=5NrJ&vaHh?)p`Gp6wtyldkH* zGhH>^={?XBz0ezd(DxstKVOS7z+@n^J%cz`28$u&P?O=zW+T{H8O7eOM)RzdG3;#_ z%b8&uT^WxFnu&DXBxb{8`cyHEG@H&&nQ1bM*)W@KHiw-f^SGld!BQ;8O00&r*hFr{ z4(t(o$$i+512}?XIE6E~j(g%E`AGAGuDrrWeA0ZT8@|xZzOplXryGJC;b&73k_?Rq zA~G2bu@D>akO0Y$66ugZWFj*oE3#{H(+i>yN{P~B8BHa6Ra8eE)JFp})3l%~t|EkDUyj4WJ;4%%t~sc(WIrP(`2A$6j{k^$ZkU(_IZ(C z6d((UB4ja9oGgJdC}&chxw57T-AYyVHBk$-MLn`U8fY5Ql}2#aG^Q&}L{qYv9nCpw ziB@Q@=|Jx&dXl}+$ANyF8~W4j8Nm5q48c$_j2t1xkYmMo(lC)eNlYQ9VmfAErkF*} z!90y8U0HyISPU;L!3wOzY75@%)?z(2U<Usa(J% zT*eh#!*$%iZE=S*+@+h{V`sQeSA4|-((sUO=3u^mr1d!~6oS6*pe)0GeSBtDa0 z@Ky7TuKUic{4n{+{0qMkQe#0kZ@Qxc_68s$+zR3w!uqAFPvbwxwc4b9L3Ej6v_ zZO|Sa&;{M$fqr5zsSLqTjKD~Y#zaiEFooSTOven&wqXwYxtJ$BNo5h1U?o<=8ym0_ zyRaKR*oXa2IKUmpfzE;`M9-5F+k&T@X<%JY-(vLje>*VH6R?$Py@p(xMEhlt)EWLSTi9YCy{urbgO4kizR)%AgW(-{!iwT&BNtj|Xjd`YK7G0T(d02qO z@WL{&hFphD*owV4fWtVAv$!ZOlUKwIGW7}m8X>PqK4!B*?5q@FuPeb^3KdZaRZtBz zPz&|oE?SfA&`I-05?8I*D z!C{=hDV)P4ahtpYUp&N9JjYAC!+Vnt%*to+mHdXE2zl}^p~%n(qX|n7hwv66vWp}l zlS))gG!Zpt4C7W~G{_ zPS!*%)J8qjM+4E6Y%W@mX06yMtwkHMEjn1}#Lm!#-qoZRv#vLDAN1AqqxTmBNM)c6 zgV+zTFqEBP7<~jrVj?D6n8I$VW*U7aW?>HIVF4Cu7Sj!0^krBj){x#}6S-MzA(gGz zjlDSFq=Vd3j@fXW{Ry1JDV)Q3+!FUlUp&E6yb^Cn<*ms(X2W~>N6jaCs8jssM}#9I zATpvN8e(hW&~yip|}kt*ehjF4i!)dHBcM% z(GZQ`jwTMY=DaQ1qXRl>I?=nLo9IsV5FVtJKJ5ErfEY+BgD?cc#0XLuX)>C5j2KHA z#?dEXvY1NF5Hm?-7Up0+Jh4D5Bo||;h2`v&6((;cvyO9Ry$u`KE1Se- za*LC;a&NoXMJl^Bd+3I}bY-6n``I552T8*rx^h??Aq_|Awgl(@$BA)vjC;qOaFRP# zPO&$fp`XP$lk?1%a9MMOu3W=)lN-#=xXC@`7H*3>Yk1KlhmyG+O?vXh1!bX`tn zB^PodFY;R`$gVJoi4tUKltnp{^2`-bMN}tiXll}xTBwaWsE5yIMK#h;gKkSL&T6BMNnPf8q9Lg?f*Tr(W@K};Flou$%0g>) z?L>Q0>41(FI#;wa5l&DBMV;v1mdnP0>QMBwM2$I%qo6yP>;DPi9+sbLN3Qn!faY7W%U@44^9m zO$IS5gEd3w%5amB%;PW~6ER6lA$3!kmFbv?*_a1UED~PiGAzd`tbsSyT3E+!J+@<~ z1G_l4WjANaUg1L?5=ThoC{ExM&fucBN-B57J@P($@yO&cv+^7-@d~fS8&Y|P&-j9G z_+i6O_P<2XbNn+-ge1d?@T4IUJqn^BCgO^CWPFi;G$f`gNkuX;IZ_}EG9VMOA{%mQ za?!2iW}inCAPb4YWHFRNX;GG}fQq6LX;y_@HB?6}3w7Al6Aehk4UJ8jFgF#=$QEdY z)@Um_kxCczL~ryFeaRV^shLH0)oh+Io5RkQxtuBU#C%fc$!xZOo!LTmhDCH`u^)Ny zoIOi8UmC!c@xFktoc9ET6}-o=l5SWbpI?Z~zl@098HnQ8~N1J)h zmMxt9XX9C+!KEtq!Ze=%ndwe)|WFL2Q`~=zq#VKFg6q+&PSs z;xu{2!dZ68B|ENg7TB)x8G-E@pJB^&&i*NG@U_@;lXKlIW-GVZ-xa>3J&!q8p7_yI zp7X0`JZpGPS6+yhq}eNWf$cS)VR%C~d&|!39lO87dp_6jf$pl0JmacQJmbh`?kHdU z;VaL&;v4s!@tu3RpUk%W;!O9O*{_10=l_R?2u4~7&i+pe!DreMk~1arf2lD1x&uO3 z-s2bHc+RiF^K1ksMdY4YBzCTd%zeLz%5$!W#(i6&bLOfTJmVKJdCpa_c;tO2ZY2f#VEk_pR5~Li_fnapX4a)) zR?@m49d|PzqaB$zGt10Q$>I-LdDg$O@eW;fW?OP_7SM9?P9>KOx!LD&QeN)q@-aIj zKliK@U~f+$&UJ;EtrTHzr6_yuwd>zi3#$8uT=e}+Rvpq98|2LV%*K3$f zw`C4zx_Qj=HJ)^3q1aCza^NuMW=GgLa+EucoaBz-6#cXvXE+NiXL+~o9J3?mxnp*L zohvSK|L=5}&v(XE?pe9UUb$}J20L4V^5;HVXIA^0yz7>@O$LNJyvLq-8T z9tMI(yi@mt`KbfXIaglbl>@Iix91J#%3G6n%&z*tGp_i^ecfkf<%=JECqW-FoDD`6Z6%ef&O-I4Iz`4b}WInIj6 z-AEQ9vx|bL4n*TTx`i0*l-ME;8Cc@-ZbLk}AwE5!g~aT1Ntl(SNG6h#j-=#{Ar;+9 zYW8Mn*csB&)0w1aRx((~$WFiSbXp06K>8u0FhXe8Xo#+oK{Lkqg072T{gJ6&65|7yoOIylggb1R+L z`&DP2wWkZ`N>@!cdQZ`d^pD;=Z}6a-^=0R*e%!TX0B44Q^ubOT!X3j>b&_osEHH3-497 zx?mf3mF*@wnQhs{nb~f3&f3FW|Jcj(iccWg$GaWb&z-<>fOi`X(gV^V-WQk-^L|H; zaK{-(xo68U&RlhZXZ|iH`RxBhr}%Zb;xzZIoMG>*v)uKob3AKyo}Du;aL<;DoH^qX z_jH$;9l63C!&SO+OE z;`2V6d}02(eC4yhS@_P*><7D_f#4VK{HOWN*W_10F7n@(XoAv}VE+Mv^K0;r5IpZ+ zA$dnA2SRhMgmEA|=Mfx;$hlc0cFu~-T`N)82ZX4+=bt1RU(cTwozL{I7`!86p#Z zvomC%E15)QQkRuk$>yZ&+|%V?Hp|IQmz!D1XCXhkfKq^W1(t%mJFpbu-2tUA?+Qpo zd7rC_^Nf{J>`SAJrYzl1j&4tR&UF=-EBQlZo~?>%n(B024Q4|vdL7i&)TiqjFe?oM zP$S-@xM|$!N)yqPw51tm{?(j!=vpu(=eBg_ ztP8rKJ9?P(WOh|Ap7B5*C-mix($AznvocT&B9$TjFq~&ciOJ*?%)@*Op6rwjPTI&l zWs@D7IWugbD_gNmY$tbWcF}j+u#f$I8xF9ya*+KYlf%r0BlM##IL2M&gg8l>onmL@ z4EwX1bM*7#0_lv4+*2-@Twyj`rzNMu`@!y) z9ltr#1-Zn(d(i}?8-me;+Yo}iEzvl0BszEOiNU#l#N_!{0W1#hQ{swvq#-`tECIWO zNTf+jcUBVaDoHIQW9LY6?l>a__neW6d(KGDJwpb1V9Us7WU?bOXND|vS7hbBe`MqN z>>?+r%f%d!a`Qez9=eiOlscj=*}#s5oaq`d8{Fsy zce<6v>;qC0-sc}pdETrUJ4182m6q(4)@UQzl1e+#f$S(ck)6@ShVJZjJ(znssTcPQ zz3CpJ52^Gu>Bp=La9}X!x*^O%EevC)3^y6c?5t7TH5<)N8Dlb**;(VbYs&=ACW=Yq zWK40wRPGq2(G4@`w#?*Ane_+F=Cd4`!yRQV=7|NQVIkd~MVxzK36_bKuY7pco_(DE&!7Ds9N>Gd95gw^tQ@!F1ZStjS<-NhZp$UkY`M&tGp=#Z z%60b2EpdmuYvDdSUkeY|nLT9p*hx>g_Y}`;c+Ot;g83C*i#Mb*-g3|E9XrE&y7EDM zBwh81XI%A}XZ+&}&+EQ2n|)*Ftnb{_{b088ll{NNFTU14;WwY-A3-kj?*;z`LHW#o zs$hI=e^PKh?@tK9=LDvZyx&!!c;-(D&1dPtF#A_n-Vx4^!tn8jwN#PNf8JY$GYcO(IKT$PY#{tXiGb?Oo`n%PggpKj--`N>%QnC67(+)-wVS)?)tb1_fMC(S(B zIcouTm4%u`bbGuw_p2p5t1Q(lqc7L2pj%nV-jUVZS>u2==eo7b$~v*0G;E+N8|~P{ znJt?+Guy&$>mRnA&vV5N?khVj>|(bUJ~r%QuiMWY*beX+jvVC9ztthWcIAl4QD$3? zab`G9H=LmVX(#zivs3JJrIRA4TOkC7LEWJ%$}IIg5qZ4#eR+t|lH`Nr*&9ERvAPkQ^yZQZYM{ zhC8~n%;}IG8AN6>tH?&`vNKl`HOX4&V4*X+F6fHx=wU}s&IUSR5On2KVdSTvk6GC- z4v~k&5%Q?!82toJS~$(_49=RIXZDW^Ja5ZI&UBZUFPmIpR<7b2ZkXI;Hr%2cZqx7B zaF4y&eRi($@V)8B}mIHA)k0;`jW(n9OL?S;*%ya)^`+Jat?@v;Zid51egUCc?G0DYjPae)~ z$;X*31vyhnIZ%mnd#ZA-tHxYiQ-f}(Nq3|ccXV}_ZK=nZS$%f82F!+rbb}k+T{I?} zpqZuxy`_a#?3C6P+OV_Imc1?QIJ2ic=T#Th1C|;vRfzClZFj+-6rPEnl1FLCfk^|Yj)CiW3R@CuIv{F zN#zg@~trXPl{9InE-N@_n4hyXE;xHvFs(2mEPnLTA^_MF`dyteR$-CGCVasJ+h59~kTi}*$we$ao4-(-+${5vR3 zNO~wuXu2URJsiR#f`~*$)x@C3c0oMuD)BW5=*~*S-NZ;Dl9IM0<4j2|Qjn>T+68I2 zo7P3?xo^lo{nH_Obnt09i<$~yPyJh%__2Uq!M?mRA%pr zD%@A9YO2$9HJFu}qBa?r>hS)5in@F)eo>F-0$P3E>0b?a$G=@eeho?^xVgxk`%Oes zvbm-Oy(L;}+R!`L(UCJ(b>bOYI&;<)-7NHAr|ZewOVgWf@Sq#|&<%a*{WSgQh5>Xd zgV-Ae({)3bm7y4hkv5ECZ#J6U7|mF^G9D96CNl?ysk~R2W??$J84k?kTsNC}4(8b~ zpS{78Ze;;`D~s6MvY0c)%LPlgYh@{WE6dpHmNT!^tfISWHP7hQFne2A%TBkBc_X%q zo#ZafZo0C^WG}N1_K8!Za#oxpFPL0pwsML6#OwThiN!W7V{c_Sdu0VyVKvrhyy?nX zv5s6XHj?&i<=mESoNX7oNM$$nXng3(K5>9NC=QW_HAm^X)ILY3gQ=BWO1IQWP zW6xR6{p%I)P+p5Sca-1`gy38klG&EfoY@kVvv3HH2qH3R zh)RzkVv=!0TrxSbAO{L)3es&U%$ZpccEvQs>4p;YlA;t@UQ{3}i&~^o8+9~w=}J8` zKtnWw8ycgD4b9oNKughzRNA5)I+}E0?uu?U^klE}61_4q{7 z$A~~SlJ_g4FdAdTSaKdbu|ljQt*l~i&uY#cS;HMOZ+5n<<7~ZV1KqHZZrDUuHe(C6 znQUj?0UzuWhsYy1j#D@z&XN~!$%d=!?YYLemFw)48{!suTihYxS710nw#3W-O4&sXVWCA3#kcgdG5_ZXvQluu$(z4T~V>YCxn`L09%gAiV zOjojr?4&LSb1vkzke6LP6c)wElA;u8C_{Io9Cvi(nUx9_DzY=H#LiijxvNw`HBEK8 zQbSXdUJG@cP?tOPP~W5hvz3PI4UOn-!ku)aF?Vcf#+lOGpIY#|D_U~D6XiMta zG3(khD;-TbG27CWGedW}(gQukY;ukRb2*=n1z2dZm|5q=tSqzeke%{W^NeoGbI#0O zvQu8;jpiL)_kmgWk@=JOOn$*ve8&$b{p8*+{MH1$#m}Y)CPI)QMJO_iCM-Q1!Xp9_ zA_-E7)MQ!<>DXDx$X>}LGLu=5)dktOYb85-XXN0XAt&8XoUSXuT-FKYxKkb#OsXl;gE!rN$|C4Oz>#?$f{Z2b} zab{&Vdna+28@r@5z` z5obwfo#U?Ad3MSL8!oZeU1qj&g}vcA{f3k7aPK~Ro%Dcv$|LcFeCniU+%tR5&Yl;X zzZP%Ex8gmie9(NPD_`*q-%Wln+wzmMUk?1{+z{k8f94Ru$-okdcN;>}!ryfYv{by)EY1J1a~IH79b4M>ad&rj4Hkj~hv2~-0t5&N65QP-xVyW% zdvFO7+=GPR?(+U?bk*1ORj;-7+Gp=`Ah&zG<2U9r=d7x=lYYld?!D<|CZyM7Alu2v z&PpccnWZe$tTw)4?oZixPsvX9Ru1lXBPZtrLoVJ`z9xH;n={HchMD|8y&bv{CbH1p`eLL0IRrjNs zyydN0+_6%dxsy8V>-s@G-q8I(U*Ag&I3Ls+@=bsGk@tMji2I&2=1db0nzA?j%q+0{ z!rQuL^uB7&8$t^|YROx=U+I-r{c39(F<#AtYz+v zb)0vyp8W@TbOMKhTWp<`3%zSZ``))nv?7zhmeyi}* zrDvS;m*>0{)L!sS-Anqw_KI%=l{b7#c}G@0kUjax8Mi)hRu}9l|9dw+3eJ5Yqz9qd zNAn;i`&fvLxKezoE&+W)B$9Gd-Kxe}p}Lo9aK0w$NOh@7eX_0rz49a3TaCD5YQoG) zQ|8UkTxv=E)j=zELK~?q)lNHhL8U$4@>U1#c&k5m+!(+)VW4IZ*)*KlhyWPL9o;B; zE2EhQ)EMq6W68=m^7sInz&$$?+1Z)IPMJ*BO`#8nsoYbhk*7PD!OkCM@{Sv`IcH}M zJJUR70WqI@3#5fq-6DErF?p$Z2HJd_lZ8(wSWuGT_+*f+X=}ow3otgUI>eDQY5M_ zGQARotVAUThG@KNB|7sMnwVrI7CE*QhpNOQ3-K)^WTqq{yOEf4c9O6Yk|LQVIax>{ zrKAd}r8HC_t%Y>VGP;zRb3ztmm9kOY%FbCKhao4uDHk){*YtLBvon3e%uXJ5d0ooS zxo-og0QU+?g{Zp1^g*v6_oRo^M|g}UcN>t`nqA`yy#h`i;i!;86 z&Hc|I4&VJ;;__`@#p4Z6;&aBI67ZfWA+tn=#Pk7?gnL3#DH-+OAUVI&jTD?qDW#&O zMjDsWa?VLQ_HLx-oRGnTjO>+f$fi8Ze3h3stmI>EB|r0T4F%{68Vb>SqcG=n#ps3N z(sxvUD#?4gQuMmg^#3Mh_`RmG%>1n!Z#pT@{(Gqc)k;O?m0YOInZQ+$U@T~_A}q})i1p9Z`X`J22*opN(-{mlB{b* z|2ehc`$AhUwd1_d-lYzl({-d5I(-2;^Bdgi!r89qCUvKpdN4EfWaddP&ggp6yU~Yp zLSLyLb%16d+0Gz#%3$&k4~DY;&A~8sRz@-xMp+omOgD}`pvH4onBYefc}tl@_GAiY z+?d8WUrgt|l^M*1S%G9W@BXKl!yk*4xy*%mhWYf~TEHEDTg02fVl2U0taGrHotp(UgoBK%mQjZcilL^Ie$3FJ3-+v-?4Ipx$YSK=W?8H zD<{dqDd{xTlQW!g>pW+LOSq!BO1_5c(hcfO{H?i5wsVi&eZvF#r_wX(bA3HPR``=;A{3)ax=H{4Ld7&nCC@43*Rym3b;^+GeTiQ5qeWmX2l#7XICNs zzT-|w2c_7V$}lU7awv~VQe~=Ag{)L1S3^A;KQI^S8ye92LqpyX8e3?>>?bre{7T;n zZEUn<-d^fR?TjwyDs`g@-O(cedU7YAdU03iYoR|gHwJLdlYyL329XCFhR}O5lrz6+ zhLM%wxtx+8=yVIQ|)&;G4=xvT(|S3+$DPE~G$8DHYX|)SO9!v`A+mJ+lnR zqRC2jBOB+G>|}q+!F%4w$$4FFdLa+;OW#rpprDOH%!MK-YM~f2p*X%Xl%y9*p|qw9 zSt#p4IrgUV%1?!a8g;Y@*j~rnj<%xvul^gFQ| zd$14taloa6oI8ZW(h=%0oRCgZPkG@qXU_z{S?(wo$ZlQa>?O@*vhFJVHC&heqAEAY z!cE-5-?$^)r3w%6*v1p)Po-y6(?BZ(@k&{SCsX_{*LTW=A`n1R(Wu#_87AY%L_zKyi z?9`mdg|BVoX8sNGX!4TtN%^S-3QfaDEo?JnyNL4D4E2FAZ zjambBQ4jUeP-;wVqG?M0+3*X!(t<3slv-2U8amQ<(sUs!UCBxhve3)Wn_lQ+<2`>( z>&vb`24J9#LCl50UK+xA(@1Os`BK>!#5w)5*dN!%TW*7I_Zl8y3)8S;%~m7nX2VSc+wu6=Y=o){=r=f_n4U;GJB+XOn!=IHeN7SUXpdM=mX+4_X6q-cZ1qnzUj$3&gkCL zd*cJ=g-=rOTl_uIXApvKhD0bIh2g%FuMBt1!B641dME1AHyy;I-c+cOW z@}@VUabAf|_9O;pOtF}`6`Qkh@Rq;c#-l3n$w~rpLK}&g2UKG2nvyU}Wk^k*2I-{q z)C>+XvdiQ`7S3c1ps%>6%SNxuPA}v@PR-Y3A-4$YT%JY_$@0nMyQIWYPl{iz? z532EoQk`t7!Az)$x~M1Br+U(mGpz$r8{Te<_EHC`(9uFCW_=oEn7Or)v%)56Gga9_4oq8l-^w=T%6789?BFfk zPI@c5m)y~SZ^>5PG5>&12zLAbFF3sr0--da$zg1SWiEvKmk7`A3`!CCo+%PDQ)FgQ zG*QW>Xv|_Ej+f$cUWg|ppe90MBtyUH#&hN`r8iXNJz4jG zUinDY1^b)7ZfJs&LwFF1y%L(N3rinf6OkN66O9~Q6OWugN=Qv)NKBs$$u%j-LMkaW zRY-%hNM|EGb0GsVA``MmIjBNTLoWKSrQB5E8$%xYyvQfzr|Q0?7YaxPsX`HykV;dP zGGw7VzDG5wI<*FBNwul zt(dvhnzKq9a@zoC#~nNE+1cs9?sMwM_w96I=Z(&s7rOYMD|b!ZnVEVrQ+kp6p}#bc zItW8-{KkA3hC3L+E+9s7PZ))<7$=RVPLw85C)=39+^wmcRi=?m)0qh~3^VDKS!B~} zX2M*}JhE;vy`81(lx5`QniXVWy$?2USGSQ~w~5})W_IT_7s$dz=@!+>ZRWxq%|GP3 zUzmIR9_0a9c&K?qerk9|ue=}&@9|Q zo;07TEFdqImQsZkScz5A8tPiC!+LDMCTzwo?8N~bm5x!Bo8-T72Y03CRN)ogAoxH0 z{Ti}LlcJ2j zh%LpXDhbF+5^_>Q3i^~bQZZLjlQSX{GE3R0IV|L4rsN_kUz5K<9w{$1AM!gWz)mQH zk|>J`sEEp_DpjY}L@iBiavjt~J^Wz!k-m|k3B8@4*$Ka(8JeSo)QW1QEpwrrh4#$s zbYRyBozYF|LG6V;QeWx-X&`kdhDpPz!U&ASSd7O6X(DwhW?PuU%ruwT5-fGFjNNjq z@ROCiqgz8Std-VLb?fOjIM~Qe*o4i}7OJtEroZGJ1K^AsOyQs=;vThIkSzN>= zT*hCxiQD)ackw{;f&2-f@BL34V_*POnk)QT#!mfBL=p(8qJI+KMi=!Wi^ z9%P}Xp%=Xyy*U>UeYj_(A9E-D+3N<-4-TLq-1B58XWaUYvrdMww=kzxNwb-}McPKSvYok| z9qg2yVD}U^$-plj?xRqTspxyJ15!wiPO?q>SbKPHO+Oha055-H||JxsSl;c z)F;wY>T|rpYt0+-Tj?ED_ksQ+J|WnB{=N;N5C&lpP6|(rU?CziUqt49R4E$ON=)WX zVzG~{i9?Pn#iJ&a5>a)D>2*ozlYIus`DO|WDVh0GD&F%&TJ9_9$ad1Rb1MU9Ga<7k zE7_B;IAiBqcD^XUeJ2IkJ1NAzu!SPbgrZV0YH@srQkv3aH_C9%N?GOsQI31M^7Mi2 zd%h7+6}an0Ma~J8yikR+x~lYcs>7E{n7#57`DgrsW>Rx%OHC`X(Aq*fX1b2_ zLMN9xb57_QK;5|4UDJcC^dy^lG1K*-@2BZcwlaXZX$Ui6m|-~m2x%16Tcf!X5M#LK zt+Cv(GLE@FjOQIY6WLADOeTA43U_o<>8BZ{)0<{8n4hzttz;|Pm3;xp9JXzBtK!;gk!1az;5#_T&s_KDV>{1}o>72Zr;!D_p=u2bb6hmwj}F z`@&Tl*O*)Rz`Wo?{%#~hbp*Q+?sW0dIY5J4h8qQfKBiP#+$!?U7Msq(XjNv=VIP!Q*z(i>h zbuy-4DyDg1I%j8Nu3;Yid}#r7Ar@wOI7xf_iGN2g@c+yWZhwU z-4S}_C|Nj$<2Zqn(x22bhO_j-HQc~!=?(QgLOkN1DMBcOL3}9zH3^aY5tlngLXcdvy$T=}q;R+4+H;P+w|56@EkysVB8J z`k}vO0NGy#@|H4~tQ$%%{Dxtg;p9=8(d4nx1nOjI3f0O~<};+3RAn}K4(4G27D|h# zOR)^gu>z~5HB>8Wnd{ckD;vlgvB|KRUf819N;Yj{=41zZVW+fm0zpfkFlE4oQNsr{wF)R7pA@t7b@q)s+Wp;xAng&ERJ z>TCX){5e!BbD0aFpZvEl&GK)p_1fE|7h3k^5h= zOZ>jehAZ?z?JD044A*(rTYqs!cY|JclU}&xqubo~)*bGc{$ZxOORwA`>+aK=9x!|8 z;1N4tJm$XX3A4cRl(+rm8E^U1bKZLqL|*b8;gw6TIj4I|@5VdMeW~8_+nju0|IzS? z-bt{h{Cny^5}bE^5rX?dNGTLGw3otg-V~NuUCtkMPTMhM9w&g%-$POIIlz_ zE78d@q?lAYvDgW*5hsYn<$M3<-}&bt9{;m*5}$ogNy)c_R9;BW*-XfdJes^@-M94q zRDk!Cf@FUv#5(~|n0x=*72(gp=Tek!`$I9_32MdpW(iG6a%q%tP?nvOa_n{G=_~r6 z5_c>6pbB@LRAXCV3WSV~%D% zc>$IhmeUI>3@hn{HCTuB(thee9Chgr&I!k*lT_U)dflJ&zBt4Evzl|{i?||Pr7G9R zf8mye+suT2a2NNb2h@jn7LL(!*k6GvOm1!omUoKGqdxC-8&l}n14d>XZ(9g zDI7JD6piXubj}Jf3^C~gLoD9)huFNMi$fnbh{WSNcH*-$C193FlbD=Dla!pyLJDS9 zQZg4(X;PEZNNK6*4C(1j8JH;<$(bx%Ex^a8_54-mOBM^+jRsd#ea{ifW3Hb;aqOlwcna-*L}QNp}8Hnzz0*W%x}_ z%Ca|=W2P%luT&%}RmfFQU8+gd)uMM&hrO;Y{SQ8<&)o)whV)i`WNxJqb0>c`AU zfA*#U%ya|kg+Ums8AA4_p}c1r&MY8CaBq}hG`*8C?3J-(VVsTe%zZV1H+(UX`&Onf zpN8p}p_xfG&0;3Z#vB`Sna{&QEW%=G3DwS0cFQ!&$yQb{{}Qd@cR5+jJ}9l>d#1I_ z?5txatk-NH>o(I{*}`16m3}*R7#<=~u?ob11`kcU}bDL+;C)=+@HFiL7lk%iJy8EQFAdGhzDAXTL5D$!R#RU6fq z>#Eb&2x7JPUTvukRjEr>>XGf#XD2j3L;Q$FQe$cp4}M~=G$p(7Gw1x}7v6HK8E19P z=}j$|eJ(Bew(zTs*36YQuHWh3teySR4eF@D1HkdQX;d#>sN_%1W|n6*Es(bLLC8hTrJM zTFwQvb$oNZw1K+O#wO<8+QOaxbX)mj6t=mroilcJuoHF$&@S%%pTPffu$w>6du;4w zuG>c+5c|0o*beZGgPKERCx_V!N2H_FW18b+D<_!iPSQI$#a{W7tUFCFoWWTO=a~Il zoaeVH7swZJDF7~W#~W8TAK0$)4JX&wTe;3$`HO7l20P)V<`y}y+~#d7e>1-m$o}Dd zZ`|d)zue<3AU&j-9x>BBrML5po$fik@WM+kIsXc;@g@koAq=7Dh0rd9;Y?r%%e%U8^rrC4{2>DG1XM)s{u@N%ciM@}?%yUVzd4#F2H8nW z_MXJzOhCluo|8E2g}8ncpSMg2m<2>4?)f4y_dlm3d|ycV1xUtk@J4dZ2Za=TN0)~_ zDCFfkx_tCPQ6ClKen1rGo{;h-|JlDL4Oy3#UYCL1Uo!GmCLd+xzOFF6QiSYDInH=e zo-@MtfuI6!dZQxe{iPOfwMPf3Bh`&goYQrtx6_54(v|#@e}=LLwU;0C<_#x(*z5Yz z+v&$HAo_F9p9b)rFi;vqwKJIA5Y14swa!+d{CLex9rSh z7f`df>tr^2-5h$;TxL$@v3D|`y|RGp)*{Y+PK)`zX$iA{TFPBtE#nQhmUC8EDXpgJ z*3b)UHS5T__4EO;fqNT0*u;LbOItYS##YXmwlNd7yRd^ZPIj^nEW3Hz${yza@;h(Y z*~@O9gZ=CR!vWsa9i;zHaELz+PY!cNca+}Wj`60G~!VQqt>E(WgOrWI#qK6IIDf_9P2u zgsk`qIi#FaPjYd_lW#cVRvylp@-p*Ae$G4jmc5+;m<#2l@2R?q^p#Ns)lglkK{eH6W~#-^RGXP6bvPr`)zl+5KqF0K zaufW7rf9DDm8@$;-`YZ3X6-y^&tB+=Zs@M*LDu!8SNf5a{^X$;hT+mks<%dQM;T2v zjbWyYCkqoalgN`X1ye0dVU7}e^UXB%p zmGrBy2J5f^o3I(%G&{(<9PDPdNBW&A?6t6u+5dL?`E%f_gS=rn%pIfA(TQ_HXB%CZTj|PN=q7cintCvE(v!WZ7c->~xi9)l1F5<}^n;}#RAHzz zjH-+v``bv~9Ay|yKgKYQe!Mh+s+&l!n?yfFno6C9>6#g2-AwvfHfA#y=1B9X!eT7N za%lxsSxFXFVKvrbowSK6Y?iiAbzAATS=i3ZtsR^db~@O_PPd2N^gA;rd)b@zG25>> zK=#H#&I^aUbcFM|WAsk`V1HaXK|PH#IBVe?v&*=mxk|n+-J;%+?ouD%37+8<-ryZR zNx|Om*E&sbvJ!$EQWJ_Sgs~8onGgXHrO4DMh-x7kGa&|IBQ???12Q9vl$Dwd*)_Sy zd63USer5%wLR3!*b4FK`z8H$5gj9+ul$Od+O=X!mDaYQe3Y@K|sYb z_XE9BpR6<_3qMMYs6n9#-!c8f%+!>b@-tazrfE)AT98}fSF}PKw9|AXE8WOFq+V2| z4_WA|=||S}r&k7$2Wy6qbwlZu;bh$idSxV87=_WAG30R=Z($-cPbPC_sx*VDn@K+l zvo&+cR^~C+&8Jrul08|(nI%|?Wmqn)pb9Io4(qW|+DzSwo!E`vE$n5c>>~>Y42S3s zTR6h(sOA`1_XquP=>+v8PT^0S##x-hCFwHNbd}jPT*ocxHuaA55B09$5xww4dPWsq zO7E!er4Q7P(kH4A{4M{iza|tpG{Q*{s1XrKib55lBbJTW%;Rd}k(KylB>`DTh(vyr zn75Kh$*DpLDJ4}%g|vqB^h#!O7U?T$4&;))rshT-O?hl zV`is2JEaHNlb)PWdXxKD=*vv$NA9l~K-LYU7Y1Q4hT=EFFnZGnW+O2QqcPSnj$Rm# z$(Vwvm?ll9&c+;RK2=yCEu<=o$##~q6P9Czw2Hb~vzEM0T2J-G2JUb4U=w>~3)!@l znX-*6Y}f1{2bEoXOW1ALLvLj-b8qb9yj%M@D;%(JkeTif{b3J|u=mwb-mr6wos~bB z3&;P1o#2nnpHA|gom1?b{K;N-n*NLnXE|f%96LMb*?H?Ccbr^d@8lZ$>n{Ao8E@R+ zyy+G*JGa>he;e-6yLF$l$^)|SNb`j3PfvMIc}9M&c|m?@culXoA-|R0QH2lEN2({E zI1~IGfA4D}6mwl@dQZY|MhJ`Wnh4}bh^&c1j_OCzcuR>+HpOHX%L}nNE5t!u#Pd>o z&byU>vz{d6jGaX6ge01z5cXkcBMBDt$%G<{&$}92ROY z6KYwg&8%J^Yr^|Zeq!&9rkwxTrC&H_r5SUjIaz5*Zf&Ctb1Q9`w?liEI&ebne@k!A_Y;{!+~1w|HYV=XG=Gm3d^-d}hL;AhLw-SXs_o zw~Br>*4S9bT-XqVHu5cDlV&s7-?s3kvXv}sv#_0+ogM6io!D(*4>R5G^vYhcvX5-% zAUo3`X8v%PcbptyZ{;X+-7$LM4<8)ou5eOwiY%P=!5QwF&N4e^I8Sf7z)W|MUU!*Z zxFTJpI=RN)U#|0(@)udTNxmiBraJkXz3vXZ?jQOu#a(`j?jF5zpX}BH&OWs9h`E!; z>;vKn_q_3x^QPy_{OJYnIeE$68?QL8drj}w8_ou%x4bXB!+S4$0iAL5%r&nT-14B&S4J@&E+n-|d zp1;N6O(8Dg8RF9m2?8J?cLFLAcl{+XZ`n!4&dv+|?~K^(#5^TZBaMT!?9v-D(7Tb5 zb51g`*JY+xvXZ}&a!_?S>2qmvlfCf`=kr*|%S@M#-dFi~qo9o<%-tx;xnfdDYAKXP z8L2F_9Lihxo>>J{v`~qeohs~vs;H)^POgEPsAZ^4uhb>ilj>6&Xd06JsS)p)8Z%Rx zkexJTFZ?VuqqdM*QiWe_v|_HbCM#{pLI-sG!gb>J`CDh+RJxG;p)2nw-N-_BLl1hT zC)r9b=5~6sbJCZ+(vR$90Q-S14d$FThH%~+Lpd)Db1p(BD*n$bAfFv-%!Sp z-5SqXD-)OprHOpcG?`gonZnzqsmz3Fn2s6JOsYT4;yov`*;|>zT$xKY&0{9amljY> z3z-RvY%FGOX9>H2Sjs&s%b2gwtR%0I)>4)A+0HX|%5$=v7wlf*mGp)x zyu~{U@0kf7@JR~xf&YC3LvZ>Kn$YAh2yk24-83p*Ge+xLJBD*HI2@bEay{s@tf+JTTSdeNSp}CMebBd;V01_k_AO z>M^%dpIt*6KQeFRrN*4M(}bNTKXJy?l$q{ldfhMdPMWcA?w|!bCoS2#@hj)7v}Uer zL+?gg&IN^bd`D>SQU}hNIx=&s6KDOQGw*cKbR`SjG~LO*=)rwmPkN;n*^}O!(evthbLlcu68*!z0RBt5YypYI2Vs=UrvMwpTkPOMC6jULlja1B)G-M$y z()l1gcfFN~JDF`{VJ>8qa!`ew$mLRQ&I#Yx$iqCZl#iNUQ-Exz5WB)Cf}*I78Ww6Y zt0mQ@n(8nU>Y^Tga8RF}(tzAh^CMZ;h`x!YDOvfM{EO6_+7hkNPSc+3qyu}QqtuDo z1ziK64|jzAngL|pKziL^dSxhC_Zz)10wXcXFq(dhW)fMLj42MLva>Rq`CQENU;%q! zAr?uCsY|8hR68r!t<rFK+ZdwQXR)RF2*C(h_P)0?_5 zv(lA$Hy=IcpIPh98*cRCoX|Uv_2vD3E)3z!Q2d5rn$cv_7-pui%)Bv<^U8Q~V4A@D zRwgpnO``W?GH2YH!dcx^dfha7({yIOn8AHdW^%@pS)B3KZ0-niEX-x*$vnAf_P}y<4$4>#aE45#mbms7idYl7MVV$V^E>HYH`2%s~ovN=mY?Qt^hJ z)aMXb=&j^s?j#?3U4DAgx6Dih zm<3cp?%FBDPFI*-DMI$7C})&nWTiN{go9`NdmE>{o85Q3U(%&goU>D!ovtjslXC3+ zp*-&>-;*n#qL(UhURRmkRE1e!s>=ILsH3w<+9bF#m*;4M2X+5M_%MYht0xv4EP zT|0VjwCB8&4(zRTWZns#UFgCYr5jo4P8NEgrw6^*+j+`gYs9X%)Q76{CEFRuP8cE$ zrT&KDE{x!eGLmd(6gy$G<_W)7@4wVMhTlBa#yIBwFrIgW379BNqM9Z%(@mkDYM4nc z%(5_>nJ@=)EzDyk%(t+B*+Q2VaZXr_C0K?P(n{(otd`bL*J{?0H)uAJw`#VLcS^rg zg}vCPIY3s9kWELK34h?YgOlup(>Bg9H=Sj64(Fu{RMSOf!X;dmu26-m9$aJZmA+oe04^VUDy(cPuLXSh#qdcf?V;Sv2~JTW|_e`a`2@8kvhm(nZhYrHpn zqE|u$4-?E=p}3<9LvJM$z@z9%Ne1Z;d}ZDnu_E~HYzh0s-P-rpeAZdb*Mi`^{GMwG(r>ngrCt2E%7T_ zp*7l|z0{E^bV6rzk-AZPqBr_t00v_Se$$K~kCaAH?TleJRvJfD#*^Kc$T?w>G?{9e z!c3TIm`<;oL2qX!JKZe$Inq3;C-XU@EFcSuu-L{D=1T+UF@K-5jJv*C&Kv%)f_DO9 zCHI`HW3O9Jzrn#qcEToUGu5<(*;eepPQxzxJ=l-qc&2$y*1e#AiC2c#^uim24DsJW zkwaSu!z?Vq`6xX1O%a$05fRA{nO+x#UWkeqh$+RQdMgfhgt$^XsxCggkT8%W=3OC) zkCJlVtz?|FlAO7dRP56@NXyQR44ljCQWnmAWynUKUCK$#C4EiJjeIDmDMS_uOGT+p zim^8pXI4V`j;fR->q^m=u~C+JIeafwqE?lvQ*|}yYoRvkI;h9alLnlz(vW#$G(l78 z7ix2~LTgPsa(k&GwUdp`%!Mu%x-#pIo>Fh>Kxr^l7-ASoKSCN!9Vd;a3R5r*v!prH zc~~GVq%JlrpUIq5w00xsebu1dG4f8!tA!$UmB zE4nkB?MIoMHa#!EFwsesnHNaibYjolj9+gl#D8*lu}XC zA|2988K@bN#llz2glxzz<)Y@6zM-1(GE?%C3!$*)J8~(MmcFOzD$pwx$yKDPR5z+| zuDVo{TH8>MUipD6)JFqNL$cDCEc}F~_yx^0&B<*Xv}31hPv1e)k*w=P-&yKH?W*ZU zcG8`F52+`$H~L6@sX{;W*9;&J!BEXGvM>T;q>0qYn1X4TiP@UDWH;tRCtBq~Uh3(iW?V|3{>?i9E z(I3VU%~7)M82ukOjuSYA(>Q~(nsa2`1^P?4j4PU}WGC0z+xdG(Uz7jEGW?&6-| zKE3b&4{bbR{uHn98gKB{@SgsoOP@IRxdjWwUu&e`R3U^*AvqT+5QXM#Aq>KL5RSbr z0=<(+?1d;^ipF_ebo!V96pMR8Y{Ze`QiTLaC?%#Qm6B0YXi||=YtoR@B0Vx7BQi^E zsU6W3-K9R%zEXec5RAY$%>=SAQJO@ZjA@vOS(-UyVJ_ww7SSt<$xE;dE3gu)u|`@; zU55>Zjr69?%&cr-z8$-y->G}CPqUwVNOOdI%)tqE!fBkrC0y2AC0~=SQ=R<9{w8i& zxXsMU-^@*Sn3?V}Q|^(4hj@g?c%gYoR$h@`yv&q*WKZ&QM)+1!fNZ58^Fk<$A}A&mrf{=ln&es@)Ml@%OJ7g=f$FXL+))~kbq(p2M&!n5f}f%uIcmd8;3H`Wpt(D}%{ShOk$Ll1;;yd22X# zbR+0T`oSpP@YQJEurrq3IE;5;0%vp+>D`*dS>0rMD^r==$-AW8RAG+`zjH>}OWvp1Pd*?W zr0R~)AH_+W!k;)Jouw-0$ZnnItd$GQ1L7k0ymg5?%4M=!S2%keH*m|sZD!v3n>(M= z9lr0af4CFW?($9DJ$g6pbMB#qN6ds5cd!AI~j9b+>TRo7~5Cgn&@O9CSoDBAr8GR zF1?j_%uVr`B|t(=QgSjRcaVx*TBMgUQiV*&j4a5CY{;p}P0r__0K38{A{C|TiqRL> zlpvQvX-yfjQjV;APp*hcsEjJ8hU%J{WPhv0n^tNwuVbMeGhKap=k^zu?4&MW=Nx&ic71~NAdVkQhW z451H*-?%qIGnza`GmflGAS)Be$|Uk+FHGUAZW{ee%`Eb4%+)L;3yZK4Yc=c0%6jr9 zY?iiBg&o+5J=lwV*pGuaf}_$gs`3X}IY|~y;SA1eE|5(ZnO(+J=^FJ0Zs9iWNdHiU zd$=z>pbC%h7*90M$j|Xo^P2od^Oh{U$0sRxIR1NXO-Qm33Skir;Sm9mrD)U`h=n+a zi-brlC7~wuAUS&>1yUjv(gZ+S?g;6m3{)!_nP=8yB@16^vXKKSJ9l#;mnJvaP9Ao7 z9pq;xeCwkE+}9PPcdHO*b%p7z6k#qD4P?c5-$`-yx)Sud@92fnnlfaiELkZ>F7M!b zb`_+G)Jmv~DlSyzjHw#4nwnbVI;dx;PcJmE(2$uMKXR^-g~rU3CS>6!O;fVcj4ZT} zT2fnST9Zu=`TOOL%sW}=%uLsnz8ktrJ*Yj=OVgX|t-jn5`uV6o_e}$s=?2mdvN43Y zFx0_s?1p(ToV}9~>_=)wk(JTpF&OKEaoioRnLt)1lI=`lr%Wa*Q^;1PGS^L`pDxX$ z&cbX9bC~(dT;B4DNl@sT(z$$eT4=$XgBD z=(l4R_F%8HpL!5S49Dn&KcwSSCnwmOPB9A#fASsEX=Z0UILqG2Irh5q^xn9@c`Fy0 zyLE}P!WCSVu2Yr2$fg_2l$+$+_#1aLcgeziJisH(W3uT9GvTS`8Tq+`7wmK|>0jA+ z&D_Zc_R2@H@JR|5o_~f*6M`Jl5Q^Runwby=VI72Hr$it}lp;};DCDR!G`G-#na~oy zq7_L_$B5D#T88sEsOBtz|q|8*^SM=E|WM`HW-=ct2kXlG8Ow|>k_lKgq zQ%qBwtSdopA@LYPkN;nS?Nu7(ucj!7yS(b=m%nuG?Xd~!*Gm{MpBhgn72AV+!Z(Ol9Y-Y1}bQXXeQa&Iq%l+0;1>=CV`fk>?v0&@aRyES8o~g{2mjGZR*5 zR+2qg#Tj9Zw3fPFvym)p#ujNiRkwrQ$u9QZ*v`DUNKPyz zp{77uWJD%p##hMhLJrOdIq|jO8+w1r!+T0zvXy+yP2VyT3K$B~D}~9XBFwx|l=E&C ztbM4C<&W=ONBb1)b4FyF9%eu=bP6U}q-3zuGUPIzT_O>cU`?5&@@ z<2~Jb`VWSW^ui|_!6Nh52Prt!-$L@H5DK9!gkh$HC5JOaq>qfKh=v%NSmfB6_~gV$ zqDe{?lG#YkJcS`Oy^uyqOU;PPQdX*v4cRq0$->u~Z^(HJdFh4xD4;1s77A-hkcCnx zgR&0Fv#Wqgs3KLPR!0rglxkD!q9K~0rKT0R4cbcWs6r=AXR^>$>P8j1qnDTZa9-D! zzP~hpI#3!!9VU&WS{cQBv|$XropJ2OV=AUe)2X@{^!_rFw}e@kEiIs$7BLeRV~JrY z{Yq&S)yit-${O-o!#eu)*nmyg?1Qb`-DY7sGhwH+iz@8FUhI<&P!Aan(5_92-<|^5AjhU6}%>UBdB;Us0xTCpC);*wqgvWS-rhMiKD zER@$&AXk#AQEQ@(rY>2ihx%xM#%PLWXeYI&c0gyBx^S*5x}m3`7kzK34^`-g0T_ru z7=mFKfsxWE>S)6R`iYo|X_$don2kA@CoP~Z!E&s?O2ZoZwOA*ur*6O&!&dt37Ircd ze#Zgn5cMdI;{;COPn`C`8O}O6&;9}~OINAaa2+>s7x$$HROKPr^oZG0Ji`mTMcAnP z>w^@Y>LdbtB@#I@qDWDxzKX^h(KRv1rkKp)O7W;le6o;KN=8kN6jEwx8YwL`J+dG- z@)+{coANO$fWjzZC`Ml#CGef5Bv~m%HkD>p#!!yFyru$KSCL*s(OapdvR1nNXg(o7-Gv@naAFdK8ExzzcZ1>~jpf9&05v{Xm-_i=)|ySux)TX1*R zV1eN7Zh_$L5(w@PAh^4`ySu~ltuvt~kMX4Ybz zw4S;F8#SBAe`7PYSlG%;*+v$&V<&cDue6W4Uphz?4&j(|oGP5eDV&zhP|xB#E?T(6 z%$>{Z2v?+Q)a$r`yMA7anRJk)PnX^n&_Q^NRdhdP9AS_xK=vq$;1u0mAd= zo(QFhKvp7>b&=?W$Wjz)G(`6&F?d%OlirtN@t#w$*^T3Y`0VNu&?iD-BtcRnLkgtQ zq#;{L%UnojNKdcJOrO<_Y@7?(k;kFD>+} zsLZ^IrYgC*8#Oqusi{S-jk>5OHJ~;^V>Cl^O$%~M&97vk4Sv(KB?}$U(VYwW7MzdIG^Xv33i+~!=C9ZGvxx=olEQpmmRvw-Zkku^#*Qw z=ob6ly3Jir+-2Wa?(>%LKzc~^t4F-?*uoQL-gwHr=Z2T`!YjNsyrEa#lHY4Sl9exH zAz+06UtoG)3c`D?1mj!@P7Wc3qJ~CTO*nESO=NNuLo|9T(V3fKFpFh~O&`ZbT;}nS z011%<$&k{aRP1>oHT!9h){S(WJCT7sQzmAaHCf1>$jW{;4`gT86S>$Iaw8A&p|Fjj z%uU6ZDJ99JP(~_8EsqKws>r@liL9$kuT&vd)l?%ZHOZ!0%uIEe)pMgh=RyNCw9tr| zohF<$)ifvDX~miFtJIp>#-VoX>DtqGka|*uUg&M;OWzOuF#v-!gULfR!^oozW9WtP z7A7#8jM;5%!M_Y^<-fK_Fyj#;t-DDsOAJ&IY~Z+ zGn%vHbB6Qu7jO}mq|4N6xP`m8FFl|>mYz_Rr{rgNF1@6_!fU+42k9f#oloq1)_frc zi1>egA`1bfKvW^HCMa15=0b4Jgb)ZVg{2DN5FQbwq*NstIfW)A*{M|Qx{{i6QyONz zl9so=g>-zbDI+tX9Ll4T)PUMhYD{ga`Gwp<(~{g;YDe`%d-jzMWTB&vb>cmti-oSt ztaM{;>ds8*N!InE*Y&3F<3c~q`g>p?yG{*aS2vhm7~(_2d256;nrh__=2pfqcVaAi zKNtne^_=VrRCG&EY*^u4X=2SwI#R;!kN2Ras27 z^A~4MEn!!;jQ+pTa(=F_X$7CR(v4M|>sHgdvxc2-VJ)BQ$~w-K^<-g_KlqzBUD?dJ zC$_M!+e-gE_=oTDHErYbbld57Xm*nQVmJ4H1bg_N%3iXs?BlH;$$q}Crw(vOIY>T) z!xoM(6OMY}73!)0?xP&ac4-eyw#M>4i@|@R>Kf@r8RoMe?nHyr&C9|Fs3?GrzVVe5N}=+4&I! z<9qs2aNY|cg{1mIDBiIXnloJ(dZ)s&D}-|+JmI{rEgWKICR1d?A+q)wseOo z+;!m|XYSl*$Mk^NLko|X1&#b4!KlFz0wJYP)G!E(a2^QHZUh?aEO2N!ZYUb{wVaJq~nUbDt%D_y? zNVb!Ovuw!WLQc*KqL5UWsw+Y-6w{O-3niseR42-?R~F?gRAA-{6?sQjiC(BIRi(O9 zjUAynYDl%Hb)>pfT|Iigs?QsC8gQm-NUt;^+iA*~&`i^UtZPaCi2uJ9QH56cRcb^1 zO=?SRhYnIlsuP{q({-j7x*EFC3*9w6$UP0c=?7{Ckq2XlG>ke%8b=i-V6rroI!&5R zoo$#)Z)F~H(|l%2+*roBuv}V66;@&O4`LnPQ@4R$_cy(6GrevLz48y)iS6upYX^5t zJDCZ)up4_cd&#DK%=Y7e<{1 zm(-iu2mLVs12IT5m^>82G{ectX!0M@Sn4>8$7Ibk@^sBi@+{289BD3f9_C|-W*K?8 zjaAIuS<8-T6EnZq%zfP!dSxqlCw6IelkM!`Y_DM-y=gx)|8#)&J#mnI(;;TM!}P8k zI(sk+$3pbhFl5SI#d*p|B?8Xz$pL*aKyD#w4!W(Aq z4DabbNFS-nC$jJvU!;Ih`DXy6KvXM%nJYoaP6TDo6pWcJ1brw&75SN*qc$^9Gk{`jm+?8CM zE4j&ekk^opURQ|TPGQcRD8imAML8FWOFvVcD9N6w6f;-Ka9-9%1?E;NGFK{*y-}5W z?$ltXrluBIsQoWfm!H?y>hY#f-_U@*p{5a8Xl$bibKw^>v(cQn(8AD?Ue}6V*P33} zhFnw{zLwH zsi>al&%Q7K12M?LU}o+NVaJ`J?3ji#vonG--AH=f@ARfo%sergec=xqW0?EZSl+NR zjx%qJ=bkcwJki1=X5O02UH>wLx4(v|e2#yZ#=A4TG?RO}S@c$BGoNQ+J~K}(;Erh_ zGvQBZ5p}Wj7uDC6@TRcTu#Dc$a?bqQ3O>WMl9{rayhgK@?9@7T*W1{@+|EYM>}=vp z_cy(6Grg59%-z|_j;FS9$5Y$6;|n`@#}{_;j<x3hePm2=Gh z=imElaDjjQtz2a87niuNTqaw&!rT*A*;lTSb=T=lH<*1*xA;8a_7CDN-_zIb@#cLO z9&l#mA#+zAasD+t=5u`I32*tuQ|{Y&#@Tbt3$p1YGgn@5?pLpQ!}NyP_wFsWa~Oqd50;CFq?f$=>&-6yNFJqBK9N ze<;Jdu9W3mD2MV=C8{?nbMHr0mGAyNsmAyD-c{#2`a%uf`EOB^pXF<-#b=soGgIo2 z|BdSMb9+D7s&izw2-uG5_?z+;Gb5k#7z1`@; zxs|@mg?^g;WdAmR&rk-EJu#Sl(-3C9G?e#r!{~+K(g^Cvui$q+!l#&rW4GZI?1l?6uokq?8+I=&)PW0{NLz2Keuqfg-e`y>N0m+ zxx%?{?HjtzXFGL+UF9ZOxka{fn=>nSm^*Qoy?c1z!b8rSdc^L(#bbU}7dW-q$6hPvk?1dCM=7a6hRRl5xjMa^^xxhf=fWAJXuyH_~#?6Y1Eu zlAihhxc)WB$gh!|Oq`iAGjk^kJD$kOzMX8Gxssi8D><0^mz=z<S!^ig8xlg?s$9L|5llXFv0vUzOkuUn$93r8K3=9r5DC|VFGt_6X_>mGNww? zsWU9hWM*d;XS&(+x;gZwxy+P#WYc_R!UDse^o#KqmbkHubElTGE37cAq_?w*Gu>Kx z-8%a9*kEBJGf!>ejw_ovcWMi}rmf7Z{KMR-?d%FWq@7e{H`!BrxTEYPdutzeb^GZL zNC&A_jxZOF;+W>2*)&g{OFi=b9JfH_}_G@}4YwaN#3o!YAnq)lPsI z{C9<=fYiVUq6tb?f|0ERXC49}5lRY84I_o63K1+sWM(BY^C&(Nm3Qn!)sJhGkmoGA&&zLt#1KlciFpdh=tLiDD> z%-ku$j!@K4l3pmSDMQwkrFWtnd)_L~T~h^Sri#pTmFR^kKbWd~U!@w^ztrGur54%L zfLTK{mYPtTYJMR%lbTbN7Gx`}n76@iQd_FfUg|*A4WSo?YKD=ATNue~v^0h)j5kc6 z7ba>ZlZ7dmYM4f^n@K+lbEO4TVIls+U(!;lX(h8&n$={}T4uWNG5O~Y5E)SrRTGWu zN(|10Sen>mZ^YrA5Z6LHW{>l!}?1)SS7Kh8;U; zITO-L8K~}LWG9o9nJQ#KR%AnVDF;=^X(1OgB{x~fVj-RCx zRH39)idq_FQAtyotW+Ua)l?%_mugaL8EVtlHPolqHJ}$7T4>Cy37X;;G(!utG_<0( z^DAebXwAOThTIPA4ISu}j$}KXIMa2e?;>@jehuCD9HED%C)r9b=1Om}t}nfne#}k% znF#|iSTl?~0wbm0siR#O!`WDj(@Y>w`WKkY&uC{VXP%hGzA~LW(}lU5Df7tg%x7nT zA1vhVpWm^?d^dOgVncXb=+ zo!H2pFKpr+S2lC5Y$0#;z(4Hjw$X3*&<^%@O1r4SZtRivQiYS!De4*N9QA@57dgL- ztD0+M;kxD~*_9WZ>t52olHO2-w|Iy5_@MbncIq>`UkpFR;;;81FoI};kwZu!sa8TU z4~;MgD}|>jQOUaK^sy1w5TD*k0_H+OO=5Bq3rU%ok}-24IeS71q(myDMjAKLa-IPh zEo5TmL>Bh4`m=1j|8J3InaOPBAc6Isa{ZoG4_mu*?Rq$V? zBtNf}Qp}wy&8||0{H>McJ2+L2U3V(5qpL`-R3V$HGV`Tsyr4ijYB<9>s63&u(AQ`(#ae{A*?<6LV8$WCc zGP6^XGokbkrVQWLm9m_>Q=XmgO$EM_UsUA2E0s96Qkl7_3bSfns?I$tHJSTTE#9+I zo4J)b%zUf6@ZZtUZHzvcj0IOxJ5 z&ivvC_x;0B-ZdR(CY+E?Q_o4^K(;%%O9eoC5lCn^RtUi{V_w3~0ET@!<>O^k#@)+{c3;B>A1yE2bL=_5a zijciglzXP)%zj1*ltd{_X|hmODo4G`e;>axwF;_gs*~;1;><5Z?sjKXOAA&sGqwJ?s^cubNeQ>S368`C%!rb{!Zc4l(s$}G;U%w}$y z!%Ud_70u(bJT;#?Ru(YVEu{ZbvxvOdjlVcwie)yIGk0eNJ62XQ_mwrg<<2^G+*!|# zvVpAINUv-nD}R%f&17XO`5znGm~Z!^9o%3dK_l3*S6{_hvvm4S)s_8B>R7CE$6N#P3 z9*DxOuSDf7A(|AO>PigGm6&8Jv6y=zHv4wsaHhm1TZzY9iBC=-C8Ro)h~1=8GOCiC zETk}`rdQICb!q9HNY9>?jLd~h$c$`KcB&}{v)oc1YF-!eaVF%K3Q(OW$X+2oD8gM` zQTnp}q#W=1xAJ_3Qx({?Qjxi@RN}45sDi4fCRL{jwJg+TW~UBky1Mj!RgX7>h87wz z6B-+u&?`;Jrsm9Aprxi2`By`0dZ*g3+g8(#+!3ApL1*4nx{yuXmKW+*^&&3g3a%M$(BG79QSIF2%yf_0eTN>hr#vD*!BY#*m_0YVpttgpx#kgp$Hg?S$hjycCfd#h*pzeRpE8^hNvJt3iwB;p-c5_9g2B;50*WW1LgDWt4aT{imcnqp+3 zxKx5#(v8xbD`m*8l;ymfRFzr{H8j7FbG6v@nR7FxZ75oDDaOp!d{B?u^om zA?wD{3*!vq>4gc>M5-@M;yq-+keQ7T53G<}+RAGVUPx4~T3i2vxHFb?) z9sLH)M)D?UGu54c*zwdh?g-nZ9aJm3nD5r?B@6qc{Z!$Q;V`{&gnU$UoUEK63nw+F z$Y-VV)Qh-+tI{>9a-A&PFx;fSgS(o0s*i{aZb%*JXxN($oCyucv95E6;S@5sUj=`+=xFYK5C zB;faOhM(w#z=k07N>H*c7`-dOIkysmc}OV~HH;LN8cq{|>`Fw=O_7-?(a6y?vB*Lk zOR?i6B2 zSD3ztRFoFo6;T;gP}PNMoHlNn zyHba9p)Ts#sL$L=1Lp2DVn=CA7Mh{CrUltfOU_(r#ktU0YC|>s#!P67b~f5Gx6*;R z(vd85GIXKuYUoC<^du|2$bHbyFo1rbW;ofY5$p;h@w+sdDvZMfOvEHi#&ioanOT{| ze70r|S(u0U(gNy27Z!2m&SG}{l9o`HO3SFrJ+y*-WffUjLl)Lzonbw_r#5g$*+{mt zi8JMI@@5CNu(KUIG&{+FO`7n;*I8Nd$&TB4`tz2S$O}b9i-Jln4 z+PKABxQ)A-hvdh2rg=erX?R8d2JfT~)KAi9>K6n^$RGa^2!S<0$U;yAmqJiON};H_ z(DYWqG7pCch=j;e6l!!SCe>51xZ_T2cASXAUR=btkbs$zkSrvU5>vgEgu8Zw5ANXoP`R^l#1lasG_Mx zu7R2sYB8&Wx)$m&^G1E{H9$i{Bl;%NFVt3OgFE~)_HC(3JF=-gGgmrrZtBRalcqDd z3%a5kx}!JxqCW;=5QbtHMqnH!ViKle8m40=W=XTD%3SgSEVS__b77IRoVvoWlHSfL z&Q@c+=5O+5%~tX@?38v>_h2vfVZU^cDjYT(r9UQ}q@KeCT*7tSz#Zu>^`3N}`T&ol z$5h=@df~a|1^Jcqn)(*+@j?1X{e;i>f&hvBBOp}>j35ZE2}KTV2t%(6OYezr>0v&d^QR&ccmcbrb5h2g_#LOPz=Q#`k6gl8G0+_m<#0% z73g)9>8qfcp*np{O)aughb+`}p&n-qq{dV`O*qrFpci_gH>O|}R%5NSjw-Cj9_-cZ zBkT6lAHYEz!ciQPj#E$Iqz|3uE#(~96X)6Y)J5*-F44PknR9Pk;hyO#GvS(r>&%?E z!Jcr_aEsp8Zu6#jQUnAL*U? z%&zVWeSpOO@e|b)keMzpy%LnH1S2cK$yP!zw-S=Ml~Bx;&}1QuLt)tqrwLDvAVs7` zGDN1=MWJ^hDtk&avJ#yf1F>9)%b5_*MttU05-?X1l1+)3DM`peQY5pGoSBePN<~dA zrJ<&?ke-C9Z|LKeD8-KgCy^kC*rFLrv{=*wK!pMIcW5WOpd zIUkB)9{QdAQPODY7>vbu!z6lT3VEtDojSvTIqWEN$*#=fTsNOyw}4*xle}2-7kMd` zV}-Pmy2i#j=DLmau59A`Z)}nNp>CIUP?eozWf$4Bo0+nQycheW161K44&gA4;Hc&p zSvY}{hEw#XaZYode96XT=2tXV$=5YE$Tx8dw=LXdCfu`epZNpnAys)qev0SP3+gMp z##_A81Wv+V)36YfnJE~v;0S?`n$Tn+j3FGoJK@=}5`lR{DH7F6ROZp7=u}-y`s_Ax zFjsPtb-C!B%FV8j*FrvKLVl?LRVZko5Hq2$rYO0XRGez%XXYg|CCQ#D#T_R~vsXqc zOBKqaA}U#^%&dy0D%pu@>?zgBPSjw}RFhdfO?|S`fZW)DU)T|vNiC>Ov}CW9L%*`; zjn>?2gWo*VmVGDMv)4iDOclCFU8zDhba$W!J3Srf#muWR@y36n;rv|RyAgaxPmE+=H;P^u?SVho{ckpgpU+pu@|LH@ac8`RiOh79=qF24 zsQzIp@BTNN#?SXHOy_fj8PZIuGK=h2vw6dbIqX@P%iO=r+JogZt&f|rJH>IEf3sg*T3B1ZQWgZR~~TgUmo(dryg_XiS(5EO!J)l zwY=c7OfQ+~UeP=Cnq50@I8)w|m3L&}!#DPc&;RV9FYJ3FKvMoW0zdePy8$(U$fm%| zoC?CO5|k_ib09c7-U`9pkUkQMcful^8{s*(6Ol6^l7-03qG+O$P0^T{VlcB3lX+~! z@jzU5b@AxqTS&l6NN6DuGdoE*Q<9Rureu6xaz9GJeRoo_^DU&}bCuL&Q(9(L(lK`` zJ-ZpCj8t6~`fP4w=iE*X&T>k*sGi8p{{MXYUxPgS>)?sJ?0--4@qP0D7b(Ec;$I5# zwo-`fPGNSwcSZS*{-qdin~F2j{Y>wPlI+_l#hFr?>_j>C%KL)~yeU+aDp4ytP?a4! z)i@KXTd2WIsExXYdh|}zXU~ZS?CBcPH`X*E3r*1s&C$YzmYn&QR=h3zYN0i=Hg2@# z+^Kf#D(%U3I&fy{#LU#0nVl}2`9fFTF?DAq^f2_I|JM5O9o*^5&iAYz-_NN5?0RDm z_l97oG>mFxICDEAICEkod;aZrKEuu^&PMyQKX~7XG37E=F|7EzVOWZe>aWhvRpGUnb`&OOsg zW~NolzDKM1UdkG>e_P9E2BfROvQTFT{twlh-~FC^QR6xW5*lMxo77EXRq-_dP}wPj=A!lEPT*>BnzK>>@)9ukpd>; zujBhcAnpc65C?*?BLwrK;M~`Rp!Y^d?s+2=_nZpNt`df9B^+}r;hFnd1m094l9fng zS0ZyRL@`9A_myb8B}8{42Iu}MChyyc#hDYa*^7&KUP!>5uOT6yqf12Z3rTp#sif?> zl8kdxa%L&rNX@x_NW;5+k&gR*k)Hb*k;$RV?0G5+cYXv}`JO+bY<%zUL3X}}w{mdT zl#`h|x!4hMTgbyq$xBx9lM5IM(z{ZKb9aieqZA`MQJg(b{LH?t1ie$G*wvM$_e2@? zb!F+xp}eLd*;JXCP{l@7=1x^(*NN)v)sSjZYoWHG4!uzK2T_mjS^pbo%xC(SCcLfu zLROlQn@cUIEu~h})`m9prr(&gwa|{4sXem}noeY)vm0GFx6+llFLdJ_r8`;Zfu0t6 zF>|LkJKpNUU0q*#r9W91@D&W?Gn^R2o^CL`GK8!fMnBwv5$ufgq2GCHlr)+u{DCnR z#xfJeSs2gEG=Z6EA~Vw@W|Mtv3hzzzzzlY0dSDj2y4m!u%;j8}PZkzv{v=yj#N5tb zoavU(>z2~HvYc~otl*w2D>?V8RlFgr_Rt#km9=Dd*0Hl58~n*e-W4|CZyTGLD_h9I zR?Rl@cI?pXB-`1=nJ0F$Z)Fd2VXw5GdO&lKY&yiu8%MckI>yW!$GPVhC%Es4md~bM)?9VCN#J2jh>N61h7?HYKq_{G)JW%{4D4sr zWGAo2I&8r|*rnM`-iQ6t0qP;m5wdU$Cve)rS!TL(^rj2Ugo~O>WYcA4!WCRKT%)&g zow;zs#!cq8a9g@dRql}=;t`(Unc+3P@`n7@!aHW~@e!Z!MGBCDfA$>#r9f06uoQ$U z1ho*1nGhVI4Poeou$pjWA-oiks>CEKvB-Afai+v4Cqi;51vM4YAf1$+DrC@PBnw%P zU6X@s%Ein|ZsvKUeAN6l3Nlv;k&9@Gl8d1P%Ah)y~SZ^^=Y=>zqn<`dbSFYE+J`5ytPy1?{7Z3JVk1Sh)^l52_dOMXkbEPupPE=vfovQ5kLUrD$ftnU-GZX5#QJ3?2Zq(St$QffsNeno3dJ8}n2M{;L$vCx%SH%)i4sV_5E`f+aR&&-v9oLd>he25FfI8%m` zl@a9MF-rP_svASE8%M89B2U&#A={bC*)&Yo%pmJ#(a*Lphna3Jy>33eo#mXFRxndm zla)1OD{GlsS;u_6w1FyYG;E^(8=J8Q`waW(4;hZqE62#XqrTFjlO&7M++>`GnEg?gI$WTgSQAsT&$8uOjp`Gp;Knz7>x&3Q-Hf?jB) z`IRiRMjNz~+EcA`U~cNjOzA=vx*59D3q3Wx$fn-Rls@FX7Wy$0`eOhFIWU+VWe8ar zO7;)Kcvl%tPMw-RUy%krF^;bh$idfiBRCw^zoG>VxkqdE7) zAME?p7~c5ajO9D|(m398Wdi5QM6xi+pG@XmWeQn0m0mZUUYLQI9-76zFx$o)=E^+s z0vG<|OjzW`V$OxX3`^*BOX-)nu$;3M(n_kZ$_s0_v(`t}@s6^dyg}MX-K6=OENr&0 zh1oySHma5F%&qKTzS9G{*xiG@hJEzHehY_~=?>G|Il`IgC^Ov&dMhWHpVFKrpRsY4 z`8k}&B@36CS-HYoxk?tUS-8nexMkxu^E)ow<;--C*?m05GdwrEpnr*1nzv*t@0sg9 z)9b#_>jI?V&nFFm=!L+VpkyTkSqOBcq})qpNKT)^3n{si8n^g+ccLn3$x1qM24qAgO=fZyDJxZ%jXno* zO1Y>)9tZNWlTRu@Er`M>f?_C+pHV_nl5C|EbD@k>mTD@;th}ZI*-Ay`l`T|fRzp*h z>_jd0OtqQWsmED;G|)68H%3$G7pkrqeRCTvnCn{7x5BTQ*5o#5i*{&l=t!^YOt0%g zFLc-RAiL9x9ig|>muh7ob77D)m^u{0q!CnMq~UjZ-6;Cenm@?G7-=k37>|k46zWuI z8g)8mNpq;W`Sij<&0pjthNbk&r4>{wE14@h$)4E7{$6PxRXBoU(s8PA!p2GFzH*AU zbf@Xpe8Zs9iWXzr08;2|DKPpQH) z%?t8Nyt43ynef()cbtFJd?E)(%O9gPLCL`p0wFDgV&;j^>j7`Ps&df3TcXvh4QGNsZ3U?kgG{GsI{cpR6BJzbD}t1wM(QTb-{dXWihm5-=smHWeOGpHuIwZ$ zyU14dFc(>Bg9SI&_y;0mrv*Qm;M zvT~Dr+o5~x3HJ>T=uHoq36C{T$WNu`RN)0);k5&A*>UF`JIV*L6Cc@g;uCuT(*4Iz zR8v4^LJ$N;NQ5$krWe8@oF)=Ex)hTdTN9TYPl``XBqgRMK~f~Mker#4f@~!f^VANd zVb4lh=1MxUmGsPY8R?ZwITvagQOu;(@77Wxo+%--L=GfoM@d2!k|DW6DcDPCNJVc-%}hx{b|o$6o=C^O zlAf$&AiI*8^DI(UYBnhcHK!pLeIDdPK@`>$AuC16c8YVR{7hC#kt?FArW)B)otd4Q zoGEq4uGHn+RG*oruJilu2HaB`l9fheU1RztZZze*nbd-6r6qHv68%W5KGeoA=DOkZBQzt) z%I{>;C}yKAjAdpT&uo%3nJP@hG-*0jnL*agreA=C_)D{dywri^?5xBp!y5Ya(nhMX ziLBd7zY}|~7yEG-N2H_F6VgfQY23w2yhiB^d~Y1VQ5?fr3+I?!EcDsj$j-TtN6JeT@@Wc^y;X?2N@21$igM3NG3Ldkl2l(S z!<$Mua(Prj6))7_PEFL+)FU^L8d8-;qp-o1EoP!WiVM7f?*gTjid^{yD^G$UmDGO${%FY7-r+WG=Y1bn#dhH zSNY?~B+ji&VQys_b8k)OuANz&xiXt`-5h#lE?JpR78Yp!B%2m9`wL5?rBq=VmP;$B z%1W}Z3ahae>#*L1jhvY_F;g~^w_q!_OFO8$uv@c-yjOFOd{{a{Jt`fio-~}IKZopb8JAN7N^pXXF=nWq3_5yun+%mp)KGYCe;{AV8-7^AlMJ zh(HL8poU=d!4U$X5e8v3;mJZoL_%al)x;pjMFIyBvSUij%#?(gkQB+J8mcKB zvy8}uEK*jglAW9jxh>>jmKXU@36;?R4K+>4LLcdYf@5t{pAIYDj&(tr5pEC3B zB^Ls676d^x!O2Ppa!3z^WmgxTK7t`4y%L$ML?H`NHPOhr==4GiDJE5kOO7YSr`k!t zSwbW>B%yaDDd+AaXGchhR8necI;2MiWHe-=7cxs(s981H$wCerIhp6y8u8 zU|vuvL{$ottrTHiR4PUlic2M^rEHXDu9PDy<;fLL2~{*z$+~LvLUm1TvQWo`x}3RF zkDZ1dYRtZ_34K!w&6o+z(GsmRzmk>T$X(D?>PGEup(is_Z)T=G%#{9QD+8Dh)C?jI z!7z-FMpCVeW-g5J&{+0`@irzfpQxEi7N$uvslqG^vzgt-9lXRVypi5gg?EMz^q=tA z#!p%J&rKHsaTWwYrQlRMAvg=A2~7?og{2DN5MGKvy~6L$MU99kh-M)=vzUk_#i0uE z5FZJV2#KX6R9!N9Ath2Fjg*e6q$g)YW@OXkAPc!1$jwe38+nQprN4={V!Uu+AJnnZII3v^Ghvc6g*p|}FkPBKorO7= zi}_f9#aJpWqpp-zQP)UoslqyJz-Da4KiFnrJ2Tx5`d!$q*+UlgVZR?8;J$EBIzl~) zuK zh2x%;@XY;N0zShp5^~?2MC`bdnDZo>q-0$(dL=noNa+Wux$6sQc;{(dN{gs}NlU19mU8B)W!y0>XSPCGNmW*nb!+I? z+1S8b*+kwd{X;cvV>vv}rQOuM7WOea;J`t4oH)eZ*L0ZAbL9xrR!%Y3ou>E18TP*iXZaqc^USPVWUgEy`_*OMP_B@jy2`GVYs~Fj=j_H0<|g0Q z8@IUkBfHJ_H{D_83wL?PbdQ;E--QR9=^oOXo-*^qbM`&)f_*1mviHjHn*NO+yydPZ z-n0L~OCPys`ozpHK6BqceBoWE0%YUQ={@ul``!r1Ju88jn*uWvf*`051mg|A2+sWw zQb?*2nyiE&ht-55hxdaB+|@;-*F~a_?13okMs*_^=XRoVW{SbgTd}$8N*vDpDlTt$ zA|Ctk-AKT>E+M^;*o7pVDM`t?Wb~d$&i>bsg3n3mfmG~%&rFpHYtdI{B<_&j>u;Zzs z-0_QI+;`_BJHiEA#SPq)Zc%l&>F+pjmmNFzI1}z09?%Pq4NvHWXEvTQxATHCD=(QV zZ^&;oAIQo_vME4zejkUQ5D`BGU^|JP?)LXozlzL9dHRuf!(D@j_hgDDlbOO32+rn#5#X5_&tyIZI(9C37Ve zSxAjENNY$(ucRltl7Vv}6EY(Q@@Vps^GgM&LSYnjcZsSLBSC?{2< z3YDbF)GC^RQHGI)y{Cvgb^62`JJqcB9GSmLAEl6`B=j^deeAj6QqgMOZ+`B zQB9MW36n9!FqPgklbI{CIG>FP{u|%=2cM*HBie?hrS*fNDZlt&;-p5E$DTv=zq1* znz^^ya98*ZZP6Z`&>3COUFt~{dP%*hcKUE8^fmOO?=KCY4)nkvb_YvCsKQXqNU|^r z<1h(RrD;@UI@y&OoC`BC+rk`X^RYl$NEH@IOR39jEN3pP#9C<`RoEbHq$-=p!rz+B zWMvCk_y^mh?bIFEg}vB^{WyR_77jBr9c88*BcG5?QH67w^JLuxdecQ_$|dq;=^E9E zo9qdPic%n61Vd zX+3p=W+QnMHe;*w4^`Oa!gkJ-on&PfS=fy|*snQ277pQvbd-7=r*PVEmi`Lbs1M|n;bUf?BOXCNJloC-BBPo(e zDX1wmsmN(GY02r4LCQ$Ygv`i-teRY8A-9x|suUy_@RQmZMmuznI#ONf%y|!~ zH&xe%zAyS?fHaUgNE%F4hLT5Mq~>?BGK#E>B@5#)UYbBPO=PBxzVw9pRP&7d+{R1h!YjPS8@#vif%!*#L4e%lDm|h7= zR)Ud3AfzS~SqP0VQdp`Ijx2;n1VoY|Q=>>xsX{EoMqCT=m|2O>JP{IWl8}X@7LqYb zZX*SAcT%#G25DVL&zY4>%(EZ|a%yssb8GUD^CBPe8w$`{DagDqilC@ej9OeOK^00$ zrKqK)GSsq$a`crfRAyEkH8eHJwWQiqr4CtFk6u@wUTHvXsA)tNnn+El!Y?+OF>hh$ zNZ-lOmA;$QohtP3Kp%DoVi1OCMv#S(_}z_BoSQ~76aK(NX%f|)DeUN`(od77Q(c+K zxwmF>*UlWy+?mUcGLNjAPrtyhklxCl%oky?m;U135)Un9f0?wLy3(+kUblu`SSzig zuGefJZ_@lt-i&{+&9I%`$`0nHUCefC_KLY~d)gV>s^63HDq$ z$@wXqmCjRzi#9GXw{n@ea)qp1B`ep+!gbuhE!@T(+_P|>neae*NPUba4n1X0cy4$> zuX{-^yt43`neGk!TfB4N13MpWd}8jY&)oUqLV!H{9s@sV0+W>>WFe>&f+~bWD1=1> zL_{PhGF6F6j%Fb`GbILDh-o1fGgEA4ain-uB|ce6Ku#znq6(QbnaM&nO?GllS!NqlAUh%*vpwp*(#BR6-T0Dpjavp$4;>4%KF_j;20Y*MQziL*}~1 z^i9wdzi66~h305sqb2iJHhyK^8f`W0$fowpI=Il0Go=$*=!`Dtif-tR9_VH0O>gSM zOxKTI*PniX2L`gM3?dIU45QZ#ryuFi@9d4jADS^_VXQQcI#Dx;EKI>POvfCYYhKRd+x%3-qU z2s3XT`rQSzNR#Mo)c-= zOQ%Usb|(Wnri{#dEfa4#m6hEbnw(@O^0QX}1yLA9q@q+^NqV7_rVLprOD^X^dCrsy zR9!QAp@pF(eJc z4%CiPCu$d|D^=-E7J6uUl7(LAjXvm$eun<^rh&|aK`spDOc-imI5XWy`tg{6NzxRm zGL@`MBkQKq&yZ$O=VBffV4;OSnJqFbrvFP?LbbD$GhrE4N~@`+HOx$FnXR+1p4kR$ z#NV3D`Z5vm9w~D zxJY+$iT!266}oa2H^pu89v*x$>H`Hx zeu`gYfIR;rAl(#*`A-SVyMl^fWN=FeW+kKuO)B9KK}05%C@w@}?}eBm7OBKRTtfnS zLN^j|mK>=?Ix-V7BMY(`a?fYIDz4 zk6i=NkW?BOn$S&6nVmFe-vTW~D^hDsSK6XII*5*>Hk7Um7b8h!lwmYo8DkhvpC~4i z${fR7x;N$-7SOeY^hH>VC5Gkn6_!=Z+G@J8PHZGMV~f~IYTM}Bu}|zLmBToKV>pfz zzBtSIIm3DS1;a(UcA2hSp`rYg?L4}@|Lsrh7WY@Bi*k)@r?F^ z{tE%}@-+v+5E7v*p_y%A*xACei{PP%+>3-LA}VQ%#xA-qyg1il(UsVSICM|N<*t)> z>`n2Rl>~-_bS05ULYh)Ar$$<&7a2$;qZ^qx%Z#kZhFr*vd?<)Qq8M2mLwV+>>I<1ii*3=`?vB)T#gQ^ZtKnP!+ycVz}=%51|N`do`Q^L*h$DvMoM!hWe6 z%Q*AIa_%WB#7c4v){1qcvR-T;O&gh&&DbKglH0J|u#>(EyRk>?CHLWwI6^8%aSX?C z!g7lFv^Ymz#3gZ!RIVFt(UsfcF6rbR`v-U|o{-8@@r+cSd*CH^Ug0&~;H`K^nm#a_ zJ~C^c=fwMC@uFg`XUqOp2*BS zPi5tUdllkcCM7=tO6>EN~BWNQiHh;>WccL z(f|z&P3X2}?3$wm+FLp>ceHe3wsmG_>%y*^=uT=q=t@uYK|f1>W^Dj{kS_*vK2!`N zM>rV8&NiBzGRDDJcH<3`=#$-;!kKLsjJ-euj@Q(y2-5EGTfn? z?lRxEJYarkctlqoTb?l6p0ax`UXp(Ciu<-V?A{vQ(Ute&1L>)c+_imTr+gM)$glV& zzLUxi%TMNCB0zq=FB1Vt$lM-Jpf9_05$LC%%Jh9Y!ZQFg^pLX;#;Wtg>c^zxztSrL`R zHU1n#6?#=eb-Gf+K}~kG{HZq2)kS?n1G>@>jnLT8gx=K9jNZc1in)!YEwd}_ICIjT zy(=9!Q#zvyx{B^(5A?M3Vs_G>{Xky~;#?Vwp<)>6%5cs`I2g%plwmYo8H@3T33OK` za;8nD+orHnrec~K(>XKEU{+=tX3@3T^f`vPbdxu;X&$pO9}5f%>B=H3!BQ;4a;y}q zNZT5A$~v*0)Hcv>>SQFVAWF=>D~zXO#mUI>7ruDO`77~;)ZWtH8Q#-B;G^L)UHO8q_>O=D{^KuF z34xFZjc|y7h=?qrkfx~2S~R*6Q^XwWl60Z-IYq5RW?+io2oMVMK$hg zHRz^V%vxP~JwttZ12p^%jd<47nAu4a_F6N#(i|-uv|`s+3?!97mJ!UOF-D9fwQ+P; z#&b47Oe7~6Cex?7Fpa%w2D35;bKUUfOq)k{GM~L^0rNj$A@B9UBFj={Ww~JmU0Eqs zk$$n7`|hme+_au~gV;oBo9VVK?6&<&w)1gJJDE+pnQeR6{a@S5=V05%&bFW30S_JI zo+l1*PdiL^a)iArM>#v@N5{FZobZQ}JabB%CY7_6bIi8$>@MJ<;S&9_hpuqXbd6cL zjvFrAWUt&3cS+@;cubm}Fnj7LcWuwuJr^%X?KS-k-r^nJ8$Qr&pV-;Hu>1O(zVW<& zeCIh&{NUbC@rw*l@P7-)tOcU~q( zuEep#Wp)yey_5LtO$nHlM3%(NS`xY~DLW;Z3n|$vsSK&fz*~tv{GYxa-%3R@1&UaxU zdz%kCWf7JcR?tnWn3dI7gZ0>8*ht@m&Dd(#M&FJdmYvLgwTowbbAUTe4zaf#W_JWf z{oxqToG_fEn@%x1xy1eouHzPNi#wz%cRBlA_jreLUpydf57{Y?@Wk+x{tVA8FPKd) znQgDwX>aJZ_v~Ex$k}JZ7y4JrcV^{>~^ z=UQ{R)`H$rv?AM}ouMOL>Fh=q&bp$TgP!cP-t<1`XXsBKfPt1F%tJBUjgg#<7Guai zWi0RdCrskK+GP4aWh(F1rqTUl7SH`(n9ax4=FolP%^gq8TEV>1!76sHtl`YB*7A&P9XoA3eWTb!YMbfG7Q0fagTH5fp|=s zo-#kfOS~5E$Pbo}%%AYZ!8dl_#Sc>X=|X_Q{5m57xe=JNAP6RclUfM6EhIZvLU9%v zVGtJKEm4`h5D)Q@z>tuhSR^HtWQOE)TS|7R+(^rrlFpKzS<6f}Wns=?$;q4xxgF$T zr{p!{qnipaD+NU%QYnlgDCR;b_O6uWtUM}+ilkBrl|>a&scNW3H&th@f!d-zX=})? zk)<)S(!|n~xtXOov(iGeByFwOwH9qitu0+?hYsjy>BOvbb)y?+PP()AL=WyMJ<-e1 zhu&B8CkJ2<23v+O4;8~m+i-Tu2r-7Vjb%4Zj3-SKm?w%!q%y_9G%*tx4aj=%1I~zFPh)tF)%%-i(+BUkjov!R~ zu#?>$7xuB=?|}o{QI6oK;TZjQoaA}swB-!5JLfpJU1FzP!A;x}w@KxWxJzme=-MOt zV>~fDqbtwF3)1w8S$j>_-q1~-m_OsI;Tv81K@VJnf1kM#j58%TLf~(N^hIdSwJ>y3 zIA$e0A|RrOM4F;9D_)3Uh)Mr%7mLsFPl(NXd=rN|ei4`Zzat*cYw_ty0+EnZ5+kW0 z89fD3A{A02jUg>v$!N$#&*DN>_SunBo6;a8BD(tmtbXRI}rqn_m)U`BVRvNm{h`p%^b5lzTW~~+7)S6jqL)Y5U z{h}TBmG*`X^p5C+&JMb<>y94iY3a?}NAx56ivgrE5QD^EQW=3!812Rw&XjQ&j|ql} zbWcp;-egQQOry`hEXy3`xemP9DGMw<%uW`uH!WedEoHY%EGLx}4py>LR$(>PVLdit zv)Dpz6?@3NVn2Dn4-RtokT^_gN9e~4C+H_}+Hi*Msk7WwE{KbyE0;J^F5{}<8vQzM z7;e#Ti#w$00kiVh!BcjoXUxiTyf9qh_vJ6+CA(LK*L3BL|Z?h3-yP&b4fG zS8{Nc6S0%~no5jvFn|TiA z;u2pkR4x=gq-_y9+hTT0{-CA2OIt>FWjSXn3@ho%Di5sYj<$yWC#~gu?yTcnTTi!b zWao)Z+_PFzw^+!HUj_tFEexTC$MzcIX} zEAI^-=*mY2pV(=i>A&kM?{McE=il)IKk*9zit#-H0{>w_c%NSdb(AeM+r+TyWGh(t(&q=sa4TXJ^3Nx>Z@B~n|`Fe_Ls#-5pCLb8DPSl_FXToM&a`55rMQDq>`MDV8SZLj>8_OH z%vPRV1w$pelgjLs8V+i)t1ar1|CV}uETujg85+}@{sGN+ht`~KYr)P_ExFsu(3-Ba zL0h!*KnL!)(vdSKo!ECabfx!1FH3J`C;iyl`m@sp(gzua(A^oz`EW6U94SVTo*Khl zCu7-<|3fD59@9i-(;x-gBsHl04(Fo!-D-VWxmTWIj1FA|GMZ3*49 zlzACeU?tXIEjC~yw)kQP=gLm(7JEqBUUu3(x@|u@a?)^`eij#T z#c+-8sOp0ax;o|Cp0>`X72Ux~Nmd+~u(K3cvrYXOS$ zy^${hajyME4{Qm-90GqMq=T^RlyHcGsECG`A{H4(#3kb+0TPNtWMU*iQlvmCq(KH3 zGO^Ew9LSBl$d58Ohue6Fmv}EelFC;ED8a8WAuvMVZ-hb^L=#@5r($w97GfiwNJu6| za->rB9 zqY0XdW~A1FuCzpJLmPSrbVMfyo!NCk zS9C)U(UWwg7iYcE*BAXb_p57W8Tr6MZ%QDyE|MK#p4)Mi%dp#d79v1mdnP0Hr7O`812GW?@em&gkw_#a zl_Vk=X-dwV0;!N1X^y5>rn}RH^RA*h*#kY%3w?YsfOBmyT^mBzhSFUb#+j25?8jo9FUE7OOf*cU z+orNJO=mXEVxDc8!>o9_F^{wPmIcgyv5@m+qfg{lFB1I6)(wGc!Lk(BdL70d|_68h+m`8gd(CSSpua{7UfU@ z6;T;g3{~k`4Z2cO)FPGIsB5T4Z-9nqf~IJW7NRBD3T@FI9Yq&X>q8%m5n>EE7UMBR zOeM8xbY-TPP0oRjSW2$K8mz+>Y{gFO!fx!rK5>9Nh(qEqc}$!jl~Xu}E4YelxQW~1 z4*5_#C700w8lnlBqB&ZkwV@4N>41)+Gug#KS9aY*U$P(i zivi?dF_d&=7-y#8%p=4oa*Ttq?38hq@ywcVy>zcXDu^ zQ{*CTx!KwBuyc~1eE}4-6k=9Np$z8x!2<5u7P2$>Fl&qHre(~_4J+uYTv*LsS&MaI zJ-I<_BsV$O%5J;ZLAtV&v)$N>{e}bdgE%CPkhY`jju}qSwNrHM4Bd2=`TQSrfp?iM zGMg?j`{pWlY}eQ+H^fcy7H;DX?*68GJa4+stUaJB5AjGmCZD+Ql)ds=yd~dR-ZR@i zuv0!6KGSVq*(u-f9X~wqlRLi*0V?n{69Ewj!9@r%B*G(tAtF68yhKb=iH$gji}*;4 zBuI*sNQE>=kIcx4T*za|$E*}YF_d(n6nj%?<}w~A$DPWkChCz5&>XF>L@XzjRal3O z*otk2?ev{EgyT3Z&XCGkQL-YxmV$O@kIv|gJ{XK)hT-&)7>g;Gj+vN+`B;c0SS8kw zo5c=tH}+yb4&X4(i1Xw{T*VD>le~`yc#4;Jh1YnC_m+>$$|v!S)V|YgKiFvjEAe9t zfe}Q6CnGqB#4Z|QBDRP}DhZHKBqfzJNQd;uATp6oGPBQutjLa>A{Ut#`H)`}Ad8|T zN}(LeqarGy3aX)|p%z`KjXJ1{`e=a0Xo?o16{)mF8?;3`(ShuOuIPrIqAxi_3@4Sb zn21SY3aL!RGzZh!DKiYS=yQcPsm!y?XI=mwv6xhrUamAj?!H@!I^T>aE5L=%dDJpaE+aE12=ICw{Zt|aS!+LKs+QLYyI#qY)aT37VoAnxh3;q7~YRwq$!t2WG7ky)(L?tLRQDJ$%uN^FD?F^g$Rd zMv|j22IDZnFp;iI5|ha(n2PCQ2C2*xv&cD^XIMyAe6R$|#By?lSVJo7u@RdMTj<(0 z`Y!CjejLY1oWliN#3fwD6xVMrw$A|RR}4m~d7BY{Xv zYANVxkQP~x9r;mElqSod0;*vY#$u|NNzTO*2g}&45G%=5Vhy>@u%51L#3pRUHtfVc z?8gBd!eN}pC0xN(+{QiJ$5Xt+dwfQ~8vH#&FcE?@g=3B<;*(k;x{?gZkwT;-O{ti* z)bunWJ(&%;L_V?*ilaK}pdK2cDVn1NTBD8VM0Q6H^uYiO#t4izOr%f36wJUPv4Y%! zZP+FDlKaF#@+eN@thhj4!WCS_P29p=+{Xhv#3MY$6FkRD@tS-q-jg51C-O6XAW%*I z_Yfh-Pzd87EW7X`0vS<6B9+J@3aLe)|S74<-t>U@0 zSceT_6S)~%uoc^|-LQjh+s#hfLs#~SeWbEq942kY*_{&S$qTrGYvMY26Sr^&cX1z& z@L0ScU*ffROPby>f56v2;5+a5iC-c>Eq+`h93mhhA|W!O2rp8Jfmk9o83*wY9|@5J zNs$KWkkOEtu4F|H7Izfy{IA@sYJJUF~>km5t~%v zBA$p(DhWg)(v>8fX-VmRk(~R!Nx>Z@rASStL0UsPdU}z8%!o{e%yd&0W+ki0MrOC< zVAgWcmE6eVATK*xK6Xle6cB|-Q(uD&#Y8LWmIvYI(u79 zcC|$v(n($R^$ZQ@wubC%jo6tQGrQA-b6Zn(S~Gfcv_c!vp6p=h$ZYDw+(mRHyP=mD zN{+&4jCU}RoiYhi#Y}RRm_up{=nKUn(zJwmxmZCeE3pn6#3pjHVH@4FgIU{2-zD~t zd$A7(a2Q8%0w={8@*FPU60YJJZsIoX;GVconjSJg#WV4o)Lznk^O`$v4Daag@c};( zxXynBCqsxZq!Je45dl#gL}lljXxvev!^;wbIhKe`x)Pr=PbA=;lF*Wf*;7flYf8#& zOUX`2ZAeR3(jmRbNM=SBOLpd*$c=o+k3tSgvQtW<9Ll2tDx-?1Nh){WybQGP)F6f3HhMx3Z=ws+h?}q^xC|npku$!*z!9g6tVZ%}S zadCn?V>nO0ATE>I6}oa44-vaAKmJ7m(v^gqxs!_v z1juSX-Im3L`aE|WIdCs-V^eeb3u93=h7jCdO-D18i?vbVk%*qoy zb?}_s3%tZD@s@liK9OG#v7UR8Id>%rXHKHBSE9KPoxSEokA(zCY)QhL6e*DksgVZh zkQrH!4S8KCz`hWQ_@XH1PKvX4r6gx%L^-lNDxeB#iMnJx)HgJs+ZwTJY-mDnie`q+ z^seZEo`zm@C%xJCL0|O401Om^$iWz58Ol7&Fq}R?OeB>_n2aedOl3a}(=p31hpx@1 zFEIGfZHw705lhKsST0tQtFT6FByF47Z56x8y_WsV2gPC1$x-&oahx!mq@OaJp`XP$ zoW~_`mAo$QlJ{^Q5AYaI#53|aUWqs4TfB4do}KampWOJ&*?0UDzepuOeZFTE!Ab3J zdT4|d;mHVyh)9Tv=)#MPfmn!xcu0(7h7|OamQ>7IYI+)xo>Ve8$jB~}$U|z9z-p|)Mr<~0qwl~j?8aW~7YE2=;skjT zr*Q@sa0!C{FG%eb zU3)`+C*G4E@JW0jwQqDMKiDe)8t{80A~2~0K~RK1NQ6RYgb`uMD2NI##6&E_770it zArcu9(~}{&NJ*waT4Y9UzZVHkmthB5T97>^n7#yl*;I;_WLv7J6SI1Wp^y&|Nvpne80A^WqYD zS==EbG~{a|q9X?4APJHpInp8nvKq3}wH$O)E@maSArC#D$WIm!g~*~P?m`LnN+}1W z*_Aihx>Rg zUXicG8&Y|P_xOZw_<>&t(uhAJAVQJ0uWQ4LTtoEBBVh&WJXRDMsbuvWmH2A z)E0F}r2!hDiD*VPM;o+5M|43~(Ua_re&~;ZVgxx7qcILsFbi`q7Ynfni?IxAunAjm z0LO3&S8)y3aa%kjpJ8_6paFagi|NV|tiVdKid=)WST8n^o5W^vi(wo62#(?ePT@SR z;s$Qw0bb(`-s2MjHsNbNf+3U$ONK`jBtlY=f=rF{A~Ts2xltVDP!aV|9}Un%G$UJ~ z1G=CadY~WrV+clL9Hzk=i^LLg8P;Guwu$ZJ4zY(kh(kDzQ#gk!xG8Rv4=fLvZI9V0 zPw*12#T)Xi_&|QbXMDjod>21R?H64M(3Jl_BEld%A|Mi?AR4?78*vaH36Ky;ky4~1 zvmm?3NoslM`A`4_Q3!=mL=+{9SxPc1Wl+vgo?gLHk=a&>U1d>)tmc90+%eT)u8CTx z?Vvt8r2!hb(3pJ_LsNP)G`F;3ZY|o9?a{%|g|75KPxL`Q48TCcAo@@Y!$^$5B+L|Z zNpA;>*sa8B2W!}^Gpwg88(i4Lev8;fKE^wIM8IbM@fR5s!4U$X5FQal6f!Deh*+c+ zn;r-8kpPL13@MNjsgV}xkO7&IQ{*9)yvT?AqA*z;rBMbIP!W|-1GP{W_0b4TL{n00 zNq5qQeS6V~?1FCSj$WbwiCOT*JS=dqke!cMOlnK$ z+H$(Knr>RdtgOQZY{X`45!=WeVmG-L`waW($^je{hsmQji*vXju8>!87mwiGobOGr z06ti4SWn-G&De@<*zI5sJ7q8SiT&hZagscX^SFwexQB;$isUW$v4^zCge=I4Y{-rr z$R%=~crz=f zaSadf5RWWRnU&{wDPECp#e4Fj;S*i^LJ!cAf9??k!4VFT5gjp+011%{$&mu7kscTM z?;2zzl`P1Ld?<_(D1|a8iwdZMYN(5bXo3#tjDF~k0T_ru7>d!DhB@$t4_0G6wqUO~ zN8ZFEJjWZn!v}mprdE88A}g64IgwZ7BbCA^iBh60sgy%`QGrw{8YNlHQny z1@OUQEWt9df?SF9*of`eE%uW8#D4M+4jYcq&)_OdU@?Roj*%FP31T8SNlYVWVm9VtK2~BK zHed@*;v6pFGOpqVZs9f_;u)UfCEkd)r1B2$EgzV*&-5>bA9U>}{g)*`8~$D*p!kc_ zg44qy93mnTVj(W#BLNa236fcoGp9f*Luz_jq(=q^8QEn)ZsbKi6ht8uLvfTqDMNXB zMN~mGQJvIk(rckM>Y_fH7@E?Xp}C<2U28*E+My#lqYJtldeF6=bfp*iSo$&dHw>T; zGz_LIBQORNFbCdP;9w!UrC5)R*o5uaA@-ApaRjGu4mWTQ55-gRrFccYHoT#Kz$bhc z0owBK0t7<{ghW_`^H6y1DNzy412MUy#IwX_HYH$I5+N~?AekXKJrzHsxWf)DjjbW#arQ61_ zb25SbL`*VFrccE*OvenvOuA_n^BggkRJ<`C3oJg&+9LWAEXQiB!$!j<`etmw4(!E# z91w>| zQjv^IVM)oXq!OvgG$Jjjq(_E7AQSJ%f^5iP$;GVXL0%LP1R6s>kK~2;`Jv2lUG)GIcLOXOock~v0$$nxOITF(_6N|7K zYp_LZC--8XI7*(xX^&8TyUJgN zAawr-%5z#U`u~OCd|cmz;Ewh;J)|3H2SPo*di{qiV z+|%OG6N@CIDJgR@k(|_0(o-R|$Vg^ER*{2rB`0UO40-5z4f*K#Ed`kiiNfS?jKC-{ zhMa&&Vlp}951Y#Sv}yDim?>tFra8>+%;jA1w#;Kz=3}87KAf2rF)ubOp*va1Uc11r zgQ~s^%f$-PwvydC%Le96*dn%)rftlwZ0BsJgI(-)V-NPav5&KZmP5?iVY+sN?unz^ zJLbZ1_9t*soFY$)v!s*r>|MFQnQ{r2#SK!qh5H_Oz#ZE|c8|nk()5H`drG%GWA_{{ z3@_=g#2fOx_&_Qj@mYK&zlk5D^3(E*SqspKe-9y$KLzEvU=BjEa}tVuXhT@K7LFbs zkt|V|wW#!Hhz>8rLR`dmAtC!jA~C5X6Ddh84P8l(3?d_$$ro8T*Rs;HA-g~1XG$D1G2FTP1!d$w4^JoMH|x8mbtw@bl@3VM|Mgl zF_WB&`B(@aEEda1+j4fkS-~CCDrRLh);L(pPFZJJ&#Y{~MzNXPf~{g3xkKzCcVj<} z;Fvf;x^t3q(*@>#!$m&MC0zEvRqk99*Gb>pi#t@0FL^edFJBh|VI=n(T5Ez%)9GKx&3mYJRlxea;f?&Rg%H~F}u<)Dx#98Olno>N^R6ZT|+&3eKZt}NTo5FpedS* zmSk(uj%+VFk=@W8JstF7r}RZX^v3`UvJ7Un4PocXP|j?_*^R(x!&tg9-i1l*ryFL_ z=eXg`*#ZX(+4&e2(M^k)U0K4JvP>)|SBO=lwwAsQ8?X_ZuoXMSE^;sSVLy)I6i(xk zxI$hv+@RmbLp;SZyv93xL69#05tIyxaEOG+h>qBZZ%9B-gd|9gG)RvuA{&|0kei+d zd65tKQ2+%|7^P7bl~5gZ&acKq{G#899&>xkMf^AM&GsC`h_em@};iy(o%_;$%rfDY~gN zb2(9gtc)tChU%gQSyR*|>!BeUqXjylGX`Q1hG3`|PL9SzOv7}{z+8A^5w>6}_Fyj# z;V6#dBrf0zu8Hg9P29p=JQmMLU@jJ7 znb<^b#V#DgQ5?ewoWliN#&z7neLTT)yhQk(|62s+$nZi!q(XXRLje><8PrByOu#hE z$6~C&YOKX}JitRd7Ej2hc!n2vkB|6R5CgFg8*xN@ zGOrdSM`jVz`5m?8b@7q%sZD zF%z>e2XirBEF={l%OYlFv1JLfvP`TXS7Mb|O|HRu2OHRJ^u<=rw_&G)UF`O_u#dg% zAUo|4T{}!af}`R%c|x2fm2=_(d0AW~uj2-8;x_K%F`nZU-rz017{1cKi$J~k`h-x1 zFmxp>B3L3a+aj^kBGWZ5dOVScOp4^lfK13Ha*_FvUlbsfLMVcwD1p)_gL0^3s6tn& zqB?4ehGbLGj8vMV721flWCziaR63(8x?>OqV+2NGEXHGkm`F~+49v95VxB7&kPERG zOR-9Hc@6pKru@vNg3L-`QH1nF zQSK?l9294#m7u#*l5?#T-AQToN?8Zx*xAanbEN`jzNyF^zo^9h%KlV^=d`Ny-%*3- z{i-I<)UwoOcBKwyrn<~ZJrC9Ao+}MFYv@K}&YJv&raars(41~+!R%ixdDcm5_Wy=9 ze4NgrE7?tSCzT$5NKfA5U%h$u|0jL;>rwimzhMB~$w2nXAj@E8(-3CUP-g!c#5qAP+F8BT`9|%tsFbQD9`;rtpe}-Q!4VVN`6$C`>s^s zOsh(Fr5b0RsKLFOs3Yo=t~B7RiD*vRTCg*(sIpdEK?9oT6d>78BZ!oI7aC*9PG zxi9*;(4YMv!w|YM6vHqYV=&e*fj&`8B2CknwdwR3elU}}v&0-ynTz>YY*<476PEHG zZ5e$zR*F^R?^w?t>d2Is0V!%={;P<$c;Wy7ry!&QH$&ul(X; zYXSQ4`)&yMF9^)X@QWbaw*_VQe=QiFgOlLw{UbEb`6di^!in&t62XOt?43kn?@naS zqx=C;d50E_?q!L|ti%=-NTnhwxloyX6+=~eHPmpS4tu2m8ln-Jh^C~{94!nj>8;UT zbRavT6S|>0dZHf&U?2ur1~WSu%6>RTic#cfF^<&6)BS1!&$u&@b7c}HV~Utcnr1L7 zGcn7JIh-kT;f?to^5LFo5wo)FU$mT$<*60iRaRoP3v1YGYw1qbu{UjG);7~UwS~L3 zt?W$On74}^q_R`&A(g#iAGzNT4szFah@I&$^AQ)0v9}#(=i~(YlQ?BL&3wjra8=W{m7g9o|?y9(*ov&zVPAPokg54#u5)K<&Ix0 zhSUC|T0L~pW>=u7s)01Om^$iZR=ISgaOSaJ%cV!D_~nr1PZW-}{ugf}@4 z^DPUQU0KMP;)A7P1-TMyu?`!=W^#*VE3>i&XLM_ zT*M{AWx95au3X0r+`?Tv5Kl(gB%)cux?@;0y6414T^hA~<%(kTL+)2i{k{l_J>K~Gp_hvyhOLpcQ4sxN zp8FjgdH%mmCq5@9o!NJB(3RbPgKm5te@b`W<)jCD-}K~;((514hj%J{E&Z5H1DI_C z*=d95%1{jdO(S^THj{gEV_U*bS>}P|-1#@H;N$sbC3j4#m{()1VI5sr?_evtZP@O@4)#0U*u~i% z>=XM*+W~g29OO(pL_h4IBiyqcWoJ9a?xZ+HIyuW;IfwI>3(VR@x^me=SGcFV7l8)x z^DKY(i)T!MnQcMXnSwLhLa=iZihbxmBnh(Xt4 z(oJ!hmH37Pbl)W8j*`fbgsvn*a*={GrDRTRNJBTJWmeLO^rS5VJ1ryKl}wyD$;{qK zR`yCZWEVL|C8r@5-AQitd63tTk8aA(tQDX;Dac+cME6u-?*5JpHTlbpfP?vd%n+Ea1Qo%^5Qe|$T4;J05tg(?Viy@v z5Y>%noH>ckUW-9j;`kyS=kW~*>4`*Q(v*Z*Ns45KEiii?qNl}U{V=2d6 zUQ{3}p$e)Rs?kl=nYG&VhN2PK60Oh%9ncY-ai0JFKv%Mx=s_wy(OdK(`xyq%2f8qr zy*7kCR17EG8O8Y+jP<}o?o2XFp*xwzUYkyzfte0wu~TNl8}l&V;6qmyV~Gn(+1r+} zQs;8teiJrhtKt7KZ`V;-uIt|Sb=r#Et=M8GHg*?c2ezUJDz>O# zVRxfqfGu`mA*d({Dz;eI*om#r_Z;)M#&eGAy+K^>+WUR~_>AxGIPcrJ_MUqhYp=Zz zvkgbsXH7!6V{@L*bYa|P;k;cixx^iTE4Yg5;wFt0x2bYR+@-pE-1qU&f=9eP7Eft3 zUf?BO;dLzD@UFbYJG{py#Ne~ZSMKllA%0Oqf@%D@z$7tu5=~OJE*ZBjC3k$J;(Kwi z;&UZ6(ulM)HtG0GNsmk>nYqof@Me~kw`?LiRdOP?$U}8`xt09FnifSdVMCP?CMCIb zrMZFLq)c(61T20_kY5cA6ErcEvU|$t_HWECfm+}2D~W^(KrrG_{`9h ztu#j~O>4Hno~=0irFMM3eLQvKd!2+MReD&^leb=?H;qeQKJO=-=s-A&LDa>>m0KC| z2gCT>FoLa>Z_85%Cc+CX1;-T?mPsAiKnd+u+8@$-cEHRs!&EajXW*$2(^ZEQw z7VsUzBKBgF<=ozym2AZaYfRR1>(+BCzG4&AZQ)k7!ykKbPz2D!IDsHdF#8lja1LQ2 zoL&@{Xap|f8m`CT2A?T65sBNlV-m%!JQR=UV?4zR@ru6vgZF&?0Ut#SHT%rl7tIg0 z@)N(1a611P0umvyNJ^856x0f7kpbC|6S-k63R0yIilZDVq4FQt@_7|aRkooTTd9s3 z!j9@1a4U_`94*jNw5IlOKwGp&Cv-tKIEtRM51cR%gWv*J42BzqVJzG+5mVuXnHJ3E zZ7vpJ8CGB=*1#8=uwCq=yRi=eI4X|Q6F4nG=ow8ITM5S{T){Qm5VxojDQ?rdn)_@+ z6x;BC{mA4AcQl^k1zzE`_(07*@)mQ2lZaMjNz8 zXY>|M)J?ck4@|-oOch>qI%Z;)W;S~c=7|M#F_yzytfH&ogEgA9?Dg=)RS@|h)% zcz>*U!hR~A(dXg?{Tna&{@;4Vk1@Pv$HzOq_Yt2oG3?Kp?`-AwUq~>EUkgM+8Xt-H zo|0H3p-NH6;wqv)PS9+ zO?7p+>x%}|(2%V(5>07yv_LDg7WUNOz;2HY=w{-`-QA=Ix2`9*(o6KENCL$4y7kG>J_#(d3Uq~^VpS!|}Dyfl9WTe@U2l+fG^Nc%bJ_weMJsA(%{H`SD;-2f+R3CdcURGkD&5fo zJ<$t&&`&r~R}2=z=~ywIPJkySVX~M(XJW3HNBXA@Y7 z^i;`=T*!mGutp&i6~(BHC`&7eYP1&YP#5)39}Uq6jV)-xTXRiIw$ci%VK3TH2XsJ3 z(S<5qMK`K+*Ysd3z0h0qrA~0hAPm7!xQUTe84Gtz(0H&FPce~B7GBgagKe10*3IKy zfQ4ABS;}4pZ>+&utb-pmh)r}ewu@c#h&V=-;|SE8WQT||R0+pLT*hrg;W47|4qxz7 zB%a4VCrBw$QN>E6p=ps3S&$7mkW=KQ`CyHLC;}T%l9okzR6s>kM?Ew|W3)tTv_S`S zfis3;6ef!~bS@TPAr@gV)?gcUY4)-W``Eew?jxF`>_BmX2ICAuaT!_X^WQV9VS~!3 zg?gxuCTInF3)=AJfVP@;Y_kr$={j+DMi)4W?o{bv(u=#d=tC7J3=pn#2;49X!!arr zqj?`=;?Avjz!MY2B&wUt?WLK@4TsoAaSCT}9uc^L8@P!` z+{1l5z)Qs7tN2EBKe=_kxRu}HpN0IHPLqh8SR|)uM0%PDc~BTdMG0COWl;%LVTanN zr)k1&1_$&OeW;-y+X=(r4i8Mi49vn3%`&#K0_(65JFpjl2*DYI;S#Rm7Vh8?qVYn! zq3`ekpAdu3_=;ahw1~eSNQu-)haAX_JjjduutotCG%3Wb6h<-Fpkypc^IjI^PyrQD zMbxB;TOX_E8)Y zfmAtxAOzziLc}GiMBuWxO0zEhS3ar~KtWN6mO^QiL0MEn6;wkFG(|Hwpe@>o_EhPC zesINLlOf#RSOp)khU(UF8~oUtuvy%q(Rhxxc!&4+h)?*2ANY;LOZa^R$&dn8NQ+D& zE6sttutp(Km=;5EltFn^K{eDtQ#40g(SaH|vb&)-`oReU;EEv_1}{v*Jj};Ztio#e zU@bP7Z06pAZP+IcQ{@Cs;XJ}{2@$v*i+j8)QFwrd;t|z7<~BTIE75o@K2zn3<{SGb z{#nYeQ%E9`QY9IRiW0OWN}(LeqXH_!7F9G=+0{@JwM7GJXvkKYpedT6IohI~NqcTX z2ezRz+pG(3N>>ZI@n%VP-g}^@rWZRlz4@#U`fB>KoiG3c;j9_NR$PQDRfdS6)ZoS* zh7n>UwPY0U%9y|4&UX#t*ai=_CnmMYS)9etOH95zv3+KLw2n(+8X1K~$ zuHgo5A`*8^?r|&kMHGF2hj=WWP~|D2@d|J7L42gTPu!pJ72oj_zmQ-VzZQxlG%1oH z6|6)WnilDh9vMtBac4m`WJeC<7I|o1k&osV1*lR`6sAfMQJj`US(FzQXeHR9I%=R6 z8lfp#q7_=hUbLZY(HB?u_ zOdPol-Pt|S3;o4F>LLcyAs7lbli}RT2$PZA${5Xf_Czs>PJx%n4DOkjh1r@pY-KLy zV-c3XTdb#wFZ{3po3S0cu+M`1yd5w($gLa_0n~7qtsE66Xb^&N8X-7`a9qSyaf{x; z1M!e5kMLMLqtEdgAMhy-F?{wJ-;iL%zmiZxQnn!lJ2lcGgSf=cw~Xw}$Rcu3B^Pod zFY=?Xu%Su`QHm<1HRae!MN|^Dw3?_+4Yk;IsBKc0yFMDA5gMa8S_*rrv_V_67oDim z*`zmjAM}Hh7(flqY!?j15DdjgjKXM)#dvtY6B9L)*oG-=#T%=z8a`NqbyyESY!Dmi zCJQ$6wpFu@?JssvWv2yuc{4k}+d&*cfaVC>aFnea#|aTc4Z&>XlsHX8a88`3N|+{` zeF2wn8CP%>*TqeG3z4`j?$Rhc#1lLf&uFxGL*L;8KH?L;i0|}=1qr?RwHzs8k&<^q zDz=qLYVI_ewCoJXB63kBKdey*MNtB!QASjz23xjL1=U1#s?-oQsZtAesExX)henzv zY_q1k>6&x5f<4-zqv%W>MGva<#sD~*xNz%Sxd+2djG!ZhI~|7!@DP*e6fu>0VTNWl zTQ`SWnJ1Rg6WLLwsHso;s^~y5Q1?MXK)th zHR0?_xPqs6fj4-I4~P+;=~sLc-{}wh!fzy8`LAR&mBxylTBN5+22Dn`k_nk(k(Kvs z$f?Q2&TEp7J3oqOim`Pixl5xA%2`l>w~C@NwbfK-*A#VVJ(K#}N@Fw?Eop0EPc3oa zy)D{l+Os=|j?}CZZLXn0} zq7JQ#`e=a0Xo41^C2gg#XB*nF|5kf`jG+TNHXZp)*M++)x@&r}m0p_O?EjWN{I%kv zFW)otWB*U+&tF#=AO=!1XWo=SaK&KZMu%az7)cGI*vc3&jw&8vBAu%7Vowv(>1@o$ zLa~@G!BQ;83ix0R)?))Ui!Ib2JFru;i@g{7#6fyU6Tm)3?3hVPo6?B7VdnqPx7$=Jz}!XzcP z&Wbw?(uwp`$$*T=B(l(4$c+Lfg}F<@7F9(xS{*fn9c_f>ut$3fI`C%b%yvX~lOEhX z(F?sz`f}@>xD5l@&ccNb#t^uP5!4+Mga`G+L`=dIOv7}{Hkre%%*SFZ70aly94p|B zmGFTtHkxeW-h!=S8&&+pPPzwsaR7&K1jiAG6F7y_;w(KU&eJelz(rgVm#K0UH*weG z9=CE|L{a6Tctj0P*iZ2c&&3P+5^wNM^O3E57GJ3H72oj#KgDmFz=z*wMGBeYBx+{ljtqA)cSVHZVlVM9xy49cP$DxjjKGTSy5Re7&wQk~mSgRRs=9n_77dVHro z8kjWXZYr8lr3G4wR#a)NX~TBVv}LzL2a}H6mUQO53%a74i6eJ+^bozMp%2?IfISe- zaDf|!iBZ%rnr(1rkHh%C;K6q-@#I~Zf~mrbDl^0^I@@Fp_gpL#OX*7ZV2x%i+pv!P zC+qo+ukfRmY~X#11>1O2w!Q*1cGo9r^IQhgorcrEJ8Ks z*}5?9*j(hZOCo|^(cEAwk(%3V^RZh(fGMr@@inu*rb9&OMT9newJh22$jqmJl_zUU8UxWEk~FdAdwiAfqS_AJcD zA}qslc#BnZHP*rxe%Oi~nw@NA7xrlOvXy=Dw4d)CLI92+2%)%y2yvBO!>xFT`wgn15t^a}TB5b49eb1*M<-!2reG?(Fb&f&OU$JUu?(x>3qNecX82>b*hBYX zKMsl`R0+f>T*GzTz@7iVU4D!u_jp(C{})8@*DyR_Km32`5kLNKJm&kBJmKAvr@SlA z#B=&09$xdEcmE4M@UIbr&*BSJzQ*DQ?>|j`asQ4(g7y6QEe?tJOqZBDDUu<%NI|WT zMx>+ZH5u5tjNGxw#Amw9+*$rYR=)eUa`IzxiQM#0^6;Iw1d3BJI0GibTYg!4bwF<*vd@I60@mc9(%r6Ko?>uR=^vp#2V@={HU@)Y^0m8 z1zX{d9oU6EVn02I!#IND2*zoIXhPY#bKK_K|t_(GL$_<`R@>c>ADNRAXpiBzycYNQnz zXm*j4=0biHMlsl+1j>lAv;r!@7Bygp+NdWQP(vej3)rI#+M@$HqBDA;H~PW}&Tz$G zj1VK~XpF&FxN9b|r(mj>PUm1g7Ge<=V=0ztRyt&GP6c)$~rFj-8YQ%$_Mm1(h<&if3^ z!~9q*=6$JHPFDzT>Z4i1R@Mt&x>f9>`*8#zIFAb!MDTVMw-AZjxPu3Hgr|5VKG0A2 zilm$PwOd%xG!~@gEj==bEL6#byvPS@6haXcM+s4imPUD05S3^ZR7V}u)zo7v4bT)V z(Haiuh)(DxdePpRe(Zt5l@7rOF@}1;6O%C$3$PkKSc~=8fQ{IUt=JBK?7(iZhwj56 z9K~@>Ao~P@5RCH(!v$PK1g_u_qT#if|60T>x&q!}4fV%PoWL1`;=Bl>mo+!oQFtgG z(Z}KmeX5COzd)ib{JLU665f)-N@S$jkR8^rK{?by12jepw1xxPp*=dFBOK8Kz0e!Z zaK!|8iivazyf6(ju^7v-8f&p08?i}jrpi|A#2y^NVH`uC2&SPphpV`bySR@B;t73@ z7kDXNQROw>i%;|ie&L_3|5qY*5+oBTXewbvQ)|+((<29RYI3pjBA>9QiUZn<4%E<% z?I?QEKIo?z%pQti7=e)(0}o8Z9_+(@9KcZ=Ly$O4&mt6I2**WS!ZqB%T@ghe;whpv z&)F~VQoN>b#9M0ijyL5aK54$Nm2W2BxeY(r$}jPoCfvq9=b8p=LnC%$G!ac{Gc?z< zWLwgT_tqMFw$cV|MSI!-9nlqzq8C;A!3hI2E^Jo}#xOC8PJkySVXE+=%1q3~0xbFq zOZcwYQr?zfIlRRh>W2;3gw62B9_+3rh2*lo4fVIZ>WgKxI@#b<~6%YNMV74R~uP8q=m|jus{@x$T7mZHM;g0!Q>f zZ}de!(VrTe*aI*SgD@CFFcfYWCPq_FlZo8QBnu|i?PgPIrj>9YgVyWTj0anTC5j-bR#yKY~eQSU|X`2_dQ}S z)$QZ{PweN%DF-Y#$lD>4!`!hs!e@qKY$XsUL=aViH7D81DNP95>FYrclk^f)wcib_W&urz3 z_)5Rwhxknm33l-BRgf4-V1DDS?tGh0-Qvxpn2Z z&C2suL1W9Vg6gQLv18XYsn4x6L?bj7O=)wqL~Gci4II!O9nl%xMNisW^rcEaO@FrH zj6s?q?BN)Vv2e$Dcw#c9zzfqb9WyXfGlxA_ET9X;V!9kYSc~=W#RhD&U^8!KTX-{U zXZve*u=ioVI6x1I0ID1|Il_GuCqxicPT~|!BSaI*4#x!%L9gPvxJfOEX{)u54X5Ze4e7Ll1T@^cPNa5L_@6BTPndn~mYk z-DDiM!Gk?fOrl<5I#p(9=CJo-9}eIk4k18ugnbNwI4Mrk5QO49E+GP!O|EcXHMz!p z9XCWIHQZq%nJu)FPvLc(vL31KE@*%&lriDZ?S`xOXg6gORJJc2Rsi6V8 zAsV4EnxGk4!yawX1wGIQ{ostj7>3~(iP0FN8OwIZI84xZuqR?NrfX)h4YSzuumFp& zO88L47aOoiY^DBU7u}E32*p+0M--yPbNT@v5rgkYvWNdn7s*Xha4RX1TBN1vM0%PL znUERTkW=KQ)+mbND2=kHf+lEzmT*94bk%fYJN`j;KG*f&R(hfrdZRy_Fi_*nc8P;4 zpBV>kXo0rqgwCQXbwqFULw^i_GhE<`!I}~5 zF`BV##U0}?0Unr)DVU0Bn1Pv?g*jqAU5e%KFfhAnGFA=on1LEX>1dv6XJa4(t?rXapYPBR+}GRQV#l(I5DU-$=Nh zzYii2O@Wk1C9G&_q(L_1f;DVV4z{Qz8q&sSie_kq_M$U&6g_A!IAJ74VKm&~p_#&- zi$z$4P1ufu2*6PU;iNcEZ{Z#u;T68%8Ix=(SkalEjpr$ z=uZ1!Fh;=xo|ud&mpcb zz&HFtqJ#XNfD}lDG)Rx!$cOwWfTAb{8&QguMj4b9kb=aXc>Y%Qs9=kpo zm^9=zG-fw3X~wOzKufejYqYVTEpKM+dDC^|Hgsa^x^OFwn(l0+2YP9Gv-=7sIzSAh zX3o3~f{VtLZ5YZ{+%VE)6!&N`hK_|hJcK9JP34|}xte)wvjw~<3$esxIk%ZNZ$9u7 zTj(}y$8PMyejGx8I6`&DxC6xr8jMpoXTe3@B5(~ia1*z17g2bMXCj&!Ua()|4c_9t z_&~qoHxeA;&qzptlt_p4$cQY+p~=Zsa$As>w|ppsq9`VcQyY}flw_Ng;;l5wh_cjB zo?R8yP!qM$6wO2{+FICC2TeP6dvp*TX(x0+SK&yzi(b^wo2~RgKTUtOGEfYnE*Oeo zVgwxpcZ|b$Ob{M)5~gB0W?+_>P3K}B7HAf+mxyK58!Lq`Rs2jga&N^pY{w4l69;Jk zj^G%AaSCSF$q)Pg_)R( zMOY@5Q)Q)CMSZXi>*0%yViVnhZ8(5~IE3Q}7ANUhgyABt;0~e?jpyPeeTCPE!8as0 z%)d`XYNSOvWQ8>fpg2mP0;-~ps85@qxoAn1R!d00S{d zxKd>ZhQiHc1h?Xj@t6P)OobO_Sul^cMOX@NtQ2eLTKHlkHenmKV<-0E5Dw!A0&zkU z#8!fFN}Q%42tzn7;G*UdTe*y@xQ-i$#2ws66rSP(V({7I2lsCzIl`Y?kP7*bA7xMu zwy1*YqBd=a#%P9C=!h=phmjbIX_$qzIDjJ}kcQxlI7crc0@n~JqUd8h#an#ASNy_4i9I-g!#IKy2ofi0h&V&fBODhIiN|<`cZfmaWBlAg29c3w)nsEUIgk^%kXw_F zt>o8Ovvmcz4aL|tsE!(_DQZzW)I~$lh&Dzuv_MNuE4Dq_q8&PGy09&A;#J#b&xivyHtyp8WZq*$&=xJGqrzVmCGHWgoyH1c<}baD*L* zAaRC<;yl7|0TCuwxv$6J2A>&jvJJP`hDf&IHrsHAeIHSHAfD0}nwRWXf9Vb1e=FY8 z5BMlz=x2Pzcl<_zKz?mCNz83X#!ewpQ9~MbI+31cKqh2GHj$m?Ku+YcAUAJHK2eYs zGAYa*A4T|H(Lb=^^OBmf|j3ro#6~c$EN7EDh_m6I(JMD>H=nGej!36lg4*@tW&e8J-Lj-Q% z4L*ubR2Rdoe8o593F7x!6c$CPp%}X)N()XP!Uy71NG1Z zEzuSo&>j6S5YA#SRYt&5Os8|O41U-mw$mNhgT2_NIl$H(e_N!(t&rS<6r2+ca_fQif*C@?G2|`4B*{GxYD5*juB!c9fi>tBiyMnUNeEM^W-*6 zVk=X`RI2mhHcVsBG?~pk7xOS*ETGClEW#4aQns>8te`8!D!K-~!jCE&#U{ELTd-AZ zqdUY-y31rY_g?JBL2-x%h@q&oaXmGB+(>g8&o3tI8voMdZ1@K^x`{8U-T3Gsp5nIVjxup!3BfGP-=-A?{OK% z=gJ6-kB13-XCkJ;3)94OYM8;EiCJPcjmumeKbO2(S#~Z(Ht#AE80fWj@=cG=!rhUi4M>> zvlUm2#&}G?WO!j3W??=SVmVf0Ew;cPJFpMIIIRg`D`ycdF3~Hvifg!mTeyoTJjN3| z#Y^#;z7_B3Cw##-{L&;m%m01{NstUFkP>N;0U41^JNAKwaR9!5C`d#yvuertZR%PR1-O#8R<>uEZ*=!$$aH z7mgtemv9TWaSu^=geUlb1fl%>Lt;%5wvrUdkP4}h1{qBU=9|+2fo-KHqy;v3*Cm@ID`{8 zjZlQ+GHxOY5AhQ3@e|3;@%IB(NQWHAiCoA7YZO8WltdX(p4y@sYKl6vA)2EFTB0@V z(FP8hcI@`(j4qn4>~5kD?I#9M7crE&iDA?*nmqv%;e|Qy#%lOtBQ{|hcH$7uB2-+Y zH*p_PCJ(qD;W3`#8D8KuKHwuh<14;tezKKcn&0dM=lS=tNNkdX`%jYco!BJjvlK`z z(oiKG(rYrXm5d@2&8*47Hp|MJE*rO!L*%5nkVoXD`GhqsfPyFj8&pIkR1?){E!d&9 zs7o85IULXdy+m(n=*M=!7>tc4cfJ>!@q9KBlQ9J|u|O=PtFQsv;Ex^HgS`mAVR4L_ z9p~)?P9j8ehOGbjZ}1i|;v4;m-$)q7 zuc0C_Rgxm5u%b#jWI+y*hvtX1C_rOVn9qu!C~QOtS`wvE2IWx&)lmx#L?dd}n70;a zr|HO6ItfRr^gvJaMqkm74ulI_F$6=!a5@t17>Duj#5Byn94y3QEQL2#iPh8x>);DN zY`{jbm2Sg!_+yu5H+wJk;~`!K}682xQ-jRDQ?ko z{BQFw-EJQpwME4;y5yu*8ZKn%X%yZAwWX%d9<&lwUUDUu;2QfaK%X+<`g z6SZ|Lvapa2uB32*C&);DR$t!u>H1okFvx!Z~M zw1enGmCopfUg(Yf7zk&$Vz3xOhYB}367Cp>37Cv2@WMf*N zGAI{|^1N3>C5N0XpR=5B{j5Sx3-`S zZ(Yz8J0EDr7|tO&+!`AGeYp)+m62D29?KZ&HD~GHg)|)lma>sE7J!h~{X8 zj_4#h({6A?5A=l_M!^%aF%OHyQmQP&a;(Ei*a;3JTMhAu@H-~0^V2+KWq>i=_av-Zihd1U>6P`5W$)=>`$Ab!c5tj~W`Wo1$erwBkFu*4*}*Hf#scmUcjAlP=ud;Hc@z?uCA0Aa#Z- z24e_@Vae$=Cc=IA(mhnys=trpqsH3`*1)UqyY%RNpXsX znuKwO;{q-r0@rX0xA7295sl}X7i`@tZo_M~;T`+E<^%g9K8Y{%HxgXs=ZHv5&64nz z3@Kq{K^orDigeVFo~>jMnQ0bHR<M}lkr`iCY#YNSJE z0)OnnZtTG!1mLhZLJh&}Q#gzB2tzn7;36V$S=^vEaTgEq z3@`B-@9;sy(9ifPzR~aaiQhSWR zxeb@t5t_?v!xi>bagAQb4RMp+(nPYAyRo>(`+bv#+>idkQ@;C5^Md^vZ%p2D>)vrI z?=>ITAOGMJpT}rEvz0HJZ*0SN_D}r6ZzPQ5_a>2uCPoq@MGB-uDvcF8HPVQ*G@VFK zGiWlgvmm=k4sKme?p*(Y-29k4A}=-MV_S;?v>*zLqSR1~T^u$jp()8Wlwp@gB~%vG zXmw2uwxJf=tTu1DdfbNk>;`BEH!*^af;+~E@zmhS4irH&l>a>LBt4A~ah9GF=V=%& z;1aIjmWZTx#Xb5!Jfu$%jhEsTRo>to-pAo1pT*!azTrE5;3s||;cfo86NzaOq(VAm zKo(>}9@wCSC`~JfO0*j4qaj+t0cZL9(V6PHa(9OlTrouB#x{&(8%D9mU>wG4Ca?`2 zY{e6kF%8o(19Pwl%ix2x@Wn=K!Z!G02liq=4j}-?5QGqfAp%##ReB9Ka0?Ic1aI*R z|J>o{s3sFTv&c=0p*TvQG%BDHs-hO`P!CPe4n5(7ff$Toni1@g7=^Kz01x~h^6dh+ zs%=}>HY{9%y9Afu1b2509z3|ayK8U=?(Xg`!QCymg%C7oko)#Jt=HdcoH1v@TC9D} ze{b!2>ib&jeU6EQ0AcN+7>-GpkHuJqvBQm1H1u>BVX^;+?kp)?i-H?;+j$9~+QYdREN4Ha+y;gx<5tUF`)F9W31LQ#* zgD+0wEUw}B#iR2sdPbyU0ZR7Q1ppr)uz z)<+{WK})nnJ9I!-bVo0Adc=<(CSxjm#7uG)=3*&UVKvrbBer2Dc4II0!SylUU!+BP zWJG4zLMV&_6Z-qh=6E_i8v^Xq9}$kC?_hCl~G;PC%w=NZO{?jF$5zp664_` zW|NDs1zWKXr*RRt;D`HoC?1mm_>S;T`E`a!h$^C!F%b)KMFKJ@lEW3Lk-?COo&{M^ z5EW1vHBk%o(F1+NAaVr8iSeYijlLZ_#4b|VjXl^e4v@+bagscR)3|`kxGJub_YC*x z55z-Kd4$J!CSH+BAl~33KI5whCchhg(v>jJ_!z)nB0L!hDUk}Pkw&B?(}@gZM&yLM z$W7)E1<1lEf?_BwI+49G65}up3$X<2umM}K13R$`2XGSSa0S=!5RdT=U+@*b5bZf1 zzetPB$PRauLRnNnRa8TD)I$?^p*7l}Bf6u9=tU03aE!uOjK>5_#th8FY|O(Vti)=p z!+LDNHtfVc9K$JG!gbulJ@JryB%YAZ5Qum9iLfvDIYMN(ATg354Kkw;D!~IaP!sjh z5RDB@>CMm*t*1W5G$|~hj19aIE!<*gC}^05BQ33 z{`}fTT*OCWq!6jdjL3`P7A2TV8cNZXGN^*;hMM$Rq7Lba255rz=!C8qg7Mgd?bwCG zIELdmiLjY3gsC`(E4YRmxC=k{BM|TK0iW;%UlEKrf&9225t73d zDUlj!kPhkLhU_Sa!YGPTsDx_pKwWsE5!#?9hGVSoCVemyvoRM7u?Q=$N^B&zVITZ( z4-fEA_>(X33W0cyH+XA!M^`>r1TlX^?ALsLhbz(|9o$4#Qp-lqE^?4LksJ9$0a7V! zC{8bl(x_(epw~ccgC|{SYG_7piB@Q9Xh-jePKM6(F6f3HPW0xikD(vkG=NzfL?3Jz zLf3}VO(U4?jAXBj5~InnVjStrc+S0@n82Afk*-X#n8G|wOeYl|8*|txbFt8gMVvXa zm~&^AaBj7nowkC$(#9%wtFZ>_#CmcQHe-v}Mw)gqE4vIQ`P!yAtG*k1414MO9N5qP z5RQnWHt!=PG-v8|-f47H;E?;V#_|_r!hD z>H#~ehwPN67SEYY{><7-x)wkW#B02D-~;<0!$OVlRo2v1ULKvx>0HQI=_WJh#HS9HTb41qT$U=k)9rqQRv2XnE)VkNV- zivBxRb6;7Djo2=Bko#~5$8id$aRFCx-H98VnQk&`x9Hj(x}S}E>>fDqi2Y;ngjAl2 zXXJCdfWO5{W>WyOomcFw-mr7#E$60p%*uQ5fwYtOEnk~~D^egkaw884qB&Zkm1sk@ zLq~K%7txLEjy~uwhL9sM3ZpR=kGD2j_R zWI0iuR4Sk%D%q&QPN|A&s16TNgRG6Z@I*s2f)`q#BYL4P`e7i3V=L_4Z6Eyr4&kskN@~7z(qa{}oi*$?8Me^3VVBrL zDtmEA93_vz7sqh|Cvh5Aa1FPFA9){-@kG2J1Mv<&5cUJVFCzltTEt_Hk3@#V^rUb_ zYLSL?LsqyWmqi|CQ$A)p`PmmV6ryW|=}Hj?in7;=(M`pfOBhPhl~NX^neCKeZ&j9E zIg~e4q*pRjqbs#V9nupG&=8GmG-lTXP0>uWAeEMAW1}6r_UMQ%=!$NJ?sTi3>>TOE znbKGECx?g;q%sm?Fjjbz6EF#rEv7JAO=YJ{!*nr|RAyl|=3uVHJZ5b^eSug+E;Fp8 zE33pBQdx)f*oaNoBDRt{u}kbGwY~Ix*pCA^X7Ht-#RXi&4cs)`ru!N0)0GE!h)0IU zbR__Rc#C&18NE*T$*kW8c? z(;^)*AfrVV=IqD`cjU5>hn*=evyu<_MFCPNXedN4=0tJMlu{_|KpFOBMMct7iMg_< zLMl~7HPWgEJFOO7sf{`o^_V@;(4sN3sR^^zl&*N88CswvTG?pBuDj?#{u8};eVD?O`sd z%(tOT5uH?AEMhUoMjRwCB%~|Jkpd}^ z%0>ouT1L9&M$ZO!k( zw_>~4Nh-Ur8+*k;@-U9rIKl3uI7Mow>1T0HTp%yvvbaKC71v1Rh66X*-x9aUI~I4D z6+hgwxX=91;t{j*7*Fxc@SLu^fWP4-Jjnj4IZfBKuz|w zMIExPp+3D4nu=zm(h{xETC^qGTXbO7I?|O+hR$@Q8+wS|q_4O@Dio+l^-I^7ye#>zeFT5szo$rEjr!BA_lW5CbJfc zZk3RookZ-FBu*sbEHqrXr=_5q(laX=L`G6`qbr$^*^q^No74Ygu+JdY{F)-h1_Ma zmwCT9Kq?0vIKjWjFTBYKHYT#0Vwg_XeCWz-%*P@u#|o?xt4U>zSWj-iMr^}& z?7==9z+rKW^u=*;f>ci8lmn;PpA{F#E4YT6xFv3r%3XsW{T?2OhvZ|!6Z%s;gTKW~ z=0Ne8{4RcxVZQx$f3XXP2!=@X$RY}+=YEOB94+La26ME z5!dk$FYpc@5QIN3fhdTLgd!1{)J8IP$>E9=NNq?%*V5D7L}oIF$VKKw z5tK(|R6$MDL4895x+9G^Yb=_OcAB!+n$bhjoI5Sh60Ok2iME`zGqk6NMhEU`o#>ry zbYZ7-MK{r%>>+xRN+0wU{mB7h2sswx;f*Pn0Uyj3b4g{MSVS(vDzTbeCpM9Lunz}u z7{_o@oFdQS3T}v7p?t>&;;@ z!)v+{gwKfZgU?ln1{Xs-dLpDm2Dl+N3ZO8G8A{Mgp){(ZHas1u&)%5^oNG?r<&fuKk68$Q!iR+|xgMJgY#a+@*JRl$91zzDD-XqxXgZ@iI z{K@BU#6WBjmyC}DNQ@*%isW!bdSn(^$=o6jnHTwx9|cexB~cw7sDXNDB$|*)Q?#^b z#oWfCJ#$BN5}nDe=!PEXg}xYo!5Ah+lXfPtpNeUifmxW1IhcoqScD~5ise{^)mS6e zk?XMq+pzN>1AcgbM|djy$pG<+48&`^!CS)zy7CF15sY65 z^NX)Big2VBo~}itD^U>*(GkNChpxm&VkAWhk&;Y}bRq+p5pKwgEXXNxk-3padS5b z28qGsaE!nhj5kc6PsAil!BkAc48tt?Jj}-e!y@`pEEj9ZP1uT^*pCA^f}`-o32~A< zi!0(9c@uZwhlh9~{K)_W;v>F_U@}aYNMXVuJR-pSUt}gFI$|J}h)*g>kQA;W1({N$ zCAIYQjKYo7GSii8!kx^6yrLMX6h{d|NxD)BWl;fDP#rZ;3$;ZZvYu#2HbxUPMRT-9 zJG3`+q<1!Sq4z*f^g(|N5Ch2}7>eN-iP0DfZ!w9~X3%{w6SKr@axRu*4c1~Kwqqyu zS?p)l4$_sQIEBmNI(bJtCZFL2UgIs^;Uhld3%(*4-|0M zj)+et6v@csa79MAiA-b;xFa_Tpgby}8fuC9WCJurQ+S~TI-nN@ib3QM48w4Y5Ti+D z48~!+@FtZBVlp{R%p&JwAr@mPR%0jj;D9(n9y9pTwG(vhB;C#__NLR!XT(`jIfwHW z7nm>NlHoGlbd_1Tft$ExxJ_5?h`XfX=fpkE9^jF9LMl)3953LHmk2bxp=`*NVOU9Dg>{Av^o?Q*xdS_~2Ybanaz74Q9A-X=(>Q|* zxQI)*id(piJGhHSc!2;BNWL+=qkqB|e8W#e*l>};C=n1*L?M;vh=tgQgSbeDq{5X< z3pZp(F60*Z$O0&ivZxLZG(a=7Ku2^!H*^<0$$l6EZ^Hz-G7*z7Sxh0PifN=agRae_ z&%u1Gz&f#++>Tv1fy=mp>$r`3c!bB|8TlOkc!>bK!Fzl~u;CY7`71oX^CAx7BN@^o z19Bq|@*+P9pa{yN4(g*JnxZv2pfmc2VdN-`$3#rS49vqatQ4!sHCTs@*oN)ci+wnV zQ#gn7;tF{KH^nXT4(=Hq(4XR&;W=INrz?SYhxhn^U=cO~AA5$s=t_7*MpQ(H3t}QR z;vx|eBQ??^3-Td93ZMvzqZCSuvSfKwKt)tS4b(zy)Dxa$LwKR3XhmwR=~_E_dmA0t zDIL)XozVr|(L?kkds*~hw$qRO01U(+3=t#9Q5Y@8kmJO7(i;;D6X~X@%*u4kfRC6- z&cbXlht%fLmtzIiiuL3cY{PEs!9j6^JdU%tgd4br2M7>v$#?jGAcT#`&pl#@m}IOF z#O6GXjkxUMiv(msB!??fBMmYj2Xc!%WPTJtK|>LGNmN87QI)KPy707U$n1sI=z?zO zk0D|>sf@r_cw;hVU_KUN5td=K*i7!kZXCgJoWm7d6F0~Q;vxA6kMRUA@J75RKO$@- zKK~<*NJJ(^N~A(+q(NGdp3Gp#L058GxHIQMeiT9x6h$dfjVr8&Eysv z+u3P5=-N)Yon7o5+0B_FdpOhf()T-YfHSK@?3BYeVmL}S9b-Q3#A(iyGvYjXL0lx2 zOBR=zwJUV(D&3iDoI7)!bLEEN7X1z$;1M1hp3tA-nFG(+EB@jo=|~`F$~*C%{D2^Q zbl?;FuZC~*?-oCql`xV2yRhu6{$dwSgeOfAm?K(5VOF9d8eIN>7(7FX8G_iH+lj+o zi$}K;pS_a6MnZO4B6?yZ5w2t^k(Nwnk)An&AtPOJLndUl$ikcz*^nJMkQ466h1`Zb z^t>pD!YG2GD2C!FVNr^?jHp0XG*qHnRbi)86CPwu8@1TgMqNXFy3!C$4K3+y(ZSG( z-Wgrc6+O@g127mvFiZ?5l~EXtG4RH8iy6#5f747}H(Sgjmx^WN3ar64>=b*+{Wxei zOn2r8=T=AA**V7k@9^by+6nq8!)dxBXE?Ju%gzyB{u>y5c8+`JaS@kr)o_ij+;HF) z``fq!Kim^fNaeZV1zqvSYrMk;e8gvb6~W{$5iSaUZb4+Y7-G=lAf8A-CPHE)MRJ2H zT}g@5A`O{IWG0m?$ZE(&S8|A)q~dPKOV{$#3tALnwo{nBsR(mX6c;5(rKBiBmKPOC zr4p)$s-($-S*d}Vs3mHXN?lQpR6J4Nq5*S5G)5CNM{CiBY>W1WE_7vwi34JYZ!S#ge3&f_93;|i|gI_}`E z@FSIbhWqq~c!bAzBA$`Y@dExLfP5`JkXjJ^6TaZ92qu*u_$k6h<9EK4Vm|$hM+A z*+Fz9JEJ>#pci_h5Bg(>7)g#2qscKCD<+WBunfzw0xK<6F)ORF7VEJA8?i}jBX?r2 z*hkvg&t5x3KZ2w16(>mLw8c5*^Wp+|30H9)H*p7kcwplpyGMq{bkkF2<(YU+DlZH# z=~e;k0`bQ1mi`_=_=wN=;=ot-!8X3L`+=WM{Nl`!u+jPYGNK@=AsXEjo!LdiBu(*{ zO$nHlgd!2CB(;&8ohwp^l%zAMI9F054bobqV@{6@!i}`b%udTn&tb?#&y9SB{PY4S zh{7mhQIy$EG4@Ici;~PrDU=OCInK56bgd%2k^`05TUB9aRh6Am9UeAnurt+Uu4Sl0 zccd<7^-v#;LZLBtnufrO^X3k;U>}l}+-ZfjHrlb%+S5%Pn6-}dPNFlZb)o-`uH5g2 z?&yJ@HhQtsdefCYe?VWJVd}>`&@hN@8qBN=!O;I77{<48_#ZZc=V>G9j*Q~WG@98o zhIy=E99)cUp;Fh>e-Z9*zEBC~G(&_;_?IB%xgvWSdcuH5EiRYx^j{xzC{9S>( zMtN;`OV{4hl@B6_)IQQb_QUEo!{}D`*wb?SAK>dj0^v!VF*t*MPN2XWL6?0 zs)$ayh!|u{8*$lb@#qP0jIV*JOoYT1Nti>Dlso@aGM?e;L`u%AQnORiiu7a#k&$#m zW@JHj~bToAs;=zC_pL&4MpgtqRgRHjJy9tab9mK!K{^{mo}84D`iDF zQY%l_D$pw#D$`9>nXB9IV5ilf*A%r#XKHh9RgayOCp%MpW~&D5tQxXwj3#Jm;l ztqpDHA!*AUtv%h;fm!J&I+1p|uvfaFJ9;?KlfBl9uJlG9(T^Nx7(zDzKUAZZ4k;)y5yUczz?yc71lyFXj z=PZJaNbHozh+>FJcf^G=CB|=v$z40K*qdTAYjNrEMFLVwL{Dr;LRXR+lF=PW&Y9~U zkb-BJQZc6%X~?ul2RCFgWTrckg|mNKR^G!-Hug$(k%RnCaOZt;8FJI}8uHOi`I!r# zpeRHZ7DY*=n2qA>N}wc4ql}>}T`4CjkQGr0RZv}ckfs{US}l5A;Yrp<1B=GYrY6jP zM^j#B<;5;EnsHBQ{(rF+eBb^jwdDPOS1VqlwWix?!~Q?1E$c;a!qdWI{h@NC<_2O=Ci@wZO{n%;!>B<1ZK)N%7IM;^KhhaEI zV59@1*ejzkMvNu3adgd_u1%yX)5Hu?@v)f6tjzjDX7e0nj*YqOw1sqKu~>Sy~*>>!}PO+O*_K1C?wx50g2Mvelhs6<6J4RQ0aRMiC z3TF-H=*oE;7uabR=|}lmnM&mnuHdTSI$gU#*KX27>o#}qh`XfbN55xrpV{<)`Jv$v zU3qNrjM?;@`GxQ&Uy1`bVq_YQ@-Pe6F)f%6Z5|d%gz*z zIlPEKYLVzlWJEz!g9}}Wfmk9A85i+v#Al}^q?-~kTP0zqC8htTCF4EqBxmnxNJ&p6 zQj=*d(lKYWaAQ_7A+sS1Ju9*yhZ8wD)7UG8p7FoY7QS7-Ya6fGDRz;{ZU^?U*Y?wuLk=8fuN*NPr7OqaYvTkv(RcheMaF%Dp`;f*+dRf$!Tz>TjgS>=RWvETBE9#MoCmI?W(L>Uh zJ9e6|Zz{aVW`9F-UZb=yw4}HCgIe<}tqr}cXh)jbGj}v}qAQ)z#YR_lrXI{nFB^T> zDSbshvOfkG2GNzlVhCw9l$|onFr2Q8z(@y1vH!b9^V+du9I1@A;muB&U@?(-l9)_7 zGlg@jsqCgGcF>ibhFx@Jw-b9fQ}&180O!goa$iFAjWVZwh9%`p)i$13%e2@{6-DvF(Lrul!{QPY;a<+|we` zor%PGNFsA5iW5;evx>$px)Uy(X))1X(SqxS`&IxCz^5A94*lX?a{%|iLP~~o4PW06Wz(4q8Dk^hn><7{V`As zA_rrL#Zcy9VmLXuv$#m0H=FpnKU1xkaS7u@sW{U;nVvFU> z$_lZP)K<}z)mRgPwVZ3~=yuk#56MREII@|uE&l;qc@JfqVFz8=ZP-iSXR)98py3ex zFpl7;1IO6=isPi!33exO#&DLdU7%kSm&seWZR0Mx2O)UE`BU+Xw0h3&h43e}mvlP; z>|Z$%$XQ6T;uLw>#u;|nS^7D{dAfFi?#M;XOjnteYlfS2<(7>* z?EJ(%@&O*hc;-C+c(7Kr|xlG-hwdi@hVwI8&O7 z7NpjSuC=C{+Av$SW!DZJ(b+~9c1kyNM-TKe^rrVgKlH~y48sU9k~EEG9)qzMhw<>n zL`=eDOfk%$D>E?%^RWO6#UfH!ES8X_Wz5UP3Q}1k){z^q$*`He&9I%W?8aW~$3bzJ zJPKcNoIHs$xPXhejH|eTo8k_s+{Ht@fWLT21{hw^LlVdxW zc4WDk`>wDE^?7tZn{-ob_G!gMMZJ4Bua_0q*jhz5tR&;=~YnGP>o() zc#ujB)I@DjhpY=vG(aPGiDqPTw6M{NT^qC$?a7X!6RC6-UC18jiQb|Qsr98R{V@=O zF%%;(3ZvmICXkab1=Gb0ayI6Q`J}d(Zd$^;6w9&F#wvDeu@398L2MBO9_Ca?p{M9W_C?iFUW`E3Zg07qq=Sby(xJX_xT%~K* z>BRYU3o72$(M#ey7rp>2Ji4e1d*Tc1z!=2 z@8Sm;CISC0hQCC3G6JF?Dx!(#qzhshV$ssid1B3k%ml*49JYE zB0H(LBQNqHKMJC-C`u~DL`kxgp)}o8hPgZ{p|YVG-2*j5O|rHVbvdhVXh_$Z(3`>w z&Cvp_(Avg$^MmiODgZgds6v;Abb>G$gc<%zsRr&`89~}h=53lj3|hT zXd*i4;zSJ2Vj>n2AQ6%v8Ir>lsgVX5kP&Xkj4a589LR%0D2@^+iBg8rbW>&KDxxZ> zRCA&_XC5|cuv2Op>eB0pMx+;77+TU>p*7l~13IFM=uY-TFZ4zq^uquQ6obgYVkkKb zBQXYJ;f)EHBBqksG`bIFVm9Vs0hVAHmSZJWV?8!u8+Kqf_Fx|l;*iA=X2n+=Cr^k| zwC@ztgEv_&tS1qnFE7!#h@+NNME*|3vo{DFrDS-Jk-iWv4C-Ig1W(cPL zMA$_CpTFqg5MD$em57LBh)RzJ7ZHP0Vj?!;A~BL7Ez%<+GFjwg&V~FafPyG2ijc)n z8f8%)l~DzCP*>C=>!TsO&>C&f4xP{keK81Q#dvZG=3qHiVl~!bgJBbWGqz$oc4IFN zh(qL29235zasp>?4j04~@|L(u`r#Q~ArP;{JMsfQ;v2#x=EvWGNbI$!^k{HF48%k% z#6eudLjoj3VkALQBtvo=uI!W)NR2eeC^C^*kQ2F)M-(E9S`=f}O3+OunMKQ!g_0bqj;U!v;twW&=ciLLCW9}e2l1e9Z72Qas z2YQL#WFPdyUqU013R%7CvgfFa0SdMKFFLY!ZI|L^K=G**Ow}GbQHV5R2E?iOpV#Ylu%z zAQF>FkkleMbBa(%$(_(h#l18lEomn``wR|bWFH!C+{+e%?3{-r2Y2k`WbcSOXLfS2 z&y74HFRA6DYx(I)0a1|D3egLrD2f@1(@R*CWHyyzE{!r4<(Rb!bgL@t>{MfKRh^yY zL9g)-)a12Rwb*I3=}Mgt)aAUM@FcYcbW=m-Mrdr&lsP0`+|ioRl@^AU^j2tXqYb;Z zXorrX6WLAlAhn)!r5AdOzN91lIO}g1NLL19s2E0$!FUUA=82eOV=}ubVj5|h&TN{& zJPWfi2XiqGi?A3=u?(xR9viV4JFwg02=hr?#0}v`THRy!46pIgflus}&lX>qm0)}q zKgqC3`Ft+IlTi^3u|#|_F)7`zP==##{Bat;<^8CGDe*g$T_PVC1aoWfPy6t~F7cq;tK00iPKg767n@D*W_ z@neL@h=N#%i-brd5|c@g6v+)K=&1~;=}H=;MLJ|aMr1`cxFZ+J*(lGh3TmPb>cSKC z(GZQ$M0kB8`5Ddj|F_Kh9iE-paObNkM&P~&p9huJAf5Hsj z=ilPPvu9$K#cXD)IqaA}$8U?ubrxoOxN+A^f2a51oQ&Hyst%~t&`?nS6JxnE; ztxB;g?Lb-frgF?$1$xC0ROY;jMOEfMp&HN8s?!w@)G*Yfhej>#*{Q?6uBbhc3_G3JcMgRv z+;OHW=caDVJf*jUF-Ss#LpoZH#NUfWFH;=nfc zj%?>_huA~zwK%}69KvB7u{g@C9Q#ctxqk|0ab8>`l}m=J^c#kobnO=1ncJKzcj1S7 zxGx@&%46|_{5ziVx@Y1!Y30w(^paT#z$+0*zQ!BzmNdO*)`IBDN5dz&_L=?#UoE~d zE8h)2=t?+O{yPFhMKnZ*iytoI0j#w!C73y6&qLCT@%+y~xXsQ_ z+$WVMcqszNS9p&ge8LwIOnyh0lzdzuBBCHB;vg=Ph@_;eNI~X6Zsa!0zsEhh&fQD!SFSHb`NTr?VNOnOl^fvUR_s1X%5yQw4 z7>UssZ{f{60aM_ES(qmll8dnftHeffE4E`V4&b0TLMlgbO!$(=aRz5`9v5&4*A2Jm z%5B^ccS%2SpVS`Gl}C8&z*F`w;E$IG5N}A+TV~}8zTzjsrsCgj5dqN<6R`}j>2VPs z36Kbh;fhp9jWkGy^vH-zA`6*SWGCH`8+lO#B~V(FBen8$s|xItiWZfawaRp*il|DO zsxeo$;lZvB>Y^SzMFY~R5j(9h-PDBH?({s! zEAo*APz)tSdD5yPyGo)qSx_EJ8dU@7j|3hVOI89 z9AH)sibLcP95o!LpAe@=(`jbq49?+#xJX_WSIFxkd>Z~Ph3s%gE|Hs5@*po7!wbzU zS}?aXw4&Q-&EC|8S!s_&Sb{ZTExFFHk-kZ6Cbcc}Z8o;E+ksu!ZLx=WFZSU8j^Y@6 zal&wtZaT$$8s~5x7sN&Ky5R<0xrN)fEBr|1fp|zh!c)8u{^Uyp;OT76=t zd=_6w<*WEcYCq`OPkPw2{CxC8C=WGb>39N$JUv)*>Bq zdSno8q@7IctunLAifke~spX)%i#()~7x_d1QYk13kyeG-X+`Ko4aMkMak^HLu9QM) zQI1q9ib`Y^Lshy~o$euOkhM@-)FDlEnH{OeS$#A_BQ$}Rp*dY^LDyQ++oPisojB7v z(@kBNt-7*P`e6hnVhW~WnwUZQU^eFc51G&VDhseM1dBLV7XL#_czsBga>vdx_I8%D zUy0RX9l0Kxo!G+JR>L;>cI?1z?6I+*-9a3(IKpf?%B&p2iBLGnozplY&XMQE1yZ@> zz-9KzRa_G{N#!o?U@OL}ZR6B9mHlx|IvN7>3yNxQK_6hO%^}9LkF-WOdYcpdouZjo53A=~@%I(p0n~ zJ6UvL*1FP_?&yuaVh}k5!!g=0madG4Hzr~dreM05LHb}OR$(pHVS|lL?38WTjvd%# z*iGMu1L7cg7)RlYzIZ??5AoRWjQ#@tB7oFh(XHOHdoMnarXc2z z;u9H+pN25$`5KW$SY{<0!ixxGBt$p3&|@MN;u_-76CsHqDLolnMG8_$X-G{srDaZs z^db{!%FJxa!kpDcHglz|xmQAz zBpoTmS!t9*1yPB#Q<;5r)c6Bx@(fcg=H{X`skB1}LuYzd2fDG>deD_#=q>t^rhd%I z01U+7P#VHL(=cXjBwZPg379A*k=kUsGQ}{BK12ABGcn7?Y<6=n4-1@F$XRGC;-0b? zOR!WdBbDWb)pTVI)>^D%wzHo7M#E;hoh|IQ+StZ!yI}`i*@fNMgMHYK1L7cg$Z(vl zouF$c=~n01Y3Jz|4VUOw3|Hyba2+?rZPIj?S@AR6qdRh+Gvxsu;*oevK5^hFd*wM^ zz+VKCuki-&#C!51KH)Qh@l%A&z~AdcWKxM@5tTWbAv*m}iOsX(h>7W-7mFq2GK&?=%1W%l zTCB6NncWs_bz(bbJFyGlozPYE zAbX+@24aL5Lym{HVIp0dL^n-l4vneYQ>Kd__Fux2T4Z`uLv*@JD8%4S%zs%do*x@={)TwGMoI98B;+}X zL=rM2Nx7pXqq~MeD(?J_)Z7oPG~Bh5mVG)W(sQP`A+sS1UCT;$BpYW+c0&&O-{sD0 z9m&O+mYW`ueB3eRXAZ3b+%06IFgvXXy=W*E_S-P1F0FZKz3iq!u@&4(i&d$1bQE@>XdinvkAo zW}^kWmZCM;#-c5=Gwr!|Lw6fq?6e;Ao?;+52tzR(BQO%9Fc#ws%fw1@71m-s ze8eWw*J3O4Huzz;*hlWiK^(?uoWWU~!$n-eWpRyEu8W)G9YX;9zIZ}DH9V(lFX(n& zvR7W=4c_5BKH?KT<12oM5E=NhQxS>`YZ0C~f^Z=tTDUSt7Ews6sO+>D^q3a0m}4U@ z;#(wSPGm?zPm1J7DN>VGY1pMj24wj|?tEU$O3#MuA_tjMiir}WQWh0Z z1=U1tvYu#2HZnA&dy3|y)`s3zv?rC0=w#?j_d+l9L4ORvFpR($F`iT=VhW~WhL}mt zwlSC8BEw?3vc#~IzRZE;?6p;NWsPAi-D(}X_3*(aY=$qkIk1DhzhNhRm)K42G3=us zz#+q7x^hGuC6D1aP8m+q<|qwR7}KxQr{}DtX-yK))*Y zgwKW_^j`>-k-vu^l88n|M;wdz%t}I$m{gL$O(Y{zAT`n;qi`p)8gkJKq6mtjxF|)I zK{Yf+6EuYNOFu7pJd;YvnEG$&$mi;XylhlEIiq;NANqo+h#bVDx;5QE6!7-2Dzc?`xH z#?dEWvY0~7!92{zBCNn_ti=ZSV3Y7A{jk%pmwwQ2gnkUiaSCT}7U#qT@{+hhUd3(P z75B*phKF>kN9;_GnYAbM=i&|d0iW<4A+!9$g>)5>$!Lgfh(V8u_(%dbBtvSXMP@@5 zx;wHW8*(6zC`1-VNt8o*8&%lVM*}p0C)$dRWEXTr57CQM`l25OVI;<4oR~mP6w}D* zn29-|nnWyRiocaR`TT6ekQP>F03`cf?&% zxo3DlSDqSP(qG{<-WopAmCyKU_(uPZ9~M8Em0yMs?)=^yp+#6SJR%re=vEQgSw&)} zL`GCYbh;@fbF3hU%Nr%0MSSK&hNN^iq(DkTTDp=B8ITc~L}t<**^yJ^A(i|V9?Yh~ z%q36~Wo(pX=SVqjrt-{61w%!8b<{yU)JFr+h-@l6$>wNbXiIO0_UK^fOz#RW^b&o^ zexg6A48c$g$4D`bG>vE0CegjcR8pHspNEB5hSk_CwvbzeAF1u4D|@gH2gG6Wh&V}} z!8x4A1zf{*ag)^U(6s>iJv_ie!(;kWJi`mT6tBoPc#Dq?d}061;s^6j5h5!;w-5@U zMHo^Ej|hl_sD@~CC59n3U5i7HClZowNP*NygY-5su*--n26wuam2Q=dT@I0(w3C;; zlFv|pu6fW+1)1#>W?#gjD0691hAb<}k>w4Q=~YEF(o~&UseziPE$Wi>P+v448=5lj=)=Vba-?AteY68(*lXkH z$^=ZpWO!qmVLDxziCKpEbkhQ6Z6RG*gymRaSV_0DioLd)ZncJ;)mnDSdTcOkq$@r_ zw260$uVE{FhYde={x~X*ktcCloFVO;Wp6sid|q56FBvY=uiz@K*|^S5xnbibyW8R} z`A9q_O;4D$XY`li75NtL@E%|A72om0#xHguv;9XXx)NH1C6#a@JQ)Elh$vjiNQf+= zlF<+Yu|#Y#4&osRk|LQ%PNqOgq((ZCiF8L+2ePxzfqd|=D9CJ8h@Dc{iK5)J67-TN zjWVJvSp`)^HL@=1p}rFhxc!cXeC|&);`5C~6S65h(G0CbYtl{|_Ev4#1*Sc3I-n!E z*yzqq^P+1#=}I5;$6yRG45cf>!~}90W?-&i9(_I*VTo8yuD~j+7Hi0LSdWeHF>Io5 zgCG2{3%jvb>?aT4AP(cW#Ytwq2I-Q zJitR6kJvrN6Fe1PNadUOPX0uQ?Eh0J<}e~086FW0uJlNVg6N1TVv%tXPb4IjL~uiL zq(B-QY1w5mWTrckg_|Sp+?1?_Z1n8NiCoByJR%=iP!uMMqJ$_#mO*(`Kt)4kx>5yI z4b|vMP1Hd>G(ZzHg(sRDTF{l2Xp4^M3@_1}?1R4OFNTvNFcPCN5tA?l(=fwgCi5)J z74yl3SS*&3%M2^%&aC7f6l-{=ti^h4gpU)OxcOqc*g@{XZtTHcv5(x3gE)#~;xu^y zmv9x=4Y%mG#T`-!5O>LY;y(EZ&%|@`rFcUs@9^Hn2X-F~pXk~b`qyCi#@p}W2dVr* z*c|+PG`P@BuFP5_x)zzPMWHKEMKn^2PLCmClCcp7@eK*+i9}M;5jSqhkQ}KDY3WKj z8(G+8wULcoaAfDbDHn4-LwUno!Kj1h8}dK7y5|4q|y)lF#rR_U~-6I7~M3Sd88OkDr0PnWj9WYCry)?wJCIO z!!-H~%oMZ9xndqUAB$`(X15e8u@>va22$HdSA4M9hA+FV*akoNi=E^y>=t{;ec~W_ z#BhRs66eHK@;dGq0_b;fUpyk8;Hh{)zQk+1!Fzl#e4;z^nfq76H~J5YpUkFT%pr2} zdw+yN7!j5X2N#Qo%vvP65?MqcwHS0ICSr-$q@6hIwYYRGK0R?Dl5*GF=vK+t1x0e+ z*-61(OG!_K)JS8Imf4h!Iin#HUC9i0jvAd$U~7)mO`F~VXbvz@W*$72GfSWIKqrqgF&7G`6v#XM%yeCD87z&mB3 zVKIHF#WH5oa^@9c6}cu5>$saXFe@A3BQ}xRX1d~wEf!muo!Q1++3vs&_Rjcm|6Trk zcBj}y?l$b9@3T0!p!K~aAw@B>{T?w#p zmt9cZ=j}s0!BafPOT#PrYm0Zx$_IB=|!z%LOp7k|%0XoNvn5uS_ymmrA9 zn@EUih(?c&7$PQVCl>qIA`Yp~JV>j8>`aB2l_DsLVt=4GpVdmzwNi9bY36c<^7M+L5~)-+ zRH19t=t>PV7EMUS)1n!(($dh1?nrBHZO~qHAUmP6p$ok$x*59D6)z`xaC4+5x8CR@ z`jT3Iy465-gD@CF92mylG=kZgk=#d%G2~b=j&x)^H)Rs0Vj8Af%wSe#IWe2td@R5s zEXH!Nk_^l$-e{}o>#$yIAUDECY$CUaZKNGP_Wsy~gBFLF?Hpl$RGcEuhzq20$>J)r z)iri@uCu>^o8lIEM+A_j2h0z}WAd4JPAV?~@rwK3_L}c}Bi@o$@7R45pU5xb8~I)Q zAhnRW`DZPJwg}4{!NP?(Vi36UMu{XMlcp%lT2#6c(-4auN5myf@t94Cm=hxjk_tC6 znMg@GlA4=UT6S6nx|WHa71<2A=#J#)Rsh9BDN-vRHrhZVXQ}Lwj^YXLLnB^tTwmtPH{s3>Cx3;ei;z-D)JeQDO|Kj1}X^@rH@?DZ-na zE@qO-EX=`NED(#x#fD{cWrblSU0Xvptz}+^_1J)o*aTl}5nD-RyVybQ!fx!x0UX33 z!(qC1jIJCHf)l(6ij%xMh0{1A&XUSGoX1667FWsZ;s$wB+#(WFjO% zQsG7hMKa!L$>}K!De0+1YBDV{i7ce%PPfXzE|q8XZ_1zMqvXh(JyUC8bRFM1F3LT~iN z05O;xhT#}3#*z~-QFxQe49vxR8;jU2F)XEP%jn7~tc4FYiEX5x*i9CPnLt|g%-M@po!NW+{FnUGmz zAr*IIMK)wdZsbJ)6hu)J6U9lb6ulfO8*0*PqaGRwPqH~$p}nCKy&HOp-ee#2$3P4b zBgiork4f;xG|a>-%=?Sx^Id=20>0Cch1>$Oh&O-BV!q322|KH$?3Rh;a;u3ioSHxBFnz&Bhz)jr3 zZ4p3fcj?+ay43@A+9Ud7JTW|_KgSEhJNkQkz$bhb-$~^Mej!voevgXqa783UM=Zof zJQ1H%5*U)u-5f~9-YPjeEd||_l37VD(vcaE6ZudOg;5fvP#R@X!BB~=Ri`U8P!qLL z2X#>o4GoRxjnM?n&=PIX79DMLV%HU3=!<^nk3krMp@w1f5g3he7>^0?#xzXF48u&i zHjBO#E5&+pJN&Ry>?RM0gXCcx#c^?p)XvfabBQ-sa1(cMPuwT9hxEsIg-`fw_(E5{ z8NSnh;uk{Y|3?^72?tk1LSzwzj3yG3N#KU$NR2eejI5}Ds;G`ysO?03Zl(szo@j>V zh8A?KCEZSI_F7wdM|47G(S=mHif&|g;YFHyFe|-9A5!Tn`jJ|Hx;B755Q8und-&g* zR5`>jls+s7M)GDf#$YVQiSeX1fv!!YPlESfFqQ9^hUsDksm-Kov*@PT%yTgh3&b*V zIaXk$SVJnl*lO5LS9Tcu>ASHf5c{|vz#$wKM@i)*PT@4p;XE$llDJG>!8IG#+1gkV;VpinA|?(xMD$D#u*GP>Eg{RZ(5kAZuFGWp0dSqB*Iw zv1rTO4js@1-O%0OMOS(ldeWWg!@VB{U?2u#lo(Gc6EG1|;EfrWi8+S3^m$?dsV$`c zZHxI%t0nBTrF7FWW^FnBcdX!Zj;!XUth3?6ZWDYhwlHtQcI<#3{ILtW#a>d|Pgf4& z2u|RnI7Obrd0fI(ah<%0Texiqpg+JP8;{vN6EDd(c!v-8h)?1(`BQ}O;MWXiee~k zC`m7c(iUZy9VyFADTnf?XsAT5j4G&xT86rGr5+lgF`A23WIMDM9Z9Pm?0TcGjehL< zivi?7F_?5_2zO-|cJq6g5#&gW##oHU1Wd#vOo2CMViuMdmeH4E1-8Hs^$YU*e$j+% z3Qt2zy3z`*MMu)A6T2?x4lndXFZ9Pi498e8o}7$nn2A|p9=Qlhuv9D~ms_l0UWqkW zhxKA3>4QxcTbPxtf!M}f+fLsBf9%3;>~&xt`~5gzI7~l@Q#g$?7H63+;4-e^I&OT8p-1J3|M0C()Tyx*K}a`-r~e01U(+48|}q zoE#;_l6J6wApKScNr)b#!e5eWTb!`iiZjA9h;o zV%{zGk_T`Qhs6<6J5ESf!c<;^oF7dsWe41v=(j1b`Er8-wB=3 zRd|s~FZ4F_r3XcS-kAn4D+8Sv#LdoN_S$f|oe}Iu8b;B_VjRYciR5HVF?iFbifN>s z>Fj4%%w$$(IWU{OG7s~yAP5%n#0M?O?X@ zV`t^h&a{hJ*<-PnS=lcRkO#4oUn^7|vT=mnF`UFHoWWU~$0c0GO~YOKeesBVjHluS z`3fKL1-}rY$bW>VM=-e1BOLqjS*wXaTXJpCt(V_#Y}PzmS8#7U@bPm7d!r!`SIfi zl|OGyJDHVT7Q314>|t+bAN&0{fP*#;u{(?-;uv`nr*H;m#Rc-RxJfFv#T_z0+#~Pf zAs*uip5cXfO}-WH$Pf60ulR-#MgI|o42ST-g^Y;Eh$>={aS;y*kpxMR2ANO{#Zd<3 zQ2`Y#sxaHB%Dx(EpeAaeP7u}QT>~^hQ?x)Uv_>1WHFThNL??7XSJ92^Y3N1oW6_tn zpP@f}pkWAoD29s>q-hkhGD%D(P2SAYF$1$P7mEyw=}W{?QdwqLN!M1<1GAbprZvoK z;UhMYrY+1{u?>FMg}ve+c^F5;QBpfb*G|%vbGU$u;u3ioS8x^A#SQXyAntO%hx>RS zo{-8@JQpv>_xOlU_>3?3iXZr8BSbO&`-37hsf0l|gtv&u>?$IWk!?g_r$jSEr^iA9 zBt#-Z61wI_*OJkd&&_#43yTc1T&=Y;o7yU8NVlcBZ#EGHYlwo2xsf-Y#NUJgIw2Aad zm<(^jG`cb!GsJ9iF6LoA7GW`#Vl_6w7u(^FUD%C1VlTPRaDaXghjAQdaUK_O30H6x zHypUh{ub^a0Cxj%kNX4hkbGqEm|1y(r+9`Jcqv|!@9+U1@daPS4>Edj{>%h1MLaUT zMH1$uNQKl$Bhr#edXa(5h%Cq&1UY!4qyO)z6D#c9lNj_`*8rLaMo~{ehmS53V;5&V{Hk(58H77hjCOKC(q*o zE{W^p4LrdMyfu8FD<2J?=${Q=>88*n`LjZVhYKPhs)#|xGsLHB3F(QE1WAzsX^_^C zj-CmbMHVs#aw0eKpa6=Bl4NO=6BWtIsDi4fiQ1wLS=UgHULOt7NHig}rgX(qG$&iy zXvHq5+VHlmp&h-Wp%c9ex}yhri9V##7o#v56EPW6F-=S-=VAdCVlkH5Sk7)GR*BW5 zvet=p+?0**!8U9+?4bL>->{Ru8+))<>?4%}HV&~nCQgtiaaNoomCLv;Zj<*c?lYSn zF+aw0yuv&9@$*Qf^1<+lu6?H4`Of|aLX_g)!6A$x99?liBoUQVq9HnBBOVeXr9~=c zC5=c+rbk9(Mi%5nKH)(YG8CZ~MRAluX_Q4J)DX4E`e=y8Xo6;eU>qi43cSTsawcYr`J^*TxUaxU ztioDsF!<1YvBj{JZraXl+QIxg{P>)SS7ulIE zF$d-fZydSG?Qgio_c(H$n|6b4y2*SCcf@`2v5hC}w5RlE;syB%Z}9=2#AouW1K-$d z-|0W`3n5DLb6%1w(wS7KSjW{!i@NRQm`Kp_+{l%SVHX_OIV z$#SARSrL^{1=Ud9i5lE$qmF1oHbpDZhHNJ~kR1(O=~{QX)|0OFqAPvT4+AjBFql3> z3?+wQI7VQU#W?2iVj?+NOd+RZmSHx14(4HjVG-T5n0XnNVPbK(N2T*eh#$87}Qv3N?Fo-vzVGQYt` z@rnF`@AxTxks-?bBNQ20ge9%Qv9pTEE;6DZszr3>7>H>Ri&=|9k1OJlrUc9h4Tj z9X{f-;R{{+M*k&3m*w}*a51>jl_-dY=!k{bh>Q3l0jVT1B&H`pQY1rik%Ba(Vh)bf zyia3DOIOl6kb!+hLneA=k%iRU>85PV*^xu!BDLJ~e8`VND2kFOi}Io(Ss7If)#%kx zL)0a;`t$~9^c$M+8O@WfG(&Sk3%b%8ZP5;$&=p?jCHj)e0E>algT!ER2u5HeMq>;n zVv=DReI{mOF6Ln&78#b%mti?pVine4oyA6GWsBHKD%&i!Gn@RGm7O;BvQzdM_S3b) z^dmTivp9zfxG1iZH^nXTHUe-L_wW#p@e;4`#^N3GM|{OM@typEpALj9$M1KA3mFlv zh=QnyE#i|2kPwNG3TcoQ=?xj^N+yfU%+j76edl@nUzu~ zjWQ@}C{M3oQIXkHiCL+FYN9$>!%&A_Pt+$H7#h+YY0Ayh(2TCNptnLB(Uw%&qXRmM z&SV#Kv(cShAJLEOk3ojPbZrP-8%iH;7)>9C@t6Q_F_oN#*_dN7k6D>-v4DA@SWIe5 z>B|f&=qs@bYq0?v;e*X$3%LWkup4{CUUEMU;4qHhB!1wh_(g^+|Bq0llG~7vUND#n z@!qO1JFOJGEXs=tWF=G=gUO*{7&+X=2zFK@*^RL=mYp)rVgj?BiR^=G5}%ojDHh($ z|CXtI_cTm5%%Izu#eN>*!WK>^5Pu@Fle^^lieA)connPO+QZ zEB2AvA^J&iiad=o;wyN!e>oSnVosY{ka1#*efp`c*S0M?Zg{yzw0fZeUA^~ zBdL9&TYYBtC5XQA?wbSO*$2fB-u)YX^1XI`vDZRW;Lkq{A?Zr!APU1fXTow1Z*ZYo zMPjE#rAHGn$ln!{&nj^(;xWe;2}mW8Au-*Ql-bQjGIq(4Du`0^E)CK-keNu>_zp@pF}UFnEU=z{L>GW4J; zJuwU;3}fipIQj%k#3W1>Q%I|+?51J5m_ceY>9fRaaxNBN36^1nVI_TySVwB>=^Ml* zatpR%J9dcOVpdTX>nTeL%0bVGN87rh61 zqBr`WFZzoC<&W2RviU72k$hj~7hidE!l ztiuMek@UqDY!lnb9q=>w)AwQ@4&VrmIdPoZNu0t3T*PHu#SPpPx5)t9$3r|aJfdEtSAqA(el zqP$T`qYTQ63S=czL3Pwd9n=#I$;K8V+3%t-1{X~CK8Gu0; zDu$86F;a{om2sF1Z%o5^NVpi&)9vTKiBi=SPG@;w^WZz7*AX}pi z+M@$HicVxV(VgsxUg#tGkpnOk!!ZhD4CCm^crlSwrobChF+n_q16$cE+Z@=zUh#uJb{Tfl9ofTeAND(OkelfUvvNY5B+m!p0{4r!j4QZ` zo46$cNYh>B2NutmUx=6Fs~~vI8`E26tB>qH89viZUznAzf9NNl|Ai1${v#ya6pA^F z2uFsuaA6LND{ri#u+w7DV~W^hLL?GNNH-)y3Z$_}%bd=To}LkzMHbS^on6*o$j)0O zheb~2T*z%BFFPea3cw=>3i75fiWrL0OQMvGvg}OdnXM|Y(<;)n%Jdqd7OB)j12jYv z;YqecTZ?wg9njIxiQdJ~o!$dI(F=V5FOr%dTOra~@hUxTKn1e-FZeuk&Z4G^c*i8Cji`Ygg+YLMDcKq2Zd&FLH zzc@f16o*LVFpl7;;RIbdjk7o>&XX4nm*~nBT*oa0h`Zz?!(;kW!!!CzymsOZH{~tf z;XOX!V<0|p501~gSH2j&(w+In{TD)3{YMy52`j>rE(TY+RU~#w6huRG#6nyVkBsj? zLiTnNu}>_LkVy@0^kf#vnNx_AWGa!4OfNE#nUTc_cWzo%x{||?lb+im53`4%5M3#b z5-9nbO7XeUqAaPEqn9^SpjR?frdL4?QIpi_(Cb>%W7Znb8>0!Dp%vPoouNJ5)PcDp zI*T4;PxM9~3>1UN!5D&}7>*GRjATDXj3B>s1Hmsqq!+OI8`bLXQ%)Z!$?eND=2llYn_R&oTng50(e9sA-#2K8$d2yB0uF-D< z!%g1WxyAnW|AIUGn14e6-*XrDa9=zim4`MSu`@kkeun3GftPq4h&SBdig%>)5uflG zUkpF!KM|tZe}trmL0E(r5lF=a5rr$ML>5s=C7K~7JvQPZ0TNjxW=?{n7Ri~Flr~bc zQ_?t)mVG*rg>*+&WJ3-^E_!a{K|bUc1xODR5`{^v7~NEoxeUr0%F)ZCBC4W>s7cmE zJwqdU6X8iVLkrQ8)LPS(w&)-_k)1^sQtL+dLXW?oC*RS_(3`IHq4z_748$PAVEQnO z#Aq>=oQO#VZ~9bB$85|M^T`Eb5xEr0#0pYbX|alVjbSZ)BYd#Q0bll8uoeE;iQU+P zeb|o!I4BO2M-0d4$HhtV49?>ME;?|Dz3CeB4RMpaCGL^hL;52;!BZ!maeFRalCSU@ zZw(*l$|ror7ktBa{1hRp^XG6P3>nT4fv&h9qHra($aF0hU5ShMNPvVQ5t&rDk;x1x z=zl5|-;vsohOVSX29b%(Y$FRhC5OmK<`elz#RCOx6k?|oK?zZcv{RaW8I&`Wr&kn} z$jYdK8mJu%b$DC%H`U{FN_{jC4ar7^X7m;k-Qy+(HJAflFB%YH%y{Wv6#xNO`}^)XJ?whtj(m)60=EVj+jf%Gt8%J z3+T#XEX8uH#u~#~`g&{>K4f4v^Ty=MtZkuh#}467?!sOi7Dq|#82yCdB>j|)3+yi9 zGOpu>xJ3pS?$RINF`kHLr1Bgu@KU@c-{76$Jze==@sZi|iTShmM*a}LNUKma_;(Np zjW8lCsfDA5H$l5S6_ajUH3PB9+*P7l`=Wl>~-_bgM+{f+{g@O-Y!wq;$=V zt|g-OKlF}j-b84hP24obONF}q#Lb@X>vLOd@8gkRMd~_v03cy1YBDEs)VknN1 zD2*~Gi*lkosa2#0rV?)|8>-N2{3SK{o?3?5^g5_3>XQwfXv9rxOm8BZl1ei}b9xIK zE!njat;xW&;Z0Dr<86D5x8u)V*@<0Z54jHq#6j|i z6UVuo#HnC7&0DK8?6k9V?E>9&ky*KdtKu4|+zf_WymjU_ckK>c32@*pd#n5G9NEGD ze+}#H3GbDsLGX+>fqBjwtC#HFIPjLe^3L#{{=tEd>`h;om9O}QANYx12vPI@7m}S8 ziXIwa9dKdqib#koqL5KVG%|*WO~yrhBoRqTB{@>5yJzBC{Yna*AA}Rc>}x zdDtoWQ5eNg5~W31vK%U-3aSQCHQs5}=`~ObwNcNaK63*!6pcyEldd#JE3_5u$PVa; z&Y~OXg&yc7`jCAs`ZEv25W`TqHjHj(IQtQXk#uboT^mgwE5?%(FcFh5MR=3b#cXm8 z=8Adb0v4d3n4Lj+|ZtTH6?8iYI!f~9yIb0N%$g8-9 zn}*x;JGg7(KD!5ah)3cH`4rE@3-YxSZ@4LM@h%YWxqmQxq-&q)&V1qiO?)SnpZJ9k zwf+&34295!F!Znp4;Mp3x~m~FU5R3dN>`#;L}!j^BQ`rbaoEQd@yJ9-ERvE+3PVb| zRVsE$8j+Svhx9>^kvCSE*xAX<-cALs5FkK$PNM zI+)7x-jQZpO57PXk`psuJ#HV_R-QzK@jF`8I-GB*>=Nu?E9V>^HU z?m(J4GAo^IbY|BDUC|vqf~Y6&lwLOau8gKE=@PV#;6rV}$3q3Gjd1Lyp z6uJ`CA|`We2jZ|-;)w)gLg7Yg$>~}ux{?+d3>oQ};Ers_jy%XOJjjA5gux01I&$S8)?} za92DamB)BucuIe6ctL-SH$m{8H(&8X{3L%NTpj*d%0?7+(M3#BiEW5Ow-c9rJj6F7 zq$`Om+?bVQhUD}V7AcvPG)ODbkr|N*?#PO4$S!h_fyv1mt6c1~-1I!ii+ncnv$NyD z-c*oTDP+-sxf4303%Xi#V-BkByw$wuc6zYyY3M~a^fv6lRATE~y)%m(g?kJvL|NoI4(|- zf9e$9p`88~o#DHK>MU=SbN>gN=da2ePwQ@*p1y z7(D0&MH{j`x`?i%(hXkdfu4rG^!{QnIRrz+Xi^(PABzcMBI(Q|?pEIHl&OZ9^jU$J z%Y7aeIIxtxwv4_UE3neAiXNENywTRs*I`2tY~;<~;=^}2vx&Pio4G5#*kag952|gv z4X*8cW=9bD@$UZ;fBt&3o%Gx7sg!l195-hwa1TsH-u$V`e8>Nm zD*V`XsaQht%`JAZ{v(h*S zn({{R{7ahgJ^!ZWe1BkC@}`vot=T)%hP%>Mv?I0l^bR&UvJ0+Ge8x^^_J5)apYJNV zk-^cO_a-l9tp{D}Nq43f_utW*&nbP;&qjZC$^aV!*(rlD)G&;0XE^&2hLQA97>zL) z8;Eh-9U0F}nc&1kZl=l1Q!pJf9hk*lS!h^9R~CyUjx}D|h1G9oR!Lf?>&aC0C zti?Ku^~~A^x*Z?(n+(46E!gV7Hul;Mx-A?HK*II6*2WaY~#ff5#a<=g4_($^~2$m&nV8t90!e{kn}C?39}#fK(nh z@rc`FJQ1%*tJmy4;tRgwoA^%tz)u^$*oCYgxKO-NLW^*u62ZciIR;{jIAmNyLV6-3 zF(jpHDd|dTi!{vXgCHYs>||l@j-1GaJjg5Zkp)CYvManX71J;qbAo9u?;V-PO`A_& z5Qv4`7a11Q9a+Y0IaWBZlD)QyzS_nbcIzBi&tBPJ!-w5w_*!gX*0$1>ZP+e$kbdwN zJ4w?n=H1wX{WxH8h*>#;W8wsP5~pziS8&b7b#|uv%n$G!FT_jo6<*^VKH!u1LTX>> z-|!tj@e3gu@N>&X7JEZ9@^F7>m-~oHnLuTzU{fWgh=I1tE zvD04Dm3M*oz}@O2JJTm-<+J!ge#JL@55y1drk~78h=%_NO*#{Xdsq>kj9_r3M@AGx z7codBCSp4gms~5Y_F8Uw9^^xQc%YytLTW|n#ZVlj4Q1(e%Ck3BWL7GnGOD1ep&DJOE^3md+RR!V zx~VR+R-fJgjnG(ll1j56Xu%t$r9~^|)@X+gq7&KK(1qSzc#%CsFH-4k=u00UhLU42 z7UM7x(=kKLBIjV9SU@hqVl2f9v4&g^A8djzwpeUq*0$6A#BOpA_Tw;);y6y=6wctH zxJ+s{=r<97ySRt@77v&o;R&AN8J^<>URk_jRzBjB#b@TP_#u9gO2|h1`hoCpK}5JB zl8wmhOwpKQ*oeu_PAv9TaoEK}d_w}dk{C(gCX$iKZKPtC2I-LjnGNprtRg3wOXMc= z2@g^!C<>EBP!y$624!uOW2aO^CDcM4)I~is5RJ&jXaY~sf^37fXpasSotc#`=!M?s zW6_sc8Due-*=h(o(@5ASqZ}B+-ZYMRf|x=o-eNkb&7jXR%%;x~^T_#FWLQjJ zf~8n)SV31-VwG4!uEjcRfRFGcl`Uc`scge`_`x5$uos8KG4cdX8_v?t+ql5)lDJG> z!!6uKfVfBA$74LlYrMrf@qsjbWVZ8#{a1Xq_`&=WAsYW9BpFJCCc_{s!XpZzB8G@b z#uBl~I7lE8l3HTAlEjdd?&d%;_9=oWCGV_Ku}h2eh79yf$ZW_;&tb?(&n0q`e<}~( zkr(+KD8RnpA1KUcgR2Oi`4dI?yjF~ERh(T3ltd|%7G+4Qvh0*{sEjJ8E$WbUMLn_s z8j40_6EuYYeO5l($>(9uCy1O$j?04V*d*vVw z;V6#bI8KN&fPw*7aEM73b##_9z@t)lW!$6g@89CR;R9X!NdJV-_=<1h zI~k(sKSGgOXu1}T9^MdvuDHMzkq{Zt3^D0SEF1CJB}5{TgiH!Iq(DlfMFwO>Hslbw zNF_J&*~rgMDQGB4FD^=wO6fq9;jWZ5l%rR)QHfn;QH6A*DmSefU8_#7A!?CYZMvO0 z?3IS15oy(!oz{e|G)D^uTC!JK8`{#_p@Zm5DqYac(4DS%(H-f@t(WLS_7wxjL1HjD z#4waT0wXb6j3dWmqL@S~lP#t(PZu*uZ5CabjX9WWV;;K&Sc+v>jum1hx!SOnz8)Ll zgU#5AZ8o;E^T*D=U>D!98+&Z*Ww#IeaR`SEN9f8?9K&&(!dYB2T%+H@J=_-$$;Wt# zXLycRc!RfikFSPrbnQDmq$j^_AQGY>29h8t+>i_@kP_*T0hy5n?#PN<$YYV8xq$E> zl|m?j5-2UokXGf`DHTLTQmah2s=`jGDyosyQ3EwaZPKa^yLzaP28O0|Pc%bI(TZ%1 zwrFQ)Pw$9M=xU=UJFPdpj~GZQgD_YOBbAY2G-(>gJPFejjo^tEhL&`twT(9HIv6_Awa#=$x^i=*J2x-%L@&{s?2CTr zj{z8r5g6&jC~n$l`dEu`%;SS#0&kRwn1sog0&l}qx@j8obi+LQd@R61EE0>!C1N?b zLaZcLV-40}BYbRZVYeNA@W&qPw{ei&F>#zcfz!AYM3;GY%Fg&q;EK@gQUS~U8Nvjg<%AhRDqXH_S3aX-ps6{qIOLRn6LwCC7 zMOS)=-lWn8{X~Cqkc}bihGLkF5$r}{EXHGkVKRLhri&TmOfj2O=3uUkdF71#S&&^8J3F`~$T)~=h)0i)L`VWRBtr_3mP{wolNpc& z?#PO4$c`MyDRPmykq-qdJeZY2D1xFW7Kq~9l@cf=%8=zySyUsdi<)F@)I(!55lzWv zPPE|G($JdT7VYu>*tzSVE3Yj5`w-k6g1fuBySux)ySux)ySqcs;O_2D2=4ZNclFve zyLR38Ip+bAo~hsa$EU7qt+mg2=&9;7B;C^rt45Kg>lf@Krs$m9w z7Up9SmS8znU=7w{9X4Q-*g|f@F6RMuxPq&eYs^lrvsZ43yX1X5#$Sf# z^cQ%IH+bj4du|`_QG6z~FLdRr;X7UP-;BTh8-Ak)KtKc$LCN3!;SG`K%I}DV=!k)sh$Ui^S{%9-j~-tn zAeDqjWJ$`bC8N7Z&P_?-2Pt{0rJ|>Hk%ql39XoH*^G3@^H)Ud0vLLI-M%uEo({j+2 zoXG7UFFPflp#a@fkhzd3O#ZAQd`D3)ig8zpqa;d+(qtKwMLAKP)GE*`qOzz)`l<$R zYkE+NTWwL7RO+EV8lVZ98d}m@8`{v_wB@F>Lwj^^(UHA3op_^lp(|ZI=*F$*KcFw) z+0W9Sd4L#5DuXP8nUx`yq0HJa`Us4{IE;5OfxVka+?1(e8mUb8UzF;+z}?A4_R1z~5nD-RhhZmO*@ZLWENQyPd@9r7;jiTkAT!19Rs zv3Np0H9Vu+{$}^wgBRSCS9pu}_#i%#pYg@;mHy2~-+AYazZU#n*YX>)n*iKA3CKMV z0wahY1m$foLvXqlf^G`Q9NH3w*%X#J9Ks_4A{rvme@Ao?gN$j2O;_R|u8Rch6B-iH z6N@BdGLeFGl9Iiany#gxD`}Aq>5&1ML>4j|av-N6H{F(pU0&oz0YgE0AyI@>ilMkD zL24!GS~5tUFGRYeW5rl>{MLnAa6O-Q9FnxVO+C37o7Yr4|biw@j7qO+k3y(_w* zJNg*<(Fb5424NV6i&3O9MvNoJi;3i9OvQ8;Guh8_Fq@q+*D{ZJzF15y5lhJxScT2l zDz=fkuv_dQm3`Q6I6yywW4P?WRc_aD19$O2JR+SuX0JV^D=+XG@9^I6nXY_?|Capq z#1McU5P?KsQVEJ+hLH3y2rD9xkr363Xxx1fop&)rEHbW0Kqf>YOJe3ENNPwE>6XGPP zoWWVkdFBhaXt~0C71sDn#2={B=+N8Bav;XWQ19?~C)C*)JhU(C<&953(=AH`Qv z`6j-T{#)_;HUvfx1Vadf5@AR!9NkHH_K^@7Q5^ivPKoM4G;Yxm6R|~H(w2Z-LQ5j% z#7Kfg0$rDmt4p(|Ef6SJ0?{xh=hd0SR?S~j|y9Ncmu zw~zAhF0X@p?6iV(rI3rl?A;XMRt&{0C77L*WUrJml%ac4mb+38DCxXb9h>4E514-u#!ahJlM!h z*<{#4-zIjDwq5Mp?B=HI#Xjse{7F|17!J`*hnbJyq!*{SpSGN1wq0PSTr^ywE0@I; z@~Y)J^G)2sZ6Dm_%{@H8!=Lbo&pvkWgq`UxX61!=MJgZg5uflGU+`V{Yt26+gMa*n z01g7OQvw-+(ETbXpYbL*Z%iSWO(B^*3B}!4p?MnyVG+&{k*-8GM4|tVs3HdGiHRuPHLs;rn1cCQPEI^u2geSgIz5TYID=-((9oC8ln*zd(ecN zsVTFsn( zybz1AL@Xtjd$5ArDy+sDthKCT_GCTxjfPEhWixgdcG8tUTSon&AdryGb|QVz%98r`)kT zWcK7ScO`Ng{@x3Iw?t#sqSIp{jwLR$5)TQG(2|JRo5Z|Pl8WSHN<(UTTBJjI2N~F9 zHe{h|S?O9fx{||?ldk2WoANN{^&metTLE^ag3N_b*iwX9D@Ip}TS_r&rRn8Fd9s3~ zBC}G-P?_$e3VW>@y*BEK`lQkTjnKr&XpByOWmF%-VVS1zZ%D$ZNQc8@P$v;tpxL%dFj_EBEol#Z&gr#7k0p zMR)R=z4FGvdv@9fy7J`*edTkuZ|wZ)JD>R{_-o6bUmXNwrv;|_RS-U-1*L1j=)pw@ z@>dJVciKX+GlgOHBs_N|GNK^Qe_39Bz9;#(dy=2Kn*!VlibCYiD$I9yQk46zQjG8V zS;hGdZ%Xh+DJe>mw({&MIH<_3lBi5-Rp?4pFRF3Zs?$xim`!zc1EKIm^4K-Y%Qm7y4B z7)~D{Mw4SO9+NNyQ!x!QEHjyvS(q*6lTH@0Um}*1+6wwgv5HjIU@bOci`YtrX02$VfN-2Z;rb-$zC~y)8Y(y-o-`smn~PAm20?# z+qi>!c#4;Jg*Oh~v-^lo_-y&Y{1yJ&{YM}&u!ErNf+09UB9sVChDBsVK~xcqjA4jP zSK=Zb5*iZG6I+rnYf0%TkqW7i25FHInUL9#g|6g4Zjp!7^3wC601BcAilYQdqLe62 zYUSvr^2}OAx~&qspH+qL@T3O!ny8IBF6y#ZnxHvaprxf1b2~$OdI!;wRJx(Ni=OOz zqYwI_KL%kiMi@rYM~N|{GFFTu$76zFBHc8Zc`Bx3rePL+j+jfD<}usmv-8yg-YN?n zEMm6=%di3~u^MZ!4(qW&Y$Uf}E4E{&VL$y(ae#Dki2Y&9F=p*JT{}THonk(XGnTW= z%6V~tyok%Vf*ax{sokP$x9N9q7x(ZGkHr)6DPG{EctyU(8;ig8{2pKYMw$XJD}fLg zK@ePoAeE4oP|Qkbghe<@1m=i_NOUDKez!zpR-$_li(4EA@z~kov-67tyjKz;k%PqS zk|3!e1^rh_$@e))#okF8_DcF+AS2&l%EX)**?vNHK5NRstmH&qsDLV{YN$c4?L{5#^-y0lARD4FnxVO9LADaD$u?+&Z=GGr0x(EQgp6i=(7+OdKaoCzwzDqz8QdAs#t+!cKcee~H(4hxg(O`Ca($z+XQR z2!S00WfuY=5lVz1m9QclsYReGkq{YCEWa~H6Vb^SA|@FZ36U7dkp}6J0hvV>GOHy! zvzwgUav`@NFI~we@{_g#>cwYzqmSrIDuWyhVK-C^Cr4nUgHi0pV4Pt*-86xDl9){T#T4GVnaWL>hUu7rnV5w+ zn2QBiXj#O(SS%rxWnv|%tj1cb!$!*{W@R(BU zeUyrKsgce>dUl><;I3puCPQYrlEspZS;>K%$b-Ddhx|S$$eRidDzU4KP5f_CR4P?1 z)tG-qbw01vp!=dG@3dNUTWxlAM14|e;71L4@1_wqUp3~fn;^d)%uX9Z*M`$Q8N+?N zm_Sa!R56XTO=ma5Fq7`dEbg-{bD8HE=F^o0SSS{ei?PJ8l)lWef_WuYxmd$qTT5Rj zHjuvB$XjI-wqQGUI@rZ-x7b4}dp+34&6EAyO$V3{;*jA8{RB?p60VAC) z6A%Ca5!eun9$bVXLyItEID|(85s{2!h)n<85S1PcF%T1R5MLxB6FW%CE}4tu?3EOj zl+3A-#)Gune3g#3T6%g$OJ-&zi^xVQ*^vXe47uq_9!p;4{DuN_Ck5FTLSYm$6sKz? z>7@*1=-!m&O*seU+1VZpUd7>jWjFD8)6L`^hUxSf zVkW7~!febDb4e%j*xTl_TZF}yrOe85tnkrF-q}{O^JWci)?&Sb4eYdy^i9}|tzrl1 z7dv_Hi$8d0+QqEwaj}=ZwvVpur`ry*JBHIZhx3*T%*sVva&U#6ldJ5NYYwinQ*Pj< z7q_@;x9O&P%%+FTPb^QFZO_>KjTd-{S9p!Lc<15+d*!3}Oe$X;d}H@r`0LD{2@Su| zwZL>Gh#@H56pT5z7a_PSp%GSuBee*0B_g64V$hYCA~qQp@kIhMF_I%C(pb_nXFx_n zCc2iH?j#F)Q#R)8h8%QLZe}en-ISkMD?nEY84A;jh@xZ(OG)OkC@0F36$};Wl~7q! zA(d(lsGrAbM(YvFE=tcGxeaImg>R>oK zWh6$4F{Ei6^JGl%U@A8!)7Z}xvq;li=EY(Oxzwpdik-3=Ys6Y|omfxWHnQ6! zHj~O0Y!%x{Z72N??80vBaj=)&ejE@7N!wv|M{vx=arVjyFHUk-PCGcm&dFK!=PWmw zmD{*uxyO88JR%<(p3;?P;%`!Uj+c0aH+U=Fk?#$k>B<-JmDK!q;jfbjh`{~&ojC_`iQHs92L;#_6opBx2;Eeaxfn`{QlwHEWenx$PRg@aDvHWv6;w4;r)xFn zH4U}tbwpjVfoMo-jp&Wh3@yExwGg>I_bq;=_C4){lx%spcq7&1~U&4 zLrK3F#{1#F$Oyh?l#j;nP8&-%jbnB)p1m^BFo{0dgDKpcOl7Z4qbt*0%wRuL%p!d; zhj(t~a`R>$Z+x+UcZ;xCEFqPpVi~C|r@L9nZIxI}YU}CBMr^`XY%^@9?{Kk`y=fP- zZ8tm99%j>C=6zy6`6mvE!{iYh#c`Yvr%2^A&WQ7*azR`quZrvB4cx^&+{YvQg}?C} zFYrpdCQToiwa;|Z7iQ%vzTvyYUsrx#4*!AG==q_TgS7Nz{!#=KvN7~}E(-P5>ASsd~1yUJO)6*cmAv0acifqV@yvQf=lLZWg z=|xZs#ZeNaQN~4C_7y}$vJ$GJ25O-J8lefAqXk-e(2ASV8f^{T=t_6=GW4b^{S5u- z$^gqiW@WI0A?&oF^xCH&qD5ET6n8%87q%r}M4O8gTFkQ?fXBlSGl{uIz=8>lP z%*p~R5{pUO5_ZZmv7B6CS;_2V6?<(p-N_pE%37=w>q%vUVH4f7nc2x!_NHyjPPVgm zvV*;8C$pQ~+_XJ(WuK1@^3KU2_J_q0(ica0r=6sqa&emd8OvE_+j(}{CAxB1TqUpL zhUFHscAM_a9o{&(%lx1Yq`6K;8yIU>8BzE5ZCIIPaAZhLH47mT=5U1Vk25NbPsJEh@X{h8T2H zOlB<>-4>T!JQ1HvAQF*@kqpU^LZl>Zso0rPGizz+X;@VJ(??0OzwZ2d9{~{rK@l7w z5k`a~ZQatKIizVG^8zfyVl2lhtiuLu#3r$s+=^}3 zj-A+rJ=km6$9%wWkbVe93`gn8F>#!9a*Dlj8s~7{a+%q5h54Ev-QfLAaf?*$ihHE5 z?(K$pdbo~!lY8}Zq&(744S!whW8uM9G z6K1U`-AyxYo;2rfYr#%wiPoYW*&wnbKlVz03=jiJZwB$kG?>}RQ1(uSvsXrlk>qGGmK=xin21SYDmhKeAZKEZgL&+1 z^Vu!HBC(j%me6fW*)78gthB6RR#qF<&`s-@*JA^=U@Nv^2mZir?7?2_!+snPhseV? zic>gkI72@tE|OPq9k*}?5Aj4iC6#A}=XB)-UgCrJNPfl_e8o2e=*jP^4Wa4bM0hfW zh)KpW#HGg<3CM&Z37Hhh93*F_q!1~|)JQARkxtUH*D}!EWag%1K~`iJImuiiFR2tT z6r^i~=!G2=WmgQvEhU)CqP(a;RuompYN(DHsEbCTDcJ%oMH{j$+M&JZKz2lDbU`}O++VJ=;nkCj-Bbz(iKY`{ir#ujYD zcI*&4$vgdghm8IM0#XIL3(6DW|4!;gS;q&I)=LR`e=ZL zq6yg)twl$&hv-fA$3P6m5HW%rjR}|{rjpYz9W%rs@*Upe3;gxw&+G_-V2CN=ka1na zW3MC-2}xTbc1mKAgw&GKZOPcB6luxy$Re_mS~hxaV;X)D04pbv`hMk!_}K`-f`6uWYwJXr}fQ5y}=STrSDqBS}iI?=m{?xd+F zb8pdyRQh2c24M(>Vx(a-eXN*3PBcuWPsJ=Tht%fM=V2jMVGY({JvLyIi_Pr+5C_P^ zI3kXbC&U@@A}-?^uH&Y-P2MrwrQgQ`JQUAJjpZHl2Yke5;jb_M8G!%@gy0B^ zs3JP4#6T>>Mm(fMYNSO5WJESYcDj;77~NEoxs)hFmNk^8YnACW zP*2n+m4;}Hrf7y1Xo)uHC_0hd&>elzUko4zVF-qak>qHM!$eHRG)%_~%oMZ8d02`S zVkNl-Yq1&I#SZch>=FA&Wj_w#u;m!@Nt_Yy$oKe&@9^L6e*~bX5Gl!2A~l)TK{|Fy z2191Lk_A~sb~2C1OXd^#$pWGFP8IOS&21RhxOQO z*~+|4Y$tb!Kgiu;54jJ2;xLYgqvQ#3nmmguxQ3g!gS+A(>EsFfr{XX2jd)9b5MRiz z@ZX=m79%i%Ap}Arj0j7H7m>&)A_f@~u@D~#kPwNG7)g=LgXG*&7*f)mq++k67HLT( zogqD4$%stIX35U1)Wwuphr&K~!R6{L8 zZMt97;k{B9_0a$gT{L2^HKi-f(833;c+=X_hPkb1N1D1Yo4PW0^P)RAnsE!(ukFpdlKICZwCD+?pF&(p#am zr7d%NbV65jLwC`G)OymD-so=_Kp%v`7~)_!yO9_z#**X3L~@dtOe#~v3{shi*@ijv zd15}PEO4-how5|m4J+wu#RhT{He)Nc8+OunVYg);^M3Isc>o8+AyPX+*N)PaW8wsP z5~pxloG0B};C9(?m9AVfT&Lf_P29q52Y1+Mcj=~k%uXJ%e`I;W{1ngdT)ZG(;f;7p zD(^h_$n6Wh!Qa6D@J|Lr5ClVTghFV9K?D(zj3gqHzZ;^_qa&sv7CkQFAwCiyA(9{| zk|U)^MW#UpWJG357UrxXJDCIdMM1KVC`Ky9MF~4Q?dF_mU6Bg&DUl;^Hhpeq$o zNmM7b8uXf|gSx0E>XQx75RF_kX0J4L(2||fTC^eCx@gC~JvyMHgHG%^8@kZF>B<`? z-Pm^*JxQ$>-ANzzw!Z94{g_StnUw(!2C^F@29v|Z2vQqKS4N4^q%sZ@F-c4zJ(L3Qpw~;nR%~dagmjMHe|QtWL9z`AMzUt(3OIQLi8di zisC3?C`m7c(uT5hHx;;57R^YdIa;8lXhpX5pgp&a=;jCAdE3L%liAjrT^}Fy=bbW0 z3?a2)bY-|0L5?zvrYmDG7UM9%Fp=)fWZo!KFby*>6SFW|%p;XWmc`6Vu^cNMtYN3D z#X7N(+-%vxyjAQVwLj>}F0q^3BleQY0UsRVjg!OdZAaO;ImXR)oSo?e^GP3_;+=My zu3QjT$!mri^jo;?;10XHcz{QEjKA?5FYv~Lx7@UM^iTMVZwNA&-&-O$LLe$)ARZEm z#AH$=LrP03=F~_l(vj(r37HMq=s84AQp-)xgM7%3LMVkAKN!f{L59I}Wr%~} z?7SJtn^A_bbklfdZ8Ci-ritmKX$G@4lRit#A?F(A(S0$WceVxW7GjZu#q5+NScc_d z1-a728ur>cy0RV{u?1VP4Lh(CyRk>?BM;!PI6|6^G9MEsNad8_H2oaT;{q-kF3~Sr zt}tJ<++@~n)9>Pectk2s4bSMx-*}D}c!@XS9jSc8C-Is5h5$qOdu|A72u=^-AS632 z6kQ38h=^o~%p65TBcqF0WE{jrJS0R?q%fqWD`}7x8AWC?J8~kQ$WInTA(TQH9L8~+ zw47#ka+baA96Rj-UAc&BxPe=^Bkq%r#S`)+Ug0&~;GK9+e!^#b5nsvg@IUl_1fVMc z5eOj=5}^?W;Sdp#L}XHnPLCtvkqMCm$wW#r71ARkvLGw6Av^M*APPAs%1$dz*GkjN zqXH@#D$|uJhN^U>x~M@aH7&K6wc7LsXoSY1De0s+`*!Gnj_8EW=z^~3X6R10^Fz#YfqAXUonmhX*;inQ}2}x#>zCWt9hOxGC$fQEVc&Vh45_cGLG@FZSaA4vVAY32}-%i_5r%>*5A^ z2lsFv5AheC;Uzxd3%=pI@Hd>_J0Ji8A*cvJhD2zDL3l((G{i(4Bt|kM7b(efNG~#w znM7tXtH?p-MgbH-Q4|x!$r6^5%uY(N*GkisGKLEDil`#0lQmFF)FtZ~>eH3RXo99_ zAzG2GMO(6y=u9eIL|3vKx{Ds9lb-B*S$Z=oeMNtAu!|w=m0=i(QDQWyjKw6(z%0zg zLM*}xv69qQ(Y4j|P1uGV*oocPhy6H!LpXucI4drYm&9fA3a;WBuH&|NMk>$o3UBZh z@5Fmj`H0Wr3;Ej!{__k$5KM$4!;45{6hsx#$mk*_84IyRTrwUKh=gPkB(tPo)>6__ zA+<@6cB~UBBChirWiLT#o3n-B}uImT`42VlI2B3QmJIA z!d%r*jc%&RTnn{D9kQOGKHW(J_DWaLgY502KD<-3W zX_$eTViu{)7W2sYScJt`ise{|)nXl~Y{E8d#}4eo9_%yhrz?Nrpy3c*J3?1Z;1teS z&N3_K#Cg(J7kKOBB709RaaXQ*aFd(u7CXPV&3kX|@a8V=i3g;<0YzXks0c|ap%7YxA(e23 z@N^}Dh(t!l?}&yNh>2K;ZHPlx;u_-9og`rIi-f#$l8C*QnEo@8@Oe{G=46HxbW=)Z zCACOHDrvn)$K6-yd8=eZW@JHDKgh=0>>?-WSGoC29^@7INu>Y^ib7;z2SwRw#puOF zDYCSo4Bb|aU3o(VdPP)16;wwp)JFp}L}N4)t;ja$h)(E&o}v%g7yZy5127OnFcuSB zOk}T2!ca zoFgybnz%tez(f3v=av`DukZn1@eTe*@#g{rL~w*h1Vly*BtSBxL@H!JMr0OQNF^(B zAfKp8)$b1X47_N zZ+7s;o1MJ*!?KInFZS?W+3R8-d((dAKgD|f|BM}^D~Ak+>Dm$cQ6C-S-Enb(w4G#U zJH^hE)7+Ia;vA{1q5leZ`JP|l9^c~^_jzx6z-)TRYZ=Ul;dqMvhFZsMT zuXywN2fg8QZymg6_rbwOcApHN=|AfW-(mX7tb8;08_hreviN8I4FL>+=t^J&5kW~U z7(KXy5bU&&bR`r*Tf#8g!m{%u9CuTAW+xHYn<6qRkrBm3RQAzC3{r{dMJ(=GY-WI=B5BQTS0bC3b8MYB8H;$ zVkquG32sVBFG_K@m1gIrEH@|R*q8TF1>XI?q9XrVwaWA=4yv;ArUq|pwb=QhHt*_) zx@3Jr1G>`4L1T75qbZ*^HDgwqix#AtmfVz9qAjVk^HF=={Tn*)b2_4vp$lE>MpwF{ zhovWTFVUBD(vSTB48$PIVCEr)p>%B+T^TM$kjhAmGK{8=!+6UiW=|$_SEl|V)A*hl zhM9D4X7R?8+1%$C=F+{H#~Wq7gGKC=#XeZdn`KxoR*>t&deXF+c?*s?IKl1|E*Y-U zuX}Nu`(1I5e1yO79IwS2QhA5ZNI2#{l90)f3aOFCl9pLXkAk8&X)3{ND#@&rK}AuC ztcseb@1hxdr9C>JljuTrHFTqEJ?R56*u@a`rlHKHVay}NC{h`Nu^5N(hAH%^n1R`1 z4mtN9G>`Ar=F_zWbY&rySynJ>E9uHAti~Fw!v+T%*==&LncX%#5|7CzhG%r;Z#?(l z1vlFpcBc2t+DH0ld@+2bn|>S1p9>KjArT7U4N>UI?}k|P*ocStNPvVQ5ot=otRzQD zq()jpI(m9!L?&c5WT9uZWMj@Qa*?*&?36qxfPyH5A|4dwrj!zu$f~G@ny4-6kPXln zP0$R@(E@D@?djfh;Ekyhv(}leb)hTW(G&eJ&@h-j6vHqaBQXvWF$43l7^|@cYb_g? zw_%TAFJ0S5ce9_H@~7nh^FbWOF>#zcfz!BzE8+%u6Su@|QoBRHi+gy4CwPh%c#jYG zgfHSN`Ca%M$KMA*5ClgUgf)btM?fURKy1WCLL@^QHU&zVwMuj zB~ezCCo7^ds-u>uO)7OPb(u}|nY9LVrJ;i+?6hX|7HEmK4%)G6kB;apx{{{u%stTy zz0n5)Fi;F4M_?pIVKl~wv7|PEu1pk@NM)*F2HiA^c{b)?9u^oD(tWjvx85w~jj{ww zu?)*ytYE*&2Wxp_TF2~U1AEg(W@QsLi>;)x4cjd{n3bIlcC%CVxj4Z71Wr3R!|rFC z<@4tZ7wMP8Wm36{Yq;U!CVS-;ZsRWQiTkATKs+Lq$9RILhG%r!-|Upg99;=7B9M_p3^J)mO`6g$r$a_$@`KF0wPj(aWJNX)*7DDW z)IGb%LFPhkffsXKl6E*=n=bt`8E7g2Jqc(263|u zW~U5sFqEB>VeE(hfRTL0G>X}i(cDdAn6icJf~N1G@~n>81nBP7bpFQHS{K&pOO^I61=J%~5V{j&akD)Bj&~f`9$m zNxH92@z!*j`Tr$n_}A+fXL;|*Iqu4Nae=g5Vt3hch50J3{V#KaU(e6D$>%+}#oczB z-JM_LF5jcwqnjQu|A>ct&aWQvng52z{9Mx$X5}vj&)EI#;yL>lK6u5Of68mVTX|!6 zOIO}`@t(V1ec&_NC;C@>gTD#?;h(hq#x8&%FkJ~^3CbJ{!GAzVKBI-9+rqNb!qGhm z&)ruMcpK4+$lTrh&do_w_DZyWSWLcOi$z!BcoCPo7N2fQ$j%puc(;bXPpVQ&OizNO zmSoJPbJ$WGO>wx>km6E61+9p#oj0h)Nz*=4PwHt}1HyK`q{TQir=I zb-8;|kNdx&K0n8=8t@rYBWAy7!h5Bur5Ur|9{T^H|W9tZGJ>gKKD=Q#dr7qKcWx6PE%jzexg6A4WOF_ zGP@bX%`}*Kh!2MHMj2)q!R)J1ytR#HH`a>@+_ky%d6+L2khX>FOpBPcC3I~mU0LR0 zIr}wOhwa#bU1B%62Ya#KaDZ+*$nMZjILv32BMy$TJ7zde_r(d`IXTJxl#A2sZD-i| z>MU=aoMZp9&hs69b%D<~xyb&Xa*6L&uHqW5`{)Mmw3~D{tNHVd+s&{0Tl^fqy3J>N zb%(cZ?sB^)?voG1V^VuU_vR^Yl)oH2W2d~tYw?DBi+3*GvsdCx;?JQX0h!Q}oY_eV z_9^`!6>t3_HSgV|;pQYQ`~QY?{M_`&;6*0xrmW0bHhOlEgH&=Nm&i>jd63VLpRN_4 zn+h=(_MiecrJ|22@lL5Ms*qY$dNnVqb60Ahrl>{wqBigTEp_-=wz};6sve(lQ=eM{ zOG9Q`BX&+2v;Wna@SRSYvNttj_NF;+Of8sOqP36O@J?$>x3y!ZwWoIw9Z5HxxG9~{ z)zFRJ9X&9>Fp%zx!Mq!S;g%81rjg8}e!yrxqm83az(m6&x-vyfC8uG!gIVnSVm|K| zh=ruKh^{TBFTqkQ6U)gJScTP=HO%Y82GX{Xoj03#qiv%r+kLc?ce}+Na5_S zHXNZVM-9j5ZjN&^onY2Z(NE)y56C;y(gKtyUENgi^xi5^Femrm~t>HISsk!ZgO*Tl83#Pm!8i> ze)dYiA5e(Tcv6_VQp813_DV4a#o7G|CHS6yN=d%k7o~XTtJ1vvRm$>RS~>d9D$jQ) z6FPl@Zf?4B zGxcEZ=|wN@PI|NN^Aq~=*?xZ1pZ9~j7|h+1A>4n|Fh1*7!}*LaM)1y?k-YJXQM~`R zjNxb5#{$Qu=qHDY9${y^+esO?Q4&o4wh@+%(T$~_Jic_TN zG_!IBXT>>EJ5Rr0xyWp~%&c9fYd7dOEw`9&X7n_e;d z;x+G-w}y9gU%lt8@)4gbpP9e>%f9mSeuZy*k6(S~Gry9*Dg5_W|Bv&}uiqEH@yiL>60mcVkeiZ7BqnXi*eS_H3erg`_CG2$pH-isg(4f6gO{5^F}K}SIUYC zq^%M=Q)T9#QH9S}^`IIzH#NCAsm0z_hh1GS>T!2dpIZ|LP1z~UM02tgTBEIKN7~x6 zQ#!in#9r%6?}{Fx7ug2`#6VIRgdsSHL%1bwlXvkzJS0tzm~D^Q`RWO8O;4Fke=$G9 z-{Lv>!i$&OO|O{$DX;nNH+XA!NB8DEZ)_jf{fLiz&M!Xk-pyxj%9kJXmCtG4=$?G% z{;T+#%I_at_-F4V0Q-Or0&&KS;=1CyCf6_96*)Eh$|~Mo%tMklv)^jglT2e3X%Q zevygyrp(M)ELoYgZ1n6RCuz#ftmUEG^0HI%ivnapOCe@c5$58SlFV8ux>5#ZQBIU6 zwTkpgsO$$-cx$T4{Ija@9a?p|uWImCscEUjtkgyw59)GrQ;(Z3>hrDv8u_3xZ+^8V ze5caPMRWEo&{gyxd!m=2H@%;wKeKHBJJUdBUku`%lfmq@A@re!VRR?M*^dyT$e%Hq z&;N)qd`=l_8ON-Rr<*1)+a|J`WSBx%rW&Tv{c1X&vCUv-o5fCwLU(eNy_;*?Zn(I`Ub&0E#53|aUg8yA zi#Md{E%OI_#3y|Aqc6PIzS6&0{7>Weik9D)l>j0T8CV1*mEa;I83tiRI8q6ZNFp++ zL_st|bb4&WLjoiciOD2LieyM3Qj=*#MlzFw%AINJD#uQA&bj-voFXnKci}_gO#bWN-Qo6RB{-aj# zStl#mJ6Xm4S6a>YIa$O0XRPJ($~qV8+5ZX~_#R~=HvNRne0Gc2N-Ep1)9?q~n_awd zvxl3q7yHD1()K4i?Eqalh(m_Mbmgew7~NOLd8?fI#ZL2m+8O%4=`26*oH$SV;sWnX z7nyCB*(p~&xW>)RO>W99afiI?;2t~WJ|5tq;R#)PO1J&R&h(7g&2w%qEH9Z~;kD&0 z^Lz1u{3t$?$``|Ty7t=)e*b_#2#lZzCW4b8L@3f0nq3%#Lqsp4aMz;Iwdiy=F}TGP zu}Lj1U5iJLj|51F#7JUDPFGSPHPRqGGC0V}PRS;6lleqJ(o~39DU2eb7+Jzll3rSr zA#6cX!F|m^Wp7e4032~A~4x%)9zA#71(HVKaS;*h(tf#18Tgv5(aD z)BnUF9L5oGlst|zI4drbS8xs2@c>WpH(rRhgtC^9s{7$VW5B06Fs4&ox7AwE5UNJu6^QXeJbov%{yHl4^!Wh$u?BDbB5gp(MQ&N_$Y2o2?wX@}dIirV=+(WoBPg;hj`>!6;fPyT=8+jUfy>)QT%yPb9iwqjs+cVKrbc4A?7x7b*SqJXG?C@P|2 z7j}1dch~-2d!F}L*L#oqdBFLuxqrVg_8*^d9Orpn4|A@yoQlq|lrHEddXT;0s_9Qx z+%OnJ#8A>~B)jpLh)I}?DVQo|lFBU1#vHh7=F#Vih2&!4K`zG%%__R$4Ikl4>in3M zb?_GfWDquE3qr6%>?HSKFZPRrq;gbqjIKoBBuTK!$gYhiI0RL5ot(D zPl1$3CDM}VkO7&H8QG9sW>kj|!-Y>Zpl2a7JU%lvJ9bIa;Ef zi3@XQbU}B~o9qi$48&kDj2t7zlFB$Sku*%EPs0q%#2n#H&cmWeEaqu@{+z_|O+u|;1%RO%Q@c<9;*yIVb@)XZB&*?Al z5^ppg=pXI)%=2sEQh>31`$rJ<)({C>oPW6EsB&v_fmq zmQ>nDq67Dia6xAaUD)ZmGI!VXp!c+)7kewN?E7i@(+7${q~eAlHVk7wQj8)Eqv>NX zR!kr#Yo^ha>6)4JSr%rqi;6kCv*OO)%3Su!e6fHuTgXmX1P=>K*x9p``!cbdTmerz zR&q0V(Ic~(H{N!v;bvG%H~7%4__B|TA8&N)n63D;SJwZb4ZOD!$X*E&TS#SV6m8?3 zvR$*At_x@WH|*i-?zeD&U1SdN<}i*#;wX13$JlS=&+k-5Xim^i+Hi`!?liM<<`13a z{W%-Xv%iEZ;wpI!*KrfKE!<_NyT^QAJRl7Z>4r!2$KomZ953(^ukc#DBbE2~6h+^7 zXZS@|ek0myzULM(NF}C-MH=GJ<076&Kqf+BBoWETXGM8f`=e($JBvxS$idpqr*Ay)RtRPYfUj znhat#xY2dPm`93HBf|3%G>KxFT+mckmF8HBaf! z@lw1Z-{7ryN502rd==lw?>78kul&R>{I(&QH@}96n4}>VJx&zG<((lO-7G%41SScY z6Kj&tqbeD1ZAs28wS_e74C(0UMF!H4k#3fmoz8*TkcDo@O3x;8kU2HE=($buFguF8 zq%I$`k{<=_D8x-EjAEiVSwd5qUIt|~<>=*6!9rzrhU#>s25O1gq*)zyiZkl{fd;%) z8b+cK_r{_*X=q7rh1O^z+LG-=ds69$PMR+C9-5wXU2o<-=qLJ<127P77>pry4CST_ z6T`_-7%e7}$`ni!)5%$4HfhUTZu2l7i?IyLu|l(wu6V&a5^K3DK6dzV+aLl+vmkbx z#AZ?n5!=a7v4d2?uoJs9yXoO#52@@G`$*jZX5B&N!y$r*A;vV@3kMRW0 z@e;4_25<2JpYcU}C3WAJzgzgl?l}-g_sNHNBA$~kBJq;@JMn@1gwNs&sr$l+l!>mqQg))l{Qb zM-5F)dM(t^IMbV;sc1neEzufn&{orq-T@tj3#oKPH*`l&(TnVjzUU|VlLIlx4mWOt zF~q`9c4oua*)xLsNQ}Z5lL^eqWHF6Yrkl)Qwlb6bEX>x-q1)ol%`lg4m`ArVpZx+X z(k!MMJm^dQz*63tEn^o|%Xz!Pf+xF`8ZWwG6%4lo92~ z3aE^#s0nA(M?*A5Q*_dFrt7*gchhvI8+y={Ug(WJ=#PP#L3B3^)(oMK#27J-oQTPo zX~RPH$`Y}hTp_$jWi|Y;9vej7+hF6XI-kNs$aGG^yxH z8l=^vqbuo=L1ZEo2a$!$DzcHeL~hcMmu|>M&u>zIS?9!DP*aFrL=+{9M?neRloX}O za-uw00hMg1%wAWGS*b2+lZvyZ0lgtwprvRgmu;TR!C zl4hgWnT=*QMvNnEnaFLbW(Iwxm_^RPZtTHc?8AP|0s2ABA-drRU5UVPae_Q4PLaxK zoDpZqbGU$uxP&X>I(Y{V@d%Ic6wk#A@}+o18s5;~+VGye@&TXm6VcZFEheeNLOjGr zLZlR_$TUc&$w1F2GLr@e`k%3?)P<(omXSR#YLCYN&zQ!kJX+q8{p_ zu?zXken$vA*!A)t2R+`rIj>3iPj4tRZTuEghhGG;(V=N|O8r#07=e)(gNc|drjS!H4KpstGKDTO}{H1kPkJF=}+(s&+!5;@m72wzi7VF4d3WL5p6xc z-XOM!OB&+S6NrSQk_dkxInp2<(xbcRL-xl&xM2u}Vw{*jPQql(6uPfiM=Bdd0I3UN z)@@=AMhLcvP;w8BAVQoZPl>bSW!%OSyvAF+7az!v_=Kh@?m+Qjlqp1-VcHB~eP0ChaN1y{xE2R<=-;ol?z?>fFp~u&Zf9E%r)n)PXbV zp-~hy=AF_c3YzjpX(pPJEj4ZEZP5GA9#{rXv68gKi`y#AYP#Z$wZexq^JS;_Y1Yvd ze>>K5vt4v=)QCE+%tiV(~^7mpLI4iNDAsNQx9li6(Y5<)&-K z+`@*I>LK&-Rb`=J@{INp7hA{<&CQy{kaXs5DdjI zF`P7vperNADALMk_Tw!~WM`N}H=E2(nSyC{%;2V*$vhi#EV#2-Hc}7=W;5AYP{7Y6a?nldZR(E@EnJF+u+!4*TrFmj}36kQo> zGJ$!rm_kk$Gsu}@78#k@yqP21NyA*aVLpA4$zo=m2lEoKlw1K%tb~_^RqVWl59w>- z$87MYD;q@s87P9tP1u61VjH;w;o<;!2uE>ToFFfV%j6YY71v4S25#X#9^x^ci07o? zCH)m%;|<>8JwD(QzT!Kg1@h|xVj~XXAt{n0r6v_UHPUF(($gWm$UtUB7UV)6jU(NV zkM1N2kwrA6=%rBsl{HoA)leNZP*>C=8=^6qixy-{(TZ%1w&cFiNs%IGLf82fs`T*X-H4ch|I_# za+0}`R}>(fL_xBMrZ~N%C`~G5P}Zb8b464^HBp_krv`VWCTgJ$oKX)A&`>lXmFAij z^wwyDwwiYI_UK^Jk-0OvpeuT!7kZoYVeX3oVjww43?_9$n3drefl(MO#*)f-%>?>H zOcqngX_$don1i`kgk@Nc6<7lwtiuLP06kCyk;*0nV+%sWb}|$@EbL^b?7|+gk34{b zI4mN_GdQQYL|3ljChp+@Uf?y};Dh)`e#RH^jr@h*nrNH&xla?F9zzq09+}v@iHn3H z5t$gtkQy09CNgsrW#L^`WJeAga+P=*i}SjR1-DHTBwb>q8_Q#*EFUpO+_nGX@?HNh3tZ!=nGf$ z69Y+Qkj9N}7(&+#V;-RyMOQ{+ET&*8W?&X(V-DOg4@<;SayeGO6JA&YKdeIl0uh8w z2o_t&5Y1M)5{ezzi~Tr^V>pgeIE!<*jBB_d?vjT4bmak_<0W3?{N_Wu@Dc5krJsiY3ON@5n17gd?<(_D2n1Jjk2gHDv>qejJl|Y`e>kO zL^m{}w?HdRYr3H=-O!HS0WRo-t{4C}496%jnw)@%n1-2{jX7dIsVu}|;YqF%t4VL+ zL#{(0f)Ijj*p4vl#4eM)%!Y&Xqd0>LxPqIwjk|b==Xi-XcrQMXpTrmPtN20w62Hml zoB7`naghj#kqpU^0;xqBQb}t=diG`+*=0f&WJeB>lhoyA&ZEgo&krXQL?M(Fl}JNX zdM(sLGm}=#ZP3=FJ#$ClLUuwA^c1~FLvOm$7aREhBdSzfHT~%QF(49yxVvHS9~#R0 zVHkmt7>)J(y{J^iVLT@M%O>&lCyObhG6S>WZZelynJ*TQ%0euHhgeD)meF;d%(krL zrg&*q)9vx*uB?R*eBp=nnhkU%0D+oK^k8g8h-L?UH}>Hmj#xOxE&``;78h_a5|_AN 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%0D}6*iQt6KYHU_a%24jc|hVo{Zi-z-V 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±UVXGFadMKJW`uaUnmxl%f)JP9X4VUc40p} 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

    *t7Ge1N-RH>j$^}xpNVi>P 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%0AB9Cxvbd!Lb4f!fdO4IgRG@2>=}HwZRpp+o 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

    ?xyeMEP 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 literal 0 HcmV?d00001 diff --git a/example/index/22_20-21M_snp.2.ht2 b/example/index/22_20-21M_snp.2.ht2 new file mode 100644 index 0000000000000000000000000000000000000000..009e07d45836bdec19a950d2626b07ee7bdd246a GIT binary patch literal 238700 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 z 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 Av;Y7A literal 0 HcmV?d00001 diff --git a/example/index/22_20-21M_snp.3.ht2 b/example/index/22_20-21M_snp.3.ht2 new file mode 100644 index 0000000000000000000000000000000000000000..4ccadf0bb401d23902ea182319026d34e6f21a6d GIT binary patch literal 26 dcmZQ%U|?VZVi5R#l%0WbK^r5(%CD>p3;-!e1d;#% literal 0 HcmV?d00001 diff --git a/example/index/22_20-21M_snp.4.ht2 b/example/index/22_20-21M_snp.4.ht2 new file mode 100644 index 0000000000000000000000000000000000000000..c699c821cd530aa6a3f56af8ef34810c5b05a2c5 GIT binary patch literal 225000 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ℜ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

    I*J%P+*OT&2~uO{f^!W5DY*+) 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 LcZbU+blm)(qKXSM literal 0 HcmV?d00001 diff --git a/example/index/22_20-21M_snp.5.ht2 b/example/index/22_20-21M_snp.5.ht2 new file mode 100644 index 0000000000000000000000000000000000000000..b8a78cb5e6ad2f7900277dabf407ac6c8aa80314 GIT binary patch literal 678405 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%0AaXZtRx@47t@&b-*jrC~2%L9zB}> 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�%mL@q+|GLLqUGWJoF`i|z9vg%B#F z1kwn(4!I9uLHZ!iAa5ZYP+6z~R28ZN-3C1XHHU(s)=*cd_g9aF20+80;ZPhj7McJh zK+m&%CNv*f1Z{vap|_!Tp`FkkXfL!M`UE-!eFx=)@xTOOk}zG^7MLOI7z_%tgdt%l zm^aK9<_9~?_AxL#EC*HstAf?RF2QcX?!$Uuk73iWSr{K&94-r2f@{Dxz_-D7!}r1u z!2f}p!=Z3XxFZ||_kst(W8iV{WH=sP0KWvk4)2Ed!e79}EtM_zS%NKNEh{XqTi&tk zv3zd%){@(5rPTo|Yb%1)MXN5WS*wp${MJ&|tE{!H&8-Wpnby~>Z&^RE?zHZ<9*rILyY~yTcwwG-0 z*s^S2+0NMt*=gD7+Wl>3W#?sAVRzTA!>-@%gPowgs{LO3AbXPi1^ajQd=AGQEFA0{ zTpUh0_&cOJ+;({4Ab3Lggz*XZiO>^wPPCs8c0A~acN}$8K&(T65J89(L^Yxb(S;a5 zyhey26_5v!&d79R7gESc+DY5#uoJ?`-zmr`#wpGz$%){U?o{Yh>Qv*@c0%{#yqp8&}H0Z%H^F4 zpR2U1w(EM=9j+#>X08ZVwChP%Ki4y^=UhpyIj&W%4A*8?mTQOWW7i?q5!a`#&s=9* zh1_J_l-#zs?Q^qnb8_=>i*$=~OLHr7yXe;C_RQ_A8<)GX`^UNU?i<|=-S@Zy?l$g@ z?w;EZ4Xo|c}Do=8tOPajWz&mhlO&s5KB&mzwX&t}j2o&%mEp3gl$cuJmJeRA!|ttSth zgq}p7^g9`IGWR6oQj`2?O&h@VJZufrX{la_3TNopWS%ukv zF~A(cSYl3N;xOqLGKP+6#I#{pm~PA&q>GbLG>GhfRneqALBkU{ftLVGdSJ&6r_o%OhFVff9_mpq2 zZ>aBC-&9|UZ?$iu?gq;`CkW}!B;I+Y^;LzZV;Ot;>aD8xN@U`Hf;OXGE!JmS;Lli<* zhNy(B30WVqDP&iOQOMB{AOsU~C*)BGU#LpxflzX2duV^?+fbP>y|4{o8^gA<{jM;h zFi_Z`up?m>VfJB;VTdsIu#;h!Fu$a2ljBsXnWB8@;mhju*tnl&h z=iveo@@%gXu_j_&gkHp!h`%C^MOa24BAg;H5djfl5eX5g5$O@x5ycS|5seWO5!{gy zk!vIOMIMNBjXW9Y9~r{-k&)*kTOvCmha;ayu8GQ2<#D9bbcXJXH! zpXoU>bLRb-xifsxBGId&w?*%ZwuweZ2S;Z_mq#~7KZqWTeitnmBO9X=vp>c>#x}+| z#y=)5=6p;;%!8Qrn1Pt5F&|=haH2SM+(z6koGI=o4vw?J+2fpW?l?bOG>(WXz%}9S z;zn_=aDuUGW7o$Xh_#Q+i@g~;5<49$6sHllBW_Qeaoj&~N8(^{>_#rmB`!EFHm)$P zHtu0uPuy_ablglF*ICiC@@F;Anw&K|>wGr$EbZ*Gv%K*l@vGyF;*Z9o;_>la@z3L> z5;i3mCwL_UCL|}Yzsi_UpD>o7lXxW2ED@4uo9K{;P7Fy*OiW8GNUTkKlK4FFRpQ6Q zwMp7Zdy@_&L6WSJB9pR{3X(1*Jx!8NMkeEuidG5)%nRB1cai++pY)RRh0!c|sp`|=bd7mPT--_Rh2k`!Q96k|Wf}g>Q5LOd5 z5G)7?LI@$B&_I|Xd>|;LZb(I>x~ImZ-c5axI-AOyCY`33wm$8zG*FsNT5wucT3?zp zQIV)mJV-le|d&q!3arsg87)G(egmDWq$q?@f11_e@VrFG?RxUvYl-dDHVD=Wm=JJ3n>) z`S~~JKc1J&Se2ogu`9zg!z#l!1D6q>QIT;yqc3APV>;t?23IC~d+JQ-OvTLAnHrg! zGIwO|&V*&!Wx8a#XL@G_W=3VkXQpHlGBY!?*gh|ll3AEpoLQM!m)V@zk~y0BZ|3_< z!7Sk{&8&@CTeA*jfwQc$9JAcA{Ii1CJ}fIXD=CYVm7bNKMa?SDs>`~Pbt|hi>tWVN z)^yg3tl6xOSt8jhv(>V7vbSa%XQQ%xvjeiDvkBQb*_7<^>^s@L?2n{~=g8(5qR zyEb=6?%`bTTwHE`ZcA=o?ojTVT*W+tJkvajyc2nDd7*ivyu7^fyc>D1^Mv!|^H=0= z$v=`0&9~1F&L`*B=eOs7%;zJkk=Kzol6R9qWHYiGIgeaNzD@2Vzb6Y(Hc(&`H%dB% zP8p`i7i=roTVPf|EnpVhEO=NjTrgF@SEyR3Tj)^eUq~!`RJe_5Lxw_jeJmC(Q7TzqVoUPtaZH zSb8M=EIpA z#Mxe=Ou9^-?N^kkl&O}jEz>B|EHfzEUbeGrPnmJqp|WFT@G{3Tmoopd*s|m@Vp(2U zSy@$CZP}Hwn`QUQ+REC?`pRCHeJm3$mnxSpUs0}BzM*_u`CsJ+%gxG>M^5k-Sc~<$=^1J1%^4{{{@~QHdXRkdTaQ?+Zge|2d?8Px5rGpVzyL)T&ILhEAc((5YfYU(c6b=J+)Db}yA-%)>{-m?Bg zeMo&u{e$}cdLD)nLz8iYVasr0_%nhTF$@Z$oAH7%!+6bj$6&vm%8+i5X;{&q(xBO} zp~0YGdjqJ!wBc}rWrIzFYs0CA*oL}>D-Dkt1TSp45OINeq4vV93zHXkn0!nLrZiKA zDbG}5Dl=Cy)tQ>i&CD%K1LjWVU(DTXzwfg*W|}j>OdF;h^90k0>CEhKpSn-(A$dWO@m5$?p>7Qq!fD zORP(ymnJT8HLq+|Y2MKcH2XKFH`g?`G>MPr>?74F63i^usm2+28uaK@}UCFyby;6Cl`AX-N;VU1m z$Y0gDy6>vTRiCSgSM#s7U43;`^qSnY)z@}hJ9zELHQ<`nHHT}?*FxByaE)^9!Zp^l zk!#Pdy=6a;Q@pNveam&D>n7K&ub;Xed_Dbo-SzhC0ynnaFuY-M!|6uwjf5MOH+pVN z+)%v55WyM6Sw-EHjc z@Y^xB3Ac-GH{Bk*&3{Mij=~+SI|g_DzGHjm%$@8z<98(PD&7U|Lhst&#oUd$d;aeA zyC3c<+}nEZ@IAkKq-RZjD^`MK@)zQ`0 zHQe>4i=&&rTclg6Te(}adw2KW-G{q@ZfLhnH>%seJEZ$eH=#SbJHNZEyS}@r`zqT% z=(qGf^u+rsuc`~K?N!}dmf2m4I> z{^>i?2lT=F?D`OW?tQ2G;`$2usC_s49{0`kt$4KO(cwqVkCGoXJ!*N>{b=mb>?7WO z>3*6175!WLP5K@BJ^Ow8!}=5YbNfsB>-xL;$NM=46b4oeY#i7!uytU^z^;KK19k(^ z1K9(W0~ZFa58NK;9pHQ{_;~GO&|~|@XCLQ2E`8kixbN|c$8(Q)2bBl63>ppE42y_3udK8|^c{rl`VIR@@;;5e{l1NZa4w^YQJ3kjcj ztkWs;+Vye)t&Gno+xfzgx7_>^yEy8!w)4K-z_E)%ZummK42|&i%QA)EAHOc}Xj)iF zIKP}|Ztg4e=U~4=VlIV@Hc~)1=Wv73t!FsbXOF`1Z4{*#B{&UdZ)PuJ#0NpC+UZHH z9hTvRT)plhdhxG4Jt8Wo=<{DcKZLs#l_>LL@w{po0d+FQFF8ej54r+(NQ1(Wg z$&eggCSxxceqg3%_vV6)24Rc(e`Uc!g2nYE3xaa4a;{GtWR5a+DRj6OM&xGHY^4sL zu&jVXkHyf`jLpan!$pzTlXMEeS4LBh>)<6p9Y`7lZGWyV7mhEmV6oqNJo{x0%Yw?E zg^R0u*aikKN$`fqoyKj*InMEhBZ_04IaoO%9YwUsd`u#Oq!1hJxk$W<*W^ag+S#LM zFbH9iY(Ww*L#CK{t3IS?JPJicjA!6OzzD4+8kdrbs7r;*=^&odJPw?jIn6k8ISwAI zh9U|voLc}84+lQG&Qvey0TlqO`6SfsqV>YI!3xmMAaQ|2Ns0dF8$x6YLtFS=H*C~k z+z4K-^OxLD>~Z3CS9*#u8kWL_I^f?IR=E=XoY1JMmRBmC)NQb+EqXVE|Vjc-rhXbh)1m1Mt z$G-o@{g(CRX}JVH381*TxU#tPIs4xDd<3jnftcW#;JKNOHxPgYuy@I1yFTlW5R4D& zGaWd8v+RHt{b%+xKnpe%5KP)&5iv>Zo zzqVyzR{qQ0U-GMCql3SaG62XPPgvTld}-Gga`}@gzYz5~Y!kX86wNioJ<1iq35DcK zLXM`f0E8T%evY z)xrr}l|0j2sho?t*~I641TnA?mLJFr?|vD<1Cb^BL%@Q_Y_u6N9}L0*;C%q}pLW>c zmE9otBIH-%2bk{@Eb?R#l1L_(8LuLDA*aPY^-QRfHT!vt5DfE38i5h;aUoyLpm{%0ayG)%OHYnpc_cO7R6$P|yy z!T{B1895wS@c;02+(xen`5%&~fgHthpn=BY;Cmuk^g63NwV-|t^L>0W|ig~7T zdKw;YK~1v&0VDg!8TL@vTJ=m6faqBS`>_dHj9Mg?HWqWT>@|0m+ z1(RY>V6Zvavi-oiVR0gUu{o8qoQ)qC<|kIOb&eM zsqJ3``V-=#)U=cz_hkV*&o(Zkg@B-JdI_>~Cyef>V-z-;W-5nF3bUhtw6R2D42cXq zGBck3J5-JUI2>1nz#VkK&c%zmzY)t& zzKPk?(!!d%E7K@*nL9{u8?PM~8F~PNm_f+3tDB?ohp(xhhby3V19*@rj8c-jA7*eR z-yg3|azlpVW2r>B7-!TD@KwpQVJGv9FZ%nJ!7MO8moCKC$dYA8xd#P9d40GrdMiQu z|H1APGe-e1BzPRq0yGG4R4WmWfKvcqHR3frg^-L^02GOE6s#JrfB@Q|sC7GFU2JX3 zYSn`FAHx3cC0TN3A1NI7!L)fS?(ST8*lPS%0r}DZdE$@$2{}c&_PNe6+l`{2HFCLPC6* zTqFWO$OWkF1rRWRClQb`NoD|Wk~bScvT-)r9tkMoWmA&yWL=1v2A+rlt`gJgw&1Jh!bgJLG$I{<1G4I=G1dV|EZ%$+BA-lFM`+N~ zGT9y8d)kClK?_&fGsWAgq`03aYn9Swhuw}7!2`-5O^&O&jIqCHQ(FoEwXmjiqT zVYQcof&+As=rlYsiAXKk_^HSSOlHV~-~~ufWE2z^iogSxQMV%jsY4b}MPOZ@;4|bO zeM4>0ieFZ*AfN9=nG2FVKtOT4gb1GEanvGXGO9LKhf_ zBvHXgb#oMWWIxt>1^TK6;N}J{2OI1wrHP{8vg*f;&*u1A;LQ`W$r?Blq8YDgD$(*+ zduT4Au!+U1zJIB7PGrR^NyH>w^^&XtA{ZX^?HfwVbpHwSVnz3gF`h%Bwfu72emrQv zjyOXoGzZXT1n?-5l&a2moN7!!2;mySoQMPq5|IoxaYBI=;1)^j-KGmq6CB8yGC8C_ zLHaSxe3Q|=vU#NlZ>1=&z*=q_Vt@&Xpk$1TBJMyYBNQZUi6g12z+hu2&D0O>)66psfCb`*< zgVR~Y7L|vfwtcjru84+Fj_huQ(e`>2=X*9O`_pvLU`H5*v^ScNV=M>Iv=Ly$ zu^NxaGjK4%48}POpfTetKBr|m7nmG%CB&l>=bB`Sw&aNEW6>gslgu%DNmJcSUn?LS#oR&=V$6PUTc(^PlVf6Y0S< zx@#Wu%1Cqy#&VxG10pFG^e%F2xTiRvEn#o=T+xnJ9Ih{k(oH3|YadX~0V%BQe3QAq z=h(5!FJ7L#PpIZ}wLTzg9`zZi|9iY;742K(ym+xE*tk}9tstL|#2TRtZiF#=V##(h zpN|WN40D?Wa&gwl7MP&`=Scj&grZSP_V|BM-#3^)qZHNOuRYAyC;<_=#*LSCW0^zk zA-Hsv3>XKV1*5uInDF3@!(xovH&xNxc;Mz@4g*1YV!cKvPaWI<4s+V}l|@kz4=*EuzI5ufo8B zoFa#jQzw;3ZN{h;M5K)Y$zFU$mJHW6Q2Y$~A9&vkTWV^(W~$~5KAMz~unZ3h*3q@~ zBp#k>1v~?X8sh=j6~ws=Lfxw-z)T&(`dj7VI<;(}r$%OuNgJ=IAjkyhev>n41Vh1- zOLhO0?qAXYFH4Z46{I!J$03au-o%r4?0AY+E7|qZKO+YV%*YtPiXw+V7+0nGUxGQP z%luXO=E>W8M_Grv&_LkI!}56b?x#Fn!Dp~p_m`<$WIldZE!al<;Lfn$kXXTgLi(og zF`m`Z=^`R4^vjO@b=^MnS-aLzutVwfjH{8U5|I1&BMt_EwHw$gAakt(FFqH*AYLFa zas=vmJ=QS`g&))|3i=nRWv}ipNh@Aj3)!sul#16P}_YI>=iebjhva4 z;0Fl43)5sJQDci>VJ{%4EHg`WNo*QqW(JWc3I>ue4xb>1+1y2Sza_rE1m_b&*Kb-M z&MzgSDpJ8SvtNjH;TcQLDh1$;yjDR$h~8s2GU9|#gJ!Am zuuKfB=1F0wIii&m@mtvW$X_&t>=#0H6?Mt{fik8d!#rI*44a4%Ov%UCNNekezpW6{ zSrO)Tc9xg{do=!TsyS%Ri{p@trZ-Yxzf znQ#$tUJNVn>-|Qy$^~crS;Vsa(lpOY=f7_aW3#NUN!WJ{m#gnz&MwdWcPBwq|B2op zKTI}XWFPNWee(gt4CXk)$^o1eG+&c90-^JSxF^SR*BPP50@KYE{hKJcJ-|Qo<%3IV9ge5yX$L%e5`wZ*8j1q z+;?TYEc;)X%Nx@-@(CErkBQ{-zQF@lFVA?8&00akc#Mkz6N6v?47eKd`efiLiO1oSy0g!XsR%?O3Gq#JLjGV~7QKhg(MO13ccpl?=%Ph@Zx; zU*;{bh(hB_*n{@&Z}?wp$~VD(P{+2aZ9OkAtRNuP$;a2>=soO^G~5kIMW;pA14)8r zmZ^3C9!7@CucBfQZMav!AdS69vscHQ>YZK#enVGw_dgay0xj*)e*pZgNjtU)ZL1OZ zTk(h(C%=s>GF%-S?9>Iwp_O3ZC+*j&nYaQ3;Ys`J4oPD(FaW;EUu}mXvDz(4{3DHQ zi~xg}Hb^?2@U#B!x2Ov?PS2@s|94xvK&~P|OpV`yfLntHkmoR#o#50Am_@a5{#F3+ ztKLx$X+c*qzdKI&{~cxbO}YuA=MK);-+mfDTyVMNEDvHa#V^uGSl#}pAZsn zswkWNzvC|aS;1>6J-DXQ+Wgpc|= zZ@&PCA1FGBA3HuG$*4J0M1mG4C)t{w5dJd%SWx-%u<7UGF2h2@t%6LYAaNglmBWqI zBq+w_1gl!PK@s<6^dHGx5>6WUWAXdJPgW>*LNH&Rda>BO&w}fN&Qm|v{U_3kI}>(V z2#PA-7ti8f(D^OAMPjw0`|41TyL}@tPz=_477AZEBirfYmqQ~%ZcprEDG>~TSTp3FwvM78^LBxZ-r$6CTON2@*N0t?A^!k(ktk* zDs}4T#{n1PR1~Y4btt877Vpmb@f*TF2m34y{u=isO#I9CuW-RNE0iVr`P0EPcSU4b z70tvpW>gs%#fMh-S(t6GzX5XQEmQ-S7f~(Isi>L!j*BZ+Vskm*@$Ur?F+^u9eE$CL z|IuN0gLW4Ro?dZGLPo#}^V*MWd^{5BJ%hH6E^!h?u-u5OegO}FO!Lk%FPJ@-ikDF$ zc6r1)A{?G;$wEmzDF-ybi9R*|7x1Rff3n%5yQfX?){0Dt%>vbKCQ85~KM%!|a-l)1 zO63oA{VjBnn_E+4=^~j$TIDnK{PXeug8$_|puIACUkR>X*(+fsu&DYg5u)y&NHmnLOQQwW)`(NGGb)%GZiD zk1piE6dyxm`wn^A*nzPw^Z3EPGU6v=?{AH>tkLj32Vv;ScM=$Z*%Tmf76k=NJ1&9Y zc;RtJ8!D2UBL-CeT-uD1A3ddOB=LCsgH{Pr@oHveOeQkS65<(!Z=M_Z|G5AB!KlTk zT{vl_vShpf7@1`T@`IS*lcH_X!HkgDG+A$qO)5(x?ugG}n06}aty~5(%A&1@Fh_)J zbvG<=0zjU7N@yi+U$g#Q5&R_MKa|n%-xYuJhzzW>k*pD*S%5Ju!yh;ILD+--Nd%%k zJhF9Do{z@%R2L@-*x6>%KQ~o9$DP~_z!2=MW+-n?>*YP`?LY!Qx&PYq8R@^rg?IOp z_N$5PS(PCcz6*|< zqm$zb^J@D$x0LOF4EICAY-6-BT;%nt6;k^J@tgL&15maX)ythjE%65v-7ng^PXI7f zPGL0V8J70Q1C56(KF$&l9F5ry>XIhBv8}N$gc(Zteg6%`;AJpBuLezD(nKFHKOiV7 zv07KkTo8)sLSXxC0sL_pzCbfloonl(OX&j94(WNw$?*2j3(Ch0qDmn^=B`~|^YR7w+qJ!5 z)$b;T7A7l9j*B+0E|pkhIAo!W>$iez1#Rcx>WkHI~(7E2x@XEG;Xu&>(jSIR{fh~AnR1)@iVCXmN#7K-398+?s#Os2 zG#$}%rnRG}`p8ZH*8{q-j2dQaw8x9_=DA6w06w~hT3(&j9_nNk3>%g$>g=p%@%8?H z@S@f)#F7a~|94S~tlFV*(=5@WDu<;%3RckNgsGp>a78LrXxg~Y`+6k0V{NtDRlT(G z6efX2Q)pH;jL#*1oS2vhaqlkZ_A7QeS7?ZXXsIrr;x8&^6HN=um-?_+7Z<9B$UpZF zT@wvg$&fY_Y9~}sh*aGj4EEk>`RI)9f)Zo0wLL^=EpDS}hG`_3#=@hWEG=wUQpS_^ zefsX^_*G`-AO>J(@B+wuxa@23bEKXUF+p*kmhc^MTE1S zZvHItEnEhbK2icm5nDN_d8W^z3s?|u6L6-blcM`(@py>+!>MQZ-M8F627st?+D= z+CPDqz>DLbxxD>=c)b@xR`-=uNq`{@19k-?x`CrKM z(sw>Y%rX-NsN{k!b3EXNvPUB_fK1E(kMTGDnE5eZv0>F6veLrt$u@8^o4&0F6w;8# zO)L%|%m7v-UXc$xPDfMl#KZWLa5As4))<39R{#?x@~}`mv$3?D<}m&(KkS_UaJKt@ zQyhV2hGxlP8`TnIcMD_W%&_Vuas&&Y$c+k|M7w}cW(J^x8Te-WQ81j8iY!W3s(KG} zn|c|;DZ+RPyJr|r@p@RDzqJ2dxUhbT`L&WPF&AmBYEBnRRO^?u6do~Egjv;0u-~>r z6?-6Ska!Iz3n##?Lcw-;{G@fY8>buodWoa9ngQ<-El5b2?1W<%!l5936XUn--_n-< zvr)lIO*?#?|M*R@*J?U)Sm8u{w~SIy-qb1=k{=kVs2OcPgW1|QI(mlUZy;8}8mf1c zm1(>5>7{Ke42{l1ZtBY=zp&L;w|wfbps{Iz`2N<{G9#8`e{PG#)bST$2iIWah{8x~ zvX6EWgdwHiteIzNJVXJu9UDWV!%$$i*$;RMyBe z*&6Phnz9Y+I+`fmDi5r-J~KjLvHT3#+p00E3F&Kogk6yIvx)w>;05-FkQaObFc2SI z^Inci1n@!Gg%G^S-L@Fg{>d;h@Afn8Dlm8hW)l(sveuI!hYQ}!*&nviVh_9l(miA% zy2QGA$Qr;W{-E}c1y8}bU<>i>Yq!ep7HKdALp^1m0>P=>Pe=2{&t{;A9u<#Dwh}X} z2HKxN#Q5kJ4yT^=Q}B~5|k z?iuX8E*;iNdgS5`@yll~H~@+=W?dL4W{ymLUf;A0b%d(d4WRA2uoqaVe!)S3oroId zFO>g*mz3bxql9)cXUfYqz>UsYG%D9z&l`>bo( zHTFx3<|CH$RcGP*;1|S0)WHg3qJUzIjI}jPL(BQFt*oDs5#ZK^iR{J`W!c-*=uebv zyRJngp^o{{A`)GqfT~g8Z~=A)5vX&)2>%xCOJvh>-1)0w-eD{?EuV?sS5H*fDVkyR zc%MaKTbX@ce!+n=E6ipM>@ktmU^KqN*qoQi&wk_q(l#f-3LAzv~e&7 zy|y$;+mUO9LOJcv%xSy1Y7l7Egd@SJa`eAIi3J6Dr^!F;p|*%OPc$uX^Ti&#z_7!4 z-pKl;)pm(^4OzuNQRmot`(oK^_OKSxtApn3NnR{|1q9C0h0P)?SV3JAsSKhl9Q5v` zmf`uBBus`Qg5`UR%0j!y|786GTlWwB;1cLXQp2Xh`h>(Y4RggzQFmB1Ho!hOihahx zyeDE^%=gtQs2+y2J^~x_8;+z9Xw!7FSw>S{a)PPYEpSzv++ze9fgPpf`z@;bfoNJT z`N1X$+a{Y(3A1%6ip`?Lly%kt=^0`*JXrJub49-*mZZjR*15b zl^h%iF$|>)-Z!X#rQ5Nh&TcmT{ramPD#kaHrsv++Qf%`i^4Ik$J`ZKF{O0`k)rpQ}P zV7JyZT|B@_zrE@^r9YJNckxTu8}{Dz9FiuQ2&GM8?+fM_J!c|U9zi(C+tQU9K>vtZ z{Oxy2F+X~RP0pd7nmL~%XE#G&mdByA@pT9QPP(7f^7;WD=KOAXy?DsqT_C;8e zJIW2nm_gvcBw*#lej5p&3i$ck6Of2%3{@430PQD&t4$UaerxaNFYZ5ZVU9YE*^;}p z_>`-}W+2mKN{LAu0Hj`W&w!+j0_;61I}iwUDmf#`m8=X-N*~-xE`)AR)KXs%)Dmgeaf3=tKgaXLk~uOq5KcT7RdLA+mg!Kp~@WMU55=c z?P{l>E_^s_g2dfvpJW2s_R0|=DqWNl_7{Cc*(TYf4PRx@py zyoU|c{|8{-k}RH`T~0&DQOT3qOyynTwVLMC+v!=1ccm~Hy!(eY%Bd#pBY0k!LP{+x z6*2nopi)|z*n@q3h;ULr3!DQ00*;g>E!DVec(FX-dp*^G;b*``YAZ`srVXaFk7U9U#H7F!+IXP4J z1P0<46{86Frfap1_p>Zm$$&U>2nPf)6`qs4q@Mp&XX3?-oiYbe|vLlrcwGU6mAmO9(e#G=?MFWQa1PsBlbj52?sP1lE zAWJd|L+Jkjq4WpI&jl5(=B~w3zUz%wf+gTGC}6}3VPlQQyFoI|*v$@NH$IhIjeJcbIi|5zUt??zet;Y7de;VX6VM08e1Q`(pQ2K zHz64mLG*_t3EP(_Bh0IF+O0cW%Ntk9|A6w`QFm^rBCO>m1o_NZUhqAvg}An_iUgB zCFl(SXipD2db0afyQRDbs9j>9x6ya;`CIV+Xh754?vq`fYow3sm9APNX%*rhi^5br zNtRM!wgeZlDFJNbv*g1$%kh3U_E?^BZjQZ6u$Qa!gr4E*XvrOSH#i-o zK0A!Hc2~*~!>*V;2;^B1sz>QYyQCoGqo<-|Gsiyl2S2kXb?xyTR_=HPsYtQsDr*W_ zx`%wz_Xxk|-=0c5byoT>eZSRA$+u9QhYi=AY^Q1p)*O7Qvg>&^t$sU+HidL43VAG) ztHMze$306+oQ>&yFLYaa_SBx{i$XIu)|57h{2GJZ1OCE&Ia`mteZA|XL-ngy&q|iR zxS)N%@8!-k&Bq7njvCb1Cu<{(Zv(9MPjLpPcizwJ=*K9hvyclgwtNc zMB^sPzi!j;1*qv4c;Ab^;NQg9VrHdD`dli8Qn5Nu^@g^aroG?&ysG=$yMtq5ac>*q z2Q}x~i@BS2_cEu)W^pwW{x8;RvrkD2?VwOg_@{vr^w~Q27u}2Xum5|jC4BG_noX8t zjj>y0iuJ8j{H1Q?*3fX>gW9fZ^cZ8EAqQ~`lHkQn39miq1uFD#l_FZaj?TpU+}QVA z^tv$N3YshD1axRq>H6o!pZ;r@u^e;>NAl72LCZAh*Qi{QQk~G%uA3?xH7+Qgo7TaO zeafqI*B;27drvrMsL;}47hb%vCBfMwL^I_5MDBzgUDP}$1eaOVJ^B0j|KeC{3G5;n z;VbJ)k-4X@qWV&5^ZK`Q)E0ebT=U!2QzAQ$Fv9xH^=ad|Pn%2iHo1fy-L%$_5uW$y z;|9h=d}-0kgufEBxM#(;_i%lle=Vx~Ux;ZJzYo5BGGqE-s#?+$HwLnKlk0FU?o$!& zALz|Eu9qJMJzojfMW3hP=CleY3*YRWjlY*YJ;rrw%DCHZ^RB!G&AEhV+TGtm&R+t* zybR3!hx`;|-{`Ycy`}FLt>C(?|3Y&xS2SEdBH_7EmX^YMDy@iXgoZY9$?yC$c{x_k zVPfc>%XDst==q|jDi6gzi6IL~U&dcco1Ng_TC^l`d%#V9sI1@y9knXyw}bJGPbRlt zcuZ?x;qnGN?(z*VXlfJLQ#jg%(Shu->0#Q?#Ie32r$cj-TOR2;?4aFJV@&)rIQ*aG z|LftX+UfEDf~?wxFtsV^3cpH{m)CY0t#MUs*xJFuS=v~-TE#5xb-D6$C3k1d$)`h# z&*muYT&5wk3qq5g<8@=_-rC3K(F&Jj=sU7$Ip6=4T|6IxfoZ3kWp`{CQ`40>bbqe# z1>-g&fBkIrp7{QIn+l_Gc{o9#qN&)@=E0}iJp>-lrmbnzf2RMIuCF63Z1`YK<3iCj znZ)+xAiw4oVdt8@&J3Oh1_i#7J-*@C8he=`oOr^OLG~3s_o-c|`*KXFHoak>_|;3X zMDA>HVP`ekUhS&fr|+9Cv`o=jit0M3#f>V3T#U5hZ)$%H{fih@(21b+a>xyNYl>uw z#_M}?E2iQ`>6-3A*-dvh?UB`ZPkow3$(t)Hn|=PbncmI#OF4M= z|KM&-7ZHD<{0A|+Dfq4`FoO>TBjmg{aIT$_xvg7Vtj!SE+&px5!_x*DjiEDni%~*y z8EmYq2r{HJt2HsG$+vE&MLnwgch{75ba1KA-Nv49{<8x=04)lFKU0e>^P+r#$P3vR zk}8+5!Dj7xSt0E;d?l*Tr+vHcj%m*&%xy1w%hwS7Y>qHK{b}mZc6y$B)1>%4TI0lI z^OW}Vr=o_tcN%Gpv~#;P|F=2MXY8-#5F4rxdP^>A!-ch8vZYNrn+6y!cHj6k{qo`j zb?z_2TRE|Bn;Huz#-^T!KR8p=+Ae&DHuz%pRe29#Pd#z!_N`{;owPMdi_c${HUVF9 z_^r5`7P7o7JQX$<`bw^JgPi(x*|8j<;?vsCbgl$m5H9t(7$kgyuW$eUyT=UulwQO30*rR(dw$q1%5HEHMaA>}0q3ibFo_sew zF+96W`N!`rhu`);poqKSVEG3dI@OQKt$CKqvHQlj3Z=1OPq}~ICylxbPvdWXU`*+4 z%ZtZpGV^xU(TknC^){Rp80)4q54^uI`(APD)Xhy3%kUTPMX+mK)3=x<V6KcYZh2iK^g}E=Zg&2l~`Y+ZCs}yAy3(+go z3K{GD<1R<%NB^ryd-SvSUzcEfA-~mxrBMn|=OeGlzub_d(Joh7_#u2m``|QtLyS*7 zpYBx@7qRzIbSP>F+U$C?vW{^vbYhj9m~^!3Kpy=Th>pIkuV?#~Q%|RO*ZlMECGPtI z?_UzPKrUJn6&}T}FuP$^LsUK@lp6JRL(g17v6`LApkWBEa_m{f``tmebjfRSUaT3& z4A+R!ei2tUhGU3LHsjKv^>;pSPM3yP+*?}rzDHj`{1Sdm*}u>tjGjTA`Ab1!JVQ2J-G=ru7eh@UGjo*D}inXJ+ed6j*Bd{G_yPHfXWvsk=~ zF-r*cmcQ&v$y{=Q9T03eC5NAUmF~FIgT*bYcvRmHOP24VNBr)Cn z821?LZ>$}>h%Ky`@OE)3^1quGEh^MtcvxH8IDd)q|B=kVDd3(eIBYc3R8a`H_O>ry zqkXOJj`%!|^Wh089BRX1kD{OEPCPA8C|(~x*Ps>T4rnsox`a2qp0xasm{$696SJnX z_;>aHyT;&q^CDw8VigsWHsUqS6hxFxotV(c&b|@5=}O^5TCy+QbS#{rrIB2wsYwsl zyL(fHXDaxO(2d#6J)%1+E;dGU&q*Xd7fN{gdyJ-~qrZjPx$qbFxUpDs#nO$FnsExn zr2+^|Qhx-a6kFG+fvYf#i+fJnz+W|}SE#GAy}Ov=(kk=DH$ z?r~UU+4s3(^Yf>70c1Wpc>b^$u&FQS-~8HE$jbHW=kL#?nU|wR7HQ7Unw7zAoJS#-pi;G@F#|d|IjUv+DoTVMl!V zS(f7P##F7h3WeE)<&2_Vm_@5IJcHN z?9rgeuJCA)3(@IQ3~Cro$26!R_HZU{_w=fos884ChP3U`rn%}j=XHI)%-jH5hl8h9tZvu@V^&7s)BiBnm()9*5x8uKow+0iI!jCTq2 zF$TRk?Z(9H-sxtdb}X&2Zfatf{)_cz-;izR$>90J_wHq)bE1XP_Dxr`%M@Em^Jwu6 z6}K8o>7~N-zUG3Q0q22DPjxyq)#e)fXbreCEjMU2LeyEBMp4}3r@4k|bXrjvcO7kc z|NA|}Z}?AhT}g+Nf|N`)>FT^voXaD5O&X8T!X_@zifDDW8ia4qY00^UjA`wL2^x-8 zJUjWq1y}N*_6>&dP;_S zDg^b`k2VYGi{JXR^@V7WF>@~<7d-uvBu-zV8~&dhV(nc3Ny&180_ zcF&@ETYP@W$q2Fh$L*jPxqoAs`nNzzQZiLCgg;2ZL$--8Tl<5WY)nO7o$yQ-yMRor zJRdB0vEpj;gQOU?8zsc@^Et2)Rl`{$z!J%6ze)O#0ZNJfP zyFq{`!B}7-BsA9P5y zbAOw%!kP@vW zJfo7&BCO{T!}7#p)Rp9RmgTeH!y97O%1cY}N%67a>5u=&`?dHn+k$@9zMt0!l71Q& zC2(IMRbE5@7$r}w+T}%`ZA$%@ohDoFD zv^Z_CXx`PH=l<=`J=;hqKUub$ziQ3D*;dj`(;Ee56&UuI3+yaw6sFfu$QK0>ItDJ1 z5?)3GRxnLBdSO8Aup2weVi;Q+=QPyi2jYzLub^;_(Ve&AQH-LvqBmRikpJcW^VdN^ z(l5gwr3V>m86O2+DY);sD!_Pe^7*Z(R!Px(FSeYp>=vqBEeu>)c~{HQ^UI>HMl@!u zdDPsLYAl2_YLJ`4*nW!@bN>WeD z;?tEH9-Xo+>rN*3rRPV*tmT^Ra>wtv`nhG>_`}q8%HP!OfxtesS!t2evK5EJ(jg7XrVZ`*GF)pW9d#_A0tR|Cmt1DNiXrChLBU%T$xv! zL(YpT!biax2ZdpH@;xa=_s#g5qImk)vWn`mGM2KYpL|~h(suRF+V?8pkVDGm5OP=C zzpqAcGvs*~6M32|tmH;_I&5tqe{lAqj_c&>-j<6#OpTPjgba6C0;q;ucC~xYrGaxh zh4Tp0#3O{64PZm{?+50G@a_DgV!Yq>DEuw#ThSQh7Uh@<1u9nT8yC#)*dR1*mGRc2#E@^(wO{C8e#Xo0=TC8jq<=3>w)8@Q9v7Pmo z_UGcC`W1n)H!n6fNhnJ3(>_rlp&oitPsAm*x^?ELo`{yc&Xm1Tl!Ohu1Vo9rxi%9p zdudwr#jb><6~#45a7ozwk^F+q=9Rr7#rR)5m@U5li^!9IF0WrGL-C}7t58`?NzA$w zTdhG%W$cvZ`^wFWwRusn=L5AdtqU^?ox!!0l~RtGyze&V2Ra#l@Ir z=zn1Pb<2N?O!|77qAEb;Gw!Zd#3|GZh3ULj6)VVFZ+@-07U3SVPH1ML$GK zHd&(aVR7vvm1{DglW)mYrLiJ^`tV9oYM!V{5#__TAH9D|#TSm1zgf2#77KI=4(#q! z+)!8*!q2D|kk`)B=|r@5^u9@`m0O8g6f5&76~Zr7z%KU5mgtaHql+_Eq4?oEeC0v5 z9vylACP-|S5OJGJ3TC_dui8Uk=M&%E&lKT`^1CaZtG}MfS>FtOzg)xLvxZUs+`G}& zF{lY5LDDF<1~aM>D+9!|MC2=H3YRW51qfzmt8b_`fQ}_7rTh zw-hlK743enSgYv0yD>~v6GQ=(KR+=z&p}COh4g)LU3aomS9a_#o86SU#XL~gu0pJS z#>mx}{(dMfVXv$jQIxc2P4VmV_xI<%ZQi#N|Mq0~HL$4oUD4QXMx|GZqr00+v_%`0 zOn}j}wKwDs%d{=gFPwx9y+4(-YeIF>dp0ZDznCW@HMoQT6 z`PM)1V17)DoZ22?iqe^WRFv1p zH$kskC`s@0J{82T?Ue0ZoBcr6dC*8%Ng;~s9FJCiz7`6&+{AqI`}Nu4PkH@8yS0cy zO7D~y3Tr9ZD5VM~tgOWLI?s5v4&sZ;=w;;I#iX38G8Tj(2aO%mFfrmwzE6FtTY7J1`?QxW`wno4AWm%qz=Yb?!0%T`*}`n z{5F?A6oC7G(o^7N*YOp?r?`Pumiy;3<<2?q_TM3?el+A}(XaTjB2Dw7zKrq@nLksDWoi6$TV zWvDe|NIzZvxClQD|4Wdna4HuS!78OGcZ;-Fm0cmcyd5nZv!t1w_dH7DMb3GTW=RvxWDh?FRO zRAvwz7HYoRk>q5L@I3h^lH_f1el6EFbLgDiO*ku7jr|t z&*_d+M@jAuy!vN^1tNwJ=K(|ouZRU)T%wAA*(Mn2QZWtvX;(E zqWVd1`BLjQx3n9U*0O@HrfxK!%NK@qy(a8&`iQ?%ma1O**okU=~oFby5RDD7%2 zVGsD?bhCQs7lJL+m_HDHGi|^AfGwh~wl-cAro5)wEf$+E@}}Z-DVfjnkyP4lK6hOsxPOpZAQHe=2QIje6w)6c{ zCc@(;uC7J&pt7DCxA@W~DPVmD#dv~YHSE)RlLCm~JFl}!Zl|dET;6n!hwa#GYl&aE zv9Ws{L%bTX@G|^?aNTKDW21Zc?fjHa+jPt}?Yr`&7EA%3ll2#FeipS?^_Jm(@ExtBmh2$Tr+akto8?K5iR|r35@LIqiFn z7+m&J3dOitRKB^T>V0wiqi+8sp-{3Zty{D$B3s^bCg%F zH;5WzvE+nxas;m1>%IiON;G0;-wMW`@Ig|b=OQe#c%>qS3^con1E1{FF#q}g_pjwN z_3K%ILV4cE(by-}qddCbS0ej4`_#q`YTM0~)xnn`*|UTN*-&xW=4Li+%Gw63 zT<6>K=idmYep$ZNim$A{-JG`wQ%x}O4P_^FDan@+vxJHjyFQ;nVr#qy0WGun z4gn>;L#0VQSn>q+nmXL~f>0t(JHcys;>B4JJOZIn_jKL|oUpNIiM5r6vYAV9-9N8vY4HKIIgnKFk&JZOff7?9jORCxoAz#-_8C6L$#BtjlUeb`25V$?(SxG55sLMe4a z$)j(3N}6LwzWDn?tNV>+%lF^otlZvt8!xd>jYAVGrRkkwj+F=)OL?%c@5Fm7RvGJN zmRg-@!W)c3pe^cgF4CN6#268d_V9D5b@6wTK-i^L?WN7kvD-rNOZ=@@_!aO=+Mqma ze{&lm8KQPjlSk^UXRuHMpNacBYq$;n!3z5qH10SAIpAG(2t44F^ZxZLAvNfM1|7;6 zkHshgu8$&MJ(_5&E|tBt_~r3W(w4%Y!A4vj?>qKDzF zaO_(TWpqQmJG#uuT8JBA|9Sq(JZ6jirx*><+UD4DVf02I1$dQi!Vy& zB@r_HZVj-JfOL@ByCePKnAkmh)-|1OY;Au+6yn{zSxrN?;ZV*Y%_`3hX53m1n zp88wZXNpaiZ|8N%)9Nl->r!yKhOCkIFH4aV@FraLvpACrRW`h4U7VQ{3MNDBzL&iP zds4}s{)_zeA;DauIzY2VNmG~R^SA*U?R9Ay!yLzb>RC^7)8Fxk$I=fDcKl!(0{)>qD8Sqa6XOC3( zUy@ffxV6KjVU=!$lE>&o@Fp&9L)X)vk`}O{BMWvD@F3eW5#OAj~nv4*AgEopx@a|HH4Q>ytHu3~gC z=Y>e;Xc|s`q{+C>MiA$)_4*_tb8H@QVjdx0k4)`M3t$UU87xk{kaKzR=iR@pkhijL zNg+@$zoISnzUxth>T0HGPe|LATEL}{?ypA139lBd4#EV@7pe#nJTdV4RCnb4LchY933vEmPF&Vv zsSzF)=};J&iq3jq5NTs=50~D&09Sc`s#MxG8a~1OH@CkVeiX|uJLa31H-PVthT3W! z)Cqv0aPU(`4n^*zizyax_u>>Z0y~aKDfPeX>YQ1Rw1($#j@)!}F19(0v2N6BQ zyeO#fND>^85~A-W>8cOc&-0o*ff~LxY;~?Q(n5&y`qY15+7jj0HKLroA2`?yRn#8V zse~1Fs&eLqEWJ2|#Q9m7rEmyx!*K|B5RK1m@nQQ*ek0DIxk2VMh z!e%)MYp!3m#rJk`YP(7y{iahahwSc8LNm14b^BnbbYNxi!r%(v3Z&uSmPk3fYmxHz zgX7;dIR|3b(I_}yrXi2>GqNQ7R0Vq3*-hx}FdXY<`)d#Q8-cPkG8f}<`!`_tZ)>t-;_S5o!yXaB!c(gxI6KNtadzQFLY`)&aE;Z*Iy1=eNPy zv06A|{gOs93gAaekoWztK@yBuPK5HD&>Z|-rhdJTuOo+fq@UZR(XTDapPILS;{9o7 z8RmGXB=t$BNf#>PjPSb(tae+<***Ujg)|?Rev7?{<#b3wxFg`hk4At!=^SzcEZ9%Wn>;PC*;ZMJ12#7AZf@yzez@OK$A6f9 zJAWy!wYibGVK1pyxSF6&oMG$C*zB%eo&~oN1|fR&i?@(AMMq@UHuiOO_K&z zK5S57Dt-)Em>5J`nwV~h51g{RfS#SI2L_%Z2<)4b7vBaCX+tHo)TZ=0PaGAY?9a zv+Ol`)C+6+r~dyBTwl}hGw0vZ7BPO|(IY9>gL(%)%aooOv0>Eej7z~L8jwTN3v3VP zxpC&E7!_X1bVE7l!?Ct$*fYFvlSc)}^aecEF5vNUW+^-f3mg9}pFh?AeM`DOJ~jSI zYVctAL8xp=43InhNE+9(;zric(J>nw2|hn>ScsZX!5-j&zIJiQgd^(FPrI#5S{vbS zOWgbs=5PxnI>qfL;U8|qv0s5(q#sqq?8&jm4AN?Pg9mkGO^(p`APrrNP4f_jctLTG zq!%uWlAiue^&b4lLaQRUWy?O+VjS5GeJ|Mvhjz1J#p(}CN*g91uwNXLws`*s@kWBWn&!Q9DPYtDa9y+WSDSHZ8>b5YA zGFX*vx{#hPs-`fXJZfooR(}&7d}VIQ<~U&!9?4qtDTNLbpJ-uaz!`L?EbV>bXJFXq zfAjnvW9qwM$0X&ckF>|3%X$T}631EKktaX8YxrC%F70r4R&pef zuLy^>$3i)H5H6kvM$&Cy?&e$sXF_taCtGPQYL(TLm27+9+~re3BPVIN{2w6pbHn|L ziVkga`TtU$P7O@nk`~uzIeej^NVf@x@B_1kIog*z>gDZjpL-LPZ~$j=GGb6ldpfm8e5(}=8t5+ z^nYXBR`j1q-;CS7zcxzSTBgcpS<{TLSNaKugyhDX_@8mAoFz>H9`by{@{CfSp8mjC|zEn0o^B3x&=BDY%C=_}oZH zkoj!InfLGC=KFmc?ZA9v-j+YWw6(!=IhU&h5V3hY5H% z<(=Wsip?{dguZ!eD#(YmO6NnMLvO*41|?^qLJKDl*s|gg>^m9*TeRp*&~~4H*Vg`V zG{$AlWHuUh$3RwpLCz-f^Lt6OMM@?XF=6$zz7w`j@a*Dz>H$BnvuTPK_V}vHqPrp8 z`im5oG1dhcqn>f3@}&PMxJ@xI|K$I9{OlNx&#TTAz{Cwt>GR8D?;MvrM9HMwJPwEN z&4B9_FF0Yb$dJiT)B$55X6Oml-j`#~--#B--;Oy{lyNzxGYBP~iLXB^`KSKxXM(oX z%J0_i^cV_7X+dcIHtdRFn*IrS-+)$N31*MNmKp$g64AxS^kz6m72^FJI@-|U$0!TgKV3uM^1;h=t` zJe>6{Tp|UNT|}er$z|boJ``U*)CF&POZe#S*qf=JZG$SFz%`i6k0`+twaq^TtU=)< zTSCAY9nbI1{`s^4bWgtu;%DhoDAY^j1(1y4VH$%vc{Y24`<+kWe)A8lMpS`ODSdPW zX==yAH|rBeC;OcUxjNp&{o6Ws$IPb#n&%{4Nw%!FljTFk# z(!e6OOz~k2gH?HNtF}{9^Te0unj7OU%+lG|WZI6C)%qckq+|+ z>e{mA8PdC_imyJAS~VfA(JR#cqvAgKr#+rlPFvuer>g8e-2$n%gsqHs(*JPw+xZ`| z{G&_40MR!Z$TybVW%P}b4Se@dC~XOw-V+_08*43Vq|ZNw!~esX0{9|PHktnz^?R!R z9C%|ToSY`(Z}h-`vyoF;z2l2 z5vUw=3)BJX2aSPdL1fTt5EYmTOb2EJ?*cP}Ilw$%5wILs9;^b^0PBMfgO7tP0N8_1 zfdjxX;6yMETmY^EH-PVe?}7WlL*Oy+6!;l<7Q6(04PFORQ!xX((eqP@P)SkAQSG5p zq|&C+qcWf}rZT6p26l>fr#eIBLlr=Up$ezEMwLdDMO8sXq-v*nK=qJn7}&}EG1Uas zGSxa21ppXA1EGU3K$sxR5Hc&s83U$p$?#qqP|X@LtR4MMBPUHkor9}g_?~uz?FZUVv>-ZKI(j;0Iu<$}Iw3k?Ite-%Iyt(%bV_sw z>5kEv(pl5l(mB(4)19LWqPs{JMVCUCPM1lSMOQ#qL{~<4i|!uXL%KP-k942tcF;4^ zv(od>^V18^i_t67YttX2hts>$`_jkLm($;*ze_(vzedl;Aj2TXpuljH;RJ&@gC&D4 z05pRqgBL>pLnuQmLpnnNLlHwQLp?(WLl?sU!#Kkv!z#nTj*%U2chKw<+^M_siSClwWwgtG*Tr46{pB^Ff{ z4Hi9?V=N~Dz*$f%)+~-J?f`sP0$47yTxUsR!LekpaYme(xr0DNLGVTH3IS*=;^SWmG!v%0Z*vIYPMWxdRr#G1-l z%v#5Ki?x@vk9B}`gmsMd3F|EDIx7_$D;po10-GkA4cjHQIJQEzYBnO&9#S1l}npTkIRtDi0cHGITwn{mg^Lk7gr3| zbuKJd4p$ym0ar0s8CMky1LkGq-On4ro5qXd&EPHKE#s}>z0KRs+rvA+JIp)5I}2cecMZU6 z-VI(b9~B=LpE{p5pE)0zFP5)?Z-{S%Z-H-v55mvQFT$_QZ^-Y!AIcxWpT=Lu|A3!I z045+Spdo-1uodtS2p701&@Hf25FzL)m>`%gm@C*S*d;h9NESRGgb;EQiW0gl^i*iq zZj;@PyR&w8>=qP0BAv?k(;k9w2@}93vhfen~u1JX$=;@I{-Q*?@9Ja-j^Jbd zlGBp2lJfu-B$p+hOMZ}KfU-dOp`y@zP+jO@=n<$n)DG$hb%UOT210|OVbIIaE6_M- z3KR#egx-P@pd{#BXb*G{It_gXr9hdbB&6h|w51M68Au(IGL|xxvX=6a@{4Wy4sTTA;$2TO-Yhe=CVMG`Sb{EzI8-_iBJ%!D{$go$i&oGD#wG6Ecs|=rvkc^0on2fxPl8i2Z z<1!{P<}$W2r)0cjf@IFiB+A^7$&)FP!OPUiG|7-;?#bMj8I@U*c`x%(=93IWmQHr3 zET=5LteC94tfs84tdZ;ySz}oY{d zI)`=4bS!n8bo_MA>qP1#>!j%v>(uJ>>3q~-)@9e_)s@hd*45NC(~ZWY19JlhgJ6RagL;ET zgBF7hgD!&*!%V|`LxSNw!+ArR!_dQWhgA<79yUJgaMX8dMyW_!)l%?!`H2~_?TGnuDM{8FA9@giqeXRqn!>yyOL$yP#LxV%B!(E3She3x24#N&l9G*EWIjlImb=Yt)b#!)gb@X!daSU(_ zay;*dag20KbWC&1b}V$PcC2$GI^F}&=lH~N+3}U*djRW>R8F)`bWS^*Se)3LxSjZ% z1e}DNM4X^bicY!!4mue+895=HY@LFf&O2Rms&Z;}nsR#U#DB{4l*cKrQ^BW_PT@`! zpXxcqg%(F!pySa6=t=Z5^eTD-P2l|QR|R{gBu+2d!u&Ssy* zpM7xl`B?$)Gv4Xmx!wftPVcAQ)82F5Wbak)HSagxe|dlO{^U*Z-g%Dw9LG7%bA0E7 z&q?76ga9p^gF^_?3z_vqZ@x%cPTd}MqyeDr-ReNaA*J{X@%K3P5l zpCun&-#xxczB;~^zG&amzFxjQzM;M`zBhcce5-v4zTLiyzJK|C@P+v81jaPQ{N((U z{WSda{mg(}e{KDo{rvnc`d#sh@w?`i=9dMa(67p`*00%bz;DQJ#&6zl(Qnz0?6>Oo z(U01n-k-^z&tJ}8(O=8o!r#i@-9N-X)xXle8Nglt2mX)!p8}ZmpYvbvf8+m`{|Eoi z{&c|48lC|D0FeOk09e4@0M!7!0K)*20Ca$BKwv<0KvqC|z{7yifbjrwz?*=N0Zf5= z1Jwdg1fB`>3rr8p49pG02UZ5w1@;Hd1+E3Y3Va*55%?*P637^|D~KbACrB_zG6)(Z z6(kd+9Hbhg5p*C(Kj>(XY0#-4mmt5Oh@iwEd{BK*W6+(T`$12Fo(H`RVhm;vh6bw# z9}PAOJ`;R7xH$M$aC2}+@M!Rp;K|^XVD1pH5QC6QA&DW4Agbq3lTUk zbzb#6;(YA+8|NF(Z=7ekaPWfng}Muy7X(6~p_-wmLVZL1LqkHp99KfqLo-8bLVH3N zLw90$FuO4l7$uA*<^bj(<`A$xnlZ)%V}?OskQghB9RPcb1I7u1#<*b4Va{X1Fj1Hk zOgg39AIDa<0~J?0Z;XP79kW}`xwUKk?mQW!QYEvzW)W>`xY zDeP`o7l47VF#uCx&%zeMUWWY@_C9PQ3=~cqP9M$;tWL%kE)ot6mkr++t`e>pZX9kI zjtaL4w-0v?_XrOO&kL^(?+@Pyr;iYgkd9D@(26(`VH{x}5f*VhA~&KoVkzQn1ouVz zi)SyUTMpHZdI#XcrB9bOFEK>&MT$o5jZ}@)jkJyojSP#7icF6z zh^&rmjvSAij@*n?xNLaY<8tKXmdpHC_FhrGa_Gw0E9b9VyV7w*D(YZVY}A7&x@ePV zyJ-LD^ys4Ky6A;y*O>RZ#>>a6#v8^TjXxQ08SfD99Dg<*6CWL) z8lM+`D}FToS^Q%BYCI@`Dggoj7z6^qn!u4DlpvlUn{YS*c*ICBO|VF?POwREOmI!` zNeD>5BwS2LNWdnfCln@>C6p&rBs3&6CEQJzNnpIjer@kH+iPd86{HxQyix*E!c&q`N>dtBdQ+xTXj6GolGBRQy3$6|9;H1=n@XEadyz(sW5Ds^U^p$DBhDKah`WG`#a+i`;Yx8$xMti4 z?jvqzx@`K1^egF%8T&F6GxRcSGfrn*$!N;pxuJL?@W#}Q^&1B>k7e3rhGiyYW@b)h z>Sdv_Y_m>fd1d)#MPy}Ua%*XRKA9bmeKVVsy`0UL z~7i9vZb=svbSaHWuMDH<#gpc z%Gt`f%07y`x8)nMDp8k1Hq@^pz5o+LZy7i&kyTMu=~a1E^;Hk5 z9#>6OEmeJ}qEtbuX{za~cU14HX02wc=BnnY=C2m67O57kma3Mm-dn9wtyZm7ty`^M zeYD!R+PoTGji|P)Mgg#{MpwI4yH}sC_OA}A##AR%U$4%pF0HPszFpl7ps#wcdZ_xr zSBz9Yt$tQLQ@v2VRJ~IDvifcHyXp_s8`V@bkQ#;>rW)oNu^P=9y&8)e*P7s(#F}gX zW@LGr3=-R8biM80;wAvfBUA2GJGSuy;+X-M-9a|kw9dDgL zop7CWol2cL0PQ;cI)gf+I!#{H)$!jHx(U6ha#R1N@lDH{ zPB%SnUbuPv=8c=BHydt_--Oh2)^h{H97^?S^*Z(N`pflc^`!cR`gip#4QvhE4Pp(_ z4e|}z4WSL#hO~y#hJl8O2AW$Yw;XT9+^W4r)9Bb3-5B4P(>TyL-uSq2s&TH7-1xQ; z+9ca#&}7$izNw(;c2j55qo(Diw@n|LJ~e>|R0L|m4#F-1D*#RcAAz4BL=YxO5TppQ zg#CmggcAe=;S9lx5KV|B#1j$;NrY5F9^n?DjnGc$Aq)WPw#^bg5x~vN&D_nB&4-&! znoXOnnjM?nn|+%7nuD9eo1>et&8f|q%|*@C&8^LS%|p$T&E)3w=3OluE&MIwEx?a= z0DD>#04TL+v>a+NY%y*zYeBSF06?|awm7snwz#&qwRp6gY4K|D2H@8c(sHroa!X9h z)s|~5xR&&m%$9XzD;n=MT(EiJcO+5y~c>1yc%FxWEM@}yKTX(naZB=MhY~A0g)2iEgur;|gv$d$TytT2F*xC)C zzjc!`(0af1QR{T;eCuK>xpf7=i`JK|uUcQX{?+;cz()WZtso+p2>A+XB0X^jk%`Dk z6eL24GDHOcYD8_~LE<5zKJhpJW1=|`PDB#XL^q-zF_0KcJWs?B!-wU*iSxwg#C75(k)Fg#;vfl;U?e5d0g^t+fMi0lBH57~0H8_E zBzMvok{8LFjZ~!t$S)?3NE`WSe0RTLyoK#J!Bh`}{NR6ac zQah=G)Jf_F&<|jMG)THndO&(YnkLPX7D!7ZGU)~B73n>I&m>SAT^m=MVB79C@wPo} zYHb>AS^#ta8~|X@cBJiC+le-_Hv2Z`HjlQTw(zzqZHa9uZRu@!ZTW5ZwwktUh{O*|E|AzO(BN^BvYZ zJa3@{CF4hRiM4yX*M4;&dV8E_o%83-8&AGkb_FpxG-I8Zsz zK5%E?(ZKV8R|AZLI|f+>*$24>`36M?)duwj%?I5FBL<@ea|Z7W4h+r>Lhj4oN8b;- zfAN0G{ag3j?|0qr`HF}4rvZ@fzqwC6#6KiCBsH{mNO?$e=)jQSkjaqckoypBsC1}f z=*1A<1G5L756(Tf^dS8K{z2n|`3Jim%0IMySoiSW!=1yN!@Gx7hjoV!54#Ol4|fgU z8}1o?Fg!B+cz9uWarou%$Kf3#yGNiSuo1-(tr5KuqY>i~#E8Yn*^z4_sUyuJPexcr zO-F-ALr1ZrH%Hq?hepRn7e=3tLdFEg#K-oG9Ub!@DkK2sLjrWbuj)NYHK6ZQ@^7!`SolkZ@@qN@ zJ>{8jod}!=od}<}G7&q0n`oRMPK-{FCw5HgPufj7PWn$?noIzYIGHqwo6Mdpnk<Ez_(yGf=gktv-im#H&TH>NVD3Z}}Ys-_yJhNmb~JEpm( zC8mw0ji=8|XHMr$lcqWmH)A-1 znsJ!%oC%tVohg{9n<31!&h*Um%?!-kpLsYlHuGd=dS-rR3Bc;ihnaN%lo{$-##!J` zt6A<@9svBaf&fHkrDkPjWoPAQ_suHJs?F-m>dxxV8qJ=ZMa|mJI?uY#dd_;!`p*W; z2G5?Ky)cUbaB23+Z0u~>Z1!y4Y~d_^wqv$uwtseHc6@ez_U-KEEX^G2oba6doa&tV zoWY#&ocWy1+}XLPxum($xqEXD=GNw3&Apj>2Vi}UV_tvWavnKvJr4}U%-heS0k{J2 zm_Ik~40$qTpz{6gJA{lcvU(n9+}=fdd1!otf1(4z371>|G=;t}QYyi7%-y`7T{qie5@sDp{&uYFHvHwJqIUy1(=oz~a*C z()!Y_Wx-{!WtnBgWus;5Wt(NEW!L4?%U;Xg%YMs&%NLd-mZO&AmlKz>mm8K_mphmH zmdBP~EQ85ZWNrXFWInP0S(GeC)*+uDo0Ab_XYv`cFBwCQAjgw4$;IS5#s!8?bpy&2uP6U_b)qiQ;=#}0le zk{Zpr@3k$Hkkti8@>4A^i(9eJPGEY%pI(goGHc=YnN(kFTaItc-@Z57K)M$l(ovA` zHV}wL#3ZuQ=WOJ8Z5%f36HIJ)hxECyiqew!!|LF4*_4iJ`lcUh#WN05on_g@w#DJ! z#2-^N{uc1nKn5*=PJ@&|JfJ-w0WO|oM=GO}6(%U)g@6|&FkQK$>G8gaCG-W@yJ&24 ztbW8<>uQL-fzjUnm;;fIg=@=r%cY=%Y~d|)QZRq!`KM`p55f1rcR{WoQ;-P=q{|}% zZqWq+?@nIUOTB2{Ccv?GuV|8pAG1krePjW)l9%Y$t&4{nLG zd_R`R`6ue%?eBkGl@_X7R1Dy9P%2Oga_-@sW$9rjhjrPV+(z5<86}v~OLlE0;!%7M zhB@Jw>bp!xsN%I^&)PJc$Z>H!dR}mPg*&bwDCu_sKqvjd_IJ}p9wZau3SI+dqFe@v zViQ?s7=-0%O;8f281LlM7h-J!{9frBE9>rdErqEv@aYP<uZb z;Jd>hw%baFjz*M)y!pHqJH5hZ8Z~xRpdho|8(5|XNTyVh-Xr=mb*X`vwF^_iN?#J!Y7{8w}-qwY*+?<%gpkc+3XZZ z7c77+5t1!(=0xD!XhQxQ*Y;T7+65TBFnuAF1~5m77i@(!Z+F}44o4)4ngkjg=7P5% zf$d7MaQGQGoELa=#19T<^@C&KU^fYP;YoN*1^>dEFUIY2r>B0tnzo(qtM<1G!pcC$ zuuSC-%!fJzwh}}k%;AP`^xZ<|3_lMlyj!wcBH7uRi(?dPnF{Aj1tSVmv2b{%0o=t| zs@9ngz2xf5Bf*Lm1gia(ijVm(#NXqr12c2zAiE&fsLa7Cw8_q#XD)b3r6xL}51e*} z*GHvDk0ctDqTS8~JDb8S4;_TtpbD|MP3Q~*AVo>1;u0^TffWq?b?>mRME}?b&oPcL zNPKmy+yU#EEr>0~;iwfvwJtp>)`_YmMD`Z zykq9Vp}Z6~q@SA~{I?8G{igqm+PkA=hauzxFt02C47Y)E!r@5Z6pfeH+)a6N{hqO#boy|4R3-U+KH9?23oXQD1`OfrTxQSPp4>eBo@O zYjQF$WuFfVFGM08QjS07J&Qzj^75udawVtedygT)OYP#_k*VWIcP!^y^DXag{DJIS zX8%5slJsT9bp(?aQw_w1rV?@o%;kzgn6e~0Ho-ac$IbOm)fXb+25sdFgxR45X8!~~AslgV`jYkPpZ-qNAzPQ8V-5*pQGZjCaBi~BmGlFbn& zaL#QmxAd-C?X7@<`D*x48@}8WCxMw}A0UTl<)|0IKtsaH#>@GCoLvb#)BpdMqvQ^A zE4i8xQaUJ7QIu-(*=!mq!-&oi9V;SD5!u*8j4>Nilw-JBiRNE9yR;h6K-5H*B~@sw0O}H(W3c2qW$vH(>mqL7y59|P&d~*qO`)yZ`fQ3yPRkQ5mT0g`&ZwA?4Lm+AtU#mHd6l@{@ z^9wsG%JbDD{eO-cXjiCKxFD(}E-Gd#9B-=}YLAHXRiaT9$;1$(w|P>2%fs67?|Xzdo=O@)zFBLnu8CLY1>Sq6oX>RTd+00}_?y?~;a znR+#ZNps`GoPKadlruEAV$e0v-=c5D6U9yoV~rNjbJ74r8)PF#$;({DPjxo{t0f@k zBRo8J)!V}WA9BI#i-b&{$YY3l7$Oi>OKb@DVL4OA;{RN=KJL%&lN6(~gTufZ&(iq0(6ES@bOnR0{gldI|)Rk+w?iJS8)g>R6f5mW~~;9`vuL2(fXjmdOd zmX=cg$T^%&@kC%A8DQOEp!zy2I>kfDwhKUpBe10X$ZPyo6R%F zh8j-nvxLxsM&TM?7eEQ=Tmv+?gu~(iU4$+HW3XlsVUbt(IV9^g!qePMuM|N_Osc7c$H^QHtU$p?l3^rG72Pz1$iiuKuWAEHf!t{>oqQKR@0H{C*9aiZ=gV;j;H z0T_X>9qOE5n-SnSb6Ed7rl7V@_f=&wkR|li9x6$!-q0S3R;7Cr z0AxHB<}nX=VQ|}*Y~xEt?9axl+M<&&)JR*xnG65}OxwF3_iunxV{be<?B5C<+xy~1t`69ksgkWa}Qv@L$y+8;%5bWn|6g8IUY+DO;Mz+y` zxJ>!%#Dm05`_Uf`5J&_x3*-{Kjm+@MCb*oh8!z&#fXkVxi_tMS9eYH1cB%8yUEwDgFxve zvB+@MIlo;$1w2CWac4u1X7SOs(7rlfSoX+5Uy)J|PiH%#5Cyk4fkdUWA`uaL(PSc- zAXi5Y$UvjLkcO>*E|rM*nJ5#GE!GsF<_uD+xCpUz+&vv_7Ka;=jGjh_(POka_`PAL zj+RdT{KK+k3r~pH<$8SbG|rC$f!273-FEqVnac|lAr5y;6JsfAOLe3jZG647I(So zX$$Ql+UR+_2?QX&2rzMmc`d zsS|c*PP8-miF{LO5%@g#>4JAAv=JIqLa8m*$IHp zO;R}KabTh)diw;(?^1y=H%3l+69L%;krYpsCrQFZ6Kk;Vfi0LsF8#&1f@X_VD)CAkJCu>~ZN3k1bIDqe9NOipN{GeBN?D z@plUQrLsf|uC4UHm1z0bfzEYeUmiu&AkYNYbs76>0B;y96n!Gi-s$779{?)&bnvqt zk#jHZDBL^z1+n=8WRDPU%HX8sKN2{8EBst++`2qTe1l?w)KgKR9;(W-*W}~s(xEWK z&A8ZGFEL23w~G6ZTs^4qAhj)`z00CD>)iJRyV3M>*kos~UV^ixyn`uf4gYhOzd0rv z8aKBd#}hTFFs>4hReUTpAgaISM7WbpZ%wxU2OE^5w^*CY-CA?ZRu1X>X1VOxANHPl zxLvVv2ltmP2>s}T%=PXl(}TW^j{KC}JGb@UOQ#0sXOkNyVhcHn^Q3jeC>tNH*qfpE z7ShgwLW-x`>Q4ht$9y=c*VI1ib6v{EG}u)?@Rh84SNM{Md(6L&?)IaF;WQo+|Kg= zVU^ytfLf5Afv=bW6i(Qj7EvHCVWg*i<1hRLMgEgI8RdoZ&YcriQQ|+PYqHE?{@QLT z5a?$|LO~ZM*4^U+Vu+Vz=56+1Aq8|#I!P=f^@Fz*%qG6IQ%R|%{^UXbBm~woQE7Lu znxk?;`Y#!SpL<}bbY!iE?fs3d^=5W^FK8MZaco^BJ9hmqh%-TRCWzmq(JObXRF&X> zeoB{!B{mbkbXo%^_BLi0$~#IN?WJPsseT`@LFU<8$?uNANLTlI2gV*QLU=i`4K!j= z-U|w`0Q9zR$Kl^u|Fb-3)v8tY5^I!}%e06Y2n)q4?cT}@3#Y%dL(C^=_@^J*y7JR4 zrBh3SDf>Xc{Dr0gYn`;~Z`#<2xN9E&5%A3-+sU`a{hiw!I1@EJhiY6jItbj&HOw&* zSCud_3iE-d4o9GxOwvL6(@h);a=6E%wpCtYDC&Xk{Y3qx_NR0BKV;+B9VfNhI%^h@ z64>jvZ#y~fJzerV`}ZJ|8qOFs-tf2y`PS7Ut1~3tD_xhdo=3h>T-9ksZ$*#;LtD8?H~5BT z7w>;^rho0NwdRsE`|_hZJ1B`q3O0a zaN%v}kP=bXP(6`Mz-@yqCKv>SppwCaT-R*?L46P0j|=hjA^3ujaal>AilvS4IMSjC zYtzz+xo4ViCR1S%YH?n2kIEuBp#?TCYOuAi1-W_B9#levM+G@A#NM`!B=i^s1aA#g zA_(nPJmOUce0IYG>Y)fXYFMDmDBt6~yU!<&TAf|)8DQgmf10$w($_LWGG7HDw{!vO zs&|EFWw^QKReLz7wav4izJVW1f~n&N-N1bq$uSnEzqN0 z!d53&VDHRn#(&F9d6Kjqy8fA@s%o^H?Sc*GV)bplAdVYa`QPcuEjEb%5p=}*Lr`-k~gZ_3>*_>Jxh>Q$% zmEUJ13Qi6tY9`*(Cq3u_K9mC>??%*C?9U(ojsms)r~7aGx*vCGq{BE_i(BuI5>-34 zC}+WiM{v=Dv9R^0QN)V`D5~B+JE14x3JQp~Jp&Z_G{Q>aZR=`&*b=rnhog5N|0W>> z(Cbl0F9-<<&mLg2C36;^w|3(f>oZdBYScwF3xq^BZrMyy(U)6fSF^{&PRzpI6%kIS zhawU^7A<(#T9ORS^(nl1!PoJr`W{^i{#!yqLazzgaRclMNzNoSPSkIX+`L0NS^cv7IdLcWtJ~@z^ilq% zeeQOhDA*&Q41;~Y0|CEp{K7ja$v)u}0H@Zcddg=V57~P$-;-!Jus;c1iI2} z?}qFTd?M!PQpA7m;aNi^CFPzW-JZVw`w!^+Z}-~5ZBI#~HAECz#IdwJwt;cCLHUK( zutxx!jn#*|kKFh4@Cg7;ig{gy6Tr^Y=Nq;G=me-M2Y%AT9`raa77akr-JgD6zEKV5 z_xd2=l!uSd{E`;Oyr$8kkN)k_*pk-u;RWHL~yBsj?a1UN(Qu}x;% zTWNx3wu0BfUu*o@>#zhgHVDzUk_KtA5Qe`X5+(`ybo7r3W+{6;cJ#yv%HJ8ij@@ufF4M1 z30WTsV7*`f=q|o~*TEy`AQXQqzePkR^t$b}sO75YY+LN9X@HYaW||Z?#*HVFsud3J z?H9_x7RxGrSeR{F?Ww7Ms2+Qy-5_Ml%Ys$!Pe%9`rG&e?YX7K;Qs%(GgpeOTu@p{FD5uRFK*oKsOsJIu<#JY1jF)-5WI&ND!T21GpTG7D7ngDE_~+}pBMRRRw>##!yi_V)U3T^D z@(;NVAJw&G<1|Fw!Ye<0J$WOQ#skP12b=aT#|d75kHc{0fSVMtC)NigJ3V$*$qX&A z0aZ%)ltq<2VtGC?X?fF6{GpEu$={L4_{L(<&poEMMy?@cZY0)+H^%#UdJ?dhRSU>y zv>HWo9Y?8gdinPJ zLA_n`7>+@c;bPP`R9O5|btlYa*ss_}?E&Wk1EZKnC^aWmikd#*TN|HU#|Pg;@g`vM zCWwjdFwXys+HJgBS2kFy4zyA-WiQoSys=>D&B+7>kh)`v1uW)6w_zj8CusO~^3IgM zL62y3bT5kTwT5x1{x#r*V&=K*_k4kLPnxvO9;L?4lfn_qF~4Rl0e&8Z%0suxzSdGu z@{qh(gQxdpuRcz0OF@5HipFgpW8{LeGN zF-docnI~aNiI0x`@;ll3V0aC1!3Mot?&?=M+IK}FE7MVBmA^|+&%C=I8#6p;Qy{!+>;$prpSd~+e z7ZRZBi$j!L$ChxZHOb`Ly>Go8bptfHYSfO)jn2UcFN5>Uu4m~-=LkO&03+#0&%lik zvyTt35SXM~srCcqKq+kKqb!#*w_nvKo@8)C%k(%Wb73yPXJ_WN0{$Mth+N86lxsY6 zgMmxRadbigiEuZqCewW#)idq(Y`bF;_U{yv@+a_p@MUt+I?^hcQrCm((vq*V=D-xQ z`mkRztsBvrk&=1nH+zUd1hKDyDax)Jx?de|7p-qrzjPdavY%)dW9Xp&XlT{H#{W^M ziOxBRJ3-uZ+2*oI&RYknQX{pl!pGJgk(0qXhe`O*LCT=+a!qM_ME_=f3t!~(p|kg& z*UVSMOwawTphsBuXjR#NA9*xxC%)6)@i$4 zN^br?ez*}n(QoQ0seScN#=IykM6#9cIzLSMR3H4Dej@L2#BDm9Qfc0IIbpA{#y;=& zN$~&a`U5utKjG*^$~%WtLdM7q=~Sz1k^WUjM6O}C!xni&kb*Jos=Zjd))N={8yJ7# z`up{7x|W!u24&Yzqm%i7<95SS*%Wa#w~)3XoUr0BQR&+~E}K<3KX>w;8I zNz;4nJcO_7?(lrw77H%c`=l8FI#ETo&tsMx`qjnE8ZrqvdHQ4qtV0#qz<(UPd6U1g z4f7NIc1G98^Y`)4J}bgc`Y;zUz}vaE+4Z4ZlCHDr9ci=z@QXxlhnnXA?F2D^w7L$o zknO~O1{xds;qXaA0(E)n=_ASB`3_KJ2`wS#y{a{`1kQq>EeHSQ_a7rAAN6Uh3dVvX zZpxQ6sHb~B%e~c2Rqc^ZxQIo%dA2^<3T<#sFFK*=LU`ev&?enxjL#6Gg7K5OTP{j{k+t44RaKdX zQFurmZQGHbcOda%5M?KPtnhuprd^_7Ggf$qxKIoP4PJ=c{HKaqPL z6&jlV;}cN!C|EIyMJ97)nkuCJ3cx4@_`-hK`#u%K|6gg&XhyDku>1K%pY^QO_Q~k{ z9ZU81I(v(mM+fdQ(^c=6-jLb(C>5%!3U#hcoTvKIJ4B4+OZ7`o6y2A)bR*R1iRwD+ zz7KJQD*r2{K)&(nc){P1D09(zeViImMsF7!avy-&s;Xh!scsvkTO-Aca&jM3$Ek_z z6S|^NP*YgnbR_5yklEVRSYN>P6iN=*W!sro>qHc=`zLZnA1LPUX4JCif_}MLfy`Zy z7diN!Ls_i^fd0N0-CBo%`w`=TqqrrTfju62ME}dz$?ou0;;NgsoWo0gQtNu%;d(g# zZ2XM%CwmSbIK1x3m?NmZzTbGivixiPUurEf)VqgR$o#<#?@2Y-4xsDtS}r~xLnm`} zsLqsR#?0P01rz-ki#biIo0$wC>237`5v{IDr#pO!(0ch? zdt#LB7zleh7LLc6E|`n6_NqW9%bS3E)iY%~f=iY!`4qn&g(0+Aa;ZU&E&w%mE`AEP z2nzD+vB!klqaMYJ)u^p=^~WGSJE0ZuLbQC=PCV$bd}q17~U*qu*CO zIbrUD5r6w>Z2dha@SlY8J|yp#@}I$24N*BH2YWMzX6Hc;z}n=c_reN(TzHy*Fd^K+ z5L?6oVcOe>ocH6Nvx5`G?AXo>&RM|I)ZQ%4tjg7Ch$#y>QMPz2KTQ8`Uvdh3;Srlq4dCr(*DrC$y3pib zt)-o00NI|M9@44b7y$;73z2WRDBpp=RzE^4|21(RYF5K<(8e)FzUq$qO%@V=x3%L6 z$&lNczvKY4J-royIGhW+NhPI(p-IW8He?!1zkvw#B9l;lP!A-50VBLV>FS&A)rtZ- z0fKkJ2V3+htblR004+drM(G)SgfGMSi};5ta3Kt?1TRGd!WPg2a!KL&wE^h(KtxC^BKE6hmJfT>`oElJ1CM0pOT7X< z`4be}44oD`EJ~#kYj3mCoBuAObEqEPzU5ioP?$U18%_R%_VyySdfdwXwWuK`j^ssc zd);76Kd=vu@yf4-dVKj8Cp&=p=8#xBMzB9tQY7n4aOs(%@j|LFHDy37Mg zC$ysDy$0CM1h1j2C0Bh3uam_cF@S+<`$xns++GdxFAN$RI1Vy*DgSjoSarDYP`Luw zsBLk~q9op5=soi9v3ZyF1eKH^PiK4^ehbP1?L*RuzH62-OmZz%BS5|tpm=g8xdHZW zKLDqBJ86`(#Kw=}vjxt$QF`J+iy zX!wzSg$AP|OSp>yTYKsIS#CpJLzK_o7dR6TL;oz;h9xw9e3cFRT>zyl{!SJn3}8$9x2ti$gd@ zzO<`}1Tf-QJ!q|O5kYAkJ-`_^|2;N4_KTB)%UdjazU$`B_#vPdkl&2ah@54YGbO=I zkuxd2>eaE`$2KUQTi&~5hy1=kTf{QA?jPH|eWejwU}Sw&eR2{EaRx`Ezm(pTkNdi) zG4Kpv4mgLy5WR?_*K4lQ5tl|da!&(%1EeU)zK89t?i`)g_{>=+J+qCIHnW1q` z$KtsB^Hqf!MtLmeV2r7;gtc(R#)2@TJMGFJ@bnx*%J}`i3Co;u)HxTtf*$b$(B(j} zz$c1OUT(_ zHs5;|v#AFhwl3fJp8oXTzl=xy5umXm3kas6k1#<&p95t;?#8N1RTX5q`-O^yu78#I z*3yw3O1mXfN)d)=OWnZYPci8iDO?8LD~8iV!E;%33WY26#4z+q)o|EC31i5JrODDx z5+l+-9quPy1wlavjn6N&Q^@18-bm>`PT!C!{#m1eMJvAd8Gnx{UOtd3oFCQ2ZOIq9 z*sQG-&4?N5HcBsOF7xUVrRUQRe>LV#p!{1&C-O|CBe@-dOHW({g&2QXidCpex7x5W z2CU?GS6fZEfSW5!*Orko&Px|AZGQ$Xpy6B6%PkoJ0nNOsmcDd0{*EE*SD%)4Nm$G~ zzM*c;l;Ph|b7V0Kp#;AG;f=Rz-&8<9xzNQNG_H;Ur$?=YthMS7gZLL(D;|vTIheCn z9MS{he!v^D%7h&#KMG%cWA)L+jX#H$f2ODR2>||X4iLy9NUEQ_7$T>XXq>A3Q^83m zYJF$V<*I5(YPG*%QwLAGJ*>;CrL2!v5xTZKzbuns9NIO|&n|za)ycB()w1O7j}EQZ z%~?Hi{qdXio*))SkQr|((NjlGZdb}N9@1W^*moAcC8BJgGcK>9uR?t|9p5Kw1%7h9 z=;Z$I<=~YeZ<*|?_rQ|T1r`=u$niu9sZD4iLySR_(5@Afp&(m?|eID#m?oUrI{;ti7tmqEN zDTJ`{*Wu}1IpqcX=Ro{p(zKuha|#7Byg0q#^aG_TW2(-5#gt<1H+oM~&gH0VNiyT3#0`%|X z;}uhSM(@l|rAA{BU2#xWmGv9QFeUwf4HH?|rf(_`iW+X#HqH4e|BRv?T}4?RDr_Ms+j5wZEmHAan3Yd6 zvChn~{+;sLs5>A!9l@ zi_!I%8^Fx#@8(2(6PFaeQdu7LooCG<>*RkQg~v^ILZCtf>Vq>q6VEm*D^y3t$fQco zL1`Xkz}VvRE$!{;eH+a(wIZ`aJ7bE3v~krj+wKG~AcjmvXdc9Pd;;1kckr-}7xpApA`UJZxKTL`U^+7bHyv_ZKQ=y7FaC&prJ7{211zTU{i$J( zwXs@$%Xgj>@2ttUzJ{ibO<_-H54ojU#@q_S@|e|64?Yt%?14xKGx{9TPn4D!a}UP7 z33)#q@{b&6Dn|tV-9=?Js!1w%yUH^N*W{y%$)$!o;fHrk^67;G%<@p8)g6&adNWU@ zf+^1b^iGpWMOmbwQ``GvmD)1RrQ)Fy`Mf9ODSQ8w3W$1uN2uL0=>}g_(OQvbfYcGb z%1ZC)!VA+oIs=v)=Tqv=npjjV6xy9*Vqr>4Oa1&_C-iM;YUKHX)@WKPxapgf-&)4M zqK*to&S;LY(1RPLc{m=MPrxoQq7u~}nrt(8rSggY5zUt90qrs{B!)&~abHH_`-)8^ z0-o#=VwQ^JVi_H*s{!TDwAt72O}CfEJTTM{*Ty%8z5A9kX7PVH3q)mpb{uc*<;$0v z)apzq2J=;;?wB$lU0c8=8|dqVY$(l5d6cNsj+d#4+zN_NzL82bg(hKoPbQVAEp@Sj z0zM`ZTH)6Ft^2e8X#C~;FYvSSERH^QSzEo`WYA!f>NTMNNyz0Wi?-0>&ege+Tsq5> z+kG~_nm24rU-cxBeg=}9n4)debbUA{*cV*zP2#Nty^G0=))O3vdg zh;fZRtlnn=gB($18b%3!&o-`L=nM?9Gr%W}$;MK7J{N^qtP1)(dc`59lJe!fLha34w0a*HQu&u zK0S&hNvUdTVnnQ!2;Do@uQ?;&qo)yK@|e6iHb?E?cz0uEV-+-3nFbp!Q!^eYO{aVt zuuSHy&s@PB%A>D@P?#;HblNvM4N*)_FTt;F7zRu9(P3ccPSz1OoyPa_AjPKD#i`%eA(XNEFXQ8T{AHZ+kUPsM+!Xc* zHJrFL@rP!Tsi(1-hBl>HmWPjG(jTOL%_z&~ufJ)xuWXd;H!2gp)bV&A46;PN^P%v= z2FL>y8q*Sd&m!j8y?Ykc*Z#>HnaM^E_E^Fjo+H?dtEMNNBxBN=#Wd49#>X`jLW?%@ zw4a!K<3ZvIjB{fQDtT7vmUnV!4F$MLV{S)Fj9D>lIH%u`TproNu%Z;D8af0CL+Cbi z-oWs5vlHBS_v5qd3DNZQ4OxkNc5#vEB9lA~H>tSviUNE=Gc7fhNso32PfaOr##2C56;(`FNGO_8jM@=N&!&39Rrmg$4-T}|}L z(sv5v2JO(Ol{d~rq<6{=QbasLX~Vi3(#>S<`K(H+?B?ZbqzI3^e>&@6&(#G+yQ82Y zKKa=-$dWcwJ5z)vUVNB77<&?;)x|FRbmMx5)``S6)&e1woIbi`=jSEOCodml^yd|% ze~b)?+%zbu)6;Uh!X$>iX6>{w#vb=%R?naGaH3X9`I1v9`N;>D{4%|2dRG$oaXbax2(z=PqWi*-wnXt+WqPkXAXEV3QNVHJa=T{g?a@U>J znlwF~VDnkdbkPLI_W?ITAGn^7LR})gqQkURlOmEH@^F|nU`?0)Tx39t8ZcJoF)T_X zu3DUpG2FXbtsI9PEVZ69wu#9It!28BpeVs83iL5#iHh8==*J03#Syg4Z(yX8MGCF|8;hKe> zt;i2ZO-;>&SP0WhK8x%dz5h05k29L!#+a$|M3qlT_!OJ}XP)Mns-k7MB4Gt~abTEL z&u(tislnh=mr}_~zx5ZH{gVqedJwsuD=hz)bGL6~g;kigOjizszNQ)6QD)VWU!32h z)6AT}pVj32tp}zez%=X$Mw8-@wp(lMimny+7gN;JyUQ3p*59r0yziIph*wy3@&*Sx2jAcMTSxn{bf0>jq4s{0 zB&#EGe=TFYX{sEXe`f@KEpSzUjajuHKqQSNA!56%fNQ^=Vv zNX{zEytkCFqGTmWE1PXug#Y{fQ%gx<)8U6s-4dJ_j{DDQSx9Kv2D6@?aucrPkANu4 z0j7Atria#VO4FNnEsGrI^%pWutXvtYZ+VmCTs~WX*AeM~$ z@3IfNi-xy_{fO!_dWoaleIU6j3v7~yD`Od(oQV!y*`T-MLFcw7ENO63%<{8?UwF^p zyys&!C#!o_9GJqKP7Ux5XNS?OwePRkylT}_UT`OGxY}B3g?4pM^@9)bNmBj~#WUXb zB(cf{28y+^s;yXkD~GJQ$_H6mI~b)R`IfT(bg>zSTk@u?vU%*g>?w98HKLkuliw4& zc?i01_6hAbE5cS?TG|yA#WwnuzTjXzbJ$|gq(JzaX-RH#XHL!sMrNjEzEk;wTiu^y zN-Lu?z&F2EM&hgf=@YgpDK7gJHUh&LIZYhXYhbj`<0f>|a&BVmq~Fx$t|(j8wKUHt zsruvH>#}8E7$y>NUnn=Ymg}p!dF#HV%expF{d0_cW#v9u%|9qe)w@H zO)Ed9B1ak$E!=0CsB&WPJD#R(X=ymQ|I#GJ|4jVK<>k2R=$qx3S80c>wX(G43HPzJ zxdnGG$AHeX(Yp z>lhyGr?bkxF+1ar;iLNL3ON?l73ae82Ai0}e#3*fJlTRXi-%8k4)DHLcXw5Ft&Ggm zf1fj4yP~Rp%<_cQ(FUH@$~?{#_H^p@joW#0x*leCS6|dgdU-aqse7Q5ZT;P`v*mj9 zlJ26G(!wgOiUN9xj(AsVfp&M5^tW#Dj(+dbuEA*L_TrdJosdLILoRN*(K$H2Z=>!_ z_&AZ}`ps)M*61EFlUmcM6V_63>1rAOOMg};N#fCOJ`pqT3xS?MuGaxr;A6V?P$YkmcE3h=)n!}HJG^wJG8b6c}f_g->8 zcU4aW`>kijfx(mY-T40l`i%Tk4fepwBOgsr4#w?Cs5 zoha_$@TdC!eDJGcfOoV2lb@_hGNY}D)$O`I7`J~{&aed7J-}?Z&nj|QY~Uq1rXVYi zJzT*kW_KHVed(m%DLd6)HQark!Dz59HcWjo*p;C?g*{on{BDn%5>HSQgJE(9F66CU z1vR?2%|5O9s5{U>TOaaZJ>D`jJq+A)H!P{2u3g+@+$E#AFSPTVtauNNQRRDCd+n;c zo-ZAJQDr~Mcn=2uVx{Gbtp6qtj=(sW6#kajbbHmU0o@8S{x%SLJWh+w+Jk#GR)0wz zPU{&M?kY$xi=y32?p^Fwimznu>FY!${!Bj`?Z?bxm!@8lmceru=Y#3}PuMs?``rSu zR!}}g3uHGc)VOV__r@%GZG;|9O`@REB5L2t#9`CY2hmKc(i=?6YGLhfuhLBhn!^@I zbS(6jq5FPpk!rrm9AsLxWh#f2wa{2J@RaF4Vhdy)A(e_m3Vrpyn!R6JtH*5vUyd>j z>U?X;D*MSZrE9x+fn$7*nVQ_BasQ(1EY@P19XMq&KzkNh`uP1t?hrnQRMA;6+(*}+ zVRS~opQRlUOtex_XJMA!yp^lgsq0%rSu*qJS$DN`GFSsq-1JQBNo2M`ffdu5{tN

    MRYLyw* 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%0D0gSP&^coJUzq;nXB!Y5<`|+EZ<48#kCRwg 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 z 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 literal 0 HcmV?d00001 diff --git a/example/index/22_20-21M_snp.6.ht2 b/example/index/22_20-21M_snp.6.ht2 new file mode 100644 index 0000000000000000000000000000000000000000..ba901df7241988baa037220fae133dd8bc7567ec GIT binary patch literal 238590 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�n4#JZ{{qn^x;Am`e7 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 literal 0 HcmV?d00001 diff --git a/example/index/22_20-21M_snp.8.ht2 b/example/index/22_20-21M_snp.8.ht2 new file mode 100644 index 0000000000000000000000000000000000000000..32bfe42f35b015ca7cd0be52d1415a0d044ae71d GIT binary patch literal 37688 zcma*wYmO{ElN{)tzXE12dC$siN&C_o^_Us6>PX!h4A385o(Kl%^sBi$v-YWD)%&df__>D9Mz`nn=jWCKJzw{Sxglk*Gx7O+-=4Qm$e$F-JoB*TlL=)0 zBBxA!KVCo29W-lBJMP!d?dO^I+o|9Gd~R6(EF0g%y(5L=ulF-E#^#L3@OFKbQ`ehq zZeNy_iDat>&B$pC$Nrr3Cn|e6ho&%>yq?6e82X`=hL4xCS0cD@ znKEpfoO7RK-j>PeeIvs1Yj4AaeNkJ8rrsv1Y|`OA&cvOiOFQZhr3~R_eV*4&tqh(K z(d}}1(4kk>x<2lopU3Munr=~|S9rI5%g@XE=lv)@f3UD8zg&KvpOW%=*{yuPvZK#~ z*=5!LZH%Aq>obg^LO=9m;(ffSeitUE&+R&=uoGpw_w9DQ-d;Jzi>5t4;n7A};7y3J z=?po6%ky1o%j@tf?{3$3xp2QeQ5@2zp1%w$wcYZX<81URpYt}-%QAbLwW;gv=X&2! zZ`a4qtGe-d@kh@Rw;gllayWZcA+bv{UJB!zO@;CSQRPC?py-mLK`;nja5m0_=(USBOdX!$v@5{ zcy%&5;-QV-6ytvHdS%b0`gDIqZ}ZxJZ&QY!i=g-%C+?i<>-LDCIG_7tlH^t~repH* z^k=(WxmCoOOl-ey(Fq?70BHXmqu~?hTFUMhOsX<4!!W-Rr6C*qkl^c6A<#J5a=Vwa zKiJb~{eIu$kHZK7@cz7ww#x1&Pm%MkIvs_~`uEq1b{JUmMs=%33)`K_A#6{F<$TA) z=g++=_`24ggyy&SdwESbRrh0)_s2u*2xHztX^w7qlq58rt*Uzuk`60wBHfGe<#=_# zg#}Oc`=KTIUeJHO8|#IZ%d3{|7=qlZ@nm21d>__0838Si_a!@_-%$_T5l}wxj>j~Q zoS#40H(GduUP^g<9fo==&>0@Hzq5MgoX5pEa~BOf)v)Lq@nwmBhC?U$YNHVMxH?4E z2OgL_w&vlDC5Nuf%SdqjlspFiKI;A8g-RQeU$4)-j9>UW7%V}m8uH-i3dSPr4=oHc z_=pQHP>YS^=!2(hgwHBaWOFpE)X}9M5i9TeuroW#As@Wapa=bZXTkgH4Hy{2Ej|dK zW77z;8w%y(O(u9K_{|i`!g;pG2We$2nF{Dd5k?qZdxR=Kq%@IX1QeTnjT$qk{IFJn z6n7bdvFUviDME4_CJb>X9Y1a$I524gu^1!s?(w)i zYVK9{#TN(yD8Dyc;R5rm$1oKcJp`8oREA5>C)(e$=_lj*Jj7SeS*gLWRZlu7!6p4% z56Tl9K+jBeWR9mMh73=`pFy0d%;TqqY9872lcWt86bgc?8`v70$M4!w{qi1$YL>}$ zI8Vk@>hr^v|IhLB0`|iOeJ(mW(DZ^?)3~0VXa2mJ(rocgW~ah=T{i10TD8V2dI}>O z(qsPib-Z6}u)^6ArO81i`V6WfZ^&ZS1}MHH_GVzO!L$#>MHI?CGw(%Ja!egQf2jBBLpW&S<3Olp}4 z=14%Ira^u09>}-WpFTism-_vlqk?`3(zZI(XVbzqk@>>G=6qW!XAZwvXc)ns#MXm_ zDY?LqC3r3zl{-~q_<<-g~S%o>!)iV6ae)4%iwyJQBoFX z|LRBL7C-w-XP10G?!hi0NTL7))Q1Zq7hLl+dC%PjnQ(>Ay2aJmpkS! z>G3wBhkpd*qq3r!`*_5ecqDC+VobbbT8i@wr@J1ALgjYm|9Twz7RNJNv|_BayEtJd z$^QHT1w82`w#Pg&J16M51s9Zd0=vuHob~WBMsVC=PI!h}AUd3lr^7i8jRIf|#2oqY zV>w8r(xb^(A?m!pyck=JG&q<04-f8m-H)G=9}|oxw3_0U$wQ*~nr? zwaGW~Y5*!5jQqSOTee^8$Aq7g2<7lFYnCE7!9Smqf1~vHnq|bG9BBG@X9*GP!@-wE zi{AWk>0zv2b(W<#L(Q2DJmr|BQ+D%Q{bP*iF%{!D-4YKI@yj7(VLw}OL4k^Y+^ee{ zb2C$L<4KE0u+ik(>UE_n3&i0GNJiVK%%}P)7^`Qc)&Xvr(A<+3F9i}s+4g~}02>Vn zkpXPYUpnSFdHIP$iBcHvL0)&F-Smsc{Vw^z^Q5+*DE<}8P<9Zr9w{DhlsbvZ7>{X_ zGa(0n7N!4}WtB3Xn)`X*W93=B!2>}5JQk|tt-SPVuJnoJgkJV`m4;NOMH<+y06`e# zy=n_$UNLJYi_y~{iiV?}an4r=KKm{km>Qd!YBgj6b-*E3}h22GPf z&qg_i?y-B;G-R#0h$Sz@QB?~L5`G>q#K0G0Ep$(wFT@{- zrH-~3Ed2d^r^tO@kCi6*Mzw%!Zv?PaNkBn%RJT8stoV5%XAc)3r<{0PmcfIz^$1T| zds!(g+&Q(|yW%Y>@?BJRIN&Y<)X7R<6($)>A8KF(!w57HfTqUwO?rZ65A zsY6+6C_G+7Q4ejxvHa@8AVC7~Wi`u~noK8at0O`MOVxZ4WE(YlW^;#|g>h9<%&6R) zUp5xbF!HRy0a1HT2Tgye?&qPpRumKGnEN(qp(cS(B$AdWg_zW~^KgWKPT)BD)EOYJW4JSGIZ2>9=KUTQT&g&G;_oCGnhvSjV}le+>`R<1~A@?k;+kwN_( zBLQn#ROBSCi88gs=5qDz3U`WdD|WU(R6Cg-lyFd{ZzZrSGY3pzW0(|hS#+j{sUKG- zUZJH)FgW*Y^#+Oi_MxN zfy6S9Jn!$^E?(s+*U9r5aAcRd4N{}_(ITFd@M`$Td>^NgxA}nNl!w*(j1yynKC?PJ zBKmiLljQ-R-2tJzrEEE|rRP;gb{0uu8|R-zw4&rQMM{cz3GP)c`hjOh5Gtt&&iOJd z?F0rzYdmUa=$obq6EoV-J`QD+Pvc51Exhq&+mM@39sMpFY8+1vK8Nz}xcf%ji6AS$ z$x`8zg<5RT?92Ng<0@ARVWl5*XAyZv5=+=~it_z~U~WtmsWZg9~uM{>gGRW~?nYEZ(G#9bTV8lm{W z5Lq^q!9rk>sE`HgcRy0a)_fiCLjzayi0C-(bDUvf>!{$EnPy4x+uVDtg$*jr6<8Y# z?57i$sL$c_AQHm(tb7#TItRe~E6VNH^C>W{5VlO@sPMYw_P1J>@Slr5cxV+vK#o#K zA?`dvq{BPEsFfY zddL~(IfG&0GzE%&)685|D%?4RJysL+_g$<^6El)VRl!vMo2Mui@Smpn5@Xcivk9RU z9r31;+c_pKvj%jRXi|>OgKDOeq+a!+-;S0gB+#wdD1fgdzrts6j@8BN(1vqzhVq&= z?E{`@`hDSYNjdYR&H8oW1h2+pY#FezK}u(kD~K(gC6DL0eCYOw?_a`EkRbVidWVK-Ca9b=s<`|#Kqvc_9H>Mn> zHtZLP#BYi;CFYKl%uN0c&SXiBaTxG-fCaqDmzyV{!Dc)hZ@9ZO){aepHQ75ILx9i_ zPRkX9P@zp1JiiH`4cOAT84h89e1~O9l)=tpqf&r;wTpQ@W80CkK$x0T%CLyM3Ox#r zA0|c4Gt?xxI9k2AVfRLdPt>m5OJ+Xx@9T*mXagL~LXf1k`M0yFro1R`vOpG1_#0v0 zC4Hu>t5}t0<=T4V+kYL23VL6J)Qv*Y zT{c0!)#!9jyGn4f8nV~P1nR(XTXC;M6rt1}x6CiU+Czb1#j$4Mqbp0dsG+XNc!4&=l@DC!)5vQmdO-8?jRh zgjUL)eKt-plU2yV5%#bN@L>_BMy)IjYO!wV%1PL@JV8;)*eh^s8J){%Dk;MaPlYzkDfpQFR02=2@WtUT53jC*I z!#@HmgDfMH3#D{hrt*~V(&@*T{JjXKszcYS^GmE2CDqI54ik1SAmwG~Vyf31o5-55;N0ribo@f}V}J>jIrfn45x!*}T5ExZ5Jx zt=x7sjIxB=s>A_9d79#;AY2Ni<60#v%!Js;t;A;kWJc>K6Kdc?UW)ihxHAOmzm)?? z55Rjm3~2h6I|Dh@)x!*gYkdr?5QuQmJ+f;F%phzz5hBl4pgTDWu_LuKaCg|5MWJZ! zwDG7eZxwv#i-uI3cBDCB@fI5?EqQe~?^GG3aIC*(YUNhDNa1t>THM+~fmMY^kj6!H z{o23 zq;N-@ccjea!=%0IfW>O5=hIFrk%UW%oLx*prLI)j#5npsH9&55CPA5#DRpuH%xVp>8Wvkw z;Y5l@oq}_g{xz1a8~O1tR+#*9vhh0--o1fUR38d0wIMN-A?&C z8Zm{7acM1i&2Pam)mbLDMlvtK(ANxNaiY43l-aEiyvavWw1kAxZlVZx8g{X<;Uf)4 z0iutCNvv{02z-@0mmw_#9dnTdtgB9bWCmVu9{}f+9Mg3d%KBK5SEVT9>BHYB>!Jn~ z(cPu>hvd``R+mN?SollAF;2A?I_E2y9NrD2iB&kX6=X&zs2cGxsR4!flvw;DQ=;8R z=0cz9V;&|9088ENZx|6ayml}OSe8H@3i$I}BFa{MA4YdjZsq2oDDj`hlnIxs0Ms%# z&}UFGH#4`?C8_~&p64}Asq9t7*s$mlN@LC<(eJ+JwG&rKU3iqW zQ)+X#CIzf4P1)~or_tC_9f_zWR!#=+DcdRJDftTWr}f0ZRBlf3l9Lm4PJ)&sHiRuI zWpt;GgXwj|4IE~%z(qJf#<>egB-daoHfMpPNp+NBGYYEwQKpkXx(Al7k(tap*Z&*d zIw6{~Q|+}{V=Bp=O2utmy3)~GjQt%UK;k)uL%T_+D=`5tH3}`0&e%Y$4~nWG~HcQa~|6HX~lEl?(t54%E^678_~d+FofF?gB_ zK%K*+39w_X8|q(@l6&LQfvf`-u)*3>*Pc|^D1H28#;*SMeOT?xRBg~{7(6?~wHl4b+%+?hLNEg5%qV@?zov5hDoTENR;-28MD!J3H$Rz>7!)yMXSTq;yPu9G(~LIJf5&8nTAFhfaI01^+YdhILmd zg8)nBmMue`$)Q`H2Y5k3`9Ud97t;SUqKrVIb0lQo|Wwkkaj&;CON`iRlAuJJ`RjpL` zP|Ix^&;WB>3}T~g75tP|2y=k3C2%8WnW|QmX@b18s}rrA%6LP+SFG%1v$-Z1d4WG{ zTuIKD=mnTM#%-3#fRAnf#FBAxeW1SIX_QjSJl@t_L39|F*aBe(TGW>3N7C`KcSzfW ze4g0jX5`<)9zxqU_4}$pY;3@Y>!wS^ABa&vVL6t_FSWqV4CSoJWk;jvBAuJe!l-P= z&f!euy=LCBE>u9! z+m6yL&5O_!Gyt`fQW0GF`Q$uY!WYkynS?L&rF1V@svO9`^9%<_LY|OM{|3YU9Zw?T z9r%#qo!M|aY!oVTMbUCbx%G1ZQSOZ@s8>VuxPrFJTb`H^P7;a|O75dA^~Rc!QwwAk zYo;|7r){ELWXf7(D|vkf*n-e|hJVJ%hk&7zA3=M$_HTZ4GrBW=iiPTNrH*R+j+s3K zw&y7u3bzdd~QH)>7lG(H2c0N6;XN_hYURfA+k2Nk7V;W*ywV6fBB7ni#> zmr#BeFSCXj;^Vq7dNf>r=5ACCIDLUM!@ux|;bYBl4%iNOMf@=pU~GE@p_ZCdO@`(& zDr&-Mt5thL>S{XqF%31%H}qUhHOeik;oi=m<&-<4*6%t}xj2PhlnDu-Fi+th*BStj z_J(dEj6bn@0T{C$3ooGJYuU0mC2#C3sw*}S6c-fHY7_#KmzZg~v zcr|2t@cl*M)F~$jR*i^evuWf5@}uys*VEjDA5E^DwKFOWv zbET@h;1+=IR&kA*rAUb~BiQitaorCT+LugmR6HPkGbNomdVNx)zwxQ0W)+C=!u5C0 zdt^jUORMd9sjyXYVEL0@Y1vv_|v90fnniT`27Q5@pmidciMp zPsOXqXTBkkQuV`@a);>kvSSFI84Rv-S-F8!jieKb`zuJ{2_36>C0h0;Sk{RM)WC=T znWf0Mlrh(8Xxkw&wl#N0kA8@USU7&*yVGkP3fqEIdSdhSDrMGiR@;ZJSL5T^3-`4-?_+~AF3Q1 za59Lt-!#|pVoo#aD@0;`_XN0sV3#w7hw;6L-#vGo3%bfO;8-rctJ*Llk-F&3*C zo;z=3oy01tl6Agb-yHU_0s#M>jMj|m)hefn_wvwg%KcEWT`hq$kT^$ykTkj@ve|>`c$|#cp;Ak}vl?YPdfKNkGrYW8cn+;A)OtIbTL_x@ z_QQA-J~0ZyUz4Z-M?2V=>%FIVfpcjLgz^w5VJ~K*Lb$bt8)&7GQ5@vLY>;JT0&zfY&B}K+o9x}s}SQ| zYNAzebmjNF#VL%EXCle)Nmt5ktZ5i!gZ(Rw=&x(Jm6%ft&qt3qBmpvCrdKU`Mgxf5 zp@vNU9Sam1$VfJaL%h(j`vg$!tblN9WG6*chWZnw2e16*Cv36k)9)*Mc^d z3QYHlJM+sLHc@YlV(pHBqTs~xIv3n{Mk_dTI?zQPPLJ0-aGtxQqx3mUPQP>QB~(K( z%y3LljFhMz@2C0`>6jA8BMs`+z8aN8xzFg-xv{ zDkuX%$J68rEpKK9@yN6aO1E1cR;+E1zz=Grp{o(9hl@XKLbOMD87&vst6C{h)BjK! z2IqEnsNx`#Hy9-zFs*M$&R-MC(_5~r3HO;B?^FIuY%q^rdzv5bBp=PnVgY{3&5U>6 zkw%T7U=KymOOon+$dM%z&WFrG!>719tvpC(TSjw+E|RF?%2ZjYES1m zjgWNIWXY^Bj|yG#z!ngljrXmTIiTnfU2QN00ekIb>-haJY8o z$WN_wR`Z;f-tG5^JxALS{zf@KARB~igh+NKIA)x#bAC{4OgG%|>;Y+B+Ub)hne&wU z66o_h0)qi5z$#zcIT}iP1VVQojIkpsRZwYmYDHxkRdDd#ipCi3q#KDdMRC&xw-t26 zGmdc|XdedWihAfOgNtuA>W&n0XQ4FGw9ZS|rHWxQV-@QMAE~t4_4Blt>Ws?)!f#4k zDgvA!o|+GDB6ih#Hc#L+cSc${1W6`I_UbJfG*wZ`rCDkTf&E%Yg8Py#fR0=$MXN{!3|1}pZ>WeF%_VisV8g*tpxQuYDG z9X=Mq7Y3pAbX+kX+F(O;04b9(1;+j@$T+c3-zssftWu5se@lb0n-Z7AVhSjh36LRk z+vfd7^+_r9B?|n0)dRs~^s2xc0@vK|dIgy}S{}%66go3JR5^=*PP_+@sCn>=mD=4+ zK?`O&XBxd<+RT}|74?l&g61x%aADZTX=c89Lkce$lS*zxo|2Y5zjZ7^i5Kc#<|oC^ z(ID#IpF)Wbsza5VBBECHVQaDx24Y&7La1*qf)hOrkwrrtv3>K5^n} zyVT}um1V>3kOVCO`Rf_S+bPfGC@dqt*zN}Wm0a?evmK7=fP!LXJ$^-9(3uJWditTm zf%>DES|#_c=+#971Ue^}j2f4F3^ znEGKZ&1l~WuK61b14$$WQ_ams3+&(ZA#VYt)lJLMoYifxH!!Xe!9P}68#===HtMu8 zi(N@!QJ<;WXOuYAS6GXh4A-u(M_n}e9;L+|% zS#6nEnn_?+zas~pzseK0n*VuD?N~~7L~0_`v`)r4ACg+iG153ui#2p4&&BR>7$iA* zLI7fg;+yqEVvy&w=p4)$YmYq1x6f*07S)YhBO#0$NW?^&P8uo8q$g#`J;o^&?BcFZ z+no`DY z%EK|JJSV)MwLBIPC12fh785z7tbXD2GlWa@`%3oTa8tLeMtUx6nVax{=<>B0o?p0l z40M3?V?)w}o(i*x0dXd9rLb~lGL9UoGLP3@u7#(3z%*!;iIsT*h^SL%(}>jY3N6H6 zJg5zG()>>L_zo~!^A+zr3`paOTVKi5ZQi;}K@CGb_ds1pBdcLt^`iK^s6tFe$NHaP z&Yf$r(*uzO(DaD6XCk{`p5Ip}r{rn+HfuoGAQ#E960lCJ{Bg&Om5=Le)F^T^-k3?h zz$bI=fP!VpeA$_VJgaEt{SJM_Gk1;D_;yi;Uc;1ic%)2o@VYy?oUoseM7cDh>yT)J z#}x|JF_&2gmy#qie2hmFeAbjn5V3!ljzJRDxyIBngae=@c}ow)?C= zh8#ok2>IQPIfWqC6AU^qfql9%YiGGbuay_(s zF_+lm_c3pK~&Ft{7#9gXuCaYjz0%tE2>zFO6q4K zeep5{VWdaV;!sIs3LCdbPxEauXSgX!-M&jIaK_0rS0aa_Y6LW4a2_ITL_!inyr_k?$#cc-mbP z`FjB&qFi#8CS!?Yl(D2zMEUb9N7!w(j+X8Ta;aK-?J#K=mKPBX&+BQ<$UF3X{%RGM zn5SV?^^%(nLp_svYNKS-w^cw90otrxYg*q`RI(5pnbbW~9bwTq`C)Hf_8}J37)`6T z#hELzPN_Nh&=49)b&H7p20WQCQhmS@4s|bgeKGmaE|`UHbqo&2jU4f&71{aBVv;1) zke;P}?P+ZT#<8SZrV@O+Sqcwl!-G0VMmR?^L2A7WPEV9Z_@$KLMje2Zlf6L zQu?r$C&}Ji60(m?{xeS10KfAYF)GYu_KN?_CC;{4mxDRg+@5KOiBO|bUc;KQt759W zU&W>r%zf;5;bfx9WdUzS7y5l5)N(hOfai52XZOe^i11s=w7ib4hY(jjG9nS_PeUeLnR?a!^{?y&fBFiWery-FAb8;ak!vuRk zsAH!f(hkd;>7k9aD2A0~ue`hOj+-d++is~Nz%oi+jc{UKFl*(`5+@cCoLzsuNGw&o zlyy8+ZHX7mvf(6e-bhnN3Gb91OF_n&(NVVOW)**Awo9Hsa~i1Q8ZU}nAu;zb(lqWC zIpw^bw1N)qOOTycUTo3-2$uC>S3cz=dz9ZuQkJb^ zmjnp3Iu;K<oLLN-6N@z6L^m7@b9x2k3j~$^ll5+^AyXXVranXF5Lx0%|kY zs&jnl*Z~=#G&;IV1R-$2I)PxxHra53%ZO5fx|8>Jp%5ZI;;dY$AJjv$`WL>=K z6E++vdpXJxb6{*fsITYPhXnJV%MeHyyxg1(4hRy)IU&8t(^fkh;2;qyUS*mMtVF}Y ziLY}lkRtXkvC)O_ACxqzoHFR6p#x~*8|st#)q$vQ>eFWLb`-*ypgb016rnfK>!3R+ zh*r}mZ3-k~g*xP}vw%6OGb@r=S#xF#B8uZ&bv!9eNsMPuw2TG?6H}qE3o8V|LO(hr zj!p`YD`@6D1Q95|fX$Uroua9`n3R5O&k}M(nQ=P0(hw83vQl{f*9r7pI7fr370ycV zKf_dWsyTrW2PW64*D{hi6bb$30X5{OdmspO2tcS?WCMPUavZ*q$~V&~`J~{frc$a5 z73AMg3sQ9>@7tYNy~){@3Z%avEaw~EBuD6oK$KwebfG*X#mvq7oBGiBC?iUBI$tFfn(lX$_g!;6tvIPd#W(>>`@UTUouE6W`Gn=q+k_p<_!o5N z4lhY{^8I<3jl!AyJl-&ra#MfrGgYZG_kwDp?h}b)Ir0`b8btAwWV4t!stiyDoEbfL z-j@RKL>(>*Xnlp!^f&S^I(ROhqG6Zr=oS`v86*S>RGTp$`fXvL@5}Tq-?LPe8au=y z*ld#e-^L!ojkWVQF~!fy25(b3x7{Ipd`zbwr1Uu2zJg=wt2Cm)@Jy~|p-e>Z7b0i!fi&d&?yAq1SZhhZ^#Wy9D7*}P6+0Z7jA&PhXeSaHg2 zK_fGbFc2`x>yB~)2eiC_@SdVXcsloc8lyPTFgUEW+kf}CtE>}~Ut`r>G;uD%$;*1M z#g>&#?6-7}t28){z`cwDs$A%0{FOo+oZe#j2)x+5IaON3t2)T+@;3{XNH=^HQ=Hwx zJE{uk)H3W#yq<+O=l?HHA?(47oU~qA$QJ!qKjik@CaSSPoRX9sKj=ypvzhzz0jOK{ z;=>8s8qMTvn{Hv0lA|Yzf~v}ADcGoOgge8TiBLoHE28}Nbs4hdTZkf5Ux$RVQZ3ip zt&=~JdP*Fy{mH}g3(+x?B`KX&{O9vpw-)ODf{WF)q4SJ`IGrWj%Y~Ube7;@9&8KEm z8fBaMd>RWiMKK7M)_qY7QMopi3#X#1NbRTtraWrmRano3=QqDOShw!OLu1&YN5n0! zN@8mMymJ;7(m3;K&6ym{7buSRC((0pzxPI=w{DQ;@+lbP=L@_4?!;ub_v*zFfMCvC zYuiyhM$uD-LO!HZzoYEwk860A%$NVI<3V7$-<^913Esu`vJ*+7=hox1hCk>H|Lm)9psx2;;o&%@nCh=()t!E_2#&T-uyS3w<@Wv$D;(UQMu z=ykKTr7Ok7Wnwb8#(S<3zN>1;=}4o8j>M-M@f*#DJtBZEmK+o|@>`FJQ*=#^8-6#);BSW7ss2hq zEuJiM#kq^8@*0VklZXcBj+VQ^QHPeZA1(MDrFOJTgZq2X+l+pOOH}%Gt+ZPF;oF{+p5ua{VS1JSEDk8r08eib{ZM(NDlDBlFMQQWfw&(8!smSb>I zr!b!6W9lcbiv33xQAwCIlN}%br>kz!S}YTinH8YnBi)EtoQ)xREWVZ{rsvAu$zh zxWq7-(h9)gqFl?fs31{xEoCMOW9Z!Z%f$ISGg*=m+_h^a2Daam=|dMeK{LU$g36z@ zkiwc5M^X|q@4#4Ao8nEF0AUmLP)~ZYUpsIy09*6DmnNEf~B6E z8|Q=akxX92Fm!_8g4cd|j9_;^&Che~D5kVjRke;5j(fR4Wq$X@2Dw;uIpnWdnoASk zA4vw&sZ{37{8=zpW+xfBOUwK239Iz<9v2?JUN&{NN63^)KQkE5F3sK*XyNf)-R87B`8 zqBymJTyx@*yC7D{>Z-x;_4itgBHwh6+2%4p_DfEkaFH=3Qzna~Xn692JT$|GOQ!!F zGd3OSUuXpZXASolklZv>Fc3-)oKAhJ=WBgxJG*xjqd(j2a#fQ2Z)Z=`I6tqJz2$OA zH?TaTp5Ek=@FFzh%MXKAPYQ-`sUqai36;5;Kh8q0d6+imuE57%%JlOvO-5ahepI!Y zGUblPxiglzP1f;?tDd*}cYJosiMR#d)pBZdr$+9|1F!8pWjiB0RqpZce3jOjs|tpZ zzzRkiRf*{`<_y_}nr5XMt2|TQLk=u`cb2=s(Pm+VcPu}W|LnH{SSO>2MwJQYqLNcV zQlT*LWVys<)+@0TkT0a}VJ2?W)%921wIGO@J5Cb8C)&DU)EOb3uxy&pnA#%i;22_=!zWK0&A&F!z)0?Qo$Iic70A zCo=VWmF$OSw5eK;Oaf?rUjWpD?0rc zG=I{9!{P)O42G41c`8Jh+KPl9#2V&i#3=;F;c~Pdis0nC)R^}`R2d`8Ir*xHt}YbO z)w*{oDydNJb01LIF0c4Pq6f|LTB*gFfhlgWg#iXq+5v|6qVt=jpp*U8S=OjFCjm8? z&yd_KLt&2Wt#MrAfM*Yf1WWGe8;#di;0&a6^J>amrP}^}3|s+f0@sZp4wTI%!uUEO z^6gZ4s#9rBDYaHx>7Ud$bK@Qo680HTooABxbAyVXNGHDZoT)X4Tm_)b6$KOES?(d~o;1#t+Vkt2{AryMEBwt*h_F5{WPy2L)#{vc;rXfg zW5oCn?O4i#0ZZ|*YbDtX${XP*jgy(#zhi7C_MVRET>=Wm6bNC1Ut|EA?Z#ZBuqz*Q zm%wWTYKpmykdJsVF#4-6nug(SIez>*Ynz$g(;}ahTZs~NDQs9w#e;g-gx@8PJaybp z1t+*U-{R#zV`+T?$(JRoLMb7;WP}dc0EF_@mwB<0Rtum*lGhv|7YnJ&5xe_5Cxs&! z;ca@4-zxwCv2LkX98nQ%SFxqV_bGeNK^&TJgQ(+D#Eu4dd8Wd$jS#DBaj7n6k6th z!ZUbp&yICPp6AI5^xT!dU{Fm?%fX-2=xQJ{jX5_u4kjD2S=b&h*5DdyX@;K3mV+ftGV(XV=Wwo?4Ga<)5)h#ujnnJuV zHUDz&^g?AGlFiU5D!IZ|GI5M3&Tn9N(sa+iZ7Ma|F}(et&y`LPMMI+@-BIMn!;z8IBTfCAvR^=Mn|^*Pmi+0aneco z^Ca=WRl}@uSQ6&Zp)M@u^jCppXoR@zBPFZq^nV_pNugVzw2!tTnE#u8N)Zw8MN7|=QZ{pM(@Ap+Kk{;&Z= zsS#;%(L>|}+JArIZPB)nnnCYRnj}NzyQ_Y=(KXSEV`>tWDAdi}WOqpZa?(8>Tv%Pc z*Y&3m>Ft9ToeXbqh8a`EWIdgNr%qD~5F%6MocYmHXUy|Ed`A-+V3OhxY-A`i*GAn9 zffSmsB46@(I-UItz3k91IzUOQ^BJCUZQ^@qpvn483JaM^tV5^*y?q;lB;P{q(1Gvu zIcxXW!4EVNDPgL9WG#14_Py0x$QEr10=p9pJSBJ4M%hi>WD3ny<`k?FY$E*BA+=dU zl5pmyT+NhHiw$1RPR^{YSYynxRi9Ma*i^|=D+@fz5?d@!DF%RC3iq&r-0l6WTBI&} z%229B&=pv`dzFY@ol!NrWE-hdgb=(@)X29ynLIkfeGw{fOKhq@6lIl7@({g{W?h_0 z+qsmPPeIUpo#S>Movp)>7SPYEGFP@bN8X0g-1gAm%`g|hfWkOP`MRVn5IZ8t59L*Eb7HmdXj7E82nuxu#G@1|KCWKm}ElXg_jR9eae*$D*J?7aRb4}~?MEAx27 zQ!XJD?)`hwBOT{fv_geM#$3LDxvxf%CQbf=NZ0!QxRG*lddpMu2VgL}x}W+z^~+ct z6b|3LMNtW8Xf8%RSmFKLZI4jnnSfO44))3Y6x(GbzPdL4p9g_6&1lGAKkpP+SfH

      Ho)=gUr2|qdrNJ3L({vmK;|+!=KD^ z8|SM0Ko^}2xUJy@cgz7RJg(xd6po+OdfTWHRHE2%3fSV27@NHTqw^!xc$kH@mQTq% zAL&lym&~XC3`*t(*1l5)S|O+sahb;BG<8qrh4q4bX6G6zQH? zaDc!%qr&p#&PZayo``7%t%tDn*qmU_IP=g&GU0wrWp}>mRIQ=ECH$upvEp=!Lc6;{ z%fY(EMnv$XIYItPdY463K!Qgd)g6)&rZ(Exlh2s~NqTvOsl(q`DOPiEK2Me@>HM}0 z+&tOOK_q}MaTY1ET2fq3+mNt_T~{I+O&AmKhQA24>`uoiBR~Vkr(*O#8k&d9mrB&K zAl1bGJgy>qeWwI{SA$gWqN~5|X~DYgWdSsmnhN>98pvI&tlTx&Xb=elnnI66 z)ALm>fHfEQ4wgzKuu&ENPH94=3E~*e;M$ru&N$ZrNY^fo@2QSAq9t)Oxm-1 zb9Kt{JrvlSVuchFMW^D4W;l^5H^+|{EXk{Zz<39Hv$x=_sDuCr1a)GpGWvMzFhinB zWhxW%yRh}Z#1wWvpJG&}fLokOJ`v*v^*R3hk?$;+QBi$7Xnj=`qDutT)zIRpMB~g? zf+EVL%3x=*t$H3*FDNkY-MxtObC|}DfXZ@&egJvFv#r^PX#?}|8M^b7^8sZ literal 0 HcmV?d00001 diff --git a/example/reads/reads_1.fa b/example/reads/reads_1.fa new file mode 100644 index 0000000..6ef20e6 --- /dev/null +++ b/example/reads/reads_1.fa @@ -0,0 +1,2000 @@ +>1 +GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT +>2 +AGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCAT +>3 +TTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCA +>4 +CTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTG +>5 +ACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCC +>6 +CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA +>7 +GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA +>8 +AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG +>9 +AGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGT +>10 +GATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAG +>11 +CAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGG +>12 +TGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTT +>13 +CTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCT +>14 +CCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCT +>15 +ACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCA +>16 +TACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCC +>17 +CCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTC +>18 +AACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCAC +>19 +GCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCCA +>20 +AGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAG +>21 +TACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGT +>22 +CCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCT +>23 +TCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCA +>24 +CGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACT +>25 +CAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATG +>26 +TGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGA +>27 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>28 +CAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCC +>29 +TCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTG +>30 +TGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTG +>31 +TGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTT +>32 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>33 +CAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAG +>34 +CCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTG +>35 +AGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAG +>36 +CACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGT +>37 +GGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGG +>38 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>39 +CCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGC +>40 +GCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACA +>41 +CAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCT +>42 +AGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGG +>43 +TCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGG +>44 +AGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCT +>45 +CCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCC +>46 +GGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGG +>47 +ACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGAT +>48 +GGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGAC +>49 +AACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCAC +>50 +GCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGG +>51 +TTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCG +>52 +ATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGT +>53 +AGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGT +>54 +CCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCG +>55 +CCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACAT +>56 +GGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGG +>57 +CTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCA +>58 +TGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTG +>59 +AGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCT +>60 +CCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGG +>61 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>62 +CGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAG +>63 +CTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAAC +>64 +TCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCC +>65 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>66 +CATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTG +>67 +AGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGT +>68 +GTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTG +>69 +CCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCG +>70 +ACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTA +>71 +GCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGG +>72 +AGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGG +>73 +CCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCT +>74 +AGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTA +>75 +CCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCC +>76 +ATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCT +>77 +CATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTG +>78 +CCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTG +>79 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>80 +TGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAA +>81 +TGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTC +>82 +GAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTC +>83 +CCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTG +>84 +GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT +>85 +AAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGT +>86 +CTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAA +>87 +CGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGA +>88 +GCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCG +>89 +TCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACC +>90 +CATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCC +>91 +GAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAG +>92 +TGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGA +>93 +ACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGAT +>94 +CCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGT +>95 +ATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGC +>96 +GCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAA +>97 +CTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGC +>98 +TAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCA +>99 +TCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTG +>100 +GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT +>101 +GTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGG +>102 +CTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGG +>103 +TGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAG +>104 +CCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGG +>105 +CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA +>106 +CCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCAT +>107 +CAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCA +>108 +AGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGG +>109 +AACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCAC +>110 +TCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTC +>111 +AGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGA +>112 +TTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTA +>113 +GGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACA +>114 +AGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTC +>115 +GCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGA +>116 +TAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCG +>117 +TCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGG +>118 +TGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGT +>119 +GGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGG +>120 +GTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGC +>121 +ACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTG +>122 +TGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAA +>123 +GAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATG +>124 +CCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGT +>125 +CCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCC +>126 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>127 +CCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGG +>128 +TGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTC +>129 +TGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTT +>130 +CACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGC +>131 +CCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCAC +>132 +ATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGG +>133 +CACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGT +>134 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>135 +CTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGG +>136 +CCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTT +>137 +GGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTC +>138 +TGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGC +>139 +CCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCAT +>140 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>141 +AGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTG +>142 +ATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACA +>143 +CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC +>144 +AGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTC +>145 +TGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTG +>146 +AGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCG +>147 +GGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAG +>148 +CAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGC +>149 +ACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCA +>150 +TCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTG +>151 +GGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAG +>152 +AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG +>153 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>154 +AAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAG +>155 +CAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGT +>156 +TCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCAC +>157 +AAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACG +>158 +AAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTT +>159 +AAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGA +>160 +TCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGG +>161 +CAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGC +>162 +GAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCA +>163 +ACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCAC +>164 +ATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTT +>165 +AAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGAC +>166 +TGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAA +>167 +AAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGA +>168 +GGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGG +>169 +TGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAA +>170 +TCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCA +>171 +GCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGA +>172 +CAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAG +>173 +AAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTG +>174 +TGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGC +>175 +GCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATAC +>176 +TGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGG +>177 +GAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGC +>178 +GCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGG +>179 +CTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACG +>180 +GGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTC +>181 +GATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGA +>182 +TCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCAC +>183 +GGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGG +>184 +CACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGC +>185 +TCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCC +>186 +TTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCG +>187 +AGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTG +>188 +CCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCA +>189 +CCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTG +>190 +GTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCA +>191 +ATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCT +>192 +AGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGG +>193 +TGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAAC +>194 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>195 +TGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACA +>196 +AAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGC +>197 +AGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGA +>198 +ATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCC +>199 +AAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCC +>200 +CAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACA +>201 +CACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGT +>202 +TTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGG +>203 +CCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAG +>204 +GTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGC +>205 +TGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTC +>206 +CAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCC +>207 +AAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGC +>208 +GGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGG +>209 +CCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGA +>210 +GTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCA +>211 +CCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCT +>212 +GAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGA +>213 +AGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAG +>214 +GGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGC +>215 +CCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTG +>216 +CATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGT +>217 +GCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTC +>218 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>219 +CTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCA +>220 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>221 +AGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAG +>222 +AGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAA +>223 +TGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTT +>224 +CCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGC +>225 +GGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGG +>226 +CACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGT +>227 +TTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTA +>228 +GAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCA +>229 +CGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAG +>230 +TCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGG +>231 +TGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAG +>232 +GCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACG +>233 +GGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGG +>234 +CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA +>235 +CCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCC +>236 +ATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGG +>237 +CCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTC +>238 +CCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCC +>239 +CACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCC +>240 +GTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTG +>241 +GCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCG +>242 +GCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCG +>243 +GACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGA +>244 +CACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCC +>245 +GAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCC +>246 +TCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGG +>247 +GGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGA +>248 +CTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGC +>249 +CAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAG +>250 +GGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGT +>251 +TACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCC +>252 +GAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCC +>253 +CTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGG +>254 +AGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCC +>255 +TTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCT +>256 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>257 +TGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGC +>258 +CATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTG +>259 +CAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCC +>260 +ACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGA +>261 +ACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCC +>262 +CCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTC +>263 +GGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGC +>264 +ACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGAT +>265 +CCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCC +>266 +CCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCC +>267 +TGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGT +>268 +GAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGC +>269 +TTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTA +>270 +GCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAG +>271 +ACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCC +>272 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>273 +GCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCC +>274 +CCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCC +>275 +ATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTT +>276 +GAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCC +>277 +GTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGC +>278 +AAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGC +>279 +CTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCC +>280 +TTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTA +>281 +TCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAG +>282 +CAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACA +>283 +CAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCA +>284 +AGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAA +>285 +AGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCT +>286 +GTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGG +>287 +ATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGC +>288 +GTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTG +>289 +CAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTT +>290 +CACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCA +>291 +GGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGG +>292 +ACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGG +>293 +TCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCAC +>294 +TGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTG +>295 +CCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGA +>296 +AGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGC +>297 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>298 +GGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGG +>299 +GTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAA +>300 +ATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACA +>301 +ATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCC +>302 +GCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGA +>303 +GCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAG +>304 +GTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGC +>305 +AGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTG +>306 +GCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAG +>307 +GGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTT +>308 +GGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGT +>309 +TCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCC +>310 +TTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGC +>311 +CATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGT +>312 +GATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGA +>313 +GATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAG +>314 +CCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCT +>315 +TTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGC +>316 +CCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCC +>317 +TCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCA +>318 +CAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCC +>319 +GAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTG +>320 +GAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGG +>321 +CACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGT +>322 +CACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCA +>323 +CTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTT +>324 +GAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGAT +>325 +GTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGA +>326 +CCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGC +>327 +AGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGAC +>328 +CCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCC +>329 +GCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGAC +>330 +GGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGC +>331 +TGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGG +>332 +CTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTT +>333 +GGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTC +>334 +TCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGC +>335 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>336 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>337 +CCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCT +>338 +GTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGG +>339 +AGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCAC +>340 +GCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAG +>341 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>342 +CAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTC +>343 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>344 +CTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCC +>345 +CCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGC +>346 +AGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGAC +>347 +GCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATC +>348 +GCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCC +>349 +GTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAA +>350 +GGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTG +>351 +GCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGC +>352 +ACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACT +>353 +CCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCA +>354 +TCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCC +>355 +CCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAG +>356 +CCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTC +>357 +CTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCG +>358 +AGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGG +>359 +CGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACT +>360 +CGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGT +>361 +CCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCT +>362 +TCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACAC +>363 +CATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTG +>364 +GAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCA +>365 +AGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAA +>366 +AGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACC +>367 +ACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACC +>368 +GGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAG +>369 +GTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATA +>370 +GGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGT +>371 +GTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGC +>372 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>373 +GCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGA +>374 +GAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCT +>375 +CGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAG +>376 +CTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCT +>377 +GTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTT +>378 +AACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGT +>379 +CTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGG +>380 +ACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGG +>381 +GAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCC +>382 +GGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGG +>383 +CTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGG +>384 +CACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGAT +>385 +CCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGG +>386 +TTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGT +>387 +TGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGA +>388 +CACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTT +>389 +CCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCC +>390 +ACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCA +>391 +ACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGC +>392 +GACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCG +>393 +AAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACG +>394 +ACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGAT +>395 +CAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCAC +>396 +CCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCG +>397 +AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG +>398 +CGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACG +>399 +CACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGC +>400 +TCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCC +>401 +CGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACG +>402 +CAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGG +>403 +GCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGAC +>404 +GCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCT +>405 +CATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTAT +>406 +GGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCC +>407 +TTTCTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGA +>408 +AATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACT +>409 +ATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATG +>410 +TACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGT +>411 +CATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCC +>412 +GGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTG +>413 +AGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGT +>414 +GCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACT +>415 +GCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAA +>416 +TGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAA +>417 +ACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCA +>418 +CTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTA +>419 +AAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACG +>420 +TGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTG +>421 +GGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGG +>422 +AGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCT +>423 +CTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTA +>424 +GCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTC +>425 +CACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGC +>426 +TTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGC +>427 +CATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTG +>428 +GGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTG +>429 +CTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTC +>430 +CACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCA +>431 +AAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGC +>432 +TCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGG +>433 +GCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGG +>434 +CGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGT +>435 +GGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAG +>436 +GTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTT +>437 +AGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGAC +>438 +GAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCC +>439 +GAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGC +>440 +GGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGAC +>441 +TCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTC +>442 +GCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGG +>443 +CCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCG +>444 +CAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGT +>445 +GTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGC +>446 +GACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCT +>447 +ACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCC +>448 +CAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTC +>449 +AACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGAT +>450 +TGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCA +>451 +CCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTC +>452 +GTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGG +>453 +CCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATC +>454 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>455 +ATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGG +>456 +CTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTT +>457 +GCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCT +>458 +CCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGG +>459 +GTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTG +>460 +GAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGG +>461 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>462 +GGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCC +>463 +CGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACG +>464 +TTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCT +>465 +ACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTG +>466 +TCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGC +>467 +ATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACA +>468 +ACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGG +>469 +ATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTG +>470 +ACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATC +>471 +CCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGC +>472 +GGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCC +>473 +GCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTC +>474 +GCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTG +>475 +CACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGT +>476 +AAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCAC +>477 +CTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCA +>478 +CAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGA +>479 +AAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAG +>480 +GGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGT +>481 +AGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCT +>482 +CCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCC +>483 +TCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCG +>484 +CAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCC +>485 +CGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAG +>486 +GCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGG +>487 +GGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGT +>488 +CAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCC +>489 +TGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAA +>490 +AGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGC +>491 +CTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATC +>492 +TGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTAC +>493 +AGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACC +>494 +TGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTC +>495 +AGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGG +>496 +ACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTA +>497 +ATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGC +>498 +CTGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGG +>499 +GATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGC +>500 +GTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGT +>501 +ATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACA +>502 +CATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGT +>503 +CAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGG +>504 +CGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGG +>505 +CAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCC +>506 +GGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACA +>507 +GCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCG +>508 +AGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGC +>509 +CCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCT +>510 +GCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACT +>511 +GGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTAT +>512 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>513 +GGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGC +>514 +AGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAG +>515 +CCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCT +>516 +ATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGT +>517 +GATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAAC +>518 +TCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACA +>519 +AGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAG +>520 +TACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCG +>521 +TGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGC +>522 +TTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCC +>523 +AAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTT +>524 +ACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTT +>525 +GAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCA +>526 +CCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGG +>527 +CGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGA +>528 +TGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGT +>529 +GGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGC +>530 +CCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCT +>531 +GCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCC +>532 +AAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAG +>533 +CAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGG +>534 +GGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGC +>535 +ACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATG +>536 +GTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACA +>537 +TACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCG +>538 +AGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCT +>539 +GTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCC +>540 +CGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGC +>541 +ACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATC +>542 +CCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCA +>543 +TGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTT +>544 +ATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACA +>545 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>546 +CCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCA +>547 +GGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGC +>548 +TCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTT +>549 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>550 +CAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTC +>551 +CCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGG +>552 +ATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCC +>553 +CATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGT +>554 +CCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAG +>555 +CCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATC +>556 +CCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTT +>557 +GGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGAC +>558 +ATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAA +>559 +AGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGC +>560 +AGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATA +>561 +TCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCG +>562 +TGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTT +>563 +GCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCC +>564 +CATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTG +>565 +CCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTC +>566 +TCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCC +>567 +GGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTAT +>568 +TGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGG +>569 +AAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGA +>570 +CGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAG +>571 +GGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGT +>572 +GCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACA +>573 +CCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACA +>574 +TGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTC +>575 +ACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATG +>576 +GGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGA +>577 +ATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGT +>578 +GAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCA +>579 +TGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGC +>580 +ACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTA +>581 +CTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCG +>582 +ACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGC +>583 +ATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGT +>584 +ATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGG +>585 +ACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGAT +>586 +CCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTC +>587 +TTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCT +>588 +CCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCC +>589 +CTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGG +>590 +GGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTAC +>591 +CCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCC +>592 +TGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGC +>593 +TACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGT +>594 +CCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGG +>595 +CCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAG +>596 +AGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAG +>597 +TGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAA +>598 +CAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCA +>599 +GGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCC +>600 +TTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAG +>601 +GACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTG +>602 +CTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAA +>603 +AACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGT +>604 +GCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCG +>605 +TTCTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGAC +>606 +CCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCA +>607 +TTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCT +>608 +CAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACA +>609 +GACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCG +>610 +CCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCT +>611 +AGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGC +>612 +AAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGC +>613 +CTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAAC +>614 +CCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACA +>615 +CATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCA +>616 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>617 +CCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGG +>618 +AGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGG +>619 +CAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCA +>620 +ACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTT +>621 +GACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTG +>622 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>623 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>624 +CCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACAT +>625 +TCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCC +>626 +TGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCC +>627 +GCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACG +>628 +ATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTG +>629 +CATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTAT +>630 +GACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCT +>631 +GGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTC +>632 +GGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGA +>633 +AGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCG +>634 +CTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTT +>635 +TGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTG +>636 +GGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGA +>637 +CAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGG +>638 +TGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAAC +>639 +CCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTAC +>640 +TCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGG +>641 +TGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGA +>642 +AGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTT +>643 +GACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTG +>644 +CCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGA +>645 +TTCTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGAC +>646 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>647 +TCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGG +>648 +TCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACAC +>649 +GGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGA +>650 +CTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGG +>651 +TGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCT +>652 +GAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGA +>653 +CGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGC +>654 +AGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGG +>655 +TCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCA +>656 +GCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCG +>657 +GTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGT +>658 +CCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCC +>659 +GTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAA +>660 +TGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAAT +>661 +CCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCAT +>662 +CATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCC +>663 +TCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACAT +>664 +ATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGC +>665 +GGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTC +>666 +GAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCA +>667 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>668 +CACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCA +>669 +CTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCT +>670 +GGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGG +>671 +TGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTG +>672 +TTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACAC +>673 +AACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGT +>674 +CAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAG +>675 +CCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTC +>676 +TTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCA +>677 +CACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACAC +>678 +GTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACT +>679 +ACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTC +>680 +GATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGC +>681 +GGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGG +>682 +GGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTG +>683 +CACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCC +>684 +GAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCA +>685 +AACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCAC +>686 +GGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGA +>687 +TCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACA +>688 +GCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTG +>689 +AAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGAC +>690 +CCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCC +>691 +CGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGA +>692 +AGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATT +>693 +AGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGT +>694 +TGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCT +>695 +CCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCT +>696 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>697 +AGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAG +>698 +AGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCT +>699 +AAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGC +>700 +AGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGG +>701 +CTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTG +>702 +TTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGC +>703 +TCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTC +>704 +AGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCT +>705 +CCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGC +>706 +CAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGG +>707 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>708 +CACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGG +>709 +CCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTC +>710 +TGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAA +>711 +GAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCT +>712 +GGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCC +>713 +CTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGC +>714 +GAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTG +>715 +GGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGG +>716 +CAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGC +>717 +CCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCC +>718 +TTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCG +>719 +CACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGT +>720 +GATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTG +>721 +ACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTG +>722 +GGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCC +>723 +AGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAG +>724 +ACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTG +>725 +ACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGG +>726 +CTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGA +>727 +TGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTG +>728 +CCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCC +>729 +CCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCC +>730 +GAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCT +>731 +GAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCA +>732 +CCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTAC +>733 +TCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGG +>734 +CCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCC +>735 +CCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCT +>736 +ACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCC +>737 +CATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAG +>738 +GATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAG +>739 +GTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAG +>740 +TCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGC +>741 +GCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTC +>742 +CTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCT +>743 +TGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGC +>744 +TGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTG +>745 +CATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCC +>746 +TGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCAT +>747 +TCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGG +>748 +GGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTA +>749 +TTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCT +>750 +GACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGA +>751 +AAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTG +>752 +CTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGA +>753 +GACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGA +>754 +CCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCC +>755 +CATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCC +>756 +TTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCAT +>757 +GAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATG +>758 +TGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAAC +>759 +GTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCA +>760 +ACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCC +>761 +CGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAG +>762 +GTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAG +>763 +GCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGC +>764 +GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT +>765 +CACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCA +>766 +CCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCT +>767 +AGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCT +>768 +ACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATG +>769 +CCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTAC +>770 +ACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGG +>771 +GGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGC +>772 +TTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCAT +>773 +GTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGA +>774 +CCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGC +>775 +GCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAA +>776 +CTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCA +>777 +GGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGT +>778 +TTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAG +>779 +AGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCA +>780 +CTGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGG +>781 +GAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATG +>782 +CTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAAC +>783 +GATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAAC +>784 +TTTCTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGA +>785 +TCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCC +>786 +CGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAG +>787 +GCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCC +>788 +GGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGG +>789 +CTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTT +>790 +GCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAA +>791 +CGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAG +>792 +TCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACAC +>793 +ATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGT +>794 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>795 +GAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGC +>796 +GCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCC +>797 +CGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCA +>798 +CCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAG +>799 +CATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCC +>800 +GCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTG +>801 +TACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGT +>802 +GTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGC +>803 +GGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGG +>804 +CTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGC +>805 +TCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGC +>806 +AAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGC +>807 +CTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCT +>808 +GAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGG +>809 +GAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCT +>810 +GACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCT +>811 +ACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTC +>812 +AGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGC +>813 +GTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCC +>814 +GAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTC +>815 +TGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGC +>816 +TGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTG +>817 +CCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCT +>818 +AGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGG +>819 +GCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAG +>820 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>821 +TTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCT +>822 +GGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAG +>823 +GTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGC +>824 +CCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCG +>825 +AGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAG +>826 +CAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAG +>827 +GTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCC +>828 +TGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAA +>829 +CTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTT +>830 +CCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTT +>831 +TGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAA +>832 +CCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGA +>833 +ACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATC +>834 +AGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGG +>835 +TCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGG +>836 +GGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGG +>837 +ATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTT +>838 +GTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGC +>839 +GGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTAC +>840 +CGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGA +>841 +ATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCT +>842 +ACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCC +>843 +CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA +>844 +CCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATC +>845 +GTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTG +>846 +CCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGC +>847 +TTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCAT +>848 +CCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGG +>849 +TGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCAT +>850 +GGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCC +>851 +TGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTG +>852 +TAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCA +>853 +TGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAAC +>854 +GGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGC +>855 +GCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAA +>856 +AGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCT +>857 +TGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAA +>858 +TGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTG +>859 +ACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCC +>860 +CTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGA +>861 +GCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCC +>862 +TGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTC +>863 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>864 +GGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGG +>865 +CAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCAC +>866 +ACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGA +>867 +CCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACA +>868 +GCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTAC +>869 +CACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGC +>870 +TTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACAC +>871 +TTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCC +>872 +TCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACA +>873 +GACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAG +>874 +GGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGC +>875 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>876 +CCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCC +>877 +CATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCA +>878 +AAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACG +>879 +GAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGA +>880 +GCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTG +>881 +CCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCG +>882 +GAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCA +>883 +CCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGG +>884 +GCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTG +>885 +GTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGC +>886 +TGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGA +>887 +CGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAG +>888 +GACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCT +>889 +GCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTG +>890 +AGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAA +>891 +GTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCC +>892 +GGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGAC +>893 +GCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTG +>894 +CTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGA +>895 +CCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGC +>896 +GGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGG +>897 +GAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGT +>898 +TGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTT +>899 +CCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCC +>900 +TTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCG +>901 +GGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGC +>902 +CAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCC +>903 +CGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGT +>904 +CTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCA +>905 +CCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCC +>906 +GATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTG +>907 +AGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGT +>908 +AGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGT +>909 +ATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTC +>910 +CCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGG +>911 +TTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCG +>912 +GTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTC +>913 +GTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTT +>914 +AAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCA +>915 +TCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCC +>916 +GGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGT +>917 +TACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCG +>918 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>919 +CTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGG +>920 +AAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAG +>921 +GCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATAC +>922 +GGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGA +>923 +GTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGC +>924 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>925 +GCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTC +>926 +AAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGA +>927 +TGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGC +>928 +AGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGG +>929 +GAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGG +>930 +AGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCT +>931 +CAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTC +>932 +TGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTC +>933 +CACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCC +>934 +TACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCG +>935 +CCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGG +>936 +TGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAAC +>937 +GCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTAC +>938 +TGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAG +>939 +GAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTT +>940 +GGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAA +>941 +AGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGC +>942 +GGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCC +>943 +TCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGG +>944 +ATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTG +>945 +CCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCC +>946 +AGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCA +>947 +AGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTG +>948 +TACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAA +>949 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>950 +ACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGAT +>951 +AACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGT +>952 +AGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGG +>953 +CTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGG +>954 +GAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGA +>955 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>956 +TGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGG +>957 +CAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCA +>958 +CAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCT +>959 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>960 +TCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAA +>961 +TGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAA +>962 +TTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTA +>963 +TTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCA +>964 +GGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATG +>965 +TGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCAT +>966 +AAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCAC +>967 +GACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCC +>968 +AAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTG +>969 +GTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCC +>970 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>971 +CTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGG +>972 +CCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGC +>973 +CCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCC +>974 +GGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGG +>975 +CAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCA +>976 +GCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCG +>977 +AAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCC +>978 +GTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCC +>979 +ACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCA +>980 +CGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCA +>981 +GCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTG +>982 +GGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTC +>983 +GCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTC +>984 +GGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGT +>985 +AGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGC +>986 +GATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAG +>987 +AGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTA +>988 +GGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTG +>989 +GGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTC +>990 +GCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGG +>991 +CCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCC +>992 +CACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACAC +>993 +TCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAG +>994 +GAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTC +>995 +CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC +>996 +GGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGG +>997 +TTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAG +>998 +CTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAAC +>999 +GCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCA +>1000 +TCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACAT diff --git a/example/reads/reads_2.fa b/example/reads/reads_2.fa new file mode 100644 index 0000000..b533b80 --- /dev/null +++ b/example/reads/reads_2.fa @@ -0,0 +1,2000 @@ +>1 +CCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGT +>2 +GCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTC +>3 +GAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGA +>4 +CGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGC +>5 +TTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTA +>6 +GAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGA +>7 +TGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCAT +>8 +TCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCA +>9 +CCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGA +>10 +CAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATG +>11 +TACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAA +>12 +TTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACAC +>13 +GAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGAT +>14 +CTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACAC +>15 +TCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTC +>16 +CCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGC +>17 +CTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTC +>18 +CGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGA +>19 +CTGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGG +>20 +GCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGG +>21 +ACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGAT +>22 +CATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTC +>23 +AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG +>24 +GCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCT +>25 +CTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATG +>26 +CCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGG +>27 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>28 +CCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTG +>29 +GCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCA +>30 +TCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAG +>31 +TTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACAC +>32 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>33 +GACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTG +>34 +GCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTG +>35 +TCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTT +>36 +CCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCT +>37 +CCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTG +>38 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>39 +AGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAG +>40 +GAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATG +>41 +CGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTA +>42 +ACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCAT +>43 +GGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCC +>44 +GGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATG +>45 +CTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGT +>46 +CTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGC +>47 +CCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCT +>48 +ATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGT +>49 +CGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGA +>50 +AGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAG +>51 +ATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTT +>52 +GGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGAC +>53 +AGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTG +>54 +ACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCA +>55 +GCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGT +>56 +GGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGT +>57 +AGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCA +>58 +GGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGA +>59 +GGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAG +>60 +AAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCAC +>61 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>62 +ATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGG +>63 +GGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTC +>64 +ACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTA +>65 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>66 +GCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACT +>67 +AGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTG +>68 +CCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCC +>69 +TGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTG +>70 +TCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCC +>71 +AGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTG +>72 +CCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAG +>73 +AGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGT +>74 +GCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGC +>75 +AACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGT +>76 +AACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGAT +>77 +TAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCA +>78 +GACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGA +>79 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>80 +GGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTG +>81 +CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC +>82 +GGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCC +>83 +CAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCC +>84 +CCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGT +>85 +GTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTG +>86 +GAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGG +>87 +CAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGA +>88 +GGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAG +>89 +GCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAA +>90 +CTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCG +>91 +GAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAG +>92 +CCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGG +>93 +TACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGT +>94 +AGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTT +>95 +GCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGA +>96 +TCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACC +>97 +GGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGG +>98 +CATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTG +>99 +GCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCA +>100 +CCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGT +>101 +AGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAG +>102 +CTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCG +>103 +GTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCA +>104 +CACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTT +>105 +GAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGA +>106 +ATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGT +>107 +AAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCA +>108 +TCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGG +>109 +CGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGA +>110 +ACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCA +>111 +CATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGT +>112 +ACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCC +>113 +TCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCG +>114 +GGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTA +>115 +ATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCT +>116 +CTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGA +>117 +AGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGG +>118 +GGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCC +>119 +TTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCAT +>120 +CCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTAC +>121 +GCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTC +>122 +TGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGG +>123 +GCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACA +>124 +GCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACT +>125 +GGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTC +>126 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>127 +ACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACC +>128 +TCTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACT +>129 +TTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACA +>130 +CCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGG +>131 +ACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGC +>132 +GTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGC +>133 +AAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTC +>134 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>135 +CAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGG +>136 +CCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCC +>137 +GTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACA +>138 +TGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTC +>139 +ATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGT +>140 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>141 +AGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGT +>142 +TCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCG +>143 +TGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTC +>144 +GGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTA +>145 +GGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTG +>146 +CCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTC +>147 +AGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCT +>148 +GGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGG +>149 +TCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTC +>150 +GCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCA +>151 +GCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCG +>152 +TCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCA +>153 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>154 +GGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTG +>155 +CAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGG +>156 +TCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAG +>157 +CTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTG +>158 +GAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCA +>159 +AGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAA +>160 +AGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGG +>161 +GGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGG +>162 +AGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGAC +>163 +GGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTG +>164 +TTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCG +>165 +TACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCG +>166 +CACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCC +>167 +TGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTT +>168 +AGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGG +>169 +GGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTG +>170 +AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG +>171 +AGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACC +>172 +GACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTG +>173 +TGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGA +>174 +GTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCA +>175 +TGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTC +>176 +TGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAA +>177 +CACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCA +>178 +GCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAG +>179 +TCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGC +>180 +GTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACA +>181 +CCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGA +>182 +TCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAG +>183 +TTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCAT +>184 +CGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCA +>185 +GATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAAC +>186 +ATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTT +>187 +GATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGC +>188 +GAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTG +>189 +GACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGA +>190 +TGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAG +>191 +GCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGA +>192 +CGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGA +>193 +TCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCC +>194 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>195 +GCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTC +>196 +AGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCT +>197 +CATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGT +>198 +TCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCC +>199 +CCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCC +>200 +TTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAG +>201 +AAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTC +>202 +GAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCA +>203 +AGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCA +>204 +TGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTG +>205 +TGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGC +>206 +GCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGA +>207 +AGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCT +>208 +TTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCAT +>209 +ACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGG +>210 +GAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGG +>211 +CACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGT +>212 +TTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCA +>213 +GCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTG +>214 +AGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGC +>215 +CAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCC +>216 +AGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGA +>217 +AGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCAT +>218 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>219 +GTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGA +>220 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>221 +TCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTT +>222 +GTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGC +>223 +TTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACA +>224 +GCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGC +>225 +GCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAG +>226 +AAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTC +>227 +ACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCC +>228 +GCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAA +>229 +TGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAAT +>230 +TGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGG +>231 +CCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCC +>232 +ACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTA +>233 +TCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAG +>234 +GAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGA +>235 +AGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAA +>236 +CGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAG +>237 +CTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTC +>238 +CCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCT +>239 +TGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAA +>240 +CCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCC +>241 +GGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAG +>242 +AGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGG +>243 +CCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTG +>244 +TGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAA +>245 +TTCTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGAC +>246 +AATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACT +>247 +CTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCC +>248 +GGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGG +>249 +GACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTG +>250 +AGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCC +>251 +CCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGC +>252 +GTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTC +>253 +CAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGG +>254 +GGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGT +>255 +TTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCC +>256 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>257 +TGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTC +>258 +TAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCA +>259 +GCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGA +>260 +CTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCT +>261 +CAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAG +>262 +CTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTC +>263 +AGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTT +>264 +GCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCC +>265 +CCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTT +>266 +CATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAG +>267 +GGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCC +>268 +TACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCG +>269 +ACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCC +>270 +GGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAG +>271 +CAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAG +>272 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>273 +ACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTG +>274 +CCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGAC +>275 +TTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCG +>276 +GTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTC +>277 +GTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACT +>278 +GGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAA +>279 +GGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGA +>280 +ACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCC +>281 +CAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCC +>282 +TTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAG +>283 +CGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAG +>284 +GTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGC +>285 +AAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGC +>286 +GAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCC +>287 +TCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTC +>288 +AAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGT +>289 +GCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTAC +>290 +GGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGC +>291 +CCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTG +>292 +CGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTG +>293 +TCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAG +>294 +CACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGG +>295 +AGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGT +>296 +GGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGC +>297 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>298 +TCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAG +>299 +CAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCT +>300 +TGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGG +>301 +AAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCT +>302 +AGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACC +>303 +GCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGG +>304 +CCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTAC +>305 +AGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGT +>306 +GCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGG +>307 +TGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTC +>308 +GTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAA +>309 +ACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATG +>310 +ACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGC +>311 +AGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTC +>312 +CCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGA +>313 +CAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATG +>314 +CGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGG +>315 +ACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGC +>316 +GAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGG +>317 +AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG +>318 +TCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAG +>319 +CCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCA +>320 +CTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAA +>321 +CCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCT +>322 +GGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGC +>323 +TTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCT +>324 +CTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCT +>325 +CTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCA +>326 +GCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGC +>327 +GAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCA +>328 +CCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTT +>329 +TGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTAC +>330 +AGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTT +>331 +TGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAA +>332 +CCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACA +>333 +GTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACA +>334 +CTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACG +>335 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>336 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>337 +CGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGG +>338 +GAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCC +>339 +CAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTC +>340 +GCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGG +>341 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>342 +CCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGC +>343 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>344 +GGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGA +>345 +CAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTC +>346 +GAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCA +>347 +GACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCC +>348 +GTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTT +>349 +CAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCT +>350 +TGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAA +>351 +CTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGG +>352 +AAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCG +>353 +GAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTG +>354 +TGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAAC +>355 +ATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGAC +>356 +GGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGC +>357 +TCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAA +>358 +ACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCAT +>359 +GCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCT +>360 +CTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCT +>361 +CACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGT +>362 +TTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGT +>363 +GCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACT +>364 +TTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGG +>365 +CCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCC +>366 +GCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGA +>367 +GCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCAT +>368 +GCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAG +>369 +AGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGG +>370 +CTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGA +>371 +GTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACT +>372 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>373 +AGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACC +>374 +ACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTT +>375 +CAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCA +>376 +GAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGAT +>377 +GCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCC +>378 +CCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCC +>379 +GCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGC +>380 +GTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGA +>381 +GTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTC +>382 +TTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCG +>383 +TGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACAC +>384 +GCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTG +>385 +TGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGA +>386 +TCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACAC +>387 +CCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGG +>388 +CCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGG +>389 +GTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTG +>390 +TCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTC +>391 +TTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGC +>392 +TGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAA +>393 +CTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTG +>394 +GCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCC +>395 +TGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGT +>396 +ACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCA +>397 +TCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCA +>398 +GACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAG +>399 +CGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCA +>400 +ACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTA +>401 +AGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCT +>402 +CTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCT +>403 +TGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTAC +>404 +TGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCT +>405 +GGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGAC +>406 +TGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGT +>407 +AAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCA +>408 +TCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGG +>409 +GGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGA +>410 +ACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGAT +>411 +ACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATC +>412 +AAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAG +>413 +CCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGA +>414 +CATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTG +>415 +TCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACC +>416 +GACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCG +>417 +TCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTC +>418 +CCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACA +>419 +CTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTG +>420 +TCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAG +>421 +TCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAG +>422 +GGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATG +>423 +CCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACA +>424 +ACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTG +>425 +CGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCA +>426 +TCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACAT +>427 +GCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACT +>428 +ACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCAC +>429 +CCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTC +>430 +GGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGC +>431 +GGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAA +>432 +GGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCC +>433 +GCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAG +>434 +CTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCT +>435 +CTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATG +>436 +GCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCC +>437 +GAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCA +>438 +GTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTC +>439 +AGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCG +>440 +ATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGT +>441 +ATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGC +>442 +AGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTG +>443 +ACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCA +>444 +CTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCA +>445 +AGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAA +>446 +CCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCC +>447 +GTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCA +>448 +CCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGC +>449 +ATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCT +>450 +GTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGT +>451 +CTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTC +>452 +AGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAG +>453 +TCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGC +>454 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>455 +GTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGC +>456 +TTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCT +>457 +CGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACT +>458 +ACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACC +>459 +AAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGT +>460 +CTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAA +>461 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>462 +TGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGT +>463 +AGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCT +>464 +TTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCC +>465 +GCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCC +>466 +GCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAG +>467 +TGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGG +>468 +CGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTG +>469 +GAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTT +>470 +CATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCC +>471 +AGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGC +>472 +TCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGG +>473 +AGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCAT +>474 +TCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTG +>475 +AAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTC +>476 +CCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGG +>477 +CAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGT +>478 +ACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGA +>479 +GAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGT +>480 +AGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCC +>481 +CGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACG +>482 +CTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGT +>483 +CTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTC +>484 +TCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAG +>485 +GAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTAC +>486 +AGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTG +>487 +CTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGA +>488 +GCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGA +>489 +GGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTG +>490 +GGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGC +>491 +GACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACAC +>492 +GCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGAC +>493 +GTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCC +>494 +CTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATC +>495 +CGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGA +>496 +GCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACG +>497 +GCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGA +>498 +GCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCCA +>499 +AGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTG +>500 +TGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCA +>501 +TGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGG +>502 +AGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGA +>503 +CTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCT +>504 +CCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCT +>505 +CCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTG +>506 +TCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCG +>507 +GGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAG +>508 +GGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGC +>509 +CGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGG +>510 +CATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTG +>511 +ACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCC +>512 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>513 +CCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTC +>514 +GCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTG +>515 +CACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGT +>516 +GGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGAC +>517 +CCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGG +>518 +GTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCT +>519 +TCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTT +>520 +AAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGAC +>521 +TGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTC +>522 +TTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCT +>523 +GAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCA +>524 +GAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCT +>525 +AGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGAC +>526 +ACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACC +>527 +AGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGG +>528 +GGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCC +>529 +CCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTC +>530 +GTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGC +>531 +GTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTT +>532 +GGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTG +>533 +GGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGA +>534 +CCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTC +>535 +TCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCC +>536 +GGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTC +>537 +AAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGAC +>538 +ACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATG +>539 +AGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACC +>540 +CTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTG +>541 +CATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCC +>542 +GAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTG +>543 +TTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACA +>544 +TCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCG +>545 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>546 +GACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCAT +>547 +CCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTC +>548 +AGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAG +>549 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>550 +CCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGC +>551 +GATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAAC +>552 +AAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCT +>553 +AGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTC +>554 +ATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGAC +>555 +TCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGC +>556 +CCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCC +>557 +CATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTAT +>558 +AAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACAT +>559 +CACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACAC +>560 +GCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCC +>561 +GGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACA +>562 +TTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACA +>563 +GTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTT +>564 +GCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACT +>565 +CTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTC +>566 +GATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAAC +>567 +ACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCC +>568 +ATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACA +>569 +TGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTT +>570 +CAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCA +>571 +CTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGA +>572 +GAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATG +>573 +GTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAA +>574 +TGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGC +>575 +AGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCT +>576 +CAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGG +>577 +CCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCAT +>578 +TTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGG +>579 +CTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGG +>580 +GCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACG +>581 +TCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAA +>582 +CCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCAC +>583 +GGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGAC +>584 +GTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGC +>585 +TACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGT +>586 +CTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTC +>587 +TTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCC +>588 +GAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGG +>589 +TGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACAC +>590 +AGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGT +>591 +GTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTG +>592 +TGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTC +>593 +ACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGAT +>594 +CACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGC +>595 +AGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGG +>596 +GCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTG +>597 +TGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGG +>598 +CGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAG +>599 +CTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCT +>600 +CAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACA +>601 +CAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAG +>602 +GAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGG +>603 +CCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCC +>604 +GGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAG +>605 +GAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCC +>606 +GAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTG +>607 +CTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTT +>608 +TTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAG +>609 +TGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAA +>610 +CTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACAC +>611 +GGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGC +>612 +AGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCT +>613 +GGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTC +>614 +GTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAA +>615 +AGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATT +>616 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>617 +CACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTT +>618 +CGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGA +>619 +CGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAG +>620 +GAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCT +>621 +CAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAG +>622 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>623 +CAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCA +>624 +GCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGT +>625 +TGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAAC +>626 +GGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGC +>627 +ACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTA +>628 +GAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTT +>629 +GGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGAC +>630 +CCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCC +>631 +GTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACA +>632 +CTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCC +>633 +GAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGC +>634 +CCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACA +>635 +CTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGC +>636 +CAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGG +>637 +CTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCT +>638 +TCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCC +>639 +GTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGC +>640 +AGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGG +>641 +AAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTG +>642 +CCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGT +>643 +CAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAG +>644 +AGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGT +>645 +GAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCC +>646 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>647 +AATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACT +>648 +TTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGT +>649 +CTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCC +>650 +GAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCA +>651 +GCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCT +>652 +CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA +>653 +GTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTC +>654 +GTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATA +>655 +AGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAG +>656 +AGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGG +>657 +TGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCA +>658 +AACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGT +>659 +GGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGT +>660 +CGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAG +>661 +ATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGT +>662 +CTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCG +>663 +TTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGC +>664 +GCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGA +>665 +CCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCC +>666 +AAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTT +>667 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>668 +GGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGC +>669 +ACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGA +>670 +TTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCG +>671 +GGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTG +>672 +TGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTT +>673 +CACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCC +>674 +ACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCC +>675 +AGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCG +>676 +GAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGA +>677 +AGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGC +>678 +GTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGC +>679 +TACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGA +>680 +AGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTG +>681 +TCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAG +>682 +AAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAG +>683 +AACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGT +>684 +GCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAA +>685 +CGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGA +>686 +ATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATG +>687 +GTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCT +>688 +CCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCA +>689 +TACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCG +>690 +ACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTT +>691 +AACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCAC +>692 +CATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCA +>693 +CCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGA +>694 +CTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGC +>695 +CCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCC +>696 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>697 +TGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGC +>698 +GGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAG +>699 +GGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAA +>700 +CGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGA +>701 +CGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGC +>702 +ACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGC +>703 +ACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCA +>704 +GGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAG +>705 +GCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGC +>706 +ATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTC +>707 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>708 +TGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTG +>709 +AGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCG +>710 +GACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCG +>711 +ACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTT +>712 +TGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGT +>713 +GGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGG +>714 +CCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCA +>715 +CTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGC +>716 +GGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGG +>717 +CCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTT +>718 +GGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGG +>719 +CCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCT +>720 +CCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAG +>721 +ACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCC +>722 +TTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAG +>723 +TGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATG +>724 +ACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCC +>725 +CCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGA +>726 +GGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCC +>727 +GGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTG +>728 +CCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGAC +>729 +AAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCC +>730 +ACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTT +>731 +AGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGAC +>732 +GTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGC +>733 +AGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGG +>734 +GACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCT +>735 +CTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACAC +>736 +CAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAG +>737 +GGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGA +>738 +CAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATG +>739 +CGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATC +>740 +GCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAG +>741 +ACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTG +>742 +GGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCC +>743 +TGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTC +>744 +CCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCG +>745 +CTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCG +>746 +GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA +>747 +GGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCC +>748 +AGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTC +>749 +CTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTT +>750 +CCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTG +>751 +TGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGA +>752 +TAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCG +>753 +CCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTG +>754 +TGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAG +>755 +CTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCG +>756 +GGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGG +>757 +GCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACA +>758 +TCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCC +>759 +TGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAG +>760 +ACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTG +>761 +GAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTAC +>762 +CGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATC +>763 +CCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGC +>764 +CCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGT +>765 +GAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGC +>766 +CCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCC +>767 +CGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACG +>768 +TCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCC +>769 +GTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGC +>770 +CCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGA +>771 +AGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGC +>772 +GGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGG +>773 +CTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCA +>774 +GCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGC +>775 +GAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCA +>776 +CAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGT +>777 +GTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAA +>778 +CAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACA +>779 +GGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGA +>780 +GCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCCCA +>781 +GCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACA +>782 +GGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTC +>783 +TCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCC +>784 +AAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCTCCA +>785 +ATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCC +>786 +ATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGG +>787 +GTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTT +>788 +AGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGG +>789 +TTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCT +>790 +TCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACC +>791 +GAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTAC +>792 +TTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGT +>793 +CCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCAT +>794 +TCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTA +>795 +AGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCG +>796 +AGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATA +>797 +CACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGC +>798 +ATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGAC +>799 +CTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCG +>800 +CCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCA +>801 +ACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGAT +>802 +CCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTAC +>803 +TCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAG +>804 +GGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGG +>805 +CCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATC +>806 +AGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCT +>807 +CAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGG +>808 +GTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCA +>809 +ACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTT +>810 +CCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCC +>811 +TACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGA +>812 +CCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGC +>813 +AGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACC +>814 +GGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCC +>815 +GTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCA +>816 +CTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGC +>817 +CCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGG +>818 +GCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCG +>819 +GGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAG +>820 +CGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGA +>821 +TTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCC +>822 +GCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAG +>823 +CCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTAC +>824 +TGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTG +>825 +CCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGC +>826 +GACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTG +>827 +TCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCT +>828 +GACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCG +>829 +TTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAGATCT +>830 +CCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCC +>831 +TGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGG +>832 +AGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGT +>833 +CATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCC +>834 +GGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGG +>835 +TGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGG +>836 +CTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGC +>837 +TTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCG +>838 +CCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCT +>839 +AGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGT +>840 +CAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGA +>841 +GCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGA +>842 +TTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTA +>843 +GAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGA +>844 +TCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGC +>845 +CCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCC +>846 +CAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTC +>847 +GGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGG +>848 +CACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGC +>849 +GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA +>850 +CTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCT +>851 +CCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCG +>852 +GGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGG +>853 +TCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCC +>854 +CCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTC +>855 +GAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCA +>856 +GGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAG +>857 +TGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGG +>858 +GTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGC +>859 +GGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTAT +>860 +TAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCG +>861 +AGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATA +>862 +GCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATAC +>863 +GCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTC +>864 +TAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCA +>865 +TGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGT +>866 +CAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGA +>867 +CTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTA +>868 +CAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTT +>869 +CCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGG +>870 +TGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTT +>871 +ATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACC +>872 +GTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCT +>873 +CGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACG +>874 +CACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCA +>875 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>876 +AACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGT +>877 +AGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATT +>878 +CTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTG +>879 +TTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCA +>880 +CACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGAT +>881 +TGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTG +>882 +TTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGG +>883 +CACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGC +>884 +AGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAG +>885 +AGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAA +>886 +CCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGG +>887 +GAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTAC +>888 +CCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCC +>889 +CACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGAT +>890 +AAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGA +>891 +TGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAG +>892 +CATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTAT +>893 +AGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAG +>894 +GGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGT +>895 +AGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGC +>896 +GGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGT +>897 +AAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAG +>898 +TTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACAC +>899 +AGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAA +>900 +GGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGG +>901 +CCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTC +>902 +TCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAG +>903 +CTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCT +>904 +GTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGA +>905 +AACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGT +>906 +CCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAG +>907 +GGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTAC +>908 +CCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGA +>909 +CAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGG +>910 +CACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTT +>911 +GGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGG +>912 +CGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGC +>913 +GCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCC +>914 +TTTCTGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGA +>915 +ATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCC +>916 +TCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGT +>917 +AAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGAC +>918 +CTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGT +>919 +GCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGC +>920 +GGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTG +>921 +TGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTC +>922 +GCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACT +>923 +CCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCT +>924 +CAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGA +>925 +TGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACA +>926 +AGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAA +>927 +GTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCA +>928 +GGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGG +>929 +GTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCA +>930 +GGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAG +>931 +AGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCAC +>932 +GCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATAC +>933 +AACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGT +>934 +AAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGAC +>935 +CACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGC +>936 +TCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCC +>937 +CAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTT +>938 +GTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCA +>939 +ATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTG +>940 +CCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGG +>941 +GGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGC +>942 +TGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGT +>943 +GGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCC +>944 +GAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTT +>945 +GACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCT +>946 +CCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAG +>947 +GATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGC +>948 +CAGTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGG +>949 +CCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAG +>950 +CCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCGCCGATGTTCAGGGACATGGAGCGCT +>951 +CCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCC +>952 +CGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGA +>953 +CTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCG +>954 +CAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCA +>955 +ATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCT +>956 +TCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGG +>957 +CGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAG +>958 +GTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAA +>959 +CAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAG +>960 +CTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACGTGCCGGTTCATGCTCCCCTTGGCCCCG +>961 +CACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCC +>962 +ACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCC +>963 +GAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGA +>964 +AGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCT +>965 +GTGGAGTAGATCTTCTCGCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGA +>966 +CCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGG +>967 +GCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATC +>968 +TGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGA +>969 +TCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCT +>970 +TGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCT +>971 +TGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACAC +>972 +GCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGC +>973 +AACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGT +>974 +CCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTG +>975 +CGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAG +>976 +AGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGG +>977 +CCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCC +>978 +TCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCT +>979 +CCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTGCAGCTCTGACCAAGTGGAGATCTTCTCCAGCCTGCTGCAGCG +>980 +CACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGC +>981 +TCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTG +>982 +CTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAAC +>983 +TGGCCTGGGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACA +>984 +GGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGG +>985 +CACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACAC +>986 +CAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATG +>987 +GCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGC +>988 +AAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAG +>989 +GTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACA +>990 +GCGAAGCACATTGCAGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAG +>991 +AACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGT +>992 +AGTGGAGATCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGC +>993 +GGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTGAGGGCCCTCTTCCTGGGGAGCACAGGGCCCCTGGTGTGTACAGTGTGTCATGGG +>994 +GGGCGTCTGTGTATCACGGTACTTCTGTAGACGGGGAACACATTTCAGTGAGCTGCTCCTGGAAGGGCAGGGAAGAGAGTCCATAAGGTGAACTTGGCCC +>995 +TGCTGAGATAAAGGAAGCAGACCCCCTGGCTGCCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTC +>996 +CCTCGGAAGCAAGTCAACCCAAACCCTGTCCCCCCGAAGTGACCCCCCACTACATCTGGATCGACTTCCTGGTGCAGCGGTTTGAGATCGCCAAGTACTG +>997 +GGGCCAAGTTCACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCC +>998 +GGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCAGCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTC +>999 +TCTTCTCCAGCCTGCTGCAGCGCTCCATGTCCCTGAACATCGGCGGGGCCAAGGGGAGCATGAACCGGCACGTGGCGGCCATCGGGCCCCGCTTCAAGTG +>1000 +TTCCCCGTCTACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGTGCTCCCCAGGAAGAGGGCCCTCACTTGAAGC diff --git a/example/reference/22_20-21M.fa b/example/reference/22_20-21M.fa new file mode 100644 index 0000000..1a0771f --- /dev/null +++ b/example/reference/22_20-21M.fa @@ -0,0 +1,16668 @@ +>22:20000001-21000000 +TGGGAAGGTGGGGAGGTGCTCACCTTGGGGAGCCCCCCTGAGTGCTCTGCAAGCTCTGGG +GTCACCTGCCTGGCCAAGGACCCAGTACCAGCCGCCTCAAAGCGGGGGAATGACCACGCC +CTTTATTGGGCCCTTTTCCCAGTGAGGATGGCCTGGGCCTACCCATGCCATGGGACCCCC +ACACTGGGTCTCCCCACCAAACTGTCCAGACCCGATGGCTGGCCATGGGGCTCTGTCAGC +CCCTGGCTACACCCCACTGATGCCCTAGTAAGCCCTGTGGTTCTGGCACGGTATCCATGG +TCCAACCAGAGGGCTGAGAGGTCTCACACTGGGGCATAAGCCTGGCCCAGGCCACACAGC +CAGATTGGCAAGCTACAGTCCTTTGGATAGCTGACGGCACAGGGCAGCTCCCATGGGTAC +ACACTGGGCCCAGAACTGGGATGGAGGATGCAGCCTGGGCTGGGTAGGCAATGAGGGGCC +CAGGTGAGCTCGCTCTGCACTCCCTGCAGTGTGGCCTCAGCAGGCCACCCCCTCCCCAAG +TCTCCTCGCTTCCTGCTCTATGAGCGCGAGGTGACACTGACTGTAGGTAGCTGAGAACAT +GCCCTGGCAACAGCCAATGCAGGCAGGTGAATGGAGTGCCCCGTGGCCAGTGGACAGGGA +AGGTCCATGCTGCTCAATGACAATGCTGTCCACTACAGCAAAACCGAGTGTTCTCCTAGG +CCTGCTGCCACCCTGGGCACATAGTGAGAACACGCCCACTTCTGCTGTGGACATTGAGGC +ACAGACCACACCTGGGAAGGCTTGGGAGGCCCCTGGGCACACACTTGAAGGACACTGCAC +TTTTGGGGCTACGCAGGCACAGGGCTAGTCCTTCACTGTCCCTGCTGAGCCTGTGTGTGG +TCACCCACCAGCTGGCCTTCAGGCTTCCTTCTGCCTGCACCAAGCATGTTGGGGGTACCG +AGGGGCCTTGCTTGGCTCCTTTCCAACTCCACGCCCTCAATAGGCGGCTTGGAGGCCGAG +CTCCGGTCATCCAAGCCAGGTGTCTGGGGAAGGGTCCTGGTCTGCCGCAGGAAGCTGGGT +GGAGCCGGTCTTGCCTGCTGTGGCGGTCCCAGCTGCCCTCTGGTGGCCATGCTCAGCTCC +CCGTTGCTCTGCCAGAGGCGGCAGCCCCTCAATCAGCAGGGGCAGTGGGAAGGGCCTGTG +CATAACTGGTTATGGAGTGGGGGGAACTCTGTGGCCCCAGGCACCCACCAGCTCTGGGTC +ATCTTCCCGACCTGAAACAGGCCAAGATATGAAGGCCCTGAGCCAGGAAAACCTACTAAG +GGATCCCTGATCCCAAGTCCCCTCAGAGTGACCCAAGACTTCATCTTGGGTTTTTCTGTT +TGTTTTTTTGTGGGTATTTTTTTTTCTTTTTTTGAGACGGAGTCTCACCCTGTCACCCAG +GCTGGAGTGCGATGGCACAATCTTGGCTCACTGCAACCTCTGCCTCCCAGGTTCAGGCAA +CCCTCCTGCCTCAGTCTCCCCAGCAGCTGGGATTACAGGCATATGCCACCAGGTCCAGCT +AATTTGTTTTGTATTTTTAGTAGAAACAGGGTTTCACCATGTTGGCCAGGCTGGTCTCAA +ACTCCTGACCTCAGGTGATCTGTCTGCCTGCCTCGGCCTCCCAAAGTGCTGGGATTACAG +GTACGAGCCACCGTGACCAGCCCATCCTGGTTGTTTTGTTTGTTTTTGTTTTTTGGAGAT +AGAGTCTCGCTCTATCACCCAGGCTGGAGTGCAGTGGTGTGATCTTGGCTCACTGCAACC +CTCACCTCCCCGGTTCAAGCGATTCTCCTGCCTCAGCCTCTTGAGTAGCTGGGACTACAG +GCGCATGCCACCATGCCCGACTAATTTTTGTATTTTTAGTAGAGACAGGGTTTCACCATG +TTGGCCAGGCTAGTGTCAAACTCCTGACCTCAGGTGATCCACCTGCCTTGGCCTCCCAAA +GTGTTGGGATTACAGGCATGAGCCACTGCGCCCGGCCTCATTCTGGTCTTAATTGAAGCT +GCTGACAAAAGAACAGACACCTCCCCATGACTAAGCCACCATCAGGGAAGTCCCCAGGAC +CCCCAAGGCCCAGCTGGTGCTCTGCAGTGCTGTCCCTGGACCCCCACCCTCCATTCCTGG +CCCTGTCTACAGAATGGGCCCTGACTCCCTATCCCAGCTCTACCCTGTCACTCCCTCTGC +CAGGGCCAGGCGGGGAGCACGACAGATGGGCTGGACAGAGGGTGGTGCCTGGCATCCGTG +TGCAGAGCTCCCTGCTCCACCCAGAGACCGGGGATCCTGCTGCTCCTGCACCTTCTGTCC +TTACTCAGGACAGCCTCATGCTCCCCCAGGCCAGACTCCTGGGGTGAAGGAGCACAGGGA +ACTCACCCTGAATCCCTGTGTAGCACAAACAGAAGGAGGGGTGCTACCCTACCCTCACAG +AGCCACAGAGATGCAGAGGGCCCCGGGACTGGGGGGAGACTACAGGGCCACCTCTGGAGG +GAGTGCCAGAGCAAACATGGGAGCCAAGCAGCCCAGATGTGGTGGGTGGGGAGACTCAAA +TTTAGCAGGATTGAGGGTCAGAACTTGTTCTCCCAGGAGGAACCTTGGTCAGAAGGTCCT +TGTGTTTATGCTGAAAAGCCTGACAGGGCAGCTCAGCCAAGAGCTGGGCAGGGGCTGGCT +TGGCTGTGCTCAACTACCCTCTCAGCTGGGACTTGAGTCCCTTAGCGAATGTTCTGTGCC +CAGTCCTCTGCTGGGCGCTGGTGGACCCCAGAATGGGGGTAGGGTGGGGACAGGGGACAG +CTGGGAGCAGACATTGCGGATAGGATGGGGCAAGACTGGGGGAAATGCCTTCCCAGACAC +GCTGCGGCTCACACTGTCGCCTGATCTAAGGCCTGGATCACCTGCTTAGGAGCTGACCGG +CCACTGGCATGGCACACCGGGCAAGAGAGCGCTGACTGCCCCCCTGCATTCAGCACCATC +CCAGCTCCAATAGAGTGAGTACAAGATAGGTAACACCTGCCTTGTTTGGACCAGACCTCT +AAACACCGCCCAGATCCCAGAGTAAAGGCAGATAAGGCAGTAGTTAAGAAGTAGGAAGAA +GTAAAGGCAGCTACCCCAGAGAAGCTAAGGTCGGGAGAGGTGGAGGCTCCCACTGCACCC +CCCTGGCCCATACCATAGGGGAGGTTTCCCCCACAGCAGCCTGGGTACTCACCTGAGGTT +ATTAGACAGCAGCATTAAGAGCCTACTCTAAAAAATACCCACGGGGCACCTTTCTTTTCC +TTATTTCTAAATATGCCTGGATGTAGGGAAAGGGAGCTGAAGTCCTTTAGTTCCATTTTA +AGTATGTTACATTACACATAGCTAAGAAACGGTGAAATATTGTAAGCAGCCAATATTTAA +TTATTTAAAAATTAAAATAGGCTGGAGCTCTCAGGCCACCTGCCCAGGGCGACTCCCCAG +CAAACCGAGCAGTCTCCCTCAGAGTGGAGATGACATGTCTCCGCACCGGCACCGAGGGGG +CGCAGGGCGGCGTGGGGAGGGGGACCCAGGCCGGGGGTCCGGGTGGCGCGCCCTCTCTCA +CCCCCGAGGCGGCAGGAGCAGCGCGGCGCGAGGACACCTCCGGGCCGTCGGTGCCCCTGA +GCTTCCCGGCGGCGCGCTGCCCCAGGAAAGTTCCCGGCCTGCCGCCCCTCGGGCTGTTGG +AAAGTTTCGGCGGCTGCAGGGCCCTGGCAGCTAGGCGCCAAGCGTCGCGCGGGGCGGGCA +CGGCTGCGGGGTCGGGCCGCGCTCGGCTGGAGTGCTCAGTGCAAGACGCCCGGACGGGTA +GGGTAGGGCCCCAAGGCCACGCACAAAGAGACCCGCCCCCGCCGGCCCGGGGTCTCGGAC +GCCGCAGAGCGCGCGGACAAGACGCGGGTGGGGCGGAGATTGGCTCCGACGTCCGGCCCA +GACCCTCGCCCGGATCTCGACTCCAGGGATAGGACCCTGTCCGGACCGCTGCCCGGAATG +CGTCCCATATCTGCAGCCCCGCCCCCAGTCCCGGCTCCGACCCGAGGCCCCAGCCCCGGG +TCCCACACCCCGCCCACTGGCTCAGGCTTACCTGGAGCGCAGCGTGGGCGGCCCCGCAGC +GCGGCCTCGGACCCCAGAAGGGCTTCCCCGGGTCCGTTGGCGCGCGGGGAGCGGCGTTCC +CAGGGCGCGGCGCGGTGCGGCGCGGCGCGGGTCGCAGTCCACGCGGCCGCAACTCGGACC +GGTGCGGGGGCCGCCCCCTCCCTCCAGGCCCAGCGCGCAACCCGAGACCCCGGGCCAGCC +CTCCCGCCCTCACGCGGCCCGTGCGCAAAGCGGACCGGGCCGGCGACGCGAATCTCCGCC +CCGCCCCATCTGACAGCAAATTTTCCCATTGGTCGAGAGACCCGGCGCGGCACGGCAACC +GGCGCCGATTGGGCGGATGCGCGGAGATGACGGCTTGCCATTGGGCCTCCGGGATGTCAG +TCCCGGCGGATGACCGGCCCCCTCGCGGAGGGGCCGCGGCCCCGCACCTGCCCGAACCTC +TGCGGCGGCGGTGGCAGGGTACGCGGGACCGCTCCCTCCCAGCCGACTTACGAGAACATC +CCCCGACCATCCAGCCCCGAGCAGGGACTGGCAGAGCCGGCGCCCCTTCCCCGGACTCTG +GCCGCGTAGCCTCCGCCACCACTCCCAGTTCACAGGTATCCTTCTTCAGCGCCTGCTACT +CGCTGCGCGCTGCGCGCCGCTCCCTCCTGTCGACATCGAATTGTATTCTTCACGCAAGCC +GCGAGAGAGAGTTCTGCTGCTATCCCCATTTTACAGTTGGGAAACAGCCTCAGAGAGGTT +CTCACTTGCTTGAACACAGTCGTCTGACCCTGGGGCCTGGGGGCTCTCTCATCCTCACGC +CCCTGGGTCCCCGCAGCGGGGAGACGATGGAGGTAGGAGCTGCAGTATTTCCGAGGGCAG +GAAGGGACCCCCTCGGTAAACCAGGGGCTCACCTCCCCCACCAGGCCTGGATGTAGAGAC +CTCTTGGGCTTGTCCCACCCTGCAGGCCCCCCATGGGGCCGCCCTTTCTTACCTCCTCCT +GGCATTCTCACAGCCCCACAGCTCTGCGTCTGGGGAGGCAGAGTTGTGCGTTTATGCCCG +CACCCCGTACTACTGTCCCATTTTCTTCACCCTACCTGGAGTCAGGAAGAAACGGTGCTT +CACTGCCTGTTGAGATTCACGTAGGTTACATTTCCTTGCCAGATTAAGAGCACCTGACAT +GAGTGGGACCATGACCCTCCGCCAGCTCTGCGTAACCTTGTGGTGTAGGGGGGAACCAGC +AGGGATGCTGCCCAGTGGGCTTTTCTAGGGGGAGGTCCTGAGATGACTTCTTAGCCAGTG +ACCCTGGCTCACGCATGCTGTCATCCTTTCCTGCCCTGGATGCACCTGGAGATGACCAGT +TCCTCGGCTCATTGCATTCTCCAAGGCCGCCTGGGGAACCAAACTGCCCACAACCATGCT +TATGAGTGGTGGAGGGGTGTGACCAGACACTCTTGTCTTATCCACCCATATTGGGAGTCC +AGTGTGTTCATCCAATCATTCCTTGGCCAGGACAAAGAAAATGAAATGGCCCAAGGCAAG +AACTCACTGCTGGGACCACCGCTGGGTCCATCTGTGTGCTGGCAGCATGGTGAATCGATC +CCAGCTGCCTTTCAGAGCCAGGCAGCTACTATCAATCGATTGGAGCTGGCACTTGACGTG +CCAATTGGCCTCCTGGCATAGGGTTGTTGCTTGCTGCTCTGGGAGGGCAGAATGAAGTAG +CTGTCCCTAGAATAGGGGCCCTCACAAACCAGGTAGCTGTCATCCTGTGGAGCAGCACCA +TGGTGACATTCTGGCTCAGGTGCTGTGTAGCTGAGGGGTCGTTTCCTCCATTTAGGAGTA +GACGTAATGAGTCCAGCTGTCCCCAGCCATCTCTTCAAGGCCATTGGACCCTGGTTCTGC +TGGAGCCCCTCTTCTCACAGTTACCTCATAGTCCTGCACCACCCCCTCCCCACACTTGCA +AGAGGGACTGGACAGACCTCTGTTGAAAGAGTGCAAAAGACAGAACCATACACCAAAATC +TGTGCAAGTGAGACTACCTCTCCTCTCATCACCACCCCTACCACCCATAGGGTTGCAGAG +ACCTGTCTGCCCTCGGCAGGCAGGATCATTAGCTGAGGTCAGAGGATGTCGGGGCAGCAC +CAATTCAAACAGGACTCAGGACCGCTGTCCAGCAGTCGGCCCATTAGGCTGCAGCCAGGG +GTCAGAAACACAACAAGGGAGGCTGGGCGCAGTGGCTCATGCCTGTAATCCCAGCACTTT +GGGAGGCCAAGGCAGGCAAATCACCAGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT +AGCAAAACCCCATCTCTACTAAAAGAATACAAAAAAAAGTAGCGGGGCATGGTGGTAGAC +GCCCATAGTCCCAGCTACTTGGGAGGCTGAGGCAGGAGATCGCTTGAACCTGGGAGGCGG +AGGTTGCAGTGAGCTGAAATTGCACCACCGCACGGCAGCCTAGGAGACAGAGCGAGACTC +CATCTCAAAAAAAAGGAAAAAAGAAAAAGATAAGAAAAACACAGCAAGGGAGACCACAGG +GACCAGTAGCCCAGTGTTCTCCCTCTCTCATCCTCTCACCTAGCTCCATGCGGACAGCTG +TGAGGCCCCCGGAGAAAGCCACAGAGAGAAAATGCTTTCAGCTGGGTGTCAAGAACTTTT +CAAGAGTGGCAGCTGTTGAAATCAAAAGAGTGGCCACAGAAGGTAGTGAGCTTCCTATCT +GAGTTTGTGTGCAATTAGAGGTTGGATGCCAGTGAGCCTGTTGCAGCCCCAAGATCCCAG +GGCTTAGGTGCCCATCCTAGACCCATTTCATCTGCCGTCACCTGCTTCCTGGCATCGCAT +GTCATCCAGACTGGAGTGTCAGTGGTGACAAAGAAGATCAGAGTGTCTGCTCTGGCTCTG +TCTAGCTGGGAAAAGTATGGCTGGGGGTGGGGATGGCCCAAGGCCACAAGGTATGACAGA +ACAGGATGCAAACCACCATCTGACATGTTACTGCATCCCTCTTTGTGGGCAAAGGGAAAC +CTTGGTCAACTCATGTCCAGCTTTGAGGTGCATGGCCTGGTGCTTTGGGGAAGCCCATTC +TCCAGGTGCTGCCATGAACCCCAGGGCACAGTCCATCACCCCCAAGCCCCAGATCCCACT +TGTCCACCACCACCACCTCTTGGCCCTATAGATTGCATAGGTTTGGCTGCTCAGAGGGAA +ATCACTGGTACCAGCCCCACATGATCCCACTGCTGGATGGTGGGAGAGACAACCATGTCT +GGCTGGGTCTGCGGCCCGCTGGCCATGAGTCCCTGGGCATCTGGAGTCCTTGTAAAAGGT +TCTGTTGGGTTCCAGGGGAAACACAGATAAGATAGCAAAAGTGTGGAGCACAACGGGCCC +GCATGTAGGTCCAGGTTAGACTCTTGCCGTTGCTGATTACCAGCCAGGCTCTTCCCATCC +CTGAGCCCCAGTTTTCTGCAGGGCATCAGGGCACCTAGGTCTTCAACACAGGTTGAAGCT +AATGTGGCCTCTCTTGCTTGCCACCTTTTTCAACTTCAACTGAATGACATAACTGCTCCA +AGTCTCAGTGTTTACATCTATAAAGTGGGATGAAAGAACTGCTGACCCAGACATTGGGTT +TAGAGTGCTTTACACATTATCATTATCCCTAATGTCTTTGTCATCCATGTCATAGTTTTT +TGAATGCTCACTTTGAGGCAGGGCCTGAGCCTCTGGGCTTTGACTCTCCACCTTTCTGCC +ACATAGGCCCAGGCACAGCCCAGAGGCTACAGGAGCAGCGGTCCCAGCTAATGCCTCTGT +CCTGTTGGGAGGGCCCCAGTCAGTGCCCACCTGCTCACCCTGCACAAGTCAAGCTGGGCC +AGCCCCTCGTCGCTGGGGCCTGGACCTGGATGTGAGCTCAAAGGCTACACTGGGGGGTGG +AAGTGGGGGAGGTGGTGGGTGTGCAGGGTATAGTGCTCAAATGCCTAGTCCAGGGTCTGG +GGGTACATACTGGGAATGGCAGGGACATCAGGGAGGAAAGAGCCGACCTGGAGGCCATAA +AGTGAAGGAAGGGATGACCAAGAGGAAGATGGCCAGGTCCAGAGGTGGGGTTGAGTGAAC +AGGATGGGGAGACCAGGACGCAGTCTGAGGGGGCCAGTCCGGAAGTGAGCATTCCTGTAC +CTCTTCCGAGAGAGGCCGCAGGGTGAGCAGGTGACAGATGGTGTCCATGAGGGCATGGAC +TCAGGGGCGGCTGCGACCTCCCATGGCGTCCCTGCAGGCAGGGAGCCGCGGAGTCCCCGA +AGGCCGCTGGATCAGGAAGCGCTCAGACGCCCGCGCAGCCCGAAGCTTTGGCGCAGCCCC +GGGGGCGGGGCGCCAGGAGGTGGCAGCCTCCGAGCGACAGCGCGCCCAGCCAACGGGACG +CCGGCATGCGGCGCGCCGCCCCGCCCCTCGCTGCGCGGCCCAATGGTGAACGCGCCGGCT +TCGGGCTGGGCGGTACTGGGCTGGCTGCGGTGGCGCGCGGGCGCGGCACCCGGAAGTCGG +CGGCGGTGGCGGAGGCGGTGAGTGCGCGGCTCCGGGGCTGGCCGACTCCGCTAGTGGCCC +GGCCGGCCTGGGCTCGGGGGCTCCGGGCTCTGGGCTCTGGGTGCGCGGACCGGGCCAGGC +TGCTTGAAGGTGGGTGGGCTGGCCGCACTTCCTCACCCTGCCTCAGTTTCCCCTTTCTGA +GGTATGGTATAGAATCAGGCGGCTGGGTCAGGGGCAACCACGTCGATCCCGGCCGACGAA +AATGCCCCGCGCGTTACTGGAAGGTGTTTTTGATAATCCCCGCTGGCACGGGATGCGAGG +GACTCTGGCAGGTGGGACCAGACTCGCTGCGGGGAGGCTGAGATCGGCAGGGTTGGGAGC +TGCGTGGTCCCTGCAGGGTGTGTGGGCTGCTCGGCCTTGGCCAGCATCAGGGACAGCTCT +GGCGCCCGGTCACTCTGCCCCCTACCCGCGGCCTGCTGCGGGCCAGCAGGGTGACAGCTA +ATGTGGGTGTGAGTAGATAGTAAGTGCTGGGTCATCCCTGCGCCTGGATGCGGCCTTCCT +GGGGAGGTTTGGGTAGTTAGATCCCCCACCCCCAACTCCAGAGCGTCAGAGGTAGGGGCT +GGCAGGGCTGCACTCAGGGCAGTCCTTGCCCCACCGCTGGGCTTTGTAGCAGCCTGGGCT +TTGCCCGTTTTCCTCTAGGAAGTGGGCACAGAGGGCTGTTTGCTGAGACCCCCACCTTCC +CTGCCCCTAGCACCTCTCCTGTGCTCCCTTGGCTTCCTGCTGGACCACAAGCTTTAGAGT +GAACCGTCTGCCCTTGGACAAGTCCCTGGGCCTCAGGCCCCCTTCCTCTTCAGGAATGTC +ACATGCCCTGCCCTGGCCAGGCCTGTTTGCACTGTCGTGTGGCTCTAGACCTGCTGACCA +CTGTTTTGCTGCCACTCTGGGCACAGTGCCCTCTTCCATGAGGCAGATGTGACGGCAGCT +ATAAGGGGGTAGCTGAGTAGCTCTTTGGAAGGCTTTCTCACGCTAGCTCATTTGCCTCTG +GGCAGCCTTTTGGGGCAAGCATTCATTGATCCAGTCCTGCTCATACAAGGAAAACTCAGG +CTAAGGTGGCAGATCGTGTTCCCAAGGTCATTCAGAGCCAGGGCCTGCTCCCAGTGCCTC +TACTACTCCTGGGCCACTCTCTTAGGAGTGTCCCTGTGTCTGTGTCCTGCGTCTGTGTTG +GGTGGGCTGGGAGCAGCTGGAGAGGGTGACCATGTTGTTAGATGGACACAGCAGAGCCTC +TGTTCCCACAGGATCCTAGTGCTCTGGTGGTCCAGGGTAGGGTGCCCTGGTGCCCCCACC +CCCTTTGACCCCTACACAGCTTTGTGTTACTTGCATGTCCTCAGACTGCAGGCCCCTCAG +ACCAAGCCCCTGCCTGCTGTGATGTGTGGTGGCCATAGCCCTTCCCTGAGCTAAGGTGAC +CAGCTGTCAGCTCTTCCTGGGCTGCCCAGCCTCTTGTGCTTCCTTGGTCTTCACTTGTGG +GCTGTCATTCTGATTACGTTTTGCAGTGTGTGGAATCACGTGCAGTGTCCTGGGAACTTG +ATCCTGTGCCCGGCTTCTGCGCCAGACGGCGAACTTGGAGGGCACCCCGGTGCCCACCCA +AGGGTGCTGCTTCTGAAAACACCCACAGGGATATGAGGGGCTTCTCAGGGACCCCAGAAG +GGGTCTGGAGAGAAATGGCCCGGGATAGGGAGGCTGGGAAGACTTCTCGAAGTAGGGCCA +TGCTTGTCATTGACACTCCAGATGCATGAGAAGCAGGGCCCATCCTTTGGTGACGTGTCA +GTCAGCACATGGCAGCAGCATGGCAGAGCCTGGCCTTTGTTGGCCCCTACCATAGGGCTT +GGGCTGTCTTGAAAACAAGCCTATCCCTACCATGAGGATGGGCTCCGTGAAAACAAGGTC +ACCCCAGAAAGACTGAGCTGCTTTTTGAGGTTATCACAGCTTTTTCCCCTTTTTCTCTCA +ACTTCCCTTTTAGACTGCAAAAATAGTTTATGCATGCTTAAAGATAAAAAAGGCTGGCCT +CCTTCTCCCAGCGGCTGCTCCCCTGGTGCACTTGCTGACATTTGGGGGTACATCCATTGA +GATCTTCAGTGCCATGCTAACTTGAAACTTGAAGTGCTTGCCTTCATCCTCTTTGCGGGC +ATGGTAGGAGTGCCCCCCTTTTTTTTTGTTTTTACTAACCACTCAGGCCGCAGGGGCCGC +TGCGAGGCTGGCCTGTCCCTGGCTTGTGAGGAAGCTGAGTGTTCCTCCCAGGAGGGCCTG +AGGATGGGGCCACCCTGTGTCCAGAGCTTGCTGTCTGCTCACGATGCCTCTTGTTTGTGC +TATTCCTTGGAACTGGGAAGAGACAGTGATCCTCTGGTGTGAGGCTGAAGAAATGCCCCG +GAAGCATTGTGAAGATCTGAGGAGAGAGTACCACTGTAGAAAATGTGTCATGATAGGCCA +AGCACGGTGGCTCACGCCTGTAATCCCAGCAGTTTGGGAGGCCGAGGCGGGTGGATCACG +AGGCCAGGAGATCGAGACCATCCTGGCTAACACGGTGAAACCCCGTCTCTACTAAAAATA +CAAAAAAATTAGCCGGACGTGGTGGTGGCAGGCACCTGTAGTCCCAGCTACTCGGGAGGC +TGAGGCAGGAGAATGGCGTGAACCCAGGAGGCAGAGCTTGCAGTGAGCCGGGATCGTGCC +ACTGCACTCCAGCCTGGGCAACAGAGCGAAACTCCATCTCAAAAAAAAAAAAAGAAAATG +TGTCATAATAAAATGCCATTTAGGCCCGGCACGGTGGCTCACACCTATAATCCCAGCACT +TTGGGAGGCCGAGACAGGTGGATCACCTGAGGTCAGGAGTTCGAGATCAGCCTGGCCAAC +ATAGTGAAACCCCGTCCCTACTAAAAACAAAATACAAAAATTTGCTGGGCATGGTGGCAG +GTGCCTGTAATCCCAACTACTCGAAAGGCTGAGGCAGGAGAATTGCTTGAACCCAGGAGG +CGAACGTTGCAGTGAGAGAGGTCACCCTCTCCAGCTGCCCCCAGCCCACCCAACAGGACC +ATTGCACTCCAGCCTGGGCGACAAGAGCAAAACTCCATCTAAAAATAAAAATAAAAAATG +CCATTTAATAGCCAGAGAGTGTAAACTGGTGAGCTCTTGCTGCGGAGATAGGAGGGAGCA +GGGCATTGCAGTGGACTGGAGACTCAGAGGGTTTCCTGACGTCAGGACTTTCTTCGCCCA +GGCCCCGTGAACAGCGACACTGTGTTCCCACGTGTGTTTACCTCCTCTGCTGACAGCCAC +CGGGAGCCCGCGTCACATGTCTGTGTCTGCCTTTGAAAAGAGCAACTCGTGCTTTCAAGC +TCTGCCCCTGGGGGCTGCCACCGCTGATGGAGTGGGGATTACAAGGGATGGGGATTGGGC +GCCCGGCTGCTCAGCCCTGCAGCACCAGCCCTTGTGGCCATTGAGGCCATTAAATGGGGG +CAGCAGACTGTAGGGCTTAGTCACCCTCTGTTCAGGGACTCACCATGTGCAGCCCCAATA +GGAGCCCGACTTGATGGCTACCCTCCCAAGTGTCTAGGTCCCCTTGACCCTGTGGTACTA +ATAGCTTGCCATTCCTCTGTCACCACTGCTTTCTGCTTAGCACACATCCCCTCTGCCCAT +GTGCTATGCTTGCCTTTTCGCTTGCCAAAGGGAAGTGGTTCCGCCAAAAGCGTGTGTCCC +ATCCCCTCTGGCCCCCAGGGTCTCCAGGTGTGGTGTTGCTGCGACAGCCCAGCTACACCC +CGTCCTATGCAGAGCTGTCTTGCACCAGGGCTGATTGGGTCTTCTCTTGCTTTCTGTGAA +CAAGTGACTCTTGGGTTCTTGCCCTTCCTTCCCTCTCTTCCCTGCCCATAGAAATGTCCC +AGCCCTGGCAGGGAAGGAGGGCAGGATCTGTACATTTTCTTTTTTTTTGCGTTTTGAGAC +AGAGTCTTGCTTTGTCACCTCAAAAGGCTGAGGCAGGAGAATCGCTTGAATACCGGAGGC +AGAGGTTGCAGTGACCTGAGATCGTGCCACTGCAACCTCTGCCTCTCAGGTTCAATGCGA +TTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCGTGCATCACCACGCCCTGCT +AATTTTTGTGTTTTTAGTAGAGACGGGGTTTCACCATTTTAGCCAGGCTGGTCTTGAACT +CCTGACCTCAGGTGATCCACCCACCTCGGCCTCCCAAAGTGTTGGGATTACAGGTGTGAG +CCACTGTGCCTGGCCAGTGCACTTTCTTTTGAGGGTAGACATTACTGTTCCCCGCCGGGA +AGCATGCTTACTGGGTGTGCACGCTTTCAGTGTCTGGCGTGACAGATTGTACAAAGTGAA +CCCAGCCACACAGCTACCGTCCATATCACACCACCACCAGCACCCAGATATCTCCCTCGT +GTCCCCCAGTGGCTGCCTAGACCAGGTGGCCCTGCCCTGCCTCCTGTCCCCATGGGCAGA +TGTTGCTTATCTCTGGCCTCTGCATGAAAGACCAAGCAGAGTGCTATCTTCTGGCTGAGA +CCTCCCTGCTGCCTCATCACCATGGAAAGGCACAGGCTGGCTTCTTTTCCAGGTTATGGA +CTTTCTTACTGTGTCACTTTGTGGACTTGGGCACCTGCAGAGTGCCTGGCATGGTGAGCA +GGAGTTGGGGCATGGCGTGATCTAGGCAGGGTTTGGAAGGTTCTTTGAATAGCCAAGGGG +GACAGTCTGGAGGGTGCCCTCCAGACACCTGAGAATGCATTGAAGCTAGGGTGACTACTG +CAGCATCAGAGGCCTGGTGACACATTTAAGGCCTCAAGGGGCCCATGTGACTAGAAGTCC +AGGATGTGGCTGAGGTGGGCCAGACTGGATGGCCAGCGGCCACCTAAGGACAATTGGCTG +TGCGTTTGGGAAGCATGGGTGGTCCCCACCTCACAGCAGTCGCACAGGCAGACAGTGGGC +AGATCCAAGAGCTTCACCAAGGCTGGGCGGGGTGGCTCACGCCTATAATCCCAGCATTTT +GGGAGGCTGAGGCGGGGGGATCATGAGGTCAGGAGTTCAAGACCAGCCTGACCAACATGG +TGAAAACCTGTCTTTACTAAAAATACAAAAATTAGCCAGGCATGGTGGCACGCACCTGTA +ATGACAGTTACTTGGGAGGCTGAGGCAGGAGAATTGCTTGAACCCAGCAGGTGGAGGTTG +TAGTGAGCTGAGATCGCGCCGTTGAACTCCAGCCTGGGCGACATAGCGAGACTTCGTCTC +AAAAAAAAAAAAAAAGAGCTTCACCACTGTGCAACCATACAAGGTAGATAAGAAAAAGGA +GTTCTCATTTTGGGACAGGGAGGGCCTTTAGCAGGACGGGACATGACTGCTGTACAGTAA +TGATGGGAAAATCCCATGTAATATAAGGCTATTTCTACTAGACAGCATCACAGGCAGAGC +TGAAAGGCAGGGGATGGCTAGGGAGAAAACAGTTGCAGGCCTGGGACAGGCACATGGTTG +CCCACATCACACCAGCTGCACTACGGGTCAGTGAGACAAAGGCCTAGCAGTCAGTACCCA +TGTTGGTGAATTGTTGGCAAGAACATACAGGAGGTCACAAGTTGCCCAGCCAGTGGGGGA +TGCCCATAAAACCCTGGCGGGAACATTTCCCACACTGCATACACCCTGGAGGCAGGTGAG +TGGCAACAGGTTCTGGTGCTAGACGTTAGCGGGGACTTGGCCAAGTCTGTTTATCTGAAA +GCGTCACCCATGGATGGAGCAATTCCACCTCTTGCGTCTATCCTAGGAATGTCCTCAGCT +GCTCTCCCACTGTTGTAAAGAAATACCTGGGACTGGGTCATTTATTAAAAAAAGAGGTTT +AATTGGCTCTCGGTTCTGCAAGGTGCACAGGAAGCATGATCCTGGCATTTGCTCAGCTTC +TGGGGAGGCCTCAGGAAACTTACAATCATGGCAGAAGGAAAAGCAGGAGCCAGCACTTCA +CACGGCTGGAGCAGGAGGAAGAGAGAGATGGGGGAGGTGCCACACACTTAAAACCAGATC +TCGTGAGAACTCTATCACTGTACAGCACCGGGGGGGATGGTGTTAAACTTTCATGAGAAT +TCTGCCCCCATGATCCAATCGCCTCCCACCAGGTCCTGCCTCCAACACTGGGAATTAAAT +TCAACGTGAGATTTGGTGGGGACACAGATCCAAGCCAAATCAGCCCATGTGCAGAGCATG +TGCTAGGGATGGTCGCTTGATGGGACGAAGACACCAGCCACAGCTGAGAGGCAGAGCAGC +GGGAAAGCTGGGCAGTGGTGAACCAGTGGGGACATGGCTCTGGTGGAGACAGACCTCATG +GCCAATCAGGGAGAACGGAGCAATGGGACCCTAGCGTGTTAACCCCACAGCATACATGTG +TCTGCTCACATGTGTGTGCAAGCAGGTTAAGAACACTCTGGCGCCACAGGCAGCCCTTGG +CTGAGGCTTTTTTTCCTTTTTTTTTTGAGACTCAGAGTCTTGCCTTGTCACCCAGGCTGG +AGTGCAGTGGTGCTATCATAGCTCACTGCAGCCTCAAACTCCTGGGCTCGAGCAATCCTT +CTGCCTCAGCCTCCTGAGTAGCTGGGACTACAGATGCATGTCACCATGCTCGGCTAATTT +TATTTTATTATTATTTATTTTATTTTACTTTACTTTTTTGAAACGGAGTCTCGCGCTGTC +ACCCAGGCTGGAGTGAAGTGGCACAATCTCGGTTCACGGCGCCCTCCGGCTCCTGGGTTC +AAGTGATCCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCCTGCACTACCATGC +CTGGCTAATTTTTGTATTTTTAGTAGAGACCGGGTTTCACCGTGTTGGCCAGGCTGGTCT +TGAATTCCTGACCTCAAATGATCTGCCCGCCTCAGCCTCCCAAAGTGCAGGGATTACAGC +CATGAGCCACTGCACCCTACCTTATTTTATTATATTATTAGTATTATATTGAGACAGAGT +CTCCCTCTGTTGCTGTGTTGCGGAAGTGCAGTGACATGATCATAATTCACTGCAGCCTTG +ATCTTCTAGGCTCAAGCCATCCTCCTACCTCAGCCTCCCAAGTAGTTGGGACCACAGGCA +TATGCCACTGCACCTGGCTAATTGTTTTTATTTGCTTTTTGTAGACAGGGACTTGCTGTG +TTTCACAGGCTGGACTTAAACTCCTGGCCTCAAACAATCCTCCTGCTTTAGCCTCCCAAA +GTGCTGGGATGACAGACATGAGCCCTGAAGGGATGGGGCTTTGGCCCGTTAAATGTCACT +GGAAATGTTTCCCTCCAGAATGTGCTCCTGGGTGACCTGAGCGATGGTATTAACAACTAT +GGGTCCCACCAGCCTCCAGAGCTGCCAGTCGTGGCTACAGGAGACTCAGCCTTAGGCTGG +GGCACAGAGAGGCTGAATAGAGGGTGAATGAACAGGCAGCGTATGGGAGGGACCAGCGTT +TCTTGGTATTATACAAAAGCTAGTGGAGGTGGTGCTGGTTGGTGTGGGGTGGGCGACTGG +CACGGTCAGATGCCTGATGCCTGTTGGCCTCCTCAGAAGGGGAGGCTGGCAGTAGTGGGT +TCTGGGACATGCAGGAGGGTGGCCTGGATTTGCCCTGCAGCACTGAGGTCTGCCTGTTCC +CCACTGGGTCCTCCATTTGAGGCCCTGTCAGCATGGCCCTCGTCCCCCTTGCTTCTTTTC +CCCATGGGCCTCTGCAAGGTTACTGCCCACCCTCCACCCCACCTACCTGCCTGTGGTGGG +CACTGAGAGCCAGGGAAGCAGATCCTCACTGCCAGGCAGCAGGCCATGTGCGCATCCATC +AGGGTGCCAGACCTTGTCCCCACGCAGCCCTGGCTGGGGTCACTGCTGCTGCTGCTCTCT +GCCTGTGGCTCTGGCCCATCTTTGCCCAGGCGTTCTGTCTGAATGGTTTTCTTGTCGTGC +CTTTTTTAGACACCGCATGGAGTGAGGTTTGGGGCTTGCCTCAACTGGAGTCTCATTCTT +CTTAGAGAGGGAGTTTAGCCCGTTTCCATTTGGCCTTAGGACAGAAGGCCCTGTTGGTTT +CTCTGAGAAGCCAGGGGAGGAGCCCTAGGCTGGAGAGGGGATTCTAGAGCGGGGTGGCTC +TCAGAAGCAGAAGGTGGGCAGAGAGGACGGTGCACGCTGGGAGAGTTCTCGAAAGCATCA +GCAGATGGGCCCAGAGTGCCTGGAAAGCTTCCGTCCTTCACAGACAGCGCCATGCTCTAA +GAATAACCCATGCCAAGTCCAGGCTTTCTTCCTGTTTTGCAGAATTACCAGGTTGTTAGG +CTAGGGGAACGTATGCTGGGATTCTGGGAAGAATTCCACCCGCACTGGTATTCTTAGAGG +ACGGGAAGCCCTTGGCTGCGGTGTGAAGAGGGCTCTCTCTTTCCATTCATATCTCATAGA +TCCTCTGGCCAGGCTTGGGGGTGTTGAGGGACTCCAGGAGTGTGGGGGGAACTTCCTCCC +TGGAAGAGGCCTGTGCTCTGTCCCTGCTGAGGCTGGTGGCATTTGCAGTCACATGGTGAG +CTCACAGTGACTGTCCCCCTCTTACCTCCCTGGCAGGGTTGGCAAAGACCACACCAAAGT +CCCAAGTGATTAGTTCCCCGGCCTCCCTGCACAGAGGCTGTGCATGTCCCCTGGGCATTC +ACTCTAGCTGTCTGGGCTGCAGGGAGGCAGGGTGCCTGGCCCAACTGGAGATGGCACTCT +ACTGGGGGTGGTTAAGTGTTGACCATCACAAAGGCGACCTCTTTTGTCACATCTGTGTGA +GAGGAGCTGGACTTTCTCAGATATGGATGAGCCTCACGACGCACATCCTTTCGTCCCTTG +CTTGTCTACCAAGTCCCTATGTGCTCCAGGAGGCAGTGGTACAGGCCAGCCGCTCCGTAT +GACCAGAGAACCAGTGCCTCACACTCCAGCGCATTTCCTTCCCAGGGTGCACCAGGACTC +TTGTAAAGAGGGCATTCTCGTGTAAGCAGTTGCTTTTTTTTTTTTTTTTTTTAATTTTTA +TTTTTTTGAGATGGAGTTTCCCTCTTGTCTCTTAGGCTGGAGTGCAATGGCACGATCTCG +GTTCACTGCAACCTCCACCTCGTGGGTTCAAGTGATTCTCCTGCCTCAGCCTCCTCAGTA +GCTAGGATTATAGGCACGCACCACCACACCTGGCTAATTTGTTTGTTTGTTTGTTTGTTT +GTTTTTTGAGATGGAGTCTTGCTCTGTTGCCCAGGCTGGAGGACAGTGGTACGATCTTGG +CTCACTACAACCTCTGCCTCCTGGGTTCAAGCAAGTCTTCTGTCTCAGCCTCCCAAGTAG +CTGGGACTACAGGCGCCCGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACAG +GGTTTCACCATATTGGCCAGGCTGGTCTCGAACTCTTGACCTCGTGATCCACCCACCTTG +GCCTCCCAAAGTGCTGGAATTACAGGCGTGATAATTTTTGTATTTTTAGTAAAGATGGGG +TTTCACCATGTTGGCCAGGCTGGCCTCAAACTCCTGACCTCAGGTGATCCACCCGCCTTG +GCTTCCCAAAGTGTTGGGATTACAGGCGTGAGCCACCTCGCCCAACCAGCAGTTGCTGTA +AAATTTTTTAAAAGGATGTCACTTATACTACCCAGTCATTAAGACTTCCTGAGGTGGAAA +GATCACTTCAGCCCATGAGTTTGAGAATAGCCTGGGCAACATAATGAGACCCCACCTCTC +CAAAAAAATTTAAAAATTAGGGCCAGGCGTGGTGGCTCATGTCTGTAATACCAGCACTTT +GGGAGGCCAAGGTGGGTGGGTCACAAGGTCAGGAGATCGAGACCATCCTGGCCAACATGG +TGAAACCCCATCTCTACTAAAAATACAAAAATTAGCTGGGTGTGATGGCACGCACCTCTA +GTCCCAGCTATTTGAGAGGCTGAGGCAGGAGAATCGCTTGAACCAGGGAGGAGGAGGCTG +CAGTGAGCTGAGATCGCGCCGCTGCACTCCAGCCTAGGTGACAGATCGAGACTCTGTCTC +AAAAAAAAAAAATTAGCCGGGTGTGGTGGTATGCAGCTGTAATCTTAGCTACTTGGGAGG +CTGAGGTGGGAGGATGGCTTGAGCCCAGGAGTTCGAGGCTGCAGTGAGCTATGATCACAC +GACTGCACCTGGGCGACAGAGTGGAGGTGATGTGCTTCCTCAAATAGCCATGAGAACAAC +GCTTCTTTTCTTGTCCTGGCTCAGGAACCTCACCACCATGCCACGTTGCCCTGCTGCGCT +GTGCTGGTGTCGTAGGTCGGTGGCAGGACATTTGCCCACCTCACAGGCTCTGCTTTCAGT +CTTGAAGTATGGCTCCTCTCGACTGCTGCCCACACGGCCTCCTGTTGTCAGCCTGGGCTA +CATATCTGGGCTCTTCCATCCCTGTGGGCCTGGTGAGGCCTGGCCATGTGCCTGTGTCAT +GCCAGTTGCTTTCAAGATGATGTTTCTAGTAGGACCACATGTGAACACAGTGACCACCAT +GGCCAGGAGGAAGCTGGCTGCCCATCACCAGCTTGCCCAGGGACCTCTTGCACCCTGGCG +GGGATCAGCAGATCCTGCTATGAGAGAGCAGAAGGCAGCATGCTGACTTCCAGGAGTGTC +CACAGCGTGGCTGGGCAGAGCAGAGCTACAAATGAACAGATCCAGTGCCGAGGCCATCCT +GACTCTCTCAGGGGCTGCCAGGCCGTGGGTGCAGGGTCCAGCAGGCCCACTTGATCCCAG +CATCCCACGTGTGCCTGCTCGGGGTGGCCAGCTCACTGCTTCTTCACCTCTAGCCCAACC +AGCAGGTGCCCCACCATGAGCCCCTCCAGGCTCACCTTGCCCATCCCTGCCATGTGACCT +GGGACTCTTGAGATGAGATCACAGCTGCAGAGCACACAGCACAGGGAGGAGCTCATCAGC +ATCTTCCCACCTGTGGTGCCCTGGCCCAGCCTCCTTCCGGTTGGGGTTGGACCCGCCCTG +GCAGCCAGGTTTTGCGTCACCTGCCCCACCCGCCCTGTAACCTACTTGCCCAACTGCTAT +CCCGGTGGCCGTGAGGCCAGTTGACAGAATGGAGAGGGGTAAGCATTTTCCGCCTGGAGA +GGATGGGCGTGTGGCCATCTGACTGCTTCTGCAAGCCTGGTGGTTGTGTGCAGGCTGCCC +TGGTGGTCTTAGCCCCTTGGGGCAGGCGGGGTCCTGTGCAGGATGCAGAGACTGGGCGTG +GCTTCCTGCAGATGTTCAGATGCTTCTGGGCTGTGGCCTCTGAGACCCAGGGCAAGGCTG +CTGACTGGACCCCAGACCCTCCTGCCTGCCTCTTCCTCCAGCTGCTCTTTGTGGTCTGGT +TCTGGCCGCCTGGGCCTCAGGGCCAACCCTGCATGGCTTTGACCACTCTGGCCTTCTTGG +ACTGCCAAGGACATGCTGAGAGTTGGTTGGGCTTGGCCCAAGTGCTGAGCCCAGGGCAGG +GGTGGGGACAGGCAGGGCGGAGCCTCACCTGGAAAGCCAGGCACGATTCTCCCTGGGACA +CCAACCCTCCTGTAGAGTTGGCCAATTCGGGCAACCTTGAGGGCGAGCTCTGTGTGGCAC +AAGAGATGCCCTGAGGAGCCCAGCCTCACCTGGTGTGATGGGACCTGTGGAAGTTGTGGG +AAGTGGTCCTGGCCACCCGTGTGCCCACATGCCCTGCGCCCAGATCAAGATATGGTGACC +AAAAGGACAAGGACTATATCCATGGCTCCCTCCCAGAGCCTGGCAAGTCAGCAGGCATGA +GAGGGTGTTGGAATGCTGTGGTGGGCCTGTGTGGGGACCTTGTAGGACCTAGGGAACCTG +CAGGGCTTGGCTTAGGGAGCACACAGGGGCCCAGGCAAAGGCAAGGTCACAGGTCGGGGG +AGGTGAAGCTGGCAGGGGGAGGGGGAGACCTGCTGGCTAGAGCTGGGTTGGGGGCCGGTG +GGCAGTGGGCCTGGCTCGAGCAGGGGGCGAGGGATTGGAGAGAAAGGCAGTTCCTGATGG +TCCCCTCCCCAGGGGCTGGCTTTCCTCTGGTCCTTCCCTCCCAATGACCGCGTCTTCGTC +GAGGCCACAGCCCTTGGCTCTGCGCCCACACCTCCAGTGCCAGGCTGTCCGGAGATCTGT +TTATGGCCTTCCCTTGGACCATGGAGCCCTCCCTGCCACTGGTGCCTGGAGGGCTGGTCT +GCTGCCCCTGCACCCTGGCCAGCTAGGATGGTGGGGTCCTGCAGCTGAACTGGGGGTGCC +TTTCTGCCTGTCTGTCCTACGTGTATCAGTGGCCAGAACTGCCCTCATCCATGGCCTTGC +CAGCAGCTGGGCGTGCAGCCCAGGGAGGGCTGAGGTCGGCTGAAGTTGATTGAGACCAAC +GGCCTTCTCTAACACCCCAGAGGAGCATGTCCCTGGTGAGCAGGCCTTGGGCAGCCCTGG +GCTCCAGGCCAGTGGGATTCCAGTAGAGACCAGCTGGCAGGGCTTCTCCAGTGACTGCAG +CCAGGGGTTCTCATGTGCAGGAAAGACCAGCTCCTCCAGAGTAAAGGGACTTGTGTCTTC +TGGCCACATGGTGAGTGCTGGGCCCACCCCATCAGTGGCACCTTGGGTGCACTCCCAAAG +CCCAGCGTGTTCCCCATCTTCCTGCACTGCATTCGGGATGGTTCTGCATCATCAGCTGCA +CCTGATTGCTCTTAAACCCACAGCTGAGCTTTAATGTGCAGTCACTGAAGCTTTCATTTC +TAAAATAGCTTCCTAAGAGTTCTTTTGGCCAGGCATGGTGGCTCATGCCTGTAATCCTAA +CACTTTGGGAGGCCGAGGTGGGTGGATCACCTGAGGTCAGGAGTTGGAGACCAGCCTGAC +CAACATGGAGAAACCCCGTCTCCACTAAAAATACAAAATTAGCTGGGCGTGGTGGCGCAT +GCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATTGCTTGAACTCGGGGGGCG +GAGGTTGCGGTGAGCCGAGATTATGCCAGCCAGCCTGGGCAACAGGAGCAAAAACAAAAC +AACAACAACAAAAAAAAACCGAGTTCCTTTTGCTGCTTTGTAAACCCAGTTTGCTCTTCA +TCACTTCCTTTGCCCTGCAGATGTTTCTGAGCTGTCTGTTTTCTTTCTGCCATCAGAGCA +TGGTTGGTTGATGATGCATGTACGGTTATCTTTCTGCTGGTTCTTGCTCATGGTGCTTCT +TTCATTATGTGGTTCTTTCTGACTATGTACTGCTTCTGGTCTTTGAAAAATGATTTTGAG +ACTTCTTTGAAGTATAGGATGAAGGTATCTTTCTCCAGAGAGAACTTCAGGCACAGGGGC +ACTACGAGTGCTGGAACCCCTTAAAACTGTGCTTGGCTTGTGGGTCCTTGTACCCCCAGT +GTGGACCTGGACGGCTGGCTGTGCCACAGCTTCTCAGAAACTTCCCTTCACTTATGTGCA +ATGTCCCCATAACCCCTGGGGGTGGCTGCGGCTGTAGTTCATCTCTCCCTAAGCATCGCT +CTTTGGAGTCCCAGCCTAACTTAGAGGAGAGTCTTCTGTTAGGTTCTTCATCCTGTGGGG +GTGACTGGACCTTGTCTTCTGTCTCCTTCGCCCCCGAGGCCACCAGAGTATGAGCCCCAG +TGTGTTCAGTGGGCAAACGCTCTCAGGCAGGATTGGCCACTGTGTTCTGCTGTCCTCTGT +GGGCCACGCTCTCCGAACTGTTGGCCAAATGCTGCATGAGCTCATCAGCTCCTGGCAATT +TTTAAGATGTTTTCATATTTCATCCAGCATCTTGAGTTGTTTTTACCAAAAGGATTGCCC +CTAGTAGCCTGCCCACCCTCGGATGATGGCCCCCTGTGGGCGCTTCCAGGGCACCCGGCA +AGGGGACCCAACCCACTTCCAGCCCCACAGTCTGCTTCCCACAGGGCCCCCTTGCAACAA +CACACCCTTTAGCTTCCCATCCTATGCAGAGTGGTGGCCAGCAGACCATCTCAAATGGCT +GCCCATCCCCCTGACCCAGTGCGTCTGCACGTGGCGCTTATTGCTATCCCAATACTTCAA +CTGCACAGCCACCAGCTCCTCACTGGAGCAGATGGTCCCCAATGGCCATCCCTAATGCCC +GTGCCTATGGAGGCACATACACTGAGCCCTCTTCACCTCCGTCCCCACTCATTAGACTTT +TCTCAGAGGAATCTTTTTGGGTCTCTTCAGTATTTGAACAGCTTCTTGGCTGTCCCATGT +CCCAGCTGTGAGCACTGGCTCTGCCCTGGAGCCGTGTCACTAAATCATTGCACATGTGCA +CATTTCAGGGAACTTGGGTGTCACCCTTGGGTGGCCTCGGAATCTAATCTCCGTTCTGCA +CTCGTTTGCATTGTGGAAAACTGCCTGCTCTGGGCCCCAGAGGTCCCTGGGTGGGGACGA +GGTGTATGCTAAGTGTGCAGTCACCCAGCGTGTCCCCGGCACGTGTCCATGCCAGCTGCT +GTGGGTGTGTGGGGCCTTCGGGTCCTGTGGGATGGCGAGTGTGTGTGCTGAGCAGGACCT +GTAGGGCCTGCATCCCAGGTGAGTGGGCCATGCTGTTGGAGGCGGAGGCAGGGCTGCCCC +CACTGGTGGCGTGTGGGGTGGGTTTGGTGCTGTTGCAGGGGAGGAGATGTGCATGTGGGG +GACAGTCTTGAAGGAAGAATGTATACAGTGGTCTATTTCCAAGACAAAGTGTCTTAAATT +GGCTTAGCTCAGCAAACTACAGAAGAAACAGGATATACTAGGCCACCCTGCTTGGATAGC +TGATGTGTGCTTGTCGGCCTCCACTTTCCCCGCACTTAGTTGCCTTCACCCGAACCAAAG +AAGTTCAGTCTAAGCTGAAAGTTTACTAGCCTGCAAAATAGCTCATTTTGTCTGTTCTTA +TCAGCCTGCCTGCTACTTAGGTCGTAAGTTAAATACTTAAAAAGTCCCTGAGCTAACTAG +GACTGCAATGCATTGTGGGCTGCAACAAAATACAGCAAGACAAGCCCCCAAAAAAACACC +TGAAGCCCCTACCCAACAATTAATAGGCGACGTCCGGGAAAATTGTGACCCCACAGTACT +CGGCCTATGAGGAACTGGGGGAGGGACCTGCGTACTAGGGGATAAATTGCTTGTCGAAAC +TGTGCTGGGTGTGCCTGTCTGACACCTGATCTTGCAAGACTGTCATTAAAAGTCTCACTT +TCGCTGTTCTCTGGGTCTGAGTTCATTCTTTAGATTTGGATGGGTAAGTTTGTTTCTCAC +AGTGTGGCTCCTGCCCTCACTTCTGCTGCCCCCCGGGGACCCCCTCGGCACCCCAGCTCG +GTGTGTCCAGGCCTTAAGACTACCATGGTGCTGATGGGATGCTTCTGTTCAGGGCTGGTG +TTGCAGGTGGTGGAGAGACAGTCTGGCCAGTGCCAATGAGTGCATGGGTTTGGGAGTTGT +TTGTGTGGCACCGGCCAAGAGTGTGGTGTCCAGTTCCCCCACACCCAGCAAGTAGTACAG +ACACCACAGAGGTGGTTCTCTCTGTTCTGGCCTGTTGCAGGTTCGGAGGGCAGCCCTGAG +TGTCTGCCATCCGCTCAACTCAGTGTTTTCCTTTTCCCGCAGACCTCGCGACCTGTGTCA +GCAGAGCCGCCCTGCACCACCATGTGCATCATCTTCTTTAAGTTTGATCCTCGCCCTGTT +TCCAAAAACGCGTACAGGTAACCCCCTCGCTCTGCATCTGCTGCGCCCTGCAGGGTCCTG +GGTGCCCAGCCAGTTCTCATGCCACCCAAGCTGCTGTGTGCAGGAAGGTGTGTGGGCCAG +GACGGGGCTGCACAGGCCTGGCACTGCCCTCCAGGACAGGGTCACTCAGTGTGGGATGCT +GTCAGAATGCCTCTCGGGGCGGGGACTCCAGTCAATGTACAAAGACGTGAAGACTCAGCC +ACAGAAGGCAGCCACAGGTAGGACAGAGGAGTGACATGGGTCCAGGTGGGCTGCAGTTCT +ATGGGCTTTGAGGAGGGTCGGGCGGCAGAACTGGGACAACGGCGTCAGTGAGTGAGAGCC +AGCTTGGGCTGGCGGGTCACAGCTGCTGGTGAGAAGTCAAAGTGGCGGCCAGGCTAGGGG +TCTGTGGGTGGGTCCTGAGCTGAGGAAAAAGAACCTGGGGAAGAGGGGACGCTGAGGACC +AGCCAGAGGAGTCAGGAAATCGAGGCCAGAAGCCACCCCTGACCCTGGACTCAGGACGGC +CACACCTCCATTCCCCAGGACACCCCAGCATTTATCCACACAGAGAACGAGGCAGAGATA +TAACCCACATCTAAAATGAAACGTGTAACCACTCTCTAATGCAACTGCTCGGGAAGTTTT +CATCATTTTAAAATCTGTACCAGAAATGATTTGAACCATTTCAAGAGGGTCTCAGATTTG +AGTCACTGCAAAGTTGCATAGACACCATGCTGCTTGACTTCAAGGCTGAGTGAAGTCATT +TCAGGCCAAGGAATCAGGAAGGAAGGGTGTCTGGTGTTTTCCCTTTTTGCAGTTGGGTGA +GTGGCAGGTCCCAGCAGCAGACAGCATGCTGCAGGGAAGGTGGAAGAAATGTTAGGAAAG +AACTATTGACTGCTACAGGGACTGGAGTAGTGTTGGGCTGGCTAGTGAGTGAACAGAACT +CTAAAGAATGTAGGGGCTGGCCGAGCACGGTGGCTCACGCCTGTAATCCCAGCACTTTGG +GAGGCCAAGGTGGGCGGATCACAAGGTCAGGAGATCCAGACCATCCTGGATAACACATCT +CTACTAAAAACACACAAAAAAATTAGCTGGGCATGGGGGTGGGCGCCTGTAGTCCCAGCC +ACTTGGGAGGCTGAGACAAGAGAATGGCGTGAACCTGGGAGGCAGAGCTTGCAGTGAGCC +GAGATTGCGCCACTGCACTCCAGCATGGGCAACAGAGCGAGACTGCATCTCAAAAAAAAG +ATGAAGGTAAAATAAGGTCATGTGGGTAGGCCCTAATCAATGTGATGGGTGACTCAGATA +CGCACAGGGGAAGCTGGTGTGTATACAGAGATAGAAGCAGTCGTCTGCATACCGAGAAGA +CCCTCAAAAGGAGCCAGCCCTGCTGACGCCTTGATCTTGGATCTCCAGCATCCAATGCTG +CGAGACAATAGTGTCTGTTGTTGCAGCCGCCTGGTCTGTGGTGCTTAGTTACGGCAGCCC +CAGGAAACTAGCACGCTGAGGAGAGCCAGCCAGCTCTGTATGCGTTTCAGGGCTGCCTCC +TGCAGGCTGCTGAAGAGACTCAACCCACCCCGAGTGCTCCCATCTCTGGAAAGGAAGCTT +GATGGCTGGCCTGCGGGTGCTGGTCAGTGCCACCCAGCCCCTTGGGTGGAGAGGAGGAGG +GTTGACATGGGCCCCTCTTGCTTTCACTCAGAACCCGTGTGTTGCTGCCAGGACCTGTCC +TGCGGGTCCTGCCATTCCAGTTGGCCTCGGGATTTCTCTGGACTATTTTCCGAAGCCCTA +AGCCAAAGACGAAATGTGCCACCTCTGGGTGACTGAGCAAATGTGCGCTGTGTTTTCCTG +ACTTCATGGGAGGGTGTGAGACACTTCTGGTGGCTGCTTCTGCTCTGCCTGTGGGGTGTC +CAGCCAGGGGAAGGGCACGCTGCAGGCTGGGAGCACAGACACTTCTATGGAGCCCCTGAC +AGCACCTCTGCAGCACTTTGGGAGGCCTCGTACAGGTACCCAGCTAGGCTGGGCTGGACT +CCTCACCTGTGGACTGGAGTAAAAAGTAGGGTGCTTTAGGCCACTATGTTTTTTTTTTTT +ATTATTATTATTATTATTTTAGAGACAGGATCTTGCTCTGTTGCCCAGGCTGGAGTACAG +TGGTATGATCATAGCTTACTGCAGCCTCAAACTCGCCGGCTCAAGCGATCCTCCCACTTC +AGCATGCCTAAGTAACTGGGACTACAACACCATGCCCGGCTAATTTTTTTTTTTTTGGTA +GAGACAAGTTCTCACTATGTTGTCCAGGGTGGTCTCGAACTCCTGGGCCCAAGTGATCCT +CCTGCCTCAGCCTCCCAAAATGCTGGGATTACATGCGTGAGCCACCATGCCCGGCCTCGG +CCACTGTATTTGGTAATTTGATACCCATCACGGAAAACCAAGACCCTGCAGCAAGATAAC +ACAATCACTTCATGATGTCACCCTATCTCTTTCAAAACTGCCTGTTTACAGCCGGGTGCG +GTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCTGAGGTGGGTGGATCACTTGAGGT +CAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCATCTCTACTAAAAATACAAA +AATTAGCCTGGCATGGTGGCGCACACCTGTAATCCCAGCTATTAGGGAGGCTAAGGCAGG +AGAATTGCTTGAGCCTGGGAGGCAGAGGTTACAGGGAACTGAGATAGCGCCACTGCACTC +CAGCCTGGATGACAGAGTGAGACTCCATCTTAAAAAAAAGAAAAAACGAAAAAAAACCTG +CCTGTTTACAGCCCCACGTGATGCCACTTGCTGGCTTCAGCCTAGAGTGGCTGCAGGACA +AGCTGTTACTCCATGGGACAGCTTCCATGGGGTCACCACTGAGGGTTTGATCACTGGATC +TCAGGCCAGAGTACCTCCTATCTGTCACCAAACTGTCCCCCAGACAGTGCACACACTCAC +CCCCCGGCAGAACACACTCACCCCCCGAGATGATGCACATACCCCCCGGACAGTACACGC +ACTCACCCTGCCTAGCAGCGTGGGTGTCAGGTGGTGATGGATAATTAGTGGTTTCAGTTA +TTGGAACAAAATAAAGCCGAGGTGACTTGCCATCCTCAGGGACCTCACCGTGGTGGGTGC +ATCCCTGTCTCTCTGGACGTGGGGCGCAGATAGGCTTCTACCCATGTGCAGCCCCACCAG +TGATGACTGAGAGAGCTACTTCCTCCTCCCTTTGGGGCTTGATCTGGGTGCTCAGCATGC +TGGCTTGTCCCTGAATTATGTATTCAATGAAATCCCTGGCAAACCACCAGCAATTCAGCT +AAACATGACTGCTGGAACAAAAATAACCTGGCAATTAATGTTCCTGAGTTATTAGGCAAA +CATATATAATTGCTCCTTGTTTAAAAACAGACAGCTGAACATCTTAGGACAAAAGTCCAT +GCTCAGTCAGCTTTTCTTCCTACTTTTCTCCCCTTTATTTTCCCTTTGTAAGAGCATTAT +GTCAGAATCAGCACCCGAAGCCAACAGCCCCAGCCTGGTTTGGGGCTGGACTGGGATGAG +GTGTCCCTGGCTCCCCCGACCCCTGTTCACCTGCAGGGCTGTGGGACGTGGAAGCAGAGG +AGGAAGGTATTTAAGAGAGAATGCTGAGCAGAACCACATGGAGCTTGACCCCACCCATAG +GGTGGAGGAGCTGTCATCCCAGACCCTGGCACATCCCCACCATAGCACTCAGGGACTGCG +GTGTTCCCCCTTCTCCTGCCCGCTGGCCAGGACACAACCAATGGGCACCTACAGGACTGG +CCCATCCAGGTCTGGGGCAAGTGCACTGCCTTCTACTAGCACTGTCCAGCCCAGGGAAGG +TGGGCTCTCCTGCCATCCCTGCTGCAGAGGTTGGGGGGCACTTCTGCCCAGAAGGGACAT +GGAGACTTGGGCTGGGTCTGGGTTGAAACATGGCAGTTAGAGGTACAAAGGCTGAGGCTC +ATCAGGGACAGAGACCACCTCCCCCTACCCCAGGCAGCACATCCCTGAGACCTGGTGCAG +CCCTGGGGCCAGCTGGGTGTCAGACCAGGCTGAATGGGGCACCCTGGAGGTGGTAAGGCT +TCCATAGCAGACCCCAAGGGCTCTAGGGCATGGCACAGTCCCTGGCAATGACCAAAAGCA +TTTCCCCAGTTCTGCTGGCAAGAAGCTTCAGGGGCAGGCACTGAGTGGGGGGCACACATG +TGCACACAGGTGTGAATGCCTCCAAGGGCATGAATGGTGGGTGCTAGCACCATGTACTTT +TTTGTTTGAAATGGAGTTTCGTTCTGTCGCCCAGGCTAGAGTGCAGTGGCACGATCTCAG +CTCCCTGCAACCTCCGCCTCCCGGGTTCAAGCAATTCTCTGCCTCAACCTCTCGAGCAGC +TGGGATTACAGGCGCCCGCCACCACACCCGGCTAATTTTTTTTTTTTTTTTTTGAGACGG +AGTCTTGCTCTGTCACTCAGGCTGGAGTACAGTAGCATGATCTCGGCTCACTGCAAACTC +TGCCTCCCGGGTTCACACCATTGTCCTGCCTCAGCCTCCCGAGTAGCTGGGACTACAGGC +GCCCGCCACCACACCTGGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTTTTACCGTGT +TAGCCAGGATGGTCTCGATCTCTTGACCTCGTGATCCTCCCACCTTGGCCTCTCAAAGTG +CTGGGATTACAGGCGTGAGCCACCGGGCCCGGCCTAATTTTTGTATTTTTAATAGAGATG +GGGTTTCACCATCTTGGCCAGGCTGGTCTTGAACTCCTGACCTCATGATCCACCCACCTC +GGCCTCGCAAAATGCTGGGATTACAGGCATGAGCCACCGTACCCAGCTGTGAGCACCACT +TTCACTCCCAATTTTATGAATGTCTGTTATTTCACATTTAATCAGGAGCAAATGTTGTTT +TATGAAATTGATGTGCAATGATCAATATGGAAATTATTTTTAAACACTTGTCGGGCTCTC +ACCACTGCAACTTGGTTTCAGACTCAGATTGTGATGGCAGGACAGCTGAGCTCTGCTCCT +TGGAGCTGCCTCTCCGGCACAAGTGCTCAGGGGGTCTTCAGCCATCACTTTTTTTTTTTT +TTTAGAGACAGGGCTTCTCTGTTCCCCAGGTTGGAGTGCAATGGTGCAGTCACAGTTCAC +TGCAGCCTCAAACTCCTGGGCTCAAATGATCCTGCTGCCTCAGCCTCCCCAGTAGTTGGG +AATACAGGCATGCACCACCACACCTGACTAATTTTTGTATTTTTTTTTTGTAGATATGGG +GTCTTACTTTCTTGCCCAAGCTGGTCTCAAAACTCCTAGCCTCAAGTGATCCTCCCACTT +TGGCCTCCCAAACTGCTGGGATTACAGGTGTCATCCACTGTGCCTGGCCCAGCCATCGCT +TCTTAGACCCTCAGGTCTAATGGACATTGCAGGAACTGACCCCTTCCACTCAGTCACTGC +TGTGTCCTTATTTGTTTTCTTCTAATGTCCAAGCTGGGACTTGAAAGTCAGTTTTCTTTC +CTCAAGACCAGGGCTCTTAAAGTTTAGATGTCTCTCCTAATTCCAAAAGAAATATTTGTT +TGATTAGGCTGGATGTGGTGGCTCACACCTGTAATCCTCCGCCTCGGAGGCCGAGGCGGG +TAGATCATTTGAGGTCAGGAGTTCAAGACCAGCTTGGCCAACATGGTGAAACCCCATCTC +TACTAAAAATACAAAAAATTAGCTGGGTGTGGTGGCGGGTGCCTGTAATCCCAGCTACTC +AGGAGGCTGAGGCGGGAGAATAGCTTGAACCCGGGAGGCGGGAGTTGCAGTGAGCCGATG +TCACGCCACTGCACTCTAGCCTGGGTGACACAGAGAGACTCCATCTCAAAAAATAAAAAT +AAATAAAAATGGAAATATTTGTTTGATTCATAATGCAAAAAAACTAGTAAAACAGTGAAG +TTCCCATCCACTCCCAACCAACCCGAGAAATTAACTCCAAAACACACAGAATGGAGCAGC +CCTCAGAGGCCCACATGCTGTGCCATTCAATCTGTATCCTTGAGCTCACGCTTCCAAGAG +CCCACGGGTTTGTTGTGGGTGTTCCCAGGGCTGGGGACAGATGGACAGAAGGAGGAACAG +CCCCCCACCCTCCAGCCTGGGCTCCCGGCATGGAGCCCAGGCTCCATGGTGCCCCTAAGG +GCCTGGCAGACCCGTCTCCCGCCATTGAATGGTGTGGATGTGTGTCCCTGCCTAGCATCC +TCCTGTTTCCCGTGCGGTCCCAGCTGCAGGCTCCCGAGAGCTCACCTGGAGCCACGGTGC +TCCTTCCTCCAGTGTGGGTGCAGCAGGACTGCCGGCTTCCTGCCCTCTCTGAGACTGGCC +CTTGTTGCCACTGAGGCCAGTTTTGTGTGTGAAAAGAGAAAAAGACTTGGCTCGCTCGTT +TCCATCTGAAGCCATCAGTGATGCTTTCCTCTTGCAGGCTCATCTTGGCAGCCAACAGGG +ATGAATTCTACAGCCGACCCTCCAAGTTAGCTGACTTCTGGGGGAACAACAACGAGATCC +TCAGTGGTGAGTCTTCCTGCGTGCTCAGCGGTGGCTGCGCCTTGTTGCTTCCCTAGCCCC +TGCGTGGCCCGAGTGACCCTAACTGAGTGGTGCTGCTTCCAAGTGTGATGGCGGGGTGTA +GAGGTGGAACTGATGGGGCTCGTGGTCGGGGCCAGCCCCAGCACCGGGCATTGCCAGAGC +TGCCCACCCAGCACTGTCTGCGTGGCTTCCTGTGCCATGCGTCTGCATGGGGGCCCCATC +ATGTGAAAGCATCAGTTGGTTTTATATGGATCCCTCCTTTTTGCTGAGGGCATGTGGGTG +GATTTGTGTGATGTACAGATCCACACTCAGTCACTTTGTGAAGCAACCCAGTCATATGAG +TGTGTGCATGCGTGTGTATGCGTGCGTGTGTGTGCCTGTGTTTGTGTTTCTGTTTGTATA +TGAGCACCCTTGCTTCAGGGATGGTGGGGCTGAGTTTGGGAAGCTGGTGGTGCTGAAGCC +CCGTCACCTGCACCATGCCTGTGTTGCATTAGGTGTACTTATAGGGCAGAAGTAGGGGTG +AGAACCAGGTCCTCCCCACCAAAGATACCAGCCTCATTGAAGTCCTGTTGGACAGGAACC +AGTTCCTGCCCATGGGGTGGTGGGAGTCTACCTGGAAGGTGCGCATAGATGGCTGGTGAG +GCCACGGGTTACTCTGCCTGCGTACCAGGCGCCAAGTGGGCCCGAGGCATCCTGGCATGC +TCCAGGGTGCCCACTCAGGCCAGATGTGTGACCTCGTGGGCCCATGGAGGCTGTGTGTGC +CCTGTGCTGCCTCCCAGGCCGGGAGGGCAGGTGTTGGGATTATAGGTGTGAACCCAACAC +TTAAGGAGGCTGAGGCAGGAGGATTACTTGAGCCCAGGAGTTCAAGACCAGTCTGGGCAA +CATGGTAAAACCCTGTCTCTACAAAAAAAAATACAAAAATTAGCCAGGCGTGGTGGCATG +TGCCTGTGGCCCCAGCTACTCAGGAGGCTGAGGCTAGAGAATTGCCTGAGCCCGGAAAGC +AGAGGTTTCAGTGAGCTGAGATTGTGCCACTGCACTCCAGCATGGGTGACAGAGCGAGAC +CCTGTCTCATTCAATCAGTCAATCAATCAATCAAATAAAAGCTCAGCTGTGGGGTTTTGT +GAGGACTCCTGTGTAGGCCTGTGGCCTGGCAGTAGTGTGAGAATGCTGCTGAGGCTGGGT +GGTCCCGGCACCGTGTGGGAGGAGGACGGGTGCATGGAGACTGAGGCAGGGTGGTCCTAG +GCCTGCTGGTATAGGAGGATGCAGTGGGTGCAGGGCTGGTCAGGACGGGTGGGTGAAGGC +ACAAGACTGATGTCCTTGGAAGGTGGAAGGTTTTCATAGATGAAGATGTGGCGGCTCAGA +GGGTTACCCTCTTCTGGTTCCTTGACTATTGTGCCCTCCTGGGCTCCATCCCACCCTGGC +ACCCAGGTCTGTCAGCTGCCTCTGAACTAGTGCCAACCCCAGCAGCTCCAGTCTTGTGGA +ATTGTTCACCCCTGTGGTGTTTTGATGGTGGCAGCTGGTGCATGGATGTACACGGGCTTC +TGCCAAGTGTCGGGGTGACCATATCACTAAGGCCCACATCCTCTCACTCTCTGGCGTCAC +CGGATTGTATGCAAAAGTTTAGGACAGTGGTTCTCCAGGTGTGGTCCTTGGGCCTGTAGC +ACCAGCTTTACTTGAGAACTTGTTAGAAATGAAATCACCCTGGGCCGGTGGCTCACACCT +GTAATCTCAGCACTTTGGGAGTCCAAGGCAGGAGGATCCCTTGAGGCCAGGAGCTTGAGA +CCGGCCTGGGCAACGTAGTGAGTCCCTGTCTTTACAAAAAAAAAAAAAAAAATTAGCCAG +CTGTGGTGGCATATGCCTGTTGTCCCAGTTACTCAGGAGGCTGAGGTGGGAGGATCGCCT +GAGCCTGGAAGGTAGAAGCTGCAGTGAACCGAGACTGAGCCACTGCAGTTAGCCTAGGCA +ACAGAGTGAGACCCTGTCTGAAAAAAAAGAAAAGAAATGCAAATCAAAATCATTAAATTC +ATAAAAATTTGGCCATCACTTCTTTTTTTTTTTTTTTTTTTTTGAGATGGAATTTTGCTC +TTGTTGCCCAGGCTGGAGTGCAATGGTGCCATCTCAGCTCACCGCAACCTCCATCTCCCG +GGTTCAAGCTGTTCTCCTGCTTCAGCCTTCCTAATAGCTGGGATTACAGGCATGCACCAC +CACACCAGGCTAATTTTGTATTTTTAGTAGAGATGGGGTTTCTCCATGTTGGTCAGGCTG +GCCTTGAACTCCCGACCTCAGGTGATCCGCCCGCCTTGTCCTCCCAAAGTGCTGGGATTA +GAAGCATGAGCCATTGCACCCAGCGGCCATTACTTTTTCAAGTAGTTTTTCTGTCTTCTC +TCTCACTCTCTCCTTCTCTCCAGTTACACACATATATTAGTTCACTTGCCCTTGTCCCAC +ACCTCTGCGATGCTCTCTGCGTACTTTTCTCGGTGCCCCTAGATCTTGAGGTTTTCCAGC +CTGGTGTCTGGGAGCCAGCCCTACTCCCTGCCCTGTGTGAGCACTGGTGGTTCTTGCCCC +AGTGTCATATAGTCTCCTCCCTGAGATGCTGATCAGACATTCTCTGTGTAGCTCCTTCCT +CTCTGGACTTTTGTGCCACTGTCTTAGTTCGTTTGTGTTGCTCTAAAGGAAAAAGCTGAG +TCTGGGTAATTTTTTTCTTTTTTTTTGAGATAGGGTCTCACTCTGTTGCCCAGGCTGGAG +TGCAGTGGCACAATCCTGTCTCACTGCAGCCTCTAACTCCTGGCCTCAAGTGATCCTCCC +ACCTCAGCCTCCCTAGTAGCTGGGACTACAAGTGCACATCACCATGCCCAGCTAATTTTT +AAAAATAATTTGTAGCGACAAAGCCTTGCTGTGTTGCACAAGCTGGTTTCAAAGTCCTGG +CCTGAAGTGACCCTCCTTTCTTGGCCTCCGAAAGTGCTGGGATTACAGATAATAAGCCAT +GGTGCCCAGCCAAGGCTGGGTAATTTTTTTTTTTTTTTTTTTTTTGAGACAGAGTCTTGC +TCTGTCGCTTAGGCTGGAGTGCAATGGTGCGACCTTGGCTCACTGCAACCTCCACCTCCC +AGGTTCAAGTGATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCACCTGCCA +CCACACCCTGCTAATTTTTGTATTTTTGTATTTTTTTATTATTATTCTTTAAGTTCTAGG +GTACATGTGCAGAACGTGCAGGTTTGTTACATAGGTATACATACATGTGCCATGTTGGTT +TGCTGCACCCATCAACTCATCATTTACATTGGGTATTTCTCCTAACGCTATCCTTCCCCC +AGCCCAATTTTTGTATTTTTAGTAGAGATGGGGTTTCACCAGGTTGGCTGGGCTGGTCTC +AAACTCCTGACCTCAAGTGATCCACAAGGCTGGGTAATTTATAAAGAAAAGAGGTTTATT +TGGCTTAGAGTTCTACAGGGGACCTGAAGCACAGTGTCAGCATCTGCTTCTGATGCAGGC +CTCAGGAAGCTTCTACTGATGGTGGAAGGGGAAGGGGAGGTGGTATGTGCAGATCACACA +CGGAGGGAGGAAGCCAGAGAGAGGGAGGAGGCGCCACGCTCTTTTAAACAACCAGTTCTC +AAAGGAACTAATAGAGCTAGAACTCATCACTGTGAGGACAACACCAAGCCGTTCATGAAG +GATCTGCCATTAGGTAGATCTGTCTCCCATTAGACCCCACCTCCAACACTGGGGATCAGT +TTTTTGGTTTGTTTGTTTTTTTTTTTTTTTTTTGAGACAGAGTTTCACTCTTGTTGCCCA +GGCTGGAGTGCAATGGCACGATCTCGGCTCACCACAAGCTCCGCCTCCAAGGTTCAAGCA +ATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCGCCTGCCACCATGCCCAGC +TAATTTTTTGTGTTTTTAGTAGAGACGGGGTTTCACCATGTTGGTCAGGCTGGTCTCGAA +CTCTTGACCTCAGGCAATCCACCCGCCTCAGCCTCCCAAAATGCTGAGATTAGAGGCGTG +AGCCACCTCACCCAGCCCGGGGATCAGATTTTAACATGAGGTCTGGGGGACAAACATCCA +AACTATGGCAGCCATGAACTCTGGTTGTCTTAGTTTCCCCAAACACTAAGCCCCTCTTCT +CAGCTCAGGGAGTCTGCTGAATTCGGCCTGGTCCCCCCACTCCCTGGGCTGGGTCCTGGA +GCCTCTCTAATCATGGGCTCACTTTGTTTCCTGTCTGTCATATCCTTTTTTGTAAAACCC +ATTTGATATGGTTTGGCTGTGTCTCCACCCAAATCTCATCTTGAATTATAGTTCCCCAAA +TCCCCACATGTCCTGGGAGAGACCCAGTGGGAGGTAATTGAATCATGGGGCATTACCCCC +ATGCTGCTATTCTCATGATAGTGAGTTCTCATGAGATCTGATAGTGTTTTGTTTTTTTTT +TTTTGAGACTGAGTTTCGCTCTTGTTACCCAGGCTGGAGTGCAATGGTGCGATCTCGGCT +CACTGCAACCTCCACCTCCCAGGTTCAAGCAATTCTCCTGCCTCAGCCTCCTGAGTAGCT +GGAATTACAGCCGCTTGCCACCACGCCCAGCTAATTTTTGTATTTTTAGTAGAGATGGGG +TTTCACCATGTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCTGCCTCG +GCCTTCCGAAGTGCTGACATTACAGGCATGAGCTGCCGCTCCCAGCCAAGATCTGATGGT +TTTATAAGGGGCTTTTCCTGCTTTGCTTGGAACTTCTCCTTCCTGCCACCATGTGAAGAA +GGACATGTTTGCTTCCCCTTCTGCCATGATTGTAAGTTTCCTGAGGCCTCCCCAGCCATG +CTGAACTATGAGTCACATATCTTTCCTTTATAAATTACCCAGTCTCGGGTATGTCCTTGT +AGCAGCATGAGAATGGACTAATAAATACACCATTGTTTCTTGAGTTTTATTTATTTATTT +ATTTTTTGGTTGTTTTATGCAGGAGGGTAAATCTGGTCCTTGTTGCTTGGGCAATTTGGA +AGTTTTGTTCTTGTTTTAATTATTGATTTGTAAGAGTTATTTACCCATTCTGGATATGAG +TCCTTTGTGCCTACTCATTTCCTTAATGATAGCTTATGGTGAGCAGAATTTTTTTTTTTT +CTTTTGAGTGGGTGGAGTCTTACTCTGTTGCCAGGCTGGAGTACAGTGGTGCGATCTCAG +CTCACTGCAACCTCCGCCTCCCAGGTTCAAGTGATTCTTCTGCCTCAGCCTCCTGAGTAG +CTGGGACTACAAGCATGCACCACCATGCCCAGCTAATTTTTGTATTTTTAGTAGAGATGG +GGTTTCACCATGTTGGCCAGGATGGGCTCAATCTCTTGACCTCTTGATCTGCCTGCCTTG +GCCTCCCAAAGTGGTAGGATTACAGGCGTGAGCCACTGCGCCCGGCCAGAATATTTCATT +TTAACAAAGTACAGTTTATCTTATCTTTTATGAGTTGTTCTTTTTGTGCCTTATCCAAAA +AGTCTTTGCCTACCCAGAGGAAAATATATAACAATATTTTCCTCCATTTGCTTCTAGAAG +CCTAATTTTTGTTTTTATGTTTGGTCTATGATTTATCTCAAGGTTTTGTACATGGTGTGA +GGTAGGGGTTGAGATTTACTGCCTCCAACCCCCAAATCTCTCTAGTTGTTCCAGCATCAT +TTATTAAATGGATTATCTTTTGCCTAGTTCATTACTATGGCAACTTGGTTGTACATCAGT +TGAACATATATGTGTGGGTCTATTCCTGACTCTGTTGTATCCCATTGATCTATGTATCTG +TCTTGATGCCAACACCATGCAGTCTATGAGTGCTGCTGCTTTTTAGTAAGTCTTGAAATC +AGGCTGAGCACTGTGGCTCACACCTGTAATCCCAGCACTTTGGGAGACCGAGGTGGGCAG +ATCACCTGAGGTTGGGAGTTCAAGACCAGCCTGACCAACATGGAGAAACCCCGTCTCTAC +TAAAAATACAAAATTAGCTGGGTGTGGTGGTCCATGCCTGTAATCCCAGCTACTCGGGAG +GCTGAGGCAGGAGAATCACTTGAACCCGGGAGGCGGAGGTTGCGGTGAGCTGAGATCACG +CCATTGCACTCCAGCCTGGGTAACAAGAGCGAAACTCTGTCTCAAAAAAAAAAAAAAAAA +GAAAAAAGAAATCAGGCAATGTGGGTCTGCCTTCTTTTTCGGGACTATTTTGGCCATCCC +AGTTCCTTTGCATATGCATAGATATTTCAGCCAGTCTGTTAATTGCTATAAAACGAAAAG +CCCCCTGGGATTTTGACTGGGCAGGTTTTGAATCTATGGGTCATGTGGGGAGAAGTGTCA +CCTTAACAATACTGAGTTGTCTAAGAAGTACCCAGTGAAACAAATAATAACAAGAAGAAA +CACTGTTGAGGCTGGGCACGGTGGCTCACGCCTGTAATTCCAGCACTTTGGAAGGCCGAG +GCGGGCCGATCATGAGATCAGGAGACCGAGACCATCTTGGCTAACACGGTGAAACCCTGT +CTCTACTAAAAAAATATGAAAAAATTAGCTAGGTGTGGTGGTGGGCACCTGTAGTCCCAG +CTACTTGGGAGGCTGAGGCAGGAGAATGGCCTGAACCCGGGAGGCGGAGCTTGCAGTGAA +CTGAGATCACACCACTGCACTCCAGCCTAGGCGACAGAGCAAGACTCTAAAAAACAAAAA +CAAACAAAAAAACACTATTGAATCTTTCAGTGAATATGCATGTCTCTCCTTAAATCAGGT +CAGCTCAACTTGAGACCCTCAACAGTGCCCTGGAGTTTTCAGTCTTTGTCACTCATTTTT +CATTAAATATTTTCCTGGTGGTTTTTTTTTTTTTTTTTTTTTTTGAGACGGAGTCTTGGT +CTGTTGCCCAGGCTAGAGTGCAATGGCGCCATCTCTGCTCATTGCAACCTCCACCTCCCG +GGTTCCAGCAATTCTCCTGTCTCAGCCTCCCGAGTAGCTGGAACTACAGGTGCCTGCCAC +CATGCCCAGCTAATTTTTGTATTTTTAGTAGAGATGGGGTTTCATCATATTGGCCAGGCT +GGTCTCGAACTCCTGACCTCGTGATCCGCCCGCCTTGGCCTCCCAAAGTGCTGGGATTAC +AGGCGTGAGCCACTGCACCCGGCTTTTTTTTTTTTTTTTAATCACACTAAGGATTTTAAA +AATGCTGTTATAAATGGTATATTTAAATGCTCACTTTCCAGTTCTTGCTAGCATTTACTT +ATTAGTTCTAATACATCGGTTTTGGTATTCCTTTTGGGTTTTCTTCATATATGATCCTGC +TGGTTGCAAATACAGTTTTGTTGGGTTTTTTTTTTTTTTTTGAGACAGAGTTTCGCTGAG +AGTGCAATGGTGTGATCTCGGCTCACTGCAACCTCCACCTCCCGGGTTCAAGCAATTCCC +CTGCCTCAGCCCCCCGAGTAGCTGGGATTATAGGCTGCCTCAGCCTCCTAAGTAGTTGGG +ATTACAGGCATGCACCACCACGCCTGGCTAATTTTGTATCTTTAATAGAAATGGTGTTTC +TCCATGTTGGTCAGGCTGGTCTTGAACTCCCAACCTCAGGTGATCTGCCCGCCTCGGCCT +CCCAAAGGGCTGGGATTACAGGTGTGAGTCACCGCACGGGGCCACAAATACAGTTTTATT +TCTTTATTTTTGATCTTTACATCTTTTCTTTTTCTGTTATAATTAATTATTGTTATAAAA +ATAATATCTTAGGGCCAGGCACGGTGGCTCACACCTGTAATCCCAGCACTTTGGGACGCC +AAGGCGGACGGATCACCTGAGGTTGGGAATTCGAGACCAGCCTGGCCAACATGGAGAAAC +TCCGTTTCTACTAAAAATACAAAATTAGCCAGGTGTGATGGCACATGCCTGTAATTCCAG +CTACTCAGGAGGCTGAGGCAGGAGAATCGCTTGAACCCAGGAGGGAGAGGTTGCAGTGAG +CCGAGAGCACACCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCTGTCTCAAAAAG +TAATAATAACAATAATAAATAAAATAACATCCTAGCCAGTGCAGTGGCTCACTCCTGTAA +TCCCAGCACTTTGGGAGGCTGAGTCGGGAGGATCGCTTGAGCCCAGGAGTTCGAGACAAG +CCTGGGCAACACAGCAAAACTTTGTCTGTACAAAAAAATGCAAAAATCAGCCGAGTGTGA +TGGTACCTGCCTGTGGTCCCAGCTACTTGGGCTGAGGTGGGAGGATCGCTTGAGCCTGGG +AGGTGGAGGTTGCAGTGAACTGTGTGATTGCCACTGAACTCCAGCTTGGGTGACAGAGTG +AGACTCTGTCTCAAAAAAATAAAAAATGAAATAAAATAATAAAAATAACATCTTAATGAC +AGCCTTTTTTGCCCCAATCTTTGGGTAAAATGACCCCCTGGTCTAAGAAGGAGCCCTCCT +GTGGCTTTCAGAGCCCTCCAACCTTGTGGCATTAGCAGTGGCCCATGCCCTGCAGATTTG +GCGGGGGTGAAGGTCCTGGTTGTGTGCTGGGCTCCTAGTGAAGGGCCTGCCCTTTGGGCC +TGGTGCATCCTGCTGGGTGAGGACAGCCAGCGTCCCTGCACCCCATTCATGCGATTGGAG +CCTAGTGCTGCCCCTCAGCCTTGACGCTGGCCCAAGTGGAAGGATGTGTTCTGCAGGGCA +TCTGTTGGGATAGGTGTGGTTGGTGTCATAGTTGTCCTGCAGGACAGGGATCTCACTTGC +ACGACCCATGAACCCCAGGGGCTGCCTGGCCTTGAAGAGTTCCAGCCACGATTCCATAGC +TGGGGCTGCTGGGCCAAGCCGCATGTCGAACGTCCTCGAGGAGCTTGAGGCAGGAGCTGG +GCCGAGTATGCGTCTCCCAGGGCTGGGAACCAGGTGGGGGACTGGAATGGGTGGCATCAA +TGGTGGTAACACTGTCATCTGCCACAGGGCTGGACATGGAGGAAGGCAAGGAAGGAGGCA +CATGGCTGGGCATCAGCACACGTGGCAAGCTGGCAGCACTCACCAACTACCTGCAGCCGC +AGCTGGACTGGCAGGCCCGAGGGCGAGGTAAGGCGAGTGGGGTGGGGCCAAGGTGAGACA +GGGTGGGGTGGGGCAGGCCTAGGTGAGACAAGGTGGGGCCAAGGGACTACAGGACTGGCC +AATGTATGGTGGAGTGGGGCGGGCCAAGGTAGGAAGTGCCAAGGTGCTTGTGCTTGGGAG +TGGGATGGGGCAGGGCTGAGGTACCGTGGGGCAGGGCCAGGTTACAGAGTGGGCGGTGAC +AAAGCGTGGCAGGGCAGGGCCCAGGTAAGGGTGGGGACAAGAAGGGGGAAGCTGGGCCCC +GTGGCAGGTGGGTGGCTTCCGTGGGCATATCACTGCCGCCACTGAGGTGTGCTGCAGGGG +TATGCGGCAGAGACAGGAAGAGTGAGGAGGGGAGCATCCCATTTCCCACACCCTGGCCCT +CTGGCGTCGCAGCCAGGAGCCCACTCCCACCTGACCCACGCAGCACTGTTTACTCCTCTC +AGGGCGCACTCTCCCCTTGTCCTCATGCATGGCACTCCTGACTGCTGTGTCACTGTCCCC +TGCCTGGAATGTTTGTAGAGTAGATGCCTTCCCCGAGACGACAGCTCTGTGGACACACAT +TGTCCCCACTGAAAGGTGTTGTTTACTTCATGCTGGATTTCCATAGGAAGACATAGTGGG +GAAATTTTTTTTTTAATAAAATGAGCAGTTTTCAGTGCCGACCTGAGTGGCAGCCAGGCT +AATGAGGTGTGGCTGACTCTTGCGGCAGTCATGACAGGCCAGGGCTCCAGTGGGACCCCT +CATCTTCCTGCATCCTCCCCAGGGGGCCCCATATCAGTGTTCCTGGGAGAAGAGCACATG +CCTGCAGCTGTGGACACAGCATCTGTCCCCTGCCTACAGGTGAACTTGTCACCCACTTTC +TGACCACTGACGTGGACAGCTTGTCCTACCTGAAGAAGGTCTCTATGGAGGGCCATCTGT +ACAATGGCTTCAACCTCATAGCAGCCGACCTGAGGTGGGTCTGCCAGAGGGGGATGGCGG +CTCTGCCCAGCACTGCCTCGGGGGCAGGCCTCAGGCTCATCAGGAAGTGGGGTTCCACTG +GGGGCTGTGGCAGCCTCTCCAGGGACGTTGCTCCTCGTGACTTGGCAAACATTCTGAGGA +CTGAGCCTGTCACAGATGTACCAACTCGGGTATTTGGGGGTGAAGCCCAAGGCTTCCTGT +GATGGCATGAGGGCTGCCGGATCCCTGGAGAAAGCTGAGGCTGTGAAGAACAGTCACATA +GAGTGGCTCTGGCCGGGTGTCCTCCCTCCCACGGGCAGGCTGTGCAGAGCAGCCCTCCGC +AGCCCTGGCTTGGAGTGACTGGGATGCTGTGCTCCCAGGGAAGCTCCTGTTGGAGATGAG +GCCGCAGGAACTGCGGAGGTTTTGGTGTTTTGCCCTTCCGTGAAGTGAGCATTCCTCCCT +CCTGCCCTCCTCCCCCTCCAAAGCCCCAGAACTTGGCCAATGCTGTTAGTCCGGGGCCTT +CTGCCAGGACAGGCAAACGGGAAGTGGTCGGCACATTGTGGCGGGCCCTGAAGCTGCCTC +CTTCCACAAGGGCAGGTCCATGGGCCTCTCTCCTGGCTCCCGAGCTCCAGGCCTGCTGTT +CGTTGAGCATCCCTTGTGTGTGGCATGCCCAGCCCTGCCCCACATGGGTCTGCACACTTG +CTATGGAGGCTGGGAGAGTTGCAGTGTCCCCTAGGTGGAAGGCCGAGGGCTGGTGCGGGG +CACTTGCTGTCCGGAGCCGTTCTTCCTGCCCATGCCTTCGTGACTCCAGGTGGCAGAGCC +CCTGTGCTCTCTGCATGCCCCCATGCTCAGGAACCACTTTTCCCGGTCAGTAGTTCCATG +TGGGTCTGATTAGTCTCAGGAGAGTTCCTCTGCGGCCGTGGCACCAGCAGGACTTGGCAC +TCAGCAGCTGTGTGGAGGTGGGGTGCCAAGGGTGCCATGCCTTGAGCAGATACACGGGCT +CCTGTGGTTGGGGGTTGGGGGTTTGGGCTCCTCAGAGCCTGTGCAACTCTCCCGGCTCCA +AAGGCTGCAGAGTGAGGGTCAGCCTCCTGGACCTAGCCTGAGGATACAGGCAGTGGCCAG +GAGAGCATACCACAGGTCAGGCAAAAGCTGGTGCCAGGGCCGAGGCTGGAGGGCGGGGGC +ATCGGAGGTCAGTGAGCAGCCCTGCTGGTAGGTGCAGATGAGGAAGCCAAGGCCTGGAAG +GGAGAGAGGCTTGTCATGGCCACAGCTATCCCTGGGTGAGGCCTGCCCTCCGCCTGGCCT +GTGGTATAGTGCTGGCAGCATGGGTGTCCAGTTCTGTAGGTCCTTACACAGAAAGCCCAG +AGGAGATTTTTGCCTGCAAACAGTCTCTGAAATTATGAACCAAGTATCTTAGGAAAGTTG +CCAAAGACCATGGTGAGGAAGAACGGGAGTGGAATGTGAACATAGACGGGGGGGCCCTTG +AAGCCTACCAGGGGTGGGGAAGGTGGGTCCCACCTGGGGGCAGCACTTCGGGGAGGAAGG +CACCATGCCTGGCTCTTTCTCTGCATCTGTTCCATCTTGAAGGCCCAGGGCTCCATGCCC +AGCATCTGGCCTGGGAGGGCATCTCACAGGCCACAAAGAGATCCTCTTCACTTTGCAAAA +AAGGCACTCCAAGTTCTAGAAGACTTACTGTGGTATTGAGGATTGGAATATTTTCAGCTG +GGGAGCATTTTGAACTATTTTCTTTTTAAAAAATGATTTATTTATTTTGTAGAGATGGGG +TCTTGCTATGTTGCCCAGTCTGGTTTCAAACTCCTGGCCTCAAGCAGTCCTCCCTCCTTA +GTCTCCAGATTAGCTGGGACTATAGGCATGAGTCACTATGCCCAGCTCTACTGTCCCTTA +ACTATTTTAAAGTGTACACTTAACACTTGAGAGTAGGAAAATGTGGTCTTTGGCGCTTTC +TTTGGAAGCCTCGATCACCCTGGGGCCACACTGGGGCCACCTGTCCAGAAACCCTCATAG +ATGAGCTGTGGTAAGGGGCCTGATGGAGAGGTTGGTGATGTGGGGATGGGGCTCAGCCCT +GCAGTTGTCCCCATGGGCAGCCTCTGTGTGTCCATGCCATGGGGCATTCGGCATGGCAGG +AGGGCATTTTAGATCCTGTGCCTCCTGGGCTGGTGGGCCCCGAGGTGAGCTGGGAACATA +CCCGTGATGCTGGACAAGAGCTGGGGCCTCCATGACCCCGCCTGCCAGGCACCTGAGGGG +CTGGGTCCTGCAAGCTCCTGACCTGGCCGCAGCGGGCTACTGCGCACATCGCTAGCCTCC +AGAAACAGGGCTGTGAGATCACCGGGCAGTGTCGGGGAGGACGCCCTATGGCTGTAGTCT +GACATTCTCTCCCCTTGGCCTGCAGCACAGCAAAGGGAGACGTCATTTGCTACTATGGGA +ACCGAGGGGAGCCTGATCCTATCGTTTTGACGCCAGGTGAGCCTGCCCTGGCAGCCTGAT +GGGGTGGGGGACTGTTTCTATGCAGAGGTCACCCTTGTGCTTTTTAGAGACCAGGCACTT +GTCATATTACTCTTCTGAGATGACTTTGTGGCCATTTAAGTGCCTTATGGTCTGTGGGCA +CCTTGCCCTGCACCTGGACACTTCAGAGAGCCCTGGCTCCCTGCTCACCCCCTCCCCATG +GGCTTTTCCTGCTGAGCAAGGTGCGCCCCTGTTCTGGGCTTCCCACCGCAGCCCTGCAGC +CCAGCCGGCCACCCCCAGCCTCACTTCCTGTGCCGTCCCAGTGTGCCCTGTGCCTGTTCC +TTCTCAGAACCTCTGGAGCCATCACCACCTGGGGTTCTTGCCTGGTCTGCTCCCTGACGC +ACAAGTACACACCCCACTCAAGCCCCACACAGATGCACGCCTCCTGCACCCAGTCCCCAG +TCTGATCCCCGGTCCCCATCCTCAGGGCCTCGAGCCCCTCTGCGCCAGGTCACACTCCAC +GGCTGGGCCCTTCCTGCCCTGGCTCTGCACCACTGCCCAGGCTGTGCCTCCTGCTACATG +CCCTTCCTTTCCCCCTCCTCGGGTGCTGCGATTTCCTGGAAGCTTCCTCTGCCAGTGCCC +CAACCTGGAGAGAATGTGTCACATTGCCCCCCTCTGCAGCCATGTTCTGGGAGGGAGGTC +TGCATCTTGTCCCAGGTCTGGTGCCAGGACAAAGCAGCACTCCTGGGAAATGGCATTTCC +CCTGGGTGCACAAAACTGTAGGGACCATAGCCTAGGTTCCGGGGACTGCTGGCTCACTCA +CTCCCACACTCGCTGCCCACAGACACTCCTCGCTGGTGGCATCGTGGAACTCTGTGCCTT +AAACGCCCGCTCTGGTCCCTCTACTCAAGCTGCTGGCTCACACAGGGTGTTCCGGCGCCT +GGGGAGTGTGTCAGTGCCCTTAGCGCCACCCACACCCCTCTGTGAGGGGGCTCCCTCACA +CCCCTGGCTCCTCTGAAGCTCCATGCCCACGTCACACAGACTTTCTTTTGCATTTGGCAC +AAATCACCAAGTGAGGTTGCAGGTCACAGGTGCACACCTTCCCACTGGGTGTACACGGTG +GAACTGAAGCCCCAGGCGTCCCTGGAGGGGCCCGAGGGAGATGATAAGCAGTCCCCAGGA +CAGCTGAGTGGCCCCATCCCACCTGCATCTTAGGGGGCTGGTGGTGCTGACGGGCTCATC +ATGAGTCCTGTGGTCCTTGCCTGGCCCACACTGGAGCTGGCTTCCAGCTTCCCACGTCTG +CCCAGTGATGTTTCATCCACAGATAGGCCCAGCCCCCATTTGCTAGGGTGGTGCCCAGAC +CCGAACCCCTGGGCTAGTTGGGATCTCCAGAGGAGGCATCTGCCTGGAGGGTGGCTTCCA +GTGTGTCCCACCCACTGCCCCCACGCCTACCAGCTGGTGCCCTCTCCTCCACCTGGGGCT +TATCCTTCCGGCCACCCTCTGTGACCCTGGTCTTCCCCTCCCTACCTTGGATACAACTGT +GGGCAGCCCACCTGAGCTCCCAAGAGCTGGGCAGTGGCACAGACACAGAGACTACCAGCG +AGGCAGGGATGTGGCCCCAGAAGGTCCTGAGCTTGCAAAGGATTGTTCTGGCTGTCTCAG +CCAGCTCTTGCTGTTCCACCTGCCCCAGAACCTCCGCATCAGTTGAGGGTCGTGGGGTTG +GAATGTGTGGCGAAGTAGGTCTGTGGCAGTGGAGTTGGGCCATGCTGAGCCTGTGACTGC +CCAGGAGAGAATTGGAAACTAAAAGGTGCAAAAGCAGTCAGAGACTCCCTACCACCCCCT +CACTGTGAACATTGGCCCAGCGGCCTCTGGGGCAGTCGCTGTAACCATCCACGTGGCATC +CTCGGTTCTCAGAGGCTGAGACCTCCGTGGCTGGAGATGCTTATTTTCTGCTCAGTTGTT +GTTCTGTAGAACTTATTTCTGTCTACATCCTGCCTCATCCCTGAGCCTGCCCCACCTGGT +CCACATTGCCTTTTTTTTTTTGATAAAGTTTTATTGAGATATGACTGACTAGCGGCACAG +TTCACCCATTTAAAGTGTATCATTCAGTAGGTTTCGTTTCATTCACAGAGTTGAGCAACT +GTCATCACTACCTAATTCCAGGACATTTCTTGATCCCCAAAGAAAGCCATACCTGTCAGC +AGCCACTCCCCATTCCCCGTCTCTTCAGCGCCTGCAACCTTTAATCTGCTTTCTGTCTCT +GGATTTGCCTATTCTGGACACTTTGTATAAAGGGAATCCTATAATATGTAGTTTAGGGGA +CTGACTTTTTTCACTTAGTGTTGTCGTCTAAAAACTCACCAGTGGCGAGGCACGGTGGCT +GACGCCTGTAATCCTAGCACTTTAGGAGGCCAAGGCGGGCAGATCACGAGGTCAGGAGAT +CGAGACCATCCTGGCTAACACGGTGAGACCCCATCTCTACTAAAAATACAAAAAATTAGC +CGGGCGTGTTGGCAGGTGCCTATAGTCCCAGCTACTTGGGAGGCTGAGGCGGGAGAATGG +CGTGAACACAGGAGGCGGAGCTTGCAGTGAGCTGAGATCGCGCCACTGTACTCCAGCCTG +GGCGACAGAGTGAGATTGCATCTCAAAAAAAAAAAAAACAAAGAAAAACTCACCAGCATG +GCTAAATGATAGAAAGGAGAGTTTTATTTGCCATATCAGTTTGCAGACCCGGAAGAGAGA +GTCTCTAGCATGGACTGAGGTGCTCTCTTTGAAGAGGGGAAGGGCAGTTTGAGTTTTATG +CCTCCCAAGGTCCATATCACACAATAGAGTCATACATATTCAGCAGGTTTGGGGAAAAGC +CATACATATTTATGAGGGGACCCGAGAACATATGCAATAGATAAACATACATGTAACATA +CATCCCATGTTCACTTTGGGGCAGGGTTTTAGCATTAAAATGAGGTAGAATCTGGATCTT +TCCATCAGAAGGTGAGCTCTAGGACACAGTTGGAGTGCAGCCTCTATGAACTGCTGAAAC +TGGCTTATGGTCTGTAGTTGCTTATCAGAAAAGAGTGTTTGAAGGCTGGTTCTCTGTCCA +GTCAGGGTTGTGGTGGTCTGGGCTGTCAAGAGTTAGGAGGGTCTGATAACGTGTGTGATC +TCTACTGTTGTGAGGGAGTTTATCAAGACTGTGGTTTTTCTTGTAGCTGTAGGAATTTAG +GGAGTTGCTGAGACAGCTGCCCTGAACCCTCGAGCCAGTTGGTACTTTTTGTTTCTTCCC +TTTATCCATTAATGGACACTTGAGTTTTTTCCACCTTTTGGCTGTTGGAAACAGTGCTGC +TCACAGTGTGACCTCACAGCATTTGTGTGGTCATATGTTTTTATGGCTCTCATGTGAATA +CGTAGGAATGGAGTTGTTAAGTCGTATGGTAACCCTGTTTAACCTTTTGAGGAACATCCA +AACTGTTTGCCAAAGCAGCCGCAGCATTATACATTCCCACCAGCAGTGTATGCGGGTTGC +AGCTTCTCTGAATCCTCACCAAAACTTGCTATGTTCTGTGTTTTTGATGATAGCCACGAT +AGTGGGTGTGAAGTTGTGTGGACTCGTGGTTTGGTTTGCGTTTCTCTGATGGCTATGATG +TTGAGCAGCTATTCTCATGCTCGTTGGCCATTTGTATGTCTTCTTTGGAGAAATGGTTAT +TCAGACTGGGTTGTCTTTTTGAGTTATAGGAGTGACTTATACATTCATTCTAGCTACAAG +TCTCTTATTTAAAGCACAAAGCTTAAAATTTTTAAGTCCTATGTCTCTCTCTTTTTTTTT +CTTTTGTTGCTCATGCTTTTGGTTTCTTATCTAAGAAACCATTGCCTAATCTAAGGTCAT +GAAGCTTTCCCCAATACTTTCTTCTTAGAGTTTTATAGCTTTTGCTCTTTCACTTAGGTC +TTTGGTTTGACTTAAGTTAACTATTTTTTTTTTTTTGAGACAGGGTCTGGCTCTGTCACC +CAGGCTGGAGTGCAGTGGTGCAGTCATGGCCCACTGCACTGTCAACCTCCTGGGCTTAAG +AGATCCTCCCAGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCAA +GGCGGGTGGATCACAAGGTCAGGAGATCGAGACCATCCTGGCTAAACCGGTGAAACCCCG +TCTCTACTAAAAATACAAAAAATTATCCAGGCGTGGTGGCGGGTGCCTGTAGTCCCAGCT +ACGTGGGAGGCTGAGACAGGAGAATGGCGTGAACCCGGGAGGTGGAGCTTGCAGTGAGCC +GAGATTGCGCCACCGCACTCCAGCCTGGGCGACAGAGTAAGACTCCGTCTCAAAAAAAAA +AAAAAAAAAAAGAGATCCTCCCTCCCAAGTAGCTGGGACTGCAGATGTGTGCCACCATGT +TCAGCTAACTTTTATGTTTTGTAGAGATAAGGCCTCACTATTTTGCTATTTTGCCGAGGC +TGGTCTTGAACTCCTGGGCTCCAGTGATCCTCCTGCCCCAGCCTCCCGATGTGCTGGGAT +TATAGGAGTGAGCCACCTCTCTTGACCTGAGTTAACTTTTGTGTATGGTGTCAGGTAGAG +TCCAACTCCCTTCTTTGCCCATGACTATGCAGTTCAATGGTCTTCCATGTTGTTCATGAT +GGAAAAAGCACTGTGACACCTGGGGCTGGCGGCTTGGCTCTGGGGGCCCCAGCAGAGCCA +GGCTGTCTCCCTGGGAAATGCCTCGGCCAAGATATTCTCCTGGAAGTCTGACAGGGAGAG +GGTGGTGTCTTGGTCTCCCTGGTGCATCATTTGGGGTGCTTGGCTCCCATCAAGCCCACC +CCTGCTGCCCTGGCCTCTAGAGAAGAGCCTCTGAGGTGAGGTGCTTCTCCACCTCAAGTC +CCTGCCCTTCACTTTCTGTGACATGAGAAACCCTTTTCCTGTTGGCCATGCCTTCTGCCA +ACACTCTGGGAGCTTGTTCAGAGTCTGTGCAGAGCCCCCCGGCTCTCCTAACCTGGGGCC +TGGCTGGTACGCAGAGGTGGGCCATGCTCTGCTGAGGCCCAGCCTACACCTGTGCCCACT +GTGTGGCGCTGTTGGGGGTTCCCCAAACAGGGACATGATTGTGGTGGGTGCCTCCTGGCC +TCTGGTGGCTAATTCTCCCACTCTTGAACTTCTCAGGTGGCCCCCCAACCTGGCGTGAGG +TGAAGAGGTTCCCTCTTGGCTGTCCCCTTTGCCTGTGAGATCTCAGGTTGCTCATTTCTT +ATTCATCCATCCATCGAGGCTGCTGGGCATCTGTGCCTTGTGGTCTCCTGTGGGTGCCCG +CTTCCGCCTACTGCTGAGTTCTCCTCTCCTTGCCATGCCATCAGGTCAGGAATGAGCATG +GGGAAGGAGCTGGAGCATGGAGCGGCTTGGCCTCAGTCTGGCCTGATTTCATGGTCCCCA +GCTGTACCCCGTGTTAGGTGGGTGGCAGGTGGCAATTTGCCCTGACATGGCACAGCAGGG +CCTCTGCATGGCCCGCTGATTGCTCCTCACAGGCACCTACGGGCTGAGCAACGCGCTGCT +GGAGACTCCCTGGAGGAAGCTGTGCTTTGGGAAGCAGCTCTTCCTGGAGGCTGTGGAACG +GAGCCAGGCGCTGCCCAAGGATGTGCTCATCGCCAGCCTCCTGGATGTGCTCAACAATGA +AGAGGCGTGAGTGGGCGGGTCCTGCTGGGGTGAGCCCCAGTGTCCCGCCACCAGGGCAGA +GGGAAAGGCAGGCCCTGCTGCCCCGGGAGGCCCATGGAAGTGGCCAGGCTGGGTCCCCAG +CTGCAGGGAAGCTGATGGATATCCTGTCCTCCCTGCCTGTCCCCTTGAGCCAGCTGAGGT +TTCCAACACCAGGGACTTTTGATGACAGAAGATGGGCCCAGGCCCAGGCCCAGGCCCAGG +GGAGGCTCAGTGCACCCAGAGGCTTGATGCAGCCACGTGGGGCCCAGAGCAGATGGATGC +TCCCCTCTGCATGCCGAGAGCTTGTGGGAAGTTCCAGAAGATTCTAGACACTCAGCAAAC +CCAGGCGGAAGAGACACATCATGGAAATGAGTGGCTAGGGTCAGCACGCTCAGGGTTGAT +GGGCTTCCCGCAAGCGGTCTGTCCCCAGCGACCCTGGGCTGAGTGCTGGGCAGGGACTTG +CAGTTCCGGGAACTGCCTGGGTGTAGGAGCTCCCACCCACTTCCTTGCCCGTAGGCCTCA +AGGCCCCTCAGGGGCCAGGCACTGGGGTCTTCGTTGCCCCAGCCGGGGGTCCTGGTGCTT +GCCATGCCAGCCTTTCTCCCACTGGGCGAGATGCCCCACCCATCCCTCGCTCCCCACCCA +GGTCAGACCACTGCCCTGCCCAGGTGATCCAGCGTCCACTCCCACCCTGTCCAGCTTGCC +CCCTTCAGAGAAGCACCCATGGACCATCTCCCACTCCTCCCCCTGGGGCCCCTTTCTGCC +CCCTGCCTACCCTCCTTCTCCTCTGGGCCTCTGATAGGCGGCCTCGTCCTTCAGCCTCAG +CATCGCTGCCTCACTGGAAGAGCCCCACCTGGGCATGCCCAGCAGCCCCTCCCAGCTGTA +AGTCCACACAGCCCCCATCAATGTGCCATCTGGGGCAGGCCGAGGACCGGCCCTGGCTGC +CCTCACTGATGGCTGGAGCCCCGATGCTAGCTACAATGGCTGGCTTGAGTGGACTTCTGT +CACAGAGGCAAATGCCCACAGGGCACCTCTTGGGGCAGGCAGGGAGCTTGTATGTGCCAT +CTGGGGCCAAAGCTCCACGATTGAGTCATAAGTTAAGGGTAGATGGAGATTTTCCGCCTT +GAGCAGAAACGTGGAGGAAACACGCCTGGTGTGTGACTCACGCCTGTAATCCCAGCACTT +TGGGAAGCCGAGGTGGGCGGATCACCTGAGGTCAGGAGGTCAAAACCAACTTGGTCAACA +TGGTGAAACTCTGTCTCTACTAAAAACACAAAATTAGATGGCTGGGTGGTGCACGCCTGT +AATCCCAGCTGACGGCTGGAGCCCCGATGCTAGCTACAATGGCTGGCTTGAGTGGACTTC +TGTCAGGAGAATTGCTTGAACTCGGGAGGTGGAAGTTGCAGTGAGCCAAGATCGTACCAT +TGCGCTCTAGTCTGGGCGACAAGAGTGAAACTCCTCCTCAAAAAAAGAAAATAAGAGAAA +AGAGAAGAGAAGAGGAAAAAGAAAAGAAGAAAAGAAACAACCCTTGCAGTTCCCCGGCCA +CTCCCCAGAGCCAGTTAGGCCACCAGGTGGGCTGGGGCTAGACCCGGCTGCGGGCGGGCC +ACAGAGGGACTAATGGCCACCACTTCTCTCCATCCTGCAGGCAGCTGCCAGACCCGGCCA +TCGAGGACCAGGGTGGGGAGTACGTGCAGCCCATGCTGAGCAAGTACGCGGCTGTGTGCG +TGCGCTGCCCTGGCTACGGCACCAGGTATTGCAGCACCGTGGGTGCGCCACCTCCTATCC +CATGTCCCACCTCCCACGCTAGAGGGCCGGCAAAGAAGCCAAGTGCCCATAGCCAGAGCC +AGGCTTCTTCCTCGCCTGAGTGGATTCCAGAGCTTCTGCCCTGTCCAGACGCAGCTGCAG +GGTGAGCAGATACCACAGGCTCCCGGGGCCCCACAGGCTGGGCTTAAGGAGCCAGTACAC +AGCCACACAGGGCCAGGATGGCTTCAGGGCTGCCTGCACATTGGTGGATCCCTGCGGGCA +AACGCCCCGGCACCATGGCACTAGGCCTGCAGGCTGTACCCTTGGGTGGTGGCTGCTGGC +CAGCCTTTCCTGCCTGGGGCTGGCTGGCCCATTGGCAGGTGCAGGGTGTCATTTCCTTCA +GCCCCTCCTCTGTCATAGGCTCATCTTCCTGTGTGTGAGGGGAAGGCAAGTGCCAACTCC +ACTCCCTGGCAGGCCGCATAGCCGCTGGGTCCCACCCCACGGGGTGCACTGCGTATGTGT +CTGCCCTGGGAACCAGCCTGTGCTGGGGCTGTTGGGGGATCCAGGGCCACCCTCCGTCTG +CAAAGCCCACGGCAGAGAGGGTTGGAGGAGAGGAGAGTGTGCTGAATGTTTGCTTCAGGT +GGGCTGGCATGGCCTGGGCAGTGGAAGAGAGGGCACAGGAGGGAAGCCTTCCAGACAGAG +GAGGCCTGGGCCCCAAGTGGTCAACAGCTTGACCTCTTGGAAGAACCAAGCATGGCTGTG +TCTGGGAACCTGGGCCTCCAAAGGGGAAGTGTGTGGTCAGCCCGCAGGCTGCCCTATGCC +TTGGCTCATGCTACACGGGGAGAGCAGGGCAGGGTGGGGTGGTTCCCAGTGAAGGTGGCA +GGACTCAGCAAGTGTGGGCCTGTGGAGCCAGCCAAGAGCTCACACGCCACTGATGGCCCC +TCATCATCCCCAAGACTGAGGCTGCTGCTCTCTGTGACTTGGCACAGCCTCCAGGCATGG +GGTTCCTAACTCTACCTGCCTGCATTCTTGCCCTATTTGTGGCTGTGACAGGCAGGGCAG +GGCTGAGGGACACCAGGTGAACGAGGGCCCCTGCTCTCTTTCAGAACCAACACTATCATC +CTGGTAGATGCGGACGGCCACGTGACCTTCACTGAGCGTAGCATGATGGACAAGGACCTC +TCCCACTGGGAGACCAGAACCTATGAGTTCACACTGCAGAGCTAACCCCACCTCTGGGCC +TGGCCAGTGGGCTCCTGGGGGGCCCTGCCTTGAGGGGCACTGTGGACAGGAAACCTTCCT +TTGCCATACTGCATTGCACTGCCCGTGGCTTGGCCAGCATCCCCCGGATCAGGGCCCTGT +GGTTTGCGTGTTACCCATCTGTGTCCCCATGCCCAGTTCAGGGTCTGCCTTTATGCCAGT +GAGGAGCAGCAGAGTCTGATACTAGGTCTAGGACCGGCCGAGGTATACCATGAACATGTG +GATACACCTGAGCCCACTCTTGCACATGTACACAGGCACTCACATGGCACACACATACAC +TCCTGCGTGTGCACAAGCACACACATGCAAGCCATATACATGGACACCGACACAGGCACA +TGTACGTGCACAGGTGTGCTACACATGTGCACACATGCACAGTTGCACAGACACACACAC +ACAGGTGCACACACACGATGCCGAACAAGGCAGAAGGGCGACTCTCACCTCTCATGTGCT +TCTGGCCAGTAGGTCTTTGTTCTGGTCCAACGACAGGAGTAGGCTTGTATTTAAAAGCGG +CCCCTCCTCTCCTGTGGCCACAGAACACAGGCGTGCTTGGACTCTTGACAAGCAGACCTG +CTCCTGCAGAGGAGACAGCCACATTTGGAATTGGGCACCGAGAAGACCTGAGAAAAACCC +ACTCTCTCTTTTTTTTTTTTTTGAGACGGAGTCTTGCTCTGTCACCCAGGCTGGAGTGCA +GTGGCACGATCTCGGCTCACTGCAACCTCCGCCTCCCAAGTTCAAGCAATTCTCCTGCCC +CAGCCTCCTGATTAGCTGGGATTACAGGCGTGTGCCACCATGCCCAGCTAATTTTTGTGT +TTTTAGTAGAGACGGGGTTTCACCATGTTGGTCAGGCTGGTCTTGAACTCCTGACGTGGT +GATCCACCTGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCACGCCTGG +CCGAAAAACCCACTCTCATAACAGAAGTGCAGACTCATTGCTAGATTCAGTGCCCTTGAG +TGTGCCAGAGGTCCTCTGTGTTTGAGACAATCCTGTGTGTGCCAGGAGGCTCCGTGTGCA +CCAGGGGCTCTCAGAATCCCGCTTACCCAGCTGGAGACCATGCCTCTGGCAGCCCCATCT +CAGCCAGCCCTGCTCTCTCCCTCTTCCCTCCAGGTGAGGCAAACTTCATAGGAATCTGTA +CCTGAATGTGAGCTCCTGATAATAAAACTCTGAGGCTTTGGTGAGCGCATTTCGAGGCCT +TTCCCTTGTATGCAGGGTGCCAGTGGGAGCTGCTATGTCTCCTGTGCAGCCAGACACCCT +GGACGAGGCCCTTCCCACCTCCCCCTTTCCTCACGGCTTCTTCAGCACCACATGTGGATG +CCTGTGGGTCAGTCCATCTGTCCATGGGCAGGGGCCGCTGTGAGAGACCCCATGCGCGTG +GGATGTGGTAGATGCTGATTATGGGGCCAGCCACCCATACAGGTCTATCAGGTCGCAATG +GAGGCCCCACTGGAGCGGGAGGCAGGCTGGCCTGGACTTCTGTTGGATGATGGGGGCCAG +GGGATGGTAGGAGGGGCAGGAGAGCAGGTCTGCATCTGTCTCAGCCCCAGGAGCTCCTGG +TTTGGGGCCAGCTCTAAGGAGCTTCATCCCTGAGCCTGGCCGAGTATAAGGGGGTCCCGG +ATATCCAATGCTGAGACCTAGACTTTTCTAAGCCTCTGCACCCAACCCCTAACTTGGCCT +TTTCAGACCCATGAGAGTGCAGGGTGGGTGTGGACCTGCGCCAGGGCTTCCCAGCCTGAT +TGTGACATGATGTGAGTCCACCTAGGGAGGAGCAGGGGCCTCCCCGTCTCTTCCCCTTCT +TGCCCAGACCACTTTGCTGGGCTCAGAGCCTTCCATGGCTCACTTTGAACTCAGAAGAGT +TTCCCAGCTGCGACCCAGGCTGCACCCCCAGGCCTGAGGAGAAACTGAGGCCCCACATCC +CATACGTGTCCTCTGAGTCAGGACAACAGGCTCCCGGCTGGGGGCACTGCCCTTGCTGCC +AACACATTCACCTGCCCCAGTGGCTACCATGTCCTGTGCCGGTGACCAGTGCCAGTCCCC +AACCTGGATGGTGCCCTGCCCTCATGAAGAGCCCCCCGGATGTTCACCTCTGCCCAGAGA +CCCGGCCTGCCCAGGAAGAGCAGTCTCTGCTCTTGTGTGGGTCCCTCTGCCCCCACCCTG +CCCAGGGCTCCCCAGCAGCCTGAGGCCCCTAAGGAAGAACAGCCCTCAATGGTGATTCTA +TTGGTGTTATGAGTTGTGTCCCCAAAGAGATATATCAGTGTCCTGACCCACAGTACCTCA +GAATGTGACTGCATTTGGAGATAGGGTTCTTCCAGGGGTAACCAAGGTAGAATGAGGTCG +TTAGTGTGGGCCCTAATCCAATATGACGGCTATCCTTATAAAAAGAGGAACATTTAGGCT +GGATACAGTGGCTCATGCCTATAATCCCAGCACCTTGGGAGGCTGAGGCAGGAGGACTGC +TTGAGCTCAGGAGTTCAAGACCAGCCTGGGGCAACATGTCGAAACGCTGTGTCTACCAAA +AAAAAAAAAAAAAAATACAAAAATTAGCTGGCCATTGTGACTCACACCTGTAGTGCGAGG +CTGAGGTGGGAGAATCGCTTGAACCCAGGAGGCAGAGGTTGCAGTGAGCCAAGATTGCAC +TACTGCACTCTGCCTGGGCAACAGAGGGAGACTCTGTCTCAAAAAAACAAAAAAGGAAGA +TTTGGGCTGGGCGCAGCGGCTCACATTGTAATCCCAGCCCTTTGGGAGGCCAAAGCTGGA +GGACTGCTTGAGCCCAGATTAGCCTGGGCAACATAGCAAGACCCCATCTCTAAAGAAAAA +TGAAAATTAAAAAATTAGCAGGGCATGGTGGTACACACCTGTAGTCCCAGCTACTTGGGA +GGCTGAGGTAGGAGGATCACTTGAGCTCAGGAGGTGGAGGCTGCAGTGAGCCGTGATTGC +ACCACTGCACTTCAGCCTGGATGATGGAGAAAAACCCTGTCTCTTAAAAAAAAAAAAAAA +GGAAAAAGAAAGATTTGGACACGGACGGATACGCGCACAGGAAGAACACCGTGTAAAGAC +TGGAATTCTGCTCCACGAGCCAAGGCATCACCAGAAGCTGGGAGAGGGGCCTGCTTCAGA +GCCTCTCTTAGAGCCTTCAGAGGGAGCAGACCTGCTGTCACTCTGATCATGGACTTCCAG +CATCCAGAGCTGTGTGACAATAAATGTCTGTTATCTTAAGTGGTTCAATTTGTGATGCTT +TTTTTTTTTTTTTTTTGGAGACAGGGTCTCACTCCATTGCCCAGACTGGAGTGCAGTGGC +AAGATCACAGCTCACTGCAGCCTCCACCTCCTGAGGTCAGGCAATCTTCCCACCTAGTCC +CCTGAGTAGATAGGACTACAGGTGCATACGACCACGTCCAGCTAATTTTTTGTATTTTTT +GTAGAGACGGGGTTTTACCATGTTGCCTGAACTGGTCCCAAACTCCTGGGCTCACATGAT +CCTCCCACCTTGGCCTCCCATAGTGCTGGGATTACAGGTGTGAGCTACTGAGCCCAGACT +GTGGTGCTTTTTTTTTTTTTTTTTTTTTTTGAGACGGAGTCTCACTCTGTCACCCAGGCT +GGAGTATGGTGGCACAGTCTTGGCTCACTGCAACCTCCACCTCCCGGGTTCAAGCAATTC +TCCTGCCTCAGCCTCCTGAGTAGCTGGGACTACAGGCACCTGCCACCACGTCCAGCTAAT +TTTTTGTATTTTTAGTAGAGACGGGGTTTCACTGTGTTAGCCAGGATGGTCTTGATCTCC +TGACCTTGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCAC +CGCTCCCGGCCGACTGTGGTGCTTTTTTAAGGCGGCCCTAACAGACTAACACAGTAGTGA +TCTTCACTTTACAGATGAAGGAACTGCGGCTTGGGGAGATACCATAACGGCCCCCCGGTT +CCGAGACAGGTGGAGAGGCAGAACCATGGGCCAGGACAGAATAGGATGAGTACAAGGTGG +CATCTCTGGGGGTGCCTGCCCCACAGATCCATGGTCTTCCCATGCTGGTGTCCCCACAAT +GTCTGGCACTGCTCCCCGCTTCACCTTACTTGCCCAGGCCTACCCCCATACCCTCAGCTC +ACAGCTACACACTCTGCACAGCTCCCACCCCAGGGTCTTTGTGCTCACAGTTCCCCTGCA +GATACCCAAACCACACTCTTCCCCCAGTTCCTGCAGGTCTTTACTGAAGTCTCGGGCAGG +CAACTCATTTAAAGTTTCAGTTTAGCCCAGCACGGTGGCACACACCTGTAATCCCAGCTA +CTTAGGAGGCTGAGGTGTGAGCGTCGCTTGAGCCCAGGAGTTTGAGGCTGTAGTAAGCCA +TGATTGCACGACTGCACTCCAGCGTGTGCGACACAGCGAGCCCCCATCTTGAAAGAAAGA +AAAAAGAAATTAAAAAGGAGGCTGGGCACTTTGGCTCACACCTGTAATCCCAGCACTTTG +AGAGGCCAAGGTGGGCAGATCACTTGAGTTCGAGACCAGCCTGACCAGCATGGTGAAACC +CCATCTCTACTAAATATACAAAAATTAGCTGGACATGGTGGCGGATGCCTGTAATCCCAG +CTATTCGGGAGGCTAAGGCAGGAGAATTGCTTGAACCTGGGATGCGGAGGTTGCAGTGAG +CTGAGATCGTACCACTGCACCCCAGCCTGGGTAACAGAGCTAGATTGTATCTCAAAAAAA +AAAAAAAAAAAAAAAAAAGGAAGGAAGGAGGAAGGAAAGAAGGAGGGAGGAAGAAGGAAG +GAAGGAACTCTCTTTTTCTCTATGGCAATGAGCACGTACCATCTGGCATGCTGTGTGCTA +GGATTGGTTCTTGCCTGTCTCCATCAGAATGGGAGCTTCAGGAAGGCAGGGACCTTCCTT +CTCTTGCCCACTACTGTACTCTGATGCCCAGGCCAGGCAGGCATTTGAGCCAAGAATGAC +AGTGCTGGTGCTTCCCAAGCCCCCATCTATTTGGGCCAACCCCTTGATGCAAGGCCCTTG +TGCTAATAGAGGGTATAGGGGTCCAAAGCCAGTGCCTTCTAGAAGAGCTTTGGACGTGAC +ACCAGGAATGGCTGGGCCTGGACAATGGCCTTCCTGGCACTGCCCAGCCAGTCCTCTGTG +CTTGTTGCCAGATGCACCTGATCCCTGAGTCCCCAGCATGGGTCTCTTTCTCCCAGGCAG +ATGGGGAACTCACCTTCTTCTCAGATGCCCCTTCCCAACATAAGCTGCTTCTGCCCTCTG +GCCCCGAGATGGCCAAGGTGAGCTGTGTAGACATAGAGTCTGGAGGCATGGGGCTGGCTA +ACGTGGAGGCAATTCTATGAACAGACATGGCCAGGCCAGGAATGCGGCATGGCCTCAGGT +CTCATCCTTGAAGGCCTGGGCTCCTGGTCTGCCTGCAGACTTCCTGAGACCACGTCTTGT +TCTCATCTGCCAGCAGATGCCTGGCTCATGGGTGAGCCGGGCTTAGGTGGAAACACAGGA +GCCCAGAGGGGAAAGGATCCTCCCCCAGCTTGGGCTGGAGTCCCAACTTCCAATCATCAA +TCTTTGCAACCCTGGGGCTGGACCTGGCTAGTTCCATGGTAAGGATCCTTCTCCGTCACC +CAGTCAGTCCCAGGCTGTGTGGGAAACTGGCTGTGGTGGGCAGGTCTGAGGTCTCAAGTC +TGACAGGGGCCACTGGAGCCTCCAACTCACCAATCAACCAAGTGTGAGAGGTTGCTTTGG +TTGAATGGCCATGTGCTGGGGTCTGACTGGCCCAGCCACAGGGAGGCTGGCATCCCCTAG +CTGAGTCCTGGACCCAGACCCTCCAGGGCATGGAGCCCATTGTGAGGTGTCTGGTGCTGA +AGTGGTGGGGGAGGCCCGTGCAGGCCTACAGCTTTGTCATCTGCAACATTCCTCTCCCCA +CTTTCTTTAAACTTTTTCATTTAGAAATGATTTCAATGGCCAGGCGTGGTGGCTCATGCC +TGTAATCCCAGCACTTTGGGAGGCTGAGGCGGGTGGATAACCTGAGGTCAGGAGTTCGCG +ACCAGCCTGACCAAAATGGAGAAACCTTGTCTCTACGAAAAATACAAAATTAGCTGGGCA +TGGTGGCACATGCATGTAATCCCAGCACTTTGGGAGGCTGAGGCAGGTAGATAACCTGAG +GTCAGGAGTTCGCGACCAGCCTGACCAAAATGGAGAAACCTTGTCTCTACAAAAAATACA +AAATTAGCTGAGCATGGTGGCACCTGCCTGTAATCCCAGCGACTTGGGAGGCCGAGGCAG +GAGAATCACTTGAACCCGGGAGGCAGAGGTTGCAGTGAGCCGAGATCATGCCATTGTCCT +CCAGCCTGGGTGACGAGAGTGAGACTCCGTCTCAAAAAAAAAAAAAAAAAAATGAAACCT +CGTCTCTACAAAATATACAAAAATTAGCTGGGCATGGTGGCAGGTGCCTGTAATCCCAGC +TACTTGGGAGGCTAAGGCAGGAGACTCGCTTGAACCCAGGAGGCAGAGGTTGCGGTGAGC +CAAGATGGCACCACTGCACTCTAGCCTGGTGACACGGCAAGACTCCATCTCAAAAAAAAA +AATTTTTTTTTCAATTTACTAAAGGATTTAAAAAGTAGAACAAAAAATTCTAGTGTCTTT +CACCCAGTTACCCCAAATGTGAATGCCGCACCCAATCACAGAAAAATGATTACAACCAGG +AAATTAACACTGATAATGTTAAAGAAAGAATTACTGAATGACATTTGCTAAAGCACTGTA +GGGAAGACTTTATTCAGGACCGTCTTGCTAGGTCTAGGGACCACAGGAATGAGATTCTGC +AGTGGGGGAGAGAGATTAAGCTCAAGTCCGAATGGGCAAGTGGGAACTGATGATAGCTGA +GGAGCAGGGCGGTGGGAGCTGGGTCAGCACATGGAAAATGACTAAGAAGAAACACCCCGG +GTGAGGGAGATTCTGGCTACACCAATTAACAGGATTTTTGCTGAAGACAGGCCACAGTGA +CCGGACATCTTCACCTGGGGGACAGTGTAGGAACGGATTAGATAAGGAGGGTGATCAGAT +GTCGAGGGTCAGGGGATGCTTCTTGCTAAAGTGACTTTGCAGGGTTCTTGCTCTAAGTGA +AATTTACAAGGAAGTGCACAGATGGGCCTAGAAGAAGGTTCAGAAGCCTGGTTTGGCCAA +GCAAAGAATCTTTGTCGGTCCCTCCTCTTGTTCAAGGAAAGAAGAGGTTATCTTTCCTTG +AATAGTACGAGTCCATTTCCTTGCTGGGCTGCCTTTTGTTCATTAAAGGCCAGCTGAATC +ATCTGCTGGGACCGGCAGTAGAGGAGATATCCTCCATGGTGTGAGCCATCAGGCGTTGCA +TGTTGAAGATAAAAGAAAAAGATATTAGTTGGAACCAACTATAAACTCAGTTTCTGAGTT +CAGAGGGCAGCTACTCAAGATTTCCAGGTGCTGTGCTTGAAGCATCTTCAGATGGAGTAG +GGGCTAACAGACTATCATGGACGGCAGTTTGCGTGTCATGAAGTCTGCCCACAAATTATC +TGTTGTGGTGCCATCTTAAAGTTTCTTTCTTTTTTTTTTTAGACAGAGTCTTGCTGTTGT +TGCCCAGGCTGGAGTGCAGTGGCGCAATCTCAGCTCACTGCAACCTCTGCCTCCCAGGTT +CAAGCGATTCTCTTGCCTCAGCCTCCAGAGTAGCTGGGACTACAGGCACACACCACCATG +CCCAGCTAATTTTTGTAATTTTTGTAGAGACGGAGTTTCACCATGTTGGCCAGGATGATC +TCAATCTCTTGACCTCGTGACCTGCCCACGTTGGCCTCCCAAAGTGTTGGGATTACAGGC +GTGAGCCACCGTGCCTGGCCTAAAGTTTCTATCAAGTTGTCCGGGTTCAGCTTAAAGGGC +TTCAGGAAATGGGAAGTTTTAATTTTTAGCGGTTCCAGGCCAGAAGGGTGGGAAAAAAAC +TGGAAACATCAGTTTAGAGAAAATCAAATATTGGAGGAAACTAGAAGAATTCAGGATCCA +ATCCAGTTTGTAGGTAAATATCAAAACCTCAAAAACAATGAACAGGGCTAGAATCTGATA +ATGGGTGCACTATAGTTTTCTTCTGAAACTAATTTTTCTCTATATAGTCACCCCACTTCT +ATCAAAGATGTTGAAGTAAGACTAATTTGTTTGTAGCTAAGTTTAGGTTGATTAAACTTG +GCCTAATTACTTACATAAGTGCCGCAACAATAGTGATTGAACACATAGGCTTTCTTTAAG +TTTCCTTTGCTAGGACTTTTTTTTTTTTTTTTTTTTTTTTGTCACGGAGTCTCGCTCTGT +CGCCCAGGCTGGAGTGCAGTGGCGTGATCTCCGCTCACTGCAAGCTCCGCCTCCCAGGTT +CACTCCATTCCCCTGCCTCAGCCTCCCAAGTAGCTGGGACTACAGGCACCCGTCACTATG +CCCGGCTAATTTTTTTTTGTATTTTTTTTAATAGAGATGGGGTTTCACCGTGTTAGCCAG +GATGGTCTTGATCTCCTGACTTCGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGCAT +TACAGGCGTGAGCCACCGTGCCCAGCCTGCTAGGACTTTTAATAAGGCATCTCAGATTGG +GCTTTTAAAAGCCTTGCCAGGCTAGGAAGCCAAGCCGAAGCTTCACCATCATACTTCATT +TGCAATCATTATAGGTTTGGGTGAATTCCTCTCTTTTTGAGGTCCCCCAAAATATCCTGA +CATCCTTGGGCCTGTCAGGAAGTGACTTTCCTTACTCACCTACAAGGCAACCACATGACC +CATGTATTCAAGGTTTAAAACCCATTTTTCCCCAAGGGCTTTATTGGTTCCATAAAGTCA +TCTTAGTTACTTAAAGTTGTCTGGCCATAGCTAAAAATATGGCATTCTAGTCAAAGCTTT +GGTAATATAAACAGCATTTCCAATTGTGTCCTGTTACAAAGAGAACAGGTTCTTACTGAA +CTTATGTAAATAACCATATTGCCATTAAAATAAAAATACTCATGAATAGTTTCCGAATTA +TGGAAGGATAAGGTACAGAGAAAAAGTAATTGTTTCACTTTTGTTTACAAAGGCATACTT +TACCAAACTGCTGTAAGCTATGGATAACTTAAAAGAGAAAAAAAAGTTTCCTTAAATCTG +GAAAACAAAACATTAAAGAACCAGCAATGTTTCAAACAAAACATAAAAAAATTATCCTGG +CTGGGTACAGTGGCTCACACCTGTAATGCTTAGGGAGGCTGAGATGGGAGGATCATTTGA +GGCCAAGAGTTTGAAACCAGCCTGGTCAACATAGTGAGACCCTATCTCTACAATAAAATT +AAATAAATAAATAATTGTAATTGGTTTATTCATTGCCATGTAATTTATTCTTGTTCTGTT +TGATCTTGATCAGCAGTTTCACGAACCCCTCAGTGTCTTCATTCAAGTTCTGGAAATTCT +GGCCAGGTGTGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCAAGGCAGGCAGA +TCAGTTGAGGCCAGGAATTTGAGACCAGCCTGGCCAATATGGTGAAACCCTGTCTCTACT +AAAAATATAAAAATTAACAGGGCGTGGTGGTGGGCGCCTGTAATCCCAGTTACTTGGGTG +GCTGAGGCAGGAGAATCGCTGGAACCCGGCAGGCAGAGGTTGCAGGGAGCCAAGATTGCA +CCACTGCATGCTGGCCTGGGTGACAGAGTAAGACTATGTCTCAAAAAAAAAAAAAAAAAA +AGAGTTCTGGAAATTTTTTTTTTTTTTTTTTGAGACGGAGTGTCAGTCACCCAGGCTGGA +GTGCAATGGCACGATCTTGGCTTACTGCAAGCTTCGCCTCCTGAGTTCAAGTAATTCTCC +TGTCTCAGCCTCCAGAGTAGCTGGGACTAAAGGCACACACCACCACACCCAGCTAATTTT +TGTGTTTTTAGTAGAGATGGGGTTTCACCATATTGGCCAGGATGGTCTCAATCTCTTGAC +CTCGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTATAGGTGTGAGCCACTGCG +CCTGGCCCCAGCCACATTTCTTAAGTAATCAAAAACCTAATAAAAGACAATATGAAGAAC +AAGGAACTATCTTGATATAACACAAAAATCTTTGTTTCCAAGGTCAATTATTTAAAAGGT +AAACAGAGGCCAGGCGAGGTGGCTCACGCCTGTAATGCCAGCACTTTGGGAGGCCGAGGC +GGGCGGATTACGAGGTCAGGAGATCGAGACCATCCTGGCTAACACAGTGAAATCCCGTCT +CTACTAAAAAAATACAAAAAATTAGCCGGGCATGGTGGTGGGCGCCTGTAGTCCCAGCTA +CTCGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCAGGAGGCGGAGCTTGCAGTGAGCCG +AGATCGTGCCATTGCACTCCATCCTGGGCGACAGAGTGAGACTCCGTCTCAAAAATAAAA +AGTAAAATAATAATAATAATAATAAAAGGTAAACAGAAATCTTCATAATCTCAAATACTG +TAAGAAAACTTTGTCATTTCAACAGAGAAGATCAAGTTAAAGTTCTGCATCATAGCACTA +CTAATAAAGCTAATTTTAACAAAACCTTATAAATGAATCCATCCAATCTCATGCAAGATA +ATATTTCTTTTCCAAGATTTCTTTTCTATAGATCTTTTACAACTTAAAAAAAATATCTGG +CCGGGCACGGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGTGGATC +ATGAGGTGAGGAGATCGAGACCAGCCTGGCTAACACGGTGAAACCCTGTCTCTACTAAAA +ATATAAAAAATTAGCCAGGTATGGTGGCGGGCAGCTGTAGTTCCAGCTACTCGGGAGGCT +GAGGCAGGAGCATGGCGTGAACCCGGGAGGCAGAGGTTTCAGTGAGTCGAGATCTTGCCA +CTGCACTCCAGCCTGGGTGACACAGAGAGATGCCATCTCAAAAAAAAAAAATCTATCAGT +ACTTTTTTTCCCCTACATTTTTTTTCTTTCTCATTCTGGAACAACCAGTTGCTATATATA +TTAGCACAGAGTCAGTTATTCCTTTAAGGGATTTTATAAATTAATTTGGTGCTACTATCT +GGAGGTAGAAAAATATCATGTATATATAACATACAAACATACATATGTAGTTGCTCTGCA +ACTGAAGTTGGCAGAGGCCAGACCCAGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAG +GCCAAGGCAGGCAGATCACTTAAGGCCAGGAGTTTGAGACCAGTCTTGCCAACATGGTGA +AACCTGGTCTCTACAAAAATACAAAAAAATCAGCTGGGCGTAGTGGCGTGCGCTTATAGT +CCCAGCTACCTTGGAGACTGAGGCAGGAGAATAGCTTGAACCCAGGAGGTGGAGGCTGCA +GTGAGCCGAGACTGCGCCACTGCACTCCAGCCTGGGTGACCCAGTGAGTCTCTGTCTTAA +ATAAATACATAAATAAATAAACAAACAAATAAATAAAGTTGGCAGAGTATATAGTCTGAA +GGGGTTTGAGGAAAGGGGATTCAGGTGACTGAGAAGTTCCGATGGGAGAAGTAGGATCCA +ATAGAGAGAACAGAGAGGCCTCACAGTGGGAAGAAAAGACTGCCAGCCCAGGAGTCAGGG +AGTGAATCCCCATTCAGAATGAAGAGCCACAAGGAAGACCTTCCAACCCAGGAAGTATTA +TACCTTTCAAAAGAAGGCTGGGACCTTAAAAATCAAAATCTGTCCTTACCAGCTAAAATA +AAAGTTTTTCTACAGTCATGGCTCAGGAGTTTGACTCACCAGTAGATCCCCAATCAGCCA +GTCAGAAGACAAAGGCTGCAAAGTTGCACATTGAGAGTCCTGGGTCAGAGGCCTGTGGCA +CCACAACCATTAAAGAAAAAAATTATTCAGCCCTTGTCAAAGCACGGTCGGGAAGGCCTT +ATTCAGGAGCATTGCCACTGGCATATGGACCACAGGCAATGGGGTTTTGCTGCAGGGGAG +AGATTGGGCTGAACTCTGAATACAGCATGGACAAGTGTGAACTGATAGCCAAGGAGCAGG +GCGGGGGTCAGTGGATGAAAAATTACTAAGAAGAAACATAAGTGATAAGGGGGATACTGG +CTAAGCTGACCTAAGAGGATTCTTGCTGAAGACAGGCTGGGGTGATCAGACATCACCTAG +AGGATGGTGGAGGGATGAGGAATTTCATCAGTATTGAGGGCGATCAGATATCAAAAGCAG +GGTGGTTCTTGCTAAACTGGAATTCTCAGACGGGCCTAGAAGATTTAGGAGCCTGACTAA +AGTTTGGCCAAGCAAATAATCTTTTGTCAATACAACAACACGATACTTTTTACTGTTTGT +TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGAGACAGAGTCTCCTGCTGTCTCCCAGGC +TGGAGTGCAGTGGCGCGATCTCAGCTCACTGCAACCTTTGCATCCCGGGTTCAAGCAATT +CTCCTGCCTCAGCCTCCCAAGTAGCTGCAACTACAGGTGCGTGCCACCATGCCCGGCTAA +TGTTTTTGTATTTTTAGTAGAGACGGGGTTTCACCCTGTTAGCCAGGATGGTCTCGATCT +CCTGACCTCGTGATCTGCCTGCCTCAGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCC +ACCGCGCCAGGCCAATACAATAGTATTAACTAATCTACAGACCTTGTTTGAATTATATCA +ATTGTCCCATTAATGTCCCTTTTCTGAGCCAGGATCCCATCTATCGTCTGGATTCCACAC +TGCATTTTGTTATCTCTTTTAATTGAAGATGGCTCCTCAGTCCATCTTTGACTTGAATGA +TCTCGATACTTGAAAAGCACTGGCTGGTAATTTTGCAGAATGCCCCTAATTTGGGGTTTG +TCTGCTCTTCATTCAGATTCTGCCTTTTGGGCAAAAATACCCACAAGTGAACTTGTGTTC +TTCTCAGGAGGTCCACAGTATGTCCTCTTACTGGAACTAACTTTTTTCATTTCTATTGAG +GCAGAATTTATATACAATGCAATACACATGTTTAAATGGTACAATTTGCTAAGTTTGCTG +GTGACCTTGATGGCTTGGTTAAAGGTGGTGTCGCCCAAGTTTTCTTCCACTCTAAAACTA +CTATTTTCCCTAGGCAATTAGTATCCTGGGGGAGAAACTTTGCAACACTGAAAACAAAAC +AAAACCTGTTTGTCATGTTTTTGCCCACTATTTTTTTTTTTTTTTGAGATGGAGTCTCAC +TCTGTCACCCAGGCTGGAGTGCAGTGGCGTGATCCCGGCTCACCACAACCTCTGCCTCCC +AGGTTCAAGTGATTCTCCTGCCTTGGCCTCCCGAGTAGCTGGGACTACAGGCACGTGCCA +CCATGCCCAGCTAATTTTTTTTGTAGTTTTAGTAGAGACGAGGTTTCACCATCTTGGCCA +GGATGGTCTTGATCTCTTGACCTCGTGACCCACCCGCCTCGGCCTCCCAAAGTGCTGGGA +TTACAGGCGTAAGCCACTGTGCCTGGCCTAATTTTTTTGTAGGGGGTTGGGGGCCGGGGA +CCGAGTCTCGTTCTGTTGCCCATGCTGGAGTGCAGTGGCTGGATCTTGGCTCACTGCAAC +TCCTGCCTCCCAGGTTCAAGCAATTCTCCAGCTTCAGCCTCCGTAGCTGGGACAACAGGC +ACCTGCCACCAAGCCCTGCTATTTTTTTTTGTATTTATAGTAGAGACAGGGTTTCACCAT +GTTGGTCAGGCTGGTCTCGAACTCCTAACCTCAAGTGATCCGCCCGCCTCGGCCTCCCAA +AGTGCTGGGATTACACGCATGAGCCACTGTGCCTGGCCTTGCTCACTATTTTTTCTGGAG +ACGGTCTCGTTCTGTCACCCAGGTTGGAGTGCAGTGGCCCGATCTCAGATCATTGCAACC +TCCACCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAG +GTGCCTGCTACCACGCCTGGCTACTTTTTGTATTTTCAGTAGAGATAAGGTTTCGCCACG +TTGCCCAAGCTGGTGTGGAACTCTTGAGCTCAGGTGATCCGCCTGCTTCGGCCTCCCAAA +GTACTGGGGTTACAGGCGTGAGCCACAGGGCCCGGCCCACTATTTTTATCACTCAAGATT +TTCGTCTACAGCAGCTATTATTGGGGTGGCTACCCAGTGGAAAATTTTTCTATTTCCACT +ATTCCTTCCACATTTATTGACAGGAAAGCTAGTCTAAGGAAGAGCTGTACCCTCACTTAC +TCAGACCCTCGTTTTCCTTTTTTTTTTTTTTTTTTTTGAGACGGAGTCTCACTCTGCCGC +CCAGGCTAGAGTGAAAGTGGTGCTATCTCGGATCACTGCAGCCTGGAACTCCTGGACTCA +GGTGATCCTTCCACCTCAGCCTCCCGAGTAGCTCGGACCACAGGCGCCCGCCACCACGCG +GCTAATTAAAAATAATTTTGGGCCCGGCGCGGTGGCTCATGCCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGCAGATCAATTGAGGCCAGGAGTTTGATACCAGCCTGGCCAACAT +GGTGAAACCCCGTCTCTACCAAAAATATAAAAATTAGCCGGGCGTGGTGGTGGGCGCCTG +TAATCCCAGTTACTCGGGTGGGTGAGCCAGGAGAATCGCTTGAATCCGGGAGGCAAAGGT +TGCAGTGAGCTGAGATCGCGCCACTGCACCCCAGCCTGGGAGACAAAGCGAGACACCGCC +TCAAAAAAAAAAAAAAAAAGAAAGAAAATTTGTAGATACTGGGCTCTCACTATGTTAGCC +AGGCTGGTCTCGAACTCCTGGGCTCAAGTAATCCTCCTGACTCGACCTCCCAAAACTCTG +GGATTACAGGCGCAAGCCACCGTGCCCGGCCGAACCACCGTGCCCGGCCGAACCCTCCCT +GTTTTGGAAATCCTGTATTAGCAAAGGGGACAGCGCCAGACAGTTGAGCACACGCGTTCT +TTATAAATGATGATGTCTGATACAGTGATGCTTTTAACAGGGTTGTGTAACGCCTGTGTG +TGCACGGTCTCTTCTGCAGTGTCCACCGAAGGTGGCCCGTCTGCGTGTCCGCTCCCGGCG +TACTCCGCGCTCCCTGTTCCCGGCATTCCCCGCGCTCCCCGAGCTTCCCGCGCTCCCCTG +CTCCCGGCATTCCCGGTGCTTCCCGTTCCCGGCGCTCCTCGCGGCCGCCGCCCTCAGTCC +AGCGAGCCCCGCCTGGGCAGCGACTGTTAGCGCGACCGCGGCCTGGGCGCCTGGTCCCTC +CCGCGCGGCCGCGCTATTGGGCCGCGCGCGGCGGACACACGCGCTACGCGCCGCCGATTG +GCGGCCTCCGCAGCGCGCTCTGCGGCTCCCCCAATGCGGGGCGGCCGCGCGCGGGGATTG +GCCGCACGCCGCGAAGGCCCGCCCTCCGCTCGCCCGGCGCGGCAGGCGGGTGCCGGCGAC +CGGAGAGCCTGGACAGGCTTTCCAGATGGCTGCGGCGGTCGGTCGGTGAGGCTTTCCCGG +CTGTGGTTTGGCTGCGGGCGGCTTGGGCAGCCCGCGGGCGCCTCAGGTAGGTGCGGGGCG +CGAGGGGCGCCCGCGGGCGGTTGGGCGGGCGCCGCGGCCTGCGCGAGGGCGCGCCCTTCC +CTCCCGCCTCCCTCCGGGACCGAGGCCGCGGGCGGGGCGGGGGCGCGGAGCCCGGCCTTT +GTGAGGCAACATGGCCGCGGGCGGTGGAGAGCGCGGGGTGGGGACGCCTCCGGGGCTGGG +GGGCGGGCCCCGGGCCCAGGCGTTGCCGACTCTCGTCGCTGTCCGCCCGGGTAAAGAGGC +TCCTCTCCCGGAGGGCCCGAAGCCTAGCATCGCCTTCAGGCGGGAAAGGTGTGGACAGGG +CCAGTGCTCGCCTGGGACCCTGCCGGCTTTAACACAGTTTGGGAAATCCAAGAAGTCGCC +TAAGTCTTTTTGTCCACAGAATGCTCACGGGTTGAGTGTCACGTAGATAATTGGGATACG +GTTTTATTGTAACAATGAGCATGGCGGAAATAAATGGAAGGTGGCAACCTGTTGACAGTG +ATGCCTGTCTGGTGTCAACCGATGGACTTGGGTTTCTTGTGGCAGGAGTCTGATTTGCCT +TTTTGCATGCTTGCATGTACCTTGTTCCTGCACGGCAGTCCTGTCTTTGGCTGTCGACTG +TTCGAGGCCAACCACCAGGCGAGGATCCACTGTTTCCTGGCCAGACTAGACTCCCAGCTG +TGGGAGTGGCCCAAACCCTGCTGCAGGCCTTCACTCACAAAAGGGAGTGAATGGCCAGCC +CGGGGTACCCAGTGTTGCCTCTAAGTGCGGGATATGAGGCCTGTTGGAGGATGACAAAAG +GAACGGATGAGGTCATACTGCCGCTGGGTTGGGCGGGAGGCTGCAGCGGGAGAGACTTGA +CCAAAAGGCAGCCTCCATGGCGCTGGCACTGGTGCTGGCCCGTCACAGCCAGTGCCTCTG +TTAGCCAACACAGCAAGTGGGCTAGGAGGAAGGGTGCTGTCCAAGTGTACGGGTTTTCTC +CCCGTGCCAAGGGTCCAGGGGAGCTTGCCGTGAGCCCGTTCCTGTCCGATAGTCCTGTTG +GCAAGGCAGGGTTTGCATGCGGTGTTTGGTCAGCTGGAGCAGTGGGGAGGCCTACGGGCA +GAGAGCTCCCCTTTGAGCCCTTTGCGGCCAGGCGCTGTGTGGAGCACTTCCCAGGGGTTG +TTTTGTAGTCTCACCGTGACCTTGGGGTAGGAAATGTGCTTCTGGCTGGCTTGCCCAGTC +TTAGACTCTCTTGTTGTAGCCCTCTCCTTTGTGATGTCACCCAGCCTCCTGACTTTAATG +CCAGCTTTCCTTGACATCTTCACAGCTCCAGCCCTGGCCTCTCTTCTGATTTCCAGCCTG +GTGTTTCTGGCCACCTCTTCCATATCTCCATGTGTTACTTTGGCGCCAAGTAGCCATATC +CAAACCAAACTCAAATCTTCACCCATGCCAAAACATTCCTTGGCCTATCTAAAGTCCCTT +TGATTCCTCTCTTTCTTACACCTTCATGCAGTCCTAAGGAGGCCCCGTCAGCTCACCTAT +TTCTAAGCACAGACCATTTCTCACCACCTTCAAGTTAACATCCTGGCCCAGCCTACCTGG +TGAGCCTCTAATTCTCTTTACTGTCACCTTAGGTCCTCACTCCCCATCCACCATCTATAG +TTTTTCTGGACACAGAGTGATTCTTCTTTCTTTCTTTTTTTTTTTTTTTGTTTTTTTGAG +ACAGAATCTCGCTCTGTCGCCCAGACTGGAGTGCAGTGGCGTGATCTCAGCTCACTGCAA +CTTCTGCCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCAAGTAGCTGGGACTGC +AGGCGTCCACCACCACCACGCCCGGCTGATTTTTGTATTTTTAGTAGAGACGGGGTTTCA +CCATGTTGGCCAGGCTGGTCTCGAACTCCTGGCCTCAAATGATCTGCCTGCCTCAGCCTT +CCAGAGCGCTGGGATTACAGGCGTGAGCCACTGTGCCTGGCCACAGAGTGATTCTTTTTA +TTTTTTTGAGACAGAGTCTCGCTTTGTTGCTCAGGCTGGAGTGCAGTGGTGCGATCTCCC +GCTCACTGTAAGCTTCGCCTCCTGGGTTCAAGCCATTCTCCTGCCTCAGCCTCCCGAGTA +GCTGGGACTATAGGCGCCCACCACCACACTCGGCTAATTTTTTGTATTTTTAATAGAGAC +GGGGTTTCAATGTGTTAGCCAGGGTGGTGTCGATCTCCTGACCTTGTGGTCCGCCTGCCT +CAGCCTCCCAAAGTGCTGGGATTACAGTCGTGCACCACCGCGCCCGGCCCAGAGTGGTTC +TTTTAAACCATAAGATGGTATAAAACAGAGGCGGTGTAGATGCAAGCCAGCTTGCCTGCT +TGTAAAGCAGCTCCATCACTTCCTGGCTGTATGACCTTGAGCATGTGGGTGAACCTTTCT +TCCATAATGCTATGTGAGACCTGGGTGAGTTAAAATGCTTAAAGTGCTTAGAACAGGGCC +TGGCTGAGGTTTGGTTGCCACTGCTATCCTGGAATCAGCTGATGCCACTGTGTGGGCCTT +CCTATCCGGTGGCCCATCTCTCTCACTAAGAGCCAAAGTCCTGGCAGCAGCCTGGGAGGA +CCAGCCCTGATCCATCTGCCCTCATGGACTTGGCCCACTGTCACGTCCCCTCAGCACACT +GCCCCAGCTGGCCACACCACATTCCTGACCCCAGCCCTCTGCTTTTCCTCTCAGTGTCAC +CTGGAACATCCCCTCCTCCCAGCCCTGTAACCCACCTGGCTCACTCCTGCCTTCACGTGG +ATGCAGGCCATGAGGCCTTCTTGGATCCCCCTTCCTAAAACTGCCTCCCCTTCTTCAGGC +GCTTTCCTTGTTTTGTTTTTGCTTGAATACTTCTTGGCATGTGACAGGGTGCATGCTTTT +CTTAGTTGTTAGCGGTCCATCTCCCCCACTAAAATGTGAGCTCTGTAGGGCAGGGTTTTG +TCCACCTTGTGTCTGTAGCATCTAGGATGGTGTGTGTGTGTGTGATGAATGGAGAAAGCT +TATAGAGGGGAGGAAGGAACTTGCCCAGGACTGCCCACCACTGAGGTCTGGGGCTGGGCA +GGTTTCCTGCTTTCCTAAGGAGCTCACTCACTTGTAAGGCACCAGGCTTTCCTGCTGTGC +ATTTCTTCAGTGCCGCCGCTTGGCCCCATTAGCACCTTTGCTTGGAACGTCTACTCTAGC +TGCTTCTTCGCCTTCTGTGGTAGCAGGCTTCCCCATTCCGTCCCACTGTTGGTCTCTAAT +CCCCTGCTCCTTGTGGCTTCTTCATGTAGCTTTTTGTGTCCCAGAATCATGGATTGACTC +ACCAGGGTCTCTATGGGACTGCCAGGTTCTGAGGTGTGTGGCCCTGGTCTTCCTTGTAAT +CTGTGGCACTGGGCGCATTGACCCCTCGGTCTGTTTTCTCTAATGGTCTTTCTTGGTTGC +CAGGAGACTGACCTCACCCCGCTTAGTGTTCCTCATGCCTGCCTGGTTGCTGCCCACAGC +CTCTTGAGCGTCTTCAGCACTTTATAGTCAGTTGTTAGCTCTGTGCTGTGTTTCCTGGAT +CCTCAGCACCTTTGATGGACACATCTTTGGGAACATACGGTGTGAAATTCCCATTAGATT +CAGAAATGTTAGGACATCTTAGAATCCAGGAAATGGGGTGACAGTGCAGTGGTCATTGAC +CTGCCAGTGTGTCCAGGCCCTGTGACCTTGTCTCTTGTCCATATAGTGCGTTCCTCGGAG +TAGATGGCCAGTGGATAGTTGTTAAATGTATTGATTAAACCTAAACTAGTCTCTGGTTTT +CATGTTGTGTCCCCTTCGAAGTACATCCACCATGCCTTGTCCCTTGTTAAATGTGTGATG +TCTGCATCTCCTGTTCTTTCCGGGAATCTTGGGAGGATGTTAGGTCATGCAGTGCGGTTT +GCATGTGTGCATCTTTACTGGTATGCACGCATGTGCATGCATGCGTGTTCCTGTGCACGT +TGTGGGAGTGTGCATGTGCGTGTGTCTGCATGTGTTCCTTCTGCTCTGATGCAGGGTTTT +CTGGCTGCCCCCTCAGACCCATCTTCCCTGCTTCATGTTGTCCCTTTCTTCATGCTTCCT +CTGTAGTAAGGCTTCCTAGAGTTGCATCCTTAACCCTCATCTCTGGGTGGCCTTCCTCCT +GTGGGTTTGGCGACTACCTCCTCAGTGCGTCCTGGCCTTCCGTATCTGGACCAGTCATGG +CTCCAGAGTTGTGGCCTCGGCACCTTCAGAGCCTGCCTGGAGGTCCCCTCTGTTCTCCTC +GCCAGGCTCCTGCCTGCATGCTGGAATTTGGGTGTCCTTCCTTGTCTTTAGTTCCCTCTT +TTCTCTGCTATCCACCTCCGTTGGGTCAACAAGTGCGGTCAGTTCTGTGACACTGTTCTT +GGCCCATTGCCAGGGCCTCTTTCACACCTTTGTCCTCTGGCCTGGAGGACTGTCCCCGTG +CCTTGGATGCAGTTGCTTCTGCCTGGCACAGCTGTGGGTCTCCCCTCTCAAGTAGGAACC +TACTTGTGGCATGAGAGTCGCTTCACCTTCAGTGGCTCCTTATTGTCCCCAGGGCGGAAC +GGGCTGCAGGTGGCACCCAGGCCTCTCTGTGCCTCGGCTCCAGCTGTCTCTTGTGGCTCC +CCACCCCAAATCCTGGCAGGTCCCTTCCCCACAGCCACCCACCCCTCTCCTCCATCGGGA +ACAGAACTATGCTGCCACCTCTGGTGACCTCAGCACGCTGCATCACTGTCCCCGTCCACG +TGCTACCCTGTGGGCCCAGGAGAGCCCTGGGGTCCCTGGGTAGCAGAGCGCCTGGCCATG +CCTCTGAGGCCCCTAGTGCCGCAGAGTTGAGCTGAGGGTCTCGCGCTCGCCCTCTGACTG +ACCCAGCCCTTGCAGGTGAGTGGATTGCTGTGCTCTGGTGGCCTGAGGGAGGCCACGCGC +CTTCTGTGTGTTCCAGAAAGGGTGCCTCCCACTGCATGCTTGCTTATCTGAGTTAGAAGA +ATGCTGTGGTGGAGTTTAGTGTAAATTTTTAAAATATTTTTTGAGCCTTATGATTATATA +GTTTTTGTGTTTCTGAAGTAGGAATTAAAGTGGGCATTAACAAAATATTTAACTTTGGAC +TTAAGTTATAATTCAGGTTCTGAAGAATAAAAGTAAGGTTAGTTTGTTTTGATGCCTAAA +AAGTCCTCTTAGGGAATATTATTTTGAAGCCCTTTACTATGCTGTTAATAGTGCTTGGCT +TTTAACTTGGTACCAGGGAATTGGAAGGTTTCTGTCATTTTGTGACGATATTTTTAAATT +TCTTTGCAGGTAGAAGAAGAAAGGTGCCACTCCGGCATGAAGACAGACTCGCTTAGTCGC +CAGTCACTTAAGCTGAGTGCATTGTGATTTCCAATAATTGAGGCAGTGGTTCTAAAAGCT +GTCTACATTAATGAAAAGAGCAATGTGGCCAGCTTGACTAAGCCGCCAGCGCACAGCGCG +GCAGGACGCGCCCGGGTCTCAGCGGACTTGTGCATGTTAGCTGTGTAGATTTATGTGAGG +GCTTGTAAAACTCTGGTCTTGTAAACTAGTCTTAAGCGCTTTTAATATGGAGACAGATGA +GAGCCCCTCTCCGCTCCCGTGTGGGCCCGCAGGAGAAGCGGTGATGGAGAGCCGAGCTCG +CCCCTTCCAAGCGCTGCCCCGTGAGCAGTCTCCACCACCTCCCCTGCAAACGTCCAGTGG +TGCAGAGGTAATGGACGTTGGCTCTGGTGGTGATGGACAGTCCGAACTCCCTGCTGAGGA +CCCCTTCAACTTCTACGGAGCTTCTCTTCTCTCCAAAGGATCCTTCTCTAAGGGCCGCCT +CCTCATAGACCCGAACTGTAGTGGCCACAGCCCGCGCACCGCCCGGCACGCACCTGCGGT +CCGGAAGTTCTCCCCTGACCTTAAGTTGCTTAAGGATGTAAAGATTAGCGTGAGCTTTAC +CGAGAGCTGCAGGAGTAAGGACAGGAAGGTGCTGTACACAGGAGCAGAGCGCGACGTGCG +GGCGGAGTGCGGTCTGCTCCTTAGCCCTGTCAGTGGGGACGTGCATGCTTGTCCCTTTGG +CGGGAGTGTTGGTGACGGGGTAGGCATAGGGGGTGAGAGTGCTGATAAGAAGGATGAGGA +GAATGAGCTGGATCAGGAAAAGAGAGTGGAGTATGCAGTGCTCGATGAGTTAGAAGATTT +TACTGACAATTTGGAGCTAGATGAAGAAGGAGCAGGCGGGTTCACGGCTAAAGCAATCGT +TCAGAGAGACAGAGTGGATGAAGAGGCCTTGAATTTCCCCTACGAGGTATGTTGGCAGCC +CCTCCTCTAGAGGGCTCTTAGCAAAACCCAAAGAGAGATTTGGGAATTGCAGCATCTTTT +GAAAGCAGGGAAATTAAAAAAAAAAAAAACAAAAACCAAAATCCCCTCTGAGGTGGAATA +ATGTTAATGTGGAGAAGAGAAAGATGTAAGGAGTCCAGATTTTTAAAGTTTCCTAATGAA +AAGTTTGGCCCATGGGTAGGCCCTGCATCCCTGATCTAGCGCGTGGGGCAGCAGGTGCTG +CTGAGTTACGCTCCTTGGCAGTGTGTGCCCCTGGACCAGGTGTGTTGGTGTCAGCTGGTA +GCTTCATCCTGTTTGTTTTTCAGATGATCATGCACCCTAAGGGCACATCTAGGCCCCCTG +AGAGCACCTCCTTTCTGTGTCTGTTCTCAGGAATGCTGTTGAGCTCTCCTGTTGCAGGAG +CATGAGCGCCAGGGGCTCTGGTGTCTGAACAGCGTGTTTTGCAGGATGACTTTGACAACG +ATGTGGATGCTCTGCTGGAAGAAGGCCTTTGTGCCCCCAAAAAGAGGCGAACAGAGGAAA +AATATGGCGGAGACAGCGACCATCCGTCCGATGGAGAGACAAGTGTGCAGCCGATGATGA +CCAAGATTAAAACAGTGCTCAAAAGTACGTGTGTGGGTCAGAAGCAGTGGGTGTTCCAGG +GCAGTGGAGGGGTGGTTGCTTCCTTAGCAGAAATGCTTTGAGAGAGCTCTGGTGCCAGGT +AGTGGGCTGGGTGGAGGCATGTTTGAGGACAGGACAGAAATATCTGAGGAGGGAAACACA +GGATGGGAGGACGTCCTGATGCATGACCCAGATGCGGATCCTGGTGTGTGCTATGGAAAC +CACAGAGCAGCAGGCACTGTGCAGAGGAATGGGAGGGGACTTCTGAGGGGGTCAGGAGGG +GATGTTGGTATATGCCAGGAGCCAGCATGACCATCAGCTGGAGGGTGTGGAGACCAAGGG +CAAGGTGGGTACACAGTGAGATGGCAGGTGATAGTTGTGATCCAGGTTCTAGTCCTGGAC +CAAGTGTCACAGGAAGCCACCAGAAGCAAGTGGTGTTACCTGATTTTTGTTTAACAACAT +GGCTTCTGGGCCACAGCATGGTGTGTGCACTTCAGCTGGGCAGGGTGGAAGTGCCCTGGT +CGACGTGGCACTTCCTCAACTTTGAGTTGAGGGTAGTGGGGAGAGCACTTGAGAGGCGCC +CAGAGTTGCACTGTGAGGCTCTGTCATCGATGTGGTGCAGGTGTTGGGGGAGTCGGAGTT +GGTGGCTTGGAGGCACCTATGAGGGTCCTGGTGGAGATGTGGGGCTCGGTAGAGGGACTG +AAGAGATGCACGGGGACTCAGGCTCACAGGTGAGACCCCAGGCTGAGGGCTGGGGTGCAC +AAGGTGGCAGGGTGCGACTGGGAGCAAAGCAAGGGGCGGGTGGCACATGGCCATCCTCCT +TGGGCCATTGAGGGGACAAGTTAGCTATGCCAGGTGCCACATGTTGCTGCCTATGTCGTG +TTGGTAGCAGTTAAGCAGGAGGGCTTTTGGTCTAGACGGTTGCAGGCAGGGTAAACCTGG +GGCTTCAGCTTCTGGGGCTGGGGGCAGGAGTCTTGACCTCGGGGCCTCTAGGAGGCTGGT +TTGGTGCTGCATTTTCAACAGGCTCATTCAGAAGGTAAACCCACATTCGTCCTGCACAGC +TCACTGGTCAGCAGCCATTCTGGCCTGGATGCCTGGATGTTCACAGACGGACAGCTGCAT +GTGACCCCCACCTCAGGTGGCTGGGCCAACTTTGTGACCACTCACTGTCACAGAGGAGCA +GCCCCAGCGGACCCGTGGCCCGTCTCTTGCTTGGCTCCGTATTCCCTTTGCTTCTTTTCC +TGACTTAACCTAAAGCTGGCAGGAGGCAGCTCCATCTTGGCCTGACTCTGTGGGGAGAGA +GCCCACGCAGTGTGCATGCACCCCTGACCTTTAACACTCCCTCCCTGAATCATCACCTGA +TGGTGGCCTGGGTACAGGTGTCAGGTCCAGGGTCAGGGCCACTTGGTGGGTACCTAGCCC +TGAGAGTCACTGGCCCTTTTTCCCCTTATGTATATTTTTTAAGGTTTCATTTGCTTTCTT +CTGTTTTTTAATTTTTTTTTTGAGGCGGGGTCTTGCTGTTACCCAGGTTGGAGTAGCTCA +CTACAGCCTCAGCCTCCCAGGCTCAAGTGATCCTCCCACCTCAGCTTCCCAAGTAGCCAG +GACTATAGGTGTATGCCACCATGCCTGGATAATTTTAAAAAGTTTTTTGTAGAGTCAGGG +TCTTGCTGTGTTGCCTAGGCTGGTCTTTCTAAGTTTTTAACTTGTTCCCAATACCTGTGA +GAAAATTAAGTTTTAGTTACATCTTTGCCTTACGCTCTTCCCAGCAGTCAGGCCTGGTGG +CAGGTGTCAAGTTGATAAGTCGTAAACCTCTTCCTCACAACTGCCTATAAAGCAAAGAAG +GGGTTGGGAGTAGTGTATTAAACCAACTTAGAAACGGAATCATTTGAAGCAGTGTTTTGT +ATGCTGCTGAGAGTGCAGCTCAGTTACAATAAAGACTTGTCACCTGGTCACTGGGAGCAG +TGGCTGACAGCCATGCAGTTTATTAGCAAAGCTCATCCAGCCCCAAGGCGCCTCTGGCCA +CAACCAGACAGGCAGCAAAGGAGTCCAGTGTCCACAGTGCTTACCAGATGTGGAGGCAGG +AGCTGAGGCTGGGACTTATATCTTGCACAGACCTGTTCTGTGCTCCTTCATGTGCTGGTT +TGACACGTGTAAATTCCCACCTCAGGCCACATGCTATCTGTCCTAGGCCTGGAGGCATAG +CAGTGAGCAAGGCAGAGAGGAATTTCGATTATCTGTGAAGACCCAGTTAAACACATGCTA +GTACCCAACAATTTCTTGTGCAGGAGGTGCTGTGGCAACAATTCCAAGTGTTTTTACAGT +GATTATAGGATGTTCTTGTCTTCCTGTGCAGGTCGTGGCCGCCCACCTACAGAGCCGCTG +CCCGACGGGTGGATCATGACATTCCATAACTCTGGAGTCCCGGTGTACCTACACAGAGAG +TCTCGGGTGGTCACCTGGTCCAGGCCATACTTCTTGGGAACGGGAAGCATACGGGTAGGG +GAGGCATCAGTCGTGACTTTAGGCTTGTAAGTTCTCAGACCAAAACGTGCACATCCACAC +ACATGGCACCGCAGCCAAGCAGAGGCCGGTGAAAGGCATCAGAGTTTCAGACTCTCGGGT +TGTCCTTGTAATCCATATTGCAATTTCACTATCCACAGAAACACGACCCTCCTCTGAGTA +GCATCCCTTGTCTGCATTATAAGAAAATGAAGGACAACGAGGAACGGGAGCAAAGCAGTG +ACCTCACCCCTAGTGGGGATGTGTCCCCCGTCAAGCCCCTGAGCCGATCTGCAGAGCTGG +AGTTTCCCCTGGATGAGCCTGACTCTATGGGTGCTGACCCGGGGCCCCCGGACGAGAAAG +ACCCACTAGGGGCTGAGGCAGCCCCTGGGGCCCTGGGGCAGGTGAAGGCCAAAGTCGAGG +TGTGCAAAGATGAATCCGTTGGTGAGTTTTTGAAGGACTCTTCCCTTCTTGCCTCCTGGG +ACCCATGAGCTTTGTTTTTCTAATGAAGGCCATAATTGTTCATAGTTCCTAGTTGTACTT +GTGAGCAAGGGGCTGTGCACCTCCACTGTTGGTGTGGCTGAAAGGCTTGTCTTCCTGTCC +TTGCAAGAACCTGCCTGGGTGCAGCACCCTAGGCTCCTGTCTGTGGGCTCTGTGGTGTCT +GCATGGCTGAGGCTGCTGGGGAGATGGCTGCTGGCACTGGCAGTGGGCCGTTTTCTCTCT +GGTTGTTTGTATGATCTTTCCCTAAGTCTTGCTTTTTCAGTAGGATGTGCTCATGTGGCA +TTGTTTTGATTTGTCTTGATGAGCTCAGTGAGCCTCTTTAATCCATGACTCAGTGTTGGG +AAACTGTCACCATTCTGTGGATAGTTCCCTCTTCAATCCTGCAATTGCTTGCTGGATGTG +TACTGGTGTTTCCCATTCTCTCTTCCATGTCTTTTAGCCTAGTCCCGCCATTTAAGTCTT +AGTTCTCTCTTCAGGTGTGGCAGGTCTCTGTGAACCCACCTGCTGGATTACTTTCAAAGA +GCACTTTCCATTTTCTAGGTTTCTATTTGTCTGTACATCACTACCCAGCCTGTCTCATAA +CTCCGTGGAGTGTGGGGTGCCCTAGAAGAGCCTGTGATGGGGGCTGTTGCTGAGGATGGG +GAAGTGGCCCGGGAGGAAATGTGACAAATGCGAGGCCCTGTGCAGGGAGCTGCCTGGGTG +TGTTGCTGACTACAGAGGTGGCCAGGATGGCCAGAAGGAAAAGAGTGAGGTGGTCAGAGA +GGTGGCGGGCGCATGGAGCCCGGGTGCTGCTGGCATTCGGGCACCTGTTTTGATACAGGG +AGGAAGTCCCGAAGGCCATCTGACTTTTTTAAGCTGTCTTTTTTCCTTTTCATTTTTGTA +TTCTTCCTGCCCCAAATAAAGTAAAAGAACATCTCAGAAATTCATCCAGAAGGGACCTGC +CAGAATAATCTGAGCTGGTGTAGGGAGGCCTTCATTCTTTGCTTCCCTCCCCTTTGAAAG +GGACGGGGAAAGGAAATAGTGTCATGTGGCCTGGGCCTGCCCCATGCACTGGGCTGTGAG +AACCTGACTCCTATGTTGGAAGTTAAGTAATTTGTTTCTCTGGTAAATCTGGGACAGATC +TCGAGGAATTTCGAAGCTACCTGGAGAAGCGTTTTGACTTTGAGCAAGTTACTGTGAAAA +AATTCAGGACTTGGGCTGAGCGGCGGCAATTCAATCGGGAAATGAAGCGGAAGCAGGCGG +AGTCCGAGAGGCCCATCTTGCCAGCCAATCAGAAGCTCATTACTTTATCAGTGCAAGATG +CACCCACAAAGAAAGGTATAAGCCTCTGCATTTTAACATCAGCAGACTGGTTATGCTGTT +ATTTCTAATGTGATGTGTTGAGGGCATGTTTTATGAGTTGCATTTCGTTCAAAGTTTATG +TTTATCCCATGAATGCAGGGGTCTGCCACATTCACGGTCGTGAGCCCCTAGTTACTGACA +TGGTAACAGGAAGCTGTGTGCTAGCTTGTGGCACTGCTTCACACTTGCTGAGATGGTTCT +TTTTGTCACAGAGTTTGTTATTAACCCCAACGGGAAATCCGAGGTCTGCATCCTGCACGA +GTACATGCAGCGTGTCCTCAAGGTCCGCCCTGTCTATAATTTCTTTGAATGTGGTAAGTC +TAACCTTCCCCATTTCAGTCCTAAAGAATCACAAGGTGTAACTTTGGTCAGGGCTGGGGA +GGCAGGCGCTGACCGCTAGCCCTACTCTACTGGAACGGGAGGAAAGGGAAGGGTAGAGAG +CAGCGTGCTGCAGATGGGTGGCTTGTTTCCTGGAGCCGCGCCCCATCTGAGTGGGTGGCT +CTGCTTTTCCCTTCCAGTCTGTCCCCTCTCCCCACCTTCCTCTTGTCCTGCCCCATCTGC +CTTGCTGGTTTCTGATCCTGCGTTGTCATGGACAGCCTTATTGCGAGCAAGGCCTCCCCA +CTGTGCACTGGGTCCTTTCCCTGGTCTCCTGGTGCCCCTGGGTGTCTGAAGGGTTCTTGG +GCATGCATTTCCCACCAGCTCTGTCTTCCTTGGGTGCCCTCATCACACCTTTGTGAAGAC +CAGTCTGTCTTCCCCTTGGAAGCTGGAGCCTGGGGGTCACTCATCCTTTGAGGTGGTGTT +TCTTTGGCAAGCCACATCTTGTGCTTTCCCATTCCGGCAGTCCTGTGTCCGTCTTTCGTA +GACCTTGGTCCCTGTCGTAGGAGGCTCTGCCCCCAGCCTCCTGCTGCCCCTCTGGCTCAC +CATCTCCCACGTGCCTCATTTCCCTCCACTTTCCCAGCTGTGCCCTTTGCTGCTGCTTGT +CTGCTGCCCGTCTCCAGTCCCAGGGAGCCCCAGGTCTCTGCAGTCAAGCACAGGCCCACT +CTCTGCAGGGACAGCCCCTGACTGCGCCTTGTCTGTCGGTGTGGGCAGACTGTGCACACG +CTTTTGATGTCTTGACTCGTATGTTTTAAAACAAGTAATTTTAATTTTAAGAGAACCCAA +GTGAGCCTTTTGGTGCCTCGGTGACCATTGATGGTGTGACTTACGGATCTGGAACTGCAA +GCAGCAAAAAACTTGCGAAGAATAAAGCTGGTAACGTGCTTGCTTGGGTGTCAAAGATAC +GTGCTGCCTGCTGTGTCTGCCTCGCTGCTTGGTTAGGGAGGGGCTGAGCAGTGGTGACAA +GTGGGGGATGTGGGTGGGGCATGTTTATTTTATTTATGTAATCATCTACTTTGATTTTTA +AAATTACATGCTCATTGGAAAAGACTCAAATAGAGCAAAATGTGAGACTTAAAAGTAGAA +GGCCTCGGCCGGGCGTGGTGTCTCATGCCTGTAATCCCAGCACTTTGGGAGGCTGAAGTG +GGCAGATCACGAGGTCAGGAGATCGAGACCATCCTGGCTAACACGGTGAAACCCTCTCTC +TACTAAAAATACAAAAAATTAGCCGGGTGTGGTGGCGGGCACCTGTAGTCTCAGCTACTC +GGGAGGCTGAGGCAGGAGAATGGCGTGAACAAGCGAGGCAGAGCTTGCAGTGAGCTGAGA +TCGTGCCACTGCACTCCAGCCTGGGCGACAGTGCAAGACTCTGTCTAAAAAAAAAAAAGT +AGAAGGCCTCTCTACTGAGTGACAGCTGGGCCAGTATGTCCCTCCCTAGTCCTGGCCCTG +CACATATTCAGGGGTGTGCCTAGAGCCAACTGGGCTGTGCTGGGCACATGCTGTAGTGCT +TGTTTGTTTTTAAACTGAGCAGCATGTGGGCATGCCAGGAGGGAGGAGAAGCGGGCCAGC +ATGCTGTTGGCATCCTCCCCCAGTGGTGCTGGCTCTTACCGGCACTATTTCCTGAGTCCT +CCCACTCCATGTTTGGGCCTAGCCACACAGAACACCTGGCACAGCGCAGCTCTGGGAAGG +CTGTGTGTCCTGGCGAAGACCCACTGCCCTTTTGGACCATGCCCTTGCCGTTTGCATTCA +TGCCCTGCATTCGTGGTAGTTGACATTCTTTCACAAAAAGCCATTTGCCTCAGCGTCCAG +GGTTAGTTGGCTTCTTGTAGGGTGGTGTTGGGTGTACCCCAGGCCCTCGCACCCACAGGT +TGATTCTCGAGGTATCTGTCATTGCCGTGTGTTTTCCAGAAGGCCTGCTGCCCATCTTAG +ATTCTGCCTAAGAGACTTTTGCAGCTCAACAAAGGGGGTGTGGTGGAGGTTTTGACAGAT +AACTTGCAGTGGGGCCTTTTGTGGGGGTGGAGATGCCTTGGGCGTGGCTGTGTGCTCTTC +CCTCTGCGGGATCACCCGCTTTCCTCCCTATGTGCTGGAACCCACTTCCCTTGCCCAGAC +TCTTGGCTGCCCTATAGACAGCTTGGCTCCATGTCTTGCCAGCACTGATAGCTCTGTGGG +GTCTATGGAGCCATCAGCCCTTGGCTATGGCAACTCCGACCCCAGTGGGCATATCCGTGC +CCTGCCCTCTAGCAGCTCCCTCTAGCGTCTCTCAGACCTGGCTGCATCTCTCCACCCACG +CCAGCCACTGCTGCTGCCACCTGGTCTAGGTACCTGCAGTAGCCTGCTCTCAGGCCTCCC +TGCATGGTCCAGGGCCCGCAAAGCTGTTTTCTCACGTGCCACCGAAGTGGTTCCCTAACA +TACAGCTCCGAGCTCCTCCCTGCCTGCTCCCAGGACCCCAGGGTGAGAGCGCACACACCC +AGTGTGGCCCGTGAGGCTTTCTGGTAGCCTGCCACACGTCTGGGCTTTTCCTTCTGTCCT +CTCCTGACCCTGTCACTGAAGTGCTGTCTCTCCTCAGGGCCCTCGCTCAGCCTCTGAGCT +GTGGGGATGGGAGGCAGCAGTGCACAGTTCACTCTGCAGGGTGGTGAGAAGAGGGCAGTG +CCCAAGCCTCACCCTCGGGCTCTTTTTTTTCATAGCCCGAGCTACACTGGAAATCCTCAT +CCCTGACTTTGTTAAACAGACCTCTGAAGAGAAGCCCAAAGACAGTGAAGAACTCGAGGT +GAGTGTTGTGGTCCTGCCCTGCTGGGAGCTGTGTGTGCAGTGCGGCTACCCTGCCCTGTT +AGTGTGAGCTGGGGGTGTCCGTGGGCTGTGCTCATGCCTTCCATGCCCTGTAGGTTAGTC +TCATCCAGCCTCCAGGTTCTTCTGTTTGTATTTCATAAAGAGGAAACTTGCCTGTCTTTG +TATAGGCAGGGAAAAAATGTCCTTTTTGTTAGAGATTTTTGTCCTCTTTTGCAGCATTGA +GTGTGCACCGTAAATGTCGGGTACACATAGGTTTGTGATGGGAATGAATCTTTGAGGCAG +TCTACAAGATTTAGATTGTTCTTTTTTTTGAGACAAAGTCTTGCTCTGTCACCCAGGCAG +TGACAGAGTTTGATCTTGACCCACTGCAACTTTCACCTCCCGGATTCAAGTGATTCTCCC +ACCTCAGCTTCCTGAGTAGCTGGGATTACAGGTGTGTGCCACCATTTCTGGCTAATTTTT +GTATTTTTAGTAGAGATGGGGTTTCACCATGTTGGCCAGGCTGGTCTCGAACTCCTGACC +TCGGGTGATCCACTCGCTTCCGCCTCCTAAAGTGCTGGGATTACAGGCATTAGCCACTGC +GCCCGGCCCTAGATTGTTCTTTATATACTTGACCCTTGAGTAACGTGGAAGTTAGGGGCA +CCAGCCTCTCACGTGGTCGAAAATTCACGCATCACTTTCAGTCCTCCCAAACCTTAACTA +CTTACTGGTAACCTACTCTTGACCAGAAGCCGTACCAGTAACAAACAATTGATTAATACA +TATTTTGTTATGTACATATTACTACATCTGTCCCCAACCTAGTTTTGGCACCAGAGATCA +GTTTCAGGGAAGACAATTTTTCCACAGACGGTGTTGGGGGGCGGGGATGGTTTCAGGATG +ACTCAAGCACATCACATTTATTGTGCACTTTTTATTTCTATTATCACTACACTGTAATAT +GTAATGTAATCACTATACAACTCACCATAATATAAAACCAGTGGGAGCCCTGAGCTTGTT +TTCTTGCAACTAGATGGTTCCCTCTGATGACGATGGGAGACAGTGACAGATCATCAGGCA +TTAGATTTGCATAAGGAGTACACAACCTAGATCCCTTGAATGCACTGTTCACAATAGGGT +TCACACTCCTATGAGAATCTAATGCTACTGCTGATCTGACAGGAGACAGAGCTCAGGTGT +AAAATGAGTGATGGGGAGCAGCTGTAAATACAGATTAAGCTTCACTTGCTCACTTACTCC +CCCTGCCCCCACCACTCATGTCCTGCTATGCAGCCCGGTTCCTAACAGGCCATGGATTGG +TACCAGTCCATGGCCTGGGGGTTGGGGACCCCTGATATATACTGTATTCTTACATTAAAG +TAAGTTACAAAAAGAATGTTATTAAGAAAATCATAAGGAAGAGAAAATTTATTTACTGTT +CTTGAAATGGAAACATCATCATGAAGGTCTTCATCCTCCACATCTTCATGTCGAATAGCT +GAGGAGGAGGGGGAAGAAGAAGAGTTGGCCTTGGTATCTCAGGGGTGGCAGAGGCAGAAG +AAAATTTTTGTATAAGTGGGCCCATGGAGTTCAAATCCATGTTGTTCAAGGGTCAGCCAT +GTGAAGAACCATTTAAAACTAGCTGTAAACCTTTTTGGGTAAATGGTTATTTGTAGCAAG +GGCTTGTGGAATTTTGAAGGGTGCATTCTTATTTATATAATAGCTTTATTGAGATAGTTT +ACATACTATAAATTTGGCCTTTTAAACTATATAAGTGGATTTTTATATATTCAGAGTTGT +ATAACCATCATAACTACCTAATTTTAGAGTATCTCAACACCCCCAAAAGAAACTCCATAC +CCATTAGCATTCCCTCTTAGTTCTCTCCAACCACCAAAAGCCACTAATCTGCTTTCTGTC +TCTATATATCTGCCAACTCTGGACATTTCATATTAGCGGAATCATACAATATGTGGTCTT +TTGTGACTGGCTTCCTTCACTTAGTGTGCTATGTCAGCTGTAGGTTTTTATCAGAATAAG +GAAATTTCCTTTTGTTCCTGGTTTGCTGAGAGTTTTTGTAGGAATGATGTTAGATTTTGT +CAAATGTTTTTCTGCTTCTATTCAGATGATCATGTTTTTTTTTGTCTTTTATTTTAGTAA +TATAGTGTATTATATTGGTTTTTGAATGGTGAGCCAACCTTGCATTCCTGGGATATATCC +CACTTGGTCATGACATATAATGATTTTTTTAATATGTTGCTGGATTCATTTTGCTGGTAT +TTTGTTAAGGATTTTTGCATTTGTAGTTATAAGCAATATTGATCTGTAGTTTTCTTGTGA +TATCTTTGTCCAGTGTAACAGCAGGTACAGGTATCAGGATAATACTGGCCTCATAAAATG +GTTGGAACATGTTCCATTTTCTTCTGTTGTGTGGAATAGTTTGTGAAGGATTGGTGTTCA +TTTTTTAAATGTTTTGTAGACTGCGTTCAGTGAAACCTTCTGGTCCCAGGCTTTTCTTTG +TCCAGAGCTACTTAATTGCTAATTCAATCTTACATGTTATAGGTCTATTGAGATTATCTA +TTTCTTCTTGAGCCAGTGTTGATAGTTTGTGTCTTTTTTGGAATTTTTTTCCCATTTGAT +GTAGATTATCTAATTGATTAGCATATATTTGTTCCTAGTATCCCCATATGACCCTTTTTT +ATTTCTATATGGTTGTGATGGTCCCTTGCTGTCATTCCTGATTTCAGTAATTTGAGGCTT +TCTTCTTTTTCTTGATCAGTAAATTGTTACACTTGATGATACATCACAGGTCTCTGAGGC +TCTGTTGTTTCTTCTCTGTACTTTTTTCTTTCTGTTCCTCAGTGTGGATTATTTCAATTG +CCCTGTCTTCAAGTTTGCTCCTTTATCTTCTGTTGGCTCACATTCTGCTGGTAAACCCCT +CTAGTGACTGTTTCATAATTTCTGTCTTTTTTAAAAAAATTCTTTATTGGGTAATGCATT +GTTTTTATACTTTAATTCTTTTTTTTTTTTTTTTTAATTATATATATAGGGTCAGGCATG +GTGGCTCACACCTGTAATCCCAGCACTTTGGGAGGCCAAGGCGGGCAGATCACAAGGTCA +AGAGATCGAGACCATCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA +TTAGCTGGGTGTGGTGGTGGGCACCTGTAATTGCAGCTACCCGGGAGGCTGAGGCAGAAG +AACCACTTGAACCCAGGAGGTGGAGGTTGCAGTGAGCTGATACTGCGCCACTGTGCTCCA +GCCTGGTGACAGAGCGAGACTCCTGTCTCAAAAAAAAAAAAAGGAAAAAGAAAAAAAATA +TATATATATATGGGGTAGAGATGGGGTTTCACCATATTGCTCAGGCTGGTCTCGAACTCC +TAGGCTCAAGCAATCTGCCCACCTCAGCCTCCCAAATTGTTGAGATGACAGACGTGCCAC +TGTGCTGGCATTATACTTCAGTTCTTTAGACATGGTTTCTTAGTCCTTTGAGTATGTTTT +CTGTAGGTGATGTAAAATCTGTTTCTGGTAAGTCCAGTTCTCAGAGAGCGTGTATATTAA +ACTGCCTTTCCCTTCATGTATGGGCTGTCTCTACTTTCCTATTTCTTTGCATATCTCAGA +ATTTTTTGTTATTGTCAAGAATTGGACATTTAAAATATATGGCAACTCTGGAAATCACAT +TACCTCACCTCCCTTAAGTTTATAGTTTTTGTCATATGTCCTTGCTCTCTATTTGTGACT +GTATCAGTTTGCTAGGGATACTGTAACAAAGTGTCACAGACTGGGAGGCTTAAATGACAG +AGATGTATAGTCTCAAAGTTCTGGAAGCCAGAAGTCCAAAATGAAGGTGTCAGAAGGCTA +AGAGAAGGCCTTTCTCCGTGGGTGGAGGATAGCGATCTCCATGTCCATGCCTTTCTCTCT +GTGTGCATGCTGGTCTCCACATTGCCCATTTGATAGAGACACCTGTCTCACTGGATTAGG +CCCTACCCTAATGACCTCATTGTAATGTGATGACCTCTGTAAAGACCTTGTCTCCAAATA +CTGTTGCATTCTGAGGGACTTCAACATGTAAATTTGGGGGTGACAGTTTACCTCATAATA +GTGACTTTCCTAGATTGATTCTGTGAAGTGTGTATTCTTTATGATTTGTGGCCACTGAAT +ACACGGGCCCTTTAGCTGAGTGGTCTCCTGATGCTTGGACAGGGATTTTCGTAAATTCCC +TGAGCCAGTAAGTCTCCCGGCCTGTGATGAGAGCTGTGGGTCTGTGGGGCTCACCTGGTG +TGCTCCGGTGGCTGCCAACTGTCTTAGCCTTTGTGTGCCACCTGCACAGAGTCTCCAGGT +CAGTCAGCTGGGAGGTTTTCCTGGGCCTGTGCGCAGTCATCTCCAGACATACGCTAGAGC +CTTTCAGAGCCCCATGGACATCTCCAGCTTTTCCTTCTTGGGTTCTTGGCCAGCCTCTTG +TTTGCCCAACTAGTGCCCCAGCCTCTGGCAGCTGCAGGGTGAAACAGTTGCCACTGGTTC +CTTTTGACAAAAGCCCTCAGGAACTGGGCTGTTTTCACTGAGTGAGATCAAATAAAGACA +AATCCTGCCATGAGGCTTTTCCAGAGGGTGGCCAGGTAAACCCAACAGTGACAGTTCTCT +GGGCCTGGGGCCTTGAGGACCCGTTCTCCATTGAGTGGCTACCACTGAGCTGGGGAGAAG +GGCTGGGAATGGGGCGAGTTAAGATGCCAGCAACTCCTTGTTCTTAGCAAGACTCGTTGT +CTTTCTTGAATCAACACTCCTCAGATTGTTGAAAGCCTTTCTTTAGTTTCCAGGGTTCTG +AAAGAATTAATTCTGACCATTTTTGCTAGTGTTCTTGTTGCTTTAATGGAGGAGAGCAGA +TTTTGGAGGTCCTTATTCGGCCATTCCAGAACTACTTTAGGATGGGTTTTGTAAAGTTTT +CTCATCTTTGTGGACTGGTGCTGTTATAAAATATGGTTAAGTGTCTATGGTAGTACTAAC +TTGCTCTTAAGTTTCTTGAACTCCTGGCTTCAAGCAGTCCTCCTGCCTCAGCCTCCCAGG +ATGATGGGATTACAGGCGTGAGCCACCACACCTAGTCTCTTGCTCTCAAGTTTCTACATG +TTTTCTGTGCTTTATGTAACTGCTTCATCGTGGACAGGCTACAGACAGATTGCAGACCAC +ATGTGGATCAAGCACAGTCTCCAAGTACTAGCTGTTCCAGGAAGAGTCACATTTGTCCCT +TTTTTTTTGAGATGGAGTCTCGCTCTGTTGCCAGGCTGGAGTGCAGTGGTTCGATCTCTG +CTTACTGCAACCTCCGCCTCCTGGGTTCAAGCGATTCTTCTGCCTCAGCCTCCTGAGTAG +TTGGGACTACAGGTGCACGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGATGG +GGTTTCACCGTGTTGGCCAGGATGGTCTCTATCTCTTGACCTCGTGATCCGTCCGTCTTG +GCCTCCCAAAGTGCTGGGATTATAGGCGTGAGCCACTGCACCTGGCCACATTTGATTTTA +TTTCTGAGTGACCCAACCGTGGGAAATATGGCTCCCAGGGAGGCTTCCAAGGCCCTCTGG +GGAAGTGCTTGCGTAGACCCTGGCCCACCAAAACTCTTAGTATGGGTTGCTGCAGACGAT +GGTGCCTGAGTTGTGTAGGTCTCACGCTGCCTTCCTGTCTGAGTAAAAGCCCTGCCTGTT +CTTTGCTATGGGGTGGTGGAAATGTCCATGAACCACTGTGGTTTCTGGTGCCAGGAGAGG +GCCCAGCGGGGAGTCAGGTTCTCAGCCTCCACTCTGGGGTTCTTCTGTGAAGTGGAGAGG +CTTTGCAGAAACCACATTGCAAAGTAGTCTGAGAAAGAAGAGGTTTCCCCAGGTGGAGAA +GGACATGGGGGTGGGGCATGTGGTGGCTTCCGCTGTAGACTCCCCTGCCTGGGGCTTTTT +CCACACCCCTACTCCGATCCTCCCACACTGCAGCCTGTCTGGAGCTAGCGTCATATCTCC +CCAGGTAAGGAGCTCAGTTTCGTGGGACTGCCCCCACTTCCTGTGCCAGCCGCAAATGGG +GGCCCCTGCCACCCGGCACAGGACCCCTCCTCGTGCTTGGAAATTTGCTAGGACTCAGGA +ACTCAGGAAAAATTTTACTTATGAAACTTATTTTTCATGAAGGGCTGAAAGTTCCTCCCC +TCTACTGACACATTTGATTTCTCCGGGGAGCCCACCCTGGCCACCTCCTCAGCATAAGCT +CTGTGGTGGGGTCGTTTTGAATCACAAAAGACAAACCTAGCACTCAGGAAATCCTCAGGG +TTTTAAGAACTCTGTTCTGGGAACCTGAGAGAAGACCGTGTGTTTTTATGATGCCATGCC +TTGGTTTAGGGTGCCTTTTGTATGTGCCCCTCCTGAGAAGCTCTTTGACCCTCTTATTTG +TATATATGTCATCTGTGGGCTGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGG +AGGCCGAGGCGGGCAGATTACGAGGTAAGGACATCGAGACCATCCTGGCTAACACGGTGA +AACCCCGTCTCTACTAAAAACATACAAAAAATTAGCCGGGCATGGTGGTGGGCGCCTGCA +GTCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCAGGAGGCGGAGCTTG +CAGCGAGCTGAGATTGCGCCACTGCACTCCAGCCTGGGCGACGGAGCGAGAATATGTCTC +AAAAAAAAAAAAATGTATATATGTCATCTGTGATGTCCCCATTTAAAAATCTGTCAGAGG +GGAAAGTAGCTTTTCCCTCCGTTGTAGGGTGGTGGGGGTGTTTAGACAGGGGTGGCCATC +TCCTGTTCCTGGGAAGTTTCTATTTGCTGGTCCTCCCTAGCGAGGCTCTCAGGTTGTGTC +CCCGCCCCCTGCTCCTCCCAGCTGCCTGTGCAGAGGTGCCAACACCTGTCCTTGGACTGT +CCCCTGGACAGCCTGGGGCGTGGGGTAGTATCCCCTCCTTGTGTGGACTCCGGAGGTGGG +GTTGACATGTCAGGAGGGGCGGGTTGATGCCTGTGAGGTGTGGTGGCCACGCGTGTATGC +TACTTGATTAAAAAGGGAAAAAAGGAACAACTGGCATCATTTCCTTTTCACAAAGCTTGT +GGTGATCTCTTGGTATTTTGTTGCTAGCTGTGGGTTGGTGGTTCATGGCTATTAAATTTA +GGTATTAGTGACCAAGTGTTTTCTTTTTTTTTTTTCATCTTATTTTAAAATTTACATAGA +GTTAAATTCACTTTTTGGTACAGTACTGTGAGTTTTGACAAATACACAGTCATGTAACCA +ACACTGCAATCAAGATGCAGAACATTTCTGTACATTCCAACATTCTTCTTTGTTGGTCAA +ACTCTCCCACCTGTATCCTCTGGTGGGCACTGAACTGCCCCTGTAGTTTTGCCAGATCCT +GAATGTCCTCTTAGTGGAGTCACCTGGTACGTAGCCTTTGAACCTGGCCTCTGGCTTGGT +GTGGTGTGACGCATCCGTCGTGTGGTCATTTGTACTCCTGAGTGCTGGCCACCAGGTGGC +TGTGCCCCTCAGTGCGTCTCTCCATTCTTCCTTGAGGGACACTGACAGGTTTCTGGGTTT +TGGTGATGGGCAGTAAGGCTGCTGTAAGGTCGTCCAGGTCTGTGTGTGATGGGCGGATTC +GTTTCCTTCAGGTAAACCCTTGGGATGGGGTTGCTGGGCTGTGTGGCAGGTGCACGCTTA +TGTTAGCATTGCCCTCACACCTTTCTCAGTCACTAGGTGACCGTGGAAGTGTGTCTGTTT +TGGGGCTGTCTACTGTCTTTCGAGCTGTGTGTCCTTTTCCTGATGCCACACTTTCCTGAT +GACTTGAAGTCTTGATACTGGGAGTCCTCCAACTTCGTTATTCTTTCTCAAAAAATTGTT +TTGGCTATTCTAGCTCCTTTGCTGTTCCATGTAGACTTTAGAAACAATATGTCAGTTTCT +ATAAAAAATTCTGGGCTGGGTGCAGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGC +CGAGGTGGGTGGATTACCTGAGGTTAGGAGTTCGAGACCTGCCTGGCCAACATGGTGAAA +CCCCATCTCTACTTAAATACAAAAATTAGGTGGGCGTGGTGGCGGGCACATGTAATCCCA +GCTACTCAGGAGGCTGAGGCAGGAGAATCGCTTGAACCCAGGAGGCGGAAGGTGAGGTGG +CAGTGAGCCGAGATTGTGCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACCCCATCT +TAAAAAAAAAAAAAAAATCTGCCTGCATTTTGATTGGAATTGATCCTGTAGATCAATCTG +GGGAGAATGGACATCCTAACAATATTGGATTTTCCAAATCATAAACATAGTTCATCTGTT +CATTTATTTAGGTCTTCTTTGATATCTTTCATGGGTGGTCGGCAGTTTTCATCACACAGG +CCCTGTGTATATTCTACTAGATTTATAGTTAAATATTTTATGTATGGCACTGTGATGAAT +AGTACCTTAGTTCCAATTGATTGTTTATTGCTAGCTTACAGAGCTAGAATTTGTTTTATT +TGCACTGATTTATTCTAGTAGTTTTTCTGTAGATTCCTTATCCAGTTTTCTTCTCTAATT +TGTTAATGTAGTTAATTACGTTGTTTTTTTAAAAATGTGTTCCTGGGATAAGTCCTACTT +GGGCATGGTATATGTTCCTTTTCATGTGTTAATGGCTTTAATTTGCTAGTTCCCTGCTGC +ATCTGTGTTCTTGGTGTTAAGGTCATGGTACGGGTAGTGTCATCAAGCGAAGTGGGAAGT +AGCCCTCCTCCTGAGTTTTTCAGAAGGGCAGGACAGATATAGGATTGGTATCATTTCTTC +CTTAAAATTTGGGCCTGGAGTTTTCCTAATGGGAAAGTTTTAAACTACTACTGTATGAAC +TACTAACTATAACTATGACTACTCTGAACTACTGTTGAGTTTCTTGAACAGGTGTAGGGC +TGTTGAGGCTACTGAGATAGTTTGTGTCTTGCCAGGCATTGGTCCATCTCATATAGATAG +TGGAATGTAGAGGTGTCGGGCGTCTGTGGTGCTCCCACACGGTCCTTTGGCATCTGCCAG +GCACTGATTGCTTAGGTTTCTCCTGTGCTGTTTGTCAGAAGCAACAGGGATTTGTCTGCA +GGTCACTTCTGCCATCTGTCTGCTCTCATGAGCTGGAGCCTCCACCTGTCCCTGGCGGGT +TAACCCTCAGTAGCACATGTGGCCTCAGGCAGCTTGGTGCAGGGCATCCTGGTGTCGGTC +TTTTTTTTTTTTTTTTTTGAGACGGAGTCTCGCTCTGTCGCCCAGGCCGGACTGCGGACT +GCAGTGGCGCAATCTTGGCTCACTGCAAGCTCTGCTTCCCGGGTTCACGCCATTCTCCTG +CCTCAGCCTCCCGAGTAGCTGGGACTACAGGCGCCTGCCACCGCGCCCGGCTAATTTTTT +TTTGTATTTTTAGTAGAGACGGGGTTTCACCTTGTTAGCCAGGATGGTCTCGATCTCCTG +ACCTCGTGATCCACCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCG +CGCCCGGCTGGCGTCGGTCTTTTGCCAGAAACTTCTGAGCGTGCTCTCTAGCTGTGTGTG +TGTCAGCCACTGCCTCAGCTTCTCCAGGGCCAGTCCCGAAGCCGTGGGGTATGTGGGTTC +TTGTGGGCCGACAGCACTGGACGTTGCTAATTGGTTGGCTGGTTGACAAACCCTTGAGGT +TCCAGGGCCTGATGTCTTGGTGAGTGACCTTCCCTGGAAAAAGACCCATGTTGATTTGTG +CACTTGAGAGGAGCAGTGTCTTCTGGGGACCTATTTGAAGACAGTAGCCAAGCCATACCT +CGAGGATTTTTCGCTTGCCAACCTCAGGGCTAGTGCCTTCCTCTTCTATGCAGTTGCAGC +GAGTTGGCCTTGCTGCTTGCTGGAGCGGCGAGGGCAGAGGAGCTGCCCACTGCCCTGTCT +GTAGGGCCAGTGTCCCTGTGGAGCGGGCTTGGCACACTGTGGAGCCTGCACAGCGAGGCG +TGTGAATCATTTGATTCTAGGTTTCCTCGCTGCCCATGGGCCAGGCAGGCTCCAGGTCCC +TGCAGACCCCTCCAGAACAGGGCCAGTGGGGGAAGCACTGTGAGGGTGTGGCTGATGGGT +AATCTCCAGTGCTTCAAAGTGTGGTCTTTTTTGGAAAGAGGATGATTGCAGATAGAATTA +GGTTAACATGAGATCACACTGAAGCAGAGCAGTGGTGTGATCCAGTGTGTCTGGTGTTTC +TCTAAGAAGAGGGAGGAGGGGCAGGGCTAGTAGTCCATATGAAAATCGGAGCAATGCTGC +CATAGCCAAGGGATGCCGGGGCCACCAGGAGCTGGCAGAGGCTCCCTAGAGGCTTCTGAA +AGAGGATGGCCCTGCTGAGGCCTTGATTTCAGACTTCAGAATGGTGAGAGAATAAACCTC +TTGTTCTAAGCCACTGACTTTGTGGTATGTTGTCACAGGAGCTCCACCAGGGAGGTTGTC +CATGCTCCAGAGTGGGCTGGATAGCATCTTCCTTTCACCCAGGAGGCACTCTCAGCTTCA +GCCAAAGTCCTAGTCTGGGAAGGCACAGTGGGCAATGTCTCTGCACCTCAGCCTGCTGCA +GCTTCCCTATGCCTCACTGTGTGGAATCTCCCCATCACCTCTTGTTTCCCTGTCTGCCTC +TCTTGTCCTTCCTGTGTGTTCTTGGGTTGGCTGCAGAGCCAGGGTGATGACACTGTTGGA +AGCCTTGCTGGGCTGGGCCTCTGCTGGCCACCTGGGGCTGGGCTCTGTGTAGCTGTGTGG +GGCTTTGGCCTTTGGGGAGCTGGGCCTTTTAAGGCCAGCTTTTGGGTCTGGCTGACTTTC +CCTCTCCTGTAGTCTCAGTTGTGGCAATAGTAAAGCCTCTCTGCAAAGGTGCTTTATCTT +TATAGAGTTCTGAGAAGGGTGCCTTATGGATCAGAATCAGATCCAAATAAGGTGGGCCTG +GCCAGCCAGCCATGTACCTGGGGCCCTCTTAGGATACCAGACTCCATCCCACAGTGCTCA +GGGTGGAAGGGTGCTGTGGGCTCTGGAGATGGGCAACTGGACGGTGAGGTACGGAGCATG +TCTTGTACCCGGTGGGTTCCTTGCAGAGTTGAGGTATGAAGTGCTAGGCGAGCTCACAAG +AACAGACATTAAGCATCTGGGGAAAGCCAACCGCAGGCCCAGCCATGAAGAGGCCGGTGG +GCCTGGTGGGGACTCACAAGCCTCTGCTTTGTGTTGTAGTATTTTAACCACATCAGCATC +GAGGACTCGCGGGTCTACGAGCTGACCAGCAAGGCTGGGCTGTTGTCTCCATATCAGATC +CTCCACGAGTGCCTTAAAAGGTAGGGTAGGGGGGTGCCTCCCCCCATGAGTCAGGTCGGG +GGAGCTCCTCTCTGGCGTCTCATATTCTTGTGGCTGTTTGTCCCAAGGCAGAGGCATGGC +CAGGTTTCCCTGGGTACACAGCAGCCCCTTGGCCCTGGCCACCAGTCAGTCCCACAGGCC +TGAATCGGGCGTGTGGAGAATTCCCTCCTCTGGCTGAGATGCAGTCTGGGGAGAGGCTTG +GTCATTTCCTAAGGGCTTCCCAGAGCAGGCCTCCTCAGAGGCAGCTGGCTGCTCTGCTCA +GGGGACGCCATCTGTTGTCTGTTTTCTCTTAAAGAAACCATGGGATGGGTGACACGTCTA +TCAAGTTTGAAGTGGTTCCTGGGAAAAACCAGAAGAGTGAATACGTCATGGCGTGTGGCA +AGCACACAGTGCGCGGGTGGTGTAAGGACTCCTTCTCTGCTGCCTGGTGGCCGCTGGGCG +GGCGGCCCCTGGTGTGGCCCTGCGCCTCTGTGGCTTGGTCTCAGCTGTTGCCCTGGCATT +GTCCCTGAGCCCAGCTGTGTGTGCTGGCCACCACACGTTCAGCCTAAGGCGGACTGGCAG +CCGTCCTGCCTGCACTTTCCCTGTCTTTTCCCTTTCCCCCGCTGTCACCCCTGTCTCCGT +CCAGCCCTTGTCCCTGTGGCAGGAGGAAAGGCCCTCCTCCTCGAACAGCCAGCAGAATCC +TGCTGCTCCCTGTTTCTGGAGGTGTGCGTCTTGGCGGGAGGGAGGCTCTCGGCTGCGTGG +CTTTGAGTGGTAGTGTCCTCAGCTCCTAGACTCTGAGGGCCACTCTCTCAAGGTGGCAGC +TGGGTACTGTGAGACTCAGGTGCCCAGAGCAGTGGCAGAGTGCTGCCTATTCCTGTAGAA +TGTGCCCTGGCTGGCCCTCGGGGTGTGGGTCAGGAGGGCTGGGAGCGGCAGGGGGCCCCA +TGAGCACTGGGTGTTTGTGACCCCCTCTCCATGCTTGCTCTTTCTCTGTGTAGGTAAGAA +CAAGAGAGTTGGAAAGCAGTTAGCCTCACAGAAGATCCTTCAGCTGCTGCACCCACATGT +CAAGAACTGGGGGTCTTTACTGCGCATGTATGGCCGTGAGAGCAGCAAGATGGTCAAGCA +GGTAACTGGCCATCAGCAGGTCCCAGGGCAGCCTGTGCTGCCACCCTGGAGCGTATTCCT +GAGGCTCTGTGCTCAGAGGGGGCAGAGCTGGGCAGCTCTGCTGTTGCTCACAGCTGCCTC +TCTCCTGGGCCACTTGTGTGGCTTTGTGGGCAGGGGTGGGGTCGTCCCAGCTACATCTCC +TATCCCAGCCTGCTGGGCATGGTCAGTGAAGTGTGGGTGATTGGGAACGCAGGCTGGGCC +CAGCTATGTGGCTTGTAGGGAGATGGCCAAAGTGCAAGGCAGGGCCAGGCAGGAGATGCT +GAAGGTGCGCCCGGCTCGGAGGTGTGCAAAGGCTCAGGAGCCAGGGCCAGCTCTCCCTGC +TTGAAGGAGAGCGAGTGTGTCAGGGTAGCTCTCCCTGGTACCAGTGCCGGTCCATCTCTA +ACAGAAGAGCATATGTGTACCATCTGTCTTGTTTCTGCTGTTGTGGCCAACATCCTGCAG +TGTAAGCCAGTGCCCACTCCTGAGGGGTGGAGGGTAACATGGGGAGGTGAGTGTAATCAT +TTTCCTCAAATGATTACAGAAACTCTCTGGGTTCTTGCCCTCCTGGTCATTGGAAGGGGA +AGTAGTTGTGGAGGGGTTAGGCCTGCAGGTGGGGCAGCCCTAGGACTGTGTGGTGGGTGG +GCCCTCTGCCCAAGCCAGCTGCCAAGAGCAGGGCCTGCCTTTAGGTCCCTGAGACCGAGG +CCTCGGCACTGTCCCCGAAGAGGCCTTTACTCTGGACATGATAAGGGAGGGTGAGGGGGC +TCACACGGGCCACCAGGGCATGTTAAGGAACTTGAGAGAGATTTTTGGGAAGCAAGTTGA +AATGTAGGTAGCACTTGCTTCTGCCCTTGCTGTGCATGGTCCTTGGCTGTGACGGAGGGA +GAGAAGGCAAGCCCCACTCTGGCCCGGGGGTGGGAAACTTCCCTGAGCAGGAGGGGGAAA +GGTCCCAGCCAGGCACAGCCACAGCTTGGGGGAGCTCTGGCATCCCGAGGAACCACAGCA +CCCTTGGGGCTGGCCTAAGACGGGAAGGGGCTGAGGCCAGCCTGATGCTGCTCTGCATTC +ATGGAGTGTGCAGAGAGCTCAGTGCCTGAGGCTGATGGGCTGGGCTGCAGCGTGCTGTTC +TTACTGGCTATGGCCACACTCTGGTTTCACTCCTTGATGAGGACTCTGGGCACCACGAGC +ACCTCACCTCCCTACTCTGCCCATGGCAGGAGGCCATATAAGTGGCGTGGTGTGGGCAGA +AAGGCCTGGCAGCTATGGACTGCCCCTCGCTCTCTGCTGCTGTCAGTGGGCCTGGCATCA +CTGAGGCGGGCCAGTCAGCATGCAGTTATGTTGCCACAGCTCCTGGCTGTTTCGTGTCTG +CCAGACCCTGGGCGCGCCTGCCTTCAGGGTCCCAGGCACACAGCTGCTGGGCAGCGGGCA +GGCCGTAGAGCTACAGCCTGCAGTCCTGAGCGTGAGGTGCTATACTTCCCAGGAGACATC +GGACAAGAGTGTGATTGAGCTGCAGCAGTATGCCAAGAAGAACAAGCCCAACCTGCACAT +CCTCAGCAAGCTCCAAGAGGAGATGAAGAGGCTAGCTGAGGAAAGGGTGAGTGCCACCCT +AGCGGGAGGGCTGCCGGGCCACGGCCATTCCTGTGGCACCTGTGGAGGGACAGCAGACCC +CAGGACCCGTGCCTGAGCTGACACCTTGGAAATGCTTGGATCCTCCTTCCAAAATCAGAT +ACAGGCTTTTCTTTGAGCTTCGACATGTGTGATAGTTTTATAAATCACTTCAGTTTTGGT +TCTGTTGTTAGAGAGCTGGCAGGCCAGCCTGTTGGTGGACCATGAAGGTCACAGTCTTGG +TGGGCCACCTGAGTCCCATGTCCTCCCTGGGTGTTTGGAGGTAGGTCAGTGCACCTGCCA +GGGTTGAATCTGTAGGGCTTGGTCCTGATGAAGCCTCCTAAAGCCACCTTGGGAACCCCA +CTCAAAGAGGGGCCTGTCAGGCTGGCAGTGGTGTCTTCTGTCTTCAGGCATCGTCTGCCT +GGCCACGGCGTGACCTGCCCACCTGGGCCTTCTGGGTGGGAGCTTTCTTAAGTGTGGCAG +TCCCCTGGCCTGGGTGAGAGCCCCAGGAGGTATCTGCTGCCGCCCAGGCCAGCAGGTCCC +TTGCTGCTCCCTGGGGTGGGGCTTGGCCTCCTGGAGCCAGTGGGACTGCCTGGTTTGCCC +CTGGTCGGAAGAGGGGCTGTGGGGCTCAAGGGCAGCAGGTGCAGGACATAGTGCTCCTGG +CTGGGCCTGGGGCAAGCAAAAGCTGGGCAAGGGAGGAACACCCAATGGGGAGGCCTGGCC +TGTCCCTGTAACTGCACCCAAAATTCTTCACTTCTTGGTACATGTCCTGATTGCCAGGGA +GGCTGCACATGTTGTACTCTGATGGCAATGCAGGGGGCCTCTGCAATCTCAGGCTGGCCT +GCCCCAGGCCTTCCCTGCTCCTCCTAGCCTGGCATCACAAGCACTGGTGCCGTTGGGGCT +CCAGGGCCTCCTGGCATGATCTGCTGGGCTCTCCCTCCACCTTGTGTCTTCCCGAGCCTC +TGCCAAGCCCACCTCACTGGTACCCCTGACCTTTGTTGTTCTTTCAGGAGGAGACTCGAA +AGAAGCCCAAGATGTCCATTGTGGCGTCCGCCCAGCCTGGCGGTGAGCCCCTGTGCACCG +TGGACGTGTGAGGGAGGTGGCACGGGCCAGGGCGCGGGGGCCGCCAGCCGCACTTCTGAG +GAGACCAGCAGTCATGCATCGTGCACCACAGTGTCAGGCCTCCAACCCACGCTCCTTCCC +TGTGGCCAACCTGTGGGCCCGGCCTTAGGGTGGAGGCTTTAGTGTACAGGGACAGCCATG +GCCACACAGCACACATGTGGAGCAGCGGCTCTCCCTGGAAAGCTCCAGGCCTGAATGGAT +GGACTCAGCGACTGCACCAGTGGCAGCTGGTGACTGTGGACAGTGGTGGACCCTGCTTCT +GTGCACCTGCTGCAGGCTCTTTTTATGAAGGCTTTCATGAATTTTAGTATGTAATACGCA +CTGACGACACATGATGCTTGGATGACAGATGAGAGGGGATGGCTGAGTCCTGTGGCTGGC +CCGTGATGCCAGGTGGCCCATGTGCCCAGGGCGCCTGCAGGGCTGCTACAGGGACCTGGT +CAGGAGGTGCACATGGTGCCCTGCCCTCACCCACCCTCTGTGTTTCCCCTTCTTTGAAAA +GGTAGAAGAGAAAGGAATATTTTAAACCTTTTTGGCTTAAACAGAATTTTAGCATCAGAA +CTAGCTTTCTGGGATTGGAGGCAAACCATCAAGGTGGTCCCTCTCCAGTCTGGACACGAT +GCCAGCAAGGATGACGTCCTGCCACCTCCTGGAGTTACCCTGGCCTCCTAGGGTCCCTTT +TTCTGATGAAGTCTTAATTCCCTAAAAGCGCCTCTTTGGACACTGAGGCCCTCTCTGCCT +TTCCTGGCCTCCGGCAACAGTTTTTTACAAAGATTTTTTGCAGTCGAGTCCATATGTCCA +CCCATTGATTTTTAAAGCTTTTGTGATATTTTAGCATTTTGAAAGACTTTCACAGTGAGA +GTAGAAGGTAGATTTGGAATCATGCATTTTAGCAAGTGGACTTGTTGAAACAGGAAGCAA +GGGCCTTCAGTGTAGCCCATTCTTGATCCAGAGCTGTTGCCTGTGACAGCGGTTTCTCTG +GATGTCAAAGGCAGCTGCCTGGTGCCCAGCTTGCTTCTCGACTGGTGGCCCCTATGGGTG +GGTGTGCGATGGAAATGTGTTCCTGCCGGAGTCTGAGGCACCAGGGTGTGCTCAAAGGCT +GGCCCTGGTGGTGGACTGGCACCTGTGCAGAGTGCCGTGTGCTTGTGGTGCGCCATCTGA +AGCAAGAGTCCAGCGTTCTGCCGTGTCTGTCCCCCACCATGCCCCCTACAGGCGGTACTG +ATGGCGCTTTTTTTTTTTTTTCTGTCAGGAAAACAATGTTGGCCTGTGGGCCGCCCACAA +CATATCCTTCCCTCACTACCTGTGTGACCAAGGTTGGCTTCTGTTGACCTTTAAAAAAGA +AACCCTCAACTCAAATTGCTATAATTAGACACTTGCTTCTGTCTTGCCTCCTGTCTGCAG +CTGTGAATAGTCATTTGACTGTGACTGTTGCCCTTAGCCAGCCAGATGCGCCTGTGAACC +AAAGCTTCGTGCACATGTGTTCCCCTAAAGGTTGGGGAGCCTCGCTGTGTCTTGCTGTTC +CCAGGCACCACCACAGCAGGTGCTGCCATACTCTTGTGGTCTCTGTGCGCCCCCCCCCCC +CCCCCACCCGTCTGCCAAGCATGGGTATGAATCGTGCACACAGCCATGCTTCAAGGCCGG +GGCAGGGGAGCCTGTGCTGATGCCATCCAGGGCACTGGGCTGTGCCTGGAAGGCGAGCCT +TGATTGTCTGAACACATAAAGCAAACTGTCCAGAAGGGAATGGCTGATGTCTTTATTCTG +AGGGTGAGAGGCTGGCACCCTGTGGACCCTTGACTGGCCAGATCCCCTCCTGGGGCCTCC +CTGCAGGCTGGACCCTGCCTTTGTAACAGCTGAGCAGCACCCCAGCATGGCCCCTTCCTT +GGTTGATGCCCTCTCTGCTGGGCTGAGGGCCAGGCTGGCCACAGAGGGGCCAACTCTGCC +CAGTGTTCTCCACCCCATGCCCCCAGCTGGTGCAGTTCCCAGACCTCTCTCTGCCTCTCC +TCAAGTTTAAGTATCAAATCGAACATTCTTTTTTAAAGTAAGCTCTGCCCTGACTCCCCC +AGCCATGCAGAGAGGCTTGCAGAGCTGCCTAGGCCTAGTTTGGCCCTTTCCCTGGCACCC +AGGCCCTGTGTTCAGACCCCTGGCTCTCATCACAGAAACACCCTTTGTTGAGCAGTTGTT +TATTCTGGCCCTCACAGCCTTGGCTAGTCCACAAAGGCCCTGGGGATGGGCAACAGGCTA +CAGGAACCCACCTGTCTTCCTGGTCAGGGCCCCTGGCCCCTAGCAGCAGGCCAATCCTGG +TGGGGCACAGGGTTCTGTGCCCTTTGGCTGCCTACCTCTGAATATCCTGGCCAGCAAGCC +ATGCCTTCCCCGCCCCTGGGGCCCTGGGAGCCCTTCAGCTCCTGTCCCCATAATGGGTCC +TGGGCCTAGGATGAGGGGAAGGTCCCAGTTTCTTGTAGGGTGTTATCTGGGGGTCCTGGT +GTGGGTTGAGCTGGAGGGCTGTGGGGCCCCAAGACCCCTGTGCCATTGGGGTGCTCCACC +CTCTCAAACAGGATGAGCATCTCACAGTGCGGGGTCTGCGGGAACAGGTCCACTGCCACA +GCCTTGACCGGCCGGAAGGGAATGCCCTTCACCCGGTTAGATGGGGCTCTGCAGAGGCTG +TGGGGGGAAAAGGGGGGCGCTAAGGTCAGCCGATAGGCTAATCAGGGGCTCCTGTGGGAG +CTGGGGGCTTGGTAGCAGGCCTAGCCCCCACCCAGGCCCCTGCAGACACTCACTCCACAA +AGTTGCCCATGGCTGCCCGGGGGTTGCATGAGACGTACAGCAGCCGCCTGAGGTTCTTAG +CTCTCCGGATGGCCAGGATCACCTTGGAATCTGAGGAGGCAAACACCAGCTGGGTCCCCA +CAGCCAGAGAGTGCATAACATGGTGAGCCACCCCATGTGTCCTCGTTCCCGTGCCACCTC +CTTAAGCAAAAGCCACTCACGCAAGCCAGCACGGGGTGGGTCCAGGATGGCCACGAGGTG +CTGGGAGGCCAGTCTGCTCACCAGGGTGGGCACCAGGTCCTCGGCCCTCCCGCAGTGGAA +CTCCACATTACTCAACTCTGAAGAGATGGCACCGTGGCCTGTCAGAGGGCCACATGCCCT +CCCAGCAGGGCCAGCCCTGGGGAACCCCTAGCCAAAGAGCTTGCTCACTTGCTCTACCTG +TCGGGCAGCCCCCAAGCCCTGGCTGTGGCTGAGGCTTGCAGCAGGGGTGGCGGCTGCCCC +CATCCCCACCCCCACCCACGGCCTTGCCACTCACCATTGTCCTGGGCGTTCACCCGGGCG +TCCTCCACAGCCTCTGGGCATAGCTCGACCCCAATGACCCTCTTTACCTTCTGAAACAGG +AAAGCGTGGTGTCGCCCCACCCAGGGAGGGGAGTACATGGGGCCCTGTGGGCAGCAAAGA +GGAGCTGGGCCTGGGGCATGATGGAGTCAGCTGTGGTGACTTTGAGCTGGGGTCAATGGG +GGTCTTGGGGTGGGGAGAGGGTGCCCTCAGCAGGGCAGGAGGGCTCACCCGGGCCAGGGC +CAGGCCAATGGTGCCGGTGCCACAGCACACGTCCAGCACCATGCTCCCCGCATCCAATTG +GGCCCAGTCCTGGATGACTGTGTAGAGCACCTCGGCTGCGGGTGTGTTCACCTGGGGGCA +GGCGGTGCCCAGGATGTCAGTGGCTCCTCTCCTGTGGTGCCACTGGTGCCCCGACGCCCA +CATTCCTGGTCCCTCCATCCTGCCGGGACCTCCGGCGCCCACTCCCCACCTTGGTGCCCA +ACGTCTTCCCTGACCCCACCTTGGACCAGCCTTGCTGATGCCCTCATCCAGCCCCTGGCT +TTAAAAGCCAAGCCCGTGCTAAGCACAGCCTCCTCCTTGCCCCACTTGGTTGAGGGCTCA +TGAGGCCCCGCAGGCCAATAGGCTGTACCTTCCCTGCCCCAGCAAGGGGGCTTTGCCTCC +CACAACTCACACCGGGGCCCCTGGAATCACCCAACTGCAGCTCCCACCCCCACACCTAGC +CCTCCAGGAGGTCCTGCCAGGCCTGTCTCCAAAAACGGCCGCTCCAGGTCCCCACAGCCT +TCCTGCAGCAGTGAGCAAACAGTGAAACAGTATTTCCCAGCCCAGAGGCCACCATGGCCT +CCCTCCTGCCGAGCCCAGAGCAGTGCCCTGTGGTAATGCACTGAGGGCCACTCCTCATCC +TCCCTGTGACAAGGGCCACTGCCGTGTGTACCTCTAGGTTATCCCGAGTCAAATCAGTGA +TGACCAACCTCTTTCTTACTTCACCCTCCCCTGTGGCTCACCTGCCTGGATACTCCCCCA +AATCTCACCGCCTGAGCCCACTGTTCCCATCACGTCCTGATGGTGCGTCAGGCCTCCCTC +AACATGTCCCCATGCCCACCAGGGACTCATGGCTACCTGGAAGAAGGCGTGTGGAGAGAT +CCGGAAGGTCAGCCCTAGCAGGTCCTCGTGGATGCACCGGTCCCCAGCCACATGCTCCAG +GGGCAGGCCCTCCTGGCTAGGAGTCTTTCTGTGGGCGAAGGTGCAGGTCCTTCAGTGTCA +CAGTCCCTGCAGGGACCTGCCCCGCCCCACTCGGGCTCCTTACCGCTGTCCCTCCTCCAC +GAAGTAGAGGCAGGTCACTCCACTGGCCCTGCCTGGCCCTGCTGTGAAGTGCTGCGCTAG +GGAGGTCTTCAGCTCTGCCAGCTCCTCAGGGCTCAGCTTCTGGAGTAAGTGGTGAAAAGT +TCCCATCAGGCTGTGCTGAGGCCCACCTAGGCTAGGCACCCTCCCCCAGCAGGGCCCCCG +TTGAGACCTGGGGGTGGAAGTAGGCAATGGCCATGGCCTGGTGGCGGCGGCTGGTGCGCA +CAGTCAGCTGCTTCCAGTGGCCTGTGTACGTCTCTGGGTCGTATGCCGAGTATGGAGTGG +ACCTGTGGGAATCACGAGCTGGCCCAAGTGCCCACAACTGGGCAAGCAGTCCCCCTGCTC +TCTCCTCTGGCCACACCTTCCTTCATCTGGCTGAAATGGCAGGCACTCCAGAATTCCCGG +GGCAGGATCACCACCCTCTGCTCCCACACCGCATAGGACTTCCCGGGAGCCCCGTCACAG +GTCCTCACCGGATGAACTCCTGGAAGGCCTTCACCACCTGCTTGGTGGCTTCGGGGATGT +GCACGGTGTCAAACGGGGCTGCCACAGCACACGTCCCGCCCTTGTACTTGCCGAGCCGAC +AGCCCACGGTGTTATCCTCCCCATCCACCCCGACGCCAACCAGAAACTCACACTTATTAC +GATACTCAGTCTGCAGGGAGAGAGAGCTGCACCTTACCCTGGCTGCCCAGCGCTTGGGCC +TGGAAACCCTGATTTCCCCACAGGGGCTGGCAGTCAAACAAGAGGAACAGCTGACAACTA +TGTGATGTTACCAGAAGAAAACACAAAGCAGGGAGATCAACAGGAAGGGTGAGCAAAAGC +AAAGTTTTTCAAAACCCAGGATAGGGGTTTGTGGCCACCGAAGTCTAGTCTGACCTGCTG +GGGTGATGGCCTGACCCCCTCCAGCGGGCAGCAGGCCTTGTTGTGCTTGTGCCTCTGCTC +GAGCAGCCAGGGCAGCAAGGCACGGTTGGTGCTCCCGATTTCCCTGTAAGAGGAGCAGAT +CGGTGGTTGGACTCCACCTACTGCCCCCGACCCATGCCAGGCCACTCCCCAAATGTCCAG +GCTCCTGACCCCTCCTTTGGGATGTCATTGTGCCCACTGTGACGTGGGTGTCTTGCTGGC +TAGCTCCCAAAGGGGCCGCCAGATCCTGTGCTGGGCCTCCCAACTGGTGCATGGACAGGC +TGAGGAAGCACAGGCCGGGCAGAGCCCTGGCCAAGAGGGGCGTCTTGCGCCCACACTCAC +TTGGCAAGTTTCTGCAGCACCTGCTCGCACTCCAGCTGCTTCCGCTCAAGCTGCTCAGCA +TAGGGCACTGTCCATAGAGGGGTCACCACGTCGGCCACTCGTGTTACTGGTGGCTCACTC +TCACCCTCCTGTCGCCTCCTCCTGGCCATGGGGTCGGCCTTGGGCCGGGCCAGGCGCACA +CTGAGTGGGCGGCCTTTCCAGAGGGCACCATGCAAAACGCGCAGGGCCTTGTCCCTCTCT +GCAGCGCTGCGGAATGTCACAAAGGCGCAGGGTGGTTGCCCAAAGAGTTTGGTTTTGTGG +GGCTGCAGACCAAAGCGGCCCAGGAAGCGCCGGACGTCGCTGAAGCTGGCGTGGCGAGGC +ACGTTCTGCAGCTCCAGTTTAAAGATCTCAGAGGTAAACAAGTCATCCCTGATGTAGCTG +TAGAGCCCGGGCTGAGGCCCCGGCCCTGTAGCCGCCCCAGCGCCCTCTTTCTCCACCTCC +TCCAGGGCTGCCGGGGCTGCAGGGGGCACCGAGACGGTAGGGCAGCTCAGGGCACTGCTG +CTCTCCTGGCCACAGCTCTCCATGGGCTTCGGGCCCTGTGTGGGGACAGATGGGGTGCTA +GGGTGAGGACTAGGCCCTGGGGGCCTGGCCCCCCAAGCTTCCTTATGGGACACCCAGACC +TCCGTCGGTGCACTCTGCACTCAGCCCTGCCCCTCCCCCAGTCTACCCTCCCGACCCCAT +TCCCGTCTCCTTTCCTCCCCTATCGCACCTGCCTCGTCCCCACCTATTCTCTGGCAGGTT +TCCTGACCCACCCCGCCTCCTCCCACCCCATCCCCGTCTCTACCCAGCGTCTCCCCGCAC +TCTACCTCGTTGTCGAGGTTCTCACTCATCGCCCAGGCGGTTCTCCGCCTAGACCAGGGA +CGCCATGGGGGCCGCCTGGCCACCTCGTCCTGGGCCTGTCACAAGGGAAGTGGCCTGTCA +CAAGGGAAGTGCTCAGAGGGGAGGTGCTCACAGAGCCGGTGCAACGCCGCGAGGTCGCCG +CCACCCCCGGCTTCGCCCCAGGCGGGGCGGGACTCGAACCTGCGATGCTCAGGTCCGGGT +CTCAGGCTTGGGGCTGTACCGCCCGCCCGCCAGGGGCCCGCGCCGGCCGCTCGCTTCGCC +AGCCACTCTTAGTCCGCCAGCGCGTGCGGCGGAGGCCGAGCGTCTCTATGATCCTGGCTT +CTGGCAACGTCATCGTCACGCGCCGGATCCAACCCCCAACCACTTTAGCCAGCTCTAGAG +GCGCGCGTGGCCGGGACGGAAGTGCGCGCGGGTGTCGCCGGGAGTGCGCGCTCCTCTGGC +TGACGGGCGGGCCGGGCATGCGCCGCGGGCGTTTTGGCGGGAAGCGCGGGGCGGGCCGGA +CAATGAGAGTGTCCGCCTCCTGAGCCAATAAAGCTGTACTGGTTTTGAATCGCGGCGCGT +TTCCCGCCGCTGGGGTCAGGGGTCGAGGTTCGGGTCGTGGGGCGGAGGGAAGAGCGGGCG +GGCGGGAGGCGCCGGCGCCAGACGCGGAGGGAAGGAGCTACGAGTAGCCGCCGAGAGGCC +GCGGAGCCAGCGACGACCGACCCAGCCGAGCCGCCGCCGCCGCCGCGCCCCCATGGCGGC +CGCCAAGGTGCCGCCGGGCCCAAGCGGGGACAGGGTGGGCGGGCGGGGCCGGGGCCGTTA +TCAGCGGCCACGTGGGCGGCCCGCGCCGCCGCCACCAACCTCCGCCGGCCTGCAGGCTCG +GCCGTCTGCTGGGCCTCGGTGGCGCGGAGTCGGGGCGCGTGGGGTTTGGGGGCTCGAGGC +CTGCGGAGTTGGGGCGTTTGGGGGTGCAGGCTCTGCAGAGGCCTGGGGGCTGCAGGGCCC +CCGCGTGACCTTGGGGTGGGTTGGGGAGCGGCCGTCGCCACGCGGGACGGCCCCAGCCTC +CAGGAACTGGTGCGGGCGGCGGGTTTCCTCCGGCTCGGCCCACTTGGGGCTCCCCACTAG +TACGGTGCATTTATTCTTTCCGTCGCCCACGCAGCACTTCATTCATTCGGTTCTTACGTC +TGGAACCGCCACTGGCCTCTGTGGCAGAAGCTCGCGTTCCAGCGTGGGGCACAGGTCCTA +GATGCGCCGACCCAGGCGGCGGCTTTGTTGGCTGCGGTGTCTGGTTGAGTGCGGGCCGCT +GCAGAGCCGCAGTGCTGTGGGGAACAGTGAAGAGCAGCGAAAAGCTTATGTTTTCTTTTC +CAGTTTGAGTCTAGTGGTGAAGTCTTGGGTCTCTTACGGACTTCTGGGTGACCAAGGCAT +GTGTTCTGGAAGACTCGAACCTAAAATATGATTATTGGTGCTCTCTTATCCTCTAAATTG +GGCCAGGATTTCATGACTTTCACCGGTACAATTTATCTAGTTATTAACTTAGTTTTCTGA +ACTGTGAAAAAATTGCTGGCAGAGCTGTGAATCCAGTGTAAATACTAGCAGTCCTGTAGC +GACTTTTTTCGTTTTACTAAGCAAGAGCACAACTATTTCCTAATTAGTCAAAACTGAAAG +AGTTACATTTTGCTTTAAAGTAATATTTCAAAATCTATTTCGACCCATCATTGTGTCCTT +TGATCTTCACACAGCAGGTATCATCTGCATTTTATGGATGAGGAAGAAACTGATGCTCAA +AGAGATGAGGCAGTTTCTGCCAGGCCACTCTCTGCAAGTGTTGGCGGCTTGTAGGGTCCC +CCATCAGTCTGTGCACAGATCTGATTGATGTCTGTGAATCTGGGGGAGGGGCCCCAAGTT +CTGGTGTCTCACTCTGTGCTCACATGGAGCTGGGCATAAACGCAGAGCTTTCCTAGTGTG +GAAGAGTGGGCCTAATTTCTTGCTTTGGGGTTGGGCCCATCCTTGTATCTGAAGTCCCTT +CATTGTCGGAGGGCTGACCACTGCAGGCACTGGTTGGGCTCTGGTTGTGAGCCAGATCCA +TAGGCCAGCAGTGTAACCTCTTTGTATCTCCACAGGACACTCATGAGGACCATGATACTT +CCACTGAGAATACAGACGAGTCCAACCATGACCCTCAGTTTGAGCCAATAGTTTCTCTTC +CTGAGCAAGAAATTAAAACACTGGAAGAAGATGAAGAGGAACTTTTTAAAATGTAAGTAG +GCTGATGTCCCAGAAATAGGACTCTTTAAGGTTGAGGTTACAACTTTTATGGGTGTCCAG +GTTTTGGCCTGACTTTTAATCAGACTGAGGCTGCTTAAAGAAAGGGCCTAAAGTTGGTGA +CTAATCCCATGTGGAAATTTAACCCGTTCCTTTCATGAATCTTCACCAGATGCCCTTGCT +GCCCTGCAGCCAGTTGCATGAAGGGCATCCCATCTTGCTGCTCTGTCCACTGGCATGGCG +GCCCCACTGCCCTTTTTTGCCACTGGCTTCTGAGGATCCAGGGAGTCCCTTGGTTGAGCA +GGGGGTTTTAAGTTTTTGCAGCATAGACTTCTTTGGCATCGTGAAGCTTATAAATCCCCC +ACCCGGTGTCTGTTGTTGTTGTTGTTTTGAGATGGAGTCTCGCTCTGTCGCCCAGGCTGG +AGTGCAGTGGTGCGATCTTGGCTCATTGCAAGCTCCGCCTCCCAGGTTCACGCCATTCTC +CTGCCTCAGCTGGAACTACAGGCACCCGCCACCACGCCCAGCTAATTTTTTGTATTTTTA +GTAGAGACGGAGTTTCACCGTATTAGCCAGGATGGTCTCGATCTCCTGACCTCATGATCT +GCCCACCCCAGCCTCCCAAAGTGCTGGGATTACAGGCGTCAGCTACCGCGCCCGGCCCAC +CCTTAATATACAACATGATGCTTGCGATAACACATGAAAATAGGTGATGGTTTAGTTATT +AAAACCACTTAAAAAAATTCTGTACATGTGCTTCTTGACGCTTTCAGTTAAGAGCTGGCT +ACAGTGGTGGGTACCAGCCTTGTGTCTTGTGACAGTGTCACAGCACCACAGAGACTGTGG +CCTGTCGCCTACACTCAGGATTGCAACAAACATCATGTTTAGTTACACACCTCAGTGAAA +ATGAGGTTGTAGTTTTTCCCTGTTCAAGTTCATGGAATCCCCCCATCCTTGAAGTTGCTT +TAAGAGTCCAGGTTAAGGTTTTGTTGCTCTGGGGTGGGAGAGGGAAGCAGAGAGAGTCAT +TCCTACTGTGAGTTTCCTATCCAAGGAAGGGGGCCAGGAGGGATACCTGGGAAAGGAGAG +CTGTGTGTCACCCTTTGGTCACAGAGGGTGATGGACATCTCCCTGAAACCACTGGGTGGC +CATGGCTCCACTCTGCTGATGCATTGCCGTAGCCCCTGTTTGGGAGTAGCTCTTTGCTGT +GGTGAAGTGCTTGCCTCTGTTCCCTCACTGCCCATGTCGGGTGGGAGGTGCTCCTGGTGG +CCTGGGCCCAGGCCCTTCCTGAGGGAGGTGAGGCCAGCAGGGTGGGCCCGGGTCTTTGCA +GTAAAGCTCCAGGGGCATCCTGTTGGGGAACCCTGTGAGACAGTCTCTTGCCAGAATCAT +GTTGGGGCAGAGAGCAGAGTCGTCTGAGAGAGGCAGGCAGAGCTGTGCACAGAGGGAGGG +CGCCAGCCTGAGCCCTGAGTGCACTGCTGGATTCTGGGTGCCCTGGTCCCCAGCGGGAGG +GGCTGCTCCTGGGCAGGAGGGCCAGGTGTTGGCCAGGGCCTGTTGCCTGATTAGAGGCCT +GGGCCTCTTCTCTGGGTCATCTGACCTCAGATGACCCGCCCGCCTCAGCCTCCCAAAATG +CTGGGATTACAGGTGTGAGCCACCGCGTCCGGTCATCTAATTCTCTTGGTTGTGGAAGTG +GAATTCAAGATGACCTGGAGTTTTTTGGGCTGCTGTGCTTCCTGGTGGTGTCGTGACAGA +GGTCCTTGGCCTGCACCTGATCCATGTTGTCCCTGCAGATCTCTGGGGCTGGGGTGCTCT +TGCACAGTGACCATGGGACGGAGTCTTGCTCTGTTGCCCAGGCTGGAGTGCAGTGGCGCG +ATCTTGGCTCACTGCAACCTCTGCCTCCCAGGTTCAAGCAATTTTCCTGCCTCAGCTTCT +TGAATAGCTGGGGCTATAGGCGCATGCCTCCATGCCTGGCTGATTTTTTGTATTTTTAGT +AGAGATGGGGTTTCACCGAGTTAGTCAGGATGGTCTGGATCTCCTGACCTCATGATCCAC +CTGCCTTGGCCTCCCAAAGTGCTGGAATTACAGGCGTGAGCCCCCGCGCCTGCTCTCTCT +TTTTTTTTTGAGATGGAATTTCGCTCTTGCTGCCCAGGCTGGTGCGCAATGGTGTGATCT +CAGCTCGCCGCAACCTCTGCCTCCCGGCTTCAAGGGATTCTCCTGCCTCAGCCTCCCGAG +TAGCTGGGATTACAGGCATGTGCCACCACACCCGGCTAATTTTGTATTTTTAGTAGAGAG +GGGGTTTCTCCACGTTGGTCAGGCTGGTCTCGAACTCCCGACGTCAGGTGATCCACCCAC +CTCAGCCTCCCAAAGTGTGGGATTACAGGCGTGGGCCACTGTGCCCTGTTTTGTTTTGTT +TTTTTTTAAAATAGGGTCTCACTCTCACCCAGGCTGGAGTGCAGCAGTGGTATCATGGCT +CACTGCAGCCTTGAACTCCTGCGCTCAAGGGATCCTCCTCCCTCTGCCTCTTGAGTAGCT +GAGACTACGGGTGTTAGCCATCATGTCCAGCTAATTTTTATCTTTTTGTAGAGATAGTGT +CTTGCTATGTTGCCCAGGCTGGTCCCCACTGAGGGAAATATTGTGACTGTAGGAGCAGTG +GGGCAATCTCCACTCACTGTATCCTCTGCCTCCTGGGCTCAAGTGATTGTCGTGCCTCAG +CCTCCTGAGTAGCTGGGATTACAGGCGTGCATCACCACACTCAGATGATTTTTGTATTTG +TAGTAGAGATGGGGTTTCACCATGTTGGCCAGGCTGGTTTTGAACTCCTAACCTCAGATG +ACCTGCCCGCCTCGGCCTCCCCGAATGCTGGGATTACAAATGAGCCACCGCGCCCGGTCG +TCTAATTCTCTTGGTTGTGGAACCGGAATTCAAGATGACCTGGAGTTTGTTGGGCTGCTG +CGCTTTCTGGTGGTGTTGTGACGGGCAGTTCTTGGAGCCTGAAGAAGGGCTGGGGCGTTC +GTGGAGGCATGGGGTCCTGCAGTGCAGAGTTGTCCTGTGTCCTCCTGCGCAGGCCCTGCA +TGTGGGCTGCAGGTCTGCACTCTTAACCTCACGGCTTTTCTTGCAGGCGGGCAAAACTGT +TCCGATTTGCCTCTGAGAACGATCTCCCAGAATGGAAGGAGCGAGGCACTGGTGACGTCA +AGCTCCTGAAGCACAAGGAGAAAGGGGCCATCCGCCTCCTCATGCGGAGGGACAAGACCC +TGAAGATCTGTGCCAACCACTACAGTAGGTGGCATGAACGACCACCTCGACAGTCCCCAG +CAGCTTGGCCTGGGACCTTTGGGAAGATTCAGGGCTGATTGGGAACTGGGGAGCGTGTTA +TTTCATGGAGTGCAAGTTTGTGGTGTGTTTGTTGAATTTAAAACCAGAAATACGTTTTTC +AGACGTGCCTCTGAACTCAGAGCAGGCCCGCAGCGAAGCTTAGAGCACACGGGGGTGTGG +AGTCAGCCAGACGGGCCCTGATGGGAGGACGCAGCGCCCAGGCTGGGCTCGGGACGAGGA +GTGAGTGCTGCAGGGCGAGGGGGTGCTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTG +TGTGTGGTGTCTGGGGGGTGGGGGTTGGTGTCTGGGGGGGGTTAATGGGGGGTATGTGTA +GTATCTAGGGGGCTGTGGTGTCTACTGGTGGTGGTGTATAGGGGTGTGTGGTTCGGTGTG +TGTGGTGTCTGGGGCAGGGGGCTGTGTGGTGTCTGAAGGTGTGTGGTGTCTGGGGCGGGG +GTTGTGTGGTTGGGTGTGGTGTTTGGGGGTGTGTAGTTGGTCTGGTGTCTGGGGGGTGTG +GTGGGGTATGTGGTTGGGTGTGGTGTCTGGCGGGGGTGGTTGGGGGTGTGTGGTTGGGGG +TCTGGTGTCTGGGTGTTTGGTGTTTGGGGTGTGTATGTGGTGTCTGGGGGTGTGTGTAGT +GTCTGAAGGTGTGTGGTCTGGGGGGCTGTGTGGTGTCTGAAGGTGTGTCGGGGCATGTGT +GGTGTCTGAAGGTGTGTGGTGTCTGGGGAGGTGTACAGTGTGTGGTGTCTGGGGGGCGGG +TGTGGTATCCGGGGTGTGTGTAGGGGTCATCTGGTGTTTGGTGTCTAGGGGGGTTTGTGG +TGTCTAAGGGGTGTGGTTGGGTGTGTGTGGTGTCTGGGGGTGTTGGGGTGTGTGGTGTCT +GGGGGTGTTGGGGTGTGTGGTGTCTGGGGGTGTTGGGGTGTGTGTTGTCTGGGGGTGTTG +GGGTGTGTGGTGTTGGGGGGGGTGTGTGGTGTCTGGGGGGGTTTGGTGTCTGAGGGGGTG +CGGTATCGCGGTGGGGGTGTGTGTGAGAGAGATTGGGGGTGTTCGGGCAGTGTAAGAGCA +GATGTGTGAGGTGCCCAGGCACCAGCCTCCCCAGTTATGGTGTGTTCTACCCTCACCAGG +ATCTTCCTGGGGAGGAAACGGGAGGGGAACGGGGCTGAGAAGGTGGCCAGGTCCTGGGCG +CCTCTGAAGCTACATAAGTAGAGGCCCTTGGGCAGGTTCAGCCAAGAGCTCCAGCCACCC +TGTGAGGGGTCCAGCCTGGCCTGCAAAGAAGTGGCAGTAGGTTGTCCTGAGTATGGCTGG +CTGCCAGCTGTCTTTAGATTGAACCTGCACTGCCCAGCTTGTTGGCATGTTTGGAAGTAC +ACTTGTCCTGGGGTGTCCCTTGGTAAGCTTCCTAGTGTCGTTTGCTGAGTGTCATGCGTG +TCCGGCGGGGCAGGGTCCCTCATCCCAGGTGCAGGATGACTGCTGGCAGGAGCCTGAGTG +GCTCAGCCCTTGAGGGCGATGCAGAGGGGTGGGTGGTGGTCTGCCTATGCCATGGGCACC +TCACTGCACGGCCTGGCCTGCCAGACTTCCTTGGGAACTGGCTCCTGGGTTCCCCTCCCT +CCCTGCTCAGCATGTCTAGTCCTGGGGAAGCTTGCACTCTGGCTGGTCCTCCTCCTCGAG +CCGTTTGAATCATTTCCTTGGGGGTCTTCCCTGATGCCCTGTGCTGCTCCCAGAGCCTGG +GTCAGGTTGTGGGTTGTTGTGTGTGCATCATAAGTTGGTTCTGGGCTCCTGGGCATCTGG +GCAGAGCCATCTGTGTAGCCAGCAGTGTCTTGTGCCCATCATGGGCCCTTGGTAGACAGG +GAAAGTGGCAGTGGGTAGAGGCTGGCTTCTGGGTAAGGTGTCGAAGAGGCTGTGGGCTGG +GTCGGGGCGGGGTGTGAAGGGGGCATGCAGGGGGCTTGGCATCCGCTGTGGCAGGCTGCA +GTAGACGAGACCCCCCCCCAGCTCCCAGTTCAGATAGTGACGTGTAGGGGTATCCTGGGG +GTGCATGTGGCCTGGACTGGGCATGGGCACCTGGGATGGTCTGGGTTCTCAGGGAGCTGT +TCTGAAGAGTGGTCACCTGCAGGGCCATCTCCCCTTGGGGCTGCCTGTGCCTGGGGAGTT +GGGGTGGAGGCGTCCATTGCAGGCCGTGGCTCTGTCTCCTGTGCCCTCCAGGCTTCAGTC +ATGGGGATGCAGGTGGGCACTCCTGCATCAATCATGGGGATGCATGGCCACGGCCCCCAG +TGGGCTCCCTTCTGGCAACTGCCCCACTTTCTAGCCTTCTGCTGCCCCCCACTTTCAGAT +AGGCTGGCTCTATGTGTTGGGTTCCCTTAGGAAAGACTGGGCCCCCTGGGCCTTGTGCCC +TGATATCTGACCCTGGGCTTCTGACTTCACGGCCAGGGTCAGAATCAAGGGGATCAGGGT +TGGGCTTGAGTGCAGCCCTGGGATACAGCTGGGGCCTGCTTTGCCAGCTCTGCTTCTCTG +CATTTCTGGAGGTGGGGGTCTGTGTGCCAAGTGATCTTGAACACAGCTCAGGAGCTCCTC +GTGGAGATGGCCTTACGGTCAGGGAACAGGTGCCCATTCCTATTTAGGATGGTCCTGGTT +TTAAGTGAATATGGAGGATTTTCAAAGAGGTTTGAATAAAACTCAGGCGCCGTGGTACTT +TGTCTAAGCCTGGTTCTCCAACCCCAGACTGTCCCCGTGTTGTCTGAAGCAGACCCCTCA +GGTTGGTGAGCAGGGTGCTCTGTGGCCGAGGGCTGGGTGGGCTGGCCTTTGCAGTCATCT +CACCATCTTCACGAGCTTCTCTCTCTTCAGTCACGCCGATGATGGAGCTGAAGCCCAACG +CAGGTAGCGACCGTGCCTGGGTCTGGAACACCCACGCTGACTTCGCCGACGAGTGCCCCA +AGCCAGAGCTGCTGGCCATCCGCTTCCTGAATGCTGAGAGTGAGCCAAGGGCCCTGGGGA +CCTGCCTGACTTGGGGCTCACCTGCGTGGCAGCGTGGCGGGTTATGTGCAACAAATGCTG +TTGCCTTTTGGGGAGAGGGGGCAGTAACTGGGAAGTGTGTCGTGTGGGCTGCCCTGCCCT +GCTGTTTGGGGGCCATGCCCAGACTGAAGCCATGAGCAGCGCCTTCCCCCTTAAACTCAA +AGCTGTGCCAAGTAGCTGGTGAACAGCAGTGCCCGCTCAGCCGCCTTGTGGCTGGCACTT +TGGTTTGCTCTCCAAGCTCCGGTTCCCATTAGTTGTTGCGGAGCCTGAGGCCCAACCCAG +GGCTTCCTCCCAGTGCTGATCCTCGTGCCAGGCTTCTGGTTCACTGGGGCCAGGGGCCCC +TCATGGTTGCCTGGGTGCCAGCAGGGGCTGGGCAGAGAGATCCACAGGCCCAGGCTGATC +TCTTCCCTGCTCAGAGGTCTTTCCAGTCCAGATCGTCCAAGCTGCGTCCAGTGGCTCCTG +GAGGAGTCAGTGGGTACTGTGGCCTGGCGCCTGGTAGCTGGCCGTTTGGTGCCAAGTGAC +CTTGTCCTTGCTGTGGGCGTGGCTGCCCCAGCAGCCTTTCCAACACGGTTGGGAGCCGAG +CCTGTGGCAAAGAGGCCCATGCCCCTTGGTTGCCTGAGGGTCCGTGCTCTACCGCTCTGC +CCAAATGGGTGCAGTCAGATGAAGGAGACAGAAGGCCAGGGCCGATGTCAGGTGGACCAG +TCCTTTCTTAGGTCAGCAATTACCATGAAATGGGTCTTCTGTGAATCCTGACTCTTCAGA +CCCGGCAGGGCATGTCTCTTCCACTGCTCACAGCTCTTAGGAAGTCTTCGCTCTCCCTTC +CACAGATGCACAGAAATTCAAAACAAAGTTTGAAGAATGCAGGAAAGAGATCGAAGAGAG +AGAAAAGAAAGGTGACGTGGTGCCATGGGTTGGGGGGCTTCTTTGCAGACTCACTCTGCA +TCTGACTATACTTCCAGGCGGGTGCTTTTTCTGTCTGCCAGATAAACATTCCAGGGTGCT +GTGGCCGCCTCACGTATCCAGAGTGATGCAGCTCCCTGGGGACACAGGTGCTTCCTGGGG +AGCCCTGAGCACTTGTCAGTGTTGCTGGCCTCAGTCCAATTGGGCAGGCATTGGAGTCCG +GGCACTGCCTGGAGCTCACCAGAAGGTGCTTTATGATGGTCCTCGGTTTGTCTCTCAGAG +GGCTTGGTCACCTCTGCCATGAGGCTGGACTGCAGCTGTGGTGGCAAGTGACCAGATGTC +ACTGAGCAGCCTGACCATGGTCTAGGCAGTGCTTGAGTGCATCCACCTGGCTTCCTTTCG +TCACTGAATTTCAAGAAGACAGACTCCAGGAGGCGGCTTGGCCAGGCAGGAGTCTGTCCC +GAGGGCGGGCAAGCCGCTGTGGGTGGGTGACGGCACTTGGGACCAGCCTGGCGAGGGCCA +TGTGCTTGAATGCACCGTGCTTCTGTTTTCTCACTGTGCTGCTTGTGTTTTTAGCAGGAT +CAGGCAAAAATGATCATGCCGAAAAAGTGGCGGAAAAGCTAGAAGCTCTCTCGGTGAAGG +AGGAGACCAAGGAGGATGCTGAGGAGAAGCAATAAATCGTCTTATTTTATTTTCTTTTCC +TCTCTTTCCTTTCCTTTTTTTAAAAAATTTTACCCTGCCCCTCTTTTTCGGTTTGTTTTT +ATTCTTTCATTTTTACAAGGGACGTTATATAAAGAACTGAACTCAACATTCAGGTTGTTT +TTTTTTTTTGTTTCTAAGTTTTTGCCCTATTGAAGATGACTTCAGAAAATCCATTCCCCA +GTCATGAAAATGTACTGTGCTAACTTTCTTTTCCATAGTGGAAACACTTATTTATAGTCA +TCAAAAATAGTGAATAAAAAACACATTTGGAACCTGGGCCAGATGGCAGGACTGTGTGTG +TACAGGCCCCTGCGCTGTGAGCGCCGCTCGCCTAAGCCTCCCGGGTGTATGTCCAGGCCT +GTCCGCAGCACAGGTGGGTGCTGCACCTCACGGTAGCCTGGGTTCCTGGGAGAGACGCCC +TGGTGTCTGAGGTCGTGCATGTATCTTGCTGTGGGCCTTGAAGCTGAGGTGTCTGAGCTG +GCGCTGGTGAGGGAGCCTGGCCAGGGGTGTCTGGTGCCGGGTGTGGTACTGATGCACGAC +TGTGGGCTGGGCAGCGTGGGCTCTGCCGAGGCAGGCTCCACTGTGCCTTATGGCCTGAAC +AGCTACTGCTTTTTTTCTATGGTGAGGAGGGGTGGGCTTTCTGTGTTTTGAGGAGAGAAA +GGAAGACCACTGGAGTACCTTGGCTTTGGAGCAGGGAGGCAGTAGCCAACTGAGCAGAGT +CTCTAGCATCGGCCAAGGCTGACTTTGGCCCCTGTGGCAGAGTGGCCCCTGTGGAGGGAA +AGGCCAGTCTGGTGTGCTGGGGGTGGGGGCTCGGCCCTGTAGCTCTTCTTTTGGAAAGCC +TATTGTACCCTGGCCTTGGAGAAAACTGGGGTCTTGGCCTCCTGGACTTGAAGTCCACAC +TTGGCAGTGTTGGAGTTATGGGCATCTGCAGTAACTTTAAATAAGGAGATATTTTCCAGT +ACGCCATTGGGGGTTGTCATGTGTAATGGATTGTCTCTGCAAATACCATCTTAAGTGTGT +GGTCCCAACTGCCATAACGTGCCCTGTCACCGTTTGTCATGAACACCTACCAGACGTGCT +TACTGTGAGGCTGGCTGCCTGCTGCCATCACTTGCTCTTTCGTGCCCTCCACCTGGGCCT +GGGCCCTGTTCTCTCTGACCTCCGTGTGCTGTGTCCTGTCTGGTGACTGCCTGCTGGTTT +AAACACCAGTCCTTTGTCTCTCTGGGGCAGGGGTCCCCAATCCCTGGCCTGCCGACCGGT +ACAAGTCTGGCCTGTTAAGAACTGGGCAACACAGCAGGAGGTGAGTGGTGGGCGAGCGAG +CTTTACCACCTGAGCGCCTCCCCTCAGATAAGCAGGGCATTAGATTCCTATAGGAGTGCG +AACGCTAACGTGAACTACGCATGTGAGGAATCCGTGTTGTGCACTCCTTATGAGAACCTA +GTGCCTGATGATCTGGGGTGGACAGTTTCATCCTGAAACCACTCCCCCACCCCTGGTCCA +TGGAAAAATTGTTTTCCACCAAACTGATCCTTGGTGCCAAAAGGGTTGGGGACTGCTGCT +CTGGGGGATGTACTTCCAAAGTCAACTACTCTCAGGTTTGTTTATTTTTACATAAATGGG +AACCACTTTATGGTCTCTAGCATCAGCCAAGGCTGACTTTGGTGGGTCCCTGTGGCAGAG +TGGCCCCTGCAGAGGAAAAGGCCAGCTCAGGAGAGAAGGCTGTGCCGACTCCTCATGGTT +TCCAGTGCCCTACATGTTCAGAGAAACGTCTTTGGTAATGAACTATGGAAATGGTCCCTG +AAGGTATGGTCTTTGCTCTAGAAAAAGCCCAACTGATGACTCCTCACTGGCATCTTGACT +GTGTTCTGTGAGCTGTGGCCCTCATGCTCATGGACTGCTTGCCTCCAGCAGGTTGGCAGG +GGGACAGTGGTGCACTTTGCACCCAAGAAGAGGTGAAGCCTGTGCCCTATGCCCTGTGCC +GAGTGAGGTCCTCGTGTTGGGAGGGTGACGCCGTCCACTGCAGATGGTGCCTTGCTGTGC +TGCACTCTTGGTGACACCCGGGGCCCCAGGTCGGGTACAGGTGTCAGTTGGAGGCTTTGA +TGTCTGTGAAAGGGAGGGCCCCTTGCACTGGCTGGAGCTTCCAGGAGAGAAGCCCTTGGC +TAGGACAGGCACCCCCCAGCACAGAAAGGATGTTTAGCATTCTGTATTTGATTTGGGGTT +CCAATAAAATTCCAGGCTGACTTCCTTCATCTGGGGATGGGAGAAATGTCTCCAAGGGAG +AGTCCCCAGCAGTGAGAAGGCCCCTCGGAATGGCTGGGAGACAGTGCCATCCTGTGGTGG +GGCTGTGTTGCAGGGTGCATTTGAGGATGCAGCTTGTTGACACTGCAGGATGCGATGGTG +CTGCGGGAAGGGAGCTGTGCTGGGAGACAGAATGCGTCCGCGTGCTGGCCCCACGGGACC +ACAGGGTAGGCTATACAAGGACGCCCATGTGGGCACTCGGGCCAGCCGTCCAGCCCAGTG +TGTTTCCATTGGCTTCCCTTTGGCAGACAATGGTGAGCAGAATGGGGTCCTGCCGGTGCT +GGGGACTGTGTGAGAATGCAGTGTGCTTCAGCCTTCCATCCCATGTCTGTCTGCCGGGCT +GCAGGCTGGGGAGCCTCCTGCTTTCTGCTTCATTTTCCTTTTCCCTGGGATCTTAGCTCT +TCTTGAGGAGGAAACTAGGCCATGGGCTTGGCAGCCATGTTGGGTGGGGAGGCCGGTGCC +AACCTCGCTTGGTTCTCTGTCTCCAGTAGTGGGTCTGCACTACTTGGGACCCCTCTGCCC +AGGCCTCTGTGTTAAGGAAAAGGGATCCCAAGGCCAGATGCAATGGTTGACACCTGTCAC +CCCAGCACTTTGGGAGGCAAACGTGGGAGGATCACTTCAGGCCAGGAGTTCAAGGCCAGC +TTGGGCAACATAGTGAGAGACCCTATCTCTACAAAAAAATATAAAAAAAATAGCCTGGCA +TGGTGGTGCACGTCTGTGGTCCCAGCTACTTGGGAAGCTGAGGCAGGAGGATCACTTGAA +CCCTGGAGGTTGAGGCTTCAGTGAGCCATGATTGCACCACTGCACTCCAGCCTGGGTGGC +AGAGTGAAACCCTGTGTTAAAAACTCAAGGGAAAAGGGATCTCACCAAGTAGGCCTGATT +CCGCTTCTTCCCACTGTCAGCATTTGGCAGTTTACTCCAGGGTTCAGCTGGTGGAGGAAG +GTGACAGTCCTGGCACCCTGCACAGAGCATGGGCATGGAGTCAGACCTGGATCCTGAGGG +GCTCTGTGGCATGTGCCACTAGAGGAGGCACTTCATGGGGGAAGGTAGGAGCAAGGGCAA +GGCTGGAGATGGGCACCAGGTGGCAGGTGTGTTGCCAACTGAGAGGCTCACTTGTGGCCA +CTGCAGAGCCCAGGTAACGAGCCATCTGCTCCAGTGGTGTCTGCTCTAGGCTCACCATTG +TGCCCTGAGACCCCTCCACTGCCTCAGAGCTACCATCAGTGCTTGGGAGCGCTCCAGGCT +GCACCTCCTGGAGCAGGGCACCCTGAGAACAGAGCTTACCACTACGGCTGCCTGGGAGAA +AGCCCATCACCATTTCTGCTGTGCAGTAGTTAGTTGCATTAAGGGCTGGGTCCCGGCCCC +AGTCCTGGGTTCCTCCTTCCAATAGCCACAACCCTGGCCTGCCCACCCTGAGGAGCTGCG +GCCGGGTGCTTCCCCAGGGGAGCAGGGGCCTGCAGGCCAAGGAGCCTCATGCCTGTGCCG +CAGGGTAGGGCCGCTCGGGGTTCTGGTTGCAGAGGAGCAGACACTCAGGGCTGGGGGCGA +TGGGTGAGGTCCCCCCACAGATCTCCACCTAGGGAGGGGTCTAATGGGTCTGGGCTTCAG +AACAGGGGACGCTCGGGGCATGTTGGCGTGGCCGAGGACAATGACCCTCACTGGGGACGC +TCCGGAGCTTGACTGAGGGTCTCCCGCTGGCACCGCCTCCTCTGCCGGCGTGTGTGTGTC +TGGGGGGGGGACCCACACGAGGCCCCGCCCCACCCCGCCCACAGCGCCGTCGGCCCCGGC +CCGGTCCACCTTAAGCGGCGGCGGGGCGGGTGGGATTTCCTGCGGGAGGAGACGCGCCGG +GCCTATCGGGCAGGGCCGGGGCGCCGGGCTTCCCAAAGGGCCCCGCCTCGGGGAGGATGG +GGGCTCCAGCCGACCGTCTCTCAAGCCTGCAGCTCGGGCCAGGACGTGGAGGGCCCGGCG +CCCGCTGGCCGGGCTCCTCCAGCCCAGTGGCCCGAGGGAGGGCTGCGAGGCGGTCAGAAG +GCAAACAGCCACGACGCCGCTGCGGTGTCACACCCGCGCCCCCTCGTGAATTCCAAGGGG +CTTCAGACCAGAGGGGTCGTTAGGGAAAGGGCTGCGCCCACAGACGCCCCCGAGGCCACC +TGCACGGCTCCGCGGCCCGGGACCAGGGGGGCCTGGCCTTCGCCGTGGTGCCCACCACCC +GGGCCGCAGGGGTGCGTGGGTGCCCGGCCCCCGAGAGCCGCGGGCGCCCGCCGGGCTGGG +GTCCCCGAGGCCGCGGGGTCCTGCCCCCTCCGAAGGTCCCGCGAACCGGTGGCGGTCCCC +GGGCCCCATCAACTCGCCCCGCCCGGTCCCGCCCCGCCGCGGCCCCCAGCGCCCGGTCCA +CCTTAAGGGGCGCGCTGACATAAGAGCGCAGCAGCCGCCGCCGCCCGTGGGGTGGGATTT +CCTCCGCCGCCGCCGCCGCCGCCGCCGCGGGTCCTGCGCCGCGTCCAGCCCGCCCGCCCG +ACCCCGGCCCGACCCCGGCCGGCCCTGCCCGCCCGGCCCCGGGGAGGGATGCGGCGGCGC +GGCGCCCAGGATGCCCCGCAGCCCCGGGACGCGCCTCAAACCCGCCAAGTACATCCCGGT +GGCCACGGCCGCCGCGCTGCTGGTCGGCTCCAGCACCCTCTTCTTCGTGTTCACGTGAGT +CGGCGCCGCGTCTGGGGGCACGCGGGCAGCGATGGGCAGGGCCCGCACAGCCCGGGCACG +GGGGCAGCGGTCGCGGGGGCTGGCGGGGCCCCGGGCAGTGGGCGGGCGGGGCGCCGGCTG +CAGGCGATGGCAGTCCCTCTCCACCCGCTGGGGCTGGGGGAGTTGAAGCGGTGTGCCGGC +GTCCCGGGCACCGGGGTGAGTCCCTTGTGTGGGGACACCAGTGCGGGCTGGGCACCTCGG +GAGTGTCCAGGCAGGCCCTGGCGGGGAGCGCTGGGCCCTGGCAGGGGAGGAGGCCGGGCT +GCCCTGGGTGTGGCTGCAGCCCTTCCCTCCCCATGGGACCCCCGAGGGGACGTGGGCCAC +CCACAACCATGAGTCTTCTCTGCAGGTGGCCGTGGGTGCCTCTCGGGTCTCCTCCTGGCT +GCCCGCCCCGGGCCAGAGTCAAGTTGTTCCCACGTAGGTGTGGCCTGGCCTCGTTGCCAC +GTGCCTGCCCCACAGCCACTGGTGACCCGGGCCTGGCCCTTGGCCTCCTTCTCAGGAAGA +CCCAGTGGTCATCACAGCTGGAGGGCCCAGGCCAGGCCACACCCAGGGCCCGATGTTAGC +ACATCACCTCCGTGGGCTGGCCATGGTGCACACCAGGACCCTTGAGGTCCTGTTTCTGGG +AGTGAGAGCCCGCGCCTGCAGGACACTGGGCCCCTCCAGCCTCAACTTCTTCACCCAAGA +TACAGGCTGGCTTAGGACCAGAGAGGCATGCGGACAGCACAGCCTCCCTCTGTGGCTGTG +GGGTCACCCCAGGGCTCCTTCAGGCACAAGGAGGGTTGGGGGCTCCAGGCTTCGGTTGCA +CAGATCTTCAACCACCCACCCCCCTTCCACCAATCTGGGGTTGAGACATAGCCCAGGTGG +CACGAACGATGGCCACCTGTTCCAAGGTGGGGCCACCCCTGAGCATGTGAGCCTGGAGAG +GGGCAGGTAGGGGCTGCCTGGCGCTCGTCACCTTTGCAAGAGTTTGGGGGGCCCCCACGT +GCATCGCAAGGCTGAATCGGGTGCCCGTGGAGGCGAGAGAGTTACCTGCAGGCTGGGGCT +GGGTGGGCACCGCAGGCTGCCAAGAGCATGTTTAAAAAAGGCCTGTGTGGACGGGCTTAT +TTCTGGCTCGGGCAAGCCAGTGTGTTCTTGTCACTTAGTTGCTGCTGGTGTGGGGCAGAG +AGAGGTGGGTGGGGGGCAGCCTGGGGAGCCTGGCCTGGGGGGACACATCCCACCAAGGCT +TCTGGAGGGGTGGGCCCAGCCCAGTGCTGGTCCCCAGGGCCTCTGTCCTTGGGCGGGGGG +TCTGGCTTGGTTCCTTACTCTGTCCATGCAATTCAGTGTCCTTTCTCATGACTTTAAAAG +TAATGTGTGGGCCGGGCGCGGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCAAG +GTGGGCAGATCACCTGAGGTCAGGAGTTTGAGACCAGCCTGGCCAACATGGCGAAACCCC +GTCTCTACTAAAAGTACAAAAACTAGCCAGGCGTGGTGGTGGGCACCTGTAATCCCAGCT +ACACAGGAGACTGAAGCAGGAAAATCACTTGAACCCGTAAGGCGGAGTGAGCCGAAATCG +CACCACTGCACTCCAGCCTGGGTGACAGAGCAAGACTCTGTCTCAAAAAAAAAAAAAAAA +AAAGTATGTTCTTTATGGGGAACTTGTGAAATACAGAAAAAAAAAATGCTAAGAAATTAA +AATCAACCCCACACACCCCCCATCTCCTGTCCTCCTTGGAGGGCTCCTCTGTTCCTGGCG +CCGCGTCTGCAGCCTGGCTGTGTGGTGGCTGCAGCTGCTGGTTCCCTCACGCGTGATGTC +AGAGGGCCCTTTACGTGACTCTGACTGTGAACCTGACCCAGCCCTAGGCATGGAGTGCTT +GGGTGGCTCCCACTCTGCTGAGCACCAGTTTCCCCTCCTCTGTTCTGGGGTTCTGGTTTC +GGCGACACCAGCAGTCTTGAGGTATGGGGTTCCCTCCTGGGGCAGTGCAGGCCATGCCTG +CACCCAACCCTACACCTGGCCTATGCTGACCTCTGCCGGCCCTGCTCCTGGGAGAAGATG +CCATGTGTCCCTGTAGCAGGATGGTGGCCTGGGTGCTCACCTGGGTTTGATGTGCAGTGG +CCACCTAGCAAGGCTAAGAAGCCCTGCTTGCCCCCTCAGGGCAGGTGAGGCCACACCCCT +GGGCTGAATGGCTGTCAGTGATCCTGGCCTCTTCCCCGACCCGCCCCGCCTCTGCTGAAC +TCCTCCGAGACTGCTCAGTTCCTGAGAAGGGGTTCTGTTGGGTCGGCTGGCCCATTGATG +CCACCCATAGCAGCTGTGCTGATTCTGGGTAGGCAGGGGTCCAGGCGGCCCCCTTCTTGG +GGCAGGCCACTTGTCTACCCGTTGCCCCACCTCCTGCCCTGTATCTGGTCCAGGCACACA +GGAAGGGGAGCAGGTTGCTCTTGTGCCCCGAATCCCTGCCCTTAGTGCCTATACAGGGTT +CCCGACTTCACTGTTTGCTCCTCGGACGTTACCAGACAGTGAGTGGCCCCAGCCCCCTCT +CTGCACTCAGTAAACATGAGTTGCTGCCGGTGGGGTGGCTTCACCCATGCACCAGGTGGG +CAGGAGTTCTGGGTGTCATGTGGTGTGGGGAGCTGGAGGCCTGAGAACCAGGGACCCCTC +CCTCAGCCAGATCGCCAAGGGTCTTGGGACCAGCAGGACATTCACACATCTCTCTAGGAG +GGTCTGGGCATGGAAGGATGCCCAGTTGTGAAGAGCACCCTCTCAGGATGGGGCACATAC +AGCAGGGCAGTTTCTCAGAGGCCCTCTTCCTTCAGGAAGCCTTCCTAGGATTTTGTTGTT +GTTTGTTTGTTTGAGACAGGGTCTCACTCTGTCACCCAGGCCAGAGTGCAGTGGTGCTAC +CTCGGCTCACTGCAGTCTCGACCTCCTGGGCGCAAGTGATCATCCCACCTCAGCCTCCTG +AGTACCTGGGATGACAGGTGGGCACCCTCACACCTGGCTAATTTATTTATTTTTTGTTTT +TTTGTTTTTTTTTAGTAGAGATGGGGTCTCGCTATGTTGCCCAGGCTATTCTCCTGAGCT +CAGGTGATCTGCCAGCCTTAGCCTCCCAAAGTGCTGGGATTACATGTGTGATCACTGCTC +CCGGCCCCTTCCTATGTTTCTGGGGGTTTTGTATCCCCCTGGGCTTCAGAAGCCCTTTAT +ACCATGGTATAATGCTAGGCTGGGTCAGCTGCTGGCAGAGGGTTCGAAGACCCCTAGGCC +AGGCTCCCGACCCTGCCCTGACTTCACTCCAGAGCCACATTGCAGAATGACAGGGACCCT +GTGAATGTCCGAGGGCTGGGGCTGCCTGGCAGGCTGCCAGTGCCTGGGGCTGAGCCAGGC +TGGCTTATCTCTGTCTGGGGCATCTGGGATGGTGTGGCTGGTCCCTAGATCGTCCTGAGC +CCTCTCCTTGCCTGGAGGCCCAGCTCAGGACAGCAGTCAGAACAGGCCCTGGGCCAGACT +AGCCTTGGTGGGCCAGGAGGGACTGAACTGCTGACTGGGACCTCATGAGTCTGGGGAACC +TGGGAGTGAAAACTCAGTGTGAGCCCCCCTGCTGGGACCCACCGCATGTGGCCTGGGGTA +TTCCTGGCCCCCGAGCCTCAGTTTCCCCATCTGTCCAGGTGTCTATAGGGATTGGACAGG +TAGGTGCAGGTACTTCGAGGCCCAAAGGCCTGGCCTGACAAGGGCGCAGCAGCTTCTGCC +CCGCCGGTCCCGAGCGCCCCACGGGCGAGTGCCACTCATACACAAACAGTGCTAATGAAG +AACCTGATTTAAATGAAAACGTCTGAGTTAAAATTTTCCATTCCACATTTAGCTGTGGCG +GACATTCTGCCCCTAAGCCACCCCTCTTGCTCGGCGGTATCTCCCTGCCAGCCCAGGCGG +GACTTGGGGCCTCAGCCCGGGTGGGGCCTATGGTGGTGGTGCATGTCCCTGCCTGTGGCC +CTGGAGGAGGGATTGGAACCTCGGGGCTGGGCCCCCTGGACCTGCCCTCCACCCGTAGCT +TGGCTGGAGCCAGCCAGGAGGGGCTCAGAGGGACATGGCGGGCCAGACACTCCACCTCCA +GCCCAGGCCCAGAGCCTGTCTTTGCCTGGCCCTCCGGCAGGCGAGCCTGGTGTGCACCAT +CAGGTCTGGGTGGGAGTGGAGCCTCCCCGAGCCTGGACCCAGACTACTGCCTGCTAGGCC +CTGCCTGTGGGAATGCGTGTCTTTGAGTGTCCCTGAGCATCCACACATGGCCTCCCCTGT +CCCCATGTGTCCTCATGCATCCTTGCATGTCCTTGTGTGTCCTCCCGTGTTCTTGCGCAC +CCTGAGAGTGCTTGTGTGTCCTCACACTTGCCCTATCCACAGAGGGGCAAAGGGAAGCCC +AGAGAGTGGGAGGGCCGTGTCTGAGGCCCAGAGTGAGGGGCAGCCGAGCCGAGGCTGGAT +AGGGCTGGGTGCAGTGTGAGGAGGCATGTGTCTATGCATGCCTGTGTTCACGCGTGTTCA +CACATAGGTCTTGGTGGGTGAGTGATGTGCAGGCGTGTCTGCGTTCATGCATGTGCACCA +GTGTGTGCACGTGTGCATGTCTGCATGCAAGTGTTCATGCATGTATATGTGTTTTGTATG +CAGACATGATTGCATGTGTGCATGTGTGCCTTCTGTGCACCAGAACAGGTTGTCTGTGTG +TTTATGTGTGTACATGCCTGTATATTTGTGTGTGTGCACACATACCCATGCACATGTGCC +CTGGAGCATGTTTGTGTGTGTGTCCATGTCTTCACACGTGTCTGTAGGTGCCTGCGTGTG +CTCCTCATCTTCTCTCCCACTGAGCCCTGAGAGCTCTGGGCCCTGGTGGGTTGGCCTGTG +AGCTGGTCCCTGTTAGGCAGGATCTGACCTTGGGGACTACAGAGAGGACAGTTGCCTCAC +TCTGGAGGACTGGAGGAGTGGGCAGCAGCTCAGGTCCCAGTCAGAGAACCCACAACAAGC +CTCCCCAACCCCTGGATTAGGGCCCATATGGGCCCTCACAGGCATGTGGCAGGTACCCGC +ACTGGGCAGGAGGGACCCGGTCACACTGCAGATTTCCCAAAGTAGCCCCACGGCTGCAAG +GCTGCTGTCCAGCCCGCCTGGTGTGGGGGAGTCCAGGCTCAGGGAGGACACAGCAGTACC +GCCTGCTTGGGCTGGCAGGGAGCTCAAGTCAGCATGGGGTTCAGGCCCCGCCTGCCTGAT +GGGCGAACACACCCCCAAGGCCCCCGTTAGGGCCAGGAGGCAGGCTGGCAGCCAGCGCAG +GTGCAGAGGGGCCCCGAGGCTTCCATCCTGAGGTCAGCACTGGGAGGACAGAGGCTGCCT +CCTTGCAGCCCGAGGGTTGACCAATGGCACTCGCCGCATCCCTTCCCAGAGCAGGCCAGC +CCCACGGGCATCATGAGGGCCTGCGTTTGGTTTAATGCTCCGCTGTCAACATCTTGAAAT +TCTCTGTAATTTTTAAATAAGGGGCCCGCAGTTTCATTTTGCACAGACTATGTAGCCAGC +CTTCCCCAGAAGGCTCGTGGAGAGCTCCACAGGCCCTGCCTCTCCCTGGGGGAGCTGCTC +ACCTGCCTGTGCCCATCTTGTTGGGCCGACCCTGCCTTAGGGGCCTGTGGTCCTGGCTGA +ATGGCGTTGCATTGGAGGCCAGGCACATGTTTGAGTGCTGCCTGTGTGCCAGGCAGGGCT +GGGGAGGGTGGAAGGAAGCCTGGGGGCTGAGCCACTGGGCAGGGACAGGGAGAGCCCTCC +CAGCAGAGGGAGGTGTGGCCGCAGCTGTGTCCTCACCCTGGTGTCTACCTCCACGGGCTG +GGCCCTGGACAAGAGGAAGGGTAACTTGGGCTCCCAGCCCCGCCGAGGATGGCTGTCGTG +GGAAGCGGAGTCTTTAAATAGCCTCTTGCTTTCCACTAAAAATAGTGAAGCTCTGCTGCC +GTGGAGGTGGTTGCCGGGGCGGCGGGGCTGGCTCTTGGCCAGGCGGGCGTGGGTGCAGCA +GCGTGGCCACGTGCGCTGGAGTGGTAGGCAGCGCGTGGGCCCCATCCACTGCTAGTGGCC +ATAGAGGTCAGGGCTGCTGTGGGGGATCCCCACTAGCCCCCCGACTATGCAGAGGGCCTG +GGTGCAGGGAGGGACGCAAACCCCTGTGTTCCTGTCCCTGCTGCTTGTCACAGCAGCTGT +CTCAGGGTGCGCAGGGGAGAGACAAGGAGCCTGAGGCCAGAGGGGCTTCTTGGAAGCTGA +GTGGGTGGATTTAGGAACCCGCTGCAGGCCGTGTGGCCCGAGGACCGGCAAGTCTCTTCA +GAGGGGACTCGGGCCAGGCCCGTTAAGGGCTGAGGAAGGCGCCTTTCAGGAAGGTGTGTG +AGGGCACACCTTATAGGGAAGCTGCAGAGGGCAGCCTGGAGTCCTGGAAAGCTTCCCGGA +AGAGGGGGTGGCCTTGGAGCCAAGTGCTGATGGCTGGGAAGATGGGAAGTGGTGGGGGGT +GTTGTGCATTCTAGAGTCCCTAAGTGTTCTACTTTGTCATCTGGGGAGGGAGGTGACAAA +CTAAAAAGAAGGGGCTGTCTGGATGGGGATGTGCCTGACTGGGAAGAGTAGGGGAGACAT +GCCCCATGCACTTACTGACCAAGGACTGGGGCTCCCCACACCCCAGAATCTGCCTGGTGA +GAGGCCCCACTGGGCCAGGGACAGGCCTGGATGAGGCATCGTGGCGCATTTTCCATCTGG +GGCTCCCACCTCCAGCCTGTGTACCGCCCCCGCCCCCTACCCCGCCCCAGTCATGGAGCC +TAGGTCGCTGGAATGGGGTGACCTTAGGTCTGTGGGCCTCTCTGAGACGGCTGCCCTGAG +AGGTTGCCGGGTCAGGGCACGGGTAGCCCACATGCTGTACTGATACGCACAGCCTCTGGC +CGTTACTCGAAGGAGCGATGTGGCTGAGGTTTCTTGGCAGGGCTGTGGCAGCCTCCCCAC +TGCCTCTGAGCTCTGAGGGTGACCTTGCAGGCCCAGCCTGCCGCACCACATAGCTCTGCG +CCTGCATCCGCTCTGCACCCCCAGACTCCACTCTCTGCCCCCACTGTCTACTGCAGGTGC +CCGTGGTTGACACGAGCTGTGTCCCCAGCTGTTCCCGTCTACAATGGCATCATCTTCCTC +TTTGTCCTGGCCAACTTCAGCATGGCCACTTTCATGGACCCTGGTGTTTTCCCCCGAGGT +AGGGCCCTGTGCTGCGGCAGCTCCTCTCACTTTCACTAGAGTGTGAGTGGCTAACTTGAG +ACAGCCTTAGGGATTCCTGGTGGGTGGGCTGGACTTGGGGGAGGGATTCACCTGCCAGGA +AAGTCAACTTCCTGCTCACTGCCTGGCTCCTGGTCTGTAGCGGATGAGGATGAGGACAAG +GAGGACGACTTCCGGGCTCCGCTGTACAAGAACGTGGATGTGCGAGGTATCCAGGTCCGC +ATGAAGTGGTGTGCCACGTGCCACTTCTACCGCCCGCCGCGCTGCTCCCACTGCAGCGTC +TGTGACAACTGTGTAGAGGTGACCGCCCTGCTGCCCCGCGCTCCCCCAGCCCTGTGCCAC +ATCCCTGCCTGCCATGTGCCCTGATGCACTGCTCCCGCCCAGGACTTTGACCACCACTGC +CCCTGGGTCAACAACTGCATCGGGCGTCGAAACTATCGCTACTTCTTCCTGTTCCTGCTG +TCACTCAGTGCACACATGGTGGGCGTCGTGGCCTTCGGCCTGGTCTACGTGCTGAACCAC +GCTGAGGGGCTGGGAGCCGCGCACACCACCATCACGTATCCTTGGTTCCTGTGGGCCTCA +TTGCAGAGGCGATGTGGACCGGGGACACGTTCACCAGGGAGATTGAGCCTCAGAAGGCTT +GGTTCCTGCCCAGGGATCCCCAGTGGGCAGGTGGCCGTCCCTAGGTTGGGAGGAGGTTTG +TCCACAGGCACCTGCTCTGTGCTGCTGCGATGGGGTCTGCGGTGTCCTGGCCTGCACCGT +TGGCCTTAACGGGCTAGCATGGCTGTCATGTGTGTGGCCGGCCTCTTCTTCATCCCTGTC +ATTGGCCTCACTGGCTTCCATGTGGTGCTGGTCACTCGGGGGCGCACCACCAACGAGCAG +GTGCAGACCCCATGGGGGATGGGTGGCCCCAAAGGGCCGAGAGAGTTGGGGCTGCATGGG +GACAGGGTGGGGGCTGGGGCACCCTTGCCTGAGGTAGCTTGTGCAGCTGTGTTGAGACGA +GGCTCCAACTCTGAGACCCCCACGTGGGGCTACGCCTGCCCCGTCCCCTGCGCACATCCT +GCCTGTGGACACTGTGGCCACCAGTGACCCAGAAATCCCACAGCTCCCTGCAAGTTCAGG +CTGGGTAACCTATGTGAGGGGCAGCCCTGGGCTGATCCCACCTAAGCCACTTCCCGCAAG +TATCAGCTTCTAAGGAACCCCAGCTCCCTTGCCCAGCCCCCTGCCCACCCTGGCCTGGAC +CTTGGGAGGCCAGGCTGGCTGAGGGTCCTGCATCCACAGGTGACTGGGAAGTTCCGCGGG +GGTGTGAACCCTTTCACCCGAGGCTGCTGTGGGAATGTGGAGCACGTGCTGTGTAGCCCC +CTGGCGCCCCGGTGAGGCCCGGCCTGGGCAGGGTGGAGGGGGGCCTCTGCTGGGTGTGGG +GCGGGCAGCCTTAGACCCTCTTGGTCCGTTTGGCTCTTGCCAGGTATGGCCAGCCCTGCC +CTTGTGTGTTTGTGGCAGGTGGGCTGGCTACTGACCCCTGTGCCCTGGTGCAGGTACGTG +GTGGAGCCACCCCGGCTGCCGCTCGCGGTGAGTTTGAAGCCGCCTTTCCTTAGGCCTGAA +CTCCTGGACCGAGCTGCACCGCTCAAGGTCAAGCTTAGTGACAACGGGCTGAAGGCTGGC +CTGGGCCGTAGCAAGGTGGGCGCCTGGGCTTAGGGATGGGCTGGCAGTCAGGCCCTTGGA +TGGGGAAACAGGCAGGTTGGTGGGGGCCTAGAAGAGGTGGATGGGGCAGACAGAGCCGTA +GACAGATTCTTGGGAGGGGGCTAGGTCCCAGGCTGAATCCCTAGTGAAGCCCTGCCCCTC +ATCCAAGCCCCACACACCACTGACCCCGCTCCCTCCCAGTCCAAGGGCAGCCTGGACCGG +CTGGATGAGAAGCCACTGGACTTGGGGCCACCACTGCCCCCCAAGATAGAGGCTGGCACG +TTCAGCAGTGACCTGCAGACCCCGCGCCCAGGCAGTGCTGGTGAGGTTGGGGCAGCCACG +ACTAGGGAGGGATATGGGTTGACCCTCCTCTGACCTCAGTCTGACAGTGGTCTGCATCCC +CAGAGAGTGCCCTGTCGGTGCAGAGGACCAGCCCCCCGACACCTGCCATGTACAAGTTTA +GGCCGGCTTTCCCCACGGGTCCCAAGGTGCCCTTCTGTGGACCAGGCGAGCAGGTAAGGA +GGCCTAGCCTGCCCCCTGGCAGGCCTCGTCCCCCAGGCCCGCCTCTAGGAGCTCGCCCCA +CAGCCTTCACCCCGTGAAGGCCCCACCTCCAGAGCCCCATCTCTCCAGCAGAGGCCACAT +CCCCTGAGGCCATGCCCCTCAGGGCTCTGCCTGGGTCACCAAGGGCCTTGTGTGACTGGT +AGGACCCTGTCTGTGTGCACCCAGAGCTGGGACCCACAGAGGGGAGCAGGGTGTCCTGGG +AGGGGCTGGCGTGGGCCATCCAGGCTTGGCGTCTGTCCCTTGGCCAGCATTGCCCTAGGC +CAGGTGGGCGGCTGCCCCCAGGAGCACTGTGTACCAGGATGCCTGGAATTCCACCATTAG +TCACTCTGTAAGGCCCACGGGAAGACTTTGGAAGAATTTGAGACGTGCTTGAGAAAGCAC +ATTTCTCTTCCCTGAGTTGCATGAGTGCTCTGTGGTCACTGGAATGGTGGGCAGTGCGGG +GCGGTCTGTGCAGTGATCAGGAACACCAAACAGTCCCAGGGTGCCATCCTTCCTTCTGGG +CCACCCCGAGAGGCAGGCCTGTGACTGGGCCCTGTGCACCTAGACCAGCCCCATCCCCAG +GGACCTCTCCCCTCAGGACTGATGTCTTTCCTGGAGAGAGTCACTGGGTGAAGCAGTGAG +TCTGAGCCTCCTTGGCCAAGGGTCTGAGTCTGCAGGCATGTAGGGGCCGTGCCTCGCAGG +AGGAGGCATCCCTGTTTGGAGATGAGGGCTCTGGGTATGTCATCTTCCTGGGACTCCTGG +GTCCAGTGGGGGATTGGGTCTGGTTGGCCAAGTGCATTGAGCCCACATTTGCCCTGATCC +ACTTCTGGCTTTGTGGTTCCTGAGGCTCTTGTCCCAAGCCCAAGCCCAAGCCCATGCCTA +TGTGCCCGTCACAGGGGCTAGACGAGGCTCCTCCTCCCTCTGGCTGCCCTGAGTGGTGGG +CCCCTGGGGCTGCATGGCTCCAAGGGCAGAACCCCAGGTGTCTGCAGTAGCCAGCTGTGG +CCTCCCTCCTGTTGCAGAGCCCCTGCCCCTCAGCCGTGGATGCTCAGGGACAGGGCCATG +GGTCACTATGTGGCTCTTATGGCTCCTTGAGGCCCAGTTCCTGAGGCCACGGTGCCATGT +GTGGCCCCCGTGGGTGCTGACTGGCGGCTGCAGGCGGGGTGGCAGGTGGGCAGTGGTGAG +AATGCCTTCTCCCTACAGGTTCCAGGCCCTGATTCCCTGACCCTGGGGGACGACAGCATC +CGTAGCCTGGACTTTGTGTCCGAGCCGAGCCTGGACCTCCCTGACTATGGGCCAGGGGGC +CTGCATGCAGCCTACCCGCCATCCCCACCGCTCAGCGCCTCTGATGCCTTCTCGGGCGCT +TTGCGCTCCCTGAGCCTCAAGGCCTCGAGCCGGCGGGGCGGGGATCATGTGGCCCTGCAG +CCCCTGCGCTCTGAGGGGGGGCCCCCCACGCCCCACCGTAGCATTTTTGCCCCCCATGCA +CTGCCCAACCGCAACGGCAGCCTGTCCTATGACAGCCTGCTCAATCCTGGCTCGCCTGGT +GGCCACGCCTGCCCTGCCCACCCAGCAGTTGGCGTGGCCGGATACCACTCACCCTACCTG +CATCCTGGGGCAACGGGCGACCCGCCACGGCCCCTACCCCGCAGCTTCAGCCCCGTGCTG +GGCCCCCGCCCCCGGGAGCCCTCGCCTGTGCGCTACGACAACCTGTCCAGGACCATCATG +GCATCCATCCAGGAGCGCAAGGACAGGGAGGAGCGTGAGCGCCTGCTGCGCTCCCAGGCC +GACTCACTCTTCGGCGACTCAGGCGTCTATGACGCTCCCAGCTCCTACAGCCTGCAGCAG +GCCAGTGTGCTGTCCGAGGGCCCCCGAGGTCCCGCGCTGCGCTATGGCTCCAGAGACGAC +CTTGTGGCTGGGCCCGGCTTCGGTGGCGCCCGCAACCCTGCCCTGCAGACGTCACTGTCC +TCGCTGTCCAGCTCCGTGAGCCGTGCACCGCGGACGTCGTCCTCCTCCCTGCAGGCTGAT +CAGGCCAGCAGCAACGCCCCGGGGCCCCGGCCCAGCAGTGGCTCACACAGGTCACCTGCA +CGCCAGGGCCTGCCCTCCCCGCCCGGCACTCCCCACTCACCATCCTACGCGGGCCCCAAA +GCTGTCGCCTTCATCCACACGGACCTCCCAGAGCCACCGCCCTCGCTGACCGTGCAGAGG +TGGGTGCCGGGAGGTGCGGGTGGGCTTCCTGGCACAGGGCAGCTGTCCAGCCGTCTCCAG +GGCCCCTCTTGGCTGGGCACTCATAGGTCATCCCAGGGGCCTGAGTTTTTCTCTGGGGAC +GGGACAGGGAGGATGCGCCTCACCCTGCCTTGAAGGCCTTGGCTAGCCCGTGTGGCCCAG +CTCTGAGGATGTCCTGGGCACGCTCTGGGGACAGGGTATGAGAATTTGTGTCCTGAGCCC +GACGACTCGTTCTTCTAGAGCTGGCACAGACCCAGCATGTGGGAGGCCATGGGGCTTTCT +CTTTGGGGCCAGTATCATGTGGCAGCCTGGGCCTCCTTTAGGCTGTGGCTCTGGCTTCCT +GGGTCACAGTGGCCCTGTCCACCCAGGGCTCTCCCTGGGCCTGCTTGGCTGCATCTCTAG +GAGGCTGGGGCTGAGGATATTACCTAGCAGCAGAATGTGCCACCCTGAGTGGCCGGGCCC +TGGCCCTCCCTGTAGGACATAGTTCTAGGAAGCAGGGGCTTCCCTGCTCGTAGGTGGGGA +AGCTGAGGACTGGAGAAAGCAGGCTGGCTCCAGGCACCCGGCAGGTTGGTGACTGAGAAG +GCGGGGTCAGCTGGCTCACAGGCCCAGGTCCAGGTAGGAGAGCTGCACACCTGCTGGGGC +CAGGACCCACGCCACAGACGCATGGTGTCCTCACGGCATCTGTCGCCCTGTCCGGGCCTG +GAAACCTCAAGCACAGGCGCAGTTGTTTCCCGTCGGCAGATGCAGCCCCAGAGGGAGAGC +CCAGCCCAGCCCAGCCCAGGCCACTTGGCCACAAAGGGGCTGAGGGCACAGCAGTCCAGC +CCTGAGCGGGTCTCCTCTACCCCACAGGGTGGGACCTGTTCAGCTTTTGTGGAGTTGGGG +AGGAGGCTGCCACTGGGAGTGATGAGTGGGGAGCCCGAGACCTAGAAGTGGGCAGCATTG +CAGCCAGGCAGGGATCGCAGCCCGGGGACAAAGGGCTCTCGCCTCAAGAAGGTTTAAGTA +GCAAAGATACAGCTGCTGTTGGTCAGCGCTGGTGGGCAGGAGGGCAGCCCCTCGTTTTCC +TGAGAGAGAGCAGGAATGAGGCCAGGCAGAGTGGCTGGGCTCCCAGTGCAGGGCACGGCA +GGGGCTCCATTCAGTGCCCACCTGGCTGCCCCATGCTCTCTGTGGCCAGTGCTGGCTAGG +AGGGACCCAGGGACTCGGGAGGGTGGTGGCAGTTCTGACAACATCTGTCTGTCCTGTGAC +AGCACAGCTGCTCCCCAGGCAGGCTCTGCATCCCTCACCTGCTTTCCAGGTGAACCCTCC +AAGCCCAGAGGGCAGGGACTGCACGGGGCCCCACAACTCGGCTGCACTAGTCCACGTCCG +CGTCGTCTCTGTCTTGCTGCCTCCTCCGTCCTCTGTCCCCGTGTTCGTGTGTTCACCGTG +TGCATGTGTGTATGTGCTTGTTTTGATGCAGGGACCACCCTCAGCTGAAGACTCCCCCAA +GTAAGCTTAATGGGCAGTCCCCGGGCCTGGCCCGGCTGGGACCTGCCACCGGCCCCCCAG +GGCCCTCTGCCAGCCCTACACGGCACACGCTGGTTAAGAAGGTGTCCGGCGTGGGTGGGA +CCACCTACGAGATCTCGGTGTGAGGACTGACTGCCACACATCCGCCATGGTGCCACGGGG +ACCAGGACCCCACAGCGCACCCCCCCTCCCCACCAACTTCTCTGCCCCAGGGACCCGAGG +CCACCCCAGCCTGGTGTGGACCCATCGGCGGGAGAGAGTGCCACGCCTCCACAGCTTGCC +CCAAGCGCTCTGCCTGCCCGTCCACTCATCTGCCCATGGGGAAGTCGGCTCACTGGGACA +AGGGCCACTGGGCTGGTCTGTGTCTGGGCCTGTCCCATGGCTGGGGCAGTGAGGGGGCCC +AGTCAGCCTCTTTGGGGCACCCTCTCTCAGCCAGGCTTGGCCCACTGCCATCACCCAGCA +CCCCAGATCACCGCCAGGCCAGCCCCCAATGGTCCCCTTACGGACAGGTCCCAGAGATGG +ACAGAGGCACCCAGGGCCCCCACCGTCCTTCTGACACAGCCTGTGGGCTCCCGGACCGAG +TGTCCCCCGCCAGGCTACTCCTAACTAACGCGTTGCCTTTCACGGACCCCGCTGGAAGCT +TGTAGCTTGGCAAGGCTGATGCTTCTGCCCTGGCCTGCTCTGGGTGGTGGTGGATAGGTG +GACAGACGGCCAGCCAGCCAGCTGTGGCCGGGGGCCCGGCTCCATGTGTCCCGTGTCTGT +GTGCTGTGCTGCCGCGCCGTGTCTGATGTGTCAGTGCTCCGGCCGCCGCTGTCCCTTTCA +TCAAAGCCTTAACCTTTGCTTTATGCTCTTGTGGGAGGCGACGGGGGGGCAGGCGGGAGC +AGGCACGGGGGTGATGCTGCCACAGGGGGCTGGTGACACCCAGAGCCCCCTCCCCAGCCC +TCAGGCCCTCCCTGCCAAACTGGAGAACCCCACCCCAAGGCATGCCACGTCCGCAGCCCC +GGCCTGGCTGCGGTGCTCGCGCCGTGGGAAAGCACACTGGGGAGGGGTCAGTGCTTCCCT +TGGTGTCAGGGACCTGAGAGTAAGCACATGACAGCGTCTGCTTGCGTTGTGTCTGTTTTA +TGTTTTTATATCTACATCTATATATCTATAATTTTATTAAAAAAAAGAAAAAGAGTTATT +TTGATTCTTTCCTTGGGCAAGGCCAGGGCTATTGCTGCAGGATCCCGAGTTAGGGGAGGG +CAGGGGCCGGGCCCCAGAAGAGGGAGTGGCTGCTGTCTGGTGTGCAGGGGTCGGTGGGTT +CCTCAGGGGCATTTCTGCCGACTTGGGCTGAGTCAGAGGCTTGGGAAGAGGGGGCGGCCG +ATGGTCTGTGGCTGGGAAGTGTGAGGGTCTCTCGCCTTGGGTCTGTGTCAGTTCTGGCAG +TGACAGGGTGTTTGGGGGAAAGACTTGGGTCTGCCGCTACCCACAGGGGACTCTCAGGAA +CCCGAGAGCTTGGGGAGATGAAATGGGGGTGCATAGGGGCCACCTGTTGGCTCAGGGCCC +TGTGGGGGCCGCTGAACCTGCTGGAACTCTCCTGCCTGCCACATGCCAGGGGCAGGGCTG +AGGGAGTGTGAGGGATGCACAGCTGTTCAGGGCTGAGACATTCTGGGCTGGGGCTGTCCC +AGCGTGGGAGGCGTGCGGGCTGTAGGGCCCCGAAGCTGACCTCCACCTTTCTGCTTCTCT +CTCACGGACGCCGCGGCCCGCAGGGGGCGGATTGGCACCTGCACCCGTGGATGGGGGCGG +CGTGGCCAGCCTTGGGTGCCTCCTGGGCTGCACCTGTGCCACCTTGGCCGCCCGGAGGAC +CGCCCACCACTGCGGGCCCCCTGGAGCCAGGCCGCCGGGGCACCCCCACGCGGGGCCATG +TGCCGCCTGCACTTGGCTGCCTCCAGTCTTTTCCCCAGCCTCTCGGGGCCCTAGCAGGAT +GACAAGTAGGCGGCTCTGGGGCCCAGGACAGCCCAGCTGGGGACCCAGGAGGTCAGACTG +CAGTGGACCCTGGGGCAGGGCTGGGGGTGGGCTGGGCTCTCTGCTCCACCAGCCACAGCT +TGACAGATTCCCAGCCTGCCAGGGCCTGAGACCCTGTGTCCACATGACCTCAGGGAGTCC +CCCACCTGCTGCAGGGGGTCCAGCACCCCACAGGGGGGCAGTCCCAGAGCTGTGGGGACC +GGCACGACCTTTGCCCAGCCTCCCTACCCAACCAAGCACTTTAGACTAAGCCACTTCCTC +CTCGGGGAGCCCAGGCCTCCGTGGGTTGGGCTGGGTGGGGGGGGGGTCTCAGGTTGCCCC +TGAAGGTCTCTGCACTCCTCCTGCCCTTCCCCTGACACATGAACAGATGCCTTAACTTCC +TGGAGCCACCAGCCTGGTGAGCCATTGGCCTCTGCCTGCCACCAAGGTCCTGTGGTCTTG +GCCAGCTCCGCCTGGGCCCCACTGGGGCTGCCTGCACCCAGAGACGATGCCGGCGGGATC +TCAGAGGGCCTGAGGCCCAAGCCCTGTGTCCTCCAGCAGTGGTACGGCCTGCGGCAGGGT +GGCACTCCGGCCAGCCCTTCTCCGTCACAGGGTCCCTGTCCCTGGGTCCACCCTGGGCTG +TGGCTCTACATCTCCCATTTGGGGACGAGAAAGCCACAAAACCATTCTCTATTGTTCTTA +AGGGTACCCCTGCTAATTAATTCCCCAAATAAAATTTTTGGTGTTGATCAGCTCTGTCTA +CCAATGTGGTCCCCTGGACCGGACAGGGCCCTGGGTTGGGGAGGTGACAGGACCTGGGCA +GGGAGGGTGGTGGCCAGGAAGGGAGGGGAGTTGCATGAGGGGCATGAGGTCAGTGGATCA +GCAGGTTCAGCGCTGAAAACCTGACCTCTGAGGTCCCTGGGAGGGCCTGGCCCAGGGGGC +AAGACCTGAGGACCCCCCAGTCCTTACTGCTGTTGCCTTTCAGTGGAGACCCTCCTAAGA +CGCCTTGGGGGGTCAGAGCCCCGTGCAGAGGGGCTGCCTTCTGGAGGGCAGGTAGGATGT +GGGGTGGGAAGCCGGCCCTGAGCTGGGGTCTCCACCCTGAGGGACCCTCGCTGCAGGATC +GCCTGGGCATCCCTCCCCCAATTTCCACAGAGACGTGCTCACCGGCCACTTATGTCATGA +TTCTATGTCCAGCCACAGGCCCAGCCCTCAGGACAGACCCCACCTCCACCCTTCTCTGCA +GCTTCTGGCAAGGATGGTGCACAGTGGTGCCATGTGCAGGGGGCTGGCACGGCCACTGGG +CATCCGGGGCAGTGCTGGTCGCCTGGCCTCCTTGCTGGGGCCGCTGGGCCTCTGGCCTAG +AAGGGCAGGAAGCCGTCCACTTTGAGGCGCAGGAAGGGGTCCAGCAGGGCCCGGAGCTTC +CAGACGGTGGCACGGCTCAGCAGGGGTGGCACCAGCCCCTCGAAAGGTGTGGGGTTCACC +ACGTACACGTAGGCAGCGGTCCAGACCAGCAGGGCGCCCAGCAGCAGCCTCAGGGTCAGC +AGCCTGCGGGCGGCGGTGGTCAGGGGCAGGGGCGCGCGGGGGGCCTGGGGGCTGGGCTCT +GCCGTGCAGTCACCTACCAGAGCTGGCCTGCCAGGCCCTTGGAGCTTCCCAGCTTTGGCC +TCCCTTTCTGTCGGGGAGGGGCTGGATCAGAGCCCACCCCGAGTGTCCAGGCTGAGGGCA +GGGATCCCTGGCTTTGGGAAACCCTCCTCAGACAGGGCTCCCCGCACCGCAGCCCTGGCC +CCTTCCTCCTGGACAGGCTCCTGCAGCCACTTTTCCGATGCCCCCTGCCCTGGACCTGCC +CTCCTGGAGCCCATTTCTCCCTCTCGCCCAAGCAGGGCCCTGGGTGGGGGGCTGGTCTCC +AGACCCAGAGTGGGGCGTGGGGGGCTCACCGACATGCTTGCCATCTGCTTCTCCTTCCTG +GCTCGAGTGCGGCACTGGGCCCGCTCCCTGCGGGGGCCTCACTGTCAGGACCCCACACCC +TCCACCCCCAGCCTGGCACCCACCCCCTGGCTCGGTGCTGTGGAGGTGGGGGGTCAAGGA +TGGGTCTGCCCTGTCCTGACCAGGACACCTTCTGAGACCCTGCTCAGCTGGCCCGGCCCC +TGCCCCCGTGTTACCTGAGAATCTCCAGCTGGATGTCCTCCATCTGGTCCAGCACGCCCC +GGATGTCCTTCTTGAGGTTCTGGGGGCCAGAGGAGGTAAGCACAGCAGGCCCCTCGCCCC +GCCCTCCGTGGCCTCTCGCCCGCCGGGCCCCGTCCTTCTGGGTGCTGCCCTGTGGGGACC +TACCAGGAGCCCGGTGGCCTGGTTGTTCAGGGCCATGTGCATCTCAGCCACGTTGTCCCA +CACCTAGGGGGAGGTGGGGTCACGCCTGAGGAGCAGGACCCACTGGGTGGGCCCCCAGCA +CCCCTCCCCCTCAGCCAGGCGGGCACCTCTGTGATGACCATCTTCTTCCTCTCAAAGCAC +AGGCGGATCTGCTGCAGCTCGTTCTGAGGGTGGGGCCCAGGATGGGCTTGGGCAGCATCA +GCAGGGTGGCCAGTACCTCCCCGCTGGGCCCACTGGCCTACTGCACGAAGACCTCCCTCC +CTAATGAATCCCTCAGGCCCACCTGGAGTGCTGTTACGAAGCTTCCTCCCCCCCCACAGC +CCCTCCCCCAGGCCCACCTGGGACTGTTGCACGAAAGCCTCTTGCCCCTGGCACAGCTCC +CGCCGCAGCAGCTGCAGAGGTGCCCTGTTCCCCAAGGGCTGCGTGCCAGCCGGGTCGGGG +GGCTGTGGGAGAGCCCCCAGATCAGCCCTAAGACTGCGGGCTAGAGGGGCGTTGGCTGCA +TGGGGTCCCTGGGCCCTGTATTTACCCAGGCCAGAGCAGTGCAGCTTGAGTGTTCGGGAC +ACAGGGGCAGGAACTGCTGCCCCGGCCCCAGGAGGGCCCCCAGCTGCTCCCGAAGTTCCT +GATTCTGCCTTTTCTGGGGTGGGGGGCAGAGAGAGGGGGCTGCCTGTCATGGCCGCTCCT +GCGGCTGGGGCTGGGGCAGGGGCAGGGGCGCCAGGTGGTGGGTGGGGCTGGGGCTGGGGC +AGGGGCAGGGGCAGGGGCGCCAGGTGGTGGGTGGGGCTGGGGCTGGGGCAGGGGTACCAG +GCGGTGGGTGGGGCTGGGGCTGGGGCTGGGGCGGTGGGTGGGGTGCTCACCAGGCTGTGG +TTCTCCTGCTCCAGCTGCAGGAAGGACTGTTCTGCAGAGCCCAGCAGCCCGCACTGAAGC +TGGGACAGGGCTACCCTGGGCGAGGCCAGGGCCCCTCCCTCCCGTGACAGGGGTGGGCAT +GGGCAGGGTCTGGTCCCTGAGCCAATGGATCCCCCCTGCCTGGGAGCCCCCTGGTTCGAC +CCTGGGTGCAGGGGCCAGCCCCACCCAAGCCCTGCCTCCAGGTCTCCTTGTCTCGGCCCC +TCAGTGTCTCTCGCTCTCTGCTCCTGGCTGGACAGAAAGAGCCCGGGAGCCTCGCCCTCC +ACTGTGGGCCCACTGCCCCCTGCCCCTGGGACTGGGAAAGGTCTCTGGGACTGCACTGAG +TGAGCAGAGGAGATGGGGCCCAGGCAGGGCCACCCTACAAATCCCTGGCAGGGCTGGTCC +AGGCCTCCTCCATGGCTGCTGGAGGCTGGGGTTGGGGGACACTGGGGGTGGGGGTGGCCG +CAGGGGCCCAGGGTTTTCAGCCCCTCCATCCCTCCCTGCAACCCCTTCCTGATCCCAGGT +CCAGGCTCTGGCCTGGCCCAACCTGCCACCCTCTTACTGAGGGGGCTGCCCCAGGCAACA +GTCACAAAGGCCTGGGTGCAGCCAGGGCGGTCACAATGGGCCCCTCCCACCTGGTCCTGA +AGCTGCCCCGCCTGATGACCTCACTGCCTCTGACCCACTGACCCACCATGCGAGTTTTCT +TTCTTTCTTTCTTTTATGGGAAGGGGACTTGCTCTGTCACCCAGGCTGGAGTGCAGTGGC +ACAAGGTGTCTCATTGCAGCCTCCAACTCCTGGGCTCAGGCAATCCTCCCACCTCAGCCT +CCCAAGTAGCTAGGACTACAGATGTGTGCAACCATGCCCGGCTAATTTTTAAGTTTTTTG +TAGAGATAAGGGTCTCGCTATGTTGCCCAGGCTGGTCACAAACTCCTGGCCTCAAGCGAT +CCTCTTACCTCAATATCTGAAAGTGTTGGGATTACGGATGTGAGCCACTGCACCCAGCCT +AGTTATAAAACAGATAATACACACACTCACAGTGTGGATTCAAAAAGTATCAAACAATAA +AAATGGTGTCCAAGCTTTTCCCACCTTTATCTCCTGTCCCTGCAGACAGGAGCTTCCTCT +TTAAGCTCCTAGAGGTGGGCTGCCGTCCCCTGCCCCTGGTTCACACAGAAGAGGTCATCC +TGTAGCCCAGCTTTGCTTTTCACCTAATATATCTCTGAGGTTTTAAAACATTCTTTTCTA +GCTATGTATTGAATATTTACATTATGCCAGATCCAGTACATGCCATTGTTATCCTCTGTT +TTTTTTTTTTTTTTTGAGACGGAGTCTTGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCGC +AATCTCGGCTCACTGCAAGCTCCGCCTCCCAGGTTCACGCCATTCTCCTGCCTCAGCCTC +CCGAGTAGCTGGGACTACAGGCGCCTGTCACCGCGCCCGGCTAATTTTTTTGTATTTTTA +GTAGAGACGGGGTTTCACCGTGTTAGCCAGGATGGTCTCGATCTCCTGACCTCATGATCC +ACCCATCTCCACCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGCGCCTGGCCTGT +TATCCTCTGTTTATGGGTGGGAAAGCTGAGGCAGGAAGCCCTTTAGTCACTTGCCGAAGG +CCACGCTGTTAACGGTCGGACCAGATTTGGGTGGCGGAAGAGAACTCATCCGACAGTAGG +GCCAGATTCACGCCCCAGGCCCGTTCCCTCCTGCTCCCTGGTGCTCCTCACACCATCGGC +CCTGCTGCCCCTCACTGCCCCTGAGTCCCTGTGCCCGTGTCCTCCTTCTTGAACCCATCA +GCCGTCAGTTAACCCTCAGAAAGCTGGCTCGGAGAAGTCCTCATATGGTAGGAAGAGCCC +CGTTCCCTCCTCTCCCGGTGTCCTGGCCCCCCTGCAAGGTGACTTCACCTCCTACATCAA +GAGGCGGGTACTGGTCTCCACCTCTGGGCTCTGGGCCGGCCTCGGATGCACTTGGCCAAT +GGGCTGCTCCTAAGCTGCTGTGGGCAGAGGTTGGCACGACACTTGTGCGCTGGGCCTGGA +CCTCTCTTGCTTGGCTCTGGGGACTGTCCTCCCTGCAGGAGGCCTGGGCTGGGCTGCAGG +ATGAGAGGCCATGGGTCAGGAGAGGCTTCTGTCGTCCCAGCCGGTCCCCAGCTGCCTAAA +GATGGGTGGACAAGCCCAGCGAGGCCCCCAGAGAACCGGCCCATACGTTAGCCAAGTTGC +CGGCCATGTACCATCGAGCCCCGGGCTGTCATGGTGGTTTTGCCACTGAGTTTTGGAGTG +TGCTGTGACGTGGGAGGAGACATTGAGAGGCCTCACAAGCCTAGAAGCGTCTTACCCTGA +CCTCACACCTGCTGGACTTCGGGCTGGGAAGAGAACTGGGGCCGAGGGCGTTTTCCCACA +GGACTGGAAGGCCGGTCGTGGTCCTTGGTGGTGAGAGCTGGCCAGGCTGCCAGCCTTCTC +CCCGGAAGCCTGCAGGGTCCCCTCTGATCCCTGCGCCTCTGGGGGTCACACCAACTGTGG +GTCTTTCCTTCCTCACCACGCTGGGCACTTGGTGAGCACATTCTGCCTTGAGACGGGGCA +TTTCTTTGATAACATTTCTTCTCATTTCCTGCTTGTTCTGGAACTCCTGTCAGTCAAATG +TTGGGCCTTTTGAATTGATCCTGTGAGTCCTTCTTTCTACCTTTGCTTGTAGATAGACTT +CCCTGAACCCAAACACAAACACTTTCTCTCTGCTTTTTAAAAAATTGGTTTTGGGGCCGG +ACGTAGTGGCTCACGCCTGTAGTCGCAGCACTTTGGGAGGCCAAGGCAGGCAGATCACTT +GAGGTCAGGAGTTCTAGACCAGCCTAGCCAACATGGTGAAACCCCGTCTCTACTAAAAGT +ACAAAAATTTGCTGGACGTGGTGGTGTGCGGATGTAATCCCAGCTACTCGGGAGGCTGAG +GCAGGAGACTGGCTTGAACCTGGAAGGCGGAGGTTGCAGTGAGCCGAGATCAAGCCACTG +CCCTCCAGCCTGGGTGACAGAGCCAGACTCTGTTTTAAAATAAATAAATAAATAAAAATA +AAAAATTGGTTTTGGATTTTAGCAGTCCTGTTTTTCATTTCCAAGACATTTCCATTGTTC +CCTGAGCTCCCCTCTTCTTGTTCCAGAGAATTCTGTTCTGCTCTTAGGGATAAAGTGGCT +TTGGGGGGAGGCGAATCTTTTGCTTTCTGCATTTTCTCTCTTGCGGTTCTTTTTTGTTTG +TTTAGTCTTGGAGCTTCACATGAGACTCAGTGCTCAAATGTCTGGCTTTTCTTTCTTTTC +AATCCCTGTTTATAGGGGAGACAGGCAGAGCTGCCGGGCACTCCTCTTTCCTTGTTAACT +TGAGGAAGCCGGACAGCCAGGTCTTGGAAGGGAGGCCTCCTGCCTCCAGGCGGCATCTCG +GGCTGCAGGGCTGTGGTCTGGAGTGCGGACAGTACCAGCTCCCACTGCTGTCCTGCCATG +CTTGTTCGCAGTACTCGTCTCCTCACACCAGTGACGAGGCCACTGCTTGCCAGCCGCTTG +CCTTCTTCCCGCCAGGCTGTCCTGCTACGTCAGCCTCCGCTCTCCACCTCAAGAAGTGTC +TCGAAATATCTTCTCTGCAGATGACCTCTCTCCTGTTCTCAGTGCCACGTGGGGCCTCCC +CAGCAGAGGCGGCTGGACACCTGGCCCTGGCTGCTGGAGGTTGTTTAGCTGCCAGAGGGT +GGCGGTAGCCTCCAGGACCCTCCCCTGGCCTCTGCCCTGTTCATCCTTTGCCGGAATGTC +ATGGGTTTCAGGATGTGCTGAGCTCCGAAACCCCATGGGGCAACTTGGGATGGGGGCTAA +GGAAGGCCTCTTGGAGGAGCCCTGAGGCGAGGTGGCCCTGGGGTGGGGTGGAGGAGGCCC +TGAGCAGCAGGGGAGGGGGTTGCACCCTGCTCTCTGTGTCCCTGAGTGAATGGGGCAGGG +GCTGCACCCTGCTCTCTGCGTCTCTGAGTGAGTGGGGCGGGGGCTGCACCCTGCTCTGTG +TGTCCCTGAGTGAGTGGGGCAGGGGCTGCCCCCTGCTCTCTGCATCTCTGAGTGGGATGG +GGGCTGCCCCCTGCTCTCTGCGTCCCTGAGTGAGTGGGGCGGGGGCTGCCCCCTGCTCTC +TGTGTCCCTGAGTGGGGTGGGGGCTGCCCTCTGCTCTCTGTGTCCTTGAGTGAGTGGGGT +GGGAGCTGCACCCTGCTCTCTGTGTCCCTGAATGAGTGGGGTGGGGGCTGCACCTGCTCT +GTGTGTCCCCAGCCTGCTAAGTGCCCCACAGGGGCCAGGATGCTGAGGAGTGAGAGGTCT +TCACAGAGACAGGTGGCTCCTGTAATAAGGAAGACAACACTGGCTTCCTGGGCGAACAGC +AGGGCGGGGTCCTTAGGTCCCACTGTAGGTGCCCAGGCCCGGATGAGATTCCCCAGTGGC +CCTGAGGGGGCGCCCGGGACACCCTGGATGGCCCAGTGTCCTCCCGTCACCCTCGCCCCT +GGGCACCATCCTCCTTGGCCTGGAAACCCCAAGCTCCCTGACGCCCCCGCCCCTCTCCCC +GGGCCTGTGCCGGGGAAGGATACTGCTGCTCCGTCAGTCAGCCATAGAGCCCCTCCTCCC +CCAGCCCCTCTCACCCCTCCCTGTGGTCCTTGCCAATCGCCCTGAGCCCGAAAAGGTGGG +AGATTCTTGGAGAGATGGGGCCCTGGATCCCCGGCCCTGGATCCCCATCCCTGGGGTCCC +CCACTCACGGGGTCAGATACGCTAACAAAGGCCAAGCGCCCTGCCAAGCGGTGTCCTGGA +TTGGGGTGGGCGTGGGGGTTCGCCTCAGGTCCAGGCTCCGGGATGTCGTGCAGGACAGGG +CGCGGTTGCGGCGGGGGCACTGGCTGGAAGCCGGAACTCCCGGCCTCGAGGGCGGAAAGT +GTGGCCAGCGCAGCGTGCTGGGGGGGCCATGGCCCCGTTGCCAGGCAGCGCCTCCCTGGA +CGCCAGTTGCCATGGAAGCCGCTTCCTGCCCATGTTGCCAGGGCGTCCAGATGGCCTCGA +GGAGCCTGGTTCAGAGGGGCCGCCCTATGCCCTTGCCCCTCCTCCGCTGCCCAGGGATGG +GCTGGGAGGACAAAGAGGAGGAGAGGCTGGGACTCCCAGCATGGAGATCCGAGTCCTTCC +TGCTGGAGCCAGGCTGCGGCCCAGGGCAGGGGCCAGATGGGGCTGTTCTGCTGTCTGCAC +CGCGGACTTGATGTTCATACCCCAAGCTCATTTTATTTATTTTCTATTTTTATTAAGAAA +GAGTCTCACTCTGTTGCCCAGGCTGGAGTGCAGTGGCGCGATCACAGCTCACTGAAGCCT +CCAGTTGGGCTCAAGGGATCCTCCCACCTCAGCCTCCCGTGTATTGGGGACCACAGGTAT +GTGCCACCATGCCCAGATAATTCTTTATTGTTTTATTTTTGTAGAGACTGGGTCTCGCTA +TGTTGCCCAGGCTGGTCTTGAACTCCTGGCTCAAGTGATCTGCCCGCCTCAGCCTCTCAA +AATGCTAGGATTACAGGTGTGAGACACCTCGCCTGTGCTTGGCTGCTCCCGAGCATATCT +CAGAAGCCAGGAAACAGGCCCTGAATGGATGGAGCTCGGGGTCACTGGGCCAGCCACAGC +CCTCAGAGGACCCCATCTCTGTGCCCTCTAACCTGGGCTCCTGGCCCACACCCACCCAGG +CTGCCTGTCAGGATCTGCTCCCTCTCCAGCCCTCAGAGCTGCCCTATGTGGAGGGTTGGG +GGTCCCAGAAAACCTGGGAGAAACGGGTCCTGGAAACAGGGTCGGGGGGAAGGGCAGAGT +GCTGGGGATGCTGGGCCCACGACCTCCCTGTCCCTGGGGCTTCCCCATGTCAGAGGTGAG +GCTCAGAGAGGTAAGGGCGCACCCTTTGTCTGCCCCCTCCCCAGCATGGCCAAGTCGCTC +CCAGGGTGCAGGCGATGGCAGGCCATTTGTCTCCCTCCTGGGTGAGTCTCTGGACATGGA +TTCTCACATTTTTTATTTAAGAATCAGAGAGATATAAGAATGTCAAGGAAAAATCCTCTC +ATGGACAATGCAGCCCCAGTAAATGACTGTCAGCCGGCGTGTCCAGGGCTTCAAGGCCCC +AGGAAGTGGCCATGCTGGGGCTGCCAGGCCTCTGGCTCCAGGGTCACTGGGGCTGAACTG +TCTGCCCAGGCCCGGAGACACCCTGCCCCTGAGGAGCCCACCGGCTTGGCCAGTCCATCT +TCTTGGCACTCCCTGACCACCACTTACCTTCTAGTCGGACAGTGGAGCCTGGGGGGACAG +CGTGGCAGAGTGCCTGATGGTCGGTGACAAAGTCATCTCCAAAGTCCTTGCTGGGGCCAA +GAGCCAGGACTCCTTGCCCGTCCCCGTCACTGCCCTGTGCCCGCCCAGCACCTGCTGGGG +ACTAGGCTGCCCATTGGAGAAGGAAACACAGTGCTGGGCTGTGAGCTCCTGAAGCCTGTC +TCTGTGCCCCAGGACCAGGCTCCTGGGTGGAGGGAGAGACCAGGGGCAGGTGAGGAAAGG +CAGGGCCCCCAGAATCCCTCCATGCCTGCCCCTCAGTCTCCAGGACTTATGTGCAGGTAC +CGTTTGGAGCTGTGGTGCAGTTCCCAGTCTCACCACCAGATGGCACCATGCCCCTGCAGA +AGCAGTGCCCAGAGCAGGCCAGGTGGTTCTCGGGGGCTGCGGTGGAGGAATCCACCCAGC +CGAAGCTCTGGCAGGGAAGGGGCAGTGCTAGGGGGAGCCCCCTCCCCACTTGGATCCGAA +GTTCCCATGGGGCCTAGGGCAGGGGCTTGCCAGGTAGCCAGAAGTTCCCTTGCTGAGTCT +AGGGTGTCTATCCCACATTTCACATGGAGACGAATCATCCCAGACACCCCGGCACTGTCC +CGGGGCCGTTTGCCACCCCTCCCAAGGGGCAGGGCTCCTGTCTTGGGGCCTTCCCAAGCA +TAGTAGCCTTCGGGCAGCCCCGGCCTGGCCCCAGGTTGTCCCACTTGTCAGTGGGCAGCT +GGGGCTGGGGGAGGGGTCCCAGCTCCTGTCCAAGGTCACCATTGCCCCTGACCAGGGTGT +GGCAGCTGCTGTGGCCTGGGTCAGTGAGGCCGTGGACGGAGGGTGGCCTGGGTGTAGGCA +CTGCTCTCAGCTAAGAGAGAGCCCATCTGGAGGAAGAACCAGGAACCAGAGGGATGGCCG +GGTTCCCAGCGTGCAGGAGGCCAGCTTAAGTTCAGTAGGGTCCCCCTGCAGGGACTCCAA +GAGGCAAACCACATGGAGAGTCACCTGAGAGGGAATGATGGAGGCTGGGGAGGTGGAGCC +CCCACCTCCAACTGCTGCCTCGGCCCCCACAGCAGGGGAGGGCGGGAGGCTGGCACTGGC +ACTGCCCTGGGAGATGCCACCTGGGCCTTGGTCTGGGGAGGAGGGCTGGCCAGGAGGCTG +GGTACGGCTACTGCTCTGGAGTGACCGAACCATTTCCACCCTGCTTGCCTTATTCTTCTC +ATGAGGGCCTCAAGGGGACACACCAGAGGTTTACTGGGGACATGGCAGGGGAGGGATCTC +AGTGCTGGCCTTCTGGGGCCCTGCGTCCACTCCGCCCCTTTCTGACCTGGGCTGGGGCCT +CTGCCCTCCCCGGGGCCTGGAGACAGAGCCCTTTTGGAGGCCCTCAGGCTTGACAAGCCT +ACTTCTTAGAGCCAGGCTGTGGGCTGGGCTGTATCCTGGTGGGATGAGGGATCTGGGGCT +TGGGTGGGAGTGGGGCTGGGAGCAGGTGGAAGTTGGTGCCTCAGGCTCTGAGGAATGGGC +CTGGGATGGCTGCAAAGTGGAGGAGAGGCTCTCTCAACCCTGGGCTTTGGGGTCTGAGCC +CAGCCCTGTCCTCAGGCAGTCTGCCCCTGCAGCCCCGCATTGCCATGTTGGTTGGAGTTG +CGATGAGAGGTGCTGGGGCCTCCCTTGCCTCTGCCCAGCACAGCTGAGAAGTTACGTGCT +GCTGCCCAACTGTGGGGGTTTCAAACCCCGCTGGAGCCTCCAGGTGGGCCCTTGGGCAGC +AGGGCCTTGTGGCGGGAGGAGGGGACCCTGGGAAGTCAGGGACCAGGCGGGGGAGGGAGA +GAAGGTGGGAGCACAGTTGTGGGTGTGGGTACCCGCCCCTTCCTGAACTGTGTTCCTCCC +GGCCCACCTGACTCTAGTCCTCTGTGCCGGCTGCCAGGGGATACCCGAGGCCACCTGCGT +CCCCAAAAGAAGGTCTCACCTTCAGAGCCAGCCTTTGAGGCTCCTGGGTGACCTCAGCCT +GTTACCCTTGACCCTGAGTTCACCTAGATCAAGTGGGAGGCCGCTCTTTGGGCCTCAGTT +CTCCCATCCTCAGGGAGTAGGTCCTCTGTCCCCTGACAGCACCCCTCCTCGCTGTGCCAC +CACCACTGCCAGGGTTCTGATCTGTGGATGTTCCCCAGGGGGTGGCTCTGGGCTCTCAGG +CAACCGGCTACTGTGGATGGTGGTTTGCACGAGAATAGTGTCACTCTTGGGTCCTTTGCT +TGAAGTTGGCTCTGCTGAGTGCAGCCTGCAGACATTTTCAGGAAACTGAATCCACAGGCT +GGAGCCTTCTGCTTCCCCACAACCCAAACGGCCCCCAGCCAGCCAAACAGCCACGAGAAC +CCAGCTGCTAGCAACTGCCAGCAGGAAACCCACTACCAGCCGCTCACAGATGGACAGCCC +ATCCCAGGAGCTGGCCCCACCTCCCCGCCCCTCTGCTGACCAACCCAGCAGCTCCTTGGG +TGGGTGTGGCCACCCTGCTGCCCCAACCTGCTCCCGGACCCTGTGCCAGGAGGTGCTTCG +CCTCAGCGGGGCCTTGCCTCCCCCAGAGCCGCTCTGCTGCCTGACCTTGCAATGTCATGG +GTCCTCTGGGCACTGGCGCAGTTGGGTGGGATCAGCTTTGGCCAGCAGGTGGGGGGCAGG +TGGGTAAATCCTCCCTCTCTGCCATCTCCGCTTCCTTCCTCCTGCCCGGCTTCCCTGCCT +TTTTCCTACTCTGGCTCCAGGGTTGCACTGCTCAGAAAGCTGTTGCTGCCTGGCCAGCAC +GCAGGCCTGATTTTCCTGGGAGCCTGGACTAAGACCCTGACCAGTCCTCCCACCCACCAC +CCACACCACCACCCAGCTAGCCAGCAGCTAGGCCAGGAGTGATCAGGAGGGGGCCCAACC +GACCACCCACCCGGCGTCTCCAGCCGGCCAACTCTGCCCACTCAGGGCCGTGAGCTGGAG +GTGCCAGGAGCCTCCCGGGAGGCAGTGTGAGGCATTCTTCTTAGTAAGTCCCGCATCGAT +GATAAAGGGCAGTATCAGCCCCTCTCTGATGCGCAGTGAGCGGCTCACCATACAGGGGAG +GCGTTTAATTTATCTCGGGAACTGGGCGCAAGTTATAAAAATGGTAATTTCTTGGAGATT +CAATTACATGTTTTCATTGTTACCCTCGATAATCAAGGAAACGATTTTTTATAAAAGGCT +GTGGGATGATACTGATCTCAGGAGAGGATCTGGGCCGGGTGGGGGCTTTGGGGACGAAGA +GGAGGGCAGTGTCTGCTGGGGGCAGGCAGGGCAAGTGGAGCTGGGCCGGCCGGCCCACCA +GCTCCTGCAGCCCACCAGTTCCTCCAGCTCCTCCAGCCCTCCAGTTCCTCTAGCTCTCCA +GCTCCTCCAGCCCACCAGTTCCTCCAGCCCTCCAGCTCCTCCGGCCCTCCAGCTCCTCCA +GCCCACCAGCTCCTCTAGCCCTTCAGCTTCTCTGGCCCACCAGTTCCTCCAGCCCTCCAG +CTCCTTCAGCCCTCTCTGGCCTCAGTCTTCCCATCTGCCGACGGGCCCATCTCTGGTAGG +GAGGGTCTGCGTTTTGGCATGAGGGCTGATGAAGTGAGGCGTGACTCCTGGGCCGTGAGG +GTGGCTGCGTCCCTGCCCCTCCCTTCCTGGTGCCCGAGCAGTCTCGTCCATCTCCTGAGG +GCTCTGCAGGGAATAGAGAGGGGTTCCTGGTGGAGTGTGGACCTGATTTTTTCCCCAAGT +GATGTCTTGGCTCTAAATAACATCTCCAGGATTAATGATGCCGGCCCCCAACAGCACCAG +GTGATTGGAAAAAGGGTTTTATGGCCCCGTGGGTGAAATTGAACTTGCATCTGAGGTGTA +TTTCCAAGATGGGATTTTCCTCCCTGGCAGAGGCGGCACATTTCACGCTAATGATAATGG +CAGCTCCTCGACATTCATCACCTATAGTTGGGGGGACACCCGTCTGGGGCACAGGGGCAG +GGTGTCCCTGGGGTAACCTCCAGGTCTCCTAATCTCAGCAGACTCTGGGGGGCTGGTTCT +AGGAGATGCGCCCTCACCCAGTGCAGGGCCAGGGAAGGGGGAGGCAGGAGCCCCCAGGGG +ATGAACGAGCTCTAGCTGGGCTGCACCAGGGAGGAGGCTGGAAGGAGGCCCCAGGCTGAG +GGTAGGACCCGGCTAGTGCTTGCCCAGGGACCCACAGGCCCCTTGCTGAGCAGACTCCAG +CGAGGGGCCTGGCCCATCTTGTTGCAAAGGGCTAGAGTCCTGGGCTGAGCTGGGCAGTTG +ACCTTGGATCTGACTCTGTCTCCCCTGAAAGCTGTTCCACCCCAATGCAGGCTCCTGCAG +CCTAGCACAGCGCCCAGCCAGGATGGGCAGGAGGAAGCCCTTCTTCCGACGGGCTGTCAC +CGCGCCCTGCCTGAGGGGCCTCAAGCCCCAGGGCTCTTGTCTCAGAACTGGGCCGTGGAG +ATTCAGGAACTATGGGAGTTTGGGGGATCTTGGTGGCTGAGGGCTGTGCTCATGGAGGAC +TCCTTGAGTTCAGAAGATGAGGCCCACCTTCTGCATAGCCAATAGGTCATTGTCACAGGG +ACACTGACCACCAGCACCAACCTCCATCCCCCGGCACCTGCCTTTATCACCCATTTCCCA +GGTGAGGACAGGGGCTCAAAGAGGGGCAGGGTTCCTCTGAGGTAACACAGCAGGTGAGCA +ACAGAGCCAGTGAGGGCCTGGGGGTGTCCTGCCACGGGCTGAGGTGTGCCCACATGCAGG +AATCCAGGGGTCCGTGGGCCAGGACACTGCCAAGAGTTGGGGGCTGGGGGAGGGAAGGGG +GCATTGCCAATGCTGCAGCCCCTGCCCTGGGGGGTAGGAGGGAGATGCCCCTCCGGGGGC +CCAAGGGCAGGGTGGGCCCATGCTGTTCCCTCCCACCTGCCACGGGTGAACCTGACAGGA +GTGGGGATGGAGCCTGGCATCCCGAGGGAACCTCCTGGAGTAATCACTCCACATGCTCGC +GGTAAATACTGGGCCCTTCTTCCCCTCCCAGTAATTGAACTTATTTACTTTTAACTAAGA +TTAAATGTTCTCTGCGAGCTCAAGATACTGACTGCCCTGTCAGGCTCAGTCCACGCTCTG +CTCTTCCTGCCTCTGGGGACCAACCCCAGGCAGGGAGGGACCAGGCAGCCCTGGAGAAGC +ACAGAAATTGTTTTTCCAGGAAACTCTGGGTGGATAATCCACTTACATCATCACCACTGT +CACCATGAGCATGGCCATAACCACCATCATGGTCAGCTCCACCAGCATCACCACCACCAC +CACCACCATCACCATCACTGCCACCACCACCGCCACCATGACTACCACCACCATCACCAC +CACCACCACCATCACTACCACCACCACCATCACTACCACCACCACCACCACGATCACTAC +CACCACCACCACCATCACCATCACTACCACCACCACCACCATCACCATCACCACCACCAT +CACTACCACCACCACCACCACCACCATCACCATCACTACCACCACCATCACTACCACCAC +CACCACCACCACCACCATCACTACAACCACTACCACCACCACCACCATCACTACGACCAC +CACCATAACCATCACTACCACCATCACCACCACCACCATCACCATCACCACCACCATCAC +CATCACTACCACCACCACCACCACCACCATCACTACCACCACCACCATCACTACCACCAT +CACCATCACTACCACCACCACCACCACCACCATCACTACCACCACCACCACCACCATCAT +CACCACCACCACCACCACCACCACCATCACTACCACCACCACCACCATCACTACCACTAC +CACCACCATCACTGCCACCACCACCACCACCACCATCACTACCACCACCACCACCATCAC +TGCCACCACCACCACCACCACCATCACTACCACCACCACCATCACCACCACCACCACCAT +CACTACCACCACCACCACCACCATCACTACCACCACCACCACCACCATCACTACCACCAC +CACCATCACCACCACCACCACCATCACTACCACCACCACCACCACCACCATCACTACCAC +CACCACCACCACCATCACTACCACCACCACCACCATCACTACCACCACCACCACCACCAC +CATCACTACCACCACCACCACCATCACCATCACTACCACCATCACCACCACCACCACCAT +CACCACCACCACCATCACCATCACTACCACCACCACCATCACCACCACCACCACCATCAC +TACCACCACCACCACCACCACCACCATCACTACCACCACCACCACCACCATCACTACCAC +CACCACCACCATCACTACCACCACCACCACCACCATCACTACCACCACCACCACCATCAC +CATCACTACCACCATCACCACCACCACCACCATCACCACCACCACCATCACCATCACTAC +CACCACCACCACCACCATCACTACCACCATCACCACCATCACCACCACCATCACTACAAC +CACCATCACTACCACCATCACCACTACCACCATCACTACCACCACCACCACCACCATCAC +CATCACTTCCACCACCACCACCACCACCATCACTACCACCACCACCACCACCATCACCAT +CACTTCCACCACCACCACCACCACCATCACTACCACCACCACCACCACCATCACCATCAC +TTCCACCACCACCACCACCACCATCACTACCACCACTACCACCAGGACCACCATCACTAC +CACCACCACCACCACCATCACTACCACCATCACCACCACCACCACCACCATCACTACCAC +CACCACCACCACCATCACTACCACCACCACCATCACCATCACCACCACCACCACCACCAC +CATCACTACCACCACCACCACCATCACCATCACCACCACCACCACCATCACTACCACCAC +CACCACCACCATCACTACCACCACCACCATCACCATCACTTCCACCACCACCACTGCCAT +CACTACCACCACCACCACCATCACCATCACTACCACCACCCCACCACTACCACCATCACC +ACCACCACCACCATCACTACCACCACCACCACCACCATCACTACCACCACCACCATCACC +ATCACTTCCACCACCACCACTGCCATCACTACCACCACCACCACCATCACCATCACTACC +ACCACCACCACCACCATCACCATCACTACCACCACCACCACCACCACCATCACTACCACC +ACCACCACCATCACTACCACCACCACCATCACTACCACCATCACCACCATCACTATCCCC +ACCATCACTACCACTGCCACCACCACCACCATCACTACCACCACCACCACCATCACTACC +ACCACTACCACCACCACCACCATCACCACCACCACCACCATCACTACCACCACCACCACC +AGCACCACCACCATCACTACCACCATCACCACCACAACCACCATCACCACCACCATCATC +AGAACCACCACCATCACCATCACTACCACCACCACCACCATCACCACCACCACCATCACC +ATCACTATCACCACCACCATCACCATCGTTACCATCACCATCACCATCACCACCACCACC +ACCATCACCATCACTATCACCACCACCATCACCATCGTTACCATCACCATCACCATCACC +ATCACCATCACCATCACCACACCTCCATCACTATGGTCGCTGTGACTGAGCCCATCCTCA +CTACTGTCATCAGCACTGTCACAGCACCATGCTGACAAGCCCACAGTGGGTTTGAGGGCT +GCCATTGCTTGGGACTAGTTCCTCAGGCACAGGAGGCTCCACGCTGGTCTGATTGCATTG +GAGGGGATGCCTGACAAAGGTCTTTATGGGGTGTGCATTGTGGAGTGGGGAGGGGGAGGC +TCAGGGAGGTCTCGAGGACTTCATGCCGTGGGCATTCTCCCCGGCCCCCTTCTGTCTCAG +CAGCTCCCCACGCTTCTTGACTGAGCTGGAGCAGAGGAAGCAGGCAGGGGTGGGAGGAGG +GGCAGGGGCAGGAGAAGGGGCAGGGGCAGCCACAACCACCTCCACTTAGGTTGGAGCACA +GCCTCCTGGCCTCCCTAAAGTGAAGGGCCACCCAGAGGAGGCACCTAACCATTCTCCCCT +CCGGACTCCACCCAGTGCTTGGATAGCCAGCGGGGCAGCTTGGGGTCGGGGCTGGGCACT +CAGCCAAAGGGGCTGGAGAGCATGCCGTGTGCAGAGCCTGCTCCCATGAGGTGGTGAGAG +CCTGCTGCACTGGTCTCCTGCCCCGAGCCTTGGCTTGCTCATCTATGAACGGGTGACGTG +GTGCCTGCTGCACAGCAGGCCACAAGAGCAGAGCGACAGGACACAGTGAGGGGCGGTAAG +GTGCTGCCTGGTAAGAGAGCTGTGGGCTGGCCTCAAGGGGTAGCCTGTGTCCTCTTGCTG +AGAATAGTGGGAAGCGAGCTGCGAGCTTGGGCCCACAGTGGTGGTCTTAGGCTGCCGTGG +TCACATAACGCCACCTCCCAGTGCCTGCGGCACCACCCCTGGGCTCCGCAGCCCCAGCCA +GCCGTCCATGTGGCCCATCCTGTCCTCTCCAGGCCTGTCTGTGTGCACCCAGTGGAGGGT +CTCCTGTCTCCTGTGGCTCCCTGAGGCTGCTGGTCACAGAGCTGATGAGGACACTAGAGA +CCGCTGCGGGGCTGGGCGGGGGCCCTGTGGGAGCGCAGCAGCCTGGGATCTGCAGCTGGG +GCTGACCTAGCACAGCAGGCCACTGATGCCACCTCTCAAGTGGCAGGGGCTTCACAGCCT +CCCACTGCAATCCCGGCAGGCCTCGGTGCCAGGGCGGCCCCATCCTGGGGGCCACTGAGG +ACCTGCATCGGCCACAGGGCTCGTGAGCATGGGCACCCCAGGGCTCAGTGGGGGCAGCTA +GAGGGAGGGTTCAGTCACCTAGGCCTGCCCAGAGCCCTGCTCAGGGCCCAGGATGAACTG +ATGGGGGCAACCTGCAGGCGGTGCCAGCGAGAGTGGGCGCTCCCCACAACAGGGGAGCCA +CAGCCAGCCTCACCGAGAGCAGGGAGGGAATGTGTGGAGATGCAGGAAACCTCTGCCACG +TCCAGGAAATATTATTAACAATTAAAAATTTTAAATCTTGGTAACATTCCCGATGGCCAG +ATAATTAATATAAGAGCAGATAATAATTACTCAATGATTAATAACTGCACTGAATAGTTT +TCAAAGTAATTGTGATAAAGAGAATGTTAAATGAAAACCCATCAAAGTTGCTGATGCCCT +GCACAGCGAGGGCACCTTAGTGCTGGGGGTGGCCATGTCGACTGGGCTGAGACTGGCCCC +CCGGGCCCACTGTGTCCTGGTGGCACGTATGGAGTGTGAGGACCACCTCCCCAACACACA +CGGGGTGAGGACCCTGCACGCACATGCAAAGGCAGGGGTCTCTCTTAGTATTGGGGCAGG +TGGGCAGAACCTGTCTCTCTTCCTGCCTCACTGGGATTGTGGATGACCATGGGGTTGGCT +CAGGAGTCTGCCCTGTGCCTGCAGATGTTCTGGATATCTGGGCTAGTGTTGGGGGGTATT +ATCTGACCCATGGACCAGTCTCTGGTTCTTCTATTGCCCCAGCCACTCCAGGCCTTTGGT +GAACCCCCTCTACCATTCAACTTGACCTGCCATGTTCCTGAGATCTAGCCCAGGGCTACT +CCATCCACCAATTCTCACTAAAGTGTGAGTGGTTGCTTGGCACTACCCTAATCTTTGCCG +CCTCATGTGTTTATTGGTGTGAAGCCTTCAGCTGCAGGGGGATGAAGAAGGTGATTCCAG +GCAGAGCAGGCCTGCTCCCTCCACCCTTAGGCTACTGACTCTGCAGTCCTGGACAGTGGC +TGGGAGCTACCAGGAGCCCAGGTTGGGGCAGGACCTGGGGACCTACTGCCCCTCACATAA +GCCAGTTTCTCCAATCCTGGTTCCTTGCCCTGTCTGCCATGCCTCCCAGCTGACACCACC +GTGCGGCTCCCTCACCTCATCCTCTGAACAGGACCATCCTGAGTTGTCACAGCTTCCAGA +CCCCCCGAAGCCACCTGGTCCCCTATCAGGCTGAGGCTGTCCAGACATGGCCTGCCACGA +GGCCCTGAGTGGATATGCTGGCCTGGACACCAAGGATGAGGGACCCTGGCACTTCGCATC +TCAGGGATGCCGGGTGCTCACCCGCAAAGACCCAGAGGAGAGAAGGGGAGAAAAAGTCTG +AAGGGCTCGTGACCACCCTGGGGTCCTGATGGGGCCAGGCACGGTGGCCATACTTGTAAC +CCTAGCAGTTTGGGAGGCTGAGATGGGAGGACTGCTGAAAGCCTGCCTGTGCAACAGGCA +TAGAAGGCCCTGTCTGTATGAAAAATAATTAGCTGGGTGTGGCAGCAAGTGCCTGTAATC +CCAGCTACTCAGGAGGTGAGCCCAGGAATTGGAGGCTGCAGTAAAAGTCATGATTGTGCC +ACTGCACTCCAGTCTAGGTGACAGAGTGAGAGCCAGTCTCAAAATAAAAAAATAAAAAAT +AAAAAAAAAGAAGGACTCCTGGATCACCCTGGGGCCGCGCAGGGATGGGTGGGCTCTGGA +GGCCACAACTCTATTCTAACCACAGTGGTAATGATGGCTTCGGGCAGGACCACTGATGGC +ACAGAAATCACCGGGTGAAAGGCTGATGCAGATGGGCCTGTGGCTGAGCTCAGCTTCCCC +ACAAGATCCTGCTTCCAGAAAGAAGAAGGCGTCCTCCTGGTGGAGAGCCCTCGGAGCTCA +GCCCATGAAGGAGGGACATGTGGTGCCCCTGCTGCGGCTGCCGCTCCCCAAGTCACCAGG +AAATGCAGACCACTGTCTGCGGCCACTGCATTGCTTCCCTTGTTCAGAGGTCGTCATCCC +ACAGTGATGGCAAAGATGGCAGTGACCACGGGGCAGGGGAGAGCCCAGTAGGCGATGGGC +CAGACAGGTGCGGGCCCGGGCAGGGCAGATGGGGCGCTTAAACTGCTCTTGCTGCTTCTT +TGAGAGTTAAATGTTTCAAGGCACAAGACTTTAAAAAGGAGGCACCTGGAGACATGAAGG +CCAAGGGTGACAGCCTCGTGGGGAGGGCCGTTGGGGGCCTTCCCGATGCTCGGCACAGAT +GGGCACTGTGGGCTATGGGCCGGGCAGGTGTGGTCCTGGCCTCAGGTTCCTGTCTCCCAC +TTCTGGGAGCTCTGCCTCCCTTGTGGCCTCTGTTTCAAGGTCATTTCTGGATGGGCAAAC +TGAGGCCCCAGTGGCTGGGGTTGTCCAAGGTCCTGAAGGCCAGTGTTGGAGCCTCCGGGC +ACTTGGCCCCTGCGGCCCCCACGCCGCTACCCCCAGCCCAGGCCCTCAGGTCCAGAACCT +CTTGCCCTCCAGCCTGGGGCCACTGTTCTGAGAGTGTGCCCCGAACGACACTCCCTCATT +AGCCGAGTCCCAGCTCTGTGTTCTGGGGTTGGAGCTCTGGGGCTGTTGTCCTCTGGGCCT +GGCTGCTCACTGAGGCTCCTCCAGGGGCCCTGCCACCCACCTTGTGTGCCTGCAGATGTC +CTTCCCATGCGAGCACCAGTGCCACAGCCCTGACCCCCCGCCCTGCCTACCCCATCATGG +CTCGCCACCAGCCCAGCTGAGCTGCTACCCCGAGCCCACCACTTCCCTAAGCCCCAGCTT +GCTCCTGGCACCTGGCATCAGCCTGGGAGGGGCTGATGATCTTGGGGGAGGATCCTGCGA +CAACTGCCGGGCCTGGGACAGTGATGGAAGTCCAGGCCTCCAGGGAGGCTAGGAGGCTGG +TCCCAGTCCCTGCTCAGCCATTAGGGCTGCCCCTCCCCATGTTGGCCTCAGTTTCCCTGT +GCGTAGCATGGGTTTGCGGTAAAGGTGATGCACTGCCATGGCAAGGTTTGTTATTGAGGG +TCCTTGGAGCGGGGCCACTGCAGCAGGAAGTCCCCGTGGGGCCCCCTGCGTGGGGTTGGC +CTGGCTCAGGAGATGGTCCCGGCTGCTATTTCATGTATCGTGAGGACACCGAATCCTACC +CCAAGGCCATGAGGGCAGAAGGCCAAGGCTGTGAGCCTTCCCTACTTGGAGACATTTGCC +CTGGGGAGCGGCTGTTCCCAGACCCTACATGCCTCCCCCACGAGTGATCTGCGGACTGGG +GAGGGCACTGCCTACATCTGCCCCAAAGGCAGTGGCAGAGGCTTTGTGGGATGAGGGTGG +TTTGTGCTCTCAGAGGCACTGGGCTCAGCCAGCGGCTGAGGTAGAGCTGGGGCCCTCCGG +GGCAAAACATCAAAAGTCTCTGAGCTCCTGTCCAGGGCTTGGATGAGTTGGGATTGGTGC +TGCCCCAGCACCCAGGATTCCCCAATGCACCTGCCACCTGGCAGTCCCTCCCCAGGGCTC +AGCACCCACCATGAGTCCTCAAGGATTTGGGTGATTCAGTGGCCTGCCTCGCTGGGCCTC +CCCCTTAATAATGCATTCTTGCTAATAACCTTCTTTCCTGTGTGTCATTAAACACATCCT +CCTGCTGGTGGGTAGTGGAGCAGCCGGTGGTGGCTGGGGAGGCCCGGGCCCCCAGGAGAG +AGGGAACCCTGGGAGGCTGGGGGGTAGGAGGGGACAGGGCTGGTGCACCACCTGAGAATA +GGTACAGGGGCTCCAGCTCTGGGCAGCATCATGAGACGCTTGTGGGGTCGGGGGCGGCAG +GGCAGAAAACAGCCTACAGGGGCCAGGCTGGGGGCTGCCCTCCTCGTCCTGTGGTCACTG +GGCTATGGGAATGGGAATGAGGGCAGGGCAGTGCTAGTGGCCCACAGCCCTGGGGGGCAG +CAGCCCAGGGATGGTTACAGGACAAGGTTTGCGTAAAACCAGGCTTGGAGGCCGGTGTGG +GGTGATCCCTCTTGGAGGTGAAGGAAGGGAGCAGTGTGGCAACGTCCTGGAAATCATGGT +CAGAGGGCCCAGCTGGGGCGTGTGGCCTGGAAAAGGCACTGCCCCCACCCCCACCAGCCA +GGGTCTTTCCCTTGCCCCTGCCCCCTCCTCAGGGCCCCGCCCTGTCAGCCCTGCCTGTGG +GTTTCAGCCCCATGGGCAGAGCATCAGACTTAGCCCGGGTGGAGGACATGGTCGGTCCTG +CGGGCAGGTCGGGGGAGTCCCAGGCCAGGGCCCAAGGCCACCCGGGGGCAGCCCTGCCCA +CGCCTCATCTGGTGGACCAGGGAGAAGTCCTCCATCAGGCATGGTTACAAAACTTCTCAG +ACTTAATTAAAGTCAATCTCCAGTTACTCAAATGCCATTGATTTGGATCTCGACTGATGG +GGAAAATATGATCATCATCATGGGAAACATCGATAGGAAGGCGCTGAGTACCTGGGCACA +GGGCCGATCTGGAGCCAACACAGTCACGGAGCCCCTGCTCTGGGCCCGACCACGGGGCCC +TCATGCAGAACCCTTGTCCAGGCCCTTCCGGAAGGGTCTGCCACTTGCTGCCTGGGTGTC +CCTGAATTCTCACCCCCTGGCTGAACCCAGGGGCCTCACAGAACCGGGATCCTGCAGGGC +TGATGGGAGGCTCAAGGGTGCGTGTCTTGGGGCCGGCAGCAGCCAGCGCTCTGTGGAGAC +CGTCTACCCTCGTCACGTGGCTGGGGTCCTCTTGATGTTGCACCGGGGACCCTGGGCTGG +CAGGACTAAGTCTAACTGGGGATCCAGGGCTCCTGCCTATCAGCCCCCAGTGAGTGAGTG +CAAGAGGGAAGGCCCTTTGGCCAGTGCTGCACCTTTTACTTGCGTGGGCTTTGAGGCTTG +GACCCAGCCCGAGGCCCATTGGGCAGCAGATGTCAGCACCTCTGTAGAGGGCAGCTGAGG +CCAGACTTCTCCATCCAGCCTCAGCAGAGAAGCAAGGGCGGAGAGCAGGTAGAACATCAA +GGCGGAAGGAGGTGATGCTGTTCGGGGGCTGGGGAGAAGTGCCTTCAACCAGAGCACCTG +AGGTTCTCTTCTGGCCTTGCAGCCTGGAGCCTGGTCTGGGGCTAGGAGGTGTCGCAGCTG +TGAGGCCCCAAGTGCAGGCCCAGGCAGAGGAGACCTGGAGGCAGCTAATGTGGGGGAGAG +TTGACTGGGGATCGTAATCTAGTTTTCTGTTTTTCCTTGGAAAAAGAAAGACAAAGTCCC +CAACTCACCTGCCCTTAAAATAAAAAGTCACAGGCTGGGTGCATTGCCTCATGCCTGGAA +TCCCAACACTTTGGGAGGCTGAGGCAAGTGGATTGCTTGAGCCCAGGAGTCGAAGACCAG +CCTGGGAAACATAGAGAGGGAAACCCCCTCCCTACAAAAAAATAGAAAAATTAGCCAGGC +ATGGTGTCGCATGCCTGTAGTCCCAGCTACCTGGGGGCCTGAAGTGGGAGGATCCTTTGA +GCTCTGGAGGTGGAGGCTTCAGCGAGCTGGGATTGCACCATTGCACTCTAGCCCGGGTGA +CAGAGTGAGACCCTGTCTCAAAAAACAAAACAAAACAAAAAAAACCACCAAAAACCAAAG +TCACATAAAATGTCTTCATAAATACAATAGAGGCAAACCTCATGTGATTTGTGTTCATGG +ACTTGGAGGGGCCAAAGGCCCAACAGAAGTGAGAGGAGGAGGGAGGGGAGGGGTGCAAGG +GCCAAGGGTAGAGGCCGGGAGGGGCCAGCATGGTGGCCTGAGTCCACTGCAGGTGGCACT +GCTGGCTTTGGTGTCCTCATTTCATCTCCTGTGACCTCTGCCCTTGGCATGTCCCCAGGT +ACCTCCTGTGGGCTCCTGGCTGGGGTGGGGTAGGAGGAGGAAGCTGAGGGTGGCCAGGGT +CTGTGTCCATCGAGGGGTGTCCAAATTCTAGTGGAGGGAGGGCTGGAGGGGAGTGGGGAG +GGGCCTTTGGCCAAAGCCAGGTGCTGGGGTGTGACGGATCTCCACGGTTGCTGGGACCTT +GTGGCCATTCCTGGGACATGGCTTTCACCTTAACAAGGGCCCTGGGTGTTCCAGGGGTCC +CCATCCCCTGCCCCTGGGGGCTCAGCACACAAAGCCCAGCCTGGGGCCTGGGCCATGGTA +GCCAGGGAGGTCAGGGTGTGAGGCCTTGGTGGCCTCCAGGTGGGCGGTGAGCCAGGGGGT +GTGGACATGTGGACAGTGCCGGGCCTGGGTCATGCACTTCGTCAACCCTTCACGCCTAGA +CCACAGCCTCTCTGAGCAGGGCCCAGCTTGCGTTGTGCTGAGTCTTTTGTTACTTTAATT +AATGCCCAGCTTCCTGACGCTTAATTAAACTGGAATTGCTCCATGTCCAATAGCCAAGCA +TCCCATTAGATACAAGTTAATGCAACTGTCGCAGTGGCCATGAAATGAGGCTGGTGCGTC +CCCCAGGGAGGGATGCAGAATGCATCTTGGAGGACAGCATGGCCTGACCGGGCAGCTGCA +CACAGGGCCAAACTGAGCCCGTACTGGACAGCCAGCCCTCAGCCCACCCAGTACTTCCAC +AAGACCCTTCCCAGGCCCCTCGAGGAGGACTCCCCATGGGGGCCCTGGCCTCCAGCTCCT +CTGCACGCCCGAGGGCAGCCTGCTTGCTTCCTGCTGAGGTTTGCTGTTCCAGCTCCATGA +GAAACTCATGCTAGTGTATCAACATTTGGAAAATGCAGAAAAATTAGAGAAAGGAAAGTA +GGGACTCCCCACCCCAGAAAGGTGCCATCCTCCCATGGGCCTGCGTTTTGGGCTCCGTAG +GGGCTACAAGGTGCTCTCTGGGGCCTGCAGTGGGGGCCGGGGCAGGAGCTCTGGGAAGGC +GTGGGGGCAGAGGCCACATTGTGAGGAGCCATTGGTTCTTCAGGAGCCGGAAGTTCTAGG +ATGGGGGGCAGGGCTGGGAGCCAGCGGGGGTGAGGCAGGCTGGGGATGCTGGGGTGATAC +CTTGCACCCACCAATCTCCAGTGCCAGCCTCTCACCCTGATGGCCCCGTGTCCAAGGCAG +CCTCACGGTGCCCTCTGCCAGTGGCCAAAGGCATTGTGCCTGGTTGGTCCATCACCCCAG +AGTCTTTTAAAATTAAATTAAATTAAATTAAATTATAATTAATTTTAGAGATAGGGTCTC +GATCTGTCACCTAGGCTGAAGAGCAGTGGCACCATCACAGTTCACTGCAGGCTTGAACGC +CCACGCTCAAGTGATCTTCCCACCTCAGCCTCCCAAGTAACTGGGACTGCAGGTGTGCAC +CACCACTCCCGGCTAATATTTAAACACTTATTTATTTATTTATTTATTTATTTGTTTTTA +GATGGGGTCTTGCTCTGTCACCCAGACTGGAGTGCAATTGTGTCATCACAGCTCACTGCA +ACCTTGAACTCTTGGGCTCAAGTGATCCTCCAGCATCAACCTCCCAAGTAGCTGGGACTA +TAGGTGCAGGCCACCACACCTGGCTAGTTTTTAAAGTTTTTTGTAGCGAGGGGCTTTCAC +TATGTTGCCTAGACTGGTCTCGAATTCCTGGCCTCAAGCGATCCTCCCACCTTGGCTTCT +CAAAGTGCTGGGATCACAGGCCTGGGCCACCACACCCGGCCAGCCCAGACTCTTGGTTCA +ATCCCCTAGAGGGCTTGAGTGGGGCAAGGAGGTGGCAAAGTGGGCAGCAAGGGGGCCGCC +CTGGACAGGTCTCCCTGTCCCCCTACCCGAGGGTACTGAGCGGCCTCTGCATTGGGCTCC +CAGGCTGGGCTGGGTGGGTCTGAGGCAGGAGCAGCCTCCCCCTGGAGGCCAGCTCAGGTG +GCAGAGGCCCGGTCTGCCCCGGGTCTGCGGAGCCGAGGGCAGGTCTCTGGTGCGTAGGTT +GCTGGGCCTGGCTCTCTCTCAAGCTTGTTTGCTGTTTGGGTCCTCCTCTTTGGGGCCAGG +GCCACACGCACCTCTGCGACATTAGCTTGGTGCCTGTGAGGGGCTGGGTATCTCAGGAGA +TCGCAGCAGGTCCTAGCACTACCCTGTTGCATTCTTCAAGGACTCCCCGCAGCCCAGTGT +CTGTGGAGTGGGGCGTGAGGTGCTGCCTCCCATGTTGCTGCTTAGAAGGACGCAGCCCTG +GAAACCCTCACTGTGGAGTCTCTGAGCCCCTCATCCGCAGAGCAGCAGTTGCTGCTGTTT +GCACAGACAGCAAATCCGGGGCATGTTTGTTTAGTAAGATTACCTCTGCTGGGGCCTGGC +CCAAGGGACAGGCCAGGCACAGAGGGGTGGGGGCTCTGTGCATACTGAACACCCCCCCGA +GAGTGGCTCTGTCTACAGCCGGACCACTCTGGAAGTGACGGCACTGCGGGCCTGGAGGGC +TGGGGCAGTCCAATTGGGCACCATGCCCTCACAAACAACACACACACCAGCGGTGGGGTT +GCGAGGGGGCGCTGAGGGAGGATCCTGGCTGCCCTGCTTAAGCCCTGCAGCCTGTGGGGC +TGTGTCCACCCGGGTCGCATGTTGCTTCTACCTGCACGGTGGCCCCACCACACAAGGTGC +CGTCCTGCCCTCCAGTCAACTTCCTGGGGCTCTGAGCAGCCTGTGGTGGCACCTCACCTG +GGCAGAGGGTGGGAGGAGCAGCGCCCTTCCTTCTGTGCAGGGAGTCTGATCAGGGTTCTG +TCTCACTGTGGGACAGTGGGGGCCGGGGAAGAGCGGCAGGTACCAAGTGCAGACAGCAGA +TGTAGATGCATGCGGGGGTCCGGGCTGGGGCCAAGAACACAGCCCTGGAGTCAGGGACAC +CGGCTTCATGTCCTCACTCTGCCATTCAAGAGCTGGGGGACCTCGGGCAGGTGGTGTAGG +AACAGGGAGGAGTCTGCCTGCAGCACGCAGAGGAGGGCTGTGCTGGTCAGGGGGTGTTTT +GGGGAGAGGACCTCAAAGGGAGGTTGACTTTGGGAAAGGGGTCAGAGTACAGAAAAAGTG +GGTCCAAATCCTGCTTCAGCACTGAGACCCTGCCTCGGCAGGGGTCTCCAAGCTTGGCTC +CACCCCCTGAGGGGCCAGTTACTGCATACCTCGCCCACCCAGGAGCTGGGGGCCCTGGTC +CTGTTTCCCAGGGAGCTGTTGGCACTTGTGGGCTCCTGGCTGGGGTCCAGGTGGGCTCTG +CTCCTCTGCCCTGCCCAGCGCTTTGTACTGAGCCCATCCTGCAGAGACTCAACGGGGCCA +AACGCACATTCCTTGACCTTCTGTGAGTCTGTCAGTCTTCATCCCTCCCTGGACCTAGGA +AGGCCTGGACAGCTTTGACCATTGGTGTTGGGTGGACATGGCGCTGCGCTGCACCCCAGG +CCCTCAGAGCCCAGCTGTTCTGCTTTCTGCTTTTGGTCCTGAGCTGCCTTGAAGGAATCT +GACCAGCAGGGAGAGCCCACGGAGCGGGAGGGCCTGTGGGGCTCAGCCCTGCAGCCGGTC +TGCCGAGGCCAGGCCTGGGGGCACAGCTGGGGCTGAGTACACTGAATGCCCCCTCGATGC +CATGCACAGCAGAAGAGCTGCCCACACCGCCCTGCTGGGCCCTGCCCGGGCTCCAGACCC +ACAGACCAAGCACACAAGAGACTGGGCTGCTTTGTCATGCAGCAGCAGGTAGCCGGACAC +ATGTTTCCCCATTCCCCTGCCATCCTCTGAAATCCTGTGGGGAGAAAGCATGTGAGGTCC +AGTGGGGGTTGGGGTGAGGGTCTGACTGGGGGCTTTCTAACCCACGTCTGAGTCCCATCC +GGCGCCAGTGCCACAGTGGCGGGTGACTGGTGCTGCTCACACTGGCAAGCTCCTACCTAG +ACTTTGGAGCCCAACTCCACAAGGCCCCTGAACTACCCCTGTAGGCACCGCAGCCCCCTT +GCCTTCCTCTGCTACGACATCAACCACTCTGATGGTATTTGTGGTTTGATGTGTTTAAGT +AAAAGGCTTGTTGCAGAGTTTAATTGACCCCATATGTCTGCCTGAGGAGGCCGTGAGCTG +CAGAGGGCAGGTGTGAGCTGGGCTCTTTCCTCAGTCCCCATGTCTTGCTGGGTACTCACA +GGGCACACACGAGCACGTGCGGCAGGGGCAGGGGCCAGCGGGGGATGGGGAGGCTTGGCG +CCCACGGCCCCGCTGCCCCATGTTTCCACTGCAGCCGAGGAGAAAACGAGGACTTTACGG +CTGTCACAAACATTTCATCTTGTGCATTTTACAGTCCACGACTGCTGTGAACACTGGGGC +TCCTGTCGGAGCTAGAAGATTCATAAAATGCATGTGAATTATTTTATTTTATTTTATTGT +TTTGAGATGGAGTCTCACTCTGTCACCCAGGCTGGAGTGCAGTGGCGCGATCTTGGCTCA +CTGTAACCTCCACCTCCTGGGTTCAAGCAATTCTCCTGCCTCAGCCTCCCAAGTAGCTGG +GACTATAGGCGTGCGCCACCACGCCTGGCTAATTTTTTTGTATTTTTAGTAGAGACGGGG +TTTCGCCATGTTAGCCAGACTGGTCTCAAACTCCTGACCTCAAGTGATCCTCCCACCTCG +GCCTCCCAAAATGCTGGGATCACAGGTGTGAGCCACTGCGCCTGGCCAAATGCATGTGAA +TTTTTATGTTCAATTATTCCAGGTTCCCTGCTCGGGGCCCATGGGCTTCCCCATGTACAA +CCCACCGGTAGGTCCCCGCCCAGTCCATGCTCCTCAAAGGCCAGCCTCACACCCATCCCA +CGTCCTCTTGGCTGGTAAACACTCTCCCCCTTCTTCCTTCTCCCTCCACATCTCAACTGC +TGGAAGGGAAGAGCTCCTCAGTCTACTTGGAGTCCCTCCTGCACAAGAGGATCCAGGGTG +GTCCAGGAGGGCCAAACCCACCTCTTTGGGTGCACCCCTGGGCAGTGGATTGGGGATCCA +GGGCTTGTGGGGGTATGCACCCACCAGGGCAGGTCCCTCAGGCTCACTCTCCCTGCGCCT +CAGTTTCCTCTCCTGAAAAATGGGCTTGTGACTAAATGTTGCAGGGAGCTGCTGAGAAAA +CGCCTGCTGAAAGCTTGGCAGGAGGTCATTGTGACCAGGGATGGGGCTGGGTGCTTCGGT +CAGGCCAGGGCTGGAGGCAGGGGCTCACACTGGGGTCAGCAGTGCAGGGGCGTGGCTGGC +GTGGCAGGCGCATGGGGATTGGCTCATCAGTTGCGGCCTCACGTCCCTTCGTTATGGCGC +CTGCAGAAGATGTTCTCTGATTAGTCTGCTGAATTATGAATTAGGTTCCGGGTCCCTGTG +CAGCTGTTCCCGGCTTGTCATCCCCACCACTTTATTTCCCCATCTGTTTATAAAACCAGG +AGCGCCGTCCTGCAATAAACACTTCAAACGCTTTTTTTAGGGGCTAATTAATTGTGTTGC +ATTTCTTCGACACAGCATGCAGGCCGGACCTGCCCCGAATTCCCAATGCGGGTGTGGCTC +CTGCTGAGCGCCTGGGGAGGGAGCCAGGCCTGGAGCCTGGGGGGCTGCATGTGGCCGCCC +CAAGTTTGTTTTCTCCAAGGCAGCCCTCCACCTTTATGTGGCGGGCTGGGCTGTCTCAGG +AATGCGCCGGCCATGTCAGGTTCCCCCTAGATTCCCCCTCCGCACCCTTTGGCTGAAGTC +CTCCTGCTCGGACCATAGGACACTCTTGAAATTATCTGTGGCACATCCAAGGTCAAGGTC +ACGCCCTGCTGCCAGCTACAGTGCTGACCCTGAGGGCTCCACCTCCCAGGCCCACTGAGC +ATCACGCTGTCTTCCCTGCCTTGCCTGCCCAGAGCACCTCTGCCCTCCAGGACCCCCTCA +GCGAGTGCGGTGGGCGAGTGCAGTGGGTGGGTGGCCCATCTAGGCAAGCCAATCTCTCCT +CGGATCCGTGCACCTCTTTGGAGAAGGCCTCTGGGAGCCCCAGCCCTGCTGTGCACCCTG +AGGCCTCACTCCGTCTGAGGAACCCAGAGAGCATCGCGGAGGAGGCTTAAAACAATGACA +ATAAGAAAACAAAATCACAATCACCAAGTCACGAAACAGCTCAGAGGCAATTGAGTTAGG +CAGCCCCCTGCCAGTGCCCAATGCCGGTAAAGTGGCTCTTTAGGAACTGAGTCCTAATGT +GGGCTGCGCAGCGGGTCAGAGGAGGTGTTCAGCCTGTGGCCAGGCATTGGGGCCCCAAGC +CAGTCCTCCACTGCGGACAGAACCTTGCCCAGCTGCAGCTGGAGCCTGAAGGCATCCACT +GCGTGCATCTGGAGGGGTCGGGGGTTCTTTGTCCCCAAGGCCACTGTGGCTCCTGTGGGC +CACCGTCATGTCCACTGGGACTGGTGGGAAACTGGGTCTGGGGACTTGTACCCTCCGCTT +CCTCATGTCCTCATCCTCAGGTGCCCTCCCAGCCCTTCAGGGGTCCTGTTTTCCAGCTGT +GGGCAGGATGTTGCTCCTCTGCCCTGTCTGTCCACGACTCAGGGTGCCAAGGCTGGTGGA +GCCTCCCTGCAGCCCCAAGGGAGGAGGCTGGGGCCAGAGACGCCCTGGGGTGGGGCACGT +CTCTTCCCAGTGAACCTCAGATCCCTCGGGCGCCCACGCTCCCCACTGAGGGCCTGGGGC +CACAGCACTCTGCCTGTGAGGGGTGGGCCCTTGGAGGCTTGGGGACATGCGCGCCCACAG +GCACGTGGGGAGAGCCTGCTGAGCGCTGTCTCAGTGATGGTTCCCCACACTGGCCCCTGA +CATGGGGCTTGGTGTGGCAGCTTGTTGGGGAGGTGGTGCGTGGAGCAGGATGGGGACCGG +GAGGTGGTTGCTGTGGGCTCTGCGGGGCGTGAGGGCCGGTGTTTGCCCCAAGCTCAGTGC +CTGCCTGTGACCACACCAGCTCATAAGTGACCTCTGGGTGGCCCAGGGGTGAGCGGAGAG +GGGACCTGAGCAGGCAACACGGGCCTGGAGAGGAGCTTTGTCTCTCTAGGAGAAGGCAGC +CTGTCCTGCCAGACCTGGTATCACGCCACCCCAAGGCAGGCCCCGCAGAGCCCTCGGGAG +CTCCACTCGGAGATGGAGACGCGCTTCCCTGTGTCGGGGCTTCGCTCAGAACATTTTTAT +GGGCTGTTAATTGTTATGCTTTCATTTAATTCTGGGTGTCATTCCATGTCAGCCAAGCCC +GACAGGCTGGGATTTATGCTTCCAAATTATGGGGCTCGGGCTGTTCAGAGGTAAAACAAT +TACCCATCAATCAGCCACCAACCGGCTTGTGCTGGGGCTGGCAGCCCCATTAGCGGGCGT +GGGCAGCCATGGCCCAGCAAGACCCCTTGAGGGACAGGACTGCCTTCGAGGGCAAGGCAG +TCTGGGTGAAGTCTCGCCCCAGGTTGGCCCTGTGCTGTGGCAGGGCGCAGCTCTCTGGGG +AGGCGGCCGCTCAGGGAAGGACCCCAGGGTCCACATTCACACCCAACTGGCTCCAGTGCT +GCAGCCCTCGGCCTCCCATATGATGGTGTGACCCTAGGTGGGCTGAGGGTGACCCGCCGG +AAGACGCTGCAGCATCAAGGTGGGGGGACCATGGGTCCCATATGCTGGGGCCTGGGGAGC +CTTGGCCAGCCATGGTCACTCAGTGGGAGGGGCAGGGTCACCTGCCTCCTGAGCACCCCA +TCCCCAGGAGGGAGGGACCAGGTGTGACCCACTTCACAGGGAGGGAAGCCTTGGCTGTCA +GAGGGGACACTGCGTCTCTCACTGGGAGGACCTCCCGGCCTGGGCTTGAGGCCCACCTGG +ATCTGTGCAAACGTAGATGTGGGTAGGGTGGGGCAGGGGAGGGGAGGTGGGCAGGGGAGG +TGGAGTGGGCTGGCTGTCAGCTCAGGAGTGGGGGTCGGGGAACCTGGGCCACAGAGCGGA +TCCTGTCCCACCTTGACCCTGGTATGGTTGAGTCGGCGGCTAAGCCAGGCCCCGTGGTCC +TTCACCCAGGGAGAGCCTGTGCCAGGCCAGGCACTGCCAGGCCAGCACACAGCCTTGACT +GAGCGCCTCCCCGTCTCAAGTTGTCTCCTGGATGCCCGGCTGGCTGCTCATGGGGACAGG +GGCAGGATGGGACAGCGAGAAGAGGTGGGCTCCCCCAGCCCCAGTGACCCTCCAGGCCAG +GGATTGGCTTCTCTCCCTGCAGAGATCGCCCTTCCCTGCCCCTCTGCCCAGCTGCCCTGG +GACTTGTGTCCCAGCCCTGCCCAGCATTCATCCTGGGTGATCTGCACGTGGGCATGGCGC +CTCACCGGGTCAGGGTGGTGTCCAGGTGAGCAGGCGGAGGACTCTCCTCACTGCCCAGCA +GTGTCCTGCTCCCCCAGCTGCTCTGACAGCCAAACTGGTCCCCAGCTGGGGCATCTCACG +CCCAGACCTGCTGCCCGTTGGTGCAGTGCAGCCCCCGCCAATGCAGACACTGTACCTCGG +TCTCCGGGACCCCCTCTGCCCCTGCAATTCGACGCTCTGCTCCTGCCCTGCTGGGATCCC +ACGTCCCTGGACCCTCCCTATGGCAGTCTCGCCCCGCGACCCTGCTACAGGCCTGCCCTG +CCACCCCCGGGCACACTCCCTCATCCAGAGTCTGTGCAGTCACATGTGGACCCCTGAGGC +CGGCCTGCGGCTCCCTGCTCACGGGCGGCTAAAAGGGGGCTTTCCAGTCACGCCCTGCCC +TGGCCTTCTGCCTAAGGCCCTGGCCCTCATGGGCCAGGCATGGTCCTCAGGCCCTTGGCT +CTGCCAAGGCTCTGAGACCCCACCCTAGAGAGACCCTGGCCCACCCAGCCTGGCCCTGCA +GCAGTGCCCCAAGTGCCCCCGAGCCCGGCCTGGCTGCTGCCAGGGTGACCACCAGGGGCA +GTAGTCAGATAGAGGGCGGTGGCCGGGCCCAGTGTGTCTGGGTGACCGCAGGGCCTGAAG +GTGTGGTGGCCCACCCGGGTCAGAGTGAAACTGAACTCCTAGGTCAGGGTCGGGTCCTCC +CAGGGTCGTGTCCTCTGGAACTTGGGGCGAGTCACTACGCCTCAGTGTCATCGTGGGCAG +AACCTTCCACATGTGGCATTGAAATCTTTCAAATTGAATAGGAAAAGCCCCACGTTTTCT +GAGCCCTATATATAGACCAGTACTGTCCTAAGTGTATTCTAGGGAAAGACAGTGGCCAGC +CCTGTAGCTCAGTTATTTCTGTTTAAAGTGTGAACGGGCTGGGTGCAGTGCTTGAAAATC +AAGCATGAAGTGAAACCCAGTGGGCCGTGCATGGCTCTGACACCCATGAGTCATTCACAC +GATGCCACTTGCTCATTGCTGTCCCACCCCAAATGCAGCACTGGTGGGCGAGACCCTCTG +GGCATATTACCTGCGGGATGTGGCTCCAGCGCCTCACTTCCAGCTCACTGCTGCCTCAAA +CTCCTGGACTCAAGGAATCCTCCTGCCTCAGCCTTCTGAATAGCTGGGACTACAGGCATG +TGCCGCCACACCCGGTGAATTTTTTTTTTGTAGAGAGGGGTTCTCTCTATGTTGCCCAGG +CTGGTCTCAAATTCCTGTGCTCAAGCGATCCTCCCACCTTGGCCTCCCAAAGTGCTGGGA +TTACAGGTGTGAGCCACTGCACCCAGCCTCTTCACCCTTTAAACAGAAACAACAACTGAA +CATACAGGGCAGACCAGTGTCTGTCCCCAGTGCCTGTGCTGGGGGTGACTTTCCAGCTGG +GGCTCAGCATTGCGAGTGGGAAGACCTCCTGGGGCCAACATGGCTTGGATTGTGAGGGCA +CGTGGGTCGCCGTGGGGCCAGAGTCCAGCAGTGGCAGAGCTGCACAGCAGTGGGGAGGGG +CAGGGCAGGGCAGGGAGAGGGCCCCGGCTGGCCCGGCTGGCCCAGCCTGCCCAGGGCTGC +ACGGTTTCCATCCCTGTCCCCAGCTGCAGTGGGACACCTGCCATGGGGGAGGCTGGGGGA +GGCCTGGGGTGGCGCCTTGGGCTCTCAGCCAGGAGTTCGCTCTCTCCAGGTCAGGCTGGC +AGAGCAGCCCCAGGGCCCCTGCACCCCCACTGCCCATGCCCACCTTGGGCTCTCTGATGC +CCGGCAGGGCCTCTGGGCTTCTCCCTCCCAAGCTTGGGTGGCAACGCTGGCATTTGGAGC +CTGGGGAGCTGCTGACAGTGCTGGTCCTGCCCGCGAAGGAGGCGGTGCCAGGCTGTTTGG +AAATGTCAGGCTGATGGGTGGTGGCACTGCCCAGCACCCCACCCCCGCTCCCACCCCAAG +AGGCTGGACACGGGCTGGGGCCCCGGTGATGGAGCCAGGCCGGGAGCCAGGAGATGCTGC +TGAGCAGGGATAGCTGGCTGAGGGCTCCTGGGCGGCAGGGGATCCGAGGCTGATGGACAA +GGGGCCTCTCCTTGCCACCGCAGCTGCGGCCTTGGTGGGCCGGTCGATGCGGAAGAGTGA +TGGTGCACGTGGGGCCGTGGGGTGTCGGAGGGAGGTTTATTGATGTCGGCTGATTTCCCT +GGGGGCCCCTTGCTGGCAGCAGCCACCATGCTCCCCGAGAGCTAACCGTATCAGGCCGGA +AGGGTGGTGGGCAGTGTGATGGATGGACTCCGGCTGTCGGCTGGCTGGGCCTGGATGGAG +CCCCGAGATGGGCACACTGGGCCGTGACAAGAGTGCCGTGGGGTCCCTGGGGGAGCCCAA +AGAGGCCTCTGAGAGGGTCTGTGCTGGGAGGTAGACCTGAGAGAGGGGAGACACCATCCC +AGGGTGGGCACAGGCATGGGGCAGAGGGCACGTGACGCCAACCTAGGGCCCCAGGGGGTG +GGACGGAGGGGCCTGGTTCTGGGGCATTGGGAGAGGCCTGGGACTCTGGACCTGGTCTGT +CTTTCTTGTCCCCAGTGTGAGCACCAGCCCTTGCAGCTGAGCCCTGGGAGGCGCCTCCTG +CCCACGCAGCAAAGCTCAGAGCTCTGTGGCCTCCTCTGGGCTCCTGCACAGCGGGTTTGC +TCCCAGCTGCTCCCCTGACACGGACACCTTCAAGGGCCACGTGACTGCCATCCCCAGGCC +TTGGCCCTCGATGAGGAAGGGCCCTTCTCAACCTGTGGCTCTGAAATAGGTCTCATGATG +GTGCCAGTTTAATGACAGGAGCAGTGGCTAATCCAGTGGTCATTATTGCATGGGCTGTCA +TGCCCTTCTCTATCCGTGCTCCCTGAAGAGGCGAGGGTCCACTGCCGGCTGCCACACAGA +GAAGCATGGCCACAGAAGGAGGCTCCTCTGCTCTGAGTGGGATGTTGGCTCCTCGGGCCA +CACTGGGCTGGAGGACAAGGGGAGGCAGGGGTGGGAGGGCCCTGGGCTGGGGTGGATGGG +GTGGGCCTCACAGATGGCATGGCCCTGTGGACAGCGAGTGGCTTTTCCTCCCCAGGTCTC +GTCCTGAGCCCTGCTCCTCCTCCTGGCCTCCCCTGGCCCCACACCTCTCCCACTGGCTTC +CTTTCCTGGCCTCTTTCTCTCTGCTCCTTGTCTCCATCTCTCATTCCTCTGGGCCTTGCT +TCACGGAGTCACCAGCCCGTGTGACAATGTCCACTTTCCCTGGCCTCATGTCTCCAACTT +AGTGTGGGACCTGCCTTTCCAGGCTCTTTGGCCACATGAGATCATGGAAACACATGGCTG +CTGTACCCACGCTGACCTGGCTCAGCCCTGGCTCATGATGCTTCCTGTGCACCCTGGTCC +CATCTGTACCTCAGTTTACCCATCTGCCACACAGGGCTGAGGGCATCTGCCTTGTGTGTG +GCGGTCAGGCTGGCCCAGTGACCGCCGAGCCATTTTGGCTTCCTCAGGTCTGGCCACTGT +GAAGGACATGGCTGTGCCCCCCGTCTGCCCTGTGTGGCCCTGGGCACATTAACCCCTTCC +ATAAGCCTGGTCTGCAGACGAGCGCCCACCGGGCTGGCAGTGCCTGAAGAGTCTCGGGCG +ACGTCCACTCACCTCCCAATCTGGTCCCAGCTCTGCTCAAACTCAGACTGGAGGATCCCC +CAGGGCAGTGACTCCAGTTCAGAGTCTAGCTGACTGCGTCCCTGGCAGCCAGGCACGGCC +CAAGGTCCAGAGCTGGAGACTGACCCCCCTGTGTAGGACCTCTGGGAAGTCCCCAGGACC +CAAGACGGCTCAGGGCTAGTGAGGTAGGGACAGGTGGCTATTTCAAGCCCCCAGCGGGCT +TCCTGCCTGGGGCACCTGGGCACAGTGGAGAAAGATGGCTCCCGGCAGAACACATGCCCC +CATCCTTCGGGGCCAGATGCCTTGGGTTGGGCACGGAGCAGGGCCCCCAGCAGACACAGA +GGCCAGGGTGGGAAGGGCCAGGGCACCGCGCAGTCTCTTGCCCTGTGTCAGGGCTCCAGG +CCTATGGTGGGGCTGGGCCTACCCACCCTGTCACTTTCCCCATACGGCTTTGGGGTCCCA +GGGGTTCAGGGGCCCCTCCTGCCTGACCCAGCCTTAACTTTTTGTTGTTTCTTCTCATTA +CAAAAGAAGCATGTTCAAAAGAACCCCACAGTCCTCCATGAACCCCACAGTACCCCGTGA +ACTCCAGAGTCCTCCATGAACCCTACAGACTCTCATGCACCCCACAGTCCCCCATGAACC +ACATAGTCCCCTATGTACCCCACAAGCTCCCATGTACCCTATAGTCCCCGATGCACCCCA +CAGTCCCCTATGTACCCCACAAGCCCCCATGCATCCCACAGGCCCTTATGTACCCCACAG +GCCCCCATGCACCCCACAGTCCCACATGCACCCCACAGGCTCCCATGAACCCCACAGGCC +CCTGTGCACCCCACAGTCCCACATGCACCCCACAGGCCCCCATGAACCCCACAGGCCCCC +GTGCACCCCACAGTCCCCTATGTACCCCACAGGCCCCCATGTACCCCACAGTCCCCTATG +TACCTACCCCACAGGCCCCCATGCACCGCACAGGCCCCCATGAACCCCACAGTCCCTCAC +AGCCCCCATGCGGGGAAAGGGCCTCACTTCTGGCCGCTGACTGACTTGCCAGTTTCCTGG +AGTTCTTTATCCAACTTTCAAGGTTGCTGAGTCCCGGGAACACCTCAGAAACCTCACGAA +ACAGTGACAGGTTGTCAATCAAGCAGCAAGGTTGACATGTTTGAGCAACGTTCAGCCTGG +GAGGCGCTGGGGCCAATTAGCAGAGACTCCCAGGTAGCAGAGCCCCCGGGCTCATGGCTG +GGGGGTGGATGGTCAGCCCTGACGCTGCTGCCCCCACCCGAGGATTTCTCCCCAGCCATG +GACTTGGGGCTGAGGGATTCCTGTACCCTCCCGGCCACCTGGACAGGGTCCCCGCCGTGG +CCCGGCCTAGGGCGTTGGCTCAGACCACACCTGCCCAAGGATGGAGCCTGACACCCAGGA +AGCAGCTCCTTGCAGCGCCCTGGGCCTCCGTGGGGCCCCTCTTGGCAGAGTGACCTGGGG +ACCAACCCCCTTCTGTGAGGCAGGTGAGGATGCTGCCTTGTGGGCTGAAGGCCAAGGGGA +AGAGGCATACTGGGGCCACTCAGGCTGAGCAGTGGTCACAGCGGCCACCCCTCCCTCTCC +AAGGCTCTGGCGACCACTGTTCTGTTTAGCCCCTACCCCTCCCCACCTTTTAAAAAGACA +GGGTCTCGCTCTGTCACCCAGGCTGGAGTGCAGTGACACAATCAGAGCTCACTGCAGCCT +CCAACTCCTGGGCTCAAGCGATCCTCTTGCTTAAGCCTCCGAGTAGCTGGGACAACAGGT +GTGTGCCACCATGCTCAGATAATTTTTTTAAAATTATTTTTTGTAGAGATGGCGGTCTCA +CTTTGTTCCTCAGGCTGGTCTCAAACTCCTGGCCTCAGGCAATCCTCCCTTCTTGGCCTC +CCAAAGCCCTGGGATTATGGGAGCCAGGTTCCCAAACACTCTCTGCTCTTCCCTCCACCT +GGCATCTCCCTCCCCAAAGCTCTGCCCCATCCTGAAGTCCCCACTGCAGATGCTGCCCCT +CCCAGAAGGTAGCTGGGCATGGGCTCTGCAGCTGCAGAGTTATGGACTGGGCCTCCCTGG +GCAGCTTCCTGGGAGCTGCACCATGCACGGGTCACGGGACCCTCCTGGGTAGGTTGAACT +GGGAGGCGACAGAGACCCTTCTAAAGTCCCTATGCCGGGTGCTGGGCTGTAGTCACATGG +TGCCCTCCCCAGGAATCCCTGAGGGGTGGGTGCGTCTCTCTCAGCAGCACCAGCAAGGAC +CAGCGGGGAGGGGTGAGCATCTTTGTTCTGTCCAAGAGCCTCTTTGGAGCACGAGCACTT +GCCACATGCAGGAGAGAGCCATGTTCACTTTCCTTTTATGGCTGAGTTTGAGATGTCTGG +ATAGAGAGTTATCAGCCAAGGCACTGATAAGGTCTGCGGGGGGAATATACTGTAAAGGGC +TGAGCGTGGAGTGGGGGCTACCTCTCCTGCTCGGGCTGGTGTTGGGGGTTGGGGTGGGCT +GGGTGAAGCTGCCACTCCTGGCCTGGATATATGGAGCCCTGGGCAGTCCTGCCTGTCCCA +TGGCTTTGCTGGACACAACAAGAACTGCCAGATGTCATTTGTGTGGGAATCATTTTGCTG +TTTGAGCGAAGTTGGATTTGTTAGTGTGCTCACCAGTGTGGATGGATGAGGTCTGACCAG +GAGGCTGCCTGTTGTCTGTCTTTCACAGAGGGCCCTCCACACCCAGGGTAGAGCTGGGGA +GAAGGAGTCCTGGGGAAATACTGAGTTAAACAAGGCTGATGTATCCTCTGCAGGACTTCT +CAGTGCCTTTAGCATGGCGGGTGTAGGTGAGTCTAAGAGATGGCCAGGTAGCCTAGGTGT +GGATATCACCAGGCTAGGGCTGCTGTCTGTCTCCTCTGCTCACGCTCCTGTGCAGGGAGG +GACTTGAGGGTGGGCCTGGGGAAACTGTGGAAAGTAGGAGTCTCTGTCCCCAGACACTGT +CTCTGAACTGGGGCCAAGATTCAGTCATTTCATGTCCCCACTAGGCAGTGCTTACAGATG +TTGCCCAGTATCAGCTGCATTGATTAAAGGAAGAGCTTTCTGACCATCAGGTGGGGGCGC +TCTCCTGGTGAGTGGGGCTGGGAGGCAGAGCCCTGTCCTCCGCGGTGTGACTGGGACGTA +ATCCCCTCCTGGGGCTGAGTGGAGCAGGGGCTTGCGCCTCCCGCAGGCCTAGCTGTGTGG +GATCTCATGGCACTCTGCTTTTATTCTGTTTGCTCCAATACCTTCTGCTTGCCACCTGCG +ATGCTTATTTTCCATTTCCAGTGGTGCTGTAAGACTTCCTTTCAAAATATAATCACTTAA +GTTAAAAAAGCCCATTCGAAGAAAGCCCTCGAGTAAACAATAGTGGAGCAGGTGGGCAGG +TGGAGCTGGCCCTTGGCCGGTGTGTGGGCTGGGGGCAAGTGGGAAGGGACAACGTGGGAA +GGAAAGGGGAGCAGGGGGTGTGGGGACCCTCCCTGGGAAACTCCCAGCCCGCCCTGGCCT +CTGTTACTGCCTGGCCCTGCTGAGCTCCCTGGGCTGCTGTCTGGTGGCCAACACTGGCGT +TGGCTGCCCACATGCCATGGGGTCTGCACACAGCAGGGGCTGGGGGACAGCGTCACAGGA +GGAGGAAGGCCACCTGTCACAGGAGAAGGAAGGGCACACAGAGGCTTGTCTGAGCCCCAC +GTGAGGATTAACAGAGGGGATGCATTGCAGTAAAGAGCACGAAGCTGCTGTGACCTTTGC +CTCTGACCGCCCCCCTTGCAGGGCCACGCCTGCACGTAGCCTCTGGGCAGGTGCCATGGG +GTCTGCCAAGGCTGGCATTGGCTGCCCAGATGCTGTCCTGCCCTGAGGTTCCATAGTCCT +CCGGCCACTGTGGCCTCACACTGTGTCCAGCTATGCTTTTTATTTACCTGTTAACCTCCC +AGCATACTTATTCATGATAACAGTGACAGGGAATGGGGCGAAAGTCTGAAGTGTCCTTCA +CCAGCAAGGGGCTGGTGGAAAAGTGGGACTCCTGTCTGAGGCCACTCTGGGTGGTGTCTG +TGTCCCAGGACTCTACAGCCAAACCCAATGCAGCTGGGGGCCTTCCATCCACAGACCCAC +ATGAGCAGTGGTAAGGACCTGCTATATTGAGCCAGCTCCTCACACACGCCCTCTTCCCAG +AGGGTAAACTGAGGCCCAGGATGTTGCCTCTTGCCTGAGGCTGCATGGCTGGGTGGAGCC +AGGCCCTGACCTCTTTGCTTCTTCACCTGCCCAGGGCAGGTGTTTGGATGTTGAGTCGAC +TGATGCCCCAGGGCGCCAGGCCCTCCTTCCATCTCACGGTCCCTGCCCCTGAGGCCCGTG +TGTTGGGGCTGGGTGGAGGTGGCCCTGTCTCCTTTCCAGGTGAGTGGTGCGCACCCTGGT +GAGCAAGGACCCCAGGCCCTGGCTGCAGGGCCTCCCTGTGGCTGGAGGTGTCTTCCACAC +GGCCAGTGTCCGGCACGAGCACTCTGGGGTCGGACACTTGAGATGGGCTGGAAGGAGGGG +GCATAGAGCCTTGCACAGACAGGGGCAGCTCAGGCCTGGGTTTGAATCCTGACCTAGGCA +CCCTGTGGTGAGGACAGCCACAGGCTGAGGACACTGGTGTCCAGCATGTGCCCAGCTGTC +ACCTCCACCCTGGGTTTGGCATGGGGCTGGCAGCAGGCCCAGGAGGGATGGGAGTCAGAG +TGTCAGGGAAGCAGTGGGAACTCGGGACACTCTGCTGCTCCATGGGAACAGCATTGGCCC +TGTGGTGTGGGCAGCCTCAGCAACTGGGCAGGGGCTGTCAGAGCCCAGGGGATGCTCCCA +GAAAGTGGGATGGGAGCCCAGAGCCCACAGCCCCTGATATCACTCAGCCTGGGAGCAGGC +CCACTGCCTCCACCGTGCAGACGAGGAAACTGAGGAGGGCCCTTGGGTCCCCTGCCCAGG +CCTCACAGAGAGCAGGTGACAGCTGGAGCCACCCCAGGCTTGTCCACCCCCCTGAAGGGA +TCCCCAGGTGCCCACCCTCTTCCTGCCATCTGGGGGCATGACTCCTACTGCTGACTTGAG +AGTGAAGCTACCGCCACCGCCTCCCTCCACACCTGGGCCAGCCTGGGCCATGCCAGGGGC +ATGCCTGCTTCTGGCCCCATGGGCCTACTGGTCTTGACCATTAAAAAGCATGTGTTGGGG +CTGGGCGCGGTGGCTCACACCTGTAATCCCAGCATTTTGGGAGGCCGAGGCAGGCAGATC +ATTTGAGTTCAGGAATTTGAGACCAGCCTGGCCAATAGGAAGAAACCCCGTCTTTACTAA +AAATACAAAAATTAGCTGGGCCTGGTGCCTCCCACCTGTAGTCCAGCTACTTGGGAGGTT +GAGGCAGGAGAATCGCTTGAACCTGGGAGGTGGAGGTTGCAGTGAGCCGAGACTGCGCCA +TTGCACTCCAGCCTGGGCGACAAAGTGAGACTCTGTCTCAAACAAACAAACAAACAAACA +AACAAAAAAGCACGTATTGGGACTACAGTCAATGATAATTTATTGTGCATTTAAAAATAA +CTAAAAGAGGCTGGGCACAGTGGCTCACGCCTGTAATCCCAGCGCTTTGGGAGGCCGAGG +TGGGCGGATCATGAGGTCATGAGAACGAGACCAACCTGGCTAACACAGTGAAACCCTGTC +TCTACTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATTAGCTAGGCTTGGTG +GCAGGCACCTGTAGTCCCAGCTACTCCAGAGGCTGAGGCAGGAGAATGGTGTGAACCTGG +GAGATAGAGCTTGCAGTGAGCCAAGATGGAGCCACTGCACTCCAGTCTGGGCGACAGAGC +AAGACTCCATCTCAAAAAAACAACAAAAAACAAACAGACAGAAAACTAAAAGAGTATAAT +TGGGGTGTTTGTAACACAAAGAAATGATGAATGCTTGAGATAATGGACACCCCATTTCCC +CTGATGTGACACTAACCATTGTATGCCTGTATCAACATATCTCATGTACCCCGTATCTCA +TGTACCCCATAGATATACCCACCTACTATGGTCCCACAGAAAAGGCATGTATTGGGGCCA +GGCCCAATGGCTCACACCTATAATCCCAGCACTGGTTTGGGAGGCCGAGGCAGGAGGATC +ACTTGAGGCCAGGAGTTCAAAACCAGCCTGGACAACATAGCGAGACCCCCATCTCTACCA +AAAACAAACAAAACAAAAAAACTTAGCCAGGTATTGTGGTCTGCACCTATAGTCCCAGCT +ACTTGGGAGGCTGAGGCAGGATTGTTTAAGTCCAGGAGTTTGAGGCCACAGTGAGGTATG +GTTACACCATGGGTGACAGAGCAAGACTATTTCTCTAAAAAACAAACAAAAAACAAAAAC +AAAACACAAAAAAGCATGTGTTTTCCTGTTCTCCCACCACCCCACGGCAAAGACAGTACT +GGCTATTGACACAAAAGGTGTGAAACGCCCACATGCTAAGGAAGACAGAAGCCCCCAGAA +TCCAACCTGGGGGTGTTTCAGAAGTGCTGAAAGGGAACAGTGTGGTCCCTTTAAATGATA +CGAAAGAGAGGAAGGGGGCTGGGCGCGGTGGCTCACGCCTGCAATCCCAGCACTTTGGGA +GCCTGAGGCGGGCGGATCACCTGACGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACCCTGTCTCTAATAAAAATATGAAAATTAGCCGGGCGTGGTGGTGGACTCCTGTAAT +CCCAGCTACTTGGGAGGCTGAGGCAGGAGAATTGCTTGAACCTGGGAGGCAGAAGTTGCA +GTGAGCCGAGATCAGGCCATTGCACTCCAGCCTGGGCAACAGGGCAAGTCTCCATCTCAA +AAGAGGGGAAGGAAAGTGCTGGGTAGAGGAAGGCATGGTCCCTGGCTAGGGTTCCACCCC +CATGGACCTAGGTGAGGACAGGCATTTCCTGCCCACATGTTGTGGCATTTCCCAAGACTA +CCCGGGCCTGCCATGCTCCATCTTGTGCCTATAAAAACCCCTGAGACCCTAGTAGGCAGA +TACTCTAGCGGCTGGACATTGAGAGGAGTGGATCAGTGGAAGAACGCACAAGTGGCTGGA +CGTCAAGCGGAATCCACAGACAGGCACTGGCAGGCCTGGCATTTGTGAAGCCGGCTGCGG +CAGAATGATGTGGAGTTTGGCTGGGGCAGTCGTAGGAGAGCTCAGGCCGCCCAGGGGAAA +ATCATCTCCCTTCTGGCTCCCCCATCTGCTGAGAGCTACTTCCATTCAATAAAACCTTGC +ACTCATTCTCCAAGCCCACGTGTGGTCAGATTTACACAAGGCAAGAACCCCAGGATCCAG +AAAGCCCTCTGTCCTTGTGATAAGGCAGGGGTCTAGTTGAGCTGGTTAACACAAGCTGCC +TATAGATGGCTAAACTAAAAGCACCCTGTAACACGCCCAGTGGGGCTTCACGAGCTGTCA +ACATCCACCCCTAGACACTGCCGTGGGGTCAACACCCCACAACTTGCCCGTCTGTATGCT +CCCCCAGAGGTTTGAGCAGCAGGGCACCGAAGAAGTGAGCCACACCCCCATTGCATGCCC +TGCGAAGGGGACAAAGGAACTTTTCCTGTTTCAGGGGAATGGTCCTCACTGCCTCCTCCA +GATTTTCTGCCCTGAGTTGTGAGGACAGCACAGCTTGGGCTCTGTCCACAGCTTTTACTG +GGAGCCTGAGGCTCCGTCACTCACTCGGCTGCTTTTTCCTGTGCTGGATGAAGCCCAGGA +GCTGGCTGTGCAGGTGTGTCTGGGATTTCATGGGCATAGATGACTCCAGGACAGCTCCTT +AAACACCAAGCTCAAGCAGGTATTGCCAGCTAAATGAGGTCAATTCCTGGCAGTGGATCT +CAGGGCGCCGGCCTTGGACCCCACCTGCTTGCCCACCCCCAGCAGGCAGAGACCTTTCTA +GAAGGTCACAGATGCTGCTGCGGGATGGATCGGGTCCCAACCCTGGCTGGGAGTGATGCC +CGACAAGCTGCTGTAATTCTCAATTCTGCTCCGGAGGCCTTGGAGATGCTGCAGGCGGGC +AGGTGGGGTTGGGGGTCAGCGTCACAGGAGGGGAAGGCCACCCATGGGGGCACATAGGGG +CTAGTGTGAGCCCTGCATGAGGATTAACAGGGCATGCATTGCAATACAGAGCACGAAGCT +GCTGTGACCTTCCCCTCTGATCGCTGTCACAGGGCCTAGCCTGCACGTAGCCTCCTGGGC +AGGCACACCCCTGGACCCCTCCCTGGTGCTCTGCTGGAGGCCACGCTGGGCTCTGGAATC +TTACTGCACAGAGCTCCTGGAGACCCACCCTCAACCCTTGGGCCCCCTCTTCCTTCCTGG +GTCCTGGAGGGGGCTGTTAGGGGGCATGAGGCCACGCAGCCCTTGAGCACCTACTGTGTG +CAAGGGCCTGGCGTTTGTGAAGCAGGCTGCGGCCATCCTGGGTGGGAGTCAGGGAATGGG +GGTCCCGGAAGTGCTGGCTTTTCTGGTGGCTGTGGGGGATCAGGGGGCCTTGCTGTGTAT +CTGTGAGCTGAGCCATCCTCTGAGGGGCTGAGCGCTGGCAGGAACCTATCACGTTTCCCA +GGGGCAGGGTTGGGCATGAGAAGCCCTATCCTGCCTCTCAGCTAGGCCATGTTTCATACC +CCACAGATGCTTTGGAGGTGACAGATCTGGGTCAAGACTGGCCTTCCTGGTGACCAGCCT +TCAGATGGACACTGGGCGGCAGGTGTTCCTGGGCTGCCATGGCTGGTCTCCTGTGCTGGT +CCCCAGAGCAGCCTTCCTCTCCCCTCCCCAGACACCCCATCCTCTGCCGAGGCCTGTGAG +CACCTGCTGTGTGCCCACCTTTTGCTTAAACCCCAGGACGGCCTTACCCAGATGGGGAGC +CTTGGTTGGATTGAAGGGGCTTGCTGGAGGTGCAGGGGGAGGGGAGGTCAGAGCCCACAT +GCATCCTGAGCTCCCTCATCTTCCACACCCCATGCTCATCCCCCCAACCTGGCCCCGATG +CTATCAGCCCTTAGCTGGGGGAGGGCGGACCCCGGGGACCTCAGAGGCAGGGCTCCTGCA +AGCACTTTGCTGCACATGTCTCTGTTCCTGAAAATGCCCCAACCCCACCAGGGCAGCAGG +CAGCAGGGTCTGTGGGAAAGTCAGGAGCCCCGCTGATGGTCCTGAGGGGCCACCCCAGCC +TCAGGAGGAGGACCTGCCCTTCTCAGGGCCCTGCTGTTGCTCCTTCAGCTCGCCTCCTCC +ATGCTGGCCTCCGGGCTGCTCACACGAGGATTAGAGGCAGGAATGAAGAAAACCAAAGTC +AGACCACTACCAGGACCAGGGTACAAGAGACCAGGCCTGGACACCACTTATGGCTGGGGG +CCTTGGGCTGGTCAGCGCCTCCCCCTCAAGGCATATACACAGTGGATCGGTAAAGGCTGT +CCCATCTGGGGCTGTGTCAGGCCTCTGTGGGAGGAGGCATGTGGCGGGCCCAGCTCAGTT +GATGGATTCAGACCCATGCATTTGGCCAGCCCTAGTCAGGGAACATTGCAGCCACTGCCT +GCCCAGCACTGGGCAGGAGGAAGTGTCCTTTCTAAGAGTGGAGGGAGCTCCTGCTCTCAG +GCCTCAGAAACGAGGTGCTAAGGGGGCTTTCAGGCAGCAGCCTCAGGCAGGAGGAGCTCC +CGTGCCATGCGAATGGCTTTGCCCAGACACCGGGTGGCTCAGGCAGGTCACTCTGCCTTC +TGTGTCCTCCTCCTTGGTGGGCTGGTGGGCTGAGCCAGGAGTCGGGCTTGGGGCCTGTTC +CAGGCTTGCAGGCAGGAACAGGCCCGGGACACCCCAGAGACAATATTGATGCTGTTTCTG +CCCAAACAAATGCCAGCTACTAATTCCGGTCTCTGTTGGAAACACAGAAATCAATGCTCA +CAGAACAGGGAGGCTGGCCCTCGAGGAGCAGTGTGGTGTTGGGTCCCCAGGCAGTGATTA +CGACAGGACAGGCAGGCAGGAGAACAGAGCTCTCGACCTTAGACACGTCCCATGCGGCCC +TCACCTGGCGACCTGGACTCGGCAGCACGTTGGGGGTCAGAACAGTGGGTTCTCAGGGAC +CTGGCCTCGGGGGGCACCCGTCATCCCTCAGCACCCTCCCCTGCAAAAGGGAAGCAGGGC +CTGGACATGACCCCCAACCCTGGCTCCTGCCACATTCCCCTGACTTTATTTACCACCCGA +GAGACTCATAAATAATAGTTGAGGGGTCAGTGAGCGAATGAACTAGCCAAAAAACCAGCT +GGGGAATGCGTGTGCAGGTGGAGAGAATGGGCGCTGGGCCTGCCTGGGCACAGGTTCACG +GGCCTCTGGATGCAGCTCACCCCGTGGGAGCCCACAGCCCTGCAGGCCGGGCAGCCTGAG +GGCCAGGACAGCCCCACCCTTCTCTCAAGGTGCTGGTCCAGGGCCTGTTTCCCCATCCAT +GTAGCATTCTTGATCTCTGGGTCCTACCACGTCCCTTGGATCTCAGGCTCCCAGCCAGGA +GGGGCTCCCACCACCATCTCATGACCTTCTGAAACCCCAGCGCTGGGTGTGCACCTTCTT +GCCAGGCTCCATGGGCAGCAAGCACCCGCCCCTGGCCTGCTGGGCACTGCACCCAGGAGG +TGCCCAGTACTTGCTGGGACAGCTGTCTTCTGCTATGTCCTGGGCTCGTGTCCTGCCTGC +AGCTTCCGGGCTGGGGAGCTTGGGCAAGGCTCTTGGCCTCCCCCACCCCCACCTTGGTAT +CCCTCAACCCATCCCCCTGGACATGGGGTTGGTGCCTCTATTGGAGGAGGTGGTAGGTCA +GGCAGCCTCTGGCCCGCAAAGTCGGCCCTGGGTCCACCAGCCGCCCCTCTGCCCTGCCTT +TCCCGGGTCCCGCCTTCCCTTTCTAGGGCTATGGCTGCTTGTGGACAAGCGTCTCACGGG +TAGGAAACGGGACCTCTGAGAGCTCCTGGCCTGGCTGGGTCCTCAGCATGTGGGTCTGTG +AGCCAGGTCCACGCCAGGCAAGGGTTTTTACCTCTCTGAGCCTCGGTTTCCTCGTCTGTA +AAAATCAGTGAGGGGATGTCTCCTTGTTGCACACACAGCAGGACTGAGATTAGAGCCACA +GCCTGCCCCACCCCAGCCCCTGGTCAGGTGGGGGTGCTGCCATCTCCCAGCAGCCTGCCC +AGGCCCCTCCCTCACCTGTTCCGAGACTTCCTGGCCCCACATGGGCACCCGGCATCCTTG +TGGGCTCACCACAGCCTGATGCTGCCCACAGCCCATCTGTGTGGCCTGGCAGGGGGCCCC +ACAGCTTGGAAATGCCGGTATCTCCTTGCAGACCCCAGGTCAACACTGTAGATTCCTCCC +TCTTCTGTCATGGACCCCAGGAAGGAGGGTGGGTGGGGCCCTGGGCTGGTGCACCGCCCC +AGAAGCCCTCAGCTCCTGGCAGGACCCCCCTCCCCCTGCAGGCCCTCCCCTGGGAGCAGC +TGCTTCCCTGTTCATTCCAGGCTGGGTGGGGACCCCCAGGATGGCCCTTTCTCTGCTGTC +TGTGGGCCTAGGGTGGGGTGGCCCTGGCCAGGCCCTGTATGGCCTCCCAGGCTTCCCCTT +CACCCACTCGTTGTGGGCATGTGACACATTCATTCTAACTACAAACTGACACCCACTCAC +TGAGGGCATTGAAAAACCGGAGAGCCCCAGGAGCCAGGTCACGTGGTGACCCCGACAGAG +ACACCCCACAAGGGTGTCCCAGCCAGGTAGAGTGGCCCTGGGTTGGGGAGGCTTTTAGGT +TGGATGCTTGGTTAGGCACCTGCCAGGTGAACCTCAGCTGGGGGCAGAGAACCTGGGGCC +AAAATCTGGGGGCCGTGGTCCTGGGGCGCTTCCCTGGGCCCCACTGCAGGCACATGCCCT +CCCACCACGCGGGGGAGCTCCCCCTGCCCGTGAGCCCTGCTTGCACTTCCTCACCCGTCC +TCACCCTGCCCCAGCCTCCAGCCCGCCCTGGAGCAGGCTCTGTCCCTCAGGCCCTCTTGG +CCATGGGGTCAGCCTGGTGCCTGCTATTTTGCCCTCAGGACCCCTTTCTCCTGACCCCTG +CCAGGAGCCCTCAGCATTCACTGAGTTTTGGAGGAGCTCCCTAAACACAGCTGTGTTCAC +TCTGGAAGGCTGAGATGTGGGGGCAGGTGCGGGTGGGGTAATGATGTTGGGTGGGCTGGC +AGTGGAGCCAGAGAAGGCCCTCCCAGGACGAGGGCGCAGGGGGCTGGAGGGGAGGGCACT +CGGGCCCTGCTTGAGATTGAACTCAGTTACTGAGCAGCCAGTCTGCCAAAGTCTGATCTC +CCGGCTTTCATTCTACATTAAAAATTGATCTGAGATGGGAGAAGTGAAGGCAGTGGCCAT +GCCACCGAGAAACACTAGCTGTTCTCTGAGGCTGCTGGAGACACAGCCTCCTCCAGGAAG +GCTCCCAGAGGCAGCTCCAGACCACCAGGCCCGCTTCCTCCATGCTCATCTGCCCCACGC +TTGCCTCAGACTCCTGGCAGATCACTAACCCCTCTGAGCCCCCAGCCAGGCCTGGATGGG +TTTGTGTTTGCATGAGGAGGCCCTGGTCCTCACAGGCTCCCCCTGTAGCCAGGGCAGTCC +ATCTCATCCTCACCCCCGTCCACTCTGCCGGGGCTCCTCTGTCCCTGAGTTCTGCCTGAG +GGGCTGAACCACCAGCCTCGGGGCGGGGGAAGCCCACTGCACACCACCTCCCTGACATCC +CGGGACATCTTGCAGAGAAGGAAACTGAGGCTTAAGAGAGGAAACAGTGTCTGCACAGGG +CACAAAGCCACAGAGCCGCCTTCTGCACAGCTCCCACCTGCACCTGCGTCTCCAGGGGAG +CTGGGATTTTCCAGGAGTAGGTCCTCAACTCTTGGGCATGTGGCTGGGCCCTTCCCGACC +CTCAGAGGAGAGCAGGAGCCACGGGACAGGAGTAGACATGAAGAAGCCTCCACAGGGTTG +GGCTTGCCCAGGGCAGCCTGTGGCCAGCGCTGGGGGTCACGGCCCCAGTGGCCTTCCGAG +GGAATGGACAGGTCTGCCCCATCTCTCGCCTTGGCTCAGGCTCTGTGTGTGCTCACTCAA +TGCAGCCGCCAGCTGCTGCTCCCCCACGGGGTCTCGCTCACTGCATGCGGGCTCTGCTGC +TGCTGTCGGTCCTTGGCCTTGAGAATTCCTCTCTGGGAATGCGTGTTTCTCTCTGTGAAC +ATGTTTTGCCTTCTACAGGCCTCCTTAGCCTCATCAGAGACTCCTGAAATGAGTTTCCCG +GTCCTGTGTGGGCCAGGGGCCACCCGCCTCTCCAGACCCCCAGGGCCCATAGTGGCCTGT +CCTTTTGTCCTGCGGCCTCGGGCCCCTGGGGTGTGTGGGGGGGTTTCCTGTCCTTCCCCT +GAGCCCTGGGGCACGGGGACCCCTGGGTGGATGCCCCTCATCCTCATCCAGTGCGCTTGC +TGCCGGCCCCAGGCCCCCCGCGAGGGGCCCTATGGAGTCGAGACAGGAGCCCACCTATAG +GCCCTGTGTGGCCTGGAAGGTGGGGATGCCAGGGGAGCTCTCCTGCAACACCCCTGACTT +CCAGACTCCCCTGAGGGAGGGACTTCCACAGGGAAATTAACCCCGGACGAGCTTGGTTCC +CAGGAACTCACTTCGAGCCTCCAGGAAACAAACAGCCCCAGAGGGCAGGACACTCGGTGT +CCGAGGCACAGGAGTGAGCAGGGTCTCCTGGGCACCGGTGACCTCCACCAGCTCATCCTT +TGTCCACACCTGGGTGGGCTGTCCCTGGCGGGCTCTCAGGGTAGAGGCGGGGGCTGGGTG +GGGGCAGAGCAGGTGCAGAGGCTGGTGAGGCCTGCTGGGTGGGAGGTGGGGGTGACCGCT +CTCTGGCTGCCTTGACTCCATTCATCAGCCTGCAGACCCCCCTCTCCAACCCCCAGTCTT +TGAAGCCACAATAAATATTGATTTGGGCAAATCGATGCATTTCCGAGGGCCTGGGTCGAT +AGCAAAGTTACAAGGATCCGGGCAAAGTCATTCACGTGCCCAACTCCAGCTCTGAGAAGA +GCCTGGCTAGAGCTAAAAGGTGACTGGCCATGTCCCGGGTGCCAGTGCCACCAGCTGGGC +TACCCCAAGGGATGGGCAGTGTGGCCCCTCACTCTCACCTGGCCACAGCCAAGCTGGGGT +TGACCGTCAGAGTCCGGCTGCCTGTCTCTGCGTCTCCCCGTGTCTGCCCCCTGCCCAGCT +CCTGGCTGCATGGCTGCCTCTCCCCGTCCTGTCTGGGTGTCTTCCCGCCTGGATCCCAGA +CACTCTTATGGGGCGCTTGGCACTGGGATCTGAGCAGTTCTGCACATGGTAACCACGGGT +CCAGGGTAGAGCTGAGGGCCCTCATGCGACGCCTCCCTCGGGCTCTCACAGTGGCCCCTG +CCCCTAGATGGGAACTCATTGCTTCCTAAGCTGCCTCTTCCATCTCCACCCGCAGCAGTG +CCTCACCCTGACCCTGGGCCACAGAGGGGACATCTCCCCAAATGCACACACCAGCCTTGG +CCTGCTTAAGGTCACCTGGCCATCTCCCCGCTCTGGCCTCAGCCTCTGTGTTTCTGCTGT +CTTCTCTGACTCCCCGTGGGGTCTGTGGAGACCTGACCACTGCGGCCCCACCTGGGTGCT +GTTTCGCACGTGGCTCCCTCTGCTCTGTCCACCGTCCACAGTTCAGCCCTTCATCCAAGC +CCCCCAAGTGCCTGAACTGCCCTCTCTAGAGGGCAAGGCTGGGGCCCAGGACCCTGGGAG +GAGGTGCCTGTCCTCTGAGTCCTCCTAAGCCAGAGGCTGGGCAGGGATGCGCTCAAGGGC +GGTGGGCATCTGGGCTGAGCCCTGCACCCTCTTTTCTCCTGACATCCCTTGCCTCCCCCC +ACCCCGCCTGGTCTCCCTCCCTCTCTAATCATTTCTCATGGCTCCAACCCACTCTGCCTT +TCTTCCTCTCCTCGAACTACAAGGCTGGGTCTGGTGCACTCTGGTGGGGCCACCTTATTT +ATGAGAATTTGGGAAATGCAGATGTGATGTTTCCAGCTAATAGCCCCAAATCACTTGCAC +CGCCCCATTAGCGGGGAAACCAGCCTGTGTACATTACATACCACCTAAGTGGGAGCCGAG +ACAGCGGTTTTATGACCCCATAAAACTTTGGGAGTTTATTGCTATTGAACAAACATGTAA +TCCGATGCTTCAAGTTCAATATATATAGCCAGCAGCATCTAGAGCCAACCATGGCCGTGG +CTCCTACAGCTGGGCCAAGCTGCTGAGACATCTAGGGGATTTGGAGCCGATTGGCAATTG +ATCTGCTGTAGGACAGGGGCAGGATTTATGGTGGCCTTGCAGGGCTGGTCCTTCTGCATA +CTAAACAGTCCAGAGGACAGCAAGGGGAGGGCAGCCGCCTGGAGCCCAGGGCAAGTGGCT +GCTTGTGGGTTGCTGGGGCAGAGCCTTTAGCAAAGGGGTATCCACCTTGAGGACCTGCCC +CTGTAAAAACCCAGCTTCCTTGGAGACTCAGCTGCGGTGGGAGCCATGCAGAAAGTGGCC +CTGTGGCTGTGTGCCCTGCCCTTCAAGAGGCACCATTGCCTCCTGAAGCCTGTTTCCTTG +TCTGCAAGATGTCCCAGGATGGTTTGTTGCCCAAGAGGTGGCCCAGCAGAGCTCCTGGAA +GGAAGGGGCAAACACACAGGCCAGAGCAGCGGTCAAATGGCTAAGCCTTATCCACCAGAG +CCCCTCACCCAGCTCCCATTCATCCACTGTCCACCATCCATTCATCTAAACACCCATCTA +TCTAACCATCCATCCTTCTACCCATTGATCCTTTCACCCATCCACCTGCCACTGATTTAT +CCATCCATCCCTCCACCCATATACCTATCCATCCATCCATCCATCCATCCATCCTTTCAT +TCATCCATCCACCTGCCCATCCACCTGCTCACCCATCCATTCATGTGTCCATCCATCTAT +CCATCCATTTACTCACCTGTCCATCTCTCTATTCATCCACTCACTCATCCATGCATCTAT +CCACCCATCTGCTAGTCCATCTGCTCATCCGTCCATCCACTCATCTATCCATTCATCCAT +CCCTCCCACCATTCATTCCTCTATTTGTCCACCTGTCCACCTACCATTCATCCACATAGC +CATCTCTCTATGCACCCATCTGTTCATCCCCCATCTACTCACCCATCCATTTTCACCTAC +TCACTGTCCATCCACCCACCTGTCCATTCACCCACCTATCTGCCCATATACTTGTGTGTC +TGTTCACTCATTCATTCACCCTCCATTCATCTGCCCATATACTTGTATGTCTGTTCACTC +ATTCATTCACCCTCCATCCATCTGCCCATCTGGCCTTCTATCCTTTCCCTCAAAGCTGCC +CCTTGTCCAGGGACAGGGCTGTCCTTATAGTCGCAGAGATGATTGGAGCCTGAGAGAGCC +AAGGTGACTTATCTCACCTTGCAGAAGGTGCTGGCATTATTGCTTGCTCAGGACACCCGC +ATCCTCTTGCCCTGGGCTTCACACTCCAGGAATGCCTTTCTCATGTCTGTGCTGCATATA +CTTATTGTAAGTAAAGGAGAACCTCATGGCCGATGATAGTTTGTTCATTTCCTCCCAGTC +TTATTGTGTGCACCTATTCTTTCTTCCAAGTTCACAGTCTCTCTGGGCTTGTATGGCGTG +CATTTCACTCACCACAGATGTCTCTTCGGGGCTGGTCCATGGTGTTACTCTCCCAGCATT +GACTTAAACATTTCCCCACTGTTGGATAGTGTAGCTGTTTCCACCTCTTTGTGGTTATAA +ATATGCTGTGGTCATTATCTGAGCTGGCAGAGTGAAGTCCGCCCCTCTACGTGTTTAATT +AGCATAGACTCCAAGAGGGGGCATTCATGGGTTAAGCATCTCATGACTTGGGACACCCCT +TGTCCGATGACAAAAACCTGGCCCTGTGATCCCTGCCCTCAGTGGAGGAGGGAGGGCCTT +CCGTGGTGCCCGGCCGGAGGGGCTGGGATGTGTTCACTGTGAGTCTGGTGGGTCTCACAT +GTAGGCAGAGTGGGGACAAGGCAGCCTGCTCTGTGGCGTGTCCCATGGCGTCCGGGTTGC +CTTGTCTGCAGTTCACTCACATTGCCCTTGGTGTTGCTGCTTCAGATAAGTTCCTGCCGT +GTTAATGCTATTAATTTTTTGTCATGTTAGTGTCAAAAATTTACCCGCCTCATTTCTTGT +CTTTTAGCTTGATGTTTTCCTTTGAGCCACCTGAGAATTTAGCTTCCACACAGTCAAAGT +GAACTCATCCTTCCCTTTATTCTTGGAAAGTTCCTTCTCACCAGGGATTCGGTAAATATT +TGCTTCTGTTTACTTCCTGTTCCTTTCAATGGTTTAAGTTATTTTCTGTCAGCATCAACT +TATTCCCCAGCCCATATCCGCAGGCCTCACACTCTAATTAAGAGGATGCCCTATGGCCGG +GCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTAGGAGCCCGAGGCAGGCTGATCACTT +GAGGTCAGGAGTTGGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT +ACAAAAATTAGCCGGGCATGGTGGTGTGTGCCTGTGATCCCAGCTACTCAGGAGGCTGAG +GTAGGAGAATTGCTTGAACCTGGGAGGTGGAGATTGCAGGGAGCCGAGATCATGCCATCG +CACTCCAGCCTGGGCAACAGAGTGAGACTCTGTCTCAAAAAAAAAAAAAAAGTAAAAAAT +AAGAGGACACCCTGTGTCCCTCCCTCTCTCCCTCCCTACCCTTCCTTCCTTCCTTCCTTC +CTTCCTTCCTTCCTTCCTTCCCTCTTCCCTCCCTCCCTCCCTCCCTTCCTTCCTCCCTTT +CTGCCTAAACTTTTCTCAATAGCCTCAAGGCTGCAAATAAGACCTGCCCCTGGCCTCAGT +GACTTGGTGGCACAGACGTGCAAAGCACAGAACGCAGAAATTCAAGTCAGGGCTGAGGAC +TGGGGGTGGATGGGGGCCTGCTGGGGGGCTGGGGGAGAGAGTGGCAGGGTGAGCTGGGGA +CATTGGAAAACTCTTGCAGCTGTGACTGATGATGGTGGGCAGGTGTAAGGGGTGGCTTTT +CGGGGGAGGCACATTTTGGCACTGGGTTATGTGCTTCAGCACCAGGAGCAGGGGTGAGGT +AGCAGACGGAGGGGAGGAGGCCATACACCTGGGCAGGGGCTGGATGGGACTGGCTGACAG +CTGACCTCCCTCCTGTGCCCAGAGAGCCACAGCCTGCTCGGTGGCCCGCATGGGATGAAA +CCTTTGTGGTCCCAGCTTCTGATCACTGGAGGTGAGAACTAGTTTTTGAGAGACGGGAGC +AACTGCTGAAGACCCAGGGGCTGGGGCACGGCCCAGCGTTTGCTTTTGAGAGCTTCGCCA +TGGCCCGTGTGGAGAGGACAGCAACCACCAGGGAGGGGGCTGGGTGCCCCAGCCTGTCTG +CCAGCTTCTGAGCCCCACCTGCGTCTGCACCTACTGGAGACAGCTGGGTGGGCTCTAACC +TGGATGGTCCTGGGTGGGAATCCCAGCTCTGCCTCATGTGAGATGAGGGCTGAGCCTCTG +CTCATCTTAGAACCTCAGTTTTGTCACCCATACAATGGGATGGTCAGTTAGCAAGGAAAC +GCGTGTAGGTGCCCCGTGTAGTGCCGGCTGCCTGGGAGGCGCTCCCAGAATGTTTCAGAG +GTGATTCTTCTCAAGGACTTCCTGGGCCCCTTGGTCATAAGGCTCTGAATTCCCAGCCTC +TGGCCTGAGTGCCACAGACCCTAGAGGGTTCCTGGCCACTCCTGGGGTCTGTGTGGACCT +CGCTGCTTAAGGCCCCCCGTGTGCACTGAAGCGCGACACCCCGCACGCAGGGGCCATCAG +GTCTTTGGGGATTGATAGAATTAAGCCCATGGAACGTGCATTTGCTTGCTGTGAAGCCGC +AACAATCTCGCTGCCACAGGGCAGAGGACGTTCTGAACTGAGTGTCCCCTCGGCTCCCTC +ACCGGCCTCCTGCACCAGCAGATGGTGCCTGATGTGGTGGCTGGCACTGGTGCCCCTTGC +CCTCTGAGCAGCGGTACCATCAAAACCCATCTTCCCAGCAGCTCAGGATCACCGCGGTGG +AGTTTCCAGTCGCAGATGCCCTTGGCAGGGGCTGTGGGACTGCAGGGGAGACGGAGGTCT +GGGCCCTACCATGTGGGGGCAGCATGCAGGAGGGGCCCATTCCTGCCCCCCGGCAATACA +AGAAGCCTACGGGGGTGCCCAGGGGTCAGGGACCTGAGAGATGTGCTCACTGAGACCTAG +CATGCTCACCCCCAGCTGCCAGAGGGGGTAGTTCCCAAAGAGGGGCAGGCCCTCAGAGTG +AGCTCCTGTCCTGAGATGGGCAAGGGAATATTCCTGGGACACTGCAGAACTGTTACCAAG +CCAGGCACAGATGGGGCCAGGCCCCTCGGCCTCTAAGACAAGGCCGGCCCATGGATGGAG +CACGATGGCCCTGACCTTGGGCACAGACCCGACGATTGAGTGAGATGGAGACACAGGCTT +GGCTTGTCCCCAAGAAGAAAGAGGCACAGAAGCAGCTACAGAGTTTCTTGCTTCCCTGTT +TGGGTTGCTGCTGGCTCAGGTACCACAGCTGGCAACAGAAACAGAGGTCAAGGCCCAGAG +GGAGGGAGGGGTCGGGTCTGCTTTGTCCAGGGCTGGCTGGCCCCAGGAGGGCCCCGAAGC +TGTGGCAGAAGCAGGTACCAGATGGTCAGTGTAGCACTGTGGCTAGCACCCAAAACTGGA +CATGGGCTGGGAGCAGCCTGAGATGCAGGGCAGAGGACAGCAAGCCACGAGTCTGAATGG +CCCCTGTTCTGGAGGCAGTGCTGGGAGGTGGAGGCTGGAGGGGGTGTCTCGCAGAGCCTG +GTCTGCTGAGACATAGGCTGGGACAGGCTGCTGGGTGTACTGTCCCTGGGAAGTGCAAGG +TGGCGAGTCAGGAAGGCCCCAGGAGCAGGGTTGGGGCAGGAGCCAGTGAGCAGGGCAGGA +CCCTCATCTGGAGGGGCTGGGGGAGGTCTCCAGTCTGGGATGGGGGTGTTCCCGGCACCA +GCCCAGTGTTTCTGGTGCAGCAGCCACGTCATTATGGTTGGAATGTGACCCCATTAGCCC +TGGGGCGGGGCTGTTCAACATCCTGAGGATAATTGATCAGAGGGAGGAGGGGCTGCACCG +CTTCCTAGCAGGTTGAGTTAATTATCAGCCTGCATTAGCACTTGACCTGTGGCATGTGTC +AACTCATTACTGCTAATTGCAGGGACTCAGTGACCTCTCCGAACTTCTGTCACCCCTGTC +ACGGCCCCTGCCCTGTGGAGGCCTGTGGAATGGGAAGTGGGGAGGGGAAGGAGAAGGGGG +CGGAGTCAGCCGGAGCCTCCTGGCCAGGCCTGGAGTCACCCTGTCCTGCCACAGCTCTCA +TGGGTTTAGAGTGGGCCCTGGGGCAGAGGGTTTGCAAGGATAGGGGTGGGTGGCTCTGCC +GAGGGCGGTGTTCTGAGTAGGTCTCATTCCCCAGTCTGCCCAGCCTGGCCCCACCCCAGC +TCTGCTGCCCTGTTACTTTGTCCCCCTGTGTTCACCCTCCACTTCCTGCCGGGGACACTC +CAAGGCCTGCCAAGGTTGGAGCAGGGGTGGGACTCAGCCATTCAACAAACGCTTCCTTGG +TTATGCAGGGCTGGGCATTGGGGTGGGGGGCTGACCTGGACCCTCCAAGACATCAGATTG +TCCAACTGCTCAGTTTTCATTGGGGCAAGTGCCTCGCTGAGGGTGAAGGGGGCTGTGAGT +GCCCATCAGGGAGCCTGGACAGGTCCCGCCTCTCACAGCTGTCCCACTCTCTGGAGCTGC +CTTGGTGGCAGATGGCACTGTCCTAGAAAGGTGAGGCTGGAGCTGTCTCTTCCACCAGGG +GTGGCCAAGGACGCTTCCAGGGTCTTCCATGCAGGCCTCCAGGGTCACCCTGGGCGTGGC +TGAGGGCATGCAGACCACGCTGTGCTCCCCCCCACCCCCCATGCCCGTCGCTTGCCTGAC +ATGCTCCTCAGCTGTCTTGCCCCGCAGAAGCTGTGTGGTCTCCCCTGTGAGTAGAGTCGG +GCTCCATGATCCTCCGGAGCAGCGCCAGGGACTCTCCCCAGGCACAATTTTAAAGGGGGC +CCTAGGACCTGCCAGGTCCACGGAAGTGGTCCTTGTAACTCTCTCCCTGGTGGCAGCCTC +TGGTGCATTCCGGCAGGGGCAGCCCCTCCTCATCACAGGGACCCTGTGTGCCAGGCCCCA +GCTGCGTTGCCGCTGAATTATGGATTTAATAGCAGAGAAGCCTTGCAGGCCGCCTGTGCT +GGCTCGGGAAACCGGGGCCCAGCCGGGGCCTGTCACGGTCCTGGTGCCGCCCTGCTTCCT +GTCGGCGCCACGGAGCAAGCGGAGAGATTTATCTTCCCGGCTTTAAGAGGTACTAACGGA +GGAGGCTGAGAGGCAGGAGCTGAATAATTGATGGCCTTCTCTGGCTCAGGATCTGCTGAA +AATGACACGGTGCAAGGCAGAGGGGCTGAGAGTGCTGACCACAAAATGCTGAGAAGCCAC +TCCAGGGCGGTCACGGCCAGAAGGAGGACCCCCACTCAGGACGGGGTCACAGGCATTTGG +GGCGGGTGTCAGAGGCTCCTGCCCTGGGTCATTCCAGGGGGCCAGGATACCCAGAAGCTG +GGCCTAGAGGCCCACAGGGCTGGCTCACCCCCACTTCCCTCTCACACGCCTGCCATCACC +GGTGCTTCAGCCCAGCAACCCCATGGCTCGTTGGCCCCGTCCACAGCCCCCACTGCCTCC +TGTGTGCTGGGCGTGGGCCTCTGAGCTCTACTCTCAGCCTCCTTAGCCCCAGGAGAGGAG +TGGAGGACAGGGGTTTAACGTGGGGTGTGGTGCGGAGCGGGGAGGGCTGTGGCGCCCCCT +CAGCCCCTCCTTTCCTAACAGCCTCAGCCTCCCCCCTGGAGAATCCCCTACCTGCTGGGC +ACATCTGGCCTCTCCCCACCATTCTGTCTCCAGCCGGGAGATCTCTACCCAGTGAAACAG +TGAAACAGGAAGGGTTCCCTGGTTACCCCGCGCAGGGCGCAGGGCATGCAGCGGGGGAGT +GGCTCGCTTCTTCAGTGCCCCACCGCTCACACCTCTAGGGGAGCATACAGACGGGCAGGC +TGTGGGGCTCTGACCCCATGGCAGTGTCTGGGGGTGAATGTTTACAGCTCTTGAAACCCC +AGTGGGAGTGCGTTACCGGGTGGTCTTTTAGTCTAGCGGTCTGTAGGTGGCTGGTGAGAG +TGAGCTCAATTAGACCCCTGCCTTATAACAAGGACAGAGGAATTTCTGTATCCCAGGGTT +TCTTGCCTTGGTGTACCAAAAAATTGGATCACACGTGGGCTTGGAGAATGAGTGCAAGGT +TTTATTGAGTGGAAGTAGCTCTCAGCAGATGGGGGAGCCAGAGGGGAGATGGTTTTCCCC +TGGAGTCAGGCAACATTCTCGGGATGTCCAGCAGCTTGTCTTCTTCCACCAGTGTGTTCC +TCTCCCCACACAGAGGCTTCTGTCTCTGCCTTGCTAGGGTCTTGGGTTTTTATAGGCATA +GGATGGAGGCATGGCAGGCCAGGGTGGTCTTGGGAAATGCAACATTTGGGCAGGAAATGC +CTGTCCTCACCTAGGTTCGTGGGGGTGGAGCCCTAGGCAGGGACCACGCCCTTCTCTACG +GAGCACTTCCCGTCCCTCCTCTGTATCATTTAAAGGGACCACGCTTTTCCCTTCTCAGCA +CTTCCTTTCCGTATCAACAGGAGGCCAGGGACTGGCTGGACCCCTAGGAGCCAGGTCCTA +CGGATAGGTGAGCCGGCCCCCCAGGGCAAACACCTCCACTGGGCAGACCTGACTGCCCAG +AGCTGGATTCTTTACTTGTAAAAGGGGCCATGAGTGACACAGGCTCGGCCTGCTGTGCCT +TGAGGAAAGGAGAGGCTAAAAATTCTGCCTTCTCTCCTAAAGCCAGCCGGGCTCTTTATG +GTGGGGGAAGGAAGGATTTGTTTATTTGCACTCTTCTGAAATAAAAGTTCTCTATCCTCC +CTCCTGGCTGGAGTTGGGAGGGCCCCATGGGTGGGCTCTGAGATGTGGCACACGGTACCC +AGGGCAGGGCTGGGAAGGGTGGGGTGCAGGGGCCTCCCTGGCTGCAGGGCCCACCCACCA +GGTGCCTGGGCTTGCTGCACTGAGCAGGCATGGGCTCTGGCCCCCCTCACTGTCCCTTCC +AGGCCCAGCCTGTGTTCAGGGCCCAGGACAGGGTCTGGCCAGCAGGCCCCAGGCCTCCAA +GATGTTCTCAGCCTCTGGAGTGTGTGTGATGATGAGCACTCATGGAGCTTCCTGTATGCT +GGGCCCTGGGCTTCTGAGAGGGCCACCGGGTGGCGACTGAGTCACGAGGTGGAGGGCCAG +TCCCAGGGACTCCAGGTGACCTCGTGTCGGCACCACGCCCTTCTCCCATGGGCAGTCCTG +GGCGCCCCTTCCTGGCCTTGGGCCCAGTGGCCTGTGGCCTGACCCCGTCCACTCCTGCTT +GGTTGTCCCAGCAGCAGCAGGAGCCCATGCTGGAGAAGGTGTTATGGGGCAGGTGGAGGG +CCCGGCTGACTCAGATGATCCCCCAAGTTTCTTTTCAATGAACACTTGTTTAGTGCAGTT +TTTCCTCCTCAAATCCCCCTCACACAGGCAGACACCCTCTTGGCCCAGGGTAATCTGCTG +AGCCTTTGCTCAAATATAGCAGCTTTGCTGCTTTCTAAACACAACTAATCCAATTTGGGA +TTTGGGGATTCGAGGTGGGCAGCACTGGGCCTCAGATGAGCCCCCATCACCCCAGACCCA +TGCAGGAAGAGCCAGGCAGGGTGGGGCCCTGGGGCCACCTGGTGGGCTCAGGGCCAGGGC +ATCGCGATGTCCCCATCCTTCACACTACGGGGCTTCCTGGCTGCAGAGTTGGGGACTCAG +CTGGGAATGCTGGCCATAGAGGCAGAGAGCCCCCATCCTGCTGGGCCAGCCCTGACCTGG +CTTCTCCAGGGTGGCCCAGTGTCCCCTTCTGCCCTTCCCCTGGCTCCCACCGTCCACATC +CCTCTATCTGCCCACCCTGGACAACAACCAGCACAGTGCAGTGTGGCCCTGCAGTGACAC +CACCTGCAGAGAGGTCAGGCCCAGCCTCCCCCGTCTCCTAAAAGGCCAGCAGGTCCCAGG +AGCTGGGGGTGGGGCCTGGCTGTGGGGCCTCCATGCCCCAGGGGCCAGGGCAGACCCTCC +TTAGCCGGCAACCACTGCAGATTCCTCCCCTGGCCAGCACTCGGGGACCTCCCTGCCCCT +GCCCCGTCCCCCTACCTTGCCTGCTGAGACATAGGGCTCCACGGGTCTCTCTCCTGGGGC +CGGGCTGACTGTGGCCTGCGAGGGGCAGTCATCGTGTTGGGTTTTCCTGCCAGAGGCAGA +AACCACAAAATTACCTGGAACATACACGCCCCAAGTGACAGATTCAATTCAATTCCACAA +ATATTGACCTCGCGTCTAATCCACTCGTCCTCCAGTGCCAGCTCATTCCTGAGAAGCCCA +GCCTGGCAGCCGCAGATCCCATTTAATCCCAGCCCCACAATGTCACCAGCTCGCAGCTTG +GGAGCTGGGCTCATCCAGGCCCTGGCAGGTGGGGCCAGAGCTGGGCTCTGACCTCTGTAC +CCACACTTACCACCATGTAAAGTGCTGGGAAGAGGGGTGGGGAGTCACGGCAAGTTGAGG +GTCCAGGCTTGCCCCAGCTCGCCAGATGCTCGCCCTGGCTGCCCTGACCTAGCAGCTAAT +CTCTGCGGGGCACTGCGGCTACATGGTGACTCCAGCACGGGGACATTTATCAGAAATGGA +ACTGATGGATTAAAGTGGAACCAAGCGAATTGATTTTTCTCCCTGGGCACTGAAATGCTG +CGCTTAATCAAGCGATCAACTCCGTGGGCAGGGTGGCTGTGGGGACGGAGGTGGGGGACA +AGGGGATGGTGGCCATGGTGGGGACTGAAAGGTGGCTATGGGGACAGATGAGGTGAGCCA +GGTGGCCCTGGGGTCGAGCTCCAGCCCAGCCTCTGGCAAAGAGGCCCTGTGTGCAGAAGT +CCGGGTGTGATGCCCTCCCCCCACCGATTGTGTGATACCGGCCAGTCCTGTCCCGGCTGA +GCCTCGGTGGCCTTGATGTAACCCTGTGGGGTCTGGTGGCAGGGACTGATTCACTCATTT +GCTCATTCATTCATGTGTTTGACACACACTGCAGCAAAGGAAAGGTGAGAGCAGCCACAG +GCTGGCCAGGGACGATTCAGACTTCAGAGTGTAGCGTGCCCGCCCCTCCTCTTGTGAGGT +CCAGCCTTGGTGTGTGTGGATTCCCAGGCACCCTCCAGGTCCACCCTCCACTCTGCAGTG +CCCCGCCCACCTGTCCACATACTCTGTTCTGTGGTTTGATCGCCATCCTTCTGCTCTGCG +GCCAACTGGATGGCCCAAGCGGACTGAGTTGGGCAGGGTGGTCATACCTGTGGAGCCTGT +GGCTGTGGTTGGAGGCCCCGTGGGCAGCTGAGGCAGCCTGGGTGGGCATGTCCCACTGGG +ACTTAAGCCCCTAGGTGGGCTGTCCGAAGTGACTCCTGAGTGGCTGGGGTGTGCTGTCCT +TCCAGCCTGGCCGTGGTGGCTGGGTGGTGTTGGAAGGCACTGAAGGAAGGGCAGGTGAAT +TCGTGCTGGACCTGGTCTCAGTGCCATGGGCCCCAGGAGCCCATGACATCACTGGCCTCA +TGGACTGTGGGGATTAACCCTGTCACTGGACACCCCCAACACACCCCCTCCAAAAGAAAG +GTGTTGGCACAAGTGAAACCCCTTGAGTGATGGCTGGGATTTCAAGCTCCAGACTGGTCC +CCACTAGGAAGCTCTGGGTCTGGCTGGTGGAGCAATGTGTACCCGCGCCTCTGCGTCTCC +CTGCATCTGGCAGCCCTCCCAACAGGGCTCATGTGGGGTGCAGTGAAGCAGCAAAGCCCC +CCACCCCACCCCACCCCAGACTAAACACAGGCTGTAGACCTGGCCCAGGGTGAGAAGGGC +CCCTGTGGACCACCTACCCAGGTGGTCTGTGGCAGCCTCTCCCAGCTTTCGGTCCAGGTG +GCCCAGGGAGGTGGCAGCCCTGACCCTTCCTGGCGATACCCTGATTGATCATAGTGAAAC +ACTGAGCTGGGAGAGCCAGGGGCACCCAGGGCTGAGCTCCCGGGGCAGCTCCCAGGAGCT +GCAAGTGGACCTGGCACTAGGAAGGAGCAGTCCACCGAGCACCTAGGCCAGGGCCCGGGA +CGGTGCCAGGCACCAGCTGAGGCCCTGCCAGGCCAGCCGCATCTTCACATTCAAGACCCC +AGGCCCCAGCCACGGCTCTGAGCTCTGGGTGTCTGCAGCCACGGTTGGCAGGGTGGGCCC +CACCTTGCCCTGACTGGGCCACGGACTGGTGTGAAGAGCTCTAAATTTCACTTACTCCCC +CAAAGTAGAAGTGGCCTAGGACTGTGTGGTGGCTCCTGGTCTCCAGAACCCTGCCAGGCT +CCAGGGCAAGCAGGGAAGTCAGGCTTAGCTGCAGGGCAGCACCTGTCTGCACACCCCGTC +CTGCCACGCTCCCTGCAGGGACCTCCGCCTGTTGTCCATGGTCCAGCTTGCTGGATGGGG +CAGCAGCTCCTACACTCAGAGCTCTGCCATCCCCAGCCCCAGGCCAGGCTCTCCCCACAG +CCCGTTAGGCCCTGACGTCCCCTGACAACCAGGAGTTGGACAGGCCTGGCCCCCAGGCTG +CCCCACACTGCCATGAGGACCCCAGCTGGCTGAGTCCCATGTCCAGGCTCACTTCCTCTG +TCCCTGCAGCAGTGAGCACCTGGGACCATCATGGTGAGCACCACCCACCTTGCCCCTTGG +CCCATACTCGGGGACCTGGGTTCCCCAGGTGATCAGGGTGGCCTGCAGGGCCTGAGGTGG +CCATGCCAGCCAAACTCCCCCTGCCCCACAACTGGGTCACCTCTTCACCCTCCCGCAGCC +CTTGGGAACCCAGTGAGCTCCTCCCCCTTGCTGCTTTGTGAGTGCTGGCAGTCCTGGGTT +GCTGTCCTGGAGCTCCAAGACCTCCCTTCTGGAAGGCTGGGGCTTCCTGGTGGAAGATCC +CGCTCACCTCAGCTGTGGCGTGGGCCTGGGCTTCAGCCTGGGGCAGCCCTCATGGGCAAC +TGCTTCAGACTGGACCCCATGTGCTGGGGTGGCCAGGGCTGTGCATGGCAGGTTCAGGGC +ACAGGGTGCAGGCAAGGGTGTGAGGGTGTGGGAGGGCTTCAGTGGGAGGCCCTGATGCTG +AGCAGACACAGTACAGCCTGGTAAACAAGGCTCGTGTGCTGGGCACTCATCGATCTTGGC +CATTCGGGCCTGGCCAACAGCCGGTGGGCTCAGGCCTGGGCGGGGGCTGGGGTGGGAGTG +AGCTGCCTCAGGCTGGGCCGTGGGCACTGCAGGTGGCTTGTCCGGACAGCCCTTTCCCTG +GACCCCTCATGCCCATGGCTCTAGCTGAAAACACAGCTGCTCTTCTCTACAGGCTCGTCC +TGGGGTGAGGAGGGTGTGGGAGCTGCCTAGCCCTTCCTTTCCCAAGGGGTTGGGTGCCCC +TGGCTGAGGAGGAGACCCTCATGGCTGGAACTTGGTGGTGGTCAGAGCCTCCTGGAAGTT +GACCAGCTGAGCTCCAGCAAGTCCATGCCTCCTGGGACACAGCCTGGCCCCGATGAACCC +TCAGCTGCCATCATCCTCAAAGTCGCAGCAGGCTGGATGCTGAAGGCACAGGGGGCCGCA +TGGACTGTGGCTGCAGCTCTCTCATTGTCATGGGGAGGGAATGGCCTGCAGCCCCATCTT +GTTCCCTTCTCTTAACAGCCTCTTTCCAAAGATGGCCCGAGCTCCCATCCCCGCCCCCAC +AGGGCTCTTCCTGCACTTCCCCAGGCATCCTGGGAGGAGAGGTGGGCTGTGGCTGGAATG +TGCCGCCCTCTCACCCTCCTGCCAGGACCACTGTGCTGGCTGCCTTGGTGGCCTGGAGGC +CTGCAGAGCTGCCCAAGCGGGGGCTCCATGCGCAGCTCCCACTCCATGTTCTGTCCCTGG +GGAGGCCCACACAGCACTGCCCCTCTGTCTCATTCCAGGTGCCTGGTCCCCAGCGATCCG +CCTTGACCCCAGATGCTCAGACTTGCTAGCCCAGGGCCAGAGGGGCACAGGACAGGGCTT +TGGAGAGGGGGCTTCCTAGGCTGGTGCTGGCCCAGCCTGCCCAGCCCTGCCCTGCTCGGC +CCCTGCCTGTCTGGGTGCTGGACCTGGCCTGATCCATGAAGCTTCTCCTAGCGAGGTGTT +TTCCAGGCCTTTGGAATCTTAGGGATGATTTCGTATGGGGAGGGGCCTTCTCCCCAGCCT +GCTGTCTTATTTTTGTGCCGATTCCCCGCAGCCCGAGCTCCTGCCCCCAGCACCTGCCTT +TCCAGCCTGTGTCCTGTCTTCCACCAGCGGACTCCAGCCTGGCTCCCACTGCCACGTGGC +TGCCTGGCGCATGCTCCACCCCGTGTCCTCCCAGGGTCCCAGTGAGGGCCCAGCCCCGCA +GTGCGCAGTCTCCGCAGCCATCGAGTAGGCGGCCAGCTGAGCAGAGGTGCTGGCCGGCTG +CCAGCCCAGCACCCGTCCTGCTGAAGTTGCTCCTGGCACGCTTCCGGCCCCAGGCTTCCC +TGGGTGGTGGGGCAGACTTTGTGTTGCTGGTGTGCAGGAAGGGCCCACGACCCCCACCCA +ACATGTGAGAGGGGCATTTGGCAGCCATGGGCAGGACACCACCTTCGACCATCAGCTAGG +GGTATGTGCAAAGGGCCTGAGTGAGAAACAAAAGACAAAATGGACCAAATGTGCTTGTGT +GGCCGGGTGTGTGAATTGTGTGCAGGTGAGTGTGGAAAGATGTGTGAGCACAAGCCTGTC +AGCATACACGTGTGGGCGTGGGCATGTGGGTGAGCATGCAAGTGTGTATACATAAGTGAG +TGAGCACGTGTGTGTGGACGTGCATGTTATGTGGATGTGCATGTGTGCATATGAGTGTGT +GAGTGCATGTTTGATGAGCATGTATGTGTGGGCACACGTGTGTGTGTCAGCGTGTGCTGA +CTGCCATGGACGTGCACCTGGCTGAGTGTGGAAATGTGTGTGTGAGTGTACTGGCAGTCC +AGGTTTTACACCCACACGGCTTTGCCTCCCCAGGAATCCGTTTTAATAGCAGAGTGGGCT +GGAAGGGCTGGCCAGGCCCTGAGGCAGTTTTCAGGCCAGCAGTCCCTGGCTCCTCATATG +CGGTGACAGCCCAGGAGGCCGGGGCCCTCAGAGTGCAGTCTTTGGACATGCCTGGTTGAT +GGATCCGTCATTACCAGCCTGGGAGCTGGGCATGGGCTCCGGGGCTGGAGGACACCCCTT +TCCATCCCTGGCCCTGGCGAGCCCGGCCCTCCTCTCGCCCCGTGATAACCTGCAGCCTCA +TGGGGAAAGGCACGCGGAGGTGGTGCCGCACCCCCAGCCCTCACCCCTGCTTTGCCAATC +CTGGATCCTGGCCTCCGCCCGCCAAAGTCCACCATTGGCCACAGGATGTGGGTGCTGTGC +TGTGTCCTTGAAAATCTGAAGATGAGGACAGCTCAGTGGGCGGGGGCGTTTCACACATTC +GACACATGCCCTCACGCCTGTGGGTGTGTGGCGGGCTGGTTTACAGTTACGTGAGGATTT +CAGACCCAAAGTGCAGAGCCTGCAGCTGAGCAGTGCCCAGGGAGGGCTGGGGAGGAAGGT +CCCAGCCAGGAAAGTAGGGTGACTCTCATCAGTGGCTGCGGTGTCCAGCTGGGATGATCA +GGGCCGTGCCAGCCTGGTGCGCCTGGGGGACCCACAGCAGAGGTCCTGCATGCACTTGGC +TGGCACGTGTAGTTCTGAAGGCCCCTGGGGAGGCCTGGCACATGCAGTGTTTGGGGACCC +TCTCTGCTGCCTAGACACTGCCACAGACCCCACACCCAACCTTGCTGTTTTTCCCCCAAG +TGAGGGGAGCTGCTTTTTCCAACTCGGATAGCCCCCCTGCACTGTGCAGCTCGCCCACCT +CCCTCACAGCTATTCCAGCATCTCTGGGCGGGTGCGGGAAGCCGGATGCAGCCAGTACCG +TTGCTGTTTTTGGAAAAGAGAGGTTCAAGGCAGGGAGGGCCCAGCCTATGTTCCAGCAGG +GTTGTCTGGCTGGGGGGGTCTGCACCTCGCCCCTGCACCCCCAGGTTCCTGGCTCCCCAC +CCCCGTGCACGAAGCCCTTCTTGCCTGGCAGGCCTGGGGGCCCCCGGCCGCCATGCGCCC +CACCGCGGGTGTGATTTGGCAGCAGCGTTCTCCTCGCCAGCTTGTTTCTCACATAGGGGA +TGTTTCCATTTTTACAGCAGAAAGAAACCGATTCCAAGCGCCTCAGCCACAGCCGGAGCG +CGACGGCCCCCAGGGAGCTGCTGCCACGTCAGGTGCTTTGGGGGTGTGGGCTGCTCTGCC +AGCCGTGGTCCTAATTGCTGTCACTCAGGGAGCCAGCTCTAGCCTGGGGCAGGCAGGAAC +CATGAGGGGGGTCTTCGGGGCAGGCACTGGTCCCTGGCGGAATCCGAACCTCTGCCTGGT +TCTCCTGGCACCCCCTCCCCAGAGACCTGGAGCACCTCCCGACTTTGGGTGGGATGGGCC +TGTGGTTCTGGAACAGGAGCTTTGCCTGTGGGACCCTCCCATGGGGGCGGGGTGTCCTCT +CTTAGCCCAGGTGGGTTTGAGCCCCACACTGCTCCTTCCACCGCTCAGATTCCCGCCTGC +AGGTCCCTGTCACGGGGCTGCTGAGGACCGACCAAGGTGACTGCCCATAGCCCCACGCCA +GCATGGGGCACAGCTGCCTGGCGGCTCTGCCGTCACCCCCCGTGCTCTGACTCTGTGCTG +TGGATTTGTGTCACCTGCAGACTTGGGTGGCATTGGGCACAGGGGCACGGTGTCCTCTGT +CACTTCCCCACCTTGCTTGGGGCTGGTCTCCCAGGATGCTGAAGCATTGAAGTGCCTCGA +GGACTGTTAGAAAGATTTTCTTAGAAAGAAACATTTGCTACCCAGGGCACAGAACAGCTC +CTCGAGGTCTCGTAAACCAGTGTGGACTCGGCCCTGCTCCCGAGACTTGGAGGAAAGGCA +GAAAGGGCGGCAAGTCACACGCAAGGCAATTTTCAAAGAAAAGGGCACAACTCATAGGAG +GCAGGGGAAGGATTCCATTTCACCTACAGTCATGGCCCCGCGTCTTCAGGGAATAGGTGC +TGTCTGGTGCATCACATTATTAGTGCTGGAGGGCATCGCAGTCCTGGGGGAGGTCACTGC +CAGCATGGCAGCCCATAGGAAGTGGGAGGGTGGGATTCAAGGGCAAGGCGGGTGGTGGGT +CCTGGCCCCTGATGAGGCAGGTGGATGGTGGACCTGCCTCCACCCTACCCAGCAGGCTGG +CCACCAGGGCGTGTCCACAGACTCCAGACAAGAAGGAGAGAGTAAATTGAGGCATGTGGG +GCCCAGGCCCTGGGCGCAAGGCTGGAGGCCTGAAGTGGCATCCCATCAGCTGGAATCAGG +ATTGCCTCGATCTTTGATTCTTGAGACAGGAGGAGTGTGGCGGTGGCCCCAGCAGGATCC +CTGAGATCTTACACAGGTGAGGTGGTTGCAGAAGCACTACACGGGGCTGGGGCCTGAGGG +TGCAGTGCTGGGTCTAGGTCTCCCTGAGAGTCCACTGACAGCTGTGGAACCAGGCCTCAG +GGGAGCTGGGTGCAAATCCCACCCCTCCACAGAGCAGCCGTGTGACCCGAGGCTGTTTTG +CCCTCTCTGCCTCAGTTTCTCTCTGGCAGCCGCTCCTCCCTGGGCCCCGACCTGACCCTT +CAGGCTCAGGAGGCTGCTCCAGGTCCAGAACCTGGTGCTGCACTGGGTCCAGCCTCCAGG +CCTTTGCTAATGTTGTGGTCTCTGCCTGTGATAACTCCTGCGAGAGCTCCTGATCTCTTA +TGACCCTCCCCTGCCTGGGCAGATGCTCCTCCTGTCACCGAGGGTCCCATTAGCTGGCAG +CTACCCTGCCACTTGGTGGACCCAGGTGATGTGGGTGGGCCTCACTCTTCATCCACAAGT +GGGTGAGAAAAGGCAGGAAAGGAGGTGAAGCCAAAGATGGCATGCTCCCCCTGCACAGGG +TGACTGTATGGGGGGGTCACGGCGGGGGAGGGAGGGGAGGAGAGTGGTCCATCTAAGGGC +CCTGCCAGGGCCCAATGCAATGTCCCATCCTTAGATCCATCTTCAGTCACATCCCCACGC +TAGGGGGAGCAGCATTTCCAAAACGCCTGCCCTGGGGGCTCTCAGAATTCAGGGGTTCCC +TTTGAGGTCACACAGGCCCCACTGAGGCCAGACACAGCAAGTCCTTGCTCCTTGGCCTAA +GCCTGCAACCCCTGAGCCTCAGTTTCCTGCAGTAAGTGGGACATGATGCCTTTCCACTCC +TCTAGGCTTCTGCCCATCCTGTGTCACCGTCCCAGCAGATGAGTAGCTGGTCTGGTGGCC +TGAGACCTTGCTTCACTGGGGGACAGGGCTGCCATCCTCGAAGGCCAGGGTCTGGGCCTC +TGGGCCGGGAGCTCCTCCATCAGCTTGCAGCCCTGGGGGAGGCTTGCAGCCCTGGAGGCC +ACTCCCTCTAGTGACAGAACCCATACCTCTGGGAACTGCTTCCTCTGCCTGCATGCCCCA +AACTTGGACTTGGAGGTTGTAGATGGCCGTGGCAGGGCCCTTGCCTGGCCCCTATCCTCC +TGCAGCCTGGCCTAGGCATGGGTGACTTACCCAGTGCCAGCAGGCTGCCTCAGCCCGTGC +CCACTAAAAAATTTGTTCCTGGCCGGGCGCAGTGGCTCACGCCTGTGATCCCAGCACTTT +GGGAGGCTGAGGCAGGTGGATCGTCTGAGGTCAGGTGTTTGAGACCAGCCTAACCAACAT +GGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGATGGCAGGCGCCTG +TAATCCCAGCTACTCAGGAAGCTTAGGCAAGAGAATCACTTGAACCTGGGAGGCGGAGGT +TGCAGTGAGCGGAGATTGCGCCGCTGCACTCCATCCTGGACAATAGAGCAAGACTCCGTC +TCAAAAAAAAAAAAATTGTTCCCATGATATTCCAAATACAGTCATATACCATAATGACAT +TTCAGTCAACCATGGGCCGTGTATATAGCGGTGGTTCCATAAGATGAGAATACTGTATTT +TTACTATACCTTTTCTATGTTTAGATACACAATACCACTGTGTTACGATCCCCTACAGTG +TCCAATAGAGTAACACGCTGCACAGGTGTGTAGCCTAGGAGCAAAAGGCCAAACCAAATA +GCCCAGGTGTGTAGTGGGCTCTGCCATCTATGCTTGCTTAAGTTACTCTATGATGTTTGC +ACAATGACGAAATCACCAAACAATGCATTTCTCAGAACATAGCCCCATCATGTAATGGCA +TGAGAGGACACGGGCAGAATTCTTGGATGCCCATTTTGGGGACAGCCACCATAGTTTGGA +CATTAATACATTTGGGCACATGCACATGAGCACACACATGCTCACATGCACATGGATGCA +CACGTATGCGCGTACCACTCACTCCCGGGCACATGCTCATTCCCGGGCACATACACAGTG +GGGCGGGGCAGGAAGGCTGGATGGGGCCCAGGGGAGTCAGGTGCTGTGGTGCGCTGGGGC +TCAGGCCCTTCCAGCATTCAAACAGAGAGTCTCCTAAGAAAGCAGGGAGCCCACAGGGCA +TGGGATTTGGAATCTGAGTCAGGGATTTGAATCCCATCTTGTGCCCTGGGCATGCTAAGT +CTCCCTCCTAGTGCAGTGGGTGCCTGCTGCCCAGGCTGCAGGAGCGTTTGAGGAGGCTTG +TCAGCCTATAGGGAACTGCCTGGCGTCCTGCTCAGTGCTGCAGGCTGCATGAGGGGCCAA +TTGAGGACCCCCTAAGCCCAGGAGGGGCAGAGGCCAGGGACCAGATGCCACAAGTATCTG +TGGGTGGGCTTGGCTGTGATGAGCAGGACAGGGCTCAGCCAATGCCCAGGGGCAGAGCCC +CCGAGGCACTGATGACCACAGTGAGGCCAGCGTCAGGCTCTGGGTCTTGGGTCTTGGTGC +TGCTCCAGGAGTGGACCCACATGGCCCCTCAGATGCTGCTCTGTGACTCCAGGCCTGGGT +CAAGCCGACCTCTCTGCTTGTCCCCCCACCTCCCTCTAGGTAACTAGGCCCCAAGATGTC +ACAGCATCAGAAATACAGAGAAAAAAAAGCATAGTTAATACTGCTCCTGCTGGGAAGGCC +CACAGCAGGGCGGATGGTAGTGCACCCAGCAGGTGTGACAGCCCAGTCTCCCCATCTGCA +GGGAAACCCCATGCCCCCTCAACCCTTACTGCCTGTCACCAGCTGGACCCCGGTCTCTCC +TGGCTGCTGTCTCACCTGCCTTCACATGGTTTCTGGTTCTTTCATCTTTTCATTATAATT +TTTGTTTGGAGAAACTTTAAAAGTAAAAGAATGTGGGCCAAAAATATGTTAACCCATTCC +CACCAGACATGCAACACTGGGGGGGCTGTTCCTCCCAGGCTCCTTGGGCCCCCCAGCTGC +CCATGACCCCTGGGTGTGCCCAGACAGCAGGGGGGGTGTAGTCCACCCCCACCACGTCCA +CAGCCCCTGACTCTCGGGTGGGTCTGGGGGCTGCTCGCCCTGGGAGAGAAGCCATCCCCT +CCCGGCGGGGCCATCTATCAGGACCTCTCTGACATCAGCATTTTCCTCTGTGGCTCTAGC +TTCCTGCCTCCTATCTCTGTCCTCCTGAGAATGTCCCATCTGTCCCATCTTTCCCATTAG +CAGCCCTGTCCTTGAGCCCAGTGCAAGCTCCACAGTGGAGAGGCCACTCAGCATTGTAAG +TGAATGCTTGTCCTCGTGCCTCCCTCCCCGGGAGCTCTGCCTGGAGCTCCTTCCCGGCTC +CGGTGAAGCTGCAGGCAGCATTTCATTGCTTTGACCTGTCCCAGGGCACCTTCCTTCTAG +AAGGGCGACTTGAAACCTTTTCATCACAGCACGACATATGCCCGGTCTTGCTTTGGTCAT +CCAGTTTTATGTGTCCCATTTTATACTCATTTTCTTCCCCTCATGTTTTGTTTTTTTCTT +TTAACTAAAACGATCCATTTATTGAGTTAAAAGATTGTATATTCAAGACGTTCACTCAGT +ATGTGATCCTGCATAGTAAACCTCGGGTGAAACAAAGACAACTATTTTTATATATTTTTA +AAAATTTAGTGGCATATAGACTTCTAATATTTTGGGGGGGGGGATATTCTTTTTTTCTTT +AATTATGGTAAAATATCCATAATATAAAACTGACCACTCGAATCATTTCTAAGTGAGCAG +TTCAGTGGCATTTGGCATACTTACATTGTTGTGCAGCCATCACCCCCATCCATCCACAGA +ACTTTTTCATCTTCCCAAACTGAAACTCTGTATCCATTAAATAACAAATCCCCACCCTTC +CCCGCCCCTGGCAACCACTGTCTACTTTCTGTCTCCATGGATTTGACTACAGTGTGTCTA +AGTGGGATCATTCAGCATTTGTCCTTTTGTGACTGGCCTATTTCACCCCTCTGTTTTATA +CCTTTCTGCTGCGTGGCGCTTTGGCTTTCTATGTTCTGCGGCGGTGGGTGGTAAAGTGGA +TGTCCTGCTTTTAATTCTGAGGGCTCGCTTCTCAGTTTTCAAAAACACACTTTAATCTCT +GATTCTCCAATTATCAAGCATTTGCCATGAAATGATACTTGCTGCTCCCCAGCACTGCAG +ACTGTGTAAGAGACATCTCAGCCAGCATTTGGATTAAGTCAAACCCCAGGAATCCGCACC +TCCTCCACCTCATCACCCAATAAAAAAGGTAACGCTGAGGTATTAGAACATTCACATTAG +TTCCATGAGCATGCCCTCTTATGGGCCTGAGAGCACCCAGGCTCTGGTGCAAGCCCCCCA +CAGCCCAGGGAAGTGTTTCAGGACTGGAGCCCTGCTCAGTGCTGTGGGCTGCACAAGGGG +TCAACTGAGGACCCCTAAGCCCAGGAGTGGCAGAGGCTGGGGACCATCCCATGGGCTCCC +AGGATGGCCTTGGGGCCACAGGGATTATGGCCAGGCTTGTACTTCCAAAGCCCTTCCAGG +GAGGAAGGCGCTCCACTTCCTGCTTTGGCTTAAAAAAGTCCAGGGAAGCACCTGATTGGC +CTGGCTCAGGTCACATGACACTCCCTCTGTCCAATCACTGTGGCCAAGAGAATGCGCTAT +TGTGATTGGCCCAGCCTGGGTCAGAGCCTTCCCCTGCTGCCTGGAGCAGGGTCTGTCTCC +AGGAGAGAGGAGTAGGGTTCAGCCATTCCAATGGCGCTGCCGCCTGAAGAGCTGTCAGTC +CTACTTTGCAGTTGAGCTGGCTCTGAGAAGAAAGTGCTCTGCCTAGCCCTGTGATTGATC +CACAACTTCATGGGGACTCAAACATGGGTTCTTTTATTCCAGGTGGAGAAATTGAGGCCC +CAAGCAGGGGCAGACTCACTGGGGTCACATGGTGAGTTGGTGGCATGAATGGGTGCTCCG +GTCTACACTGTACCACCTCCTCCAGGAAGCCTTCCTGGCTTGGTCAAGCCAGGCCTGGGG +TGGTCACCACCTGATGTCACATCCCCTTGAGACAAAGCCCCCCCCCTCCCCCGCCACCAG +GCACCTATCCCCAGTGTCCAGGACATAGCTACTGGATTCAGGCAGCTTCTGCAGATGAGC +TCCCAGCCCTATGTCCAGGAGGTTTCTGGAATCGACAGCTCTCCATGCCACAATACCCTC +CATGGCTATTTAGGGAACACCCAGTGTGTGCCAGGTTCGGCTGGCCTGGGAGAGTGCACA +GTGGACACTGGTCACCAGGAGACACAGGGGGCCAGTCCACACCCTTCCGCAGTCGGGCCT +GGGGAATGGGTTGGGTACTGACCTGGAGGAGGGAGGGACAGCAGGAAGGGCTGGCTGGGC +CTCAGCTCTCTTGCTTACCTTCCATTCTCTCGATGGCCCTGGCTAGACACATGCTGGCTC +GCCCAGGCCCTACTCATGTTTCGGCACAACGACCCTGCTCTGCCTCCGTCCCCAAGACCC +TGGGCTGTGCAACCAGGGCCAGACCTGTTCTTCAGCCGCACCAGGGCCTGGCTGTGCCTC +TGCCTGTCAGTGGCCAAGCCCTGAGCCTGGAGCCATCCAGAGCCGCACGGAACCCACAGC +CTGCAGGGTGGGGCTAGACATGGCTCCTCCTGCCCGCCCGTGGGTCGTACACCAGCTCAT +TAGAGCCAAAGCAGCATCGATTTTGTGAATGATGAGCATGTGTACGTGTTTTTGGAGCCC +TGGTGTGATTTGGCGTGTGCAGCTGATGATTCAGGGGGGTCATGTGCAAACGACACGCCT +TATAAATGTGAACCCACCAGAACGCCCCGTTACGGAGATTTACACTGATCCTTAAACATC +GTAGATTAATTTTTGGAAAACATCTATAAAATAAGAGATTTATACCTAAAACAATACCCT +ATGCTGTGACAGGAAGGGATTAGAGTCAATTTATTCCTGTATTAGTCAAAAACTCAATTT +CATATATTGTGTGGAAAAATTAAAACCCTTTCTACATTTTATTACAAATTATGCATACTC +CATATATGGAGATAAATAATTGATAGCATTACAAATACTTAATCTAGAAAATATTTATTA +GGAACAGACAACTCATTTTTCATGTGTTTTGTTGAGAACAATATTGCACACTTTAAAAAA +TTAATGATGACTCTTTGCAAAAATAAATGTCTACATCCTAATTCTTTTGTTTAGCATTGT +GTCCAAGCCAGGCAGACGCAGCCGGGCAGTGGGCAGGTGGCCATGGAGCTGGGATGTCCA +CTCCCTGGCCCCTGGCTGTGGATGGGTCAGAGGGCTCATGTGCTGTGGCAGTTGGCCAGG +GAAGGTGCATTTGGAGAGTGTCAACATACTGTTTGTCTTCTGCTGTGCAAACTCTCCTCG +ACTTGTAATTTAAAACTAAAAGTGTTTCCGACTTAATTTCTGAGAAAGCACCAAGTAATG +GGATTTGTGGATGGACTTGAAGAGCCAAGAAATCAACACTGACTGCCTCTCGACCTGGAG +AATTACGGAGCCCATGAATTCTCTGGGCCTCAGCTCTGGTCCCAGGCTCTGTGCACAAAG +AGAGGTGGGCCTGGTGGGTGGTGCGGAGCTTGGCCTTGTACTTCGTGGCTGGCTCAGCCT +GCCCTCCTGGGACAAGTGGCTCTGCCGGGTTCTGTGTGCCTCCTGGCATCTCTCTGAGGG +GAGCTCCCAGCCTCTGCCTAGAATACCTGGGCAGCGTGTTCAGACCTGGGGCCCCCTGCA +CCATCACCCCATTCCAGGCTGGGAAGCTTGAGGACCCAGGCAGGGAAGCTTGAGGACCCA +GGCAGGGCCCCAGTGTGCCACAGGGCTTGGCCACTGTGCAACTGCACTGCAGCTCTGGCC +TCTGGCCGGGCCTTGCTTACCGACCTCTGCCCTCTGCCGTGTGTCCTCCACCTTGGCCAT +GCACAGCGGGGGCTAGGCGGGCACATGGTGGAGGCTGCCAATGGTGCCCTGGCAAGTTCT +CTTCGCCCTCGTGCCAGCCACTCCAGGGAGCACCAGGGATTGAATAAATAACTGCCACGT +TTATTAAAAAATAAATTTGGTGCCTAACGGAAGTGCTGTTTCTATACATAGAAAAAAATG +TTTAAAATAAAAACCAAAACAGTTCTCAAAGGCGCTGTGGCATTAATTATTCATCGCTTG +CTAATGAAAACATGGCTTTGCAGGCGTGGCCCCCACCTCCCTCCAAATAAGACTCGGGCT +CAGGGAAAGCCTGGCCTTAAGGGCAGGGAGCTGGTGACCCCTGAATAAAATGGGGGTGGC +TGTGATATCCTCCATGGGTATTTAGGGAGCACCCAGTGTGTGCCAGGCTCGGCTGGCCTG +GGGGAGTGCACAGTGGGCACTGGTCACCAGGCAGGCACAGGGGGCAGTCTGCACCCCTCC +TTAGTCAGCCTGGGGAATGGCTTGGGGTCTGACCTGGAGGAGGGAGGGAGCAGCAGGAGG +GGCTGGCTGGGCAGCAGAGCCACCTCTTGGAGGAAAGAAATGGGGACAGAGGCCACTCTG +GCCAGCACCAGAGGACAGTGGCTACATGTCTGGGCACCCAGGCCAGGGGCCTGGCAAACC +CCCACAGGGTGGGTGGGTGAGGCCCTGTTCTAAGTCATTTGATGACCCAGCCACCCTCTC +AGATGCTGCTGGATCCCAGACAGAGGGAGAGAGGGAGGCTGCAGGCCTTGCCGGAACCTA +GGCGTGCCATGCATGCCCCAGCAGCCAGAACCAGCCATGTGGTGGTGCCACACCAGAAAG +GGCCGGCCTGCCAGGCAGTCAGGGGCAGATGGGAGCAACTTGGGAAACAGCAGCAGGAGC +CTCCACTCCCTCTGCCTCCACCTCTCCAGCAGACTATATGGCACACCCTGCCCAGCTGTG +TGCAGCAGGGAAATTTGTGCCAGGCCTCGGGCACCTGAGCCCACACTGGGCATCGCTGTC +CTGTCACTGATCCTGGGCACTGATAGGAACTGTGAACAAAGCTCGGTCCAGGGCCCTGTG +GACTGAGCTCCCCATCCTCAGGGCCCGGGAGCCCCTCCTCCTGCAGTCACCTGGGGCAGC +CCTATCTCTGTGGGGAGGCCTGGAGCATTTGTTCTTTTGTTCATTCATTCGTTTATTTAT +CCATAAATGCCCCCGAGCTGGCTGCCTGGTCTCCTGGGGAGAAGGGATGCTGATCCCATC +AGTCACCTGCCTGAGCAGGGGGTCTGGGAGGCTGAGAGGAAGCCTCTCTGAGCTGCTGTG +GGTGCAGGTGGTATCCAGGGCGACAGCTCCTGGGCAGGAGATGAGCTGTGCCCTGAGGTG +GTCAAGTGGAACCCCAGCAGGGGCCTTTGAAGCTCCGCCAGCCCCTGGGGCAGGTCAGGG +ATGGGGAAGAGGCTGCAGGGGGCGGCAGGAGAGTGAGGCTCCATCTCTGCTGGGTGGCTC +CGTCCTGGTTAGCAAGGTCTCTCGCGTCCTGGCCCCTGTGCTGGCTCCTGGGACGTGGAG +TGGAACCCGCATCCCTGCTGCCCATGTGTGAGGACCCGGGCTGCCAGGGCTCCAGCTGGG +CCCCAGGCTCAGGGTTTGTGTGCTGGAGACCCAGCAAAGCTGGACAGAGCCTGGCGGGAC +CTGGCTCTGCGATGGCCCAGCTTGGTGTACTCAGAAGGCCTGATGGGAGCTAGCCTGGAC +ACCTTGGCCTGATTTAAGCCTGGGAGCCGCGTAAGGGGAGGCAGTTGGGCCTGCCGCCGA +ACCGACGCCCCGCTGCCCCCACTTGCCTCTCCCGCCGGTGGGCCTGACCTTGCTGGAAGC +ATCCCTCAGCCTGGTATGGATTTCCTGTCTTCACCGAGGCCGCAGGGCCAGCCGGGCGCA +GGAGCCGAGCGGTGGTCAGGCCCGGGGATGGTTTTTTGTTTGTGGGGGCAGGGGCTGAGG +GGACCCAAACCTTCCAGAGCTGGGGGGTTTTCTTCTCACCTGTCACTCCGTGGCTCCCTT +TGGTGGCTCTTTGTCTGGCATGGGTGCTGGGCCCACCCTGCGGTGTGGGCAGCTGTCCAG +CCTAGAGCCTGCCTCTGACCCTGGTCCTATCCTCAGGGCCCCTTCCAGGGCTGGAGCAAC +AGGGACACAATTGCTGAGCTCAGCCTGTGTCAGGTGCACAAGTGACCTCACTTGGGAGAC +AGTGCAACTGCAGTGGGCCTAGAGAGGGCTCTTCAGCTCCCAGTCACACAGCCAGGCCTG +GAGAGGTACACATCCTGGTCCCTGATTCCCCCATCGGCACTGGGTGGACTGAGGAGTGGA +GTGGGGACCCTGGGTGGGGGAGAGGAAGGAACTGGGCACAGGGGGAGAGCCAGGGACCAG +AGGGCATCATGGAGATGAAAGGACAGGCGAGCCCAGGAGGGCACACACCATGGCACGGCA +GGCAGACAGACATAGACATAATGCCCATATGGCAGCATGATCTCTCACACACACACATGC +TCACATGGGCAGCACACTCACACACACGTGCATATGGACGGCACGCTCACATACACACGC +ACACATGGGCAGCACGCTCACACACACACGCACACATAGGCAGCACACACACACGCACAC +ATGGACAGCAGGCTCTCACACACGCACACATGGGCAGCATGCTCACACACACACATGCAC +ACATGGGCAGCATGCTCTCAGATACATGCACACATGAACATGGGCAGCACACACGTACAC +ATAAGCAGCATGCTCACACATGCACACATGGGCAGCACGCTCACACACTTGCACACATGG +GCAGCACACACACACGCGAGCAACACGCTCACACACACAACATGGGCAGCACACACATGT +ACACATAAGCAGCACACACAATGCACACATGGGCAGCACACACATGCACACATGGGCAGC +ACACACATGCACACATGGACAGCACACTCACACGTGTACACATGGGCAGCACGCTCACAC +ACATGCACACATGGGCAGCATGCTCACACATGCACAGATGGGCAGCACACACACACATGC +ACACATGGACATCACACACGGACATCACACACATGCACACGTGGACAGCATGCTCATACA +TGCACAGATGAGCGGCACGCTCACACACTATGAGCAACAAGCTCACACACATGCACACAT +GAGCAACAGACACGCACACAGGCACAACATGGGCAGCACACACACATGCATATGAGCAGC +ATGCGCACACATATGCACACATGAGCAGCACGCTCACACATGTAAACAGGCAGCACACAC +ACAAGCACACAAGAGCAACACACACACATGCACAACATGGGCAGCACACACATGCACACA +AGCAGCATGCTCACACATATGAACACATGGGCAGCACGCTGACACACACATGCACACGTG +AGCAGCATGCTCACACACGCACACGTGAGCAGCATGCTCACACATATGCACACATGGGCA +GCATGCTCACACACACGCACATAGGAGCAGCACGTTCATACACACATGCATACATGAGCA +GCACACTCACATGCACATGTGTGCACATGGACAGCACACAGATACACATGCACATGTGGG +CCACACATACACACACATGCACACATTTATGCACATGGGAAGTATACTCACACACATGCA +TGCACACATGGGCAGCACATTCACATGTGTACATATGTGCATACCTAGGCAGTATGCTCA +CACACACACACACTCATGTGGGCAGCACACACACGCACACCTGGACAGCATATTTACACA +TGCATGTGCAGCACACATACACGAGGCAGCATGCTCACAGACACACGTGCACACACACAA +GCACACTCAGAACAAGCTGTGGGGCCTGCGGTGAGGACACCAGGCAGGCAAGGCGGCTGC +TGCAGAAATAATTAGTCACTGGTAGACAGGCCTGGCTCACCTTCTCCAAAGCCAAAGGGG +GGCTACCAGCCCCCAGCTCTGGGAAAGGGCTCTGAGGGCCCGCCCCCACCTTGCAGTGGT +TCCTGGGACCTGCAGGGAGCATCCCAAGCACGGCCCGTGGGGTGCGGGACTCTGCCATGT +GATCCCTGAGGCTGGGCCTGGCCGGACGTGCCTTGGCCCCTGCAAACCGTGCACATCCCC +AGGTCCCCCAGCACAGCAGCAGTGCAGGGAGTGGAGACGTGAAGATGGGGAGTGGAGACG +TGAAGATGGGGAAGAAGGAGGTTGGAGGTGCAGGGCCGCCCTGTGTTCTTGTTGGAGTGG +GGGTAGGAGCACTCCAGGTCTGGTTGGGCCCTGTGAGGGTGTTGGGGACCCCAGGCCAGG +CCTGGGTCGGATCCATCACTCCCTGGAGGAGGCATCTGAGTCCAGGGATGCCGGACAGGC +TGGTCCCAGGTCCCCAGGCTGACTGGGCCTCAGGCATATGGGCATCTGCAGCTGTCTGGG +GCCAGGCCCAGGCTGAGGGGCAGCCAGCAGGGTGCAGGAACTCCCAGGCCCTCAGCTTGC +AGCGCAGAGAAGGGTGACTGCTCTGCTGTTAAAACAATTTATTTTGCTCTTCAAAAAGCT +AACAGCTGTTTACAGTCAGCATGTGGGAGCTGCCCCCTGGGTGATGGATTCTGCCAATCC +AGCCCTCCCTTGCCTTCCGGCGAGGAGGGGTCATCCCAGGCTTCGGGTCAGGATGGGCAG +AGCAGACCACTGGGGGCCAGGCCATGATGTTCCTGGCCACTCCACGTCCCCTCGGCTGCC +GTCCTGTGTGCTGCCCTGGGAGAGTGCAAGGAAGGGTGGCCCCCTGAGGCTGATACGAAA +TGGTACGGTGATGTGAGGGGGTCAGGAGGGAGGACCACTGTGGGAGGCGTGAGGTGCAGT +GGAAAGGTCAGGGAGACCTTCTGAGAAGGCCAGCAGGGAGGGCTGCCCAGGGCCTGGAGA +GCGTGCATAGCTGGGGGCAGGGTGGGGGCAGCCGGCAAGGGCAAAGCCCAGTGGGTGTGG +CGATGCCCTGGGGGATGGGCCCCGATGCCCCTAAACTGGTTCGGCTCTCTAGACCAGACT +AGTGTGCTATGTCGGAGCCGAGCAACAGTCCCCCTCAACTGTATGCATGTACAGTAGGCG +CTCAACAGACACTTGCTGGATTTGACAATAGCCCTGGACGGAGGACTGAGGCCTGGGCTG +CACACATTCTGGGCTCCTGCAAGCCCCTGGCAGCCCTGAGCTGGTTTCTGAGTGCAGAGG +GAGGGGCTGTCAAGGGTGGAACCCACACATGCCAAAGCCTGGAGGCCAGTGCAGGGGCAG +GGCACCTGCTGCCTCGGGACAGCGCTGAGGTTCAAAGCCACCTGCTGGTTCCCACCTGCC +TGGCACAGGACCCTGTGTCGGTGGGGGTGGCCAGATAGGGCAGCTCCTTGTCTCCCTGGA +ACCTGTACCCTCAGAGGTCCAGGATCCCTGGGGGAGGTTCCGGGGCTGGAGAGACGGCCC +CTGTGGCAGGGCAGGGACAGACGGGCTGATTCTATCTAGGATGGGGGCACACAAAGACTT +CCTGAGGGGCGCTTCAAGGCCACAGCAATCTAGGTGGGACAGGGACATCAGTCAGAGGTG +CCCTGTGGAGACCCCCAGGTCCAGCTCCTGGTACTGTGAGAAGCCAGTTGTTCCCTCGCA +GGCCGCCAAGGCACCGCACAGTCCTGGCCTGAGTCGTTGTGGGGTCTTGGGGAGGAGGGT +TCTCTGGAAGGACACTGAGCCTGGACTTTGGGGCAAGAGACCCAGAGCCCCTGGATGCTT +GCGGCCTCAAGGCCCAACATGCAGCCAAGCAAAAGCTGGGGGCACAGGCAGGGGATCCCC +TCTGGGGAGGATGCAGAAGCCGAGCCAGGCTGGGCCGAAGCTCCTTACCTGATCTGGTGT +CCTCCTGTGCGATGGTACAAGAGCCTCAGGGCACATCTGGTCTCTGTGACACCCCCCGAG +ACACCCGGGGAATGTTCCCAATGACCACTGTTGGGCCACTGCCCGACCACGTCACGGTTG +CCCCTGCCAGGACTCAGGCAAAACCCAGCTGTCCCTGGCGCTGTCTCCCAACAGCCCTGC +AGGGCCCAGTGCTGGACCAGGGCCTTGTCTCCAGCCTCTCCCCCATGGGACTCTGGGGCC +TTTGGGGGCCCTTGGGGGCCTTCCTGCACCCTCACACCTACTCATCTCTGGACTCAGCCT +CAGTGTGAATGCTCACCTCGGGCTGAGCCAACCCCTCCAGACACGTTCTGCAGCTCGAGG +AAGGAACTGCCCTTTGCAGCTGGGATCTGCCCGAGTTTCAGCAGCAGCCTTGAATTGTAA +TCCCGAGCGGCTGGCGAATAACACAGCACACAGCACTCGAGAGCCCAGGTGAGTCCTAAG +TGGGGCTGGGCTATGGGATCTCTGGCTTCTGGGCCTTTCTCAGAACAGACCCTCCAGGCC +ACTCTCCCCTACATCCCCGGTTGCTGCACTGGGTGCAGGGGTCCAGAGCCAGGTCAGCTG +CTGCCCAGGGAGAGGGCCAAGACTGCAGACCCCGCCAAGCCTGGGGGCAGCCTTCCTGAC +AACAGCACCATTTGCTGCTTGGGATCAGCCAGGCCGGCTCCCCGCAGATGGGAGGGCTGT +GAGGTGAGCACCAGCGAGCCCCTGGAGGTGCCAGAAAATGCCAGTGTGGGCACCAGGGGG +CTTCCTTGGGCTGGCATGTCAGGGGAAGCCCACTGGGGCGGCTCAGTGCCCATGATGGAA +GCTCAAGTCCCACGGTGCTGCCCCAGGAGCTATACCCCAGTGAGGGTCGTTGGCTGGCGA +TGTGTCTGGCTGGCATGGGCTGCCTGGTAACGAGGGGGGCCCATGTGTGAGGAGCCTTAG +GTAAGGATCCAGCTGGCACACCGAAGACCCCAGGCCAGGGGACACAGGCTGGGGGAGGGG +GCTACAGAGACATGAACCCAAAAGAGAATGTCTGCTGACATCCCAACCCTGACAGATAAC +CAGCTGGGTGACAGGTGGGGGCTGTGCTCAGATCACCCTCCTCTGTCCTGTGCACATGTG +TGGGTGCATGGGAGTCCATGCGTTGCTCCTGGCTTGCCCCCTCCTCTCCTCGGCCCAGCT +TGTGGTGCTGCGCTGTGCATGGAGCTCGGTTTCTTAGCAAGTTCATGCCATGAGCCGCCA +GCTAGGCTGAGGAGGAGTGGGTCTGGGTGCCACTGGGGCGGTCTGGGCTTCCCTCAGCTC +CAGGGCTCTTGCCCTTGCTAGCATTGCTGTGATTCTCACCATTGCGCCCTGTTACAGAAG +AGACAACTGAGGCATGGGGAGGTGATGGGACCCCCAGGGCCACCCGCAGGAGGTGGCCAG +CCCAGCAGCCCTGCCCAGTCCCCCGCCGGCCTTGTGCTCCCATCTGGGCCCCTATCTGTA +GTTTCCCCAGTTAACAAAATCACAACAGTCATTCCTGGTTGTTCTTGCTGAATTCTCTCC +ATTTGAGGAGCAGCATTTTGGGGTCTGTGTCCTAAATGGACCCAATCACAGGAGTCACCC +AGGGCACTGGCTCAGCCCAAGACAACACCTTCCCCCATGTGGACACACACACATGGGGGA +AAGAAAACCTTGCCAACCCGCCCTCTAGCAAAGGGGCCTGGACTCGCATTTTTAACAAGA +ACCAAGAGATCCCGTGGAGGAGGTAGTCCACAGGGGGAAAAACACCCTTGAGTCTCAAGT +CCCCCGTGGCTCCCCAGCTCTGCCAGTGGCTGCATGGCGGGTGAGATGATGGTGGCTCTT +GGGTCCCTCTGAGTCTTGCTGCCCAGGCTGGCACCGGCACATTTTGTCTTGGCTCCATGC +TGTCGGGCCCTGAGCTGGGCACTGGGCTCCCTGAGTCTCGTGGGAGCTGTCTGGGTCCTG +AAGCAAGTGGTGGCCCGAGCAGGGGAGGCGGTCCCCACCCTCGGGGACACTGTCTGCTCC +GGCTGTGGGCTCCGGGGGCTGAGAGCTATTTCGGCTGCACTGGCCTCTCCACTCCTGCCA +GGCTTCAGTGAGCTAAGATTGTGCCAAAGTCAACAGAACAGAAAAGAGAGGCTATGGCGC +TCTGTCAGGGAGAAAGCCCAATTAGGAGGGGCTTGTGGGGGCAGGGCGGGAGTGCAGAGG +GAGCCCCGGAACCTAGCCAGCCCACTGTGATGACAGGGCCTTCGACAGCAGCCCAGCACT +TGGACTGTGCAGAACTGCGGAGATGGTGCTGTGAGCCTGGGGAGGGTGCCTTTCTCCCCA +GGGGCCCGCATGGGGCCAAGTCTACCAGACTTCTGAGCCGGCATGTCTGGGTACAGGACC +TGGCCCTGCAGAACTAGCCTGGGCATCAGAGCCCACCAGAGGTGACTGCCAGCGGCCAGG +ACCCACCACGGAGTCTCAGGGAGCAGCACACGGGTGGGGAGCGGGTGGAGGGCACACAAC +GCTGGTGGGGCATGGGCCTGGGCACCTCTCCAGCTGGACACTGCACATGACACCCCAGGC +CAGGCCAGGGTCCCCTGACTCACAGACCCCAGGCACAGGGACATGCTGTTTTCCTTTTAG +TCCAAGTGTACGGGGTGAGGAGCTGCAGCCCCCACCCTGAGGGCCTGCTCTGTTTAGAGG +GGGTGCCAGGGTCCTGGGTCCCTCCCTCTGTTAGAGCTGTCTGGAAATCCTGAGTCGGGT +AGGTGAGGTAGGAAAGGGAGACCTCCCCACCCACTGCCCTGCCTGAGCGGCTCCCACGGT +CTAAACCCTGTCTTGGGGGTGGTTCCCAGGAGGAGGCAGCAGAGCCTGGTGAAAAGAGAC +CAGACAGTGTGGACCTCCCTGGCCCTGGGATCAACAGCCTCTCCTGGGCCCAGCTTCCCC +AGGCCTGAGCTTGGGGTTGGAGGATCGGCAGGAGAGTGAGTCCATGAAGGCACCATCCCC +ACCCCTCAGCACCCTTTCCCTCCATGTCATCTCGGCCACCCATCTCAGAGCCCAGCTCAG +CACCCGGGCCCTACTGGGCCACCCCGTCAGGCCCTGAGTCCCCATGGAGGGTTTGGAGGC +TGGAGGCCGGTCAGCTGGGGAGGGGAAGGGCAGAGGAGCAGGGGTGAGCCACTTGGCTCA +GGGCTGAGGACCTCTCGCACTCTGGCCACTGCAGAGGGTGTCCGGCTGGGGCAGGAGGGC +TGTGGGAGAGAGATCACATCGTGTGTGGGAGGGGACAGTCCCCTCCTGCCCAGTCCCCTC +CTGCCCAGTCCCCTCCCCACAAGGCCTTAGGGAAGGGTGGGGGTGCCACACACCATGGGC +TGGTGCCCCCATCCTGGCTTTGCCTACCTAAGGCTCTGGGATTGGCAGGCATGGAGTTCC +CCAGCCCTGAGCGTGGCAGGGGCAGGATGACAGACCCACGGTCCCCTAAGCCCTCCCTCC +TCCACTTACACCCTCGCCCGCCAGACCCCAGTCATTCTCCTGCCCTCAGGGCCTGGATTC +AGCCCCACCCCCAGCCTCCTTGTAAGCCCGGCCTTATTAGTGCTGCTTCACCCCGACTTT +GCAAGTCAAATTCCGCATTACTGCGCTCCTGCTCTGTTTCCACCTTGATGCATGGAGAGC +TGGAGAGCAGCTGGAGCAGAGAAGGCACTGCAATGAGGCGGCAACCCGTGCTGGCCAGGG +GCCCCAGGGCCCAGAGCCAGGTGGGGTGGACCCCGAGGCCCTGTCTTTCCACAGGTGTCC +AGGGTCACTCCCACCCCACCCTTGGCCTCCTGCTGGCTCAGCCCCACACCCCCACCAAAG +GGCCAGGCTCCGGGTGAGTGATCCTCAGGGCCCCCGCACAGGCTGTTCCCTCTGCACACA +GGCTATCCCTGCCTTCCTGTCCAGCCAGTGGGTGGGGAGAAGCGAGTCCCTCCTTTCAGG +GATTCTCAGGAACCGAGTGGCTATCAGGGTATGCAGCTGTGATGCACGTGGCAGGAGAAG +ACCTCAGACGCCACAGCCTAGCTCTCTGTGGGGCAAGTGTGTCTCAGCCTCTCTCTGAGG +AGAGGAGAGCCCCTGGACTGGAGGGTGCCCTGCTCAGCTCTGCCTGGGTATTCTGTGGCT +TGCAGGGTGGAAGGTGAAGGGCTGCAGGCGCTGGCCTTCCCAGGCCCCCCACTGTCTGCC +CAGCTTTTCCTTCTTTGGCAGCCCCAGTTCCTTCCTTATACCCAGTGGGACAGCAGGGCC +CAGCCCTAGGGGCCGCAGGAGACAGACATGCCCCAACTGAGACAGACAATGGCCAGCATG +GCAGGTGGCCCAGTCTCGGCCACCAGGACGTCCTAGGAGGTACGGCCCCTCAGCTAAGCT +GGCTGTCCTTAGTGGCCCAGCTCTGGCTCTGGCTGGTCCTGTGAACTCAAGATGGCAGAC +ACTGTTCCTGGTCTCAGGCCAGGTCTTGGGTGAAGAACGTTGGGTGTAGGACCCTGTACC +TCTCCTCCTGGAACACCCCCAGTGGATGGCGAGGTCACTGAGGCTCCATCCAACGGGCAG +CCTCCAGGGCAGCCCTCGCTCCTCCCTTGCCCTGGAGGTGGGCACGGGTCAGTGGAAGGA +TGGGACTGAGGGGCTGGGCCCTTCACCGACCCTGGAAGGTGGCTCCCTGTGGCCTTCCCT +GCAGTTTCCTGGTCCAGTGTGGTTCAGCCTAAGACACAGGTGAAGGCCTGGTTATCACTT +GGCTGCTTTTGCCAAAAGAGTGGCTTCCAGTGAAATCCTTTGGCTGCCGAAAGGCAAAGT +CACCCTCCCTCCCTGTGGCCCCAACACCTGCAGGGTTTGTCAGCAGAAGGTTTTCACGGT +CCACTGGGCATTCGCGGGCCTTTGGCATCCTCGAGGGCCTGCCTTTGATTAGCACACACC +CTTTGCTTGACCCAGAGGGTCCAGATGGCACTGGCTCCACGGCATGGCCTTGAGAATTGA +GGCCGGCTTCGGCGAGGATGGTCCCACCTACTCTGGCCTTCAGGCCTTCACCAGGAGAGA +TTCAGGCTGCTGGCCCAGCCAGTCTCTGCAGGGACACCCCGGTGGGCCCAGGGAGGGACT +GGGGTCAGCTGGGGCCCTGGACTTACAGTGGATCCCACTTCCCCCACGTCTTGCTTGGTT +CTGGGCATAAGGGTCCTAGTTCTTAGGGCCTGGCCTGGCCCTCTCACTGCTCCCGGGAAA +CCTCGGGAAACATGGCAGGCTGTGTTCCCCATCCTCAGGCTCCCAAGTCGCTTCTGTCCA +GTCCTCTGCTGGTATCTGTGACTCAGCACCATGACGGGGCCCTGTCCAGGGCGTCCTGGG +CAGAAGGCTGCTCCGAGTGCACAGCGGGCACCCCCATGGACAGGCTGCGTCCATGTGCCA +CTCCTTGGCCGCCCTCTCTTCATCTGTAGTGATGACACAGTGACCCCCACCTGCAGGCCT +GGTGGCACTGCTGTCACCAGGCACAGGGAGCCTGCCCCCAACCTGGGTGGTGTTGTGGGA +GTGGCTGGGCAAGGAACGCTGCTATCCCTGCTGAGCTGGGTGGGCACTGATGGGCATGGG +GACCTGGAGTGCTGACCCCTAGCCCTACTGTCGGCAGGCCACGCCTGCCCCTCTGGGGAA +CTGCTGTGTCCCCCTTGGCTGGCCTAGAAGTGCCTAGAAATGTCTTTTATGTGGGGAGTC +GGTGGGTGAGGGCCCCACTGTCCCATCCCTTGAGGAAGGGAGGGCTCTGGGCAGGGTCTG +CACCAATTCCCCAGTGCCTGCTGAGGCCTGTGGCTGCCTCAGGGACAGTGTCAGTCACCC +CTTCACCCTGGCATAGGTGTCCTATTTCCAGAGTGTAGTGCTGGATGCTTCTGTTTGGCT +GTGTTAATTGAGACCAGCTTTTACAGAATGAGCCTCTTGGGGTGGGAAAATCTGCACAGC +CTTGGTGTTTAGGGTAACCTGAAAGTGGAGAGTGAGCCTGGGGTGCAGTCTCACTCCCCC +ATGCCCCTGGGCACAGCTACCCACAGGCCCACAGCAGGCAGGCAGGACTGATGCCATCCT +CCAGATCCCCCGACCAGGCCCAGAGGTGGGGCCAGGAGAGATCTGGGGAGTTGGTGCCAC +CAGATTTCCCAACCATGACAGGATGTCGGGGGGTGGGGGGCAACAGCAGGACTGCCCCAG +GCTGGGTCCCCACCCAAGTGAGGCTTGGTCGTGGCCTCATGGCCAGTTTGTCCCTCTGCG +GATCTGGAGGGGTCCTCGGCTGCAGCAGGGGGCCCAGATGATCCTGACCTGGGGATGGGA +AGGCCTCTGTCCGTGGTTCCCCAGCAGAGCGGGGCCTGTTGAGAGGAGCAGGGGATGGTC +TGTTGAAGGAGTCGGTGAACGGAGAGGCATGCAGGGATGGATATGGACAGGGCGGGTGCT +CAGACCCTACAGTCTGAGGTGGAGGGGTGGGGTTGGAGGCTGGAATGGCCGCGGGGGAGC +CTAGAGGGGTAGGGCTGTGGCTCCACCACTGTTGGCTAAGGGACCTCAGGGAGGGCTTCA +GAGGCTGGGGCCCTGGCTCCCAAGGCCTCAAGACCCTCCTGCTCCCCCTGAAGGTAGCAG +TGACCGCCTCTCAGAAACCCCTGGCATCCCTGGAGGCTGCAGTCCCCCGCCCCGCCTCCA +CTCTTTCTCTCTGCTCTGTCATTTTTCAAAAATAATTGTGCAGCAGCACCAGGCTGTCTC +TGTGCCCCTCCTGTAGGTTGCCCTACCCCACCAGGTCCCTGGCTCGGCGTCCCCAGACTC +TGCCAGGCTGGCCTCACCGTGTGTATCGAGGTGTTCTCCCTGCAAGGTCTTCATCATTCC +CCAATTGCTCGCATTTATTTTTCTCCTTCCTTGGTGAGTGGCCCTGCCAGCCTCAGCCTT +GTCTCTCCTTGGTGAGCGTCATTAATGCAGCTTCCGCGCCACGATCAGAGGGGGCTGCCC +CCACCCTGCCGGCCCTGCCGCTTCTCCTCTGCCCGCCTCGGGATGGATGTTCATTTATTG +CCCATAAATCTCTGCACAGCCCTTTGTAAAGACAAATTGGAGGCCTCCTGTTCCCCGGTG +TTGGTTGGGCCGATCGGTGGTGGGTTTAATTGGCCCTTCCCGTGGAGGCTGCCCCTGCAG +GAGAGGCTCGTTGTGGGCTGGGCCAGATGCACTGCGTCTGCAGAAGGGGCCATTCTCTGC +CCCTCATTTTGTCTAGCGTCTGAGGCTGGGCCATGTGCAGGGACAAAGTGTGGATCCTCC +CTCGGGCTTCCAAAACATGGCCTCCCCGCATTCACGTGGCCTGGCAGCAGCCCAGGCCCA +GGCAGGGCCCTCTCTCACCCAGGGGGTGATGCCTGCAGCTTCAACAGCAACCTCCAGGAA +GGAGGCGCATGGGTTCGTTGAGGTGATACAGGAGTGGAAGAGCTTGGTCCCTTGAAATGA +ATGATAGGGAAAAGGGGAAGTGCTGCGTAGAGGAGGGTGTGATCCCTGGCTGGGGCTCCA +TCCCACAGACCTAGGTGAGGACAGGCATTTTTGCATTTCCCAAGACCACCCTGGCCTGCC +ACACCCCCATCCTATGACTATAAAAACTCGCGAGACCCTGGCAGGCACGCACAAGCTGCT +GGACGTGGAGAGGAGCGGATTGGCAGAGGAGCACTCAGGCGGCTGGACGTCGAGAGGAAC +GCACTGACGGGCGCCGGCACCCCGGCAGGCTACCAACCGGCAGCAGAATGACCTGGAGTT +TGGCTGGGGCAGCCAGAGGAGAGCCCGGGCCCGACTCCAGGGGAAAACCGTCCCACTCCA +TCTTCTTCTGCCTTCCCCCATCTGCTACCTCCACTCAATAAAACCTTGCACTCATTCTCC +GAGCCCACGTGTGGTCCAATTCTTACACCAAGGCAAGAACCTTGGGATGCAGAAAGCCAT +CTGTCCTTGCGATAAGGCAGGGCTCTAACTGGGGTTTAATTGAGCTGAGTAACAGAAGCC +ACCGATAGAGTTAAACTAAAACAGCAAAACTAAAAGAGCACCCTGTAACACGCTCACTGG +GGCTTCAGCTATAAACATTCACCCCTAGACACTGCCGTGGGGTTGGAGCTCCACAGCCTG +CCCGTCTGTATGTTCCCCTAGAGATTTGAGCAGCAGGGCACTGAAGCAAGCCACAACCCC +ATTGCATGTACTGTGAGGGGAACAAGGGGACTTTTCCTGTTTCACCAGCACACAGCAGGT +GCCTAATAAACGCACAGCGAACTGGTCAGAGAGAGAGGGACCCTCCACCGAGCCCAGCCA +CTGCACAGGCTGGGAGGGCAGGACTCCTGCCGAGCTTGGCACCCTTTCCTGCACCCAGGT +GGCTGTGAGCCTGGCCCTGCCCCGGTCAGCAGGCCTGTGCTGACCCCACATGCAATCTGC +TGTTGGTGCCAAGGAAGTGCTACCTGTGCAGCTCTCAGAATGTCAGGCTGGGTGCTCCTC +CACTGAGGTCAGGGTCAAGAGACCCTAGGCCAGCTCTGGGGGGCCCACAGGGCGTGAGGG +GGGTCCAGGCAGCCAGCCCGGCCCAGCCTGGTTCCACTGCTTACTGTGTGGCCTTGGGGG +GCTCCCTTGGCTTTCTGGGGCCTGGGGAACCAGGCGCGAGCTTGGTCCTGTGGTCTGAAT +CCAAGAAGACAGGTTGTGGGTGGGGACATTTGGAGGGAGGGACAGCCTCGGCCTCAGCTT +TGGGACCGTGTGGCAGAAGCACCCTGTCTGGCCCTCTATGAGCTCCTCCAGGGCTGGGCC +CAAGCAGGGACCTCTTCTTCCATGAGGGTTTACTCATTCCTCAAAACAGGCACAAAAGCA +GAGGGCTGTTGAGGGGTAGTGACCTGCCCCTGGCTCTGGCCATGCGGGTCTGGGCACTGT +GGATCCACTCCATGGCCACCTGGCTGGGTGAGGACCAGCCTGGAGGATCAGGAAGAGCTT +CTTGGAGAAGGGAGTGGTGTCAGAACTGAATACTGAGCAAAGAGGAAGGACCAAGAAGAA +GATCCTAAGGAGTTCTGGGGCTGGGGGCTGGGGATTGGGAGCAAAAGGAGAGATGAGGCT +GGACAGGTGCCTGTTCCTCCACCCACTGGCTCAGGACTCCAGGCATGGCCCAGCAAGGGT +CCCCTGCCCCTGGGAGCAGGACTCCCCTGCAGCAGACAGAGGCAGGTGGGGAGTGCGACG +CACCTGGAAGGGGCTTCCGGAGAGGTGTGCCCTGGCAGAGCCCCACCTCCCCCAGGAAAA +GACAGTAGCACCAGGCCCCAGCCCTGGAGAAGCCTGACCAACCAGAGAAGTCCCACGGCC +TCCTCCATGGAGTTTGGGGCTCCTCCTCTAGACCTGGGATTGGCACTTTGGGGTCAGGCC +AGCTGCTGGGGAGCCCTGGGCCCCGACACATGCACCCTCCCAACAGGAGTGGGGCTCCGG +GGGCCACTGGGCTCATGCCCATCGCAGCCACTCTCCAAGGCCTTGGCATAATGGGATCCT +TGAGCTGCTGTGCCCGGCGGGGTGGGGGGGGATGGGCTGAGATACACCCTTTGCTGACAG +TGGCCATTGCACTTTTCCCACCCAGGCCTCATGTGGGGAGCCCTGCCAAGCCCAGGCTGT +GGTGTACACAGGGGCTGGGCTGCAGGGCAGGGCTCCGGAGCGGCCTAGCCCAGAGCAGGG +TGGGAAAGGAGCCAGCTGGGGTCCAGGCAGAACAGAGGCCAAGGCCACCAGTGAGAAATC +TGGGCATGAGGGTGGCCACCAGGCCGGCAACGTGGGGGAAATTGAGTTGAGGGCTGGGCC +TCCTCACTGTGGCTGGAGGCGGCCCAAAGGCCAGCTGACCAGACACAGAGCTGCCTCAGT +CACAGAGGTGCCACAGCTCAGGGTGCCACCCCGAGTGACATCCCTAGGCTGACTGACACA +GTGGAGGGAATTGACACCCAGGGTCTTGTGATGTCCCCGGGCACTGGGATGGAGAAGCAG +AGCAGCACTCTGGAGCACAAACACAGTTGGCAGCGAAGGGTCTGCTCCCGCGTGGCCTCG +GGCCCAATCCTGCCTGACATGTTGCTTCATGTCTCTGGGCCTCCGTTTCCTCATCTGTGC +CCTGGGGACATTAGCAGTGTCTTCCTGCGGGGATGTGAGTGTGAGGTGCCCTACCACCCC +AGGGAGGCTGTGAGCTGCAGGCAGCCCGGCAGTGAGGAGCCCCCACCCCTGCCGCCGCCG +CAGTGGCCCGCCCCGGGCCCCAGCTCACACCACAAACACTTGCCTCCCTCTCAACTTGTT +TCCGGCATGTTCTCAGTCTCGCTGGATGTTAGTTTACCATCGGCTGCTGAACATTCGGCA +GCTTCTATTATTTCAGAACTAATTTAAGGATTAAAAAGTAATTCTCCCAATTACTAGGCA +AAGCCCTGGGCAGCCAGATAAACAGGGGGCAGGCGCTCCCATCCAAGGACAGGGCTGCTC +CTGCAGCCCTGGGCAGACAGGTGTGCAGGGCAGCTCTGGTGCAGCTCAGCCCCCAGGGCC +GCAGGGGTGGAGTCGGGGTGGTTGAGAGGAATCCCCAGGAGCAGCCCAGCCTGGGCCCGA +CATCTGAGGGTTGCTTGCCCCTATCCCCCACCCAGGTCGGCTACAGCCACCTAGTGGTGA +GCCCAGCCCCAGCTGTCACCTCCACCAATTGTGCTGGGTGGTGCTGCCCTGGCTAGGCCT +GCAACACAGGGACAGGCCCATGAGCTGTGAAGGATTCGGTCCACAGGGCCCCCTGGGGCT +GGCCAGGCATCTTTGGACGGGGCCAGGAGAGTCTGTGGTAGACCAGCAGCCCGCATGGGG +TGGGGGCCAGGATTTGATACCCTCAAGGCTGATTCACGCAGCTTTAATTAGCTTTCTGCA +CCTGCTCTGGGGTCTGGGTGATCAAGGCTGGACACCAGCTGCCACCCCCAACCCCTGCCT +GGTCCAGCACCTGACCTCAGGGGCCCAGCCGGCCGGGGCTGGTCAGGCAGAGCTGGGGAG +TGCCGGGGTCGGCGCAGGAAGGAGCTGAGTCCCTGGGCCCTGGCCCAACGCCCCGCCCAC +TCCGGGCCCCTCGTCAGCAGCGGCCGGCCGGTGAGCTCATCTCTTCCTGGGCTGTAAATA +TCACCCAAGTGCTCACGACTCCCAAATGTGTCCTCCAGCCGGGCCCCTCTGCTGAGCTCA +GCCTGCACAGCCCACGCGACACCCCCGCCCAGATGTCTCCTGGGCCTCGACAAAGCGGCC +GCTCCTCTCGGCGCCCCCACCTCAGGGACGGGCGCCCCGTGCCGGCTGCTCAGGCCTGGG +AGCCCTGCCTGCCGCCTCCACCCCATGGGAGCGTCCATGCATCCTGCTGAGTCCAACTTA +AAACTCGTCCACTTCCTTCCGGATCCTCTCACCCCGTCCTCAGGTCTGGTTGGACTGTGC +CCAACTCCCCACCCCTGCCACTGCACAGGCCCCCACTGTGGCCTGGAGGGGAGGGTGCAG +AGCCCTGAGGGCAGCTGGTGGTGACAGTCAGCCCCGAAGCTGGCCTGAGGGCGACAGGTG +CCTGCTTCTTAGTTAGGAGTGGGCCCAGCAGAGGTAATGAACTCCTTGTCCTGGGAGGTG +TGCAAGCTGAGGCAGGATCTGCTGTCCTTCCACAAGCCATTGAGGGCGCCAGCATCCACT +GCAGTTGGGTCACTCAGGTGGGGCTCAAGGCTCTTTGGAAATGGGTGGCTTCGGTTTCCT +GGCTCTGACTGCAAGGAGCCCCCAGCCTCAGCTGAGAGCACTAGCCCAGATCCAGCAGTT +TAGCTGCCTCTTCTCAGGCATGACAGGGGCCACTTGGGAGAAAAACTGAATAAAACCCTG +CCTATGCCAGTGCCCAGGCACAGCCTGGCAGAATCCTGGGCCTGGCTGTGGGGTCACAGA +GACTGGGGGTGCCAGGGGTGCTGATGGTAGAGCTCCAGGCACAGGACAGAGACTGCACAA +CATTTTGACATCAGGCCATCCATGGAGAGGCCTCTGCTGGGGCTGCCAAGGGTCTCCTGG +GCCCAGAGGGGCTGCAGAGGGAGCCCTGGGCAAACAGCACCCCACCCCGGCAGGGCTGCC +CTGCCTGAGCTGCCCCCAGCCTTGGGGCAAGGCTGCCGGCCCTGGATCTCAGGTGAGCAG +AGGGGCAAACTGCAGGTGGAGGTGTGCGCAGCCACACGGGGGGCCTCAGCACCTGTGGGC +ACAGGCACAGGGTCTCTCAGGAGAGACAGGACATGTGGGAGGACCCTGAGGAGGGTACAG +GCCAGACAGGACCACTGCATCCTGGCTCTGCCCTGTGCTTGATGGGAGGGGTCTGAGCCT +TGGGCCGCAGCACACGCACAGAGAAGCGGGCGGAGGAGCTGGGGCCTTGGCTGCTAAGCG +CGTCCTCCCCGCTTCTTCTCCCTCCTTCTCCTCCCCCCAGGCTTCTGGAGCCCCGGCCGC +CCCCACGACCATCTGGCTTCACCAGCAACGCTCCCCCACACCCTCCCCCACGTCACTGTT +TTTCTCCCTCTCCCCCTCCCCAGCCACTGCCCTGGCGGGGAGGGGGCCCTTTCCTGGGAA +GGCTTCCTGGCCACGTGGCCCTTCCCTTTTGTTTCTGAGTCCTCTTCGGCCCAGGCCGTG +GGAAAGCGTGCCTGTGCATATTTCTGCCTGTGCATATTTTTGCCTGGATGCGTGTGCTGC +TCTCGAGCCCCCGGTGCCTGCATGTGTGTGGACATGTGTTCCCTGCCCTGCTGTGTGTGC +ATGCGTGTATGCATACATGGGTGCAGGGACATGCAGACCCACCACGGCCTATGTTTGGGG +TGTGGGCATGCTGTAAGTGGGGGTGCCCCAGACACGCATGTGGGGTCTAGTGTGACCACC +AGCAGCGGTGTGAGGGTGCATACAGCCCCCACTGGGCCTTGAGGCCAGGCCTGACCCGCC +CAACTCTCCTTCAGGGCCTTCCTCTCCTGCCACCCACCAGGGGTAGGAACAGGGTCCCTC +ATCCTCAGCCTCCTCCTGGGGGCTGCCCGGGCAGCCTGATTGGGGTGGGGGGCCCGAGAG +CAACTGTCCCCACAGGGGCTGCTATGTCCAGACCCATGGACCTGGCATGTGCTCCATCAG +CCAGGCTCAACGACGTCAGCCACCAAGCATGCTCCATCTGTGCGGCTGGGGGGCCAGGGG +CACCTGACATTGGAGCTGCCCTTGGCCAAGGCTGTCCCACCTGTGGTGCCAGGCAACTCC +CTTCCTCTGGGGGCCTTGTGATGGGGGAGAGGCTGCCCGTCCAGCACCCACCCCTGCTTC +TCACCGCCCACAGCACCCTAGCCTGAGAGGCCACAGCTTAAGAAAAGAGCTCTTTATTCC +ACGTCGTCCGATATTTTTACACAAGTAAAATAAAATGCATATCTCTATATACCGCGATCT +GGGTGGGAGGCGGCGTTCTGGAACAAACGCTGCCGCCGAACCCTGTAAACATGATGGGGT +GGAGATGGGGGTGGCGGGCGGCAGGCGTCCATCAGGGAGGACCTGGCCTGGCCTGCCCCA +CGGGTCGGCCGCCCGGCTGGCTTGGCGGCGTGGAGAGAGACCCCGTATGTACACACACCT +GGCTGCTGAGCACGCTCTTGTGTCCGCTGGGGGTCAGCAGGGCCCAAGCACTGTCCACAG +CACCAGCGCCAGGCCCAGGGGGGTGAGGCTGCAGGTGAGGCTGGGTAGGGCACCTGAGCC +TTCTGAGTCACCAGTCCCGCCACCCCCGCTGCCTGCCTGGCCCAGACGGCAGTGGCTGCG +GGTGCGGTTCTTGCGTGAACAGCCTGGCCTCCGGCGAGGGCCCGAGGTGGGGAACCCTGG +TGGCTCGGAGCCCTCGGGCCGCACTGCAGTGAGCGGGGGCTCAGCAGAGCCAGGCAGAGT +CCCAAAGGGTGAGTCATTGATGTGCCGTGGGCCAGAGCCGTTGCCCGGCGGGCTGTCACC +GGGCGGCACGCGTCCCTTCAGCGCATTGCCTGCCGAAGCTGGTCTTCCAGGCTCCAGTAC +TGAGGCCTTGTCAGCGGCATCTGGCTGGCAGCACTTGGGAAGCCCCAGCGGCTCCTCATC +GGTGGCCCTGCCGGTCCAGATGGGATGGTAAGGGCCGGTGGCCACAGCGCAGCCCTGCAG +GTCATTGGCAGCTAGGCGTTTGAGGTCACGGCCAGCCAGGCGTTGCGGGAGGCTGCAGGG +CACCTCGGAGGAGGAGCCGCGGAACTTCTGCAGCCAGGCCCAGAGTGGGCGTGCCCGGCA +GTCACACACCCAGGGGTTGTCGTTGAGCCTCAGGTACTGCAGGGCACGCAGGGGGGCCAG +GGCCTCAGTGGGCAGCGCTGATAGATTGTTGGCAAACAGATAGAGTGTCATGAGGCGGCC +AAGGTCACGGAAGGCATGCGGGTGCACATGGGCCACGCGGTTCTGGTGCAGTAGGAGACG +GTCGAGGCTGTGCAGCCCACGGAAGGCGCGCTCGGGCACGCTGGAGATGCGGTTGCCGTG +CAGGAAGAGGTGTGTGAGGTTGCCCAGGTCGCGGAAGGTGTCATCAGGCAGTGCCTGCAG +CGCGTTGTCCTGCAGGTAGAGGTACTGCAGGGCAGCCAGGCCGCGGAACAGCCCCGGGCC +CAGCTCCTGCAGGCCGCAGCGGTCCAGGTGCAGCGTGTGTAGGCGGCCCAGGCCGTGGAA +TGTGGCAGGGTCCACAGACCGGAGCTGTGCATTATCGCTGAGGTCCAGCTGCTCCAGGAG +GGCCAGGCCAGTGAAGGCAGCCGCATCAATTCGGGCCAGCACATTCGAGTGCAGCCACAG +GATGGTGAGGTTGCGGCAGGCACGGAAGCTGGCAGCTGGCACATGCGAGATGCGGTTGCC +GTGCAGGAAGATGCGCTGGCTGGCAGCAGGGATGCCCACGGGCACAGCCTGCAGGCCCTG +CTGGGGGCAGCTTGTCGTCACCTTGGGCTCATTGTAGCATACGCAGGCACCTGGGCATGG +GGCTGCCACCTGCCAGGCCTGCAGCCACAGCACCCATGCCAGCAGCCGGCTCCCTGTGGG +CAGAAGACAGAGTGGTTAGCAGGAAGGGCAGGGGTACTGGAGAAGCTGGAGGTTTTGCTA +GAGCCAGGTGGGCCCCGGAGATTGGGTCTCAGGAGGACCTGGGGCTGGGTCCAAGATGTG +GCCACCACCCCCGGGAATCGCAGTGTTGGGATCCCTGCTTCACAGGCCTCATGGACGATG +CTGGGCTAGAACATGCCTTGGAGCCATGCACTCCACCCTGGAAGCCACATCTGCAGACTC +CCCATACCACACCCAGGAGCAGCCCACTGGGTCACCAGGGGCACTCACTTGAAGGCCTCC +TGGAATGGACACTGGTGACTGCAGGTACCTCCTCAGGACTCCAGTGAACACAGAGCCCGC +ATTGCAGGAGTCCCCGGGGGGTCCCAGTGGGGGTTCCACCCACAGGGCCTAGGAAACACT +GCAATGGGGCTGGGGTCCCTCTGGGCACGTCTATCTCAAAAACGGGCGCCTGGATGCCCG +AGGGCGGGGGTGGAGGGCAAGTGTGTCCAGGGCTTAGGAGGAGTCGCGTCCCACAACCAC +CCAGGCAGCCTGCTCCCTCCTCCACACATCCTCCTTTCAAGCACTTCCTGACTTGGCAGG +AACCCTCCTGAAGCCTCCGCCCCCTGGCCTCATTCTCTGCTCCATCTCCTCCCTGGGAGG +AGTTCACTCCTCCCCAGCCAACCCCTGCAGTGCCAGCTGCCTGCACCCCTCCCACCCAGA +CGCCATCAGCAGGGATAGCCTCCCAGTGGGTTCTCCCCCAGCCCCAGGTGCCTGCAACCC +CTCCTCCATTACAGGGCCAGATACACCTGGGGCTTCACCAAGGCCCTACATGGGCAGTAG +TCCCTCCCGGGGTGCCGCATCCAGAGCTGGTCTCACCAGCGGGGTCACCCACTCCGGAGT +AAGCTTTCCTGCCTCTCATTCCACCATTGAGCCCCCACCCCTTTGGAATGCTGAAGATTC +TTTCTGCCTTCAGCAGTGAGTCTATTAAAATGTGAATCCCCCTGGGAAGGTTATGGCTTA +TCAGCTAACACTTGAGTTATCAGCTAACACCTGCGTTGACAGCTAACACCTTCCACGGCA +GCTGGCTAAGAGCAGGATTCTGCAGACATGAGGCCGGCTAAGTGCTGGGGTTGGAGCCGG +GCAGGAGGAAGGAGTGGACCACAGGCCAGCTTCCCCAACCTAGAACTGTGACCCTGGGGC +CCTCCTACCCACATGGGGCCCCTGCCCCACTGGGTCCTCTCTACTTGGGCAGACAGTGCA +GTCGCCCTAAACGCAGAGCCCAGCAAGCCCAGCACGCGCAGTGACCGCTGGGCATGTGCG +TCCTCCCAGACTCAGGTTCATAGGTCCTCAGACCCCCTCCCCACAGCCTGGGGGCCTCCT +CTGCCAAACCCCCTGCCCCAGGGCCATTTGTTGGCTACCAGGGAGATGGCAGCCCAGGGA +TGGGGGTCCGGAGGCCCCTCCCTGGGTGGGCTGGGTGAGGAAAGCACCTGGCCTCGTGTT +CTGTTTAAACTGCGGACACCCTCTCTGCTCTCTTTCTACACACTCTTCCTAGGAAGGTGG +GGCCTGACCATGTCAGCTCCCCACTGCTGTCTCACCTGCTGTCACCAGAGGGAAAACTGT +GCTATGTAAATGGCACTTCCTGTCCTGGGGCCAGGTGGGGTGGAGGCCCCACATGCTCAT +GGGGCAGGGTCAGGACTCACTGCCACATTATCGACCACACCACACCACTGACTGTGGGGG +TCACCAACTGAGCCTTGTCACCAACCATACCATGCGGCTGACTGCACCCACCAAGACTAG +CCACCCATGGTGGCCACGCCCGCCACATTACCACTGAGCCATGCCACCATCCCACCACTG +TCCTGTGGCTCCAGGCCCGAAGCTGTGGGCTGTGAGTCTGGCTGTGGTCAGGGCTCAGCT +CACTCGCCTTGAACCGAGCCCTGTGCTCATGGATCTCCCTCCCGAAGCAGCTGTGTGTCC +ACTCTAAACATGCCCCCAGTGAGGTGCCAGAACTGAGCCACACGGTGGTGCGGGGTCGGG +GGAGACAGGGGAGGACATGGGGGAGTGGCCACGTGGCGCTCAGTTCTGCCAGGAAGTGGG +TATTGGGCGCAAAGACACGGCTCGGTTCCTGCCGAGACAACTGCTTTTCGTAAACCAACT +TCTGAGAGTCGGGTGAGGTGGGCTCTCTCCTCGCTGCAGCCATGGTAATTGGCTCCAGCC +TGGCCCCCCTTGGGGCCTGCCCGCTGGTCTCCATGGCAACCCCTCTGCTGAGCGAGCAGG +AGGGGGCATCTTTTTATGAGATAATCAAACCCAACTTTGCAGCATGGGTTTGTCTTCACA +GCCGGGGCCCTGGGATGAGGGAGACGCAGCCAGGTGGGGGGAGGGTGTCCTCTGACCCCA +TCCCAGGGGCCAGACTGGTGACTCACCAGCCTCCTCCCTGGCCCCATGGTGGACTGCAGC +CCCTCCCCACCCCAAAAGACCTCCCTGGCCCGTGGCCCCTGACCTGTCCCCTGGGCTCTG +CAGCCTCAAGGCCACAAGGCCTCTCTGGCCCTCTCGCCCACCTTTCTCTCTCCTCTATCT +GCCTGGCCAACTCTAATAGGATGCTCTACTGTCCTTCTGGAGATAGCATGGCCTCCCTGC +CTGCCATCACCCCACTTTCCACTCTCACCCAGTCTCACCCTGGCCCCAGTTCTCACGGAG +CCTCCAGTATGAGCTCTGTCCTTCCTGCCCCTTGCACACGGGGTGAGCAACCAGCCCTGC +CATGGCCCCAGCTCTCACAGAGAAACCATGGATAGCGTGCCTGTCCACCGTCCCCACCCA +GGTTGGCCCTGCGGCCACCTGAGCCTGCGAGGGCCCCAGAGGGCTCTCCTCAGCCTCCAA +GCTGCACACAAACTGGTACATCTGTGCCTCTCCCACCCTCCCAGGCCAATTAACATCTCT +TCTTTCCTCCAGGGTCTCCTCCTGGGACCTCCCCGGAGGATGGCCCTGCTGGCTGTCAGG +GCTGGGTCATAGCTAGGAGCTCCTGTCTCAGCCCAGGCCTGGCTCAGGAGCCACAGTCAG +GGGAGGGCTGGCTCTCCTGCCTGGAAGGCTCTGAGCTTTCCCAGCGGGGACAGTGACCGG +ATACTGACCCAGAGCCTCTCCCTGCGGCAGCCAGACTGGGCAGGGTAGGACCCAGGATCA +CCAGGCTGAAGGCCCAGGAGGCTGGGCAGCAAACAGTCCAGGACGCATCCCCCTGACGGG +AGCAACAGGCAGCCCAGGTGGGCACCTGCACCATCAGTTCTGGTGAGTGGAGGGCTGTTC +ACGTTCACTGCAGGAGGGAGTGTGGCGGGGGGAGGAGGAGGTGGGAGGAGAGCGAGGAGG +GCAGGAGCAGAGGGGAGGGGTGGAGAAGGGGGATGGGGAGGTGGCGGTGGGAGGCTCTGG +GGATATGCCCAGCCATTGGGCAGGCAGGCGGCTGCTGAGGTCAGCAGCTCACCCCAGCAG +CCCAGGGAGCTGAGCCGAGCCGAGCAGGGATGGCCTTCTTCATGTGGTCCCTGGCCCCCA +CTGTTCCTGGGGCCCCGCCCACCTCCGTGCCCTCCCAAGCTTGGGCTGAAGTTCCACAGG +GATGCCTTTGCCTCTGCCCAGCGATGCCAGGAGGCAGCACAGGGCAGGCAGCTGTGGAGG +CGCCGAGCACCGGCTTTCATCCACGCACAGCTTGGTGCCCTCGGGCCCCAATGCCGCCCC +TGGGCTGGGATCACCGGAGGGTCCCATCACCTGCTATAAAAAGTGAGACAGCAATACATT +TACAGATTAGGAAACTGAGGCAGTGAGTGGTTAAGCCCTGCCCTGCTCCCACTCCAGACT +ACCCAGGTGGAGAGGCGGCCAAGGGAGACACTCACAGTGCTGCCCGGAGGGGCCACGAGG +CATGTCCTGCCCAAGCAGGAAGGCTGGCGGCCTGGCTAGTAATGGGGGAGGGTGTGGAGG +GGCTGGGCTGCAGGCCACGTGCAGAGGGGCAGGCAGCGCCCTCCTGTGTCATGGGTGGCC +GGGAGGGGAATCTCCAGGGAGGCTCTGAGCTGCTGCTTCCCAGGGCTGGGGTAAGAGGCT +GCAGAGGGCTGGGGCTGGGGGTGGGACCAGCTGTAGCACAGCCGGGACATCAGTCAGCTC +AGGATCCTCTCGGACACCAGCCATGTCCCCGTCAGGCGGTCACGTCACAGACCACAGTTA +TGAGGCAGAACAGGAGGCCACAGCTCAGTGCACCAAGGCCAGAAATAGCTCCAGGCGGGG +GTGGCGGGCCTATGTCATCCCCACACCACAGAGGGTCAGGGCACCCCTCCCACGCCTGCT +CCCCACTCCTGGCCCTCCACCACTGACTCACTCCCCCCGCCCCCCACCCATCTGTCCCCC +GATCCTCGCTTGCTTCTCACATGTACACCCACCCGCCATCCATCCTCAGGCCCACAGACA +CGTGCAGGGGCAGCCAGAATTCCCATGGTGTTTCCTGTGCCCTTCCAGGGCTCCAGGTGC +TGCGGCAGGAGATTGGCAGCAGCTTCTGGTGGGGGCAGTCTGCCCTTGAGGGGTCCTGAG +TCTCCTAGGGAAGTGAGTACCAGCCCCTGATGCCCTGGCCCTGGCCCCTGCTCCTTGTTG +ATCTTGGCTGCAGGGGCAGGGTAGGCAGACCAGGTCAATAACAGGCAAGGACACCTGCCA +TGGTGAGAGGTCACTGGACCCAGACTGAAGCAGCTCCAGGCCTAGCTAGCTACATGCTGT +GGGGGAAACTGAGGCCCAGTGTGGGCAGAGCCTTCAGGACTGGCCTCCTGAGTGTGCCTA +GTGCTTCCTCAGCCCCCTCGGCTCCACTCTTTGCCCTGGCCGGCAGGGCTCGTCCCTGCC +CCGTGATGCTGGGCTCACCAGAGACAACGAGATGTAGGTAGGTCCAGGGCCAGCAGGCCA +GGCCAGAGGCTGGGCCCTTCAATCCAGCAAATTCTCTTGGAGGGGGTGTCAAGTTTATTG +ACCCATTTTACAAATGAGGAACATAAGAACTGGTGTGGGTATAATCAATAGCAAACACAA +TCCAAGGTCAAATCCAACCATATGCTACTTACAAGAAACATGCCTAAAAGTACACAAAAT +CTTGCAATTAAAGATATTATCAGAAAAATAATAACAAGTAAAGCAGGAGAAGCCACAGCC +CCAGGGCTAGCGGGCTTCCCAGTCTCATGGCCCCAGGGGTGCGAAAAGGTCTTGCTGGGC +AGTAAAGGCTCAGCCACCCCCGCTCCTAACCTGAGCTCCACAGTCCTGTTTCCAGCCAGC +AGGGCACCTGAGAGGGTACACCTTTCAAGTCACAGACACTGAAGCTAGCAGAGGATGGCC +TGGCCCAGGTGAGAGCTGGCAGCCCTGGATGGCACCCTCACCCCAAGGACACATCAACGT +GGGCCACACCGTGCAGGATCATCCACTCGCTTGGCCCTCCCTCCGTACCTTGGCAAGGTG +TGAAGTGGCCCCTGTCCCAGGTGCTGTGCTGAGTGCCGCCCATACAAGACCAGGCCGAGG +AGCCGGGTCCCAGGCACTCACGGTCCAGGGCCAGCTGACCACGGGCAGCCACCCTGCTGC +ATGGCAGGTGCCCTATGGGAGAGTTAGGAGCCACAGAGGCCTGAGCCAGCCCCAGGCAGC +ATGAGGATGTTGGCAGGAGCCCAGGAGCCCACTACCAGCCAAAGGGTCTTGGCAGAGCCC +CAAGTGGGCAGGATCCTTGGCCTAGCACCTAGGCCTCGAGGATTCATCTTTGGTCAATGC +TGGGCTGCCTGCGTGGAGGGCTCCAGAACCTTGCCCCATCCAGCCCATACACCCCTCACT +GGAGGTGCACCCTCCTCGGCTCCCACCCCAGTGAGCCCCACACTGGGGGCCCCTGGAGGC +TCTGCCCAGTGGAGGCCTCGCCCAGCCCAGGGCACAGCCAGTGCCCCCTTGCCCCACAGG +AGGCTTGAGCCCACCTGCTCCTCCATGCTCCACCAGGAGCCAACAAACACCTGCTGCCTA +ATTATCTGGAGAATCCTGTCTCCACCAAGGGCTCATCTTGGTCCTGCAGCTAATTCAATC +CAGCAGCCAGAGCAAGCTGAGTCCCCAGAGGACACTAATGAGCAAGTGACCGGTGGCCGG +CCTGCTCCCACCCTGGGGACGCACTCTGAGCCAGGTCTGGGCCCAGCACTGCCATACACC +TGCCTCCCATGCCCATCTGCCTGCCTGACCCTGCCCGCTACCTGGTGCCTAGCCCTGCAG +GGCCCACATCCACTCCCATGGGCTAGCATCCAGACCTAAGCCCCAGCCCTCCCACACTCC +CCCAGGACCCTGGATCTGCTGCATGCACAAGGCTGACCACTGCCTGTGAGCCCAGAGTGT +CGGCCTTGACAGGGCAGGAGGAAGTACAAGAGCACATGCTCAGGGTGCACGAGCCAGGAG +CACAGACTCAGTGCATGCAATGGGACCCCTGGGGGTGCACACGATAGGCGTGCATACCGG +AAACACACAATAAGAGCCCCCAGGGCTGGTCAGGGCTCAGGCAGAGTCCACTGAGCAGTA +GAGGGTTGCTGGGATGCGAGCCCCTCCCAGGAGCCAGGGCCCGGCTGGAGGGTCTGCATG +CCGCTGCGGCAGAGGAAGATGTGTAGGCACATCCCCATGTGTTCTCTTGCCCTCAGCATT +TGTAAAACATGATCAACCAGGCAGGCGAGCGGCCTCTGTCCGAGCAGAATTTATTCTGCT +GTGAAAAGACACGTGTGGGTCCTGAGGCTCTTGCCGGCTTGTTCTCAGCAGCCTTGGATC +AGCCTCAGTCAGCAGAACAGCAGCTGGACAGGCTCCCATTGGAGCCATCCCAGGGACTGC +CCAGCCCTTCACATTAGAAACTGAGCTGGGGGCAGCAGCTGGCCCACGGCACATAAGCAG +TGCCTGCTAAGACCACAGAGAAGCTCAGCCAGGCAGGGCCAGTGGGATCCAGCACTCCCC +AGGGGATGAGGAATCTAAGAGGCAGGAGAGGATCCTCCTCAGCCTGGGATGTTCCCATTG +GAATTCCCCCAGCCAAGGCCAGAGCTCCGTGTCCGGGGGCCAGAGTGGAACCCTTGTCAG +AGCCGACAGGCCTTGGCCTCCTATTCTACTGGCACCTGGCAAACTGGCCCAAGGGCTGGC +TGCTGCTTCTGTAAAGGATGTGCTATTGGCAGCCAGCCACACCTATGTGTTCACGCATTG +TCCATGGCTGCTTTCCCGCAACAACAGCAGAGCTGAGTTGTTATGACACACTGTGTGGCC +CACAAAGCTGGAATTATTTAGTATCACACCATTCACACAAACAGTTTGCCGACCTGGTTT +GTGAGCAAGCCGAGTGTGGGTGCTGCCACCTTCACCCTCACAATGGCCCCAGCAGTTCAC +TCAGACCCCCACTAATGAAAAGGAAACCAAGGGTCAGAGAAGACCACGGTCCTGCTGAAG +TCACATAGCCAGGTGAACAGAGCCCAGCAACCTCAGTGCAGGCTCAGCTCTGTGGAGACC +TGGGCAAGGTCAGCATCTCACGGAGGCCTAGGGTGAGGGGTTCTAGGCAAGAAAGAGACT +CAGAAATACTGAAATACTCTGCAGGTCAAAACAGAAATGATCATTTTTCTAAAGAGGCTG +TCAGGAGTCTCACAGTCAAATATGCATAAAATAGGACAACCTAACACAAATAAGTTGGGA +GGGGTGGCTCACACCTCAGCCTCCTGAGTAGCTGGGATTACACACACACACATGCATGCA +CACACACACACACACATACACACAAAGAGAACAAAATGGTTGTAAGGAGAGGGGGACAGC +AGAGGAAGTGCTGAATGACACAGTCCGGCTTCGGAGGAAAGGACTTGGGTGGCACTTCAG +AGGAGACAAATCCAGTGCAGGTAGTTTTGAAGAGGGCAGCCGTTTAACTGAGGTAGGGGG +TCTCTGGGGACAGGGCCCCTCCATGCCAGTCCACCCACCTTGGAACCCTGCAGAGGCTGG +GCCGAGGCCTCTCCCTGCACCTTGTATCAGGGACTCTGGCCAGGTCACACCAAGGTGGCT +TATGACCCATTAACATCAAGCTGCCTCCCTGGGCTGGACAGGGCCTGGAAAGAGGTGACC +TGGGCAGATCCGTGTCGATGTACTTCCCAGGACATCAGGATTCCAGCCTCTGCTAAAGGG +ATCTTCACAGTTAATAACAAAGAAATATTAAAGATGAGAACACTTGGTGCAGGAAACAAG +AGAGGAAAGGGAGTGCGGTCCCTCCTTGCAAACAGGATGCCCTGGACCACCCTCCACGGC +CTCAGGCCTGGATGCTCCTGCAGACCCATAGCCAAGATTGTGAAGGAAAAGTAGGCTGTG +GAGGCATTTTCTGTCCTTGTTATCATCATTGTAAACATACTCATCATCACCATCACCATC +CTCATCACCATCACCACCACTATCACCACCATAATCATCAGCAGCAGCATCATCACCATC +ATCACCACCACTATCATCATTACCATCCTCATTACCATCACTATCACCACCATCATCTTC +ATCACCATCCTCATCACCATCACCATCCTCAACACCATCCTCAACACCATCATCACCATC +ACTATCATCATCACCATCACCATCCTCAACACCATCATCACCATCACTATCACCACCACT +ATCATCCTCATCACCATCCTCATCACCATCACCAGCCTCAACACCATCATCACCAACACT +ATCACCATCATTATCATCATCACCATCCTCATCACCCTCACCATCCTCATCACCATCATC +ACTATCACTATCACCACCATCATCATCACCACTATCCTTATCACCATCATCATCCCCAGG +CGACCAGAGCAGCACCATCCTTATCCTCATCACTATCACCATCACCATCACCATCATCAC +CATCCTCATCCTCATCACCATCATCCCATCACTATCATCACCATCCTCATCACAATCACT +ATCATCACCATCACCATCCTCATCATCACCATCGTCCTCATCACCATCACCGCCATCAGC +ATCCTCATCACTATCATCATCACCATCCTCATCCCTGTCACCATCATCGTCTTCATCATC +ATCACCGTCATCATCACTATCATCACACCAGCTCTGTGCAAGGCCCTTAGATAAAGGGCA +GCCTGGGGCTGACCTCACACAAGGATAGGAAGCCCCAGGTGAGCAATGGGTCAGTACTGG +GTCGACACCAGATATCCCTGGGCAGAGGCCCTGGCCCAAGGATGGGGAAGGGAAGAGGAC +AAGGGATGGGGAGTAAGAAATGAGGGCCCCTCGCCTCCCTGGGACAGCCCAAGGTGCAGC +CTTTCCTCATTCCTGGAGGTTTCAGGATATCCCTGTGCTGCATCCTCCCATTGTACGGTG +AGGGGGTGACTGCCAACCCACTCCTCAGATGAGGCACTGACTGAGGCAAGTGCCTTGCTG +GCCACCTTGCAAGGCCAGGAGACAGTGCACACAATCTGGACTCCAAGATCTCTGCCCACC +CCCATCTTCATCACCACTATCCTTATCACCATCATCATCCCCAGGCGACCAGAGCAGACC +CTGAGCCCCAGGGATGACACAGCAGGGAGGGGCAGCCACTCTGGGCTCCCCAGTCCCCCA +TGGCACCTCAACCTCAGCCCAGGAGGCTGCCCTCCCAGGGATGGCTGAAAGTGGGCCCTG +GGGTCTTGCAGCCCTGGGCTCAGATGTAGCCTCTGCACCCCCTCACAGAGTAGGCAGAGA +ATCTGCCAGCCCCCTCCAAATCTGTCCCCACACCAGTGATGTGAGGACAATGAGAGGCCA +GCACCTACCTCCCCCCAGGACCCCAAAGAAACCCCACCCAGGCCCCCACCCAGCATCCTG +CCTCCCCAGAGGCCTGCCAATGTGACCTGGGTCAGCCTCGTCTCAGGTGAGGAGTCCAGG +GAGGCAAGGTACAGCTCACAGCGTCCCAGAGCCACACGGACCCCTCTGCTCCAGCGGTCT +TGCAAGGCCACTCTGGCCTGGCCTGGCAGTAGCCCTGCTTTATTGAGGAGATATGGCAGG +CAGGATCCTGGCTGCATCTGGGCTGGAAGAGGGGGCAGCAGCCAGGCTGTGCTACAAACC +CACCTGGAGCCACTTCCTCGCTGCTTCTGCCCATCTCAGCCTCAGCAGAGAAAGAAGGCT +TGAGGACAGGCCTGGTGCAGCCTGACTCATCTCATGAGAGACCCGGCCTGTGCTCAGAGT +CGAGTTGCTGTGGCTTCTCATGCAACACTGATGGTCCCCCTCCCCTGCTCACCCACCATG +TGTTAGACACGGGGATCTGCATGAAAGACACGTGTTCCTCCCCTTCCAGAGACCCACCGA +AATGAGGGTGATGCAGAGTGAGGAGTGGGGAGCACAGTGGCAGGCTGCTCCCCTGGAGAA +ACACCCAGAGAAAGGGGTTCCACCACTGGTATCCAGGAGCACCCAGGGCCGATGGGCAGA +AGAAAAGCTCCATCTCAGCAGAGCAGCCAACCAGCTTCCCTCATAAAAGTGACCAGAAAA +CCAGTGACCACCAGGCATCCGGAAAACATATCAATGCAGAAAAAGAGGGAGAATGATGCT +AGAGGAAGCCGACAGTGTGGGAAAAAGACAAAAATTAGGAGAAACATCTAATTTGTGTCT +TCCTAGGCATAGATGGGGATTTAAAACAAGAACAGGCTGCTATGAACAAGGAGGCATCAG +ACAAAAAGAAAGAGTGCCTGGAAATTAAAAATAGAATCACTAAAATTAAAAAAAAAATCA +ATACAAGTGTTAGAAAACAAGGTCAAAGAAATCTTCCAGAAAGAAAAACAAAGGAGAAAG +ACAAATGAATGAGATTTGGGAGACAAATATAGGTTGAACATCCAAGGGGAGTTCCAGAAG +AGAAAACAAAAAAACTGAGAAAAGCTAGCAAAGAAACAATACCAGAAAACTTCCCAAAGC +TGAGTACCCAGTCCTCCACTGGGCATTCACAGTGCACTTTCAGGCCCCCAGGGGTCAAGG +GAAGTCTGAAGCTCCAGGAGGAGAAGCTGGTCACAAAGAGGCAACACGAAGCCATGAGCA +GCAGTGCACGCCGGTAATCCCAGCACTTTGGGAGACTGAGGTGGGAGGACTGCTTGAGGC +CAGGAGTTTGAGACCAGCCTGGGTAACACAGTAAGACCCTGTCTCTACAAAAAATTAAAA +AGTTAGCCGGGTGTGGTGATGCATGCCTGTAATCCCAGCTACTTGGGAGGTTGAGGTGGA +AGGATTGCTTGAGCCCAGAAGTTTGAGGCTGCAGTGAGCCATGATCATGCCACTGCACTC +CAGCCTGGGTGACAGAGTGAGACTTTCTCCAAAAAAACACACAACAAAGAAGATGCACTA +TGGTATTGGCCTCCTTCATAGCACACTAGATGCCAGGAAACAACAACACTGCAACAGCTT +CATAGCTCTGAGGGGAAACTAATTTCAACATGGAATTCTAGACCGAAACAATCCAGCTTG +AACATACTTGTAAATACAGGAAGACTTCCGGAATGATTCTTCACCATATCTTCTTTAGAG +AGTGAGTCAGGCTTATGTTTCAGCCAAAATGAGGTGCAAACCCAGAAAGAGGAAAACGTG +GGGCCCAGGAAGCATTAACTGAAATTTCAACAGGTGGTAAAGGGAAGTTATGGGGCAGCA +GGACAAGTGCTTGGGGTGAATCTTTATCCAGGGAAAAAAATGAGACCCCAATAGAAGCCC +TGATGTGGGGAAGAGTAAGCCCATGAGGGTGGTGGATGGGTAAAAAACATCAACTGTAAG +CCCCAAGGAAAACAAAAGGCCATGAAAGAGAAGGAAGGTCACCCATCCCACGGCAGGATT +GAGAAGAACATTTATGGGACCTGGGTTGGGAAACACTGGCTGTGAATTTAACTGATGGCA +GCGAGACAGCCATGCTGGGGAGTGTGCTGGAGGAGACAGAGCTGGAGTAGAAGCTGAGGA +AATGTGGCGGCAACCACTGGCAAAGCCAGGGAACAGAGGCGACAGTGGCTGCCTCCCAGG +AGGACGCGGGGCAGGGGCAGATTGAGCCCATTCTCCAGACCAGCCTCCGAGGCTGGGTGC +AGGTGTTAACTCTGCAATATGTTGTTGACCGAATGTTATTATTTTTTAAAACAACTGCAT +ATGTGGCACTAAAATCTCAGAAAACAGATAAATAAAAAGAAAAAAAAGAAAGTGTATCTT +CCAGAAGGTGGAGACAAATGTAGGTTAGAAGCAGGTGTCTCCAAGGTGCAGGAGGAGAGC +GAGGGACAGTGAGAGCTCAAGAGCACCTGGACATACAGCCCCAGGGCAGCTGGCATCTGG +CCAGGGAGGATCCACATGCTGCTTTTTGGTCCCCTGCTCGGCCAAGGGTGGCTGAGGATA +CATCTGGGTCTCCCAGGACACTATGGGCTCTTGGCCCCAGAGACTCTGCAATCCAGACAC +CCGAAGGGGCAGCTTCTGGCCTAAAAGCCCAACTCTGTGCTTGGGCCTTCCCTGCAGGCC +AGGCAGCTGCTTCCCTGAACCAGCCTCAGAGTTCCTGCCTGCCCACCCAGCCCAGCCCTC +ACACTGTGATGAAGCCCCACCCCTGGATTCCCCTTACCCCTGCCCGCTCCTGTCCCCTCC +TTGTCACAGATCTGAGCCCCCCACTCCAGGCTGGGGCCCCTCAGGAGCCGGGGGTAGGGG +TGTGCGGTCAACACCCAGCAGGGGTCGCCTAGCACTGGGGTGGGTGTGCAGCCCCCAGCC +TCCTTTCTGACCGTGCACACGGGCTTCTCTCAGCTGCTATGAGAGCCCCCAATGCGTCTC +CACAACCAAACCGAGGCACGCACGCAGCGGCGACGTGAATAAGTAATTGCTCTTTTATTA +ACAAGTGATAAATTATTCCTATATGATTGTGTGTGATAACTCTTCCTTATTTGAAATCAA +TTTGGGATGGAAACTGTTGTCGGCTTCTCATCCACGAGGGTGGGAGGCCCAGGTGCCGCT +GCCTCTTGGAAAACGAGGTCAGTGTATTTCAGCTACTTCCTGAGGCTGATGCGCCGCCCC +ACTGCGCAGGGCCAGTGGAAGGGGGTCAGCTGCCCTCCGGGAGGCGGGGCAGTCCGGCCT +TATTTCCTCAGCATCTCTGTCTGGGACCCACGCCACTGAGCCCAGGGCACAGAGGGGTCC +CTCAAGTCCAAGGCCACACTGGGCGTCACCACAGGGTCATCAGGGGTCAGGGGGCCATGC +ACAGGCCATACTGCATTCATCCCCCCATGTAAGCCCCAAAGACTGGGCAGCCTGACCTTT +CATCCCACAGAGGACACTCCAGCACCCAGCTGGTCTCCTGGCCTGCCCGGGCCACCCCAC +GGTGGCTTCTCAAACCTGCAAAGGCATAAGCCATTCTCCTAAAATTGTCCTGATGATTTT +ACAACAGCCCTGGCCCCATCCCCTTTTCTTCCTCCCCCAGCCTCACAGAGGAGGGTTCAG +GGACTCAGCCTGTTCAGGGCAGCCCCTGGGCCAGGCCTCAGCACCTCTTCTGTTAATGCA +TATTTAAAACCTTGCAACCCACCGGGCAGCCAGCCAGCCGGTGCCTCCCTCCCAGGCCAG +GCCTGCAGGAAGCCATGCCCCGTCCCGCTCACTCCTCCACTGGCTGCTTCTCCGACCCCG +ATCATGGCTGCAGCAGGCCTGGAGGCCCGGTCACCCCCAGGCCCAGTCACATGGCCCTAC +TCAGGCACCACCTGTGCTTCTTGGCTGGGTTTCTCATCTGAGAAATGGGAAGGCTGGGTC +TGGGTGAGGCACTTCTGTGGGCCCACTCCCACGGTCTCCTTGACACCCCTCCACCTTCTG +CCCACTGCCAGGGTGCCCATTCCACTCCACACCTCGCTGGCCCACTTAGCAGGCTTCTGT +GTAGCTTGTTTCTGTCGGTTGAGGCACCCTGGGCTTTGGGCTCCACAGGGGCTGGTGACC +CGCATACAGGAGGTGCTCCATAAATGTTAGTCATGTGAATGCACTAAATGCTCACCACTA +AGGGCAAGTGGCAGGCTTTGTGCAGCTATAGAGACAGCATTCCCCAGGATGTCCAGCCCT +GGGAGAGAGCCTTGGCCCACAGCCCATGAGGCAACGGATGTTCCTGGGTTGGGGGCATGG +CTCCAGCACCCCAGTGCCAAGGGCACGGTCTCTAAGTAGCAACATGGATAGCTTTACTTC +TGTTACAGCTCCATGTCTGCGTCTCCCCCAGATTCACGTGTCGAAGCCCTAACCCCCAGT +GTGATGGTATTTGGAGGCGGGGCCTTTGGGAGGTGATTACGGTTAGATAAGGTCACAAGG +CTGGGGCCCTCACCATGGCATTAGTGGCCTGGAAGAGAAAGAGACCTCAGAGAGTACATG +CCCTCCTCTCTCTCCACCCTTCCATCCCCTACCACGTGAGGGCACGGTAAGGAGGTGGCT +ACCTGCAAGCCAGGAAGGGAACTTCCACCAGAACCAGCCCATGCTGGCACCCTGATCTCA +GACTTCCAGCCTCCAGAACTGTCAGGAAATGTGCTTCCGTTGTTTAGGACACCTTGTCTA +TCGTATTTTGTCATGGCAGCTTGATCAGACTAATACAACTTCTTTCTTAAAACTTTGGTG +TATTTTTCCAGATTTTCTACAATGAACATGACCTCATAAAATCAAGAGTGTTTTTCGTTT +GTTCTGTTTGGTCTTATGCTGACACTGGGCCAGGTGGAAGGGTGGGTGAGTCCGTCTTGC +AGGTGGCAGGAGCCCCCTCCATGAGCCCCCACACCCCAGGGTCCCTGCCCAACGTGATCG +GCCCTGCAGGGCAGTCCTGGAACCAGTTCAGGGCTTGGGGCCCTGGCTCTGCCTAGGGAG +GTCTCAGGCAGGCCCCCCAACGTCTCAGAACTGCTTCCCTCAGTTGGAAATGGAGATAAT +AAGGCCCACCTCATGGCACCCACAAAGAATGGGGCAGCCTGCACCTGGCCTCTCCCTGGA +GGACCTTCTCACATCACCCCCGGAGGGACCACCATCCCCACCCCACAGAGGAGAAAGCCC +AGCTCCAAGGCCAAGTTGCAGCCAGGAAGTGCTCTGCTGGCATCCTACCTGGCCCTGACG +CCAGGCCTGAAGCCAGCACCACCCGGGGCTCTGTTGCTCCAAGGCCATTGCCCCTGCTGG +CGTTTGCTCAAGGAGCTCCCCCTCCAGAATGCCCTGCCCTATTCCCAGACACACTTCCTC +TGGGGGGCTCTTCTCCCCCAGCCCCACCCCTGCCACCCCTAAGGAGGCTGGCCCCTTCCC +AATCCCTTCCTCGTCTGCACCACTGCCTTGCCCAAGGTGTCCATCCTCAGACCCAATGGG +GCCACCATGGGAGCCCGGCTGGGTAATGGCCCATAAGCTCCTGCCCATGGAGTACTCAGG +CAGGGAGGGGCACAAGCTTGGCTGAGCATGAGTGACAGGCTGGGTGGGTCTCAACCTCAC +CCTGGGCCTGGGGTAGCCCCTTGCAAGTGAGGATGTTGAACACGGTGGACCCCCAGGCAG +AAAGTGAGCCACGGGGGGCTATGCAGGACTGCAGCCCTCCCCTCCCCTCAATTCACTGGT +GAGTAGCCTGCTACTCCCCTGGCTCCCAGGGCAGGGCCCTCATCACCTCGAGACCCAGAA +GCAGTGATGGAGACCGTCCTGCAACATCAAGCTCCCTGTGATCTGGGGGCCAGGGGATCC +TGAGTACCCTGCCTCCTGGAGTGCTCTGCCTGCAGGGGGCAGTAGCAGCACCTTCAGGTG +GGGTGGTTGGGGTGGCTTCCCGGAGGAAGTGATAACTCAGCTAGGAGTGGGGCGTGGGGG +TGGTCCTGACATGTACCAAGGCTGGGGGTCAAGTGTGCACTGTCTCTCAGCCAGGAGGGT +GGAGGCGCTGGACCAAGGCTGGGGGTCAAGTGTGCACCGTCTCTCAGCCAGGAGGGTAGA +GGCACTGGACCACTGGGGCCTCAGGTGTCCAGGTCACTTGTCCCTGGAGTCCCTGGCTAT +GACAGAGGCCCTGGTGGGCAGCTCGGGGTTGGGGACAGGCCAAGGCATAGGGGAGGGCAC +AAAGGGAGGTTGGTGCCCCACCCATCACCCATCATCCGCCTCAGGCCACCCCAGGGGACC +GGCCTCCGCTCCGGCAGCGGGTGAAGAATGGACTCCATTAGGGCCGCCATCTGTCTCAGC +CATGACGGGTCCTCGCGGTGACATCCGGGAGGTATGTAGATGGAATATCTTTATGGGGAG +AGTTTTTCTTTTGCCAGTTTTCAAATAGGAAGCCAGACACTTGTCACACCTGTCCCTGTG +TCAGCCTCTGCCTGACATAAATTGGGGCCGAGGCAGGGAGATGAAAGACAGCCTGGAGGC +AGCCGGGTGCGCAGGGCCCATGTGTCAGGCCGAGGGAGCACCAGAGCTGCAGGCAGCCTC +CTGCTGGGGCCAAGGAGAGCTCGCCCCGCAGTCCACCTCCGCAGCCTCTGCCCCTCCCTC +CACTCCCCTCTGGACCCACAAGTTCTTCACCTGCCCTCCCCCAACCCAGAGCCCTCCAAG +CATCTCACCCGGGCAGTGGCCTGTCCTGCAGCCACTGGGCTTCTGTTAGGGGACACTGGA +GCCTCCTCAGCCCCCAGGCCAGCAGCTCCAGCTCCTCTTCCAGACCTGGGGCCAGTGTGG +CTTTCATGAGCGGTCAATGTGGGAGGCTCAGAGTCCTCAACCTCACCCCCGCTGCCACTC +CTAGGGACCTTGTGGGCTTCAGCATGTTTCCCTGGAATCTGGGGGACTTGGGGGTAGAGC +ATGTCAAGAACCTCAAGGTCCCTGCCGCCCAGCATGGGACTATCTTAGAACTGATGCCAG +GAAGAATTTGCTAAGAGAATGAAGGGAGAAGCAAGTGACCCCTGTGGGCCTCCCCTGCAT +CGGGGACTGGACCAGGGCCCACTGGGAGTGCATCTTGGTGCCTGAAACTGCACCAAGGAT +GAGGAGGGGAGGACCCTCCCCAGGGGACACTTGGGGTTCACCTGGCAGGCCACACTCAAG +TCCACAGTCCCCCATGGCCCCAGCGGGTGGGGCAGGGGACGCACCCAGCTGAGGGAACTG +TGGCAGTCCTGCTGTTGTCTCACGTGGCCCTAGGGGGCTCATCTGTAGCCCCCACGGGAG +CCCCAAGAAGCCAATCCCTGCTGGGCTCATGGGCTACCACCTCATACAGCCCCATCCCTC +GGGAGGCCCTGAGGAGACCCTGGGGCTGGGCAGGGCGTGACCGGCCAGCTCCATGCTTCC +TGACAAGGGGGCCTGGATGTCCAGGGAGAGCCAGGAGGGAAGCGGAGACTCAAGTGGAGA +GTGTGTGGGAGGGAACGTTGCTGGGCTCCACAAAGGAGGGGGCACCAGGGCTGACTCCCA +GGTTCCTGGTGGCATGCGTGGAGGCAGGTGGGGCCAGGAGCACCAGCGCAGCACATCCTG +CGTGACCTTGGGCCAGCTCCTCAGCCCTCCCTCGACAGCCGTGCTGGTAGCTGGCCAGGC +CCGGGTGAGTGAGTTCCCCAGGTAGGTGGAAGGGGCTTCTGGGGTAGGGGCCACGCCCGG +GGGCAGGTGGCCCACCCTCCCAATACCCAGTCCCACCCCGCCCTACCACAACTGAGGACT +CTGCCCAAGGACCAGTCAGGGACGAGGCATCCTCTCCAACTGCACTGCAAGGCCAGCACA +AGTGAAGGGCGGGACAGAAGCCTCCACACAACAAAGGCAGAGGACCCCATACTTCTCTCT +GAGTCAGTGCAGAGGTCCTGCGGCAGAGCTCCTGCTGGAACCCAAACTGCGCCGTAGGCT +CCTCACTGAGAACTAGGGACTTCTCCACATGCACCCAGCCTCCCCTCCGGACTCCACAGC +TGCTAGCCCTGCCCGGACCCTGTGCACCCCACTCCCACCCCGTCATAGCCTCTCAGCCCC +ACTGTCATTTGGGCTCCCCTGGCATGAACTAACGTGTCTCTCAGGATGTCCTACGAGGAC +CCTCACGGCAGAAGGACCGATGGGGAGGAGTGGCCCCAGAGAGCAGTTCCTTCTCTGTAC +CCACCAGGGTTCAGCAGAGGCTCCTGCTCCAGGCAGTACAGTGGGGCCCACATGCCCATC +CTCACTGGCCACATGGGCTGGTCAGAGTCCAGCCTGGATCCCCCCAGGGCAGGACAGGAC +AGGTAAGAAGGGCTGAAAACCTGGGAGGCCTCCAGGAGGTGAGGGACCTGCCACCCCTTC +CCACAAGGCCCTAAGGCCCCAATCACTAGTCTCGATTTCCACAGCTAGTTTAGTCCAGGC +CAGGAAAGGGCGTGCAAGGGGCCTGGCCTGGAAGAAGGGGTCCCTGGAGCCAGGTGCACC +AGGAGCCTCCAGCTTGCCCAAATCAAGCTGCCACTATGGCCGGGTCCTGTGGGCAGTGCT +CACTCACCACCGCTCCAGCTTCACGATAGCCACGTGCGGACAGGGAGGCTCAGAGGGTAG +GTGGCTCCCCGGGGGAAACAGAGCAACCCTTGTGCAGCCGGCTGGGCCAACTGATCTGCA +CCTAACAGCCAGTCTTGAAGGCCACCAACCCTGGGGTCTCCCGGAGCTGACCCAGGGACA +GAAGGGCACCAGGCACTGCCCACAAAGGTGCAACTGATCCTCCTCACCGGCGCCTGGGCC +CTCCCTCCCTGCCAGTGTGGCTGTCCCACCCTTCATGGCTTTCTGCATCCTCAAGCTAGG +CCTGGGCTCTTCAAGTGGAGAGGGGTAGGCAGACACAGGTGCCAGGCACTGGGAACTAGG +GACGGGGGCTTCCCTGGTGAGGATGGAAAAGAAGGTTCCTACATGAGACCCTCTAGCCCA +GGCCCTGAGAACGAAGGGGCCAAAGCTTCACCTAGGGGCAGCCATGGGGGAGTTTAGGCA +GGCAGTGCCTGGCTGGAAACATGTCTTAGGGAAGCACTTGAATCCCGGGGTGGGGAACAA +GATGGTAGGCAGGGAGCCGGGGCCGGCTGTGGCCACAGGCCGGGGACAGAGGCCAGGTCT +GAGGATGGCCCTCAGTGAGGAGTAAAGGGGATGGACCGGGAGACAGGGTGCAGGTTTGAC +ACTGATTTTGCCTTTGGGGATGGGTCGAGGGAAGAGGCTGAGACTCTGGGCTTGGACGTT +GGGTACGGAGGATGTGACACTAGCAGACAGGCTGGATCTGGAGGCCCAAGGTGTGTAGTG +TGGGGAGCTGTGTGTGCAGGAGAGATGCAGGGCACTAGGGAGCCTGAACCCCTGCTCCAG +TGCACAGGCCGGGCACACGGCAGGGAGGAGGCAGTCACCATTCCCTCACTTGCCGGGACC +TGGGAGGCAGGGCAGAGTGGGTGATGGGCCAGGCTGGGGCCTTGGAATGACATCTGGCAT +GTGGCAGCGGAGGGGGGACATGTAACTGGGGACTGTGGACTCCCAGCTGGAATCCACCTC +CACCTTCCACATCCACGCACTGCATTTTGGTCTTTACTGAGCACCTGCTGTGTGCAGGGG +CTGCTCTAGCCCCTGGGACCACCAAGGGCCAGCCCTCCACAACCCCAGACCTGCACTCAG +CCCCCACCCACTTCCTCCAGAGCCCCACACCCCACACACTGAGGACTCTAGGCATTTTCC +CACTCTTGAAGACACTGAGCTGGGAACACCACCTCTGGCTACCAGCCGTGGACTGCAGAG +AGGCCTACGGTGACCAGGAAGGGTGGAGCTGCCCAAGGTCACACAGCAAGCCAGCACTGC +ACAAGCTTACCCATGGCTGCCCAGCCTTGGGGAATGGGGGACTTCTGGCATGTCCCCGAG +CTGGGCCCTGGCAGAAGGCAAATAAAGGCAACATCTCAACAAGGTTGTGATAGCCGGGGA +TCCAGGCAAGCAAGGGACAATCCAGGAAGGCTCCCAGGAGGAGGTGAGGGGCCTGGAGCC +CACCCTGGCCTGAGCCCCTCCTTGGCACTCCAGCCTGCCTAGCCCTGCCCCCTTCCTTGA +CGGGCCCCTCACCCAGCCTCAGCCTTGGCCTGACATTTCCCGTGACATTTGCTGCAAAGA +AATAGAGTCATAAATCCAAAGGTTAAATTTGCACATCGCCTCAAATTGCTGGGAGAAGCA +GTGGTCCCTCCACCCACTGGGCGCCCCGTGGGTGCGGGGTTTGTGTGGCAGGGTCTACCC +ATCCCAGGGCCCTTGCTGGAGGCCCACAGGTCTCCTCCTCTGGTCCTCCGGGGCACTTCA +ACCACTGTTTCCCAAAACAGGTTCCTGGGCACACCAGGCCCTGAGGTACATCGCATAGGG +GTGCCTCTCAGAGAAGGTGCTGCCCACCCCTCTCCAAAACAGGGCCCAAGACGCCCTGCG +GGAAAGGAGCACCATCAGCACCATTTATTCCAGCAGGTCCCACATTTGACCACAAAGCCC +TTATGTGATACCCCCAACATTCCAAAGAATTTCAACTCCATGGACCGTGACCCGTGACAG +CCAGCTAAGAATGCCAGGGTGCTGACTGGAGAGCCAAGAGGCACCCGGGGGCCCAGGGCA +GGCTGCTCTGAGTGAGGCTGGGTCAGCACCCGACACCTCACTCCCAGATCAGCCCAGCTC +CATGTGCCAGGGCCCTGAATGGGGCTTTCCACCTGCCAGGCCTGTGTAGACCTACATGGG +GACCCTGGCCTGTGCCCACTCAGCCCCTCCTAAGGCCACTCTCGAGGTGTGCCAACTGCC +CTGCCTTTCTTCTCCACCTCCTGGTCTGGCTGCTGTGGGTTGCCTCCATCGGACAGGACA +CAGCTGCGGAACAGTGTCAGCATCACCCCATGCCCCGCTGCCCTGCTGCCCCGCAGAAGA +GGCCCCGCAGGCCATAGCAGGCAAGACCAGAGGCTGTATGAAAGAGGCAGGGGAGAGGTG +GCCCCAAGGCACCCACTGCACAAATGGCTGCCCAGACTCTACTCACTCACCATCACCTAC +CCGGCCAGCCCACGGTTGTCAAAGCCTCAGTGGGCTAGGAGGGGCAGGATCTGGCCCTGC +TGCCGAGTCCCCTGAAATCAGCCCAAGCATCGGGGGAGAGGCACGTGACCAGACCCCAGA +CCTGGTGGGTGCCAGCTGAGGACATGGTGGGGTGGGTGTGCAGAGCTGCATCTCCCAGTG +TCCAGCTCCACGGCTGCAGGCAGTGCAGGAGGCCGGTGCAGGTTTGGATAAATAAATGAT +GGTGCATTCTCAGGAAGGGATTCCACACACACCAGAAAACCCATGATGCACAAGAATAGT +TCCCGATGTGCAAAATGTTTAAAATACAGCGATAAAAGAAGAAACGGCAGCACAGAACAC +CTGGTGTGGGGGAGCCCAGCTGGGCCCCAGGGACAGTGCAGGGAGATTTGTGGGGTGGGG +CAGCATGCCCGCCGCTCCGATCGGGCTTCCCTGGGCCACTCTGTGACCTCCTATCCTTTA +AAGCATTTAATCCTAGAGATGCCCGATGCCAAGGATCACACCCCTTGATTTGCCTGGCTC +AGAAGAGAATCTGACAGGCTAGGAACGAACGAGTGAATGAATGAACAAATGAGAAAGTGA +ATGGATGGTTGGGGCAAATGCAGCATCTGGGATCTGGCTTTGAGGAGGGTGCCTGTGACC +TTGGCCTGGGTGCAGCCAGACCGCAGAGCAGGGACACTGAGGGGTGCAGAGAGGGACCCG +AGAGGGCATCTGCACAGCTGCAGAGGCAGCAGGCGGCCAAGCCAGCTCCCGCAGACCCTG +AGGCCCAGGCCCTGGGTGGCTGCAGAGGGTCAGGCAGACCAGCCTGGGGGTCAGAGGTCA +GGCTCACCAGAATGGGGGCGGGACGGCATGAACCTCATTGATCAGATAGTAGCCAAGTGT +CAGGAGCCCTCACTAACCCTGTGCCAGGGCCGGGCGGGGCGCCTGGCTCACACACGCATT +TGTTCATTTCCAGGTCATCCTGAAACTCCCCGTGTGCTTCCTGCTCTTGACCCCTTTCCC +AGGTGCACAGACCAAGGCTCCCGGTGAGAGGTTCCGGGCCACAGGCCCAGGACAGCAGGA +GGGCTCCTCTGCCTCCCGCCCGTCCTGTCCTCACCAGCTGGACCCTCCTGGTGTTGCACC +GGCTGCACAGGGCCGTCCGTGCCACAAAGCATGAATTCAAGGCTGGGGCAGGGACGAGGA +GAGGGCAATGCTACAAGGCTGCACTGTTCCTGGGCAGAGGGAGGGGGAGAGCACGGTCCC +ACACACCCTGGCCCTCACAGCCTGCCTGTCACTCACAGCAACAGCAAACAAACCCTGGCC +CCTCCACAGGCTGTGGGCCAGTTCCCAGCCTCCCAGGACAGCAGGACCTTCCCCCACCTT +CCAGGGCCCCAGCCCCTGTAGGGGTGTCCTCCATGGACCCTCCACAAGCCCTCTGGCTTT +CAGAGACGTGCTGGGCCAGGCCCTCCCTCAGCCTCTCCCCTGCTTCTCACTCCATGCAAA +CCTACGTTTCTGCCAGTCCCAGCAGAAGGACCCTGGCACGGGGAAACTGAGGCTCAGGGG +TTCCACAGACCCCCAGGTGAGGAACAGGGGGAGGGCAGGGAGGGAGTGAAGGTACTATGG +GAGGGTCTCCCAAGCTGGGCAGCATCCCTGCCCTGTCCCCTCTCCACTCACCTGTGGCCC +GAGTTGCCTGACTAGGGGCTTTTATTGTCCCTTCTGCACATGGATGGGGTGAGGGGCCAG +CTGGCAGTGCAAAGGTCCCAGGAGGACTCTGCTGAGTGGGGGTGTGGGGAGGTGTTGTGG +GCATTCTGAGGCAGAAGCACCAGAGTCAGAACTCCACAGGGAAAGCCGGGCCAATTCCGC +CCAGCCTCAGCCTGGAAGTGCCCCGATAATCCCTGACCACTGGCCCATGGTGCAGGTGAG +GAAGACTGAGGCAGAGAGGCGACCTGTCACACCCAAGGTCACACCGCCAGCAGGTGGCTG +AGCCAGGACCCAAATCCAGGTCACGGTTCTGCCACGGCAGGCCCTGCACGTGCCCCTCTG +CCAGGTGGCGTCTAGGTGCTGATGGCCACCCATTCCCACCCCCGGCATGGGAGCTCACTT +CCTCCTCACCTCAGTAGAGAAGAACAGGGAACAGTACCCCCTTTATAGATGGGAAGACTG +AGGCTTAGAAAAAGAGACTGGCCAGCCCCACTGCTTCAGCTGCCCCTCTGCTAGTATGTT +TCACCCTCACACAACCTACAAGGATAACCTGCTGGTCCCCACTCTATAGATGAGCCTCTG +GTGGTGGCCAGGGGAGCAGGAGGTGTGGCCTGCCAATCCAAGCCCCAGCCCAGGGCCCTT +GCCACAGTGCTAGTGGGCCACCCTTGCCCATCATGCAGCATGGCATCCATCTGCTCAGCA +CCCTACACAACACCGGAGGTAGGGGAGCCCACCACAGAACCCCTCACCAAGAAGGTCCTC +ACCATGGAGAAACTGAGGCACTGGAGGCGGGGCCTCTGCAGTCACGCTGGGTCACGTGCT +CCAGTCAGCCAAGCTGCAGCGGCCACCAAGGGTGCCCAGGGTCTGGCCTGTTGGTCACAG +TGTTGACCTCATGGCCTGAAATGGGTCTTCCCTGCCCAGACAGGTTCCAGCCCACCATCA +TCTATCTGCCTCAGCCCTGGTGGGTAGGGAGTGGCTGGGAGACCCTGCCCCTCACACCCT +GGGCTTTGCGGTATTCAACGAGCCCCCAACACACATTCCAGGGCCTCTGCTCCAGATTAG +GCCACAGCCTGTCTAGGCACACAAGGGGCACCCACACCCTGGAGGCAAAGAGACATGCCT +ATGTGCCCGCAGGCACACATGATCACGCGCACAGACACACGTGCAGATGCATACCAAGTT +ACACACACGCACACAAGCCCGAGGCGGGGACCCCCAGGACACGGAGGCAGGCAGGCAGAG +GTGGGGCCCAGGATGTCTTGCCCCTGTCTGTGGGCCTGGCCTCCCCACTCAACAGACGAG +CATGTGGGTGCGGGAGTGGTTATTGCGAAAGGGGCCCCAGCATGTGCCACCCGTGGAGAC +CACAGCAGGCATGCCGCGTGCATGCATGTGTGGCCGTGGGTGTGCAGGCGGGGGCGAGGA +CACAGATATGCACCCTCAGAGTCCGTGTGTGCACCCAGTGTTTGTGCATGTGCACACTGG +GGCGGCGTTGGCTTGCATGTGCACCAGAGGTGTGCAAGTGTGCAGTCCGTGTAGACAAGT +GCACGTGCAAGGAAACGTGTGTGCAGCCTGCGGCACCATGGACATCAGCAGGGCAGCCTG +GGTGGGCACCTGGGGAGCACCCTCCAGGCGGGGCATGCCCAACTCACATGGAGCCCACCC +TCCCTTGCCCGCACCGCGGGACCTCACAGCCGGTGGGGCGGGGGAGTCCCACGAGGGCTG +CTAGGGAGGGGTTGCTGATTGCCCCACCGCCCCTGATTCCCCCAGCCAAGCCTCTCAATG +TCCCTCGGGCTGCAGATGGTGGGCGTTGCTGCCTCCTCTCACCGCCCGCCCTGGAGGCAG +CGCTGGGACAACCCTGTCCCCCACGCCCTCTACTGCCGCCAACGCCCCCATTCATCCCAC +TGTGGACTGACCTCGGAGAAACGGGAGGTTCTGAGCCCAGACCGTGAGGCTGGGGTGGAG +GCGGCCCGACACCCCCACCCACCCTCGGTACCCACGTTTCTGCAAAAACCCGCTCGTTAA +CCCCTTGGTGGCCGGGGCGCTCCGAGGCCGGGCCCCGCCCTTCCAGCCCACGGCCCCCGC +CCTCGACTTGGCCCAGCATCGGGGACCCTCGGACCGCCACCCTCGGCCCTGCCGAAGCCG +TCAACTTTCCCGGGAAGCGGCAACTTTTCCTGCCGCCTCCGGCTCCGCCCTCCCGGGGCC +GGGGCGCCAGCGGCCCCAGCCTGGCGCGGCACTGCGGTGGCTTTCCCTGCCGCCCGGCTA +CGCTTCCCTCGCCTCGGCAGCCCGGGACGGGCCCTGCGGCTCCGGGGAGGGGGCGAGCCG +CCCCCCTCCGCGCCCCGCCGCCGGCCGGGCTCGGGTGCAGCGCGGACACTCACCTCCAGC +GGACGCCCTCTTCATCGTAGGGGTTGGGCGGGGCGCGTCGGGGACTGAAAGTCGTTTCGG +GGCGGGCGCCCGTCTCCCCGCGGCCGGGTCCGCATCCAGGCGCCGCCGCTACGGCCCGGC +CCCGGCCCGGCCGCGGGACGAGGCTCGGCGCGCTCCGCTCCGCCCGGCTCTGGCTGGGCT +CGGGCCGCGGGTGCGCAGGGCGCGCAGGGCGCACAGGGCGAGGGCGGCGGCGGCGCGGGG +GTTGGGGCGTGGGCGGCGCGGCGGGCCGGGGCGCGCAGGCCGGGCCGCAGGAGGCGCTCA +GCCCGCCCGGTGCACCGGCGCCGCGCGGTCCCAGACAAAGGCGGCGCATTCCTGAAGAGG +CGGCGGCCCCTGCAGGCGGCGGAGGGGATGGCGGCCCGGGCCGGAGCCGGCCGGGGACGC +GGGCCCGAGGGTGTGGCGGCCTAGGCTGGCCCGGTCCCCAAGCGGGCAAGGGCTTTGTCC +CGAGGCCTAGGAATGGCCTCTGCCTGACCCACTCCCTTCCTGGCCTCACGAAACCCATGA +ATCCCCCGCCCCCTGCACAGAAGCCCCTTGCTGCAGCACGATCGCCCCCATTTTTCAGTA +AGAAACAGGCTCAGGGCTTAAGAGAGTTCTGGGGGCCCTCCTGGGCCTTTGTGGCCCTCT +CTGCACCATCCTAGAGAAGGGACCTAGGCCTGATGTTACCCGTAACCCTGCAGGGGTCCC +CCACCTCTTCCCTTCTGCGGAATGGGGGCTCCAAACCCAGAAGACGCTCTCCGAGGTCAC +CTGCTTAGTATCCCCCCACTCTACCAAGCCAGCCCCCCACGGGCGGTGTGAGGCATGGGG +CCAGAGAATCCAGTGACGCCCCTGCACACACCACACAGGGGTGCAGGTGTCCCTTCTCAA +TCTTCTGCTCGGGGCACCTACCGGGCCTCACCGATGAGCTCCTAAGTGCATCCCGGGGTC +TTCAGACAACTGCCAGGCTGCCCCTGCACCTGGAGAAGTGCTGGGAGTCAGCTCAGCCGG +GCTGGGTCCTCCCCAGGCCCACCCTGCATGAGAGGACCATGCAGATGAGGGTCTTGCAGG +CCCACCTGGTGTCAGTCTGTAGGACCCTGACTCAAGGACGGAGTGGGCCAGCCTGATGCC +TTGATGGCCCCCCTCAGAGCCCAGGTCCACTGATATGAAGCAGAGAGACCTGGTGACTGG +GCACCCCTGTGCCCTCTGCCTGCCCCTGGCCATGGAGGTGGCCCTGAGGGAGATGAGCAG +GGCGCAGGGCCGGTGACCTGCCTGCCTTGTGCAGAGGAAGTGAGGACCTCCCAGAGCCCT +GGTGCTCCCATCTGATCCCAGTGGCAGGCAGCTTCGCAGGGTGGAGCCATGCTGGGTGGG +CCCTCTGCCTGGTGTGGAGGCTGCACTGCCCACATGCCTCTGGCTGCCGCTCTGTGGCCC +TCATCACTTTGGCCTGCTTTATCCCTATCACCCTTGTCCCAGCCTAGGCTTATGAGGGCA +TTGTGGAGTGCATGCCATTCCCAGCCACACAGAAGGTGAGGTGGGGCCCAGACACCCCCA +GCCACTCTGTCCCCTGGCCTCCTGAAGGGGTGGGCTGTGCACACACTGCCACCTCCCCAG +AGGGTGCTGGCTGCCGAGTGCCACCAGCTCAGCCCCTGAGGTGGCTCAACAGGTCCTCCC +AGAGCCACACCAAGACGTCATCACCCATTGCACAGATAGGGAACCTCAGGCGAAGCTCAC +AGAGCCAGTGGGAGGCTGAGGCCTGACCCCCAGACAAGCATTCTTCTCCAGGGTCCCTGC +ACACAGCAGCCCCCAGGCTAGGAACTGAGCTCTCTCCACAGGGATGTATCAGACCCTAGA +TGAGTCACGTGGCACTGACCATCAGTCTGAGGACAGCGCTGGGGTGGACCAGGCTCCAGT +CTCGGGCTGCTCTGTGCTTGCAGAAAGGCCTTGAGAGGACACTTGCTTGCTTACTCCGCA +GGCGTCTCTTCAATTACCAGTGACCCAGAGCAGCCCACTATAGCTGAAGATTGTGACCCC +ACACCCTATCTCATAGGTTTAAAGCCCCTCCCACCCCTCCTGCCGCAGCCGAAGTGACCA +TTCTGGGGCATGGGATGGGCATGGGGTGAAATGGGGAGCAGGGGTGGCCCTGGAGGCTTC +TGGCACCAGCACCCTCTCCAGCCACCAACCTGGCTGTTCCCGGTTGCTCTGCGCTGGGAC +CTGGGCCTCCACCTCCCCACAGGTCTCTGCATGGGAGCAGGGCTGAGGCCTGCAGAGGGA +GCGCTGGGGGATGGGCTGGTTTCCTGTGTCCGCCACCTCGGTCAGCACGTTGGCCAGCAC +CCTCCCCACTGGAAGCTGGGCCCACTCCTGGGTGCTAGCTGGGATGGTTAGGCGTCGGCC +AGCGCTGATAGGGAGTTATGGGGGTGCAGAGGCAGAGTTGAGCAGGGCTAGGCAGCCGGT +GGGTCTGCTACCAGCAAGGCACAGCCCACTTCTCAGGCTGCGCATGTGGGAGGGTTTGGT +AAGCCACATTTTTCAGGGTGTAGCCGGGTGAGGGGTAGCATGGGGAGTGGTGTACTCTTT +GGGCAGGCGACCACGGAGCCATCACCCCCCAGGGCCCAACGGGCAAGAAGGGGAGCAGCT +GACGGCTGGTGAGGGGCTAGCAGGGAGGGCTTGACAAGGGCTGGAGCCCCTGGTCAAGGG +GCACAACCAGTTCTATCGGGTCACCTTGTGGGAGGAGCCAGGGACCCTGTGGGCAGAGCC +TGGCCGTCTGCTGCCCGGAGTCTACACCAGTCAGTTCCTAGGAAGCCCCATCAGGGGTGC +TGGGAGGACAGGCCATCTGTGCCCAGCTGATGCAAGCTCCCAGGCTTTCTGGACACGTGG +CCCTGGGGATCAGGAGTGAGCTGGAGACTGCAGACAGCTGTGCCCTCAGGGCCACACAGA +CCTGTCACACCCTGCCTGGACTGGGTCAGCAGGGCCACACGGGCATCTGCCCGAATCGTT +CCCCACCTCACACCCACCATGTGGGGCACATTCTTTGCCAGCTTCCCCAGCCCACCACCC +CTCTACAGTGAGGCCAGGGGCTGTCTCACCTCCCACCCACACCCACACCCAAAATGTGGG +GCTCAGCCTCCACGACCAGCATGCCGGTCATGAGGGCCCTGCCCAGCTGTGTGACCTCAG +CCCAGTCCCTTGGCCTCGCTGAGCTTGCACAGCATGTGGACGAGGCAGACGCTAATGCCT +CAGGTCCTGGTCAGCTGGTCACCATCCCTCCTTTGTTCACCTCGCCTGTCCCCTGAGAGG +ATCATGCAGGGTTTTCACTCAAAACTCCAGGACTGCCCATAGAAGCCAGCTTGAGATGAG +GGGAACTTTCGCGGTGGCCTGTCTTGGGCTGACAGGGACACGGTTCAGCCTCCTTGGAAG +GTCACTGCTTCCCAGGGCTTGGGAAGACTCATCTCCTGCCTGGAGAGATAGGCGTGCCAT +GGCTTTCCTTGGCATGCCTGTGCGGTACTCACGGACATCCAGGCCCTCAGTGTCTCCTGG +GGAGGGATGGGGCAGCAAGGAAACTGGGTCTTTGCTCCACACATTCTGGGCCACTCCAGG +CCAATGCAAGGAGAGACCAAGAAGGAAGCTAGAAGGTCATGTGGCAAGCACATGCCTGCT +GCCCAAGTGTGTCAATGTGACTGACCTTCCCTGCACTCTGAGTGGGCGGCTGGGGATGTG +GTCCCAGTGCCAGGGAGCTGGGGGGTGTTGGCCTGCCATCTGCTCTCACCATGGAGGGCG +GCTGCATGCCCAAGGCCTAAGAGGACTCTGTGCCAGGCCTGCTGAGTGAGTCATCCCATT +CAATCCTACAGTGTAGACACTACTACCACTACCCATTTTCCAGACCAGAGAAGGAGGTCT +GGGGAGCTTAGGTGGACCCACATCTTGGCAGCCCCTTTCTGCCCTCTCTTTGTCCACAGC +CTCCGCCTCCTCCAGAAGCCTCTCACCATCCCCCATCCCCGGGGCTGCAGAGGGTGTCCT +GGCCTTCCCCTATCAGCTCTGCACCCCTGAGGACTCCCATCCCTAGGAGTCCCTCTGCCC +AACTTTGGTGCATGTTAAGCCATAATTAATCTGCTTCCTCATCTCTTATTCATCAAAGCC +ACAGCAGCAGCAAAGGGGGCTGGCACAAGGAAGGGACCGACAACCAAACCCTGGCAGTGG +CCCCAAGAATCCCACTGGGCCTGCCCATCTCCAAATGCCTCTGACCCTTCACTAGCGAGG +GCCTCCTCCCACAGAATGGCATCCTGGATTGTGCCACACTAGGCAGGCCCCCTGACGGAC +CATGCGCACCTCCCACCACCTGGAGGCTGCTGGGGACCGTCAATGGGACGTATGCATTGC +ACAGTGATGGCCCTTACCTCTGCGTCCCCCAGCCCTGGACTGGATCCCTTGTGGCCCATC +TCCAGGATGGGAGCCTGAACGGAGATGAAAGGACACTCGGCCAAGTGGGACATGCCAGGC +TGGCACCTGGACCCTGGTCCGCCACTCTTCCTGGTGCCTAGAGGAAGGGGTGAGTCCCCA +GGGCTCCTGGACCTTGAGATGAGCCTCGGGCCACTTGTGTTTGCCAGCAGATGGGCTCAG +GGTCTTCTCTCAGTGGGCACAACCGAGTTGGTGGCCTCTCTCTGGGGAGGCCGGCTGGTG +GGGGCTGGGGAGTAGGCGGCTTCTGGTCCCTGAAGGCCCAAATCTGGTGCAGGGGCAGAG +CTCCGGAAGGCGGGGGTCCCTGGGCTGTGCCCAAGGCATCCGCTGTGGCTTCACGCCCCT +CCCCCGCCCCTGCAGGGAGTGTGGATCCTTCTAGAGCCACCCACCTGGCAGTGACAGCTA +AATTGGGAGCCGCTGTTCACACCAGGAGCCCAGCGGGCAGTCAAAACCGGGTCGGGGGGG +AGGGGCACCCGCTGAAAACACCCACAAGCTCCCAGTGGGGCAGGGAAGGCAGGGAAGGCA +TGGTGATAGCTGTCAGCAGGAGTGGGTGGGGAGTGGAAGGCAGGGTAGACCGCCAAACCC +ATCTTGGGGCCATAGTGAGATGGCCCCTGGGATGCTTCGGCTGGCCAGTGCCCAGCCTTG +CTCTTGTAGGAGCTCCCTGGGCCCCTGGGTTCCCCACTCTGGGCCACCACAATCCATGCA +GCATGCAGGTTTGTTCCGTTTCCCAGATGGAGAGGCTGAGGGCTTACCACAGGGTTCCGT +CAAGGACGCAAAAGGGCCAGCCTGACTCTGAGCTCAGTAGCCCCACCCTCCACAGCCTCC +CTTGCCGCCTTCATCTGCTCACTTCCTCAGTCACTCAACAAACACTCTGGGAGGCAGACT +GTAACACCCTGCATACCTCTGCTGGACCCCCATTCCACATATCCCCACTGGTTACAGGTG +GGGAAACTGAGTGCCTGGGAGGCGGGCCTTGGCCTGAGTCCCCCAGTCAGTGATTCCAGG +ATAAAGGGCATAGCCATGCCATTTGGTCACTTGAAGCCCACAGGGGTGACTGGGAAGAGC +CCACCTAGCACCCCACATTCTGCTAGGGTGACTCAGACCAAGTCCTTGGGGCTCTGCCCC +CCAGCCAGTGGCTCTGCCTCTGAGAGCCATGGGACAGGGAGCTGTGCAGGGTGGGGCCAG +CAGAGCCTGTGCCCCTGCCTGAGCTAGTCGTGATGGGGCCTGCCCTGACCCCTTCCCAGG +CTCATGGGTGCGGAGCAGGGCGGGGCCTTACAGTGAGATGGGGGCCTCTGTGGGCAGTCC +TGGAGGCCAGGCCCTGGGGCTGGGACTCACTGGCACAGGGCCTAAGTTTCCTCCTGTGTC +CGCAGGCCTTATTGCCTGCAAGGGAGGTGGAGGGGCACAGGGGCGGTGCCCAGCGTGAGG +AGGGGGCTCTGAGGAGGCTGCAGCAGCCGGCAGGCCTCTGAGACTGGGATATTTTTAGCC +AGGATTCCTGCTGACGGTCCAGGCTGGCCGGGGTTTGCTGCCAGCCTTAGAGGCGCTTCT +CCTAGTCTGTGTCCGGACATCTGGGGTCTGCTGGCCCCACCCACCCTCTGCTCAATGCCC +CCGCCCCACTGGCCCATCCAGCCAGGCGAGGGGCTCCCAGGAGGCCGGCCATGGTGGGAG +CAGAGCCTGGGGCCCTCGGGGTGTGGCTGAGAAGAGGCCACATGGGCTGCTGGGGGCTGC +CTGTGTCCTGGGTCTCCAGCTCCCAGCTGCCACTCTTAGCCGACCCGCTTAAGGGGCAGG +TTTCTGGAGGCTCCGGTTCATGCCCAGGCTCGAGTTCTGAACTGAGCATTCTCAGTCCGC +TGCCTGCTGCCTGCTGGAACGGATGGCTCAGCAGAGCGGCCACAGCTTGGCTCCCTCCTG +GGCACTCCTGCCTGCCCTTGCCGCTTAGGTGCTCTGGTCATCAGGCCTCTCTGGCTGGCT +CTACCAAGGTGCATGTGTGCAGGGCCTGGGCTTGCAGGGCCTTGTGGCTCAGCCAGGACC +ACCTCCCTTCCCATGGGCAAGTGAGGACATCCAGAAAGAGGGTCCTCTGCCTCGGCCACT +CCCTTGGGACACCCCTCCACCCCAAGGCCTCTCGTGGAAACAGAGTCCAGCACTCAGCGT +CATGCCTATGCACTCCACCGGCAGGACTGGCTGAGTCCCGAGGAGCCAGGCCCTGGGGCA +CAGGCCAATCGGATGGAACCCAGATGAAAGCCCAGTGCTGGGACCCACGGCCCATTCTCT +GGCCTGGCTGAAGCCTGATGGCTTGTTCCTTGAATGAATCAGGAGGCCCATCCAGAGCAA +TTGTGAAGTTCACATGAAAGAATGAACGTACGGAGAGAGATGGGCCATGTCGCATCCTGA +AACGCCTTATATTCTAAGACCATGATAATTAACACAGACCCTGGACAGTCACACGATGGG +AAAGAGTCCAGAAAGAGGCTCAAATGCAAATATGAGAAGAGGCAGGTCAAATCCAAGAGG +AGAGATGGAATATTCAACAAATAATCCCACATATACAATCAACACTTGGCCTTAAGACAA +CGGAATTGACATATGGAGGAAACATTTGGATTCCTACCTCACTCCTTGACGCTAAAACAA +GTTCCAAGTGGAACTAAGATTTAAAAAGTAAAAATGAAACCATAAAACTCCTAGAAGAAA +GCATGGATGGCAAAAAACCAATCTTGAGTCACTCTAAGAATTATACAAAACCCAGAAGCC +ATGAAGTAAAAGATGGGTATATTCAACCTCGTGAAAATAAAAGGCAGATGCATGGAGAGA +AAAAAACCACCATAAAATGATAACCAACAAAGGGTAAAAACATCGGCAACTCAGTTCACA +AAGGGCCGTTTTTGGTTCTCAATACAAATCAGTAAGAAAAAGAGCAACAGCCCAAGAGAA +AAATGGGCAAAGGCATGAAAGGAACCTCCCATCACCCCCTGCTGACCTTCACTCAGAGTG +AGAAACATGCGGATCTAAGCTGCAGTGAGATGCTGCCCCTCACCCACAGGGATGGCAGCC +GCATCAGGCTGGGGGTTCCCTAGGGGGGCTGCTTAGGGGCTCCCACAGGTCTGGCTGTTG +GAGGGCAGGGAGAGGCCTGCGGGTCTGGTGGGGCCGGGGTGAGGCACTCACAGATATGTC +TAGTGGGGGTGAGGAGGGGGACCGCCTGCAGGTACAGCTGGGGGTGTCAGGTCGCTGGGG +ATGGGGTGGAAGGAGAGGATACCCATTCAAAACAGGAAATATATATATTTTAAAGTAAAA +CAGGCTAAGTGCAGTGACTCACACCTGTGATCCCAGCAGAGCGGGGAGAATCCCTTGAGG +CTAGAAGTTCGGGACTAGCCTGGGGAACATAGTGAGTCCCAGTCTCTATAAAAATTAAAA +AATAAAATTATCTGGCTGTTACGATGCACGCCTGTAGTCTCCGCTACTTGGGAGCTGAGG +CGGGAGGATCACGTTAGCCCAGGAGTTCGAGGCTGCAGTGAGCCATGATTGTGCCACTGC +ACTTCAGCCTGGGCAACAGAGCAAGACCCTCTAGAAAAATAATTAAAAAAAAATAAAAAT +AAATATAAAATAAAATAAAAACCAGCTGACATCCATCCTCTCCTTGCCACCACTGACATG +GCCGTGGGCCGAGTTCTCATGGCCATCCCACCGCGAGTCCCCAAGCGCTCCTGATGCCTG +CTCACCCTTCTTGTCTTTGTTAGCGCCCCGTTAGCAGAGGCCTGCTTAACTTGTCTCTGG +TCTTGCTTCTCAGGAGCCGTGTCACATTCAACAGTGGCAGCACAGAGGCCCTGCTCAGCC +CCAGTCCCTCACCCTAGGCCTCCACTGCCAGATGTGGTCCTGGTGGTCCTGCGGACTCAA +GCTGTCCCCCCCTGCCCAACCTTCACAGGCCACCAGCAAGTCCCAGGCCTCCCACAGGCA +TGGCTCTGGGCAGTATCTTTACCTTCCCAGCCTCAGTTTCCCTGATGGTGAAACAGGGTG +AGATCTACTTCCTAGCAGAGAATCCGGGGGAATGGAGGCCGTGGGAGGAAGAGGACTTGA +GGAAAGGAGCATTCCTGAGGGGTCCCAGAGCGGGCTGGGGCTGACAGGACTGAGTTTGCA +GGGCCTGGGGACATTCCCTGGGGAGGTGCTAAGATGCCGGTCAGCTAGAGCAGCGGGGAG +TGATCCAGGATGGCTGCCCGGATGAGGGGCTGGGTCGCTGGTCCCTGAGTGCCAAGGTGG +TCTGTCCATGTCTGCAGGAACACACCCACCCTGCTGCCTCCAGGAGGGGTGCTGGACAGG +CCTGAGCTCCAGGATCATAGGAGGCAAGAGCCACTCTCACCAAAGAACAGCAAGTGTGCC +TCCCCTGCCAGCAATCTGTCCGGTCCAGCCCCTGCCCAGCTATCTGGGGAAAAGGCCACC +TTTTCAGTGGAGGCTGAGCTCAGGGCAGGAAGAGGTTGAGAGGGGAGAAATGGAGTGAGA +ACTGGAAGGTGAGAGGTGTGAGTGAGAGGTAGGGGTGTGAATTGGGGGTGAGATGTGGTA +GGTGAGAGCGGCAGGTGAGAGGTAGGGATGAGAGGTGGGGGTGAGAAGTGGAGGTGGGCA +GTCATGGTGATAGCTTGTGGGGTGAGAAGTGGAGGGTGAGAATTGGGGTGGGAGTTGGGG +TGTCACCTCCCAAACCCTCTCACCCTCAGATTAAGAAGCCCCTCCTATGGGCCCTGGAGG +AACAGGCCTTTGACCCACCCCAACCCCACTGGTGTCTTGGGCAGGGAGATCTCGAGGTGG +GGGCCTCAGCTCCCCGTAGGACCGTCTAGCCCTGGACCACCTGACCACAGCTACAGTGGG +ACAAGGCCCCTGTTGCCTGTCTGCTGGGGGCCGAGCGTGGTATGGAGGAGCCAGCAGCCC +CCGCCTTCATCACAGAGGAGGAATCCGAGGCCCAGGAGGGTGTCTCTGGCACCCAACACG +TGAGACCCTTTGAAAATCCCCCGAGTGTGTGGGGGGCTGGGATGAACATCTGGGGGCGGC +AGCAGCAGGTGGCCCACCTGGCCAAACACACTCCTGTGTCCCCTTGTTTTTGGCAATTTC +AATGACCAAAATCAGATCCTGGTATGGAGAAAAAGACATCGGTAAGGACGAAGGAAATGT +GAACACTGCATGGACGATGGCTGATAATAGTGTGCCGCTATTGGCTCAGCAACTCTAACC +TACCAATGCCAGATGCTCACAACGGTGAAACTGGTGTGTGGTAGATGCGATCTCTCTGTA +CTGTCTTCTCAATTTTTCAGCAAAGATAAAACTGTTCTAAAGTTGAAAAGTTTATTAAAA +AAAAAAAAAGAAAAAAGACGGGCTTATTAGCAAAAATCTGAGATAGAACCAAGCAGTAGG +GCCCAGCCCACCCCCCGCTCAGGGCGCACCAGCAGTACCCCTCTCTCAGGGACATGGCCA +GGCCTGGGCCACTCCGAAGAGCTCTTCCTGGTGCTGGGGGGCCTGGTGGGTTTATTCCAC +CTGTCAGTCTCACTGCAAAGTGTGGCAGTGGAGTCTGAGTTAGGCTGACTCTTACCCTGC +CAAGGACACCCCTGCACTCAGGACCCAGCCCCGGCCCCCTTGCCCTGTGGGCTGGAGGCG +ACCCTGTGTGCAGATGGCAGATGGAGGGGCATGGTGCTGTTGCTCTCAGGTCAGGGGCAG +CAGCCTCAGCCCTGACCAGCCCTCTCCTGCGTGGTTGTGGTTGGGTCTCCTGGTCTCTGG +CCTCCTTTCCATTCCAACCTGTAGAAAACAGTGTGGTGGGGGATGCTCGGCCTGCAGATC +AGACAGGCCGGGGTCAAAGCCCCGAACTACCACCTGAACTAGTCCTGGCCGAGTGGCGCT +GATGCTCTAGGCCGAGGGCCCCCTTGACAGAACAGCCATCATCTAGCTCCGCCGCAGGGT +AGGGGAGGTGGCAGTGTGGGCCGCAGCCCTCGGCTGAAGCGGGGGCCAAGCGGGGCTCTG +CCTGGTGCAGGGGGTTTCCTCTATGGGGCAGGGGCTCCCAAATTAGCCCTGGTGACATCT +GGAGCTCACCTCTGGGGGCTCTGGGGGCTGAGAGAGCAGGCGGGGCCCAGTTCTATCAAT +CATCTGCCTTGTTCCTGGGGGATCGCGGTCAGTCCCAGCCTCCCCACAAGTCCTGGGGCG +GGGCAGGCCTGCTGGAAACCCAAGATGCAGAGAAGAGCGCCAAGCACCTGAGACAGGGCT +CTGAGCACGGAAGGCAAGGACGCCTCCCTCAGCCTCAGCTGGGGAGCCAGTGGCCCTGCA +TGCACTTTCTCCCGTCTGGGGAGCCTGAGCCCTGACCCAGTCCCGAGGCCCATGTGTGCA +CAAAAGCCCCCTGCTTTCTCACCCAGGACACTGGCGATCAGTGGGTAGGCGAGCCGGAGC +CCAGCTGCTGCGCTCCCTTCCCTGCCAGGACCGGGCCAGCTGCATCCTCATGCCTGGGTT +TCAGGGCTTCTCGGGGGATGTGATGGCACTGCCTGAGGATGTGGGATCCTTCCACTGAAA +AGGGCCACACGGCTGTCCCCAGCACCCTTCCAGAAGGGACAACCCACTCCTGGGAGGTCT +TAATGTAGACATCGAGGTCCCCCGAGCTTCCTCCATGGCCTGGCCACTTCACAACCATAT +TTCTTTATGTTCCACGCGCCTTGCCTGCTCCACGGCCAGGACCAGGGCCACCATCTTTGC +AGCCGGTGAAGGGACAGCTGCCGTGGGCTGGGCTGCTGAGGCAGGACAGGGGTCCGGGCC +AGGGAGGGGTGGATGGAGGCCAAGGATGGGCCCCTTGGAGACAGCCTTGGGGTGCAGCCG +GCTCTGCCACCTCTCCCTGGCTTCCTTCCCTCCAACCTGTGACTCCTGGGAAGTCCCTGA +TGGGCCAGCCACTTGGGGCCGGGAAGTAACTGTGGTGTGTGGTGGTCACCCTCACCAGAG +TTCATGGGGTGGAGCAAGGGGGAAGAATCTCCCCCAAAATCAGGTGTCTTGTTCCCAGGC +CCAGCACAGAGACCTGGCCCCCAGACATCTCTGGACATTTGTTAAGAGTGGACAACTGCT +TCCATTACACAGGAGAGGAAACCGAGGCTCTAAGGGGTCCCAGACTTGCCTGGCTGCCAC +AGTGAGCAGGCAACAAATACCAAGTGGCTGCCGCAATGGGGTAGGTGGGAGGCAGTGGCT +GAACCAGAAAGTGCTGCTGTCGATTCTGCTGGTTGCATGAGTCTTAGGAGATCATCAAAG +GGCAGATTGTGGGGAGATAAAAAGTATGAGTGGGGAACAGGATTGGGGGGAGCAGAAGAG +CCTCAAAGACCCTGCGACATTCTCAACGTCTCGATGGTGACTCAGAGATAGCTCCAACCC +GCATGGCGGGCAGAGTGCGGAGGGGACGGCTTTGTGGCTGGATTAGTCATCCCGGTGCAG +CTCACCCCAAATCCCGGCTTCCAGCCCTGGGCCGTCCATGCTGGGATGGAGGAAGGGCAG +CCTCTCCGCAGGGCCACGTCCTGGAGCCTGATAACCTGGCCAGCACACTGTGCAAATGGT +GCATGAGACAGGGAGTTGGCTCTGTGTTCCCCACGGTGGCCAAGGGACCAGCTGTGCCTC +AGTTTCCCTTATTCTATCAAACTTTGAAGAAGGTCCCGTAAAAGCGCATCTGTTTCCAGG +GTAGGGGCCAGAGTCAGCCACCCACACCAGAGTGAGAATTGGTGGGTGCCCTAGCCCTGG +CAGGATCTGGCATTTTGCTGGACGGAGAGAGGAGGCAGCACCCACTGGGGCTCGGGCAAC +CATCCCGGCTACCCCCGCCCCGGCCCGCCAGGAGAGGAGGGAAGCCTTGAAGTGCCAGGC +CTTTGAATCGCCCATCTCCATGGCAACGCGTGGGCACAAAGGGCCGGGCCGGCGAGCAGG +CGGCGGCTGCGCAAGCTGGAAGGAGGAAGGGAATCTTTTATTTATGGGGAGGGAGAGTCG +GGGAGCCAGGCTGCGCCCACGCTCAGGGCCAGGCCGCAGTCTTGAGGCTGGGCCCCCTGC +CCCATAGCCAGGGCCTCTGAGCAGCACCTGCCCACACACCCCTGACCCTCCGTGCCTGGC +TGGGTGGACGGAGCATGGGCAAATGGAGGGCAGAATGGAGTGAGTGTCCAGCATGCACCC +AACCTGGAGATCGGCCCAGAGGGTCCCTGGGAGCCTGCCATCCTCCATACCCCAGTCTCT +GTGATGCGGGCACCCGGGCAGATACCATGCTGAGAGCCAGCTGGGCCTGCAGTGAGGAAA +CGTAGCCCAAAGCAGACTGCAGAGCTGGAACTCAGGTGGGGCTGCTGCCATAGGCTCTGA +AGACAGCGCAGGAGACCGGGAGGGGTCACCAGTGCCAAGGCCCTGAGGCAAGCCAGAGCT +GGGAGCATCTGAGGATGGGCATTAGCGTGGGGCTCCAGGGTACAGCCGGTCCACTGCAGG +CAGCCTGGCCTCCCCAGAGACCCAGCCACGGCTCCTCACCTTGGACAGGGGGCCCTGGGC +CTTGGGCATCAAATGACCTGCTTGCCGCGGTGGAGGCTGCCATACCAGGACGCCGGCCCA +CGGCCTCCAGCGGCCCGTCCCCACCTTCCCAAGCCCCTCCCCTCATGGCTCACACCCTGT +TCCCTGAGCCCCCAAACATGGGAAATGGCACCTGTTGTGCCCCAGCGGGGGAATTCTGAC +CCCAGACCCTGGGGCCAGTGCAGAAACCACCACTGTATCAGATTTTATTTCATCTAAAAA +ATATCTGAGCCAGATTGAAAGCAGCGGGGAAAGGGTCCCATGGCTGCTTCCCCCAGCCCC +ACCCTCCACAGGCCCTGGGCCCTCCCAGCCCCCATTTCCTTTCCTTGAGAAAGTCTAAAG +TGGGGCAATATTTTGTGAAATTGGAGGCACCACGTTGGAAATTCCAAACCCGTGTGTACG +ATGAGCTGCACGCGCGTTTTGAACCTGCCCTGGTTTTGAGCTGAGGGAAGCGGAGGGTGC +AGGAGTTGCCCACTCCAGAGGCCCTGGGTGTGCATGAGGAGCCCTGAGGCTGGGCCGAGA +GCCGCTTGTGGGAGGCACTGTGCCCCCTGCCCCCGAGATCAGGGCCTGGGTGCCCAGGAC +ACTACAGACCTTTTGGGGATCCTGGGGGTTGGGAAGCCTAGAGCTGGAACCCACAGGCCA +GAGTCTGAGCTTTCATCCCCCACCCCCGAAGACGCTCCCCCAGCCACTGCCTGCGCATCG +GGGGAGACAAGCTCCCCCCACGCCCACCTTGCCTCCAGCAGGGCTGTTCCTCCCCTCATC +TGCTGGCATCAGTTTTTTCTTTAACTGAGCCCCATGCTGGGGAAGGGAGAGCTCCAGGGG +ACCAGGCAGCAGAGAGGGGAGGAGAGAAGCCATCAAACAGGCCGGGGGCTGGGAGGCCAT +GCACTCAGCATAGAGCCCCACATGGCAGCAGGGGGCTGGATGGCCGGCTTAGAGCCCATT +CTCTCCTGGACACTGTTCTGGAATGGCCCCTGGCCCCTCCGTTCCAAAGATGGGACCCTC +CGGTCCCCGGGGACCCGGGATGATGTCCCCCAAACCACCTCTCTTCCCAGACTTCATCAA +TGGCAATGAATGGTGCATCCTGGCTGGGGCCGCCGCCCCTCACTGTGAGACTTCAGCCCA +GACGAGCGCCCAGCCCCTCCTGGGGTCTCAGATAGTCAGAAAGAAAGGCTCACGGCTGCC +ATGCACTTCCACAGGACTTTGTGGTTCCTCCTGCACCCCCGGTGATGCTTTCATCCCTCT +CCAGCACCATTCCAGAGGCCAGAAAACCATGATGTTTGGGGTCAAACAGCTGGGAGAGGC +AGTTGGAACTCAGGCCAGGCCTGTCTGACTGGACAGTGCAGAGACTGGGACCATGCTCCC +CTACAAGTGCTGTCAGTGCACCCTCGATGCCCCCCAGAGCTTGCCATGCCCCGACAGTCC +CTTCATGGCCAAAGTGTTCCCTGGCACAGGATACCCTGGGGTGCCATGTCTGCAAGAGCT +CACACCCTTCTCTCCCCAGCTGCTGCTAACTGCTGCCAGAGGTGGGAGTGTGGAGGGCTC +GGGGCCTCTTCACCCTCCCTGCACCAACTCAGCTCCAGAACATTCCCAGCAGTGAGAAGA +GGGTGGCCACTGTGCTGCAGCCCCAAGGGATGGGCAAGGCCATGCCAGCTGGAGTCATCC +ATGTCCCCTTGGACATGGTGGCCTCATTCAGAGGGCAGCATGGAGGAAGGTGCAATGAGG +GTGGCTACCAGAGACAGTGGAGATGAGGCAGTCAGGAAGCCCAGGGACAGGACTGGAGGG +GACACACGGCCAGCCTGGGACAGGGCATGAGGCCTTTGTTCTGCGTGCTGTGGCATACGG +TGTTGGCTCTGGCCCTGGCCCATCTTTTGTTAGTGGTAGGAGGGTGCTCCTTTAATCAGC +CAACTCTTTGTTTCAAATTGCCCCTGTCCTTGAAAACACTGCTTCAGGGAAGCGTGAGAC +AAAGCCAGTTCAGTGGGGTGCCTACCTGGCCAGCAGCCCTCATCCGCAGGGGCTGCTCCT +GGGGCACGTGCCAGAATCAGACAGTCCCACCGTCATGCAGGTGCTGGGGCCTTCAGTCAG +CAGGACCAGGCAGCCCATGTCCTGGGGACCCTTGGGGAGGTGTGGGCATTTGCTGAGTTG +GGCTGTCATTTGCTAGACAGGCGCTTGGCGAAGGGGCCCTTTTGTGCATGGATGCCCTGG +GCAGGTGTCAGTCCTGAGTCCTGGAGAGGAAGGCAAGCTTTGGAGTTGATGCTGGGTCCT +AGGAGGGAGCGTGTGGTTTCGCCAGCTTCTCAAAAGTCACCTGAGACCCTGCCAAGGGAC +CTCCAGACATTCGGTGCAGGCTCCTGGAGGCTGGACAGAGGGCACCAAAGGGCGACGGGC +CCCGAGGACAGAGGTGTGCAGCCAGGTGGGGCCATGGCCAGGCTGGGACCTGCTGGAGCT +CTTGTGTGTGAGCCTGGAGGAGCTGCCAGGCTGGGGGAGATCGGGGCTGGGGCTGGGGGC +GGGGCTGGGCGTCAGCAGGGTCTGCAGCTCCCATCTTCCCAGCTTATAGACCTGAATATC +CAGGTTGAGAATAAACCATTCTCCCAGGGCACCATAGCCTCCAGGAAGCACCTCCTCCTT +CCACCATCCGCCTTTCAGGAGGGGCCTCCCTGGGGGGCTGTCTCTGGGACTGCAGAGGCT +GCTTGGTGTATCTGGGGCTCTGACATGAGTGAGATTGTTCCGGGGCCTGTGCTGCCCAGC +CTCTTCCCCAACAGCTTCCTCTGGAGGCAAGGGGCTTGGCAGGAGCTGCAGGGAGCCAAT +TATCCCTGAGGCAAGCTGGCTGCAGATAATTGGGAAGACAGGCTTTTCACCAGCAGCCAA +GCTCTGGGGCGCACTCGCCACACCAGGACTTGGGACTTGAGGATCCAGAGGTCTGCCAAA +CCCCACGCCTGATTGGGAGCCCCATGTGCTGCCATCTACCAGGGGAGGTGGCATTTTCTT +GGCAACTGAGGGGGGAAGCCAGGTGCTGAGGTGTGGCCCACGGGACGCCTCGCCTGGGGA +CCTCCCAGCCCTTCTCCTCTGCCTCCTAGGGGCCTCCTCTCCTTACACATGAAAACCTCC +AATGTCTAGCCCAGGGCTCCAGATTAGGGGTCAGTGCCGCCCCCAGCCCAACTTCCTCTG +GGAAGTGTGGGGTTCTCCCCGGGGCACTCAGGCCTCTTTCTTACAGGGCTTCCCAAGGGG +AGGCATCCAGAGGAAGGCAAAGGCTGTGATCAGGTAGAACCCGCTGGACGCCCCCACCAT +CTCCCTCCATCAACATCAAAAGACAAGCTGACCACCCCCAATGCAAGGTGGACATTAGGG +TTAAACCCTGAGTGACCAGCACTCAGCTCCCAGCCTGGCCGGGATGCAGTGGGGTGGGGT +GTGGTGGGCTCATGGGGCTGGTGAGAGCCCGGTGGGGTGGGTTTCAGGTGCTGCTTGTCC +AGGGCTCAGCTCTGTTCCTTGGGGCTCCCTCAGCCCAAGGGCCCACCTCCCCTCTGGGCA +GCCCCGATCGGCGTGTTCTGCCTCGGCCAGCTGTCAGCCACCTGCAGCTCCTCCCTCATT +GCACCACCCTGGAGCATCACGGTGCCCAGGGCAGGCCGTGGAGACCTGGCTAGCCCATGG +TCTGCTCAGTCCTCACCAGCTGTTGTGACAGAAACAAGTCTGTGCTGATGAGCTGAGCCG +ACCAGGCTGCAGCCCTCACTTCAGGAGAGGGTCAGGCCCAGCCAGGCCTGGTGAGCAGGT +GTGGGGAAGGATGGGTGCTCATGTGCGGGAAGTTTCTCAAGAGTGGTGGAAGGAGGATAG +ACAACGAGGGCCCAGTGGATAGGGCGGGGAGGCAGGAAGAGGGGACAGAGAGGGGACCAG +TGAAGGAGAGTGGAGGGTACTGCCCCCCTGGGGGAAGGATGGGGTGGGGCTGGTGTTAGC +TGGGTTGGGTGTGTGGGTCTGGCAGGGAGCCGGGCATGGGAGTGGGTCCCGAGGAATGCT +AGGTTGGAGCCAGGACCATGGGCCTCACCAGTCATAGAAGCCTCACCTCAGGGCAGAGGG +GGCTGACAGACTGGGCTGACGGGAAGGGGGGCTTCCTGTCACCAGAGAACATAAAGGGAC +CACTAGTGGCCTGGGCCATGAGGCTCTGTGGCCCTCAAGGTGCTGAGCTCAAGGTGGGCC +CAGCCCATGGCTGCCTTTGTGGGGACCCCACAAGGAGATGCTGGCCTCTGAGGATGCTCA +GACCTGGTTCAGCATGGCCAGGCCCTGGCCTAGCCCAAGGTCAGCACTGGCCACTACCCT +GGGGGCTGAGTCTCCGTCTCGCCCTGTGACATGGTGCCCACACTATGAGCCAGTGTCAAC +CCTTTGCCCATACACCGGGAGCCTTGTGTGTCCATACTCATGGCTGAGGGCCTGTTTGGG +GGTCTCTGTGTTGGGGGAGGTGGGTCCAGGGTGCGTGGCCCCTGGGATTGTTCATCATGA +GTGCCACCTGGAAGGTGCTGGAGCCTCACCCGTCCTCCAGAGTGTTTTGGGGAGATCCTG +TGCTGGCATCTTGGCTGGGCCAGGATGGTGTCTAGGAGGGACCCTTGGGAGGGAAGCAGG +GGCATCAGGGGGCCTGGTGCTGGGGTGGGTGGCAGGAGAGGCCTGGAGGGCGGCGGCCCA +AGCCAGTGGCTGGGCAGGTGTCAGGAGGGAGAGGGGTGAGGCCTGGCCTCCCTGCCACAG +CTTAGCCAGGGCCTGGGGTGTCTTGGGGTGGGACAAGGCCCAGGGCAGAGGCAGGGCTGC +TTGCATGCAGGGTGGCCACATCCCGGCCTGGTGAGTGCCGGCCACTCAGTTCTGTGGCCC +TCTGCTGCCCTCTGCCGGCCGCCTCTGTCCCTGCAGGCCCAGCCATCTACCTGCAGGTCT +GGACAGACCCTCAGAGCCTAGGCTGGGAGGTCTCAGGAGTCAAGACAGGGTTGAATCCCA +TTTGAGGGCATCTGAAGGAGTGAGAGCCTATGTCAATCCCCTGCCCAGCCTTGCCTCGGC +CAGTGGCTCCCAGGGGACTCTGGTGGGCAGTGGCTAAAGATGACAGAGGGGCTCAGAGAG +GCTGAGCTGCTCTGTAAGGTTGCACAGTGAGCAGGGGCCGAGTGGCCTTGGGAGAGGCAA +CAGCAGGAGGGTCCTCGTCATGGCCACAGCCCAGGGACAGGAAACCCCTGCTGGGTTCCC +CCACCAAGTAGCTCCCATTCCCAGCCCTTAGGGTGTCTCAGGAGAGGTTCCGGGGGAGGT +CCCACCTGCCTCCTGCCTTCTCCCCCAACCACACCCTAAATGGGTCCCAGCTCCCCAGCC +CCTCCCACAAGGGCTCACCCGCCAGAGCTCGGGGAGAGGCCCTGCAGGGCGGCTGTTCCT +CCGTGTGCTGCAGTCCTCTGGACACTGAAAGCCAATCCCATCCATCTTAATGGCATTTAA +TATGCACAGTGAAAGTCAGCAGCCACAGCCACGGGCGTGTGCTCAGGGCAAGGTTTACAC +GCGGATGCCACCAGGCTTAGCCCATGAGTGGCCTCCTGGGTCCCAGGAGACCTGTGGGGT +GGGGGTGCAGCTGGGTGGGCCATGGTAGCAGAGACCTGGGGAGGGGATGTGGGAGGTAGG +AACTGGGCTAGGCAGGGACTCAGGGGAGGCTGAGGCCTGGAACAGGGAGACTGAGACCTC +AAGGAGGCTGGGACATTGGGAGTCAAGACTTGGGGAAGCTGGAACATGGGCAGGCCGAGA +CGCAGGGGTTTAAGAATGAGGGTCTGGTGCAGACCTGAGTTGGAGCCCAGCCGCTGCTGG +CCCCACGTAGCTGGAGAGTGTGCTGACCCCATGGTGGCTAGAGAATGTGCTGTTGGTAGG +GAAGGCAAGTGCTGGGAAGGGAAAAGTGTGGTCCATTTAAATGATACGGAAGCAGGGGAG +GGAAGTGCTGGGTAGAGGAGGGCATGGTCCCAGACTAGGGCTCCAACCCCACGGACCTAG +GTGAGAACAGGCACTTCCTACCCAAATGTTGCATTTCTCACGACCACCCTAGCCTGCCAC +GCCCCCATCCTGTGCTTATAAAATCCCCCGAGACCTTAGCAGGCAGACACAGGCAGCTGG +ACGTGGAGAGGAACACATCAGCGGAGACACACACGGGCGGCTGGATGTCGAGATGAACGC +ACTGATAGGCACCGGCATGCTGGCAGGCCACTGACTGGCAGAACCACACGGAGTTTGGCT +GGGGCAGTTGGAGGACAGCCCGGGTGCACAGCGGCCCCACTCCAGGGGAAAACCTTCCCA +CTCCACCCCCTTCTAGCTTCCCCTATCTGCTGGGAGCCACCTCCCCTCAATAAAACCTTG +CACTCATTCTCCAAGTCCACGTGTGATCTGACTCTTCTGGTACACAAAGGCAAGAACCCC +AGGATCCAGAAAGCCCTCTGACTAACACAAGCCACCCTACAGACGACAAACTAAAAAAGC +CCCCGTGACACACGCCCACTGGGGCTTCAGCTGTAAACCTTCACCCCTAGACACTGCTGT +GGGGTCGGAGCTCCACAGCCTGCCCGTCTGTAAGCTCCCCTAGAGGTTTGGGCAGCAGAG +CACTGAAGAAGCGAGCCACTCCCCTTCTCACACACCCTGCTAGGGCAACAAGGGAACTTT +TTCCGTTTCACTGGCCCAAGGTGGCTGGACAGTGTGCTGGCCCCACGGTAGCTGGAGAGT +GTGTCGCGCTCCCTGGCTTTCCTCCTGATGTATAAAATGAGTTAGCGGGTCCTGGGGGCT +GTTCCCACAGTGACGTGGTGGAGGCTGACCCTGACACCCACCCCTGCTGAATGCTCAGTG +AATGGTGGTTGCTGTCAGGAAGCATCATTGCTGTCCTCCATCAGTGTCTGTGGGGCTAGG +TGACTCTTGGAGGATGCTTCCAGCAACGTTGCACTGCCAAGACAGAGGCCGTCCACCTGC +CTCTGGGCTTCCTGGTGTGAACAGATGGATGGATGCGTGGGCCTGCTGCGTGCAGGGAGC +TGAGGCTGGGTCTTCACCTATGGGCAGGAGGCTACACAGGGCTCTGGGAGAGACAGCACT +GTGGCTGGGACAGAGCCCATGTGATGAGATGCCCTCGGTGCCCCTGGCCTCCCTCCTCGC +TCCTGCCCCTCTGGAACATCACCCAGAGCCCCCCTTGCTCTTTTGGGGGATGTCTGGGTG +TCTGCGGTTGCTGTCACTCTTGATCCCACCCACCCACCCCTGCAGGTTGCTGGCAGGACA +AGTGCAGGAGTCATCTCATGGCTTTCCCTGGGATCTCTGTACCCGCTGAGAGCCGGGAGC +TGCACACAGCCTGTCCACCATCCTGGGAACTCACCCTGTTGCTGCCGCTTGTCCTGGGTC +ATCCTGGGGCTCACTCCTTGCCATTCAGACCCCTGTGAGGAGAGCACTGGCTGTGAGTTG +CTCTGTGGCTAGTGATGGCAAGGCAGGGCCTGGAGTAGATCCATCACGAATAGTTCTTTT +TTTTTTTTTTTTTTTTGAGATGGAGTCTCGCTCTGTCACCAGGCTGGAGTGTGCGATCTC +GGCTCACTGCAACCTCCGACTCCCTGGTTCAAGCAATTCTCCTGCCTCAGCCTCCTGAGT +AGCTGGGATTAAAGGCACATGTCCCTATGCCCAGCTAATTTTTGTATTTTTAGTAGAGAT +GGGGTTTCACCATGTTGGCCAGGACGGTTTCGATCTCCTGACCTCGTGATCCACCTGCCT +CAGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCACGGTGCCCAGCTGAGAATTCTTA +ATGAAATGGGAACATGCCTCCCACGAAATGCACAGGGGCCTGCAGTGATAGAGTGGCCTC +AGGTATGTGCACAGGTGTGAACACGCCTTCCACAGAGGGCAGTGGACGTGCACATGCCTC +ACACACACTGTGGCGCAGGGCAAGTGTCCCACATGTGTTCATGCTTGCGCACATGTCAGT +GGGCTGGATGTGTGTGTGCACACCTGTGTCATGCCTGCAGAGAAGACAGTGGAGAGAAAT +ATGCCCAAATCTCCCCTCTGGGTCCCTGCCCTGGGTGCTGGGATGTCAGAACAGGTCGAT +GTCCTTTTATCCTTCCCCATATCCACCACGCTGTCTACCAAAGCACGCTTTAGTTTTATA +ATCAGAAATGAAATGCACCGTTTCAAGAAAGCCATGGGCCAGCCCCTCTGTGCCCTGGTG +TTGGCGGGGGCAGAGGGGTGGGGTGTGTAGGGGGAGATTAGCCTCATGCAGCCGTGGGGC +CAGGGAGGCCAAGGTCAGCTTGCTCAGCACCTGGAGGTACAGCGAGTACCAACAACACAG +CCTAGCTTGACCGCGGAAGGAAAATCAATGCTGGGCGCAAGGACTGACGGCAGACTCACT +GGGAACACTGTCCACCGACGTCAGAGCTGCTCACAGGGCACCGGGAGCTTGCCAGCGAGC +TTGGCTGCCTGTGTTTGGAACAACCCTGGTGGGCGAGCACGGGCCCCTCACCTGACTCCA +CTCAGTGCCCTTCCCAGAGGGGAGACAAAGGCTGTGAACAGCTCTGGAGGCCCTCCCTGC +CAGTGCCCCCCAGGCCTGGCTAAAGAAATCTCAAATACCCCGAAGGGCCTGGCTCCAGCG +GCCCCTGCTATGGGTCAGCCTCAGGGGGATGCTCATCTTCAATTGACCCTGACTGTTCCA +CATTACAAGATAAACTGTGGGGTTAACTCAAGGCGGTATTACTTTGTAAAGACTGCTCTT +TATACAAGAGCGGTGGATGCAAAAACAAAAACATTGCCATGTAAGACGGGAGTCCTCCGA +GTCCTGTCTTCCTCCATTCCGTGTCCTTGCACCCCATCCATGTGTGGCCTGCATGGACAG +ACAGCTTCACACACTCAGACTCTTCCCTCCCCACGCATCAGAGATGTGTGTCCCTGTTAC +TGACATGCAGGGAGGGGCTCATCATCTTGGGCACACCCCATGGTGCTCTGAGCCCATCAT +CACCTATGGTGGACGTTGAAGGAGTTCCCAGGTTTTCCTTTTCAGGAGCCATGGCTCGGG +CCAGTGCCTAGGAGGTCAGAGGTTGGGGGCCCAGGGAGAGGTCACTGCCCAACCGTGCCA +CCTTGGACTCAGAGTGCCGGCCCAGGGAACCAGGCAGGCCCGGCTCTGACCGTGCCGCTG +GGCGACCGCTGGCTGAGACCTGGGGCTGAAACACATCCCACATCAGCCAAGGAAACAGGC +TCTGCATGAGGCCTGAAGCCCCTGAAGGGCTCTGGGACAGGAGGAGAGCCCAAGCCTTCA +GCTGTGATGTGCACAGCACCGTCTGTCCTCCACCCAAGGGAACTCACCTTGGTGACCCTG +CTGGAAGGCACAGGTTGCTGACATTCTGACCCCTGACATTCGGACCTCCAGCAGAGCCTG +CAGTTTGAGACCTCTGGTTCAGGAGCTGGGACTGATGGGGCCCTTGGGGATTCCCGTGCT +GCTGGAGGAAGATGGGGGCATGGGGGTGTCCACAGCAAAGAAGTGAGAAGTAGAGGCCGC +CAGCCCCCCGCCCCGACCCTTCCCTGGCTAGAGTGGGGCAGGCTTGGGGGTGAGTCTGGG +GTGCTGATTTCACCCTCCTGGGCCAAAGTCTCCCCGTGACTTTATGGACTGTCTCCCTGT +GCTCCCTGAGACCCTGGTTCTCCCTCACCAGCCTGGGTCCTTCTTGTCTCAGCTCAGCTG +TCACCTCCTCCGGGAAGCCCCCAAGCCCTTGAGTGGGTGCCCAGCAGGCATGGTCAGTGC +TGAGGCTACAAGCCCTGCCGGCACCCGGCAGGGAACACAAGGCCAGGTCAGGCTCTGGGG +ACAGTAGACAAGCTTATCCCTGCACACTGGGGACTGCCCACCTGGGGGAGAGAGCTAGGT +CAGGCTGGGGAGACGTCAGGGGATGGCCGGGCACCCCTCCCTGAGGAGAGCTCCACCTGA +GCAAGAGTGTCACCAGGCCCACTCCAGACACATGCACTGCCTCAGACGGGCTGGAGAGAG +GGTGTGGCCGGGCCATGGGATGAACCATTCTGGGCGGTTGTCCTGGCATCACCAGACATG +TGGCTCTATTAAGCATCTCGACTCCACAGGAGCCCATGTGGCATGTCCTCTGACCTCCTG +TTCACTTCTGAAAGGGGCGGCCCTCTGAGATTCTGCCTGGAACCTGTCAGCCCTCCTGAC +AAGGTCTCTGGTTCCCGGCCATCACAGGCACCCAGCCACCCTACAGAGAGGCTCTGGGAG +GCTCAGCCTTGCCTGGGGCCCCAAGACTGATGCCAGCTGGGGCATCTCACAGGGAGCACC +CCTACCTGTAAACCGCCCAGCTCAAGCCCTGCCTCGACCTCTCCAAGTCAGCAGCCGACC +TTCCCCAGGGCCCCTCCCAGCCTGCAGGGGGTCTGAGGCTCTGAGGCTTTTCTGCAGCCT +CTCAGTCCCCCACCCTGCTACCTGCTCAGGCAGAGAGATCATGGCTCTGGGTTATTGTGT +GCTTAGTGGGTGCTGGAGCTCGTGCTAAACAACTTGGGTGCCCCCTGAATCTTGACAATA +ATCTGAGGGGGCATTATTATTACTATTCTCACTTCCCCGAGGAAGAAGTCCCAAACCCCG +TCTGGCACAAAGCCAGCGCCCCGAGTCTCCCTCTGCAGTCCATGTGCTCCCACGTGGGGC +ATGCCTGGGACATCACAACATCTGGGGTCAATGCGGCTGCTGTTGTCACTGTGGCATTCA +GCTTTCCCAAGGCTCACATCTGCTCCATCCAGCAAAGGGGTCTTGCACCCCAAGCCTGCC +TCCCTCTTCACACACACAATCCCACTTCGTCAACCACAAAGATGCATGGGTTTACCCAGC +CTCAACCCCATCGGCCCCTCCCCTTCCAGTTGCCGGAGGGCTCGGGCCCCTTCAGCTGGG +CTCCCACATTCCTGACCCCTGGCCTGCAGGCCCTCAAGACTATGCCAGCCCGGGCTCACC +TGGTGCCAGACACCTGCATCTCCCTGGGGTGGGGGTTGGGGGCAGTAGGCTCCGTGGACC +TAGCACACGTATGATTCTTGGAAAATGTAAATGTCTCTGAGGACAGCGATCCCAGCTTCA +AATATTGCTGTGGGCTCTCGGGCAAGTCCCTCCTCCTCTCTGAGCTTCAGTTTCCCCCGC +ATAAAATGGAGCAGTGATCGTAGCTCCTGCATGGGAAGGTTGTGAACACCATGCTTGTCA +GCAGAATATACCCTAATTTTGCAAGGAAACAATATGGCAGGGGTGGGGGGGATCTAAATA +CCTTTCCTTATACACGCATTGAAAATGATTATATAAAGTGGTGAAGTGTGATTGCATTCA +CATAAACAGTGGCATGTTCTGGGATCTAGCAGACAATCTTAACTTCAGGAAATGCAATCA +TATTTTACTAGCTTTGAGAAAAGTGAATAAAATGTCATAGCTAAATAGAACTCAAGTAGG +ATCTGTGAACGGCAGCATGGAGTGGATAAGGGGATAACGTACCGATGAGGGAATTTATAT +ACCCAGCAGCCCAGGTTTGGTGCAGGCTGATAACGGAAAGACAAACTCCAAATTAAATGA +ATGTGAATGAATTCCTTTGCCTGCGGACAGACCAAAAATATCGGTAAAAGTGGCTACAGG +GCAAGCAGAAAAATGCAACAAATTAGAATGAACGCAGGGAACCATGTTTCTGGCAGAGAA +ACAAATATTTCAGAGTACAGGTAAGAGGCACATGGCAAAAAAAACAACAACCTGACTTTG +CCAGAGCTCCAATGTCATGCTCACGGCTGAGGAGAAACAATTATCTCGCTGGGAATGAGT +GCAAGTGAGAGAACGGAAGGAGTCCTGAGCACGGTTGACTGCATGTGCCCAGGGGCCCGG +ACAGGCAGCACAGCGGCCTCTCTACCCTCGAAGGTCTGTTTCTTGTCTGCTTCCTCCTTG +AGAGTGGCAGGCCCTGGTAACTGGCCCAACCTCGGGGGCGCCCAGCAGCTGGGTCCCCAC +CACATGCCCAAGTCTGGCCCTCTCAGATCTGCCTGTCTCCTGAGCTGGAGAACGGAGCCC +ACCCCTCCATCCCCGACACTCATCTCCCATCCAGTTGATCTCCCTGAGGACCCCCCCACC +GACAACTCCCACCTGGATCCCCTGGCCCTGGTGGGGCATCATTCTTTCAAAATAATCCAT +GACTGTGTTCAGTGGCTCACGCCTGAATCCCAGCACTTTGAAAGGCCAAGGTGGGAGGAT +TGCTTGAGCCCAGGAGTTTCAGATCAGCCTGGGGTAACACAGCCAGACCCTGTCTCCACA +AAAAACTATTTTTTAAAAATTAGCTGGGTGCAGTCCAGCCTATAGTCCCAGCTACTTGGG +AGGCTGAGGCAGGGGGATCACAAGCCCAGGAGTTCAAGGCTACAGTGAGCTGTGATCACA +TCACTGCACTCCAGCCTGGGCAACAGAGACCTTGTCTCTTAAAAAAAAAAAAAAAAAAAA +AGCCATCAGCTGGCTCAGGGTAGCCACCTGCCAAGGGTCCCCAGCTGAGCGTAAGACCTG +CTTCCTAGGATTTACAGAGCTCCTGTGAAACTCGGTTGTTTCATTGATTGTCACATGGAG +CCAGTGACTTTCAGGCCAGCCTTGTTCCCACAGGTGGGCTCTCCCGTGGGCCTGGGCACC +CAGCGCTAGGCCTGCCCTGCTATGGTCTGGATGTGAGCAGAGATCTCTGTGATCCCTGTA +CCCCTCGCTTCTCCCCCTGCCCTCTCTGCAGCCCTGCCCCTGGCAGCCCCTGCCCACCTT +CGCCTCTGTGCAGGGCCACAGGCTTCCTTGAAGCAAATGCTAGAACTTTGAGCTCTTTGC +TTTTTAAAAAAAGATAACAGCTTTATTGAGATATAATTCATTATACTATTCATTTATTAC +CTTTTGCATTATACCATGCAATTTTTTCCATTTCAATGGCACAATCGAATGGTTTTTTAG +TCTATACACAAGGTTGAGCAGACATCAACACTCTGTAGCCCCAGAGTATTTCCAGACCCC +AAAGAAACTCCGTGGGCCTTGGCAGCCCCTCCCACTCCCCCTGTCCTCCACCTCCAGGCC +CTTACCAGTGCCACAGTCACCAGGCTACATTATGGGCTTGTCTTCGTGTGACTTCTGTCT +CTATGGGTTTGCCTATTCTGAACTCTTCATATAAACTGAACCATAAAACTTGTGGCCGTC +TGTGTCTGGCATCTTTCTTTCTTTTCTTAAAAAAATTTCACTTTTATTTTAGAGACAGGG +TCTCCTTCCATTGCCCAGGCTGGAGTGCAGTGGCACGATCATAGCTCACTGCAGCCTCAA +CCTCCTGGGCTCAAGCAATCCCCTCACCTCAGCCTCCTGAGTAGCTGGGATAACAGACAT +AGACCACCATGCCTGGTTAATTTTGTATTTTTTTATAGAGATGAGGTCTTATTATGTTGC +CCAGACTGGTCTAGAACTCTTGGGCTCAAGTGATCCTCCTGCCTTGGCCTCCCAAATTGC +TGGGATTACAGGTGTGAGCCACCACACCTGGCTATTTTTATTTTTTAATTGACACATAAT +AATTGTACATATTCGTGGGGTACGTAGTGATGTTTCTATACATGCAATGTATGGTGATCA +GATGAGGGTAATTAGCACACCTATCATCTCAAACATTTATCATTTCTTTGCATTACGAAC +ACTCAATATTCTCTTTCTAGCTAGCTGAAAATACATAATTTTTGTTTTGGTTTGGATTTT +GGTTTTTGTTTTTTGTTTTTGAGACAGGGCCTCACTCTGTTGCCCAGGCTGGAGTGCAGT +AGCACCATCACGACTCACTGTAGCCTCTACCTCCCAAGGCTCAGGTGATCCTCCTGCCTC +AGCAACCCGAGTAGCTGGGACTACAGGCATGTACCACCACACCTGGCTAACTTTTGTATG +TTCTGTAGTGATGGGATTTGACCATGTTGCCTAGGCTGGTTGTGAACTGCTGGGCTCAAG +CAATTCTACCCCTCTAGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCGTGACACCT +GACCCATAATATGTTGTTGTTAACTAGAGTCATCCTACATTGGTGTAGAACACTAGAACT +TATTCCTGCCATGTAGCTATAATTTTGTATCCTTCAACACATCTCTCCCTCCCTCTCCCT +CCCTTCTTTCCACCCTTCCCAGCCTCTACTATCCTCTGTTCTACTTTTGACTTCTATGAG +GCCAGCTTTTTTTAGCTTCCGCATATGAGCAAGAACATGCGGTGTTTAACTTTCTGTTCT +GTCTCATTTCACTTAACATAAGTTTCTCCAGTTCCATGCATGTGACTGGCTTCTTCGATT +TTGCATACTTTCAAAGTTCATCCATGTCATGGCATGCATTAGTACTTCATTCCTTTTTAT +AGCTTAATAGTATTCCACTGTATGGATGGATCACGTTTTGTTTGCACCGTTTTGCTGTTG +TGAATAGTGCTACTGTGCACCAGGGTTGTATTCCTCTGTGTGCCACTGGGTTGAGGGTTG +GGGGATGGTAGGTGCTCCCATAAAGGGGGAAATTGACTGATACTGGCTGAAATGGACCAG +GCTCTTCATTAAGCTGGCCTCTGAATGTTGCAAAAGCATTCTGTTGGTTTCCAGGATCAC +TGCTTAAGACGGTTCCTTTCAGTACCACTGTTGTCCAGGGGAGGGATGGGTTCCCGGAGC +TTCCTGATCTGCCACCTTCTCTGATGTCACCCTCAGACCCTCTGCTTTTGAGCCCCAGGC +TACAGAGTAAAAGTCTGATGGTAGGATGTGAGGTGAGGGACCTTCCTTGACCCGGCACCC +ACATGAGGCAGGACTGAGAACACCCTGAGGACTGCCCGGGTGGCTGGGGTGCTGAAGCCA +GGCTTGGCCCCTCCACAGGCCATGCATGACAAGGACCACCCTGTCTCTGAGCTTTGCCTT +GGCCTTGCCGTGACATTTTCAGGTGTGTTTCAGCTTAGATTCTGCTCTGGGGTTTCCCGT +GTAAGAACAGGGATGACGTCTAAGCCCTTGTCTGGCATTTGTCAGGAATATTGGGAGAGG +CAATGTGGCAGTGTGAGAAACAAGCTCACCCATCCAAACCTGAAGAATGGACTCAGAGGC +ACGAGCAGTGAAAGTGAGACTTTTTTTTTTTTTTTTTTGAGACGGAGTCTCGCTCTGTCG +CCCAGGCTGGAGTGCAGAGGCGCCATCTCGGCTCACTGCAAGCTCCGCCTCCCGGGTTCA +CGCCATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGACTACAGGTGCCCACCACCACACC +TGGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTTTCACCGTGTTAGCCAGGATGGTCT +GGATCTCCTGACCTGGTGATCCGCCCGCCTCCGCCTCCCAAAGTGCTGGGATTACAGGCG +TGAGCCACCATGCCCGGGAAAGTGAGACTTTTAATAGTGGTCTTGCGAGATTGGTGTCTG +GTGGATAGGCGCACTCAGGGCAGTCACAGCAAGTAACTTATGCCCTAGCACACAAGTCCC +TCCTCCTCATTGGTCGAGTACTATGGGGTTACAATCTTCCAGGACATTGCCTAAGTTTCA +TTATCCACCTTATAAGGTTATACCCCGTCGCCTTCCCCGCTTAAGTTTCAATTTTCCAAT +AACGAAACTTTCTTCCCTTTTATGGGCTGACCCTTTTTCTACATTCTGTCTGCTTATTGT +GATCTTCTACGTGCATGAGCCGTGCGGTTTGTTACATTCTCAGGCTGGCTGCCAGTACTT +AGATTTATCATGCCTTGAAAATGGGCCATTTAAAATGTTTTCTCATGGCGGTAAATCGGT +GAGCTGACTGTCATACACTCAGTCATTTTGCCCAAAGTGTGTGTGATGTGGAGGGCTGAC +AGCCTTCTCCATTACCAGTGCAGTGAGAGGTGGCACAGCTGGTGGGACCCCCTCTCTCTC +ATGGATATGAGTGCGTTAGAGGGGAGGTCTTGGGCCAGGAGCAGATCAGATCAACAGGAT +TATCCAGAAAATGGCAGTCATGGCGAGTATTGGCTCCAGATGGGGAGGGTTAGGGTCAGG +GTCGGCTCTTCTCACCTTCCTGAGCGAGTCACCAGCGTCGACAAGTTACTCCCAACATAC +AGGGCCTGGGTGGAGGCTGAGTGCTAGGAACCCAGGCTCCAATTCTGGTAACCAGGTGCA +GATGCTCAGGAGAAGAATGCAGCCCAGACAAGCGTGGTGTGCCCTCCAGAGGAGAGGACG +TGGCATCAAAGGGCTGTCTTCATGGAGAGCAGGAACAGAGACTTTGGGAAGCCAGGGGGC +CTTGGCCTCAGCCCTGCTGGCAGAGGGTCCCCACCATGTAGCTGAAGTGCCAGGGTGCTT +GTGAGGACTGGGTGTGGTCCAGGGTGACTCAGGGCAAGGCCTGGGGGATGCATCTCAAAT +CCACAGTCACCAGCCTAGAAACTGGGGTCACACTTCCCACATGGGTTCCCACATGTGGAA +ATTTCATTCACTAAATAACGACACATCAAGGCAGCAGTATGGATGGGGCACAGCTGTCAA +AGTCACCAGCAACAAGTGCAAGAAGAGAAGAGGGAGTTGCAGCCACATAGGTGCCCAGGT +GGGCCCTGGGGGTCAGAGAGGGCCTGCCAGGGGTAGCACCCACCATGCTGACCCTGATGA +GGAGAGGAAGGAGGGTGTGGGATGCAGGGGAGGGAAAGGTGCCTGAGAGCAGCATGCAAA +CAGCCTGGGCTCAGGAAGAGCCGATGGCATGACAGGTGCTGGGGAGAAAGGCGTGATAGG +TGTGGACAGGGGCCACAGGAGGAGGGATGGTCCTCAGGAAGGGGAGACTGGTGGCTATGG +CCGGCTGCCGAGGCTAGCCTCTCTCCAGCAAAATGAGCCTGGATTCATCCACTCCTTTTG +TCTCTCCCCTTTGCTCTGTGGTGCCGGCAGGAGGAAGAGGAGCAGAAAAACTGTTGCTCC +ATTCATCAGGAAGCCTCTCTCTCTCTCGAGTGGTGGTGATGGTGTCCCCCAGGGGCACCT +GGCAATGTCTGGAGACATTTACGGCTGTCCCGACTGTGTATGTCTGTGTGTGTGTGTACT +ACAGGCCTCTGGTTCCTGGAGGCCAGGGATGCTGATACACAACCTGCAATGCACAGGGCA +GCTCCCACAAGGAAATTATTCAGCCTCAAATTTCAACATTGCAGAACAGGTCAGGGAGTG +CAAGGTACCTCCTGCTCTTTCCAGCAGGTGCAAGGTGCACAGGGAGAAGCAGGTGGGTGA +GGTGGGAGGAGGCTGGAGCCAGACCCAGCGTCTGTGGGGTGCAGGAATATCGTGAGGTGA +CGAGGGGCCCAGCGGTGAGTGATGGGGAGGGGTGCACTACGGCAGGCCGCCAGGGGCGGT +TCCACCAAGAAAGTGACATCTGGGAGGGGCATTGAGGCAAAGGGGCCGCGAGAGGGTAGG +TGCTCTAGAGGTGGCCCACGGGCGGGCGGCACTGAGGCCGGGCCTGCAGGGGAGGCGGTG +TGGCCAGCGGACTCTTGTTGGGTGGCAAGGGAAGGGAAGAACCACAGGGCTGCACAGGTT +CCGAGGGGGCCTAGTGGTCCGCATTTGCCCTTGGGTGGGCGGTGGGACTGGGAGGACAGG +AGAGGAGCGCGGGGCAAGCCCCTAAGAGGCCTGAGGGGTGGGAGGGAGAGGACGGCTTCC +CATACGCCCATTTAGACCAGAGGAGAAGCGGACCCACTTTGAGGGCTGGATTCTCAGCCG +ATCCGGCCTCAGCTGTGGGTCCACGCGGCTCAAGGACCAGGGAGGAACCCAGGTGTGCGG +CTGCGCTGATCGGCGGGCTCCGGACCCACCTGGCTGGCCTGGGGACCTGGGAAACCCGGT +GTGGTGGGGAGACCGCAAGCCTGGTCAGGGGTCCCGCTCCCAATGGGGCGGGTCTCCTGT +GAGGAAGGCGGAGCTCAGGGCGGGTAGCCCCGGGGACCGGGTCTCTCGCGGGGGTGTGGC +CACGGCCCGGTGGGCGGGGCCTGCTGTGGACGCACAGAGGTCTGCAGCGCGCGGGGCGGA +ACCTCCCGAGGAGAGGGCGCGGCTGGGAGCGCGGGGCGGGGCCTTCCGAGGAGAGGGCGA +GACTGGGAGTGTGAGGCAGGGCTTCCCACGGAATGGGGGCGCGGAGCCGGTCCTCCCGAG +GAGCGGGCGCGGCTGGGAAGGCGGGTCGGGTCCTCTCGAGGAGCGGGCGCGGCTGGGAGC +GCGGGGCGCGGCCTCAAGAGGAGAAGGGGCGGTGGGTCCTGGGGCGTGCCAGAACCCTTG +AGGAAGAAGCGCTGGTGTTCTGGAGTATGACCACCGGAGCCGGCCGGGCCTCGGGTTGGG +GCGGGGCCTCAGGGGTGGGGTTGGGACTTCGGGATGGGTTCTCCAGAGGTGAGAGCTGGG +GTCGTAGGGTGGACCGGCGTCTGCTGAGGAAAGGGAGCTGCTTGGAGCGCGGGGCGAGGG +ACTCACGTGGAGAAGGCGTGGGCCCTACGGCGGGCGGGGCGGGGCCTCAAGAGGAGCGGG +TGCAGATGCTAGGGAGGGGCGGGGCCCCTGGGATGGGGCGGTGTCTCCCGAGGAGTGGGC +GCGGCTCGGAGCGTGGGACTTCTAAGGAGAGAGCGCGGCTAGGGGGCATGCGGGGCGGGG +AGGGGCGGGGCGGGACCAATAGCGCATACTTAAGCGGCCCGGGCGGGTACCGGCGTCCCG +CCATGGCTCTGCGGCGCGTCTTGCCCGCGCTGCGCCCCTACATTCCCCGCTTCGCGCCGC +TGTCCACGGCGCCGGCCGCCAGCGAGCAGCCCGCCGCGGGCCCAGGGGCCGTGCCAGGAC +GTGGGTCGGCCAGGGCAGTGCGGCCGCTGGTGCCCGCCGTGGACTTCGGCAACGCGTAGG +AGGCGTACTGCAGCTGGCGAACCTGGGAGCTGGCGCGCAGCCTGCTGGTGCTGCGCTTCT +GCGCCTGGCCCGCGCTGCTGGCGCGCCACGAGCAGGTGCGCGGGGTGCAGCCGGGGCGCG +GGGCTTCTGCCCGTCCCGGGAGCCTTTACGGAGTTTCCTGGCGTGAAACGGGTGCCTCCC +AAGCATCTCCTGGAGCAAGGGAAGCCAGGAAGGGAGGCGTTTCCTGCAGTCCCTTTCTGA +TATCGCGAATTTTCCTACTTCTCGATGTCTACCAACTAAAAACAATGGTCGTTTTAATAT +TTACGATATATACCACTTGTGGGAATACAGAGTTATCACTTGGAATTTAAAATGGAGTAT +TCTTCATGTTGACACAAGAGAAGCCTGGTGTAGGGCTCATAGCCTGGAACCCCAGAGTTC +AATCCCCGGGACCCAGCCGCTTCCCAGACACGGCCACTCTGAGAACACTGTTGGGGAAAA +ATGGGAAGCCCCTCAAACGCCCAGCTTTGAACTCACCCATGGTAACTTTAAAAAGTGTCA +GGGCTTTTGGTGGCGGTGGTGGGGGGCAACAAGCAGAACACTGTTTTAGCCGCATCAGCC +TAGGGGTACTAGAGATGACGGTTATCTCCAGGTGACCCTGGGAAGAGTTTGCAAGGTTCC +GCTTTTTGGCGCCAGGGTATCTGGTGGTGTTGATTTCTCAGGTGAGACTGTACAGAGGTC +GGGGGCTGCACCCCTGGCCTCAACAGGAGGCGGGGGAAGGCGGGGGACGGTGTGAGATGA +GAAGCACCGAGCCACACTTGAGCTTAGGTGAGGCCTCGGCGGGTGCGAGGTGAGGGCAGG +GATCCACGAACTCAGAGTCAGATGCTGTTGGCCCGAATCCCATGGGGAGCGCCAAGGTCA +GCCTAGGACCCGTGGTGGCGGGAGTGCGGAGGATGGTGGAGGAAGAAGGAGCTGAACTGG +ACAGATGGAGGGCTCTGGGAGGGCACTGCTGTGCTTGTGCACACAAGGATGTCTTAAGGT +CAAGTTTTGGCCATAGAGAGCCCCGGCCAAGGAGACAGGAGGGCGAGAAGGGACATCCCA +GGTAGAGGAACTGGCAAGGTGAGGGACGGCGATGTGGAGGCTTTGGGGAGTGCCCACATC +TAAGGGGCATCCCAAAAGAGGAGCCAGTGCTGGTGGTGCTGCAATAGGAGGAGGAGGCAG +CAGGGCAGGAATGCCAGGGGAGGGAGTGGCCAGCCACAGGGCAAGGACGGGCATTCTAGG +TGGCAGCTGAGTGGGACAGAGACTAGCCATGCAGAAGCCATGCCCACCTTGTGGCCAGGA +TGTAGTGGGGGCTAGGAAGGCACCAGGTCAGGTTTCTTTTTTCTTTTTTTTCTTTTTCTT +TTCTTTTCTTTTCCTTCCTTCCTTTTCTTTTCTTTTTTTTTTTTTTTATGGAATTCGCTC +TGTCACCAGGCTGGAGTGCAGTGGCGCGATCTCTGCTCACTGTGACCTCCACCTCCCTGG +TTCAAGCGATTCACCTGCCTCAGTCTCCCGAGTGGCTGGGATTACAGGCACGCGCCACCA +CACCCAGCTAATTTTTGTATTTTCAGTAGAGACAGGGTTTCATCATGTTGGCCAGGATGG +TCTCAATCTCCTGACCTCATGATCTGCTCACCTTGGCCTCCCAAAGTGCTGGGATTACAG +GCATGAGCCACTGTGCCCAGGGAGCTGGTGCCGCATCTTCTGCCTGGGAATCCCTTCCTG +ACACAGCCTCTGGGGGCCAGAGATGGGGGGAGCAGGGCTCCAGGGGTAGAGAAGCCAGAG +GTCACTAAGGCCCAGTGTCCTTCCGTGTTAGAAACACCCGACCCTGCACAGCCCCATGCT +GGCCCCAGCAGCCCTCCGTCAGGGGCAGCGGGTCCCAGGCCTGTTTATGTTTTTGTTTGT +TTGTTTCAAATGAGACTGGGTCTTGCTCTGTTGCCCATGCTGGAGTGCAGTGGTGTGATC +ATAGCTCACTGCAGCCTAGACCTCCTGAGCTCAAGCCATCCTCCCACCTCAGCCACTTGA +GTAGCTGGGTCTACAGGTGCATGCCGCCACACATGGCCAAGTTTTTTTTTTTTTAATTTT +TGTAAAGAGGAGGTCTCACAGTTGGGCGTGGTGGCTCATGCCTGTAATTCCAGCACTTTG +GGAGGTGAGGCTGGTGGATTGTCTGAACTCAGGAGTTCAAGACCAGCCCGGGCAACAGGG +TGAAATCCTGTCTCTAATAAAATACAAAACATTAGCCAGGCATGGCGGCAGGTGCCTGTA +ATCCCAGCCACTCGGGAGGCTGAGACAGAATTGCTTGAACCCGGGAGGCAGAGGTTGCAG +TGAGCCGAGATCACTCCACTGCACTCCAGCCTGGGTGACAGAGTGAGACTCCGTCTCAAA +AAAAAAAAAAAAAAAGAAAAAAGATGAGGTGTCACTATGTTACCCTGGTTGGCCTGGAAC +TCCTGGGCTCAAGTGATCCCCCCACCTTGGCCTCCCAAAGTGCTGGAATTACAGGCGCAC +ACTACCACACCCAGCTAATTTTCATATTTTTTGTAGAGATGGTATTTCACCATGTTGCCC +AGGCTGGTATCAAACTCGTGGCCTCAAGTGAACCTTCCACTTTGGCCTCCCAAAGTGCTG +GGATGACAGGGCATACCACTGCATCTGGCCCTTCTGAGCAGTGCTTGGAAGCCACCTCCT +GACGGGGGCTGGGGGTCAGAGTGGCCAGCTGAATGCTGGGCCATCAGGGTGAGGGGCGTT +TTCTCCTCATCCATTGCCTGTTCTCCTGGGGCAGATGTAAGGGGAAGGCCCTGCACTGGG +GTGGTGTTAAACAAGATGAGATGGTAAGATCTGCTTTCACTTTAAAGGAACATTTCTGGT +TGTTGCTTGGAAAGAAGTGTCAGGGGCAAGAATGCTGCAGGAGGGCTGGCCTGGAGGGCA +GGGTGGGACTGCAGGCTGGCTGCACGGGGGCAGGAGCCTGCGCTTGCGTCAGAGGTTCCT +GAGAGACTTGGGCTCTGGGGCAGAGGCCTGAGCAAGGGGGCCTCGCTGGGGTGTCTCTGT +CTTAGCCACACTCGGTGTTTCTGGGTCCTGTGACCCATGTGTGAGCAGCCTGTGGTGCTG +GTGGCACAGGGGAGGAAACCGAGGCAGGGAGCCTGTGGGGGCTGCTCGGCAGGGGACAGG +CAGCTCCTGTGCCCACTGCTGTCCCACACCTGCATGGAAACACAAACCCCACCACGGAGC +CCCCTCTCATCTCTACAGGGCCTCCAGAGCGCCATGTGCAAGAACTTCATGGGCGGGGTG +GGGTGGGGTCAGGAGCCTGCTGTGGGCTGGCCAGGCATGAACACCAAGCTGGAGGTGGCG +GTGCTGCAGGTGGGGCAGCCTTCCCCTTCCCCACTCCTGTGGCTTGTGAGGGGGTGGGCA +CCGTGGGGGCGCACAGGGGGCATGGTGGGCAGTGGTCGGAGGTGGTTTTGGGAACTCACC +CAGGGCACGTGGCTCACTCTGCAGCTGCTGGGGTTGGCCTGGTGGGGAGGAGGAGGTCGG +AGGGACTCTGAACAGAGAGGGGAGATGCTGGCAGGAGGGCTGGAGACCCAGCCCTGCAGG +GCGTGGGCGTGCATCAGCAGCGGGGTGGGAATAGACCTGTCTATGCAGTAGAAACAAACC +AGACATGGATCCTGTTCTTACTAACGATGTAATAAAGCCAGAAACAGCACCAGAGGCCAA +TGGGTGGGGGGAAGAATAAAATGTGAGCGAATGGGGCTGATCCAGGCCTTCTCACTTCTC +AAGGAAAGTGTCGCAAAGATGGGCATCGCATCCAGGGCTGAGATTGAGGACTGGTTCACG +GCAGAGACCCTGGGAGTGTCTGGGTGAGAGCAGCCCCCAGGCTGAGAGGACACGAGCATC +AGCCATGGTTCCAGCCAAGCCCCAGTGACGTCTCCCAGTCCTGGCTGCCCTGCCTGAGAG +GGTGGGCCTTGGGATGACAGTGCTGAAGGAACTGCTTTTCACACAGCAGGACTTGATGGC +CTCAGGAGTCCCTGAGGCTGGGGCTGGGCTGGGCAGGGGAGACACAGGGCCAGCACAGAC +CCCATAGAGGGCTCTTTATAGAATTATCTGGGTCCAGAGCAAAGGTGGCACTCTCAGCCC +TCCCTGGAGTCCACGCCGGCAGGTGAAGGATCAGAGCCCCATGCCCCATCCTTGGGGCCA +GGGGCTGGGACCCAGGTCACCAGGAGCCTCCAGTTGAAGTGGGGAGGTGACTGGGGTGGT +GCAGTAGTGAGCCATCCCCTCACACACTGCCAGCCTTGCCCACTGTGTCCTCCCTGGCCG +CCCGGAGCTGTGTCCGCCTCCTGCCTGGCTGCCTGTGCTCGGCCCCTCCACAAGCCCAAA +ACAGCCCTAGGGTACTCAGTGTTTTCAGAGCCGCCTAGATGCAGGACTGTTTGTGTTTTG +GTTTTAAATTTTTTTAATTAATTTATTTTTTATAGAGACCAGGTCTCACCATGTTGCCCA +GGCTGGTTTCAAACCCCTGGGCTCAAGTGACCTGCCCGCCGCAGCCTCCCAAAGTGCTGG +GATTACAGGTTTGAGCTACTGCACGCCACTGGTTTTAAATTTTTAAACAGAAAACAATAT +TTACATTTCCTCTGTCTTTTTTTTTTTTTTTTTTTTTGAGACGGAGTCTCGCTCTGTCAC +CCAGGCTGGAGTACAGTGGCGCGATCTCTGCTCACTGCAAGCTCCGCCTCCTGGGTTCAT +GCCATTCTCCTGCCTCAGCCTTCTCGTCTTTTAAAACTGAACACTGAGGTGGGTTTTGTG +GTGGTTGGTGAACGGACAGGTTTGGGCCTGGATCCCCCACCCGACCCTAGCACCCACAGG +TGGGGTCGCCAACTCTGCTGATGTGCCTCCTCCCTCAGCACTGTGGACCTGCTGGACTGG +AGCAGCCTCATCGACAGCAGGACCAAGCTGTCCAAGCACCTGGTAGTCCCCAATGGACAG +GTAACACCTCCGCTCCTCAGTGAGGCCCAGCTCAGCAGGGCGCTGCGCTAAGAAGGGAAT +TCAGCCTGCCACATGTTTCTCTTGTTGCCTACCCTGGGAACTTAACATGACCAAGATCAC +TGCACACTATGGCCCCACAGACCCCCTATGGTCCAGGGGGAAAAGAAGACAAACCCACTA +GTGTCCACAGAGTGCTTGGTGGGACAGAGACCCACGCGGAGCCTTAAAACACCACAAGGA +GAGGGGGTCTGGGGGCCTTCCCCAAGTCATCTGTCTTGTGCATCAGGTCACCCCAAACTT +CAGAGGCCTAAAACGGCAGCAGCCACTCTGCTTCTGCCTCATGGTTCTGGGGTTGACAGG +GCTCAGCTGGGCAGTCCTCGCTTGGGGTCTCCTGGGTAGCTGTACTCACAGAGTGGTGGC +GCTGGGACCTGGGGGAGGCGCCCACTCACATGTCTGGGAGTTGGTGCTGGCTGTGGCTTG +GGCTTTTTCCCAACATGGCAGCTGGGCTCTAAGGGCCAGTGTCCCCTGAGACGTGAGAGC +CAGGCAGAAGCTGGGTGACCTTTTCCTGCCTCACCTCAGAAGTCACACGGTGTCTTTTCT +GGCAAGTTCTGTTTGTTAGAAGCATGTCACCAGGCCAGCCTGTATACTGCGGGGAGAGGA +ATGAGACTCATCTGCCTGTGGGAGGGGGGCCCAGGACCTGGCTGACTGCTTGAAACCACA +ACCTAAACTGGAATTCGAAGAAAGAACAGAAGCACCTTCAGAAAACATCCTGCAGAGGCA +GCTTTCCATGACACATCTAGCCCCAGTCCACTAAGGGCCCAGCCTCAAACTCAGAGCCCC +CGACCCAGAGCCTCGGGGCGCAGTGCGTACAGTGTGGCTGTGCACCAAGGCCACCAGCTG +TTGGAGACTTTAGCATGGTGTAGCAAGGGATAGAGTGGTACTGCTTGTGCCCAGTGAGGC +AAGGCTGCTGGGGCCAGCAAAGGGGTGAGCGGGAGGCCCTGCGGGATGGGTCCCCACGGC +CTCTGAGCACCAGCTCCTTGAAGGCCTCATCCTGGCGGTTGCCCTGGTCCCTGGCTACGT +GTCAGCACGTGCTGCACAACTGCCCTGTCTGCCTGTAGCCAGGGGTCTTCCTCCTGGGCC +CTCTTCCTGCTCTGGGTGGAGCCCTTCTGTTTGACGATTGGGTGGTCAGTGTTCACTTCC +TCAGTGTCACATGGGAGCTGCAGGGGGCCCTCCCACAATGGTGGGGCCTCTGTGAGAACT +GGGGAGGCTGTTAGAGTACACACTTCGGAGTGCAGGCCTGGACTGAGCCTGGGGCCCACT +GACATGGGCACTGAGCTCCCTCCTGGTACCCCCAGGGCCCGCGTAGGGCAGTGCACTGGC +TGCGTTGGAGGTTCCGGGGCTCTGTGCTGCTTGTCCAGGTGGCCCTCCCTCCCGGCCCTG +CATGAGAGGGTTCCCGTGGGCTGGGAACACTAAGAGAGGTTTAGCCTGGGCCTCAGGGTG +GCACTTCCTGGCCCTTGCTGTGGCCTGACCATGTGCTGTACCCCCAGACAGGACAGCTGG +AGCCCCTGCTGTCCCGGTTTGCTGAGGAGGAGGAGCTACAGATGACGAGGATGCTACAGC +GGATGGATGTCCTGCCCAAGGCGAGCTGTCCCGCTCGGGCAGAGGGCTGGGGCCTTGGGG +ACCCGGGACTCATGCAGAAGAGGGCACCTGCCTCACTTGAGCAATAGTTGCTCCCACTCT +CCCACCCCCTGCGCCTCTCAGAAAGCCACAGAGATGGGCGTGCGGCTGATGGTGGATGCC +GAGCAGACCTACTTCCAGCCGGCCATCAGTCGCCTGACGCTGGAGATGCAGCGGAAGTTC +AATGTGGAGAAGCTGCTCATCTTCAACACATACCAGTGCTACCTCAAGGCAAGCCCCCGC +TCAGCCCCTCCCTGCCTGCCTTGGGGCTTGGAGACCCCACAGGAGGGGCTCCTCTCATCT +GAGCTCCCTGGCATTTGCCTGGTTTTATACTCAGCACCCACCAGGGAGCTCACGGGATGG +AGGAGGGAGTGGGCCGTGCCCCCAAGGGGTTGTTGGGGTCTTCTGCAGCACAGCTCACCC +AGCGGGCCCCAGGGTCCAGGAAAGAGCCCCTTAGGTGGTGGCCACAGCCAGGCCTGCAGA +GGAGGCCGAGGCCAGGGTGACTGCCTCAGAGTAGCAAGAAAGGCCCGCTGCCCGCAGCCT +CTCCCCTGGTTCTCAGAACCAGCCAAGAGTGTCTAAGGAGCAAGAGGAAGACAACGATCT +TTATGAGGGTCCACTAGATGTACCCGACACCCCAAACTTGGAAGGTGTCACATGACCATT +TCCTCCAGCGTGTTTTCAGTTCAGCGCCCCTAAGAACCTCATGAAAGCTTTGGGCCCTCC +CCGGAAAGACTCACCCAGGATGTCACATGTATTCAGGGAGCCCATCCTAGCCTGTGGGCC +CCAAACTGCTCAGGGATGTTAGCAGGTCCAGAGCTCTCAGGGGTGAGCCGGGTGCCCAGA +GGACACAGGGTGGCATGGGGAGGGGGTCCAGGCAGGAGCATGCAGTATGCACCCCTCCTG +GTCGGCCTGGGAGTCTGGAGCACATGATGGCTGCTGGCGCCTGGGCTGCCCCCATAGGGC +TGTCCACAGGCCACAGAGGAAGCTGCAGATGTCCCCACTGCCATTGCTCCCTGGAGACAG +AGGTTGGAGAACCATCCTCACCCACACCTGGTCCAGGTGCCTTGAGCTGCACCTCCCCAG +GCAGCTGCTGCCCAGCCCTGGTGACTGCACCTGGGCCCAGGAAGGCCCCATCCTGCTGTC +ACTTGGGCTTGCCCAGGCTCCCTGTGACTTTTGGCCCTGGCCCCACAGGATGCCTATGAC +AATGTGACCCTGGACATGGAGCTGGCTCACCGTGAGGGCTGGTGTTTTGGGGCCAAGCCG +GTGCGGGGCGCATACCTGGCCCAGGAGCGAGCCTGTGCAGCAGAGATCGGATATGAGGAC +CCCATCAACCCCATGTACGAGGCCACCAACACCATGTACCACAGGTGCGCAGCTCTCCCA +CCCCTCTGTCTTCTCAGGGCAGGGCGCCAAGAAACCAGGCCTGAGGGAGAGGCTTGGAGA +CTGAACTTGTCAGCCACATGTGTCCCCAGGTCAGAACTGGTATTTCCTCAGCTTTTATGT +CATGTGTTACTTTTTCAAAAGCATTAAGGTTATTCTTTTATAAATATAGAAAAGCCTATT +GAACAAAGTAAAATTGGCCACAGTTCCCTGAGCCTGCTCCTGCAGACACTTAGATCCAGA +GATGTGCATGAACACTCGGTCCTCCCCACCCTGCAGGCTCAGCCTGTTTGCTTTTCAGTT +CACACAGTGGGATCGCCCATCAGCTGTTCTGCACCTGCTTTTACTGCTCTAGTTTCTTGG +TGATCTTTTCATGTAGCACAGGCTGGCCAACCATGGGCTTTTCCTCTTAGAGGCGTGTGT +GCATGCTGCAAATTCAGAGAGACCCCAAGTGCCTCCTGGTTGGCTCCAGCTCCCCTCCTG +CAGCCGCTGTGCATGTCGTGCCACAGCGCACACATCTCCGCCATTGTTGTTTGCGCTGTA +GCGTGTCCTCTGCCCGATGTGTTTTTCATTTCGCGTTCCATCTGGGTCCTCTTGTGTGGG +CTTGCAGAGTGGTGCTGTCAACAGCCAGCATGGAGTGCCCGGGGCTATGTGTCCAGCATC +TTTGATCTTACTGGTTTTCAGTCTGGTTATTGTAACAGGGACTCGCTGGACATACCGTCA +CCCTCTGTGGTACACACGGGCCGTCAGGGGTTTTGTGTCTGAGGATGCAGCTGTCCTAGG +TTGCTGGAAATGGAATTGCTGGGTCAGAGAGAACGTGCGCGTGGTCAAGCCTGCTGAGTG +TCCTCGCTGCAGGAGGGCCGTACTGCTCGGGCTTCCTGGTGCACCGGGATGCCCACCCCC +ACTGTGCCCTACAGGGACCTGCTTCCCTTTTATTTCCTTTCAGGGCCAGGGGTGCACTGT +ACGATCCCTCCCCAGACGCAAAGCTGTGTCTGTCATGAGGCTTATGGGCATGTTTGGGCT +GGTCCCCAGAGTCACGGCATGTTTGATGCAGGGACGCTGTGCCCCAGCTGGTTCTGTGTG +AATTGTCTGGTCCCAGACATCGCTTTTGCTTGGTTGCTGGTCTTTCTTTTTCATGAGGTG +CTGGGAGGGGCAGATGCTGCTCCTGTTCCTCCTGATCCTGTGGATACCCTTGGAAAGAGC +CAGCTCACTGGATGGATCTGGGTCTGCCTTCGGCCTCCTCTCTGTGCAGCTGGTAATGAG +AGGTGCAGGCGACCACAGGCCTGGAACTGGGCTCACATGGCACTCTTCACAGGTGCCTGG +ACTACGTGCTGGAGGAGCTGAAGCACAACGCCAAGGCCAAGGTGATGGTGGCCTCCCACA +ATGAGGACACAGTGCGCTTCGCACTGCGCAGGTAGGTGTGCCCCACCCTGCACCGAAACC +CCAACCTGAGCCGTTGTCTCCTCCAGCTGGGGAGAGGTGGCAGCAGTGCAGAGCTCAGGG +TGGGCAGAGTGACCTGCTGGGTGGTCGGGCATTTGTGGGGAAAGGCTGGTGAAATGAGCT +GGAGGGTGGCTTCAGTGGGCAGGCCCAGGCCCGCTGGCATTCTGGACATCGGACTGTGAG +AGCACAATGGCTCTTTGCAGTTACGTTGGTTTTTAAAATTAACTTTTTTTTTTAGATAGA +ATCTCGCTGTCACCTATGCTGGAGTGCAGTGGCGTGGTCTCAGCTCACTGCAACCTCCGC +TTCCCAAGTTCAAGCAATTCTTCATGCCTCAGCCTCCCAAGTAGCTGGGATTACAGGCAT +GTGCCACCACGCCTGGCTAATGTTTTGTATTTTTAGCAGAGACAGGGTTTCACCATGTTG +GCCAGGCTGGTCTCAAACTCCTGGCCTCAAGTGATCCTCCCTTCTTGGCCTCCCAAAGTG +CTGGGATTACAAGCATCAGCCACTGTACCCAGCCTTTTAAAAATTAACATTTGACTTATT +AAACTTCACAATTAAAAAACTAAATTTCATCAGGGTATTCGGATGGCTCCTGAAAGGTAC +AAATGTAGTGTTGGAGCCCAGTCCCTCAGGAGGCCTCCACAGCGCTGCCTCATTTATAAG +CAGTTCCCTTAACATTTTAACTACATCTGGAATGTAACGGTTTGTTTTCTCTTTAAACAT +TTGTCCCATGGAGCACAACTTCGGTAGAATTCTAACAAGTCAAATGCAGAAGTTAGGTGA +AGTCAGTTCTTGGATACTCCTGTACTGTCACCCTGGTCTTATCTCATGCCTTAGCCCAAG +CTATGCACACAATGGGGTCCTAGGTCCCCCTCCCCTCCCAGATTCCGCCTTCCCAGGGAT +GGGACCCCCTAGAACCCTCGGAGGCCTGGGCAGTGGCCTCGCTGGCTCTCGCCTTCCTAG +GAGCTGAGCAGGAGCTCCACTCTCAGCAGGGCAGGGTGCCCCAGATCCATGACTTGTGGC +ACGAAGGGGCTCCCCAAGAAGCTGTGAAGCCACAGGGCCAGGCTTGGGGCCAGGGCTGCA +GCCAACAGGACACATCCTGGTGCTGCTCGGGAGCTGACTCACGGCTCTGAAATCATTCAG +TGATGTCCACATTCAGCCTTTGTTTACGATGCTGCTACTTTTTCATGGCCTGAAATTGCA +GCACACCCATTTTTGTGCCCTGATCCTCTGCTAATTGTCATAGATGTGTCGGTGATGGGA +CAGACTCACTTTCTCCACACGCACAGGCCTGGTGGCCAGCACTGCCCAGCACTCGGGAGC +TGGTGGGGGTTCCTCTCAGCTTGTAATCAGGACTCCCAGCCTCTGGGTGGACTCTCAATG +CTGGTGGACTCACAGCCTGACTAGACACATCACCATCCAACTCCGAAAGGACAGCCCGCC +CTCAGCAGGGCTTCCTCTCTCCAGCTTAGCCCCGGCACCTGTCTGTCCCTACTATCTTGC +TGTGGCAGTGGCTTCCCCAGTGGACACAGCTTCCCCCTCCCGAGTGGCAGCCGGGCTCTC +TCCTCTTGGCCCCAAGGGCCCTGTGCCGGGCTCCCCCAGTACCATGCTCACATCCCTGCC +TGAGAGGCTGGACCCCTGCAGGCTTCAGCTCTGCCCCTGCTGTGGGTGGCTGGGGAGCTC +TGGGGAGCTGGGGTCCCCTCCCATGGGTAAGTGGTTCTAGACTATGGCAGCTGCTCTGTC +CTGTGCTGGGCCCAGACTGCCACACCACCCACCCTCAAACAACCCGAGTTGGCTTTGGCC +AAGGAACAAACCAGCCCCAAACTTAGAGGCTGGAACAGTGGCATGTTCTGTAGGCCAGGG +GTGGGCTGGCTCAGCTGATGCTTCTGCTGCTGGCTGTGCCTGTGTCCCTCCTGCGTCTGT +GATCTGGGGCCGGTGGGGCCTAATGAGCTCATTCATGGCTGGTGTAGTAAAGGAGACTAC +ATCCTGGGTCCAGCGTCCCACAGGCCAGCCCAGGCTTGGGCACGTGGTGGGCTCAGGCTT +CCAGAAGGCCTGGAGAGGGCAAGCCTCTGCTTGTGTCACCTTTGGTACCTCCCTGTTGGC +CAAAGTGCCTCACGAGGCCAAGCCCAGATGCCAGGTGGAGTGAGCCACTGTCCTGTGCTG +GGAGGAGCCGCAGTCACATGGCAGAGGCTGTGCACACCAGCAGGGGAGGGGGCAGCCAGC +AGTGGCACCCGGCTCTCGGGTTCATGTCCTGGGGTTGAGGAAGACACAAGATGGAAGCCA +GGGCGATGTGGCAGAGATGGGTGCCTGCTTTAGACTGGGTGGTCCCGACACTGGAGCCCA +GCCCAGGGATGGAGGGAAAGGGCCTCTGGCCGATGGGTACTCTGGGAGCCAGGGCTGGGG +CAGATGGAGAACAGGGGAGGTGAGGCCCTCGGGGAGGGAGTGGGAAGCACAGCACAGGCA +CTGCCAGTCACCCGGGTGATGCGTGAGCAGCAGGCGGAACTCGCCCCAGGCTGGGGGACC +CAGTGCTGTGCAGACCAGCGAAGTCGGGATACCTGGATATAGTAAGCTGGAGATGAAACT +TGAGAACTGTCACTGCGTGGATATTTCAAACCCTGAGAATCTTTGTAAGACCCTATACGG +GGTGGTGTGAAGACAGGACAGAGTGGAGGCCCCACCCCAGTATCTGAGCAGTGCTAATAG +ATGTATAATGCAAGCCACATCTGTAATTTAAAGTTTTTTGGTAGCTACGTTAAAAGATAA +AATGAATTTCAAGAATACATTTTAATTAACCCAAAATATACAAAATATTACTTCAAATTG +TATTCAAGTTGATTTTAGAAAAGCAATGCGGCATCGTGCATTTTTCTAGAAAGTCTCCTA +AATCCCGTGTGTATTTGACATTTGCAACACATCTCGATTCAGAGCAGCCGCCTTCCGAGG +ACTCGGGGGCTGGTGGCAGCTGTGTGGGACACAGCAGCTGTGGGGATGGGGCAGAGCAGC +AGCCCACAGAGGGCGAGGGCAGGGGCCGGAGACCAGTCATACCACAGAACCCTGGAGGGG +CTTGAGGAAGGGATGGCAGGAGAGCTGAGGAGCTTCTCTGCCCTGTGGGGCAGGCTGCTG +GGTGGGTCAAAGCCCCAGAAGGGCTGCACCTCCAAGAAGGGAGGTAGAGGAGAGGTGGGA +GAGAGGAGGGTAGGGAAGGCAGGAGGGGGGCCTTGTTGGCTAAGGGCTGAGGCCTCCCCA +GGGAGAAGAGTAGGGCAGCCCAGCAGAGTCCTGCTGGGAAGAGGCCTCACTGGGAGAGGG +CCGGACAGAGCCTATATCCCAACCCCACTTCAAAGGGGATAAAGTCTGGAGAGTGTAGAT +GGGGGACCTGGGGTGGCAGGACAGGGTCAGAGCTGGGACAGGGGCCCTGTACCCCTGCAC +CGGGGACAGTGTCCTGGAATTAGCCCTCAGCTCCTGGCTTTACCTGCACAGGATGGAGGA +GCTGCGCTTGCATCCTACTGTACTTTGGACAGCTGCTAGGCATGTGTGACCAGATCAGCT +TCCCGCTGGGTGAATGGGGCCCTCCCTGGTGCGATGGAGTGTGGTGCTGGGCCTGGGCCT +CATGGCATTATCTGCCCCCATGCAGGCCAGGCTGGCTACCCTGTGTACAAGTATAGGGCT +GTAGGTGCTGTCATACGTGTCCTGCCACGCCCTGGAGAACAGCAGCCTCGTGAAGGGTGC +CCGTCGGGAGCGGCAGCTGCTGTGGCTGGAGCTCTTGAGGTGGCTCCGAACTGGCAACCT +CTTCCATTGCCCCACCTAGCACCCCCCCGCCCCCGCCCAGGCCATCACCACAGCTGCAGC +CAACCCCATCCTCACACAGATTCACCTTTTTTCACCCCACACTTGCAGAGCTGCTGGAGG +TGGAGTCAGGTGCCTCCCAGCCCTGCCAATGGTGGGGGCACTCAGGTGTGGGCTGACCCT +GATACCTGCCTGGGATAGCCGCTGGTAACTGTTAGGAACTTTCCTCGGATGTGTGGGCCC +AAGGCCCCCACCTCTGTGACCCCCATGTCCTTGGACCTAGAGGATTGTCCACCTTCTCCC +AAGGCCAGCCCACATAGCCCGAGCCCCTCGGGGAGCAGTGGCCGGGCTGGGGAGGCCTGC +CTGGTCAATAAACCACTGTTCCTGCAGCTGAGAGCCCTTTGCCCTCACACAGGGTCAGCT +CTGGGCAACAAAGAGGGAGTGGCTCAGACAGGGTCAGAGAAGTCTCATCCCAAACTCTGG +CTTCCAGCATCATCTGTTCCTGGAGGCCAGGCCCTGCGCAGACCTGGCCACCCAGGGTGC +TGGACACCCCCAACCCTGACTCCACAAGGACCCAGCAGGGCCCATGGGCCCAGGCCAGCA +CGGAGGGGACTCATGCAGATGCAGAAGCCAAGCTCCCCAGGTGGCCCTGGCATGCCTCCC +CGCAGGGCTCCTCCTCAGGCCATTCCTGCCACCCTGAGTCCTCTATCCCAGTGACCTGCA +TCAGGCTCCTCCTAGTGGTTCCCACAGGACACTGACCAGGCTGCGGCAGGCGCATACTTG +CACTCCGGGCCTTCTCCCATGCTCTCCAGCCCCCAGCCCCACAAAGCAGGCTGGATGTGG +TCCTCATGCCCTGGGGCTTGGATGGGGGCCCCTGTACAGATGGCAGTGACAGCATCCTGG +GACCAGGGCTGGGGCAGGAAAGGCTGGAGGGTCCCAGTCTCCAGGCAGGGGGAGGGGTGG +TGGGCTGGGCACACAGCCCAGGAAGGGGCCCCCAGGTAGAGGCCTCTGCTGCAACAGAGG +TGGGGGCCCTACCAGGGCCCCGGTTATGGCAGAACCTGCAGCTATCACACAAGCCACATT +TGGGCCACACTGAGGCATCTTTATTTCTCTGGGTCACACAGAGCTTGGGCCTGGGAGCCT +CTTCTGCATGGGGGCTGCAGCTGCCAAGGGAGCGGCTGAGACCAGAACAAGCGCTCGGGT +GGGCCCCAGTGCAGGTTGGGATGTGCCCGGTGGAGTAAGGTGTGAGAACCCCCAGCCTCA +CTCTCTGCCTGGTCCTGAAGCAGACAGCAGCAGGCTGGCCCAGCCTCCCCTTTATGAGAC +TATCCTAGGGTTTGACAGCAAGTCCCAGATGAAGGGTGACAGGCAGCTGGGGTCCACCTG +GTCTCTCCTCAGCAGGGGGAACCCCCTGCGGGCAGCTGGGAAGGCAGTGGCCAAAGGTCA +AGAAGATGAACTCTGCCCAGACTTCTGCTGCCTGTGGCTATGGTGGGACAGGGCTGCCTT +TCTGGTCACACTGGGCAGCAGGCGACTGCCAGGGACCTCCCAGTCCCAGGGCTGCATTCC +CTGCCCGGCAGCCCCTCTGCTGCAGCTTTCGGATGAGTTCCAGCAGGTTCATCTGCAGCA +TCAGCTCCTGGGATACAGAGGGGCCCCATGAAGGCCAGAGTGACCCCCAGGCCCCTTTCA +TCCCGGCCCAAGGGTGCCAGGCAGTGAGCCCACGGGGGCGACCATCCTGTGAAGCCTGGT +CATGGCCTGCCAGGACAGGGTGGAATCTGAGCTTCTGCCCCCAACAGGGCCACTCGGAAT +CTGAGCCTCTGCCCCCAGCAGGGCCACTCGGAATCTGAGCCTCTGCCCCCAGCAGGGCCA +CTCGGAATGGCATGCGGGAGGGGAGCAGAAGAGGGCCCTGTGTGGCACAGCAGGCCTGGA +GAGGGTGGGCAGTGCCCATGGCTGGCTGGCTCACCCTCCTGTAGGGAATGGGCCTGGCCT +CCGTGCTGGGAATGGCACAGAAATCCTTTCCAGAGCCTCAATCCTTCCACTTCACCCCCA +TACCCTGAGCCTGGCTCCCCAGGGACCAGCAGTAAAACCCCAGATGGAATGGGGCCCCGG +GGCACTCGGGCTAGGGCAGAGCAGGCCCAGGCACTGACCTGTGGGTTGGTGGTCACGTAG +AAGCCAGCCACCCCCGCCTTCTCCAGTGTGCTCTGCTGGTCAGCCACCTTCCGGTCCAGC +TCCAGGATGATCTTCTGGTCCATCGCCCGCTGCTCCTCACGGATCCGGTGTTCCACGGCC +TGCCATGGGGCCAGGGCGCGGAGGGGGAGAGGTGAGGGCAGCTCTGCCATCAGGGGGCGG +GGAGGTGAGGGCAGCTCAAACACATGCTCCTGCTGCCGTCCCCAGTGGCAGCAGCTCTGA +CACCACCGGTGCATCCTCACCACACCCAGGCCTCTCCTCGGCCATGTGAACCCCTGAAGG +GGGCCCCAAGGGGCTTCCACGAATGCCCTGGCTTGGGACTGCCTTAGGACCACACACACA +TCTCCACAGGCACACCCTGCCCCACGGCTTGTTGGTTACATGCCAGTCTCTGGTTGTCCC +TGTGCTCCCTGGGAGAAGGATGGGCCCCTTCCTGGCCCCAACACCCTACCATTGCCTTTG +TACCCCCCTGAGGCCACCTGCTCTGTGGAGGCCCAAACCCACGAGGAGCTGCTATCCAGG +GGAGCACTGGTGGGTTCTCAACCTCCACCCAGCCCCAGCACACTTGGTATCCGCAAAGAG +GAGCCACCTGGTGGGACTCACTAGGCCTCCAGTGTCCCACTCAGGCCCAGGACAGCCACC +CATGCCTGAGCCCCCACACCCCTTCAGCTCAGCCCAGTCAGCAGAGCCAGGTGGTGCCCA +CAGGAGAGCTGGGCCGGCCACCCTGCCTGCGCCCCCAGTACCTCTAGTTCTCGCTGCTGA +GCCGCCTGAACCACAGGCAGGTTGTGGGGCCGGCAGGCCTGCTGGGCTTCCTGGTGCTTC +TGCCGCAGCGCCTGCCTGAGCACTGGGAGGGATGAGAGCCCGTCAGCAGGCGGTGGGACT +CGGCAGCAGCCCTCACCCATGGGCACCTGCCTTGCCAGCCCAGCAGAGCAGCCAGGCCAA +AGGGGTGTCTGCAGTGGGGAGGATGCCAGCCTCCTCCATCCTCCCACCCCACTGTCACCC +AGGGCCGGGCCCTTATCTGGTGGCAAGTCTCCAGGGGACTCCAGAAGGTGCGGGGCACTG +AAAGAGTGGGGTGGGGAAGACTGGCCAGGTGGGGCCAAAGCTGCAGCCCCAGACCCAGGG +CAGCTGGAGGAGGCAGGCGGGAGGGAGGCTGCAGTCTGAGGGCTTCAGGGCCCCCATGGC +CACAGGCCATGAGACATCTACTCAAGTGTCAGAGACCACCTCAGGCAAAGGCATGGGAAA +GGAGCAGGAGGAGCGGGGTCGCTGACCCTGAGCGTGGGGCCTCTGCCTACCAGGGGTGTG +GTCGGGCCCTCCACCCTCAGTGCTGCCCTTCAGGGTAGACAGCCCCTCCCTCATTTGCAG +CTCCCAGCCCCCGCACAGCGCCAGAGGGAGAAGGGTGGGCAGACCTGGGAGGCCCAAGTT +TGGGATGAGCTTGGGGTGCCATAAGCCTGTGTGGCTCTGAGGGGCTCACCCTCAGCCATC +AAGTAAAGCTCCACGGTCCTTGCTAAACTGTGCACAAACACAGATGTGTGCAAACTGTCT +GGTCTGAAGGGAATGTACAGAGGAAGCGATCATGGGACATAAACCACCATGAAACAGAAC +ATGCAGCACCCCACAGCTGGCGCCAGTGACCAGTAAGTGCCAAATGGCTACAGCTCCCCA +GGAGGGAGGGGTCCCTGGCCAAAAGAAAAGGTGAAACCCAACACTCTGTTCCTGGGAAGA +GCCCTGATGTTGCAGCTCTTCTCTGGTGGCCAGTCCCCAGGGAACTCCAGGGCCCCTGAG +GCTCCCCTGCAGGTAGCCTGGCTCCCGCTGTGCCTACAGCCTTCCCCGATCTCCTGTCTC +TTCACATTCTGTACACACCTCGACGATGGTATTTACCAAAAGCCCCCCTCAAGACAGCTC +CATAACACAGGGAAGCAGGGAAATGTCATCTCCTTCACTCTACTGATCAAACATTGCTAC +AAGTGCCAGGTCCACTACCAGATTCCACTAGATAGACAACCAAAAGGCAAGAAGAGAGCC +ACGCTGGCTGCCTGGGCAGAAGGGGCCTGGCCTTAGACATGACCAGGGAACACAAAGGAG +GCAGGAGCAGCCAGTCGCCCCTGCCAAATCAGCAGGAGAAGCAGAAAGTCAATGCAGGCA +TGCCTGCTGCTGGTGGAACCAGGGCCTGGCCCAAACCTTCTGAAGCACAAACAGCATTGG +GCCCAGGCAGTTACTAAAACTCCCCATCCTGCTATAAGGAACTATAGCTCTGTGGAAAAA +TGGCCGATTCCAGGACTGAGACACGGAGAAAACAAGAAAAGATGAGCCTGAACACATACC +TGAACCAGAAAGCAAGAAAGTGCTCACAGAATGATGGGGCGGCATCTAAAGGTGCCTGGA +GCGCCCCCAACTGGCCACACATGGCACAGTCTGGGCATTAAGGAATAATGAGCCATGCGC +TTGGGATTAGTAAACTACATACATCTTACAGCTCAATAAAAAATTTTAAAAAGACAATCG +CCCAGACATTTAGGGGAAGAAGTAATGCCAATTCTACACAAACTCTTCTGGAAAACTGAA +GAGGAGAGAACACTTCGAAACTCATCCTATAAGGCTGGCAAAAACCCTGATACCCAAACC +AGATATTACATGAAAACTATAGACCACAGTTTATCATGAACATAGACCAAAAAATTCTTA +AGATTTTAGCAAATCAAATCCAGCATACATAAAAAGGATACTACAGCACGACCCAGTAGG +ATGGAATTCAAGTGACTGTAATTCACTGTAGTAATAGAAAATGATTCACCACGTGATCAT +CTCAAGAGCTGCCGAAAAGGGAACTGCCAAAATCCAACATCCATTCTTGATAAAAACACA +CCAATCCTGGAGCAGATGGACACTGCCTGCCTTCTGGGGAAGGGGGCCTTGCACTGCTAG +GAGAAATTTTTGCCACATTAAACCTGCTTCTAATCAGGCTTCTACCAGCAGTCCAGTGTA +CAGGAAACCCAGAGAGTGGAGAAGCAGGTTAAATGCAAGAGGAAGCATTTCGTCTGATAG +ATCAAGAGCAGGGCATTCTATAAAATTAGAATGCCCTGGACTCTACAAAAAAGTCAATGC +CACAATAAATGTTGGGGACTGTTTCAGAAGCAAAGAGACCAAAGTAACCAATTGTAGTAC +ATGAACTTGGACTGGATCCTTACTTATAAAGCAACAATTTGCCACAAGTTAGGTACCATG +ATGTGGCCGTGCACTGAAAGTCAGGAGACACCCGGAACAGTTAATTTCTCAGGGGGCTAC +CTTCTGCAGCTGTGTAGGAGACCAGTTTTGTTCTAGAGCACTTGCTCCCAATCCAAGGCC +AAGGTTGACCCCACCACCCAGGTTGTCTGGAGGCATTCTTGGTTTTCAGGACTAGGGAGG +GTACCCCTGCCATCCTGCAATGCGCAAGACAGCATCTCACCAAAAAGACTTACCCAGCCA +CAAATGTCAGCATGGCTGGGTTGAAAATCCTGGTCTCCAGGAATGCTGAAGACTCTTGGT +GAATGCTATGCTGTCACATGTATATATTTTGGGATGTCAAGAACTAGAGCAAAACGTTAA +CTATTGAACTTTAGTGAAGAGCACAAGCGTATGCACTATACTATCTTTTCAGCTTTTCTA +AATGTTTTAACTTCTAAAATAAGAAGTTTGGGAAAAATAACAAAGGTGGAAACTGATGGT +GCAGGGGGACCTGCCCTATATAATTTGCAGGAAAGGGCTCCCAAGCCCACCAAGCAGGCC +TGGCTCAAGTGGGAAGCTCTTCGGGTTTGGGAGGGCGCCACAGGAGACAGTGCTTAGGAA +TTTGATGTGCAACTGGAATGAGGCCCTGCGAGGCCTGAGAGGGAACTGACCCTGAAAGAC +GCTTGCTGCACAACTGTCAACAGACTTCCAACTACTGAGGGGCAATGCTGCTGCAGTCAG +CGCCACCACCAGAGTCTGCCTGCAGGCCAATCAGGCACCGAGGCCTAGGGCCATCCTGTC +TGGAAGCGCGTGGGGCACAGGGAAGCCCGAACAGGGAGTTTCTGCTAAGAAGGTGGGTGC +TGCGCAACTGAAAACAAAACTGGTTGGACCCACTGATCACCAAAAAGGCGCTGTCTCAGT +CTCTGCGCCCGTTGATTTTGTCAATCTTAGAGACCTCTTCCGAACACTTCCAAGGAAGGA +GCTGATCTGCACAGATACCAAGAGCTGCCCGGAGGCGCCGACCCGGAGGAGGCGGCACCT +CATCCCGCTGCCCCCGCGCACCTCGGTGCTCGTTCTGTAGGCGCAGGCGCTGGTTGTACA +GGCTCTTTTCGGTGAGGTGCTGGATCTCCAGTAGCCCCTGCACGATTTCGAACACGGTGC +CGTCGAGAAGCGCCAGGGCCAGGTCGCTGAGCGTGGTGTAGGACAGGCGCTGCTGGAAAG +AGCTGCGGGTAGGGGGGCGCGGTGAGCCCCGGCGGGAAACGAAGCCGCCTCCGCAGGCCT +CCGCCCGCCCCGCCTGCGTACCTGGGCAACTCCTTCACCAGGCTCTGTAGCGCCGACAGC +AACTGGTAGTGTCGCTCCTGCTGCCGGGCACCGTCCGCCACCTCCTCCAAGGCGGCCGCG +TAGCGCTCCATGGCGCGGACGCCCGCTAGCCGCCGGCGGCGGCGACGAGCTCCCCCAGCT +TCACGACATCCCGAGCGCGGCGCGTCCCGCCCCTTTTACGATTGTCCCACGCGCGGCGCG +CTCCGCCCCCTTTTACGACAGTCCCGAGAGGGCCTGGCCGCCTGCCCCGCCCTGCCCCGC +GCCCCGCCGCCTGCTTATTCAGGAGGCGCGCCCCGCTCCTCTGCGGAGACTCCAAGGAGG +GTTTTGCTCAGCCCAGGCTCGCACCTGCCTGCTCCCCGCGCGACATTAAAGGCGAGACTC +CGCCGTCTGGATATCGCAGGACCACGGAGAATCCCACCGGCCCTTGCTGAGTCATTGCGG +GCCGAGGTCCGGGCTCCGCGCCGGCGCGCCTGCGAGGTGGACTGTCCCGGTCACCGGCCT +CCCCAGAGGCAGGGGTCTCGGGCCAGAGCCCACAGGACCTGGGTCTAAGGCACCATCCGC +GGCCGAGCAGTGGCGCTGGGGTCTGTCTGCGTCCTCCCCGCCCCCGGGGTGAGACAGACA +GGACCGCCCTAGAGCCTCTGGGTCAGGACAGTCGGAGCCAGAGTCCCCATCTGGGCCTCC +GTGGCCCCCAGCCCGTGAGCCCAGACTGCGCTCTCCCCGCTCCACAGGCCAGCTGCTGGG +CCGGGGCTGGGGGGCTTCTGGTGGCTGGGGCTGAACCGTCTAGGAACAGGCTTTAATAGG +AGGGGCTCGGGTGGAGGAATGGCTCCTGCAAAGGCCCTGCCAGAGTCAGGTCAGGTGGGT +GGGCGAGAGGACCAGTGTGGCCAGGCTGCGGAAGCCAGCACAGGAGACAAGGGCGGGTGC +TGTGCATTACAGAGGCTGCTGGGGGCTTGTCCATAGAGCAGCAGGGGGCACGGAAGGGCT +TGGGGACGCAGACACGATCAGACTTGCATTTCATCAGGCACTCTTTAGCTGCCTGCTGGG +TGGCTGGGCTGTGTGAGATGACCCTGCTTTGACCAGGTTAGGAATTATGACTGGTTTCCA +GAGAGAACATTGGTTAGTAATTGGCTATGGGGAAGAGGGGGCGTTGAGCCAACCAACTGG +GGTCCCCCTGAAGTGCCAGCAAAGTGTCTGGTTTTCTCCAGGATCTGTTTCCTCAGTCCC +TGGCAGGATTGGCTCCCCTGCACGCCATGTCCTTGTGGTCCCTTCCAGACAGAAACCAGG +CATGAATAAAGTGAATAATGACAAGCGCTCAGGCCACTGCCGTGGAGGGCGGTCCACAAC +CCAGAGCTGGTCATGCGCCGGGCACCCTGGCCTCCAGGTCCCTCAGAATGGCAGGAGCTG +GAGGTGGGACTCGAGATTGTGGGAGCTGAGTCTGTAGTGAGTGACCAGGAGCCAGCTGGG +GCTGGGCTTGGTCACTGTCACCTCCCCCGGAGGTGGTGAGTGGGATGATTAGCTGGGTGA +AGACGCCTGCCTGTTTCACCAGTGTCCCTGCCCTCAGTCCCCCAGTCCATGAAGAGTGTC +TGTGTGGAGACTGGGAGGATATAGGGCAGCCCCACGTGATGATATGTCTGTGGCCAGCTG +GGCAACACTGTCGCCAGCTCCGGGGTCTGCCAGGTGGGGTGGGGGCTGTGAGCCACAGCA +GGAGCAGGCCAGGCCTGGGTTTGGACACCTGCTCCTCTGCCTTGTCCGGGTGCTGATGCA +GGAAGGCCCCTTCTCCAACCCTTGGTGCAACGTCTGACCTGAACCAGCTTCCCCAGCCCA +GCAACACTGCTCCCCTAATGTGGATGTCAACCTAAAGAAACAAACTGAACCACAGTTCAT +ATAGAGAGTTTGTCTGGGCCAAGGCTGAGAGAGCTGCCCAGGACACACCAAGTTGCCCTG +GGAGTGCTTCATTCAGCCTTATTACAAGCAAGTTTTTAAAGACTGAAGGGGACAAGGAGT +GGGCTGATATGAAGTCAGCAGGAATTCTGACTGCTTTCCAGAGAGAACCCTTAGTGACTG +GCTATAAGGTGTTGGACTACTGGGTAAGAGTTATGGTGTCCAGCGTATGGCTTTTTATGC +CTACTTGGTGTCAGTCTGGAACCCACAGAGCAATTGGCTTCAAGAGGTCGTTAGCTCAAG +TAGGAGTGGGATGTGACTGCTGTTTCATTCCAGTGCCTCTCTGGGCCAGATAATTAAAGG +GAGCTCACATTCCTCAGATAAAAAAGTTCCTTTCGCATTAGGAGAAATACGTAATGTAGA +TGATAGGTTCATGGGCACAGCAAACCACCATGGCACGTGTATACCTATGTAACAAACCTG +CACGTTCTGCACATGTACCCCAGAACTTAAAAGAATATATATATGAATATATATATATAC +TTTATACATATATATATAAACTTCCATTGTGCGCGCGCGCACACACACACACACACACAC +ACACACACAAAGTTCCTTTTCTTTTTCATGGACATGAGCAGTATGTCACTCAGGCATGGG +GACTCCTGGGCCACCTCTGGGTCTTCAGGGAGGGCCTGGTCTGGAAGGAGGGGTCTCATC +CTCCAGAGCCCCAGGGATGGGTGATATATGTGTAGGAATGGGGGAGCTGGTTCGCAGACG +TGCGTTTCCCCTGTGTGTGTGGACACGATGGGCCCCATGGCTCTTCCCGTCGGGTGGTAT +CCACCGAAGGCCTTTGCTCTGCGGCCACTGTCCACCTCCACTTGGCCTCCCGAGTCCACC +AGGCTGGCTGGTGACACCTTGGGTTAGTGTGGGGTGACTGGTGTGTGTTGGGGAGCTGCA +GGTCCCCTGTCTCTGACACAGCTGTGTCTGGGCAAACACCAAGGTTTGAAGGAGTGGGTG +CCTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGTGCGCGCACGTGTGTCAAAAGGCTTT +GCTGCATGCCTTTTGTGTGGCTCTTTGTCACATGTGCCTTTCTGTGTTTCTCTGTGAGTT +TTCATGTGTCAGGTTGTATGTCTGTTGTGTGGGCGGAGAAACAGCTCTGCTGTGGGGCCC +TGAGCCATTGCAGGATCCCCATAGGCCATGCAGAGGTGCACACAGCACCTGACCTAAGCC +TGCTCCTCCCAGAACATCAGGCTGCACCCAGGCCACCGCTCACTCCGTCTGTCTCCCGAG +ACTGTTCCTCACTTCCTGCCTCACTGGCCCTGGTGAGGGTGAGGCTCCCTGCCCCCGGCC +CTCAAAACAGAGCTGCAGATGAGGACGCCACCCAGCTGCAGTGTCAAGGGGCTCCTCCAC +AGTGGGTGTCCCGCAACGCATGCTCTCTGACCCCTTTTGTTTCAGTGTTGTCCTTTTTAG +TGTGTGGCACCAGGACAGCAGGGAGCTGCCACCTCAGGCTTCTCTTATTTTCACTCTGTG +AGTAATAAGGTCTGAATGAGAGGGGCTCATTGTGTCTTTACTGTCAAATCAGTCAGGCCT +TGGCCTTGGCATGTCTTGCGTGTGCTTGACAAATGTATTGCTCATGGGGTCTGGTGGAGG +CACAGCACCCTTTTAGAAGACAGGGTCTGTGCGGACCAGTTACGGGTGACATTTCCTAGG +CACAGCTCTTGCCTAAGTGGTGTGGGATGGGAGGAGGGCGGGGCTTCCCACTGTCCCACC +AGCAAAATGGGCTGTGTGGCCAGCTCCTCAGGACCCGAGAGCATTTGCTCCAGGTTGATA +AAATGTTGCGGTGTTGGGTGGCAAGAGTAGGATTGAAACCAGCCACCCAGTTGGTGCTTT +GTTACCATCAGAAGTGTTTGCTGAGTCAAAGCAAATGGCCACTCAAAACTGAGTGGGCTG +AGTGTGGTGACTCACACCTGTAATCCCAGCACTTTGGGAGGCCAAGATGGGCAGATGGCT +TGAGGCCAGGAGTTCAAGACCAGCCTGGGCAACAGGGTGAGAGCCTGTCTCTACAAAAAG +TTTAAAAAATTCGCTGGCATAGTGGCATGTGCCTGAAGTCCCAGCTACTTGCCACTTGGG +AGACTGAGGTGGGATCACTTGAGCCCAGGAGGTCCAGGCTGCAGTGAGCTGAGATCACAC +CACTGTACTGCAGCCTGGGCAACAGAACAAGAATCAAATAATAAATAAGTAAGTAAGTGA +GTAAATCCATCCATCCACCCCAGAGTGAGTCAGCTGGGGCTGCTGCATTGCTCCTCCCTC +ACCCACAGGATTCCCTGGTTCCAGCCAGGAGACGATGGTCAACAGCCACTGCTGTAGTGG +TGCCTAGTTAAAACTCTTTGGTTTCTGTCTCTGTAAAAAAAAGTGTCTAATTGCATTTGG +GCAAAAAACTTGCAGTGAAGAGAGAAAAAGAGATGAAAGCAACCTGTGAGGGAGGCTCGG +GTTGACGTGCGGCATGTGCTGTTTGAGTGTGATGAGTGTGTCGGTTTGCACTGTAGATGC +TCAGGAAGTGAGGATATGTGGAGTGCTGACTGTATACATGATGCCTCCACTGGCTGGCTG +AGTAGAGTTTCATGAAACAATGTTGGTGGACTCAGCCCTGAATCCCTCAGGCATTCAGAG +AGCAACCTCTGTCTTTTTTTTTTTTTTTTTTTTTTTTGAGATGGAGGCTCGCTCTGTTGC +CCAGGCTGGAGTGCAGTGGTGCAATCTCGGCTCGCTGCAACCTCTGCCTTCCGGGTTCAA +ATGTCCTGGCTTTAATTTCACAGATTCTTTCTTCTGTTTCTTCTGTTTGATCAAGTCTGC +AATTGAAATTCTCTATTGCATTTTCATTTCATTCATTTATTTATTTTTATATATTTTTGA +GACAGAGTCTGTGTCACCCAGGCTTGAATGCAGTGGTGCCATCTTGGCTCACTCCAACTT +CCACCTCCCGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCTAGTAGCTAGGATTACAGGC +ATATGCCACCATGCCTGGCTAATTTTTGTATTTTTAATACAGATGGGGTTTTGGCATGTT +GGCCAGGCTGGTCTTGAACTCTTGACCTCAAGTGATCCGCCTGCCTCGGCCTCCCAAAGT +GCTGGGATTACAGGAGTCCGCCACGGCACCCAGCTTGCATTTTCATTTTATTCATTGTAT +TCTTCAGTTCTAGAATTTCTGTTTGGTTCTTATTATTTCTGTATCTTTATTGAACTTTTA +GTTTTGTTCATCTACTATTTTCTTGATATTATTGAGTTGATATATACATTCTAGTAAATT +TCACTGAGCTGTCTTAAATCAATTATTTTGAATTGTCAGACAATTTGTAGATCTCTATTT +TTGGGGGGTTGATTACAGGAGATTTATGAGTTTATTTTGGTAGTGTCATATTTGCTGATT +CTTCATGATCTACAGACTTTCATTAATGTCTATGAAGAAGCAAATACCTCTTCTTTTTTT +TTTTTTTTTTTTTTTGAGACAGAGTCTTGCTCTGTCACTCAGCTGGAGTGCAGTGGCGTG +ATCTCAGCTCACTGTAACCTCCACCTCCCAGGTTCAAATGATTCTCCTGCCTCAGCCTCC +CAAGCAGCTGGGATCACAGGCATGTGCCACCACGCCTGGCTAATTTTTTTGTATTTTTTG +TAGAGACAGAGTTTCACCGTGTTGTCCAGGCTGGTCTCAAACTCCTGGCCTCAAGTGGTC +TGCCCGCCTTGGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCACCATGCCCAATCTC +TTTCTGTCTTTATAGATTGGTTTCAGCAGGTACAAACCTTTTCCTGCTGGATCCCTTGAC +TGGATCACAGTCAAGTGGGCCTGGAGCCATATCACATGGCTGCTGCCTGGTCTGCAGCTG +AATCTCTGATTGGCAGGCCTGCTATCAAGGCATAGGTTAGTGATGCAGTTTCTGCTGGAT +CCTCAGGAGAACTGGACTGCCTCTGATACCCTGATTGAACAGGACTGGAGCCAGGTCATG +GGGCCACTTCTAGTTCTACAGTCAAGTCTTCAGATATCAGGCCTATTACCAAGGGCATGG +ACTGGTATAGCTCCCTGTGGGTCCCAGATTGAGCTCCTGCTGGTTTACTAGGTAGGTCCA +TGGGAAGACAGGACTGCCTCCAGACCACAGTAGAGCAGGGCTAGAGCCAAGTCACAGGAC +AGCTTTGGTGACCACATTTGGGTTCAAGATTGGTGGTCCTCTTATTAGGAGAATGGATGG +TATGTCTTTCACCAGGTCCCAGGATGGGCTGGACTGTGCCCAGACGGGCAAAGCAAGACT +GGAATGGAGTCACAGGGCTACTTTAGTGTCCATAGCTGACACTGAGATCAGCAGGCCTGT +TACCAAGGGCATGTAAAGGCATCACTGAATTCCTGGGCAGGCAAGACTGACTGTGGTAGA +GTGGGGCTGAAGCCAGGTCAGGGCTGCTTTAGTTTCTGCAGTCAGGACCATGGTTAGAAG +GCCTGTTACTGGGGGCATAAATGGTCATGGTTCCTCCTAGGTGCTTAGTGGATGGGGCTA +GTTGCAAGAACATGATCTAGTGGAGCTGGACCCAAGTCCATAGGAGGACAAAGCTGCTTT +CAGTCTGCAACTGGGAACCTGTCACTGGTGTGTGGACCTGCCTTCTCAAAGCAGCTCTCC +TTGGTTTTGGGCTTTGCTAGAGTTTTGCCACCTCCTGCCTGGATATTAAAACTCTTGCAA +AGGCAGTTTTGTCCATGAATGGCTCCAGATCATTGTTTGTGTGGGGAGAGGTGAGTGGAG +GGCCTCCTGTTCTGCCATCTTGCTGATGTCACCCTAAGATGATTATTTGAATTCTTTGTC +AGGCAATTTGTAGATCTTCATGTCTTTGGAGTCAGCCACTGGAGTTTCATTTTGTTTCTT +TGGTGGTGTCATATTTTCTCATGCTTCCTGTTCTTTGAAGACTTAGATTGCTTTCTTCAT +GTTTGAAGAAGGAGTCATCTTTTCCACTCTTTACTAACTTCAGGAGAGAAAGACCATCAA +TTAGCTAAGCTATAGATTCTGGGGGTCTCTCAGTCCTTTTCTGTGGGTGGTCCTTCCCTT +TTAAGGGGGATGTCTTAGGATTTTGTCCCTTGTCTTCATTTCACAAATGAATAAAACAAC +CAGACCAGACATAAGTAAAGGAATACAGCACTTGAACAACACCTGAAAAAACAACTAGAC +CTAACAGACATACACAGGATATTCTACCCAACAACATAATACACATACTTCTCAAGTATA +CATGGGACATTTTCAGGATAGACCATATAACACATCACAAATTAATTCTCAATAGGGGCT +GGGTGCAGTGGCTCACGTCTGTAATCCCAGAGTAATTTGGGAGGCTGAGGCGGGTGGATT +GCTTGAAGCCAGGAGCTTGACATCAGCCTGGCCAACACGGTGAAACCCCATCTCTACTAA +AAATACAAAAATTAGCTGGGCATGGTGGTGCGTGCCTGTGATCCCAGCTTCTTGGGAGGC +TGAAGCGTGAGAATTGCTTAGGAGCCCAGGAGGTTGAAGCTGCAGTGAGCAGAGATTGTA +CCACTGTACTCCAGCCTGTACTTCATGACAAAGAAAATGTACCATTGTACCACTGACAGA +ACGAGACCCTGTCCCAAAAAAGGAAAAAAGCTCAGTAGATTTAAAACGATAGACATCATA +CAAAGTGTCTTCTCTGACCACAACAGGATAAAGTTAGAAATCAATAACAGAAGATTTTAA +AAAGTTCACAAATTAGTAGAATTTAAACAACACACTCTCAAACAACCAATGGATCAAAGA +AATCACAAAGAAATTATAAAATTCTTAAAGACAAATGAAAATGAAAGCACACTATATCCA +AACTTATGGGTTGTGGCCAGTTGTGGTGGCTCACACCTGTAATCCCAGCACTTTGGGAGA +CTGAGGGAGGTGGATAGCTAGAGGTCAGGAGTTCAAGATCAGCCAGGCCAACATGGTGAA +ACCCCGTCTCTACTAAAAACACAAAAATTAGCTGGGAGTGGTGGTACGTGCCTGTAGTCC +CAGCTACCCAGGAGGCTGAGGCATGAGAATTTCTTGAACCCAGGAGGCAGAGGTTGCACC +ACTGAGCTAACACCACTGCACTCCAGCCTGGGTGACAGAATGAGACTCTGTCTCAAAAAA +CAAAGAAACAACAAAAAACCACAACTTATGAGTTGTGGTGAAAGGAGTGCTAGGGAGGAA +ATTTATAGCTATAAACACATTAAAAAAAGAAACACCTCAATTCAACAACATAAGTTTACA +CATTAAGAAACTAGAAAAAGAAGAATGAAACTAAACCCAAAGTTAGCAGAAGGAAGGAAA +CAATAGAGATCAGGGCAGAGATAAATGGAAAAGAGAATAGAAAAACAATAAAAAACAAAA +CCAAAAGTTGGTTCTTCAAAAAGATTAATAAAACTGACAAGACTACACTTTGGGAGGCCG +AGGCGGGCGGATCACGAGGTCAGGAGATCGAGACCATCCCAGCTAAAACGGTGAAACCCC +GTCTCTACTAAAAATACAAAAAATTAGCCGGGCATAGTGGCGGGCGCCTGTAGTCCCAGC +TACTTGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCGGGAGGCGGAGCTTGCAGTGAGC +CGAGATCCCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAAAA +AAAAAAAAAACTGACAAGACTAAGGAAAAGGGAAACAATCTAAATTACTTAAAACAGAAA +TGTATTTGAGAATATCTTTATATATTTCTGTCTGTCTGTCTGTCTGCCTGTCTATGTTTT +AGAAACAAGTGTCTGTCTATGTTTTAGAGACAAGGTCTAGCTCCATCGCCCTGGCAACAA +TCAGATGCAACCACAATCAGTGGCACAATCGGCTCACTGCAGCCTCGAATTCCTGGGCTC +GCCACTATGCCAGCTCTTTTTTTTTTTTTTTTTTTTAAGAGACAGGATCTTGCCATGTTA +TCCAGGCTGATCTTGAACTCCTGGCCTCAAGGAATTTTCCCACCTCGGCCTCCCAAATTG +TTGGAATTACAGGCATGACCCACCATTCCCAGCCTAGAAAGGATTATAAAAGATTACTAT +AAATAATTGTGTGCTCATAAATTGGATAACCCAGATGAAATAGATGAATTCCTAGACACA +CAAAACCTACCAAGACTCAATTATAAAGAAACAGAAAGTCAGAATAGACCTAACCTAGTA +AGGGAATTGAGTCAGTAATAAGACAATCTCATGACAAAGAAAAGTCCTGGACCTGATAGC +TTTACTGGTGAGTTCTGCCAAACGTTTAAAGAAGAACTAACACTGATTCTTTTCAAGCAT +TTCCAAAGAGTGGAAGAGGAGTGAATACCTCTTAACTCTTTCTATGAGGCCAGCATTACC +CTGATACCAAAGCCAAAAACACTATAAGAAAATAAAACAACAGATCAATATGCCTCTGAT +CATTGATGCAAAAACTCTAAAAATACTAGCATACTGGGTGGGGCATGGTGGCTCATGCCT +GTAATCCCAGCACTTTGGGAGGCTGAGGTGGGTGGATCACCTGAGGTCAGGAGTTCAAGA +CCAGCCTGACCAACATGGAGAAACTCTTGTCTCTACTAAAAATACAAAATTAGCCATGTG +TGGTGGTGCATGCCTGTAACCTCAGCTACTCGGGAGGCTGAGACAAGAGAATCGCTTGAA +CCCGGGAGGTGGAGGTTGTGGTGAGCCGAGATCATGCCATTGCACTTCAGCCTAGGCAAC +AAGAGCAAAACTTTGTCTAAAAAAAAACTATCATACTGAATTCAGCATCATATTAAAAGG +ATTATACACCATGACCAAGTGGGATTTATTCCTGGAATGCAACGATGTTTCAATATATAA +AAATTGATCCATATAAATTCAGACAATTAATTTTAACTGATGTATAGTTTCACATTATAT +GCACATACCACGATTTACTTTTCCATTTTCCTAGTAATGAGCTTTAAGATTATTTCCAAT +TTTTAGCTATTACTAATAATGTTTCAACAAACACCTTTGGACATCTCTTCTGCAAATGTG +TGTGTATTCTCTTGGAGAAGGTTTACCTTGTGGAATTTCTAGTGTGTATGTGTATGTGTG +TGGGTATATATATATACACATATGTATATATTTTCAACTTTACTATATATTTCCAAAAAA +CTCTTCAAAGTGGCAGATTTAAACTCCCCTTCGCCGTATATAAATTCACGGTTCCTAAAG +CCCTTGGCATAGTTTTGTGTTTTTATAGAAAAGGGCATAAAGTCTTATTGCTGTTGAATT +GTACCTTGCTCTTTTCAATTGTCTTTTCACAATAATTCACTATTTATCATCTGTTGTGAA +TATTGTGGAGTAGTTCTTAATCATTTTTTCTACTAAACTATTTTATATCATTAATTTGTA +GAAATCCTCTTTATATAATGGATATTATACTTTTCAATTATATATTTTGTAAATATTTTA +CCCAATTTTCTGGCTTGCATTTAACCTTTATTTAGGATGCCTAGGATTTTTCATTTTAAT +ACAGTCTAATTTATTTTTCTTTTCTTCTTCATGCATTCTGGCATTTGATTAATAAGCCAT +TTGTTGCCCAACGTCATTAGTTCTCTGTATATACTTTTAAATATCTTAAACATGTAATAT +TCATAAGTAATTTCACAAGTAGTTTAAGATTTGAGTCTGTAACCTAAATAGATACAGGAT +TTTGTGATATGCTGTAATATACAGATTTTTATTTATATATGGATAAAAATTTATATGTTT +TTTCTGACAGCATTTATTGGATAGTATAATTTTTCTACTGACTTTTAGTATCATATCTTT +TATTACAAGTCCAATGTATTCAGCATACCTATGGATCTATTTCTTGGTGCTTCCATTTTT +TCCCATTGTTTAACGGTGTATCACTGAGCCAAAGCAAACCATTTTAATTATTATAATTAA +AACACATTTAAATATTGATAGGCTATTATTGTTCAAAATAACTTTGGTTCTTCCTTTCCG +TTGATTACTTTAATATGACTTTTCCAATCAAGTTCTAAAAAAATACTGGTGGTATATTTA +TTGAAATAACTTTAATAAAATTAAATGAAAGATCATGTATTTGTTTTCTGAATTAATTCT +TAGATACATTAATGTTTTATGTTACCATGAATGTGATATTATAATATAATATTTTTAATT +GGTTGCTACTGTTTATAAGAATTTCATTTTCTGTTTACTTTGCCTTCATATCTGAAAACC +TTGCTGATTTGATTAGTGCATCCACAAATTTTCTTGGATTTTCTATGGGTAATTACAAAT +CTCCACACAATGAGGTTGCAGTGAGCCAAGATCACACCACTGTACTCCAGCCTGGGCGAC +AGAGTGAGACACCATCTCACAAAAACACATAAACAAACAAACAGAAACTCCACACAATGA +CAACGTATGTGTTTTCTTTTTTTCTTCCTCTTTCTGTAATATTTCTTTGTCCTATCTTAA +CTGAACTGGCCAGAAACCCCAGGACAATGATAAATACGAGCAGTGTCAACAGACATCTCA +TTCCCTTTCCTAGCTTTTATAAAAAATAACGATTATGCTTCAACATTACATATGGTGGTG +TCGATGGTTTTGTTATAGATAAGCTTATCAGGTTAAGAAATTTGTCTGCTTTTCCTAGTT +TGGTATAAAGATTTTAATATAAATGAATGTTGTATTTTACCATCTTATTTTTTTCCTACA +TCTGCTAAGATAATCCTGTGTTTTCCCTTTTTCAATCTCCTAATGTGGTGAATGACATTA +AAATACCTTCTATTGTTAAAATATTCTTGCAACGCTGTATAGAACCAATGCCTTTATTCT +GTATTGCTGATGGATTTTTGAAAAATATGTAGGTGGACTTAGTTTTCTAAGGGGAATAGA +ATTTCTAATATATTTAAAATATTTTGCATGTATGTTCTGAAGGACATTGGTGTGTCATTT +CTATACCATCTGGCTACGAGAGGAGCCGACTGAAAGTCACACTGCCGGAGGAGGGGAGAG +GTGCTCTTCCGTTTCTGGTGTCTGTAGCCATCTCCAGTGGTAGCTGCAGTGATAATAATG +CTGCGGTGCCGACAGTTCTGGAAGGAGCAACAACAGTGATTTCAGCAGCAGCAGTATTGC +GGGATCCCCACGATGGAGCAAGGGAAATAATTCTGGAAGCAATGACAATATCAGCTGTGG +CTATAGCAGCTGAGATGTGAGTTCTCACGGTGGCAGCTTCAAGGACAGTAGTGATGGTCC +AATGGCGCCCAGACCTAGAAATGCACATTTCCTCAGCACCGGCTCCAGATGCTGAGCTTG +GACAGCTGACGCCTTGGATCATCTGCCACTGATCTCTGGTCAACATTTTTATCACCCAAC +ACAAAAGAAGCAGAGATTTATCAAGTTACTTAACCTGACCCTTTCATCTTTTGCTACACA +TACTCTTGTAATTGATCTCTCCATGAATTGTTTTCTGTTTAAAATATCTAGAATGTTTTC +TGCTTCCTGACTTGATTCTAATATTGTATAGGTACTAGAAATGGTTCTAGAAATAGATCT +TTATAGATGAGAATCTGGAAGTGGTTTGCTGACCTGTTTCAGTCTGAATGAATTCCTGAC +CTTCTTGTCGGGAGGAGACAGAAACCTGATCATCTGTAGTGTACGGTGGTATCATGATTA +CTTAAATCATCAAATGTGGTTATTGGGAATGATGTGTTTTTTAAAGTGGTACATGAGAGG +TAAAATTGCTATTGTAGTTGACTGTTGCAGTTATAATTTTGTCAACATGGTCTGTAAGAG +TGCAATGGCGTCGGCCCGGTGCGGTGGCTCACGCCTGTAATCCCAATACTTTGGGAGGCC +AAGGTGGGCCGATCACGAGGTCAGGAGATCCAGACCATCCTGGCTAACACAGTGAGACCC +CATCTCTACTAAAAATACAAAAAATTAGCCGTGTGTGGCGGCACACGCCTGTAGTCCCAG +CTACTTGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCGGGAGGCAGAGCTTGCAGTGAG +CCGAGATCGCGCCACTGCATTCCAGCCTGGGCGACAGAGCAAGACTCCATCTCAAAAAAA +AAAAAAAAAAAAAAAAAAAAGAGTGCAATGGAAAGCTGGTAGAAAATGGACATTGTTTAA +AGACCAAAACAACCACACTACTTTGCTAATCCCTATCAGCTAAAGACTAGAGAATATATG +AGGCATAGATTTACGTGGTGTTTGACTAAGGCATGCAGAATATAATCTTGACATAGGCTA +AGTTTATCAACATAGATACATAGAGATTCTAAAGTTAAAGTCTTAGCCCAAGAAGTTAGA +AGTGGTGCTCAAGTTTGTTTGTCTGACAGAAACTGTGAATCCACACTGGCCTGCTTATTT +TGAGGTTGCGTTGCCAGAGCTTTCCTAGCATAATAAAGAGAGGTGCATACAAAGGAATAG +GAATAGTAGGAGGTGGGGGTAAAAATATCAGGTGTGATCCACATGCCAAGCCGACCCCCA +CTGTGTCCCACAGGAAGCCCCAGAAGATGTTTCTCCAAGAAATTAGGATTCGTTTGTTGG +GGAGGGCTGCTGGCATGCTTGAAAAGTACTGTGACGGCTGAATTTTGTGGGCTTGGGGAG +ATTGCAGGTTCTCTGATTTCAAGGGGAATGATGTGATCCTAGAGTTGCAAAGAACAAGTG +ACAGTGGAGGCGCTTATGCTTTGTGACTGCACTAGAGACAAGGAAGACACAACTAGAATA +ATGGGGAGCAGGAATGGAGCGGCCAACAGAATATCTGACTGTTAGGGATCTTTGATGAAG +GCTGATTCTCAGGGAGTGAACTAGATCAGTGACCAACTATTTGTCTTTATATAACTGGGT +AGTGTGGATGGATTCTAATAAAGGGACTACTTACAGCACAGCAGGAAAGTCACAAAGAAA +CCAGACAGAAGAGTGTAAGTAGTAAGGGGCCAAGCAGTCATCTGACTAGAGACAGTGCCA +GCTTGCCAAAGAAGGCACCAGACAGAAGCTGTGATCTTCAGCAAAGGGACACAGTCTGCC +TGTGCTGACCCTGCAGGGGCAGAGGTGGGGGATAAACACACTCTTCTCTCACCTATCTTC +TGCCACCCCCTCCATTAGCTGAACCCCAATAAAAGCATGAGGGTAAGGGAGATCTCTGAA +GTATCCAATTCAGGTGAGCCTCCTAAGGAACAAAGCAGAATGCAGAAAAATTAAGAGTGG +GTCTAGGGAATAAAATAGAGATATGCACCAGAGTATGATGATGTGTCTGGGAAAGAATAT +ACAAATACTTTTAAAATTACTAGACAATAAACCTGAGATGACACTAATACAGGTAAATCT +CATTTAATGGTAATATATTCCAAGAAATGCATCATTAGGTGATTTTGTGGCTGTGCAGAC +ACCAAAGAGTGTACTTTATACAAACCTAGACAGCGTAGCCTACTACATACCTAGGCTATA +TCGTACAGCCTATTGCTCCTGGGCTACACACCTGTGCAGCATGTCACTGTGCTGAATACA +GTAGGCCAATGGTCCGCAACACCCAAGCCATGGACCAGCACCGGTTCGTGTCCTGTTAGG +AACTGGGCACAAAGCAGTAGATGAGTGGCTGGCCAGCCGAGCATTACTGCCTGAGCTCCG +CCTCCTGTCAGATCAGCAGCAGCATTAGACCCTCACAGGAGCGCAAACCCTATTGTGAAC +TGCCCATAGAAGGGATCTAGGTTATGTTCTCCTTATGAGAATCTAACTAGGCTGGGTGCT +GTGGCTCACGCCTGTAATCCCAACACTCTGGGAGGTCGAGGCAGGTGGATCACAAGGTCA +AGACAATCCTGGCCAACATGGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCTGGGT +GTGGTGGCGCATGCCTGTAGTCCCAGCTACTCGGGGGACTGAGACAGGAGAATCACTTGA +ACCCGGGAGGCAGAGGTTGCAGTGAGCCGAGATTGTGCCACTGCACTCCAGCCTGGCAAC +AGTGGGAGACTCAGTCTAAAAAAGAAAAAAAAGAAAAAAAAGAATCTAACTAATGCCTGA +TGATCTGAGGTGGAAGAGTTTCAGCCCAAAGCCATCCCCACTCCGTGGAAAAATTATCTT +TCACAAAACCAGTCCCTGGTGTCAAAACTTTGGGGCCCACTGCTGTAGGCAGTTATATCA +CAGTAGTAATATCTAAACATGGAAAAGATACAGTAAAAACATAGTACATTGGGAGACCGA +GGGGGGCGGATCACCTGAGGTCAGAAGTTCGAGACCAGCCTGACCAACATGGAGAAACTC +CGTCTGTACTAAAAATACAAAATTAGCTGGGCATGCTGGCGTGGGGCTGTAATCCCTGCT +ACTCGTGAGGCTGAGGCAGGAGAATCACTTGAACCCCGGAGGCAGAGGTTGCAGTGAGCC +AAGATCGTATCATTGAACTCCAGCCTGGGCAACAAAATAAAACTCCTTCTCAAAAAAAAA +CAAAGAAAAAAATATATATATATTACAAAATTTAAAGAGAGTGGTACACCAGTAAAGGAC +ACTTAGCATGAACAGAAGTTGCAGGACTGGCAGTTGCTCTGATGAGTCAGTGAGTACTTG +GTGAGTGAATGCGAAGGCCTAGGATATTACTGTACATAACTATAGACTTTATATGCACTG +TACACTTAGGCTACACTAAATGTATTTAAATTTTTTCTTTCTTTAACAAGTTCATCTTAG +CTTATCATGACTTTATAAACTTTTAATTTTTTTAATTTTTTGATTCTTTGGTAATAACAC +ATCTTAAAACAAAAACACATTGAACAGCTGTACAGAAATACTTTATATCCTTATTTGATA +AGCTTCATTTATTTTGATTTTTTATGTTTTAAACATTTTTGTTAAAAACTAAGATACAAA +CACACACACTAGCTTAGCCCTGTAAGGGTCAGGATAATCAATATCACTGTCTTCCATCTC +GAAATCTTGTCCAAGTGAAAGGTCTTCAGGGTCTTCAGTGGCAATAACATACATGCAGCT +GTCATTTTCTATGATAACAAGGCTTTCTTCTGGAAGAACTCGTGGAAGACCTTCCTGAAG +CTGTTTTATAGTTAATTTTTTTTAATGAGTAGCAGTACTACACTCTAAAAATATGAATAA +AATCTATAGTATTATACATACTGTTGATCCTTGAACAGTGCAAGGGTTAGGGGACCAGCT +CCTCTGCAGTTGAAAATCCATATATAATTCTGGGATATCCCCAAACTTAACTTAATATAT +GATATATATCATATATAATATATATGATATATATTACATATGATATATATCATATATATT +ATATATGATATATATTATATATAATATGTATGATATATATTATACACAATATGTATGATA +TATATTATACACAATATGTATGATATATATTATACACAATATGTATGATATATATTATAC +ACAATATGTATGATATATATTATATACAATAAGTATGATATATATTATATACAATATGTA +TGATATATATTATATACAACATATGATATATAATATACTATATGATAGAGATTATATACA +ATATATATGATAGAGATTATATACAATATATATGATACAGATTATATACAATATATATGA +TACAGATTATATACAATATATATGATACAGATTATATACAATATATATGATAGATTAGAT +ACTATATATGATATAGATTATATACAATATATGATATAGATTATATACAATATATATGAT +ATAGACTATATACTATATATGATATAGATTATATACTATATATGATATAAATGGTATATC +ATATATGATATAAATGGTATATCATATATGATATATACAATATATCGTATATATGATATA +GATGATATATCATCTATAAGATATAGATGATATATCATCTATAAGATATAGATGATATAT +CATCTATAAGATATAGATGATATATCATCTATAAGATATAGATGATATATCATACCTGAT +ATAGGTGATATATCATATATGATATAGATGATAAATCATATATGATATAGATGATATATA +TCATATATGATATAGATGATATATATCATATATGATATATCATATATTATATAATAAATG +ATATATATTATATATAATAAAAGCTATATATTACATAATAAATGATATATATTATGTAAA +ATATATGATATATATTATATATTATATCTGATATATATTATATATTATATATTATATATT +TTATCTGATATATATTATATTTGATATATTATATATTATATTATATATAATTATATTATA +TTATATTATATTATATATATTTTATATTATATTATATATAATTATATTATATTATATTAT +ATATTATATATAATTTATGATATATATAATGTATTATATATAATTTATGATATATATTAT +ATATTATAAATCATATATCATATATATTATGCTATATTATATATAATATAGCATAATATA +TCATATATTATATAATATATAATATAATATAATATAATATAATGTAATCATATATAATAT +ATAATATATTATATTATAAAATATATTATATTATGATATACTATATATTACATATTACAT +TAGATAATATTTTATATAATATATAATATATATTATATATTATACTTTATTATATTACAT +ATATAATTATACATTATATTTCATATATAATTTATAATTATATATAATTATATATTATAT +TATATAATATTATGTATAATATATTATTAAATATAATATTATATATTATATTAAATATAA +TATTATATATTATATTAAATATAATATTATATATTATATTAAATATAATATTATATATAA +GGATGCAGGATGTAAAAGGAAATTATATATATGTTATATATTATATATATTATATTATAT +ATAATTATATATATATTTGGGGGTGCCCTATTTCCTATCTCATAACTTATTTTAAGAAGC +ACAGCATAATAATGTGTGGACTTGGGATTCAGTTTTTGAAACGACACACTGAGCCTTCCA +TGACCTTCCTGTACATGTGAAAGCACACCTGTCTGCATGGCAGCATTTGGACCTCACAGT +GTGGATTGTGCCTTCACCCTGGAATGTTTATGCCCTATCGCCATGGTGATGTGATTAGGG +ATCTGCTGCCCTTGGTCCTAAGTGCCACTATCTGTGCTGAGTTTTTCAAAGGTCAGAGCA +GATTGAACCTTTGTGGTTCCATTTTCCCTGATTTTGATTTTTCTTATGGGGAACCTGTGT +GGCTGCATTCAAGGTATGTTCATACTGGCCTGTCAAATGCGATCTTTTCAAATTACTAGT +TAATGCTTTCAAAATATGTTATTTAAAAAATTAGCCTCTGTATTTTCCATATGCAGTTAT +AAATATGTTTCATGGTTAGGTTTTATTCCTCAATTTATATATTTGATTCTTATACCAAGC +AGAGTACCTTTGAAATTTTTCTTCATTTAAAAAATATGTATCTTGGCTCAAGCCTGTAAT +CCCAGCACTTTGGGAGGCCAAGGCAAGAGGATCACAAGGTGAGGAGATCAAGACCATCCT +GGCCAATACGGTGAAACCCTGTCTCTACTAAAAATACAAAAAATTAGCCAGGCATGATGG +CAGCTGGTGTAGTCCCAGTGTGAATTGGGATTCAGTTTATTCCCAAATTCCCAAAATATA +TATATATATATAATATATATTATATTATATATAATTTTATATATAATATATATTATATTA +TATATAATTTTATATATATATATTTGTCGGTGCCCTATTTCCCATCTCATAACTTATTTT +AAGAAGCCAGCATAATAATGTGTGGGCTTGGGATTCAGTTTTTGAAACAAAACACTGAGC +CTTTGATGACCTTCCTGTACTTGTAAAAGCCCACCTGTCTGCATGGCAGCAGTTGGACCT +CACAGTGTGGATTGTGCCTTCACCCTGGAATGTTTATGCCCTATCGCCATGGTGATGGGA +TTAGGGATCTCCTGCCCTTGGTCCTAAGTGCCACTATCTGTGCTGAGTTTTTCAAAGGTC +AGAGCAGATTGAACCATTGTGGTTTCATTTTCCCTGATTTTGATTTTTCTTATGGGGAAC +CTGTCTTGCTGCATTCAAGGTATGTTCATACTGGCCTGTCAAATGCGATCTTTTCAAATT +ACTAGTTAATGCTTTCAAAATATGTTATTTAAAAAATTAGCCTCTGTATTTTCCATATGC +AGTTATAAATATGTTTCATGATTATGTTTTATTCCTCAATTTATATATTTGATTATTGTA +CCAAGCAGAGTATCTTTGAAATTTTTCTTCATTTAAAAAATATGTATCTTGACTCAGGCC +TGTAATCCCAGCACTTTGGGAGGCCAAGGCAAGAGGATCACAAGGTGAGGAGATCAAGAC +CATCCTGGCCATTACAGTGAAACCCTGTCTCTACTAGAAATACAAAAAATTAGCCAGGCA +TGGTGGCAGCTGGTGTAGTCCCAGTGTGAATTGGGATTCAGTTTATTCAGTTTATTCCCA +AATTCCCAAATTATATATATATATATATATAATTTCCTTTTACATCCTGCATCCTTCAAC +GTTCCATCCCCCACCCCACAGATTAAGTTATTCCCCAGGGGAGAATATGGCAAAGTCTAT +TTTAATGCAGTTTTTAACCCAATTAAGAACCTATGAAATCATTACTTTCCAAAACTTTGG +AACAAAGCCACAGTAGTATGGATCCGTTGGAGGCTTTTCACACAATAAAATGTACATCTC +TTTGTTTTTAACATGTTTTTCCCTTCCTCTCTTCTTTTTTTGTGAAATGTGTATTTACTT +TAATATATTTGTAGTAAGTCACTTCCATGCACATATTAATTTTTTAAAGTAATAAGTATG +TGTATTGTCTACGTGTGAAAGAAAACACACATTTATTTTTATGCCTTGGAAGTTATCCAG +AATCATGGAATTGTCAATCACAGTCAATCACCCAACCTACTCACCTTTCCAGTGTAATCT +TAGTCAAATTTTTTTTTTGTTATCCAATGAGATGCAGTATTTCAACTCAGAAAGATAAAT +AGAGTGAATTTATAGAGACTATTAACTAAGAACATACAGTTTTATTTATACTCAGAAGCA +AGTAGATTATGTACATATATATGAAGATAAAAATTAAAAGGATAATTGTGTAAATTTGCA +TGTAGAGAGCTTTGAAAACCTGTTTACTTGTTAATGCTGTTTTGATGTATTGTGTCTTTG +TTCTCCCGACCCATCATCCAGAGCTCTCTGCAGGAGCTAAGTGCTCATCAGTTCCATGAT +TTGGAAACTGTCTAAGTTTAGAGGCACTTGTATTTGTTAGTAAATAAGGCAAGATGATAT +TGTTTCACAGGTTTTAGTGCAGAAGACTGAATAGATAAGCTGCTCCACCCAGTACACTGG +TGTTCATTTCATGGTCATCTCATCTGTTAACCATGGATATAAAACATTTATCTTCAATGA +TGGGGTTTTACCATGTTGGTCAGGCTGGTCTCGAACTCCTGACCTCAAATGATCCACCCA +CCTCCACCTTCCAAACTGCTGGGATTACAGGTGTGAGCCACTATGCCTGACTGATTATTT +TCATAACCAAGAAAAGAAATAAATACAATTAATGCTGGTGCATGGTATTAAATCTAGTTT +TTAAAACATTCACACATAAACAAGGCAGAACCCTATACCCTCCATGATAAATGCAGTAGC +AGTGTATGTGGGTCTGTGGAGGTTGAAAGGGACTTGGTAGATGTCAAGAAGGTAGTGGCA +GTCCTGCTGGGCTTTTAAAGGGTCTGAAGAAGTGACAGGATGCTGTGGTTGAATCCTAGC +ATGTATTTTAGCATTTGTTCATTTGGAGTTGATTATTTCACGTTGCTTTCATTTGCCATT +ACCTGGAAAGCCAAGGGCTCTACTCTCATTTCCTTGCTGCTCTTTCTTTGCCTTCCTTGG +TCCGTGAAGAAGATGGTCCAGGAGAAGCTCATTCCATGCTTGTTAACCAGGCACGCCCCT +AAGTTCCAGTCCCTGAGTCATTCATGAGTAGCACTGCCAATGAACTGACAGCAATGCTGT +GTCCCTCCACATCCCCTAGGTGACTCGAAGAAGCCTTCCAAAAAGCGTGTGAAAAGGAAG +CCCTACTCTACTACCAAGGTAAAGTAGCCTGTCTTTGCCTAAGATGCAAATGTTGTTTTC +TTGGATCCTTTATTTTTCAGTTGATATCAGCTATGGGAAAATTATCCACTACATTATAGG +TGTTAGATAATATTTCCTTGGGGGTGGAGGAGGTGTATTTTACCAACTGACACCTGATTC +CAGAGGACGTGCAAAATTGGCAGTGTCAGATAGTACACTGGGTGCTAAGGGATGTTTTCT +TCAGGAACAAGCTTTCCACTTTAGATAAGAATTCTGCAATTTCTACTCAAAAATTACCTA +GACAGAAACATTCTTCAAGAAAAGCTCCTGTGCTTTCCTAAGGGAACTCTACTCTAGAGT +TGGGGCTTTTGACTTGAACCTTATTTCCAGTCTTGGTTACCCAGAGTTTCCAAGTGAACA +AAAGACCTGTGTGAGCCATCCATAGCATAGCCTGATTCTCAGAGTGTTTTCCTTCTCTAA +TTACAGGTGACTTCAGGGAGCACATTCAATGGTACGTATTCTGGAATCACTCACTGGTTG +TTAGAAAAGGATTCTACAGGAAATCTGGAGCTTAACTGCTGGCTTTTGTCTGGAGAGCCT +CCATGATCCAAGACATCTGGTGGGAATGAGGATGTAGGGTATAGTAAAAGAAACTGGTTT +TCCTGGTGACATACTCTTTTTATCTATGTATAGTTTCTGGGAACATGTTCACATTAGGTT +GTGTGTGGGTATGTGTGTATTAGGGCGGGGGTGGGGTGAGGTGGTCTGTGTGCAAGTCTG +CATGATTTGCTTGTGAATGTGTGTCTATGTGTGTTTCCCCTACGAAAAAAATGTTGTGTT +TACCCAGCACAACTCTCAGTGCCATGTTTCTTAATTTAACAAATCAGACCACATACTTTA +CTTACATTAGTTCACACCTCATCATCATCATGCCCATATGTTGTGAGCTTGTTTACTGAG +CCCACATGCCAGATGGAGAAACTAAGCCACATAAATAAATGTGCCCTGGTTCACTTGCTG +CATAGTGAAGAGTCAAAATGTTTACTCATACGGTGCTAATGTTGAAGGCCTGAACTACAA +CCTCTATTTATCAGCCAGTGAAGAGATCACTATTCACCATGCAAGGGAGTTCCAGCACCC +TCTATGCCTGGAATTACCCACACCTGCAGAGATCCCAAACGCCATCCCTCACATAAGAGA +ACGTCATGATCTCATAATCCAGGTAGCTATGTAGACATCTTCCTGCAGGTGTCACATAGT +CCTTAGTGTGAAACCAACATAGAAAGCCCATGTTTCTGATCAAATCACAGGTTCTGAAAC +ACTAAGGGAGGCACTAAGTAGGACAATGTGGTGCCTGCGTGTCATAGCTGGGTCTCCTCA +AGACATGGATCAAGTCCAGTAAGAATTGGGGAGATGCTTTAGAGTCTTGATGGAGTTATC +ACCACAAGCCCTCTGAGCTACACACTTTAGGGATCATGACCATTAAGTACTCAAATTACC +ATTTGGTTGTTATCCGGGTATCCGTCGTCCTTGTGGCAACCCTCTTGTGAAGCTGGTGTG +GACAGCCTCAGTGCTGGAGCTGTGCCTGCCTTCTGAGTGGACCCTTTCTGTGTTAGCAGG +TGGGTACAAGCGTGGGGGTCAGCACACTCAGTGGATTTACACACACAGCGTTGAAGAGTA +AGGCTGGGCTTCATTATTTATACATTTTCAATAAATGATGATCTTCATAACATAAAATCA +ATGATGTAGTACACTAGAATACTGTCCCTAGTATTGAATCTTGTCTCTCAGCAAAGGGTT +GCTTAAAGTCACGTGACAGATTCCATTCAACTGATGGCACATGCTGTAGCAGCAGTTAAA +GCAGTCATTTGAAAAGGCTTTTACTATAAACTTACGTGTGAGCCTGAAGTGGGGGATAAA +AGAGGCGATTAGCTCCCCTGTGCCATGTTTCTCTTATGTGCGTGGTGGAGGAAAATTACA +CAGGAAGGTGATGGAGAGAACAGAGCAAAGGATTGGACAGGTCCATTGAACCCATAAGAC +TATGGTGAGGTTAGTGAATGAGATTGGTCATTTTAGGTCAAATTTTACCCAGAGCTGGTG +CAGCCACTGCCCATTCTTAGCCAGACCTTATTGCAGGCAGCTCTGATCAATAGTCAAGGA +GGCAGTGGGGGTTGTAGACTTTACTCATTAAATCACCAAAGCACCAGCCCACACGGCCAC +TTTTCCAGTTAATTGACAGTAGCTTGCACATTCAGGTTTGATCAGTGGAAGGGAAGTTAC +TCTTTGCAGACCCATTTTTGACAATCATTTTGCGGTGTCGGAAGGTCTGAGCAGCCTCGG +GAGGCAAGCAGTCCCTGGTCCCTCAGTGTAGTCACTGGAGGAGACAGTCACTGAGAGGCA +GCTGGCAGGGTGAAGGGAAAGGGGAGGCAGGCCACAGAGATGACAGCCTTTAAGCTGTCA +TACTGGGAGGTCAAGGATCTGAAAGAGGAAGGAGAATTCTTTATCATTAAGGACCTGTCC +TTATCTCAGGCATTTCCTCCAGAGCACCACCTTTGTCCACCCACACACCTTGGGCTAGGA +GGACTGGAGAAAGACAGTGAGGGGTCTCTTGGGTCTCTGGCACAGGGCGTGATGAAGAGA +TGGCAGTTTTTCAGGAATCTCTCTCTTTAGGGAACCAAATACATTTCCCATCTCAGGTCC +TTCACTCAGCGGGGTTGAGGTTCTGCTCGTCACTTATCATCTCTGAATGTCAGCACCCTC +AAGTGTAAAATCTCAGCCACAGCCCCTCCTCTGCACCCCCTGCAGGGCTGATGTTCTCTA +TAAACCATAAGGCGTCATGCCCACGGAAAAGCCGAACAGGAAAGCATGCTCCACTGCCCC +GGAGCCATCCAAGTTCCCCCTCCATATTCCGCCACTGCTAAGTGTCCAGCTTATTCCTCC +TGGCATGTAGTAAACACTTAGAGAACATTACTGAAGTACCAGTCCTCTCTAAGGTTTTCC +TGTATTTAGTGATTTTTTAGCCCTGTACTGTGATACTAAGAAGTAGGGCTTAAATAGGGC +CTAAAAAGTATTGCTAAAATTACATTATGACAGTGCAGAGAACTGAGGGCAGAGGGAGGA +CATGAGCTTGCCAGGTCCACATGGCTTAGTGGAATTTGAATCCGGGCCCCCACTCTGCAC +CAGCCCTGCACTCACAGTCATCCTGCTGTGTTCCCCTCTCCAGGAAGGCACTGCCCACGC +AGTCTGTCTGATAGAGGTGTTGAGTGCTCACTGAACTCCGTGATCTTCCTGAAACCCAAC +TTTGATTCAGTGGGCTCTGCTTGGAAGCCTGTAAAGAAAAGGATCATAAGTTTAAACTTA +GAACAGATTATCACTATTTTCCCTCTGGTCTTCTGTCAGCAAGATGTCAACAGCCCTATC +TATTGTCAATGCATTAACCAGCATCTTCTCTGATAGAGAATACAAGAAGATATGCTGTGC +ACACCAACCAGTGTAGGAGACCTCATGGCTCCCGGGTAAAGAAGAAGAGGTACCCACAAG +AAGGTACTGTGGAAGTTCATTAATTAAGTTGATTCAAGAATTGCAGTTGCGGGGAGTATT +CAGTGTCCCATATGTAAGAGGAAACTATGAAGAGACTAAGCCATATTTTTTAATGTGTCA +GGATTCTAATTTGCCTGGTCAGTAAATATTGCTACCACCACAAAAGTAAATATCTACTTA +AAAGTCAATTTTGGTTCATGTTTAATGATAGACAATGTTTCAAGCTAATGTCTAGAACTT +ACCTGGTTGTTAAACATAAGCATAGATCTCCCTGAAAGAGTGGTGCTATATTATTATTTT +TCAATTAATATATTTCTTTAGAGAGTTTTAAATTGACATAAAAACTGAGCATATGGCCGG +GCGTGGTGGCTCACACTTATAATCCCAGCACTTTAGGAGGCCAAGGCAGGCAGATCATCT +GAGGTCAGGAGTTGGAGACCAGCCTGGCCAACATGGTGAAACCCCATCTCTACTAAAAAT +CCAAAAAAATTAGCCGGGTGTGGTGGCAGGCGCCTGTAATCCCAGCTACTCAGGAGGCGG +AGGCAGGAGAATCGCTTGAACCCAGGAGGCAGAGGTTGCAGTGAGCCAAGATCATGCCAT +TGCACTCCAGCCTGGGTGACAAGAGTGAAACTCCATCTCAAAATTAATAAATAAATAAAT +AAATAAATAAATAAATAAAAATTGAGTATATAATACAGGAAGTTCCCATATTATTCTGTC +TCCTCACCCTCACTTCCTAATTTCACCTATTAGTAACATCTTACATTACTGTGGTACATT +TGCTAGAATAATGAGAAAATATTGACACATTATTATCTGAAGTCTACATTTGCATAATGT +TCATTCTTTCTGTTATACATATATATGAATTTTGAAATATTTAAAACATTATGTTCACCC +TTATGGTCTCATAAAGAAAATGTTCACTTCCCTAAAAATCCTCTCTTCTCATTAATCTCT +GTCCTCTTTCTCCAGAAACCTTGGCAACTATTAATATTTTTACTATCGCTTCAGCTTTGC +CTTTTCCAGAATGTCATATAGTTGGAATCATATATTATGTAGTTTTTTCAGATGAATTTA +TTGCACTAAATTGATGTACGCTTTAGCTGCTTTCATGTCTTTTTTATGCCTTAATGGCAA +AAAATGGCACATTAAATCACCAAATAATATTGCATTCAATGAATTTTTGTCTTTTTATTC +ACCTGTTGAAGAATTCGGTAGATTTCATGAGAGAAACCATCTGGGCCTGGTGCTTTCTTT +TTCGGAATGCTCTTAATGTGAATTCAACTTATTTAATAGACATAAGTTTATTCACATTAG +GATTCTAGCGTGACCTTGGGAAGATTGCCTTTCAAGGAATTGATACATTTCACTGAGGTT +ATCAGACTGCGGTCATAGAACTGTTCATGATATTCCTTTTAATGCCTAACAGTTCAGTAG +AGATGGCTCCTCTTTTATTTCTGAAATTGGTCATTTGTGTTATCTTCTTTTTCTTGGTTA +GCCTGCATATCAATTCATTCATTGTAATGAGCATATCAAAGAACCAGCTTTTGGTTTTAT +TGATTTTCTGATGATTTCAGTGTTTTAATTTTATTGATTTCTGTGATGTTGTTTATTACT +TTTACTTGCTTTCCATTGCATTCCTCTATTTTCTATAGTTCCCTAATTGAAACATGATAT +TACTGATTTTAGGTCTTGTGATTTTTAGTATATTGCATCCAATGCTGTAGATTTCCCTCT +AAGGACTGCTTTTGCTACATCCAGAAATCTTGCCAAGTCACATTTTCTTTTAATGTAGTT +AAAAGTATTTTTAATTTTCTATTGAGACTTCTTAACCCATGAGTTATTTAAAAGTGCATT +GCTAATTTGCAAATATTTGGGGATTTTGTGGCTCTTTTACAGTTGTTGATTTTTTGTTGT +CAGGTATGTGTTGCAAAAGCAGTCGTCTACCTCATCTTGCCACCACCCAAGATGGCCCAG +GATGTGGGCTCTCCCTGAGTGAATCTTTGGCAATCTGCCAACCTGATGTGTTCGGCCTCC +TTCTTTAGTCTGAGCTTGCCTTCTGCTTAGAAAGGGCCATTCTCAGTTCTGGCAGGGAGT +TTTCCCAACATTGAGAAGGTGGCATTCTTACTCCCCACTGCAGCCTGCACCTCTGACCGG +TGGTCAGCAGACAGGACAGAGGTCCTCATTAGACAGAGTTCAGCAGGGTCTCTGACCAAA +GTGCATCTTCAGAGTCTGCACCTACCCACTGTGACCACGGGCAGGCTCTGAGTCCTAAAG +CAGGAGGAACTGTGCGACCATCCTGATTGGAAATTTGTGAGGATCACCGTGTTACTCAAG +TAAGGTCTTTGGAAAGTGTCGTATTACTACTGTTTGTGAACTGCTTGTTGGTGGCCTGGC +TGAGCCACACACTTTATGAAAACCAGGACCCCTCAGCTGGTGTGGGTGTCTATGCAGCCT +GAGACCCTCATGTGAACAGCCTCGTGGCAGCTGTCTTTGCCCCTTGCCACCATCAGTGCC +TCCTTGTTCCTGGGCACTGCTTTCTCTGATGGTGCTCCATTGTTTTCCTGCACCTCAGTG +TCTACAGCTGGATGTCTCTTCCGCAATCTAGGCGAGGGGGCATCAACGGCAGTTCTGCTG +TGGCACTGCCCTCCTTCTTAGCTTGTCTTGCTCTGTCTTAGGCTCCCTCAAAGATCCCAC +CCTTCAGGTTCTTCCACAAGTTTCTTATTGAAATCCGAGCAGAAAACTATGACCAATATG +ACCAATCCTATACCCACTGAAGACATGAATGAAGAATTAAAACAATTCTCCATGGACTCT +ACCATATAGATCCCTAGAAGTAATTTCTAAAAAAAAAAAAATCAAGGAAAATGTAATAGT +TTTCCATAAATTAGAATACCCTACATGTACAATTAAATGAAATGGCTAGTATAGTCTTGA +AACCAAAACCAGATAAGGTAAATTAAATTCTGTGATATTTTAAAATACTTTAAATTCTGA +CTAATGTGAGTTAATCTCAAAATATGAAATAGTAGATTAACATTGAAAATGCAATAAATA +AAATTAGCTACCTCAAGAGTTTAATGGAAAAAAATGTGATTATTGCAATAGATTCAGGAA +ATTCATGAATAACATTCACCCTATATTTGTAGGACAACTATCTGATTAACTTTAAGTGAC +CTGTTACAACCACTTGAATTAATGCTGCTTTCACAGCATATCTCTTGGCTTGTTAAAAAC +CCGACAAGAATTTCCGTAACATTATTTTTAACACCTATATTGGGTGTGAACCCACCATAA +AGTTTGCCCACTGAAAAGGTCTACAATTTGATGCTTTATTAAATTGATACTGTGTGCACC +CAACACCACGATCTAATTTAAATATGTTTCCCTCACCCAAGTTCTGTCTTGCGCACTGGC +AGTTAATCCCCACTCCCATCTCCAGCCCTAAGCAATACTGCTGTGACATTCCATCTCCAT +AAATTTCCCACTTGCTTTATAGAAATGGACATATATATATATTTGGAATCTGACTTCCTT +CATTTAGCATACTATGTTTGAAGTTAATTGACGTGTTAGCACGTGCTGGTCATGTGTTTT +CCTTCATAGTCTGCTGTGTTTATTCATACAAATAGTGTTTATTCATTTATCAGTTAATGG +ACATTTAATTGTTTTGTTATTTTCTTTGATGAGTAATGTAGCTTTGAGCATTCACATACA +GTCATGTAATGCATAATGACATTTTGGTCAAAAAAAATTTTTTTTTTTCTGAGACCCAGG +CTGGAGTGCAGTGGCACAATCTCGGGTCACTGGAACCTCCATCTCCCAGGTTTAAGCAAT +TCTCATGCCTCAACCTCCCGAGTAGCTGGGACAACTGGCACACACCACCACGCCTGGATA +ATTTTTGTATTTTCAGTAGAGACAGGATTTTGCTGTGTTGGTCAGGCTAGTCTCAAACTC +CTAGCCTCAGGTGATCCACCCACCTCTGCCTCCCAAAGTGCTGGGATTATAGGCATGAGC +CACCACACCCAGCCTAATTTTTTTAAGAAAGAAGGGAACTATTTTCTAAATTACTTTTGC +CAATTTATATTCCTACCATGATGCATAGCACTAATTTCACCGTACAATGTATGGTAGGCC +CCAATATGTAAGAAATGATGAAAGTAACACATAAAGATTAGTATAAGACAAATGAGATTA +TCGTTGTTGCTATCATCTTTGTCAAATTCTGAAAACAATCTGAGTATATTTTTATATAAA +TATGCTTGGCAACATAGCTGAAAAAAGCATTATCAGTTACATTTATCAGTAACAAAGACA +TAAATTTGAAGGGGGAAAAACACTTGTACTAACAATGCAATGTCAGAATTAACATAAAAA +TTCTGCTGGTCACTTTGGAATATTTAATTGCCTGGGGCAGTGTTTAGTAGACAAATGAGC +ATCTATGGAGCACCCAAAGTAGGGGAATCAACAGAACTTGGGTTTCAAAAGTTATCTGGG +TTTAGAGCGTGAAACTTTGTTAGAGGACACACACCTTGCATGAGTGAGGTGCCTTGGTGT +GTGTGGACGTATCATTATGCTTGGAGGTACAGCATAATGGTGGCTTCCTCCAGAAAGGGA +CATTTGGGGTAGATTCATGCCATCTAGACAACACAGCCTGATGTGGCATGGACATGAATG +GAGGTGAAATGGTCAGTAGTTGAGAGGATCAGTCCTGACAAGGGCCGAGGTGAAAAACCT +GGGAACACCTTCAGGTGCAAAGTCTTCAGTTGAAAAAGGAGGTGGTCACAGGAAATACTG +AGATGGGTCAGCAATGCATGGGAGACAGAGTTCTTGGCCCTGCAGGGTGAGTAGTGTGGA +TTCTCAAGTTTTCTCCTCTCTCCATTAATTTCTTTCCCAATGCAGATGACTTCCATCATA +CAGTCTTCAGCAACCTTGAAAGATTGGACAAGCTTCAGCCCACTCTTGAAGGTAAAGGAA +GGCAGCTAACAAGACTGGCATCTGGGCTTGGCTGTGCATGTTTTCTATCGTGGGGAAATA +TATGTAACACATTATTTATCATTTGAACCTTTTAACCAAAGTGTGCACTCCGTGGCATTC +AATATATTCACAGGGTTGCATAACCAACACCACTATCTACACCCACAATTTTGATGATTT +CTTACAAAACCTTGTCCACAATAAGCAATATAGCACCTTCCCCCTATTTCCAGCCCATGG +TGATTCCTATCCGACTTTCTCTTGTATGAATTTGACTATTCTAGGCACTTCATGTAATTA +CAATTATACAATATATTCCTTTTGTGTCTGGCTTATTTCACTAAGCATAATGTTCTCAAT +GTCCACCCATGTTGTATCATCTATCAAAATGATGTTCGTTTTTTACAGATGGATGATGTA +GCATTGCATGCAGACCACCTTGCTTTTATTACATTCATTTGTTCACTGATGGTTGGATTA +TTTCCACCTTTTGGCTCCTGTGAAAAGTGATGCTACAAACATTAGTATACAAACATCTGT +TTGATTTCTGTTCTCTATTCTTTGGGGTGCCTAAGAGTAGAGTTCCTGGGTCCAACAGGG +GTTCTATATTTAACCTTCTGAGCCACTGCAGACTGTTTTTCACAGTGGCTGCAACTTTAT +CCATTTCTACCATCAATGTATCAGGGTTACAATTTCTTTACGTCCTTGTTCACACTTATT +TTCCTTTAAATCATCCTAGTAGGTGTATATTGGTGGCTGCTTGTGTTTTTCATTTGCATT +TCCCTAATGACTAATGATCCTGAGCAGCTTTTCCTGTGCTACTATCTGTGGCTGTATCTT +CTTTAGGGAAATATATGTTGAAGTCTTTTGCCCATTTTTAAAGAGTTGTCTGATTTTTAT +TTAGTTAGTTTGTTGCTGTAGATTTTTGAATATATCTTAAATATATTTAAAAATATTCTA +AATTTTAGTCTCTTACAAGATAAATGATTTGCAAATATTTCCCCCTTTGTGTAGAACTTT +AGATTCACAAACTTCATTAATTTGTATGAAATCCTCAGCAGTTGACCCCAAACAGATAAG +ACTGAAGCAGTATTTTAGGAATAGTTGAAAGTATGATCACCACAAAACATAAGCGTAATC +AAATCCTGCAAGCTACATGTAAGGCACAATGACAAATAAGGCAGCAAAGGGCCATCTGGT +GATTAGTTCACCACACTTGTTGCAACTGTTTGCACTGCAGAGTTAAAACATACCAGCATT +CAACCCATGTCTCCTGTCTTGAAGTAAACTGTCGTATGTTGGCTGGCCTGAACAAGCGTA +GATATTCTCCATCCTCAATTAATATGCATGCATGACAAAGAAAAGGAGGCCTGGATGAAA +AAATACTGTGTGATTAATAATTATGCTTTAATTAATTTTAAAGGATATAATTTCAGTACT +TCTAATTCTCCCATCAGCAGTTATAACAAAGGATTAGTGAATAAATACCATAGACTGTTT +TGCCTAGAATTGAATCCAACCTGTCTATTAAACTTTGCTTTTATTCAAGTGCAAAATGCT +AAAACACATAATAACTGCAGTGACAGCCACTGTGGATCCTCAGAGGTAAAAGTAGTCTTG +GGACATAAATCCTGCAAGTAATATTGTTTTTACAGGTTTAGAAAACCATTTAGCTGGGTT +TCAAACCTCACAGTGTGAGCAGTGGGACTCTCATCAAACTATAGCATGTGCTTCAGTACC +ATTTGTAGACTGACTCATTCCCATTGCCTTAAGTTGCCATCAGCAAAATGCCAGGGACTC +TATTTCTTGCTCCTTAGCTCCTCGTTCTTGCCTGTCTTTCCACGAGGGAGGATTTTCTAG +CAGGAGCTCAAGCTGTGCTTTTAATGAAACACATCCACACACACTGTCCTGTTGTCCACA +TTAAGCAGAGCTCCCTGAATAACTCATGAACAAAAGCATCTATGACTAACTGTTGCTCTG +TGTCCTCCTAGCCTCTGAGGAGTCTCTAGTTCACAAGGACAGAGGAGATGGAGAGAGGCC +AGTCAACGTGAGGGTAAGGTTGCCTTGCTTTCTCTGAAATAGAAATGTTCCTTTCTTGTT +GTCTTTCTTTTTCAACTGACTTTACATGTGAAAAGATGACAATGTCCATGACAGGTATTA +AATGCAGTTTTCTGAGGGGGAGGAAGAAGTGACTCTTAGCAACTGATATGTAATACAAAA +TGGCATTTAGCTATGATGGCTTCAGGTTGTAGACTGTATCCTTGGGGTCCTTGTCCTTGG +AAGCAATGTCTTCTCCTTGGATTCAGTATTTTGCACTTGCCAACCTACGTGGACCTGAGA +GATCCACCATCCAGAAGCTGATGTCTTTTCCAGTGTGTATCCTACCCTTGTTTTGGAGGC +CTTGAAGTTGACTACACTTTCTGATCAAGTTTTCAATATTCATTGAGAGAAACACAGCCT +TGTGCAAACAATCCACAACATGACATACCCCTCAAAAAGCTTTGTTTCTGTATTGCAGGT +GGTGCAGGTGGCCCCTCTGAGGCATGAATCTAGTAAGTATTCTGGAATCACTTACCAAGA +AAACAATCTGGATGCCAAGAAAGGTGTGGCATCCTTGCCTGGTTTCAATGTGAAGAGCCA +CCCTGATCCTGGGATTGTGATAGGAATAAGTATAGGGGAAGTGTTTTTTTAAAACCTGAA +TTCCCCAGGGAAAAATTATGGCCAAATTTTGAGGAAGCAGCTGTGCTCCCTTTTGGGTGG +TGCTGAGTTGGGTGCTTGAGGATTGGTGGTGTCTTGTGTGAGGCTGCATCGTGTGGTGTG +AATGTGTGTGTTTCTGTACAGGTGAGGCTGTGTGTTTTCTCAGGAGAGATTTCCCACTTA +TACAACCCAATCACCAGTGTCCACTTCTAACAATAAAATCCACCCCCGCTCTACTCTCTC +TGTACAGTGACTCCTCCACCCTCACCAGAGCCATCCCCGGGTCTGCCTTATTATCCCCAC +TGCTCAGGTGGAGAACCTGAAGGGCCAAGGGAGTGGCCCCAGCTCCCGAGTTCCTGAATG +AAAAAGTGAAAACACGAACCCAGGAGTGTGGGCCAGTGCTGACGCTGACATGCACTTAGT +CATGGGGTGTTCACCACCACACAGGGAGTCCAGCATTCATGTATAAACCCTAAGGCACCG +AGCCCAAAAGGCCCCAGGCACTGCCCATCATCATAAAGTGGTCTCCGTGGTCACACAACC +CAGGGCAGTTATAGGTTCATCTCCCCACGGACAGGCATAGTCATCAGTGTGTCAAAAGCA +CAAAGATCCCCAGGTGTTTGGCTCAGCTCACCGATCCTTTTTTTTTTTTTTTTTAACTTT +TAAGTTCAGGGGTACATGTGCAGGATGTGCAGGTTTGCTACATATATAAATGTGTGTCAT +GAGAGTTTGTTGTACAGATTATTGCATCACCCATATATTGAGCCTAATATCAGTTATTTT +TCCTGATCCACCCCCTCCTCCCACCTCCCACCCTCCAGTAGGCCCCACGCTCACAAATTC +TAAGAGGAGTGGGGGACCACAAAGGCCAGTGTGGCCCACTTCAGTTGTGAAGTTAATTTG +CTCAGCAACTGGCCAAAGTCTATAAGGATGGGTGATGTATTTTAGTAGATTTAGTAATAC +TATCTTCCCAAGCCCTAAAATGCTCAAATCCTGCCAGCCAAAAATGGTGAGGAGGGACAG +ATAGGAACTCTGTGTGGCACTTGGTTATTAGCCTGGCTTCCATCCCTTAGTGGCAACTCT +CTTGTATATGTGGGTTAAAGACCCTCAGCCTCAAGCCAAGCCTCCTCCATGAGGAGCCAT +CTCACTATTGACTGGCTAGTGCCGGGTATGGCCACCAGCCCAACTGAAACAAAATGTTGC +TTTAAAACAAGTGTAAATCTCATACATACAACAGGCAAATGCAGAAGCAGTGTGGTCTCG +CAAGTTGTAAAGAGGACAGTCGCAATTTTGCTGGACTTCAACCTGGGTAGAAGACACGAG +GGAACTCTGTCACTAAATCACGGCAGAGTTCAAGGCCGCTTGTAGACTATTTCGTGTTAT +AGAAGGTGGCCTTTAGCTACTAAGCAAAGGCCTCTGTTTCTCATTTCTTTCCTGTTCATC +TCCTTGGTCATCCTTCTTCCACAAGGGAAACGAGCCCAAGCAAAAGGCAGTTTCAATATT +AATTTGACCGAGGTTTTGTGCAGTTAATTATCATCCAGGTAATCAGGTGCAACCCAGTCT +GCCTAGCAGCCCCCCTATCTCTGCTCTGTGTTTTCATTTAATAAACATTTTGGTCTACTT +ACTATGTGCTAGATTTTCTCGAGACCAAGTAAATGAGATAGAATCCTTATGTTGGCAGCT +AAGTTAGATTTCACATAACTGACAAAAATTAAAATTTCTGATTTCTTGTAAAAATATTTT +GTATGTGTGAATGCATACTGAATGTAAAGTGGATAAAAAACTCACACTTGCACTCATGGA +AGGCTTTTCATGAATTTGTCAATTTTTATTTTTTATATTTCCCCACTTCACTGGATAATG +CATACCTGAACCTGGAAACTGATGCCCACTGCAGAAAGTGTTCTGAGCCACATCCCTTAG +CTTCACTAGTGCAGGTCCACCTGGGAGGATGTCCCAGCATCAGCTTGGCCCATGCTGTGA +TCAGCCACCTCCATGCACCACACCAAGCAAGCCCCTGGGTGATTCACAGTCTCCACTACC +AGGGCACTGACCTTAACTCTGTGTTCTTCTAGCTCCCCATGAGGACACCGTACACAACAT +CACTAACGAGGATGCCTCACACGATATCACTAACGAGGACGCTGTCCACGGCATCGCTAA +CGAGGCCGCCGACAAGGGCAACGCCAACGAGGACGCCGCCCAGGGCATCGCCAACGAGGA +CGCCGCCCACGGAATCGCCAGCGAGGACGCCGCCCAGGGCATCGCCAACGAGGTCGCCGC +CCAGGGCATCGCCAACGAGGACGCCGCCCAGGGCATCGCCAACGAGGACGCCGTCCAGGG +CATCGCCAACGAGGACGCCGCCCACGGCATCGCCAACGAGGACGCTGCCCACGGCATTGC +TAACGAGGATGCCGTGCACGGCATCGCTAATGAGGACTCCGTATACGACATCGCTAATGA +GGATGCCATATATGACATCGCTAATGACACCGTACAAGGCACGCTAAAGAGGACGCTGTA +CACGACATCGCTAATGAGGACACCATACAAGGCATTGGTAATGAGGACGTTGTATATGAC +ATCGCTAACAAGGACACTCTACAAGCCGTCGCTAACAAGGACACTGTACACAACATCGCT +AATGACGGCACCGTACAAGACATCACCAATGAGGGCGCTTTATACGACATTGCTAATGAT +ACCGACAAGGCACGCTAACGCGGACACTGTACACGACATCGCTAATGAGGACTCCGTATA +CCACATCGCTAATGAGGGTGCCGTATATGACATCGCTAATGACACCGTACAAGGCACGCT +AACGAGGACGCTGTACACGACATCGCTAATGAGGACACCATACAAGGCATCGGTAATGAG +GACGCTGTATACGACATCGCTAACGAGGACACCATACAAGCCGTCGCTAACAAGGACACT +GTACACAACATCGCTAATGACGGCACCGTACAAGACATCACCAATGAGGGCGCTTTATAC +GACATTGCTAATGATACCGACAAGGCACGCTAACGTGGACGCTGTACACGACATTGCTAA +TGAGGACACCGTATAAGACATCGCTAGTAACTATCGCAAGAACAAAAAACCAAACACCGC +ATATTCTCACTCATAGGTGGGAATTGAACAATGAGATCACATGGACACAGGAAGGGGAAT +ATCACATTCTGGGGACTGTTGTGGGGTGGGGGGAGGGGGGAGGGATAGCATCGGGAGATA +TACCTAATGCTAGATGATGAGTTAGTGGGTGCAGCGCACCAGCGTGGCACATGTATACAT +ATGTAACTAACCTGCACAATGTGCACATGTACCCTAAAACTTAAAGTATATATAAAAAAA +AAAGACATCGCTAGTGAGCACGCTGTATACGACATCGCTAATGAGGACACCATACAAGGC +ATCGCTAACGATGACGCTGTACACAACATCACTAATGATGACACCGTATAAGACATCGCT +AATTATGACGCTGTATACGACATCGCTAATGACACCGTACGAGGCACGCTAACAAGGATG +CTGTACACAACATCGCTAATGAGGACAGTGTACAAGCCATCGCTAATGAGGACACTGTAT +ATGACATTGCTAACGAGGACACTGTACAAGGCATTGCTAACGAGGACGCTGTACACAACA +TCGCTAATGAGGACACCATATAAGACATCACCAATGAGGATGCTCTATATGACATCGCTA +ATGACACCCACAAGGCATGCTAACGAGGACGCTGTAGACGACATTGCTTATAAGGACACC +GTACAAGACATCGCTAACGAGGACGCTGTATACGACATCGCTAATGAGGACGTTGTATAT +GACATCGCTAATGAGGATGCTTTACAAGACATAGCGAATGAGGTTGCTGTATATGACATC +GCTAATGAGGACATTGTATATGACATCGCTAATGAGGACGCTCTATACGACATCACTAAT +GAGGACGCTGTATACAACATCGCTAATGAGGACGCTGTATATGGCATCGCTAATGAGGAT +GCTGTATACGAATTCGCTAATAAGGACGCTGTATATGACATTGCTAATGAGGACACTGTA +CAAGACATCTGTAAAAAAGAAGATGCTGCCAATGTAAGACACTTTTCTTTGTCTTGAACA +GAAATGTTACTTTCCTGGCTTCTTTCCAATCAGATGTAGACATGAACATCTGCCAGTGTG +CATTATCGATGTCATCTGCAGTTTAATCAAATGTAGACATGAACATCTGCCAATGTGGAC +TATTTATGACATCTGCAATTCCCTTGGTGTGGTGCTATTGATTGGCGGCCTCTCACCAAC +CCATGCCAGGCACACTGGGGTGTGGTAGATGGCAGCATCCACGATCCACTGCAATGCAGA +GGTGTTTCCCTCCACAGCAGTTTTCCCCCATGGATTAAGAGTTGTGAAACTGCCAATCTA +GATACACTTTAAAGATAAATTCTGTGGGAAAAGGTCTTGTCTTTTCCACAGGTGTCTTCC +GTGCCAGTTTTGGGGGACTTTGACCTTTGACTCAATCACTATACCCCTTCTTATTTTCTC +TCTCAAGTTGTCGAGAGACTATCAGATCTGTGTGACGTGTATGGCATCATTTCACCCTCC +TAATGTTTTCTTTTCTATAATTGCAGGAGCCATTGACACTGGAGAATGATACCTACCCTG +AAATAACTCACTTCCTGAGGAAAAAACGCCATCTCTAGGGTACAGAAACCTGATTCTGGG +CTCCTTTTGGGAAGGAGGATTTGGAGTCTGGTGAGAGCAAATGATTTTGCAAGTATAAAA +CAATGTCCAGAGAGGCTGTAGGGATATCTGTGAGCCCAGAGGAAACACCAGGGGATCCTG +TGCGAAGCACCATGGCTTCAGCTAGGGTGGGAGGAGTGGGTGGGCCTCTCTCTAATGACT +TATCCTGGTGTTTGTGTTTCTAAAGATTTGATTGTGGAGAGCATATCTGATGATGGGGAT +TTGTAGGTAGGTAACTACTTTCCACGTAAGATCCAATTGGAGAGAGTTCCCAGGGGCCTT +CGGGGTATCCATGCTGCTTGGGAGGTTAAGGGAGGGGGCATGAAATCAAAAGGAAACAGG +AAATATGTGTCATATTGGATTTGGTCTTTTCCGGGTTTATTGGCATAATAGTTAGAACTG +TCTCTCTGGGCTATGAGGGTGCTGTGATATTTAAAGGTGGTCTTTCCCAGAACACCTGGC +CTTTTCTTTTCTGCCTCTGCCAAACATCACAGCCTTTGGGTTGGATTAGTCAGCACCCCT +TGGGATTGTGCAGAAGAGGTTTGGGGTTGCATCGAGTGTCACCTGTGGTGAACAGAATCT +GAGGGACACAACTCTCTCACAGGCACTTCCTTCAACCTGGAGACAGAGTTCTCCTGGTGT +GTGCCCAGGGGTGGAGGAGAAATTGACAGTCTGCCTCTGAACTTTCAGGACTTTAAAAAG +CACTCATGTTTCCATCCTCACTGTTGACTCCTGGCTTAAAGGGATCTCCCGGGGTGAGTG +AGGAGGCGGGATCGGACCCTGGCAGTCTGACGGCAGCACCTGTGTTCCTCTGCACTGGGC +CGTGGATGACATTACACACCTTGGTGAGAATCAGGAATTGAGGCTAACCACATCTGAAAT +TGAGATGGGCCTTGAGTCATATAAATAGTTTGGAAAAGATGCATTTTACTACGCTATTGA +AAGAAACCATTTATTTCTCACTCCAGCAGGATAAATGGTTTTCAGTATCCACTTAACTGC +TCATTGACTCTTACTGTAGATGAGGAGGTGGCCAGCAGCCCCTGCCCTCCCCCAGTTGTA +GGCCCAAGGTAACCAGCAATTGACTGGATATAATGGAAGAGTGGTGCATTCGGAGGTATC +TGTATTAATGGGACCCACATGATATGGATGAGAGCTATTAGGGTGAGAAAAAGCCTGGGA +GCACAATGAAATATTTAAATATTAAACAAAACATTGTTGAAATCTCCATTGTACTTTAGT +AGTTGAAGTCATTCTTGTGGTCATCACTGCCTTTCCCAAGCATAACAAGCTACTTAATAT +CACATGGACCCGTGCCATGAGGAATGATGATCAGTTTGTCAAATGCCAATAAAACAATTG +CCTCTATAAGCCACAATGTTTCATCCATATATTTCAATTTCCATGTGTAAGTATAGTTCA +AATTTCAGAAATTTATTATTATCTAATAGAATATGCATGGTATATCAATGAGCAATTATC +ATACTGTTTCTATTAACAATTATTTGTATGATGAAAAAAGCAGACTCCCATTCTTGGATT +TTTCTCAGTTTGCACACATTAGCATGACAGCCCCATTTCCACCTGACATGTGCCAGCAAG +AGGCCAGGAACAGAGGCTTTTCTTATTAACTAAGATTTCTAAATGTATTACGTATTCACA +TTTAGAAACTCTAAATATCATAAAAGGTTAGCAAGGAAGTTTCCCTTCCACTCTGAACTT +CCAAACACCAAGTCAACGTTTTTGTTTGCATATCATCCCTGCAATCTATGTGCAAATAGA +AGCATGCACCTGGAATGCAGGCTGATGTGTGATCGTGTTTACACAAAGTCCTCTGCACCT +CTGCATATATCACTGGGCAATGCACCTTAGTTATCATTCCACATTTCAAATGTAAATCCA +TTGTATTGTTTCAGAGCTATAAAGTACTGCACCCCATGACTATTCCCAAAATTACTTAAG +CACCCCGCTATGGGTATCCGTTTGTTCTGTTTCCAGTCTTGCTCTTATAACCAATGCTGT +AGTGAACAGCACTGTGTTGAGAAGCGGTGAACGTGGGCATCTTTGTCTTGTTCCCTTCCT +CAGGGGGAATGCTTTCAACTCTCCCCCATTCAGGAAAATGTTGGCTGTGGGTTTGTCATA +GATAGCTTTTATTACCTTAAGGTATGTCCGTTCTATGCTGATTTTGACGAACGGTTTTAA +TCATAAAGAAATGCTGGATTTTGTCAAAGGCTTTTTCTGCATCTATTCAGATTATCATGT +GATTTTTGTTTTTAGTTTTATTGATGTGATGTATCACATTTATTGACTTGCGTATGTTAA +ACCATCCCTGCATCCCTAGTATGAAACCCACTTGAATCATGGTGGATTATCTTTTTGATA +TGCTGTTGGATTCAGTTAGCTTGGTTGTAGCATTTCTTATTATTCCATCTGTGGAATGTA +TTGGTTGAAATAATGAAAACATGTTCTATCCTCACTGCTTAGCACTTTGTGTTTCTTTAA +TAGCCTTCCCAACAGGGCAACATAAAAGCAGGAGCCCTGCTAGTCTCCCCTTAACCCGGA +ATCCCCCCTTCTCCACAGCTCGCTCATTGGACAGGATAGACTGGGCGCCCAGGCTTCAAG +GTAAGGACGTGCTCTGTCACCTAGAGGTGCAGTGCTTGGGAAGGCCAACCTTGGAGGGTT +GCCTGCCAGCTTTACAGTGACAGAGGTGTTGAGAGGGACTGACCACCAGTGCATAAGGCT +GTGCTTTGTTGGTGACATAAAGGATTGTTTCACAGATTGTTGGGGAGGGACAATCCCAAG +GCCTCCCCTGGCCCTGGTGCTGGCTCTGCACAAAGGCAATAAGAGAGGGATGCTGGTAAG +GGCTGACCTGTTGCTGTGCTGGGGAGGAAGGTGCTGGGCTGAAATTCAGGAGGCTGAGGA +TGCAGCAGTCCCATAGGAGGTACATGACCTTCAGGATACATTTTCTTCATTGATGATCAA +TGGAAATGAGAAATCACTGACTATTTTTTCTATCATTGGAATCTACTCTCCACTGCTCAT +GCTGTTCCTGTCTTTTGGGGAAGATGGAGGATCAATCAGTGTGCGCTGCACTGAGTGGAA +GGAAGGAGAACTGTGACAAAAATTAAGGAAGGATGAGAGACGGGAGGGCCCTTCATCCAG +CTGCTTGCAGAGTCCTCCTGAGGAGGAAAGCCCCGTGGCTCCCTGGCGAAGGAGCAGTGA +GGGCTGCGTGACTCCCACAGTGAAGTGTGTGGTATGTCTGAGGACACCCAGGCTGGTGGT +CCATGAGGAGCCAGTGGCAGAGTGAGAAGAAGAAAGGCCAGGAGGGTGGCTGGAGGCCAG +GCTCTGAGTCATTCTCCATGTGATGGAAACAGCCGGAGCCCAGTGGGCTTGGAGGTACAG +GATGCGGTGGCTGATGACAGAACAATGTGGAGAGAGGCGTCATTTGTCAAATCCTTACTT +TGTTCTGGGCATTGTACTAAAAATTCTAATGGCTCATCCCATTTAGGGGCTGAAAGTTGC +AGAGGTTTAGGAAGCTCACCCACGATACTGGAGCCCCCATCTCTTGCCCTAGTGCTGTCC +ACCTTCTCACCCAGCCACCACCTGTTTCGGGGGAACACACAGAAGTGGTAACCTCTTATG +GAGAGGCAAGTAAATTCTGCTGTTTTTGTTATTCACAGAAAAACACTGGCTCGTGTGGGT +TGGGAAGGTGAAATACCAGAAGTATTTCATCTGGTTATTTCTACCCATGCAACTCCTATA +GTATTGAAATGCATAGGTTAGCATTTTTGGCCAATTTACTCAGCATTCTGGGTTAAAGGC +TTTTATTTATTTTATTTATTTATTTATTTATTTTTGAGATGGAGTTTCACTCTTGTTGCC +CAAGCTGGAGTGCAATGGTGCGATCCTGGTTCATTGCAACCTCCGCCTCCCAGGTTCAAA +CTATTCTCCTGTCTCAGCCTCCCAAGTAGCTGAGATTATAGGCACATGCCACCACACTGG +GCTAATTTTTTTGTATTTTTAGTAGAAATGAGATTTCACCATGTTGGTCAGGCTGGTTTC +GAACTCCTGACCTCAGGTGATCTGCCCTCCTCGGCCTCTTAAAGTGCTGGGATTACAGGC +GTGAGCCACCACGCCTGCCCTAAAGTCTTTTAAAATTCACTTGTATAAGTTGACTTAGTT +TTCTTTAACCTTGTAGAAAAATACAAAAATGGCAATCTCTTTTATCACACAAATAATGTC +TTTTTAATGGAGTGATTTTTTTCTAATTGAGGTATTATGTACTTTTCATTTACAAATTAT +TGTTTACATTTGAAGTGTTTTATGAATTAATATTTAATTGCATAGATGAAGATTACTAGT +TATAGGCATTTTACTAACCAATACTCATTAAGCATAGCATGGATTCATATGACATCAAGG +AGCTATTTTATTTGGTAAAACGAAAAAGCACAAGAATGAACGAATGCAAGAACTGAAACA +GTGGAGACACCTAGAATGACTTGTCTAAGATCTAAATCATTTTGTTGTCTTCCCAGCATA +CTTATTATCCTGATCATTGTCATCAGCATTGTTTGGGTCCTTTTAGCACAGATTTCTCAA +AATGGGTAACTCCATAACAGTTGGAAGCTTACGAATTCATATAATTTGTAAGAGGTCAAT +TTGGAAGTACCTATCTATTTTAAAATTCCAATAACCTGGGAATTTCATCCCATGTCTAGA +GTCTTTTATGTAAAATATTTCCACAATTAGGAGAAATATGTGCATGGGGATTTTCTATGT +AGCGGTGTTTTGATAGAATAGAAAATTGGGATAAATCAAATTTCCATCACGAAGGAAATA +GTAATATGCTGAATAATAATACAGCGAATATTATGCAGGCTTTAAACATCAAAAAAGAGT +TCAACTTCTGACTTCCGATGATGGTGTTGAAGCAGGTCACTGCTGGTTTACATTTGATTT +TCATGTGGGAACTCTGGAAGTCCGCCTTAGTGATTTTACATGTGGCTAAATTGAGCTAAT +GACAAGCCGTTCGAAGTATGGCAAAATGGAACTTTAAAACAGTATCTTGTCAACAACCAA +GAGGACCTGTTTCACATAAAGCCCATGCATTCATCTGCCTGTCCATCATTCTGTCTGTCC +ACACGGGCATCATTCGTTAGTGGAACTGAGTGCCCACTGTCGAGCTGACAAGCCCATAAC +CTCCCTGTTCCTAGTCACACATTAATTCTTCAACAAGTCCCTTTTGATAGATTGTGATTA +AGCTTAGCTACTATTTCCAATTGCTTCCCCAAACGTACTTCTCACTGTTCTCCCATCACA +CCCTTCAGCCCATCCATGCGGGGTTCCTTTGCTTTTCCCACCTTACACCAAACTCCCTAT +TTTTACTCCCACTTTTACCTCCTCTCCAAGACAAAACAAACAAAACTAGCATTTTAAAAC +TTAGTTGTAATCTTTCTTCCTTCATGAAAATTTCTCCAACAGCCACTCCCACGGTCCTGT +GTGTTCCAGATATTTTAAAATAATGGCTATAAGGCTGAGCACTTCAGGATATGCTGTTTT +GCTGTGTGCAGATGGAGGCAGTGGCTGGAGTGAATGAACGGCAACACTTGCTGGCAACCG +GCAGAAGCTGAGAGACAGGGAACAGGCTCTCCTCCAGAGCCTCCAGGAGCCAGGCCTTTG +GACACCTTGAATGTGGGCTTCTGGGAGACCATGCGTTTCTGTTATAAGCAGCCCAGTCTC +TGGCAGTTTTTACGGCTGCCCCGGAACACTCATCTATACCTGTCTGACAAGGTCAAGCTC +CAAGGAAGGGATTCTCTACATATCTACATTGTTTGCAGATTTTACAATAATCATTTATTC +TTGCATGGCTGATCATTGTTAACCAATACAAATAAAATAATAAAGAAATGACCCACATTT +TATGTTGGGAGTTTGATCTGCCATTTATCAAGTATGGAATCTTGAACAAGGGGTTAAACA +TCTGAATGTCTCCATCACTTCATCTCTAAAGTGGGGGTGCTCACACCCACTGGGCTCCCC +CACCCAGGTTGGTGCCGGACTCTCCCTGGGCCCCCCTGTTCTCTCACCAGCCACATCCAT +TCTCCCCCCAGAGGCGCTAGTGACTGTGCGTGGCTTTCCATTCCCACCATGTTTGTCTCT +AACCCCAGTGGCAGATCAGTGTAAGAACACAGCTGAGTGCTCCTCGCCTCCTTGCCCCTT +CAAGGGCTCCTCACCACCCACCAGATCAGGTGCAAACTTCCAAGCCTTACTGGATCCCCT +TCCACATTCTGAGCTCCGCCTGCCTTCCCATCGCTATCCTTCCCCACCTGCCTCCCTGGT +AGAGAAAAGCAGAGTGTGTGATGCTGTCTGAATGCTGAGCACGGCCTTTTGCAGCCAGTC +CACTGTGTATGCTGCCCCTATCGGAGACCTCCACCTTAACCCTTTCCAGCCTGGAGGCTC +CTCCCAGGGCCCCACAACAGAAGTGACTTCCCTTGCCTTTGAATTTCTATAGCACAAGCC +CTACTGCCCCCCGTTAAAACTGCAAAGTCCTTTTGTGGAAAATAACTTTATTCATGACTG +TGTTTATCACACTATCTTATGGAGAAGAGATGATCAATAAATATTTGTTGAATAAATGAA +TAGCAGTTACAAAACACTTGATTCATATGGAATTAATGTTGGTTCTCAAAGTGAAAAATT +ACAAACAGCACTGATATTCAGCCAGTATACAAGTCTGGTCACAGCAGTTGTATAATACTG +AAATACCCCCTGCCACTGACCTTTGGCCCCCAGATGCCTCCCACTGCCACTGCTCTCCCC +ACTGGGAACCCCTGAAGTTCCCACAGGCTCATAACTAAAGGGCTAATGTCTCGCACAGCA +GCGAGCACCCAGGACCGAGCAGCCACATGGCCGGGTCTGCTGGTGAAAGCATCCATTCTG +ACTGATCAGGACCTGAGGGGCCTCATGGTTACATATTTTGATAATATCCCTAATTATAAA +TAAGGCTCAGTTATATAGTTTGAAAACAATGCTTCTCCTCATCGCAAAATCTCTTAGAAG +ACTCCGTAGATCCAGGAACGGAAATGGAAAATGACAGCGTGTCAATCTCTGAAGGTTTTG +GGCATTTCCATTAGCACTCCATCTTCATGTAAACCAGAAGATATGCAGTTTCCTGCCTAG +AGAGAAGAGAAGACACATCAGCACAGCGGCATGAAAGCTTCATCAGAAAACAATGCTTCA +TTAATCCGTGACAGGACAAGCGTCAGCAAACTTCCAGGCGGCTGGATTAGGCCTTCATCT +ATCCATCACCTTGGAGAGGAACAAAATAGGTGGCCTGGGAAGATAAGCACTATGTTTCTA +TTCCTTAATATCTAAAGCGGAGGTTAACAAGCTATGGACACACAAGCCAAACCCAGCCCT +CTTGGGGTTTTTTAAATCTACTTTCAACTTTTATTTTAGATTCAGCGGGCACATGTGCAG +GTTTGTCACGTGGATATGAGCATACTCCCCAACAGTTGGCCTTTCACCCCTCCCCTCCCT +CCCCATCCAGCAGTTCCCAGTTGTTGCCATCTTTAAGTCAATGAGTCCCCATGTTTAGCT +CCCATTTATAAGAGAGAACATGCATTATGTTTTGTTTGGTTTTTGCTGGTTTTTTTTTTT +TTTTTTAATGGAGTCTTGCCCTGTAGCCCAGGCTAGAGTGCAGTGGCACAATCTTGGCTC +ACTGCAACCTCCGCCTCCCAGGTTCAAACGATTCTCCCTCCTCAGCCTCCCGAGTGGCTG +GGACTACAGGCGCCCGCCACCACGCCCGGCTAACTTTTTGTATTTTTAGTAGAGACAGGG +TTTCACCGTGTTAGCCAGGATGGTCTCAATCTCCTGACCTCATGATCTGCCCACCTCAGT +CTCCCAAAGTGCAGGGATTACAGGCGTGAGCCACCGTGCCCAGCCTTTTGTTTATTTTTT +GACGAGACGGTTCTTGCTCTGTCACCAGGCTGGAGTGCACTGGCACAATAATAGCTCACC +ACAGCCTCGTGCTCCTGGGCTCAACTGACCCTCCTGCCTCAGTTTTAGCTTCCTGAGTAG +CTAGGACTACAGGTGTGTACCACCATGCCTAGCTATAATAATTTTTATTTTTTTGTAGAG +ATGGAGTCTTGCTTTGTTGCCCAGGCTGGTCTTGAAGTCCTGGCTTGAAGTGATCCTCCT +GCCTCGGCCTCCCAAATTGCCGGGATTAAAGGTGGGAGATCGCACCCAGTCTCCAACCCT +CTTTTTGCAAGTAAATGTAACTGGACCCCAGCCATGCTCATCTGCCCATGTACTGTCTAC +GGCTGCTTTTGCTCTACAGGGCAGAGTTAAGTGGTTGCAACAGACACCGCACAGACCACA +AAGTCTGAAGTACTTTCTCTCCAGCCCTTTACAGAGAAAGTCTGCCAACCTCTAATCTCA +ATAACAGGGAAATCAATGACAACCACAAAGTGACAAAGACTGGGTGTCTAAGATGGATGC +TCAGAATAAACAAGAGAGAAAGATGAAAAGTAGAAGGAGGATTTCAAACGCAAGCTTCAC +CTAATCCGTTATTTTTCAAATGACCAGGCCTATCTCTGTAGCTGAAAATCACCTCAAATA +AGATCTCTGATATACAGTCTCCAAAAGCTCAGCCAAGAAACTTACAAAGTCTCTCTGCCT +TAACTTCATCCACCTTTTTTCTCTCCAGCTTCTCCTCGGTAGTTAATGATTATAAAAATA +TTTATTGGCTCATGCCTGTAATCCCAGCACTTTGAGAGGCCGAGGCGGGCAGATCACGAG +GTCAGGAGATCGAGACCATCCTGGCTAACACGGTGAAATCCCGTCTCTACTAAAAATACA +AAAAATTAGCCAGGCGTGGTGGCGGGCGCCTGTAATCCCAGCTACTCAGGAGGCTGAGGC +AGGAGAATGGCATGTACCCACAAGGCGGAGCTTGCAACGAGGTGAGATCCCACTACTGCA +CTCCAGCCTGGGCGACAGAGCAAGACTCCATCTCAAAACAAACAAACAAACAAACAAAAA +AACAGTGTGATGGCCAGGCGCAGTGCTCATGCCTATAATCCAAGCACTTTGGGAGGCTGA +AATGGATGGATGGCTTGAGCCCAGTAGTTTGAGACAAGCCTGGCAACATAGCGAGACCTC +ATCTCTACAAACATCTTTAAAATATGCCAGGCATGGTGGTGCATGCCTGTAGTCCCAGCT +ATTCAGGAAGCTGAGGTGGGAGGATCACCTGTGCCCGGGAGTTCAAGGCTGCAGTGAGCT +ATGATCACACCACAGTGCTCCAGCCTGGGCAACAAAGCAAGACTCCATCTCTAAAAATAA +AATAAAATTAAAAAAAAAAGATCTTCGCTGTAAAAGAGGTACACTCAAATGCAATAAAAG +CATATAAGAAGGCCGGGTGTGGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCGA +GACGGGCGGATCACGAGGTCAGGAGATTGAGACTATCCTGGCTAACGCGGTGAAACCCCA +TCTCCTCTAAAAGTACAAAAAAATTAGCTGGGCTAGGTGGCAGGCGCCTGTAGTCCCAGC +TACTCAGGAGGCTGAGGCAGGAGAATGGCATAAACCCGGGAGGCAGAGCTTGCAGTGAGC +CTAGATAGCACCACTGCCCTCCAGCCTGGGTGACAGAGCGAGACTCCGTCTCAAAAAAAA +AAAAAAAAAAGAAAAAGAAAAGAAAAGTTCTTGTGACATTTGTGTATGAAATCAGCCTTC +ACTACATGGATAGGACCAGCACGCTTCTGCGGCACGACTCTGCAATCTTACTACATTTTT +TTTTACTTTGTATTTTATTTATTCCTTTTGAGACAGAGTCTCACTCTGTCACCCAGGCTG +AAGTGCAGCCGAGATCTCGGCTCACTGCAACCTCCACCTCTTGGGTTCAAGCAATTCTCT +TGTCTCAGCCTCCCAAGTAGCTGGGACTACAGGCACACGTCAAAACGCCCGGCTAATTTT +TGTATTTTTAGTAGAGATGGAGTTTTGCCATATTGGTCAAGCTGGTCTCGAACTCCTGAC +GTCAGGTGATCGACCTGTCTTAGCCTCCCAAAGTGCTAGGATTACAGGTGTACATTTATT +TATTTATTTGAGATGGAATCTTGCTCTGTATTTATTAATTTATTTATTTGAGATGGAGTC +TTGCTCCATCGCCCAGGCTAGAGTGCAGCGGTGCAATCTCGGCTCATTGCAACCTCTGCC +TTCCAGGTTCAAGCGATTCTCCTGCCTCAGTGTCCCAAGTAGCTGGGATTACAGGTGCCT +GCCACCACAGCTGGCTAATTTTTGTATTTTTAGTAGAGACAGTGTTTCACCATCTTGGCC +AGGCTGGTCTCGGGCTCCTGACCTCATGAACCACCTGCCTCAGCCTCCCAAAGTGTTGGG +ATTACAGGCCTAAGGCACCATGCTCGGCCATATTTATTTATTTAATTATTTAGAGACAAA +GTCTTGCTCTGTCACCCAGGCTGGAGTGCAGTGGCGCCATCTCAGCTCACTGCAGCCTCC +GCCTCCGAGGTTTAAGCAATTCTCATGCCTCAGCCTCCTGAGTAACTGGGACTACAGATA +CTTGCCACCACGCAGGGATTTTTTTTTCTATTTTTTTTGTAGAGACACAGTTTCACCATG +TTGGCCAGGCTGGTCTCGAACTCCTGACCTTAGGTGATCTGACAGCCTCGTCCTCTCAAA +GCACTGGGATTACAGGCATGAGCCCCTTGCCCGGCCTCTCACTACATTTAAGTGACGCCA +TGGCTCATGCCTGTAATCCTAGCACTTTGGGAGGCCAAGGCAGGTGGATCACCTGAGGTC +AGGAGTTCGACATGAGCCTGGCCAACATGGGGAAACCCCGTCTCTAGTAAAAATACAAAA +ATTAGTCAGGTGTGGTGGTACAAGCCTGTAGGCCCAGCTACTTGGAAGACTGAGGCAGGA +GAATCACTTTAAGCGGGAGGCAGAGGTTGCAGTGAGCCAATATCATGCCACTGCACTCCA +GCTTGGGTGACAGAGTGAGATACTGTCTCAAAAAAAAAGAAAAAAAGAGAGAAAAACATA +TGATGCCAGGGCATCTCGGCCTCAATACCTGGGTGAGCACAGTCATGTCCAGGCCAGGGC +TGCTGGTCGAGGTCCGGCCCCATCTCTTCCAGCAGAAAGGGAGTAAGCTTGCAGGGAGGC +TGGGGGACAAGATCCCAGGATCTCAGCCTCTGCTCATGGATCAGCTCTGAGACCCCGAGT +GAGCTGGGGGTGCTCTGTGCGCATTGGTTTCCCCAGCTGTCAAGTAAAGAGATTGGATGA +GGAAGTCTTGTCAAGGTGGAATGATCTCAGATTTGGGGCAGCAGTGAATGATCCCGCTCC +CTGGGCCATGCCAGTGGCCCGGCCTCGGCTGAACACAGCCCCAACACTCTGGAATGGGGA +TGAGGGGGCAGTCAGCTCTTGCTCCTAGTAAGAGAGATGCAACAGGGCTCTGTGGCTGAG +CTGGGTGCCTTGCCTCACACCTGTAATCCCAACCTTTGAGAGGCCGAGGCAGGAGGATTG +CTCGAGGCCGGGAATTTTGAGAATAGCCTGGACAACATAGCCAGACCCCATGTCTACAAA +ATAATAATAAAACACACAGCTATAGTCCAAGCTACTTGGCAGGCTGAGGCAGGAGGGTCC +CTTGAGTCCAGGAATTGGAGGCTGCATTGAGCTATAATCGCACCACTGCACTCCAGCTTG +GGTGACAAAGTGAGACCCTGTCTCTAAAAGAAAAAAAAATTGGCCTGTGAGCATGGGCTT +GATTTTCAAACAGGACCCGGAGGGTAGGGTAAACGTGTGGGTAAATCTAAATGAATGTTA +TTGGTATAAAATTACAGTAGTATAGAAAATGATATCTTGTGGGGTTTAAAATAAATAAAA +CATACTGAAATATGTATGGGTACAGTTATATATCTGGGATTTGCACTGAAATAATGTGGG +GTAGAGGGAAGCAGGAAAGAGTATACATGAAATGAGCTTGGCCATAAGATTGTTGTTGAA +ATTGAATGGATACTCTGGGCTTCATTACACAATTCTCTTTACTCTTACATAGCTCTACAC +TCTCAACATAAATAAGAATAAAAACACAAAAAACACACAGATACATCTATGCACACACAC +ATATTTAAAATACACAAAAATATTAGCATATAAGTCACTGGGGGTAAATTTAGTTCCTGT +TCCAAGGTTCTTGTACTGACTAGGAAGAGGATAGAAGTACTAACTCATAGGCTGGGCGCG +GTGGCTCACGCCTGTAATCCCAACACTTTAGGATGCCGAGGTAGGCAGATCTCTTAAGGT +CCGGAGTTCAAGACCAGCCTGGCCAACATGGTGAAACCCTGTCTCTACTGAAAAAGAATA +CAAAAATTGGCCGGGCATAGTGGTGCACACCTGTGGTCCCAGCTACTCAGGTGACTGAGG +CAGGAGAATTGCTTGAACCCAAGAAGTGGAGGTTGCAGTGAACCAAGATTGCTCCACTGC +ACTCCAGCCTGGGCAGCAGAGGAAGACTCTCTCTATCTCAACCACAACAAAAAGTACTAG +CTCATGTTAGACTTTGATAAGGGAAGGATGCATGTTGTAAGCTCTAAAATAATCCAGTCA +TCTTTTAAAATAACTCTAAGACTGCACAGTTATGAAACTAATAGAGAAGGAGGAAATTAA +ATAATAAAACTAATAAATCCAAAACAAGATGTGAGAGGAGATAAGAAGAAATAGAATAGG +CATGGAAAACAAATTGGTGGTGGGTTTCAACCCAAATAAATCATTAGTTACATTTAAAAG +GACAATAAAAATTAAAATAATTGAAAATAAAGTAAAACCCAACTAATGCCTTTTATATAA +GGGTACAGAGAGGTGGAAGATCATGAAAAATATGTCATGCATGTACTAACCAAGAAAGCT +GTATAACTTTTTTTTTTTTTTTTTTTTTTTTTTTGGAGATAGAGCCTCACTCTGTCTCCC +AGGCTGGAGTGCAGTGATGTGATCTTGGCTTACAGCAATCTCTCCCTTCTAGGCTCAAGC +GATTCTCCCACCTCAGCATCCCAAGTAGCTGGGACTACAAGTGTGCCAACTTAGAATTAT +ATTAGCCACACCCAGCTAATTTTTGTATTTTTTGTAGAGGCAGGGTCTCGCCATGTTGCC +CAGGTTGGTCTTGAACTCCTGGGCTTCAGTGATCCACCCACCTCGACCTCCAGCAAAGTG +CCAAGATTACAGCCATGAGCCACCATGCCCAGCATAACTATTTTTAATGAAGTAGACTTT +AAGAAGAAAAGTATTATTAGAGGTAAGGGACACATCACAGAAAAGAAGAATTTACTAGGA +GCCAGGCGCAATGGCTCGTGCCTGTAATTCCAGCACTTTGTGAGGCCAAGGCGGCGGATC +ACCTGAGGTTGGGAGTTCAAGACCAGCCTGACCAACATGGAGAAGCCCTGTCTCTACTAA +AAATACAAAAATTAGCCAAGCATGGTGGCACATGCCTGTAATCCCAGCTACTCAGGAGGC +TGAGGGAGGAGAATTGCTTGGACCCAGGAAGTGGAGGTTGCGGTGAGCTGAGATTGTGCC +ATTGCATTCCAGCCTGGGCAACAAGAGCAAAACTCTGTCTCAAAAAAAAAAAAGAAGTTA +CTAGCTAGTTTCGGTAATTCTTAACATCCAGGAAACTGGATGTGAAAGTTTTTCAGAGAA +ACTAAACCAATAGATTATACATAGAGAGAGACTTATTTAGGAATTGGCTCACATGATTGT +GGGGACTAGCAAGTTTTAAAATCTGTAGGGCAAGCCAGCAGGCTATAAATTCAGGTAAGA +GTTGATCTCGAAGTCTGGAACCTAAAATCTGTAGAGCAGTCAGCAGGCCAGAAACTCAGG +CAGGGTTTGTGTGTTACAGTCTTGAAGCAGAATTCCTGCTTCTCTGGGAAACCTCAGTTT +TTGTTCTTAAGGCCTTCAACTGATTGGAGGTGGCCCACCCATATTATGGTGGGTAATCTG +TTTTACTTAAAGTCAATTGACTGTCAGTGTTAATCACATCTATGAAATAACCTCCCAGCA +AGATATTGACAAGTATTTGACCAAACAACAGGACACCATAGCTTAGCCAAGTTGACACAT +AAATTAACCATCAGGAGCAAGTAGAATATCCAAAAAACAACATACTAGGGGTATTATATC +TTATATAGCTATTATAATTATATAAAACATATAATTATAGAATGACGATATTAAGATAAC +CATTAGAACAAAAATATAAACTTTTCTTTCTTTTTTTTTTTTTTTTTTTGAGACCAAGTC +TTGCTCTGTCACCCAGGCTGGAGTGCAGTGGTGCAATCTTGGCTTACTGCAACCTTTGCC +TCCTGCGTTCAAGTGATTCTCCTGTCTCAGCCTCCCAAGTATCTGGGATTACAGGCACCT +GCTACCATGCCCAGCTAATTTTTGTATTTTTAGTAGAGACATGGTTTCACCATGTTGCCC +AGGCTGGTCTCCAACTCCTGACCTCAAGTGAGCCACCCCCCTTGGCCTCCCAAAGTGCTG +GGATTACAGGTGTGAGCCACCACACCCAGCCAAAAATCACCTTTTTTACAAGGATCAAAA +CAGTCATTATGCTGGAGATGACAGACCTCACTGTCACCATGCTCCTTTTGTATGTCTACT +AGGCACGGTGCTGGGTCCACACTCACAGAAACCTTAGGAACTCGCACCCAGGGGCTCCGG +CTGTAGCAGAATCCCAAGAATAAAACCTGGTGCTGAAAGAGTAGGAGATGAGGCCGGGTG +CCATGACTCACTCCTGTAATGCCAGCACTTTGGGTGGCCAAGGCGGGTGAATCAAGAGAT +AGAGACCATCCTGGCCAACACGGTGAAACCCCGTCTCTACTAAAAATACAGAAATTAGCG +GGGCGTGGTGGCTGGCACCTGTAGTCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATCAT +TTGAACCGAGGAAGCAGAGGTTGCAGTAAGCTGAGATCGCGCCACTGCACTCCAGCCTGG +TGACAGAGTGAGACACCGTCCCAAAAAAAAAAAAAAAAAAAAAAAGCAGGACACTGAACT +CTGGGAGGGCCTCCTGGTGAGAGGTGAGCACAGAGGGGAGAGATGGAGGCAGGAGCATGG +GCTTCTGGTGGCCCCAGCAGACCCTGTGGCAGCGTGGCCAGGGTCCTCTGCAGGGAGGAA +TCTTGGCCAGGATGACGCTGTAGCAGGCCTCTTCCTGAGGCCTCCAGCCAGCCCGGCCAG +GGTCCCAGCGTCCAGTGACCCCTGTTTCACAGCAGCAGCTGGGGCCAGCCCCAGGCTCTC +TTCCACTCCCAGCTTCTTAAAACTGGAAGTGGAGAGAGTTGTTTGATAAAACACTGGGGC +AAACCACATCCTCTCTTCACCAAGGGAGAGTTCGAGGGGATGCCGGCAGAGGGAGCTTTA +GAGTAGAGACCCCTACCCAACCAGTGACCGTCACGCACACAGCAGGGCATGCTATGGAGA +CCCCCAGACAGTCACTCGGGGAGACCCAGCAGGTCCAGACTCTTCAGAGATCTGTGGCAG +CAGGTCCCCACTCCCAAAAGCCACGTGCCCACGGGTGGTCTCTGGTGCCTGAGACCCCAG +TCTCATTTGCATCTTTGCAACTTCGAGTTTAAGTGGGTGTCGCATCTCTGTATGTCCTCC +CGAGCAGAGGAGGGGCACAGCCTGGGGTGGCAGCTGGCGTCAAACCCTCAAATCCCCTGA +GAGCCACTGGGGAGACTAAGCAGTCCCCAGCCCCCACTTGTCCCTGAGCTGCCATTCTCA +GCCCTGTGGGAGGAGACAGAAAGCCCTGAAGAGAAACCAAAGGACCAGGTCAGGAGGGGC +TGGGGGGGTGGCATGAGCAATCAGGGCAGGGAAGGATGGACCGATGGGGGAATGGAGGGA +AGAAGGAATGAATGAAAAGGTGAATGAATGAACAAAGAGAGAGAACGGCCACTCCTCCCT +TGCTTTAGTTTACAAAGTACTGGGATCCTCCCAACAGCCTGCAAGACAGAATTTCTGGGA +AGCAGACCAGGTGGCTGGCAGGGAGGGGAGGCTTGCCCTGGCTTTTGTGGGCCCAATGGG +AGGCAGGGGGCAAGAAGGGGCATCCTGTGTGTGTCCTCCCTGCAGTGGCAGCAGCACCTT +CCTGGAAGAGGGTCAGGAAACACCCGCTGTGGCCCCTCTCCACCACGCCCTCATCCAGGA +CACCAAGTATCAGTCACTCAGCTCACGAGACCCAGGCCCTGACTCAGGGAGAGAGGATGT +GAGGGGTGGGGCACCGGGCTCCTCAGGACTGAGAGACCTGGGATGTGGCCCCGGGCTGGG +TGTAGGGGCAGACTGGCTATGGCAGCATTGTGTGTACCCCAGCAGGCCAGTACCCACGCA +GGGAGCCTCCAAACCCCTTCACCCATGACCCTGGGAGAAGACCGCAGCCTTGGAGAATTG +GCCTCACTGAAGGGGCCTGCACCGGCCAGCAGGGTCAGGCGGGGCCAGACAGGTTCCCAC +CTGGGATATGCAAATGGGCCTCCTGAATCCTGGAGCCAGGTATGGACTCACACACCACCA +TTGTCCCCAAGTCCCCATCTGCCCCACGGGCACACCCTGCCGCCTGTTCTGTGCAAGGGC +CCTGAGGCTGTCTCCTTGCGCCCAAGACCTGCAGGTGCTGAAGCCCACACACACGGCTCC +TGCTTCCTGGGCCAGTGCACGTGCACACACACACACGTGCACACACACACACACACCCAC +AAATATACCCACACACAATCACACACATTCACACATACCCACCCCCCATACTCACACACA +CATTTACACACACCCACACACCCACACTCACACACTCACAGTCACACACACCCTCACACA +GCGAAACACAATCACACACATTCACACCCACCCACACCCCACACACTCACACTCACATAT +ACTCACACACACCCACACACACATACACAAACACAATCACACACATTCACACACACCCAC +ACTCACACATACACACACCCAAACACGATCACACACATTCACACACACCCACACCCCACA +AACACACTCACACATATACCCACACACACTGACACATAATCTCTCACACACACACATGCT +CACACACACACGCCTTCTCCAGGAGGGGCTGGCTGCCAAAGGCCACCCAGCTTCCTCCCA +CGTCTCACTCACCGTACAATATTTGAGAAGACCTTGGAGTCAGCAGCAACAGCGGCGTGG +GCAAAGGCCGGGGGTCAAATGGGGCCTGGTGTCGAGAGAGGACCACAGCCAGCACAATGA +CAGCCAGCGCCAGCCCCAGCCCCAGCCCCAGCAGGACCAGGTCACCCATGGCTCCGTAGT +CCTGGGCCATGGCTCTGCGGCCCAGAAGGAGAGGGGAGGCCGGTGGGCAGATGGAGGGAC +AGATGGGTGGGCAGATGAATGGACAAGAAGATGCATAGATAGACTCACAGGTAATTGGAC +AGATGGACAAACAGGTGGGGGCTGAAGACAGACACGAAGATGGATCGACAGACAGGCCAG +ATAGCTAGACAAAGAGGACAGTAAGAGAAAGATGGTCAGATAGACAATGGGACAGAGATG +GGCTTACAGATGGGCGGACAGACAGACAGGTCTGAACAGCGGGCTGCCAGATGGACAGAT +GGGTGAATGGACAGATGGCTGGCAGCTGTGGCGAGCTGCTGCCCTCACCAAGTGCACACT +ACGGAGTGGCCAAACTCATGCCTCAACTTCTAGTTTTCAGCTCCTGCTTGTTCCTGGCAG +GAGGCCAGGCAGCAAAGCGTCTGAGGGGAGTTTTCTTTGCCTAGAGAAGTCAGCTGCTGT +GTTAACTCCCTCACTGCTGGTAGGTCCAAAGGCCCCACCTACCGCCCGCCAGAGCCCATG +GTCACACTGTCGCAATGTGCAGGAGAACTTGGTGCGTGCTGCACTGCGGTTGCCAGGTAG +GGGCAGGGCTCCCTGGAACCTCCACACCATTCCCCAGGTTCTCAGCAGCTCTGGGAAAGC +AGAGCTGGGGCCGCTTAACTCTGCCCTGGATCCGGCAAGGCTGCCCCCCTCCCAGAGTGG +AGCCCTGCTCCCCAGCTCCCATCTCTATCCCCTAACCCTCTCCGCATGGCCCAGCCTAGT +CAGCATCAAGGTGGAGCTGAACAGAGGCAGAAGGAGGAGGACCCAAGGTGGTGTCACTCA +GGACCCGGGTTCAAGTCCTTATGCTTCTGCAGCCTGGCCTGGGTCCCCCAACTCCCCCAG +GGTGACCAAGGGCTTTCCAGTCTGCACAGAGGACAGGGGGTCTTGACAGCATCAAATTCT +GGTGACTACGAGACACTTACGTGGGAAATGCAGACAGACCATGCCTCTAGCCCTTGGCAC +CAGGCACCATCCATCCCTGGGACTTGCTGTCCTGGAAATGCAGCATGGTCCTCCAGGGAG +GGGGGCTGTGCCATGTGGGGGCCCCACCCCACCTGCAGCTCTTTCCCACCCTGGCTGCAG +GTCTGCTTCCCTGAATCCAAATCCGCTACTACTGTGCTGGCAGCGCAGCCTCTCTGGGGA +CACTGGCCTGGCTCTGTTCTCCCCAGGCCTCAGGGTGCCTAAATGGGAGGCAACCAGGGG +AGTGAGGACCCACTGAGGGGCTCCGTTGACCAGGCTCAGCAGGGGTGCAGGTGATGTGGG +GTGGAATCCTTCCCACATGGCCCCCACAGTCCTCCCCGCTTCCTCCCCAACTGAACACTG +CCTGCTCCAGATGTGTACACCTGGAGTCTGGGCCCCTCCATCTGGGCAGCAGAGAAACTG +AGGCACAGAGACAGACTGTGTCCTTACAGGGCACACAGCCTGCCAGGCCCCTATGTCCGG +CCAGAGCCCCTGGTCAGCCTGGGCTGCAGTGATTGTTTAGAGGTAGGCTGTTCCCACGGC +TGCCTCTCACGGTAGGGGGGCCTGTGGACGCCTCCTCCCGCCCCCACCCGACTCCCAAGC +CTCAGTGACATTGCTCAACCAGGAGCTGAAGTGCATTCCTGGGCTCCGGCCAGCCCACCC +ACCCACCCGCTGCAGTCCTGGAAGCCCAGAGGCCTGGGCAGCAGGAACAGTGGAGACAGC +AGTGTGGGGGACGTCCCCCTCCTCTCCCCACCATCCTCGTCAGGCAGAGGCCAGGGTGCA +GGGACCACCGGAGCAAAGGCCCAGGGAAATGAATGGGTGTCATTCTGGTCCTGACCCGAG +GCACAGCCAGGAAGGTCCCTGTGGGGAAAAGAAAGAGATATCAGACTGTTACTGTGTCTA +TGTAGAAAGAAGTAGACGTAAGAGGCTCCATTTTGCTGTGTAGTAAGAAAAATTCTTTTG +CCTTGAGATGCCGTTAATCTGTAACCCTAGCCCCAACCCTGTGCTCACAGAAACATGTAC +TGTGTCGACTCAAGGTTTAATGGATTCAGGGCTGTGCAGGATGTGCTTTGTTAAACAAAT +GCTTGAAGGCAGCATGCTTGTTAAGAGTCATCACCACTCCCTAATCTCAAGTAAGCAGGG +ACACAAAACACTGCAGAAGGCCGCAGGGACCTCTGCCTAGGAAAGCCAGGTATTGTCCAA +GGTTTCTCCCCAGGTGACAGTCTGAAATATGGCCTCGTGGGAAGGGAAAGACCTGACCGT +CCCCCAGCCCGACACCTGTAAAGGGTCTGTGCTGAGGAGGATTAGTAAAAGAGGAAGGCC +TCTTTGCAGTTGAGATAAGAGGAAGGCATCTCTCTCCTGATCGTCCCTGGGCAAAGGAAT +GTCTCAGTGTTGATTGTATATTCCATCTGCTGAGATAGGAGAAAACTGCCTTAGGGCTGG +AGGTGGGACATGCTGGTGGCAATACTGCTCTTTAATGCATTGAGATGTTTATGTATATGC +ACATCAAAGCACAGCACCTTTTTCTTAACCTTGTTTATGACACAGAGACATTTGTTCACG +TGTTTTCCTGCTGACCCTCTCCCCACTATTACCCTATTGTCCTGCCACATCCCCCTCTCT +GAGATGGTAGAGATAATGATCAATAAATACTAGGGAACTCAGAGACTGGTGCCAGCGTGG +GGCCTCCATATGCTGAGTGCAGGTCCCCTGGGCCCACTTTTCTTTCTCTATACTTTGTCT +CTGTGTCTCTTTCTTTTCTCAGTCTCTTGTCCCAGCTGATGAGAAACACCCACAGGTGTG +GAGGGGCAGGCCACCCCTTCAGGTCCCTGAATGTCCTTCCTCAGGAAATGATGGGGGAAG +GGGCGATGAGAATGAAGGAGACGATTTAAGTCCCTCACCCCCCGAGGTAGTCCTGGGCTG +AGCCCCATGGGACCTAGAGAACCAGGGTGTACCCCACCAGCATGTCGGGTCCAGGAAGCC +TCGTGGCCAGCTCCCACTTCTCTTCCTGCTGTGCAACCCAGAGCAAGGCCTGCCCCTCCA +GCTTCAGTCTTCTCCCCTGCAAATGGGGCCACGGCCTTTCCTCTCAGGCCAATATAAGGA +TTGAGGCCGGGTGCAGTGGCTACCCCTGTAATCCTAGCACTTTGGGAGACTGAGATGGGG +GGACTGCTTGAAGTCAGGAGTTAAGACCAGCCTGGTCAACATAGTGAGACCCCATCTCTA +TTGGTTTAAATTTTTTTTAAAAAAATTAAATAAATAAAATAAGGATTGAAGAGTGACTTG +TACACCAGTTGAGCCCACCTCCATCTCACCCTTGCAGAGCCCCAGAGACACAGCCCTCCA +GAGCTCAGACCCAGTGGGACTTGACTCCACAGGCATAAAACCCTGTTTGTCTATGGGCCC +TTTGGAATCACCAGGTTTTCGGGGCTCCTGAAGGATAGCCCCGACCTGGCCTCACCTGGC +CCCTGGCCCCAGTGCCCCTGGTGATATCCAGGTGCTGGGCTGTGATCACCGCCTCCCACC +AGCCCACCTCCACCAGCCCTTCCCAGAACCCTGCTCCAGGTGTTGGAACTGTGCACAGAG +GAGGGAGCAGGCCCCGAGGGAGGCCTGGAGGGGCTGCCAATGGTGAAGGCTGCTGTGTCG +AGCTGTTTCCTTCCGGACCCACTCCCTCTGGGCTGCGTCCCCGGCTGGTCCAAGCCCTGA +TCCCTGGGATCTGGGGACATCTTCCCGTTTGCTGTTCCCTGAGAACCAGGCCTCCCTGTG +GAGAGGATCACAAGCTTGGGTTTCACTCTGGGCTTGCTCTTGGGAACCCCCCAGGGGCAT +GGCTCTGACCGAGATGTTTTCCTCCAGCCTGTTGCCCAGTCCCCATTCCTCGGACCCTCA +GCTTCACCTCCAGTGTCATCGGCAGGGTGAGCTGGACGCCTACGGGTCTGAGAAGGCGCC +CGGGTTCCCAGCATCGGCTGGCCACCCTCTGCCTAAGAAAGCGCCAGGGTCGTGACACCC +CCTGGTGGCTGATCCTAGGTAGTGTCACTGCCCAGCCCCAGTAAGGGAGGGCCTGGCCCC +AAAGTCTGAGGGATCAGGGTGGGAAGGGGCAGGGTTTGGTGTGAACCTTCCCCTGGCCCC +CAGCCATGTGCCTTGCTCTCCCCATGCTGAAGATGCTGAGGCTAGTTCCAGTGCCCGCAT +TGTGAAGATCTCCGAATCCCACCTCTCTGTTCCTCCCCAGCCAGATGGCTCCATTTCACA +CACAATACACTGAGGCCCAGAGAGTGGGGAGACAGGCCAGGGAGGCCACCTGGAGCCTGG +CACAGTGGCCTCATTTATTATGCTGCTCTGCTGCTCACAGGGGAAGCCCGTCCCCCAAAG +TCCTCTTCCTCATCCTGGTGAGTATCTTGTCCCTGGATTGCTTGTCAGCCTTGTCTGCCT +GGAGCAATCAGTAGCCAGCAGGTTCCCCGCCTTTCCTGGAGTCCGAGGCAGCTGCCCAGC +CACCAGCCGTGCGGACGATGGCTTGCACCACAGCGATGAAGGTGGATGCGATCTGGGTGT +GATGGTGCCGGGTCTCCAGGGCTGCAGTCACTGCCTGGGGGTGGGAGGAGAGGGGAAGCC +TGAGCAGGGCTCCAGATGCCACCTGAACCACACCTGTGTGGTCACAGGCCTCAGCCCAGG +TGGTGCCATTTCAGGCCAGGTCATCAGGAAGAGCAGGTTGGGGCCTGCTGGGTCTCACTG +GAGCAGGGGGCTTGGCTCTCATGTCACAGGGGCTCCAGATGGCCCAGGCACTAGAGAGAG +GACACCAACCATTGTCCACTCTGTGATGATCCAGGCCTCCAGCCCAGGATGCCCTGGGAC +CCCACACCGTGACTCAGTTTCTCCAACCCCTGGCCCACCTGGTCAATGTTTCTCTCCACT +GTCGTGACGTTGGGCAGAAGCTTGTTGTGCAGCCGGGGCTCCTCCACGGCCCTCTTCACG +TCATAGCCGAACCAGAGGTTGTAGATGATGGCCTGGGGCATGGGAGTGTGATCAGCGTGG +CTTGGGGGCTGTGCAGAGTGGGCAGGGCCAGGGAGAAAAGGGGTGACACATACCAGTGCA +GTGTCTGTGGTGATCTGCGTGCCCCCAGCAGCTCCCACCACCATCCGGACCTGGCCGTCC +TGGCCCACCATGATCGTCGGGCACATGGACAAGAGCGGCTGCTTCCCTGCGGCCGATGGG +AGAAGACAGGGATGCCCGTCAGCTGCCTGCCCAGGACACCCGCCCCTCTCCACCCCAGTC +CCCCACCCCCCAGACCTCCACCCCATACCTGGCTGGATGAAATTGGCAGGTGAGGGGGGT +GCCCCAAACTCATTGGTGAATGCTGGGAGAGCTGAAGTCGTCCATTCATTATTGAACAGG +ATCCCACTGACCGGGGAGCAGACCTTGGAGCCAAAGCTACCGCCCAGCCAGGTCAGACAG +CACCCGACCTTGCCTGGCCCAGCCTGGTCCCTATCCACCCACTGAGGCTCAAACATACTC +ACTGAGAGGCCCAGGATAAGCTACCAAGGTTGGGCCTCAGTTTCCCACCAGGAAAAGAGG +TGATGGAGCCACCTTACTGGATAAGTGGGCAGTCCCTGGGCCACCCGCCCCTGGCCCTTT +CCCACCCAGGCGGCCCAGCAGCCCCTACTAGAGGTTGATGGTGCTGGTGGCGGACACAGC +ACTGCCGTCCTCTGCGACGACAGACAGGTGAGCAGTGCCCCCGTCATCCGGCGTGTAGAA +CTCGGGCTTGTAGTAGGAGATCGGGTGAGTGGTGTGGTCAGAGATCTGGGACCGGAGCTG +GGCAGCGAAGAACTCAGAGGTCATGTTGCGGACCACCTGCTGAGACCCCAGAGCTGGCCT +GAGGAGGTGGGGAGGGAGGGTGGGGAGGGGGCACAGGTCTCAGAAGGCCCTTGACTGTGA +CTCTGACCGCAACCCTCTGGCACCCACAACCTTCCGTGGCTCCCCAGGACCCAAGGGCAG +GCCCAAGACCTTGCATGACCAGTCTGACTCCCTGTCTCTGTCGCGTTCCAGCAACTCTGA +ATGTCTGTCTGCCTGGTCCTCAGCCTCCAGACCCTTGCCGCATTCAATCACTCATTCTTT +CATGCAAAAAATATTTCTACAATTTGCACTGCATGCCTGGCACTGGGGAATCAACAGGGA +ACAGACACTTAGGTCCTGCCCTCATGCCAAGAAAAACAAACACACACAGGGAAAGTGCTG +AAACCACAGGCCAGGTAAGGGGAATCAAGAGGCATGAGGTATGGGCAGAGTGGTCAGGGA +GGGCTTCTCAGAGGAGGCAACGTGTGAAAAGAGCCTGGAAAGTGGCCTAAATGGTCAGTG +CAAAGGCCCTGAGGCAGGTGGCATAGGCTGGTGAGCGATAGGCAGAGAGTGAATGGAGTA +GGGTGGGGAGAAGAGGATGAAGATGCAGGCTGGGGCCCATCCCACAAGACCTCCTAGGTC +CCATAACAACTGGCTTTTGCTCTGTGCCATGCAGGCTTAGGACAGAGGAATGAGCAGGCT +GGGGAGTGTTTTCACAGGGTCCCTCTGGCAGCTATGACGGGGATAAGGATAAAGCCCAAA +GGGGAGGCTGTGGGTATCAACCAGGCAAGAGATGATGGCCTGGGTGGGAGAAAGAGAAGA +AGCCTGTGCGTTCTGTCCATGTGATGAGGTGGGCTCCTCTCAATCTTCACACAGCACAGC +TGAGCCTCAAACCCAGCACTCACCCTGACCTCTCACCTCCCCACAAGGTAGGAAAACCTG +TTGCCCAGGCTGGAGTGCAGTGGCACGATCCCGGCTCACTACAACCTCTGCCTCCTGGGT +TCAAGCGATTCTCCTGCCTCGGCCTCCCAAGTAGCTGGGACTATAGGCGCCCACCACCAC +GCCTGGCTAATTTTTGTATTTTTAATAGAGACAGGGTTTCACTGTGTTGGCCAGGCTGGT +CTTGAACTCCTGACCTCGGGATCCACCCACCTCGGCCTCCCAAAGTGCTGGGATTACAGG +AGTGAGCCACCGCATCCAGCCCCTATTTCTTTTTAAGACACGGTCATGATTCATTGCCCA +GGCTGGAGTGCAGTGGCACGATCACGGCTCACTTCAGCCTCACACTCCTGGGCTCAAGCA +ATCTTCCTGCCTCAACCTCTTGAGTAGCTGGGACTATAGGAATGCCGCACCACACCTGGC +TAATTTAAATTTTTTTTTTTTTTTTTTGTAGAGGTCTCACTATATTGCCTAGGCTGGTCT +TGAACTCTTGGGTTCAAGCAGTCCTCCCACCTCAGACTCCCAAAGTGTTGGGATTACAGT +TGTGAGCAACCATGCCCAACCAGATTTTATTTTTATTTTTATTTTTGAGACAGGGTCTCA +CTGTATCACCCAGGCTAGAGTACAGTGGTATGTTCACGGCTCACTGCAGCCTTGGCTTCC +TGGGCTAAGTAATCCTCCCACTTTAGCCTCCCTAGTAGCTGGGACCACAGGCACACACCA +CCATGCCCAGCTTTTTATGTTTTTATTTTTTTATTTTTTGTAGAGATGAAGTTTTGCCAT +GTTGCTCAGGCTGGTCTGAAACTCCTGGGCTCAAGCGATCTGCCTGCCTCAGCCTCCCAA +AATGTGGGGATTTCAGGGGTGAGTCACCACACCTGGCCCAGATTTTATTATTTAAGTTAA +CATTTTGTTACCATTGCTTAAAGCCACCTGGTCCTTTTCATCAGATAGTTTCTTACAGCC +AGGCACAGTGGCTCACACCTGTAATCCCAGCACTCTGGGAGGCTGAGACAGGTGAATTGC +TTGAGCCCTGGAGTCTGAGACCAGCCTAGGCAACACAGTGCAACCATGTCTCTACTAAAA +GTTTTGGTCTCGATCTACTGACCCCGTGATCCGCCCGCCTTGGCCTTCCAAAGTGCTGGG +ATTACAGGCGTGAGCCACCGCGCCGGCCTAAATATTTTTTTTTTAATTAGCTGGGTGTGA +TTGAGGCTGGGCACTGTGGCTCACGCCTGTAATCCTAGCACTCTGGGAGGCAGGTGGATT +GCCTGAGCTCAGGAGTTCAAGGCCAGCCTGGGCAACATGGCGAATCCTCGTCTCTACTAA +AAATACAAAAAAAAAAAAAAAAAAAAAAAAAAAATTGGCCAGGTGCAGTGGCTCACGCCT +GTAATCCCAGCACTTTGGGAGGCCAAGGCGGGTGGATTACCTGAGGTCAAGAGTTCAAGA +CCAGCCTGGCCAACATGGTGAAACCCTATCTCTACTAAAAAATACAAAAATTAGCTGGGT +GGTGGCGGGTGCCTGTAATACTGGGTACTCGGGAGGCTGAGACAGGAGAATTGCTTGAAC +CCAGGAGGTAGAGGTTGCAGTGAACCGAGATCACGCCATTGCACTCCAGCCTGGGCAACA +AGAGCGAAACTCCGTCTCAAAAAAAATTAGCTGGGTATGGTGGCATGTGCCTGTAATCCC +AGCTGCTTTGGGGGCTGAGGCATGAGAATTGCTTGAACCGGAAGGCAGAGGTTGCAGTGA +GCCAAGATCGTGCCACTGCACTCCAGCCTGGGCAACAGAGTAAGATTATCCAAAAAGAAA +AAAAAAAATTAGCGGGTGTGGCTACACCTGTAGTCCCAGCTATGTGGGAGGCTGAAGTAG +GAGGATCGCTTGAGTCCAGGTGGTGGAGGCTGCAGTGAGCTATGATTGTGTGACCGCACT +CCAGCCTGGGTGACAGAGCCAGACCCTGTCTCAAAAAGAAAAGGGTCATGATGCCTCCCC +AACAGGATATGGTGGGGACGCTCCAAGACCATGGGAGAAGAGGATACGAGCCGGAGCTAT +GGAAGAAGTGAACACGTAAGACTCCAGAGGCAAACTGCCCGTCTAGACAGCTCTGGCCTG +CAGAGCCCACCACTCCCAGGCCAGCGCCGTGAGGTCCTGTTGAGCCACCCACCTCACTGT +GATCATCCCCAGGTAAACCCTCGGACGTGGGCCCGGTGCCCTCCTTGCTGAGGCTGAAGC +CACGTGGCCATGAAAACCTGAGCATCACAAGCCGCTCTCTGCGTTTGTGGTGTGATCAGG +GCCTTCTACCACAAGCCATGTGCCCAGGCTGATCCTCTCTAATGTGGAGAGGCGGCTGCG +CTGGAAAGGCCTCAGTAAGAGCAGCTGGGCCCTTGCAGACAGACATCACGGTGTGACCCT +CGGGACTGGCTCCCTGCGGCCACTGCAGCACAGGTGTTCACATCTCACAGTGGAGGCAGT +GGAGACCATGCTCGCCTGCAGGCTCTCGGCGAGGCTCTGAGTCTGGCCCCTTGCGTAGCC +CCTGGTGACTCCTTGGCTTCTGGAGCGGAACTCCATCCTTCACATGGCGCTTTCCTCGAG +GGCCTGTGTGCGTGTCATCTGTGGCCAAGTTCCCACTTCATAAGGACATCAGTCATATTG +GATGGGGTCCCACCCTGCTCCAATGAGACCCCATCTTTTTTTTTTTTTTTTTTTTGAGAC +AGAGTCTTGCTCTGTGGCCCAGGAGGGAGTGCAGTGGCACGATCTTGGCTCACTGCAAGC +TCCGCCTCCTGGGTTCACGCCATTCCCCTGCCTCAACCTCCCAAGGAGCTGGGACTACAG +GCGCTCGCCACTGCACCCGGCTAATTTTTTGTATTGTTAGTGGAGACGGGGTTTCACTGT +GTTAGCCAGGATGGTCTTGATCTCCTGACCTTGTGATCCACCCTCCTCGGCCTCCCAAAG +TGCTGGGATTACAGGCATGAGCCACCGCGCCCGGCTGAGACCCCATCTTAATCACACCTG +CAGTGACCCTGTTTTCAAGTTAAGGCCACATTCTGAGGTATTGAAAATTAGGACTCCAAT +ATGAATTCGGGGGGACCCAATTTAACCTGTAATATGTATATCCCAAATGCAATTTTCTCC +TTTTTTCTTTTAGACAGTTGCTCTGTCACCCAGGCTGGAGTGTAGCTCTTGGCTCACTGC +CTCTGCTTCCCGGGCTCCCGCAATCCTCCACCTCAGCCTCCTGAGTAGCTGGGACCACAG +GCGCACACCACCACACCCAGCTAATTTTTGTATTTTTGAGAGAGATGAGGTTATGCCATG +TTGCCCAGACTGGTCTTGAACTCCTGAGCTCAAGAGATGCACTCACCTCAACCTCCCAAA +GTGCTGGGATTACAGGTATGAGCCAGCATGCCTGGCCTCCAAATGAAATTTTCAGAAAGG +CCTTTTCATAATAGTAACGGGAAACAAGTGACATAGGCATAGCCTTGATAAATGTGCCAA +AAGCCCATTTGGAAATAGCACATTTGTAGGAGGCCTGAGGCAAGACTTGTGGGATTGGAC +GGGAATGCTCTGTTCCTGGGACCAATACCTGATGATGGAGAGTGTCCATTCTTCCCTTTA +AAATTTTTATTTTAATATTTTATTTTTAAAAAGGGGTCTTGCTATGTTGCCCTGGCTGGT +CTGGAAGTCCTAGGATCAAGTGGTCCTCCCACCTTGGCCTCCCAAAGTGCTGGGATTACA +GGTGTGAGCCACTGTGCCCAGCCCATTCTTCCCTTTTAATATATACGCTTCACATACAGG +CTTTGTTTTTGCAACTCCTATCAAATCCCAACAATGTATTTGGGAGAATTTGACAAGACA +GTTCTAAAGTTTATCTGAAAGAGAAGCAGCAGATCCTAAATGGCTTTCCCCAGGCCCAGC +ACTGGCAGATAGCACCTTTCTAACCTTCGGGTGTGAATCCAAGGGTGGTGGTGGAGCTTC +AGGACACATGCACCCTCGTGTCCCTCCTCTATGTAAATGGAAGCCTTCAGTGCCAGCTCC +TTTAGGTTGTAAGGACTGAACACGCTCACAGAAGTCGTGTGCACAGTGAGGTGGGGGCTG +AAATGCAGCAGCTCCTCTCCCTGTGTTCTGTCCCCGCCCCACCTCTCCCCCACCTCAACT +TTGACCACTAGGGGACCAATTATAACATGAGATGGCAAGAATAGCTCATGTAAAGCCACC +CCACCCCAGTCACCTGGTTGCTGCATAGTGTCACATTCATAGGAGTACAATTTAGTCACT +AGTAATCCTTTGCGAATAATACAAACGTCCAGTAATTCTTTGCTGCATAACAGGCCTTGT +GCTCAAAAGGTTCTGCAGACCTTGCCTGGGTGCTCTGGCCAAGCTGCAGTCATCCCAGGG +CTGGCTGGGGGCTGGGGGTTTGCCGGCATGCCTGCTGGTTGGTGCTGCTGCCAGTCCCAG +CTACTCGGGAGGCGGAGGTACGGGGACGGCTTGGTCTCAGGAGGTTAAGGCCGCAGTGAG +CCATGATCGTGCTATTGCACTCTGGCCTGGGCAACCAAGCAAGACTCTGTCTCAGAAAAA +AAAAAAAAATAAGGGGGTGAGAGGGGCTATAAAGGCTCTGAGGTCCACGCTCTGGAGGCC +CACAAAGTCTTTTCTGCATCATCTTGTTTGTCAGAGCAAGACCCAAGGGTGAGCCTAGAT +TCCTGAGCTGGGGAAACAGGCTCCACCTACTGGTGGTGAGAACTGTAGACAATCTGTGGT +CGTTTTGAGTCCACTATAAGTAACCAAAATACCTTCAGTCTTGCTTGCATTTCTCAACAT +TAGTGAAAGGGGACCCAGTGCTTGGTTGTAGCAGGCGTCCTAAACTCTCCTTCTGACCTG +CAGAGTTTTCATCTGCAGAATGTCCCCTCCTGGTGCACAGCATTCATGTCCCTTGTCCTC +ATCCCTGGTGGGTGCTCTCGCCGCCTCCTTTCTGATCCCATCCTCCTCCTTGTCCTACCA +ACCGTCTGTACTCACCCTGTGTATTTAGTTTATATAAATGTTAATGCCTGGCCAGCCGTG +GTGGCTCACGCCTGTAATCCCAGCACTCTGGGAGGCTGAGGCGGGCGGATCACCTGAGGT +CAGAAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTTTCTACTAAAAATACAAA +AAATTAGCTGGGCATGGTGGCGAGTGCCTGTAATCCCAACTACTCGGGAGACTGAGGCAG +GAGAATTGCTTGAACCCTGGAGGCGGAGGTTGCGGTGAGCTGAGATCATACCATTGCACT +CCAGCTTGGGCCACAAGAGTGAAACTCTGTCTCAAAAATAAAAAAATTAAAAATAAATGT +TAACACCTGTAGTCCCAGTGCTTTGGGAGGTCAAGGCAGGAGGATCACTTTAGCACAGGA +GGTCGAGGCTGCAGTGAGCTGGGATGGCGCTACTGCTCCTCAGCCCGGGCAACAGAGTGA +GACTCGATCTCAAAAAAAAAAAAAAAAAAAAAGACCAGCGGGGGTGGTTCATGCCTGTAA +TCCCAGCATTTTGGGAGGCCAAGGTGAGTGGATCACTTGAGCCCAGGAGTTTGAGACCAG +CCTGGTCAACATAGTGAGACTTCATTTCTACAAAAAAATAATCAGCCATGCTGTAGTCCC +AGCTACTGGGGGTGCTGAGGTGGGAGGATTCCTTGAGCCCAGGATTTCAAGACCGCAGTG +AGCTAGGATCAAGCCACTGAAGTTCAGCCTGGGTGACAGAGCAAGATCCTTTCTCTCTAA +CAAAAAATTAAAATTAAAAAATATTGGCCAGGTGTGGTGGCTCACGCCTGTAATCCCAGT +AACTTTGGGAGGCTGAGGCAGGTGGATCATTCGAGGTCAGGAGTTCGAGACCAGCCTGAC +CAACATAATGAAACCCTATCTCTACTGAAAATACAAGGATTAGCCAGACGTGGTGGTGGG +CGTCTGTAGTCCAGCTACTTGAGAGGCTGAGGCAGGAGAATCACTTGAACCACCACGCCC +AACCTAATTTTTTTGTTGTTGTTGTTGTTAGTAGAGGCAGGGTTTCACCATGTTGGCCAG +GCTCATCTTGAACTCCTGACCTCAAGTGATCCACCTGCCTCAGCCTCCCAAAGTGCTGGG +ATTACAGGTGTGAGCCACCGCGCCCGATCTGAAGACATTTTTGATTGGTTGATTGAGTTG +GGGGTCTCACTGTTGCCCAGGCTGGAGTGTGGTGGCATGATTATAGCTCACTGCAGCCTT +AAACTCCCAAGCCCAAGAGATCCTCCCAGCTCAGCCTTCTGAGTAACCGGGACTACAGGT +GCACACCAGCACACCCAGCTCATTTTAAATTTTTTCTTTTTTTTTGAGATGGATCTTGCT +CTGTCACCCAGGCTGGAGTGCAGTGGCGCAAGCTCCGCTCACTGCAAGCTCCGCCTCCCG +GGTTTATGCCATTATCCAGCCTCAGCCTCCCGAGTAGCTGGGACTATAGGCACCCGCCAC +CACGCCCGGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTTTCACCGTGTTAGCCAGGA +TGGCCTCGATCAGGAGATCGTCCATCTTGGCCTTCCAAAGTGCCGGGATTGCAGGCGTGA +GCCACCGCGCCCGGCCCCGTAGTTTCTTACATGTTCACAAAGAGACAAACTTAAAAGAGC +AAAGCATTACGAACTTTAAGAGGCCAGTGCAGGAGGATCACTTGTAGCTAGAATTTTGAG +ACCATCCAGGGCAACAAAGTGAGACTCTGTCCCTACAAAAAAAATTTTTTTTTTTTTTTT +TTTTGAGACAGACTCTCGCTCTGTCGCCCAGGCTAGAGTGCAGTGGCGTGATCTTGGCTC +ATTGCAACCTCCGCCTCCCGGGTTCACGCCATTCTCCTGCCTCAGCCTCCCGGGTAGCTG +GGATTACAGGCACTCGCGACCATGCCCAGCTAATTTTGTATTTTTAGTAGAAATGGGGTT +TCACCGTGTTAGCCAGGATGGTCTTGATCTCCTGACCTCGTGATCTGCCCTCCTTTGCCT +CCCAAAGTGCTGGGATTACAGGCATGAACCACCGTGGCCAGCCTCTTTTACTATTTTTTT +TTTTTTTTTTTTAAGATGGAGGCTCACACTGTTGCCCAGGCTGGAGTGCGGTGGCACGAT +CTCGGCTCACTGCAACCTCCGCCTCCTGGTTTTATGCGATTCTCCTGCCTCAGCCTCCTG +AGTAGCTGGGATTATAGGCCACCATGCCCAGCTAATTTTTTGTATTTTTAGTAGAGGTGG +GGTTTTACCATGTTGGCCAGGCTGGTCTCAAACTCCAGACCTCAGGTGATCCACCCACCT +TGGCCTCCCAAAGTGCTGGGATTACAGGTGTGAACCACTGTGCTTGGCCTTTACTACTAC +ATTTTTTTTTTTTTTTGAGATGGAGCCTCCCTCTGTCACCAGGCTGGAGTGCAGTGGTGC +AATCTCGGCTCACTGTAACCTCTGCCTCTCGGGTTCGATTCCCCTGCCTCGGCCTCCCGA +GTAGCTGGGACTACAGGCAAGCACCACCATACCCGGCTAACTTTTTTTTTTGTATTTTTA +GTAAAGACAAGATTTCACCATCTTGGCCAAGCTGGTCTTGAACTCCTGATCTCATGATCC +ACCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGTGCCCGGCCGTC +TACTACTTCTTAAAGGGTGAGAGGCGGAAGGATCACTTGAGCCCTGAAGTGTGCGACTGC +AGTTAGCTTTTATCGTACCACTGCACTCCAGCCAGGGTGACAGCAGGACCCTGACTCTAA +AAAAAAAAAAAAAAAGCAAAAAAAAGCATATACTATTAATACTTCCTCCTTACTATAATG +TTTACTGTGGCCTTTATCAGACTAGAGAGTGCTTTTATCTCTCCCTTTTGTTAGAGCTTT +TAGAATTATCAATAGATGGTCAGGTGAGGTGGCTCAGGCCTGTAATCCCAGCACTTTGGG +AGGCCGAGGTGGGTGGATCACGAGGTCAGGAGTTGAAGACCAGCTTGGCCAAGATGGTGA +AACCCTGTCTCTACTAAAAATACAAAAAAATTAGCTGGGCGTGGTGGCGAGTGCCTGTAA +TGCCAGCTACTCTGGAGGCTGGGGCAGAGAATTGCTTGAACCCAGTAGGCGGAGGTTGCA +GTGAGCCAAGATTGTGCCACTGCACTCCAGCCTGGGCAACAGAATGAGACTCTGTCTCAG +AAAAAAAAAAAATTATTAATAGATGGTGACCCTCATCTTCATGTTTTCTGCATCTATTGA +AGTGCGCCATTGAGATCGTGGAGTTCTTCCCTGTTTGTCCATATGGTGAACAACACTGAT +TTTCTGATGTTGAACAATCTCTGGAATAAACTCTGTTTGGTTTCCATGGATTTCTGTTTC +CCTTTAGATTTTGTTAGTAATGTATTTTGGATTTTTGCATCCAAGTTCATAATTGTAACT +GGACAAATAAAGGCAGATTTTAAAAGGACAAGTTGGGAGGCTAAGGCGGAAGGATCACTT +GAGCCTGGGAGATTGAAGCTGCAGCTAGCCTCGATTGCTCCACTGTACTCCAGCCTGGTG +ACAGCAGGACCTGCCTCTAAAATAATAATACTTAAAAGGACGAGTTTACCTACAGTCTCA +CCAAGCAATGAAAGAGCTTATCTTCCTCCTGTTTCCTTTACGGATCTTGCTCATGTATTT +TATCTTAGTTACTTTAGCATAAATGCTAAATCAAATTCTTTTTCACTAGACATCATCATA +GCTCTAGGCATACCACATAATACCCAAGCACATTTTAATCATTAAAATTGTTTCCTTTTT +TTGTGGCTACTGTAACCACTTCAGCGAACCATTTAGTGTGTAGTGGGTTTAAATTATTTT +TTCTCCTTTCTGGGATAAATTTCCCAGGAGAAGGATAATTGGGTCAAAAGCTACGAACAT +ATTTATGGGTTCTTTTCCACAAGAGATCGATCAGTTTGCAAGTGCCATCTGCAGTGTGGG +GGAACCAATCTTCAACTTGCCTGCATTTGGTATTAGTATTTTATTAACCTTTCATTGATC +CAATTACGGCTCTTTGACACAATTTTCATCAGTGATGGACTAAGTGTGATCCGGCCTGAC +CCGCCTCCGGCCGGCGTGAGAAGGGGCATGTGTCGGGCTACGCTCGGGCTTCCCCTGCCG +CCCATTGTGATCCAGCCCGCTAGGCGCTCCCTGCCGCCCATTGTGACGCCTGCCAGCCGC +AGGCTGGGTCCCCGAGGCGGGCGGCATTTAGGCTCGGTCTCCACAGCCATGGCCGCGACG +CAGGAGCTGCTGCTGCAGTTGCAGAAGGATAACCGAGATGGTCGCCAGCGGAAGCAGGAG +CTAGAGAAGCTGATGCGCGGGCTCGAGGCCGAGAGCGAGAGCCTCAACCAGCGCCTGCAG +GACCTGAGCGAGCGGGAGCGGAGGTGCGCGGGGAACGCCGCTCTTCTACCTGGCGGGCGC +GCGAGGGTCGGTCCCGCAGGCAGCGCCGCGAGGTGCTTCGCAGAGTACCAGGCTGATCCG +CCCGGGCCCGCATCTCTGCTCTAGGCCCTTGGGAACGGGTGATCCACCCAGCGGACCCAG +GTGGGGGACTCGGCCAGGACTTCCCAGTCCTCAATCATGAGCCTGCGGCTGGTCCTTCCT +GGCGACTGCGGGATCCTGAGCGACCCAGTCCGCCTTGTAGCGCCAACCTCAGTTTCCCTC +TGCAGCCTGCTGCGGAGGCGAAGCCAGGCAGCGCAGCCTCTGCAAGGGGAGGCGCGCGAG +GCGGCGCGGGAGCGCGCGGAGCGGGTGCGCAGAAGACTGGAGGAGGCGGAGCGCCACAAG +GAGGACTTGGTGAGGAAGAGTCCTAGAATGGGGCTGGACCCAGGGTGGGGTGAGGCAGGG +CGGGCGGAAGGGGGCGGGATCCGGGGGTGGGGTGAGGTAGGACCGGCGGAGAGGTCGGCA +CCGCCCCAGGACCCCGTCCGCAGGAGCAGCACAGCAGGCAGCTGCAGGAGCAGTGGGAGG +AGCTGTCGAGTCAGGTACGTGCAGGAGATGGGAGGGCCTGTCTCTTGGTTCCTCTCGGAA +GTCCTGCCCTTGTCCTCGCCCTTGTTGTCTCCCCGTCCCTGTCTCCCCTGACACTCGTTC +CTCCAGAAGCCCGGTAAACCCCGCCCTTACAAGCCCCGCCCCTAGCTCTTCTACGGAGGG +GAACCGCAGAGCCAGAAGAGCACGGAGCAGCAACTCGCAGCCCAATTGGTGACGCTGCAG +GTGCTTGAGCGGGACCCTGAGGTCTTTAGTAGGGGCGGAGCAGCAGCGTGAGCGGGGCCG +TGACCACCTGGGGGTGTGGCTTAAGGCAGGCCCTGAAGGCGTGGGCGGGGCGGGGGATGT +GGGCGGAGCACAATCGCATGGGGGCGGGGCTCTGAGGGCTAGAATAGGGGCGGAGCGCGG +AGGGGGCGTGGCCATGACCAGTTGGGGCGTTGCTTACGACTGGTCCTGAGGACGCGGGCG +GGGTCATGATCGCCTGGGGGCGGGCACTGAGGGCCGGGGGCGGGGCCCGGAGGCGCAGCG +GGTTGCCGGCCTGCGGACCTCCTGACATTCCCTGGGTCCTTCTCAAGAATGAACTGGAGC +TGGCGGAGACCAAATGCGCCTTGCAGGAGGAGAAGCTGCAGCAGGTGAGGGCAGAAGCGG +GTTCTGTTGGAGGAGGGTAGGCTTTCGAGTGTGGATGGGGAAGGGCCTGTCGCCCCGACG +CCGCCGAGTCTAACCCGGGTGTCCACACCCAGGACGCGCTGCAGACAGCGGAGGCCTGGG +CCATATTCCAGGAGCAGACCGTAGTCCTGCAGGTGCGGCCCCACTCAGACGCCAAGGTGC +CTCCCGCCTCTCCTCCCCCAGACCTGGGGCGGTAAGTCTCCCAACCCACCGCCAGGACGC +CTCCCCGAGGCCTCAGTCCGCACTCTCACCCGCTCCAGGAGGTGCAGGTGAAGGTGATGG +AGGCTGCGGAGGAGCTGGACGCCTGGCAGAGTGGCCGGGAACTGTAAGGGAGTTGGGCCT +GCGGGCGCGGCGGGGCACTGTGGGGCCGGGCTGGGCTCCCACCTGCATGCCTGTCCCCGC +AGGTGTGACGGGCAGCTTCGCGGAGTGCAGTACAGCACCGAGTCGCTCATGGAGGAGATG +GCCAGGGCGGACCGAGTGAGCGCCTGCGCGGGTCCGGGCGGGGTGGGCTGGAGCGGGACA +ACCCTCCCCGTCCCCCCCGCGGTACCGCCTCCCCCTCCTCCTGGAAACCGGGCCGGCGCC +GCGGGCGCGGAGGTAGCTGGATGCGGCCCTCTCTCCCCGCAGGAGACGCGGCTGTTCGGC +GGCCCTCGCGCGCTGGCCATCAGGTGAGCCGGGCGGTGGGCGCGGCCGCGGTCCCCCACC +TGCCCGCCTTTCGCCCCGCAGGCGGTGCGTGCTGGGCGCGCTGCAGGTGCTGCTGACGCT +GCCGCTCCTCTTCCTGGGGCTGTCGCTGCTCTGGACGGTGCTGTTGGACCCCGGCGCCGT +CTCCGCGTGGCTCTGGAGCCTCACCTCGGAGACGACGCTGCGCCGCCTGCGCTACACGCT +GTCCCCGCTGCTGGAGCTGCGCGCTAACGGGCTGCTGCCAACCTAAGTGCAGCGCCCCGC +GCCTGGCTCCAGGTGGACTCCAGGGCACCTGGCTTTATTTCTGGTGCACTCCTCTCCTGA +GAGTGTAGACCAAGGTTGCCTAATAAACTCAAGGGATGAAGCTCGTGGGTTCGTCGTCTG +TCTCCCATGTCATGTAGGAGCTTGACTGGCTTTTCAGCCTCCAAAGATTCCTTCCTTCCT +TACAGCTCATGGATTTAGAGCCACTCCCCAGTATTGTAAACAGCATTTTTAGTTTTTCAG +GATACATAATTTGCCATATTGCCAGAAACTTGTACATAGCATTTGACACTTTGCCAATCT +GACAAGCTGCCTTTTCAAGTATTGTGATTTGAAATTATTTCTACTATATTTGAATTTATT +TCTACCATTTGTAACATGTTGATCCTGATTTTTCAATGCTCCCCTTTCCTTCTGTTTATT +TGGGAAGTCACACTCTGTATTCTGGTATTCTTACTACTTGAGCTCAGCTCATCGCTGTCA +TCTTCCCCTAAACCGCCTTAAAGCATCTTAGGTCTTTTCCCTCTGATCACATGTGCTACT +TTTTTTTTTCTTTTCTTTGGAGACGGAGTCTTGCTCTGCGCCCAGGATGGAGTGCAGTGG +CATGATCTCGGCTCACTGCAAGCTCTGCCTCCCGGGTTCCAGCGATTCTCCTGCCTCAGC +CTCCCAAGTAGCTGGGACTTCAGACGCCCGCCATCATGCCCGTTTAATTTTTTGTATTTT +TTGTAGAGACAGAGTTTCACTGTGTTAGCCAGGATGGTCTCGATCTCCTGACCTCGTGAT +CCGCCCACCTTGGCCTCCCCAAAGTGCTGGGATTACAGGCATGAGCCACCGTGCCTGGCC +AACATTTTCTCCAGATATCTTACTGAGTCCTAATTTCCACTGTGGCCAGAGAATACACTC +TGCATGATTTTAATTCTATCTCATTTACTGAGACTTGTTTTGTGGCCCAGCACAAAGCTT +GTAATGAACACTGAGAAGAAAGTGTATTGTTGCTGTTGACAGAGTGATTTTTTTTTTTTG +AGACGGAGTCTCGCTCTGTCGCCAGGCTGGAGTACAGTGGTGTGCAATCTCGGCTCACTC +CAACCTCCACCTACTAGGTTCAAGTGATTGTCCTGCCTCAGCCTCCTGAGTAGCTGGGAC +TACAGATGCATTCCACCATGCCCAGCTAATTTTTGTATTTTTAGCAGAGACAGGGTTTCA +CCGTGTTGGCCAGGATGGTCTTGATCTCTTGACATTGTGATCCGCCTGGCTTGGCCTCCC +GAAGTGCTGGGATTACAGGCATGAGCCACCGTGCCAGGCCGACAGAGTGTGTTCTAAATA +CCCAGCAGGTCCAGGTGAGTGACAGGCTTGTTCAGGGCTCCTGTGTTTACTTTCTTGTTG +GTAGCGCCGTCAATTGCTTATTGTGAAATGCCCCTTCATAAACACCCATACACATTTTGA +TTATGGATGGCCAGTCTTTTTTCTATCTGTTATTTTCATCTTACATCTGTCTTCATATGT +AAAGTGCTTTGGTTATAATCAGCACATAACTGGGTCTCACTTCTTCAATTCATGTTTGTA +ATCCCTGACTTTTAAATTGGGCTGGTAAGTCTATTATGTTTCTCCTTTTCTGCCTTCTTT +TGGATTAGTATCTTTTAAAACTCCTTTTAACTTATACGCTGACTCATATTTTTTATTAAG +ACAGTCTCACTCTGTCATCCAGTGTGGAGTGCAATGGTGTGATCTTGGCTCACTGCAACC +TCCACCTCCCGGGCTCAAGCGATCCACCTCAGCTTCCTGAGTAGCTGGGACTACGGGCTT +GTGCCACCATGCCCGGATAATTGTTGTATTTTTTGTAGAGATGGGGTCTTGCCATGTTGC +TCAGGCTGTTTTCAAACTGCTGGACTCCAGCAATCCACCCACCTCAGCCTCCGAAAGTGC +TGGGATTACACATGTGAGCCACTGTGCCCAGCCTATATTTTTATTTGTACTGCTCAGGAC +TCAACTGTGCTTCCTAAAGCTGAATATTTGTGTTTTTCAACTCTGGAAATCCCATTAGAA +GTTGATTGGGGCCGGGCACGGTGGCTCCAATCTCAGCACTTTGGGAGGCCGAGGCGAGCA +GATCACCTGAAGCCAGGAGTTCAAGATCAGCCTGGCCAACATGACGAAACCCCTTCTCTT +CTAAAAGTACAAAAATTAATTAGCTGGGTGTGGTGGCGTGCAGCTGAAATCCCAGCTACT +TAGGAGGCTGAGGTAGGAGAATTGCTTGAACCTGGGAGACAGGTTGCAGTGAGCAGAGAT +CACGCCACTGCACTCCAGCCTGGGCGACAGAGTGAGACTCCGACTAAAAAAAAAAGAAAA +AGTTGACTGGAGCTTTTCATTCAACTCTTCTTTTTTTTTTTTTTTTTGACCGTTACCCAG +GCTGGACTGCAGTGGTACCATCATAGCTCACTGGAGTCTTGCTCTTCGGCTCCAGTGATC +CTATCTTTCTTACCCTCCTGAGTAGCTGGGACTACAGGCATGCACCACCATGTGGCTAAT +TTTAAATTTTTTTGTAGAGACAGGGTCTTCCCGTGTTGCTTATGCTGGTGTTGAACTCCT +GGACTCAAGCAATCCTCCTGCTTTGGCCTGCTGAAGTGCTGGGATTAGGAGCCACCCCGC +TTGGCTTTCCTTTCCTTCACACTGCATGTTTGGTCATTTCACTATTCTGATCACTGATTT +TCTCTTCTTACCTGCTGCTGTTTAGCTGATCTTTTGGAGTTTCTCTTTTGTTTCAGGTCT +TTATTCCTATCTGCTTCAGATGCAGGGCCTCGGTGGGTGGGAGTAGATGCTTGCTGGGTC +TAGTCACACAAAGATTTTGGAGTTCCAGAGCACAGCACTTGAAAACAAGCAAGAGGGAAA +GACTAGAGCAGTGGGAAGATGCTGCGGAGAGCCACAGACAGGCCCCCACGGCAGCCCTGA +GGGAGACAGTTTTGGAGCGGGCAGACAGCAGTCAGGACAAACACAATGTGTGTTTTGGTG +CACCTATGCCGTGGTGAGATTATGGGAATCTCATGTTTGTTAAGCCACAACCCGTGCTCC +TGGGCCCCAGCCTATGAGTGCAGCCAACACTGGGCCCCCCTCTCTAGGGGCAAATCCAGG +AACTGCCCTTTGGCTGAAGGTGGACTTAGGACTTGACACAAAACCTCACAGATTCCAACA +CAGCACTATTTTGGGTTTTTATTTTGTTGATGTTGGTTAAATCTTATCTCTTTTTTTATA +CACAATACTTCATGTACCTATGAAATAAAACAGGTAGGGAATATGTCCAGTGCAAACAGA +GGACTCACACCTGTGCATAGACAGCACCATCCACTGATTGTCGCTGCAGTCCACGGCGTT +ACTAAGCCTGCGCCACCCACGTGCTGCCCCAGGAGGCGCTACCAGGCTCTTCGGGCCACA +GGCCTCTCCTCCACTGCATGTGGCGGCAGGGCGGGTAGGTCGCAGGGCTCCATGATTGTG +GGGCAGCTTCAAGGGCACATGGGGCAGAGGCCCTCGAAGGTCCCCTCCTCAGTAGGGGAT +GTCATTCTGATAGTACTGGATCATGTTGTAGGTCCGGCTCCTGAAAGGCCAAGAAGAGTG +AAGGGAGATTCGAGGAGCCAGCAGGGTCTGGGGTCCCTCCCTGCAGGGAGCCCTACCTGT +CCAATCAGCCCCTTATGGCTGCCCAGCACCTGAAGGTACAAATGTCCCAGGCGTGCCCTC +CCCCACCCAGTGACCACATCTGCTCCAACCCGGGGGACTCTGAGGCCACCTCATGCTCCT +CAGCCAAACCGCTTCCATCCGTGGGAGCCACTGCTCTGCCCCATGGGCCTCGGGCCCCTT +GGCTCGTCCTGGCCAGATGCCTCCAAGGGGTCTGTACGCTCTCCTCGCACCTCTGGAGAG +CCCCTTCTCGCCCTGCCCCAGCCCCTCTTGAGGTCCTGGCCGCCTGGCTTCTCTGCTTCC +TATCAGCAAGAGCTCCTTCCGTGCCCAGCCTCCACAGTGCCCTTGTTAGGGTGACGGACC +TGGGCGCCACCTGGGGGCAGGTCTCAGCTTCCTCTCACGCTCCTCCGGCAGTTCCCCATG +CAGATGGCCACACCTGGGCCCCTCCTCCTAGTCTGGATGTGGTCTGTCCCATGGCACAGC +CTTGGGCTCCCACATGCCCCTCAGGGCCTTACCAACCCCACATGTTTAAGTGCTGCCCCC +TTCGGGGATGGCTCACTTGCTGGGATCGCCATCCTCCCTTTGTTCAGGCCGGACCCCTCA +AAGCCACCTCTGACTCCCACAGCAGGGAGCCTGTCAGCCCGGTGCTCTGCCTTCAGACCC +TGAGCCAGCCCTCCCCAGGGCCCCCTGCACCCATCTCCTCCCACCACAGTAGTGACCAGC +AGCCCGGCCTGCACCTCCAGTCACTGCCCACGAAGCAGCCCGAGGCAGGCGCAGGGAAGG +AGTGGGCTCTGACTCCTCAGCCCTCCTGGGAGGAGGGAGGCCTGACACCACACTCAGTTC +TAATACTCCTGGCCTTGTGTCCCTATTGCTCCTTCGGCCTCACGAGCCCTGCCCAGGTGG +GCCCGGCCTCTGCCAAGTGTTCCCCTCGGCACACCACAGCCCCCTAAACCAGCACCCCAC +TGCTCCTCAAGAGTTCCTGTCAAGACTTGGGTCTTCATGAGAGGGGCGGCTTGGGGACAG +CAGAATCCTCATCGCCTGGTGCAGGCAAGGCCCTGCAGGTGCCCAGTGGCCACCGAGGCA +GTGGGAGAAGGCAGGGGGGCGGGGCACTCACCTGTTGCTGAGGAAGCAGCTCTGGATGAC +CTTCATGATGAAATTTGCAGCCTCGCGCTCAGTCATGTTGGGGCTAAACCTGTGCCTGGA +GAAGAGGCTGTGTCAGGGCTGCCATGGGCAGGGCCGTGCTGGCTCCCTGGCCCAGTGGGA +GGAGGGTCTTCCATGGGGACGGACTTCAGCTGAGAGCCATGCCCTGGAAATGTACCTTTG +GGGTCCACATGTTGGAAGATGGGGTGCTGTGAAGGCCACACCTGGCCTATCATGGGCCCT +GTCCCCTTCCCAGCATCACCTGAGTGGCCCCATGGCATTAGGGGACTAAGCATTGGGGAG +CTAAGCTACTGCAGCCCCAGACCTTAGGGTGGAGGTGGGGTGGGCGTAGCATCCTTGACA +TAAATAGAGGCCCCTGGGTGGGTCTCTGGTGTGGCCGGCACAAGCAGGGGCCCCTCACAG +TTGTGGTCTAGGGGTAGAGCCTCACCTAGGAACCCTGTCTGCTCTGAGGTTCCAAGGAGA +TGACAACCACAGTGACAATTACATGAAAGGTACCTATCTTGGATGGAGCCTCAGCTAATG +GACAACTGTCCCCCAGATGGCCTGCGTGTCCACCAAGGAACCTACTTCAAGAACTTGATT +GTCTGGCCGCGAAAACAGGGCAGGCCCGTGTCCAACATGATAGTGACCAGGGAGACGACC +ACATCCATGTAGGGCCTGGGGAGAGACAGGAGGGAGCGGTGGGCAGAGGCCAGCCTAGGT +GGTGGCCCTGCCTGTAGTCCTGTGGACTGGCTGATGCCAACAGCCTCAGGTGTGGGCTCC +TGCCACCCACCTCGCCTGCCACATCTTGCACATCCCCGAGGCAACTTTCGATCTGCTGCA +CTCGGTCACCCGTACTGCCCAGGCAAGGGCTGCCCATACGCACTCTGGACAGGCTGAGTG +TCCTGCCCTGTCCCCCACATAAGGCTGCCGGCCATGGCTTCTGCACCTGGGTGGGATGCA +GACACGCTGACCTGCCTTTCTCTGCGGGGCAGTGGGGATGAACCCAGGTTGGACTGTGGC +CTTGGCCAAGTGACCTGTATATGAAACTGGGACAAAGCCCATCTTTGGCACGTAGCCTGT +GGGGTGGCAGGTGCTCAGGCTTTGGTGACAGGGTGGATGGGATGCCCAGAAAGGGAGAGC +CCATGGCTGAAGGCGTGGGCAGGATTGTGGGGAAGGTGGTTGGAATTAGATGCCCAGAGC +AAGAATTTACTGGCACAGGTGGGCAGACAGAGGTGACCAAAGGACAGGTGTAGGTCAGCA +GGTGGCTGCTAGCACCTACCTCACTCTCTGGAACCGGATTCCCTTCATCCTAAAGGGGAT +CTCAGAACGTTCCACACACCCCCTCCGCCTCCACCCTGGTCCTCACCCAGGCTCACCGCA +CAGCCAGGTAGCCTGGACACACATCTCCATGAACCACTTGAAGGGTGTGGCCTCCATCTT +GCCCCCCATGATCATCACCATCTCATCCGTCAGCTTGATGTCGGGTTCCCAGCCGAGATT +GCCGCCCGGCGAGCTTTCAAACATGAAGCCAAAGTCTGCAAAACCCCAAAGAGCTGCCTG +TGACTGGGTAGGAGCCAGGGCGGGCAAGGACGAGTGGTCTGTTTTGAGGAGTGGAAAAGG +ACTCTGCAACAGGAGCACCCCCTCCACCCCCAAAAGGCAGGTTGTGTTTTCTTGGAGACA +GTGATGGGGTGGGTGGTGGGGCAGCAGGCAGAGAAAGAGAAGGGAGGAAGTGGAGGAAGG +AGCCAAGCTGGGGCACTGAACCTGGACGAGCCCCACTCCGCCCAGCTCCAGCTTCTGACT +CAGAGCAATGGCGGCTCTCGCCCCAGCTCCCTGGGGCCGGGGCCAGGCACCCTCTACAGC +AGAACAGCTTGGTGGCCGACAGTTCGGACCTCAGAGCTGGACCCTGACACTCCTGGCAGG +GTGGTCCTGGGCATTCTCCTCTCTGTGGGGTGGGGATCCCTATCCACCCCTGGGTGCCGG +GGTGAAGGGAGAGGAGGGTGGCGCTGTGGCTGGCTGACCGATGTGGATGATATGGCCCTT +CTTGTCCAGCATAATGTTGCCGTTGTGTCTGTCCTTGATCTGCAGCAGGAACAGCAGGAG +GCTGTAGGCGGCCATGCTTCGGATGAAGTTGTAGCAGGCCTGTGCAGAGAGCGCCCTGGG +CTCAAAAAGGCCCTGGGGCCTGTGGGCATTCTCCCTGGTCCCACACCCAGGATCCCTGGG +CCTGTGGGCACTCTCCCTGGCTCTGTGCCCCCACTATGGAGGCAGAGCCCGAATCAGCAA +GTCAGTCTTCGGCAGCAGGAGTGACGGGCTGTCTGGATGTGGGGGTGCAGGCACTTCCTC +CCACACTCAGAACTTAACTTTCTTCTAAGGAGTCCAGCCCAGCTCTACATTCTTTTGACT +CCCAAAGTGGCTTACAGATGCCCTGGTGTTTTTTTTTTTAAATGGAGTCTCGCTCTGTCG +CCAGGCTGGAGTGCAGTGGCATGATCTTGGCTCACTGCAACCTCTGCCTCCTGGGTTCAA +GAGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGACTACAGGTGCCCACCACCATGCCC +AGTTAATTTTTTTACTTTTAGTAGAGATGGGGTTTCACCATGTTGGTCGGGATGGTCTCG +ATCTCTTGACCTCATGATCTGCCCGCCTTGGCCTCCCAAAGTGCTGGCATTACAGGCGTG +AGCACTGCGCCCGGCCAGGTGCCCTGGTTTTTTTTTTTTTTTTTTTTTTCAGATGGAGTC +TCACTCTGTTGCCCAGGCTGGAGTGCAGTGGTGCAATCTCGGCTCACAGCAACCTCTGCC +TCCTGGGTTCAAGCGATTCTCCTGCCTCAGCTTCCTGAGTAGCTGGGACTGCAGGCGCGT +GCCACTATGCCCAGCTAATTTTTGTATTTTTAGTAGAGACAGCGTTCACCATTTTGGCCA +GGATGGTTTTGATCTCTTGACCTCGTGATCTGCCCGCCTCGGCCTCCCAAAGTGCTAGGA +TTACAGGCGTGAGCCACCGTGCCCAGCCCAGGTGCCCTGGTTTTAACCCTTAACAAAGGA +TGACTGAGGAGAGCAGGGTGTGGGTAGAGGCTGGGTATGGGTGGCTGGGGTAGGGTGGAG +CGCACACGACTTTCCCCGGCCTGTGGCCACCCTGGCTACCTGCTGGAAGGCCAGAGTGGA +CTCATCCCCGTACTGGCGTGTGAAGTAGTCGTACATGCCAAAGTCTGTCTGGCGGCCCAG +CTGGTCCCGGGAGGTGCAGTCGGGGATGCACTCGATCACCCCGCACTAGGAGGAAAGGCC +AGTTCTGAGGCCCGCCGGGTGCGAGGTGCCCAGGGCTGCCCTACTGGCTCCACTCAGGGA +ACTTACCCCAGGGGCAGTGGCCACCACGCGGTAGGGAAAAACAAAGAGGTCCAGGCCGAC +CAGCTGGAAGATGTTCTTGAAGAGGTCGATGATCTGCAGGGCCAGCATGTCCTGGGAAGC +CGGGAGGCGCAGGATGCGGTCAGTTGGCGTCCTTGCACCCCAGTAGCTCTTCTGGCTCAT +GCAGGGCAAAAGCCGAGAACCCAGAGATGGAGTGAGGTGGGGAGACCACAGCCGAGCAAG +AGTCTGGAAGGCCTTCCTTTCTGACCACCGGGGGCTGGACTCAGGCTGCTGGGACCACCA +GGCCCTGGGCTGAGCATGAGGCTGAGCTGTCTGGTGGGGTGTGTGAGATAAGGCACCCAA +CCCCTGGACAGTTCCCTCAGGTGGGCACTGGCATGGCAGGGACAGTGGGAAAGGGGCTGG +AAGGAGAGGCCTCTGGGTTTTGCAGAAGCCCTAATTTACCCCGTGGCACCTGAACCATGT +AAGAGAAGGAAAAGATTCACATTTCTGCATATGAGATTGGACTCTGGTGGGCCTGGAGCC +TTGGGGAGCAGCAAGCCCAGTCCCCAAGCCTACTTGAGGCCTGACCCTGCTTACCTGCCG +GCAGTCGTCTCCCAGTTTGAAGATGGCTGCCTGCCAGGAGATCTTCTGGCCGTCGGCCTC +CTGCGTGCTGCACTCATCCTCAGAGTCTGAGCGGCACCGCAGACCTGCCCGCAGGGAGAG +AGGCCACTGTTAGCCTGTAGGCAGTGAGAAGCCCTCTGAGGGGGCCAGGGATGAGTCCTC +TCACATGCCTGAAAGGAACCCCAGCAATCTTGGGGATCACTTCTTCAAAACCCCAAGGAG +GCCAAGGAGGAGCCCAGCAGGGCCCAAGGAAAGCCTTGGAACAGCAGGTGGAATCCAGGG +TTGGAGTCTAAGAACATTTAGGCTTAAATGGAACTAAAAACAGAGCCCCATTTCATCTGC +AGTGAAGACCCAGGTGTGCCTGAGTCAGTGTTGGGTGCTGTGAGCTGGGGGGCAGGAGGA +ATGTGTCTGTACACTGGGGTCCTGGGAGGGCTCGGGGCCAGTGTGCAGACATGGCCATGG +GAGGCAGGTCCCTGCAAGGGGTGGCAGCCCCCTCTCCACAGCTGGCCACACCGTCTGTAC +TGGGTTGAAGAGTGTCTCCCTAAAATTCATGTTCACCCCAAACCTTAGAATGTGTCCTTA +TTTGGAAACAGGGTCTTTGCAGATGTAATTAGGTTAAGACAAGGTCACAGTGGATTAGGA +CAGTCCCTAATCCAATGACTGATGTCCTTCAAGGGAGATCATCATGTGAAGAGGGAGGCG +GAGATGGGAGTGGAGCATCTGCAGGCCAAGGTGAGCCCAGGACTGCTGGCAACACCACCA +GAAGCTGAGGAGGCAAGGTGTGACCTGCCCAGAGCCTTCAGAGGGGGCACGACCCTGATG +ATGGACTCCAGCCTCCAGAACTGAGATCGTCCGTACAGTAGCCCCAGGAAACTAACACCC +CCCAACGGCCCCGGGCCCCTCAGCCTCAGGAAGGAGCCTGCTGGAGCATGCCAGCTGACT +CATGGCAGACAGACCTCTGGGGTGGCACATCTGTCAGTGCATTTGAGCTCCCTGCCATCC +CCTAGCGAGGGGTCTGACTGAGGGCAGACAGATGGACAGACATCATCTTTTATGGAGAGC +TGTACTAAATTTAACACATGCCAGAAGAAACTGGCATTAGCAAGGAAAAGCACTGAGCTC +CCAAACAAAATCAGGGTTCTTTACTGACCTTCTTTTTCAAGTTCACTAACTCCACATCGC +TTCACCTTGAACTTGGCCAGATATGGGGCTTTTGCAGCACTGAAAACAACAAAAAGAATG +TGGCACCCATGATGCAGCCGAGAAAAACTTCACACGCGGACGCTGTGGAAGCGGGGGATG +GGTAGGGTGAGGCGCTCACCTCTACATCGGGGTCCCAGACTTGTAGTCGACGTCCAGCAC +AATGGCTTCAGGGTTGCTGGGCAGGGAGCAGCCTGTGCAGGGACAGAGGCAGTCACAGGG +AGTGCATGTGTCACCACAGGTGAGCCAGAGTCAGTTTCCAACACGGATGTTACGTGCGTG +TCCACCCTGCAGGCACACCCCACCCCTGTGGAGGGGCCTCTGGTCCTTGTCCAGGGCACC +ACTAACTTATTATTCTGTGGCCGCTAAGGGTCCGTCCTCCTTGACTCTTCGACTCTTCCA +ACCATCGACCAAATGAGTCTGCACCTTCTGGGAAATGCTCTTCCTAGAGGAGCACTGAGC +CCCATCCTCACGGATACAGCCCTACTGCTTCTGGGGGTGTGTGTGAGGCCTGTCCTGCCT +CCACCTGCCTGAGCAACAGCCTCTGAACAGCCCTCCATTCTTGGAGTCCCTGTTTTTTTT +TTTTTTTTTTTTTTTTTGGATAGAGTCTCACTCTATCACCCAGGCTGGAGTGCAGTGGTG +CGATCTTGGCTCACTGCAACCTCCGCCTCCCAGGTTCAAGCAATTCTTCTGCCTCAGCCT +CCTGAGTAGCTGGGATTATAGGTGCCTGCCACCATGCCTGGCTAATTTTTATATTTTTAG +TAGAGATGGAGTTTCGCCATGTTGGCCAGGCTGGTCTCAAACTCCTGACCTCAAGTGATC +CACCCGTCTTGGTCTCCCAAGTGCTGGGATTACAGGTGTGAGCCACCACGCCCGGCCTTC +CTTACCCATTTGAACACTACTCTCTCAAAAGCCTTACTTAAATGTCACTATGTCCATGAA +CTGTCCTTGGTTCTCCCAGCCTTTAGGACTTTTGTCTAACACGTTTCTTTTTTTCTTTTT +CTTTTTGAGACGGAGTCCTACTCTGTCGCCCAGGCTGGAGTGCAGTGGCTCGGTCTCGGC +TCACTGCAACCTACGCCTCCCAGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGC +TGGAATTACAGGCGCCCGCCACCGCGCCTGGCTAATTTGTGTACTTTTAGTTGAGATGGG +GTTTCACCAAGTTGGCCAGGCTGGTCTGGAACTCCTTACCTCAGGTGATCCACCCGCCTT +GGCCTCCCAAAGTGCTGGGATTAAGGCATGAGCCACCGTGCCAGGCCAACATTGTTTCTT +TATGCTTATTTTATATCTCTGTGAGTTCAAGCTTCTTCAGCTCAGGGACCATGTCTTACT +CATCTTTTTAACAGCCACAATACCCAATGTCATGCCTTTTCTTTTCTTGTTTTTGCTTTT +TTGAGACAGAGTCTCACTCTGTCACCCAGGCTGGAGTTCAGTGGTGCGATCTCGGCTCAC +TGCAACCTCCACCTCCTGGGTTCAAGTGATTCTTGTTCTCAGCCTCCCAAGTAGCTGGGA +TTACAGGCACGCGTCACCATGCCTGGTTAATTTTTTTTTTTTGAGACCGAGTGTCGCACT +GTCATCCAGGCTGGAGTGCAGTGGCGCAATCTTGGCTCACTGCAAGCTCTGCCTCCCGGG +TTCACGCCATTCTCCTGCCTCAGCCTCTCGAGTAGCTGGGACTACAGGCGCCCGCCACCA +CACCCGGCTGATTTTTTGTATTTTTGGTAGAGACGGGGTTTCACCGTGTTAGCCAGGATG +GTCTTGATCTCCTGACCTCAGGTGATCCACCTGCCTTGACCTCCCAAAGTGCTGGGATTA +CAGGCATGAGCCACCGCGCCCGGCCCAGGCTCCCCTTTCTCAGTGAGTGCTCAGTAAATG +TGTGAAATAAGAGGACAAGGGAAAGCCTGTTTCTGGCCAAGGAACTGCCAGTCCCCAAGG +GGGATGTGTGCTCCTTGAGCCCTGAGAGGTGGGCTTTGAGGGGAGCCAAGCTTGGCCTTG +CTGTGGGGTACAGGGAGAGGGGGGCATGCCATCTCCTCCTCTTCCTCACCTGCCCTTCTG +CCTGCTCCAGGCTGTGGCTCACACTCAGGCCCCTCTGTGCTCTCCTGCTAGAGCCCTGCT +GGCTTCCCTGACCTCTGGGGCAAGACTCAGCCAACACAATCTAGAGCCAGGGGCTGGGGA +CTTCTGTGCATGCCCCCTGCAGTACAATGCTTCCAGCTCTTTTTGCCCCTCCCCAGCAGT +TGTGGCCTTCCCAATGCGGGAACAGAGGCCCTGCATACATGTCCTGCCCTCTCTGGGAAG +CCGTGCTGTTGTGTGAGCTCAATACAATGTGTTGGGAAGAAATGGTTAAACCGGGGTCCT +GCAGGGCACTCAAGGACCAGCCGCTGTGAACATCTGCACGGGACAGACAGAGTTTGGAAG +ACAAGTTTGTGCCAATAGTTAGAAATGCAGAGAGAGGCCGGGCACAGTGGCTCATGCCTG +TAATCCTAGCACTTTGGGAGGCCGAGGCGAGAGGATCACAAGGTCAGGAGATTGAGGCCA +TCCTGGCTAACACGGTGAAACCCTGACTCTACTAAAAATACAAAAAAATTAGCCGGGTGT +GGTGGCGGGCGCCTGTAGTCCCAGCTACTCGGGAGGCTGAGGCGACAGAGCAAGACTCCA +TCGCAAAAAAAAAAAAAAAGAAATGGAGAGAGAGCTGCCCAGTGAAGTCTGGATTTCCAT +CTTCTCTTGAAAAGCTCGGCTTGAATTCCCATGTGGCCACAGCCACAGGCACCCAGGAGC +GACTTCCCATGGAGGCGGTGAGGGGGTGGTGCTGATGGGTCCCAGCACACCTGAGCCCTC +CCACACTGGGCCCGCCATCCCCTTGTCTGTGTGACCTGCTCCTGTAATGCTGGAGCCTAG +GAACCCTCTTCTAGAGTAACAGCTACTGAGGTCAGTGTGAGCCTCCAGAAAAACAGCAGG +CAGCAAGGAAGATGAAGGGCACCCACTGACGAGCAGCTCCCGCTCACTAGCGGCAGATTT +TGGGGAGGGGCTGGGGTCCTGGGGCACCAGGCACCGTGGGCCCAAGCAGGTGTGGGGCTG +GCCAAGCCACTGTGTCCACATCCTGCAGTGCCTGGAGAGGGCAGCAGCCTTCACGCCCCG +CCGCCCGCCTGCAGGAAGAGGTTGGTCTGAGCCTCCAGAAGCCACCTGCTCACCTGGCTG +CACCGTCACTTCAGACAGGGCCGACAGACAAGCCTTCTTTCTCTGGTCGCCTTTAGGGTA +GGGCCTGAGAAACAGGAAAGAAATTCTTGCTTTGTCTCCTGGAGGAACTGGCTACTGGGG +GACAGCCCAGGGCCCCTCCTGCCTGGATTGCCCTCTCTGTCCCTCTCTTCCCGGCTCTAG +CTGCTCCTAGCGCAGCCAGGCACCACTGGCAGCGATTCTTGCCCTGCATTCCTCATGGAG +AATCCCCGACAGCCCCGGAAGGGCTGTTTTCTGGCAGGCTCTGCCCCTGCTGTGTGCGGG +GGTGTGTGGCTGGGGGTGGTGGGGGTAATAATGCCTGCCACCTGCTGCCACCCAGGAAAC +GCTAGCTCCCGTCCTTCATCTCTTGGGTTAGAAGCTGCCAGCACTGCTATTCTCAGCACC +CAGCCCAGAAAAGGGCCTCAAAGTGACCAAGGTCAGAGCAGTGTACGCAATGGAGACAGC +CCAGCCGGCGTGCCCAGCATTGATGACTCCAGGGTTTCATCCCTTATGAATGCACAAAGC +CACCAACATCCAAGGATGGTGTCAGGTCCACATGAATGGAAGGTCTAGGAAAACGATGAC +AGGAGCTGCAAAGGCAGTCTGGTTTTCCTGACACCAAGAGGATCGATCCTTCAGAGTGTG +GAGAGGGCAGGGTGACCTCAAATTGTGGAGCCATGTGCTAAATTCCACAAATCTCAGGAA +TGAAACTAAGCTGTGTTTCCTGAAACTGGCGTGGCCGTGCATTCTGCCATACCTTCAAGA +GCCCTGACTCACCCCAAGCAGTGCTTCCCCACCCACCCTGGCTGTCCATCAGAACCACCA +GCAGCCCCGCTGCTAGAGACTCTCATTCATCTGGTTGGGGCCACGCACGGGTATTTTTAA +AGCTTCCCAGGCAATTCTGTTAAGCTGCAGGGACTGGAACAAGATTCCAGAAGGTGGTTT +CCGAAGCACTGCACTTACTTGATGACAGCCGACACGTTGGTGATCTTGTTAAAGAAATCA +AACTCCCGCTGGTAAAAGTCCTTCGCTGGGCCCGACAAGGAGCCTGTGTTCTCCTCTACT +AACTGCTCCCGGAGGTCGCCGATGTCAGCTGCCAAGGAAACAAAGAGGCTGAGTCTCTGT +GGCTGTGGCAGAGGCCCCTCAGGAATACCAGCCCTGTTTCCCAGGCCCCAGACTGGCGGT +GCCCAGAGTATGCTCTGCAGGCTTGGTGAGACCATAACAGCTGCTGTGTGCCCCTTTTGC +TGTGTTGACACAGCCGACACTGCTGGGAAGCTAAGCTGGTGCCTAAGCGGAGCTCAAGGT +AGGGGCCAAGCGCACAAGTGGACGTGGAATCCTCACTGCTGCACACGCTACACACGCAGG +AAGAAAAAAGCCCGTGTCATTTATGAATGTCACAGGGCATAGAATCCTCACTGCTGCACA +CGCAGGGAGAAAAAAGCCCGTGTCATTTATGAATGTCACAGGTGAAGCAATGAAAACTAA +TTCTTATTAAACTCTACCCTGAATACATGTCTTTTTTTTTTTTTTTAATAGAGGCACACA +GTGGGCGGGGCTCTATATTAAATAGTGTCTCTCACTATTCAAATCCCAGGCTGAATTTAA +ATTCCTGGGCTCAAGAGATCCTCCTGTCTCAGTCACCTGAGTTGCTGGGACTACAGCTAG +TAGGTGGGACTACAGGTGCGCATCACCACATCTGGCTTTTAAAGTATCCTTTGTGATGAA +ACGGGATGTGCACGAAGCACTCTTGCCGCATCTAAGGCAGGCGCTGTCCTGAGAAGCACC +TGGAGCTTGTCTGATTTTGGAGCCTGGACTAACCTTTTTCACAGACCTTTGTTTTTACTT +GAAGAAATGACTGACAGACAACATATAGCTATTCAGACTTAGGGATGTGGCAGATGTTTT +CCTGAAAATGAACAAAAAATAAATCTTCCACTCAAAGGAACTGAAACATTTTTTTGGAAA +ACTTGGATCTGCTGCTGTGAGCTCAATAGCTTCCCTTAAAAACTCTTTCTGGGCCGGGCG +CGGTGGCTCATGCCTGTAATCTCAGCACTTCAGGAGGCTGAGGCGGGCGGATCAGAAGGT +CTCAGCCAGGCAATGTGGCCCACACCTGTAATCCCAGCACTTTAGGAGGCCGAGGTGGGC +GGATCAGAAGGTCTCAGCCAGGCAATGTGGCCCACACCTGTAATCCCAGCACTTTAGGAG +GCTGAGGCGGGCGGATCAGAAGGTCAGGAGTTTGAGACCAGCCTGGCCAACATGGTGAAG +CCCCGTCTCTACTAAAAAATAAAAAAATTGGCCGGGCACGGTGGCTCATGCCTGTAATCC +TGGCAATTTGGGAGGCTGAGGTGGGCGGATCACGAGGTCAGGAGATTGAGACCATCCTGG +CTAACACAGTGAAACCCCATCTCTACTAAAAATACAAAAAATTAGCCGGGTGTGGTAGCG +AGCGCCTGTAGTCTCAGCTACTCGGGAGGCTGAAGCAGGAGAATGGTGTGAACCCGGGAG +GCGGAGCTTGCAGTGAGCGGAGACTGCGCCACTGCATTCCAGCCTGGGCGACAGAGCGAG +ACTCCGTCTCAAAAAAAAAAAATTTAAAAAAAAGTCCGGGTGCGGTGGCTCACGCCTGTA +ATACCAGCACTTTGGGAGGCCAAGGCGGGCGGATCACGAGGTCAGGAGGTCGAGACCATC +CTGGCTAACACGGTGAAACCCCGTCTCTACTAAAAAAATACAAAAAATTAGGCGGGCGTG +GTGGCGGGCGCCTGTAGTCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATGGCATGTACC +CGGGAGGCAGAGGTTGCAGTGAGCCGAGATTGTGCCACTGCACTCCAGCCTGGGCGACAG +AGTGAGACTGTCTCTCAAAAAAAAAAGAAAGCCCTCTCTCGTCTCTCAGTCTGTGCTTAG +TAATCAGCTAGGCGCTGAGAGAACAGGGCATGGCCTCCTTACAGAGGTTTGCTGCTTCTT +TGCGTGGCATGTTTTCATTTGGCATTCCCTTCCCTGGAATGCTCTGCCCTGTCCACCCTG +CATGCCGGTGCAGCCTTTCAGACTCAGCTCAACTGTCTCTTTTCCAGAAAACCATCTCTG +ATTCCCCAACTCTGGATGGGCCAAGTGTCTGTACCGGAGGACTGCTCCCACAGTTCCCTC +AAATTGAAATCACCTGTCCATTTGACTGCCTCCTACAAGACAACAACAGACCATACCCCA +GTCATGTAGGTGTGCACCAGCCTCAGCCCAATCCTGGGCCGTCAGCTGCTCAGAGGGGTG +TGTGAACGCAGCTGGTGCCAGTGCAGGGAAAGTGCGGTGAGTGGAGTCTGCTCAGCTGCC +TCGGGTGCGTGTTTATGCTTCTCAGCTCAGGCCAGAGGAGAAGCAGAGCCAGGCATGCAC +CGGCCTCCAATGACCGTGCAACACAGTCAAGGCCAGGGCTCAGGGGGGTCTAACTGCTTT +TCCGTCCCTACCTCTGGCACCCTCAGGGCTGCCCACGTTGCACCCCTGTCCTGCCTGCCT +CCACCATGAGCAGCTGCACTGTTGAGGGTTACCTGGGGGAACAAGCTGGCTGGCGGTCAG +GTACTTCTTATCTGAGAACATGGCGGTCCAAAATTTAATCATGATGCTTATGTCTTCACG +CAGCCGCTTCTCTCCTTGAGTAGGAAACTTTGGGGGACAGCTTCAAACAACCATAAGAGG +ACAACGGCTGAGTGTCTGGAGTCAGGGACTAGAGGCCAGTCACACAAAGCAGTGAGAAGG +TGATGCAGACAATTTCTTAATGACAAAAGGTCAGCCCAAAGCCAGTCATTAGCAAGGATG +ATCTGGCCCATTCCCATGGGAAGGTGTGGTGGCTCGGGAGCCCTCTTATGCCCTCCTCCC +TCACTGCCCACAGCAGCCCCTACAGCTTTCCACTGAAGCTGCACTTGTGGCAGATCAGGG +CAAGGAAGCTGCACTCACACAACAGCACAGCCTATGGGTGCAGAGCCCCAGGCAGTGGGT +GTTTGCAATTCTTCGTGCAATAAGCCTTCACATTAACAGGGAAATTAAATGGACGCACTT +AATCTCCTAAATCAGTTGAACTGAGGGAAAATTTGCCTACATCTCGCTGGGAGGCTAGCT +CTAAGTACACGGGACACATGCACAGGGCTGAAGGGTATTTAAATCCACAGGGCCAGGGAT +ACTGAAGGAGGAGGTTGGTGAGCACAACTGGGCAACTGTGTATTCCTGTGAGTGACTTCC +TGGGGGTCTGGGGCGATGGAGCACTTGGAGGGGCTGGGCCGTCCCTGGATGCCGCACAGC +ACATCTTGGGGGAGTACCTGAAGTAGTCAAAGGCAGTGGAGTAGATCTTCTCGCGAAGCA +CATTGCGGATGGTTGCATTTGGAACCACATCGGCATGCAGGAGGGACAGCCCCAGGGTCA +GCAGCCTGTGAGGGAGCCCCGGACCCGGTCAGAGCAGGAGCCTGGCCTGGGGCCAAGTTC +ACCTTATGGACTCTCTTCCCTGCCCTTCCAGGAGCAGCTCACTGAAATGTGTTCCCCGTC +TACAGAAGTACCGTGATACACAGACGCCCCATGACACACTGTACACACCAGGGGCCCTGT +GCTCCCCAGGAAGAGGGCCCTCACTTGAAGCGGGGCCCGATGGCCGCCACATGCCGGTTC +ATGCTCCCCTTGGCCCCACCGATGTTCAGGGACATGGAGCGCTGCAGCAGGCTGGAGAAG +ATCTCCACTTGGTCAGAGCTGCAGTACTTGGCGATCTCAAACCGCTGCACCAGGAACTGA +GCGAAAAGAGGAAGACGCTGTGGTGGTGGGGCTGAGCCGGGCTAACCCTGGGGCCGGCAG +AGACAGCTGAGGAGGGGTTCTGGGCTGACTGGCCGAGCTTGCCGAAGGCCTTGGGCTCGG +CTACCCCCACCCCAGGAACAGTCCTGGCCCCCCAGGTGGAGCACCCCACAGCCTTGGTCG +GGGAACAGGCACGTACGTCGATCCAGATGTAGTGGGGGGTCACTTCGGGGGGACAGGGTT +TGGGTTGACTTGCTTCCGAGGCAGCCAGGGGGTCTGCTTCCTTTATCTCAGCAGAAAACA +GGCCAAATTTCTGCTCCACTGTCATGTGCCAGCCCCTGCCATCTCCCGCATGAACTACAG +GTACAGAAGGAATGTTAGCTCCTCTGTGAAACACAAAAAGGGGCTACTGTCAAGTTTTCT +CTAATTAAAAAAAGGAACACGTGCTCACTGAATAAGATTTAGAAACCAAGAAAAGTATGA +AGAAAAAAATGAAGATCGCCTATAGTCCCACATCCCAGGGTCATCTGTGTCAGTGCTTGG +TGTATTTTCTCCAGCCTCTCGAGGCTGCATTCTGTTCAACCCGGTTCACCGTGTGGACAT +TGCAGGTGTGAGGTGGCAGCACCCGGGATGTACCTGATGCCCTGACAGGCACTGGGTAGG +TGACTCTTCTCTATAACCCTGATAACCCTCTGTGGCTGTGAGCGGGAAGACCCCTCTGTG +GGCTGCTGAGCTGGCAAGGGCAGAAGAGGGTTCTGGATCCAGGGCCTGGCTCCTCCTCTC +CACCCCACACAGACCCTACCCGATACCTTCATCCCGCTAACCAGATTAGGAAGGCCCATG +GAGCCGAGGCGAGCCTGCAGCCACCATGGCCAGGCCTGGGAGCCCAGGGTCAGGCTGCTC +CCATGGCCCAGTCATGCTCAGCCAGGTCCCCATTCCGTGGGGGGGCATGAGGGGTGCCCA +GAGGGAGCAGCATGGTGCCCGGGAGACACCTGGGTGCTGCAGAGAGTAAGAGGTGCAGCT +CACACATGGAAAGCCCCCATGATTTCTGGGTGTTTTTACAAGGAGACCAACAAACAGCAT +TTGGCATCTGGCCAAAGAGGATTCTATCCCTCTGTTGTCCCAGCAGCACCAGCTTCTACA +AGGGCTCCAAGCGCCTGTGCAGAGGTGGCAACGAGGCCTAGTGAGTAGAACACACACCGC +GGCTCCCTCCCCAGTACCCATCCCCTCCCTTCTTCCTCATGAGGTGGATCAGGGTGGCCA +CGTGGCCAGTCACAGGGCTCTCAGCCAGGGTCCCTGCTGGCTGAGGCGGCCACTGTTCTC +CCCGGCCACTCTAATGAGCCAGGGAGAGTGAACTGGGCAAGGCCCTGGGAACACATGCCA +GGGTGAGCTTCATAAGGTCAAGGCAGCTGGCCTCTGCCCTTTGCACTCTGTCCTTGTCTT +CCTTCCTGCTGGGAGGCACAGAAGCCATCTGGAGGCTGTGAGGGTGGAGACAAAGGCCAC +ATAAGCCCAGGATGGCCAGGAGCCGACAGGAGCCTGGGGCGGGGCTCTGTCTGCTGCTTC +CCTCTAAGCTGCCCATGGGGTGAGGACTCCTGGGGGACGAGGCACTACAGCCTGCTTTGT +GTTTCCTGCAGACCGATTAGTCTTATGGAAGCAGACAAGGGAGCAAAAAAATGGCGGTGG +GGGGGACCCCAGAACTGCCACGGACAAGAAGCCATCGAAGAGACACACTCCCATCTATTT +GTTAAACAACCACATCCTGGTGGCTGCCTCTGTGCCAGGGCCTCGTGGACTCTGGGCATG +GTGCTCTGAATGAAGACAAACATGACCACACAGTCTATGGTGGGGACCACAGACAACAAG +AAATAAGCTACACACACTGAGAAACACTAAGAAACAGCAGTGCGAGTGAGCGTGTGGCCA +GGTGGCCAGGGAGAGCCCTGGCAAGGAGGGGACATCTGAGATGAGCCCTGGAGGAGACGC +AGGAGTGAGGCGCAAGGCACGGCCATCTGAGAAGAGGGAATGCATGACGCGGCCTATGGT +GGGAGCAGCCCAGGAGGGCAGCTTCAAAAGTGAAACTGATGGGATGTGCTGAGAATCATC +CGTGGGAAGTGCAAGCAGGACCCCAGCATGGCCACAGCACAGCAAGCGAGGGGAAGAGAG +AGGATGGAAGTCAGGTGGGAAGGGGGCTTGCAGGTCACAGAAACAAGCCCACCTTCGAGT +CTGTAGGGGGGCTCTGATTCCCCCCTGGCTTGCGCCAACCGCATGTGGAGAAGGGGAAGA +TGCCTGGGGTTGGGGAGCAGGAGGCCAGGCCAGGGGGCAGCAGCTGGGATGCTGGGACTT +GTCAGATCCTGGATAAACCTCAAAGGTGAAGGTGATGGGATGTGCTGAGAGTCATCAGTG +GGATGTGCATAAGAGGGAGTCAAAGATGTCTGAGCAGAGAGAAGGACCTCGCTGGCATCT +ACAGTGAAGGGAGGGACCTCGCTGGCATCTACAGTGAATGGAGGGACCTCGCTGGCATCT +ATAGTGAAGGGAAGGGTCACGCTGGCATCTACAGTAAAGGGAGGGACCTAGCTGGCATCT +ACAGTGACGGGAGGGACCTCGCTCACATCTACAGTAAAGGGAGGGGCCACACTGGCATCT +ACAGTAAAGGGAGGGGCCCCACTGGCATCAACAGTGAAGGGAAGAACCACCCTGGCATCA +ACAGTGATGGCGGATGGGCGACCAGTGCAGCGGTGTCTGGAGCTGAGGTCGGACCCATTA +GTTGGGGCTGCTAATCAGTTCACCATGCAGGCCGTGGGCCAAGCCACTGAAGGGATCCAC +CTGGACTAGGAGTGACTGGGCTGGGTAAGCAGTGGAGCTGGCCAGAGTAGCCAGGCAGGG +AGGAGGAGCCCTGGGGCATGCCAGTACTGAGAAGGCCCTGAGCTCAAGAAGGTCCCTTTA +TTCTGGAGGATGAAAGGGCTACAAAAATTACAAAGGCCTTAAGTCCCTGGGAAAAGCAGT +TAGGCTCCCAAAACAGCTGCTTTCAAGACCCAGAACTCTGAAGGAGGCTGTGAGCAGCTT +TCCCTGAGCTGATCTGTCCTCCTACCATCTGGGACCTGCTAGTGATATCTGTACTCCAAC +TGCCCTGCCCCCAGGGGTCAACCAACCCACTCCTATCTGAGGACCCACTCCTATCTGAGG +ACCAGACAGAGAGGCCAGAGGTTCAAGGGCACCTGGACTAAGGAAGTGGAGAGGAGAGAG +ACAGATCTGGGCTCCAGAGCCCCAGGTACAATGTGAGGGCTGACACGTGGTCAGGAGCAC +CCCCAGTGCCCTGTGAAATGGGAACGGCTACAGCCCCTACTCTTTTTCTTTTTTTTTTGA +GACGGAGTTTCGCTCTTGCTGCCCAGGCTGGAGTGCAATGGTGCGATCTTGGCTCACCGC +AACCTCCGCCTCCTGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCTAAGTAGCTGGGATT +ACAGGCACATGCCACCACACCCGGCTAATTTTGTATATTTAGTAGAGACAGGGTTTCTCC +ATATTGGTCAGGCTGGTCTCGATCTCCCGACCTCAGGTGACCCACCCGCCTCTGCCTCCC +AAAGTGCTGGGATTACAGGCGTGAGCCACTGCGCCTGGCTGAGCAGCCCCTACTCTTAAG +GCCCACCGAGGTCTGAGGCTGAAGCAGCATATGGAAAGGAATCCTGACCATAGCAGCACT +GTGTCCTGACAGTCACAATTTGTGGTGAAACCAGGGCTTTCTGGTGACCCCAGAAAACAT +CAGTGCCGGCTCTGCCAGCACCCAGACACCTGGTACCCCGAGACTGGCAAGGGGACTGGA +AGAGGGCAGTGGCCTCCAGGCTCCCTCCACACTGCCCAGTGCTGTGTGCACACAAAGGAC +CACGGGTCAGACAGATAGAGGCCGAGCTGTGGGGCTGTGTGCCACCCAGAAACTCCGGGG +AAAGGGGCCAGTGGCGGTCCCCCCTCCCCTGCGCCTCACCAGAGTGCCAAGGGCCCAGAC +ACCATGTGAGCAGCAGCCAGCGGGGCGGGGGGGCCTCCTGAGCCCGTGGCCTTCCTGGGG +GTGCATCAATGCCTGGTCACCTGGGGAAGAGAAGACGAACACAGTCACCCAGACAGCCAT +CAGCGAAGAAGGGAGGGAAGGGCGATGAAGGGACGCACCTGGGGGTCTCTGGCTGGGGCA +CCAGGGGCAGCCCAGCAGGAGACTGTGACCACAGAGCCTGGTAGTTGGATCTGACAGCCA +GGAAGAGTAAGGACCAGCGAACAGGTCTAGGGAGTTCGGTGGGTGCAATACCTGCCCCTC +TAACACAGGACATTAAGGACACCCAGGGGCCACCTAGGCCAGGGGGCGCTGGTGGCAGAC +ACACAATTCTTGGCCTGCGGGTGTGGTAGCAGGAGGCCTGGGCAGGGCCCTTCCCAAGCT +GGCCACATTTACATAACAAAAGGTCAAAATTGGAGCCACTTGTGCAAGGGCTATTTATAA +GAACCAGTCTCAACCGCTTTTGGCTCCCCCGTTCCTTCCCTTCCTGATCTGCTCTCACCG +CCTCCCTGCCCAGAGGGCCCAGCCCCCTAGCCCGCCTGGCCTGACCACATGGCCTTCCCT +CTCCAGAGGTTTCACTGCCTAAGGGCTCACCCAAGCTGCAGGCCTGGGCTTTCAATACCG +GCCCACCAAAGCCTTGGGCAGCTGCCGCCAGGAAACGAGGGGTTCCCTCCCACCCCCAGA +GCTCTGGGTCCTGCAGGAGGGGGGATCCTGAGGTGGTGGGTCCTTGCACCCCACACCTGC +CAGCCTGGGCCCCCACGGAATAGAGCCGGGGTCGGGGAAGGGGCGTGCAGCGGCCCGTCC +CCGTTTCCCCTTCCCCCACTCCACCCCCAGGGCCAGGGAGGCTCAGCAGGTCCCTCAGGA +ATGTGACCAGACCCGGGGTGCCGGCCCAGAGCTGGGAGGCCTAGGCTGCAGCTGGCCAGC +TGTCTCTCCAGCCCCTAGTGCAGCTCCCCTCTGGGTGGGGGGTGTGAGGGGAGGGGGTGC +ATGGCTGGTCCAGGACCCCACCAAAGGCCCAGAGGGCAGCAGAACCAGCTCTGTTGGTAG +GAAGCCCAAGGGCGTCCACAGTTAGCAAGGGTTGGGCCCAGTGGGCTAATGCTGGGATGA +GGCCAGTAGGGCAGGGGCCACTGAAACACTGGCGGGAGCAGTCGAAAAACTGGGTAGAGG +GTCTCGGTGGCACACTGGAGGCAATCAGATACCACCATCCAGCCCTGTGCCACTTCATCT +GCTCCCCAACCACTGCCCCTCAGGACCCAGTCAACCATGGGTAGAGCGCATGCCAAACTC +TGCAGCCAGGGGTCACCTGACCTTGCCAGAGGCCAGGCCAGCTACTGGATGCCGCGCAGG +GAGTGGGTGGCAGAATAGGACTGGGGGGCACCTGAGTGCCATGGGGGTGGGAACACCCTC +CGTCAGTGCCCACTGCCTGGCCCTGTCGGGCACTTTACAAGCCCAAGGCTAGCACTAGGT +CTCCCCACCAAGGAAGGATGGCCCCAGGCTGGGTCAGCTGTGATGTAGAACAGGGCAGGG +CTCCTCCCTGAACCCTCCACTTGAGTTAGGGGGTGTCAGAGCCACCTGCAGAAAGTTCAC +AGCAAGCACAATGCCACCATGCGTGCCATCCACACCAGCTGGGCCAAGTCTGGGCCACAT +CTAGGCCGCCACTGTGTCTGCGAGCAGCAATGCAGCCTCACCCCATGGCGGGGCAGGGGG +TGGCACACGCCATCCTGCTGCGAAACGCCTACTAAGCACTGCTCCTTCCTTCTCAGCCAC +AGAGCTCTGCCCTACCCGCTCACCGCTGGACATGAAACAGCAAGTGCCTATCCTGGAGGG +CTCCGCCTGGGGAGTGCCAGGTAACTAGAAACACGGCTCTGGGTGCTGGCCCGGATGCTG +GTGCTCAGCCCTGGAAGCAGCTGACTGCAGGCTGCGATGAGAATGCCACCTAGCACCCAG +CAGCCCCTGGCAGCAGGCCCGGGCAGCACGCCTATCAGCCCCCAGGCTAGCACGCCCAGC +CCTGGCCTACTGCCCATCCAGAAACGCTGGCTCCCAGGACGCCCAGGATCTGAGGCAGTA +GGGCAGCAGGCCTGGGCTATCGGGGCCAGCTGGGCATTCGCCTAAGGCTGTGACCCATCC +CCTCCCTAGGACAGAGCCTTCAGGGGTCCAGGGGAGAGGCAAGAAGGGTAGCACAGAAAC +TATCTCCCAAGTTAGGATCCCTCAGCTCCAGGATTCCCCCTGTAGGTGGACTGGCCCCAG +CTGGGAAGGACAAGAGCCCCAGCAGCTGGAGGGAGGGCCAGCTCTCTCTGCGGAATCCTG +AAGGTCTGCAGGAAGGAACACAAAGCCTCGGGGTTACCTTCCCAGGCCATCTGTTAGAGC +AGACACACGGCCCTGTTTACGGAACAGCCAACATGCCAACTGCTCTCCTTTCCTTCCCCT +CCCAGTCCCCGCCACAAAAAAGCCAGAAAGCCATGTCCCCAGACACTGAGGGCAGGCCCA +GGGCCCAGGCAGGTGCTAGCGGGCTGGAACAGCACTCAGATACTCCAGCCTCTCAAGCCA +CTGGTGGCACATGCCCAAGCTCTGTAGAACTGGGCCAGCCACAGCAGCCCCACCCCCGCT +CTGTTCGCCCTCAAAGAACTTACAGTAAGGCAGCTGCTCTGCAAGGCCCAGTCAGAGCCT +ACCCGGCCCAGCAAGTCCATTCTGTGGCAAGAAAAACCTTGGGGACACACATACCCAACT +GCTAAGTAAGATTATCTCTGGGGAGCGGGATTACAGAAAAACCATAGTATCTGTATATTA +TGTTCATTTCTGTAATACTCAACATTTTAAAAAGTATTACCTTTTTTTTTTTTTTTGATG +GAATCTCATTCTGTCCCCCAGGCTGGAGTGCCATGGCGATCTGGGCTCACTGCAAACTCT +GCCTCCCAGGTTCATGCCATTCTCCTGCCTCAGTCTCCCGAGTAGCTGGGACTACAGCCG +CCTGCCACCACGCCCGGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTTTCACCGTGTT +AGCCAGGATGGTCTCGACCTCCTGACCTTGTGATCCGCCTGCCTCAGCCTCCCAAAGTGC +TGGGATTACAGGTGTGAGCCACCGTGCCCAGCCAAAAGTATTACTTTTAAAACCCTAAAA +ATACAAAGGGCAGAAATGATGCAGAGACATGGATGAACCTCACAGTCGTGGCACTGAGTG +GAAGAAGACTTTTGCGAGAGTACAGACTGCATGACTCCATTTACATCAAGTTCTAGAATA +GGCAAAACGGACTGAGGGTAAAAACCAGAGCAGAACAGGCTGTGAGCGACAGGTGAGGAC +TGTCCAGGATGGGGCGAGGGACAAGCGCCCACTGCCTGGCCCTGACAGGCCTATCCAGGA +CGGGGCATGAGGAACTCTTTGGGGTGAGGGCAGCTCTCTAGCTTGCTGGGAATCTGGGTT +AAGGTAAATGAAAATACAATTTTAGGCCCTTAATTGTATGTAAACTTTACTTCCAATGAA +ACCTCCAGACAGAGGCTTTCACAGGACATTCTCATCTCAGAAGCTCAGCACGATACCCTG +GAAACACCACCAGCTAACCTTTCCTGGGCACTGTTGTATGCCCGACCATGTGCTATGTCA +CTGGAGCCGCAGGGCCACCCAGGAGCCTGTGCGTTCTGTCCATGTGATCAGGTGGGCTCC +TCTCAATCTTCACACAGCACAGCTGAGCCTCAAACCCAGCACTCACCCTGACCTCTCACC +TCCCCACAAGGTAGGAAAACCTGGGGCTGAAAGTGTGCAGGGACATGTCATCTTTAGCCT +TGGGCAAAGGCAACCTTTCCCACTGATGATTTCCAGATCACCCAGGGGTATTGGTTCTGC +CTCAATTTTCCAACTGGCACAGAGATCAAGGGCGACGGTGAAGCAGATTGGAAGGGCAAA +GACGCCACGGTGGGAACAGGTTCCTATCCCTCCCGGCTGCTCTCCAGCTGGGTGGCCCTC +AGTGCATCTCCAGAGGGCAGTCAAAAGCCCCAGGCCAAGACCACCCTGCACTCTGGATCC +CTCTACTCGCTCACCAAACACAGACCAGCCAAATAACCAACGGGGATGGCAGAGGCCAGG +GCACTGTGCACCCCTCGCTGCCTCCTGACACTCGAAGCAGCCCCCCATTGGGGGACCCAC +TAGCCCATGATCCTACGCGAGCGAGGTCAGGCCACACCTGCCCGTGTGTGGAGCCTCTGG +TCAGTCCACATGGCTGCAGGGGCCTGTGGGGAGGCTGGAACAGGGTTACCTCAAGGCCTT +TCTTCTAAGCACCCAGCAAAGGGCAGGAGAGTGTGCTCTAGTCAGCATCTTTCAAAGGCC +AGGAGAGAGGAGGTTTTCAGATCAAAGTGATCCCTGCTGAGGCAGAAAGCAGAAAACTCC +AGCCCCAATTCTGAGAGGCACTGCCCCAACCCAGCCTGGATACCCACCTTGCCTAGAACC +TTGGCCTCCAAGAAGCCAGGCATTCAGAACTGCTCCAGGTGCTGGGCCTCCACATGGCTC +CTTCTGGAGGCCATGACTCTGGGAGACAGGAACACATCTCACGCCCATATCCAGGCCCAC +AGGCGGGGGTCAAACTCAGGGTCAAACTCATCTCAGCCACATGATAACCCTGCCTTCAGA +CTGAAACTTCTGGCTCACGCCCAGCCAGGAGGGAGGCCTGGGGAGAAGGGTGAAGACCAG +GAAAGGGCGCCACCCCAAGCAGGCCATCCCGCCTAGCCCTCCTAGGATCCTTCTCATCCA +CCTTCCTCCCTGGAAGCTATCCTTTACTACCAAGAAAGGGGCTTCCTGCAGGAGGCCTGG +AGCTATGCTGGAGGACTGAGGAGAAGCTCCCCCCAGCCCACTCCCAAGGAGCAGCACCTT +AACCACCTCCCAGCCTAAACAAAAGTAACAGTGAAATGAGAACCCTCCAGCTAACGCCAA +GACAGCTGAGAGTGAGCAGGGCCGCCCACGGCCCGCCCGAGCTCCACTGTCAGGTGGGAG +GGACAAGCATGCCAGGCTGAGAAGCCATGCTAGGCAGGGCAGGGCCACCAGGCAACTTCC +ACAACCCAGAGGTCTAAGTACATCTGACCAGGGTCAGAGAGAGCCCCAGACTTGCTGCCA +CTGCTCCCAAACTTCAGTCTAAGGTCAGCATCGGCCCTGGTTCCAGACCAACCCCCAACT +ATAGTCACCTCATACTTCAGGTGTGGCCGGGACAGATGCAGCTGCAACGGGTGGCCCTGT +GTGAGCTCAGCCTCTTCCCAGGAGCCCCTAAGCCATGGGAGAGACTGCCTGGAAGGCACA +AGGCAGCCAGGCAGGAGGCAGCCAGTATCCAGAAGTGCCCCAAGGCCCAGCCCCTGGACA +CACCAACCAGCCCTGCACAGTCACAAGCCCAGGACTTTGTTCATCCTATCCCCATGGCCT +GGAGTCCTCCCTGAGGAAGCCTTGGTAGACAAGAGATAGCTCCAAGGGGCGAAGGCTGCA +CCTCGCCCACCGCCACAGCCCTGTATGAGATGGCAGCCTACATGTGGGCAGGTCTGATCT +CCTCAATCTTCCCACAGGCCCAGTGAGCGGGGCGTTATCTCTGCAGTTTCAGATAAGAAA +TTAAAGGTTCTTGGGGGTTAAGCAACTTGCCCAGGGTCACAAGAGCATGTAGGTAGCAGA +GTGAGGACCTAAAGCCTGACTCCAGTGTTGTAGTCTGATGACCCCCCCGCCCAACGCAGG +CAGGGCCAGGGATGCCACTCACACATGGCTTCCAACTGCCAAGCTGCTTGGGGGAGCTAG +AGGAGGCACCGCCCTCCATGCACTGGTGTGCCAGGAGCAGGGACTCCAGTCTGCACCTCC +ACCCTCACTCCCCCACCCCCCAGCACCACCTGCCTATCCACAGCAGGGCCCCACCTGGGT +GTATTCTCCCAAACTCACTGTGAGGGCATGGGGTCTGCCCAGCTCCTCCACCAGAAGTGA +CAAGGTGGAGCCCCCATGCAGCCTGCTTTGGAGGCCCAGGTTGTGCTTGCTGCTCCTCTG +GGAACACCCCCACCCTCCATGACCTCCTTCCCTGTCCCTTCAGGAATGGGCTGGTGGTGG +GTGGGGCTCACTGCTCTGGGCAAGCCCAGCCATGTAATCCAGCCCAGACCTGGATGCCGG +CCAGCAGCTCCTGGCTCTCCTCCCAGACCATCCTCCTGGAAAGCAACAGGCTCCACAAAT +GCCAGGAGCCCAGCTCTCTCCAACGCAGCTTCTACAAAATAAACACTCGGGTTCCACTCA +ACACATTGGTGATGCAGCGATTGGGACCTGAGGCTGGCCTCCTCCTCCTCTGCTCCTCAG +GCCAGCCCTGTGGCCTAAAGTGAGGGAGGTAGCATCCACCCCAGCCCAGTGACTTTCCCA +AGCCCATCCTGAAATGCCCATGGGACCTACTGATGACCTCGTACTGCCCACAGCAGGGCC +AAGCCCTGCATGGTCCGAGCCACCCGCCCATGGGTACTGTCCCTTCTGAGGTGAGGAAGC +CCGGGCTAACACCCCAGCACAAGGAAAAGGCTGGAATGGGCTGCTGAGAGGAGAGCTGGA +CCGAAAGTGCCTCCAAACTGTGCTTCCCCCAGAAGGTACAGCCTCAGTCCCCTCCCTCTC +CTCATCACTTCCGGGTTTGGAGCCAGCAAGGAATGAGGCCAGGAAGACCTTGGAGACCTG +CAGCTGATTTCCCCTGCTAGTGCTGGCACCAAGGAGGGCCCCAGGCCTGGCACAGTCTGG +CTGACAGTTCTGAGACAGGATATTGGAGACAGGCAGGGGAACATTGCTTTAACAAGCAGA +ATAACGGCCAGGTGCGGTCTGTAATCCCAGCACTCCGGGAGGCTGACATGGGTGGATCAT +GAGGTCAGGAGATCAAGACCATCCTGGCTAACACTGTGAAACCCCATCTCTACTAAAAAT +ACAAAAAATTAGCTGGGTGTGGTGGCACGCGCCTGTAGTTCCGCTACTCCGGAGGCTGAG +GCAGAATTGCTTGACCCTGGGAGGCGGAGCTTGCAGTGAGCCGAGATCGCGCCACTGCAC +TCCAGCCTGGGTGACAGAGTGAGACTCTGTCTCAAAAAAAAGAAGCAGAATAACAATTTA +AGGTTGTGATAGTGACTACGAATGCTGTGCTCACCTCCAAACTCCATCCCAACACTACCC +TGCCCCCTAAGAGGGGCCTGAGCATGGGGTAAAAGGCTCGCTGACAGCCACAGAGCAGGA +GCCCACGCAAGACCACCAGAGGATGTGCAGCTGCTGTTCCTAGTAGGTGAGGAAAAAGCA +GGAATCTGGCATCCACACATGTCAGGAGGCAAAACAGGCCCTGTGCTGGTTTCTGCAGTC +CTCTCCAGCCCACTTCCCTGCTCTTCTTGCTCACTGGCCATGACCCAAGAAACAGCAGCA +GCACCACCAGGGATCTTGTTAGACACGCAGAGGCTCAGACTCCATCCAGCCCTAACCACC +AGAACCCTGGGGGCTCAAACACACAGTCAAGTCTGAGAAGGGCTAGGTTAGAAGCTTTTT +TTCCTTCTTTTGTTTTTACCTGGACACCACTGATTGGAAAGCTCTCTACGGCCTGAAAGC +CAAGCGCTCCACAAGTAGTAAACGCTCAAGGGATGGGCATCAAGTGGAAGGAGAAAGCCC +CCAAAACGAAGATACATGTCCCATGTACACAAGCTCACAGGCTGGTGAATACAAACGGTA +GACCTAGAATGTGCCACACCAAGGCTGAGCGTGTTACCACAGGTACCAGAATGGTGACCA +CGCTGGAGGGTTCCACAAACCCTGATCAGAGAAGTAGGCGTGAGTGGCAGGCAGAGAACA +CAGCTCTGTGTGGCAGGGAGGGAGGACAAGCAGTGGCAGCACAGCAGACAACAGGTGGAA +ATTCTACATGAAAGGCACTAAATGGGCGAGGAAAGCCTGGGCCGCCCAGGTGGAAGGGAC +TATCGTGATCATCTCTCTCACCCTAGGGACACCTTAAAAGGAGGTAACTGAGCCCCAAAG +GGAGGCACCCAGCACAGCTGAGTCACAGAGCTGCAGCCATCCAACCCACAGCTCCAGGAG +GGACTCTCCAACTTCACAATTTCAAAATCAACCCTAGCAGCTAACAATTTCTTAATGCCA +AGTAAAGACTAGAATTAGAAACAAACAGAAACCCTATCATCTTCTACCATCATTACTTCA +CAAAAGAAAACATTTCAATGATCAAAGAGCAGGAAGAACTACTGGCAGTCCTGCACCTAT +GCAGTTCTCCAGGCCTGGCAAAGGCTCTGAGGCAACCAGCATGAAGGAGCCACTGCACCG +TCTGTACGCAACACCGCCTGACCCCCGGGCTGGGACAAGACTGAGATGACATGCTGAAAG +GGAATCAGAAAAAACAAAAACACAAAAATTCAACAACAGATACTAAAGACGGGATTTTGA +CTAGCCAAACAAAGACTAAAAGAGTATCTCCCAGGGATGAAAGGAAAATGGGGATGTTTT +TAAACAAGACCAGGACTGTTCCAGAAACAATAAGAACGTCAAAGCCCATCAGGAAAAAGG +TAACACCAAATGTTGGCCAGGCAGTAAGGCAACCAGAAGTCTCACATACTTTATAATTTT +TTATTTTTTTGAGAGAGAGTCTTGCTCTGTCACCCAAGCTGGAGTGCAGTGGCGAGATGG +CTCACTGCAACCTTCGCCTCCCAGGTTCAAGCAATTCTCCTGCCTCAGCCTCCCGAGTAG +CTGGGATTACAGAAGTGCAGTGCGCCACCACCCGCAGATAATTTTTGTATTTTTCGTAGA +GATGGGGTTTCACCATGTTGGCCAGGCTGGTCTCCAACTCCTGGCCTCAAGTGATCTGCC +CATCTCAGCCTCCCAAAGTACTGAGATTACAGGCATAAGCCACCGCACCTGGCCAGAAAA +CTCACATGGTTTAGAAAACCCTTGGATGGCACAATCTAAAACTGTGGGCCCAAGGCCGTG +GGTGGTGGCTCACGCCTGTGATCTCAGCACTTTGTGAGGCCAAGGTGGGTGGATCGCCTG +AGGTCAGGAGTTTGAGACCAGCCTGGCAAACATGGTGAAACCCCGTCTCTACTAAAAATA +CAAAAATTAGTTGGGCGTGGTGGCAGGCTCCTGTAATCCCAGCTATTTGGGAGGCTGACG +CAGGAGAATCACTTGAACCCAGGAGGCAGAGCTTGCAGTGAGCTGAGACTGCGCCACTGC +ACTCCAGCCTGGGCGACAAGAGCCAACTTCGTCTCTAAATAAATAAAGCAAACAAGCTAG +CTAGCTAGCTAGCTGTGGGCCCAAAAACTCACCCAAGGTATACGCCAACAAGAATGCACA +CGTATGCACACCAAACAGGCAGGCACACTCATGAAGGCCCAACAATGGAAAACAACTATG +CCCACCCTGAGAAGGGACAGCTGCAGGTATAAAAGACTATGAGCCAGCAGTGAACAGGAC +AGAACGTTTAGGTTGAACTGTATGAATTTACCTTTTAGGGGTAAAAAAACAGCTGGCTGC +TGATAATTTCACATGGTTTGACTTACAAACAACGCAGATGAATCTCTCAAATATACTTTT +GAGCAAAGATGCCAGAGCCAAAAAGACTATTACAGTTCCATTTGCATACATTCAAAAGCA +GGCAGCACTAATCTTATGGGTGGGGGTTGAGAGTGACTACAAGCTTCAGGATACGTGAGG +GGCTTCCAGGGTTGTGTTTCGCACTCTGGATGCTAGTTACAAGGGCATAATCATTTGTGA +AGAACTCTTGGAGCTGTGCACACTTCTTACGTAGGCTGTCCTTGAATTCAATACGTGCAC +AGAAACCTTCAGAAGGGAAGCAGAGATCAACTTCATCCTGATCAGCAAGTAGACTCAGTC +CAGGCAGCAACCTCTCCTGGACCCCCAACCAATAACAACAACACAGGAAGCAAAATATTG +GCAGGACAGCTGGCAACGCGGCAATGTCCAGGATGGAGTGCCCATCCTAGAGGAGGGAGC +TCACACAAGCCAGCCAGGAGCCCACAGGAAACAGAGAGACTACTGTAAATCCTTATTAAG +AGCAGACTCATGTCTGCTATCTAAAAGATAAAAACCTGATAATGTTTTTAAGTTGTCCTA +AGGTCCAATTGACTTTTTTTTTTTTTTTTTTTGAGACAGAGTTTTCCTCTTGTTGCCCAG +GCTAGAGTGCCATGGTGCAATCTCGGCTCACCGCAACCTCCGCCTCCCGGGTTCAAGCGA +CTGTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTCCAAGTGTGCACCACCATACCTGGCT +AATTTTGTATTTTTAGTAGAGACGGGGTTTCTCCATGTTGGTCAGGCTGGCCTGGAACTC +CCGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAAGTGCTGGGATTATAGGCGTGAG +CCACCACACCCAGCCCCAGTTGACACTTCTAAAGGAGAAGGGGTTCTGCAAATCCTGAAA +GGCAAGCCCAGGAGAAACAGGAAATCTGGGAGCACGGCAAGCAAGGTTCAAACAGGACAC +CAAATAATTCCCAGCAACCGCCTCCAGCAGGTCCTGGTGGCAGCCAGGTAGGGCAGGAGC +CAGCTGGGCATATCAAAGGGAGGAAGCCAAGAAGAAAATGGGCGAGACTCTCAGGGATTT +GGGGTCAAAGGAAGCCGCTGGGAGAAGGAAACAGCCCACTTGCTCCTTCATAGGTAATCA +ACACACAAACCCCCCAGTGCCTCAAATGGCTCAGGAGCTACAGCCAAAGATCAAGGATCA +AGTTATTTTACTCCAAGAAAGAAAAAAAAAAGAAAAAGTTATACATTCGGCATCCATTGG +AAGTTTTGTGATTGTTTGGAGACAGGGTCTTGCTCTGTGGCCCAGGCTGGAGTGCAGTGG +CGCGATCATAGCTCTAATTTATGGGCTCAAGGGATCCTCCCGTCTCAGCCTTTTGAGTAG +CTGGAACTAAAGGTGCATGCCACGATGCCCAACCAATTTTTAAAATTTTTTGTAGAGATG +AGGTCTCACTATGTTTTCCAGACTGGCCTCAAACTCCTGGGCTCAAGTGATCCTCCTGCC +TCAGCCTTCCAAAATGTTGGGATTACAGGTGTGAGCCACTGTGCCAGGCCTTAAAAAGCA +ATTTTTACAGATAAAATTGGGCAACTGCTATGGAAAATATTACAATCTATGGTCCTGTGC +CTGAAAAGCCTCCAAGTGTGATACTTTATAGAGAAGAGGTCTCTCCTGTCCAGTAGGTAA +CTTGAAAGTGTCTAAGAGACAAGTGCCCAAGAACTCAAAGAATGAGAGAGGGATCCATTC +AAACTCAGGGAGAAAAATGCTCACAAAGTTTCACTGTACTTCTAAACTGAGTCTCAGTGG +TGCATTAAGGAACTGGATTTAGAGACAGAAAACAAAATAAACTGGCACTTCTCTGCCTCA +AGAAGCATAGCTTGGGGGTGAAAAGTCAGCTACTTAGAAAGCAGCAAAAACAAAACCCAG +AAACCCACCCAAATGCTCACTGCCAGCAGGACAGGTGATTATGTGTGGATGGCGCCACCT +TGGACACTGAAATGGAGAATGGGAACGCAGGAACTGCTGCTCCTGGTGTCCCAAGAGTGC +AGGACACCCGGCTCCCAGCGAACTGAGCCAAAATCATTCGCAGTTTCAGGATCCAGACAA +AGGTGGGAAACCGACAAAAGCCAGCGAATGGCTGACCCGCAATTCAGAAGACTGTTGGCT +TCTAGAGGGAAGTGGGAATAAGCCAGGGAGAAGTGCATGGGGTGTCCCAGGAACTTGGGA +GGCTATTTCTTATGTGGCCATGAGGGAACAACGGTGTCACGCTTAGTGGGACACCCACGA +TTCAACCAATAGTGGGTTTACCACTACTTATCTATTCTTTAAGATTTGTGCACACACATA +TATACGTGTAATTTACCTTTGTTTTTTTTTTTTTTTGAGTATTCCTCTGTCGCCCAGGCT +GGAGTGCAGTGGCACAATCTCGGCTCACTGCGACCTCTGCTGCCCGGGTTCAAGCGATTG +TCCTGCCTCAGCCTCCCGAGTAGCTGGGGATTACAGGCACCCATCACCACACCCAGCTGA +TTTTTGTGGTAGAGACAGGGTTTCACCATCTTGGCCAGGCTGGTCTCAAACTCCTGACCT +CAAGTGATCCGCCTGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGGGTGAGCCACCACG +CCCGGCCTATTTACACCTTTGTAAATAACTTCTTAGAGTTCAATGGCTAAGTATACTAAG +GAAGCTGAGCCTGCTCTGTGCAGAAGTCTCAAAAGAAAGGAAAGTCGGGTGTGGTGGTTC +ATGCCTTTAATCTGAGCACTTTGGGAGATTGAGGCAGGAGGATCGCTTGAGCCCAGGAGT +TCAAGACCAGCCTGGGCAACAAGGCAAGACCCTGTCTCATTTATAAAACAAACAAACAAA +CAAACAAACAAAAAACAGAGAGAGAGAGAGAAAAGAAAGAGAAAAAAGAAAGAGGAAAGA +GACCTCCCTGGAAATCCCAATCCAGGGAGAAGCCAAGAGGCTAAAGCTGAGGTGCACTCA +CAGAGCACCTCCCTTTCACCACCCGAGAGATCACCTGGTCCACAGCCGTCAAACTCAGCA +AGGCCACACACTTGGGCAGCTATGACAACAATGCACAAATGAGGGCTTTGGAGGGCTCAG +TTCCCACAAGAGATAACCCAGAAAATATCACCCTGTCCTAATCATACAAAGCAAAAGAAC +CTGGGGCCTCCACACCTGGGGTAGCAGGTATGCTTCACTCAACAGAAGTTGTCCAGGAGG +GAGAAATCCCAGGCAACCTCCCAAGGTCTACAGGAGAAAGAAGGGCAGAATCAGAGCCAC +TCTAAGTGAAAATATCAGCGTTTAGAACACAATCACCCCCCTGCAACCCCTCCAGCCAAC +CCTCGCCTAGTCCCTGTACCCTCCAATTCAGAGTCCAATAACCCTGAGTTATCTTTCTCA +ACACCCATCTCATCAAGCCACTCCCCTGCTTAAAGCTTTCAATGGGCCGGGCATGGTGGC +TCACACCTTTAATCCCAGCACTTTGGGAGGCCCAGGCGGGCAGATCATCTGATGTCTGGA +GTTTGAGACCAGCCTGACCAACATGGAGAAACCCCATCTCTATTAAAAATACAAAATTAG +CTGGGCATGGTGGCGCATGCCTGTAATCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATC +ACTTGAACCCGGGAGGAGGAAGTTGCAGTGAGCCAAGATCGCGCCATTGCACTCCAGCCT +GGGCAACAAGAGTGAAACTCTATCTCAAAATACAAAAAAAAAAAATTAAAAAAATAAATA +AAGCTTTCAATAAATTCCTGATGCCTAGCATAAAGTCCATGCTCAGGCCTGGCATGCAAA +GCACTTCCCACAGGGGCATCAAGCCCACCTCATCCCTTCCACAGACACACCTGAGAGCTC +CTGCAGGCCGTGCCCTACTCTGGGAGGAGCCTGCCCCCTCACGACTCCCTCCTCTGTGAA +GCCAGAACTGCCTCTGTTGTCCCCCCGCTTCCAACGTCAGCACCAGCTGCCAAGCTGCTT +CCCTCCTGCCTACCCCCACCACCCCATAGACCAGTACCCAAAGTTAGACCCTGTGTCCCA +AGCAGCCACAGCAGCAGGCATGCAGCAGGCACTCATAAACATTCATTAGGTGAGCAAATG +CTGGTCAGACCCAATGCTGAGAAGAGACAGAGTGAAACAACATGTGAAAGATAAGGAGGC +ACGTGGGGAAGATGGAAATGTCCAGTACCCTCCTTGCCACTGGTTCTAAAATTGTGTTGT +TTACATTCTGAAATAGTCAGGGCTCCTAACGAGCATCTGCTTATGTGGCTTCTCTATTAC +TGTTTTGTGGGGTTTTTTCTGAGACAGGGTCCTGCTCTGTCACCCAAGCTGAAGTGCGGT +GGTACAATCATAGCTCACTGCAACCTCGAACTCCTGGCTTCAAGCCATCCTGCAGCCTCA +GCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCACTGCATCTGGGCTGTTGCTGTATTT +GATGTTACCATGTACTACAACAGTGCCCTCTTATTCAGTTTTTTTTTTTTTTTTTCCTGA +GACGGAGTCTCGCTCTGTGGCCCAGGCTGGAGTGCAGTGGCGTGATCTCGGCTCACTGCA +AGCTCCGCCTCCCGGGTTCACGCCATTCTCCTGCCTCGGCCTCCCGAGTATCTGGGACTA +CAAGCGCCCGCCACCGCGCCTGGCTAATTTCTTTTTGTATTTTTAGTAGAGACGGGGTTT +CACCGTGTTAGCCAGGATGGTCTCGATCTCCTGACCTCGTGATCTGCCGCCTCAGCCTCC +CAAAGTGCTGAGATTACAGGCGTGAGCCACCGTGCCCGGCCAAAAAAATTTTTTTTAAAG +GCTGAGCACAGTGGCTCACGCCTGTAGTCCCAGCACTTTGGGAGGCTGAGGTAGGTGGAT +CACTTGAGGTCTGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCATCTCTACTA +AAAATACAAAAAATTAGCCAAGCGTGGTGGCAGGTGCCTGTAATCCCAACTACTTGGGAG +GCTGAAGCAGGAGAATGGCTTTACCCCAGGGGAGGGTGTGGGGTGGAGGTTGCAGTGAGC +CAAGATTGTGCCATTGCATTCCAGCCTGGGCAACAAGAGCGAAACTCTGTCTTAAAAAAA +AAAATAGGCTGGACGCAGTGGCTCATGCCTGTAATCCTAGCACTTTGGGAGGCCGACGCG +GGTGGATCACCTGAGGTCAGGAGTTTGAGACCAGCCTGCCCAACAGGGTGAAATACAAAA +ATTAGCCAAATGTGTTGGTGCATGCCTGTAATCCCAGCTACTGGGGAGGCTGAGGCAGGA +GAATCACTTGAACCTGGGGGAAGCAGAGGTTGCAGTGAGCCAAGATCACGCCATTGCACT +CCAGCCTGGACAAGAGCAAAACTCCCTCTCAAAAAAAAAAAACAACAACATTTAAAAAAA +TACAAAAATTAGCTGGGCGTGGTGACAGGTGCCTGTAATCCCAGCTACTCAGGAGGCTGA +GGCAGCAGAATCCCTTGAACCCAGGAGACGGAGGTTGCAGTAAGGAGAGATTGTGCCACT +GCACTCCAGCCTGGGTGATAAGAGTGAGACTCTATCCGAAAAACAAAACAAAAAAAGGGC +TGGGCACGGTAGTTCACACTTGCAATCCCAGCACTCTGGGAGGCCGAGGCGGGCGGATCA +CGAGGTCAAGAGATCCACACCATCCTGGCCAACAGGTGAAACCCCATCTCTACTAAAAAA +TATATATATACATACAAAAATTAGCTAGGTGTGGTGGCGCGCACCTGTAGTCCCAGCTAG +CTAGAAGGCCGAGGCAGGCAAATCACTTGAACCCGGGAGGTGGGGGTTGCAGTGAGCAGA +GATCGCGCCACTGCACTCTAGCCTGGCGACAGAGCGAGACTGTCTCAAAAAAAAAAAAAA +GAAAAGAAAAGAAAAAAAGAAGGATAGCATTGCTTTACACTTTTATAAATCTCTTTAATG +TCTAGCCTAATAGAAGAAGCTGGATTCTCATATCTCCTGCATTCAGTCTGTTAGGATATG +CGGTTTTGATTAAAGTCTTTAAAGAAATTTGGCCTTACACAGAAAGAAGGAAGGAGTATT +TTAATAACTTTTTCAGAAAACTGTCTATTCTTCATTGATATTACACTAAAGCTCGACAAA +TGAGTTTCTTAAAAGTTGCTATGGGCCAGGCGCGGTGGCTCACGCCTGCAATCCCAGCAC +TTCGGGAGGCTGAGGCAGGTGGATCACTTGAGGTCAGGAGTTCAAGACCAGTCTCGCTAA +CGTGGTGAAATCCCGTCTCTACTAAAAATACAAAAATTAGCCAGGTGTGGTGGCAAGCGC +CTGTAATCCCAGCTACTCAGGAGGCTGAAGCAGGAGAATTGCGCAACTGCACTCCAGACT +AGCAACAGAGCAAGACTCCGCTTCAAGGAAAAACATAAATAAAAGTTGCTATGTAGGCCA +GGTACGGTGGCTCACATCTGTAATCCCAGCACTTTGGGAGGCTGAGGTGGGCGATCACAA +GGTCAGGAGTTTGAGACCAGCCTGACCAACATGGAGATACCCAGTCTCTACTAAAAATAC +AAAAATTAGCCGGGTGTGGTGGCACGTGCCTATAATCTCAGCTACTTGGGAGGCTGAGGC +AATAGAATTGCTTGAACCCGGGAAGCAGAGGTTGCAGTGACCCAAGATCGTGCCACTGTA +CTCCAGCCTGGGCAACAGAGACTCCATCTCAAAAAAAAAAAAAAAGTTGCTATGTAGGCT +GGGCACAGTGGCTCAACACCTGTAATCCCAACACTTTAGGAGGTCGTGGTAGGAGGACTG +CCTGAGCCTAGGAGTTCAAGACCAGGAAGATCCCATCTCTGGAAAAAAAAAAAAAAAACA +GCTGGGTGTGGTGGCACATGACTGTGGTCCTAACTACTCGGGAGGCTTATGAAGGAGGAT +CATTTGAGCCCAGAAGGTGAGGCTGCACTGAGCCGTGATTACATCATCACTGCACTCCAG +CCTAGGCAACTGAGGGAGACCACATCGTCAAAAAAAATTAAAAATAAAAAAAAAATTGTA +AAGCCTCATGCCGGGCATGGTGGCTAATACCTGTAATCCCAGCACTTCGGGAGGCCAGGG +CGGGTGGATCACCTGAGGTCAGGAGTTCAAGACCAGCCTGGCCAACATGGCGAAACCCAG +ACTTTATTAAAACTAGAAAAAATTACACCAGGCGCAGTGGCTAATGCCTGTAATCCCAGC +ACTTCGGGAGGCTGAGGCGGGCGGATCACGAGGTCAGAAGTTCGAGACCAGCCTGACCAA +CATGGTGAAACCCCATCTCTACTAAAAATGCAAAAATTAGCTGGGCATGGAGGCGCATGC +CTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCAGGAGGCGGA +GGTTGCAGTGAGCGAGATCGCACCACTGCACTCCAGCCTGGGCGACAGGGAAAGACTCCG +TCTCAAAAAAAAAAAAAAAGAAAAAATTAACCAGGCGTGGTGGCAGGCGCCTGTAATCCC +AGCTACTCGGGAGGCTGGGGTAGGAGAATCGCTTGAACCCAGGAGGCGGAGGTTGCAGTC +AGCGAGATCGCACCACTGCACTCCAGCCTGGGCGACAGGGCAAGACTCCGTCTCAAAAAA +AAAAAAAAAAAAGAAAAAAATTAACCAGGCGTGGTGGCGGGTGCCTGTAATCCCAGCTAC +TCGGGAGGCTGAGGCACGAGAATGACTTGAACCCAGGAGGTGGAGGTTGCAGTGAACTGA +GATTGCGCCACTGCACTCCAGCCTAGGCAACAGCGAGACTCCATCTCAAAAAAAAAAGCC +TCATGCATCCTTCCTATTTCATCACACAGAAAAGTAAAAATATGTGTAATTAAAGGTCTA +GATTTAATACTCAGTCATCTGTACTGCCTCCCCTGGACATGTGTAGAACTGGTGGGTCTC +AGCCCCCAGTGCTGGCTAACAGTGGGGAACACAACTCTGGCAGTGCAAGTGTCCACCCAG +GGCAGAGGCCAGTGATTTTTTTTTTTTTTTTTTTTTTTAGATGGAGTCTCGCTCTGTCAC +CCAGGCTGGAGTGCAGTGGCAAAATCTTGGCTCACTGCAACCTCCGCCTCCCAGGTTCAA +GCCATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGACTACAGGCGTGCGCCACCACACCC +AGCTAATTTTTGTATTTTTAGGAGAGGCGGGGTTTCACCATGTTGGCCAGGCTGATCTGG +AACTCCCAACCTCAGGTGATCCACCCGCCTTGGCCTCCTAAAGTGCTGGGATTACAGGCG +TGGGCCACCGCATCTGACCTTGTAACTTCTAAATATACTGAAAAAGGTATCGGGGACCCT +CAGGGTCTGCAAACAACTTTGAGAATAGCTGACAAGCACTGCCTCAAATATTTCTAACAA +CTCGTTTACAGGCAAGGAGAATGAGGCCTGGAGAGCTTAAGAGACTGGCCCACGGAGGAA +GCAGGAGTCATCTTTCCACAAAACTACACTTCCCCAAAAGCTGAACTCTTGGACAAGGAG +CCCACTGCCAAACCTAAGAGTAACAAATTTCAGCAAATAAAAGGAAGTGCCATTTCCAAT +GGCATCCTCGAATACTCTAAGAGGCGGGGCTGGCAGAATCCATCAACAGGCCTCCAGAGG +CCTGCTACTAAGAGCCAGCAACGCTGCTGAAAGCGGCACTGCCTCTGCAGGCTGTGTGAC +CAGGACCCGGCGGGGGCCCTGCACCTGGAAGCAGAGGGGGTCGGTGGGGGAGGGGTGCTA +CCAGGAAGCAAGATGTGCATGCTGCCTGCTGGGGGCATGAAGTCAAAGTCCCCTCCTGCC +CAAAGTGGCTAGGCCAGCCCTAGGCTGCCTTATCAGCATCAACACATGCCTGGAATGTGG +GACTTTGGCAACAACCCTCTCCCTTCGGCCAGCACGGGGCTGACGCCTGGTCCCTGGGCT +CTGGTTCACAGTCAGAGGACAACCACCTTGAAGCACCAGAACCCGCACCCCCAGCCCATC +TACCAGAAGACAATCTACCAAGAGTCACCGAGAGGAGCTATCCTGCCTGTGTCCCCACAC +CACCAAGGGCCGTGTCTGAGCACCTCGTTTGTCCACACTCAGAGAATCTCAAGAGCTCAG +CTCTGGTCCCTGCAATGTCCAGACCATCCCCCACATGGCTCTCCTGGAGGTGTTCGGCAA +AGGCACAGGCTGCCGTGGGGCAGAAGATTCCCACATACCAGACAGTAAGGAGCTGCGTGT +GACTGGAAGGATGAGGACGACCCAGAGAATGCTCTCTGGCCCCTGGTCCTTGGGGAGGAA +TGGGGGACCTGCAGGGGACCACCTTCCCACTCTGGGAGCCAGATTCCCTGGCTTTGTCCA +GAGCAGCCAACCCACTACCCCACTCAAAATGAACACCTCAGCTGCCCTCCAGCCCAAGCA +CTGCGCAGAGTAAGGAGTCCTCACTCACAAATGTGTCCGAGGCTTTCACACACTTCACCT +GGAGCTTCGCCACTCACTTCTTAGATGTACGACTCTGACTTCTCTGAGCCACTTGTACAA +CGAGGACTGACAAGATGATGAGGACCACACCGGTGTGTTCTGACAACTGAACCGGGCATA +GAATGCCCACTGCCAGGCTGAGCCCAGGAACGAGCCCAGGATGAGTGCTTACCCTCTTCA +CCACTACCTTCCTAGCCTTCTGTCAGAACTCCGTGGGGACCATCCTCTTCCCATCTTCTA +AGCCAAGTACCCTGGTACAAGCCAGACAGAAACTATAATAGCAGCTGCTTCCATAAAGGG +GAAGGGCCATGGGGTCCCGGACAGGGCTGGGGTGAAGGGGCACAAGACCTAGGGCAGGAA +TCCACCCCCAGATCACTCACTCAGGACAGGACCACCTGGACCCAGCTACCAAGATGTGCA +CCACCCCCTTCCTTCTGAGCCCCTTTTCCCATCTCCTCTACTGCCCCTGGCCAGGTTGCT +GTCCCACCTCTAAGAGGCAAGATTTCCTACCCAGGATGCTGACCAAAACCACACCCAGGG +GCCTACCCGTCCCCTCACATGATAGGCTGCTCCTAGCTGGCAGGAGCCGTCTTATAGCCT +CTCTCCCTCAAATACAAACAAAACCCCAGAACAACCTATTGTTCTGTTCCAGCAAAGGGG +GCCAGGCCCAGCCAGGCCCTACCTGAAGCTCTCTGTCTCCCGTCCCCCTTCAGTCCCCTC +CCACTCGTCCTTCTCTGCCCCTATTAGTGGCCTCATATACCTTGTCCAGATAACACAGCC +CAAGAAACCAACCTCAGGGACAAATCTCTTCTCTTCCAGGGAGAAGAAGACAGAGGTCCC +AGGAGTCCCAGGGGCCCCCATTACTGGCCACCTCCGCTCAACCCAAACTGCACTATGTGA +GGTCCCGCCAGACTACATACAGGCCAACGAGAGCCCAAGAATGCAGCCAGGAAACCAGGC +CAGGCAGACTCCAAAAGCCCGTGCTACGGGGTCAGTAGGACCCGCCTACAGCTGAGGGCT +ATAGGCAGCTCTCCAGAGGACCTCCCAGGAGAAGCCAACAGTGCACATGGGCTAGGTTCC +TCCTGCTGTTCACCCTCTGTGCCCAGTAACTACCCAGGAACAGGCATGACTGACTCTGCC +AACTCATTCACTGGGTAACCGCTGACCCCACCAGGCCCTCGGAGTAAAGCAGTTAGTGAG +AACCGCAGGTAAAAGCGCGGGCTACTCATCCCTCCGCCTGTGGATTCTATTATCAACAAA +GATGCATCACCTGCTAGAAGAGCGGTTCTCAAACTTGGCTGCACATCAGGTTCACTTCAA +AAGCTTCAGGAAAAGCTAGTGCCTTGGGCCCACCCCAGAGACAGGTATAGCTCAAGGTGA +GAACCAGAGCACCAGCAGGCAGGCCTCTGCCAGGCAGCATGGGCAACGTGTGCTGGGTGA +ATGTGCGGCCTGCACTCATCACCCAGAAGAGCCCCACTGTGTCCACACAAGGACAGGCCA +CCGAAGTCCCAGTCCCCACTCTCCCTTCTCACTTACTTTGTGAATGAGAGCTCACCAACA +GTTTACCGTCTTCCGAGTGCTGCGGCCTCACCGCCCGACCCGCAGCAGGGGTGAGGGCTT +GCAAAGGCCATGCAACAGATCCTCCCCCTCAAAGGGGCTCAGGCCTCAGTGTGGTAATGG +GAGCGGCCCCTTCCCACACTTGTCAGAGAACCCACCCACCCGGTGGAATGAAGCCGAAGC +CCAAGCCGCAGGGCAACAGCCCGGGACGGCAGGGGACAAGTCTGTACAGCAGCCACACCC +CTGCCAGAGCCAGGAGCTCTTCCATTTCCACAGCAGGCCAACTCTCACCTGGAAGCACCC +ACCTAACCAAACCCAATCCCTGCCTTCTTTTAGTCACACTGGGAACTGCCACAGGAAGGC +TGGGGACTCCACATACTCCCTCCTCACCACACCCCATGTGTGATCACCCTTAAACAGAAA +ACATGCACCTAAGATCCTACGATGCGCTGCCCACCTCACAAAAAACCGGTGCCTCTAGGT +AAGAGCACCTAGCTGACCCATCCCTGTTCCCTCTCACCATTAGAAGGACCCCCAAGTCCC +CCTGTTCTAACACCGAGGCTGCACTCCCACTCTCCACCCACTAACATTACCATAAAAAAT +AAATTGAATAGTTAGAAGGAGGGGCTCCCCAAAGCCTGGCCACCTTCCCGAGGGTCCCAA +GCAGTTTCTTGGAGTCCCTCTCCCCACTCAGTCCCGCCACACCCCTCTCAGGCAGTCTGG +CCCTTCCCTCCTGAACTTTGGCGGGCTGGAACCAGCTCCCAGCCTCTCCTCCCTTATCAA +GCTCACTGGGGGCCCACACAGAGCTCCCATCCCCACCAGCTTTTCTCGCTTTGCCACTCC +CAGCTAAAACTGGGCTCAAGGCAAGCAAGCCTGCAGTCCCTCAGTCCCTCGGGGCCCAGC +CCCTCCTCAGAGCCCTCCCCCAGCCCAGGTCCCTAACCCTTAGGGCAAGGCCCCTCCCAG +CAGGAAGCGAACCCTGGCGGTGCCAGGCAGAGTCAAACTGGAAGGGCTGGTTCAGAAGCC +CCTAAATGGGAGCCAGGACCTCTCTTAGGGAGGGGGCTTTCAGCCCCATCCTCCCTAGTG +CGATCTCAGATCTCTCCAGACACCACACTATATGGGCCTCCACAGGCGGTGGAGTCAAAG +GCATTTACCCTCCAGCCCCCAGCAAGCTACTTAACTTCCAAAAGCAGCTCCTTCCCTCCT +CCAGAGGAGAACGGGCCGCGTGCTGAACTGCAAGCGCCTCTATCACCCCGCCCAGGCAAG +TCTGTGAGCACCAGAAAGCAGGGGCCAACATGACTTGGTCTAAACCAAGGGGGCCAGGCA +CTGACTTTGCGCTCAGAAAATGTGGCGGAATGAATAAAAAGCTTGAAAAAGAGCCGCATA +CATGCCTGGCTGGCAGTGGGGTCTCCCAAGCGGGCTTCACAGCTCACACAGTACCCGTGG +GTCCGCGTCCTCAGTGCTCTCCAGCTGTCTCCACTGCCACCCTCTACCCTACCACTGCCT +TTTAAAACCCAGTAGCAGTCACTTCCTGGTTAAAACCCCTCCCCTCCAGGCCAACCCCAA +CCCACATGGCATCCAGGGTTCTCAGCCAGCCCACGGCCGGCTCCTCCCACGCCACCGCTA +TGCCCTCTGCGCTCCGCTAGATGCCAGCCCTTATCACCCCATCTTATAATCATTTGTTGA +GTGTCTGCCTTCCCTAGGCTGAGCTCCAGAAAACAGCGATACATGAATGTAAACTCCAGT +TCTGTTCCCATTGTAGAAACGAGGCAGGAGAGTCAATCACTGCTCAAGGTCATGACGGGA +GTAAATGGCAGAGCCAGCAATGCACTACAGACTTTGCGACCGACCAAGTCCAGTTCCCCT +CTCACTGCCCCACAGGGGTCCGTCCTAGGCCAGGCTCGGAGGAGACAAGAAGGGAGGAAC +CCAATGTGTTCTTTCTTCCCGCGGTGAAAGCTGCCTCCCAGGCCAGCAAGAGCAGCCCAG +AAGAAGTGCCCCACTCTCCCAGGGATCAGGTACTGGGGGCAGCGGGCAGGACAAGGTATG +GGGTGGGGCTGACTGCTCCAGGCCAACAGACCAAGCAATAAGGTTGGAACCACAAGTCCC +CTGGGTAAACTGAACTTTATTCCTTCCTCACGGCTCTCACTCTCCAGAACTGCCCCGCCA +GCTCTTCTCCAGGGGCTGGCTGCTGATTAAATGGCACTTCCCCACCCCTCAGATCTGACC +CCGCAAACAATAAGGACTTGAGGGGAGGCGGCAGGCTATCAGCTCAATAATGCAAAACCC +TGTTGCTCCTCGTCCACAACAGCTGACTTCAAGTGGATGGGAGGCTGCGCTTATTAACAA +AATGAGAAATCTGATCTACGGAAAGAAAACACTACGTGAGGATTAATCCGCGACTGCAGC +TTGTGGAGAAGGCTGGGCTGCTGGCCAAGACCAAGGATCGAGGATGGGATCGTGCCTACC +TGTCCCCAGAGCAGGTATCATGCAGCACAACAGGACTCATCACCCCTGCCCCACCTGCGC +CTTCTCTTCTCCTTCCAGCAACTTCGACAATCATTTCGGTTTTGCTTTAATTAAAGGCCT +GACTCCCTCGGGCTGCTTCTTCCTCTACACAGAGGCAGCAACCAGAGGGAGATTTTTCTT +TTCAGGAATCGGTCGTAAAAACTCAGTGACTAATCTACAAGTTCCAACAACTGGCAGAAA +AACACCGCAGGGAGAGGTTGCTGGGCACACAGCAGCACTCAGAGCCAACTGACCAGAGAA +GCTGGGCCACAGGCACTCTACTACAACCTCCCTCCCCCAGCCCGACACTGGCCTGCCGAC +CCACCTGAGAGCTCTGACCTCCCAAGGCAGGCAGCTGGGGAGCCTCTTCCCAGCCTTCCA +AGTCTACTGCTCGTCCTGTGGGACCCAGAGATCTTCACAGTCTCAATGGCACAAGACGGA +ACGTTCACTTCCAGGCAACAATCCTGGGCCACAGGACTCAGTTCAGCCCCCAAGTATCAG +ACTCCCGGCCCTGTTCTTGGTGTTCAGAGCCCACTAAACCAGCAGTCTTGCCACACAGCT +TTGTCTCCAGAGGCCAGCTCATCTGCTTTTTTTCACACTACTCCAGCAACCCTGCTCCAC +CAAGCACGCACACTCTCCTTGACACAGGGCTCCAGACCAACCACATGGCCTGTGCTCCTG +AAAATGCCTGCCTGAAGGCCCAGGGAGTCCAGACACTGGCAGATGAGAATGGACGAAAAG +AAGCCAAGCCAGAAGCCAGGAAGCAATAAATGCTAGACCCAGAAAGGCCTTAGGTTTGAG +TGACCCAGCTCCATCCCTCCATCCTGGATCCTTGGAGGACAGCCCCAAGTTCAGCCTAGG +AGCTCCCAAGGCCCCTCCACTACCTGCCAGCTCTCCGACAGCACAAGAGACACAGCAATC +CCACATCAGTCAACAACCCACCGCCACAGGATTCCTAGGGGCAAGGCTCTGCCCCTCCCC +CCAGCACATATGTCAGAGGGGTGGCTTCCCTGGGTTACACCCCTCCTGCTGTTGGGGGAG +TGGGGGGTCGGGGAACACAGCTTTCCAGATGTGCTTGGCAACTCCTACTAGAAAAGACTA +GGGGTGCGGGGGACAGGAGAAGACATGGATAAATAACTTTAACACCGCTCCAACCCATCC +GGCTCAGCACTGGGCTCCCTTACACAGGCAGTCCCAGGCAGTTCTGGGTGGGGCCGTTGG +GAGCATTATCTGGCCTCATTCCCTCCTCTCAGCAAGTCACTGCCCCCCAGGGAGAGGCAT +TCCCCCCCCCCCCCAACCACGCACACACCCAGGCCTGTGTGAATATGAACCATCTTGGAA +GATAAACAGAGAGTGACAAGCTGGGGCCCCTCAGCCCCCTCCCTCAGCCAGCCGGTCCCT +TCCCCCTGAAAGCCGACCCCCTCCCCCAAGCCCATCTCTCTTCCTGCCAAGCGGCTGCCT +ACAGGAGAGGTCTGGGGGCAGGGCAGCGAGCCCACCAGCCGCAGAGCCCGGCCCTCTGGG +AGCGGCCCCTCCAGGCCCGCCCCTGCCCCTGCCGTGGCCAGTCTTCCCGCGGGGAGGAGG +CAAGAGGAGAGGAGACCGCAGACGGTGCAGGACCGCAGTCCTGGAAATCGCAAAATCCTC +TAGCGAGGGGGCGGCCGCGGGCGCAGGGCCGTTTGCATAATGGGAGCCCTCCCGCCTGTC +AGGCAGCGCAGCTCGCCCGACGCTGTTCGGATTAGATTGCTAATGAAAAGGCACAAAGAG +CCGGCGCCCGCTCGCCCGCCGACCCCCGCTCCGCAGACCCGCGCCGCCTGGGCCTGGCGC +GGCCCGGTGGGCTTTGTGCCCCGGGTGCCCCACCGCCCGCGCCCCTCCGGGCATCTGGCC +CACAAAGCCCGGGCCTGCCAGGGGTCCCGCGTGCGCCCCAGCCCAGGCCCGCCAGACGCT +AGCGCGTCCCCCACGCGCGCAGTCCCACGTCGCCCGGGCGCGCGCGCGTCCACGCCCCTC +TCCCCGGGGACGCGCCCAGCCCGCGGCCCCGGCCCCCGCCCGCTCCCCGCGACCCCCGCC +CCCCAAGGCCGCCCCTCACCTCGTGTGCGTCGGCGGCGGCGCTCCGCCCGCCGGCCGGCC +GGCCCTACCAGCGGCCCTTGTCCTCAGCGCCCGGCTCGCGCCGCACGCGCCCGCCCCGTC +CGCCTGCCGCCAGCCCGGCTCGGCTCCCCGCCTAGCGCGCCCCGAGCGCCGCTCACAGCC +GCCCGCCCAGCGCCATCTTGGAAGCTTGTGACGTCGGCGCCGCCCGCTCACCCCTGACCC +ACATCTGAATGGGCGAGCGGCGGGGCGGGGACAGGGGGCAGCTGGGGGCGTGGCCTGTGA +ACAGGGGCGGGGCCTCGGGGGCGGGGCCGGGCCGGACAGCGGTCCCAGCACTAGGCGGGC +GGGCTGCCGGGGTCCGGCGCCGTGGGGAAGGGGTGCGCGGGAGGAGACGGGGACCCAGAC +CCCGGACATCTAACCGGACTCCGACCTCAAGCGCCAGGGCAGGACCGCGACCTCGCCCCT +GAAATACCCGAACCGCATACCGGCCCCCGGGACAGGGACCCTGGCCCCCCCCGACAGGCT +GACGCCCACCCCCTCAAACTCTGGTGGACTTACCCCCTTTTAGCCCTACCCTGACCCCTA +GGAGCCCCGAATTAGGGACCTCTATCGGCCTACGCGCCCCCTCCCCGACCCCTTTGCGAC +CCCTGCTCGACGCTCCCTGCGGTTGCCCGAGGCTCAAAGGCGCAGCCAGCAGTGACTGCA +AGCTCGGGGGTCTGGGCTCCTGGGGAAGCCCGGGCTGGTTGGGTGCAAAAGAGAAGGGGC +GCCCCTCCCGTGACCCCAGCGCCCCTCGGGCCCCCGCGGGCGCACCCCCGCGAACCCTAC +CTGCTCCGAGGGCGCGGAGGACCCAGCACGCTGCGCTCAGCCAGCCCCTTCCGGTGGCCG +CAGCCCCTCGCAGGCCCCAGGGGTCAAGCGCCTGCCCGAGCCGGCCCACCAGGACCCGGG +CTCCCGGCCGCCATGCAGATAGCCTTCCCAGGGGCTGGGCTGGCCTGAGCCGCCACTGCT +TCTCTAGGGAGCTAGTTAATGGACCTCTCTCTACTTTGAACACCAAACAAAGGAACACAC +CGCTATCGAGGTCGCCCAAGTCCAAGAGGAGCCCAGGTCTGCCTTACAGGGAAGTTGTGC +CCCAGCTCCAGTCAAGATCAAAAACCAGTTTCAATAACCCTTCGCCAAGCTGATGATGCA +ACCTTTCTTTCCTAATGGATGTATAGGTTTAATGTCATCCTAACAACATTTCTTAGACTT +CACAAAATTCTAAGTTCACCTGGAAAAATAAATAGCCGAAAACAGCTATGGTTTTCCCCC +CTTGGGAACAAAAGCAGGCATGAGGGTAGACTTGCCCTAACAGATATCAAAACAAATTGT +AAAGCTACCGCAGGCATTTCAGTGTGGTACAGAACAGGAAATAGAATAGAAAGCCTAGAA +ACATCCTAGAAATGGTAAGAACACAATAGATGAAAAAGGAAATATCAAACATCTGTGGAA +AAAAAAGAGCTATCAAACATCCCTGAAGAAGAACAAGAATATTCCACAAATAGAGCCTAG +CAGAGGACTCACTATTTGAAGGAACGACTGAAAAAAAAAGTCAACCATTCTACTAACCCA +AGACATATAAATTAAAACTATAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACT +TTGGGAGGCCAAGGCGGGCGGATCACGAGGTCAGGAGATCGAGACCATCCTGGCTAACAC +GGTGACACCCCGTCTGTACTAAAAATACAAAAAATTAGCCAGGCGAGGTGGCGGGCGCTT +GTAGTCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCCGGGGGGCGGAG +CCTGCAGTGAGCCGAGATCGTGCCACTGCACTCCAACCTGCGCGACAGCGAGACTCCGTC +TCAAAAAAATAAATAAATAAATAAAATAAAACTATAAGAAGCTGGGTTTTCTCCTAAACA +AATTAAAAATCAGTTTCAAGTGATAACCTTCAAACACAAGGTCTGATAGGTAATCACTCT +CATATACTTTTGGAAGCACATAAATCACCTCAAAATTCCTGGACATGAGTTTGGCGGTAT +GAGCCAAAAGTTGTTTTTTTGGGGTTCTTTTGTCTTTTTTTGTTTTTTGGAGACTCGGAG +TCTCACTCTGTTGCCCAGGCTGGAGTGTAGCCTCAAACTCCTGGGATCAAGTGATCCTCC +TGCCTTCCAAAGTGCTGGGATTACAGGCATAAGCCAACGCACCTGGCCCCAAAAATATTT +TAAAATAATTATACCCTCTCAGACCAGTATTCCAGGATTCTGTTCTGGGGAAATTAGCCA +CGTTTGCAGACCACGTACTTATTATCTGTCTCTCTACCCATAAGTAAGTTTGTACCTGTA +AGTTTGGAACCCATGCCTAGGAGCACACCTGAGACAACAGGCATTCCACGGTCCCTTGTT +TCATCTGCATTTGAAAACTAATGTGGCTGGCTCATGCCTGTAATCCCAACACTTTGGGAG +GCCAAGGCCGGCAGATCGCCTGAGGTCAGGACTTTGAGACCACCCTGGCCAACATGGTGA +AACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGATATCGCGGTGCATGCCTGTAGTC +CCAATTACTCGGGAGGCTGAGACAGGAGAATTGCTTGAATCTGGGAGGCTGAGGTTGCAG +TGAGCTGAGATCATGCCATGACACTCCAGCCTGGGCAACAGAGGGAGACTCGGTCTCAAA +AAACAACAAAAAAGATAACTAATATATGATAATATTTTTTAAGTGTCATGTATAATAGTG +AAAGAAAGCATATACAGGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCTGAG +GCGGGAGGATCACCTGAGGTCAGGAGTTTGAGACCAGCCTGGCCAACATGGTAAAACCCC +GTTTCTACTGAAAATACAAAATTAGCTGGGCATGGTGGCGTATGCCTGTAATCCCAGCTA +CTTGGGAGGCTGAGGCAGGAGAATTGCTTGAACTCCAGAGGCGGAGGTTGCAGTGAGCTG +AGATCCTGCCATTGCACTCCAGCCTGGGCAACAGAGCAAGACTCCGTATCAAAAAAAAAA +AAGAAAAAAGCATATACAAATTTCTCACAATGGGGTTAAATAGTCCACATAATGGAATGT +AGATTAGGCCAGGAGTAGTGGCTCATGCCTGTAATCCCAACACTTTGGGAGGCCGAGGCG +GGCAGATCACCTGAGGTCGGGAGTTCGAGACCAGCCTGACCATTATGGTGAAACCCCGTC +CCTACTAAAAATACGAAAAGTTAGCTGGGCGTGATTGCGCATGCCTGTAATCCCAGCTAC +TCGGGAGGCTGAGGTAGGAGACTTGCTTGAACCCGGGAGGCGGAGATTGCGGTGAGCTGA +GATCGCACCATTGCACTCCAGCCTGGGCAACAAAAGTGAAACTCCGTCTCAAAAAAAAAA +TTAGCCAAGCATGGTGTCACATGCCTGTAGTCCCAGCCACTCAGCAGGCTGAGGCGCAGC +ACGAGAGTTGCTTGAACCTGGGAGGCAGAGGTTGCAGTGAGCCGAGGTGGTGCCACTGCA +CTCCAGCCTGGGCGACAGAGTGGGACTCCATTTTAAAAAAATAAATAGGCCAGGCGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCCAGGCAGGTGGATCACGAGGTGAGG +AGTTCAACACCAGCCTGGCCAAGATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATT +AGCCAGGCATGGTGACGGGCACCTGTAATCCCAGCTATTCGGGAGGCTGAGGCAGAGAAT +CGCTTGAACTCAGGAGGCGGAGGTTGCAGTGAGCCCAGATCACACCACTGCACTCCAGTC +TGGGCGACAGAGTGAGACTCGGTCTCAGAAAATAAATAAATTAATAAATAAATAAATTAA +ATTAGTAGGATGGGCACGGTGGCTCACTCCTGTAATCCCAGCACTTTGGGAGGCCGAGGC +GGGTAGATCACCCAAGGTCAGAAGTTTGAGACCAGCCTGGCCAACATGGTAAAAGCCCGT +CTCTACTAAAAATACAAGATTAGCCAGGCATGGTGACGTATGCCTGTAATCCCAGCTACT +TGGGAGGCTGAGGCAGGAGAATTGCTTGAGCTCCAGAGGCGGAGGTTGCAGTGAGCTGAG +ATCCTGCCATTGCACTCCAGCCTGGGTGACAAGAGTGAAACTCCGTCTCCAATAATAATA +ATAATAATAATAATAAAGTAAATTTTTAATTAAAAAATAAAATTTTTATTTATTTATTTA +TTGAGACAGAGTCTCACTCTGTCATCCAGGCTGGAGTGCAGTGGCATCATCTCAGCTTGC +TGCAACCTCTGCCTCCCAGGTTCAAGCAATTCTCTGCCTCAGCCTCCTGAGTAGCTGGGA +TTACAGGCGCCCACCACCACACCCAGCTAATTTTTGTATTTCTAGTACAGACGGGGTTTC +ACCATCTTGGCAAGGCTGGTCTGGACCTCTTGACCTCATGATCTACCCGCGTTGGCCTCC +CAAAGTGCTGGGATTACAGGCGTGAGCCACTGCGCCCAGCCAAAAATAATTTAAAAAAAA +AAAAAAAAGAAGAGGCCAGGTGCAGTGGCTCACGCCTGTAATCCCAGCACTTTGGAAGAC +TGAGGCAGGAGGATCACTTGAGGTCAGGAGTTCGATACCAGCCTGGCCAACATGGTGAAA +CCCCATCTCTACTAAAAATACACACAAAAATATTAGCCAGGCATGGTGGCACACCCCTGT +AGTCCCAGCTACTCGGGGGACTGAGGCAGGAGGATCACTTGAACCCAGGAGGTGGACGTT +TCAGTGAACCAAAATCACACCACTGCACACTCCAGCCTGGTCAACAGAGCTAGACCCTGT +CTTAAAAAAAATTGTATTTTTTGTACAAAAAAATTAGCCGGGCCTGGTGGCAGATGCCTG +TAGTCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATGGCGTGAAAACCTGGGAGGCGGAG +CTTGCAGTGAGCCAAGATTACGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGATTCCG +CCTCAAAAAAAAATTTTTTTTTAATTGCATTTTTTAAATGCATGCAAAAATATTGATATA +TGGAAAAGCAACTGAAGAAAATAAATCAAAAATATTTACGGAGGTTCTCTCTGGAAGTTG +GGAATTTTTTTTCTACACATGTATACTTTAGCGTGTGTGTTATTTTTATTTTATGAAAGT +AACATTTCTAATCGGAACAATTCTAGAGATGCTGAAGCACATTTTATTTTTATTTTATTA +TTTATTTTTGAGACAGAGTCTAGCTCTGTTGCCCAGGCTGGAGCACAGTGGCGTGATTAT +GGCCCACTGCAGCCTCCACTTCCTAGGCTCAAGTGATTCTCCCAGCTGGGACTACAGGCA +TGCACCACCACACCCGGCTAATTTTTTATTTTCTGTAGAGACAGGGTCTCACTATGCTTC +CCAGGCTGAACTCAAACTCCCAGACTCAAGCAATTCTCCCACCTCAGCCTCCCAAAGTGC +TGGGATTACAAGCATGAGACACCATGCCCGGTAATTTTTTTTTTTTTTTTGTGCAGATGG +AGTCTCGCGCTGTCACCCAGGCTGGAGTGCAGAGGCGCGATCTCCGTTCATTGCAACCTC +CGACTCCCGGGTTCAAGCGATTCTCCTGCCTCGGCCTCCCAAGTAGCTGGGATTACAAGT +GAGCACCGCCACACCAAGCTAATTTTTGTAGTTTTAGTAGAGATGGGGTTTCACCATGTT +GCCAGGGTTGTCTCGATCTATTGACCTCGTGATCTGCCCACCTCGGCCTCCCAAAGTGCT +GGGATTACCGGCGTGGGCCACCGTGCCCAGCCCATGCCCAGCAATTTTTTAAAGTTAAAT +TCTCCCTCCTCCTCCACCCTAATCAGTCCTTTCTGAAGTAACATTAACAGTTTAACTCTC +TTCTCTGACATCAATATGTATCTACTCACCTTACAAAAAAGATCCTACTATTTTGAAATC +ATAGACATTTTTCTAGTTCATTTCCATAATTCATTCTTTTTTTTTTTTTTCATGTCAGAC +GGGTAATGTGCCTATGTCGTAACAAGATTTGAAGGTGGCGGCCGGGCGCGGTGGCTCACG +CCTGTAATCGCAGCACTTTGGGAGGCCAAGGCGGGCGGATCACGAGTTCAGGAGATTGAG +ACCATCCTGGCTAACACAGCGAAACCCCATCTCTACTGAAAATACAAAAAAATTAGCCGG +GCGTGGTGGCGGGTGCCTGTAGTCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATGGCAT +GAACCCGGGAGGCGGAGCTTGCAGTGAGCCAAGATCGCGCCACTGCACTCCAGCCTGGGT +GACGGAGCAAGACTCCCTCTTAAAAAAAAAAAAAAAAATATTTGAAGGTGGCACATCTTA +CATGGGAACGTGTGTGAACACATAATCATCATGCTTATGAACTACAAAAGGATCATAATT +CATTCTTTAAGAGCTGACAAATGTTCCAGAGTATGGAGCTTCTGTAATTTATTCACACTT +CGTTAACCATGGTTGTTCAGTTTATTTACAGTGTGGTGCTTTTTGTTTTCTTTTTTCTTT +GTTCTTTTTTTTTTTTTTTTTTTTTGAGATGGAGTCTTGCTCCTGTCACCCAGGCTAGAG +CGCAATGGCACAATCTTTGCTCACTGCAACCTCCACCTCCCGGGTTCAAGCAATTCTCCT +GCCTCGGCCTCCTAAGTAGCTGGGATTACAGGTATCTGCCACCATGCCTGGCTAATTTTT +GTATTTTTCGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTTGAACTCCTGACC +TCAAGTGATCCACCCGCCTCAGCCTCCCTAAATGCTGGGATTACAGGTGTGAGCCACCGC +ACCCAGCCTACACTGTGGTGCTATTAAAAAATATTTTTAGGCTGGGCACAGTGGCTCACA +CCTCTAATCCCAGCACTTTGGGAGGCCGAGGCAGGTGGATCACTTGAGGCCAGGAGTTTG +AGACCAGCCTGGTGATCATGAAGAAACCCTGTCTCTACTAAAATATTAGCCAGGCATGGT +GTCACATACGGATAATCCCAGCTACTCGGGAGTCTGAGGTGGGAGAATCACTTGAACTAG +GGAGGCAGACGTTGCAGTGAGTTGAGATCATGCCACTGCACCCCAGGCTGGACAACAGAG +CGAGACCTCGTCTTAAAGTAATTAATTAATTAATTAATTAATTAATTAATATAAATAAAA +TAGCAGATTTCAAAAATTTGTTCTCCCTGGCAGCAACCCAGTAAAGCTAGATCTGGGCGG +AAGGTAATATGGAAATATAAAAACTACAGATTAGCAGGGATGGGAAGACCCGCCAGAAAT +GGGTTCATTTTGTGTCCTCACTCCCTCCGGATTCTCTGTGTGTCTAGTCCAAGATCTAAC +CACTATGATCTGCTTTCCTCATCCATTTGGGAATCAGGGCACCACCCCCTTGGGAGGCTT +GAATGACATGAGGTTGAGCAGGCAGAGCACGGAACTCAGGCTCTGGTGAGCCCTGGTACA +GTGACTATGATTGTTGTGTCATGTAGGAAGGGTCTGTTATTTTACCATTATCTGTTTTCA +ATAAAAAACAGAAAGAAAACAAATATACAAAATACCCCCAAACAGTAAATTTCAGCTTCT +TACTATGACAGCTAGATTTAGCATTTAACAGTATGCCCAAATTTGAATTTCGGATAAACA +ACCAATAATGCTTAATATAAGTATGTCCCGGCCGGGCGCGGTGGCTCACGCCTGTAATCC +CAGCCCTTTGGGAGGCCGAGGCGGGCGGATCACGAGGTCAGGAGATCAAGACCATCCTGG +CTAACACGGTGAAACCCCGTCTCTACTAAAAATACAAAAAATTAGCCGGGCGCGGTGGCG +GGCGCCTGTAGTCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCCAGGA +GGCGGAGCCTGCAGTGAGCTGAGATCGTGCCACTGCACTCCAGCCTGGGTGACAGCGAGA +CTCCGTCTCAAAAAAAAAAAAAAAAGTATGTCCCATACAATATCACTTCTCACCTTCCCA +TATCCCAAGCTCAAGACACCTTATATACGCCATGATTTCTCCTGCCATCTCTGGGCATTC +ACACCAGGGCTCCTCCTGTCCAGGCCAGCCTTCTCCCTTCTCCCACCTGTGCCTGGTGAA +CAACTCAGTTCAGACATCATCTCTTGTAGGAAGTCTCCTGTGATCCCAGGCTAATCACCC +TGATACAGTCCTGAAATACTGCTGAGCAGTTGGCATGAGGGCAGGAAGGCTTGGTCTTGT +TCACTCTTGTATCCAGCTTATACATGGCACAAAGTAGGTTCTCAATTAAAAGTCAAATGA +GGGGCCAGGTGCAGTGGCTCACGCCTGTAATCCCAGCACTTTAGGAGGCCAAGGCGGGTA +GATCACCTGAGGTTGGGAGTTCGAGACCAGCCTGGCCAGCATGGTGAAACCCCATCTCTA +CTAAAAGTACAAAAATTAGCCAGACGTGGTGGCAGGCACCTGTAATTCCAGCTACTCGGG +AAGCTGAGGCAGGAGAATCACTTGAACCCGGGAGGGAGAGGTTGCAGTGAGCCAAGATTG +CGCCATTGCACTCCAGCCTGGGCAACAGAGCAAGACTCCATCTCAAAAAAAAAAAAAAAG +TCAAATGAAGTCGGGCACAGTGGTTCGCGCCTGTAATCCCAGCACTTTGGGAGACTGAGG +CAGGAGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAGCATATGAAATCCTGT +CTCCACTAAAAATACAAAAAAAAAAAAAAAAAAAATAGCTGGGTGTGGTAATGCACGCCT +GTAATCCCAGCTATTTGGGAAGCCGAGGCAGGAGAATTGCTTGAACCCGGGACACAGAGG +TAACAGTGAGGTGAGATCATGCAACTGCACTCCAGCCTGGGCTACAGAGCAAGACTCTGT +CTCAAAAAAAAAAAAAAAAAGTCAAATGAGACCACTCATGGTAGCTGGCGCCTATAATCC +CAGCACTCTGGGAAGCCAAGGCGGGAGGATTGCTTGAGTCCAGGAGTTTGATACCAGCCT +GGGCAAAACAGTGACATCTCATCTCTACAAAAAATTTTTAAAATTAGCCGGGCATGGTGG +CACTCGTCTATAGTACTAGCTACTTGGGAGGCTGAGGTGGGAGGATTGCTTGAGCCCAAG +AATTCGAGGTTGCAGTGAGCTATACTTGCGCCATTGTACTATAGCTGGGCAACAGCCAGA +CGCGGCCTCAAAAAAAAAAAAATTTTAGCCGGGCTTGGTGGCATGTACCTATAGTCCCAG +CTACTCAGAAGCTAAGACAGGAGGATCATTTGAGCCCAGGAATTTGACGCTGCAGTAAGC +CAAGGTCACACCACTGCACTCCCGCCTGGGAGACTGAGTGAGACCCTGAGTCTAAAACAA +ATAATAATAAAAACGAAAATGAAAGTCAAATGAATGAGGCCAGGGGTGGTGGCTCATGCC +TGTAATCCTAGCACTTTGGAAGGCTGAGGTGGGTGGGTCAGCTGAGCCCTGGAGTTACAG +ACCAGCCTGGGCAACATGGCGAAACCCTGTCTCTACAAATACAAAAAAGAAAAAAGCCAG +GCCCATGGTGGTGAGTGCTTGAAGTCCCAGCTACTCAGGAGGGTGAGGTGGGAGAATAGC +TTGAGCTCAGGAGGTCAAGGCTGCAGTGAGCTGAGATTGCATCACTGCAGCCTAGCCATG +ATGACAGGGCAAGACCCAGTAGAAAACCAAGGTTAGAGAGGTTAAGTCACCTGCCCAAGG +TCCGTAGCTAACCTCAGACTCCAGCCCCTCAGACTGACATGAGCTCAGTTCACCCTCTTA +GGAACACCATCTGAAGAATGCATCCCCAGCAAGCCTATTCCCTATAGCAAAGGCCAGGCC +TGTGATGGGTGCCCCGCTCCTCACCACACACCTCCCTGTCAAGTCACCACTCCTTCACCC +CTAGCAGAGCCAGGCACCTTGAGCCCAAGGGAGGCCACTCATGGAACTGTCATTCAACCA +ACAGATGCTGACAGCAATGATGAGGTGGGCACTGGGCTAGTGAACAGCACAGATGTGTTC +CCTGGCCTCAGAAGCCCACAGACTAAGGAGAAGACGACAGAATACTCACAAGGGTGCTGG +GGCTGGGCAAAAAGGTGCAGGCTGCTTTGTCTGGTCATAAGAGGGGAACTGACTTCCCTG +GTCTGAGGAGCCAAGGAAGGGGCCGTGCCCTTGCCATGCCCTCTGCCTGCCATGCCTTGC +TGTTCTTCAGTGCCTGCTCTAAGGTCACTCCTAGTGTGGTTTTCTCTGGCTGCTCTTTTT +TTTTTTTTTTTTTTTTGAGACAGAGTCTCGCTTTGTCACCCAGGCTGGAGTGCAGTGGCA +CCATCTTGGCTCACAGCAACCTCCGCCTCCTGAGTTCAAGTAATTCTCCTGTCTCAGCCT +CCTGAGTAGCTGGGACTACAGGTGTGCACCACTACGCCCAGCTAATTTGTGTATTTTTAG +TAGAGACGGGGTTTCACCATATTGGTTGGCCAGGATGGTCTCAATCTCTTGACCTCCAGA +TCAACTCCCCTTGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCC +ACTTTTTTTTTGGAGTCTCGCTCTGTCCCCCAGGCTGGAGTGCAGTGGCGCGATTTCGGC +TGACTGCCAGCTCCGCCTCCCGGGTTCACGCCATTCTCCCACCTCAGCCTCCCGAGTAGC +TGGGACTACAGGCGCCCGCCACCACGCCTGGCTAATTTTTTGTATTTTTAGTAGAGACGG +GGTTTCACCCTGTTAGCCAGGATGGTCTTGATCTCCTGACCTTGTGATCCGCCCGCCTCG +GCCTTCCAAAGTGCTGGGATTACAGGCTTGAGCCACCACGCCTGGCCTCTTTTTCTTTTT +TGTTGAGACAGATTCTCACTCTGTCGCCCCCAGGCTGGAGTGCAATGGCGCAATCTTGGC +TCATTGCAACCTTGGCCTCCTGGGTTCAAGCAATTCTCTGCCTCAAGCCTCCCGAGTAGC +TGAGATTACAGGCGCCCACCACCACACCCGGCTCATTTTTGTGTTTTTAGTAGAGACAGG +GTTTCACCATCTTGGCCAGACTGGTCTTAAACTCCTGACTTCGTGATCTACCAGCCTCGG +CCTCCCAAAGCGCTGGGATTACAGGCTTGAGCCACCGCACCTGGCCATGCTCTTTCTTTT +TTATTTGTATTTTTATCTGTTTCTTAGAGACAGGGTCTCACTCTGTCATCCAGGCTGGAG +TGCAGTAGTGTAATCATAACCCACTGCAGCCTCAAACTCATGGGCTCAAGGGATCCTCCT +GCCTCAGTCTCCCAAGCAGCTGGGACTACAGGTGTGCACCACTATGCCCAGCTATTTTTT +TTTTTTTTGAGACAGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGTGCCATCTCG +GCTCACTGCAACCTCTGCCTCCTGGGTTCAAGTGATTCTCTGCCTCAACCTCCTCAGTAG +CTGGATTACAGGTACCTACCACCATGCCAAGCTAATTTTTGTATTTTTTTTTTTTTTTGA +GATGGAGTCTTGCTCTGTCACCCAGGCTGGAGTGCAGTGGCGCAATCTCGGCTCACTGCA +AGCTCCACCTCTCAGGTTCACGCCATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGACTA +CAGGTGTCCGCCACCATGCCCGGCTAATATTTTGTATTTTTAGTAGAGACGGGGTTTCAC +CGTGTTAGCCAGGATGGTCTCAATCTCCTGACCTCGTGATCCGCTGGCCTCGGCCTCCCA +AAGTGCTGAGATTACAGGCGTGAGCCACCGTGCTCGGCCTAATTTTTGTATTTTCAGTAG +AGACACGGTTTCACCATCTTGGCCAGGCCGGTCCTGAACTCTTGACCTCATGATCCACCG +GCCTCGGCCTCCCAAAGTGTTGGGGTTATAGACGTGAGCCACCGTGTCTGGCCTGGCTCC +ACTTTCTTAGGGAGCTTTGCTTGCCCTCTGCTTGGGGTAGTTTGTGAATTCAGTGCTCTC +TCTCTCCCAGGTCCTGGGTCTCCTGCTCCTGATCAATCTGCCACGTGCCATTTGATCTCA +GAGTTGTCTCCACCATTAGACTGGCAGGGTCTGTCTTCTGGGGTCTGTGTGTAGGATACA +GTGGCCCCAGGATGGGTAAAGGAGGGGACCCAGTTGTTCTTCTGTGATAGGTGGAGACAA +GGGCCAGCAGGGCTGTTTCTCGGTGAAACCCATGGGGAGATAGTCGAACCAGGAACCAAA +TCCGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTAGGAGGCCGAGGTGGGC +GGATCACCTGAGTTCGGGAGTTGGAGACCAGCCTGACCAATATGGTGAAACCCCATCTCT +ACTAAAAAAAAATATATACATATATATACAAAATTAGCCTGGCGTGGTGGCACATGCCTG +TAATCCCAGCTACTCGGGAGGCTGAGGCAAGAGAATCACTTGAAACTGGGAGGCAGAGGT +TGCGGTGAGCCAAGATCGCACCATTACACTCCAGCCTGGGTGACAGAGACTCAGTCTCCA +AAAAAAAAAGTCCAAAAATTAAAAAAAAAAAAAATGCCGAACTCAGTGGCTCACGCCTAT +GATCCTACCACTTTCAGAGGCCGAGGCGGGCACGGTGGCGCGTACCTGTAATCCCAGCTA +CTCCGGAGGCTGAGGCAGAAGAATCACTTGAACCCGGGAGGCAGAGGTTGCAGTGCGCTG +AGATCGTGCCACTACACTCCAGTGTGGTGACAGAGCGAGACTTGGTCTCAAAAAAAAAAA +AAAGTCCTGGCTGTGCCACTAGGCCAGACGCCCTAGAACTGACTTCTATGGACCTCAGTT +TTCATACCTGTGAAATGGAACTCAGAGCCATATCTACTTCATTGGGTTGTGTGAATGTGA +GGTAGTTACAGGATGGAGCAGGCAGAAGGTCAGCACAGCCTCAGTGGTTGGAGGAGTGGG +GGTCAAGTGGACAGAGAGGGTACCCCAGGGCCAGAGGTAGAGGCAAGGTGAAGCAATGCT +TCATTTCCCTGCTGAGGTTCCTCTCTAGCAGTTTGGAGGTGGGGCAGGAGTGGAGAAAAC +ACATCCCCTCCTCAATATGGGCTGAGGAACAGGGTTCTTGAGGCACCAAGAACCTCTTTG +GGGCTCTGGCTTGCCTCCTGTAGTGAAAGGGATGGGCTGTGTGCAATGAACTCACACCTG +TAATCCCAACACTTTGGGAGACAGAGTCAGGAGGTCCAGAACAGCCTAGGCAACATAGCA +AGACCTTGTTTCTACAAAAAACTTTTTAAAAAATTAGCCAGGCGTGGTGGTGGCACCTGT +AGTCCCAGCTACTTGGGAGGCTGAGGTGGGAGGATTGCTTGAGCCTGGAGAGGTTGAGGC +TGAAGTGAGCTATGATAGCACCACTGTACTCCAACCTGGGCAACAGAGTGAAACCCTGTG +TCTAAAATAAAAAGAGGGCCTGGCGTGGTGGCTCACGCCTGTAATCCCAGCACTTTAGGA +GGCCGAGGCAGGCAGATCACTCGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACTCTGTCTCTACAGAAGTACAAAAATTAGTCGGGCGTGGTGGCAGGCGCCTGTAATC +CCAGCTGCTTGGGAGGCTGACCTGGGAGAATCTCTCGAACCTGGGAGGCAGAGGTTGCAG +TGAGCTGAGATCACACCATTGCACTGCAGCCTGGGCAACAAGAGCGAAACTCCGTCTCAA +AAAAAAAAACAAACAAATAATAAAATAATAATAATAATAATAATAATAATAATAATAATA +ATAAAGAGGGTGGGAGTGGACCAAGGCCTAATGGCATGGAATTTGCAAACTTTATCTTCC +TAGTTTTCTCTGGGGAGCCTTCCTCCATCACCAGGGCCCAGCAGGGCCTCAGATGGCGGG +GGGTGGGGCGGGGGCTACACATATCCCTCATGGCCAAGATGCTAGGAAGCCCCTGAGCTG +GGGCAACAGCCTCTGGTCACAGTCATGAGGGAGGCTGGGTGCAGTAGCGCTTATCTTGCC +TGACCTTGTGGAGACTGACCACTCCCTCCTTCTGGAAAACGTTGCCCCCTGCCCTCTCCA +AGGCCTCCTCCTTCTTACATCCCCTGGTCCTGGCTAGGGCCTCAGCACCCAATTCTACTC +CTTGACCCACCACCCTGTGGTGCTTTTGCCGGGCCCCAGCCCACAGCCATCTGCCAAACA +CCTCCCCCTGGAGTCCCTGCGGCGTCTCTGACTCAGCAGGTCTGTGCCTGCCCCTGCTGT +TCCCCCCACCCAGTGGCTCTGCAGAGCACCCTGTTGCCCAAGCCCTGAGTACTGGCCACT +CCCAGGGCCTCGCCTTCCCCCACCACCAGCACCACCAATTTGAATTCCTATCTCTCCCTC +TGGCCTCCTCCCTAGACCCAGGCCCTGCCCCAGGGTGGGGGAAGGAATCCTACAGATAAG +GGCATTGGTCAAAGGGACACACCTGGGTTCGGGCCCCCAGCTCTGCCCCCAACCTGCTAA +ATGACCACACCCCTCTCCAAATCTGAGTTATTCCCTATGTAAAAGGGGGAAATAATTAAA +CTAGCTGGGTATGCTGTGCTGAGCAATATGTGAGCTCAGGAAAGGTCAGTTTTCCAGGGG +AAGTATGGCCGCTGAGAGCCTCAGTCTAGTGCTTCTCATTCACGAGCTGGTTGGTGCCTT +TCCTAAGTTGGAAATGGGTTAGTCCACAAATCCCGTTGCCTGGTCCATGCCAGGTCCAGG +TACCTGCATTCAGGGTGCAGGGTGGAGTAAGACAGTCTGAAGGGTGAGGTAGCAGGATGA +ATGAGTAATTCCTGGGTGCGTTTTGGGATTATGCCTAAGGGCTGTCCGAGCACGTGGGAG +GGGTAGCTAAATCCTGTAAGGGAGGGGAGAATGGGGAAGGCTGCCTGCAAGAGGTGGTGG +AGGGTGCTTTCAAAGGATACCTGGGAGTGAGCTGGCTGTAGGCACAGGGCAGCTGGAAGG +CCAATTTTAGGGAAGAGGAAATTGAGGCTGAAAGTCAAAAAACAAAGGAACTGCCTGAGG +TCTCTCAACTGAGAAGTGAGTGGGCCAGGGTTCACATTCAGCCCCCACTCCATTCTCAGG +CTGGGCAGGAAGGTACTTTGCCCTCAGGAGGGCACCTTCGACCCAAAGCACCCTGACCAA +GAGGCTGTGCACCGTGGCAACCCTAAGACTGAGGCCCAGGTCCTGGAGTTCCACCAAGGT +AGGTACAACCAGCCAGGCCGTCAGTGACAGGAGGATTTACTGGGGCTTCTAGGGACCCCG +TGAAAGGGCAAAAAGACGGCACAGAAGCCTGTGGATATCAGATATAGATAGTGAGGGCTA +GGGCTTTATGGGGAGGGTGGATGGGCCCTGTGGGCGGGGGATGTTTAGGAGATCTTCCAA +ACAGAGCATTCCAGCCTGGGGGAACAACCCATTATAGACCCCACCCAGCACCGAAGACAG +GGACAGGTGGGGCTGAGCCTGGAGGCTGGCAGGACCTGTGCGGCCGGCTGCGGTGTCAGC +AATGCCACCGTGTGTGGAACCCTCTGTGCCTAGGTTCCTGGAGCCAGCTCCACCTGGCAA +TGTGCTTTGTTTCACAAGACTAGAGTTGGCCCATCTTGTTCCGCCTCAGATGGAACACCT +GACCTCCTGCACACCCCACCCAGCCTCCAAATTCAACCACCCCAGTAGTGAGACAGGGAG +AGTAGGGTGTGACCAGAAGGTGGAATGAGCTTAAAATAGGCTGCAGAGATATCTCTGAGC +TTTTAAAAAGTCGTATCTTTCATATCGTGTTCTTGTGAAATCTTCTCCAGATTTTTTACA +ATGACTCTGAAATTGATCAGTTAGCCTCATGCTTTCAAAATCCATAGCCGCAGTGAGCGA +GAGGGGGCAGGTCAGCTAGAGGTGGAGGGGGCAGATGGGCCAGAGGCGCCTGGGCAGGGG +TGGATGGGGCCTGGACAGGCTTAGTGACCCTTGCACCAGAACTCTCCGGACACCGCCCCT +TCGCCCACTCGTTAGGCTCCTCTGCCTTCGGGCCGGCTGGGCTGCCCATCCCCCCTCGTT +CCCCTCCTGGGCAGGTCTGGACTGGACAGGTTTTGGGCCTCCAGGTCGTGCAGTCAGTCA +GGGAAGGGGCCTGGTGCAGGCCACAGCCAGGCATCCACCTCCTTCCCAGCCCACCCCTAC +CCCCCAGCAGCCTGCCAACTTGCTAGACCTGTGCGGCCTTCCCTTCTGCTGAAAGTCTCC +AGATTCTCAGGGCTCTGCACGGGGAGCCAAGCTGGGGCTTAGAACTGTGCTCCCTTGCCC +CCACCCCCGACCTGTGCCCTCATCAGCTTTCTTTTTTTTTCTTTTTTCTTTTTTTTTTTG +AGACACAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGTGCGATCTCAGCTCACTGC +AACCTCTGCTTCCCGGGTTCAAGCAATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGAGT +ATAGGTGCGTGCCACCACACCCCGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTTTCA +CCGTGTTGGCCAGGATGGTCTCCATCTCCTGACTTGGTGATCCACCCGCCTCGGCCTCCC +AAAGTGCCGGGATTACAGGCGTGAGCCACCGCGCCCGGCCTATTTTAAATTTTTTTTGTA +GAGACAGAGTCTCACCATGTTGCCTAGGCTTGTCTCGAACTCCTGGTCGCAAGTGATCCT +CCCCTCTCTGCCTCCGCCGTAGCTGGGATTGCAGGCACAAGCCATGACGCCCCCCTTCTC +ATCAGCTGTCTGGGTCTTTCTCGGGGTCCTGACACCAGGCCAAGTGTTCTGCACACCTGA +CCTGCTCAAAACAAAACCAGTTCTGCCACAGTCTGGGAAAATGAGGCTCAGAGAGGCCTT +GCAGCTGTCTGTGAGCAGGCTGGCATTTGGATCCAGTGACTGGGTTCTGGAGCCCAGTGG +CTCTGTGGCCCTGCCTCTCCAGCCTTATGCTTCTTTAAAACTGCCCATGGCCTCTGAAGT +TGAGGATTTAGGGGAGCAGGGCTGCCAGAGGGGTGAAGAAGGAGATCTTTCTGTGGGTGG +GTGTCAGAATGACCAGGCCTGACACTGGTCCCTGCTCCCCTGGAAGGACAGCCCCTCTCG +GTTATGTGGGGGGTGGGCTGCCTAGGGTGCTCTGGGGAGAAGGGAGGGAGAGAATGGGGC +TGGTCGGGTGGGGTGTGGATTCCAGGCCTGCTTGGTCAAAAAGATACAGTATTTCCTATT +CCCCCTTACACTGGGCAGGCAGGTGTGGCCCAGGCAGCTCTGCCAGGTGTGCAGCCCCTG +GAGAATGACCCTAAAGTGCACCTAGGCTGCCCCCTGGCGGCAGCATGAGGTCCTCCTCCC +TGGACTTGTAACCCTCCCAGGGGGAGGAGGTCCACACCAGCTGATGGGTTGGCACCTGTC +CCCAGTCCCTTTCTTCTTTCCTGTGCCACTGCTCCCAGAGTTGCCCAAAACACACGATCA +GGTGCAGTGGCTTGAACGAAACCCTGTCTCTACGGAAAATACAAAAATTAGCCAGGCATG +TTGGCTCATGCCTACAGTCCCAGCTACTTGGGAGGTTTAGGTGGGAGGATCGACAGCCCA +GGAAGTCAAGGCCGCAGTGAGCAGTGAGCTGTGGTTGCGCCACTGTACTCCATACTGTAG +CCTGGGTGACAGAGTGAGACCTTGTCTTTTTTTTTTTTTTTTTTTTGAGACGGAGTCTCA +CTGTGTCATCCAGGCTGGAGTGCAGTGGCGCGATCGGCTCACTGCAAGCTCCGCCTCCCG +GATTCATGCTATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGACTATAGGCGCCCCTCAG +CCTCCTGAGTAGCTGGGACTACAGGCGCCCGCTACCACGCCTGGCTAATTTTTTTGTATT +TTTAGTAGAGACGGGGTTTCACTGTGTTAGCCAGGATGGTCTCGATCTGCTGACCTCGTG +ATCCACCCGCCTCGGCTTCCCAAAGTGCTAGGATTACAGGCGTGAGCCACTGAGCCTGGC +CGAGACCTTGTCTTAATTAAAAAAAAAAAAAAAAAGATAAAAACCTAGGTAACATGCTGG +GGGGTGATGAGGGTTATGGAGGAAAATAAAACAGGTGGGGGCTGGAGTGAAGAGTGGGGG +TGCCCCTCATAACTCTGACAAAGACTACAACGCAGCTGTCAGAAAAAAAGCTGATTTGAG +GCAATGGTCAGGGAAAGTTGTGAAATTAAGTAAAAAGTGATGGAACAGGCTAGGTGGGAA +GTGGTGGCTCACACCAATAATCCAAGTGCTTTGAAAGGCCAAGCAGGAGGATCTCTTGAG +GCCAGGTGTTTGAGATCAGCCTGGGCAACATAGCAAGACCCTGTCTTTACAAAAAATGTA +AAAATTAGCTGGAGGCTAGGCTCAGTGGCTCATGCCTGTAGGGAGGCCAAGGTAGGTGAA +TTGCTTGAGCCCAGGAATTTGAGACCAGCTTGGGCAACATGGCAAAATTCCATCTGTACA +AAAAAATTGCCAGGCATGGTGGCTCATGCCTGTAATCCTAACACTTAGGGAGGCCAAAGT +GGGCAGATTACCCGAGGTCAGGAGTTTGAGACCACCCTGGCCAACATGGTGAAACCTCGT +CTCTACTAAAAATACAAAAATTAGCTGGGCGTGGTGGCGCATGCCTGTAATCCCAGCTAC +TCGGGAGGCTGAAGCAAGAGAATTGCTTGAGCCTGGGAGACAGAGGTTGCAGTGAGCCTA +GATCGTGCTACTGCACTCCAGCCTGTGTGACAGAGCAAGACTATGTTTCAAAAAAAAAAG +AAAAATTAGCTAGGTGTGGTGACATGCACCTGTAGTCCCAGTTACTCAGGAGGCTGAGGT +GAGAGGATCACTTGAGCCCAGGAAGTTGAGGCTATGATCGTGCTACTGCATTCCAGCCTG +GGTGACAGCCAGATTCTGTCTCAAAAATCAAAACACAACAGGGCACAGTGGCTCACTTTG +GCCTTCCAAAGTGCTGGGATTACAGGTCTGCACCACCATGCCTGGCCTGAGAGTGCATGA +ATTAAAGTTTCTATTCTCTTGCTAGTCTGTCATTGCTTCCCTAGTGTGTGGGAACCATAC +TTGTCCCCACTTCTCAGTCAGAGAGCAGCCTGCCAACCTCCAAGTCTCTTGCCCCTGACC +CAAAAGGTCCCAGGCTGTCCTCTCGGCAGAAGCAGCTGTCTTGTGGCTTACTGTGCTCAG +ACTCCATTTCTAGGCTGTGGGCTCATCAGGGATCTAGTGCTTTGAAAAAGTGTAAAGGAG +AGCAGCAGTATTATTCACAATAGCTAAAAGGTAGAAACGACCAAAGTATCCATTGACAGA +TGAATGGATAAACAAAATGCATTACATACACACAATGGACTATTATTCAGCCTTAAAAAG +GAAGGAGGCCAGGTGTGGTGGCTCACACCTATAATCCCAGCGCTTTGGGAGACTGAGGCA +GGCGAATCACTTGAAGCCAGGAGTTGGAAACCAGCACAGACAGCATGGGGAAACCCCCTC +TCTACTGAAAATACAAAAGTTAGCCAGGTGTGGTGGCACATGCCTATAATCCCAGCTACT +CTGGAGGCCAAGGCATGAGAATCGCTTGAACCTAGGAGGTGGAGGTTGCAGTGAGCCAAG +ATCATGCCACTGCACTCCAGCCCGGGTGACAGAGTGAGACACTGTCTCAAACAAACAAAC +AAAAAAAAAGAAACGTGTGGTGGAAGAAGGGAAGAAAATTGGCCAGGCACACTCTGGTAG +GGGATGGTTGGATGATGAAATACAGACAATAGAAAAACCTAGATAAAGACCTGGCGTAAT +GGCTCATGCTTGTAATCCCAGCACTTTGGGAGGCTGAGGCGGAAGGATCTCTTGAGGCCA +GGAGTTTGAGACCATCCTGGTAAATATAGTGAGACCCCAGTCTCTTAAAAAATAATAATT +GGCTAGGCGCGATGGCTCACGCCTATAATCCCAGCACTTTGGGAGGCCAAGGCGGGCGGA +TCACCTGAGGTCGGGAGTTCGATACCAGTCTGGCCAACATGGAGAAACCCCATCTCTGCT +AAAAATACAAAATTAGCTGGGCGCGGTGGTGTGTGCCTGTAATCCCAGCTACTCGGGAGG +CTAAGGCAGGAGAATCGCTTGAACCTGCAAGGTGAGGTTGCAGTAAGCTGAGATTGTGCC +GTTGCACTCCAGCCCAGGCAACAAGAGTGAAACTCCATCTCCAAAAAATAAAAATAAAAA +TAAAAATAAAAAAGAAATAGGCCGGGTGCAGTGGCTCACGCCTATAATCCTAGCACTTTG +GGAGGCCAAGGTGGGGGCGGGGTGGATCACTTGAGGTCAGAAGTTCGAGACCAGCCTGGC +CAACATGGTGAAACCCAATCTCCACTAAAAACACAAAAAATTAGCCGAGCATGGTGGTGG +GCACCTGTAATCCCAGCTACTCGAGAGGCTGAGGCAGGAGAATGGCTTGAACCTGGGAGG +CGGAGGTTGCAGTGAGCCAAGATCACCCCACTGTACTCCAGCCTGGGTGACAGAGTGAAA +CTGTCTCAAAAAATAAATAAATAAATAAATAAAACTTTTAAAAAGTAAGAAGAAGAAGAA +AAAAAATATATGGAAATTAAAAAACAAGAAAAAAATAATAGGCCAGGTGCAGTGGCTCAT +GCCTGTAATCCCAGCACTTTGAGAGGCCGAGGTGGGCGGATCATGATGTCAGGAGTTCAA +GACCAGCCTGGCCAACATAGTGAGACCTCGTCGCTACTAAAAATAGAAAAAAATTAGCCA +GGCGTGGTGGCGGGCACCTGTAATCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATCACT +TGAACCCATGAGGCGGAGGTTGCAGTGAGCCGAGATTACGCCATTGCACTCCAGCCCGGG +TGACAGTGCGAGACTCCATCAAAAAAAAAAATAAATAAAATAAATAAATATTAATAATAA +TTTTAAACAATTAAAAAATATGGGATTTTTTTGAGACAGAGTCTCACTCTGTCGCCCAGG +CTGGAGTGCAGTGGCATGATGTCAGCTCACTGCAACCTCCGCCTCCTGGGTTCAAGTGAT +TCTTCTGCCTCAGCCTCCCAAGTAGCTGGGACTACAGGCACGCGCCACCACGCCCAGCTA +ATTTTTGTATTTTTAGTAGAGACAGGGTTTCACCATATTGGCCAAGCTGGTCTGGAACTC +CTAACCTTGTGATCCACCCGCCTCGGCCTCCCAAAGTGCTGGAACTATAGGTGTGAGCCA +CTGCACCCGGCCAAAAAATATGTTTTTTAAAATAATAGAGATGAGGCCGGGTGTGGTGGC +TCACACCTGTAATCTCAGCACTTTGGGAGGCCAAGGTGGGTGGATCACTTGAGGTCAGGA +GTTCGAGACCAGTCTGGGCAACATGGTGAAACCCTGCCTCTACTAAAAATACAAACCTGA +GCTGGGCATGGTGACGCATGCCTCTAGTTCCAGCTACTCGAGAGGCTGAAGCAAGAGAAT +CGCTTGAACCCGGGAGGCGGAGACTGCAGTGAGCCAAGATAGCACCACTGCACTCCAGCC +TGGGAGACAGAGCAAGACCCTGTCTCAAAAAATAAAATAAATAAAATAAAATAAAATAAA +ATAAAATAAAATAAAATAAAATAAAATAAAATAAAAAATAAAATAAAATAAAATAAAATA +AAATAAATAAAATAGATGAAGGCCAGGTGCAGTGGCTCACGCCTGTAATCCCAACACTTT +GGGAGGCCAAGGCAGGCAGATCACCTGAGTTCAGGAGTTAGAGAGCATCCTGGCCAACAT +GGTGAAACCCTGTCTGTACTAAAAATACAAAAAAATTAGCCAGGCATTGTGGCGGGCGGC +CAATAATCCTGGCTACTTGGGAGGCTGAGGCAGGAGAATCACTTGAACCTGGGAGGCGGA +GGTTGCAGTGAGCCAAGATGGTACTACTGCACTCCAGCCTGGGTGACAGAGCAAGACTCT +GTCTCAAAATAATAATAATAGGCCGGGCACGGTGGCTCACACCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGCAGATCACAAGGTCAGGAGATCGAGACCATACTGGCTAACATGG +TGAAACCCTGTCTCTACTAAAAATACAAAAAATTAGCCGGGTGTGCTGGTGGGCGCCTGT +AGTCCCAGCTACTTGGGAGGCTGAGGCAGGACAATGGCGTGAACCCGGTAGGCGGAGCTT +GCAGTGAGCCAAGATCGTGCCATTGCACTCCAGCCTGGGCGACAGAGCGAAACTCCACCT +CAAAAAATAATAATAAAATAAAATAAAAATAAAAATAATAATAATAGAGATGAGGTTTTG +CCATGTTACCCATGCTGGTCTCCAACTCCTTGGCTCAAGTGATCCATCCACCTTGGCCTT +CCAAAGTGCTGGAACTACAGGCTTGTGCCACCACCCTGGCCTTAAACAATTATTCATGAA +AGGAAGGAAATTCTGACACATGCTGCAACATGGATGAAGCTCAAGGACATTATGCTAAGG +GAAGGAAGCCAAAGACCTGCCAGCCGAGGTCCCAGTCCGTCAAGGGCTCCAGTGAGCGAG +CAGGATTGAGCAGGTCCCTGGGCTGAGCAGTGGGAACTCTGCTTTGCTGTGAGTGTGGCA +CGGGTGGCGGCAGACTGTGGAGTGCAGGCTCTGTGGAGCAACTGGACACTCTGTTGAACG +AAGTGCAAGGTGGTAGGTTTTTGCTTTTTTTTTTTTTTCTGAGACAGAGTCTCACTCTGT +CTCCTAGGCTGGAGTGCAGTGGCATGATCTCGACTCATTGCAACCTCTGCCTCCCGGGTT +CAAGCAATTCTCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCGCGAGCCACCACAC +CCAGATAATTTTTAAAATATTTTTGGAAGAGACGGGGTTTTACCATCTTGGCCAGGCTGG +TCTCGAACTCCTGACCTCGTGATCCACCTGCTTCAGCCTCCCAAAGTGCTGGGATTACAG +GCATGAGCCACCGCGCCCGGCCACAAGGTGGTAGTCTTTCTCAAGGACGCTGGGGCAACC +CCATTGCGTCTTCACCAACACCCTGGTACAGATCCTGCAGCTGCAGTCTACCCCGCATAC +AACATGTTCAATGATCCCTAGCTAGACAAGGCATTGAAAACTATTCCATAGGCCGGGTGC +AGTGGCTCCTACCTGAAATCCCAGCAGTTTTGGAGCAAGGCGGGTAGATCATCTGAGGTC +AGGAGTTCGAGACCAGTCTGGCCAACATAGCGAAACACCGTCTCTTCTAAAATACAAAAA +ATTAGCTGGGTATGGTGGTGCATGCCTGTAATCCCAGCTACTTGGGAGGCTGAGACATGA +GAATCACTTGCACCAGGAGGCGGAGGTTGCAATGAGCCGAGATCACACTACTGTACTCCA +GCTTGGGTGACAGAGTGAGACTCTGTCTCAAAAAAAAAGAAAAAAAAAATTAGCTGGGCA +TGGTGGCATGCACCTGCAGGCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATCGCTTGAA +CCCAGGAGGCTGCAGTGAGCCAAGATCGAACCACTGCACCACAGCCTGAGTGACAGAGTG +AGACTCCATCTCAAAACAACAACAACAACAAAAATCAACTATTCCTTGGGAGGCAGAGGC +AGGAGGATGGCTTCAGGCCAGGAGTTGGAGCCAAGCTAGGCAACATAGCGAGAATTCCTC +ATCTCTACACACACACACACACACACACACACACACACACACACATTAATTAGCTGGGTG +TGGTGGCACATGCCTCCAGATACTCAGGAGGCTGAGCGGGAAGGATGGTTTGAGCCCTGG +AGGTTGAGGCTGCAGTGAGCCATGATCACGCCATGACAGAATGAGGACCAGGTGGAAGAA +CTGAAAACGCTGGGGATCCACACATCCGCTCCATCCTTTCAGATGGAAAGAAATACCAAG +ACTCAAAAAAATGAGGGTGCCCAGGTCCTCACTGAGCAGAGACTCACTGCTAAAAAAAAG +CCTTACCTATTTGGGTTTTCACTAGTAAGCAGTTGGTTTGTAAGCAGTTGGTGATTTTAG +TTTGTCTGGGTTTCAGCCATGAATATTCTATTGTAAACTTAATTATAACAACTGCACTGT +AATAATTCAATGTCCTATTATGATGTTGTTATAGACAAAATTTGCCTTTACATTGTCATT +TATTTTATTTTATTTTTCTTTTGAGACAGGGTCTCACTCTGTCACCCAGGCTGGAGTGCA +GTAGCTCAATCTTGGCTCACTGAAACCACTGCTTCCCAGGCTCAAGCGATTCTCCCACCT +CACCTTCTCGAGTAGTTGGGACCATAGGTGTGAACCACCATATCAGGCCAATTTTTGTAT +TTTTAGTAGATACGGGGTTTCAACATGTTGCCCAGGCTGGTCTTGAATTCCTGTGCTCAA +GCGATCCACTTGCCTCGCCTCCCAAAGTGCTGAGATTACAAGTATGAGCCATTGACATTT +AATCTTCCTTCCTTCCTTCTTTCCTTCCTTCCTTCCTTCCTTCCTTTTCTTTTTTTGAGA +TGGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCACGATCTCGGCTCACTGCAAG +CTCCACCTCCTGGGTTCAAGCATTTCTCCTGCCTCAGCCTCCGGAGTAGCTGGGACTATA +GGCGCAGGCCACCATGCCCAGTGATTTTTTATTTTTATTTTTTTTGAGACGGAGTCTCAC +TCTGTCACCAGCCTGGAGTGCAGTGGCGCATTCTTGGCTCACTGCAACCTCCACCTCCAG +GGTTCAAGCAATTCTCTGTTTCAGCCTCCCGAGTAGCTGGGATTACAGGCACCCACCACC +ACACCCAGCTAATTTTTGTATTTTTAGTAGGGATGGGGTTTCACCATGTTGGTCAGGCTG +GTCTTGAACTCCTGACCTCGTGATCCACCAACCTCGGCCTCCCAAAGTTCTGGGATTACA +GGCGTGAGCCACCGCACCTGGCCTACTTTTTTAAACTTAAATTTTAAAAAAAATTAAGTT +TATTTTTAATGTGATTTATTTATTTATTTATTTTTTAGATGGAGTCTTTCTCTGTCGCCC +AGGCTGGGGTGCAGTGGCACTATCTTGGCTCACTGCAACCTCTGCCTCCCGGGTTCAAGT +GATTCTTCTGCTTAGCCTCCCAAGTAGCTGGGGCTACAGGTGCATGTCACCACGTCCAGC +TAATTTTTTTGTATTTTTAGTAGAGACAGTGTTTCACTGTATTGGTCAGGCTGGTCTTGA +ACTCCTGACCTTGTGATCCGCCTGCCTCAGCCTCCCAAAGTGCTGGGATTACAGGTGTGA +GCCATGGCACCCGGCCTATTTATTTATTTATTTTTTAATTTTTTTTGAGACGGAGTCTCG +CTCTGTCACCCAGGCTGGAGTGCAGTGGTGCAGTCTCGGCTCACTGCAAGCTCCACCTCC +CGGGTTCATGCCATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGACTACAGGCGCCCGCC +ACCACGCCCAGCTAATTTTTTTGTATTTTTAGTAGAGATGGGGTTTCACCGTGTTAGCCA +GGATGGTCTCGATCTCCTGACCTCGTGATCTGCCCACCTTGGCCTCCCAAAGTGCTGGGA +TTACAGGCGTGAGCCACCGCGCCCGGCCTCTTTCAATCATTTCTGATGACACCGGAGAAG +GCAGTGTCCTTTCCTTATTGTCTCTTTTTTTTTTTTTACCTGGGTATTCTGGAAGTGTCT +TTCCTCTGACAGTGTTGTTGGACGTGGGGAAACAAAAGGGTATCAAAGAGAGGGAGAGAA +GGATAAAGACCACCCCTCATTCCCGCCCTCCCAGAGGGGCAGCCTGGGGAGTCTATGGAG +GAGGTGACTTTGAGCCATGATGTGACCTTAGATGAGGGGCCTCTCTGAGCCTCAGGAAGC +TCTTCTGCAAAATGGGGCAAATAAAGAAATGCCCTCTGTGTGCAGTGGCTCAGGCCTGTA +ATCCCAGCACTTCGGGAGGCCAAGGCAGGAGAATCACTTGAGCGCAGGAGTTCCAGACCA +GCCTGGGCAACATAGTGGGACCCCATCTCTACCAAAAAATTTAAAAATTAGCCAGGCATC +AGGTGTGGTGGCTCAGGCCTGTAATCCCAGCACTTTGGGAGGTTGAGGCAGGCAGATTGC +TTGAGCCCAGGAGTTTGAGACCAGCCTGGGCAACACAGTGAGACCCCTGCTTCTACACAC +ACACCAAATTAGCCAGGTGTGGTGGTGCACATCTGTAGTCCCAGCTACTTGGGAGGCTGA +GGTGAGAGAATCATTTGAGCCCTGAAGCTCAAGACTACAGTGAGCTGTGATTGTGCCACT +GCCCTCCAGCCTGGGCAACAGACCAAGACTCTGTCTCAAAAAAAGGAAAGGTCCAGGCGC +GGTGGCTCATGCTTGTAATCCCAGCACTTTGGGAGGCTGAGGTGGGCGGATCATGAGGTC +AGGAGATTGAGACCATCCTAGCTAACACAGTGAAACCCCGTCTCTAGTAAAAATACAAAA +AATTAGCCAGGCGTGGTGGCGGGCGCCTGTAGTCCCAGCTACTCAGGAGGCTGAGGCAGG +AGAATGGCGTGAACCCGGGAGGCAGAGCTTGCAGTGAACTGAGATTGCACCACTGCACTC +CAGCCTGGGCAACAGAGCAAGACTCCATCTCAAAAAAAAAAAAAAAAAAAAGTGGAAAAG +AAGGCCGGACGCAGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCTGAGGCGGGCA +GATCACGAGGTCAGGAGTTTGAGACTAGTCTGGCCAACATAGTGAAACACTGTCTCTACT +AAAAATACAAAAAATTAGCCAGGTGTAGTGGTGTGCACCTGTAATCCCAGCTACTCGGGA +GGCTAAGGCAGGATAATTGTGTGAACCCGGGAGACAGAGGTTGTGGTGAGCCGAGATTGT +GCCATTGCACTCCAGCCTGGGTGACAGTGCGAGACTCTGTCTCCAAATAAAAAAAAAAAA +GGAAAAGAAATTCCATCCCAAGGTGATCCCTCACAGGAAGTGACTCAGAAAAGCAGTGAG +CTACGAAAGCTATCTGAATGAAGCAAGATCGTCATGTGGGAGACACTGACTACCCACTCC +TAGCAAAGGGCTCAGCAGCACACGGCCTCCCTGCGGGGATGCCCTCGGGGAAGATGTGGC +CCAGAGGAGTTTTTTGGGCCTTGCTCCTCAGTCCTGGCTCTTAGTAGGACCCTCTGCAGC +CAAACTAGCATATCCTGAGCCAGGCTGACCTTAAAAAGTAAGCATTCAGGGCCTAGGGAC +CTTGGGCAAAGCAGAGAAGCTGGTGTCAGATGAGGTGCAGCAGGTACAGTAGGATAAGGT +GTTCTCAGGTCGCCAGTGCAGCCCCAAGATGAGCCTGCAGTATTTTCCTTACATGATCTG +GTCCTACTGTGGGCAGCGCTGCTGCCCAGAGCCTGAGAGGATTATGAAAACATGGCAACG +GAAGTGAGGCCAGGGGACACAGCATGGGGGCATGAGGAGCAGGGGACAGCGGGTGGGGCT +AGAGGAGAGGGAGGTTTAGGGAGGCCTCTGCTGCTGTGACTGTGAGCCCCAGCCAATGAT +GACGTGGCCACCGCACAATCTGAGTTCTGGGAACCATGTGATGGAATGTGTTCTGGGAAT +AGACTGCAGCCAGGAAAAAAAAAGCAGAAGGGTGCACCCTCCCTTCCTCAGCCAGGAAAA +CATTTCTGTAGCCCTTGCGGACCCAATGCGCAGAAGTGAGAGGGAGGAAAGCCAGGCTCA +TGTTTCCTTGGTTGTGCTTCAACTTCTAAAATATGTTTTTTCTATGAACATTTTAATGAG +GGGTTGGACATAAGACAGAAAAATAACATTCTGAGAGCTCGTTTGGAGGTTCTAGCAGGG +GAGCGCAGCTACTCTTATACTCTTGACTGAAGACCGATCGTCCTCTATCGGGGATGGTCA +TCCTCTTCCATTGAGCACACAGCTTCTGGAGGGACGCACATGGAGTGGTGAGGGAGGAAG +GGGATACCCGCCTAGTCAGCCAGATCAGCCGAATCAACCCTGATGATCAATGGGGTGACA +CATGTCGCAGCCAGATCACCCTCACATCCCAAAAATAACACTCAGATTGCTTTTTCTTTT +TTAAGATGTAGACTTTTCTTGAGACTTTCGTACAAGGCAATGGACAGATAACCTTAACCT +CCCAGAGAAAACACACATTGGCCACAGAAAAAGGCGCTTCTCCGTATACCTGCCATAGTT +ATCAGCAACTTTGAAATGGCTTCTCAGACTCTCAGGGGTTGGCTTGTTGTGTTTGCTTTT +GCAAATAACTCAGGCTTAAGTCCTGCTACTTTCAGAGCCTAGGGGACGCTTAAGGACTAC +CATCAGTTTAACACAGTGGCACTTGGAGCACATGCTACTTATGGTGGTGAGGAGGGGTGC +TGGTGTGAGGGTCTGAACGCTTGCTTCTCCTCTGGCAGGGTGTGAGCAGCCAGAGGCCAC +TACCTGGGCAAGGATGCTTGCTCAGTGTCCATGGAGGGACATGTGATCCAGCAGGTGGGC +AGGAACCAGGCCCCTGTGGCCGCCCAACTCTCCATAATAGAATCCTTGGTCATCCATGGG +CCCGTAAACCATGACCACGTCTCCTGCCCTCAGCGCCAGCCTGCCCTTCCCCTGGCCCCC +CATTTGCCCATCCCCAGGATCATAGTCCAGAGCTGCTATCATGATCTTTGGAGTCCACAG +TGGGAGTCTCTTGGAGTTCCCCTGGAGCACCAGGGAGGAACCCTGGGGGATGGTGAGCCC +CTGAAAGTCCTCGAGGTGGGCCACAGAAGGCAGGTTCCCTTGGGCCGGAGAACGCCACCT +CCTATCAGTCTGCTCTGTCCCCACCTCCATCTCAGCCACTAGGCGCCCGGGGATATTGCC +CACTTGCCTGTTGCACTCGCTGAGGTAGAAATCATGGGTGTCCTGAGAGCCCCACACTCT +TAGCAACTGCCTTTTCTGGAAGACCAGCTCCTCCTCTGCAGCCTTGAGGTTGGCAGACAT +CACCAGGGGGTTGTAATCAGAGAGGGCCACAAAGACCCTGGCTGGAGTGTTGGCCCCCGT +CCCCAGCTGTTGGGGGCCACCCCTGGGCATCTTGATGACTTTGGCGGATGGAGCTGGACA +CAGTGCCGAGCTGGGCTCATGGAGCTGGCACCCTCTCTTCACCCCCAGAGCTTGTCCTTG +CCTGCTGTGGGGCTCAGGCTCCCTCCTCTCCTCTCGCCTCTCTGTGCCCCACAGATCCAA +GCACAGTGCCTCCTGCTCCTCCTTCAAAACGTTATGGAAGTCAGATGCATACTGTTGGCT +GGCGCCCAGCTGGGGAGGTGTGAACCCTTGGGCATCTTGCTTTTGCCGAAGTACCCTCTC +AAGGGCAGCCTTTTCCTGACACGGTTCTTTCCTGGGCCCACACTCGGTGCGTAGATGGAT +GAATCCTGGAGCAGGGCTTTTGCTGGTGCCCATGTGCTGGGAGCAATTTTCCTTCTCCCC +AGGCTGGTCACTGACTGAAGGTGGCCTGTGGTTCTGGGGACTCTTCTGAAAGAGCAGGTC +CTTTCTACAGCCCTCCCAGGCCTCTGCAAGCTCCTGGGCTTGGCTGCCAGCCCCTGAACT +CGGACATTCTCCTTCTGAGCCCAGGTTGGACACTGGGGATTGCCTCCTTGGGGGTTCTTC +AAAGAATGCTTCTAGGAACTTGGCCTGGGGCTCCCCGCAGCTTCCAGGGTTGTGGGGGCT +GGCCTTGGCACTCGGAGGAGCCAGTGACAGCTTCTGGGGGCAGACGGGGAAGGTGACTCT +GTAGGTGGATGGGTCGCCACAAGTGTAGCTAAAGGGTGGAGTCTCTGGCCATCGGTGACA +CATGAAGAAGTCCTCGGGGATCTGAGCAGGCACTGAATCCAGGGACTCACCACAGAGTGA +CATGGTTCTCACTGAGACCTTCTGCCACGTGAGGGGCACCTGTAGCTGGGAGAATTCCAA +TAGGGTGCTCCCAGCAGTGGCATCGGCGACCTCACAAACCTTAAGCCCATCTGCATACAC +AGCATAACCGGTGACCTGGACTCCATTGGAGGACCCAGCTGAGTCAATGGTCACAGGGAG +CCAGCTGACCACCAGGACACCTGGCGAGGCATGGCGCTCCACCAGCACATCCAGCGGTGG +GTAGGGAGGTCCTGCCAAGAGTGTGTCGAAGGTGACGGTGGAGGACATAGTTCCCCAATA +CACCTGCAGCAAGTCCCGTGGCAGCCGCACCTCCACCCGCGCCCGGTAGTGCGTGCCGGG +GCACAGGCCCTGGAAGGTGTAGCAGCTCACGCCCGCTGGGGTCAGGGCATGCTCTCGGTC +ATCAAGATATACCACATGGGGGTGGCGGTGGCTGCTGTAGACCCAGGTGATGTTGGCTGA +TGTGGCTGTGACATTCTGCAGGTGTAGCTGCATGGGAGCCATACGGAGCACCCCTTTGGT +CCCCAGAAGGGGTCTGGAGAGGCCCTGCTTCCCCATGCTCTGCAGCAAGCCCAGCTGGCA +GGCTTCCGTCTTGGTATCCAGGATCTCTGTTGCTACTTCTGTCTTGGAGCCCACCCTGAC +CATCTGGCACAGCCCTCTGTCCACCACTCCCTGGGCTTTCCCAGATAATAAGCTGTCTTC +CTCCAGAGCTTCATCCTGCCCCGCTGGGAGTTGACTGGGGCCAAGATCAGGGGATTTGGC +AGGCAGGCAGCCTGGGATGTAGCTGTCCGGAATCTGCTCCACGAAGTTGGAGGGCACCAG +CCCCCGCCGGCCATCCTCAAGCTCCCCCTCATAGAAGCCATCCTCATCCATGTCCCCGAA +GATATATATGTAGTCCCCAGCTGTGAGGGGCAGCTCACCCTCAGGGTGATCATTGGGCCC +CTCAAATGGGTTGTAGTTATACTGAGCCATGAAGATCTTGAGCTTGGGGGCAGCAGGAGC +CGCCGAGCCCCCCATTTCCAGGGCCAGGGACACGCTGTCAGGCTCCAGGTCATCCACCTC +ACTGGCTGTGTCCCTGTCCAGAGTAGGGGAGGACGGCACGGTGGCCCACATCGACCCCTC +AGAGGAGGAGTTTGACTGGGAGCTGGTTTTCTTGGACAGAGGTTGGCTGGCAGGGACTGT +CTCTGAAACTTGGGGGACACTGGCTGACTCCCCAAGGGCAACTGGGCTCTCCTCGAGGGA +GGCTTCCCTTTTCTCCTGTATGTCTCTGTTGGGCTGTGACACTGCGTAGTCTTCAGGCCG +TGCGTGGAACTTGGGCCTTCTGCTACCTTTAACTTGGGACTCCGGCATTTGACTGGTCTC +CCAGGGCTGTTCAGGAGGGTGACCAGGCCGACACTGGAGCGCCTGTATCTCCTTCCAGGA +AGGATGGAGGTCACACAGGGCCTTCTGCGGGTCGCGTTGCAGCTGCTGCTGCCTGTCCTG +CCCGCGCGCCGCCTGCTGCAGCAGCTGTTCGGCGATCAAGCCGGAGGCATCGCGCTCTTG +ACACGCGCGGCCCAGGTGGCCGCGCACTTCGCTATTCTCAGCCTCCACCTTCCGCACCCA +GTCGGTCTTGGCCTGCAGCCGCCCATTCTCCTCCGCCAGCCAGGCGTTTTTGAGCAGCGC +CGCCTGCAGCTGTGTCTCGGCCTCCTCGCCACGTCGCCGCGCCGGGGCCGCCTGCGCGCC +CAGCTCCTGGCACTCGCGCCGCCGCTGGTCCAGCTCGCGCTCCAGCGCCAGCATCTGCCG +TCGCACCTCCTCGCAGGTTGCGCTCTGGCCGCCCGCCTCGGGCCAAGCGCCACCGTTGCC +CTGCTGAAGCATCAACTGCCTCTGCAGGCGCAGCACTTCCCGCTGGGACTCGCGCTGCAG +GCGGTCTAAGTCTCTGACGTTGAGCCACTGGGTGCAGGGGCCGCCCCTTCCAGTATGCAG +GTCGCTGCAGGGACCCGAGGCGACACGCGCCTGCAGGAGGTGGCACTCCTGCCGCAGCTC +TTCGATCTGCTTGTCCTTGGCCAGCGGCGCGCTCGCCTGCTCCGACAGGTCCCGAGCGCG +CTGGCGGGCAAAGACTTGGCACAGCTCCAGGCCGGCGCAACTCTCGCCGGGTATAGGCGC +GCTCACGGCCCGGAGGTTGGTCTCCTGCAGCTTGCGGGCGCGGTCAGCTAGGCGCCGCGC +GAGCCCGGTCAGCTCCGCGCGCTTTACCTTGAGCCGCTTCACCTTCTCGTCTGCCTGGTA +GGGGCAGCCTGCACGCCGCAGCTGCTTGTTCTCCGCTTGCAGGGTATAACAGCGGCGCGC +CAGCACCCACAACGCCTTGGCCAGCAGCCAGTTCAGCTTTATCAGCTCGTGGTGGCCCAG +GCCCGGGGGTGAGGGAGTCAGGACTTCGCAGGGCTGGCTCTCAGAGCCTTCTCCTCCCCG +CGGGTTGCTGAGTTTCCTGTGGGCTGACGGTGGTGGTGGCGGCGGGAGTGGCGATGGTGG +CGGCGAGAGCCTCCGGGAGCCAGGGGTGGAGGTGTCTGGTGAGGAGGGCCGCTCCTCGGA +TTTGGAGGCCTTGGGGAGGCTCCGGGTGCTGTCAAGCGAGCGGGAACACGCAGGTGCGAA +GCAATCAAGGGAGCTGGCGTGCGTGGAGAGCAGGCCGTCTGGGGAGCTGGAGCACGCAGA +GGACACCAGGCCTAGCGAGCGGGAGCGCACACCGACTTCAGCACTCAGGCTGTCTAGAGA +TCCGAGTTGGCAGGCGGGTTTGGGGGCGTGGCAAGAGCCGCTGGAGGTCTGGGGCAGCGG +TTCTTCCAAGGAATGCACAGCTTGGGGGTCCGGTGATCCCGACAAAGCCGGGTGCCCGCG +GAAGTGCGCCAGGATGTACTTGAGGAAGAGCTGGCGCTCCACCTCCAGCGCCGCCTGCAG +ATAGCGGATGCGCGCCGCCTGCTCGCCGTCAGTCTGCCAGCGAAGCTGCGCCAACACTTC +CTGCAGGCGACAGCGGCACTGCGCCGCGGAAACCTCGGACGCCCCCGGGCGGCTACAGTG +GCCGCGGTTCACCAGCTCCTCGGCCAGCTGGCGCTGCAGCTCCCGGGCTTGGCGCACCAC +GCCATCGCGCTCCCGGTGCAGCAGCTGCTGCAGCTGCCGCTGCTCGGCCTCCTTCCAGCG +CAGCAGCTGCCGGATCTCGGCCTCGCGTTCCCGCTGCATCTCCTCTTGCAGCTGCCGCAA +CTCCCGGCTGCGCTGTGCCTCCCACTTGGAGCGCAGACGGTCAGCCAGCTGTCGCCGCTC +CCGCTCGGCCTCCTCACGCAGCTGGCGCTCCCGGGCAGCGAAGCGCCGCCGTTCCGCCCG +CCAGCCTGCCCGCTCCGCCTCCAGCTCCGCCCGTAGCTTCTCCAGCTCCCGCCTCTGGTT +CTCCAGCACTGCCGCCGCCGGGCTGGAGCAGCCCGGCTTCTTGGGCGACGCGCCCAAGGG +GCTGGGCGAGTCCTTGGCCATTGCGGCCGCGGCCCGGCTGGTCTCCAGACTTCGCCTGGC +AGGCCTCAGCTCGCCAACGGCCGCCGCCGACCGCCCGGCGCGCCCCTTCCGGCGCCCCCT +GGGGGTCTCCGCGTGCCCCTTCCGCCTCTTGGCATGTTCCCCCGCCTCCTGCCGCGGATG +TCTGGCCCAGGCGCCTCTCCACCTGGCAAGGCCAGGGCTGGACTCCCACACCCCTGCTCA +AACTGGCCCATGTCCCTTCCAGGATGCACGGGGGCTTTTCCGGTCCCTACACTTTTCCTG +CTTCTAGCACCAAGTCCCTTGTGACCCTCCCCAGGCACCCTCCCAGGCACTGTGCAGTCC +CAAGCAGGCCGCGGTGCCCCGAGGGAAGTCTGGGCTGCTGCTCCTGTACTTGGAGAAAGG +GGCAGGGTGTGTGTGTTAAGGCCACCCATGGGGTGTGGGCATACCTGGTCGTGGGTTCAG +GTGGTGTATTTGGGTCAGGTGGCTGGAAAATGCAGCAGGATAGGCCTCAACTTGGCTAGA +CCTGGACTCCCCAGGACCCTTCAGCCCCCTAACAGCCCTGATCACCCAACTGGTCATCCA +CCTTTTGAGGAAAGGATGTGCCTGATACACATTTGTGTTACTGCGCAGAGTCGGCTCAGA +GGAGGTGTAAGCGAAAAGACCCTCCCCAGCAAGGTGGCATAGGGACCCAGGGCCAGATAG +GCATGAGGGGCACTGCCCAAACTGGCCATCTGGCCTGTCTACCTCCCACATCCAGGTACC +ACCTGGTGACAAACACTGGAGCCCCAGTGTCTGGGCTACTCATTGGCATCTTAGGTAGAG +GCCTCAGGATGGGCCAGGAGTGAGGGTGAGGCTTCAGCAGAAATGTTGGAGGCATCCTGA +GCTGCAGAAGAAACACACACACACACACACACACACACACACACACACACACAGCTGCAG +AAGAAACATACACACACACACATACTGAGCTGAAGGAATACACACATACACTGAGCTGCA +GAAGAAACATACATACACACACTGAACTGAAGAAATACACACACACACACACACACACAC +ACACACTGCCTCTCTGACTGGTGGCCACCTGTGTGGCTTGGGAGCTAAGAAGCCCTGCTT +CAGTCTGGCTCCTCTTTGCCCTTCCTGTCTGCTCCTGGTGCCAAGTGGCTTTTGGGAGAC +ATGGATGGACACCTGATACCTGGCAGTCTGCATCGAGACATTGATTTTTTTTTTTTTGAG +ATGGGGCCCCACTCTGTCGCCAGGCTGGAGTGCAGTGGCGCAATCTTGGCTCATTGCAAC +CTCTACCTTCCACGTTCAAGAGATTCTCCTGCCTCAGCCTCCCAAGTAGCTGGGATTACA +GGCTTGAGCCACCATGCCCAGCTAATTTTTTGTACTTTTTAGTAGAGACAGGGTTTCAGT +ATGTTGGCCAGGATGGTCTTGAACTTCTGACCTCAAGTGATCCACCCGCCTCGGCCTCTT +AAAGTGCTGCGATTACAGGCATGAGCCACTGTGCCCGACAAGACCTTGATATTGAAGTCA +CATCAGAGGCCCCTTTGCTTCTTGGTCTGTCGTGTCTCCCTGTCCCCAGGAAGCACCTGG +GACCTCTCACAACTGCTGTGTTCACTCAGCTTATGGCCCTCCTTTACAACACTCAAGTTT +TTCAAATCAGTTTCCCCGGAACCCACAGAACATGCCTTTAGGCAGTGTCAAGTAACAAGA +ACATCGGGAATTATGGCTCCAGATGTTCTTTTTTTTTTTTTTTTTTTTGAGATGGAGTCT +CGCTCTGTCGCCCAGGCTGGAATGCAGTGGCGCAATCTCTGCTCACTGCAAGCTCCGCCT +CCTGAGTTCACGCCATTCTCCTGCCTCAGCCTCTCAAGTAGCTGGGACTACAGGTGCCCG +CCACCATGCCTGGCTAATTTTTTTTGTATTTTCAGTAGAGATGGTCTCGATCTCCTGACC +TTGTGATCTGCCCGCCTCAGCCTCACAAAGTGCTGGGATTACAGGCGTGAGTCACGGCGC +ATGGCCCTTTATTTTATTTTATTTTATTTTATTTTATTTTATTTTATTTTATTTGTGAGA +CAGAGTTTTGCTCTGTCACCAGGCTGGCATGCAGTGGCACGATTTCGGCTCACTGCAACC +TCCAACTCCCTCGTTCAAGTGATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAG +GCATGCGCCACCACGCCCAGCTAATTTTTGTATTTTTAATAGAGACAGGGTTTCATCATG +TTGGCCAGGATGATTTCGATCTCCTGACCTTGTGATCCGCCCACTTTGGCCTCCCAAAAT +GGTGGGATTACAGGCGTGAGCCACCGTGCCCAGCCCAGATGTTCTTTATGAGAGGTGAGG +CAGATGTAGTGTGTATGTGAGAGGAAGGGGAGGTGAGATGCAGGGATGGCCTTAGCCTTG +AACTGGTGCTGGGCTCCTGGGCATGGTAGCCACAGGGAGGACTATCTTGAGAGAATCTTC +ATCACAGCCCTGTTTTACGGAAGAGAACCTGAGGCTCAGTGAGAGCCACTGGCTTGCCAG +GGCACATGGGCAACTGAGGCAGAGCTGGTGGGTGGGGTTTCACAGCCTGGATGCCCTGCT +GCAGTCTCCAGTAGGGCCTCAACTGTCAGGTCAGGAGGGCAGGCTGGGCCGGGCATGGTG +GCACAGACCTGTAATCCCAGCCCTTTGGGTGACCAGGGTGGGAGGATCACTTGAGCCCAG +GAACTCAAGACCTGCCTGAGCATCATAGAGAGACCCTGTCTCTACAAAAAAAATTTTAGC +TGGGCGTGCTGGTGCATGCCTGTAGTGCCAGCTACCCAGGAGGCTGAGATGGGAGGGTCA +CTTAAGCCCGGGAGTTTGAGACTAGCCTGGGCAACAGAGTGAGCGAGACCCAGTCTGCAT +TTCCAGCTGAGATGAAATGATTGCTTGAGCCTGCAAGGTGAGGTCAAAGTCGCAGTGAGC +TGTGATGGCACCACTGCACTCCAGCCTGGGCAACAGAGCAAGACTGTCTCAAAAAAAAAA +AAAAAAAAAAAAAGCCTGGTGCGGTGGCTCACTCCTGTAATCCCAGCACTTTGGGAGGCC +AAGGCAGGCGTATCACGAGGTCAGGAGATAGAGTCCATCCTGGCTAACATGGTGAAACCC +CGTCTCTACTAAAAATACAAAAAATTAGCCATTAGCCAGGCGTGGTGGCGGGCACCTGTA +GTCTCACTTATTTGGGAGGCCGAGGCAGGAGAATGACATGAACTCAGGAGGTGGAGCTTG +CAGTGGGCCGAGATCCCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCATCTC +AAAAATAAAAATTAAAATTAAAATTAAAAAAAGAGAGTAGGCTGTCACCAAGAAAAAGGA +CACTGGGGTGGATGGGTCTCTGGGAACCCCACAGTTACCATCCAGCAGCTGCCCCAAAGT +ATGTCAAAAGCATTCGGGAATGTTGGTTGAGTGGATGAGCAAAGCCAGGCTTCCCCAGGG +CTGGGTTTCTGCCATCCCTGTTCTCATCATGTTGTGCAGTGATTGTCCAGTGACCTGCCT +GTCACCCCCATCAACTCTGATCTTGGGGAGAGCAGAAGCCATGTTTTCCCTTGTCCCTAT +TGCATCCGTGCATGTGACTTAGCACATCACTGGTGCCCAAGACATATGAGAATGAGTTGC +AGGGAGGCAGGAGTCCCTGCATGAGCTCACCATGCTGCTGCCTTCTCCAGGTTCAACTTT +CTCACCTATTAAATGAAAGAGATGGTTTCTTTTTTTTTTCTTTGAGATGGAGTCTCACTC +TGTCACCCAGGCTGGAGTGCAGTGGCATGATCTCGGCTCACTGCAATCTTCACCTCCTGG +GTTCACGTGATTCTCCTGCCTCAGCCTCTCAAATAGCTGGGATTACAAACACCTGCCACC +ATGCCTAGCTGATTTTCATAGTTTTAGTAGAGACAAGGTTTCGCCATGTTGGCCAGGCTG +GTCTTGAACTCCTGACCTCAAGTGATCCACAGGCCTCAGCCTCCCAAAGTGCTGGGATTA +CAGGCATGAGCCACCATGCCCAGCCTGAAAGTGGTGGTTTCAAACTGGGTTCTTTAGGGC +TCCAGGGTTCCTTGGAAATATAGAACTGCTGGGCACACACCTATACTCCCAGCTACTTGG +GAGGCTGAGGCAGGAGGCTTGCTTGGATCCAGGACTTCTGGATTGTAATGTACTATACTG +ATGGGGTGTCTGCACTAAACTTGGCATAAATTGGTGACTTCCTGGGAGCAGGAAACCACC +AGCTTGTCTAAGGAGAGGTGAACTGGCCCAGGTTAGAAAAGGAGCAGGTTGGCCGGGCTC +GGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCAAGGTGGGCAGGTCACCTGAGG +TCAGGAGTTCGGGACCCGCCTGGCTAACATGGTGAAAACCCGTCTCTACTAAAAATGCAA +AAATTAGCTAGGCATTGTGGCGCATGCATGCCTAATCCCAGCTACGCGGCAGGCTGAGGC +AGGAGAATTGCTTGAATCTGGGAGGTGGAGGTTGCAGCAAGCTGAGATTGCACCACTGCA +CTCCAGCCTGGGCGATAGAGTGAGATTCCATCTCAAAAAAAAAAAAAAAAAAAAAAGAAA +GAAAGAAAAAGGAAAACGAAAAGGAGCAGGTCAAAACTCCTGTGCTGGCTGGGCGCAGTG +GCTCACGCCTGTAATCCCAGCACTTTGGGCAGTTCAAGACCAGCCTGACCAATATAGTGA +AACCCCATCTCTACTAAAAATACAAAAAATTAGCTGGGTGTGGTGGCAGGCGCCTGTAGA +CTCAGCTTCTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGCGAGGCAGAGGTTGCA +GTGAGCCAAGATCATGCCATTGCACTCTAGCCTGGGTGACAGTGCAAGACTCCATCTCAA +AAAAAAAAAAAATTTTTTTTTTTGTAGGCTGGGCGCCGTGACTCATGCCTGTAATCCCAG +CACTTTAGGAGGCCAAGGTGGGTGGATCACTTGAGATCAGGAGTTCAAGACCAGCCTGGC +CAACATGGTGAAACCCTGTCTCTACTAAAAATACAAAAATTAGCTGGGCATGGTGGCAGG +TGCCTGTAATCCCAGCTACTCGGGAGGCCGAGGCAGGAGAATTGCTTGAACCCAGGAGGT +GGAGGTTGCAGTGAGCTGAGATCACGCCATTGTACTCCAGCCTGGGCAACAGAGTGAGAG +TCTGAGTCAAAAAAAAAAGAAAAAAAATTAACAACAGGCCAGATGTGACGGCTCATGCCT +GTAATCCCACCACTATGGGAGGCTGAGACGGGCAGATCACTTGAGCTCAGGAGTTCAAGA +CCAGCCTAGACAACACGGCAAGGCTGCATCTCTATAAAAAAATTACAAAATTTAGCCTGG +CATGGTGGTGCACGCCTGTAGTCCCAGCTATTTGGGAGGCTGAGATGGAAGGATACCTTG +AGCCTGGGAGGCAGAGGTTACAGTGGACTGAGATTGTGCCACTCCACTTCCACCTGGACG +AGAGAGCCAGTCCCTGTTTCAAACAACCAAAAAAACAAAAAACCCACCCCCCCAAAATAA +AAACAATAATAATAATAAAAATAAATAAAACAGAAATACCATAGGCCTTTTGGGAGGAGG +TATGCAGGAAGCGGATGGGGAGAGACAGTGCCCCTACTTGCTTCAATGGGCAGATCTACT +CTTTTTTTTTGAGACGGAGTCTCGCTCTGTCACCCAGGCTGGAGTGCAGTGGTGCAATCT +TGGCTCACTGCAACCTCCGCCTCACGGGTTTATGCCATTCTCCTGCCTCAGCCTCCCGAG +TAGCTGGGACTACAGGCGCCCGCCACCGAGCCCGGCTAATTTTTGTATTTTTTAGTAGAG +ATGGGGTTTCACCATGCCAGCCAAGATGGTCTCGATCTCCTGACCTCGTGATCCACCCTC +TTCGGCCTTCCAAAGTGCTGGGATTACAGGTGTGAGCCACAGCACCCGGCCGGCAGATCT +ACTCTTAAGTGTCACTTATCAGATTCGAAGAAGGGTTTTGGTTTAATAAAGCGTTATGCT +CCTTGAAACAAGTTTCAGAACCCCTGGGTTAGAGGACCTCTTGCCCATTGTGTGCTCACA +CACACACGACACACACATACCCCATCCCAGTACGTAATGACTTCCCTGACCCGGAGAGAA +GGCGATATGTCCCCCTTACATCTCAGTTGGCTCCACATCGCCAGCTCTGTATTCCACTTT +CCCTCTCTCTACAACCCCAGTCTATGACTTTTGGGCCATGGAGTCTGGGTTCCTGGGCAA +CCTGGTTCACATCCTTCTCCTGCCGGCATGGCCTGGCTCCATTTCTGTTCGGCTACCAAA +GCCCCAAGCTTTGTGGAGCCTGCCTGGCCTTGAGGAGGGGAATGGGCTCCATCCTGAGAG +CCTGCAGGAGGGTTTAAGCTTCCCATCCCCCATTGCTACAGTAGCTCCCCCAGCTTTTCA +TTCCATATCCTTTATTTTTATTTATTAAAAACTTAATTTTTGGCCGGGCGCGGTGGCTCA +CGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCAGGCGGATCACGAGGTCAGGAGATCG +AGACCATCCTGGCTAACACGGTGAAACCCCGTCTCTACTAAAAATACAAAAAATAGCCAG +GCGTGGTGGCGGGCGCCTGTAGTCCCAGCTACTTGGGAGGCTGAGGGAGGAGAATGGCGT +GAACCCGGGAGGCAGAGCTTGCAGTGAGCCAAGATAGCACCACTGCACTCCAGCCTGGCG +ACAAAGTGAGACTCCGTCTCAAAAAAAAAAAAAAACAAAAAACACTTAATTTTTTTTTTT +GTAGAGACAGGGTCTCCCTATGTTGCCTGGGCTGGTCTCAAACTCTTAATCTCGAGTGAT +CCTCCCACCTCAGCCTCCCAGAGGGATGGGATTACAGGCATGAGCCACCATACCCAGCCA +CATATTTTTTATTTTTGTTTCTATGTGTTTTCTGTCTGTTCTTTGCTGTCTCCTCCATGT +CTAGAACAGTGCCTGGCACATGATAGGTGCTCAGTAAATACAGGACTGAAGAAGACAGAG +GCAGACAGGCCAGATGTGGCTGCTGTCCTTAGGGAATTGACAGTCCATGATCTATGAGAA +TGAGCTGCAGACTGGGAGGCAGGTGTCCCAGCATGGGCTCACCAAGCTCCTACCCTCTCC +CGGTCCAGCTTTCTCACCTATGAAATAAAAGTGAAGCTGGACATGGTGGCCCACGCCTCT +AATCTCAGCAGTTTGGGAGGCCAAGGTGGGTGGATCACTTGAGATCAGGAGATTGAGACC +AGCCTGGCTAACATGGTGAAACCCCATCTCTACTAAAAAACACAAAAATTAGCCGGGCGT +GGTGGCAGTTGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATTGCTTTAAC +CTAGGAAGTGGAGGTTACAGTGAGCTGAGGTTGTGCCACTGCACTCCAGCCTGGGTGACA +GAGCAAGACTCTGTCTCAAAATAAATAAATAAATAAACAAACAAACAATAAATGAAAGTG +ATGGATTACATGAATGGTTTTCAAACTGGGTTCCTCAGGGCTCAGTTTGGGGGAGAATGC +AAAGGTTAAATACAAACAACAATGGAATGTAGTAACATTGGCGCTTGGGCGAGTGCTCTG +GGTGAGGAATGTGGTGCTCATGGGGAGAAGAGCCGCATCAGAGCAGGCTTCCTGCATGAG +GCAAGGAGGAAACACAAGAGCTGAGAGCTGAAGGAGAGGGAGTGAGGGCTGCCAGAGGAG +CTGGGAGGCGATTTCAGGCAGTGGGAACTGGAGCTGCAAACCCCCAGCCTCCTGCAGTCT +GGCTATCTGTACCAGCCCTCACCCATGCCCACCACCCTCAGGGCACTCACATCCCTTCTT +GCACTGATATTTTCCCGTCCTATCATGACCCTCGTTTGAGGGTGCAGGGAGGACTGGAGC +TCAGAGAGGGAGGGTCACCTGGCCAGACCCTAACCCGCTGAGTTCCAGTGGAGTTCCTTC +CATCCCCCAGCACTGGATGGGGCTGGATACCTGGAGAGGGACCGTGCTGCTCTTCCTGGG +CCCTGCAGCCTGCCTGGCTGGTCCACATCTTCCTGGGCCAGGAGGGCAGTATGGTGCGAG +CTTCTAGCTCTCTGGCTGGGGCCCCCTGGCCTACTGGGCTGGCTTCCTGCCCTGGTGGCC +CTGGCCCAGCTCCCCAGCTCATGTGCCTCTGCAGCGAGTGGTCAGCCCCTTCCCATCTGC +ACTTTACAAGCCTCATCGCTGAATCCTCCCCATAGCCAGAGAGCCTGGCACTCTCCTCTC +CAGAGAAGGAAACTGTCCAGGGTCACACAGGGACTTATGGGCAGGTCTGTGTGACCTGAG +TCTGGGCTCTGAACTGGTGCTTGCAGGGTCTTGCCCTCTGGCTCTGGCAGCCTGAGTGTT +ACTGTAATCCCTGAGCCTTTGAACAAGCAGGCACTGCTTCCTGAGATCCCCATTGCTGCT +GTCAGCGTCTCTGTTTCCCAGCTCCACACTGCTGCCAGGACAGACGTATCTTCTGTCTTG +TAGCATCTCCATTTCTCTTCCCTTTAGATCTATTTTTTTTTTTTTGAGATGGAGTCTCGT +TCTATCATCCAGGCTGGAGTGCAGTGGCACAATCTTGGCTCACTGTAACTTCTGTCTCCT +GGATTCAAGCGATTCTTCTGCCTCAGCCTTCCAAGTAGCTGGGATTACAGGTGCATGCCA +CCACGCCTGGCTAATTTTTGTATTTTTAGCAGAGACGAGGTTTCACCACGTTGGCCAGGC +TGGTCTCAAACTCCTGACCTCAGGTGATCTGCCCACCTCAGCCTCCCAAAGTGCTGAGAT +TACAGGCATGAGCCACCGCTCCCGGGCTGGATCTATTTCAATCACCCTCCTTCCTCTGCA +GCCTGAAACTTGAGGCTTTGCCCACTTCCCAAAGGCACGAGTAGCAATGACCATTTGTTC +TGTCATTTGGCCATAGCTCTAGGTCAGAGGACAGTCCTTCATCAAATGTTTGTTAAGCAT +GCAATCTAGACAGGGGAGGACAAGGGCCAAGTAATGTGTTAATTTCTTCATTCACTAAGC +ACAGAGAATGGAGTAGAAGGAAGGTGGAAAGGAGAAGGAAGGAAAAGAGAGAAGAAGGAG +GATAGAAAGGAAGGAAGGTGGGAGGGAGAAAGGAAAGAAAGAGGGAGTCCTTTAGGTTAT +CTAAGTCCCCTCAGGACTTGGTCTGGCCCTCACAGTTCAAGAACAGACTTGGGCTTGAGC +CTCTGACCAGCCAGATGACTGAGAAGCTGAGGAACAGCTTGAGCCTCAGTTTTTTCCTCT +GTAAATGGGGTTGATAGCAGTTCTGACCCAGCGGGCTGTTGGGGGAGTCACAGAGATGCT +GGGTGCTGCCTTTGCACTCAGAAGGGTCCAGGCTAGGTGTGGTGGCTAACACCTGTAATC +CCAGTACTTTGGGAGGCTGAGGTGGGAGAATTTCTTGAGTCCATGAGTTACAGACCAGCC +TGGGTAATATAGAGACAAACTGTCTCTATAAATTTTTTTCCCAAAAATTAGCCAGGCATG +GAGGTGTGCACCTGTAGTTCTAGCTGCTTGAGAGTCTGAAGTGGGAGGATAACTTGAGTA +CAGGAGGTTGAGGCTGCACTGAGCCATGATCACACCACTATACTCCAGCCTGGGTGACAG +AGCCAGACCCTATCTCAAAAAAAAAAAAAAAAAAAAAATCAAAGGGGTCCAGCAGCATCT +TCCTGTCAGCTTACCTAAGGGAGCATGATAAATTGAGTCCCTGCCACGATGGACATGGGG +AGTGTAGTGGGAGGGAATGGCAAAGGCACCACAGGCAGAGGGAACAGCCTGGGCATAGTG +GGGGGTGTGATGTGGCACAGCACTGATTGTGGGAAGCGAGGGATGTGGGAGATGAGGCTT +CAGGTAGTCAGAGGGAGGTTGAGGCAAAGCCTCACCTGCATGCTCTAGATGAGGTCCAAT +TCCTGGTACCCAGCTCCTAGCCTAGTAATGGGCCACTTCTCCCAGGGCCACAGTTTTCTC +TCCTATCAAATGGAACATGTTAGCACTGCTCTATGGTGCCAATGAAGGGTATAAGTGTCC +AGTGCCCATTTCCTGCCCCAGCAAAGGCACTTTCTTTTCCTTGTCCTCTTGCCTACTGGG +GAACTCCTTCCATCCCTGGTTCCTCCCCCAGCTTCTGCGAGGCCCCTCCTCTGAGCCCCC +ACACCTCATCAAACCCTCAACACCGTCTGGTGTTTTCCTTGGTGCCTCTTCAAGATGCTG +TGAGCTCCTTGGGGGCAGGTGGTGCCTGTGTACCTCTTTTTTTTTTCTTTTTTTTTTTTT +TTTGAGACGGAGTCTCGCTCTGTCACCCAGGCTGGAATGCAGTGGCGCGATCTCGGCTCA +CTGAAAGCTCCACCTCCCGGGTTCACGCCATTCTCCTGCCTCAGTCTCCTGAGTAGCTGG +TACTACAGGGGCCCGCCACTGCGCCCGGCTAATTTTTTCTTTTTTTCTTTTTTTTTTTTT +TTGAGACGGAGTCTCGCTCTGTCTCCCAGGCTGGAGTGCAGTGGCACAATCTCCGCTCAC +TGCAAACTCCGCCTCCCGGGTTCACGCCATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGG +ACCACAAGCACCCGCCACCACGCCCAGCTAATTTTTTGTGTTTTTAGTAGAGACGGGGTT +TCACCGTGTTAGCCAGGATGGTCTCGATCTCCTGACCTCATGATCTGCCTGCCTCGGCCT +CCCAAAGTGCTAGGATTACAGGCGTGAGCCACCACGCCTGGCCTTTTTTTTTTTTTTGTA +TTTTTAGTAGAGATGGGCTTTCCCTGTGGTCTTGATCTCCTGACCTCGTGATCCACCTGC +CTCGGCCTCCCAAGGTGCTGGGATTACAGGCGTGAGCCACTGCGCCTGGCCCTGTGTATC +TGTTTTTCTGGACCGCCATCATGTTCAGGAAGGCATCGAATATTTTGTCCGCGACTGCAA +TCACACACTGCATCATCCCTGAAACGAGGTTTCCACGGATAAGGTGCAGCAACAGAGAGA +GAATCCTAGCAACTTTCAATCATTTTCTTTTGAAATGGTTTTAGACTTACAGAGAGTGGC +AAAGACAGCACAGAGCTCCCATATACCCTTCACCTAGCTTCCCTGGATTTTAACATCTGC +AGTAACCAGGCTGATGTGTCAAAACTGAGTCAGATATTGATATAATCCTATTACCTAAAC +TTCAGACTTCGTCTGGATTTCCCAGGTCTCCCACACATGCCCCGCTTCTGTTCCAGCATC +CAACCCAGGACACCAGGTGGCATTTAATCTCTGTGTCTCCTACTCCCTTCCAATATGTGG +TGACTCCCCAGTCTGTCAATGTCTTTTGTGACTTTGACACTTTTGAAGAACAGTTATTTT +GTTGAATGTCCCCTAATTTAGGTTTGTCTGATGCTTGCCCATGATAAGACTAGGGTTACA +GGATTTGAGGGAGAACTCCATAGAGTGGATGTGCCCTTTCTTTTTTTCTTTATCATTTTT +TTGAGATTGAAACTCGCTCTGTCGCCCAGGCTGGAGTGCGGTGGCACGATCTTGGCTCAC +TGCAACCTCTGCCTCCTGGGTTCACGCCATTCTCCTGCCTCAGCCTCCTGAGCAGCTGAG +ACTACAGGCGCCCGCCACCACGCCCGGCTAATTTTTTGTATTTTTAGTAGAGACTGGGTT +TCACCACATTGGCCAGGATGGTCTTGATCTCCTGACATCATCGTGATCCGCCCGCCTTGG +CCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGTAACCAGCCTGCCCTGCGTAATT +TTTGTTGTCGATGATCCAAAGTGCACCCACTCGCCATCTCTGGTAGCTGGGAGGAGCAGG +TTTTTGGGTGAAGGTGAAAGAGCCGGAGTTGGGGATGTGTGTGGCTGGGGGGTACAGGTG +CGACCACTTTGCAGTCCACTCCTGTGAGTAGGGCATTCCTGAGGGAGAGAAGGCCTGGTT +AGCCCTGGGGCTCCTTCAAGGCCTGGCCCCAGGCCTTGATACCTAGAGCAGCCTGACACA +TGTGTGGATGGACTGCCAGGCGGTCCCCTTAGGAGGGGCTGTTCTAGCAGGGACCCTGGC +TTGGGTGACCACCACCTCCTGCCACACTCCAGGATCCCTGTCCCTGCTGGAAGCCGGGCC +CAGGGCCATGCCAGCCGTGAGGGGTTCCTCATGAGCCTCCTCCCCGGGACCCAGGCCCCA +TGCAGCTGCCCCCTCCCACCTGCCTGACCCCCCTGGCCTGCACTTCCCTCCATCCGAATC +CTCAATCTCCGCCTGGAATTCCCTTCCCTCCTCAACCCCACCTGGAAACTCTCCTCCTCC +TCCCACACAGCTGGGACTCCCTTTCTCCCACCTCTGGGGGCCCAAAGCTCTGGATGCCAC +CCTAGCCCTCAGCTGGCCTCACCTGTCTCCTCATAGCCCCACAGCTTGATGGTGTCTGTG +TGGGCAGCGCCTCAACGTGCCAGGTCAGGCTGAGGTTGCCTGAGGTGTTGGCGGTGCCGT +AGTATTGCCAATGCATCTCGTTCATCAACTCACTCTTCTCCTTCATCAACACTTTGTTGG +GGTGCACTGGGCAGGGGAGGTGAGGGGTGAGTGAGGGCTGGGCCCAGGGAAGCAGGGAGG +AGGCCCTGAGGCTTCAAGGGCTGTGGGAGCCTCCAGGGCCAATGCATGGCAGCAGCTGGG +TGATGGTCTCTCCGGCCCTCATGGCAGAAAAGGACGCTGAGGCCGGAGAGGCAGGGGCCT +GCCCTCCCTCCACTGCCCACGCCTCTAGCCTCCACCTGGCTTCTCCCCTGCCCTGGTGTG +GCGGAGCTCAGTGGATAGGCACTGGCCCACCTCTCTAGGGACCCCTGCAGCTCCCACTCA +CTCTGGGCTGGGACCGTGGTCTGGATGCCAGGGAGTGGAAAGGAGCTGAAGGAACTCTCG +CAGGCGGGCAGGCCTCCCAAGGGATTGGTTCAGCCAGAGAGGCAGGACACGGACGGGCCA +AGTCTCGGTGTGCATAGATTAGCGCTGGGGAAAGTCCCCGTGGGGGCAGGCTGTGGGCAG +GGAGGAGGGCTCACCAGCCAGCCAAGTGCCCGCACGAGGGAAGGAGTGGCCATCGTCCAG +TGAGATGGTGAAGGGGACGTGGCCGCTCTCATAGAGCAGGGGCGACACGAAGTGCACTTG +CCCGGAGGAGTCCACATGGCCGAGGGTCTGGATGCTCTCCTGTGGCATGCAAACCTGTGG +GCCTGGTGGTGGTAGGAGGTGCTGGGCCACTGCAGGCTGAGCATCTCGACAGTCTGGGCC +CCCAACCTCCCTGGGGAACCCATCCAACCAGCTGTCCTGTGCCCTCCTGCCTGTCCTGGG +TCTGAGGGGCTCCATTCAGCCTGCCAGTGGGTCTGAGCCCTCAGCATGCACAGGGATGGG +GGCGTGGGGCCCCAGTGCCCGGCCTCCTGGGCCTCCCAACCTGCAGATCACACTGGTGTC +TGTGGGGCTGGACATCTTGAAGTGCCGCACCACAAAGTCCTTGCCGCCCATCATGGAGAC +TGAGTAGGGCAATATCTCCAGGCAGAAGTCCTGGAAATCCAAGCAGCAGGTACCAAGGCC +GGAGCACGTCGGGTGGCAGGAACATGGCCTGTCCAGGGCGCCACAGCGCATGGAGCAGCT +CTCTTGGGCATCTGGAGGAGAGGATGCTGAGGGCCTGGCCTGGCGGGTGCTGGACTGGCT +GCCCCATGTGCAGGGCCTGTCTCTGTTTCTCCCACAGCCCATTAGACAGCAGCATCCCCA +GGAAAATGCTGGCCGGGAACTGCACAGGCCACCACGTTGATATGGTAGAAAGTCACAGGG +CCCGTGGGGATGGGATGAATCTTAGCATAGACCATCTGGCTGTTGCCCTGACTGATGGGC +TAGAATGCAGCGAGAAGAGGCAAAAGGCTGCACCCGCTCAGCCCTGCAGGGTCAGGAGAA +GCCCCCTGGGCATGACTGCCCTTCAGCCACCAAGTCCTCTATCCCACAGGCGGGGGTCCT +CAGAGGGCCACGGTAGCTGGAGCCCTCGACCTCTCTTGGCTCCCCAGGGTGTCTGTGAAC +AGTGCGCCTTCTGGGGGCCCTGAAGACTGCAGAAGAACCCCTTTTGCTTGCCTGGACTGG +GGTGGGGGATACAGCTGCCAAGAGTCCCATTCGAGGCCTGGTAGGGAATGGTGCAGGGTC +TGAACTTGACCCTTCTCACTCTCCCAGGGGCTGCAATTGAGACCCCAAAGAGAGCTCCGC +CCTCAGGGCAGAAGGCCAGGGCTGCTCCCCTCCTTTCTGGGGGGAGGAGGGACATTTCAA +GCAGGTGTCCCAGCAGTGGGGAAAGGGAAGTGGGGGTGCACACTGCGAGGGGCTGTGGGT +GCTGGGCCCAAAGCATCTCCTATGGGCCATGACACCCACGGCAGGGCCACATTTCCAGGG +ACTGGCATGGAGGAAGAGTTGCAGGGAGGGACTGGGGCAGGTGCGTGCCCAGCTGGGGGC +CCTGAAGGGAGACAGGTCCCATCCCCGGGCTCCAGAGATGCCACCACCCAGGGAAGCCTT +GGCTGTCCCAGCCACACCTAATCCTGCCGCTCAGAGTTTGCATAATTTAATCAGTGTTCA +CCTCCCTTCTTGAGCAGATGAGGAAACTGAAGCTCAGATGCGGACAGGCAAGGCCGAGCC +AGGCCCTTGGTGGCTTCTGGGAGCCCCTGCAGCCAGGGCGGGTGGTAAGGGCTGTGGCCT +GGGACTGGTCACTTGGGCCCTGCCACCTGGGCTGGACGTCCAGACAGGCGGGTGGTCCTC +TCCCAGCTGCAGCTTCTCAAGGTGTCCAAAAGGGACCCTTGCCACACTTGCAGGGAGTCA +GAGCTGGCCCCAGGGCATGAGCTTAGGCCATCTGGTCTGTGATCTGCCCCAGCGCTTGCG +GCCAGGCCAGCCCATTGTTCCCCAGCCTGTTCTCTCTCTTGCCTGGGTGGTGCCTGCTGG +GAACCACAGGGTGTTGGCAGCCACCCATGGCTCCAGAGAGGTGGGCCCCTACTGAAAGTG +TTAGAGGCATGTGCTGGGGGACTTGGCTCCTGAGTCCCCACACAGAGCTGTTCCAGGGAA +GCCACACCCGCATTTGATGTCTTCCCACCTCCCAAAGACATTTGGTGAGAGGCCCCCAAG +ACCTTCAGCTTCTCAGGACTGTTTCCAGAGGGGAGAAAGTCCCTTAACCCACAACGGTGC +TCAGGGTACCTCTGCAGGTGAGTGTCCTGTAAGTGGATGCTCAGGCGCTGAGCCACGGAG +AGCCTGTCTCCTGGCCCCAGGCTGGCGAGGGCATTCATCCCAGGCCCAGGGCTGAGGTTG +CTCCCTACAGCACTGGGTGCAGGTGTCCATCCTCCTGTAGGTGAGGCTCCGGGTGGTTCG +TCTGAGACAGTTCCCAGGAACTGGAGGAGGGAGAGCTGCTGCTTCCTGTTTCTGGCCTGG +GAACCCTTGCTGTGCGTGTCTGGAGACGATGGAAGTCCGGTAGGGGCTAGGTGTGCAGTC +TGGGAAGCTCCATACCACAGGCCCTGCCGTCAGCTGAGTAACTGAGGCTGGCTCATCTCA +GCCCCCCAAAGGTGGGTTCAGCCAGACCCATATGGGGCCGCCAAGCCTCTGGTTCCAAAA +GGGCAGTGCCCAGCCCTTTAGGCCTTTCTTCTTGGGTGGTGGGTGTGTCCAGCCCATGAG +GGGCACAGGGCAGTGAGGAGGGTCCCCATCTCCATCCTGGACAGAGAGCCTGCTCCATGG +GAGGTCCCAGGGGCCAGGAGGGCCCCTGTGGTGCTGGGAGGGGAAGAGAGTTGTGAAGGG +TGGGTTTGGGTCCCTGGAACCTGTGCATCCCCAAGACAGATGGGCCTGGAGCCTTCGGGG +GCGGGGCCAGCTCTAGGGGCTTGTTTAATGCTCTGTGGTGGCTGCCTTAAAATACTTAAT +CATTTTTGGTCAGGCACGGTGGCTCAGGCCTGTAATCCCAGCACTTCGGGAGGCCTAGGT +GGGCGGATCACTTGAGGTCAGGAGTTCAAGACCAGCCTGGCTAACATGGTGAAACTCCGT +CTCTACTAAAAATACAAAAATTAGCTGGGCGTGGGGACATGTCCCTGCCCCCTGCCCCTT +GTGCCCGCCCTCTCCCTCCCCCTGCCCCTTGTGCACACCCTCTGTACCCCCCTTCCCGCC +CCAGCCTGTGTTTGCAGTGCTACAGGGTGGCTGCAGCCTTCGCCTCCCACAGCTCCTCAA +GGTCAGAGGGCTGGGAACCCCTGGGATGTGGCTGGGATGAGGACCCTGCCCCTCGTCAGG +CATTTCCAGGCAAGGGGCACAGAGACACAGCCAGCCCAGCAGCTGAGCCCCTCCTATCAG +GCCAGGTGGGAAACTGAGGCATGAACACAACCCCAGACTGGAAATAACAAAGCCATCATG +TACTGTGTGCCTACTGAATGCCAAGCCCTATGCCCTATTCTTTAATGTCATCTTTAATGA +GATGTCTTCACTCAGTTCACCACATGATAGTAGACAGGTATTTATGATGCGCCTACTGCA +TGCTGGGCACTTTTCTGGGCCATGAGGACTCAGGGAGGTCCCTGCTCTGGTAGAAGTCAA +ACCCGACAGGAGACAGAGACTAGGGCCCCACACACCAGGAGGAAGAACCCAGTGCAGAGA +GTGCCAGCAGGAAGCCACAGGGGCAGGGAAGGCGCTCCTGGGAGGGTGGGTGGCTGCGTC +CTGAGGCTGAGCAGGGGGAGCCGGCCTAGGGACAGGATGTGCGCAGGCGTGGAGCAGGAA +GTTCCTGGAATGATGGGCAAGAGGGAGCAGGTCACTGGGGGCAGGTCTAAATACTGGGGG +CTGCATTGGGATAGCAGAGGCCTCGGACAGGCCCGCTCAGCATGTAGACTCCCCTCCCTG +GCCCCTTCCCTAGGATGACAGTGGAGGTCCATCCCCAGGTGGTGGTGAGGACACTCCTGA +CACAGAGACCCCAGCCCAGCTGGCAGGGGAAGGGGAGCCCTCAAGGACCCCTGTAGGTTG +GGGCATGTCCCGCCAGGCGGCCCTCCATGGTGCCCAGCAGCAGCCCTGCTTGCGGACCCT +CTTTAGTCCCCACTGTTAAAAAAATAATTCAGTGAAAATTGACACTAGCTGGGCATGGTG +GTAGGTGCCTATAATCCCAGCTACTCGGGAGGCTGAGACGGGAGAATCGCTTGAACCAGG +GAGTCGGAGGTTGCAGTGAGCCGAGATGGCACCACTGCATTCCAGCCTGGTGACAGAGTG +AGACTCCGTCTCAAAAAAAAAAAAAAAAAAAGAAAAGAAAAAAAGAAAAATGACACTTGC +CAAAGCGCCGTAGGGAAGACTGTCCAGGACCGTGTCACTAGGCATAAGGGACCACGGCGA +TGAGATTCTGCAGTGGGTAAGAGACTGGGCTCAGCCTCGAAGACAGCATGGGCAAGTGGG +ATCGGACCGTCAAGGAGCAGGGGGAAGACTATCCAGGACCGTGTCACTAGGCATAAGGGA +CCATGGCGATGAGATTCTGCAGTGGGTAAGAGACTGGGCTCAGCCTCGAAGACAGCATGG +GCAAGTGGGATCGGACAGTCAAGGAGCAGGGTGGGGGGCAGTGCATGGAAAGTGACTAAG +AGGAAGCATCAGCAGCCAGGGATTCTGGCTTAACTCCCCTAACAGAATTCTTGCTGAAGG +CCGGCCAGGATGGCCAGACCGCACCTGGGGGACAGAGGGGGAACCCGATCAGATGTCAAG +GACGGGGGGCTTCTCGCTAAACTGACTTTGCAGAATTCTTGCTAAAACTAGAGTTTATAA +GGAAGTGCTCAGATGTGCCTAGGAGAAGGCTCAGGAGCCTAAATAAAGCTTGACCAAGCA +GAGAATCTTTGTCACCAGCTTGGTGAGAGTGAGGCCCAGAGTGGGTCAGGGCTTACCTGC +TCAGGTTGTACAACTGGGAGGGGTCCGTCAGGAGCCTGGAGTCTTCCCACTGGGGGCTGA +GTCTGGGCCCTCAGGGCACATATAGGTAGATGCTGTCAGGCCCGACACCCCATGCAGTGC +AGACTGGGATGCTGGTGCCTGTGGCACAGACTGGTCAGACCCACCCCAGGCTAGACATTC +CTTGCAGGGAGAGCTGAGGCTGTTGATGCCAGGAACAGACAAACAAGGTCATCACCAGGT +AATGAGCTCGTTACCCACATCAGGCAAGGCCATTGCTGGGTAATCATTTGGCCTCCTGCA +GAGCCACCTGCCCTGGGACGGTTCCCAGAGATCTGGCTAGCCAGTGCCACAGGAGGCCGG +GGCACAGTTCCAGGGCCTAGTGGGCAAGGCAGGGGTATTCAGGGACAAGGTGCACCTGAG +TCCCCACAGGAAGCCCCAGACCCTGCAGTAAGACCTGGAACAAGTCATTCTCCTCTCTAA +GCTCTCAAAGAAGAGGTCAGCTCAGGGGTCGGGGAGGCAAGGTCTCCTAGAGTAGACTAA +GCTGGCCGCTGCCATGCTAACACACACCCTCCCAGCCAGCCGCTGGTCCTGACAGATGAG +GAAACTGAGGCTAGGTGTTTTCATGAGGCCTCTGAACCCAGAACCCAGTACCCAGTGTCC +TGAGCAAAGCCCAAGCCAGACCTGCCAGCTTATGTGTACAGAGGCCCCACTATGCAGCCT +GCACTCCTGGGGCCTAAAAGGACCATCACCTCCCCTTCTAAGAGGCTGGGCACAGGGGCT +GGGTCCCAGCCAGGCCACCCTTCCTCCTCCTCCAAAGGCCCAGCAGCAGCTGCTCCCAGA +GCAAGCAGCACAGTCGCAGCAAAGGCTGGACAAGTGTCCTGTGCTCTGTGGTCTGAGCAG +AGGGCCAGGGGCCGTGACCCACATGGCCCCTCCAGGAGCAGCTCCAAGATGAGCCTTCCT +GTCCCCACCAGTGTGTCCGGGACCTCAGGGTGGATCAGCCGCACCTGCCGGCTGCTCCTG +TTCCTTGCTCTTCCTGGGGCTCCCCACCACCTTTGGGAGGCAGCTCCAAGACCCTGCTGC +CTCCCTTGCTTACCCTCAGGCCCCTGCTGGGTGTGCCCCCTCCCCACACAGACCCCTGAG +CCAGCTTCGAGGACTCTGCCTGCATCTCCACGTCCACTCTGATGACTGTGAAGCTACAGT +CACACTCTCTGCCTCCACCCCCGCCCTGCCGGGTCCCTGCAGCAGCTCTCAGAGGCCCCC +ACAGCCCCTCCCACACACAGAGCTCGCCTGGCCCTGCCGTCTGAGCGCTCCCCTGGCTCC +CAACCGCCCTTGGGCTCTGGGACATAAAACCTCCAGCCAAGGTGGCTGCCAAGTTTTATT +TAATAGCCATAGAGCACAAAAGGGATGACAATTAAGTCACACGGAGAGACTGCCCCATCG +GGACCCCTGGCCAAGCTAAGCAGAGGAGCCCTGGGGTTTCCTCTGACCCCCCACTGTGAA +TGCATTACTGACGGGCAAGGTGGCCAGTTGCCCACCCAGCCTGCACGTCTGCATGCACAG +AGCTACAGCCTGGGCCCAGGGACAGCCCCGGGAGCCGGTGGCTTCCCACAGGCACAGCCA +GCCTCCCCACCCCCACCATGCCTGGCCCCCGGCCCAGGGCACACTGAGGGGAACAGGAGG +GGAAGGAGCAGGCCCTGCACTGGAGCCTCAGTCAGCTCCTCTGTGCCAGGGGCAGCTGGA +GCTGGCTGAATTTGAGGAACTTCCCGGAGGAACTGGAGAGCAGACCTGTGTGCGCGCCCC +GCTCTGCCACGTTCCCTGAGGGACACACTGCTTTGACCAGCCCCCACCCCATCTCCTCTC +CGCCAGTCCCCGGTGTCCACCCCAGCCCCGCTACCGATGAAGCTCAAGCCAGGGTCCCCA +TCACCTGCTTCACGGCCATCCCTGCACTTGAGCTCAGGGGCTCAGGGTTGTGCTGACACG +CCTGCCTGTCCACCCCTCACCGACACCTCTGCAGTCCTCCTCAGGGCCCAACAGGGTCCC +CAGGACCCCGCTCCCATTCTGCCCTTGCTCCTGCCAACCTGTCTTCTCTATGCCCATGAC +TTTGGGACCCTCTGCCATAAGTACCAGCCCCCACATCTGTAGCCTCTGCAGGAACAAGCC +CTAATCTGGACTCATTGCAATGGCTCAGGTTCTCTTCCAGCCTGTCCATAGACCTCCAGG +CAGAGATCACAAAACTAACAGCTCTTTCTGCAAATCTGGACTCTCTCCTGCACCTTCGCC +ACCATCCAGGCCTCCCTGTCACTCCTCCTGGGGACCTCAGAGATCTCTTCATTTCACAGG +TGAAGACTTGGCTCAGAGAGGGCAGAGCCCCTGGGTCACACAGCCCGTCTCCAGTAGGGC +TGGGGAAAAGAACCCAGGGCGCTCTTGTTGGCAGTGTTTTAATGACTGGGGGGAGGGAGA +GAATGGCTAATGAGGCTCTAGGGATCAGCAGAGCCAGCTGCTGGAGGTCCCAGAGGACGG +GTGACTCAGCAGGAATGGGGGAGTCTGAGGGGTTGACAGAGTGCCCAATTCTCACCTCCT +CCTGCACCTTCCAGGGAGACGAGCTGCAGGGAGTGATTGAGTGGATGAACATGACTAGAG +GGACCCAGTCTTCTCCTCAGCAGCTGCTTGAGGACAGTATTAGCGGTCCCCTCAATCCCC +CCCCCAACACATGCACACATGCACTGATCTGCAGGGGCCAGACCCCAGTGGACCCGGGGA +CACAGCTTCCAGGGGCTGTCTTGCCATGTCCCTTCCCAGACCTGCCTGGATTCATGCCAG +GCCACCCTCCACAATTTGCTGAGGGAGGCCCCAGGGTCCAGGGCACCCAGAGTGCTAACT +AGCCCCTGGGGGTACAGGGAGAACAGCATGCTGTGTGGGGGATACTACTCTGCCCATACC +TAGGGCCCTGTGGCGGCCACAGGCAGCACTGCTTATGCAGAGGCACTGGGGTGAGAAGGA +GTAGGGTGCAGTAGTGAGGGCTCCACAGAGGGTGGAAGGGCTGCAGGGGAAGGCAGACCA +GCAGGGATGCCATGAGGGCCTCAGATGCCAGGCTGCAGAGGTGGAGGGGCTGGCCAGCTC +CTCTCCCCAGCCTCCTACTGTAAAATGGGAGAGGATCCCAGCCCTGCTGATTCATCCACT +CACTCCATGGCAAGACAGCCACTGACAGCTGTGTCCTGGGGCCCACCCGGGCCTGGCCTC +TGTGCAGGCTAGCACTCAGCATGCTTAGTGCCACACTCGGCCCAGGAGAAATGACCCAGC +CCTGGGCTCAGAGACCCCACAGTGGGTGGATGGAAAACAGAGTCATTTAAATACAACTGT +GAAGGGTGCTGTGGAGGAGGGGCTCGAGGTCCCCAGTGTGGGATGGGGTGGTCATGGAAC +ATTTCCCTATCTAAGTGGGAAAAGTGAGAGCCACCAGGAAAATGGCAGGGGTTGGGGGGA +GAGGAACTGTGCAAAGACCCAGAAGGATGAAGAAGACTGTTGGATTAGAGGAGGTTAAAG +ACACAGACAGGCTTGGACATGGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCAA +GACAGGAGGATCACTTGAGGCCAGGAGTTCAAGACCAACCTGGGAAACACAGTGAGACCC +TATCACTACAAAATAAATAAATAAATAAAATAAAATAAATAAAAATAAAAATAAAAAAAG +CCGGGCATGGTGGTGCACGCTTGTAGTCCCATCTACTCAGCAGACTGAGGTGGGAGGATC +GCTTGAGCCCAGGAGATGGAGGCTGCAGTGAGCTATGATTGCACCACTGCACTCCAGCCT +GGGCAACACAGCAAGATCCTGTTTATAAAAACAAAACAAAACAAAAAACCCAGCTTGAGA +TGGCCAGGGATTTCCAGAGGCCCTAGGCGGGCCACCTTGGAGAGTAAGGGAGACCCTGAA +GAGCTCGCATGGAAGGACCAGCAGCTTGGGGCTGGAGATGCCACCTGGATGGATTCCTCC +AGCTGTGTGGACTAGGGGACAGGGTGAGGAGATAATGGCCTGGACTACATGGAAGGACGT +CGCCCTGAGCCATTGAAAAGGGCTGTGGGGTCCATGACCACTCCTGGCCTTCCCTTGACT +ATGATGGAGACAGTAGCTTCTAGTGTAAAATGTGAGCTCAGTTCCTGACTCGTGTCTAGC +GGGTGGTGCCTGGTCTTTGGCTGGCGATGCTCCATGTCACCTATGCCCAGAAACTGGGCC +ATGCCCTTTGTGAGGACCTGCCCACAACGTCGTTGTTCCCGCAGGGTCCCCGGGGAACCG +GGCTGCCCGGGACCCAGCCCTGCCAGGGTTCCCTGCGGCCCAGGCCGGAACCCCCAGGGC +TTTGGTCGTTCCCAAAGCCGTCCCGCGGGCCCCCTCCACGGTGCGTCGCCTGGGCCCCAG +CGATGGCTAGGCTGCAGCCTGGGGCTCCCGGCCATCCCGGGCGCTGGCGGCGGTGGAGGC +AGCAGGGCGGATGGCGACGCCCGGCCGCCCGTGGGCCCAGGCGCGTAGTGCGTACAGAGC +CAGCGAGGTGCTGCGGCGCGTCACGGGCCGCCGGCGGGACCCGGGGCCGCAATCCAATGG +GCCGGGCCGGGAAGACGCCCGAGCCCCGGGCCGGCTGGCTCGCCTGCTCCGCCAGCTCCG +GGCCGAAGCGGCTTCGCGGTCCGAGGTGCCGCGGCTGCTGAAGCTGGTGGAGCGTGCGGG +GGCCGGGGCGGCGGGCGCGGGCGAGAGGACCGGCGCGCACAGCCGCGGCTCCGTGTGCTC +AGTATGCGGGGAGCCCCGCGGCAGGGCCACCTACCCGGCGGGGGTCCTGGAGGTCAGCGA +GCGGCGGCTGCAGGAGGGACTCGCGGCAGTGCGCGAGGAGCTGGGCGCCGAGATTGAGGC +GCTGCGCGCGGAGCTTCGAGCGGAGCTGGACGCTCTGCGCGCGCTGCTGCCGCCGCCGCC +GCCGTCCCCGCCTGCCCGCCGCGAGCCCCGCGCCGTCCCCCGCGCCGCGCCCCGCGGCCC +GACCCTGCTGCGGACGCTCGGCACCGTGAGCGCCCTGGTCGCCGCCTCCAGGCCCGCAGA +CGACGCCCCGGACGGCCCAGCAGAATGCGGAGCGCACCGAGCCCCGGCCAGGAAGAACCA +CAAGAAGATGCCAGTGCCGCCTGGGGCCCCGCAAGGTGGCGGGGACTGAGGGCGGCCGCA +CAAGGGCAGCCTAGGCGAGGTGCGGAAGGCGTCGCGCTGGCTACTCTGGTACCCCCAGGA +CGGGGCAAGTGAGCAGATCGGTCCCCCTCGTGTAGCGTGGCTCTGAGTCAGAAGGGTGCC +CGGGTGCCGCCAGTTAGGGCTCCGGTACTGGAGGGAGGGGGTGGGCGCGGGACGGGCGGA +GGGTGGGCCACGTGCGTCTGGGGAGTGCGGATGGGAGCCGGGGTCCTTGCGAGAGACTGA +GTCCGGCTAGAGAACAGGGTGGAGCCCCTTTGGACCTTAGAGCTGGGCCTTTGGGCCTTG +GGTCTGGGTCAGCCTTTGGGCCAGGGCTGGGTCAGCCTCCAGGGGAACAGCCGAGACTCC +TCTTCCTTGGGGTGACTGCACGTTCTTTTTCTTTCAAGGTCTCAGTGACGAGGCAGGGTC +TCCACGCACTGGAATAGTGTCAAACCACACACAAGGGCACAGAACCCAGGGACACAGGGC +GGCTGAGACACGCAGCTGGTGATGGCCCTCAGGACGGTGTCAACCAGTATGTAATCACAT +TCCACACGGCACCAATTGGACAGCGGCCTCCGGTCAGCCTCACTCTGACTGCAACCCCCT +CTCACTGGACAGCATCACCTGGACACAGAGCCTCACCTAGTCTGTGTCCCGTGGACACAA +CTTTGCTTTGGACAGTGACACCAAGAATACTCACCCCTTTACTTAGCCAGACCACAGGCA +GCCACCGGGACACAAACATCTCTCCAGAGTCACCCTCCACACAGACTCCACAGCAGAACT +CCCAGGGAGGCACTGGGGCATGGCTTCAGAGCACCAGGCAGCGCTCCGCGGTGCCCAGCA +CCCGCTCAGCCAGGGCAGCCTGCAGCGGAGCCTGGAGCCAGCAGCTTCTCATCTCTTGGC +CTCGGGAAATGTAGCTGGAGTCATCATTTAGCAGAGCACGGTGTCCCTGGGTTGGCCACC +CAGCTTAGTTTTAAAATAAAATAATGTAATCTTGGCCTAATGGTGGAATTTCTGACTGCT +AGATGTTCTCCTTCCATCTGACCAGGGGATTCAGACACAATGTATAGGATGAGGGTGGGG +GCCCTTCTCCCTCTGAGAGGAACCTGGAGAGGCCCGGGTTCTGCTGAGGTAGGAGAGGGT +CACTCAGAGGGCTCCCACGGAACAGACAGGCACACTGAGGCCTCAGTGGGATTAGGGCAG +GAAATGCCCCTCTTGCAGTGGGGGACCGCGCCGGGTCACGCACCCACCCCCTCCAGGCCA +CATTAGGCTAAGGTCACTCTGTGCATTATTTCATTATTTCACACGGAGGGTCGCCCACGG +TTGACAGAACCACAAGCTGAGCCCCAGGCGCATCAGAGCGCAGTGCACACCTGCTAGGGT +GGGGGAAGAGCGGGGGGCTGCTGCGGGGACCGAGGCTCTGGGGGAGGCCAAGACTGTGTG +CCCCTTAAGAGGCTGCTGTGGGCCAGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGCGGATCACGAGGTCAGGAGATCGAGACCATCCTGGCTAACACGG +TGAAACCCCGTTTCTACTAAAAATACAAAAAATTAGCCGGGCGTGATGGCGGGCACCTGT +AGTCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATGGCATGAACCCGGGAGGCGGAGCTT +GCAGTGAGCTGATTCCACCACTGCACTCCAGCCTGGGCGACACAGCAAGACCCCGTCTCA +AAAAAAAAAAGAGGCTGCTGTGGGCGGAAGTTACCCGTGAGCGGTATGGGGTGAAAGTGG +GAGGGTCCAGCCTGGGGCACGGTGTGGAACAGGGTCATCTGAGGGTGCAGGGCAAAGAGA +TCAAAACGGGGTGGGAGAGGGGCAGCGCCTGCGGGAGGAGCCAGGCAAGGCCCGGGGAGG +GGTGTGGGGGGCGAGGGGGGACGGTGGCTCCACCTGCACCCACCGGATGGGTATGGGGTC +CTCGAAGACGGTCCAGAGCACCGTGGGCTCGCAGTCAGGCGGGGTCAGTGACCCAGCGAA +GCGACAGTAGCTCGAGGTGTTGGGCCGCATCGACGCCAGCAGGAAGGTGGACATCAGATT +CACTGAGAGCCCCAGGCGGCAGAGGGAGGGGGATTGGAACCAGCCTCCCCGTGCCCTGCT +GGTGCCATCCCCAGCAAACCCCCCGCCCCTGAGCCGGAAAACGACCCGGTGGCTCCTCAC +CTGGCTCAGGCACCTTCCTCAAGCCCGACACTATGGCGCAGAAGTTGGTGTTGCTACAGT +CCTGCTCCTGGGAGGGGCTCCAAGTGCAAGGGGTTCTGAGTGGGGGAGTCTCTGAAGAGG +GAACTCAGCTGGGATACTCTAAGCAGGAGGCTCCCAGTGGCAGGAGGCATCTGGCATCTG +GGAAATGGGGTGGAGGGTTCTCGCCGCCACTGGCCCTGCCGATTCAGGCATTCCCACCGC +CCTATCCTCCCACAGATCCTATAGACCCTAGAGATCCCCCCATGGACTCCACAGGCCTAG +CCTGTCCACTTCCAGGATCCCCATGGACCCCTTTTTTGGAAACATACATAGAATCACAGC +CCTGCCTTCACCGCCAGCAGCACCTCCAGCAGCAGGGCCTGCACTCGAGCCCATCACCGT +GGCGTGGTGCCTCCTCCATGCTCTGGTACTTTGTGTTACTGTGGACCACATGCATCTGGG +GGTAGGCACAGATGTGGGAGATACCCAGCTGCCCCCACCTTGCTCTCTCTCATCTCCGTG +GGAGCACTCCGGCCACCCCACCTTGTGCCCAAGTCTACCTCCATAGCCTGGCGCTGCCTG +TCCAGGCTGTGCTCTGAGTCTGCTCGCCTCGGGCCCCCCCCCCGCCCCCAGCTGATGTGC +AGCCGCAGTGCGCGGTAGACAGGCAACAGCAGCCCAGCCTCCCAAATCTCCAGGTGGTTC +TGAGGATCAGTGTCCATTCAGAGTAGCAATGAAGGGGAGGAGGCACACGACACCCTCTCT +ACCTCACCACCTGCCCACCTTGTGCCATTAGAGCACAGGGTACGAGCAGAGGCCCTTCCT +CAGGCCAGGCTGCTCCCCAGTGGGGCCCCATTGCCTCCATGGAATGGAACCCATGGTGTC +CATGGCTCCTGCTGGTCAGCAGAGCAGAGTTCCACAGACTGCAGGGGAAACCCTCCCCCA +CACACCCAGCATGGCATGGAAGAAGGCAGAGGGCAGCCCTCCTGGGGTGGGGCTCTGAGC +CCAGCTGTGTGTGGTCAGGGATCCTGGCCCTGCCAGAGACCCTGACTCCTGGTCCTCAGG +GGCCATGGCTGGTTGTGATTTGTAGGGTGGGACCTGGCACCTACACAGAGGGCGCATCTG +GACTGCTGTGTGAGGATGCTCCTTTCCTGTGAAGCTAGCCCCTGTGGAGGGTTTTTGGCC +CTGTAGGATGTCTCAGCTCCCGTGTGTAGGGGGTCCTGGTCCCTGTGTACACTCAGGAGC +TCTCATGCCCTGTGTGGGGCTCCTGCTCCTGCCTAGGAGGGGTCCTGACCACAGGGTGCT +GACCTGTGTGGCTGTCATTCTCCAGGGTCCAAGGGCCTGGAGGTGCTGAGTCATAGCCTC +GGAAGATGAAGGGCCCTAGGGTAGAGTTCCGCCGGACCCTGTGAAAGTCAATGTCGATGA +GGGACTGGCCTGGGCCCCCACAGGCAGGGGCCAGCTTCTTCCAGTGGGTGGGGACTGCTG +GAACAAGGACTGGGGCCTTTGGGGTGGGGGTGGGGTCAGGGAGGCAGCCTGGGGGTGCAG +CAGAGAGTGGCCCCCATACACCCAGAGGATAGCCCAGCCTCAGGAAACCCAGCTCCCTGC +TTCCCCCACACCTGAACAGGTCACAGCATCCCCCTTCTCTTGTACCCTGCATCTGGCCTA +TCCATCTAGTCTCCCGGTTGGCTGCCCCATGGTGAGATGAAGGCAAAAGAGTCTCTGGCA +CACAGTTGCACACCCACACTGGGACCTCTATCACCTGCACACACTTGGGCTGGCCACAGT +AACAGGCACACCAGCCTTGACTGACTCGGGACCGGCGATCACAGCAGGCCCAGACTCACA +CACAGGGGGACAGTCACGCACTTGCACCTGATGCCCAGTCAGTCTACTGGGGCAGACGAC +TACAGACAGAAACCTGCAAAGGCCACAGAGTGCAGGGTGCAGACTGTCTCTTGGCCACTC +TTGCACCACTGGCACATGCTCTGGTGGTCCCAGGACACAGACTGATCTCACTCAGCCTCA +CATGACACTCTGTCCTCACCACACTTGGGGTCCTGGGAGTCGTAGCACCAGGCACCTATA +GAGACAGTGGGCAGGAGGCTGAGCTGAGAGACCAGTCATCTGGGTCCTCTCCAAGCCCCA +TCCCATCAGCTGGGGTCCAAGAATGAAGTAGGCCAGGGGCTTAGGCCAGGGGAGGCCAGT +GAAGAACCTTCTCTCCTGTCACCCCTACCCCAGTATTTTCTCTCCCCAGTCCCTCCCCAC +TCCCAGTGGCAAGACCTAAGGGGTGGTGGAGCATGGCAAGAGGGTAGATTGGAGACCAGA +CGGGAAGAGTCCTGGTGCTCACTCTCAGAGTCTGCGCCACACCAGCTGCACTGCAAGGCG +AGCATGATGCCAGGGGCGTGCGTGGCTCAGTGGCAGCCGCAGCTAGGAAGGACTAGAAAG +TGGCTAGACCTCGGAGCCAAGATGCTGGCCTGGCTACTACATATTTATTCATTAGCTAGC +TGGGCTAGGGGCGTGGCTATTGAGGAGAGGATGGGAGGGGTCGGTGCCCAGGCAGGGCCA +CCAGGAAGAGCGCGAGCGCTCCAAACTCACCCAGGTGTGCTGTGGTCCCAGGGCTGCACT +GATGCCAGCAACAATCGCTGAGGTTAATCCTGCAGGGGAGGGGTGACCTATTATTATCCC +CACTTACAGTCCAGGAAACAGAGGCTGGGGACCAGAATGACACACCAAAGCCACCAGCAA +GAAAGGTCAAATAGTGAGGGCACCTTGAACCCCAGCGCTCATGACTTTCGGGGCAAGGAT +GGGAGGAAGGTGTAGGATGTCTCTTGCCCCACTGTGGGCCTGGAACTGCCACCCCATCCC +AAGACCACAGCCTCCCTCCTGCCCAGGCCCCCCTGCGGATCCAGGCCAAGACGGAGCCCT +GCAGGAGGTCAGAGGAGGGGACTTCTTTGCACCCTGCGCCTCTTTCCAATCGCCAGAGGG +CAGGGCCCTACCCACATTGGGGATGGGAAGTCAAATGCAGAAGTTAGGTGAAGTCAGTTC +TTGGATACTCCTGTACTGTCACCCTGGTCTTATCTCATGCCTTAGCCCAAGCTGTGCACA +CAATGGGGTCCTAGGTCCCCCTCACCTCCCAGATTCCACCTTCCCAGGGATGGGACCCCC +TAGAACCCTCGGGGGCCTGGGCAGTGGCCTTGCTGGCTCTTGCCTTCCTAGGAGCTGAGC +AGGAGCTCCACTCTCAGCAGGGCAGTTCACTGCAGCCTCTGCTTCCTCAGCTCAAGCCAT +CCTCCCACCTCAGCCTCCTGAGTAGCTGGGAATGCAGACACACACCACCACGCCTGGCAA +ATTTTTGTATTTTTAGTAGAAACAGGGTTTCACCATGTTGCCCAGGCTGGTCTTGAATGC +TTGAGCTCAAGCGATCTACCCACCTCGGGCTCCCAAAGTGTGGGAGCCAAGATGGGAACC +CAAGCATACGGCCCCAATGCTGAGGCTCTGAACTACTGACCTGCCCTCAGCACTCAGCCT +TGGGATCATGAGTCACTGTGCAAGGGAGTTCCAACATCTGCATGTATGTCTGGAATGATC +TGAGCCTGCAGAGTTCCTACACACTGGCCACATTATAGGGTGGTGTCTGTGGTCACACAG +CTCAGGTCAGGTATTTATTAGTACATGAATAGCTTAGCTGTGTCATAGTCTTTATGTGAA +AGGCACATAAAAGGCACTTTGGCAGGCTCAAAGTGTGGGGATTATAGGTGTCAGCCACCG +TGCCTAGCCCACTGGATGACTTATGATATCATATGTGACATTGTGACATCATGTGAGTCA +GGGATGTACCCCGTTCTCAGCTGCTATATGCTATGTTACAGTGACAGAATGGGAATGAAG +AATGTGTCCCACTCTCTCAGCTGTTGTATTATATCATACAAGGTGCAGTGACTAAGTGTG +TCAGCTGTGTCCTCATCCTACATAGCATATGAGAGTGTGTGACGGGAGATAGGATGCAGA +CCTGAGAAGCATTAAACACCTAGGCAATAAAGGTGCCAGCATCAGCTGAGAGCGCAGGTA +GACCTCAGTCACATTTGTTACTGTGTAACTAAAAATACAAAATTAGCTGGGTGAGGTGGT +GCACGCCTGTGGTCCCCACTGCTCAGGCGCCTGAGGCAGGAGAATTGCTTGAACCCAGGA +GGCAGAGGTTGCAGTGAGCTGAGATTACACCACTGCACTCCAGCCTTGGGGACAGAGTGA +GACTGTATCTCAAAAAAATAAAATAAAATAATCTAGGACAACCAAGAGAAGGACTCAGGC +TCACCTTACTCTATGTCACATGTGATATATAACACTTGAGGGGGACACACACTTGTCACT +TTGTATCACTATGTCCTATATGATAGCCAATGATAACCCAAGAGGGGGAGGCAGCCTTGT +TCACACCATGTCACTTATGATATTATATGACATCAAGGAGCCCAGACCTCAGTTGCATTA +TGTCACTATGGCACATACAGTATCATGCAACAACTGACAGAAGGGTTGTGGGCCTGATTC +ACAGTGTATGTGAGTCACAAATGTCACTTATGACACCATACAGCAGGTGAGAGGGGATAG +TCATTATTCACCTCGGGTCACATTGTCACACATGATACCATATGATAGCAGAGGGGGATG +CAGAACTGAGTTGTATTATGTCGCTATGTAACCTGTGATAGATGATAGCTGATGCGGGTG +AAGACCAAAGTTACATTTTGTACCTACATTATATGAAATATACAACATGCACGAGGGAGG +TGCAGACACAAATCACACTGTGTGCTGTATCCCATATATGTGTTTAATTTCTGTGTTTAA +GAGAGCTGGGTTCATGAATGAACGTAGTCACTGCACCTTGTATGATATAATACAACAGCT +GAGAGAGTGGGACACATTCCTCATTCCCATTCTGTCAGTGATTGACCACACCTTGTGTTA +ACTGTATGAGCCACTGTGTTTGGCCGTGTATAGCGCACGTGGCACATTGTTCACTGATAC +ATATTTGCTCCGTACTGAAGTGAGGCAGATGCATGAGTGATTGAGAATAATGCTACCTTG +GTGAAGCATTCCATTTAGAAGCATGAGGTTCAGGTACTACCATCTTCTGTGATACATATT +TAAATGTTAAGTTTAACAGTTAGGTCTACCATGAGTGAATGAGCCTTGCATTATCTTTGA +GAATCGATGTGTTTAGCAGGGTGTGGCTCATCTAAGATAGCCTTCTTTAATGCATGTTCA +CTATCTGTGTTTATTAGAAATAGGTTTGTGAATGACTTAGCATAGTGTTTTCCCTATGAA +ACCCTGTTTATTTATTTATTTATTTATTTTGAGATGGAGTTTTGCTCTTGCAACCCAGGC +TGGAGTGCAATGGTGTGGTCTCGGATCACTGCAACCTCTGCCTCCCAGGTTCAAGCGATT +CTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACGGGCGTCTGCCACCACACCCAGCTAA +TTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTCGAGCTCC +TGACCTCAGGTGATCCTCCTGCCTCAGCCTCCCAAAGTGCTGGAATTACAGGCGTGAGCC +ACCACACCCGGCCAAAACCCTGTTTTAAGAAGTGTGTGGTGCAGGTACTACATTCTTTGT +TGTTCCAAGTTCAAACCCTGTGTTTAACAGAGATAGGTGCAAGATTGCCTAGGTGTAGCG +TAGACTCTTGGAAATACTGTGGTTAGCATTCTGTGTTTTCTGTAGCATAGTTTCAGTGAT +GCCTGTTTAGATAGTTTATCAGATCTAGGTACTAGTGTTATGTCAGCGAAACACTGTTTA +GCTGCACGCGGTGCATGTAATACTTTGTTCATTGATATTTGTTTAAATCAATCAGTGTTT +ACCAGAACTAGATATGTGAGTTACTGAGAATAGCCTAATCTCTGAAAATGTTTTCCAGCC +TATGGTGCATGTAATATACTCTTCTATGGTACCTCTTTCCAATGTTTTTATTGTGGCAAA +ATATACATAACAGATTATACCATTTTTAAGTGTAGAATTTAGTGGTAGTAAGTATAGAGA +GAACCTTAAAAGCAGCAAGAGAAAAGTGACTTCTCATGTGCAAGGGAGCCTCTAGAAGAT +TATCAGTGGATATTTCAGCAGAAACCCTGCAGGCCAGAAGGTGGTGGGATGATACATTGA +AAGTACTGAAAGAGTAAAGCCTGCCAACTGAGAATACTATATTTGACAAAACTGTCCTTC +AAAAGTGAAGGAGAAATTAAGACATTCCCAGATAAATAAAAGCTGAAGGAGTTTATTACC +ACTAGACCTGACCAATAAGAAATAATAAAGGGGCCAGGCACAGTGGCTCATGTCTGTAAT +CCCAGCACTTTCGGGGGCCGAGGCAGGTGGATCACCTGAGGTCAGGTGTTCAAGACCAGC +TTGACCAACATGGCGAAACCCCATCTCTAATAAAAATACAAAAATTAGCTGGGTGTGGTG +GCACGCACCTGTAATCCTAGCTACTCAGGAGGCTGAGGCAGGAGAATCACTTGTACCCGG +GAGGTAGAGGTTGCAGTGAGCTGAGATCACACCACTGCACTCCAGTCTGGGCAACGGAGC +GAGACTTCATCTCAAAAAAAAAAAAAGAAACAATAAAGGGAGTCCTTCAAGTTGATATGA +AGGGATACTAGACAGTTGCTCAGCCTGATGAAAATATAAAGGTAAATACATAAAGATTAA +AACCTGTATTATTGTAATTTTTGCTAATAACTCAATTTTTAATACTTTAATGGAATTTAA +AGGACAAAAGCATAATAATTATAAATCTATGTTAATGGATACAAAGTATATAAAGTTTAA +TTTGTGACATCAGTAACTTAATAGTGGGGCAAAGATGTAAAGAGTAGAGGTTTTGTATGT +GATTGAAGTTATCTGTTTAAAATAATAAGATAACTTTAAGATGTTCCATGTAATTCCCAT +AGTAACCACAAAGAAAATACCTACAGAATATATGCAAAAGGAAATGAGAAGGAAATCAGA +GCATAGCACTACAAAAAATCAACTATAACACAAAGGAAGACAATAAGGGAGGAAAGAAGG +ACAAAAAGGCTCTAAACATACAGAAAACAATGACCAAAATGGTGGTAGTAAGTCCTTCCT +AATCAATAATTTCATTAAATGTGCATAGGTTAAACTCCCAATAAAAAGACATAAATCGGC +TGATTGGATTTAAAAAAACGGGATTCAACTATATATGCTGTCTACAAGAGACTCATTTGA +AATCCAATACAAATGGGTTGAAAAATGAGAGAATGGAGAATATTCCGTGCAAAAAGTAAC +CAAAACAGATCAGGAATGGCTGTACAAGTTATGGCTGTACAAGTTGTTGGGTTTTATGTT +ACTGAAGAATGAACAGAGATGAGTAAGTGGAGGTGTTATGTAAAGGCATACTGTACTCAA +AATCTGAAGACCTGCAGCAGATTTAAATTCCAGCTCTTATTATAACTTTTTAAAAGATTG +TGAAAATATCAAAATATAGATGAATCAAGTTTTAATATACTGTATGATGGGTGGATGAGG +CTGTCCATTGTACCATTTGTTTGAATTCTCAGGCATGGTTTGGCAGTGCAAGAACTCTGT +AACGTTAACAAATTCAATAAAAAGTAAATATATGGAAAAAAAAGTATAGACAAAATAGAT +TTTAAGTAAAAAACTATTACAAGAGAGGGTTCTGGGAAGAAAGTGGAGTAGGAAGCACTG +GGAATTCATCTCCCCACCTAGAAAATAATCACACTGGCAGAATCTGCCTGATATAACTAT +TTTGGAACTCTAGACTCTATCAAAGGAGGCTTGTAACCTCCAAATGAAGGCTTAAACTAT +AATTTTTACTTAATTTTGGTCAATTTCAGCTCTTAGCTCAGCAGTGGCTACCCAATCCCC +ATGCCCCAGCTTCACGGCAAGAAGCTTTGCATGTGTTCCTGAAGCAGCTTGTACCAAGCT +TGTGGGAACAATCATGGGCAATAAGCACTCTGTCCTCCAAGTGTTAGCATCTGCGTTCTG +GTTGTTGATTGCTACTTTTGATTATGGAAGGGCAAACACAGAGGCTGGCAGCCATTATTG +CTCACAACTCCCCACTCCACTGCTGCAAGCCCTTACCAGACTGAAGCAACTTCTAGGAGA +TAGAAAAGGCCAGAACCCCATTTCCCTTCCCCTTCATTGTTCTCTTTTCCTTTTTTGGGA +GCCAAACATTAAAGACTAGGACACTCAAAAGCAATGGCATACCCAGAGGAAATTAAAGTT +ACCACACATCCTTGGAGAGAGGAGTGTGTGCCCAGGGAAAGGAGCAGCTTCAGACCTGAG +AAGACCTCAAGCTTACAACTCAGGTTGATCCTCAGCATGGAGACAACCTACAACAATGTA +AAACATAACAAAACCCCAAAACAGCAAACCCTGAGGAAGAGGAGAGTCTCATCTCCAGAG +TTACTGCATTATTATATTCAAGTGTCCAGTTTTCAATACAAAACACAAGGCATACAAAAA +ACAAGAAAATATGGTATTTCAAAGGAAAAACAACAACAGAAACTGTTCCAGAGAAAGACC +AGATGGTAACCTACTACACAAATACTTTAAAACAACTTTCTTAAAGATGGTCAAAGAACT +GAAGGAAGATGTGGAGAAAGTCAGTAAAATTATGTGTAAACAAAATGGGAATATCAATAA +AGAGATAGAAAACCTAAAAAGAAAAAAAATAAATAAATTCTGGAACTAAAAGTGTAGTGA +TTGAAATAAAAGTTCACCAGAGGGATTCAAAAGCAGATTTGAGCAACAGAAGAAAGATTC +AGTGAATTTGAAGATGGGACACTTGAAATGATCAAGTCAGAGGAACAGAAATAAAGATGA +TTGTTGAATAGCAAGCAGACATTGTGGAAGTCCCAAAAGAAGAGAGGGAAAGGGGCAGAG +AGATCATTTGAAGAAATAATGGCTGAGGCTGAACACGGTGACTCACACCTGTAATCCCAG +CACTTTGGGAGGCCAAGGTGGGTGGATCACAAGGTTAGGAGTTCGAGACCAGCCTGGCCA +ATATGGTGAAACCCCGTCTCTACTAAAAACACAAAATTAGCCAGGTGTGGTGGTGCATGC +CTGTAATCCCAGCTACTTGGGAGGATGAGGCAAGAGAATCGCTTGAACCCAGGAGGCAGA +TGTTGCAGTGAGCCGAGATTGTGCCATTGCCCTCCAGCCTGGGCAACAAGAGTGAAACTC +CGTTTAAAAAAAAAAAAATTAGCTGGGCGTGGTGGCACGTACCTGTAGTCCCAGCTACTC +AGGAGGCTGAGGCAGAAGAATCGCTTGAATCCAGGAGGCAGAGGTTGCAGTGAGCCAAGA +TCACACCACTGTACTCTAGCCTGGGCAACAGAGCGAGACTCTGTCTCAAAAAAGAAAAAA +AAAAAGCTGAACACTTCCCAAATTTGATGAAAGACATGAAAATAAATATCCAGAAAACTC +AATGGACTCCAAGTAGGATGAAAAAAAAAAAAAAGACTCATACTGAGACATTATAATTAG +CCAGTAGGGCCTCTTGAAAGCACCAAGAGAGAAGCAACTAGTCACATGCTAGGAATATAT +AATAGGATTATAAGTAGATTTCTCATCAGACACTTTGGAGAACAGAAGACAATGGGATGA +CATATGTAAAGGGCTAAAAGAAAAACAACCACTACCTCTCAACCAAGAATCCTATATCCA +GCAAAACTGTCCTTCAAAAGTGAGGAAGAAATTGGGAAATCCCCAAATAAACCAAAGTTG +AGAAGTTTGCTACCATTAGACCTGCCCTGCAAGAAATCTTAAAGAGAATCATGCAGGTTG +AAAAGAAAGAACACTAGATAGTAACTCAAAGCCATATGAAGAAATAAAGATGCCAGTAAA +AGTAAATATATGGGAAAATATTAAATCTAGTATTATCGTAACTTTGGTTTAAAACTCCAT +GTTTTGCTTTCTACATAATTTAATAGACAAATGCATTAAAAACAATTATTAGTTTATGTT +TATGGACACACAATGTACAAAAATGTAATTTTGTGACATTGATAACTGAAAGAGGAGTGG +CAAAACTGTGAGGAGAGTTTTTGCATATTATTGAAATATAGCTGGTATGAATTCAAGTTA +GAGTGCTATAACTTTAGAATGTTAAGTGTAATCCCTATGGTAACCACAAATAAAACATTA +TATAACATAAAAAAGTAAATGAGAAGGGAATTAAAACACTTCGCTACAAAAAATCAACTA +AATACAAATGAGATCATGCAGGAAATGGACAAAAATGCTGTAAGGCATATAGAAAATGTA +TAGCAAAATGCCAGAAGTAAGTCCCCCCTTATCAGTAATTACTTTATTACTTTTTAAACC +ATTTTGTTGAGGAATGATTTACATAAAAACTGTACATATTTAACGTACACATCTTGATAA +ATTTACACCATAAAACCATTATCATCAAGCCTATAAACATATCCATCACCTTTTAAAATT +TCCTTCTGCCTCTTTATTATTATTATTGTATAAAAAAAAGTTTTTAATGGCCAGGTGCGG +TGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCTGAGGCAGGCGGATCACCTGAGATC +AGGAGTTGGAGAGCAGCCTGGCTAAGATGGCAAAACCCCATCTCTACTATAAATACAAAA +ATTAGCTGGGCGTGGTGGCGGGTACCTATAATCTGAGCAAAGTACTGGGAGGCTGAGGTG +GGAGAATCTCTTGAACCTGGGAGGCGGAGGTTGCAGTGAGCCGAGACAGCACCATTGCAC +TCCAGCCTGAGCAACAAGAGTGAAAATCTGTCTAAAAAAAAATAATAATAATAAAAGTTT +TTAATTAAACAATTTAAGAATATAGTAACATTTTCTGTGGGTACTATGCTGTATAGCTCT +CCAGAACTTACTTATCTTGCATAACTGAAATTTGTACACTTTAACCATCAACTTCCCATT +TCCTTCTCTTCCCCAGCTCCCAGCAACCACCATTCTGTTCTCTTCTTCTGAGTTTGACGT +CTTTAGGTTCCACACATAAGTGAGATTGTACAATATTTCACTTTCTGTGTCTGGCTTATT +TTACTTAACATAATGCCCTCCAGTCCATCTATGCATAGAAATGCAACTGATTTTTGGATG +TTGACTCTGTATCTTGCTACTTTATTGAATTTATTACTTCTAACAGTCTTTTAGTGAAGT +CTTTACAGTTTTCTATACATAAAAATATGTCATCTATGGAGACCATTTTACTTCCATTCT +TATTTCTTTACTTGCTTAATTGTTCTGGCTAGGACTTCCAGTCCTATTTTGAGGAGAAAT +GGTGAGAGTAGGAATTCTTGTCTTGTTCTTCATCTTCGAGGAAAAACGTTCAGTCTTTCA +CTGTTGAGTATGTTACATGTGGTCTTCATTATGTTGAGGTACATTCCTTCTGCACCTAAT +TTGCTCAGTTTGTTGTTTTTTTTAATCATGAAAGGATGTTGAATTTTATCAAGTGCTTTT +TAATAATAAAAATAAAGGATTTTTATCGTTTATTGTGTTGATGTGGTGTATCACATTTAG +TGACTCTTGTATGTTAAAGCATCCTTGCATGCCAGAGATAAATCCCACTTGATCCTGGTG +AATAATTCTTTTTTTGTTTTTTATTTATTTATTATGTATTTATTTTTTTGAGATGGAGTC +TCGCTCTGTCATCCAGGCCTGAGTGCAGTGGCGCGATCTCGGCTCACTACAAGCTCCGCC +TCCCAAGTTCACGCCATTCTCCTGCCTCAGCCTCCCTAGTAGCTGGGACCACAGGCACCC +GCCAGCATGCTCAGCTAATTTTTTTTTTTTTTGGATTTTTGGTAGAGACTGGATTCATGG +TGAATAATTCTTTTAATGCACTGTTGAATTTGGTTTACTAGTATTTCATTGAGGATTTTT +GCATCTATGTTAACCAGGGATATTGACCTATAGTTTTCTTATTTTGTAGTGTTCTTATCT +GGCATTGATATCAGGATAATGCTGGCCTCTTAGAATGAGTTTCAATGTGTTCCCTTTTCT +TCAATTTTTTTGGAAGAGTTTGAGAAGGATTGTTATTAATTCTTTAAATGTTTGTTGAAA +TTGACCAGTAAAACCATTTGGTCCTGGGATTTTCTTTGTTGGGAGATTTTTCATTACTGG +TTTAATCTCTACTTATTTTTTCTGTTTTTTTTTTTTTTTTTAATTATACTTTAAGTTCTG +GGGTAGCCGTGCAGAAAGTGCAGGTTTATCACTTAGGTATACATGTGCCATGGTGGTTTG +CTGCACCCATCAACCCATCATTTACATTAGGTACTTCTCCTAATACTATCTCTCCCCTTG +CCCCCATCCCCCAACAGGCCTCAGTGTGTGATATTCCCTGCCCTGTGTCCAAGTGTTCTG +ATTGTTCAACTCCCACTTATGAGTGAGAACATGCGGAGTTTGGTTTTCCGTTCCTGTAGT +TTTCAGATGTGCTCTGGCCTCCAAGGACCATGAAGCCAGGCGGTGGTGGGGGGGTGTCCT +CTGTATAAAAAGTGCTGTCCCAGGAACTTCCTGACGGACACTTTGGGGCATGTGAGCGAT +TCCTGGGGAGGGCACCTCGGCCTTCCTAAGGCTACCCCTGCAGCCAGTGCTGGCCATTCT +CACCAGCAACCAACCAAAAAACATCAGAGTCCCTGTAAACCTGGTTGTGATGATAAAAAC +CAAATGTTTTCTAATCTAAGACTTGTATGCAGAACACAGAAAACTGCAGTTAAGGAACAC +CCTACAAAATTGACCAACAGTATTTTCCAAAAACATTTTTCATCACTTCAAATAATGTAC +AAAATCTACAAAAATCATATTTACCAGGACACATCTGTTAAATAAAAGCATTGTTTCGTG +TTGGTATACATATACACAAGACTATGTATAACAGACTGTTTCCCCTCCCTGCAACCACAG +AACCATCACACACAGGCACAGATACACGTCGGCTATGCCGCTTTCCACGAATGCATGGAA +CCCAGGACGCGAACCCACAGCTCGAGGTCTTATACCTTCACTACTGAGCTGCCGCCACTG +CAGCAGCAACACCTCTGCGGAGGTGTCGCTGAAGTCACTGGTGTCCCTGCCCAAGGTGTC +CTGGTCCTGGTCAACTCTACTGATTGACCCTTCGTGGATACCTCAGGTCTAAAATCCTTT +CCTCCGAGCCAGAGCTCTTCCTGTTGTGCAAACTCAGCCCCGTCTGTACCTTCCTGCTTG +GCCGGTGATCGCAGTCCTTCTTCGCCAGCAAGTGTGGGCTTCCAAAGACAGGGCTGGGCC +TGGCCTGGGACTCCCTGAAGGCCGAGAAGGACAGGCCCTGCAGAGGCAGCCCCAGGTAGG +GGCTGAAGAGGCCGGTCTCCCTGCCCCCCCAGGAGACACCCTTTCCAAAGTGGAAGAGCT +GGGTGGACAGCAGCGGGGAGAAGCCCGCAAGGGGCAGGCTGGGCAGGCCCCGGGCGGGGC +CCTCGGACCCCTTGTCTCTCTCTCCCAATGCCGCCCCCTCCACGCCGCATCTCTACCTTT +GGAGCGCAGTGCCCATGGGCTGGGCAGCCGACTGTGGTGGGCAAAGTCACTCCAGGGCGG +GGCGCGGTTGGCCTGGGCTCCAGCATCCCTCTCAGCTCCCGGGCTGGGGGTCAGGAAGCT +CCGGTTCCTGCAGTCCACGTGAAAGGTCCCCCTGGCTCCTCCTGCCTCGGTGCCCGCTGT +GGCACAGCTGGGCCGCTGACCAAAAGCACTTTTGGCAGCAGGCTCAGCCCCTCGTGGGCT +CTGGTCTTTGTAAACGTAAACATTTCTCTTGCTCACTGAGAGACCTTGGCGGAGACACTG +CCGCTGGTCCTCCTGGGTGGCGCATGATCCCCTCCGCCGGATCAGTGGGGAGCCCCTTCC +CACCCTGGCTGAGCAGGCACGCTGCGCCCTGTGCTCCTGCGCTCCCTGCGCCTCGATGCC +CTTTAGCCAAATGTGGGACCCCCCGGCCCTCTGGCTCCGTGTGCACATGCCAGGCAGTGG +GGCCGGCTCCTTCCTGCAAGGTACCTCTGGCCTGGCTGGGCCCCCTGTCCCGAGAGCGGT +GGGGCCCTCTGCCTGAACTTCTGAACTGCTCACCGACTCCTTGGCCTTTTCCACCAAAAA +CTTCCTAATCTCCAGTTCGATGCTATCGTCGCTGTCCACTGAACTGCTGTTGTCAGACAA +GGAGCCAGGGCTGGGAGCTGGGCCCTGGGACTCTCTGGGGAATAGATTCTCTTCGGAGGC +GGAGGCAGAAGCGGGTCTCCTCACCAGGAAGGCCGGGGCTTCGTCCTCTCGGCCCTGCTG +CCAAAGACACTGGGGGGTTTCTTCCTGGAGCCCTCGCAGCTGTCTCTCTTGGACTTAGGC +AGCTCTTCAGCACCTGCAGGTGCCTGTTTTTCCACTCTCTCAGGAGCCTGCCCAGCTGCT +CCTGGAAGTGCGTCTGGGAGGTGCTGAACCTGACCTTCTTCCTGCACACAGCCCTGGGCT +CCCTGGACCTCTTCTTGAGCTTTCACTTGGACCTTAACAAGTCCTTGATGGCTGTGTCCA +GGTCCTTGTCACTGTCCAGGGAACTGCTTTTGTCTTCGGAGCTCTTCTTCTTGTCTAGGT +GCCTTGCCTCGTCTGTCTTACCCTGGCCCTGTGACGTGCGAGTGTCACCGGGCACCCTAG +CGGCGCCCTCTCCTCCCGGGGCCTCGCTGGCTGTGCCCTGGATGGAAAGGTCCCGCCCCT +CATGGCCCGGCCCGGCTCTCCCCTGGCTGCGGTCGGCATCCTGGCCACCCTCTTTCCCCA +CCACCCGCATGTTCTTGGGAGTGGATGGCCTCACTTGGCAGCCGCCTCTATGCTTCCTTT +TGCAGCCAGGAGTGGGTCCAGTGTTTTAGAGAGAGGGGCCTTGGGGCTGCCGGTCTGGCT +GCTGAGGCCAGGTGGTGAAAGTGGGCCCTGGGCAGCCTGAGGGCAGCTCTCACCTCTGGC +CAGCAAACTTCTAGACTGCACCTTGAGGGCCAAAAACGTCCAGATTTCCTGCTCAATGCT +GTCGTCGCTGTCCACGGAGCTACTGTCACCATCAGAGCGGGAAGGCACGTTGGGGGAGTA +GAAGAGTGGGCTTGCGGACAGGGACCCATCGCTGCCCTCCATAGGGCCGGCAGGATCGTC +TTGAAAATGTCCAGGACTGCTTCTACACACATCAGCTCAGCGGAGGTGTCTGCCTGGCAA +GAGGACCATTCCACAAACTTGCTCCTGGAAGCCGGGCTCGTTGGAGGTGGAGCTTTGGTT +TCCTTTGGGATCTTGGGGGAATGGTCAGCGTCCAGATCCCCTGGACCAGGGTCCGTGGTC +TTGGTGGGCACTGGCTTCTTCTTGCTGGGTGTTTTCCTGTGGGTCTCTGGCAAGGCACTT +TTTGTGGCGCTGCTTGTGCTGTGTGCGGGAGGGGCAGGTGCTCTTTCCTCTTGGAGCTGG +ACCCTCTGGGGCGGGTCCCCGTCGGCCTCCTTGCGTGTTTTCTGCACCTGGTACAGCTGG +ATGGCCTCCTCAATGCCGTCGTCGCTGCTGGAGTCGGACGCCTCGGGCGCCTGTACGGCG +CTCGTGACTCGCTTTCCCCTCCTTGCGGTGCTGGCGTTCCTTTTAATCCCACTTTTATTC +TGTACTGCTTCTGAAGGGCGGTGGGGGTTGCTGGCTTTGTGCTGCCCTCCTTCTCCTGCG +TGGTCGTGACCTTGGACCTGAGGCTTCTGGGCTGCACGTTTGTCTTTGCTAACCGGGGGA +GGTCTGCAGAAGGCGAACTCCTTCTGGACGCCCATCAGGCCCTGCCGGTGCACCACCTTT +GTAGCCGGCTCTTGGTGGGATTTCGAGAGTGACTTCGCCGAATTTTCATGTGTGTCTGGT +TTCTTCTCCACTGACCCATCACATTTTTGGTTCTCATGCTGTCTTTTCTCATTCAGAAAC +TGTTCGATTTCTGCCCTGATGCTCTGCTCAAAGGAGTCTGCTCTGCTCATGCTGACTGGG +GAGGCAGAGCCCTGGTCCTTGCTGGATCCCACCTGGCTGCCAGGGCCACACCACCTGAGC +CAGGTACAAGTTTTGGGGAACACAGGGCAGTTGGGCACTGCTGTGAGCCAGTTCCGGCTT +ACATCTACTGCCTCCGCCTGCAGCCCTGGAAGGCTGTGCATGGCTGGGCCCCGCTGGCCC +CGGGCTGTGCGGCTCCACTCTTTACCTTCAGGTACTCCTGGATGGCCTCCTCAATGTCCC +GGTCCACGGAATCGTCACTGTCTGAATCTAGCACCAATGGGCCAAAGTCTGCAGTTTCCT +CCTCCCCCACGGGGTCAAAGTCAGCAACAAGACCACAGGCAGCCAACGCAGGCAGCTCCT +TGTGCATGGTGGGCTTGGCAGCAGGCCTGGCGTCGTGGCATCCCTCTGCCCCCTCTGCGC +AGTGCGCTCATCGCTGGTGCCCCTAGCAGCCCTGTCGCTCTGCAGCGTGCTGATGAGCAT +CTGCACCCGGGTGCTCACCGACATGCTCTCCACGCCCTTGTCAGCCTCCGAGAAGCACCC +GGGGAACCTAAAGCTCCCTGGTGGGACAGAGGCCACCCATTTGCGCTGGAGAGCAACCAC +TGGAGGAGCATTCATGAGAAACATTCTGGCAGATGGGGAGCGACGCGCAGAGGGGCGACA +CTTTATTTCTCTGCAGGCTTCACATCCTCCAAAGATTGGCAAGCAGTACCCGTGAAATAA +CTTTAAACCTGCAAATGCTTCTTTGCAGGTTTAAAAGGATGACTATAAACTATGACGTCA +TGCCTAGATTCATTCTTGACCCAACCAACAAGCTCTTGACATTCTCTGAGTCCAGGTTGA +CTGTGATGAAAGGCAGCTAGTGTTCCCAAATGGCCCAGGGATCAGGTCTTCATCGCTCCA +CTCAGAGGGAAGCATCCTCTCTCTGCTTTTTAAATAGACTTTTGACTGGGGCTCCAGCAG +CGCGGGGCGCGCAGACCTGGAGTTGCATGGAGGCCAGAGCCACGACACCCGCCTGGGGAA +CGGAGCAGCCCCAGGCGCTGATCCCCGTCCACCTGCCCCACGGAGCCCTCGCCGCCCGCT +TGCCACTGCCTGCATGGCCCTCCTGTCCCCGGCCCCCCAGCCCTCCTTTCCCCAGCTCCC +CCACCCTCCTGTCCCCGGCACCCCAGCTTCCCAGCCCCCGAAACCGCCCCCCCACCTCGA +CCCGGCCCATGCCGCAAGTCGCCCGCTGCGCGGACCCGGCCTCCGCCCGCCTCCTGCGTC +CTGGGGGAGGCGGCTGCCGGGGGTGGTGGGGGAGGGAGAGGGGGAAGAGGCCGCCCTCCG +CCCGGGTGCGGGGAGGGGGCGCAGGGGTGTCCGGCCAGGCCCCCCGCCTCCCCGCCTCCC +CGCAGCAGCTGCCCCGCTCCCGGGCCGCCTAATACTTTTACATTTTAACTTTTATACTAC +AGTGAAAAGTGATTTACACACCACCACTGCAATATTACAGTGTTATGAATGTGACTATAT +ACTTACCTTTCCCTGTGAACTTTTTTTTTTGAGACAGAGTCTCGCTCTGTCGCCCAGGCT +GGAGGGCAGTGTCCATGATCTCGGCTCGCTGCAAGCTCTGCCTCCCGGGTTCAAGTCATT +CTCCTGCCTCGGCCTCCCGAGTAGCTGGGACTACAGGCACCCGCCACCACGCCTGGCTAA +TTTTTTGTATTTTTAGTAGAGACGGGGTTTCACCGTGTTAGCCAGCATGATCCCCCTCTT +CTGACCTTGTGATCCACCCGCCTTGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCA +CTGCGCCCGGCCTACCTGTGAACTTAATATCTTAATGTTTTAATGTTGCTAATCAGAATC +CTTTTATTTCAACTTGAAAAACTGCCTTATAAGGCAGGTGCAGTGGTGATGAACTCCCTT +AGAATTTTTTTGGTGGGAGTCTGGGAAAGACCTTATCATCTCTTTTTCATTTCTGAAGGA +CAGCTTTACAAGTTGTGGTCTTCCTGATTGGCAGTTTTTTTCTTCCAATACATTGAATAT +AGCATCCTATTCTCTCCTGGCTTATAAGGTTGCTGCTGAGAAATCCACTGATAGCCTTAT +TGAAGTTTCCTTGTATGTGATGAATTCCTTTCTTCTTGCTGCTTTTGAAAGTCTCTGTCT +TTGACTTTTGATATTTTAATTATAATACATCTTGGTATTATGGTCTTTGGGCTGGCCTTT +TTTGGGGCCTCTGAACTTCATGTGTCTGGAAGCCCACTTGCCTCTAAGAATTTGGAAAGT +TTTTACCCATTATGTCTTCAAATATACTTTCAGGCCTTTTCTATCTTTTTTACTTCTAGA +AAGTCCATAATATGTTTGACCCACTTCATGGTGGTGTCCTATAAATCCCAAAGGTTTTTA +CTTTATAAACTTTTTTTTCTTTCTGGTCTTCTGACGGGATATTTCAAATGTCCTGTCTTT +AATTTCACAGATTCTTTCTTCTGTTTGATCAAGTCTGCAATTGAAATTCTCTATTGCATT +TTCATTTCATTCATTTATTTATTTTTATATATTTTTGAGACAGAGTCTGTGTCACCCAGG +CTTGAATGCAGTGGTGCCATCTTGGCTCACTCCAACTTCCACCTCCCGGTTCAAGCGATT +CTCCTGCCTCAGCCTCCCTAGTAGCTAGGATTACAGGCATATGCCACCATGCCTGGCTAA +TTTTTGTATTTTTAATACAGATGGGGTTTTGGCATGTTGGCCAGGCTGGTCTTGAACTCT +TGCCATCAAGTGATCTGCCTGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTCCGCC +ACGGCACCCAGCTTGCATTTTCATTTTATTCATTGTATTCTTCAGTTCTAGAATTTCTGT +TTGGTTCTTATTATTTCTGTATCTTTATTGAACTTTTAGTTTTGTTCATCTACTATTTTC +TTGATATTATTGAGTTGATATATACATTCTAGTAAATTTCACTGAGCTATCTTAATTATT +TTGAATTGTCAGGCAATTTGTAGATCTCTATTTTTGGGGGGTTGATTACTGGAGATTTAT +GAGTTTATTTTGGTAGTGTCATATTTGCTGATTCTTCATGATCTACAAACTTTCATTAAT +GTCTATGAAGAAGCAAATACCTCTTCTTTTCTTTTTTTTTTTTTTTTGAGACAGAGTCTT +GCTCTGTCACCCAGCTGGAGTGCAGTGGCGTGATCTCAGCTCACTGTAACCTCCACCTCC +CAGGTTCAAATGATTCTCCTGCCTCAGCCTCCCAAGCAGCTGGGATCACAGGCATGTGCC +ACCACGCCTGGCCAATTTTTTTGTATTTTTTGTAGAGACAGAGTTTCACCGTGTTGTCCA +GGCTGGTCTCAAACTCCTGGCCTCAAGTGGTCTGCCCGCCTTGGCCTCCCAAAGTGCTGG +GATTACAGTTGTGAGCCACCATGCCCAATCTCTTTCTGTCTTTATAGATTGGTTTCAGCA +GGTACAAACCTTTTCCTGCTGGATCCCTTGACTGGATCACAGTCAAGTGGGCCTGGAGCC +ATATCACATGGCTGCTGCCTGGTCTGCAGCTGAATCTCTGATTGGCAGGCCGCTATCAAG +GCATAGGTTGGTGATGCAGTTTCTGCTGGATCCTCAGGAGAACTGGACTGCCTCTGATAC +CCTGATTGAACAGGACTGGAGCCAGGTCATGGGGCCACTTCTAGTTCTACAGTCAAGTCT +TCAGATATCAGGCCTATTACCAAGGGCATGGACTGGTATAGCTCCCTGTGGGTCCCAGAT +TGAGCTCCTGCTGGCTTACTAGGTAGGTCCATGGGAAGACAGGACTGCCTCCAGACCACA +GTAGAGCAGGGCTAGAGCCAAGTCACAGGACAGCTTTGGTGACCACATTTGGGTTCAAGA +TTGGTGGTCCTCTTATTAGGAGAATGGATGGTATGTCTTTCACCAGGTCCCAGGATGGGC +TGGACTGTGCCCAGACTGTGGCAAAGCAAGACTGGAATGGAGTCACAGGGCTACTTTAGT +GTCCATAGCTGAGACTGAGATCAGCAGGCCTGTTACCAAGGGCATGTAAAGGCATCACTG +AATTCCTGGGCAGGCACGACTGACTGTGGTAGAGTGGGGCTGAAGCCAGGTCAGGGCTGC +TTTAGTTTCTGCAGTCAGGACCATGGTTAGAAGGCCTGTTACTGGGGGCATAAATGGTCA +TGGTTCCTCCTAGGTGCTTAGTGGATGGGGCTAGTTGCAAGACCATGATCTAGTGGAGCT +GGACCCAAGTCCATAGGAGGACAAAGCTGCTTTCAGTCTGCAACTGGGAACCTGTCACTG +GTGTGTGGACCTGCCTTCTCAAAGCAGCTCTCCTTGGTTTTGGGCTTTGCTAGAGTTTTG +CCACCTCCTGCCTGGATATTAAAACTCTTGCAAAGGCAGTTTTGTCCATGAATGGCTGCC +AGATCATTGTTTGTGTGGGGAGAGGTGAGTGGAGGGCCTCCTGTTCTGCCATCTTGCTGA +TGTCACCCTAAGATGATTATTTGAATTCTTTGTCAGGCAATTTGTAGATCTTCATGTCTT +TGGAGTCAGCCACTGGAGTTTCATTTTGTTTCTTTGGTGGTGTCATATTTTCTCATGCTT +CCTGTTCTTTGAAGACTTAGATTGCTTTCTTCATGTTTGAAGAAGGAGTCATCTTTTCCA +CTCTTTACTAACTTCAGGAGAGAAAGACCATCAATTAGCTAAGCTATAGATTCTGGGGGT +CTCTCAGTCCTTTTCTGTGGGTGGTCCTTCCCTTTCAAGGGGGATGTCTTAGGATTTTGT +CCCTTGTCTTCATTTCACAAATGAATAAAACAACCAGACCAGACATAAGTAAGGAAATAC +AGCACTTGAACAACACCTGAAAAAACAACTAGACCTAACAGACATACACAGGATATTCTA +CCCAACAACATAATACACATACTTCTCAAGTATACATGGGACATTTTCAGGATAGACCAC +ATAACACATCACAAATTAATTCTCAATAGGGGCTGGGTGCAGTGGCTCACATCTGTAATC +ACAGAGTAATTTGGGAGGCTGAGGCGGGTGGATTGCTTGAAGCCAGGAGCTTGACATCAG +CCTGGCCAACATGGTGAAACCCCATCTCTACTAAAAATACAAAAATTAGCTGGGCGTGGT +GGTGTGTGCCTGTGATCCCAGCTTCTTGGGAGGCTGAAGCGTGAGAATTGCTTAGGAGCC +CAGGAGGTTGAAGCTGTAGTGAGCAGAGATTGTACCACTGTACTCCAGCCTGTACTTCAT +GACAAAGAAAATGTACCATTGTACCACTGACAGAATGAGACCCTGTCCCAAAAAAGGAAA +AAAGCTCAGTAGATTTAAAATGATAGACATCATACAAAGTGTCTTCTCTGACCACAACAG +GATAAAGTTAGAAATCAATAACAGAAGATTTTAAAAAGTTCACAAATTAGTAGAATTTAA +ACAACACACTCTCAAACAACCAATGGATCAAAGAAATCACAAAGAAATTATAAAATTCTT +AAAGACAAATGAAAATGAAAGCACACTATATCCAAACTTATGGGTTGTGGCCAGTTGTGG +TGGCTCACACCTGTAATCCCAGCACTTTGGGAGACTGAGGGAGGTGGATAGCTAGAAGTC +AGGAGTTCAAGATCAGCCAGGCCAACATGGCGAAACCCTGTCTCTACTAAAAACACAAAA +ATTAGCTGGGAGTGGTGGTACGTGCCTGTAGTCCCAGCTACCCAGCAGGCTGAGGCATGA +GAATTTCTTGAACCCAGGAGGCAGAGGTTGCACCACTGAGCTAACACCACTGCACTCCAG +CCTGGGTGACAGAATGAGACTCTGTCTCAAAAAACAAAGAAACAACAAAAAAACACAACT +TATGAGTTGTGGTGAAAGGAGTGCTAAGGAGGAAATTTATAGCTATAAACACATTAAAAA +AAGAAACACCTCAATTCAACAACATAAGTTTACACATTAAGAAACTAGAAAAAGAAGAAT +AAAACTAAACCCAAAGTTAGCAGAAGGAAGGAAACAATAGAGATCAGGGCAGAGATAAAT +GGAAAAGAGAATAGAAAAACAATAAAAAACAAAACCAAAAGTTGGTTCTTCAAAAAGATT +AATAAAACTGACAAGACTAAGGAAAAGGGAAACAATCTAAATTACTTAAAACAGAAATGT +ATTTGAGAATATCTTTATATATTTCTGTCTGTCTGTCTGTCTGTCTGTCTGCCTGTCTAT +GTTTTAGAGACAAGGTCTAGCTCCATTGCCCTGGCAACAATCAGATGCAACCACAATCAG +TGGCACAATCGGCTCACTGCAGCCTTGAATTCCTGGGCTCGCCACTATGCCAGCTCTTTT +TTTTTTTTTTTTTAAGAGACAGGATCTTGCCATGTTATCCAGGCTGATCTTGAACTCCTG +GCCTCAAGGAATTTTCCCACCTCGGCCTCCCAAATTGTTGGATTACAGGCATGACCCACC +ATTCCCAGCCTAGAAAGGATTATAAAAGATTACTATAAATAATTGTGTGCTCATAAATTG +GATAACCCAGATGAAATAGATGAATTCCGCGNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN +NNNNNNNNNNNGTGTCTCATGCCTGTAATCCCAACACTTTGGGAGCCTGAGGTAGAAGTT +GAGGTCAGGAGGTCCAAGACAAGCCTGGGCAACATAGTGAGTCTACAAAAAAAATATTGA +GAATCTACATAAATATAGTGGGGGTGGGGGTGGGGAACAAGAAAACAAAAAATTCAAAGC +ATAGTGAAAAGAAATATAGCAAAACCCAGCCGGGCATGGTGCCTCACGCCTGTAATCTCA +GCACTTTGAGAGGCCGAGGCATGTGGATCACGGGGTCAGGAGATCGAGACCATCCTGGCT +AACACAGTGAAACCTGTCTCTACTAAAAATACAGAAAAATTAGCCACATGTGGTGGCGGG +TGCCTGCAGTCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATGGCGTGAACCTGGGAGGC +GGAGCTTGCAGTGAGCCGATATCGCGCCACTGCACTCCAGCCTGGGCGATAGAGCGAGAC +TCCGTCTCACAAAAAAAAAAAAAAAAGAAAGAAAGAAATATAGCAAAACACAACAAAAAA +ATTAAAATTTGCTGGGTGTAGTTGTGCCTTTAGTCTCAGCTACTGGGGAGGGTCTGCTGG +AGGATCACTTGAGCCCAGGGGTTCAAGGCTGTGATTAAGCCACTGCACTCCAGCCTGGGT +AACAGAGCAAGATCGTATCTCTAAAAAAAAAAAAGAAAAAAGAAAACACTCTCTGGCCAC +AGATGAGAGAAGGCAGACAGGAAGCCAGTAAGCCAAGCAGGCAGAGGGCAGGTGGCCCCA +GCCCAGCTGTCGGGTGGTGAGCAGTGTCAGGGAGACAGGAGTGCCGGAGCTGGTGAGGTT +CCCAAGGAGGTGAGGTTGCCTGTGGCCCCCTCCCAGGGCACAGTCCCACCCCTCCAGTAG +TGCACTCTGTCCTCCCTGGTAGGTACAGGCTTTTCCCCACCACCATGGTGCAGCCATGCC +TGCCCCCAACACCACTGGTGCAGCTCCATCCTCCACGCAGTGGTGCAGCCCCATCCCAGC +GCCCATTCGAGCTGCTGTCCCATTGCAGGGGGCATTGTGACAGCTGAGGACCTGAACAAC +TACCGTGCTGAGCTGATCGAGCACCCGCTGAACATCAGCCTGGGAGACGCGGTGCTGTAC +ATGCCCAGTGCGCGGCTCAGCGGGCCCGTGCTGGCCCTCATCCTCAACATCCTCAAAGGT +GAGTGGTCGCACCACAGCCGTGTGGTAGGACCCATGACACTGCCTCTCTCTCCCCACGCC +CCACCCCTCCTGCATCTCTGCTCGCCCCCCATGCCACGTCTTTCCATCACTGAGCTCCTG +AGGTGTGTCCCTGCGTCACAGCTCACCATGTCCTGAAGGAGGCAGTGCAGAGCAACAGGG +CTGAAGCGGGCAATGCTCAAGGGTTGGAGGAGGAACAGGAGTCATCAGGAGGGAGAGAGG +TGCAGGAGCTCAGGGCTGCAGGGCCGGTCCAGAGGGTACCCCGGTCCAGTGGGTGACCCT +GCCACTTGGTCATTGAATGGCCAGAGCTGATGCGTGACGTGAGGTCCAGGCTCAGGAGCC +CTCACCTTACTTCACTCTCACCACAGCCTTCTGAAGCAGCTGCTGCTATTGGTTATTAAA +CGCTCCTTGAGGTGGGCAAAGTGGCTCAGGCAGGTGTTAACCCTCTGAGCCCCTCAGAGC +CTCTGGGGCTCAGCAACATGCACCTGGCTCTGATCAACCAGGGTACAACTTCTCCCGGGA +GAGCGTGGAGACCCCCGAGCAGAAGGGCCTGACGTACCACCGCATCGTAGAGGCTTTCCG +GTTTGCCTACGCCAAGAGGACCCTGCTTGGGGACCCCAAGTTTGTGGATGTGACTGAGGT +AAGGGGCAGGGGCTGGCTCACTGTGGGTGTGGGGCCTGCCGTAGAGGCATCAGGTGGGCT +CCCCAGGGTGGCTACAGCCTCACATATGCTTTATGAATCCATTCCTGCCACAGAATTTGA +TTGCGGGCCTACTGTGTGCTCGGATGGACTCGTGGGTGACCCCCAGTCTTGGCTTCTGCC +CCACAGAACTGACAGTGTGGGGAATTAGTGGCCACCCTCCTACCTCAGGTCCTTTGCACA +TGCTGTGGTTCTTGAGTGCTCAGTGCTGAGATGAGGAATGCATGGGGGCATTGCAGCCCT +CGGGCATGGTGAGATGGATGGGTGAAAGGGAGAGGGCCAGGTGAACAGAGACCTCGGCCA +CCCACTCCCTGTCACTCCAAACTAACGCTTCCCAGATGCCACCCTCAGCCCTGCACCACC +TGACCCACTCACCCAGTAGTTGCCCCAGCTCCATGCTGGGTCCCTATAAGACCCTGTCAT +ATCCCTTCCCGCTGAGGATCCTCACATCCCTCCTTACCTACTTGGGTCCTTGGCATTCCT +GGGCGGATCTGCAGACCCCCCCACACTGACCAGTGACCTCCCAGGAGGGGCGTCAGCTGC +CCGGGTGGTGTCTTCTCTTTCCCTGTGAGCATTCTGCACCTCTGACTCCCGCTGCAGCCA +GTGACCTGGTGTCTTGTCTCTCTAAGGGGACAGAGCCACTGCAGCGTGTCCCTCTGCCCT +CCTTTTTGGCTAAGGCCAGGTCCTTCATCTACTCGCTGGCTCGGGGTGCTGTTCCTACAA +TGCTCCTGTCTGCCTCTGATGATTTATTTCTTTATCACGGATTATTCCCAAAAAAAAGGC +AGCTGTTATTGCTCTAGAGACTTCTATCTGCTGCCTCCTTCTGTCCTTTGCTCCTCTTAG +AGCAAACATGGCTGGGCTATGTCCTCTCTCCCTTCAGGGTATCCCCTCCCCTGCTCTATC +CCCATGCCACCAGATCGCCATGTCCAGCCTCAGTTTCCCCATCAGGCCCCACTCAGCAGC +ATCTCACACAGCTCACCACACTCTCCTCGAGTTTTCATTTTGCAAATTTTCGCACCTACA +AAAATGTAAAAAAAACCCAAAACTGCCCAAGCATCAATGTTCCCTTTTCCTGGATTCTGC +AGTGTGGACATTTCTGCCGGATTTCCTAACTCTCTCCGTCTCCACCCACATCTATTGGGA +TTCGTGTTTTTCTGAGGGATTCCACAGTAGGTTACTGATGTCGCACCTCAGGGTGTGTCT +CAAAAGTGAGACTTGAACATAGCACAGCAGGATGTCGGGGTGACACAACCTGCTGTCCCT +TCTCTTTACCTACAGTAGGCTCCCTTGGCTGTTTTGTTTTTGTTGTGTTTTTGTTTGTAC +ACAGAGTCTCTGTCATCCAGGTTGGAGTGCAGTGGTGTGATCTTGGCTCACTGCAGCCTC +AACCTCCAGGGCTCAAGCAATCCTCCCACTTCAGCCCCCTGAGCAGCTGGGACCAGAGGC +ACGTGCCACCAAACCTGGATAATTTTTGTATTTTTTTTAGAGACAGGGTCTTGCCCAGAC +TGGTCTCAAACTCCTGGGATCAAACTGTCTTCCCACCTCAGCCTCCCAAAGCGCTGGGAT +TACAGGTGTGTTTTTTCTTTGAGACGGAGTCTCGCTCTGTTGCCCAGGCTGGAGTGCAGT +GGCGCTATCTCGGCTCACTGCAAGCTCCGCCTCCTGGGTTCACGCCATTCTCCTGCCTCA +GCCTCCCGAGTAGCTGGGACTACAGGCGCCCGACACTGCGCCCAGCTAATTTTTTGTATT +TTTAGTAGAGACGGGGTTTCACCGTGATCGCGATCTCCTGACCTCGTGATCCGCCTGCCT +CGGCCTCCCAAAGTGCTGGGATTACAGGCATGAGCCACCGTGCCTGGCCTGTTTTGTTGA +TTTTTAAAGCCCAGGGCAGTAGTCTTGGAAAATGTCCCACATCGTGGATTTGCCTTTCTG +TTTCCTTGAGGGCAGATTCAGACAGAACACCTTTCCCTGGGATTGGTCAGCTAATCCGTG +GGGTGTTGCTGAAACTTTATTTTATTTTATTTTATTTTATTTTATTTTATTTTTGAGACG +GAGTCTCGCTCTGTCCCCCAGGCTGTCCCCCAGGCTGGAGTGCAGTGGCGGGATCTCGGC +TCACTGCAAGCTCCGCCTCCCAGGTTCACGCCATTCTCCTGCCTCAGCCCCCCAAGTAGC +TGGGACTACAGGTGCCCACCACCGCGCCCAGCTAATTTTTTGTATTTTTAGTAGAGACGG +GGTTTCACTGTGTTAGCCAGGATGGTCTCGATCTCCTGACGTCATGATCCGCCCTCCCAA +AGTGCTGGGATTACAGGCCTCGGCCTCCCAAAGTGCTGGGATTACAAGCGTGAGCCACCG +CGCCCGGTGTTGAAACTCTCTTGAGGCATTTTCTTCGGCCTTCGGGTCCATCCTCTCTGT +CTCCTCTTTGACCTCCTCATCTCCTCCTCGCCACTGCCTTGGGGACCTTGGCCAGGCTCA +TGGCATCCAGCAGCCACTCAATGTCAATACCTCCATGTTCATCTCTCAGCCCGCCCTTGC +CCGTGAACCCATGCTTATTTATTTATTTTTTTTATACGTGCACCCATGCTCTTTGGGTCT +GATGAAGTATCCAAAATCAAGCTCCTGACCATCCCCAAACCGGCCCCTTCTGCCGGCCTC +GCTAGTCGGCACCATGCTTGATTCTTCTCTTTCTCCCACCCAGGCCATCATCTCTTGCCT +GGTTGATACCCACAGCCTCCCCTTTGGGCTTTATCCTTATCCCCGTCATAGCTGCCAGAG +GGACCCTGTGAAAACACTCCCCAGCCTCCTCATTCTTCTGCCCTAAGCCTGCATGGCACA +GAGCAAAAGCCAGTTGTTATGGGACCTAGGAGGTCCTGTGGGATGGGCCCCAGCCTGCAT +CTTCATCCTCTTCTCCCCACCCCACTCCATTCACTCTCTGCCTATCGCTCACCAGCCTAT +ACCACCTGCCTCAGGGCCTTTGCACTGACCATTTAGGCAACATTCCAGGCTCTTTTCACA +CGTTGCCTCCTCTGAGAAGCCCTCCCTGACCACTCTGCCCATACCTCATGCCTCTTGATT +CCCCTTACCTGGCCTGTGGTTTCAGCACTTTCCCTGTGTGTGTTTGTTTTTCTTGGCATG +AGGGCAGGACTTAAGTGTCTGTTCCCTGTTGATTCCCCAGTGCCAGGCATGCAGTGCAAA +TTCTAGAAATATTTTTTGCATGAAAGAATGAGTGATTGAATGCGGCAAGGGTCTGGAGGC +TGAGGACCAGGCAGACAGACATTCAGAGTTGCTGGAACGCGACAGAGACAGGGAGTCAGA +CTGGTCATGCAAGGTCCTGGGCCTGCCCTTGGGTCCTGGGGAGCCACGGAAGGTTGTGGG +TGCCAGAGGGTTGCGGTCAGAGTCACAGTCAAGGGCCTTCTGAGACCTGTGCCCCCTCCC +CACCTCCTCAGGCCAGCTCTGGGGTCTCAGCAGGTGGTCCGCAACATGACCTCTGAGTTC +TTCGCTGCCCAGCTCCGGTCCCAGATCTCTGACCACACCACTCACCCGATCTCCTACGAC +AAGCCCGAGTTCTACACGCCGGATGACGGGGGCACTGCTCACCTGTCTGTCGTCGCAGAG +GACGGCAGTGCTGTGTCCGCCACCAGCACCATCAACCTCTAGTAGGGGCTGCTGGGCCGC +CTGGGTGGGAAAGGGCCAGGGGCGGGTGGCCCAGGGACTGCCCACTTATCCAGTAAGGTG +GCTCCATCACCTCTTTTCCTGGTGGGAAACTGAGGCCCAACCTTGGTAGCTTATCCTGGG +CCTCTCAGTGAGTATGTTTGAGCCTCAGTGGGTGGATAGGGACCAGGCTGGGCCAGGCAA +GGTCGGGTGCTGTCTGACCTGGCTGGGCGGTAGCTTTGGCTCCAAGGTCTGCTCCCCGGT +CAGTGGGATCCTGTTCAATAATGAATGGACGACTTCAGCTCTCCCAGCATCACCAATGAG +TTTGGGGCACCCCCCTCACCTGCCAATTTCATCCAGCCAGGTATGGGGTGGAGGTCCGGG +GGGTGGGGGACTGGGGTGGAGAGGGGCGGGTGTCCTGGGCAGGCAGCTGACGGGCATCCC +TGTCTTCTCCCATCGGCCGCAGGGAAGCAGCCGCTCTTGTCCATGTGCCCGACGATCATG +GTGGGCCAGGACGGCCAGGTCCGGATGGTGGTGGGAGCTGCTGGGGGCACGCAGATCACC +ACAGACACTGCACTGGTATGTGTCACCCCTTTTCTCCCTGGCCCTGCCCACTCTGCACAG +CCCCCAAGCCACGCTGATCACACTCCCATGCCCCAGGCCATCATCTACAACCTCTGGTTC +GGCTATGACGTGAAGAGGGCCGTGGAGGAGCCCCGGCTGCACAACAAGCTTCTGCCCAAC +GTCACGACAGTGGAGAGAAACATTGACCAGGTGGGCCGGGGGTTGGAGAAACTGAGTCAC +GGTGTGGGGTCCCAGGGCATCCTGGGCTGGAGGCCTGGATCATCACAGAGTGGACAATGG +TTGGTGTCCTCTCTCTAGTGCCTGGGCCATCTGGAGCCCCTGTGACATGAGGGCCAAGCC +CCCTGCTCCAGTGAGACCCAGCAGGCCCCAACCTGCTCTTCCTGATGACCTGGCCTGAAA +TGGCACCACCTGGGCTGAGGCCTGTGACCACACAGGTGTGGTTCAGGTGGCATCTGGAGC +CCTGCTCAGGCTTCCCCTCTCCTCCCACCCCCAGGCAGTGACTGCAGCCCTGGAGACCCG +GCACCATCACACCCAGATCGCGTCCACCTTCATCGCTGTGGTGCAAGCCATCGTCCGCAC +GGCTGGTGGCTGGGCAGCTGCCTCGGACTCCAGGAAAGGCGGGGAACCTGCTGGCTACTG +AGTGCTCCAGGCAGACAAGGCTGACAAGCAATCCAGGGACAAGATACTCACCAGGATGAG +GAAGAGGACTTTGGGGGACGGGCTTCCCCTGTGAGCAGCAGAGCAGCATAATAAATGAGG +CCACTGTGCCAGGCTCCAGGTGGCCTCCCTGGCCTGTCTCCCCACTCTCTGGGCCTCAGT +GTTTTGTGTGTGAAATGGAGCCATCTGGCTGGGGAGGAACAGAGAGGTGGGATTCGGAGA +TCTTCACAATGCGGACACTGGAACTAGCCTCAGCATCTTCAGCATGGGGAGAGCCAGGCA +CATGGCTGGGGGCCAGGGGAAGGTTCACACCAAACCCTGCCCCTTCCCACCCTGATCCCT +CAGACTTTGGGGCCAGGCCCTCCCTTACTGGGGCTGGGCAGTGACACTACCTAGGATCAG +CCACCAGGGGGTGTCACGACCCTGGCGCTTTCTTAGGCAGAGGGTGGCCAGCCGATGCTG +GGAACCCGGGCGCCTTCTCAGACCCGTAGGCGTCCAGCTCACCCTGCCGATGACACTGGA +GGTGAAGCTGAGGGTCCGAGGAATGGGGACTGGGCAACAGGCTGGAGGAAAACATCTCGG +TCAGAGCCATGCCCCTGGGGGGTTCCCAAGAGCAAGCCCAGAGTGAAACCCAAGCTTGTG +ATCCTCTCCAGAGGGAGGCCTGGTTCTCAGGGAACAGCAAACGGGAAGATGTCCCCAGAT +CCCAGGGATCAGGGCTTGGACCAGCCGGGGACGCAGCCCAGAGGGAGTGGGTCCGGAAGG +AAACAGCTCGACACAGCAGCCTTCACCATCGGCAGCCCCTCCAGGCCTCCCTCGGGGCCT +GCTCCCTCCTCTGTGCACAGTTCCAACACCTGGAGCAGGGTTCTGGGAAGGGCTGGTGGA +GGTGGGCTGGTGGGAGGCGGTGATCACAGCCCAGCACCTGGATATCACCAGGGGCACTGG +GGCCAGGGGCCAGGTGAGGCCAGGTCGGGGCTATCCTTCAGGAGCCCCGAAAACCTGGTG +ATTCCAAAGGGCCCATAGACAAACAGGGTTTTATGCCTGTGGAGTCAAGTCCCACTGGGT +CTGAGCTCTGGAGGGCTGTGTCTCTGGGGCTCTGCAAGGGTGAGATGGAGGTGGGCTCAA +CTGGTGTACAAGTCACTCTTCAATCCTTATTTTATTTATTTAATTTTTTTAAAAAAAATT +TAAACCAATAGAGATGGGGTCTCACTATGTTGACCAGGCTGGTCTTAACTCCTGACTTCA +AGCAGTCCCCCCATCTCAGTCTCCCAAAGTGCTAGGATTACAGGGGTAGCCACTGCACCC +GGCCTCAATCCTTATATTGGCCTGAGAGGAAAGGCCGTGGCCCCATTTGCAGGGGAGAAG +ACTGAAGCTGGAGGGGCAGGCCTTGCTCTGGGTTGCACAGCAGGAAGAGAAGTGGGAGCT +GGCCACGAGGCTTCCTGGACCCGAAATGCTGGTGGGGTACACCCTGGTTCTCTAGGTCCC +ATGGGGCTCAGCCCAGGACTACCTCGGGGGGTGAGGGACTTAAATCGTCTCCTTCATTCT +CATCGCCCCTTCCCCCATCATTTCCTGAGGAAGGACATTCAGGGACCTGAAGGGGTGGCC +TGCCCCTCCCCACCTGTGGGTGTTTCTCATCAGCTGGGACAAGAGACTGAGAAAAGAAAG +AGACACAGAGACAAAGTATAGAGAAAGAAAAGTGGGCCCAGGGGACCTGCACTCAGCATA +CGGAGGCCCCACGCTGGCACCAGTCTCTGAGTTCCCTAGTATTTATTGATCATTATCTCT +ACCATCTCAGAGAGGGGGATGTGGCAGGACAATAGGGTAATAGTGGGGAGAGGGTCAGCA +GGAAAACACGTGAACAAATGTCTCTGTGTCATAAACAAGGTTAAGAAAAAGGTGCTGTGC +TTTGATGTGCATATACATAAACATCTCAATGCATTAAAGAGCAGTATTGCCACCAGCATG +TCCCACCTCCAGCCCTAAGGCAGTTTTCTCCTATCTCAGCAGATGGAATATACAATCAAC +ACTGAGACATTCCTTTGCCCAGGGACGATCAGGAGAGAGATGCCTTCCTCTTATCTCAAC +TGCAAAGAGGCCTTCCTCTTTTACTAATCCTCCTCAGCACAGACCCTTTACAGGTGTCGG +GCTGGGGGACGGTCAGGTCTTTCCCTTCCCACGAGGCCATATTTCAGACTGTCACCTGGG +GAGAAACCTTGGACAATACCTGGCTTTCCTAGGCAGAGGTCCCTGCGGCCTTCTGCAGTG +TTTTGTGTCCCTGCTTACTTGAGATTAGGGAGTGGTGATGACTCTTAACAAGCATGCTGC +CTTCAAGCATTTGTTTAACAAAGCACATCCTGCACAGCCCTGAATCCATTAAACCTTGAG +TCGACACAGTACATGTTTCTGTGAGCACAGGGTTGGGGCTAGGGTTACAGATTAACGGCA +TCTCAAGGCAAAAGAATTTTTCTTACTACACAACAAAATGGAGCCTCTTACGTCTACTTC +TTTCTACATAGACACAGTAACAGTCTGATATCTCTTTCTTTTCCCCACAGGGACCTTCCT +GGCTGTGCCTCGGGTCAGGACCAGAATGACACCCATTCATTTCCCTGGGCCTTTGCTCGG +GCGGTCCCTGCACCCTGGCCTCTGCCTGACGAGGATGGTGGGGAGAGGAGGGGGACGTCC +CCCACACTGCTGTCTCCACTGTTCCTGCTGCCCAGGCCTCTGGGCTTCCAGGACTGCAGC +GGGTCGGTGGGTGGGCTGGCCTGAGCCCAGGAATGCACTTCAGCTCCTGGTTGAGCAATG +TCACTGAGGCTTGGGAGTCGGGTGGGGGCGGGAGGAGGCGTCCGCAGGCCCCCCTACCGT +GAGAGGCAGCCGTGGGAACAGCCTACCTCTAAACAATCACTGCAGCCCAGGCTGGCCAGG +GGCTCTGGCCGGACATAGGGGCCTGGCAGGCTGTGTGCCCTGTAAGGACACAGTCTGTCT +CTGTGCCTCAGTTTCTCTGCTGCCCAGATGGAGGGGCCCAGACTCCAGGTGTAGACATCT +GGAGCAGGCAGTGTTCAGTTGGGGAGGAAGCGGGGAGGACTGTGGGGGCCATGTGGGAAG +GATTCCACCCCACATCACCTGCACCCCTGCTGAGCCTGGTCAACGGAGCCCCTCAGTGGG +TCCTCACTCCCCTGGTTGCCTCCCATTTAGGCACCCTGAGGCCTGGGGAGAACAGAGCCA +GGCCAGTGTCCCCAGAGAGGCTGCGCTGCCAGCACAGTAGTAGCGGATTTGGATTCAGGG +AAGCAGACCTGCAGCCAGGGTGGGAAAGAGCTGCAGGTGGGGTGGGGCCCCCACATGGCA +CAGCCCCCCTCCCTGGAGGACCATGCTGCATTTCCAGGACAGCAAGTCCCAGGGATGGAT +GGTGCCTGGTGCCAAGGGCTAGAGGCATGGTCTGTCTGCATTTCCCACGTAAGTGTCTCG +TAGTCACTAGCATTTGATGCTGTCAAGACCCCCTGTCCTCTGTGCAGACTGGGAAGCCCT +TGGTCACCCTGGGGGAGTTGGGGGACCCAGGCCAGGCTGCAGAAGCATAAGGACTTGAAC +CCGGGTCCTGAGTGACACCACCTTGGGTCCTCCTCCTTCTGCCTCTGTTCAGCTCCACCT +TGATGCTGACTAGGCTGGGCCATGCGGAGAGGGTTAGGGGATAGAGATGGGAGCTGGGGA +GCAGGGCTCCACTCTGGGAGGGGGGCAGCCTTGCCGGATCCAGGGCAGAGTTAAGCGGCC +CCAGCTCTGCTTTCCCAGAGCTGCTGAGAACCTGGGGAATGGTGTGGAGGTTCCAGGGAG +CCCTGCCCCTACCTGGCAACCGCAGTGCAGCACGCACCAAGTTCTCCTGCACATTGCGAC +AGTGTGACCATGGGCTCTGGTGGGCGGTAGGTCGGGCCTTTGGACCTACCAGCAGTGAGG +GAGTTAACACAGCAGCTGACTTCTCTAGGCAAAGAAAACTCCCCTCAGACGCTTTGCTGC +CTGGCCTCCTGCCAGGAACAAGCAGGAGCTGAAAACTAGAAGTTGAGGCATGAGTTTGGC +CACTCCGTAGTGTGCACTTGGTGAGGGCAGCAGCTCGCCACAGCTGCCAGCCATCTGTCC +ATTCACCCATCTGTCCATCTGGCAGCCCGCTGTTCAGACCTGTCTGTCTGTCCGCCCATC +TGTAAGCCCATCTCTGTCCCATTGTCTATCTGACCATCTTTCTCTTACTGTCCTCTTTGT +CTAGCTATCTGGCCTGTCTGTCGATCCATCTTCGTGTCTGTCTTCAGCCCCCACCTGTTT +GTCCATCTGTCCAATTACCTGTGAGTCTATCTATGCATCTTCTTGTCCATTCATCTGCCC +ACCCATCTGTCCCTCCATCTGCCCACCGGCCTCCCCTCTCCTTCTGGGCCGCAGAGCCAT +GGCCCAGGACTACGGAGCCATGGGTGACCTGGTCCTGCTGGGGCTGGGGCTGGGGCTGGC +GCTGGCTGTCATTGTGCTGGCTGTGGTCCTCTCTCGACACCAGGCCCCATTTGACCCCCG +GCCTTTGCCCACACCGCTGTTGCTGCTGACTCCAAGGTCTTCTCAAATATTGTACGGTGA +GTGAGACGTGGGAGGAAGCTGGGTGGCCTTTGGCAGCCAGCCCCTCCTGGAGAAGGCGTG +TGTGTGTGAGCATGTGTGTGTGTGAGAGATTATGTGTGAGTGTGTGTGGGTATATGTGTG +AGTGTGTTTGTGGGGTGTGGGTGTGTGTGAATGTGTGTGATCGTGTTTGGGTGTGTGTAT +GTGTGAGTGTGGGTGTGTGTGAATGTGTGTGATTGTGTTTGTGTATGTGTGTGTGGGTGT +GTGTGAGTATATGTGAGTGTGAGTGTGTGGGGGTGTGGGTGGGTGTGAATGTGTGTGATT +GTGTTTCGCTGTGTGAGGGTGTGTGTGACTGTGAGTGTGTGAGTGTGGGTGTGTGGGTGT +GTGTAAATGTGTGAGTGTGAGTATGGGGGGTGGGTATGTGTGAATGTGTGTGATTGTGTG +TGGGTATATTTGTGGGTGTGTGTGTGTGTGCACGTGTGTGTGTGTGCACGTGCACTGGCC +CAGGAAGCAGGAGCCGTGTGTGTGGGCTTCAGCACCTGCAGGGCTTGAGCGCAAGGAGAC +AGCCTCAGGGCCCTTGCACAGAACAGGCGGCAGGGTGTGCCCGTGGGGCAGATGGGGACT +TGGGGACAATGGTGGTGTGTGAGTCCATACCTGGCTCCAGGATTCAGGAGGCCCATTTGC +ATATCCCAGGTGGGAACCTGTCTGGCCCCGCCTGACCCTGCTGGCCGGTGCAGGCCCCTT +CAGTGAGGCCAATTCTCCAAGGCTGCGGTCTTCTCCCAGGGTCATGGGTGAAGGGGTTTG +GAGGCTCCCTGCGTGGGTACTGGCCTGCTGGGGTACACACAATGCTGCCATAGCCAGTCT +GCCCCTACACCCAGCCCGGGGCCACATCTCAGGTCTCTCAGTCCTGAGGAGCCCGGTGCC +CCACCCCTCACATCCTCTCTCCCTGAGTCAGGGCCTGGGTCTCGTGAGCTGAGTGACTGA +TACTTGGTGTCCTGGATGAGGGCGTGGTGGAGAGGGGCCACAGCGGGTGTTTCCTGACCC +TCTTCCAGGAAGGTGCTGCTGCCGCTGCAGGGAGGACACACACAGGATGCCCCTTCTTGC +CCCCTGCCTCCCATTGGGCCCACAAAAGCCAGGGCAAGCCTCCCCTCCCTGCCAGCCACC +TGGTCTGCTTCCCAGAAATTCTGTCTTGCAGGCTGTTGGGAGGATCCCAGTACTTTGTAA +ACTAAAGCAAGGGAGGAGTGGCCGTTCTCTCTCTTTGTTCATTCATTCACCTTTTCATTC +ATTCCTTCTTCCCTCCATTCCCCCATCTGTCCATCCTTCCCTGCCCTGATTGCTCATGCC +ACCCCCCCAGCCCCTCCTGACCTGGTCCTTTGGTTTCTCTTCAGGGCTTTCTGTCTCCTC +CCACAGGGCTGAGAATGGCAGCTCAGGGACAAGTGGGGGCTGGGGACTGCTTAGTCTCCC +CAGTGGCTCTCAGGGGATTTGAGGGTTTGACGTCAGCTGCCACCCCAGGCTGTGCCCCTC +CTCTGCTCGGGAGGACATACAGAGATGCGACACCCACTTAAACTCGAAGTTGCAAAGATG +CAAATGAGACTGGGGTCTCAGGCACCAGAGACCACCCGTGGGCACGTGGCTTTTGGGAGT +GGGGACCTGCTGCCACAGATCTCTGAAGAGTCTGGACCTGCTGGGTCTCCCCGAGTGACT +GTCTGGGGGTCTCCATAGCATGCCCTGCTGTGTGCGTGACGGTCACTGGTTGGGTAGGGG +TCTCTACTCTAAAGCTCCCTCTGCCGGCATCCCCTCGAACTCTCCCTTGGTGAAGAGAGG +ATGTGGTTTGCCCCAGTGTTTTATCAAACAACTCTCTCCACTTCCAGTTTTAAGAAGCTG +GGAGTGGAAGAGAGCCTGGGGCTGGCCCCAGCTGCTGCTGTGAAACAGGGGTCACTGGAC +GCTGGGACCCTGGCCGGGCTGGCTGGAGGCCTCAGGAAGAGGCCTGCTACAGCGTCATCC +TGGCCAAGATTCCTCCCTGCAGAGGACCCTGGCCACGCTGCCACAGGGTCTGCTGGGGCC +ACCAGAAGCCCATGCTCCTGCCTCCATCTCTCCCCTCTGTGCTCACCTCTCACCAGGAGG +CCCTCCCAGAGTTCAGTGTCCTGCTTTTTTTTTTTTTTTTTTTTTTTTTTGTGACGGTGT +CTCACTCTGTCACCAGGCTGGAGTGCAGTGGCGCGATCTCAGCTTACTGCAACCTCTGCT +TCCTCGGTTCAAATGATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGACTACAGGTGCCA +GCCACCACGCCCCGCTAATTTCTGTATTTTTAGTAGAGACAGGGTTTCACCATGTTGGCC +CAGGATGGTCTCTATCTCTTGATTCACCCGCCTTGGCCACCCAAAGTGCTGGCATTACAG +GAGTGAGTCATGGCACCCGGCCTCATCTCCTACTCTTTCAGCACCAGGTTTTATTCTTGG +GATTCTGCTACAGCCGGAGCCCCTGGGTGCGAGTTCCTAAGGTTTCTGTGAGTGTGGACC +CAGCACCGTGCCTAGTAGACATACAAAAGGAGCATGGTGACAGTGAGGTCTGTCATCTCC +AGCATAATGACTGTTTTGATCCTTGTAAAAAAGGTGATTTTTGGCTGGGTGTGGTGGCTC +ACACCTGTAATCCCAGCACTTTGGGAGGCCGAGGGGGGTGGCTCACTTGAGGTCAGGAGT +TGGAGACCAGCCTGGGCAACATGGTGAAACCATGTCTCTACTAAAAATACAAAAATTAGC +TGGGCATGGTAGCAGGTGCCTGTAATCCCAGATACTTGGGAGGCTGAGACAGGAGAATCA +CTTGAACGCAGGAGGCAAAGGTTGCAGTAAGCCAAGATTGCACCACTGCACTCCAGCCTG +GGTGACAGAGCAAGACTTGGTCTCAAAAAAAAAAAAAAAAAAGAAAGAAAAGTTTATATT +TTTGTTCTAATGCTTATCTTAATATCGTCATTCTATAATTATATGTTTTATATAATTATA +ATAGCTATATAAGATATAATACCCCTAGTATGTTGTTTTTTGGATATTCTACTTGCTCCT +GATGGTTAATTTATGTGTCAACTTGGCTAAGCTATGGTGTCCTGTTGTTTGGTCAAATAC +TTGTCAATATCTTGCTGGGAGGTTATTTCATAGATGTGATTAACACTGACAGTCAATTGA +CTTTAAGTAAAACAGATTACCCACCATAATATGGGTGGGCCACCTCCAATCAGTTGAAGG +CCTTAAGAACAAAAACTGAGGTTTCCCAGAGAAGCAGGAATTCTGCTTCAAGACTGTAAC +ACACAAACCCTACCTGAGTTTCTGGCCTGCTGACTGCTCTACAGATTTTAGGTTCCAGAC +TTCGAGATCAACTCTTACCTGAATTTATAGCCTGCTGGCTTGCCCTACAGATTTTAAAAC +TTGCTAGTCCCCACAATCATGTGAGCCAATTCCTAAATAAGTCTCTCTCTATGTATAATC +TATTGGTTTAGTTTCTCTGAAAAACTTTCACATTCCAGTTTCCTGGATGTTAAGAATTAC +CGAAACTAGCTAGTAACTTCTTTTTTTTTTTTTTTTTGAGACAGAGTTTTGCTCTTGTTG +CCCAGGCTGGAATGCAATGGCACAATCTCAGCTCACCGCAACCTCCACTTCCTGGGTCCA +AGCAATTCTCCTCCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCATGTGCCACCATGCT +TGGCTAATTTTTGTATTTTTAGTAGAGACAGGGCTTCTCCATGTTGGTCAGGCTGGTCTT +GAACTCCCAACCTCAGGTGATCCGCCGCCTTGGCCTCACAAAGTGCTGGAATTACAGGCA +CGAGCCATTGCGCCTGGCTCCTAGTAAATTCTTCTTTTCTGTGATGTGTCCCTTACCTCT +AATAATACTTTTCTTCTTAAAGTCTACTTCATTAAAAATAGTTATGCTGGGCATGGTGGC +TCATGGCTGTAATCTTGGCACTTTGCTGGAGGTCGAGGTGGGTGGATCACTGAAGCCCAG +GAGTTCAAGACCAACCTGGGCAACATGGCGAGACCCTGCCTCTACAAAAAATACAAAAAT +TAGCTGGGTGTGGCTAGTATAATTCTAAGTTGGCACACTTGTAGTCCCAGCTACTTGGGA +TGCTGAGGTGGGAGAATCGCTTGAGCCTAGAAGGGAGAGATTGCTGTAAGCCAAGATCAC +ATCACTGCACTCCAGCCTGGGAGACAGAGTGAGGCTCTATCTCCAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAGTTATACAGCTTTCTTGGTTAGTACATGCATGACATATTTTTCATGA +TCTTCCACCTCTCTGTACCCTTATATAAAAGGCATTAGTTGGGTTTTACTTTATTTTCAA +TTATTTTAATTTTTATTGTCCTTTTAAATGTAACTAATGATTTATTTGGGTTGAAACCCA +CCACCAATTTGTTTTCCATGCCTATTCTATTTCTTCTTATCTCCTCTCACATCTTGTTTT +GGATTTATTATTTTTATTATTTAATTTCCTCCTTCTCTATTAGTTTCATAACTGTGCAGT +CTTAGAGTTCTTTTAAAAGATGACTGGATTATTTTAGAGCTTACAACATGCATCCTTCCC +TTATCAAAGTCTAACATGAGCTAGTACTTTTTGTTGTGGTTGAGATAGAGAGAGTCTTCC +TCTGCTGCCCAGGCTGGAGTGCAGTGGAGCAATCTTGGTTCACTGCAACCTCCACTTCTT +GGGTTCAAGCAATTCTCCTGCCTCAGTCACCTGAGTAGCTGGGACCACAGGTGTGCACCA +CTATGCCCGGCCAATTTTTGTATTCTTTTTCAGTAGAGACAGGGTTTCACCATGTTGGCC +AGGCTGGTCTTGAACTCCGGACCTTAAGAGATCTGCCTACCTCGGCATCCTAAAGTGTTG +GGATTACAGGCGTGAGCCACCGCACCCAGCCTATGAGTTAGTACTTCTATCCTCTTCCTA +GTCAGTACAAGAACCTTGGAACAGGAACTAAATTTACCCCCAGTGACTTATATGCTAATA +TTTTTGTGTATTTTAAATATGTGTGTGTGCATAGATGTATCTGTGTGTTTTTTGTGTTTT +TATTCTTATTTATGTTGAGAGTGTAGAGCTATGTAAGAGTAAAGAGAATTGTGTAATGAA +GCCCCGAGTATCCATTCAATTTCAACAACAATCTTATGGCCAAGCTCATTTCATGTATAC +TCTTTCCTGCTTCCCTCTACCCCACATTATTTCCGTGCAAATCCCAGATATATAACTGTA +CCCATACATATTTCAGTATGTTTTATTTCTTTTAAACCCCACAAGATATCATTTTCTATA +CTACTGTAATTTTATACCAATAACATTCATTTAGATTTACCCACACGTTTACCCTACCCT +CCGGGTCCTGTTTGAAAATCAAGCCCATGCTCACAGGCCAATTTTTTTTTCTTTTAGAGA +CAGGGTCTCACTTTGTCACCCAAGCTGGAGTGCAGTGGTGCGATTATAGCTCAATGCAGC +CTCCAATTCCTGGACTCAAGGGACCCTCCTGCCTCAGCCTGCCAAGTAGCTTGGACTATA +GCTGTATGTTTTATTATTATTTTGTAGACATGGGGTCTGGCTATGTTGTCCAGGCTATTC +TCAAAATTCCCGGCCTCGAGCAATCCTCCTGCCTCGGCCTCTCAAAGGTTGGGATTACAG +GTGTGAGGCAAGGCACCCAGCTCAGCCACAGAGCCCTGTTGCATCTCTCTTACTAGGAGC +AAGAGCTGACTGCCCCCTCATCCCCATTCCAGAGTGTTGGGGCTGTGTTGAGCCGAGGCC +AGGCCACTGGCATGGCCCAAGGAACGGGATCATTCACTGCTGCCCCAAATCTGACATCAT +TCCACCTTGACAAGACTTCCTCATCCAATCCCTTTACTTGACAGCTGGGGAAACCAACGC +GCACAGAGCACCCCCAGCTCACTCGGGGTCTCAGAGCTGATCCATGAGCAGAGGCTGAGA +TCCTGGGATCTTGTCCCCCAGCCGCCCTGCAAGCTTACTCCCTTTCTGCTGGAAGAGATG +GGGCCGGACCTCAACCAGCAGCCCTGGCCTGGACATGACTGTGCTCACCCAGGTATTGAG +GCCGAGATGCCCCGGCATCATATGTTTTTCTCTTATTTTTTCTTTTTTTTTGAGACAGTA +TCTCACTCTGTCACCCAAGCTGGAGTGCAGTGGCATGATATTGGCTCACTGCAACCTCTG +CCTCCCGCTTAAAGTGATTCTCCTGCCTCAGTCTTCCAAGTAGCTGGGCCTACAGGCTTG +TACCACCACGCCTGACTAATTTTTGTATTTTTACTAGAGACAGGGTTTCCCCATGTTGGC +CAGGCTCGTGTCGAACTCCTGACCTCAGGTGATCCACCTGCCTTGGCCTCCCAAAGTGCT +AGGATTACAGGCATGAGCCATGGCATCACTTAAACGTAGTGAGAGGCCGGGCAAGGGGCT +CATGCCTGTAATCCCAGTGCTTTGAGAGGACGAGGCTGTCAGATCACCTAAGGTCAGGAG +TTCGAGACCAGCCTGGCCAACATGGTGAAACTGTGTCTCTACAAAAAAATAGAAAAAAAA +AATCCCTGCGTGGTGGCAAGTATCTGTAGTCCCAGTTACTCAGGAGTCTGAGGCATGAGA +ATTGCTTAAACCTCGGAGGCGGAGGCTGCAGTGAGCTGAGATGGCGCCACTGCACTCCAG +CCTGGGTGACAGAGCAAGACTTTGTCTCTAAATAATTAAATAAATAAATATGGCCGAGCA +TGGTGCCTTAGGCCTGTAATCCCAACATTTTGGGAGGCTGAGGCAGGTGGTTCATGAGGT +CAGGAGCCCGAGACCAGCCTGGCCAAGATGGTGAAACACTGTCTCTACTAAAAATACAAA +AATTAGCCAGCTGTGGTGGCAGGCACCTGTAATCCCAGCTACTTGGGACACTGAGGCAGG +AGAATCGCTTGAACCTGGAAGGCAGAGGTTGCAATGAGCCGAGATTGCACCGCTGCACTC +TAGCCTGGGCGATGGAGCAAGACTCCATCTCAACTAAATAAATTAATAAATACAGAGCAA +GATTCCATCTCAAATAAATAAATAAATGTACACCTGTAATCCTAGCACTTTGGGAGGCTA +AGACAGGTCGATCACCTGACGTCAGGAGTTCGAGACCAGCCTGACCAATATGGCAAAACT +CCATCTCTACTAAAAATACAAAAATTAGCTGGGCGTTTTGACGTGTGCCTGTAGTCCCAG +CTACTTGGGAGGCTGAGACAAGAGAATTGCTTGAACCCAAGAGGTGGAGGTTGCAGTGAG +CCGAGATCTCGGCTGCACTTCAGCCTGGGTGACAGAGTGAGACTCTGTCTCAAAAGGAAT +AAATAAAATACAAAGTAAAAAAAAATGTAGTAAGATTGCAGAGTCGTGCCGCAGAAGCGT +GCTGGTCCTATCCATGTAGTGAAGGCTGATTTCATACACAAATGTCACAAGAACTTTTCT +TTTCTTTTTCTTTTTTTTTTTTTTTGAGACGGAGTCTCACTCTGTCACCCAGGCTGGAGT +GCAGTGGTGCGATCTAGGCTCACTGCAAGCTCTGCCTCCCGGGTTTATGCCATTCTCCTG +CCTCAGCCTCCTGAGTAGCTGGGACTACAGGCGCCTGCCACCTAGCCCAGCTAATTTTTT +TGTACTTTTAGAGGAGATGGGGTTTCACCGCGTTAGCCAGGATAGTCTCAATCTCCTGAC +CTCGTGATCCGCCCGTCTCGGCCTCCCAAAGTGCTGGGATTACAGGCATGAGCCACCACA +CCCGGCCTTCTTATATGCTTTTATTGCATTTGAGCGTACCTCTTTTACAGCGAAGATCTT +TTTTTTTAATTTTATTTTATTTTTAGAGATGGAGTCTTGCTTTGTTGCCCAGGCTGGAGC +ACTGTGGTGTGATCATAGCTCACTGCAGCCTTGAACTCCCGGGCACAGGTGATCCTCCCA +CCTCAGCCTCCTGAATAGCTGGGACTACAGGCATGCACCACCATGCCTGGCATATTTTAA +AGATGTTTGTAGACATGAGGTCTCGCTATGTTGCCAGGCTTGTCTCAAACTACTGGGCTC +AAGCCATCCATCCATTTCAGCCTCCCAAAGTGCTTGGATTATAGGCATGAGCACTGCGCC +TGGCCATCACACTGTTTTTTTGGTTGTTTGTTTGTTTGTTTGTTTTGAGATGGAGTCTTG +CTCTGTCGCTCAGGCTGGAGTGCAGTAGTGGGATCTCACCTCATTGCAAGCTCCGCCTTG +TGGGTTCACGCCATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCGCCCGCC +ACCACGCCTGGCTAATTTTTTGTATTTTTAGTAGAGACGGGATTTCACCGTGTTAGCCAG +GATGGTCTCGATCTCCTGACCTCGTGATCTGCCCGCCTCGGCCTCTCAAAGTGCTGGGAT +TACAGGCATGAGCCAATAAATATTTTTATAATCATTAACTACCGAGGAGAAGCTGGAGAG +AAAAAAGGTGGATGAAGTTAAGGCAGAGAGACTTTGTAAGTTTCTTGGCTGAGCTTTTGG +AGACTGTATATCAGAGATCCTATTTGAGGTGATTTTCAGCTACAGAGATAGGCCTGGTCA +TTTGAAAAATAACGGATTAGGTGAAGCTTGCGTTTGAAATCCTCCTTCTACTTTTCATCT +TTCTCTCTTGTTTATTCTGAGCATCCATCTTAGACACCCAATCTTTGTCACTTTGTGGTT +GTCATTGATTTCCCTGTTATTGAGATTAGAGGTTGGCAGACTTTCTCTGTAAAGGGCTGG +AGAGAAAGTACTTCAGACTTTGTGGTCTGTGCGGTGTCTGTTGCAACCACTTAACTCTGC +CCTGTAGAGCAAAAGCAGCCGCAGACAGTACATGGGCAGATGAGCATGGCTGGGGTCCAG +TTACATTTACTTGCAAAAAGAGGGTTGGAGACTGGGTGCGATCTCCCACCTTTAATCCCG +GCACTTTGGGAGGCCGAGGCAGGAGGATCACTTCAAGCCAGGAGTTCAAGACCAGCCTGG +GCAACAAAGCAAGACTCCATCTCTACAAAAAAATAAAAATTATTATAGCTAGGCATGGTG +GTACACACCCGTAGTCCTAGCTACTCAGGAAGCTAAAACTGAGGCAGGAGGGTCAGTTGA +GCCCAGGAGCACGAGGCTGTGGTGAGCTATTATTGTGCCAGTGCACTCCAGCCTGGTGAC +AGAGCAAGAACGGTCTCGTCAAAAAATAAACAAAAGGCTGGGCACGGTGGCTCCCGCCTG +TAATCCCTGCACTTTGGGAGACTGAGGTGGGCAGATCATGAGGTCAGGAGATTGAGACCA +TCCTGGCTAACACGGTGAAACCCTGTCTCTACTAAAAATACAAAAAGTTAGCCGGGCGTG +GTGGCGGGCGCCTGTAGTCCCAGCCACTCGGGAGGCTGAGGAGGGAGAATCGTTTGAACC +TGGGAGGCGGAGGTTGCAGTGAGCCAAGATTGTGCCACTGCACTCTAGCCTGGGCTACAG +GGCAAGACTCCATTAAAAAAAAAAAAAAAAAACCAGCAAAAACCAAACAAAACATAATGC +ATGTTCTCTCTTATAAATGGGAGCTAAACATGGGGACTCATTGACTTAAAGATGGCAACA +ACTGGGAACTGCTGGATGGGGAGGGAGGGGAGGGGTGAAAGGCCAACTGTTGGGGAGTAT +GCTCATATCCACGTGACAAACCTGCACATGTGCCCGCTGAATCTAAAATAAAAGTTGAAA +GTAGATTTAAAAAACCCCAAGAGGGCTGGGTTTGGCTTGTGTGTCCATAGCTTGTTAACC +TCCGCTTTAGATATTAACGAATAGAAACATAGTGCTTAACTTCCCAGGCCACCTATTTTG +TTCCTCTCCAAGGTGATGGATAGATGAAGGCCTTATCCAGCCGCCTGGAAGTTTGCTGAC +GCTTGTCCTGTCACGGATTAATGAAGCATTGTTTTCTGATGAAGGTTTCATGCCGCTGTG +CTGATGTGTCTTCTCTTCTCTCTAGGCAGGAAACTGCATATCTTCTGGTTTACATGAAGA +TGGAGTGCTAATGGAAATGCCCAAAACCTTCAGAGATTGACACGCTGTCATTTTCCATTT +CCGTTCCTGGATCTACGGAGTCTTCTAAGAGATTTTGCAATGAGGAGAAGCATTGTTTTC +AAACTATATAACTGAGCCTTATTTATAATTAGGGATATTATCAAAATATGTAACCATGAG +GCCCCTCAGGTCCTGATCAGTCAGAATGGATGCTTTCACCAGCAGACCCGGCCATGTGGC +TGCTCGGTCCTGGGTGCTCGCTGCTGTGCGAGACATTAGCCCTTTAGTTATGAGCCTGTG +GGAACTTCAGGGGTTCCCAGTGGGGAGAGCAGTGGCAGTGGGAGGCATCTGGGGGCCAAA +GGTCAGTGGCGGGGGGTATTTCAGTATTATACAACTGCTGTGACCAGACTTGTATACTGG +CTGAATATCAGTGCTGTTTGTAATTTTTCACTTTGAGAACCAACATTAATTCCATATGAA +TCAAGTGTTTTGTAACTGCTATTCATTTATTCAGCAAATATTTATTGATCATCTCTTCTC +CATAAGATAGTGTGATAAACACAGTCATGAATAAAGTTATTTTCCACAAAAGGACTTTGC +AGTTTTAACGGGGGGCAGTAGGGCTTGTGCTATAGAAATTCAAAGGCAAGGGAAGTCACT +TCTGTTGTGGGGCCCTGGGAGGAGCCTCCAGGCTGGAAAGGCTTAAGGTGGAGGTCTCCG +ATAGGGGCAGCGTACACAGTGGACTGGCTGCAAAAGGCCGTGCTCAGCATTCAGACAGCA +TCACACACTCCGCTTTTCTCTACCAGGGAGGCAGGTGGGGAAGGATAGCGATGGGAAGGC +AGGCGGAGCTCAGAATGTGGAAGGGGATCCAGTAAGGCTTGGAAGTTTGCACCTGATCTG +GTGGGTGGTGAGGAGCCCTTGAAGGGGCAAGGAGGCGAGGAGCACTCAGCTGTGTTCTTA +CACTGATCTGCCACTGGGGTTAGAGACAAACGTGGTGGGAATGGAAAGCCACGCACAGTC +ACTAGCGCCTCTGGGGGGAGAATGGATGTGGCTGGTGAGAGAACAGGGGGGCCCAGGGAG +AGTCCGGCACCAACCTGGGCGGGGGAGCCCAGTGGGTGTGAGCACCCCCACTTTAGAGAT +GAAGTGATGGAGACATTCAGATGTTTAACCCCTTGTTCAAGATTCCATACTTGATAAATG +GCAGATCAAACTCCCAACATAAAATGTGGGTCATTTCTTTATTATTTTATTTGTATTGGT +TAACAATGATCAGCCATGCAAGAATAAATGATTATTGTAAAATCTGCAAACAATGTAGAT +ATGTAGAGAGTCCCTTCCTTGGAGCTTGACCTTGTCAGACAGGTATAGATGAGTGTTCCG +GGGCAGCCGTAAAAACTGCCAGAGACTGGGCTGCTTATAACAGAAACGCATGGTCTCCCA +GAAGCCCACATTCAAGGTGTCCAAAGGCCTGGCTCCTGGAGGCTCTGGAGGAGAGCCTGT +TCCCTGTCTCTCAGCTTCTGCCGGTTGCCAGCAAGTGTTGCCGTTCATTCACTCCAGCCA +CTGCCTCCATCTGCACACAGCAAAACAGCGTATCCTGAAGTGCTCAACCTTATAGCCATT +ATTTTAAAATATCCGGAACACACAGGACCGTGGGAGTGGCTGTTGGAGAAATTTTCATGA +AGGAAGAAAGATTACAACTAAGTTTTAAAATGCTAGTTTTGTTTGTTTTGTCTTGGAGAG +GAGGTAAAAGTGGGAGTAAAAATAGGGAGTTTGGTGTAAGGTGGGAAAAGCAAAGGAACC +CCGCATGGATGGGCTGAAGGGTGTGATGGGAGAACAGTGAGAAGTACGTTTGGGGAAGCA +ATTGGAAATAGTAGCTAAGCTTAATCACAATCTATCAAAAGGGACTTGTTGAAGAATTAA +TGTGTGACTAGGAACAGGGAGGTTATGGGCTTGTCAGCTCGACAGCGGGCACTCAGTTCC +ACTAACGAATGATGCCCGTGTGGACAGACAGAATGATGGACAGGCAGATGAATGCGTGGG +CTTTATGTGAAACAGGTCCTCTTGGTTGTTGACAAGATACTGTTTTAAAGTTCCATTTTG +CCATACTTCGAACAGCTTGTCATTAGCTCAATTTAGCCACATGTAAAATCACTAAGGCGG +ACTTCCAGAGTTCCCACATGAAAATCAAATGTAAACCAGCAGTGACCTGCTTCAACACCA +TCATCGGAAGTCAGAAGTTGAACTCTTTTTTGATGTTTAAAGCCTGCATAATATTCGCTG +TATTATTATTCAGCATATTACTATTTCCTTCGTGATGGAAATTTGGTTTATCCCAATTTT +CTATTCCATCAAAACACCGCTACATAGAAAATCCCCATGCACATATTTCTCCTAATTGTG +GAAATATTTTACATAAAAGACTCTAGACATGGGATGAAATTCCCAGGTTATTGGAATTTT +AAAATAGATAGGTACTTCCAAATTGACCTCTTACAAATTATATGAATTCGTAAGCTTCCA +ACTGTTATGGAGTTACCCATTTTGAGAAATCTGTGCTAAAAGGACCCAAACAATGCTGAT +GACAATGATCAGGATAATAAGTACGCTGGGAAGACAACAAAATGATTTAGATCTTAGACA +AGTCATTCTAGGTGTCTCCACTGTTTCAGTTCTTGCGTTCGTTCATTCTTGTGCTTTTTC +GTTTTACCAAATAAAATAGCTCCTTGATGTCATAGGAATCCACGCTATGCTTAATGAGTA +TTGGTTAGTAAAATGCCTATAACTAGTAATCTTCATCTATGCAATTAAATATTAATTCAT +AAAACACTTCAAATGTAAACAATAATTAGTAAATGAAAAGTACATAATACCTCAATTAGA +AAAAAATCACTCCATTAAAAAGACATTATTTGTGTGATAAAAGAGATTGCTATTTTTGTA +TTTTTCTACAAGGTTAAAGAAAACTAAGTCAACTTATACAAGTGAATTTTAAAAGACTTT +AGGGCAGGCGTGGTGGCTCACACCTGTAATCCCAGCACTTTAAGAGGCCGAGGAGGGCAG +ATCACCTGAGGTCAGGAGTTCGAAACCAGCCTGACCAACATGGTGAAATCTCATTTCTAC +TAAAAATACAAAAAAATTAGCCCAGTGTGGTGGCATGTGCCTATAATCTCAGCTACTTGG +GAGGCTGAGACAGGAGAATAGTTTGAACCTGGGAGGCGGAGGTTGCAATGAACCAGGATC +GCACCATTGCACTCCAGCTTGGGCAACAAGAGTGAAACTCCATCTCAAAAATAAATAAAT +AAATAAATAAATAAAATAAATAAAAGCCTTTAACCCAGAATGCTGAGTAAATTGGCCAAA +AATGCTAACCTATGCATTTCAATACTATAGGAGTCGCATGGGTAGAAATAACCAGATGAA +ATACTTCTGGTATTTCACCTTCCCAACCCACACGAGCCAGTGTTTTTCTGTGAATAACAA +AAACAGCAGAATTTACTTGCCTCACCATAAGAGGTTACCACTTCTGTGTGTTCCCCCGAA +ACAGGTGGTGGCTGGGTGAGAAGGTGGACAGCACTAGGGCAGGAGATGGGGGCTCCAGTA +TCGTGGGTGAGCTTCCTAAACCTCTGCAACTTTCAGCCCCTAAATGGGATGAGCCATCAG +AATTTTTAGCACAATGCCCAGAACAAAGTAAGGATTTGACAAATGACGCCTCTCTCCACA +TTGTTCTGTCATCAGCCACCGCATCCTGTACCTCCAAGTCCACTGGGCTCCGGCTGTTTC +CATCACATGGAGAATGACTCAGAGCCTGGCCTCCAGCCACCCTCCTGGCCTTTCTGCTTC +TCACTCTGCCACTGGCTCCTCATGGACCACCAGCCTGGGTGTCCTCAGACATACCACACA +CTTCACTGTGGGAGTCACGCAGCCCTCACTGCTCCTTCGCCAGGGAGCCACGGGGCTTTC +CTCCTCAGGAGGACTCTGCAAGCAGCTGGATGAAGGGCCCTCCCGTCTCTCATCCTTCCT +TAATTTTTGTCACAGTTCTCCTTCCTTCCACTCAGTGCAGCGCACACTGATTGATCCTCC +ATCTTCCCCAAAAGACAGGAACAGCATGAGCAGTGGAGAGTAGATTCCAATGATAGAAAA +AATAGTCAGTGATTTCTCATTTCCATTGATCATCAATGAAGAAAATGTATCCTGAAGGTC +ATGTACCTCCTATGGGACTGCTGCATCCTCAGCCTCCTGAATTTCAGCCCAGCACCTTCC +TCCCCAGCACAGCAACAGGTCAGCCCTTACCAGCATCCCTCTCTTATTGCCTTTGTGCAG +AGCCAGCACCAGGGCCAGGGGAGGCCTTGGGATTGTCCCTCCCCAACAATCTGTGAAACA +ATCCTTTATGTCACCAACAAAGCACAGCCTTCTGCACTGGTGGTCAGTCCCTCTCAACAC +CTCTGTCACTGTAAAGCTGGCAGGCAACCCTCCAAGGTTGGCCTTCCCAAGCACTGCACC +TCTAGGTGACAGAGCACGTCCTTACCTTGAAGCCTGGGCGCCCAGTCTATCCTGTCCAAT +GAGCGAGCTGTGGAGAAGGGGGGATTCCGGGTTAAGGGGAGACTAGCAGGGCTCCTGCTT +TTATGTTGCCCTGTTGGGAAGGCTATTAAAGAAACACAAAGTGCTAAGCAGTGAGGATAG +AACATGTTTTCATTATTTCAACCAATACATTCCACAGATGGAATAATAAGAAATGCTACA +ACCAAGCTAACTGAATCCAACAGCATATCAAAAAGATAATCCACCATGATTCAAGTGGGT +TTCATACTAGGGATGCAGGGATGGTTTAACATACGCAAGTCAATAAATGTGATACATCAC +ATCAATAAAACTAAAAACAAAAATCACATGATAATCTGAATAGATGCAGAAAAAGCCTTT +GACAAAATCCAGCATTTCTTTATGATTAAAACCGTTCGTCACAATCAGCATAGAACGGAC +ATACCTTAAGGTAATAAAAGCTATCTATGACAAACCCACAGCCAACATTTTCCTGAATGG +GGGAGAGTTGAAAGCATTCCCCCTGAGGAAGGGAACAAGACAAAGATGCCCACGTTCACC +GCTTCTCAACACAGTGCTGTTCACTACAGCATTGGTTATAAGAGCAAGACTGGAAACAGA +ACAAATGGATACCCATAGCGGGGTGCTTAAGTAATTTTGGGAATAGTCATGGGGTGCAGT +ACTTTATAGCTCTGAAACAATACAATGGATTTACATTTGAAATGTGGAATGATAACTAAG +GTGCATTGCCCAGTGATATATGCAGAGGTGCAGAGGACTTTGTGTAAACACGATCACACA +TCAGCCTGCATTCCAGGTGCATGCTTCTATTTGCACATAGATTGCAGGGATGATATGCAA +ACAAAAATGTTGACTTGGTGTTTGGAAGTTCAGAGTGGAAGGGAAACTTCCTTGCTAACC +TTTTATGATATTTAGAGTTTCTAAATGTGAATACGTAATACATTTAGAAATCTTAGTTAA +TAAGAAAAGCCTCTGTTCCTGGCCTCTTGCTGGCACATGTCAGGTGGAAATGGGGCTGTC +ATGCTAATGTGTGCAAACTGAGAAAAATCCAAGAATGGGAGTCTGCTTTTTTCATCATAC +AAATAATTGTTAATAGAAACAGTATGATAATTGCTCATTGATATACCATGCATATTCTAT +TAGATAATAATAAATTTCTGAAATTTGAACTATACTTACACATGGAAATTGAAATATATG +GATGAAACATTGTGGCTTATATAGGCAATTGTTTTATTGGCATTTTACAAACTGATCATC +ATTCCTCATGGCACGGGTCCATGTGATATTAAGTAGCTTGTTATGCTTGGGAAAGGCAGT +GATGACCACAAGAATGACTTCAACTACTAAAGTACAATGGAGATTTCAACAATGTTTTGT +TTAATATTTAAATATTTCATTGTGCTCCCAGGCTTTTTCTCACCCTAATAGCTCTCATCC +ATATCATGTGGGTCCCATTAATACAGATACCTCCGAATGCACCACTCTTCCATTATATCC +AGTCAATTGCTGGTTACCTTGGGCCTACAACTGGGGGAGGGCAGGGGCTGCTGGCCACCT +CCTCATCTACAGTAAGAGTCAATGAGCAGTTAAGTGGATACTGAAAACCATTTATCCTGC +TGGAGTGAGAAATAAATGGTTTCTTTCAATAGCGTAGTAAAATGCATCTTTTCCAAACTA +TTTATATGACTCAAGGCCCATCTCAATTTCAGATGTGGTTAGCCTCAATTCCTGATTCTC +ACCAAGGTGTGTAATGTCATCCACGGCCCAGTGCAGAGGAACACAGGTGCTGCCGTCAGA +CTGCCAGGGTCCAATCCCGCCTCCTCACTCACCCCGGGAGATCCCTTTAAGCCAGGAGTC +AACAGTGAGGATGGAAACATGAGTGCTTTTTAAAGTCCTGAAAGTTCAGAGGCAGACTGT +CAATTTCTCCTCCACCCCTGGGCACACACCAGGAGAACTCTGTCTCCAGGTTGAAGGAAG +TGCCTGTGAGAGAGTTGTGTCCCTCAGATTCTGTTCACCACAGGTGACACTCGATGCAAC +CCCAAACCTCTTCTGCACAATCCCAAGGGGTGCTGACTAATCCAACCCAAAGGCTGTGAT +GTTTGGCAGAGGCAGAAAAGAAAAGGCCAGGTGTTCTGGGAAAGACCACCTTTAAATATC +ACAGCACCCTCATAGCCCAGAGAGACAGTTCTAACTATTATGCCAATAAACCCGGAAAAG +ACCAAATCCAATATGACACATATTTCCTGTTTCCTTTTGATTTCATGCCCCCTCCCTTAA +CCTCCCAAGCAGCATGGATACCCCGAAGGCCCCTGGGAACTCTCTCCAATTGGATCTTAC +GTGGAAAGTAGTTACCTACCTACAAATCCCCATCATCAGATATGCTCTCCACAATCAAAT +CTTTAGAAACACAAACACCAGGATAAGTCATTAGAGAGAGGCCCACCCACTCCTCCCACC +CTAGCTGAAGCCATGGTGCTTCGCACAGGATCCCCTGGTGTTTCCTCTGGGCTCACAGAT +ATCCCTACAGCCTCTCTGGACATTGTTTTATACTTGCAAAATCATTTGCTCTCACCAGAC +TCCAAATCCTCCTTCCCAAAAGGAGCCCAGAATCAGGTTTCTGTACCCTAGAGATGGCGT +TTTTTCCTCAGGAAGTGAGTTATTTCAGGGTAGGTATCATTCTCCAGTGTCAATGGCTCC +TGCAATTATAGAAAAGAAAACATTAGGAGGGTGAAATGATGCCATACACGTCACACAGAT +CTGATAGTCTCTCGACAACTTGAGAGAGAAAATAAGAAGGGGTATAGTGATTGAGTCAAA +GGTCAAAGTCCCCCAAAACTGGCACGGAAGACACCTGTGGAAAAGACAAGACCTTTTCCC +ACAGAATTTATCTTTAAAGTGTATCTAGATTGGCAGTTTCACAACTCTTAATCCATGGGG +GAAAACTGCTGTGGAGGGAAACACCTCTGCATTGCAGTGGATCGTGGATGCTGCCATCTA +CCACACCCCAGTGTGCCTGGCATGGGTTGGTGAGAGGCTGCCAATCAATAGCACCACACC +AAGGGAATTGCAGATGTCATAAATAGTCCACATTGGCAGATGTTCATGTCTACATTTGAT +TAAACTGCAGATGACATCCATAATGCACACTGGCAGATGTTCATGTCTACATCTGATTGG +AAAGAAGCCAGGAAAGTAACATTTCTGTTCAAGACAAAGAAAAGTGTCTTACATTGGCAG +CATCTTCTTTTTTACAGATGTCTTGTACAGTGTCCTCATTAGCAATGTCATATACAGCGT +CCTTATTAGCGAATTCGTATACAGCATCCTCATTAGCGATGCCATATACAGCGTCCTCAT +TAGCGATGTTGTATACAGCGTCCTCATTAGTGATGTCGTATAGAGCGTCCTCATTAGCGA +TGTCATATACAATGTCCTCATTAGCGATGTCATATACAGCAACCTCATTCGCTATGTCTT +GTAAAGCATCCTCATTAGCGATGTCATATACAACGTCCTCATTAGCGATGTCGTATACAG +CGTCCTCGTTAGTGATGTCTTGTACGGTGTCCTTATAAGCAATGTCGTCTACAGCGTCCT +CGTTAGCATGCCTTGTGGGTGTCATTAGCGATGTCATATACAGCATCCTCATTGGTGATG +TCTTATATGGTGTCATTAGCGATGTTGTGTACAGCGTCCTCGTTAGCAATGCCTTGTACA +GTGTCCTCGTTAGCAATGTCATATACAGTGTCCTCATTAGCGATGGCTTATACACTGTCC +TCATTAGCGATGTTGTGTACAGCATCCTTGTTAGTGTGCCTCGTACGGTGTCATTAGCGA +TGTCGTATACAGCGTCATAATTAGCGATGTCTTATACGGTGTCATCATTAGTGATGTTGT +GTACAGCGTCATCGTTAGCGATGCCTTGTATGGTGTCCTCATTAGCGATGTCGTATACAG +CGTGCTCACTAGCGATGTCTTTTTTTTTTTATATATACTTTAAGTTTTAGGGTACATGTG +CACATTGTGCAGGTTAGTTACATATGTATACATGTGCCACGCTGGTGCGCTGCACCCACT +AACTCATCATCTAGCATTAGGTATATCTCCCGATGCTATCCCTCCCCCCCCCACCCCACA +AGAGTCCCCAGAGTGTGATATTCCCCTTCCTGTGTCCATGTGATCTCATTGTTCAATTCC +CACCTATGAGTGAGAATATGCGGTGTTTGGTTTTTTGTTCTTGCGATAGTTACTAGCGAT +GTCTTATACGGTGTCCTCATTAGCAATGTCGTGTACAGCGTCCACGTTAGCGTGCCTTGT +CGGTATCATTAGCAATGTCGTATAAAGCGCCCTCATTGGTGATGTCTTGTACGGTGCCGT +CATTAGCGATGTTGTGTACAGTGTCCTTGTTAGTGACGGCTTGTATGGTGTCCTCGTTAG +CGATGTCGTATACAGCGTCCTCATTACCGATGCCTTGTATGGTGTCCTCATTAGCGATGT +CGTGTACAGCGTCCTCGTTAGCGTGCCTTGTACGGTGTCATTAGCGATGTCATATACGGC +ACCCTCATTAGCGATGTCGTATACGGAGTCCTCATTAGCGATGTCGTGTACAGCGTCCAC +GATAGCGTGCCTTGTCGGTATCATTAGCAATGTCGTATAAAGCGCCCTCATTGGTGATGT +CTTGTACGGTGCCATCATTAGCGATGTTGTGTACAGTGTCCTTGTTAGCGACGGCTTGTA +TGGTGTCCTCGTTAGCGATGTCGTATACAGCGTCCTCATTACCGATGCCTTGTATGGTGT +CCTCATTAGCGATGTCGTGTACAGCGTCCTCGTTAGCGTGCCTTGTACGGTGTCATTAGC +GATGTCATATACGGCACCCTCATTAGCGATGTCGTATACGGAGTCCTCATTAGCAATGTC +GTGTACAGTGTCCACGTTAGCGTGCCTTGTCGGTGCCATTAGCAATGTCGTATAAAGCGC +CCTCATTGGTGATGTCTTGTATGGTGCCGTCATTAGCGATGTTGTGTACAGTGTCCTTGT +TAGCGACGGCTTGTAGAGTGTCCTTGTTAGCGATGTCATATACAACGTCCTCATTACCAA +TGCCTTGTATGGTGTCCTCATTAGCGATGTCGTGTACAGCGTCCTCGTTAGTGTGCCTTG +TACGGTGTCATTAGCGATGTCATATATGGCATCCTCATTAGCGATGTCGTATACGGAGTC +CTCATTAGCGATGCCGTGCACGGCATCCTCGTTAGCAATGCCGTGGGCAGCATCCTCGTT +GGCGATGCCGTGGGCGGCGTCCTCCTTGGCGATGCCCTGGGCGGCGTCCTCGTTGGCGAT +GCCCTGGGCGGCGACCTCGTTGGCGATGCCCTGGGCGGCGTCCTCGCTGGCGATTCCGTG +GGCGGCGTCCTCGTTGGCGATGCCCTGGGCGGCGTCCTCGTTGGCGATGCCCTTGTCGGC +GGCCTCGTTAGCGATGCCGTGGACAGCGTCCTCGTTAGTGATATCGTGTGAGGCATCCTC +GTTAGTGATGTTGTGTACGGTGTCCTCATGGGGAGCTAGAAGAACACAGAGTTAAGGTCA +GTGCCCTGGTAGTGGAGACTGTGAATCACCCAGGGGCTTGCTTGGTGTGGTGCATGGAGG +TGGCTGATCACAGCATGGGCCAAGCTGATGCTGGGACATCCTCCCAGGTGGACCTGCACT +AGTGAAGCTAAGGGATGTGGCTCAGAACACTTTCTGCAGTGGGCATCAGTTTCCAGGTTC +AGGTATGCATTATCCAGTGAAGTGGGGAAATATAAAAAATAAAAATTGACAAATTCATGA +AAAGCCTTCCATGAGTGCAAGTGTGAGTTTTTTATCCACTTTACATTCAGTATGCATTCA +CACATACAAAATATTTTTACAAGAAATCAGAAATTTTAATTTTTGTCAGTTATGCGAAAT +CTAACTTAGCTGCCAACATAAAGATTCTATCTCATTTACTTGGTCTCGAGAAAATCTAGC +ACATAGTAAGTAGACCAAAATGTTCATTAAATGAAAACACAGAGCAGAGATAGGGGGGCT +GCTAGGCAGACTGGGTTGCACCTGATTACCTGGATGATAATTAACTGCACAAAACCTCGG +TCAAATTAATATTGAAACTGCCTTTTGCTTGGGCTCGTTTCCCTTGCGGAAGAAGGATGA +CCAAGGAGATGAACAGGAAAGAAATGAGAAACAGAGGCCTTTGCCTAGTAGCTAAAGGCC +ACCTTCTATAACACGAAATAGCCTTGAACTCTGCCGTGATTTAGTGACAGAGTTCCCTCG +TGTCTTCTACCCAGGTTGAAGTCCAGCAAAATTGCGACTGTCCTCTTTACAACTTGCGAG +ACCACACTGCTTCTGCATTTGCCTGTTGTATGTATGAGATTTACACTTGTTTTAAAGCAA +CATTTTGTTTCAGTTGGGCTGGTGGCCATACCCGGCACTAGCCAGTCAATAGTGAGATGG +CTCCTCATGGAGGAGGCTTGGCTTGAGGCTGAGGGTCTTTAACCCACATATACAAGAGAG +TTGCCACTAAGGGATGGAAGCCAGGCTAATAACCAAGTGCCACACAGAGTTCCTATCTGT +CCCTCCTCACCATTTTTGGCTGGCAGGATTTGAGCATTTTAGGGCTTGGGAAGATAGTAT +TACTAAATCTACTAAAATACATCACCCATCCTTATAGACTTTGGCCAGTTGCTGAGCAAA +TTAACTTCACAACTGAAGTGGGCCACACTGGCCTTTGTGGTCCCCCACTCCTCTTAGAAT +TTGTGAGCGTGGGGCCTACTGGAGGGTGGGAGGTGGGAGGAGGGGGTGGATCAGGAAAAA +TAACTGATATTAGGCTCAATATATGGGTGATGCAATAATCTGTACAACAAACTCTCATGA +CACACATTTATATATGTAGCAAACCTGCACATCCTGCACATGTACCCCTGAACTGAAAAG +TTAAATAAAAAAAAAAAAAGGATCGGTGAGCTGAGCCAAACACCTGGGGATCTTTGTGCT +TTTGACACACTGATGACTATGCCTGTCCGTGGGGAGATGAACCCATAACTGCCCTGGGTT +GTGTGACCACGGAGGCCACTTTATGATGATGGGCAGTGTCTGGGGCCTTTTGGGCTCGGT +GCCTTAGGGTTTATACATGAATGCTGGACTCCCTGTGTGGTGGTGAACACCCCATGACTA +AGTGCATGTCAGCGTCAGCACTGGCCCACACTCCTGGGTTCGTGTTTTCACTTTTTCATT +CAGGAACTCGGGAGCTGGGGCCACTCCCTTGGCCCTTCAGGTTCTCCACCTGAGCAGTGG +GGATAATAAGGCAGACCCGGGGATGGCTCTGGTGAGGGTGGAGGAGTCACTGTACAGAGA +GAGTAGAGCGGGGGTGGATTTTATTGTTAGAAGTGGACACTGGTGATTGGGTTGTATAAA +TGGGAAATCTCTCCTGAGAAAACACACAGCCTCACCTGTACAGAAACACACACATTCACA +CCACACGATGCAGCCTCACACAAGACACCACCAATCCTCAAGCACCCAACTCAGCACCAC +CCAAAAGGGAGCACAGCTGCTTCCTCAAAATTTGGCCATAATTTTTCCCTGGGGAATTCA +GGTTTTAAAAAAACACTTCCCCTATACTTATTCCTATCACAATCCCAGGATCAGGGTGGC +TCTTCACATTGAAACCAGGCAAGGATGCCACACCTTTCTTGGCATCCAGATTGTTTTCTT +GGTAAGTGATTCCAGAATACTTACTAGATTCACGCCTCAGAGGGGCCACCTGCACCACCT +GCAATACAGAAACAAAGCTTTTTGAGGGGTATGTCATGTTGTGGATTGTTTGCACAAGGC +TGTGTTTCTCTCAATGAATATTGAAAACTTGATCAGAAAGTGTAGTCAACTTCAAGGCCT +CCAAAACAAGGGTAGGATACACACTGGAAAAGACATCAGCTTCTGGATGGCGGATCTCTC +AGGTCCACGTAGGTTGGCAAGTGCAAAATACTGAATCCAAGGAGAAGACATTGCTTCCAA +GGACAAGGACCCCAAGGATACAGTCTACAACCTGAAGCCATCATAGCTAAATGCCATTTT +GGATTACATATCAGTTGCTAAGAGTCACTTCTTCCTCCCCCTCAGAAAACTGCATTTAAT +ACCTGTCATGGACATTGTCATCTTTTCACATGTAAAGTCAGTTGAAAAAGAAAGACAACA +AGAAAGGAACATTTCTATTTCAGAGAAAGCAAGGCAACCTTACCTTCACGTTGACTGGCC +TCTCTCCATCTCCTCTGTCCTTGTGAACTAGAGACTCCTCAGAGGCTAGGAGGACACAGA +GCAACAGTTAGTCATAGATGCTTTTGTTCATGAGCTATTCAGGGAGCTCTGCTTAATGTG +GACAACAGGACAGTGTGTGTGGATGTGTTTCATTAAAAGCACAGCTTGAGCTCCTGCTAG +AAAATCCTCCCTCGTGGAAAGACAGGCAAGAACGAGGAGCTAAGGAGCAAGAAATAGAGT +CCCTGGCATTTTGCTGATGGCAACTTAAGGCAATGGGAATGAGTCAGTCTACAAATGGTA +CTGAAGCACATGCTATAGTTTGATGAGAGTCCCACTGCTCACACTGTGAGGTTTGAAACC +CAGCTAAATGGTTTTCTAAACCTGTAAAAACAATATTACTTGCAGGATTTATGTCCCAAG +ACTACTTTTACCTCTGAGGATCCACAGTGGCTGTCACTGCAGTTATTATGTGTTTTAGCA +TTTTGCACTTGAATAAAAGCAAAGTTTAATAGACAGATTGGATTCAATTCTAGGCAAAAC +AGTCTATGGTATTTATTCACTAATCCTTTGTTATAACTGCTGATGGGAGAATTAGAAGTA +CTGAAATTATATCCTTTAAAATTAATTAAAGCATAATTATTAATCACACAATATTTTTTC +ATCCAGGCCTCCTTTTCTTTGTCATGCATGCATATTAATTGAGGATGGAGAATATCTACG +CTTGTTCAGGCCAGCCAACATACGACAGTTTACTTCAAGACAGGAGACATGGGTTGAATG +CTGGTATGTTTTAACTCTGCAGCGCAAACAGTTGCAACAAGTGTGGTGAACTAATCACCA +GATGGCCCTTTGCTGCCTTATTTGTCATTGTGCCTTACATGTAGCTTGCAGGATTTGATT +ACGCTTATGTTTTGTGGTGATCATACTTTCAACTATTCCTAAAATACTGCTTCAGTCTTA +TCTGTTTGGGGTCAACTGCTGAGGATTTCATACAAATTAATGAAGTTTGTGAATCTAAAG +TTCTACACAAAGGGGGAAATATTTGCAAATCATTTATCTTGTAAGAGACTAAAATTTAGA +ATATTTTTAAATATATTTAAGATATATTCAAAAATCTACAGCAACAAACTAACTAAATAA +AAATCAGACAACTCTTTAAAAATGGGCAAAAGACTTCAACATATATTTCCCTAAAGAAGA +TATAGCCACAAATAGTAGCACAGGAAAAGCTGCTCAGGATCATTAGTCATTAGGGAAATG +CAAATGAAAAACACAAGCAGCCACCAATATACACCTACTAGGATGATTTAAAGGAAAATA +AGTGTGAACAAGGATGTAAAGAAATTGTAACCCTGATACATTGATGGTAGAAATGGATAA +AGTTGCAGCCACTGTGAAAAACAGTCTGCAGTGGCTCAGAAGGTTAAATATAGAACCCCT +GTTGGACCCAGGAACTCTACTCTTAGGCACCCCAAAGAATAGAGAACAGAAATCAAACAG +ATGTTTGTATACTAATGTTTGTAGCATCACTTTTCACAGGAGCCAAAAGGTGGAAATAAT +CCAACCATCAGTGAACAAATGAATGTAATAAAAGCAAGGTGGTCTGCATGCAATGCTACA +TCATCCATCTGTAAAAAACGAACATCATTTTGATAGATGATACAACATGGGTGGACATTG +AGAACATTATGCTTAGTGAAATAAGCCAGACACAAAAGGAATATATTGTATAATTGTAAT +TACATGAAGTGCCTAGAATAGTCAAATTCATACAAGAGAAAGTCGGATAGGAATCACCAT +GGGCTGGAAATAGGGGGAAGGCGCTATATTGCTTATTGTGGACAAGGTTTTGTAAGAAAT +CATCAAAATTGTGGGTGTAGATAGTGGTGTTGGTTATGCAACCCTGTGAATATATTGAAT +GCCACGGAGTGCACACTTTGGTTAAAAGGTTCAAATGATAAATAATGTGTTATATATATT +TCCCCACGATAGAAAACATGCACAGCCAAGCCCAGATGCCAGTCTTGTTAGCTGCCTTCC +TTTACCTTCAAGAGTGGGCTGAAGCTTGTCCAATCTTTCAAGGTTGCTGAAGACTGTATG +ATGGAAGTCATCTGCATTGGGAAAGAAATTAATGGAGAGAGGAGAAAACTTGAGAATCCA +CACTACTCACCCTGCAGGGCCAAGAACTCTGTCTCCCATGCATTGCTGACCCATCTCAGT +ATTTCCTGTGACCACCTCCTTTTTCAACTGAAGACTTTGCACCTGAAGGGGTTCCCAGGT +TTTTCACCTCGGCCCTTGTCAGGACTGATCCTCTCAACTACTGACCATTTCACCTCCATT +CATGTCCATGCCACATCAGGCTGTGTTGTCTAGATGGCATGAATCTACCCCAAATGTCCC +TTTCTGGAGGAAGCCACCATTATGCTGTACCTCCAAGCATAATGATACGTCCACACACAC +CAAGGCACCTCACTCATGCAAGGTGTGTGTCCTCTAACAAAGTTTCACGCTCTAAACCCA +GATAACTTTTGAAACCCAAGTTCTGTTGATTCCCCTACTTTGGGTGCTCCATAGATGCTC +ATTTGTCTACTAAACACTGCCCCAGGCAATTAAATATTCCAAAGTGACCAGCAGAATTTT +TATGTTAATTCTGACATTGCATTGTTAGTACAAGTGTTTTTCCCCCTTCAAATTTATGTC +TTTGTTACTGATAAATGTAACTGATAATGCTTTTTTCAGCTATGTTGCCAAGCATATTTA +TATAAAAATATACTCAGATTGTTTTCAGAATTTGACAAAGATGATAGCAACAACGATAAT +CTCATTTGTCTTATACTAATCTTTATGTGTTACTTTCATCATTTCTTACATATTGGGGCC +TACCATACATTGTACGGTGAAATTAGTGCTATGCATCATGGTAGGAATATAAATTGGCAA +AAGTAATTTAGAAAATAGTTCCCTTCTTTCTTAAAAAAATTAGGCTGGGTGTGGTGGCTC +ATGCCTATAATCCCAGCACTTTGGGAGGCAGAGGTGGGTGGATCACCTGAGGCTAGGAGT +TTGAGACTAGCCTGACCAACACAGCAAAATCCTGTCTCTACTGAAAATACAAAAATTATC +CAGGTGTGGTGGTGTGTGCCAGTTGTCCCAGCTACTCGGGAGGTTGAGGCACGAGAATTG +CTTAAACCTGGGAGATGGAGGTTCCAGTGAGCCGAGATTGTGCCACTGCACTCCAGCCTG +GGTCTCAGAAAAAAAAAAATTTTTTTTGACCAAAATGTCATTATGCATTACATGACTGTA +TATGAATGCTCAAAGCTACATTACTCATCAAAGAAAATAACAAAACAATTAAATGTCCAT +TAACTGATAAATGAATAAACACTATCTGTATGAATAAACACAGCAGACTATGAAGGAAAA +CACATGACCAGCACGTGCTAACACGTCAATTAACTTCAAACATAGTATGCTAAATGAGGG +AAGTCAGATTCCAAATATATATATATGTCCATTTCTATAAAGCAAGTGGGAAATTTATGG +AGATGGAATGTCACAGCAGTATTGCTTAGGGCTGGAGATGGGAGTGGGGATTAACTGCCA +GTGCGCAAGAGAGAACTTGGGTGAGGGAAACATATTTAAATTAGATCGTGGTGTTGGGTG +CACACAGTATCAATTTAATAAAGCATCAAATTCTAGACCTTTTCAGTGGGCAAACTTTAT +GGTGGGTTCACACCCAATATAGGTGTTAAAAATAATGTTACGGAAATTCTTGTCGGGTTT +TTAACAAGCCAAGAGATATGCTGTGAAAGCAGCATTAATTCAAGTGGTTGTCACAGGTCA +CTTAAAGTTAATCAGATAGTTGTCCTACAAATATAGGGTGAATGTTATTCATGAATTTCC +TGAATCTATTGCAATAATCACATTTTTTTCCATTAAACTCTTGAGGTAGCTAATTTTATT +TATTGCATTTTCAATGTTAATCTACTATTTCATATGTTGAGATTAACTCACATTAGTCAG +AATTTAAAGTATTTTAAAATATCACAGAATTTAATTTACCTTATCTGGTTTTGGTTTCAA +GACTATAGTAGCCATTTCATTTAATTGTACATGTAGGGTATTCTAATTTATGGAAAACTA +TTACATTTTCCTTGATTTTTTTTTTTTTAGAAATTACTTCTAGGGATCTATATGGTAGAG +TCCATGGAGAATTGTTTTAATTCTTCATTCATGTCTTCAGTGGGTATAGGATTGGTCATA +TTGGTCATAGTTTTCTGCTCGGATTTCAATAAGAAACTTGTGGAAGAACCTGAAGGGTGG +GATCTTTGAGGGAGCCTAAGACAGAGCAAGACAAGCTAAGAAGGAGGGCAGTGCCACAGC +AGAACTGCCATTGATGCCCCCTCGCCTAGATTGCGGAAGAGACATCCAGCTGTAGACACT +GAGGTGCAGGAAAACAATGGAGCACCATCAGAGAAAGCAGTGCCCAGGAACAAGGAGGCA +CTGATGGTGGCAAGGGGCAAAGACAGCTGCCACGAGGCTGTTCACATGAGGGTCTCAGGC +TGCATAGACACCCACACCAGCTGAGGGGTCCTGGTTTTCATAAAGTGTGTGGCTCAGCCA +GGCCACCAACAAGCAGTTCACAAACAGTAGTAATACGACACTTTCCAAAGACCTTACTTG +AGTAACACGGTGATCCTCACAAATTTCCAATCAGGATGGTCGCACAGTTCCTCCTGCTTT +AGGACTCAGAGCCTGCCCGTGGTCACAGTGGGTAGGTGCAGACTCTGAAGATGCACTTTG +GTCAGAGACCCTGCTGAACTCTGTCTAATGAGGACCTCTGTCCTGTCTGCTGACCACCGG +TCAGAGGTGCAGGCTGCAGTGGGGAGTAAGAATGCCACCTTCTCAATGTTGGGAAAACTC +CCTGCCAGAACTGAGAATGGCCCTTTCTAAGCAGAAGGCAAGCTCAGACTAAAGAAGGAG +GCCGAACACATCAGGTTGGCAGATTGCCAAAGATTCACTCAGGGAGAGCCCACATCCTGG +GCCATCTTGGGTGGTGGCAAGATGAGGTAGACGACTGCTTTTGCAACACACACCTGACAA +CAAAAAATCAACAACTGTAAAAGAGCCACAAAATCCCCAAATATTTGCAAATTAGCAATG +CACTTTTAAATAACTGTTGGGTTAAAGAAGAAGTCTCAATAGAAAATTAAAAGTACTTTT +AACTACATTAAAAGAAAATGTGACTTGGCAAGATTTCTGGATGTAGCAAAAGCAGTCCTT +AGAGGGAAATCTATAGCATTGGATGCAATATACTAAAAATCACAAGACCTAAAATCAGTA +ATATCATGTTTCAATTAGGGAACTATAGAAAATAGAGGAATGCAATGGAAAGCAAGTAAA +AGTAATAAACAACATCACAGAAATCAATAAAATTAAAACACTGAAATCATCAGAAAATCA +ATAAAACCAAAAGCTGGTTCTTTGATATGCTCATTACAATGAATGAATTGATATGCAGGC +TAACCAAGAAAAAGAAGATAACACAAATGACCAATTTCAGAAATAAAAGAGGAGCCATCT +CTACTGAACTGTTAGGCATTAAAAGGAATATCATGAACAGTTCTATGAGCGCAGTTTGAT +AACCTCAGTGAAATGTATCAATTCCTTGAAAGGCAATCTTCCCAAGGTCATGCTAGGATC +CTAATTTGAATAAACTTATGTCTATTAAATAAGTTGAATTCACATTAAGAGCATTCCGAA +AAAGAAAGCACCAGGCCCAGATGGTTTCTCTCATGAAATCTACCGAATTCTTCAACAGGT +GAATAAAAAGACAAAAATTCATTTAATGCAATATTATTTGGTGATTTAATGTGCCATTTT +TTGCCATTAAGGCATAAAAAAGACATGAAAGCAGCTAAAGCGTACATCAATTTAGTGCAA +TAAATTCATCTGAAAAAACTACATAATATATGATTCCAACTATATGACATTCTGGAAAAG +GCAAAGCTGAAGCGATAGTAAAAATATTAATAGTTGCCAAGGTTTCTGGAGAAAGAGGAC +AGAGATTAATGAGAAGAGAGGATTTTTAGGGAAGTGAACATTTTCTTTATGAGACCATAA +GGGTGAACATAATGTTTTAAATATTTCAAAATTCATATATATGTATAACAGAAAGAATGA +ACATTATGCAAATGCAGACTTCAGATAATAATGTGTCAATATTTTCTCATTATTCTAGCA +AATGTACCACAGTAATGTAAGATGTTACTAATAGGTGAAATTAGGAAGTGAGGGTGAGGA +GACAGAATAATATGGGAACTTCGTGTATTATATACTCAATTTTTATTTATTTATTTATTT +ATTTATTTATTTATTTATTTTGAGATGGAGTTTCACTCTTGTCACCCAGGCTGGAGTGCA +ATGGCATGATCTTGGCTCACTGCAACCTCTGCCTCCCGGGTTCAAGCGATTCTCCTGCCT +CAGCCTTCTGAGTAGCTGGGATTACAGGCGCCTGCCACCACACCCGGCTAATTTTTTTGG +ATTTTTAGTAGAGATGGGGTTTCACCATGTTGGCCAGGCTGGTCTCCAACTCCTGACCTC +AGATGATCCGCCTGCCTTGGCCTCCTAAAGTGCTGGGATTATAAGTGTGAGCCACCACAC +ACGGCCATATGCTCAGTTTTTATGTCAATTTAAAACTCTCTAAAGAAATATATTAATTGA +AAAATAATAATATAGCACCACTCTTTCAGGGAGATCTATGCTTATGTTTAACAACCAGGT +AAGTTCTAGACATTAGCTTGAAGCATTGTCTATCATTAAACATGAACCAAAATTGACTTT +TAAGTAGATATTTACTTTTGTGGTGGTAGCAATATTTACTGACCAGGCAAATTAGAATCC +TGACACATTAAAAAATATGGCTTAGTCTCTTCATAGTTTCCTCTTACATATGGGACACTG +AATACTCCCCGCAACTGCAATTCTTGAATCAACTTAATTAATGAACTTCCACAGTACCTT +CTTGTGGGTACCTCTTCTTCTTTACCCGGGAGCCATGAGGTCTCCTACACTGGTTGGTGT +GCACAGCATATCTTCTTGTATTCTCTATCAGAGAAGATGCTGGTTAATGCATTGACAATA +GATAGGGCTGTTGACATCTTGCTGACAGAAGACCAGAGGGAAAATAGTGATAATCTGTTC +TAAGTTTAAACTTATGATCCTTTTTTTACAGGCTTCCAAGCAGAGCCCACTGAATCAAAG +TTGGGTTTCAGGAAGATCACGGAGTTCAGTGAGCACTCAACACCTCTATCAGACAGACTG +CGTGGGCAGTGCCTTCCTGGAGAGGGGAACACAGCCGGATGACTGTGAGTGCAGGGCTGG +TGCAGAGTGGGGGCCCGGATTCAAATTCCACTAAGCCATGTGGACCTGGCAAGCTCATGT +CCTCCCTCTGCCCTCAGTTCTCTGCACTGTCATAATGTAATTTTAGCAATACTTTTTAGG +CCCTATTTAAGCCCTACTTCTTAGTATCACAGTACAGGGCTAAAAAATCACTAAATACAG +GAAAACCTTAGAGAGGACTGGTACTTCAGTAATGTTCTCTAAGTGTTTACTACATGCCAG +GAGGAATAAGCTGGACACTTAGCAGTGGCGGAATATGGAGGGGGAACTTGGATGGCTCCG +GGGCAGTGGAGCATGCTTTCCTGTTCGGCTTTTCCGTGGGCATGACGCCTTATGGTTTAT +GGAGAACATCAGCCCTGCAGGGGGTGCAGAGGAGGGGCTGTGGCTGAGATTTTACACTTG +AGGGTGCTGACATTCAGAGATGATAAGTGACGAGCAGAACCTCAACCCCGCTGAGTGAAG +GACCTGAGATGGGAAATGTATTTGGTTCCCTAGAGAGAGAGATTCCTGAAAAACTGCCAC +CTCTTCATCACGCCCTGTGCCACAGACCCAAGAGACCCCTCACTGTCTTTCTCCAGTCCT +CCTAGCCCAAGGTGTGTGGGTGGACAAAGGTGGTGCTCTGGAGGAAATGCCTGAGATAAG +GACAGGTCCTTAATGATAAAGAATTCTCCTTCCTCTTTCAGATCCTTGACCTCCCAGTAT +GACAGCTTAAAGGCTGTCATCTCTGTGGCCTGCCTCCCCTTGCCCTTCACCCTGCCAGCT +GCCTCTCAGTGACTGTCTCCTCCAGTGACTACACTGAGGGACCAGGGACTGCTTGCCTCC +CGAGGCTGCTCACACCTTCTGACACCGCAAAATGATTGTCAAAAATGGGTCTGCAAAGAG +TAACTTCCCTTCCACTGATCAAACCTGAATATGCAAGCTACTGTCAATTAACTGGAAAAG +TGGCCGTGTGGGCTGGTGCTTTGGTGATTTAATGAATTAAGTCTGCAAGCCCCACTGCCT +CCTTGACTATTGATCAGAGCTGCCTGCAATAAGGTCTGGCTAAGAATGGGCAGTGGCTGC +ACCAGCTCTGGGTAAAATTTGACCTAAAATGACCAATCTCATTCACTAACCTCACCATAG +TCTTATGGGTTCAATGGACCTGTCCAATCCTTTGCTCTGTTCTCTCCATCACCTTCCTGT +GTAATTTTCCTCCACCACGCACATAATAGAAACATGGCACAGGGGAGCTAATCGCCTCTT +TTATCCCCCACTTCAGGCTCACACATAAGTTTATAGTAAAAGCCTTTTCAAATGACTGCT +TTAACTGCTGCTACAGCATGTGTCATCAGTTGAATGGAATCTGTCACGTGACTTTAAGCA +ACCCTTTGCTGAGAGACAAGATTCAATACTAGGGACAGTATTCTAGTGTACTACATCATT +GATTTTATGTTATGAAGATCATCATTTATTGAAAATGTATAAATAATGAAGCCCAGCCTT +ACTCTTCAACGCTGTGTGTGTAAATCCACTGAGTGTGCTGACCCCCACGCTTGTACCCAC +CTGCTAACACAGAAAGGGTCCACTCAGAAGGGAGGCACAGCTCCAGCACTGAGGCTGTCC +ACACCAGCTTCACAAGAGGGTTGCCACAAGGACGACGGATACCCGGATAACAACCAAATG +GTAATTTGAGTACTTAATGGTCATGATCCCTAAAGTGTGTAGCTCAGAGGGCTTGTGGTG +ATAACTCCATCAAGACTCTAAAGCATCTCCCCAATTCTTACTGGACTTGATCCATGTCTT +GAGGAGACCCAGCTATGACACGCAGGCACCACGTTGTCCTACTTAGTGCCTCCCTTAGTG +TTTCAGAACCTGTGATTTGATCAGAAACATGGGCTTTCTATGTTGGTTTCACACTAAGGA +CTATGTGACACCTGCAGGAAGATGTCTACATAGCTACCTGGATTATGAGATCATGAGGCT +GTCTTATGTGAGGGATGGCGTTTGGGATCTCTGCAGGCGTGGGTAATTCCAGGCATAGAG +GGTGCTGGAACTCCCTTGCATGGTGAATAGTGATCTCTTCACTGGCTGATAAATAGAGGT +TGTAGTTCAGGCCTTCAACATTAGCACCGTATGAGGAAACATTTTGACTCTTCACTATGC +AGCAAGTGAACCAGAGCACATTTATTTATGTGGCTTAGTTTCTCCATCTGGCATGTGGGC +TCAATAAACAAGCTCACAACATATGGGCATGATGATGATGAGGTGTGAACTAATGTAAGT +AAAGTATGTGGTCTGATTTGTTAAATTAAGAAAAATGGCACTGAGAGTTGTGCTGGGTAA +ACACAACATTTTTTTCCTGGGGGAAACACAGATAGACACACATTCACAAGCAAATCATGC +AGACTTGCACACAGACCACCTCACCCCACCCCCGCCCTAATACACACATACCCACACACA +ACCTAATGTGAACATGTTCCCAGAAACTATACATAGATAAAAAGAGTATGTCACCAGGAA +AACCAGTTTCTTTTACTATACCCTACATCCTCATTCCCACCAGATGTCTTGGATCATGGA +GGCTCTCCGGACAAAAGCCAGCAGTTAAGCTCCAGATTTCCTGTAGAATCCTTTTCTAAC +AACCAGTGAGTGATTCCAGAATACGTACCATTGAATGTGCTCCCTGAAGTCACCTGTAAT +TAGAGAAGGAAAACACTCTGAGAATCAGGCTATGCTATGGATGGCTCACACAGGTCTTTT +GTTCACTTGGAAACTCTGGGTAACCAAGATTGGAAATAAGGTTCAAGTCAAAAGCCCCAA +CTCTAGAGTAGAGTTCCCTTAGGAAAGCACAGGAGCTTTTCTTGAAGAATGTTTCTGTCT +AGGTAATTTTTGAGTAGCAATTGCAGAATTCTTATCTAAAGTGGAAAGCTTGTTCCTGAA +GAAAACATCCCTTAACACCCAGTGTACTATCTGACACTGCCAATTTTGCACGTCCTCTGG +AATCAGGTGTCAGTTGGTAAAATACACCTCCTCCATCCCCAAGGAAATATTATCTAACAC +CTATAATGTAGTGGAGAATTTTCCCATAGCTGATATCAACTGAAAAATAAAGGATCCAAG +AAAACAACATTTACATCTTAGGCAAAGACAGGCTACTTTACCTTGGTAGTAGAGTAGGGC +TTCCTTTTCACACGCTTTTTGGAAGGCTTCTTCGAGTCACCTAGGGGATGTGGAGGGACA +CAGCATGGCTGTCAGTTCATTGGCAGTGCTACTCATGAATGACTCAGGGACTGGAACTTA +GGGGCGTGCCTGGTTAACAAGCATGGAATGAGCTTCTCCTGGACCATCTTCTTCACGGAC +CAAGGAAGGCAAAGAAAGAGCAGCAAGGAAATGAGAGTAGAGCCCTTGGCTTTCCAGGTA +ATGGCAAATGAAAGCAACGTGAAATAATCAACTCCAAATGAACAAATGCTAAAACACATG +CTACGATTCAACCACAGCATCCTGTCACTTCTTCAGACCCTTTAAAAGCCCAGCAGGACT +GCCACTACCTTCTTGACATCGACCAAGTCCCTTTCAACCTCCACAGACCCACATACACTG +CTACTGCATTTATCATGGAGGGTATAGGGTTCTGCCCTGTTTATGTGTGAATTTTTTAAA +AACTAGATTTAATACCATGCACCAGCATTAATTGTATTTATTTCTTTTCTTGGTTATGAA +AATAATCAGTCAGGCATAGTGGCTCACACCTGTAATCCCAGCAGTTTGGAAGGTGGAGGT +GGGTGGATCATTTGAGGTCAGGAGTTCGAGACCAGCCTGACCAACATGGTAAAACCCCAT +CATTGAAGATAAATGTTTTATATCCATGGTTAACAGATGAGATGACCATGAAATGAACAC +CAGTGTACTGGGTGGAGCAGCTTATCTATTCAGTCTTCGGCACTAAAACCTGTGAAACAA +TATCATCTTGCCTTATTTACTAACAAATACAAGTGCCTCTAAACTTAGACAGTTTCCAAG +TCATGGAACTGATGAGCACTTAGCTCCTGCAGAGAGCTCTGGATGATGGGTCGGGAGAAC +AAAGACACAATACATCAAAACAGCATTCACAAGTAAACAGGTTTTCAAAGCCCTCTACAT +GCAAATTTACACAATTATCCTTTTAATTTTTATCTTCATATATATGTACATAATCTACTT +GCTTCTGAGTATAAATCAAACTGTATGTTCTTAGTTAATAGTCTCTATAAATTCACTCTA +TTTATCTTTCTGAGTTGAAATACTGCATCTCATTGGATAACAAAAAAAAAAATTTGACTA +AGATTACACTGGAAAGGTGAGTAGGTTGGGTGATTGACTGTGATTGACAATTCCATGATT +CTGGATAACTTCCAAAGCATAAAAATAAATGTGTGTTTTCTTTCACACGTAGACAATACA +CATGCTTATTACTTTAAAAAATTAATATGTGCATGGAAGTGACTTACTACAAATATATTA +AAGTAAATACACATTTCACAAAAAAAGAAGAGAGGAAGGGAAAAACATGTTAAAAACAAA +GAGAGTTACATTTTATTGTGTGAAAAGCCTCCAACGGATCCTTACTACTGTGGCTTTGTT +CCAAAGTTTTGGAAAGTAATGATTTCATAGGTTCTTAATTGGGTTAAAAACAGCATTAAA +ATAGACTCTGCCATATTCTCCCCTGGGGAATAACTTAATCTGTGGGGTGGGGAATGGAAC +GTTGAAGGATGCAGGATGTAAAAGGAAATTATATATATATTATATATATTATATATTATA +TGATATATATAATATATATATTATTTATTATATATATTATATGTTATATATAATATATAT +AAATAATATATAATGTACATAATATATAATTATATAATATATATTATATATTATATATTA +TATACATAATATATAATTATATAATGTATAATATATATTATATATAATATAATATATATT +ATCTATAATATATATAATATATTATATATATTATATATTATATTTAATATATTATATATA +TTATATATATAATATATTATATATAATATATATAATATATTATATATAATATATTAAATA +CATTATATATATATTTTATATATATATATATTTTTTATATATATATATATAATATATATA +TATAATTTGGGAATTTGGGAATAAACTGAATCCCAATTCACACTGGGACTACACCAGCTG +CCACCATGCCTGGCTAATTTTTTGTATTTGTAGTAGAGACAGGGTTTCACTGTATTGGCC +AGGATGGTCTTGATCTCCTCACCTTGTGATCCTCTTGCCTTGGCCTCCCAAAGTGCTGGG +ATTATAGGCCTGAGTCAAGATACATATTTTTTAAATGAAGAAAAATTTGAAAGATACTCT +GCTTGGTACAATAATCAAATATATAAATTGAGGAATAAAACATAATCATGAAACATATTT +ATAACTGCATATGGAAAATACAGAGGCTAATTTTTTAAATAACATATTTTGAAAGCATTA +ACTAGTAATTTGAAAAGATCGCATTTGACAGGCCAGTATGAACATACCTTGAATGCAGCC +ACACAGGTTCCCCATAAGAAAAATCAAAATCAGGGAAAATGAAACCACAATGGTTCAATC +TGCTCTGACCTTTGAAAAACTCAGCACAGGTAGTGGCACTTACGACCAAGGGCAGGAGAT +CCCTAATCCCATCACCATGGCGATAGGGCATAAACATTCCAGGGTGAAGGCACAATCCAC +ACTGTGAGGTCCAACTGCTGCCATGCAGACAGGTGGGCTTTTACAAGTACAGGAAGGTCA +TCAAAGGCTCAGTGTTTTGTTTCAAAAACTGAATCCCAAGCCCACACATTATTATGCTGG +CTTCTTAAAATAAGTTGTGAGATGGGAAGTAGGGCACCCACAAATATATATATATATAAT +TATATATAATATAATATATAGTATATATATAATATATTTAATATATTATATATATATATA +ATTTGGGAATTTGGGAATAAACTGAATCCCAATTCACACTGGGACTACACCAGCTGCCAC +CATGCCTGGCTAATTGTTTGTATTTGTAGTAGAGACAGGGTTTCACTGTATTGGCCAGGA +TGGTCTTGATCTCCTCTCCTTGTGATCCTCTTGCCTTGGCCTCCCAAAGTGCTGGGATTA +CAGGCCTGAGTCAAGATACATATTTTTTAAATGAAGAAAAATTTCAAAGTTACTCTGCTT +GGTACAATAATCAAATATATAAATTGAGGAATAAAACATAATCATGAAACATATTTATAA +CTGCATATGGAAAATACAGAGGCTAATTTTTTAAATAACATATTTTGAAAGCATTAACTA +GTAATTTGAAAAGATCGCATTTGACAGGCCAGTATGAACATACCTTGAATGCAGCCACAC +AGGTTCCCCATAAGAAAAATCAGAATCAGGGAAAATGAAACCACAATGGTTCAATCTGCT +CTGACCTTTGAAAAACTCAGCACAGATACTGGCACTTAGGAGCAAGGGCAGGAGATCCCT +AATCCCATCACCATGGCGATAGGGCATAAACATTCCAGGGTGAAGGCACAATCCACACTG +TGAGGTCCAACTGCTGCCGTGCAGACAGGAGGGCTTTTACAAGTACAGGAAGGTCATCAA +AGGCTCAGTGTTTTCTTTCAAAAACTGAATCCCAAGCCCACACATTATTATGCTGGCTTC +TTAAAATAAGTTATGAGATGGGAAATAGGGCACCCACAAATATATATATATATAATTATA +TACAATATAATATATATAATATATATAACATATATATAATTTCCTTTTACATCCTGCATC +CTTATATTATATATAATATTATGTATAATATAATATGTATTATTATATATAATATAATAT +ATATGAATATATATAATTATATAATATAATATGTAATTCTATATAATTCTATATAATATA +ATATATATTATATATAAATATATATAATATACTATATTATATATAAGTATACATAATATA +TTATATATACGTATACATAATATAGTATATTATATAAACATATATATAATATATTATATA +TACGTATATATAATATATTATATATACGTATATATAATATATTATATTATATATACGTAT +ATATAATATTATATATACGTATATATAATATATTATATTATATATACGTATATATAATAT +TATATATATATTATATATAAGTATATATAATAATGTAATATATTATATATAAGTGTATAT +AATGTAATATATAATATAATATAATAATATATTATAATATATTATATATTATAACATAAT +ATAATATAATATACATTATAATATAATATATAATATTATATATAATATAATATATAATAT +AAAATAATATAATATATAATATAATATATAAAATAATAATTAATATTTTAAATTAATTAT +TATTAATTAATATTAATTAATATTAAAAATAATATAAAATATAATTACTATAATATAATC +TATAATTATTATATATAATATAATATACAATTATATATAATATTATATATAATAAAATAT +ATATAATTATGTGTATTTATTACATATAATATAATACATAAATTATATATAATTATTACA +TATAATATAATATATAATTATATATAATTATTACATATAATATAATATATAATTAGATAT +AATTATTACATATGATATAATATATAATTATATATAATTATTACATATGATATAATATAT +ATAATTATATATAATTATATAATTATATATACAAGATAATAATATATAATATATAATATA +TATTACATAATATTTTATATAATATATTATACTATATATATTATATAATATTTTATATAA +AATATTATATATTATATATAATATAATATTTTATATAAAATATTATATATTATATATAAT +ATAATATTTTATACAATATAATATATAATATATATTATATTATCATATGTTATACAATAA +TATGTTATAGTATAATATATATTATAATCTAATATATTATATATTATTATATATTATATT +ATATATAACATTATATAGTATTATATATTTTATAATAATAATATAATATATAATATTATA +TATTATATATAATATATAATATATTATGACATATTATATATAATATATAATATATTATGA +ATATATTATATATAATATATAATATATTGTGATATATATTATATATTATATAATATATTA +TGATATATATTATATATAATATAATATAATTATATGTAATATAATATTATATATCTTATA +TATCACATATTATATATTTTATATCATATACTATATATTATATCATACATTACATATAAT +GTATGTCACATATTATATGTAATATATGTCACATATATGTAATATATGTCATATATTATA +TATAATATATATCATATATTATATATGTCATTTATTCTGTAATATGTATCATACATATTA +CATAATATGTATTATGGTGTCTGGTGGTCCCAGGACACAGACTGATGTCACTCAGCCTCA +CATGACACTCTGTCCTCACCACACTTGGGGTCCTGGGAGTCGTAGCACCAGGCACCTATA +GAGACAGTGGGCAGGAGGCTGAGCTGAGAGACCAGTCATCTGGGTCCTCTCCAAGCCCCA +TCCCATCAACTGGGGTCCAAGAATGAAGTAGGCCAGGGGCTTAGGCCAGGGGAGGCCAGT +GAAGAACCTTCTCTCATGTCACCCCTACCCCAGTATTTTCTCTCCCCAGTCCCTCCCCAC +TCCCAGTGGCAAGACCTAAGGGGTGGTGGAGCATGGCAAGAGGGTAGATTGGAGACCAGA +CGGGAAGAGTCCTGGTGCTCACTCTCAGAGTCTGCACCACACCAGCTGCACCGCAAGGCG +AGCATGATGCCAGGGGCGTGCGTGGCTCAGTGGCAGCCGCAGCTAGGAAGGACTAGAAAG +TGGCTAGACCGCGGAGCCAAGATGCTGGCCTGGCTACTACATATTTATTCATTAGCTAGC +TGGGCTAGGGGCGTGGCTATTGAGGAGAGGATGGGAGGGGTCGGTGCCCAGGCAGGGCCA +CCAGGAAGAGCGGGAGCGCTCCAAACTCACCCAGGTGTGCTCTGGTCCCAGGGCTGCACT +GATGCCAGCAACAATCGCTGAGGTTAATCCTGCAGGGGAGGGGTGACCTATTATTATCCC +CACTTACAGTCCAGGAAACAGAGGCTGGGGACCAGAATGACACACCAAAGCCACCAGCAA +GAAAGGTCAAATAGTGAGGGCACCTTGAACCCCAGCGCCCATGACTTTCGGGGCAAGGAT +GGGAGGAAGGTGTAGGATGTCTCTTGCCCCGCTGTGGGCCTGGAACTGCCACCCCATCCC +AAGACCATAGCCTCCCTCCTGCCCAGGCCCCCCTGCGGATCCAGGCCAAGACGGAGCCCT +GCAGGAGGTCAGAGGAGGGGACTTCTTTGCACCCTGCGCCTCTTTCCAATCGCCAGAGGG +CAGGGCCCTACCCACATTGGGGATGGGAAGTCAAATGCAGAAGTTAGGTGAAGTCAGTTC +TTGGATACTCCTGTACTGTCACCCTGGTCTTATCTCATGCCTTAGCCCAAGCTGTGCACA +CAATGGGGTCCTAGGTCCCCCTCACCTCCCAGATTCCACCTTCCCAGGGATGGGACCCCC +TGGAACCCTCGGGGGCCTGGGCAGTGGCCTTGCTGGCTCTTGCCTTCCTAGGAGCTGAGC +AGGAGCTCCACTCTCAGCAGGGCAGTTCACTGCAGCCTCTGCTTCCTCAGCTCAAGCCAT +CCTCCCACCTCAGCCTCCTGAGTAGCTGGGAATGCAGACACACACCACCACGCCTGGCAA +ATTTTTGTATTTTTAGTAGAAACAGGGTTTCACCATGTTGCCCAGGCTGGTCTCGAATGC +CTGAGCTCAAGCGATCTACCCACCTCGGGCTCCCAAAGTGTGGGAGCCAAGATGGGAACC +CAAGCATACGGCCCCAATGCTGAGGCTCTGAACTACTGACCTGCCCTCAGCACTCAGCCT +TGGGATCATGAGTCACTGTGCAAGGGAGTTCCAACATCTGCATGTATGTCTGGAATGATC +TGAGCCTGCAGAGTTCCTACACACTGGCCACATTATAGGGTGGTGTCCGTGGTCACACAG +CTCAGGGCAGGTATTTATTAGTACATGAATAGCTTAGCTGTGTCATAGTCTTTATGTGAA +AGGCACAAAAAAAGGCACTTTGGCAGGCTGAAAGTGTGGGGATTATAGGTGTCAGCCACC +GTGCCTAGCCCACTGGATGACTTATGATATCATATGTGACATTGTGACATCATGTGAGTC +AGGGATGTACCCCGTTCTCAGCTGCTATATGCTATGTTACACTGACAGAATGGGAATGAA +GAATGTGTCCCACTCTCTCAGCTGTTGTATTATATCATACAAGGTGCAGTGACTAAGTGT +GTCAGCTGTGTCCTCATCCTACATAGCATATGAGAGTGTGTGACGGGAGATAGGATGCAG +ACCTGAGAAGCATTAAACACCTAGGCAATAAAGGTGCCAGCATCAGCTGAGAGCGCAGGT +AGACCTCAGTCACATTTGTTACTGTGTAACTAAAAATACAAAATTAGCTGGGTGAGGTGG +TGCACGCCTGTGGTCCCCACTGCTCAGGCACCTGAGGCAGGAGAATTGCTTGAACCCAGG +AGGCAGAGGTTGCAGTGAGCTGAGATTGCACCACTGCACTCCAGCCTTGGGGACAGAGTG +AGACTGTATCTCAAAAAAATAAAATAAAATAATCTAGGACAACCAAGAGAAGGACTCAGG +CTCACCTTACTCCATGTCACATGTGATATATAACACTTGAGGGGGACACACACTTGTCAC +TTTGTATCACTATGTCCTATATGATAGCCAATGATAACCCAAGAGGGGGAGGCAGCCTTG +TTCACACCATGTCACTTATGATATTATATGACATCAAGGAGCCCAGACCTCAGTTGCATT +ATGTCACTATGGCACATACAGTATCATGCAACAACTGACAGAAGGGTTGCAGGCCTGATT +CACAGTGTATGTGAGTCACAAATGTCACTTATGACACCATACAGCAGGTGAGAGGGGATA +GTCATTACTCACCTCGGGTCACATTGTCACACATGATACCATATGATAGCAGAGGGGGAT +GCAGAACTGAGTTGTATTATGTCGCTATGTAACCTGTGATAGATGATAGCTGATGCGGGT +GAAGACCAAAGTTACATTTTGTACCTACATTATATGAAATATACAACATGCACGAGGGAG +ATGCAGACACAAATCACACTGTGTGCTGTATCCCATATATGTGTTTAATTTCTGTGTTTA +AGAGAGCTGGGTTCATGAATGAACTTAGTCACTGCACCTTGTATGATATAATACAACAGC +TGAGAGAGTGGGACACATTCCTCATTCCCATTCTGTCAGTGATTGACCACACCTTGTGTT +AACTGTATGAGCCACTGTGTTTGGCCGTGTATAGCGCACGTGGCACATTGCTCACTGATA +CATATTTGCTCCGTACTGAAGTGAGGCAGATGCATGAGTGATTGAGAATAATGCTGCCTT +GGTGAAGCATTCCATTTAGAAGCATGAGGTTCAGGTACTACCATCTTCTGTGATACATAT +TTAAATGTTAAGTTTAACAGTTAGGTCTACCATGAGTGAATGAGCCTTGCATTATCTTTG +AGAATCGATGTGTTTAGCAGGGTGTGGCTCATCTAAGATAGCCTTCTTTAATGCATGTTC +ACTATCTGTGTTTATTAGAAATAGGTTTGTGAATGACTTAGCATAGTGTTTTCCCTATGA +AACCCTGTTTATTTATTTATTTATTTATTTTGAGATGGAGTTTTGCTCTTGCAACCCAGG +CTGGAGTGCAATGGTGTGGTCTCGGATCACTGCAACCTCTGCCTCCCAGGTTCAAGCGAT +TCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACGGGCGTCTGCCACCACACCCAGCTA +ATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTCGAGCTC +CTGACCTCAGGTGATCCTCCTGCCTCAGCCTCCCAAAGTGCTGGAATTACAGGCGTGAGC +CACCACACCCGGCCAAAACCCTGTTTTAAGAAGTGTGTGGTGCAGGTACTACATTCTTTG +TTGTTCCAAGTTCAAACCCTGTGTTTAACAGAGATAGGTGCAAGATTGCCTAGGTGTAGC +GTAGACTCTTGGAAATACTGTGGTTAGCATTCTGTGTTTTCTGTAGTATAGTTTCAGTGA +TGCCTGTTTAGATAGTTTATCAGATCTAGGTACTAGTGTTATGTCAGCGAAACACTGTTT +AGCTGCACGCGGTGCATGTAATACTTTGTTCATTGATATTTGTTTAAATCAATCAGTGTT +TACCAGAACTAGATATGTGAGTTACTGAGAATAGCCTAATCTCTGAAAATGTTTTCCAGC +CTATGGTGCATGTAATATACTCTTCTATGGTACCTCTTTCCGATGTTTTTATTGTGGCAA +AATATACATAACAGATTATACCATTTTTAAGTGTAGAATTTAGTGGTAGTAAGTATAGAG +AGAACCTTAAAAGCAGCAAGAGAAAAGTGACTTCTCATGTGCAAGGGAGCCTCTAGAAGA +TTATCAGTGGATATTTCAGCAGAAACCCTGCAGGCCAGAAGGTGGTGGGATGATACATTG +AAAGTACTGAAAGAGTAAAGCCTGCCAACTGAGAATACTATATTTGACAAAACTGTCCTT +CAAAAGTGAAGGAGAAATTAAGACATTCCCAGATAAATAAAAGCTGAAGGAGTTTATTAC +CACTAGACCTGACCAATAAGAAATAATAAAGGGGCCGGGCACAGTGGCTCATGTCTGTAA +TCCCAGCACTTTCGGGAGCCGAGGCAGGTGGATCACCTGAGGTCAGGTGTTCAAGACCAG +CTTGACCAACATGGCGAAACCCCATCTCTAATAAAAATACAAAAATTAGCTGGGTGTGGT +GGCACGCACCTGTAATCCTAGCTACTCAGGAGGCTGAGGCAGGAGAATCACTTGTACCCG +GGAGGTAGAGGTTGCAGTGAGCTGAGATCACACCACTGCACTCCAGTCTGGGCAACGGAG +CGAGACTTCATCTCAAAAAAAAAAAAAAGAAACAATAAAGGGAGTCCTTCAAGTTGATAT +GAAGGGATACTAGACAGTTGCTCAGCCTGATGAAAATATAAAGGTAAATACATAAAGATT +AAAACCTGTATTATTGTAATTTTTGCTAATAACTCAATTTTTAATACTTTAATGGAATTT +AAAGGACAAAAGCATAATAATTATAAATCTATGTTAATGGATACAAAGTATATAAAGTTT +AATTTGTGACATCAGTAACTTAATAGTGGGGCAAAGATGTAAAGAGTAGAGGTTTTGTAT +GTGATTGAAGTTATCTGTTTAAAATAATAAGATAACTTTAAGATGTTCCATGTAATTCCC +ATAGTAACCACAAAGAAAATACCTACAGAATATATGCAAAAGGAAATGAGAAGGAAATCA +GAGCATAGCACTACAAAAAATCAACTATAACACAAAGGAAGACAATAAGGGAGGAAAGAA +GGACAAAAAGGCTCTAAACATACAGAAAACAATGACCAAAATGGTGGTAGTAAGTCCTTC +CTAATCAATAATTTCATTAAATGTGCATAGGTTAAACTCCCAATAAAAAGACATAAATTG +GCTGATTGGATTTAAAAAAACGGGATTCAACTATATATGCTGTCTACAAGAGACTCATTT +GAAATCCAATACAAATGGGTTGAAAAATGAGAGAATGGAGAATATTCCGTGCAAAAAGTA +ACCAAAACAGATCAGGAATGGCTGTACAAGTTATGGCTGTACAAGTTGTTGGGGTTTATG +TTACTGAAGAATGAACAGAGATGAGTAAGTGGAGGTGTTATGTAAAGGCATACTGTACTC +AAAATCTGAAGACCTGCAGCAGATTTAAATTCCAGCTCTTATTATAACTTTTTAAAAGAT +TGTGAAAATATCAAAATATAGATGAATCAAGTTTTAATATACTGTATGATGGGTGGATGA +GGCTGTCCATTGTACCATTTGTTTGAATTCTCAGGCATGGTTTGGCAGTGCAAGAACTCT +GTAACGTTAACAAATTCAATAAAAAGTAAATATATGGAAAAAAAAGTATAGACAAAATAG +ATTTTAAGTAAAAAACTATTACAAGAGAGGGTTCTGGGAAGAAAGTGGAGTAGGAAGCAC +TGGGAATTCATCTCCCCACCTAGAAAATAATCACACTGGCAGAATCTGCCTGATATAACT +ATTTTGGAACTCTAGACTCTATCAAAGGAGGCTTGTAACCTCCAAATGAAGGCTTAAACT +ATAATTTTTACTTAATTTTGGTCAATTTCAGCTCTTAGCTCAGCAGTGGCTACCCAATCC +CCATGCCCCAGCTTCACGGCAAGAAGCTTTGCATGTGTTCCTGAAGCAGCTTGTACCAAG +CTTGTGGGAACAATCATGGGCAATAAGCACTCTGTCCTCCAAGTGTTAGCATCTGCGTTC +TGGTTGTTGATTGCTACTTTTGATTATGGAAGGGCAAACACAGAGGCCGGCAGCCATTAT +TGCTCACAACTCCCCACTCCACTGCTGCAAGCCCTTACCAGACTGAAGCAACTTCTAGGA +GATAGAAAAGGCCAGAACCCCATTTCCCTTCCCCTTCATTGTTCTCTTTTCCTTTTTTGG +GAGCCAAACATTAAAGACTAGGACACTCAAAAGCAATGGCATACCCAGAGGAAATTAAAG +TTACCACACATCCTTGGAGAGAGGAGTGTGTGCCCAGGGAAAGGAGCAGCTTCAGACCTG +AGAAGACCTCAAGCTTACAACTCAGGTTGATCCTCAGCATGGAGACAACCTACAACAATG +TAAAACATAACAAAACCCTAAAACAGCAAACCCTGAGGAAGAGGAGAGTCTCATCTCCAG +AGTTACTGCATTATTATATTCAAGTGTCCAGTTTTCAATACAAAACACAAGGCATACAAA +AAACAAGAAAATATGGTATTTCAAAGGAAAAACAACAACAGAAACTGTTCCAGAGAAAGA +CCAGATGGTAACCTACTACACAAATACTTTAAAACAACTTTCTTAAAGATGGTCAAAGAA +CTGAAGGAAGATGTGGAGAAAGTCAGTAAAATTATGTGTAAACAAAATGGGAATATCAAT +AAAGAGATAGAAAACCTAAAAAGAAAAAAAATAAATAAATTCTGGAACTAAAAGTGTAGT +GATTGAAATAAAAGTTCACCAGAGGGATTCAAAAGCAGATTTGAGCAACAGAAGAAAGAT +TCAGTGAATTTGAAGATGGGACACTTGAAATGATCAAGTCAGAGGAACAGAAATAAAGAC +GATTGTTGAATAGCAAGCAGACATTGTGGAAGTCCCAAAAGAAGAGAGGGAAAGGGGCAG +AGAGATCATTTGAAGAAATAATGGCTGAGGCTGAACACGGTGACTCACACCTGTAATCCC +AGCACTTTGGGAGGCCAAGGTGGGTGGATCACAAGGTTAGGAGTTCGAGACCAGCCTGGC +CAATATGGTGAAACCCCGTCTCTACTAAAAACACAAAATTAGCCAGGTGTGGTGGTGCAT +GCCTGTAATCCCAGCTACTTGGGAGGATGAGGCAAGAGAATCGCTTGAACCCAGGAGGCA +GATGTTGCAGTGAGCCGAGATTGTGCCATTGCCCTCCAGCCTGGGCAACAAGAGTGAAAC +TCCGTTTAAAAAAAAAAAAATTAGCTGGGCGTGGTGGCACGTACCTGTAGTCCCAGCTAC +TCAGGAGGCTGAGGCAGAAGAATCGCTTGAATCCAGGAGGCAGAGGTTGCAGTGAGCCAA +GATCACACCACTGTACTCTAGCCTGGGCAACAGAGCGAGACTCTGTCTCAAAAAAGAAAA +AAAAAAAGCTGAACACTTCCCAAATTTGATGAAAGACATGAAAATAAATATCCAGAAAAC +TCAATGGACTCCAAGTAGGATGAAAAAAAAAAGACTCATACTGAGACATTATAATTAGCC +AGTAGGGCCTCTTGAAAGCACCAAGAGAGAAGCAACTAGTCACATGCTAGGAATATATAA +TAGGATTATAAGTAGATTTCTCATCAGACACTTTGGAGAACAGAAGACAATGGGATGACA +TATGTAAAGGGCTAAAAGAAAAACAACCACTACCTCTCAACCAAGAATCCTATATCCAGC +AAAACTGTCCTTCAAAAGTGAGGAAGAAATTGGGAAATCCCCAAATAAACCAAAGTTGAG +AAGTTTGCTACCATTAGACCTGCCCTGCAAGAAATCTTAAAGAGAATCATGCAGGTTGAA +AAGAAAGAACACTAGATAGTAACTCAAAGCCATATGAAGAAATAAAGATGCCAGTAAAAG +TAAATATATGGGAAAATATTAAATCTAGTATTATCGTAACTTTGGTTTAAAACTCCATGT +TTTGCTTTCTACATAATTTAATAGACAAATGCATTAAAAACAATTATTAGTTTATGTTTA +TGGACACACAATGTACAAAAATGTAATTTTGTGACATTGATAACTGAAAGAGGAGTGGCA +AAACTGTGAGGAGAATTTTTGCATATTATTGAAATATAGCTGGTATGAATTCAAGTTAGA +GTGCTATAACTTTAGAATGTTAAGTGTAATCCCTATGGTAACCACAAATAAAACATTATA +TAACATAAAAAAGTAAATGAGAAGGGAATTAAAACACTTCGCTACAAAAAATCAACTAAA +TACAAATGAGATCATGCAGGAAATGGACAAAAATGCTGTAAGGCATATAGAAAATGTATA +GCAAAATGCCAGAAGTAAGTCCCCCCTTATCAGTAATTACTTTATTACTTTTTAAACCAT +TTTGTTGAGGAATGATTTACATAAAAACTGTACATATTTAACGTACACATCTTGATAAAT +TTACACCATAAAACCATTATCATCAAGCCTATAAACATATCCATCACCTTTTAAAATTTC +CTTCTGCCTCTTTATTATTATTATTGTATAAAAAAAATGTTTTTAATGGCCAGGTGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCTGAGGCAGGCGGATCACCTGAGATCA +GGAGTTGGAGAGCAGCCTGGCTAAGATGGCAAAACCCCATCTCTACTATAAATACAAAAA +TTAGCTGGGCGTGGTGGCGGGTACCTATAATCTGAGCAAAGTACTGGGAGGCTGAGGTGG +GAGAATCTCTTGAACCTGGGAGGTGGAGGTTGCAGTGAGCCGAGACAGCACCATTGCACT +CCAGCCTTAGCAACAAGAGTGAAAATCTGTCTAAAAAAAAATAATAATAATAAAAGTTTT +TAATTAAACAATTTAAGAATATAGTAACATTTTCTGTGGGTACTATGCTGTATAGCTCTC +CAGAACTTACTTATCTTGCATAACTGAAATTTGTACACTTTAACCATCAACTTCCCATTT +CCTTCTCTTCCCCAGCTCCCAGCAACCACCATTCTGTTCTCTTCTTCTGAGTTTGACGTC +TTTAGGTTCCACACATAAGTGAGATTGTACAACATTTCACTTTCTGTGTCTGGCTTATTT +TACTTAACATAATGCCCTCCAGTCCATCTATGCATAGAAATGCAACTGATTTTTGGATGT +TGACTCTGTATCTTGCTACTTTATTGAATTTATTACTTCTAACAGTCTTTTAGTGAAGTC +TTTACAGTTTTCTATACATAAAAATATGTCATCTATGGAGACCATTTTACTTCCATTCTT +ATTTCTTTACTTGCTTAATTGTTCTGGCTAGGACTTCCAGTCCTATTTTGAGGAGAAATG +GTGAGAGTAGGAATTCTTGTCTTGTTCTTCATCTTCGAGGAAAAACGTTCAGTCTTTCAC +TGTTGAGTATGTTACATGTGGTCTTCATTATGTTGAGGTACATTCCTTCTGCACCTAATT +TGCTCAGTTTGTTGTTTTTTTTAATCATGAAAGGATGTTGAATTTTATCAAGTGCTTTTT +AATAATAAAAATAAAGGATTTTTATCGTTTATTGTGTTGATGTGGTGTATCACATTTAGT +GACTCTTGTATGTTAAAGCATCCTTGCATGCCAGAGATAAATCCCACTTGATCCTGGTGA +ATAATTCTTTTTTTGTTTTTTATTTATTTATTATTTATTTATTTTTTTGAGATGGAGTCT +CGCTCTGTCATCCAGGCCTGAGTGCAGTGGCGCGATCTCGGCTCACTACAAGCTCCGCCT +CCCAAGTTCACGCCATTCTCCTGCCTCAGCCTCCCTAGTAGCTGGGACCACAGGCACCCG +CCAGCATGCTCAGCTAATTTTTTTTTTTTTTGGATTTTTGGTAGAGACTGGATTCATGGT +GAATAATTCTTTTAATGCACTGTTGAATTTGGTTTACTAGTATTTCATTGAGGATTTTTG +CATCTATGTTAACCAGGGATATTGACCTATAGTTTTCTTATTTTGTAGTGTTCTTATCTG +GCATTGATATCAGGATAATGCTGGCCTCTTAGAATGAGTTTCAACGTGTTCCCTTTTCTT +CAATTTTTTTGGAAGAGTTTGAGAAGGATTGTTATTAATTCTTTAAATGTTTGTTGAAAT +TGACCAGTAAAACCATTTGGTCCTGGGATTTTCTTTGTTGGGAGATTTTTCATTACTGGT +TTAATCTCTACTTATTTTTTCCTGTTTTTTTTTTTTTTTTAATTATACTTTAAGTTCTGG +GGTAGCCGTGCAGAAAGTGCAGGTTTATTACTTAGGTATACATGTGCCATGGTGGTTTGC +TGCACCCATCAACCCATCATTTACATTAGGTACTTCTCCTAATACTATCTCTCCCCTTGC +CCCCATCCCCCAACAGGCCTCAGTGTGTGATATTCCCTGCCCTGTGTCCAAGTGTTCTCA +TTGTTCAACTCCCACTTATGAGTGAGAACATGCGGAGTTTGGTTTTCCGTTCCTGTAGTT +TTCAGATGTGCTCTGGCCTCCAAGGACCATGAAGCCAGGCGGTGGTGGGGGGGTGTCCTC +TGTATAAAAAGTGCTGTCCCAGGAACTTCCTGACGGACACTTTGGGGCATGTGAGCGATT +CCTGGGGAGGGCACCTCGGCCTTCCTAAGGCTACCCCTGCAGCCAGCGCTGGCCATTCTC +ACCAGCAACCAACCAAAAAACATCAGAGTCCCTGTAAACCTGGTTGTGATGATAAAAACC +AAATGTTTTCTAATCTAAGACTTGTATGCAGAACACAGAAAACTGCAGTTAAGGAACACC +CTACAAAATTGACCAACAGTATTTTCCAAAAACATTTTTCATCACTTTAAATAATGTACA +AAATCTACAAAAATCATATTTACCAGGACACATCTGTTAAATAAAAGCATTGTTTCGTGT +TGGTATACATATATACAAGACTATGTATAACAGACTGTTTCCCCTCCCTGCAACCACAGA +ACCATCACACACAGGCACAGATACACGTCAGCTATGCCGCTTTCCACGAATGCATGGAAC +CCAGGACGCGAACCCACAGCTCGAGGTCTTATACCTTCACTACTGAGCTGCCGCCACTGC +AGCAGCAACACCTCTGCGGAGGTGTTGCTGAAATCACTGGTGTCCCTGCCCAAGGTGTCC +TGGTCCTGGTCAACTCTACTGATTGACCCTTCGTGGATACCTCAGGTCTAAAATCCTTTC +CTCCGAGCCAGAGCTCTTCCTGTTGTGCAAACTCAGCCCCGTCTGTACCTTCCTGCTTGG +CCGGTGATCGCAGTCCTTCTTCGCCAGCAAGTGTGGGCTTCCAAAGACAAGGCTGGGCCT +GGCCTGGGACTCCCTGAAGGCCGAGAAGGACAGGCCCTGCAGAGGCAGCCCCAGGTAGGG +GCTGAAGAGGCCGGTCTCCCTGCCCCCCCAGGAGACACCCTTTCCAAAGTGGAAGAGCTG +GGTGGACAGCAGCGGGGAGAAGCCCGCAAGGGGCAGGCTGGGCAGGCCCCGGGCGGGGCC +CTCGGACCCCTTGTCTCTCTCTCCCAATGCCGCCCCCTCCACGCCGCATCTCTACCTTTG +GAGCGCAGTGCCCATGGGCTGGGCAGCCGACTGTGGTGGGCAAAGTCACTCCAGGGCGGG +GCGCGGTTGGCCTGGGCTCCAGCATCCCTCTCAGCTCCCGGGCTGGGGGTCAGGAAGCTC +CGGTTCCTGCAGTCCACGTGAAAGGTCCCCCTGGCTCCTCCTGCCTCGGTGCCCGCTGTG +GCACAGCTGGGCCGCTGACCAAAAGCACTTTTGGCAGCAGGCTCAGCCCCTCGTGGGCTC +TGGTCTTTGTAAACGTAAACACTTCTCTTGCTCACTGAGAGACCTTGGCGGAGACACTGC +CGCTGGTCCTCCTGGGTGGCGCATGATCCCCTCCGCCGGATCAGTGGGGAGCCCCTTCCC +ACCCTGGCTGAGCAGGCACGCTGCGCCCTGTGCTCCTGCGCTCCCTGCGCCTCGATGCCC +TTTAGCCAAATGTGGGACCCCCCGGCCCTCTGGCTCCGTGTGCACATGCCAGGCAGTGGG +GCCGGCTCCTTCCTGCAAGGTACCTCTGGCCTGGCTGGGCCCCCTGTCCCGAGAGCGGTG +GGGCCCTCTGCCTGAACTTCTGAACTGCTCACCGACTCCTTGGCCTTTTCCACCAAAAAC +TTCCTAATCTCCAGTTCGATGCTATCGTCGCTGTCCACTGAACTGCTGTTGTCAGACAAG +GAGCCAGGGCTGGGAGCTGGGCCCTGGGACTCTCTGGGGAATAGATTCTCTTCGGAGGCG +GAGGCAGAAGCGGGTCTCCTCACCAGGAAGGCCGGGGCTTCGTCCTCTCGGCCCTGCTGC +CAAAGACACTGGGGGGTTTCTTCCTGGAGCCCTCGCAGCTGTCTCTCTTGGACTTAGGCA +GCTCTTCAGCACCTGCAGGTGCCTGTTTTTCCACTCTCTCAGGAGCCTGCCCAGCCGCTC +CTGGAAGTGCGTCTGGGAGGTGCTGAACCTGACCTTCTTCCTGCACACAGCCCTGGGCTC +CCTGGACCTCTTCTTGAGCTTTCACTTGGACCTTAACAAGTCCTTGATGGCTGTGTCCAG +GTCCTTGTCACTGTCCAGGGAACTGCTTTTGTCTTCGGAGCTCTTCTTCTTGTCTAGGTG +CCTTGCCTCGTCTGTCTTACCCTGGCCCTGTGACGTGCGAGTGTCACCGGGCACCCTAGC +GGCGCCCTCTCCTCCCGGGGCCTCGCTGGCTGTGCCCTGGATGGAAAGGTCCCACCCTAG +CGGCGCCCTCCCATCCCGGGGCCTCGCTGGCTGTGCCCTGGATGGAAAGGTCCCGCCCCT +CATGGCCGGGCCCGGCTCTCCCCTGGCTGCGGTCGGCATCCTGGCCACCCTCTTTCCCCA +CCACCCGCATGTTCTTGGGAGTGGATGGCCTCACTTGGCAGCCGCCTCTATGCTTCCTTT +TGCAGCCAGGAGTGGGTCCAGTGTTTTAGAGAGAGGGGCCTTGGGGCTGCCGGTCTGGCT +GCTGAGGCCAGGTGGTGAAAGTGGGCCCTGGGCAGCCTGAGGGCAGCTCTCACCTCTGGC +CAGCAAACTTCTAGACTGCACCTTGAGGGCCAAAAACGTCCAGATTTCCTGCTCAATGCT +GTCGTCGCTGTCCACGGAGCTACTGTCACCATCAGAGCGGGAAGGCACGTTGGGGGAGTA +GAAGAGTGGGCTTGCGGACAGGGACCCATCGCTGCCCTCCATAGGGCCGGCAGGATCGTC +TTGAAAATGTCCAGGACTGCTTCTACACACATCAGCTCAGCGGAGGTGTCTGCCTGGCAA +GAGGACCATTCCACAAACTTGCTCCTGGAAGCCGGGCTCGTTGGAGGTGGAGCTTTGGTT +TCCTTTGGGATCTTGGGGGAATGGTCAGCGTCCAGATCCCCTGGACCAGGGTCCGTGGTC +TTGGTGGGCACTGGCTTCTTCTTGCTGGGTGTTTTCCTGTGGGTCTCTGGCAAGGCACTT +TTTGTGGCGCTGCTTGTGCTGTGTGCGGGAGGGGCAGGTGCTCTTTCCTCTTGGAGCTGG +ACCCTCTGGGGCGGGTCCCCGTCGGCCTCCTTGTGTGTTTTCTGCACCTGGTACAGCTGG +ATGGCCTCCTCAATGCCGTCGTCGCTGCTGGAGTCGGACGCCTCGGGAGCCTGTACGGCG +CTCGTGACTCGCTTTCCCCTCCTTGCGGTGCTGGCGCTCCTTTTAATCCCACTTTTATTC +TGTACTGCTTCTGAAGGGCGGTGGGGGTTGCTGGCTTTGTGCTGCCCTCCTTCTCCTGCG +TGGTCGTGGTCGTGACCTTGGACCTGAGGCTTCTGGGCTGCACGTTTGTCTTTGCTAACC +GGGGGAGGTCTGCAGAAGGCGAACTCCTTCTGGACGCCCATCAGGCCCTGCCGGTGCACC +ACCTTTGTAGCCGGCTCTTGGTGGGATTTCGAGAGTGACTTCGCCGAATTTTCATGTGTG +TCTGGTTTCTTCTCCACTGACCCATCACATTTTTGGGTCTCATGCTGTCTTTTCTCATTC +AGAAACTGTTCTATTTCTGCCCTGATGCTCTGCTCAAAGGAGTCTGCTCTGCTCATGCTG +ACTGGGGAGGCAGAGCCCTGGTCCTTGCTGGATCCCACCTGGCTGCCAGGGCCACACCAC +CTGAGCCAGGTACAAGTTTTGGGGAACACAGGGCAGTTGGGCACTGCTGTGAGCCAGTTC +CCGCTTACATCTACTGCCTCCGCCCGCAGCCCTGGAAGGCTGTGCATGGCTGGGCCCCGC +TGGCCCCGGGCTGTGCCGCTCCACTCTTTACCTTCAGGTACTCCTGGATGGCCTCCTCAA +TGTCCCGGTCCACGGAATCGTCACTGTCTGAATCTAGCACCAATGGGCCAAAGTCTGCAG +TTTCCTCCTCCCCCACGGGGTCAAAGTCAGCAACAAGACCACAGGCAGCCAACGCAGGCA +GCTCCTTGTGCATGGTGGGCTTGGCAGCAGGCCTGGCGTCGTGGCATCCCTCTGCCCCCT +CTGCGCAGTGCGCTCATCGCTGGTGCCCCTAGCAGCCCTGTCGCTCTGCAGCGTGCTGAT +GAGCATCTGCACCCGGGTGCTCACCGACATGCTCTCCACGCCCTTGTCAGCCTCCGAGAA +GCACCCGGGGAACCTAAAGCTCCCTGGCGGGACAGAGGCCTCCCATTTGGGCTGGAGAGC +AACCACTGGAGGAGCATTCATGAGAAACATTCTGGCAGATGGGGAGCGACGCGCAGAGGG +GCGACACTTTATTTCTCTGCAGGCTTCACATCCTCCAAAGATTGGCAAGCAGTACCCGTG +AAATAACTTTAAACCTGCAAATGCTTCTTTGCAGGTTTAAAAGGATGACTATAAACTATG +ACGTCATGCCTAGATTCATTCTTGACCCAACCAACAAGCTCTTGACATTCTCTGAGTCCA +GGTTGACTGTGATGAAAGGCAGCTAGTGTTCCCAAATGGCCCAGGGATCAGGTCTTCATC +GCTCCACTCAGAGGGAAGCATCCTCTCTCTGCTTTTTAAATAGACTTTTGACTGGGGCTC +CAGCAGCGCGGGGCGCGCAGACCTGGAGTTGCATGGAGGCCAGAGCCACGACACCCGCCT +GGGGAACGGAGCAGCCCCAGGCGCTGATCCCCGTCCACCTGCCCCACGGAGCCCTCGCCG +CCCGCTTGCCACTGCCTGCATGGCCCTCCTGTCCCCGGCCCCCCAGCCCTCCTTTCCCCA +GCTCCCCCACCCTCCTGTCCCCGGCACCCCAGCTTCCCAGCCCCCGAAACCGCCCCCCCA +CCTCGACCCGGCCCATGCCGCAAGTCGCCCGCTGCGCGGACCCGGCCTCCGCCCGCCTCC +TGCGTCCTGGGGGAGGCGGCTGCCGGGGGTGGTGGGGGAGGGGGAGGGGGAAGAGGCCGC +CCTCCGCCCGGGTGCGGGGAGGGGGCGCAGGGGTGTCCGGCCAGGCCCCCCGCCTCCCCG +CCTCCCCGCAGCAGCTGCCCCGCTCCCGGGCCGCCTAATACTTTTACATTTTAACTTTTA +TACTACAGTGAAAAGTGATTTACACACCACCACTGCAATATTACAGTGTTATGAATGTGA +CTATATACTTACCTTTCCCTGTGAACTTTTTTTTTTGAGACAGAGTCTCGCTCTGTCGCC +CAGGCTGGAGGGCAGTGTCCATGATCTCGGCTCACTGCAAGCTCTGCCTCCCGGGTTCAA +GTCATTCTCCTGCCTCCGCCTCCCGAGTAGCTGGGACTACAGGCACCCGCCACCACGCCT +GGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTTTCACCGTGTTAGCCAGCATGATCCC +CCTCTTCTGACCTTGTGATCCACCCGCCTTGGCCTCCCAAAGTGCTGGGATTACAGGCGT +GAGCCACTGCGCCCGGCCTACCTGTGAACTTAATATCTTAATGTTTTAATGTTGCTAATC +AGAATCCTTTTATTTCAACTTGAAAAACTGCCTTATAAGGCAGGTGCAGTGGTGATGAAC +TCCCTTAGAATTTTTTTGGTGGGAGTCTGGGAAAGACCTTATCATCTCTTTTTCATTTCT +GAAGGACAGCTTTACAAGTTGTGGTCTTCCTGATTGGCAGTTTTTTTCTTCCAATACATT +GAATATAGCATCCTATTCTCTCCTGGCTTATAAGGTTTCTGCTGAGAAATCCACTGATAG +CCTTATTGAAGTTTCCTTGTATGTGATGAATTCCTTTCTTCTTGCTGCTTTTGAAAGTCT +CTGTCTTTGACTTTTGATATTTTAATTATAATACATCTTGGTATTATGGTCTTTGGGCTG +GCCTTTTTTGGGGCCTCTGAACTTCATGTGTCTGGAAGCCCACTTGCCTCTAAGAATTTG +GAAAGTTTTTACCCATTATGTCTTCAAATATACTTTCAGGCCTTTTCTATCTTTTTTACT +TCTAGGAAGTCCATAATATGTTTGACCCACTTCATGGTGGTGTCCTATAAATCCCAAAGG +TTTTTACTTATAAACTTTTTTTTCTTTCTGGTCTTCTGACGGGATATTTCAAATGTCCTG +TCTTTAATTTCACAGATTCTTTCTTCTGTTTGATCAAGTCTGCAATTGAAATTCTCTATT +GCATTTTCATTTCATTCATTTATTTATTTTTATATATTTTTGAGACAGAGTCTGTGTCAC +CCAGGCTTGAATGCAGTGGTGCCATCTTGGCTTACTCCAACTTCCACCTCCCGGTTCAAG +CGATTCTCCTGCCTCAGCCTCCCTAGTAGCTAGGATTACAGGCATATGCCACCATGCCTG +GCTAATTTTTGTATTTTTAATACAGATGGGGTTTTGGCATGTTGGCCAGGCTGGTCTTGA +ACTCTTGACCTCAAGTGATCCGCCTGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGT +CCGCCACGGCACCCAGCTTGCATTTTCATTTTATTCATTGTATTCTTCAGTTCTAGAATT +TCTGTTTGGTTCTTATTATTTCTGTATCTTTATTGAACTTTTAGCTTTGCTCATCTACTA +TTTTCTTGATATTATTGAGTTGATATATACATTCTAGTAAATTTCACTGAGCTATCTTAA +TTATTTTGAATTGTCAGGCAATTTGTAGATCTCTATTTTTGGGGGGTTGATTACTGGAGA +TTTATGAGTTTATTTTGGTAGTGTCATATTTGCTGATTCTTCATGATCTACAGACTTTCA +TTAATGTCTATGAAGAAGCAAATACCTCTTCTTTTTTTTTTTTTTTTTTTTTTTTTTTGA +GACAGAGTCTTGCTCTGTCACCCAGCTGGAGTGCAGTGGTGTGATCTCAGCTCACTGTAA +CCTCCACCTCCCAGGTTCAAATGATTCTCCTGCCTCAGCCTCCCAAGCAGCTGGGATCAC +AGGCATGTGCCACCACGCCTGGCTAATTTTTTTGTATTTTTTGTAGAGACAGAGTTTCAC +CGTGTTGTCCAGGCTGGTCTCAAACTCCTGGCCTCAAGTGGTCTGCCCGCCTTGGCCTCC +CAAAGTGCTGGGATTACAGGTGTGAGCCACCATGCCCAATCTCTTTCTGTCTTTATAGAT +TGGTTTCAGCAGGTACAAACCTTTTCCTGCTGGATCCCTTGACTGGATCACAGTCAAGTG +GGCCTGGAGCCATATTACATGGCTGCTGCCTGGTCTGCAGCTGAATCTCTGATTGGCAGG +CCGCTATCAAGGCATAGGTTGGTGATGCAGTTTCTGCTGGATCCTCAGGAGAACTGGACT +GCCTCTGATACCCTGATTGAACAGGACTGGAGCCAGGTCATGGGGCCACTTCTAGTTCTA +CAGTCAAGTCTTCAGATATCAGGCCTATTACCAAGGGCATGGACTGGTATAGCTCCCTGT +GGGTCCCAGATTGAGCTCCTGCTGGTTTACTAGGTAGGTCCATGGGAAGACAGGACTGCC +TCCAGACCACAGTAGAGCAGGGCTAGAGCCAAGTCACAGGACAGCTTTGGTGACCACATT +TGAGTTCAAGATTGGTGGTCCTCTTATTAGGAGAATGGATGGTATGTCTTTCACCAGGTC +CCAGGATGGGCTGGACTGTGCCCAGACTGTGGCAAAGCAAGACTGGAATGGAGTCACAGG +GCTACTTTAGTGTCCATAGCTGAGACTGAGATCAGCAGGCCTGTTACCAAGGGTATGTAA +AGGCATCACTGAATTCCTGGGCAGGCATGACTGACTGTGGTAGAGTGGGGCTGAAGCCAG +GTCAGGGCTGCTTTAGTTTCTGCAGTCAGGACCATGGTTAGAAGGCCTGTTACTGGGGGC +ATAAATGGTCATGGTTCCTCCTAGGTGCTTAGTGGATGGGGCTAGTTGCAAGACCATGAT +CTAGTGGAGCTGGACCCAAGTCCATAGGAGGACAAAGCTGCTTTCAGTCTGCAACTGGTA +ACCTGTCACTGGTGTGTGGACCTGCCTTCTCAAAGCAGCTCTCCTTGGTTTTGGGCTTTG +CTAGAGTTTTGCCACCTCCTGCCTGGATATTAAAACTCTTGCAAAGGCAGTTTTGTCCAT +GAATGGCTGCCAGATCATTGTTTGTGTGGGGAGAGGTGAGTGGAGGGCCTCCTGTTCTGC +CATCTTGCTGATGTCACCCTAAGATGATTATTTGAATTCTTTGTCAGGCAATTTGTAGAT +CTTCATGTCTTTGGAGTCAGCCACTGGAGTTTCATTTTGTTTCTTTGGTGGTGTCATATT +TTCTCATGCTTCCTGTTCTTTGAAGACTTAGATTGCTTTCTTCATGTTTGAAGAAGGAGT +CATCTTTTCCACTCTTTACTAACTTCAGGAGAGAAAGACCATCAATTAGCTAAGCTATAG +ATTCTGGGGGTCTCTCAGTCCTTTTCTGTGGGTGGTCCTTCCCTTTTAAGGGGGATGTCT +TAGGATTTTGTCCCTTGTCTTCATTTCACAAATGAATAAAACAACCAGACCAGACATAAG +TAAGGAAATACAGCACTTGAACAACACCTGAAAAAACAACTAGACCTAACAGACATACAC +AGGATATTCTACCCAACAACATAATACACATACTTCTCAAGTATACATGGGACATTTTCA +GGATAGACCATATAACACATCACAAATTAATTCTCAATAGGGGCTGGGTGCAGTGGCTCA +CATCTGTAATCCCAGAGTAATTTGGGAGGCTGAGGCGGGTGGATTGCTTGAAGCCAGGAG +CTTGACATCAGCCTGGCCAACATGGTGAAACCCCATCTCTACTAAAAATACAAAAATTAG +CTGGGCGTGGTGGTGCGTGCCTGTGATCCCAGCTTCTTGGGAGGCTGAAGCGTGAGAATT +GCTTAGGAGCCCAGGAGGTTGAAGCTGCAGTGAGCAGAGATTGTACCACTGTACTCCAGC +CTGTACTTCATGACAAAGAAAATGTACCATTGTACCACTGACAGAACGAGACCCTGTCCC +AAAAAAGGAAAAAAGCTCAGTAGATTTAAAACGATAGACATCATACAAAGTGTCTTCTCT +GACCACAACAGGATAAAGTTAGAAATCAATAACAGAAGATTTAAAAAAGTTCACAAATTA +GTAGAATTTAAACAACACACTCTCAAACAACCAATGGATCAAAGAAATCACAAAGAAATT +ATAAAATTCTTAAAGACAAATGAAAATGAAAGCACACTATATCCAAACTTATGGGCTGTG +GCCAGTTGTGGTGGCTCACACCTGTAATCCCAGCACTTTGGGAGACTGAGGGAGGTGGAT +AGCTAGAGGTCAGGAGTTCAATTTCAGCCAGGCCAACATGGTGAAACCCTGTCTCTACTA +AAAACACAAAAATTAGCTGGGAGTGGTGGTACGTGCCTGTAGTCCCAGCTACCCAGGAGG +CTGAGGCATGAAAATTTCTTGAACCCAGGAGGCAGAGGTTGCACCACTGAGCTAACACCA +CTGCACTCCAGCCTGGGTGACAGAATGAGACTCTGTCTCAAAAAACAAAGAAACAACAAA +AAAACACAACTTATGAGTTGTGGTGAAAGGAGTGCTAAGGAGGAAATTTATAGCTATAAA +CACATTAAAAAAAGAAACACCTCAATTCAACAACATAAGTTTACACATTAAGAAACTAGA +AAAAGAAGAATAAAACTAAACCCAAAGTTAGCAGAAGGAAGGAAACAATAGAGATCAGGG +CAGAGATAAATGGAAAAGAGAATAGAAAAACAATAAAAAACAAAACCAAAAGTTGGTTCT +TCAAAAAGATTAATAAAACTGACAAGACTAAGGAAAAGGGAAACAATCTAAATTACTTAA +AACAGAAATGTATTTGAGAATATCTTTATATATTTCTGTCTGTCTGTCTGTCTGTCTGCC +TGTCTATGTTTTAGAGACAAGGTCTAGCTCTATTGCCCTGGCAACAATCAGATGCAACCA +GAATCAGTGGCACAATCGGCTCACTGCAGCCTTGAATTCCTGGGCTCGCCACTATGCCAG +CTCTTTTTTTTTTTTTTTTTTTTAAGAGACAGGATCTTGCCATGTTATCCAGGCTGATCT +TGAACTCCTGGCCTCAAGGAATTTTCCCACCTCGGCCTCCCAAATTGTTGGATTACAGGC +ATGACCCACCATTCCCAGCCTAGAAAGGATTATAAAAGATTACTATAAATAATTGTGTGC +TCATAAATTGGATAACCCAGATGAAATAGATGAATTCCTAGACACACAAAACCTACCAAG +ACTCAATTATAAAGAAACAGAAAGTCAGAATAGACCTAACCTAGTAAGGGAATTGAGTCA +GTAATAAGACAATCTCATGACAAAGAAAAGTCCTGGACCTGATAGCTTTACTGGTGAGTT +CTGCCAAACGTTTAAAGAAGAACTAACACTGATTCTTTTCAAGCATTTCCAAAGAGTGGA +AGAGGAGTGAATACCTCTTAACTCTTTCTATGAGGCCAGCATTACCCTGATACCAAAGCC +AAAAACACTGTAAGAAAATAAAACAACAGATCAATATGCCTCTGATCATTGATGCAAAAA +CTCTAAAAATGCTAGTATACTGGGTGGGGCACGGTGGCTCATGCCTGTAATCCCAGCACT +TTGGGAGGCTGAGGTGGGTGGATCACCTGAGGTCAGGAGTTCAAGACCAGCCTGACCAAC +ATAGAGAAACTCTTGTCTCTACTAAAAATACAAAATTAGCCATGTGTGGTGGTGCATGCC +TGTAACCTCAGCTACTCGGGAGGCTGAGACAAGAGAATCGCTTCAACCCGGGAGGTGGAG +GTTGTGGTGAGCCGAGATCATGCCATTGTACTTCAGCCTAGGCAACAAGAGCAAAACTTT +GTCTAAAAAAAAACTATCATACTGAATTCAGCATCATATTAAAAGGATTATACACCATGA +CCAAGTGGGATTTATTCCTGGAATGCAACGATGTTTCAATATATAAAAATTGATCCATAT +AAATTCAGACAATTAATTTTAACTGATGTATAGTTTTACATTATATGCACATACCACGAT +TCACTTTTCCATTTTCCTAGTAATGAGCTTTAAGATTATTTCCAATTTTTAGCTATTACC +AATAATGTTTCAACAAACACCTTTGGACATCTCTTCTGCAAATGTGTGTGTATTCTCTTG +GAGAAGGTTTACCCTGTGGAATTTCTAGTGTGTATGTGTATGTGTGTGGGTATATATATA +TACACATATGTATATATTTTCAACTTTACTATATATTTCCAAAAAACTCTTCAAAGTGGC +AGATTTAAACTCCCCTTCGCCGTGTATAAATTCACGGTTCCTAAAGCCCTTGGCATAGTT +TTGTGTTTTTATAGAAAAGGGCATAAAGTCTTATTGCTGTTGAATTGTACCTTGCTCTTT +TCAATTGTCTTTTCACAATAATTCACTATTTATCATCTGTTGTGAATATTGTGTAGTAGT +TCTTAATCATTTTTTCTACTATATTATTTATTTTATATCATGAATTTGTAGAAATCCTCT +TTATATAATGGATATTATACTTTTCAATTATATATTTTGTAAATATTTTACCCAATTTTC +TGGCTTGCATTTAACCTTTATTTAGGATGCCTAGGATTTTTCATTTTAATACAGTCTAAT +TTATTTTTCTTTTCTTTTCTTCTTCATGCATTCTGGCATTTGATTAATAAGCCATTTGTT +GCCCAACGTCATTAGTTCTCTGTATATACTTTTAAATATCTTAAACATGTAATATTCATA +AGTAATTTCACAAGTAGTTTAAGATTTGAGTCTTTAACCTAAATAGATACAGGATTTTGT +GATATGCTGTAATATACAGATTTTTATTTATATATGGATAAAAATTTATATGTTTTTTCT +GACATCATTTATTGAATAGTATAATTTTTCTACTGACTTTTAGTATCATATCTTTTATTA +CAAGTCCAATGTATTCAGCATATCTATGGATCTATTTCTTGGTGCTTCCATTTTTTCCCA +TTGTTTAACGGTGTATCACTGAGCCAAAGCAAACCATTTTAATTATTATAATTAAAACAC +ATTTAAATATTGATAGGCTATTATTGTTCAGAATAACTTTGGTTCTTCCTTTCCATTGAT +TATTTTAATATGACTTTTCCAATCAAGTTCTAAAAAAATACTGGTGGTATATTTATTGAA +ATAACTTTAATAAAATTAAATGAAAGATCATGTGTTTTCTGAATTAATTCTTAGATACGT +TAATGTTTTATGTTACCATGAATGTGATATTATAATATAATATTTTTAATTGGTTGCTAC +TGTTTATAAGAATTTCATTTTCTCTTTACTTTGCCTTCATATCTGAAAACCTTGCTGATT +TGATTAGTGCATCCACAAATTTTCTTGGATTTTCTATGGGTAATTACAAATCTCCACACA +ATGAGGTTGCAGTGAGCCAAGATCACACCACTGTACTCCAGCCTGGGCGACAGAGTGAGA +CACCATCTCACAAAAACACATAAACAAACAAACAGAAACTCCACACAATGACAACGTATG +TGTTTTCTTTTTTTCTTCCTCTTTCTATAATATTTCTTTGTCCTATCTTAACTGAACTGG +CCAGAAACCCCAGGACAATGATAAATACGAGCAGTGTCAACAGACATCTCATTCCCTTTC +CTAGCTTTTATAAAAAATAACGATTATGCTTCAACATTACATATGGTGGTGTCGATGGTT +TTGTTATAGATAAGCTTATCAGGTTAAGAAATTTGTCTGCTTTTCCTAGTTTGGTATAAA +GATTTTAATATAAATGAATGTTGTATTTTACCATCTTATTTTTTTTCCTACATCTGCTAA +GGTAATCCTGTGTTTTCCCTTTTTCAATCTCCTAATGTGGTGAATGACATTAAAATACCT +TCTATTGTTAAAATATTCTTGCAACGCTGTATAGAACCAATGCCTTTATTCTGTATTGCT +GATGGATTTTTGAAAAATATGTAGGTGGACTTAGTTTTCTAAGGGGAATAGAATTTCTAG +TATATTTAAACTATTTTGCATGTATGTTCTGAAGGACATTGGTGTGTCATTTCTATACCA +TCTGGCTACGAGAGGAGCCGACTGAAAGTCACACTGCCGGAGGAGGGGAGAGGTGCTCTT +CCGTTTCTGGTGTCTGTAGCCATCTCCAGTGGTAGCTGCAGTGATAATAATGCTGCGGTG +CCGACAGTTCTGGAAGGAGCAACAACAGTGATTTCAGCAGCAGCAGTATTGCGGGATCCC +CACGATGGAGCAAGGGAAATAATTCTGGAAGCAATGACAATATCAGCTGTGGCTATAGCA +GCTGAGATGTGAGTTCTCACGGTGGCAGCTTCAAGGACAGTAGTGATGGTCCAATGGCGC +CCAGACCTAGAAATGCACATTTCCTCAGCACCGGCTCCAGATGCTGAGCTTGGACAGCTG +ACGCCTTGGATCATCTGCCACTGATCTCTGGTCAACATTTTTATCACCCAACACAAAAGA +AGCAGAGATTTATCAAGTTACTTAAACAACCTGACCCTTTCATCTTTTGCTACACATACT +CTTGTAATTGATCTCTCCATGAATTGTTTTCTGTTTAAAATATCTAGAATGTTTTCTGCT +TCCTGACTTGATTCTAATATTGTATAGGTACTAGAAATGGTTCTAGAAATAGATCTTTAT +AGATGAGAATCTGGAAGTGGTTTGCTGACCTGTTTCAGTCTGAATGAATTCCTGACCTTG +TTGTCGGGAGGAGACAGAAACCTGATCATCTGTAGTGTACGGTGGTATCATGATTACTTA +AATCATCAAATGTGGTTATTGGGAATGATGTGTTTTTTAAAGTGGTACATGAGAGGTAAA +ATTGCTATTGTAGTTGACTGTTGCAGTTATAATTTTGTCAACATGGTCTGTAAGAGTGCA +ATGGATTCGGCCCGGTGTGGTGGCTCACGCCTGTAATCCCAATACTTTGGGAGGCCAAGG +TGGGCCGATCACGAGGTCAGGAGATCGAGACCATCTTGGCTAACACAGTGAGACCCCATC +TCTACTAAAAATACAAAAAATTAGCCATGTGTGGCGGCACACGCCTGTAGTCCCAGCTAC +TCGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCGGGAGGCAGAGCTTGCAGTGAGCCGA +GATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCAAGACTCCATCTCAAAAAAAAAAA +AAAAAAAAAAAAGAGTGCAATGGAAAGCTGGTAGAAAATGGACATTGTTTAAAGACCAAA +ACAACCACACTACTTTGCTAATCCCTATCAGCTAAAGCCTAGAGAATATATGAGGTATAG +ATTTACATGGTGTTTGACTAAGGCATGCAGAATATAATCTTGACATAGGCTAAGTTTATC +AACATAGATACATAGAGATTCTGAAGTTAAAGTCTTAGCCCAAGAAGTTAGAAGGGGTGC +TCAAGTTTGTTTGTCTGACAGAAACTGTGAATCCACACTGGCCTGCTTATTTTGAGGTTG +TGTTGCCAGAGCTTTCCTAGCATAATAAAGAGAGGTGCATACAAAGGAATAGGAATAGTA +GGAGGTGGGGGTAAAAATATCAGGTGTGATCCACATGCCAAGCCGACCCGCACTGTGTCC +CACAGGAAGCCCAGAAGATGTTTCTCTAAGAAATTAAGGATTCGTTTGTTGGGGAGGGCT +GCTGGCATGCTTGAAAAGTACTGTGATGGCTGAATTTTGTGGGCTTGGGGAGATTGCAGA +TTCTCTGATTTCAAGGGGAATGATGTGATCCTAGAGTTGCAAAGAACAAGTGACAGTGGA +GGCGCTTATGCTTTGTGACTGCACTAGAGACAAGGAAGACACAACTAGAATAATGGGGAG +CAGGAATGGAGCGGCCAACAGAATATGTGACTGTTAGGGATCTTTGATGAAGGCTGATTC +TCAGGGAGTGAACTACATCAGTGACCAACTATTTGTCTTTATATAACTGGGTAATGTGGA +TGGATTCTAATAAAGGGACTACTTACAGCACAGCAGGAAAGTCACAAAGAAACCAGACAG +AAGAGTGTAAGTAGTAAGGGGCCAAGCAGTCACCTGACTAGAGACAGTGCCAGCTTGCCA +AGAAGGCACCAGACAGAAGCTGTGATCTTCAGCAAAGGGACACAGTCTGCCTGTGCTGAC +CCTGCAGGGGCAGAGGTGGGGGATAAACACACTCTTCTCTCACCTATCTTCTGCCACCCC +CTCCATTAGCTGAACCCCAATAAAAGCATGAGGGTAAGGGAGATCTCTGAAGTATCCAAT +TCAGGTGAGCCTCCTAAGGAACAAAGCAGAATGCAGAAAAATTAAGAGTGGGTCTAGGGA +ATAAAATAGAGATATGCACCAGAGTATGATGATGTGTCTGGGAAAGAATATACAAATACT +TTTAAAATTACTAGACAATAAACCTGAGATGACACTAATACAGGTAAATCTCATTTAATG +GTAATATATTCCAAGAAATGCATCATTAGGTGATTCTGTGGCTGTGCAGACACCAAAGAG +TGTACTTTATACAAACCTAGACAGCGTAGCCTACTACATACCTAGGCTATATCGTACAGC +CTATTGCTCCTGGGCTACACACCTGTGCAGCATGTCACTGTGCTGAATACAGTAGGCCAA +TGGTCCCCAACACCCAAGCCATGGACCAGCACCGGTTCGTGTCCTGTTAGGAACTGGGCA +CAAAGCAGGAGATGAGTGGCTGGCCAGCCGAACATTACTGCCTGAGCTCCGCCTCCTGTC +AGATCAGCAGCAGCATTAGACCTTCACAGGAGCACAAACCCTATTGTGAACTGCCCATAG +AAGGGATCTAGGTTATGTTCTCCTTATGAGAATCTAACTAGGCTGGGTGCTGTGGCTCAC +GCCTGTAATCCCAACACTCTGGGAGGTCGAGGCAGGTGGATCACAAGGTCAAGACAATCC +TGGCCAACATGGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCTGGGTGTGGTGGCG +CATGCCTGTAGTCCCAGCTACTCGGGGGACTGAGACAGGAGAATCACTTGAACCCGGGAG +GCAGAGGTTGCAGTGAGCCGAGATTGTGCCACTGCACTCCAGCCTGGCAACAGTGGGAGA +CTCAGTCTAAAAAAGAAAAAAAAAGAAAAAAAGAATCTAACTAATGCCTGATGATCTGAG +GTGGAAGAGTTTCAGCCCAAAGCCATCCCCACTCCGTGGAAAAATTATCTTTCACAAAAC +CAGTCCCTGGTGTCAAAACTTTGGGGCCCACTGCTGTAGGCAGTTATATCACAGTAGTAA +TATCTAAACATGGAAAAGATACAGTAAAAACACAGTACATTGGGAGACCGAGGGGGGCGG +ATCACCTGAGGTTAGAAGTTCGAGACCAGCCTGACCAACATGGAGAAACTCCGTCTGTAC +TAAAAATACAAAATTAGCTGGGCGTGCTGGCGTGGGGCTGTAATCCCTGCTACTCGTGAG +GCTGAGGCAGGAGAATCACTTGAACCCCGGAGGCAGAGGTTGCAGTGAGCCAAGATCGTA +TCATTGAACTCCAGCCTGGGCAACAAAATAAAACTCCTTCTCAAAAAAAACAAAGAAAAA +AATATATATATATTACAAAATTTAAAGAGAGTGGTACACCAGTAAAGGACATTTAGCATG +AACAGAGGTTGCAGGACTGGCAGATGCTCTGATGAGTCAGTGAGTACCTGGTGAGTGAAT +GCGAAGGCCTAGGATATTACTGTACATAACTATAGACTTTATATGCACTGTACACTTAGG +CTACACTAAATGTATTTAAATTTTTTCTTTCTTTAACAAGTTCATCTTAGCTTATCATAA +CTTTATAAACTTTTAATTTTTTTAATTTTTTGATTCTTTGATAATAACACATCTTAAAAC +AAAAACACATTGAACAGCTGTACAGAAATACTTTATATCCTTATTTGATAAGCTTCATTT +ATTTTGATTTTTTATGTTTTAAACATTTTTGTTAAAAACTAAGATACAAACACACACACT +AGCTTAGTCCTGTAAGGGTCAGGATAATCAATATCACTGTCTTCCATCTCGAAATCTTGT +CCAAGTGAAAGGTCTTCAGGGTCTTCAGTGGCAATAACATACATGCAGCTGTCATTCTCT +ATGATAACAAGGCTTTCTTCTGGAAGAACTCGTGGAAGACCTTCCTGAAGCTGTTTCATA +GTTAATTTTTTTTAATGAGTAGTAGTACTACACTCTAAAATATGAATAAAATCTGTAGTA +TTATACATACTGTTGATCCTTGAACAGTGCAAGGGTTAGGGGACCAGCTCCTGTGCAGTT +GAAAATCCATATATAATTCTGGGCTATCCCCAAACTTAACTTAATATGATATATATCATA +TATAATATATATGATATATATCGTATATATTACATATGATATATATCATATATAATATAT +ACGATATATATCATACATAATATGTATGATATATATTATACACAATATGTATGATATATA +TTACATACAATAAGTATGATATATATTATATACAATATGTATGATATATATTATATACAA +TATATGATATATATTATATACTATATGATATAGATTATATACAATATATATGATAGAGAT +TATATACAATATATATGATACAGATTAAATACAATATATATGATACAGATTATATACAAT +ATATATGATACAGATTATATACAACATATATGATAGATTATATACAATATATATGATATA +GATTATATACAATATATATGATATAGATTATATACAATATATATGATATAGATTATATAC +AATATATATGATATAGATTATATACTACATATGATATACATGATATATCATATATATGAT +ATACATGGTATATCATATATGATATATACGATATATCGCATATATGATATAGATGATATA +TCGTATATATGACATAGATGATATATCATACCTGATATAGATGATAAATAATATATGATA +TAGATGATATATATCATATATGATATATCATATATTATATAATAAATGATATATATTATA +TATAATAAAAGATATATATTACATAATAAATGATATATATTATGTAAAATATATGATATA +TATTATATATTATATCTGATATATATTATATATTATATATTTTATCTGATATATATTATA +TATTATATCTGATATATTATATATAATTATATTATATTATATTATATATTATATATTTTA +TATTATATGATATATAATTATATTATATTATATTATATTATATATATTATATTATATATA +ATTATATTATATTATATATTATATATTATATTATATATAATTATATTATATGATATTATA +TATTATATATAATTTATGATATATATTATGTATTATATATAATTTATGATATATATAATA +TATTATTTATCATATATCATATATATTATGGTATATTATATATAATTGTATTATATATAA +TAATATATAATATACCATAATATATCATATATTATATAATATATAATATAATATAATATA +ATGTAATCATATATAATATATAATATATTATATTATAAAATATATTATATTATGATATAC +TATATATTACATGTTACATTATATAATATTTTGTATAATATATAATATATATTATCTATT +ATACTTTATTATATTACATATATAATTATACATTATTATATTTCATATATAATTATATAA +TTATACATAATTATATATATTATATTATATATAATGTTATGTATAACAATATATATTATA +CATAATATTATATATTATATTAAATATGATATTATATATAAGGATGCAGGATGTAAAAGG +AAATTATATATATGTTATATATTATATATATTATATTATACATAATATATATATATATTT +GGGGGTGCCCTATTTCCTATCTCATAACTTATTTTAAGAAGCACAGCATAATAATGTGTG +GACTTGGGATTCAGTTTTTGAAATGAAACACTGAGCCTTCGATGACCTTCCTGTACATGT +GAAAGCACACCTGTCTGCATGGCAGCAGTTGGACCTCACAGTGTGGATTGTGCCTTCACC +CTGGAATGTTTATGCCCTATCGCCATGGTGATGGGATTAGGGATCTGCTGCCCTTGGTCC +TAAGTGCCACTATCTGTGCTGAGTTTTTCAAAGGTCAGAGCAGATTGAACCTTTGTGGTT +TCATTTTCCCTGATTTTGATTTTTCTTATGGGGAACCTGTGTGGCTGCATTCAAGGTATG +TTCATACTGGCCTGTCAAATGCGATCTTTTCAAATTACTAGTTAATGCTTTCAAAATATG +TTATTTAAAAAATTAGCCTCTGTATTTTCCATATGCAGTTATAAATATGTTTCATGGTTA +GGTTTTATTCCTCAATTTATATATTTGATTATTGTACCAAGCAGAGTACCTTTGAAATTT +TTCTTCATTTAAAAAATATGTATCTTGGCTCAAGCCTGTAATCCCAGCACTTTGGGAGGC +CAAGGCAAGAGGATCACAAGGTGAGGAGATGAAGACCATCCTGGCCAATGTGGCGAAACC +CTATCTCTACTAAAAATACAAAAAATTAGCCAGGCATGGTGGCAGCTGGTGTAGTCCCAG +TGTGGTGTAGCCCCAGCTACCTGGGAGGCTGAAGCAGGACAATCGCTTCCACCCGTGAGG +CAGAGGTTGCAGTGAGCCAAGATGGCACCATTGCATTCCAGCCTGTGCAACAGAACAAGA +ATCTGTCTAAAAAAAATTATATATATATAATGTATATTATATGTACTATATATTACATAA +AACATATAATATATAATATATATAATATATATAAAATATAATATACATTATATATAAATA +ATATATATTATATGTCACGTTATGTAATATCTATGATACATATTACATAATAAAAGACAT +ATATAATATATGATATATATTACATATAATATATGATATATATTACATATAATATATGAT +ATATATTACATATAATATATGATATATATTACATATAATATATGATATATATTACATATA +ATATGTGACATATATTACATACAATATGTGACATATATTATATGTAATATATGATATATA +ATATATAATATATGGTATATAATATATAATATATGATATATAATATATGATATATAATAT +ATAATATATGATATATAATGTTATATTACATATAATTATATTATATTATATTATATATAT +CATAATATATTATATAATATATAATATATATCATAATATATTATATAATATATAATATAT +ATCATAATATATTATGTAATATATATAATATATCATTTTATATATTATATATAATATGTC +ATAATATATTATATAATATTATATATAATATATCATAATATATTATATATTATATTATTA +TAAAATATATAATACTATATAATGTTATATATAATATAATATTATATTAGATTATAATAT +ATAATATTATATTAGATTATAATATATAATATTAGATTATAATATATAATATATTAGATT +ATAATATACATTATATTATAATATATTATTGTATAATATGTTATAATATAATATATATTA +TATATTATATTATACATAATATTATATTATATATAATATATATAATATTTTATACAACAT +ATTATATATAATATCTTATATAATATATTATACAATATATTATATTGTATAATATATTAT +ATATATTATGTATTATTATCTTGTATATATAATTATATATAATTATATAATTATATATAT +TATATTATAGGTAATAATTATATATAATTATATATTATATTATATGTAATAATTATATAT +AAGTATATATTATATTATATGTAATAATTATATATAATTTATGTATTATATTATATGTAA +TAAATACACATAATTATATATATTTTATTATATATATTATGTATAATTGTATATTATATT +ATATATAATAATTATAGGTTATATTAGATATATTAATTGTATTTTATATTATTTTTAATA +TTAGTTAATATTAATTAATAATAATTAATTTAAATATTAATTATTATTTTATATATTATA +TTATATATTATGTTATATATTATATTATATATTATATTATATTATATATTATATTATATT +ATATATTATATTATATATTATATTATATATAATATAGATAATTATATATTATATATCATT +ATATATAATTACATATATTATATTATATTGCTATATATATTCATATATATTATATTATAT +ATAATAATACCTATTATATTATACATAATATTATATATAATATAAGGATGCAGGATGTAA +AAGGAAATTATATATATGTTATATATATTATATATATTATGTCATATATAATTATATATA +TATATTTTTTTGGGTGCCCTATTTCCCATCTCATAACTTATTTTAAGAAGCCAGCATAAT +AATGTGTGGGCTTGGGATTCAGTTTTTGAAACAAAACACTGAGCCTTTGATGACCTTCCT +GTAGTTGTAAAAGCCCTCACCTGTCTGCATGGCAGCAGTTGGACCTCACAGTGTGGATTG +TGCCTTCACCCTGGAATGTTTATGCCCTATCGCCATGGTGATGGGATTAGGGATCTCCTG +CCCTTGGTCCTAAGTGCCACTATCTGTGCTGAGTTTTTCAAACGTCAGAGCAGATTGAAC +CATTGTGGTTTCATTTTCCCTGATTTTGATTTTTCTTATGGGGAACCTGTGTGGCTGCAT +TCAAGGTATGTTCTTACTGGCCTGTCAAATGCGATCTTTTCAAATTACTAGTTAATACTT +TCAAAATATATTATTTAAAAAATTAGCCTCTGTATTTTCCATATGCAGTTATAAATATGT +TTCATGATTATGTTTTATTCCTCAATTTATATATTTGATTATTGTACCAAGCAGAGTATC +TTTGAAATTTTTCTTCATTTAAAAAATATGTGTCTTGACTCAGGCCTGTAATCCCAGCAC +TTTGGGAGCCCAAGGCAAGAGGATCACAAGGTGAGGAGATCAAGACCATCCTGGCCAATA +CAGTGAAACCCTGTCTCTACTACAAATAGAAAAAATTAGCCAGGCATGGTGGCAGCTGGT +GTAGTCCCAGTGTGAATTGGGATTCAGTTTATTCCCAAATTCCCAAATTTTATATATATA +TATATATAAAATATATTAAATATATTATATATATACTATATATTATATTATATATAATTA +TATATATATATATTTTTGGGTGCCCTATTTCCCATCTCATAACTTATTTTAAGAAGCCAG +CATAATAATGTGTGGGCTTGGGATTCAGTTTTTGAAACAAAACACTGAGCCTTTGATGAC +CTTCCTGTAGTTGTAAAAGCCCACCTGTCTGCATGGCAGCAGTTGGACCTCACAGTGTGG +ATTGTGCCTTCACCCTGGAATGTTTATGCCCTATCACCATGGTGATGGGATTAGGGATCT +CCTGCCCTTGGTCCTACGTGCCACTATCTGTGCTGAGTTTTTCAAAGGTCAGAGCAGATT +GAACCATTGTGGTTTCATTTTCCCTGATTTTGATTTTTCTTATGGGGAACCTGTGTGGCT +GCATTCAAGGTATGTTCATACTGGCCTGTCAAATGCGATCTTTTCAAATTACTAGTTAAT +GCTTTCAAAATATGTTATTTAAAAAATTAGCCTCTGTATTTTCCATATGCAGTTATAAAT +ATGTTTCATGATTATGTTTTATTCCTCAATTTATATATTTGATTACTGTACCAAGCAGAG +TATCTTTGAAATTTTTCTTCATTTAAAAAATATGTATCTTGACTCAGGCCTGTAATCCCA +GCACTTTGGGAGGCCAAGGCAAGAGGATCACAAGGTGAGGAGATCAAGACCATCCTGGCG +AATACAGTGAAACCCTGTCTCTACTACAAATACAATCAATTAGCCAGGCATGGTGGCAGC +TGGTGTAGTCCCAGTGTGAATTGGGAGTCCGTTTATTCCCAAATTCCCAAATTTTATATA +TATATATATATAATATATATAATATATAATATATTATATATATTTTATATAATATATAAT +ATATATAACATATATATTATATATAATATATACATTATATGTAATATATTATATATATTT +TATATTATATATAAAATATATATACTATATATAATATATATAGTATATATAATATATATT +ATATATAATATATATAGTATATATAATATATATTATATATAATATATATAGTATATATAA +TATATATTATATATAATATGTATAATATTATATATTATATATATTATATATATTATATAT +TATATATTATGTATATAATATATATTATTTATATATTATATATAATATATAATATATAAT +ATATAATATATAATTATATATTATATATATTATATATTATATAATATATAATAAATAATA +TATATTATATATATAATATATATGATATATAATTATATATTATATATTATATAATATATA +ATATATAATAAATAATTATATATCATATATATAATATATATAATATATATAAATAATATA +TATTATATACATAATATAATTATCATATATTATATATATGTCATATATAATATATGTCAT +AATATAATATATGTCATAATATATATAATATAATATATGTCATAATATATATATAATTTC +CTTTTACATCCTGCATCCTTCAACCTGCATCCTTCAACGTTCCATCCCCCACCCCACAGA +TTAAGTTATTCCCCTGGGGAGAATATGGCGAAGTCTATTTTAATGCTGTTTTTAACCCAA +TTAAGAACCTATGAAATCATTACTTTCCAAAACTTTGGAACAAAGCCACAGTAGTAAGGA +TCCGTTGGAGGCTTTTCACACAATAAAATGTAACTCTCTTTGTTTTTAACATGTTTTTCC +CTTCCTCTCTTCTTTTTTTGTGAAATGTGTATTTACTTTAATATATTTGTAGTAAGTCAC +TTCCATGCACATATTAATTTTTTAAAGTAATAAGCATGTGTATTGTCTACGTGTGAAAGA +AAACACACATTTATTTTTATGCTTTGGAAGTTATCCAGAATCATGGAATTGTCAATCACA +GTCAATCACCCAACCTACTCACCTTTCCAGTGTAATCTTAGTCAAATTTTTTTTTTTGTT +ATCCAATGAGATGCAGTATTTCAACTCAGAAAGATAAATAGAGTGAATTTATAGAGACTA +TTAACTAAGAACATACAGTTTGATTTATACTCAGAAGCAAGTAGATTATGTACATATATA +TGAAGATAAAAATTAAAAGGATAATTGTGTAAATTTGCATGTAGAGGGCTTTGAAAACCT +GTTTACTTGTGAATGCTGTTTTGATGTATTGTGTCTTTGTTCTCCCGACCCATCATCCAG +AGCTCTCTGCAGGAGCTAAGTGCTCATCAGTTCCATGACTTGGAAACTGTCTAAGTTTAG +AGGCACTTGTATTTGTTAGTAAATAAGGCAAGATGATATTGTTTCACAGGTTTTAGTGCC +GAAGACTGAATAGATAAGCTGCTCCACCCAGTACACTGGTGTTCATTTCATGGTCATCTC +ATCTGTTAACCATGGATATAAAACATTTATCTTCAATGATGGGGTTTTACCATGTTGGTC +AGGCTGGTCTCGAACTCCTGACCTCAAATGATCCACCCACCTCCACCTTCCAAACTGCTG +GGATTACAGGTGTGAGCCACTATGCCTGACTGATTATTTTCATAACCAAGAAAAGAAATA +AATACAATTAATGCTGGTGCATGGTATTAAATCTAGTTTTTAAAAAATTCACACATAAAC +AGGGCAGAACCCTATACCCTCCATGATAAATGCAGTAGCAGTGTATGTGGGTCTGTGGAG +GTTGAAAGGGACTTGGTCGATGTCAAGAAGGTAGTGGCAGTCCTGCTGGGCTTTTAAAGG +GTCTGAAGAAGTGACAGGATGCTGTGGTTGAATCGTAGCATGTGTTTTAGCATTTGTTCA +TTTGGAGTTGATTATTTCACGTTGCTTTCATTTGCCATTACCTGGAAAGCCAAGGGCTCT +ACTCTCATTTCCTTGCTGCTCTTTCTTTGCCTTCCTTGGTCCGTGAAGAAGATGGTCCAG +GAGAAGCTCATTCCATGCTTGTTAACCAGGCACGCCCCTAAGTTCCAGTCCCTGAGTCAT +TCATGAGTAGCACTGCCAATGAACTGACAGCCATGCTGTGTCCCTCCACATCCCCTAGGT +GACTCGAAGAAGCCTTCCAAAAAGCGTGTGAAAAGGAAGCCCTACTCTACCACCAAGGTA +AAGTAGCCTGTCTTTGCCTAAGATGTAAATGTTGTTTTCTTGGATCCTTTATTTTTCAGT +TGATATCAGCTATGGGAAAATTCTCCACTACATTATAGGTGTTAGATAATATTTCCTTGG +GGATGGAGGAGGTGTATTTTACCAACTGACACCTGATTCCAGAGGACGTGCAAAATTGGC +AGTGTCAGATAGTACACTGGGTGTTAAGGGATGTTTTCTTCAGGAACAAGCTTTCCACTT +TAGATAAGAATTCTGCAATTGCTACTCAAAAATTACCTAGACAGAAACATTCTTCAACAA +AAGCTCCTGTGCTTTCCTAAGGCAACTCTACTCTAGAGTTGGGGCTTTTGACTTGAACCT +TATTTCCAGTCTTGGTTACCCAGAGTTTCCAAGTGAACAAAAGACCTGTGTGAGCCATCC +ATAGCATAGCCTGATTCTCAGAGTGTTTTCCTTCTCTAATTACAGGTGACTTCAGGGAGC +ACATTCAATGGTACGTATTCTGGAATCACTCACTGGTTGTTAGAAAAGGATTCTACAGGA +AATCTGGAGCTTAACTGCTGGCTTTTGTCTGGAGAGCCTCCATGATCCAAGACATCTGGT +GGGAATGAGGATGTAGGGTATAGTAAAAGAAACTGGTTTTCCTGGTGACATACTCTTTTT +ATCTATGTATAGTTTCTGGGAACATGTTCACATTAGGTTGTGTGTGGGTATGTGTGTATT +AGGGCGGGGGTGGGGTGAGGTGGTCTGTGTGCAAGTCTGCATGATTTGCTTGTGAATGTG +TGTCTATGTGTGTTTCCCCTAGGAAAAAAATGTTGTGTTTACCCAGCACAACTCTCAGTG +CCATGTTTCTTAATTTAACAAATCAGACCACATACTTTACTTACATTAGTTCACACCTCA +TCATCATCATGCCCATATGTTGTGAGCTTGTTTATTGAGCCCACATGCCAGATGGAGAAA +CTAAGCCACATAAATAAATGTGCCCTGGTTCACTTGCTGCATAGTGAAGAGTCAAAATGT +TTCCTCATACGGTGCTAATGTTGAAGGCCTGAACTACAACCACTATTTATCAGCCAGTGA +AGAGATCACTATTCACCATGCAAGGGAGTTCCAGCACCCTCTATGCCTGGAATTACCCAC +GCCTGCAGAGATCCCAAACGCCATCCCTCACATAAGACAGCCTCATGATCTCATAATCCA +GGTAGCTATGTAGACATCTTCCTGCAGGTGTCACATAGTCCTTAGTGTGAAACCAACATA +GAAAGCCCATGTTTCTGATCAAATCACAGGTTCTGAAACACTAAGGGAGGCACTAAGTAG +GACAATGTGGTGCCTGCGTGTCATAGCTGGGTCTCCTCAAGACATGGATCAAGTCCAGTA +AGAATTGGGGAGATGCTTTAGAGTCTTGATGGAGTTATCACCACAAGCCCTCTGAGCTAC +ACACTTTAGGGATCATGACCATTAAGTACTCAAATTACCATTTGGTTGTTATCCGGGTAT +CCGTCGTCCTTGTGGCAACCCTCTTGTGAAGCTGGTGTGGACAGCCTCAGTGCTGGAGCT +GTGCCTGCCTTCTGAGTGGACCCTTTCTGTGTTAGCAGGTGGGTACAAGCGTGGGGGTCA +GCACACTCAGTGGATTTACACACACAGCGTTGAAGAGTAAGGCTGGGCTTCATTATTTAT +ACATTTTCAATAAATGATGATCTTCATAACATAAAATCAATGATGTAGTACACTAGAATA +CTGTCCCTAGTATTGAATCTTGTCTCTCAGCAAAGGGTTGCTTAAAGTCACGTGACAGAT +TCCATTCAACTGATGACACATGCTGTAGCAGCAGTTAAAGCAGTCATTTGAAAAGGCTTT +TACTATAAACTTACGTGTGAGCCTGAAGTGGGGGATAAAAGAGGCGATTAGCTCCCCTGT +GCCATGTTTCTCTTATGTGCGTGGTGGAGGAAAATTACACAGGAAGGTGATGGAGAGAAC +AGAGCAAAGGATTGGACAGGTCCATTGAACCCATAAGACTATGGTGAGGTTAGTGAATGA +GACTGGTCATTTTAGGTCAAATTTTACCCAGAGCTGGTGCAGCCACTGCCCATTCTTAGC +CAGACCTTATTGCAGGCAGCTCTGATCAATAGTCAAGGAGGCAGTGGGGGTTGCAGACTT +AATTCATTAAATCACCAAAGCACCAGCCCACACGGCCACTTTTCCAGTTAATTCACAGTA +GCTTGCATATTCAGGTTTGATCAGTGGAAGGGAAGTTACTCTTTGCAGACCCATCTTTTG +ACAATCATTTTGCAGTGTCGGAAGGTCTGAGCAGCCTCGGGAGGCAAGCAGTCCCTGGTC +CCTCAGTGTAGTCACTGGAGGAGACAGTCACTGAGAGGCAGCTGGCAGGGTGAAGGGAAA +GGGGAGGCAGGCCACAGAGATGACAGCCTTTAAGCTGTCATACTGGGAGGTCAAGGATCT +GAAAGAGGAAGGAGAATTCTTTATCATTAAGGACCTGTCCTTATCTCAGGCATTTCCTCC +AGAGCATCACCTTTGTCCACCCACACACCTTGGGCTAGGAGGACTGGAGAAAAACAGTGA +GGGGTCTCTTGGGTCTCTGGCACAGGGCGTGATGAAGAGGTGGCAGTTTTTCAGGAATCT +CTCTCTCTAGGGAACCAAATACATTTCCCATCTCAGGTCCTTCACTCAGCGGGGTTGAGG +TTCTGCTCGTCACTTATCATCTCTGAATGTCAGCACCCTCAAGTGTAAAATCTCAGTCAC +AGCCCCTCCTCTGCACCCCCTGCAGGGCTGATGTTCTCCATAAACCATAAGGCATCATGC +CCACGGAAAAGCCGAACAGGAAAGCATGCTCCACTGCCCCGGAGCCATCCAAGTTCCCCC +TCCATATTCCGCCACTGCTGAGTGTCCAGCTTATTCCTCCTGGCCTGTAGTAAACACTTA +GAGAACATTACTGAAGTACCAGTCCTCTCTAAGGTTTTCCTGTATTTAGTGATTTTTTAG +CCCTGTACTGTGATACTAAGAAGTAGGGCCTAAATAGGGCCTAAAAAGTATTGCTAAAAT +TACATTATGACAGTGCAGAGAACTGAGGGCAGAGGGAGGACATGAGCTTGCCAGGTCCAC +ATGGCTTAGTGGAATTTGAATCCGGGCCCCTACTCTGCACCAGCCCTGCACTCACAGTCA +TCCTGCTGTATTCTCCTCTCCAGGAAGGCACTGCCCACGCAGTCTGTCTGATAGAGGTGT +TGAGTGCTCACTGAACTCCGTGATCTTCCTGAAACCCAACTTTGATTCAGTGGGCTCTGC +TTGGAAGCCTGTAAAGAAAAGGATCATAAGTTTAAACTTAGAACAGATTATCACTATTTT +CCCTCTGGTCCTCTGTCAGCAAGATGTCAACAGCCCTATCTATTGTAAATGCATTAACCA +GCATCTTCTCTGATAGAGAATATAAGAAGATATGCTGTGCACACCAACCAGTGTAGGAGA +CCTCATGGCTCCCGGGTAAAGAAGAAGAGGTACCCACAAGAAGGTACTGTGGAAGTTCAT +TAATTAAGTTGATTCAAGAATTGCAGTTGCGGGGAGTATTCAGTGTCCCATATGTAAGAG +GAAACTATGAAGAGACTAAGCCATATTTTTTAATGTGTCAGGATTCTAATTTGCCTGGTC +AGTAAATATTGCTACCACCACAAAAGTAAATATCTACTTAAAAGTCAATTTTGGTTCATG +TTTAATGATAGACAATGTTTCAAGCTAATGTCTAGAACTTACCTGGTTGTTAAACATAAG +CATAGATCTCCCTGAAAGAGTGGTGCTATATTATTATTTTTCAATTAATATATTTCTTTA +GAGAGTTTTAAATTGACATAAAAACTGAGCATATGGCCGTGTGTGGTGGCTCACACTTAT +AATCCCAGCACTTTAGGAGGCCAAGGCAGGCGGATCATCTGAGGTCAGGAGTTGGAGACC +AGCCTGGCCAACATGGTGAAACCCCATCTCTACTAAAAATCCAAAAAAATTAGCCGGGTG +TGGTGGCAGGCGCCTGTAATCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATCGCTTGAA +CCCGGGAGGCAGAGGTTGCAGTGAGCCAAGATCATGCCATTGCACTCCAGCCTGGGTGAC +AAGAGTGAAACTCCATCTCAAAATAAATAAATAAATAAATAAATAAATAAATAAATAAAT +AAAAATTGAGTATATAATACACGAAGTTCCCATATTATTCTGTCTCCTCACCCTCACTTC +CTAATTTCACCTATTAGTAACATCTTACATTACTGTGGTACATTTGCTAGAATAATGAGA +AAATATTGACACATTATTATCTGAAGTCTGCATTTGCATAATGTTCATTCTTTCTGTTAT +ACATATATATGAATTTTGAAATATTTAAAACATTATGTTCACCCTTATGGTCTCATAAAG +AAAATGTTCACTTCCCTAAAAATCCTCTCTTCTCATTAATCTCTGTCCTCTTTCTCCAGA +AACCTTGGCAACTATTAATATTTTTACTATCGCTTCAGCTTTGCCTTTTCCAGAATGTCA +TATAGTTGGAATCATATATTATGTAGTTTTTTCAGATGAATTTATTGCACTAAATTGATG +TACGCTTTAGCTGCTTTCATGTCTTTTTTATGCCTTAATGGCAAAAAATGGCACATTAAA +TCACCAAATAATATTGCATTAAATGAATTTTTGTCTTTTTATTCACCTGTTGAAGAATTC +GGTAGATTTCATGAGAGAAACCATCTGGGCCTGGTGCTTTCTTTTTCGGAATGCTCTTAA +TGTGAATTCAACTTATTTAATAGACATAAGTTTATTCAAATTAGGATCCTAGCATGACCT +TGGGAAGATTGCCTTTCAAGGAATTGATACATTTCACTGAGGTTATCAAACTGCGCTCAT +AGAACTGTTCATGATATTCCTTTTAATGCCTAACAGTTCAGTAGAGATGGCTCCTCTTTT +ATTTCTGAAATTGGTCATTTGTGTTATCTTCTTTTTCTTGGTTAGCCTGCATATCAATTC +ATTCATTGTAATGAGCATATCAAAGAACCAGCTTTTGGTTTTATTGATTTTCTGATGATT +TCAGTGTTTTAATTTTATTGATTTCTGTGATGTTGTTTATTACTTTTACTTGCTTTCCAT +TGCATTCCTCTATTTTCTATAGTTCCCTAATTGAAACATGATATTACTGATTTTAGGTCT +TGTGATTTTTAGTATATTGCATCCAATGCTATAGATTTCCCTCTAAGGACTGCTTTTGCT +ACATCCAGAAATCTTGCCAAGTCACATTTTCTTTTAATGTAGTTAAAAGTACTTTTAATT +TTCTATTGAGACTTCTTCTTTAACCCAACAGTTATTTAAAAGTGCATTGCTAATTTGCAA +ATATTTGGGGATTTTGTGGCTCTTTTACAGTTGTTGATTTTTTGTTGTCAGGTGTGTGTT +GCAAAAGCAGTCGTCTACCTCATCTTGCCACCACCCAAGATGGCCCAGGATGTGGGCTCT +CCCTGAGTGAATCTTTGGCAATCTGCCAACCTGATGTGTTCGGCCTCCTTCTTTAGTCTG +AGCTTGCCTTCTGCTTAGAAAGGGCCATTCTCAGTTCTGGCAGGGAGTTTTCCCAACATT +GAGAAGGTGGCATTCTTACTCCCCACTGCAGCCTGCACCTCTGACCGGTGGTCAGCAGAC +AGGACAGAGGTCCTCATTAGACAGAGTTCAGCAGGGTCTCTGACCAAAGTGCATCTTCAG +AGTCTGCACCTACCCACTGTGACCACGGGCAGGCTCTGAGTCCTAAAGCAGGAGGAACTG +TGCGACCATCCTGATTGGAAATTTGTGAGGATCACCGTGTTACTCAAGTAAGGTCTTTGG +AAAGTGTCGTATTACTACTGTTTGTGAACTGCTTGTTGGTGGCCTGGCTGAGCCACACAC +TTTATGAAAACCAGGACCCCTCAGCTGGTGTGGGTGTCTATGCAGCCTGAGACCCTCATG +TGAACAGCCTCGTGGCAGCTGTCTTTGCCCCTTGCCACCATCAGTGCCTCCTTGTTCCTG +GGCACTGCTTTCTCTGATGGTGCTCCATTGTTTTCCTGCACCTCAGTGTCTACAGCTGGA +TGTCTCTTCCGCAATCTAGGCGAGGGGGCATCAATGGCAGTTCTGCTGTGGCACTGCCCT +CCTTCTTAGCTTGTCTTGCTCTGTCTTAGGCTCCCTCAAAGATCCCACCCTTCAGGTTCT +TCCACAAGTTTCTTATTGAAATCCGAGCAGAAAACTATGACCAATATGACCAATCCTATA +CCCACTGAAGACATGAATGAAGAATTAAAACAATTCTCCATGGACTCTACCATATAGATC +CCTAGAAGTAATTTCTAAAAAAAAAAAAAAATCAAGGAAGATGTAATAGTTTTCCATAAA +TTAGAATACCCTACATGTACAATTAAATGAAATGGCTAGTATAGTCTTGAAACCAAAACC +AGATAAGGTAAATTAAATTCTGTGATATTTTAAAATACTGTAAATTCTGACTAATGTGAG +TTAATCTCAATATATGAAATAGTAGATTAACATTGAAAATGCAATAAATAAAATTAGCTA +CCTCAAGAGTTTAATGGAAAAAAATGTGATTATTGCAATAGATTCAGGAAATTCATGAAT +AACATTCACCCTATATTTGTAGGACAACTATCTAACTTTAAGTGACCTGTGACAACCATT +TGAATTAATGCTGCTTTCACAGCATATCTCTTGGCTTGTTAAAAACCCGACAAGAATTTC +CGTAACATTAATTTATTTTTAACACCTATATTGGGTGTGAACCCACCATAAAGTTTGCCC +ACTGAAAAGGTCTACAATTTGATGCTTTATTAAATTGATACTGTGTGCACCCATCACCAC +GATCTAATTTAAATATGTTTCCCTCACCCAAGTTCTCTCTTGCGCACTGGCAGTTAATCC +CCACTCCCATCTCCAGCCCTAAGCAATACTGCTGTGACATTCCATCTCCATAAATTTCCC +ATTTGCTTAATAGAAATGGACATATATATATATTTGGAATCTGACTTCCTTCATTTAGCA +TACTATGTTTGAAGTTAATTGACGTGTTAGCACGTGCTGGTCATGTGTTTTCCTTCATAG +TCTGCTGTGTTTACTCATACAGATAGTGTTTATTCATTTATCAGTTAATGGACATTTAAT +TGTTTTGTTATTTTCTTTGATGAGTAATGTAGCTTTGAGCATTCATATACAGTCATGTAA +TGCATAATGACATTTTGGTCAAAAAAATTTTTTTTTTTCTGAGACCCAGGCTGGAGTGCA +GTGGCACAATCTCGGCTCACTGGAACCTCCACCTCCCAGGTTTAAGCAATTCTCGTGCCT +CAACCTCCCGAGTAGCTGGGACAACTGGCACACGCCACCATGCCTGGATAATTTTTGTAT +TTTCAGGAGAGACAGGATTTTGCTGTGTTGGTCAGGCTAGTCTCAAACTCCTAGCCTCAG +GTGATCCACCCATCTCTGCCTCCCAAAGTGCTGGGATTATAGGCATGAGCCACCACACCC +AGCCTAATTTTTTTAAGAAAGAAGGGAACTATTTTCTAAATTACTTTTGCCAATTTATAT +TTCTACCATGATGCATAGCACTAATTTCACCGTACAATGTATGGTAGGCCCCAATATGTA +AGAAATGATGAAAGTAACACATAAAGATTGGTATAAAACAAATAAGATTATCATTGTTGC +TATCATCTTTGTCAAATTCTGAAAACAATCTGAGTATATTTTTATATAAATATGCTTGGC +AACATAGCTGAAAAACGCATTATCAGTTACATTTATCAGTAACAAAGACATAAATTTGAA +GGGGGAAAAACACTTGTACTAACAACGCAATGTCAGAATTAACATAAAAATTCTGCTGGT +CACTTTGGAATATTTAATTGCCTGGGGCAGTGTTTAGTAGACAAATGAGCATCTATGGAG +CACCCAAAGTAGGGGAATCAACAGAACTTGGGTTTCAAAAGTTATCTGGGTTTAGAGCGT +GAAACTTTGTTAGAGGACACACACCTTGCATGAGCGAGGTGCCTTGGTGTGTGTGGACGT +ACCATTATGCTTGGAGGTACAGCATAATGGTGGCTTCCTCCAGAAAGGGACATTTGGGGT +GGATTCATTCCATCTAGACAACACAGCCTGATGTGGCATGGACATGAATGGAGGTGAAAT +GGTCAGTAGTTGAGAGGATCAGTCCTGACAAGGGCCGAGGTGAAAAACCTGGGAACCCCT +TCAGGTGCAAAGTCTTCAGTTGAAAAAGGAGGTGGTCACAGGAAATACTGAGACAGGACA +GCAAAGCATGGGAGACAGAGTTCTTGGCCCTGCAGGGTGAGTACTGTGGATTCTCAAATT +TTCTCCTCTCTCCATTAATTTCTTTCCCAATGCAGATGACTTCCATCATACAGTCTTCAG +CAATCTTGAAAGATTGGACAAGCTTCAGCCCACTCTTGAAGGTAAAGGAAGGCAGCTAAC +AAGACTGGCATCTGGGCTTGGCTGTGCGTGTTTTCTATCGTGGGGAAATATATATAACAC +AATATTTATCATTTGAACCTTTTAACCAAAGTGTGCACTCCATGGCATTCAATATATTCA +CAGGGTTGCATAACCAGCACCACTATCTACACCCACAATTTTGATGATTTCTTACGAAAC +CTTGTCCACAATAAGCAATATAGCACCTTCCCCCTATTTCCAGCCCATGGTGATTCCTAT +CCCACTTTCTCTTGTATGAATTTGACTATTCTAGGCACTTCATGTAATTACAATTATACA +ATATATTCCTTTTGTGTCTGGCTTATTTCACTAAGCATAATGTTCTCAATGTCCACCCAT +GTTGTAGCATCTATCAAAATGATGTTCGTTTTTTACAGATGGATGATGTAGCATTGCATG +CAGACCACTTTGCTTTTATTACATTCATTTGTTCACTGATGGTTGGATTATTTCCACCTT +TTGGCTCCTGTGAAAAGTGATGCTACAAACATTAGTATACAAACATCTGTTTGATTTCCG +TTCTCTATTCTTTGGGGTGCCTAAGAGTAGAGTTCCTGGGTCCAACAGGGGTTCTATATT +TAACCTTCTGAGCCACTGCAGACTGTTTTTCACAGTGGCTGCAACTTTATCCATTTCTAC +CATCAATGTATCAGGGTTACAATTTCTTTACGTCCTTCTTCACACTTATTTTCCTTTAAA +TCATCCTAGTAGGTGTATATTGGTGGCTGCTTGTGTTTTTCATTTGCATTTCCCTAATGA +CTAATGATCCTGAGCAGCTTTTCCTGTGCTACTATCTGTGGCTGTATCTTCTTTAGGGAA +ATATATGTTGAAGTCTTTTGCCCATTTTTAAAGAGTTGTCTGATTTTTATTTAGTTAGTT +TGTTGTTGTAGATTTTTGAATATATCTTAAATATATTTAAAATATATTCTAAATTTTAGT +CTCTTACAAGATAAATGATTTGCAAATATTTCCACCTTTGTGTAGAACTTTAGATTCACA +AACTTCATTAATTTGTATGAAATCCTCGGCAGTTGACCCCAAACAGATAAGACTGAAGCA +GTATTTTAGGAATAGTTGAAAGTATGATCACCACAAAACATAAGCGTAATCAAATCCTGC +AAGCTACATGTAAGGCACAATGACAAATAAGGCAGCAAAGGGCCATCTGGTGTTTAGTTC +ACCACACTTGTTGCAACTGTTTGCGCTGCAGAGTTAAAACACACCAGCATTCAACCCATG +TCTCCTCTCTTGAAGTAAACTGTCGTATGTTGGCTGGCCTGAACAAGCGTAGATATTCTC +CATCCTCAATTAATATGCATGCATGACAAAGAAAAGGAGGCCTGGATGAAAAAATATTGT +GTGATTAATAATTATGCTTTAATTAATTTTAAAAGATATAATTTCAGTACTTCTAATTCT +CCCATCAGCAGTTATAACAAAGGATTAGTGAATAAATACCATAGACTGTTTTGCCTAGAA +TCGAATCCAATCTGTCTATTAAACTTTGCTTTTATTCAAGTGCAAAATGCTAAAACACAT +AATAACTGCAGTGACAGCCACTGTGGATCCTCAGAGGTAAAAGTAGTCTTGGGACATAAA +TCCTGCAAGCTAATATCGTTTTTACAGGGTTTAGAAAACCATTTAGCTGGGTTTCAAACC +TCACAGTGTGAGCAGTGGGACTCTCATCAAACTATAGCATGTGCTTCAGTACCATTTGTA +GACTGACTCATTCCCATTGCCTTAAGTTGCCATCAGCAAAATGCCAGGGACTCTATTTCT +TGCTCCTTAGCTCCTCGTTCTTGCCTGTCTTTCCACCAGGGAAGATTTTCTAGCAGGAGC +TCAAGCTGTGCTTTTAATGAAACACATCCACACACACTGTCCTGTTGTCCACATTGAGCA +GAGCTCCCTGAATAACTCATGAACAAAAGCATCTATGACTAACTGTTGCTCTGTGTCCTC +TTAGCCTCTGAGGAGTCTCTAGTTCACAAGGACAGAGGAGATGGAGAGAGGCCAGTCAAC +GTGAGGGTAAGGTTGCCTTGCTTTCTCTGAAATAGAAATGTTCCTTTCTTGGTGTCTTTC +TTTTTCAACTGACTTTACATGTGAAAAAATGACAATGTCCATGACAGGTATTAAATGCAG +TTTTCTGAGGGGGAGGAAGAAGTGACTCTTAGCAACTGATATGTAATCCAAAATGGCATT +TAGCTATGACGGCTTCAGGTTGTGGACTGTATCCTTGGGGTCCTTGTCCTTGGAAGCAAT +GTCTTCTCCTTGGATTCAGTATTTTGCACTTGCCAACCTACGTGGACCTGAGAGATACAC +CGTCCAGAAGCTGATGCCTTTTCCAGTGTGTATCCTACCCTTGTTTTGGAGGCCTTGAAG +TTGACTACACTTTCTGATCAAGTTTTCAATATTCATTGAGAGAAACACAGCCTTGTGCAA +ACAATCCACAACGTGACATACCCCTCAAAAAGCTTTGTTTCTGTATTGCAGGTGGTGCAG +GTGGCCCCTCTGAGGCATGAATCTAGTAAGTATTCTGGAATCACTTGCCAAGAAAACAAT +CTGGATGCCAAGAAAGGTGTGGCATCCTTGCCTGGTTTCAATGTGAAGAGCCACCCTGAT +CCTGGGATTGTGATAGGAATAAGTATAGGGGAAGTGTTTTTTTAAAACCTGAATTCCCCA +GGGAAAAATTATGGCCAAATTTTGAGGAAGCAGCTGTGCTCCCTTTTGGGTGGTGCTGAG +TTGGGTGCTTGAGGATTGGTGGTGTCTTGTGTGAGGCTGCATCGTGTGGTGTGAATGTGT +GTGTTTCTGTACAGGTGAGGCTGTGTGTTTTCTCAGGAGAGATTTCCCACTTATACAACC +CAATCACCAGTGTCCACTTCTAACAATAAAATCCACCCCCGCTCTACTCTCTCTGTACAG +TGACTCCTCCACCCTCACCAGAGCCATCCCCGGGTCTGCCTTATTATCCCCACTGCTCAG +GTGGAGAAACTGAAGGGCCAAGGGAGTGGCCCCAGCTCCCGAGTTCCTGAATGAAAAAGT +GAAAACACGAACCCAGGAGTGTGGGCCAGTGCTGACGCTGACATGGCACTTAGTCATGGG +GTGTTCACCACCACACAGGGAGTCCAACATTCATGTATAAGCCCTAAAGCACCGAGCCCA +AAAGGCCCCAGACACTGCCCATCATCATAAAGTGGGCTCCGTGGTCACACAACCCAAGGC +AGTTATAGGCTCATCTCCCCACAGACAGGCATAGTCATCAGTGTGTCAAAAGCACAAAGA +TCCCCAGGTGTTTGGCTCAGCTCACCAATCCTTTTTTTTTTTTTTTTTTAACTTTTAAGT +TCAGGGGTACATGGGCAGGATGTGCAGGTTTGCTACATATATAAATGTGTGTCATGAGAG +TTTGTTGTACAGATTATTGCATCACCCATATATTGAGCCTAATATCAGTTATTTTTCCTG +ATCCTCCCCCTCCTCCCACCTCCCACCCTCCAGTAGGCCCCACGCTCACAAATTCTAAGA +GGAGTGGGGGACCACAAAGGCCAGTGTGGCCCACTTCAGTTGTGAAGTTAATTTGCTCAG +CAACTGGCCAAAGTCTATAAGGATGGGTGATGTATTTTAGTAGATTTAGTAATACTATCT +TCCCAAGCCCTAAAATGCTCAAATCCTGCCAGCCAAAAATGGTGAGGAGGGACAGATAGG +AACTCTGTGTGGCACTTGGTTATTAGCCTGGCTTCCATCCCTTAGTGGCAACTCTCTTGT +ATATGTGGGTTAAAGACCCTCAGCCTCAAGCCAAGCCTCCTCCATGAGGAGCCATCTCAC +TATTGACCGGCTAGTGCCGGGTATGGCCACCAGCCCAACTGAAACAAAATGTTGCTTTAA +AACACGTGTAAATCTCATACATACAACAGGCAAATGCAGAAGCAGTGTGGTCTCGCAAGT +TGTAAAGAGGACAGTCGCAATTTTGCTGGACTTCAACCTGGGTAGAAGACATGAGGGAAC +TCTGTCACTGAATCACGGCAGAGTTCAAGGCCACTTGCAGACTATTTCATGTTATAGAAG +GTGGCCTTTAGCTACTAAGCAAAGGCCTCTGTTTCTCATTTCTTTCCTGTTCATCTTCTT +CGTCATCCTTCTTCCGCAAGGGAAACGAGCCCAAGCAAAAGACAGTTTCAATATTAATTT +GACCGAGGTTTTGTGCAGTTAATTATCATCCAGGTAATCAGGTGCAACCCAGTCTGCCTA +GCAGCCCCCCTATCTCTGCTCTGTGTTTTCATTTAATAAACATTTTGGTCTACTTACTAT +GTGCTAGATTTTCTCGAGACCAAGTAAATGAGATAGAATCTTTATGTTGGCAGCTAAGTT +AGATTTAACATAACTGACAAAAATTAAAATTTCTGATTTCTTGTAAAAATATTTTGTATG +TGTGAATGCATACTGAATGTAAAGTGGATAAAAAAAATCACACTTGCACTCATGGAAGGC +TTTTCATGAATTTGTCAATTTCTATTTTTTTATATTTCCCCATTTCACCGGATAATACAT +ACCTGAACCTGGAAAATGATTCCCACAGCAGAAAGTGTTCTGAGCCACATCCCTTAGCTT +CACTAGTGCAGGTCCACCTGGGAGTATGTCCCACCATCAGCTTGACCCATGCTGTAATCA +GCCACCTCCATGCATCACACCAAGCAAGCCCCTGGGTGATTCACAGTCTCCAGCACCAGG +GCACTGACCTTAACTCTGTGTTCTTCTAGCTCCCTATGAGGACACTGTACACGACATCGC +TAATGAGGACGCTGTATATGACATTGCTACTGAGGACGCCATATATGACATCGCTAACGA +GGACGCCGTCCAGGGCATCGCAAAGGAGGACGCCGCCCAGGGCATCGCTAACGAGGAAGC +CGTCCACGACATCGCTAACGAGGATGCCGCCCACGTAATCGCTAACGAGGACGCCGCCCA +GAGCATCGCTAACGAGGACGCGGTCCACGACATCGCTAACGAGGATGCCACCCAGGGCAT +CGTTAATGAGGACGCCGCCCACAATATCGCTAATGAGGACGCCGCCCACGGCGTCGCTAA +CGAGGTCGCCGCCCAGGGCGTCGCTAACGAGGACGCCGTCCACTGCATCGCTAACGAGGT +CGCCGCCCAGGGCGTCCTTAAAGAGGACGCCGCCCAGGACATCGCAAACGAGGACGCCGC +CCAGGGCATCGCTAACGAGGACGCCGCCCACGGCATCGCAAACGAGGACGCAGCCCAGGA +CATCGCAAACGAGGACGCCGCCCAGGACATCGCAAACGAGGACGCCGCCCAGGGCATCTC +TAAGGAGGACGCCGTCCAGGGCATCGCGAACGAGGATGCCGCCCAGGGCATCGCTAAGGA +GGACCCCGTCCAGGGCGTCGCTAACGAGGACCCCGTCCAGGGCGTCAATAACGAGGACGC +CGTCCAGGGCATCGCTAAGGAGGACCCCGTCCAGGGCGTCGCTAACGAGGACCCCGTCCA +GGGCGTCGCTAACGAGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCGTCCACGGCGT +CGCTAAAGAGGTCGCCGCCCACGGCGTCGCTAACGAGGATGCCGCCCACGCGATCGCTAA +GCCGGACGCCGCCCGCGGCATCGCTAACGAGGTTGCCGCCCAGGGCATCGCTACCGAGGA +CGTCGCCGACGGCATCGCTAACGAGGACGCCGCCCACGGCGTCGCTAACGAGGTCGCCGC +CCAGGGCGTCGCTAACGAGGACGCCGTCGAGGGCGTCGCTAACGAGGACGCCGCCCAGGG +CGTCGCTAAAGAGGTCACCGCCCACGGCGTCGCTAACGAGGACGCCGTCCAGGGTGTCGT +TAACGAGGACGCCCTCCACGGCGTCGTCGCTAACGAGGATGCCGCCCAAGCGATCGCTAA +GCCGGACGCCGCCCATGGCATCGCTAACGAGGTCACCGCGCAGGGCATCGCTAACGAGGT +CGCCATCCACAGCATCGCTATCGAGGACACCACACCGTCCAGGGCGTGGCTAACGAGGTC +GCTGCCCAGGGCATCGCTACCGAGGATGTCGCCGACGGCATCGCTGAGGACGCCGCCCAT +GGCATCACTAACAAGGAGGCCGCCCAGGCCATCGCTAAGCAGGATGCCGCCCACGGCATC +ACTAACGAGGACGCCGTCCAGGGCGTCGCTAACGAGGTCGCCGCCCAGGGCGTCGCTAAC +GAGGACGCCGCCCACGGCGTCGCTAACGAGGTCGCCGCCCACGGCGTCGCTAACGAGGAC +GCCGCCCAGGGCGTCGCTAACGAGGTCGCCGCCCAGGGCGTCGCTAACGAGGACGCCGCC +CAGGGCGTCGCTAACGAGGACGCCGTCCAGGGCGTCGCTAACGAGGTCGAAGTCCAGGGC +ATCGCACACAAGGACGCCATCCAGGGCATCGCTAACGAGGATGCCGCCCACGGCATCGCT +AACGAGGTCGCCGCCCACGGCATCGCAAACGAGGACGCTGCCCAGGGCATCGCGAACGAG +GACGCCGCCCAGGGCATCGCTAACGAGGTCGCCGCCCACGGCATCTCTAAGGAGGACACC +GTCCAGGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCTAAAGAGAACCCCGTCCAG +GGCGTCGCTAACGAGGACCCTGTCCAGGGCGTCGCTAACGAGGTTGAAGTCCAGGGCGTC +GCACACGAGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCGCCCACGGCATCGCGAAC +GAGGTCGCTGCCCAGGGCATCGCGAACGAGGACGCCGCCCAGGACATCGCAAAGGAGGAT +GCCGCCCAGGACATCGCAAACGAGGACGCCGCCCAGGGCATCTCTAAGGAGGACGCCGTC +CAGGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCTAAGGAGGACCCCGTCCAGGGC +GTCGCTAACGAGGACGCCGTCCAGGGCGTCGCTAACGAGGTTGAAGTCCAGGGCGTCGCA +CACGAGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCGCCCACGGCATCACTAACGAG +GTCGCCGCCCACGGCATCGCGAACGAGGACGCCGCCCAGGGCATAGCACATGAGGATGCC +GTCCAGGGCATCGCTAACGAGGACGCCGTCCACGGCGTCGCTAAAGAGGTCGCCGCCCAC +GGCGTCGCTAACGAGGATGCCGCCCACGCGATCGCTAAGCCGGATGCCGCCCACGGCATC +GCTAACGAGGTCGCCACCCAGGGCATCGCTACCGAGGATGTCGCCGACGGCATCGCTAAT +GAGGACGCCGCCCACGGCGTCGCTAAAGAGGTCACCGCCCACGGCGTCGCTAACGAGGAC +GCCGTCCAGGGCGTCGTTAACGAGGACGCCCTCCACGGCGTCGTCGCTAACGAGGATGCC +GCCCAAGCGATCGCTAAGCCGGACGCCGCCCATGGCATCGCTAACGAGGTCGCCGCCCAC +GGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCTAACGAGGTCGCCGCCCACGGCATC +TCTAAGGAGGACGCTGTCCAGGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCGAAC +GAGGACGCCGCCCAGGGCATCGCACACGAGGACGCCGTCCAGGGCATCGCTAACGAGGAC +GCCGTCCACGGCGTCGCTAAAGAGGTCGCCGCCCACGGCGTCGCTAACAAGGATGCCGCC +CACGCGATCGCTAAGCCGGACGCCGCCCGCGGCATCGCTAACGAGGTTGCCGCCCAGGGC +ATCGCTACCGAGGATGTCGCCGACGGCATCGCTAACAAGGACGCCGTCCACGGCGTCGCT +AACGAGGTCGCCGCCCACGGCGTCGCTAACGAGGATGCCGCCCACGCGATCGCTAAGCCG +GATGCCGCCCACGGCATCGCTAACGAGGTCGCCACCCAGGGCATCGCTACCGAGGATGTC +GCCGACGGCATCGCTAACGAGGACGCCGCCCACGGCGTCGCTAACGAGGTCGCCGCCCAC +GGCGTCGCTATCGAGGACGCCGTCCAGGGCGTCGCTAACGAGGACGCCGTCCACGGCGTC +GCTAACGAGGACGCCGCCCAGGGCGTCGCTAAAGAGGTCACCGCCCACGGCGTCGCTAAC +GAGGACGCCGTCCAGGGCGTCGTTAATGAGGACGCCCTCCACAGCGTCTTCGCTAACGAG +GATGCCGCCCAAGCGATCGCTAAGCCGGACGCCGCCCATGGCATCGCTAACGAGGTCGCC +GCCCACGGCATCGGGAACGAGGACGCTGCCCAGGGCATCGCGAACGAGGACGCCGCCCAG +GGCATCGCTAACGAGGTCGCCGCCCACGGCATCTCTAAGGAGGACGCCGTCCAGGGCATC +GCGAACGAGGACGCCGCCCAGGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCACAC +GAGGACGCCGTCCAGGGCATTGCTAACGAGGACGCCGTCCACGGCGTCGCTAAAGAGGTC +GCCGCCCACGGCGTCGCTAACGAGGACCCTGTCCAGGGCGTCGCTAACGAGGACGTCGTC +CAGGGCGTCGCTAACGAGGTTGAAGTCCAGGGCATCGCACACGAGGACGCCGTCCAGGGC +ATCGCTAACGAGGACGCCGCCCACGGCATCGCTAACGAGGTCGCCGCCCACGGCGTCGCG +AACGAGGACGCCGCCCAGGGCGTCGCTAACGAGGACGCCGCCCAGGGCGTCGCTAACGAG +GACGCCGTCCACGGCGTCGCTAACGAGGACGCCGCCCAGGGCGTCGCTAAAGAGGTCACC +GCCCACGGCGTCACTAACGAGGACGCCGTCCAGGGCGTCGTTAACCAGGAGGCCCTCCAT +GGCGTCGTCGCTAACGAGGATGCCGCCCAAGCGATCGCTAAGCCGGACAGCGCCCATGGC +ATCGCTAACGAGGTCGCCGCCCAGGGCATCGCTAACGAGGTCGCCGTCCACAGCATCGCT +ATCGAGGACACCACACCGTCCAGGGCGTGGCTAACGAGGTCGCTGCCCAGGGCATCGCTA +CCGAGGATGTCGCCGACGGCATCGCTGAGGACGCCGCCCATGGCATCACTAACGAGGAGG +CCGCCCAGGCCATCGCTAAGCAGGATGCCGCCCACAGCATCACTAACGAGGATGCCGTCC +AGGGCGTCGCTAACGAGGACGCCGCCCACGGCGTCGCTAACGAGGACGCCGCCCAGGGCA +TCGCTAACGAGGTCGCCACCCATGGCATCTCTAAGGAGGACGCCGTCCAGGGCATCGCGA +ACGAGGACGCCGCCCAGGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCACACGAGG +ACGCCGTCCAGGGCATTGCTAACGAGGACGCCGTCCACGGCGTCGCTAAAGAGGTTGCCG +CCCACGGCGTCGCTAACGAGGACCCCGTCCAGGGCGTCGCTAACGAGGACGCCGTCCAGG +GCGTCGCTAACGAGGTTGAAGTCCAGGGTGTCGCACACGAGGACGCCGTCCAGGGCATCG +CTAACGAGGACGCCGCCCACGGCATCGCTAACGAGGTCGCTGCCCATGGCATCGCGAACG +AGGATGCCGCCCAGGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCACACGAGGACG +CCGTCCAGGGCATCGCTAACGAGGACGCCGTCCACGGCATCGCTAAAGAGGTCGCCGCCC +ACGGCGTCGCTAACGAGGATGCCGCCCACGCGATCGCTAAGCCGGACGCCGCCCGCGGCA +TCGCTAACGAGGTCGCCACCCAGGGCATCGCTACCCAGGATGTCGCCGACGGCATCGCTA +ACGAGGACGCCGCCCACGGCGTCGCTAACGAGGTCGCCGCCCACGGCATCGCTAACGAGG +TCGCCGTCCACTGCGTCGCTATCGAGGACGCCGCCCAGGGCGTCGCTAAAGAGGTCACCG +CCCACGGCGTCGCTAACGAGGACGCCGTCCAGGGCGTCGTTAACGAGTACGCCCTCCACA +GCGTCGTCGCTAACGAGGATGCCGCCCAAGCAATCGCTAAGCCGGACGCCGCCCATGGCA +TCGCTAACGAGGTCGCCGCCCACAGCATCGCGAACGAGGACGCTGCCCAGGGCATCGCGA +ACGAGGACGCCGCCCAGGGCATCGCTAACGAGGTCGCCGCCCACGGCATCTCTAAGGAGG +ACGCCGTCCAGGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCGAACGAGGACGCCG +CCCAGGGCATCGCACACGAGGACGCCGTCCAGGGCATTGCTAACGAGGACGCCGTCCACG +GCGTCGCTAAAGAGGTCGCCGCCCACGGCGTCGCTAACGAGGACCCCGTCCAGGGCGTCG +CTAACGAGGACGCCGTCCAGGGCGTCGCTAACGAGGTTGAAGTCCAGGGCGTCGCACACG +AGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCGCCCACGGCATCACTAACGAGGTCG +CCGCCCACGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCGAACGAGGACGCCGCCC +AGGGCATCGCACACGAGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCGTCCACAGCG +TCGCTAAAGAGGTCGCCGCCCATGGCGTCGCTAACGAGGATGCCGCCCACGCGATCGCTA +AGCCGGACGCCGCCCGCGGCATCGCTAACGAGGTTGCCGCCCAGGGCATCGCTACCGAGG +ATGTCGCCGACGGCATCGCTAACGAGGACGCCGCCCACGGCGTCGCTAACGAGGTCGCCG +CCCACGGCATCTCTAAGGAGGACGCCGTCCAGGGCATCGCGAACGAGGACGCCGCCCAGG +GCATCGCTAAGGAGGACCCCATCCAGGGCGTCGCTAACGAGGTTGAAGTCCAGGGCGTCG +CACACGAGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCGCCCACGGCATCGCCAACG +AGGACGCTGCCCAGGGCATCGCGAACGAGGACGCCGCCCAGGACATCGCAAACGAGGACG +CCGCCCAGGGCATCGCTAAGGAGGACCCCGTCCAGGGCGTCGCTAACGAGGACCCCGTCC +AGGGCGTCGCTAACGAGGACGCCGTCCAGGGCGTCGCTAACGAGGTTGAAGTCCAGGGCG +TCGCACACGAGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCGCCCACGGCATCGCTA +ACGAGGTCGCCGCCCACGGCATCGCGAACGAGGACGCCGCCCAGGGCATCGCGAACGAGG +ACGCCGCCCAGGGCATTGCACACGAGGACGCCGTCCAGGGCATCGCTAACGAGGACGCCG +TCCACGGCGTCGCTAAAGAGGTCGCCGCCCACGGCGTCGCTAACGAGGATGCCGCCCACG +CGATCGCTAAGCCGGACGCCGCCCGCGGCATCGCTAACGAGGTCGCCGCCCAGGGCATCG +CTACCGAGGATGTCGCCGACGGCATCGCTAACGAGGACGCCGCCCACGGCGTCGCTAACG +AGGATGCCGCCCAAGCGATCGCTAAGCCGGACGCCGCCCATGGCATCGCTAATGAGGTCG +CCGCCCAGGGCATCGCTAACGAGGTCGCCGTCCACAGCATCGCTATCGAGGACACCACAC +CGTCCAGGGCGTGGCTAACGAAGTCGCTGCCCAGGGCATTGCTACCGAGGATGTCGCCGA +CGGCATCGCTGAGGACGCCGTCCAGGGCATCACTAACGAGGAGGCCGCCCAGGCCATCGC +TAAGCAGGACGCCGCCCACGGCATCACTAACGAGGACGCCGCCCAGGGCGTCACTAACGA +GGTCGCCGCCCAGGGCGTCGCTAACGAGGACGCCGCCCACGGCGTCGCTAACGAGGTCGC +CGCCCACGGCGTCGCTAACGAGGACGCCGCCCAGGGCGTCGCTAACGAGGTCGCCGCCCA +GGGCGTCGCTAACGAGGACGCCGTCCACGGCGTCGCTAACGAGGACGCCGTCCAGGGCGT +CGCTAACGAGGTCGAAGTCCAGGGCATCGCACACAAGGACGCCATCCAGGGCATCGCTAA +CGAGGACGCCGCCCAGGGCGTCGCTAACGAGGACGCCGCCCAGGGCGTCGCTAACGAGGT +CGCCGCCCACGGCGTCGCTAACGAGGATGCCGCCCACGGCGTCGCTAACGAGGTCGCCGC +CCAGGGCGTCGCTAACGAGGACGCCGCCCAGGGCGTCGCTAACGAGGTCGCCGTCCACGG +CGTCGCTAACGAGGACGCCGCCCGGCACATGGCTAAGGAGGACGCCGCCCAGGACATCGC +TAACGAGGACGCCGCCCACGGCATCGCTAACGAGGACGCCGTACACGGCATCGCTAACGA +GGACTCCGTATACGGCATCGCTAATGAGGATGCCGTATATGACATCGCTAATGACACCGT +ACAAGGCACGCTAACGAGGACACTGTACAGGACATCGCTAATGAGGACACCATACAAGGC +ATCGGTAATGAGGACGCTGTATACGACATCGCTAACGAGGACACCCTACAAGCCGTCGCT +AACAAGGACACTGTACACAACATCGCTAATGAGGGCACCATACAAGACATCACCAATGAG +GGCGCTTTATACGACATTGCTAATGATACCGACAAGGCACGCTAACGCGGACACTGTACA +CGACATCGCTAATGAGGACACCGTATAAGACATCGCTAGTAACTATCGCAAGAACAAAAA +ACCAAACACTGCATATTCTCACTCATAGGTGGGAATTGAACAATGAGATCACATGGACAC +AGGAAGGGGAATATCACACTCTGGGGACTGTTGTGGGGTGGGGGGGGGAGGGATAGCATC +GGGAGATATACCTAATGCTAGATGACGAGTTAGTGCGTGCAGCACACCAGCATGGCACAT +GTATACATATGTAACTAGCCTGCACAATGTGCACATGTACCCTAAAACTTAAAGTATAAT +AAAAAAAAAAAGACATTGCTAGTGAGCACACTGTATACGACATCGCTAATGAGGATGCTA +TATATGACATCGCTGATGAGGACGTTGTACACGACATCACTAATGAGGACACCATACAGA +TGGCTTGAGCCCAGTAGTTTGAGACAAGCCTGGCAACACAGCGAGACCTCATCTCTACAA +ACATTTTTTAAAAATATGCCAAGCATTGTGGCGCATGCCTGTAGTCCTGGCTATTCAGGA +GGCTGAGGTGGGAGGATCACCTGTGCCCAGGAGTTCAAGGCTGCAGTGAGCTATGATCAC +ACCACAATGCTCCAGCCTGGGCAACAAAGCAAGACTCCATCTCTAAAAATAAAATTAAAT +TAAAAAAAAAGATCTTCGATGTAAAAGAGGTATGCTCAAATGCAATAAAATCATATAAGA +AGGCCGGGTGTGGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCTGAGGCAGGTGG +ATCATGAGGTCAAGAGACTGAGACCATCCTGGCCAACATCGTGAAACACCGTCTCTACTA +AAAATACAAAAAACAATCAGCTGGGCGTGGTGGCACACACCTGTAGTCCCAGCTATTCAG +GAGGCTGAGGCAGGAGAATCGCTTGAACCTGGGAGGCGGAGGTTGCAGTGAGCCAAGATT +GTGCCACTGCACTCCAGCCCGGCAACAGAGCGAGACTCCGTCAAAAAAAAGAAAAAAAGA +AAACCATACAAGAAGCCCCTACGAATCTGGGTGAATCAGCAAAGGCTTCACAGGATAGGA +AAAGGCCATGAGTATGAAAACATGAGTGGGGGGTTGGCCTAGATGGTAAACGAGGAGAGG +ACAATACGGCCAGGAAGTGCATGTGCACAGCAGACGGGAGATGGAGGGCACGGCTGATTG +GCAGCTACCTGTACTTTAATATTCCTGGAGTGTGACGTGTGAGGCAAACATGGGGTGGTG +GGGTGAGTGCTGGAGATGAGGCAGACAGTGAGCCATCAGCATGTTAGTAACAGGGGAATC +CATGGGCGTTTCATGCAGCTCCAAGGACCCTATGTGAGCTCATCAGACTCCAATTACCCA +AATCTGTTTCTTACCAGTGGTAGTTAGGATTTCCGTAGGTACACTGGATGTCTTCCCAGG +ACACCTGGAAGCCAGAAACAAATGGGGTCAAGCAGCCAGCTGACACAAGCACCCACAGAG +GACAGGACACTATAATGTGCCCCTCATCCTCCAGACAAGCCCACCCCTAGCAACTCCCAA +GAGCCTGGAGCAACAGCAGCAGGATGTCTTGTGCAGTGAAGTATGTTTAGCGCCCTTGTC +CCTGTGTTTAAACTTGGTCATGCTTTTCCCAGAGGCCTAACTTACATATTTCTAACTCTC +CTTGCTCTCTAGACATTTCCCACAAAGCAGGAAGCTGCAGAGCATGAGCCTAGAGCACCA +AAAACTTAGAAGTGAAGTGAATTGAACCCTTGCAGAGGTGCAAACCACATGGGGACTTCA +GACCGAAAAAGGCTTGAACCCTCATCAAAGGCCCCACACCCAGACAGCAGGATCACAGTG +TGTCTTGATCTCAGAGACCCAGGCAGCCCTGAGCCCAGCATTTGCTAGAGGTGGCCAATC +CAGGGCAGGAGGCAATTGTGGATGATGTTTCTTACCAAGCAAATATTGGAGTCATTGAAG +CAGAACCATTTTCCATCCACAGCATTCCGGATGTAGACACAGTAATGACCGGAGTCTGCC +ATTCCCACGTGCGCAATCACAGCAAAAAGCTCATACTGCCCTCCAGACTGGAAAGAGACA +GGCACGAGACAGTTCACCCACCACCACAAACACGACTGCCTCACACATTTATACCTGTCC +ACCCGAGGCCCGACTCTGGGACTTTAGAATATTAGAAAACAGTCCTGACCCACGGCCAGT +GGGCACCCTCCAGGAGGGGCTTTCCTGAGTGTGGATCCTGAACTGTGAAGGCTCAGCAGC +TTGGCAGGGCAGAGCACACAAGAGATGGAAGGCATGAGGTCATGAGAGAGGCCCCCAAAG +CCAAGGCAAGATTAGAACTTTCCCCTGGGAGGGGTGGGGATCATCAGAACACAGTTCTGC +TTCTCCACAAGCCCAGGAATGACCCTAACCTGAGCCACCGTACCCAGCCAAAAAAGTCTT +TTGTAGGGGGAGGGGAGACAGAGGGCAAGGGCGGCACACGCAAAGCTGAGTCACCCACAG +TGGAGGCTGAAATTATCCCTATTTCCATTTGCAGACTTTGTGCAGAACTTTACAAAATGC +AGGGCAATATCTGTATCTAAATATTAGTTTACAAGAAATAAAAGGGTTATAGATGATGTT +AAAAGATATCAACCAGCCAGTGCTGGCATATGAAAAAAATATTCAACCAAATCAACTGCA +AGGAAAAGAAAAGGAGCGGAAATCTAAAAGGAACTTAAGAAAAGAAAGAAACTTAACCAA +ATGCAAGTGTAGGCGTTGTTTGGATCTAGAGTCAAACAAACCACATAGATTACACAACAG +TCAGGAAGTCTGAACGTTAACCAGATATTTGATGCTATTAAGGAATTGCAAGATGGAGAT +GATTATCTTTTAAGTGCTTATTCTTTAGTGATACATAATGAAGTGTTTATAAATGAAATA +GTATGATGTCTGGGATTTGCTTCAAAAAAATCCAGTACAGGGTTGGGTGAAACAAGAGGG +TGGGTTATAGGAAAAGCAAGACCTGCCATGCGTTTTGGTAACTGTTACAGCCAAGGATTC +ACTGTCTAACTCTTCCTTCACTACACACTTTGGTATCTATTTGTAATGTTCCATAACAAA +GTCTTTTTTGTTGTTGTTGCAAAGATGGAGTCTTGCTTTGTTGTCCAGCTGGGCTCGACT +CCTGGACTCCAGCAATCCTCTTGGCCCCGCAAAGAGCTGGGATTACAGGTGTGACCCACT +GCATCCAGCCAAAAAAGTCTTTTTTAAGTGAAAAACAATTTTAAATGTACTTCATCGGGT +AGAATCTGCAGGTAGAAATAAAAAGAACTAGAAGGAAAGAAAAAGAGAATCCTATGAAAT +GTATACGGCCTAAGTAGGGAAAGAAATCATGTTATAATAGGAGCTATTGTAACGTATTAT +CAGGTCTTAATTTTCTAAATGTCATGGTTCTAGAGCATAAATAGCCAAACAGACCAATAA +AACAGAAGAGACACTCCAAAAATAGACCCGTACATATAGAAATACAAAATTTGTTATGTA +GCATTTCAAATCTATGGAAAAAAAGATATTTGGGTCCTTTTTTTTTTTTTTTTTTTTTTT +TTTTAAGTTTTTCTTGTTTTGTTTTTAGAGACGGGGTCTTGCGCTGTCACCCAGGCTGGA +GTACAATGATAGATCATAGCTCACTGCAGCCTCAAACTCCTGGGCTCAAGTGATCCTCCA +ACTCAGCCTCCCAAGTAGCTGGGACTAAAGGTTTGTGCTACCACACCCAGCTAATTTTTT +TTTTTTTTTTGAGAGACGGGGGTCTCATTATGTTGCTGAAGCTGGTCTCGAACTCCTGGG +CTCAAGCAATCCTCCTGCCTCAGCCTTTTGAGGTGTGGGATCACAGGCATGAGCCACATC +ACCTGGCCTTGTGTCTCTTTTTTTCTCAGAATCTCTTGATAAGTTATTATCTCAGGACAA +GTGAATTAAACTTTACTCTGATTAAATGTGGTCCAGTCAACTGGCTACTTTATGATTATC +CTCAAAGTGGGCACAGGCCATCTGAGGAAGAAAGTTTGGTTGGTACTATGAACCCACAAT +GACATGTTTGCCTATGCATTTCTATGTATTCCACATTATTTCCAAAGAAGCCTACTGAAT +TCTGGATTCTGTCCCTCAGTGCTGTGAGGCATATGAACACAAATCCAATATTTAGAAAGA +AGAAAGGCTTTTGAGGCTGGGGACAGTCTCTGAGGAACAGGTGGCTCCTAGCAGACTGGG +GGTGAAGGAAGGGAAAACAGAAAGGACATGGCATCTGGGGAGAGGCAGGATGGCAAGGAG +GTCGGGATCATCCCACCTGCTCCTCAGCATCACAAGACTCTCGCTTCATTGGAAGGATCT +GGCTGAAATCCAAGCTCTGGGGGAAGTACAGGGAGTGGCAGATCTTTCTCGTCTGTGAAT +TCCTGATGGAGAATCGCATGAGGTGGATTGTCAGGGTCTGGGGCAAATGGGTCAGCTTCA +AGACCTGAAAAATCAAAATCACTCTGGAGATGAAGTCCACTTGGAATGAGAGAGTCAGAG +AAATGTCAGGGCTAGCAACGCGTTCTTCCCAAAAAGAGGGGAGCAGGGCGACATCATGGA +GTTCAAGGCTCCTGTTCACTGAATCTGCTGAGCTCCTCTGAGAATAATGCAAAACTTGGC +TATTCTACCACCATGTGGCCCCCCACAAGAGGCACAAGGGCACAGGGCTCTGCACAGGTA +CCAGGACCCAGGGAGCCACCACGTCTGCTCCAGGGAGCTGGTCTCGCCCCGAGGGAAATG +CCCTGCCCGCTGCTCTCAGGCCCCCTCCTGCAGTCCCTCTCAGTGATGCGACATGAGAAG +CCACATCCACGGCTCCAGATATCAGAACCACAGCGTCCCAGATACTAGCCAGACCCAGAT +TCCCTTTCTCACCCATCATGGGATGTCCTCGGGGCCTCTGATGATTCTATCAGGAAATCC +ACGGGGGGCAACCCCAGACTAGTGAAGGACAGATGACCCCTGAACAGCACAGGTTTGGAC +TGTATGGGTCCGCTTATACACAAATTGTTGTAAATAAATACAGTCTGCCCTCCCCCATAG +GCACGAGTTCCACATCTGCAACCAAATGCTCATCAAAAATAAAGTATCCCAGATGCACAA +CCGCATAGATGAGGGACTGACTTTTCCTATACGTGGGTTCCACAGGGCCGACTGGGTGTG +ACTTGAGTGTGTGTGGATTTTGGTAAAAGCAGGGGTCCTGGAACAAATCCCCCATATGCA +CCGAGGGACAGCTGAGTCTGATTTAGGGAATGAGTACCTGTTTCCCACGGGTCTTCTTCC +CACAGTTCTCACAGAAGCATTTGCTTTTGCTTGATAACTCCCTGGGCTGGAAGAAGCAGT +GCAGGGCGTCCTCCTGTCCCACCCAAGAGAACAGGGAAAAAGCAGCGTTGGTATTTCCCA +CCTAGAATACTATATTCGTCTGTTCTCACACTGCTGTGAGACAATAGCTGAGACTGGGTA +ATTTATAAGAAAAGAAGTTTGATTGGCCCATGGTTCTGCAGGCCGACCGGAAGCATGGCA +GCATCTGCTTCTAGGGAGGCCGCAGGAAGCTCCCAATCATGGCGGAAGGCCAAGCAGGAG +CAGGCGTCTTACCTGGGAGGAGCAGGTGCAAGAGACCAAGTGGGGAGCTGGAGTGCAGGA +GCGCGATCTCAGCTCACCGCAACCTCCACCTCCCGGGTTCAAGCGATTCTCCTGCCTCAG +CCTCCTAAGTAGCTGGGACTACAGGCTGCACCACCACGCCCAGCTAATTTTTTATGTTTT +TAGTAGAGACAGGGTTTTACCATGTTGGCCAGGCTGGTCTCAAATTCCTGACCTCAGGTG +ATCCACCCACCTCAGCCTCCCAAAGTGCTGGGATTATGGGCGTGAGTTACCACACCCAGC +CTGGCTCCACACTTTTAAACAACCAGATCTCATGAGAACTCACTGTCACAAAGACAGTAC +CACGGGGGATGGTGCCAAACCATTCACGAGAAACACTCCCCCATGATCCAATCTCCTTCC +ACCAGGCTTTACCTCCAACACTGGGGATTACAATTGAACAGGAGATTTTTGGGCAGGGTC +ACAGACCCAAACTGTATCAGGTACAGCCTCCCCACACTTTGCAGCTGAGGGTTTCAGCTT +TTCTTCTGGTTCTCCTCATATCCCCCTTAATGCCTGGCCTGGTGTGGTCCACTTGGCAGG +ATCTCAAAGGGCACCTACTGACTGGAGGAACAAAACAGGAGGGGGCTCCTATTAAGGGAG +CAGTATGAGGGAAGTGGAGGTAGGAGGGAAAAACATTTTTGCCAAAACAAAGGAGAAATT +GGCCAGCGCCGTGAAAATGAAATAAGTGACTTTCCAGAAGCCAGAGATAGATCAAAGAGG +CAAGGGGGAATTGGCCACACTGTGCTGTGTGGTGTGATGGTTTGAGGGTTTGTCCTCCCC +AAAACCCAGGTTGAAACTGAATCCCCAGTGTGGCTGTATGGAAAGGTGGGGACTTTGAGA +GATAATTGGGGAGGGCAAGGTGTCTCATGCCTGTAATCCCAAGGAGGCTGAGGCAGGGGG +ATCACTTGAAGTCAGGAGTTTCAGATCAGCCTGGCCAACATGGTGAAACCCCATCTCTAC +TAAAAATACAGAAATTAGCCGGGCATGGTGGTGGGCACCTGTAATCTCAGCTACTTGGGA +GGCTGAGGCAGGAGAATCGCTTAACACCGGAGGCGGAGGTTGCAGTGAGCTGAGATTGTG +CCACTGCACTTCAGTCTGGGTGACAGAGGAAGAATCTGTCTCCAAAATAAAAGGTAGGGG +GGTTATTGCGTCATGAGGGCACAGCCCTCATAAATGAATTAATCCACTCATGGATTAATG +GGTTAATCGGTTATCCTGGGAGTGGGACTGGTGGCTTCATATGAAGAGGAAGAGAGACTT +GAGCCGGCACATTAGCATGCTCAGCCCCCTCGCCATGTGATGCCCTGCACTGCCTCGCCT +CAGGACTCTGAGAGTCCCCACCAGCAAGCAGGTCCTCACCAGGTGCAGCCCCTCAACCTT +GACTTCCCAGCCTCCAGAACTGTAAGAAATAAATTACCTAGTCTCAGATATTGAGTTATA +ACAACAGAAAATGGACTAACACATACAGGTGCAGCAAATACCAAGAGAATCCCCTTACCA +GTGTCTTCAGGGGCTTTGAGTCCACATCAAAAAAAGAAAGTCGGAGGGTGAGCATGCTGC +TGTTTCTGCTACTCTCCATGGCACAGTCAAGGCAAATCAAGGAGTCCTTCATCCGGATCA +TATACAGGGCCTGCAGTCTCTCCACCTGCAAGAGGGAGAGCGGAGAGGTGAGATGGGAAC +ACCACCATAAGCCAGGTCAGGCCAACTGCCAGAAGGTGGAGCCAAGAGACAGAAGCTCCT +CACAAAGGTGCAAAATAATACCAGTAACAATATTATGAAACTGTGATAAGTGTTTTATGT +GGATTAACTCTTTTTTTTTTTTTTTTGAGACAGAGTCTCGCTCTGTCACCCAGGCTGGAG +TGCAGTGGCGCGATCTCGGCTCACTGCAAGCTCCACTTCCCGGGTTCACGCCATTCTCCC +ACCTCAGCCTCCCGAGTAGCTGGGACTACAGGCGCCCGCCACCACGCCCGGCTAATTTTT +TGGTATTTTTAGTAGAGACAGGGTTTCACCGTGTTAGCCAGGATGGTCTCGATCTCCTGA +CCTCGTGATCTGCCTGCCTCAGCCTCCCAAAGTGCTGGGATTACAGGGGATTAACTCTTT +TATTCCTCTACACACTACGGGAACAACAGCTGAATGAATGAAATGAGCAGCATCTTAAGC +TTCCGAGTGCTCTGGTTCTAGGTTCTTACCAAGTGCACATCAGCGATCTGGTCCTTAATC +AGGTTCCAGAGTTTGAGGTACAGTTGGGCAGCATCATGTTGGACAAACACTGGCCACAGA +GAAAAGGAACAGCCAATTAGTGAGGTCTTCAGAGTCACTTCTCATGCCCTGGTACTTAGA +CACACATGAACACTGATCACTTTGTCTCTTCCTAGCCCTCCACCCCACTGCAAGGCTAAG +TCGGCACGACAGAAGAAGTGATCAATAAACAAACAGTAAGTTTGGTATTGATTTTTGAGA +ACGCCTCTTAATACTTAAGCTCCAGTGCCAGATGTAGTGGCTCATGCCTATAATCTTAAC +ACTTCGGGAGGCCAAGGTGGGAGGATCGCTTGAACTCAGGAGTTTGAGACCAGCCTGGGC +AACATAGCAAGACTCCGTCTCGATAAAAAATTTAAAAAAGTACTTGAGAGTAGCGGTGCA +CGCCTGTAGTCAGAGCTACTTGGGAGGCTGAAGCAGGAGGATCACTGGAGCCCAGGATGT +TGAGGCTACAGTGAGCTGTGATGTCACCACTGCACTCAGCCTGGGGAATGAGATGTCCAC +AGGGACTTTGAAAAGCACTGATACATTCCTGAGGATCTAGAAGGCCAGGCGCATGCCCAA +GTAAGACCTGAGAGGGCTCCGATCCCTCCCCTCTGGCTGACCACAAGGCCACATGCAAGA +AAGCAATGAAGGCGAATACAGAATCATGAACTGCCCAGAAACGATAAAACAGCAACAACA +ACAAACCCTGCTGTGGGGATCTCTGATGTCCAGTGTTGCCACCTTACATTATCTAAAATG +TTCATTTTCCAACAAAAGAGACAAGACCTACAATGAAACAGAAAAGCATGGCCACCCAGG +AAAACAGCAATCGTAGAACCTTCCACTGAGAAGCCCTAGATGTTGGCGTTACTAAACAAA +GACTTTAGCCGTTATAATATGTTCAAAGAACTAAAGAAAACCATGTCAAAAGATGTAAAA +GAAAGTGTGAAAATGCTGCCTCACCAAATAAAAAGTATCAATAAAGAAAAAACTATAAAA +GAAGAACCAAGCAGAAATTCTTGAGTTGAGGAGAACCATAACTGAAATGAAAAATGTACT +AGAGGAGGTCAATAGCAGATTAGAGCTGGCAAAAGAAAGAATCCATAAACCTGGAGCTAG +GTTGGTTGAGGTTCTCCAGACTGAGGACGGAAGGAAAGCTGAACACAGTACCTATGCAGC +GAAAAGCTGAGGAGCTGCTCACTGCGTGTAGAGCTCAACTAACTCTGATACAAAAAAAAA +TGTGATACAAAAGGTTTTATACACAAACGTGAACTTATTCTGAAGCCAGCCTGGGGCAAG +GAGCAAGACACATCCTGCCTTTTAATGTGCCATTTCTCCTTTGGAGGAGAGAGGGGCATT +TTCATAAGGTGTGTTGTGGGGGTGGGGGGAGTGAGCAATGGCGGTTTTCTACCGGGCAGT +TATCAAGTTCCCAGCAGCTGAGTTGGCGCCTTTCCGGGCAGAAAAGTGGCCGAGTGGGCA +TGCTTTCTCCATGCCTTCCTAGTGGGTGAAAGACAAACCCCTAGAGGGTGGAAGTTTCGA +AGCCACCCCCTGGCAGGGAGAGTTCCCTGGTGGGTATGCTTTGGGCTGCAAATCTACTGC +CAAGTCTCAGGAAAGATCAGCTGGAAGATCTTGCCCTGTTCTCAATCAAACCTCCATCAG +CCTACCTCCATTTACAGATTCTTCCTTTTGCCCAGCAGGGAATGTCTGGAGAGGGGTAGG +CGAAAGGTGATATTTGCATTTCTAAAGGGCTAACAGGAAACAGGAAACACGGCCGCGGTG +AGGGGTGAGGGATGGGAAGAGGAGAAGTGAAAAGAAAGTAATAAGAAAACTAATATAACT +ATCTCTTAGAAAATGGGAGTACTCAGTTACACCCAGATGGGTTCACTAGTGAACGATGGG +TTCTACCAAACATTTATGGGAAAAATTATACCAATTCCCTACAACCTCTTCCAGAGGACA +AAAGCAGAGAGAACACTTCCTAACTCATTCTCTGAGGCCAGCATTATCCTAACACCAAAA +CCAGACAGACATTGTAAGAAAAAAACCTAAAAACCAGTATCTCCCGTGAACATAAATGCA +AAATTCCTCAACAAAATATTAGTGAATCAAATTCAACTATGTATAAAAAGAATCACAGAG +GGTGACACAAGCGAGATGGTAGAGAAGGAGGCTCCTGGTGCTCCCCTTCTCCCATGGACA +CACGGTAAAACTCTCATCTACACACAGATCAACTCCCTCTGAAAGAAACCCAGAAACCAG +CTGAGAGAGGCCTGCACAGGGGGCAATGGGGAGAACACCCACATCGCAACCGGTTGGAAA +AGCTGAGACACACTCGAACCACAAGCCCCACCCCAGACACAGTACCTTACTGTGAGGAAG +GAATCCCTACTCCCAGCTTTCTCCTGGAGAGGGGAGGGTTTGGACCACACATAGGCAGCC +CCAGCTTTTGCAGTTCCCACTCAAGGGCTTGGCTGCTGGGTCACCTAGCTCTGGGAGCAG +ACATGGGTTAGCAGTTATGAATCCTCTGCGACCACAGAGGACAAAGAGGCAGTTTTAAAC +GGGCACGTGAGCACTTCCAGCAGCTGTGCTCAGCACAGAGCAAACAGGCAGAAATGCCAG +GCTCCCAGTTCCTCCCTGGAAGGATATGTCTGCGGGCTCTCCTAGCTGTTGCCCGAGGGA +TGGGCTTCTATTAATAACTGGCCTGCACCTGGAGCCAATGAGGCAGGTAAACAATAGATT +TCCAGGAGTCTGGACAGGCCTGTGGGCAAGTCCCATGCCTTCTCCCACCCCCTGCTGTAT +GGTAAAATCAGGTCTCTAACTTCACACATTGAGTACACATTTACCCCTCTCAAATGAAGG +TCTAGCTCCTCAACCACCGAGCTTTGGGAGCTGACAAGGCTCTGTATTTGTAAGTCCCAC +AGGGGCACAGAGACCAAAGAACATCCCCCCAGGCCCAGTGCAGCGTGAACAGGCAAAAAG +GCCCGGCTCCTACTTTCTCCCTAGAAGGAGTTTGTCTGCACAGTGCAGCTGCTGCCCTGG +GGTTTCTATGCATCTGGGAGCTGACAGAGCAGGAAACCAGTGCTCCTCTGAGACCCTGAA +CAGGCAGGTGAGCACCTCCACAGCTGCTCCCACTGGTTTGCTCAACAGATAGCGTCAAGC +TTCCAACTAACCTGTCCGTCTCTAAGCAGAGAACAGCCAGCATTTGCTAGGCCCCTGGGG +GTGACAAAGAGTAAAACAATGCATGAAGGAGTGTGCAGTTTAAACTTGAGTGCAGGCACT +TGCCACAGATCCTCTCTCCAGCATTTTGCAGAGCGAGTGGCAGATAAACTCATGCTCCCA +GCTTTTCCCTGAGGATAGAATAAACTGGAACACACATTTAATGCCCCAACGTCTCCAGCT +GCACCTCAAGGGGCTGGTTTCTATCTCCCCTGTCTGGGGCACTGACAGGACATGACACAT +TCTAATCTCCTGAGGGCCGCTAAGAACATAGATGACAGTTTGGACAACACAAAAGGTCAA +GAGGTGCTCCGAGTGTCTGGCAGGGCTAATTGGTAAGTTCGTCTCTTATACAAGGCCCGT +GGGACAAGACTGGGAGAGGTATTTTTCTTTTTTTTTTTTGAGACGGAGTCTCGCTCTGTG +GCCCAGGCTGGAGTGCAGTGGTTCGATCTCGGCTCACTGCAAACTCCACCTCCCAGGTTC +ACGCCATTCTCCTGCCTCAGCCTCCCAAGTAGCTGGGACTACAGGCACCCGCCACCACGC +CCAGCTAATTTTTTGTATTTTTAGTAGAGACAGGGTTTCACCGTGTTAGCCAGGATGGTC +TCCATCTCCTGACCTCATGATCTACCCGCCTCAGCCTCCCAAAGTGCTGGGATTACAGGT +GTGAGCCATGATGCCCAGCCTGGGAGAGGTATTTTTCTTAACTAAAGTACAGAAAATAAC +AGAGAATCAAGAACAATGAAGAAACAGAGAAATCTGTTCCAAGCAAAAGAACAAGATAAA +TCTCCAGAAAATGCCCCCGGTGAAATGAAGATAAGTGACTTACCTTACAGACAATTCAAA +ATAATGATCATGAAGATGCTTACCATGTCTAGGACAGCAATGCATGAACAAAGTAAGAAT +TTCAGCAAAGAGACAGAAAAAAGTTCAAAAGAAATAATAGAGCTGAAGAATACAATAACT +GAAATAAGAGCTCAAAAGAGAAGCTCAACAGACTAAATCAAGCAGAAGAAAGGATTAGCA +AACTAGAAGATAGGTCACTGGAAATCATTCAGAGGAGCAAAAATGAAAAAGAATGAAAAA +GAGTGAAGATATCTTAAGAGAGTTAGGGGACATCAAGCCGACCAAAATAGGCATTATCAG +AGTCCCAGAAGGAGGAGAGTGAGAAGAGATGGAAAGCTTATCCAAAGAAATAACAGTCAC +GAGTTGCAGATCAACATTTCAGTCAATGGCAGACCGCATGAGCACAGTGGCCATAGCATG +CAGCCTAGCTGTGTAGTAGGCTGTCCCATCTAAGTTTGTGTAAGTGCACTCCATGATGTC +CACACAATGACAAATTCACCTTCTGATGCATTTTCAGAACGTATCCCTGTTGGTAAGCAA +CGCATACCTATAATGACTGAAAACTTCCCAACCCAGGGAAGGAAATACAAATCCACATCC +AGGAAGCCCAAAGGACACCAATAAGACTGATCTAAAGCAACCCACATCAAGACACATCAT +AATCAATTTCAAAAGTTAAAGACAAAGAATTCTGAAAGCAGCAAGAGAAAAGCAATGTAT +TATACACAAGGGAAAACCCGTAAGTGTAGGATTTCTTCTGGGGGTGATGAAAATGTTATG +AAATTAGATTGTGATGATGGAGGCACAACTCTGTGAATACACTACAAACCTTTGAATTGT +ATGTTTTTAAATGGATGAATTTTACAGTATGTGATGCACATCCCAATATAGCTATCTAAA +AAAAAAACCTGACCTATTTGTGAATTATTTTGTAGAACATGTTTTCTCTTTTTTATTCCT +TTATTCTGTTTTCCTGCAGTTCCCTAACTGTGGTGGAATAAGCTTGGAGGAGATGCCTTC +ACCTACTCTACTGAGAGGCAGAGAAAGGTTAGGTATGGAAGTAAAATGTCCATAAATAAT +ATCAATTCTGCACCTCCAAAGATGTGTGCCTCTTACACAAATGTCTCTATAATCTGAGGG +GTCCAGGCTACCTAACTTGCTTCTTGTTGCTTCACTGCCCATTAGTTCCTCTCTTCACTC +TCTAAGCTTCCCATCCCCTTTGGATCAGCAGCCAGGAACCCAGTGGGAGGGTATCTTACG +GGGCACGTTGTACTTCTGCAGGCAGTAGGCCAGCTCCAGGGGCCACACTGCTTTCTGCCG +GCTGTCCTGCATCTTCTCCAGCAGCAGAAGCATCTGGAAAGGGACGCTTCTCCTCTGCTC +GTCAGCTCCCCTGGGCACCGTGATCCTGCCACACAAGAACAGCCAGAAACCTCCTTACAT +GTAGTTCTCAAAGCTAGGTGCACACTGGAATCACCTGGGAGAAATTTTAAATCTTCATAT +CCAGGCCACTCCCATACAAATTAAACCAGAATTCTGGGTCCGGGGGGCGGGGCGCGGGCA +GTTATCAGAATTTTTCAGTTCCTCAGATTATTTCAATGTGTGGTCAAGGTTGAGAAGCAC +CATGTGAGTGAATCTGCTCTACAGGGGACCCTCTAGAGAGGGGGATCAGCATGACTGCTG +CCTTGGCCCCTCTGCACCCTGCCCAGCAATCGTGCTAGAGCAGACGGCAGATGCACGAGG +TCCTGGCTCCACATCTCGGGCAAGCAGCAAAATGTCCAGCCTAAAGCTCTCCAGACTGCA +GAGGCACATGCTGGGTTAGGTCCTGGGAAGAAAGGCAACATGAAAGGCTGTCCGTGTGGT +TTGGCAATGATTCATTTAATCACAGGCATTTTTCGGATGGGAAAAAGGAGAGAGCACAGG +GCAGAAAAGGAGTGATAGAGAGAGACAGAGGGAGAGAGTGCATTGTGTGAGTGTTGGTGG +AAGGAGGGGTGTGTACTCCCCACTGACTTACTCCTTCTCCGACTTTGGTCTAGTCCCAAC +TCTGTCTTTTAACCAAGTCAGTGGCTGTCAATCCTGGCTGCATTTAAAATCACCCAAAGA +GGGCTTTTAAAAAGTACCAATACCTGGCCGGGCCCAGTGGCTCATGCCTGTAATCACAGA +ACTTTGGGAAGCTGAGGCGGGCAGATCACCTGAGGTCAGGAGATTGAGACCAGCCTGGCC +AACATGGTGAAAACTCGTATCTACTAAACATACAAAAATTATCCAGGTGTGGTGGCGGGC +GCCTGTAATCCCAGCTACTTGAGAGGCTGAGGCAGGAGAATCCCTTGAACCTGGGAGGCG +GAGGTTCCACTGAGCCGAGATTGCACCATCCCTCTCCAGCCTGGGGACAGAGTGAGGCTT +TAGCTCAAAAAAAAAAAAAAAAAAGTACCAATACCTGGGCCGCACCCCAGACCAACCTAA +GAAGTTTTAGAAATAATGTGTAGGCCAGAATATGCAGAAGCCGATCTTTCCTCTGCCAGC +TTTTGAGAGAAGATCTCAAAAAGTCCAAGTCACTGTGAATAACTGAATATATTAAAAATG +AAATAATACAGGCCGGGTGCAGTGGCTCACGCCTGTAATTCCAGCACTTTGGGAGGCTGA +GGTGGGTGGATCACGAGGTCAGGAGATCAAGACCATCCTGGCTAACACGGTGAAACCCCG +TCTCTACTAAAAATACAAAAAAAATTAGCCAGGCATGGTGGCGGGCTAGTCCCAGCTACT +CGGGAGGCTGAAGCAGGAGAATCGCTTGAACCCGGGGGGCAGAGCTTGCAGTGAGCCAAG +ATCGCGCCACTGCCCTCCAGCCTGGGCAACAGAGCAAGACTCCATCTCAAAAAAAAAGAA +AAAGAAATAATACAAACGCTTATCAGCCTGAAGAACAGTCTTACCTCTTCAATATCCTGG +CGAAGTCCACATTCATTACAAACACCTGAATCAAGGAGTTAAGGCAGCAGGTCTGTCCAA +TGTTGTGTAAACCAACCAGGCCTATAAGGGGAAGAGAAAAAAATGCTGAGGGCAAGGCCT +AGGTAAAGAAGTTGACAAGGCTGGGCATGGTGGCTCACGCCTGCAATTCCAGTACTTTGG +GAGGCCGAGGTGGGCGGATCACCTGAGGTCGGGAGTTCGAGACCAGCCTGGCCAACATGG +TAAAACGTGTCTCTACAAAAAAATCCAAAAATCAGCCGGGTGCGGTGGCTCACGCCTGTA +ATCCCAGCACTTTGGGAGGCCAAGGCAGGTGGATCACCTGAGGTCGGGAGTTCGAGACCA +GCCTGATCAACATGGTGAAACCCCGTCTCTACTAAAAAATACAAAACTAGCTGGGCATGG +TGGCACATGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGTAGGAGAATCATTTGAAACC +AGGAGGTGAAGGTTGTGGTGAGCCGAGATCACACCATTGCACTCCTTTCTGGGCAACAAT +AGTGAAACTCCATCAAAAAAAAAAAGAAGAAGAGAACTTACAGCAGGGTGTGGCGTTTCA +CACCTGTAATCCTAGCACTTTGAAAGGCCAAGGTGGGCAGATCACCTGAGGTCAGGAGTT +CAAGACCAGCCTGGGCAACAGGGCAAAACCCTGTCTCTACTAAAAATACAAAAGCTAGCC +AGGCATGGTGGCAGGTGTCTATAATCCCAGCTTCTTGGGAGGCTAAGGCAGAAGAATCAT +TGGACCTAATTTATTGATTTTTTTGAACTTGGAATATGGTGTCATGACAAAATCATGCCA +CTGCACTCAATCCTGGATGACAGAGCAAGACTCTGTCTCAAAAAAAAAAAGGTTACTTTT +TATTTCCTGAAAAGCTTGACTTCCTGACAATGAAAGTCCTAAGGAGCGAGTGGCAGAAGA +CAGCTGGCAGCTGGCAGTCATTGGTGGGGCAAAGGCAGAGATACCACTGCTGACTCTACT +GGGCCTCGGGCCTCAGCGCTCATGGGAAGGGACCCTCTTTCAAGCTTTTGGAGGGGTAAG +GGAGGGCCAGGTAACAGTGCCTACATCTTAGGCACCGAAAACAACTGGAGCTGCTTCATG +CAGTCAAGAATCCCCTGAAGAAGGAAGGCAGTTACCTCCCTATTCTCCAGATCTCTTCAG +CTGGCCTGGCTCTCATCCTTTCCAAGACCTGGCTGTTTGCTTTGCATTTAGTTATATGAG +CTAATTCATATGCTTCTAATAAATGCCTTTCATCCTTCTCCAAAGTTAGCCCTAGAGTAT +ATTGCTGTTGTTTACAATCAAAAAGCCCCAGAGGTGTACTCTCCAATTCTCTTAATAACC +TCATTTTTCTGTCATTACCCCTGTTTTAGTACAAGTAGCTGAGCTTCAGAGAAGTTAAAA +GATGTGCCCAAGGTCGCACAGCTAATGAGTGTCACAGTCAGAATCTGAACCCAAGTCTGT +CTGATGTGGGGTCATGACAAGAGCATGGGTTTTCTTGGGAGAAAAAAATGACTTCAAATC +CCCACTTCCCGCATAAAAATGCACAATGGGTGTAGCAATGCCGAAGCCACAGAGCTATTG +AGGATGGATGGAGGTGACGCATAGGAAAGCACATGGCCTAGGGTATGTATTCCCAACACT +TTGGGAGGCCGAGGTGGGCAGATCACCTGAGGCCGGGAGTTCAAGACCAACCTGACCAAC +ATGGAGAAACCCTGTCTCTACTAAAAATACAAGATAAGCTGAGTGTGGTGGTGCATGCCT +GTAATCCCAACTACTTGGGAGGCTGAGGCAGGAGAATAGCTTGAACCCAGGAGGCAGAGG +TTGTGGTGAACCAAGATCATGCCATTGCAGTCCAGACTGGGTGAAAAGAACAAAACTCCA +TCTCAAAAAAAAAAAAAAAAGAATTAAGAAAAAATATTTGAACACTTCTTTTTATCCCTA +ATTTATTCATGTTTTTGAACTTGGAATAGGAACACTACTGCCAACAAAAGTAATTAGAGA +ATATAGATGTTAAATCTATTCTCTAAATGAATTATTGCTTATTTTAAAATTGCATATTAA +TTAATTACAGGAAATTTGGAAAGTAAGAGACATATGAAGAAAAAAAGGTAAAAATGATTT +GTAATCCCTCTGAGAGTTACCCTTTAATGCCATTTTTGGTATATTTCCTCTCAGTTCTTT +CCCCCTCCACCACCAGTATGTGTGAGTAGTTTATGTTTTATAAAGCTGGGTTCATACAAT +ATGATTTCTTGGCTGGTGTGGTGGCTCATGCCTGTAATTCTAGCACTTTGGGAGGCTGAG +GCAGGCATATTGCTTGAGCCCAGGAGTTCCAGACCAGCCTAGGCAACACAGTGAGACCCC +ATCTTTACAAAAAGTAAAAAATTAGGTGGTGGATATGGTGGCACTTGCCTGTAGTCCCAG +CTACTTGGGAGGCTGAGACCAGAGGATCACTTGAACGGAGGAGGAGTCTGCAGTGAGCCT +AGATTGTGCCACTGCACTCCAGCCTGGGTGACAGAGTGAGACCCTGTCTCAAAAAACCCA +AAAAAGATTTCTCTATAATTTCTTTTTTTATTCAGTAAAATATTGTAGTTTTCTCTATCT +TGATTAAACAGTCTAAAATGGTTTTAATGTCACCATAGTATTCCATTTTATAAATTTGTC +AAAATTTATTTAACCCTTATTGTTACATTTCCATTTTTTAAAATAGTGCTGCAGCTGTTG +ATTTGAAAAGATACTTTTTTCAGGTAGTTGACAACCAAAATATCCCCTTGATGGGTTCCA +GCATACCCCATGCCTCAGTATCACACAGTATACCTTTGTAACTAACCTGCATGGTACCCC +CGATTCTAAAATAAAAGTTGAAAAAAAATCATCTAGTGTTTTAAAACAAATTATGTATTA +TTTTTGGGCCAAGCGTGGTGGCTCACACCTGTAATCCCAGTTCTTTCAGAGGTTGAGGTG +GGAGGATCACACAAGAGGATCCACTGAGACCAGGAGTTTGAGACCAGCCTGGGCAACATA +GTGAGACCCCCATCTCTACAGTAATTAAAAAAAAAATTAGCTGGGCATGATGGCATGCAC +TTGCAGTCCCAGCTACTTAGGAGGCTGAGGTGAGAGGATTGCTTGAGCCCAGAAGTTTGA +GGTTACAGGGAGCTATGATGATGCCACTGCACTCCAGCCTGGGTGACAGAGCGAGACTCT +GTCTCAAAAAAATATACTATTTTAAATTTATAAATGACAATTGAATTACATTTATATAGT +ACAATGTGATGTGTGATGTATGTATACTGTTAAAGAGAAAAGCCTTTGACTAAATTTGAC +AGAGTTTAGTTGAACAGAAAAAAGATTCATGAACCAGGTAGCACTGAGAACCAAAAGTGG +TTCAGAGATCTCTGCTCCACAGGTGGGCAGGGAATATTTATAGCCAGAAAACGTAAGTTT +CATTGAGAAATAGCCTGTTGGTTACAGCTCTGCAGTTGCCTTGTTTGAACATGTTTTTGG +CAGCTTGCAGCCTGTGAAGGGCTGAGAGCTCAGCTGCTGTGATTGGCTGAGACTGGGCTA +CTTATTCCAAGGGCATATTCTCAGGTTAGGTTGCAGTTTGTTTTGTTTACCTATGTGAAC +CCCCAATAGCTGAGACAGGTCTCAGTTAATTTAGAAGGTTTATTTGCCAAGGTTGGTGAC +ATGCACCCATAACACAGCCTCAGGAGGTCCTGACATGTGCCCAAGGTGGTCAGAGCACAG +TTTGGTTTTATACATTTTAAGGAGACATGAGACATCAATCAACATATGTAAGATGAACAT +TGGTTCGGTCCAGAAAGGCAGGACAGCTCGAAGCAAAGGTGGGACAACTCGAGGTGGGGA +GGGGGCTTCCAAGTCTTAGATAGATAAGAGACAAATGGTTGCATTCTTTTGAGTTTCTGA +TGAGCCTCTCCAAAGGAGGCAATCAGATATGCATTTATCTCAGTGAGCAGAGGGGAGACT +TTCAATAGAATGGGAGGCAGGTTTGCCCAAAGCAGTTCCCAGCTTGACTTTTCCCTTTAG +CTTCTTGGGGCCCCAAGATTTATTGTCCTTTCACATCTATTAAGTTAGATTACAGTGTGC +TATATATGGAGGCAGCTTTATTTTATTTTAATTAATTAATTAATTTATTTGTTGGTGATG +TTGATTTCTCTTGTTTTAAAATCAACATTATAGGCTGGGCATGGTGGCTCATATCTGTAA +TCCCTGCACTTTGGGAGGCCGAGGCGGGTGGATCACTTGAGGTCAGAAGTTCAAGACCAG +CATGGCCAACTTGGCAAAACTCTGTGCCTACTAAAATATATGAAGATTAGCTGGTCACGG +TGATGCACACCTGAAATTCCAGCTACTCAGGAAGCTGAGGCAGGAGAATCACTTGAACCC +AGGAGGCAGAGGTTGCAGTGAGCTGAGATTGCACGATTGCACTCCAGCCTGGGTGATAGA +GTGAGACTCCAACTCAAAAATAAATAAATAAATAAATTAATTAATTAAATAAAATCAACT +TTACGGAGAAAAATTTACATTCAAGAAAATACGCCCATTTTAAGTGTCCAGCTGGATGAA +TTTTCAGAAATGTGTGTACCCTCATGACCACTTCCTCAATCATGATACAGAACATTCCCA +TAACCTGGAAATCCCTGTGGCCCTTTGCTGGCAGTTTCCCCACCCAGCCCCAGGCAACCC +CTGATCTGCCCTCTGTCACTGTAGACTAGTTTTGCCTTTTCTAGAATCTCATATAGAGGG +AGTCATGCAGTATGTACTCTCTTGTAGCTAATGTTTTTGAGGTTCCTTGGTGTTACTGCA +TTGTTTTCTATTGCTGAGTAGTATTCCGTTCTACTCAGTACCATAATTTGCTCATCTACT +CTTCTGTGGCTGGACTTTCCAGTTTGGCGCTAATATGAATTGTGGAGGCAGTTTTAGACC +AAATTTAACTTAACAATACAATATGAAAAGATTAAGTCAAGCTAATGAACATACCTGTTA +CCTCACTTACTTGGCATTCTTTTAAGTTGATGCACTAGAAATTTTCTCTCTTAGACCGGG +CACAGTGGCTCACACCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGGGGATCATGAG +ATCAGGAGATCGACACCATCCTGGCTAACACAGTGAGACCCCGCCTCTACTAAAAATACA +AAAAATTAGCTGGGCGTGGTGGCAGGCGCCTGTAGTCCCAGCTACTTGGGAGGCTGAGGC +AGGAGAATGGCATGAACCCAGGAGGCAGAGCTTGCAGTGAGCCGAGATCACACCACTGCA +CTCCAGCCTGAAAGACAGAGACTCCGTCTCAAAAAAAAAAAAATTTCCTTAGTTATTTTG +AAATATTCATTATTATTGACTATAGTCTCCTGCTGTGCAATAGACCTCAAAACTTTTTTC +TCCTGCTTGGCTGAAACTTTGTACCTTTTGAAGAGGAAGTCTCCATTCCCTTGTTCTGCC +ACCTCGCCAGCTCTGGTAACCATTATTCTTCTACTGAATGAATTCAACTTTTTTTTTTTT +TTTTTGAGATGTCTCACTCTGTCACCCAGGCTGGAGTGCAGTGGCACAATCTCAGCTCAC +TGCAACCTCCGTCTCCCAGGTTTAAGCGATTCTCCTGCCTCAGCCTCCCAAGTAGCTGGG +ATTACAGGCGCCTGCCACCATGCCCAGCTAATGTTTGTATTTTTAGTAGAGACAGGGTTT +CACCATGTTCGCCAGGCTGGTCTCAAACTGCTGACCTCAAGTGATCCACCTGCCTCAGCT +TCCCAAAATGCTGGGATTACCAGCATGAGCCAGGGCGCCTGGCCCAAATTCAACTTTTTT +TTTTTTTTTATGAGTGAGCAGCAGCAAGATTTATTGCGAAGAGCGAAAGAACAAAGCTCC +CACAGTGTGGAAGGGGACCCGAGTGGGTAGCTCCCAAATTCAACTTTTAAAAGATTCCAC +GGGCATGTGAGATTATGTGGTATTTGTCTTTCTGTGGTATTTGTATTTCACTTAGCAGTA +TGTCCTCTAGATTTATTCGTGTCATTCCCAATGACAGAGTTTTGTTCTTTTTTATTTTTT +TGGAGATGGAGTTTCATTCTTGTTGCCCAGGCTAGAGTGTAATGGCATGATCTCGGCTCA +CCACAACCTCCACCTCCCGGGTTCAAGTGATTCTCCTGCTTCAGCCTCCCAAGTAGCTGG +AATTACAGGAATGTGCCACCACACCTGGCTAATTTTGTATTTTTTTTTAATAGAGATGGG +GCTTCACCATGTTGGTCAGGCTGGTCTTGAACTGCCGACCTCAGGTGATCTGCCCACCTG +GGCCTCCCAAAGTGCTGGGATTACAGGCATGAGCCACTGCTCCCGGCTGAGTTTTGTTCT +TTTTAAGGCTGAATAGTACTTCGTTGTATGCGTGCACCGCCTTTTCTGTACGCATTCATC +TTAGGCTGATTGACTTAGGCAGATTCCACATCTTGGCTACTGTAAATGGGGCCGCAGTGA +ACATGGGAGTGCAGACATCCCTGAACACACTGATTTCAATTCCCTTGGATATATTCCCAG +AAGTGGGATTGCTGGCTCACATGATAGTTCTATGTTTAGTGTTTTGAGGAACCTCCATGC +CATTTTCCATCGCGGCTGTACTACACACCGGCAGTATACTAGGATTCCCCTTTCTCCACA +TCCTGGCCAAAACTTACCTTCCATCTTTTTCATAAAACTTGTTCTGATGAGAGGGAGATG +TTATGTCACGGTGGTTTTAATTTGCATTTTCCTAAAGATTTAGGTTGCCACTGGTCAGCT +CCAGGCCCCAGAGCTTCTTCAACTGAAGAAGTACTTGCTGTCTATAGTAAGCATCTCAAA +CTTTAACGTGCATGTGGATCACCTGGGAATCTTGTCAAATGCAGCTTCCAGGTAAGTGGG +TCTGCAGTGGGGCCTGATATTTTGCCTTTTGAACAAACTCCCAGATAATACTGATGTTAC +TGGTCCCAGGACCTGCCTTTGAGGTAGCATTTTTTCATGAACCTATTGGCTGTTTGTATG +TCTACTTTTGAAAAATGTGTTTGGTTCCTTTATTCATTCTTACATTGGCTTATTGGTTCT +TTTGCTGTTGAGTTGATTGAGTTCCTCATATATTTTGGATATTAGCCCCTTTTCTAATGT +ATGGTTAGCAGATATTTTTTCTCACGACGTGGGTTATCTCTTTGTTACTTGTTCCTTTTG +CTGTGCAGAAGCTTTTCAGTTTGATGCCATCCTGTTTCTATTTTTGCTTTTATTGCCTGT +GCTTTTGGGGACATACCCAAAAAATCATTGCCCAGATCAGTGTCATGGAGCTTTTCCTCT +GTGTTTTCTTATAGTAATTTTACAGTTTCCGGCATAATGTTAAAGTCTTTGATCCATTTT +GGGTTGATTTTGGGGCATGGTGTAAGATAAGGGTCTAATTTTATTTTCTGCATATGAATA +GCCACTTTTCCCAGCACCATTTATTGAATAGAGTGTTCTTACCCCTTGGCGTGTTCTTTG +TGCCTTTGTCAAAAGTCAATAGACAGTCAGCTGGGCACGGTGGCTCACGCCTGTAATCCC +GCACTTTGGGAGGCCAAGGCAGGTGGATCACCTGAGGTCAGGAGTTCAAGACCAGCCTGG +CCAACATGGTGAAACCCCATCTCTAATAAAAATACAAAAAATTAGCCGGGTGTGGTGGCA +GGCACCTGTAATCTCAGCTACTCGGGAGGCTAAGGCAGGACAATCGCATGAACCCAGGAG +GCAGAGGTTGTAGTGAGCCGAGATCACTCCACTGCACTCCGTCCAGCCTGGGCAACATTC +CTTCTGTGTTCTGGGATATATATTCTTGAGGGTATTCCCATCTGTGGATAGTTGCCAGTT +AGATTTCTGTGGTGGGGAAGTGGAGCTAGAGTATTCTTTTCCTTTTTTTTTGAGACAGCA +TCTCACTCTGTCATCCACGCTGCAGTGCAGTGGCATTAACATGGCTTCATTGATCTCTTG +AGCTCAAGTGATCCTCCCACCTGAGTCTCCTGAAAAGCTAGGGCTACAGGCATGCATCAG +CATGCCCGGCTAATTTTTAATTGTTTTGTAGACATGGGTTCTTGCTGTGTTGCCTAGGTT +GGTCTCGAACTCCTGGACTCAAGCAGTCCTCCTGCCTTGGCCTCCCAAAGTGCTGGGATT +ACAGGCGTGAGCCACTGCTCCTGGTCTGTTTCTTTTGTTTAGTATTTTTGTTTGCTTTGT +TTCATGAGCTGCTATTTTGACTACAGTTTTAATATTTTTAGCAATTTTTTGGATATGCAG +AAATTTAATTCTTATTCATCAAATATATTTTAGTATTTTGTGTGTTTTTTAGATTTCCTT +TTTTAGGAGTCTTTCCAACCATAAACTGCCAAATAGAAATACACACACACACATACACAG +AGGCTATGAATAGACAACTAATTGAAACAGAAAAAAATTGATTAATTAAAGCACCTATGG +GATTTTTCTCCAGCCAAATTAGCATTTTTATTTAAAAAAATCTTTTAGTGTTATTTAGCC +TACATAGGAAGAGGCTTACTTATGTAGTTGATAAGAGTGTGAATTGATCAACTTTTTGGA +AAATAATCTGCCAGTATAATTAAAATTATAATTAAAATGTATCATAGGTCAGTTACACCA +CTTTGAGAATCCTATACTACAGAAAAGAAGAAATATAAAACAAAAACATCAGTGGGATCC +ATGTATATTGATGATTATTGTAGTCATCAGTGGTGGGAATTTTTAAAAACAACCTTAATA +TCCATCTAATAGGGAATAAAGAAATCAGAACTTATCTACAATGCGCATTACTACACAGAA +ATTCAAATGATACATTTGATCTACATTAGCTGGAATTAGTAATGTCCATGTACTCTAATG +GGAGAAAGAAAATTACTAAATAATGTAAGATTTGAGCACGTTCTTTAAACAAAACAAATC +AATAAAGCCCTAAAAGGACATACTATTGAAAGCAAGTCACAAAATCCAGAAATGGCAGGG +AAAATGTTCAACAATTTGACTATGTAAAAATGAAAGTTTCTTCAAAACAAAGATAATATA +AACAAAATAAAAGTTATGATACAGACCTTAAGAAACAAACTTGCTAATTATATGGAATTA +ATAAATGTGCAGAATATATAAAGAATATCATTACATGAATTAGAAAACTAGTAAATCATA +ATGAAATTCTCAGCGAGAAATACAATTGGCCAGTAAACATATGCAAAAATGCACAATCTC +TCTAATAAGTGGAGAAATCCAAATTAAAAATGGAAATATTTCTTAATCATAAAATTGGCC +AAGGTTAGCATTGGTCATTTCCTCTGTAACTAAGGGTGTGTGGAAATAGGAACTCTCATA +TACTGATGGTGGGAGTATAATATCATTAAATTTTTTTGAAACACAGATTTTTAATTTTTT +ATCAAAATATGGCCAGGTGCAGTGGCTCACGCCTGCAATCCCAGCACTGTGGGAGGCCAA +GGCAGGCAGATCATGAGGTCAGGAGATCGAGACCATCCTGGCTAACATGGTGAAACCCCG +TGTTATTTGTAAAAATACAAAAACAAAATTAGCTGGGTGTGGTGGTGGGCACCTGTAGTC +CCAGCTACTTGAGAGGCTAAGGCAGGAGAATGGCATGAACCTGGGAGGCTGAGCTTGCAG +TGAGCCAAGATCACACCACTGCACTCCAGCCTGGGCAACAGAACGAGACTCTGTCTCAAA +AAAATAATAATAATATTAAAAATTTATACTTTGCCTCAGTATTTTATTTTTAGAAATCAA +TCATAAAAGAAAAAACCCACCTAACTAAGGTACCAAAAAGATGAATATACAGGTATGCCC +AGGATAGTGTAGGTAACGGTAACAAATAACTGAATCCAACATAAAAATTCCACAGTGAAA +AAGTGACCAAATTATGGTCAGATACCCTGTTGAATAATGATGCAACTATAAATAAGAATG +AGAGAGACCTATATGCACTCATAAGCAATGATCACCACATTCTATTTTATATGGAAAAGC +CAGTTAGGGAACAACACACAAAGCAGGATTACGTTATGTAAAAACATGGGCATGTCTATC +TGTGTGTAAGTGGATGTAGACGACTGAGTGGGCTGGGAGCTGGCGGTGACACATTTCATT +CTACAGACCTAAGCAGTATTTGAATTTTTATAACAATAGCATATGTGTTTCTTATGTGAT +TTACTAGAAACAATTTAATTTCTTCAGTTGTAAAAGGTGTATTTTAAACCTATATAAAGG +TACATGGAGATCGTCATTCAGAATAACAAAATAAAAAGCAATATAAAGACACAAATAGAT +ATAGTACAATATTAAATACTACAATATTCAAGATGATATTAAAATTATATATATCTACAT +CTATATGCATGTAAGGATCTCAGTAAATGATATTGTCTAAAATTAAACTGTGGTAATTTT +TGCAGACCTCTGTGAATATATTAGAAACCATTGAATTGTGTGTACACTGTGTGTGGGTGA +AATTTATTGTATTTGAATTATATCTCAAAGTTCTGTTAAAAAATGAATGGCTTGATATTC +TAGTGCTAAGGGATGGTTTTATTTAAAACATAAACTAATAGTTTCCAGCAGAGTCCCTTA +AAAATATTACAGCAGGGATTTCCAGATCACACTCACTCCCACCTTTTTAGAATTTTTGAC +TATTTTCCAAAGTATTGAATTCAATGAGGTGCAGGTGGAAGAAAGCGTTTACAAAGTCAG +TGGGTTACGGGAGAGCTGGTGTGGGTTGAGGCAGAGTGGGGAGAGAGGCTCCTTTCAAAT +GGAAGCCTCTGGAACCCACAGACGGCAAGCGTAAGGCAGGGCAATCTTCTGGAGACCTAC +CAGAGAAAGGCTTTAGACCCAACACTCCCATTCACAAACATGGACAGGGGCATCTCAGTG +TTTCCTTAACTTCACTCTTTCTATATTGACACAAGGAAATAATTAAAAGGGGGTAATTCT +GGTTTAGTTTATTTCATTAAATTATCAACAAACAACTTTTGAAACAAAAACTATTAAAGT +GGAACTCAATAAAATTACTAGGTTTAATAATCTGTATCTGTGACTCAGATACAGATCAGG +CAAACCAGCTGTGGATGAAGCTCCCAGCTGTGGATGATGCCCCCAGACATGGATGAAGCC +CCCAGCTGTGGATGATGCCCCCAGATGTAGATGAAGCCACAAATGATGCCTGTGTGGACA +GACAGAATGATGGACAGGCAGATGAATGTGAGGGTTTTATGTGAAACAAGTCCACTTGGT +TGTTGACAAGATGCTGTTTTAAAGTTTCATTTTGCCATACTTTGAATAGCTTTTCATTAG +CTAAATTTAGCCACATGTAAAATCACTAAGGCAGACACCTGGAGTTCCCATATGAAAATC +AAATGTAAACCAGCAGTGACCTACTTCAATGTGATCATCGGAAGTCAGAAGTTGAGCTCA +TTTTTGATGTTTAAAGCCTGCATAATATTCACTGTGTTATTATTCAGTGTATTACTATTT +CCTTCATGATGGAAATTTGGTTTGCCCCAACTTTCTATTCTATCAAAACACTGCTACATA +GAAAATCCCCATGCACATATTTCTCCTAATTGTGGAAATATTTTACATAAAAGACTCTAG +ACATGGGATGAAATTCCCAGGTTATTGGAATTTTAAAATAGATAGGTACTCCCAAATTGC +CGTCTTACAAATTATATGAATTCGTAAGCTTCCAACTGTTATGGAGTTACCCATTTTGAG +AAATCTGTGCTAAAAGGACCCAAACAATGCTGATGACAATGATCAGGATAATAAGTACGC +TGGGAAGACAACAAAATGATTTAAATCTTAGACAAGTCATTCTAGGTGTCTCCACTGTTT +CAGTTCTTGCATTCATTCTTGTGGTATCTTTTCCCTTTTACCAATAAAAAAGCTCCCTGA +CATCACATTGTGGCAGTCCCCATGGTTTGCCGCAGTTACTGCGGGACTGAACGAAGGAGG +ACGAATGAAGAAATGAAAACCAAGGAAAAAAGGAGCTGTTTAAAGAAGGGTCCAGGGAAG +AAGAAGAGGGCTCCCAGCTTCTAGTGAGCAAGGGCAGCAGCCCTGAGCTTCTACAGCCCT +TCATATTTATTGAGTAGAAAGAGCAGGGAGCAGGAGGTAATGATTGGTCAGCTTCTCAAT +TGATCACAGGTTCACATTATTGCTAACAGGTTTCAGATGTGCCTAATCTCAAGAAACGCC +GCGCCTGGGGCATGACTGCCCTCAGCATTCCCTCTGGGTGGCAGACGCAGTTTGCCAACA +TTCTGCATTCATGAGAACAGTTTACTGTTTACTCATATAACCTCCAGTGGTACACCGAGT +TGATCATGACCCTCCCTCTTTCGGCCTGCAACATCACATGAATCCAATGAGTATTGGTTA +GTAAAATGCCTATGACTAGTCATCTTCATCTATGCAATTAAATATTAATTCATCAAACAC +TTCAAATGTAAGCAATTAATAATTAGTGAATGAAAAATACATAATACATCAATTAGAAAA +AAACTCTATTAAAAAGACATTTGTGTGATAAAAGAGATTGCCATTTTTGTATTTTTCTAC +AAAGTTAAAGAAAACTAAGTCAGCTTATATAAGTGAATTTTAAAAGCCTTTAGGCCAGGC +ATGGTGGTTCATGCCTGTAATCCCAGCACTTTGGGAGGCCAAGGTAGGCAGATCACCTGA +AGTCAGGAGTTCGAGACCAGCTTGGCCAACATAGTGAAACCCATCTCTACCAAAAATACA +AAAATTAGCCAGGCGTGGTGGCAGGTGCCTGTAGTTCCAGCTACTAGGGAGGCTGAGGCA +GGAGAATTGCTTGAACCCGGGAGACGGAGATTGCAGTGAGCCGAGATGGTACCACTGCAC +TCCAGCCTGGGCAACAGAGTGAGACTCCATCTCAGGAAAAAAAAAAAAGGGCATATATAT +CCATTATTTCACTGGGCCTTCACACAGCCCTGCTAGTCAACCCTCGAGAATTGAGGAATC +AGAGAACTTAGGAACAAGAACATGACCTGGGACTTCTTATGTAAGTGAGAATCTTAGGCT +AAATTGTCTTGCGGTAAATGCCTTTCCCATCCTCAGAAGTCTATAGTGAGCAGAAAGCAG +TAACAGCATCCTCCCTTCCACTCTTCCCTTCAGGCTGAACACATCCCTGTCCCTACAGCC +TTTGCAGAGACACAGGTGACAGAGCACTCAATATAGAATCCCTGGGCTCACACTGGCTTT +CCTACAGACACAGGGGATCCATGAGGCCCACAGTGACATACACATGTACACAAGGATGCA +CGTACTGACACTGATGAGCCCTGGAAGTCAACACAGAGTGGCATACAGAAGAACACATGC +AGGCACACACACAGCCACAACTGGACCTGCGAGGTCTACAGCCCCACAAATGAAAAGAGG +TGCATACCATCTCACAACAAACTAGAACTTTGAGAGAACCACACACACACACAGGTCTAC +AAATTCACCTGAACAAGACGCCGTCCATAGTCACTGGCGTAAGGCATCTACTCACTATCA +CACAGAACACACTCAGGCAAGCAGACATAGATGATACATCCACAATCTACAGAGATGAAC +TGCAGAGTTACATGCACAGATATGCCAGTCATACATTCAGATCTGTGTAAACAGTGAGGC +ACACACACACATACACATGTGCACTTATACAGAAAGACTCAGACCCAGCCAGGCATGGTG +GCTCAGGCCTGTAATCCTAGCACTTTGGGAGGTCGAGGCGGGTGGATCACGAGGTCAAGA +GATTGAGACCATCCTGGCTAACATGGTGAAACCCCATCTCTACTAAAATTACAAAAAAAT +TAGCCGGGTGTGATGGCGGGCACCTGTAGTCCCAGCTACTCAGAAGGCAGAGATTGCAGT +GAGCTGAGATTGCGCCACTGCACTCCAGCCTGGACAACAGAGCGCGACTCCATCTCAAAA +ACAAAAAAAGAAAGACTCAGACCTGACCTGTTAGTCAACAGCCAGATGCCAACAGATAAT +CACATTAGACTCATCAGCAAGCACACCGTGCACACAAGTTCCACTCCCATGTACAGGTTC +CTGTCCCATGTACACAAGCCTGCACACAAACACGTATCCAGACTCCAGAACTGTTGAGAC +AGTGCCCACATACACACTCATAGAGTCACCTGTGCACAGGTGCACGTACACATTGTTTCA +CAGAGGCACACCAGGACAGAAACACATAAGAAATGTGAGGCAAAAGCGGACCCACACCTA +CACCTGTAAGATACACAGAGAAACAAACACATACACAAACTTACACATAGACTCATGCAC +TGTGTAATCAACAGTTCTATACCCCACCAAGGCTCTTGTCCTGGTGTGTCCAGAATTGGT +GGGTTCTTGGTTTCACTGACTTCAAGAATGAAGCCACAGACCCTCGTGGTGAGTGTCACA +GTTCTTAAACGCAGCGTGCGCGGAGTTTCTTCCTTCTGGTGCGTTCGTGGTCTCGCTAGC +TTCAGAAGTGAAGCTACAGACCTTCGCAGTGTTAACAGCTCATAAAGGCAGCGTGGACCC +AAAGAGCTAGACACAAAAGTTCTCCACGTCCCCACTAGATTAGCTAGATACAGAGTGTCC +ACTGGTGCATTCACAAACCCTGAGCTAGACACAGAGTGCTGATTGGTGCATTTACAAACC +TTGGGCTAGATACAGAGTGCCAATTGGTGTATTTACAATCCCTTAGCTAGACATAAAGGT +TCTCCAAGTCCCCACCAGAGTAGCTAGATACAGTGTTGATTGATGCATTCACAAACCCTG +AGCTAGACACAGAGTGCTGATTGGTGTGTTTACAAACCTTGAGCTAGATACAGAGTGCCG +ATTGGTGTATTTTCAACCCCTTAGCTAGACATAAAGGTTCTCCAAGTCCCCAGCAGAGTA +GCTAGATACAGTGTCGATTGATGCATTCACAAACCCTGAGCTAGACACAGGGTGCTGATT +GGTGTGTTTACAAACCTTAAGCTAGACACAGAGTGCCCACTGGTGTATTTACAATCCCTT +AGCTAGACATAAAGGTTCTCCAAGTCCCCACCAGACTCAGAAGCCCAGCTGGCTTCACCC +AGTGGATCCCGCACCGGGGCCGCAGGTGGAGCTGCCTTCCAGTCCCGCGCCGTGCGCCCG +CACTCCTCAGCCCTTGGGTGGTCGATGGGACTGGGCGCCGTGGAGCAGGGGGCGGCGCTT +GTCGGGGAGGCTTGGGCCGCGCAGGAGCCCACGGCGGTGGGTAGGCTCAGGCATGGCGGG +CTGCAGGTCCCGAGCCCTGCCCCGCGGGGAGGCAACGAAGGCCCGGCGAGAAGTCGAGCA +CAGCAGCTGCTGGCCCAGGTGCTAAGCCCCTCACTGCCCGGGTCCGGCTGGCAGCTCCGA +GTGCGGGGCCCGCTGAGCCCACGCCCACCCGGAACTCGTGCTGGCCCGCAAGCGCTGCGC +GCAGTCCCGGTTCCCGCCCGCGCCTCTCCCTCCACACCTCTCGGCAAGCTGAGGGAGCCG +GCTCCGGCCGCAGCCAGCCCAGGAAGGGGCTCCCACAGTGCAGCGGTGGGCTGAAGGGCT +CCTCAAGCGCGGCCAGAGTGGGCGCCAAGGCCGACTAGGCGCCGAGAGCGAGCAAGGGCT +GTGAGGACTGCCAGCACGCTGTCCCCTCTCACTGGGTTGCTATTAAAAATGGGCGCTGAA +TATAAAAATTAACCGGGCGTGGTGGTGCATGTCTGTAAGTCCCAGCTACTCCGGAGGCTG +AGGTGGGAGAATAGTTTGAGCCCGAGAGACTGAGGCTACGGTGAGCCGTGATTGTGCAAC +TGCACTCCAGCCTGGGCGACAGAGTGAGACCCAGTCTCAAAACAAAATCAAACACGGGCG +CTGCCCTGGGCAGGGGAGGTCTGGGCACAGCTGTGCTGATGTGGGCAGTGGACAGGTGTC +ACGTGAGAGCCTGTGGCCAAGCCTAAGCTGCGGTTAAGGTGGGAGGCTGAAGGGTTTGGA +GTGTGCACCACCCCGGACCACCTCTCAGTAGGAATGTGGCAATGCACTTCGGTGCTGGAT +TCCTACTTCTGGCTGTGTGATTTGCGACACGTTACCCCACGCACCTGTACCACAACTTCC +TCATCTCCCAAATGGGATGACAGTAGTTAGCAAACCTCCCTGGACTGCTGTGAGCATTCT +GCCAGAAAAATGTACTCCAAGCTCTTGAAGTAGGCCTGGCGTTTGGTTGGTGCTCAGTAC +ATATTCAATGTTTCTGTCGCTGGCGTCATCACTGTGTTCATGGCAGAGCTCTGTGCCGCC +AGGACTGGGCCGCCACCCAGACCTTCCTTTCCCGCCCCAGGGGTGAACTGTGGACAGGAC +CCTCTGGGGGGACTAGGCCAAGGCTCTCCCACCTCTGGGGACCCGCGCCCATGGGCCTCA +GATATGTGGCTCGAGAAGGGGGAGTGGGGGCAGGGCCCCTGGAAAACCCCTCGAGGCCAG +ACCCACCACTCCCAATATCCGTAAGACCAGGGGCTTGAGTCTTTCCTGCAGACAGATGTG +GGCAGGAACCCACCCGACTCCCAGCTACGTGGGGACGTGGACGAACTAACAGGACAAATT +CTAGTTCCTGGACACCGCCCTCCCAGTATCCTCGCAATTAGACACCCATGCAGCGGCACT +ACACTGATCCGCACACGGAGATACACAGCGACATCCGCCCGCAAGAGCATGGTGGGTGCC +GGAGCTCCCGGCTGTGGGCCCAGGAACTACATTTCCTAGAAGGATGTGCTAGATACTCGT +TCGCGTCGGGACGCAAGCACCGGCCCGAACTCGCTCTAGGAAATGGAGTCTGACGCCTGC +GCGGCGCAAACGCTCCCGGGAGGTGTAGTTTGCGCCTATTTCGCGCAGGCGCGCTTTCCC +GCAGCGGCCGCCTGCTGCTCTTTGTGGCAGTCGCAGTCCTTTTGTGGGAGTCCGGTCTGT +CCACTTGCCGGTCCCTCAGACCGTCGGCGGTCTCTGTCCGCTTCGGGACCTGTCCGCTGG +TCGCTCCGCGTCCGATGGCTCCTGGCCGCGGAACCTTAGGCCTGGCCCTGGTCTCCGAGC +GCGGGTTCGCCGGGAGGAGCGTGTGGCGGGGGTGTGCCGGGGCGTGAGTGCGCCGAGCAT +GGGGCTGAGCCTGGTGTGGGGAGTGGGTATCTGCGGAGCCGGCCTGAACCCCACCTCAGC +CGGGCGCGGGGAGGGGGCTCCGTGCGTGTGATCGTGCAGCTGTGAGCGCGTGGCCGCCCC +GCGGGGCTCCGCTGCAGGCCCCTCAGCCCCAGGAGCAGTACTCGCTCTTCAGGGCCTGCC +CTGGATCCTGGAGGCTACACAGCTGCCCACTCCTCCTGGGGAGGCTGCCGTGGAGGCCAT +GGAGATCCCTGCCCCGGAGCCCGAGAAGACAGGTACAGCTTCACTCTTGTAGTCAGTATG +TCTGTGGATTTGCACTTGAGGATATTGACACTCAGAGAGATCAGGCCAGTTTCCCAGAAG +CATCCAGCATCTTTTTTTTTTTTTTTAAATGGAATCTCACTCTGTCACCCAGGCGGGAGT +GGTGCAATGGCTTGATCTCCGCTCACTGCAACCTCTGCTTCCCGGGTTCAAACTATTCTC +CCGCCTCAACCTCCCAAGTAGTTGGGATTGCAGGCGCGCGCCACCACGCCCGGCTAATGT +TTGTATTTTTAGTAGAGACGGGGTTTTGCCATGTTTCCCAGGCTGGTCTTAAGCTCAAGC +GATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCATCGCTCCTGG +CCTCCTGCTTCTTTCTTCCCCGCGCCCAATCATTTGTTCCCACTCAGACGTGCTTGATTG +GGGGTAGCAGCTCTTTTCGTCATGAATTGGAGTGTCTGAGACACAGGCAGATTATTCCTC +GATGCTGTTTCTGTTGGTGCTAGCTACTGGGGCTCGTTCCCCACCTGGCCTTGCTGGCAG +GTTCTGCCTCCTCTCTGATTCTCACTTGTGCCACGACAGGTGGGCTTTAAGCTCAGCCGT +GAGCCTGGTAGCCGTGACCTTGACTCATTTCTCCTTCGCCAGCTCTTTCCTCTCAGGATC +CTGCTCTTTCCCTGAAAGAGAATCTCGAGGATATATCGGGTTGGGGTCTTCCCGAAGCCA +GGTCCAAGGTGAGTGGCTGTGTGTTCTTCCTTCTTTATGAAGAGGGTTGGCACATTCCCT +CCCCAGCCCTGGATCGTCAGCCTTCCACAGACCTTCACCCGGGTACCTGCTGGCCAGTCC +TCAGGAAGCTCTGGGCAGTGGGAACAGCTCCAAGTGAAGAGTCCAGATGTTGCCCGAGGT +GTGCCCTCGAGATGTGCTCTATTGAATGTCTCGCCCAGTCCAATTCAGTGGGTCAGTTGC +TGGGGATCTCTCTGCCCAGCGCTGTGCTGGGAGCTCTGAGGAGTGGTTTTAGTGGAATCT +GAGAAAGTAGTTGACGGCTCACATGGGGTCGCTTTGCCTATCCACGTGCTGGCCAGGGGT +TGGTGCAGGATGTTTGCACGGTTGGTTTACTGGGACTGGAATCAGACAGGGGCACGTGGA +GCAGCTCAGGAAGGGCTGGATTGCAGCACTTGGTTAAGAGTGGCGGTAGGGGACACATCC +CTGTGTGCTTTCCTCTGTACCCAGCCCCTGGCATGGGGCCTTCATGGAGAGTCCTGGAGA +TTTAGAGAATCTGGGGGCTCAGCAAGGAATTGGCCCTGGGAACTTCTGCAGCCAAATGGG +ACCCAGATCCCTCCTTTTACAGACTGTGAACTCTGTTCCTCATTTTGTTTTTCTACCGCA +ACCACCTCACCCCATGGTTGTATTTAGAAGGGTGCAGTTGACAAAGAGAGCACAGTAGAG +TGAAAGATGTGGAGGAATAAGGGGTCTTTGGGTTTTTGTTTTTTTTTTAGCATTTTGTGA +TTTTGTCAGTCTGCCACTCAAAAGAGGTGATGGCAGATTATAGCCAGCTAGAAACAGCTG +CAAAACGTGTATTGTGAGCTGTGCCTCACTTCTGTAGTGTGTCACAATGCTTTATAGTCC +TCAAGAAACTTGACAGTCAAATGCAATGCATGTTCCTTGCTTAGGGGATAGATCCAAAAA +AATTGATAAAGGGCAGTTTGGGACAAGAGGAAATTTGAAAATGGGCTGTATCTTAGGTCA +TATTGTATCAATATGAAATTTATTGCATGTGATAATAGTACTGTGATTATGTAAGAGAAT +ATCCACAGGAGATACAAGCTGAAGACTGTAGAGTGAGACATCATGATGTCTGCAACTTAC +CTTCAAATGGTTCAGCAAAAAAAAATGTGTGTGCATGTATGTATGTCTGTATGTGTCTGT +GCAGCTCCGTCTAGGTGGTAGGGCCCTCATGCATGTGTTATTCCTATTCCTAAAATATTA +GCTTGTTAGATCTTTGAATAACCAGTTGACTCTCCTGAGTACACATCAGCTTTGGCATTT +TCTCTTGACAGTCTCATTCTCACTCACAGTTCAAGTTGTTCTGTCTCCTGGGACATCTTG +TGTGGTCTGTTCTGACTTCTCTGCTAGTGTCATTACCACATCAGCATCTGATTCCAATGC +ATACTGTCTGGGTTTTTTATTCCTTTCCCTGCAGAATGATGACACATTAGACATGGACTT +CTCCCAGTGGCCAGAAATACCCATCAAAAAGGCCTGTGCGGGCCTCAGACCCTACCCTAC +TCTTGCTGGTTTTGCTCCCCACACTGAAGCCATGTAGCCTCTGACAGCCTCACTGGCCAA +CACCATATTCTGATACCTGTGGAGCTATTTTTTTGTTTTTCTTTCTTTTTCTTTTTTTTT +TTTTGAGACAGAGTCTTGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCACAATCATAGCTC +ACTGCAGCCTTCAACTCCTGGGCTCAAGCAAATCCCCCACCTCGGCCTCCTAAGTAGTTG +GGACCAACGTGTGTGCCCCCACACCTGGCTTGGAGCCTTGTTTCAGCCCATTTTCTCCTT +CCCTCGGCTATCGTCATCCTTCATGCCTGCATGCCTCAGTTAGGGGTGTGTTCTCAGCAT +TTGTCCTCATCTCTACCTCCTCATCTGAAATCCAGTGTTTTGGGGGGTAAGGTTTTATTG +AGGTGTAATTTATATACAGCACAGTTGTACAATTTTAAGTATACAATTTGATGAGGTTGA +GCAAACGTATACAGTTGTGTAACCAGCACCACAATCATGATATGGGACGTTTCCATGACC +CAAAAATGTCCTCATGCCCCTGTGCATTCAGTGGTCTCCCCTCTCCCCTTGGTAACCACT +ATAGTTTTGCTGTAGATTTTCCTCTTTAAGGATTTCATATGGAATTTATATTATGTGGTC +TTTTGTCTCTGCTTTATTTCGCTTAGCATATGCTTTTGAGTTTATCCATATTGTTGTGTG +AATCAGTAGTTTGTTCCTTTTTATTGGTGAGTAATATTCCATTTGTATTAGTCTGCTAGG +GTTGCCATACAAAGTATGGCAGGAGGGCTTAAATGACAGAAATGTATTTCCTCACAGTTC +CAGAGGCAAGAAATCTGAAATCAAGGTGTCAGCAGGGTTGATTTCTTCTGAGGCTTCTCC +TTGGCTTGTAGATGGCCACCTTTTCCCCGCATCTTCACATGGTCTTACCTCTTCTATGTC +TGTGTCCAAATTTCCTCTTCTTATGAGGACACCAGTTATATTGGATCAAGGCCCACTGCA +TTGAATTCATTTTAACTGAATTACTTCTTTAAAGAACCTCTCTCCAGGCCGGGTGCAGTG +GCTCACGCCTGTAACCCCAGCATTTTGGGAGGCTGAGGTGGGTGGAACACTTGAGGTCAG +GAGTTCAAGACCAGCCGGCCAACATGGTGAAACCCTGTCTCTACTAAAAATACAAAAATT +TAGCTGGGCGTTAGTTCTCGCCTGTAGTCCTAGCTACTCAGGAGGCTGAGGCAGGAGAAT +CTCTTGAACCCAGGAGGCAGAGGTTGCAGTGAGCTGAGATTGCACCACTGTACTCCAGCC +TGGGTGACAGAGTGAGACCATGTCTCAAAAAAAAAAAAAAAAAAAAAAAACCTCTCTCGG +AGTTACCAAGCATTGAGACATAAGAATTTGAGGTGAGGGGTATACATTTCATCCCATTGC +TCCATTGGATGGAGCAAACTGCTCCGCAGTTTGCTTATCCATTCACCAGCCGATGGACAT +TTAGGTTACTCATAGGCTTTTGCTATTACAAATAAACCCGCTATAAATATTTGAGTACAC +GTATGGCTGTGCATTTTAATTTCTCTTGCATAAATACCTAGGTGTGAAATTGCTGAGCCA +TATAGTAAATATATGTTTGTCAATTTTATTGATCTTTTCAAAAAACAATTTTTTTGTTTT +ATTGATTTTTCTCTATTTTCTGTTTTCCATTTCAGAGATTTCTGATCCTTATTATCTCCT +TGGTGTCTTAAGATTGAAACTTACTTTACTTACTTTAGTGTCTTAAGATTGAAACATAGA +TATTGATTTGATACCTTTTTTCCTCATATAGCATTCAGCGTTGTAAATTTCTAAGCACTG +CCTCAACTATATCCTACAACTTTTGTTATGTCACATTTTCACTTTTATTCAGCTCAAAAT +AGCTTCTAATTTCCCTAGTGATGTATTCTTCAGCCATATGTTATTTCAGAATGTGTTGTT +TCATTTCCTAATATTTAGGGCATTTTCCAGATAACTTTCTATTATGGATTTCTGATTTAA +TTCTATTGTCATCAAAGAATGAACTTTGTGTGATTTAAAGTCTTTCAAGTCTACCAAGAT +TTATTTTATTTCCCAGAGTGTGGTTTATCTTGGTAAATGTTCCACATGCCCTTGAAAAAA +TATGTATTATGCCTTTGTTGGTTAGAGTGTTATGTAAATATCAGTTAAGTCAAGTTGAAT +GATGGTGTTTTTTAATTGTTCTGTCAGTTTTTGCATTATGTATTTTGAAGCTCTTTTAGT +AGATACATTTATATTTAGGATTGCTATGAGTTCTTAATGAATTAACTGTTTTATCATTAT +GTAATATTCTCTTTGTCTCTGATAGTCCTCTCTCTGAAATCTACTTTGCTATTACTATAG +GCACTTGAGCTTTTTTTTTTTAAATTAGTATTTGCAGGGTTTATCTTTTTCTATCCTATC +ACTTTTAACCTATCTTTGTATGTAAAGTGGGTTTCTGTAGCTTGCTTTTTGAATTCAGTT +TGACAATCTCCACCTTTTAATTGGAGTGTTTAAACTATTCGCATTTAGTGTAATTATTAA +TATGGTTGGATTTACATGTCCTTTTTTTTTTTTTCTTTTGACAGAGTTTGGCTCTTGTCA +CCCAGGCTGGAGTGCAGTGGCGCAATCTTGGCTCACTGCAACCTCCACCTCTTGGGTTCA +AGCAATTCTCCTGACCTCAGGTGATCTGCCACCTTGGCCTCCCAAGTGCTGGGATTATAG +GCGTGAGCCACCCCACCCGGCCTTGCTATTAGTTTTCTATGTCTTATGTCTTTTTTGTTT +CTCATTTCCTCCCTTAATGACTTCTTTTGAGGTAAACACATACTGTTCTAATATACTCTT +AATTCCTCTGATTTCATTAATATTTTTCACCTTTTAGTTATTTGATTGGATGCTGGACAT +TGTGAATTTTACTTTGTTGAGTAGGTTTTTGGAATTCCTTGTTTCTGGGATTTGTTCTGG +GATGCAGTGAAATTACTTGGCATCTATTTGATCCTTTCAAGGATCAAAGCAAGTCTGGAG +TTGGGTGGTGGCCAGGATGCCCAGGCCCAGGGGGAGCAGGCAGGAAGGATTGGAAGGCAG +TCAGGTGAGGACTGCAGGTAGCCTCTCTTAGTCCCTTGGGGCACAGAACTTGCTGATATA +TACAAGGTTTCCTTCCTTAGAGTGTAATAACAGTTTCTAGTCTGGGATCGGATCCTTTTG +CGTTACTGAGCTTTGAATAGAGTTGCTGGGATTTTTGTACTATTAATATTCTCTCAAATT +TTTAAGTTTGAAATTCTTGACTCCAGGAAGCATAGCATCTCACCCAGGACTTAGAGCCTG +ATACAACAGCCATGTACAGCCCCTGGGTCCCACCGCAAGTTGCCAGGGCCCTGTGGTGTC +TATTCAGACCTGCTTTCCCAATCTAGAAGGTGGTGTGGGAATGCATGCCAATTCCCAGCC +CCCCTCCCTGCCCCTGGTCCCCGAATTCAGTCATGGTCAGTGTCTACAGCACAACCTTCT +GGCATGGGAGAAGGTCACCTGAGGTTAACCCTTTACTTGTAGGGTCCTTAATCAATCTCT +GGCTCCTTTGGAACCATGGACACAGAATCAGTCCTGGGTGAGAACCTATATGTCATTTCA +GGAATCGGTGAGTTTCAAGGATGTGGCTGTGGACTTCACCCAGGAGGAGTGGGGTCAACT +AGACTCCCCTCAGAGGGCCTTGTACCGGGATGTGATGTTGGAGAACTACCAGAACCTTCT +TGCCCTAGGTAAAATCCCCCCAGCCCCAGGCTGGGCGTCGGCTGTCAGCCTTCTTCTACA +TGGTAGATATTAAGGAGAATCCCTTCAGTGCCGGCCCTGGTGCCAGATATATCATGGGGT +GGGAAGCAAGGCCTGTGCCTTGGGGCACTCATGGCCAGGGGCCTCGGCCACGCCAGAAGT +CCCCAAGGGACAGCGTGGGAGCTGGTAGCATCCTTGCTTGGTGTTTCCCCTGGTCCTGGG +ATAGGGGCAGGGAGAGAAGAGAAGAAGGTGGGACCCTGGAGCCCAGCTGGCTCTGGAACA +GTCCTCAAGCAATGAAGTAAGGACGTCAGCACACGTGGGGTCTTCAGAGTATACACTGGG +ATTTGGGTTCCAGTCTGAGACCCTCACTGCTTTTGGCCCAGAGGACCTCCTGTTCCCAGA +GAGGGTGTCCACTTCACAGGCATTGTCCTTGTTAGGGGGCGGCCTGTAAGGTCGACTGGG +CCTGGAGAGCTGCAGCATGCCCAGCCCACTTTCTCTCCACGAGCAGGACCTCCACTGCAC +AAGCCAGATGTGATCTCTCATCTGGAACGAGGCGAGGAGCCATGGAGCATGCAGAGGGAA +GTCCCCAGAGGGCCCTGTCCAGGTGAGCAGAGGCACAGGTGGAAGGGTGCCAGCCCCAGC +ACCCCTGGTGGCACCTCCTCCTATGGCCCCTATTTTCCTCCCTCAGTTTGCCCCGGCTCC +ATCTCCCCTTTTCAGGTCCCCCGCCAGACCCTCCTGCCTGCCTCCCTTCAGCACGTACTG +AGCACTGCCTGTGTGCTGAGACCTGTTCTGGGATACAACAGGGAACAAACCTGGCCACTG +GGACCAAATGGTCACCTGCTGATGGGGATGGGGAGGCAGGAATAGAAATATTGAGCCATT +GGTGTTGGCTGGGCAGCCGGGGGTGTGGGATTGGGGGCAGGGGGCCACCAGGGAAGGGGC +AGCTGGCGTTGGTCAGTGTCAGGGTCAGCATGAGCATCAGCATCAGGGCCAGCGTCAGCG +TCAGGGTCAGAGCCAGCATCAGTGTCAGGGCCAGCGTGAGCATCAGCATCAGGGCCAGTG +TGAGCATCAGTGTCAGGGCCATCATCAGCGTCAGGGTCAGAGTCAGCATCAGCATTAGGG +TCAGCATCAGCGTCAGGGTCAGGGTCAACGTCAGCGAGGGCTTCCAGGCTGTGGCCAAGA +TGGCAGCCCTCCGTAAGGGAAAGGGGACTGGGGTGGGTGTTGAGCAGAAGGTAGTCTGCT +TTTCTTCTCCAACATTCTTTTTGTAGACTTCTCTTCTGAGTTGGTTGATAAATAAGTGGT +AAATTCGGCTTAATTTATTGGACAGTGACTGCTGAGCATGTTAGGTGTCTAGAAAGCTCG +AGAAACACCTTTCTGTGGGAAAGGCAGCCGATAAGCTGTGGAGCACAGAACACGGGGGTC +GGGGAAGGCAGCCCCTCCTCCATCCCCCTCCACTGCCACATACCACCCAGCCCCAACCTG +CAACAGTGGCTGCAGCCCCAGCTTTCTGGTCTTTATTTCTCACCCCAGCCTCTGATGCTT +GCTTTGTCCTCTTTAACAAGATTACAGGTTTCAAAAAATTCATATTTTTGTTTGATTCAT +ATATGAATATACTGAAAATGAGGCTGAAAGGTTACTGAAATCCTGCATAATCTTTCCACC +CAGAGATGACGGTTCTCTAATAACTGACCATGTCACTGATTCCTCTGGGCCCTTCCTCTG +TGTGCGGATAGACTTCTAAAGCTACATGTGGCCAGGCGTGATGGCTCACACCTGTAATCC +CAACACTTTGGGAGGCCGAGGCAGGCAGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT +GACCAACATAGAGAAACCCTGTCTCTACTAAAATTACAAAATTAGCTGGGCATGGTGGTG +CATGCCTGTAATCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCAGGAG +GCAGAGGTTGCGGTGAGCTGAGATCGTGCCATTGCACTCCAGTCTGGGTAACAAGAGTGA +AATTCCATCTCAAAAAAAAAAAAAAAAAAAAATTAGCTGGGCGTGGTGGTGAGCACCTGT +AATCCCAGCTACTCTGGAGGCTTAGGCAGGAGAATTGCTTGAACCCGGGAGGCAGAGGTT +GCAGTGAGCCATGATCGCACCATTGCACTCCAGCCTGTGTGACAGAGCTAAACTCCATCT +CAAACAAATAAATAAATAAAGCCTTATGCACCCTCGGAAGCACAGCACTCACGCCGGAGT +CTGGCTACCACACTGGCCATGGCATAGTGAGCGTCCTCACGTGATGTTTACTGATTGCAC +AGTATCCCTTAGATGAATGTGCCCTGCTGTGTTGTTGGCCCTATTGCTGCCAAAACAACT +TTTTTCTGGCCTGGGCCTCTTCTCTCTGCTCTGTGCAACTTCCCTAGACTCTTACCTCTC +ACTTGGTGTGGATGTGGTCTACACTATAGCAACACCAGCTGAGCTGCAGCCCTGTGTCAC +TGACCATCTCGTGGGCCTCTGCTTGCATGTCTAAAACCAGACTTGGAACTGGCCCTTCCT +CCTCCTTTATAAAAGCTTCCACCATCCACCCAGGCTTGGGTGTTTGCTGAGGTCTCATCC +TCTCCCCCATTTCCTCTCTTGCCACCTTCAGTCAACAGCTAGGGCCATCAGTTTTAGCAC +CTAAATGGCTCTTAGATCTGCTGCTTCCTGTTCATTTTCACAGCCTTGGTTCCAGTCTGA +AGTTGCCATTTTTCACCTGAATTATTCAGATGGCCTCCCTAACTGGCCTCCCTAACTGCT +GGCTCCAACCACCTTACACACCACCAAAGCCACCTTCAAGACAAACCATTATGCCAGGCA +CAGGGACTCACACATCTAATCCCAGCACTTTGGGAGGCCAAGGCAGGAGGACCACTTGAG +CCCAGGAGTTGGAGGCTGCAGCGAGCTGTGATTGCACCCCTGCACTGCAGCCTGGACAAC +AGAGCGAGACTGTGTCCCCGCCCTCTGCTTCCCCCGCCCCCCGTCAAGACACCATATGAT +CACATCACCCTCTGTGCAAAAGGCCTTTCTTCCCCGGCTGCCCTCTGAGTCAGGCATCTG +GTCACCTCGAACCCATCCACCTTGCCAGGGTCACCTCTCAGCCTTCCTGCCTCTGCGTGT +CTTGTCTTCATCTTACTGTCTCACCTCTGAGCTTCTGCACATGCTGTTCACTCTCCACCT +GGCTACCTGCCATGTGTGCCATGGCCAGTTCCACTTGCCCTGCTCTTCTGCATGTGTTGG +GGCCACAGGCAGCACCACCATGCAGCTCTGCCCGCTGCACTAGACTGCTCCCTTTTAAGC +CTGGGGAGGACAGAATTAGAAATAAAATCTCCTGCCAGCTCAGAAAACCTTGCTATAGAG +ATAGAAAAGAAAGAAAGCCTTCTTATTGAATAAGTGTTTAACCAGATGTGGTGTACAGGA +GAGAAAGAAACCTCCCCCTTTGACAGAGGAGACACATCCAACCCAGCACACAGGGCAACT +GTCTTCACCTAAAGGAAGAGTACAGCTTTTTGGGTTTTGTTTGTTTGTTTGTTTTTTGAG +ACAGGGTATCCCTCTATTGCCCAGGCTGGGGTGCGGTTGCATGATCATAGCTCGAAGCCT +CAACCTCCCTAGGCTCAGGTGATCCTCCCACCTCAGCCTCCTGAGTAGCTGGGACTATAG +ACAGGTACCATCATTCCTGGCTAATTTTGTATTTTTTGTAGAGGGGTCTCACTGTGTTAC +CCAGGCTGGTCTTGATCTGGGCTCAAGTGATCCGCCACCTTGACCTCCCAAAGTGCTGGG +ATTACAGGTATGAGCCACCGCGCCCAGCCTCTTGTAGCTTTTTGACAAGCAGGAAGTTAC +ATCTTGGACTCGACTCTTGGACTAGGCTCATTTTGCTTCTGAAAAGGTTTGCATGCGTCT +CGAGACAGAGAAAGCATTTGCAATTCCCAGTGTTCTAAAGGGAAGCGCTGGGGTGTGGGG +AGCCCTTTTTTCCTTTTGGCACCACAGACAATTTTTAATTCATTTGTTAGTCCTAGCTAC +TCGGGAGGCTGAGGCCGGAGAATGGCGTGAACCTGGGAGGCGGAGCTTGCAGTGAGCCGA +GATCGCGCCACTGCACTCCGGCCTGGGCGACAGAGCGAGACTCGGTCTCAAAACAAACAA +ACAAACAAAAAACATGTATTTGTCCTGTGTATTGCGAGCACCTGCCATGGTATTGATACA +GAGCAGTCGGTCAGCCGACGTGTCCGTGAATGAGTGTAATCCTCATCAACAGCTCCCAAG +CTTGCCCCTTTCTCAGCCCCCTTGGTGCTTGTAGCTGTTCCTTCCGGGATTCCTTTGGCT +TCTCCGCCTCTCCCGGTCTTTGCTCTCTGGTAGCTCCTTCCGTGTTCTTCCTCTCCCTTC +TTCCCGCTCTTGCTTGCCCATCTCATCCTGGGCGCTCCCTTCTCTCTGCCTGCACCTTCC +AGCCTTGGCCCTGGTGGCCTCTCCTCTCTTTTCTGGGCTTATCTGCATCTCCAGGCCAAT +TCTCAAATCTGAATTCTAGGCCAGGTTTCCGCTTGCTCACAGAAAATCATTTTCAATATC +TTACAGAATGGGAGCTGAAGGCGGTGCCCTCTCAACAGCAGGGCATTTGCAAAGAAGAAC +CGGCCCAGGAGCCCATCATGGAGCGGCCCCTCGGCGGGGCGCAGGCGTGGGGGCGCCAGG +CAGGTGCTCTGCAGAGGAGTCAGGCTGCGCCCTGGGCGCCCGCACCTGCCATGGTCTGGG +ACGTCCCTGTAGAGGAATTCCCCCTCAGGTGTCCCCTCTTCGCCCAGCAACGCGTTCCCG +AGGGGGGACCCTTGCTGGACACACGCAAGAACGTCCAGGCCACTGAGGGCAGAACCAAGG +CCCCCGCGAGACTGTGTGCAGGGGAAAACGCCTCCACGCCAAGTGAGCCAGAAAAGTTCC +CCCAGGTGCGCCGGCAGCGCGGGGCGGGCGCCGGGGAGGGCGAGTTCGTGTGCGGCGAGT +GCGGGAAGGCGTTCCGCCAGAGCTCCTCCCTCACGCTGCACCGGCGCTGGCACAGCCGGG +AGAAGGCTTACAAGTGCGATGAATGCGGCAAGGCCTTCACCTGGAGCACCAACCTTCTGG +AGCACCGGCGCATCCACACCGGCGAGAAGCCCTTCTTCTGCGGCGAGTGCGGGAAGGCCT +TCAGCTGCCACTCGTCCCTCAACGTGCACCAGCGCATCCACACGGGCGAGCGGCCCTACA +AGTGCAGCGCCTGCGAGAAGGCCTTCAGCTGCAGCTCGCTGCTCAGCATGCACCTGCGGG +TGCACACCGGCGAGAAGCCCTACCGGTGCGGCGAGTGCGGCAAGGCCTTCAACCAGCGTA +CACACCTCACACGCCACCACCGCATCCACACGGGCGAGAAGCCCTACCAGTGCGGCTCCT +GCGGCAAGGCCTTCACCTGCCACTCATCCCTCACCGTGCATGAGAAGATCCACAGCGGGG +ACAAGCCGTTCAAGTGCAGCGACTGCGAGAAGGCCTTCAACAGCCGCTCGCGCCTCACCC +TCCACCAGAGGACGCACACGGGCGAGAAGCCCTTCAAGTGCGCCGACTGCGGGAAGGGCT +TCAGCTGCCACGCGTACCTGCTCGTGCACCGGCGCATCCACAGCGGCGAGAAGCCCTTCA +AGTGCAACGAGTGCGGCAAAGCCTTCAGCTCCCACGCCTACCTCATCGTGCACCGGCGCA +TCCACACAGGCGAGAAGCCCTTCGACTGCAGCCAGTGTTGGAAGGCCTTCAGCTGCCACT +CGTCCCTCATCGTGCACCAGCGCATCCACACCGGTGAGAAGCCCTACAAGTGCAGCGAGT +GCGGCAGAGCCTTCAGCCAGAACCACTGTCTCATTAAACATCAGAAAATCCACTCCGGGG +AGAAGTCGTTTAAGTGTGAGAAATGTGGGGAGATGTTCAACTGGAGCTCGCACCTCACTG +AGCACCAGAGGCTGCACAGCGAGGGGAAGCCCTTGGCCATCCAGTTCAACAAACACCTGC +TCAGCACATACTACGTGCCTGGCAGCCTGCTGGGTGCAGGGGATGCTGGACTGAGGGACG +TGGATCCCATCGACGCGCTGGATGTGGCAAAGCTCTTGTGCGTGGTTCCCCCCAGAGCTG +GCAGGAATTTCTCCCTGGGGAGCAAACCTCGAAACTAACATGATGTGCTTTGGTGTCAGT +AGCTGCTTTCTGAGCTACTCAACAAGGAAAGCACCCTGGTCCTCCCTGGCTCCTAGATCC +AGACCACCTTCCTCCAGGTGTGGGAGCCTTGCCTTATCACCCCCATCAGGTCTGCATGCC +AGGGTGCCTCCTCTAGTTAAAGTCAGTCACCTCCCCAGAAGGGCCACACTCCAGGAGGAG +TGTTGAGAGTCATTTGAGGTAGTCTTGCCACCTGTTTTCCTTGATGGGCCTGGAAGTTGT +TGACAAGGGGAAAGATCTTTCTTGCCAATAAAAAGAAGGGATATCGTTGGGTGCCATGGC +TCACACCTGTAATCTTAACACTGTGGGAGGCCAAGGCAAGGGGATCACTTGAGCCCAGGA +GTCTAGGACCAGCCTGGACAACATGGTGAGACCTCGTCTCTACAAAAAATGCAAAAATTA +GCCAGATGTGGCGGCATGTCCCTGTGGTCCCAGCTACTCAGGAGGCTGAGGTGGGAGGAT +CATTTGAGCCTAGGAGGTCAAGGCTGCAGTGAGCCATGATTCACAGCACTGCACTGCAGC +CTGGGTGACAAAGCAAGACCCTGTGTGAAATTAAAAGGAGGTATATCAACTGTTGTATCC +TCGGACGGGCTCCTGACACGGCTTTAATCAGGAGTTTCCTCCATAAACTATTATTTTCAG +AATAATAATAAAACAAGAATTATGACTAGCATCACTTTCCAGTGAACATTATTATATTGC +TAGAGAGGAGAATAATCTTGGGTGGTGGGCATTTGGAAAAAGTGAATTTCCTGGACTTAA +CTCATGTAAATAGCTCTACTGCAGAGCTGTGTGTTTAGTGACAGTGCAGTCAGGGGCATT +CCCACAGCTGTCACAGCACGGCCCAGCATCATTGTAGCCAGATCCTAACATGCCAACATC +ACCTCTTGCCATTTAGCCCCTAGTGAGAAATTGGGAGCTACCAGGCAGGTGCCCAGTGCA +TTCAGGGAAGATGGGCACAACATCAGGATGGGTGTGTCTGGAAGCTCCTCTTCACTGACC +AGGGCTGGGCAGGGCCACCCTGGGCTGGTGAGGCTGCCCTGCAGGGCTTCTCACTATGTA +GCACCAGTCACCAGCCCAGGTCACAGAAGAAGCCCCTCCCAGCACCCACTGGAGAGGGGA +AGCTGAAGCCCAGGGAGACGGGCTCCATGGTGGTCCCACATGGAGCTGTTTTGCAAACCC +TGGAAAAGGCGGCTCTCCCTGTCCCAACACTCTTCAGAGACAGGAAGACAGAGTTAATCT +TGAATGAATGTTATTTCTACTTAGTCCTAAGCAAGAATAAGCTGCCCTCTTGGTGATCAT +ACTTTATACGGAGTGCTATCGTTTATGAAATGCTTTCAGTATGCTTTTTAAATTATGCAG +GCAAAATAACCACACTTCAGAAAATGTGGACTTCTGAAAAATAAAATCCCCATAATTCTT +AATAAAACTGCCTTTTGCACTTTGATACATTACCCTCTGCTTTGTTCATGTAGAACTTTG +CATTATTTTCAACACAGTGTATCTATAGTTTTTATCTTTTTTCCCTCTTTAGCTTTGTAG +CAGATTTTTTTTTCAAGCATCTAAACTGTCCTCGTTATACTTCTTTTTTTTTTAAATTAT +ACTGTAAGTTCTAGGGTACGTATGCACAACGTGCAGGTTAGTTACATATGTATACATGTG +TCATGTTGGTGTGCTGCACCCAGTAACTCGTCATTTAACATTAGGTATATCTCCAAATGC +TATCCCTCCCGCCTCCCCCCACCCCACAACAGGCCCTGGTGTGTGATGTTCCCCTTCCTG +TGTCCATTGTTCAATTCCAACCTATGAGTGAGAACATGCGATATTTGGTTTTTTGTCCTT +GCGATAGTGTGCTGAGAATGATGGTTTCCAGCTTCATCCATGTCCTTGTTATACTTCTAA +ACAGAGGCACAGTGTTCTCTCTGGTCTCTTAGATACTCTTTTGTTGGATGTTGAAGTTAT +TTCCATGGTGCAGTGGTGTGATCACAGCTCACTGAAACCTCAACCTCCCTGGCTCAGGTG +ATCCTCCCACCTCAACCTCCTGAGTGGTTGGGACTTTGGGACTACAGGTGTGCGCCACCA +CGCCCAGCTAAATTTTTGGGGGGGGCAGGGGGTCTCGCTGTGTTGCTCAGGCTGGTATTG +AACTCCTGGTCTCAAGCGATCCTCCCACCTCAGCCTCTCAAAGTGTTGGGGTTACAGGCA +TGAGCCACTGCACCCAGTCTATTGATCTTTCTTTTTGAAAAATATTTGAATATGCCCTTT +GTCCCTCTTTATATTGGAGTCTTGATGTTTTTCTTTTATGTATGTAAAAACTTTTCCCTG +ATTATGAATATTATATGTATACTGCAGAAAATTTTTAAAAATCACAAAATCATAATAAAA +ATGACCCTCAGGTTCCAGCTCAGTGGCTCATGCCTGTACTTTGAGAGGCCAAGGCAAGAT +TGCTTGAGCCCAGGAGTTCAAGACCAGCCTGGGCAACATAGGGAGATCCCATCTCTACAA +AAAATACAAAAAAAAAAAAAAAATTAGCTGGGCATGGCGGTGCGTGCCTGTAGTCACAGC +TACTCTGGAGGCTATGGTGGGAGGATCACTTGAGCCCAGGAGGTCAAGGCTGTAGTGAGT +CATAATGGCACCACTGCACTCCAGCCTGGGTGACAGAGCAAGACTGTCTCAAAACAAACA +CCTTCAGAATCAGTTCATGGATCATTACCATTATTAACATTTAGATGCGTTTTCTTGCAG +TTGTTTTCTATGCATGTATACATATCTTTTTTCTTTTAAAAGAAAATTAGGCTGGGTGCG +GTGGCTCACGCCTGTAATCCCAGCACTTTGGGAAGCCGAGGTGGGCAGATCACCTGAGGT +CAGGAGTTTGAGACCAGCCTGGCCAACATGGTGAAACCCCTGTCTCTACTAAAAATACAA +AAATTAGCCGGGTATGGTGGCCGGTGCCTGTAATCACAGCTAGTCAGGAGCCTGAGGCGG +GAGAATCGCTTGAACCTGGGAGGTGGAGGTTGCAGTGAGGCCAGATTGTGCCATTGCACT +CCAGCCTGGTCAACAAACAAGAGCGAAACCCTGTCTCAGAAAAAAAAAAAATTAGATTCA +TATTCTACATATTATTTTTATCATTTTCCATTTAACATTTTATGATAAGCATTTTCTATG +TTATAAAATATTTTCAGACATAATTGGCCACATCATTTTCTGTCTTACAGTTGTATCTTA +ATTTATCTATTCCCTTACTATTGAACATCAAGATTGTTTGTGCCTATAAATAATTATTTA +ACATAGGCCTCTGTTCCCATCTTTGATCATTTCCTCTGAGTACGTTCTGAGAAATGCAGT +TAACTGGTGAAGGTTATGAACACTGAAGCTCGTTGGTGTTCCTGGGTGGAATCTGATCTG +GTGGACCTGCTGTGAGCTGTTCCCATCGGCTCTGACATGACGCTGTGAGCTGTTCCTCCC +TGGACGAACATGTTCCTCCCATGACGCTGTCACCACTCCCTGGCCAGCATGGGGTCGTTC +CGGCCTTGATTTTTATATCTGCCATTTTGAGGCTTTAAGAATGTTATTTGTCCCTGCTTG +TTGGCCGTTTGTTTTTCTCTTCATATGTGTGGTCTGTTCTTGTCTTTTGTCCACTATTCT +CTTTGGTTTATTTCACACACACACATACACAGAGAGACACACAGATGCATAAATGACATA +CACATACACACATAAACAGATGCATAAGCACAGACACACACACACACATATATATCCCCT +TGGCATGTACATTTTCTGTCTTTGTTACAGCATTTTTAATGCCCAGAGGTTTTCTTTTTC +TTTTTTCTTTTCTTTTCTTTTTTTTTTTTTTTTTATGAGATGGAGTCTCCCTCTGTTGCC +CAGGCTGGAGTGCAGTGGTGTGATCTCGGCTCACTGCAAGCTCCGCCTCCCGGGTTCACG +CCATTCTCCTGCCTCAGCCTCCCAAGTAGCTGGGACTACAGGCACCTGCCACCACGCCCA +GCTAATTTTTTGTATTTTTAGTAGAGGCGGGGTTTCACCGTGTTAGCCAGGATGGTCTCG +ATCTCCTGACCTTGTGATCCGCCTGCCTCGGCCTGCCAAAGTGCTGGGATTACAGGCGTG +AGCCACCGTGCCCGGCCAAAAAGGACTCTTAAAACTCAACAATAAGAACATGAACGGCTG +GGCACAGCCGTTCATGACACAGATGGCTGTGTCATGGGCCATAGAATAATTTAAAAAACA +ATAAAAGTCTCAGCTGGGCACAGTGGCTCATGCCTATAAACACAGCATTTTGGGAGGCTG +AGGTGGGAAGATCACTTGAGGCCAGGAGCTCGAGACCAACATGGACAACATAGCAAGACT +CCATCTCTACCAAAAAAACAAAAAAAATTAGTTGGGCATGGTAATATGCACCTGTAATCC +CAGCTGCTTGGAGACTTAGGCAGGAGGATTGCTTGAGCCCAGGAGTTCAAGTCTAGTGAG +CTATGATTGTGCCACTGCACTTTAGCCTGGGCGACAGAGCAAGACCTTGTCTCAAAAAAA +AAATTCTATTTTTTAATAAATGGACCTGAATATTTTACCGTAGGTCTTCCCAAAGGGTCC +AGGGATGCCATCACCCGATTGCATAGCTAGAAAGCGGATGGACTTTTTAGTAAGTGTGGG +TTCTAGTAAGTGTTGCCGCACTGAAGAACATCTCTGGCCAGGCGCGGTGGCTCACGCCTG +TAATCCCAGCACTTTGGGAGGCCAAGGTGGGTGGATCACTTGAGGTCAGGAGTTCAAGAC +CATTCTGGCCAACATGGTGAAACACTTCCTCTACTAAAAGTACAAAAATTAGCTGGGCAT +GGTGGTGGGTGCCTGTAGTCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATCGCTTGAAC +CCAGGAGGTGGAGCTTGCAGTGAGCCGAGATCATGCCACCGCACTCCAGCCTGGGCAACA +GAGCAAGACTCCGTCTCGAAAAACTAAAAAAGAAGAAGAACATCTCTGCTCTCAGCTTAG +GTCCTGGGCCCCTAAAGTCAGCGAGGCAGCCATTGTCCTAGGGTGATACGATGACATGGA +TTTGGGACTCCCTGGAGGAGGCCACACACACACAAAATGCAACTCTACAAGGGGAGGGAA +CAGAAACTGAAACAGGTATCTGCAATGTGCCTGGATCCGAATTTCAAAATGTGTTGAAGA +ATTATGGATTTACACCATGAGAAAAGCACTGGTTGGCTTTTGTGCCTGCTTCACTTTGGC +TCTGAGTTAACTTCAAACACTGCCAAACACAATGCTAGCACATGGTGACCCTCAAACTAA +TAATTTATAAGATGGGATCCACTTCCCCGGTGGAAGTGGCCACATGCTGCCCTCTCCCCA +CCCCCACGGCATACTTGGGCATGACCTGCAGCCTTTTGTTGCCATCCAGGTTCGTGTTCA +TTCTGCTGGTGCAGTAAATCAACCACTATGACATGGTTTTGCAAAAAAGAAAAGATTTAT +TCACAAGGGCACTGATCGGGGAGGTGGATCCTTTTTAAGTCCTTAAGTCTTTCGTCCCCC +GAAGATAAGTAACAGCTTCCTTCTGTGTGAGCATGGCTGGAGTTCATGGCATTTCACAAG +ACACGTGTACAGAAGAGGGTAGCATTAGCATTTTCCAAAGGCGGAGTTTTTGGCCCTCCA +GTGTCAAAAGGCCACCTTTCGGGCACTTGTGCAGGCCCAATTGAAGGGTTGGTGGTCTCA +ACCAGTTTGAACTGGACAGGAGCTGGCCCAAGTTCCTGAAAAACAACTGAAGAAGCCGGC +ACCATGGTGACTTATGCATGTTATCTATACAGTAGCCAGGGAAGGTTAAGTTTCAGCATT +CAGCGGCAAGGCTTTCAGCTACTGTGGCCCTTAAGCTTCACAGAAAAAGGAGAAAAAAAA +ATTAAAAACCAAATGACCCAAAAGCAAGCAGAGCAGGCAGACCTGGCCAAATTAACCCTT +CAGTTTCACTTTCCCTTGCTCTGTTGGGCATTTGTGGCTTGGAAAATGGCCCCCTCCTGC +CGCAGACAGACCCTTTACTGCTGACACCAATCATTACATTGATCTGTCGTGGTTCAGTGC +ACCACTGCACTCCAGCCTGGGCAACAGAGTGAGACCCTGTCAAAAAGGAAAGGAAAGGAT +AGGAAAAGGGAAGAGAAGAGAAAGGGGAAGGGGCAAGGGAAGGGGAAGGGGAAGGGGAAG +GGGAGGAGGGAGGGAAAGAAAGGAAGAAAATAAAAGAAAGAAAAGAGAAAAGAAAAGAAA +AAGAAAAAAAGAAAAGAAAAGAAAATGCACAGTGAGTTAGATTTGGCCTGGAGGCTGTAG +CTTGCCAACTCCTCCTCTGGATTCATGGATTAGAGTTTAAGGAAGAGATGGAGAAGTATG +GCAGAAGAACTGGAGTGAGGCCGAACCCCGTGGTGTTCTAGAAGAAAGGCTCTTGACACA +AGCATCTGGCAGTTATTTTTCAGGGGAGAACCTACAAATTATAAGGCTGTGCAGCTCCCC +TTACTAGTCAAGTGATTACACTTTTGTTTTCTTTTATTTTTTTTTAGAGACAGGATCTCC +CTCTGTCACCCAGGCTGGAGTGTGGTGCCGCAGTCACAGCTCACTGCAGCCTCGAACTTG +TGGGCTCAAGTGATCCTGCCTCAGCCTCCTGAGTAGCTGGGACTACAGACACACTCCACC +ATGCCTGGGTAATTGTTTCTAGTTTTGTAGAGATGAGGTCTCCTTGTGTTGCCCAGAATG +GTCTTGAACTCCTCGCCTCAAGCAATCCTCCCACCTTGGCCTCCCAAAGTGCTGGGATTA +TAGGTATGAACCACCATGCCCGGCCTCATGTGACTACTCCTACAGAGGCCCTCGATGGCC +TGGAATGATTGATTCCAGGACCCTGTCTTCTCATCCCAAAGCACCAAACCCTACTGACAA +GGAAAGAGCCCCCATTTCAGAACTTCCATGGCCACCCCCCAACCCTGGGATTGGCAACTT +TGCAACCTGGGCTTCTCCGATAATCAGATTTACGGTAAGACCCCAAAGAGGTCCAGGCGC +TTCTAAAACAAGTTAGACAGAGAATCCAAACCCAAATCCTCAAGATGTGAGCCCACATCA +CATCCCCCAAAATAGAGCATCCGTGACCACTCCAGCCTTGCTAGGGACACAGCATACTCC +TTGACCCTCACCAAAGGACAATTGCTCTCACAAACACGGGGATCCACTGGTTCCCACGCA +CTAAGCAAACTTTTATGGCCTTAATTGACACTGTTTCCCCAGAGACCCCACTAAATGTAA +GGGAGGAACCCTCTCTGTTCCCTGGGACATAAGATTGAAGGCAAACAAGTCCGCCTTAGC +CTGATCACTGGTGCAATAGCTTTGCAGAATATTCCAGTGGTCTCAGTTCTTTCTGCTCTT +GAATTTCTATCACTGGGACAGATGCTCCAATTGGAATAAAACCCACACTTTGTCCCTTAC +TGTTGGTCTTGGCAGATGAGACCCTGAGGACCTGCCCAAGCCATTAAAATCATTAATATG +ACCCAAAATAAATTAAAACAGGGACTTCAAGGATTGAGAGAAGGGGTGACCATCCCCTCT +GTTTCTCCATTTAACAGCCCAATTTGACGTGTTCTTCAAATGGAAAAGAACAAATGACAT +CTCACAGTCGATGCTGAAACCTTAACCCAGGGGGCCATGGGGGCCCCAGCCCCTGCAGAC +TGAAAGGATGGAGCCCATTCAGTCTTTTGCTGGCCGATATTTTGCTATTTTTGCTTCCTT +GCAGTGTTCCACAGTACCTAATTCAACAGGCTCTCAGCCTCTACTCCCATTCTATTTATT +GTGGTAAAATATATAACAAAATTTACCGTTTTAACCTTTTTCTTTCTTTTTTTTTTTTTT +TGAAACAGGGTCTCACTCTGTCACCCAGGCTGGAGTACAGTGGTGCCATTGCAGATCACT +GCAGCCTCAACCTCCTGGGTTCAAGTGATCCTCCCACCTCAGCCTCCTGAGTAATTAGGA +TTACAGGCTTAAGCCACCATGCCCAGCCTACTTTAATCATTTTTTAATTTTAATTTTATT +TATTTTTTTAAATTTTACTTTAAGTTCTGAGATTCATGTGCAGAACGTGCAGGTTTGTTA +CATAGGTATACACATGTCATAGTGGTTTGCCGCAGCTGTCAACCCGTCATCTAGGTTTTA +AGCCCTGCATGCCTTAGGTATTTCTCCTAATGCTGCCCCTCCCGCAGCCCCCCATCCTCA +GACAGGCCCCGGTGTGTGATACTCCCCTCCCTGTGTCCATGTGTTCTCATTGCTCAACTG +CCACTTATAAGTGAGAACATGCAGTGTTTGGTTTTCTGTTCCTGTGTTAGTTTGCTGAAA +ATGATGGCTTCCAGCTTCATCCGTGTCCCTGCAAAAGACATGAGTTCATTATTTTTTATG +GCTGCATAGTATTCCATGGTGTATATATGCCACATTTTCTTTATCCAGTCTATCACTGAT +GGGCATTTGGGTTGGTTCCAAGTCTTTGCTATTGTAAATAGTGCTGCAATAAACATATGT +GTACAGGTGTCTTTACAGTAGAATGATTTATAATCCTTTGGGTATGTACCCAGTAATGGG +ATCACTGGGTCAAATGGTATTTCTGGTTCTAGATCCTTGAGGAATCGCCACAATGTCTTC +CACAATGGCTGAACTAATTTACACTCCCACCAACAGTGTAAAAGCGTTCCTATTTCTCCA +CAGCCTTGCCAGCATCTGTTGTTTTCTGACTTTTTAATAATCGCCATTCTAACTGGTGTG +AGATGGTATCTCATTGTGGTTTTGATTTGCATGTCTCTAATGACCAGTGATGATGAGCGT +TTCTTCATATGTTTGTTGGCTACATAAATATCTTCTTTTGAGAAGTGTCTGTTCATATCC +TTTGCCCACTTTTTGATGGGGTTGTTTTTTTCTTGTAAATTTGTTTAAGTTCCTTGTAGA +TTCTGGATATTAGACCTTTGTCAGATGGGTAGCTTGCAAAAGTTTTCTCCCATTCTGTAG +GTTGCCTGTTCACTCTGATGATAGTTTCATTTGCTGTGCAGAAGCTCTTTAGTTTGATTA +GATTCCATGCGTCAATTTTGGCTTTTGTTGCCATTGCTTTTGGTGTTTTAGTCATGAAGT +CTTTGCCCATGCTTATGTTCTGAATGGTATTGCCTAGGTTTTCTTCTAGGGTTTTTACGG +TTTTTGGGTTTTACATTTAAGTCTTTAATCTATTTTGAGTTAATTTTTGTATAAGGTATA +AGGAAGGGGTCCAGTTTCTGTTTTCTGCTTGTGGCTAGCCGGTTTTCCCAGCACCATTAT +TAAACAGGGAATCCTTTTTCCATTTCTTGTTTTTGTCAGGTTTGTCAAAGATCAGATGGT +TGTAGATATGTGGTGTTATTTCTGAGGTCCCTGTTCTGTTCCATTGGTCTATATATCTGT +TTAAAAATATGGAACACTTTGGCTGGGTGCGGTGGCTCACACCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGTGGATCATGAGGTCAGGAGATCAAGACCATGGTGAAACCCCGTC +TCTACTAAAAATACAAAAAATTAGCCGGGCGTGGTGGCGGGCGCCTGTAGTCCCAGCTAC +TCGGGAGGCTGAGGCAGGAGAATGGCATGACCCTCGGAGGCAGAGCTTGCAGTGAGCCGA +GATTGTGCTACTGCACTCCAGCCTGGGTGACAGAGCGAGACTCCGTCTCAAAATAAATAA +ATAAATAAATAATAAAAAATAAAAATAAAAATATGGAACGCTTCACACATTTGCGTGTCA +CCCTTGGGCAGAGGCCATGAGAAACTTCTATCGTTCTGATTTTAGTATATGTGCTGCCGA +AGCGAGCACTATTTTAATCATTTTTAAGTGCACGGTTTAGTGACATTAAGTACATTCACT +GCCATCTATTTCTAGAATCTTTTCATCACCCGAAACTGAAACTCTGCATTCCTATTAAAC +ACTAATTCCCATACCTCCCAGCCCGTGGTAACCACGGTTCCACCTTCTGTTTCTACAGAA +TTTTTTTTCTTTTTTTTTTTTTTTTTTGAGATGGAGTCTTGCTCTGTCGCCCAGGCTGGA +GTGCAGTGGCGTGATCTCGGCTCACTGCAACCTCTGCCTCCCGGGTTCAAACGATTCTCC +TGCCTCAGCCTCCCAAGTAGCTGGGACTACAGGCACACATCACCATGCCCTGCTAATTTT +TTTGTTTTGTTTTGTTTTTGTTCATTTGTTTTCTTTGAGGCAAAGTTTTGCTCGTCACCC +AGGCTGGAGTGCAGTGCCGTGGCAGTGGCGCAATCTTGGTTCACCGCTACTCTGTCTCCC +GGGTCCAAGTGATTCTCTTCCCTCAGCCTCCCAAGTAGCTAGGATTACAGGCACACACGA +CCACATACGGCTAATTTTTGTATTTTTGGTAAATTTTGTATTTTTGGTATTTTTGCCAGG +CTGGTGTCAAACTCCTGACCTCAGGTGGTTCACTCACCTCCGCCTCCCAAAGTGCTGGGA +TTACAGGCGTGAGGCACCTCGCCCCGCCTGTCTCTACGAATTTGACTCCTCTAGATACTC +CACATACATGGAACTGCACAGTATTTGTCGCTGACTTCTGGCTGTCCTCACCTGGCTATG +CCTACTTTGGGGGATAATCTGGGCCTGGGACACCACATCCCCGTAGCAGGCCCCACCGGG +CCGCACAAACAGAACTGCGCCGAAGTTCCCCCAGGCTGTTACCCCCACTTGTTTAGGCTC +TTCAAAGATGCTACCGGCCGGGCGTGGTGGCTCATGCCTGTAATCCCAGCACTTCGGTGG +GCCGAGGTGGTCAGATCACTTGAGGTCAGGAGATCGAGACCAGCCTGGCCAACATGGTGA +AACCCCGTCTCTACTAAAAATACAAAAATTAGTCGGGCTTGGTGGTACGCGCTTGTAATC +CCAGCTACTCTGTAGGCTAAGGCAGGAGAATCGCTTGAACCTGGGAGGCAGAGGTTGCAG +TGAGCCAAGATTGCGCCACTGCACTCCAGCCTGGGCGATAAAGTGGATACTCTGTTTCAA +AAGAAAAAAAAAAGGTGGCACCGGCCCGGTGCGGTGGCTCACACCTGTAATCTCAGCACT +TTCGGAGGCTGAGATGGAAGGATGTCTTGGGCCCGGGGGATGGAGGCTGCAGTGAGCGGT +TATTGAGTGACTGCGTCCAGCCTGGGCCTCAGAGTGAGGCCGTGCCTCAAAAAGAAGAAA +AAAAAAAAAAAAAAAAGCAGCAGCTACCCATCCAGCCGCCAGATGGCAGCACGATTCCAT +GGCCCCCACTAGCCGCTGGCTGCCTGGTGCCGGATGCAGTCCGAAAGGCGGTTCTGAGCT +CCAAGGGCCGGCGCCGCGCGTGCCTGCGGTCCCAGCTGCTCGGGAGGCCCAGGCAGGAGA +ATCGCGTGACCGGGAGTTCTGCGCTGCAGTGCGCTGTGCCGATCCAGGTCCTCACTGAAG +CCGGCATCAGTATGGTGGCCTCTGCCACCAGGCCGCCTAGGGAGGGGCGAGGCAGCCCCA +GTTGGAAACGGAGCGCGTCAGTAGTGGCATCGCGCCTGGGAATAGCCTCTGCGCTCCAGC +CGGGTCGACCTGCCGAGACTCCGCCTCTAAAACCAGCAAATACCGGGAGGCTGAGGGACG +AGGACCGCTGGAGCCCGGGAGGCGGAGGTTGCAGTGAGTAGCTGGGATTACAGGCAGGCG +CCACCACGCCCGGGTAATTTTTGTGTTATTAGTAGAGACGGGGTTCCACCATGTTGACCA +GGCAGGTCTTGAACTCCTGACCTCAAGTGATCCACCCTCCTTGGCCTCCCAAAGTGCTGG +GATTACAGGCGTGAGCCATTGCGCCTGGCCAAATAAGTAATTTAAGCAATTTTTTTTGTT +TCAGAAAAAAAATTAACTCATAAAGGAGCCCCCCCGACACACACACACACACACACACAC +ACACACACACACACACACACACGGGAAGCAGCAGTGTAATTGGAATGCCCACTGCTGAGG +CTCTCGAATGAGTGTCATGTGTGCACATTTTGCCCCTCACAATGCACGTCAGACTATTAA +TAGGAAGCAGCCGCTGGAATACCTCTGGTGGGGTGTGTGCAGCAGGCAGCTTTGGAATTA +CGGTATCCCCAATGTGACAGCAGGACAATGGCTTCTTCACTGGCACTGTCCAACCACAGT +GCTGTGGTTATGTCTCGAGGTCCATTATTGGGCGAAGGTCACTGCAGACTCAGGGAGGCC +CAGGAGCTCACCCCAACCAGCTTCTTTACCAGGTGAGTGACCTCAGCCCTGCAGCTGGAC +TCATGGAGACAATGACCTCACCCGAAGATAGATGACCCCTGTCCACCGTCCACACAACAA +CTGAACTGGCCCCAGGTTGACTCCTCTACACCCTGCTTCCTACTGTACCCCTGTCAAAGG +CCTTCCTCCCACCCTTCCCACTCCTCTTCCTCCCTGGCAGCCCAACCACCACAAATTCAC +TAACTTGTTTTCAACTCTTACAGGCTGCCCTCCTAACCCTAGCCCTGACCTCTGCCCTCC +TAACCCCAGCCCTGACCCCACCGCCCTCTCAGGAGGCTTTACCAATCCTCTGCATGTTAG +CCCCACCCAAGGAACAGGCCTATTTTCAAGCATACTAACTGTTGGGTGTGTCGCTTACCT +ATGCATATGACAGCCAATCCAACCTACCTAAATGACAGCACAGCTCCATCCATGGATGTG +GCTGATCACATCTCCAAACCATCTTCCCACTGGGGACAAATTCTTGGATTTTTTAGAGAC +AGGTTCTCACTCTGTCACCCAGGCTGGAGTACAGTGGTGAGCCTCAGACTCCTGGGCTCA +AGGGATCCTCCCACCTCAACCTCTGGAGTAGCTGGGACTACAGGTGCACACCACCACCGT +GCCTGGCTAAATTTTTAATTTTTTTTTTTTTTTTTTTTTTTTTAGAGATGGGGGTTGCTA +TGTTTTCCAGGCTGGTTTTGAACTCCTATCCTCAAGTGATCCTCCCACCTCAGCCTCCCA +AAGCACTGGGATTATAGATGTGAGCCACCAATCTTAGCCCAAATTTTTAACTAAACTCAA +TTAAACAAATGAACAAACAGAAAAGACTCTCAAACCACACACTGTCGTCTCTCACCCAAC +AGAGACAAGACGTCTATAAACCACCAATCTGTTTAAAGAGACCACCAAATGTTCAGACCA +TGAAACTGAAAGAATCAAAATAAAGTTGTCACTATGCCACCAACGGACAAAAGCCAGGAG +CACACAACCAGGGGTCATACTCACTGAAGGTCCCCCACCCTGATGGCCAGTCAGGGGCGG +CTTGCGGGTCTCAGAGAGGGCTCACCACCTGCTTGCAGTCATTGGGGATGGGAAGGTAAG +TCCAACCCATGCCAGGTCAAGGCACAAAGACTGTGGGGGGAATGCACCAGACACATAAAG +AGATGACTTTATTCAGGCTACTGCTATGGGAAGAAAACTCACTAATGAGGAAGGAGGGGC +CTGGTAAATAAGAGACTCATGTGGAAGGCTGGAGGCGGGGTCTTAGAATGGACAAGGGCA +AAGTGCTCCTTCTGGTCTCACTATTTCTCAGAACGCAAAGGAAGAGGCAATTTCTCAGTG +AGCACCATTTCCCTGGAACCCAGGGCTGAGATGAATTTCAGTACTGCCAGCGGCCTCCGC +GTTCTCCTGTGTGTGTAGGAGTTTGTGTGTTCCAGTGTGCGTGTTCCCACTGTGTCTTGG +TGTTTCTGTGTGCCTGGTGGCATGTCTGTGTGTGTATCTGCAGGGTGAAAGACCACAGAT +ACTATCCGAATTCCCGTGCTCAAGTGCGCCTCCTGCCTTGGCTTTCCTGAGTGTGGGGAT +GACAGGCGTGAGCCACCACGCTGGGCCTCATGATCTGTTTCTAGTGCAGTGAGTGCATCT +TAGGGTGGGTGCCCGCCTCCATGCTTAGTAGGGCATGGATGCTGTGTATGCCATCTGTCG +GTAGGATGGTTACACTTCTGTGTGTTGGCTGATGTGTGTGTCTCAGTATTTAGTCGGCTC +TGGTGGCACATGTGTGTGTTGCAGGTTGTATAAGTTGCTGTTTCTCTGTGTCTGGTGGAA +GGTGTCTATGGTTGCAGAGTGAGGGTCTCTTGGTGTTTCTGTGTGTCAGAGGGTGTGTGT +GTGTGTGTGTGTGTGTGTTTTGCAGGATGAGGTGTGTTCTGTGAGTGTGATGTGGGGGGT +GCAGGGTGCATATCTGTGTCTACATTTCTTTTTTTTCTTCTTCTTCTTTTTTTTGAGACA +GAGTCTCGCTCTGTCGCCCAGGCTGGAGCGCAGTGATGCGATCTCCACTCACTGCAAACA +CTGCCTCCCAGGTTTAAGCAATTCTCCCAGCTCAGCCTCCCAAGTAGCTGAGATTACAGG +CGCATGCCACCACGCCCGGCTAATTTTTTGTATTTTTAGTAGAGATGCGGTCTCACCATG +TTGGCCAGGCTGGTCTTAAACTCCTGATCTCAAGTGATCTGCCTGCCTCGGCCTCCCAAA +GTGCTGGGATTAACAGGCGTGAGTCACTGCACCCAGCCTGTCTGCATTTCTGTCTGGTGG +TGAGCTATGTGCTGCAGGTAGTGTGTTTAATGTGTTTCTCTCATGTTTCCGTGTATCTGG +TGGAAGATGTGTGTCTGCAGGATGAGTGTCTCTTTTGTCGGTGTATCATGGATTGTGTGT +TTGTGTGTGTTGCAGGGAATGTGTTTGTCTCAGTATCTGAGTGTGTCGGGTCGTGTGCAG +GTGTGTGTTTTTTTGTGTGTTTGTTTGTTTGAAACAGAGTCTCACTCTGTCGCCAGGCTG +GAGTGCAGTGGTGTGATCTCAGCTCACCTGCAACCTCCGCCTCCCGGGTTCAATCGATTC +TTCTGCCTCAGCCTCCTGAGTGGCTGGGATTACAGGCGTCTGCCACCACACCCAGCTAAT +TTTTTGTATTTTTAGTGGAGACAGGGTTTCACCATGTTGGCCAGGCTAGTCTTGAACTCC +TGATCTCAAGTGAACCGCCTGCCTCGTCCTCCCAAAGTGCTAGAATTACAGGCGTGAGCC +ACCGTACCCGGCCGCACGTGTATTTTGTATGATATATATCTGCTTCTGACTTTGGTGAAG +TGTGTGTGTCGCAGGGTTGTGTCTATCTTGTGGTTTCTATGTGGCCTATGGTGTGTGTGC +TGCAATGAGTCTCTGTCTTGGTGTTTCTGTGTCTGGTGATACATGTTGTATGTTGCAGAG +TGAGTCTTTTTTTCCATTTTTATGTGCGTGGTGTGGGTTGAGTGTCCTCCATAGTAGTGG +GCTGGCTGTGTGTGTGTCACAGCGCGTCTGTCTCTGTGAGCGGTGGGTTGTGTGTGTGTG +TTGGAGAGTGAGTGTTTCTGTCTGATGGAGTGTCGTGTGTGTGTGTGTGTTGGCAGGTGA +GTGGCTGTGTTCCTCTGGGCCCAGTGCTGTGTGGGCGTCTGTTGCAGTGTGTGTGCCGTC +TCTGTGTTTCTGAGATTCTGCTGGCTTTGTGTGTGCATGTCTGCGTTTCGGGCTGTGTGT +CTGTGTTGGTGTTTCTGAGTCTAGAGGAGCGTGCATGCGGCGTAGGGTTAGTGTCTGCAG +GCCTCTGTGTGCTGTGGCCTGCGTCTGCTTGTAACCACCAGGCTGGGCCTGGTCCCCACA +TTCCTCCCACTCCATTGTGCTCTGTGCTACAAAAAATATTTGCGTTTTCCACCACTCATA +ATTTTTCCTCCTCAATCGCTACCAGATGTGGGTCCTGTGGTCCCCATCCCCATGGCAACG +GAGGTTCCAGCAGCCGCGGTTCCCTTTTGTGGCGCCTGCCCTGGGAGCTGGCACTGCTGT +GAGCCCCGAGGGGGTGGGGAGAAGCGGGTGGTGGGAGGCAGGAGGCTGGAGGGGTCCCAG +CAGCTCCCTTCCCAGCAGCCACTGGAACCCTCCTGGGGGGAAGGGAAGGCTGGTGGTAGG +TTGGGGGGGGTCCCCTGTTTTGTGAGGCACCCACAGGTAGAGTCTTCGACACCTAGGGGG +CTTCCCAGAGAAGGGCAAGGAGAGGTCCCCAGAAAGGCCTGGTCACTGGGACATCCCTGT +TCTCTCCAAATCGTGCTGGTCCAGGCTGGGGGAGGAGAAATAGCAAGAGCTGAGGGCTTG +GGGGTTCAGGGAACAGCAGTGTGGCATCCTCATCGTTCTGGGGGGTGGGCACCGCCTAGA +CAAGAATGTGGTCTGAGCCCCTGCACTGCCCACCCCTCACCCACACGCAGGCACTGCCCT +GCCCTCGCGGAGCCCGGCTGGGCATCTGCCCTCTTGGCCTTAACCCCAGCAGCCCGCATG +GCGCAGTGCCCAAACAGAGCAGAGGCTTTCCAGCCACAGGGCCATGGCTGGGAGGGTGCC +CAGCTGGCTCCAGGGAAGCAGTATGGCCCAGAGGCAGGGATCCCACATTCCACGTGCTGC +CTGTTTGTGTCCTGCCAGCTGCTCTGGACGGCCGACCCAGGGCAGGACGCAGTCTCCACT +CAGATGGCTGGGCCTTCTGAGATGGGTGACCCCTCTAAGATGGGTGACCAAAGTTGACCT +CCGTGGGGCATCTGGTCAGAGGATGAGAGTGTGCCCAGGACGAGAGCCCCAAGTTGCCAG +CGTGAGACCAATGAGTGCTGTGTGGCGGCTGCAGGGTGATCAGAAGATCCTGGCAGCAGG +GGAAGACTTTGAGCTGGGCATCAAAAGATGAGATGCAGGAGAACAAGAAGAGGCCTGCCG +GGCAGAGGCAGGAGGTGGGAGGAGAACAGACAGGCAGGAGCTGGGGGAACTTAGTGTGGG +GACAGCAGGGGCCATGGAAGGTGAGGGTCTGCGGCTTAGGAGGGTCACTTAGGAGGCCTG +CCCGGGAGGGTAGGCGGGTCAGGAGCAGCGAGGCCGTAGGGCACAGATGGTCACAGATAG +CCAGGCAGCCGGGTCTGGCTTGGGGGCAGGGGATCTGCCCCGGGCGCTCCCTCCGTCTCC +CTCAACCTTCCGCAGTAGCAGGCGGGGCTGGCAGGCAGGAGAGTTTCCGGCTGAGGACAA +GGAACCCGTTGAGGCAGACAGCAGGGCTCTGTGCAGCAGGAGACCGGCTTGTTTGTGCTG +GAGGAGGCCCGGCTGGAGTAAGCGCCCGCGGCCCCCTGGCCGCAGCCTCTGCACCCCCCG +CAAGCTGCCACCAACAGCTCTGAGGCCCAAGTTTAACAGCAGCGGCCAGGGGAAAAGGCC +GGGATCCGAGGCAGGCCCATCGCCTGTCCCTTTCAGTCAGGGACTCTGCCTGATCTGCCC +CCACCCAACCTTCCTCCCCGTGACCAGTCCAGAATGGGGCAGGCCAGATCGGGGCCGCAT +AAACTTGATAAACAAACGAAGCCTGTGGGTTGACACAGCCCACTTCCACCATGGTCCCGG +GAGACCCACGCCTGGGCTCCAGGGCTCCCCGCTGAGATAAGGGGTGGGGGAGAGTGCAGG +ACAGGTCGTCACATAAAGTTACTTCTGGGGGGCATCTTTGGCCGAAGCCTGCAAACAGGA +AGTGATCAGAGCATGAGGGGAAAGGCATTTTATTAAGAAAGCTTTGGCCAAGCCCCCGCC +GGGAGGAGCCCATCCTGGGGCACCGGCCGAGGGGGGAGCAGCCCTGCTGGGGGCCTATAA +ATACATCTCCTCAGGCCACTAGAGTCGCCCCTGGAGGTCCCGCGGCGTGTGGGGCAGTGG +GAGGCCATCAAAACCAGCTGACAGCTGAGGGGCCTGGGCCCGGGGCGCCAGGGAAGGGAA +GGGGTGGGACGGACTAAGCCCCTGAGGAGCGGAGACCAGCCCTCCTCCCCAGGCTGGGGT +CAACCAGATGCCCGGGAGCCTGGCCAGTGGAAGTAGCCCCGGGCTCTATTGGGACGGCCA +AGGGAGGGAGCCTCCAGCCAGAGGCACCAGGCCCTAGCGGGGGAGAGGCAGCCCGGGCAG +AAGTGCCTCTGGCTGCAACCAATGAGAAGGTAGCCCTAACCAAGTCCACTCCTGGCCAGT +AAGAGGCGGTCTTTAAGCGGAACCCTCCCATCTTTGGCCAATGAGACGCTGTCTGGTCGG +AGCGCTCCATAACTCGGCCAATGGGGAGGGAGTCGCCCGCTAAGCGCCTGTCAGGCCTCG +ACCAACGGGATGGGCCCTTCCCGCCAGAGCACACTGCTCCAATCCAGGAGCGGCTGCAGG +ACCTGAGCCAATGAGACGCAACCTCCGCTAGCCGCGCGGTGCCCGGCCAATAGGAGGCCG +CCCGTGCCCGGTAGCGTGGGAGGTGTGGGGTGGCGGGCGGCGCTGCGAAGCTGAGGGAGC +TGCGCGCGGACGAGCCACAGCCTGCTACAGGGTGGGTGCGCCCGCCCTGCCCAGCTCGCC +CGCCGCCTCCCGGCTCTTCTTGCGCGGCGGCTTCTGGATGGGGGTCTTCTTCCGGGGGGT +CTCAGGCGCGGGCAAGTCGGTCGCCGCCTTCTCAGGCCCCGGGGTTTCGGTCGCTGGGGG +CGCGCGGGCGGGCGAGGCTGGCGGCACGGAGCGCTTGGCTTTCTGTGGGGGCGCCGGCTT +TTCCCTGGGGCCCTGCGCGCCCAGGGCCACCTCGGCGCGGCCCAGGCTGCGAGTCTTGCC +GCGCACGTCAGCGGCCAACATGGAGGCAGCCTCGGCGCGCTTCGCGGGGGACCGCCGGCG +TCCGTGGGCTCCAAGAGGCCGGGGCGCGGCGCGCGCTCGGGCCCTGGGCGGCGAGGGCGC +AGCGAGGGCTGTCGCCTCCTCGGGCAGCCCCGGGGGGCGCGGCGTTGGGTCGCGGGTCCG +GGGGCTGCCGTGTTCGACCGTATGCGCCGATTTGTCGCTGGGCGTCCGTTTCCTCTTGCT +GGGGCTGGGCGCGGCCTCGGAGCCTGGCGGCGGTGGTGAGGGCGCACGGCCAGCTGCAGC +GGCGCTGTGCTTGCCGTGGATCCAGGACACCTTAGGCTTGGTGGCGGGGTCAGGTGGCGG +CGGTTTCCTGCGCTCGGGCGATGGCGACAGCGACAGGCCCCCAATCTCGCCCCGGGCCCG +GGCCGGCCGGGCCTCGCGTCGGGCCACGCGCGCGTACAGAGCCCCTCCGGGCCCCTCCAC +GCTGGACGCCGACCGCTCGCTGTCGGAGGACGCGGGGAGGGGTATCGCCTCCTCGGCGGA +GGCTGGCGTGGTCAAGGGCACAGGGGACGGCGCCGGCGCCTCGGCAGGGACAGTGGGGAC +TTCGGGGTCCCGGCTCTCCGCTGGTGCCTCTGGCAAGGGAAGAGCAGGGCGGTCACAGCC +TTCAGGAATACCTTTAGGGGCTCCAACCTCCAGGCGCAAACCTTCACCTTTCCTCCTCTA +CCCACGCCCTTGGCACTGTGTCACCCTGGCATCTAGACGTGCCTGGCACAGAGCACCAAC +CACACATGTGTACTTCAGAGCCTCAGGCTATGCGGCTGACTCTGAACTCAGGCTGTGCAA +GGAGTGATGGGCGCATTCCCGCGACTGAAGCCCAACCTTGGCCTGGCCTGGCAGCCCTGC +CCCAACACCCCTCCAGCCTTGGGCGCCTGCATCATCGAATTTGAGGCTGGAACATCCCCA +CAGGGGTTCCATTATCCTTCTTTAAGAGAGAAGGCTTCTAGCTGGGCGTGGTGGCTCACG +CCTGTAATCCCAGCACTTTGGGAGGCTGCGGTCACCTGAGGTCAGGAGTTTGAGACCAGC +CTGGCCAATATGGTGAAACCCTGTCTCTACTAAAAATACAAAAATTAGCTGGGCGTGGTC +GTGGGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATTGCTTGAACCCAG +GAGGCAGAGGTTGCAGTGACTGGAGATCATGCCACTGCACTCCAGCCTGGGTGACAGAGG +CAGACTCCGTCTCAAAAAAAAAAAAAGAGCGATAAGGCTTCTGAGGCTCTGAGTTGGTCA +CCTGCCCGTGGCATCTGGGGGCACAGTCAAGGGAGGAGACAGGGCAGAATCCCAGACCAT +CAGGCTCCTTTCTGCTATCTGTGGATCAAAGGCTGTGTGTGGATCCAACTCCCATACTCT +GTGGATCCCTTCCTCCTGTCTCCTCTGCCACCCCCTACCTAAGCCCAGAAACTTCTCTCT +GCCTACTTTCCCCCAGGAGCAACCCTGGGCTGTGGCCTACCCATCTCCCCACACCTGTCT +CCGGTACTGAGCAGCAGAGTCCAGCTCTATGGCCTCAGCTCTGTGGGCAACCCTCAGGTA +CCAGCATGGCCAAGGCCTTCCTCTCCATGCTGCCTGCCCTTCTCCTGTGTCCCACCCAGA +ACACAGCTTTTCCATGGGAACATTTCACTGGGCTGGAGTGATGCCCAGGTAGGGCCTTAC +TTACCCTCATGGGGTACACAGTACACAGGGCCTTCATCAGTGGTGTCAAACGAGGAGAAG +GAGGCCCGAGAGGACCAGGATGGTGAGGGCTGCTCCAGCCCTGAGGGTGGCTCCAGGAAG +CTGCAGTTGAGTGTGTTATCCAGGTCGTGGTGGGCCACTGGGGAAGGATGAGGCAGAGCT +GCCAGGGGTCCACTCTGCCCCAGCCGGTGCCCTCATTAGCCCCTGCTGTGACAAATGTTG +ATGGGGTGACCAAGACCAGCCCTATTCTTGGACTGCAGGGGGCACAGGCAACTCAACAGG +TACAGTGACACTGGGCCAGGACTGGAGAATGGGTAGAGGTGAACCCAGAAAAGAAACATG +GGCACAACATGTGTTAAGGTGCAAGGCAAGTGTGTGCATCCAGGGAGCTGGAAAAGGTTG +GGCTGACGTGTTGAGAAAAGGCCAGAAAGGTGGGAGACGGGGCTGAAGAAGACACCTGGC +TGGGACAGGCCACCAAGGCCTCCAAGCTCTGTTTTAGGCCCTGCCTTGTGCGAATAAGGA +AGCCTTGGAGCACTTCTGAGCCCAAATGCGCAGTGGCAGGGCTGCCCTTTGGCTCAGCCC +ATCTCAGCAAGCTGCACCCTAGGCCTGGCCTCCAGAGATGCAGACCCCACAACAGGGGGC +CCCAGAAGCTGGCTAGCCTGGCCTCCATTCCACAGAGGGATGTGGGGTCCACTCCCCACA +CCTATGTCCCCAGATGCCATGCTGCTAGGTGGGCCAAGGGGTTTTCTCTCTCTTGCTTGC +TTGCTTTTTCTTTTCTTTCGACAGTTTTGGGGTTTCTCCTCCCTCCCTCCCTCCCTCCCT +CCCTTCCTTCTCTTTCTTCTTTTCTCTTCTCTTCTCTTCTCCTCTCCTCTCCTCTCTTCT +CTTCTCTTTTTTCTTGACAGTTTTGCTCTTGTTGCCCAGGCTGGAGTGCAATGGTGCGAT +CTCGGCTCACTGCAACCTCTGCCTCCCTGCAACCTCTGCCTCCCAGGTTCAAGTGATTCT +CTTGCCTCAGCCTCCAGAGTAGCTGGGATTATAGGCATGCGCCACCACACCCGGCTACTT +TCGTATTTTTAGTAGAGACCGGGTTTCTCCATGTTGGTCAGGCTGGTCTTGAACTCCAGG +CCTCAGGTGATCCACCTGCCTCGGCCTCCCAAAGTGCTGAGATTACAGGCATGAGCCACC +ATGCCCGGCTTGGCTAAGGGGTTTTCTCAGCTGTTTCCTTCATCTCCCAAGAGTCTGAGC +CCCCTTCCCCTCCATCTTTAGAAATAAGTGGGAAAGAGAGGAAGAGAGGGTCCACCCAGG +TGCAAGTCAGCATGGAGAGAAGCGGCACACCCCACCCCCCTATCCTGTTGGTGGGTGGGG +ACCAGCCTGCCCACTTTCCAGGAGGATCTCTGGGTACTGCTGGGGATGTAGGCAGGAGGG +TGGGTCCTCTCCGTGGGGCAGGGCACTCCCGTGGCCACGCATTCCCCCAGCAGCTCTGGC +CGGGATATACAGCATTCTCCTACAGACTGGGGGAGCCTGCGGGACCCAGATGTCCACACA +CCCCTGATGCGATCACTCTCAGGGCCAACGTTTCTGACATATGCCCACATCAGCCGGCGC +ACCTAGGACTCCTGCCTTCCTACCTTGCCTCGCCCTCAGCAGCTGCCACACCTCTTACCT +TCCCTCTGGTCGCACCTCCTCGCGCCCACGCACATCAACACTCAAGGTCCCCCATTTCCT +CACTGAGATCTGGACCCCCTCACACCCATTTCCCAGCAGCTTCCTGCGTCGAGAGGTGTT +TCTCCCAGATACCCCGCGCTGTCATCCTTACCTACGACTTTGGGTAGTTTCTGCCTCCGG +AGCGGGATCCGGGGCAGCTTCATGCTGATGCGACTGAAGCGCCCGCATAGTCGGTGCGGC +GCCTTCTTCCTCCCAAGCGAAAGCTCCCTGCGGGGGCGGGGTCTGAGCGGAGGGGCGGGG +CCGGGGCGGGGCCCAGGGGCGATTAGATCTCGGCCGGAGCCAAGCACAGAAGGGGCGGGG +CCACGTCCGGGGCAGGGGCGCGGAAGGGTTGGATCTGGGTCCGGTGGCACCCAGAGGGTG +CGGCCTGAACCCAGGCGAAAGCGGGGCAGTATCTGGGCTCACCGGCGCGTAGGGTCCTTG +CCGCGGCAAGCGCAGCAGCAGCCGAGCAGCGAGAGCAGCAGGCAGACGAGCAGGACGAGC +AGCGCGCCCGCGCCCATCACGCCCTTGCGCTGGTTGGTTTCTGTAGGGGGTTATGGGGTC +AGCGCGGTTTCTGGCACCCCCTGCATTCCTTAACGGGACGCCCCTCATCCACTTACCTAG +GTGGCAGGCACCAGTGACCGGGTCGCACGTGTCCTCGTGGCAGCTGCAGGCCTGAGCACA +GTCCGCGCCGTGGAGTCCGGGCGGGCACGTCACGTTACAGCTGCCGGGACATAGGGTCAA +GGCATGCCACAGCCGCCCCCCTAGGATGCCCCCTACCCTCACCCCTCACCCGCGGCCAGG +GCCCAGGGTCCAGGGTCCCAGAACCGGGCTCTCTCTCGCTGCATTCGTCGTCTAGGGATT +GAAGCCCCGCCCCGCCCGTGGCACATATTGGGTAGTGGATGTTTTGGAAACGAATGTTGC +ACAACACTAGTGGGGGGGCCTGGGGGATAGGACCCGTGGTGGCCGCGCCGCAGCGCCCAC +TGCTGGGGCTGACTCGGCTAGGTGGGAAGAGGGGCTGCTGAACCAGACCCTTGGCTGTAA +GTGGAGGTCCCTGGTCCTTCTGTACCAACTCGGGGTCACCTTAAGAGCCCACTGACACAG +GCTGGACTGGTCACCAGATCCTGCGCTGAACGTGAGCTCCCCGACATCCAGGCAGGAAAC +TGCCCCCAAAGAGCCTACTGTCACTCCCTAGCTGGGGTAAGGGACCAAGGCTGAGGTGAT +AACCCAGCTCAGGGTGGAGAGGCCACCTCGTCGGCTGGACCCCCCTCTGTGGCAGGTACA +AGCCCCCAACCCCCTCCCGGTCCCGGGGCACTCACTGGGGCCCGTGGACGCCAGGGCTGC +ACAGGCAGCGCCCCGACTGGAAGTCGCAGTGTCCGCTGCCGCAGTCGGCGCACACGAAGG +CGCAGTCCTCGCCGTAAGTGCCATTGCTACACTTGGTCTCGCACCTTGGAAAGAGGGGAG +GAGGCGTCAGCAGAAATGGAGGCAAACGGACCACAGCGCCCTCGACATTGGGGCCTTTGT +TAGGGAGGCAGGGCGGGGGACTGCGTGTCTGGGCCGACGCAGGCAGGGCTGCTCACCGGT +CGCCGATCCAGCCCGCGTTGCAGCGCGTACACTTGCCGGTGACATGGTTACAGGCATGCC +CGTCGCGGCATGGCGGACAGCGGTGGCTGCAGCCCTCGCCATAGAAACCGGTGGCGCAAG +GCTGGTCGCACTTGGTTCCGTTCCAGCCGGGCTCGCACGTCAAGCAGCGGCCCTCGGCCA +CCGTGCACGGCTGCTGGCCCTTGCACTGGCCACACCTGGGGGAGGGGTCGGAGGCTAGGG +AAGGCTGGGACCCGCCTCACCCCTGTCCCCATCGGCGGCCCGCCCTTCCACCTCCTCCCT +CCCTGGCCGAGAGACCGCGCTTACCGGCGGCGACAGCCCAAGCCGTAGAAGCCGGCGGGG +CACGGCTCGCGACAGTACTTGCCGCGGTAGCCCGGCTCGCAGGCACACGTGCCGTCCACA +GGGTGGCAGCGGCCGCGGAAGCACTGGCAGTAGCGATCGCAGCGCGCGCCGAACGTACGC +TCGCGGCACTGACAGCGGCCGCTCTGCTGCTCGCAGGGAGACGAGTTGCAGGCGCACTGG +TTGTTGCAGCTGCGGCCCCACCAGCCTGCGTGGCACAGGCAGGCGCCGGTCTGTGGGTCG +CAGCGCGACGTGGCGCTGCAGTAGCACGCGCTGGCGCACTGCGCGCCCCACCAGCCGGGC +TCACAGCGGCACGCGCCGCTCCGCGGGTGGCACGTGCCGTGCTGGCACTGGCACGCATGC +TCGCAGCGCGCGCCCCAGCGCCGCGCGTGACAAGTACACTGGCCTGTCACGTCCTCGCAC +TGCCCGTGTGGGTGGCAGCTACACAGCTCCTTGCAGTCGGGGCCCCAGAACTGGCGCGGG +CACTCTGCAGGGGAGGAGCGGAGGGGGTGGAAGGCCCCGGTGCTTGAGTAGGTGCCCCCA +GCCAGCCGGAACCTGCCCGCGTCCCGCACTCCAGCCGCCACCTCTGGGGACCCGCCCCGA +AGGCGGATCCGACCCCGCCCCACCTTGGACCCCGCCCCATCTCTCCAGGATTCCGCCCCA +CCGACCAATACCGGCCCGACCCCACGCTCACTGGTGTCGCAGTTGGCACCGAAGTAGCCG +TGGCGGCAGCGGCACTCGCCAGGCCTCACGCACACCTCGTTCTCTGAGCACGTGGAGTTG +CCTTCGCACACCGCTGTGGACGAGACAGGCCAGAGCTGCTGCGCGTCCTAGCCCCGCCCC +CTCCCCCGCCCCAGGTCCCCGGGATGACCCACTCACCAATCCCACACTCGTCCCCTTGCT +GCCTCCAGCCAGCGCAGCACGTGGGCACCTGGGAGCTGCGAGCAGAGGGAGGACATCTAA +GCCCGATGCCCCTCCCCCAGCCCCCATCTGCTCCGGGCTCCTCCGCAGCCTCCGCACAGC +CTCCCTGCCTCTGCAGTTGCGCTCCTGTCCTAGGGGGGTGGTTAATGAGGTCCTGCCAGG +CAGTCGTCTGGCGGTGGAGGATTGCCACAAACAGACCTCACCGCCAAGAACTTTCCAGCC +CAGAACCACCCACCCCATCTCACCTAACTCCTTTGTGTCCTCCTCCCACAGCCATTAGGC +CTGAGAAAAGTGGCCTTGGAGTCCCAGGAAGGACAGCAGTGAGGCAGCAGCCAGGGAGAA +GACCATGGGCCTCAGGACCTGCCCAAATGTGAGGGTCTAGGGCATCCCTCCAAGTGGAGG +GCCCAGCCTAATGGGTGTCATGGATCCAGATGTCATGTGATGTGACATGATGAGGACGGC +ACTAGGACTAGCTGGGCCACAGGGACACACCTAGATGCCCAGTTGGGGTTGAGCTCCAGT +GGGGAGGGGCAGCCTCTGGACAGGGGGACGGGGGGTGGCATGTAGACACAGTGAGGTGAC +CACTTGGCAGAGGGGCTTCTGGAGGGAGGTGGGGTGAGGCCCACCCAGCCACTAGGGAAG +GAGCAGGCACATGGGGAGTCCTCCACGTGCAGGAGGAAAGTCAAACTGTGGCAAAAGGGC +TCAGGGACCAGGGTGGAGGAAGGAGCTATTAGAGCATCTGTTTATGCCTTTGTTGTTGGT +TTTGAAACAGTCTCGCTCTGTTGCCCAGGCTGGAGTGCAGTGGCACGATCTCGGCTCACT +GCAACTTCCACCTCCCAGGTTCAAGCAATTCTCCTGCCTCAAACCTCTCAAGTAGCTGGA +ATTACAGGCACGTGCCACCACACATGGCTAATTTTTGTATTTTTACTAGAGACAGGGTTT +CGCCATGTTGGCCAGGCTGGTCTTGAACTCTGACCTCAGGTGATCCGCCCGCCTCGGCCT +CCCAAAGTGCTGGGATTACAGGCATGAGCCAGCGTGCCCGGCCTGTTTATGCTGATTGTC +TTCCACTTGTTCCATTTGATTTGGCTTTACAGAGTACACAATGCTACCGCAGCACTTCAG +GAGAGCACAACCTCTAAAACCCTGGGTGGATGGGGTGTGTGAGCACAAAGGTTTGGAGGC +CCTGCCTGAGTGAAGCCATGATGGCTAGAGAGGGTTCGTAGGGGATGAGCTGGGGTTAGC +CCACATTCAGGGGCAGAGGAGGCTGAGAAGGAAGAGCCACCAAGGCTGCGGGATCCTAGG +TTCCCAGCCGACCCAGAACTTCGCCTCGATCCTAAAGGCATGTAACAGCCATTCGCACTT +TAGAGAAAAGGAGCACGCTTCTTCACAAGCAGGCTTGGATTCAGTATCTGAATCTAGAAC +CGGAAGGTGGTGGGGGGCGGAGTTTGGGAGGAAGCCTGAAGACCCTAGCGGGATGGGATA +GACTGGCCCTACACCATGCATTTCAGGATAGTACATGCCTGGCATGCTCCTGCCCAGGCT +TCCGAGGATGCCCCAGCCATTCCCCAGCTAGACAGAATACCACCCCTTGTACAGAGCACC +TAGGCCTCGAGGCCCCTCCTCCTGAACAAGGCTTGGTTCTCCTTCAGGCCAAAGATGGGA +CCTGGCGAACAGGACCATAAAATCTCAAACTTTGGGGAATTGGTCCAGTGTATTTTCCAC +AATAAAACTGGAAACCAGAGACAGGAATACAAAGGCCTGGCTTTTCCTGGCCCCTGCCCC +CACTGTCTCCACCCACCCAGCCCTGACCCAGGGGGCACCAAGGTGCCCATCTGCAGGGAG +ACCCAGGTCTGCTGGCCATCACCCACCCACTTGTGTCTGCTTCTGAACCATGTTCACTGG +ATGGAGAGCCTCTGCAGGTGTCCCTCCTGTGGGGAGCTTTGCCAGGTGGCCTGCTGGAAT +TGCCCCGGAAGCACTAACCCCCTTCTGCCCTGGACATAAGGCTCTGTGGCTAGGACCCTC +GTTTTAGGGCCACACTCAGCTGGGTTTGATGTCTGGGTTTGCCACTTGCTGTGTGACCTC +AGGCATGCAGCTTAAGCTCTTTGAGCTTCAGGCTCCTTAGCTATATAGTAGGGCTCTACT +GTAGAAAGATTAAGAGAGCCAAGATGTTTTTTTGCCGGGCGTGCTGGCATGTACCTATAA +TCCCAGCTACTCAGGAAGCTGAGGCAAGAGGATTGCTTGAGCCCAAGGAGTTTGAGGCTG +CAGTGAGCTGTGATGGCACCACTGCTCTCCAGCCTGGGCAACAGAGTGAAACCCTGTCTC +AAAAAGAGAGATAGAGATAGGAGAGAGAGAGAGACAGAGAAAGACGACAGAGAGAAAGAG +AGCGCGCGCCAAGACCTATGAAGTGGTTTGGCACATACTAAGCACAAAGGATCCTGAGCA +CAGGCTGCAGTGCCTCTGAGTGCACTCGGTCATCTCTGGTTTAGCGGGCACCCAGGCCTA +ACCCCAGCAGAGCTAATGCCCACCAGCAGGACAGAGTCCATTTGGGTTCACTGAGAACAA +GATGCTTTCCTTCTTGGAAGGGCTGGCAGAAAAGGCCGGGTGGTGGTGGCAAGCCCACTC +TCTGAAGATCTTACAAAGACGGGTGGGGAAAGATGGCCTGCTGCAGGGCTGCTCCCACGC +TTGCCCTGTAAGTCGGCAAGACCCTCAGAAGCCAGGCCATAGGCTGGGCCCAGGCCCCTC +AGCAAGCAAGACATGCCGTAGGCTTCTCCCTCGTAGAGCATTAGTTCTGTGATTCAAACC +CACTGTGAGTTCTTACATCTTCAAGTTGGCTCATGGGGTCCATACCTGTCCATGTTCTCC +CCCAAATCCAGGCAGAAAAGCTTCTCTGCCTGCCACACCCTTCAGACCCCACACCAGCCC +GACCCTCCTGCTGCCCCGCCTGGACACCTCTCCTCTGGTTTCTGTCCCCATCCTCAGATC +TCTCTTGTGTCCACACTAGCTCCCTCGGGAAGCTCACTGAACACTGACAACACCTTGGAC +CCTCCAGCAGGGCTCTCCCCATCAATGCTAGACTTGCAAATCCAACTGCCCAATAGATGA +TGTCACCAGAAGGAGACCTCATGGGCCTCATGCCCAACCAGCCCAAACCTGAACTCTTGA +CCTCCTTGCACCCTGAGTCTTCCCTGCCTCAGATAACCCTGCCTGTCCTTTCAGGCTGGG +AAGCTGAGACCTGGAGAAGCATCTCTGACTCTTCTTTCTTGTCTACACCAGATCCATTGA +GAAAAAAGACGCTGAGCTCTAGCTTCTAAACGATATCTAAAATGGGATCACTTCCTCCTT +CCCTATCCCAGCCTTGTGAGAGCCACCCTCCATCTCCCTGGCTTTTTGTAACTGGCCCCA +GCTTCCACCCCCTGCCCCCCAGGGTGCGAAGTGTTTGCCACCTGGCAGCCAATCCTGGTC +AGATCCCACCCTTTCTCTGTACAAAGCCCCCAGGGGGTCCCATGGCCCTCAGAAGAAAAG +CCCAAGTCTTCTGAGCAGTGGCAGCCCACGGTGGCCTGCCCACCCTCACTCTCTGGCAGC +TCCTCCGCCAGCCCCTCCTGGACTCTGCCCAGCCTCCTGGATCCTTCCTGTACTTCCACA +GGCCCTCTGCCTTGGGAACCTTGCCCCAGACACCCACAGGGCCTCCGTGCTCTTCTGCAG +GCCTGTGCTCACTCACCACCTTCTCAGCCGTTCTCCTCAGAACACCCTAAAGGAAACAGC +ACTCCCCAACCCAACACCTCCCAGCTCTTGCTAGATGTCTAGACACACTTGCTTTTCTGG +ACTGTGTCTCCTCTGCCACAGGGTCAGGGTCTCCACTGCAGCTTCCCTACACCAATACAG +GCCTGGCACAGTGTAGGTGCATAGGATTTTACTGGCTTTGCACTCTCCTCTCCCCATCCT +CCTGCCTCCCAGGAAAGGGAAGGGCTGATGGAAGCCTTGCAAGATGTGGGAGGACAACAA +AGACATGACCCAGACCCCAGGTGGGCAGTGCCCAGAGTGGCTGTCCTTCCCATCGACCCT +TGCCACTCATGACCACAGCGATCTCCACTTAGCCCCATGAGGGGGTTGTGATCACTATCC +CATTTTACAGAGGTGGAGACAGGCCCAGAGAGGTCAAATGACTTGCCCAGGTCCACACAG +CTGGGTAGGGTGGCACCAGGATGGGAACCCAAACCCAGGCTCGGTTCCTGGAGCAGGCGC +CTCCTGGGAGGTCTGCAGACCAGGGGAGCGGGAGCAAAGGGCTCTCAGGCTCCGGACAGC +TAGAGCCTGGCACCGGACCCCCATTCCTGGTCCCGGGCCTGTCTGGGAAAGAGGGCTGGA +GTGAGTAGACAGAGACCACGGCGATCGCGCCCTCCCCCTCTCCAGGCACCGCCCCGCCCG +CCGCCGCCGCTGCATTCCTGGGGCCGGGGAGGCCCGGGAGTCCGCGGCGGCGGCATCGAT +GCGAAGCAGATGGCGGGCCAGGCCGGCCCCCGCCCCGGAGGCGGGGCTCGCAGCGGGGAG +GGGTCTGCGCGCCTCCGGACCAGAGTTCGGAAACCCCGCGCTGCCCCCTCGCAGCCCCTT +GTCTCTGGCGCCGAGCCCCTGGACTCGGCTTGCCCCGGGTCCGTGGCTCAGGCGCCCCGA +CGCGACCCAGCTCGGAGCCCGGCGGCCGCCTCTGCGGCTGCCAGCCCGTGCGGCGTCTCC +AATCCGCGCCAAGGCGCCCCCACACGCCCGCTCCTCACCCCTGCGTGGAGATGCCCTTGA +CCTTGTGGCCTTTGGCCAGCCCACCGGCTCCCCCGACCCCAGCTCCTAACTCCTGGCGTC +CGGGGCTCACCTCTCTGCCCTCCGTGCAAACTCCCGGACTCGCCCCCCCACCGGCCGGGC +CTGTCGCCTGCCTGTCCCACACTGGCTTCCCCAGCCGGCGCCCCACATTTGCGCGGCCCC +TTCTTGCACCCAGAATCCCCACCTGGTTGTCGCCAGGGTTCCCACATCCTCCGGTCCCCT +GTGCCTGTCATAGTCCTTCCGCCTCCCGCTTCTGGTCCACTTCGAGCGCCGGCTCCTCGA +CGCTCGCCTGGGTCACCACCCTCCCACCCGCGCCCGCTCTAAGACGCGAATCTGTCTTTC +CAAGTCTGGCTTGCTCCAGGACCTCCCCGGCTAGCACCGCTCCTCCTCCCCTGACCTTCC +TCCTCACTCCCACTCCCGGCTCCAGTCGGACTAGTGCGGGGCTTTAGCACATGCAGTTCC +TTTGGCTTGAATGCCCTTCCCCAGCTTTTCCCCGTGGACTTCACAACTCGGTCAAGGGTC +CCTTTTTCCAGGTCTTTCCTGATATCCCGGACAACGCGTGTCATCCCCTGGGTGCCCACG +GCACTCCATCCTCCCCTCAGGTGACTTCTCGTCCAGGGTTCCCTGGGATGCACTGTCGTG +GCCCATGGCCGAGGCTGGGCCTGGAACGGAGCCGCGCTGGCTAGGGAGCCGAAGGGGCCC +ACACTTGGCGTAGGAAGGTTCCGGTAGCCCCCTCCCAATGCCCGGCGCCGCCACACCACT +GCCCAGAGCGTCCCTCTCGCCCCCTCCCCCAGCCAGGCCGGCTCCTACCCGGGAGCACGG +CACACGTTGCGGCCGCGAGGGTTCAGTTCCTGAGGCGCCACGGTGTCCGGCAGCATCCAG +AGCAGCAGCAGCAGCAGCAGCGACGGCAGCAGCGGTGACGGCGGCCCCCCGGCTCCCCGG +CGCCGCGCCGGCCCGGCCCCCCGGGGCCCTGCGCCCTCCATGAGGCGCGGGGCAGGCGCG +GGGCGGGCACGGGCGCGGGTGCGGCCGCAGCGAGAGCGGCCGGAAGCGGAGTGCGAGGCC +GGGCGGGGGGCGGCAGGAGGGGCGCCGAGCCGGGCAGGAAATTCCACATCGGCTCCCTGA +TCCCGGGCCAGCCGCGGCCGGCCAGGCGGCAGCGCCCGCCCCGCGCTCCAGACCCCACCC +TCCGGCCTAGCCACCGCCCCTCCGCGCAGCCCCCGCCCCCATTTGGCCGCTCGCAAACTT +GGGGGCGAACTTGGAGGAGGCCCGCCGAGCGCTGGTGGAGGGAGGGTCCGCCCGAGGAAT +CCCCGGTTCCCGCGCCTTTCCCTCCGCTCCCTAGACATCTACCGAAGCAGCCGCCCCTGC +GCGCCCACTGCGTAGGCCAGGCCCGGGACGGGAAGGCGGATCGGGGACACGGACGCGACT +CCGCAAGCCCACCCCCGCTCCCAGCGCCTCGGAACCGGCCAAGGGAGTGGGGCCCGCAGA +CAGCCCAGGTCGAGGCCGAAAGCCAACTCCACAGCACCCCACCGCGAAGTCCTTGTAGTG +CTGGGGTGTGCGGTCAGCTCCCCCTGCGCACTCCTGCGCACTCAGAGCTCGCAAGGGGCG +GACCGAGCAGGATGCTTGAGGCCTGTGGTAGACTCGGTCCGGACCAGAGGCCTGGGGGAA +GGGGTCTCCGTAGGGACGGATGGGAGAGATACAGAGGAAGTAGAATGGCCAGGCTGTGGA +CTGCGGTAGGAAGTAGAGGTAAAGACAGAAGGAGACCCCCGGGATGGAAACCCTGCAGTC +CTAGTTGAGGAGTGAAGGGGGCTGGGGGAGCCTGGGCGGTGGATTCTGCTGGCTGTCGGA +TTTCCAGGAGAGGCTGGGGCTAGAGAGTGGGAACTCCTGCATCAGGTAAGGTGGGTAACA +GCACAGAGCAGAAGGAAGGTGTGGGAAGGGAGCAAGACAGAGGGACAGGCCCTAGGGAGC +CAGCGGGGAAGCTGGACTTGGACTGGGAGGCAGCAGGGTGCGGGTCCCCGGGGGGCAACT +GGGGCAGACCGACTCTGGAAGTTGGGCAGGGAGCACAAATGTCCCGTGTGTAGCCAGGTC +CTAGTGAGGATGTTTGTCTTTTGGGGACTTGAGAGCTGGCAGAAGGCCTAAGCAGGGAGC +GGGCACCTCCGTTCTTTGGGGAGCAGGCCACATGCGGCCCACAGGCTCACTGAGGGAGGG +CAGGCAGACTCTGTCCAGGTGTGGCCAGATAGCCCCGAAGGGTGGGGCTGGAGGAGGGGG +CTTGGAGGAGGAGCCACTGAAAGGCCCAAGGCCATGGGCATCACCAGGCTGGCACAGGCA +GAGAGTGGGATGGGGAGGAGCAGGCCCCTCACTCAGCCATGCTGGTGCAGGAGGGAGGTG +GGGTGGGCTGAAAGAGAAGTGGAACTAGTGTGGACACGAATGCAACTACCTGGGGACAAA +TAAACAGGCCAACCACTTCTGGGCAGCTCAGCCTGGGCACAGCCCTGACCTCAGCAATGC +CCTCCCAGTGCTGGGGCCCCTCCCACGGAGGATCCGGATTGCGGCTCCCAATAGAGGCCA +GCAGAGGTCCCAGTGGCTGCAAGGTCTGTCCCAGCCCAGCTCCTGGCTTTAGAGGCACTG +ACCCCCTGGGCTGGAGGGGACACTCACCTCAGCTGGATGGAGGTCATGAATAGGCATATC +AAATTCCATCACCTTTCTCCTTCCCCCAGACCTGTCCAGGGAGGGCACCACCTGGATGGT +GCCCCCCAATCCCCCAGGACCTCCTAAATGTCTTAGATCTCTGCCCACCCCTGTCTGCCA +CCCAGAGTAGTCTTTTTAATCTCACATGTGGCTATCCACCACTGCTCTCAGGATGAGGAC +CATCCCCAGTCTCACCTCACGACCCGGTACATACATCCCTTGCAGTAGATGGCAACTTTG +GGTGTCATGGGCAGAGCCCTCATTTCTCCCAACCACCACTGCACCCCTAGGGGAAGACTG +AGAAGTATGGGAGGAATGAAGGATCATCCACATGGCACTAGGATGTAGAAGGAACCCACA +GACAATTGACCACCACGCAGGCAAACTGCTGGAGCCCGGAGCCCTGGCCTGCTGGTTTTG +GCCAGGATGGCTGCCAGAAGGAAGTGGACTTTGAAGGCTGAGGAGGGTTTTGCATGAAAG +CAGGGACCAAGAGCCTAGCCACACTGGAGAGCACAAGTTGGGCTGCCTCAGCTCCGGGGT +ATCAGGTGTAACCCTTAGAAACCCAGCTTAGCCCCAAGGCTGACAGTGGCAGGGCCAGGC +TGCGCCCAACTCCAAGGCACTCTCCACCCCTCCCCAGGCTGTGCAGGACCTCAGTGAGCC +CTTCCTGCCCCTGCAGACCAGAGGCCTCCTGCAAACCTGTGGCTGTGGCTGGTGGCTCAG +GTGAGATGTTGCCAGCCAGCATGTTGTCAGGACGCACTGGAGAGTGGTGGGGCATGTCTG +GTGCTCCTCCTTTCCAGAAACCTCTGAGGTCTGCAGGAGCTATTGCCCTGGCCTGCCAGG +TGGTAGCAGAGACACAGGAAGTGCTGGGTCTGAGACCCACAGAGTGGGGTTCCTACTCTG +AACCCATGCTCTTGCGCCTCACCCTCAGGAGAAAGGGAGATGACACTGGAGTGTATAGCC +ATCCCGCCCCACTAGGGCTCAACACTGGGTCTGCCACCCCAAGGCAATGTCATGTTTCCT +CAGGGGTACTCAGGGCCCAGGACAGTGAGGAAGGTCTTCAGGTTACACACACACCCACAT +ACCACAGCCCTGGGGGCACAGGCCAACTCTGAGGGCTTTGTCTCTACCCTCAAGAATCCT +TGGGGTATCCATTTAGGAGAGCCCAGAGTGACTGATAGTCCCCCGTCCCCATCCCCTCTC +CTCCCATCAAGGAGCACACACTGCCCCCTTCTCTTCCGGGACAGGATGCCAGCAGGAACA +CATGGCTGTCCCCATGCTCTGCCCAGTCAACTGGGAAAGGATGGGGCCTTGGCAAGTTAC +AGCCCTGTCTGCGGGATGGCTCTGGGCACAAGGCTCATAGTAGGAGTCTGCAGGTGCAGA +CCCTATGAGGGCATCAGGATGGAAGAAAGCTTCGTGTGGTGCAGCCCTGCAGTGAGGCTG +GTGTGGGCTCACAGCCCATCCATGCAGGGTGCAGGCTAAGCCTGGCAGTCTCAAGAGGGC +AAGAAAAGCATGGGGACAGGTGAACAGGGGAGGGTCCCAGCTGCTGTGCCAGTGTGGTCC +TTGAGACTGGGTGCCTAAGGGTTACCTGGCAAACCTGTAGCACATGCAGCTCCCCTCCCC +AGCACACTCAGCTTCAGGAGGTTGGGAGGAGCCGGGCACAGGCCAGAGGGGCCCCCCCCA +CCGACCCCCTGATGCTGCCCCGCTCCCAGGTGCTGAAGCTCTGGTTCCCTGACCCTCAGG +CTGAGAGACTCCTAACGAGCTGGGCTGAAACTCTGCGTGCTGCCCTGGTTGGGAGACAAG +TTCCACACCAGAGAAGACACTCAAGTGGCTGCACAACCACCTGTCACCAGACCAGGGCGA +GTTCCAGCTTTCCCACTGAGTGCCCTGTTAGCTTGTGGAGTTTACTGTGCTTCCCTCTCA +GGCAGGGTCTTCCCAGTGCCACTTGGCTTCTGGCCTGGGCTTCCACAGCCTCTCCCAGAT +GGCAGCTCTGACCCCAGAAGCCACGCTTCCTGGGGACGCAGCTTGGGTGCACTGTGGAAA +GGAACTGAGGCTGTGGCTACAGAAAAACAGTTAACACCTTCTGTAAGATGCTTTATTTCA +TTGACCAACAACATGGGGTCTGAAAACCCAGCGGGAGGGGTCTTTTTATCACAGAGCCAG +TCCCAGGCGAGCTGATGCATCTCTGCTCCTCTGCCCCTCAGGAGCTCTCATCCTCCAACC +CCAGCTGCCCCCACAGCCCCACCCCATTCACAGAAAGAGGGCTACCACGTGCCTCAGCCC +CCCTGCCCAGGCTGCCAGCTCCCAGGTCCTTTTGGAGAAGGACTGATCTAGGCAGGGAGG +AGAGAAGGCCAACCCCTCCAGGGCTCACTGAGGAAGGCCAAAGCCTTTCAGAAGCAGTTC +CTGCAGTGACGTAATCCACAGCCTGGGATCTGCATGGCCCTGAGATGCCTGCGGCAGGCT +GGCCAAGGGGCTGGTGTGAAGAAAGAGGGCAGGGCCCATAAGCTGTGGCCAACAGGGGCA +GGGGCCCTGCCTGGAGTAAAGTGCTCTGGCCTAGGCTGCGTGGGTTTCACTGCCCTGCAG +CCCCAGCCTCCCTTCCCTCTGATGCCAGGCACAGGGAGCCTAGTCCTCACTGGAGTTGTC +AAACTCCTCCCAGTCAGACACACTCATCACCTCAGAGGCAAAGTCCGGGTCGGCCTGGCT +GCGGTCAGGGGTCCCGCGGGGCGGCTCAAGGAGCAGGGAGCGGGGCAGGGTGAGCACACA +GGCCGCCAGGCCTGAGATGGAGTTGTCCAGCTGGGGCCCTTCCTCCCAGCAGTCCTTCTC +CACATCGTAAATGTGCACGTAGCCTGTGCGGCTGCCGCGGTTGTGTGAGCGGCCACCTAA +CACATAGATCCTGTTGTCCAGCACAGCAATGCCAGGCTCACCGTGCCCAGCAGGGAGTGG +GCAGACAGATGACCACTGTCCAGACGTGCAGCTGTAGCAGGCCACCTGCAAAGCCAAGGC +TAGAATAAAGCCCAGCACCCACTGGGACGAGGCTGCCAGCTCCCCCACAAGCCCACTGAC +CAAGGTGGCAACAGTTACCCACCATTCTGACAGGTCAGGCCCCCTGGAAGGATGGCACAG +GGCCAGTGTTGAAACATCCTGTCCATGGGCCAGGCTGCTGCTTTCTCACCCAGGGATGGC +CGAGTCTGCAGGAGGCTGTCTTTTGGGCCCTCCCCTAGAATGATCCTATTCTCTCTGGCT +TTGCTCCAGCCCAGCCCTTCCTCTAGGCCACCCGGCCCTAAGCCAGTCTCTGCCCCCGAG +TGTGTGGCTGTGCCCCCATCAGCATGTGGTCATTCCCCATGTCTGAGGGCACTGCTTCTC +TCCCCTCCAGGAAACGAAGCTGCCTGAGAGACATGGACTCCACTGAAATGTCTTCAACCT +CCTTCTGCAGCACTCAACACAGGCAGTAGGACAGGGGGAGGAGACAGAAAGTGGAAGTAA +TTCCTTGCGGAGTAGTCAACATCAATATTCTCTTGTCTTCAAAATTGTCCAAACAGTAAA +CAAAGACATGGAAAAATGTTCAACCTACTAGTAATTCAAGAAACGCAAAATCAAAACATC +AGAGACAAATTTTTCAACTAGCAACCACTGCAGAGAAGGAAAATCACAAAACCCAATGCT +GTTGAGGGTGTGGTAAAGCCATACTACTATGTATCTGTCTGACATGCCAGAAAAGGAATT +TGGCAATAAGTATTAAGAGCCATAAAAATCTTACCTTCTTGACTGATTAGCCGTTTTTGG +TTCTCTAGCTATGGTGGGCAGAATAGTGGCCCCCAAAGATGTCTAGTTCCTAATCTCCAG +AATATGCTACCTTAAGCAGCCAAAGGGGCTTTGCAGATAGGATCAAGGGTACAAGAATAC +AAAAAAAAAAAGGATTAAGGGTGCAGACCCTGAGATGGGGCAGTTTTCCTGGATTTTCCA +GGTGATCCATCCAATTGCATGAGCCCTTAAAAGTGGAAGGGGAGAGGCCGGGCGTGGTGG +CTCACGCCTGTAATCCCAGCACTTTGGGAGGCCAAGGCGGGCTGATCACAAGGTCAAGAG +ATCAAGACCATCCTGGCCAACATGGTGAAACCTCGTCTCTACTAAAAATACAAAAATCAG +CTGGGCATGGTGGCACATGCCTGTAACCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATC +ACTTGAACCCAGGAGGCAAAGGGTGCAGTGAGCCAAGAGCACCACTGCACTCCAGCCTGG +CGACAGAGCGAGACTCTGTCTCAAACAAACAAACAAAAAAAGTGGAAGGGGAGGCCGGGG +GTGGTGGCTCACGCCTGTAATCCTAGCACTTTGGGAGGCTGAGGTGCGTGGATCACCTGA +GGTCAGGAGTTTGAGACCAGCCTGGCCGACATGGCAAAACCCCGTCTCTACTAAAAATAG +AAAAATTAGCTAGGTGTGGTGGCGAACACCTGTAGTCCTCCTAGCTACTCCGGAGGCTGA +AGCAGGAGAATCGCTTAAACCCAGGAGGCAGAGGTTGCAGTGAGCTGAGACTGCACCAGT +GCCCCCCAGCCTGGGTGACAAAGCAAGACTCCATCTCATAAAAAAAAAAAAAAGAAAAAA +AGGAAGGGTAAAGCCAGACAAGAGAGCTGAGAAGTGAGGAGGACTCAACCTGCCATTGCT +GGCTTTGAAGACGAAGTGTCCCCAAGCCAGGAAAAGTGGGGACCTCTAGAAGCCAAGAAG +GCCCTCAACTGACAGCTAGCAAGGAAATGGGACTGCAACTGCCAGGGACTGAATTCTTCT +AACCAGAGTGAGCAGGGAGGCAGATCCCCACTAGGGTCTCCACAAAGGAAAGATGCCCTG +ACCGCACCCTGGTTTTAGCCTGGCAAGGCCCATGTCAGAGGACTTATGAATGCAGAATAA +ATTTATCTTAAGTTGCTATGTTTGTGGTGATAGGTTACTGAAGCAATAGAAAACTAATGT +GCTGGCCCAGAGGATCTCACAAGCAGAGGACCTGTTAAAAGCCAGATCGCCAAGACCCAC +CCTCAGGGCTTCCGAATCAGTGGGTCTGAGGTGCCTCGTAACACAGCGTTCCCAGGTGAT +GCAGACTCTGTTAGTCTGAGAATCACACTTTGAGAACTGTTGCATGAACCTAAGGAAATA +ATCCAAAATACCTGAAAAGCTCAACAAAGCAACTATTACTTGTCATGTTATTTGGAATAG +TTAAAACTTAGACACAAGAGGGGATGATGAAGATTGAGTGTTAATCTGGAAAATGCCCAG +GACAAAAGTCACTGAGAGAAGCAGAATGGGATATGGGATGCTCTTTTTTGTTTGTTTGTT +TGTTTGTTTGAGACAAGGTCTCGCTCTGTTGCCCAGGCTGGAGTGCAGTGGCACCATCAC +GGTTCACTGCAGCCTCAACCTCCTGGGCTCAGTTGATTCTCCCTCAGCCTCCCAAGTAGC +TGGGACCACAGGTGCAAGCCACCATGCCTGGCTAATTTTTTTTTGTATTTTTAGTAGAGA +TGGAGTTTCACCATGTTGCCCAGGCTGGTATCAGTTCCTGGACTCAAGCCATCCACCTGC +CTTGGCTTCCCAAAATGCAGGGATTACGGGTGTGAGCCACTGTGCCCAGCTCAGAATGGG +ATGCTCTTTGACTACAATCAGGCAGAAAACATACACGGTCAATGCTGAAAATGGTCATAC +TGAAAAACAGTACTGCAGGGGCCTGATTATGAATGCTTTTCCTCACCCTTCTCTATTTTT +TTTTTTTTTTTGAGATGGAGTCTTGCTCTGTTGCCCAGGCTGGAGTGCAGTCGTGTGATC +TCAGCTCACTGCAACCTCTGCCTCCCGGGTTCCAGCGATTCTCCTGCCTCAGTCTTCCCA +AGTAACTGGGATTACAGGCGCCCATCACCGCACCTGGCTAATTTTTGTATTTTTAGTAGA +GATGGAGTTTCACCATCTTGGCCAAGCTGGTCTTGAACTCCTGACCTCGTGATCCACCTG +CCTCAACCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCCACCCATCT +CTATTTTTTAAAGTTCCGGCAATGTGGTTATATTAACTTTATAATAAAAGTTTTGTTCTG +TTGTTTTGTTTTATTTTGTTTTGAATAGAGACAGGGTCTCATTCTGTCACCTAGGCTGGG +GAACAGCGGTGTGATCATAGCTCAGTGAAGCCTCCAACTCTGGGCTGAAACAATCCTCCC +ACTTCAGCCTCCTGAGTAGCTGGGACTACAGGTATGTGCTGCCAGCCTGGATCTAAAAGT +TTTGTTGTTGTTTTTTTTTGTTTTTTTTGAGACAAGGCCTGGCTCTGTCGCCCAGGCTGG +AGTGCAGTGGCGTGATCTCAGCTTACTGAAACCTCTGCCTCCTGGGCTCAAGCCATCCCC +CAACCTCAGCCTCCCAAGTAGCTGAGAGTACAGGCATGCAACCACACCTGGCTAATTTTT +GTATTTTTGTAGAGATGGGGTTTTGCCATGATGCCCAGGCTGGTCTCAAGCTCCTGAGCT +CAAGTGATCCTCTCGCCTTGGCTTCCCAAACTGCTTGGATTACAGGCATGTGCCACCACA +TCCGGCCTAAAAGTTTTTAAGAGTAATAAGCAAAGGTAGATGTGTATGTGTGTGATACTG +TCATGGTGACATTTGTCCAAACCTATAGAATGTGCCAAGAGTGAACACTGTGGACTCTGG +TTGATGGTGATGCATCAATGCAGTTTCAACAACTGTGACACATCCACCCCTCTGGAGCGA +GAGGTCTGCAGTGGGGAGGCTATATGTGTATGGGGGGAAAAGGGGGTGTATGGAAACTGT +ACCTTCCACTTAATTTTGCTGTGAACCTAAAACTGCTCTAAAAAATAGTCTATTTTTAAA +AGGCACATGATTCAATTACATTTTCCATCAATAACAACTGAGAGGCTTGGGAATGATGAC +GGGTGTGGACTGCCCCGGGCCCCACTCACCTGGTGCACGTCCCTCCTGTATCCGGCATCG +TTGTTGCTGCCCCCGATCACATACAGCTTGTTGAGGAGGGTTGCCATGCCGTGCCAGGCG +CGCCGCACAGGCCCATCAGCCAGTGTGTGCCAAGTGTTGCTGCCTGGATCGTAGCAGTGT +GTCTCTTTCAGGTAATCCTCCCCTCTGCGGCCGCAGGTGATATACATCTTCCCCTCCAGC +GTCGCGCCTGCGTGGGCATACACCTGTGTGGAGCCACCAGGAGAAATGGCGTGAGAGGGC +AGTGAGGAAGGGTGGCTGGGTACTCTGTCAAGGCCAATCACCACCCCACACCTGCCTGAC +AACGCTGTGAGGCTTCACCACTTCCCACTCACATACAGACAAGAATCCTCCCTCGATTCT +CATGGGACATACTGTCCTAGTCATTGACCTCTAACCTCTTCCCAATAGCGGATACATCTA +TAGACTCAGAAATGAAATGTAGCCTTTGTCTTTCCTTTGCTCCTAAAGTTAACATCTGCA +TGGGGGAACTCCAAGAAAATAAAAGCATTTTTTCCAAGCCAGTCTGGAAGAAGCCACAGA +ACCCTGGGGACCGCTGACCCACCCTCAGTGGCCTCCACCCCTCCCCCACTCCCACTGGAC +ATGCAATCCTCCGGGCCTGCTGACCCTGCTTTTAAAATGTTTGTAAATAATATCTGACAC +TAAACTCATGATGTGGGGAGAAAAATACACATGGTTCTTGATTCTGGTCCTGAACCTTCT +GTGGGCTTTTTACCCTCCCTCTGTTGGGCTATCTCCATAGGGCCCAGCCTGCCCCCATCA +TGGGCACCTCTTACCCTGGCCCTACCACTTCCGGAACCCACCCACTCACACCCAGCAGGC +CAACAGAAGGCCCCAAGGCAAGGCCCTGGGTGTTTTGAGGGTAGAGGAGCCCCTCAGGGT +GTGGAGGCTCCAGAGCTATGTTACTGGGCAAGTCACTAACACTGAGGCCATGCGGGTGGC +AAAAACACAAGAGTCTAGAGAGGTGGACGGAGCAGTGGGGAGGAAGAACACACACCAAGG +GTTTGGTTTGGGTCTTCTCCTATCACCAGTAGGGGTCTGGGGAGGTTTTTCTTTTTTTTT +TTTTTTTTGAGACGGAGTCTCGCTCTGTCACCAGGCCGGAGTGCAGTGGCACGATCTCGG +CTCACTGCAATCTCCGCCTCCCGGGTTCGAATGATTCTCCTGCCTCAGCTTCCCGAGTAG +CTGGGATTATAGGCGCCCGCCACCATACCCAGCTAACTTTTGTATTTTTAATAGAGACAG +GGTTTCACCATGTTGGCCAGGATGGTCTCGATCTCCTGACCTCGTGACCCACCTGCCTCG +GCCTTCCAAAGTGCTAGGATTATAGGCATGAGCCACCACGCCCAGCCGAGGTTTTTCTTT +TTAATTAAACTTTTCATTTTGAGATAAGTGTAGTCACGTGTAGTTGGAAGTAAAAATACA +GAGGTCTCACGTGCCTTCTTTCCCCCATGGTAGGAGCCTGTGTCACTATATCACAGGGTC +ACCAGGATGCTGACGTGGACACAGCCACAGAACTGTCCTATCACCACCAGGATCCCGAGG +GGCTGCCCTTTAGGGTGACATCCACTCACCTCCCTTACCCTAATCCCTTCCTTAAGCCCT +GGAAACCACCAATCTCTTCTCTATTTCTACAGTTTTGTAACTTCAAGAGTGTTGTCTGAA +TTAAATCAGTATACAACCTTTTGACATTGGCTTTCTACCCCAACCCAGGTTCTACCAGGT +TGTTGCATGTACAGGTTGAGTACCTCCAAAATCTGAGACTTTTTGAGCACAAACACGGCA +CTCAAAGGAAATGCATTTCAGACTTTTGGATAAGAAATGCTGAACCAGTAACTATAATGC +AAAGATTCCAAAATCTGAAAAAATCTGAAATCCAAAACACTTCTGGTCCCCAGCATTTCA +GATAAAGGGTACTCAACATGTACCAATAGTTGGTTCCTTTTCTATTGCTCAGTAGTATTC +CATGGGTATCTACCACAGCTTGTTTAACCATTCACTGTTGAAAACACCTGATTTGTTTCC +AGTTTCTGGCTATTACCAATAAAGCTACTATTAACATTCATGTACAGATAAGTTATTTTT +TATTTTTTTGAGACAGGGTCTTGGTCTATTGCCCATGCTGGAATATAGTGGCACAATCTT +GGCTCACTGCAACCTCTGCCTCCCGGGTTCAAGCAATTCTTGTGCCTCAGCCTCCGGAGT +AGCTGGGATTACAGGCACGCATCACCATGCCTGGCTAACGTATACAGAGTAGTTTTCATT +TCTCTGGGATAAATACCCAGGATGGTAACTGCCAGATCTGTTTTCCAGAGTGGCTGTACC +ATTTCACATTCCTATCAGCAATCCATGAGCATAGTTTCCCTGCACAGTCACCAGTATTTC +GTATTTTCACTACTTTTTATTTTAGTCATCCTGAGGTAGTTCTCTCACTGTGGCTTTAAT +TTGCATTTCCCTGATAGCTAATAATGTTACATATCTCCTTATATGCTTATTTGCCATCTA +TACATCCTCTTCAGTGAAATGTTTCTTCAACTCTTTTGCCTTCTGTTTTTTGTTTTGTTT +TGTTTTGTTTTGTTTGTTTTTTTTTGAGACAGAGTCTTGCCGTGTCGCCCAGGCTGGAGT +GCAGTGGCACAATCTCAGCTCACTGCACCCTCTGCCTCCTGGGTTCACACCATTCTCCTG +CCTCAGCCTCCCAAGTAGCTGGGACTATAGACGTCCGCCACCACATCCAGCTAATTTTTT +GTATTTTTAGTAGAGATGGGGTTTCACCGTGTTAGCCAGGATGGTCTCAATCTCCTGACC +TCGTGATCCACCCACCTTGGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCACCGTGC +CCGGCTTCTTTTGCCCTCTTTTTAATGGGGTTATTTGCAGTATTTTGCCAAGGTTTTTTG +TTTTTGAGATGGAGTCTCACTCTGTCGCCCAGGCTGGAGTGCAAAGGCACGGTCTCGGCT +CACTGCAACCTCTGCCTCCCAGGTTCAAGCAATTCTCCTGCCTCAGCCTCCCAAGTAGCT +GGGATTACAGGCGTGTGCCACCGCGCCCAACTAATTTTTGTAGTTTTAGTAGAGATGGGG +TTTCACCATGTTGGCCAGGCTGGTCTCTGGTCTCGAACTCCTGACCTCGTGATCCGCTCA +CTTCAGCCTTTCAAAGTGCTGGGATTACAGGTGTGAGCCACCACACCTGGCCGTTTATTG +AGTTTTAAGAGTTGTTTATATATGTATTTATTTAATACTAGTCCTTTGTCAGATAGGTGG +TTTGCAAATATTTTTTAATTTTGATGAAGTCCAGCTTATCAATTTTTCTTTTTATGGCTC +ATGCTTTTGGGGTCAAGTCTAAGAATTCCTTGCCTAGCCCTAGCTAGATCCTCAAGATTT +TCTTCTGGTCATCACGTCGCGTGGCCGCAGGGAGCAGACCCGGACAGCTCCAGAGCCTCC +GGGCCGGGGCGGCGGCGGCGACGCTTCGGCTCCTCCTGAGCCACCTGCTGGACCCGCACC +CCACTCCATCCCCACAGGCTGGGGACAGGCCCTGGCGCGGCTGTGTGGGATCAGAAGCAG +AGTTGCAGAATCCAAGGACCTATTTTTGTTCTTTCTCCGCACTGCTTTATGGGAGGCATT +ATGGCCCCCAAAGACATAATGACAAATACTCATGCTAAATCAATCCTCAGTTCAATGAAC +TCCGTTGGGAAGAGCAATACCTTCTGTGATGTGACATTGAGTAGAGCAGAAAGACTTTCC +TGCCCATGAGATTGTGCTGGCTGCCTGTAGTGATTACTTCTGTGCCATGTTCACTAGTGA +CCTTTATAGAAGGGGAAACCCTATGTTGACATCCAAGGTTTGACTGCCTCTACCATGGAA +ATTTTATTGGACTTTGTGTACACGGAAACAGTACATGTGACATGGAGAATGTACAGGAAC +TGCTTCCTGCAGCCTGTCTGCTTCAGTTGAAAGGTGTGAAACAAGCCTGCTGTGAGTTCT +TAGAAAGTCAGTTGGACCCTTCTAATTGCCTGGGTATTAGGGATTTTGCTGAAACCCACA +ATTGTGTTGACCTGACACAAGCAGCTGAGGTTTTTAGCCAGAAGAATTTTCCTGAAGTGG +TACAGCATGAAGAGTTCATTCTTCTGAGGCAAGGAGAGGTGGAAAAGCTAATCAAGTGCG +ATGAAATTCAGGTGGATCCTGAAGAACCAGTCTTTGAGGCTGTCATCAGTTGGGTGAAGC +ATGCCAAGAAAGAGCAGAAAGACTCCTTGCCCAGCCTGCTACAGTATATGCAGATGCCCC +TGCTAACCCTCAGGTATATCACAGATGTAATAGATGCTGAGCCTTTCATCCACTATGGTT +TACAATGCAGGGATCTGGTTGATGAAGCAAAGAAGTTTCATCTGAGGCCTGAACTTCAGA +GTCAGATGCAGGGACCCAGGACAAGGGCTCGCCTAGGAGCCAATGAAGTGCTTTTGGTGG +CTGGGGGCTTCGGAAGCCAGCAGTCTCCCATCGATGCAGTAGAGAAATATGACCCCAAGA +CTCAGGAGTGGAGCTTTTTGCCAAGCATCACTTGTAAGAGATGTTATGTGGCCTCAGTGT +CCCTACATGACCAGATCTACGTCATTGGTGGCTGTGATGGTCGTTCCAGCCTTAGTTCAG +TGGAATGTCTAGACTACACAGCAGATGAGGATGGGGTCTGGTATTCTGTGGCCCCTATGA +ATGTCTGATGAGGTCTTGCTGGAGCCACCACCCTGGGAGATTTGATCTATGTCTCTGGAG +GCTTTGATGGAAGCAGGCGTCACACCAGTATGGAGCGGTATGATCCAAACATTGACCAGA +GGAGCATGCTGGGAGATATGCAGACAGCCCGGGAAGGTGCCGGACTCGTAGTGGCCAGTG +GAGTGATCCACTGTCTAGGAGGATATGACGGCTTGAATATCTTAAATTCAGTTGAGAAAT +ATGACCCTCATACAGGACACTGGACTAATGTTACACCAATGGCCACCAAGCGTTCTGGTG +CAGGAGTAGCCCTGCTGAATGACCGTATTTATGTGGTGGGGAGATTTGATGGTACAGCCC +ACCTTTCTTCCGTTGAAGCATACAACATTCGCACTGATTCCCGGACAACTGCCACCAGTA +TGACCACTCCACGATGCTATGTAGGGGCCACAGTGCTTCGGGGGAGACTCTATGCAATTG +CAGGATATGAAGGTAAGTCCCTGCTAAGTAGCATTGAATGTTACAACCCTATCATCAACA +GCTGGGAAGTCGTGACATCCATGGGAACCCAGCGCTGTGATGCTGGTGTGTGTGTTCTCC +ACAAGAAGTGACCATTGTTGGAGCACCATCCAGAGCTAGTGACCAGTCCAGTGGACAGTT +AGTGGGAGAATCAAGAATCCTTTCTAGAATGTCTGTTTCTCACTATGTGCACAGGGTGAT +TACAGGCACCAGTGCAGTGATGATTGTACTTATTTGACACATACTCCCCCTCGTCCTGGT +TGTTGTTCCTGAGAAGGGTGGGTAACAGATACTCCAGGGAAAAGAATGCACATTGAATGG +ATGTGAGAGACCACATTACCTCTCCCACTACTTTGGGGAGCACTTTCCTGTCATTTCTAA +CTTACCACGTGCTTGGTGTACTATATGTATGTTGTGCCTCATATGTTGCAAAGAACTAAG +GTGAGTATAGCCTACTAGATGTGAGCAATATCCAGCCTAGATGATTGGAAAGATACCAAT +TTAAGTAAACTTGGTAAAATCCAAGTCTTTTTTTTTTCCAGGAACAAATACATTTTCTAA +TCTACAGGTAGCTAGGGGCAACACAGTTCCATTCTAAAGGGAAACAAAAGGGAGAGCCCC +ACAAAACTTTGGGGGCAAGGGAGAGATACTCATCTGACACTTCTTTTGGAGGTCAGGGTT +TGTATATCAGAATTGAAGTTAGAATCAGTGAATTAAACTGAATTTGATGGAATGTGAGTG +AACCTAGAACAGCACTGAAGTATTACATAACCTGGAAGACTGAGAAGGGTATATTCTTTG +AATGATCTTTTTATTTCCCCAAGGTCTTTCACACTGGAGACAGCATAAAAGAGTGAACCA +ATGTTGGGATGAGAGAAGATGACATAAATGTGGGAGTTCAGTATAACTGGGGATAAACTA +GAAGTACCTGTGATTTTACAGTCATCTTATTGCCTGCCAGGGGTCATCTAGCCATGGCAG +TGTTAACCTTGAATGGGGGTGAAAGCCTTTCTTTGTTGAATCAAATACTACTACACTATT +ACACTTCCACACTATTTATTTGGGGATGGACTGGGAGTGACAGTAGCCTAGTAGTTCAGC +TACCTGATTACTGCCCCATTCTTTTAGAAGCACACTTCTGCCAAGGAGTGGTTTGTACTG +CTGTGATTGGTACATTTAGTCTTTTTTCTGCTATAAGTTTTCCTTACCTGTCCTTTAGTG +TAGATTTTATTCATTACAGGACAGAATAATCAAGGACAACCAAAATCCTTTTGTTAGTTT +CAGTACCTCAGCTATCAACATTTCTGAGCTATCATTCAATGTTCCTCTGTGTCATGGAGT +GAAATTCTTGTTTTATGGGTATTGGGAGTGTGGGAATGTGATAACCTAAACAACCTTTGC +TCTGAAATTCCATTTTTCCCTCTTTCCCTGAAGTGTACTGACCTGTACTACAGAGTTAAT +TTCTTTTGTATTTTTTTAAGAAAATATTAAAAATCAATGGTCTCAAAAAAAAAAGATTTT +CTTCTTCTTTTTTTCTAGAAGTTTTATGGTTTTACATTTAACTCCATAAACCATTTTGAA +TTCATTTTGGTATATGGTATGAGACTTGGGTTGATATCCATTTTTTTGCCGACGCATGTC +TAATTGCTCCAGTACTATTTGCTGAAAGATATCTTTCCTCCACTCAATTGTTTCTGCACC +TTTGTCCAAAATCATGTGTAACATGACTGGGCATATTTACTCAGGTCTGTGGGTTTTCCA +TTCTGTTTCACTGATCTATGTGTCTATCACTGTATCCATACCACAGCCTTGATTACTGTA +GCTATGTAGTAATCTTGAAATTGGGCAGACTCCTCCCATCTTATCGTTCTTTTTCAAAAT +TATTTGAGCTATTCTAGTTCCTTTGCCTTTATATATACATTTCAGAATAATCTCATTTAC +ATCTAATGTCACAAGTAAAATCAAATCAAAATTAAAAAATTTATTTTATTTATTTTGAAA +TTTATTTTATTATTATTTTTTGAGACAGTCTCACTCTGTCGCCCAGGCTGGAGTGCAGTG +GCGCAATCTCGGCTCATTGCAACCTCTGCCTCCTGGGTTCAATCCATTCTTGTGCCTCAG +CCTCCCCAGTAGCTGGGATTACAGGTGTGTGCCACCACACCCAGCTAATATTTGTATTTT +TAGTAGAGATGGGGTTTCACCATGTTGGCCAGGCTGGTCTTGAACTCCTGACCTCAAGCG +ATACACCATCCTCGGCCTCCCAAAGTGCTGGGATTACAGACGTGAGCCACTGCGACCAGC +AATAAAAAAAAATTTTAGGCTGGATGTGATGGCTCACTTCTCTAATCCCTGCACTTTGGC +CGAGGCAGACAGATCCCTTGAGACCAGGGGTTCAAGAACAGCCTGGGCAATATGGTGAAA +CCTTCATGATACTAAAAATATAAATATTAGCTGGGCATGGTGGTGCTCACCTGTAATCCC +AGCTACTTGGGAGGCTGAGGCAGGAGGATCACTTGAACCAGGGAGGCAGAGGTTGCAGTG +AGCCGGGGTCATGCCACTGCACTCCAGCCTGGGTGACAGAGCGAGACTCTGTCTCAAAAA +AAATAAAAATAAAAAAATTTTTAAAAAGCTTATTGTGCATGTAAAAGAAGAGTTCATGAA +CCAGGAAACCCCAAACTGGAAGTGGTATGAAGCCCCAATTCACAGCAGTTACAACACAGT +TTATAAAGCATGAATGAGGAAGAATATTGTTCCCTACTGTGCATGTGGAGCTGCATAAGC +TTTCTTTGTAAAGCTATCACACTGAGGGAGGAAAGCTTAAGTTTCAGTTACATGGCTACA +GGCAGTTGGCCTAGGGGTATATCCAAACCTCAGCTTCAATTTTCATTTTCCCTTAATAGT +ACAAAAAACCTTCCTGAAATTTTGATAGGAATACTAGTATTCCTGTATTAATACTATATC +AATATGAGGAATTCTGTATTAATATATGTATTATTAATTGGGTTGGGAAAGAACTGACAT +TCTTACTATTCTTACTCTTCCAATCCATGGACTTGGTATGTCTCTCCATCTATTCACATC +TTCTTTTATTTCTTTCATCGGCTTTTTGTAATATTCAGTGTACCAATCCTGTGAGGTTTT +TTGTTTGTTTGTTTTGAGACGGAGTCTTGGCAGAGTCTTGCTCTGTTGCCCAGGCTGGAA +TGCAGTGGTGTGATCTCAGCTCACTACAACCTCTGCCTCCCGGGTTCACGCCATTCTCCT +GCCTCAGCCTCCTGAGTAGCTGGGACTATAGGCGCCTGCCACCATGCTCAGCTAATTTTT +GTATTTTTAGTAGAGATGGGGTTTTACCATGTTGGCCAGGCTGGTCTTGAACTCCTGACC +TCAGGTGATCCCCCCCGCCTGGGCCTCCCAAAGTGCTGGGATTACAGACGTGAGCCACCG +CGCCCTGCCAACATGACCTATCCTTTTTCATTCCCCAACATCTGATCCATCAGCAAGCCT +GATCAGTTTACCTCCACGCTACACTCTGAACCCTCCCATCTCCCTCCAGCTCCACAGCTG +TGTGCCAGCACAGGCTACTGCTGTCTTCAGCCCAGACCACGCAATGACCCAGGGCCAGCC +TCGCTTGCTCTGCTCTTGATCCTTGGGCTTCCTTCTTCTACAAGCATGCCCCATGCTTCC +TCTCCTGCTCAGGAAAAGCTGTGAGCCCCTCTCCTGCCCTGGAAGGTCCTTCTGCTAGAC +TAGGCAGATGGTTAGATATGAGCAGGGAAGTGGACTCCAGGTTGGCCTCAGCCCCTAGCA +TGGCCAGAGGGACTATGACCTCTGAGACATGTTAACCACACCTGGGGTTTCAAAAGTCCC +AACCCCTCTTTCAGTTAAGCTTATCCAGCTCAAGTAGGAACTAACCCCACAAGGAACTTT +CCACCCCCGGGAGCCTGTGTTGTATAGTTTGCCCCAGTTTTGCTTGCTTCGAAAGTAACC +TTTTGTTCACTGCAGTGGTAAAAAACACACCTCCTGGGTGAAGATTTAAGATGCTAATGA +GACATGCGATAAATACACTAGCACGTAGAGCCACAGTGCATGCGCTGCTAGAAGACCACC +CAAACAAAACATGCTTATGAGTAACACCTCTTCCCGCCCATTTATGAATAATCATGTAAG +CCTCCTGTAAGGGAGGTTTCCCATGCCAGTTGGGGCGATCTTATTCTGGAGCAGCCTGCT +CTGACTCGGCCTTCAGAATGTACCTTCACTTTTGCAATAAACTGCCTTACACTTATCTTC +GTTAATGCATGTCTCTTGCTTAAAGTCTTAACCAAGAAGACAAGAACCGAGGACACATTC +CCAGTAACATTTCCTCCCTCTGTAAATGGCAGGTCTAATTGACATCTCCTCAGATGGACA +TTCCCCAAAAAGTCCCTCTAGATTCATCCTACCAGAGCCCCCTCCCTGGAAATCCTCCAG +TTCAGCCCCCTCTTCATTTCACTTACCATAATTGTAACCACTTTACTGATCTGTTTTCTG +GTTAAGAGTGGTTTCTCCTACAAGGCTGTAAACACCATGGAGTGGGGAGTCTTTCTCATT +TCTTGTCACCACTGGATTCCCAGGACTTGGTACATGGTGCTTAGTAGTTGCGGAATGAAT +GCGTGCATGAAGGAACACCGGCAGCCACGATGCAGCTGGTTGAAAGCCAAGGCTGCCCCT +CTGTGGCCAAGCTGGAGAACTGCTGCTTCCCCAGCTGCCGCAGACAAAGAAACTGCTAAG +CCCCTCCCACAACACCCACCTAGGAGGCTTCCCCCAACACCCTTCCTGGAACAGAACCCA +AGAGCCCTCCTTGTCCACTTGGTCTCAAGGACCTCCTGATCTTCTCCATGCAAAATCTGC +TCCTTTCCCCAGGATGGGGGTACGGAGTGTCCTTCCAAAGAGGCTTCCTTCTCCCCAAAG +AAGCTGAGAGCAAGGAGCAGGCCACAGCTTGCAGCTCACAGCTGCCCAAGAGACAGAAAT +CTGTGTGGGCTGTGTGAATGACCTGGATAAAGAAGAGCTGGATCCATTGAGGAGACACTA +GCCCTGACCCCTGAAGTCAAAGTCTAAGTCCCTGGGGGAATTGGGGGTCATGAGAGATAC +TGGAAAGAGGCTTACAAAGGCCAGAGCTCTTGCTAAACTCCCTGAGGCAGTGCAGGTAGA +ACCTGCCCCCCATACCATCCTCTGCCTCTCAGGTGCTCGGTTATCCCCAAAGGTGTACCT +GGCCCATAGCAGGTGCTCCACAAATGCTATGCCAGTACTAGCGGGGTGCCCTGCTAGGGT +ACCCCTAGTACTGCTAGGGTATGCCCTGTTCTCGGAGGCTGAGACCCAGGAAGTAGGGGG +CCAGCAAGGCCTGTTCCTTCCCTGGGATCCCATGTCTGGTTGTTACACCAGGCCTGAGTA +CCCCAAAGTCGTAAGATAAAAGAGAGGCACCTCCCTAAAACATCATTTTTCCATAATGAA +CATAATTTTAAACATCTTCAAATTGGAATAAACCAAGGTATTATATAGGATGCACGTGAT +TTTTTTTTCAAGTTGTCCCAATATTCAAACATAGGATTTAATATAAAAAATAAAACCTTA +GAGTGTTTCTTGGCTCTGGAAGGCGCCACCCTTCAGGGGACCTAGAGGGAAGAGGTCTGA +GGATAGGCCAGTGAGCTCTCAGGGTCCCTTCCTGTTTAACATCTCTGGAAGTGTCCCAGC +TCGTCTCAGCTGCACAAAGAGCAAATGTTCTATCCACATTTGAACTACAAGGTTTAAGCA +GCTTGCCAGGGCCAAGGTGGTGTGACAAGGTCTCAGCATGTAAGACTCACAAGTGGGGCA +CAATTCTGAGCAATGGGGTCTGGATCCTTGATGAGCCTCCCCAGGTGGACTGGCTGAACC +TCATGGGGCCTCATCAATGCATTCAATGCAGGGTCTCTGGAGAAGCATGGATTCTGCTCA +CTGAGCCTGTTTCTCTGACCTGGGACAGGCCTTGACACCTAGGCCTCTCACTCTTTGCAC +ATCCTGGGGAAGGAAATTAGGCAGGAGAAGGCCCCTCTTCGAGGGCTTCCTTACCTCCCT +CTTGAGTGGGGCCACGTATGCCCAGGAGTTGGTGGCAGGGTCGTAGCGCTCCACAGCATT +CAGGTCATTGTGGTAGTCACGGCCCGCCACAGCGTAGATGTACCTGCCTACAACACACAC +GGACAGGTCGGCGTGCTCCTGCTGCAGGGACTGGATCTGGAACCAGCGGTTGTGCCGTGG +GTCATACCTGTGCCGAGACATGAGGAAAGCACAGCACTGACTAGGCAGGGAGGCTGCTCC +GCAGGCTTGCACCTCTTGTTCTGGTCCCATTTCTGCTTTGCCTCAGCCCAGCCTGAACCC +TCCCCAACTACCCCACATACCAGTGCACACCGATCTACAGCCAGGCCCACAGGCTGTTAC +ACACCTGAGCACAGGTGCTCCCCACCACACAGCATGGAAGGAATGGCCAGGAGCCTCCTG +TGTTTCCACCTAACTGTCCACCTGGGCTGTCCAATGGCTCTTTTTTTTTTTTTTTTTTTT +TTTTTGTGGAGAGAGGTCTCTCTGTCCCCTAGGCTGAAGTGCAGTGGCACAATCATGGCT +CACTGTAGCCTCGACCTCCTGGGCTTAAGTGATCCTACCACCTCAGTCTCCTAAGTAGCT +GGGACTACAGGTGCGCACCACAACGCCCGCTATTTTTTTTTTTTTTTTTTTTTTTGATAG +AGACAAGGTCTTGACACCTGGGATATGGACTTAGGCAATCCTCCTGCCTCAGCCTCAATG +GCTGTTCGTACAGCCACTTCCATCTCACTTACCTCATCTCATCATCCACATAGCCTTGCT +CCCACTCAGGAGGGCCTCCAAATACAGCCTCTCCACTGGATGGGTGCCATCAGCCCCCTC +ATTGGCCTCCAAGCCTTGAACTTCCCCCAGCACTCCATCAGGAGTGGTCTTCTCAGGCAC +GCCCTGCACACAGCACCCATCATACCCTCAGCTTTGTCAACAGCCGCACACACAAGGCTC +TGGTCATCGTACTTTCACCTCCTCCCACCATGCTGCCAGCCCCGCGTTTCCTGACCTCCC +CTCCACTCAAGGTCTCCCTCTCTGGGAAAGTGGAAAGGGTTAACTCCCACCCTGGACTGC +AGGCTCTGTAAGGGCAGGGTGTGTGAGATTCCAGGGACCCCCATGGGAGAAAAGGCACTA +GACTGGTTGCGGCAGGCCCACGAGGGTGGAGGAGTCTGGCCAGGACCCAAGGAGGGCTCC +TGGGCTGAGCACCAACAGGGAGCATGGCCTGCAATGTGGAGCAGAGATGATCACAGAGCC +ATGAGGGGCCAGGACCCAGTGAGCTCAAAGCCAGTATCTGAAGTGTCCTTGCCCAACAGC +CCACAGATAGTTACAGCCTCTTTCAGACAAGTGTTTTTATTTCTGCAGAGGAAGACCTAT +TCCAAAGAGAACAAGTCTAACTTCAACTGGCTCACAAGAGAGTAACCAAAGTTTTCTTTG +GCCTGTGCCCTATGCTGGTTAGTGAAAAGATCAGTTTCATCCTTTGCTTCCTGCAGCCCC +TGCAGTGTGGCCAGCCCCTCCCCGCCGCCTACCAGGAATGCAGCAAACAGGAGCCTCAGA +AGGCAGGGCCAACAAGAGAGGGAACACACACCTGGGTCTCCCTGACCTGGTGTGAATCCT +GGGCTCTTCCCTGTCTAGCTGGGTGTGCCTGGGCATCAGTTTTAATCTCTTGGGATTCGC +TCAGTTCTGCACCTGTCCAATGAGGTGATATCACCTGCCTAGAAAAGCTATCAAGAAGAA +TCATAAAAGACGAGCATGAAAAGTGTCCTTGTTAACTTGGGGGTTCTGATGGATCATGGT +TCATTTCTATATTCCTAGACCTCAGTGTAGCCTCTGGCTCAGGACAGATTATGTTCTGTC +TGCTGAATGAATTAAACAAAGGAGTAAGATTACCAGCAATGAATCATTCATTCACTCTAC +CAACATTCCCAGGTCTCCCACTGTGGATGGGGCACAGTGCTCAGCACTACATCCAGAGGG +AGCCTCAAGAGGTCAGGGCCCTGCCTTCCCCTGCAGAATGGAAACAGGCTAACCAGAGCA +AATGAGTGCTTAATATAATGACAGACACTGTGAAAGAAAGAAAGGGAGGTAAGAAGATGA +GTGACCTGCTGGTCAGCGGGGCCTGGGGAGGGCAGAGCTCCCTTGCAGTGATCAGGAAAG +GCCTCCTGAGAAGGCAGGGTCTGAGACCTGCATGACCTGGGGCACAAGCCAGAAGAAGGT +CTGGCAGGGGACCAGCAGTCCAGGATTGGGGCACAGCACTCACAGGGGCCCCGTCAACTG +GCTGGGATGGTGCTGTTCACTGCCTTTCCTGTGCGCCTTCCTCCTTTATATACAAGTCTC +TCCTCTCTTGTGTTCAGTCTGGCTCAATCACCATCTGCACCCCAAGTGTCTGCAACCAGA +GTGAGATAGGACCCTCCATGTGCTCCTGTTTGCTCCTTCGAGTCTATTGTCCTCACAGCT +TTTTAAGCTGAGTTCATGTGGATTTGTGGCTTCAAATTTAAAGACACACACAGGGCCGGG +CGTGGTGGCTCACGCCTGTAATCCCAGAACTTTGGGAGGCTGAGGCGGGTGGATCACGAG +GTCAGGAGTTCAAGACCAGACTGTCCAATATGGTGAAACCCCGTCTCCACTAAAAATATA +AAAAAATTAGCCAGGCATGGTGGTGTGTGGCTGTAGTTCCAGCTACTCGGGAGGCTGAGG +CAGGAGAATCACTTGAACCCGGGAGGCAGAAGTTGCAGTGAGCTGAGATCATGCCATTGC +ACTCCAGCCTGGGCGACAGAGTGAAACTCCATCCCCCAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAGACACCAACAGTGATACCATATGTCAATAATTTAGACATAGCCAAA +GTTACACTGATTTCTTATTTCCCTGTTGTGTCCTGTATCCCTCTTCTTCTTTATTGAATT +AATTTTCTACTTTATGAGAATAAGTCCTCAAGTAATATTTTTCTAATAAAAATAAGCTTT +ATTTTTGCATATAAAGATATAAACAATTTTACTTATTGCTATGGACTAGATGTTTGGATT +CCCCCAAAACCCCTATGTTGAAGGCCTAACCCCCATTGTGATGGTAGTGGGAGGCATGGC +CTTTGGGAGGTGATCAGGTCATGAGGGTGGAGCCCCATGATGGGCTTAGTGCCCGAGGCT +ACAGCTCTTTCTCTCCACCATGTGAGAACACAGACGGAAAGGACCTTACCGGGACTAAAC +TGGCCAATACCATGATCTTGGACTTCCCAGTATCCAGACAGTGAGAAATAGAGGTATGTT +GTTTAAGTCACTCCATCTATAGTATTTGTTATAGCAGCTGAAACTGACTAGGAGAGTCAC +TTTAACTCAGATTTGTATCATCCTATTGTAAACTCAGACATGAACCCTAGAGTTGGTACA +AAAATATTCTGGAATTCTTGTTAAATTCATTAGACTGTGGCCAGGCACGGTGGCTCACGC +CTGTAATCCCAGCACTTTGGGAGGCTAAGGCGGGAGGATCATGAGGTCAGGAGATCAAGA +CCATCCTGGCTAACACGGTGAAACCCCGTCTCTACTAAAAATACAAAAAATTAGCCAGGC +GTGGTGGTGGGCGCTTGTAGTCCCACCTACTCGGGAGGCTGAGGCAGGAGAATGGTGTGA +ACCCAGGAGGTGGAGCTTGCAGTGAGCTGAGATCACGCCACTGCACTCCAGCCTGGGTGA +CAGAGAGACTCCAACTCAAAAAAAAAAAAAAAAAAAAAAAAATTCAGTAGACTGTTTTTC +TTCTATATTTCCATGACTTAAGTATTTTCATGACTATTAATGTTTTAATGTCTATTAAAT +TTTTTAAATAAATTAAATGTACTGACCGGGCACGGTGGGTGGCTCATGCCTGTAATCCCA +GCACTTTGGGAGGCTGAGGCAGGCGGATCACCTGAAGTCAGGAGTTCAAGACCAACTTGG +TCAACATGGTGAAACTCCATCTCTACTAAAAATACAAAAAAATGGCCGGGCGTGGTGGCT +CACACCTGTAATCCCAGCACTTTGGGAGGCCCAGGTGGGCAGATCACCTGAGGTCAGGAG +TTCAAGACCAGCTTGGCCAACATGGTGAAACCCTATCTCTACTAAAAATACAAAATTAGC +CAGGCATGGTGGCGTACACCGGTAATCTCAGCCACTCGGGAGGCTGAGGCAGGAGAATTG +CTTGAACCTCAGAGGCGGAGGTTGTGGTGAGCCAAGATTGCACCATTGCACTCCAGCCTG +GGCAGAAAACAGCGAGACTCCATCTCAAAACAAAAAAACAAAAAAACAAAAAAATTAGCT +GGGCGTGGTGGTCGGCGCCTGTAATCCCAGCTATTCAGGAGGCTGAGGCAGGAGAATGGC +TTGAACCCGGGAGGCAGAGGTTGCAGTGAGCCGAGATCGTGCCACTGCACTCCAGCCTGG +GCGACAGAACGAGACTCTGTCTCAAAAAAAAAAAAAAAAAAATTAAATTTACTTTAAAAT +ATTAGCAGCCATGAAATGCCGAAGGAAAAATTACATTATTATTTAAAAAATTTTTTTTAG +AGACAGGGTCTCACTCTGTTGCCCAGGCTACAGTACAGGGGCATGATCATAGTTCACCGA +AGTCTAAAACTCCTGGACTCAAGCGATCCTCCTGCCTCAGCCTTCCAAGTAGCCAGGGCT +GCAAGCACGTACCATCAGGCCCAGCTAATTTTTTTTTTTTTTTTTTGGTAGAGACGAGGT +CTCGCTTTGTTGCCCAGGCTGATCTTGAACTCCTGGGCTCAAAAGATCCTGCTGCCTCAG +CATCCCAAAGTGCTGGGATTATTGACATGATCTGCACATAGCCTAAATTATTATTTTAAG +TAGGGTCAGGGCACATAGCAACATGTAACCAGCTACTACTAGGTATACCATGTAGTTGGT +GTTCAGTAATCCACAGGGCTATGGCTATGGGAAAGGTACAAGGAATGATGCAGATAATAT +AGATGCAAAGAAAGAAGGAATGAAAGAGAAAAAGTAGTATATTGGAGACAAACACCATTT +GCTCCAAGAGAGGAAAGGTTTTTAAATATGCGGTTTCTGCACCAATGCTTTAAGATATAA +CCTGGTAAGTAATAACTCCTCAAAATGCAAAGCCTAATTTACTGCAAAATCTTGTTTCCT +TATATTCTAAAAGCCTATAGCTTTTAGAATTCACCAGTTCTAAGGCTGATGAAATGAGAA +AGCAGAGAAAGAACCAAATCTTAGAATATTCAAATTAAGGATTCATCTGGAAGTTTTGAG +TCCACTGGAAGGTTAATGATGCCTTCATTCTGGAGAGATGATACATCCCTGGGTTAACCA +GTAGGGCTGTGGTCCTTCCTGCCACCTCCACTCTGTGGATACCTACTCTCTCAAGGCAGG +TCTTGCCGACCCCACTTGCCATTGTGATCCTACTCTCAGACAGGAGTTTGGGACTGGTTA +TTGGTTACAGGGTCTAATATTAGCATTACCCAGAGTTCAGCTTTGGTCTCACACCCCTTC +ACAAGGGGAAATTCAGACTCCTACTTTAAGTGAAAGTGAGATCAATGGCCCATAGCAGGT +GGACAGAGGACAGGGGCAGGCAGAATCCCAAGCTGTCACCCCCCTAGGGACAGCTCTGTG +GAAACATCCAGCATTACTGCCAAGCACACAGCTGTCTCTACCTTCTGCTAAGGGCCAGAA +GCCAAAACACTCTGGAGAGATTGGCTTTGCAGGTCTGTAGGTTACTCTCAGCAGGGTGGT +CTGGCCTTGGCCCCCCAACTGGGAAACCGAGCCCCCTAAAAAAGAAGGTTTAAGGTTTGG +CCAAAGGGAAGTCTAAACCTAGTGTGGCCACACCCACTGGGGGCACAACTTTGTTTAGAG +AGGAAATGAAGGTAGCTGTTTCCTTTTTTCTGAAACCTGCCCTTCCTCATATTTAACCAC +AATGTGTTATTGCCAACCTCTGAGTCTCATCAGCTTAACAAAGGAGATCACTTCCTGGGG +CCAGCAGTAGAGAGGTCGCTGAGAAATGGCCTTCTCCTCCTTGGCCAGGATCACTATGCT +TGATTCCAAGTGGCATGGCCAGGCCAGGCCCTACCCCACCCTGACCCCAGAAAATAGAAA +CATGAACATGAACTCAGTCAGCATCTAGCTCATGGCTGCTGGAAATAGTTGGCAATCTCT +CTCTCTCCAACACAGCTCCATCTTTCAGCATGAAGGGTAGGGAGATTTCTCACATGCACC +AAGGTAAGGTGGAGGGGTCCCTGGAAATCTAATGGTAGCTGAGTCTTGTGGGCCTGAACC +ACTGTCCCTTGCTCTGCCCAGAAATGGATTTGTGAGATCACAGCCTAAGTGACTGATGGA +GCCAGGCGCATCCTACGGACCACAGCAGTCCACAAAACTCTCTCTTGGGAAAACTGCCTC +TTCCCAGGGGAAATTGTGCCAAGTGCGTGGCAGACTGCAGGGCAGAGCGGAAATGTAGCA +TGAGGCTCGGTGATGCTTGTTGGCCTTTACCACGCCCCTGGGCTGAAGACCGCATGCTGC +TCAGGCACAGCAGCAGGAAGCCTGTTCCACCATTAGCAAGCAGGTAAGAGAGAAGAGCAA +AGCTGACTGGTGAAGGGAAACTGAAACAACATGCATCAAAGCTCAGAGAGAGCATGATGG +AGGGCGAGGCTGCTCAGCTGGCACTGCTCCTAGGTCCTCTCCATCCCAGTCCGACTGCCT +TTCCTGCTGTGGGCTCCTCTCCCCTCCCGTCTCCTCCTGCACAATGCACTCGCAACCTAG +CCTACCCCAAAGAGGCTGAGCAAGGGTCCAGGGTAAGTGGGTTTCTGAGGAGTAGGGGAC +ATGCAGGAAAGAAGGCGATCCACATGTCCCCTTCTCTTATCTCACTGCTGTCCACCTTCT +CTGAATTCACCTAGACTTCATTCCACAATGGCAAGTGATGCTCATGTGAAAGGCTGGGGG +GAACCTGACCAGCTCTCTCAGCCCATGACTTCCACACCCTCTCATCACCTGAAGACAAAG +GGACCAGCTAGCACCCTGTCCTACCTCCAGCATCGGGACTCTGCTCGAAATCCTTGGACA +TTGTTGTCCCCTCCAATCAAGTATACGAAGTTGTTGAGCACCGCGATGCCCTGGTTGGAC +ATGCGGGGGGCCAGGGAGGCAGTGAAGTGCTTCCACTCTCCCAGTAAGGGGTTTAGATAC +TTGGCCTGGTCGCTGAGGACAGTGGACGGCGTGGAGTGAATGCCCCCGAAGCCCACAACG +CACTGGAAGTCCGACCGCAGCTCCGTTTGCGGGCTCTGCAGGCTGGGCTGTAGGCTCTCG +TTCCGGTGGTACATGAGGGCGCTGGCCACTGTGTCCCTCAAAGGGCTGGGGTCCAGCTTG +TCATGCAGCCGCTGCAGGACCTCAGCTTCCATCAGCGGAAACCGCACTGTCTCAAGGAGC +TTTGGGGGCTCGTGCAGCGAGATCTGGTCAGCCTGCACCTGCTCCAGGCTATAATGGTAG +AGAAGGGCCCCCTCATATACCTCGGTCTCGCAGGAGACCTCCAGGCGATTGCTGCTGAGG +AGGGAGTAGACCTTCTCCAATGGAAGCTGGCGGTACTTGTCAGTCCGAGAGAAGGCCACA +AAGTTTTTGAGGATATAGGTGTCCAGTTGCTCAGTCAGGCGGCTCAAGTCAAACAGCTCT +GCCAGCCGGTAGACATCGAGAATGTTCTCTTCGTCCACCCAGGACATGAGGAAATCACAG +CAGAAATGGATAATTTCTGGGATCTGCAGAGAGAATGACACCCATTCAAGCCTGGGCTGG +TGAACAGCATCTGGGGGTGGGAGAGAGAATGATGGCAGAAATACGGGCTGTTGTGGGCCA +GGCAAAGCAGAAGGGAAGTCCTCCTTAATTGTCCCCGACCTTTTCTGACACACTGGAGAC +TGGGGCTTACTGCAGACTAGGTTTAAGTCCTGGTTTGGAAACATACTGGGTGACAGGATA +TACAGCATGTTTTTTTTTGGTTTTGTTTTGCTTTTCTTTGAGACAAAGTTTCGCTCTTGT +TGCCCAGAATGGAGTGCAGTGGCAGAATCTCGGCTCACTAACACCTCCCCCTCCCGGGTT +GAAATGATTCTCCTGCCTCAGCCTCCCGTACAGAATGTTTTTAACCTCTCTAAGCCTCAG +TCTCCTCATCTATAAAACGGGGATCATTAAAGTGAAGAGGAACATGATGAAAATGAGAGA +GCACATAGGAGTGGACCCTTGATATATGTCAGTTCCCTCTTAGATCAAAAGTACTGGCTC +GGCCGGGTGCGGTGGCTCATGCCTATAATCCCAGCACTTTGGGAGGACAAGGTGGGTGTA +TCACGAGGTCAGGAGTTTGAGACCAGCCTGACCAACATGGTGAAACACCGTCTCTACTAG +AAATACAAAAATTAGCTGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCAGGAGGC +TGAGGCAGGAGAATCGCTGGAACCCAGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCC +ATTGCACTCCAACCTGGGTGACAGAGCGAGACTCCGTCTAAAAAAAAAAAAAAAAAAAAA +AAAAGAAGTACTGGCTCTCCAGAAAAGCAGGAAGCAGCACAAATGGTCACTGTGTCATAT +ATCTGTGGTTTGGAAAGGACCTAAGACCATCCCCATCCCTACCCTAGGATTCTCTGGAAG +AGCCTGCCTCTCCAAAAGCGCTGGGACCAGAAACAAACCTGGCTTTTTCCCCCGCCAGAA +CATCCACCCTGGTTCCCTAGAAGTGCTCAGAGCCTCTCAGACACCTAACCAATACCCACC +CAGGAACCTGATTTAGAATTATTTTTCTTTTTTCTTTTTAAAATTTGAGACAGGGTCTTG +CTCTGTTGCCCAGGCTGCAGTGCCATGGCAAGATCATAGCTCACCGAAGTCTCAAGCTTC +TGGGCTCAAGTGATCCCTGACTCAGGGTTCTTGAGGTTCCCAGCTGGGTCAAGACCCACT +TGACTCCAGTAAGTGCAGGGGCTCCCAGGTGGCCATATCAACCCTTCCCAGCCATGGGGA +AGCACTAGTGGTTTGAAAGGACGGCAAGAGAGAGAATGACACTGGAGGGAGGTGGGAACA +AGGCCACAACCAGCAGGCTGTTAAAGGCCACCCTGTGAACAGACAACCAAATCTTGGGAG +AATAGGAGACAAAGGGAAGGGCCCTAGGGAAAACTGCCTGGGAGAACAAACCAGGTGTTG +ATAAATTATTTAGGAAAGCAGGATTTTAGAGTTTCAGTGGGGCCCCCCAGTGCCCACCTC +CTTTCTTTCCATGTTCAGATTGAAAATGACGAGTACCTTGACCTCTCTGTGACCCAGACA +GCTGCAGGTTCTCCCAGCAGGCTTGAACCCAAACCAGGCCCTTGAACATTCCCAGGCACT +GATAAAGGCATCAAGGTTGTTACCCAAAACACTGAAGGAAAAACTGGTTCTGGCCCTGAG +ACAAATTCCTTAAACCCTCATAGAAACTCCATACACTAACCCACTCTGTGGGCAAGCCTG +GGTAAAGCCTCTCTTTTCCCTTGTCTGTCTTGAGGACATGCTACATCACTCTATACATAA +GTTCCCCTAATAAACGCTCTGGCCAGATCACCCTGGTGTTTGATGCTTCTTTCTTTGGAA +TCCCAAAACGGCTCCATTTCAGGATGCTGTGGGGTCCCCTCTTGTGGGAACCCCCTTGCT +ACCAACTCCAGCCATGTGTTCAATGCAATAAATCAGTTTCTCTAAAAATGGGAATACCTG +GCTTATCCAGGATCATCAATAAATTAACCATTACACATGGAATAATTCTGCTGGTATTTA +TGTATTTATTTATTTATTATTTTGAGATGGGGTCTCACTCTGTTGCCCAGGCTGGAGTGC +AGTGGCACGATCTCGGCTCACTGCAAGCTCCGCCTCCCGGGTTCACGCCATTCTCCCACC +TCAGCCTCCCAAGTAGCTGGGACAACAGACGCCCGCCACCACGCCCGGCTAATTTTTTGT +ATTTTTAGTAGAGACGGGGTTTCATCGTGTTAGCCAGGATGGTCTCGATCTCCTGACCTC +GTGATCTGCCCGCCTAGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACGGCGCCC +GGCCAAGGTATTTAAAGCTTATCAATAAACACTAACTATAACTTTTTTAAAATTCAAAAG +ACATCTAATATTGCTTGCAAGGTGACATGCTAAGAGCTGGATGAGACCTACCAAATGTCA +GGCAGGTATGTGCCCTACATGAGGTATCCCCATGGTGCTTTGCTAGGCCCTGACCAGCTT +CACTTGACCTTCTTTTTTCCCTTTTTGCCAGTCTTCTGCTTTGCCACTTCTTCCCAAACT +ACTAGGTTTTCCTAAAATTCTGGTTTGTCATGGGCCAGGGTCCTGAAGACCAAGTTTTGG +GCAGAATGTGAGCACAAACAGCCCTGAAGAAGCCTGGGCAGCAGCAGCTCCTTGAGAGGA +CCCTGCTGACTCTCCTTTCAGTCCTATTTTTAGAGCAGTGGGCCTTCTGTTCAGTGAAAT +CTCACAGAGGAACCAGCCTGGGCTCAGGATGTGCAAAAGCCCCATACGAGGCTCACAGAA +GGGACTGCATTTGCTTGGGGTAACCCAATAGGACAGTGTTACTGGGAATCAGACTCAGGC +CTCTGGGGACACCGTGAAGAATCTGGTCCCAGGCCTACTGCAGGGCACAACACATGGGGG +AAGCCTCCAAAAGTCACTAGCTATGTGAACATACATGATTCTACAGGCCTATGGACTTGA +CATGGTTATGCCAAGTAAAACCTGCTATAAAACAATATTGTGAAGAAGCCTGTTTTTTTT +TGTTTGTTTGTTTTTTGTTTTGAGATAAGCTGGCATGTAGTGGTGTGGTGATCACAGCTT +ACTGAAGCCTCCACCTCCTGGGCTCAAGTGATTCTCCCACCTCAGCCTCCCGAGTAGCTG +GAACTACAGGTGCATGCCACCATGCCCGGCTATTTTTAAAGTGCTTCTGTAGAGGTCTCG +CTTTGTTGCCCAGGCTGATCTCAAACTCCTGGCCTCAAGCAATCCTCTCACCTTGGCCTC +CAAAAGTGCTGGGATTACAGGCATGAACCTCCAAGCCTGGCCCAGAAGCCTGATATGTTA +AAAAACTAAGATAGGCTGCTGCCTCTGAGATGACCTCTGAGGCACTGGGGGAGATGACCC +AGGGCTGTCGGGAGCACTGGCCAAACCAACAGAGAGAGACTGCAGGCCTCCAAGCTGACT +GGTGAGAGAGGGAAAGTGATGTTAGAAAGATGATCTGGTTTCAGTGTGTGTGATCACTGC +AGGGAGAAGAAAGAAATGGCAGAAACATACAGATGGAGGCCAGGCAAAAGGGAAGGAAAT +GGAAACACAGAACAGAGATGGCTACAAGCAATACCGAGAAGGATGACCTGTCCTCACATG +GACGCAGGGAATTAAGAAGGTGGACGGGCTCAAGGAGCCACTGAGGTTGAGCCCAGGGAA +CTGGCAGGATGGTCACAGGACACACAGAGCAGGGGGACTGACAGGGGAGCTCCGGGAGAG +TGGCAGGTGTGGAGGAGGAGATAGGACAGCTGGACCTGAGCCATGCTGGGGGAGATGTTT +CAGAGGCAGCTGAATCAGGAGTTAACTGCTGCCAGGGTGGAGAATTGGATGAGGGTTCCC +AAAGCAACAATGACAGGGATGTGGGGACAGAAGAGATCTCTAAATAAAAGAACAGGGGGA +AATTCTTTTGTTGTAAAAGCCAACTCCATCTACTCACCATGCAGGTATGGTGAGACAAGT +CAGTCATCTCAGATCAACCCACCCAGCATCCAGGTCCTATCCACCAATCTGAGAACAGGG +CACAGGGAGGCTGCCAGGGCCCTGTCACATGGGGTGGCACCTCCACATGCCCCCGAACAG +GTTGGTTTTCCTGTGACTTGAGTTGTTTTTTTTTAATTGCGTCAAACCTGCTCTCATGGG +AAGAAAGGTCAGAATGATGAACTTAGCATAGCATTTTGTTTCACTTTTAAGAAATGTGGG +AAGAGGTGACTGTCAACTCCTATCAGGCCTCTGCCTGATAGCTCAAAGGCACCTGCAGGC +CCAGTCCCGTGTAACTGCACCCACACCACTGAGAATAATCATCCAAAACATAAGTCACAC +TGTCAAAGCCTCAGAAAACTTTTTGAATTCTGCAGGAAAACAAGTACTTAAAGTTCAATA +ACAGGTTGGGTACAGAGGCTCACACCTGTAATCCCAGAACTTTGGGAAGCCAAGGTGGGA +GTATCACCTGAGGCCAGGAGCTTGAGACCAGCCTGGGCAACATAACAAGGCCCCATTCCT +ATAAAAAAATATATATATATATAATATCAGCTAGGCACAATGGCACGCATCTTTAGTCCC +AGCTACTCAGAAGGCTGAGGCGGGAGGACCACTTGAGCCTAGGAGGTGGAGGCTACAGTG +AACTATGATCATGCCATTGCATTACAGCCTGGGTAACAGAGTGAGACCCTGTCTTTAAAA +AAAAAAAAAAAATAGGCCAGGCGCAGTGGCTCACACCTGTAATCGCAACACTTTGGAAGG +CTGAGGTGGATCACTTGAGGCCAGGGGTTCAAGACTAGCCTAAGCAACAAAGCAAGCCTC +TATCTCTATAAAAATAATTTAAAAATTAGCCAGGTGTAGTGGCACATGCCTATAGGTCCT +AGCTATTTGGGAGGCTGAGGCAGAAGGATTGCTGGAGCCCAGGAGGTTGAGGCTGCAGTG +AGCTGTGATCGTGCCACTGCACTCCAGCCTGGGCAAGAGAGAGAGAGCTTGTCTCCAATA +AATTGAATGAGTGGATGGATGGATGGGTGGATGGATGGATGGATGGATGGATGGATGGAT +GCATGCATGGATGGATGGATGGATGGATGGATGCCTGCCACCATGGATGGATGCATGCAT +GGATGGATGGATAGATGGATGGATGGATGGATGGATGGATGGATGGATGGATGGATGCAT +GCATGCATGGATGGATGGATGGATGCGTGCATGCATGGATGGATGGATGGATGGACAGAC +AAATAGATAGATAAAGTTCAGTAACAAAACACATAAGTTTTCAAGAGACTGAAGTGGCCC +AGTGAGGGGACAGGCAGGAAGGGCCCTGGCAGCAATGCTGGTGGATGCTCCCCATTGCCA +GACCCCAGAGCACACAGGACGTCCACATGCAGCCTCGGGTCAGCCTACCTGCTTATGTGC +AGGATGCTTTCAATGACAGGGAGACTCAGACAGTGGGGAAACAACCAGCAATAGAGAAGA +GGGCAAAGGCAGAGGCCTGGGGTGTCTAGAGCGGCTCTGCTTGAGCTCCAGGAACAACTC +CAGAGTCTTCCCCACTTCATGGCCTTCGTCACTGCTTGGTCTCCTCACATTCCTGACCCA +TCTTCAAGCCAATGCTAGTGCCCGGCAGGCATCATGGGCATCTCAGGGAACCCCACCTGG +GTGTGGGTCTGCCTTGCTAGATGAGACATGCCTCACCTGAAGCTGGCAGGCAGCCACCAG +TGTCTCTTGTACATTGCTCAGGCTGAGCTCCAGCTCGGAGGTGTATATGAAATGTAGGAT +TTGGCACATAGCATTGTAGGACACACCGTGGATCAGGACCTCTTCCTGTTCCATCTCCTT +CAATCCCCCAGCAAACATTCCTCTGCAAAGTGAAGACACAAGAAAATGGAGTTATACCAA +CAGGGACTTAAGCCCATGTTGCCAAGAGTGACAGCATTCAGAGAAGAACCTGGCGCTGGT +GGCAGGGCCCTGGTAGTGGGCTGACCCACTCTGTGCTCTGAGTGAACTGTGTGCATGCAT +GAGCCATCCCACAAAAGGATCCTGACGAAGTCTGGGCAGCCATCCTGGAAATTGTCCTGT +TTCCCTTTTCATGGGCCCAAGGAGTCCCATGTGAGCTTCGGGAGGTGAGGCCACAAGCAG +CTTGCTTCTGCTGTGTTCATCAGTGCAGTTCCTGGATCGGAGCAGTAGCAACTCCAGAGC +ACATTTCAAAGCAATGAATTAATTAATGGGAAACTAATAAAAGTCATTTCATTCAATGTA +TATTTATGGAGTTCCTACCAAATGCCAAGTATCATTCAAAGAGCAGAAGGAGGCCAGGCA +CGGTGACTCACACCTGTAATCCCAGCACTTTGGGAGGCCAAGGCAGGCAAATCACTTCAG +GTCAGGAATTCGAGACCAGCCTGGCCCACATGGTGAAACCGCGTCTCTACTAAAAATACA +AATATTAGCCGGGCATGATGTTGTGCATCTGTAGTCCCAGCTACTTTGGTGGCTGCGGCA +CAAGAATTGATTGAACCTGGGAGACGGAGGGTGCCATGAGCCAAGATTGCACCACTGCAC +TCCAGCCTGGGCAACAAAGCAAGACTGTCTCAAAAAGCAAAACAAAACAAAAAACAAAGA +GCAAAAGGAGTTATAGTGAAGTAAACTGGTAAAATAGCTGGGCGCGGTGGCTCACGCCTC +TAATCCCAACCCTCTGGGAGGCCAAGGCAGGCAGATCCCTTGAGCCTAGGAGTTCAAGAC +CAGCCTAGGCAACACGGTGAAATCCTGTCTCTACAAAAATTACAAAAATTGGCCGGGCGT +GGTGGCTCACGCCTATAATCTCAGCACTTTGGGAGGGCAAGGCGGGCAGATCACCTGAGG +TCAGGAGTTCAAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAA +AAATTAGCTGGGTGTGGTGGCGGGCGCCTATCATCCCAGCTACTCAGGAGGCTGAGGCAG +GAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCACACCACTGCGAT +CCAGCCTGGGTGACACAGCAAGACTCTGTCTCAAAAAACATATATACATATATAAATAAA +TGCTAAGAAGGAACCCAGCAGGGCATCTGACCTGAGAGTCACTGGTTAGAAGAGGGGTAG +GTGGAATGATGAGAAGGAGCAGGGAAAGCCCCATCTGAGGAACTGAGACCTAAGGATAAG +GCTGAGAGGGTGTAGGCAGCCGGGGAGGGAGTTCCAGGTGAAGGAGACAGGTGTACAAGT +TCTGGGGCAAGGCAGAGCTTGGCATGCAAGGCAGCCAAGATGATGACGAAGTGAGCAGAA +AGTGGGATGGGCAGGCAGGCCTTGGAGCCAGGTCCCCCTACCTCTAGGGTAGGTACAGTC +CAGATTGAAATCTGAGCATTATGGGATGCTCTTGAGGAATTTACCCACAGAGTGATGTGA +ACTGACTGGCTTTCCGACTCAGGTGCTGGAGGAGGAGCCCCTGGAAGACCAATTAGGCCT +GAGATTCCTGTGGGCCTGGAGGCCAAGGGTGACCCTGGCCCTGGGGAGGGCATTGCAGCT +AGAAAGCAGTAGCTGAGACTACCCTGGGACACGGCACAGAGAACCTACTGACAGACTGAA +TCTAGGAGGACCTGGGAGGACTCAAGGCCCTCTGCTGGGCCGAAGAGGACCCTTTACTGA +TGGAAGAAAATCTGGACAGCTGGGAGTCCCGTGATTGTGTGATCAGTGTGAGATACCTGT +GAAACCTCCAAGTGTAGACACTGATTAGGTGTTTGGAGGTAAGAGGCTGGCAACTGGGGC +TGAAGTTTAAATATGACAGCAACATGAAGATTATAAGAGAAGCTATTTTTACATTTTATT +TATTTTTTTGACTAGGTAATACATATACATGCTACCAGATTTAAAATACAGTATAGGTTA +GGCCGGGCACAGTGGCTCACGCCTGTAATCCCAGGACTTTGGGAGGCCGAGGCAGGCCGA +TCATCTGAGGTTGGGAGTTCGACACCAGCCTGACCAACATGGAGAAACCCCATCTCTACC +AAAAATACAAAATTAGCTGGTCATGGTGGCACATGCCTGTAATCCCAGCTACTCAGGAGG +CTGAGGCAGGAGAATTGCTTGAACCCAAGAGGCGGAGGTTGCAGTGGGCCAAGATCGTGC +CATTGCACTCCAGCCTGGGCAACAAGAGTGAAACTCTGTCACACACACAAAAAAAATACA +GTATAGGTTGTGGTGAAAGTCCCCTTGCCTCTGCTCCCAGACCATCAGTCAGTTCCCCTC +CCAGGGCCACACTATCCTCAGGGCAGTCATATTCCACATCTCACTTGGCTTTTTTCTTTT +TTTTGAGACGAAGTCTCACTCTGTTGCCTGGGCTGGAGTGCAGTGGTGCGATCTTGGCTC +AGTGCAACCTCCGCCTCCTGAGTTCAACTGATTCTCCTGCCTTGGCCTCCCAAGTAGCTG +GGACTACAGGTGCCCCCCACCACGCCCAGCTAATTTTTTGTATTTTTAGTAGAGACCGGG +TTTCACCGTGTTAGCCAGAATGGTCTTGATCTCCTGACCTCGTGATCTGCCTGCCTCGGC +CTCCCAAAGGGCTGGGATTACAGGCGTGAGCCACTGCACCCAGCCCGGTTTTTACTTAAC +AATATAGCTTGGAGACTGATCCATGCCCATGTACGCAAGACTGCCTCACTCTTTGCAAAG +GCTGTCTCACTTTTTTTATTTTATTTTATTTTTTTAAGATGGAGTTTCGCTCTTGTCGCC +CAGGCTGGAGAGCAATGGTGCAATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCAAG +CAATTCTCCAAACTCAGCCTCCCGGGTAGCTGGGATTACAGTCCTGCGCCACCATGCCCG +GCTAATTTTTGTATTTTTAGTAGAGATGGGGTTTCACCACGTTGGCCAGGCTGGTCTCAA +ACTCCTGACCTCAGGTGATCCACCCGCCTCAGCCTCCCACAGTGCTGGGATTACAGGCAT +GAGCCACCGCGCCCAGCCAGCTGTCTCACTTCTTTAACCCATTTCTACAGGGGTATATTT +AGGTTACTTGTAATTTCCAGTTATTTCACATGATGAACATCCTCACCCTTACAACATGCT +GAGTATGCATATGCCAGGATTAAGTCCCACAAATACAGTTGCTGGGTCGAAGGGTTTACA +TACATTTATACTTTGATAGTATTGTCAAGTTGCTGTTTTTATATCATTCCTGATAGCAGG +GCCTGGTGCCTGCACCCTCTACCCCCAACCCAGGAAGACACCAGCTCTAACTCACCACCA +CAAAAGGGAAAAACCTTATCACATAAGGTACAGAAAATCTCCTTATATGTTAAAGAGCCA +TTTCCATTTTCTTTTCTGAACAGTTCAGATTCTTAGTCAGTTTTCTGTTAGACTGTCTTA +TCAATTTGAAGAAATCTGCCCTTTCTTTGATGAGGAGTTTCCCCGATCTTTTGATTTTGT +ATTGCTTTTTTGCCATGCAGAAATTTGTCTTTTTTTTTTTTTTTTTTAAACAAGTCTAGT +CAACTGCAGTAGTGAGAAGGTGAAAAAGTAGAACCTGGAGTTGGATCTGTGACTGTGAAC +AATCAACTGAGGTAACTCACACTACCTTCGGACCAACCTATCTTCGTTTTCAATGTTGTC +AAATTTACCATTTACTTGCCTCTGAGTTTTGTGTCAAACTTAGAAAGGCTTTTTCTTTCT +GAGATTATTCAGAAAACATTTCCGATATTTTCCTCTAGTGTTTTTATTATTGAATCTTTC +ACATTTAAAACTGTTGATCCACCTGTAATTTATTTTGGTATAAGGTATGAAGCAAGGGTC +CAACTTTGTTTTTCTAGATGGCAACTCTGTCGTCTTCCCTCCTTCCTCTAATTTTTTTTT +TTTTTTAAGACGAAGTCTCACTCTGTTGCCCAAGCTGGAGTGCAGCAGCGCGATCTCGGC +TCACCACAACCTCCACTTCCCGGGTTCAGGAGATTCTCCTGCCTCCCAGCCTCCCGAGTG +GCTGGGATTACAGGCATGTACCACCACACCCGGCTAATTTTGTATTTTCAGTAGAGATGG +GGTTATCACTATGTTGGCCAGGCTGGTCTTGAACTCCTGACCTTGTAATCCGCCTGCCTT +GGGCTCCCAAAGTGCTGGGATTACAGGCGTGAGTCACCGCACCCAGCCCCTTCCTCTAAT +TTTTGAGGCTATCTTTATCACATAGGACAGGAATAGTCTCCTTTCGTTACTTTTGTTTTC +GACAATTTCCTGGCCACTGCTAGCTTTTTACATTTGAATTTTAGAATCAAGTTTCTGTAA +TTGCCCCAAATAAACCCTCTTGGTATTTTAGGGGGTTATGTTAAACATCTAGGTTAATGT +AGAGATAAATAGCATTTTTATAATGGACACAGTGGATCTTTTTAACTGTCCAGCCATCCT +CTGGGTCCATTTGGAAGTCTTATAAGTCATCTTCCTACAGATCTGGCACATATTTGTTAC +ATTTATTCCCAGACATTTCACTCCATGCATGGCCAAGCCCTCGGGGCACTTTCCCATGCT +CTTTACAGTGGTCTGTCTGGCTCTCCTGGACTTTCCAGGACTGTGCTCGTGCATGTACTT +CTGTCTGATTCTTCTGCTGGCACCTCTGGGACTATATTGGCAGCAGTGGAGATGGCAACA +TTTCAAGCACTGCCCGCCCTGAGCAGGGTGTGGGTGCTTGGATTGACACAGATTTTTTTT +TTTTTTTTTTTTTTTTTTTGAGACGAAGTCTTGCTGTTGCCCAGGCTGGAGTGCAGTGGC +GCGATCTCGGCTCACTGCAGGTTCCGCCCCCCGGGGTTCACACCATTCTCCTGCCTCAGC +CTCCCGAGTAGCTGGGACTACAGGTGCCCGCCACGTCGCCCGGCTAATTTTTTGTATTTT +TAGTAGAGACGGGGTTTCACCATGTTAGCCAGGATGGTCTCGATCTCCTGACCTCATGAT +CCGCCCGCCTCGGCCTCCCAAAGTGCTGGTATTACAGGCGTGAGCCACCACGCCCGGCCT +TTTTTTTTTTTTGTGACAGAGTCTCGCTCTTGTTGCCCAGGCTGGAGTGCAATGGCGCAA +TCTCGGCTCACTGCAACCTCCGCCTACCACGTTCAAGCGATTCTCCTGCCTCAGCCTCCC +AAGTAGCTGGAATTATAGGCATGTGCCACCACGCCTGGCTATTTTGTATTTTTAGTAGAG +ACAGGGTTTCACCATGTTGGTCAGACTGGTCTCGAACTCCTGACCTGATGTGATCCACCC +ACCTCGGCCTCCCATAGTGCTGGATTACAGGTGTGAGCCACCACGTCTGGCCGGACACAA +ACTTTTACCATTTTAAGAAAAAAAAAAATCTTATAATCCTTTCGGGGGCCAAGGCAGGAA +GACTGCTTGAGGCCAGGACTTTAAGATTAGACTGGGCAGCCAGGCACCATGGCTCACACC +TGTAATCCCAGCACTTTGGGAGGCCGAGGTGGGCAGATCACTTGAGGCCAAGAGTTCGAG +ACCAGTCTGGCCAACATGGTGAAACCTCATCTCTACTAAAAGTACAAAAATTAGCTGCAT +GGTGGTGCACACCTGTAATCTCAGCTACTTGGGTGGTTGAGGCATGAGAATCACTTGAAC +CTGGGAGGCGGAGGTTGCAGTGAGCTGATATCGCACCACTACTCTGTGACAGAGCAACAC +TGTGCCTCAAAAGAAAAAGAAAAAGAAGGGAAAAAAAAAGACCAGATGGGGCAACACAGA +AAGACCCCATCTCTTAAAAAAAATTAGCTGGGCATGGTGGCACGCATCCATAATTCCATC +AATTTGAAATGCTGAGGTGGGAGTGTTGCTTGAGCCCAGTATTTTGAGGCTGCAGTGAGC +TATGATGACACCATTGCCCAGCCTGGGCAAAAAAGTGAGACTCTGTCTCTTAAAAAACAA +AACAACACAAAAAAGTTCACTGCATGGATCATGAATGGAGGGAGGAGAAAGAAGATATGA +GACATTGTGGGTGCAATTAGGAAAATCTGAACGTGGACTCAATGTCAGATGAAATTATAG +AATGATTACACATTTCTTTTTCATTTTTATGTTTTTAGAGACAGGGTTGCTACGTTGCTC +AAGTTGGACTTAAACTCCTGTGCTCAAGTGATCCTCCCACCTCAGCCTCCCAAATAGCTG +GGACTAAAAGCACTCGCCATGGAACATGGCTCAATCATAAATTTTCTTATATCATGATAG +TATTACAGGTATGTCAAAGAATCTCCTCATCCTTAGAGAGGCGAACTGAAGTTGTTAGAG +ATAAATTGTCATGATATCTATAACTTACTCTGAAGTGAATATGCAAAATGTTAACTGATG +AATTTAAGCCAAGAGCACAGTTGTTCACTATACTTAACTTTCAACTTTTCTGTAGGATTT +AAATATTTCAAAATAAAAATCAGAGAGAAAAAAGAGCCCAAAAGAAAAATAAAATATATA +GTCACTCCTTTTTATTGTTTTTCTTTTTCACCAAAAATTTTACCAAATTTAATTTTTTTT +TTTTTTTCTGAGGCAGAGTTTCACTCTTGTTGCCCAGGCTGGAGTGCAATGGCGCAATCT +CGGCTCACCACAACCTCCAGCTCCCAGGTTCAAGCAATTATCCTACCTCAGTCTCCCGAG +TAGCTGGGATTACAGGCATGCGCCACCACACCCGGCTAATTTTGTATTTTTAGAAGAGAT +GGGGTTTCTCCATGTTGGCCAGGCTGGTCTTGAACTCCCGACCTCAGGTGATCCACCCTC +TTCAGCCTCCCAAAGTGCTGGGATTGAGCCACCAAGCCCGCCCCAAACTTAATTCTTTTT +TTTTTTTTTTTTTTTTTTTGAGATGGAGTCTTGCTTTGTCACCCAGGCTGGAGTGCAGTG +GCATGATCTCGGTTCACTGCAAGCTCCGCCTCCCAGGTTCACGCCTTTCTCCTGTCTCAG +CCTCCCGAGTAGCTGGGACTATAGGCGCCCGCCACCACGCCTAGCTAATTTTTTGTATTT +TTAGTAGAGACGGGGTTTCACAGTGTTAGCCAGGATGGTCTCGATCTCCTGACCTCGTGA +TCCTCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCATGCCCAGCC +TCCCAAACTTAATTCTTTAAACATTCATTTTTGGGGCTGGGCGCGGTGGCTCATGCCTGT +ATCCCAGCACTTTGGGAGGCCGAGGTGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCA +ACTTGGCCAACATGGTGAAACCCCGTCTCTAGTAAAAATACAAAAATTAGCTGGGTGTGG +TGGCAGGCGCCTGTAATTCCAGCTACTTGGGAGGCTGAGGAACAAGAATTGCTTGAACCT +GGGAGGTGGAGGTTGCAGTGAGCCGAGATGATGCCACTGCACTCCAGCCTGGGCGACAGA +GTGAGATTCTGTCTCAAAAAAAAAAAATTCATTTTTGGCTCACGGCAGCCTCAACCTCCT +GGGCTCAAGTGATGCTTCTGCCTCAACCTCCCAAGTAGTTGGGACTATAGGCATGCACCA +TCATGCCTGGCCAATTTTTAAAAAAATATATTAAAAAAAAATTATTACTACTTTTCTGTA +AGTCAGGAATTATGTCAAAATAAAGACTTAAAAGTTTTAAAAAGTTGTTCACACCTCATA +TCCATTAGGATGACCACTATAAAAAAACAACAAAACAAACAAACAAAAAGTAGGCCGGAT +ATGGTGGTTCACATCTATAATCTCATGTCCATAATCCCAGCACTTTGGGAGGCTGAGGTG +GGAGGATTGCTTGAGCCCAGGAGTTTGAGACCAGCCTGGGAAACATAGTAAGATTCTGTC +TCTACAAATAATTTTTTTAAAAAACTGGCCAGGCATGGTGGTGCATGCCTATAGTCCCAG +CTACTTGGGAGGCTGAGGCAGAAGCATTGCTTGAGCCCAGGAGGTGGAGCCATGATGGTG +CCCCTGAACTCCAGCCTAGGTGACAGAGCAAAATCCTGTCTCAAAAAACAAAACAAACAA +AAAACCAGAAAATAACAAGCTTTAGCAAGGATGTGGAGAAACTATAACCCTTGTGCACTG +TTGGTGGGAATGAAAAGTGGTGCAACTGCTATGTTCCTCAGAAAATTGTCAATAGAATGA +TCTAGCAATTCCACTTCTGGGAATATAGCCAAAGAACTGAAAGCAGAGTCTCAGACATTT +GCACACCCATGTTCATAGCAGCATTATACACAATAGACAAGAGATGGAAGCAAACCAAGT +ATCCCTTGATAGGTGAATAGACAAACAAAATGTGGTATATCCATAAAATGGCACACTATT +CAGCCTTCAAAATGAAGGAAATCAGGTCACATGTTATAACACACATGAACCTTAAGGACA +CGATGCCAAATGAAATAAGCAAGTGATAAAGGGCTAATGCTGTATGATTCTACTTATGAG +GTACTTAGAATAGTTTAATTCATAGAGACAGAAAGTAGAATGGTAGCTGCCAGGGCCTGG +GGGTAAAGGAGAAAAGGGAGTTGTGGTTTAGTGGGTATAGAGTTTCAGATTTGTAAGATA +AAAAAGTTCTGGAGATCTGTTTCGTAATAATGTGAATAATCGTAATATTACTGAACTAGA +TGGTAAGTGTTATTTGTGTTTATTATTTTAGAACCACAATTTTAAAAAATTGTTCACCAA +GTACCCAGTAGCAGGGGAATGACCAAATAAATAGAGGACATCGACAGCACGGAACACTCC +ACAGCACAGAGAGTGAGGGCCATCTCTACTGCTGGTGCCTGGGACCTCCAGGATGTCACA +GGTACAGAATGGCAAACCAGTATGCTGCCTCTGGTGTGAGATGGGGGAGAAAAATATTTC +TTGGGTCAGCTTGTTCAGGTCCTCGATCCCTTGTCCAAACTCTTTAAATCAAGTGTATTT +TAGAATTCAGAAGGTTCCAACGTGAGAAATACTGTACACATGCCACATAGGATCTTATAT +CCCACGGGATCTGGGTCGGTGCCTCCTCTTCAAACACCTTAATATGCCCCCCAAAAAAGT +ATAAAGACTCACACTAGGATAAAAAATATAATTAGCCTCGAAAATAATTTTGAGTTTTGG +GTGGGTTCCGTGGCTTAATGAGTTTACGCCAAACTTTTTTTTTTTTTTTTTTTTTTGAGA +CGGAGTCTTGCTCTGTCGCCCAGGCTGGAATGCAGTGGCGCGATCTCGGCTCACTGCGAG +CTCCGCCTCCTGGGTTCACGCCATTCTCCTGCCTCAACCTCCCGAGTAGCTGGGACTACA +GGCACCCGCCACCATGCCCGGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTTTCACCA +TGTTAGCCAGGATGGTCTCGATCTCCTGACCTCGTGATCCGCCTGCCTCGGCCTCCCAAA +GTACTGGGATTACACGCGTTGGCCACCGCGCCCGGCCTACGCCAAACATTTCTTTAAGAC +GTTTGGCTGGGCCAAAGTTAGCTGAGTTATTTCAGTTGATTGTTCATAGTCAGTAACAGA +TCAAACTCATTCGTCTCTGTCCCCCCTTCTCACTACTGCACTTAACTAGTCTAAAAAATA +ATAATAGATAAAAATAGGCCGGGCACGGTGGCTCACGCCTATAATCCCAGCACTTTGGGA +GGCCAAGGTGGGTGGATCACCTGTGGTCAGGAGTTCAAGACCAGCCTGGCCGACATGGTG +AAACCCTGTCTCTTTCAAAAAATACAAAAATTAGCCGGGTGTGGTGGCATGCACCTGTAC +TCACAGCTACTCAGGAAGCTGAGGTGGGAGAATCACTTGAACCTGGTAGGCGGAGGTTGC +AGTGAGCAGGGATCATGCCACTGCACTCCCGCCCGGGCGACAGAGAGAGACTCCATCTCA +AAATAAAAAAAAATTAAAAAAAAATTTTTTTTTCTTTTGTAAACGGAGTCTTGCTCTGTC +GCGCAAGCTGGACTGTAGTGGGACCATCTTGGCTTGGCTCGGCTCACTGCAGCTTCAACC +TCCAGGCTCAAGCAATCCTCTCACCTCAGCCTCCCAAGTAGTGGGGACTACAGGTGTGTG +CCACTGTGCCCAGCTAATATTTGTATTTTTTGTAGAGATAGGGTTTTGCCATGTTGCCTA +GGCTAATCTCAAACTCCAGGACTGAACTGATCTGCCCACCCCAGTCTCCCAAGGTGCTAG +GGTTATAGGTGTGAGCCACCCTGCCCAGCCCCAAAAGTTTTTTGGTTTTTGTTTGTTTTT +GAGAGATGGACCCTTGCTATGGTGTCCAGGCTGCAGTGCAGTGACATGATCCCACTACTC +AACAGCATGGGAGTTTTGACCTGGTCCATTTCCATCCTGGGCCGGTTCACACCTCTTTTT +AGGCAACCCTGCTCCAGGAAGGTCACCATATTGATGCCAAATTTAGTGTGGATACCCTGT +TGGCATGGCACACTGCAACCCAGAACTTCTGGGCTCAAGCAATCCTCCGGCCTATTCTCC +CAAGTAGCTGAGACTATAGGTTTGAGCCACCACGCCCTGCTCAAAAAACTTTTTAACTGT +GAGAATGGATGCTGAATGTTATCACATGCCTGCTCACCATGTCTGCAGATATGCTATATA +GACACGTATGCAGATATGTTGGGTTGTCATGAATTGATGGAATGCCATGATTCCCTGGCA +TGTAACTAGTAAGACAGATTCCCTAGCATGAAACCAATTTTTTTTTTTTGAGACAAGGTC +TTGCTGTGTCACCCAGGCTGGAGTGCAGTGGCACACTCACAACTCATGGCTCACTGTAGC +CTTGACCTCCCCAGGTTTAAGTGATCCTCCCACCTCGGCCTCCCCAGAAGCTGAGACTAC +AGGCATGCCTGGCTAATTTATGTTTTGTTTTGTTTGTTTGTTTTTCTTTTTTTTTTTGAG +ACGGAGTCTCACTCTGTCGCCCAGGCTGGTGTGCAGTGGTGCGATCTCGGCTCACTGCAA +CCTCCGCCTCCCAGGTTCAAGCGGTACTTCTGCCTCAGCCTCCCAAGTAGCTGGGATTAC +AGGCATGCACCACAACACCTGGCTAATTTTTGTATTTTTTTTTGACCTCTGAACTTTTTA +TTGGCCTCCTGCTCCCCAAAGGATACCCTGCTTCTGGTGGCTTAATGTCTCAGAACTTTG +GTGTCATTGGTCTCAGACACCACTTTGCCATCCATTATCTGGCAGGTGGTGGTCTTTTGG +ATGGTTTGCATGGAGTTGCTGCTGTCCAGGGCATCACCAAGACTGAAGTCCTCGCCATCT +TCCAGCAGGCGGCAGTAGGTGGTGATCTTAGCCTCCAGCTTGACCTTAACGTTCACCAGG +GCGTCCTACTCCTAGGCCTGGCACTGTCCCTCTGCCCGGATTTGTGCCACCTCTGACTCC +AGGTGCAGCAGGATCCCATTGAGCTGCTCCATCTACAGGGCATAGAAGGCCTCCACCTCC +CTGAGGCTGTTCTACAAGCTGGCCTTCAGATTTCTCAAGGAGTCCAGGTTGATCTCCAAG +GACTGGACGTACGTCTCAACTCCGTGATTGTCATCTCAGCAGTTCCAACCTCAGTGGACT +GCATGGTGACCACTGTGGTGCTCTCCTCAATCTGCTGAGACCAGTACTTGTCCAGCTCCT +GTCGTTTCTTCCGAGCCAGCTCATCATATTGAGCCTGGATGTCTGCCACGATCTTGGCAA +GGTCCTGAGATTTGGGGGCATCTACCTCCACAGTCAACCCAGAGCTGGCAATCTGGTCTT +GTAGGCCTTTTACTTCCTCTTCATGGTTCTTCTTCATGAAGAGCAGCTCCTCCTTGAGAG +CTTCGATCTCTGTCTCCAGCTACAGCTGAGGGACATTGGTGTCATCAATCACTTTGCGAA +GCCCATGTATGTCGCTCTCCACAGACTAGTGCATGGGCAGTTCTGTCTCATACTTGACTC +TAAAGTCATCAGCAGCAAGACGGGCATTGTCGATCTACAGAAAGATACGGGCGTTGTCCA +CAGTATTTGCAAAGATCTGAGCCCTCAGGTCCTCGATGGTCTTGAAGTAATGCCTCCAGT +CTCTGATCTGGGTCCCTTCTTCTCCAAGTGCTTCTGGATTTTGCTCTCCAGCTTCCGGTT +CTCGGTCTCCAGGCTCCTCGCTCTGTCCAGGTAGGAGGCCAGGCGGTCATTCAGGCTTTG +TATGGTCTCCTTCTCATTCTGGATGCTTCCCATTCCTGCCAGATCCCCAGCCATCCCCGC +GGCCAGGCCCCCAGACCCCATGCAGCCCTGGAAGCTGGTGGAGCGGGACACGAAGATCCA +GGAACCAGAGCCCTCGGTGCCTGCATAGACGCTGGCCACGCTGCTGACCAGCCAGGCGCC +ATAGCTGGGAGCCTGGACAGAGCCCAGGGACCAGTAGTTGGTGGAGAAGGTAGAGCGAGT +GGTGAAGCTCATGCTGTCCGGGGAGGAGAGCAAGAGGACAGGACTCAGGCTTTGCTGATG +ACCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCGCCATGTTGGCCAGGCTGGTCTCC +AACTCTGGACCTCAGGTGATCCACCCGCCTCAGCCTCCCAAAGTGCTAGGATTACAGGCA +TGAGCCACCGTGCCCAGCTTTGTTTGTTTTTTGCTTTTTGAGGCAGAATCTCACTCTCTC +ATCCAGTCTGGAGTGCAGTGACGCGATCTCAGCTCACTACAACCTCCACCTCCCAGGCTC +AAGCGATTCTTGAGCCTCACCCTCCTGAGTAGCTAGAATTACAGGTGTGCACCACTACGC +CCAGCTAATTTTTGTATTTTTAGTAGAGATGGGTTTTTGCCATGTTGGCCACACTGGTCT +TGAACTCCTGGCCTCAAGTGATCTGCCGGCCTTGGGCACCCATTGTGCTGGGATTACATG +CATGAGCCACTGTGACCAGCTCTAATTTTTGTATTTTTTGTAAACATGGGGTTTCGTCAC +GTTGCCCAGGCTGGTCTCGAACTCTTGGGCTCAAACAATCTGCCCACCTTGGCCTTGCAA +AACGCTGGGATTATAGGTGTGAGCCACTGTGCTCAGCCTTTTTTTTTTTTTTTTTACGAG +AAAAGAGGTCTCTTACTTTGTCATCCAAGCGAGAGTGCAGTGGCATGATCATGGCTCACT +GCAGCCTCAACCTCTCAAGCTCAAGCTATCCTCCCTCCTCAGCCTCCCAAGTAGCTGGGA +CTATAGGCCACGCCACCATGCCCAGCTAATTAAAAAAAATTTTTTTTTCTTTTTCTGAAA +CTGCTCTGAAAAAATTTAAATGGCATTGGAGTCTTTTCATAAAAGGCACACCTACCCTGG +AAAACATCTGGGCTTTGTGTTTTGTGGGGAATACAACTTTCTCTCTCTTTTGGGGATAAA +GTGCTATTAATTTTTTAAAAATAAAATCATCAATTGTATCCAAACTTTTAAAGTAACAGA +CATTGAGTTCAGCTAAGCAGTCTTTTATAATTCACAGATGGAATGAAAACTAAGGGAGGG +ACGAGGTGACCCATGGAGGTTGTATAAAAAGGACAGAGCCTTTGGGCTCTTCAGACTATA +AGGGTCCAGGAGGAGAGGAGAAACCACCTCAGAAGCATACAAGGTTAAAGCATACAAGGT +GGGTGTAGGGTCAGGGGAGCCAAAGTAAGTGTGCAATGAAAAGTTATTAACAAAAGTCAA +AAAAAGAAAATGCAGTCTGGCCATCCAATTCCTAAACCATGTACAGAGTACACAGAAAGA +GCACAGGAGGCTTCCTGCAGCAGGGCAGTACAGCTCTCTGCCCTTCAGGAAAACTGAGAT +TCCTCCACCTGGGAAACAGCAAGGGACAATTAGGGAAAGCTCTCCAGAGGAGGAGGCATC +TCAGGTGGGCCAAAGAAGAAAAATTTCCACAGGACAGAAAAGGCAGAGAAGAGGCCAGGC +ATGGTGGCTCACGTCTGTAATCCGAACACTTTGGGAGGCCAAGGCAGGCGGATCACCTGA +GGTCAGGAGTTGGAGACCAGCCTGGCCAACATGGCAAAACCCCGCCTCTACTAAAAATAC +AAAAATTAGCCGGGTTTGGTGGCACACGTCTGTAATCCCAGCTACTCAGGAGGCTGAGGC +AGGAGAATCACTTGAACCCGGGAGGCAGAGGTTGCAGTGAGCCGAGATTGCCCCACTGCA +CTTCAGCCTGGGGGACAGGGCGAGACTCCATCTCAAAACAAACAAACAAAAGGCTGGGCG +TGGTGTGGCTCACACCTGTCATCCCAGCACTTTGGGAGGCCAAGGAGGGCAAATCACAAG +GTCAGGAGTTCGAGATCAGCCTGGCCAACATGGTGAAACCCTGTCTCTACTAAAAATACA +AAAAATTAGCCGGGCGTGGTGGCGCACACCTGTAGTCCCAGCTACTCGAGAGGCTGAGGC +AGGAGAATTGCTTGAACCCGGAGGCAGAGGTTGCAGTGAGCCGAGATCACACCACTGCAC +TCCAGCCTGGGTGACAGAGTGAGATTCCGTCTCAAAAAAAAAAAAAAAAAAAGAAATTTA +TGTTCTTTGTAAAATAATTCAGACAATGCAGTAAACAGAAGAAATTCAGCCTCCCTCTCC +CTTTGCCCTTTGCTGAGTCCCCACGGTGCAGCAAGATCCTTCCAGATCTTCATGGTTGGG +ATCATCTTCCACCAGGTCCTGAGGTTTTTCACTCCCTATCAGTAGACACACCACACTGCC +CAGTTTGCAAGTAGCTCCATTGGATAACACAGAAAGGCTCTGTCCTGCACCATGTCTCAG +CACTGGGTGCATCGTCCCACAGGAATGACACCTAGACACCCAACATACAACTGCAGGGCC +CTAAACTATGGGCCAGCCCACCCCTAAATGCCCTTCTCTCTACCCTTGCCCATATCAAAT +ATTACAAGCCTCTCACACATATTTACCAGTCATACTGGGAAAAAAATAGTCCTTTATCAT +TTTAACATTTCACAAGTAACTAAAACAAATAATAAACATGCTAACACTTGGGAATGGTCT +ATTTCTTTTCTTTTTTTTTTTTTTTGAGACGGAGTTTCATTCTTGTTGCCCAGGCTGGAA +TGCAGTGGCGCAATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCAAGCAATTCTCCT +GCTTCAGCCTCCTGAGTAGCTGGGATTACAGGCATGTGCTACCACGCCCAGCTAATTTTG +TATTTTTAGTAGAGACAGGGTATTGCCATGTGGGTCAGGCTGGTCTCCAACTCCTGACCT +CAAGTTATCCGCCCTCCTTGGCCTCCCGAAGTGCTGGAATTATAGGAGTGAGCCACCAAG +CCTGGCCTCTTTCTAGGCTCACTGCAACCTCCGCCTCCTGGGTTCAAGTGATTCTCCTGC +CTCAGCCTCCCAAGTAACTGGGATTACAGGCATGTGCCACCACGCCCCGCTAGTTTTTGT +ATTTTTAGCAGAGACGGAGTTTCACTATGTTGGCCAGGCTGGTCTCGAACTACTAATCTC +AGGTGATCCACCCGCCTCGGCCTCCCAAAGTTCTAGGATTACAGGCGTGAGCCACTACAT +CCAGCCTCTTTTTTGTTTTTTTGAAACAGGGTCTTGCTCTGTCACCCAGGCTGGAATGCA +GTGGCACAATCTCGGCTCACTGCAACCTCCGCATCCTGTGTTCAAGCAACTCTCCTGCCT +CAGCCTCCCAAGTAGCTGGGATTACAGGCGCCCACCACTACACCCAGCTAATTTTTTTTT +TTTTTTTTAGTAGAGACAGGGTTTCACCATGTTGGCCAGGCTAGTCTCAAACTCCTGGCC +TCAAGTGATCCACCTGCCTTGGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCACCGT +GACTGGCCTCTATTTCTTATTTATACATACACACACACACCCCCCTGTGAAATGACTCTG +GGCTCTTCCAATAATGTTGCCACTCTCCCGCTCCCCTTCCCAATGGAAGTGGAGGGATGC +AGGGGGTGTTAGTGATGCATTGTAATCATCCCGGAGAGCAGGACACCTCTCATAAGAGGT +TTACCCAAGGGGGGCTGTGGAAAGGGCTAGAAATTGCTCCTGGAGGACGTGGAAAGCCAC +ATAAGGTTTTTGACAGATTAGCGAAAGGCTGCCTACACTGTCATCTTCAGAAAGAGTGGT +ATGACACTAAATCAAGAAGGGCTGAGAGGGTGAGCCCAGGGGATCCCATAGGCTCCACAG +CCTCTGGCCATCCTCTCCTATACAGGTCCTAAGTCCCCTGCAGGGGGCCCTCAGCTCCTC +TACCCTACCCACTGTCCTGTATGTTATCTTAATGCTTATTAAAGGCCTCAGCTGAATTTC +CCTGGTGAACTGAAAGAATTCTGCTGCTCCTGGACACATCTGCACCAAGCCACCACTGGG +TCACATTCTCCAAAACTCCTTTTGGAGACAGAAGGCACTTAAACCATACATATTTTGCTT +GATAGTTCCTAATTAAAAAAATAGAGAGAGATAAAGAGAAAGAGAGAGAGAGAGAACTAC +AACTAAGCCTTGAAGACAAAATGATTGAACAGAATCAGAGCTAGAATGGAACACCTCAGG +CTTGGAGTCCCATGACAACCTTGCTGGGGACCACGAGTGGCCCTCAGTCCTTCTCAGGCT +CATGCCACCTATGTGAAATAAGGGTGGTGACACCCACCTCCTTGAGTGCAGAGCAGTGCA +GACAACAGGGCAAATGGTGTATTGATCTGCTATCTGTGTACATAAATTTATTCATTTAAG +CCATGGGTATTGTTTGAATATGTGAAAACCATGTCAGGTGCTAGGGATAAGAGACAGATT +CCAACCCAGTGGAAAAGACAGATAAGCCAGTGGTTCCTCACACTGTGCCAAGTGCTGGGA +TGGGGTCACGAAGGAGGCCATAAGAAACCCCAGAGGGGCCACAGAGCTCACTGGGAGGGC +CAGAGGCTAACACCTGAGGGATGAGAGGTGTGAGCCAGAAGGTGATGCATACACAGCAAT +AATTACTGACGGAGGGGAGGAATGGTAAGGGAGGGGAGGAGAGAAAGGAGGAAAGAAAAG +AGAAAAGAAAAGAGAGAGAAAAGGAAAAGAAAAGGAAGAGAAGAGAGGGAAGAGAAGAGG +AGGCAAAGCCCAAGAAACAGGATCACTGAATGAAAAATGAACTCTAAGACCCCCTTCTGT +CTCTCACACTTGTTGACTAAGTCATAGCCACAAGGAGTAGGGGAGGCTCTGAGGTGAGCA +GGAGACCAGCCACTGTCACCGCCAGTACCTTTACTAGCAGAGCCAGGATTACCTTTGTTA +TTCTTCTTACAAACAGCTCTAGTGAACTCACCTGAAGTAATCGCAGGACGCAGCCAGCAG +GATGCGATGGGCCTCGATGTGTCTGCCCTCCACCACCAGCACAACATCGAAGAGGATTCC +GCTGTCCCGGAGAGCCAGCAGCCCTCGGAGCAGAGCCTGGGAGTGCTGTGCGCTGCGGTA +GGTGTTGTTCACGCAGTGTGGGTGTGAGGGCTGTGCAGGCAACTTGCAGAGCTGGGTGAA +CTCCTGCTCCTCTGCCATCCTGACAGCCACAAGATCCCTTACAACTGTGGCCTGACAGTT +GGCAAAACAGGGGACAGGGGTGAGCAGGCAGGCATCAGCCCCACCACACACAGACTGGCC +AGCTCTGTTGCTCCCCTTGCTCCTGTGCCTCCCTCAGGCTCACCTGTTTTCCCTCTATTT +CCAAATCCCCTAATTCCTTCTCCCCTCCCACCTCTAGTCCAACTTCCTGATGGCCTTCTT +CCTGATGACCTGTGTGCCATCATGCCCAAGACTCTTCATCTCATTGTATCTTCTTCAGCG +GCAAAGTCAAACAGAAGGGTTTTGGGAAACAGACTGACCTGGGTTGGAGCCCAACTCCAC +AGGGACTTACAACATGACCAAACTGAGCCTCGAGCTCCCCAATTTTAAAAAGAGAGATAA +AAGTACCTACCCCATTGGGGTATTCTAAAATTGGTAAAACAATGAACATGAAGCATAAGC +ACACACCAGGTTCTCAAGAGCTCTTCCTCCCTCCCATTGAATGAACAAAATTGGGTTCTT +CCTCATAGTAATGGATGCATAAAAATGGCAAGACCTGAGTAGTGGTCAGGAGACACACAG +CCAGGAGTCTGGGAGGTGGGTGCCAAGGGGGTGGCATTTCCAGGGCCTACTTTCCTTTAC +TGAAATTCTGAGAGTCAAGCACAGTAACTGTGATTGAACCTGATGCATTTAAATTCATCT +GCATTGCCTTTTAAATTAAAGATTATCTTCTAATAATTGAGTCAGTACGTTCAAAAACCG +CAAACTGATTTGAATTGGAGCCTCTAAAACCTAATCAGTAAAATGAACCTACTGCAAATG +CACTTTTGCCATGGAGCAACCAAAAGTGACTGTGGATAGCCAGCTGTTCAGGTCAGGGAG +TGGCCAGTCCCACACTGTGAGGCATGGCCAAGCTGCAGGCTCTGTAGGCACAGCACAGTC +AGCTACAAGATGTGAACATCTGTCTTCTCCACCTCACTTCATCCTACTTTCCTCTCCCCA +AAATATGTTTATTCTCCAATTACCTCCAGTCATGCATCACTTAATGTTGGGGATACATTC +TGAGACTTATATCGCTGGAGGCAATTTCCTCAGTGTGTGAACATCAAAGGGTACACCTAC +ACAAACCTAGGTGGTAGAGACTACTACACATCTAGGCCATAAGGTACAGCCAATTGCTCC +TAAGCTACATACTTGTACAGCATGTTACTGTAGTTCTGAATGAAAAAAACACACTGTTTT +TCCTCTCCTCTTATACCACAACAACAAACACAGGAGACTTCTGTGACCAAATGTGTGAGG +GTTTTTCCCCATTAACAAGCAAGCAATCAATTCTGCCACAGATACCAGCTGGGTGTCTTC +TAATTCAGCAGTCCCCAATCTTTTTGGCACTAGGGACCACTTTCTTGGAAGACAATTTTT +CCACGGGGTCGGGGAATGGTTTCGGGATCAAACTGTTCCACCTCAGATTATCAGGCATTA +GCTAGATTCTCTTTCGGAGCACACAATCTGGACCCCTCACATGCATGGTTCACAACAGGG +TTTGTGCTCCTATGAGAATCTGATGCCACCTCTGATCTGACAGGAGGTGGAGCTCAGGTG +GTAATGCTGGATCACCCTCCACTCACCTCCTGTTGTGCCACCTGGTTCCTAACCAGCCAC +AGACTGATACAGGTCTGAGGCCTGGGGGTTGCGGACCCCTGCTCTAATTCAACTCTAACA +CTACCTGGAGACAGTGTCTGATCCCACAGGTTGAGGGCTGAGTCTCCCAGGTTGTTTCAC +CTGTGCTTCTGACCAATAGGCTATAAATTGGGTTCCCAAGATCCCCTTCTTGGGTTCAAC +TAATTTGTTAGAGCGACTCACAGAACTCAGGAAAATACTCATGTCTACTGGTTTGTTATA +AAGGGTATTGCAAAGGATACAGATGAAGAGATGCATGGGGCCAGACATGTGGGAAGTGGT +GCAGAGCTTCCAGGCCCTCTCCAGGAACATCACTCTTTAGGAGCCTCCATGTGTTCAACT +ATCCAGAAGTTTTCCAAACCCAGTCATTCAGAATTTTTATGGAAGCTTCATTATGTAGGC +ATGACTGATTAAATCACTGGCCATTGGTGATGAACTTAATCTTCAGCCTGTCTCCCCTCT +CCGGAGGTTGAGAGGTGAGGCTGAAAGTCCCAACCCTCTTATGCCTGCCTTGGCCTTTCC +TGTCACCAGCCCCCATCCTGAAGCTACCTAGGGGCTGCTGGCCAGCATACAAAAAGGCAT +CACTCTGGAAAGTCCAAAGATTTTAGAAGTTGTATGCCAAGAAATGAGACAAGACCAAAT +ATATATTTCACAATATCACAGTACTGAATACTATAGGCAACTGTAACACAATGGAATTTG +TGTATCTAAACACAGACAAGGTACAGTAAAAATATGGGACCACCATCCTTCATGTGGTCT +GGTCTGTCATTGACGGAAACATCACTGTGTGGCACATGATTATATATCTTTAAAAGAAAA +AATGAAAAATATATGCTGATATAAAACTTGCCAAAAAGAAGAGGTCTCTCTCTTCACTAC +TGAGGCTCAGGGCCACCCCCAACCCCATCCCCTGGATGCTCTACTGCTTCCCATCAAACA +CACTCAGTTATCTGTGCCTGCCCCTGAGTCTGCCTCCAGGACCTGGGACCTCTATCCAGC +CACCCACCCATTCCTTTCCCCCTCCTGGGCTGGCTCATCTTTCTCACCAAGGCCCCAGAG +ATGGCCACAGCCAAGGTGTATACCCCATGACCACCTCTCACTTAGGATTCTCTTGCCTGG +AAACTCTGCTCTATGATAATTCTCCCTTTTCTGACCTCTCTCTTTCATCCCACACACCCT +GCTCGAGCCCATCCTTCTTTCCCAGTGGTTCACATTCCCAGTTTCACCTACAGCTCAGTG +CCTAATCTAGCTAGTAGCCCTCCAACTTGTCTAATTTTACTATCAAAGCTACCATTTCCA +TCTTGGAAACCTCACTGTTTTAATATTTTTCCTTTCTAACCCATGTGCCCTATGAACCTA +CTAGTTCTGATTCCTTCACCTCTCCTCCATCTCAGACAGCCACCCTCCACTCCTCCAGGG +CCACCACTCTGGGTCAGACCACAGCAGTGATGCCCCTACCAGTTTCCCTACCTCTTGTCT +CATCCTCCCCAGGCTGCTCTCCTTCAAGCCTTACCTACTCAGCCCCATCAGCAGTCCTTA +GTCCAAAAGGGATACCTGTCATCCCCTGAACACCTTTAGTCACCCATCTAGGCCATTCTG +TCTCTCATAGTCCCATATTGGTCAAGGTCTAGCTCGATTACTTCTCCCTCTATCATTGTA +CAGAGAACATGACAAATATGCCCCACCATTCAAACCTGCCCTTTTTTTTTTTTTTAGACG +GAGTCTCGCTCTGTCACCCAGGCTAGAGTGCAGTGGTGTGATCTTGGCTCACTGCAACCT +CTGCCTCTCAGGTTCAAGTGATTCTCCTGCCTCAGCCTCCCCAGTAGCTGGGATTACAGG +CGTGCACCACCACACCCAGCTAATTTTCTTGCATTTTTAGCAGAAATGGGGTTTCACCAT +GTTGGTCAGGCTGGTCTCGCATTCCTGACCTCAGGTGATCCATCTGCCTTGACCTCCCAA +AGTGCTGGGATTACAGGCATGAGCCACCGCGCCCGGCCCAAACCTGCCTATTTACCCACG +ACAAGGAGATTCCGGCTTCTTGAGGGGTGAGGTTTTATCTCACAAACATCTCAAAAGCCC +CCATGGCTGGCTGTACCACTTGCTAATGACAGACTCTGGGCACTTGTCTCATATACCCAC +GCCTCAGCTTTCTCATCACCACCATGACCACCGCAGAGTCAAGAGGGCCTCCTTCTCTGA +GGGTGACCTCCACAACTACCCCAATAGACATCAAGCCCCCAGGTGGATCCTCACCTTCCG +TGAGCATAGTAGTGCCTCTGCTCTCTTGGGAAGGGATAAATGGCAGCTACTCCCTAAACC +CATACTGCAAAAACAAGTACGGTAAAACAGAAAGACATCTTCCATGGGCAGGCAAAGCAC +ATTTACCAAGTCCAATTTAAGAAACTTAGCTAGGGGCTAAGGGGGATATGCTGAAAAATG +AATCAATTCTCTGCTGGGAAGGAGCACAGCACAGGGTGCAACATTTAAAACATTTAAAAC +CACATCTATACGGTTTTAAATCACCAAAACGTCCACCCTCAGGAGAACAGATGTCATGGC +ACAGTGATCTGACAGAACATTAGGCAACAGTCAAAATGCGCAAAGTGGCCGGGCGCAGTG +GCTCACGCCTGTAATCCCAACACTTCGGGAGGCTGAGGCGGATGAATCACGAGGTCAGGA +GTTCAAGACCAGCCTGGCCAACATAGTGAAACCCCATCTCTACTAAAAATACAAAAAAAT +TAGCCGGGCATGGTGGTAGGTGCCTATAATCCCAGCTACTTGGGAGGCTGAGGCAGGAGA +ATCACGCCACTGCATTCCAGCCTGCATGACAGTGCGAGACTCCGTCTCAAAAACAAAAAA +ACAAACAAAAAAACAATGTGCAAAGTAGGCTGGGCACAGTGGCTCATGCCTGTAATCCCA +GCACTTTGGGAGGCCAACGTGGGAGGATCACCTGAGGTCAGGAGTTCAAGACCAGCCTGG +CCAACATGAGGAAGCCCCATCTCTACTAAAAATACAAAAATTAGTGGGGCGTGGTGGCGC +ATGCCTGTTATCCCAGCTACTGGGAAGGCTGAGGAAGGGGGAAGCTGAGGCAGGAGAATC +GATTGAACCCAGGAGGTGGAGGTTGCAGTGAGCCAAGATTGTGCCATTGCACTCCAGCCT +GGGCGACAGAGCCAGACTTTGCCCCCCCCCCAAAAAAAAAAGTGCAAAGTAGGCTGGGCA +TGGTGGCTCATGCCTGTAATCCCAGTGCCTTGGGAGGTCCAGGTAGGTGGAGTTCAAGAC +CACCTTGGGCAATATAGCGCGACCCTTTCTCTACAAAAAATTTAAAAATTAACTAGGCAT +GGTGGTGTACACCTGTAGTCCTGGCTATCTGGGGTGAGACAGCTTGGGGTTCACTGCAGT +CTCAAGCTCCCAGGTTCAAGTGATCCTCCCACCTCAGCTTCCTCAGAAGCTGGAACAACA +GGAGCTCACCACTGCGCCCGGCTAATTTTTCAAATTTTCTTTGTAGAGAAGAGGTTTCAC +TATATGGTGTAGGCTAGAGTGCAGTGGTAGGGTCTTGGCTCACTGCAGCCTTCATCTCCT +GGGTTCAAGCGATTCTCCTACCTCAGCCTCCCGAGTAGCTGGGATTACAAGCACGTGTCA +CCACACCCAGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGC +TAGTCTCTCCTGACCTCAGGTGATCTGCCAGCCTTGGCCTCCCAAAGTGCTGGGATTACA +GGCATGAGCCACCGCGCCCGCCCCCAGTCTCATATCCCCAATTTTAGTCATCACAAGCCA +AGTTCCCCGTTTTGTACTGTTCGAAGTTTCAGTGGGGAGAAGAAAGGAAGCTTAATGTGC +CACATAGCTACAAACTGAAGGATACAAGATGAATTTTTATGAAGTGATGGATGGCAGAGT +CAAAATCATTTCAGAGGAACTTTCAGTTCGGTACGATTTTACTGAGTAGATACCCTCAGC +CTTCTGTAGGGCCCCCGAACGAGCAGTATCCCCTCAAAGAAACTCAATCCTTGGCAGCAT +GAAGCAAGGTCGGCCACAAAGGCAAAGGGGGCGGCTGCGGTAGAGGAGAGGGAGTGGGTG +CTGATTCCCAGCGGGGCAGCCTTCCAAAGGGTGCGCTCTGGAAGAATCTCCCAGGGAGCC +GTCTTGGAGGCACTCGGCCCCGCGGAGGGCCGGAGCGAGGGCGCCCAGTGAGGAGCCCAG +GCGGAAGGTGGCGGTGCCCCGCTGCCCGCCCCAGATCCACTCGGCTCGGCCCGCACCGGA +TCTAAAATGGTCAGAACTGGCAGCCGACGCTTCGCGCTCTGGTGATTTTGCACTGACAGC +GCGATCTCCGGCTCCTCTCAGGAAACCGGGAGAGCTGGCAAGGCTGGGCTCCTACGGCTG +CAGTCCCCGGGCCCGATCGAGGGAACTGAGGCTCGTCAGGCCGGCCCCAAATCGCCCGCC +TGTTGCAAGGCCGCCCGCTCCAGCGCGGAGGGTCGCGGCCAGGAAGGCCGCATTCGGACC +TGCCGCAGGCAACAGGGCCCGCCCGGGTGCCAGGAGGCCGGCGCGCCAGCAGCCGCGCTG +AGGAGGCCTCGCACCCTGGCCCCTGGCCGAGCGCCAGATCCCGGCCCCTACGCGCCCGCG +CCCGGGGATCCCGCCGGCCGCGTCCCCGCCACGTCAGGCCGCGGGCTCTCCTCAGGTCGC +CGCCCCCGAGCCTCCGGCCCGCGCCCGCCCCCGCGCCCCTCGGACTCCGCGCCGCTAGCT +TGTCCCCGGCCCAGCGATGCCTGCTTGCCGCCCGACCCCCGCGTTCGCTGCCGCCCGGCC +CGTTCGGCTCACGCCTCGCAGCTGACCTGGTGCCGCCGCCAGCCGAGGCCGCACTCGCAG +CTGGAGGGAGGCGGGAGGCGGGAGGCGGGAGGCGCGAGGCGGGAGGCTGGGCGAGAGGAG +CCGGCGGGGCGGGGGCCTGGGCCGTCACGTGGGTGCGCCGCGCAGGCGCCGGGCGGGCCA +GACGTAGGCCCGGGGGTTCCCGGCCTGGCCGGGTAGCAGCGCGGGGGCGGCCCTGGGGCG +GGGAGACAGGGGGCGGCTCCACTCCGGCGCTCTGCGGAGGACAGCAGCGATCGCCAAGGC +TCAGTGAGTCCCCGCACTAGCGCGGCACCTGGCACTTGGCGGGGCCGAACCAACGAATGA +GCGAATTTGCCGAGAGTCGCCCCGTCTGAATCCATTGACTCTTTCCTTGCCTCGGTCCTA +CCCTCATTCCTCGACTCACTTCCTCCTGCCCTTCCTCACTATCTCCCTCCCCGCTCATAT +CCTCCCTCTCCTTTCCTCATTCCCTTCTTCACTCTCTTCTCTCCTCTCTTACTCCCCCCC +TCTCATTCCCTCCCTCCTTCACTCTCTCATTCCTTCCCTTCCTATCTTACCCACCATTCC +CTTCCTCCCTCACTCATTCACTCCCTCCCTGTCTCCCCCTCTCATCCCCTCCCTCTCTCA +TTCCCTTTCCCTCCCTCCTTAACTCTCGTTCTCTCCTCCCTCTCTCATTCCTTCCCTCCC +TGTCTCATTTCCCCCCTTCTTTCCCTCCCTCCCTCTCCTCTTCTCCCATTGCCTCCCTCC +CTCTTTGATTCCCTTCTTTCCTCCTCTCCTCCACTTGTTCCCTTCGTCACGCGCTCATTC +CCTCCCTCCCGCGGCCTGCTCCTTCCCCGCTCCCTCCGCGGTCGGTGCCGCTGACCGTAG +CGCGCCCCCTGCGGGATATCGGGGAGAATCGCTTAACACCGCCAGAGTGAACAGGTGCTA +GTTTGTGTGCCCGTTCCTTTACTGAGATTTTGCAGTAAATCTAATTCCCAGTCTTAAAGC +CTGGTCCCAGAGGTCCGTGCGCGGGTCTTGGCATTCATTGTTCTCCACCTCACCTTCGAG +CAGGTCCCATCCTCCGAGGCGTATCCGTAATGGCTGCGCCCAGAGCTTGGAGCCACAGAG +CCTCCTGATGGGATAAGGTTGGAGTGTCCCACACTGTGGTTTTGAGAGGGACTGTGAAGG +GTGGAGAGAGTGGTAGGGGGAGGATGTGGCTGGAGATGGCTCATGGTTAAAAAGAAAGGT +GGGGCCGGGCTTGGTGGCTGGCGCCTGTAATCCCAACACTTTGGGAGGCCGAGACGGGCG +GATCACGAGGTCAGGAGATGGAAACCATCCTGGCCAACATGGTGAAACCCCATCTCTACC +AAAACACACACAAAAAAACTAGCCGGTCGTGGTGGCGCGCACCTGTAGTCCCAGCTACTC +GGGAGCCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCAGAGGTTGCAGTGAGCCGAGA +TCACGCGCCACTGCACTCCAGCCTGGTGACAGAGCGAGACTCCGTCTCAAAAAAAAAAAA +AAAAAAAAAAAAAAAAATTGGTGGAAGGGGAATGTAAAAGGAGGAAAATACACGGAAGAG +AATTGCTGTCCTGGCTGAGTCCAGAGAGATAACTGAGGGTCCCAGACAAGGATCAAGAGA +ACGGGATTGGCCTCCAGAGGCAGAGGTTCCAAATGGGAGTGGGCTTCCTCCTAGAAAGAC +TTTCTGGAGGAGACCCCCCTACTGTGTAACAGAGGAGGACTTTGGGATTAAGAAAAGCAT +TCCAGGAAGCCGACAGTGTCAGCAAACGTGGAGGTGAGATCCTTCAAAGTGAGTGGTGTG +GAGGTTTCCAGAATTTTCTGAGCCTGAAGGGAAGGTTGGAGAGCAGACCCTGCCCTTTGG +AGGCTTGACTTAGCCCTGAGGGCACCCTGTAGCCAGGGTGGGCAGATGCCAATATGGTAG +AGACGAAGACTGAGTAGGGAGCCAGCCACAGTGCTGTGGTCTCAGGCAGGGAGTGAAGAC +CAGAGTGGAGCAGGCTAGAAACCTGGGAAGGAAGCAGGTTCCCCAGTATAAGCCCAGTGA +TGTGTGAAGAATGAGCCCAGGAGATGGGTGGGGAAGTAGGCCCACCCTGCCTACAGGGGA +GCCAGAGCAAGAGCAGGTCTGGGGGAAGATGAGGCCCCCCTTGGCTCCAGGTAGGGGAAG +ACTGACCTCCAAGGCCCAATGGGACCAGGTGTACGGGTGGACCCAGAGAGGAGAGGAAAA +GGAATCCTGGGGCAGCAACAAGAAGGCCACTGTGGTCTGAATGTCGGTACCCCCAAAATT +CATATGTTGGAACTGAATCCTCAGTGCGATACTATTATAAAGTAGGGCCTTTGGGAGGGG +TTTAGGTCATGAGGGTGAAGTCCTCACCATGGGATCAGTGTATAAAAGAGGTTCGAAGGA +GCTCATCCCCCACTTTTGCCAGGTGAGGACACTGTAATAAGCACCATCTTCAAGGCAGAG +AATCGGCTGGGCGCAGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAAGCCGAGGTGGG +AGGATCATGAGGTCAGGAGATCAAGACCATCCTGGCTAACATGGTGAAACCCCATCTCTA +CTAAAAATACAAAAAATTAGCCAGGCATGGTGGTGGGCGCCTGTAGTCCCAGCTACTTGG +GAGGCTGAGGCAGGAGAATGGCGTGAACCCGGGAGGCAGAGCTTGCAGTGAGCTGAGATC +GCGCCACTGCACTCCAGCCTGGGTGACAGAGCAAGACTCCGTCTCAAAAAAAAAAAGCAG +AGAACGGACCCCTCACTAGACACTGGGGCTTTTTTCTGAAGGCTACTGTGTCATATAAAA +TTTATATTAAATAAATTGATATGCTTTTCTCTTGTTAATCTGTCCTTTGTTAGAGGGGTG +TCAACCAGGAACCTTGTGATGCGTGAGGAAAAAATATTACCTTTTCCCCCTACTCTTTCT +GGCACCCAACAAACAAGTGGGGTGGCAAAGACACCCCACTTGGGACAACTGGCAAAAGGT +AAGCATTCTTACCAAGGTTAACTGTCCCATATCACTGCCTGTAGTACTCAGCTGAGAGTG +GAAGGTAAAAACTTCTTGTCCCTTCCTTTCCAAATTCAAATTAGCAGAAGAAAACATTGT +GTCTGGATTGTGACTCTTGCTTAAATTTGGTTGAGGGGTAACTGTTTGTTATTGATCCTT +TCCTCCCAGGCACAGCTACCTCTTTCCTGTTTGTTTTATTTGTGTCCTGAGAGCTTGGCT +TTATGACCAGTGAGAATATTCTCCCTGATCTCTGAATAGCCAGTGGGTGCAAGTGACAGC +TTGCTTTAGGACAGCTTGCGTTAGGGTTGCAAGTAACAGCTTGCATTATTACAAACTCCT +CTGTCCCGGTCAGAAAAAGAGAAAGTTTGGTTTTTGTTTGTTTGTTTGTTTTTTGTTTTG +TTTTAATAGTCTTGCTCTTTCGCCCAGGCTGGAGTGCAGTGGCATGGTGGCATGATCTTG +GCTCACTGCAACTGCTGCATCCTGGGCTCAACTGATTCTTCTGCCTCAGCCTCCTGAGTA +GCTGGGACTACAGGCACACACTACCACGTCCAGGTAATTTTTTTTGTATTTTTAGTAAAG +AGGGGGATTCATCATGTTGCGCAGGGTGATTTTTTTTTTTTTTTTTTAATTCTTTTCTGA +GACGGAGTCTTGCTCTGTCACCCAGGCTGGAGTGCAATGGCGGGATCTCGGCTCAGCCTC +CTGAGTAGCTGGGATTACAGGCACCTGCCACTACGCCAGCTAATTTCTGTATTTTTAGTA +GAGACAGGGTTTCACCATGTTAGTCAGGCTGGTCTCGAACTCCTGACCTCGGGTGATCTG +CCCACCTCGGCCTCCCAAAGTGCTGGGATTACAGGCATGAGCCACCGTGGCTGGCCTCTT +TTATTTTTAAGATACAGGGTCTCACCCAAGCTGGTCAGGAACTCCTGGCCTCAGTCCACC +TGTCTCAGCCTCCCAAAGTGCTAGGATTACAGGCATGAGGGACCACGCCCGGCCAAAGAG +AAGGTTCTGAACCTTCTCTTTTTCTGACCATGACAGAGGAGTTTGTAAGTGGGCCAAGTC +TATAAGGGGTTTTTGTTGTCTCAGTATTCATTGGTGTGATAGATGAGCCAGTCCATGACT +GGAGACGTGACAGTGTTCTGTACAAGATGACATCCTTAGTCACCTGTGTCAACAAAGGTG +CCTTCTGGCTAGGCACGGTGGCTCACGCCTATAATCCTAGCACTTTAGGAGGCTGAGCCA +GGCAAATCACGAGGTCAGGAGTTAGAGACCAGCCTGACCAACATGGTGAAACCCTGTCTC +TACTAAAAATACAAAAAAATTAGCCAGGTGTGGTGGCGCATGCCTGTAATCCTAGCTATT +CGGGAGGCTGAGGCAGGAGAATGGGTTGAATCTAGGAGGCAGAGGTTGCAGTGAGCCAAG +ATCGCGCCACTGTACTCTAGCCTGGGTGACAGAGCGAGACTCCGTCTCAAAAAAAAAAAA +AAAACCCAAAGGTGCCTTCTTTCTTTTGACTGTCTTTGCAAGGGGTCTGGATTTGAGAGT +GCTGAATCTTTGTGCACCCTCTTTGGAGTGTGTCTTTCTCTCTCTCTCTCTCTCTTTTTT +AAGAGACAGAGTCTCACCCAGACTGATCAGGAACTCCTGGCCTCAGGTGGTCCTCCCACC +TTGACTTCCCAGAGTGCTGAGATTACAGGCATGAGCCATTGTGCCCAGCCTTGAGGATGT +CTCTTTTGTCCATGGTTAAGTCATAAAATGCTTATTGGTCTTGGTTCTGAGTTGCTTGGT +AGGTACCTTTGGTTTACAAGAAGAAAAGTGGTGGGTGGGCAGGGTGGTAGTAGGGAAGAG +TGTTCAGTACTGCCAGGAATATGTACTATCTGTTCTGGCTGAAAACTGACAATGAGATAT +TTGAAAGGATTTTTTTTTTTTTTACAGCTCTATGATCAGAAGATGGCATAAGTGGGGCTG +GGCACAGTGGCTCAGTGCCCAGCTGGGATTACGCCTGTAATACCAGCACTTTGGGAGGCC +AAGGTGAGTGGATCACGAGGTCAGGAGTTGAAGACCAGCCTGGCCAACATGGAGAAACCC +CGTCTCTACTAAAAATACAAAAAATTAGCCGGGCGCGGTGGCAGGTGCCTGTAATCCCAG +CTACTCGGGAGGCTGAGGCAGGAGAATAGCTTGAACTCAGAGGGCGGAGGTTGCAGTGAG +CCAAGGTTGCGCCACTGCACTCCAGCCTGGGCGACAGAGTGAGACTCCGTCTCTAAAAAA +CAAAAAAGAAGATGGCGTAATCAGAAGTTGATATTCTGTCTATTGGATCCTGCTTCTCCC +CTGGGGTCTTCTTGGTTCCCTGAAGCCCCTCTTCCGGAGTCCCTGCCCTCTATCGGCTCT +GCCTCCTGCTTCTTTTCTGTATTGCCATGATTTTTGCTAAGGATAAAGGACAACTTCATT +GGCTTCTTTGGGAAACTTGCAATCTCCCCAAACAGGCCCCTCTGAGATTTCTCCTTTCCA +TTTGCTTCTGCTCCCCCTTCCTCCTTTTGCCACCTTCGATATTTTCTCCAGTTTCCTTGA +TTCCTTTGATACGTCCCCATTCAGGCCACTCTGGCCCTCCATCCAACCTGCCAGAACTTT +TTCCACTTCAGCACTTCAGTCACTTAAACATTAGGGCTCCCTGCCCTAAAGGGACTCAAA +ATCCTGCAAAAACAACCACCTAAGGATAAAAAGAGAAAAAATGAAACTGTTTGGAAACTG +GGCAAATGAATACTCTTTTAAAAGTCTTTTTCTGGGGGCCAGGTGTGGTGGCTCACGCCT +GTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCAGATCACAAGGTCAGGAGTTCAAGACC +AGCCTGGCCAATATGGTGAAACCCCGTCTCTCCTAATGATACAAAAAAAATTAGCCAGGT +GTGGTGGCATTCGCCTGTAGTCCCAGCTACTTGGGAGGCTGAGGAAGGAGAATCGCTTGA +ACCCGGGAGGCGGAGGTTGCAGTGAGCCAAGATTGCACCACTGCACCAGCCTGGCGACAG +AGCAAGAAGACTCCATCTCGAAAAATATATATGTATGTATATATACGTATTTACGTGTAT +ATATGTATGCATACATATATATATATATAGAGAGAGAGAGAAACCAGTGAGTTTGTATTA +CTGTGTTTTACTGACTCACGACTACCATTTTGGAATGAAAGCTATAAGATCTTTGTGTTT +TTACGTTTATGTGTTTATATTTGTGTATATCTATGTATGTATGTTTGAATATTATATATA +ATATTTTTTCTATCTCCATATTCAGTATTACTAACTGAATTTTTTTTTTTTTTTGAGATG +GAGTCTCACTCTGTCACCAGGCTGGAGTGCAGTGGCATGATCTCGGCTCACTGCAACCTC +CGCCTCCCAGGTTCAAACAATTCTCCTGCCTCAGTCTCCTGAGTAGCTGGGACTACAGGT +GCGAGCCACCATGCCCAGCTAATTTTTGTATTTTTAGTAGAGACGAGGTTTCACCATGTT +GGCCAGCATGGCCTCTATCTCTTGACCTAGTGATCCACCCACCTCGGCCTCCCAAAGTCC +TGGGATTACAGGCATGAGTCACCACGCCCAGCCTAAATTTTTTAAATCCCTTAAAGGAGT +TATATTCAAATTGTACCCTCCTTTGAAGATGTCTCTTTTGTCTGTGGTGTCTTAAAAGGA +TTATTGGTCTTAGAGGGAGGTAAATAAGCATTCATACAAGCTAAATATTACCAAAAATTT +AAGAAAAATAGAAACTAATCCAACTGCTTTTTAGTTTACATGATCTGGAATATTCTTTAG +TAAATAAAGCTAGTTTGAAAATTGATGGACTACGCCGGGTGCAGTGGCTCAGGCCTGTAG +TCCCAGCACTTTGGGAGGCCAAGGCGGGCGGATCACGAGGTCAGGAGATCAAGACCATCC +TGACTAACACGGTGAAACCCTGTCTCTACTAAAAATACAAAAAATTAGCCAGGTGTGGCA +GCATGGGCCTGTAGTCCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCA +GGAGGCGGAGCTTGCAGTGAGCTGAGATCACGCCACTGTACTCCAGCCTGGGCAACAAAG +CAAGACTCCGTTTCAAAAAAGAAAATTGATGGACTAGTCAAACAAGTTTTATGTTATCAC +TACTGAATGGTAAAGATAATAAAACTATCAATCCAACCTAAGAGCAAAATGTGCAATAAA +AATGAATTGCGGCTGGGCTCACCCCTGTAGTCCCAGCAGTTTGGGAGGCCGAGGCGGGCG +GATCACCTGAGGTCAGGAGTTTAAGACCAGCCTGGCCAATATGGTGAAACCTGGTCTCTA +CTAAAAATAAAAAGTAAGGCCAGGTGTGGTGGCGGGACCTACCTGTAATCCCAGCTACTT +GGGAGGCTGGGGCAGGAGAATCGCTTGAACCTGGGAGGTGGAGGTTGCAGTGAGCCGAGA +TCGTGCCACTGCACTCCAGCCTGGGAGACAGTGCGAGACTCCATCTCAAAAAAAAAAAAA +AAAATTGGGCACGGTGGTACAAGCCTGTAATCCCAGCTACTTGGGAGTCTGAGGCAGGAG +AATTGCTTCAACCTGGGAGGCGGAGGTTGCAATGAGCCAAGATCGTGCTGCTGCACTCCA +GCCCAGGCAACAGAGTGAGACTTTGTCTCAAAAAAAAAATGAATTGCATGGCTTGGCGCG +GTGGCCCATGCCTGTAATCCAGCACTTTGGGAGACTGAGGCAGGTGGATATTTGAGGTCA +GGAGTTCGAGACCAGCCTAGCCAACATGGTGAAACCCCATCTCTACTAAAAATACAAAAA +ATTAGCCAAGTATGGTGGCGTGCGCCTGTAATCCCAGTTACCTGGGAGGCTGAGGCAGAA +TTGCTTGAACCCAGGAGCTGGAGGTTGCAATGAGCCAAGATTGCACCACTGCACTCCAGC +CTGGGCAACAGAGTGAGACTCCATCTCAAAAAAAAAAAAAAAAGAAACAATAACCACTCC +CTCCCTACCTCCACATACATAAGTGATTACAGGCTCCAGGCCAAACACACAGAGGAGTTA +CATCTGGCTGGTGCTAGGATGGAAGGTGGGGCAGGTCACCACCTCCCAGGGACTGAGTGC +CAAAGCAAGGAGGAAGATTGGAGGTGAGGCTGTATGGAGACAGCCACAGGCTCACAGAGC +TTGTGCTGAGCTCTCTAGGGGGAAGCTTGATCTGCCTGGGAAGCTTCCAGCTCCTACCTC +CTGCAGAGCCCAGAATGGTGTCCAGGAAATATGTGGCCATTGAGTGGAACCAGCCTTGGC +ATGGTAGCCTGCAGGAACCCGCAGGCTAGAGACATGGCCACATGAGCAGTGAGGATCTCC +CCCGAGATGAGGATCCCCAGAACATAGTGTGGGATGCAGGTCTGGCCTCTGCATACCCTC +GGCTTCCTCCATCACTTATTCTCAGACATCTAAACCACTAACATCCAGACTGGGGATCCC +AGGAGGGTCTACAGTGTCAAGAGAGGGCAAGTCCACTTCAGGATCAACCTTCCTGTGGCC +CCTTACTTTCCTTGGTCCACCTTTCCAGGTCACCCATCCAGACTGTCACCAGGGATCACT +GCCCTGGGCACCAACCCAATGCGGGGACAAGTAGAAAAAGAGCTCTGGGGAAAATACCAA +AGGGAATAGTCACTCAATTTTACTGTGATGATAAACTCCTGGCAAAGTTCCAGGCCTCTC +TCTGTCTGTGTCTGTGAATTATGTGTCTGTGTCTCCATCAACCATAGTGCAGAAGGGGGA +GGGTTGTCCTAAGTATCCTATTAACATGTTTGTTTGTTTGTTTGTTTGAGACAGAGTTTC +GCTCTTGTTGCCCAGGCTGCAGTGCAATGGCATAATCTCAGCTCACTGCAACCTCCACCT +CCTGGGTTCAAGTGATTCTCGTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCACACA +CCACCATGCCTGGCTACTTTTGTATTTTTAGTAGAGACGGGGTTTCACTATGTTGGCCAA +GCTGGTCTCGAACTCCTGACCTCAGGTGATCCACCTGCCTCAGCTTCCCAAAGTGCTGGG +ATTATAGGCGTGAGCCACCATGCCCAGCCAGAACACAGGACTTTCAAAACTTAAACCTGG +GGCTGGGCACGGTGGCTCACACCTGTAATCCCAGCACTTTGGGAGGCCGAGGCAGGCGGA +TCACCTGTCAGGAGTTCAAGACCAGCCTGGGCAACATGGTGAAACCCCATCTTTACTAAA +AATAAAATAAAATAAAATACAAAAATGAGTCGGGCGTGGTGGCGCACTGTAGTCCCAGCT +ACTGGGGAGGCTGAGGCACGAGAATCACTTGAACCCCGGATGGCGGGGACTGCAGTAAGC +GATCACGCCACTGCACTCAAGCCTGGCAGACCTAGCGAGACTCTGTCTCAAAAAAAAAGA +AAACAAGGCTGGGCGTGGTGGCTCACGCCTGTAATCCCAACACTTTGGGAGGCCAAGGCG +GGTGGATCGCCAGGTCAGGAGATTGAGAACATCCTGGCCAACATGGTGAAACCCTGTCTC +CACCAAAAATACAAAAATTAGCCAGATGTGGTGCCAGGTGCTTGTAGTCCCAGCTACTCA +GGAGGCTGAGGCAGGAGAATCACTTGAACCTGAGAGGCGGAGGATGCAGTGAGCTGAGAT +TGCGCCACTGCACTCCAGCTTGGGCGACAGAGTGAGACTCTGTCTCAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAACCAAGGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCAAT +TTGGGAGGCCGAGGCAGGCGGATCATGAGGTCAGGAGATCGAGACCATCCTGGCTAACAC +GGTGAAACCCTGTCTCTACTAAAAATACAAAAAAATTAGCTGGGCGTGGTGGCGGGCGCC +TGTAGTCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATGGCGTGAACCCGGGAGGCGGAG +CTTGCAGTGAGCCAAGATTGTGCCACTGCACTCCAGCCTGGGCAACAGAGCAAGACTCCA +TCTCAAAAAACAAACAAACAAACAACAACAACAAAATAAAACAAGGAAAAAAACACTAAA +ACCTTGGATGTCCTGGGCAACCCCGGTCAAGATGATCACTCTAGATAGAGTTTTTAAAAA +TTAGTTTTCAGCCTGGCCAAGATGGTGAAACCCTGTCTCTACTAAGGATACAAAAAATTA +GCTGGGCTTCGTAGCAGGCACCTGTAATCCCAGCTACTTGGGAGGCTGAGGCAGGAGAAT +CACTTGAACCCGGGAGGCAGAGGTTGCAGTGAGCCGAGATGTCACCACAGCACTCCAGTC +TGGGCAACAGGGCGAGACTCCATCTCAAAAAAAAAAAATTAGTTTTGCCACCGGGCACGG +TGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGTAGGTGGATCACCTGAGGTC +AGGAGTTCGAGACCAGCCTGGCCAACGTGGTGAAACCCTGTCTCTACTAAAAATACAAAA +ATTAGCCAGGCATGGTGGGGTACGCTTGTAATCCCAGCTACTGGGGAAGCTGAGGTGGGA +GAATTGCGTGAACCCGGGAGACAGAGGTTGCAGTGAGCCGAGATGGCACCACTGCACTCC +AGCCTGGCCAACAAGGGCTAAATTCTATCCCCCCCCCCTCAAAAAAAACAATAACGATTT +TGGGAGTATTAGAGCAGAAAACGTTTGAAAACATGAACAGCTCTCACATCAACACAAGAC +ATGAAACTCTGTTGGCAAGAGAGGCCTCTTTGGGGAGAGTGCTCACTCCTCTCCCACCCA +CTCTCTACCACCTTCAACCTCCTGTCTGGGGCACAGTAACAAGGGGTGTAAGGGGTGTAC +AGTGCCTAGCAGGGGCCTGGCACTTAGGCTTCAGTAGGTGCCAGTCCACAGTCTCCTGAG +GCCCATGTTGGTTGGTGTCCACCTGGTGCTTATTGACCACTTGGGCTCCAGATTTTCCTC +ACGTCACCTCCCTCCCCAGGGTAGCAGATAAAGGCCCCATAGTTCCAAGGAGGCAGAACT +TTTACATTCCTAAAAGCATTCTCAGGCCCCCATAACCCCTCATCCCACCTTCAGCTCGCT +CACCTTCACCTATCAAATTCGTTTGACATCTGGCCTCCAGCAACTAGCTAGGCTGAGTTC +TCCATGAAGGGGACGTGGCTGCTGGTCAAAAGGGAAAGCCCATGTCTAAAAATTAATTAA +CGTGGTTTAGGGGCCTCACATTCCCAACCCCCAAATACAGCCATTGTGAGATGTGAGATT +CAAAAAATCGAAGAGTGAAGCGGTGATGAGAGTCCATCTGGTCGCTCTTCGGATGCGGCG +CTAGCAGGCAGTTGCATGAAAGCAGATCCCAGATCACGTTGCACTGGCACACAGTAGGTA +CCCACACATATTTGATAAATAAACACTCTCTCCCTAGCATTACTATAGATAGCTGGCAGC +TTGGCCTGGCATCCCGGAGGGGTCTGGATCTCAGGGACTAGATAAGGCCAGCACACTGAA +GAGTTGCAGAAAATGCAGGCGGTCAGGCGCAGGTCTGCTGCGGGAGCACCTGCCGTGTCC +GACAGCTGCACTGGAAGAGGGGCGTGTGTCTCCCAGCCGGGCGGAACCGAGACCGCTTCG +TCCCCGGCGGGGAACTTCATTTCCCACAAGCCTGTGCGCGAGACTCCATTTCCCACAAGC +CCTCCTTCACTTCCGGCTCGGCCGAGGCACTGCGGACGGCTTCCGGGTTTGGGCCTGGCT +CTGTGACTGAGGCGGCGGCGGTGGCGGCCAAGCGGGATACGGGCGGCGGGAGCTGGGGAA +CAGGCATGGACGTTTCCGGGCAAGAGACCGACTGGCGGAGCACCGCCTTCCGGCAGAAGC +TGGTCAGTCAAATGTGAGTAGTGGTCGGGGCAGGGGGCTGGATTGTGGGACCTTCCTCCT +TAGCGTGGCGGGCGAGGCCAGGGCCGGACCCGTGAGAAACCTACGGCGCCGGGAGACAGA +AGGCGCCGGGGACTTGCGTGGGTCCCAGGGCTCGGGCCCCCCCGTCTGTCCCCTCCGTTC +CCGACATGGACTGCTCGTTTGCTTTCCTGGGGCCGAGCTCTGCAAACCAACGAGCCCTGG +CTTATGAATCATCGTCTTGAGCTTTCTCATTCGTCATTTGTGTGCTTTGGGTGCAGACTT +TCCCCCGCTTTTTGAACCACACTGAATAGGGAAAGGGAGAGAAGCAGCCGGCTGTAGTGG +GTTTAGCAGGGCTGGGTGCTTCATGGTTTCTCTTCCAGAAAAGCGCATCAACGGTGAAAG +AAAGTGATGGGAGGAGGGTGGATGTAAGATGAGATTGGGAAGGTAGTTGTTTGGGGTGTG +GGCGGTGGGACGGAGGATCTGAGGGTGACCCCCCGAAGGAATGTGGACTTTGCCGAAGGA +TGGCAGGAAGCCGCTGTCAGGAAGCGATCGTCGTTTCTGGAGGAGAGCGTGAAGAGCTGG +GGTCAGTGGCCCCGCTCAGAGGAACTCTAGCCCCTCACCACCGACTGCTTGTTTCTGTTA +GCAGTTTTTTTCATGCGCGTCCGTGTGAAGAGACCACCAAACAGGCTTTGTGTGAGCAAT +AAAGCTGTTTATTTCACCTGGGTGCAGGTGGGCTGAGTCCGAAAAGAGAGTCAGCGAAGG +GAGATAGGGGTGGGGTCGTTTTATAGGATTTGGGAAGGTAATGGAAAATTAGTCAATTGT +TCTCTGGTGGGCAGGGATGGATCTCACAAAGTACATTCTCAAGGGTGGGGAGAATTACAA +AGAACCTTCTTAAGGGTGGGGGAGATTACAAAGTACATTGATCAGTTAGGGTGGGGCAGG +AACAAATCACAATGGTGGAATGTCATCAGTTACGGCTGTTTTTACTTCTTTTGTGGATCT +TCAGTTACTTCAGGCCATCTGGATGTATACGTGCAAGTCACAGGGGATGCGATGGCCTGG +CCTGGGCTCAGAGGCCTGACAGTTTTTAACTGAGCTTATTGGCGTGTTGTGCTCGCCACA +GATTTGCCTGAGACACAGCCCCTTTCCTGAGGGATGGTAAAGGAACCGTCACAGCGCAGT +CTTGTCAGTCTGTAATGTGTATACTGCAGGGGTTTCTTGCGAAGCGGCGGTTAACTTGAG +CAGACCAGGGGCAGTCTAGTGAGTAGGTGACGAATAAATTGAGTCCTAGAAAGACAAGTA +GGAGTGTGAATAGCCACCATTCCAAGCTGAGGAGTTAGGAAACATGAGCATTTACTGCGT +GGAGGGAGGATCTTGTAGGCTGAGAGTTCTGGGGCTCGAGGAGTAAGAGAGCCCAGGAGA +TGATGGAATGAGGGTGAGCAGGTACTAGCACTTTAGTGGGGGTGTTGTGCCAAGGAATTG +AGCCTGTGTTTGGCATGTGGCATTCTTTGGAGTAGTGAAATGCCAGTGTTGGGAATATGC +CTAGAGTCCCTGTCCCTGGAGATGGATGCAGGGCAGAGAAGAGAGACCAGTTAAGCTATT +AAGAGAGTTTGAACATTTGGAGGGAGTAGGGAACCTGTCCTTTTTCATCCTTATATTCTC +ACTGCTAGCTCACTGCCTGCCACATTGCTCCGTAAAATGATTGTGGCATGACCTAGTCGG +GCGGGAGATTATAAAGGCCTGCATTAGACAGTGGTAGAAACTGAAAGAGGAAGACAGATT +CCAGAGGAGGGGGAACGTAGACAATTCTTGATGACTAACTGGATGGAGGGGGGTGGGGTG +TGGGGTGAAGCATTGTGGAAGGAAGGAAGCCGGGCTGAATGCTGGGAAACCTTTCAGTAC +AGTGGAAAGAGTAGGGACTGTAGAGTTAGTAGCTATGGGCTTTGGGAAGAATAGCCTTGG +GATATTTCTGGGGATATTGCACAATCAGTGAACAGTGTTTTACTGATAAAATATAGTTAT +CTGTAGGTGAAAACTTGAGAGATATCCCACTTCAGGGTTCCTGCAAGAAAAGTCCCCAGG +GCAAGGGTTCTTCTCTGGGAAAGCCCAGAATTAAGAACTGGAAGGGTGAGTTGTCATCAA +AGAAAATGGGGGTAGGGGAAGTGTTAAGAGGGCTGGGAGGGTGATTGAAGAGTTTATGGG +TGTTGAGTGACTGGATACTTCATAACTCAGCTTTATTTTGCTTCCGGGAGAATTGAGTTC +TTTATTTTTTTCGATATTGCTGTTTGTGTGTTTTTCTGTTGCCGCTCTAACAAATTACCA +CAAGTTTAGCATCTTAAAACAACACACCTTTAGCCAGGTGTGGTGGCTCACGCCTGTAAT +CCCAGCACTTTGGGAGACTGAGGCAGGCGGATCACGAGGTCAAGAGACTGAGACCCATCC +TGGCCAACACGGTGAAACCCTATCTCTACTAAAAATCCAAAAATTAGCTGGGTGTGATGG +CGCACACCTGTAGTCCCAGCTACTCAAGAGTCTGAGGCAGGAGAATTGCTTGAACCCGGG +AGGCGGAGGTTGCAGTGAGCCGAGATCGCACCACTGCTATCCCGCCTAGTGACAGAGCGA +GACTCCATCTCAAAAACAAACAAACAAAAAACACACATTTATCATTTGGTAGTTTCTGTA +GGTCAGAGGTCCAAGTAGGTTCCACTAGGTCTCCTGCTATCAAGGCCTATCAAGGCTGAA +ATCAAGACGTTGGCAGGGTGCATTTCTTACTGAATGCCTTGGGGTGGAACTTGCTTGCAA +GCCCATTTATGCTGTTGGCCATATTCAGTTCCTTGAGCTTGTAGGACTGAGGTGCCCTCT +TTCCTTACTGGCTGTTAGCCAGGAGTCAGTCTTTGTTCCCAGAAGCTGCCCGAATTCCTT +CTCATGCTTTTTATGTGTCTCCCTCCAGCGAGGGCCAGTTCTTCTGCCACATCTCTCTGA +TTTCAGCTAGAGAAAATATCCTGCTTTTCAGGGCTCAGATTAGATTTAGTGCACACAGAG +AAGCCAGGATAATCTCTTTATTTTAAAGTTTGTAATTTTAATTACATCTGCAGAATTCCT +TTTGACATGTAATGTAGCATATTCACAAGTTCTAGGGATTAGGCACGAGATGGGCATTCT +CCTACCACAGCCGGGAAGAGCAGTTTCAGAGGTTGCCTTCCCTAGGTGATGTGGGTGTTC +TCAGTTCTCAAATTTGTCTGTTTTCTCTCTAGGGTTCACTTTCTCTCTAGGGTTCACGTT +GAAAGTCGTGATTCTTGGTGCCTTGATTTATTGTGCTCATAGGGTTAAAAAAAGATTTGC +ATTAGAATTCTAGACATACCTTTAACTCTTAACTTCCTCCCATGTTTTTACACTGTTGTT +TAAATTTGGCCATTTTGGGAAATGCTTTATACCCAAGTAATTTATAGTTGATGAAGGGAT +AGAGAAAGTGTCTTGCTTGTGGCACCGTGACTCACACCTGTAATCCCAGCACCCTGGGAG +GCTGAGATCTGGGACTACTTGAGTCCAGGAGTTTGAGACCAGCCTAGGTAACATAAACAA +ATACAACAATCAGCTGGGTGTGGTGGCGTGCACTCGTAGTCCCAGCTACTCTGGAGGCTG +AGGTGGGGGGATCGCTTGAGCCTGGGAGGTCGAGGCTGCAGTGAGCTACGTTCACACCAC +TGCACTCCAACCTGGGCCACAGAGCAAGACCCTTCTCAAAAAAAGAAAAAAAAAAAGCAT +TCTGAGTTTTGACAGAGAAGAAAACATTTGATGGTTACTTATCTGTCTCTACCAAGAGCC +TAGGGAACAATGCCCCAGAGCATGAGCTGGTATATAGTCTAGTCTCCTGGCTCCCACTGA +GAAAAAGGGATTTTGAGTTGAGGCTGGCTATGACTAGACAGCCATTGCAGGGACTCTCCA +GTTCAGCCTCTTAGCCCTCCACTGCCTCCACCTCATCTGGGCCCATTCTGGGCTGTGGTC +TCCTGCTCTCTTCCCAGTCCCATCCTTCTTCCCCCAACAGCACAAGTGAGGGTGAGGCCT +AAAGTGTAGCCACTGCCCTGCTGCAGAACAATCAGTGACTTTTCTTAGCATTAGAATAAA +ACTCCAGATGTCCCACCCTCCCAGCCCCTCACCCTGACCTGGTATAGTCATCTCTTCTCC +TACCCCCACCGTGTTCTGACCTCTCTGGTCTTTCAGCTTCTTGAACATTCTAAGCTTTTT +TTTTTTTTTTTTGGAGACAAGATCTTGCTCTGTGGCCCAGGTTAGAGTGCAGTGGTACGA +TGATAGCTCACTGCAGCCTTGACCTCCCAGGGTCAAACGATCCTCCCACTGTAGCCTTCT +GAGTAGCTGGGACTACAGGCACACACCACCACGCCTGACTGATTTTTATATTTTTTGTAG +AGATGAGGTTTCACCATGTTGCCCAGACTGGTCTTGAACTCCTGGGTTCAGATGATCCTC +CCTACTAGCCTTCCAAAGCACTGGGATTACAGATGTGAGCTACTATGCCTGGCCCCTGAG +CTCTTTCTTTTTAACCAATTTATTATCAAGTGTTTAAGGTATTGAAAAATGAGTAGACTC +CTCCCCACCACTGTATTCATGACTAGCTCCTTCTTTTAGGTGTCTGCTCAGTATCAGATA +CTCAGAGGATCCTTCCCTGCTTGATCTAAAGTTGGTCACCGCCTCTGATATGTTTTATCT +CAGCCCTTTTTAGTTTCCCATAGGACCTCATACCTATGAAGCTTGGTACCTGGTATACAA +AACACTTGTTGAGGAGTGGAATAGTATTTTCTTGGGGGCTGTGTGAGTCACCTCTTTTTT +TTTTTTTTTTTTTTTTGAGGTGGAGTCTCGCTCTGTTGCCCAGGCTGGAGTGCAGTGTCA +CAATCTCAGCTCACTGCAAGCTCCGCCTCCCAGGTTCACGCCATTCTCCTGCCTCAGCCT +CCTGAGTAGCTGGGACTACAGGCGCCCGCCACCACGCCCAGCTAATTTTTTTTTTTTTTG +AGACAGAGTCTCACTCTGGAGTGCAATGGTGTGATCTCGGTTCCTTCAACCTCTGCCTCC +CGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAATAGCTGGGGTTACAGGCATGCGCC +ACCAGGCCCAGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGTCAGG +CTGGTCTCGAACTCCTGACCTCGTGATCCACCCGCCTCGGCCTCCCAAAGTGCTGAGATT +ACAGACATGAGCCACCACGCCCGGCCGGGTCACCTCTTGTATTACAGTGGTATTCTTTAT +TTTTTTATTTTTTTAAGAGACAGGGTCTTGCTTTGTCACTTGGGCTGGAGTGCAGTTGGT +ATGATCATAGCTCACTGCAGCCTCAAACTCCTGGACTCAAGTGATTCTCCAGTGCAGTGG +TATTCTTTACCTGAACCAGTGTACATTGTGAAGCTCTGGAGCCCCTGCTTTCTCCACTTG +TTACACTTGTTAGCCTTTCTTTTTCTTTCTTTTTTTTTTTTTTTGAGACGGAGTCTCGCC +CTGTGGCCCAGGCTGGAGTGCATTGGTGCGATCTCAGCTCACTGCAACCTCTGCCTCCCG +GGTTCAAGCAGTTCTCTGCCTCAGCCTCCAGAGTAGCTGGGATTACAGGCACCCGCCACC +ACTCCTGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATCTTGGTCAGGCTG +GTCTTGAACTCCCAACCTCATGACCCACCTGCCTCGGCCTCCCAAAGTGTTGGGATTACA +GGCGTGAGCCACTGCACCTGGCCTAGCCTTTCTTAATCGTGTCCCTCATCAATGAAATGG +TAGAAAGCCAATCTGTTTTACAGGTGTGGTAGAAGGGAAAAATGAAGAGACCTCTGTACA +AGCCTTTGCAGAGGTCTTGGGACTCAGTGGTGAGCTCCCTGCCACCACCTCCTGTGCCCT +TGCAGGAGTAGGAGATCTATAGTCTTGGAGAATAAGGGTGATACCCCAATACCCCAAGCC +TGGTTAGGGAAATTGATGACCCTTATTGGAGCCTGTGGGGAGGTAGTTGGGAAATTGTTA +GTAGCTTCATGTTGGCATTTTCTTTTTTGAAACAGAATCTTGCTCTCTCCTCCAGGTTGG +AGTGCAGTGGCATGATCTTGGCCCACTGCAACCTCTGGCTCCCAGGCTTAAGCGATCCTC +CCACCTCAGCATTCCCAAGTAGCTGGTACTACAGACGCATGCCACCAGGCCCAGCTAATT +TTTGTATTTTGTGTAAGAGACAGGGTTTCACCATGTCTCCCAGGCTGGTCTTGATCTCCT +GGGCTCAAGTGATCCACCTGCCTCAGCCTCCCAAAGGGCTAGGATTACAGGTGTGAGCCA +CCGTGCTTGCCTTTGTTGACTCTTTATTGAACATCTACTCTCCCTGCAGAAACTGCAGGA +TAAGCCACCCTTAGAACCAATTTAACTGGCCTTTTTGGGGCTTGGACCTTCCTCATGGGA +TTGCTGGGTTAATGTTGAGCCTGTCTCTGGGCTATAGGCTCTCAGAGAACAAGAGTGCAT +CTGCAATGACTAGTGCTGCACCTGTCATACAGGTTTGTAGAAAATATTTAAGCTGTGAAT +GAACAAAAGGACCTTATCAGCTATTTTCTTTCAATTCTTTTTGGTTTTTCTGTGATCCTA +TTCTTGAGACTTTTATCCCTCCCACCCCTCTGTACAGCAGATTGCACATATAAAGATGAA +ATAAATAGATGTCCATTGGGCAAAACAATACAGAGAGGAGGTGACACAGCTGGGGAAGGA +CAGTCCAGTATCTGATGAAGTGCCAGAAGGGGCTTAGGGGGAGCATGGAATGGAGCTGGA +ACTGCCAGGTCAGCCACCTCTTCTAGTGAAGCCTCCAGAGAGACGTGAGCTCCAAGTAAG +ACAACACAAGGAACAAAACATACAACTGAACAGCAACTTCCAAGGGTCTGGAGAGGTCTT +CAGAAGGATAGGGAGTGCCCTTAAACTTGCAAGCCCAGATTCTGCCTGTGGGTCATGGTC +GTGCCATAGGCAGAAGCCAGTGAGTCAGCCTTGGCGGAGCTTTTTCTGTGGCTTTTCCCA +CTCACAGCTCTGTGCCCTTCTGGTGCAGCTCCAGCCCTTGTTTTCCAGCTTCATAGCCTG +GTTGTCACATAAATGGCTGCACTGGCTTACAGGTGTCTGTGTATAACCTATTGCTAGAAT +GTCCATTCCTTGAGGCTAGGGGCCCTGTCTGTCCCTCTCTTCACTTTCATAGCCCCAGTG +CCCCATAGGGCTGCTCCTGATGGGCAAATAGGAAGTGGTTGTTGAGCCTCTAGGCCAGTC +GTGACAGTGACCTGAGGGGACTTGAGCCCTCAGTCATCTGCTCAGGAGTTCAGGGCTTTC +TCAACAGCAGCTGACGTGCGGCAGGCATGCTATGCCAAGCCCTGTTGCAGGAGTTGACAG +ATGTTGACTCATCCCCTCTTCATGCTTTCTTTGTCAGTAGATGTACATGTTACTCACATT +TATAAGATGAGGAAAATGAGACCTAGAGGAGAGGCCACTGCTGCTTAGAGTTACTCTACA +TGTTGTAAATCAGGGGTGTCCAGTCTTTTGGCTTCCCTGGGCCATGTAGGAAGAAGAATT +GTTTTGGGCCACACATAAGATACACTAACACTAATGATAGCTGACGAGCTAAAAAAAAAA +AATTGCCAAAAAATCTCATAATAAAGTTTACGAAGGCTGGGCGTAGTGGCTCACGCCTAT +AATCCTAGCACTTTGGGAGGCTAAGGTGGGTGGATTGCTTGAGGTCAGGAGTTTGAGACC +AGTCTGGGCAACATGGTGAAACCCCATTTCTACTAAAAATACAAAAATTAGCTGGGCATG +GTGGCGGGCACCTGTAGTCCCGGTGGGGAGGCTGAGGCAGGAGAATCGCTTAAACCCGGG +AGGCAGAGGTTGCAATGAGCCAAGGTCGCGCCACTGCACTCCAGCCTGGCGACAGAGTGA +GACTCAGTCTCAAAAAAAAAAAATATATAGACCAACCTGGCCAAGATAATAAAACCTCGT +CTCTACTAAAAATACAAAAATTAGCCAGGCATAGTGGTGCACACCTGTAGTCCCAGCTAC +TTGGGAGGCTGAGGTAGGAGAATCGCTTGAACCTGAGAGGCGGAGGTTGCAGTGAGTCAA +GATCACGCCACTTCACTCTAGCCGGTGACAGAGCAAGACTCTGTCTCAAAACAAACAAAA +AAAATTAAAAATAAATAAGTAGGTTGGGCGCGGTGGCTCACACCTGTAATCCCAGCACTT +TGGGAGGCTGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCTAGACCAGCCTCAACATGG +AGAAACCCTGTCTCTACTAAAAATACAAAATTAGCTGGGCATGGTGGTACATGCCTGTAA +TCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATTGCTTGAACCTGGGAGGCGGAGGTTGC +AGTGAGCCGAGATCACGCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCGTCTC +AATAAATAATAATAATAATAATAATAATAAATAAGTAAATAAATGAATGGTTGCTGAACC +ACAGCAGGACAAGACAGACAAACCCCTTTTATTTGTTTTTGTTTTTTGGACCCTAACAGC +AGAGGAAGAGCCAGCCAGCAAGCCCCTTTTGATCTTTGGCCTCTGCCAACCAGTACCCCC +CAGACCTTAACCCCCAGCCCTACCAGGTCCCTTTTGTAAGTGACCCCACATGCCTACCAC +AGTTGCAGGCCCTGACATCCACCCTGACCAGAGGTCTTCCAGCTATTACTGGTGTTTGTG +ATGCTGTGGCTGTGGCCAGTCAAGGACCCATGCTGGGCATCCCGAGGTAGGAAGGACCAT +GACCACGTGATTATCTCCCTGCCACTATCATGGCAGGGCTGTGGGGTACTAGCCTCCTTT +AAAGCATTCCTTAGGACAGTAATTTCTGTTAAATATCTGGAGGGCAAACATTTTAAGGAA +TTTTAATGAATTTTTAAAAATTCAAAATGAAAAATTTAAATCATAAAACCAAATAGAAGA +AAGACCCCTATGTCCATATACGCACCACTCTGCTTCAGTGATTATCAACTCTTGTCTCAT +GTACTTGACCTCCACACAATTATTATTACTATTTTTTGAGAAAGGGTCTTGTTATGTTGC +CCAGGCTGGAGTGCAGCAGTACAATCATAGCTCACTGCAGCCAACTCCTGGGCTTAAGTG +ATCTTCCTGCCTTAGCTTCCCAAGTAGCTGGGACTAAGGGTAGGCGCCACCATGCTGGCT +AATTTTCTTATTTTTTTTTTTTTTGGTAGAGACCAGGTCTTGGTTTGTTGCCCAGGCTGG +TCTTGAACTCTTGGCCTCAAGTGAGCCTCCTGCCTTTGCCTCCCAAAGTGTTGGATTACA +GGCATGAGCCACTACGCCTGGCCATCCCCAGTTATTTTGATGCCCAGACTGTTTTAGTGG +CTGCCCACTGTCTGTGGATTCTGTTCTTAGTCTTGATCCTTCGTGCAGTGTCTGCACCTG +CCTGCCAGTTCCTTGACCTGTGCTCCATCATACCAAGCTGGCAGTGGATCCTCAGACAAT +CTCAGTTCTTACTCCCTGCTCTGTGTCCAGTTTGTTTGCCTACCTAAAAGATCCTTCCTT +TTCGTGGCTGAGCAGTGCAGCCGTTCTCCAAGGAGACTGGGCCTTCTGCTGCCCCCACCA +CCCTGCTCTTTTCACTGCCCCCACCCCGCTGCTCTTTTCACAGGCTTGGTGAGGAGTTTC +CAGGTTGCACTTGGTTTGTTTGAAGGCTTATCTCCTCCTAGTCTGAACTCGTCAGGGCAG +GAGCTTGAATCAATCATTTCCTGCCTCTCAGGACTGCTGTAGCAGGGGGATTCCTAGATC +TGTCCAGTGCCAGTTTCCTGAGTACTGCTGCAGGCCCATTTCAGCTGCTATGGTGATGGG +GGCTGTCCTGAGGGGACATTCACCTCAGGTAGAGATGGCAGAAACACCACAGGAAGATGC +AACCAGTCAGCTCAGCTGGGGGCACTTAAATTAGATCCATTTTTTTTCTGGAAGGCCTTT +TGGCAATACTGTTTATCCCAGTACCTTAAAAATGTCGATTTCCTCCAAGGGCGCAATCAG +GAAAGTATTCAAAGCCTGATGGTGATGAGGGTGCTCATTGCCGCATCATTGTCTCAGGAG +TGGGATTTGTGAAACAGACCAACAGTGGGAGCTTGGTTAGAGTTGTAGCTGCAGGTGATG +GGCTCTGTGCTGCTGTTGACATTGACGTGAGGGACTGCCATAATGCGTCAACATCGACAA +GCGCTTGTTACCAAGCAGGATGCGTGGTACAGGCTGAGTTTTATTAAACAGATGTCTTTA +ACTGGTATGAATGATTTTAATTTTTTCTTTGTTTGAGATGGAGTCTCGCCCTGTCGCCCA +GGCTTGCGTGCCTGGTGACTTCTCTCACCTGGGCCCTCAATGCCAGACCAGCCTTCCCAG +GATGATTCCATCCTTTCCATCCCTGCAAGGGAGCTTGAGGCCCTTTCCCTTTCAGTTTGA +TACTGTCCTTCCAAGTTACCTTTCTTCATGTTGGCACGAGAGCTTTGTGCCACACCATGC +CCTTTCTGGATGCTGTAGTGTCTGGCTCTTCCTCTGTCTCTGTGACCCTCTTCCCTGGTG +AAGCTTTGACCTTGGCTTCATCCCCTCCAGATGACCCCTGATGGTTAGCTCAGCCTGTGG +TGGCTCCAGAGCCCTCATTGAGTGCATCCTGACACGAACTGAACAGATTAACTATTTTTT +GCCTTGCCAACAGCATTGGAAATTCCTTGAGTGTGGGACCTGGACTCATAGCTCTATGTC +TCTTATAGTTCTTAGCACAATATCTTGGCCTAGATGAAGTACATAATAATTATATGTAGG +GTTGTGGAAAGCAGTGCTGGCTTTAATTAAAGCCTGCCATGGTTTTGTCCATCAGTGCTG +CCTAAACCGTTCTGAACTTCTCATTTTGAACTTTTTTCCCTCACAGCTTGTGATGGTTGA +TTTTCTTTTTGAGACATTCATTTATTTGTTTGTTTATTTGGCAGGGTCTCACTCTGTCAC +TCAGGCTGAAGTGCAGTGGCGTGATTGTGGCTCACTGCAACCTCCACCTCCTGGGCTCAA +GCGATCCTCCCACGTCAGCCTCCCAAGTAGCTGGGACCACAGGTGTGTGCCTCCATGCCC +GGCTAATTTGTGTAATTTTTTGTAGAGTAAGGGTTTTGCCATGTTGTCCAGGCTGGTCTC +CAACTCCTGGGCTCAAGCGATCTGCTGCCTCCGCCTCCCAAAGTGCTGGGATTACAGGTG +TGAGCCACTGTGCCTGGCCCTGAGACATTTATTTAAAGACAAAGGGGAGTACAGGCTAGA +GAACAGAGGGGAATAGAATAGCAGCCAAGGCATAATTACCTCTAAACCATCACCCCATAA +GGGAGATGTTCGCCTCAACTTTAGTAATGACTCTCTTTCTAGTCTAGGTGCAGGGCTGTT +AATAGAGGCCCTGTGATTGGGTTAAGGGCTTGAGGTACAATAACTCTGTTATTTAGGGCA +GTGAGTCCTTGGAGAAGATGCTTTACCTTCTTTCCAAGCCCCATGTCTCCTTATTTTGAG +GGTGTTTTTTTTTTTTTTTCTTGAGACAGTCTTGCTCTGTTGCCCAGGCTGGAGTGCAGT +GGCCTGACCTCGGCTCACTGGCCTGACCTTGGCTCACTGCAACCTCCGCCTTCCGAGTTC +AAGTGATTCTTGTGCCTCAGCCTTCTGAGTGGCTGGGATTACAGGCCTGCACCACCACAC +CTGGCTAATTTTTGTATTTTTATTAGAGATGGGGCTTCACCATATTGGCCAAGCTGGTCT +CAAACTTCTGACCTCAGGTGATCTGCCTGCCGCATCCTCCCACAGTGCTGGGATTACAGG +CGTGAGCCATTGCATCCGGCCTGAGGTTTTTATTTTGAGAATATTTCAAATGTACAGAGA +GTTGCAAGGACAGTAAAAGCACTCAGGCATCCTCTTCCCTGGGATTCACCAGCTCATTCT +CACTTTTACCATCTTCCCATACTCCCTGGGGGCCTCCTCCTTCTGGGCTTCGTTTCCTTT +TATTTGTTTCTGTCTTTTTAATTTTAATTTTTTTTTAACTAGCCCTTCTCTTTGGCAGGA +TTTGTTCACTTTTAATCCTTGGCCCCAGCAGCTTCTCTGAGCTCTGCCTATGAATCTGGG +GGAGAGATAGGGGCTCACACAAGAGTGAAGTGTGAGCTGGAGGGCTGAAGGGGAATGAGG +GACATCTGGGCCAAAGGCAGGGGACCAGCAAGGCCCCCACCCCTGGAACTTCTGTTCTTC +CCAGCCTACGTACCCCTTGCTTCTTCTTATGTTGGTGGGCTCTGGGGGCTGGGTGAAAGC +AGTGCTTGTAGGTTAAGAAGTGACTCATCCCACGTGCCCGCTGCCCTTCTCTTCTGTTCT +TTGCTCTTTCCAAGCTTCCTTTCAGTCCTCCTCATCAGACATGACCTTTGAGGAAGTGAT +GAGTCTGCTATGTGTGAGACAGAGCCCCTGTTGTGAAGTAGAACTCAGGGTTCGTCCTCA +GAAGCCTCGGTGGGTCACCATACGTCCTGCAAGTGCTGTCAGTCTGCTTTGATTCGTGTG +AGGGAGAAGTCCCTGCCAAGTGCTCTGTAGTAGGCATTCAGGCCAACCAAAGAACAGGGC +AGGGTCCTGAGGCACAGGCTCAGAGCTCTTGCTTATTTCATGGGGTGTTTAAATTGAGGT +ATAATCCCTATCACAGTGAACGACACGCATACTTCCAATCTTGAGTGTGCCACCAGAGAA +CTGTTGATACTCCCCAGATCTGCACCCAGCCAGGGCAAACTGTGCACCACTCTTCTGACT +TCCATGGCCAGCCGAGACATTTGGAATCTCTGTGCAATCACACTCTGTGCCATCTTTTTT +TCGAGACAGGGTCTCGCCCTGTTGCCCAGGGTAGAGTGCAGTGGTACAATCTCGGCTAAC +TGCAGTCTCGACCTCCTGTGGGCTCAAGCAATCTTCCCACCTCAGCCTCCCAAGTAGCTG +GTACTACAGGTGCTCACCACCATGCCCTGCTAATTTTTGTGTTTTTTGTAGAGATGGGGT +TTTGCCATGTTTCCCAGGCTGGTCTCGAACTCCTGGGCTCAAGCAATCCACCTGCTTCAG +CCTCCCAGAGTGCTGGGATTACAGTCCTCTGTGCAATTGTGTGCATCATGTGTGAAATTT +ATCCTCATTTATCCTCACAGGCAGCAGTTGTTCTATTTTTTTTTTTTTTTTTTTTTTTTT +TGAGATGGAGTCTCACTCTGTTACCCAGGCTGGAGTGCAGTAGCACAATCTTGGCTCCCT +GCAACCTCTGCCTCCTAGGTTCCGGCAGTTCTCCTGCCTCAGCCTCCCGATTAGCTGGGA +TTACAGGCACGTACCACCATGCCTAGCTAATTTTTATATTTTTAGTAGAGACTGGGTTTT +GCCATGTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGGGATCCACCCACCTCGGCCT +CCCAAAGTGCTGGGATTACAGGCATGAGCCACCATGCCCAGCCTGTGTTTTTGTTTTTTT +TGAGACTGAGTCTCACTCTGTCGCCTAGGCTGGAGTACAGTGGCGTGATCTTGGCTCACT +GCAAGCTCTGCCTCCCGGGTTCACACCATTCTCCTGAGTAGCTGGGACTACAGGCGCCCA +TCACCACACCCGGCTAATTTTTTTTTTTTTTTTGTATTTTTTTTAGTAGAGATGGGGTTT +CACCATGTTAGCCAGGATGGTCTCCATCTCCTGACCCCGTGATCCCCCTACCTCGGCCTC +CCAAAATGCTGGGATTACAGGCGTGAGCCACTGCGCCTGGCCTTATTTATTTATTTATTT +ATTTATTTATTTATTTATTTATGTATTTCTGAGACAGAGTCTTTCTCTGTTGCCTAGGCT +GGAGTGTGGTGGCTCAATCTCACCTCACTGCAGCCTCTGCCTCCAGGGTTCACATGATTC +TCCCACCTCGGCCTCCAGAGTAGCTGGGACTACAGGCGTGCACCACCATGCCTGGCTAAT +TTTTGTATTTTTAGTAGAGATGGGGTTTCGCCATGTTGGGCAGGCTGGTGTTGAACTCCT +GACCTGACCTCAGGTGATCCACCCGCCTTGGCCTCCCAAAATACTGGGATTATAGGCGTG +AGCCACCGTGACCAGCCTGTTCTTGTTTATGACGTGTTATTCCATGGAGGACTCTGTTCC +AGATAACTCTTTTATTTTGTGCCTAATGAACTTTGGTGTTAGTTCCAGATGTTGGCTACA +TGAAGGCAACCCCAGGAATGGCTTTGGTCATGTCTTCTGGTAAATATATGCACTTAATTC +TCTGGGCTGTGCACCTAGAAGTTAAATAAAGGACTGGGTCAGAGGATGTGTCTCTTAGCA +TGTTCTGCTGAACAGTGTTCCCAAGTGGTACCAGTTTACGTTCCCACCAGCAAAATGTGA +GGGAGTTCCACTTGCTGGACATCCTTGCCAACACCTGGTATTGTCAAGGAACCTGTCTGT +AACAGGCACTCTCGTTGATTTTGAATGCACGCTGAAATTTACTGGGTGCAGTGACAGTAG +GAAGGGAAAGGATGATTAAAAAAAGAAAAAAGGAATGGAAAGGCTGATCTAGGAGGGAGG +AAGCTCATAAGGAAATAAGTGGTAGGATTTGGTGATTCCATGTGTGAATGCTCGTATTCC +GTGTGCATGCGTATATGAGCTTGCAGGAGAAAGGGAGGAGGGAGGCACTGGTATGCACTC +CACCAGTTCTCCTGCCACAGCCTCTCTACTGATCTGAGGGCTGGGTGTAAGGTGATGATG +TGGGGAGTGGGTGTGGGTGAAATTTCCAACAGTCAGTGGGAGATGGGGGAAGCAAACCTG +GGAAGAGCAGCCTGCTGCAGGAGCAAGTGGGTGGGCCGTCCTGGAGGCTGGATGAAACCT +GTCTGCCTAGGTGGGGATGGCAGAAGTGGCAGAGCAGAGAACTCCAGAGCAGGGCTGTGG +TGGGCAGAGCAGATGTGAAGGAAGACTGTGGGATGAGAGGATGGGGCACGGTGGAGCCCC +ATCAGCCTCCAGTCACAGCAGCCCCGGTCCCGTCTCTCCCTCCTGTTTTGGTCAGTACCT +TCAGGACTTGTGGGTGTAGTACTTCGTTCCATTCCGGATAACATTGTAGAAGACTGAAAA +ACAGGAAGGTGTTTTCCATACTCTCTCCAGAGCTGGCTGTTACTGACATATTGATATATT +TCCACCAGTCTTGTGTGTGCTTATAGCTTGATATGTATGCATTTTAAATATGTAAATATA +TATACACATGTATTTTTAAAGTGAAACTAGGCTGAGACTGTGAGTTCAGTTTTGAGTTAT +AGGTTTCCCATGGCTTAGGTTGTGTTCTCTCCCTGGATGGAGTCTGGCTGGGACCTGCAT +GCTCACAGCCCAGGTTCACATGAGGTGTGGATCATGCACAATCATCCCACGGGCTTGAGA +TAAGCATTTGACTTCCTTTTTTTTTAAAAAAAAAGTTCATTATGGACTTTTTCAAGTGTT +CCCAGAAGTAGAGATAATAGAAAAGTGGTCTCCCAACTACTTTGAGAGTTAGCAACATAT +GGCCAGTGTTGCTTCACCCACCCTTCCTCATCACCTCCTGGACTATTTTAAATCACATCC +CAGACACCAGATGATTTCAACTGTGAGTACTTGAGTGCAGATCTCTAAAAGATCGAGCTT +CCCCACCCCCACCAAATACCACAGAGCCATGTGAGATCAGCATTTGGGTTGGCAGATCTC +CTCCTTGCCACATGCTTGCCTGGTGGTGAATGGGACACTTTCAGGCGAGACCTAGGGGAG +CCCCAGGCCAGCACCAGGACAGAGATCTCGAGGCCTTTCCAACTCTGCTGGTTCTTCAGA +AGTCAAACCAACAGATTGGAGTATGTGAAGGAAGCTCGTGTATTCTTCTGAACTAGCTTA +GACAACAGTACACAGTTTGAAGGGCAGCAGCCTTTTCTGCAGGTTAGTTCTTTCAATGAT +CTTGTTTACTGGGAGTTGAGAGACCTTGAGGATAGAGGCAAGAAAGCGTCATCAAGCAGC +CCAGAGGGGTGTACAGTGTTTGAAGTCTCCTGTATTGGTATGATTCGAGATTTTCATTCT +GCAGGACCAAAATACCCATTCCTACATGTGGGTGGAGAGTTAAATTCTGAAGTATATATT +TTTATCTTGTTAAAAAAACACTTTTATGTTTCTTTAAAAAGTAAAAGAACCAGAATGTAG +AAGTTTCAGTAAAGGAAAAAGTTACAGTTTGTTTGGGATACAGTTTGACAAATGTGCTCC +CAGCTGCCTGAGAGATAGAGAGGCCAGATGTTTGCTTTGGTTACATTGATGACTGAACAA +TCGGTATCTCATCATTTCCTGCCTTAGAGATGAAAGCACCTGGGCACTGGGGCAGTAAAT +TGGTTGCAGGATTGGAAGAAGTCCAAGGACAGTGTGGGATGCCACCCTGTAGCTGTCTAG +AGACCTAGTGAAGGTCAGAAGGCTGGGTGAGAACAAGCCCTGCACTGATGGAGGACAGGG +AAGGGGCTTTTCTGGCTGGGAGTGTGGTGAGGCATTTGAGCTGCAGCCAGAAGGCACCTC +TCAGATTGGTGGGGCTTGGGGTGGGGGTGGGAGGAACTGCTTTGCCTGTGCCGTTGGCCT +CACTCATCCTGAGGTCCCTTCAAACTCCATCCATACTCTGACTGTGGGGCCACTTGCAGA +AGGAATATGTGGCAGGTTTTTTTTGTTTTGTTTTGTTTTTTGTTTTGAGACGGAGTCTAG +CTCTGTCACCCAGGCTGGAGTGCAGTGGCACGATCTCGGCTGACTGCAACCTCCGCCTCC +CGGGTTCAGGCGATTCTCCTGCCTCAGCTTTTGGAGTCGCTGGGCTTACAGGCGCCTGCC +ACCATGCCCAGCTAACTTTTGTAATTTTAGTAGAGACGGGATTTAGTAGAGACGGGATTT +CGAACTCCTGACCTCGTGATCCGCCTGCCTTGGCCTCCCAAAGTCCTGGGATTATAAGTG +TGAGCCACTGTTCCCTGGCCTGTGGCAATTTTTTGAGACGCTCCTGGGGGTCCAAATTGC +TAATAGAGGAGAAACTTACTGTCCCTGTGTTGACTGAGACAGGAAGGTTTAGATAGGTGA +AAGTGGTCTGGGCGCAGTTGCTCACACCTATAATCCAGCACTTTGGGAGGCCAAGGTGGG +AGAATCGCTTGATGCCAGGAGTTCAAGACTAGCTTGGGCAACATAGTGAGATCCTGTCTC +TATAAAAAATAATTTTAAAAAATTAGCTAGGCCTGTAGTCCCAGCTACTCGGGAGACTGA +GGAGGGAGGATTGCTTGAGCCTAGGAGTCGGAGGCTGCAGTGAGCTGATTGCGCCACCAT +ACTCCACCCTGGGCAACACAGAGAGCCTGTCTCAAAAACAAAAGAAAGGTGAACATGAGT +TTTTTTGTTTTTTTTTTGACATAGTTTTGCCCTGTCCCACAGGCGTGGGCCACCACGCCC +AGCTAATTTTTGTATTTTTAGTGGAGATGGGGTTTCGCCATGTTGGCCAGGCTGGTCTTG +AACTCCTGGCCTCTCAAGTGATCCACCCACCTCGGTCTCCCAAAGTTTTGGGATTACAGA +CATGAGCCATTGAGCCTGGCCAAACATGACCTTTCTCTTTTTTTTTTTTTTTTTTTTTTT +GAGACGGAGTTTCACTCTTGTTGCCCAGGCTGGAGTACAGTGGCACGATCTCAGCTCACT +GCAAACTCCACCTCCCGGGTTCAAGTGATTCTCCTGCCTCAGCCTCCTGAGTAGCAGAGA +TTACAGGCATGCACCACCACGCCTGGCTAATTTTGTATTTTTAGTAGAGACGGGGTTTCT +CCATGTTGGTCAGGGTGGTCTCAAACTCCCCACCTCAGGTGATCCACCTATCTCAGCCTC +CCGAAGTGTTGGGATTACAGGTGTGAGCCCCTGCACCCGGCCACGTGACCCTTCTTAATA +GCTATTGTTCGCTGAGTATTTCTCTACGACACTCTTTATGTGCATTTTGTCATTTAATTT +TAATTTTAATTTTCTTTTTTTTTTTGAGACAGGGTCTTACTCTTTCACCCAGGCTGTAGT +GTAGTGGCACGATTTTGGCTCGCTGCAGCTTCCGCCTCCTGGGCTCAAGAAATCCTCCCA +CCTCAGCCCCCGAGTTTCTGGGACTACAGGCATGCACCACTATGACTGGCTAAGTTTTTG +TATTTTTTGTAGAGATGGGGTTTCACTATATTGCCCAGGCCAATCTTGAATCTTGAATTC +CTGGGCTCAAGCATGAGCCACCACACTCGGCCTCATTTAATTTTTAATTACTTTAAATTT +TATCAACATAATATATCACATAAACTGTAAAAAGACAAGAAACTACTGTGGTTCCCATTC +TGCCAGTTCTCCCCAGAGGTAGCAACTGCCTTTACATCTGAGCTTTCTTCCGGCATATAC +CTCTGATTCTAGGTAATAGGCACATGCTGCTTTTGCAACTTGGCGTTTTACAAATTATGT +TGGCTTGCTCTGTAGCTCCCTTCCATCGCCATTATCTCTGCTTCTCCTCCCTCATTCTTC +CAGTATTCTACTTTCTGCATAAATCGGTAATGAATGTTTACATTTTCTGCCTACACAAAT +GATATTCACAGCTGAGCATAGTGGTGTACTGCAATTGCTTGTTATTTTTTTCCTAGGAAA +GAATTGCCTTTTCAACACTATGCCCAGTTTTCTGTGTATCTATTCTTATTCTTCCTTTAT +TTTCCGGTTGCCTCTCAGTACAGTTATCTTCAGGCTCAGTGCTAGTGAGCTGTCAGTTTC +AGTTCAAACCCCTGGCCTCAAGTGATCCATCCACCTCGGCCTCCCAAAGGAGGTGGGCGG +TGACCCTCTTGGACCTCCCTTCTGGAACCCTCTAGGCAGTGGCCGCAGGTGTGGTGTGAC +AGCCCTCAGCGTGCTTGTCTGCCCAGACTGGGACTGTTGTCTTCCTTTGTTGGGTCCCTT +GTTTTCTATATCCTGTGTCTCATCCTTTGTGATTTATTCCCTCATTCTGCCAGCTTCCTG +AGAAGGGACTCCTGGGAATTAACTTTCTGGAGACCATGCCAGTTTGAGTGCATCTAGGCC +CCCTGGTGGGACATGCTAACTGGGGAATTTAAAATGATGTTACACTGCGCTGCCCTTGTG +CTGGCTTGTGCTTCTGTCTCCTGAGGTGCTAGCTCTCAGCCTCATATGACTTGTCTTGAT +CCCTAAACCCAAGTCCTGCTCTACTTGGGAAGTTCCTTTGAGTCATTTCAGGGGAATCTC +ACTCCCTACACTTCCTGTGCTGGAGTGTTTAATGTTCACTCTTTGGGCCTCTAGTTTTAT +CTTTTATCTCCTGTTTTCTATCTCTTTTACTTTTAGCTCTCCTCTCTAAGTGATTTCCTC +AATTTTTTCTTTGACCTTTCACTGCTAACATGCTTTTATTTCCAAGAACTCCTTCTTTTT +CCTTTTTTGTAATCTGACTTTTCCCTTTTTATAGCACCCATTCCTGTTAAATGGATACAA +TGTAGTATAATATTTATATATATTATAATAAATTCTACCGTTTTTTTTGATAAATTTTCA +CTTTATTGCCCAGGCTGGAATGCAGTGATGTGTTCATGGCTCACTATGGCCTCGAACTCC +TGGGCTCAAGTGATCCTCCCACCTCAGCCTCCCAAGTAGCTGGGACTGCAGGCATGCACC +ACCACTCCTGGCAAATATTTTTGTTTTTCGTAGAGATGGGATCTTGTGATGTTGCCCAGG +CTGGTCTCAAACTCCTGACTTCAGCTGGACGCAGTGGCTCACACCTGTAATCCTAGCACT +TTTGGGAGGCCGAGGGCAGGCGGATCACAAGGTCAGGAGTTCGAGACTAGCCTGGTCAAT +ATGGTGAAACCCCATCTCTACTAAAAATCAAAAATTAGCTGGGCATGGTGGCGCGCGCCT +GTAGTCCCAGCTACTCGGGAGGCTGAGGCAGAAGAATCACTTGAACGTGGGAGGCAGAGG +TTGCAGTGAGCCGAGATCGTGCCACTGGACTCCAGCCTGGGCGACAGAGCTAGACTCCGT +CTCAAAAAAAAAAAAAAAAAAAATCAAACTCCTGACCTCAAGTCATCCTCTCGCCTCAGC +CTCTGAAAGTACTGAGATTACAGGTGCGAACCACTGCACCTGGCCTAATAAATTCTACAT +TTCCTTCTTCTTGCTGAATTTCTGTTACCGCTAAATTACTCTTTTCTTGTGGGGTCTTTA +TTGGCCATGTTATGGCGTCTGGCTGCCCTTGGCTGGTTGCTCACTCTGAGAGGGACCCTC +CAAAGCCTAGGAGTCTCTTCCAGCACGTGGAGCTTGTCGACTGGGAACTTCATTGAAGGC +TCATCTGGCTGCAGATTCTGAGTCCTTCCTCCAGAACAATGGTCCCCAACCTTTTTAGCA +CCAGGGACCGGTTTCACAGAAGACAATTTTTCTACAGACCGGCAGATGAGGATGGTTTCA +GGATGAAATTGTTCCACCTCAGATCATCAGGCATTAGATTCTCATAAGGAGCATGCGACC +TGGATCCCTCACATGCACAGTTTACAGTGGGGTTCGTGCTCCTATGAGAATCTGATGCCA +CCACTTATCTGACAGGAGGCAGAGCTCAGGCAGTAATGCTTGCACACCCTCTGCTCACCT +ACTGCTGTGAGGCCTGGTTCCTAACAGCCCACAGACCTGTACTGGTCTGTGGCCCAGGGC +TTGGGGACCCTGCCCTAGAGCATGGTCTTCCAGACACTGGGCTGTGGGTGAAGACCTGGC +TGCCAGCATGCTGCTCACTGCGATGGAGGAGGCTGATGGGCCAGTGGGTCTCGGCAGTTA +GCGTGCATCGATCTAGTCACTTAGACCAGAGCACAGATGACCACACAACCCACCTCTCTC +AGTGTCCTACCTGTGCCTTTTCAACTGGGTGGGTTGGCCCCCTAGTCCAGTGACTATCCG +TTTCATGCTTTTCCAGAGAGTAAACCTCCTGTGGTCACCTGGTGCTGGAGTAGCTACCCA +CAGTGTAAAGTTGGGGAGTGAGGGATGCAGGGATATCTTTCACCCTCTGTCCCAGAGCAC +TTGGTGCAGCCTGGCCTCAACCTGGCAAAGACCTAGGGCTGTCACTGGGTGGGCGCACCC +CCTCCTCACTGTTACTTAGGACTCTGGTTTCTTGGTCCTCTTGCTGTGTACGTTACCACT +GGGCCATCAGCTTTCCAGCTTCTAAAAGGCTGTTGAGGCCACCATTTCCATTCTTCCTGG +TTTTTTTTTCTGTGGTTTTAGTCAGGTTTTAAGATGGAAGGGAATTAAATGTGCAGGCTT +TGTTCCTCATTTCAACTTGGAGGTTCATATCTGTTATTTATTTATTTATTTAGAGACAGA +GTCTCACTCTGTTACCCAGGCTGGAGTGCAGTGGTGCTACCTTGGCTCACTGCAACCTCC +ACCTCCCTGGTTCAAGCGATTCTCTTGCCTCAGCTTCCCAAGTAGCTGGGATTATGGCCG +CACACCACCATGCCCAGCTAATTTTTATATTTACGTATATATTTTTTTGAGACAGAGTTT +TACTCTTGTCACCCAGGCTGGAGTGCAATGGCTTGATCTTGGCTCACTGCAACCTTCACC +TCCCAGGTTCAAGTGATTCTCCTGCCTCGGCCTCCCGAGTAACTGGGATTATAATGCACG +CCACCATGCCTGGCTAATTTTTGTATTTTTATTTTTTATTTTTGAGACAGAGTTTCACTC +TTGTTGCTCAGGCTGGAGTGCAGTGGTGGGATCTTGGCTCATTGCAACCTTTGCCTCCCG +GGTTCAAGCCATCCTCCTACCTCAGCCTCCCGAGTAGCTGGGATTGCAGCGCCCACCACC +TTGCCCTTTTGTATTTTTAGTAGGGATGGGGTTTCACCATGTTGGCCAGTCTGGTCTCGA +ACTCCGGACCTCAGGTGATCCACCTGCCTTGGCCTCCCAAAGTGCTGGGATTACAGGCGT +GAGCCACTGTGCTCAGCTAATTTTTGTATTTTTAGTAGAGACGTTTCACCATGTTGGCCA +GGCTGGTCTCGAACTCCTGACCTCAAGTGATCCACCTACCTCCGCCTCCCAGAGTGCTGG +GATTACAGGCGTGAACCACCACACCTAGTCCAAATCTTTTTTTTAATATGGGAAAATCTT +TTTTCCTTTATAGTGTCTGCTTCTGGTGACATGCTTAGGAAACCATCATCCTGATATTGT +ATAACTCTCCTTCTGTTGTCTTGTGGTCCTCTGTGATTTAGGTTTTTAAACACATAGGGT +AAAGGGTCCCACATACAAGCTGTGGGCTCCTGTCCCAGGTGGGCAAGCAGGCTGCACACA +CAGGCAGCAATTTACTGGGAGGCTTCTTGGGTGGGGTGAAGTGGAGCTGCCAAAAATTTA +TTCTGCCCTATGAGAGTTCACTTGATTGATAGATGTTGTGTTTCTCAAAATTAGAAAATT +AGAAGAAACTCACAGAAGTTTCCTTCGAGCAGAACATAAATCGGCTGAGAGGAATCATCC +TGCCCCCCTGAGGTCAGGAGGGTGAATCTGTGCCCCAGGGAGGAACGCACCTTCCTGCTT +TAGACACCAGCAGAGGACAGAGAAGCTGGCTGTCCTGGGAATTCATGCCCTCATTCAGCA +ATGGGAAAGCAGTTGGACCAGGGAAGGGGGCCTGGCAGTGTGGCAGGGGGAGCAGTGGTA +AAGAGGGTGGGGTCAGGGGAGAGGCCTCACTGAGAGGGGAGAGGGTCCTTGGTGGGAACC +AGGGCGGTTGTGGAAGGAAGAGTCAGGGCGTGGAGCAGAGCAGAGCGGGAGTTGGGGTGG +GGAGGCCAGTTCATGCCTCATCAACATGCCTGTGTGAGTGTCCTTCTTGCGGGCGGTGGA +GCTGGCCTCAGGGTACACTGCAGGTGACTCAGAGCTCCAATGGGAGGGTGGCTCTGCCTG +AGGGAGCTGCACATGCTCATTGGGCCATCGTCTGCTGAGGAGGGGGCAACAATAACCTCA +ACACATGGCGGAGGTGTTTTGGGATGCATCCTATTGCACATTTGGGCAGGTTGTTGCCTG +ACTTATTTCTTTAACGCATACCTAGCACTTCCTGTATGTCCAGTGCCTTATAATATTAAC +TACTATCATCCTCAGGGCTACCCGTGAGGTCGGCACTGTCCCCACCCTTTGTGCAAAGGA +AGGATAGGGAGGCGCTGCCAGATGGGTTGAGGGCAGACCGGGGCAGCTTGCCTCAGGCCT +CCCTGGCCTTAGCAGGCTTTAAGTTTGATGCCCTGTGCTCCTTCCCTAGGAAGCTCAGTT +TGCCAGTTTTTTGCTTTATCTTAGTCTCATTCAGATTACAAGGACTGGGACTGGACTCCT +GTTGCCAGTTTCTCAATTTGGAATAGGAAGGAGGTGAGGAACAACAGGCCCATGCTGGGC +AGAAGCCCTGCAGACCAGGCCAACAGTGGGCCTCTCCTCACTGCCTGGCCCTGTCTGTGC +ACCTTCGTCCTGGCCACAGCCTCTCAGAGCCCCTCCTTTATGAAGAGGTTACGCTTTAGG +GGAGGGAGTGCCTCTCCCAAGACCCAGAGCTGGTGAGTGGCTAGGTTGGAATTTGAGCCC +AGGTCCCTCCTCCCCTGTCTGCTTCCTGCCAGGCCCAGCTGCCTGCCCCAGCACACGCCT +TCTCCCAGGCACCCTGGCCTCCACTGCCAGGACGTGCCTGTTTGAGGCCTGGATTCCCCC +ATGGCTGCCACGCTGATTCTCCGTTCTGCACGTCGTGTCCCATCAAAATGCATGACAGTA +CCACTCCTTGTGTTAAAAAGAGCCAGTTATTGTGCCTGGCAGTGATGACTGCCCACTGCA +CACAAAAGTGGACGCCGTTGTCTCTGCTCTCAGGGTGTTCTTAGTATAGTGGGGCTGGCA +CACAGAAACCAGAGATTCCTCCAGGAAGTGCCACAGACATGGGTGAGGTGGCTACAGGGT +TTCTGTGCAGCCGACAGCAGGGGTGCCTGGGTGGAAGCAGGGTGGGAGGCCCTAACAGGC +CTGATGGGATAGTCAGGCAATGTGCCAGGTAGTAGGTCATCATCCCTGGGGCCCTGGGGA +GAGTGTGTGGGGCAGGCGCAGGAGCAGGCTCCTCAGTGGGCTCCTGGACAGGCTGCCTGC +TCTGCTGGTGAGGAGCGAGGCTCAAAGCAAGCAGGGGCCTGGGTTGCTTCCCACACTCAG +TGGCAGTTGCTCACTGGCAGTCATGTGACCTGGGGAGCTGGCGAGGGCGTGGGGGTAGGA +ATGGGAACGGGAGACAGAGGCCCTTTGGGAGGAATTGCCACAGATGCAGTGGGAGTTGGG +GCAAAGATTTGAACTTTGGAGAATTAAAGGTGGCAGTCAGAAAGTGAAGGGAGTTCCCAA +GTTTCTGGGATGGGCACTTGGTGCTGGGAGATGAAGACACGAAGAGCTTTTCTTGATGTA +TCCCTGCTGGCTGCTCAGGCAGGGTCGGGCAATGCCATTAAGACACACTGTGTTCTGGGA +ACAGTTCTGGACAGTAAGGACATCCTCAGACCCCTTAGTGGGGGAGCTCCAAGGGCCTGT +AATGATGAATCGGTCCCCTGGGAGGCTTCAGTCTAAGCTAGATACCAGTTGAACCCTGAC +TGAGTACACAGACATAGCTATGGCAACCAGCTAGACCATGGCCAAAGGCAGAGCATTGGA +GCCCAGTTCACAGCAAGGGACTGTGTGCTCTGAGCCGGTAACAGTCCTTGTGTTCAGAGG +TCTGGCTGGTCGCAACCAGGGAGTGGCCCCCAGCCCCCTTCCTCAGCTAGAGCGAGCACC +ACCCAGGCAGCCTTGGGTTCTTTGGTGGCCGCCTCATAGGCCTGTACTGTTTGTGAACCT +GTTGCTTATGTTGGACAGGACTGTGGCAGGACAGCCATCAAGGGTCTTCCCTTGTGAGCT +GACACCAGTCTGCTCTTTGTCCTCCTCTGGCTGGACAGGCCCTCGTCTTCCCGGCTTGCT +TGTGTGGGGGAAGAGCTCACTGTGACATGTGGGTTCTCTGTTCTTTGTCTCAGGCTGTGC +TCCTTACTCCATGTTGGGGGCTGTCTCCTTGTGTGATAGTTTCCTTTCATTTCGTGACAG +TGGCTCGAAGGGTTTTGTTTTCAGGAGACAGAGACTGAGGAGTAGCCATTCGGGTCTGGC +TGCTCAGGAAGGCATGCTGGGGATGGCAGCAGAGCCCAGCTCAGGGAGATCAGAAGGGGG +CTTTGGGAGCAGCCAGTGCTGTTCTGAAGGTGGGCCTGGGTCCTGCCTGCAGCCTCCCGC +AGCGGGTGTGTTAGGTCTAAGGGAGGAAGGAAGGGGACTTGACCTCAGCAGGAGTGTGAA +ATGGGTACCCTCCTGGAGTCAATGTCCAGGCAGGGGATGCCTCTGAAAAGCGCCAGGCCA +GCTGGAGAGGAAAGGGCAGGCATCTGCAGGGAAGTGTGGGGGATTAGCTGCAGAGTTCCT +GGGTTCTTTTTCGCTTTGTCTCTATTTTGTGACACTTGATCTTCAAACTAGAAACAGGAG +CAAAGACATTTTCAAAAATACAGTTGTCAGAACTGCAAAACCACACAGGGTCTGTTACTG +GCCACCAAACCTGCTGGGCCTCCCTGGGTGGATGCTGTGGGAGAGATGTGGGAGTGACAT +GGCACAGTGCTGCTGTTCTGAGCGGTAGCCTTGCTGGAGGAGCGCCTTGCCGGAGGAGCA +CCTTGCTCCTTGGCCCCACTCTGACCCTCCGAAGCTCATGTGGAACTGGACATTTACCCC +AACTCGGTTTCCTGGTGTTGGCCTGTCAAGACTTGCCTGTTTCTGGCCTCCAGCTTGGTC +CATGCTCCTCAGGCTCTGAGTAGCTGACGGTGCCCACAGTGTCCATGTCATCTGTGACAT +TACCCAGGACAGGACAGGGCCCGTCTGCCAGTACATCCCCTGGTGTATGGTGCCACCTTG +CCTTCAGCTCACCAAGCATATTTCTTCAACCTGGTCATCCCACCACCTCAGAGCTATTGC +ACTAAGCTGTGTTTCTAGATCTTGTCTCTCTGACTGTGCCAGGTGTCTCTGCTGCACCAA +GACAGTGTCTGTCTGGGGCCTGCCAGTCTGCTGACACTCTCAAAAACGGCCAGTAGCAGC +TCAAAAGGACTGCTTTTGTATCAAAGCCTGGCTTTGCTCTCTGATCGCTGCTGGTGGGCA +CAGAGCCCATCTGTGTAACTGGTTGTCACTCCCCAGACTCTTCTGCACCCTTCTTCCTCT +CTGACTCCTGGCCACATCTGCCACCCACAGCCTCCCCACTCCTTACACAGCCAGCCTCCA +GGCCGTCCTGCTTGGCCTGCAAATGCTCCCCTGCTGTTTCTACTGCTCTTCCCTGAGTCT +CCCTATTGGTCCCAGTGCTTTGGGAGGCCAAGGTGGAGGATCACTTAAGGCCAGGAGTTT +GAGACCAGCCTGGGCAACAAAGCAAGACCCTGTCTCTACAAAAAAAGTAAAAAATAAAAA +AATTAGCCAGGCGTGGTGGCGCATGCCTGTAGTCCCAGCTATTTGGGAGGCTGAGGTGAG +AGGATACTTGAGCCCAGGAGTTTGAAGCTGCAGTGAGCTGTGTTTGCCCCACTGCGCTGC +ACCTGTGAGAGAGTGAGACATTGTCTCAAAAAACAAAAGAAGAAAAAGAAAAAAGGAAGG +TGGGAAGAACAAGTATGCCTTTGAAGGGCATACCTGCCTTGAGGGGCACAGATGAGGCAA +CCTTCAGAAAACAGGCCTGTGCAGCCACTTCTATCAGAAATGCTCACTGACTTCTTGGGG +CCTAGCAGCTATCGTCTCAGCCTCTGGGTGTGGAGACCCTGCCCCATGCTAACCTGAGAG +CATGAGTACAGGGTCCTCCCAGCCCACCCATGCCTCGCTTCCCCAGGACTCTGACCCAGT +GCCGCGCGTGAGTTGGTTGTCATTATCCTCCTGGATTGTTAACTCTCTCATCTTTTGTGG +CCCTGGTGACCTTTCTTACTTGTCTGTTCCACACCTGGATGCCTTGTGAGCAGAAACCCC +TTGCTGCCTCCTCGCCTCCCTTCAGGCTTCAGGAAGCAGACAGGGAGGTAGGAACTCCAA +GAGTGCAGGAGTCTCATTCTGTCGCCCAGGCTGGAGTGCAGTAGTGCCATCTTGGCTCAC +TGCAACCTCTGCCTCCAGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGG +ACCACAGGTGCCTGCCACCACACCCGACTAATTTTTGTATTTTTAGTGGAGACAGGGTTT +CACCACGTTAGCCAGGCTGGTCTCAAACTCCTGACCTCAGGTGATCCACCTGCCTCGGCC +TCCCAAAGTGCTGGGATTACAGACCTGAGCCATCGTGCCCAGCCCAAGAGTGCTTTTTGA +ATCTAGCAGGGTGGTAGGTCAATGTCATTTTGTTTTTCTTTTTACATTAAGACAGATGTA +TGCACCTCTCAGCATTAAACCTCCTTTCTGTGATGTCTTTAAGAATCACAGTCATATTGC +TGTAGCCCCGTCTGTACATTCCTTCAGTTTCCTGAGGTTGGCTGGTTGCTGTTTGGAGTG +GTCAGAATGCTTTCTAGCACGAGCTGGACTGGGCCTATTCAATTCACTCAGAGGCAAGGC +CCCAGAGCCCTGACATGTTTGCTTGTTTCTTTTTTCTTTTGCTTTCTTTCTTTTTTTTTT +TTTTGAGACGGAGTCTCGCACTGTTGCCCAGGCTGAAGTGCAGTGGCGCAATCTCCGCTC +ACTGCCAGCTCCGCCTCCCGGGTTCATGCCATTCTCCTGCCTCAGCCTCCCGAGTAGCTG +GGACTACAGGCGCCTGCCACCATGCCCAGCTAATTTTTTGTATTTTTAGTAGAGACAGGG +TTTCACTGTGTTAGCCAGGATGGTCGTGCTCGCCTGACCTCGTGATCTGCCCGCCTTGGC +CTCCCAAAGTGCTGGGACTACAGGCGTGAGCCACCGTGCTCAGCCTGCTTCTTTCTTTCT +TTTTTTTTTTTTTTTTTTTTTTGAGATGGAGTTTCGCTCTGTCACCCAGGCTGGAGTGCA +GTGGCGCAATCTCGGCTCACTGCAACCTCCACCTCCCGGTTCAAGCGATTCTCCTGCCTC +AGCCTCCTTTGTAGCTGAGATTACAGGCATGCGCAACCACACCCTGCTAATTTTGTATTT +TTAGTAGAGACAGGGTTTCACCATGTTGGTCAGGTTGGTCTTGAACTCCTGACCTCAGAT +GATCCACCCGCCTCGGCCTCCCAAAGTGTTGGGATTACAGGCGTGTGGCACTGCACCTGG +CCACTTGTTTCTTTATCAGCAAGCCCAGGGTGGGAGGCCAGGCAAGGAAGAGACCCATCC +CACTGGCAAGAAGGCAGGCAGTGAGCACACCAGAGCAGTCCACCCCTGGGAGCCACAGGC +CAGGCCTTTCTAACAGATTCACACTTGTTTTTGTCTTTCTGTGTGTGAGTGTGGGAGGTG +GGGGTGGGGGTGGGTGGGGCAGCATGTGCTGCATTCGAGGGGTCTCCACCTTAACTGATG +TACATGGCTCTTTATCCCCGTGGAGCAGCAGTGTGATGAAAAACTCTTCATAGGATTCTA +TCTCTTAGTACAAAATTGTTGGTAAATGGGTTTTTAAAGATATTTTTCACATTTATGTGG +TCTTTCTCTTCTTGTCTCTAGCTAGAAGTGAAGTTGGAGCTTGTCTCTTTGATCCCACAT +ATAGGACCTGCATTGTCCCACATAGGGACAGACCCTTGCCTTGGGAGGGACTGAGAGATG +ACTTCATGTGGCCCCTTCATTTTATAGGAGTAATCGAGTCTAGAACCAGGGTGCTACCAT +CTGGCAGAGTTCATGGGGAACGCAGGCCACTCAGAGAGCAGGAAATAGAGGCCAGCTGGC +CACCCAGTAGTCTAATGCGTACTTCCTTGATCCTGAACTGGTTGTGAGCCATCCCTAGGG +GCAACCCCTCCCCCGCCCCGTCCCTTCATGCCAGGGCTCTCTCTTTGCTTCATGGCGACC +ACCTTTCCTGTCCCTTTTTTCTGATCACCCTGCTCAGTGGCCTGTCATTGCTCTCTGTTG +AGTGCCCCTTCCCATATGCCTCTCCTGGACCTCAGCCAGGCTGGTGTGCTGGCGATAGCA +CCTTGTCACCAGGGGCAGCTGCTATGCAGGGCCTGTTGGCCAGGGCCCTGCAGCGGTGGA +GTCACTGGTGTGTGCAAACGTCTCTTCTCCTTTTGTGTTTCAGCGAGGATGCCATGAGGA +AAGCTGGTGTGGCACACAGTAAATCCAGCAAGGATATGGAGAGCCATGTTTTCCTGAAGG +CCAAGACCCGGGTAAGGCCCTAGTAAGTGGAGCCACTCTGGCAGAGAGACTTGGAGAGGA +GAGCATCACAGACTCTGGAACCCCTCTGTTGGGTGTCCTAGGGTGTAGGGGTGGGGTGGT +TGCTCATCGATTGATCACAGGCACAGTTGGTTTTGCCTGCAGCAGTCTGGGTCCTCCTGT +GTGTCCATGGTACAGGGAGGGCACTTGGGTTGCAGGCCCAGCCTCTGGCCCCAGACCTCA +CTGCCGTCACCTTCCATCTGTGGTCAGCCCCTGTGAATCCTACAGGAAGCTTGCTCAGGC +CCCTAGCTGGTCCTGTGGAAGGGATCAATGCCGTGAGCAAGAACCTGGTTTGTCCTCAGC +CCCTCCTAGGGGTCCTTACCTAAGCCCTACAGGGCCCTGAGGCATGGGCCCAGAAGCATT +CCTGTCCCCTTTTGCTAAGTGAAGAAGGTGATGCTTATCTAGAACTCGCCACAGGTGGAG +TGGAGAAGAAGGATTTCCACTATATGTGGGCTTTCTCCCTGGGTGGGGCACCACACTGAG +GGCTTTATGTGACCACCTCCTTTAATCTGTGTGTGCTCCCTGGGACAGAACCGTTTTACT +AGAAATGAACAAAACACATATTCACTTGTGTGCACGTGTGTGTGCAAGGCAGAGCTGCAA +GAGCACAGGGACTGAGGTGGGGTAGAGTGGGCTCTGTACTATGGACACGTGTGACTGAAG +TGGGATAGAGTGGGCTCTGTATTATGGATACGTGTCACTGAGGTGGGGTAGAGTGGGCTC +TGTACTACGGATACGTTTGATAAGCTTTTTCTTTTTCTTTAAGAGCTTTATACGGTTCAC +CCTTTAAAGTTTACATTTCAGTGGTCTTTAGGATATTCACAGAGTTGTGTGGCCATCACC +AAAATCTAATTTTGGAACATTCATTAATAAATAAAAAGAGGTGCAGCTTCCCTGTGTTGC +CCAGGCTGGTTTCAAACTTTTGGCCCTACGCCATCCTCTTGCCTAGGCCTCCCAAAGTGC +TGGGGTCACAGGTGCGAGCCACCAAGCCTGGCCTAATTTTAGAACTTTTTTTTTTGAGAC +AGGGTCTCACTCTGTACCCAGGCTGGAGTGCAGTGGCGTGATCTCAGCCTGCTGCAGCCT +CAATCTCCCGGGCTTAGGCGATCCTCCTTTCTCAGTCTTCTGAGTAGCTGGGACTACAGG +CATGTGCCACCACACCCGGCTAAGTTTTTTATTTTTTGTGGAGACGAGGTCCCACTATGT +TGCCCAGGCTAGTCTTGAACTCCTGATCTCAAGCTATCCCCACGCCTTGCCCTCCCTAAA +TGCTGGGATTACAAGTGTGAGCCACCATGCCCAGCCTTCAACATTTTTTAAAGAAACTTT +ATACCTGTTAGCAGTCACACTCCCTTTTCCTTCAACCCTCAGCTACCACTTATACTTTCT +ACTGCTGTAGATTTGCCTATTCGGAATTTTCCATATAAATATAATTGTACAACATATGGG +TTTTTTTTGTTTGTGCGTGTGTGTGTGTGACAGTTTTCCTCTTGTGCCCAGGTTGGAGTG +CAGTGGCACAATCTCAGCTCACTGCAACCTCCGCCTACCAGGTTCAAGCGATTCTTCCGC +CTCAGCCTCCCAAGTAGCCAGGATTACAGGTGCGCACCACCACACCCGACTAATTTTTTG +TATTTTTAGTAGAGACTGGGTTTCATCATGTTGGCCAGGCTGGTCTCAAACTCCTGAGCT +CAGGTGATCCGCCCGCCTCAGCCTCCCAAAGTGCAGGGATTACAGGCATGAGCCACCGCA +CCCAGCCACGTACAATATATGTTTTTATTTTGCAGCTGGCTTATTTCACTTAGCATAATA +TTTTCAAGGTTCAAGGTCCATGAACCATGTTTGGTATATACTTTATTCCTCTTTTGTTTT +TTTTAGATGGAGTCTCGCTCTGTCACCCAGGCTGGAGTGCAATGGCACGATCTCGGCTCA +CTGCAACCTCCACCCACTGGGTTCAAGCAAGTCTCCTGTCTCAGCCTCCTTAGTAGCTGG +GATTACAGGTGTGTGCCACCATGCCTGGCTAATTTTCGTATTTTTAGTAGAGATGGGTTT +TGCATTGGTCTGGGGCTATGTTGGCCAGGCTGGTCTCAAACTCCTGACCTCAGGTGATCC +ACCTGCCTTGGCCTCCCAAAGTACTGGGATTACAGACGTGAGCCACCGTGCCTGGCCAAC +TTTATTCCTTTTTATTGTCAAATATTCCATTTCTGGATGGCCATATCACATATTTTATAG +CCATTCGTTAGTTGGTGGACATTTACATAGTTTCTACTTTTTGGTTATTATGAGTAAGCA +GAACAATAGTTAATGTATAAATTTTTGTGTGGGCTGTGTTTTCATTTCTCTTGGGTATAT +ACCTAGGGGTAGAGTTGCTGGGTCATACCCTACCTCTGTATTTGACCTTTTGAGGAATTG +CCAGATGTTTCCCAAAGCAACTGTACTATTTTAAATTCTCACCAGCAGCTTAAATGAGGT +TTCAATTTCTCCTCATCCTCTCCAATACTTGTTATTGTCTATTTTAATTGTAGCCATTAT +AATGGGTGTGATTTGCATTGTTTTGATCTGCATTTGCCTAGTGACTAATGATGTTGAGCA +TCTTTTTCATGTGCTTTTTGGCCATTTGTATATTTTCTTTGGAGTAATGTCTATTCAGAT +CCTCTGTCCATTTTTAAATTGGGTTGTTAGTCTTTTTATTGTTGGGTTGTAATAGTTCTT +TATGCATTTGGATATAAGTCTGTTATTAAATATATAATTTGCAAATATATAGGGGGGATT +TTATTTATTTATTTTTATTTTTGTTTTTTTGAGACAGTCTCGCTCTGTCGGCCAGGCTGG +AGTGCAGTGGAAGTGGAGGGATGCAGGGGGTGTTAGTGATGCATTGTAATCATCCCGGAG +AGCAGGACACCTCTCATAAGAGGTTTACCCAAGGGGGGCTGTGGAAAGGGCTAGAAATTG +CTCCTGGAGGACGTGGAAAGCCACATAAGGTTTTTGACAGATTAGGGAAAAGGCTGTGCC +ACTCTTTCTGAAGATGACAGTGTAGGCAGCCTTTCCATTTTGTGCCAAAAATAAAATTTT +AAATACATAAATCACAGTAGTTTCTAGGACAACTGGGTAACTACATACAAAATATTGAGG +TTGAGCCCCAACTTCATACCCTATACAAAACTTAACTCAAAATAAAAAACACCAGCCAGG +CATGGTGGCGCGTGCCTGTAGTCCTGCCTAATCGACAGGCTGAGGCTGGAGGGTCACTTG +ATCCCAGGAGTTTGAGATTACAGTAAGCTATGATTGTACCAACATGTTCCAGCCTGGGTG +ACAGAGTGAGACTCTGTCTCTAAAAAACTTTTTAAAAAATTAACTCAAAATGGGTCAAAA +ACCTAAATTTACAAGCTAAAACTATAAATATCTTAGAAGAAAGCAGAGGCGTACATCTTC +ATGACCTTGGATTAGGCAGTAGTTTCTTAGATATGATGCCAAAAAAGCACAAGCTACAAA +AAACGTAGATAAATTTGACTTCATCAAAATTAAAAACTTGTACATCATAGGACACTGTCA +TAAGAGGGAAAAACAACCCATGGGATGGGAGAAAATATTTGCAAATCACATATCAGGTAA +GGGTTTAATATCCAGAATACATAAAGAACTCCTACAACTCAACAACAACAACAACAACAA +CAACAAAAAGCAACTAAAAAATAGGCAAAATACAGCCAGGCGCGGTGGCTCACACCTGTA +ATCCCAGCACTTTGGGAGGCCGAGGTGGGCAGATCACGAGGTCAGGAGATTGAGACCATC +CTGGCTAACATGGTGAAACCCTGTCTCTACTTAAAATACAAAAAAAGGAAAAAAAATTAG +CCAGGCGTGGTGGTGGGCGCCTGTAGTCCCAGCTACTCAGGAGGCTGAGGCAGGAGAATG +GCGTGAACCCGGGAGGTGGAGCTTGCAGTGAGCCAAGATCATGCCACTGCACTCCAGACT +GGGTGACAGAGTGAGACTCCGTCTCAAAAAATAAATACATAAATAAAATAAATAAAAATA +AATGAAATAAAAAATAGGCAAAATACTTGAATAAACCTATCTCCAAAGAAGAGATACAAA +TGGCCAACAACCATGTGAAAAGATGCTCAACATCACTAGTCATTAGGGGATTGCAAATAA +AAACCACAATGAGATGCCACTTCATTTCCATTATAATGGCTATGATTTTTAAAAAAGACA +ATAATAAGCGTTGGCAAAGATGTAGAGAAATTGGAATTCTCTTTCTTTTTGAGACAGTCT +CGCTCTGTCGCCCAGGCTAGAGTGCAGTGGCACAATCTCGTCTCACTACAGCCTTCGCCT +CCCAAATTCCGGTGATTTTCCTGCCTCAGCCTCCTGGGTAGCTGGGACTATAGGCACACA +CCATCACACCCAGCTAATTTTTTTTTTTTTTTTTTGAGATGGAGTCTCGCTCTGTCGCCA +GGCTAGAGTGCAGTGGCGGGATCTCGGCTCAACGCAACCTCCGCCTCCCAGGTTCAAACA +ATTACCCTGCCTCAGCCTCCCAAGTAGCTGGGACTACAGGCATGTGCCACCATGCCCAGC +TAATTTTTGTATTTTTAGTAGAGACAGGGTTTCACCATGTTGGCCAGGATGGTCTCGATC +TCTTGACTTTGTGATCCACCCACCTAGGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGC +CGCTGCACCCAGCCAATGCCCGGCTAACTTTTGTATTTTTAGTAGAGACAGGGTCTCATC +ATGTTGGCCATGCTGGTCTTGAACTCCTGACCTCAGGTGGTCTACCCATCTTGGCCTCCC +CAAAGTGCTGGGATTACAGGGGTGAGCCACCGTGCCTGGCAGAGAAATTAGAATTCTCAT +ACATTGCTGGAGAGAATGTGAAATGGTGCTGTGGAAAACAGTATGACAGTTCATCAAAAA +ATTGAATGTAGAGTTACCATACGACCCAGAAGTTTCACTCCCAGGTATATATCCAAGAGA +AAAGAAAACATGTCCACACAAAAATATATACACAAATGTTTATAGCATCATTATAACATC +ATAAATAGCCAAAAATGGAAACAACCCAAATGTCTACCAGCTGATGAATGGATAAACAGA +ATGTAGAATATCCATACAATGAATATCATGTGGCCACACGAAGCAATGAAGGGCTGATAC +ATGCTACAACATGGATGAAGCTAAAAACATTACATAAATGAAGCAGTCACAAAGGATGAC +ATGTTGCATTTTTATAAAATGTCCAGAGAATACGAAGATCTATAGAGATAGTGTATTAGT +TTCCCATGGCTGCCATAACAAGTTACCATAAAGTTGGAGGCTCCTATCTCTGGGTCCATG +GCTCTGACTTCTGAGCCCATGTCTCTGCCCTCACTTTCTTAAAGGGTAGCACATGTTTGA +GGCTGCGTAGTTTTATCAGCCTATTCCTGCTTCTAAAATTTTGGGAGTTCTTCTTTGATT +TTGCCTAGTCTATAAACTTTCTACTCCAAGCTGGCAGTGTTTCTGCTGGTAGAACATTCT +CAAAATCCTTGTGGAACTTCTACATATATGATGGAATTCATAGTATTAGATGAGGTTTCT +CCACAGATCTTTCCTAGATAATTTCATCTCTCTTCCTCACTTCTGTGAGATGATTGAGGG +GATTCATGAGTCCCATGTTTAATCTCTTTGGCACTAGAAAAATTTGGAAGATATGCCACA +CCCTTGGCATTCTCTACAGAACACACTTTCCTAACAGTAAATCTCCTAGTTTTAGCATTT +TGGTTTTTTCCAATCTAAATAGCCTGAGAATTTCCCAAATCATTAAGTCTAGATTCCTTT +CTGCTTAACAGTTCTTCCCTCAATTTCTCTCTCTTCTTTGTGTGTGTGTGTGTGTGTGTG +TGTGTGTGTGTGTGTGTGTATTTTTAAAATTCTTTTTATTGTACCCTTAATTTATCTCTT +TCATGTTGCTTTTTTTTTTTTTTTTTTTTTTTTTTGGAGACGGAGTCTCACTCTCTCGCC +CAGGCTGGAGTGCAGTGGCGTGATCTCAGGTCATTGCAACCTCCGCCTCCTGGGTTCAGG +TGATTATCCTGCCTCAGCCTCCCAAGTGGCTGGGATTATAGGTGCCCACCACCACACCCA +GCTAATTTTTGTATTTTTAGTAGAGACAGGGTTTCACCATGTTGGCCAGGCTGGTCTTGA +GCTCCTGACCTCAAGTGATCTGCCTGCCTTGGCCTCCCAAAGTGCTGGGATTATAGACGT +GAGCCACCATGCCCGGCCTCCTCTTGCATTTTACTACAAGCAGAAAGAAGAAACCAAGCT +GAGTCCTTTTTTTTATTTTTTTGAGACTGAGTCTCACTCTGTCGCCCAGGCTGGAGTGCA +GTAGCGCGATCTCGGCTCATTGCAACCCCCACCTCCCAGGTTCAAGTGATTCTCCTGCCT +CAGCCTCCCAAGTAGCTGGGATTACAGGTGCCCACCACCACGCCCGGCTAATTTTTGTAT +TTTTAGTAAAGATGGGATTTCACCATGTTGGCCAGGCTGGTCTTGAACTCCTGACCTCAG +GTGATCTGCCTGCCTCAGCCTCCCAAAGTGCTGGGATTATAGGCATGAGTCACTGTGCCC +GGCCCAAGCTGAGTCTTGAATGCTTTGATTGGAAGTCTGCTCAGCTAAATGTGCAAACTT +ATTGCTTATGATTCTGCCTTCCACACAGCTACAGGACACAATCCAGCTAAACTTTTTGCC +ATTATATTACAAAGATCACCTTTGCTCTAGTTTCCAGTAACATGTTCCTTGTTTCCTTTG +TTTCTTTAGAATCACCTTTAATTTTCATGTTTCTAACAACATTCTGTTTTTGATAGTATA +TGTATTCTTGAAGATAATACAGACTTTCTGTATCAAGTTCGTCATTTCCTTTAAGGCAGA +GTCTGGGTGACAGTCTTTAACATCCGCATTTCTACCCACAGCCTGTTCAAGGAAACCTAG +GCCTTTTCTATCATGCTTCTCACAATTCTACTAGCCCTCCTTTGTTATTGAGTTACAAAG +CCACTGCCATATTTTTAGGCACCCTACTCCTGGTAACAAAATTCGTATGTTTCCTGTGGC +TGCTATAACACGTTACTACAAGCTTGGTGGCTTAAAAGAACAGAAATTTAGGCCGGGTGC +GGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCTGAGGCGGGCAGATCACAAGATC +AGGAGATCGCAACCATCCTGGCTAACATGGTGAAACCCCCGTCTCTACTAAAAATACAAA +ACAACTAGCCAGGCGTGGTGGCGGGCGCCTGGAGTCCCAGCTACTCGGGAGGCTGAGGCA +GGAGAATGGCTGAACCCGGGAGGTGGAGCTTGCAGTGAGCCGAGATCGCGGCACTGCACA +CCAGCCTGGGTGACAGAGTGAGACTCTGTCTCAAAAAAACAAACAAACAAACAAATTTAA +TCTCACAGTTTTCAAGGCCAGATGTTCAAAGTCAGTACCATGGGTAAAAATCGCAGTGGC +AGCAGGGAGGCTATAGGAGAGGAACCTGTTTCTTGCATCTTTTAGCTTTTGGTCACTGCT +GGTACTCCTTGGCTTGTGGCTGTATCACTCCAGTCTTCAAGTCCAGCATCACGAGGTAAA +TACATTCTCTGTATTCCATCTTCACGTCGCCTTCTCTGTGTGTGTGAACTTTCCTTCTGC +CTCCCTCTTAGGAGGATACATGCAATTGCACTTGGGGTCCACCCGCATAACCCAGGATAG +CCCTCCATCTCAAGATGTTTAACTTCATCATATCTGCAAAGACCTTTTTCTCAAATAAGG +TAACATTTACAGGTTCCAGGGAATAGGACCTGATTTAAGGACTGTTATTTAGCCTGCCAC +AGACAGAAAGTTGATTATTGATTGCCAAGGGTGCTGTAGGGAAATGGAGTTTTCATTTGG +AGTGAAGATGATGTTCTAAAATTAGGCCAGGCACGGTGGCCCATGCCTGTAATCCCAACA +CTTTGGAGGCCAAGGCCAGTGGATCACTTGAGGCCAAGAGTTTGAGACCAGCCTGGCCAA +CATGGTGAAATCCTGCCTCTACTAAAAATACAAAAATCAGTAGGGGGTGACAGCGCATAC +CTGTAGTCCCAGCTACTTGGGAGGGTGAGGCAGGAGAATCACTTGAACCCAGGAAGTGGA +GGTTGCAGTGAGCTGAGATGGTGCCACTTCAGCCTGTGTGACAGAGCGAGACTCCACCTC +AAAAAAAAAAAAAAAAAAAAGAAACAAAATGCTTTAAAATTGATTTTGGTAATGCTGCAG +AACTCTGAATGTAGTACCAAAAACCATTGAATGGCATGTTTTAAATGGGTGAATTGTATC +TCAGCCAGCCTATTACATATATTTTTAATGGAACGAGTGAAAATGATGAATAACAGGTCT +GTTTTCCCTTGGTGGCCAGGTCAGGGCCGTGTGGTTTCCTTGGGTGGGGGGCACTGCTGG +GGCTGCCTTGTCCCTACTTGGTTTCTGATGGTGTGTCCTGTGGGCTGGGGCCAAGGTCCC +ATGGGGCTATGGATACTATCATGGAACCACTCTTTCTGGAATTTGATGGTATTTCAAAAT +CTATTAGGAAAACTCTGAGACATGAAAGCACAGAGGCGTCATATTCCTCTAATCTGGAGT +CAGCAGTTGCTGTGGTTTGGTGACTTTTCCCTTGGCTGTCTCTGTGTCCCTCCTGAAGTG +TCGAGGGCACATCCCCACCCTCAGGGTTGTATCTCTGCTGAGCATCTCCACACTGGCCTG +TGCTAGGGCCCCACCTGACAATCACATGGAGTCACTATTGTCATCAATGGGAAGGCCTCT +TTCAAGTTTCAACGCTTTTTTCCTAATAGTTGGCTTCTTTGAATCAGGATCCAAACGAGG +GTCTTTTCTCCCCTCTGGCCCCTCCCAGCCTGGTGAAGGAGCAGCCCAGCTGTCCTGCAG +CCCTCCCCATGGGCTCTGATGTCTCCCAAGCTGCTGATTCATCCTGCCTGCCCCCTCCTT +CTTATGAACTGGGTGCTAAATCGGAGAGCAGAGAGGGTGCCGTGGTCTTTTAGCAAAAAT +ATATCCGAAGTATTGCCTTAATTTGTATTTCTGGGCATCTTGATATTCCCATAAGACCAC +AATTTGGAGGTTTGGAGAGCAACAACAGCCTGACCCTTGTAAAGCTCCTATTATCTTTCC +GATGGTTTCATCATTTAATTAGGGCTTGTAGACTAATTCTGGCTTTTCTCCCACATTCGT +TACATGGAGTTTTTTTTGTTTTTTTTTTTTTGTCAAGAAAGGTTTTCTTTCGTCAGCCAG +GGCTAGATGATTGTTTGAAACCCTGTGTGTTCAGGACCTCCAGGAATGCTGTTTTTCTGA +TCTTTCCAGTCTAAGGAGTCCCCCCAAGGGCCACAGATGGGTTCTCTTTGAGTGACATTT +TGAGCTCAGGGCTGTGTATCTGGGGTGTTCTGGTCCATTGCTGTCATTCATTTTGATGCT +TAGATGGTCCCATCCTCATCTAGCAGGAGCTCCTGTGTCTCTTGGGGCCCTCACACAACC +TCTTTAGTTTTTCTTAGTCTGCTGGCATTTAGACCCAGATTGGCTGCTCCTCTAGGGAGT +GAACCCTGGGGACTTCTGCCGGTAAAGTGGCATTTGGAGCATGCTACGTGGGCGCTGGTC +TGTTCATTGCTTTGGGCCTTTCAGTGAACAGAACTAAGAAAAAACATGTTTTTGAAATAA +CAGCAACAACAAAAACCCATAATTTTACACTAATATTTCTAATTCAAATTTAAACTTATA +TATAGGGTTTTTACTTCTTTCATTTTAAACATGTGTCTTTTCTGTTACTATGAATATCTT +GGTTTCTAATATTATTAGCATACTTGGTTGCTTTACTTTAAAATCATTTCAGAATAAACA +GTTTATATTACCACTGATAACAAAAGGTAGACTAAACATTTAAGATTACCTTGAAGTTCT +AATTGTCCTTAAAATGTATCCCTTTTATTGAGAACATTTTGCTTTTTGTTTCATTTTTTT +AAAAAGCCTCTCAAAAGATTTCTTTTCTCTATATGATTCTGCCACCAACTTAATATTCAG +CTCATTTGTTTTAGTTTATTTGGAATGTTTAGGAATTGGACCTTTTTCTTTAGATTTGCT +ATACTTTTCATTTTAGAAAAATATTTTAGGCTGGCTACAGTGACTCACACCTGTAATCCC +AACACTTTTGGAGGTTGGGGACTGAGCAAAAGACAAGCCGGCCAACATGGCAAAACCGTG +TCTCTCCAAAAAATACAAAAAATTGGCCAGGCGTGGTGGCTCACGCTTGTAATGTCAGCA +CTTTGGGAGGCTGAGGTGGGCGGATCAGAAGGTCAGGAGATCGAGACCATCCTGGCTAAC +ACAGTGAAACCCCGTCTCCACTAAAAAATACAAAAAATTAGCCAGACGTGGTGGCAGGCG +CCTGTAGTGCCAGCTACTTGGGAGGCTGAGGCAGGAGAATAGCTTGCACCACCCGGGAGG +CGGAGCTTGCAGTGAACTGAGATTGCACCACTGCACTCCAGCTTGGGCCACAGAGTGAGA +CTCCATCTAAAAAATAAAAATAAATAAATAAATAAATTAGCTGGACATGGTACTGCATGC +ATGTAGTCCCAGCTGCTCAGGAGGCTGAGGTGGGGAGGCTCACTTGAGCCCAGGAAGTTG +AAACTGCAGTGAGCGATGATCGCGTCACTGCACTCCAGCCAGGGCGACAGAGTGAGACCC +CATCTCAAAAAATATATATATTTTTTAGAGAAATAAAATTCACTGAGTTGCCCCTGAGTT +GCCCAGGCTGAACTCCTGGGTGTAAGCAATACTCCTACTTTATCCTTCCAAGTAGCTGGG +ATTACAAGACTGTGCCACTGTGCCTAGCTTTGATTTGTTTTTTTTGTTTTTTGTTTTTTG +TTTTGAGACAGAGTTTTCACTCTTGTTGCCCAGGCTGGAGTGCAGTGGCGTGATCGCGGC +TCACTGCAACCTCTGCCTCCTGGGTTCAAGCAATTCTCCTGCCTCAGCCTCCCAAGTAGC +TGGGATTACCGGCATGCGCCACCAGGCCTGGCTAATTTTTTTTGTATTTTTAGTAGAGAT +GGAGTTTCACCATGTTGGCCAGGCTGGTCTTGAATTCCTGTCCTCAGGTGATCCTCCTGT +CTTGGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCAAGGTGCCCGACTTGATTTGGC +TTTATCTTCTCAATAGTAAAAGATTTATGTGCTTCTGAAGTGAAAACCCATAACACTGTG +GATTTAGAGAGGGCACATTTCCAGCCCAGTTCCTGATACTTGCTGGGTTGTCGATTTTCA +ATTTTGGTGTATCTTTCCAGTGTTTCTCATGGCAGATTTAAGCAAATATGTGTGTTTACG +TTCCACAGGTCTTATATAAAAGGTGTATGTCATGCAGTGTATGTGGCACGGAGCACGTGT +TTCTATCCTTTCTCCTTCCTTGTGTTCACTCCACAATATGTTGTGAGGCACTTGTGCAAG +ATTTCCACATGTCAAGCAAGTGTGGAAATTCTATGAAGCTTTTAACTTTTTGAGGTGGGG +TCTCACTCTGTCGCCCAAGCTGGAGTGCAGTGGAGTGGTCACAGCTCATTGCAGCATTGA +TCTCCCAGGCTCAAGCCTCAGCCTCCCACTTTGAGGCCACTGGCGTGTGCTACCACACCA +GGGTAATGTTTGTTTGTTTGTTTGTTTTGTAGAGATGGTGTCTTACTATGTTGCCCAGGC +TGGTCTTAAACTCCTGGCCTCAAGGGACCCTCCTGCCTTGGCTTCCCAAAATGTTGGAAT +AATAGATGTGAGCCTCCACGATTGGCCTCTATGGAGTTTTTTAAGGTTTCTGTTTTCTTA +TCTGTAAACTGGATGTGTTAGTAGTACCTGCCTCTGGGTGGTTGGGAGAAATCAAGGCGA +TAATGCATGTGAATTGATGACTCCTGTGTCTGGCACTGTAAAGTGCCAAGTGCTAGCTGT +TACTGTCATGATGTTCATTGTTTATGGTTTGTAATACTCAGCCTCAGGTACAGCTGGACA +CTTATATTTTGATAGCCAGCAGGGGAGCTGGAGCAGACCAAGTGAAGATAGGGAGTTTCC +TGACTCTTTAGCCCTTTTTTCTGCAGCAGTTCTAGGGGAGTTGGTGTGCTTTGGAGCAGA +AAGGGGCATAATAATCTGTCCATCTGGATGGGGGTGGGGGTGGATGGTGAGGAGTCAGGA +GTGAAAGAGCCCAGCCAGGGGGATCAGAGGCGCAGTTTCAGATCCAGGGCTTTCTCCCCT +GGAAAGGAGTTGTTGTGGTTGACCCATTGCGTTCAGCCCCTAGATGTTCCTAGATAAACC +TGCCTTTGGGGGAATGTAGGAAGTATCATCGCCCACAAGAAAGCTCCTTGGCTGGCAGCA +TGACAGCTTCCTGTGCTTGTTTCTCACATCAGGCGTCCCCTCCCTCCCCGCTCCCCACTA +AGCCTCCTCACGCTGGTCTGGTAGCAGAGCTGGAGCAGATGGCAGTGGCTGCGCCTACTG +TGGGTCAGGAGTGGTGCTGGGCACTGCAGGATGATGATGCCTGCCCACTGCATTCCAGGT +GCTGGGCTGGCAGTGGGTCTTGCTCAGCCCTGGTGTTATGCAGAAGGGCTTTGGTGACAT +GGTCCTGAGCCTTGTTTGAGTGTCTTATGTCTAAGTAAAAGTATCTTGTTGCTTTTGAAA +CCTACTTCCCCTTGTTTTACCTTTTATGGATGTGGAGAAAACAAATTCATTTAAAGTATC +GCAGACCTAAAAAATGGTCCAGGGCCTTAGGAGCTGTGAGGTGTTGACCTGGCTGGCCCC +CAGGCCCTTCTCCCCTCATACATGGCCACCTTGCTTCTGTTCCTGAGTGTCCTCAGGTTC +CCACACCTCCATTGCCCCCATTCTCATACCACTGTCCTTCAGGGACAGGCTGCCTGTGGG +CCCCCTTCACACGCACATCAGCTTTCCTATCAGTAATTGATGGGGATAGCCGGAAGCTGG +GCGTGTTGACAGAACTGCCTTGGTGTCCCCTTGTTCTGGCCAGGCCTCGCTGCTTATCCC +AGCTTTTCCTCTCCCCTGGGCCTTTCTTCTTCATGTTGTCCTGTGCTAATTCCCCGAGCT +GAAAAAAAGAAGTGGGGTAGAGTTTGGAGATAGATGTGGGATGATAAAGATTTCAAAAGT +GTCTTTGTATTTTTACACTCATCTGAGACCACTTTTCATCATCCTTCCCTCTGCCCTGCC +ATCTTATGAGTGTAGTGGATGGACTCTGAGTGTCACAGTGACTCAGGAGGAAGGTTGGGT +GAGCAGGGCACGGAGCCGGGGCTTTGCCCCTTCCAGGCTGCCCTGCCAGAAGGATGGGCA +CTTCAGCAGAAGACAAGGATGCTTCTCTGAAATAAGACTTTACCTCAGACATCCGTGTAT +TGACCACAAGACCAACTCACAGTAGTGATTTCCCTGAAACACTTGGGAGTGAGTGTCCTT +GGGGCCAAAGAGGACAATGGGTGGGAGGCAGCCCCTGCCAGACAATCTCAGAAACACAGC +AGCTTGCATATAGCGGGCCTTGGCAGCCAGTGGCCTTCACCTCACCTGAGAGTGGGCTTC +ACCCTCTGCCTTGCCTGTGCGTAAATGGAGATGAACACAGATTCTCCCGGAAAGCGCAGC +CAGGGGAGGGCCGCCCAGATTTTCAGCAGATACTGCGTCATCAGTGAAAAGGCAGCAACA +GGCTGGGCTGAGAAATGAAAGCCCTTCTTTACAGATAGTGCAAAGACACAGCGGCCCACC +CACGGCTGCCTCTGACAGGCCTTGTGCCCTCAGGCCAGCGCCTCATCACCCCCAACCTGC +CTGTCCCCTTTGTGATGAAGAGAGGGCACTCAAGATGGCTCCCAGCTCTCTCAGCTGAGT +GCCTTTCCATCAGGGGAGAGGAGTGGCCGTTGGAGGCTCTCTGTCCCCTTCTTGTTTCTT +TGTGCCTGTTATTGGCCAGCCTAGCTGAGCACTGACGGCTCTCTTCCGAGAGGCGGATTC +CAGAGGAGGCCGAGCAAGCGTCTGAATCTGCCTTGCAGGATGGGCTTCAGCTCGGTGCCA +GCAGGCGAGGGGGCGGGAAGGGGGAGTCCGATGACTGCGCTTCTTCATCTGGTATTAAAC +TGCTTCCTGTTTTTACTTTTAGGACGAATACCTTTCTCTCGTGGCCAGGCTCATTATCCA +TTTTCGAGACATTCGTAAGTAAGATTTTGCATTTCTGGGTTGTTGAGATCTCTGTGAGAG +GCCAGCCCTGACGCTGCCTCGGCAGAGCTTTCTGGGCAGGCCGTGGTGCCTGAGTCAGAA +GGTCTGTGTCACCTCACTTGCTTCTGGGAAGTTCTTCACTGCCTTGCATTTGACTCCAGA +TCCCTCCATCCTCCCAGAGCCTTGGCCTCAAAAATGCTGATTCTAGCATCATGGAAATGC +TGTCCTCAAAGTGGTCTAAACGGGTTGCTGCTTCACTTGCTCACTTAATCTCCCTTTTCA +TAGGGCTGTTGTTTTTACTTCTGGGAAGTTCTGTTTACCCTGGAACAGAAACTCTCTTCC +CTAAAAGTTGATTTTATTGACCCATGGAGGCCAGAGACACTTAGGCATATTTTCCCTCCA +GACTAGAAGCTTCTGAGGAGGACCTCCTGAGTCTGCACCCTGGCTCCCTGCTGTGCTGAG +GGCCCCCGTGTTAACCTCACGTTGTGCCTCCTCTGATTCAGAGGGCCCAGTGTGGTTCTG +TCAGCCAGGCAGTGGCCCCAGCTCTACAGAAATGAGTTGTCATTGCATCCTAGGGCCAGG +GTCTTCGTGCTTGTGTGTGTTACGTGGAAGTATGTGGACACCAAGTGTTCCTGGATGGCC +ACAGCCTGCGAAGGAAACTGGGGCCAGCAGCTGCTCTGTGTTTTCAGCCAACAATGGCTC +CTGCCCACTGCCGCTGCATAACCACCAGAGGCAGGCTTCTCTTGACACAGGCCTGTCGTT +GGAGCATGTGCCTGGCGAGTCCTATTTCTATTCCCCTGTGGGTTAGGGACAGGCAGCTGT +ACCTTCAGTGTGTTGCTGGGTCAAAGGGAGACATTGAGCACTCCAGAGCCTGGTAGGTTT +TGCTTCTTTCCACACTAACTTTTCACCAGAATGGCCAGCAAAGTGAACTTCACTGATCTC +ACTCTCTGTGGTGTTGGAAAGTCACTGGGATGTGTAAGAGGAGAAGGAGCAGCCCAGATG +ATCTGGCCCAGATGCGCTGGCAGACTCCGCATGTTCTGCTTTCAGGGACAGTGGCCTGGC +TGGTGCACACAGTCCTGTGGGGCTCATGAGGTCATGGGAAGCAGCCGAGCAGGAGGCTCA +GGGCCCCATGACTGCTACAGAAGTTCTCCGCTGGGCACTGGGGTCAGCTGGACTGGCTTC +CAGCTGGCCGTGGACAGCCTCAGTTTCCTCATCTAGGTAACAGAGACACTGCCTCACCAG +AGTGGGCTGCAAAGGGAGGCAGTGTCAAGTCTTGGCACCACTCCAGCCCCGCCGTGGGTT +CCTGTAGTGTTCTATTATTTGTTTGCTCAGGGCTGAGCTGAGACTCTGGACCTGGGAAAA +AGGAAAGCCAGAGTAGGCCCAGGGTCCCCAACCCCAGAGTGCTTCAGCCTTGGGGGCAGC +TCCCTAAGGCCCCAGGTTGACCCTGGAGCTACTCTGCACCCTCTGCCCCCAGGTCTCTTG +TGGGGTCAGCGCTGCCAAGAGTAGAAACACTTCCCCCAGTAGTGGGGAGTACTAGGAGCT +CCGTGGGGATTAAGGCTTGGGCAAATGCCTACAGAACTGACCTACCCATGGAAATATGTG +GTTATATAAAACTATGTTTACTTTCGTTTTTTTGTTTGTGTTTTCATATAGATAACAAGA +AATCTCAAGCTTCCGTCAGTGGTAAGAGTTTTCCCTTTTGAGTTAAAGTTTCTCCCAACT +TTGGATTTGAGGTGGCAAGAATGACATAGTGCATGCCTCATGTGCCTGGGTTAACCTGTC +ACTAGAGGAGAATGCTTGCGGAGAGAACTCTGGAGGGAGGAGGCTGACCAGCTGTGCCCT +GACCTCTCCAGCCTTCGTCTTCCTGCAGACTGTGAAGTCGCATGATCCTCCCCATCCCGT +TTCACACAAATGCTGCCTTTGCCCAGCAAAAAGATAAACACTCACAAAGCTATTAAGACA +TTATCCAAAAGTGTTGAGCTCTCTGGTAGAGAATTATTATGCTGTTTTCAGTGTAATAAT +ATGTAGTAGCATTTCTGAGAAAATGCTGTGAATTCACTTTTTTAAGTTACAAAGTTTCTT +TGTAAATTTAGAAATCTGGCTGGGTGCTGTGGCTCATGCCTGTAATCCCAACACTGTGGG +AGGCTGAGGCAGGCAGATCAGTTGAGGTCAGGAGTTCAAGACCAGCCTGGCCAACATGGT +AAAACCCCATCTCTACTAAAAATACAAAAATAGCCGGGTGTGGTGGCATGCGTTGTAGTC +CCAACTACTCAGGAGGCTGAGGCATGAGAATCGCTTGAACCTGGGAGGCTGAGGTTGCAG +TGAGTTGAGATCGTGCCACTGCACTCCAACCTGGATGACTGAGTGAGACTCCATCTCAAA +AAAAAAGTTTAGAAATCCATATTTTTAAATTTCAGCGTTTATCACATGAGGGGAATTCTG +TCAATTCAGCCTTGGTCTCTGCTGACTAAGCTGCAAGGGAAGGGGTTTAACAGATCCAGG +CTGGCCAACTGCATTCTGCCATTGGGAAGGGAGTGCACTGACCTCACAGGCTGCACGCCA +CTGTCTGCCCTGCCCTAGACAGTAGAGCTGTACATGCCAGCTGTCTCTGCCCATGTGGGT +CTCACCTCTCAGCCAGGACAGGGATTCTTGGCCAACTGGGGCTGAGCGGCAGCAAGGGCA +TGTGGCCAGAACATCTGGGCCCCTTGGCATTGGAGCATGGGGTCCTGGGTACCACCCAGT +TGTGTGGCATGGCGGTCCTGCCAGGACATACCTGTCTGTGGGTAGCTGTTTGCTGTGAAG +TCCACACTGTTGTGACAATGGCATCCTTGTCCTTGGTTGTGGCATTGCTCACTGAGCTGC +TGACCTGGTGGGCTTGGGACATTTCTCCTCAGTGCTCTGTGGAGCCCTCCTCTGCACCCC +TAAGCTGTTCTGGCATGGTGGCCCTGCACACAGGGGCCCAGGCTGAGTTGGACTCTGCAA +CAGCACGAGTGGAGCTGTGTGTGCCTGTGGACTTGTGCCCTCCCTGGGAGAGCGTCCCCT +GGCCACTGTGTTACCGCTTGCTCAGAAGGGCCCATCGTGCTTTGTACGCTCACCCAGCAG +GAGGGCTGGACAGCCAGGAGAGGCAGGGGTTGCCACCTGCCCTCAAGGCCTCAGCCCATC +TTTAGTGTATCTGCAGGCATCAGAGAGGTCATTTGTCCCTTAACATTAGGACTCTGGTCC +AGGCCAGGCTAGAGGTATGGGTCATGCAGTGACCAACACACCTGGCGTCCTAGCCATTCA +TATTTGGGAGTCTCCAGGAGCCTAGTCTCTTACTGCTTGGGGCTGTGAGGGGATTGAGCC +TGTAGGTAGGCGAGATCTGTGCTCTGTGAGCCTTACGCCCTTTGAGCCATGGTCAGTCTG +GTAGGCCCTTTCCTGAGAAGCTCTGCCCTTGTGTTCCCACAGATCCTATGAATGCACTCC +AGAGCCTGACTGGCGGACCTGCTGCGGGAGCCGCTGGAATTGGCATGCCTCCTCGGGGCC +CGGGACAGTCTCTGGGCGGGATGGGTAGCCTTGGTGCCATGGGACAGCCAATGTCTCTCT +CAGGGCAGCCGCCTCCTGGGACCTCGGGGATGGCCCCTCACAGCATGGCTGTCGTGTCTA +CGGCAACTCCACAGAGTGAGTACCACACTTCTTGGAGGATTTGCCGCTTTCCTTGCAAAC +GACAACACATTTTATTCCTGTGCTTATGATGGTATCAAGAAAAGCATGGAGAAGCTCCAA +ATCGCTCTGGTTTTTTTGTTTTTTAAATCTTTGTTGTATGTGGAGAGAAAAGGCTTCCAA +TTTTCGTTGAGCTCCCAGAAGGGTTAAGTGATGCTGGGCCCTCCTCCTCCTCCTAGCCCT +GGGCAGGAGGGTGGGGATGGCCTGAGACTCCATCCAAAGGTTTGTGTTTTGTGGCTGAAA +TAGATACAGTGTGTTTCAGAGGGTTCTCAGCTACAAGGCAGGGCTGAGTGCCAGCAACCA +CAACTCCACTGTCTGCCCGAGCTCTGGGCACCATCTCTTCTAGTGCTGCCCTTGCCCCTT +GGTCACCATGGGTGTGGCTTGCAGCCATATTATCTTCTGGCTTCCTTTCTGTGAAGGAGA +CTCTGTGTCCTCTCCACACGGCTGCTGTGGTGGGAAACTGGGCTGTGATCAGGTGTTATA +GGTGAACCAAAGCTGCTCTAAAGGGGAGGCAAAGAACCTCCCTCTTCTTTCCAGGACCTG +TCTTTTGAGACGGGGTCTCGCTCTGTGGGCCACATTGGAGTGCAGTGGCACAATCACGGC +TCACTGCAGCCTGGACATCCTGGGCTCAGGTGATCCTCACACCACAGCCTCCAAAGTAGC +TGGGACTATAGGCTCACAGCACCGCGCCCGGCTAATATTTTGTATTTTTTGTAGAGATGG +GACTTCACCATGTTGCCCAGGCTTATCTTGAACTCCTGGGCTCAAGCGATCTGCTCACCT +CGGCCTCCCAAAGTGTTGGGATTACAGGCGTGAGCCAACGCGCCTGCCCTTAGGACCTAT +CTTGATGTATCCTTGAGTCCCATCAACATTTCTTAGAGTGTGCTGTGCCCACTGCAAAGT +GCTTTAGTGTTTTTTTCCCCTTTCATGTAACTTTTTATTTTTAAAATAGGAGTCACAGGA +AGTTGTGGAATAGCATAGAGAGTTCCCACATGCCCTTTACCCAGCTCTCCCCAATAATAG +TATCTTACATAGAACATTGTCAAAACCAAGAAATTAATGTTGAGGCAGTGTAATCACCTC +AGTTAGAGACTTAGCTTGGACTTCATCAGTTTTTTTTTTTTTTTTGAGACAGAGTTTCAC +TCTTGTTGCCCAGGCTGGAGTGCAGTGGTGTGATCTCAGCTCACTGCAACTTCTGCCTTC +CGAGTTCAAGCAGTTCTCTTGCCTCAGCCTCCGACTACCTGGGACTACAGGCGCCTGCCA +CCATGCCCAGCTAATTTTATATTTTTAGTGGAGATGGGGTTTCACCATGTTGGCCAGGCT +GGTCTCAAACTCCTGACCTCAAGTGATCTTCTCTCCTGAGCCTCCCAAAGTGCTGGGATT +ACAGACGTGAGCCATCACGCCCAGCCGACTTCATCAGTTTTTTTACACTCATTCTTGGGC +TACATATATGGGTATGTGTAGGTCTGTGAGATTTTACCACGTGTCAAATCAAGTAGCCAT +CACCACAATTGGCATGCGGAGCCGTTCCATTACCACCAACCAACTCTCTTGTGTTACCTC +TCAGAGATCGCGCCCTCCCTCCAGCCTTAAGCAGTGACAATTGCTGATCTGTTGTGTGTC +TCTGTAGTTCTGTCCCTTTGTGAATGTTGTATAAATGGAATCATACCATATGTGACTTTT +TGAGATTGGCTTTTTAAATTCAATCTGATACCCTTGAGACCCAGCCAGGTTTTATCAGTA +ATTCATTCCTTTTCATCACTAAGTAGTGTTCCATGGAACGGATTTTCCACAGTTTGCTTA +TTCATTCACCCATGAAGGACATTTGGGTTGTTTCCTGCTTTTGCTTACTATTATGCAAAC +AAAGCTGCTGTGGATATCTGTGTACAGGCTTCAGTGCTTCAATATATTTTTGTCACACAT +CCCTCATGATAACCCTATGAAGAGGGCAGCATCGCCCCCTCTGCTTTGTCAGTGTAGCAG +CTGCTAAGGAGAACTGGAGTCACACCCCAGGCCAAGAGCTGGGATCGAAGCTGCTGCCTG +ACCCCATCCTCACACTCCTACCCTATCCTGTGTCAGGTTTCCTCTTCTTTGGGGCCATAG +GCATCCTCATTTCTACCCACTCCTGCTCTGGAATCTTCCTCCATCCCAAGCCACCTTCCC +TTCTCATACCTTAATTCTCCTCTTACTTCCTGTTGTCTAACTCTCAGCACGTGCTGGTTT +CCTCATCCTAGAACAATCTGCCTGGTTCTTCGTCCCAAGCTCTCATTACCTCACTATTTT +TAGCACATCAGATAAGTACACCAGCTGGGTTTAGGGAGGACCCACAGAAGTGCCGGCTCA +AGTTCCTTGTCACGTTCTACTCTTGTGTACTTGGTGCATTTTTTTTTTAATCATGAGCTT +ATACTTGATAATAAATTGTTTTTAAATGTATGAGTTTAGAATGCTCACATGAGTTGCCTT +GTCATCCCACTTCAGAGACTTTGTCTTAAACCAGTTCTTTGTCAGAAGTTCAGTGGTGAA +GCTTGATATCCTGCCCACGCCCTCCCCAGTCTGGCCTTGGCCCCCACATCCTGTTTTTAG +CTTCCAAGGGGACTGGTCTTCTGTGTGGCACTAGTTGAAAGTTACAGTGGGGGCTGGGCA +CGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCTGAGGCGGGCGGATCACGAGGT +CAGGAGATCGAGACCATCCTGGCTAACACGGTGAGACCCCGTCTCTACTAAAAATACAAA +AAATTAGCCGGGCGTAGTGGTGGGTGCCTGTAGTCCCAGCTACTCGGGAGACTAAGGCAG +GAGAATGGCATGAACCTGGGAGGCGGAGCTTGCAGGGGGCGAGATCGTGCCACTGCACTC +CAGCCTGGGCAACAGAGCGAGACTCTGTCTCAAAAGAAAAAAGAAAAAGTTACAGTGGAT +TCTCTACTTCAGGATCTTGTTACCACCTTTGTCAGAGGCCAACTCTCCCTGCCCTTCACC +ACTTGCCTCCCTGGTCTCCCTGAAACTAGTAGTGTTGTCTGATGGGCATTTGATACCCCT +TCCTGACACCTTTCCCAAAGACTACTGCATGATTAAGGCCCTTTCAGATCTTCATCTAGT +GCCACCAAGAGGACAGAGCCTGGGTCAGAGGTTTTGCCAGGGACTCTCAAAGGGTAGGCC +AGGGGACATTGTGATAGTTTTCAGGTGACCCAGGTTAGTCGGAAAAGGCTGAAACTGCTG +GTTGTTCCTATGGCTGGGGCTGCAGTACAGAGTTGGAAGCAAAGCTTTTCACTCTGCGCA +TTTTTGTTTCTCATGAGTTTTATATGACGTGCATGTAAAGCCGACTTTAAAAATAATTTC +TACTGCCAGTTGTGTGATGGACTGGGGTGCTGAGGACATGTTCTCCTCCTGGATAACTAG +GTTCTGGTTAGGATGCACTTTGGAATGCTGGCCTGCAGCAGTTGGGGAGGCTTTGTCCTC +CTGAGCCTCAGCTGCTGCAAGGTGGGGGAAGAAAGCTTGGGATTCCTGTAGTCAGCCAGG +ATTTGTGCTGGGTCCTGTGTCACCCCCCATACCCCCCAGAAGCAGGTGCAGATTGGAGCA +GGTGCGGATTGGAGGAACATGTCCCCAGTGTAAGACCTGTGACAGTTGCACATTAAGGTC +AAGCAATCAGCATACAAAGATCACCAGCCTTGAAGGGAAGGAGAGACACCATGAAGGTGA +ACAGAAAAAATAGACACATGTAGGCATGCCCAGTGACCACACACACAGGAACTGTTAGTT +ATGGGCCATGGGGTATATAAAGAAATAAAGTGGAGAGCCGGGCACAGTGGCTCACGACTA +CACTCCTGGCTACTCGGGAGGCTAAGGCAGGGGGATTGCTTGAGGCCAGGAGTTTGAGGC +TATGGTGAACTATCATTGCACCACTGCACTCCAGCCTGGGGGATAGAACGAGACACCATC +TCTGAAAAAATAGAAAACAAAAAGGAAAAGAAAGAGCAGAAATTCAAATGAAAAAGCATC +ATCAGGAGCAATGAAGCAGATTTGAAACGGAACCAAATGAAAGCTGTAGAAATGAGCAAT +ATAATTATTGAACGAAGAAAGTGGATGAATGAACAGCGCATTAGATACAGCTGAAGAAAG +AATTTGTGTAATAGAAGCTACATTTGAAGAAATTATCTAGAATGTAGCACAGAGAAGAGC +ACATGGAAAATGTGAAAGCAAGGGTAAGAAATGAGGATAAGATCAGAAATTCTAATTGGC +ATCCAAGCAAAGCCCCGGAAGGATCAAATGGAGAGAATGGAAGAAAACAATATGTGAGGG +GATAACTACTGAGAAAAGCCCATCTGGCCCCAACCAAGTTAGCCATCTCATCTGCTGTGA +GACTGCAGAGCACCAAAGGCCAGAGGAATGTCTTAGAAATAGGCAGTTCCTGCAAAGGAG +CAATGAGTACACTCAGCAGTAGAGTCAGAAAGGTAATAGAATATTGTTAAAGCATTGAGA +ATAGAGCTGCCAGTCACATTTGTATGCCAGCAAGACTCAAGGATGTGGAAAGCAAGCCAT +TTTTAGATAAACCTAGCCTTAGAGACCATCACTAAAAGATTTTCTAAAGGATATATCTTT +TTTTATCCTTTTTCCAATAAGCCTTTTGCACTCTTAGATATATTCTTTTGTTTATCCTTT +CCTCTTCCCTCTCAGGTGATACAAGGTAAAATGGGAAAAGAAACGTTGAGCATAGGTGAT +AGTAAATGTGTATAAATCTAAAGCAGTGATTCTCACCCAGGGTGACATTCCACCACAGGG +GATATTTGACAATGTCTGGAGACATTTTGGGATGTCACTACTGTGGGGGTGCTGCTGGTG +CGTAATGGGTGGAGACCAGAGGTGCTGCTAACCATCTTACAAATACAGGTCAGTCCCCCC +AACAACATAGAATCATCTGGGTCAAGTGTCAGTAGTGAAAAGGTTGAAAATCGCTGGTGT +AAATAAAAATTTACCTCTGTAAAATAAAACAGTCAGGCTAACCTCCATACAGACTTGCCA +CATTCCAAGCACTATTTCATTTCTTTTCTATTATTATTATTATTATTATTAAGATGGAAT +CTCGCTCTGTCAACAGGCTGGAGTGCAGTGGTGCAATGTCGGCCCACTGCAACCTCGACC +TCCCAGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCAAGTAGCTGGGACTACAGGCGCGC +GCCACTACGCCCAGCTAATTTTTGTATCTTTAGTAGAGACGGGGTTTCACCATGTTGGCC +AGGATGTTCTCGATCTCCAGACCTTGTGATCTGCCCTCCTTGGCCTCCCAAAGTGCTGGG +ATTACAGGCATGAGCCTCCGCGCCTGGCCTATTATTATTATTTATAGAGCTAGGGTCTCC +TTATGTTGCCCAGGCTGGTCTTGAATTGCTGGGCTCAGGCGATCTGCTCTGCCTTGGCTA +TCCAAAGTGTGAGATTACGGGCATGAGCCACAGCACCCAACCCCAGGGACTATTTTGAGT +GTTTTACTTACATAATAGATTATTTAATTCTTAGTCCAGTGTGTGGAGTAGGTACTATTA +TTGCATTTTCTAACAGGGAAAACTAAGGCAATGAGCAGTGACAGAGTTGAGGTTTTGAGT +CCAGGCAGCCTAGCTTGGAGGCTGTATCCCTAGCCTCAAATCCATCCAGCCTCTTAATAG +AATGTCTGCTGTGAAGAGTTAAAATAGATCAACAAAATATGAAATAAATGCAAGTCAGCA +GGGAGATAGAGCGTGAATATCGGTTCTGTCGGGTACATATAAAACCTACTTTAAAAAGTA +GTAAATTTGGGAAATGCTAAAATATTGATGAGGTTTATACTTTAAGTTAAATATGCATGA +TAAAATTGAAAAATTATTGCTAAAACAATGGAAATAATTCATAAAATTTAAGATCAATAG +AAAAAATAGGATAAGGCAGAAATCCAGATAATACAAAGTTCAATCCAATCATCCAACAAA +AATGCAATCAAAAAAGACAAAGAAGCTTAGAAAAGGAAAGACAAAGGCCGGGCGCGGTGG +CTCAGGCCTGTAATCGCAGCACTTTGGGAGGCTCAGTCAGGCAGATCACGAGGTCAGGAG +ATTGAGGCGATCCTGGCCAACATGGTGAAACGCCGTCTCTCCTAAAAATACAAAAAGTTA +GCTGGGCATGGTGGCGCATGCCTGTAATCCCAGCTACTTGGGAGGCTGAGGCAGGAGAAT +CGCTAGAACCCGGGAGGCGGAGGTTGCAGTGAACCGAGATCACGCCACTGCACTCCAGTC +TGGCGACAGAGTGAGATTCCATCTCAAAAAAAAAAAGGAAAGGAAAGACAAATATTAATA +GAAAATAAGTTTAAAAATATAAGTAATCATAATAAATGTGAGTGGACTAAACTTTTCTGC +TGAAAGATAGGAAATGTGAGAACAAATGGAAATGAAACAGCACAGTTGTTTTATTGTTAG +AAGAAACACACACCTACAATAAAACATGCGGAAGGATTTAAAAATAAAAGATGAAGAAAG +GCCAAGTGCAGTGGCTCACGTCTGTAATCCCAGCACTTGGAGAAGCTGAGGTGGGAGGAT +CACTTGAGCCCAGGAGTTCAAGACCAACCTCGGCAAAATAGGAGACCCCCATCTCTACAT +AAAATTTAAAAATTACCTGTAGGTACACTTGAGATGCTGAGGTAAGAGGATCACTTGAGC +CCAGGAGGTCAAGGCTGCAGTGAGCCATGATTGCACTATTGCATTCCAGCCTGGGCTGCA +GTGAGACCCAATCTCAATCAATCAGTCAATAAAATTAGCTGAGTGTGGTGGTACACACCT +GTAGTCCCATCTACTTGTGAGGCTGAGGTGAGAGGATCGCTTGCTTGAGCCTGGAACGCT +GAGTCTGCAATGAGCCACGATGGAGACACTGCATTCCAGCCTGGGTGACAGAGCAAAATC +CCGTCTCAAAAAAGAAACAAACAAAAAAAAGGATGAAGAAAGATGTATTGGGCAATTACT +TCAATTACATCTCTTTGTTATTGATAAACAGACCAAAAAATTCATTTACAGAAAATTTGA +ACAATGTAATGAACAACTTAATTTAAGCATATGATGGAACAATATGTTTATAAAAATAAA +TCATAAAGCAAGCTTCAACAATTTCAGAAAATTTAAAAGTATTGTCATACTTTTTGTTGT +TGTTGTTTTGAGACAGAGTCTCACTCTGTCACCCAGGCTGGAGTGCAGTGGCGCGATCTC +GGCTCACTGCAACCTCTGCCTCCCGGGTTCAAGCAATTCTCCTGCCTCAGCCTCCTGAGT +AGCTGGGATTACAGGCACGTGCCACCATGCCCGCTAATTTTTGTATTTTTAGTAGAGATG +GGTTTTTGCCATGTTGGCCAAGCTGGTCTCAAACTCGACCTCAAGTGATCCTCCTGCCTG +AGCCTCCCGAAGTGCTGGGATTAGAGGTGAGAACCACCGCGACCCGCCGGTCATACATGT +TTTATGAATGTCAAATAAAGTTAGAAATCTGTCACAAAATAAATTAAAAATTTTTTACAC +TTGGCCAGGCACAGTGACCCACGCCTATAATCTCAACACTTTGTGAGGTCGAGGCAGGAG +GATCACTTGAACCCAGGAGTTTGAGATCAGCCTGGGCAACAAAGTGAGACTGTCTCTATA +AAAATTTTACAAATTAGTTGGGTGTGGTGGCATGCACCTGTAGTTCCAGCTACTCGGGAG +GCTGAGGCAGGAGGGTCACTTAAGCCCAGGAGGTCAAGGGTGCAGTGAGCCACGATGGTA +CCACTTCAGTCCAGACTGGGCAACAGAGTGAGACCCCACCTCAAAAAAAAAAAATCTTAC +ACCCATCAGAATTGCTAAAATGAATAGTGACAGCCTCAAGTGTTGGTGACAGAGAAACTG +AATCACTCATATATTGCTGGTGAGAATGTAAAGTGGTTTTACCTTCTTTCAAAATGAAAT +ATGCAACTCAGCAGTTACACTCTTGGGTATTTTTCCTAGAGAAATGAAAACCTCGCATAA +AAACCCATGCACGAATTTTAACAGCAGCTTTATTTGTGGTAGCCCAAATCTACAGTTACC +CAAATGTCCTTCATGTAGACGGTTAAACACACTGTGAGGTGCTTGTACCATGGAATACCC +TGGCAGTACTGTTGCTAGAACTACAACCTGTATGCTGAATGTAAAAAGCCGATCCCAAAA +AGGTTCATACTGTATGGTTCCATTTTTGAAATATTATGTATAATTTTGAAATGACAAAAT +TTTAGAAATGGAGGATGCTGCAGTGGTTGCCAGAGTTTGCGGGTCAGGGTTGCTGAGAGA +GGTGGCAACACGAGGGATCCTTGTGGTGTGGGGACTGTGTAGTGTATTGACTGGTGGTGA +CTGAACCCACCCAGGTGGTTAAATTGTCCAGAACTTAGTACACACACCCACACAAGTGAG +CACACATCGTGGTTGTGATACCTTGTAAGTTTGTAGAATGTTACCATTGGAGGAAACTGG +GCAAAGTATACAAAGGATCTCTCTATATTTCTTTAATACAGCTTTATTGAGACATAATTC +TCATTAGCATACAATTCACCCATCTGAAGTGCTCCACTCGGTAGGTTTTAGTGTAATCCA +CAGAGTTGTGCAGCCATCAGCACAATTTTAGAACATTTTTATGTTCACCCCAAAAGAAAC +CTCACCTCAGAAAATCTTGTAATTGACTGTTCATATAAGCAGTTTTCATAATAGCCACAA +AGTAGAAGCAGCGCAAATGTTCATCACAGGAAATCGGTGTAGTAGAATATTATTTGGCGA +TAAAAATAACACAGAAAAACTGATAACATGCCACGACATGGGCGAACTCGTAAATATTAT +GCTAAAGAAGCTAGTCACAAAAGAGCACATGTTCGATGCCATTCGTACAAAGAGTCCGGA +AGTGGCCAATCCATAGAGACAGAGAGGAGATTACTGATTGCCAGAGTCTAGGCTTCTTAT +TTATCCAAAAGACTTAGTTGTCCCTTTTCTTTTGTCTTTGGTTATTATAGAGTAACTCAT +GATAGGAAATCCCAAAATCAACACAAATGCTACTTCGTATTCTATCTTTCTGTCTGTGGT +AAATGGAACGTTCAGATTCCAGCGGCAGCCGTGGCAGTGGGGCTTTTGCTGGCTGTTTTG +TCCCTTGCTGTGCAGCCCTGCAGCGTTTCTGGGAATCTGCCCTGTGGACTGACTGGCGAC +TCTGGTCTTTTCTCAGCCCAGCTGCAGCTCCAGCAGGTGGCGCTGCAGCAGCAGCAGCAA +CAGCAGCAGTTCCAGCAGCAGCAGCAGGCGGCGCTACAGCAGCAGCAGCAGCAGCAGCAA +CAGCAGCAGTTCCAGGCTCAGCAGAGTGCCATGCAGCAGCAGTTCCAAGCAGTAGTGCAG +CAGCAGCAGCAGCTCCAGCAGCAGCAGCAGCAGCAGCAGCATCTAATTAAATTGCATCAT +CAAAATCAGCAACAGGTACCAGGTCCCCTGTTCCTGCTCTTGGCCTCCCTCCTGCAGCGT +GAGCCCTGGGCTGGCATCAGCCACAATGCTGGGTGCAGTGCCCGGAGCCAGCCGAGGGTT +CTCTTGACACGTGTGCCTGCCCTTTTCCATGGGCTTCTCAAAAAGTCTGGGACAAGGCCG +GGCCCAGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCAAGGCAGGCGGATCATC +AGGAGTTCAAGACCAGCCTGGCCAGCATGGTGAAACCCCATCTCTACTAAAAATACAAAA +AATTAGCTGGACATGGTGGCGTACACCTATAATCCCAGCTATTTGAGAGGCTGAGGCAGG +AGAATCGCTAGAACCTGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCGCTGCGCTC +CAGCCTGGGCAGCAGTGAGACTCCGTCTCAAAAAAAATAAAAATAAAAAAGGAAAACAAA +AGTCTGGGACAGGCAGGAGAAACAGGCCCTGACTCACTAGGAAGGTTCTGTGATCGAGCC +CTTCCATTTGGGCTTGGGCATCTGGCGGTGGGCCTCCTGTGTAGTTCAGGGGCTGCGAGG +GATTCAAACAAGAGTGAGCTGAAGCAAGAAGTGAGACGAACACTCTGAGGCTTGGGACTA +CTTGAGCCATTGTGGGCCATTTTGGCTGAGGACACATGTGCCTCCTGTTTACCTCTGTGT +CTTGGGTTCTGGGCTCAGTGTTAGTCGACCTCCAGCTGGTGTTGCATGAGGTGATGGTGA +TGTCATGTTAGCAGCACTGCTTCTCAGAAGTTGTTCAGCTTCCCATGGTTTCCATAGAGA +GTCTAGACGTGTTAAACATCTGCCCTCACAGCAGGTCTTGGTTGGGAGAGGAAAGCCCCA +AAGGGCCCCACCACCCTCCCACCCCTTCAGGCCTCAGCTAGCTGGGCTTCTCTGGATCTT +GGCACCCCTCTCCCAGAGCTGACAGTGCATCTGCAGCCACACTTTTCCTTCTCCTGCTGA +CAAGCAGACCTTGACCGTCACCGTGAGGCTCATGCCACTGACCTATAGGGGCAAAGCAAG +CATCGTTGCAGAGGCTTCAGAAATCTGCAGTTGCCCCAGCTTTTATCCTAGCTTCCATGG +AGCTGTACCTATTCCTTGTCATCTTTTGCTGAAGTTTCTAGGTATGCCCTTTGAACCATC +CTAGTGGAATGGTAGACCAGAGCCCAGGCACACACTTGGTGCCTCCCCGGTGTCAGGAAG +GCAGCTGGTGTTGGCCTCGGGGGGCCCAGAGCCTTTCTGTGGGAGATGTGCCCCTCCCCG +TGTGAGTGAGAGGTCAGCCTGTCAGCCCAGGAAGGCCTTTTTTTTTTTTTTTTTTTTGAG +ACTTTTTTTTGCCTCTTACTCTGTTGCCCAGGCTGGAGTGCAGTGGTGTGATCTCGGCTC +ACTGCAACCTCTGCCCCACCAGTTTAAGTGATTCTCCTGCCTCAGCCTCCCAAGTAGCTG +GGATTACAGGTGTGAGCCACCATGCCTGGCTAATTTTTGTATTATTAGTAGAGACGGGGT +TTCGCCAGGTTGTCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCTGCCCGCCTCGG +CCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACTGCACCCAGCCAGGAAGGCTTTCTT +GATGGCTCTGCAGATGGCCACCTGGGCTTCCTGAGGCCCAGACTGTCACAGGGAGGAGCT +GGTGCCACAGAGGCAGATGAGTGATAACCGAGTGCTGCTTGTTCTGTCTCTAGATACAGC +AGCAGCAACAGCAGCTGCAGCGAATAGCACAGCTGCAGCTCCAACAACAGCAACAGCAGC +AGCAGCAGCAGCAGCAGCAGCAGCAGCAGGCTTTGCAGGCCCAGCCACCAATTCAGCAGC +CACCGATGCAGCAGCCACAGCCTCCGCCCTCCCAGGCTCTGCCCCAGCAGCTGCAGCAGA +TGCATCACACACAGCACCACCAGCCGCCACCACAGCCCCAGCAGCCTCCAGTTGCTCAGA +ACCAACCATCACAACTCCCGCCACAGTCGCAGACCCAGCCTTTGGTGTCACAGGCGCAAG +CTCTCCCTGGACAAATGTTGTATACCCAACCACCACTGAAATTTGTGAGTACCTGTGGCC +CACAGTGGAGCACATGCAGCCCGTGGCTCTGTCAGCAGTAGTTTCTAGGCTCTTTGGCTA +GAGATAGCATATCCTATTCTTCAAGTGCTGAGACTTCAGGCAGCCCCCACCCCTTGCCAG +CCCTGCCGACTCTAGCATGGCTCAGCAGGGAAGCATGTGTTTTGCATTTTGTGTTCTGAG +AGCTGCTTCTGCACCCCGCACAGGGTACTGCTGCTGCTACTGGGGCACCAAGTCGCATTC +CAAGCAGTGTGGCTGATTGCAGCAGTTCTGTGGGCCCTTTCAGGGTGTGAGCACTTCGAC +TGATGAGCACCACATGAAAGGATGTGCCAGCTCCGTCAGTGTCTGGTGGTTTGCCAACTA +CTCAGAGTTAATGTTCTAAGCAAATATCTTTTTTTTTCCTTTACACTCTGCCAAGTCTCA +GGAGAACAAAGTTCATTACTATATTTTTGAGAGGAGTATTAATATAAAATACTGTTATTC +CTAGTTTCATTTTGTATCTCTGCACAAAGCCAGTCTACTCAGTGACAGGCACAGAGGACA +GAGTATGATCACCAGGATGAAGGTAGCTGCATCAAGGGGCCATTTGGACAACTCTTTGGC +TCCCTTGGTTTTTGTGGCCTTTTCTGTTTGTGATTCATGAGTGGAATGGGGCCTGAGGCA +AGTGTGGGGGTGAACAAGAGGCCTCATAGGCAGACTGGAAGTCTAGGAGAGTTGTGAGGA +GCAGATATGCTCACTCATCTGTCACCTGGGAGTCGACACACTGCCTGACCCCGGGGACTG +TGCAGACTGAAACCCTTGTGTGCTGCATGGTGGAATGTGCCCTGGCAGGGTTTGCCCTAG +TGGCTTGGAGATGTCTAAGGAAGAGCCCGCTGCATGTTGGAATGTGCCCTGGCAGGGTTT +GCCCTGGTGACTTGGAGATGTCTAAGGAAGAGCCCCCTGCATGGTGGCGCGGGCCTGTCT +CGTCCTTCTGGAGGCCCCTCCATGCAGTGGCTCCACAGTTGCCCCTTTTGCCCAAGTTTG +CCCCCCACCCCCACTTTTTTCTTTTGAAGACAGGGTCTCTGTTTTCCAGGCTGGAGTGCA +CTGATGTGATCAGACCTCCCTGCTCAAGCGATTCTCCCACCTCAGCCTCCCAAGTAGCTG +GGGCTGCAGGTGTGCATCCCCACACCTAGCCAAATTTTTGTATATTTTGTAGATATGGGG +TTTGGCCGTGTTGCCCAGGCTAGTCTTGATCTCCTGGGCTTAAGCGATCCACTGGCCTTG +GCCTCCCAGAATGCTGAGAATACAGACAGGAGCTACTACGCCCTGCCCTCTGCTGGCCGG +CTAACCCAGCTTTCCTTCAAGGAATCAGGCTGAGTGAAGCTCTTGTGGACCATCAGCATG +CTTGGCCCAGAGGATGAGCAGGCTAGGCTGTAAGCTCTGCATTGGAAGTCGTCAGTGCTT +GTGATAGCTGGTGCTGAGGGATGTGTGGAGACATCCCAGTGGGAGGGCCACATTGCCACT +TGCCAGAATTGGATTTGAGCTAATGGGATCCTAGATGGCCAGTAAGGTGACATCACAGCA +CATGAGGTCATGAAAGTCCCATTCCTCACCTCAAGAAAGGCTCCATTTCCTAAGCTTCCA +CAGGAAGACTAGGCTCTGCTCTCTGACCCAGGTGGTTCCAAATCACATTCTCTCTTTCTC +CCTCAAGGTCCGAGCTCCGATGGTGGTGCAGCAGCCCCCAGTGCAGCCCCAGGTGCAGCA +GCAGCAGACAGCAGTACAGACAGCTCAGGCTGCCCAGATGGTGGCTCCCGGAGTCCAGGT +GAGGGCCTGGGGGTGGAGGGCTCCATAGTCATCAGCAGGTGCATGTTCACCTGCGCATGT +AGTGCTACAGTGAGGGTTCTGGTTGGATTAGGGGCTGGGGGCTAAGTTGGTAAAGCAGGG +GCTTCTCTCCCCCTTGCACTCTGCAAGACACCCCTGGAGTCCTTGGGGTGGGCAGCTGTG +CTTGGTCATGTCTAGGACCCACCAGCCGCATAGTGCGTGTCGTTTCCAGCTTTGCTCGGG +CATCCTTCATTATCCCTCTTCCTTGCCACTCTGAGTGACTCTGGGAACATGTATCAGAGA +GTAGAAGGCTGCAGTTTTCTCCTCACCTCTCATCTTCCATTTGAGAGTCTGAGTACAGAG +CTGACCAGGGTGGAGGGCAGCTTTCTAGACACTCGGAAGCAGATGGGAGCCACATGCAGC +AGGAGCGTGGGAGAAGGCATCCTGGTGCTCGCCTGCACTCAGGGACTCCGGCGCTGTGTG +GTGAGAAGCGTGCCACTCCCACATTGCTGAGCTTGCTGGTGTGTCACATGTGTGGAATGT +GTGTGTGTCTCTGTGTGTCACGTGTTAGTGGAATGCAGATGGCCTTGTCTGGCCTCCTAG +TGTCCTGGGATTGGAGGCCCAGGGTTTCTGTACCTTTTCCTATAACCCCTCCTCTCCTTC +TTGTGGGGAGACGTACAGTCTGGGGCTTCAGTTTTTCCTCTTTTCACATGATGGTGGAAA +CACTGTTGGTCCTGACTCGGAAGGGGCGTTGGCTTTAGAAAGAGTCAGAATGTGCTAGTT +GATGTGGTAAGACTGTGGCTGGGTCCCAGCCCACAGCTGGCAGTGCGCCTGCACTTTGCT +GTCGTCTTAAGGGTACCTGGCCTTGTGGTTTTCTGCAGGCCTGCTGGGCGCAGCGCCTGG +GTGCACAGTGCCTCGTGGCAGGCTTCATCTCACGCTTGGGGGGTGCTCAGTAATGTCCTT +CATGGTGCCTGCTACCTCTTTTAAGTCCCTGGGAAGCTGCCTGAGGAGGGAATCTGAGGT +ATTTGGCTGCAGCTGAGGTTAGCATCCTACCTTGGCAGGGCACCAAATGACTTGGGGCCA +GGGTCCCCATGTCACATTCTTACTTAGATGGAGCCCTGTATGAAACACACCACAGAACTC +ACATTTACTTACAGCTGGGGGAGGCTGACCACTTCGTGTGATGAGGTTGGAGGTCTCTGC +CACCTCCCTGTGTGTCTCGGCATGTCCTCAGGCCTCGTGGGGGGGCTCCCTTGTCCTGGT +CTCATGCAGAGGAAGGACGTGGTGTGTTCAGAGTCAGCTTAGTGGTGGCACATAGTGACT +GCCCACCCAGTGGAAGCTGCTACCTTTGCCTCTTTGGACCATCGATCCTCTGTTCAGGAC +CTCACTTCCTGGAAACTTTTTTTATTTTTTGAGATGGAGTCTTGCTCTGTTGCCAGGCTG +GAGTACAGTGGCACGATCTTGGCTCACTGCAACCTCTGCCTCCTGGGTTCAAGTGATTCT +CCTGCCTCAGGTTCCCGAGTAGCTGGAACTACAGGCGCGTGCCATCACACCTGGCTAATT +TTTGTATTTTTAGTAGAGACATGGTTTCATCATGTTGGCCAGGATGGTCTCCATCTCTTG +ACCTCGTGATCTGCCGGCCTTGGCCTCCCAAAGTGCTGAGATTACAGGCATGAGCCAATG +CGCCCGGCTGGAAACTTCTGTACCGCAGGTCAAGCCCAGCAGGAAAGTGAGAACTGCTCT +TTTCTTTATTTCTTTCTGTCTTTTTTTTTTTTTTTTGAGACAGAGTCTGACTCTGTCATC +CAGGCTGGATTGCAGTTTTGCGATCTCGGCTCACTGCAACTTCTGCCTCCTGGGTTCAGG +CGATTCTTGTGCCTCAGCCTCCCAAGTAGCTGGGACTACAGTTGCACACCACCACACCTG +GCTAATTTTTGTATTTTTAGTAGAGATAGGGTTTCACCATGTTGGCCAGGCTGGTTCGAA +CTCCTGACCTCAAGTGATTCACCCGCCTCAGCCTCCCAAAGTGCTGGGATTATAGGCATG +AGCCATCGCACCCAGCCTAGAACTTCTCTTCTCTTCTCTTTTTTCTCTTTTCTTTTCTTT +CTTTCTTTCTTTCTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGACAGAGTCTTGCTCTC +TCACCTAGGCTAGAGTGGCTGGAGTGCAGTGGTGCAATCTTGGCTCACTGCAACCTCTGT +CTCCCAGGTTCAAGTGATTGTCCTGCCTTTGCTCCCAAGTAGCTGGGACTACAGGCATGC +GCCACTATATCCAGCTAATTTTTTTTTCCTCTTGTATTTTTAGTAGAGATGGGCCAGGCT +GGTCTTAAGCTCCTGACTTCAAGTGATCCACCTGCCTCAGCCTCCCTAAGTGTTGGGATT +ACAGGCGTGAGCCACTGTGCCCAGCCGAACTTTCCTTTTCTTTCCATTTCTTGGTATTTG +GAAAGTGAATAGCCATGGAGCAGCCAGTGTTTTCAGCTGGTGCAGGCCCAGCTGGTATGT +TCGTTAGGCTTCTAGCTCAAGGAAGTGTCCACTCTGCAGTCTCACTGGCATCCCATCACC +GTCCAGAAGCAGGATGCCAGCTGTGTGTGCTCATGGCCCATGCTGAGCCTGTCCTTGGGC +CACTGGTCTTCCTGTCGGTTTCTCCACCCCTTGTTTCAGGTGGAGGTCCCCGCCCGACTG +GCACAGGAAGGAGGATGGAGAGTGGTTACCACTGTGGTTCGTTGCTGAGTGAGTTTGATG +TTTTAAGGATCATTGCCCACCTGCCCTGTGGCACCATGTGCTGCCATGCAGGGGATTCCC +AAGTGCTAGTGGCAGAGGAGCCTTGTAGTTTCTCAAAGTCCAGCAGTGGGTAGGGCGTAT +CTATGAGGTGCTTCTCAGTCCAGATGTGGCACCTTGAAATTCTGTAACCCGCATTCTGCT +GGTTTTCTCTCAGAGCTTGGTCTTGCCTTGTTGCAAGCAGTGCAGTTTCTTGGGGGCTAA +TTGGGCACCCTCACTGCCTTGTTCCACCAATAGCAGCGCCCCCTGCTGGGGGATGGGGAG +GGTTGGGCACAGCAAGCCCTCTGAGGGGCCATCTGGATTCATGATCTTCTTTTGAAACTT +GAATTGGCACAGTGACCAGCTGAGGCTACGGTACTCTGATCTAAAAACTTTAAAAGTATG +TGTGGTAACTGTAGAACCCAGAAAGTGGAGAGGAACAGAAGTAAGAGAACCATTCCATGA +GAGAGAAGGTCTGGTGTCCTTTCTGGTTGTTTCCCATAGTCAAGGTCATGCTATCCTGGG +GTTTTTTGTGCAGCATCTTCCACATCAATAGGGGATGAAATGTTCTCCTTTAATTAGAAA +GCCCTGGTCGGCACGAAGGAACTCTTGTCATACCCCTCTGTGAATGTCTCTTGCCATCCT +CAGTTACCATCTTGTTCTTGGACCTTGTAATAATTTCCGATTTTTTGCTATTACCAGTGA +CACATATCTTGATGTCTTAGATTGTTCCTGGAGCTGATGGAGGTGAGTGAATGGTTCACT +TTGAGGGCCTTCAGATCTGATCAGCCACCCTCTAACCAGGAGGTCAGAGATGCAGATTGG +AGCTCCCCTTGTGTTGTTCACACAGTGGACATCAGGACGTGGTGACCACGTGTTGCAGCT +TTGTATGTATGAGCTGCCGCGTGCTGCGGAAACAGGCCTCTTGAGTTCATGAATGAAATT +CTGGGATTGGGGGCCCCCATGCAGGCAGCCCTCCATGCCCTGTCTCTCAAGCCCATCTTA +GAGCCGAAGAGAGGCGCCCTGTCAGGCCCTTGCAGTACTGTGGTGTTGGATGTGGTAAAG +GGTAGCCTGGGACTGAGTATTCTAGAAAAATTGCTCAGCCTTGTGCTGTGCACACCTGGT +TCTCTTTCCAGTGTTATTTATGTAGCTGAGAAGGGCAATGTCACCCACAAGGGGATTTAG +CAGGACACAGCAGACTTCTTTTTCTCCCCTATAAAACCAAGACATGCAGGCACAGTGGCT +CATGCCTGTAATCCCAACGTTTTGGGAAGCCAAGGTGAGAGGATCACTTGAGACCAGGAG +TTCAAAACTATCCTGGGCAACACAGCGAGACCCTGTCTCTACAAAAAAATAAAAATAAAA +AGTTAGCTGGGCGGAGTGGTGCGTGTCTGCAGTCCCTGCTACTCGGGAGGCCGAGTTGGG +AGGATCGTGCAAGCCCAGGGGTTTGAGGCTGCAGTGAGCTGTGATGACAGCATTACACTC +TAGCCTGGGAGACAGAGCAAAACTCTTGTCTCTTTAAAAAAGCAAGAAACAGGACAGAAT +GCATCTCATTTTCTTTTTTTTTTTTTTTTTAAAGACAGAGTCTCTTGCTCTGTCACCCAG +GCTGGAGTGCAATGGTACAGTCTCAGCTCACTGCAGTCTCCACCTCCTGGGTTCAAGGGA +TTCTCCTGCCTCAGCCTCCCAAGTACCTGGGATTACAGGCATGTGCCACCATGCCTGGCT +AATTTTGTATTTTTAGTAGAGACGGGGTTTTGTCATGTTGGCCAGGCTGGTCTTGAACTC +CTCGCCTTAAGAGATGTGCCCGCTTTGGCCTCCCAAAGTGCTGGAATTACAGGCGTAAGC +CACTGTGCCTGGCCATGCATCTCATTTTCAAACAGTCCCTATACCTTTGTCATTTAACGT +TCTATTCTTTTAGTATGTGAAAACCAAACTCTAATTTACAAGTCACAAAGAATTATCCAA +GACAGACTCCCATTGTGGACATGTATGTGGCATTGCTGATTCACAGCTACTGTACTGAAG +CCTTGGCCACCCTGGAGGACCCTCTCTCTTTTTGCTGGACCCTTCTGCACAGTGACTGCA +GTAGGGAGAGTCAGACCTGGGGGTGGGGGAGAGGTTTTTTGGATTCCTCTCTGGGTAGAT +GTGTGTTGGGAAGTAGTGAAATGTTGATAGCTGCCTGGCTCATCTGATCCAGTAAACATA +ACTGGTGCGTTTGGGTTGAAAGAAATTGGGCTTTCCTTATCAGTTCTCAGTTATAAGAAC +ATCAGTCAGCAGTACATTAGACTTAAGCTTTGCATTCCTTGCGTTTTTTTGTTTGTTTTT +CTCTTCCTGGAAAAAAGTTTGCTTCTCTCATACCATCTGACTTACTTCCAGGCTTTTCTC +CCTTGTGGAACGAGTGCCGTTGAGCCCTGCTGCACTCTCAGACGGGCTCCTCCGAAGTGC +CGCAGGTGGTGGTAAATCGACTCTCACCCACTGGGGTCGCTCCTTCGTGTCTCCCCCCGG +TCGGTTCATCTGTTGCTCTGGCTGCAGGAGGAACGAGTGAGCTTCTGGTCGGCGTCTGCC +ATGCCGTGTCACCCCGGCTTCTGGCACCTCCTGTGCGTGCCCAGGATTGTGAATGTGGGC +CGTGTGTGTGAGGCCACGGGTCTCCCTGCAGCCACTCTCCTGCTGGAGCTCTGTTACTGG +CACCTGTCGCTGCCTGCACCGAAGGCTGGCAGCACCTCCTGGAGCTTGGGACCCAGAGCA +CAGCCTCCCACCATGAGATGTGTTGTTTTTCTGTGGATCAGTCCTCCTTTCTTTCTGAGC +CTGGCGTGTTTTGTTCTAGTTTGTTACCGTCCTAAGTGCCTGTAGGCCCTGCTCTCCAGG +GACGAGACTCGGGCTCTACCCCCAACTCAGAACCCAGAGCAAGAGTGGTCGGGCCCGGGC +CCACAACAGTGCTCAGCTGTCCTGCTGCCTTTGTAGTTCAAGAAGTGTCCATTGATGAGG +GGAATGGTCCTGGCTCATGCTGGAGTTCCTGACTCGCATCCCTGTGGAGATGAACTTCCT +CGTCAGGGCGGAGGCCTGCCAAGCAGTCCCCCCAGGCTTCTCTTGCTCACCTTTGCCCAT +TTTTATTACGAAAGAAAACCAGTTCCTTGATAGATACCAGGACCATCAGCCTCAGGCCTG +GAGGAGGAGAGGAGGATGATTTGGGTTCGGGCTGTAAGAGGTGTGCCACTGAGAAGGAGG +GATGCTGTGAGCAGGCTTAACTGAGCTCATGGTTCAGTGGGAGTTGAGTGTTCTCATCAC +AGGCTTTGGTGGAATGTACTCTTGACATCTGTCCCCAGGAGCCTGGTCTCCAGAAACACC +AGCTCAGGCCCTCAAGGTCTGGCTCTGATGGTTCTGTGGGCTATAGGATTCTGATCTGTT +AGCGAGGTGTGTTCAGAAGTGTGTTGAGGACACCAGTGCAGGAGAGCAACCAGTAGAACA +GAAAGGTCTGGAAGCAGCATTCTTGGCAAATCTTCTAGATTCCCAATGCCCAGACAGACC +TGGAGGTGCTGTGGGCTTGAACATGTGGGTGGCCTCCCCTCCCAGGCTGCCCCGAGCTGC +CCAAGCTTTCCTTGCCCTGGTGCTCCTTCTTGCAGAGGCTACACGTGCCCTCTCCACCTG +CCCAGGCACTGAGTTTCTTTGTTGCGATCACCTTGTCTGTTGTCCCTCTGTCCTCAAAGA +TGATCACGGAAGCCTTGGCCCAAGGTGGGATGCACATAAGAGCCCGGTTCCCGCCTACCA +CCGCTGTGTCCGCCATCCCGTCAAGCTCCATCCCTTTGGGCAGACAGCCCATGGCACAGG +TATTTACGGGGCAGCGCCCAGGGCACGGCTGGGAGCTCGGGGCGTCCTCTGAGCGCCTTT +GTAAAGCGCACCTGTCATTATCATCGCCGGTGACTTCTTTTATGGTGGCTTTCAGAGTGC +CAAACCCACAGTCCCTTTTTTTTTTTTTTTAAATGAAGCCAAGCCCAGCTTGTGCTTGTT +GAGAGGATATGAATAAATATCTGGGTCTTTTCAGCTTAAAATAGTTATACTGTACGCATT +TTCATGGTAAAAATAAAACAGCAGCTAAGCAAAAGTTTTGCTTTCTAGAGCTGTGCTATC +TAATAGTGTAGCCACTAAGCATGTGTGGCTGTTTACATTTAAATTGACTAAAATTAGGCC +GGGCACAGGGGCTTATGGCTATAATCTCAACACCTCAGGAGGCCGAGATGGGAGGATCAC +TTGAGGCCAGGAGTTTGAGACCAGCCTGGTTCACATAGCGACATACTATCTCCAATTAAT +TATATACATTTTTTAATGGAAAATATATATATAAATGTATATATATTTTAAAAACAAAAA +AAAAACCTAAAAGTCAACTAAAATTAAATAAAATGAAAAAATGCAGTTCTTCAGTCGCAC +CAAATAAATTTTAAGCCCTCATTTGCCCACAGGGAAGCTAGTGGCTGCTGCAGTGGACAG +CACAGACTCCAGAACGTGGCCAATGTGGCCAAAGTGGTATTGGGCCATGCTGTTGTAGAG +TTTGATGTGTAGAGTGTGTAATTTGTAACACAGATCCCCTTTCTAGGTAGAGGTAGACTT +CTGTGTACATTATGCTTTTCAGAGACAGGAATTCCCGGCTTCTTTTATTGTATGAAATTT +GGAATTACTCCATGGCATAGTCATTTTTTTAACAAATAGTTACCACATGCATTCTGTGTG +CCAGGCACTATGCTAAGATTCTGAGAATAAAATTATGCTGAAGTTCTCTCATCATACAGG +CTTTCCATTTTAGTGGGTTTGTCGTGAAAACATCAAATTTGCCAAAAGAACTTTACAATT +CAGTTTCTGTTTTAGGGGAAATGCCTCTATAATCCTAGCAGACAGTGGTCCCTGTCCATC +CCTGAACGCCCAGGTGCAGGCACTGCCACCACCCTGGCTTGTGCAGTGGCGTCTCTGCAG +CTCTGTTCTACACAGGAAGAAGTGGAGGCTGAGCCAGGATGGCCCTTGGTCCATGTGGCC +CCAAGCCTGGTGCCACACACCACACACTGCCAAGAAAGTGGCCTGGGCCCCCACTGGGGC +ATGTTTAGCTTTTGCCTTCCCTGCATACTAACCCCCTGGGTTACCCCAGATGTGCCATTC +ACATAGTTACTGACTGGAACTTAGTTTCTTTGGCAGGGACTTCCTTTTTAGTAGTTGTTG +AATTACAGCGGGAGGAAGTGCCTGGAATCTGCTGGTAGAAAGGCTTTGGTGAAAGAGCTC +TCCAGAGGAGCGGAAGTTGGGGGTCAGGAATTAGGTTGTGTGGCTGTGGTGGAAAGGAGG +CCAGTGTGGGCAGAAGCCAGGGTGCAGTTCCCCATGGCCTGGAGGCTGTGAGTTCCACGA +CCTGCTCACATGCTGCTGGTGTCTCCTTGACTAGACCCCTTTGGGTTCTGCACTCTTGTC +TGCTAAAACTGCTTCTCCTCCTTTCCCATAGCCTCTGGCACAGTATCCACTGGGTTCACA +GAATCAGGTTGGGTTGCTGTATGTGGAGGAATGACTTTAGTAGCAGCATGTAGGACTGAT +TTTTATAAACACAAAAAGTCCCCAATGTTTTCAGTGTGCGATATGTGCCAGGCCTTGAGC +TAAGCTCTTTGTGTACAGAGCCTCACTGTTTCTTGTTGTAGCAGGTCATAGTTTGAGCAT +TTAGCCCCTTTTACAGACTAAGAGTGCCCCCAGGGAGCCACCAAGTCAGGATCGAGGGCT +CAAGTGAAACCCTTATGCCTTGGCCTCTCAGCAGGATTCTTCTGGAAACTCCTCACTCCC +CTTCCTGCTGGGCTGATGACCTGGCTTCTCCTTCTTGTTTACTGGGCACTCCTGGGTGGG +CTCCCTCCATGCCCCCACAAGACCAGGCTCTGTCCTGGGCTTTGGCTTGCCCATACTCTG +TTGTGGGCTGGCCACTCCCCACACCCAGCTGCTGGTGTTTCCACCTAGACTTCTCACAGG +CAGCCCCTCCCTCCCTCCCTCCCTCCTTCCCACCAGTTCCCAAACCCACTCAGTCTTTCC +CTCCCCAGCCTTCCCTGGCCCTTAGATTAAGTCTGCCCTGAGTTATGCCAGCTAATAGGT +CTCTCTCTCTCTAGAAGCTTCCAACCCCCAAAGGCAAGGAGGTAAGGTGGAGCAGAGGAA +GGATAGAGAAATATATGATGAAGCTGAAAAAGTTATTGCCTTGGAATAAATGCCATGGAG +AATTCTGGTTTGTCCTCATTGCACTGTGTGGGGTGAGAGCGCTCTCATGGGAAGATGCTG +GCTAACTGCACACAGATTTAATCACCAGGCCCCGCCCATTCGCACTGGCAGTGAGAGGCA +CACCCCTGAACCTTTGGGGTTGTTCACTGAGGACAAACGCGGCAGCATTTAGAAAGTATT +CCTCGTCCCGGCAGTAGACAAAAGCCACAGGATTTATGGAAAGAGGAAGGAAGGCACAGA +ACTGGGGCAAGGTTCTGGTTTTGTTCTGTTATTTTGTTGTCATTGTTACTGTTTGTTTTT +CTTTTTTTGAGACAGAGTCTCGCACTTGTCCCCCAGGCAGGAGTGCAATGGCGCACTCCT +GGCTCACTGCAACCTCCACCTCCCAGCTTCAAGCGATTCTCCTGCCTCAGCCTCTCGAGT +AGCTGGGACTACAGGCGCCTGCCACCACATCTGGCTAATTTTTGTATTTTTAGTAGAGAT +GGGGTTTCACCATGTTGGCCAGGCTGGTCTTGAACTCCTAACCTTAGGTGATCCGCCCGC +CTCGGTCTCCAAAACTGTTGAGATTACAGGTGTGAACCACTGCGCCCAGCCTTGTACTGT +GTTTTTAAAGCAGGTTTGTTCATGCTTGTTAGCTGCAAGAAAGGAAACTGGAAGGAGTTG +AGGGAGGGAGAAAAGCGAATAGAGGGACACCCTGGAGTGGAAGCCTCCCTACTGCCCAGG +CAGCTGCTCTGCAGCCCTCTCTGGTCCTGGCCTTCCCCGCAGAGGGCCCTCCCCAGCTCA +GCCCTCTACGTCCGGCTGCAGTACCAGGCTCTTGGTACAGTCTCCCACACCTGGCTGTGG +GCCAGCCTTGGGGACGTGAGGCATGCTGGGCCCCGTGTACCAAGGGCATTCACCTGACCA +CACCAGGTGGCTCCAGAGGTGTGCCTCTGCTTTTGTGTCAGTATCTTTCAATCCAGTCCC +TTCCGAGAAAAAGAGAGCTTATCTCAGGAACGTATCTGTTGATCTCACCAGGAATTGCCC +CACTGTGTCCCATCTGAGCTCTCAGGGGCCAGAACCTGCTGTCTCCAGTGTGTCCAGATG +GCCACTCTGTGGCCACTGTCCCTCCAGCCACTTGCCCTCAGCAGTCAGCAGGACACAGTC +TGGAGACTACACTGCCCATTTGCTCTTGCTCTTTCCTTGTGGCAACAAATTAGGTCCAAG +AAAACAGGTGGAGCTGAAAGAGGGAATGTACGTGCCCCATGGGCTCTTCTCCAGAGGGCA +GGGCCCAGGCTCCCTCCCTCTGTCTTGACGGCTCATGGCTGCATCTTCCTGTTACGGTGG +GCATGCCTCACGGACTCAGGCTACCAGGTCAAGCAGGATTCTGTGCTGGGTGCATTCTGG +ACACAGTGCTCAGCACGGGGGCCCAGGGGGTGGCATGGCCCATGCCACAATCCTCCCTTG +GCAGATGTAAGCAGGCAGTGTCTTTCTCACTAGGGGCTTGTCCTTTGACTAGAGAGGCAC +TGTTGCCTCCCTGTTCCCTGCTCCAATCCCAGACCTGACATGAGACCAAGGACTGGGAGG +TTTCTTTCTCGCCTCTCTGGCTGCCTCCCCAGAGCCTAGAGCCTGTCTTTGGATGAGTCT +TTGCAGGGGCTGCTTCTCATCCCAGGTGCTGGACTTGGACTGCCCACCACTGACACCTGG +GCACAGGGCCTGGCTTCCTGCTCTCGTGCTCTTGGAAATGAATGGGTGCCCTTCATTTGT +TTTTCTTCCCACTAGAAATCTCCCTGCCTCCCATCCTCTGGGCTCTGCTGGCTGCCAGCT +GCCAGGGTGAGACCCGTGTTCCACTGCACCCTGGGGAGTGCCTCCAGGGGACACACTGAG +TGCCGGAGCCAGGAGCAAGGAACGGTTCCCAGTATGTGGGGGCGGGGGTGGGGATCGCGC +AGTGCCGCCAGCCTTGCCTGAGGGTTCCTCTGTGAGATGGAGCTCCCTGGACCAGCCTTT +TTGCCCTCCCACCTCCTCTCTGGCCCACTCGGTGTCCACCTGCCTTCAGCTCCAGGCTGC +TGTGTGGGTCCCTTTCCCAGAAATGCAGTTCAGGCCATTGTTGCTGGGGTGGTGGTGTTG +CTGGGGTGTTGATGTTTAGCGTGCCTGAGCTCCCTTCATCACTAGGATGACCTTGAGCAA +GTCACTTCCCTCTGAGCTCCCTGTTCCCAACCTGTGACACACAGGTGACAGGTGGTGTGC +ACTCAGAAACTCCTTCCCTAGGATGTGTGACATTCTTGTCCTGGGGCCTTTGCTAGCTGT +GACACACCGGCGCCCGACCTCTCTGGCTGCCTCCCTAATGCCAGTTGTGTCTTCAGATGA +GTCTTTGGGGGGCTGCTTCTCATCCCAGGTGCTGGACTTGGACTGTCCACCACTGACACC +TGGGCACAGGGCCTGGCTTTCTGCTCTTGTGCTCTTGGAAATGAAAGGGTGCCCCTCGTT +TGTTTTTCTTCCCACTAGAAATCTCCCTGTCTCCCATCCTGTAGGCTCTGCTGGCCACCA +GCTGCCCTGACCTGGGGCAGCTGAAGAACTGAGATAGACCTAAGTTCTGGGTGGGTGCTT +GGAGGCCCCACGGGCGTGGCTGGTGAGATTGCCGCTTCAGGGCCAAAGTGGGTGCCGGGC +TTCCTGAGGTTCGAGAGCAGATGAGAACTCTTGAGTGGCAATGAGGGCTGTGTGGTGGCC +TTCTCTGCTTGGCAGCCTCTGCCCAGCCTGCAGCTGCCTTGCTCCTCAGAGAAGCGCTGA +GCTTTAGGCCACAGAAAAGAGCTGACCATCTTCTAGAAGGGACAGCTGCTCAGGCACAGG +CGCCTCTCTGGAAGAGGCAGTCAGGTAGAGGCAAGGGGAGGGGCCCTGACCTTCAAGCAG +GAAGAGAGGTGAGCTTGTGAGACAGCTTTCTGGGGTGCAGGTAGAGAGTAGCAGCAAGTC +AAGCATGGGTCAGAAAAGGCAGAGTTGGGCTGAGCATGGGGCCCAGAGTCTTTGCTTCCC +ACTCCTCGGTGCCGTCTGTGGTTCTCTGTATGGAATTTTCTGGCCTTGGGATTTTGTTGA +CACCTGGATAAGTCTAGAACATGTGTTCCGGTGTCTGGGACATGCCCTTACTCCTCTTCA +GCTAGGGCTCTGTGCACCCCAGCACCGTGAATGCACAGGACTTTGGTGGGAGAAATCTCT +GTACTTGTTCAACTCAGCATTTAGCAAATGAAGTCACATCAGTCCCCGTTTCTGACCTTG +CTAACCTTTGCGAGAATCACCGCGAGCCATTTTGCTCCATTAGGTAGAGTGATGAGGCCC +GGCAGGCCGAGGCTGGGGCTCCTGCACTCTGTCCCTCCTCTCCCAGGCAGAGGTGTCTTG +ACCACAAAGCAGTGGGAACAGTCCATTCCATCGGTTGATGTCCCACTGGGCCAGTGGCTT +TGGATAGGGACCTCTGACCCAGCTGTGCTGGAAGTACCCTGTTGTGGTCACGCTCTGTGC +CTTAGCCCCCCACCCCCTGGTCTCCCAGCACACGTGGTTCAGGAACGGCCTGCACCCAGC +ATCCCTTGCAGCACTGTCAGGCACAGCCCATGGAACAGGCAGGACAGAAAGAGCATTTCG +CTCCAGGAGCTTGGTCCACGTGGTGCTGAAAGGGCAGTGCCACCCTGCCCTCTGCTGCCT +GGTGGGGTGGTGAGGAGGGCAGCATTCTGTTTGTGGGCTCTGGGCCTGGTCCCCAATTTA +AGGAGCTTAGAAAGCAGCTGTCCTATCCCAGTACTCACAGCACTGTGGTGGAAGTGCTTG +GGGGGTGGTGTGAGCCGTGGCCCGAGACAGGCGTTCATGGCCAGAGTGCCCCAGGAGAAG +CACTGAGTTGGTCTACAGAAATGGATGGTCCAGGGGCCTGGCTCCTAGGCAGACTGTGAG +GGGATGCTTGGCATGCAGGGGGTTGACTAGGGTGTGGGAAATGTAGCAGGGCCTTCAGGG +TTCCCCCAGTGTGACAAGGCATCCCTCTTTGCTGAGAGTCCCTCTAGGGGAGGCCAGACG +CCCAGGGCTGGCAGGCAGCTGTTCTCCCCATCAAAGCAGCCATCTGTGCTCCACCCCAGG +AAGGTGTGGGTGTTTTACATATGCTTATCCCTGATGCCTGGGTGGTGTGGTTTCATCCCT +AGAGTTTACGGATGAAGACAGTGGTGTCCCTGGTGCAGACACTGGGGTGATTGATCTTAT +TTGTGTCGTGGCCAGCAAGGCCTGGGGAGCAGAGCAACAGCCTTGCTTTGCATACACACA +GGGCCTCAGAGGACTCAGGTGCACACCTGCATGGCAGAACCAGGCTCTGGGCCCAGGTGT +CTGACACTGAGTAGCTCGCCTCTCCCAGGGGCGCTGGTGTGGGCCGATGCAAGTGCCACC +ATGGGTGTGTGTGTGGCTCCCTGGGCCACCTCACTCCAATTAAGCAGGTCCAGGTGGGAC +AGCCTGGGACCAGCCCTGCAGCAGCATGTGTTAACCACAACAGATGGCTGTAGCCACCAG +GCTTGTCCTTGGTGCAGTCAGCCTGGGGGCTGCGGGGGCTTGTGGAAGCATGTGGGAAGA +CGGTCCCACTGGTCAGCAGAGCAGGGTCCTCACCGACCCACAGAGGAGCATGTCACAGGA +CAGGCAGGCGTGTCAGGGAAGGCCAGGCTAGTGCCAGCCAAGGGCATTGCCTCCCAGACT +GCCCTTTTCCTCACACTCCCACGACACAGCCCTCAAAGCCTGTGCCCCTGTGGGTCCCTG +GCCAAGGAGCAAGGGCTGCCCTGCCTGGGCCCCCCCCGCCAGCCCCTTGGTCACCTCATG +CTGTGTGCCAGGCTGGGGGAGTGTGCCTGTGTGTATGTCCAGGTGGCATTTGGATGAAGA +CACAGGTGTGTGGTGAGGCTGTGCGGGAGGATGGGCCTATGCGTGCGGTGGGCAGGTGGT +GTGGAGGCAGGCGGGCGGGCGTGTGGCAGCGCGCCGGCTGAGCCCCTCCACTTCCAGGTC +AGCCAGAGCAGCCTCCCCATGCTGTCCTCGCCGTCACCGGGCCAGCAGGTGCAGACCCCG +CAGTCGATGCCCCCTCCCCCCCAGCCGTCCCCGCAGCCCGGCCAGCCCAGCTCACAGCCC +AACTCCAACGTCAGGTAGGCCTGGCCTGGGGTGCCCCTCCCCACCTGGCCCTCGAGGCTG +GCCCTGCCTGGACCCCGGCTCACATGTTTCTCTCACTTGGCTGCAGCTCTGGCCCTGCCC +CATCTCCCAGTAGCTTCCTGCCCAGCCCCTCACCGCAGCCCTCCCAGAGCCCAGTGACGG +CGCGGACCCCACAGAACTTCAGTGTCCCCTCACCTGGACCTTTAAACACACCTGGTAAGT +TGGGCCTGAGGTGCTAAGGTCACTCCTCACCTTTATGAGGCCTCAGCTCATACTGGGTGT +GCGAGCTCTGGGGCCCTCAGAGCTCAAGTTCCCCACCCGAGGGTCGAGGGCTGTGGCCTC +ACCCGCCTGTGTCCTGCAGTGAACCCCAGCTCTGTCATGAGCCCAGCTGGCTCCAGCCAG +GCTGAGGAGCAGCAGTACCTGGACAAGCTGAAGCAGCTGTCGAAGTACATCGAGCCCCTG +CGCCGCATGATCAACAAGATCGACAAGAACGAAGGTAGGCTGCAGCCAGGGCAGGGGCCT +GCACCCTGGGGACACCACCAGGCTTGTGTCTTAGTGTGTACCCTCTTCTGTCCCAGACAG +AAAAAAGGACCTGAGTAAGATGAAGAGCCTTCTGGACATTCTGACAGACCCCTCGAAGCG +GTGAGCTTTGCCCACAGCCCACGGAGGGTCCACAAGGGCACAGATAGCCCAGCCATGGAT +GGGCACTTGGTGATGATGTGGGTTTAACAAAGGCACCAGGCAGCTCTTTGGACCCTGGCC +AGAGGCCTCCAAGGCTCCACTCTGGTGTGTGCTGGGGCTTCAAGCCCAGGCTTCATCTTG +GCCCATGCCCAGCCTTTGCCCTATTCCTGGCTGCTGCTGTGGCCCTCATGCTGGGCCATC +ACAGCCAGACCTCATCCAGTCAGCAGCCAGGGGCCCAGCTTGCAGTGGCCTGACCATCAG +CTGGCCCAGATGGGCCTGAGCCTGACCTGGAGTTCTGCCCCTGACTTGCTGGTGACCATG +GGCAGGCGACTGCATCTCAGTTACCCCATTTGTAGCCCACGTGTGTTGTCATGAAAATGA +AACAAGGTGGCGCTGGTGAGAAGCAGGTGGAAGGCAGGGCTGCTGGCCACAGGCTGCTGT +GAGGATCAGAGCTCGGGCAGTACCTCCAAACTGCATGGGCATTGGCATATACCTCCCTTT +CACCTCAACTCAGGCTATCCCCCAACCCCTGTCTAGAAGGGTCTCTCTGTTCTGCTTGTC +TGGATAGAATGCCAGTCACTATTGGGTGGTCCTCCAGGTCTTCATGGGTTGATCCTTTGT +TAGGGTTATAGGGATGAGTGGGGCAGGGACTGGCCTACATGACAATGAGGCATTCACAGC +CTGATCAGGGGCCTGGCCACTGTCCCTTCTCTTGACCCATCACCTCACTCTGCCAACCAG +GGACAAGCAGCTCCTGGGGTTGAGGGCTGCCTGCCTTCAACTCTGGGTCTGGGAACAGCT +GGTCAACTGGTAGGAGCTCCTGCAGAGGTTTCTGATGGCTGAGGCCCAGTGGCAGTAGTT +GGGATCCTGAGCCTGAGAACTGCCATGTCTTCCACTCTTTCAGCCCAAGTCCTCTCTCTC +TGCAGGTGTCCCCTGAAGACCTTGCAAAAGTGTGAGATCGCCCTGGAGAAACTCAAGAAT +GACATGGCGGTGGTGAGTGGGATGCCAGACACCCCTAGGGGAACCAGGGCTCTCCTAAGA +GCTCCTGGGAGTGCTGCTGAGAGGGCCTTCAAGGTCAGGGCATCTGGGCGGGGGCCGGGC +CTGACCTTGGACCCTGCCCACGAGGCTTCCTGGCCAGGTCTGCTGTGCTGGGTGGGAACA +TGGGAGAAGTCACCCTCTGTCTACGGCCCCCGTGGGTGCCTCCTTCACCCATTTCAGAGG +AGGCAGGGACTGTAGGGAGGATAGGCTGTGGGGGTGGGGGATTATTCCCAGGATCAGCCA +ACATTGTCTGCACAAGGGTGGAGGCTGTGAGAGAGGCCTCGGGAATCTGACTGTGAGTGA +CCATGGGCCTGGGGTGTGAAGGCCCCCTAAATGGGGAACCCTCGGGTCCCGGGCTGCTGA +CCGTGCCCATCCTGTCTCCAGCCCACTCCCCCACCGCCCCCGGTGCCACCGACCAAACAG +CAGTACCTATGCCAGCCGCTCCTGGATGCCGTCCTGGCCAACATCCGCTCACCTGTCTTC +AACCATTCCCTGTACCGCACATTCGTTCCAGCCATGACCGCCATTCACGGCCCACCCATC +ACGTATGTCCAGCTGGGCTGGGCTTTGCGGAGGGCGGCCAGCCCTGGGCCGCGTGTGCCA +GGTGTGGTCACCATGCCGCCTCCCCAGGGCCCCAGTGGTGTGCACCCGGAAGCGCAGGCT +TGAGGATGATGAGCGGCAGAGCATCCCCAGTGTGCTCCAGGGTGAGGTGGCCAGGCTGGA +CCCCAAGTTCCTGGTAAACCTGGACCCTTCTCACTGCAGCAACAATGGCACTGTCCACCT +GATCTGCAAGCTGGGTGAGTGTCCAGAGGGCCGGGACTGGTGTGGGAAAGCAGGCCCTGA +CCGCAGCCCCAGGACTCTGCCATCCAAGCCAGATGGCACAGCGCCCAGAACCCACCCTGT +GTTCACGCCCCGCCAGGCTGTCTGCTCTATCCTCACACACACCGGGCTCCAGACAGCCTG +GCCATGCCTCAGTCCCCACTGCCAGAGCCCGCACACTCTCACCTCCCCAACACAGATGTG +GCTTTGCTTGCCTGGGCCCTAGGGAGGTGGTAGGCAGGACCTCTGGGCACCCATCAATGC +AGAGCACTCCAGGCTTCACGTTTGGAAATCTGAGAGTCAGAGAGACCTCCTCCAGGCTTT +GCCACAAGCTTCACCAGAACCTCCCTGGGTGTGGAGTCCTGTTCCAGAGCAGGGCTGTGA +GGCAGGGCAGGCCGGGGCTTGTCCAGGTCACAGATAGAGCCTTCTGTGTTGCAGATGACA +AGGACCTCCCAAGTGTGCCACCACTGGAGCTCAGTGTGCCCGCTGACTATCCTGCCCAAA +GCCCGCTGTGGATAGACCGGCAGTGGCAGTACGGTAGGTAGACCCAGAGGAGCTGTCTGG +GGACCCAGGGCAAGCAGGGGTCATTGTGGAAAACCAGGCTTCCACTGCAGCAGGGACAGC +CTCTGTGTGCTCCTGCCCCTCCCCAGCTCAGGCCCCTCCCTCCCCTCTTCTGGCTCCTCC +TGCACAGACAGCAGCGGGTTTTCCAGTGGTCGCCTGAGAGAAAAGGGTCTCTGCTCCCAC +TGTGTCCCTTCGCCCCTTCAACTTGTGTCACGTCAGCTGTCCAGGGTGGTTGTGTTCAGT +GGGTGAGGGGTGAGTAAGCCCATGGCTCAGGGACAGTCCCCGCTCTTCCCAGAGGCCACT +AGCTTCCCAGAGGCCACTACCTTGGCAGGGCTGCCAGGTTCCACTGGTAGCTTGGGCACA +CAGGGCCCAATCTGGGTGCTGTGGCTCCAGAGAGAACCACGGTGGCAGGGGGCAGTCTCT +GAGCCCAGAGCTGGCACACAGCAGAGCTGGCACACAGCAGAGCTGGCACACAGTAGAGCC +AGGCTGGGTCCCCAAGGTTGTTAGAGGCAGAGCCCTAGATCCTGTTCAGATTTGGTTCTC +ACTGACGATGAGGCTCTGGGAGGAGAGCCCAAAGGCCGGGCAGCGTGCAGGACACATCAC +CTCCTGGTGCTTCGGCCCGCGCCTGGGGCTACCCCTTCCCAGAGCACTGCCGGGTGTGCC +AGGAGCGAGCGCAGCGCCGGCCGCCTTAGGTTCACGCCCACTGCTCTGTTGCAGACGCCA +ACCCCTTCCTCCAGTCGGTGCACCGCTGCATGACCTCCAGGCTGCTGCAGCTCCCGGACA +AGCACTCGGTCACCGCCTTGCTCAACACCTGGGCCCAGAGCGTCCACCAGGCCTGCCTCT +CAGCCGCCTAGCCAAGACTGCAGGGATGGCCCGCAGCCTCATCGGGGCCAAGGACACACG +CCTCCTGTCAGACACTTCTAGGTGTTGGCTTCCTTAGAGAGCCTGGGGTTAGGTTAGCTT +TCCTGCTTTTATCTTCTGCCTTGGGGACCTGCCAAACGAAATCCCACACCTGTACAGAAC +TGGGATAGGCGCAGTGGAGCGGGTTGCTTGGGGGGCGTTGGCCGACTTCTTAGAGAAGGC +CCTCCATGTGACTTCCTCCCAGGAGCCAGATGCGATCCTCAGGCTGCTCTCACCGTGGCC +TGTCCACGGTCCAGGTCCATCTCAGCAGCGTGAGGGTGCACTCAGGGTGTTGTTAGAGCG +TCTCGTGTGTGCTAGACGCACCCCTACTCGTTCCTATAGAACACAGAGGACATAGGAAAC +CCTTAAAACACACATGGGATTCTCTGGTCACAGTTTTGGGTTCAGGCTATGCTGCTTTGG +GCAGGTGGAGCACCCCCCGAGGAAGCCTGCAAGTCCAGGGCACAGGCTGCCTTTTGGAGG +GAGGGCTGGCCCATAGGTGCTGCTGGCTCCCCGCCACCAGCTGGGCCTCAGCCCTCACGG +CATTCCTGCTGAGCACCGTGGGGCACCCAGGGAGCAGGGGCGTCAGGGATCCTGCTGCCG +GCACCCCTGTGCCGCTGGCATGAGGGCCGTGTCCCCACTGTGAAGGATGAAGAGCAAGGC +CCTCAGGACCCGTGTCCTCAGAGCACCACACACTGAGCACCCAGAGACAGCGGGCCTGGC +AGCGGGCCGGGCCATGCAGGGAGCGCCTCCCTATGTTGCCTGCCACTCTGGGCACCGGCC +AGCACCCTCTGGTGAGAAGAGGTCCCCCCTTTTTATGTGCACTACCCCACCATCTGTGAT +TATAATAAATTTATTATTCCTGTGTTTGTCAGTTGTTCATCACTGTGTCCCCTTCTCCAT +GAATCTGGGCTCGCTGTCCTGTCAGGATGCTGTCAGCCTTGGGGCTGCCTGGGGCCTCTG +CCTCCCTTCCAGGAGGGACTTGAGGTGCTGCAGCTGAAAGGCAGGGGCAGGGGTGTGGTG +GGGCCTGCGGTGGCACCAGGCTGCCCAGGGCCATCCCCACCACCCAGGGCCTCACCTCTT +GGGCCTGCAGAAGGTTGGTATTCCACAGCTGGTGGATGACCACTTACACTGCTGAAGTGT +GGTGGGCTTTCGCAGGTGTGGGGACAGGATCATCGGGGAGTGCCATCATCTGCCTGTCCC +TGTGCTGGCTGCCCACCCAACAGAAAGCCCTGGCGTTAGAGGCCTCTGCTTCCCTGTCTC +TGAAAGTCATTACAGTAGCCAGAAATGACCTGCCCAGGTGGGTCTGAGCATCCAGGCAGC +ATACTTCCCCCAGGCAGTGCCCAGGCCAGTGTGGGGAACAGGGCCTGGCTCCCTTCTCCC +ACTGACCAGAGTGCTCTGGGTGCCAGATGGGGGTCTCGGACTGGGGTCTGTCCCTTCCTC +CCCTCTGAAGGTGCCCTGAGGGTCAGATGTGCTTCAGTGGGTGACCAGCTAGCTGCCAGG +CTGCCCTTAGTCAGGACCCTATACCCAGTGGGGCTTCTTGCTTCAGGGCTGGTCTCAGGG +GACGTGCAGAGATGCAGGAGCCTGTCCTGCTGGTTGCACCGCTCAAAATGTGCACTCTGC +AATGTCTCAGGGCAGCCCGGCAACTCGGGGAGTACCAGAGCCTGGTCCTGCTCTCCTAGT +CCCCTCCAAAGGCAGGCTGTGGCCAGGGGCAGCAGGCACTGACCAGCTCCATTCTAATCA +GGCCCAGGAACACAACTCACTTTTCTTGGTAAAAAGATTACTTTGTTTTCTTTTCTCTGA +GAAAGTGGTTTAGGGGCTGTTGCTGCCCCCTCTTGTGGGCTCAGGTCAGCACAGGTAATC +TGCAGGACTCCAGGGGAGGGGAGGAAGACAGCGCCCACCCAATGGACAGAGTGTGGACAG +AGCGTGGCCATTGTCTGCTTTCATGAGCCCTGGAGACAGGATCCTAGAGCAAGGGACACA +GCAGTTTGCTGACTGCAGTGTGGGAGCCTAGTAAATGTGGTCCTGGGGCCCTTAGGGTGC +AGGCAAACCTTACTTGGACTGCCCTTGCACCCCAGGAACTTTGTCCAGCTTGCTGTTGTG +AAGCAGTGGCTCCTCCTCAAGGTCTGCCTTCTGGGGTACCTTAGAGTACCCCAGTGCTTT +AGAGTCTTGTTTCTTGAAGGAACCGGCTGGGGCCTGTCCTTTCCTTGAGAGTTGGCTGCA +GGTCAGACCCGACAGGGCCAGTCACTGCAGGCACCAACAGCCGCTGCCCAAGTCTTTCAG +GATCAGCTGTGTGTGCCCAAGAAGCCCCTGCCTCAGTTGCCTCCTCTGTAAAGGGAAGCC +TGCCTTGGAGGGTTCTAGGAGGAATAAATGAGGTTCTGAGGATGAAGCCCATGGGTGGTG +CCTGTGAACATTCTAGAACAGTCAATATAGTGGAAGCTGGCTCTGTTTTGGGTAAAATAA +AACTGCATGCGAGGCCTGGGACTAAGCCTGCATGGGTTTCCTCTGCAAGGACAACGCCCA +TGGCACGCCTGGGCTCATCACAGGAACAATAGGGGCCAGGGTTGGGGCCAAGGAAGATGC +CTGGTCTCGAGCCACTCCCCGCTCACTCTGCAGAAGATGCCATGAGCCCAGGGCTCCGTG +GGCAGTGCCATCCCTCCTGTATCCTGTCTGCTTGTGGAGGGGGACGTGGGCCAAGCAGGG +CCTCTGCCAGGCAGCCAGTGTACGTCCTTCCCCCTAGAAGGCCACCCAAGGAGGCCCCTT +CTGACCGCTTGCTGTGCTGGCTTGGGGTGCCTGCCATGAGGCCTTGCTGCCCTGCGTTGA +CAGCCCCTGTGACTGGCCCCCAGTCCTGCCCACCCCACCCTAGGCCCCTCCTGGTGGTTT +CAGCTTACAGGGCTCCCTTCAGCTGCCCGTTCACCCCCAAATCCTTGAGGTTGGCCCAGC +AGAGGACTTTCAGCTCCCTGGTCAGCACCTCTAGTGACCACCCAGGCTGGGGTCCCTGTG +GGGCACTTGCCCCTGTGAGCACATGGAGGACACCAGCCTGCTCACCTGACACCATTTAAT +TCGAGGTGGAGTTGACAGGCTGGAAGTTGCCACCCGCACACCTGCCTGAGGGAGAAGCCC +TCCGTCTGCCTGCAGGCCTGTGTCCTCCCTGCTCTACCCACACTCCACTGAGGCAGCCCC +AGACCCACCGCGCGCCCAAGGGAGCAGAGGCCCCGGAAAGGTTGTTTCCTGAGGGGCCAT +CCAGAAAGCGGGAGGGCTTGGGACCCATGGAGCAGCAGGTCCGGAGGGAGAGCATGGCCT +CTTCCCGTGTCCTGTCAGGGTCCCCAGCACTGCAGGGCCACACTTTGCCCAGAACAGCTC +ACTGGAGTTGCCACCGCAGCTAGGGAAGGGCCTTCACTCAATCCCATTCTCTGTGTCTCC +CTAGAAGGGAGAGCCCTGGACAATGCCCCAGCTGGGATGTTCCCAGGCTGGTCCCATTCA +CCAGTCAGATGTCCTCCTGATGTCAGCCCCGGCCCCAAAGGTAATAGAGTGAGCTCAAGA +ACTCAACCAGAATCCTGGGCTGGGTGGGGGCCACCATTGGGATGGGGAAGTGCCTTGGAC +AAGTGGCAGGGAAGCAGGACTCTGGTTACTCCCCCCACCCCCATCCCCACAGTTGTTGCT +GAGATGGCAGGAAGGAATCCCTGGATGGGGTGTGCCCGGAGCCCTTCTCCCAGCGTATCA +GGAATCAGAGCCACAAGGCTGGAGATCCTAGGCCCAGCCACAGCAGCAATCTGAGGCAAA +GACCCAGCAGGGTAGGGGCTGTCCCAGAGTCCCCTCCCATTTCAGGAGCTCTGCTTGGAG +GAGGGAAGGTCTGGGAAGCACCCTGTGCCCACCATCACCACTGCACTGACCACAGCCCTT +GGGCTTCCTGAGAGCAGCACGTGCTGTGCTTGGCTGTATAACATCGTCCAGCCATGGCTA +GGGGCAGCAGCATCTGTCCAGGTCCCTCAGAACCTGTCCTCACTGGGTTGGCATACAGAG +GCCAGTGCAGCCAGGTGGGCAAGGACAGTCTGGAGGGGCTCCCCGGGGTGGCAGGAGCTT +CCCATCAGGCACGAAAGGGCCCAAGTCTCACCTTTCTCCTGTGACTCATTCATTATGAGC +TTGTAATGGGGATCTGAAATCAAGCGCATGCTCTTCTCATCACTTGTGAAGCCACAGCCA +TTCTAAGAGAAGCAGCTTGGGCTGTCCACTACCCCCTGCTGAACCCCGAGAGTCCTGGCT +CGCCACTGGCTGACTGGGCCCTGCCCCACAGGTCCCGCTTTCCACCACACCTTTGCTGTG +GGCATGTGAGGGCAGGAATGACCCTGCCTGTTCCCTAGGCAGAGCCCACCCAGCACATCA +GCCTCATCCTCCCATCTGACTACAAGACGCCCATGGTGCCAGGCAGGACCTGGGCCCCAG +GGGTACAGGGGTGAACTCTGGGAGCCCCTGGCCATGGATGAGCATGGTCAGTGTCATGAT +CCTGTGGGCATCAGGGACTGGGGAGAGGCTCAAGAAGACATGGGGAAGGGGGATCCTGAC +ATAACAGATGCCTGGTGATGGAATACTTAGCACCTAGGTAAGGCAGCACCAGGGAGCGGG +GAGGGAGATGAGGCTGCAGGCACTGGTGCCCTCGCTGGAGCCTCTGCTGAAGCAGGGAGG +GAGGAGCGGAGCCACATCCTGGCGGGCCCTCTTTCTGCTCTGGTGGGCAGTGGGGGTGAG +GAGCTGCTAAGGGTGCAGTTAGGAAGGCCCAGCCCGAGGACAGTGTGGGCACAGGCGAAG +CCGGGGGCATGCCTGCTCCTGATCCGGCATGTTTAGTTGGAGAAAATTCACTCAGTTGTG +CACCGGCACTGGGCATGTTTTCCTTCTACGAAGTTTTTAACAGATGTGTACCTGACCCTG +CCTGGAGAGGGGAGGGCTGGCAGGGTCAGCGTTTGAAATGATGCTGCCCCCGGCGGGACA +GGCAGACAAGGAGGGCACCGCCCCGGGCCTAGGCGGGTCTCCGTCCTGGGGCAGGGGAAG +AGCTCAGCATGGCAGGACCTAGCGTGGGCTTGCTGCCCTGTGTCCTCCCTGAGCCCAGGC +AGGTGCTGGAGTTCATGTGCTGCGTTTCTGCTCTGCGGGCCGCCGCCGTGTTCAGGCGCT +TGGGGAGGCAGGGCAGGCCTAGGGCCCTGTGGCTGGGCTCACCCTTGTTCTCCCACTTCA +GATGCTCGATCTTCTAGTGGAGCTTGGCCAGCAACTCCAAGGACTGCTGCTGTAGGAACT +GCAGGCCCAGGTCCAAGTCCAGGATCTGCCTCTGCTGGTCGATCTGGACACCCACAGACC +GGCGGCACTGCGGGGGGTGCGACGTAACCTGAGATCCCGGGGACCAGCTGGGAGGCTAGC +TCGCACGGCTCATGTCGCCACCCCCAACTACACAGCCGCTGCCACTGCACCCTGGCTCAG +TGGCCATGCTGCCCGTCACAATGGAAAGGGGCGTGGCTGAGGAGCAGGGTGGGCAGCTGG +GGCAGGGCCTGTGGCTGGCTCTTCCTGGGTGAGTACAGTCTGATTTAAAAGGCACCCAGG +GCTGGGCACGGTGGCTCATGCCTATAATCCCAGCACTTTGGGAGGCCCAGGTGGGCGGAT +TACTTGAGGTCAGGAGTTTGAGACCAGCCTGGCTAACATGGTGAAACCCCTTCTCTACTA +AAAATACAAAAATTAGCTGAACGTGGTGGCACGTGCCTGTAGTCCAAGCTACTTGGGAGG +CTGAGGCCGGAGAATGGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCAGAGATCGCGC +CACTGCACTCCAGCCTGGGTGACAGAGGGAGACTCTGTCTCAAAAAAGAAAAAATAAAAT +AATAAAACGCATTCAGGCATTCTCTACAGCCTGGGCAACATAGTGAGACCCTGTCTCTAT +AAAAAGTAAAAGAAAAAAAATTAGCCGGGCTTGGTGCTGTGCTCCTGTAGTCCCAGCTAC +TTGGGAGGCTGAGGCAGGAGGACTGCTGGAATCCCGGAGGTCAAGGCCGCAGTGAGCTAT +GATGGCACCACTGAACTCCAGGCTAGGTGACACAGTGAGATGCTGCCTAAAAGAAAAAAA +AAAAAAGAAATATGTCTTTCTTTACAAGGCCTGCCCTAAAAAAAAAAAAAAAAAAAAATG +TTCGCCAGAGCCAGGCCAACTGTGATTTTACCAGATGCCAACATACCCAACCCAAGGGAG +GAAGGGAACATACCCAATCCCAGCCTGTTCTAGCTCCTCTTCCCCACATCTTCCTGCCAC +ATCAATAGGGCTCCTGTATAATAACAGGGGATACAAGTGAAAGAACAGCCCATCTCAGAA +CTTATTTGAGAAATGTCTAGGAAACCCTAAAGACAACAGGGAGACAAAAACTAAGACACC +AGAGGAAGTTTATGCCTCTGACACTTACAGTTAGAACAAACAGCACACATGGCCCAACCC +CTAACCAGAGCAAAATAAAACCTCACACAGGCCGGGCGCTGTGGCTCACCCCTGTAATCC +CAGCACTTTGGGAGGCCGAGGCGGGTGGATCACGAGGTCAGGAGTTCAAGACCACCCTGG +CCAAGATGGTGAAACCCCATCTACTAAAAATACAAAAATTAGCGGGCGTGGTGGCAGGCA +CCTGTAATCCCAGCTACTTGGGAGGGTGAGGCAGAGAATTGCTTGAAGCCAGGAGGTAGA +GCTTGCAGTGAGCGGAGATTGCGGCACCGCACTCCAGCCTGGGTGACAAAGTGAGACTCT +GTCTCAAAAAACAAAAACAAACAAACAAAAACTTCACACAGAAAGCCCATTTATCACGTA +CCCCGTACAGCATGTCCAGCTCCCCACAAAAAATTTCAAGGCATAATAAAAACCAAAAAA +TGCAGTTTGAAGAGACAGCAAGCATCAGAGCCAGACTCAAATATGGCAGAGATGTCGGAA +TTATCAGACCAAGAAATGGAATACAACTATGATTAATATGCTAAGGGCTCTAATGGAAAA +GTGGACAACATGAGATTACAGACAGAAAATGGAAACAGGGATAGACACTCTGAGAAAGAA +TCTAAAGAATATGTGAAGGCCGGGCACAGTGGCTTATGCCTGTAATCCCAGCACTTTGGG +AGGCTGAGGCAGCGGATCACTTGAAGTCAGGAGTTCGAAGACCAGCCCAGTTCGAGACCA +GATGGCAAAACCCCATCTCTACTAAAAAATACAAAAATTAGCCAGGTGTGGTGGCATGAA +CCTGTAATTCCAGCTATTCAGGAGGCTGAGGTGGGAGGACTGCTTGGACCCAGGAGGTGG +AGGTTGCAGTGAGCTGAGATTGTGCCACTGCCCTCAAATCTGGGTGACAGAGTGAGACAC +CACCAAAAAAAAGAAAAGAAAAGAAAGGAAACAAGGAGAGGAAAGAAAGGAAAGAAAGAA +AGAAAGAAAAGAAAGAAAGAAAGAGAAAGAGAAAATAAAGAAAAAGAAAGAAAGAAGGAG +AATATGTGAGAAGTCAGCCAGGTAGTGACTCATGACTGTAATCCCAACACTTTGGGAGGC +TGAGGTGGGTGGATCACTTGAGGTCAGCAGTTCAAGACCAGCCTGGGCAACATGGTGATA +ACCCATCTCTACTAAAAATAAAAAAATTAGCTGGATGTGGTGTCATGCACCTGTAATCCC +AGCTACTCAGGAGGCTGAGGCAGGAGAATTGCTTGAACCTGGGAGGTGGAGGTTGCAGTA +AGCTGAGATTATGCCACTGCACTCCAGCCTGGGCAGTAAGACTCCGTCTCAAAAAACAAA +AAGAAAATATAAGAAGTCAAAAACACAACAGAATGAAAGATCAGGGCTGGCAGCAGTGGC +TCATGCCTATAATCCCAGCACTTTGGGAGGCCAAGTTGGGTGGATCACCTGAGGTTAGGA +GTTGGAGACCAGCCTGGCCAACATGGAGAAACCCCGTCTCTACTCAAAATACAAAAATTA +GCTGGGTGTGGTGGCGCATGCCTGTAATCCCAACTACACAGAAGGATGAGGCAGGAGAAT +TGCTTGAACCTGGGAGGTGGAGGATGTAGTGAGCCGAGATCATGCCACTGCACTCCAGCC +TGGGTGACAGAAGGAGACTCTGTCTCAAAAAAGAAAGAAAGAAAGGTCAGGTGCATGGCT +CATGCCTGTAATCCCAGCACTTTGAGAGGCCAAAGTAGAAGGATCGTTTGAGCCCAGGAG +TTGGAGACCAGCCTGGGCAATATAGCCAGACCCTGTCTCTACAAAAAATTAAAAAAATTG +CCAGCATGGTGGTGCACATCTGCAGTCCCTGCTACTCAGGAGGCCAAGGCTGCAGTGAGC +TGTGATTGTACTACTGCACTCTGGCCTGGGTAACAGAGAGAGACCCTGTCTCAAAAATGG +GGTAAAATGGTATAGGAAATTTGGATCTAAAAAAAAAAAAAAGGAAGTGCATTAGATAAG +AAATAAATGAAGATAAAATAGAATCTTTTTTTTGGTGGGGGTGGGGAACGGAGTTTCACT +CTTGTTGCCCAGGCTGGAGTGCAATGGCACGATCTTGGCTCACCACAACATCCGCCTACT +GGGTTCAGGCGATTCTCCTGCCTCAGCCTCCTGAGTAGCTGGGATTACAGGCATGTGCCA +CCACGTCCAGCTAATTTTGTATTTTTATTAGAGTCGGGGGTTACTCCACGTTGGTCAGGC +TGGTCTTGAACTCCTAACCTCAGGCGATCTGCCTGCCTCGGCCTCCCAAAGTGCTGGAAT +TACAGGCATGAGCCACTGCACCTGGCCAGAATCTTGTATTGTTCTTATTTTTAGTTGAAC +AGATGGCAGGTTATTCAAAATAATTATATCAACATGTATTCAGTAATTATAGCTTATGGA +TAGCTGGAATGAATGGCAGCAATGTTATAAGGGATGGGAAGGAGGATATCCTGAGTGGAA +AGAAAGTCACCCAGGCTGGAGTGAAGTGGCACAATTATAGCCCACTTGCAGCCTGCAACT +CCTGGGCTCAAGCCATCCTTCTGCTTCAGCCTCCCTGGTAACTGGGATTACAGACACACA +CCACCATGCCTGGCTAATTTTTAAATTTTTTGTCTCGCTGTGTTGCCCAGGCTGGTCTCA +AACTCCTGGGCTCAAGAAATCCTCCTGCCTTAGCCTCCCAAAGTGTTGAGATTACAGGCG +TGAGCCACTGTGCCTGGTTTATGGTTGCTTTTGAATGTCCTAGTCCTACATAAGTGGCTT +CCAAGAAGGGAAAAAGAAAAATGCAGGCAGGAAAAGGTGCTGATCCATAAAAACCTCTGG +AAGGTATGTCTCTAGGGAGGGGGTGAGTGTTGAGGAGGGATGTTGCAAACATGGTAGTGG +AGATGGCAAGAGTGGCTGCCTGCCTCTTCGTCTGCACTTCCACAATCTGAAGCAGCCATC +ATCAATCGGAACACAGATCCCCAGTATTTGGAGGATGGGGCTCTTATTGCCTGCTGTGGC +TCCTGCAAGCTATAGGGAAGCTACCCCAGAAGTATAGGCATGGCTGCTTGCACCACCAAT +TTAAATGCTAATTACTTCTGAAAACACCCTCACACACATGCCCAGAAATAATGTGTAACC +AGATATGTGTGCATCCAGTGGCCCAGACAAGTTGACATATAGAATTAACCATCACAAGTC +CACCCCTTGTCAACCTGGTACCTACACACATCTCCTTAAACCATACTTAACCTCCAAATA +AACACAATAACAAAGTCAGTGTTAGCAGTGGAAGGTGTCTGAGTTAGTGGCAGCGAATCC +GTATGGGTCTGCAGCAACCTCAATTCTTGCCTCCTCAGAAAAAAGAATTCAACTGGCCGG +GCATGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCAAGGCGGGCAGACCACGA +GGTCAGGAGATCGAGACCATCCTGGCTAACACGGTGAAACCTCGTCTTTACTAAAAATAC +AAAAATTAGCCGGGCATGGTGGTGGGTGCCTGTTGTCCCAGCTACATGAGAGACTGAGGC +AGGAGAATGGCAGGAACCCAGGAGGCGGAGCTTGCAGTGAGCCGAGATCGCGCCACTGCA +CTCCAGCCTGGGCGACAGAGCAAGACTCCGTCTCAAAAAAAAAAAGAATTCAACTGAGGG +GCATAAGGCAGAAAAAGAGACCGAGGCAAGTTTTGGAGGAGGAGTGAAAGTTTATTTAAA +AAAGCTTTACAACAGGAAAGAAAGTATTCTTGGAAGAGACCTAAACAGGCACATAAAGGT +CAAGTGCGGTGTTTAACCTTGATTCTAGGACTTTATAGACTGACCCCTTTCCCAAGATTC +TTCCCCTAGGGTGGGCTGCCTACATGCACAGTGTCCTCCTTACCCTTGGGAGATGAGCAC +ACGCAGTGTGTTTAGGAAACTGTACGCATGCCCATCTGAAGATTTCTTCCGTCCCAGAAG +GTCATACTCTGCCATTGTCTCTTAATGCACATGGCCGGGGAAATTGCTTCTCCCTGGTGC +CTGCATTCAATTAACACTTTAATGAAACAGGTGTGACCCATCAGGAACTGGCCTCTCCCT +GATGCCAGCTGCCAATTTATCACTTTCATTTTTAATTTATTTTTTAGAAGGAGTCTCACT +CTGTCACCCAGACTGGAGAGCAGTGGCATGATCTCGGCTCACTGTAACCTCTGCCTCCCA +GGTTCAAGTGATTCTCCTGCCTCAGCCTCCCGAGTGGCTGGGATTAGAGGCATGCACCAA +CATGCCTGGCTAATTTTTGTATTTTTAGTAGAGATGGGCTTTCACCATGTTGGCCAGGCT +GGTCTCGAACCCCTGATGTCAAGTGACCCACCCACCTTGACCTCACAAAGTGCTAGGATT +ACAGGCATGAGACACCATGCCCAGCCCTGGCTTTTTTTTTTTTTTTTTTTTTTTTTGAGA +CGGAGTCTCGCTCTGTGGCCCAGGCTGTAGTGCAGTGGCATGATCTCGCCTCGCTGCAAG +CTCCGCCTCCTGGGTTCACGCCATTCTCCTGCCTCAGCCTCCAGAGCAGCTGGGACCACA +GGCGCCCACCACCACGCCCAGCTAATTTTTTGTATTTTTAGTAGAGACGGGATTTCACTG +TGTTAGCCAGGATGGTCTCGATCTGACCTCATGATCCGCCCGCCTTGGCCTCCCAAAGTG +CTGGGATTACAGGCGTGAGCCACTGTGCCCAGCCGCTAATTTTTTATTTTTTATTGTTTG +TAGAGAGGGGGTCTCCCTATGTTGCCTAGGCTGTTTTGTTTTTTTTTTTAAACAGAGACA +GGGTCTTGCTATGTTGCCCAGGCTGGTCTTGAACTCCTGGGCTCAAGCAGTCCTCCCATC +TTGGTTTTCCAAAGTGCTAGGATTACAGGCATGAACCACCAGGCCCGGTCTCCACTGTGA +ATCTTTTTTTTTTTTTTTTGAGACTGAGTTTCACTCTTGTTGCCCAGGCTGGAGTGCAGT +GGCACCATCTCGGCTCACCGCAACCTCCGCCTCCTGGGTTCAAGCAATTCTGCTGCCTCA +GCCTCCTGAGTAGCTCAGATTACAGGCATGCACCACTACGCCCAGCTAATTTTTTGTATT +TTTAATAGATACAGGTTTTCACCATGCTACCCAGGATAGTCTTGATCTCCTGACCTCATG +ATCCACCTGCCTCAGCCTCCCAAAGTGCTGGGATTACAGATGTGAGCCACCGCACCCGGC +CGCTAATGTTTTATTTTTTATTGTTTGTAGAGACAGGGTCTCCCCATGTTGCCTAGGCTG +TTTTTTGTTTTGTTTTGTTTTGTTTAACAGAGACAGGATCTTGCTATGTTGCCAAGGCTG +GTCTTGAACTCCTGGGTTCAAGCAGTCCTCCCATCTTGGTCTCCCACCCAAAATGCTAGG +ATAGGCGTGAACCGCCAGGCCCGGTCTCCATTGTGAATCTTTTTTTTTTCTTTTTTTTTT +TTTGAGACTGTGTTTTGCTCTTGTTGCCCAGGCGGGAGTACAGTGGTGCGATCTCGGCTC +ACCGCAACCTCCGTCCGCCTCCTGGGTTCAAGCGATTCTCCTGCCTCAGCCTTCCTGAGT +AGCTGGGATTACAGGCATGCGCCACCATGCCTGGCTAATTTTGTATTTTTAGTAGAGATG +GGGTTTCCCCATGTTGGTCAAGCTGATCACGAACTCCCGACCTCAGATGATCCACCCGCC +TCGGCCTCCCAAAGTGCTGGGATTACAGGCATGAGCTACCGCGCCCGGTTTACCATTTTG +AATCTTAAGAGGACAAAGTCTGGTTCTCTAGAAGGCCCGAGTAGCTTTTCCCCTGAGCAT +CTTGAGAAAAAAGTGCTCTGAGCACTCCTTGGGAAGTCCGAGACAGCACATGCAGCCAGG +TGCTCCCTGGCTGCTCTCCCAGAGGTCAGCACAGCTGGAGGCAGCTGGAGGGAGGAGGCT +GCAGAGGCGCTGAAGCCAGGAAGACCCAACAGTGGAGAGAGAAGTTGCCTGGTGACTGAC +CCTCGGCTTGACCCTGTGCTCCCCTGGGCTGAGCTGGGTGTCAAAAGGCCTCCACCCTCC +AAAGTGCCAGCCTCCTGCTGTGGCTGGAAAGCATTTGCTCCTCCTCCTCTTCTCACTTCT +TTGCATTCTTCTGATCTCTTAAGGGCGTACAAAGATTCACATGGATATTAAAGTCAATGG +TGATTTTCATAGCTGGAATACTCGTTGGGAGAAAGTAGGAATTCTTTTTTTTTTTTTTTT +CTCCCAAGCTCAAGCGATCCTCCCACCTCAGCCTTCTGAGTAGCTGGGACCACAGGTGTG +AGCCTCCATGATGGCCTGGCTAATTTTTTATATTTTTAGTAGAGATGGGGTTTCACCATG +TTGCTCAGGCTGGTCTCAAACTCCTGAGCTCAGGCGATCCACCTGCCTCGGCTTCCCAAA +GTGCTGGGATTACAGGCGTGAGCCACTGTGCCTGGCCAAAAGTAGAAATTCTTGATTGGG +AAATAATTTTATATATTTCGGCCCCTTCTCACTTGGGAAAATTCTGCTAAGAATTCTGGT +TTTGAGAGTCAAGGGAAGCTAGCTTAATTTTTAAAGTGAAGGCTACATAAGAGTCCTCTC +TCCAGTGTGGTGGCTCACACCTATAAACCCAGCGCTTCGGGCAAATCACTTGAGCCCAGG +AGTTCAAGACCAGCCTGGCAATGTAGTGAGACCCCTATCTCTACAAAAAAATTTAAAAAT +TAGCAGGGTGTGGTGGTGCGTGCCTGTAGTCCTGGCTACTTGGGTGGGATGCTGATGTGG +GAGGATTGCTTGAGCCCAGGATTTGGAGGTTGCAGCGAGCCATGATGGTGCATTGCACTC +CAGCCTGGGCAACATGGCAAGACCTCGTCTCAAAAAAATACAAAGAGTCCTCTCTATGTT +GGAAATGTCAGAGTTATTGGCCATTTAGGGGATCTAACTTGCTCTTTGATGTCCAAGAGG +AAAGGTATAGAGTTCTCCTGATTACACAGGGCCTCTGCTTGTGGGTCGCCTGCATGAGGC +GATCAGAATCTGAGTCACCTGGGATCATGTGGGTGCTGGTACATCCTAGAGATAGGATGT +GTTGGTCATGGAAGAGAGTGGGCCACAAATGGGTTCCAGGGGAATAGCGTTGCCTGGTGC +AAGGAGGGGGATGTGGAGGTGCAGGGAGCAGGGGTGGTGTCTGGAGAGCCTGAAGCTGTG +CTGCCAGAGGCTCCAGGCCATGAGGTCTGAGAAGCATCTAGATTTGGCCTGTTCACAGCA +GGGAAGTGTGGTCCAGTGGCAAAAAGTTGAGGGCATCCTAGGAGTTGAGGAGGTGGTGGC +GGTTAGAGTAAACCACTCTGGAGGCGTCCGGGGTGGAGAGACGAGAATGTGCAAGAACTC +CTGCCTCTAGCCTGGCCTCCTCAGGACCCCGGCCACCAGCCTCCCTCCTAGAAGTCCCCA +GAGCTTCCTCCTCCTTGTGCCCCAGAACTGGTTCCTGGGTTGCTCCAACCCCAGACCTTC +CCTGGAAGTCCCCCCCAGTGCCTCCTGGCTGGGAACCCCCAACTGCATTTTGCTTCTGCT +CTCGTGCCAGTAGTCCCCTTTTCTCTCCAGTGTCCAGGCCCCAACCACCAAGACCCTGCC +TCCTCACTTGGCTTTGCTGTTCTTAGTTCTCTACTCAGTAGGTTGTGTCTGCCTCCATTC +CTGGCCAGACGCTGCCCTGGGGCTGAGTGCACAGTCCCCAGCCACTCCCGAGATCCTCAG +AGCTTCTGGAAGCCACAGACATGGTGGCATATGTTTCAGGTCGTCAGCTTGTTTTTTTTT +GGAGACAGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCGGTGACGTGATCATTCACTGCA +GCCTTGACCTTCTGAGCCCGGGTGATCCTCCCACCTCAGCCTGTCAAGTAGCTGAGACCA +CATGTGTGAGCCACCACACCTAGCTTTTTGAATCTTTTTTTTTTTTTTTTTTGAGACGGA +GTCTCACTCTGTCACCCAGGCTGGAGTGCAGTGGCACAATCTTGGCTTACTGCAACCTCC +AGCTCCCAGGTTCAAGTGATTCTCCTGCCTCTCCCGAGTAGCTGGGATTACAGGTAGGTG +GCACCACACCTAGCTAATTTTTATGTCTTTAGTAGAGACAAAGTTTCACCATGTTGGCCA +GGCTGATCTTGAACTCCTGACCTCAGGTGATCTGCCTGTCTTGACCTCCCAAAGTGCTGG +GATTACAGGCGTGGGCCACGCGCCCAGCCAACTTTTTGAATCTTTTGTAGGGATGGGGTC +TTGCTGTGTTGCCCAGGCTGGGCTTAAACTCCTGGACTCAAGTGATCCTCCCTGCCTTGG +TTTCTCAAACTTCTGGGATTACAGGCCAATCTACTCAACGTTGATATTGAGTAGAAGGCA +AAATTCACATGGCTCCGGCCCAGCCCCTTTCTGTCTCAGGCACTTCAGTGTTAATATGCG +CCTTGGTTTTGCTGCTGCCGAGTCTACTGTGCCCCTGGGCAAGGAAAGCAAAGGAAACCA +GAGGGCCAGGCCCGTGGACACTGGGGTGAGGGGCCAACAGGGTGCCCAGCAGTTGTTTCC +ACAGCCCCCACGTGGTCAGGGACCCTGTATGGGTGAACCGCCTGGATACTGAGCCTAGGC +GGCGGAAAACTCAAAAGCAAGGGCAGGTTTATTCAGATCCCTGGTGGAGTTACAAGCTTG +GTTTGGTTTTTGGTCACAGGCCCTAAAATACCTGTATTCTGAGTTTACATAAAAATACAA +AGCACTGGCCGGGCGCGCTGGCTCACACCTGTAAGCCCAGCACTTTGGGAGGCTGAGGTG +GGTGGCTAACATGAGGTCAGGAATTTGAAACCAGCCTGACTAACATGGTGAAACCCCATC +TCTACTAAAAATACAAAAATTAGCTGGGCATGGTGGCGCATGCCTGTAATCCCAGCTATT +CGGGAGGCTGAGGCAGGAGAATCACTTGAACCTGGGAGGCGGAGGTTGCAGTGAGCCATG +ATCGCACCGCCGCACTGCAGCCTGGGCTACAGAGCAAGACTCTGTCTCAAAAAAAAAAAA +AAAAAAATCACCACCGAGACGCTGTTCTCCCTGGTGTGTCATCTGTGGGGTGAATGAAGG +TGTGAGATACCCCGTGGTGGTTTCTGTCAGTGAATCTGTAGTTGTCATATATTTTGAATA +CTTCAATATCATCGAACAGTTGCTGTGTCTTTAAGCACTAGATTTTATTGAAGCTACCTT +CTTCCCTTTTTAGTCCCATTTCCCCTAGATGCATCCACGACTGCAGGAACCCCCCTGCCC +CCACCAGGAGCCCAAAGATAACCATGTTCCCACCTGGAGTGGCCTCCCACCTCCAATGCC +ATCAGGGCTGGTGCAGCTTCCCCACCTGGTCAGCAACATCATGGCCAAGGAGTAGAGGGC +GTAGCCCAGGGTGAACAGCAGTGCACAGGTGAGGGGCCTGATGCAGAACAGAGAGGCCAT +GAAGAAAGCCAGCAGTAGCCAGGGCAGTGTCAGGTAGCTGCCTAGGAAGTGCAGGTTGAG +CCTGTGGCCGCTGGCCAGCGTGGGCTCTGTGAGGTGGTAGCAACAGAAGCTGGCAAGGAA +GTCATCTCAGGAACACAGAGCCGCCATCTGGTCTGCAAACTGAAGCGCAGGCAGTGGCAC +GGGGGCATGGGGTGGTGGCACCACAGGCCTCAGGACAGCTGCACCCCACCCCCACAGGCC +ACCCTGAGACTGCACCCCAGGCAGGAGCACCCAGAACCCTCTCTGAAGAGGCCAGGCCAG +CCCTCCTGCCCACTCACTCTGTGTTTGATGGCAGATGACAGCCGGAAGGATGCTCAGACC +AAGCTGGTAATCTCATAACTCCAGAGGGGCTGCAGCTCCGGGTCCCCCTGGTACTCAATT +TCAAACCTTTGCAGCCTGTTGATGATCTAGAAACCCAGGCTATAGGGTTGGGCCAGAAAA +CATGGCCCTGGCCAGGTGCAGTGGCTCATGCCTGTAATCCCAGCACTCCGGGAGGCCGAG +GCGGGCGGATCACAAGGTCGGGAGTTAGAGACCAGCCTGATCGATATGATGAAACCCCGT +CTCTATTAAAAATACAAAAATTGGCCAGGTGCAGTGGCTCACACCTGTAATCCCAGCACT +CTGGGAGGCTGAGGCAGGTGGATCACGAGGTCGGGAGATCAGGACCATCCTGGCTAACAC +TGCGAAACCCCGTCTCTACTAAAAAAAATACAAAAAAAAATTAGCTGGGCTTGGTGGCGG +GCACCTGTAGTTCCAGCTACTCAGGAGGCTGAGGCAGGAGAATAGCGTGAACCCAGGAGG +TGGAGCTTGCAGTGAGCCGAGATTGCGCCACTGCACTCCAGCCTGGGCTACAGAGCAAGA +CTCCGTCTCAAAAAAAAAAAAAAGTTAGCCAGGCATGGTGGCATGTGCCTGTAATCCCAG +CTATTCAGGAGGCTGAGGTGGGAGAATCGCTTGAACCCAGGAGGTGGAAGTTTCAGTGAG +CCAAGATCATGCCACTGCACTCCAGCCTGGGCAAGAGAGGGAAACCTTGTTTCAAAAAAA +AGAAAGAAGAGAAAAGGAAACATGGCCCCTGCACACAACTCAGAAGAGCCAAGCCATCTC +TGCTCACAGGGGAGGAGGGAGCTGGGGACACGTCAGGGCCCAACCCATGCACCTCTGGGA +CTTGGGCCTCTCACCTGGTACTGGCCCAGGGGCGTGGGGATGAGTCTGTCCTCACCCGCG +ATGCAGTCCGGAGCTGCTTCTTTCCATTCTCATCCTGGATGGTGTCCAAGGCAAGTGTGA +GAGACTCTGCGTGAGCTGCACTTCACTGAGCTACCAGAGAGAGAGAAGCTCCTCTGCCCT +CAGTGTCAAGGCAAAGGAACACCAGTCTTCACCCCACCAGCCTCTAACAGTGGCAACGAG +AGCACCCGGACATGACACTCGGGGTGTGGGCCTGCCTCCCACAACACCGGGTTCATCTGC +ATGGGGCCTGGGACGGATGCATGCTGACCATGGGCAAAGGGGGAGTGGATCCTTCGGGGA +AGGGGACCCTAACGGCCGTGGAACAGGCCCCATTGCTCATACTCGGAATATCTGGCGCAG +GTACGCCAGGGCCTCCTCCAGGCACTCGTCCATCTTCTGGACGCTGTCCTGCCCCATCTC +GCCCAGGTCATGGCTGAATAGGAGCCGTTGGTGTCTGTGGGGCCAAAGCCCAGCCACAAC +AGGAAGGAGTGGCCAGCTGGAGTCTCCACACACTGGTCCGAGATGGACCTGGCCGTGTGC +TTGGCCTGCGTGATGAGCTGAGTAAGGTGCAGGACCTGCAAGGGAGGCGAGGGCAGGTCA +CCGGCAGGATACGCCTGTACTGCCACCCAGGCAGGCTGGCTGGGGGCCCTAAGATGGGTG +CACAGCCAGATCACTGAGTGACGGGAGGAGCAGCTTCTGCTGGAGGACTTTTAAAGACTA +AAGAATGATCTTCTAAATGTGAAATTTCCCAACACTGCCTTCGTTATCAGAAACAAATCA +GACTTTACTGAAACGGGGAAAGGAGATGTGCGTCAACTCTCCGCCCAACCTCCCTCCCTC +CCGCCAGAACACAGCACTTCCCTGCCTCTGCTCAGCCTTGTGGCTCCAGGGGTCCTGTGA +AGGGGCACCGCCAACCCACTCACCAGGGTGTAAGCCTCGGGCCCGAACATCGGGTGTACT +TGCAGTCCTGGCCCTCCAGGCCATAGATGTGACTCTTCACATTGAAGGAGGCATCAGTGA +CCACTGGTGGCCACTATGACAGGATGCTGCTGGCGAATGTGCAGGCTGTGAAGAGTCGGT +GCTGGCGGTAGGGGGATGACGAGCTCCGGCTCCGGGAACAGCTGCTCGAACTGGAAGGCA +GGAGACGAACCTAGCGCCCACTTCCGGGGGCACAGAGAACCTGGTTGCTGCCCACAGGTT +TTCAGGATGCCTCCGAGGTATCTGGGGAGCCATGACCCAGGGGTGTCCTCCTGAGGTCCT +GCCCAGCAGTGTCTCCCATGTAGCAGGTGGCCGACATGGGGAGGGCAAATGAGGGAGCTG +GTGGCTCACAGAGCCCCCGACAGTGTCTGCAGGAGGGCAAACACCAGGAGGAGTGACAGA +AGCCAATGTCCAACCCAGCCAAGACAAACGCATGCCAGAGACCAAGACCGCCTCCCAAGG +ATGCTGCCACGAGTTGCCAGGGAGAAACTGTGGTGCCATGGGCCCGCAGCTTGGTCTGTG +CAGACCCCCTCTGTGGGTATACCTGCGGTCTTCCACCCAGTGCCTGGTGCCTGGTGGCTG +CAGGGCAGGCAGGGTCCAGCCGGTCTCAGCCTTAACTGTGCAGTGTTATGGATGACAGCT +CAGGAGACTGTTGGCAGGCAGGGAGGGCAGGACACAGGCAGGTGAGACCCAGGCCCTCTG +AGGTTGCTGCATCCTTAGCAGGCCTGAGGCCCCTTTCCAAGAGGACTGAAGCCACCATGG +CAGAGGCCAGCCCAGAGCCTGAGGGGGCTGAGGGAGGATCCCCCAGAGGGTCCAAAGGGG +AAGGCCTCGGGCAAGGAAAGGAGAGGTCAGTGGCCACGCCAGGTGCCATGGAAGCCTGGG +GGGGTCTGCTGTGAGGATCAAGCAGGAGATGAGGGGAAGGTGGCCACTGGTCTGCTCTGT +GCTGGTAAGGAAGGGTTAAGGAACAGTTTGGGGGTCACCATGAAAATTTGTCTGGGCCAG +AAGGGAGAGGGGACAGGTCACCCACTGCTTCCATGAGAAACCCATTCTAGGGCCTGGCGA +AGTTGAGCCTAGGAAGGGCTGGTCTGTGCTCCACTCAGCAGCAGCTGGGAGAGGGCCAGG +GCCAGGCTGACCCCAGCACAGGCCGCTGTCTTGGCCTCCACCCACTGGAGCAACATTTGC +CCAGGGGAGCCAGTGGCATGTGAGGAGAGGGGGCCAGGGCTCACCATTTCTCAGACACAC +TGGGGCTGGGAGTTGCTGCTGGCAGCCTGCTTGTCAGCTGCATACCACCATGGCTGCAGG +TAGCTCAGCCACACCTCCAGGACCTGTGGGGGAGGTGTGTGCTGAAGGCCCAGTGGCTGG +GGCCAAATCCTCTGATGGCCTGGAACCCAGGTACCCAGGTGGCAGCTAAGTTGGCTCTTC +CCACGTCCCCCAGAGGGCGCAGGAGAGACGCGCACAGCCCTGTGAGATTTGGTTCTCTCA +CTGCTCTTCAGAAGCCAGGGTCATGGGCGGGCTCTTCCCGGCCCACGGGACCCAGTGCTA +CCTGGTTGCGTAAGAGTAGAAACCTGTCTGGCACCAGACAGGTGGGATGGGGCAGGGCTT +TGCTGTGCCTGAGGGTTGCCTTTGGAAACTGAAACAGAAAGAACAACGTGGCCCTCCAAG +GCCCCCTCCTCTCCAAGGTCTCTGTGACAACACTTGTTCTCCTTCATCCACCCCAGGGGA +CCTCCCTCATTGGGGCACACAGAAGACACAGGCACACATGTGATGGGGCCGACACTCCTA +GCTCTGAACAATGCGTCCAAGGGCCAGTGGCCAAAGCAATGCCGCAGGAAGAGGTAGAGT +TTCTGCTGGACTAACCTCGGGACAGCGGCCTGCAGAGGAGGGGAGGGTCACCAGCCGCTT +GCACAGTAAGGTGGCCCTGCTCACAGATGAGCCCGGGGTTCCCATTAGTGAGGGTTGGCT +CTGCTGGGAGAGAGCACTAGGCACTTCTGAGTGGTAAGAGCTGGTTTCAGCCCCATTCTT +CAGAGGAAGAAACCGAGGTTAGGGAGCATCCCGAGGACACAGCATGCAGGCGGCCAAGCC +ATTGCATCTCCTGCACACACCTCACCTCAGCCCCACACAAAACAGCCCACTCTGCCAGCC +CCGATGGGCCTGGGAGTCAGGACCCGCCCCAACCCTTCTCCTGACGGGTGGGGAGGAGCA +AGAGACGGCACCGTGATGGGGCCTTTTTGGCCAGTCTGGAGAGAGAGGCTCTGGGAGCCA +GAGATCAGCCGGCAGCCCCACCAGGCTAGCTGAGAAGGCACTTGCGTAGCCCTCCAGAGG +CCTCACGTGCTCTGTGAGCAGGAAGGGATTCCCCTCACCCTGCCCCCCATGCCCCGGGGA +GAGGTCGCCGTGGGCAACACCGGAGGAGGGGAACGAGGAGGAGACAGCAGCGGCTGGAAG +CCGCAAGGGCCACCCACTGTTTGAACTCCCCCAGCGGGCTGGTGGTGTGGGAGTGGACGA +AAGGTGAGACCTGCTCTGGCTTCAGGCTGTCGGCAAAGGCGTGCAGGTGCTTCAGTGGCA +GGCGCACCACCAGCATGTGCCCCTTGGTGGGCATGAACGACTCCTAGGTGGAGGAAGAGG +AGTCAGGGCCTGGGAAGGGCTGCAGCACGTGGCCTCCAGGTCTGACCACAGCCCGCCCTG +GGACAGCTGATCTGCCTCCACACAGGAGGCACGAGCCAGGCAAAGAGTGGGGCCACCACT +GTGCCTCACACCCAGCGGGTGTGCCTTGCACTGCTTGGTCTGAACTGCGACCAGCTCGTG +GTAGGGAAGTGCTTGGCCCAGCGCCCACACAGCCTACCTGGGGAGAACTCGCTGAGACAG +ACGCATCTGCTTCTGCACCGCTGCACACCCGCGGTGGGTGGCACAGGGCTATGGCCCGCC +AGACTGTGCCCTTGGCCATTGCTGCCTATCTTGATCCTCATGGCAGGAGGAGGCCGATGT +CACCCCCAAGCTCTGGATCCAGGGTCTCCCAGGGAAGATGGCTAAGGCCAGGAATTCGAG +ATTCGCTTGGGCAACATAGGGAGGCCCTGTCTCTACAAAAATTTTAAAAAGTTAGCTGGG +CATGGTGGTGTGCACCTGTAGTCCTAGTGACTCAGGAGGCTAGGGTGGGAAGATCGCTTG +AGCCCAGGTGTTCTTGGTGCAGTGAGCTAGGATCGTGCCACTGCACTCCAGCCTGGGTGA +CAGAGTAAGACCCTGTTCAAAAAATAAGAACCTTCACTTTTCTCCCCAATTCCTTCCATC +TGCTCCTCATTCTGGACACAGCTGGATGAGGGCTCACCCTGGGAGAAGCGCTGGGCATCA +ATTCCTCTGTTGCCCACAGACCTGTGGTCAGGAAAACCCCAAGACAAGAGCACAGTCAAG +CTAACAGGCCAAGCTTTTGATTTACAATGTACAAGCAGGATCCTGGAGACCTACACCCAA +GAGGAAAGCCTTTTTGCTGGCTGTGGGCTTTCTCTGGTTGCTCAGCATTGAGAGGGCAGG +GGGGAGCATCAAGAGTGGATGAGGGCAGGAGAAGGGGGCACTGAGGGTGGGCCCCTGAGT +CCGAGTGGACATGCTCGCCTCTCCATGCTTACCCCCAGCCCTTTGGGCCTCAACACATCT +GTGATGCTGAGACTGGTGCAGGGCCCGGCCTCTGGGTATATCCTGGGATGCTGCAGAACC +CACATGGACCACTGCTCACATCACTGCCCACTCAAGTCTGCCCGTCAGGAAAATGTCCCC +ACAGGTCCAGGAGACACACCCCACAGATCAGTGGCTGAGGCTGGGAATGGAGGTATTTTC +TTCTTCTTCTTTTTCTTTTTTTTTTTTTTTTTGAGACAGGGTCTCACTCTGTCACCCAGG +CTGGAGTGCAGCAGCACAATGTCGGTTCACTGTAACCTCTGCCTCCTGGGCTCAAGGGAT +CCTCCCACCAAAGCCTCCCGAGTAGCGGAGACCAGAGGCACATACCAACATACCCAGATA +ATTTTTCTATTTTTTTGTAGAGGCAGGGGTCTCATCATGTTTCCCAGGCTGGTCTCAAAC +TCCTGAGCTCAAGCAATCTGCCTTCCTTGGCCTCCCAAAGTTCTGGGATTCCAAGTTTGA +GCCACCGTACCTGGCTATTTTCTTCTATCTCTATCTTTAAGTATTTAGGCAATGAATTTG +CATTGCTTTGGAAGGAAGGAGAAAACCAGTACCTATACGGCCCGACTAGAATGGTACTAG +TGGGGTGGGAAGTTAGACCAGGGTCCTTCTCCTCCAGTCTCACCCCTGGCCCTCCCTCTG +ATCCTGGCCTGGGATCCTGAGCCATGACATCCTCCCTGCAGCTCACGGGAGGGGACAGCA +TCCACATAGGAACTGGGAACCTGCCTTCCCCTGCAGGTTCACTTACCCAACATCACCTGG +TCCTTCCAGAGGGTCTGGAGGGGCCAGTGTCTGCCCCTGCCCCCAGCAGTCACATGAAAG +CCTCTCAGGCTATTTTCCCACAGATTTGCTGAGCCAAACTTTTCCCTCAGCTCTGTACCC +CTCCTGGGCCACATTCCCATGTGTAGTCCCTGGCCACAGTCACACCTGCTTGCTTCTCAA +AGATGTGTACCCAAAGCCCCGCATTTCCCACTGGGCCCAGCCTCACAGCACCTCAGCTCA +CTCCTCCAGGGTCTCCCTGGTCACCTGTCCTGCCATGGGGGTTGCTAGATGCTTCCTGGA +CACTGCCCTGGCCCAAGCCCTCATGTCCCTCTTCTCCAGTGGCTCCTGCGGAACAGGGAC +GCCATCACATGCAGTGGTTGCCATCCCAACCCACCGGCACTTGGGGCCCACATGTTTTTT +TCATCTTGCGCTCAAATTCCCATTCAATCACGTGTGCTCCTTCGCAGGGTGAACGGGACA +GACCCCTGGCTGTGGGCACAGCTCGTCTCCCCGGGCTCTCACAGACTCACTAACTCTGTC +GTCCCCGAAATCCCCCATGGGCCTGAACTCTGCTTCACTGACCTCAAATCCATCCATACG +CTTGTCATTTGTGCCTAGGCAGACCACAACCTCTATGAGGTCACTACCTATTCTCATCCA +CCTCCACAGGTGTCTACGAGTGGCCAGGGCTCCCTAGGTGAAGGACTGACAGCCTCTGTG +AGCTATAGGGCCAAGCCCCAGGTCCTCCCCAACCCCCTTGCCTCACACACAGTCTGGGTC +ATGGAACCTCCAAGCTGGATGACAGTTCTGAACAGGGCAGCACCCACATTACCGTAAGTC +CCAGGCCTCTGTGTCTTCAGCTCCTTCCTTAGCACTGGGCCCTGCAGAGTGGGGGTGAAC +CGGGCCACTGCAGAGGCCTCACGACTCCAGCTCTTCAAACCAGGGCCGAGCACAGAGCCT +CCAACACCAGAGAACTTGTGACACCTCCACCACTGGTGGGGAGTCTGGCCAGCCCAGGCC +ACATGCCTCATTCTGACACACAGCCACACCCCACTCCCACAAGCCAGGCTAGTCTGCAAA +GCCAGGGGCCAGGCCAGGCTGGAGGCTGATCTCTGCCTCCCTCAACACAGGGGCTTCACT +CTGCCTGAAACTAGCCTCTGAGTCACCTGCAGCTGGGCCCAGCCAGCCCCTTGCTTTGCC +AGGCGCAGACACGCACTCCGGGCAGGGGAAGGGAATGAACGAGCACAGCCAGTACTTGGT +AGGTGTGGAGGGCCTGGAGGTTGGGCTGCCGGGGGCTGTGGTGGGCACTGGAGACACAGA +GTCGGTAGTGCAGCACCTCCAGCTGAGAGAGTGAACAGAGAGAAGCCGGAAGAGGCAGAA +GAGAAAAGCATGAGAGGACAGGGTGGTGAAGGAGAGACATGGTACCGGACATGGGAGGGG +GAAGTGGAGAAAGAAAGCAATGAGAACGAGCCCAGAAGTGAGGAGAAAAAAACAACAAAA +GCATGGTCAGTGACCATCCAAACAACTGCAGTCCCAGCAGCTGTGACCAGCGCAGCACCC +TCCTCGGCAGCCAGGCCAGAGCTGTGACAGCACTCTCCTCAGCCTTGGAGGCTGGGGGCG +GATAGACCCTCCAGGTCACCTGGGTGGCCTCTCAATGTCGCTGGGGCCTAAAGGCCTCTC +CAGCTCATTGGAAGGGCCCAACTCACTGCCCTTCCAGATGGGACCCGCTCTCCCCAGTGA +CTCTGAGGCCACACCGTGTGTGCCATGTGCACACCACAGCCCTTCAAGTACCCAGGGCCT +TCTCTCTGGGACATGCTGTCAGCCACCAAGGCCTCAAGATCCTGAGGCCCAGAAAATAAA +CTGGCAAAGCATGTTCTAGGAGGAGGACTCTGCCTAGAGAAGACACATATGTAATTGACT +GGATTTCCCTGGGTTGTTTTGAGAAATTTATCAAATTTGTATATGACATGATCAATTCCT +ATGTCTAAAACCCAATCAATGTCCCCTCCATGAGTGGATCTCTCTGAGAGCTGAGGATGA +GGACAGGTCCCCAAGGGTAGCACAGGCTCAGGCCCCCAGGCCCTGCCCTCCGCACTCCCC +CAGCCTGGAGGTCAGCCGAGGTGGTGTGTGCATCAGCTCTGACTCCAGGAGGCAACCTCT +CCTACCGCATCAGGAACTCCCACCCTCCAGATATGGAGGGCTCCCAAGGGCAGGAGCCCC +CGAGGACCTGGCCACAGCCACACACACCCAGAGGCAACAGGAAACTGAGGCTAAGCTGGC +CCCCAGCCAGGACCCTCCAATCTACCACCCTGCAGCGCTGCAGCCTCCGAAGCACCCCTT +CGGCCCAGCATAGCCAGAGCTGGCCTGGTGCATATCCTGCCCCGTGAGCGCCATGCCTCC +TGCCCAAGTAGCACGACCACTGGGCTCCACACAGGAGACATCAGAACACACCTGCTAGAT +GTCACAACACGCAGAGCAGGGCGGGAAGGAGCAGGGCAGAGAGATGTTGCCCTTCACAGC +CTTCCTCTGTGCCAGACCTAGGGCTCAGGCAGGAAACAGACACACAGTTCTCCAGTGCGT +CTCTGCCCTTGCCTAAGGAACACGGTGGCTTGTGGGGCCATTGGCCATCTTTATGGCCCA +CGGGGCCACCAGGGAGCAAGCATGCACCTCGGATTCAACCAGGGTGTGGAGGGCAACCCT +GGGAGCCTCACTTCCTGCATCTGAAAATAAGAGCTAGCAGAGACAGGCAGGGATTTCTGT +ATGGCAGGAGCAGCATAGGCCTGGGCAAGCGGCAAAGGGCCAGGGGCCTTGGGGGCCCCG +ACCTCCACAGCTGCCTTTCTCTGACCCCCACCCACCCAGTTTTCTCACGTTTTGTTTTTT +GCCTCAACTGGAAGAGGCAAAAAGTGGAGCATCTCTGGGCACTTCGTCCCACCACTGCAA +GTCATTCTGAGCAGGACTCACGCAACCCAAGGTCTGGCCAAGAGGAAGCGAACATTGAGA +AGAGGGGAAAGGCACCTCCTGCCCTCTGCAGGGACGACGCCTTGCCAGTTCCCCTGACCC +ATGAGGACACAGAATCCTCACAGGTGACAGCCCAGAAGAGCCTTTCTGGCTTGCCCTTGA +AAGTAGGTGTGTTTCCACTCACTCAGTAGGCAGAACCAGCAGATAGGAAGGTGACACAGT +GCAGCGGCCCCTGCCCCTGCCAGGTCAAGCCACATGCAAGAGCGCTGAGCAAGTGTTCTA +GGGCGCCAGGGAGAAGCGGGGCCCTAGGAACCAACCAGCCCCCCAGGCACCAGCCAGGCA +TATGCAGTAAGTCTGCTCTGGAAGCGGGAAGGGCACTGCAGGCTCTTTGTGACTCAGGAG +GCCCAAGATGGGGTCCCCAACTTTTCCTTGTGCTCCTTCCAGGTGATGCTGAGGGTGAGG +ATTTGGGGGAACCTATGCTCTGAGAGAGCCTTCACATGGCAAAGCATGGGGCCACAGAAC +TGGCTGCAGAGGCTGTGGCAGAAACAGACCCACAGCTCTTCTCCAGAACCGGAGGAAAAG +TGACAGGAGGCTCTTCTGAAGTTTAACTCCATCACCCACAGATCCTTCATTCTGGATGAA +GCCTTCTGGAACTTTGTCAGCAATAAAGGCAAAGTCTCCCATGCATAGACGCCACGGGCA +CCGGACTACAGGATGTGTGCCCAGGGCATGCTGCCTAGAGAGAGAGTGGGGAGAGGCGAG +GCGGAGGGGGAGGAAGCAGGCCAGGCTGCTTGTAGGAGGGCGCCAGGCCCCACACACCAT +GAGTATGGCGGCTTGCTCATGCTCTGGAGGAGGTGGGGGAGTGGGGGGCAGACAAAGGAG +GCTAACTATGGTGCCACTATGGTGGGCATGGGTCTGCCCTGGGCCATCACTTCATGGGAA +AGCACAAAGGCACTGCTGATGGTGGAGGAGACAGACGAGAACGCGGCTCCCAGAGGCATT +GCAGCTCCCCCACCCCCACAGCAAAAGTGCCACAACCTCATCTGTTCCTGTTGCCAGGGA +GGGGGCTCCGGAAGCTGCACAGGAAAGGCCCTGGAGAGGCCAGACCTCCAGGCCTCAGTG +TCCACATATCAGGGTGCAATGCCACCTGCTCCTCATCGGGAACTAGAGAACTATGCCCAC +TTCTTATTCAGCTTCTGAATGAAGGGTGGGTGGTGGATTTCTGCTTCCCACCATCCGGTC +TGTGAAAACTCACTCAAATGCAGGATAAGAAGCAGCAGGCTGAGCATGGTCAGAAGCAGG +AGGTGGGAAGAAAAACTATGGAAACCTACCTTGGCATGAGGGGAACTGCATTTTTTGGTA +CATCTCCAGAGAATAGTGTTGAAGCCACATTTCGACAAAAACCTGCAAAAGAGCATTACG +TAGTCAAATCATTCTCGATAACTGCCAAGACCATTCAGTGGGGAAAGGACAGTGTCTCCC +ATAAGCAGAGCTGGGAACACAGAACACCCTCATGCAGAACAGTGAAGCTGGGCCCTGCCC +TCACACCATCGACAAAAACTAACTCAAAGTGGGTAAGCGGCCTGAGGATAAGAACTAAGA +CCATAAACTTACAGAAGAAAACATGGGAGAAAGCTTCATAACACTGGATTTGGCAATGAT +TTATTAGATATGATGCCCAAATCACAAGCAACAAGCAAAAAAATACAGCATCAAAAGATA +CTACTGATAGAGTGAAAAGAACCAGCGGGCATGATGGCTCAGGCCTGTCATCCCAGTGCT +TTGGGAGGCCGAGGCAGGTGGATGGCTTGAGGCCGGGAGTTCAAGACCAGCCTGGGCAAC +ATAGCAAAAAGTTGTCTCCACAAAAAGCACAAAAATTTGCTGGGTGTGGTGGGGCACAGC +CATAGTCCCAGCTACTGGGAGTCTGAGGTGGGAGGATCGCCTGAGCCCAGGAATTTGAGC +TGTAGTGAGCCAAGATCATGCCACTGCACTCCAGCCTGGGAAACAGAGCGAGACCCTGTC +TCAAAATAAATAAATAAATAAATAATAAAATAAAAATAGAAGCAACTCCAGTGTTCACTG +AGAGATGAATAGATAAACACAACATGGTACATCCGCACAAGGGAACACTATGCAGCCTTA +AAAAGGAAGCAAATTCTGACACATGCTGTAACATGGATTAATCTCGAATCCATTATGCTA +AGTGAAGCATGCCAGTCACACACAAAGAAGTACTGTGTGCTACAGAAAAATGCTTTAGAT +ATGAGATCTAGGAGTCAAACATATAGAAACAGAAAGCAGAATAGTGGTTGCTAGGGGCTG +CGTGGGGAATTAATTGTTCAGTTTCTTTTTTTTTATTAAAAGAGATGGGGAGCCAGGCAT +GGTGGCTCATGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGTGCATCATGAAGTC +AGAAATTCAAGACCAGCCTGGCCAAGATGGTGAAACCCCGTCTTTACTAAAAATATAAAA +ATTAGCTAGGCACCGTGGCAGGTGCCTGTAATCCCAGCTACTCAAGAGGCTGAGGCAGGA +GAATCACTTGAACCCGGGAGGCAGGGATTGCAGTGAGCTGAGATCGCACCACTGCACTCC +AGCCTAAGCGACAGAGTGAGACTCTGTCTCAAAAAAAAAAAAAAAAAAAAAAAAAAAAGA +GAGAGAGAGACGGGGTGTCACTATGTTGGCGAGGCTGGTCTCAAACTCCTGGCCTCAAGC +AATCTTTCCCACCTTGGTCTCCCAAAGTGCTAGGATTACAGGAGTGAGCTCTCATGCCTG +GTCGGTTCAGTTTCAGTTTTGCAAGATTCTGGAGATTGGAAAGGAAGCAAATTCTGACAC +ATGCTGTAACACGGATTAATCTTGAATCCATTATGCTAACTGAAGCATGCCAGTCACACA +CAAAGAAGTACTGTGTGCTACAGATAACAACAACGTGAATGTATTTAATACTACTGGCTG +TACACTTGGAAATGGTTAAGACAGTAAATTTTATGTTATGTATATTTTACAATTACAGTT +TTTTTCTTAATTAAAAAAACGAAAAGCATTAATGCTTTGGTCCAGGAAACAGCAGAACCT +TCCAGTTCTGTCCTGTTGTAAGCTTGTGTCATGGTCTCCTGCCCTCTTCACAGCCAGCAC +ATCCCATGGTCCACACAGCCAAGAGCCATCTGGGTATCATGGTCCCCTCTGGGGACCATG +CCCCTCCCAGGGACAATGGTCCCTATCATTCTAGCACCCGAGGTTGTTGTGAAATGGTGT +GGAGGCTTCAAAAAGCACGGCACCCCACATATTAGGAGTTATGTACAAGGTCGGAGACAG +AATCCTATCTTATCTACTTCCCAGGTGTCAACGGCGAGGCTGTGGCTACCAAGTCAGTCC +TAGGATCCAGTGTCAGGAGCAGCACCTGCCAAATCTCTCCAAGTTATGCTCAGAAGACAC +AGCCAGGACCTGGTGGATAGCACTCAGGGAGTGAGCCAGTCCACACCATCGTGAGAGGCT +GGAGCCCCCCAGGACAGACAAGGGACTCTGTCACCTACTATTTGGATCCCCTGAATCAAC +AGAAGGCCTGTGGAGGCTGCACAAACCCCTCACCATTCCGTGTCACAAAAGTGCTACTGG +GGCAACGCTTAATATCCACATGATGGTAATCATAGGAAGCATCTCCAGCAACACGAGAGA +CGGACACCAAGAGACCGCAACAATTATATCACAATGGGCAAATGAAACGACTCCGATGGA +CAGGGGATCCTGGGATGAAAAACACCATGAATGACAAGTAAGTTAGGTGGGTGGGCAGAC +TTATATTCATGTTTTCTAAATGTCATACCAGGAAAATGCCAACAATTTAGAATCAGCCCT +GGGCTAAGCGGCCGCCTCTGGGACTCTGACCCATATAGTGGAAGATGGCTGACCAGTTTC +TTTTGAAACAGACGTTGAGACCAGCTCAGCTCTCACCCGGAGCAGAGTTTCTGACCTCCA +GATCTCCTGGGAGGCGGGGTCTGCATTCACAGACATCTGATGAGAGAAGTGTCGCTTCAG +GGGGCTAGTGTGCTGGAGGCTACAGGAAGCAAAGGGCATGGCTGGTGTCCTGAGGGAGAC +ACGGAAACAGGCCCAAGGTAGGAGCTCCTGCTGGCCAGGCCAGGGGCGATCTGGACATCA +AAATCAATGACAGCAGGGACGTATTACAACTTGTTCAATTGCACAATGCACAAACCTCAC +CCCTGCCCCAAATCCACACTGATACACCTGAATAAACAAATAGCAAAGAGAAAAGTCTTC +CTTCCCGCAGAGCGACCACTGACCCAATACAGGAAGAATGAAGTTAGGGAACCACCACTT +GGCAACTGCCCTATTAATAGCTTATTTGGTCAAGAATCAAGTGAGGCCAGGCATGGGACC +TGCGTGAGACGCCTGAAATCTCAGCACTTTGGGAAACCAAGGCAGGAGGATCTCTTGAGG +CCAGGCACTTGAGACCAGCCTGGGCAACACAGTGAGACCCCGTCTCTACAAAAACATTAA +AACATGAAATAGCTGGGCACGGTGGGGTGTGCCTGTAGTCCTAACTACTTAGAAGGCTGA +GAAGGGAAAATGGCTCCCTCCTTGGGCCTAGGAGTTGAGGCTGCAGTGACCTATGATGGC +ACCAACTGCACTCCAGCCTGGGGTGACAGAGCGAGACTCTGTTTCTAAAAAAAATAAGAT +GTCCAGCTTGGGCAACATGGGCAAAACCCATCTCTATTAAAAAAAAAAAAAAGCATTCAG +ATGTGGTGATGCATGCCTGTAGTCCCAGATACTTGGGAGGCTGAGGCAGGAGGATCACTT +GAGCCTAAGAGATTGAGGCTGCCGTGAGCCTAGATCATGCCACTGTACTTCAGCCTGGGG +TGAGAGAACAAGATCCTGTCTTAAAGTAAAATAAAATCAATTTGAAAAAAGGAAAGAATC +GACTTCTCTGTGTATGGAGTAGCCCTTCTTCTATTCCTTTACTTTCTTAATAAACTTGCT +TTCACTTAAAAAAAAAGAGAAAAGAATCAACAGTTGATGTTAATACTAGTGATAATACAT +AGTCTCTATACATCTTCCCGGTAAATCATCATTACCAATTTTTCTTTTTTTTGAGACAGG +GTCTCATTCTGTTGCCTGGGCTGGAGTGCAGTGCTGTGATCACAGCTCACTGCAACCTCA +ACCTCCTAGACCCGGGCCTCCCAAGTAGCTGGGACCACAGTGCACACCACCATGCCTGCA +TGCCTGGCTAATGTTTTTCTTTCTTTGTTTTTTGTTTTTGTTTTTTTTTTGAGACAGACT +CTCACTCTGTTACCAGGCTGGAGTGCAGTGGCTCCATCTCGGCTTACTGCAATCTCTGCC +TCCCAAGTTCAAGCGATTCTCCTGCCTCAGCCTCGTTAGTAGCTGGGACTACAGGCATGC +ACCACCACGCCTGGCTAATTTTTTGTATTTTTAGTAGAGACGGGGTGTCACCATGTTTCT +CAGCCTGGTCTTGAACTCCTGACCTCATGATCTGCCCGCCTCTGCCTCCTAAAGTGCTGG +GATTACAGGCGTGCACCACCACACCCAGCTAATTTTTGTATTTTTAGTAGAGATGGGGTT +TCACCGTGTTGACCAGGATGGTCTCGATCTCCTGACATCGTGATATGCCTGCCTTGGCCT +CCCAAAGTGCTGGGATTACAGGCATGAGCCATTGTGCCTGGCCAATATTTTTCTTTTTAG +TACAAACAAGGTCTTGCTATGTTGTCCAGGCACTCATTACTAATTTTTTTTTTTTTGAGA +TGGGCTCTCACTCTGTAGCCCAGGCTGGAGTGCAACAGCATGATCTTGGCTCAATGCAAC +CTCTGCCTCCTGGGCTTGAGTGATCCCCCCACCTCAGCCTCTAAGTAGCTGGGATTACAG +GCGCATGCCACCACGCCAGGCTAATTTTAAAATTTTTGGTAGAGATAGGATTTTGCTATG +TTGCCCAGGCTGGTCTCAAACTCCTGAGCTCAGGTGATCCACCCACCTTGGCCTCCCTAA +GTGCTGGGATTCCAGGCGTGAACCACTGCACTCAGCCTCATTACTATTTAATCTGGGCAC +GAAGTACTTATTTTACAGTGGACAAACCTGGCCGACACCCTTTCCACCCAGTGATAAAGC +TAGCATCACCAGTGATGGGGCAAAGGGGCACTGCAGGCCTCCTGATGAGACACCTGGCAA +GGACCAGGTGTCCCCGCTGCAGTGCTCCTGCCAACAAAGCCCAAGCTATGCCTAATCACC +AGCAAATACAAGACAGCCCAAGGGGTGGCCACATGCTTTGGAGGGGTCAAGGTCAGGAAA +GACAGACAGGCTGCAGAACCATTCCGGACTGAAGGGGACTAGAAACATCACTGCATGCAG +TGGGTGAGCCTGTGCTGAAACCCAGCCAGGTAACGGGCATGAGTGGGGTAGCTGGTGGTG +AACCCCGAGGTCTGATGACTAGGTGTAGCCTGGTGGCAATACTAACTTCCTGGTGTGGTG +GCATGTGCTGGCTTGCACATGCCAGCAGATCTGGGGTGGGCCAGCATCTGCAGAAACGGG +CCTGTATGCAGCCTCCTGGGGAAGGCAATGGGGCAGCAAGATTAAGGAGGGTCAGAGGAG +CACACGCACTGTGACTATATAAGATAATGCATTCACTTTTAGGAAATACACTGACATATT +AAGAGGCCAAGGGGTGTCCTACCTGTAGTTTATTCTTATTGGCTTAGGGGAGAAAAAACA +TATCATAGAAAGGGGATAAAGCAGATGCAGCAAAGTGTTAATTTGGAAATCTGGATGAAG +GGTCTATGAACTTTTTTTTTTTTTCTGAAACAGGGTCTTCTTGTGTCACCCCAGGCTAGA +GTGCAGTGGCGCAATCATAGCTAACTATAGCCTTGAAGAGTGCACAAGAGATCCTCCCAC +CTCAGTCTCCTGAGTAGCTTGGTCCACAGTTGCACGTCACCATACTCAGCTGATTTTATT +TTTTGTAGAAATGAGGTCTCCCTATGTTGCCCACACTGGTCTCAAATTCCTGGCCTCAAG +TGATCTTTCTGCCTTGGCCTCCCTAAGTGTTGGGATTACAGGAGTAAGCCACCATGCCCA +GTCTGCAAGTTCTTTTTATTATGCGTGGAAACTTTTCTGTAAGTCTGAAGTTATTTCAAA +ATAAAAAGTTAGCTAGGTGTGGTGGCCTGCGCCTGTAATCCCAGCTACTTGGGAAGCTGA +GGCAGGTTCACCCTCCCAATCCGTGCAGTATGGCATCAGGCTCAGCCTGTTTGGTCTGGC +ACAACAGGCTCTTTGGCCCAGGGCCTCCCCCTCTCAAGACCTGCTCCTGGGGCCAATAAA +GGATTGTGGAAGCTAGGAGTTCAAGACCCACCAGGGCAACACAGCAAGCCTCCCCTGTCA +TATCTCTACAAAAAAAAAATGTTTTAAAATTATCTGGCTGTGGTGATGCGTGCCTGTAGT +CACTGAGGTGAGAGGATGACTTGAGCCCAGGAATTTAAGGCTGCAGTGAGTGACGACTGT +GCCGCTGCACTCCAGCCTGTGTGACAGAGTAAGACCCTGTCTTTAAAAAGACATAATGAC +TGAATGTGGTGGCTCATGCCTGCAATCCCTGCACCTTGGGAGGCTGAGGCAGGAGGATCA +TTTGAGCCCAGGAGTTCTAGACCAGCCTGGGCAACATAGCGAGACCCATCTTACAAAAAA +TACAAGCTGGATGTGGTGTTGCACACCTGTAATCCCAGCTACTCAGGAGACTGAGACAGG +AACATCACTTGAACCTGGGAGGTGGAGGTTGCAGTGAGCTGTGATCACAATACTGCCCTC +CAGCCTGGGCAATTGAGCAAGACTCTGTTTCCAATATATATATGTGTGTGTATATATACA +CATATATATATTATACACACACATATATATAACATAAATGTGTATATATACACACATTAT +ATATATATAATTTCTAAAAGAAAAAATTAAATTACAAAAAAACTCAAAAGCTGGGCATAA +AAACCACTTGGCAACTGAATTGTACATCTGAGAGGGTGTGAATCCACCTCACCTCCAAGT +CCTCCACAGCATCAGCAACATTTCAGGGTCACTGACCACTGCCGCCACCCAGGCAGCCTC +TCCTCCTTGCTGCTCCCTTTCTCCCCTCCACCCTCTGGGGCATCTGTCCACACATGTGAA +TTGTAGGTAGAGGCCTGTCCTGGCTTGCACATGCCAGCAGATCTGGGGTGGGCCAGCATC +TGCAGGAAGGGGCCTGCACGCAGCCTCCCAGGGAAGGCGATGGGGCAGCAAGATTAAGGA +GGGTCAGAGGAGCACAGGCAGCTGCTGCCTGTGCAGAGGGTCTCCTGGGAGGTCCCCAGA +GGGTCTCCTGGGAAGTCAGCCAAGAGGCCCTGGGTTAGGGCCCACTGAGACCCCAGCACA +GCTAGGCACAAGAGCCCCTGGTTCACACTTCCCACCTGTGCAGTCACCAACAGGCTCAGC +TTGTTTGGACTGACACACAGGCTCTTTGGCCCAGGGCCTCCCCTTCAAGACCTGGTCCTG +GGGCCCAGAGAGATTTCCATTTTTTTTTCCCCCATAGAACAAGCCTTCTGCCATGCTCAC +CACCTCAGACACTGCATGTGGGGAGGGCTGCTTCATGCAGAACACAGCCCATTCCCATGC +AGGCCGTGGAGGCCTCCAGAGACCTGATAGCTTCAGTGATGGCCACAGACATCGAAAACT +AAAGGACAGATCACCCTCCTCACCCCCACCCTCCAGTCTGTGCTAAGAAAGCTGGAGGTG +GGGAATGAGGCATAAGACAAATTTGGGAACCCTGGACAAAGGGTGGCACCATTGTCCTGG +TGGGTGATTCAACTGACCAGGCCACTCCCTTATGGAAGGGCCAGGTCTTCACAATCAGGG +TAGCCTTACCTGGGAGCAGGTGAGGGACTGGCCCATCCTGGGCTGGAGGACAGTGAGGGT +GGTGGCAGGCTGCCTTTGGTGGGCAGGAACCATGACAGGTACCTGTCCACCAGGAGGAAA +TAGGTACAGTCTGAAATATGGACATGGAGAGACACAGGGAGTGGCTGGAAAACCAAGCTA +GTTCTTAGCATGGGGTCTGGGCACTGCCTGGCCCCAGAGCACTGGCAAGTGCAGGGAAGC +CCCGGGCCATGCCCCCACCCCTCCCAGCAAGAGGCATCCCTTCCCTACCTTTAGTGTGTT +GAGGCTCAAGGCAAAGAAGCATATGTAATACTCGAACGGATCTGATGGCAGCGTCAAGGG +CAAATACACAGGGTTGCTGGGAAACCCCCAGTGTTGAGAGCTGAGCCACCCACAACCTTC +CTACCTCAAGGCCACCAAAGGATACTCAAGGCCAGGTTCAGGCCAAGGCCCTTAGTTGGG +CGGAACTGGATCTTGTGTTACAGAGGACTGTCAAGGACGCACTCCTGGATGGATGCCTTC +ACGAGACCCTGCAGAGAGAGGCAGCAAGGCTTGTGGGCAGGCACTGGCGTGTAGTGCCCG +GTACGCAGTGCCCCACATGCACAGCAGCCCTTTGGGAAAGCTGCTGGGGAAGAGACCCGC +ACACAGAACTCACCTGTGGGGACAGTGCCCTGCTCCTGAGCAGTGCCTCAACAAGAGTCT +TTGCTCAGAACTTCCACCATCTCATAAAAAGCTGCAGACAGGCCAGGTATGGTGGCTCAC +GCCTGTAATCCCAGCACTTTGGGAGGCCGAGGTGGGCAGATCACAAGGTCAGGAGTTCCA +GACCAACTTGGCCAATATAGTGAAACCCCATCTCTACTAAAAAAAAAATACAAAAATTAG +CCGGGCATGGTGGCATGCATCTGTAGTCCCAGTTACTTGGGAGGCTGAGGCTGAAGAATT +GCTTGAACCCAGGAGGCGGAGGTTGTGGTGAGCCGAGATCGTGCCACTGCACTCCAGCCT +GGCAACAGAGTGAGACTTTGCCTAAAAAAAAAAAAAAGCTGCAGATGGCAAGGGTAGCAG +CCATGCAATACCCATCTCCTTTGCCTCTCATACCCCCGGAGCAAATCACTCCTTAATTTG +CCCTCAGAGGACCGGAGGAGACTGCCCGTCACCACTGGGCTGTGCAAGGTCCACTGCCCG +AGCACCACTCTCACCACTGTGGTTTACTTATGGGCAGGTAGGAGATGGGAAAGTCAAACT +TAAGTCTTCAGCTTGAAGCTTATAAACCAACTTCATCATTGGGCCGCTGAACATGAAATT +GAACAAACAAAAACAGGGTATATGAACTGCAAATTATCTTGCTTTGATTGTATCTTAACC +TTAAGAAATTGAGAGTGACTTAAAAGTGGAATCACCATGAGGAAGCACCCTGCCTCTCTC +GGGTGTCAAACCTACCTTCCCAGGGTCGAGAAATTCCATCACCATGCTGTACTTCACAGG +ATTCACGCGCCTCTGTAAGCAGCGCAGGTTCCAGCCCACAAGGACACCATCCAGGCTGCC +GAAAATGCTACCAGCCATGGGGAGATGGCGTGCAGCTCCTGAAACAGTGTGCGGTGAGGC +TGCAGGCAGGACCAGCACCCACTCCTGCCCCAGCTCCAGGCCTGCACCACCTGCTGCCCA +GCTCCCTCTGAGGAGGCCACTCCCTGGCTGAGACCCATGGGATCAGCCCTGCGCTCAAAG +GAACCCTGGTGCGGTGATGCCAATGAGAAGAGCAGCTTTGGGTTCTTTCACTGGGGTACG +TGGCTTACCAAGCAGTGCTGCTTTAGACGTGGGCCAGTTAAGTAAGTCAGCCTCTGATCA +AAATACATTTTTTGTGTGTGATAAAAGCCTAAATTAAGGGAAAAAAAAAACAAAAAAATG +AAAAAATGAAAAATAAAATAAAATAAACAAAATACCTATTCTTTTGAGACAGGGTCTCAT +TCTGTTGCCCTGTCTGGAGTACACTGGCGCAATGCACAGCTCACTGCAGCCTTGGCCTCC +TGGCCTCAAGCAATCCTCCTGCCTTAGCCTCCTGAGTAGCTGGGACTGTGGGCACACACC +ACCACGCTCAGCTAATTTTTAGATTTCTTGTAGAGATAGGGTCCCAGTATGTTGCCCAGA +CTGGTCTCAAACTCCTGGCCTTAAGTGATCCTCCCACCTCAGCCTCCCAAAGTGTTGAGA +TTACAGGCATGAGCCACCACACCAAAAGATTTTTTTTTTAATGTCAGAAACTTCTGATGG +ATGCGAAGGATGCTCTATTAGAAAGGAAAGCAACACCCTTCCCAGAGTGAAGCCCTTAAA +ATCTAACTGACCTGTTGTCATTTGGTATTAACTCCTTGTCTAGGCCAGCTTCCTGGGCTT +GACAATTCCAGGTGTGATTTAAATACATATTTTTAGCATTTACATCAGGGTTCCTCAACG +TTGATGCTATTGACATTTTGGGCTGGATTCTTCTTTGTTGCAGGGAGCTGTCCTGTGCTT +TGCAGGATGTTTCCAGCATCCCTGGCCCCTACTTACTAGATGCCAGTAGCACACACTCCC +CATCACCCCCAGTTGTGATAATCAAAAATGTCTCTGATATTGCCAAGTGTCCCCTGAGGG +ACAGAGCACCTGTGGTTAAGAACTCCTGATCTGCAAGTTCACATATTTAAATGTGTCCAT +AAACATGACGGTCATGATAATGGGCCAGGACTCTGTGCCAGGCAGTGCTTGGAGTGGGGG +TGGTGGGGGGAATTAGGAATTATAATAAAGTTTTTAAAGGAATGTGTAAGACATGCTCCA +AAGAGAGATGTCAGCAGAGCTATACCTCTGCTGGAAAATCCTCAATGACTTTAACCAAGT +CTTGGCATCACTGTGCAAAGGGCTTATTTACAGAGTCAGCTTTCAGGGTAGCCTAGAAGG +TAGAACAAAGTGAAAAAATCATGAGGACATTCACTGCAGCTTTTAGTGATACTCTGGCTT +GAGTCAAACAGAAATCCAAGTGATAGGTTATGAGTCAGACACATAACCACTGGCGTGATT +CCCCAGCCCCTCATGTGTGTCAGTGGCCCAAAGGATGCTACTAGGAGAGGCTGTGGTTCT +ATGCACTCTGGACCAGGAACTCTCAGGCTTGCTTCCCAGTACCAACTCAGCGTGCTGCTC +ATCATCAGAACAGGACTGACTTCCACCAATCCATAAGTAGGGGTTGGCCCCAGGGTCAGC +CCCAGAGCCAGAAGAGGATCTCGATTGTGTAAGGGCACCTCTCACAGACCACAGAGTACT +ACTGAGTTCGTACGCATCAAATGGAAATTTCCCACCTGATGGACCATCATGATTACACAG +TTGTGATCATCAGTAAGAATGCCCAACAAAATCAGGGCTACAGCATCCTCTCTTAACTGA +GCTGTCTTTTATTCAGCAGACAGTGAACCTACTAAACCAATGACCTTAAAACACAGGGCA +GGGCCGGGCGTGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCAAAGTGGGCAA +ATCACAAGGTCAGGAGTTCAAGACTAGCCTGGCCAAAATGGTGAAACCTTGTCTCTATTA +AAAAAACACAAAAAAATTAGCCGGGCTTGGTGGTGCATGCCTGTAATTCCAGCTACTCTG +GAGGCTGAGGCAGGAGAATCGCTTGAACCTGAGAGGCAGAGGTTGCAGTGAACTGAGATC +GCACCACTGCACTCCAGCCTGGGCGACAGAGAGAAACTCCGTCTCAAAAAAAAAAAAAAT +AAAACAAAGCAAAACAACAACAACAAAACACACACACACACACACAAGGCAGGTAAAAAT +TATAGATGGCTTGCACCAAGTAAACACTAAACATAAAGGCAATGGAGAGGCCAGAAAAGA +CTCAGGACAAGGACTAATAAAATCTACCCACAGTCGTGGGATATACGGAAAGCATCCTGA +CTACAAGGATAAAAATAGCGTCTGTGCAAATGGACTCACATCAGGAGAAACTGCTAGAAT +CTGTCTACCTCCAAATGCCTTGTCTACCTCCAAATGAGGGTGGATTTCACAGGATTTGAG +ACAAGAGATGGAGACCTGAGTTGTCTGGCCATGTGGCAGACCTGGTGGCTCTAGTGGGGT +GCCCTGGGGAGGAACGTCCTTCCACATACATATTTACAAAAATACCTCCTAAGAACTAAA +ATTAGGAACTTTCATCACCAATACTTGCTCATACCTAACTTCTCGCTTCTCAGTATCATT +TTTTCTTTTTTTTTTTTTTGAGTCTTACTGTGTTGCTCAGGCTGGTCTTAAAACTCCTGG +GCTCAAGTAATCCTCCTTCCTCGGTGTCCTTAGTAGTTAGAACTACAGATACGGACCATT +ACACCCAGTTCTCAGCACCATGTTTAATAGTTAAAGTGCTAACCTAGCACCCCCTCAGAA +CATAAGAGTGTCTCCATTTTTCACTAATGACAATTATGATTATCAGAATGTTTCATGTCT +GTTTAAGAACTTACAGATCATGAACACTCTGATGTACATCATTCTCATTTGCTCCTCCCC +CTCCTCCTCCTCATACCCCCTTGGGAAGTAGAGAAAATAGAACTTGAATGAATTTGTCTT +GTATGGGAAAACCCAGAGCCCAGAGCCCAGCGGTTGAGTAACCCCAAGGCCCTGTAGTAA +TAAGGGGGCACAGTCAAGCTTAAGGAGTCTGGCATTGCTTCCATCACACGCTCCTAAAAG +ACAACCACTAGAGAATTCTTCAAGTCAATGGGAAGAACATTCAAGTCCCACAGCTACAGA +GCTGTGGCCACACTGACACTCATCCAGACAGCTGATATTTACCAGTAGAAAGCTGGGCCG +CTGCAGGTGAGGGAACGCCATAAAAGCCTCCAGTGGAGAGTTGAAAATGGCCTTCTTAGC +AAACCACTGTGGAAAAACAGAGACAAAATCTCAACATCTGCAGCACAGCAGAATCTTTTT +ATTTTTCTAGAGACAGGGTCTCATTCTGTTGCCCAGGAGAGAATGCAATAGCACGATCAT +AGCTCACTGCAACCTCAAACTCCTGGGTTCAAGCAATCCTTCCCCCTGAGCCTCCTGAGT +AGCTGGAACTACAGGCACACACCACCATGCCTGGCTAATTTTCTTCTTATTTTCTTTTTT +GTAGAGACAGGGTCTCGCTATGTTGCCCAGGCTAGTTTCAAATTCCTGGCCTCCACTGGC +CCTCCTGCCTTGGCCTCTTAAGTGCTGGGATTACAGGTGTAAACCACTGCACCTGGCCCT +AACAAAATATTACATAGTTTCACAATGCCCAGGAGAACATTTGTGTAACTCAACATGCAT +TACATTATCGATTCTCATGTCTTCTTTATTTATTTGTAGAGACAGGGTCTTGCTTTCCCA +CTCAGGCTGGAGTGCAGTGGTATGATCATAGCTCACTGCAACCTCAGACTCCTAAGCTCA +AGCGATCCTCCTGCTTCAGCCTCCCAAATAGCTGGGACTACAGGCACACACCACCAGGCC +CTGCTAATTTTTATATTTGTTGTAGAGATGTGGTTACATCATGTTGCCCAGGCTGGTCTT +CAGCTCCAGGGCTCAAGTGATCTACTTGCCTCAGCCTCCCAAAGTACTGGGATTACAGGC +GTGAGCCACCACGCCCGGCCAGCAATTCCCACATTTTACAGAAACACCATTCGCATGCAG +CCCACAGTGGCCAGCTTCAGAGCCAAGTCTGTGGTACTGAATCCTTGGTAATGCTTGTAC +AGCACTTGCTGTATGCCAGGACTTGCTCTATACACCACACACACTGTCAGTCCCCAGGAG +GGGAATGTGGTATGTGATGCTTCATAAACACATTGAACTCTTTCTGCCAAGGAACAGCCA +TTAACACCTTGGGGTTACTTGCAACTCACCTGTGGACTGTTGGTCTGAGCTATTGTCCAT +CACTTGCAACTCAGTGTACACAGGTTCATCAGAGCTGGTCCCAAAAGCAAGTCCAAGCGC +TGGAGAGCATGAGTGGGAAATCTCACTTCCACCTCGGATGGAGAAAAACTTCAGCAAGAT +TGTCATTTTATCTTTCCGACCCAGATGGACTCCATCTTGACTCAAAGACAACCAGAACAT +CACCAAGCATCTCCTACAGGGCAGGCTTGGTACTAGGTGGTTTTATTTAGATTATTTCAT +GGAATGTTCAGGAGAATTGCTCCCTCTTCACTCCTGAATTCTTGATGCAGTTCTTCCACT +TTCGCCCTTTCTTCTCGTCTCTGTCTCATTCAGCTCCCTCATTACAAACCTTCCAACTGG +CTGGATGGCGCAGTTGCTCAACCAGCAGAGAGCACTGGGGTAGCCCCAAATAAATGTTCA +TGTCATCTCCAAATTACCAGCACTATTCCCAGGTCCCAATTCAAGACAAAACCTTATCAG +CCTCATCAGTGAGAGCACGTTTTCACCGAGCTGAGTAAAAACTTAGGTACAAGACCATTC +AGTGGGGAAAACACTCATTTCTTTGAAGAATGGTGCTGGGAGAACTGGATATCCACATGC +AAAAGGATGAAGCTGGACCCCTACATCACACCATATACAAAAATTAAGTCACAATAGGTC +AAAGCCCTAAGTATAAACACTAAAACTGTTAAACTCTAAACAAAAAACATGGAATTACAT +TTTCAAGATCTTGGATTTGGCAATGGATTCATTCTTATTTGGTTTTTAACTTCATTGTGA +GCCAATTTAGCATCCAAAATTCCAGTAGGTTTGGTAAAAATTGACAAGCTGATTCTAAAA +TTATAGCAAAAATGTAAAGGGCAGGCCGGGTGCAGTGGCTCACACCTGTAATCCCAGCAC +TTTGGGAGGCTGAAGCAGGTGGATCACTTGAGGTCAGTAGTTTGAGACCAGCCTGGCTAA +CATGGTGAAACCCCATCTCTGCTAAAAAAAAAAAGAAAACACCAAAAATTATCCGGGCAT +GGTGGAGTGTGCTGTACCTGTAATCTCAACTACTTGGGAGACTCAGGCAGGAGAATCACT +TGAAGCCGGGAGGCGGAAGTTGCAGTGGGCCAAGATCATGATACTGCACTCCAGCCTGGG +TGATAGAGTGACTCTGTCGAAAGAAAGAAAGAAGGAAAGAAAAAAAAGAAAAAGAAGAAA +GAGAGAGAGAGAGAGAGACAGACAGACAGACAGAAAGAAAGAAAGAAAGAAAGAAAGAAA +AGAAAGAAAGAGAAAGAGAAAGAGAGAAAGAAAGAGAGAGGGAGGGAGGGAGGAAGGAAG +GAGAAAAAAATGTAAAGGACAAAGAAAATCTAGACTCTTCTTAAAGGACAACTCACCTCA +TCCTGGTCATCTTGGCGTCTTCATGATTATGAGCATGAGGACTTCTAGAATTCTCTCTCT +CTGTCCCCTGTCCTCTCTAGGATTCCACAGTCTTCCCAGGTGACCAATACTTGGGATCCA +CCTTTCAGGCAAGGTCCTCTTCTTACCCATGGGGCTTACATATCTAATCCAGTGGTTCTT +ACCCAGAGCTGTGCACTGGCACCAGGACACCCCAGGCACACTTGGGGCAGCCCCTAGAGA +TTCGGTTGGTCTAGTTTGGAGTCTTCTTCCACAAACGCGACTGTGATTGATTTACATCTG +TGACTGAATCCCTAGTGAAGATGCCTAATTGCAGCACAGTGACCTCAGTGACGCTAGCCC +TAAGCATAGCCACCCAGAAGAACAGGGCATTTGGCCAAGCGAGAGTGGTGTTCTGAGGAG +GGTCCTGGTCACACACCTCCATCTGTCTCCACACCTGTCTGGCCATCTGGGCCCAGCTAA +TCGGAGTCCAGTACCTCTTTTCTTGGTCTCAGGCCCACACAGCTTCACTCTTCGCATGTA +AGCCATGCCCCTCTGAATTTCTGATGCCACTATCTTATCTCCAGTGCTGGAGTTACTACT +TCTTTCAGGGAACATCACAATTCTTTCCGCATTTGAAACTTCCCACTTTCAAAAGTTTTG +TCTTTCTCAGTGTCACCTCCTCTGTCTAAGGGTAGGGCCCAGGTGTGAGAAGCAGGGAAC +TAAGAGAACCATCCTGACTCTCGGGGAGCTGTTCTGCCTTGGCCCGTTGCTGTGAGGACA +CACGTCCATGGTACTGAGACAGCCAACAGCCCTGGGAACCAGAAACCTCACCCTCCTATG +AGCAGGTCATGGCAGGTAGACACAAGCCTTGTTCTGGGGGCCAGGCTAAGAATGTCCCAT +GGATTGAACAGTAGAGACATTGACCCTGTTTGAGGTGTGAATTCTAGATTTGAGCTCCAG +CAGTGCAGTTAGAAGCAGCCGACCTGCCTCTAGTTCCTAAGCCCTCGTACCCATCACACT +GTTCTACAGAAGTGGCCACTTGATCCCCTAAAGCTGTGCCCTCAATGGACACTTTGTTCA +CATTTAAGTGAATATGATCCTTTTAAAAATTAAAAATACATATTTTAAAGATAGTCTTAC +CCTGTCACCCAAGACGGAGTGAAGTGGGATGAACACAGGTCACTGCAGCCTCAATTCCTG +AAGTTGAGGAGTCAACTGCCTCTGTCTCCAAAGTAGCTGAGACTACAGGCGTACACCACA +CCTGGTTTCATTCAGGTGAATATAATCTTTGCTGCCAGCATCTCACCCTTTGATAGTAAT +CACATCCTCTTAAGAGGGCTTTGGAAACAATTGGCCTTGGCTAGCCAATCCCAGGTTTTC +GCTTCCATGAGGGTCTCCAGCTTCACACAATATTGTGCCCATATCTGTAGCGGCCTTGGT +TTTTAATTGCAAACAACAGCATCCACCCACATCAGTGTTGGTAAAAAATAAATTGCTTTT +TTTTTTTTTTTTGAGACAGACTCTCGCTGTCGCCCAGGCTGGAGTGCAGTGGTGTGATCT +CGGCTCACTGCAAGCTCTGCCTCCCAGGTTCACGACATTCTCCTGCCTCAGCCTCCCAAG +TAGCTGGGACTACAGGTGCCCACCACCATGCCCGGCTAATTTTTTGTATTTTTAGTAGAG +ACGGGGCTTCACCGTGTTAGCCAGGATGGTCTCGATCTCCTGACCTTGTGATCCACCCGC +CTCAGCCTCCCAAAGTGCTGGGATTACAGGTGTGAGCCACCACGCCCGGCCAAGGTATTG +CTTCTTTAAGAATGGAGCTGTTAATACTGCTGGTACCAGAAACATTAAAAAAGAAAAATC +CTGCATGAGGGCCAGAGGAGGAGTACAGGAGAGTGAGATGGAGTGGAATCCTCCAGTGGG +TGATAGATGGATGGACAGACAGATGAATAGACAGACGAACAGATGAACAGACGGACAGAC +ATGAATAAACAGGTGGACAGACAGATGAATAGATGAACAGACAGATGGACAACTGGATAG +ATGGACAGATGAAACTAATAATCTGAGAAATCAGAAAAGCTTCATGAAAAAAGTGGGACT +GAGCTGTGTCTCCACGGATAGATATAAAAGCAGAGGACTCTCCACTTGAGTCGAGAATGA +CCCAGTGTCCTGATCCAGAGAGGAAGCCAGCCTGGCTTGACTGGGAAATTTGTGGGAGGA +CTCAGAGGCCCTTAAAATGAGGCCAGGTGAGGTTGGGCTGATCCGAGCCAGCTCAGGACT +CCTCTGCCACACAGCACAGCTGCCTTAGGGGACACATTACTCAGGGAGTTGCTGGGACCT +ACTGGGCCCAGCATTGCCACCAGCACCAACAGCTTCAGAGAGGGGGGACACACACTTGGG +GTGACTCCAAGACTGTGGGTGGCACCTGCCTCAAACAGGGGACAGGCACAGGGACACCTC +TCGGGGTCTGGCACCCCCACGCACTGTGCCTAGGTCCCAACAACGCCCACTGCAGCCCTG +TGCCCATCATGCCCAGAAGGTTTCCGCTTCAGCCTGGCCCCTGTACTGGCCCCAGGAATT +TGGACCCAAGCCTCAGTCACTGGGTAAACAGCAGTGGGAACCAGCTCATTACTCTAGGTA +AGTGGCTCTTACAACCTTCCCCAGCCAGTTCCACCCTCTGTTGTCTCTGGAAAATATGTT +TTCTCTCCCTGGGGTGGCTTCTCCTCTGCCCTCCCAGCCTTAATCACTGACCCCTACCTT +TCTCTATGGGTCCTGGGGGAGGTGGGTTAGTCTTGAGGTAACCAGCAGAAGGGCCCCAGG +TTCCAACAGCCAGACGCAGCCTGGTCCCGGGGCCTGGGCTGGGTTTAGGCAAGGTCAGAG +TTCCTTCACCTCTTTCAGGGCAGGCACCCGAGGTGCGGGGCAAAGGCCAGTTCTGACTGG +CACACTGCAGTAGCATCAGAGACACCCCCCGGACCCCAGGGTCTAGGCTGATGGCTGGAT +GCCCATCCAGCCTGGGAAGGCCACACGGGGGCCTGGGGACAAAGGGGTCACCATGAGGTG +ACATCAATGCAGGTGCAGAGAGGGCTCTGGGTCTAGGCTGCAGCTCTCTGGCCTCTGCTG +GGTCATGAGGACACAGGGACAAAAAAAGAAGATGGGTCAGATGGGGCAAGATGGCCAGAG +CCCAGCCCTCCCAGAATAGTCATCAGAGAGGAGCAGATCCCTTAGGGCAGAGACATATTT +GTCCCTGGAGCCCCTTCACCCCTGGGGCCTGGCGTCTCACTGTCCATGGGTCAGTCTCCC +ACCTTCCTCAAAGGGCACGTTAGACTCAGGAGGTGACAAGAGGGGAGCGAATGGGGGGTG +CAGAGGACTCTACGGCAGCCAGCTGAAGTCTAGAGTTGTCAGAGTCCGTGGAGGCAGGCA +TGGGGGGCTGCTGTGTCCCGTGGTCCAGGGGAGCAGCCCCAACACCACAGTGGAGGTGAA +GGGTCCTATGGTTGGGGTGGTGGGGACAAGGGAGGTGAAGAGCGGTGGAGGAGCCCCGGG +GCTTGTCTGGGTGCAGCCCACCCTTCATCAGGAAAGCTGAATGGGATGGGCTGGGGCAAA +GCCTGGTGCCCCAGGGGACAGGAAGCTCCAGGCCCCACCAGGCTTGGGCCTTTCCACACT +CTGCCAGGATAGTCCTGTGGGCTGGGCGGGGACGTGCAAATTCCAAACTCAGACTCCAGA +GACCAGAGAGGAGGGAGCACAGCCTGCCCTGGGTACACACAGGGAAACAGAGGCTGCAGA +GGAGGGCTGGGCCAGGGCTCCTAGAAAAGGTGACTTGGGAAGAGCTCCTAGGAAGGTGCG +GGCTGGCTGCTCTGCAGAGGTCTTGAGTGAAAAGGAGGGGAATGAGGAGGGAAGAGGCAG +CCCCGGGTGGACTGGACAGCCATGCCGTGAACCTCACAGAGACTTTAGACAGAGAGGGGG +CTCTACAACACCCCAGTACTCCCTCTGCCTCTCTTGCCCCCTCCTCTGTCCACACAGGTC +TGCCCAAGGCCGCCCCTTTGGACACTCTGAGGAACTCCAAGCCAACAAGATGCCTCTCAT +TAGTGACTTCTACCCTGATGCCGTGATGGTGGCCTGGAAGGCAGAGGGCACCACCATCAC +CCTGGGCATGAAGACTGCCACACCCTCCAAACAGAGAAACACAAGTACACGGTTAGCAGC +TACCTGAACCTGACGTCTGACCAGTGGAGGTCCCCCAGCAGCTATGTTCTTAGGCCCCTC +ACCCCACCCACAGCAGCCAGGAGCTGCAGGATCCCAGGGCAGGGGTCTCCCCTCCCACCC +CAAGGCATCCAGCCCTTCTCCTTGCACCCAATAAACCCTCAGTAAATATCCTCATTGTTA +ATCAGAAATTCTGCTCCCTGTCTTCATTTCTTACCTTTCATATAATTTGACACTTCCCCC +AGGTTCTCAGTGGGGGATGGGGGAATCCTGACACTCAGTGGGAAAATAGCTTGTGGGAGA +GGCTCCCAGGCTCCCAGGGGCATCTGCTGGAGAAACAGGCCAGGCAAGGAGCAATCTGAT +CACTGAAGACCAGTCCCTCTGCCCTCTCCCTCCTCCAATTCCCCGCTGCAGCACTCCCTC +CCCCAACCCCCCGCCACTCCCTGCCTCCTTTCTGGATGGAGCTGTCCCTGGCTGGGCCTT +CAGATATGCCCTCTGTCCTTGCCCTAGTAAAGACACTCTTCCCACCTACGACCTCTTTTT +CCTCAGCCTGGAAGTAACACTCTGGGCCTGGAGTTCCTCTGCCCGTGGCCCTGGCCCCTG +GAATCCCCTCCTCCCTCTCTGCCCAACTCCCCACCCCTGAGAGCTGGACTGTCCAGAATA +CTCCAGCACCTTCAAATTCATGAGCTGTTAAATTTGGGGCCCACCTCGATTCTTCACCTG +CCAGCAGGTTCACAGGTGTAAGAAAAATCGGAGGAAGGCAAGAAGGAAACACACACAAAA +GGCTTGCAGGAGGCTCAGGACACTTGCCAAAGATAGGCTCTAAGCTCCCCAGGAACCAGA +GCAAGAAGGGTAACAGGAGCTCCATCATTTCTATGAGATTTAACAAAGCCTTTGCTTGAG +GGAAGTTGGTGTTTTCAATGCTGAGGCCAGGCATCTCCTCAGAACTAACAGTGGGGATGT +GTTTTTTGTCTGTTTGTTTTGTTTCGTTTTGTTTTGAGACGGAGTCTCACTCTGTCGCCC +AGGCTGGAGTGCACTGGTGCAATCTCGGCTCACTGCAAGCTCCGCCTCCCAGGTTCACGC +CATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGACCACAGGCGCCCACCACCATGTCCGG +CTAATTTTTTGTATTTTTTTTTAGTAGAGGTGGGGTTTCACCGTGTTAGCCAGGATGGTC +TTGATCTCTTGACCTCGTGATCTGCCCACCTTGGCCTCCCAAAGTGCTGGGATTACAGGT +GTGAACCACCACTCCAGGCAGTGGGGATGTGTTTTACCCAATCCCTTAGTATTGATTGGA +TTTGGGCTCCGACACCTGCACAGGTGACTGCCTGGCAGCCCCAGAACACGGAGATGTTCT +CAAGTGTGTGGCACAGAAAGTCACTGGCTGCCTTTGGGGGGCATTCTTTTTGGGAAACAC +CTCTCCATTGGATCCTGGGCCTCAGGTGGAAAACCAGGTCCTGCCTCGGGACTTTCTCTG +TGAGGCTCCCTGGGTCTGGGGCTCCAGCCATTCTCCGAGAGGAAGGTGCCAGGAGAGAGA +GCAAGGCCCAGCCCCACCTAGTCTTTCCTGCATGGTCCCTGCTCTGGTAGAGACAGGGTT +TGGCCTGGCTGGGTTCCACACCTGCTGAAGGATGCACAGATGGTAGATGCCCAGTCTGAC +CCTGGGTCTACCCAGGGCTAACCCCCTTCCCTGAGGCCAGACTGAGGAGGCTGAGCCTGC +CCAGGTCCTGCAGGTGTTCAGGGCAGCACAGACAGTGGGTGCCCAGGCCCCTGACCCAAG +GTCACCCTTCCCTCTTGAGGCTGTGCTAGGCAGGGCCAGGAGACAGTACTGAACACACCA +ATCCCCTTGTGGCTCTGTGGGGTTGGGGACCTACACTCCTCAGTCTACATCGAGCCGGTG +TAGGAGACAGGCAGAAGCAGGAGGGTCCTCGGAGTCCACAAAGCAGAGCAGGGGCAGGTG +CTCGTGTGCCCATTTCACCGAAGAGAGAACTGAGGCTCCACGGGAAGGGAAGTGACCTGC +CCGGGTCAACATGGTGAGCTGCTGCCTGACCCACCCCCAGCCTCTTTCCACAGCTCCTCA +GTCCTTCATTCATTCACTCACACACTCATTCAGCAAACCCTCAGTGAGCACAGCTGTGGG +CCAGGTGCTGGTGCAAGACCAGGACCACCTGCCCTGGAGAAGCTCATGAGCTGGAGGACA +ACAGGGAGACACCACTGCACCCCCCTGTCCTCAAGTCCCCAAGGTTGGAGCTTGGCCCAG +GGAGCGCCTGGGGCAGCAGGGGCATCTCCCCCTACTTAGCAGAAGATTTAACTGAAAGAA +CCATCTGACGGAGCCCCAGCTGTCATCCCTGGGCCACAGTGGGAACATCACAGTCCCTCA +TCAACCCTCACAGTGACCCTGAGGCCCAGGGCAGCCATGGTCCACCTCACATAGGGCAGG +CCGACCATGAGGAATGCACCACGGTTGCCTCATAGCGACCCTGAGCTCTAGAGCTGCCAT +TGCCCACCTTATAGAGGGGATGCTGACCAGGAGGGAGGCACCAACCAGGGCCACCCAGGC +TCCGGCCAGCCTGAGAGTGGCCCAGCTGGCCCTGTGCCTGCACTGCCCTGCACCTGCTGC +CCTGCCCAGCTCAGACCCTGGTCATATCCTCAGGAGTGATGGCCCCACAGCACCAGGGCA +GGGTAGGTCCACACTGGGAGAGCCCCTAAAGGTACAGAGAAGAGCACTGGAGTCCAGGGA +GGAGGGATTGTCCCGGCCCTGGTCCTGCCTCGCTGTGACCAGGGCTGAGGCATTTGCTCT +AAATCAGATGGGGGAGGGGCATCTGTGGCTTCCTCTACAGCCAAAACCAGAGCCCCAAAT +AGCCCCGGTGGGTATGGAGGGGCCTTGGGGGAGGGGAGGAAATGGGAGGGGAGGTGGCTG +CTTGGGGCTCTGGGTGAGGGCTAGGAGCTCCTACTGAGCTAAGCGGATGACTCTCCTATC +TGACCTGGCCCCCCATGGGGCCTGCAAAAGCACCAAGAGAGCATCCCCAGCCAGGCCTGT +GGAGGGGCCCTTGACCCCTCATACTCACTGAGCCCAGTGGTGGGAAGAGGGGGCTGGTCC +CCGGCCAGTATTCTCCTGAGGACACCGACACTCACTGGTAACAAGCAAACCAGACCCAGA +TGCTCCAAAAAGAGGCCACTGGATCCCAGCAAGCACCCACTCCCCCCAACACGAAGGTCC +AAAACCAAGCTTCAGCCAACTAGAATGTGGGAACTTCCCGGGAGGTAGAGGAAACAAGTC +ACTGTCCACTTGCAATGCCCACCGGTTAGTGACGCAGCACAATGACAGTCACACCTCTCA +GAGGGGGCTCTCCCTCGACTCTCCTTCCTGACACATCAACAAGGACAGCCTTACCAAGGG +CCACACCTGGGCAGTCACCATGGGGTTCGTGGTCTCACGTGGGCCCTGCTTAAAGCCCCT +GGGGATAAGCTCACTCCAGCTCATGAGAGGCCGGGGGTGACCCTGACCCCATTTTCCGAT +CAGCGATAGCACAGCACATGTGGGGACCAATGAGAAATGAGTCTGGGGAGACCACGGGCT +TCAGGGAGAATGTTTCGATGAGGCAAGTACAAGAGCCAGTGAGGGACTGGGTGACTTCTG +TGGCCTGTGTCACAGAGCTGGGGCCATCAGATGCCCCATGTCCACTCTGAGGACAGAGTA +GCCCATGGTTAGGATGACCCACCAGCCAGGCCTGGCCAGGGCACCCACAGGAGACAGGAA +GGCTGTGAGGGCCCGGGGGCACGGAGCAGCTCTGAAAGGAAGGGGTGCTGGGTCCCGGGG +CTCCTGGGCAGAGTGGTTGAAGAAGGTGAGACCCCAGACCAGCCAGATGGGCCCACTTCT +CAGGGGACCCTGGTCAGACAAGGGAGCACCTCCTGCTCATGGAACACAGCAAGGGGCAAG +GTAGGCACAGCCAGGCTCGGAGAACTCGTATTTGGGGGAGATGTAAATCAACCCAATAGA +CAAGGGAGCGATGTGGTGTAGGAGATGGGGTTTGTGCTGGGGAGAAATAAGGCAGAGAGT +GGGGAGTAGAGAGCACCTGTCTGGGGTCTCAGGAGGAGCGATGTCCCAAGACTGGAGGCG +GCCAGGGGCTGAGGAGCCCTGACTGGGCCAGGCCTGTGGCTGGAGCTGGAGGCTCGGGTT +CAGCCTCAGTTTCCCCTCTGTGAAGCTAGGTTCATAATAATGGAAATTGACTTTCTGGGT +GGCTGGAGAGACATTCAGATGGAAAATGGATATTCTATTTTGTCTCTGTCCTTGGTTGTT +GTCATCTCAGGCTGTTCCAGCCCCAGTTAGCCTCGGGTCAGCCCCCTGCCCATGTTGGTC +TCCCCATGAGCTCAGGCACCTCATCCCCAGCACAGCTGGCCTGGAGAAACCAAGATTCCC +TGAGGCTTAAAATAGCTGGAAAGCCAGCCCAGCTGCAGGTGCCTCCCTGTAGGATAAAAT +GTAGGAGAAGATCTTCAAGAGCTAGGACTAGGCAAAATTTTCTTAGACTTGACACCAAAA +ACATAGTCTACAAAAGGAAAAATTGCTAAGCTAAGTTTCATCAAAATTTAAAAATTTGTT +CTGCAAAACACCTTGTTAAAAAGATGACAAGTTACAGACTAGGAGAAAATATTTTCAAAC +AACATATATGAACAAAGCACTGTTATCTTGAGTATATAAGGAACTTGCAAACTCCACACA +AAAAATCAAACAATCCAATTAGAAGATGGGCAAAAGACACGAGCAGACATTTCACCAGAG +ATGATACACAATGGACAAATAAGCCCATGAAAAGATCTTCAACTTCACTAGCCATTTGGG +AAATGCAAATTAAAACCACAATGAAATATAATTTACACACATCAGAGTGGCTAAAATAAA +AAATAGTGACAAGACAAAACTCTGCTGAAGATATAAGTGTGAATCACTCATATATTGCTG +GTGGGCATATAAAATACCACAGCCACTGCAAAAGTGTGGCAGTCTCTTTTTTCTCTTTAG +AGACAGGGTCTCCCTATATTGCCCAGGCTGGACTCAAATTCCTGGGCTAAAGTGATCCTC +TCGCCTCAGCCTCCAGAGTAGCTGGGACTAAAGGCACATGCTACTGTTGATGTTTGGCAG +TTTCTTATACGACTGAACATGGAACTACCGTATGACCTAGCAATTACATTCTGACTCATC +TATCCCAGAGAAATGACAACCTGTGCTCATACAAACAACCGTACGTGAATGTTCATTACA +GCTTTAATAGCAATAGCCAAAAATCTAGAAATAACTCAGCCATCCATCAGCAGGTGAACA +GTTAAACTGTGCTACATCCATCTTATGGAATAGCACTCAGCCATCCAAAGGAATCAACTC +TTGATACACTCAACCAGCTCAACCCTCCCCAGAACGCACCTGGGTGGGAAGGTGCACAGC +AGATTGGGCCACTAGATTTACCCAGTGTGGAGGAAACAGGTACCTCCTCCTAGATTTTGT +TCTTGGCAGAGATAAACCAGTGCTTCTCAGTCATTTTTGCTTTTTACTAGCCATGGGAGG +TATTTTCCAGTAAAGGCTTCTATGACCAAATGCATTTGAAGGAATGTTCCATATGCTCTC +CCACACGCCTTCAATTTCCTGAGAGTGACAAGAATACCAGAATAGCCAAGGTTCTAAGAT +ATCCTTCAGGATACCTGTTTAACTTAAACTTCCCCAAACTATTTGATTATGAGACTCTTT +TCAAGCATAAACATTTTCCTTCCAGGAACATTTGTATTCTTATAAGAAAATATTAGAAAG +CATTCCAGGTGACTTACCTAATGGGAGAACCTCAGGCGCCAAGCCAGATGAGATAAAAGT +TTCAAATAGTGCTGATAAGGTTTTCTTGGTTCAGCTGCCTCCCTCCAACTCAGCTGCTGT +CACACTTCTAGGCAGTTTTGACTGGACTGTAAATTCCTTCTGGCTGGGGCCATGTCTCAG +CACCTTGTGCAGGAGTGATACAAACTAATGCTTCATAATAAATACTTACTCACTGACTTT +CTCTTTATTCATCCCAGGTGAGCATGTTTTCCATCCCCTTCAATCTCCACACTCACGGGC +AAAAGTGAGTTGTGGGTCTTGGAACTCTCAAGAAGAGGAGGAGATCTTCAATTTGCATAT +GCAGAATCCAAACAAGTCATCTTGAGTCCCCACAAGTAGGTGGGCTTATTTCTCACATAA +CAAAATCGCCCCTCCTTTGCAGCCTCTACACCACTGCAGATCAAGCCCAGCTAAACCTTG +CTGTGCTATCCTGAAGGTATTGCTCCCAGATCCCGGCTGTCAGCTCCTGTCCAGCATCAC +AGGGCAAGTCCAGAGACATGATCATGTAATTGACCAGGGATGACAAGTGGGTCCTCTCAG +TGGACAGGTGTCTGCAGTAGGTAAGCCCTGTCAGGAGAGGAAAGAAAAGCATCATCATCT +ACCACCTGATACCCTTTGCCCTGTCTTATGGAGTCCCCAAAGTGCTGTCCCACACTCCCA +TCTTTATTTTTTTATTTTTCTGAGACGGTCTCGCTGTCACCCAGGCTGGAGTGCAGTGGC +GTGATCATGGCTCACTTCAGCCTAAGCCTCCCGTGCTCGAGCAATCCTCCCATCTCAGCC +TCCTGAGTAGCTGGGACTACAGGCATGTGCCATCATGCTCAGCTACTTTTTAACCCCTCC +TTTTCTTCACAAGGAAGGCAAGGCTTGATGTCACTTGCTGGCTGAATGGCTTAATAGCTC +TACAACCCTAGGGAAGTCTTATCACCTTGCTCAGCCACAGTCAGGGTGATGCCATCCTCC +TCTGCTGGAAGCCAAAACATTTAATTGATAGGCTGGAGGCAGAGAAGGGACAGGAAAGAA +GGTGGCCAATGACTCTGTGGCCTTGCTGTGCCTTTGTCTGCCTCCAATCCATACACAGAG +AAAGACACTGTGAGATGTGGACAACTTTCTTTCAAATATCAGCTGAATACAGGTATTCAT +CCAAAAGAAAGGAAATCAGTACATCAAACAGTTATCTGCATGCCCATGTTTACTGCAGCA +CCATTAACGATAGTACAAAATCAACCTATGTGTGGAGGAATAGTACAGAATCAACCTAAG +TGTCCATCAATGAATTGACAGTTAAAGGAAATGTGGTATATGTATGCAATGGAATATTAC +TCAGCCATGAAAAAGGATGAAATCCTGTCACGTGCAGTAACATGAATGGAACTGAAAATC +ATTATGTTAAGTAAAAAAAGTGAGGCACAGAAAGACAAATATCACATGTTCTCAGTCATA +CATGGAAGCTAAAAAAGTATTTCTCATGAATGCGGAGAGTAGACTGGTGGTTACCAGTGG +CTGGGAAGGGAAGAGTAGGAGGGGAATGAAGAGAAGTTGGTTAATGGTACAAAAATCCAG +TTAGATGGAATTAAGTTCTTGTATATTATAGTAGGAAAAATATAATTAACAGTAATTTAT +TGTATATCTCAAAATAGCTAGAAGAACTGTAAAGTTCCCAACATGAAGAAAACATAAATG +TTTGAGGTGATGGATGTTCCAATCACCTCAAACGTGATAGATCAATACGCAGTGGATCTA +TCAAAATACTACATGCACCCCCAAAATATGTACAACTACAGTATATCTATTACAAATTTT +TTTAAAAAGAGGGCCGGCCGGGCACAGTGGCTCACGCCTGTAATCCCAGTGCTTTAAGAG +GCTGAGGTGGGTGGATTGCTTGAACCCAGGAGTTCTGGACTAGCCTGGGCAACACAGTGA +AACCCAGACTCTACAAAAAATAAGCAAACTTAGCTGGGTGTGGTGGCGTGTGCCTGCAGT +CTCAGCTACTTGGGAGGCTAAGGTGGGAGGATTGCTTAAGCCTAGGAGGTCAAGGCTGCA +GTGAGCCAAGATCTTGTCTCTAAAAAATAAAATCGGCTGGGCGTGGTGGCTCACGCCTGT +AATCCCAGCACTTTGGGAGGCCGAGGCCGGTGGATTGCCTGAGGTCAGCCATCCTGGCCA +ACATGGTGAAACCCCGTCTCTACCAAAAACACAAAAATTAGCCGGGCATGGTGGCACACC +CCTGTAATCCCAGCTACTTGGGAGGCTGAGGCAGGAGAATTGCTTGAGCCTGGGAGGCAG +AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGATTGACAGAATGAAACTC +TGTCTCAAAATAAATAAATAAATAAATAAAACAAAATCAGATAAAAATAAAACAAAATTG +CAGCTGGATTAAAAAGGCCCCAGTAAGTCAGGAACCAGGGAGAGAGATACTGAGGGGGCA +GCTTGCTTTCAATGATGGTCCTGCCTCAAAAGCACACCTACCAATGTGCCACCCCTTATC +TGTCACACCCTGTCACCTGGAGGGTGTTAGGCAAAGTGCCTCAGCAAACGCCAGCCCGTG +CTGTTTGCTCTGGCTGTGCCCTTTCCTTCTGGCGTTCCCCAGCCATTTCATCCTCAATTC +CCAGTGAGAACCCTGGACATTTTGCAGCCTGGGGACTAAATTCTAACAGGAGGGTCAATC +ATAGCAATGATGATGATGATGATGACCACGATGATCTAATAGCTAATACTTACACAGTAC +ACACTATGTGCCAGGGAGCTGTTAGCAGAGTTTGCATAACTCAGTCTCGCCACAACCCAA +GAAAGCAGGCGCTACTGTTATTTCCATCTTATGGATGGGGTAAGTTGAGGCCCAGACTGG +TTATGTCACTTGCACAAGTTACATAACTGGAATCTGAAACCAGATCACCTGGCTCCAAAA +CCTGGGCTCTCAACCACCATCAGCCATGAGCCACATCATCTGATGACATTATTCCAGACC +CGTATCAACCCCCAACCCTTCCTGCAGGAAGATATTTCATTTGGGTCCAAAAATACTTGC +CCAATGCCTGCTCCACGCCAGCCCCTGCATTAGGCAAAAACGTGGATTGTAACGGAACAG +GCAAAACCTTTGTCCTAGTAGAGTCACGCTCTCCCCGCCTCTGCAGCACTCAGGTGAGCT +GCACTGTGGTTTCACAGGCCCATGCAGGTGTGTGTATAGCTGCAGGTTTTATTTCCCTAG +CCTCACAGCCTCAAGAGGAGAGATAAAATGTGTATATTCAGGGATGGAAAACACACACAC +ATTTTCTCTCTCCCATCAAGGCTGTGAGGCTACGGAAATAAAACCTGCTAAGAATAAATA +TACGGAGAAGAAAAAACAAAGCCTTGGAGTCAGGCCAGAGTCTGAGTCCCAGCTCTGCTG +CTTGGTAGCTGTGTGACCTTGGGCAAGTCACTTTGTCTCTCTGTGCCTTAGTTTCCTCAT +CTGTTAAGTGGGAACAATCAGAATACAGATACTAGGAATTTAATTTTTAAGTTTTGGGGG +AGGCATAACGTCACTTTACTCTTCTGCTTCTGCCCATGACAGAAGGAAACTGACATTTAC +TGAGCACCTACAGTATGCAAGACTAGCTGCCAGGGGCTTTCTACATGCTCCTCACTTAAT +CCTGAAAACAAACCCTCCACTGTGGCACCTGGGGGTACAATGGTGATTTAATGAAACCTC +TGTCCCCAGGGGTCCCCATTGTTCACTGCCCTCTCTTAGGACTCAGGCATAAAATTTATC +CCCAATCTGTAGATGATGAAACTGAGGCTCAGAACGGTTCATGTAAATTCACTGAAACCA +GGCATTCAGGTAATAGAGGAGGAGAGGTTCAAGCTCCAAAGCCAGTATCTCCTGGTATCG +CTGACATAGAGTAGGCACTGATAACTGCCCCTCGGAGACTACACGGCAACAAAGACCTAT +GTACATCCATAGAAGGCTCTGCAGAGGATCTGGTACTTCATATTGTCACAAGAGAAGTTT +CTGGGGAGCCCTGCAGGCAGAGAAGGAGGGAGATGCTTAGAATAGATTCAAACACAGCCC +AGGTTTTTTGGAGAGGAGCACAACTTGTTATCTCTAGAGGGTAACTGAAATCAGCCAGTC +ATGAGGAGTGCAGGGAGGGTGCTATTACCTCCACCTTTACAACATCACCTCTTCCACTAC +CAGTGACCCAGTTTGCCCTTGAGAAATCACTCCGTCCACAACTTTCTGTCTCCGGTTTCT +AAAGGGATGACTCTACCCATTTATAGGACCAAAGCTGGAGTCATAGTAATGGAAGCGGAG +ATTGTCATATGACCCAACCTGAGCCAATGAGAATTAGGCTTGGGACTTTCATTGTAACTA +CCAGGAAAAAGTCTTTTTCTGCTTCAGTTTCTAAACCAGTGGGATACAGGACAGTAGCTC +CTAGGAGCTATCTTTGCCACAACATAAAAAGGGCCTGCCTGTGGATGGAACCATCACAGA +GGGAAGCAGAGCCAAGAGCTGAAGAAACAGAGATTCCCGTCTCGAGCATCTGAGCCTGAA +GCCACTATGACTCTAAGCTTCTGTTATGCCAACAATTTTTTTTACCTGAACCAGTCTGAA +GTGGGTTTCTATCACTTGCAGAAAGAGTTCTGATTTCTTTTTTTTTTTTTTTTTACACAG +AGCCTCGCTCTGTCGCCCAGGCTGAAGGGCAGTGGCGCGATCTCGGCTCACTGCAAGCTC +CACCTCCCAGGTTCACGCCATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGACTACAGGT +GCCCGCCACCACGCCTGGCTAATGTTTTGTATTTTTAGTAGAGACGGGGTTTCACCGTGT +TAGCCAGGATGGTCTCGATCTCTGACCTTATGATCTGCCTGCCTCGGCCTCCCAAAGTGC +TGGGATTACAGGCATGAGCCACTGCACCCGGCCGAAAGAGTTCTGATTTCTAAAGTGACC +CAGCTGAACCAAGAGCCAAACTGGGATTCAGTATCTGGCTGTTTGCTAAGTAGGTGATGC +CTCAAGGATTCTCCCTGCATGGGAATTTGTGGCAACTTTTTTGGCTGAAAGAGGCAAGAG +GAGTAAGGTACCAGCATTGCTGGATAAATCCAGGACTGCTGAAGGGAGTGTTGTACGCTC +TTGCAATGAACAGAATGGAAGAATATCGGCATATTTATTCTCAGCACATCCCAAAGGACA +TCCAGAAAAATCCAGGGAGACTGGGGTGGGGGAAACATAGCCGAAGTCCTCTAGTTAGAC +ATGTGAACTCCAAATATGAGAGACAGGTCTCAGTTAATTTAGAAAGTTTATTTTGCCAAG +GTTGAGGATGTGCGCCCACGGTACCGCCTCAGGAGGCTCTGACGACATGTGCCCACGGTG +GTCAGAGCAGTTTGGTTTTATACATTTTAGGGAGATATGAGACACCAATCACCGATCAAT +GTATGTAAGATGAGCATTGGTACTGTTCAGAAAGGCAAGACAACTTGAAGTGGGGAGGAG +GCTTCCAGGTCATAGGTAGATAAGAGACAAACAGTTGCATTCTTTTGAGTTTCTGATGAG +CGTCTCCAAAGGGGGCAATCAGATATGCATTTATCTCAGTGAGCAGAGGGGAGACTTTCA +ATAGAATGGGAGGCAGGTTTGCCTTAAGCTGTTCCCAGCTTGACTTTTCCCTTTAGCTTA +GTGGTTTGGGGCCCTGAGATTTACTTTCCTTTTACAGGCACATGGAGGCATTGAATACTG +AAGTGTCCCACTTTGTGCCCTCAGGTTGGTGAGGCTTACAGTTGCTCAGGTTACATGAGA +ATAGGGTCACATAAACAGCTGTCCCACTGTGGGCTTGGTTTTCTGCAAGGTACTGAGTTC +CCCATTATGCCAGGTGTGTAAGCAGACGCTGTAACAGGAGAGAGGGCAGTAAGTTATGGC +AGCATTTTTTTTCTTTTTTCTTTTCTTTCTTTTTTTTCTTTTTGAGATGGAGTTTTGCTG +TTGTTGCCCAGGCTGAAGTGCAATGGCGTGACCTTGGCTCACCACAACCTCCGCCTCCCA +GGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGTATTACAGGCATGCGCCAC +CACACCCAGCTAATTTTGTAGGTTACAGCAGCATTTCTCACTGGTCCATGGACCATCAGC +CTAACAGTTACTTGCAGTTGCTCCAACATGTGTATTCCTGGGCCCTGCACAGACTTAATC +AGAACTTCTATGAAGTAGTCTAGGAGCTGGCATGTTTTGCTACCTAGCCCAGGGGATTCT +GATGCACAATAAGAGAATATCCGGTAACATTAGCACTTCTCAATCTTAAAAGTACACACA +TGGTCTTGGGACTACGTTAAACACAAATTCTGATTCAGAAGGTTTGGTATAAGAGACTGA +CCATCTGCCCGGTGCTGATGCTGGTTCACAGGCCACAGTCTGAGGAGCCAGGAGCTTAGA +TGATGACTTCAACAATGTAATGCCAGCCCTCACACCGTACACTCCTATGGCTGAAGACTG +GACCACACACTGGTACAGAAGACCAGCAAGGACAATAGGGTTCCATTCTACCAGGCAAGG +CCAGGAGGAAACAAAACCAGTCTCATGAACTGGCTGAATAGTTCCAAAGAGACAAAAGCT +CTATGGGCAAAGAGAGAGATGCGCCTGAGATTTAAGTTTACATGATAAAATGGTAACTGT +TATTTACTGAACAGTACTGTGTGCAGGTGGCATATTCTGGCCACTTTAAACCATTATCTG +AGCTGGCATTTACCATAGCCATATAAAGTAAGCACCAGAATCTCCACTGTGTGGAGGAGC +AAACTGAGATGAATGTGGTTGACATTAAATAATATTTGAGATTATTCTGCCTTCTAGGCT +CATGGTAGGGCTGCACTTCCTGGCTCCTTGTGGATGGGGCCAATGAGCTGTGGGTGGGTA +TGACATGCTAATTTTGGGTGGGGCCCTTTTATTGTGGGTTCAAGCCCCTCCAATGCTACC +TTTCCCTGTCACTGTGACTGGCAACATTCAAATGATGGCT diff --git a/example/reference/22_20-21M.snp b/example/reference/22_20-21M.snp new file mode 100644 index 0000000..68abb59 --- /dev/null +++ b/example/reference/22_20-21M.snp @@ -0,0 +1,3502 @@ +rs73387790 single 22:20000001-21000000 145 A +rs55902548 single 22:20000001-21000000 427 T +rs114690707 single 22:20000001-21000000 770 C +rs147349046 single 22:20000001-21000000 809 T +rs1978233 single 22:20000001-21000000 949 G +rs2079702 single 22:20000001-21000000 1005 A +rs139570132 single 22:20000001-21000000 1158 T +rs5993894 single 22:20000001-21000000 1332 T +rs71788814 deletion 22:20000001-21000000 1587 2 +rs111598545 single 22:20000001-21000000 1821 G +rs73877109 single 22:20000001-21000000 2230 T +rs9605047 single 22:20000001-21000000 2847 T +rs62223726 single 22:20000001-21000000 3058 T +rs75213299 single 22:20000001-21000000 3151 T +rs2531714 single 22:20000001-21000000 3265 G +rs2531698 single 22:20000001-21000000 3333 A +rs10678141 insertion 22:20000001-21000000 3490 AG +rs2531715 single 22:20000001-21000000 3730 T +rs2531699 single 22:20000001-21000000 3785 A +rs113101099 single 22:20000001-21000000 4162 A +rs551721384 deletion 22:20000001-21000000 4216 5 +rs2286480 single 22:20000001-21000000 4310 T +rs141779732 single 22:20000001-21000000 4429 T +rs2531716 single 22:20000001-21000000 4703 T +rs2531717 single 22:20000001-21000000 4936 G +rs9606210 single 22:20000001-21000000 5257 T +rs3788322 single 22:20000001-21000000 6039 T +rs2531700 single 22:20000001-21000000 6143 C +rs5748501 single 22:20000001-21000000 6353 C +rs5748502 single 22:20000001-21000000 6549 C +rs2531701 single 22:20000001-21000000 6573 A +rs74731343 single 22:20000001-21000000 6710 T +rs1858770 single 22:20000001-21000000 6991 C +rs115149055 single 22:20000001-21000000 7391 T +rs7288996 single 22:20000001-21000000 7598 A +rs182897799 single 22:20000001-21000000 7969 G +rs73387800 single 22:20000001-21000000 8172 C +rs10427828 single 22:20000001-21000000 8227 A +rs73387801 single 22:20000001-21000000 8487 T +rs737986 single 22:20000001-21000000 8710 T +rs111664354 single 22:20000001-21000000 8834 C +rs56270168 single 22:20000001-21000000 8887 T +rs737985 single 22:20000001-21000000 9077 T +rs4819854 single 22:20000001-21000000 9927 C +rs2518827 single 22:20000001-21000000 10729 G +rs56345620 single 22:20000001-21000000 10818 C +rs4819855 single 22:20000001-21000000 10849 A +rs55725292 single 22:20000001-21000000 10922 A +rs9605049 single 22:20000001-21000000 11158 T +rs145679795 single 22:20000001-21000000 11317 G +rs1476771 single 22:20000001-21000000 11473 G +rs5746852 single 22:20000001-21000000 11836 C +rs2518828 single 22:20000001-21000000 11988 A +rs113192851 single 22:20000001-21000000 12021 T +rs2518829 single 22:20000001-21000000 12285 G +rs189209957 single 22:20000001-21000000 12863 T +rs9754500 single 22:20000001-21000000 12956 A +rs114176759 single 22:20000001-21000000 12998 A +rs2531719 single 22:20000001-21000000 13221 G +rs8142163 single 22:20000001-21000000 13288 A +rs112567206 single 22:20000001-21000000 13681 T +rs12165568 single 22:20000001-21000000 13776 T +rs2531720 single 22:20000001-21000000 13802 C +rs9606211 single 22:20000001-21000000 14031 C +rs41326345 single 22:20000001-21000000 14060 G +rs5748504 single 22:20000001-21000000 14151 G +rs80254054 single 22:20000001-21000000 14197 G +rs2531705 single 22:20000001-21000000 14403 C +rs2531706 single 22:20000001-21000000 14472 C +rs5748505 single 22:20000001-21000000 15015 T +rs73389717 single 22:20000001-21000000 15227 C +rs4629255 single 22:20000001-21000000 15390 A +rs2520732 single 22:20000001-21000000 15510 T +rs9606212 single 22:20000001-21000000 15614 A +rs5748507 single 22:20000001-21000000 15740 T +rs2531707 single 22:20000001-21000000 15973 C +rs7290592 single 22:20000001-21000000 16011 G +rs5748508 single 22:20000001-21000000 16491 A +rs9606213 single 22:20000001-21000000 16970 A +rs2531721 single 22:20000001-21000000 17267 G +rs73389721 single 22:20000001-21000000 17349 C +rs2531708 single 22:20000001-21000000 17444 C +rs2531722 single 22:20000001-21000000 17552 A +rs556782134 deletion 22:20000001-21000000 17673 1 +rs72195121 deletion 22:20000001-21000000 17857 4 +rs9605050 single 22:20000001-21000000 18102 T +rs200431361 deletion 22:20000001-21000000 18131 3 +rs143984612 single 22:20000001-21000000 18691 A +rs572490569 insertion 22:20000001-21000000 18720 A +rs9606219 single 22:20000001-21000000 19177 T +rs2078749 single 22:20000001-21000000 19767 G +rs887205 single 22:20000001-21000000 20072 G +rs2008591 single 22:20000001-21000000 20228 T +rs76656759 single 22:20000001-21000000 20408 G +rs117194710 single 22:20000001-21000000 20600 A +rs117194710 single 22:20000001-21000000 20600 T +rs112637156 single 22:20000001-21000000 20767 G +rs79885628 single 22:20000001-21000000 20882 C +rs114783249 single 22:20000001-21000000 21229 T +rs142921548 single 22:20000001-21000000 21659 A +rs2531709 single 22:20000001-21000000 21695 G +rs72211264 insertion 22:20000001-21000000 21730 AC +rs6518597 single 22:20000001-21000000 21862 T +rs6518598 single 22:20000001-21000000 21937 T +rs75566222 single 22:20000001-21000000 21984 A +rs78880579 single 22:20000001-21000000 22093 A +rs2520733 single 22:20000001-21000000 22497 G +rs62222174 single 22:20000001-21000000 22745 T +rs73150855 single 22:20000001-21000000 22839 T +rs4819858 single 22:20000001-21000000 23009 C +rs2531710 single 22:20000001-21000000 23086 T +rs2531711 single 22:20000001-21000000 23302 G +rs2531712 single 22:20000001-21000000 23443 T +rs5748510 single 22:20000001-21000000 23631 A +rs2520734 single 22:20000001-21000000 23730 T +rs2531713 single 22:20000001-21000000 24173 G +rs74628130 single 22:20000001-21000000 24900 T +rs112148654 deletion 22:20000001-21000000 25176 1 +rs9617858 single 22:20000001-21000000 25310 T +rs73150856 single 22:20000001-21000000 25651 T +rs9606221 single 22:20000001-21000000 25766 T +rs117607297 single 22:20000001-21000000 25852 A +rs11703292 single 22:20000001-21000000 25950 T +rs62222175 single 22:20000001-21000000 26206 A +rs71691029 deletion 22:20000001-21000000 26448 1 +rs7288316 single 22:20000001-21000000 26524 G +rs116356549 single 22:20000001-21000000 26557 A +rs11361191 deletion 22:20000001-21000000 26623 1 +rs115650955 single 22:20000001-21000000 26676 A +rs114089161 single 22:20000001-21000000 26757 T +rs393947 single 22:20000001-21000000 26916 C +rs16982922 single 22:20000001-21000000 27269 A +rs114114568 single 22:20000001-21000000 27321 T +rs148174824 single 22:20000001-21000000 27456 C +rs143084532 single 22:20000001-21000000 27603 C +rs389471 single 22:20000001-21000000 28540 A +rs7364127 single 22:20000001-21000000 29082 T +rs695326 single 22:20000001-21000000 29259 C +rs79343076 deletion 22:20000001-21000000 29411 1 +rs58838155 single 22:20000001-21000000 29538 G +rs374225 single 22:20000001-21000000 29877 C +rs114456898 single 22:20000001-21000000 29953 T +rs77937532 single 22:20000001-21000000 30040 A +rs148393048 single 22:20000001-21000000 30173 C +rs113697305 single 22:20000001-21000000 30656 T +rs409519 single 22:20000001-21000000 30748 A +rs446388 single 22:20000001-21000000 30979 T +rs45548038 single 22:20000001-21000000 31015 C +rs12627769 single 22:20000001-21000000 31101 A +rs17817665 single 22:20000001-21000000 31663 A +rs77046301 single 22:20000001-21000000 31849 G +rs140487675 single 22:20000001-21000000 31908 T +rs455049 single 22:20000001-21000000 31963 T +rs62222177 single 22:20000001-21000000 32006 G +rs138004901 deletion 22:20000001-21000000 32054 4 +rs397701 single 22:20000001-21000000 32326 C +rs17210273 single 22:20000001-21000000 32575 A +rs62222178 single 22:20000001-21000000 32679 G +rs375897671 deletion 22:20000001-21000000 32795 1 +rs111315345 single 22:20000001-21000000 32833 C +rs570570040 deletion 22:20000001-21000000 33022 2 +rs143413803 single 22:20000001-21000000 33734 A +rs114166464 single 22:20000001-21000000 33756 G +rs74752779 single 22:20000001-21000000 34313 C +rs4819860 single 22:20000001-21000000 34390 T +rs148446823 single 22:20000001-21000000 34818 T +rs118008587 single 22:20000001-21000000 35027 T +rs76173340 single 22:20000001-21000000 35150 T +rs79375034 single 22:20000001-21000000 35263 A +rs368880 single 22:20000001-21000000 35689 T +rs78882292 single 22:20000001-21000000 36513 A +rs80146538 single 22:20000001-21000000 36694 G +rs138276244 single 22:20000001-21000000 37107 A +rs405342 single 22:20000001-21000000 37314 A +rs115571782 single 22:20000001-21000000 37506 T +rs147134283 single 22:20000001-21000000 37697 T +rs111797664 single 22:20000001-21000000 37819 T +rs695500 single 22:20000001-21000000 37890 G +rs114758499 single 22:20000001-21000000 38296 A +rs114758499 single 22:20000001-21000000 38296 T +rs79393192 single 22:20000001-21000000 38491 G +rs76309774 single 22:20000001-21000000 38721 G +rs114226275 single 22:20000001-21000000 38755 C +rs174875 single 22:20000001-21000000 39154 A +rs189306965 single 22:20000001-21000000 39634 T +rs115084231 single 22:20000001-21000000 39717 A +rs3804046 single 22:20000001-21000000 39866 T +rs77399579 single 22:20000001-21000000 40219 T +rs28635282 single 22:20000001-21000000 40539 A +rs17817689 single 22:20000001-21000000 40601 T +rs695727 insertion 22:20000001-21000000 40821 G +rs16982925 single 22:20000001-21000000 41231 G +rs366148 single 22:20000001-21000000 41608 T +rs115208925 single 22:20000001-21000000 41703 C +rs73877127 single 22:20000001-21000000 41735 C +rs429965 single 22:20000001-21000000 42074 G +rs57180287 single 22:20000001-21000000 42113 A +rs758376 single 22:20000001-21000000 42562 A +rs61371564 single 22:20000001-21000000 42847 G +rs75170603 single 22:20000001-21000000 43100 G +rs16982930 single 22:20000001-21000000 43358 C +rs113449283 single 22:20000001-21000000 43699 G +rs75011475 single 22:20000001-21000000 44040 A +rs62222179 single 22:20000001-21000000 44932 A +rs73877128 single 22:20000001-21000000 45382 A +rs440042 single 22:20000001-21000000 45410 G +rs201660291 insertion 22:20000001-21000000 45552 TA +rs5748514 single 22:20000001-21000000 45738 A +rs59609897 single 22:20000001-21000000 45882 C +rs61095784 single 22:20000001-21000000 45966 A +rs8140658 single 22:20000001-21000000 46041 G +rs148529668 single 22:20000001-21000000 46149 A +rs5748515 single 22:20000001-21000000 46343 G +rs399162 single 22:20000001-21000000 46686 A +rs140134708 single 22:20000001-21000000 47097 A +rs58308907 single 22:20000001-21000000 47586 C +rs142549904 single 22:20000001-21000000 47765 A +rs111276581 single 22:20000001-21000000 47814 C +rs111323873 single 22:20000001-21000000 47850 T +rs76518635 single 22:20000001-21000000 47972 T +rs75418691 single 22:20000001-21000000 48082 C +rs113509411 single 22:20000001-21000000 48446 A +rs73877129 single 22:20000001-21000000 48646 C +rs73389740 single 22:20000001-21000000 48862 T +rs61737483 single 22:20000001-21000000 49149 A +rs61737483 single 22:20000001-21000000 49149 C +rs2286481 single 22:20000001-21000000 49243 T +rs2286482 single 22:20000001-21000000 49284 A +rs410655 single 22:20000001-21000000 49339 C +rs149412137 insertion 22:20000001-21000000 49414 GGCCCA +rs426894 single 22:20000001-21000000 49453 G +rs2286484 single 22:20000001-21000000 49494 A +rs417981 single 22:20000001-21000000 49934 C +rs74276823 single 22:20000001-21000000 50018 T +rs419135 single 22:20000001-21000000 50400 C +rs111669330 single 22:20000001-21000000 50699 T +rs73389745 single 22:20000001-21000000 50956 T +rs73389746 single 22:20000001-21000000 50978 A +rs432909 single 22:20000001-21000000 51465 A +rs115297588 single 22:20000001-21000000 51927 T +rs75305197 single 22:20000001-21000000 52049 T +rs16982614 single 22:20000001-21000000 52088 G +rs34082990 single 22:20000001-21000000 52142 T +rs3804045 single 22:20000001-21000000 52301 A +rs17818431 single 22:20000001-21000000 52419 A +rs3804044 single 22:20000001-21000000 52441 G +rs3804043 single 22:20000001-21000000 52480 A +rs415520 single 22:20000001-21000000 52531 G +rs442277 single 22:20000001-21000000 52565 A +rs367450 single 22:20000001-21000000 52781 T +rs140840130 single 22:20000001-21000000 53008 T +rs11555967 single 22:20000001-21000000 53153 T +rs1054215 single 22:20000001-21000000 53553 T +rs115561292 single 22:20000001-21000000 53579 T +rs73389755 single 22:20000001-21000000 54176 G +rs34919729 deletion 22:20000001-21000000 54208 1 +rs57497163 single 22:20000001-21000000 54457 C +rs74938744 single 22:20000001-21000000 54479 G +rs60598731 single 22:20000001-21000000 54506 A +rs11913070 single 22:20000001-21000000 54945 C +rs391310 single 22:20000001-21000000 55081 T +rs695800 insertion 22:20000001-21000000 55245 A +rs75563814 single 22:20000001-21000000 55569 A +rs116724863 single 22:20000001-21000000 56111 A +rs114497925 single 22:20000001-21000000 56193 A +rs61046561 single 22:20000001-21000000 56924 T +rs116496431 single 22:20000001-21000000 56976 C +rs7284822 single 22:20000001-21000000 57077 T +rs7285397 single 22:20000001-21000000 57142 G +rs5992507 single 22:20000001-21000000 57457 G +rs143585153 deletion 22:20000001-21000000 57659 5 +rs406086 single 22:20000001-21000000 57805 T +rs11913908 single 22:20000001-21000000 58273 A +rs75651845 single 22:20000001-21000000 58356 A +rs145089673 single 22:20000001-21000000 58680 T +rs450977 single 22:20000001-21000000 58862 A +rs73389760 single 22:20000001-21000000 59217 T +rs446059 single 22:20000001-21000000 59762 A +rs546604629 insertion 22:20000001-21000000 59849 T +rs377793 single 22:20000001-21000000 59979 T +rs453352 single 22:20000001-21000000 60022 A +rs2110139 single 22:20000001-21000000 60098 T +rs442479 single 22:20000001-21000000 60135 C +rs5748522 single 22:20000001-21000000 60723 A +rs146199336 single 22:20000001-21000000 60757 C +rs139142965 single 22:20000001-21000000 60816 T +rs4425182 single 22:20000001-21000000 61414 C +rs75504350 single 22:20000001-21000000 61947 A +rs553587287 deletion 22:20000001-21000000 62022 1 +rs560994073 deletion 22:20000001-21000000 62053 1 +rs147073705 single 22:20000001-21000000 62293 T +rs5992510 single 22:20000001-21000000 63423 A +rs12628100 single 22:20000001-21000000 63726 G +rs111268543 insertion 22:20000001-21000000 64143 AGGAG +rs60877362 single 22:20000001-21000000 64381 T +rs5746857 single 22:20000001-21000000 64718 T +rs9605055 single 22:20000001-21000000 64750 C +rs174884 single 22:20000001-21000000 64777 C +rs60807043 single 22:20000001-21000000 64805 A +rs5993913 single 22:20000001-21000000 64904 G +rs5748526 single 22:20000001-21000000 65085 A +rs9606231 single 22:20000001-21000000 65275 C +rs73877134 single 22:20000001-21000000 65313 T +rs9606232 single 22:20000001-21000000 65369 A +rs112475914 single 22:20000001-21000000 65750 G +rs145098347 single 22:20000001-21000000 65792 A +rs145098347 single 22:20000001-21000000 65792 T +rs150648253 insertion 22:20000001-21000000 65982 ACA +rs148839941 single 22:20000001-21000000 66135 G +rs111275592 single 22:20000001-21000000 66240 A +rs77669633 single 22:20000001-21000000 66421 C +rs9606233 single 22:20000001-21000000 66610 C +rs117313664 single 22:20000001-21000000 66664 A +rs41281421 single 22:20000001-21000000 66797 G +rs61555679 single 22:20000001-21000000 66901 C +rs367842687 deletion 22:20000001-21000000 67082 1 +rs75798129 single 22:20000001-21000000 67231 C +rs9606234 single 22:20000001-21000000 67516 G +rs174886 single 22:20000001-21000000 67658 G +rs174887 single 22:20000001-21000000 67694 C +rs57117909 single 22:20000001-21000000 67979 T +rs61174903 single 22:20000001-21000000 68085 C +rs34310575 deletion 22:20000001-21000000 68111 1 +rs2269723 single 22:20000001-21000000 68406 C +rs75967927 single 22:20000001-21000000 68495 T +rs2269724 single 22:20000001-21000000 68555 A +rs117653823 single 22:20000001-21000000 68722 T +rs62222181 single 22:20000001-21000000 69113 T +rs9606235 single 22:20000001-21000000 69171 G +rs73877135 single 22:20000001-21000000 69296 C +rs566411699 single 22:20000001-21000000 69589 T +rs11704078 single 22:20000001-21000000 69724 A +rs4819865 single 22:20000001-21000000 69843 A +rs9605057 single 22:20000001-21000000 69912 G +rs9606238 single 22:20000001-21000000 70170 C +rs9606239 single 22:20000001-21000000 70284 A +rs1008101 single 22:20000001-21000000 70353 G +rs75051956 deletion 22:20000001-21000000 70407 1 +rs142817386 insertion 22:20000001-21000000 70889 GTGT +rs76889809 single 22:20000001-21000000 70955 A +rs28610569 single 22:20000001-21000000 71350 G +rs9606240 single 22:20000001-21000000 71422 C +rs17817767 single 22:20000001-21000000 71629 A +rs1558495 single 22:20000001-21000000 71651 G +rs1558496 single 22:20000001-21000000 71736 C +rs1558497 single 22:20000001-21000000 71898 T +rs3827292 single 22:20000001-21000000 72415 C +rs2302497 single 22:20000001-21000000 73146 C +rs61746264 single 22:20000001-21000000 73517 T +rs35987994 single 22:20000001-21000000 74005 G +rs34301880 single 22:20000001-21000000 74154 G +rs2073778 single 22:20000001-21000000 74574 T +rs7291552 single 22:20000001-21000000 74698 T +rs11703058 single 22:20000001-21000000 75047 A +rs9606241 single 22:20000001-21000000 75857 G +rs67625586 deletion 22:20000001-21000000 76125 2 +rs142558416 deletion 22:20000001-21000000 76763 1 +rs34204101 single 22:20000001-21000000 77719 C +rs2073779 single 22:20000001-21000000 77862 C +rs79279088 single 22:20000001-21000000 79581 T +rs11089328 single 22:20000001-21000000 79602 G +rs112629076 single 22:20000001-21000000 79687 C +rs74576059 single 22:20000001-21000000 79972 A +rs60133865 single 22:20000001-21000000 80021 G +rs2286925 single 22:20000001-21000000 80446 A +rs138402987 single 22:20000001-21000000 80796 A +rs9606243 single 22:20000001-21000000 80926 G +rs116662725 single 22:20000001-21000000 80959 G +rs77989302 single 22:20000001-21000000 81517 A +rs7291773 single 22:20000001-21000000 81675 C +rs1640297 single 22:20000001-21000000 81851 C +rs2286926 single 22:20000001-21000000 82073 T +rs35569747 single 22:20000001-21000000 82292 G +rs55929151 single 22:20000001-21000000 82565 T +rs1807527 single 22:20000001-21000000 82861 T +rs8141289 single 22:20000001-21000000 82921 T +rs76639574 single 22:20000001-21000000 82945 C +rs116089709 single 22:20000001-21000000 83426 T +rs139814453 deletion 22:20000001-21000000 83500 3 +rs9606245 single 22:20000001-21000000 84680 A +rs59528277 single 22:20000001-21000000 84820 C +rs62894660 single 22:20000001-21000000 85354 A +rs113504177 single 22:20000001-21000000 85572 G +rs174890 single 22:20000001-21000000 85678 A +rs74858445 single 22:20000001-21000000 85804 T +rs7288396 single 22:20000001-21000000 86570 T +rs7284918 single 22:20000001-21000000 86736 C +rs79374459 single 22:20000001-21000000 87187 A +rs79061783 single 22:20000001-21000000 87257 T +rs73389779 single 22:20000001-21000000 87374 T +rs78119820 single 22:20000001-21000000 87399 T +rs9606247 single 22:20000001-21000000 87472 A +rs9606248 single 22:20000001-21000000 87538 G +rs1628967 single 22:20000001-21000000 87644 G +rs4276104 single 22:20000001-21000000 87691 A +rs9606249 single 22:20000001-21000000 87749 T +rs77437399 single 22:20000001-21000000 88323 T +rs12170420 single 22:20000001-21000000 88469 T +rs34220917 single 22:20000001-21000000 88662 G +rs78743119 single 22:20000001-21000000 88802 C +rs112297714 single 22:20000001-21000000 89082 A +rs113307754 single 22:20000001-21000000 89270 G +rs73389783 single 22:20000001-21000000 89523 T +rs174891 single 22:20000001-21000000 89750 C +rs9605062 single 22:20000001-21000000 89879 C +rs9605063 single 22:20000001-21000000 90037 T +rs9606250 single 22:20000001-21000000 90191 T +rs144836942 single 22:20000001-21000000 90612 G +rs112346953 deletion 22:20000001-21000000 90865 4 +rs75810475 single 22:20000001-21000000 90944 C +rs75728310 single 22:20000001-21000000 91192 C +rs2904565 single 22:20000001-21000000 91627 T +rs1633418 single 22:20000001-21000000 91755 C +rs112367533 single 22:20000001-21000000 91832 A +rs11705462 single 22:20000001-21000000 92411 A +rs9606251 single 22:20000001-21000000 92776 A +rs9605065 single 22:20000001-21000000 92962 G +rs9606252 single 22:20000001-21000000 92995 T +rs443678 single 22:20000001-21000000 93125 C +rs8139107 single 22:20000001-21000000 93287 T +rs8139591 single 22:20000001-21000000 93316 G +rs8139374 single 22:20000001-21000000 93521 T +rs113088659 single 22:20000001-21000000 93966 A +rs113088659 single 22:20000001-21000000 93966 C +rs113088659 single 22:20000001-21000000 93966 T +rs4819529 single 22:20000001-21000000 94262 T +rs149617395 deletion 22:20000001-21000000 94569 3 +rs74689531 single 22:20000001-21000000 95442 A +rs56689361 single 22:20000001-21000000 95681 C +rs146106255 insertion 22:20000001-21000000 96168 G +rs1633442 single 22:20000001-21000000 96313 A +rs77725161 single 22:20000001-21000000 96394 G +rs79989360 single 22:20000001-21000000 97244 G +rs73389786 single 22:20000001-21000000 97335 G +rs41281423 single 22:20000001-21000000 97729 T +rs41281425 single 22:20000001-21000000 98167 C +rs1640299 single 22:20000001-21000000 98358 G +rs2286928 single 22:20000001-21000000 98520 A +rs417309 single 22:20000001-21000000 98543 A +rs142317498 deletion 22:20000001-21000000 98574 4 +rs73389791 single 22:20000001-21000000 98795 T +rs720014 single 22:20000001-21000000 98881 C +rs1063286 single 22:20000001-21000000 99245 C +rs114225267 single 22:20000001-21000000 99298 A +rs3757 single 22:20000001-21000000 99330 A +rs145947632 deletion 22:20000001-21000000 99579 2 +rs9605066 single 22:20000001-21000000 99653 T +rs73389792 single 22:20000001-21000000 99751 T +rs1048659 single 22:20000001-21000000 99890 G +rs113958995 single 22:20000001-21000000 99940 A +rs447017 single 22:20000001-21000000 100157 C +rs56997592 single 22:20000001-21000000 100386 A +rs9606254 single 22:20000001-21000000 100408 T +rs1633445 single 22:20000001-21000000 100595 C +rs73877139 single 22:20000001-21000000 100910 T +rs117918233 single 22:20000001-21000000 101342 T +rs111617686 insertion 22:20000001-21000000 101392 CT +rs8142540 single 22:20000001-21000000 101433 A +rs78218055 single 22:20000001-21000000 101630 T +rs59276810 single 22:20000001-21000000 102045 T +rs885980 single 22:20000001-21000000 102089 C +rs2073777 single 22:20000001-21000000 102749 T +rs77201758 single 22:20000001-21000000 103011 A +rs79886149 single 22:20000001-21000000 103188 C +rs9605067 single 22:20000001-21000000 103262 T +rs59177373 single 22:20000001-21000000 103461 T +rs2008701 single 22:20000001-21000000 104234 T +rs114221480 single 22:20000001-21000000 104267 G +rs395446 single 22:20000001-21000000 104300 C +rs713982 single 22:20000001-21000000 104818 C +rs2286929 single 22:20000001-21000000 104852 G +rs555759275 single 22:20000001-21000000 105227 A +rs737871 single 22:20000001-21000000 105640 T +rs4589855 single 22:20000001-21000000 106068 A +rs2871050 single 22:20000001-21000000 106103 C +rs28496942 single 22:20000001-21000000 106304 T +rs140554045 single 22:20000001-21000000 107063 A +rs60558247 single 22:20000001-21000000 107112 T +rs78885732 single 22:20000001-21000000 107399 C +rs73877140 single 22:20000001-21000000 107463 T +rs2238798 single 22:20000001-21000000 107728 A +rs78632306 deletion 22:20000001-21000000 107855 2 +rs5992511 single 22:20000001-21000000 107914 C +rs75229755 single 22:20000001-21000000 107956 C +rs73877141 single 22:20000001-21000000 108061 C +rs9606256 single 22:20000001-21000000 108499 A +rs61127939 single 22:20000001-21000000 108550 G +rs111522241 single 22:20000001-21000000 108735 G +rs2871051 single 22:20000001-21000000 108939 G +rs1640407 single 22:20000001-21000000 109087 T +rs2238799 single 22:20000001-21000000 109324 G +rs139120568 insertion 22:20000001-21000000 109557 CC +rs72490649 single 22:20000001-21000000 109669 T +rs548036766 single 22:20000001-21000000 110312 G +rs572135609 deletion 22:20000001-21000000 110422 17 +rs117243758 single 22:20000001-21000000 110660 A +rs144916982 insertion 22:20000001-21000000 110770 A +rs143558410 deletion 22:20000001-21000000 110825 1 +rs200793138 deletion 22:20000001-21000000 110939 19 +rs76318258 single 22:20000001-21000000 111675 T +rs100798 single 22:20000001-21000000 111728 T +rs114855038 single 22:20000001-21000000 111857 C +rs140198500 deletion 22:20000001-21000000 111970 1 +rs73391904 single 22:20000001-21000000 112228 T +rs5844407 insertion 22:20000001-21000000 112343 C +rs111795946 insertion 22:20000001-21000000 112513 G +rs73391907 single 22:20000001-21000000 112621 C +rs114654023 single 22:20000001-21000000 112751 T +rs175162 single 22:20000001-21000000 113252 G +rs73391909 single 22:20000001-21000000 113335 T +rs175163 single 22:20000001-21000000 113776 C +rs147429452 single 22:20000001-21000000 113808 T +rs143470990 deletion 22:20000001-21000000 114717 1 +rs58050290 single 22:20000001-21000000 114877 A +rs79918302 single 22:20000001-21000000 114949 C +rs145735203 deletion 22:20000001-21000000 115258 4 +rs77648957 single 22:20000001-21000000 115412 A +rs77856381 single 22:20000001-21000000 115468 A +rs79100373 single 22:20000001-21000000 115509 C +rs175164 single 22:20000001-21000000 115561 T +rs28415889 single 22:20000001-21000000 115675 A +rs74276833 single 22:20000001-21000000 115871 A +rs175165 single 22:20000001-21000000 116014 G +rs76243800 single 22:20000001-21000000 116095 A +rs175166 single 22:20000001-21000000 116181 G +rs62219901 single 22:20000001-21000000 116593 A +rs175167 single 22:20000001-21000000 116669 T +rs175168 single 22:20000001-21000000 116905 T +rs2871052 single 22:20000001-21000000 116971 C +rs2871053 single 22:20000001-21000000 117045 C +rs80098812 single 22:20000001-21000000 117083 T +rs117718692 single 22:20000001-21000000 117343 T +rs117422471 single 22:20000001-21000000 117644 G +rs139564597 single 22:20000001-21000000 118309 A +rs41281437 single 22:20000001-21000000 118351 C +rs41281439 single 22:20000001-21000000 118449 C +rs533822857 deletion 22:20000001-21000000 118621 1 +rs146644744 single 22:20000001-21000000 118777 A +rs113118838 single 22:20000001-21000000 118913 C +rs76972128 single 22:20000001-21000000 119001 G +rs191584744 single 22:20000001-21000000 119176 C +rs187564771 single 22:20000001-21000000 119207 A +rs8135702 single 22:20000001-21000000 119244 C +rs8137316 single 22:20000001-21000000 119301 C +rs545014283 insertion 22:20000001-21000000 119343 CCG +rs9606258 single 22:20000001-21000000 119711 G +rs77304385 single 22:20000001-21000000 119883 A +rs62219902 single 22:20000001-21000000 119929 G +rs142441474 single 22:20000001-21000000 119983 T +rs151120156 single 22:20000001-21000000 120978 T +rs175170 single 22:20000001-21000000 121079 T +rs113514212 single 22:20000001-21000000 121210 T +rs60407076 single 22:20000001-21000000 121644 A +rs383129 single 22:20000001-21000000 121841 T +rs75031525 single 22:20000001-21000000 122090 G +rs201045886 insertion 22:20000001-21000000 122644 T +rs116955623 single 22:20000001-21000000 123011 G +rs175173 single 22:20000001-21000000 123234 T +rs60292854 single 22:20000001-21000000 123504 C +rs116320840 single 22:20000001-21000000 124312 C +rs114111317 single 22:20000001-21000000 124669 G +rs149005029 deletion 22:20000001-21000000 124762 3 +rs117746982 single 22:20000001-21000000 125199 T +rs116846796 single 22:20000001-21000000 125701 C +rs73391922 single 22:20000001-21000000 126005 G +rs117318384 single 22:20000001-21000000 126467 T +rs45450699 single 22:20000001-21000000 126701 T +rs61737216 single 22:20000001-21000000 126740 T +rs175174 single 22:20000001-21000000 127553 G +rs175175 single 22:20000001-21000000 128650 G +rs79425519 single 22:20000001-21000000 128673 C +rs2286930 single 22:20000001-21000000 128879 A +rs77480122 single 22:20000001-21000000 129105 C +rs79627501 single 22:20000001-21000000 129489 T +rs175177 single 22:20000001-21000000 129537 A +rs11704034 single 22:20000001-21000000 129741 C +rs74491992 single 22:20000001-21000000 129967 A +rs117183915 single 22:20000001-21000000 130147 G +rs150179091 single 22:20000001-21000000 130625 T +rs537210848 single 22:20000001-21000000 130699 C +rs115574320 single 22:20000001-21000000 131054 T +rs9605069 single 22:20000001-21000000 131114 T +rs3747072 single 22:20000001-21000000 131426 C +rs117888991 single 22:20000001-21000000 132298 C +rs4819866 single 22:20000001-21000000 132459 T +rs175178 single 22:20000001-21000000 132637 A +rs175179 single 22:20000001-21000000 132971 G +rs114492336 single 22:20000001-21000000 133242 T +rs11556521 single 22:20000001-21000000 133289 C +rs1974652 single 22:20000001-21000000 134146 G +rs1974653 single 22:20000001-21000000 134349 A +rs9606261 single 22:20000001-21000000 134441 C +rs11705346 single 22:20000001-21000000 134524 T +rs9605070 single 22:20000001-21000000 134738 T +rs60730595 single 22:20000001-21000000 134973 T +rs527450612 single 22:20000001-21000000 135096 T +rs7290959 single 22:20000001-21000000 135210 C +rs2292570 single 22:20000001-21000000 135339 C +rs7286804 single 22:20000001-21000000 135382 T +rs9606262 single 22:20000001-21000000 135584 C +rs8137258 single 22:20000001-21000000 135960 C +rs175180 single 22:20000001-21000000 136107 T +rs175181 single 22:20000001-21000000 136262 A +rs60603127 single 22:20000001-21000000 136330 T +rs4819867 single 22:20000001-21000000 136378 A +rs56959114 single 22:20000001-21000000 136477 G +rs73877146 single 22:20000001-21000000 136605 C +rs75274389 single 22:20000001-21000000 136638 T +rs7291332 single 22:20000001-21000000 136665 A +rs7291332 single 22:20000001-21000000 136665 C +rs548968027 insertion 22:20000001-21000000 136804 C +rs9606264 single 22:20000001-21000000 137045 A +rs8142411 single 22:20000001-21000000 137408 C +rs368639630 deletion 22:20000001-21000000 137433 1 +rs116805844 single 22:20000001-21000000 137616 T +rs139050179 single 22:20000001-21000000 137722 T +rs3887519 single 22:20000001-21000000 137821 G +rs560586592 insertion 22:20000001-21000000 137948 TGGGGC +rs560586592 insertion 22:20000001-21000000 137948 TGGGGCTGGGGC +rs73391926 single 22:20000001-21000000 138104 C +rs77065155 single 22:20000001-21000000 138764 T +rs76091326 single 22:20000001-21000000 138785 A +rs3885541 single 22:20000001-21000000 138892 A +rs114106572 single 22:20000001-21000000 138976 T +rs59634879 single 22:20000001-21000000 139164 A +rs9605071 single 22:20000001-21000000 139203 C +rs175182 single 22:20000001-21000000 139298 T +rs175183 single 22:20000001-21000000 139339 T +rs138336705 single 22:20000001-21000000 139539 C +rs186157328 single 22:20000001-21000000 139606 T +rs73877149 single 22:20000001-21000000 140153 T +rs80308524 insertion 22:20000001-21000000 140234 C +rs16982973 single 22:20000001-21000000 140294 T +rs4819869 single 22:20000001-21000000 141061 A +rs595224 single 22:20000001-21000000 141991 G +rs619015 single 22:20000001-21000000 142378 G +rs11913445 single 22:20000001-21000000 142512 A +rs625686 single 22:20000001-21000000 142931 T +rs117085592 single 22:20000001-21000000 143398 T +rs638956 single 22:20000001-21000000 143625 T +rs639516 single 22:20000001-21000000 143781 T +rs8136462 single 22:20000001-21000000 143860 A +rs73150878 single 22:20000001-21000000 143903 T +rs1860943 single 22:20000001-21000000 144239 C +rs568827214 deletion 22:20000001-21000000 144527 1 +rs653448 single 22:20000001-21000000 144559 T +rs649737 single 22:20000001-21000000 144662 G +rs9605073 single 22:20000001-21000000 144752 A +rs78426131 single 22:20000001-21000000 144795 A +rs738078 single 22:20000001-21000000 144856 A +rs175184 single 22:20000001-21000000 144901 C +rs60321341 single 22:20000001-21000000 145034 T +rs175185 single 22:20000001-21000000 145120 G +rs9606269 single 22:20000001-21000000 145257 T +rs114715156 single 22:20000001-21000000 145331 G +rs17817803 single 22:20000001-21000000 145525 T +rs666346 single 22:20000001-21000000 146084 C +rs670708 single 22:20000001-21000000 146148 A +rs62218076 single 22:20000001-21000000 146497 A +rs9605074 single 22:20000001-21000000 146532 A +rs175187 single 22:20000001-21000000 146794 C +rs2106148 single 22:20000001-21000000 146879 A +rs680725 single 22:20000001-21000000 146953 C +rs594652 single 22:20000001-21000000 147206 A +rs584567 single 22:20000001-21000000 147279 G +rs5992515 single 22:20000001-21000000 147391 A +rs117643825 single 22:20000001-21000000 147904 A +rs588536 single 22:20000001-21000000 148117 G +rs9618744 single 22:20000001-21000000 148157 G +rs9618745 single 22:20000001-21000000 148181 C +rs599380 single 22:20000001-21000000 148242 C +rs599434 single 22:20000001-21000000 148282 C +rs1640282 single 22:20000001-21000000 148366 T +rs1640284 single 22:20000001-21000000 148587 G +rs701450 single 22:20000001-21000000 148682 C +rs701449 single 22:20000001-21000000 148740 T +rs8138714 single 22:20000001-21000000 149169 G +rs148485532 single 22:20000001-21000000 149204 T +rs60242968 single 22:20000001-21000000 149470 T +rs73391941 single 22:20000001-21000000 149514 G +rs57629764 single 22:20000001-21000000 149658 G +rs12171242 single 22:20000001-21000000 149807 C +rs146217113 single 22:20000001-21000000 149860 C +rs115554508 single 22:20000001-21000000 149919 A +rs550118721 insertion 22:20000001-21000000 149986 ACT +rs371812250 single 22:20000001-21000000 151056 C +rs111213231 single 22:20000001-21000000 151153 T +rs531796616 deletion 22:20000001-21000000 151554 3 +rs190277665 single 22:20000001-21000000 151600 C +rs571803356 insertion 22:20000001-21000000 151725 ACC +rs374075810 single 22:20000001-21000000 151772 A +rs139580779 single 22:20000001-21000000 151798 C +rs549131213 insertion 22:20000001-21000000 151890 ACCATC +rs539377113 insertion 22:20000001-21000000 151992 ATCACT +rs453205 single 22:20000001-21000000 152558 C +rs62218079 single 22:20000001-21000000 152861 A +rs629665 single 22:20000001-21000000 152907 C +rs682114 single 22:20000001-21000000 152931 A +rs112329860 single 22:20000001-21000000 153458 C +rs454656 single 22:20000001-21000000 153623 C +rs449360 single 22:20000001-21000000 153656 A +rs112413245 single 22:20000001-21000000 153738 A +rs111691053 single 22:20000001-21000000 153889 G +rs415796 single 22:20000001-21000000 154320 A +rs422213 single 22:20000001-21000000 154726 G +rs603084 single 22:20000001-21000000 154767 G +rs373747 single 22:20000001-21000000 155191 C +rs605321 single 22:20000001-21000000 155273 T +rs423543 single 22:20000001-21000000 155297 A +rs175191 single 22:20000001-21000000 155665 A +rs77886622 single 22:20000001-21000000 155742 A +rs384110 single 22:20000001-21000000 155982 C +rs74670780 single 22:20000001-21000000 156057 T +rs429994 single 22:20000001-21000000 156110 G +rs28384 single 22:20000001-21000000 156414 C +rs73391947 single 22:20000001-21000000 156598 A +rs105273 single 22:20000001-21000000 156743 A +rs74898296 single 22:20000001-21000000 156852 C +rs5992517 single 22:20000001-21000000 156885 A +rs117487307 single 22:20000001-21000000 157217 T +rs9605078 single 22:20000001-21000000 157298 T +rs2010063 single 22:20000001-21000000 157964 A +rs139231218 single 22:20000001-21000000 158242 T +rs607556 single 22:20000001-21000000 158297 C +rs738026 single 22:20000001-21000000 158332 A +rs1153415 single 22:20000001-21000000 159048 G +rs74550883 single 22:20000001-21000000 159167 C +rs622741 single 22:20000001-21000000 159309 A +rs1153416 single 22:20000001-21000000 159346 T +rs111837408 single 22:20000001-21000000 159421 C +rs201558243 single 22:20000001-21000000 159460 A +rs624146 single 22:20000001-21000000 159698 G +rs625467 single 22:20000001-21000000 159980 C +rs625467 single 22:20000001-21000000 159980 T +rs77178912 single 22:20000001-21000000 160080 A +rs455127 single 22:20000001-21000000 160204 T +rs5992518 single 22:20000001-21000000 160288 G +rs144519743 deletion 22:20000001-21000000 160329 10 +rs72236103 deletion 22:20000001-21000000 160527 4 +rs67222192 single 22:20000001-21000000 160585 G +rs117988645 single 22:20000001-21000000 160671 T +rs116550458 single 22:20000001-21000000 160729 A +rs175192 single 22:20000001-21000000 160770 T +rs1210776 single 22:20000001-21000000 160971 C +rs9617862 single 22:20000001-21000000 161029 T +rs9605079 single 22:20000001-21000000 161294 A +rs1153417 single 22:20000001-21000000 161316 C +rs1153418 single 22:20000001-21000000 161423 C +rs8136093 single 22:20000001-21000000 161604 A +rs615103 single 22:20000001-21000000 161737 C +rs737826 single 22:20000001-21000000 162620 A +rs175193 single 22:20000001-21000000 162722 C +rs201608214 insertion 22:20000001-21000000 162758 CT +rs201608214 insertion 22:20000001-21000000 162758 CTGCC +rs175194 single 22:20000001-21000000 163069 A +rs8137965 single 22:20000001-21000000 163461 G +rs75442801 single 22:20000001-21000000 163832 T +rs11464394 insertion 22:20000001-21000000 164318 G +rs404060 single 22:20000001-21000000 164359 C +rs5748545 single 22:20000001-21000000 164579 T +rs405011 single 22:20000001-21000000 164695 T +rs412160 single 22:20000001-21000000 164801 T +rs175195 single 22:20000001-21000000 164948 A +rs79507494 single 22:20000001-21000000 165007 T +rs4474965 single 22:20000001-21000000 165265 A +rs79312272 single 22:20000001-21000000 165363 C +rs175196 single 22:20000001-21000000 165438 A +rs175197 single 22:20000001-21000000 165631 T +rs1153419 single 22:20000001-21000000 165830 A +rs58319702 single 22:20000001-21000000 165863 T +rs175198 single 22:20000001-21000000 166012 T +rs80093097 single 22:20000001-21000000 166183 T +rs1153421 single 22:20000001-21000000 166221 T +rs74815951 single 22:20000001-21000000 166685 A +rs419438 single 22:20000001-21000000 166722 G +rs451455 single 22:20000001-21000000 166910 A +rs117888625 single 22:20000001-21000000 167009 T +rs79525085 single 22:20000001-21000000 167405 T +rs75267189 single 22:20000001-21000000 167784 A +rs116804714 single 22:20000001-21000000 167852 A +rs175199 single 22:20000001-21000000 168294 T +rs175200 single 22:20000001-21000000 168508 A +rs390906 single 22:20000001-21000000 168603 T +rs111441035 single 22:20000001-21000000 168624 C +rs117700651 single 22:20000001-21000000 168900 T +rs150450872 deletion 22:20000001-21000000 168982 9 +rs175203 single 22:20000001-21000000 169036 C +rs175204 single 22:20000001-21000000 169093 T +rs393174 single 22:20000001-21000000 169366 T +rs73150891 single 22:20000001-21000000 169421 A +rs12484240 single 22:20000001-21000000 169456 A +rs438798 single 22:20000001-21000000 169498 G +rs78429682 single 22:20000001-21000000 169895 T +rs9306236 single 22:20000001-21000000 170092 A +rs73391970 single 22:20000001-21000000 170776 T +rs658073 single 22:20000001-21000000 170995 A +rs658583 single 22:20000001-21000000 171145 G +rs10212087 single 22:20000001-21000000 171250 T +rs10212092 single 22:20000001-21000000 171348 G +rs74880766 single 22:20000001-21000000 171374 G +rs659918 single 22:20000001-21000000 171448 G +rs9618747 single 22:20000001-21000000 171567 T +rs618773 single 22:20000001-21000000 171652 T +rs671840 single 22:20000001-21000000 171813 C +rs117780955 single 22:20000001-21000000 171875 G +rs75275392 single 22:20000001-21000000 172047 A +rs114977667 single 22:20000001-21000000 172141 A +rs701447 single 22:20000001-21000000 172312 T +rs632194 single 22:20000001-21000000 172405 T +rs10212004 single 22:20000001-21000000 172818 T +rs687264 single 22:20000001-21000000 172900 C +rs5844408 insertion 22:20000001-21000000 173497 G +rs175206 single 22:20000001-21000000 173525 C +rs5993927 single 22:20000001-21000000 173576 A +rs79270025 single 22:20000001-21000000 174099 G +rs118095966 single 22:20000001-21000000 174269 C +rs74931122 single 22:20000001-21000000 174497 T +rs55911007 deletion 22:20000001-21000000 174561 1 +rs663353 single 22:20000001-21000000 174711 A +rs75766 single 22:20000001-21000000 174852 A +rs75765 single 22:20000001-21000000 174958 T +rs9618749 single 22:20000001-21000000 175222 C +rs117565467 single 22:20000001-21000000 175367 T +rs7290062 single 22:20000001-21000000 175472 C +rs116622544 single 22:20000001-21000000 175571 C +rs79714974 single 22:20000001-21000000 175618 A +rs139587601 single 22:20000001-21000000 176518 A +rs201946414 deletion 22:20000001-21000000 176558 4 +rs149723481 single 22:20000001-21000000 176704 T +rs175207 single 22:20000001-21000000 177060 T +rs597859 single 22:20000001-21000000 177218 A +rs175208 single 22:20000001-21000000 177319 T +rs667987 single 22:20000001-21000000 177594 G +rs5992519 single 22:20000001-21000000 177644 T +rs599687 single 22:20000001-21000000 177668 G +rs600545 single 22:20000001-21000000 177847 G +rs600608 single 22:20000001-21000000 177890 G +rs601014 single 22:20000001-21000000 177942 A +rs670147 single 22:20000001-21000000 178022 C +rs601541 single 22:20000001-21000000 178094 A +rs2871058 single 22:20000001-21000000 178146 G +rs2871059 single 22:20000001-21000000 178174 G +rs4819874 single 22:20000001-21000000 178204 G +rs684186 single 22:20000001-21000000 178798 G +rs175210 single 22:20000001-21000000 178914 T +rs4819876 single 22:20000001-21000000 178988 T +rs4819877 single 22:20000001-21000000 179038 C +rs1640409 single 22:20000001-21000000 179095 C +rs137898282 single 22:20000001-21000000 179132 A +rs78736437 single 22:20000001-21000000 179172 A +rs1642138 single 22:20000001-21000000 179222 T +rs701446 single 22:20000001-21000000 179254 C +rs701445 single 22:20000001-21000000 179285 A +rs627833 single 22:20000001-21000000 179338 A +rs627891 single 22:20000001-21000000 179378 A +rs5992520 single 22:20000001-21000000 179439 T +rs589754 single 22:20000001-21000000 179502 C +rs76414747 single 22:20000001-21000000 180070 T +rs56252913 single 22:20000001-21000000 180103 A +rs701444 single 22:20000001-21000000 180454 A +rs116924716 single 22:20000001-21000000 181042 A +rs646002 single 22:20000001-21000000 181125 T +rs917837 single 22:20000001-21000000 181210 A +rs147687370 single 22:20000001-21000000 181487 T +rs676524 single 22:20000001-21000000 181983 T +rs58263193 single 22:20000001-21000000 182068 T +rs689135 single 22:20000001-21000000 182455 T +rs34529390 deletion 22:20000001-21000000 182566 1 +rs634473 single 22:20000001-21000000 182636 A +rs635394 single 22:20000001-21000000 182863 G +rs583898 single 22:20000001-21000000 183029 A +rs637599 single 22:20000001-21000000 183344 C +rs696884 single 22:20000001-21000000 183508 G +rs11089331 single 22:20000001-21000000 184001 A +rs652976 single 22:20000001-21000000 184444 C +rs78412557 single 22:20000001-21000000 184475 G +rs611299 single 22:20000001-21000000 184576 A +rs612140 single 22:20000001-21000000 184709 G +rs10222234 single 22:20000001-21000000 184832 A +rs73394005 single 22:20000001-21000000 184936 T +rs80115931 single 22:20000001-21000000 184960 A +rs665780 single 22:20000001-21000000 185010 C +rs613930 single 22:20000001-21000000 185118 A +rs666349 single 22:20000001-21000000 185190 C +rs625704 single 22:20000001-21000000 185456 A +rs625749 single 22:20000001-21000000 185486 T +rs3081798 insertion 22:20000001-21000000 185699 TCT +rs138361379 single 22:20000001-21000000 185886 T +rs627919 single 22:20000001-21000000 185965 C +rs680652 single 22:20000001-21000000 185998 G +rs628355 single 22:20000001-21000000 186073 C +rs681112 single 22:20000001-21000000 186101 C +rs7292285 single 22:20000001-21000000 186549 C +rs77264923 single 22:20000001-21000000 186635 A +rs558869332 deletion 22:20000001-21000000 186986 4 +rs701442 single 22:20000001-21000000 187130 G +rs655618 single 22:20000001-21000000 187542 C +rs655656 single 22:20000001-21000000 187574 T +rs73394008 single 22:20000001-21000000 187922 G +rs658298 single 22:20000001-21000000 188159 C +rs658353 single 22:20000001-21000000 188198 C +rs114252382 single 22:20000001-21000000 188344 C +rs670665 single 22:20000001-21000000 188608 T +rs144211478 single 22:20000001-21000000 188745 T +rs574475587 insertion 22:20000001-21000000 188856 A +rs143552218 deletion 22:20000001-21000000 188919 12 +rs672570 single 22:20000001-21000000 189076 T +rs672966 single 22:20000001-21000000 189119 T +rs185065728 single 22:20000001-21000000 189151 A +rs673062 single 22:20000001-21000000 189201 A +rs684423 single 22:20000001-21000000 189377 T +rs62218156 single 22:20000001-21000000 189407 A +rs685667 single 22:20000001-21000000 189621 T +rs686104 single 22:20000001-21000000 189721 C +rs2098257 single 22:20000001-21000000 190054 T +rs687965 single 22:20000001-21000000 190173 T +rs114137281 single 22:20000001-21000000 190378 A +rs738079 single 22:20000001-21000000 190412 A +rs592681 single 22:20000001-21000000 190696 A +rs661900 single 22:20000001-21000000 190759 C +rs741414 single 22:20000001-21000000 191545 G +rs117701200 single 22:20000001-21000000 191590 A +rs117182259 single 22:20000001-21000000 192146 G +rs9605084 single 22:20000001-21000000 192330 G +rs12485013 single 22:20000001-21000000 192543 A +rs638150 single 22:20000001-21000000 192585 C +rs41282451 single 22:20000001-21000000 193098 T +rs585450 single 22:20000001-21000000 193158 A +rs585450 single 22:20000001-21000000 193158 G +rs114911618 single 22:20000001-21000000 193818 T +rs654389 single 22:20000001-21000000 193860 C +rs144829478 single 22:20000001-21000000 195038 T +rs75367243 single 22:20000001-21000000 195485 A +rs627235 single 22:20000001-21000000 195590 T +rs17818762 single 22:20000001-21000000 195729 T +rs35630489 single 22:20000001-21000000 195777 C +rs13056865 single 22:20000001-21000000 195927 A +rs17746105 single 22:20000001-21000000 195998 C +rs17746115 single 22:20000001-21000000 196045 A +rs75313062 single 22:20000001-21000000 196181 C +rs77763468 single 22:20000001-21000000 196281 G +rs67477750 single 22:20000001-21000000 196449 A +rs35306520 single 22:20000001-21000000 196565 A +rs9605085 single 22:20000001-21000000 196675 G +rs62219680 single 22:20000001-21000000 196735 G +rs9606276 single 22:20000001-21000000 196771 G +rs17818792 single 22:20000001-21000000 197334 A +rs111479272 single 22:20000001-21000000 197456 A +rs11912140 single 22:20000001-21000000 198134 A +rs9606277 single 22:20000001-21000000 198203 T +rs9606279 single 22:20000001-21000000 198238 G +rs9606280 single 22:20000001-21000000 198340 C +rs17746140 single 22:20000001-21000000 198531 A +rs9606281 single 22:20000001-21000000 198583 T +rs78864465 single 22:20000001-21000000 198724 T +rs145389230 insertion 22:20000001-21000000 198805 T +rs115483801 single 22:20000001-21000000 199232 T +rs9605086 single 22:20000001-21000000 199578 A +rs9605086 single 22:20000001-21000000 199578 T +rs116036640 single 22:20000001-21000000 200128 C +rs79330709 single 22:20000001-21000000 200358 A +rs9606282 single 22:20000001-21000000 200512 G +rs73394013 single 22:20000001-21000000 200616 T +rs79714928 single 22:20000001-21000000 200653 A +rs116485434 single 22:20000001-21000000 201052 T +rs9606283 single 22:20000001-21000000 201429 T +rs9605087 single 22:20000001-21000000 201736 A +rs730669 single 22:20000001-21000000 201953 T +rs75747087 single 22:20000001-21000000 202002 T +rs9606284 single 22:20000001-21000000 202113 C +rs9606285 single 22:20000001-21000000 202159 A +rs9606286 single 22:20000001-21000000 202421 T +rs35945458 single 22:20000001-21000000 202504 G +rs587317 single 22:20000001-21000000 202666 C +rs71312739 single 22:20000001-21000000 202711 C +rs640207 single 22:20000001-21000000 202788 A +rs77527928 single 22:20000001-21000000 202851 A +rs5748552 single 22:20000001-21000000 202958 T +rs9606287 single 22:20000001-21000000 203157 C +rs9606288 single 22:20000001-21000000 203364 C +rs35410261 single 22:20000001-21000000 203389 T +rs9605088 single 22:20000001-21000000 203448 G +rs17746176 single 22:20000001-21000000 203667 A +rs17746176 single 22:20000001-21000000 203667 G +rs17746176 single 22:20000001-21000000 203667 T +rs66790491 single 22:20000001-21000000 203936 T +rs4819530 single 22:20000001-21000000 203996 A +rs2192152 single 22:20000001-21000000 204035 T +rs2192153 single 22:20000001-21000000 204158 T +rs146513613 single 22:20000001-21000000 204233 A +rs542849601 insertion 22:20000001-21000000 204302 A +rs9618751 single 22:20000001-21000000 204602 G +rs5993932 single 22:20000001-21000000 204747 A +rs5993933 single 22:20000001-21000000 204790 T +rs9606289 single 22:20000001-21000000 204922 T +rs77703137 single 22:20000001-21000000 205065 A +rs7293153 single 22:20000001-21000000 205262 A +rs672297 single 22:20000001-21000000 205332 T +rs150406620 insertion 22:20000001-21000000 205758 G +rs1642170 single 22:20000001-21000000 205779 A +rs855066 single 22:20000001-21000000 205831 C +rs184586910 single 22:20000001-21000000 205925 T +rs1642171 single 22:20000001-21000000 206051 C +rs16983093 single 22:20000001-21000000 206263 A +rs16983095 single 22:20000001-21000000 206383 T +rs11403191 insertion 22:20000001-21000000 206493 G +rs76335459 single 22:20000001-21000000 206603 T +rs73394025 single 22:20000001-21000000 206808 T +rs34702408 single 22:20000001-21000000 207005 A +rs16983098 single 22:20000001-21000000 207140 C +rs17818857 single 22:20000001-21000000 207327 C +rs79041058 single 22:20000001-21000000 207439 T +rs1640426 single 22:20000001-21000000 207824 T +rs535028580 insertion 22:20000001-21000000 207877 CCT +rs855067 single 22:20000001-21000000 208059 C +rs117866503 single 22:20000001-21000000 208134 C +rs58095234 single 22:20000001-21000000 208259 T +rs117251787 single 22:20000001-21000000 208307 A +rs11382517 insertion 22:20000001-21000000 208347 C +rs16983102 single 22:20000001-21000000 208416 T +rs79718986 single 22:20000001-21000000 208498 T +rs138984011 deletion 22:20000001-21000000 208603 1 +rs140668404 deletion 22:20000001-21000000 208652 1 +rs5748554 single 22:20000001-21000000 209029 C +rs145930670 single 22:20000001-21000000 209121 T +rs1642172 single 22:20000001-21000000 209424 A +rs77300267 single 22:20000001-21000000 209448 A +rs5748555 single 22:20000001-21000000 209486 A +rs145585391 single 22:20000001-21000000 209706 T +rs1640348 single 22:20000001-21000000 209774 G +rs1640349 single 22:20000001-21000000 210054 A +rs1640349 single 22:20000001-21000000 210054 T +rs1642173 single 22:20000001-21000000 210118 A +rs117027931 single 22:20000001-21000000 210183 A +rs1640350 single 22:20000001-21000000 210362 T +rs12166707 single 22:20000001-21000000 210429 C +rs117725357 single 22:20000001-21000000 210630 A +rs8142885 single 22:20000001-21000000 211138 C +rs1640351 single 22:20000001-21000000 211327 G +rs1642174 single 22:20000001-21000000 211348 G +rs60356256 deletion 22:20000001-21000000 211529 1 +rs1640352 single 22:20000001-21000000 211560 G +rs56350811 single 22:20000001-21000000 211689 T +rs141901933 single 22:20000001-21000000 211790 C +rs111163807 single 22:20000001-21000000 212539 G +rs71718621 deletion 22:20000001-21000000 212584 2 +rs536300675 single 22:20000001-21000000 212660 G +rs143894206 insertion 22:20000001-21000000 212700 AA +rs62651450 single 22:20000001-21000000 212736 C +rs368437419 single 22:20000001-21000000 212911 A +rs78870595 deletion 22:20000001-21000000 212947 2 +rs201670381 deletion 22:20000001-21000000 212976 2 +rs111066904 single 22:20000001-21000000 213003 T +rs183700374 single 22:20000001-21000000 213176 T +rs529446461 insertion 22:20000001-21000000 213249 CA +rs140384568 deletion 22:20000001-21000000 213308 4 +rs116821952 single 22:20000001-21000000 213367 C +rs142260528 insertion 22:20000001-21000000 213478 CA +rs4389405 single 22:20000001-21000000 213634 A +rs854962 single 22:20000001-21000000 213677 C +rs1962811 single 22:20000001-21000000 213717 T +rs854964 single 22:20000001-21000000 213757 C +rs701436 single 22:20000001-21000000 213810 G +rs140866047 deletion 22:20000001-21000000 213926 21 +rs114523918 single 22:20000001-21000000 214087 T +rs696883 single 22:20000001-21000000 214224 T +rs114211813 single 22:20000001-21000000 214384 G +rs57810421 single 22:20000001-21000000 214412 G +rs2110150 single 22:20000001-21000000 214484 T +rs77599853 single 22:20000001-21000000 214621 C +rs117156885 single 22:20000001-21000000 214752 T +rs116142588 single 22:20000001-21000000 214781 T +rs701434 single 22:20000001-21000000 214898 T +rs67698406 single 22:20000001-21000000 215190 A +rs80027834 single 22:20000001-21000000 215271 T +rs113169311 insertion 22:20000001-21000000 215376 TGTC +rs75859816 single 22:20000001-21000000 215488 C +rs854965 single 22:20000001-21000000 215569 G +rs701433 single 22:20000001-21000000 215939 C +rs8137809 single 22:20000001-21000000 215980 C +rs8141593 single 22:20000001-21000000 216155 C +rs78061232 single 22:20000001-21000000 216386 T +rs74841242 single 22:20000001-21000000 216455 C +rs150727039 deletion 22:20000001-21000000 216665 1 +rs115687216 single 22:20000001-21000000 216714 A +rs114970991 single 22:20000001-21000000 216783 T +rs77569499 single 22:20000001-21000000 216858 G +rs60594683 single 22:20000001-21000000 217202 A +rs854966 single 22:20000001-21000000 217339 A +rs854967 single 22:20000001-21000000 217627 C +rs62219686 single 22:20000001-21000000 217679 T +rs73877189 single 22:20000001-21000000 217797 T +rs113635983 single 22:20000001-21000000 217867 A +rs77924361 single 22:20000001-21000000 217938 A +rs55974715 single 22:20000001-21000000 218133 A +rs9606290 single 22:20000001-21000000 218236 A +rs56310064 single 22:20000001-21000000 218259 A +rs59497188 single 22:20000001-21000000 218375 A +rs73877191 single 22:20000001-21000000 218517 A +rs73877191 single 22:20000001-21000000 218517 C +rs9618754 single 22:20000001-21000000 218606 T +rs73152989 single 22:20000001-21000000 218751 A +rs854968 single 22:20000001-21000000 218996 A +rs1210818 single 22:20000001-21000000 219171 G +rs62219688 single 22:20000001-21000000 219479 C +rs73394049 single 22:20000001-21000000 219509 T +rs74404487 single 22:20000001-21000000 219570 A +rs117703390 single 22:20000001-21000000 219640 A +rs79892278 single 22:20000001-21000000 219914 A +rs1076449 single 22:20000001-21000000 220110 G +rs2871060 single 22:20000001-21000000 220165 C +rs696882 single 22:20000001-21000000 220336 C +rs113263410 single 22:20000001-21000000 220419 C +rs73877195 single 22:20000001-21000000 220480 T +rs5993935 single 22:20000001-21000000 220763 C +rs854969 single 22:20000001-21000000 220988 A +rs854970 single 22:20000001-21000000 221556 A +rs117600433 single 22:20000001-21000000 221797 A +rs13340092 single 22:20000001-21000000 221826 C +rs9618755 single 22:20000001-21000000 221855 T +rs855073 single 22:20000001-21000000 221962 T +rs10212079 single 22:20000001-21000000 222104 G +rs77601027 single 22:20000001-21000000 222475 G +rs9618756 single 22:20000001-21000000 222622 G +rs113434912 single 22:20000001-21000000 222914 G +rs855075 single 22:20000001-21000000 223024 T +rs114024471 single 22:20000001-21000000 223207 T +rs370354715 insertion 22:20000001-21000000 223341 CCGGCAGGCTACCAA +rs56729142 single 22:20000001-21000000 223468 T +rs78851436 single 22:20000001-21000000 223507 T +rs2871061 single 22:20000001-21000000 224121 T +rs138074275 insertion 22:20000001-21000000 224682 AA +rs116399860 single 22:20000001-21000000 224822 T +rs114153637 single 22:20000001-21000000 224895 A +rs16983133 single 22:20000001-21000000 224980 C +rs78658262 single 22:20000001-21000000 225043 G +rs35400391 insertion 22:20000001-21000000 225143 G +rs112428913 single 22:20000001-21000000 225275 A +rs112428913 single 22:20000001-21000000 225275 T +rs759577 single 22:20000001-21000000 225535 G +rs11913543 single 22:20000001-21000000 225625 C +rs73394077 single 22:20000001-21000000 225748 A +rs73152993 single 22:20000001-21000000 225781 A +rs113186711 single 22:20000001-21000000 226003 A +rs13433573 single 22:20000001-21000000 226075 C +rs115769370 single 22:20000001-21000000 226111 T +rs701431 single 22:20000001-21000000 226454 C +rs115157974 single 22:20000001-21000000 226530 C +rs117480194 single 22:20000001-21000000 226682 T +rs117775417 single 22:20000001-21000000 226788 T +rs80024082 single 22:20000001-21000000 226948 A +rs147191054 insertion 22:20000001-21000000 227090 A +rs13433575 single 22:20000001-21000000 227383 C +rs701430 single 22:20000001-21000000 227550 G +rs73877201 single 22:20000001-21000000 227594 A +rs5993937 single 22:20000001-21000000 227954 G +rs5993937 single 22:20000001-21000000 227954 T +rs701429 single 22:20000001-21000000 228464 T +rs887764 single 22:20000001-21000000 228486 A +rs701428 single 22:20000001-21000000 228541 G +rs114995292 single 22:20000001-21000000 228593 A +rs34031696 single 22:20000001-21000000 228763 A +rs114960593 single 22:20000001-21000000 228826 A +rs74315508 single 22:20000001-21000000 230300 A +rs115511482 single 22:20000001-21000000 231077 T +rs114444096 single 22:20000001-21000000 231544 G +rs149364449 single 22:20000001-21000000 231859 T +rs80121779 single 22:20000001-21000000 232603 A +rs9618759 single 22:20000001-21000000 232662 G +rs34909867 single 22:20000001-21000000 233230 T +rs701427 single 22:20000001-21000000 233267 C +rs854971 single 22:20000001-21000000 233428 C +rs79189372 single 22:20000001-21000000 233538 T +rs117611205 single 22:20000001-21000000 233745 A +rs9606293 single 22:20000001-21000000 233864 A +rs189652039 single 22:20000001-21000000 234090 C +rs74868504 single 22:20000001-21000000 234111 A +rs9606294 single 22:20000001-21000000 234524 T +rs143133500 single 22:20000001-21000000 234617 T +rs77225097 single 22:20000001-21000000 234640 T +rs116703716 single 22:20000001-21000000 234751 C +rs696881 single 22:20000001-21000000 234812 G +rs696880 single 22:20000001-21000000 235199 A +rs140464581 insertion 22:20000001-21000000 235221 A +rs114946480 single 22:20000001-21000000 235498 T +rs150607319 single 22:20000001-21000000 235671 A +rs149419362 single 22:20000001-21000000 235786 A +rs17818126 single 22:20000001-21000000 235972 A +rs117664735 single 22:20000001-21000000 236086 C +rs7290335 single 22:20000001-21000000 236436 A +rs9618761 single 22:20000001-21000000 236631 C +rs111745046 single 22:20000001-21000000 236829 A +rs145052327 single 22:20000001-21000000 236913 G +rs116786539 single 22:20000001-21000000 237050 A +rs79002492 single 22:20000001-21000000 237104 C +rs117333152 single 22:20000001-21000000 237238 C +rs117725102 single 22:20000001-21000000 237329 T +rs145579679 single 22:20000001-21000000 237533 C +rs144718685 insertion 22:20000001-21000000 238771 A +rs112525813 single 22:20000001-21000000 238917 A +rs855077 single 22:20000001-21000000 239080 T +rs200367744 single 22:20000001-21000000 239107 T +rs566415111 insertion 22:20000001-21000000 239429 CAT +rs78143546 single 22:20000001-21000000 239805 G +rs7292462 single 22:20000001-21000000 240188 G +rs701424 single 22:20000001-21000000 240230 T +rs116729469 single 22:20000001-21000000 240841 A +rs1005863 single 22:20000001-21000000 240998 A +rs1567871 single 22:20000001-21000000 241159 T +rs11333422 deletion 22:20000001-21000000 241367 1 +rs7287730 single 22:20000001-21000000 241435 A +rs370890149 single 22:20000001-21000000 241478 T +rs117998532 single 22:20000001-21000000 241619 A +rs142238138 single 22:20000001-21000000 241922 A +rs76826266 single 22:20000001-21000000 242484 C +rs116561438 single 22:20000001-21000000 242521 G +rs117877353 single 22:20000001-21000000 242647 A +rs112291347 single 22:20000001-21000000 242983 G +rs701423 single 22:20000001-21000000 243304 T +rs115304055 single 22:20000001-21000000 243404 A +rs116881746 single 22:20000001-21000000 243651 A +rs117285556 single 22:20000001-21000000 243756 C +rs78055866 single 22:20000001-21000000 244258 T +rs115714416 single 22:20000001-21000000 244550 A +rs9606296 single 22:20000001-21000000 244615 T +rs9606297 single 22:20000001-21000000 244722 T +rs8136268 single 22:20000001-21000000 244814 A +rs4819879 single 22:20000001-21000000 245173 C +rs117060868 single 22:20000001-21000000 245539 G +rs76149327 single 22:20000001-21000000 245733 C +rs701421 single 22:20000001-21000000 246080 A +rs115321896 single 22:20000001-21000000 246199 C +rs58754659 single 22:20000001-21000000 246446 T +rs79810059 single 22:20000001-21000000 246485 T +rs115015860 single 22:20000001-21000000 246618 T +rs115307663 single 22:20000001-21000000 246683 G +rs74933079 single 22:20000001-21000000 247271 C +rs854927 single 22:20000001-21000000 247857 C +rs117839889 single 22:20000001-21000000 247996 T +rs73879307 single 22:20000001-21000000 248172 G +rs73879307 single 22:20000001-21000000 248172 T +rs855050 single 22:20000001-21000000 248390 A +rs855051 single 22:20000001-21000000 248712 G +rs114406286 single 22:20000001-21000000 249037 A +rs79829870 single 22:20000001-21000000 249099 A +rs855052 single 22:20000001-21000000 249420 A +rs855053 single 22:20000001-21000000 249550 C +rs148220813 single 22:20000001-21000000 249580 G +rs148220813 single 22:20000001-21000000 249580 T +rs115273511 single 22:20000001-21000000 249685 G +rs9617866 single 22:20000001-21000000 249716 T +rs146194573 single 22:20000001-21000000 249775 C +rs855054 single 22:20000001-21000000 249806 A +rs1807466 single 22:20000001-21000000 249917 C +rs142689515 single 22:20000001-21000000 250043 C +rs12170447 single 22:20000001-21000000 250546 A +rs12171082 single 22:20000001-21000000 250745 G +rs855055 single 22:20000001-21000000 250918 T +rs12166302 single 22:20000001-21000000 251015 T +rs3970485 single 22:20000001-21000000 251062 C +rs701420 single 22:20000001-21000000 251085 T +rs5748568 single 22:20000001-21000000 251311 C +rs573917653 insertion 22:20000001-21000000 251540 AAAG +rs12166236 single 22:20000001-21000000 251611 A +rs12166774 single 22:20000001-21000000 251632 C +rs73153000 single 22:20000001-21000000 251924 A +rs854928 single 22:20000001-21000000 251953 A +rs116957492 single 22:20000001-21000000 252116 A +rs8143104 single 22:20000001-21000000 252337 G +rs112535005 single 22:20000001-21000000 252398 G +rs855056 single 22:20000001-21000000 252511 A +rs113463158 single 22:20000001-21000000 253199 T +rs141339830 single 22:20000001-21000000 253459 T +rs145089296 single 22:20000001-21000000 253552 A +rs114446548 single 22:20000001-21000000 254194 G +rs7293034 single 22:20000001-21000000 254514 A +rs9617867 single 22:20000001-21000000 254539 G +rs854929 single 22:20000001-21000000 255019 C +rs112035786 single 22:20000001-21000000 255096 T +rs701417 single 22:20000001-21000000 255159 A +rs117475224 single 22:20000001-21000000 255247 A +rs367897714 single 22:20000001-21000000 255354 T +rs117774209 single 22:20000001-21000000 255980 A +rs9618765 single 22:20000001-21000000 256309 T +rs2871065 single 22:20000001-21000000 256803 G +rs3960058 single 22:20000001-21000000 256975 C +rs5993943 single 22:20000001-21000000 257028 A +rs187924471 single 22:20000001-21000000 257235 A +rs12330099 single 22:20000001-21000000 257349 T +rs150288217 single 22:20000001-21000000 258002 T +rs2102667 single 22:20000001-21000000 258144 T +rs34141746 single 22:20000001-21000000 258193 T +rs854930 single 22:20000001-21000000 258410 G +rs116978178 single 22:20000001-21000000 258518 C +rs111641237 single 22:20000001-21000000 258579 T +rs854931 single 22:20000001-21000000 258622 A +rs9617868 single 22:20000001-21000000 258889 T +rs117781464 single 22:20000001-21000000 258969 T +rs113277925 single 22:20000001-21000000 259325 G +rs3091371 insertion 22:20000001-21000000 260111 C +rs3091371 insertion 22:20000001-21000000 260111 T +rs150603492 single 22:20000001-21000000 260244 A +rs71776343 deletion 22:20000001-21000000 260558 9 +rs11350657 deletion 22:20000001-21000000 260731 1 +rs854936 single 22:20000001-21000000 260813 T +rs854937 single 22:20000001-21000000 261080 G +rs62219713 single 22:20000001-21000000 261302 T +rs113297045 single 22:20000001-21000000 261585 T +rs192910773 single 22:20000001-21000000 261686 T +rs854939 single 22:20000001-21000000 261822 G +rs855060 single 22:20000001-21000000 262165 A +rs189886717 single 22:20000001-21000000 262218 T +rs13433533 single 22:20000001-21000000 262338 C +rs565237655 deletion 22:20000001-21000000 262786 1 +rs854940 single 22:20000001-21000000 262852 C +rs36076240 single 22:20000001-21000000 263017 G +rs182008760 single 22:20000001-21000000 263099 T +rs73879318 single 22:20000001-21000000 263212 A +rs150341931 single 22:20000001-21000000 263243 A +rs113436252 deletion 22:20000001-21000000 263332 4 +rs854941 single 22:20000001-21000000 263506 A +rs114029464 single 22:20000001-21000000 263547 T +rs11297569 deletion 22:20000001-21000000 263624 1 +rs187916289 single 22:20000001-21000000 263964 G +rs5993945 single 22:20000001-21000000 263986 C +rs117523061 single 22:20000001-21000000 264055 C +rs854942 single 22:20000001-21000000 264100 A +rs114123407 single 22:20000001-21000000 264151 A +rs114123407 single 22:20000001-21000000 264151 C +rs113787821 single 22:20000001-21000000 264295 A +rs113072881 single 22:20000001-21000000 264325 T +rs151078850 single 22:20000001-21000000 264349 C +rs149903682 single 22:20000001-21000000 264474 A +rs71186647 insertion 22:20000001-21000000 264547 GGTGAGAGGTGTG +rs854944 single 22:20000001-21000000 264936 A +rs112732937 single 22:20000001-21000000 264962 A +rs13433673 single 22:20000001-21000000 265762 G +rs854946 single 22:20000001-21000000 265869 A +rs200714027 single 22:20000001-21000000 265917 A +rs2110151 single 22:20000001-21000000 266002 A +rs566429444 single 22:20000001-21000000 266170 A +rs854947 single 22:20000001-21000000 266353 A +rs854948 single 22:20000001-21000000 266408 T +rs9618767 single 22:20000001-21000000 266471 A +rs701416 single 22:20000001-21000000 266527 C +rs854949 single 22:20000001-21000000 266796 C +rs56211463 insertion 22:20000001-21000000 267023 C +rs855061 single 22:20000001-21000000 267212 A +rs854950 single 22:20000001-21000000 267270 A +rs142729824 single 22:20000001-21000000 267387 A +rs854951 single 22:20000001-21000000 267556 T +rs701415 single 22:20000001-21000000 267688 A +rs191141480 single 22:20000001-21000000 267868 T +rs9618769 single 22:20000001-21000000 268133 C +rs9618770 single 22:20000001-21000000 268211 A +rs11705685 single 22:20000001-21000000 268296 T +rs701414 single 22:20000001-21000000 268482 T +rs143271913 single 22:20000001-21000000 268543 C +rs11705580 single 22:20000001-21000000 268611 A +rs854953 single 22:20000001-21000000 268775 A +rs854954 single 22:20000001-21000000 269134 A +rs201157197 insertion 22:20000001-21000000 269198 TA +rs151068286 single 22:20000001-21000000 269702 T +rs854955 single 22:20000001-21000000 269741 T +rs67659900 single 22:20000001-21000000 270249 C +rs9606308 single 22:20000001-21000000 270366 T +rs5993947 single 22:20000001-21000000 270849 T +rs147109067 single 22:20000001-21000000 271208 T +rs5993948 single 22:20000001-21000000 271286 A +rs113581498 single 22:20000001-21000000 272062 A +rs112262759 single 22:20000001-21000000 272252 C +rs701413 single 22:20000001-21000000 272792 G +rs9617870 single 22:20000001-21000000 272894 T +rs854957 single 22:20000001-21000000 273125 A +rs701412 single 22:20000001-21000000 273403 G +rs12167477 single 22:20000001-21000000 273440 A +rs12167520 single 22:20000001-21000000 273476 A +rs148753980 single 22:20000001-21000000 273519 C +rs854958 single 22:20000001-21000000 273576 C +rs854958 single 22:20000001-21000000 273576 G +rs115983387 single 22:20000001-21000000 273957 T +rs116389213 single 22:20000001-21000000 274082 A +rs150248016 single 22:20000001-21000000 274187 A +rs34726340 single 22:20000001-21000000 274497 A +rs701411 single 22:20000001-21000000 274610 G +rs115713971 single 22:20000001-21000000 274788 T +rs184316207 single 22:20000001-21000000 274847 T +rs369960903 single 22:20000001-21000000 274868 A +rs369960903 single 22:20000001-21000000 274868 G +rs854959 single 22:20000001-21000000 275266 A +rs12152120 single 22:20000001-21000000 275367 T +rs9606311 single 22:20000001-21000000 275409 C +rs1640384 single 22:20000001-21000000 275455 A +rs55851392 single 22:20000001-21000000 275635 A +rs142456498 single 22:20000001-21000000 275661 G +rs9606313 single 22:20000001-21000000 275684 A +rs35275474 deletion 22:20000001-21000000 275728 1 +rs140558888 single 22:20000001-21000000 275752 C +rs855062 single 22:20000001-21000000 276094 A +rs854960 single 22:20000001-21000000 276383 G +rs147392519 single 22:20000001-21000000 276527 T +rs117897640 single 22:20000001-21000000 276600 G +rs145440008 single 22:20000001-21000000 276882 T +rs9606315 single 22:20000001-21000000 276947 A +rs9606315 single 22:20000001-21000000 276947 T +rs112744194 single 22:20000001-21000000 277053 T +rs855063 single 22:20000001-21000000 277112 C +rs145876893 single 22:20000001-21000000 277324 T +rs146603621 single 22:20000001-21000000 277482 A +rs854961 single 22:20000001-21000000 278003 G +rs118187598 single 22:20000001-21000000 278035 A +rs138647324 single 22:20000001-21000000 278071 G +rs79026442 single 22:20000001-21000000 278378 G +rs5748573 single 22:20000001-21000000 278470 G +rs855064 single 22:20000001-21000000 278528 A +rs5993951 single 22:20000001-21000000 278734 T +rs79510620 single 22:20000001-21000000 278915 A +rs9617872 single 22:20000001-21000000 278952 T +rs9618775 single 22:20000001-21000000 279127 C +rs12628408 single 22:20000001-21000000 279158 A +rs12168751 single 22:20000001-21000000 279532 A +rs12169202 single 22:20000001-21000000 279717 T +rs116156996 single 22:20000001-21000000 279814 C +rs113821366 single 22:20000001-21000000 280438 A +rs75341343 single 22:20000001-21000000 280633 T +rs5993952 single 22:20000001-21000000 280781 G +rs532736304 single 22:20000001-21000000 281054 C +rs57059797 single 22:20000001-21000000 281260 T +rs112314714 single 22:20000001-21000000 281340 T +rs9618776 single 22:20000001-21000000 281852 C +rs7287659 single 22:20000001-21000000 282242 C +rs5993953 single 22:20000001-21000000 282494 T +rs28483521 single 22:20000001-21000000 282728 C +rs144106158 deletion 22:20000001-21000000 282774 2 +rs5993954 single 22:20000001-21000000 282885 T +rs75220018 single 22:20000001-21000000 282926 C +rs5993955 single 22:20000001-21000000 283227 T +rs141153949 insertion 22:20000001-21000000 283373 T +rs11913556 single 22:20000001-21000000 283417 A +rs17757179 single 22:20000001-21000000 283559 C +rs570173676 deletion 22:20000001-21000000 283700 1 +rs12628656 single 22:20000001-21000000 283731 A +rs55936357 single 22:20000001-21000000 283995 A +rs111740045 single 22:20000001-21000000 284026 A +rs9617874 single 22:20000001-21000000 284604 A +rs114718020 single 22:20000001-21000000 286069 T +rs741413 single 22:20000001-21000000 286098 G +rs141109831 single 22:20000001-21000000 286423 T +rs202027003 deletion 22:20000001-21000000 286543 1 +rs712977 single 22:20000001-21000000 287089 G +rs184027097 single 22:20000001-21000000 287282 G +rs566802242 single 22:20000001-21000000 287873 G +rs375965193 single 22:20000001-21000000 288096 A +rs187389825 single 22:20000001-21000000 288767 A +rs117680284 single 22:20000001-21000000 289158 T +rs111245247 single 22:20000001-21000000 289197 T +rs73155116 single 22:20000001-21000000 289237 T +rs545001354 insertion 22:20000001-21000000 289541 T +rs138285111 single 22:20000001-21000000 289781 T +rs71683800 deletion 22:20000001-21000000 290385 5 +rs56185412 single 22:20000001-21000000 290948 A +rs56306832 single 22:20000001-21000000 291029 C +rs3970483 single 22:20000001-21000000 291258 T +rs548744927 single 22:20000001-21000000 291352 G +rs548744927 single 22:20000001-21000000 291352 T +rs9618779 single 22:20000001-21000000 292392 A +rs113465869 single 22:20000001-21000000 293303 C +rs2904577 single 22:20000001-21000000 293624 A +rs2241306 single 22:20000001-21000000 294618 A +rs7286515 single 22:20000001-21000000 294866 G +rs199755922 single 22:20000001-21000000 295378 T +rs139500366 single 22:20000001-21000000 295413 C +rs144421249 single 22:20000001-21000000 295453 C +rs148492600 single 22:20000001-21000000 295525 A +rs5993962 single 22:20000001-21000000 295577 G +rs738076 single 22:20000001-21000000 296320 A +rs4995261 single 22:20000001-21000000 296539 C +rs12166558 single 22:20000001-21000000 297309 T +rs9605096 single 22:20000001-21000000 298057 T +rs373572922 single 22:20000001-21000000 298190 A +rs373572922 single 22:20000001-21000000 298190 C +rs112074972 single 22:20000001-21000000 298514 G +rs112086538 single 22:20000001-21000000 299117 G +rs113848355 single 22:20000001-21000000 299414 A +rs111505542 single 22:20000001-21000000 300664 A +rs111505542 single 22:20000001-21000000 300664 T +rs145639142 single 22:20000001-21000000 300737 C +rs141053532 single 22:20000001-21000000 301345 G +rs3890996 single 22:20000001-21000000 301799 G +rs1056804 single 22:20000001-21000000 302275 C +rs1056804 single 22:20000001-21000000 302275 T +rs183700583 single 22:20000001-21000000 302403 T +rs113468394 single 22:20000001-21000000 303663 A +rs5993964 single 22:20000001-21000000 303853 A +rs111772448 single 22:20000001-21000000 304105 A +rs117526563 single 22:20000001-21000000 304706 T +rs397844026 single 22:20000001-21000000 304819 A +rs12627754 single 22:20000001-21000000 305356 G +rs36033784 deletion 22:20000001-21000000 305986 2 +rs397788332 single 22:20000001-21000000 306277 G +rs2280116 single 22:20000001-21000000 306715 T +rs2280117 single 22:20000001-21000000 306992 T +rs7235 single 22:20000001-21000000 307255 A +rs142800099 insertion 22:20000001-21000000 307346 C +rs190235761 single 22:20000001-21000000 307519 T +rs113667770 single 22:20000001-21000000 307602 A +rs61587716 single 22:20000001-21000000 308278 A +rs1210828 single 22:20000001-21000000 308750 A +rs1210829 single 22:20000001-21000000 308799 A +rs1210830 single 22:20000001-21000000 308928 G +rs55828031 single 22:20000001-21000000 309072 A +rs752689 single 22:20000001-21000000 309392 G +rs146050228 deletion 22:20000001-21000000 309870 4 +rs7410411 single 22:20000001-21000000 311135 T +rs901789 single 22:20000001-21000000 311424 A +rs901790 single 22:20000001-21000000 311452 T +rs370525522 single 22:20000001-21000000 312435 C +rs370378383 deletion 22:20000001-21000000 312722 1 +rs550697009 single 22:20000001-21000000 312944 C +rs56407284 single 22:20000001-21000000 313298 G +rs200183474 insertion 22:20000001-21000000 314124 G +rs539415100 single 22:20000001-21000000 314156 C +rs35488903 single 22:20000001-21000000 315928 T +rs535072475 deletion 22:20000001-21000000 316072 1 +rs557642247 insertion 22:20000001-21000000 316336 T +rs9618787 single 22:20000001-21000000 317093 A +rs201255184 insertion 22:20000001-21000000 317798 TATT +rs28595448 single 22:20000001-21000000 318161 A +rs558372232 deletion 22:20000001-21000000 320012 4 +rs375452397 single 22:20000001-21000000 320228 A +rs138497664 single 22:20000001-21000000 320730 G +rs9605099 single 22:20000001-21000000 320762 G +rs367872441 single 22:20000001-21000000 320937 G +rs200930121 single 22:20000001-21000000 321015 C +rs200325927 single 22:20000001-21000000 321214 G +rs5742509 single 22:20000001-21000000 321400 C +rs5742536 single 22:20000001-21000000 321578 A +rs8139497 single 22:20000001-21000000 321888 G +rs369341018 single 22:20000001-21000000 322873 C +rs368454934 deletion 22:20000001-21000000 322911 1 +rs536650213 single 22:20000001-21000000 323146 A +rs573996925 deletion 22:20000001-21000000 323186 1 +rs6518604 single 22:20000001-21000000 323210 A +rs62217987 single 22:20000001-21000000 323741 T +rs199719896 insertion 22:20000001-21000000 323978 TATATGATAGAGATTATATACAATA +rs191287568 single 22:20000001-21000000 324162 T +rs111220727 single 22:20000001-21000000 324415 A +rs111220727 single 22:20000001-21000000 324415 T +rs62651454 single 22:20000001-21000000 324437 C +rs376032434 deletion 22:20000001-21000000 324547 2 +rs374108049 insertion 22:20000001-21000000 324681 TATATC +rs56651470 single 22:20000001-21000000 324731 A +rs143971653 single 22:20000001-21000000 324890 C +rs143502836 deletion 22:20000001-21000000 324916 5 +rs372011139 deletion 22:20000001-21000000 324962 17 +rs7511281 single 22:20000001-21000000 324991 G +rs7511299 single 22:20000001-21000000 325094 A +rs201125528 single 22:20000001-21000000 325376 C +rs28411685 single 22:20000001-21000000 325424 A +rs9618790 single 22:20000001-21000000 325848 A +rs9618793 single 22:20000001-21000000 325905 A +rs9606328 single 22:20000001-21000000 326524 G +rs533988831 single 22:20000001-21000000 326856 C +rs577032639 single 22:20000001-21000000 326969 A +rs9606332 single 22:20000001-21000000 328086 A +rs542506597 single 22:20000001-21000000 328784 T +rs572559485 single 22:20000001-21000000 328841 G +rs9618801 single 22:20000001-21000000 329382 G +rs201353123 single 22:20000001-21000000 329425 T +rs60443210 single 22:20000001-21000000 330512 G +rs60443210 single 22:20000001-21000000 330512 T +rs9617876 single 22:20000001-21000000 330743 T +rs529255526 single 22:20000001-21000000 332452 G +rs370283224 single 22:20000001-21000000 333875 C +rs62218051 single 22:20000001-21000000 334969 G +rs62218052 single 22:20000001-21000000 335224 G +rs377551426 single 22:20000001-21000000 335814 T +rs201990883 single 22:20000001-21000000 339616 T +rs62218058 single 22:20000001-21000000 339653 G +rs571632636 single 22:20000001-21000000 340608 A +rs200279950 single 22:20000001-21000000 341137 A +rs553506061 single 22:20000001-21000000 341429 A +rs62218577 single 22:20000001-21000000 341960 T +rs12167504 single 22:20000001-21000000 342117 C +rs12168181 single 22:20000001-21000000 342287 C +rs371394196 single 22:20000001-21000000 342335 C +rs543306940 single 22:20000001-21000000 342363 A +rs373507807 single 22:20000001-21000000 342573 T +rs199634801 single 22:20000001-21000000 343214 T +rs542550911 single 22:20000001-21000000 345875 A +rs532764825 single 22:20000001-21000000 349567 T +rs201169033 single 22:20000001-21000000 350074 T +rs575276568 single 22:20000001-21000000 351051 A +rs560936846 single 22:20000001-21000000 351328 T +rs200564038 single 22:20000001-21000000 351703 C +rs199730484 single 22:20000001-21000000 351791 G +rs113612733 single 22:20000001-21000000 351818 T +rs535538762 single 22:20000001-21000000 351941 G +rs377011547 single 22:20000001-21000000 353257 A +rs77014131 single 22:20000001-21000000 353415 A +rs77014131 single 22:20000001-21000000 353415 C +rs77014131 single 22:20000001-21000000 353415 T +rs554377674 single 22:20000001-21000000 353474 A +rs572346121 single 22:20000001-21000000 353795 T +rs140562723 single 22:20000001-21000000 353878 G +rs555841649 insertion 22:20000001-21000000 357933 CACTTT +rs200470960 deletion 22:20000001-21000000 358724 1 +rs3962691 single 22:20000001-21000000 360855 A +rs143901841 single 22:20000001-21000000 360880 A +rs556586210 single 22:20000001-21000000 360927 C +rs576544144 single 22:20000001-21000000 360973 T +rs112091896 single 22:20000001-21000000 361253 T +rs184623332 single 22:20000001-21000000 361276 A +rs116539977 single 22:20000001-21000000 361374 A +rs542543351 single 22:20000001-21000000 361454 G +rs140439240 single 22:20000001-21000000 361620 C +rs140439240 single 22:20000001-21000000 361620 G +rs527489294 single 22:20000001-21000000 362071 G +rs569673765 single 22:20000001-21000000 362877 G +rs572271810 single 22:20000001-21000000 363672 A +rs578023590 single 22:20000001-21000000 363875 T +rs201054810 single 22:20000001-21000000 366366 C +rs199549402 single 22:20000001-21000000 366460 A +rs527456804 single 22:20000001-21000000 366489 A +rs201511466 single 22:20000001-21000000 367250 G +rs5997420 single 22:20000001-21000000 367780 C +rs62218637 single 22:20000001-21000000 368019 A +rs202041794 single 22:20000001-21000000 368168 A +rs372514025 single 22:20000001-21000000 368263 T +rs75792497 single 22:20000001-21000000 368386 G +rs373752216 single 22:20000001-21000000 368441 G +rs111275698 single 22:20000001-21000000 369106 A +rs552051382 single 22:20000001-21000000 369981 A +rs537663619 single 22:20000001-21000000 370619 C +rs2542835 single 22:20000001-21000000 371296 G +rs116228135 single 22:20000001-21000000 374714 T +rs2845468 single 22:20000001-21000000 375541 C +rs375818636 single 22:20000001-21000000 375603 C +rs2845469 single 22:20000001-21000000 375665 A +rs144356941 single 22:20000001-21000000 375743 G +rs2542838 single 22:20000001-21000000 376407 G +rs2542839 single 22:20000001-21000000 376435 G +rs564004426 insertion 22:20000001-21000000 376498 A +rs531229763 single 22:20000001-21000000 376706 A +rs383405 single 22:20000001-21000000 377591 A +rs422893 single 22:20000001-21000000 377760 T +rs2909302 single 22:20000001-21000000 378592 G +rs372269496 single 22:20000001-21000000 378807 C +rs376605814 single 22:20000001-21000000 378834 C +rs547549857 insertion 22:20000001-21000000 378890 CTA +rs55698413 single 22:20000001-21000000 378964 C +rs56006201 single 22:20000001-21000000 379065 T +rs199961704 insertion 22:20000001-21000000 380315 T +rs201171045 insertion 22:20000001-21000000 380615 AT +rs200663001 deletion 22:20000001-21000000 381347 1 +rs192854033 single 22:20000001-21000000 381639 T +rs577338017 single 22:20000001-21000000 382385 C +rs567789504 insertion 22:20000001-21000000 382665 A +rs554712972 single 22:20000001-21000000 383711 A +rs546518638 single 22:20000001-21000000 383800 T +rs576233803 single 22:20000001-21000000 383862 A +rs572081719 single 22:20000001-21000000 384063 G +rs2629347 single 22:20000001-21000000 384360 C +rs556166906 deletion 22:20000001-21000000 384521 2 +rs371888151 single 22:20000001-21000000 385201 G +rs189445532 single 22:20000001-21000000 385440 T +rs146242498 deletion 22:20000001-21000000 385739 4 +rs200418297 single 22:20000001-21000000 385844 T +rs2261264 single 22:20000001-21000000 386499 C +rs569353582 single 22:20000001-21000000 386699 C +rs114530820 single 22:20000001-21000000 386906 A +rs202117096 single 22:20000001-21000000 387159 A +rs202117096 single 22:20000001-21000000 387159 T +rs574087712 single 22:20000001-21000000 387275 G +rs533039262 single 22:20000001-21000000 388261 A +rs9606381 single 22:20000001-21000000 388690 C +rs201856114 deletion 22:20000001-21000000 389997 1 +rs9618819 single 22:20000001-21000000 390062 C +rs1892849 single 22:20000001-21000000 390125 T +rs534652005 single 22:20000001-21000000 390291 A +rs557930232 single 22:20000001-21000000 390327 C +rs180958865 single 22:20000001-21000000 390416 A +rs1892850 single 22:20000001-21000000 390443 G +rs528776917 single 22:20000001-21000000 390489 G +rs2629355 single 22:20000001-21000000 390720 G +rs536778745 single 22:20000001-21000000 390983 T +rs534872361 single 22:20000001-21000000 391760 A +rs2629356 single 22:20000001-21000000 391787 A +rs2629357 single 22:20000001-21000000 391936 C +rs543992948 insertion 22:20000001-21000000 393004 A +rs375588630 single 22:20000001-21000000 393203 C +rs375966002 single 22:20000001-21000000 393296 A +rs369000751 single 22:20000001-21000000 393474 A +rs62218654 single 22:20000001-21000000 393584 C +rs575999723 single 22:20000001-21000000 393786 T +rs200092583 single 22:20000001-21000000 394493 A +rs457751 single 22:20000001-21000000 394525 T +rs2508168 single 22:20000001-21000000 394629 A +rs185513629 single 22:20000001-21000000 394784 C +rs561004990 single 22:20000001-21000000 394993 G +rs147643879 single 22:20000001-21000000 395127 C +rs554639305 single 22:20000001-21000000 396583 T +rs66752705 single 22:20000001-21000000 396613 A +rs560814968 deletion 22:20000001-21000000 397513 1 +rs562662261 single 22:20000001-21000000 397926 A +rs576159895 single 22:20000001-21000000 398210 G +rs2629364 single 22:20000001-21000000 398237 G +rs376186645 single 22:20000001-21000000 399410 G +rs9605122 single 22:20000001-21000000 399867 G +rs9606389 single 22:20000001-21000000 399958 C +rs188751969 single 22:20000001-21000000 400015 A +rs62219187 single 22:20000001-21000000 400163 A +rs9605123 single 22:20000001-21000000 400370 A +rs567926851 single 22:20000001-21000000 400909 C +rs143231396 single 22:20000001-21000000 400953 A +rs28473258 single 22:20000001-21000000 401065 C +rs2629366 single 22:20000001-21000000 401089 T +rs9606391 single 22:20000001-21000000 401418 T +rs3016141 single 22:20000001-21000000 401718 T +rs9617890 single 22:20000001-21000000 402304 A +rs470943 single 22:20000001-21000000 402340 G +rs9617891 single 22:20000001-21000000 402386 A +rs73382204 single 22:20000001-21000000 402649 G +rs558135405 single 22:20000001-21000000 402933 A +rs369085249 single 22:20000001-21000000 403012 T +rs2101297 single 22:20000001-21000000 406215 C +rs532784199 single 22:20000001-21000000 406576 A +rs2019782 single 22:20000001-21000000 406629 G +rs529596108 single 22:20000001-21000000 406793 G +rs2020423 single 22:20000001-21000000 407332 G +rs571639553 single 22:20000001-21000000 409610 G +rs182525195 single 22:20000001-21000000 412485 C +rs113561534 single 22:20000001-21000000 412902 G +rs62219190 single 22:20000001-21000000 412981 G +rs4820055 single 22:20000001-21000000 413859 G +rs552031623 single 22:20000001-21000000 414040 T +rs187945649 single 22:20000001-21000000 414558 T +rs149889172 single 22:20000001-21000000 414823 A +rs559773908 single 22:20000001-21000000 415426 A +rs2629370 single 22:20000001-21000000 418875 G +rs187688475 single 22:20000001-21000000 419418 T +rs9618826 single 22:20000001-21000000 421155 C +rs5998191 single 22:20000001-21000000 421529 T +rs201827947 single 22:20000001-21000000 421612 T +rs531144600 single 22:20000001-21000000 421896 C +rs140987377 single 22:20000001-21000000 423567 G +rs536392073 single 22:20000001-21000000 426623 G +rs539306598 single 22:20000001-21000000 430562 C +rs559314693 single 22:20000001-21000000 430624 A +rs9618830 single 22:20000001-21000000 431155 T +rs138803844 single 22:20000001-21000000 431657 C +rs141920510 single 22:20000001-21000000 432172 C +rs564821190 single 22:20000001-21000000 432450 G +rs189544432 single 22:20000001-21000000 432732 T +rs201838577 single 22:20000001-21000000 433012 A +rs2629371 single 22:20000001-21000000 433149 T +rs536612136 deletion 22:20000001-21000000 434061 1 +rs201046218 single 22:20000001-21000000 436776 T +rs181600012 single 22:20000001-21000000 437003 A +rs529922417 single 22:20000001-21000000 438732 C +rs538781968 single 22:20000001-21000000 439548 T +rs186367178 single 22:20000001-21000000 440172 A +rs561472877 deletion 22:20000001-21000000 442231 1 +rs556097218 single 22:20000001-21000000 445213 T +rs468131 single 22:20000001-21000000 447832 A +rs9617893 single 22:20000001-21000000 447985 C +rs9618833 single 22:20000001-21000000 448061 A +rs9618834 single 22:20000001-21000000 448123 G +rs7410700 single 22:20000001-21000000 448457 A +rs183002658 single 22:20000001-21000000 448806 G +rs139180081 single 22:20000001-21000000 449099 G +rs4051030 single 22:20000001-21000000 449383 G +rs532538945 deletion 22:20000001-21000000 450125 3 +rs112040170 single 22:20000001-21000000 450216 G +rs188048949 single 22:20000001-21000000 454581 T +rs374395444 single 22:20000001-21000000 456764 A +rs9617896 single 22:20000001-21000000 457169 T +rs199673858 single 22:20000001-21000000 457382 T +rs201532727 single 22:20000001-21000000 458028 C +rs374606390 insertion 22:20000001-21000000 458100 CACCTG +rs200600994 single 22:20000001-21000000 458332 G +rs12169145 single 22:20000001-21000000 462489 T +rs375703269 single 22:20000001-21000000 462548 T +rs142672399 single 22:20000001-21000000 463315 C +rs77517009 single 22:20000001-21000000 463374 T +rs201871245 single 22:20000001-21000000 464664 A +rs2629307 single 22:20000001-21000000 464947 C +rs2629308 single 22:20000001-21000000 465129 C +rs2553081 single 22:20000001-21000000 465274 G +rs2930745 single 22:20000001-21000000 465808 C +rs201056222 single 22:20000001-21000000 466460 T +rs76133228 single 22:20000001-21000000 466861 A +rs561093882 single 22:20000001-21000000 466889 C +rs187704075 single 22:20000001-21000000 466938 T +rs536711359 single 22:20000001-21000000 466992 T +rs199636404 deletion 22:20000001-21000000 467039 3 +rs536238319 single 22:20000001-21000000 467323 T +rs55764652 single 22:20000001-21000000 467392 A +rs201768123 single 22:20000001-21000000 467530 A +rs560115061 single 22:20000001-21000000 467779 C +rs375812371 single 22:20000001-21000000 468501 C +rs373903545 single 22:20000001-21000000 468976 T +rs529863292 single 22:20000001-21000000 469496 T +rs2629318 single 22:20000001-21000000 471235 C +rs2845431 single 22:20000001-21000000 471503 G +rs2629319 single 22:20000001-21000000 471783 C +rs62219206 single 22:20000001-21000000 471977 A +rs57602388 single 22:20000001-21000000 472040 T +rs5994322 single 22:20000001-21000000 472134 T +rs62219207 single 22:20000001-21000000 472215 C +rs2629323 single 22:20000001-21000000 472300 C +rs62219209 single 22:20000001-21000000 472630 A +rs546552263 single 22:20000001-21000000 473051 T +rs2845427 single 22:20000001-21000000 473417 G +rs62219232 single 22:20000001-21000000 474592 C +rs9606411 single 22:20000001-21000000 474991 C +rs2542873 single 22:20000001-21000000 475020 A +rs3016125 single 22:20000001-21000000 475049 C +rs62219233 single 22:20000001-21000000 475111 A +rs550030019 single 22:20000001-21000000 475718 T +rs5997671 single 22:20000001-21000000 477377 T +rs576983814 single 22:20000001-21000000 477544 T +rs200034603 single 22:20000001-21000000 477834 G +rs541420811 single 22:20000001-21000000 478132 C +rs143051943 single 22:20000001-21000000 478748 T +rs2909305 single 22:20000001-21000000 479021 C +rs112022569 single 22:20000001-21000000 479174 T +rs539220275 single 22:20000001-21000000 480562 A +rs575730762 single 22:20000001-21000000 480593 A +rs540645874 single 22:20000001-21000000 481178 G +rs543604580 single 22:20000001-21000000 481209 G +rs566201976 single 22:20000001-21000000 481341 A +rs570610441 single 22:20000001-21000000 481409 T +rs539769640 single 22:20000001-21000000 481431 C +rs578183428 single 22:20000001-21000000 482445 C +rs558825079 insertion 22:20000001-21000000 484308 GCC +rs200918691 single 22:20000001-21000000 484805 A +rs9606413 single 22:20000001-21000000 486325 A +rs369235919 single 22:20000001-21000000 486640 G +rs79270954 single 22:20000001-21000000 486835 G +rs371437107 single 22:20000001-21000000 486913 G +rs71317874 single 22:20000001-21000000 487030 T +rs138155637 single 22:20000001-21000000 487085 A +rs9618845 single 22:20000001-21000000 487366 T +rs9617903 single 22:20000001-21000000 488777 C +rs363894 single 22:20000001-21000000 488924 C +rs5753125 single 22:20000001-21000000 488961 C +rs200076771 single 22:20000001-21000000 489029 T +rs9606414 single 22:20000001-21000000 489120 T +rs9606417 single 22:20000001-21000000 489259 G +rs558886792 single 22:20000001-21000000 489342 A +rs5753121 single 22:20000001-21000000 489578 C +rs528381246 single 22:20000001-21000000 489711 T +rs936774 single 22:20000001-21000000 490446 G +rs73155195 single 22:20000001-21000000 490506 T +rs4820841 single 22:20000001-21000000 490660 C +rs553926870 single 22:20000001-21000000 491059 G +rs62219247 single 22:20000001-21000000 491455 T +rs559931919 single 22:20000001-21000000 491805 G +rs532822831 single 22:20000001-21000000 492201 T +rs370938883 single 22:20000001-21000000 493175 G +rs542330989 insertion 22:20000001-21000000 494052 A +rs188855964 single 22:20000001-21000000 499047 G +rs577428873 single 22:20000001-21000000 499295 C +rs368372863 single 22:20000001-21000000 499487 C +rs540442379 single 22:20000001-21000000 499838 T +rs576878656 single 22:20000001-21000000 499913 A +rs562068139 single 22:20000001-21000000 500041 T +rs568355827 single 22:20000001-21000000 502475 A +rs1659630 single 22:20000001-21000000 502770 G +rs111955416 single 22:20000001-21000000 502805 T +rs564740928 single 22:20000001-21000000 502869 T +rs5992222 single 22:20000001-21000000 503436 G +rs142043904 single 22:20000001-21000000 503487 A +rs376970331 single 22:20000001-21000000 505467 T +rs5747617 single 22:20000001-21000000 507900 C +rs368729527 single 22:20000001-21000000 508291 A +rs5746553 single 22:20000001-21000000 508424 C +rs9306237 single 22:20000001-21000000 508496 G +rs2930752 single 22:20000001-21000000 508530 T +rs62219967 single 22:20000001-21000000 509125 C +rs202184662 single 22:20000001-21000000 610426 C +rs113919133 insertion 22:20000001-21000000 612109 A +rs2260886 single 22:20000001-21000000 613309 A +rs573853982 single 22:20000001-21000000 614838 G +rs201295428 single 22:20000001-21000000 614899 T +rs547158110 single 22:20000001-21000000 617632 G +rs9618813 single 22:20000001-21000000 623121 T +rs76427616 single 22:20000001-21000000 623151 G +rs559622704 single 22:20000001-21000000 623185 G +rs369139964 single 22:20000001-21000000 624131 G +rs564451226 deletion 22:20000001-21000000 624380 1 +rs530398743 single 22:20000001-21000000 625022 T +rs567168109 single 22:20000001-21000000 625428 C +rs552355790 single 22:20000001-21000000 626105 G +rs374497719 single 22:20000001-21000000 626206 A +rs12484743 single 22:20000001-21000000 626659 G +rs75830540 deletion 22:20000001-21000000 626770 1 +rs2629382 single 22:20000001-21000000 627264 G +rs569181015 single 22:20000001-21000000 627494 A +rs372781346 single 22:20000001-21000000 627873 A +rs451661 single 22:20000001-21000000 628358 G +rs2570606 single 22:20000001-21000000 629049 C +rs9611247 single 22:20000001-21000000 629156 T +rs572567411 single 22:20000001-21000000 629224 T +rs9611301 single 22:20000001-21000000 629386 A +rs531484780 single 22:20000001-21000000 630499 A +rs568279229 single 22:20000001-21000000 630753 A +rs373865441 single 22:20000001-21000000 638849 A +rs555986999 single 22:20000001-21000000 639001 C +rs375699301 single 22:20000001-21000000 639051 T +rs144932868 single 22:20000001-21000000 639229 G +rs570343827 single 22:20000001-21000000 639270 C +rs368130601 single 22:20000001-21000000 639323 A +rs566351057 single 22:20000001-21000000 639367 A +rs544044522 single 22:20000001-21000000 639448 A +rs542999762 single 22:20000001-21000000 639527 T +rs62220045 single 22:20000001-21000000 639570 T +rs62220046 single 22:20000001-21000000 639628 T +rs552068448 single 22:20000001-21000000 639781 T +rs375158475 single 22:20000001-21000000 639873 C +rs369382441 single 22:20000001-21000000 639985 T +rs8139291 single 22:20000001-21000000 640043 T +rs371060663 single 22:20000001-21000000 640073 T +rs140752632 single 22:20000001-21000000 640153 G +rs376587890 single 22:20000001-21000000 640200 G +rs370859808 single 22:20000001-21000000 640229 A +rs62220047 single 22:20000001-21000000 640374 G +rs62220048 single 22:20000001-21000000 640410 G +rs62220049 single 22:20000001-21000000 640461 C +rs71232734 single 22:20000001-21000000 640547 C +rs12157795 single 22:20000001-21000000 640611 C +rs201246106 single 22:20000001-21000000 640634 T +rs199788739 single 22:20000001-21000000 640668 A +rs12159681 single 22:20000001-21000000 640731 G +rs568415142 single 22:20000001-21000000 640867 A +rs566777369 single 22:20000001-21000000 640900 C +rs575236172 single 22:20000001-21000000 640932 A +rs1210208 single 22:20000001-21000000 641050 G +rs1210207 single 22:20000001-21000000 641089 A +rs201337867 single 22:20000001-21000000 641781 A +rs199992440 single 22:20000001-21000000 643677 C +rs576540233 single 22:20000001-21000000 646864 C +rs541424142 single 22:20000001-21000000 647133 G +rs9624391 single 22:20000001-21000000 647782 T +rs71263644 single 22:20000001-21000000 647886 C +rs565432 single 22:20000001-21000000 650830 G +rs572552379 single 22:20000001-21000000 651354 G +rs564584408 single 22:20000001-21000000 651570 T +rs533322206 single 22:20000001-21000000 651752 A +rs556120606 single 22:20000001-21000000 653138 A +rs200546022 single 22:20000001-21000000 653708 A +rs145880464 deletion 22:20000001-21000000 655613 5 +rs12158734 single 22:20000001-21000000 655791 T +rs3931714 single 22:20000001-21000000 655852 G +rs113912182 single 22:20000001-21000000 656504 T +rs549044110 single 22:20000001-21000000 657098 A +rs375148435 single 22:20000001-21000000 657261 C +rs111383011 single 22:20000001-21000000 657335 A +rs536237400 single 22:20000001-21000000 657380 T +rs147969392 single 22:20000001-21000000 657401 C +rs201300574 single 22:20000001-21000000 657562 A +rs79480102 single 22:20000001-21000000 657610 T +rs71313954 single 22:20000001-21000000 657641 C +rs567640061 single 22:20000001-21000000 658149 A +rs531678622 insertion 22:20000001-21000000 658349 ATA +rs369534471 single 22:20000001-21000000 658374 A +rs566497608 single 22:20000001-21000000 658434 T +rs28969632 single 22:20000001-21000000 658795 T +rs549833549 deletion 22:20000001-21000000 658854 2 +rs143307432 single 22:20000001-21000000 659320 G +rs10689549 insertion 22:20000001-21000000 659350 AA +rs28482902 single 22:20000001-21000000 659405 T +rs2570607 single 22:20000001-21000000 659521 G +rs11090371 single 22:20000001-21000000 659556 A +rs12160710 single 22:20000001-21000000 659640 G +rs12160710 single 22:20000001-21000000 659640 T +rs2570609 single 22:20000001-21000000 659776 G +rs141766341 single 22:20000001-21000000 659991 T +rs71313956 single 22:20000001-21000000 660079 G +rs546242842 single 22:20000001-21000000 660487 C +rs562851011 single 22:20000001-21000000 660516 T +rs376154 single 22:20000001-21000000 660590 T +rs200333335 single 22:20000001-21000000 663143 A +rs442561 single 22:20000001-21000000 663164 A +rs540495340 single 22:20000001-21000000 663249 A +rs5993150 single 22:20000001-21000000 667847 G +rs537575869 single 22:20000001-21000000 667900 C +rs553997796 single 22:20000001-21000000 668423 C +rs577513610 single 22:20000001-21000000 668498 T +rs541487565 single 22:20000001-21000000 671528 G +rs560389629 single 22:20000001-21000000 672457 T +rs423039 single 22:20000001-21000000 673233 A +rs423039 single 22:20000001-21000000 673233 C +rs201029695 insertion 22:20000001-21000000 677258 T +rs199641621 deletion 22:20000001-21000000 679373 1 +rs531358249 single 22:20000001-21000000 690785 A +rs561438348 single 22:20000001-21000000 691057 A +rs113293990 single 22:20000001-21000000 691926 G +rs191176164 single 22:20000001-21000000 693179 A +rs62221374 single 22:20000001-21000000 699590 T +rs62221376 single 22:20000001-21000000 704318 T +rs470210 single 22:20000001-21000000 705901 C +rs3888410 single 22:20000001-21000000 706868 C +rs554887243 deletion 22:20000001-21000000 707191 2 +rs9754433 single 22:20000001-21000000 708640 T +rs5753493 single 22:20000001-21000000 708684 C +rs113229144 single 22:20000001-21000000 708751 A +rs114369088 single 22:20000001-21000000 708789 T +rs113701813 single 22:20000001-21000000 708868 A +rs538372579 deletion 22:20000001-21000000 708949 27 +rs144843298 single 22:20000001-21000000 708993 T +rs35733491 single 22:20000001-21000000 709065 C +rs72617204 single 22:20000001-21000000 709227 A +rs72617204 single 22:20000001-21000000 709227 T +rs77252703 single 22:20000001-21000000 709249 G +rs5013585 single 22:20000001-21000000 709306 G +rs146423980 single 22:20000001-21000000 709386 T +rs371497993 single 22:20000001-21000000 709411 G +rs11089437 single 22:20000001-21000000 709561 A +rs369591645 single 22:20000001-21000000 709646 C +rs11089440 single 22:20000001-21000000 709734 C +rs10212022 single 22:20000001-21000000 709839 C +rs187881685 single 22:20000001-21000000 709953 A +rs375606213 single 22:20000001-21000000 710051 T +rs138536179 single 22:20000001-21000000 710078 T +rs62218177 single 22:20000001-21000000 710218 T +rs11089443 single 22:20000001-21000000 710385 T +rs11089444 single 22:20000001-21000000 710558 G +rs558827029 single 22:20000001-21000000 710636 C +rs199806732 single 22:20000001-21000000 710820 A +rs12160675 single 22:20000001-21000000 710984 C +rs556571211 single 22:20000001-21000000 711166 G +rs568475296 single 22:20000001-21000000 711239 T +rs368174987 single 22:20000001-21000000 711434 C +rs12172593 single 22:20000001-21000000 711476 A +rs12172593 single 22:20000001-21000000 711476 C +rs35704269 single 22:20000001-21000000 711696 G +rs369305236 single 22:20000001-21000000 711737 T +rs371180846 single 22:20000001-21000000 711791 G +rs370233176 single 22:20000001-21000000 711836 C +rs62218197 single 22:20000001-21000000 711895 T +rs62218198 single 22:20000001-21000000 711956 T +rs62218200 single 22:20000001-21000000 711984 A +rs371807106 single 22:20000001-21000000 712007 T +rs71317839 single 22:20000001-21000000 712046 C +rs71317841 single 22:20000001-21000000 712068 G +rs142119189 single 22:20000001-21000000 712130 T +rs146591865 single 22:20000001-21000000 712153 C +rs377460378 single 22:20000001-21000000 712289 A +rs144875927 single 22:20000001-21000000 712401 A +rs200035577 single 22:20000001-21000000 712491 A +rs559723354 single 22:20000001-21000000 712530 A +rs371738345 single 22:20000001-21000000 712554 A +rs138633425 single 22:20000001-21000000 712608 A +rs566144792 single 22:20000001-21000000 712692 G +rs116799229 single 22:20000001-21000000 712724 T +rs62218239 single 22:20000001-21000000 712788 G +rs151337892 single 22:20000001-21000000 712951 T +rs138862071 single 22:20000001-21000000 713063 A +rs62218245 single 22:20000001-21000000 713117 G +rs200774933 single 22:20000001-21000000 713377 T +rs541497429 single 22:20000001-21000000 713760 A +rs12168608 single 22:20000001-21000000 713975 A +rs541753746 single 22:20000001-21000000 714157 C +rs62218251 single 22:20000001-21000000 714235 T +rs12168773 single 22:20000001-21000000 714328 A +rs202066321 single 22:20000001-21000000 714730 C +rs146925076 single 22:20000001-21000000 714776 A +rs201759295 single 22:20000001-21000000 714835 G +rs180935332 single 22:20000001-21000000 714865 T +rs71317857 single 22:20000001-21000000 714901 T +rs62218961 single 22:20000001-21000000 714926 G +rs199653697 single 22:20000001-21000000 714956 A +rs202170294 single 22:20000001-21000000 714983 A +rs201421607 single 22:20000001-21000000 715018 T +rs200303972 single 22:20000001-21000000 715060 T +rs187089255 single 22:20000001-21000000 715167 T +rs371049047 single 22:20000001-21000000 715205 A +rs190757663 single 22:20000001-21000000 715280 C +rs542848105 single 22:20000001-21000000 715414 T +rs150186951 single 22:20000001-21000000 715507 A +rs190505990 single 22:20000001-21000000 715672 G +rs373236512 single 22:20000001-21000000 715736 A +rs201779658 single 22:20000001-21000000 715821 G +rs199549488 single 22:20000001-21000000 715885 G +rs200674668 single 22:20000001-21000000 715939 A +rs201507643 single 22:20000001-21000000 715962 C +rs145854951 single 22:20000001-21000000 716054 G +rs62218969 single 22:20000001-21000000 716109 T +rs74830498 single 22:20000001-21000000 716153 G +rs62218970 single 22:20000001-21000000 716224 G +rs111878801 single 22:20000001-21000000 716288 G +rs112628579 single 22:20000001-21000000 716838 T +rs113311941 single 22:20000001-21000000 717197 A +rs190361552 single 22:20000001-21000000 717384 A +rs190361552 single 22:20000001-21000000 717384 T +rs2543700 single 22:20000001-21000000 717802 G +rs3827282 single 22:20000001-21000000 718115 A +rs2277833 single 22:20000001-21000000 718524 C +rs2530576 single 22:20000001-21000000 718677 C +rs28540966 single 22:20000001-21000000 718725 C +rs45444397 single 22:20000001-21000000 718765 C +rs737973 single 22:20000001-21000000 718919 T +rs547587826 deletion 22:20000001-21000000 718956 1 +rs117070904 single 22:20000001-21000000 719016 G +rs142680475 single 22:20000001-21000000 719247 G +rs147440632 single 22:20000001-21000000 719324 G +rs2075298 single 22:20000001-21000000 721136 C +rs2075297 single 22:20000001-21000000 721159 C +rs140748893 single 22:20000001-21000000 721486 G +rs148842077 single 22:20000001-21000000 721782 G +rs60080017 single 22:20000001-21000000 722009 G +rs362116 single 22:20000001-21000000 722219 G +rs12167355 single 22:20000001-21000000 722522 T +rs145532549 single 22:20000001-21000000 723277 A +rs62218975 single 22:20000001-21000000 723493 G +rs147981494 single 22:20000001-21000000 723535 T +rs61741937 single 22:20000001-21000000 723761 G +rs61741937 single 22:20000001-21000000 723761 T +rs75178771 single 22:20000001-21000000 723831 C +rs191610943 single 22:20000001-21000000 724173 A +rs191610943 single 22:20000001-21000000 724173 T +rs137981924 single 22:20000001-21000000 724385 C +rs79737013 single 22:20000001-21000000 724621 T +rs377364815 single 22:20000001-21000000 724805 G +rs201047142 single 22:20000001-21000000 724854 A +rs572637793 single 22:20000001-21000000 724962 A +rs143014385 single 22:20000001-21000000 725292 A +rs201882021 single 22:20000001-21000000 725383 G +rs543519631 single 22:20000001-21000000 725640 A +rs17757293 single 22:20000001-21000000 725719 C +rs149363840 single 22:20000001-21000000 726047 A +rs549941186 single 22:20000001-21000000 726233 T +rs200383105 single 22:20000001-21000000 726318 A +rs142395307 single 22:20000001-21000000 727025 T +rs201685089 single 22:20000001-21000000 727183 T +rs199637954 single 22:20000001-21000000 727247 A +rs559480049 insertion 22:20000001-21000000 727296 ACA +rs2542122 single 22:20000001-21000000 727331 G +rs60469696 single 22:20000001-21000000 727674 T +rs73879334 single 22:20000001-21000000 727974 T +rs138313869 single 22:20000001-21000000 728589 T +rs376641802 single 22:20000001-21000000 728903 T +rs114525765 single 22:20000001-21000000 729417 T +rs2542134 single 22:20000001-21000000 729790 C +rs2542135 single 22:20000001-21000000 729824 G +rs148868491 single 22:20000001-21000000 729884 T +rs377472356 single 22:20000001-21000000 729940 G +rs371098813 single 22:20000001-21000000 730073 A +rs111648638 single 22:20000001-21000000 730859 A +rs375357548 single 22:20000001-21000000 731022 A +rs138280542 single 22:20000001-21000000 731280 T +rs142942616 single 22:20000001-21000000 731303 A +rs61752242 single 22:20000001-21000000 731565 G +rs143879121 single 22:20000001-21000000 731667 T +rs6003874 single 22:20000001-21000000 731789 C +rs78043622 single 22:20000001-21000000 731938 G +rs362117 insertion 22:20000001-21000000 732014 A +rs34771823 deletion 22:20000001-21000000 732536 1 +rs148920262 single 22:20000001-21000000 732576 A +rs362064 single 22:20000001-21000000 732808 T +rs79609167 single 22:20000001-21000000 733170 T +rs6003971 single 22:20000001-21000000 733494 G +rs362243 single 22:20000001-21000000 733666 T +rs9609613 single 22:20000001-21000000 733903 T +rs77021806 single 22:20000001-21000000 735223 G +rs362106 deletion 22:20000001-21000000 735627 4 +rs75545215 single 22:20000001-21000000 735795 G +rs147617380 single 22:20000001-21000000 735958 A +rs6004065 single 22:20000001-21000000 735993 T +rs112357213 single 22:20000001-21000000 736262 C +rs535233152 deletion 22:20000001-21000000 736300 1 +rs376864875 insertion 22:20000001-21000000 736830 A +rs7290852 single 22:20000001-21000000 737315 T +rs61614631 single 22:20000001-21000000 737571 G +rs6004125 single 22:20000001-21000000 737796 A +rs112724111 single 22:20000001-21000000 737878 A +rs9609699 single 22:20000001-21000000 737902 A +rs113492390 single 22:20000001-21000000 738470 A +rs78418667 single 22:20000001-21000000 738602 C +rs13055191 single 22:20000001-21000000 738688 A +rs13055393 single 22:20000001-21000000 738789 T +rs7286096 single 22:20000001-21000000 738878 C +rs13056016 single 22:20000001-21000000 739058 C +rs74556925 single 22:20000001-21000000 739334 A +rs7292186 single 22:20000001-21000000 739374 A +rs147549438 insertion 22:20000001-21000000 739422 T +rs112578295 single 22:20000001-21000000 739499 C +rs7287029 single 22:20000001-21000000 739625 T +rs4822505 single 22:20000001-21000000 740036 C +rs7285976 single 22:20000001-21000000 740777 C +rs5760515 single 22:20000001-21000000 741059 A +rs7288007 single 22:20000001-21000000 741232 C +rs8137370 single 22:20000001-21000000 741286 C +rs2108744 single 22:20000001-21000000 741889 C +rs361689 single 22:20000001-21000000 742449 A +rs60935923 single 22:20000001-21000000 742491 A +rs115459716 single 22:20000001-21000000 742641 C +rs577624713 single 22:20000001-21000000 742667 T +rs56303282 single 22:20000001-21000000 743105 A +rs9609829 single 22:20000001-21000000 743175 T +rs62219003 single 22:20000001-21000000 743511 T +rs2041969 single 22:20000001-21000000 743535 C +rs113582314 single 22:20000001-21000000 743621 T +rs2041970 single 22:20000001-21000000 743717 G +rs361766 single 22:20000001-21000000 743770 T +rs362215 single 22:20000001-21000000 744110 G +rs361885 single 22:20000001-21000000 744467 G +rs78154936 single 22:20000001-21000000 744976 G +rs362125 single 22:20000001-21000000 745200 G +rs5760821 single 22:20000001-21000000 745379 A +rs5760843 single 22:20000001-21000000 745615 C +rs76618551 single 22:20000001-21000000 745963 C +rs137990895 single 22:20000001-21000000 746351 C +rs6004458 single 22:20000001-21000000 746401 C +rs8137787 single 22:20000001-21000000 746974 T +rs138614277 single 22:20000001-21000000 747346 T +rs887021 single 22:20000001-21000000 747762 G +rs61261475 single 22:20000001-21000000 747862 T +rs2266945 single 22:20000001-21000000 748052 A +rs887022 single 22:20000001-21000000 748252 C +rs35012563 single 22:20000001-21000000 749041 G +rs12233360 single 22:20000001-21000000 749334 C +rs113662065 single 22:20000001-21000000 750171 A +rs361927 single 22:20000001-21000000 750202 G +rs113020357 single 22:20000001-21000000 750283 A +rs362199 single 22:20000001-21000000 750428 C +rs362080 single 22:20000001-21000000 750457 T +rs12627942 single 22:20000001-21000000 750593 C +rs361877 single 22:20000001-21000000 751135 G +rs6004729 single 22:20000001-21000000 751166 A +rs361591 single 22:20000001-21000000 751254 T +rs75106793 single 22:20000001-21000000 751279 T +rs362075 single 22:20000001-21000000 751338 C +rs361657 insertion 22:20000001-21000000 751361 TTTCTT +rs5752197 single 22:20000001-21000000 751665 A +rs361749 single 22:20000001-21000000 752118 G +rs8135306 single 22:20000001-21000000 752353 T +rs5761169 single 22:20000001-21000000 752475 G +rs362244 single 22:20000001-21000000 752646 G +rs362103 single 22:20000001-21000000 752686 G +rs362062 single 22:20000001-21000000 753040 A +rs362030 single 22:20000001-21000000 753064 T +rs362164 single 22:20000001-21000000 753100 C +rs57342969 single 22:20000001-21000000 753134 C +rs362165 deletion 22:20000001-21000000 753200 15 +rs361613 single 22:20000001-21000000 753270 T +rs57137868 single 22:20000001-21000000 753304 G +rs361640 single 22:20000001-21000000 753614 A +rs362222 deletion 22:20000001-21000000 753670 1 +rs362181 single 22:20000001-21000000 753770 T +rs7289261 single 22:20000001-21000000 753794 G +rs362136 insertion 22:20000001-21000000 753861 T +rs361860 single 22:20000001-21000000 754038 A +rs5761326 single 22:20000001-21000000 754238 G +rs12330004 single 22:20000001-21000000 754287 C +rs2329377 single 22:20000001-21000000 754505 G +rs4485654 single 22:20000001-21000000 754549 A +rs73879341 single 22:20000001-21000000 754596 G +rs4546089 single 22:20000001-21000000 754654 T +rs4546090 single 22:20000001-21000000 754688 T +rs73879342 single 22:20000001-21000000 754843 C +rs1990249 single 22:20000001-21000000 755097 G +rs55651125 single 22:20000001-21000000 755131 T +rs4581986 single 22:20000001-21000000 755225 G +rs7290661 single 22:20000001-21000000 755282 G +rs6004920 single 22:20000001-21000000 755339 G +rs117562299 single 22:20000001-21000000 755512 A +rs117562299 single 22:20000001-21000000 755512 T +rs12484067 single 22:20000001-21000000 755753 T +rs76196980 single 22:20000001-21000000 755864 G +rs73382250 single 22:20000001-21000000 756298 T +rs73879346 single 22:20000001-21000000 756406 A +rs9610170 single 22:20000001-21000000 756475 A +rs5761392 single 22:20000001-21000000 756511 G +rs12628614 single 22:20000001-21000000 756727 A +rs56834439 insertion 22:20000001-21000000 756793 TT +rs5761416 single 22:20000001-21000000 756967 A +rs6004975 single 22:20000001-21000000 757254 G +rs73879348 single 22:20000001-21000000 757628 G +rs77930355 single 22:20000001-21000000 758108 T +rs2108745 single 22:20000001-21000000 758135 A +rs141707686 single 22:20000001-21000000 758730 T +rs737811 single 22:20000001-21000000 758953 T +rs73879349 single 22:20000001-21000000 759245 G +rs77462388 single 22:20000001-21000000 759404 T +rs5761555 single 22:20000001-21000000 759533 G +rs3747076 single 22:20000001-21000000 759671 A +rs2229316 single 22:20000001-21000000 760105 T +rs200156770 single 22:20000001-21000000 760514 C +rs2228236 single 22:20000001-21000000 761062 A +rs117467773 single 22:20000001-21000000 761191 T +rs4020 single 22:20000001-21000000 761383 A +rs117506051 single 22:20000001-21000000 761565 A +rs887023 single 22:20000001-21000000 761898 T +rs13433540 single 22:20000001-21000000 761936 C +rs9610309 single 22:20000001-21000000 761975 G +rs2266946 single 22:20000001-21000000 762053 A +rs3088200 single 22:20000001-21000000 762399 G +rs12628313 single 22:20000001-21000000 762422 A +rs140749953 deletion 22:20000001-21000000 762879 3 +rs11704853 single 22:20000001-21000000 762954 T +rs12628644 single 22:20000001-21000000 763031 G +rs377391797 insertion 22:20000001-21000000 763084 CATGTGTTCT +rs6005202 single 22:20000001-21000000 763120 G +rs62219007 single 22:20000001-21000000 763229 C +rs73382266 single 22:20000001-21000000 763314 G +rs6005214 single 22:20000001-21000000 763397 T +rs74626013 single 22:20000001-21000000 763427 T +rs75599766 single 22:20000001-21000000 763537 C +rs61507812 deletion 22:20000001-21000000 763807 2 +rs73156918 single 22:20000001-21000000 763999 A +rs59857822 single 22:20000001-21000000 764219 G +rs141735774 deletion 22:20000001-21000000 764456 2 +rs147542853 single 22:20000001-21000000 764537 G +rs1013633 single 22:20000001-21000000 764558 C +rs1013634 single 22:20000001-21000000 764594 G +rs6005267 single 22:20000001-21000000 764993 C +rs5761913 single 22:20000001-21000000 765020 C +rs56660586 deletion 22:20000001-21000000 765136 1 +rs112254027 single 22:20000001-21000000 765168 G +rs111314022 single 22:20000001-21000000 765200 C +rs11704282 single 22:20000001-21000000 765239 A +rs368651913 deletion 22:20000001-21000000 765362 3 +rs60349480 single 22:20000001-21000000 765417 A +rs68039353 single 22:20000001-21000000 765537 C +rs5761947 single 22:20000001-21000000 765581 C +rs5761951 single 22:20000001-21000000 765654 G +rs28558075 single 22:20000001-21000000 765813 G +rs55992499 single 22:20000001-21000000 765976 T +rs5761998 single 22:20000001-21000000 766083 C +rs5762002 single 22:20000001-21000000 766149 C +rs5762009 single 22:20000001-21000000 766193 A +rs5762012 single 22:20000001-21000000 766272 A +rs12159543 single 22:20000001-21000000 766374 T +rs12157280 single 22:20000001-21000000 766455 A +rs5762024 single 22:20000001-21000000 766729 A +rs5762031 single 22:20000001-21000000 766956 G +rs5762039 single 22:20000001-21000000 767102 T +rs73382284 single 22:20000001-21000000 767164 A +rs5997205 single 22:20000001-21000000 767212 G +rs73879356 single 22:20000001-21000000 767302 A +rs141432776 deletion 22:20000001-21000000 767569 3 +rs549852927 deletion 22:20000001-21000000 767591 1 +rs200236731 insertion 22:20000001-21000000 767618 AG +rs5762058 single 22:20000001-21000000 767716 A +rs17819170 single 22:20000001-21000000 767790 T +rs2041971 single 22:20000001-21000000 768029 A +rs139864261 single 22:20000001-21000000 768094 T +rs116015090 single 22:20000001-21000000 768265 G +rs5762084 single 22:20000001-21000000 768295 G +rs73382290 single 22:20000001-21000000 768406 A +rs55999317 single 22:20000001-21000000 768474 C +rs9610418 single 22:20000001-21000000 768517 A +rs362220 single 22:20000001-21000000 768634 C +rs75163427 single 22:20000001-21000000 768701 G +rs9610447 single 22:20000001-21000000 768890 T +rs917409 single 22:20000001-21000000 769003 A +rs12330023 single 22:20000001-21000000 769054 T +rs35359276 insertion 22:20000001-21000000 769186 T +rs147913459 single 22:20000001-21000000 769416 C +rs77424257 single 22:20000001-21000000 769728 G +rs58771127 single 22:20000001-21000000 769965 T +rs149129621 single 22:20000001-21000000 770053 G +rs9607342 single 22:20000001-21000000 770789 T +rs362023 single 22:20000001-21000000 770889 C +rs5762277 single 22:20000001-21000000 770967 C +rs11912225 single 22:20000001-21000000 771514 G +rs138656412 insertion 22:20000001-21000000 771539 TTTTG +rs1073829 single 22:20000001-21000000 771589 A +rs1073828 single 22:20000001-21000000 771618 A +rs74647853 single 22:20000001-21000000 771979 C +rs112094838 single 22:20000001-21000000 772002 T +rs35317976 insertion 22:20000001-21000000 772047 C +rs9610540 single 22:20000001-21000000 772098 A +rs9610543 single 22:20000001-21000000 772152 G +rs116551437 single 22:20000001-21000000 772364 C +rs148687416 single 22:20000001-21000000 772419 G +rs738089 single 22:20000001-21000000 772597 A +rs76881461 single 22:20000001-21000000 772772 A +rs6005636 single 22:20000001-21000000 772909 C +rs5762370 single 22:20000001-21000000 772986 A +rs5752645 single 22:20000001-21000000 773166 G +rs367565697 deletion 22:20000001-21000000 773209 1 +rs58803203 single 22:20000001-21000000 773479 C +rs738088 single 22:20000001-21000000 773520 C +rs8139756 single 22:20000001-21000000 773710 T +rs67939127 deletion 22:20000001-21000000 773844 27 +rs5752660 single 22:20000001-21000000 774065 C +rs6005680 single 22:20000001-21000000 774453 G +rs362031 single 22:20000001-21000000 774478 G +rs5752676 single 22:20000001-21000000 774613 A +rs9808840 single 22:20000001-21000000 774753 G +rs5752681 single 22:20000001-21000000 774807 A +rs361638 insertion 22:20000001-21000000 775034 GTA +rs1638038 single 22:20000001-21000000 775081 C +rs1771145 single 22:20000001-21000000 775166 T +rs1638039 single 22:20000001-21000000 775199 C +rs1771146 single 22:20000001-21000000 775246 T +rs1771147 single 22:20000001-21000000 775273 T +rs73384210 single 22:20000001-21000000 775404 T +rs738087 single 22:20000001-21000000 775549 G +rs200601342 deletion 22:20000001-21000000 775594 3 +rs149007797 single 22:20000001-21000000 775635 A +rs5762477 single 22:20000001-21000000 775781 C +rs11705342 single 22:20000001-21000000 775851 T +rs1638041 single 22:20000001-21000000 776198 A +rs1638042 single 22:20000001-21000000 776265 G +rs1638043 single 22:20000001-21000000 776405 G +rs59618208 single 22:20000001-21000000 776796 A +rs111787024 single 22:20000001-21000000 776818 C +rs6005740 single 22:20000001-21000000 776842 A +rs10606665 deletion 22:20000001-21000000 776973 3 +rs58298509 single 22:20000001-21000000 777288 A +rs73879364 single 22:20000001-21000000 777312 T +rs61318380 single 22:20000001-21000000 777468 A +rs117815810 single 22:20000001-21000000 777532 T +rs738085 single 22:20000001-21000000 777671 G +rs5762554 single 22:20000001-21000000 777940 T +rs738084 single 22:20000001-21000000 778065 G +rs5762563 single 22:20000001-21000000 778150 A +rs10212080 single 22:20000001-21000000 778446 A +rs1076486 single 22:20000001-21000000 778769 T +rs968456 single 22:20000001-21000000 779510 T +rs1319199 single 22:20000001-21000000 779562 T +rs7286419 single 22:20000001-21000000 779603 G +rs874101 single 22:20000001-21000000 779767 C +rs874100 single 22:20000001-21000000 779821 C +rs759612 single 22:20000001-21000000 779945 G +rs587606297 insertion 22:20000001-21000000 779973 G +rs5844420 insertion 22:20000001-21000000 780024 C +rs185252842 single 22:20000001-21000000 780078 T +rs9680797 single 22:20000001-21000000 780295 A +rs111631797 single 22:20000001-21000000 781005 T +rs71746154 deletion 22:20000001-21000000 781225 2 +rs12152201 single 22:20000001-21000000 781370 T +rs77025632 single 22:20000001-21000000 781444 G +rs57456207 insertion 22:20000001-21000000 781492 TG +rs57590287 single 22:20000001-21000000 781669 C +rs2241231 single 22:20000001-21000000 782101 C +rs116142926 single 22:20000001-21000000 782138 C +rs148075695 deletion 22:20000001-21000000 782497 4 +rs373753666 single 22:20000001-21000000 782524 C +rs144200018 single 22:20000001-21000000 782570 T +rs11267636 deletion 22:20000001-21000000 782649 17 +rs5997411 single 22:20000001-21000000 783484 A +rs8137004 single 22:20000001-21000000 783720 T +rs2241230 single 22:20000001-21000000 784049 A +rs35216297 single 22:20000001-21000000 784101 G +rs35216297 single 22:20000001-21000000 784101 T +rs882745 single 22:20000001-21000000 784216 T +rs7289390 single 22:20000001-21000000 784549 G +rs73156937 single 22:20000001-21000000 784629 A +rs879193 single 22:20000001-21000000 784907 A +rs879193 single 22:20000001-21000000 784907 C +rs879193 single 22:20000001-21000000 784907 G +rs361566 single 22:20000001-21000000 785638 A +rs5763025 single 22:20000001-21000000 786487 C +rs4823020 single 22:20000001-21000000 786599 G +rs4823021 single 22:20000001-21000000 786809 A +rs57291235 single 22:20000001-21000000 787331 T +rs75366319 single 22:20000001-21000000 787476 T +rs76753324 single 22:20000001-21000000 787773 G +rs76753324 single 22:20000001-21000000 787773 T +rs1155419 single 22:20000001-21000000 787849 C +rs9622744 single 22:20000001-21000000 788129 G +rs5763152 single 22:20000001-21000000 788230 A +rs12483784 single 22:20000001-21000000 788435 G +rs1123521 single 22:20000001-21000000 788589 A +rs115253544 single 22:20000001-21000000 788869 T +rs2108746 single 22:20000001-21000000 788968 G +rs9610925 single 22:20000001-21000000 789045 A +rs1005640 single 22:20000001-21000000 789073 C +rs5763244 single 22:20000001-21000000 789189 C +rs5763252 single 22:20000001-21000000 789293 G +rs139207108 deletion 22:20000001-21000000 789459 1 +rs114366243 single 22:20000001-21000000 789528 T +rs1477177 single 22:20000001-21000000 789573 C +rs1477178 single 22:20000001-21000000 789687 A +rs9610946 single 22:20000001-21000000 789914 A +rs9622791 single 22:20000001-21000000 789959 A +rs5752939 single 22:20000001-21000000 790086 C +rs9610955 single 22:20000001-21000000 790722 G +rs12628193 single 22:20000001-21000000 791437 A +rs9619753 single 22:20000001-21000000 791820 A +rs113021966 single 22:20000001-21000000 792629 T +rs62219027 single 22:20000001-21000000 793066 T +rs1035239 single 22:20000001-21000000 793913 C +rs62219028 single 22:20000001-21000000 794074 C +rs75336684 single 22:20000001-21000000 794118 G +rs5763655 single 22:20000001-21000000 794483 G +rs62219029 single 22:20000001-21000000 794725 C +rs56163007 insertion 22:20000001-21000000 794804 AC +rs59848556 single 22:20000001-21000000 794923 T +rs62219031 single 22:20000001-21000000 795125 G +rs112153408 deletion 22:20000001-21000000 795295 2 +rs60574840 single 22:20000001-21000000 795419 G +rs62219032 single 22:20000001-21000000 795453 C +rs1153427 single 22:20000001-21000000 795756 T +rs2287256 single 22:20000001-21000000 795925 T +rs8353 single 22:20000001-21000000 796116 T +rs9997 single 22:20000001-21000000 796174 C +rs8142474 single 22:20000001-21000000 796866 C +rs5763911 single 22:20000001-21000000 797288 C +rs741436 single 22:20000001-21000000 797409 A +rs77467662 single 22:20000001-21000000 797459 G +rs553553094 deletion 22:20000001-21000000 797640 1 +rs741435 single 22:20000001-21000000 797789 A +rs1153428 single 22:20000001-21000000 798353 A +rs73156947 single 22:20000001-21000000 798779 T +rs150439544 insertion 22:20000001-21000000 799066 TTTG +rs150439544 insertion 22:20000001-21000000 799066 TTTGTTTGTTTG +rs139519810 single 22:20000001-21000000 799152 A +rs114552752 single 22:20000001-21000000 799455 T +rs5753167 single 22:20000001-21000000 799639 A +rs62219033 single 22:20000001-21000000 799826 A +rs114051492 single 22:20000001-21000000 799885 C +rs5997675 single 22:20000001-21000000 799971 G +rs144812370 deletion 22:20000001-21000000 800041 3 +rs62219034 single 22:20000001-21000000 800255 T +rs78186591 single 22:20000001-21000000 800354 G +rs34110805 single 22:20000001-21000000 800780 G +rs8748 single 22:20000001-21000000 800834 G +rs1058990 single 22:20000001-21000000 800982 A +rs75249336 single 22:20000001-21000000 801053 T +rs361727 single 22:20000001-21000000 801220 C +rs77101095 single 22:20000001-21000000 801572 A +rs79820558 single 22:20000001-21000000 801874 A +rs73384246 single 22:20000001-21000000 802177 A +rs62219035 single 22:20000001-21000000 802698 G +rs146343607 deletion 22:20000001-21000000 803327 10 +rs12159159 single 22:20000001-21000000 803582 A +rs12160833 single 22:20000001-21000000 803610 C +rs112983520 single 22:20000001-21000000 803843 T +rs12168610 single 22:20000001-21000000 804245 A +rs12167329 single 22:20000001-21000000 804294 T +rs3810601 single 22:20000001-21000000 804349 T +rs16988440 single 22:20000001-21000000 804496 G +rs2329356 single 22:20000001-21000000 805368 G +rs2003591 single 22:20000001-21000000 805685 G +rs76649694 single 22:20000001-21000000 806396 A +rs62219036 single 22:20000001-21000000 806957 G +rs5997972 single 22:20000001-21000000 808712 T +rs12157521 single 22:20000001-21000000 809458 T +rs5753651 single 22:20000001-21000000 809619 T +rs5753658 single 22:20000001-21000000 809717 A +rs361988 single 22:20000001-21000000 810053 T +rs75125763 single 22:20000001-21000000 810751 T +rs73879379 single 22:20000001-21000000 811104 A +rs5749316 single 22:20000001-21000000 811230 G +rs111314590 insertion 22:20000001-21000000 811324 CG +rs362071 single 22:20000001-21000000 811644 C +rs361573 single 22:20000001-21000000 811673 T +rs34030327 deletion 22:20000001-21000000 811853 1 +rs362087 single 22:20000001-21000000 811929 A +rs73384254 single 22:20000001-21000000 812479 G +rs5753787 single 22:20000001-21000000 812727 A +rs28478721 single 22:20000001-21000000 812941 C +rs5753802 single 22:20000001-21000000 813246 C +rs79873328 single 22:20000001-21000000 813397 G +rs148076715 deletion 22:20000001-21000000 814310 3 +rs139831649 single 22:20000001-21000000 814666 A +rs4820064 single 22:20000001-21000000 814759 A +rs192682105 single 22:20000001-21000000 814936 T +rs73384257 single 22:20000001-21000000 815265 G +rs73384259 single 22:20000001-21000000 815314 T +rs8140159 single 22:20000001-21000000 816110 T +rs5753874 single 22:20000001-21000000 816192 C +rs62217858 single 22:20000001-21000000 816271 A +rs4626022 single 22:20000001-21000000 816310 G +rs113178597 single 22:20000001-21000000 816421 A +rs165658 single 22:20000001-21000000 816549 T +rs7285244 single 22:20000001-21000000 816675 G +rs558617516 deletion 22:20000001-21000000 816808 1 +rs17819290 single 22:20000001-21000000 817182 G +rs165809 single 22:20000001-21000000 817807 T +rs98399 single 22:20000001-21000000 818103 A +rs165807 single 22:20000001-21000000 818266 G +rs165630 single 22:20000001-21000000 818420 C +rs75351052 deletion 22:20000001-21000000 818504 2 +rs77097917 single 22:20000001-21000000 820131 T +rs62219860 single 22:20000001-21000000 820532 T +rs73384264 single 22:20000001-21000000 820850 T +rs73384265 single 22:20000001-21000000 821025 A +rs116129811 single 22:20000001-21000000 821131 C +rs5998587 single 22:20000001-21000000 821696 G +rs165889 single 22:20000001-21000000 821873 T +rs5998600 single 22:20000001-21000000 822004 A +rs62219862 single 22:20000001-21000000 822136 A +rs165864 single 22:20000001-21000000 822365 T +rs78391699 single 22:20000001-21000000 822706 T +rs177343 single 22:20000001-21000000 822944 T +rs76783915 single 22:20000001-21000000 823241 T +rs114505951 single 22:20000001-21000000 824279 T +rs62219863 single 22:20000001-21000000 824372 A +rs9611669 single 22:20000001-21000000 824469 A +rs5994653 single 22:20000001-21000000 824815 T +rs5749549 single 22:20000001-21000000 824901 T +rs538204093 insertion 22:20000001-21000000 824967 TGGA +rs566014622 insertion 22:20000001-21000000 825006 ATGG +rs4820097 single 22:20000001-21000000 825059 C +rs57089443 single 22:20000001-21000000 825129 C +rs144278149 single 22:20000001-21000000 825153 G +rs5754388 single 22:20000001-21000000 825188 G +rs115766542 single 22:20000001-21000000 825278 G +rs73384271 single 22:20000001-21000000 825409 G +rs114700187 single 22:20000001-21000000 825871 T +rs78490140 single 22:20000001-21000000 827098 C +rs5749587 single 22:20000001-21000000 827263 C +rs62219865 single 22:20000001-21000000 827509 C +rs77539215 single 22:20000001-21000000 827620 T +rs78498710 deletion 22:20000001-21000000 828221 1 +rs181310028 single 22:20000001-21000000 828348 A +rs62219866 single 22:20000001-21000000 828537 A +rs9623544 single 22:20000001-21000000 828637 G +rs165828 single 22:20000001-21000000 828866 C +rs112756688 single 22:20000001-21000000 828925 T +rs57516660 single 22:20000001-21000000 829664 T +rs11914248 single 22:20000001-21000000 832036 C +rs5749656 single 22:20000001-21000000 832189 C +rs5754661 single 22:20000001-21000000 832335 T +rs68060846 deletion 22:20000001-21000000 832492 1 +rs200673843 single 22:20000001-21000000 832522 C +rs5749659 single 22:20000001-21000000 832579 A +rs5749659 single 22:20000001-21000000 832579 C +rs9623646 single 22:20000001-21000000 832661 C +rs112585570 single 22:20000001-21000000 832718 T +rs181474359 single 22:20000001-21000000 833048 T +rs62219868 single 22:20000001-21000000 833080 A +rs201980940 deletion 22:20000001-21000000 833552 1 +rs74335326 single 22:20000001-21000000 833696 A +rs5999159 single 22:20000001-21000000 834269 G +rs62219869 single 22:20000001-21000000 834312 C +rs4401303 single 22:20000001-21000000 834563 A +rs62219870 single 22:20000001-21000000 834709 T +rs73384283 single 22:20000001-21000000 834939 G +rs5749718 single 22:20000001-21000000 835088 T +rs7288014 single 22:20000001-21000000 835242 G +rs183361424 single 22:20000001-21000000 835267 A +rs75482140 single 22:20000001-21000000 835433 G +rs113106249 single 22:20000001-21000000 835795 A +rs147017596 single 22:20000001-21000000 835821 C +rs111410527 single 22:20000001-21000000 835883 T +rs116454307 single 22:20000001-21000000 835922 A +rs75115156 single 22:20000001-21000000 836188 G +rs76041972 single 22:20000001-21000000 836300 T +rs361967 insertion 22:20000001-21000000 837034 T +rs5749793 single 22:20000001-21000000 838054 C +rs5749798 single 22:20000001-21000000 838198 A +rs5749800 single 22:20000001-21000000 838228 C +rs5749808 single 22:20000001-21000000 838435 C +rs5749818 single 22:20000001-21000000 838592 T +rs12159968 single 22:20000001-21000000 838742 T +rs5749847 single 22:20000001-21000000 838861 G +rs576583986 deletion 22:20000001-21000000 839018 1 +rs62219872 single 22:20000001-21000000 839620 G +rs75179603 single 22:20000001-21000000 839809 T +rs4564890 single 22:20000001-21000000 839874 A +rs1970990 single 22:20000001-21000000 839911 C +rs559391443 deletion 22:20000001-21000000 839979 1 +rs112326480 single 22:20000001-21000000 841054 A +rs73384285 single 22:20000001-21000000 841268 T +rs144900889 single 22:20000001-21000000 841486 A +rs35035626 deletion 22:20000001-21000000 841671 1 +rs5755236 single 22:20000001-21000000 841840 A +rs5999507 single 22:20000001-21000000 841919 T +rs1572876 single 22:20000001-21000000 842156 G +rs1771144 single 22:20000001-21000000 842361 C +rs1572877 single 22:20000001-21000000 842383 G +rs5755286 single 22:20000001-21000000 842668 C +rs528013093 single 22:20000001-21000000 842961 G +rs9623846 single 22:20000001-21000000 843377 A +rs165613 single 22:20000001-21000000 843884 G +rs9620147 single 22:20000001-21000000 844335 C +rs12484813 single 22:20000001-21000000 844662 A +rs12169691 single 22:20000001-21000000 844943 A +rs12169691 single 22:20000001-21000000 844943 C +rs78138393 single 22:20000001-21000000 845954 A +rs112668245 single 22:20000001-21000000 846547 C +rs4821372 single 22:20000001-21000000 846640 G +rs200685174 deletion 22:20000001-21000000 846746 1 +rs5755677 single 22:20000001-21000000 847471 T +rs144135811 single 22:20000001-21000000 848166 A +rs144807249 insertion 22:20000001-21000000 848360 G +rs115394808 single 22:20000001-21000000 848451 A +rs12160574 single 22:20000001-21000000 848856 C +rs114867051 single 22:20000001-21000000 849422 A +rs115435672 single 22:20000001-21000000 849602 A +rs554510520 single 22:20000001-21000000 849744 C +rs562091946 single 22:20000001-21000000 850207 A +rs2079099 single 22:20000001-21000000 850439 G +rs7287307 single 22:20000001-21000000 850465 G +rs7287307 single 22:20000001-21000000 850465 T +rs1860127 single 22:20000001-21000000 850576 T +rs9608041 single 22:20000001-21000000 851423 T +rs138249536 single 22:20000001-21000000 851449 T +rs5750181 single 22:20000001-21000000 852483 T +rs115998938 single 22:20000001-21000000 852835 G +rs79092664 single 22:20000001-21000000 853156 C +rs371461908 single 22:20000001-21000000 853479 T +rs6519391 single 22:20000001-21000000 853520 T +rs62219897 single 22:20000001-21000000 853606 T +rs562639782 deletion 22:20000001-21000000 853709 1 +rs148640315 single 22:20000001-21000000 853867 A +rs5756019 single 22:20000001-21000000 853910 A +rs4820216 single 22:20000001-21000000 854160 C +rs111499360 single 22:20000001-21000000 854305 A +rs539471333 deletion 22:20000001-21000000 854678 4 +rs35094345 deletion 22:20000001-21000000 855009 1 +rs139058763 single 22:20000001-21000000 855183 A +rs113733472 single 22:20000001-21000000 855213 T +rs165798 single 22:20000001-21000000 855285 A +rs1682 single 22:20000001-21000000 855538 C +rs115649345 single 22:20000001-21000000 855615 A +rs61740440 single 22:20000001-21000000 855637 C +rs9612142 single 22:20000001-21000000 855696 T +rs61747404 single 22:20000001-21000000 855728 T +rs5995230 single 22:20000001-21000000 855763 T +rs74368349 single 22:20000001-21000000 855850 A +rs138574421 deletion 22:20000001-21000000 856214 2 +rs201449145 deletion 22:20000001-21000000 856419 1 +rs113152604 single 22:20000001-21000000 856620 A +rs78379949 single 22:20000001-21000000 856857 C +rs4820226 single 22:20000001-21000000 857049 T +rs6000237 single 22:20000001-21000000 857390 A +rs34592890 single 22:20000001-21000000 857644 A +rs144189613 single 22:20000001-21000000 857680 C +rs76788398 single 22:20000001-21000000 857794 G +rs557848953 insertion 22:20000001-21000000 857838 C +rs79785707 single 22:20000001-21000000 858094 G +rs373739552 single 22:20000001-21000000 858328 A +rs75702695 single 22:20000001-21000000 858742 A +rs6000285 single 22:20000001-21000000 858802 T +rs5995304 single 22:20000001-21000000 859291 A +rs145396820 single 22:20000001-21000000 859562 G +rs2876824 single 22:20000001-21000000 859628 A +rs2876825 single 22:20000001-21000000 859800 C +rs530924853 single 22:20000001-21000000 859939 A +rs79538179 single 22:20000001-21000000 859988 A +rs375433191 deletion 22:20000001-21000000 860070 3 +rs1807511 single 22:20000001-21000000 860378 C +rs112097936 deletion 22:20000001-21000000 860486 1 +rs35816559 insertion 22:20000001-21000000 860794 G +rs2010947 single 22:20000001-21000000 860880 G +rs142518536 insertion 22:20000001-21000000 860908 T +rs738092 single 22:20000001-21000000 860930 T +rs74754583 single 22:20000001-21000000 861289 T +rs5844426 insertion 22:20000001-21000000 861405 G +rs76278738 single 22:20000001-21000000 861505 G +rs386486036 single 22:20000001-21000000 861642 C +rs12159991 single 22:20000001-21000000 861721 G +rs917408 single 22:20000001-21000000 862148 T +rs5750324 single 22:20000001-21000000 862645 G +rs118084062 single 22:20000001-21000000 863436 T +rs73156970 single 22:20000001-21000000 863884 A +rs75633876 single 22:20000001-21000000 864043 C +rs76651446 single 22:20000001-21000000 864341 G +rs111354787 single 22:20000001-21000000 864391 G +rs141370998 single 22:20000001-21000000 864420 T +rs57046550 single 22:20000001-21000000 864600 C +rs76188872 single 22:20000001-21000000 864666 T +rs8137729 single 22:20000001-21000000 864843 T +rs6000569 single 22:20000001-21000000 864939 T +rs5756526 single 22:20000001-21000000 865144 C +rs11704564 single 22:20000001-21000000 865290 C +rs35887140 insertion 22:20000001-21000000 865785 A +rs6000620 single 22:20000001-21000000 866230 C +rs997734 single 22:20000001-21000000 866292 T +rs997144 single 22:20000001-21000000 866377 T +rs997145 single 22:20000001-21000000 866657 T +rs5756597 single 22:20000001-21000000 866833 A +rs5756605 single 22:20000001-21000000 867072 T +rs62238762 single 22:20000001-21000000 867119 T +rs165687 single 22:20000001-21000000 867264 A +rs5756675 single 22:20000001-21000000 868222 A +rs115442611 single 22:20000001-21000000 868251 A +rs74637305 single 22:20000001-21000000 868673 C +rs78093216 single 22:20000001-21000000 868705 G +rs11703747 single 22:20000001-21000000 868963 T +rs13053946 single 22:20000001-21000000 869135 T +rs28438593 single 22:20000001-21000000 869474 T +rs28676928 single 22:20000001-21000000 869508 T +rs73384298 single 22:20000001-21000000 869566 G +rs361781 deletion 22:20000001-21000000 869750 1 +rs11703134 single 22:20000001-21000000 869960 T +rs150125958 single 22:20000001-21000000 869987 A +rs145506338 single 22:20000001-21000000 870027 A +rs148839032 single 22:20000001-21000000 870153 A +rs536348998 insertion 22:20000001-21000000 870286 CAAAACAAACAAA +rs569935957 insertion 22:20000001-21000000 870604 AAT +rs114048337 single 22:20000001-21000000 870684 T +rs5756801 single 22:20000001-21000000 871337 C +rs548844927 insertion 22:20000001-21000000 871390 T +rs76713085 single 22:20000001-21000000 871742 T +rs75516987 single 22:20000001-21000000 871963 G +rs77931322 single 22:20000001-21000000 872109 C +rs112448672 insertion 22:20000001-21000000 872139 T +rs112448672 insertion 22:20000001-21000000 872139 TT +rs112448672 insertion 22:20000001-21000000 872139 TTT +rs11090191 single 22:20000001-21000000 872506 T +rs75439996 single 22:20000001-21000000 872720 G +rs2014654 single 22:20000001-21000000 872854 T +rs11090193 single 22:20000001-21000000 873392 A +rs11913315 single 22:20000001-21000000 873557 G +rs11912924 single 22:20000001-21000000 873874 A +rs73879393 single 22:20000001-21000000 874447 G +rs114516538 single 22:20000001-21000000 874539 A +rs11912433 single 22:20000001-21000000 875405 C +rs114056587 single 22:20000001-21000000 875484 T +rs5750555 single 22:20000001-21000000 875692 T +rs148027533 single 22:20000001-21000000 875713 T +rs141901165 single 22:20000001-21000000 875776 A +rs557681487 deletion 22:20000001-21000000 875837 1 +rs200999942 deletion 22:20000001-21000000 875982 20 +rs8140155 single 22:20000001-21000000 876274 A +rs7291930 single 22:20000001-21000000 876508 G +rs114191051 single 22:20000001-21000000 876840 A +rs9612171 single 22:20000001-21000000 877224 T +rs74548973 single 22:20000001-21000000 877583 A +rs61541782 single 22:20000001-21000000 877644 A +rs75902369 single 22:20000001-21000000 877766 G +rs199594432 insertion 22:20000001-21000000 878900 TTTTG +rs8137443 single 22:20000001-21000000 879126 T +rs113246670 insertion 22:20000001-21000000 879607 T +rs141994484 single 22:20000001-21000000 880011 A +rs114335926 single 22:20000001-21000000 880118 A +rs117141812 single 22:20000001-21000000 880709 T +rs79962566 single 22:20000001-21000000 880897 T +rs1076348 single 22:20000001-21000000 881110 A +rs1110462 single 22:20000001-21000000 881384 G +rs11090206 single 22:20000001-21000000 881677 A +rs148371154 deletion 22:20000001-21000000 881739 1 +rs12165407 single 22:20000001-21000000 882326 T +rs6001257 single 22:20000001-21000000 882388 T +rs114819925 single 22:20000001-21000000 882608 G +rs114819925 single 22:20000001-21000000 882608 T +rs144682660 deletion 22:20000001-21000000 882735 2 +rs11913514 single 22:20000001-21000000 882951 T +rs78944331 single 22:20000001-21000000 883025 T +rs79052816 single 22:20000001-21000000 883376 T +rs1771149 single 22:20000001-21000000 883448 C +rs1638036 single 22:20000001-21000000 883637 A +rs149561599 single 22:20000001-21000000 883739 G +rs6001392 single 22:20000001-21000000 884236 T +rs12484631 single 22:20000001-21000000 884299 T +rs6519408 single 22:20000001-21000000 884909 T +rs141160674 insertion 22:20000001-21000000 885037 G +rs74434132 single 22:20000001-21000000 885306 T +rs115226093 single 22:20000001-21000000 885417 T +rs144537609 deletion 22:20000001-21000000 885474 8 +rs75648513 single 22:20000001-21000000 885688 A +rs73156978 single 22:20000001-21000000 886277 A +rs5995708 single 22:20000001-21000000 887079 G +rs77182190 single 22:20000001-21000000 887191 A +rs5995717 single 22:20000001-21000000 887532 G +rs74875546 single 22:20000001-21000000 887603 G +rs73879395 single 22:20000001-21000000 887971 T +rs115972182 single 22:20000001-21000000 888166 T +rs5995739 single 22:20000001-21000000 888737 C +rs115678536 single 22:20000001-21000000 888774 G +rs115678536 single 22:20000001-21000000 888774 T +rs73156979 single 22:20000001-21000000 888827 A +rs77372198 single 22:20000001-21000000 888925 T +rs11703918 single 22:20000001-21000000 889101 G +rs5757702 single 22:20000001-21000000 889270 A +rs5757702 single 22:20000001-21000000 889270 C +rs148429575 single 22:20000001-21000000 889368 G +rs79089854 single 22:20000001-21000000 889685 T +rs6001632 single 22:20000001-21000000 889907 A +rs6001633 single 22:20000001-21000000 889932 A +rs139346388 single 22:20000001-21000000 889994 C +rs5995758 single 22:20000001-21000000 890026 A +rs4528873 single 22:20000001-21000000 890117 T +rs556617943 deletion 22:20000001-21000000 890159 6 +rs5757755 single 22:20000001-21000000 890266 A +rs147886513 single 22:20000001-21000000 890656 A +rs77859693 single 22:20000001-21000000 891139 A +rs2269830 single 22:20000001-21000000 891258 A +rs5995779 single 22:20000001-21000000 891365 C +rs148534902 insertion 22:20000001-21000000 891498 CCTA +rs4821915 single 22:20000001-21000000 891544 G +rs2269831 single 22:20000001-21000000 891567 A +rs75878005 single 22:20000001-21000000 891724 T +rs2269832 single 22:20000001-21000000 891841 T +rs2269833 single 22:20000001-21000000 891927 T +rs78413892 single 22:20000001-21000000 892831 T +rs142664482 single 22:20000001-21000000 893193 T +rs139562158 single 22:20000001-21000000 893267 G +rs140034483 insertion 22:20000001-21000000 893574 G +rs1638037 single 22:20000001-21000000 893768 C +rs79860789 single 22:20000001-21000000 894170 T +rs140548641 single 22:20000001-21000000 895023 A +rs2329363 single 22:20000001-21000000 895157 C +rs144714885 single 22:20000001-21000000 895371 C +rs76852703 single 22:20000001-21000000 895772 C +rs113878252 single 22:20000001-21000000 895926 T +rs137870605 single 22:20000001-21000000 896220 T +rs11914092 single 22:20000001-21000000 896692 A +rs73156987 single 22:20000001-21000000 896899 C +rs7292126 single 22:20000001-21000000 896925 A +rs56167190 single 22:20000001-21000000 897231 C +rs147394731 single 22:20000001-21000000 897558 T +rs5750937 single 22:20000001-21000000 897845 T +rs140000135 single 22:20000001-21000000 897882 T +rs9608082 single 22:20000001-21000000 897913 A +rs5750938 single 22:20000001-21000000 898004 T +rs4821945 single 22:20000001-21000000 898119 C +rs115166844 single 22:20000001-21000000 898156 G +rs4821947 single 22:20000001-21000000 898322 C +rs75472746 single 22:20000001-21000000 898401 A +rs77937663 single 22:20000001-21000000 898507 T +rs147989304 single 22:20000001-21000000 898814 A +rs5757972 single 22:20000001-21000000 898955 C +rs150376781 deletion 22:20000001-21000000 899157 1 +rs5757984 single 22:20000001-21000000 899185 A +rs5757992 single 22:20000001-21000000 899253 A +rs5757994 single 22:20000001-21000000 899315 A +rs114481046 single 22:20000001-21000000 899362 G +rs12483842 single 22:20000001-21000000 899633 T +rs12484159 single 22:20000001-21000000 899704 A +rs56307139 deletion 22:20000001-21000000 899760 1 +rs4821961 single 22:20000001-21000000 899970 A +rs4821963 single 22:20000001-21000000 900073 C +rs4821967 single 22:20000001-21000000 900576 T +rs4821970 single 22:20000001-21000000 900797 T +rs16988498 single 22:20000001-21000000 900943 T +rs35724035 single 22:20000001-21000000 901075 T +rs16988501 single 22:20000001-21000000 901619 A +rs16988502 single 22:20000001-21000000 901649 C +rs9637342 single 22:20000001-21000000 901695 C +rs11913912 single 22:20000001-21000000 901797 A +rs60395699 single 22:20000001-21000000 902116 T +rs140738445 deletion 22:20000001-21000000 902439 7 +rs76279337 single 22:20000001-21000000 902871 T +rs886319 single 22:20000001-21000000 903409 T +rs12484992 single 22:20000001-21000000 903438 C +rs886320 single 22:20000001-21000000 903516 C +rs73879402 single 22:20000001-21000000 903695 A +rs17211374 single 22:20000001-21000000 903862 G +rs116345961 single 22:20000001-21000000 904030 T +rs5751024 single 22:20000001-21000000 904072 C +rs75195136 single 22:20000001-21000000 904263 G +rs114815122 single 22:20000001-21000000 905061 G +rs1209259 single 22:20000001-21000000 905087 C +rs115227665 single 22:20000001-21000000 905204 C +rs116430800 single 22:20000001-21000000 905619 G +rs77357764 single 22:20000001-21000000 905645 T +rs1075339 single 22:20000001-21000000 906366 A +rs28681662 single 22:20000001-21000000 906453 T +rs165829 single 22:20000001-21000000 907302 C +rs71725860 deletion 22:20000001-21000000 907650 2 +rs177419 single 22:20000001-21000000 908114 A +rs5758363 single 22:20000001-21000000 908514 T +rs165749 single 22:20000001-21000000 908701 C +rs634622 single 22:20000001-21000000 908731 C +rs165609 single 22:20000001-21000000 908992 C +rs145029830 single 22:20000001-21000000 909205 T +rs117046295 single 22:20000001-21000000 909447 T +rs73157002 single 22:20000001-21000000 909543 A +rs73159105 single 22:20000001-21000000 909640 T +rs165804 single 22:20000001-21000000 909673 C +rs79160294 single 22:20000001-21000000 910030 T +rs117176662 single 22:20000001-21000000 910090 G +rs73159109 single 22:20000001-21000000 910192 G +rs116891401 single 22:20000001-21000000 910219 C +rs148876050 single 22:20000001-21000000 910263 T +rs115069799 single 22:20000001-21000000 910481 T +rs361842 deletion 22:20000001-21000000 910589 1 +rs165752 single 22:20000001-21000000 910682 G +rs5758417 single 22:20000001-21000000 910832 T +rs138331367 single 22:20000001-21000000 910865 T +rs5758468 single 22:20000001-21000000 911755 C +rs1807730 single 22:20000001-21000000 912208 T +rs165855 single 22:20000001-21000000 912252 T +rs139965797 deletion 22:20000001-21000000 912403 2 +rs4560234 single 22:20000001-21000000 912841 G +rs145095141 single 22:20000001-21000000 912878 C +rs165833 single 22:20000001-21000000 912969 G +rs16988513 single 22:20000001-21000000 912994 A +rs165671 single 22:20000001-21000000 913509 G +rs177421 single 22:20000001-21000000 913756 A +rs177422 single 22:20000001-21000000 913877 A +rs141805630 insertion 22:20000001-21000000 914548 TATTAT +rs141805630 insertion 22:20000001-21000000 914548 TATTATTAT +rs148167389 single 22:20000001-21000000 914626 T +rs147303132 single 22:20000001-21000000 914688 T +rs165779 single 22:20000001-21000000 914756 A +rs165672 single 22:20000001-21000000 914957 T +rs112729229 single 22:20000001-21000000 915534 T +rs5758631 single 22:20000001-21000000 915616 G +rs4822096 single 22:20000001-21000000 915674 T +rs150408219 single 22:20000001-21000000 915791 C +rs5996131 single 22:20000001-21000000 915988 G +rs5751254 single 22:20000001-21000000 916332 T +rs73159117 single 22:20000001-21000000 916619 G +rs74972844 single 22:20000001-21000000 916666 T +rs362137 deletion 22:20000001-21000000 916694 2 +rs148221516 single 22:20000001-21000000 916831 T +rs165884 single 22:20000001-21000000 917066 G +rs165788 single 22:20000001-21000000 917303 T +rs8137236 single 22:20000001-21000000 917526 G +rs77047145 single 22:20000001-21000000 917683 G +rs143377454 single 22:20000001-21000000 917830 G +rs143377454 single 22:20000001-21000000 917830 T +rs532571713 single 22:20000001-21000000 918637 G +rs165874 single 22:20000001-21000000 919305 G +rs177423 single 22:20000001-21000000 919376 A +rs3791192 single 22:20000001-21000000 919445 A +rs165685 single 22:20000001-21000000 919754 T +rs73159120 single 22:20000001-21000000 920043 T +rs165900 single 22:20000001-21000000 920198 C +rs555771579 deletion 22:20000001-21000000 920317 4 +rs116294672 single 22:20000001-21000000 920701 A +rs539945336 insertion 22:20000001-21000000 920831 CAG +rs165664 single 22:20000001-21000000 921338 G +rs77616353 single 22:20000001-21000000 921454 A +rs116892353 single 22:20000001-21000000 921722 G +rs165727 single 22:20000001-21000000 921892 T +rs79106741 single 22:20000001-21000000 922155 G +rs12484645 single 22:20000001-21000000 922315 C +rs17819434 single 22:20000001-21000000 922469 T +rs55636848 single 22:20000001-21000000 923360 T +rs72200590 deletion 22:20000001-21000000 923922 3 +rs165846 single 22:20000001-21000000 924027 G +rs165721 single 22:20000001-21000000 924590 G +rs362206 deletion 22:20000001-21000000 924680 1 +rs143351279 single 22:20000001-21000000 924780 A +rs146839104 single 22:20000001-21000000 924812 A +rs574570557 deletion 22:20000001-21000000 925033 16 +rs2079096 single 22:20000001-21000000 925100 A +rs595044 single 22:20000001-21000000 925203 G +rs138548433 single 22:20000001-21000000 925353 T +rs57039063 single 22:20000001-21000000 925623 G +rs5751448 single 22:20000001-21000000 925759 T +rs165620 single 22:20000001-21000000 926294 C +rs79995359 single 22:20000001-21000000 926558 A +rs165918 single 22:20000001-21000000 926624 A +rs5759268 single 22:20000001-21000000 926812 T +rs362058 insertion 22:20000001-21000000 926926 C +rs531789186 insertion 22:20000001-21000000 927256 CTT +rs531789186 insertion 22:20000001-21000000 927256 TTC +rs177425 single 22:20000001-21000000 927542 T +rs5759311 single 22:20000001-21000000 927674 A +rs5759314 single 22:20000001-21000000 927715 C +rs165666 single 22:20000001-21000000 927801 A +rs11704626 single 22:20000001-21000000 928129 T +rs6003200 single 22:20000001-21000000 928233 T +rs165772 single 22:20000001-21000000 928265 A +rs165674 single 22:20000001-21000000 928808 T +rs12484576 single 22:20000001-21000000 929083 C +rs165842 single 22:20000001-21000000 929285 G +rs177426 single 22:20000001-21000000 929781 A +rs165684 single 22:20000001-21000000 929913 T +rs11365089 deletion 22:20000001-21000000 930008 1 +rs61090860 deletion 22:20000001-21000000 930055 1 +rs199804769 deletion 22:20000001-21000000 930342 1 +rs361812 deletion 22:20000001-21000000 930978 3 +rs12484690 single 22:20000001-21000000 931093 C +rs12484039 single 22:20000001-21000000 931122 C +rs114152992 single 22:20000001-21000000 931489 G +rs17819470 single 22:20000001-21000000 931543 A +rs582898 single 22:20000001-21000000 932166 A +rs2079097 single 22:20000001-21000000 932237 G +rs94001 single 22:20000001-21000000 932278 T +rs2079098 single 22:20000001-21000000 932457 T +rs116277470 single 22:20000001-21000000 932679 A +rs78146318 single 22:20000001-21000000 932711 T +rs66846976 deletion 22:20000001-21000000 932963 2 +rs56024156 deletion 22:20000001-21000000 933197 2 +rs17757688 single 22:20000001-21000000 933734 T +rs6003243 single 22:20000001-21000000 933783 T +rs5751537 single 22:20000001-21000000 933900 C +rs73877705 single 22:20000001-21000000 934039 T +rs5759416 single 22:20000001-21000000 934238 A +rs78095529 single 22:20000001-21000000 934410 T +rs79876592 single 22:20000001-21000000 934507 T +rs200362928 deletion 22:20000001-21000000 934763 1 +rs5751540 single 22:20000001-21000000 934971 G +rs73159139 single 22:20000001-21000000 935008 T +rs165838 single 22:20000001-21000000 935375 G +rs165614 single 22:20000001-21000000 935672 C +rs633788 single 22:20000001-21000000 935716 A +rs73159140 single 22:20000001-21000000 935945 A +rs646164 single 22:20000001-21000000 936333 T +rs111672536 single 22:20000001-21000000 936819 C +rs116529718 single 22:20000001-21000000 936872 A +rs165643 single 22:20000001-21000000 937600 T +rs5759455 single 22:20000001-21000000 938179 A +rs165690 single 22:20000001-21000000 938376 G +rs1572878 single 22:20000001-21000000 938771 C +rs165835 single 22:20000001-21000000 939122 A +rs61741073 single 22:20000001-21000000 939399 A +rs61748930 single 22:20000001-21000000 939445 T +rs2285698 single 22:20000001-21000000 939607 A +rs2285699 single 22:20000001-21000000 940084 A +rs165615 single 22:20000001-21000000 940207 C +rs165695 single 22:20000001-21000000 940265 G +rs734740 single 22:20000001-21000000 940290 T +rs116623013 single 22:20000001-21000000 940330 T +rs73877706 single 22:20000001-21000000 940476 A +rs93173 single 22:20000001-21000000 940793 A +rs148327276 single 22:20000001-21000000 940821 T +rs12484193 single 22:20000001-21000000 941011 T +rs648963 single 22:20000001-21000000 941194 A +rs648963 single 22:20000001-21000000 941194 C +rs648963 single 22:20000001-21000000 941194 T +rs741191 single 22:20000001-21000000 941449 C +rs150690002 single 22:20000001-21000000 941550 T +rs73877708 single 22:20000001-21000000 942157 A +rs11913826 single 22:20000001-21000000 942191 A +rs2240029 single 22:20000001-21000000 942216 A +rs73159144 single 22:20000001-21000000 942640 A +rs9620292 single 22:20000001-21000000 942962 T +rs1076456 single 22:20000001-21000000 943201 A +rs56023828 single 22:20000001-21000000 943589 C +rs77784036 single 22:20000001-21000000 943618 C +rs77214221 single 22:20000001-21000000 943671 C +rs6003315 single 22:20000001-21000000 943948 A +rs165600 single 22:20000001-21000000 944154 G +rs73877709 single 22:20000001-21000000 944404 C +rs165765 single 22:20000001-21000000 944832 C +rs361989 single 22:20000001-21000000 945318 A +rs11912746 single 22:20000001-21000000 945760 C +rs78227773 single 22:20000001-21000000 946197 A +rs77700530 single 22:20000001-21000000 946266 T +rs165591 single 22:20000001-21000000 946301 T +rs595272 single 22:20000001-21000000 946402 T +rs12160935 single 22:20000001-21000000 946445 T +rs139511310 single 22:20000001-21000000 946675 T +rs165638 single 22:20000001-21000000 946862 T +rs165870 single 22:20000001-21000000 946907 T +rs165904 single 22:20000001-21000000 947016 G +rs165716 single 22:20000001-21000000 947082 G +rs361646 single 22:20000001-21000000 947273 G +rs177427 single 22:20000001-21000000 947366 A +rs77272549 single 22:20000001-21000000 947480 G +rs150549289 deletion 22:20000001-21000000 947834 4 +rs577762 single 22:20000001-21000000 947902 G +rs165708 single 22:20000001-21000000 947995 T +rs165723 single 22:20000001-21000000 948457 A +rs77737922 single 22:20000001-21000000 948489 G +rs147796987 insertion 22:20000001-21000000 948516 AAAG +rs4820534 single 22:20000001-21000000 948552 A +rs12160184 single 22:20000001-21000000 948761 A +rs5759496 single 22:20000001-21000000 949162 G +rs59219870 single 22:20000001-21000000 949242 G +rs361690 insertion 22:20000001-21000000 949302 A +rs59461209 single 22:20000001-21000000 949364 T +rs372403230 insertion 22:20000001-21000000 949468 AAAAA +rs58792806 single 22:20000001-21000000 949548 T +rs12160007 single 22:20000001-21000000 949577 G +rs140659230 deletion 22:20000001-21000000 949715 1 +rs658396 single 22:20000001-21000000 949856 T +rs76211167 single 22:20000001-21000000 950021 T +rs607893 single 22:20000001-21000000 950078 A +rs9620311 single 22:20000001-21000000 950116 C +rs4822328 single 22:20000001-21000000 950327 C +rs4822329 single 22:20000001-21000000 950429 A +rs362089 single 22:20000001-21000000 950472 G +rs554733 single 22:20000001-21000000 950563 T +rs117887561 single 22:20000001-21000000 950820 A +rs7410267 single 22:20000001-21000000 950858 C +rs139424286 single 22:20000001-21000000 950883 C +rs139565162 single 22:20000001-21000000 951011 A +rs181876047 single 22:20000001-21000000 951110 T +rs28576992 single 22:20000001-21000000 951218 A +rs8135752 single 22:20000001-21000000 951260 G +rs115767262 single 22:20000001-21000000 951319 G +rs689145 single 22:20000001-21000000 951442 C +rs853122 single 22:20000001-21000000 951772 C +rs9624294 single 22:20000001-21000000 951846 A +rs11090281 single 22:20000001-21000000 951987 G +rs12170799 single 22:20000001-21000000 952038 T +rs7511235 single 22:20000001-21000000 952131 G +rs187454438 single 22:20000001-21000000 952170 G +rs685627 single 22:20000001-21000000 952225 C +rs115803514 single 22:20000001-21000000 952284 A +rs144972331 single 22:20000001-21000000 952518 T +rs853125 single 22:20000001-21000000 952635 G +rs138298773 deletion 22:20000001-21000000 952802 5 +rs114688043 single 22:20000001-21000000 952941 T +rs56075775 deletion 22:20000001-21000000 952969 1 +rs12166518 single 22:20000001-21000000 953028 T +rs142358110 single 22:20000001-21000000 953056 A +rs117381628 single 22:20000001-21000000 953187 G +rs34814924 deletion 22:20000001-21000000 953519 3 +rs545280536 deletion 22:20000001-21000000 953744 1 +rs80296680 single 22:20000001-21000000 953849 G +rs138098180 single 22:20000001-21000000 953876 T +rs684057 single 22:20000001-21000000 954189 T +rs34443648 single 22:20000001-21000000 954213 T +rs12166099 single 22:20000001-21000000 954686 G +rs12166147 single 22:20000001-21000000 954751 C +rs165785 single 22:20000001-21000000 954865 A +rs527831543 deletion 22:20000001-21000000 955474 1 +rs165919 single 22:20000001-21000000 955521 C +rs147181459 single 22:20000001-21000000 955750 A +rs74466416 single 22:20000001-21000000 955906 C +rs12165536 single 22:20000001-21000000 955935 T +rs143814858 single 22:20000001-21000000 955999 A +rs626568 single 22:20000001-21000000 956162 T +rs546419 single 22:20000001-21000000 956241 T +rs165703 single 22:20000001-21000000 956440 C +rs566704625 deletion 22:20000001-21000000 956568 2 +rs5759527 single 22:20000001-21000000 956599 T +rs144048639 deletion 22:20000001-21000000 956662 2 +rs552823 single 22:20000001-21000000 956905 T +rs111348451 single 22:20000001-21000000 956992 C +rs9612414 single 22:20000001-21000000 957036 A +rs117727383 single 22:20000001-21000000 957111 A +rs60128632 single 22:20000001-21000000 957342 T +rs58090831 single 22:20000001-21000000 957401 A +rs5759533 single 22:20000001-21000000 957495 A +rs74756466 single 22:20000001-21000000 957598 A +rs111822094 single 22:20000001-21000000 957833 T +rs9612416 single 22:20000001-21000000 957866 A +rs35725919 insertion 22:20000001-21000000 957909 A +rs9612417 single 22:20000001-21000000 958043 T +rs12170292 single 22:20000001-21000000 958141 A +rs79337706 single 22:20000001-21000000 958312 C +rs74476273 single 22:20000001-21000000 958399 G +rs5751562 single 22:20000001-21000000 958460 A +rs5751562 single 22:20000001-21000000 958460 T +rs9620323 single 22:20000001-21000000 958487 T +rs9624321 single 22:20000001-21000000 958573 A +rs165897 single 22:20000001-21000000 958624 T +rs78264877 single 22:20000001-21000000 958706 A +rs5751564 single 22:20000001-21000000 958778 T +rs8141468 single 22:20000001-21000000 959070 T +rs13340094 single 22:20000001-21000000 959099 T +rs75679744 single 22:20000001-21000000 959167 T +rs526942 single 22:20000001-21000000 959251 G +rs34877965 deletion 22:20000001-21000000 959349 1 +rs528634 single 22:20000001-21000000 959406 A +rs731272 single 22:20000001-21000000 959690 T +rs3747078 single 22:20000001-21000000 959801 A +rs73877712 single 22:20000001-21000000 959914 G +rs731273 single 22:20000001-21000000 960185 A +rs76481083 single 22:20000001-21000000 960452 A +rs34944089 insertion 22:20000001-21000000 960567 G +rs879953 single 22:20000001-21000000 960624 G +rs115786135 single 22:20000001-21000000 960663 T +rs561595 single 22:20000001-21000000 960706 G +rs879955 single 22:20000001-21000000 960936 C +rs13340098 single 22:20000001-21000000 961108 T +rs13433634 single 22:20000001-21000000 961188 C +rs73386169 single 22:20000001-21000000 961780 A +rs73386169 single 22:20000001-21000000 961780 T +rs17819593 single 22:20000001-21000000 962027 T +rs73386171 single 22:20000001-21000000 962210 C +rs67888103 single 22:20000001-21000000 962378 A +rs67695329 single 22:20000001-21000000 962418 A +rs510270 single 22:20000001-21000000 962560 A +rs73159154 single 22:20000001-21000000 962688 G +rs143565951 single 22:20000001-21000000 962771 G +rs5759551 single 22:20000001-21000000 962804 A +rs17819599 single 22:20000001-21000000 962977 T +rs514648 single 22:20000001-21000000 963039 A +rs556083381 deletion 22:20000001-21000000 963075 1 +rs6003435 single 22:20000001-21000000 963206 A +rs6003437 single 22:20000001-21000000 963267 A +rs1557798 single 22:20000001-21000000 963372 A +rs602808 single 22:20000001-21000000 963474 C +rs544887 single 22:20000001-21000000 964055 A +rs79101340 single 22:20000001-21000000 964103 C +rs58396621 single 22:20000001-21000000 964465 A +rs59007955 single 22:20000001-21000000 964755 T +rs680548 single 22:20000001-21000000 965554 C +rs112940211 single 22:20000001-21000000 965655 A +rs493316 single 22:20000001-21000000 965854 A +rs5759559 single 22:20000001-21000000 965898 T +rs5759560 single 22:20000001-21000000 966098 G +rs5759562 single 22:20000001-21000000 966124 A +rs115257028 single 22:20000001-21000000 966216 G +rs650538 single 22:20000001-21000000 966269 C +rs1108099 single 22:20000001-21000000 966395 G +rs1108101 single 22:20000001-21000000 966456 A +rs738040 single 22:20000001-21000000 966546 G +rs6003459 single 22:20000001-21000000 966726 G +rs6003460 single 22:20000001-21000000 966823 C +rs7285254 single 22:20000001-21000000 967163 G +rs7287256 single 22:20000001-21000000 967189 T +rs16988585 single 22:20000001-21000000 967286 G +rs472409 single 22:20000001-21000000 967332 T +rs473304 single 22:20000001-21000000 967449 A +rs12484196 single 22:20000001-21000000 967611 C +rs5759567 single 22:20000001-21000000 967755 A +rs145036582 insertion 22:20000001-21000000 967970 T +rs853127 single 22:20000001-21000000 968291 A +rs619770 single 22:20000001-21000000 968582 C +rs58136388 single 22:20000001-21000000 968684 G +rs76937208 single 22:20000001-21000000 968705 G +rs114671525 single 22:20000001-21000000 968733 T +rs7285851 single 22:20000001-21000000 968763 C +rs78344658 single 22:20000001-21000000 968876 G +rs112669588 single 22:20000001-21000000 968932 G +rs617867 single 22:20000001-21000000 969009 C +rs148735102 single 22:20000001-21000000 969043 A +rs142285441 single 22:20000001-21000000 969184 T +rs141897641 single 22:20000001-21000000 969305 C +rs80189286 single 22:20000001-21000000 969578 G +rs147731752 single 22:20000001-21000000 969679 T +rs602738 single 22:20000001-21000000 970071 G +rs11090296 single 22:20000001-21000000 970174 T +rs9624340 single 22:20000001-21000000 970260 T +rs562536 single 22:20000001-21000000 970287 G +rs113244786 deletion 22:20000001-21000000 970321 12 +rs853131 single 22:20000001-21000000 970884 A +rs853131 single 22:20000001-21000000 970884 G +rs853131 single 22:20000001-21000000 970884 T +rs569817 single 22:20000001-21000000 971050 A +rs570795 single 22:20000001-21000000 971163 T +rs482165 single 22:20000001-21000000 971221 G +rs483273 single 22:20000001-21000000 971369 G +rs112133338 single 22:20000001-21000000 971452 A +rs543463705 insertion 22:20000001-21000000 971647 A +rs75156636 single 22:20000001-21000000 971738 C +rs5759575 single 22:20000001-21000000 971833 A +rs143269077 insertion 22:20000001-21000000 971920 T +rs143269077 insertion 22:20000001-21000000 971920 TT +rs143269077 insertion 22:20000001-21000000 971920 TTTTTG +rs143269077 insertion 22:20000001-21000000 971920 TTTTTT +rs118139208 single 22:20000001-21000000 971980 A +rs112372337 single 22:20000001-21000000 972101 A +rs490749 single 22:20000001-21000000 972175 T +rs5759576 single 22:20000001-21000000 972208 A +rs512705 single 22:20000001-21000000 972276 C +rs79438615 deletion 22:20000001-21000000 972403 1 +rs79882895 single 22:20000001-21000000 972758 T +rs11912543 single 22:20000001-21000000 972845 T +rs654526 single 22:20000001-21000000 973385 C +rs67589781 deletion 22:20000001-21000000 973451 1 +rs8138867 single 22:20000001-21000000 973483 C +rs653181 single 22:20000001-21000000 973687 C +rs114547898 single 22:20000001-21000000 973905 A +rs2027369 single 22:20000001-21000000 973950 T +rs8141122 single 22:20000001-21000000 974460 T +rs199593637 insertion 22:20000001-21000000 974510 TA +rs201122671 deletion 22:20000001-21000000 974542 2 +rs116432563 single 22:20000001-21000000 974823 C +rs202212126 deletion 22:20000001-21000000 975199 1 +rs11090300 single 22:20000001-21000000 975591 T +rs623679 single 22:20000001-21000000 975689 G +rs111319236 deletion 22:20000001-21000000 975866 4 +rs9620335 single 22:20000001-21000000 975891 G +rs9620335 single 22:20000001-21000000 975891 T +rs73386179 single 22:20000001-21000000 975924 T +rs73386180 single 22:20000001-21000000 976037 A +rs78003513 single 22:20000001-21000000 976087 A +rs111455684 single 22:20000001-21000000 976133 A +rs557958 single 22:20000001-21000000 976357 G +rs143901038 single 22:20000001-21000000 976534 A +rs148714004 single 22:20000001-21000000 976605 C +rs77793416 single 22:20000001-21000000 977047 T +rs564493 single 22:20000001-21000000 977076 A +rs34404739 single 22:20000001-21000000 977266 T +rs687164 single 22:20000001-21000000 977291 T +rs687106 single 22:20000001-21000000 977338 T +rs531775638 single 22:20000001-21000000 977440 G +rs578134684 deletion 22:20000001-21000000 977498 1 +rs115769480 single 22:20000001-21000000 977553 A +rs144037599 single 22:20000001-21000000 977604 C +rs480471 single 22:20000001-21000000 977645 A +rs116434024 single 22:20000001-21000000 977676 C +rs685380 single 22:20000001-21000000 977718 G +rs142051118 insertion 22:20000001-21000000 977789 T +rs74607071 single 22:20000001-21000000 978213 T +rs79591662 single 22:20000001-21000000 978260 C +rs73159169 single 22:20000001-21000000 978387 G +rs16988610 single 22:20000001-21000000 978496 C +rs28690416 single 22:20000001-21000000 978535 A +rs17818796 single 22:20000001-21000000 978671 G +rs670380 single 22:20000001-21000000 978718 C +rs8135803 single 22:20000001-21000000 978976 T +rs8135829 single 22:20000001-21000000 979028 A +rs8142362 single 22:20000001-21000000 979078 G +rs72050218 deletion 22:20000001-21000000 979145 2 +rs115556005 single 22:20000001-21000000 979319 A +rs115556005 single 22:20000001-21000000 979319 C +rs554397435 insertion 22:20000001-21000000 979805 T +rs10427922 single 22:20000001-21000000 979979 G +rs112030875 single 22:20000001-21000000 980004 C +rs1861078 single 22:20000001-21000000 980307 G +rs4822364 single 22:20000001-21000000 980356 T +rs73159173 single 22:20000001-21000000 980436 G +rs4822365 single 22:20000001-21000000 980558 T +rs150412261 single 22:20000001-21000000 980771 A +rs111445826 single 22:20000001-21000000 980796 A +rs2539916 single 22:20000001-21000000 980961 G +rs149404181 deletion 22:20000001-21000000 981661 1 +rs623999 single 22:20000001-21000000 982127 C +rs117536765 single 22:20000001-21000000 982391 A +rs77465539 deletion 22:20000001-21000000 982463 1 +rs9620348 single 22:20000001-21000000 982574 A +rs112467558 single 22:20000001-21000000 982698 G +rs376886796 insertion 22:20000001-21000000 982733 A +rs5759632 single 22:20000001-21000000 982875 T +rs7285862 single 22:20000001-21000000 983227 G +rs597996 single 22:20000001-21000000 983259 A +rs597996 single 22:20000001-21000000 983259 G +rs597996 single 22:20000001-21000000 983259 T +rs597617 single 22:20000001-21000000 983308 G +rs596235 single 22:20000001-21000000 983591 C +rs7286749 single 22:20000001-21000000 983615 T +rs115287577 single 22:20000001-21000000 983692 G +rs150886737 single 22:20000001-21000000 983752 C +rs117082775 single 22:20000001-21000000 983793 C +rs12483894 single 22:20000001-21000000 983829 G +rs555454 single 22:20000001-21000000 984032 T +rs115952739 single 22:20000001-21000000 984184 A +rs578356 single 22:20000001-21000000 984247 C +rs375348388 deletion 22:20000001-21000000 984356 1 +rs78263078 single 22:20000001-21000000 984390 T +rs2039822 single 22:20000001-21000000 984724 C +rs61417886 deletion 22:20000001-21000000 984768 3 +rs5759640 single 22:20000001-21000000 984877 T +rs16988629 single 22:20000001-21000000 984999 A +rs673440 single 22:20000001-21000000 985782 G +rs114160819 single 22:20000001-21000000 985927 C +rs741192 single 22:20000001-21000000 986009 G +rs602269 single 22:20000001-21000000 986070 A +rs73159179 single 22:20000001-21000000 986254 C +rs6519496 single 22:20000001-21000000 986298 T +rs12627833 single 22:20000001-21000000 986382 T +rs565048 single 22:20000001-21000000 986546 T +rs7364324 single 22:20000001-21000000 986656 A +rs11090304 insertion 22:20000001-21000000 986699 G +rs41277303 single 22:20000001-21000000 986933 G +rs7364305 single 22:20000001-21000000 986963 G +rs10854776 single 22:20000001-21000000 987463 T +rs585467 single 22:20000001-21000000 987525 T +rs9624384 single 22:20000001-21000000 987856 T +rs583184 single 22:20000001-21000000 988044 T +rs1974310 single 22:20000001-21000000 988172 A +rs1974309 single 22:20000001-21000000 988232 A +rs853108 single 22:20000001-21000000 988371 G +rs4822376 single 22:20000001-21000000 988748 C +rs664193 single 22:20000001-21000000 989381 A +rs5759659 single 22:20000001-21000000 989408 T +rs113275556 single 22:20000001-21000000 989498 C +rs149210767 single 22:20000001-21000000 989541 T +rs662758 single 22:20000001-21000000 989748 G +rs1003718 single 22:20000001-21000000 989897 A +rs139226225 single 22:20000001-21000000 989962 T +rs661440 single 22:20000001-21000000 990056 C +rs79261470 single 22:20000001-21000000 990134 T +rs57517020 single 22:20000001-21000000 990255 T +rs75042821 single 22:20000001-21000000 990292 A +rs648936 single 22:20000001-21000000 990518 A +rs145875329 single 22:20000001-21000000 990569 A +rs17757910 single 22:20000001-21000000 990661 T +rs12166248 single 22:20000001-21000000 990854 A +rs580204 single 22:20000001-21000000 991061 C +rs5751615 single 22:20000001-21000000 991128 C +rs5751616 single 22:20000001-21000000 991234 C +rs633773 single 22:20000001-21000000 991577 G +rs9612546 single 22:20000001-21000000 991636 A +rs2080195 single 22:20000001-21000000 991770 G +rs78488852 single 22:20000001-21000000 992012 G +rs5996510 single 22:20000001-21000000 993307 T +rs741193 single 22:20000001-21000000 993466 A +rs741194 single 22:20000001-21000000 993518 A +rs73877727 single 22:20000001-21000000 993549 C +rs5996512 single 22:20000001-21000000 993621 A +rs741195 single 22:20000001-21000000 993765 G +rs2016016 single 22:20000001-21000000 993796 A +rs9612548 single 22:20000001-21000000 993960 T +rs117692845 single 22:20000001-21000000 993989 T +rs113977853 single 22:20000001-21000000 994079 C +rs2539918 single 22:20000001-21000000 994185 T +rs78464105 single 22:20000001-21000000 994219 G +rs9624394 single 22:20000001-21000000 994343 C +rs7292155 single 22:20000001-21000000 994541 G +rs56772365 single 22:20000001-21000000 994643 T +rs78817229 single 22:20000001-21000000 994722 G +rs9754375 single 22:20000001-21000000 994748 A +rs117437821 single 22:20000001-21000000 994770 T +rs7288217 single 22:20000001-21000000 994951 C +rs12484849 single 22:20000001-21000000 994996 C +rs113982879 single 22:20000001-21000000 995097 A +rs10522714 insertion 22:20000001-21000000 995287 AAATAAAT +rs505603 single 22:20000001-21000000 995479 C +rs759226 single 22:20000001-21000000 995606 C +rs510954 single 22:20000001-21000000 996025 C +rs201135342 deletion 22:20000001-21000000 996055 1 +rs141761092 single 22:20000001-21000000 996403 A +rs658793 single 22:20000001-21000000 996594 T +rs61351538 deletion 22:20000001-21000000 997219 1 +rs9624401 single 22:20000001-21000000 997320 A +rs673017 single 22:20000001-21000000 997482 T +rs35333818 deletion 22:20000001-21000000 997597 1 +rs491264 single 22:20000001-21000000 997644 G +rs674393 single 22:20000001-21000000 997810 A +rs759228 single 22:20000001-21000000 998185 A +rs115900295 single 22:20000001-21000000 998450 G +rs5759729 single 22:20000001-21000000 998534 A +rs520609 single 22:20000001-21000000 998583 A +rs11090308 single 22:20000001-21000000 998884 A +rs2003574 single 22:20000001-21000000 998964 A +rs113572801 single 22:20000001-21000000 999020 T +rs526119 single 22:20000001-21000000 999189 G diff --git a/extract_exons.py b/extract_exons.py new file mode 100644 index 0000000..42f705d --- /dev/null +++ b/extract_exons.py @@ -0,0 +1 @@ +hisat2_extract_exons.py \ No newline at end of file diff --git a/extract_splice_sites.py b/extract_splice_sites.py new file mode 100644 index 0000000..7b09145 --- /dev/null +++ b/extract_splice_sites.py @@ -0,0 +1 @@ +hisat2_extract_splice_sites.py \ No newline at end of file diff --git a/fast_mutex.h b/fast_mutex.h new file mode 100644 index 0000000..fbd7846 --- /dev/null +++ b/fast_mutex.h @@ -0,0 +1,294 @@ +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + +***************************************************************************** +Copyright (c) 2016 Nigel Dyer +This version has been modified from the original, whose original Copyright notice +is reproduced above. The permissions continue as above. + +The software has been modified in three ways: + + a) mHandle is now a mutable pointer variable which is passed to the + copy in the new =operator. This allows it to be pushed into a vector or equivalent + It is not intended to allow multiple copies of a mutex to be created + + b) The code for 64bit MSC builds uses InterlockedExchange which provides more + efficient access to the xchg assembler instruction than implementing the code as + a function in a separate .asm file. MSC does not support in line assembler for 64 bit builds. + + c) The NO_FAST_MUTEX_ASM option has been introduced + +*/ + +#ifndef _FAST_MUTEX_H_ +#define _FAST_MUTEX_H_ + +/// @file + +// Which platform are we on? +#if !defined(_TTHREAD_PLATFORM_DEFINED_) + #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define _TTHREAD_WIN32_ + #else + #define _TTHREAD_POSIX_ + #endif + #define _TTHREAD_PLATFORM_DEFINED_ +#endif + +// Check if we can support the assembly language level implementation (otherwise +// revert to the system API) +#if !defined NO_FAST_MUTEX_ASM && ((defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || \ + (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) || \ + (defined(__GNUC__) && (defined(__ppc__)))) + #define _FAST_MUTEX_ASM_ +#else + #define _FAST_MUTEX_SYS_ +#endif + +#if defined(_TTHREAD_WIN32_) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif + #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif +#else + #ifdef _FAST_MUTEX_ASM_ + #include + #else + #include + #endif +#endif + +namespace tthread { + +/// Fast mutex class. +/// This is a mutual exclusion object for synchronizing access to shared +/// memory areas for several threads. It is similar to the tthread::mutex class, +/// but instead of using system level functions, it is implemented as an atomic +/// spin lock with very low CPU overhead. +/// +/// The \c fast_mutex class is NOT compatible with the \c condition_variable +/// class (however, it IS compatible with the \c lock_guard class). It should +/// also be noted that the \c fast_mutex class typically does not provide +/// as accurate thread scheduling as a the standard \c mutex class does. +/// +/// Because of the limitations of the class, it should only be used in +/// situations where the mutex needs to be locked/unlocked very frequently. +/// +/// @note The "fast" version of this class relies on inline assembler language, +/// which is currently only supported for 32/64-bit Intel x86/AMD64 and +/// PowerPC architectures on a limited number of compilers (GNU g++ and MS +/// Visual C++). +/// For other architectures/compilers, system functions are used instead. +class fast_mutex { + public: + /// Constructor. +#if defined(_FAST_MUTEX_ASM_) + fast_mutex() : mLock(0) {} +#else + fast_mutex() + { + #if defined(_TTHREAD_WIN32_) + mHandle = new CRITICAL_SECTION(); + InitializeCriticalSection(mHandle); + #elif defined(_TTHREAD_POSIX_) + mHandle = new pthread_mutex_t(); + pthread_mutex_init(mHandle, NULL); + #endif + } +#endif + +#if !defined(_FAST_MUTEX_ASM_) + /// Destructor. + ~fast_mutex() + { + if (mHandle) + { + #if defined(_TTHREAD_WIN32_) + DeleteCriticalSection(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_mutex_destroy(mHandle); +#endif + delete mHandle; + mHandle = 0; + } + } + /// The handle is passed from the source to the desitination + /// Used primarily when mutexes are pushed onto a List either on their + /// own or as a member variable of another classs + fast_mutex & operator = (const fast_mutex& fm) + { + mHandle = fm.mHandle; + fm.mHandle = 0; + return *this; + } +#endif + + /// Lock the mutex. + /// The method will block the calling thread until a lock on the mutex can + /// be obtained. The mutex remains locked until \c unlock() is called. + /// @see lock_guard + inline void lock() + { +#if defined(_FAST_MUTEX_ASM_) + bool gotLock; + do { + gotLock = try_lock(); + if(!gotLock) + { +#if defined(_TTHREAD_WIN32_) + Sleep(0); +#elif defined(_TTHREAD_POSIX_) + sched_yield(); +#endif + } + } while(!gotLock); +#else + #if defined(_TTHREAD_WIN32_) + EnterCriticalSection(mHandle); + #elif defined(_TTHREAD_POSIX_) + pthread_mutex_lock(mHandle); + #endif +#endif + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return \c true if the lock was acquired, or \c false if the lock could + /// not be acquired. + inline bool try_lock() + { +#if defined(_FAST_MUTEX_ASM_) + int oldLock; + #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + asm volatile ( + "movl $1,%%eax\n\t" + "xchg %%eax,%0\n\t" + "movl %%eax,%1\n\t" + : "=m" (mLock), "=m" (oldLock) + : + : "%eax", "memory" + ); + #elif defined(_MSC_VER) + #if defined(_M_IX86) + int *ptrLock = &mLock; + __asm { + mov eax, 1 + mov ecx, ptrLock + xchg eax, [ecx] + mov oldLock, eax + } + #elif defined(_M_X64) + oldLock = InterlockedExchange(&mLock, 1); + #endif + #elif defined(__GNUC__) && (defined(__ppc__)) + int newLock = 1; + asm volatile ( + "\n1:\n\t" + "lwarx %0,0,%1\n\t" + "cmpwi 0,%0,0\n\t" + "bne- 2f\n\t" + "stwcx. %2,0,%1\n\t" + "bne- 1b\n\t" + "isync\n" + "2:\n\t" + : "=&r" (oldLock) + : "r" (&mLock), "r" (newLock) + : "cr0", "memory" + ); + #endif + return (oldLock == 0); +#else + #if defined(_TTHREAD_WIN32_) + return TryEnterCriticalSection(mHandle) ? true : false; + #elif defined(_TTHREAD_POSIX_) + return (pthread_mutex_trylock(mHandle) == 0) ? true : false; + #endif +#endif + } + + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() + { +#if defined(_FAST_MUTEX_ASM_) + #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + asm volatile ( + "movl $0,%%eax\n\t" + "xchg %%eax,%0\n\t" + : "=m" (mLock) + : + : "%eax", "memory" + ); + #elif defined(_MSC_VER) + #if defined(_M_IX86) + int *ptrLock = &mLock; + __asm { + mov eax,0 + mov ecx,ptrLock + xchg eax,[ecx] + } + #elif defined(_M_X64) + InterlockedExchange(&mLock, 0); + #endif + #elif defined(__GNUC__) && (defined(__ppc__)) + asm volatile ( + "sync\n\t" // Replace with lwsync where possible? + : : : "memory" + ); + mLock = 0; + #endif +#else + #if defined(_TTHREAD_WIN32_) + LeaveCriticalSection(mHandle); + #elif defined(_TTHREAD_POSIX_) + pthread_mutex_unlock(mHandle); + #endif +#endif + } + + private: +#if defined(_FAST_MUTEX_ASM_) +#if defined(_M_X64) && defined (_MSC_VER) + long mLock; +#else + int mLock; +#endif +#else + #if defined(_TTHREAD_WIN32_) + mutable CRITICAL_SECTION * mHandle; + #elif defined(_TTHREAD_POSIX_) + mutable pthread_mutex_t * mHandle; + #endif +#endif +}; + +} + +#endif // _FAST_MUTEX_H_ + diff --git a/filebuf.h b/filebuf.h new file mode 100644 index 0000000..66dffb4 --- /dev/null +++ b/filebuf.h @@ -0,0 +1,718 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef FILEBUF_H_ +#define FILEBUF_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "assert_helpers.h" + +/** + * Simple, fast helper for determining if a character is a newline. + */ +static inline bool isnewline(int c) { + return c == '\r' || c == '\n'; +} + +/** + * Simple, fast helper for determining if a character is a non-newline + * whitespace character. + */ +static inline bool isspace_notnl(int c) { + return isspace(c) && !isnewline(c); +} + +/** + * Simple wrapper for a FILE*, istream or ifstream that reads it in chunks + * using fread and keeps those chunks in a buffer. It also services calls to + * get(), peek() and gets() from the buffer, reading in additional chunks when + * necessary. + * + * Helper functions do things like parse strings, numbers, and FASTA records. + * + * + */ +class FileBuf { +public: + FileBuf() { + init(); + } + + FileBuf(FILE *in) { + init(); + _in = in; + assert(_in != NULL); + } + + FileBuf(std::ifstream *inf) { + init(); + _inf = inf; + assert(_inf != NULL); + } + + FileBuf(std::istream *ins) { + init(); + _ins = ins; + assert(_ins != NULL); + } + + /** + * Return true iff there is a stream ready to read. + */ + bool isOpen() { + return _in != NULL || _inf != NULL || _ins != NULL; + } + + /** + * Close the input stream (if that's possible) + */ + void close() { + if(_in != NULL && _in != stdin) { + fclose(_in); + } else if(_inf != NULL) { + _inf->close(); + } else { + // can't close _ins + } + } + + /** + * Get the next character of input and advance. + */ + int get() { + assert(_in != NULL || _inf != NULL || _ins != NULL); + int c = peek(); + if(c != -1) { + _cur++; + if(_lastn_cur < LASTN_BUF_SZ) _lastn_buf[_lastn_cur++] = c; + } + return c; + } + + /** + * Return true iff all input is exhausted. + */ + bool eof() { + return (_cur == _buf_sz) && _done; + } + + /** + * Initialize the buffer with a new C-style file. + */ + void newFile(FILE *in) { + _in = in; + _inf = NULL; + _ins = NULL; + _cur = BUF_SZ; + _buf_sz = BUF_SZ; + _done = false; + } + + /** + * Initialize the buffer with a new ifstream. + */ + void newFile(std::ifstream *__inf) { + _in = NULL; + _inf = __inf; + _ins = NULL; + _cur = BUF_SZ; + _buf_sz = BUF_SZ; + _done = false; + } + + /** + * Initialize the buffer with a new istream. + */ + void newFile(std::istream *__ins) { + _in = NULL; + _inf = NULL; + _ins = __ins; + _cur = BUF_SZ; + _buf_sz = BUF_SZ; + _done = false; + } + + /** + * Restore state as though we just started reading the input + * stream. + */ + void reset() { + if(_inf != NULL) { + _inf->clear(); + _inf->seekg(0, std::ios::beg); + } else if(_ins != NULL) { + _ins->clear(); + _ins->seekg(0, std::ios::beg); + } else { + rewind(_in); + } + _cur = BUF_SZ; + _buf_sz = BUF_SZ; + _done = false; + } + + /** + * Peek at the next character of the input stream without + * advancing. Typically we can simple read it from the buffer. + * Occasionally we'll need to read in a new buffer's worth of data. + */ + int peek() { + assert(_in != NULL || _inf != NULL || _ins != NULL); + assert_leq(_cur, _buf_sz); + if(_cur == _buf_sz) { + if(_done) { + // We already exhausted the input stream + return -1; + } + // Read a new buffer's worth of data + else { + // Get the next chunk + if(_inf != NULL) { + _inf->read((char*)_buf, BUF_SZ); + _buf_sz = _inf->gcount(); + } else if(_ins != NULL) { + _ins->read((char*)_buf, BUF_SZ); + _buf_sz = _ins->gcount(); + } else { + assert(_in != NULL); + _buf_sz = fread(_buf, 1, BUF_SZ, _in); + } + _cur = 0; + if(_buf_sz == 0) { + // Exhausted, and we have nothing to return to the + // caller + _done = true; + return -1; + } else if(_buf_sz < BUF_SZ) { + // Exhausted + _done = true; + } + } + } + return (int)_buf[_cur]; + } + + /** + * Store a string of characters from the input file into 'buf', + * until we see a newline, EOF, or until 'len' characters have been + * read. + */ + size_t gets(char *buf, size_t len) { + size_t stored = 0; + while(true) { + int c = get(); + if(c == -1) { + // End-of-file + buf[stored] = '\0'; + return stored; + } + if(stored == len-1 || isnewline(c)) { + // End of string + buf[stored] = '\0'; + // Skip over all end-of-line characters + int pc = peek(); + while(isnewline(pc)) { + get(); // discard + pc = peek(); + } + // Next get() will be after all newline characters + return stored; + } + buf[stored++] = (char)c; + } + } + + /** + * Store a string of characters from the input file into 'buf', + * until we see a newline, EOF, or until 'len' characters have been + * read. + */ + size_t get(char *buf, size_t len) { + size_t stored = 0; + for(size_t i = 0; i < len; i++) { + int c = get(); + if(c == -1) return i; + buf[stored++] = (char)c; + } + return len; + } + + static const size_t LASTN_BUF_SZ = 8 * 1024; + + /** + * Keep get()ing characters until a non-whitespace character (or + * -1) is reached, and return it. + */ + int getPastWhitespace() { + int c; + while(isspace(c = get()) && c != -1); + return c; + } + + /** + * Keep get()ing characters until a we've passed over the next + * string of newline characters (\r's and \n's) or -1 is reached, + * and return it. + */ + int getPastNewline() { + int c = get(); + while(!isnewline(c) && c != -1) c = get(); + while(isnewline(c)) c = get(); + assert_neq(c, '\r'); + assert_neq(c, '\n'); + return c; + } + + /** + * Keep get()ing characters until a we've passed over the next + * string of newline characters (\r's and \n's) or -1 is reached, + * and return it. + */ + int peekPastNewline() { + int c = peek(); + while(!isnewline(c) && c != -1) c = get(); + while(isnewline(c)) c = get(); + assert_neq(c, '\r'); + assert_neq(c, '\n'); + return c; + } + + /** + * Keep peek()ing then get()ing characters until the next return + * from peek() is just after the last newline of the line. + */ + int peekUptoNewline() { + int c = peek(); + while(!isnewline(c) && c != -1) { + get(); c = peek(); + } + while(isnewline(c)) { + get(); + c = peek(); + } + assert_neq(c, '\r'); + assert_neq(c, '\n'); + return c; + } + + /** + * Parse a FASTA record. Append name characters to 'name' and and append + * all sequence characters to 'seq'. If gotCaret is true, assuming the + * file cursor has already moved just past the starting '>' character. + */ + template + void parseFastaRecord( + TNameStr& name, + TSeqStr& seq, + bool gotCaret = false) + { + int c; + if(!gotCaret) { + // Skip over caret and non-newline whitespace + c = peek(); + while(isspace_notnl(c) || c == '>') { get(); c = peek(); } + } else { + // Skip over non-newline whitespace + c = peek(); + while(isspace_notnl(c)) { get(); c = peek(); } + } + size_t namecur = 0, seqcur = 0; + // c is the first character of the fasta name record, or is the first + // newline character if the name record is empty + while(!isnewline(c) && c != -1) { + name[namecur++] = c; get(); c = peek(); + } + // sequence consists of all the non-whitespace characters between here + // and the next caret + while(true) { + // skip over whitespace + while(isspace(c)) { get(); c = peek(); } + // if we see caret or EOF, break + if(c == '>' || c == -1) break; + // append and continue + seq[seqcur++] = c; + get(); c = peek(); + } + } + + /** + * Parse a FASTA record and return its length. If gotCaret is true, + * assuming the file cursor has already moved just past the starting '>' + * character. + */ + void parseFastaRecordLength( + size_t& nameLen, + size_t& seqLen, + bool gotCaret = false) + { + int c; + nameLen = seqLen = 0; + if(!gotCaret) { + // Skip over caret and non-newline whitespace + c = peek(); + while(isspace_notnl(c) || c == '>') { get(); c = peek(); } + } else { + // Skip over non-newline whitespace + c = peek(); + while(isspace_notnl(c)) { get(); c = peek(); } + } + // c is the first character of the fasta name record, or is the first + // newline character if the name record is empty + while(!isnewline(c) && c != -1) { + nameLen++; get(); c = peek(); + } + // sequence consists of all the non-whitespace characters between here + // and the next caret + while(true) { + // skip over whitespace + while(isspace(c)) { get(); c = peek(); } + // if we see caret or EOF, break + if(c == '>' || c == -1) break; + // append and continue + seqLen++; + get(); c = peek(); + } + } + + /** + * Reset to the beginning of the last-N-chars buffer. + */ + void resetLastN() { + _lastn_cur = 0; + } + + /** + * Copy the last several characters in the last-N-chars buffer + * (since the last reset) into the provided buffer. + */ + size_t copyLastN(char *buf) { + memcpy(buf, _lastn_buf, _lastn_cur); + return _lastn_cur; + } + + /** + * Get const pointer to the last-N-chars buffer. + */ + const char *lastN() const { + return _lastn_buf; + } + + /** + * Get current size of the last-N-chars buffer. + */ + size_t lastNLen() const { + return _lastn_cur; + } + +private: + + void init() { + _in = NULL; + _inf = NULL; + _ins = NULL; + _cur = _buf_sz = BUF_SZ; + _done = false; + _lastn_cur = 0; + // no need to clear _buf[] + } + + static const size_t BUF_SZ = 256 * 1024; + FILE *_in; + std::ifstream *_inf; + std::istream *_ins; + size_t _cur; + size_t _buf_sz; + bool _done; + uint8_t _buf[BUF_SZ]; // (large) input buffer + size_t _lastn_cur; + char _lastn_buf[LASTN_BUF_SZ]; // buffer of the last N chars dispensed +}; + +/** + * Wrapper for a buffered output stream that writes bitpairs. + */ +class BitpairOutFileBuf { +public: + /** + * Open a new output stream to a file with given name. + */ + BitpairOutFileBuf(const char *in) : bpPtr_(0), cur_(0) { + assert(in != NULL); + out_ = fopen(in, "wb"); + if(out_ == NULL) { + std::cerr << "Error: Could not open bitpair-output file " << in << std::endl; + throw 1; + } + memset(buf_, 0, BUF_SZ); + } + + /** + * Write a single bitpair into the buf. Flush the buffer if it's + * full. + */ + void write(int bp) { + assert_lt(bp, 4); + assert_geq(bp, 0); + buf_[cur_] |= (bp << bpPtr_); + if(bpPtr_ == 6) { + bpPtr_ = 0; + cur_++; + if(cur_ == BUF_SZ) { + // Flush the buffer + if(!fwrite((const void *)buf_, BUF_SZ, 1, out_)) { + std::cerr << "Error writing to the reference index file (.4.ebwt)" << std::endl; + throw 1; + } + // Reset to beginning of the buffer + cur_ = 0; + } + // Initialize next octet to 0 + buf_[cur_] = 0; + } else { + bpPtr_ += 2; + } + } + + /** + * Write any remaining bitpairs and then close the input + */ + void close() { + if(cur_ > 0 || bpPtr_ > 0) { + if(bpPtr_ == 0) cur_--; + if(!fwrite((const void *)buf_, cur_ + 1, 1, out_)) { + std::cerr << "Error writing to the reference index file (.4.ebwt)" << std::endl; + throw 1; + } + } + fclose(out_); + } +private: + static const size_t BUF_SZ = 128 * 1024; + FILE *out_; + int bpPtr_; + size_t cur_; + char buf_[BUF_SZ]; // (large) input buffer +}; + +/** + * Wrapper for a buffered output stream that writes characters and + * other data types. This class is *not* synchronized; the caller is + * responsible for synchronization. + */ +class OutFileBuf { + +public: + + /** + * Open a new output stream to a file with given name. + */ + OutFileBuf(const std::string& out, bool binary = false) : + name_(out.c_str()), cur_(0), closed_(false) + { + out_ = fopen(out.c_str(), binary ? "wb" : "w"); + if(out_ == NULL) { + std::cerr << "Error: Could not open alignment output file " << out.c_str() << std::endl; + throw 1; + } + if(setvbuf(out_, NULL, _IOFBF, 10* 1024* 1024)) + std::cerr << "Warning: Could not allocate the proper buffer size for output file stream. " << std::endl; + } + + /** + * Open a new output stream to a file with given name. + */ + OutFileBuf(const char *out, bool binary = false) : + name_(out), cur_(0), closed_(false) + { + assert(out != NULL); + out_ = fopen(out, binary ? "wb" : "w"); + if(out_ == NULL) { + std::cerr << "Error: Could not open alignment output file " << out << std::endl; + throw 1; + } + } + + /** + * Open a new output stream to standard out. + */ + OutFileBuf() : name_("cout"), cur_(0), closed_(false) { + out_ = stdout; + } + + /** + * Close buffer when object is destroyed. + */ + ~OutFileBuf() { close(); } + + /** + * Open a new output stream to a file with given name. + */ + void setFile(const char *out, bool binary = false) { + assert(out != NULL); + out_ = fopen(out, binary ? "wb" : "w"); + if(out_ == NULL) { + std::cerr << "Error: Could not open alignment output file " << out << std::endl; + throw 1; + } + reset(); + } + + /** + * Write a single character into the write buffer and, if + * necessary, flush. + */ + void write(char c) { + assert(!closed_); + if(cur_ == BUF_SZ) flush(); + buf_[cur_++] = c; + } + + /** + * Write a c++ string to the write buffer and, if necessary, flush. + */ + void writeString(const std::string& s) { + assert(!closed_); + size_t slen = s.length(); + if(cur_ + slen > BUF_SZ) { + if(cur_ > 0) flush(); + if(slen >= BUF_SZ) { + fwrite(s.c_str(), slen, 1, out_); + } else { + memcpy(&buf_[cur_], s.data(), slen); + assert_eq(0, cur_); + cur_ = slen; + } + } else { + memcpy(&buf_[cur_], s.data(), slen); + cur_ += slen; + } + assert_leq(cur_, BUF_SZ); + } + + /** + * Write a c++ string to the write buffer and, if necessary, flush. + */ + template + void writeString(const T& s) { + assert(!closed_); + size_t slen = s.length(); + if(cur_ + slen > BUF_SZ) { + if(cur_ > 0) flush(); + if(slen >= BUF_SZ) { + fwrite(s.toZBuf(), slen, 1, out_); + } else { + memcpy(&buf_[cur_], s.toZBuf(), slen); + assert_eq(0, cur_); + cur_ = slen; + } + } else { + memcpy(&buf_[cur_], s.toZBuf(), slen); + cur_ += slen; + } + assert_leq(cur_, BUF_SZ); + } + + /** + * Write a c++ string to the write buffer and, if necessary, flush. + */ + void writeChars(const char * s, size_t len) { + assert(!closed_); + if(cur_ + len > BUF_SZ) { + if(cur_ > 0) flush(); + if(len >= BUF_SZ) { + fwrite(s, len, 1, out_); + } else { + memcpy(&buf_[cur_], s, len); + assert_eq(0, cur_); + cur_ = len; + } + } else { + memcpy(&buf_[cur_], s, len); + cur_ += len; + } + assert_leq(cur_, BUF_SZ); + } + + /** + * Write a 0-terminated C string to the output stream. + */ + void writeChars(const char * s) { + writeChars(s, strlen(s)); + } + + /** + * Write any remaining bitpairs and then close the input + */ + void close() { + if(closed_) return; + if(cur_ > 0) flush(); + closed_ = true; + if(out_ != stdout) { + fclose(out_); + } + } + + /** + * Reset so that the next write is as though it's the first. + */ + void reset() { + cur_ = 0; + closed_ = false; + } + + void flush() { + if(!fwrite((const void *)buf_, cur_, 1, out_)) { + std::cerr << "Error while flushing and closing output" << std::endl; + throw 1; + } + cur_ = 0; + } + + /** + * Return true iff this stream is closed. + */ + bool closed() const { + return closed_; + } + + /** + * Return the filename. + */ + const char *name() { + return name_; + } + +private: + + static const size_t BUF_SZ = 16 * 1024; + + const char *name_; + FILE *out_; + size_t cur_; + char buf_[BUF_SZ]; // (large) input buffer + bool closed_; +}; + +#endif /*ndef FILEBUF_H_*/ diff --git a/formats.h b/formats.h new file mode 100644 index 0000000..05ee679 --- /dev/null +++ b/formats.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef FORMATS_H_ +#define FORMATS_H_ + +#include + +/** + * File-format constants and names + */ + +enum file_format { + FASTA = 1, + FASTA_CONT, + FASTQ, + TAB_MATE5, + TAB_MATE6, + RAW, + CMDLINE, + QSEQ, + SRA_FASTA, + SRA_FASTQ +}; + +static const std::string file_format_names[] = { + "Invalid!", + "FASTA", + "FASTA sampling", + "FASTQ", + "Tabbed mated", + "Raw", + "Command line", + "Chain file", + "Random", + "Qseq", + "SRA_FASTA", + "SRA_FASTQ" +}; + +#endif /*FORMATS_H_*/ diff --git a/gbwt_graph.h b/gbwt_graph.h new file mode 100644 index 0000000..0ab86f0 --- /dev/null +++ b/gbwt_graph.h @@ -0,0 +1,2797 @@ +/* + * Copyright 2015, Daehwan Kim , Joe Paggi + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef GBWT_GRAPH_H_ +#define GBWT_GRAPH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "alt.h" +#include "radix_sort.h" + +// Reference: +// Jouni Sirén, Niko Välimäki, and Veli Mäkinen: Indexing Graphs for Path Queries with Applications in Genome Research. +// IEEE/ACM Transactions on Computational Biology and Bioinformatics 11(2):375-388, 2014. +// http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6698337 + +//-------------------------------------------------------------------------- + +struct NongraphException : public exception +{ + const char* what () const throw () + { + return "Nongraph exception"; + } +}; + +struct ExplosionException : public exception +{ + const char* what () const throw () + { + return "Explosion exception"; + } +}; + +template class PathGraph; + +// Note: I wrote the following codes based on Siren's work, gcsa (see the reference above). +template +class RefGraph { + friend class PathGraph; +public: + struct Node { + char label; // ACGT + Y(head) + Z(tail) + index_t value; // location in a whole genome + + Node() { reset(); } + Node(char label_, index_t value_) : label(label_), value(value_) {} + void reset() { label = 0; value = 0; } + + bool write(ofstream& f_out, bool bigEndian) const { + writeIndex(f_out, value, bigEndian); + writeU16(f_out, label, bigEndian); + return true; + } + + bool read(ifstream& f_in, bool bigEndian) { + value = readIndex(f_in, bigEndian); + label = (char)readU16(f_in, bigEndian); + return true; + } + + bool operator== (const Node& o) const { + if(value != o.value) return false; + if(label != o.label) return false; + return true; + } + + bool operator< (const Node& o) const { + if(value != o.value) return value < o.value; + return label < o.label; + } + }; + + struct Edge { + index_t from; // from Node + index_t to; // to Node + + Edge() {} + Edge(index_t from_, index_t to_) : from(from_), to(to_) {} + + bool write(ofstream& f_out, bool bigEndian) const { + writeIndex(f_out, from, bigEndian); + writeIndex(f_out, to, bigEndian); + return true; + } + + bool read(ifstream& f_in, bool bigEndian) { + from = readIndex(f_in, bigEndian); + to = readIndex(f_in, bigEndian); + return true; + } + + bool operator< (const Edge& o) const { + if(from != o.from) return from < o.from; + return to < o.to; + } + }; + + static index_t EdgeTo (Edge& a) { + return a.to; + } + + struct EdgeFromCmp { + bool operator() (const Edge& a, const Edge& b) const { + return a.from < b.from; + } + }; + + struct EdgeToCmp { + bool operator() (const Edge& a, const Edge& b) const { + return a.to < b.to; + }; + }; + +public: + RefGraph(const SString& s, + const EList& szs, + const EList >& alts, + const EList >& haplotypes, + const string& out_fname, + int nthreads_, + bool verbose); + + bool repOk() { return true; } + + void write(const string& fname, bool bigEndian) { + ofstream rg_file(fname.c_str(), ios::binary); + if(!rg_file.good()) { + cerr << "Could not open file for writing a reference graph: \"" << fname << "\"" << endl; + throw 1; + } + writeIndex(rg_file, (index_t)nodes.size(), bigEndian); + for(index_t i = 0; i < nodes.size(); i++) { + nodes[i].write(rg_file, bigEndian); + } + writeIndex(rg_file, (index_t)edges.size(), bigEndian); + for(index_t i = 0; i < edges.size(); i++) { + edges[i].write(rg_file, bigEndian); + } + rg_file.close(); + } + + void nullify() { + nodes.nullify(); + edges.nullify(); + } + + void read(const string& fname, bool bigEndian) { + ifstream rg_file(fname.c_str(), ios::binary); + if(!rg_file.good()) { + cerr << "Could not open file for reading a reference graph: \"" << fname << "\"" << endl; + throw 1; + } + index_t num_nodes = readIndex(rg_file, bigEndian); + nodes.resizeNoCopyExact(num_nodes); + for(index_t i = 0; i < num_nodes; i++) { + nodes[i].read(rg_file, bigEndian); + } + index_t num_edges = readIndex(rg_file, bigEndian); + edges.resizeNoCopyExact(num_edges); + for(index_t i = 0; i < num_edges; i++) { + edges[i].read(rg_file, bigEndian); + } + rg_file.close(); + } + +private: + static bool isReverseDeterministic(EList& nodes, EList& edges); + static void reverseDeterminize(EList& nodes, EList& edges, index_t& lastNode, index_t lastNode_add = 0); + + static void sortEdgesFrom(EList& edges) { + std::sort(edges.begin(), edges.end(), EdgeFromCmp()); + } + static void sortEdgesTo(EList& edges) { + std::sort(edges.begin(), edges.end(), EdgeToCmp()); + } + + // Return edge ranges [begin, end) + static pair findEdges(const EList& edges, index_t node, bool from); + static pair findEdgesFrom(const EList& edges, index_t node) { + return findEdges(edges, node, true); + } + static pair findEdgesTo(const EList& edges, index_t node) { + return findEdges(edges, node, false); + } + static pair getNextEdgeRange(const EList& sep_edges, pair range, bool from) { + if(range.second >= sep_edges.size()) { + return pair(0, 0); + } + range.first = range.second; range.second++; + + if(from) { + while(range.second < sep_edges.size() && sep_edges[range.second].from == sep_edges[range.first].from) { + range.second++; + } + } else { + while(range.second < sep_edges.size() && sep_edges[range.second].to == sep_edges[range.first].to) { + range.second++; + } + } + return range; + } + +private: + struct ThreadParam { + // input + index_t thread_id; + RefGraph* refGraph; + const SString* s; + const EList >* alts; + const EList >* haplotypes; + string out_fname; + bool bigEndian; + + // output + index_t num_nodes; + index_t num_edges; + index_t lastNode; + bool multipleHeadNodes; + }; + static void buildGraph_worker(void* vp); + +private: + EList szs; + EList tmp_szs; + + EList nodes; + EList edges; + index_t lastNode; // Z + + int nthreads; + +#ifndef NDEBUG + bool debug; +#endif + +private: + // Following composite nodes and edges are used to reverse-determinize an automaton. + struct CompositeNodeIDs { + index_t id; + EList add_ids; + + CompositeNodeIDs() { + id = (index_t)INDEX_MAX; + } + + bool operator<(const CompositeNodeIDs& o) const { + if(id != o.id) return id < o.id; + if(add_ids.size() != o.add_ids.size()) return add_ids.size() < o.add_ids.size(); + for(index_t i = 0; i < add_ids.size(); i++) { + assert_lt(i, o.add_ids.size()); + if(add_ids[i] != o.add_ids[i]) return add_ids[i] < o.add_ids[i]; + } + return false; + } + + index_t size() const { + if(id == (index_t)INDEX_MAX) return 0; + return (index_t)add_ids.size() + 1; + } + index_t getID(index_t i) const { + if(i == 0) return id; + else { + i -= 1; + assert_lt(i, add_ids.size()); + return add_ids[i]; + } + } + void push_back(index_t node_id) { + if(id == (index_t)INDEX_MAX) id = node_id; + else add_ids.push_back(node_id); + } + }; + + struct CompositeNode { + CompositeNodeIDs nodes; + index_t id; + char label; + index_t value; + + CompositeNode() { reset(); } + + CompositeNode(char label_, index_t node_id) : + id(0), label(label_) + { + nodes.push_back(node_id); + } + + Node getNode() const { + return Node(label, value); + } + + void reset() { + nodes.id = (index_t)INDEX_MAX; + nodes.add_ids.clear(); + id = 0; + label = 0; + value = 0; + } + }; + + struct CompositeEdge { + index_t from; + index_t to; + + CompositeEdge() : from(0), to(0) {} + CompositeEdge(index_t from_, index_t to_) : from(from_), to(to_) {} + + Edge getEdge(const EList& nodes) const + { + assert_lt(from, nodes.size()); + const CompositeNode& from_node = nodes[from]; + assert_lt(to, nodes.size()); + const CompositeNode& to_node = nodes[to]; + return Edge(from_node.id, to_node.id); + } + + bool operator < (const CompositeEdge& o) const + { + return from < o.from; + } + }; + + struct TempNodeLabelCmp { + TempNodeLabelCmp(const EList& nodes_) : nodes(nodes_) {} + bool operator() (index_t a, index_t b) const { + assert_lt(a, nodes.size()); + assert_lt(b, nodes.size()); + return nodes[a].label < nodes[b].label; + } + + const EList& nodes; + }; +}; + +/** + * Load reference sequence file and alt information. + * Construct a reference graph + */ +template +RefGraph::RefGraph(const SString& s, + const EList& szs, + const EList >& alts, + const EList >& haplotypes, + const string& out_fname, + int nthreads_, + bool verbose) +: lastNode(0), nthreads(nthreads_) +{ + const bool bigEndian = false; + + assert_gt(nthreads, 0); + assert_gt(szs.size(), 0); + index_t jlen = (index_t)s.length(); + +#ifndef NDEBUG + debug = (jlen <= 20); +#endif + + // a memory-efficient way to create a population graph with known ALTs + bool frag_automaton = jlen >= (1 << 16); + if(frag_automaton) { + { + EList > alt_ranges; // each range inclusive + for(index_t i = 0; i < alts.size(); i++) { + const ALT& alt = alts[i]; + index_t left_relax = 128, right_relax = 128; + pair range; + range.first = alt.pos > left_relax ? alt.pos - left_relax - 1 : 0; + if(alt.type == ALT_SNP_SGL) { + range.second = alt.pos + 1; + } else if(alt.type == ALT_SNP_DEL) { + assert_gt(alt.len, 0); + range.second = alt.pos + alt.len; + } else if(alt.type == ALT_SNP_INS) { + assert_gt(alt.len, 0); + range.second = alt.pos; + } else if (alt.type == ALT_SPLICESITE) { + assert_lt(alt.left, alt.right); + range.second = alt.right + 1; + } else { + assert(alt.exon()); + continue; + } + range.second += right_relax; + + if(alt_ranges.empty() || alt_ranges.back().second + 1 < range.first) { + alt_ranges.push_back(range); + } else { + assert_leq(alt_ranges.back().first, range.first); + if(alt_ranges.back().second < range.second) { + alt_ranges.back().second = range.second; + } + } + } + + index_t chunk_size = 1 << 20; + index_t pos = 0, range_idx = 0; + for(index_t i = 0; i < szs.size(); i++) { + if(szs[i].len == 0) continue; + if(szs[i].len <= chunk_size) { + tmp_szs.push_back(szs[i]); + pos += szs[i].len; + } else { + index_t num_chunks = (szs[i].len + chunk_size - 1) / chunk_size; + assert_gt(num_chunks, 1); + index_t modified_chunk_size = szs[i].len / num_chunks; + index_t after_pos = pos + szs[i].len; + ASSERT_ONLY(index_t sum_len = 0); + while(pos < after_pos) { + index_t target_pos = pos + modified_chunk_size; + if(target_pos < after_pos) { + for(; range_idx < alt_ranges.size(); range_idx++) { + if(target_pos < alt_ranges[range_idx].first) break; + } + pair alt_free_range; + if(range_idx == 0) { + alt_free_range.first = 0; + } else { + alt_free_range.first = alt_ranges[range_idx - 1].second + 1; + if(alt_free_range.first >= jlen) { + alt_free_range.first = jlen - 1; + } + } + + if(range_idx == alt_ranges.size()) { + alt_free_range.second = jlen - 1; + } else { + alt_free_range.second = alt_ranges[range_idx].first - 1; + } + + assert_leq(alt_free_range.first, alt_free_range.second); + if(target_pos < alt_free_range.first) target_pos = alt_free_range.first; + if(target_pos > after_pos) target_pos = after_pos; + } else { + target_pos = after_pos; + } + + tmp_szs.expand(); + tmp_szs.back().len = target_pos - pos; + tmp_szs.back().off = 0; + pos = target_pos; + ASSERT_ONLY(sum_len += tmp_szs.back().len); + } + assert_eq(pos, after_pos); + assert_eq(sum_len, szs[i].len); + } + } +#ifndef NDEBUG + index_t modified_jlen = 0; + for(index_t i = 0; i < tmp_szs.size(); i++) { + modified_jlen += tmp_szs[i].len; + } + assert_eq(modified_jlen, jlen); +#endif + } + + if(nthreads > (int)tmp_szs.size()) { + nthreads = (int)tmp_szs.size(); + } + assert_gt(nthreads, 0); + AutoArray threads(nthreads); + EList threadParams; + for(index_t i = 0; i < (index_t)nthreads; i++) { + threadParams.expand(); + threadParams.back().thread_id = i; + threadParams.back().refGraph = this; + threadParams.back().s = &s; + threadParams.back().alts = &alts; + threadParams.back().haplotypes = &haplotypes; + threadParams.back().out_fname = out_fname; + threadParams.back().bigEndian = bigEndian; + threadParams.back().num_nodes = 0; + threadParams.back().num_edges = 0; + threadParams.back().lastNode = 0; + threadParams.back().multipleHeadNodes = false; + if(nthreads == 1) { + buildGraph_worker((void*)&threadParams.back()); + } else { + threads[i] = new tthread::thread(buildGraph_worker, (void*)&threadParams.back()); + } + } + + if(nthreads > 1) { + for(index_t i = 0; i < (index_t)nthreads; i++) + threads[i]->join(); + } + + index_t num_nodes = 0, num_edges = 0; + for(index_t i = 0; i < threadParams.size(); i++) { + num_nodes += threadParams[i].num_nodes; + num_edges += threadParams[i].num_edges; + // Make room for edges spanning graphs by different threads + if(i > 0) { + num_edges += 16; + } + } + nodes.resizeExact(num_nodes); nodes.clear(); + edges.resizeExact(num_edges); edges.clear(); + + // Read all the nodes and edges + EList tail_nodes; + bool multipleHeadNodes = false; + for(index_t i = 0; i < threadParams.size(); i++) { + if(threadParams[i].multipleHeadNodes) multipleHeadNodes = true; + std::ostringstream number; number << i; + const string rg_fname = out_fname + "." + number.str() + ".rf"; + ifstream rg_in_file(rg_fname.c_str(), ios::binary); + if(!rg_in_file.good()) { + cerr << "Could not open file for reading a reference graph: \"" << rg_fname << "\"" << endl; + throw 1; + } + index_t curr_num_nodes = (index_t)nodes.size(); + ASSERT_ONLY(index_t curr_num_edges = (index_t)edges.size()); + ASSERT_ONLY(index_t num_spanning_edges = 0); + // Read nodes to be connected to last nodes in a previous thread + if(i > 0) { + assert_gt(tail_nodes.size(), 0) + index_t num_head_nodes = readIndex(rg_in_file, bigEndian); + for(index_t j = 0; j < num_head_nodes; j++) { + index_t head_node = readIndex(rg_in_file, bigEndian); + for(index_t k = 0; k < tail_nodes.size(); k++) { + edges.expand(); + edges.back().from = tail_nodes[k]; + edges.back().to = head_node + curr_num_nodes; + ASSERT_ONLY(num_spanning_edges++); + } + } + } + while(!rg_in_file.eof()) { + index_t tmp_num_nodes = readIndex(rg_in_file, bigEndian); + for(index_t j = 0; j < tmp_num_nodes; j++) { + nodes.expand(); + nodes.back().read(rg_in_file, bigEndian); + } + index_t tmp_num_edges = readIndex(rg_in_file, bigEndian); + for(index_t j = 0; j < tmp_num_edges; j++) { + edges.expand(); + edges.back().read(rg_in_file, bigEndian); + edges.back().from += curr_num_nodes; + edges.back().to += curr_num_nodes; + } + + if(nodes.size() >= curr_num_nodes + threadParams[i].num_nodes) { + assert_eq(nodes.size(), curr_num_nodes + threadParams[i].num_nodes); + assert_eq(edges.size(), curr_num_edges + num_spanning_edges + threadParams[i].num_edges); + // Read last nodes in this thread + tail_nodes.clear(); + if(i + 1 < (index_t)nthreads) { + index_t num_tail_nodes = readIndex(rg_in_file, bigEndian); + for(index_t j = 0; j < num_tail_nodes; j++) { + index_t tail_node = readIndex(rg_in_file, bigEndian); + tail_nodes.push_back(tail_node + curr_num_nodes); + } + } + break; + } + } + rg_in_file.close(); + std::remove(rg_fname.c_str()); + if(i + 1 == (index_t)nthreads) { + lastNode = threadParams.back().lastNode + curr_num_nodes; + assert_lt(lastNode, nodes.size()); + assert_eq(nodes[lastNode].label, 'Z'); + } + } + + if(s.length() + 2 == nodes.size() && nodes.size() == edges.size() + 1) { + cerr << "Warning: no variants or splice sites in this graph" << endl; + throw NongraphException(); + } + + if(multipleHeadNodes) { + if(!isReverseDeterministic(nodes, edges)) { + if(verbose) cerr << "\tis not reverse-deterministic, so reverse-determinize..." << endl; + reverseDeterminize(nodes, edges, lastNode); + } + } + assert(isReverseDeterministic(nodes, edges)); + } else { // this is memory-consuming, but simple to implement + index_t num_predicted_nodes = (index_t)(jlen * 1.2); + nodes.reserveExact(num_predicted_nodes); + edges.reserveExact(num_predicted_nodes); + + // Created head node + nodes.expand(); + nodes.back().label = 'Y'; + nodes.back().value = 0; + // Create nodes and edges corresponding to a reference genome + for(size_t i = 0; i < s.length(); i++) { + nodes.expand(); + nodes.back().label = "ACGT"[(int)s[i]]; + nodes.back().value = (index_t)i; + + assert_geq(nodes.size(), 2); + edges.expand(); + edges.back().from = (index_t)nodes.size() - 2; + edges.back().to = (index_t)nodes.size() - 1; + } + + // Create tail node + nodes.expand(); + nodes.back().label = 'Z'; + nodes.back().value = (index_t)s.length(); + lastNode = (index_t)nodes.size() - 1; + edges.expand(); + edges.back().from = (index_t)nodes.size() - 2; + edges.back().to = (index_t)nodes.size() - 1; + + // Create nodes and edges for haplotypes + for(index_t i = 0; i < haplotypes.size(); i++) { + const Haplotype& haplotype = haplotypes[i]; + const EList& snpIDs = haplotype.alts; + assert_gt(snpIDs.size(), 0); + assert_lt(haplotype.right, s.length()); + bool pass = true; + for(index_t s = 0; s < snpIDs.size(); s++) { + index_t snpID = snpIDs[s]; + assert_lt(snpID, alts.size()); + const ALT& snp = alts[snpID]; + assert(snp.snp()); + if(s + 1 >= snpIDs.size()) break; + index_t snpID2 = snpIDs[s+1]; + assert_lt(snpID2, alts.size()); + const ALT& snp2 = alts[snpID2]; + assert(snp2.snp()); + if(snp.type == ALT_SNP_INS) { + if(snp.pos > snp2.pos) { + pass = false; + break; + } + } else if(snp.type == ALT_SNP_DEL) { + if(snp2.type == ALT_SNP_DEL) { + if(snp.pos + snp.len >= snp2.pos) { + pass = false; + break; + } + } else { + if(snp.pos + snp.len - 1 >= snp2.pos) { + pass = false; + break; + } + } + } else { + if(snp.pos >= snp2.pos) { + pass = false; + break; + } + } + } + + if(!pass) continue; + + index_t prev_ALT_type = ALT_NONE; + index_t ID_i = 0; + for(index_t j = haplotype.left; j <= haplotype.right; j++) { + if(prev_ALT_type == ALT_SNP_INS) j--; + const ALT* altp = (ID_i < snpIDs.size() ? &(alts[snpIDs[ID_i]]) : NULL); + assert(altp == NULL || altp->pos >= j); + if(altp != NULL && altp->pos == j) { + const ALT& alt = *altp; + assert_lt(alt.pos, s.length()); + assert(alt.snp()); + if(alt.type == ALT_SNP_SGL) { + assert_eq(alt.len, 1); + nodes.expand(); + assert_lt(alt.seq, 4); + assert_neq(alt.seq & 0x3, s[alt.pos]); + nodes.back().label = "ACGT"[alt.seq]; + nodes.back().value = alt.pos; + if(prev_ALT_type != ALT_SNP_DEL) { + edges.expand(); + if(j == haplotype.left) { + edges.back().from = alt.pos; + } else { + assert_gt(nodes.size(), 2); + edges.back().from = (index_t)nodes.size() - 2; + } + edges.back().to = (index_t)nodes.size() - 1; + } + if(j == haplotype.right) { + edges.expand(); + edges.back().from = (index_t)nodes.size() - 1; + edges.back().to = alt.pos + 2; + } + } + else if(alt.type == ALT_SNP_DEL) { + assert_gt(alt.len, 0); + assert_leq(alt.pos + alt.len, s.length()); + edges.expand(); + if(j == haplotype.left) { + edges.back().from = alt.pos; + } else { + edges.back().from = (index_t)nodes.size() - 1; + } + j += (alt.len - 1); + assert_leq(j, haplotype.right); + if(j == haplotype.right) { + edges.back().to = alt.pos + alt.len + 1; + } else { + edges.back().to = (index_t)nodes.size(); + } + } else { + assert_eq(alt.type, ALT_SNP_INS) + assert_gt(alt.len, 0); + for(size_t k = 0; k < alt.len; k++) { + uint64_t bp = alt.seq >> ((alt.len - k - 1) << 1); + bp &= 0x3; + char ch = "ACGT"[bp]; + nodes.expand(); + nodes.back().label = ch; + nodes.back().value = (index_t)INDEX_MAX; + if(prev_ALT_type == ALT_SNP_DEL && k == 0) continue; + edges.expand(); + edges.back().from = ((k == 0 && j == haplotype.left) ? alt.pos : (index_t)nodes.size() - 2); + edges.back().to = (index_t)nodes.size() - 1; + } + if(j == haplotype.right) { + edges.expand(); + edges.back().from = (index_t)nodes.size() - 1; + edges.back().to = alt.pos + 1; + } + } + ID_i++; + prev_ALT_type = alt.type; + } else { + int nt = s[j]; + assert_lt(nt, 4); + nodes.expand(); + nodes.back().label = "ACGT"[nt]; + nodes.back().value = j; + if(prev_ALT_type != ALT_SNP_DEL) { + edges.expand(); + if(j == haplotype.left && prev_ALT_type == ALT_NONE) { + edges.back().from = j; + } else { + edges.back().from = (index_t)nodes.size() - 2; + } + edges.back().to = (index_t)nodes.size() - 1; + } + if(j == haplotype.right) { + edges.expand(); + edges.back().from = (index_t)nodes.size() - 1; + edges.back().to = j + 2; + } + prev_ALT_type = ALT_SNP_SGL; + } + } + } + + // Create nodes and edges for splice sites + for(size_t i = 0; i < alts.size(); i++) { + const ALT& alt = alts[i]; + if(alt.pos >= s.length()) break; + if(alt.type != ALT_SPLICESITE) continue; + if(alt.excluded) continue; + assert_lt(alt.left, alt.right); + edges.expand(); + edges.back().from = alt.left; + edges.back().to = alt.right + 2; + } + + if(s.length() + 2 == nodes.size() && nodes.size() == edges.size() + 1) { + throw NongraphException(); + } + + if(!isReverseDeterministic(nodes, edges)) { + if(verbose) cerr << "\tis not reverse-deterministic, so reverse-determinize..." << endl; + reverseDeterminize(nodes, edges, lastNode); + assert(isReverseDeterministic(nodes, edges)); + } + } + +#ifndef NDEBUG + if(debug) { + cout << "num nodes: " << nodes.size() << endl; + for(index_t i = 0; i < nodes.size(); i++) { + const Node& n = nodes[i]; + cout << i << "\t" << n.label << "\t" << n.value << endl; + } + + sort(edges.begin(), edges.end()); + cout << "num edges: " << edges.size() << endl; + for(index_t i = 0; i < edges.size(); i++) { + const Edge& e = edges[i]; + cout << i << "\t" << e.from << " --> " << e.to << endl; + } + } +#endif +} + +template +pair RefGraph::findEdges(const EList& edges, index_t node, bool from) { + pair range(0, 0); + assert_gt(edges.size(), 0); + + // Find lower bound + index_t low = 0, high = (index_t)edges.size() - 1; + index_t temp; + while(low < high) { + index_t mid = low + (high - low) / 2; + temp = (from ? edges[mid].from : edges[mid].to); + if(node == temp) { + high = mid; + } else if(node < temp) { + if(mid == 0) { + return pair(0, 0); + } + + high = mid - 1; + } else { + low = mid + 1; + } + } + temp = (from ? edges[low].from : edges[low].to); + if(node == temp) { + range.first = low; + } else { + return range; + } + + // Find upper bound + high = (index_t)edges.size() - 1; + while(low < high) + { + index_t mid = low + (high - low + 1) / 2; + temp = (from ? edges[mid].from : edges[mid].to); + if(node == temp) { + low = mid; + } else { + assert_lt(node, temp); + high = mid - 1; + } + } +#ifndef NDEBUG + temp = (from ? edges[high].from : edges[high].to); + assert_eq(node, temp); +#endif + range.second = high + 1; + return range; +} + +template +void RefGraph::buildGraph_worker(void* vp) { + ThreadParam* threadParam = (ThreadParam*)vp; + RefGraph& refGraph = *(threadParam->refGraph); + + const SString& s = *(threadParam->s); + index_t jlen = (index_t)s.length(); + + const EList >& alts = *(threadParam->alts); + const EList >& haplotypes = *(threadParam->haplotypes); + + EList nodes; EList edges; + const EList& tmp_szs = refGraph.tmp_szs; + + index_t thread_id = threadParam->thread_id; + index_t nthreads = refGraph.nthreads; + std::ostringstream number; number << thread_id; + const string rg_fname = threadParam->out_fname + "." + number.str() + ".rf"; + ofstream rg_out_file(rg_fname.c_str(), ios::binary); + if(!rg_out_file.good()) { + cerr << "Could not open file for writing a reference graph: \"" << rg_fname << "\"" << endl; + throw 1; + } + +#ifndef NDEBUG + set snp_set; +#endif + + const bool bigEndian = threadParam->bigEndian; + + index_t& lastNode = threadParam->lastNode; + + index_t& num_nodes = threadParam->num_nodes; + index_t& num_edges = threadParam->num_edges; + index_t szs_idx = 0, szs_idx_end = (index_t)tmp_szs.size(); + if(threadParam->thread_id != 0) { + szs_idx = (index_t)((tmp_szs.size() / nthreads) * thread_id); + } + if(thread_id + 1 < nthreads) { + szs_idx_end = (index_t)((tmp_szs.size() / nthreads) * (thread_id + 1)); + } + + index_t curr_pos = 0; + for(index_t i = 0; i < szs_idx; i++) { + curr_pos += tmp_szs[i].len; + } + EList prev_tail_nodes; + index_t alt_idx = 0, haplotype_idx = 0; + for(; szs_idx < szs_idx_end; szs_idx++) { + index_t curr_len = tmp_szs[szs_idx].len; + if(curr_len <= 0) continue; + index_t num_predicted_nodes = (index_t)(curr_len * 1.2); + nodes.resizeExact(num_predicted_nodes); nodes.clear(); + edges.resizeExact(num_predicted_nodes); edges.clear(); + + // Created head node + nodes.expand(); + nodes.back().label = 'Y'; + nodes.back().value = 0; + + // Create nodes and edges corresponding to a reference genome + assert_leq(curr_pos + curr_len, s.length()); + for(size_t i = curr_pos; i < curr_pos + curr_len; i++) { + nodes.expand(); + nodes.back().label = "ACGT"[(int)s[i]]; + nodes.back().value = (index_t)i; + assert_geq(nodes.size(), 2); + edges.expand(); + edges.back().from = (index_t)nodes.size() - 2; + edges.back().to = (index_t)nodes.size() - 1; + } + + // Create tail node + nodes.expand(); + nodes.back().label = 'Z'; + nodes.back().value = (index_t)s.length(); + lastNode = (index_t)nodes.size() - 1; + edges.expand(); + edges.back().from = (index_t)nodes.size() - 2; + edges.back().to = (index_t)nodes.size() - 1; + ASSERT_ONLY(index_t backbone_nodes = (index_t)nodes.size()); + + // Create nodes and edges for haplotypes + for(; haplotype_idx < haplotypes.size(); haplotype_idx++) { + const Haplotype& haplotype = haplotypes[haplotype_idx]; + if(haplotype.left < curr_pos) continue; + if(haplotype.right >= curr_pos + curr_len) break; + const EList& snpIDs = haplotype.alts; + assert_gt(snpIDs.size(), 0); + bool pass = true; + for(index_t s = 0; s < snpIDs.size(); s++) { + index_t snpID = snpIDs[s]; + assert_lt(snpID, alts.size()); + const ALT& snp = alts[snpID]; + assert(snp.snp()); + if(s + 1 >= snpIDs.size()) break; + index_t snpID2 = snpIDs[s+1]; + assert_lt(snpID2, alts.size()); + const ALT& snp2 = alts[snpID2]; + assert(snp2.snp()); + if(snp.type == ALT_SNP_INS) { + if(snp.pos > snp2.pos) { + pass = false; + break; + } + } else if(snp.type == ALT_SNP_DEL) { + if(snp2.type == ALT_SNP_DEL) { + if(snp.pos + snp.len >= snp2.pos) { + pass = false; + break; + } + } else { + if(snp.pos + snp.len - 1 >= snp2.pos) { + pass = false; + break; + } + } + } else { + if(snp.pos >= snp2.pos) { + pass = false; + break; + } + } + } + + if(!pass) continue; + + index_t prev_ALT_type = ALT_NONE; + index_t ID_i = 0; + for(index_t j = haplotype.left; j <= haplotype.right; j++) { + if(prev_ALT_type == ALT_SNP_INS) j--; + const ALT* altp = (ID_i < snpIDs.size() ? &(alts[snpIDs[ID_i]]) : NULL); + assert(altp == NULL || altp->pos >= j); + if(altp != NULL && altp->pos == j) { + const ALT& alt = *altp; + assert_lt(alt.pos, s.length()); + assert(alt.snp()); + if(alt.type == ALT_SNP_SGL) { + assert_eq(alt.len, 1); + nodes.expand(); + assert_lt(alt.seq, 4); + assert_neq(alt.seq & 0x3, s[alt.pos]); + nodes.back().label = "ACGT"[alt.seq]; + nodes.back().value = alt.pos; + if(prev_ALT_type != ALT_SNP_DEL) { + edges.expand(); + if(j == haplotype.left) { + edges.back().from = alt.pos - curr_pos; + assert_lt(edges.back().from, backbone_nodes); + } else { + assert_gt(nodes.size(), 2); + edges.back().from = (index_t)nodes.size() - 2; + } + edges.back().to = (index_t)nodes.size() - 1; + } + if(j == haplotype.right) { + edges.expand(); + edges.back().from = (index_t)nodes.size() - 1; + edges.back().to = alt.pos - curr_pos + 2; + assert_lt(edges.back().to, backbone_nodes); + } + } + else if(alt.type == ALT_SNP_DEL) { + assert_gt(alt.len, 0); + assert_leq(alt.pos - curr_pos + alt.len, s.length()); + edges.expand(); + if(j == haplotype.left) { + edges.back().from = alt.pos - curr_pos; + assert_lt(edges.back().from, backbone_nodes); + } else { + edges.back().from = (index_t)nodes.size() - 1; + } + j += (alt.len - 1); + assert_leq(j, haplotype.right); + if(j == haplotype.right) { + edges.back().to = alt.pos - curr_pos + alt.len + 1; + assert_lt(edges.back().to, backbone_nodes); + } else { + edges.back().to = (index_t)nodes.size(); + } + } else { + assert_eq(alt.type, ALT_SNP_INS) + assert_gt(alt.len, 0); + for(size_t k = 0; k < alt.len; k++) { + uint64_t bp = alt.seq >> ((alt.len - k - 1) << 1); + bp &= 0x3; + char ch = "ACGT"[bp]; + nodes.expand(); + nodes.back().label = ch; + nodes.back().value = (index_t)INDEX_MAX; + if(prev_ALT_type == ALT_SNP_DEL && k == 0) continue; + edges.expand(); + edges.back().from = ((k == 0 && j == haplotype.left) ? alt.pos - curr_pos : (index_t)nodes.size() - 2); + edges.back().to = (index_t)nodes.size() - 1; + } + if(j == haplotype.right) { + edges.expand(); + edges.back().from = (index_t)nodes.size() - 1; + edges.back().to = alt.pos - curr_pos + 1; + } + } +#ifndef NDEBUG + snp_set.insert(snpIDs[ID_i]); +#endif + ID_i++; + prev_ALT_type = alt.type; + } else { + int nt = s[j]; + assert_lt(nt, 4); + nodes.expand(); + nodes.back().label = "ACGT"[nt]; + nodes.back().value = j; + if(prev_ALT_type != ALT_SNP_DEL) { + edges.expand(); + if(j == haplotype.left && prev_ALT_type == ALT_NONE) { + edges.back().from = j - curr_pos; + assert_lt(edges.back().from, backbone_nodes); + } else { + edges.back().from = (index_t)nodes.size() - 2; + } + edges.back().to = (index_t)nodes.size() - 1; + } + if(j == haplotype.right) { + edges.expand(); + edges.back().from = (index_t)nodes.size() - 1; + edges.back().to = j - curr_pos + 2; + assert_lt(edges.back().to, backbone_nodes); + } + prev_ALT_type = ALT_SNP_SGL; + } + } + } + + // Create nodes and edges for splice sites + for(; alt_idx < alts.size(); alt_idx++) { + const ALT& alt = alts[alt_idx]; + if(alt.pos < curr_pos) continue; + if(alt.pos >= curr_pos + curr_len) break; + if(!alt.splicesite()) continue; + if(alt.excluded) continue; + assert_lt(alt.left, alt.right); + edges.expand(); + edges.back().from = alt.left - curr_pos; + edges.back().to = alt.right - curr_pos + 2; + assert_lt(edges.back().from, backbone_nodes); + assert_lt(edges.back().to, backbone_nodes); + } + +#ifndef NDEBUG + if(refGraph.debug) { + cerr << "Nodes:" << endl; + for(size_t i = 0; i < nodes.size(); i++) { + const Node& node = nodes[i]; + cerr << "\t" << i << "\t" << node.label << "\t" << node.value << endl; + } + cerr << endl; + cerr << "Edges: " << endl; + for(size_t i = 0; i < edges.size(); i++) { + const Edge& edge = edges[i]; + cerr << "\t" << i << "\t" << edge.from << " --> " << edge.to << endl; + } + cerr << endl; + } +#endif + + if(!isReverseDeterministic(nodes, edges)) { + reverseDeterminize(nodes, edges, lastNode, curr_pos > 0 ? curr_pos + 1 : 0); + assert(isReverseDeterministic(nodes, edges)); + } + + // Identify head + index_t head_node = (index_t)nodes.size(); + for(index_t i = 0; i < nodes.size(); i++) { + if(nodes[i].label == 'Y') { + head_node = i; + break; + } + } + assert_lt(head_node, nodes.size()); + index_t tail_node = lastNode; assert_lt(tail_node, nodes.size()); + + // Update edges + const index_t invalid = (index_t)INDEX_MAX; + bool head_off = curr_pos > 0, tail_off = curr_pos + curr_len < jlen; + for(index_t i = 0; i < edges.size(); i++) { + index_t from = edges[i].from; + from = from + num_nodes; + if(head_off && edges[i].from > head_node) from -= 1; + if(tail_off && edges[i].from > tail_node) from -= 1; + if(head_off && edges[i].from == head_node) { + edges[i].from = invalid; + } else { + edges[i].from = from; + } + + index_t to = edges[i].to; + to = to + num_nodes; + if(head_off && edges[i].to > head_node) to -= 1; + if(tail_off && edges[i].to > tail_node) to -= 1; + if(tail_off && edges[i].to == tail_node) { + edges[i].to = invalid; + } else { + edges[i].to = to; + } + } + head_node = tail_node = invalid; + // Also update lastNode + if(!tail_off) { + lastNode += num_nodes; + if(head_off) lastNode -= 1; + } + + // Connect head nodes with tail nodes in the previous automaton + index_t num_head_nodes = 0; + index_t tmp_num_edges = (index_t)edges.size(); + if(head_off) { + EList nodes_to_head; + for(index_t i = 0; i < tmp_num_edges; i++) { + if(edges[i].from == head_node) { + num_head_nodes++; + if(prev_tail_nodes.size() > 0) { + for(index_t j = 0; j < prev_tail_nodes.size(); j++) { + edges.expand(); + edges.back().from = prev_tail_nodes[j]; + edges.back().to = edges[i].to; + assert_lt(edges.back().from, edges.back().to); + } + } else { + nodes_to_head.push_back(edges[i].to); + } + } + } + + if(nodes_to_head.size() > 0) { + assert_gt(thread_id, 0); + assert_eq(prev_tail_nodes.size(), 0); + writeIndex(rg_out_file, (index_t)nodes_to_head.size(), bigEndian); + for(index_t i = 0; i < nodes_to_head.size(); i++) { + writeIndex(rg_out_file, nodes_to_head[i], bigEndian); + } + } + } + + // Need to check if it's reverse-deterministic + if(num_head_nodes > 1) { + threadParam->multipleHeadNodes = true; + } + + // List tail nodes + prev_tail_nodes.clear(); + if(tail_off) { + for(index_t i = 0; i < tmp_num_edges; i++) { + if(edges[i].to == tail_node) { + prev_tail_nodes.push_back(edges[i].from); + } + } + } + + // Write nodes and edges + index_t tmp_num_nodes = (index_t)nodes.size(); + assert_gt(tmp_num_nodes, 2); + if(head_off) tmp_num_nodes--; + if(tail_off) tmp_num_nodes--; + writeIndex(rg_out_file, tmp_num_nodes, bigEndian); + ASSERT_ONLY(index_t num_nodes_written = 0); + for(index_t i = 0; i < nodes.size(); i++) { + if(head_off && nodes[i].label == 'Y') continue; + if(tail_off && nodes[i].label == 'Z') continue; + nodes[i].write(rg_out_file, bigEndian); + ASSERT_ONLY(num_nodes_written++); + } + assert_eq(tmp_num_nodes, num_nodes_written); + tmp_num_edges = (index_t)edges.size(); + assert_geq(tmp_num_edges, num_head_nodes + prev_tail_nodes.size()); + if(head_off) tmp_num_edges -= num_head_nodes; + if(tail_off) tmp_num_edges -= prev_tail_nodes.size(); + writeIndex(rg_out_file, tmp_num_edges, bigEndian); + ASSERT_ONLY(index_t num_edges_written = 0); + for(index_t i = 0; i < edges.size(); i++) { + if(head_off && edges[i].from == head_node) continue; + if(tail_off && edges[i].to == tail_node) continue; + edges[i].write(rg_out_file, bigEndian); + ASSERT_ONLY(num_edges_written++); + } + assert_eq(tmp_num_edges, num_edges_written); + + // Clear nodes and edges + nodes.clear(); edges.clear(); + + curr_pos += curr_len; + num_nodes += tmp_num_nodes; + num_edges += tmp_num_edges; + } + + if(nthreads > 1 && thread_id + 1 < (index_t)nthreads && prev_tail_nodes.size() > 0) { + writeIndex(rg_out_file, (index_t)prev_tail_nodes.size(), bigEndian); + for(index_t i = 0; i < prev_tail_nodes.size(); i++) { + writeIndex(rg_out_file, prev_tail_nodes[i], bigEndian); + } + } + + // Close out file handle + rg_out_file.close(); +} + +template +bool RefGraph::isReverseDeterministic(EList& nodes, EList& edges) +{ + if(edges.size() <= 0) return true; + + // Sort edges by "to" nodes + sortEdgesTo(edges); + + index_t curr_to = (index_t)INDEX_MAX; + EList seen; seen.resize(5); seen.fillZero(); + for(index_t i = 0; i < edges.size(); i++) { + index_t from = edges[i].from; + assert_lt(from, nodes.size()); + char nt = nodes[from].label; + assert(nt == 'A' || nt == 'C' || nt == 'G' || nt == 'T' || nt == 'Y'); + if(nt == 'Y') nt = 4; + else nt = asc2dna[(int)nt]; + assert_lt(nt, seen.size()); + if(curr_to != edges[i].to) { + curr_to = edges[i].to; + seen.fillZero(); + seen[nt] = true; + } else { + if(seen[nt]) { + return false; + } + seen[nt] = true; + } + } + + return true; +} + + +template +void RefGraph::reverseDeterminize(EList& nodes, EList& edges, index_t& lastNode, index_t lastNode_add) +{ + EList cnodes; cnodes.ensure(nodes.size()); + map cnode_map; + deque active_cnodes; + EList cedges; cedges.ensure(edges.size()); + + // Start from the final node ('Z') + assert_lt(lastNode, nodes.size()); + const Node& last_node = nodes[lastNode]; + cnodes.expand(); + cnodes.back().reset(); + cnodes.back().label = last_node.label; + cnodes.back().value = last_node.value; + cnodes.back().nodes.push_back(lastNode); + active_cnodes.push_back(0); + cnode_map[cnodes.back().nodes] = 0; + sortEdgesTo(edges); + + index_t firstNode = 0; // Y -> ... -> Z + EList predecessors; + while(!active_cnodes.empty()) { + index_t cnode_id = active_cnodes.front(); active_cnodes.pop_front(); + assert_lt(cnode_id, cnodes.size()); + + // Find predecessors of this composite node + predecessors.clear(); + for(size_t i = 0; i < cnodes[cnode_id].nodes.size(); i++) { + index_t node_id = cnodes[cnode_id].nodes.getID((index_t)i); + pair edge_range = findEdgesTo(edges, node_id); + assert_leq(edge_range.first, edge_range.second); + assert_leq(edge_range.second, edges.size()); + for(index_t j = edge_range.first; j < edge_range.second; j++) { + assert_eq(edges[j].to, node_id); + predecessors.push_back(edges[j].from); + } + } + + if(predecessors.size() >= 2) { + // Remove redundant nodes + predecessors.sort(); + index_t new_size = (index_t)(unique(predecessors.begin(), predecessors.end()) - predecessors.begin()); + predecessors.resize(new_size); + + // Create composite nodes by labels + stable_sort(predecessors.begin(), predecessors.end(), TempNodeLabelCmp(nodes)); + } + + for(size_t i = 0; i < predecessors.size();) { + index_t node_id = predecessors[i]; + assert_lt(node_id, nodes.size()); + const Node& node = nodes[node_id]; i++; + + cnodes.expand(); + cnodes.back().reset(); + cnodes.back().label = node.label; + cnodes.back().value = node.value; + cnodes.back().nodes.push_back(node_id); + + if(node.label == 'Y' && firstNode == 0) { + firstNode = (index_t)cnodes.size() - 1; + } + + while(i < predecessors.size()) { + index_t next_node_id = predecessors[i]; + assert_lt(next_node_id, nodes.size()); + const Node& next_node = nodes[next_node_id]; + if(next_node.label != node.label) break; + cnodes.back().nodes.push_back(next_node_id); + if(next_node.value != (index_t)INDEX_MAX) { + if(cnodes.back().value == (index_t)INDEX_MAX) { + cnodes.back().value = next_node.value; + } else { + cnodes.back().value = max(cnodes.back().value, next_node.value); + } + } + i++; + } + + // Create edges from this new composite node to current composite node + typename map::iterator existing = cnode_map.find(cnodes.back().nodes); + if(existing == cnode_map.end()) { + cnode_map[cnodes.back().nodes] = (index_t)cnodes.size() - 1; + active_cnodes.push_back((index_t)cnodes.size() - 1); + cedges.push_back(CompositeEdge((index_t)cnodes.size() - 1, cnode_id)); + } else { + cnodes.pop_back(); + cedges.push_back(CompositeEdge((*existing).second, cnode_id)); + } + + // Increment indegree + cnodes[cnode_id].id++; + } + } + + // Interchange from and to + for(index_t i = 0; i < cedges.size(); i++) { + index_t tmp = cedges[i].from; + cedges[i].from = cedges[i].to; + cedges[i].to = tmp; + } + sort(cedges.begin(), cedges.end()); + active_cnodes.push_back(0); + while(!active_cnodes.empty()) { + index_t cnode_id = active_cnodes.front(); active_cnodes.pop_front(); + assert_lt(cnode_id, cnodes.size()); + const CompositeNode& cnode = cnodes[cnode_id]; + index_t i = (index_t)cedges.bsearchLoBound(CompositeEdge(cnode_id, 0)); + while(i < cedges.size()) { + assert_geq(cedges[i].from, cnode_id); + if(cedges[i].from != cnode_id) break; + index_t predecessor_cnode_id = cedges[i].to; + assert_lt(predecessor_cnode_id, cnodes.size()); + CompositeNode& predecessor_cnode = cnodes[predecessor_cnode_id]; + if(cnode.value == predecessor_cnode.value + 1) { + active_cnodes.push_back(predecessor_cnode_id); + break; + } + i++; + } + } + // Restore from and to by interchanging them + for(index_t i = 0; i < cedges.size(); i++) { + index_t tmp = cedges[i].from; + cedges[i].from = cedges[i].to; + cedges[i].to = tmp; + } + + // Create new nodes + lastNode = 0; // Invalidate lastNode + nodes.resizeExact(cnodes.size()); nodes.clear(); + assert_neq(firstNode, 0); + assert_lt(firstNode, cnodes.size()); + CompositeNode& first_node = cnodes[firstNode]; + first_node.id = 0; + nodes.expand(); + nodes.back() = first_node.getNode(); + active_cnodes.push_back(firstNode); + sort(cedges.begin(), cedges.end()); + while(!active_cnodes.empty()) { + index_t cnode_id = active_cnodes.front(); active_cnodes.pop_front(); + assert_lt(cnode_id, cnodes.size()); + index_t i = (index_t)cedges.bsearchLoBound(CompositeEdge(cnode_id, 0)); + while(i < cedges.size()) { + assert_geq(cedges[i].from, cnode_id); + if(cedges[i].from != cnode_id) break; + index_t successor_cnode_id = cedges[i].to; + assert_lt(successor_cnode_id, cnodes.size()); + CompositeNode& successor_cnode = cnodes[successor_cnode_id]; + assert_gt(successor_cnode.id, 0); + successor_cnode.id--; + if(successor_cnode.id == 0) { + active_cnodes.push_back(successor_cnode_id); + successor_cnode.id = (index_t)nodes.size(); + nodes.expand(); + nodes.back() = successor_cnode.getNode(); + if(nodes.back().label == 'Z') { + assert_eq(lastNode, 0); + assert_gt(nodes.size(), 1); + lastNode = (index_t)nodes.size() - 1; + } + } + i++; + } + } + + // Create new edges + edges.resizeExact(cedges.size()); edges.clear(); + for(index_t i = 0; i < cedges.size(); i++) { + const CompositeEdge& edge = cedges[i]; + edges.expand(); + edges.back() = edge.getEdge(cnodes); + } + sortEdgesFrom(edges); + +#if 0 +#ifndef NDEBUG + if(debug) { + cerr << "Nodes:" << endl; + for(size_t i = 0; i < nodes.size(); i++) { + const Node& node = nodes[i]; + cerr << "\t" << i << "\t" << node.label << "\t" << node.value << (node.backbone ? "\tbackbone" : "") << endl; + } + cerr << endl; + cerr << "Edges: " << endl; + for(size_t i = 0; i < edges.size(); i++) { + const Edge& edge = edges[i]; + cerr << "\t" << i << "\t" << edge.from << " --> " << edge.to << endl; + } + cerr << endl; + } +#endif +#endif +} + +template +class PathGraph { +public: + struct PathNode { + index_t from; + index_t to; + pair key; + + void setSorted() { to = (index_t)INDEX_MAX; } + bool isSorted() const { return to == (index_t)INDEX_MAX; } + + index_t value() const { return to; } + index_t outdegree() const { return key.first; } + + bool operator< (const PathNode& o) const { + return key < o.key; + }; + }; + + static inline index_t PathNodeFrom (PathNode& a) { + return a.from; + } + + static inline index_t PathNodeKey (PathNode& a) { + return a.key.first; + } + + struct PathNodeKeySecondCmp { + bool operator() (const PathNode& a, const PathNode& b) const { + return a.key.second < b.key.second; + } + }; + + struct PathNodeFromCmp { + bool operator() (const PathNode& a, const PathNode& b) const { + return a.from < b.from; + } + }; + + struct PathNodeToCmp { + bool operator() (const PathNode& a, const PathNode& b) const { + return a.to < b.to; + } + }; + + struct PathEdge { + index_t from; + union { + index_t to; + index_t ranking; + }; + char label; + + PathEdge() { reset(); } + + PathEdge(index_t from_, index_t ranking_, char label_) : from(from_), ranking(ranking_), label(label_) {} + + void reset() { + from = 0; + ranking = 0; + label = 0; + } + + bool operator< (const PathEdge& o) const { + return label < o.label || (label == o.label && ranking < o.ranking); + }; + + }; + + static inline index_t PathEdgeTo (PathEdge& a) { + return a.to; + } + + struct PathEdgeFromCmp { + bool operator() (const PathEdge& a, const PathEdge& b) const { + return a.from < b.from || (a.from == b.from && a.to < b.to); + } + }; + + struct PathEdgeToCmp { + bool operator() (const PathEdge& a, const PathEdge& b) const { + return a.to < b.to || (a.to == b.to && a.from < b.from); + } + }; + +public: + // Create a new graph in which paths are represented using nodes + PathGraph( + RefGraph& parent, + const string& base_fname, + size_t max_num_nodes_ = std::numeric_limits::max(), + int nthreads_ = 1, + bool verbose_ = false); + + ~PathGraph() {} + + void printInfo(); + + bool generateEdges(RefGraph& parent); + + index_t getNumNodes() const { return (index_t)nodes.size(); } + index_t getNumEdges() const { return (index_t)edges.size(); } + + bool isSorted() const { return sorted; } + + bool nextRow(int& gbwtChar, int& F, int& M, index_t& pos) { + if(report_node_idx >= nodes.size()) return false; + bool firstOutEdge = false; + if(report_edge_range.first >= report_edge_range.second) { + report_edge_range = getEdges(report_node_idx, false /* from? */); + firstOutEdge = true; + if(report_node_idx == 0) { + report_M = pair(0, 0); + } + } + assert_lt(report_edge_range.first, report_edge_range.second); + assert_lt(report_edge_range.first, edges.size()); + const PathEdge& edge = edges[report_edge_range.first]; + gbwtChar = edge.label; + assert_lt(report_node_idx, nodes.size()); + F = (firstOutEdge ? 1 : 0); + + report_edge_range.first++; + if(report_edge_range.first >= report_edge_range.second) { + report_node_idx++; + } + assert_lt(report_M.first, nodes.size()); + pos = nodes[report_M.first].to; + M = (report_M.second == 0 ? 1 : 0); + report_M.second++; + if(report_M.second >= nodes[report_M.first].key.first) { + report_M.first++; + report_M.second = 0; + } + return true; + } + + index_t nextFLocation() { + if(report_F_node_idx >= nodes.size()) return (index_t)INDEX_MAX; + index_t ret = report_F_location; + pair edge_range = getEdges(report_F_node_idx, false /* from? */); + report_F_node_idx++; + assert_lt(edge_range.first, edge_range.second); + report_F_location += (edge_range.second - edge_range.first); + return ret; + } + +private: + void makeFromRef(RefGraph& base); + void generationOne(); + void earlyGeneration(); + void firstPruneGeneration(); + void lateGeneration(); + + void mergeUpdateRank(); + pair nextMaximalSet(pair range); + pair getEdges(index_t node, bool by_from); // Create index first. + + struct CreateNewNodesParams { + PathNode* st; + PathNode* en; + PathNode* curr; + index_t* sub_temp_nodes; + PathGraph* graph; + }; + static void createNewNodesCounter(void* vp); + static void createNewNodesMaker(void* vp); + void createNewNodes(); + + struct GenEdgesParams { + typename RefGraph::Edge* st; + typename RefGraph::Edge* en; + EList* label_index; + EList* nodes; + EList* edges; + EList::Node>* ref_nodes; + }; + static void generateEdgesCounter(void* vp); + static void generateEdgesMaker(void* vp); + +private: + int nthreads; + bool verbose; + EList from_table; + EList past_nodes; + EList nodes; + EList edges; + index_t ranks; + index_t max_from; //number of nodes in RefGraph + index_t temp_nodes; // Total number of nodes created before sorting. + index_t generation; // Sorted by paths of length 2^generation. + bool sorted; + + // For reporting GBWT char, F, and M values + index_t report_node_idx; + pair report_edge_range; + pair report_M; + // For reporting location in F corresponding to 1 bit in M + index_t report_F_node_idx; + index_t report_F_location; + + size_t max_num_nodes; + + // following variables are for debugging purposes +#ifndef NDEBUG + bool debug; +#endif + + EList bwt_string; + EList F_array; + EList M_array; + EList bwt_counts; + + // brute-force implementations + index_t select(const EList& array, index_t p, char c) { + if(p <= 0) return 0; + for(index_t i = 0; i < array.size(); i++) { + if(array[i] == c) { + assert_gt(p, 0); + p--; + if(p == 0) + return i; + } + } + return (index_t)array.size(); + } + + index_t select1(const EList& array, index_t p) { + return select(array, p, 1); + } + + index_t rank(const EList& array, index_t p, char c) { + index_t count = 0; + assert_lt(p, array.size()); + for(index_t i = 0; i <= p; i++) { + if(array[i] == c) + count++; + } + return count; + } + + index_t rank1(const EList& array, index_t p) { + return rank(array, p, 1); + } + + // for debugging purposes +#ifndef NDEBUG +public: EList > ftab; +#endif +}; + +//creates prefix-sorted PathGraph Nodes given a reverse determinized RefGraph +//outputs nodes sorted by their from attribute +template +PathGraph::PathGraph( + RefGraph& base, + const string& base_fname, + size_t max_num_nodes_, + int nthreads_, + bool verbose_) : +nthreads(nthreads_), verbose(verbose_), +ranks(0), temp_nodes(0), generation(0), sorted(false), +report_node_idx(0), report_edge_range(pair(0, 0)), report_M(pair(0, 0)), +report_F_node_idx(0), report_F_location(0), +max_num_nodes(max_num_nodes_) +{ +#ifndef NDEBUG + debug = base.nodes.size() <= 20; +#endif + // Fill nodes with a PathNode for each edge in base.edges. + // Set max_from. + makeFromRef(base); + + // Write RefGraph into a file + const bool file_rf = base.nodes.size() > (1 << 22); + const bool bigEndian = false; + const string rf_fname = base_fname + ".rf"; + if(file_rf) { + base.write(rf_fname, bigEndian); + base.nullify(); + } + + // In the first generation the nodes enter, not quite sorted by from. + // We use a counting sort to sort the nodes, otherwise same as early generation. + generationOne(); + // In early generations no nodes become sorted. + // Therefore, we skip the pruning step and leave the + // nodes sorted by from. + while(generation < 3) { + earlyGeneration(); + } + // On the first generation we perform a pruning step, + // we are forced to sort the entire list of nodes by rank + // in order to perform pruning step. + firstPruneGeneration(); + // In later generations, most nodes are already sorted, so we + // perform a more expensive random access join with nodes in rank order + // in return for avoiding having to sort by rank in order to prune nodes. + while(!isSorted()) { + lateGeneration(); + } + // In the generateEdges method it is convenient to begin with nodes sorted by from. + // We perform this action here, while we still have past_nodes allocated to avoid + // an in-place sort. + nodes.resizeNoCopyExact(past_nodes.size()); + radix_sort_copy(past_nodes.begin(), past_nodes.end(), nodes.ptr(), + &PathNodeFrom, max_from, nthreads); + past_nodes.nullify(); + from_table.nullify(); + + if(file_rf) { + base.read(rf_fname, bigEndian); + std::remove(rf_fname.c_str()); + } +} + +//make original unsorted PathNodes given a RefGraph +template +void PathGraph::makeFromRef(RefGraph& base) { + // Create a path node per edge with a key set to from node's label + temp_nodes = (index_t)base.edges.size() + 1; + max_from = 0; + nodes.reserveExact(temp_nodes); + for(index_t i = 0; i < base.edges.size(); i++) { + const typename RefGraph::Edge& e = base.edges[i]; + nodes.expand(); + nodes.back().from = e.from; + if(e.from > max_from) max_from = e.from; + nodes.back().to = e.to; + + switch(base.nodes[e.from].label) { + case 'A': + nodes.back().key = pair(0, 0); + break; + case 'C': + nodes.back().key = pair(1, 0); + break; + case 'G': + nodes.back().key = pair(2, 0); + break; + case 'T': + nodes.back().key = pair(3, 0); + break; + case 'Y': + nodes.back().key = pair(4, 0); + break; + default: + assert(false); + throw 1; + } + } + // Final node. + assert_lt(base.lastNode, base.nodes.size()); + assert_eq(base.nodes[base.lastNode].label, 'Z'); + nodes.expand(); + nodes.back().from = nodes.back().to = base.lastNode; + if(base.lastNode > max_from) max_from = base.lastNode; + nodes.back().key = pair(5, 0); + printInfo(); +} + +template +void PathGraph::generationOne() { + //nodes enter almost sorted by from + //this is only generation method that whose + // incoming nodes are in the nodes EList + generation++; + //Sort nodes by from using counting sort + //Copy into past_nodes in the process + //first count number with each from value + for(PathNode* node = nodes.begin(); node != nodes.end(); node++) { + nodes[node->from].key.second++; + } + //convert into an index + index_t tot = nodes[0].key.second; + nodes[0].key.second = 0; + for(index_t i = 1; i < max_from + 2; i++) { + tot += nodes[i].key.second; + nodes[i].key.second = tot - nodes[i].key.second; + } + // use past_nodes as from_table + past_nodes.resizeExact(nodes.size()); + for(PathNode* node = nodes.begin(); node != nodes.end(); node++) { + past_nodes[nodes[node->from].key.second++] = *node; + } + //reset index + for(index_t i = max_from + 1; i > 0; i--) { + past_nodes[i].key.second = nodes[i - 1].key.second; + } + past_nodes[0].key.second = 0; + //Now query direct-access table + createNewNodes(); + printInfo(); + past_nodes.swap(nodes); +} + +template +void PathGraph::earlyGeneration() { + //past_nodes enter sorted by from + //do not yet need to perform pruning step + generation++; + for(index_t i = 0; i < past_nodes.size(); i++) { + past_nodes[past_nodes[i].from + 1].key.second = i + 1; + } + createNewNodes(); + printInfo(); + past_nodes.swap(nodes); +} + +template +void PathGraph::firstPruneGeneration() { + //past_nodes enter sorted by from + //first generation where we need to perform pruning step + // results in us needing to sort entirety of nodes after they are made + generation++; + //here past_nodes is already sorted by .from + // first count where to start each from value + time_t start = time(0); + //Build from_index + for(index_t i = 0; i < past_nodes.size(); i++) { + past_nodes[past_nodes[i].from + 1].key.second = i + 1; + } + if(verbose) cerr << "BUILT FROM_INDEX: " << time(0) - start << endl; + start = time(0); + // Now query against direct-access table + createNewNodes(); + past_nodes.resizeNoCopyExact(nodes.size()); + + if(verbose) cerr << "RESIZE NODES: " << time(0) - start << endl; + start = time(0); + + //max_rank always corresponds to repeated Z's + // Z is mapped to 0x101 + // therefore max rank = 101101101101101101101101 = (101) 8 times + index_t max_rank = 11983725; + radix_sort_copy, index_t>(nodes.begin(), nodes.end(), past_nodes.ptr(), + &PathNodeKey, max_rank, nthreads); + + if(verbose) cerr << "SORT NODES: " << time(0) - start << endl; + start = time(0); + + nodes.swap(past_nodes); + mergeUpdateRank(); + + if(verbose) cerr << "MERGE, UPDATE RANK: " << time(0) - start << endl; + start = time(0); + + printInfo(); + past_nodes.swap(nodes); +} + +template +void PathGraph::lateGeneration() { + //past_nodes enter sorted by rank + //build direct-access table sorted by from, + //but query with original nodes sorted by rank + //since nodes we query with are sorted by rank, + // the nodes produced are automatically sorted by key.first + // therefore we only need to sort clusters with same key.first + generation++; + time_t overall = time(0); + time_t indiv = time(0); + assert_gt(nthreads, 0); + assert_neq(past_nodes.size(), ranks); + from_table.resizeNoCopy(past_nodes.size()); + + if(verbose) cerr << "ALLOCATE FROM_TABLE: " << time(0) - indiv << endl; + indiv = time(0); + + radix_sort_copy(past_nodes.begin(), past_nodes.end(), from_table.ptr(), + &PathNodeFrom, max_from, nthreads); + + if(verbose) cerr << "BUILD TABLE: " << time(0) - indiv << endl; + indiv = time(0); + + //Build from_index + index_t from_table_size = from_table.size(); + for(index_t i = 0; i < from_table_size; i++) { + if(from_table[i].from + 1 >= from_table.size()) { + from_table.resize(from_table[i].from + 2); + } + from_table[from_table[i].from + 1].key.second = i + 1; + } + + if(verbose) cerr << "BUILD INDEX: " << time(0) - indiv << endl; + + createNewNodes(); + + indiv = time(0); + + mergeUpdateRank(); + + if(from_table_size != from_table.size()) { + assert_lt(from_table_size, from_table.size()); + from_table.resize(from_table_size); + } + + if(verbose) cerr << "MERGEUPDATERANK: " << time(0) - indiv << endl; + if(verbose) cerr << "TOTAL TIME: " << time(0) - overall << endl; + + if(ranks >= (index_t)max_num_nodes) { + throw ExplosionException(); + } + + printInfo(); + past_nodes.swap(nodes); +} + +//----------------------------------------------------------------------------------------------- + +template +void PathGraph::createNewNodesCounter(void* vp) { + CreateNewNodesParams* params = (CreateNewNodesParams*)vp; + PathNode* st = params->st; + PathNode* en = params->en; + PathGraph& graph = *(params->graph); + + size_t count = 0; + if(graph.generation > 4) { + for(PathNode* node = st; node != en; node++) { + if(node->isSorted()) { + count++; + } else { + count += graph.from_table[node->to + 1].key.second - graph.from_table[node->to].key.second; + } + } + } else { + for(PathNode* node = st; node != en; node++) { + count += graph.past_nodes[node->to + 1].key.second - graph.past_nodes[node->to].key.second; + } + } + *(params->sub_temp_nodes) = (index_t)count; + + //check for overflow + if(count > (index_t)-1) { + cerr << "exceeded integer bounds, remove adjacent SNPs, use haplotypes, or switch to a large index (--large-index)" << endl; + throw 1; + } +} +template +void PathGraph::createNewNodesMaker(void* vp) { + CreateNewNodesParams* params = (CreateNewNodesParams*)vp; + PathNode* st = params->st; + PathNode* en = params->en; + PathNode* curr = params->curr; + PathGraph& graph = *(params->graph); + if(graph.generation > 4) { + for(PathNode* node = st; node != en; node++) { + if(node->isSorted()) { + *curr++ = *node; + } else { + for(index_t j = graph.from_table[node->to].key.second; j < graph.from_table[node->to + 1].key.second; j++) { + curr->from = node->from; + curr->to = graph.from_table[j].to; + (curr++)->key = pair(node->key.first, graph.from_table[j].key.first); + } + } + } + } else if(graph.generation == 4) { + for(PathNode* node = st; node != en; node++) { + for(index_t j = graph.past_nodes[node->to].key.second; j < graph.past_nodes[node->to + 1].key.second; j++) { + curr->from = node->from; + curr->to = graph.past_nodes[j].to; + (curr++)->key = pair(node->key.first, graph.past_nodes[j].key.first); + } + } + } else { + for(PathNode* node = st; node != en; node++) { + for(index_t j = graph.past_nodes[node->to].key.second; j < graph.past_nodes[node->to + 1].key.second; j++) { + curr->from = node->from; + curr->to = graph.past_nodes[j].to; + index_t bit_shift = 1 << (graph.generation - 1); + bit_shift = (bit_shift << 1) + bit_shift; + (curr++)->key = pair((node->key.first << bit_shift) + graph.past_nodes[j].key.first, 0); + } + } + } +} + +template +void PathGraph::createNewNodes() { + time_t indiv = time(0); + AutoArray threads(nthreads); + EList params; params.resizeExact(nthreads); + EList sub_temp_nodes; sub_temp_nodes.resizeExact(nthreads); sub_temp_nodes.fillZero(); + PathNode* st = past_nodes.begin(); + PathNode* en = st + past_nodes.size() / nthreads; + for(int i = 0; i < nthreads; i++) { + params[i].sub_temp_nodes = &sub_temp_nodes[i]; + params[i].st = st; + params[i].en = en; + params[i].graph = this; + if(nthreads == 1) { + createNewNodesCounter((void*)¶ms[0]); + } else { + threads[i] = new tthread::thread(&createNewNodesCounter, (void*)¶ms[i]); + } + st = en; + if(i + 2 == nthreads) { + en = past_nodes.end(); + } else { + en = st + past_nodes.size() / nthreads; + } + } + + if(nthreads > 1) { + for(int i = 0; i < nthreads; i++) + threads[i]->join(); + } + if(verbose) cerr << "COUNTED NEW NODES: " << time(0) - indiv << endl; + indiv = time(0); + //update all label indexes + temp_nodes = 0; + for(int i = 0; i < nthreads; i++) { + // done to check if we exceed index_t range + size_t val = (size_t)temp_nodes + (size_t)sub_temp_nodes[i]; + if(val > (index_t)-1) { + cerr << "exceeded integer bounds, remove adjacent SNPs, use haplotypes, or switch to a large index (--large-index)" << endl; + throw 1; + } + temp_nodes = (index_t)val; + } + if(verbose) cerr << "COUNTED TEMP NODES: " << time(0) - indiv << endl; + indiv = time(0); + nodes.resizeNoCopyExact(temp_nodes); + if(verbose) cerr << "RESIZED NODES: " << time(0) - indiv << endl; + indiv = time(0); + temp_nodes = 0; + for(int i = 0; i < nthreads; i++) { + params[i].curr = nodes.begin() + temp_nodes; + temp_nodes += sub_temp_nodes[i]; + } + if(verbose) cerr << "RESIZED NODES: " << time(0) - indiv << endl; + indiv = time(0); + //make new nodes + for(int i = 0; i < nthreads; i++) { + if(nthreads == 1) { + createNewNodesMaker((void*)¶ms[0]); + } else { + threads[i] = new tthread::thread(&createNewNodesMaker, (void*)¶ms[i]); + } + } + + if(nthreads > 1) { + for(int i = 0; i < nthreads; i++) + threads[i]->join(); + } + if(verbose) cerr << "MADE NEW NODES: " << time(0) - indiv << endl; + indiv = time(0); +} + +//------------------------------------------------------------------------------------ + +template +void PathGraph::mergeUpdateRank() +{ + if(generation == 4) { + // Merge equivalent nodes + index_t curr = 0; + pair range(0, 0); // Empty range + while(true) { + range = nextMaximalSet(range); + if(range.first >= range.second) + break; + nodes[curr] = nodes[range.first]; curr++; + } + nodes.resize(curr); + + // Set nodes that become sorted as sorted + PathNode* candidate = &nodes.front(); + pair key = candidate->key; ranks = 1; + for(index_t i = 1; i < nodes.size(); i++) { + if(nodes[i].key != key) { + if(candidate != NULL) { + candidate->setSorted(); + } + candidate = &nodes[i]; + key = candidate->key; ranks++; + } else { + candidate = NULL; + } + } + if(candidate != NULL) { + candidate->setSorted(); + } + ranks = 0; + key = nodes.front().key; + for(index_t i = 0; i < nodes.size(); i++) { + PathNode& node = nodes[i]; + if(node.key != key) { + key = node.key; + ranks++; + } + node.key = pair(ranks, 0); + } + ranks++; + } else { + PathNode* block_start = nodes.begin(); + PathNode* curr = nodes.begin(); + PathNode* node = nodes.begin(); + ranks = 0; + do { + node++; + if(node == nodes.end() || node->key.first != block_start->key.first) { + if(node - block_start == 1) { + block_start->key.first = ranks++; + *curr++ = *block_start; + } else { + sort(block_start, node, PathNodeKeySecondCmp()); + while(block_start != node) { + //extend shift while share same key + index_t shift = 1; + while(block_start + shift != node && block_start->key == (block_start + shift)->key) { + shift++; + } + //check if all share .from + //if they share same from, then they are a mergable set + bool merge = true; + for(PathNode* n = block_start; n != (block_start + shift); n++) { + if(n->from != block_start->from) { + merge = false; + break; + } + } + //if not mergable, just write all to array + if(!merge) { + for(PathNode* n = block_start; n != (block_start + shift); n++) { + n->key.first = ranks; + *curr++ = *n; + } + ranks++; + } else if(curr == nodes.begin() || !(curr - 1)->isSorted() || (curr - 1)->from != block_start->from) { + block_start->setSorted(); + block_start->key.first = ranks++; + *curr++ = *block_start; + } + block_start += shift; + } + // if we are at the last node or the last node is mergable into the previous node, we are done + if(node == nodes.end()) break; + if(node + 1 == nodes.end()) { + assert(curr >= nodes.begin() + 1); + if((curr - 1)->isSorted() && node->from == (curr - 1)->from) + break; + } + // check if we can safely merge the node immediately following the unsorted cluster into the previous node + // must be that: + // 1) node is not itself part of an unsorted cluster + // 2) the previous node is sorted + // 3) the nodes share the same from attribute + assert(node + 1 < nodes.end()); + if(node->key.first != (node + 1)->key.first) { + assert(curr >= nodes.begin() + 1); + if((curr - 1)->isSorted() && node->from == (curr - 1)->from) + node++; + } + } + block_start = node; + } + } while(node != nodes.end()); + nodes.resizeExact((index_t)(curr - nodes.begin())); + } + // if all nodes have unique rank we are done! + if(ranks == nodes.size()) sorted = true; +} + + +// Returns the next maximal mergeable set of PathNodes. +// A set of PathNodes sharing adjacent keys is mergeable, if each of the +// PathNodes begins in the same GraphNode, and no other PathNode shares +// the key. If the maximal set is empty, returns the next PathNode. +template +pair PathGraph::nextMaximalSet(pair range) { + if(range.second >= nodes.size()) { + return pair(0, 0); + } + range.first = range.second; + range.second = range.first + 1; + if(range.first > 0 && nodes[range.first - 1].key == nodes[range.first].key) { + return range; + } + + for(index_t i = range.second; i < nodes.size(); i++) { + if(nodes[i - 1].key != nodes[i].key) { + range.second = i; + } + if(nodes[i].from != nodes[range.first].from) { + return range; + } + } + range.second = (index_t)nodes.size(); + return range; +} + +//----------------------------------------------------------------------------------------- + +template +void PathGraph::printInfo() +{ + if(verbose) { + cerr << "Generation " << generation + << " (" << temp_nodes << " -> " << nodes.size() << " nodes, " + << ranks << " ranks)" << endl; + } +} + +//------------------------------------------------------------------------------------------ + +template +void PathGraph::generateEdgesCounter(void* vp) { + GenEdgesParams* params = (GenEdgesParams*)vp; + typename RefGraph::Edge* st = params->st; + typename RefGraph::Edge* en = params->en; + EList& label_index = *(params->label_index); + EList::Node>& ref_nodes = *(params->ref_nodes); + EList& nodes = *(params->nodes); + //first count edges, fill out label_index + for(typename RefGraph::Edge* edge = st; edge != en; edge++) { + char curr_label = ref_nodes[edge->from].label; + int curr_label_index; + switch(curr_label) { + case 'A': curr_label_index = 0; break; + case 'C': curr_label_index = 1; break; + case 'G': curr_label_index = 2; break; + case 'T': curr_label_index = 3; break; + case 'Y': curr_label_index = 4; break; + case 'Z': curr_label_index = 5; break; + default: assert(false); throw 1; + } + assert_lt(edge->to + 1, nodes.size()); + assert_lt(nodes[edge->to].key.second, nodes[edge->to + 1].key.second); + label_index[curr_label_index] += nodes[edge->to + 1].key.second - nodes[edge->to].key.second; + } +} + +template +void PathGraph::generateEdgesMaker(void* vp) { + GenEdgesParams* params = (GenEdgesParams*)vp; + typename RefGraph::Edge* st = params->st; + typename RefGraph::Edge* en = params->en; + EList& label_index = *(params->label_index); + EList::Node>& ref_nodes = *(params->ref_nodes); + EList& edges = *(params->edges); + EList& nodes = *(params->nodes); + for(typename RefGraph::Edge* edge = st; edge != en; edge++) { + char curr_label = ref_nodes[edge->from].label; + int curr_label_index; + switch(curr_label) { + case 'A': curr_label_index = 0; break; + case 'C': curr_label_index = 1; break; + case 'G': curr_label_index = 2; break; + case 'T': curr_label_index = 3; break; + case 'Y': curr_label_index = 4; break; + case 'Z': curr_label_index = 5; break; + default: assert(false); throw 1; + } + for(index_t j = nodes[edge->to].key.second; j < nodes[edge->to + 1].key.second; j++) { + edges[label_index[curr_label_index]++] = PathEdge(edge->from, nodes[j].key.first, curr_label); + } + } +} + +template +bool PathGraph::generateEdges(RefGraph& base) +{ + //entering we have: + // nodes - sorted by from + // edges - empty + // base.nodes - almost sorted by from/to + // base.edges - almost sorted by from/to + + //need to join: + // nodes.from -> base.nodes[] + // nodes.from -> base.edges.to + // nodes.from -> edges.from + + if(!sorted) return false; + + time_t indiv = time(0); + time_t overall = time(0); + + //replace nodes.to with genomic position + //fast because both roughly ordered by from + for(PathNode* node = nodes.begin(); node != nodes.end(); node++) { + node->to = base.nodes[node->from].value; + } + + if(verbose) cerr << "NODE.TO -> GENOME POS: " << time(0) - indiv << endl; + indiv = time(0); + + // build an index for nodes + index_t node_size = nodes.size(); + for(index_t i = 0; i < node_size; i++) { + // very rare case where the number of prefix-sorted nodes is smaller than the number of the initial nodes + // , which could happen with a very small graph and a variant as follows + // ATAGAGCAGTTCTGAAAAACACTTTTTGTTGAATCTGCAAG(T)GGACATTTGGATAGATTTGAAGATTTCGTTGGAAACGGGAATATCTTCATATCAAATG + // (G) + // where G(T) and G(G) will be combined as there is no other node that intervene those two path nodes. + if(nodes[i].from + 1 >= nodes.size()) { + nodes.resize(nodes[i].from + 2); + } + nodes[nodes[i].from + 1].key.second = i + 1; + } + + if(verbose) cerr << "BUILD FROM_INDEX " << time(0) - indiv << endl; + indiv = time(0); + + // Now join nodes.from to edges.to + // fast because base.edges roughly sorted by to + + //count number of edges + AutoArray threads(nthreads); + EList params; params.resizeExact(nthreads); + ELList label_index; label_index.resize(nthreads); + typename RefGraph::Edge* st = base.edges.begin(); + typename RefGraph::Edge* en = st + base.edges.size() / nthreads; + for(int i = 0; i < nthreads; i++) { + label_index[i].resizeExact(6); + label_index[i].fillZero(); + params[i].label_index = &label_index[i]; + params[i].st = st; + params[i].en = en; + params[i].nodes = &nodes; + params[i].edges = &edges; + params[i].ref_nodes = &base.nodes; + if(nthreads == 1) { + generateEdgesCounter((void*)¶ms[0]); + } else { + threads[i] = new tthread::thread(&generateEdgesCounter, (void*)¶ms[i]); + } + st = en; + if(i + 2 == nthreads) { + en = base.edges.end(); + } else { + en = st + base.edges.size() / nthreads; + } + } + + if(nthreads > 1) { + for(int i = 0; i < nthreads; i++) + threads[i]->join(); + } + + if(verbose) cerr << "COUNTED NEW EDGES: " << time(0) - indiv << endl; + indiv = time(0); + //update all label indexes + index_t tot = label_index[0][0]; + label_index[0][0] = 0; + for(int i = 1; i < nthreads; i++) { + tot += label_index[i][0]; + label_index[i][0] = tot - label_index[i][0]; + } + for(int j = 1; j < 6; j++) { + for(int i = 0; i < nthreads; i++) { + tot += label_index[i][j]; + label_index[i][j] = tot - label_index[i][j]; + } + } + edges.resizeExact(tot); + //make new edges + for(int i = 0; i < nthreads; i++) { + if(nthreads == 1) { + generateEdgesMaker((void*)¶ms[0]); + } else { + threads[i] = new tthread::thread(&generateEdgesMaker, (void*)¶ms[i]); + } + } + + if(nthreads > 1) { + for(int i = 0; i < nthreads; i++) { + threads[i]->join(); + } + } + base.nullify(); + + // delete unused nodes + if(node_size != nodes.size()) { + assert_lt(node_size, nodes.size()); + nodes.resize(node_size); + } + + if(verbose) cerr << "MADE NEW EDGES: " << time(0) - indiv << endl; + indiv = time(0); + + EList& index = label_index[nthreads - 1]; + + EList temp_edges; temp_edges.resizeExact(edges.size()); + + radix_sort_copy, index_t>(edges.begin() , edges.begin() + index[0], temp_edges.ptr(), + &PathEdgeTo, (index_t)nodes.size(), nthreads); + radix_sort_copy, index_t>(edges.begin() + index[0], edges.begin() + index[1], temp_edges.ptr() + index[0], + &PathEdgeTo, (index_t)nodes.size(), nthreads); + radix_sort_copy, index_t>(edges.begin() + index[1], edges.begin() + index[2], temp_edges.ptr() + index[1], + &PathEdgeTo, (index_t)nodes.size(), nthreads); + radix_sort_copy, index_t>(edges.begin() + index[2], edges.begin() + index[3], temp_edges.ptr() + index[2], + &PathEdgeTo, (index_t)nodes.size(), nthreads); + for(index_t i = index[3]; i < edges.size(); i++) { + temp_edges[i] = edges[i]; + } + sort(temp_edges.begin() + index[3], temp_edges.begin() + index[4]); + sort(temp_edges.begin() + index[4], temp_edges.begin() + index[5]); + edges.xfer(temp_edges); + + if(verbose) cerr << "SORTED NEW EDGES: " << time(0) - indiv << endl; + indiv = time(0); + + EList past_nodes; past_nodes.resizeExact(nodes.size()); + radix_sort_copy, index_t>(nodes.begin(), nodes.end(), past_nodes.ptr(), &PathNodeKey, ranks, nthreads); + nodes.xfer(past_nodes); + + if(verbose) cerr << "RE-SORTED NODES: " << time(0) - indiv << endl; + indiv = time(0); + +#ifndef NDEBUG + if(debug) { + cerr << "just after creating path edges" << endl; + cerr << "Ref edges" << endl; + for(size_t i = 0; i < base.edges.size(); i++) { + const typename RefGraph::Edge& edge = base.edges[i]; + cerr << "\t" << i << "\t" << edge.from << " --> " << edge.to << endl; + } + + cerr << "Path nodes" << endl; + for(size_t i = 0; i < nodes.size(); i++) { + const PathNode& node = nodes[i]; + cerr << "\t" << i << "\t(" << node.key.first << ", " << node.key.second << ")\t" + << node.from << " --> " << node.to << endl; + } + + cerr << "Path edges" << endl; + for(size_t i = 0; i < edges.size(); i++) { + const PathEdge& edge = edges[i]; + cerr << "\t" << i << "\tfrom: " << edge.from << "\tranking: " << edge.ranking << "\t" << edge.label << endl; + } + } +#endif + +#ifndef NDEBUG + + // Switch char array[x][y]; to char** array; + if(debug) { + cerr << "after sorting nodes by ranking and edges by label and ranking" << endl; + cerr << "Path nodes" << endl; + for(size_t i = 0; i < nodes.size(); i++) { + const PathNode& node = nodes[i]; + cerr << "\t" << i << "\t(" << node.key.first << ", " << node.key.second << ")\t" + << node.from << " --> " << node.to << endl; + } + + cerr << "Path edges" << endl; + for(size_t i = 0; i < edges.size(); i++) { + const PathEdge& edge = edges[i]; + cerr << "\t" << i << "\tfrom: " << edge.from << "\tranking: " << edge.ranking << "\t" << edge.label << endl; + } + } +#endif + + // Sets PathNode.to = GraphNode.value and PathNode.key.first to outdegree + // Replaces (from.from, to) with (from, to) + { + PathNode* node = nodes.begin(); node->key.first = 0; + PathEdge* edge = edges.begin(); + while(node != nodes.end() && edge != edges.end()) { + if(edge->from == node->from) { + edge->from = (index_t)(node - nodes.begin()); edge++; + node->key.first++; + } else { + node++; node->key.first = 0; + } + } + } + + if(verbose) cerr << "PROCESS EDGES: " << time(0) - indiv << endl; + indiv = time(0); + + // Remove 'Y' node + assert_gt(nodes.size(), 2); + nodes.back().key.first = nodes[nodes.size() - 2].key.first; + nodes[nodes.size() - 2] = nodes.back(); + nodes.pop_back(); + // Adjust edges accordingly + for(size_t i = 0; i < edges.size(); i++) { + PathEdge& edge = edges[i]; + if(edge.label == 'Y') { + edge.label = 'Z'; + } else if(edge.ranking >= nodes.size()) { + assert_eq(edge.ranking, nodes.size()); + edge.ranking -= 1; + } + } + if(verbose) cerr << "REMOVE Y: " << time(0) - indiv << endl; + indiv = time(0); + +#ifndef NDEBUG + if(debug) { + cerr << "Path nodes" << endl; + for(size_t i = 0; i < nodes.size(); i++) { + const PathNode& node = nodes[i]; + cerr << "\t" << i << "\t(" << node.key.first << ", " << node.key.second << ")\t" + << node.from << " --> " << node.to << endl; + } + + cerr << "Path edges" << endl; + for(size_t i = 0; i < edges.size(); i++) { + const PathEdge& edge = edges[i]; + cerr << "\t" << i << "\tfrom: " << edge.from << "\tranking: " << edge.ranking << "\t" << edge.label << endl; + } + } +#endif + temp_edges.resizeExact(edges.size()); + radix_sort_copy(edges.begin(), edges.end(), temp_edges.ptr(), &PathEdgeTo, (index_t)nodes.size(), nthreads); + edges.xfer(temp_edges); + for(index_t i = 0; i < edges.size(); i++) { + nodes[edges[i].ranking].key.second = i + 1; + } + + if(verbose) cerr << "SORT, Make index: " << time(0) - indiv << endl; + if(verbose) cerr << "TOTAL: " << time(0) - overall << endl; + + return true; + +//----------------------------------------------------------------------------------------------------- + bwt_string.clear(); + F_array.clear(); + M_array.clear(); + bwt_counts.resizeExact(5); bwt_counts.fillZero(); + for(index_t node = 0; node < nodes.size(); node++) { + pair edge_range = getEdges(node, false /* from? */); + for(index_t i = edge_range.first; i < edge_range.second; i++) { + assert_lt(i, edges.size()); + char label = edges[i].label; + if(label == 'Y') { + label = 'Z'; + } + bwt_string.push_back(label); + F_array.push_back(i == edge_range.first ? 1 : 0); + + if(label != 'Z') { + char nt = asc2dna[(int)label]; + assert_lt(nt + 1, bwt_counts.size()); + bwt_counts[nt + 1]++; + } + } + for(index_t i = 0; i < nodes[node].key.first; i++) { + M_array.push_back(i == 0 ? 1 : 0); + } + } + assert_gt(bwt_string.size(), 0); + assert_eq(bwt_string.size(), F_array.size()); + assert_eq(bwt_string.size(), M_array.size()); + + for(size_t i = 0; i < bwt_counts.size(); i++) { + if(i > 0) bwt_counts[i] += bwt_counts[i - 1]; + } + +#ifndef NDEBUG + if(debug) { + cerr << "Path nodes (final)" << endl; + for(size_t i = 0; i < nodes.size(); i++) { + const PathNode& node = nodes[i]; + cerr << "\t" << i << "\t(" << node.key.first << ", " << node.key.second << ")\t" + << node.from << " --> " << node.to << endl; + } + + cerr << "Path edges (final)" << endl; + for(size_t i = 0; i < edges.size(); i++) { + const PathEdge& edge = edges[i]; + cerr << "\t" << i << "\tfrom: " << edge.from << "\tranking: " << edge.ranking << "\t" << edge.label << endl; + } + + cerr << "i\tBWT\tF\tM" << endl; + for(index_t i = 0; i < bwt_string.size(); i++) { + cerr << i << "\t" << bwt_string[i] << "\t" // BWT char + << (int)F_array[i] << "\t" // F bit value + << (int)M_array[i] << endl; // M bit value + } + + for(size_t i = 0; i < bwt_counts.size(); i++) { + cerr << i << "\t" << bwt_counts[i] << endl; + } + } +#endif + + // Test searches, based on paper_example +#if 1 + EList queries; EList answers; +# if 1 +# if 1 + queries.push_back("GACGT"); answers.push_back(9); + queries.push_back("GATGT"); answers.push_back(9); + queries.push_back("GACT"); answers.push_back(9); + queries.push_back("ATGT"); answers.push_back(4); + queries.push_back("GTAC"); answers.push_back(10); + queries.push_back("ACTG"); answers.push_back(3); +# else + // rs55902548, at 402, ref, alt, unknown alt + queries.push_back("GGCAGCTCCCATGGGTACACACTGGGCCCAGAACTGGGATGGAGGATGCA"); + // queries.push_back("GGCAGCTCCCATGGGTACACACTGGTCCCAGAACTGGGATGGAGGATGCA"); + // queries.push_back("GGCAGCTCCCATGGGTACACACTGGACCCAGAACTGGGATGGAGGATGCA"); + + // rs5759268, at 926787, ref, alt, unknown alt + // queries.push_back("AAATTGCTCAGCCTTGTGCTGTGCACACCTGGTTCTCTTTCCAGTGTTAT"); + // queries.push_back("AAATTGCTCAGCCTTGTGCTGTGCATACCTGGTTCTCTTTCCAGTGTTAT"); + // queries.push_back("AAATTGCTCAGCCTTGTGCTGTGCAGACCTGGTTCTCTTTCCAGTGTTAT"); +# endif + + for(size_t q = 0; q < queries.size(); q++) { + const string& query = queries[q]; + assert_gt(query.length(), 0); + index_t top = 0, bot = edges.size(); + index_t node_top = 0, node_bot = 0; + cerr << "Aligning " << query << endl; + index_t i = 0; + for(; i < query.length(); i++) { + if(top >= bot) break; + int nt = query[query.length() - i - 1]; + nt = asc2dna[nt]; + assert_lt(nt, 4); + + cerr << "\t" << i << "\tBWT range: [" << top << ", " << bot << ")" << endl; + + top = bwt_counts[(int)nt] + (top <= 0 ? 0 : rank(bwt_string, top - 1, "ACGT"[nt])); + bot = bwt_counts[(int)nt] + rank(bwt_string, bot - 1, "ACGT"[nt]); + cerr << "\t\tLF BWT range: [" << top << ", " << bot << ")" << endl; + + node_top = rank1(M_array, top) - 1; + node_bot = rank1(M_array, bot - 1); + cerr << "\t\tnode range: [" << node_top << ", " << node_bot << ")" << endl; + + top = select1(F_array, node_top + 1); + bot = select1(F_array, node_bot + 1); + } + cerr << "\t" << i << "\tBWT range: [" << top << ", " << bot << ")" << endl; + // assert_eq(top, answers[q]); + cerr << "finished... "; + if(node_top < node_bot && node_top < nodes.size()) { + index_t pos = nodes[node_top].to; + index_t gpos = pos; + const EList& szs = base.szs; + for(index_t i = 0; i < szs.size(); i++) { + gpos += szs[i].off; + if(pos < szs[i].len) break; + pos -= szs[i].len; + } + + cerr << "being aligned at " << gpos; + } + cerr << endl << endl; + } +# endif + + // See inconsistencies between F and M arraystimy thread +# if 0 + cerr << endl << endl; + EList tmp_F; + for(index_t i = 0; i < F_array.size(); i++) { + if(F_array[i] == 1) tmp_F.push_back(i); + } + + EList tmp_M; + for(index_t i = 0; i < M_array.size(); i++) { + if(M_array[i] == 1) tmp_M.push_back(i); + } + + index_t max_diff = 0; + assert_eq(tmp_F.size(), tmp_M.size()); + for(index_t i = 0; i < tmp_F.size(); i++) { + index_t diff = (tmp_F[i] >= tmp_M[i] ? tmp_F[i] - tmp_M[i] : tmp_M[i] - tmp_F[i]); + if(diff > max_diff) { + max_diff = diff; + cerr << i << "\tdiff: " << max_diff << "\t" << (tmp_F[i] >= tmp_M[i] ? "+" : "-") << endl; + } + } + cerr << "Final: " << tmp_F.back() << " vs. " << tmp_M.back() << endl; +# endif + +#endif + return true; +} + +//-------------------------------------------------------------------------- + +template +pair PathGraph::getEdges(index_t node, bool by_from) { + if(node >= nodes.size()) { + cerr << "Error: Trying to get edges " << (by_from ? "from " : "to ") << node << endl; + } + if(nodes[node].key.second == 0) { + return pair(0, 0); + } + if(node == 0) { + return pair(0, nodes[node].key.second); + } else { + return pair(nodes[node - 1].key.second, nodes[node].key.second); + } +} + +#endif /*GBWT_GRAPH_H_*/ diff --git a/gfm.cpp b/gfm.cpp new file mode 100644 index 0000000..9637020 --- /dev/null +++ b/gfm.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include +#include "gfm.h" + +using namespace std; + +#ifdef BOWTIE_64BIT_INDEX + +const std::string gfm_ext("ht2l"); + +#else + +const std::string gfm_ext("ht2"); + +#endif // BOWTIE_64BIT_INDEX + +string gLastIOErrMsg; + +/** + * Try to find the Bowtie index specified by the user. First try the + * exact path given by the user. Then try the user-provided string + * appended onto the path of the "indexes" subdirectory below this + * executable, then try the provided string appended onto + * "$HISAT2_INDEXES/". + */ +string adjustEbwtBase(const string& cmdline, + const string& gfmFileBase, + bool verbose) +{ + string str = gfmFileBase; + ifstream in; + if(verbose) cout << "Trying " << str.c_str() << endl; + in.open((str + ".1." + gfm_ext).c_str(), ios_base::in | ios::binary); + if(!in.is_open()) { + if(verbose) cout << " didn't work" << endl; + in.close(); + if(getenv("HISAT2_INDEXES") != NULL) { + str = string(getenv("HISAT2_INDEXES")) + "/" + gfmFileBase; + if(verbose) cout << "Trying " << str.c_str() << endl; + in.open((str + ".1." + gfm_ext).c_str(), ios_base::in | ios::binary); + if(!in.is_open()) { + if(verbose) cout << " didn't work" << endl; + in.close(); + } else { + if(verbose) cout << " worked" << endl; + } + } + } + if(!in.is_open()) { + cerr << "Could not locate a HISAT2 index corresponding to basename \"" << gfmFileBase.c_str() << "\"" << endl; + throw 1; + } + return str; +} diff --git a/gfm.h b/gfm.h new file mode 100644 index 0000000..3d8fd2e --- /dev/null +++ b/gfm.h @@ -0,0 +1,6980 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef GFM_H_ +#define GFM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef BOWTIE_MM +#include +#include +#endif +#include "shmem.h" +#include "alphabet.h" +#include "assert_helpers.h" +#include "bitpack.h" +#include "blockwise_sa.h" +#include "endian_swap.h" +#include "word_io.h" +#include "random_source.h" +#include "ref_read.h" +#include "threading.h" +#include "str_util.h" +#include "mm.h" +#include "timer.h" +#include "reference.h" +#include "search_globals.h" +#include "ds.h" +#include "random_source.h" +#include "mem_ids.h" +#include "btypes.h" +#include "tokenize.h" +#include "repeat.h" +#include "repeat_kmer.h" + +#ifdef POPCNT_CAPABILITY +#include "processor_support.h" +#endif + +#include "gbwt_graph.h" + +using namespace std; + +// From ccnt_lut.cpp, automatically generated by gen_lookup_tables.pl +extern uint8_t cCntLUT_4[4][4][256]; +extern uint8_t cCntLUT_4_rev[4][4][256]; +extern uint8_t cCntBIT[8][256]; + +extern bool threeN; + +static const uint64_t c_table[4] = { + 0xffffffffffffffff, + 0xaaaaaaaaaaaaaaaa, + 0x5555555555555555, + 0x0000000000000000 +}; + +#ifndef VMSG_NL +#define VMSG_NL(...) \ +if(this->verbose()) { \ + stringstream tmp; \ + tmp << __VA_ARGS__ << endl; \ + this->verbose(tmp.str()); \ +} +#endif + +#ifndef VMSG +#define VMSG(...) \ +if(this->verbose()) { \ + stringstream tmp; \ + tmp << __VA_ARGS__; \ + this->verbose(tmp.str()); \ +} +#endif + +/** + * Flags describing type of Ebwt. + */ +enum GFM_FLAGS { + GFM_ENTIRE_REV = 4 // true -> reverse Ebwt is the whole + // concatenated string reversed, rather than + // each stretch reversed +}; + +/** + * Extended Burrows-Wheeler transform header. This together with the + * actual data arrays and other text-specific parameters defined in + * class Ebwt constitute the entire Ebwt. + */ +template +class GFMParams { + +public: + GFMParams() { } + + GFMParams( + index_t len, + index_t gbwtLen, + index_t numNodes, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + index_t eftabLen, + bool entireReverse) + { + init(len, gbwtLen, numNodes, lineRate, offRate, ftabChars, eftabLen, entireReverse); + } + + GFMParams(const GFMParams& gh) { + init(gh._len, gh._gbwtLen, gh._numNodes, gh._lineRate, gh._offRate, + gh._ftabChars, gh._eftabLen, gh._entireReverse); + } + + void init( + index_t len, + index_t gbwtLen, + index_t numNodes, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + index_t eftabLen, + bool entireReverse) + { + _entireReverse = entireReverse; + _linearFM = (len + 1 == gbwtLen || gbwtLen == 0); + _len = len; + _gbwtLen = (gbwtLen == 0 ? len + 1 : gbwtLen); + _numNodes = (numNodes == 0 ? len + 1 : numNodes); + if(_linearFM) { + _sz = (len+3)/4; + _gbwtSz = _gbwtLen/4 + 1; + } else { + _sz = (len+1)/2; + _gbwtSz = _gbwtLen/2 + 1; + } + _lineRate = lineRate; + _origOffRate = offRate; + _offRate = offRate; + _offMask = std::numeric_limits::max() << _offRate; + _ftabChars = ftabChars; + _eftabLen = eftabLen; + _eftabSz = _eftabLen*sizeof(index_t); + _ftabLen = (1 << (_ftabChars*2))+1; + _ftabSz = _ftabLen*sizeof(index_t); + _offsLen = (_numNodes + (1 << _offRate) - 1) >> _offRate; + _offsSz = _offsLen*sizeof(index_t); + _lineSz = 1 << _lineRate; + _sideSz = _lineSz * 1 /* lines per side */; + if(_linearFM) { + _sideGbwtSz = _sideSz - (sizeof(index_t) * 4); + _sideGbwtLen = _sideGbwtSz << 2; + } else { + _sideGbwtSz = _sideSz - (sizeof(index_t) * 6); + _sideGbwtLen = _sideGbwtSz << 1; + } + _numSides = (_gbwtSz+(_sideGbwtSz)-1)/(_sideGbwtSz); + _numLines = _numSides * 1 /* lines per side */; + _gbwtTotLen = _numSides * _sideSz; + _gbwtTotSz = _gbwtTotLen; + assert(repOk()); + } + + index_t len() const { return _len; } + index_t lenNucs() const { return _len; } + index_t gbwtLen() const { return _gbwtLen; } + index_t sz() const { return _sz; } + index_t gbwtSz() const { return _gbwtSz; } + int32_t lineRate() const { return _lineRate; } + int32_t origOffRate() const { return _origOffRate; } + int32_t offRate() const { return _offRate; } + index_t offMask() const { return _offMask; } + int32_t ftabChars() const { return _ftabChars; } + index_t eftabLen() const { return _eftabLen; } + index_t eftabSz() const { return _eftabSz; } + index_t ftabLen() const { return _ftabLen; } + index_t ftabSz() const { return _ftabSz; } + index_t offsLen() const { return _offsLen; } + index_t offsSz() const { return _offsSz; } + index_t lineSz() const { return _lineSz; } + index_t sideSz() const { return _sideSz; } + index_t sideGbtSz() const { return _sideGbwtSz; } + index_t sideGbwtLen() const { return _sideGbwtLen; } + index_t numSides() const { return _numSides; } + index_t numLines() const { return _numLines; } + index_t gbwtTotLen() const { return _gbwtTotLen; } + index_t gbwtTotSz() const { return _gbwtTotSz; } + bool entireReverse() const { return _entireReverse; } + bool linearFM() const { return _linearFM; } + index_t numNodes() const { return _numNodes; } + + /** + * Set a new suffix-array sampling rate, which involves updating + * rate, mask, sample length, and sample size. + */ + void setOffRate(int __offRate) { + _offRate = __offRate; + _offMask = std::numeric_limits::max() << _offRate; + _offsLen = (_gbwtLen + (1 << _offRate) - 1) >> _offRate; + _offsSz = _offsLen * sizeof(index_t); + } + +#ifndef NDEBUG + /// Check that this EbwtParams is internally consistent + bool repOk() const { + // assert_gt(_len, 0); + assert_gt(_lineRate, 3); + assert_geq(_offRate, 0); + assert_leq(_ftabChars, 16); + assert_geq(_ftabChars, 1); + assert_lt(_lineRate, 32); + assert_lt(_ftabChars, 32); + assert_eq(0, _gbwtTotSz % _lineSz); + return true; + } +#endif + + /** + * Pretty-print the header contents to the given output stream. + */ + void print(ostream& out) const { + out << "Headers:" << endl + << " len: " << _len << endl + << " gbwtLen: " << _gbwtLen << endl + << " nodes: " << _numNodes << endl + << " sz: " << _sz << endl + << " gbwtSz: " << _gbwtSz << endl + << " lineRate: " << _lineRate << endl + << " offRate: " << _offRate << endl + << " offMask: 0x" << hex << _offMask << dec << endl + << " ftabChars: " << _ftabChars << endl + << " eftabLen: " << _eftabLen << endl + << " eftabSz: " << _eftabSz << endl + << " ftabLen: " << _ftabLen << endl + << " ftabSz: " << _ftabSz << endl + << " offsLen: " << _offsLen << endl + << " offsSz: " << _offsSz << endl + << " lineSz: " << _lineSz << endl + << " sideSz: " << _sideSz << endl + << " sideGbwtSz: " << _sideGbwtSz << endl + << " sideGbwtLen: " << _sideGbwtLen << endl + << " numSides: " << _numSides << endl + << " numLines: " << _numLines << endl + << " gbwtTotLen: " << _gbwtTotLen << endl + << " gbwtTotSz: " << _gbwtTotSz << endl + << " reverse: " << _entireReverse << endl + << " linearFM: " << (_linearFM ? "Yes" : "No") << endl; + } + + index_t _len; + index_t _gbwtLen; + index_t _sz; + index_t _gbwtSz; + int32_t _lineRate; + int32_t _origOffRate; + int32_t _offRate; + index_t _offMask; + int32_t _ftabChars; + index_t _eftabLen; + index_t _eftabSz; + index_t _ftabLen; + index_t _ftabSz; + index_t _offsLen; + index_t _offsSz; + index_t _lineSz; + index_t _sideSz; + index_t _sideGbwtSz; + index_t _sideGbwtLen; + index_t _numSides; + index_t _numLines; + index_t _gbwtTotLen; + index_t _gbwtTotSz; + bool _entireReverse; + bool _linearFM; + index_t _numNodes; +}; + +/** + * Exception to throw when a file-realted error occurs. + */ +class GFMFileOpenException : public std::runtime_error { +public: + GFMFileOpenException(const std::string& msg = "") : + std::runtime_error(msg) { } +}; + +/** + * Calculate size of file with given name. + */ +static inline int64_t fileSize(const char* name) { + std::ifstream f; + f.open(name, std::ios_base::binary | std::ios_base::in); + if (!f.good() || f.eof() || !f.is_open()) { return 0; } + f.seekg(0, std::ios_base::beg); + std::ifstream::pos_type begin_pos = f.tellg(); + f.seekg(0, std::ios_base::end); + return static_cast(f.tellg() - begin_pos); +} + +/** + * Encapsulates a location in the gbwt text in terms of the side it + * occurs in and its offset within the side. + */ +template +struct SideLocus { + SideLocus() : + _sideByteOff(0), + _sideNum(0), + _charOff(0), + _by(-1), + _bp(-1) { } + + /** + * Construct from row and other relevant information about the Ebwt. + */ + SideLocus(index_t row, const GFMParams& ep, const uint8_t* ebwt) { + initFromRow(row, ep, ebwt); + } + + /** + * Init two SideLocus objects from a top/bot pair, using the result + * from one call to initFromRow to possibly avoid a second call. + */ + static void initFromTopBot( + index_t top, + index_t bot, + const GFMParams& gp, + const uint8_t* gfm, + SideLocus& ltop, + SideLocus& lbot) + { + const index_t sideGbwtLen = gp._sideGbwtLen; + assert_gt(bot, top); + ltop.initFromRow(top, gp, gfm); + index_t spread = bot - top; + // Many cache misses on the following lines + if(ltop._charOff + spread < sideGbwtLen) { + lbot._charOff = ltop._charOff + spread; + lbot._sideNum = ltop._sideNum; + lbot._sideByteOff = ltop._sideByteOff; + lbot._by = lbot._charOff >> 2; + assert_lt(lbot._by, (int)gp._sideGbwtSz); + lbot._bp = lbot._charOff & 0x3; + } else { + lbot.initFromRow(bot, gp, gfm); + } + } + + /** + * Calculate SideLocus based on a row and other relevant + * information about the shape of the Ebwt. + */ + void initFromRow( + index_t row, + const GFMParams& gp, + const uint8_t* gfm) { + const index_t sideSz = gp._sideSz; + // Side length is hard-coded for now; this allows the compiler + // to do clever things to accelerate / and %. + _sideNum = row / gp._sideGbwtLen; + assert_lt(_sideNum, gp._numSides); + _charOff = row % gp._sideGbwtLen; + _sideByteOff = _sideNum * sideSz; + assert_leq(row, gp._gbwtLen); + assert_leq(_sideByteOff + sideSz, gp._gbwtTotSz); + // Tons of cache misses on the next line + _by = _charOff >> 2; // byte within side + assert_lt(_by, (int)gp._sideGbwtSz); + _bp = _charOff & 0x3; // bit-pair within byte + } + + /** + * Init two SideLocus objects from a top/bot pair, using the result + * from one call to initFromRow to possibly avoid a second call. + */ + static void initFromTopBot_bit( + index_t top, + index_t bot, + const GFMParams& gp, + const uint8_t* gfm, + SideLocus& ltop, + SideLocus& lbot) + { + const index_t sideGbwtLen = gp._sideGbwtLen; + // assert_gt(bot, top); + ltop.initFromRow_bit(top, gp, gfm); + index_t spread = bot - top; + // Many cache misses on the following lines + if(ltop._charOff + spread < sideGbwtLen) { + lbot._charOff = ltop._charOff + spread; + lbot._sideNum = ltop._sideNum; + lbot._sideByteOff = ltop._sideByteOff; + lbot._by = lbot._charOff >> 3; + assert_lt(lbot._by, (int)gp._sideGbwtSz); + lbot._bp = lbot._charOff & 0x7; + } else { + lbot.initFromRow_bit(bot, gp, gfm); + } + } + + /** + * Calculate SideLocus based on a row and other relevant + * information about the shape of the Ebwt. + */ + void initFromRow_bit( + index_t row, + const GFMParams& gp, + const uint8_t* gfm) { + const index_t sideSz = gp._sideSz; + // Side length is hard-coded for now; this allows the compiler + // to do clever things to accelerate / and %. + _sideNum = row / gp._sideGbwtLen; + assert_lt(_sideNum, gp._numSides); + _charOff = row % gp._sideGbwtLen; + _sideByteOff = _sideNum * sideSz; + assert_lt(row, gp._gbwtLen); + assert_leq(_sideByteOff + sideSz, gp._gbwtTotSz); + // Tons of cache misses on the next line + _by = _charOff >> 3; // byte within side + assert_lt(_by, (int)gp._sideGbwtSz); + _bp = _charOff & 0x7; // bit-pair within byte + } + + /** + * Transform this SideLocus to refer to the next side (i.e. the one + * corresponding to the next side downstream). Set all cursors to + * point to the beginning of the side. + */ + void nextSide(const GFMParams& gp) { + assert(valid()); + _sideByteOff += gp.sideSz(); + _sideNum++; + _by = _bp = _charOff = 0; + assert(valid()); + } + + /** + * Return true iff this is an initialized SideLocus + */ + bool valid() const { + if(_bp != -1) { + return true; + } + return false; + } + + /** + * Convert locus to BW row it corresponds to. + */ + index_t toBWRow(const GFMParams& gp) const; + +#ifndef NDEBUG + /** + * Check that SideLocus is internally consistent and consistent + * with the (provided) EbwtParams. + */ + bool repOk(const GFMParams& gp) const { + ASSERT_ONLY(index_t row = toBWRow(gp)); + assert_leq(row, gp._gbwtLen); + assert_range(-1, 3, _bp); + assert_range(0, (int)gp._sideGbwtSz, _by); + return true; + } +#endif + + /// Make this look like an invalid SideLocus + void invalidate() { + _bp = -1; + } + + /** + * Return a read-only pointer to the beginning of the top side. + */ + const uint8_t *side(const uint8_t* gbwt) const { + return gbwt + _sideByteOff; + } + + /** + * Return a read-only pointer to the beginning of the top side. + */ + const uint8_t *next_side(const GFMParams& gp, const uint8_t* gbwt) const { + if(_sideByteOff + gp._sideSz < gp._ebwtTotSz) { + return gbwt + _sideByteOff + gp._sideSz; + } else { + return NULL; + } + } + + index_t _sideByteOff; // offset of top side within ebwt[] + index_t _sideNum; // index of side + index_t _charOff; // character offset within side + int32_t _by; // byte within side (not adjusted for bw sides) + int32_t _bp; // bitpair within byte (not adjusted for bw sides) +}; + +/** + * Convert locus to BW row it corresponds to. + */ +template +inline index_t SideLocus::toBWRow(const GFMParams& gp) const { + return _sideNum * (gp._sideGbwtSz << (gp.linearFM() ? 2 : 1)) + _charOff; +} + +#ifdef POPCNT_CAPABILITY // wrapping of "struct" +struct USE_POPCNT_GENERIC { +#endif + // Use this standard bit-bashing population count + inline static int pop64(uint64_t x) { + // Lots of cache misses on following lines (>10K) + x = x - ((x >> 1) & 0x5555555555555555llu); + x = (x & 0x3333333333333333llu) + ((x >> 2) & 0x3333333333333333llu); + x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0Fllu; + x = x + (x >> 8); + x = x + (x >> 16); + x = x + (x >> 32); + return (int)(x & 0x3Fllu); + } +#ifdef POPCNT_CAPABILITY // wrapping a "struct" +}; +#endif + +#ifdef POPCNT_CAPABILITY +struct USE_POPCNT_INSTRUCTION { + inline static int pop64(uint64_t x) { + int64_t count; +#ifdef USING_MSC_COMPILER + count = __popcnt64(x); +#else + asm ("popcntq %[x],%[count]\n": [count] "=&r" (count): [x] "r" (x)); +#endif + return (int)count; + } +}; +#endif + +/** + * Tricky-bit-bashing bitpair counting for given two-bit value (0-3) + * within a 64-bit argument. + */ +#ifdef POPCNT_CAPABILITY +template +#endif +inline static int countInU64(int c, uint64_t dw) { + uint64_t c0 = c_table[c]; + uint64_t x0 = dw ^ c0; + uint64_t x1 = (x0 >> 1); + uint64_t x2 = x1 & (0x5555555555555555); + uint64_t x3 = x0 & x2; +#ifdef POPCNT_CAPABILITY + uint64_t tmp = Operation().pop64(x3); +#else + uint64_t tmp = pop64(x3); +#endif + return (int) tmp; +} + +#ifdef POPCNT_CAPABILITY // wrapping of "struct" +struct USE_POPCNT_GENERIC_BITS { + // Use this standard bit-bashing population count + inline static uint64_t pop64(uint64_t x) { +#else +// Use this standard bit-bashing population count + inline static uint64_t pop6464(uint64_t x) { +#endif + x -= (x >> 1) & 0x5555555555555555ULL; + x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL); + x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL; + return int((x * 0x0101010101010101ULL) >> 56); + } +#ifdef POPCNT_CAPABILITY // wrapping a "struct" +}; +#endif + +/** + * Tricky-bit-bashing bitpair counting for given two-bit value (0-3) + * within a 64-bit argument. + */ +#ifdef POPCNT_CAPABILITY +template +#endif +inline static int countInU64_bits(uint64_t dw) { +#ifdef POPCNT_CAPABILITY + uint64_t tmp = Operation().pop64(dw); +#else + uint64_t tmp = pop6464(dw); +#endif + return (int) tmp; +} + +// Forward declarations for Ebwt class +class GFMSearchParams; + +/** + * Extended Burrows-Wheeler transform data. + * + * An Ebwt may be transferred to and from RAM with calls to + * evictFromMemory() and loadIntoMemory(). By default, a newly-created + * Ebwt is not loaded into memory; if the user would like to use a + * newly-created Ebwt to answer queries, they must first call + * loadIntoMemory(). + */ +template +class GFM { +public: + #define GFM_INITS \ + _toBigEndian(currentlyBigEndian()), \ + _overrideOffRate(overrideOffRate), \ + _verbose(verbose), \ + _passMemExc(passMemExc), \ + _sanity(sanityCheck), \ + fw_(fw), \ + _in1(NULL), \ + _in2(NULL), \ + _nPat(0), \ + _nFrag(0), \ + _plen(EBWT_CAT), \ + _rstarts(EBWT_CAT), \ + _fchr(EBWT_CAT), \ + _ftab(EBWT_CAT), \ + _eftab(EBWT_CAT), \ + _offs(EBWT_CAT), \ + _gfm(EBWT_CAT), \ + _useMm(false), \ + useShmem_(false), \ + _refnames(EBWT_CAT), \ + mmFile1_(NULL), \ + mmFile2_(NULL), \ + _nthreads(1) + + GFM() {} + /// Construct a GFM from the given input file + GFM(const string& in, + ALTDB* altdb, + RepeatDB* repeatdb, + EList* readLens, + int needEntireReverse, + bool fw, + int32_t overrideOffRate, // = -1, + int32_t offRatePlus, // = -1, + bool useMm, // = false, + bool useShmem, // = false, + bool mmSweep, // = false, + bool loadNames, // = false, + bool loadSASamp, // = true, + bool loadFtab, // = true, + bool loadRstarts, // = true, + bool loadSpliceSites, // = true, + bool verbose, // = false, + bool startVerbose, // = false, + bool passMemExc, // = false, + bool sanityCheck, // = false) + bool useHaplotype, // = false + bool skipLoading = false) : + GFM_INITS + { + assert(!useMm || !useShmem); + +#ifdef POPCNT_CAPABILITY + ProcessorSupport ps; + _usePOPCNTinstruction = ps.POPCNTenabled(); +#endif + + packed_ = false; + _useMm = useMm; + useShmem_ = useShmem; + _in1Str = in + ".1." + gfm_ext; + _in2Str = in + ".2." + gfm_ext; + + if(skipLoading) return; + + if(repeatdb == NULL) { + readIntoMemory( + fw ? -1 : needEntireReverse, // need REF_READ_REVERSE + loadSASamp, // load the SA sample portion? + loadFtab, // load the ftab & eftab? + loadRstarts, // load the rstarts array? + true, // stop after loading the header portion? + &_gh, // params + mmSweep, // mmSweep + loadNames, // loadNames + startVerbose); // startVerbose + // If the offRate has been overridden, reflect that in the + // _eh._offRate field + if(offRatePlus > 0 && _overrideOffRate == -1) { + _overrideOffRate = _gh._offRate + offRatePlus; + } + if(_overrideOffRate > _gh._offRate) { + _gh.setOffRate(_overrideOffRate); + assert_eq(_overrideOffRate, _gh._offRate); + } + } + + // Read ALTs + EList >& alts = altdb->alts(); + EList >& haplotypes = altdb->haplotypes(); + EList& altnames = altdb->altnames(); + alts.clear(); altnames.clear(); + string in7Str = in + ".7." + gfm_ext; + string in8Str = in + ".8." + gfm_ext; + + // open alts + if(verbose || startVerbose) cerr << "Opening \"" << in7Str.c_str() << "\"" << endl; + ifstream in7(in7Str.c_str(), ios::binary); + if(!in7.good()) { + cerr << "Could not open index file " << in7Str.c_str() << endl; + } + + EList to_alti; + index_t to_alti_far = 0; + readI32(in7, this->toBe()); + index_t numAlts = readIndex(in7, this->toBe()); + + + // open altnames + if(verbose || startVerbose) cerr << "Opening \"" << in8Str.c_str() << "\"" << endl; + ifstream in8(in8Str.c_str(), ios::binary); + if(!in8.good()) { + cerr << "Could not open index file " << in8Str.c_str() << endl; + } + + readI32(in8, this->toBe()); + index_t numAltnames = readIndex(in8, this->toBe()); + + assert_eq(numAlts, numAltnames); + + if(numAlts > 0) { + alts.resizeExact(numAlts); alts.clear(); + to_alti.resizeExact(numAlts); to_alti.clear(); + while(!in7.eof() && !in8.eof()) { + alts.expand(); + alts.back().read(in7, this->toBe()); + to_alti.push_back(to_alti_far); + to_alti_far++; + + altnames.expand(); + in8 >> altnames.back(); + + if(!loadSpliceSites) { + if(alts.back().splicesite()) { + alts.pop_back(); + assert_gt(numAlts, 0); + altnames.pop_back(); + assert_gt(numAltnames, 0); + numAlts--; + numAltnames--; + to_alti.back() = std::numeric_limits::max(); + to_alti_far--; + } + } + if(alts.size() == numAlts) break; + } + } + assert_eq(alts.size(), numAlts); + assert_eq(to_alti_far, numAlts); + assert_eq(alts.size(), altnames.size()); + // Check if it hits the end of file, and this routine is needed for backward compatibility + if(in7.peek() != std::ifstream::traits_type::eof()) { + index_t numHaplotypes = readIndex(in7, this->toBe()); + if(numHaplotypes > 0) { + haplotypes.resizeExact(numHaplotypes); + haplotypes.clear(); + while(!in7.eof()) { + haplotypes.expand(); + haplotypes.back().read(in7, this->toBe()); + Haplotype& ht = haplotypes.back(); + for(index_t h = 0; h < ht.alts.size(); h++) { + ht.alts[h] = to_alti[ht.alts[h]]; + } + if(haplotypes.size() == numHaplotypes) break; + } + } + if(!useHaplotype) { + haplotypes.nullify(); + } + } + + // Read repeats + _repeat = false; + if(repeatdb != NULL) { + _repeat = true; + + // Number of repeat groups in the index + index_t numRepeatIndex = readIndex(in7, this->toBe()); + assert_gt(numRepeatIndex, 0); + EList > repeatLens; repeatLens.resizeExact(numRepeatIndex); + + for(size_t k = 0; k < numRepeatIndex; k++) { + repeatLens[k].first = readIndex(in7, this->toBe()); + repeatLens[k].second = readIndex(in7, this->toBe()); + } + + if (readLens != NULL && !readLens->empty()) { + // Load subset of repeat groups. + size_t k = 0; + size_t k2 = 0; + + _repeatIncluded.resizeExact(numRepeatIndex); + _repeatIncluded.fillZero(); + + while(k < numRepeatIndex && k2 < readLens->size()) { + if (repeatLens[k].first >= (*readLens)[k2]) { + _repeatIncluded[k] = true; + k2++; + } else { + k++; + } + } + + // at least last repeat group is included + _repeatIncluded[numRepeatIndex - 1] = true; + + _repeatLens.clear(); + for(size_t i = 0; i < numRepeatIndex; i++) { + if (_repeatIncluded[i]) { + _repeatLens.push_back(repeatLens[i]); + } + } + } else { + // Load all repeat groups + _repeatLens = repeatLens; + _repeatIncluded.resizeExact(numRepeatIndex); + _repeatIncluded.fill(true); + } + + repeatdb->read(in7, this->toBe(), _repeatIncluded); + index_t numKmertables = readIndex(in7, this->toBe()); + EList filePos; filePos.resizeExact(numKmertables); + for(size_t k = 0; k < numKmertables; k++) { + filePos[k] = readIndex(in7, this->toBe()); + } + for(size_t k = 0; k < numKmertables; k++) { + if(!_repeatIncluded[k]) + continue; + if(k > 0) { + in7.seekg(filePos[k-1]); + } + _repeat_kmertables.expand(); + _repeat_kmertables.back().read(in7, this->toBe()); + } + in7.seekg(filePos.back()); + } + + in7.close(); + in8.close(); + + // Sort SNPs and Splice Sites based on positions + index_t nalts = (index_t)alts.size(); + for(index_t s = 0; s < nalts; s++) { + ALT alt = alts[s]; + if(alt.snp()) altdb->setSNPs(true); + if(alt.exon()) altdb->setExons(true); + if(alt.splicesite()) { + altdb->setSpliceSites(true); + alts.push_back(alt); + alts.back().left = alt.right; + alts.back().right = alt.left; + altnames.push_back("ssr"); + } else if(alt.deletion()) { + alts.push_back(alt); + alts.back().pos = alt.pos + alt.len - 1; + alts.back().reversed = true; + string altname = altnames[s]; + altnames.push_back(altname); + } + } + if(alts.size() > 1 && alts.size() > nalts) { + assert_eq(alts.size(), altnames.size()); + EList, index_t> > buf; buf.resize(alts.size()); + EList buf2; buf2.resize(alts.size()); + for(size_t i = 0; i < alts.size(); i++) { + buf[i].first = alts[i]; + buf[i].second = (index_t)i; + buf2[i] = altnames[i]; + } + buf.sort(); + for(size_t i = 0; i < alts.size(); i++) { + alts[i] = buf[i].first; + altnames[i] = buf2[buf[i].second]; + if(buf[i].second < numAlts) { + to_alti[buf[i].second] = i; + } + } + } + + if(useHaplotype) { + EList& haplotype_maxrights = altdb->haplotype_maxrights(); + haplotype_maxrights.resizeExact(haplotypes.size()); + for(index_t h = 0; h < haplotypes.size(); h++) { + Haplotype& ht = haplotypes[h]; + for(index_t h2 = 0; h2 < ht.alts.size(); h2++) { + ht.alts[h2] = to_alti[ht.alts[h2]]; + } + if(h == 0) { + haplotype_maxrights[h] = ht.right; + } else { + haplotype_maxrights[h] = std::max(haplotype_maxrights[h - 1], ht.right); + } + } + } + + assert(repeatdb != NULL || repOk()); + } + + /// Construct an Ebwt from the given header parameters and string + /// vector, optionally using a blockwise suffix sorter with the + /// given 'bmax' and 'dcv' parameters. The string vector is + /// ultimately joined and the joined string is passed to buildToDisk(). + GFM( + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + const string& file, // base filename for GFM files + bool fw, + int dcv, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + uint32_t seed, + int32_t overrideOffRate = -1, + bool verbose = false, + bool passMemExc = false, + bool sanityCheck = false) : + GFM_INITS, + _gh( + joinedLen(szs), + 0, + 0, + lineRate, + offRate, + ftabChars, + 0, + refparams.reverse == REF_READ_REVERSE) + { +#ifdef POPCNT_CAPABILITY + ProcessorSupport ps; + _usePOPCNTinstruction = ps.POPCNTenabled(); +#endif + packed_ = packed; + } + + /// Construct an Ebwt from the given header parameters and string + /// vector, optionally using a blockwise suffix sorter with the + /// given 'bmax' and 'dcv' parameters. The string vector is + /// ultimately joined and the joined string is passed to buildToDisk(). + template + GFM( + TStr& s, + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + int nthreads, + const string& snpfile, + const string& htfile, + const string& ssfile, + const string& exonfile, + const string& svfile, + const string& repeatfile, + const string& outfile, // base filename for GFM files + bool fw, + bool useBlockwise, + index_t bmax, + index_t bmaxSqrtMult, + index_t bmaxDivN, + int dcv, + EList& is, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + EList* parent_szs, + EList* parent_refnames, + uint32_t seed, + int32_t overrideOffRate = -1, + bool verbose = false, + bool passMemExc = false, + bool sanityCheck = false) : + GFM_INITS, + _gh( + joinedLen(szs), + 0, + 0, + lineRate, + offRate, + ftabChars, + 0, + refparams.reverse == REF_READ_REVERSE) + { + assert_gt(nthreads, 0); + _nthreads = nthreads; +#ifdef POPCNT_CAPABILITY + ProcessorSupport ps; + _usePOPCNTinstruction = ps.POPCNTenabled(); +#endif + _in1Str = outfile + ".1." + gfm_ext; + _in2Str = outfile + ".2." + gfm_ext; + packed_ = packed; + // Open output files + ofstream fout1(_in1Str.c_str(), ios::binary); + if(!fout1.good()) { + cerr << "Could not open index file for writing: \"" << _in1Str.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + ofstream fout2(_in2Str.c_str(), ios::binary); + if(!fout2.good()) { + cerr << "Could not open index file for writing: \"" << _in2Str.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + + // Build + initFromVector( + s, + snpfile, + htfile, + ssfile, + exonfile, + svfile, + repeatfile, + is, + szs, + sztot, + refparams, + fout1, + fout2, + outfile, + useBlockwise, + bmax, + bmaxSqrtMult, + bmaxDivN, + dcv, + parent_szs, + parent_refnames, + seed, + verbose); + // Close output files + fout1.flush(); + int64_t tellpSz1 = (int64_t)fout1.tellp(); + VMSG_NL("Wrote " << fout1.tellp() << " bytes to primary GFM file: " << _in1Str.c_str()); + fout1.close(); + bool err = false; + if(tellpSz1 > fileSize(_in1Str.c_str())) { + err = true; + cerr << "Index is corrupt: File size for " << _in1Str.c_str() << " should have been " << tellpSz1 + << " but is actually " << fileSize(_in1Str.c_str()) << "." << endl; + } + fout2.flush(); + int64_t tellpSz2 = (int64_t)fout2.tellp(); + VMSG_NL("Wrote " << fout2.tellp() << " bytes to secondary GFM file: " << _in2Str.c_str()); + fout2.close(); + if(tellpSz2 > fileSize(_in2Str.c_str())) { + err = true; + cerr << "Index is corrupt: File size for " << _in2Str.c_str() << " should have been " << tellpSz2 + << " but is actually " << fileSize(_in2Str.c_str()) << "." << endl; + } + if(err) { + cerr << "Please check if there is a problem with the disk or if disk is full." << endl; + throw 1; + } + // Reopen as input streams + VMSG_NL("Re-opening _in1 and _in2 as input streams"); + if(_sanity) { + VMSG_NL("Sanity-checking Bt2"); + assert(!isInMemory()); + readIntoMemory( + fw ? -1 : needEntireReverse, // 1 -> need the reverse to be reverse-of-concat + true, // load SA sample (_offs[])? + true, // load ftab (_ftab[] & _eftab[])? + true, // load r-starts (_rstarts[])? + false, // just load header? + NULL, // Params object to fill + false, // mm sweep? + true, // load names? + false); // verbose startup? + // sanityCheckAll(refparams.reverse); + evictFromMemory(); + assert(!isInMemory()); + } + VMSG_NL("Returning from GFM constructor"); + } + + /** + * Static constructor for a pair of forward/reverse indexes for the + * given reference string. + */ + template + static pair + fromString( + const char* str, + bool packed, + int reverse, + bool bigEndian, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + const string& file, + bool useBlockwise, + index_t bmax, + index_t bmaxSqrtMult, + index_t bmaxDivN, + int dcv, + uint32_t seed, + bool verbose, + bool autoMem, + bool sanity) + { + EList strs(EBWT_CAT); + strs.push_back(std::string(str)); + return fromStrings( + strs, + packed, + reverse, + bigEndian, + lineRate, + offRate, + ftabChars, + file, + useBlockwise, + bmax, + bmaxSqrtMult, + bmaxDivN, + dcv, + seed, + verbose, + autoMem, + sanity); + } + + /** + * Static constructor for a pair of forward/reverse indexes for the + * given list of reference strings. + */ + template + static pair + fromStrings( + const EList& strs, + bool packed, + int reverse, + bool bigEndian, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + const string& file, + bool useBlockwise, + index_t bmax, + index_t bmaxSqrtMult, + index_t bmaxDivN, + int dcv, + uint32_t seed, + bool verbose, + bool autoMem, + bool sanity) + { + assert(!strs.empty()); + EList is(EBWT_CAT); + RefReadInParams refparams(false /* color */, REF_READ_FORWARD, false, false); + // Adapt sequence strings to stringstreams open for input + auto_ptr ss(new stringstream()); + for(index_t i = 0; i < strs.size(); i++) { + (*ss) << ">" << i << endl << strs[i] << endl; + } + auto_ptr fb(new FileBuf(ss.get())); + assert(!fb->eof()); + assert(fb->get() == '>'); + ASSERT_ONLY(fb->reset()); + assert(!fb->eof()); + is.push_back(fb.get()); + // Vector for the ordered list of "records" comprising the input + // sequences. A record represents a stretch of unambiguous + // characters in one of the input sequences. + EList szs(EBWT_CAT); + std::pair sztot; + sztot = BitPairReference::szsFromFasta(is, + file, + bigEndian, + refparams, + szs, + sanity); + // Construct Ebwt from input strings and parameters + GFM *gfmFw = new GFM( + TStr(), + packed, + -1, // fw + lineRate, + offRate, // suffix-array sampling rate + ftabChars, // number of chars in initial arrow-pair calc + file, // basename for .?.ebwt files + true, // fw? + useBlockwise, // useBlockwise + bmax, // block size for blockwise SA builder + bmaxSqrtMult, // block size as multiplier of sqrt(len) + bmaxDivN, // block size as divisor of len + dcv, // difference-cover period + is, // list of input streams + szs, // list of reference sizes + sztot.first, // total size of all unambiguous ref chars + refparams, // reference read-in parameters + seed, // pseudo-random number generator seed + -1, // override offRate + verbose, // be talkative + autoMem, // pass exceptions up to the toplevel so that we can adjust memory settings automatically + sanity); // verify results and internal consistency + refparams.reverse = reverse; + szs.clear(); + sztot = BitPairReference::szsFromFasta(is, + file, + bigEndian, + refparams, + szs, + sanity); + // Construct Ebwt from input strings and parameters + GFM *gfmBw = new GFM( + TStr(), + packed, + reverse == REF_READ_REVERSE, + lineRate, + offRate, // suffix-array sampling rate + ftabChars, // number of chars in initial arrow-pair calc + file + ".rev",// basename for .?.ebwt files + false, // fw? + useBlockwise, // useBlockwise + bmax, // block size for blockwise SA builder + bmaxSqrtMult, // block size as multiplier of sqrt(len) + bmaxDivN, // block size as divisor of len + dcv, // difference-cover period + is, // list of input streams + szs, // list of reference sizes + sztot.first, // total size of all unambiguous ref chars + refparams, // reference read-in parameters + seed, // pseudo-random number generator seed + -1, // override offRate + verbose, // be talkative + autoMem, // pass exceptions up to the toplevel so that we can adjust memory settings automatically + sanity); // verify results and internal consistency + return make_pair(gfmFw, gfmBw); + } + + /// Return true iff the Ebwt is packed + bool isPacked() { return packed_; } + + /** + * Write the rstarts array given the szs array for the reference. + */ + void szsToDisk(const EList& szs, ostream& os, int reverse); + + bool checkPosToSzs(const EList& szs, index_t start_idx, index_t pos) + { + assert(szs[start_idx].first); + for(index_t i = start_idx; i < szs.size(); i++) { + if((i != start_idx) && (szs[i].first)) { + // span to next chr + return false; + } + + if(pos < szs[i].off) { + return false; + } else { + pos -= szs[i].off; + if(pos < szs[i].len) { + return true; + } + pos -= szs[i].len; + } + } + assert(false); + return false; + } + + /** + * Helper for the constructors above. Takes a vector of text + * strings and joins them into a single string with a call to + * joinToDisk, which does a join (with padding) and writes some of + * the resulting data directly to disk rather than keep it in + * memory. It then constructs a suffix-array producer (what kind + * depends on 'useBlockwise') for the resulting sequence. The + * suffix-array producer can then be used to obtain chunks of the + * joined string's suffix array. + */ + template + void initFromVector(TStr& s, + const string& snpfile, + const string& htfile, + const string& ssfile, + const string& exonfile, + const string& svfile, + const string& repeatfile, + EList& is, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + ofstream& out1, + ofstream& out2, + const string& outfile, + bool useBlockwise, + index_t bmax, + index_t bmaxSqrtMult, + index_t bmaxDivN, + int dcv, + EList* parent_szs, + EList* parent_refnames, + uint32_t seed, + bool verbose) + { + // Compose text strings into single string + VMSG_NL("Calculating joined length"); + index_t jlen; + jlen = joinedLen(szs); + _repeat = (parent_szs != NULL); + assert_geq(jlen, sztot); + VMSG_NL("Writing header"); + writeFromMemory(true, out1, out2); + try { + VMSG_NL("Reserving space for joined string"); + s.resize(jlen); + VMSG_NL("Joining reference sequences"); + if(refparams.reverse == REF_READ_REVERSE) { + { + Timer timer(cerr, " Time to join reference sequences: ", _verbose); + joinToDisk(is, szs, sztot, refparams, s, out1, out2); + } { + Timer timer(cerr, " Time to reverse reference sequence: ", _verbose); + EList tmp(EBWT_CAT); + s.reverse(); + reverseRefRecords(szs, tmp, false, verbose); + szsToDisk(tmp, out1, refparams.reverse); + } + } else { + Timer timer(cerr, " Time to join reference sequences: ", _verbose); + joinToDisk(is, szs, sztot, refparams, s, out1, out2); + szsToDisk(szs, out1, refparams.reverse); + } + + { + Timer timer(cerr, " Time to read SNPs and splice sites: ", _verbose); + _alts.clear(); + _altnames.clear(); + EList > chr_szs; + index_t tmp_len = 0; + for(index_t i = 0; i < szs.size(); i++) { + if(szs[i].first) { + chr_szs.expand(); + chr_szs.back().first = tmp_len; + chr_szs.back().second = i; + } + tmp_len += (index_t)szs[i].len; + } + + // Write SNPs into 7.ht2 and 8.ht2 + string file7 = outfile + ".7." + gfm_ext; + string file8 = outfile + ".8." + gfm_ext; + + // Open output stream for the '.7.gfm_ext' file which will + // hold SNPs (except IDs). + ofstream fout7(file7.c_str(), ios::binary); + if(!fout7.good()) { + cerr << "Could not open index file for writing: \"" << file7.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + // Open output stream for the '.8.gfm_ext' file which will + // hold SNP IDs. + ofstream fout8(file8.c_str(), ios::binary); + if(!fout8.good()) { + cerr << "Could not open index file for writing: \"" << file8.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + writeIndex(fout7, 1, this->toBe()); // endianness sentinel + writeIndex(fout8, 1, this->toBe()); // endianness sentinel + + for(index_t i = 0; i < _refnames.size(); i++) { + _refnames_nospace.push_back(""); + for(index_t j = 0; j < _refnames[i].size(); j++) { + char c = _refnames[i][j]; + if(c == ' ') break; + _refnames_nospace.back().push_back(c); + } + } + + map snpID2num; + if(snpfile != "") { + ifstream snp_file(snpfile.c_str(), ios::in); + if(!snp_file.is_open()) { + cerr << "Error: could not open " << snpfile.c_str() << endl; + throw 1; + } + + while(!snp_file.eof()) { + // rs73387790 single 22:20000001-21000000 145 A + string snp_id; + snp_file >> snp_id; + if(snp_id.empty() || snp_id[0] == '#') { + string line; + getline(snp_file, line); + continue; + } + string type, chr; + index_t genome_pos; + char snp_ch = '\0'; + string ins_seq; + index_t del_len = 0; + snp_file >> type >> chr >> genome_pos; + if(type == "single") { + snp_file >> snp_ch; + } else if(type == "deletion") { + snp_file >> del_len; + } else if(type == "insertion") { + snp_file >> ins_seq; + } + index_t chr_idx = 0; + for(; chr_idx < _refnames_nospace.size(); chr_idx++) { + if(chr == _refnames_nospace[chr_idx]) + break; + } + if(chr_idx >= _refnames_nospace.size()) { + continue; + } + assert_eq(chr_szs.size(), _refnames_nospace.size()); + assert_lt(chr_idx, chr_szs.size()); + pair tmp_pair = chr_szs[chr_idx]; + const index_t sofar_len = tmp_pair.first; + const index_t szs_idx = tmp_pair.second; + bool involve_Ns = false; + index_t pos = genome_pos; + index_t add_pos = 0; + assert(szs[szs_idx].first); + for(index_t i = szs_idx; i < szs.size(); i++) { + if(i != szs_idx && szs[i].first) { + break; + } + if(pos < szs[i].off) { + involve_Ns = true; + break; + } else { + pos -= szs[i].off; + if(pos == 0) { + if(type == "deletion" || type == "insertion") { + involve_Ns = true; + break; + } + } + if(pos < szs[i].len) { + break; + } else { + pos -= szs[i].len; + add_pos += szs[i].len; + } + } + } + + if(involve_Ns) { + continue; + } + pos = sofar_len + add_pos + pos; + if(chr_idx + 1 < chr_szs.size()) { + if(pos >= chr_szs[chr_idx + 1].first) { + continue; + } + } else { + if(pos >= jlen){ + continue; + } + } + + _alts.expand(); + ALT& snp = _alts.back(); + snp.pos = pos; + if(type == "single") { + snp.type = ALT_SNP_SGL; + snp_ch = toupper(snp_ch); + if(snp_ch != 'A' && snp_ch != 'C' && snp_ch != 'G' && snp_ch != 'T') { + _alts.pop_back(); + continue; + } + uint64_t bp = asc2dna[(int)snp_ch]; + assert_lt(bp, 4); + if((int)bp == s[pos]) { + if (!threeN) { + cerr << "Warning: single type should have a different base than " << "ACGTN"[(int)s[pos]] + << " (" << snp_id << ") at " << genome_pos << " on " << chr << endl; + } + _alts.pop_back(); + continue; + // throw 1; + } + snp.len = 1; + snp.seq = bp; + } else if(type == "deletion") { + snp.type = ALT_SNP_DEL; + snp.len = del_len; + snp.seq = 0; + snp.reversed = false; + } else if(type == "insertion") { + snp.type = ALT_SNP_INS; + snp.len = (index_t)ins_seq.size(); + if(snp.len > sizeof(snp.seq) * 4) { + _alts.pop_back(); + continue; + } + snp.seq = 0; + bool failed = false; + for(size_t i = 0; i < ins_seq.size(); i++) { + char ch = toupper(ins_seq[i]); + if(ch != 'A' && ch != 'C' && ch != 'G' && ch != 'T') { + failed = true; + break; + } + uint64_t bp = asc2dna[(int)ch]; + assert_lt(bp, 4); + snp.seq = (snp.seq << 2) | bp; + } + if(failed) { + _alts.pop_back(); + continue; + } + } else { + cerr << "Error: unknown snp type " << type << endl; + throw 1; + } + _altnames.push_back(snp_id); + assert_eq(_alts.size(), _altnames.size()); + snpID2num[snp_id] = (index_t)_alts.size() - 1; + } + snp_file.close(); + assert_eq(_alts.size(), _altnames.size()); + } + + _haplotypes.clear(); + if(_alts.size() > 0 && htfile != "") { + ifstream ht_file(htfile.c_str(), ios::in); + if(!ht_file.is_open()) { + cerr << "Error: could not open "<< htfile.c_str() << endl; + throw 1; + } + + while(!ht_file.eof()) { + // ht66 A*01:01:01:01 371 533 66,69,72,75,76,77,84,88,90,92,95 + string ht_id; + ht_file >> ht_id; + if(ht_id.empty() || ht_id[0] == '#') { + string line; + getline(ht_file, line); + continue; + } + string chr, alt_list; + index_t left, right; // inclusive [left, right] + ht_file >> chr >> left >> right >> alt_list; + assert_leq(left, right); + index_t chr_idx = 0; + for(; chr_idx < _refnames_nospace.size(); chr_idx++) { + if(chr == _refnames_nospace[chr_idx]) + break; + } + if(chr_idx >= _refnames_nospace.size()) { + continue; + } + assert_eq(chr_szs.size(), _refnames_nospace.size()); + assert_lt(chr_idx, chr_szs.size()); + pair tmp_pair = chr_szs[chr_idx]; + const index_t sofar_len = tmp_pair.first; + const index_t szs_idx = tmp_pair.second; + bool inside_Ns = false; + index_t add_pos = 0; + assert(szs[szs_idx].first); + for(index_t i = szs_idx; i < szs.size(); i++) { + if(i != szs_idx && szs[i].first) break; + if(left < szs[i].off) { + inside_Ns = true; + break; + } else { + left -= szs[i].off; + right -= szs[i].off; + if(left < szs[i].len) { + if(right >= szs[i].len) { + inside_Ns = true; + } + break; + } else { + left -= szs[i].len; + right -= szs[i].len; + add_pos += szs[i].len; + } + } + } + if(inside_Ns) { + continue; + } + left = sofar_len + add_pos + left; + right = sofar_len + add_pos + right; + if(chr_idx + 1 < chr_szs.size()) { + if(right >= chr_szs[chr_idx + 1].first) { + continue; + } + } else { + if(right >= jlen) { + continue; + } + } + _haplotypes.expand(); + _haplotypes.back().left = left; + _haplotypes.back().right = right; + EList alts; + tokenize(alt_list, ",", alts); + assert_gt(alts.size(), 0); + _haplotypes.back().alts.clear(); + for(size_t i = 0; i < alts.size(); i++) { + const string& alt = alts[i]; + if(snpID2num.find(alt) != snpID2num.end()) { + _haplotypes.back().alts.push_back(snpID2num[alt]); + } + } + if(_haplotypes.back().alts.size() <= 0) { + _haplotypes.pop_back(); + } + } + _haplotypes.sort(); + ht_file.close(); + } else { + for(index_t a = 0; a < _alts.size(); a++) { + const ALT& alt = _alts[a]; + if(!alt.snp()) continue; + _haplotypes.expand(); + _haplotypes.back().left = alt.pos; + if(alt.deletion()) { + _haplotypes.back().right = alt.pos + alt.len - 1; + } else { + _haplotypes.back().right = alt.pos; + } + _haplotypes.back().alts.clear(); + _haplotypes.back().alts.push_back(a); + } + } + + if(ssfile != "") { + ifstream ss_file(ssfile.c_str(), ios::in); + if(!ss_file.is_open()) { + cerr << "Error: could not open " << ssfile.c_str() << endl; + throw 1; + } + map ss_seq; + while(!ss_file.eof()) { + // 22 16062315 16062810 + + string chr; + ss_file >> chr; + if(chr.empty() || chr[0] == '#') { + string line; + getline(ss_file, line); + continue; + } + index_t left, right; + char strand; + ss_file >> left >> right >> strand; + // Convert exonic position to intronic position + left += 1; right -= 1; + if(left >= right) continue; + index_t chr_idx = 0; + for(; chr_idx < _refnames_nospace.size(); chr_idx++) { + if(chr == _refnames_nospace[chr_idx]) + break; + } + if(chr_idx >= _refnames_nospace.size()) continue; + assert_eq(chr_szs.size(), _refnames_nospace.size()); + assert_lt(chr_idx, chr_szs.size()); + pair tmp_pair = chr_szs[chr_idx]; + const index_t sofar_len = tmp_pair.first; + const index_t szs_idx = tmp_pair.second; + + // check whether ambiguous base is in exon's last and first base + if(!checkPosToSzs(szs, szs_idx, left - 1) + || !checkPosToSzs(szs, szs_idx, right + 1)) { + //cerr << "Skip ss. " << chr << ", " << left - 1 << ", " << right + 1 << endl; + continue; + } + + bool inside_Ns = false; + index_t add_pos = 0; + assert(szs[szs_idx].first); + for(index_t i = szs_idx; i < szs.size(); i++) { + if(i != szs_idx && szs[i].first) break; + if(left < szs[i].off) { + inside_Ns = true; + break; + } else { + left -= szs[i].off; + right -= szs[i].off; + if(left < szs[i].len) { + if(right >= szs[i].len) { + inside_Ns = true; + } + break; + } else { + left -= szs[i].len; + right -= szs[i].len; + add_pos += szs[i].len; + } + } + } + if(inside_Ns) continue; + left = sofar_len + add_pos + left; + right = sofar_len + add_pos + right; + if(chr_idx + 1 < chr_szs.size()) { + if(right >= chr_szs[chr_idx + 1].first) continue; + } else { + if(right >= jlen) continue; + } + + // Avoid splice sites in repetitive sequences + // Otherwise, it will likely explode due to an exponential number of combinations + index_t seqlen = 16; assert_leq(seqlen, 16); + if(left >= seqlen && right + 1 + seqlen <= s.length()) { + uint64_t seq = 0; + for(index_t si = left - seqlen; si < left; si++) { + seq = seq << 2 | s[si]; + } + for(index_t si = right + 1; si < right + 1 + seqlen; si++) { + seq = seq << 2 | s[si]; + } + if(_alts.size() > 0) { + if(_alts.back().left == left && + _alts.back().right == right) continue; + } + if(ss_seq.find(seq) == ss_seq.end()) ss_seq[seq] = 1; + else ss_seq[seq]++; + } + + _alts.expand(); + ALT& alt = _alts.back(); + alt.type = ALT_SPLICESITE; + alt.left = left; + alt.right = right; + alt.fw = (strand == '+' ? true : false); + alt.excluded = false; + _altnames.push_back("ss"); + } + ss_file.close(); + assert_eq(_alts.size(), _altnames.size()); + + for(size_t i = 0; i < _alts.size(); i++) { + ALT& alt = _alts[i]; + if(!alt.splicesite()) continue; + index_t seqlen = 16; assert_leq(seqlen, 16); + if(alt.left >= seqlen && alt.right + 1 + seqlen <= s.length()) { + uint64_t seq = 0; + for(index_t si = alt.left - seqlen; si < alt.left; si++) { + seq = seq << 2 | s[si]; + } + for(index_t si = alt.right + 1; si < alt.right + 1 + seqlen; si++) { + seq = seq << 2 | s[si]; + } + assert(ss_seq.find(seq) != ss_seq.end()); + alt.excluded = ss_seq[seq] > 1; + } + } + } + + if(exonfile != "") { + ifstream exon_file(exonfile.c_str(), ios::in); + if(!exon_file.is_open()) { + cerr << "Error: could not open " << ssfile.c_str() << endl; + throw 1; + } + while(!exon_file.eof()) { + // 22 16062156 16062315 + + string chr; + exon_file >> chr; + if(chr.empty() || chr[0] == '#') { + string line; + getline(exon_file, line); + continue; + } + index_t left, right; + char strand; + exon_file >> left >> right >> strand; + // Convert exonic position to intronic position + left += 1; right -= 1; + if(left >= right) continue; + index_t chr_idx = 0; + for(; chr_idx < _refnames_nospace.size(); chr_idx++) { + if(chr == _refnames_nospace[chr_idx]) + break; + } + if(chr_idx >= _refnames_nospace.size()) continue; + assert_eq(chr_szs.size(), _refnames_nospace.size()); + assert_lt(chr_idx, chr_szs.size()); + pair tmp_pair = chr_szs[chr_idx]; + const index_t sofar_len = tmp_pair.first; + const index_t szs_idx = tmp_pair.second; + bool inside_Ns = false; + index_t add_pos = 0; + assert(szs[szs_idx].first); + for(index_t i = szs_idx; i < szs.size(); i++) { + if(i != szs_idx && szs[i].first) break; + if(left < szs[i].off) { + inside_Ns = true; + break; + } else { + left -= szs[i].off; + right -= szs[i].off; + if(left < szs[i].len) { + if(right >= szs[i].len) { + inside_Ns = true; + } + break; + } else { + left -= szs[i].len; + right -= szs[i].len; + add_pos += szs[i].len; + } + } + } + if(inside_Ns) continue; + left = sofar_len + add_pos + left; + right = sofar_len + add_pos + right; + if(chr_idx + 1 < chr_szs.size()) { + if(right >= chr_szs[chr_idx + 1].first) continue; + } else { + if(right >= jlen) continue; + } + + _alts.expand(); + ALT& alt = _alts.back(); + alt.type = ALT_EXON; + alt.left = left; + alt.right = right; + alt.fw = (strand == '+' ? true : false); + _altnames.push_back("exon"); + } + exon_file.close(); + } + + // Todo - implement structural variations + if(svfile != "") { + cerr << "Warning: SV option is not implemented " << svfile.c_str() << endl; + } + + // Sort SNPs and Splice Sites based on positions + if(_alts.size() > 1) { + assert_eq(_alts.size(), _altnames.size()); + EList, index_t> > buf; buf.resize(_alts.size()); + EList buf2; buf2.resize(_alts.size()); + for(size_t i = 0; i < _alts.size(); i++) { + buf[i].first = _alts[i]; + buf[i].second = (index_t)i; + buf2[i] = _altnames[i]; + } + buf.sort(); + for(size_t i = 0; i < _alts.size(); i++) { + _alts[i] = buf[i].first; + _altnames[i] = buf2[buf[i].second]; + } + + EList buf3; buf3.resize(_alts.size()); + for(size_t i = 0; i < buf3.size(); i++) { + index_t before = buf[i].second; + assert_lt(before, buf3.size()); + buf3[before] = (index_t)i; + } + for(size_t h = 0; h < _haplotypes.size(); h++) { + EList& alts = _haplotypes[h].alts; + for(size_t a = 0; a < alts.size(); a++) { + index_t before = alts[a]; + assert_lt(before, buf3.size()); + alts[a] = buf3[before]; + } + } +#ifndef NDEBUG + for(size_t i = 0; i < _alts.size(); i++) { + if(i + 1 < _alts.size()) { + assert(_alts[i] < _alts[i+1]); + } + const ALT& alt = _alts[i]; + if(alt.snp()) { + assert(_altnames[i] != ""); + } else if(alt.splicesite()) { + assert(_altnames[i] == "ss"); + } else if(alt.exon()) { + assert(_altnames[i] == "exon"); + } else { + assert(false); + } + } +#endif + } + + writeIndex(fout7, (index_t)_alts.size(), this->toBe()); + writeIndex(fout8, (index_t)_alts.size(), this->toBe()); + for(index_t i = 0; i < _alts.size(); i++) { + _alts[i].write(fout7, this->toBe()); + fout8 << _altnames[i] << endl; + } + + writeIndex(fout7, (index_t)_haplotypes.size(), this->toBe()); + for(index_t i = 0; i < _haplotypes.size(); i++) { + _haplotypes[i].write(fout7, this->toBe()); + } + + EList >& repeats = _repeatdb.repeats(); + if(_repeat) { + ifstream repeat_file(repeatfile.c_str(), ios::in); + if(!repeat_file.is_open()) { + cerr << "Error: could not open " << ssfile.c_str() << endl; + throw 1; + } + if(parent_szs == NULL) { + throw 1; + } + if(parent_refnames == NULL) { + throw 1; + } + + EList > parent_chr_szs; + index_t tmp_len = 0; + for(index_t i = 0; i < parent_szs->size(); i++) { + if((*parent_szs)[i].first) { + parent_chr_szs.expand(); + parent_chr_szs.back().first = tmp_len; + parent_chr_szs.back().second = i; + } + tmp_len += (index_t)(*parent_szs)[i].len; + } + index_t parent_jlen = joinedLen(*parent_szs); + + string prev_repName = ""; + while(!repeat_file.eof()) { + // >rep1*0 rep 0 100 470 0 + // 20_rep:26622650:+ 20_rep:26628088:+ 20_rep:26632508:+ 20_rep:26635636:+ + // 20_rep:26669936:+ 20_rep:26672654:+ 20_rep:26675373:+ 20_rep:26678095:+ + string repName, repAlleleName; + repeat_file >> repAlleleName; + if(repAlleleName.empty()) // Reached the end of file + break; + if(repAlleleName[0] != '>') { + cerr << "Error: the file format is not correct" << endl; + throw 1; + } + repAlleleName = repAlleleName.substr(1); // Remove '>' + index_t alleleID = 0; + size_t star_pos = repAlleleName.find('*'); + if(star_pos >= repAlleleName.length()) { + repName = repAlleleName; + } else { + repName = repAlleleName.substr(0, star_pos); + string strID = repAlleleName.substr(star_pos + 1); + istringstream(strID) >> alleleID; + } + + string refRepName; + index_t repPos, repLen; + repeat_file >> refRepName >> repPos >> repLen; + index_t rep_idx = 0; + for(; rep_idx < _refnames_nospace.size(); rep_idx++) { + if(refRepName == _refnames_nospace[rep_idx]) + break; + } + if(rep_idx >= _refnames_nospace.size()) { + cerr << "Error: " << refRepName << " is not found in " << endl; + throw 1; + } + + if(repeats.size() == 0 || + repeats.back().repID != rep_idx || + repeats.back().repName != repName) { + if(repeats.size() > 0) { + repeats.back().positions.sort(); + } + repeats.expand(); + repeats.back().init(repName, rep_idx, repPos, repLen); + } + + // update repPos and repLen + if(repPos < repeats.back().repPos) { + repeats.back().repLen += (repeats.back().repPos - repPos); + repeats.back().repPos = repPos; + } + if(repPos + repLen > repeats.back().repPos + repeats.back().repLen) { + repeats.back().repLen = repPos + repLen - repeats.back().repPos; + } + + size_t baseOff = 0; + if(repeats.size() > 1 && repeats[repeats.size() - 2].repID == rep_idx) { + baseOff = repeats[repeats.size() - 2].repPos + repeats[repeats.size() - 2].repLen; + } + + index_t numCoords, numAlts; + repeat_file >> numCoords >> numAlts; + EList snpIDs; + EList snpStrIDs; + if(numAlts > 0) { + string snpStrID; + repeat_file >> snpStrID; + tokenize(snpStrID, ",", snpStrIDs); + if(snpStrIDs.size() != numAlts) { + assert(false); + cerr << "Error: the number of SNPs (" << snpIDs.size() << ", " << snpStrID << ") does not equal to " << numAlts << endl; + throw 1; + } + for(index_t i = 0; i < snpStrIDs.size(); i++) { + if(snpID2num.find(snpStrIDs[i]) == snpID2num.end()) { + cerr << "Error: " << snpStrIDs[i] << " is not found" << endl; + throw 1; + } + index_t numID = snpID2num[snpStrIDs[i]]; + snpIDs.push_back(numID); + } + } + + EList >& positions = repeats.back().positions; + size_t sofar_numCoords = positions.size(); + while(positions.size() - sofar_numCoords < numCoords) { + string chr_pos; + repeat_file >> chr_pos; + size_t colon_pos = chr_pos.find(':'); + if(colon_pos + 1 >= chr_pos.length()) { + cerr << "Error: : is not found in " << chr_pos << endl; + throw 1; + } + string chr = chr_pos.substr(0, colon_pos); + string strPos = chr_pos.substr(colon_pos + 1, chr_pos.length() - colon_pos - 3); + bool repfw = (chr_pos[chr_pos.length() - 1] == '+'); + index_t pos = 0; + istringstream(strPos) >> pos; + index_t chr_idx = 0; + for(; chr_idx < parent_refnames->size(); chr_idx++) { + if(chr == (*parent_refnames)[chr_idx]) + break; + } + if(chr_idx >= parent_refnames->size()) { + cerr << "Error: " << chr << " is not found in " << endl; + throw 1; + } + assert_eq(parent_chr_szs.size(), parent_refnames->size()); + assert_lt(chr_idx, parent_chr_szs.size()); + + positions.expand(); + positions.back().tid = chr_idx; + positions.back().toff = pos; + positions.back().fw = repfw; + positions.back().alleleID = alleleID; + + pair tmp_pair = parent_chr_szs[chr_idx]; + const index_t sofar_len = tmp_pair.first; + const index_t szs_idx = tmp_pair.second; + bool involve_Ns = false; + index_t add_pos = 0; + assert((*parent_szs)[szs_idx].first); + for(index_t i = szs_idx; i < parent_szs->size(); i++) { + if(i != szs_idx && (*parent_szs)[i].first) { + break; + } + if(pos < (*parent_szs)[i].off) { + involve_Ns = true; + break; + } else { + pos -= (*parent_szs)[i].off; + if(pos < (*parent_szs)[i].len) { + break; + } else { + pos -= (*parent_szs)[i].len; + add_pos += (*parent_szs)[i].len; + } + } + } + if(involve_Ns) { + assert(false); + throw 1; + } + pos = sofar_len + add_pos + pos; + if(chr_idx + 1 < parent_chr_szs.size()) { + if(pos >= parent_chr_szs[chr_idx + 1].first) { + assert(false); + throw 1; + } + } else { + if(pos >= parent_jlen){ + assert(false); + throw 1; + } + } + + positions.back().joinedOff = pos; + } + repeats.back().alleles.expand(); + assert_geq(repPos, baseOff); + repeats.back().alleles.back().init(repPos - baseOff, repLen); + + } + if(repeats.size() > 0) { + repeats.back().positions.sort(); + } + repeat_file.close(); + + index_t total_repeat_len = 0; + for(size_t r = 0; r + 1 < repeats.size(); r++) { + if(repeats[r].repID != repeats[r+1].repID) { + index_t repeat_len = repeats[r].repPos + repeats[r].repLen; + total_repeat_len += repeat_len; + } + } + index_t repeat_len = repeats.back().repPos + repeats.back().repLen; + total_repeat_len += repeat_len; + if(total_repeat_len != s.length()) { + cerr << "Error: repeat length (" << repeats.back().repPos + repeats.back().repLen; + cerr << ") does not match sequence length (" << s.length() << ")" << endl; + throw 1; + } + + _repeatLens.resizeExact(szs.size()); + for(size_t i = 0; i < _repeatLens.size(); i++) { + _repeatLens[i].first = numeric_limits::max(); + _repeatLens[i].second = 0; + } + for(size_t i = 0; i < repeats.size(); i++) { + index_t id = repeats[i].repID; + index_t len = repeats[i].repLen; + assert_lt(id, _repeatLens.size()); + if(_repeatLens[id].first > len) { + _repeatLens[id].first = len; + } + if(_repeatLens[id].second < len) { + _repeatLens[id].second = len; + } + } + + writeIndex(fout7, _repeatLens.size(), this->toBe()); + for(size_t i = 0; i < _repeatLens.size(); i++) { + writeIndex(fout7, _repeatLens[i].first, this->toBe()); + writeIndex(fout7, _repeatLens[i].second, this->toBe()); + } + _repeatdb.write(fout7, this->toBe()); + writeIndex(fout7, chr_szs.size(), this->toBe()); // number of repeat indexes + EList seqs; + EList tableFilePos; + streampos filepos = fout7.tellp(); + for(size_t i = 0; i < chr_szs.size(); i++) { + writeIndex(fout7, 0, this->toBe()); + } + for(size_t i = 0; i < repeats.size(); i++) { + const Repeat& repeat = repeats[i]; + assert_lt(repeat.repID, chr_szs.size()); + index_t template_len = 0; + if(repeat.repID + 1 < chr_szs.size()) { + template_len = chr_szs[repeat.repID + 1].first - chr_szs[repeat.repID].first; + } else { + template_len = s.length() - chr_szs[repeat.repID].first; + } + assert_leq(repeat.repPos + repeat.repLen, template_len); + index_t pos = chr_szs[repeat.repID].first + repeat.repPos; + assert_leq(pos + repeat.repLen, s.length()); + seqs.expand(); + seqs.back().clear(); + for(index_t j = 0; j < repeat.repLen; j++) { + int c = s[pos + j]; + assert_range(0, 3, c); + seqs.back().push_back("ACGT"[c]); + } + + if(i + 1 == repeats.size() || repeats[i].repID != repeats[i+1].repID) { + const size_t w = RB_Minimizer::default_w, k = RB_Minimizer::default_k; + RB_KmerTable kmer_table; + kmer_table.build(seqs, w, k); + kmer_table.write(fout7, this->toBe()); + seqs.clear(); + tableFilePos.push_back(fout7.tellp()); + } + } + assert_eq(tableFilePos.size(), chr_szs.size()); + streampos origpos = fout7.tellp(); + fout7.seekp(filepos); + for(size_t i = 0; i < tableFilePos.size(); i++) { + writeIndex(fout7, tableFilePos[i], this->toBe()); + } + fout7.seekp(origpos); + } + + fout7.close(); + fout8.close(); + } + // Joined reference sequence now in 's' + } catch(bad_alloc& e) { + // If we throw an allocation exception in the try block, + // that means that the joined version of the reference + // string itself is too larger to fit in memory. The only + // alternatives are to tell the user to give us more memory + // or to try again with a packed representation of the + // reference (if we haven't tried that already). + cerr << "Could not allocate space for a joined string of " << jlen << " elements." << endl; + if(!isPacked() && _passMemExc) { + // Pass the exception up so that we can retry using a + // packed string representation + throw e; + } + // There's no point passing this exception on. The fact + // that we couldn't allocate the joined string means that + // --bmax is irrelevant - the user should re-run with + // ebwt-build-packed + if(isPacked()) { + cerr << "Please try running bowtie-build on a computer with more memory." << endl; + } else { + cerr << "Please try running bowtie-build in packed mode (-p/--packed) or in automatic" << endl + << "mode (-a/--auto), or try again on a computer with more memory." << endl; + } + if(sizeof(void*) == 4) { + cerr << "If this computer has more than 4 GB of memory, try using a 64-bit executable;" << endl + << "this executable is 32-bit." << endl; + } + throw 1; + } + + // Succesfully obtained joined reference string + assert_geq(s.length(), jlen); + if(bmax != (index_t)OFF_MASK) { + // VMSG_NL("bmax according to bmax setting: " << bmax); + } + else if(bmaxSqrtMult != (index_t)OFF_MASK) { + bmax *= bmaxSqrtMult; + // VMSG_NL("bmax according to bmaxSqrtMult setting: " << bmax); + } + else if(bmaxDivN != (index_t)OFF_MASK) { + bmax = max(jlen / (bmaxDivN * _nthreads), 1); + // VMSG_NL("bmax according to bmaxDivN setting: " << bmax); + } + else { + bmax = (uint32_t)sqrt(s.length()); + // VMSG_NL("bmax defaulted to: " << bmax); + } + + int iter = 0; + bool first = true; + streampos out1pos = out1.tellp(); + streampos out2pos = out2.tellp(); + + if(!_repeat) { + // Look for bmax/dcv parameters that work. + while(true) { + if(!first && bmax < 40 && _passMemExc) { + cerr << "Could not find approrpiate bmax/dcv settings for building this index." << endl; + if(!isPacked()) { + // Throw an exception exception so that we can + // retry using a packed string representation + throw bad_alloc(); + } else { + cerr << "Already tried a packed string representation." << endl; + } + cerr << "Please try indexing this reference on a computer with more memory." << endl; + if(sizeof(void*) == 4) { + cerr << "If this computer has more than 4 GB of memory, try using a 64-bit executable;" << endl + << "this executable is 32-bit." << endl; + } + throw 1; + } + if(!first) { + out1.seekp(out1pos); + out2.seekp(out2pos); + } + if(dcv > 4096) dcv = 4096; + if((iter % 6) == 5 && dcv < 4096 && dcv != 0) { + dcv <<= 1; // double difference-cover period + } else { + bmax -= (bmax >> 2); // reduce by 25% + } + iter++; + try { + if(_alts.empty()) { + VMSG("Using parameters --bmax " << bmax); + if(dcv == 0) { + VMSG_NL(" and *no difference cover*"); + } else { + VMSG_NL(" --dcv " << dcv); + } + { + VMSG_NL(" Doing ahead-of-time memory usage test"); + // Make a quick-and-dirty attempt to force a bad_alloc iff + // we would have thrown one eventually as part of + // constructing the DifferenceCoverSample + dcv <<= 1; + index_t sz = (index_t)DifferenceCoverSample::simulateAllocs(s, dcv >> 1); + if(_nthreads > 1) sz *= (_nthreads + 1); + AutoArray tmp(sz, EBWT_CAT); + dcv >>= 1; + // Likewise with the KarkkainenBlockwiseSA + sz = (index_t)KarkkainenBlockwiseSA::simulateAllocs(s, bmax); + AutoArray tmp2(sz, EBWT_CAT); + // Now throw in the 'ftab' and 'isaSample' structures + // that we'll eventually allocate in buildToDisk + AutoArray ftab(_gh._ftabLen * 2, EBWT_CAT); + AutoArray side(_gh._sideSz, EBWT_CAT); + // Grab another 20 MB out of caution + AutoArray extra(20*1024*1024, EBWT_CAT); + // If we made it here without throwing bad_alloc, then we + // passed the memory-usage stress test + VMSG(" Passed! Constructing with these parameters: --bmax " << bmax << " --dcv " << dcv); + if(isPacked()) { + VMSG(" --packed"); + } + VMSG_NL(""); + } + VMSG_NL("Constructing suffix-array element generator"); + KarkkainenBlockwiseSA bsa(s, bmax, _nthreads, dcv, seed, _sanity, _passMemExc, _verbose, outfile); + assert(bsa.suffixItrIsReset()); + assert_eq(bsa.size(), s.length()+1); + VMSG_NL("Converting suffix-array elements to index image"); + buildToDisk(bsa, s, out1, out2); + } else { + RefGraph* graph = new RefGraph( + s, + szs, + _alts, + _haplotypes, + outfile, + _nthreads, + verbose); + PathGraph* pg = new PathGraph( + *graph, + outfile, + std::numeric_limits::max(), + _nthreads, + verbose); + + if(verbose) { cerr << "Generating edges... " << endl; } + if(!pg->generateEdges(*graph)) { return; } + // Re-initialize GFM parameters to reflect real number of edges (gbwt string) + _gh.init( + _gh.len(), + pg->getNumEdges(), + pg->getNumNodes(), + _gh.lineRate(), + _gh.offRate(), + _gh.ftabChars(), + 0, + _gh.entireReverse()); + buildToDisk(*pg, s, out1, out2); + delete pg; pg = NULL; + delete graph; graph = NULL; + } + out1.flush(); out2.flush(); + if(out1.fail() || out2.fail()) { + cerr << "An error occurred writing the index to disk. Please check if the disk is full." << endl; + throw 1; + } + break; + } catch(bad_alloc& e) { + if(_passMemExc) { + VMSG_NL(" Ran out of memory; automatically trying more memory-economical parameters."); + } else { + cerr << "Out of memory while constructing suffix array. Please try using a smaller" << endl + << "number of blocks by specifying a smaller --bmax or a larger --bmaxdivn" << endl; + throw 1; + } + } + first = false; + } + assert(repOk()); + + // Now write reference sequence names on the end + assert_eq(this->_refnames.size(), this->_nPat); + for(index_t i = 0; i < this->_refnames.size(); i++) { + out1 << this->_refnames[i].c_str() << endl; + } + out1 << '\0'; + out1.flush(); out2.flush(); + if(out1.fail() || out2.fail()) { + cerr << "An error occurred writing the index to disk. Please check if the disk is full." << endl; + throw 1; + } + } + VMSG_NL("Returning from initFromVector"); + } + + /** + * Return the length that the joined string of the given string + * list will have. Note that this is indifferent to how the text + * fragments correspond to input sequences - it just cares about + * the lengths of the fragments. + */ + index_t joinedLen(EList& szs) { + index_t ret = 0; + for(unsigned int i = 0; i < szs.size(); i++) { + ret += (index_t)szs[i].len; + } + return ret; + } + + /// Destruct an Ebwt + ~GFM() { + _fchr.reset(); + _ftab.reset(); + _eftab.reset(); + _plen.reset(); + _rstarts.reset(); + _offs.reset(); + _gfm.reset(); + if(offs() != NULL && useShmem_) { + FREE_SHARED(offs()); + } + if(gfm() != NULL && useShmem_) { + FREE_SHARED(gfm()); + } + if (_in1 != NULL) fclose(_in1); + if (_in2 != NULL) fclose(_in2); + } + + /// Accessors + inline const GFMParams& gh() const { return _gh; } + index_t numZOffs() const { return _zOffs.size(); } + index_t zOff(index_t i) const { assert_lt(i, _zOffs.size()); return _zOffs[i]; } + index_t zGbwtByteOff(index_t i) const { assert_lt(i, _zGbwtByteOffs.size()); return _zGbwtByteOffs[i]; } + int zGbwtBpOff(index_t i) const { assert_lt(i, _zGbwtBpOffs.size()); return _zGbwtBpOffs[i]; } + index_t nPat() const { return _nPat; } + index_t nFrag() const { return _nFrag; } + inline index_t* fchr() { return _fchr.get(); } + inline index_t* ftab() { return _ftab.get(); } + inline index_t* eftab() { return _eftab.get(); } + inline index_t* offs() { return _offs.get(); } + inline index_t* plen() { return _plen.get(); } + inline index_t* rstarts() { return _rstarts.get(); } + inline uint8_t* gfm() { return _gfm.get(); } + inline const index_t* fchr() const { return _fchr.get(); } + inline const index_t* ftab() const { return _ftab.get(); } + inline const index_t* eftab() const { return _eftab.get(); } + inline const index_t* offs() const { return _offs.get(); } + inline const index_t* plen() const { return _plen.get(); } + inline const index_t* rstarts() const { return _rstarts.get(); } + inline const uint8_t* gfm() const { return _gfm.get(); } + inline const EList >& alts() const { return _alts; } + inline const EList& altnames() const { return _altnames; } + bool toBe() const { return _toBigEndian; } + bool verbose() const { return _verbose; } + bool sanityCheck() const { return _sanity; } + EList& refnames() { return _refnames; } + bool fw() const { return fw_; } + bool repeat() const { return _repeat; } + const EList& getRepeatIncluded() const { return _repeatIncluded; } + +#ifdef POPCNT_CAPABILITY + bool _usePOPCNTinstruction; +#endif + + /** + * Returns true iff the index contains the given string (exactly). The + * given string must contain only unambiguous characters. TODO: + * support skipping of ambiguous characters. + */ + bool contains( + const BTDnaString& str, + index_t *top = NULL, + index_t *bot = NULL) const; + + /** + * Returns true iff the index contains the given string (exactly). The + * given string must contain only unambiguous characters. TODO: + * support skipping of ambiguous characters. + */ + bool contains( + const char *str, + index_t *top = NULL, + index_t *bot = NULL) const + { + return contains(BTDnaString(str, true), top, bot); + } + + /// Return true iff the Ebwt is currently in memory + bool isInMemory() const { + if(gfm() != NULL) { + // Note: We might have skipped loading _offs, _ftab, + // _eftab, and _rstarts depending on whether this is the + // reverse index and what algorithm is being used. + assert(_gh.repOk()); + //assert(_ftab != NULL); + //assert(_eftab != NULL); + assert(fchr() != NULL); + //assert(_offs != NULL); + //assert(_rstarts != NULL); + // assert_neq(_zGbwtByteOff, INDEX_MAX); + // assert_neq(_zGbwtBpOff, -1); + return true; + } else { + assert(ftab() == NULL); + assert(eftab() == NULL); + assert(fchr() == NULL); + assert(offs() == NULL); + assert(rstarts() == NULL); + assert_eq(_zOffs.size(), 0); + assert_eq(_zGbwtByteOffs.size(), 0); + assert_eq(_zGbwtBpOffs.size(), 0); + return false; + } + } + + /// Return true iff the Ebwt is currently stored on disk + bool isEvicted() const { + return !isInMemory(); + } + + /** + * Load this Ebwt into memory by reading it in from the _in1 and + * _in2 streams. + */ + void loadIntoMemory( + int needEntireReverse, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool loadNames, + bool verbose) + { + readIntoMemory( + needEntireReverse, // require reverse index to be concatenated reference reversed + loadSASamp, // load the SA sample portion? + loadFtab, // load the ftab (_ftab[] and _eftab[])? + loadRstarts, // load the r-starts (_rstarts[])? + false, // stop after loading the header portion? + NULL, // params + false, // mmSweep + loadNames, // loadNames + verbose); // startVerbose + } + + /** + * Frees memory associated with the Ebwt. + */ + void evictFromMemory() { + assert(isInMemory()); + _fchr.free(); + _ftab.free(); + _eftab.free(); + _rstarts.free(); + _offs.free(); // might not be under control of APtrWrap + _gfm.free(); // might not be under control of APtrWrap + // Keep plen; it's small and the client may want to seq it + // even when the others are evicted. + //_plen = NULL; + _zOffs.clear(); + _zGbwtByteOffs.clear(); + _zGbwtBpOffs.clear(); + } + + /** + * Turn a substring of 'seq' starting at offset 'off' and having + * length equal to the index's 'ftabChars' into an int that can be + * used to index into the ftab array. + */ + index_t ftabSeqToInt( + const BTDnaString& seq, + index_t off, + bool rev) const + { + int fc = _gh._ftabChars; + index_t lo = off, hi = lo + fc; + assert_leq(hi, seq.length()); + index_t ftabOff = 0; + for(int i = 0; i < fc; i++) { + bool fwex = fw(); + if(rev) fwex = !fwex; + // We add characters to the ftabOff in the order they would + // have been consumed in a normal search. For BWT, this + // means right-to-left order; for BWT' it's left-to-right. + int c = (fwex ? seq[lo + i] : seq[hi - i - 1]); + if(c > 3) { + return std::numeric_limits::max(); + } + assert_range(0, 3, c); + ftabOff <<= 2; + ftabOff |= c; + } + return ftabOff; + } + + /** + * Non-static facade for static function ftabHi. + */ + index_t ftabHi(index_t i) const { + return GFM::ftabHi( + ftab(), + eftab(), + _gh.linearFM() ? _gh._len : _gh._gbwtLen, + _gh._ftabLen, + _gh._eftabLen, + i); + } + + /** + * Get "high interpretation" of ftab entry at index i. The high + * interpretation of a regular ftab entry is just the entry + * itself. The high interpretation of an extended entry is the + * second correpsonding ui32 in the eftab. + * + * It's a static member because it's convenient to ask this + * question before the Ebwt is fully initialized. + */ + static index_t ftabHi( + const index_t *ftab, + const index_t *eftab, + index_t gbwtLen, + index_t ftabLen, + index_t eftabLen, + index_t i) + { + assert_lt(i, ftabLen); + if(ftab[i] <= gbwtLen) { + return ftab[i]; + } else { + index_t efIdx = ftab[i] ^ (index_t)INDEX_MAX; + assert_lt(efIdx*2+1, eftabLen); + return eftab[efIdx*2+1]; + } + } + + /** + * Non-static facade for static function ftabLo. + */ + index_t ftabLo(index_t i) const { + return GFM::ftabLo( + ftab(), + eftab(), + _gh.linearFM() ? _gh._len : _gh._gbwtLen, + _gh._ftabLen, + _gh._eftabLen, + i); + } + + /** + * Get low bound of ftab range. + */ + index_t ftabLo(const BTDnaString& seq, index_t off) const { + return ftabLo(ftabSeqToInt(seq, off, false)); + } + + /** + * Get high bound of ftab range. + */ + index_t ftabHi(const BTDnaString& seq, index_t off) const { + return ftabHi(ftabSeqToInt(seq, off, false)); + } + + /** + * Extract characters from seq starting at offset 'off' and going either + * forward or backward, depending on 'rev'. Order matters when compiling + * the integer that gets looked up in the ftab. Each successive character + * is ORed into the least significant bit-pair, and characters are + * integrated in the direction of the search. + */ + bool + ftabLoHi( + const BTDnaString& seq, // sequence to extract from + index_t off, // offset into seq to begin extracting + bool rev, // reverse while extracting + index_t& top, + index_t& bot) const + { + index_t fi = ftabSeqToInt(seq, off, rev); + if(fi == std::numeric_limits::max()) { + return false; + } + top = ftabHi(fi); + bot = ftabLo(fi+1); + assert_geq(bot, top); + return true; + } + + /** + * Get "low interpretation" of ftab entry at index i. The low + * interpretation of a regular ftab entry is just the entry + * itself. The low interpretation of an extended entry is the + * first correpsonding ui32 in the eftab. + * + * It's a static member because it's convenient to ask this + * question before the Ebwt is fully initialized. + */ + static index_t ftabLo( + const index_t *ftab, + const index_t *eftab, + index_t gbwtLen, + index_t ftabLen, + index_t eftabLen, + index_t i) + { + assert_lt(i, ftabLen); + if(ftab[i] <= gbwtLen) { + return ftab[i]; + } else { + index_t efIdx = ftab[i] ^ (index_t)INDEX_MAX; + assert_lt(efIdx*2+1, eftabLen); + return eftab[efIdx*2]; + } + } + + /** + * Try to resolve the reference offset of the BW element 'elt'. If + * it can be resolved immediately, return the reference offset. If + * it cannot be resolved immediately, return 0xffffffff. + */ + index_t tryOffset(index_t elt, index_t node) const { + assert(offs() != NULL); + for(index_t i = 0; i < _zOffs.size(); i++) { + if(elt == _zOffs[i]) return 0; + } + if((node & _gh._offMask) == node) { + index_t nodeOff = node >> _gh._offRate; + assert_lt(nodeOff, _gh._offsLen); + index_t off = offs()[nodeOff]; + return off; + } else { + // Try looking at zoff + return (index_t)INDEX_MAX; + } + } + + /** + * Try to resolve the reference offset of the BW element 'elt' such + * that the offset returned is at the right-hand side of the + * forward reference substring involved in the hit. + */ + index_t tryOffset( + index_t elt, + bool fw, + index_t hitlen) const + { + index_t off = tryOffset(elt); + if(off != (index_t)INDEX_MAX && !fw) { + assert_lt(off, _gh._len); + off = _gh._len - off - 1; + assert_geq(off, hitlen-1); + off -= (hitlen-1); + assert_lt(off, _gh._len); + } + return off; + } + + /** + * Walk 'steps' steps to the left and return the row arrived at. + */ + index_t walkLeft(index_t row, index_t steps) const; + + /** + * Resolve the reference offset of the BW element 'elt'. + */ + index_t getOffset(index_t row, index_t node = 0) const; + + /** + * Resolve the reference offset of the BW element 'elt' such that + * the offset returned is at the right-hand side of the forward + * reference substring involved in the hit. + */ + index_t getOffset( + index_t elt, + bool fw, + index_t hitlen) const; + + /** + * When using read() to create an Ebwt, we have to set a couple of + * additional fields in the Ebwt object that aren't part of the + * parameter list and are not stored explicitly in the file. Right + * now, this just involves initializing _zEbwtByteOff and + * _zEbwtBpOff from _zOff. + */ + void postReadInit(const GFMParams& gh) { + _zGbwtByteOffs.resizeExact(_zOffs.size()); + _zGbwtBpOffs.resizeExact(_zOffs.size()); + for(index_t i = 0; i < _zOffs.size(); i++) { + index_t sideNum = _zOffs[i] / gh._sideGbwtLen; + index_t sideCharOff = _zOffs[i] % gh._sideGbwtLen; + index_t sideByteOff = sideNum * gh._sideSz; + _zGbwtByteOffs[i] = sideCharOff >> 2; + assert_lt(_zGbwtByteOffs[i], gh._sideGbwtSz); + _zGbwtBpOffs[i] = sideCharOff & 3; + assert_lt(_zGbwtBpOffs[i], 4); + _zGbwtByteOffs[i] += sideByteOff; + } + assert(repOk(gh)); // Ebwt should be fully initialized now + } + + /** + * Given basename of an Ebwt index, read and return its flag. + */ + static int32_t readVersionFlags(const string& instr, int& major, int& minor, string& extra_version); + + static void readProgramVersion(int& major_version, int& minor_version, string& extra_version) { + char extra[256] = {0,}; + int second_version; + sscanf(HISAT2_VERSION, "%d.%d.%d-%s", + &second_version, + &major_version, + &minor_version, + extra); + extra_version = extra; + } + + static void readIndexVersion(int index_version, int& major_version, int& minor_version, string& extra_version) { + major_version = (index_version >> 16) & 0xff; + minor_version = (index_version >> 8) & 0xff; + if((index_version & 0xff) == 1) { + extra_version = "alpha"; + } else if((index_version & 0xff) == 2) { + extra_version = "beta"; + } else { + extra_version = ""; + } + } + + static int getIndexVersion() { + int major_version = 0, minor_version = 0; + string extra_version; + readProgramVersion(major_version, minor_version, extra_version); + int version = 2; // HISAT2 + version = (version << 8) | (major_version & 0xff); + version = (version << 8) | (minor_version & 0xff); + version = version << 8; + if(extra_version == "alpha") { + version |= 0x1; + } else if(extra_version == "beta") { + version |= 0x2; + } + return version; + } + + /** + * Pretty-print the Ebwt to the given output stream. + */ + void print(ostream& out) const { + print(out, _gh); + } + + /** + * Pretty-print the Ebwt and given EbwtParams to the given output + * stream. + */ + void print(ostream& out, const GFMParams& gh) const { + gh.print(out); // print params + return; + out << "Ebwt (" << (isInMemory()? "memory" : "disk") << "):" << endl; + for(index_t i = 0; i < _zOffs.size(); i++) { + out << " " << (i+1) << " zOffs: " << _zOffs[i] << endl + << " " << (i+1) << " zGbwtByteOff: " << _zGbwtByteOffs[i] << endl + << " " << (i+1) << " zGbwtBpOff: " << _zGbwtBpOffs[i] << endl; + } + out << " nPat: " << _nPat << endl + << " plen: "; + if(plen() == NULL) { + out << "NULL" << endl; + } else { + out << "non-NULL, [0] = " << plen()[0] << endl; + } + out << " rstarts: "; + if(rstarts() == NULL) { + out << "NULL" << endl; + } else { + out << "non-NULL, [0] = " << rstarts()[0] << endl; + } + out << " ebwt: "; + if(gfm() == NULL) { + out << "NULL" << endl; + } else { + out << "non-NULL, [0] = " << gfm()[0] << endl; + } + out << " fchr: "; + if(fchr() == NULL) { + out << "NULL" << endl; + } else { + out << "non-NULL, [0] = " << fchr()[0] << endl; + } + out << " ftab: "; + if(ftab() == NULL) { + out << "NULL" << endl; + } else { + out << "non-NULL, [0] = " << ftab()[0] << endl; + } + out << " eftab: "; + if(eftab() == NULL) { + out << "NULL" << endl; + } else { + out << "non-NULL, [0] = " << eftab()[0] << endl; + } + out << " offs: "; + if(offs() == NULL) { + out << "NULL" << endl; + } else { + out << "non-NULL, [0] = " << offs()[0] << endl; + } + } + + // Building + template static TStr join(EList& l, uint32_t seed); + template static void join(EList& l, EList& szs, index_t sztot, const RefReadInParams& refparams, uint32_t seed, TStr& s, bool include_rc = false, bool CGtoTG = false); + template void joinToDisk(EList& l, EList& szs, index_t sztot, const RefReadInParams& refparams, TStr& ret, ostream& out1, ostream& out2); + template void buildToDisk(PathGraph& gbwt, const TStr& s, ostream& out1, ostream& out2, streampos headerPos = -1); + template void buildToDisk(InorderBlockwiseSA& sa, const TStr& s, ostream& out1, ostream& out2, streampos headerPos = -1); + + // I/O + void readIntoMemory(int needEntireRev, bool loadSASamp, bool loadFtab, bool loadRstarts, bool justHeader, GFMParams *params, bool mmSweep, bool loadNames, bool startVerbose, bool subIndex = false); + void writeFromMemory(bool justHeader, ostream& out1, ostream& out2) const; + void writeFromMemory(bool justHeader, const string& out1, const string& out2) const; + + // Sanity checking + void sanityCheckUpToSide(int upToSide) const; + void sanityCheckAll(int reverse) const; + void restore(SString& s) const; + void checkOrigs(const EList >& os, bool mirror) const; + + // Searching and reporting + bool joinedToTextOff(index_t qlen, index_t off, index_t& tidx, index_t& textoff, index_t& tlen, bool rejectStraddle, bool& straddled) const; + bool textOffToJoined(index_t tid, index_t tlen, index_t& off) const; + +#define WITHIN_BWT_LEN(x) \ + assert_leq(x[0], this->_gh._sideGbwtLen); \ + assert_leq(x[1], this->_gh._sideGbwtLen); \ + assert_leq(x[2], this->_gh._sideGbwtLen); \ + assert_leq(x[3], this->_gh._sideGbwtLen) + +#define WITHIN_FCHR(x) \ + assert_leq(x[0], this->fchr()[1]); \ + assert_leq(x[1], this->fchr()[2]); \ + assert_leq(x[2], this->fchr()[3]); \ + assert_leq(x[3], this->fchr()[4]) + +#define WITHIN_FCHR_DOLLARA(x) \ + assert_leq(x[0], this->fchr()[1]+1); \ + assert_leq(x[1], this->fchr()[2]); \ + assert_leq(x[2], this->fchr()[3]); \ + assert_leq(x[3], this->fchr()[4]) + + /** + * Count all occurrences of character c from the beginning of the + * forward side to and add in the occ[] count up to the side + * break just prior to the side. + * + * A Bowtie 2 side is shaped like: + * + * XXXXXXXXXXXXXXXX [A] [C] [G] [T] + * --------48------ -4- -4- -4- -4- (numbers in bytes) + */ + inline index_t countBt2Side(const SideLocus& l, int c) const { + assert_range(0, 3, c); + assert_range(0, (int)this->_gh._sideGbwtSz-1, (int)l._by); + assert_range(0, 3, (int)l._bp); + const uint8_t *side = l.side(this->gfm()); + index_t cCnt = countUpTo(l, c); + assert_leq(cCnt, l.toBWRow(_gh)); + assert_leq(cCnt, this->_gh._sideGbwtLen); + assert_eq(_zGbwtByteOffs.size(), _zGbwtBpOffs.size()); + for(index_t i = 0; i < _zGbwtByteOffs.size(); i++) { + index_t zGbwtByteOff = _zGbwtByteOffs[i]; + if(c == 0 && l._sideByteOff <= zGbwtByteOff && l._sideByteOff + l._by >= zGbwtByteOff) { + // Adjust for the fact that we represented $ with an 'A', but + // shouldn't count it as an 'A' here + int zGbwtBpOff = _zGbwtBpOffs[i]; + if((l._sideByteOff + l._by > zGbwtByteOff) || + (l._sideByteOff + l._by == zGbwtByteOff && l._bp > zGbwtBpOff)) + { + cCnt--; // Adjust for '$' looking like an 'A' + } + } + } + index_t ret; + // Now factor in the occ[] count at the side break + const uint8_t *acgt8 = side + _gh._sideGbwtSz; + if(!_gh._linearFM) { + acgt8 += (sizeof(index_t) << 1); + } + const index_t *acgt = reinterpret_cast(acgt8); + assert_leq(acgt[0], this->_gh._numSides * this->_gh._sideGbwtLen); // b/c it's used as padding + assert_lt(acgt[1], this->_gh._gbwtLen); + assert_lt(acgt[2], this->_gh._gbwtLen); + assert_lt(acgt[3], this->_gh._gbwtLen); + ret = acgt[c] + cCnt + this->fchr()[c]; +#ifndef NDEBUG + assert_leq(ret, this->fchr()[c+1]); // can't have jumpded into next char's section + if(c == 0) { + assert_leq(cCnt, this->_gh._sideGbwtLen); + } else { + assert_leq(ret, this->_gh._gbwtLen); + } +#endif + return ret; + } + + /** + * Count all occurrences of all four nucleotides up to the starting + * point (which must be in a forward side) given by 'l' storing the + * result in 'cntsUpto', then count nucleotide occurrences within the + * range of length 'num' storing the result in 'cntsIn'. Also, keep + * track of the characters occurring within the range by setting + * 'masks' accordingly (masks[1][10] == true -> 11th character is a + * 'C', and masks[0][10] == masks[2][10] == masks[3][10] == false. + */ + inline void countBt2SideRange( + const SideLocus& l, // top locus + index_t num, // number of elts in range to tall + index_t* cntsUpto, // A/C/G/T counts up to top + index_t* cntsIn, // A/C/G/T counts within range + EList *masks) const // masks indicating which range elts = A/C/G/T + { + assert_gt(num, 0); + assert_range(0, (int)this->_gh._sideGbwtSz-1, (int)l._by); + assert_range(0, 3, (int)l._bp); + countUpToEx(l, cntsUpto); + WITHIN_FCHR_DOLLARA(cntsUpto); + WITHIN_BWT_LEN(cntsUpto); + const uint8_t *side = l.side(this->gfm()); + assert_eq(_zGbwtByteOffs.size(), _zGbwtBpOffs.size()); + for(index_t i = 0; i < _zGbwtByteOffs.size(); i++) { + index_t zGbwtByteOff = _zGbwtByteOffs[i]; + if(l._sideByteOff <= zGbwtByteOff && l._sideByteOff + l._by >= zGbwtByteOff) { + // Adjust for the fact that we represented $ with an 'A', but + // shouldn't count it as an 'A' here + int zGbwtBpOff = _zGbwtBpOffs[i]; + if((l._sideByteOff + l._by > zGbwtByteOff) || + (l._sideByteOff + l._by == zGbwtByteOff && l._bp > zGbwtBpOff)) + { + cntsUpto[0]--; // Adjust for '$' looking like an 'A' + } + } + } + // Now factor in the occ[] count at the side break + const index_t *acgt = reinterpret_cast(side + _gh._sideGbwtSz); + if(!this->_gh.linearFM()) acgt += 2; + assert_leq(acgt[0], this->fchr()[1] + this->_gh.sideGbwtLen()); + assert_leq(acgt[1], this->fchr()[2]-this->fchr()[1]); + assert_leq(acgt[2], this->fchr()[3]-this->fchr()[2]); + assert_leq(acgt[3], this->fchr()[4]-this->fchr()[3]); + assert_leq(acgt[0], this->_gh._gbwtLen + this->_gh.sideGbwtLen()); + assert_leq(acgt[1], this->_gh._gbwtLen); + assert_leq(acgt[2], this->_gh._gbwtLen); + assert_leq(acgt[3], this->_gh._gbwtLen); + cntsUpto[0] += (acgt[0] + this->fchr()[0]); + cntsUpto[1] += (acgt[1] + this->fchr()[1]); + cntsUpto[2] += (acgt[2] + this->fchr()[2]); + cntsUpto[3] += (acgt[3] + this->fchr()[3]); + masks[0].resize(num); + masks[1].resize(num); + masks[2].resize(num); + masks[3].resize(num); + WITHIN_FCHR_DOLLARA(cntsUpto); + WITHIN_FCHR_DOLLARA(cntsIn); + // 'cntsUpto' is complete now. + // Walk forward until we've tallied the entire 'In' range + index_t nm = 0; + // Rest of this side + nm += countBt2SideRange2(l, true, num - nm, cntsIn, masks, nm); + assert_eq(nm, cntsIn[0] + cntsIn[1] + cntsIn[2] + cntsIn[3]); + assert_leq(nm, num); + SideLocus lcopy = l; + while(nm < num) { + // Subsequent sides, if necessary + lcopy.nextSide(this->_gh); + nm += countBt2SideRange2(lcopy, false, num - nm, cntsIn, masks, nm); + WITHIN_FCHR_DOLLARA(cntsIn); + assert_leq(nm, num); + assert_eq(nm, cntsIn[0] + cntsIn[1] + cntsIn[2] + cntsIn[3]); + } + assert_eq(num, cntsIn[0] + cntsIn[1] + cntsIn[2] + cntsIn[3]); + WITHIN_FCHR_DOLLARA(cntsIn); + } + + /** + * Count all occurrences of character c from the beginning of the + * forward side to and add in the occ[] count up to the side + * break just prior to the side. + * + * A forward side is shaped like: + * + * [A] [C] XXXXXXXXXXXXXXXX + * -4- -4- --------56------ (numbers in bytes) + * ^ + * Side ptr (result from SideLocus.side()) + * + * And following it is a reverse side shaped like: + * + * [G] [T] XXXXXXXXXXXXXXXX + * -4- -4- --------56------ (numbers in bytes) + * ^ + * Side ptr (result from SideLocus.side()) + * + */ + inline void countBt2SideEx(const SideLocus& l, index_t* arrs) const { + assert_range(0, (int)this->_gh._sideGbwtSz-1, (int)l._by); + assert_range(0, 3, (int)l._bp); + countUpToEx(l, arrs); + assert_eq(_zGbwtByteOffs.size(), _zGbwtBpOffs.size()); + for(index_t i = 0; i < _zGbwtByteOffs.size(); i++) { + index_t zGbwtByteOff = _zGbwtByteOffs[i]; + if(l._sideByteOff <= zGbwtByteOff && l._sideByteOff + l._by >= zGbwtByteOff) { + // Adjust for the fact that we represented $ with an 'A', but + // shouldn't count it as an 'A' here + int zGbwtBpOff = _zGbwtBpOffs[i]; + if((l._sideByteOff + l._by > zGbwtByteOff) || + (l._sideByteOff + l._by == zGbwtByteOff && l._bp > zGbwtBpOff)) + { + arrs[0]--; // Adjust for '$' looking like an 'A' + } + } + } + WITHIN_FCHR(arrs); + WITHIN_BWT_LEN(arrs); + // Now factor in the occ[] count at the side break + const uint8_t *side = l.side(this->gfm()); + const uint8_t *acgt16 = side + this->_gh._sideSz - sizeof(index_t) * 4; + const index_t *acgt = reinterpret_cast(acgt16); + assert_leq(acgt[0], this->fchr()[1] + this->_gh.sideGbwtLen()); + assert_leq(acgt[1], this->fchr()[2]-this->fchr()[1]); + assert_leq(acgt[2], this->fchr()[3]-this->fchr()[2]); + assert_leq(acgt[3], this->fchr()[4]-this->fchr()[3]); + assert_leq(acgt[0], this->_gh._len + this->_gh.sideGbwtLen()); + assert_leq(acgt[1], this->_gh._len); + assert_leq(acgt[2], this->_gh._len); + assert_leq(acgt[3], this->_gh._len); + arrs[0] += (acgt[0] + this->fchr()[0]); + arrs[1] += (acgt[1] + this->fchr()[1]); + arrs[2] += (acgt[2] + this->fchr()[2]); + arrs[3] += (acgt[3] + this->fchr()[3]); + WITHIN_FCHR(arrs); + } + + /** + * Count all occurrences of character 1 from the beginning of the + * forward side to and add in the occ[] count up to the side + * break just prior to the side. + * + */ + inline index_t countMSide(const SideLocus& l) const { + assert_range(0, (int)this->_gh._sideGbwtSz-1, (int)l._by); + assert_range(0, 7, (int)l._bp); + index_t cCnt = countUpTo_bits(l, false /* F? */); + const uint8_t *side = l.side(this->gfm()); + cCnt += *(index_t*)(side + _gh._sideGbwtSz + sizeof(index_t)); + assert_leq(cCnt, l.toBWRow(_gh)); + assert_leq(cCnt, this->_gh._numNodes); + return cCnt; + } + + /** + * Counts the number of occurrences of character 'c' in the given Ebwt + * side up to (but not including) the given byte/bitpair (by/bp). + * + * This is a performance-critical function. This is the top search- + * related hit in the time profile. + * + * Function gets 11.09% in profile + */ + inline index_t countUpTo(const SideLocus& l, int c) const { + // Count occurrences of c in each 64-bit (using bit trickery); + // Someday countInU64() and pop() functions should be + // vectorized/SSE-ized in case that helps. + bool usePOPCNT = false; + index_t cCnt = 0; + const uint8_t *side = l.side(this->gfm()); + int i = 0; +#ifdef POPCNT_CAPABILITY + if(_usePOPCNTinstruction) { + usePOPCNT = true; + int by = l._by + (l._bp > 0 ? 1 : 0); + for(; i < by; i += 8) { + if(i + 8 < by) { + cCnt += countInU64(c, *(uint64_t*)&side[i]); + } else { + index_t by_shift = 8 - (by - i); + index_t bp_shift = (l._bp > 0 ? 4 - l._bp : 0); + index_t shift = (by_shift << 3) + (bp_shift << 1); + uint64_t side_i = *(uint64_t*)&side[i]; + side_i = (_toBigEndian ? side_i >> shift : side_i << shift); + index_t cCnt_add = countInU64(c, side_i); + if(c == 0) cCnt_add -= (shift >> 1); +#ifndef NDEBUG + index_t cCnt_temp = 0; + for(int j = i; j < l._by; j++) { + cCnt_temp += cCntLUT_4[0][c][side[j]]; + } + if(l._bp > 0) { + cCnt_temp += cCntLUT_4[(int)l._bp][c][side[l._by]]; + } + assert_eq(cCnt_add, cCnt_temp); +#endif + cCnt += cCnt_add; + break; + } + } + } else { + for(; i + 7 < l._by; i += 8) { + cCnt += countInU64(c, *(uint64_t*)&side[i]); + } + } +#else + for(; i + 7 < l._by; i += 8) { + cCnt += countInU64(c, *(uint64_t*)&side[i]); + } +#endif + + if(!usePOPCNT) { + // Count occurences of c in the rest of the side (using LUT) + for(; i < l._by; i++) { + cCnt += cCntLUT_4[0][c][side[i]]; + } + + // Count occurences of c in the rest of the byte + if(l._bp > 0) { + cCnt += cCntLUT_4[(int)l._bp][c][side[i]]; + } + } + + return cCnt; + } + + /** + * Counts the number of occurrences of character 'c' in the given Ebwt + * side down to the given byte/bitpair (by/bp). + * + */ + inline index_t countDownTo(const SideLocus& l, int c) const { + // Count occurrences of c in each 64-bit (using bit trickery); + // Someday countInU64() and pop() functions should be + // vectorized/SSE-ized in case that helps. + index_t cCnt = 0; + const uint8_t *side = l.side(this->gfm()); + int i = 64 - 4 * sizeof(index_t) - 1; +#ifdef POPCNT_CAPABILITY + if ( _usePOPCNTinstruction) { + for(; i - 7 > l._by; i -= 8) { + cCnt += countInU64(c, *(uint64_t*)&side[i-7]); + } + } + else { + for(; i + 7 > l._by; i -= 8) { + cCnt += countInU64(c, *(uint64_t*)&side[i-7]); + } + } +#else + for(; i + 7 > l._by; i -= 8) { + cCnt += countInU64(c, *(uint64_t*)&side[i-7]); + } +#endif + // Count occurences of c in the rest of the side (using LUT) + for(; i > l._by; i--) { + cCnt += cCntLUT_4_rev[0][c][side[i]]; + } + // Count occurences of c in the rest of the byte + if(l._bp > 0) { + cCnt += cCntLUT_4_rev[4-(int)l._bp][c][side[i]]; + } else { + cCnt += cCntLUT_4_rev[0][c][side[i]]; + } + return cCnt; + } + + /** + * Tricky-bit-bashing bitpair counting for given two-bit value (0-3) + * within a 64-bit argument. + * + * Function gets 2.32% in profile + */ +#ifdef POPCNT_CAPABILITY + template +#endif + inline static void countInU64Ex(uint64_t dw, index_t* arrs) { + uint64_t c0 = c_table[0]; + uint64_t x0 = dw ^ c0; + uint64_t x1 = (x0 >> 1); + uint64_t x2 = x1 & (0x5555555555555555llu); + uint64_t x3 = x0 & x2; +#ifdef POPCNT_CAPABILITY + uint64_t tmp = Operation().pop64(x3); +#else + uint64_t tmp = pop64(x3); +#endif + arrs[0] += (uint32_t) tmp; + + c0 = c_table[1]; + x0 = dw ^ c0; + x1 = (x0 >> 1); + x2 = x1 & (0x5555555555555555llu); + x3 = x0 & x2; +#ifdef POPCNT_CAPABILITY + tmp = Operation().pop64(x3); +#else + tmp = pop64(x3); +#endif + arrs[1] += (uint32_t) tmp; + + c0 = c_table[2]; + x0 = dw ^ c0; + x1 = (x0 >> 1); + x2 = x1 & (0x5555555555555555llu); + x3 = x0 & x2; +#ifdef POPCNT_CAPABILITY + tmp = Operation().pop64(x3); +#else + tmp = pop64(x3); +#endif + arrs[2] += (uint32_t) tmp; + + c0 = c_table[3]; + x0 = dw ^ c0; + x1 = (x0 >> 1); + x2 = x1 & (0x5555555555555555llu); + x3 = x0 & x2; +#ifdef POPCNT_CAPABILITY + tmp = Operation().pop64(x3); +#else + tmp = pop64(x3); +#endif + arrs[3] += (uint32_t) tmp; + } + + /** + * Counts the number of occurrences of all four nucleotides in the + * given side up to (but not including) the given byte/bitpair (by/bp). + * Count for 'a' goes in arrs[0], 'c' in arrs[1], etc. + */ + inline void countUpToEx(const SideLocus& l, index_t* arrs) const { + int i = 0; + // Count occurrences of each nucleotide in each 64-bit word using + // bit trickery; note: this seems does not seem to lend a + // significant boost to performance in practice. If you comment + // out this whole loop (which won't affect correctness - it will + // just cause the following loop to take up the slack) then runtime + // does not change noticeably. Someday the countInU64() and pop() + // functions should be vectorized/SSE-ized in case that helps. + const uint8_t *side = l.side(this->gfm()); +#ifdef POPCNT_CAPABILITY + if (_usePOPCNTinstruction) { + for(; i+7 < l._by; i += 8) { + countInU64Ex(*(uint64_t*)&side[i], arrs); + } + } + else { + for(; i+7 < l._by; i += 8) { + countInU64Ex(*(uint64_t*)&side[i], arrs); + } + } +#else + for(; i+7 < l._by; i += 8) { + countInU64Ex(*(uint64_t*)&side[i], arrs); + } +#endif + // Count occurences of nucleotides in the rest of the side (using LUT) + // Many cache misses on following lines (~20K) + for(; i < l._by; i++) { + arrs[0] += cCntLUT_4[0][0][side[i]]; + arrs[1] += cCntLUT_4[0][1][side[i]]; + arrs[2] += cCntLUT_4[0][2][side[i]]; + arrs[3] += cCntLUT_4[0][3][side[i]]; + } + // Count occurences of c in the rest of the byte + if(l._bp > 0) { + arrs[0] += cCntLUT_4[(int)l._bp][0][side[i]]; + arrs[1] += cCntLUT_4[(int)l._bp][1][side[i]]; + arrs[2] += cCntLUT_4[(int)l._bp][2][side[i]]; + arrs[3] += cCntLUT_4[(int)l._bp][3][side[i]]; + } + } + + /** + * Counts the number of occurrences of character 'c' in the given Ebwt + * side up to (but not including) the given byte/bitpair (by/bp). + * + * This is a performance-critical function. This is the top search- + * related hit in the time profile. + */ + inline index_t countUpTo_bits(const SideLocus& l, bool F) const { + // Count occurrences of c in each 64-bit (using bit trickery); + // Someday countInU64() and pop() functions should be + // vectorized/SSE-ized in case that helps. + bool usePOPCNT = false; + index_t cCnt = 0; + const uint8_t *side = l.side(this->gfm()); + if(F) { + side += (_gh._sideGbwtSz >> 1); + } else { + side += (_gh._sideGbwtSz - (_gh._sideGbwtSz >> 2)); + } + int i = 0; +#ifdef POPCNT_CAPABILITY + if(_usePOPCNTinstruction) { + usePOPCNT = true; + int by = l._by + (l._bp > 0 ? 1 : 0); + for(; i < by; i += 8) { + if(i + 8 < by) { + cCnt += countInU64_bits(*(uint64_t*)&side[i]); + } else { + index_t by_shift = 8 - (by - i); + index_t bp_shift = (l._bp > 0 ? 8 - l._bp : 0); + index_t shift = (by_shift << 3) + bp_shift; + uint64_t side_i = *(uint64_t*)&side[i]; + side_i = (_toBigEndian ? side_i >> shift : side_i << shift); + index_t cCnt_add = countInU64_bits(side_i); +#ifndef NDEBUG + index_t cCnt_temp = 0; + for(int j = i; j < l._by; j++) { + cCnt_temp += cCntBIT[0][side[j]]; + } + if(l._bp > 0) { + cCnt_temp += cCntBIT[(int)l._bp][side[l._by]]; + } + assert_eq(cCnt_add, cCnt_temp); +#endif + cCnt += cCnt_add; + break; + } + } + } else { + for(; i + 7 < l._by; i += 8) { + cCnt += countInU64_bits(*(uint64_t*)&side[i]); + } + } +#else + for(; i + 7 < l._by; i += 8) { + cCnt += countInU64_bits(*(uint64_t*)&side[i]); + } +#endif + + if(!usePOPCNT) { + // Count occurences of c in the rest of the side (using LUT) + for(; i < l._by; i++) { + cCnt += cCntBIT[0][side[i]]; + } + + // Count occurences of c in the rest of the byte + if(l._bp > 0) { + cCnt += cCntBIT[(int)l._bp][side[i]]; + } + } + + return cCnt; + } + + +#ifndef NDEBUG + /** + * Given top and bot loci, calculate counts of all four DNA chars up to + * those loci. Used for more advanced backtracking-search. + */ + inline void mapLFEx( + const SideLocus& l, + index_t *arrs + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + assert_eq(0, arrs[0]); + assert_eq(0, arrs[1]); + assert_eq(0, arrs[2]); + assert_eq(0, arrs[3]); + countBt2SideEx(l, arrs); + if(_sanity && !overrideSanity) { + // Make sure results match up with individual calls to mapLF; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + assert_eq(mapLF(l, 0, true), arrs[0]); + assert_eq(mapLF(l, 1, true), arrs[1]); + assert_eq(mapLF(l, 2, true), arrs[2]); + assert_eq(mapLF(l, 3, true), arrs[3]); + } + } +#endif + + /** + * Given top and bot rows, calculate counts of all four DNA chars up to + * those loci. + */ + inline void mapLFEx( + index_t top, + index_t bot, + index_t *tops, + index_t *bots + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + SideLocus ltop, lbot; + SideLocus::initFromTopBot(top, bot, _gh, gfm(), ltop, lbot); + mapLFEx(ltop, lbot, tops, bots ASSERT_ONLY(, overrideSanity)); + } + + /** + * Given top and bot loci, calculate counts of all four DNA chars up to + * those loci. Used for more advanced backtracking-search. + */ + inline void mapLFEx( + const SideLocus& ltop, + const SideLocus& lbot, + index_t *tops, + index_t *bots + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + assert(ltop.repOk(this->gh())); + assert(lbot.repOk(this->gh())); + assert_eq(0, tops[0]); assert_eq(0, bots[0]); + assert_eq(0, tops[1]); assert_eq(0, bots[1]); + assert_eq(0, tops[2]); assert_eq(0, bots[2]); + assert_eq(0, tops[3]); assert_eq(0, bots[3]); + countBt2SideEx(ltop, tops); + countBt2SideEx(lbot, bots); +#ifndef NDEBUG + if(_sanity && !overrideSanity) { + // Make sure results match up with individual calls to mapLF; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + assert_eq(mapLF(ltop, 0, true), tops[0]); + assert_eq(mapLF(ltop, 1, true), tops[1]); + assert_eq(mapLF(ltop, 2, true), tops[2]); + assert_eq(mapLF(ltop, 3, true), tops[3]); + assert_eq(mapLF(lbot, 0, true), bots[0]); + assert_eq(mapLF(lbot, 1, true), bots[1]); + assert_eq(mapLF(lbot, 2, true), bots[2]); + assert_eq(mapLF(lbot, 3, true), bots[3]); + } +#endif + } + + /** + * Counts the number of occurrences of all four nucleotides in the + * given side from the given byte/bitpair (l->_by/l->_bp) (or the + * beginning of the side if l == 0). Count for 'a' goes in arrs[0], + * 'c' in arrs[1], etc. + * + * Note: must account for $. + * + * Must fill in masks + */ + inline index_t countBt2SideRange2( + const SideLocus& l, + bool startAtLocus, + index_t num, + index_t* arrs, + EList *masks, + index_t maskOff) const + { + assert(!masks[0].empty()); + assert_eq(masks[0].size(), masks[1].size()); + assert_eq(masks[0].size(), masks[2].size()); + assert_eq(masks[0].size(), masks[3].size()); + ASSERT_ONLY(index_t myarrs[4] = {0, 0, 0, 0}); + index_t nm = 0; // number of nucleotides tallied so far + int iby = 0; // initial byte offset + int ibp = 0; // initial base-pair offset + if(startAtLocus) { + iby = l._by; + ibp = l._bp; + } else { + // Start at beginning + } + int by = iby, bp = ibp; + assert_lt(bp, 4); + index_t sideGbwtSz = this->_gh._sideGbwtSz >> (this->_gh.linearFM() ? 0 : 1); + assert_lt(by, (int)sideGbwtSz); + const uint8_t *side = l.side(this->gfm()); + while(nm < num) { + int c = (side[by] >> (bp * 2)) & 3; + assert_lt(maskOff + nm, masks[c].size()); + masks[0][maskOff + nm] = masks[1][maskOff + nm] = + masks[2][maskOff + nm] = masks[3][maskOff + nm] = false; + assert_range(0, 3, c); + // Note: we tally $ just like an A + arrs[c]++; // tally it + ASSERT_ONLY(myarrs[c]++); + masks[c][maskOff + nm] = true; // not dead + nm++; + if(++bp == 4) { + bp = 0; + by++; + assert_leq(by, (int)sideGbwtSz); + if(by == (int)sideGbwtSz) { + // Fell off the end of the side + break; + } + } + } + WITHIN_FCHR_DOLLARA(arrs); +#ifndef NDEBUG + if(_sanity) { + // Make sure results match up with a call to mapLFEx. + index_t tops[4] = {0, 0, 0, 0}; + index_t bots[4] = {0, 0, 0, 0}; + index_t top = l.toBWRow(gh()); + index_t bot = top + nm; + mapLFEx(top, bot, tops, bots, false); + assert(myarrs[0] == (bots[0] - tops[0]) || myarrs[0] == (bots[0] - tops[0])+1); + assert_eq(myarrs[1], bots[1] - tops[1]); + assert_eq(myarrs[2], bots[2] - tops[2]); + assert_eq(myarrs[3], bots[3] - tops[3]); + } +#endif + return nm; + } + + /** + * Return the final character in row i (i.e. the i'th character in the + * BWT transform). Note that the 'L' in the name of the function + * stands for 'last', as in the literature. + */ + inline int rowL(const SideLocus& l) const { + // Extract and return appropriate bit-pair + return unpack_2b_from_8b(l.side(this->gfm())[l._by], l._bp); + } + + /** + * Return the final character in row i (i.e. the i'th character in the + * BWT transform). Note that the 'L' in the name of the function + * stands for 'last', as in the literature. + */ + inline int rowL(index_t i) const { + // Extract and return appropriate bit-pair + SideLocus l; + l.initFromRow(i, _gh, gfm()); + return rowL(l); + } + + /** + * Given top and bot loci, calculate counts of all four DNA chars up to + * those loci. Used for more advanced backtracking-search. + */ + inline void mapLFRange( + const SideLocus& ltop, + const SideLocus& lbot, + index_t num, // Number of elts + index_t* cntsUpto, // A/C/G/T counts up to top + index_t* cntsIn, // A/C/G/T counts within range + EList *masks + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + assert(ltop.repOk(this->gh())); + assert(lbot.repOk(this->gh())); + assert_eq(num, lbot.toBWRow(this->gh()) - ltop.toBWRow(this->gh())); + assert_eq(0, cntsUpto[0]); assert_eq(0, cntsIn[0]); + assert_eq(0, cntsUpto[1]); assert_eq(0, cntsIn[1]); + assert_eq(0, cntsUpto[2]); assert_eq(0, cntsIn[2]); + assert_eq(0, cntsUpto[3]); assert_eq(0, cntsIn[3]); + countBt2SideRange(ltop, num, cntsUpto, cntsIn, masks); + assert_eq(num, cntsIn[0] + cntsIn[1] + cntsIn[2] + cntsIn[3]); +#ifndef NDEBUG + if(_sanity && !overrideSanity) { + // Make sure results match up with individual calls to mapLF; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + index_t tops[4] = {0, 0, 0, 0}; + index_t bots[4] = {0, 0, 0, 0}; + assert(ltop.repOk(this->gh())); + assert(lbot.repOk(this->gh())); + mapLFEx(ltop, lbot, tops, bots, false); + for(int i = 0; i < 4; i++) { + assert(cntsUpto[i] == tops[i] || tops[i] == bots[i]); + if(i == 0) { + assert(cntsIn[i] == bots[i]-tops[i] || + cntsIn[i] == bots[i]-tops[i]+1); + } else { + assert_eq(cntsIn[i], bots[i]-tops[i]); + } + } + } +#endif + } + + /** + * Given row i, return the row that the LF mapping maps i to. + */ + inline index_t mapLF( + const SideLocus& l + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + ASSERT_ONLY(index_t srcrow = l.toBWRow(_gh)); + index_t ret; + assert(l.side(this->gfm()) != NULL); + int c = rowL(l); + assert_lt(c, 4); + assert_geq(c, 0); + ret = countBt2Side(l, c); + assert_lt(ret, this->_gh._gbwtLen); + assert_neq(srcrow, ret); +#ifndef NDEBUG + if(_sanity && !overrideSanity) { + // Make sure results match up with results from mapLFEx; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + index_t arrs[] = { 0, 0, 0, 0 }; + mapLFEx(l, arrs, true); + assert_eq(arrs[c], ret); + } +#endif + return ret; + } + + /** + * Given row i and character c, return the row that the LF mapping maps + * i to on character c. + */ + inline index_t mapLF( + const SideLocus& l, int c + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + index_t ret; + assert_lt(c, 4); + assert_geq(c, 0); + ret = countBt2Side(l, c); + assert_lt(ret, this->_gh._gbwtLen); +#ifndef NDEBUG + if(_sanity && !overrideSanity) { + // Make sure results match up with results from mapLFEx; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + index_t arrs[] = { 0, 0, 0, 0 }; + mapLFEx(l, arrs, true); + assert_eq(arrs[c], ret); + } +#endif + return ret; + } + + /** + * Given row i and character c, return the row that the GLF mapping maps + * i to on character c. + */ + inline pair mapLF( + SideLocus& tloc, SideLocus& bloc, int c, + pair* node_range = NULL + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + assert_lt(c, 4); + assert_geq(c, 0); + index_t top = mapLF(tloc, c); + index_t bot = mapLF(bloc, c); + if(node_range != NULL) { + node_range->first = top; node_range->second = bot; + } + return pair(top, bot); + } + + /** + * Given row i and character c, return the row that the GLF mapping maps + * i to on character c. + */ + inline pair mapGLF( + SideLocus& tloc, SideLocus& bloc, int c, + pair* node_range = NULL, + EList >* node_iedges = NULL, + index_t k = 5 + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + assert_lt(c, 4); + assert_geq(c, 0); + index_t top = mapLF(tloc, c); + index_t bot = mapLF(bloc, c); + if(gh().linearFM()) { + if(node_range != NULL) { + node_range->first = top; node_range->second = bot; + } + if(node_iedges != NULL) { + node_iedges->clear(); + } + return pair(top, bot); + } + if(top + 1 >= gh()._gbwtLen || top >= bot) { + assert_eq(top, bot); + return pair(0, 0); + } + + tloc.initFromRow_bit(top + 1, gh(), gfm()); + index_t node_top = rank_M(tloc) - 1; + + index_t top_F_loc = 0, top_M_occ = 0; + size_t iter = 0; + while(true) { + const uint8_t *side = tloc.side(gfm()) + gh()._sideGbwtSz - gh()._sideSz * iter; + top_F_loc = *((index_t*)side); + side += sizeof(index_t); + top_M_occ = *((index_t*)side); + assert_leq(top_M_occ, node_top + 1); + if(top_M_occ <= node_top) break; + iter++; + } + if(top_M_occ > 0) top_F_loc++; + + tloc.initFromRow_bit(top_F_loc, gh(), gfm()); + + if(node_top + 1 > top_M_occ) { + top = select_F(tloc, node_top + 1 - top_M_occ); + } else { + top = top_F_loc; + } + + bloc.initFromRow_bit(bot, gh(), gfm()); + index_t node_bot = rank_M(bloc); + + const uint8_t *side = bloc.side(gfm()) + gh()._sideGbwtSz; + index_t bot_F_loc = *((index_t*)side); + side += sizeof(index_t); + index_t bot_M_occ = *((index_t*)side); + assert_leq(bot_M_occ, node_bot + 1); + if(bot_M_occ > 0) bot_F_loc++; + + bloc.initFromRow_bit(bot_F_loc, gh(), gfm()); + + if(node_bot + 1 > bot_M_occ) { + bot = select_F(bloc, node_bot + 1 - bot_M_occ); + } else { + bot = bot_F_loc; + } + + if(node_range != NULL) { + (*node_range).first = node_top; + (*node_range).second = node_bot; + } + assert_leq(node_bot - node_top, bot - top); + if(node_iedges != NULL && node_bot - node_top <= k && node_bot - node_top < bot - top) { + getInEdgeCount(top, bot, *node_iedges); + } + + return pair(top, bot); + } + + /** + * Given top and bot loci, calculate counts of all four DNA chars up to + * those loci. Also, update a set of tops and bots for the reverse + * index/direction using the idea from the bi-directional BWT paper. + */ + inline void mapBiLFEx( + const SideLocus& ltop, + const SideLocus& lbot, + index_t *tops, + index_t *bots, + index_t *topsP, // topsP[0] = top + index_t *botsP + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { +#ifndef NDEBUG + for(int i = 0; i < 4; i++) { + assert_eq(0, tops[0]); assert_eq(0, bots[0]); + } +#endif + countBt2SideEx(ltop, tops); + countBt2SideEx(lbot, bots); +#ifndef NDEBUG + if(_sanity && !overrideSanity) { + // Make sure results match up with individual calls to mapLF; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + assert_eq(mapLF(ltop, 0, true), tops[0]); + assert_eq(mapLF(ltop, 1, true), tops[1]); + assert_eq(mapLF(ltop, 2, true), tops[2]); + assert_eq(mapLF(ltop, 3, true), tops[3]); + assert_eq(mapLF(lbot, 0, true), bots[0]); + assert_eq(mapLF(lbot, 1, true), bots[1]); + assert_eq(mapLF(lbot, 2, true), bots[2]); + assert_eq(mapLF(lbot, 3, true), bots[3]); + } +#endif + // bots[0..3] - tops[0..3] = # of ways to extend the suffix with an + // A, C, G, T + botsP[0] = topsP[0] + (bots[0] - tops[0]); + topsP[1] = botsP[0]; + botsP[1] = topsP[1] + (bots[1] - tops[1]); + topsP[2] = botsP[1]; + botsP[2] = topsP[2] + (bots[2] - tops[2]); + topsP[3] = botsP[2]; + botsP[3] = topsP[3] + (bots[3] - tops[3]); + } + + /** + * Given row and its locus information, proceed on the given character + * and return the next row, or all-fs if we can't proceed on that + * character. Returns 0xffffffff if this row ends in $. + */ + inline index_t mapLF1( + index_t row, // starting row + const SideLocus& l, // locus for starting row + int c // character to proceed on + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + if(rowL(l) != c) return (index_t)INDEX_MAX; + for(index_t i = 0; i < _zOffs.size(); i++) { + if(row == _zOffs[i]) return (index_t)INDEX_MAX; + } + index_t ret; + assert_lt(c, 4); + assert_geq(c, 0); + ret = countBt2Side(l, c); + assert_lt(ret, this->_gh._gbwtLen); +#ifndef NDEBUG + if(_sanity && !overrideSanity) { + // Make sure results match up with results from mapLFEx; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + index_t arrs[] = { 0, 0, 0, 0 }; + mapLFEx(l, arrs, true); + assert_eq(arrs[c], ret); + } +#endif + return ret; + } + + + /** + * Given row and its locus information, set the row to LF(row) and + * return the character that was in the final column. + */ + inline int mapLF1( + index_t& row, // starting row + const SideLocus& l // locus for starting row + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + for(index_t i = 0; i < _zOffs.size(); i++) { + if(row == _zOffs[i]) return -1; + } + int c = rowL(l); + assert_range(0, 3, c); + row = countBt2Side(l, c); + assert_lt(row, this->_gh._gbwtLen); +#ifndef NDEBUG + if(_sanity && !overrideSanity) { + // Make sure results match up with results from mapLFEx; + // be sure to override sanity-checking in the callee, or we'll + // have infinite recursion + index_t arrs[] = { 0, 0, 0, 0 }; + mapLFEx(l, arrs, true); + assert_eq(arrs[c], row); + } +#endif + return c; + } + + /** + * Given row and its locus information, proceed on the given character + * and return the next row, or all-fs if we can't proceed on that + * character. Returns 0xffffffff if this row ends in $. + */ + inline pair mapGLF1( + index_t row, // starting row + SideLocus& l, // locus for starting row + int c, // character to proceed + pair* node_range = NULL + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + assert_lt(c, 4); + assert_geq(c, 0); + index_t top = mapLF1(row, l, c); + if(top == (index_t)INDEX_MAX) return pair(0, 0); + if(gh().linearFM()) { + if(node_range != NULL) { + node_range->first = top; node_range->second = top + 1; + } + return pair(top, top + 1); + } + index_t bot = top; + + l.initFromRow_bit(top + 1, gh(), gfm()); + index_t node_top = rank_M(l) - 1; + + index_t F_loc = 0, M_occ = 0; + size_t iter = 0; + while(true) { + const uint8_t *side = l.side(gfm()) + gh()._sideGbwtSz - gh()._sideSz * iter; + F_loc = *((index_t*)side); + side += sizeof(index_t); + M_occ = *((index_t*)side); + assert_leq(M_occ, node_top + 1); + if(M_occ <= node_top) break; + iter++; + } + if(M_occ > 0) F_loc++; + + l.initFromRow_bit(F_loc, gh(), gfm()); + + if(node_top + 1 > M_occ) { + top = select_F(l, node_top + 1 - M_occ); + } else { + top = F_loc; + } + + index_t node_bot = node_top + 1; + if(node_bot + 1 > M_occ) { + SideLocus l2; +#if 0 + l2.initFromRow_bit(top + 1, gh(), gfm()); + bot = select_F(l2, 1); + ASSERT_ONLY(index_t bot2 = select_F(l, node_bot + 1 - M_occ)); + assert_eq(bot, bot2); +#else + bot = select_F(l, node_bot + 1 - M_occ); +#endif + } else { + bot = F_loc; + } + + if(node_range != NULL) { + (*node_range).first = node_top; + (*node_range).second = node_bot; + } + + return pair(top, bot); + } + + /** + * Given row and its locus information, proceed on the given character + * and return the next row, or all-fs if we can't proceed on that + * character. Returns 0xffffffff if this row ends in $. + */ + inline pair mapGLF1( + index_t row, // starting row + SideLocus& l, // locus for starting row + pair* node_range = NULL + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + for(index_t i = 0; i < _zOffs.size(); i++) { + if(row == _zOffs[i]) return pair((index_t)INDEX_MAX, (index_t)INDEX_MAX); + } + + mapLF1(row, l); + index_t top = row; + if(top == (index_t)INDEX_MAX) return pair(0, 0); + if(gh().linearFM()) { + if(node_range != NULL) { + node_range->first = top; node_range->second = top + 1; + } + return pair(top, top + 1); + } + index_t bot = top; + + l.initFromRow_bit(top + 1, gh(), gfm()); + index_t node_top = rank_M(l) - 1; + + index_t F_loc = 0, M_occ = 0; + size_t iter = 0; + while(true) { + const uint8_t *side = l.side(gfm()) + gh()._sideGbwtSz - gh()._sideSz * iter; + F_loc = *((index_t*)side); + side += sizeof(index_t); + M_occ = *((index_t*)side); + assert_leq(M_occ, node_top + 1); + if(M_occ <= node_top) break; + iter++; + } + if(M_occ > 0) F_loc++; + + l.initFromRow_bit(F_loc, gh(), gfm()); + + if(node_top + 1 > M_occ) { + top = select_F(l, node_top + 1 - M_occ); + } else { + top = F_loc; + } + + index_t node_bot = node_top + 1; + if(node_bot + 1 > M_occ) { +#if 0 + l2.initFromRow_bit(top + 1, gh(), gfm()); + bot = select_F(l2, 1); + ASSERT_ONLY(index_t bot2 = select_F(l, node_bot + 1 - M_occ)); + assert_eq(bot, bot2); +#else + bot = select_F(l, node_bot + 1 - M_occ); +#endif + } else { + bot = F_loc; + } + + if(node_range != NULL) { + (*node_range).first = node_top; + (*node_range).second = node_bot; + } + + return pair(top, bot); + } + + /** + * Given row i, return rank + */ + inline index_t rank_M( + const SideLocus& l + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + index_t ret = countMSide(l); + assert_leq(ret, this->_gh._numNodes); + return ret; + } + + /** + * Given row i, return select + */ + inline index_t select_F( + SideLocus l, + index_t count + ASSERT_ONLY(, bool overrideSanity = false) + ) const + { + assert_gt(count, 0); + const uint8_t *side = l.side(this->gfm()) + (_gh._sideGbwtSz >> 1); + while(true) { + index_t remainingBitsSide = (_gh._sideGbwtSz << 1) - l._charOff; + assert_gt(remainingBitsSide, 0); + index_t minSide = (count < remainingBitsSide ? count : remainingBitsSide); + uint64_t bits = *(uint64_t*)&side[l._by]; + uint8_t advance = 64; + if(l._bp > 0) { + bits >>= l._bp; + advance -= l._bp; + } + if(minSide < advance) { + advance = minSide; + bits <<= (64 - minSide); + } + uint8_t tmp_count = 0; +#ifdef POPCNT_CAPABILITY + if(_usePOPCNTinstruction) { + tmp_count = countInU64_bits(bits); + } else { + tmp_count = countInU64_bits(bits); + } +#else + tmp_count = countInU64_bits(bits); +#endif + assert_leq(tmp_count, count); + count -= tmp_count; + if(count == 0) { + assert_gt(advance, 0); + l._charOff += (advance - 1); + assert_lt(l._charOff, _gh._sideGbwtSz << 1); + l._by = l._charOff >> 3; + l._bp = l._charOff & 0x7; + break; + } + + assert_leq(l._charOff + advance, (_gh._sideGbwtSz << 1)); + if(l._charOff + advance == (_gh._sideGbwtSz << 1)) { + l.nextSide(_gh); + side = l.side(this->gfm()) + (_gh._sideGbwtSz >> 1); + } else { + l._charOff += advance; + l._by = l._charOff >> 3; + l._bp = l._charOff & 0x7; + } + } + return l.toBWRow(_gh); + } + + /** + * + */ + inline void getInEdgeCount( + index_t top, + index_t bot, + EList >& node_iedges) const + { + assert_lt(top, bot); + node_iedges.clear(); + SideLocus l; l.initFromRow_bit(top, _gh, gfm()); + const uint8_t *side = l.side(this->gfm()) + (_gh._sideGbwtSz >> 1); + assert_lt(l._by, (_gh._sideGbwtSz >> 2)); + assert_eq((side[l._by] >> l._bp) & 0x1, 0x1); + bool first = true; + index_t curr_node = 0; + index_t num0s = 0; + while(top < bot) { + if(first) { + first = false; + } else { + int bit = (side[l._by] >> l._bp) & 0x1; + if(bit == 0x1) { + curr_node++; + num0s = 0; + } else { + num0s++; + if(num0s == 1) { + node_iedges.expand(); + node_iedges.back().first = curr_node; + } + node_iedges.back().second = num0s; + } + } + if(l._charOff + 1 == (_gh._sideGbwtSz << 1)) { + l.nextSide(_gh); + side = l.side(this->gfm()) + (_gh._sideGbwtSz >> 1); + } else { + l._charOff++; + l._by = l._charOff >> 3; + l._bp = l._charOff & 0x7; + } + top++; + } + } + + +#ifndef NDEBUG + /// Check that in-memory Ebwt is internally consistent with respect + /// to given EbwtParams; assert if not + bool inMemoryRepOk(const GFMParams& gh) const { + assert_eq(_zOffs.size(), _zGbwtByteOffs.size()); + assert_eq(_zOffs.size(), _zGbwtBpOffs.size()); + for(index_t i = 0; i < _zOffs.size(); i++) { + assert_geq(_zGbwtBpOffs[i], 0); + assert_lt(_zGbwtBpOffs[i], 4); + assert_lt(_zGbwtByteOffs[i], gh._gbwtTotSz); + assert_lt(_zOffs[i], gh._gbwtLen); + } + assert_geq(_nFrag, _nPat); + assert_eq(_alts.size(), _altnames.size()); + return true; + } + + /// Check that in-memory Ebwt is internally consistent; assert if + /// not + bool inMemoryRepOk() const { + return repOk(_gh); + } + + /// Check that Ebwt is internally consistent with respect to given + /// EbwtParams; assert if not + bool repOk(const GFMParams& gh) const { + assert(_gh.repOk()); + if(isInMemory()) { + return inMemoryRepOk(gh); + } + return true; + } + + /// Check that Ebwt is internally consistent; assert if not + bool repOk() const { + return repOk(_gh); + } +#endif + + bool _toBigEndian; + int32_t _overrideOffRate; + bool _verbose; + bool _passMemExc; + bool _sanity; + bool fw_; // true iff this is a forward index + FILE *_in1; // input fd for primary index file + FILE *_in2; // input fd for secondary index file + string _in1Str; // filename for primary index file + string _in2Str; // filename for secondary index file + EList _zOffs; + EList _zGbwtByteOffs; + EList _zGbwtBpOffs; + index_t _nPat; /// number of reference texts + index_t _nFrag; /// number of fragments + APtrWrap _plen; + APtrWrap _rstarts; // starting offset of fragments / text indexes + // _fchr, _ftab and _eftab are expected to be relatively small + // (usually < 1MB, perhaps a few MB if _fchr is particularly large + // - like, say, 11). For this reason, we don't bother with writing + // them to disk through separate output streams; we + APtrWrap _fchr; + APtrWrap _ftab; + APtrWrap _eftab; // "extended" entries for _ftab + // _offs may be extremely large. E.g. for DNA w/ offRate=4 (one + // offset every 16 rows), the total size of _offs is the same as + // the total size of the input sequence + APtrWrap _offs; + + // _ebwt is the Extended Burrows-Wheeler Transform itself, and thus + // is at least as large as the input sequence. + APtrWrap _gfm; + bool _useMm; /// use memory-mapped files to hold the index + bool useShmem_; /// use shared memory to hold large parts of the index + EList _refnames; /// names of the reference sequences + EList _refnames_nospace; // names of the reference sequences (names stop at space) + char *mmFile1_; + char *mmFile2_; + int _nthreads; + GFMParams _gh; + bool packed_; + + static const uint64_t default_bmax = INDEX_MAX; + static const uint64_t default_bmaxMultSqrt = INDEX_MAX; + static const uint64_t default_bmaxDivN = 4; + static const int default_dcv = 1024; + static const bool default_noDc = false; + static const bool default_useBlockwise = true; + static const uint32_t default_seed = 0; +#ifdef BOWTIE_64BIT_INDEX + static const int default_lineRate_gfm = 8; + static const int default_lineRate_fm = 7; +#else + static const int default_lineRate_gfm = 7; + static const int default_lineRate_fm = 6; +#endif + static const int default_offRate = 5; + static const int default_offRatePlus = 0; + static const int default_ftabChars = 10; + static const bool default_bigEndian = false; + + // data used to build an index + EList > _alts; + EList _altnames; + EList > _haplotypes; + RepeatDB _repeatdb; + EList _repeat_kmertables; + + bool _repeat; + EList > _repeatLens; + EList _repeatIncluded; + +protected: + + ostream& log() const { + return cerr; // TODO: turn this into a parameter + } + + /// Print a verbose message and flush (flushing is helpful for + /// debugging) + void verbose(const string& s) const { + if(this->verbose()) { + this->log() << s.c_str(); + this->log().flush(); + } + } +}; + +/** + * Read reference names from an input stream 'in' for an Ebwt primary + * file and store them in 'refnames'. + */ +template +void readEbwtRefnames(istream& in, EList& refnames) { + // _in1 must already be open with the get cursor at the + // beginning and no error flags set. + assert(in.good()); + assert_eq((streamoff)in.tellg(), ios::beg); + + // Read endianness hints from both streams + bool switchEndian = false; + uint32_t one = readU32(in, switchEndian); // 1st word of primary stream + if(one != 1) { + assert_eq((1u<<24), one); + switchEndian = true; + } + readU32(in, switchEndian); // version + + // Reads header entries one by one from primary stream + index_t len = readIndex(in, switchEndian); + index_t gbwtLen = readIndex(in, switchEndian); + index_t numNodes = readIndex(in, switchEndian); + int32_t lineRate = readI32(in, switchEndian); + /*int32_t linesPerSide =*/ readI32(in, switchEndian); + int32_t offRate = readI32(in, switchEndian); + int32_t ftabChars = readI32(in, switchEndian); + index_t eftabLen = readIndex(in, switchEndian); + // BTL: chunkRate is now deprecated + int32_t flags = readI32(in, switchEndian); + bool entireReverse = false; + if(flags < 0) { + entireReverse = (((-flags) & GFM_ENTIRE_REV) != 0); + } + + // Create a new EbwtParams from the entries read from primary stream + GFMParams gh(len, gbwtLen, numNodes, lineRate, offRate, ftabChars, eftabLen, entireReverse); + + index_t nPat = readIndex(in, switchEndian); // nPat + in.seekg(nPat*sizeof(index_t), ios_base::cur); // skip plen + + // Skip rstarts + index_t nFrag = readIndex(in, switchEndian); + in.seekg(nFrag*sizeof(index_t)*3, ios_base::cur); + + // Skip ebwt + in.seekg(gh._gbwtTotLen, ios_base::cur); + + // Skip zOff from primary stream + index_t numZOffs = readIndex(in, switchEndian); + in.seekg(numZOffs * sizeof(index_t), ios_base::cur); + + // Skip fchr + in.seekg(5 * sizeof(index_t), ios_base::cur); + + // Skip ftab + in.seekg(gh._ftabLen*sizeof(index_t), ios_base::cur); + + // Skip eftab + in.seekg(gh._eftabLen*sizeof(index_t), ios_base::cur); + + // Read reference sequence names from primary index file + while(true) { + char c = '\0'; + in.read(&c, 1); + if(in.eof()) break; + if(c == '\0') break; + else if(c == '\n') { + refnames.push_back(""); + } else { + if(refnames.size() == 0) { + refnames.push_back(""); + } + refnames.back().push_back(c); + } + } + if(refnames.back().empty()) { + refnames.pop_back(); + } + + // Be kind + in.clear(); in.seekg(0, ios::beg); + assert(in.good()); +} + +/** + * Read reference names from the index with basename 'in' and store + * them in 'refnames'. + */ +template +void readEbwtRefnames(const string& instr, EList& refnames) { + ifstream in; + // Initialize our primary and secondary input-stream fields + in.open((instr + ".1." + gfm_ext).c_str(), ios_base::in | ios::binary); + if(!in.is_open()) { + throw GFMFileOpenException("Cannot open file " + instr); + } + assert(in.is_open()); + assert(in.good()); + assert_eq((streamoff)in.tellg(), ios::beg); + readEbwtRefnames(in, refnames); +} + +/////////////////////////////////////////////////////////////////////// +// +// Functions for building Ebwts +// +/////////////////////////////////////////////////////////////////////// + +/** + * Join several text strings together in a way that's compatible with + * the text-chunking scheme dictated by chunkRate parameter. + * + * The non-static member Ebwt::join additionally builds auxilliary + * arrays that maintain a mapping between chunks in the joined string + * and the original text strings. + */ +template +template +TStr GFM::join(EList& l, uint32_t seed) { + RandomSource rand; // reproducible given same seed + rand.init(seed); + TStr ret; + index_t guessLen = 0; + for(index_t i = 0; i < l.size(); i++) { + guessLen += length(l[i]); + } + ret.resize(guessLen); + index_t off = 0; + for(size_t i = 0; i < l.size(); i++) { + TStr& s = l[i]; + assert_gt(s.length(), 0); + for(size_t j = 0; j < s.size(); j++) { + ret.set(s[j], off++); + } + } + return ret; +} + +/** + * Join several text strings together in a way that's compatible with + * the text-chunking scheme dictated by chunkRate parameter. + * + * The non-static member Ebwt::join additionally builds auxilliary + * arrays that maintain a mapping between chunks in the joined string + * and the original text strings. + */ +template +template +void GFM::join(EList& l, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + uint32_t seed, + TStr& s, + bool include_rc, + bool CGtoTG) +{ + RandomSource rand; // reproducible given same seed + rand.init(seed); + RefReadInParams rpcp = refparams; + index_t guessLen = sztot; + if(include_rc) { + s.resize(guessLen << 1); + } else { + s.resize(guessLen); + } + ASSERT_ONLY(index_t szsi = 0); + TIndexOffU dstoff = 0; + for(index_t i = 0; i < l.size(); i++) { + // For each sequence we can pull out of istream l[i]... + assert(!l[i]->eof()); + bool first = true; + while(!l[i]->eof()) { + RefRecord rec = fastaRefReadAppend(*l[i], first, s, dstoff, rpcp); + first = false; + index_t bases = (index_t)rec.len; + assert_eq(rec.off, szs[szsi].off); + assert_eq(rec.len, szs[szsi].len); + assert_eq(rec.first, szs[szsi].first); + ASSERT_ONLY(szsi++); + if(bases == 0) continue; + } + } + + // Change 'C' in CG to 'T' so that CG becomes TG + if(CGtoTG) { + for(TIndexOffU i = 0; i + 1 < guessLen; i++) { + int nt1 = s[i], nt2 = s[i+1]; + if(nt1 == 1 && nt2 == 2) { + s[i] = 3; + } + } + } + + // Append reverse complement + if(include_rc) { + for (TIndexOffU i = 0; i < guessLen; i++) { + int nt = s[guessLen - i - 1]; + assert_range(0, 3, nt); + s[guessLen + i] = dnacomp[nt]; + } + } +} + +/** + * Join several text strings together according to the text-chunking + * scheme specified in the EbwtParams. Ebwt fields calculated in this + * function are written directly to disk. + * + * It is assumed, but not required, that the header values have already + * been written to 'out1' before this function is called. + * + * The static member Ebwt::join just returns a joined version of a + * list of strings without building any of the auxilliary arrays. + */ +template +template +void GFM::joinToDisk( + EList& l, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + TStr& ret, + ostream& out1, + ostream& out2) +{ + RefReadInParams rpcp = refparams; + assert_gt(szs.size(), 0); + assert_gt(l.size(), 0); + assert_gt(sztot, 0); + // Not every fragment represents a distinct sequence - many + // fragments may correspond to a single sequence. Count the + // number of sequences here by counting the number of "first" + // fragments. + this->_nPat = 0; + this->_nFrag = 0; + for(index_t i = 0; i < szs.size(); i++) { + if(szs[i].len > 0) this->_nFrag++; + if(szs[i].first && szs[i].len > 0) this->_nPat++; + } + assert_gt(this->_nPat, 0); + assert_geq(this->_nFrag, this->_nPat); + _rstarts.reset(); + writeIndex(out1, this->_nPat, this->toBe()); + // Allocate plen[] + try { + this->_plen.init(new index_t[this->_nPat], this->_nPat); + } catch(bad_alloc& e) { + cerr << "Out of memory allocating plen[] in Ebwt::join()" + << " at " << __FILE__ << ":" << __LINE__ << endl; + throw e; + } + // For each pattern, set plen + int npat = -1; + for(index_t i = 0; i < szs.size(); i++) { + if(szs[i].first && szs[i].len > 0) { + if(npat >= 0) { + writeIndex(out1, this->plen()[npat], this->toBe()); + } + npat++; + this->plen()[npat] = (szs[i].len + szs[i].off); + } else { + this->plen()[npat] += (szs[i].len + szs[i].off); + } + } + assert_eq((index_t)npat, this->_nPat-1); + writeIndex(out1, this->plen()[npat], this->toBe()); + // Write the number of fragments + writeIndex(out1, this->_nFrag, this->toBe()); + index_t seqsRead = 0; + ASSERT_ONLY(index_t szsi = 0); + ASSERT_ONLY(index_t entsWritten = 0); + index_t dstoff = 0; + // For each filebuf + for(unsigned int i = 0; i < l.size(); i++) { + assert(!l[i]->eof()); + bool first = true; + index_t patoff = 0; + // For each *fragment* (not necessary an entire sequence) we + // can pull out of istream l[i]... + while(!l[i]->eof()) { + string name; + // Push a new name onto our vector + _refnames.push_back(""); + RefRecord rec = fastaRefReadAppend( + *l[i], first, ret, dstoff, rpcp, &_refnames.back()); + first = false; + index_t bases = rec.len; + if(rec.first && rec.len > 0) { + if(_refnames.back().length() == 0) { + // If name was empty, replace with an index + ostringstream stm; + stm << seqsRead; + _refnames.back() = stm.str(); + } + } else { + // This record didn't actually start a new sequence so + // no need to add a name + //assert_eq(0, _refnames.back().length()); + _refnames.pop_back(); + } + // Increment seqsRead if this is the first fragment + if(rec.first && rec.len > 0) seqsRead++; + assert_lt(szsi, szs.size()); + assert_eq(rec.off, szs[szsi].off); + assert_eq(rec.len, szs[szsi].len); + assert_eq(rec.first, szs[szsi].first); + assert(rec.first || rec.off > 0); + ASSERT_ONLY(szsi++); + assert_leq(bases, this->plen()[seqsRead-1]); + // Reset the patoff if this is the first fragment + if(rec.first) patoff = 0; + patoff += rec.off; // add fragment's offset from end of last frag. + // Adjust rpcps + //index_t seq = seqsRead-1; +#ifndef NDEBUG + if(bases > 0) { + ASSERT_ONLY(entsWritten++); + } +#endif + // This is where rstarts elements are written to the output stream + //writeU32(out1, oldRetLen, this->toBe()); // offset from beginning of joined string + //writeU32(out1, seq, this->toBe()); // sequence id + //writeU32(out1, patoff, this->toBe()); // offset into sequence + patoff += (index_t)bases; + } + assert_gt(szsi, 0); + l[i]->reset(); + assert(!l[i]->eof()); +#ifndef NDEBUG + int c = l[i]->get(); + assert_eq('>', c); + assert(!l[i]->eof()); + l[i]->reset(); + assert(!l[i]->eof()); +#endif + } + assert_eq(entsWritten, this->_nFrag); +} + +/** + * Build an Ebwt from a string 's' and its suffix array 'sa' (which + * might actually be a suffix array *builder* that builds blocks of the + * array on demand). The bulk of the Ebwt, i.e. the ebwt and offs + * arrays, is written directly to disk. This is by design: keeping + * those arrays in memory needlessly increases the footprint of the + * building process. Instead, we prefer to build the Ebwt directly + * "to disk" and then read it back into memory later as necessary. + * + * It is assumed that the header values and join-related values (nPat, + * plen) have already been written to 'out1' before this function + * is called. When this function is finished, it will have + * additionally written ebwt, zOff, fchr, ftab and eftab to the primary + * file and offs to the secondary file. + * + * Assume DNA/RNA/any alphabet with 4 or fewer elements. + * Assume occ array entries are 32 bits each. + * + * @param sa the suffix array to convert to a Ebwt + * @param s the original string + * @param out + */ +template +template +void GFM::buildToDisk( + PathGraph& gbwt, + const TStr& s, + ostream& out1, + ostream& out2, + streampos headerPos) +{ + const GFMParams& gh = this->_gh; + assert(gh.repOk()); + assert_lt(s.length(), gh.gbwtLen()); + assert_eq(s.length(), gh._len); + assert_gt(gh._lineRate, 3); + + index_t gbwtLen = gh._gbwtLen; + streampos out1pos = out1.tellp(); + if(headerPos < 0) { + out1.seekp(8 + sizeof(index_t)); + } else { + out1.seekp(headerPos); + } + writeIndex(out1, gbwtLen, this->toBe()); + writeIndex(out1, gh._numNodes, this->toBe()); + out1.seekp(out1pos); + + index_t ftabLen = gh._ftabLen; + index_t sideSz = gh._sideSz; + index_t gbwtTotSz = gh._gbwtTotSz; + index_t fchr[] = {0, 0, 0, 0, 0}; + EList ftab(EBWT_CAT); + EList zOffs; + + // Save # of occurrences of each character as we walk along the bwt + index_t occ[4] = {0, 0, 0, 0}; + index_t occSave[4] = {0, 0, 0, 0}; + // # of occurrences of 1 in M arrays + index_t M_occ = 0, M_occSave = 0; + // Location in F that corresponds to 1 in M + index_t F_loc = 0, F_locSave = 0; + + // Record rows that should "absorb" adjacent rows in the ftab. + try { + VMSG_NL("Allocating ftab, absorbFtab"); + ftab.resize(ftabLen); + ftab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating ftab[] " + << "in GFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Allocate the side buffer; holds a single side as its being + // constructed and then written to disk. Reused across all sides. +#ifdef SIXTY4_FORMAT + EList gfmSide(EBWT_CAT); +#else + EList gfmSide(EBWT_CAT); +#endif + try { + // Used to calculate ftab and eftab, but having gfm costs a lot of memory + _gfm.init(new uint8_t[gh._gbwtTotLen], gh._gbwtTotLen, true); +#ifdef SIXTY4_FORMAT + gfmSide.resize(sideSz >> 3); +#else + gfmSide.resize(sideSz); +#endif + } catch(bad_alloc &e) { + cerr << "Out of memory allocating ebwtSide[] in " + << "GFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Points to the base offset within ebwt for the side currently + // being written + index_t side = 0; + + // Whether we're assembling a forward or a reverse bucket + bool fw = true; + int sideCur = 0; + + index_t si = 0; // string offset (chars) + ASSERT_ONLY(bool inSA = true); // true iff saI still points inside suffix + // array (as opposed to the padding at the + // end) + // Iterate over packed bwt bytes + VMSG_NL("Entering GFM loop"); + ASSERT_ONLY(index_t beforeGbwtOff = (index_t)out1.tellp()); + while(side < gbwtTotSz) { + // Sanity-check our cursor into the side buffer + assert_geq(sideCur, 0); + assert_lt(sideCur, (int)gh._sideGbwtSz); + assert_eq(0, side % sideSz); // 'side' must be on side boundary + if(sideCur == 0) { + memset(gfmSide.ptr(), 0, gh._sideGbwtSz); + gfmSide[sideCur] = 0; // clear + } + assert_lt(side + sideCur, gbwtTotSz); + // Iterate over bit-pairs in the si'th character of the BWT +#ifdef SIXTY4_FORMAT + for(int bpi = 0; bpi < 32; bpi++, si++) +#else + for(int bpi = 0; bpi < 4; bpi++, si++) +#endif + { + int gbwtChar = 0; // one of A, C, G, T, and Z + int F= 0, M = 0; // either 0 or 1 + index_t pos = 0; // pos on joined string + bool count = true; + if(si < gbwtLen) { + gbwt.nextRow(gbwtChar, F, M, pos); + + // (that might have triggered sa to calc next suf block) + if(gbwtChar == 'Z') { + // Don't add the 'Z' in the last column to the BWT + // transform; we can't encode a $ (only A C T or G) + // and counting it as, say, an A, will mess up the + // LF mapping + gbwtChar = 0; count = false; +#ifndef NDEBUG + if(zOffs.size() > 0) { + assert_gt(si, zOffs.back()); + } +#endif + zOffs.push_back(si); // remember GBWT row that corresponds to the 0th suffix + } else { + gbwtChar = asc2dna[gbwtChar]; + assert_lt(gbwtChar, 4); + // Update the fchr + fchr[gbwtChar]++; + } + + assert_lt(F, 2); + assert_lt(M, 2); + if(M == 1) { + assert_neq(F_loc, numeric_limits::max()); + F_loc = gbwt.nextFLocation(); +#ifndef NDEBUG + if(F_loc > 0) { + assert_gt(F_loc, F_locSave); + } +#endif + } + // Suffix array offset boundary? - update offset array + if(M == 1 && (M_occ & gh._offMask) == M_occ) { + assert_lt((M_occ >> gh._offRate), gh._offsLen); + // Write offsets directly to the secondary output + // stream, thereby avoiding keeping them in memory + writeIndex(out2, pos, this->toBe()); + } + } else { + // Strayed off the end of the SA, now we're just + // padding out a bucket +#ifndef NDEBUG + if(inSA) { + // Assert that we wrote all the characters in the + // string before now + assert_eq(si, gbwtLen); + inSA = false; + } +#endif + // 'A' used for padding; important that padding be + // counted in the occ[] array + gbwtChar = 0; + F = M = 0; + } + if(count) occ[gbwtChar]++; + if(M) M_occ++; + // Append BWT char to bwt section of current side + if(fw) { + // Forward bucket: fill from least to most +#ifdef SIXTY4_FORMAT + gfmSide[sideCur] |= ((uint64_t)gbwtChar << (bpi << 1)); + if(gbwtChar > 0) assert_gt(gfmSide[sideCur], 0); + // To be implemented ... + assert(false); + cerr << "Not implemented" << endl; + exit(1); +#else + pack_2b_in_8b(gbwtChar, gfmSide[sideCur], bpi); + assert_eq((gfmSide[sideCur] >> (bpi*2)) & 3, gbwtChar); + + int F_sideCur = (gh._sideGbwtSz + sideCur) >> 1; + int F_bpi = bpi + ((sideCur & 0x1) << 2); // Can be used as M_bpi as well + pack_1b_in_8b(F, gfmSide[F_sideCur], F_bpi); + assert_eq((gfmSide[F_sideCur] >> F_bpi) & 1, F); + + int M_sideCur = F_sideCur + (gh._sideGbwtSz >> 2); + pack_1b_in_8b(M, gfmSide[M_sideCur], F_bpi); + assert_eq((gfmSide[M_sideCur] >> F_bpi) & 1, M); +#endif + } else { + // Backward bucket: fill from most to least +#ifdef SIXTY4_FORMAT + gfmSide[sideCur] |= ((uint64_t)gbwtChar << ((31 - bpi) << 1)); + if(gbwtChar > 0) assert_gt(gfmSide[sideCur], 0); + // To be implemented ... + assert(false); + cerr << "Not implemented" << endl; + exit(1); +#else + pack_2b_in_8b(gbwtChar, gfmSide[sideCur], 3-bpi); + assert_eq((gfmSide[sideCur] >> ((3-bpi)*2)) & 3, gbwtChar); + // To be implemented ... + assert(false); + cerr << "Not implemented" << endl; + exit(1); +#endif + } + } // end loop over bit-pairs + assert_eq(0, (occ[0] + occ[1] + occ[2] + occ[3] + zOffs.size()) & 3); +#ifdef SIXTY4_FORMAT + assert_eq(0, si & 31); +#else + assert_eq(0, si & 3); +#endif + + sideCur++; + if((sideCur << 1) == (int)gh._sideGbwtSz) { + sideCur = 0; + index_t *uside = reinterpret_cast(gfmSide.ptr()); + // Write 'A', 'C', 'G', 'T', and '1' in M tallies + side += sideSz; + assert_leq(side, gh._gbwtTotSz); + uside[(sideSz / sizeof(index_t))-6] = endianizeIndex(F_locSave, this->toBe()); + uside[(sideSz / sizeof(index_t))-5] = endianizeIndex(M_occSave, this->toBe()); + uside[(sideSz / sizeof(index_t))-4] = endianizeIndex(occSave[0], this->toBe()); + uside[(sideSz / sizeof(index_t))-3] = endianizeIndex(occSave[1], this->toBe()); + uside[(sideSz / sizeof(index_t))-2] = endianizeIndex(occSave[2], this->toBe()); + uside[(sideSz / sizeof(index_t))-1] = endianizeIndex(occSave[3], this->toBe()); + F_locSave = F_loc; + M_occSave = M_occ; + occSave[0] = occ[0]; + occSave[1] = occ[1]; + occSave[2] = occ[2]; + occSave[3] = occ[3]; + // Write backward side to primary file + out1.write((const char *)gfmSide.ptr(), sideSz); + + // + memcpy(((char*)_gfm.get()) + side - sideSz, (const char *)gfmSide.ptr(), sideSz); + } + } + VMSG_NL("Exited GFM loop"); + // Assert that our loop counter got incremented right to the end + assert_eq(side, gh._gbwtTotSz); + // Assert that we wrote the expected amount to out1 + assert_eq(((index_t)out1.tellp() - beforeGbwtOff), gh._gbwtTotSz); + // assert that the last thing we did was write a forward bucket + + // + // Write zOffs to primary stream + // + assert_gt(zOffs.size(), 0); + writeIndex(out1, (index_t)zOffs.size(), this->toBe()); + for(size_t i = 0; i < zOffs.size(); i++) { + writeIndex(out1, zOffs[i], this->toBe()); + } + + // + // Finish building fchr + // + // Exclusive prefix sum on fchr + for(int i = 1; i < 4; i++) { + fchr[i] += fchr[i-1]; + } + assert_lt(fchr[3], gbwtLen); + // Shift everybody up by one + for(int i = 4; i >= 1; i--) { + fchr[i] = fchr[i-1]; + } + fchr[0] = 0; + if(_verbose) { + for(int i = 0; i < 5; i++) + cerr << "fchr[" << "ACGT$"[i] << "]: " << fchr[i] << endl; + } + // Write fchr to primary file + for(int i = 0; i < 5; i++) { + writeIndex(out1, fchr[i], this->toBe()); + } + _fchr.init(new index_t[5], 5, true); + memcpy(_fchr.get(), fchr, sizeof(index_t) * 5); + + + // Initialize _zGbwtByteOffs and _zGbwtBpOffs + _zOffs = zOffs; + postReadInit(gh); + + // Build ftab and eftab + EList > tFtab; + tFtab.resizeExact(ftabLen - 1); + for(index_t i = 0; i + 1 < ftabLen; i++) { + index_t q = i; + pair range(0, gh._gbwtLen); + SideLocus tloc, bloc; + SideLocus::initFromTopBot(range.first, range.second, gh, gfm(), tloc, bloc); + index_t j = 0; + for(; j < (index_t)gh._ftabChars; j++) { + int nt = q & 0x3; q >>= 2; + if(bloc.valid()) { + range = mapGLF(tloc, bloc, nt); + } else { + range = mapGLF1(range.first, tloc, nt); + } + if(range.first == (index_t)INDEX_MAX || range.first >= range.second) { + break; + } + if(range.first + 1 == range.second) { + tloc.initFromRow(range.first, gh, gfm()); + bloc.invalidate(); + } else { + SideLocus::initFromTopBot(range.first, range.second, gh, gfm(), tloc, bloc); + } + } + + if(range.first >= range.second || j < (index_t)gh._ftabChars) { + if(i == 0) { + tFtab[i].first = tFtab[i].second = 0; + } else { + tFtab[i].first = tFtab[i].second = tFtab[i-1].second; + } + } else { + tFtab[i].first = range.first; + tFtab[i].second = range.second; + } + +#ifndef NDEBUG + if(gbwt.ftab.size() > i) { + assert_eq(tFtab[i].first, gbwt.ftab[i].first); + assert_eq(tFtab[i].second, gbwt.ftab[i].second); + } +#endif + } + + // Clear memory + _gfm.reset(); + _fchr.reset(); + _zOffs.clear(); + _zGbwtByteOffs.clear(); + _zGbwtBpOffs.clear(); + + // + // Finish building ftab and build eftab + // + // Prefix sum on ftable + index_t eftabLen = 0; + for(index_t i = 1; i + 1 < ftabLen; i++) { + if(tFtab[i-1].second != tFtab[i].first) { + eftabLen += 2; + } + } + + if(gh._gbwtLen + (eftabLen >> 1) < gh._gbwtLen) { + cerr << "Too many eftab entries: " + << gh._gbwtLen << " + " << (eftabLen >> 1) + << " > " << (index_t)INDEX_MAX << endl; + throw 1; + } + + EList eftab(EBWT_CAT); + try { + eftab.resize(eftabLen); + eftab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating eftab[] " + << "in GFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + index_t eftabCur = 0; + ftab[0] = tFtab[0].first; + ftab[1] = tFtab[0].second; + for(index_t i = 1; i + 1 < ftabLen; i++) { + if(ftab[i] != tFtab[i].first) { + index_t lo = ftab[i]; + index_t hi = tFtab[i].first; + assert_lt(eftabCur*2+1, eftabLen); + eftab[eftabCur*2] = lo; + eftab[eftabCur*2+1] = hi; + // one node can be shared, and one node can have at most four incoming edges + assert_leq(lo, hi + 4); + ftab[i] = (eftabCur++) ^ (index_t)INDEX_MAX; // insert pointer into eftab + assert_eq(lo, GFM::ftabLo(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i)); + assert_eq(hi, GFM::ftabHi(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i)); + } + ftab[i+1] = tFtab[i].second; + } +#ifndef NDEBUG + for(index_t i = 0; i + 1 < ftabLen; i++ ){ + assert_eq(tFtab[i].first, GFM::ftabHi(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i)); + assert_eq(tFtab[i].second, GFM::ftabLo(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i+1)); + } +#endif + // Write ftab to primary file + for(index_t i = 0; i < ftabLen; i++) { + writeIndex(out1, ftab[i], this->toBe()); + } + // Write eftab to primary file + out1pos = out1.tellp(); + if(headerPos < 0) { + out1.seekp(24 + sizeof(index_t) * 3); + } else { + out1.seekp((int)headerPos + 16 + sizeof(index_t) * 2); + } + writeIndex(out1, eftabLen, this->toBe()); + out1.seekp(out1pos); + for(index_t i = 0; i < eftabLen; i++) { + writeIndex(out1, eftab[i], this->toBe()); + } + // Note: if you'd like to sanity-check the Ebwt, you'll have to + // read it back into memory first! + assert(!isInMemory()); + VMSG_NL("Exiting GFM::buildToDisk()"); +} + +/** + * Build an Ebwt from a string 's' and its suffix array 'sa' (which + * might actually be a suffix array *builder* that builds blocks of the + * array on demand). The bulk of the Ebwt, i.e. the ebwt and offs + * arrays, is written directly to disk. This is by design: keeping + * those arrays in memory needlessly increases the footprint of the + * building process. Instead, we prefer to build the Ebwt directly + * "to disk" and then read it back into memory later as necessary. + * + * It is assumed that the header values and join-related values (nPat, + * plen) have already been written to 'out1' before this function + * is called. When this function is finished, it will have + * additionally written ebwt, zOff, fchr, ftab and eftab to the primary + * file and offs to the secondary file. + * + * Assume DNA/RNA/any alphabet with 4 or fewer elements. + * Assume occ array entries are 32 bits each. + * + * @param sa the suffix array to convert to a Ebwt + * @param s the original string + * @param out + */ +template +template +void GFM::buildToDisk( + InorderBlockwiseSA& sa, + const TStr& s, + ostream& out1, + ostream& out2, + streampos headerPos) +{ + const GFMParams& gh = this->_gh; + assert(gh.repOk()); + assert(gh.linearFM()); + assert_lt(s.length(), gh.gbwtLen()); + assert_eq(s.length(), gh._len); + assert_gt(gh._lineRate, 3); + + index_t len = gh._len; + index_t gbwtLen = gh._gbwtLen; + assert_eq(len + 1, gbwtLen); + streampos out1pos = out1.tellp(); + if(headerPos < 0) { + out1.seekp(8 + sizeof(index_t)); + } else { + out1.seekp(headerPos); + } + writeIndex(out1, gbwtLen, this->toBe()); + writeIndex(out1, gh._numNodes, this->toBe()); + out1.seekp(out1pos); + + index_t ftabLen = gh._ftabLen; + index_t sideSz = gh._sideSz; + index_t gbwtTotSz = gh._gbwtTotSz; + index_t fchr[] = {0, 0, 0, 0, 0}; + EList ftab(EBWT_CAT); + EList zOffs; + + // Save # of occurrences of each character as we walk along the bwt + index_t occ[4] = {0, 0, 0, 0}; + index_t occSave[4] = {0, 0, 0, 0}; + + // Record rows that should "absorb" adjacent rows in the ftab. + // The absorbed rows represent suffixes shorter than the ftabChars + // cutoff. + uint8_t absorbCnt = 0; + EList absorbFtab(EBWT_CAT); + try { + VMSG_NL("Allocating ftab, absorbFtab"); + ftab.resize(ftabLen); + ftab.fillZero(); + absorbFtab.resize(ftabLen); + absorbFtab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating ftab[] or absorbFtab[] " + << "in GFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Allocate the side buffer; holds a single side as its being + // constructed and then written to disk. Reused across all sides. +#ifdef SIXTY4_FORMAT + EList gfmSide(EBWT_CAT); +#else + EList gfmSide(EBWT_CAT); +#endif + try { +#ifdef SIXTY4_FORMAT + gfmSide.resize(sideSz >> 3); +#else + gfmSide.resize(sideSz); +#endif + } catch(bad_alloc &e) { + cerr << "Out of memory allocating gfmSide[] in " + << "GFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Points to the base offset within ebwt for the side currently + // being written + index_t side = 0; + + // Whether we're assembling a forward or a reverse bucket + bool fw = true; + int sideCur = 0; + + // Have we skipped the '$' in the last column yet? + ASSERT_ONLY(bool dollarSkipped = false); + + index_t si = 0; // string offset (chars) + ASSERT_ONLY(index_t lastSufInt = 0); + ASSERT_ONLY(bool inSA = true); // true iff saI still points inside suffix + // array (as opposed to the padding at the + // end) + // Iterate over packed bwt bytes + VMSG_NL("Entering GFM loop"); + ASSERT_ONLY(index_t beforeGbwtOff = (index_t)out1.tellp()); + while(side < gbwtTotSz) { + // Sanity-check our cursor into the side buffer + assert_geq(sideCur, 0); + assert_lt(sideCur, (int)gh._sideGbwtSz); + assert_eq(0, side % sideSz); // 'side' must be on side boundary + gfmSide[sideCur] = 0; // clear + assert_lt(side + sideCur, gbwtTotSz); + // Iterate over bit-pairs in the si'th character of the BWT +#ifdef SIXTY4_FORMAT + for(int bpi = 0; bpi < 32; bpi++, si++) +#else + for(int bpi = 0; bpi < 4; bpi++, si++) +#endif + { + int bwtChar; + bool count = true; + if(si <= len) { + // Still in the SA; extract the bwtChar + index_t saElt = sa.nextSuffix(); + // (that might have triggered sa to calc next suf block) + if(saElt == 0) { + // Don't add the '$' in the last column to the BWT + // transform; we can't encode a $ (only A C T or G) + // and counting it as, say, an A, will mess up the + // LR mapping + bwtChar = 0; count = false; + ASSERT_ONLY(dollarSkipped = true); + zOffs.push_back(si); // remember the SA row that + // corresponds to the 0th suffix + } else { + bwtChar = (int)(s[saElt-1]); + assert_lt(bwtChar, 4); + // Update the fchr + fchr[bwtChar]++; + } + // Update ftab + if((len-saElt) >= (index_t)gh._ftabChars) { + // Turn the first ftabChars characters of the + // suffix into an integer index into ftab. The + // leftmost (lowest index) character of the suffix + // goes in the most significant bit pair if the + // integer. + index_t sufInt = 0; + for(int i = 0; i < gh._ftabChars; i++) { + sufInt <<= 2; + assert_lt((index_t)i, len-saElt); + sufInt |= (unsigned char)(s[saElt+i]); + } + // Assert that this prefix-of-suffix is greater + // than or equal to the last one (true b/c the + // suffix array is sorted) +#ifndef NDEBUG + if(lastSufInt > 0) assert_geq(sufInt, lastSufInt); + lastSufInt = sufInt; +#endif + // Update ftab + assert_lt(sufInt+1, ftabLen); + ftab[sufInt+1]++; + if(absorbCnt > 0) { + // Absorb all short suffixes since the last + // transition into this transition + absorbFtab[sufInt] = absorbCnt; + absorbCnt = 0; + } + } else { + // Otherwise if suffix is fewer than ftabChars + // characters long, then add it to the 'absorbCnt'; + // it will be absorbed into the next transition + assert_lt(absorbCnt, 255); + absorbCnt++; + } + // Suffix array offset boundary? - update offset array + if((si & gh._offMask) == si) { + assert_lt((si >> gh._offRate), gh._offsLen); + // Write offsets directly to the secondary output + // stream, thereby avoiding keeping them in memory + writeIndex(out2, saElt, this->toBe()); + } + } else { + // Strayed off the end of the SA, now we're just + // padding out a bucket +#ifndef NDEBUG + if(inSA) { + // Assert that we wrote all the characters in the + // string before now + assert_eq(si, len+1); + inSA = false; + } +#endif + // 'A' used for padding; important that padding be + // counted in the occ[] array + bwtChar = 0; + } + if(count) occ[bwtChar]++; + // Append BWT char to bwt section of current side + if(fw) { + // Forward bucket: fill from least to most +#ifdef SIXTY4_FORMAT + ebwtSide[sideCur] |= ((uint64_t)bwtChar << (bpi << 1)); + if(bwtChar > 0) assert_gt(ebwtSide[sideCur], 0); +#else + pack_2b_in_8b(bwtChar, gfmSide[sideCur], bpi); + assert_eq((gfmSide[sideCur] >> (bpi*2)) & 3, bwtChar); +#endif + } else { + // Backward bucket: fill from most to least +#ifdef SIXTY4_FORMAT + ebwtSide[sideCur] |= ((uint64_t)bwtChar << ((31 - bpi) << 1)); + if(bwtChar > 0) assert_gt(ebwtSide[sideCur], 0); +#else + pack_2b_in_8b(bwtChar, gfmSide[sideCur], 3-bpi); + assert_eq((gfmSide[sideCur] >> ((3-bpi)*2)) & 3, bwtChar); +#endif + } + } // end loop over bit-pairs + assert_eq(dollarSkipped ? 3 : 0, (occ[0] + occ[1] + occ[2] + occ[3]) & 3); +#ifdef SIXTY4_FORMAT + assert_eq(0, si & 31); +#else + assert_eq(0, si & 3); +#endif + + sideCur++; + if(sideCur == (int)gh._sideGbwtSz) { + sideCur = 0; + index_t *uside = reinterpret_cast(gfmSide.ptr()); + // Write 'A', 'C', 'G', 'T', and '1' in M tallies + side += sideSz; + assert_leq(side, gh._gbwtTotSz); + uside[(sideSz / sizeof(index_t))-4] = endianizeIndex(occSave[0], this->toBe()); + uside[(sideSz / sizeof(index_t))-3] = endianizeIndex(occSave[1], this->toBe()); + uside[(sideSz / sizeof(index_t))-2] = endianizeIndex(occSave[2], this->toBe()); + uside[(sideSz / sizeof(index_t))-1] = endianizeIndex(occSave[3], this->toBe()); + occSave[0] = occ[0]; + occSave[1] = occ[1]; + occSave[2] = occ[2]; + occSave[3] = occ[3]; + // Write backward side to primary file + out1.write((const char *)gfmSide.ptr(), sideSz); + } + } + VMSG_NL("Exited GFM loop"); + if(absorbCnt > 0) { + // Absorb any trailing, as-yet-unabsorbed short suffixes into + // the last element of ftab + absorbFtab[ftabLen-1] = absorbCnt; + } + + // Assert that our loop counter got incremented right to the end + assert_eq(side, gh._gbwtTotSz); + // Assert that we wrote the expected amount to out1 + assert_eq(((index_t)out1.tellp() - beforeGbwtOff), gh._gbwtTotSz); + // assert that the last thing we did was write a forward bucket + + // + // Write zOffs to primary stream + // + assert_eq(zOffs.size(), 1); + writeIndex(out1, (index_t)zOffs.size(), this->toBe()); + for(size_t i = 0; i < zOffs.size(); i++) { + assert_neq(zOffs[i], (index_t)OFF_MASK); + writeIndex(out1, zOffs[i], this->toBe()); + } + + // + // Finish building fchr + // + // Exclusive prefix sum on fchr + for(int i = 1; i < 4; i++) { + fchr[i] += fchr[i-1]; + } + assert_lt(fchr[3], gbwtLen); + // Shift everybody up by one + for(int i = 4; i >= 1; i--) { + fchr[i] = fchr[i-1]; + } + fchr[0] = 0; + if(_verbose) { + for(int i = 0; i < 5; i++) + cerr << "fchr[" << "ACGT$"[i] << "]: " << fchr[i] << endl; + } + // Write fchr to primary file + for(int i = 0; i < 5; i++) { + writeIndex(out1, fchr[i], this->toBe()); + } + + // + // Finish building ftab and build eftab + // + // Prefix sum on ftable + index_t eftabLen = 0; + assert_eq(0, absorbFtab[0]); + for(index_t i = 1; i < ftabLen; i++) { + if(absorbFtab[i] > 0) eftabLen += 2; + } + assert_leq(eftabLen, (index_t)gh._ftabChars*2); + eftabLen = gh._ftabChars*2; + EList eftab(EBWT_CAT); + try { + eftab.resize(eftabLen); + eftab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating eftab[] " + << "in GFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + index_t eftabCur = 0; + for(index_t i = 1; i < ftabLen; i++) { + index_t lo = ftab[i] + GFM::ftabHi(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, i-1); + if(absorbFtab[i] > 0) { + // Skip a number of short pattern indicated by absorbFtab[i] + index_t hi = lo + absorbFtab[i]; + assert_lt(eftabCur*2+1, eftabLen); + eftab[eftabCur*2] = lo; + eftab[eftabCur*2+1] = hi; + ftab[i] = (eftabCur++) ^ (index_t)OFF_MASK; // insert pointer into eftab + assert_eq(lo, GFM::ftabLo(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, i)); + assert_eq(hi, GFM::ftabHi(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, i)); + } else { + ftab[i] = lo; + } + } + assert_eq(GFM::ftabHi(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, ftabLen-1), len+1); + // Write ftab to primary file + for(index_t i = 0; i < ftabLen; i++) { + writeIndex(out1, ftab[i], this->toBe()); + } + // Write eftab to primary file + out1pos = out1.tellp(); + if(headerPos < 0) { + out1.seekp(24 + sizeof(index_t) * 3); + } else { + out1.seekp((int)headerPos + 16 + sizeof(index_t) * 2); + } + writeIndex(out1, eftabLen, this->toBe()); + out1.seekp(out1pos); + for(index_t i = 0; i < eftabLen; i++) { + writeIndex(out1, eftab[i], this->toBe()); + } + + // Note: if you'd like to sanity-check the Ebwt, you'll have to + // read it back into memory first! + assert(!isInMemory()); + VMSG_NL("Exiting GFM::buildToDisk()"); +} + +extern string gLastIOErrMsg; + +/* Checks whether a call to read() failed or not. */ +inline bool is_read_err(int fdesc, ssize_t ret, size_t count) { + if (ret < 0) { + std::stringstream sstm; + sstm << "ERRNO: " << errno << " ERR Msg:" << strerror(errno) << std::endl; + gLastIOErrMsg = sstm.str(); + return true; + } + return false; +} + +/* Checks whether a call to fread() failed or not. */ +inline bool is_fread_err(FILE* file_hd, size_t ret, size_t count) { + if (ferror(file_hd)) { + gLastIOErrMsg = "Error Reading File!"; + return true; + } + return false; +} + + +/////////////////////////////////////////////////////////////////////// +// +// Functions for searching Ebwts +// (But most of them are defined in the header) +// +/////////////////////////////////////////////////////////////////////// + +/** + * Take an offset into the joined text and translate it into the + * reference of the index it falls on, the offset into the reference, + * and the length of the reference. Use a binary search through the + * sorted list of reference fragment ranges t + */ +template +bool GFM::joinedToTextOff( + index_t qlen, + index_t off, + index_t& tidx, + index_t& textoff, + index_t& tlen, + bool rejectStraddle, + bool& straddled) const +{ + assert(rstarts() != NULL); // must have loaded rstarts + index_t top = 0; + index_t bot = _nFrag; // 1 greater than largest addressable element + index_t elt = (index_t)INDEX_MAX; + // Begin binary search + while(true) { + index_t oldelt = elt; + elt = top + ((bot - top) >> 1); + if(oldelt == elt) { + tidx = (index_t)INDEX_MAX; + return false; + } + index_t lower = rstarts()[elt*3]; + index_t upper; + if(elt == _nFrag-1) { + upper = _gh._len; + } else { + upper = rstarts()[((elt+1)*3)]; + } + assert_gt(upper, lower); + index_t fraglen = upper - lower; + if(lower <= off) { + if(upper > off) { // not last element, but it's within + // off is in this range; check if it falls off + if(off + qlen > upper) { + straddled = true; + if(rejectStraddle) { + // it falls off; signal no-go and return + tidx = (index_t)INDEX_MAX; + return false; + } + } + // This is the correct text idx whether the index is + // forward or reverse + tidx = rstarts()[(elt*3)+1]; + assert_lt(tidx, this->_nPat); + assert_leq(fraglen, this->plen()[tidx]); + // it doesn't fall off; now calculate textoff. + // Initially it's the number of characters that precede + // the alignment in the fragment + index_t fragoff = off - rstarts()[(elt*3)]; + if(!this->fw_) { + fragoff = fraglen - fragoff - 1; + fragoff -= (qlen-1); + } + // Add the alignment's offset into the fragment + // ('fragoff') to the fragment's offset within the text + textoff = fragoff + rstarts()[(elt*3)+2]; + assert_lt(textoff, this->plen()[tidx]); + break; // done with binary search + } else { + // 'off' belongs somewhere in the region between elt + // and bot + top = elt; + } + } else { + // 'off' belongs somewhere in the region between top and + // elt + bot = elt; + } + // continue with binary search + } + tlen = this->plen()[tidx]; + return true; +} + +template +bool GFM::textOffToJoined( + index_t tid, + index_t textoff, + index_t& off) const +{ + assert(rstarts() != NULL); // must have loaded rstarts + index_t top = 0; + index_t bot = _nFrag; // 1 greater than largest addressable element + index_t elt = (index_t)INDEX_MAX; + // Begin binary search + while(true) { + ASSERT_ONLY(index_t oldelt = elt); + elt = top + ((bot - top) >> 1); + assert_neq(oldelt, elt); // must have made progress + index_t elt_tid = rstarts()[elt*3 + 1]; + if(elt_tid == tid) { + while(true) { + if(tid != rstarts()[elt*3+1]) { + return false; + } + if(rstarts()[elt*3 + 2] <= textoff) break; + if(elt == 0) return false; + elt--; + } + while(true) { + assert_leq(rstarts()[elt*3+2], textoff); + if(elt + 1 == _nFrag || + tid + 1 == rstarts()[(elt+1)*3 + 1] || + textoff < rstarts()[(elt+1)*3 + 2]) { + off = rstarts()[elt*3] + (textoff - rstarts()[elt*3 + 2]); + if(elt + 1 < _nFrag && + tid == rstarts()[(elt+1)*3 + 1] && + off >= rstarts()[(elt+1)*3]) { + return false; + } + break; + } + elt++; + } + break; // done with binary search + } else if(elt_tid < tid) { + top = elt; + } else { + bot = elt; + } + // continue with binary search + } + return true; +} + +/** + * Walk 'steps' steps to the left and return the row arrived at. If we + * walk through the dollar sign, return 0xffffffff. + */ +template +index_t GFM::walkLeft(index_t row, index_t steps) const { + assert(offs() != NULL); + assert_neq((index_t)INDEX_MAX, row); + SideLocus l; + if(steps > 0) l.initFromRow(row, _gh, gfm()); + while(steps > 0) { + for(index_t i = 0; i < _zOffs.size(); i++) { + if(row == _zOffs[i]) return (index_t)INDEX_MAX; + } + pair range = this->mapGLF1(row, l, (pair *)NULL ASSERT_ONLY(, false)); + index_t newrow = range.first; + assert_neq((index_t)INDEX_MAX, newrow); + assert_neq(newrow, row); + row = newrow; + steps--; + if(steps > 0) l.initFromRow(row, _gh, gfm()); + } + return row; +} + +/** + * Resolve the reference offset of the BW element 'elt'. + */ +template +index_t GFM::getOffset(index_t row, index_t node) const { + assert(offs() != NULL); + assert_neq((index_t)INDEX_MAX, row); + for(index_t i = 0; i < _zOffs.size(); i++) { + if(row == _zOffs[i]) return 0; + } + if((node & _gh._offMask) == node) { + index_t off = this->offs()[node >> _gh._offRate]; + if(off != (index_t)INDEX_MAX) + return off; + } + index_t jumps = 0; + SideLocus l; + l.initFromRow(row, _gh, gfm()); + while(true) { + pair node_range(0, 0); + pair range = this->mapGLF1(row, l, &node_range ASSERT_ONLY(, false)); + index_t newrow = range.first; + jumps++; + assert_neq((index_t)INDEX_MAX, newrow); + assert_neq(newrow, row); + row = newrow; + for(index_t i = 0; i < _zOffs.size(); i++) { + if(row == _zOffs[i]) return jumps; + } + + if((node_range.first & _gh._offMask) == node_range.first) { + index_t off = this->offs()[node_range.first >> _gh._offRate]; + if(off != (index_t)INDEX_MAX) + return jumps + off; + } + l.initFromRow(row, _gh, gfm()); + } +} + +/** + * Resolve the reference offset of the BW element 'elt' such that + * the offset returned is at the right-hand side of the forward + * reference substring involved in the hit. + */ +template +index_t GFM::getOffset( + index_t elt, + bool fw, + index_t hitlen) const +{ + index_t off = getOffset(elt); + assert_neq((index_t)INDEX_MAX, off); + if(!fw) { + assert_lt(off, _gh._len); + off = _gh._len - off - 1; + assert_geq(off, hitlen-1); + off -= (hitlen-1); + assert_lt(off, _gh._len); + } + return off; +} + +/** + * Returns true iff the index contains the given string (exactly). The given + * string must contain only unambiguous characters. TODO: support ambiguous + * characters in 'str'. + */ +template +bool GFM::contains( + const BTDnaString& str, + index_t *otop, + index_t *obot) const +{ + assert(isInMemory()); + SideLocus tloc, bloc; + if(str.empty()) { + if(otop != NULL && obot != NULL) *otop = *obot = 0; + return true; + } + int c = str[str.length()-1]; + assert_range(0, 4, c); + index_t top = 0, bot = 0; + if(c < 4) { + top = fchr()[c]; + bot = fchr()[c+1]; + } else { + bool set = false; + for(int i = 0; i < 4; i++) { + if(fchr()[c] < fchr()[c+1]) { + if(set) { + return false; + } else { + set = true; + top = fchr()[c]; + bot = fchr()[c+1]; + } + } + } + } + assert_geq(bot, top); + tloc.initFromRow(top, gh(), gfm()); + bloc.initFromRow(bot, gh(), gfm()); + ASSERT_ONLY(index_t lastDiff = bot - top); + for(int64_t i = (int64_t)str.length()-2; i >= 0; i--) { + c = str[i]; + assert_range(0, 4, c); + if(c <= 3) { + top = mapLF(tloc, c); + bot = mapLF(bloc, c); + } else { + index_t sz = bot - top; + int c1 = mapLF1(top, tloc ASSERT_ONLY(, false)); + bot = mapLF(bloc, c1); + assert_leq(bot - top, sz); + if(bot - top < sz) { + // Encountered an N and could not proceed through it because + // there was more than one possible nucleotide we could replace + // it with + return false; + } + } + assert_geq(bot, top); + assert_leq(bot-top, lastDiff); + ASSERT_ONLY(lastDiff = bot-top); + if(i > 0) { + tloc.initFromRow(top, gh(), gfm()); + bloc.initFromRow(bot, gh(), gfm()); + } + } + if(otop != NULL && obot != NULL) { + *otop = top; *obot = bot; + } + return bot > top; +} + +/////////////////////////////////////////////////////////////////////// +// +// Functions for reading and writing Ebwts +// +/////////////////////////////////////////////////////////////////////// + +/** + * Read an Ebwt from file with given filename. + */ +template +void GFM::readIntoMemory( + int needEntireRev, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool justHeader, + GFMParams *params, + bool mmSweep, + bool loadNames, + bool startVerbose, + bool subIndex) +{ + bool switchEndian; // dummy; caller doesn't care +#ifdef BOWTIE_MM + char *mmFile[] = { NULL, NULL }; +#endif + if(_in1Str.length() > 0 && !subIndex) { + if(_verbose || startVerbose) { + cerr << " About to open input files: "; + logTime(cerr); + } + // Initialize our primary and secondary input-stream fields + if(_in1 != NULL) fclose(_in1); + if(_verbose || startVerbose) cerr << "Opening \"" << _in1Str.c_str() << "\"" << endl; + if((_in1 = fopen(_in1Str.c_str(), "rb")) == NULL) { + cerr << "Could not open index file " << _in1Str.c_str() << endl; + } + if(loadSASamp) { + if(_in2 != NULL) fclose(_in2); + if(_verbose || startVerbose) cerr << "Opening \"" << _in2Str.c_str() << "\"" << endl; + if((_in2 = fopen(_in2Str.c_str(), "rb")) == NULL) { + cerr << "Could not open index file " << _in2Str.c_str() << endl; + } + } + if(_verbose || startVerbose) { + cerr << " Finished opening input files: "; + logTime(cerr); + } + +#ifdef BOWTIE_MM + if(_useMm /*&& !justHeader*/) { + const char *names[] = {_in1Str.c_str(), _in2Str.c_str()}; + int fds[] = { fileno(_in1), fileno(_in2) }; + for(int i = 0; i < (loadSASamp ? 2 : 1); i++) { + if(_verbose || startVerbose) { + cerr << " Memory-mapping input file " << (i+1) << ": "; + logTime(cerr); + } + struct stat sbuf; + if (stat(names[i], &sbuf) == -1) { + perror("stat"); + cerr << "Error: Could not stat index file " << names[i] << " prior to memory-mapping" << endl; + throw 1; + } + mmFile[i] = (char*)mmap((void *)0, (size_t)sbuf.st_size, + PROT_READ, MAP_SHARED, fds[(size_t)i], 0); + if(mmFile[i] == (void *)(-1)) { + perror("mmap"); + cerr << "Error: Could not memory-map the index file " << names[i] << endl; + throw 1; + } + if(mmSweep) { + int sum = 0; + for(off_t j = 0; j < sbuf.st_size; j += 1024) { + sum += (int) mmFile[i][j]; + } + if(startVerbose) { + cerr << " Swept the memory-mapped ebwt index file 1; checksum: " << sum << ": "; + logTime(cerr); + } + } + } + mmFile1_ = mmFile[0]; + mmFile2_ = loadSASamp ? mmFile[1] : NULL; + } +#endif + } +#ifdef BOWTIE_MM + else if(_useMm && !justHeader) { + mmFile[0] = mmFile1_; + mmFile[1] = mmFile2_; + } + if(_useMm && !justHeader) { + assert(mmFile[0] == mmFile1_); + assert(mmFile[1] == mmFile2_); + } +#endif + + if(_verbose || startVerbose) { + cerr << " Reading header: "; + logTime(cerr); + } + + // Read endianness hints from both streams + size_t bytesRead = 0; + if(!subIndex) { + switchEndian = false; + uint32_t one = readU32(_in1, switchEndian); // 1st word of primary stream + bytesRead += 4; + if(loadSASamp) { +#ifndef NDEBUG + assert_eq(one, readU32(_in2, switchEndian)); // should match! +#else + readU32(_in2, switchEndian); +#endif + } + if(one != 1) { + assert_eq((1u<<24), one); + assert_eq(1, endianSwapU32(one)); + switchEndian = true; + } + + _toBigEndian = switchEndian; + + // Can't switch endianness and use memory-mapped files; in order to + // support this, someone has to modify the file to switch + // endiannesses appropriately, and we can't do this inside Bowtie + // or we might be setting up a race condition with other processes. + if(switchEndian && _useMm) { + cerr << "Error: Can't use memory-mapped files when the index is the opposite endianness" << endl; + throw 1; + } + + // Reads header entries one by one from primary stream + int index_version = (int)readU32(_in1, switchEndian); bytesRead += 4; + int major_index_version, minor_index_version; + string index_version_extra; + readIndexVersion(index_version, major_index_version, minor_index_version, index_version_extra); + int major_program_version, minor_program_version; + string program_version_extra; + readProgramVersion(major_program_version, minor_program_version, program_version_extra); + if(major_program_version < major_index_version || + (major_program_version == major_index_version && minor_program_version < minor_index_version)) { + cerr << "Warning: the current version of HISAT2 (" << HISAT2_VERSION << ") is older than the version (2." + << major_index_version << "." << minor_index_version; + if(index_version_extra.length() > 0) { + cerr << "-" << index_version_extra; + } + cerr << ") used to build the index." << endl; + cerr << " Users are strongly recommended to update HISAT2 to the latest version." << endl; + } + } else { + switchEndian = _toBigEndian; + } + + index_t len = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + index_t gbwtLen = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + assert_lt(len, gbwtLen); + index_t numNodes = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + int32_t lineRate = readI32(_in1, switchEndian); + bytesRead += 4; + /*int32_t linesPerSide =*/ readI32(_in1, switchEndian); + bytesRead += 4; + int32_t offRate = readI32(_in1, switchEndian); + bytesRead += 4; + // TODO: add isaRate to the actual file format (right now, the + // user has to tell us whether there's an ISA sample and what the + // sampling rate is. + int32_t ftabChars = readI32(_in1, switchEndian); + bytesRead += 4; + index_t eftabLen = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + // chunkRate was deprecated in an earlier version of Bowtie; now + // we use it to hold flags. + int32_t flags = readI32(_in1, switchEndian); + bool entireRev = false; + if(flags < 0 && (((-flags) & GFM_ENTIRE_REV) == 0)) { + if(needEntireRev != -1 && needEntireRev != 0) { + cerr << "Error: This index is compatible with 0.* versions of Bowtie, but not with 2.*" << endl + << "versions. Please build or download a version of the index that is compitble" << endl + << "with Bowtie 2.* (i.e. built with bowtie-build 2.* or later)" << endl; + throw 1; + } + } else entireRev = true; + bytesRead += 4; + + // Create a new EbwtParams from the entries read from primary stream + GFMParams *gh; + bool deleteGh = false; + if(params != NULL) { + params->init(len, gbwtLen, numNodes, lineRate, offRate, ftabChars, eftabLen, entireRev); + if(_verbose || startVerbose) params->print(cerr); + gh = params; + } else { + gh = new GFMParams(len, gbwtLen, numNodes, lineRate, offRate, ftabChars, eftabLen, entireRev); + deleteGh = true; + } + + // Set up overridden suffix-array-sample parameters + index_t offsLen = gh->_offsLen; + index_t offRateDiff = 0; + index_t offsLenSampled = offsLen; + if(_overrideOffRate > offRate) { + offRateDiff = _overrideOffRate - offRate; + } + if(offRateDiff > 0) { + offsLenSampled >>= offRateDiff; + if((offsLen & ~(((index_t)INDEX_MAX) << offRateDiff)) != 0) { + offsLenSampled++; + } + } + + // Can't override the offrate or isarate and use memory-mapped + // files; ultimately, all processes need to copy the sparser sample + // into their own memory spaces. +#if 0 + if(_useMm && (offRateDiff)) { + cerr << "Error: Can't use memory-mapped files when the offrate is overridden" << endl; + throw 1; + } +#endif + + // Read nPat from primary stream + this->_nPat = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + _plen.reset(); + // Read plen from primary stream + if(_useMm) { +#ifdef BOWTIE_MM + _plen.init((index_t*)(mmFile[0] + bytesRead), _nPat, false); + bytesRead += _nPat*sizeof(index_t); + fseek(_in1, _nPat*sizeof(index_t), SEEK_CUR); +#endif + } else { + try { + if(_verbose || startVerbose) { + cerr << "Reading plen (" << this->_nPat << "): "; + logTime(cerr); + } + _plen.init(new index_t[_nPat], _nPat, true); + if(switchEndian) { + for(index_t i = 0; i < this->_nPat; i++) { + plen()[i] = readIndex(_in1, switchEndian); + } + } else { + size_t r = MM_READ(_in1, (void*)(plen()), _nPat*sizeof(index_t)); + if(r != (size_t)(_nPat*sizeof(index_t))) { + cerr << "Error reading _plen[] array: " << r << ", " << _nPat*sizeof(index_t) << endl; + throw 1; + } + } + } catch(bad_alloc& e) { + cerr << "Out of memory allocating plen[] in Ebwt::read()" + << " at " << __FILE__ << ":" << __LINE__ << endl; + throw e; + } + } + + // TODO: I'm not consistent on what "header" means. Here I'm using + // "header" to mean everything that would exist in memory if we + // started to build the Ebwt but stopped short of the build*() step + // (i.e. everything up to and including join()). + if(justHeader) { + // Be kind + if(deleteGh) delete gh; +#ifdef BOWTIE_MM + fseek(_in1, 0, SEEK_SET); + if(loadSASamp) fseek(_in2, 0, SEEK_SET); +#else + rewind(_in1); + if(loadSASamp) rewind(_in2); +#endif + return; + } + + bool shmemLeader; + + this->_nFrag = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + if(_verbose || startVerbose) { + cerr << "Reading rstarts (" << this->_nFrag*3 << "): "; + logTime(cerr); + } + assert_geq(this->_nFrag, this->_nPat); + _rstarts.reset(); + if(loadRstarts) { + if(_useMm) { +#ifdef BOWTIE_MM + _rstarts.init((index_t*)(mmFile[0] + bytesRead), _nFrag*3, false); + bytesRead += this->_nFrag*sizeof(index_t)*3; + fseek(_in1, this->_nFrag*sizeof(index_t)*3, SEEK_CUR); +#endif + } else { + _rstarts.init(new index_t[_nFrag*3], _nFrag*3, true); + if(switchEndian) { + for(size_t i = 0; i < (size_t)(this->_nFrag*3); i += 3) { + // fragment starting position in joined reference + // string, text id, and fragment offset within text + this->rstarts()[i] = readIndex(_in1, switchEndian); + this->rstarts()[i+1] = readIndex(_in1, switchEndian); + this->rstarts()[i+2] = readIndex(_in1, switchEndian); + } + } else { + size_t r = MM_READ(_in1, (void *)rstarts(), this->_nFrag*sizeof(index_t)*3); + if(r != (size_t)(this->_nFrag*sizeof(index_t)*3)) { + cerr << "Error reading _rstarts[] array: " << r << ", " << (this->_nFrag*sizeof(index_t)*3) << endl; + throw 1; + } + } + } + } else { + // Skip em + assert(rstarts() == NULL); + bytesRead += this->_nFrag*sizeof(index_t)*3; + fseek(_in1, this->_nFrag*sizeof(index_t)*3, SEEK_CUR); + } + + _gfm.reset(); + if(_useMm) { +#ifdef BOWTIE_MM + _gfm.init((uint8_t*)(mmFile[0] + bytesRead), gh->_gbwtTotLen, false); + bytesRead += gh->_gbwtTotLen; + fseek(_in1, gh->_gbwtTotLen, SEEK_CUR); +#endif + } else { + // Allocate ebwt (big allocation) + if(_verbose || startVerbose) { + cerr << "Reading ebwt (" << gh->_gbwtTotLen << "): "; + logTime(cerr); + } + bool shmemLeader = true; + if(useShmem_) { + uint8_t *tmp = NULL; + shmemLeader = ALLOC_SHARED_U8( + (_in1Str + "[ebwt]"), gh->_gbwtTotLen, &tmp, + "gfm[]", (_verbose || startVerbose)); + assert(tmp != NULL); + _gfm.init(tmp, gh->_gbwtTotLen, false); + if(_verbose || startVerbose) { + cerr << " shared-mem " << (shmemLeader ? "leader" : "follower") << endl; + } + } else { + try { + _gfm.init(new uint8_t[gh->_gbwtTotLen], gh->_gbwtTotLen, true); + } catch(bad_alloc& e) { + cerr << "Out of memory allocating the gfm[] array for the Bowtie index. Please try" << endl + << "again on a computer with more memory." << endl; + throw 1; + } + } + if(shmemLeader) { + // Read ebwt from primary stream + uint64_t bytesLeft = gh->_gbwtTotLen; + char *pgbwt = (char*)this->gfm(); + while (bytesLeft>0){ + size_t r = MM_READ(this->_in1, (void *)pgbwt, bytesLeft); + if(MM_IS_IO_ERR(this->_in1, r, bytesLeft)) { + cerr << "Error reading _ebwt[] array: " << r << ", " + << bytesLeft << endl; + throw 1; + } + pgbwt += r; + bytesLeft -= r; + } + if(switchEndian) { + uint8_t *side = this->gfm(); + for(size_t i = 0; i < gh->_numSides; i++) { + index_t *cums = reinterpret_cast(side + gh->_sideSz - sizeof(index_t)*2); + cums[0] = endianSwapIndex(cums[0]); + cums[1] = endianSwapIndex(cums[1]); + side += this->_gh._sideSz; + } + } +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) NOTIFY_SHARED(gfm(), gh->_gbwtTotLen); +#endif + } else { + // Seek past the data and wait until master is finished + fseek(_in1, gh->_gbwtTotLen, SEEK_CUR); +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) WAIT_SHARED(gfm(), gh->_gbwtTotLen); +#endif + } + } + + // Read zOff from primary stream + _zOffs.clear(); + index_t num_zOffs = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + for(index_t i = 0; i < num_zOffs; i++) { + index_t zOff = readIndex(_in1, switchEndian); + bytesRead += sizeof(index_t); + assert_lt(zOff, gbwtLen); + _zOffs.push_back(zOff); + } + + try { + // Read fchr from primary stream + if(_verbose || startVerbose) cerr << "Reading fchr (5)" << endl; + _fchr.reset(); + if(_useMm) { +#ifdef BOWTIE_MM + _fchr.init((index_t*)(mmFile[0] + bytesRead), 5, false); + bytesRead += 5*sizeof(index_t); + fseek(_in1, 5*sizeof(index_t), SEEK_CUR); +#endif + } else { + _fchr.init(new index_t[5], 5, true); + for(int i = 0; i < 5; i++) { + this->fchr()[i] = readIndex(_in1, switchEndian); + assert_leq(this->fchr()[i], gbwtLen); + assert(i <= 0 || this->fchr()[i] >= this->fchr()[i-1]); + } + } + assert_gt(this->fchr()[4], this->fchr()[0]); + // Read ftab from primary stream + if(_verbose || startVerbose) { + if(loadFtab) { + cerr << "Reading ftab (" << gh->_ftabLen << "): "; + logTime(cerr); + } else { + cerr << "Skipping ftab (" << gh->_ftabLen << "): "; + } + } + _ftab.reset(); + if(loadFtab) { + if(_useMm) { +#ifdef BOWTIE_MM + _ftab.init((index_t*)(mmFile[0] + bytesRead), gh->_ftabLen, false); + bytesRead += gh->_ftabLen*sizeof(index_t); + fseek(_in1, gh->_ftabLen*sizeof(index_t), SEEK_CUR); +#endif + } else { + _ftab.init(new index_t[gh->_ftabLen], gh->_ftabLen, true); + if(switchEndian) { + for(size_t i = 0; i < gh->_ftabLen; i++) + this->ftab()[i] = readIndex(_in1, switchEndian); + } else { + size_t r = MM_READ(_in1, (void *)ftab(), gh->_ftabLen*sizeof(index_t)); + if(r != (size_t)(gh->_ftabLen*sizeof(index_t))) { + cerr << "Error reading _ftab[] array: " << r << ", " << (gh->_ftabLen*sizeof(index_t)) << endl; + throw 1; + } + } + } + // Read etab from primary stream + if(_verbose || startVerbose) { + if(loadFtab) { + cerr << "Reading eftab (" << gh->_eftabLen << "): "; + logTime(cerr); + } else { + cerr << "Skipping eftab (" << gh->_eftabLen << "): "; + } + + } + _eftab.reset(); + if(_useMm) { +#ifdef BOWTIE_MM + _eftab.init((index_t*)(mmFile[0] + bytesRead), gh->_eftabLen, false); + bytesRead += gh->_eftabLen*sizeof(index_t); + fseek(_in1, gh->_eftabLen*sizeof(index_t), SEEK_CUR); +#endif + } else { + _eftab.init(new index_t[gh->_eftabLen], gh->_eftabLen, true); + if(switchEndian) { + for(size_t i = 0; i < gh->_eftabLen; i++) + this->eftab()[i] = readIndex(_in1, switchEndian); + } else { + size_t r = MM_READ(_in1, (void *)this->eftab(), gh->_eftabLen*sizeof(index_t)); + if(r != (size_t)(gh->_eftabLen*sizeof(index_t))) { + cerr << "Error reading _eftab[] array: " << r << ", " << (gh->_eftabLen*sizeof(index_t)) << endl; + throw 1; + } + } + } + for(index_t i = 0; i < gh->_eftabLen; i++) { + if(i > 0 && this->eftab()[i] > 0) { + assert_geq(this->eftab()[i] + 4, this->eftab()[i-1]); + } else if(i > 0 && this->eftab()[i-1] == 0) { + assert_eq(0, this->eftab()[i]); + } + } + } else { + assert(ftab() == NULL); + assert(eftab() == NULL); + // Skip ftab + bytesRead += gh->_ftabLen*sizeof(index_t); + fseek(_in1, gh->_ftabLen*sizeof(index_t), SEEK_CUR); + // Skip eftab + bytesRead += sizeof(index_t); + bytesRead += gh->_eftabLen*sizeof(index_t); + fseek(_in1, gh->_eftabLen*sizeof(index_t), SEEK_CUR); + } + } catch(bad_alloc& e) { + cerr << "Out of memory allocating fchr[], ftab[] or eftab[] arrays for the Bowtie index." << endl + << "Please try again on a computer with more memory." << endl; + throw 1; + } + + // Read reference sequence names from primary index file (or not, + // if --refidx is specified) + if(loadNames) { + while(true) { + char c = '\0'; + if(MM_READ(_in1, (void *)(&c), (size_t)1) != (size_t)1) break; + bytesRead++; + if(c == '\0') break; + else if(c == '\n') { + this->_refnames.push_back(""); + } else { + if(this->_refnames.size() == 0) { + this->_refnames.push_back(""); + } + this->_refnames.back().push_back(c); + } + } + } + + _offs.reset(); + if(loadSASamp) { + bytesRead = 4; // reset for secondary index file (already read 1-sentinel) + + shmemLeader = true; + if(_verbose || startVerbose) { + cerr << "Reading offs (" << offsLenSampled << " " << std::setw(2) << sizeof(index_t)*8 << "-bit words): "; + logTime(cerr); + } + + if(!_useMm) { + if(!useShmem_) { + // Allocate offs_ + try { + _offs.init(new index_t[offsLenSampled], offsLenSampled, true); + } catch(bad_alloc& e) { + cerr << "Out of memory allocating the offs[] array for the Bowtie index." << endl + << "Please try again on a computer with more memory." << endl; + throw 1; + } + } else { + index_t *tmp = NULL; + shmemLeader = ALLOC_SHARED_U32( + (_in2Str + "[offs]"), offsLenSampled*sizeof(index_t), &tmp, + "offs", (_verbose || startVerbose)); + _offs.init((index_t*)tmp, offsLenSampled, false); + } + } + + if(_overrideOffRate < 32) { + if(shmemLeader) { + // Allocate offs (big allocation) + if(switchEndian || offRateDiff > 0) { + assert(!_useMm); + const index_t blockMaxSz = (index_t)(2 * 1024 * 1024); // 2 MB block size + const index_t blockMaxSzU = (blockMaxSz / sizeof(index_t)); // # U32s per block + char *buf; + try { + buf = new char[blockMaxSz]; + } catch(std::bad_alloc& e) { + cerr << "Error: Out of memory allocating part of _offs array: '" << e.what() << "'" << endl; + throw e; + } + for(index_t i = 0; i < offsLen; i += blockMaxSzU) { + index_t block = min((index_t)blockMaxSzU, (index_t)(offsLen - i)); + size_t r = MM_READ(_in2, (void *)buf, block * sizeof(index_t)); + if(r != (size_t)(block * sizeof(index_t))) { + cerr << "Error reading block of _offs[] array: " << r << ", " << (block * sizeof(index_t)) << endl; + throw 1; + } + index_t idx = i >> offRateDiff; + for(index_t j = 0; j < block; j += (1 << offRateDiff)) { + assert_lt(idx, offsLenSampled); + this->offs()[idx] = ((index_t*)buf)[j]; + if(switchEndian) { + this->offs()[idx] = endianSwapIndex(this->offs()[idx]); + } + idx++; + } + } + delete[] buf; + } else { + if(_useMm) { +#ifdef BOWTIE_MM + _offs.init((index_t*)(mmFile[1] + bytesRead), offsLen, false); + bytesRead += (offsLen * sizeof(index_t)); + fseek(_in2, (offsLen * sizeof(index_t)), SEEK_CUR); +#endif + } else { + // Workaround for small-index mode where MM_READ may + // not be able to handle read amounts greater than 2^32 + // bytes. + uint64_t bytesLeft = (offsLen * sizeof(index_t)); + char *offs = (char *)this->offs(); + + while(bytesLeft > 0) { + size_t r = MM_READ(_in2, (void*)offs, bytesLeft); + if(MM_IS_IO_ERR(_in2,r,bytesLeft)) { + cerr << "Error reading block of _offs[] array: " + << r << ", " << bytesLeft << gLastIOErrMsg << endl; + throw 1; + } + offs += r; + bytesLeft -= r; + } + } + } +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) NOTIFY_SHARED(offs(), offsLenSampled*sizeof(index_t)); +#endif + } else { + // Not the shmem leader + fseek(_in2, offsLenSampled*sizeof(index_t), SEEK_CUR); +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) WAIT_SHARED(offs(), offsLenSampled*sizeof(index_t)); +#endif + } + } + } + + this->postReadInit(*gh); // Initialize fields of Ebwt not read from file + if(_verbose || startVerbose) print(cerr, *gh); + + // The fact that _ebwt and friends actually point to something + // (other than NULL) now signals to other member functions that the + // Ebwt is loaded into memory. + + // Be kind + if(deleteGh) delete gh; + + if(!subIndex) { +#ifdef BOWTIE_MM + fseek(_in1, 0, SEEK_SET); + if(loadSASamp) fseek(_in2, 0, SEEK_SET); +#else + rewind(_in1); + if(loadSASamp) rewind(_in2); +#endif + } +} + +/** + * Read reference names from an input stream 'in' for an Ebwt primary + * file and store them in 'refnames'. + */ +template +void readGFMRefnames(istream& in, EList& refnames) { + // _in1 must already be open with the get cursor at the + // beginning and no error flags set. + assert(in.good()); + assert_eq((streamoff)in.tellg(), ios::beg); + + // Read endianness hints from both streams + bool switchEndian = false; + uint32_t one = readU32(in, switchEndian); // 1st word of primary stream + if(one != 1) { + assert_eq((1u<<24), one); + switchEndian = true; + } + + // Reads header entries one by one from primary stream + readU32(in, switchEndian); // version + index_t len = readIndex(in, switchEndian); + index_t gbwtLen = readIndex(in, switchEndian); + index_t numNodes = readIndex(in, switchEndian); + int32_t lineRate = readI32(in, switchEndian); + /*int32_t linesPerSide =*/ readI32(in, switchEndian); + int32_t offRate = readI32(in, switchEndian); + int32_t ftabChars = readI32(in, switchEndian); + index_t eftabLen = readIndex(in, switchEndian); + // BTL: chunkRate is now deprecated + int32_t flags = readI32(in, switchEndian); + bool entireReverse = false; + if(flags < 0) { + entireReverse = (((-flags) & GFM_ENTIRE_REV) != 0); + } + + // Create a new EbwtParams from the entries read from primary stream + GFM gh(len, gbwtLen, numNodes, lineRate, offRate, ftabChars, eftabLen, entireReverse); + + index_t nPat = readIndex(in, switchEndian); // nPat + in.seekg(nPat*sizeof(index_t), ios_base::cur); // skip plen + + // Skip rstarts + index_t nFrag = readIndex(in, switchEndian); + in.seekg(nFrag*sizeof(index_t)*3, ios_base::cur); + + // Skip ebwt + in.seekg(gh._ebwtTotLen, ios_base::cur); + + // Skip zOff from primary stream + index_t numZOffs = readIndex(in, switchEndian); + in.seekg(numZOffs * sizeof(index_t), ios_base::cur); + + // Skip fchr + in.seekg(5 * sizeof(index_t), ios_base::cur); + + // Skip ftab + in.seekg(gh._ftabLen*sizeof(index_t), ios_base::cur); + + // Skip eftab + in.seekg(gh._eftabLen*sizeof(index_t), ios_base::cur); + + // Read reference sequence names from primary index file + while(true) { + char c = '\0'; + in.read(&c, 1); + if(in.eof()) break; + if(c == '\0') break; + else if(c == '\n') { + refnames.push_back(""); + } else { + if(refnames.size() == 0) { + refnames.push_back(""); + } + refnames.back().push_back(c); + } + } + if(refnames.back().empty()) { + refnames.pop_back(); + } + + // Be kind + in.clear(); in.seekg(0, ios::beg); + assert(in.good()); +} + +/** + * Read reference names from the index with basename 'in' and store + * them in 'refnames'. + */ +template +void readGFMRefnames(const string& instr, EList& refnames) { + ifstream in; + // Initialize our primary and secondary input-stream fields + in.open((instr + ".1." + gfm_ext).c_str(), ios_base::in | ios::binary); + if(!in.is_open()) { + throw GFMFileOpenException("Cannot open file " + instr); + } + assert(in.is_open()); + assert(in.good()); + assert_eq((streamoff)in.tellg(), ios::beg); + readGFMRefnames(in, refnames); +} + +/** + * Read just enough of the Ebwt's header to get its flags + */ +template +int32_t GFM::readVersionFlags(const string& instr, int& major, int& minor, string& extra_version) { + ifstream in; + // Initialize our primary and secondary input-stream fields + in.open((instr + ".1." + gfm_ext).c_str(), ios_base::in | ios::binary); + if(!in.is_open()) { + throw GFMFileOpenException("Cannot open file " + instr); + } + assert(in.is_open()); + assert(in.good()); + bool switchEndian = false; + uint32_t one = readU32(in, switchEndian); // 1st word of primary stream + if(one != 1) { + assert_eq((1u<<24), one); + assert_eq(1, endianSwapU32(one)); + switchEndian = true; + } + index_t version = readU32(in, switchEndian); + readIndexVersion(version, major, minor, extra_version); + + readIndex(in, switchEndian); + readIndex(in, switchEndian); + readIndex(in, switchEndian); + readI32(in, switchEndian); + readI32(in, switchEndian); + readI32(in, switchEndian); + readI32(in, switchEndian); + readIndex(in, switchEndian); + int32_t flags = readI32(in, switchEndian); + return flags; +} + + +/** + * Write an extended Burrows-Wheeler transform to a pair of output + * streams. + * + * @param out1 output stream to primary file + * @param out2 output stream to secondary file + * @param be write in big endian? + */ +template +void GFM::writeFromMemory(bool justHeader, + ostream& out1, + ostream& out2) const +{ + const GFMParams& gh = this->_gh; + assert(gh.repOk()); + uint32_t be = this->toBe(); + assert(out1.good()); + assert(out2.good()); + + // When building an Ebwt, these header parameters are known + // "up-front", i.e., they can be written to disk immediately, + // before we join() or buildToDisk() + writeI32(out1, 1, be); // endian hint for priamry stream + writeI32(out2, 1, be); // endian hint for secondary stream + int version = getIndexVersion(); + writeI32(out1, version, be); // version + writeIndex(out1, gh._len, be); // length of string (and bwt and suffix array) + writeIndex(out1, 0, be); // dummy for gbwt len + writeIndex(out1, 0, be); // dummy for number of nodes + writeI32(out1, gh._lineRate, be); // 2^lineRate = size in bytes of 1 line + writeI32(out1, 2, be); // not used + writeI32(out1, gh._offRate, be); // every 2^offRate chars is "marked" + writeI32(out1, gh._ftabChars, be); // number of 2-bit chars used to address ftab + writeIndex(out1, 0, be); // eftab length + int32_t flags = 1; + if(gh._entireReverse) flags |= GFM_ENTIRE_REV; + writeI32(out1, -flags, be); // BTL: chunkRate is now deprecated + + if(!justHeader) { + assert(rstarts() != NULL); + assert(offs() != NULL); + assert(ftab() != NULL); + assert(eftab() != NULL); + assert(isInMemory()); + // These Ebwt parameters are known after the inputs strings have + // been joined() but before they have been built(). These can + // written to the disk next and then discarded from memory. + writeIndex(out1, this->_nPat, be); + for(index_t i = 0; i < this->_nPat; i++) + writeIndex(out1, this->plen()[i], be); + assert_geq(this->_nFrag, this->_nPat); + writeIndex(out1, this->_nFrag, be); + for(size_t i = 0; i < this->_nFrag*3; i++) + writeIndex(out1, this->rstarts()[i], be); + + // These Ebwt parameters are discovered only as the Ebwt is being + // built (in buildToDisk()). Of these, only 'offs' and 'ebwt' are + // terribly large. 'ebwt' is written to the primary file and then + // discarded from memory as it is built; 'offs' is similarly + // written to the secondary file and discarded. + writeIndex(out1, gh._gbwtTotLen, be); + out1.write((const char *)this->gfm(), gh._gbwtTotLen); + writeIndex(out1, (index_t)_zOffs.size(), be); + for(index_t i = 0; i < _zOffs.size(); i++) + writeIndex(out1, _zOffs[i], be); + index_t offsLen = gh._offsLen; + for(index_t i = 0; i < offsLen; i++) + writeIndex(out2, this->offs()[i], be); + + // 'fchr', 'ftab' and 'eftab' are not fully determined until the + // loop is finished, so they are written to the primary file after + // all of 'ebwt' has already been written and only then discarded + // from memory. + for(int i = 0; i < 5; i++) + writeIndex(out1, this->fchr()[i], be); + for(index_t i = 0; i < gh._ftabLen; i++) + writeIndex(out1, this->ftab()[i], be); + for(index_t i = 0; i < gh._eftabLen; i++) + writeIndex(out1, this->eftab()[i], be); + } +} + +/** + * Given a pair of strings representing output filenames, and assuming + * this Ebwt object is currently in memory, write out this Ebwt to the + * specified files. + * + * If sanity-checking is enabled, then once the streams have been + * fully written and closed, we reopen them and read them into a + * (hopefully) exact copy of this Ebwt. We then assert that the + * current Ebwt and the copy match in all of their fields. + */ +template +void GFM::writeFromMemory(bool justHeader, + const string& out1, + const string& out2) const +{ + ASSERT_ONLY(const GFMParams& gh = this->_gh); + assert(isInMemory()); + assert(gh.repOk()); + + ofstream fout1(out1.c_str(), ios::binary); + ofstream fout2(out2.c_str(), ios::binary); + writeFromMemory(justHeader, fout1, fout2); + fout1.close(); + fout2.close(); + + // Read the file back in and assert that all components match + if(_sanity) { +#if 0 + if(_verbose) + cout << "Re-reading \"" << out1 << "\"/\"" << out2 << "\" for sanity check" << endl; + Ebwt copy(out1, out2, _verbose, _sanity); + assert(!isInMemory()); + copy.loadIntoMemory(eh._color ? 1 : 0, true, false, false); + assert(isInMemory()); + assert_eq(eh._lineRate, copy.eh()._lineRate); + assert_eq(eh._offRate, copy.eh()._offRate); + assert_eq(eh._ftabChars, copy.eh()._ftabChars); + assert_eq(eh._len, copy.eh()._len); + assert_eq(_zOff, copy.zOff()); + assert_eq(_zEbwtBpOff, copy.zEbwtBpOff()); + assert_eq(_zEbwtByteOff, copy.zEbwtByteOff()); + assert_eq(_nPat, copy.nPat()); + for(index_t i = 0; i < _nPat; i++) + assert_eq(this->_plen[i], copy.plen()[i]); + assert_eq(this->_nFrag, copy.nFrag()); + for(size_t i = 0; i < this->nFrag*3; i++) { + assert_eq(this->_rstarts[i], copy.rstarts()[i]); + } + for(index_t i = 0; i < 5; i++) + assert_eq(this->_fchr[i], copy.fchr()[i]); + for(size_t i = 0; i < eh._ftabLen; i++) + assert_eq(this->ftab()[i], copy.ftab()[i]); + for(size_t i = 0; i < eh._eftabLen; i++) + assert_eq(this->eftab()[i], copy.eftab()[i]); + for(index_t i = 0; i < eh._offsLen; i++) + assert_eq(this->_offs[i], copy.offs()[i]); + for(index_t i = 0; i < eh._ebwtTotLen; i++) + assert_eq(this->ebwt()[i], copy.ebwt()[i]); + copy.sanityCheckAll(); + if(_verbose) + cout << "Read-in check passed for \"" << out1 << "\"/\"" << out2 << "\"" << endl; +#endif + } +} + +/** + * Write the rstarts array given the szs array for the reference. + */ +template +void GFM::szsToDisk(const EList& szs, ostream& os, int reverse) { + size_t seq = 0; + index_t off = 0; + index_t totlen = 0; + for(size_t i = 0; i < szs.size(); i++) { + if(szs[i].len == 0) continue; + if(szs[i].first) off = 0; + off += szs[i].off; + if(szs[i].first && szs[i].len > 0) seq++; + index_t seqm1 = (index_t)(seq-1); + assert_lt(seqm1, _nPat); + index_t fwoff = off; + if(reverse == REF_READ_REVERSE) { + // Invert pattern idxs + seqm1 = _nPat - seqm1 - 1; + // Invert pattern idxs + assert_leq(off + szs[i].len, plen()[seqm1]); + fwoff = plen()[seqm1] - (off + szs[i].len); + } + writeIndex(os, totlen, this->toBe()); // offset from beginning of joined string + writeIndex(os, (index_t)seqm1, this->toBe()); // sequence id + writeIndex(os, (index_t)fwoff, this->toBe()); // offset into sequence + totlen += szs[i].len; + off += szs[i].len; + } +} + + +/////////////////////////////////////////////////////////////////////// +// +// Functions for printing and sanity-checking Ebwts +// +/////////////////////////////////////////////////////////////////////// + +/** + * Check that the ebwt array is internally consistent up to (and not + * including) the given side index by re-counting the chars and + * comparing against the embedded occ[] arrays. + */ +template +void GFM::sanityCheckUpToSide(int upToSide) const { + assert(isInMemory()); + index_t occ[] = {0, 0, 0, 0}; + ASSERT_ONLY(index_t occ_save[] = {0, 0, 0, 0}); + index_t cur = 0; // byte pointer + const GFMParams& gh = this->_gh; + bool fw = false; + while(cur < (upToSide * gh._sideSz)) { + assert_leq(cur + gh._sideSz, gh._gbwtTotLen); + for(index_t i = 0; i < gh._sideGbwtSz; i++) { + uint8_t by = this->gfm()[cur + (fw ? i : gh._sideGbwtSz-i-1)]; + for(int j = 0; j < 4; j++) { + // Unpack from lowest to highest bit pair + int twoBit = unpack_2b_from_8b(by, fw ? j : 3-j); + occ[twoBit]++; + } + assert_eq(0, (occ[0] + occ[1] + occ[2] + occ[3]) % 4); + } + assert_eq(0, (occ[0] + occ[1] + occ[2] + occ[3]) % gh._sideGbwtLen); + // Finished forward bucket; check saved [A], [C], [G] and [T] + // against the index_ts encoded here + ASSERT_ONLY(const index_t *ugbwt = reinterpret_cast(&gfm()[cur + gh._sideGbwtSz])); + ASSERT_ONLY(index_t as = ugbwt[0]); + ASSERT_ONLY(index_t cs = ugbwt[1]); + ASSERT_ONLY(index_t gs = ugbwt[2]); + ASSERT_ONLY(index_t ts = ugbwt[3]); + assert(as == occ_save[0] || as == occ_save[0]-1); + assert_eq(cs, occ_save[1]); + assert_eq(gs, occ_save[2]); + assert_eq(ts, occ_save[3]); +#ifndef NDEBUG + occ_save[0] = occ[0]; + occ_save[1] = occ[1]; + occ_save[2] = occ[2]; + occ_save[3] = occ[3]; +#endif + cur += gh._sideSz; + } +} + +/** + * Sanity-check various pieces of the Ebwt + */ +template +void GFM::sanityCheckAll(int reverse) const { + const GFMParams& gh = this->_gh; + assert(isInMemory()); + // Check ftab + for(index_t i = 1; i < gh._ftabLen; i++) { + assert_geq(this->ftabHi(i), this->ftabLo(i-1)); + assert_geq(this->ftabLo(i), this->ftabHi(i-1)); + assert_leq(this->ftabHi(i), gh._gbwtLen); + } + assert_eq(this->ftabHi(gh._ftabLen-1), gh._gbwtLen); + + // Check offs + int seenLen = (gh._gbwtLen + 31) >> ((index_t)5); + uint32_t *seen; + try { + seen = new uint32_t[seenLen]; // bitvector marking seen offsets + } catch(bad_alloc& e) { + cerr << "Out of memory allocating seen[] at " << __FILE__ << ":" << __LINE__ << endl; + throw e; + } + memset(seen, 0, 4 * seenLen); + index_t offsLen = gh._offsLen; + for(index_t i = 0; i < offsLen; i++) { + assert_lt(this->offs()[i], gh._gbwtLen); + int w = this->offs()[i] >> 5; + int r = this->offs()[i] & 31; + assert_eq(0, (seen[w] >> r) & 1); // shouldn't have been seen before + seen[w] |= (1 << r); + } + delete[] seen; + + // Check nPat + assert_gt(this->_nPat, 0); + + // Check plen, flen + for(index_t i = 0; i < this->_nPat; i++) { + assert_geq(this->plen()[i], 0); + } + + // Check rstarts + if(this->rstarts() != NULL) { + for(index_t i = 0; i < this->_nFrag-1; i++) { + assert_gt(this->rstarts()[(i+1)*3], this->rstarts()[i*3]); + if(reverse == REF_READ_REVERSE) { + assert(this->rstarts()[(i*3)+1] >= this->rstarts()[((i+1)*3)+1]); + } else { + assert(this->rstarts()[(i*3)+1] <= this->rstarts()[((i+1)*3)+1]); + } + } + } + + // Check ebwt + sanityCheckUpToSide(gh._numSides); + VMSG_NL("Ebwt::sanityCheck passed"); +} + +/** + * Transform this Ebwt into the original string in linear time by using + * the LF mapping to walk backwards starting at the row correpsonding + * to the end of the string. The result is written to s. The Ebwt + * must be in memory. + */ +template +void GFM::restore(SString& s) const { + assert(isInMemory()); + s.resize(this->_gh._len); + index_t jumps = 0; + index_t i = this->_gh._len; // should point to final SA elt (starting with '$') + SideLocus l(i, this->_gh, this->gfm()); + while(true) { + for(index_t j = 0; j < _zOffs.size(); j++) { + if(i == _zOffs[j]) break; + } + assert_lt(jumps, this->_gh._len); + //if(_verbose) cout << "restore: i: " << i << endl; + // Not a marked row; go back a char in the original string + index_t newi = mapLF(l ASSERT_ONLY(, false)); + assert_neq(newi, i); + s[this->_gh._len - jumps - 1] = rowL(l); + i = newi; + l.initFromRow(i, this->_gh, this->gfm()); + jumps++; + } + assert_eq(jumps, this->_gh._len); +} + +/** + * Check that this Ebwt, when restored via restore(), matches up with + * the given array of reference sequences. For sanity checking. + */ +template +void GFM::checkOrigs( + const EList >& os, + bool mirror) const +{ + SString rest; + restore(rest); + index_t restOff = 0; + size_t i = 0, j = 0; + if(mirror) { + // TODO: FIXME + return; + } + while(i < os.size()) { + size_t olen = os[i].length(); + int lastorig = -1; + for(; j < olen; j++) { + size_t joff = j; + if(mirror) joff = olen - j - 1; + if((int)os[i][joff] == 4) { + // Skip over Ns + lastorig = -1; + if(!mirror) { + while(j < olen && (int)os[i][j] == 4) j++; + } else { + while(j < olen && (int)os[i][olen-j-1] == 4) j++; + } + j--; + continue; + } + assert_eq(os[i][joff], rest[restOff]); + lastorig = (int)os[i][joff]; + restOff++; + } + if(j == os[i].length()) { + // Moved to next sequence + i++; + j = 0; + } else { + // Just jumped over a gap + } + } +} + +/** + * Try to find the Bowtie index specified by the user. First try the + * exact path given by the user. Then try the user-provided string + * appended onto the path of the "indexes" subdirectory below this + * executable, then try the provided string appended onto + * "$HISAT2_INDEXES/". + */ +string adjustEbwtBase(const string& cmdline, + const string& ebwtFileBase, + bool verbose = false); + +#endif /*GFM_H_*/ diff --git a/gp.h b/gp.h new file mode 100644 index 0000000..02744fa --- /dev/null +++ b/gp.h @@ -0,0 +1,83 @@ +/* + * Copyright 2016, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +/* + * gp.h + * + */ + +#ifndef GP_H_ +#define GP_H_ + +#include +#include + +/** + * Encapsulates alignment policy for graph + */ +class GraphPolicy { + +public: + + GraphPolicy() { reset(); } + + GraphPolicy(size_t maxAltsTried, + bool useHaplotype, + bool haplotypeOnly, + bool enableCODIS) + { + init(maxAltsTried, + useHaplotype, + haplotypeOnly, + enableCODIS); + } + + /** + */ + void reset() { + init(0); + } + + /** + */ + void init(size_t maxAltsTried, + bool useHaplotype = false, + bool haplotypeOnly = false, + bool enableCODIS = false) + { + maxAltsTried_ = maxAltsTried; + useHaplotype_ = useHaplotype; + haplotypeOnly_ = haplotypeOnly; + enableCODIS_ = enableCODIS; + } + + size_t maxAltsTried() const { return maxAltsTried_; } + bool useHaplotype() const { return useHaplotype_; } + bool haplotypeOnly() const { return haplotypeOnly_; } + bool enableCODIS() const { return enableCODIS_; } + + +private: + size_t maxAltsTried_; + bool useHaplotype_; + bool haplotypeOnly_; + bool enableCODIS_; +}; + +#endif /*ndef GP_H_*/ diff --git a/group_walk.cpp b/group_walk.cpp new file mode 100644 index 0000000..4abb1de --- /dev/null +++ b/group_walk.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "group_walk.h" diff --git a/group_walk.h b/group_walk.h new file mode 100644 index 0000000..2a8c6d2 --- /dev/null +++ b/group_walk.h @@ -0,0 +1,1624 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* + * group_walk.h + * + * Classes and routines for walking a set of BW ranges backwards from the edge + * of a seed hit with the goal of resolving the offset of each row in each + * range. Here "offset" means offset into the concatenated string of all + * references. The main class is 'GroupWalk' and an important helper is + * 'GWState'. + * + * For each combination of seed offset and orientation, there is an associated + * QVal. Each QVal describes a (possibly empty) set of suffix array ranges. + * Call these "seed range sets." Each range in the set is "backed" by a range + * of the salist, represented as a PListSlice. Such a range is the origin of a + * walk. + * + * When an offset is resolved, it is entered into the salist via the + * PListSlice. Note that other routines in this same thread might also be + * setting elements of the salist, so routines here should expect that elements + * can go from unresolved to resolved at any time. + * + * What bookkeeping do we have to do as we walk? Before the first step, we + * convert the initial QVal into a list of SATuples; the SATuples are our link + * to the correpsonding ranges in the suffix array. The list of SATuples is + * then converted to a list of GWState objects; these keep track of where we + * are in our walk (e.g. what 'top' and 'bot' are, how many steps have we gone, + * etc) as well as how the elements in the current range correspond to elements + * from the original range. + * + * The user asks the GroupWalk to resolve another offset by calling advance(). + * advance() can be called in various ways: + * + * (a) The user can request that the GroupWalk proceed until a + * *particular* element is resolved, then return that resolved + * element. Other elements may be resolved along the way, but + * those results are buffered and may be dispensed in future calls + * to advance(). + * + * (b) The user can request that the GroupWalk select an as-yet- + * unreported element at random and and proceed until that element + * is resolved and report it. Again, other elements may be + * resolved along the way but they are buffered. + * + * (c) The user can request that the GroupWalk resolve elements in a + * particular BW range (with a particular offset and orientation) + * in an order of its choosing. The GroupWalk in this case + * attempts to resolve as many offsets as possible as quickly as + * possible, and returns them as soon as they're found. The res_ + * buffer is used in this case. + * + * (d) Like (c) but resolving elements at a paritcular offset and + * orientation instead of at a specific BW range. The res_ buffer + * is used in this case, since there's a chance that the + * + * There are simple ways to heuristically reduce the problem size while + * maintaining randomness. For instance, the user put a ceiling on the + * number of elements that we walk from any given seed offset or range. + * We can then trim away random subranges to reduce the size of the + * problem. There is no need for the caller to do this for us. + */ + +#ifndef GROUP_WALK_H_ +#define GROUP_WALK_H_ + +#include +#include +#include "ds.h" +#include "gfm.h" +#include "read.h" +#include "reference.h" +#include "mem_ids.h" + +/** + * Encapsulate an SA range and an associated list of slots where the resolved + * offsets can be placed. + */ +template +class SARangeWithOffs { + +public: + + SARangeWithOffs() { reset(); }; + + SARangeWithOffs( + index_t tf, + index_t bf, + index_t ntf, + index_t nbf, + const EList >& n_iedge_count, + size_t len, + const T& o) { + init(tf, bf, ntf, nbf, n_iedge_count, len, o); + } + + void init( + index_t tf, + index_t bf, + index_t ntf, + index_t nbf, + const EList >& n_iedge_count, + size_t len_, + const T& o) { + topf = tf; + botf = bf; + assert_lt(topf, botf); + node_top = ntf; + node_bot = nbf; + assert_leq(node_bot - node_top, botf - topf); + node_iedge_count = n_iedge_count; + len = len_, + offs = o; + } + + /** + * Reset to uninitialized state. + */ + void reset() { topf = (index_t)INDEX_MAX; } + + /** + * Return true if this is initialized. + */ + bool inited() const { + return topf != (index_t)INDEX_MAX; + } + + /** + * Return the number of times this reference substring occurs in the + * reference, which is also the size of the 'offs' TSlice. + */ + size_t size() const { return offs.size(); } + + index_t topf; // top in GBWT index + index_t botf; + index_t node_top; // top node + index_t node_bot; + EList > node_iedge_count; + size_t len; // length of the reference sequence involved + T offs; // offsets +}; + +/** + * A group of per-thread state that can be shared between all the GroupWalks + * used in that thread. + */ +template +struct GroupWalkState { + + GroupWalkState(int cat) : map(cat) { + masks[0].setCat(cat); + masks[1].setCat(cat); + masks[2].setCat(cat); + masks[3].setCat(cat); + } + + EList masks[4]; // temporary list for masks; used in GWState + EList map; // temporary list of GWState maps +}; + +/** + * Encapsulates counters that encode how much work the walk-left logic + * has done. + */ +struct WalkMetrics { + + WalkMetrics() { + reset(); + } + + /** + * Sum each across this object and 'm'. This is the only safe way + * to update a WalkMetrics shared by many threads. + */ + void merge(const WalkMetrics& m, bool getLock = false) { + ThreadSafe ts(&mutex_m, getLock); + bwops += m.bwops; + branches += m.branches; + resolves += m.resolves; + refresolves += m.refresolves; + reports += m.reports; + } + + /** + * Set all to 0. + */ + void reset() { + bwops = branches = resolves = refresolves = reports = 0; + } + + uint64_t bwops; // Burrows-Wheeler operations + uint64_t branches; // BW range branch-offs + uint64_t resolves; // # offs resolved with BW walk-left + uint64_t refresolves; // # resolutions caused by reference scanning + uint64_t reports; // # offs reported (1 can be reported many times) + MUTEX_T mutex_m; +}; + +/** + * Coordinates for a BW element that the GroupWalk might resolve. + */ +template +struct GWElt { + + GWElt() { reset(); } + + /** + * Reset GWElt to uninitialized state. + */ + void reset() { + offidx = range = elt = len = (index_t)OFF_MASK; + fw = false; + } + + /** + * Initialize this WalkResult. + */ + void init( + index_t oi, + bool f, + index_t r, + index_t e, + index_t l) + { + offidx = oi; + fw = f; + range = r; + elt = e; + len = l; + } + + /** + * Return true iff this GWElt and the given GWElt refer to the same + * element. + */ + bool operator==(const GWElt& o) const { + return offidx == o.offidx && + fw == o.fw && + range == o.range && + elt == o.elt && + len == o.len; + } + + /** + * Return true iff this GWElt and the given GWElt refer to + * different elements. + */ + bool operator!=(const GWElt& o) const { + return !(*this == o); + } + + index_t offidx; // seed offset index + bool fw; // strand + index_t range; // range + index_t elt; // element + index_t len; // length +}; + +/** + * A record encapsulating the result of looking up one BW element in + * the Bowtie index. + */ +template +struct WalkResult { + + WalkResult() { reset(); } + + /** + * Reset GWElt to uninitialized state. + */ + void reset() { + elt.reset(); + bwrow = toff = (index_t)OFF_MASK; + } + + /** + * Initialize this WalkResult. + */ + void init( + index_t oi, // seed offset index + bool f, // strand + index_t r, // range + index_t e, // element + index_t bwr, // BW row + index_t len, // length + index_t to) // text offset + { + elt.init(oi, f, r, e, len); + bwrow = bwr; + toff = to; + } + + GWElt elt; // element resolved + index_t bwrow; // SA row resolved + index_t toff; // resolved offset from SA sample +}; + +/** + * A GW hit encapsulates an SATuple describing a reference substring + * in the cache, along with a bool indicating whether each element of + * the hit has been reported yet. + */ +template +class GWHit { + +public: + GWHit() : + fmap(0, GW_CAT), + offidx((index_t)OFF_MASK), + fw(false), + range((index_t)OFF_MASK), + len((index_t)OFF_MASK), + reported_(0, GW_CAT), + nrep_(0) + { + assert(repOkBasic()); + } + + /** + * Initialize with a new SA range. Resolve the done vector so that + * there's one bool per suffix array element. + */ + void init( + SARangeWithOffs& sa, + index_t oi, + bool f, + index_t r) + { + nrep_ = 0; + offidx = oi; + fw = f; + range = r; + len = (index_t)sa.len; + reported_.resize(sa.offs.size()); + reported_.fill(false); + fmap.resize(sa.offs.size()); + fmap.fill(make_pair((index_t)OFF_MASK, (index_t)OFF_MASK)); + } + + /** + * Clear contents of sat and done. + */ + void reset() { + reported_.clear(); + fmap.clear(); + nrep_ = 0; + offidx = (index_t)OFF_MASK; + fw = false; + range = (index_t)OFF_MASK; + len = (index_t)OFF_MASK; + } + +#ifndef NDEBUG + /** + * Check that GWHit is internally consistent. If a pointer to an + * EList of GWStates is given, we assume that it is the EList + * corresponding to this GWHit and check whether the forward and + * reverse mappings match up for the as-yet-unresolved elements. + */ + bool repOk(const SARangeWithOffs& sa) const { + assert_eq(reported_.size(), sa.offs.size()); + assert_eq(fmap.size(), sa.offs.size()); + // Shouldn't be any repeats among as-yet-unresolveds + size_t nrep = 0; + for(size_t i = 0; i < fmap.size(); i++) { + if(reported_[i]) nrep++; + if(sa.offs[i] != (index_t)OFF_MASK) { + continue; + } + for(size_t j = i+1; j < fmap.size(); j++) { + if(sa.offs[j] != (index_t)OFF_MASK) { + continue; + } + assert(fmap[i] != fmap[j]); + } + } + assert_eq(nrep_, nrep); + return true; + } + + /** + * Return true iff this GWHit is not obviously corrupt. + */ + bool repOkBasic() { + return true; + } +#endif + + /** + * Set the ith element to be reported. + */ + void setReported(index_t i) { + assert(!reported_[i]); + assert_lt(i, reported_.size()); + reported_[i] = true; + nrep_++; + } + + /** + * Return true iff element i has been reported. + */ + bool reported(index_t i) const { + assert_lt(i, reported_.size()); + return reported_[i]; + } + + /** + * Return true iff all elements have been reported. + */ + bool done() const { + assert_leq(nrep_, reported_.size()); + return nrep_ == reported_.size(); + } + + EList, 16> fmap; // forward map; to GWState & elt + index_t offidx; // offset idx + bool fw; // orientation + index_t range; // original range index + index_t len; // length of hit + +protected: + + EList reported_; // per-elt bool indicating whether it's been reported + index_t nrep_; +}; + +/** + * Encapsulates the progress made along a particular path from the original + * range. + */ +template +class GWState { + +public: + + GWState() : map_(0, GW_CAT) { + reset(); assert(repOkBasic()); + } + + /** + * Initialize this GWState with new gfm, top, bot, step, and sat. + * + * We assume map is already set up. + * + * Returns true iff at least one elt was resolved. + */ + template + pair init( + const GFM& gfm, // index to walk left in + const BitPairReference& ref, // bitpair-encoded reference + SARangeWithOffs& sa, // SA range with offsets + EList& sts, // EList of GWStates for range being advanced + GWHit& hit, // Corresponding hit structure + index_t range, // which range is this? + bool reportList, // if true, "report" resolved offsets immediately by adding them to 'res' list + EList, 16>* res, // EList where resolved offsets should be appended + index_t tp, // top of range at this step + index_t bt, // bot of range at this step + index_t n_tp, // node at top + index_t n_bt, // node at bot + const EList >& n_iedge_count, + index_t st, // # steps taken to get to this step + WalkMetrics& met) + { + assert_gt(bt, tp); + assert_gt(n_bt, n_tp); + assert_geq(bt - tp, n_bt - n_tp); + assert_lt(range, sts.size()); + top = tp; + bot = bt; + node_top = n_tp; + node_bot = n_bt; + node_iedge_count = n_iedge_count; + step = st; + assert(!inited_); + ASSERT_ONLY(inited_ = true); + ASSERT_ONLY(lastStep_ = step-1); + return init(gfm, ref, sa, sts, hit, range, reportList, res, met); + } + + /** + * Initialize this GWState. + * + * We assume map is already set up, and that 'step' is equal to the + * number of steps taken to get to the new top/bot pair *currently* + * in the top and bot fields. + * + * Returns a pair of numbers, the first being the number of + * resolved but unreported offsets found during this advance, the + * second being the number of as-yet-unresolved offsets. + */ + template + pair init( + const GFM& gfm, // forward Bowtie index + const BitPairReference& ref, // bitpair-encoded reference + SARangeWithOffs& sa, // SA range with offsets + EList& st, // EList of GWStates for advancing range + GWHit& hit, // Corresponding hit structure + index_t range, // range being inited + bool reportList, // report resolutions, adding to 'res' list? + EList, 16>* res, // EList to append resolutions + WalkMetrics& met) // update these metrics + { + assert(inited_); + assert_eq(step, lastStep_+1); + ASSERT_ONLY(lastStep_++); + assert_leq((index_t)step, gfm.gh().len()); + assert_lt(range, st.size()); + pair ret = make_pair(0, 0); + index_t trimBegin = 0, trimEnd = 0; + bool empty = true; // assume all resolved until proven otherwise + // Commit new information, if any, to the PListSlide. Also, + // trim and check if we're done. + assert_eq(node_bot - node_top, map_.size()); + ASSERT_ONLY(index_t num_orig_iedges = 0, orig_e = 0); + index_t num_iedges = 0, e = 0; + for(size_t i = mapi_; i < map_.size(); i++) { + bool resolved = (off((index_t)i, sa) != (index_t)OFF_MASK); + if(!resolved) { +#ifndef NDEBUG + while(orig_e < sa.node_iedge_count.size()) { + if(map((index_t)i) <= sa.node_iedge_count[orig_e].first) { + break; + } + num_orig_iedges += sa.node_iedge_count[orig_e].second; + orig_e++; + } +#endif + while(e < node_iedge_count.size()) { + if(i <= node_iedge_count[e].first) { + break; + } + num_iedges += node_iedge_count[e].second; + e++; + } + // Elt not resolved yet; try to resolve it now + index_t bwrow = (index_t)(top + i + num_iedges); + index_t node = (index_t)(node_top + i); + index_t toff = gfm.tryOffset(bwrow, node); + ASSERT_ONLY(index_t origBwRow = sa.topf + map((index_t)i) + num_orig_iedges); + ASSERT_ONLY(index_t origNode = sa.node_top + map((index_t)i)); + assert_eq(bwrow, gfm.walkLeft(origBwRow, step)); + if(toff != (index_t)OFF_MASK) { + // Yes, toff was resolvable + assert_eq(toff, gfm.getOffset(bwrow, node)); + met.resolves++; + toff += step; + assert_eq(toff, gfm.getOffset(origBwRow, origNode)); + setOff((index_t)i, toff, sa, met); + if(!reportList) ret.first++; +#if 0 +// used to be #ifndef NDEBUG, but since we no longer require that the reference +// string info be included, this is no longer relevant. + + // Sanity check that the reference characters under this + // hit match the seed characters in hit.satup->key.seq. + // This is NOT a check that we associated the exact right + // text offset with the BW row. This is an important + // distinction because when resolved offsets are filled in + // via refernce scanning, they are not necessarily the + // exact right text offsets to associate with the + // respective BW rows but they WILL all be correct w/r/t + // the reference sequence underneath, which is what really + // matters here. + index_t tidx = (index_t)OFF_MASK, tof, tlen; + bool straddled = false; + gfm.joinedToTextOff( + hit.len, // length of seed + toff, // offset in joined reference string + tidx, // reference sequence id + tof, // offset in reference coordinates + tlen, // length of reference sequence + true, // don't reject straddlers + straddled); + if(tidx != (index_t)OFF_MASK && + hit.satup->key.seq != std::numeric_limits::max()) + { + // key: 2-bit characters packed into a 64-bit word with + // the least significant bitpair corresponding to the + // rightmost character on the Watson reference strand. + uint64_t key = hit.satup->key.seq; + for(int64_t j = tof + hit.len-1; j >= tof; j--) { + // Get next reference base to the left + int c = ref.getBase(tidx, j); + assert_range(0, 3, c); + // Must equal least significant bitpair of key + if(c != (int)(key & 3)) { + // Oops; when we jump to the piece of the + // reference where the seed hit is, it doesn't + // match the seed hit. Before dying, check + // whether we have the right spot in the joined + // reference string + SString jref; + gfm.restore(jref); + uint64_t key2 = hit.satup->key.seq; + for(int64_t k = toff + hit.len-1; k >= toff; k--) { + int c = jref[k]; + assert_range(0, 3, c); + assert_eq(c, (int)(key2 & 3)); + key2 >>= 2; + } + assert(false); + } + key >>= 2; + } + } +#endif + } + } + // Is the element resolved? We ask this regardless of how it was + // resolved (whether this function did it just now, whether it did + // it a while ago, or whether some other function outside GroupWalk + // did it). + if(off((index_t)i, sa) != (index_t)OFF_MASK) { + if(reportList && !hit.reported(map((index_t)i))) { + // Report it + index_t toff = off((index_t)i, sa); + assert(res != NULL); + res->expand(); + index_t origBwRow = sa.topf + map((index_t)i); + res->back().init( + hit.offidx, // offset idx + hit.fw, // orientation + hit.range, // original range index + map((index_t)i), // original element offset + origBwRow, // BW row resolved + hit.len, // hit length + toff); // text offset + hit.setReported(map((index_t)i)); + met.reports++; + } + // Offset resolved + if(empty) { + // Haven't seen a non-empty entry yet, so we + // can trim this from the beginning. + trimBegin++; + } else { + trimEnd++; + } + } else { + // Offset not yet resolved + ret.second++; + trimEnd = 0; + empty = false; + // Set the forward map in the corresponding GWHit + // object to point to the appropriate element of our + // range + assert_geq(i, mapi_); + index_t bmap = map((index_t)i); + hit.fmap[bmap].first = range; + hit.fmap[bmap].second = (index_t)i; +#ifndef NDEBUG + for(size_t j = 0; j < bmap; j++) { + if(sa.offs[j] == (index_t)OFF_MASK && + hit.fmap[j].first == range) + { + assert_neq(i, hit.fmap[j].second); + } + } +#endif + } + } + + // Trim from beginning + assert_geq(trimBegin, 0); + mapi_ += trimBegin; + if(trimBegin > 0) { + top += trimBegin; + index_t e = 0; + for(; e < node_iedge_count.size(); e++) { + if(node_iedge_count[e].first >= trimBegin) break; + assert_geq(top, node_iedge_count[e].second); + top += node_iedge_count[e].second; + } + if(e > 0) node_iedge_count.erase(0, e); + for(e = 0; e < node_iedge_count.size(); e++) { + assert_geq(node_iedge_count[e].first, trimBegin); + node_iedge_count[e].first -= trimBegin; + } + } + + node_top += trimBegin; + if(trimEnd > 0) { + // Trim from end + map_.resize(map_.size() - trimEnd); + bot -= trimEnd; + index_t node_range = node_bot - node_top; + while(node_iedge_count.size() > 0) { + if(node_iedge_count.back().first < (node_range - trimEnd)) break; + assert_geq(bot, node_iedge_count.back().second); + bot -= node_iedge_count.back().second; + node_iedge_count.pop_back(); + } + } + node_bot -= trimEnd; +#ifndef NDEBUG + assert_leq(node_top, node_bot); + index_t num_nodes = node_bot - node_top; + index_t add = 0; + for(index_t e = 0; e < node_iedge_count.size(); e++) { + assert_lt(node_iedge_count[e].first, num_nodes); + add += node_iedge_count[e].second; + } + assert_eq(bot - top, num_nodes + add); + +#endif + if(empty) { + assert(done()); +#ifndef NDEBUG + // If range is done, all elements from map should be + // resolved + for(size_t i = mapi_; i < map_.size(); i++) { + assert_neq((index_t)OFF_MASK, off((index_t)i, sa)); + } + // If this range is done, then it should be the case that + // all elements in the corresponding GWHit that point to + // this range are resolved. + for(size_t i = 0; i < hit.fmap.size(); i++) { + if(sa.offs[i] == (index_t)OFF_MASK) { + assert_neq(range, hit.fmap[i].first); + } + } +#endif + return ret; + } else { + assert(!done()); + } + // Is there a dollar sign in the middle of the range? + tmp_zOffs.clear(); + for(index_t i = 0; i < gfm._zOffs.size(); i++) { +#ifndef NDEBUG + if(i > 0) { + assert_lt(gfm._zOffs[i-1], gfm._zOffs[i]); + } +#endif + assert_neq(top, gfm._zOffs[i]); + // assert_neq(bot-1, gfm._zOffs[i]); + if(gfm._zOffs[i] > top && gfm._zOffs[i] < bot) { + tmp_zOffs.push_back(gfm._zOffs[i]); + } + } + + // Yes, the dollar sign is in the middle of this range. We + // must split it into the two ranges on either side of the + // dollar. Let 'bot' and 'top' delimit the portion of the + // range prior to the dollar. + if(tmp_zOffs.size() > 0) { + tmp_gbwt_to_node.clear(); + index_t n = 0, e = 0; + for(index_t r = 0; r < (bot - top); r++) { + tmp_gbwt_to_node.push_back(n); + if(e < node_iedge_count.size()) { + assert_leq(n, node_iedge_count[e].first); + if(n == node_iedge_count[e].first) { + for(index_t a = 0; a < node_iedge_count[e].second; a++) { + tmp_gbwt_to_node.push_back(n); + r++; + } + e++; + } + } + n++; + } + assert_eq(bot - top, tmp_gbwt_to_node.size()); + for(index_t i = 0; i < tmp_zOffs.size(); i++) { + // Note: might be able to do additional trimming off the end. + // Create a new range for the portion after the dollar. + index_t new_top = tmp_zOffs[i] + 1; + if(i + 1 < tmp_zOffs.size() && new_top == tmp_zOffs[i+1]) { + continue; + } + assert_leq(new_top - top, tmp_gbwt_to_node.size()); + if(new_top - top == tmp_gbwt_to_node.size()) { + break; + } + index_t new_node_top = tmp_gbwt_to_node[new_top - top] + node_top; + assert_lt(new_node_top, node_bot); + index_t new_bot; + if(i + 1 < tmp_zOffs.size()) { + new_bot = tmp_zOffs[i+1]; + } else { + new_bot = bot; + } + index_t new_node_bot = node_bot; + if(new_bot - top < tmp_gbwt_to_node.size()) { + new_node_bot = node_top + tmp_gbwt_to_node[new_bot - top]; + if(new_bot - top > 0 && + tmp_gbwt_to_node[new_bot - top] == tmp_gbwt_to_node[new_bot - top - 1]) { + new_node_bot++; + } + } + tmp_node_iedge_count.clear(); + if(new_top >= new_bot) continue; + for(index_t j = new_top - top; j + 1 < new_bot - top;) { + index_t n = tmp_gbwt_to_node[j]; + index_t j2 = j + 1; + while(j2 < new_bot - top) { + if(n != tmp_gbwt_to_node[j2]) { + break; + } + j2++; + } + if(j + 1 < j2) { + tmp_node_iedge_count.expand(); + assert_lt(node_top, new_node_top); + tmp_node_iedge_count.back().first = n - (new_node_top - node_top); + tmp_node_iedge_count.back().second = j2 - j - 1; + } + j = j2; + } + st.expand(); + st.back().reset(); + st.back().initMap(new_node_bot - new_node_top); + for(index_t j = new_node_top; j < new_node_bot; j++) { + st.back().map_[j - new_node_top] = map(j - node_top + mapi_); + } + st.back().init( + gfm, + ref, + sa, + st, + hit, + (index_t)st.size()-1, + reportList, + res, + new_top, + new_bot, + new_node_top, + new_node_bot, + tmp_node_iedge_count, + step, + met); + } + assert_eq((index_t)map_.size(), node_bot - node_top + mapi_); + bot = tmp_zOffs[0]; + assert_lt(bot - top, tmp_gbwt_to_node.size()); + node_bot = tmp_gbwt_to_node[bot - top - 1] + node_top + 1; + map_.resize(node_bot - node_top + mapi_); + index_t width = node_bot - node_top; + for(index_t e = 0; e < node_iedge_count.size(); e++) { + if(node_iedge_count[e].first >= node_bot - node_top) { + node_iedge_count.resize(e); + break; + } + width += node_iedge_count[e].second; + } + if(width != bot - top) { + assert_eq(width, bot - top + 1); + assert_gt(node_iedge_count.size(), 0); + assert_gt(node_iedge_count.back().second, 0); + node_iedge_count.back().second -= 1; + if(node_iedge_count.back().second == 0) { + node_iedge_count.resize(node_iedge_count.size()- 1); + } + } + } + assert_gt(bot, top); + // Prepare SideLocus's for next step + if(bot-top > 1) { + SideLocus::initFromTopBot(top, bot, gfm.gh(), gfm.gfm(), tloc, bloc); + assert(tloc.valid()); assert(tloc.repOk(gfm.gh())); + assert(bloc.valid()); assert(bloc.repOk(gfm.gh())); + } else { + tloc.initFromRow(top, gfm.gh(), gfm.gfm()); + assert(tloc.valid()); assert(tloc.repOk(gfm.gh())); + bloc.invalidate(); + } + return ret; + } + +#ifndef NDEBUG + /** + * Check if this GWP is internally consistent. + */ + bool repOk( + const GFM& gfm, + GWHit& hit, + index_t range) const + { + assert(done() || bot > top); + assert(doneResolving(hit) || (tloc.valid() && tloc.repOk(gfm.gh()))); + assert(doneResolving(hit) || bot == top+1 || (bloc.valid() && bloc.repOk(gfm.gh()))); + assert_eq(map_.size()-mapi_, bot-top); + // Make sure that 'done' is compatible with whether we have >= + // 1 elements left to resolve. + int left = 0; + for(size_t i = mapi_; i < map_.size(); i++) { + ASSERT_ONLY(index_t row = (index_t)(top + i - mapi_)); + ASSERT_ONLY(index_t origRow = hit.satup->topf + map(i)); + assert(step == 0 || row != origRow); + assert_eq(row, gfm.walkLeft(origRow, step)); + assert_lt(map_[i], hit.satup->offs.size()); + if(off(i, hit) == (index_t)OFF_MASK) left++; + } + assert(repOkMapRepeats()); + assert(repOkMapInclusive(hit, range)); + return true; + } + + /** + * Return true iff this GWState is not obviously corrupt. + */ + bool repOkBasic() { + assert_geq(bot, top); + return true; + } + + /** + * Check that the fmap elements pointed to by our map_ include all + * of the fmap elements that point to this range. + */ + bool repOkMapInclusive(GWHit& hit, index_t range) const { + for(size_t i = 0; i < hit.fmap.size(); i++) { + if(hit.satup->offs[i] == (index_t)OFF_MASK) { + if(range == hit.fmap[i].first) { + ASSERT_ONLY(bool found = false); + for(size_t j = mapi_; j < map_.size(); j++) { + if(map(j) == i) { + ASSERT_ONLY(found = true); + break; + } + } + assert(found); + } + } + } + return true; + } + + /** + * Check that no two elements in map_ are the same. + */ + bool repOkMapRepeats() const { + for(size_t i = mapi_; i < map_.size(); i++) { + for(size_t j = i+1; j < map_.size(); j++) { + assert_neq(map_[i], map_[j]); + } + } + return true; + } +#endif + + /** + * Return the offset currently assigned to the ith element. If it + * has not yet been resolved, return 0xffffffff. + */ + index_t off( + index_t i, + const SARangeWithOffs& sa) + { + assert_geq(i, mapi_); + assert_lt(i, map_.size()); + assert_lt(map_[i], sa.offs.size()); + return sa.offs.get(map_[i]); + } + + /** + * Return the offset of the element within the original range's + * PListSlice that the ith element of this range corresponds to. + */ + index_t map(index_t i) const { + assert_geq(i, mapi_); + assert_lt(i, map_.size()); + return map_[i]; + } + + /** + * Return the offset of the first untrimmed offset in the map. + */ + index_t mapi() const { + return mapi_; + } + + /** + * Return number of active elements in the range being tracked by + * this GWState. + */ + index_t size() const { + return (index_t)(map_.size() - mapi_); + } + + /** + * Return true iff all elements in this leaf range have been + * resolved. + */ + bool done() const { + return size() == 0; + } + + /** + * Set the PListSlice element that corresponds to the ith element + * of 'map' to the specified offset. + */ + void setOff( + index_t i, + index_t off, + SARangeWithOffs& sa, + WalkMetrics& met) + { + assert_lt(i + mapi_, map_.size()); + assert_lt(map_[i + mapi_], sa.offs.size()); + size_t saoff = map_[i + mapi_]; + sa.offs[saoff] = off; + assert_eq(off, sa.offs[saoff]); + } + + /** + * Advance this GWState by one step (i.e. one BW operation). In + * the event of a "split", more elements are added to the EList + * 'st', which must have room for at least 3 more elements without + * needing another expansion. If an expansion of 'st' is + * triggered, this GWState object becomes invalid. + * + * Returns a pair of numbers, the first being the number of + * resolved but unreported offsets found during this advance, the + * second being the number of as-yet-unresolved offsets. + */ + template + pair advance( + const GFM& gfm, // the forward Bowtie index, for stepping left + const BitPairReference& ref, // bitpair-encoded reference + SARangeWithOffs& sa, // SA range with offsets + GWHit& hit, // the associated GWHit object + index_t range, // which range is this? + bool reportList, // if true, "report" resolved offsets immediately by adding them to 'res' list + EList, 16>* res, // EList where resolved offsets should be appended + EList& st, // EList of GWStates for range being advanced + GroupWalkState& gws, // temporary storage for masks + WalkMetrics& met, + PerReadMetrics& prm) + { + ASSERT_ONLY(index_t origTop = top); + ASSERT_ONLY(index_t origBot = bot); + assert_geq(step, 0); + assert_eq(step, lastStep_); + // assert_geq(st.capacity(), st.size() + 4); + assert(tloc.valid()); assert(tloc.repOk(gfm.gh())); + assert_eq(node_bot-node_top, (index_t)(map_.size()-mapi_)); + pair ret = make_pair(0, 0); + assert_eq(top, tloc.toBWRow(gfm.gh())); + if(bot - top > 1) { + bool first = true; + ASSERT_ONLY(index_t sum = 0); + index_t newtop = 0, newbot = 0; + index_t new_node_top = 0, new_node_bot = 0; + gws.map.clear(); + // Still multiple elements being tracked + index_t curtop = top, curbot = bot; + index_t cur_node_top = node_top, cur_node_bot = node_bot; + for(index_t e = 0; e < node_iedge_count.size() + 1; e++) { + if(e >= node_iedge_count.size()) { + if(e > 0) { + curtop = curbot + node_iedge_count[e-1].second; + curbot = bot; + if(curtop >= curbot) { + assert_eq(curtop, curbot); + break; + } + cur_node_top = cur_node_bot; + cur_node_bot = node_bot; + } + } else { + if(e > 0) { + curtop = curbot + node_iedge_count[e-1].second; + assert_lt(node_iedge_count[e-1].first, node_iedge_count[e].first); + curbot = curtop + (node_iedge_count[e].first - node_iedge_count[e-1].first); + cur_node_top = cur_node_bot; + } else { + curbot = curtop + node_iedge_count[e].first + 1; + } + cur_node_bot = node_top + node_iedge_count[e].first + 1; + } + assert_lt(curtop, curbot); + index_t upto[4], in[4]; + upto[0] = in[0] = upto[1] = in[1] = + upto[2] = in[2] = upto[3] = in[3] = 0; + // assert_eq(bot, bloc.toBWRow(gfm.gh())); + met.bwops++; + prm.nExFmops++; + // Assert that there's not a dollar sign in the middle of + // this range +#ifndef NDEBUG + for(index_t i = 0; i < gfm._zOffs.size(); i++) { + assert(curbot <= gfm._zOffs[i] || curtop > gfm._zOffs[i]); + } +#endif + SideLocus curtloc, curbloc; + SideLocus::initFromTopBot(curtop, curbot, gfm.gh(), gfm.gfm(), curtloc, curbloc); + gfm.mapLFRange(curtloc, curbloc, curbot-curtop, upto, in, gws.masks); +#ifndef NDEBUG + for(int i = 0; i < 4; i++) { + assert_eq(curbot-curtop, (index_t)(gws.masks[i].size())); + } +#endif + + for(int i = 0; i < 4; i++) { + if(in[i] > 0) { + // Non-empty range resulted + if(first) { + // For the first one, + first = false; + pair range, node_range; + backup_node_iedge_count.clear(); + SideLocus::initFromTopBot(curtop, curbot, gfm.gh(), gfm.gfm(), curtloc, curbloc); + range = gfm.mapGLF(curtloc, curbloc, i, &node_range, &backup_node_iedge_count, cur_node_bot - cur_node_top); + newtop = range.first; + newbot = range.second; + new_node_top = node_range.first; + new_node_bot = node_range.second; + // Range narrowed so we have to look at the masks + for(size_t j = 0; j < gws.masks[i].size(); j++) { + assert_lt(j+mapi_+(cur_node_top - node_top), map_.size()); + if(gws.masks[i][j]) { + gws.map.push_back(map_[j+mapi_+(cur_node_top - node_top)]); + assert(gws.map.size() <= 1 || gws.map.back() != gws.map[gws.map.size()-2]); +#if 0 + // If this element is not yet resolved, + // then check that it really is the + // expected number of steps to the left + // of the corresponding element in the + // root range + assert_lt(gws.map.back(), sa.size()); + if(sa.offs[gws.map.back()] == (index_t)OFF_MASK) { + assert_eq(newtop + gws.map.size() - 1, + gfm.walkLeft(sa.topf + gws.map.back(), step+1)); + } +#endif + } + } + assert_lt(new_node_top, new_node_bot); + if(new_node_bot - new_node_top < gws.map.size()) { + assert_eq(curbot - curtop, cur_node_bot - cur_node_top); + SideLocus tmptloc, tmpbloc; + pair tmp_node_range; + index_t j1 = 0, j2 = 0; + for(index_t c = 0; c < gws.masks[i].size(); c++) { + if(gws.masks[i][c]) { + j1 = c; + break; + } + } + for(index_t j = 0; j + 1 < gws.map.size(); j++) { + for(index_t c = j1 + 1; c < gws.masks[i].size(); c++) { + if(gws.masks[i][c]) { + j2 = c; + break; + } + } + assert_lt(j1, j2); + SideLocus::initFromTopBot(curtop + j1, curtop + j2 + 1, gfm.gh(), gfm.gfm(), tmptloc, tmpbloc); + gfm.mapGLF(tmptloc, tmpbloc, i, &tmp_node_range); + assert_gt(tmp_node_range.second - tmp_node_range.first, 0); + if(tmp_node_range.second - tmp_node_range.first == 1) { + index_t jmap = gws.map[j]; + assert_lt(jmap, sa.offs.size()); + sa.offs[jmap] = gws.map[j]; + gws.map[j] = (index_t)OFF_MASK; + } + j1 = j2; + j2 = 0; + } + for(index_t j = 0; j < gws.map.size();) { + if(gws.map[j] == (index_t)OFF_MASK) { + gws.map.erase(j); + } else j++; + } +#ifndef NDEBUG + for(index_t j = 0; j < gws.map.size(); j++) { + assert_neq(gws.map[j], (index_t)OFF_MASK); + } +#endif + } + assert_eq(new_node_bot - new_node_top, (index_t)(gws.map.size())); + } else { + // For each beyond the first, create a new + // GWState and add it to the GWState list. + // NOTE: this can cause the underlying list to + // be expanded which in turn might leave 'st' + // pointing to bad memory. + st.expand(); + st.back().reset(); + tmp_node_iedge_count.clear(); + pair range, node_range; + SideLocus::initFromTopBot(curtop, curbot, gfm.gh(), gfm.gfm(), curtloc, curbloc); + range = gfm.mapGLF(curtloc, curbloc, i, &node_range, &tmp_node_iedge_count, cur_node_bot - cur_node_top); + assert_geq(range.second - range.first, node_range.second - node_range.first); + index_t ntop = range.first; + index_t nbot = range.second; + st.back().mapi_ = 0; + st.back().map_.clear(); + met.branches++; + // Range narrowed so we have to look at the masks + for(size_t j = 0; j < gws.masks[i].size(); j++) { + if(gws.masks[i][j]) st.back().map_.push_back(map_[j+mapi_+(cur_node_top - node_top)]); + } + assert_lt(node_range.first, node_range.second); + if(node_range.second - node_range.first < st.back().map_.size()) { + assert_eq(curbot - curtop, cur_node_bot - cur_node_top); + SideLocus tmptloc, tmpbloc; + pair tmp_node_range; + index_t j1 = 0, j2 = 0; + for(index_t c = 0; c < gws.masks[i].size(); c++) { + if(gws.masks[i][c]) { + j1 = c; + break; + } + } + for(index_t j = 0; j + 1 < st.back().map_.size(); j++) { + for(index_t c = j1 + 1; c < gws.masks[i].size(); c++) { + if(gws.masks[i][c]) { + j2 = c; + break; + } + } + assert_lt(j1, j2); + SideLocus::initFromTopBot(curtop + j1, curtop + j2 + 1, gfm.gh(), gfm.gfm(), tmptloc, tmpbloc); + gfm.mapGLF(tmptloc, tmpbloc, i, &tmp_node_range); + assert_gt(tmp_node_range.second - tmp_node_range.first, 0); + if(tmp_node_range.second - tmp_node_range.first == 1) { + index_t jmap = st.back().map_[j]; + assert_lt(jmap, sa.offs.size()); + sa.offs[jmap] = st.back().map_[j]; + st.back().map_[j] = (index_t)OFF_MASK; + } + j1 = j2; + j2 = 0; + } + for(index_t j = 0; j < st.back().map_.size();) { + if(st.back().map_[j] == (index_t)OFF_MASK) { + st.back().map_.erase(j); + } else j++; + } +#ifndef NDEBUG + for(index_t j = 0; j < st.back().map_.size(); j++) { + assert_neq(st.back().map_[j], (index_t)OFF_MASK); + } +#endif + } + assert_eq(node_range.second - node_range.first, st.back().map_.size()); + pair rret = + st.back().init( + gfm, // forward Bowtie index + ref, // bitpair-encodede reference + sa, // SA range with offsets + st, // EList of all GWStates associated with original range + hit, // associated GWHit object + (index_t)st.size()-1, // range offset + reportList, // if true, report hits to 'res' list + res, // report hits here if reportList is true + ntop, // BW top of new range + nbot, // BW bot of new range + node_range.first, + node_range.second, + tmp_node_iedge_count, + step+1, // # steps taken to get to this new range + met); // update these metrics + ret.first += rret.first; + ret.second += rret.second; + } + ASSERT_ONLY(sum += in[i]); + } + } + } + mapi_ = 0; + // assert_eq(new_node_bot-new_node_top, sum); + assert_gt(newbot, newtop); + assert(top != newtop || bot != newbot); + //assert(!(newtop < top && newbot > top)); + top = newtop; + bot = newbot; + node_top = new_node_top; + node_bot = new_node_bot; + node_iedge_count = backup_node_iedge_count; + backup_node_iedge_count.clear(); + if(!gws.map.empty()) { + map_ = gws.map; + } + //assert(repOkMapRepeats()); + //assert(repOkMapInclusive(hit, range)); + assert_eq(node_bot-node_top, (index_t)map_.size()); + } else { + // Down to one element + assert_eq(bot, top+1); + assert_eq(1, map_.size()-mapi_); + // Sets top, returns char walked through (which we ignore) + ASSERT_ONLY(index_t oldtop = top); + met.bwops++; + prm.nExFmops++; + pair node_range(0, 0); + pair range = gfm.mapGLF1(top, tloc, &node_range); + top = range.first; + assert_neq(top, oldtop); + bot = top+1; + node_top = node_range.first; + node_bot = node_range.second; + if(mapi_ > 0) { + map_[0] = map_[mapi_]; + mapi_ = 0; + } + map_.resize(1); + } + assert(top != origTop || bot != origBot); + step++; + assert_gt(step, 0); + assert_leq((index_t)step, gfm.gh().len()); + pair rret = + init( + gfm, // forward GFM index + ref, // bitpair-encodede reference + sa, // SA range with offsets + st, // EList of all GWStates associated with original range + hit, // associated GWHit object + range, // range offset + reportList, // if true, report hits to 'res' list + res, // report hits here if reportList is true + met); // update these metrics + ret.first += rret.first; + ret.second += rret.second; + return ret; + } + + /** + * Clear all state in preparation for the next walk. + */ + void reset() { + top = bot = node_top = node_bot = step = mapi_ = 0; + ASSERT_ONLY(lastStep_ = -1); + ASSERT_ONLY(inited_ = false); + tloc.invalidate(); + bloc.invalidate(); + map_.clear(); + node_iedge_count.clear(); + backup_node_iedge_count.clear(); + tmp_node_iedge_count.clear(); + } + + /** + * Resize the map_ field to the given size. + */ + void initMap(size_t newsz) { + mapi_ = 0; + map_.resize(newsz); + for(size_t i = 0; i < newsz; i++) { + map_[i] = (index_t)i; + } + } + + /** + * Return true iff all rows corresponding to this GWState have been + * resolved and reported. + */ + bool doneReporting(const GWHit& hit) const { + for(size_t i = mapi_; i < map_.size(); i++) { + if(!hit.reported(map(i))) return false; + } + return true; + } + + /** + * Return true iff all rows corresponding to this GWState have been + * resolved (but not necessarily reported). + */ + bool doneResolving(const SARangeWithOffs& sa) const { + for(size_t i = mapi_; i < map_.size(); i++) { + if(sa.offs[map((index_t)i)] == (index_t)OFF_MASK) return false; + } + return true; + } + + SideLocus tloc; // SideLocus for top + SideLocus bloc; // SideLocus for bottom + index_t top; // top elt of range in GBWT + index_t bot; // bot elt of range in GBWT + index_t node_top; + index_t node_bot; + EList > node_iedge_count; + int step; // how many steps have we walked to the left so far + + // temporary + EList > backup_node_iedge_count; + EList > tmp_node_iedge_count; + + EList tmp_zOffs; + EList tmp_gbwt_to_node; + +protected: + + ASSERT_ONLY(bool inited_); + ASSERT_ONLY(int lastStep_); + EList map_; // which elts in range 'range' we're tracking + index_t mapi_; // first untrimmed element of map +}; + +template +class GroupWalk2S { +public: + typedef EList, S> TStateV; + + GroupWalk2S() : st_(8, GW_CAT) { + reset(); + } + + /** + * Reset the GroupWalk in preparation for the next SeedResults. + */ + void reset() { + elt_ = rep_ = 0; + ASSERT_ONLY(inited_ = false); + } + + /** + * Initialize a new group walk w/r/t a QVal object. + */ + void init( + const GFM& gfmFw, // forward Bowtie index for walking left + const BitPairReference& ref, // bitpair-encoded reference + SARangeWithOffs& sa, // SA range with offsets + RandomSource& rnd, // pseudo-random generator for sampling rows + WalkMetrics& met) // update metrics here + { + reset(); +#ifndef NDEBUG + inited_ = true; +#endif + // Init GWHit + hit_.init(sa, 0, false, 0); + // Init corresponding GWState + st_.resize(1); + st_.back().reset(); + assert(st_.back().repOkBasic()); + index_t top = sa.topf; + index_t bot = sa.botf; + index_t node_top = sa.node_top; + index_t node_bot = (index_t)(node_top + sa.size()); + st_.back().initMap(sa.size()); + st_.ensure(4); + st_.back().init( + gfmFw, // Bowtie index + ref, // bitpair-encoded reference + sa, // SA range with offsets + st_, // EList + hit_, // GWHit + 0, // range 0 + false, // put resolved elements into res_? + NULL, // put resolved elements here + top, // GBW row at top + bot, // GBW row at bot + node_top, // node at top + node_bot, // node at bot + sa.node_iedge_count, + 0, // # steps taken + met); // update metrics here + elt_ += sa.size(); + assert(hit_.repOk(sa)); + } + + // + // ELEMENT-BASED + // + + /** + * Advance the GroupWalk until all elements have been resolved. + */ + void resolveAll(WalkMetrics& met, PerReadMetrics& prm) { + WalkResult res; // ignore results for now + for(size_t i = 0; i < elt_; i++) { + advanceElement((index_t)i, res, met, prm); + } + } + + /** + * Advance the GroupWalk until the specified element has been + * resolved. + */ + bool advanceElement( + index_t elt, // element within the range + const GFM& gfmFw, // forward Bowtie index for walking left + const BitPairReference& ref, // bitpair-encoded reference + SARangeWithOffs& sa, // SA range with offsets + GroupWalkState& gws, // GroupWalk state; scratch space + WalkResult& res, // put the result here + WalkMetrics& met, // metrics + PerReadMetrics& prm) // per-read metrics + { + assert(inited_); + assert(!done()); + assert(hit_.repOk(sa)); + assert_lt(elt, sa.size()); // elt must fall within range + // Until we've resolved our element of interest... + while(sa.offs[elt] == (index_t)OFF_MASK) { + // Get the GWState that contains our element of interest + size_t range = hit_.fmap[elt].first; + assert_lt(range, st_.size()); + st_.ensure(st_[range].node_bot - st_[range].node_top); + // st_.ensure(4); + GWState& st = st_[range]; + assert(!st.doneResolving(sa)); + // Returns a pair of numbers, the first being the number of + // resolved but unreported offsets found during this advance, the + // second being the number of as-yet-unresolved offsets. + st.advance( + gfmFw, + ref, + sa, + hit_, + (index_t)range, + false, + NULL, + st_, + gws, + met, + prm); + assert(sa.offs[elt] != (index_t)OFF_MASK || + !st_[hit_.fmap[elt].first].doneResolving(sa)); + } + assert_neq((index_t)OFF_MASK, sa.offs[elt]); + // Report it! + if(!hit_.reported(elt)) { + hit_.setReported(elt); + } + met.reports++; + res.init( + 0, // seed offset + false, // orientation + 0, // range + elt, // element + sa.topf + elt, // bw row + (index_t)sa.len, // length of hit + sa.offs[elt]); // resolved text offset + rep_++; + return true; + } + + /** + * Return true iff all elements have been resolved and reported. + */ + bool done() const { return rep_ == elt_; } + +#ifndef NDEBUG + /** + * Check that GroupWalk is internally consistent. + */ + bool repOk(const SARangeWithOffs& sa) const { + assert(hit_.repOk(sa)); + assert_leq(rep_, elt_); + // This is a lot of work + size_t resolved = 0, reported = 0; + // For each element + const size_t sz = sa.size(); + for(size_t m = 0; m < sz; m++) { + // Is it resolved? + if(sa.offs[m] != (index_t)OFF_MASK) { + resolved++; + } else { + assert(!hit_.reported(m)); + } + // Is it reported? + if(hit_.reported(m)) { + reported++; + } + assert_geq(resolved, reported); + } + assert_geq(resolved, reported); + assert_eq(rep_, reported); + assert_eq(elt_, sz); + return true; + } +#endif + + /** + * Return the number of BW elements that we can resolve. + */ + index_t numElts() const { return elt_; } + + /** + * Return the size occupied by this GroupWalk and all its constituent + * objects. + */ + size_t totalSizeBytes() const { + return 2 * sizeof(size_t) + st_.totalSizeBytes() + sizeof(GWHit); + } + /** + * Return the capacity of this GroupWalk and all its constituent objects. + */ + size_t totalCapacityBytes() const { + return 2 * sizeof(size_t) + st_.totalCapacityBytes() + sizeof(GWHit); + } + +#ifndef NDEBUG + bool initialized() const { return inited_; } +#endif + +protected: + + ASSERT_ONLY(bool inited_); // initialized? + + index_t elt_; // # BW elements under the control of the GropuWalk + index_t rep_; // # BW elements reported + + // For each orientation and seed offset, keep a GWState object that + // holds the state of the walk so far. + TStateV st_; + + // For each orientation and seed offset, keep an EList of GWHit. + GWHit hit_; +}; + +#endif /*GROUP_WALK_H_*/ diff --git a/hgfm.h b/hgfm.h new file mode 100644 index 0000000..89cb7aa --- /dev/null +++ b/hgfm.h @@ -0,0 +1,2655 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef HGFM_H_ +#define HGFM_H_ + +#include "hier_idx_common.h" +#include "gfm.h" + +/** + * Extended Burrows-Wheeler transform data. + * LocalEbwt is a specialized Ebwt index that represents ~64K bps + * and therefore uses two bytes as offsets within 64K bps. + * This class has only two additional member variables to denote the genomic sequenuce it represents: + * (1) the contig index and (2) the offset within the contig. + * + */ +template +class LocalGFM : public GFM { + typedef GFM PARENT_CLASS; +public: + /// Construct an Ebwt from the given input file + LocalGFM(const string& in, + ALTDB* altdb, + FILE *in5, + FILE *in6, + char *mmFile5, + char *mmFile6, + full_index_t& tidx, + full_index_t& localOffset, + full_index_t& joinedOffset, + bool switchEndian, + size_t& bytesRead, + size_t& bytesRead2, + int needEntireReverse, + bool fw, + int32_t overrideOffRate, // = -1, + int32_t offRatePlus, // = -1, + uint32_t lineRate, + uint32_t offRate, + uint32_t ftabChars, + bool useMm, // = false, + bool useShmem, // = false, + bool mmSweep, // = false, + bool loadNames, // = false, + bool loadSASamp, // = true, + bool loadFtab, // = true, + bool loadRstarts, // = true, + bool verbose, // = false, + bool startVerbose, // = false, + bool passMemExc, // = false, + bool sanityCheck, // = false) + bool useHaplotype) : // = false + GFM(in, + altdb, + NULL, + NULL, + needEntireReverse, + fw, + overrideOffRate, + offRatePlus, + useMm, + useShmem, + mmSweep, + loadNames, + loadSASamp, + loadFtab, + loadRstarts, + true, // load Splice Sites + verbose, + startVerbose, + passMemExc, + sanityCheck, + useHaplotype, + true) + { + this->_in1Str = in + ".5." + gfm_ext; + this->_in2Str = in + ".5." + gfm_ext; + readIntoMemory( + in5, + in6, + mmFile5, + mmFile6, + tidx, + localOffset, + joinedOffset, + switchEndian, + bytesRead, + bytesRead2, + needEntireReverse, + loadSASamp, + loadFtab, + loadRstarts, + false, //justHeader + lineRate, + offRate, + ftabChars, + mmSweep, + loadNames, + startVerbose); + + _tidx = tidx; + _localOffset = localOffset; + _joinedOffset = joinedOffset; + + // If the offRate has been overridden, reflect that in the + // _eh._offRate field + if(offRatePlus > 0 && this->_overrideOffRate == -1) { + this->_overrideOffRate = this->_gh._offRate + offRatePlus; + } + if(this->_overrideOffRate > this->_gh._offRate) { + this->_gh.setOffRate(this->_overrideOffRate); + assert_eq(this->_overrideOffRate, this->_gh._offRate); + } + assert(this->repOk()); + } + + + /// Construct an Ebwt from the given header parameters and string + /// vector, optionally using a blockwise suffix sorter with the + /// given 'bmax' and 'dcv' parameters. The string vector is + /// ultimately joined and the joined string is passed to buildToDisk(). + template + LocalGFM( + TStr& s, + const EList& sa, + PathGraph* pg, + full_index_t tidx, + full_index_t localOffset, + full_index_t joinedOffset, + EList >& alts, + index_t local_size, + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + const string& file, // base filename for EBWT files + bool fw, + int dcv, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + uint32_t seed, + ostream& out5, + ostream& out6, + int32_t overrideOffRate = -1, + bool verbose = false, + bool passMemExc = false, + bool sanityCheck = false) : + GFM(packed, + needEntireReverse, + lineRate, + offRate, + ftabChars, + file, + fw, + dcv, + szs, + sztot, + refparams, + seed, + overrideOffRate, + verbose, + passMemExc, + sanityCheck) + { + const GFMParams& gh = this->_gh; + assert(gh.repOk()); + uint32_t be = this->toBe(); + assert(out5.good()); + assert(out6.good()); + _tidx = tidx; + _localOffset = localOffset; + _joinedOffset = joinedOffset; + writeIndex(out5, tidx, be); + writeIndex(out5, localOffset, be); + writeIndex(out5, joinedOffset, be); + writeIndex(out5, gh._len, be); // length of string (and bwt and suffix array) + streampos headerPos = out5.tellp(); + writeIndex(out5, 0, be); // gbwtLen + writeIndex(out5, 0, be); // num of nodes + writeIndex(out5, 0, be); // eftabLen + if(gh._len > 0) { + assert_gt(szs.size(), 0); + assert_gt(sztot, 0); + // Not every fragment represents a distinct sequence - many + // fragments may correspond to a single sequence. Count the + // number of sequences here by counting the number of "first" + // fragments. + this->_nPat = 0; + this->_nFrag = 0; + for(size_t i = 0; i < szs.size(); i++) { + if(szs[i].len > 0) this->_nFrag++; + if(szs[i].first && szs[i].len > 0) this->_nPat++; + } + assert_eq(this->_nPat, 1); + assert_geq(this->_nFrag, this->_nPat); + this->_rstarts.reset(); + writeIndex(out5, this->_nPat, be); + assert_eq(this->_nPat, 1); + this->_plen.init(new index_t[this->_nPat], this->_nPat); + // For each pattern, set plen + int npat = -1; + for(size_t i = 0; i < szs.size(); i++) { + if(szs[i].first && szs[i].len > 0) { + if(npat >= 0) { + writeIndex(out5, this->plen()[npat], be); + } + npat++; + this->plen()[npat] = (szs[i].len + szs[i].off); + } else { + this->plen()[npat] += (szs[i].len + szs[i].off); + } + } + assert_eq((index_t)npat, this->_nPat-1); + writeIndex(out5, this->plen()[npat], be); + // Write the number of fragments + writeIndex(out5, this->_nFrag, be); + + if(refparams.reverse == REF_READ_REVERSE) { + EList tmp(EBWT_CAT); + reverseRefRecords(szs, tmp, false, verbose); + this->szsToDisk(tmp, out5, refparams.reverse); + } else { + this->szsToDisk(szs, out5, refparams.reverse); + } + + if(alts.empty()) { + assert(pg == NULL); + buildToDisk(sa, s, out5, out6, headerPos); + } else { + assert(pg != NULL); + // Re-initialize GFM parameters to reflect real number of edges (gbwt string) + this->_gh.init( + this->_gh.len(), + pg->getNumEdges(), + pg->getNumNodes(), + this->_gh.lineRate(), + this->_gh.offRate(), + this->_gh.ftabChars(), + 0, + this->_gh.entireReverse()); + buildToDisk(*pg, s, out5, out6, headerPos); + } + } + + out5.flush(); out6.flush(); + if(out5.fail() || out6.fail()) { + cerr << "An error occurred writing the index to disk. Please check if the disk is full." << endl; + throw 1; + } + } + + template void buildToDisk( + PathGraph& gbwt, + const TStr& s, + ostream& out1, + ostream& out2, + streampos headerPos); + + template void buildToDisk( + const EList& sa, + const TStr& s, + ostream& out1, + ostream& out2, + streampos headerPos); + + // I/O + void readIntoMemory( + FILE *in5, + FILE *in6, + char *mmFile5, + char *mmFile6, + full_index_t& tidx, + full_index_t& localOffset, + full_index_t& joinedOffset, + bool switchEndian, + size_t& bytesRead, + size_t& bytesRead2, + int needEntireRev, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool justHeader, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + bool mmSweep, + bool loadNames, + bool startVerbose); + + /** + * Sanity-check various pieces of the Ebwt + */ + void sanityCheckAll(int reverse) const { + if(this->_gh._len > 0) { + PARENT_CLASS::sanityCheckAll(reverse); + } + } + + bool empty() const { return this->_gh._len == 0; } + +public: + full_index_t _tidx; + full_index_t _localOffset; + full_index_t _joinedOffset; +}; + +/** + * Build an Ebwt from a string 's' and its suffix array 'sa' (which + * might actually be a suffix array *builder* that builds blocks of the + * array on demand). The bulk of the Ebwt, i.e. the ebwt and offs + * arrays, is written directly to disk. This is by design: keeping + * those arrays in memory needlessly increases the footprint of the + * building process. Instead, we prefer to build the Ebwt directly + * "to disk" and then read it back into memory later as necessary. + * + * It is assumed that the header values and join-related values (nPat, + * plen) have already been written to 'out1' before this function + * is called. When this function is finished, it will have + * additionally written ebwt, zOff, fchr, ftab and eftab to the primary + * file and offs to the secondary file. + * + * Assume DNA/RNA/any alphabet with 4 or fewer elements. + * Assume occ array entries are 32 bits each. + * + * @param sa the suffix array to convert to a Ebwt + * @param s the original string + * @param out + */ +template +template +void LocalGFM::buildToDisk( + PathGraph& gbwt, + const TStr& s, + ostream& out5, + ostream& out6, + streampos headerPos) +{ + assert_leq(s.length(), std::numeric_limits::max()); + const GFMParams& gh = this->_gh; + + assert(gh.repOk()); + assert_lt(s.length(), gh.gbwtLen()); + assert_eq(s.length(), gh._len); + assert_gt(gh._lineRate, 3); + + index_t gbwtLen = gh._gbwtLen; + streampos out5pos = out5.tellp(); + out5.seekp(headerPos); + writeIndex(out5, gbwtLen, this->toBe()); + writeIndex(out5, gh._numNodes, this->toBe()); + headerPos = out5.tellp(); + out5.seekp(out5pos); + index_t ftabLen = gh._ftabLen; + index_t sideSz = gh._sideSz; + index_t gbwtTotSz = gh._gbwtTotSz; + index_t fchr[] = {0, 0, 0, 0, 0}; + EList ftab(EBWT_CAT); + EList zOffs; + + // Save # of occurrences of each character as we walk along the bwt + index_t occ[4] = {0, 0, 0, 0}; + index_t occSave[4] = {0, 0, 0, 0}; + // # of occurrences of 1 in M arrays + index_t M_occ = 0, M_occSave = 0; + // Location in F that corresponds to 1 in M + index_t F_loc = 0, F_locSave = 0; + + try { + VMSG_NL("Allocating ftab, absorbFtab"); + ftab.resize(ftabLen); + ftab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating ftab[] or absorbFtab[] " + << "in LocalGFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Allocate the side buffer; holds a single side as its being + // constructed and then written to disk. Reused across all sides. +#ifdef SIXTY4_FORMAT + EList gfmSide(EBWT_CAT); +#else + EList gfmSide(EBWT_CAT); +#endif + try { + // Used to calculate ftab and eftab, but having gfm costs a lot of memory + this->_gfm.init(new uint8_t[gh._gbwtTotLen], gh._gbwtTotLen, true); +#ifdef SIXTY4_FORMAT + gfmSide.resize(sideSz >> 3); +#else + gfmSide.resize(sideSz); +#endif + } catch(bad_alloc &e) { + cerr << "Out of memory allocating ebwtSide[] in " + << "LocalGFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Points to the base offset within ebwt for the side currently + // being written + index_t side = 0; + + // Whether we're assembling a forward or a reverse bucket + bool fw = true; + int sideCur = 0; + + index_t si = 0; // string offset (chars) + ASSERT_ONLY(bool inSA = true); // true iff saI still points inside suffix + // array (as opposed to the padding at the + // end) + // Iterate over packed bwt bytes + VMSG_NL("Entering LocalGFM loop"); + ASSERT_ONLY(uint32_t beforeGbwtOff = (uint32_t)out5.tellp()); + while(side < gbwtTotSz) { + // Sanity-check our cursor into the side buffer + assert_geq(sideCur, 0); + assert_lt(sideCur, (int)gh._sideGbwtSz); + assert_eq(0, side % sideSz); // 'side' must be on side boundary + gfmSide[sideCur] = 0; // clear + if(sideCur == 0) { + memset(gfmSide.ptr(), 0, gh._sideGbwtSz); + gfmSide[sideCur] = 0; // clear + } + assert_lt(side + sideCur, gbwtTotSz); + // Iterate over bit-pairs in the si'th character of the BWT +#ifdef SIXTY4_FORMAT + for(int bpi = 0; bpi < 32; bpi++, si++) { +#else + for(int bpi = 0; bpi < 4; bpi++, si++) { +#endif + int gbwtChar = 0; + int F = 0, M = 0; + full_index_t pos = 0; + bool count = true; + if(si < gbwtLen) { + gbwt.nextRow(gbwtChar, F, M, pos); + + // (that might have triggered sa to calc next suf block) + if(gbwtChar == 'Z') { + // Don't add the '$' in the last column to the BWT + // transform; we can't encode a $ (only A C T or G) + // and counting it as, say, an A, will mess up the + // LR mapping + gbwtChar = 0; count = false; +#ifndef NDEBUG + if(zOffs.size() > 0) { + assert_gt(si, zOffs.back()); + } +#endif + zOffs.push_back(si); // remember GBWT row that corresponds to the 0th suffix + } else { + gbwtChar = asc2dna[gbwtChar]; + assert_lt(gbwtChar, 4); + // Update the fchr + fchr[gbwtChar]++; + } + assert_lt(F, 2); + assert_lt(M, 2); + if(M == 1) { + assert_neq(F_loc, numeric_limits::max()); + F_loc = gbwt.nextFLocation(); +#ifndef NDEBUG + if(F_loc > 0) { + assert_gt(F_loc, F_locSave); + } +#endif + } + // Suffix array offset boundary? - update offset array + if(M == 1 && (M_occ & gh._offMask) == M_occ) { + assert_lt((M_occ >> gh._offRate), gh._offsLen); + // Write offsets directly to the secondary output + // stream, thereby avoiding keeping them in memory + writeIndex(out6, pos, this->toBe()); + } + } else { + // Strayed off the end of the SA, now we're just + // padding out a bucket +#ifndef NDEBUG + if(inSA) { + // Assert that we wrote all the characters in the + // string before now + assert_eq(si, gbwtLen); + inSA = false; + } +#endif + // 'A' used for padding; important that padding be + // counted in the occ[] array + gbwtChar = 0; + F = M = 0; + } + if(count) occ[gbwtChar]++; + if(M) M_occ++; + // Append BWT char to bwt section of current side + if(fw) { + // Forward bucket: fill from least to most +#ifdef SIXTY4_FORMAT + gfmSide[sideCur] |= ((uint64_t)gbwtChar << (bpi << 1)); + if(gbwtChar > 0) assert_gt(gfmSide[sideCur], 0); + assert(false); + cerr << "Not implemented" << endl; + exit(1); +#else + pack_2b_in_8b(gbwtChar, gfmSide[sideCur], bpi); + assert_eq((gfmSide[sideCur] >> (bpi*2)) & 3, gbwtChar); + + int F_sideCur = (gh._sideGbwtSz + sideCur) >> 1; + int F_bpi = bpi + ((sideCur & 0x1) << 2); // Can be used as M_bpi as well + pack_1b_in_8b(F, gfmSide[F_sideCur], F_bpi); + assert_eq((gfmSide[F_sideCur] >> F_bpi) & 1, F); + + int M_sideCur = F_sideCur + (gh._sideGbwtSz >> 2); + pack_1b_in_8b(M, gfmSide[M_sideCur], F_bpi); + assert_eq((gfmSide[M_sideCur] >> F_bpi) & 1, M); +#endif + } else { + // Backward bucket: fill from most to least +#ifdef SIXTY4_FORMAT + gfmSide[sideCur] |= ((uint64_t)gbwtChar << ((31 - bpi) << 1)); + if(gbwtChar > 0) assert_gt(gfmSide[sideCur], 0); + // To be implemented ... + assert(false); + cerr << "Not implemented" << endl; + exit(1); +#else + pack_2b_in_8b(gbwtChar, gfmSide[sideCur], 3-bpi); + assert_eq((gfmSide[sideCur] >> ((3-bpi)*2)) & 3, gbwtChar); + // To be implemented ... + assert(false); + cerr << "Not implemented" << endl; + exit(1); +#endif + } + } // end loop over bit-pairs + assert_eq(0, (occ[0] + occ[1] + occ[2] + occ[3] + zOffs.size()) & 3); +#ifdef SIXTY4_FORMAT + assert_eq(0, si & 31); +#else + assert_eq(0, si & 3); +#endif + + sideCur++; + if((sideCur << 1) == (int)gh._sideGbwtSz) { + sideCur = 0; + index_t *uside = reinterpret_cast(gfmSide.ptr()); + // Write 'A', 'C', 'G' and 'T' tallies + side += sideSz; + assert_leq(side, gh._gbwtTotSz); + uside[(sideSz / sizeof(index_t))-6] = endianizeIndex(F_locSave, this->toBe()); + uside[(sideSz / sizeof(index_t))-5] = endianizeIndex(M_occSave, this->toBe()); + uside[(sideSz / sizeof(index_t))-4] = endianizeIndex(occSave[0], this->toBe()); + uside[(sideSz / sizeof(index_t))-3] = endianizeIndex(occSave[1], this->toBe()); + uside[(sideSz / sizeof(index_t))-2] = endianizeIndex(occSave[2], this->toBe()); + uside[(sideSz / sizeof(index_t))-1] = endianizeIndex(occSave[3], this->toBe()); + F_locSave = F_loc; + M_occSave = M_occ; + occSave[0] = occ[0]; + occSave[1] = occ[1]; + occSave[2] = occ[2]; + occSave[3] = occ[3]; + // Write backward side to primary file + out5.write((const char *)gfmSide.ptr(), sideSz); + + // + memcpy(((char*)this->_gfm.get()) + side - sideSz, (const char *)gfmSide.ptr(), sideSz); + } + } + VMSG_NL("Exited LocalGFM loop"); + // Assert that our loop counter got incremented right to the end + assert_eq(side, gh._gbwtTotSz); + // Assert that we wrote the expected amount to out5 + assert_eq(((uint32_t)out5.tellp() - beforeGbwtOff), gh._gbwtTotSz); + // assert that the last thing we did was write a forward bucket + + // + // Write zOffs to primary stream + // + assert_gt(zOffs.size(), 0); + writeIndex(out5, zOffs.size(), this->toBe()); + for(size_t i = 0; i < zOffs.size(); i++) { + writeIndex(out5, zOffs[i], this->toBe()); + } + + // + // Finish building fchr + // + // Exclusive prefix sum on fchr + for(int i = 1; i < 4; i++) { + fchr[i] += fchr[i-1]; + } + assert_lt(fchr[3], gbwtLen); + // Shift everybody up by one + for(int i = 4; i >= 1; i--) { + fchr[i] = fchr[i-1]; + } + fchr[0] = 0; + // Write fchr to primary file + for(int i = 0; i < 5; i++) { + writeIndex(out5, fchr[i], this->toBe()); + } + this->_fchr.init(new index_t[5], 5, true); + memcpy(this->_fchr.get(), fchr, sizeof(index_t) * 5); + + // Initialize _zGbwtByteOffs and _zGbwtBpOffs + this->_zOffs = zOffs; + this->postReadInit(gh); + + // Build ftab and eftab + EList > tFtab; + tFtab.resizeExact(ftabLen - 1); + for(index_t i = 0; i + 1 < ftabLen; i++) { + index_t q = i; + pair range(0, gh._gbwtLen); + SideLocus tloc, bloc; + SideLocus::initFromTopBot(range.first, range.second, gh, this->gfm(), tloc, bloc); + index_t j = 0; + for(; j < gh._ftabChars; j++) { + int nt = q & 0x3; q >>= 2; + if(bloc.valid()) { + range = this->mapGLF(tloc, bloc, nt); + } else { + range = this->mapGLF1(range.first, tloc, nt); + } + if(range.first == (index_t)INDEX_MAX || range.first >= range.second) { + break; + } + if(range.first + 1 == range.second) { + tloc.initFromRow(range.first, gh, this->gfm()); + bloc.invalidate(); + } else { + SideLocus::initFromTopBot(range.first, range.second, gh, this->gfm(), tloc, bloc); + } + } + + if(range.first >= range.second || j < gh._ftabChars) { + if(i == 0) { + tFtab[i].first = tFtab[i].second = 0; + } else { + tFtab[i].first = tFtab[i].second = tFtab[i-1].second; + } + } else { + tFtab[i].first = range.first; + tFtab[i].second = range.second; + } + +#ifndef NDEBUG + if(gbwt.ftab.size() > i) { + assert_eq(tFtab[i].first, gbwt.ftab[i].first); + assert_eq(tFtab[i].second, gbwt.ftab[i].second); + } +#endif + } + + // Clear memory + this->_gfm.reset(); + this->_fchr.reset(); + this->_zOffs.clear(); + this->_zGbwtByteOffs.clear(); + this->_zGbwtBpOffs.clear(); + + // + // Finish building ftab and build eftab + // + // Prefix sum on ftable + index_t eftabLen = 0; + for(index_t i = 1; i + 1 < ftabLen; i++) { + if(tFtab[i-1].second != tFtab[i].first) { + eftabLen += 2; + } + } + if(gh._gbwtLen + (eftabLen >> 1) < gh._gbwtLen) { + cerr << "Too many eftab entries: " + << gh._gbwtLen << " + " << (eftabLen >> 1) + << " > " << (index_t)INDEX_MAX << endl; + throw 1; + } + EList eftab(EBWT_CAT); + try { + eftab.resize(eftabLen); + eftab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating eftab[] " + << "in LocalGFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + index_t eftabCur = 0; + ftab[0] = tFtab[0].first; + ftab[1] = tFtab[0].second; + for(index_t i = 1; i + 1 < ftabLen; i++) { + if(ftab[i] != tFtab[i].first) { + index_t lo = ftab[i]; + index_t hi = tFtab[i].first; + assert_lt(eftabCur*2+1, eftabLen); + eftab[eftabCur*2] = lo; + eftab[eftabCur*2+1] = hi; + assert_leq(lo, hi + 4); + ftab[i] = (eftabCur++) ^ (index_t)INDEX_MAX; // insert pointer into eftab + assert_eq(lo, GFM::ftabLo(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i)); + assert_eq(hi, GFM::ftabHi(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i)); + } + ftab[i+1] = tFtab[i].second; + } +#ifndef NDEBUG + for(index_t i = 0; i + 1 < ftabLen; i++ ){ + assert_eq(tFtab[i].first, GFM::ftabHi(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i)); + assert_eq(tFtab[i].second, GFM::ftabLo(ftab.ptr(), eftab.ptr(), gbwtLen, ftabLen, eftabLen, i+1)); + } +#endif + // Write ftab to primary file + for(index_t i = 0; i < ftabLen; i++) { + writeIndex(out5, ftab[i], this->toBe()); + } + // Write eftab to primary file + out5pos = out5.tellp(); + out5.seekp(headerPos); + writeIndex(out5, eftabLen, this->toBe()); + out5.seekp(out5pos); + for(index_t i = 0; i < eftabLen; i++) { + writeIndex(out5, eftab[i], this->toBe()); + } + // Note: if you'd like to sanity-check the Ebwt, you'll have to + // read it back into memory first! + assert(!this->isInMemory()); + VMSG_NL("Exiting LocalGFM::buildToDisk()"); +} + +/** + * Build an Ebwt from a string 's' and its suffix array 'sa' (which + * might actually be a suffix array *builder* that builds blocks of the + * array on demand). The bulk of the Ebwt, i.e. the ebwt and offs + * arrays, is written directly to disk. This is by design: keeping + * those arrays in memory needlessly increases the footprint of the + * building process. Instead, we prefer to build the Ebwt directly + * "to disk" and then read it back into memory later as necessary. + * + * It is assumed that the header values and join-related values (nPat, + * plen) have already been written to 'out1' before this function + * is called. When this function is finished, it will have + * additionally written ebwt, zOff, fchr, ftab and eftab to the primary + * file and offs to the secondary file. + * + * Assume DNA/RNA/any alphabet with 4 or fewer elements. + * Assume occ array entries are 32 bits each. + * + * @param sa the suffix array to convert to a Ebwt + * @param s the original string + * @param out + */ +template +template +void LocalGFM::buildToDisk( + const EList& sa, + const TStr& s, + ostream& out5, + ostream& out6, + streampos headerPos) +{ + assert_leq(s.length(), std::numeric_limits::max()); + const GFMParams& gh = this->_gh; + assert(gh.repOk()); + assert(gh.linearFM()); + assert_lt(s.length(), gh.gbwtLen()); + assert_eq(s.length(), gh._len); + assert_gt(gh._lineRate, 3); + + index_t len = gh._len; + index_t gbwtLen = gh._gbwtLen; + assert_eq(len + 1, gbwtLen); + streampos out5pos = out5.tellp(); + out5.seekp(headerPos); + writeIndex(out5, gbwtLen, this->toBe()); + writeIndex(out5, gh._numNodes, this->toBe()); + headerPos = out5.tellp(); + out5.seekp(out5pos); + + index_t ftabLen = gh._ftabLen; + index_t sideSz = gh._sideSz; + index_t gbwtTotSz = gh._gbwtTotSz; + index_t fchr[] = {0, 0, 0, 0, 0}; + EList ftab(EBWT_CAT); + EList zOffs; + + // Save # of occurrences of each character as we walk along the bwt + index_t occ[4] = {0, 0, 0, 0}; + index_t occSave[4] = {0, 0, 0, 0}; + + // Record rows that should "absorb" adjacent rows in the ftab. + // The absorbed rows represent suffixes shorter than the ftabChars + // cutoff. + uint8_t absorbCnt = 0; + EList absorbFtab(EBWT_CAT); + try { + VMSG_NL("Allocating ftab, absorbFtab"); + ftab.resize(ftabLen); + ftab.fillZero(); + absorbFtab.resize(ftabLen); + absorbFtab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating ftab[] or absorbFtab[] " + << "in LocalGFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Allocate the side buffer; holds a single side as its being + // constructed and then written to disk. Reused across all sides. +#ifdef SIXTY4_FORMAT + EList gfmSide(EBWT_CAT); +#else + EList gfmSide(EBWT_CAT); +#endif + try { +#ifdef SIXTY4_FORMAT + gfmSide.resize(sideSz >> 3); +#else + gfmSide.resize(sideSz); +#endif + } catch(bad_alloc &e) { + cerr << "Out of memory allocating gfmSide[] in " + << "LocalGFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + + // Points to the base offset within ebwt for the side currently + // being written + index_t side = 0; + + // Whether we're assembling a forward or a reverse bucket + bool fw = true; + int sideCur = 0; + + // Have we skipped the '$' in the last column yet? + ASSERT_ONLY(bool dollarSkipped = false); + + index_t si = 0; // string offset (chars) + ASSERT_ONLY(uint32_t lastSufInt = 0); + ASSERT_ONLY(bool inSA = true); // true iff saI still points inside suffix + // array (as opposed to the padding at the + // end) + // Iterate over packed bwt bytes + VMSG_NL("Entering LocalGFM loop"); + ASSERT_ONLY(uint32_t beforeGbwtOff = (uint32_t)out5.tellp()); + while(side < gbwtTotSz) { + // Sanity-check our cursor into the side buffer + assert_geq(sideCur, 0); + assert_lt(sideCur, (int)gh._sideGbwtSz); + assert_eq(0, side % sideSz); // 'side' must be on side boundary + gfmSide[sideCur] = 0; // clear + assert_lt(side + sideCur, gbwtTotSz); + // Iterate over bit-pairs in the si'th character of the BWT +#ifdef SIXTY4_FORMAT + for(int bpi = 0; bpi < 32; bpi++, si++) { +#else + for(int bpi = 0; bpi < 4; bpi++, si++) { +#endif + int bwtChar; + bool count = true; + if(si <= len) { + // Still in the SA; extract the bwtChar + index_t saElt = (index_t)sa[si]; + // (that might have triggered sa to calc next suf block) + if(saElt == 0) { + // Don't add the '$' in the last column to the BWT + // transform; we can't encode a $ (only A C T or G) + // and counting it as, say, an A, will mess up the + // LR mapping + bwtChar = 0; count = false; + ASSERT_ONLY(dollarSkipped = true); + zOffs.push_back(si); // remember the SA row that + // corresponds to the 0th suffix + } else { + bwtChar = (int)(s[saElt-1]); + assert_lt(bwtChar, 4); + // Update the fchr + fchr[bwtChar]++; + } + // Update ftab + if((len-saElt) >= (index_t)gh._ftabChars) { + // Turn the first ftabChars characters of the + // suffix into an integer index into ftab. The + // leftmost (lowest index) character of the suffix + // goes in the most significant bit pair if the + // integer. + uint32_t sufInt = 0; + for(int i = 0; i < gh._ftabChars; i++) { + sufInt <<= 2; + assert_lt((index_t)i, len-saElt); + sufInt |= (unsigned char)(s[saElt+i]); + } + // Assert that this prefix-of-suffix is greater + // than or equal to the last one (true b/c the + // suffix array is sorted) +#ifndef NDEBUG + if(lastSufInt > 0) assert_geq(sufInt, lastSufInt); + lastSufInt = sufInt; +#endif + // Update ftab + assert_lt(sufInt+1, ftabLen); + ftab[sufInt+1]++; + if(absorbCnt > 0) { + // Absorb all short suffixes since the last + // transition into this transition + absorbFtab[sufInt] = absorbCnt; + absorbCnt = 0; + } + } else { + // Otherwise if suffix is fewer than ftabChars + // characters long, then add it to the 'absorbCnt'; + // it will be absorbed into the next transition + assert_lt(absorbCnt, 255); + absorbCnt++; + } + // Suffix array offset boundary? - update offset array + if((si & gh._offMask) == si) { + assert_lt((si >> gh._offRate), gh._offsLen); + // Write offsets directly to the secondary output + // stream, thereby avoiding keeping them in memory + writeIndex(out6, saElt, this->toBe()); + } + } else { + // Strayed off the end of the SA, now we're just + // padding out a bucket +#ifndef NDEBUG + if(inSA) { + // Assert that we wrote all the characters in the + // string before now + assert_eq(si, len+1); + inSA = false; + } +#endif + // 'A' used for padding; important that padding be + // counted in the occ[] array + bwtChar = 0; + } + if(count) occ[bwtChar]++; + // Append BWT char to bwt section of current side + if(fw) { + // Forward bucket: fill from least to most +#ifdef SIXTY4_FORMAT + gfmSide[sideCur] |= ((uint64_t)bwtChar << (bpi << 1)); + if(bwtChar > 0) assert_gt(gfmSide[sideCur], 0); +#else + pack_2b_in_8b(bwtChar, gfmSide[sideCur], bpi); + assert_eq((gfmSide[sideCur] >> (bpi*2)) & 3, bwtChar); +#endif + } else { + // Backward bucket: fill from most to least +#ifdef SIXTY4_FORMAT + gfmSide[sideCur] |= ((uint64_t)bwtChar << ((31 - bpi) << 1)); + if(bwtChar > 0) assert_gt(gfmSide[sideCur], 0); +#else + pack_2b_in_8b(bwtChar, gfmSide[sideCur], 3-bpi); + assert_eq((gfmSide[sideCur] >> ((3-bpi)*2)) & 3, bwtChar); +#endif + } + } // end loop over bit-pairs + assert_eq(dollarSkipped ? 3 : 0, (occ[0] + occ[1] + occ[2] + occ[3]) & 3); +#ifdef SIXTY4_FORMAT + assert_eq(0, si & 31); +#else + assert_eq(0, si & 3); +#endif + + sideCur++; + if(sideCur == (int)gh._sideGbwtSz) { + sideCur = 0; + index_t *uside = reinterpret_cast(gfmSide.ptr()); + // Write 'A', 'C', 'G' and 'T' tallies + side += sideSz; + assert_leq(side, gh._gbwtTotSz); + uside[(sideSz / sizeof(index_t))-4] = endianizeIndex(occSave[0], this->toBe()); + uside[(sideSz / sizeof(index_t))-3] = endianizeIndex(occSave[1], this->toBe()); + uside[(sideSz / sizeof(index_t))-2] = endianizeIndex(occSave[2], this->toBe()); + uside[(sideSz / sizeof(index_t))-1] = endianizeIndex(occSave[3], this->toBe()); + occSave[0] = occ[0]; + occSave[1] = occ[1]; + occSave[2] = occ[2]; + occSave[3] = occ[3]; + // Write backward side to primary file + out5.write((const char *)gfmSide.ptr(), sideSz); + } + } + VMSG_NL("Exited LocalGFM loop"); + if(absorbCnt > 0) { + // Absorb any trailing, as-yet-unabsorbed short suffixes into + // the last element of ftab + absorbFtab[ftabLen-1] = absorbCnt; + } + // Assert that our loop counter got incremented right to the end + assert_eq(side, gh._gbwtTotSz); + // Assert that we wrote the expected amount to out5 + assert_eq(((uint32_t)out5.tellp() - beforeGbwtOff), gh._gbwtTotSz); + // assert that the last thing we did was write a forward bucket + + // + // Write zOffs to primary stream + // + assert_eq(zOffs.size(), 1); + writeIndex(out5, zOffs.size(), this->toBe()); + for(size_t i = 0; i < zOffs.size(); i++) { + assert_neq(zOffs[i], (index_t)OFF_MASK); + writeIndex(out5, zOffs[i], this->toBe()); + } + + // + // Finish building fchr + // + // Exclusive prefix sum on fchr + for(int i = 1; i < 4; i++) { + fchr[i] += fchr[i-1]; + } + assert_lt(fchr[3], gbwtLen); + // Shift everybody up by one + for(int i = 4; i >= 1; i--) { + fchr[i] = fchr[i-1]; + } + fchr[0] = 0; + // Write fchr to primary file + for(int i = 0; i < 5; i++) { + writeIndex(out5, fchr[i], this->toBe()); + } + + // + // Finish building ftab and build eftab + // + // Prefix sum on ftable + index_t eftabLen = 0; + assert_eq(0, absorbFtab[0]); + for(index_t i = 1; i < ftabLen; i++) { + if(absorbFtab[i] > 0) eftabLen += 2; + } + assert_leq(eftabLen, (index_t)gh._ftabChars*2); + eftabLen = gh._ftabChars*2; + EList eftab(EBWT_CAT); + try { + eftab.resize(eftabLen); + eftab.fillZero(); + } catch(bad_alloc &e) { + cerr << "Out of memory allocating eftab[] " + << "in LocalGFM::buildToDisk() at " << __FILE__ << ":" + << __LINE__ << endl; + throw e; + } + index_t eftabCur = 0; + for(index_t i = 1; i < ftabLen; i++) { + index_t lo = ftab[i] + GFM::ftabHi(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, i-1); + if(absorbFtab[i] > 0) { + // Skip a number of short pattern indicated by absorbFtab[i] + index_t hi = lo + absorbFtab[i]; + assert_lt(eftabCur*2+1, eftabLen); + eftab[eftabCur*2] = lo; + eftab[eftabCur*2+1] = hi; + ftab[i] = (eftabCur++) ^ (index_t)OFF_MASK; // insert pointer into eftab + assert_eq(lo, GFM::ftabLo(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, i)); + assert_eq(hi, GFM::ftabHi(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, i)); + } else { + ftab[i] = lo; + } + } + assert_eq(GFM::ftabHi(ftab.ptr(), eftab.ptr(), len, ftabLen, eftabLen, ftabLen-1), len+1); + // Write ftab to primary file + for(index_t i = 0; i < ftabLen; i++) { + writeIndex(out5, ftab[i], this->toBe()); + } + // Write eftab to primary file + out5pos = out5.tellp(); + out5.seekp(headerPos); + writeIndex(out5, eftabLen, this->toBe()); + out5.seekp(out5pos); + for(index_t i = 0; i < eftabLen; i++) { + writeIndex(out5, eftab[i], this->toBe()); + } + + // Note: if you'd like to sanity-check the Ebwt, you'll have to + // read it back into memory first! + assert(!this->isInMemory()); + VMSG_NL("Exiting LocalGFM::buildToDisk()"); +} + +/** + * Read an Ebwt from file with given filename. + */ +template +void LocalGFM::readIntoMemory( + FILE *in5, + FILE *in6, + char *mmFile5, + char *mmFile6, + full_index_t& tidx, + full_index_t& localOffset, + full_index_t& joinedOffset, + bool switchEndian, + size_t& bytesRead, + size_t& bytesRead2, + int entireRev, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool justHeader, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + bool mmSweep, + bool loadNames, + bool startVerbose) + { +#ifdef BOWTIE_MM + char *mmFile[] = { mmFile5, mmFile6 }; +#endif + + // Reads header entries one by one from primary stream + tidx = readIndex(in5, switchEndian); bytesRead += sizeof(full_index_t); + localOffset = readIndex(in5, switchEndian); bytesRead += sizeof(full_index_t); + joinedOffset = readIndex(in5, switchEndian); bytesRead += sizeof(full_index_t); + index_t len = readIndex(in5, switchEndian); bytesRead += sizeof(index_t); + index_t gbwtLen = readIndex(in5, switchEndian); bytesRead += sizeof(index_t); + index_t numNodes = readIndex(in5, switchEndian); bytesRead += sizeof(index_t); + index_t eftabLen = readIndex(in5, switchEndian); bytesRead += sizeof(index_t); + + // Create a new EbwtParams from the entries read from primary stream + this->_gh.init(len, gbwtLen, numNodes, lineRate, offRate, ftabChars, eftabLen, entireRev); + + if(len <= 0) { + return; + } + + // Set up overridden suffix-array-sample parameters + uint32_t offsLen = this->_gh._offsLen; + uint32_t offRateDiff = 0; + uint32_t offsLenSampled = offsLen; + if(this->_overrideOffRate > offRate) { + offRateDiff = this->_overrideOffRate - offRate; + } + if(offRateDiff > 0) { + offsLenSampled >>= offRateDiff; + if((offsLen & ~((index_t)OFF_MASK << offRateDiff)) != 0) { + offsLenSampled++; + } + } + + // Can't override the offrate or isarate and use memory-mapped + // files; ultimately, all processes need to copy the sparser sample + // into their own memory spaces. + if(this->_useMm && (offRateDiff)) { + cerr << "Error: Can't use memory-mapped files when the offrate is overridden" << endl; + throw 1; + } + + // Read nPat from primary stream + this->_nPat = readIndex(in5, switchEndian); + assert_eq(this->_nPat, 1); + bytesRead += sizeof(index_t); + this->_plen.reset(); + + // Read plen from primary stream + if(this->_useMm) { +#ifdef BOWTIE_MM + this->_plen.init((index_t*)(mmFile[0] + bytesRead), this->_nPat, false); + bytesRead += this->_nPat*sizeof(index_t); + fseek(in5, this->_nPat*sizeof(index_t), SEEK_CUR); +#endif + } else { + try { + if(this->_verbose || startVerbose) { + cerr << "Reading plen (" << this->_nPat << "): "; + logTime(cerr); + } + this->_plen.init(new index_t[this->_nPat], this->_nPat, true); + if(switchEndian) { + for(index_t i = 0; i < this->_nPat; i++) { + this->plen()[i] = readIndex(in5, switchEndian); + } + } else { + size_t r = MM_READ(in5, (void*)(this->plen()), this->_nPat*sizeof(index_t)); + if(r != (size_t)(this->_nPat*sizeof(index_t))) { + cerr << "Error reading _plen[] array: " << r << ", " << this->_nPat*sizeof(index_t) << endl; + throw 1; + } + } + } catch(bad_alloc& e) { + cerr << "Out of memory allocating plen[] in Ebwt::read()" + << " at " << __FILE__ << ":" << __LINE__ << endl; + throw e; + } + } + + bool shmemLeader; + + // TODO: I'm not consistent on what "header" means. Here I'm using + // "header" to mean everything that would exist in memory if we + // started to build the Ebwt but stopped short of the build*() step + // (i.e. everything up to and including join()). + if(justHeader) return; + + this->_nFrag = readIndex(in5, switchEndian); + bytesRead += sizeof(index_t); + if(this->_verbose || startVerbose) { + cerr << "Reading rstarts (" << this->_nFrag*3 << "): "; + logTime(cerr); + } + assert_geq(this->_nFrag, this->_nPat); + this->_rstarts.reset(); + if(loadRstarts) { + if(this->_useMm) { +#ifdef BOWTIE_MM + this->_rstarts.init((index_t*)(mmFile[0] + bytesRead), this->_nFrag*3, false); + bytesRead += this->_nFrag*sizeof(index_t)*3; + fseek(in5, this->_nFrag*sizeof(index_t)*3, SEEK_CUR); +#endif + } else { + this->_rstarts.init(new index_t[this->_nFrag*3], this->_nFrag*3, true); + if(switchEndian) { + for(index_t i = 0; i < this->_nFrag*3; i += 3) { + // fragment starting position in joined reference + // string, text id, and fragment offset within text + this->rstarts()[i] = readIndex(in5, switchEndian); + this->rstarts()[i+1] = readIndex(in5, switchEndian); + this->rstarts()[i+2] = readIndex(in5, switchEndian); + } + } else { + size_t r = MM_READ(in5, (void *)this->rstarts(), this->_nFrag*sizeof(index_t)*3); + if(r != (size_t)(this->_nFrag*sizeof(index_t)*3)) { + cerr << "Error reading _rstarts[] array: " << r << ", " << (this->_nFrag*sizeof(index_t)*3) << endl; + throw 1; + } + } + } + } else { + // Skip em + assert(this->rstarts() == NULL); + bytesRead += this->_nFrag*sizeof(index_t)*3; + fseek(in5, this->_nFrag*sizeof(index_t)*3, SEEK_CUR); + } + + this->_gfm.reset(); + if(this->_useMm) { +#ifdef BOWTIE_MM + this->_gfm.init((uint8_t*)(mmFile[0] + bytesRead), this->_gh._gbwtTotLen, false); + bytesRead += this->_gh._gbwtTotLen; + fseek(in5, this->_gh._gbwtTotLen, SEEK_CUR); +#endif + } else { + // Allocate ebwt (big allocation) + if(this->_verbose || startVerbose) { + cerr << "Reading ebwt (" << this->_gh._gbwtTotLen << "): "; + logTime(cerr); + } + bool shmemLeader = true; + if(this->useShmem_) { + uint8_t *tmp = NULL; + shmemLeader = ALLOC_SHARED_U8( + (this->_in1Str + "[gfm]"), this->_gh._gbwtTotLen, &tmp, + "gfm[]", (this->_verbose || startVerbose)); + assert(tmp != NULL); + this->_gfm.init(tmp, this->_gh._gbwtTotLen, false); + if(this->_verbose || startVerbose) { + cerr << " shared-mem " << (shmemLeader ? "leader" : "follower") << endl; + } + } else { + try { + this->_gfm.init(new uint8_t[this->_gh._gbwtTotLen], this->_gh._gbwtTotLen, true); + } catch(bad_alloc& e) { + cerr << "Out of memory allocating the ebwt[] array for the Bowtie index. Please try" << endl + << "again on a computer with more memory." << endl; + throw 1; + } + } + if(shmemLeader) { + // Read ebwt from primary stream + uint64_t bytesLeft = this->_gh._gbwtTotLen; + char *pgbwt = (char*)this->gfm(); + + while (bytesLeft>0){ + size_t r = MM_READ(in5, (void *)pgbwt, bytesLeft); + if(MM_IS_IO_ERR(in5, r, bytesLeft)) { + cerr << "Error reading _ebwt[] array: " << r << ", " + << bytesLeft << endl; + throw 1; + } + pgbwt += r; + bytesLeft -= r; + } + if(switchEndian) { + uint8_t *side = this->gfm(); + for(size_t i = 0; i < this->_gh._numSides; i++) { + index_t *cums = reinterpret_cast(side + this->_gh._sideSz - sizeof(index_t)*2); + cums[0] = endianSwapIndex(cums[0]); + cums[1] = endianSwapIndex(cums[1]); + side += this->_gh._sideSz; + } + } +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) NOTIFY_SHARED(this->gfm(), this->_gh._gbwtTotLen); +#endif + } else { + // Seek past the data and wait until master is finished + fseek(in5, this->_gh._gbwtTotLen, SEEK_CUR); +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) WAIT_SHARED(this->gfm(), this->_gh._gbwtTotLen); +#endif + } + } + + // Read zOff from primary stream + this->_zOffs.clear(); + index_t num_zOffs = readIndex(in5, switchEndian); + bytesRead += sizeof(index_t); + for(index_t i = 0; i < num_zOffs; i++) { + index_t zOff = readIndex(in5, switchEndian); + bytesRead += sizeof(index_t); + assert_lt(zOff, gbwtLen); + this->_zOffs.push_back(zOff); + } + + try { + // Read fchr from primary stream + if(this->_verbose || startVerbose) cerr << "Reading fchr (5)" << endl; + this->_fchr.reset(); + if(this->_useMm) { +#ifdef BOWTIE_MM + this->_fchr.init((index_t*)(mmFile[0] + bytesRead), 5, false); + bytesRead += 5*sizeof(index_t); + fseek(in5, 5*sizeof(index_t), SEEK_CUR); +#endif + } else { + this->_fchr.init(new index_t[5], 5, true); + for(index_t i = 0; i < 5; i++) { + this->fchr()[i] = readIndex(in5, switchEndian); + assert_leq(this->fchr()[i], gbwtLen); + assert(i <= 0 || this->fchr()[i] >= this->fchr()[i-1]); + } + } + assert_gt(this->fchr()[4], this->fchr()[0]); + // Read ftab from primary stream + if(this->_verbose || startVerbose) { + if(loadFtab) { + cerr << "Reading ftab (" << this->_gh._ftabLen << "): "; + logTime(cerr); + } else { + cerr << "Skipping ftab (" << this->_gh._ftabLen << "): "; + } + } + this->_ftab.reset(); + if(loadFtab) { + if(this->_useMm) { +#ifdef BOWTIE_MM + this->_ftab.init((index_t*)(mmFile[0] + bytesRead), this->_gh._ftabLen, false); + bytesRead += this->_gh._ftabLen*sizeof(index_t); + fseek(in5, this->_gh._ftabLen*sizeof(index_t), SEEK_CUR); +#endif + } else { + this->_ftab.init(new index_t[this->_gh._ftabLen], this->_gh._ftabLen, true); + if(switchEndian) { + for(uint32_t i = 0; i < this->_gh._ftabLen; i++) + this->ftab()[i] = readIndex(in5, switchEndian); + } else { + size_t r = MM_READ(in5, (void *)this->ftab(), this->_gh._ftabLen*sizeof(index_t)); + if(r != (size_t)(this->_gh._ftabLen*sizeof(index_t))) { + cerr << "Error reading _ftab[] array: " << r << ", " << (this->_gh._ftabLen*sizeof(index_t)) << endl; + throw 1; + } + } + } + // Read etab from primary stream + if(this->_verbose || startVerbose) { + if(loadFtab) { + cerr << "Reading eftab (" << this->_gh._eftabLen << "): "; + logTime(cerr); + } else { + cerr << "Skipping eftab (" << this->_gh._eftabLen << "): "; + } + + } + this->_eftab.reset(); + if(this->_useMm) { +#ifdef BOWTIE_MM + this->_eftab.init((index_t*)(mmFile[0] + bytesRead), this->_gh._eftabLen, false); + bytesRead += this->_gh._eftabLen*sizeof(index_t); + fseek(in5, this->_gh._eftabLen*sizeof(index_t), SEEK_CUR); +#endif + } else { + this->_eftab.init(new index_t[this->_gh._eftabLen], this->_gh._eftabLen, true); + if(switchEndian) { + for(uint32_t i = 0; i < this->_gh._eftabLen; i++) + this->eftab()[i] = readIndex(in5, switchEndian); + } else { + size_t r = MM_READ(in5, (void *)this->eftab(), this->_gh._eftabLen*sizeof(index_t)); + if(r != (size_t)(this->_gh._eftabLen*sizeof(index_t))) { + cerr << "Error reading _eftab[] array: " << r << ", " << (this->_gh._eftabLen*sizeof(index_t)) << endl; + throw 1; + } + } + } + for(uint32_t i = 0; i < this->_gh._eftabLen; i++) { + if(i > 0 && this->eftab()[i] > 0) { + assert_geq(this->eftab()[i] + 4, this->eftab()[i-1]); + } else if(i > 0 && this->eftab()[i-1] == 0) { + assert_eq(0, this->eftab()[i]); + } + } + } else { + assert(this->ftab() == NULL); + assert(this->eftab() == NULL); + // Skip ftab + bytesRead += this->_gh._ftabLen*sizeof(index_t); + fseek(in5, this->_gh._ftabLen*sizeof(index_t), SEEK_CUR); + // Skip eftab + bytesRead += this->_gh._eftabLen*sizeof(index_t); + fseek(in5, this->_gh._eftabLen*sizeof(index_t), SEEK_CUR); + } + } catch(bad_alloc& e) { + cerr << "Out of memory allocating fchr[], ftab[] or eftab[] arrays for the Bowtie index." << endl + << "Please try again on a computer with more memory." << endl; + throw 1; + } + + this->_offs.reset(); + if(loadSASamp) { + shmemLeader = true; + if(this->_verbose || startVerbose) { + cerr << "Reading offs (" << offsLenSampled << " " << std::setw(2) << sizeof(index_t)*8 << "-bit words): "; + logTime(cerr); + } + + if(!this->_useMm) { + if(!this->useShmem_) { + // Allocate offs_ + try { + this->_offs.init(new index_t[offsLenSampled], offsLenSampled, true); + } catch(bad_alloc& e) { + cerr << "Out of memory allocating the offs[] array for the Bowtie index." << endl + << "Please try again on a computer with more memory." << endl; + throw 1; + } + } else { + index_t *tmp = NULL; + shmemLeader = ALLOC_SHARED_U32( + (this->_in2Str + "[offs]"), offsLenSampled*2, &tmp, + "offs", (this->_verbose || startVerbose)); + this->_offs.init((index_t*)tmp, offsLenSampled, false); + } + } + + if(this->_overrideOffRate < 32) { + if(shmemLeader) { + // Allocate offs (big allocation) + if(switchEndian || offRateDiff > 0) { + assert(!this->_useMm); + const uint32_t blockMaxSz = (2 * 1024 * 1024); // 2 MB block size + const uint32_t blockMaxSzUIndex = (blockMaxSz / sizeof(index_t)); // # UIndexs per block + char *buf; + try { + buf = new char[blockMaxSz]; + } catch(std::bad_alloc& e) { + cerr << "Error: Out of memory allocating part of _offs array: '" << e.what() << "'" << endl; + throw e; + } + for(index_t i = 0; i < offsLen; i += blockMaxSzUIndex) { + index_t block = min((index_t)blockMaxSzUIndex, (index_t)(offsLen - i)); + size_t r = MM_READ(in6, (void *)buf, block * sizeof(index_t)); + if(r != (size_t)(block * sizeof(index_t))) { + cerr << "Error reading block of _offs[] array: " << r << ", " << (block * sizeof(index_t)) << endl; + throw 1; + } + index_t idx = i >> offRateDiff; + for(index_t j = 0; j < block; j += (1 << offRateDiff)) { + assert_lt(idx, offsLenSampled); + this->offs()[idx] = ((index_t*)buf)[j]; + if(switchEndian) { + this->offs()[idx] = endianSwapIndex(this->offs()[idx]); + } + idx++; + } + } + delete[] buf; + } else { + if(this->_useMm) { +#ifdef BOWTIE_MM + this->_offs.init((index_t*)(mmFile[1] + bytesRead2), offsLen, false); + bytesRead2 += (offsLen * sizeof(index_t)); + fseek(in6, (offsLen * sizeof(index_t)), SEEK_CUR); +#endif + } else { + // If any of the high two bits are set + if((offsLen & 0xc0000000) != 0) { + if(sizeof(char *) <= 4) { + cerr << "Sanity error: sizeof(char *) <= 4 but offsLen is " << hex << offsLen << endl; + throw 1; + } + // offsLen << 2 overflows, so do it in four reads + char *offs = (char *)this->offs(); + for(size_t i = 0; i < sizeof(index_t); i++) { + size_t r = MM_READ(in6, (void*)offs, offsLen); + if(r != (size_t)(offsLen)) { + cerr << "Error reading block of _offs[] array: " << r << ", " << offsLen << endl; + throw 1; + } + offs += offsLen; + } + } else { + // Do it all in one read + size_t r = MM_READ(in6, (void*)this->offs(), offsLen * sizeof(index_t)); + if(r != (size_t)(offsLen * sizeof(index_t))) { + cerr << "Error reading _offs[] array: " << r << ", " << (offsLen * sizeof(index_t)) << endl; + throw 1; + } + } + } + } +#ifdef BOWTIE_SHARED_MEM + if(this->useShmem_) NOTIFY_SHARED(this->offs(), offsLenSampled*sizeof(index_t)); +#endif + } else { + // Not the shmem leader + fseek(in6, offsLenSampled*sizeof(index_t), SEEK_CUR); +#ifdef BOWTIE_SHARED_MEM + if(this->useShmem_) WAIT_SHARED(this->offs(), offsLenSampled*sizeof(index_t)); +#endif + } + } + } + + this->postReadInit(this->_gh); // Initialize fields of Ebwt not read from file + if(this->_verbose || startVerbose) this->print(cerr, this->_gh); +} + +/** + * Extended Burrows-Wheeler transform data. + * HierEbwt is a specialized Ebwt index that represents one global index and a large set of local indexes. + * + */ +template +class HGFM : public GFM { + typedef GFM PARENT_CLASS; +public: + /// Construct a GFM from the given input file + HGFM(const string& in, + ALTDB* altdb, + RepeatDB* repeatdb, + EList* readLens, + int needEntireReverse, + bool fw, + int32_t overrideOffRate, // = -1, + int32_t offRatePlus, // = -1, + bool useMm, // = false, + bool useShmem, // = false, + bool mmSweep, // = false, + bool loadNames, // = false, + bool loadSASamp, // = true, + bool loadFtab, // = true, + bool loadRstarts, // = true, + bool loadSpliceSites, // = true, + bool verbose, // = false, + bool startVerbose, // = false, + bool passMemExc, // = false, + bool sanityCheck, // = false + bool useHaplotype, // = false + bool skipLoading = false) : + GFM(in, + altdb, + repeatdb, + readLens, + needEntireReverse, + fw, + overrideOffRate, + offRatePlus, + useMm, + useShmem, + mmSweep, + loadNames, + loadSASamp, + loadFtab, + loadRstarts, + loadSpliceSites, + verbose, + startVerbose, + passMemExc, + sanityCheck, + useHaplotype, + skipLoading), + _in5(NULL), + _in6(NULL) + { + _in5Str = in + ".5." + gfm_ext; + _in6Str = in + ".6." + gfm_ext; + } + + /// Construct a HGFM from the given header parameters and string + /// vector, optionally using a blockwise suffix sorter with the + /// given 'bmax' and 'dcv' parameters. The string vector is + /// ultimately joined and the joined string is passed to buildToDisk(). + template + HGFM( + TStr& s, + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + int32_t localOffRate, + int32_t localFtabChars, + int nthreads, + const string& snpfile, + const string& htfile, + const string& ssfile, + const string& exonfile, + const string& svfile, + const string& repeatfile, + const string& outfile, // base filename for GFM files + bool fw, + bool useBlockwise, + TIndexOffU bmax, + TIndexOffU bmaxSqrtMult, + TIndexOffU bmaxDivN, + int dcv, + EList& is, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + bool localIndex, // create local indexes? + EList* parent_szs, + EList* parent_refnames, + uint32_t seed, + int32_t overrideOffRate = -1, + bool verbose = false, + bool passMemExc = false, + bool sanityCheck = false); + + HGFM() {} + + ~HGFM() { + clearLocalGFMs(); + } + + /** + * Load this Ebwt into memory by reading it in from the _in1 and + * _in2 streams. + */ + void loadIntoMemory( + int needEntireReverse, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool loadNames, + bool verbose) + { + readIntoMemory( + needEntireReverse, // require reverse index to be concatenated reference reversed + loadSASamp, // load the SA sample portion? + loadFtab, // load the ftab (_ftab[] and _eftab[])? + loadRstarts, // load the r-starts (_rstarts[])? + false, // stop after loading the header portion? + NULL, // params + false, // mmSweep + loadNames, // loadNames + verbose); // startVerbose + } + + // I/O + void readIntoMemory( + int needEntireRev, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool justHeader, + GFMParams *params, + bool mmSweep, + bool loadNames, + bool startVerbose); + + /** + * Frees memory associated with the Ebwt. + */ + void evictFromMemory() { + assert(PARENT_CLASS::isInMemory()); + clearLocalGFMs(); + PARENT_CLASS::evictFromMemory(); + } + + /** + * Sanity-check various pieces of the Ebwt + */ + void sanityCheckAll(int reverse) const { + PARENT_CLASS::sanityCheckAll(reverse); + for(size_t tidx = 0; tidx < _localGFMs.size(); tidx++) { + for(size_t local_idx = 0; local_idx < _localGFMs[tidx].size(); local_idx++) { + assert(_localGFMs[tidx][local_idx] != NULL); + _localGFMs[tidx][local_idx]->sanityCheckAll(reverse); + } + } + } + + const LocalGFM* getLocalGFM(index_t tidx, index_t offset) const { + assert_lt(tidx, _localGFMs.size()); + const EList*>& localGFMs = _localGFMs[tidx]; + index_t offsetidx = offset / local_index_interval; + if(offsetidx >= localGFMs.size()) { + return NULL; + } else { + return localGFMs[offsetidx]; + } + } + + const LocalGFM* prevLocalGFM(const LocalGFM* currLocalGFM) const { + assert(currLocalGFM != NULL); + index_t tidx = currLocalGFM->_tidx; + index_t offset = currLocalGFM->_localOffset; + if(offset < local_index_interval) { + return NULL; + } else { + return getLocalGFM(tidx, offset - local_index_interval); + } + } + + const LocalGFM* nextLocalGFM(const LocalGFM* currLocalGFM) const { + assert(currLocalGFM != NULL); + index_t tidx = currLocalGFM->_tidx; + index_t offset = currLocalGFM->_localOffset; + return getLocalGFM(tidx, offset + local_index_interval); + } + + void clearLocalGFMs() { + for(size_t tidx = 0; tidx < _localGFMs.size(); tidx++) { + for(size_t local_idx = 0; local_idx < _localGFMs[tidx].size(); local_idx++) { + assert(_localGFMs[tidx][local_idx] != NULL); + delete _localGFMs[tidx][local_idx]; + } + + _localGFMs[tidx].clear(); + } + + _localGFMs.clear(); + } + + +public: + index_t _nrefs; /// the number of reference sequences + EList _refLens; /// approx lens of ref seqs (excludes trailing ambig chars) + + EList*> > _localGFMs; + index_t _nlocalGFMs; + //index_t _local_index_interval; + + FILE *_in5; // input fd for primary index file + FILE *_in6; // input fd for secondary index file + string _in5Str; + string _in6Str; + + char *mmFile5_; + char *mmFile6_; + +private: + struct ThreadParam { + // input + SString s; + EList > alts; + EList > haplotypes; + bool bigEndian; + index_t local_offset; + index_t curr_sztot; + EList conv_local_szs; + index_t local_sztot; + index_t index_size; + string file; + EList sa; + index_t dcv; + index_t seed; + + // output + RefGraph* rg; + PathGraph* pg; + + // communication + bool done; + bool last; + bool mainThread; + }; + static void gbwt_worker(void* vp); +}; + + +template +void HGFM::gbwt_worker(void* vp) +{ + ThreadParam& tParam = *(ThreadParam*)vp; + while(!tParam.last) { + if(tParam.mainThread) { + assert(!tParam.done); + if(tParam.s.length() <= 0) { + tParam.done = true; + return; + } + } else { + while(tParam.done) { + if(tParam.last) return; +#if defined(_TTHREAD_WIN32_) + Sleep(1); +#elif defined(_TTHREAD_POSIX_) + const static timespec ts = {0, 1000000}; // 1 millisecond + nanosleep(&ts, NULL); +#endif + } + if(tParam.s.length() <= 0) { + tParam.done = true; + continue; + } + } + while(true) { + if(tParam.alts.empty()) { + KarkkainenBlockwiseSA > bsa( + tParam.s, + (index_t)(tParam.s.length()+1), + 1, + tParam.dcv, + tParam.seed, + false, /* this->_sanity */ + false, /* this->_passMemExc */ + false); /* this->_verbose */ + assert(bsa.suffixItrIsReset()); + assert_eq(bsa.size(), tParam.s.length()+1); + tParam.sa.clear(); + for(index_t i = 0; i < bsa.size(); i++) { + tParam.sa.push_back(bsa.nextSuffix()); + } + } else { + tParam.rg = NULL, tParam.pg = NULL; + bool exploded = false; + try { + tParam.rg = new RefGraph( + tParam.s, + tParam.conv_local_szs, + tParam.alts, + tParam.haplotypes, + tParam.file, + 1, /* num threads */ + false); /* verbose? */ + tParam.pg = new PathGraph( + *tParam.rg, + tParam.file, + local_max_gbwt, + 1, /* num threads */ + false); /* verbose? */ + } catch (const NongraphException& err) { + cerr << "Warning: no variants or splice sites in this graph (" << tParam.curr_sztot << ")" << endl; + delete tParam.rg; + delete tParam.pg; + tParam.alts.clear(); + continue; + } catch (const ExplosionException& err) { + exploded = true; + } + if(!exploded) { + if(!tParam.pg->generateEdges(*tParam.rg)) { + cerr << "An error occurred - generateEdges" << endl; + throw 1; + } + exploded = tParam.pg->getNumEdges() > local_max_gbwt; + } + if(exploded) { + cerr << "Warning: a local graph exploded (offset: " << tParam.curr_sztot << ", length: " << tParam.local_sztot << ")" << endl; + + delete tParam.pg; tParam.pg = NULL; + delete tParam.rg; tParam.rg = NULL; + if(tParam.alts.size() <= 1) { + tParam.alts.clear(); + } else { + for(index_t s = 2; s < tParam.alts.size(); s += 2) { + tParam.alts[s >> 1] = tParam.alts[s]; + } + tParam.alts.resize(tParam.alts.size() >> 1); + tParam.haplotypes.clear(); + for(index_t a = 0; a < tParam.alts.size(); a++) { + const ALT& alt = tParam.alts[a]; + if(!alt.snp()) continue; + tParam.haplotypes.expand(); + tParam.haplotypes.back().left = alt.pos; + if(alt.deletion()) { + tParam.haplotypes.back().right = alt.pos + alt.len - 1; + } else { + tParam.haplotypes.back().right = alt.pos; + } + tParam.haplotypes.back().alts.clear(); + tParam.haplotypes.back().alts.push_back(a); + } + } + continue; + } + } + break; + } + tParam.done = true; + if(tParam.mainThread) break; + } +} + +/// Construct a GFM from the given header parameters and string +/// vector, optionally using a blockwise suffix sorter with the +/// given 'bmax' and 'dcv' parameters. The string vector is +/// ultimately joined and the joined string is passed to buildToDisk(). +template +template +HGFM::HGFM( + TStr& s, + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + int32_t localOffRate, + int32_t localFtabChars, + int nthreads, + const string& snpfile, + const string& htfile, + const string& ssfile, + const string& exonfile, + const string& svfile, + const string& repeatfile, + const string& outfile, // base filename for EBWT files + bool fw, + bool useBlockwise, + TIndexOffU bmax, + TIndexOffU bmaxSqrtMult, + TIndexOffU bmaxDivN, + int dcv, + EList& is, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + bool localIndex, + EList* parent_szs, + EList* parent_refnames, + uint32_t seed, + int32_t overrideOffRate, + bool verbose, + bool passMemExc, + bool sanityCheck) : + GFM(s, + packed, + needEntireReverse, + lineRate, + offRate, + ftabChars, + nthreads, + snpfile, + htfile, + ssfile, + exonfile, + svfile, + repeatfile, + outfile, + fw, + useBlockwise, + bmax, + bmaxSqrtMult, + bmaxDivN, + dcv, + is, + szs, + sztot, + refparams, + parent_szs, + parent_refnames, + seed, + overrideOffRate, + verbose, + passMemExc, + sanityCheck), + _in5(NULL), + _in6(NULL) +{ + _in5Str = outfile + ".5." + gfm_ext; + _in6Str = outfile + ".6." + gfm_ext; + + // const bool repeat_index = (parent_szs != NULL); + + int32_t local_lineRate; + if(snpfile == "" && ssfile == "" && exonfile == "") { + local_lineRate = local_lineRate_fm; + } else { + local_lineRate = local_lineRate_gfm; + } + + // Open output files + ofstream fout5(_in5Str.c_str(), ios::binary); + if(!fout5.good()) { + cerr << "Could not open index file for writing: \"" << _in5Str.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + ofstream fout6(_in6Str.c_str(), ios::binary); + if(!fout6.good()) { + cerr << "Could not open index file for writing: \"" << _in6Str.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + + // Split the whole genome into a set of local indexes + _nrefs = 0; + _nlocalGFMs = 0; + + index_t cumlen = 0; + typedef EList EList_RefRecord; + ELList all_local_recs; + + if(localIndex) { + // For each unambiguous stretch... + for(index_t i = 0; i < szs.size(); i++) { + const RefRecord& rec = szs[i]; + if(rec.first) { + if(_nrefs > 0) { + // refLens_ links each reference sequence with the total number + // of ambiguous and unambiguous characters in it. + _refLens.push_back(cumlen); + } + cumlen = 0; + _nrefs++; + all_local_recs.expand(); + assert_eq(_nrefs, all_local_recs.size()); + } else if(i == 0) { + cerr << "First record in reference index file was not marked as " + << "'first'" << endl; + throw 1; + } + + assert_gt(_nrefs, 0); + assert_eq(_nrefs, all_local_recs.size()); + EList& ref_local_recs = all_local_recs[_nrefs-1]; + index_t next_cumlen = cumlen + rec.off + rec.len; + index_t local_off = (cumlen / local_index_interval) * local_index_interval; + if(local_off >= local_index_interval) { + local_off -= local_index_interval; + } + for(;local_off < next_cumlen; local_off += local_index_interval) { + if(local_off + local_index_size <= cumlen) { + continue; + } + index_t local_idx = local_off / local_index_interval; + + if(local_idx >= ref_local_recs.size()) { + assert_eq(local_idx, ref_local_recs.size()); + ref_local_recs.expand(); + _nlocalGFMs++; + } + assert_lt(local_idx, ref_local_recs.size()); + EList_RefRecord& local_recs = ref_local_recs[local_idx]; + assert_gt(local_off + local_index_size, cumlen); + local_recs.expand(); + if(local_off + local_index_size < cumlen + rec.off) { + local_recs.back().off = local_off + local_index_size - std::max(local_off, cumlen); + local_recs.back().len = 0; + } else { + if(local_off < cumlen + rec.off) { + local_recs.back().off = rec.off - (local_off > cumlen ? local_off - cumlen : 0); + } else { + local_recs.back().off = 0; + } + local_recs.back().len = std::min(next_cumlen, local_off + local_index_size) - std::max(local_off, cumlen + rec.off); + } + local_recs.back().first = (local_recs.size() == 1); + } + cumlen = next_cumlen; + } + + // Store a cap entry for the end of the last reference seq + _refLens.push_back(cumlen); + +#ifndef NDEBUG + EList temp_szs; + index_t temp_sztot = 0; + index_t temp_nlocalGFMs = 0; + for(size_t tidx = 0; tidx < all_local_recs.size(); tidx++) { + assert_lt(tidx, _refLens.size()); + EList& ref_local_recs = all_local_recs[tidx]; + assert_eq((_refLens[tidx] + local_index_interval - 1) / local_index_interval, ref_local_recs.size()); + temp_szs.expand(); + temp_szs.back().off = 0; + temp_szs.back().len = 0; + temp_szs.back().first = true; + index_t temp_ref_len = 0; + index_t temp_ref_sztot = 0; + temp_nlocalGFMs += ref_local_recs.size(); + for(size_t i = 0; i < ref_local_recs.size(); i++) { + EList_RefRecord& local_recs = ref_local_recs[i]; + index_t local_len = 0; + for(size_t j = 0; j < local_recs.size(); j++) { + assert(local_recs[j].off != 0 || local_recs[j].len != 0); + assert(j != 0 || local_recs[j].first); + RefRecord local_rec = local_recs[j]; + if(local_len < local_index_interval && local_recs[j].off > 0){ + if(local_len + local_recs[j].off > local_index_interval) { + temp_ref_len += (local_index_interval - local_len); + local_rec.off = local_index_interval - local_len; + } else { + temp_ref_len += local_recs[j].off; + } + } else { + local_rec.off = 0; + } + local_len += local_recs[j].off; + if(local_len < local_index_interval && local_recs[j].len > 0) { + if(local_len + local_recs[j].len > local_index_interval) { + temp_ref_len += (local_index_interval - local_len); + temp_ref_sztot += (local_index_interval - local_len); + local_rec.len = local_index_interval - local_len; + } else { + temp_ref_len += local_recs[j].len; + temp_ref_sztot += local_recs[j].len; + } + } else { + local_rec.len = 0; + } + local_len += local_recs[j].len; + if(local_rec.off > 0) { + if(temp_szs.back().len > 0) { + temp_szs.expand(); + temp_szs.back().off = local_rec.off; + temp_szs.back().len = local_rec.len; + temp_szs.back().first = false; + } else { + temp_szs.back().off += local_rec.off; + temp_szs.back().len = local_rec.len; + } + } else if(local_rec.len > 0) { + temp_szs.back().len += local_rec.len; + } + } + if(i + 2 < ref_local_recs.size()) { + assert_eq(local_len, local_index_size); + assert_eq(temp_ref_len % local_index_interval, 0); + } else if (i + 1 < ref_local_recs.size()) { + assert_leq(local_len, local_index_size); + assert_geq(local_len, local_index_interval); + } else { + assert_eq(local_len % local_index_interval, _refLens[tidx] % local_index_interval); + } + } + assert_eq(temp_ref_len, _refLens[tidx]); + temp_sztot += temp_ref_sztot; + } + assert_eq(temp_sztot, sztot); + for(size_t i = 0; i < temp_szs.size(); i++) { + assert_lt(i, szs.size()); + assert_eq(temp_szs[i].off, szs[i].off); + assert_eq(temp_szs[i].len, szs[i].len); + assert_eq(temp_szs[i].first, szs[i].first); + } + assert_eq(temp_szs.size(), szs.size()); + assert_eq(_nlocalGFMs, temp_nlocalGFMs); +#endif + } + + uint32_t be = this->toBe(); + assert(fout5.good()); + assert(fout6.good()); + + // const local_index_t new_localFtabChars = (repeat_index ? 4 : localFtabChars); + const local_index_t new_localFtabChars = localFtabChars; + + // When building an Ebwt, these header parameters are known + // "up-front", i.e., they can be written to disk immediately, + // before we join() or buildToDisk() + writeI32(fout5, 1, be); // endian hint for priamry stream + writeI32(fout6, 1, be); // endian hint for secondary stream + writeIndex(fout5, _nlocalGFMs, be); // number of local Ebwts + writeI32(fout5, local_lineRate, be); // 2^lineRate = size in bytes of 1 line + writeI32(fout5, 2, be); // not used + writeI32(fout5, (int32_t)localOffRate, be); // every 2^offRate chars is "marked" + writeI32(fout5, (int32_t)new_localFtabChars, be); // number of 2-bit chars used to address ftab + int32_t flags = 1; + if(this->_gh._entireReverse) flags |= GFM_ENTIRE_REV; + writeI32(fout5, -flags, be); // BTL: chunkRate is now deprecated + + if(localIndex) { + assert_gt(this->_nthreads, 0); + AutoArray threads(this->_nthreads - 1); + EList tParams; tParams.reserveExact((size_t)this->_nthreads); + for(index_t t = 0; t < (index_t)this->_nthreads; t++) { + tParams.expand(); + tParams.back().s.clear(); + tParams.back().rg = NULL; + tParams.back().pg = NULL; + tParams.back().file = outfile; + tParams.back().done = true; + tParams.back().last = false; + tParams.back().dcv = 1024; + tParams.back().seed = seed; + if(t + 1 < (index_t)this->_nthreads) { + tParams.back().mainThread = false; + threads[t] = new tthread::thread(gbwt_worker, (void*)&tParams.back()); + } else { + tParams.back().mainThread = true; + } + } + + // build local FM indexes + index_t curr_sztot = 0; + EList > alts; + for(size_t tidx = 0; tidx < _refLens.size(); tidx++) { + index_t refLen = _refLens[tidx]; + index_t local_offset = 0; + _localGFMs.expand(); + assert_lt(tidx, _localGFMs.size()); + while(local_offset < refLen) { + index_t t = 0; + while(local_offset < refLen && t < (index_t)this->_nthreads) { + assert_lt(t, tParams.size()); + ThreadParam& tParam = tParams[t]; + + tParam.index_size = std::min(refLen - local_offset, local_index_size); + assert_lt(tidx, all_local_recs.size()); + assert_lt(local_offset / local_index_interval, all_local_recs[tidx].size()); + EList_RefRecord& local_szs = all_local_recs[tidx][local_offset / local_index_interval]; + + tParam.conv_local_szs.clear(); + index_t local_len = 0, local_sztot = 0, local_sztot_interval = 0; + for(size_t i = 0; i < local_szs.size(); i++) { + assert(local_szs[i].off != 0 || local_szs[i].len != 0); + assert(i != 0 || local_szs[i].first); + tParam.conv_local_szs.push_back(local_szs[i]); + local_len += local_szs[i].off; + if(local_len < local_index_interval && local_szs[i].len > 0) { + if(local_len + local_szs[i].len > local_index_interval) { + local_sztot_interval += (local_index_interval - local_len); + } else { + local_sztot_interval += local_szs[i].len; + } + } + local_sztot += local_szs[i].len; + local_len += local_szs[i].len; + } + + // Extract sequence corresponding to this local index + tParam.s.resize(local_sztot); + if(refparams.reverse == REF_READ_REVERSE) { + tParam.s.install(s.buf() + s.length() - curr_sztot - local_sztot, local_sztot); + } else { + tParam.s.install(s.buf() + curr_sztot, local_sztot); + } + + // Extract ALTs corresponding to this local index + map alt_map; + tParam.alts.clear(); + ALT alt; + alt.pos = curr_sztot; + index_t alt_i = (index_t)this->_alts.bsearchLoBound(alt); + for(; alt_i < this->_alts.size(); alt_i++) { + const ALT& alt = this->_alts[alt_i]; + if(alt.snp()) { + if(alt.mismatch()) { + if(curr_sztot + local_sztot <= alt.pos) break; + } else if(alt.insertion()) { + if(curr_sztot + local_sztot < alt.pos) break; + } else { + assert(alt.deletion()); + if(curr_sztot + local_sztot < alt.pos + alt.len) break; + } + if(curr_sztot <= alt.pos) { + alt_map[alt_i] = (index_t)tParam.alts.size(); + tParam.alts.push_back(alt); + tParam.alts.back().pos -= curr_sztot; + } + } else if(alt.splicesite()) { + if(alt.excluded) continue; + if(curr_sztot + local_sztot <= alt.right + 1) continue; + if(curr_sztot <= alt.left) { + tParam.alts.push_back(alt); + tParam.alts.back().left -= curr_sztot; + tParam.alts.back().right -= curr_sztot; + } + } else { + assert(alt.exon()); + } + } + + // Extract haplotypes + tParam.haplotypes.clear(); + Haplotype haplotype; + haplotype.left = curr_sztot; + index_t haplotpye_i = (index_t)this->_haplotypes.bsearchLoBound(haplotype); + for(; haplotpye_i < this->_haplotypes.size(); haplotpye_i++) { + const Haplotype& haplotype = this->_haplotypes[haplotpye_i]; + if(curr_sztot + local_sztot <= haplotype.right) continue; + if(curr_sztot <= haplotype.left) { + tParam.haplotypes.push_back(haplotype); + tParam.haplotypes.back().left -= curr_sztot; + tParam.haplotypes.back().right -= curr_sztot; + for(index_t a = 0; a < tParam.haplotypes.back().alts.size(); a++) { + index_t alt_i = tParam.haplotypes.back().alts[a]; + if(alt_map.find(alt_i) == alt_map.end()) { + assert(false); + tParam.haplotypes.pop_back(); + break; + } + tParam.haplotypes.back().alts[a] = alt_map[alt_i]; + } + } + } + + tParam.local_offset = local_offset; + tParam.curr_sztot = curr_sztot; + tParam.local_sztot = local_sztot; + + assert(tParam.rg == NULL); + assert(tParam.pg == NULL); + tParam.done = false; + curr_sztot += local_sztot_interval; + local_offset += local_index_interval; + + t++; + } + + if(!tParams.back().done) { + gbwt_worker((void*)&tParams.back()); + } + + for(index_t t2 = 0; t2 < t; t2++) { + ThreadParam& tParam = tParams[t2]; + while(!tParam.done) { +#if defined(_TTHREAD_WIN32_) + Sleep(1); +#elif defined(_TTHREAD_POSIX_) + const static timespec ts = {0, 1000000}; // 1 millisecond + nanosleep(&ts, NULL); +#endif + } + + LocalGFM( + tParam.s, + tParam.sa, + tParam.pg, + (index_t)tidx, + tParam.local_offset, + tParam.curr_sztot, + tParam.alts, + tParam.index_size, + packed, + needEntireReverse, + local_lineRate, + localOffRate, // suffix-array sampling rate + new_localFtabChars, // number of chars in initial arrow-pair calc + outfile, // basename for .?.ebwt files + fw, // fw + dcv, // difference-cover period + tParam.conv_local_szs, // list of reference sizes + tParam.local_sztot, // total size of all unambiguous ref chars + refparams, // reference read-in parameters + seed, // pseudo-random number generator seed + fout5, + fout6, + -1, // override offRate + false, // be silent + passMemExc, // pass exceptions up to the toplevel so that we can adjust memory settings automatically + sanityCheck); // verify results and internal consistency + tParam.s.clear(); + if(tParam.rg != NULL) { + assert(tParam.pg != NULL); + delete tParam.rg; tParam.rg = NULL; + delete tParam.pg; tParam.pg = NULL; + } + } + } + } + assert_eq(curr_sztot, sztot); + if(this->_nthreads > 1) { + for(index_t i = 0; i + 1 < (index_t)this->_nthreads; i++) { + tParams[i].last = true; + threads[i]->join(); + } + } + } + + fout5 << '\0'; + fout5.flush(); fout6.flush(); + if(fout5.fail() || fout6.fail()) { + cerr << "An error occurred writing the index to disk. Please check if the disk is full." << endl; + throw 1; + } + VMSG_NL("Returning from initFromVector"); + + // Close output files + fout5.flush(); + int64_t tellpSz5 = (int64_t)fout5.tellp(); + VMSG_NL("Wrote " << fout5.tellp() << " bytes to primary GFM file: " << _in5Str.c_str()); + fout5.close(); + bool err = false; + if(tellpSz5 > fileSize(_in5Str.c_str())) { + err = true; + cerr << "Index is corrupt: File size for " << _in5Str.c_str() << " should have been " << tellpSz5 + << " but is actually " << fileSize(_in5Str.c_str()) << "." << endl; + } + fout6.flush(); + int64_t tellpSz6 = (int64_t)fout6.tellp(); + VMSG_NL("Wrote " << fout6.tellp() << " bytes to secondary GFM file: " << _in6Str.c_str()); + fout6.close(); + if(tellpSz6 > fileSize(_in6Str.c_str())) { + err = true; + cerr << "Index is corrupt: File size for " << _in6Str.c_str() << " should have been " << tellpSz6 + << " but is actually " << fileSize(_in6Str.c_str()) << "." << endl; + } + if(err) { + cerr << "Please check if there is a problem with the disk or if disk is full." << endl; + throw 1; + } + // Reopen as input streams + VMSG_NL("Re-opening _in5 and _in5 as input streams"); + if(this->_sanity) { + VMSG_NL("Sanity-checking ht2"); + assert(!this->isInMemory()); + readIntoMemory( + fw ? -1 : needEntireReverse, // 1 -> need the reverse to be reverse-of-concat + true, // load SA sample (_offs[])? + true, // load ftab (_ftab[] & _eftab[])? + true, // load r-starts (_rstarts[])? + false, // just load header? + NULL, // Params object to fill + false, // mm sweep? + true, // load names? + false); // verbose startup? + sanityCheckAll(refparams.reverse); + evictFromMemory(); + assert(!this->isInMemory()); + } + VMSG_NL("Returning from HGFM constructor"); +} + + +/** + * Read an Ebwt from file with given filename. + */ +template +void HGFM::readIntoMemory( + int needEntireRev, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool justHeader, + GFMParams *params, + bool mmSweep, + bool loadNames, + bool startVerbose) +{ + PARENT_CLASS::readIntoMemory(needEntireRev, + loadSASamp, + loadFtab, + loadRstarts, + justHeader || needEntireRev == 1, + params, + mmSweep, + loadNames, + startVerbose); + + bool switchEndian; // dummy; caller doesn't care +#ifdef BOWTIE_MM + char *mmFile[] = { NULL, NULL }; +#endif + if(_in5Str.length() > 0) { + if(this->_verbose || startVerbose) { + cerr << " About to open input files: "; + logTime(cerr); + } + // Initialize our primary and secondary input-stream fields + if(_in5 != NULL) fclose(_in5); + if(this->_verbose || startVerbose) cerr << "Opening \"" << _in5Str.c_str() << "\"" << endl; + if((_in5 = fopen(_in5Str.c_str(), "rb")) == NULL) { + cerr << "Could not open index file " << _in5Str.c_str() << endl; + } + if(loadSASamp) { + if(_in6 != NULL) fclose(_in6); + if(this->_verbose || startVerbose) cerr << "Opening \"" << _in6Str.c_str() << "\"" << endl; + if((_in6 = fopen(_in6Str.c_str(), "rb")) == NULL) { + cerr << "Could not open index file " << _in6Str.c_str() << endl; + } + } + if(this->_verbose || startVerbose) { + cerr << " Finished opening input files: "; + logTime(cerr); + } + +#ifdef BOWTIE_MM + if(this->_useMm /*&& !justHeader*/) { + const char *names[] = {_in5Str.c_str(), _in6Str.c_str()}; + int fds[] = { fileno(_in5), fileno(_in6) }; + for(int i = 0; i < (loadSASamp ? 2 : 1); i++) { + if(this->_verbose || startVerbose) { + cerr << " ¯ " << (i+1) << ": "; + logTime(cerr); + } + struct stat sbuf; + if (stat(names[i], &sbuf) == -1) { + perror("stat"); + cerr << "Error: Could not stat index file " << names[i] << " prior to memory-mapping" << endl; + throw 1; + } + mmFile[i] = (char*)mmap((void *)0, (size_t)sbuf.st_size, + PROT_READ, MAP_SHARED, fds[(size_t)i], 0); + if(mmFile[i] == (void *)(-1)) { + perror("mmap"); + cerr << "Error: Could not memory-map the index file " << names[i] << endl; + throw 1; + } + if(mmSweep) { + int sum = 0; + for(off_t j = 0; j < sbuf.st_size; j += 1024) { + sum += (int) mmFile[i][j]; + } + if(startVerbose) { + cerr << " Swept the memory-mapped ebwt index file 1; checksum: " << sum << ": "; + logTime(cerr); + } + } + } + mmFile5_ = mmFile[0]; + mmFile6_ = loadSASamp ? mmFile[1] : NULL; + } +#endif + } +#ifdef BOWTIE_MM + else if(this->_useMm && !justHeader) { + mmFile[0] = mmFile5_; + mmFile[1] = mmFile6_; + } + if(this->_useMm && !justHeader) { + assert(mmFile[0] == mmFile5_); + assert(mmFile[1] == mmFile6_); + } +#endif + + if(this->_verbose || startVerbose) { + cerr << " Reading header: "; + logTime(cerr); + } + + // Read endianness hints from both streams + size_t bytesRead = 0, bytesRead2 = 4; + switchEndian = false; + uint32_t one = readU32(_in5, switchEndian); // 1st word of primary stream + bytesRead += 4; + if(loadSASamp) { +#ifndef NDEBUG + assert_eq(one, readU32(_in6, switchEndian)); // should match! +#else + readU32(_in6, switchEndian); +#endif + } + if(one != 1) { + assert_eq((1u<<24), one); + assert_eq(1, endianSwapU32(one)); + switchEndian = true; + } + + // Can't switch endianness and use memory-mapped files; in order to + // support this, someone has to modify the file to switch + // endiannesses appropriately, and we can't do this inside Bowtie + // or we might be setting up a race condition with other processes. + if(switchEndian && this->_useMm) { + cerr << "Error: Can't use memory-mapped files when the index is the opposite endianness" << endl; + throw 1; + } + + _nlocalGFMs = readIndex(_in5, switchEndian); bytesRead += sizeof(index_t); + int32_t lineRate = readI32(_in5, switchEndian); bytesRead += 4; + readI32(_in5, switchEndian); bytesRead += 4; + int32_t offRate = readI32(_in5, switchEndian); bytesRead += 4; + // TODO: add isaRate to the actual file format (right now, the + // user has to tell us whether there's an ISA sample and what the + // sampling rate is. + int32_t ftabChars = readI32(_in5, switchEndian); bytesRead += 4; + /*int32_t flag =*/ readI32(_in5, switchEndian); bytesRead += 4; + + if(this->_verbose || startVerbose) { + cerr << " number of local indexes: " << _nlocalGFMs << endl + << " local offRate: " << offRate << endl + << " local ftabLen: " << (1 << (2 * ftabChars)) << endl + << " local ftabSz: " << (2 << (2 * ftabChars)) << endl + ; + } + + clearLocalGFMs(); + + index_t tidx = 0, localOffset = 0, joinedOffset = 0; + string base = ""; + for(size_t i = 0; i < _nlocalGFMs; i++) { + LocalGFM *localGFM = new LocalGFM(base, + NULL, + _in5, + _in6, + mmFile5_, + mmFile6_, + tidx, + localOffset, + joinedOffset, + switchEndian, + bytesRead, + bytesRead2, + needEntireRev, + this->fw_, + -1, // overrideOffRate + -1, // offRatePlus + (uint32_t)lineRate, + (uint32_t)offRate, + (uint32_t)ftabChars, + this->_useMm, + this->useShmem_, + mmSweep, + loadNames, + loadSASamp, + loadFtab, + loadRstarts, + false, // _verbose + false, + this->_passMemExc, + this->_sanity, + false); // use haplotypes? + + if(tidx >= _localGFMs.size()) { + assert_eq(tidx, _localGFMs.size()); + _localGFMs.expand(); + } + assert_eq(tidx + 1, _localGFMs.size()); + _localGFMs.back().push_back(localGFM); + } + +#ifdef BOWTIE_MM + fseek(_in5, 0, SEEK_SET); + fseek(_in6, 0, SEEK_SET); +#else + rewind(_in5); rewind(_in6); +#endif +} + +#endif /*HGFM_H_*/ diff --git a/hi_aligner.h b/hi_aligner.h new file mode 100644 index 0000000..ef2c735 --- /dev/null +++ b/hi_aligner.h @@ -0,0 +1,7006 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * This file is edited by Yun (Leo) Zhang for HISAT-3N. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef HI_ALIGNER_H_ +#define HI_ALIGNER_H_ + +#include +#include +#include +#include "qual.h" +#include "ds.h" +#include "sstring.h" +#include "alphabet.h" +#include "edit.h" +#include "read.h" +// Threading is necessary to synchronize the classes that dump +// intermediate alignment results to files. Otherwise, all data herein +// is constant and shared, or per-thread. +#include "threading.h" +#include "aligner_result.h" +#include "aligner_cache.h" +#include "scoring.h" +#include "mem_ids.h" +#include "simple_func.h" +#include "aligner_driver.h" +#include "aligner_sw_driver.h" +#include "group_walk.h" +#include "tp.h" +#include "gp.h" + +// Allow longer introns for long anchored reads involving canonical splice sites +inline uint32_t MaxIntronLen(uint32_t anchor, uint32_t minAnchorLen) { + uint32_t intronLen = 0; + if(anchor >= minAnchorLen) { + if(anchor < 2) anchor = 2; + uint32_t shift = (anchor << 1) - 4; + shift = min(max(shift, 13), 30); + intronLen = 1 << shift; + } + return intronLen; +} + +inline float intronLen_prob(uint32_t anchor, uint32_t intronLen, uint32_t maxIntronLen) { + uint32_t expected_intron_len = maxIntronLen; + if(anchor < 14) expected_intron_len = 1 << ((anchor << 1) + 4); + if(expected_intron_len > maxIntronLen) expected_intron_len = maxIntronLen; + assert_gt(expected_intron_len, 0); + float result = ((float)intronLen) / ((float)expected_intron_len); + if(result > 1.0f) result = 1.0f; + return result; +} + +// Allow longer introns for long anchored reads involving non-canonical splice sites +inline uint32_t MaxIntronLen_noncan(uint32_t anchor, uint32_t minAnchorLen_noncan) { + uint32_t intronLen = 0; + if(anchor >= minAnchorLen_noncan) { + if(anchor < 5) anchor = 5; + uint32_t shift = (anchor << 1) - 10; + shift = min(shift, 30); + intronLen = 1 << shift; + } + return intronLen; +} + +inline float intronLen_prob_noncan(uint32_t anchor, uint32_t intronLen, uint32_t maxIntronLen) { + uint32_t expected_intron_len = maxIntronLen; + if(anchor < 16) expected_intron_len = 1 << (anchor << 1); + if(expected_intron_len > maxIntronLen) expected_intron_len = maxIntronLen; + assert_gt(expected_intron_len, 0); + float result = ((float)intronLen) / ((float)expected_intron_len); + if(result > 1.0f) result = 1.0f; + return result; +} + +/** + * Hit types for BWTHit class below + * Three hit types to anchor a read on the genome + * + */ +enum { + CANDIDATE_HIT = 1, + PSEUDOGENE_HIT, + ANCHOR_HIT, +}; + +/** + * Simple struct for holding a partial alignment for the read + * The alignment locations are represented by FM offsets [top, bot), + * and later genomic offsets are calculated when necessary + */ +template +struct BWTHit { + + BWTHit() { reset(); } + + void reset() { + _top = _bot = 0; + _node_top = _node_bot = 0; + _node_iedge_count.clear(); + _fw = true; + _bwoff = (index_t)INDEX_MAX; + _len = 0; + _coords.clear(); + _anchor_examined = false; + _hit_type = CANDIDATE_HIT; + } + + void init( + index_t top, + index_t bot, + index_t node_top, + index_t node_bot, + const EList >& node_iedge_count, + bool fw, + uint32_t bwoff, + uint32_t len, + index_t hit_type = CANDIDATE_HIT) + { + assert_leq(node_bot - node_top, bot - top); +#ifndef NDEBUG + if(node_bot - node_top < bot - top) { + assert_gt(node_iedge_count.size(), 0); + } +#endif + _top = top; + _bot = bot; + _node_top = node_top; + _node_bot = node_bot; + _node_iedge_count = node_iedge_count; + _fw = fw; + _bwoff = bwoff; + _len = len; + _coords.clear(); + _anchor_examined = false; + _hit_type = hit_type; + } + + bool hasGenomeCoords() const { return !_coords.empty(); } + + /** + * Return true iff there is no hit. + */ + bool empty() const { + return _bot <= _top; + } + + /** + * Higher score = higher priority. + */ + bool operator<(const BWTHit& o) const { + return _len > o._len; + } + + /** + * Return the size of the alignments SA ranges. + */ + index_t size() const { + assert_leq(_top, _bot); + return _bot - _top; + } + + index_t len() const { + assert_gt(_len, 0); + return _len; + } + +#ifndef NDEBUG + /** + * Check that hit is sane w/r/t read. + */ + bool repOk(const Read& rd) const { + assert_gt(_bot, _top); + assert_neq(_bwoff, (index_t)INDEX_MAX); + assert_gt(_len, 0); + return true; + } +#endif + + index_t _top; // start of the range in the FM index + index_t _bot; // end of the range in the FM index + index_t _node_top; + index_t _node_bot; + EList > _node_iedge_count; + bool _fw; // whether read is forward or reverse complemented + index_t _bwoff; // current base of a read to search from the right end + index_t _len; // read length + + EList _coords; // genomic offsets corresponding to [_top, _bot) + + bool _anchor_examined; // whether or not this hit is examined + index_t _hit_type; // hit type (anchor hit, pseudogene hit, or candidate hit) +}; + + +/** + * Simple struct for holding alignments for the read + * The alignments are represented by chains of BWTHits + */ +template +struct ReadBWTHit { + + ReadBWTHit() { reset(); } + + void reset() { + _fw = true; + _len = 0; + _cur = 0; + _done = false; + _numPartialSearch = 0; + _numUniqueSearch = 0; + _repeat = false; + _partialHits.clear(); + } + + void init( + bool fw, + index_t len) + { + _fw = fw; + assert_gt(len, 0); + _len = len; + _cur = 0; + _done = false; + _numPartialSearch = 0; + _numUniqueSearch = 0; + _repeat = false; + _partialHits.clear(); + } + + bool done() { +#ifndef NDEBUG + assert_gt(_len, 0); + if(_cur >= _len) { + assert(_done); + } +#endif + return _done; + } + + void done(bool done) { + assert(!_done); + assert(done); + _done = done; + } + + index_t len() const { return _len; } + index_t cur() const { return _cur; } + bool repeat() const { return _repeat; } + + index_t offsetSize() { return (index_t)_partialHits.size(); } + size_t numPartialSearch() { return _numPartialSearch; } + index_t numActualPartialSearch() + { + assert_leq(_numUniqueSearch, _numPartialSearch); + return (index_t)(_numPartialSearch - _numUniqueSearch); + } + + bool width(index_t offset_) { + assert_lt(offset_, _partialHits.size()); + return _partialHits[offset_].size(); + } + + bool hasGenomeCoords(index_t offset_) { + assert_lt(offset_, _partialHits.size()); + index_t width_ = width(offset_); + if(width_ == 0) { + return true; + } else { + return _partialHits[offset_].hasGenomeCoords(); + } + } + + bool hasAllGenomeCoords() { + if(_cur < _len) return false; + if(_partialHits.size() <= 0) return false; + for(size_t oi = 0; oi < _partialHits.size(); oi++) { + if(!_partialHits[oi].hasGenomeCoords()) + return false; + } + return true; + } + + /** + * + */ + index_t minWidth(index_t& offset) const { + index_t minWidth_ = (index_t)INDEX_MAX; + index_t minWidthLen_ = 0; + for(size_t oi = 0; oi < _partialHits.size(); oi++) { + const BWTHit& hit = _partialHits[oi]; + if(hit.empty()) continue; + // if(!hit.hasGenomeCoords()) continue; + assert_gt(hit.size(), 0); + if((minWidth_ > hit.size()) || + (minWidth_ == hit.size() && minWidthLen_ < hit.len())) { + minWidth_ = hit.size(); + minWidthLen_ = hit.len(); + offset = (index_t)oi; + } + } + return minWidth_; + } + + // add policy for calculating a search score + int64_t searchScore(index_t minK) { + int64_t score = 0; + const int64_t penaltyPerOffset = minK * minK; + for(size_t i = 0; i < _partialHits.size(); i++) { + index_t len = _partialHits[i]._len; + score += (len * len); + } + + assert_geq(_numPartialSearch, _partialHits.size()); + index_t actualPartialSearch = numActualPartialSearch(); + score -= (actualPartialSearch * penaltyPerOffset); + score -= (1 << (actualPartialSearch << 1)); + return score; + } + + BWTHit& getPartialHit(index_t offset_) { + assert_lt(offset_, _partialHits.size()); + return _partialHits[offset_]; + } + + bool adjustOffset(index_t minK) { + assert_gt(_partialHits.size(), 0); + const BWTHit& hit = _partialHits.back(); + if(hit.len() >= minK + 3) { + return false; + } + assert_geq(_cur, hit.len()); + index_t origCur = _cur - hit.len(); + _cur = origCur + max(hit.len(), minK + 1) - minK; + _partialHits.pop_back(); + return true; + } + + void setOffset(index_t offset) { + assert_lt(offset, _len); + _cur = offset; + } + +#ifndef NDEBUG + /** + */ + bool repOk() const { + for(size_t i = 0; i < _partialHits.size(); i++) { + if(i == 0) { + assert_geq(_partialHits[i]._bwoff, 0); + } + + if(i + 1 < _partialHits.size()) { + assert_leq(_partialHits[i]._bwoff + _partialHits[i]._len, _partialHits[i+1]._bwoff); + } else { + assert_eq(i+1, _partialHits.size()); + assert_eq(_partialHits[i]._bwoff + _partialHits[i]._len, _cur); + } + } + return true; + } +#endif + + bool _fw; + index_t _len; + index_t _cur; + bool _done; + index_t _numPartialSearch; + index_t _numUniqueSearch; + index_t _cur_local; + bool _repeat; + + EList > _partialHits; +}; + + +/** + * this is per-thread data, which are shared by GenomeHit classes + * the main purpose of this struct is to avoid extensive use of memory related functions + * such as new and delete - those are really slow and lock based + */ +template +struct SharedTempVars { + SStringExpandable raw_refbuf; + SStringExpandable raw_refbuf2; + EList temp_scores; + EList temp_scores2; + + // Align with alternatives + EList > ssOffs; + EList > offDiffs; + EList > raw_refbufs; + EList alt_edits; + ELList candidate_edits; + ELList > ht_llist; + Haplotype cmp_ht; + + ASSERT_ONLY(SStringExpandable destU32); + + ASSERT_ONLY(BTDnaString editstr); + ASSERT_ONLY(BTDnaString partialseq); + ASSERT_ONLY(BTDnaString refstr); + ASSERT_ONLY(EList reflens); + ASSERT_ONLY(EList refoffs); + + LinkedEList > raw_edits; + LinkedEList > > raw_ht_lists; +}; + +/** + * GenomeHit represents read alignment or alignment of a part of a read + * Two GenomeHits that represents alignments of different parts of a read + * can be combined together. Also, GenomeHit can be extended in both directions. + */ +template +struct GenomeHit { + GenomeHit() : + _fw(false), + _rdoff((index_t)INDEX_MAX), + _len((index_t)INDEX_MAX), + _trim5(0), + _trim3(0), + _tidx((index_t)INDEX_MAX), + _toff((index_t)INDEX_MAX), + _joinedOff((index_t)INDEX_MAX), + _repeat(false), + _edits(NULL), + _ht_list(NULL), + _score(MIN_I64), + _localscore(MIN_I64), + _hitcount(1), + _edits_node(NULL), + _ht_list_node(NULL), + _sharedVars(NULL) + { + } + + GenomeHit(const GenomeHit& otherHit) : + _edits(NULL), + _ht_list(NULL), + _hitcount(1), + _edits_node(NULL), + _ht_list_node(NULL), + _sharedVars(NULL) + { + init(otherHit._fw, + otherHit._rdoff, + otherHit._len, + otherHit._trim5, + otherHit._trim3, + otherHit._tidx, + otherHit._toff, + otherHit._joinedOff, + *(otherHit._sharedVars), + otherHit._repeat, + otherHit._edits, + otherHit._ht_list, + otherHit._score, + otherHit._localscore, + otherHit._splicescore); + } + + GenomeHit& operator=(const GenomeHit& otherHit) { + if(this == &otherHit) return *this; + init(otherHit._fw, + otherHit._rdoff, + otherHit._len, + otherHit._trim5, + otherHit._trim3, + otherHit._tidx, + otherHit._toff, + otherHit._joinedOff, + *(otherHit._sharedVars), + otherHit._repeat, + otherHit._edits, + otherHit._ht_list, + otherHit._score, + otherHit._localscore, + otherHit._splicescore); + + return *this; + } + + ~GenomeHit() { + if(_edits_node != NULL) { + assert(_edits != NULL); + assert(_sharedVars != NULL); + _sharedVars->raw_edits.delete_node(_edits_node); + _edits = NULL; + _edits_node = NULL; + } + if(_ht_list_node != NULL) { + assert(_ht_list != NULL); + assert(_sharedVars != NULL); + _sharedVars->raw_ht_lists.delete_node(_ht_list_node); + _ht_list = NULL; + _ht_list_node = NULL; + } + _sharedVars = NULL; + } + + void init( + bool fw, + index_t rdoff, + index_t len, + index_t trim5, + index_t trim3, + index_t tidx, + index_t toff, + index_t joinedOff, + SharedTempVars& sharedVars, + bool repeat = false, + EList* edits = NULL, + EList >* ht_list = NULL, + int64_t score = 0, + int64_t localscore = 0, + double splicescore = 0.0) + { + _fw = fw; + _rdoff = rdoff; + _len = len; + _trim5 = trim5; + _trim3 = trim3; + _tidx = tidx; + _toff = toff; + _joinedOff = joinedOff; + _repeat = repeat; + _score = score; + _localscore = localscore; + _splicescore = splicescore; + + assert(_sharedVars == NULL || _sharedVars == &sharedVars); + _sharedVars = &sharedVars; + if(_edits == NULL) { + assert(_edits_node == NULL); + _edits_node = _sharedVars->raw_edits.new_node(); + assert(_edits_node != NULL); + _edits = &(_edits_node->payload); + } + assert(_edits != NULL); + _edits->clear(); + if(edits != NULL) *_edits = *edits; + + if(_ht_list == NULL) { + assert(_ht_list_node == NULL); + _ht_list_node = _sharedVars->raw_ht_lists.new_node(); + assert(_ht_list_node != NULL); + _ht_list = &(_ht_list_node->payload); + } + assert(_ht_list != NULL); + _ht_list->clear(); + if(ht_list != NULL) *_ht_list = *ht_list; + + _hitcount = 1; + } + + + bool inited() const { + return _len >= 0 && _len < (index_t)INDEX_MAX; + } + + /** + * Check if it is compatible with another GenomeHit with respect to indels or introns + */ + bool compatibleWith( + const GenomeHit& otherHit, + index_t minIntronLen, + index_t maxIntronLen, + bool no_spliced_alignment = false) const; + + /** + * Combine itself with another GenomeHit + */ + bool combineWith( + const GenomeHit& otherHit, + const Read& rd, + const GFM& gfm, + const BitPairReference& ref, + const ALTDB& altdb, + const RepeatDB& repeatdb, + SpliceSiteDB& ssdb, + SwAligner& swa, + SwMetrics& swm, + const Scoring& sc, + TAlScore minsc, + RandomSource& rnd, // pseudo-random source + index_t minK_local, + index_t minIntronLen, + index_t maxIntronLen, + index_t minAnchorLen, // minimum anchor length for canonical splice site + index_t minAnchorLen_noncan, // minimum anchor length for non-canonical splice site + const index_t maxAltsTried, + const SpliceSite* spliceSite = NULL, // penalty for splice site + bool no_spliced_alignment = false); + + /** + * Extend the partial alignment (GenomeHit) bidirectionally + */ + bool extend( + const Read& rd, + const GFM& gfm, + const BitPairReference& ref, + const ALTDB& altdb, + const RepeatDB& repeatdb, + SpliceSiteDB& ssdb, + SwAligner& swa, + SwMetrics& swm, + PerReadMetrics& prm, + const Scoring& sc, + TAlScore minsc, + RandomSource& rnd, // pseudo-random source + index_t minK_local, + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + index_t& leftext, + index_t& rightext, + index_t mm = 0); + + /** + * Adjust alignment with respect to SNPs, usually updating Edits + * + */ + static bool adjustWithALT( + index_t rdoff, + index_t len, + const Coord& coord, + SharedTempVars& sharedVars, + EList >& genomeHits, + const Read& rd, + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + const GraphPolicy& gpol); + + /** + * Adjust alignment with respect to SNPs, usually updating Edits + * + */ + bool adjustWithALT( + const Read& rd, + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + const GraphPolicy& gpol); + + /* + * + */ + static void findSSOffs( + const GFM& gfm, + const ALTDB& altdb, + index_t start, + index_t end, + EList >& ssOffs); + + /* + * Find offset differences due to deletions + */ + static index_t findOffDiffs( + const GFM& gfm, + const ALTDB& altdb, + index_t start, + index_t end, + EList >& offDiffs); + + /* + * + */ + static index_t alignWithALTs( + const EList >& alts, + const EList >& haplotypes, + const EList& haplotype_maxrights, + index_t joinedOff, + const BTDnaString& rdseq, + index_t base_rdoff, + index_t rdoff, + index_t rdlen, + const BitPairReference& ref, + SharedTempVars& sharedVar, + index_t tidx, + int rfoff, + index_t rflen, + bool left, + const GraphPolicy& gpol, + EList& edits, + ELList >& ht_llist, + EList >& ht_list, + Haplotype& cmp_ht, + int cycle_3N, + ELList* candidate_edits = NULL, + index_t mm = 0, + index_t* numNs = NULL) + { + int best_rdoff = (int)rdoff; + if(numNs != NULL) *numNs = 0; + index_t numALTsTried = 0; + EList& alt_edits = sharedVar.alt_edits; + alt_edits = edits; + index_t nedits = (index_t)edits.size(); + if(candidate_edits != NULL) candidate_edits->clear(); + ht_llist.clear(); + // ht_llist.expand(); + // ht_llist[0] = ht_list; + alignWithALTs_recur( + alts, + haplotypes, + haplotype_maxrights, + joinedOff, + rdseq, + rdoff - base_rdoff, + rdoff, + rdlen, + ref, + sharedVar.raw_refbufs, + ASSERT_ONLY(sharedVar.destU32,) + alt_edits, + best_rdoff, + NULL, /* rfseq */ + tidx, + rfoff, + rflen, + left, + edits, + mm, + ht_llist, + cmp_ht, + candidate_edits, + 0, /* tmp_numNs */ + numNs, + 0, /* dep */ + gpol, + numALTsTried, + cycle_3N); + index_t extlen = 0; + if(left) { + assert_geq(best_rdoff, -1); + assert_leq(best_rdoff, (int)rdoff); + extlen = rdoff - best_rdoff; + } else { + assert_leq(best_rdoff, (int)(rdoff + rdlen)); + assert_geq(best_rdoff, (int)rdoff); + extlen = best_rdoff - rdoff; + } + if(extlen > 0 && edits.size() > 0) { + const Edit& f = edits.front(); + if(f.pos + extlen == base_rdoff + 1) { + if(f.type == EDIT_TYPE_READ_GAP || + f.type == EDIT_TYPE_REF_GAP || + f.type == EDIT_TYPE_SPL) { + extlen = 0; + } + if(f.type == EDIT_TYPE_MM && f.chr == 'N') { + extlen = 0; + } + } + const Edit& b = edits.back(); + if(extlen > 0 && b.pos == rdoff - base_rdoff + extlen - 1) { + if(b.type == EDIT_TYPE_READ_GAP || + b.type == EDIT_TYPE_REF_GAP) { + extlen = 0; + } + } + if(extlen == 0 && edits.size() > nedits) { + if(left) { + edits.erase(0, edits.size() - nedits); + } else { + edits.resize(nedits); + } + } + } + return extlen; + } + + /* + * + */ + static index_t alignWithALTs_recur( + const EList >& alts, + const EList >& haplotypes, + const EList& haplotype_maxrights, + index_t joinedOff, + const BTDnaString& rdseq, + index_t rdoff_add, + index_t rdoff, + index_t rdlen, + const BitPairReference& ref, + EList >& raw_refbufs, + ASSERT_ONLY(SStringExpandable destU32,) + EList& tmp_edits, + int& best_rdoff, + const char* rfseq, + index_t tidx, + int rfoff, + index_t rflen, + bool left, + EList& edits, + index_t mm, + ELList >& ht_llist, + Haplotype& cmp_ht, + ELList* candidate_edits, + index_t tmp_numNs, + index_t* numNs, + index_t dep, + const GraphPolicy& gpol, + index_t& numALTsTried, + int cycle_3N, + ALT_TYPE prev_alt_type = ALT_NONE); + + /** + * For alignment involving indel, move the indels + * to the left most possible position + */ + void leftAlign(const Read& rd); + + index_t rdoff() const { return _rdoff; } + index_t len() const { return _len; } + index_t trim5() const { return _trim5; } + index_t trim3() const { return _trim3; } + + void trim5(index_t trim5, + const Read& rd, + SpliceSiteDB& ssdb, + const Scoring& sc, + index_t minK_local, + index_t minIntronLen, + index_t maxIntronLen, + index_t minAnchorLen, + index_t minAnchorLen_noncan, + const BitPairReference& ref) + { + assert_eq(_rdoff, trim5); + assert_eq(_trim5, 0); + _trim5 = trim5; + calculateScore(rd, + ssdb, + sc, + minK_local, + minIntronLen, + maxIntronLen, + minAnchorLen, + minAnchorLen_noncan, + ref); + } + void trim3(index_t trim3, + const Read& rd, + SpliceSiteDB& ssdb, + const Scoring& sc, + index_t minK_local, + index_t minIntronLen, + index_t maxIntronLen, + index_t minAnchorLen, + index_t minAnchorLen_noncan, + const BitPairReference& ref) + { + _trim3 = trim3; + calculateScore(rd, + ssdb, + sc, + minK_local, + minIntronLen, + maxIntronLen, + minAnchorLen, + minAnchorLen_noncan, + ref); + } + + // for repeat alignments + // reverse fw + void reverse(const Read& rd) + { + _fw = !_fw; + index_t end = _trim5 + _rdoff + _len; + assert_leq(end, rd.length()); + _rdoff = rd.length() - end; + index_t tmp_trim = _trim5; + _trim5 = _trim3; + _trim3 = tmp_trim; + Edit::invertPoss(*_edits, rd.length()); + // complements + Edit::complement(*_edits); + } + + index_t ref() const { return _tidx; } + index_t refoff() const { return _toff; } + index_t fw() const { return _fw; } + + bool repeat() const { return _repeat; } + void repeat(bool repeat) { _repeat = repeat;} + + index_t hitcount() const { return _hitcount; } + + /** + * Leftmost coordinate + */ + Coord coord() const { + return Coord(_tidx, _toff, _fw); + } + + int64_t score() const { return _score; } + int64_t localscore() const { return _localscore; } + double splicescore() const { return _splicescore; } + + const EList& edits() const { return *_edits; } + + /** + * Retrieve the partial alignment from the left until indel or intron + */ + void getLeft(index_t& rdoff, + index_t& len, + index_t& toff, + int64_t* score = NULL, + const Read* rd = NULL, + const Scoring* sc = NULL) const + { + assert(inited()); + toff = _toff, rdoff = _rdoff, len = _len; + const BTString* qual = NULL; + if(score != NULL) { + assert(rd != NULL); + assert(sc != NULL); + *score = 0; + qual = &(_fw ? rd->qual : rd->qualRev); + } + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& edit = (*_edits)[i]; + if(edit.type == EDIT_TYPE_SPL || + edit.type == EDIT_TYPE_READ_GAP || + edit.type == EDIT_TYPE_REF_GAP || + (edit.type == EDIT_TYPE_MM && edit.snpID != (index_t)INDEX_MAX)) { + len = edit.pos; + break; + } + if(score != NULL) { + if(edit.type == EDIT_TYPE_MM) { + assert(qual != NULL); + if(edit.snpID == (index_t)INDEX_MAX) { + *score += sc->score( + dna2col[edit.qchr] - '0', + asc2dnamask[edit.chr], + (*qual)[this->_rdoff + edit.pos] - 33); + } + } + } + } + assert_geq(len, 0); + } + + /** + * Retrieve the partial alignment from the right until indel or intron + */ + void getRight(index_t& rdoff, + index_t& len, + index_t& toff, + int64_t* score = NULL, + const Read* rd = NULL, + const Scoring* sc = NULL) const + { + assert(inited()); + toff = _toff, rdoff = _rdoff, len = _len; + const BTString* qual = NULL; + if(score != NULL) { + assert(rd != NULL); + assert(sc != NULL); + *score = 0; + qual = &(_fw ? rd->qual : rd->qualRev); + } + if(_edits->size() == 0) return; + for(int i = (int)_edits->size() - 1; i >= 0; i--) { + const Edit& edit = (*_edits)[i]; + if(edit.type == EDIT_TYPE_SPL || + edit.type == EDIT_TYPE_READ_GAP || + edit.type == EDIT_TYPE_REF_GAP || + (edit.type == EDIT_TYPE_MM && edit.snpID != (index_t)INDEX_MAX)) { + rdoff = _rdoff + edit.pos; + assert_lt(edit.pos, _len); + len = _len - edit.pos; + if(edit.type == EDIT_TYPE_REF_GAP) { + assert_lt(edit.pos + 1, _len); + assert_gt(len, 1); + rdoff++; + len--; + } else if(edit.type == EDIT_TYPE_MM) { + assert_leq(edit.pos + 1, _len); + assert_geq(len, 1); + rdoff++; + len--; + } + toff = getRightOff() - len; + break; + } + if(score != NULL) { + if(edit.type == EDIT_TYPE_MM) { + assert(qual != NULL); + if(edit.snpID == (index_t)INDEX_MAX) { + *score += sc->score( + dna2col[edit.qchr] - '0', + asc2dnamask[edit.chr], + (*qual)[this->_rdoff + edit.pos] - 33); + } + } + } + } + assert_geq(len, 0); + } + + /** + * Retrieve the genomic offset of the right end + */ + index_t getRightOff() const { + assert(inited()); + index_t toff = _toff + _len; + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& ed = (*_edits)[i]; + if(ed.type == EDIT_TYPE_SPL) { + toff += ed.splLen; + } else if(ed.type == EDIT_TYPE_READ_GAP) { + toff++; + } else if(ed.type == EDIT_TYPE_REF_GAP) { + assert_gt(toff, 0); + toff--; + } + } + return toff; + } + + /** + * Retrieve left anchor length and number of edits in the anchor + */ + void getLeftAnchor(index_t& leftanchor, + index_t& nedits) const + { + assert(inited()); + leftanchor = _len; + nedits = 0; + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& edit = (*_edits)[i]; + if(edit.type == EDIT_TYPE_SPL) { + leftanchor = edit.pos; + break; + } else if(edit.type == EDIT_TYPE_MM || + edit.type == EDIT_TYPE_READ_GAP || + edit.type == EDIT_TYPE_REF_GAP) { + nedits++; + } + } + } + + /** + * Retrieve right anchor length and number of edits in the anchor + */ + void getRightAnchor(index_t& rightanchor, + index_t& nedits) const + { + rightanchor = _len; + nedits = 0; + if(_edits->size() == 0) return; + for(int i = (int)_edits->size() - 1; i >= 0; i--) { + const Edit& edit = (*_edits)[i]; + if(edit.type == EDIT_TYPE_SPL) { + rightanchor = _len - edit.pos - 1; + break; + } else if(edit.type == EDIT_TYPE_MM || + edit.type == EDIT_TYPE_READ_GAP || + edit.type == EDIT_TYPE_REF_GAP) { + nedits++; + } + } + } + + + /** + * Is it spliced alignment? + * Return: first is spliced-alignment, second is spliced-alignment to known transcripts + */ + pair spliced() const { + pair result(false, true); + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& e = (*_edits)[i]; + if(e.type == EDIT_TYPE_SPL) { + result.first = true; + result.second &= e.knownSpl; + } + } + result.second &= result.first; + return result; + } + + /** + * + */ + bool spliced_consistently() const { + int splDir = SPL_UNKNOWN; + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& edit = (*_edits)[i]; + if(edit.type != EDIT_TYPE_SPL) continue; + if(splDir != SPL_UNKNOWN) { + if(edit.splDir != SPL_UNKNOWN) { + if(splDir == SPL_FW || splDir == SPL_SEMI_FW) { + if(edit.splDir != SPL_FW && edit.splDir != SPL_SEMI_FW) + return false; + } + if(splDir == SPL_RC || splDir == SPL_SEMI_RC) { + if(edit.splDir != SPL_RC && edit.splDir != SPL_SEMI_RC) + return false; + } + } + } else { + splDir = edit.splDir; + } + } + return true; + } + + /** + * return one of EDIT_SPL_FW, EDIT_SPL_RC, EDIT_SPL_UNKNOWN + */ + int splicing_dir() const { + int splDir = SPL_UNKNOWN; + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& edit = (*_edits)[i]; + if(edit.type != EDIT_TYPE_SPL) continue; + if(splDir != SPL_UNKNOWN) { + if(edit.splDir != SPL_UNKNOWN) { + if(splDir == SPL_FW || splDir == SPL_SEMI_FW) { + if(edit.splDir != SPL_FW && edit.splDir != SPL_SEMI_FW) + return SPL_UNKNOWN; + } + if(splDir == SPL_RC || splDir == SPL_SEMI_RC) { + if(edit.splDir != SPL_RC && edit.splDir != SPL_SEMI_RC) + return SPL_UNKNOWN; + } + } + } else { + splDir = edit.splDir; + } + } + if(splDir == SPL_FW || splDir == SPL_SEMI_FW) + return SPL_FW; + else if(splDir == SPL_RC || splDir == SPL_SEMI_RC) + return SPL_RC; + else + return SPL_UNKNOWN; + } + + bool operator== (const GenomeHit& other) const { + if(_fw != other._fw || + _rdoff != other._rdoff || + _len != other._len || + _tidx != other._tidx || + _toff != other._toff || + _trim5 != other._trim5 || + _trim3 != other._trim3) { + return false; + } + if(_edits->size() != other._edits->size()) return false; + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& e = (*_edits)[i]; + const Edit& oe = (*other._edits)[i]; + if(e.isReadGap()) { + if(!oe.isReadGap()) return false; + } else if(e.isRefGap()) { + if(!oe.isRefGap()) return false; + } else { + if(!(e == oe)) { + return false; + } + } + } + // daehwan - this may not be true when some splice sites are provided from outside + // assert_eq(_score, other._score); + return true; + } + + bool contains(const GenomeHit& other) const { + return (*this) == other; + } + + /** + * Return number of mismatches in the alignment. + */ + int mms() const { +#if 0 + if (_e2.inited()) return 2; + else if(_e1.inited()) return 1; + else return 0; +#endif + return 0; + } + + /** + * Return the number of Ns involved in the alignment. + */ + int ns() const { +#if 0 + int ns = 0; + if(_e1.inited() && _e1.hasN()) { + ns++; + if(_e2.inited() && _e2.hasN()) { + ns++; + } + } + return ns; +#endif + return 0; + } + + int ngaps() const { + return 0; + } + +#ifndef NDEBUG + /** + * Check that hit is sane w/r/t read. + */ + bool repOk(const Read& rd, const BitPairReference& ref); +#endif + + void replace_edits_with_alts(const Read& rd, + const EList >& alts, + SpliceSiteDB& ssdb, + const Scoring& sc, + index_t minK_local, + index_t minIntronLen, + index_t maxIntronLen, + index_t minAnchorLen, + index_t minAnchorLen_noncan, + const BitPairReference& ref) { + assert(inited()); + if(alts.size() <= 0) + return; + if(_edits->size() <= 0) + return; + + index_t joinedOff = _joinedOff; + int offset = 0; + size_t i = 0, next_i; + while(i < _edits->size()) { + next_i = i + 1; + Edit& ed = (*_edits)[i]; + if(ed.type == EDIT_TYPE_SPL) { + assert(false); + } else if(ed.type == EDIT_TYPE_READ_GAP || ed.type == EDIT_TYPE_REF_GAP) { + for(; next_i < _edits->size(); next_i++) { + Edit& next_ed = (*_edits)[next_i]; + if(ed.type != next_ed.type) break; + } + } + + if(ed.snpID == (index_t)INDEX_MAX) { + ALT cmp_alt; + cmp_alt.pos = joinedOff + ed.pos + offset; + index_t alt_i = (index_t)alts.bsearchLoBound(cmp_alt); + for(; alt_i < alts.size(); alt_i++) { + const ALT& alt = alts[alt_i]; + if(alt.left > cmp_alt.pos) break; + if(ed.type == EDIT_TYPE_MM) { + if(alt.type != ALT_SNP_SGL) continue; + if("ACGT"[alt.seq] == ed.qchr) { + ed.snpID = alt_i; + break; + } + } else { + size_t gap = next_i - i; + if(ed.type == EDIT_TYPE_READ_GAP) { + if(alt.type != ALT_SNP_DEL) continue; + if(alt.len == gap) { + for(size_t ii = i; ii < next_i; ii++) { + Edit& ii_ed = (*_edits)[ii]; + ii_ed.snpID = alt_i; + } + break; + } + } else { + assert_eq(ed.type, EDIT_TYPE_REF_GAP); + if(alt.type != ALT_SNP_INS) continue; + if(alt.len == gap) { + uint64_t seq = 0; + for(size_t ii = i; ii < next_i; ii++) { + Edit& ii_ed = (*_edits)[ii]; + seq = (seq << 2) | asc2dna[ii_ed.qchr]; + } + if(alt.seq == seq) { + for(size_t ii = i; ii < next_i; ii++) { + Edit& ii_ed = (*_edits)[ii]; + ii_ed.snpID = alt_i; + } + break; + } + } + } + } + } + } + + if(ed.type == EDIT_TYPE_SPL) { + offset += ed.splLen; + } else if(ed.type == EDIT_TYPE_READ_GAP || ed.type == EDIT_TYPE_REF_GAP) { + size_t gap = next_i - i; + if(ed.type == EDIT_TYPE_READ_GAP) { + assert_gt(joinedOff, gap); + offset += gap; + } else { + offset -= gap; + } + } + + i = next_i; + } + + calculateScore(rd, + ssdb, + sc, + minK_local, + minIntronLen, + maxIntronLen, + minAnchorLen, + minAnchorLen_noncan, + ref); + } + +private: + /** + * Calculate alignment score + */ + int64_t calculateScore( + const Read& rd, + SpliceSiteDB& ssdb, + const Scoring& sc, + index_t minK_local, + index_t minIntronLen, + index_t maxIntronLen, + index_t minAnchorLen, + index_t minAnchorLen_noncan, + const BitPairReference& ref); + +public: + bool _fw; + index_t _rdoff; + index_t _len; + index_t _trim5; + index_t _trim3; + + index_t _tidx; + index_t _toff; + index_t _joinedOff; + bool _repeat; + EList* _edits; + EList >* _ht_list; + int64_t _score; + int64_t _localscore; + double _splicescore; + + index_t _hitcount; // for selection purposes + + LinkedEListNode >* _edits_node; + LinkedEListNode > >* _ht_list_node; + SharedTempVars* _sharedVars; +}; + +/** + * Check if it is compatible with another GenomeHit with respect to indels or introns + */ +template +bool GenomeHit::compatibleWith( + const GenomeHit& otherHit, + index_t minIntronLen, + index_t maxIntronLen, + bool no_spliced_alignment) const +{ + if(this == &otherHit) return false; + // check if they are on the same strand and on the same contig + if(_fw != otherHit._fw || _tidx != otherHit._tidx) return false; + // make sure itself is closer to the left end of read than otherHit + if(_rdoff > otherHit._rdoff) return false; + // do not consider a case itself (read portion) includes otherHit + if(_rdoff + _len > otherHit._rdoff + otherHit._len) return false; + // make sure itself comes before otherHit wrt. genomic positions + if(_toff > otherHit._toff) return false; + + index_t this_rdoff, this_len, this_toff; + this->getRight(this_rdoff, this_len, this_toff); + assert_geq(this_len, 0); + index_t other_rdoff, other_len, other_toff; + otherHit.getLeft(other_rdoff, other_len, other_toff); + assert_geq(other_len, 0); + + if(this_rdoff > other_rdoff) return false; + if(this_rdoff + this_len > other_rdoff + other_len) return false; + if(this_toff > other_toff) return false; + + index_t refdif = other_toff - this_toff; + index_t rddif = other_rdoff - this_rdoff; + + // check if there is a deletion, an insertion, or a potential intron + // between the two partial alignments + if(!no_spliced_alignment) { + if(refdif > rddif + maxIntronLen) { + return false; + } + } + return true; +} + +static inline char get_ref_base(int threeN, int* mapping, char base) +{ + return threeN ? mapping[base] : base; +} + +/** + * Combine itself with another GenomeHit + * while allowing mismatches, an insertion, a deletion, or an intron + */ +template +bool GenomeHit::combineWith( + const GenomeHit& otherHit, + const Read& rd, + const GFM& gfm, + const BitPairReference& ref, + const ALTDB& altdb, + const RepeatDB& repeatdb, + SpliceSiteDB& ssdb, + SwAligner& swa, + SwMetrics& swm, + const Scoring& sc, + TAlScore minsc, + RandomSource& rnd, // pseudo-random source + index_t minK_local, + index_t minIntronLen, + index_t maxIntronLen, + index_t minAnchorLen, // minimum anchor length for canonical splice site + index_t minAnchorLen_noncan, // minimum anchor length for non-canonical splice site + const index_t maxAltsTried, + const SpliceSite* spliceSite, // penalty for splice site + bool no_spliced_alignment) +{ + if(this == &otherHit) return false; + assert(compatibleWith(otherHit, minIntronLen, maxIntronLen, no_spliced_alignment)); + assert_eq(this->_tidx, otherHit._tidx); + assert_lt(this->_tidx, ref.numRefs()); + + // get the partial part of the alignment from the right + // until an indel or splice sites + index_t this_rdoff, this_len, this_toff; + int64_t this_score; + this->getRight(this_rdoff, this_len, this_toff, &this_score, &rd, &sc); + assert_geq(this_len, 0); + assert_leq(this_score, 0); + assert_geq(this_score, this->_score); + + // get the partial part of the other alignment from the left + // until an indel or splice sites + index_t other_rdoff, other_len, other_toff; + int64_t other_score; + otherHit.getLeft(other_rdoff, other_len, other_toff, &other_score, &rd, &sc); + assert_geq(other_len, 0); + assert_leq(other_score, 0); + assert_geq(other_score, otherHit._score); + + assert_leq(this_rdoff, other_rdoff); + if(this_len != 0 && + other_len != 0 && + this_rdoff + this_len > other_rdoff + other_len) return false; + assert_leq(this_rdoff + this_len, other_rdoff + other_len); + index_t len = other_rdoff - this_rdoff + other_len; + const index_t reflen = ref.approxLen(_tidx); + if(this_toff + len > reflen) return false; + assert_leq(this_toff + len, reflen); + + // check if an indel or an intron is necessary + index_t refdif = other_toff - this_toff; + index_t rddif = other_rdoff - this_rdoff; + bool spliced = false, ins = false, del = false; + if(refdif != rddif) { + if(refdif > rddif) { + if(!no_spliced_alignment && refdif - rddif >= minIntronLen) { + assert_leq(refdif - rddif, maxIntronLen); + spliced = true; + } else { + del = true; + } + } else { + ins = true; + } + } +#ifndef NDEBUG + if(ins) { + assert(!spliced && !del); + } else { + if(spliced) assert(!del); + else assert(!spliced); + } +#endif + + if(no_spliced_alignment) { + if(spliced) return false; + } + + // if the combination of the two alignments does not involve an indel or an intron, + // then simply combine them and return + if(!spliced && !ins && !del && this_rdoff + this_len == other_rdoff) { + index_t addoff = otherHit._rdoff - this->_rdoff; + for(index_t i = 0; i < otherHit._edits->size(); i++) { + _edits->push_back((*otherHit._edits)[i]); + _edits->back().pos += addoff; + } + _len += otherHit._len; + calculateScore( + rd, + ssdb, + sc, + minK_local, + minIntronLen, + maxIntronLen, + minAnchorLen, + minAnchorLen_noncan, + ref); + assert(repOk(rd, ref)); + return true; + } + + // calculate the maximum gap lengths based on the current score and the mimumimu alignment score to be reported + const BTDnaString& seq = this->_fw ? rd.patFw : rd.patRc; + const BTString& qual = this->_fw ? rd.qual : rd.qualRev; + index_t rdlen = (index_t)seq.length(); + int64_t remainsc = minsc - (_score - this_score) - (otherHit._score - other_score); + if(remainsc > 0) remainsc = 0; + int read_gaps = 0, ref_gaps = 0; + if(!spliced) { + read_gaps = sc.maxReadGaps(remainsc + sc.canSpl(), rdlen); + ref_gaps = sc.maxRefGaps(remainsc + sc.canSpl(), rdlen); + } + if(ins) { + if(refdif + ref_gaps < rddif) { + return false; + } + } else if(del) { + if(rddif + read_gaps < refdif) { + return false; + } + } + int this_ref_ext = read_gaps; + if(spliced) this_ref_ext += (int)intronic_len; + if(this_toff + len > reflen) return false; + if(this_toff + len + this_ref_ext > reflen) this_ref_ext = reflen - (this_toff + len); + assert(_sharedVars != NULL); + SStringExpandable& raw_refbuf = _sharedVars->raw_refbuf; + EList& temp_scores = _sharedVars->temp_scores; + EList& temp_scores2 = _sharedVars->temp_scores2; + ASSERT_ONLY(SStringExpandable& destU32 = _sharedVars->destU32); + raw_refbuf.resize(len + this_ref_ext + 16); + int off = ref.getStretch( + reinterpret_cast(raw_refbuf.wbuf()), + (size_t)this->_tidx, + (size_t)this_toff, + len + this_ref_ext + ASSERT_ONLY(, destU32)); + assert_lt(off, 16); + char *refbuf = raw_refbuf.wbuf() + off, *refbuf2 = NULL; + + // discover a splice site, an insertion, or a deletion + index_t maxscorei = (index_t)INDEX_MAX; + int64_t maxscore = MIN_I64; + uint32_t maxspldir = SPL_UNKNOWN; + float maxsplscore = 0.0f; + // allow an indel near a splice site + index_t splice_gap_maxscorei = (index_t)INDEX_MAX; + int64_t donor_seq = 0, acceptor_seq = 0; + int splice_gap_off = 0; + + int refConversion_3N[5] = {0, 1, 2, 3, 4}; + if (threeN){ + if (((rd.threeN_cycle == threeN_type1conversion_FW || rd.threeN_cycle == threeN_type2conversion_RC) && !rd.oppositeConversion_3N) || + ((rd.threeN_cycle == threeN_type1conversion_RC || rd.threeN_cycle == threeN_type2conversion_FW) && rd.oppositeConversion_3N)) { + // type 1 conversion + refConversion_3N[asc2dna[hs3N_convertedFrom]] = asc2dna[hs3N_convertedTo]; + } else { + // type 2 conversion + refConversion_3N[asc2dna[hs3N_convertedFromComplement]] = asc2dna[hs3N_convertedToComplement]; + } + } + + if(spliced || ins || del) { + int other_ref_ext = min(read_gaps + (int)intronic_len, other_toff + other_len - len); + SStringExpandable& raw_refbuf2 = _sharedVars->raw_refbuf2; + raw_refbuf2.resize(len + other_ref_ext + 16); + int off2 = ref.getStretch( + reinterpret_cast(raw_refbuf2.wbuf()), + (size_t)otherHit._tidx, + (size_t)(other_toff + other_len - len - other_ref_ext), + len + other_ref_ext + ASSERT_ONLY(, destU32)); + refbuf2 = raw_refbuf2.wbuf() + off2 + other_ref_ext; + temp_scores.resize(len); + temp_scores2.resize(len); + if(spliced) { + static const char GT = 0x23, AG = 0x02; + static const char GTrc = 0x01, AGrc = 0x13; + static const char GC = 0x21, GCrc = 0x21; + static const char AT = 0x03, AC = 0x01; + static const char ATrc = 0x03, ACrc = 0x20; + static const char AA = 0x00, AArc = 0x33; + int i; + for(i = 0; i < (int)len; i++) { + int rdc = seq[this_rdoff + i], rfc = get_ref_base(threeN, refConversion_3N, refbuf[i]); + if(i > 0) { + temp_scores[i] = temp_scores[i-1]; + } else { + temp_scores[i] = 0; + } + if(rdc != rfc) { + temp_scores[i] += sc.score(rdc, 1 << rfc, qual[this_rdoff + i] - 33); + } + if(temp_scores[i] < remainsc) { + break; + } + } + int i_limit = min(i, len); + int i2; + for(i2 = len - 1; i2 >= 0; i2--) { + int rdc = seq[this_rdoff + i2], rfc = get_ref_base(threeN, refConversion_3N, refbuf2[i2]); + if((index_t)(i2 + 1) < len) { + temp_scores2[i2] = temp_scores2[i2+1]; + } else { + temp_scores2[i2] = 0; + } + if(rdc != rfc) { + temp_scores2[i2] += sc.score(rdc, 1 << rfc, qual[this_rdoff + i2] - 33); + } + if(temp_scores2[i2] < remainsc) { + break; + } + } + int i2_limit = max(i2, 0); + if(spliceSite != NULL){ + assert_leq(this_toff, (int)spliceSite->left()); + if(i2_limit <= (int)(spliceSite->left() - this_toff)) { + i2_limit = (int)(spliceSite->left() - this_toff); + i_limit = i2_limit + 1; + } else { + i_limit = i2_limit; + } + } + for(i = i2_limit, i2 = i2_limit + 1; + i < i_limit && i2 < (int)len; + i++, i2++) { + int64_t tempscore = temp_scores[i] + temp_scores2[i2]; + char donor = 0xff, acceptor = 0xff; + if((index_t)(i + 2) < len + this_ref_ext) { + donor = refbuf[i + 1]; + donor = (donor << 4) | refbuf[i + 2]; + } + if(i2 - 2 >= -other_ref_ext) { + acceptor = refbuf2[i2 - 2]; + acceptor = (acceptor << 4) | refbuf2[i2 - 1]; + } + bool canonical = false, semi_canonical = false; + uint32_t spldir = SPL_UNKNOWN; + if((donor == GT && acceptor == AG) /* || (donor == AT && acceptor == AC) */) { + spldir = SPL_FW; + canonical = true; + } else if((donor == AGrc && acceptor == GTrc) /* || (donor == ACrc && acceptor == ATrc) */) { + spldir = SPL_RC; + canonical = true; + } else if((donor == GC && acceptor == AG) || (donor == AT && acceptor == AC)) { + spldir = SPL_SEMI_FW; + semi_canonical = true; + } else if((donor == AGrc && acceptor == GCrc) || (donor == ACrc && acceptor == ATrc)) { + spldir = SPL_SEMI_RC; + semi_canonical = true; + } + tempscore -= (canonical ? sc.canSpl() : sc.noncanSpl()); + int64_t temp_donor_seq = 0, temp_acceptor_seq = 0; + float splscore = 0.0f; + if(canonical) { + // in case of canonical splice site, extract donor side sequence and acceptor side sequence + // to calculate a score of the splicing event. + if(spldir == SPL_FW) { + if(i + 1 >= (int)donor_exonic_len && + (int)(len + this_ref_ext) > i + (int)donor_intronic_len && + i2 + (int)other_ref_ext >= (int)acceptor_intronic_len && + (int)len > i2 + (int)acceptor_exonic_len - 1) { + int from = i + 1 - (int)donor_exonic_len; + int to = i + (int)donor_intronic_len; + for(int j = from; j <= to; j++) { + assert_geq(j, 0); + assert_lt(j, (int)(len + this_ref_ext)); + int base = refbuf[j]; + if(base > 3) base = 0; + temp_donor_seq = temp_donor_seq << 2 | base; + } + from = i2 - acceptor_intronic_len; + to = i2 + acceptor_exonic_len - 1; + for(int j = from; j <= to; j++) { + assert_geq(j, -(int)other_ref_ext); + assert_lt(j, (int)len); + int base = refbuf2[j]; + if(base > 3) base = 0; + temp_acceptor_seq = temp_acceptor_seq << 2 | base; + } + } + } else if(spldir == SPL_RC) { + if(i + 1 >= (int)acceptor_exonic_len && + (int)(len + this_ref_ext) > i + (int)acceptor_intronic_len && + i2 + (int)other_ref_ext >= (int)donor_intronic_len && + (int)len > i2 + (int)donor_exonic_len - 1) { + int from = i + 1 - (int)acceptor_exonic_len; + int to = i + (int)acceptor_intronic_len; + for(int j = to; j >= from; j--) { + assert_geq(j, 0); + assert_lt(j, (int)(len + this_ref_ext)); + int base = refbuf[j]; + if(base > 3) base = 0; + temp_acceptor_seq = temp_acceptor_seq << 2 | (base ^ 0x3); + } + from = i2 - donor_intronic_len; + to = i2 + donor_exonic_len - 1; + for(int j = to; j >= from; j--) { + assert_geq(j, -(int)other_ref_ext); + assert_lt(j, (int)len); + int base = refbuf2[j]; + if(base > 3) base = 0; + temp_donor_seq = temp_donor_seq << 2 | (base ^ 0x3); + } + } + } + + splscore = SpliceSiteDB::probscore(temp_donor_seq, temp_acceptor_seq); + } + // daehwan - for debugging purposes + // choose a splice site with the better score + if((maxspldir == SPL_UNKNOWN && spldir == SPL_UNKNOWN && maxscore < tempscore) || + (maxspldir == SPL_UNKNOWN && spldir == SPL_UNKNOWN && maxscore == tempscore && semi_canonical) || + (maxspldir != SPL_UNKNOWN && spldir != SPL_UNKNOWN && (maxscore < tempscore || (maxscore == tempscore && maxsplscore < splscore))) || + (maxspldir == SPL_UNKNOWN && spldir != SPL_UNKNOWN)) { + maxscore = tempscore; + maxscorei = i; + maxspldir = spldir; + maxsplscore = splscore; + if(maxspldir != SPL_UNKNOWN) { + donor_seq = temp_donor_seq; + acceptor_seq = temp_acceptor_seq; + } else { + donor_seq = 0; + acceptor_seq = 0; + } + } + } + } else { + // discover an insertion or a deletion + assert(ins || del); + int inslen = (ins ? rddif - refdif : 0); + int dellen = (del ? refdif - rddif : 0); + int64_t gap_penalty; + if(ins) { + gap_penalty = -(sc.refGapOpen() + sc.refGapExtend() * (inslen - 1)); + } else { + assert(del); + gap_penalty = -(sc.readGapOpen() + sc.readGapExtend() * (dellen - 1)); + } + if(gap_penalty < remainsc) return false; + int i; + for(i = 0; i < (int)len; i++) { + int rdc = seq[this_rdoff + i], rfc = get_ref_base(threeN, refConversion_3N, refbuf[i]); + if(i > 0) { + temp_scores[i] = temp_scores[i-1]; + } else { + temp_scores[i] = 0; + } + if(rdc != rfc) { + temp_scores[i] += sc.score(rdc, 1 << rfc, qual[this_rdoff + i] - 33); + } + if(temp_scores[i] + gap_penalty < remainsc) { + break; + } + } + int i_limit = min(i, len); + int i2; + for(i2 = len - 1; i2 >= 0; i2--) { + int rdc = seq[this_rdoff + i2], rfc = get_ref_base(threeN, refConversion_3N, refbuf2[i2]); + if((index_t)(i2 + 1) < len) { + temp_scores2[i2] = temp_scores2[i2+1]; + } else { + temp_scores2[i2] = 0; + } + if(rdc != rfc) { + temp_scores2[i2] += sc.score(rdc, 1 << rfc, qual[this_rdoff + i2] - 33); + } + if(temp_scores2[i2] + gap_penalty < remainsc) { + break; + } + } + int i2_limit = (i2 < inslen ? 0 : i2 - inslen); + for(i = i2_limit, i2 = i2_limit + 1 + inslen; + i < i_limit && i2 < (int)len; + i++, i2++) { + int64_t tempscore = temp_scores[i] + temp_scores2[i2] + gap_penalty; + if(maxscore < tempscore) { + maxscore = tempscore; + maxscorei = i; + } + } + } + if(maxscore == MIN_I64) return false; + assert_lt(maxscorei, len); + if(spliced && spliceSite == NULL) { + uint32_t shorter_anchor_len = min(maxscorei + 1, len - maxscorei - 1); + assert_leq(this_toff, other_toff); + if(maxspldir == SPL_SEMI_FW || maxspldir == SPL_SEMI_RC || maxspldir == SPL_UNKNOWN) { + if(shorter_anchor_len < minAnchorLen_noncan) { + float intronLenProb = intronLen_prob_noncan(shorter_anchor_len, other_toff - this_toff, maxIntronLen); + if(intronLenProb > 0.01f) + return false; + } + } else { + if(shorter_anchor_len < minAnchorLen) { + float intronLenProb = intronLen_prob(shorter_anchor_len, other_toff - this_toff, maxIntronLen); + if(intronLenProb > 0.01f) + return false; + } + } + } + if(maxscore < remainsc) + return false; + } + + bool clear = true; + for(int i = (int)_edits->size() - 1; i >= 0; i--) { + const Edit& edit = (*_edits)[i]; + if(edit.type == EDIT_TYPE_SPL || + edit.type == EDIT_TYPE_READ_GAP || + edit.type == EDIT_TYPE_REF_GAP || + (edit.type == EDIT_TYPE_MM && edit.snpID != (index_t)INDEX_MAX)) { + _edits->resize(i+1); + clear = false; + break; + } + } + if(clear) this->_edits->clear(); + // combine two alignments while updating edits + if(spliced) { + assert_geq(this_rdoff, this->_rdoff); + index_t addoff = this_rdoff - this->_rdoff; + int rd_gap_off = -min(splice_gap_off, 0); + int ref_gap_off = max(splice_gap_off, 0); + for(int i = 0; i < (int)len; i++) { + assert_lt(this_rdoff + i, rdlen); + int rdc = seq[this_rdoff + i]; + assert_range(0, 4, rdc); + int rfc; + if(splice_gap_maxscorei <= maxscorei) { + if(i <= (int)splice_gap_maxscorei) { + rfc = get_ref_base(threeN, refConversion_3N, refbuf[i]); + } else if(i <= (int)maxscorei) { + rfc = get_ref_base(threeN, refConversion_3N, refbuf[i - ref_gap_off + rd_gap_off]); + } else { + rfc = get_ref_base(threeN, refConversion_3N, refbuf2[i]); + } + } else { + if(i <= (int)maxscorei) { + rfc = get_ref_base(threeN, refConversion_3N, refbuf[i]); + } else if(i <= (int)splice_gap_maxscorei) { + rfc = get_ref_base(threeN, refConversion_3N, refbuf2[i + ref_gap_off - rd_gap_off]); + } else { + rfc = get_ref_base(threeN, refConversion_3N, refbuf2[i]); + } + } + assert_range(0, 4, rfc); + if(rdc != rfc) { + Edit e((uint32_t)(i + addoff), rfc, rdc, EDIT_TYPE_MM, false); + _edits->push_back(e); + } + if(i == (int)maxscorei) { + index_t left = this_toff + i + 1; + if(splice_gap_maxscorei <= maxscorei) { + left = left - ref_gap_off + rd_gap_off; + } + index_t right = other_toff + other_len - (len - i - 1); + if(splice_gap_maxscorei > maxscorei) { + right = right + ref_gap_off - rd_gap_off; + } + index_t skipLen = 0; + assert_lt(left, right); + skipLen = right - left; + Edit e((uint32_t)(i + 1 + addoff), 0, 0, EDIT_TYPE_SPL, skipLen, maxspldir, spliceSite != NULL, false); + e.donor_seq = donor_seq; + e.acceptor_seq = acceptor_seq; + _edits->push_back(e); + } + if(i == (int)splice_gap_maxscorei && splice_gap_off != 0) { + if(rd_gap_off > 0) { + assert_lt(left, right); + for(index_t j = 0; j < (index_t)rd_gap_off; j++) { + int temp_rfc_off = i + 1 + j; + int temp_rfc; + if(i < (int)maxscorei) { + temp_rfc = get_ref_base(threeN, refConversion_3N, refbuf[temp_rfc_off]); + } else { + temp_rfc = get_ref_base(threeN, refConversion_3N, refbuf2[temp_rfc_off - rd_gap_off]); + } + assert_range(0, 4, temp_rfc); + Edit e((uint32_t)(i + 1 + addoff), "ACGTN"[temp_rfc], '-', EDIT_TYPE_READ_GAP); + _edits->push_back(e); + } + } else { + assert_gt(ref_gap_off, 0); + for(index_t j = 0; j < (index_t)ref_gap_off; j++) { + assert_lt(this_rdoff + i + 1 + j, rdlen); + int temp_rdc = seq[this_rdoff + i + 1 + j]; + assert_range(0, 4, temp_rdc); + Edit e((uint32_t)(i + 1 + j + addoff), '-', "ACGTN"[temp_rdc], EDIT_TYPE_REF_GAP); + _edits->push_back(e); + } + i += ref_gap_off; + } + } + } + } else { + index_t ins_len = 0; + for(index_t i = 0; i < len; i++) { + char rdc = seq[this_rdoff + i]; + char rfc = (i <= maxscorei ? get_ref_base(threeN, refConversion_3N, refbuf[i]) : get_ref_base(threeN, refConversion_3N, refbuf2[i])); + assert_geq(this_rdoff, this->_rdoff); + index_t addoff = this_rdoff - this->_rdoff; + if(rdc != rfc) { + ALT cmp_alt; + assert_geq(this_toff, this->_toff); + cmp_alt.pos = this->_joinedOff + i + (this_toff - this->_toff) - ins_len; + index_t alt_i = (index_t)altdb.alts().bsearchLoBound(cmp_alt); + index_t add_alt_i = std::numeric_limits::max(); + for(; alt_i < altdb.alts().size(); alt_i++) { + const ALT& alt = altdb.alts()[alt_i]; + if(alt.left > cmp_alt.pos) break; + if(alt.type != ALT_SNP_SGL) continue; + if(alt.seq == rdc) { + add_alt_i = alt_i; + break; + } + } + + Edit e((uint32_t)(i + addoff), rfc, rdc, EDIT_TYPE_MM, false, add_alt_i); + _edits->push_back(e); + } + if(i == maxscorei) { + index_t left = this_toff + i + 1; + if(other_toff + other_len < len - i - 1) + return false; + index_t right = other_toff + other_len - (len - i - 1); + index_t skipLen = 0; + if(del) { + assert_lt(left, right); + skipLen = right - left; + for(index_t j = 0; j < skipLen; j++) { + int temp_rfc; + if(i + 1 + j < len) temp_rfc = get_ref_base(threeN, refConversion_3N, refbuf[i + 1 + j]); + else temp_rfc = get_ref_base(threeN, refConversion_3N, ref.getBase(this->_tidx, this_toff + i + 1 + j)); + assert_range(0, 4, temp_rfc); + Edit e((uint32_t)(i + 1 + addoff), "ACGTN"[temp_rfc], '-', EDIT_TYPE_READ_GAP); + _edits->push_back(e); + } + } else { + assert(ins); + assert_lt(right, left); + skipLen = left - right; + for(index_t j = 0; j < skipLen; j++) { + assert_lt(this_rdoff + i + 1 + j, seq.length()); + int temp_rdc = seq[this_rdoff + i + 1 + j]; + assert_range(0, 4, temp_rdc); + Edit e((uint32_t)(i + 1 + j + addoff), '-', "ACGTN"[temp_rdc], EDIT_TYPE_REF_GAP); + _edits->push_back(e); + } + i += skipLen; + ins_len += skipLen; + } + } + } + } + index_t fsi = (index_t)otherHit._edits->size(); + for(index_t i = 0; i < otherHit._edits->size(); i++) { + const Edit& edit = (*otherHit._edits)[i]; + if(edit.type == EDIT_TYPE_SPL || + edit.type == EDIT_TYPE_READ_GAP || + edit.type == EDIT_TYPE_REF_GAP || + (edit.type == EDIT_TYPE_MM && edit.snpID != (index_t)INDEX_MAX)) { + fsi = i; + break; + } + } + assert_leq(this->_rdoff, otherHit._rdoff); + index_t addoff = otherHit._rdoff - this->_rdoff; + for(index_t i = fsi; i < otherHit._edits->size(); i++) { + _edits->push_back((*otherHit._edits)[i]); + _edits->back().pos += addoff; + } + // for alignment involving indel, left align so that + // indels go to the left most of the combined alignment + if(ins || del || (spliced && splice_gap_off != 0)) { + leftAlign(rd); + } + + // update alignment score, trims + assert_leq(this->_rdoff + this->_len, otherHit._rdoff + otherHit._len); + _len = otherHit._rdoff + otherHit._len - this->_rdoff; + assert_eq(_trim3, 0); + _trim3 += otherHit._trim3; + calculateScore( + rd, + ssdb, + sc, + minK_local, + minIntronLen, + maxIntronLen, + minAnchorLen, + minAnchorLen_noncan, + ref); +#ifndef NDEBUG + if(_joinedOff != (index_t)INDEX_MAX) { + ASSERT_ONLY(bool straddled = false); + ASSERT_ONLY(index_t tmp_tidx = 0, tmp_toff = 0, tmp_tlen = 0); + gfm.joinedToTextOff( + 0, + _joinedOff, + tmp_tidx, + tmp_toff, + tmp_tlen, + true, // reject straddlers? + straddled); // straddled? + assert_eq(tmp_tidx, _tidx); + assert_eq(tmp_toff, _toff); + } +#endif + assert(repOk(rd, ref)); + return true; +} + +/** + * Extend the partial alignment (GenomeHit) bidirectionally + */ +template +bool GenomeHit::extend( + const Read& rd, + const GFM& gfm, + const BitPairReference& ref, + const ALTDB& altdb, + const RepeatDB& repeatdb, + SpliceSiteDB& ssdb, + SwAligner& swa, + SwMetrics& swm, + PerReadMetrics& prm, + const Scoring& sc, + TAlScore minsc, + RandomSource& rnd, // pseudo-random source + index_t minK_local, + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + index_t& leftext, + index_t& rightext, + index_t mm) +{ + assert_lt(this->_tidx, ref.numRefs()); + index_t max_leftext = leftext, max_rightext = rightext; + assert(max_leftext > 0 || max_rightext > 0); + leftext = 0, rightext = 0; + index_t rdlen = (index_t)rd.length(); + bool doLeftAlign = false; + assert(_sharedVars != NULL); + + const index_t minIntronLen = tpol.minIntronLen(); + const index_t maxIntronLen = tpol.maxIntronLen(); + const index_t minAnchorLen = tpol.minAnchorLen(); + const index_t minAnchorLen_noncan = tpol.minAnchorLen_noncan(); + + // extend the alignment further in the left direction + // with 'mm' mismatches allowed + const BTDnaString& seq = _fw ? rd.patFw : rd.patRc; + if(max_leftext > 0 && _rdoff > 0) { + assert_gt(_rdoff, 0); + index_t left_rdoff, left_len, left_toff; + this->getLeft(left_rdoff, left_len, left_toff); + assert_eq(left_rdoff, _rdoff); + assert_eq(left_toff, _toff); + if(_toff <= 0) return false; + int rl = (int)_toff - (int)_rdoff; + assert_geq(_score, minsc); + index_t reflen = _rdoff + 10; + rl -= (reflen - _rdoff); + if(rl < 0) { + reflen += rl; + rl = 0; + } + index_t numNs = 0; + index_t num_prev_edits = (index_t)_edits->size(); + index_t best_ext = alignWithALTs( + altdb.alts(), + altdb.haplotypes(), + altdb.haplotype_maxrights(), + this->_joinedOff, + seq, + this->_rdoff - 1, + this->_rdoff - 1, + this->_rdoff, + ref, + *_sharedVars, + _tidx, + rl, + reflen, + true, /* left? */ + gpol, + *this->_edits, + _sharedVars->ht_llist, + *this->_ht_list, + _sharedVars->cmp_ht, + rd.threeN_cycle, + NULL, + mm, + &numNs); + // Do not allow for any edits including known snps and splice sites when extending zero-length hit + if(_len == 0 && mm == 0 && _edits->size() > 0) { + _edits->clear(); + return false; + } + if(best_ext > 0) { + leftext = best_ext; + assert_leq(num_prev_edits, _edits->size()); + index_t added_edits = (index_t)_edits->size() - num_prev_edits; + int ref_ext = (int)best_ext; + for(index_t i = 0; i < added_edits; i++) { + const Edit& edit = (*_edits)[i]; + if(edit.type == EDIT_TYPE_REF_GAP) ref_ext--; + else if(edit.type == EDIT_TYPE_READ_GAP) ref_ext++; + else if(edit.type == EDIT_TYPE_SPL) ref_ext += edit.splLen; + } + assert_leq(best_ext, _rdoff); + _rdoff -= best_ext; + assert_leq(ref_ext, _toff); + _toff -= ref_ext; + _len += best_ext; + assert_leq(_len, rdlen); + assert_leq((int)numNs, ref_ext); + assert_leq(ref_ext - (int)numNs, _joinedOff); + _joinedOff -= (ref_ext - (int)numNs); + for(index_t i = 0; i < _edits->size(); i++) { + if(i < added_edits) { + assert_geq((*_edits)[i].pos, _rdoff); + (*_edits)[i].pos -= _rdoff; + } else { + (*_edits)[i].pos += best_ext; + } + } + } + } + + // extend the alignment further in the right direction + // with 'mm' mismatches allowed + if(max_rightext > 0 && _rdoff + _len < rdlen) { + index_t right_rdoff, right_len, right_toff; + this->getRight(right_rdoff, right_len, right_toff); + index_t rl = right_toff + right_len; + assert_eq(_rdoff + _len, right_rdoff + right_len); + index_t rr = rdlen - (right_rdoff + right_len); + index_t tlen = ref.approxLen(_tidx); + if(rl < tlen) { + index_t reflen = rr + 10; + if(rl + reflen > tlen) { + reflen = tlen - rl; + } + int ref_ext = (int)_len; + for(index_t ei = 0; ei < _edits->size(); ei++) { + const Edit& e = (*_edits)[ei]; + if(e.type == EDIT_TYPE_REF_GAP) ref_ext--; + else if(e.type == EDIT_TYPE_READ_GAP) ref_ext++; + else if(e.type == EDIT_TYPE_SPL) ref_ext += e.splLen; + else if(e.type == EDIT_TYPE_MM && e.chr == 'N') ref_ext--; + } + + index_t best_ext = alignWithALTs( + altdb.alts(), + altdb.haplotypes(), + altdb.haplotype_maxrights(), + this->_joinedOff + ref_ext, + seq, + this->_rdoff, + this->_rdoff + this->_len, + rdlen - (this->_rdoff + this->_len), + ref, + *_sharedVars, + _tidx, + (int)rl, + reflen, + false, + gpol, + *this->_edits, + _sharedVars->ht_llist, + *this->_ht_list, + _sharedVars->cmp_ht, + rd.threeN_cycle, + NULL, + mm); + // Do not allow for any edits including known snps and splice sites when extending zero-length hit + if(_len == 0 && mm == 0 && _edits->size() > 0) { + _edits->clear(); + return false; + } + if(best_ext > 0) { + rightext = best_ext; + _len += best_ext; + } + } + } + +#ifndef NDEBUG + if(_joinedOff != (index_t)INDEX_MAX && seq[_rdoff] < 4) { + ASSERT_ONLY(bool straddled = false); + ASSERT_ONLY(index_t tmp_tidx = 0, tmp_toff = 0, tmp_tlen = 0); + gfm.joinedToTextOff( + 0, + _joinedOff, + tmp_tidx, + tmp_toff, + tmp_tlen, + true, // reject straddlers? + straddled); // straddled? + if(!gfm.repeat()) { + assert_eq(tmp_tidx, _tidx); + } + assert_eq(tmp_toff, _toff); + } +#endif + + if(doLeftAlign) leftAlign(rd); + assert_leq(_rdoff + _len, rdlen); + calculateScore( + rd, + ssdb, + sc, + minK_local, + minIntronLen, + maxIntronLen, + minAnchorLen, + minAnchorLen_noncan, + ref); + assert(repOk(rd, ref)); + return leftext > 0 || rightext > 0; +} + +/** + * Adjust alignment with respect to SNPs, usually updating Edits + * + */ +template +bool GenomeHit::adjustWithALT( + index_t rdoff, + index_t len, + const Coord& coord, + SharedTempVars& sharedVars, + EList >& genomeHits, + const Read& rd, + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + const GraphPolicy& gpol) +{ + if(gfm.gh().linearFM()) { + genomeHits.expand(); + genomeHits.back().init( + coord.orient(), + rdoff, + len, + 0, // trim5 + 0, // trim3 + (index_t)coord.ref(), + (index_t)coord.off(), + (index_t)coord.joinedOff(), + sharedVars); + return true; + } + index_t width = 1 << (gfm.gh()._offRate + 2); + EList >& ssOffs = sharedVars.ssOffs; + findSSOffs(gfm, altdb, (coord.joinedOff() >= width ? (index_t)(coord.joinedOff() - width) : 0), (index_t)(coord.joinedOff() + width), ssOffs); + assert_gt(ssOffs.size(), 0); + bool found = false; + for(index_t s = 0; s < ssOffs.size(); s++) { + index_t off = (index_t)coord.off(); + index_t joinedOff = (index_t)coord.joinedOff(); + pair& ssOff = ssOffs[s]; + if(ssOff.first > 0) { + assert_neq(ssOff.second, 0); + if(ssOff.second > 0) { + off += ssOff.first; + joinedOff += ssOff.first; + } else { + off -= ssOff.first; + joinedOff -= ssOff.first; + } + } + size_t numGenomeHits = genomeHits.size(); + genomeHits.expand(); + genomeHits.back().init( + coord.orient(), + rdoff, + len, + 0, // trim5 + 0, // trim3 + (index_t)coord.ref(), + off, + joinedOff, + sharedVars); + GenomeHit& genomeHit = genomeHits.back(); + EList >& offDiffs = sharedVars.offDiffs; + const index_t single_offDiffs_size = findOffDiffs(gfm, + altdb, + (genomeHit._joinedOff >= width ? genomeHit._joinedOff - width : 0), + genomeHit._joinedOff + width, + offDiffs); + assert_leq(single_offDiffs_size, offDiffs.size()); + + const BTDnaString& seq = genomeHit._fw ? rd.patFw : rd.patRc; + const EList >& alts = altdb.alts(); + + index_t orig_joinedOff = genomeHit._joinedOff; + index_t orig_toff = genomeHit._toff; + bool found2 = false; + // maxAltsTried is not directly related to the size of offDiffs, + // but let's make the size of offDiffs is determined by maxAltsTried + const index_t max_offDiffs_size = max(4, gpol.maxAltsTried() / 4); + if(offDiffs.size() - single_offDiffs_size > max_offDiffs_size) offDiffs.resize(single_offDiffs_size + max_offDiffs_size); + for(index_t o = 0; o < offDiffs.size() && !found2; o++) { + const pair& offDiff = offDiffs[o]; +#ifndef NDEBUG + if(o == 0) { + assert_eq(offDiff.first, 0); + assert_eq(offDiff.second, 0); + } +#endif + if(offDiff.second >= 0) { + genomeHit._joinedOff = orig_joinedOff + offDiff.first; + genomeHit._toff = orig_toff + offDiff.first; + } else { + if(orig_toff < offDiff.first) continue; + assert_geq(orig_joinedOff, offDiff.first); + genomeHit._joinedOff = orig_joinedOff - offDiff.first; + genomeHit._toff = orig_toff - offDiff.first; + } + + genomeHit._edits->clear(); + ELList& candidate_edits = sharedVars.candidate_edits; + candidate_edits.clear(); + index_t reflen = genomeHit._len + 10; + index_t alignedLen = alignWithALTs( + alts, + altdb.haplotypes(), + altdb.haplotype_maxrights(), + genomeHit._joinedOff, + seq, + genomeHit._rdoff, + genomeHit._rdoff, + genomeHit._len, + ref, + sharedVars, + genomeHit._tidx, + (int)genomeHit._toff, + reflen, + false, /* left? */ + gpol, + *genomeHit._edits, + sharedVars.ht_llist, + *genomeHit._ht_list, + sharedVars.cmp_ht, + rd.threeN_cycle, + &candidate_edits); + if(alignedLen == genomeHit._len) { + found2 = true; + assert(genomeHit.repOk(rd, ref)); + for(index_t i = 0; i < genomeHits.size() - 1; i++) { + if(genomeHits[i] == genomeHits.back()) { + found2 = false; + } + } + if(found2) { + for(index_t e = 0; e < candidate_edits.size(); e++) { + genomeHits.expand(); + genomeHits.back() = genomeHits[genomeHits.size() - 2]; + *(genomeHits.back()._edits) = candidate_edits[e]; + assert(genomeHits.back().repOk(rd, ref)); + for(size_t i = 0; i < genomeHits.size() - 1; i++) { + if(genomeHits[i] == genomeHits.back()) { + genomeHits.pop_back(); + break; + } + } + } + } + } else { + genomeHit._edits->clear(); + } + } + if(!found2) genomeHits.pop_back(); + found = genomeHits.size() > numGenomeHits; + } + return found; +} + +/** + * Adjust alignment with respect to SNPs, usually updating Edits + * + */ +template +bool GenomeHit::adjustWithALT( + const Read& rd, + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + const GraphPolicy& gpol) +{ + if(gfm.gh().linearFM()) return true; + assert_lt(this->_tidx, ref.numRefs()); + + assert(_sharedVars != NULL); + EList >& offDiffs = _sharedVars->offDiffs; + index_t width = 1 << (gfm.gh()._offRate + 2); + const index_t single_offDiffs_size = findOffDiffs(gfm, + altdb, + (this->_joinedOff >= width ? this->_joinedOff - width : 0), + this->_joinedOff + width, + offDiffs); + assert_leq(single_offDiffs_size, offDiffs.size()); + + const BTDnaString& seq = _fw ? rd.patFw : rd.patRc; + const EList >& alts = altdb.alts(); + + index_t orig_joinedOff = this->_joinedOff; + index_t orig_toff = this->_toff; + bool found = false; + // maxAltsTried is not directly related to the size of offDiffs, + // but let's make the size of offDiffs is determined by maxAltsTried + const index_t max_offDiffs_size = max(4, gpol.maxAltsTried() / 4); + if(offDiffs.size() - single_offDiffs_size > max_offDiffs_size) offDiffs.resize(single_offDiffs_size + max_offDiffs_size); + for(index_t o = 0; o < offDiffs.size() && !found; o++) { + const pair& offDiff = offDiffs[o]; +#ifndef NDEBUG + if(o == 0) { + assert_eq(offDiff.first, 0); + assert_eq(offDiff.second, 0); + } +#endif + if(offDiff.second >= 0) { + this->_joinedOff = orig_joinedOff + offDiff.first; + this->_toff = orig_toff + offDiff.first; + } else { + if(orig_toff < offDiff.first) continue; + assert_geq(orig_joinedOff, offDiff.first); + this->_joinedOff = orig_joinedOff - offDiff.first; + this->_toff = orig_toff - offDiff.first; + } + index_t reflen = this->_len + 10; + index_t alignedLen = alignWithALTs( + alts, + altdb.haplotypes(), + altdb.haplotype_maxrights(), + this->_joinedOff, + seq, + this->_rdoff, + this->_rdoff, + this->_len, + ref, + *_sharedVars, + this->_tidx, + (int)this->_toff, + reflen, + false, /* left? */ + gpol, + *this->_edits, + _sharedVars->ht_llist, + *this->_ht_list, + _sharedVars->cmp_ht, + rd.threeN_cycle, + &_sharedVars->candidate_edits); + if(alignedLen == this->_len) { + found = true; + } else { + this->_edits->clear(); + } + } +#ifndef NDEBUG + if(found) { + assert(repOk(rd, ref)); + } +#endif + return found; +} + +/* + * Find offset differences due to splice sites + */ +template +void GenomeHit::findSSOffs( + const GFM& gfm, + const ALTDB& altdb, + index_t start, + index_t end, + EList >& ssOffs) +{ + ssOffs.clear(); + ssOffs.expand(); + ssOffs.back().first = ssOffs.back().second = 0; + if(gfm.gh().linearFM() || !altdb.hasSpliceSites()) return; + const EList >& alts = altdb.alts(); + + // Find splice sites included in this region + ALT alt_search; + alt_search.left = start; + for(index_t i = (index_t)alts.bsearchLoBound(alt_search); i < alts.size(); i++) { + const ALT& alt = alts[i]; + if(alt.left >= end) break; + if(!alt.splicesite()) continue; + // + if(alt.left < alt.right) { + ssOffs.expand(); + ssOffs.back().first = alt.right - alt.left + 1; + ssOffs.back().second = 1; + + const index_t relax = 5; + if(alt.right > relax) alt_search.left = alt.right - relax; + else alt_search.left = 0; + for(index_t j = (index_t)alts.bsearchLoBound(alt_search); j < alts.size(); j++) { + const ALT& alt2 = alts[j]; + if(!alt2.splicesite()) continue; + if(alt2.left < alt2.right) continue; + if(alt2.left + alt2.right == alt.left + alt.right) continue; + if(alt2.left > alt.right + relax) break; + ssOffs.expand(); + if(alt2.right < alt.left) { + ssOffs.back().first = alt.left - alt2.right; + ssOffs.back().second = -1; + } else { + ssOffs.back().first = alt2.right - alt.left; + ssOffs.back().second = 1; + } + } + } else { + ssOffs.expand(); + ssOffs.back().first = alt.left - alt.right + 1; + ssOffs.back().second = -1; + } + } + + if(ssOffs.size() > 1) { + ssOffs.sort(); + index_t new_size = (index_t)(unique(ssOffs.begin(), ssOffs.end()) - ssOffs.begin()); + ssOffs.resize(new_size); + } +} + + +/* + * Find offset differences due to indels + */ +template +index_t GenomeHit::findOffDiffs( + const GFM& gfm, + const ALTDB& altdb, + index_t start, + index_t end, + EList >& offDiffs) +{ + offDiffs.clear(); + offDiffs.expand(); + offDiffs.back().first = offDiffs.back().second = 0; + if(gfm.gh().linearFM()) return offDiffs.size(); + const EList >& alts = altdb.alts(); + pair alt_range; + + // Find SNPs included in this region + { + ALT alt_search; + alt_search.pos = start; + alt_range.first = alt_range.second = (index_t)alts.bsearchLoBound(alt_search); + for(alt_range.second = alt_range.first; alt_range.second < alts.size(); alt_range.second++) { + const ALT& alt = alts[alt_range.second]; + if(alt.splicesite() && alt.left > alt.right) continue; + if(alt.deletion() && alt.reversed) continue; + if(alt.pos >= end) break; + } + } + if(alt_range.first >= alt_range.second) return offDiffs.size(); + + for(index_t second = alt_range.second; second > alt_range.first; second--) { + assert_leq(second, alts.size()); + const ALT& alt = alts[second - 1]; + if(!alt.gap() || alt.splicesite() || (alt.deletion() && alt.reversed)) + continue; + int off = 0; + if(alt.type == ALT_SNP_DEL) { + off = alt.len; + } else { + assert_eq(alt.type, ALT_SNP_INS); + off = -alt.len; + } + assert_neq(off, 0); + offDiffs.expand(); + offDiffs.back().first = abs(off); + offDiffs.back().second = (off > 0 ? 1 : -1); + } + + if(offDiffs.size() > 1) { + offDiffs.sort(); + index_t new_size = (index_t)(unique(offDiffs.begin(), offDiffs.end()) - offDiffs.begin()); + offDiffs.resize(new_size); + } + + const index_t single_offDiffs_size = offDiffs.size(); + for(index_t second = alt_range.second; second > alt_range.first; second--) { + assert_leq(alt_range.second, alts.size()); + const ALT& alt = alts[second - 1]; + if(!alt.gap() || alt.splicesite() || (alt.deletion() && alt.reversed)) + continue; + int off = 0; + if(alt.type == ALT_SNP_DEL) { + off = alt.len; + } else { + assert_eq(alt.type, ALT_SNP_INS); + off = -alt.len; + } + for(index_t second2 = second - 1; second2 > alt_range.first; second2--) { + const ALT& alt2 = alts[second2 - 1]; + if(!alt2.gap() || alt2.splicesite() || (alt2.deletion() && alt2.reversed)) + continue; + if(alt2.type == ALT_SNP_DEL) { + if(alt2.pos + alt2.len >= alt.pos) + continue; + off += alt2.len; + } else { + assert_eq(alt2.type, ALT_SNP_INS); + if(alt2.pos >= alt.pos) + continue; + off -= alt2.len; + } + bool found = false; + for(index_t i = 0; i < offDiffs.size(); i++) { + int off_cmp = offDiffs[i].first * offDiffs[i].second; + if(off == off_cmp) { + found = true; + break; + } + } + if(!found) { + offDiffs.expand(); + offDiffs.back().first = abs(off); + offDiffs.back().second = (off > 0 ? 1 : -1); + } + } + } + + return single_offDiffs_size; +} + + +/* + * + */ +template +void add_haplotypes( + const EList >& alts, + const EList >& haplotypes, + const EList& haplotype_maxrights, + Haplotype& cmp_ht, + EList >& ht_list, + index_t rdlen, + bool left_ext = true, + bool initial = false) +{ + pair ht_range; + ht_range.first = ht_range.second = (int)haplotypes.bsearchLoBound(cmp_ht); + if(ht_range.first >= haplotypes.size()) + return; + + if(left_ext) { + for(; ht_range.first >= 0; ht_range.first--) { + const Haplotype& ht = haplotypes[ht_range.first]; + if(!initial) { + if(ht.right >= cmp_ht.left) continue; + } + index_t ht_maxright = haplotype_maxrights[ht_range.first]; + assert_geq(ht_maxright, ht.right); + if(ht_maxright + rdlen - 1 < cmp_ht.left) break; + if(ht.alts.size() <= 0) continue; + bool added = false; + for(index_t h = 0; h < ht_list.size(); h++) { + if(ht_list[h].first == ht_range.first) { + added = true; + break; + } + } + if(added) continue; + ht_list.expand(); + ht_list.back().first = ht_range.first; + assert_gt(ht.alts.size(), 0); + if(ht.right < cmp_ht.left) { + ht_list.back().second = ht.alts.size() - 1; + } else { + assert(initial); + ht_list.back().second = ht.alts.size(); + for(int a = (int)ht.alts.size() - 1; a >= 0; a--) { + index_t alti = ht.alts[a]; + assert_lt(alti, alts.size()); + const ALT& alt = alts[alti]; + assert(alt.snp()); + ht_list.back().second = (index_t)a; + if(cmp_ht.left > alt.pos) break; + } + if(ht_list.back().second == ht.alts.size()) { + ht_list.pop_back(); + } + } + } + } else { + if(initial) { + for(; ht_range.first >= 0; ht_range.first--) { + const Haplotype& ht = haplotypes[ht_range.first]; + index_t ht_maxright = haplotype_maxrights[ht_range.first]; + assert_geq(ht_maxright, ht.right); + if(ht_maxright < cmp_ht.left) break; + if(ht.right < cmp_ht.left || ht.left > cmp_ht.left) continue; + if(ht.alts.size() <= 0) continue; + bool added = false; + for(index_t h = 0; h < ht_list.size(); h++) { + if(ht_list[h].first == ht_range.first) { + added = true; + break; + } + } + if(added) continue; + ht_list.expand(); + ht_list.back().first = ht_range.first; + assert_gt(ht.alts.size(), 0); + ht_list.back().second = ht.alts.size(); + for(index_t a = 0; a < ht.alts.size(); a++) { + index_t alti = ht.alts[a]; + assert_lt(alti, alts.size()); + const ALT& alt = alts[alti]; + assert(alt.snp()); + ht_list.back().second = a; + if(cmp_ht.left <= alt.pos) break; + } + if(ht_list.back().second == ht.alts.size()) { + ht_list.pop_back(); + } + } + } + + for(; ht_range.second < haplotypes.size(); ht_range.second++) { + const Haplotype& ht = haplotypes[ht_range.second]; + if(ht.left < cmp_ht.right) continue; + if(ht.left >= cmp_ht.right + rdlen) break; + if(ht.alts.size() <= 0) continue; + bool added = false; + for(index_t h = 0; h < ht_list.size(); h++) { + if(ht_list[h].first == ht_range.second) { + added = true; + break; + } + } + if(added) continue; + ht_list.expand(); + ht_list.back().first = ht_range.second; + assert_gt(ht.alts.size(), 0); + ht_list.back().second = 0; + } + } +} + +/* + * + */ +template +index_t GenomeHit::alignWithALTs_recur( + const EList >& alts, + const EList >& haplotypes, + const EList& haplotype_maxrights, + index_t joinedOff, + const BTDnaString& rdseq, + index_t rdoff_add, + index_t rdoff, + index_t rdlen, + const BitPairReference& ref, + EList >& raw_refbufs, + ASSERT_ONLY(SStringExpandable destU32,) + EList& tmp_edits, + int& best_rdoff, + const char* rfseq, + index_t tidx, + int rfoff, + index_t rflen, + bool left, + EList& edits, + index_t mm, + ELList >& ht_llist, + Haplotype& cmp_ht, + ELList* candidate_edits, + index_t tmp_numNs, + index_t* numNs, + index_t dep, + const GraphPolicy& gpol, + index_t& numALTsTried, + int cycle_3N, + ALT_TYPE prev_alt_type) +{ + if(numALTsTried > gpol.maxAltsTried() + dep) return 0; + assert_gt(rdlen, 0); + assert_gt(rflen, 0); + if(ht_llist.size() <= dep) ht_llist.expand(); + if(raw_refbufs.size() <= dep) raw_refbufs.expand(); + if(rfoff < -16) return 0; + size_t contig_len = ref.approxLen(tidx); + if(rfoff >= contig_len) return 0; + if(rfoff >= 0 && rfoff + rflen > contig_len) { + rflen = contig_len - rfoff; + } else if(rfoff < 0 && rflen > contig_len) { + rflen = contig_len; + } + if(rflen == 0) return 0; + if(rfseq == NULL) { + SStringExpandable& raw_refbuf = raw_refbufs[dep]; + raw_refbuf.resize(rflen + 16 + 16); + raw_refbuf.fill(0x4); + int off = ref.getStretch( + reinterpret_cast(raw_refbuf.wbuf() + 16), + tidx, + max(rfoff, 0), + rfoff > 0 ? rflen : rflen + rfoff + ASSERT_ONLY(, destU32)); + assert_lt(off, 16); + rfseq = raw_refbuf.wbuf() + 16 + off + min(rfoff, 0); + } + + int refConversion_3N[5] = {0, 1, 2, 3, 4}; + if (threeN){ + if (cycle_3N == 0 || cycle_3N == 3) { + // C to T conversion + refConversion_3N[asc2dna[hs3N_convertedFrom]] = asc2dna[hs3N_convertedTo]; + } else { + //G to A conversion + refConversion_3N[asc2dna[hs3N_convertedFromComplement]] = asc2dna[hs3N_convertedToComplement]; + + } + } + + if(left) { + index_t tmp_mm = 0; + int min_rd_i = (int)rdoff; + int mm_min_rd_i = (int)rdoff; + index_t mm_tmp_numNs = 0; + for(int rf_i = (int)rflen - 1; rf_i >= 0 && mm_min_rd_i >= 0; rf_i--, mm_min_rd_i--) { + int rf_bp = get_ref_base(threeN, refConversion_3N, rfseq[rf_i]); + int rd_bp = rdseq[mm_min_rd_i]; + if(rf_bp != rd_bp || rd_bp == 4) { + if(tmp_mm == 0) { + min_rd_i = mm_min_rd_i; + } + if(tmp_mm >= mm) break; + tmp_mm++; + Edit e( + mm_min_rd_i, + "ACGTN"[rf_bp], + "ACGTN"[rd_bp], + EDIT_TYPE_MM); + tmp_edits.insert(e, 0); + } + if(rf_bp == 4) { + if(tmp_mm == 0) tmp_numNs++; + mm_tmp_numNs++; + } + } + if(tmp_mm == 0) { + min_rd_i = mm_min_rd_i; + } + if(mm_min_rd_i < best_rdoff) { + best_rdoff = mm_min_rd_i; + edits = tmp_edits; + if(numNs != NULL) *numNs = mm_tmp_numNs; + } + if(mm_min_rd_i < 0) return rdlen; + if(tmp_mm > 0) { + tmp_edits.erase(0, tmp_mm); + tmp_mm = 0; + } + + // Find SNPs included in this region + pair alt_range(0, 0); + if(alts.size() > 0) { + ALT cmp_alt; + const index_t minK = 16; + assert_leq(mm_min_rd_i, rdoff); + index_t rd_diff = rdoff - mm_min_rd_i; + rd_diff = (rd_diff > minK ? rd_diff - minK : 0); + if(gpol.enableCODIS()) { + rd_diff = 0; + } + if(rd_diff >= joinedOff) { + cmp_alt.pos = joinedOff; + } else { + cmp_alt.pos = joinedOff - rd_diff; + } + alt_range.first = alt_range.second = (int)alts.bsearchLoBound(cmp_alt); + if(alt_range.first >= alts.size()) { + assert_gt(alts.size(), 0); + alt_range.first = alt_range.second = alt_range.second - 1; + } + for(; alt_range.first >= 0; alt_range.first--) { + const ALT& alt = alts[alt_range.first]; + if(alt.snp()) { + if(alt.deletion() && !alt.reversed) continue; + if(alt.pos + rdlen < joinedOff) break; + } else if(alt.splicesite()) { + if(alt.left < alt.right) continue; + if(alt.left + rdlen - 1 < joinedOff) break; + } else { + assert(alt.exon()); + continue; + } + } + } + + // Update and find Haplotypes + EList >& ht_list = ht_llist[dep]; + ht_list.clear(); + if(gpol.useHaplotype() && haplotypes.size() > 0) { + if(dep > 0) { + EList >& ht_prev_list = ht_llist[dep-1]; + for(index_t p = 0; p < ht_prev_list.size(); p++) { + const pair& ht_ref = ht_prev_list[p]; + const Haplotype& ht = haplotypes[ht_ref.first]; + assert_lt(ht_ref.second, ht.alts.size()); + index_t alt_id = ht.alts[ht_ref.second]; + assert_gt(tmp_edits.size(), 0); + const ALT& alt = alts[tmp_edits[0].snpID]; + const ALT& ht_alt = alts[alt_id]; + if(!alt.isSame(ht_alt)) continue; + if(ht_ref.second == 0) { + cmp_ht.left = cmp_ht.right = joinedOff; + add_haplotypes(alts, + haplotypes, + haplotype_maxrights, + cmp_ht, + ht_list, + rdlen); + } else { + ht_list.push_back(ht_ref); + ht_list.back().second--; + } + } + } + if(ht_list.size() <= 0) { + cmp_ht.left = cmp_ht.right = joinedOff; + add_haplotypes(alts, + haplotypes, + haplotype_maxrights, + cmp_ht, + ht_list, + rdlen, + true, // left_ext? + dep == 0); // initial? + } + } + + assert_geq(rdoff, 0); + const index_t orig_nedits = (index_t)tmp_edits.size(); + for(; alt_range.second > alt_range.first; alt_range.second--) { + ALT alt = alts[alt_range.second]; + if(alt.pos >= joinedOff) continue; + if(alt.splicesite()) { + if(alt.left < alt.right) continue; + index_t tmp = alt.left; + alt.left = alt.right; + alt.right = tmp; + } + if(alt.deletion()) { + if(!alt.reversed) continue; + alt.pos = alt.pos - alt.len + 1; + } + if(alt.exon()) continue; + bool alt_compatible = false; + int rf_i = (int)rflen - 1, rd_i = (int)rdoff; + int diff = 0; + if(alt.type == ALT_SNP_SGL) { + diff = joinedOff - alt.pos - 1; + } else if(alt.type == ALT_SNP_DEL) { + if(alt.pos + alt.len >= joinedOff) continue; + diff = joinedOff - (alt.pos + alt.len); + } else if(alt.type == ALT_SNP_INS) { + diff = joinedOff - alt.pos; + } else { + assert(alt.splicesite()); + diff = joinedOff - (alt.right + 1); + } + if(rf_i < diff || rd_i < diff) continue; + rf_i -= diff; + rd_i -= diff; + int rd_bp = rdseq[rd_i]; + if(rd_i < min_rd_i) { + if(alt.type == ALT_SNP_INS) { + if(rd_i + 1 >= min_rd_i) continue; + } + break; + } + + // Check to see if there is a haplotype that supports this alt + if(ht_list.size() > 0 && alt.snp()) { + bool ht_found = false; + for(index_t h = 0; h < ht_list.size(); h++) { + const pair& ht_ref = ht_list[h]; + const Haplotype& ht = haplotypes[ht_ref.first]; + assert_lt(ht_ref.second, ht.alts.size()); + index_t ht_alti = ht.alts[ht_ref.second]; + const ALT& ht_alt = alts[ht_alti]; + if(alts[alt_range.second].isSame(ht_alt)) { + ht_found = true; + break; + } + } + if(!ht_found) continue; + } + + if(alt.type == ALT_SNP_SGL) { + if(rd_bp == (int)alt.seq) { + int rf_bp = get_ref_base(threeN, refConversion_3N, rfseq[rf_i]); + Edit e( + rd_i, + "ACGTN"[rf_bp], + "ACGTN"[rd_bp], + EDIT_TYPE_MM, + true, /* chars? */ + alt_range.second); + tmp_edits.insert(e, 0); + rd_i--; + rf_i--; + alt_compatible = true; + } + } else if(alt.type == ALT_SNP_DEL) { + if(rfoff + rf_i > (int)alt.len) { + if(rf_i > (int)alt.len) { + for(index_t i = 0; i < alt.len; i++) { + int rf_bp = get_ref_base(threeN, refConversion_3N, rfseq[rf_i - i]); + Edit e( + rd_i + 1, + "ACGTN"[rf_bp], + '-', + EDIT_TYPE_READ_GAP, + true, /* chars? */ + alt_range.second); + tmp_edits.insert(e, 0); + } + + } else { + // long deletions + int new_rfoff = rfoff - alt.len; + index_t new_rflen = rf_i + alt.len + 10; + if(raw_refbufs.size() <= dep + 1) raw_refbufs.expand(); + SStringExpandable& raw_refbuf = raw_refbufs[dep + 1]; + raw_refbuf.resize(new_rflen + 16 + 16); + raw_refbuf.fill(0x4); + int off = ref.getStretch( + reinterpret_cast(raw_refbuf.wbuf() + 16), + tidx, + max(new_rfoff, 0), + new_rfoff > 0 ? new_rflen : new_rflen + new_rfoff + ASSERT_ONLY(, destU32)); + assert_lt(off, 16); + const char* new_rfseq = raw_refbuf.wbuf() + 16 + off + min(new_rfoff, 0); + for(int i = 0; i < alt.len; i++) { + int rf_bp = get_ref_base(threeN, refConversion_3N, new_rfseq[rf_i - i + alt.len]); + Edit e( + rd_i + 1, + "ACGTN"[rf_bp], + '-', + EDIT_TYPE_READ_GAP, + true, /* chars? */ + alt_range.second); + tmp_edits.insert(e, 0); + } + } + rf_i -= (int)alt.len; + alt_compatible = true; + } + } else if(alt.type == ALT_SNP_INS) { + if(rd_i > (int)alt.len) { + bool same_seq = true; + for(index_t i = 0; i < alt.len; i++) { + rd_bp = rdseq[rd_i - i]; + int snp_bp = (alt.seq >> (i << 1)) & 0x3; + if(rd_bp != snp_bp) { + same_seq = false; + break; + } + Edit e( + rd_i - i, + '-', + "ACGTN"[rd_bp], + EDIT_TYPE_REF_GAP, + true, /* chars? */ + alt_range.second); + tmp_edits.insert(e, 0); + } + if(same_seq) { + rd_i -= (int)alt.len; + alt_compatible = true; + } + } + } else if(alt.type == ALT_SPLICESITE) { + bool add_splicesite = true; + if(rd_i == rdoff && prev_alt_type == ALT_SPLICESITE) { + add_splicesite = false; + } + if(add_splicesite) { + assert_lt(rd_i, rflen); + assert_lt(alt.left, alt.right); + index_t intronLen = alt.right - alt.left + 1; + Edit e(rd_i + 1, + 0, + 0, + EDIT_TYPE_SPL, + intronLen, + alt.fw ? SPL_FW : SPL_RC, + true, /* known splice site? */ + false); /* chrs? */ + tmp_edits.insert(e, 0); + alt_compatible = true; + } + } + if(alt_compatible) { + numALTsTried++; + assert_leq(rd_i, (int)rdoff); + if(rd_i < 0) { + best_rdoff = rd_i; + edits = tmp_edits; + return rdlen; + } + index_t next_joinedOff = alt.pos; + int next_rfoff = rfoff, next_rdoff = rd_i; + const char* next_rfseq = rfseq; + int next_rflen = rf_i + 1, next_rdlen = rd_i + 1; + if(alt.splicesite()) { + assert_lt(alt.left, alt.right); + next_joinedOff = alt.left; + index_t intronLen = alt.right - alt.left + 1; + assert_geq(next_rfoff, intronLen); + next_rfoff -= intronLen; + next_rfseq = NULL; + } + if(next_rflen < next_rdlen) { + int add_len = next_rdlen + 10 - next_rflen; + if(next_rfoff < add_len) add_len = next_rfoff; + next_rfoff -= add_len; + next_rflen += add_len; + next_rfseq = NULL; + } + index_t alignedLen = alignWithALTs_recur( + alts, + haplotypes, + haplotype_maxrights, + next_joinedOff, + rdseq, + rdoff_add, + next_rdoff, + next_rdlen, + ref, + raw_refbufs, + ASSERT_ONLY(destU32,) + tmp_edits, + best_rdoff, + next_rfseq, + tidx, + next_rfoff, + next_rflen, + left, + edits, + mm, + ht_llist, + cmp_ht, + candidate_edits, + tmp_numNs, + numNs, + dep + 1, + gpol, + numALTsTried, + cycle_3N, + alt.type); + if(alignedLen == next_rdlen) return rdlen; + } + // Restore to the earlier state + assert_leq(orig_nedits, tmp_edits.size()); + if(orig_nedits < tmp_edits.size()) tmp_edits.erase(0, tmp_edits.size() - orig_nedits); + } + return 0; + } else { + index_t tmp_mm = 0; + index_t max_rd_i = 0; + index_t mm_max_rd_i = 0; + index_t mm_tmp_numNs = 0; + for(index_t rf_i = 0; rf_i < rflen && mm_max_rd_i < rdlen; rf_i++, mm_max_rd_i++) { + int rf_bp = get_ref_base(threeN, refConversion_3N, rfseq[rf_i]); + int rd_bp = rdseq[rdoff + mm_max_rd_i]; + if(rf_bp != rd_bp || rd_bp == 4) { + if(tmp_mm == 0) { + max_rd_i = mm_max_rd_i; + } + if(tmp_mm >= mm) break; + tmp_mm++; + Edit e( + mm_max_rd_i + rdoff_add, + "ACGTN"[rf_bp], + "ACGTN"[rd_bp], + EDIT_TYPE_MM); + tmp_edits.push_back(e); + } + if(rf_bp == 4) { + if(tmp_mm == 0) tmp_numNs++; + mm_tmp_numNs++; + } + } + if(tmp_mm == 0) { + max_rd_i = mm_max_rd_i; + } + if(mm_max_rd_i + rdoff > best_rdoff) { + best_rdoff = mm_max_rd_i + rdoff; + edits = tmp_edits; + if(numNs != NULL) *numNs = mm_tmp_numNs; + if(candidate_edits != NULL) candidate_edits->clear(); + } else if(mm_max_rd_i + rdoff == best_rdoff) { + if(candidate_edits != NULL) { + candidate_edits->expand(); + candidate_edits->back() = tmp_edits; + } + } + if(mm_max_rd_i == rflen) { + return mm_max_rd_i; + } + + // Find SNPs included in this region + pair alt_range; + { + ALT cmp_alt; + const index_t minK = 16; + index_t rd_diff = (max_rd_i > minK ? max_rd_i - minK : 0); + if(gpol.enableCODIS()) { + rd_diff = 0; + } + cmp_alt.pos = joinedOff + rd_diff; + alt_range.first = alt_range.second = (index_t)alts.bsearchLoBound(cmp_alt); + if(alt_range.first >= alts.size()) return 0; + for(; alt_range.second < alts.size(); alt_range.second++) { + const ALT& alt = alts[alt_range.second]; + if(alt.splicesite()) { + if(alt.left > alt.right) continue; + } + if(alt.deletion()) { + if(alt.reversed) continue; + } + if(alt.left > joinedOff + max_rd_i) break; + } + } + if(mm_max_rd_i == rdlen) { + bool further_search = false; + for(index_t s = alt_range.first; s < alt_range.second; s++) { + const ALT& alt = alts[s]; + if(alt.splicesite() && alt.left < alt.right) { + further_search = true; + break; + } + } + if(!further_search) return mm_max_rd_i; + } + if(tmp_mm > 0) { + tmp_edits.resize(tmp_edits.size() - tmp_mm); + tmp_mm = 0; + } + + // Update and find Haplotypes + EList >& ht_list = ht_llist[dep]; + ht_list.clear(); + if(gpol.useHaplotype() && haplotypes.size() > 0) { + if(dep > 0) { + EList >& ht_prev_list = ht_llist[dep-1]; + for(index_t p = 0; p < ht_prev_list.size(); p++) { + const pair& ht_ref = ht_prev_list[p]; + const Haplotype& ht = haplotypes[ht_ref.first]; + if(ht_ref.second < ht.alts.size()) { + index_t alt_id = ht.alts[ht_ref.second]; + assert_gt(tmp_edits.size(), 0); + const ALT& alt = alts[tmp_edits.back().snpID]; + const ALT& ht_alt = alts[alt_id]; + if(!alt.isSame(ht_alt)) continue; + } + if(ht_ref.second + 1 >= ht.alts.size() && joinedOff > ht.right) { + cmp_ht.left = cmp_ht.right = joinedOff; + add_haplotypes(alts, + haplotypes, + haplotype_maxrights, + cmp_ht, + ht_list, + rdlen, + false); // left_ext? + } else { + ht_list.push_back(ht_ref); + ht_list.back().second++; + } + } + } + if(ht_list.size() <= 0) { + cmp_ht.left = cmp_ht.right = joinedOff; + add_haplotypes(alts, + haplotypes, + haplotype_maxrights, + cmp_ht, + ht_list, + rdlen, + false, // left_ext? + dep == 0 && rdoff_add == 0); // initial? + } + } + + const index_t orig_nedits = (index_t)tmp_edits.size(); + for(; alt_range.first < alt_range.second; alt_range.first++) { + const ALT& alt = alts[alt_range.first]; + if(alt.splicesite()) { + if(alt.left > alt.right) continue; + } + if(alt.exon()) continue; + if(alt.deletion()) { + if(alt.reversed) continue; + } + bool alt_compatible = false; + assert_leq(joinedOff, alt.pos); + index_t rf_i, rd_i; + rf_i = rd_i = alt.pos - joinedOff; + if(rd_i >= rdlen) continue; + assert_leq(rd_i, max_rd_i); + int rf_bp = get_ref_base(threeN, refConversion_3N, rfseq[rf_i]); + int rd_bp = rdseq[rdoff + rd_i]; + + // Check to see if there is a haplotype that supports this alt + if(ht_list.size() > 0 && alt.snp()) { + bool ht_found = false; + for(index_t h = 0; h < ht_list.size(); h++) { + const pair& ht_ref = ht_list[h]; + const Haplotype& ht = haplotypes[ht_ref.first]; + if(ht_ref.second >= ht.alts.size()) + continue; + index_t ht_alti = ht.alts[ht_ref.second]; + const ALT& ht_alt = alts[ht_alti]; + if(alts[alt_range.first].isSame(ht_alt)) { + ht_found = true; + break; + } + } + if(!ht_found) continue; + } + + if(alt.type == ALT_SNP_SGL) { + if(rd_bp == (int)alt.seq) { + Edit e( + rd_i + rdoff_add, + "ACGTN"[rf_bp], + "ACGTN"[rd_bp], + EDIT_TYPE_MM, + true, /* chars? */ + alt_range.first); + tmp_edits.push_back(e); + rd_i++; + rf_i++; + alt_compatible = true; + } + } else if(alt.type == ALT_SNP_DEL) { + bool try_del = rd_i > 0; + if(rd_i == 0 && dep > 0) { + // Avoid consecutive deletions + assert_gt(tmp_edits.size(), 0); + const Edit& e = tmp_edits.back(); + if(e.type != EDIT_TYPE_READ_GAP) { + try_del = true; + } + } + if(try_del) { + if(rf_i + alt.len <= rflen) { + for(index_t i = 0; i < alt.len; i++) { + rf_bp = get_ref_base(threeN, refConversion_3N, rfseq[rf_i + i]); + Edit e( + rd_i + rdoff_add, + "ACGTN"[rf_bp], + '-', + EDIT_TYPE_READ_GAP, + true, /* chars? */ + alt_range.first); + tmp_edits.push_back(e); + } + rf_i += alt.len; + alt_compatible = true; + } else { + // long deletions + index_t new_rflen = rf_i + alt.len + 10; + if(raw_refbufs.size() <= dep + 1) raw_refbufs.expand(); + SStringExpandable& raw_refbuf = raw_refbufs[dep + 1]; + raw_refbuf.resize(new_rflen + 16 + 16); + raw_refbuf.fill(0x4); + int off = ref.getStretch( + reinterpret_cast(raw_refbuf.wbuf() + 16), + tidx, + max(rfoff, 0), + rfoff > 0 ? new_rflen : new_rflen + rfoff + ASSERT_ONLY(, destU32)); + assert_lt(off, 16); + const char* new_rfseq = raw_refbuf.wbuf() + 16 + off + min(rfoff, 0); + for(index_t i = 0; i < alt.len; i++) { + rf_bp = get_ref_base(threeN, refConversion_3N, new_rfseq[rf_i + i]); + Edit e( + rd_i + rdoff_add, + "ACGTN"[rf_bp], + '-', + EDIT_TYPE_READ_GAP, + true, /* chars? */ + alt_range.first); + tmp_edits.push_back(e); + } + rf_i += alt.len; + alt_compatible = true; + } + } + } else if(alt.type == ALT_SNP_INS) { + if(rd_i + alt.len <= rdlen && rf_i > 0) { + bool same_seq = true; + for(index_t i = 0; i < alt.len; i++) { + rd_bp = rdseq[rdoff + rd_i + i]; + int snp_bp = (alt.seq >> ((alt.len - i - 1) << 1)) & 0x3; + if(rd_bp != snp_bp) { + same_seq = false; + break; + } + Edit e( + rd_i + i + rdoff_add, + '-', + "ACGTN"[rd_bp], + EDIT_TYPE_REF_GAP, + true, /* chars? */ + alt_range.first); + tmp_edits.push_back(e); + } + if(same_seq) { + rd_i += alt.len; + alt_compatible = true; + } + } + } else if(alt.type == ALT_SPLICESITE) { + bool try_splice = rd_i > 0; + if(rd_i == 0 && dep > 0) { + // Avoid consecutive introns + assert_gt(tmp_edits.size(), 0); + const Edit& e = tmp_edits.back(); + if(e.type != EDIT_TYPE_SPL) { + try_splice = true; + } + } + if(try_splice) { + assert_lt(rd_i, rflen); + index_t intronLen = alt.right - alt.left + 1; + Edit e(rd_i + rdoff_add, + 0, + 0, + EDIT_TYPE_SPL, + intronLen, + alt.fw ? SPL_FW : SPL_RC, + true, /* known splice site? */ + false); /* chrs? */ + tmp_edits.push_back(e); + alt_compatible = true; + } + } + if(alt_compatible) { + numALTsTried++; + if(rd_i == rdlen) { + assert_leq(best_rdoff, rdoff + rd_i); + if(best_rdoff < rdoff + rd_i) { + if(candidate_edits != NULL) candidate_edits->clear(); + } + if(candidate_edits != NULL) { + candidate_edits->expand(); + candidate_edits->back() = tmp_edits; + } + best_rdoff = rdoff + rd_i; + edits = tmp_edits; + return rd_i; + } + index_t next_joinedOff = 0; + int next_rfoff = rfoff + rf_i, next_rdoff = rdoff + rd_i; + const char* next_rfseq = rfseq + rf_i; + index_t next_rflen = rflen - rf_i, next_rdlen = rdlen - rd_i; + if(alt.type == ALT_SNP_SGL) { + next_joinedOff = alt.pos + 1; + } else if(alt.type == ALT_SNP_DEL) { + next_joinedOff = alt.pos + alt.len; + if(rflen <= rf_i) { + next_rflen = 0; // Will reset next_rfseq and next_rflen below + } + } else if(alt.type == ALT_SNP_INS) { + next_joinedOff = alt.pos; + } else if(alt.type == ALT_SPLICESITE) { + next_joinedOff = alt.right + 1; + index_t intronLen = alt.right - alt.left + 1; + next_rfoff += intronLen; + next_rfseq = NULL; + } else { + assert(false); + } + if(next_rflen < next_rdlen) { + next_rflen = next_rdlen + 10; + next_rfseq = NULL; + } + index_t alignedLen = alignWithALTs_recur( + alts, + haplotypes, + haplotype_maxrights, + next_joinedOff, + rdseq, + rdoff_add + rd_i, + next_rdoff, + next_rdlen, + ref, + raw_refbufs, + ASSERT_ONLY(destU32,) + tmp_edits, + best_rdoff, + next_rfseq, + tidx, + next_rfoff, + next_rflen, + left, + edits, + mm, + ht_llist, + cmp_ht, + candidate_edits, + tmp_numNs, + numNs, + dep + 1, + gpol, + numALTsTried, + cycle_3N, + alt.type); + if(alignedLen > 0) { + assert_leq(rdoff + rd_i + alignedLen, best_rdoff); + bool search_further = false; + if(alt.splicesite()) { + for(index_t sf = alt_range.first + 1; sf < alt_range.second; sf++) { + const ALT& alt2 = alts[sf]; + if(alt2.splicesite() && alt2.left < alt2.right) { + search_further = true; + break; + } + } + } + if(!search_further) { + if(rd_i + alignedLen == rdlen) { + return rd_i + alignedLen; + } + } + } + } + + // Restore to the earlier state + assert_leq(orig_nedits, tmp_edits.size()); + if(orig_nedits < tmp_edits.size()) tmp_edits.resize(orig_nedits); + } + return 0; + } +} + + +/** + * For alignment involving indel, move the indels + * to the left most possible position + */ +template +void GenomeHit::leftAlign(const Read& rd) +{ + ASSERT_ONLY(const index_t rdlen = (index_t)rd.length()); + const BTDnaString& seq = _fw ? rd.patFw : rd.patRc; + for(index_t ei = 0; ei < _edits->size(); ei++) { + Edit& edit = (*_edits)[ei]; + if(edit.type != EDIT_TYPE_READ_GAP && edit.type != EDIT_TYPE_REF_GAP) + continue; + if(edit.snpID != (index_t)INDEX_MAX) + continue; + index_t ei2 = ei + 1; + for(; ei2 < _edits->size(); ei2++) { + const Edit& edit2 = (*_edits)[ei2]; + if(edit2.type != edit.type) break; + if(edit.type == EDIT_TYPE_READ_GAP) { + if(edit.pos != edit2.pos) break; + } else { + assert_eq(edit.type, EDIT_TYPE_REF_GAP); + if(edit.pos + ei2 - ei != edit2.pos) break; + } + } + assert_gt(ei2, 0); + ei2 -= 1; + Edit& edit2 = (*_edits)[ei2]; + int b = 0; + if(ei > 0) { + const Edit& prev_edit = (*_edits)[ei - 1]; + b = prev_edit.pos; + } + int l = edit.pos - 1; + while(l > b) { + assert_lt(l, (int)rdlen); + int rdc = seq[_rdoff + l]; + assert_range(0, 4, rdc); + char rfc = (edit.type == EDIT_TYPE_READ_GAP ? edit2.chr : edit2.qchr); + if(rfc != "ACGTN"[rdc]) break; + for(int ei3 = ei2; ei3 > (int)ei; ei3--) { + if(edit.type == EDIT_TYPE_READ_GAP) { + (*_edits)[ei3].chr = (*_edits)[ei3 - 1].chr; + } else { + (*_edits)[ei3].qchr = (*_edits)[ei3 - 1].qchr; + } + (*_edits)[ei3].pos -= 1; + } + rdc = seq[_rdoff + l]; + assert_range(0, 4, rdc); + if(edit.type == EDIT_TYPE_READ_GAP) { + edit.chr = "ACGTN"[rdc]; + } else { + edit.qchr = "ACGTN"[rdc]; + } + edit.pos -= 1; + l--; + } + ei = ei2; + } +} + +#ifndef NDEBUG +/** + * Check that hit is sane w/r/t read. + */ +template +bool GenomeHit::repOk(const Read& rd, const BitPairReference& ref) +{ + if(_len <= 0) return true; + assert(_sharedVars != NULL); + SStringExpandable& raw_refbuf = _sharedVars->raw_refbuf; + SStringExpandable& destU32 = _sharedVars->destU32; + + BTDnaString& editstr = _sharedVars->editstr; + BTDnaString& partialseq = _sharedVars->partialseq; + BTDnaString& refstr = _sharedVars->refstr; + EList& reflens = _sharedVars->reflens; + EList& refoffs = _sharedVars->refoffs; + + editstr.clear(); partialseq.clear(); refstr.clear(); + reflens.clear(); refoffs.clear(); + + const BTDnaString& seq = _fw ? rd.patFw : rd.patRc; + partialseq.install(seq.buf() + this->_rdoff, (size_t)this->_len); + Edit::toRef(partialseq, *_edits, editstr); + + index_t refallen = 0; + int64_t reflen = 0; + int64_t refoff = this->_toff; + refoffs.push_back((index_t)refoff); + size_t eidx = 0; + for(size_t i = 0; i < _len; i++, reflen++, refoff++) { + while(eidx < _edits->size() && (*_edits)[eidx].pos == i) { + const Edit& edit = (*_edits)[eidx]; + if(edit.isReadGap()) { + reflen++; + refoff++; + } else if(edit.isRefGap()) { + reflen--; + refoff--; + } + if(edit.isSpliced()) { + assert_gt(reflen, 0); + refallen += reflen; + reflens.push_back((index_t)reflen); + reflen = 0; + refoff += edit.splLen; + assert_gt(refoff, 0); + refoffs.push_back((index_t)refoff); + } + eidx++; + } + } + assert_gt(reflen, 0); + refallen += (index_t)reflen; + reflens.push_back((index_t)reflen); + assert_gt(reflens.size(), 0); + assert_gt(refoffs.size(), 0); + assert_eq(reflens.size(), refoffs.size()); + refstr.clear(); + + int refConversion_3N[5] = {0, 1, 2, 3, 4}; + if (threeN){ + if (((rd.threeN_cycle == threeN_type1conversion_FW || rd.threeN_cycle == threeN_type2conversion_RC) && !rd.oppositeConversion_3N) || + ((rd.threeN_cycle == threeN_type1conversion_RC || rd.threeN_cycle == threeN_type2conversion_FW) && rd.oppositeConversion_3N)) { + // type 1 conversion + refConversion_3N[asc2dna[hs3N_convertedFrom]] = asc2dna[hs3N_convertedTo]; + } else { + // type 2 conversion + refConversion_3N[asc2dna[hs3N_convertedFromComplement]] = asc2dna[hs3N_convertedToComplement]; + } + } + + for(index_t i = 0; i < reflens.size(); i++) { + assert_gt(reflens[i], 0); + if(i > 0) { + assert_gt(refoffs[i], refoffs[i-1]); + } + raw_refbuf.resize(reflens[i] + 16); + raw_refbuf.clear(); + int off = ref.getStretch( + reinterpret_cast(raw_refbuf.wbuf()), + (size_t)this->_tidx, + (size_t)max(refoffs[i], 0), + reflens[i], + destU32); + assert_leq(off, 16); + for(index_t j = 0; j < reflens[i]; j++) { + char rfc = refConversion_3N[*(raw_refbuf.buf()+off+j)]; + refstr.append(rfc); + } + char* bufA = raw_refbuf.wbuf() + off; + string test_string = ""; + string bases = "ACGTN"; + for (int k = 0; k < reflens[i]; k++) { + int a = bufA[k]; + test_string += bases[a]; + } + } + if(refstr != editstr) { + cerr << "Decoded nucleotides and edits don't match reference:" << endl; + //cerr << " score: " << score.score() + //<< " (" << gaps << " gaps)" << endl; + cerr << " edits: "; + Edit::print(cerr, *_edits); + cerr << endl; + cerr << " decoded nucs: " << partialseq << endl; + cerr << " edited nucs: " << editstr << endl; + cerr << " reference nucs: " << refstr << endl; + assert(0); + } + + return true; +} +#endif + +/** + * Calculate alignment score + */ +template +int64_t GenomeHit::calculateScore( + const Read& rd, + SpliceSiteDB& ssdb, + const Scoring& sc, + index_t minK_local, + index_t minIntronLen, + index_t maxIntronLen, + index_t minAnchorLen, + index_t minAnchorLen_noncan, + const BitPairReference& ref) +{ + int64_t score = 0; + double splicescore = 0; + int64_t localscore = 0; + index_t numsplices = 0; + index_t mm = 0; + const BTDnaString& seq = _fw ? rd.patFw : rd.patRc; + const BTString& qual = _fw ? rd.qual : rd.qualRev; + index_t rdlen = (index_t)seq.length(); + int64_t toff_base = _toff; + bool conflict_splicesites = false; + uint8_t whichsense = SPL_UNKNOWN; + for(index_t i = 0; i < _edits->size(); i++) { + const Edit& edit = (*_edits)[i]; + assert_lt(edit.pos, _len); + if(edit.type == EDIT_TYPE_MM) { + if(edit.snpID == std::numeric_limits::max()) { + int pen = sc.score( + dna2col[edit.qchr] - '0', + asc2dnamask[edit.chr], + qual[this->_rdoff + edit.pos] - 33); + score += pen; + mm++; + } + } else if(edit.type == EDIT_TYPE_SPL) { + // int left = toff_base + edit.pos - 1; + // assert_geq(left, 0); + // int right = left + edit.splLen + 1; + // assert_geq(right, 0); + if(!edit.knownSpl) { + int left_anchor_len = _rdoff + edit.pos; + assert_gt(left_anchor_len, 0); + assert_lt(left_anchor_len, (int)rdlen); + int right_anchor_len = rdlen - left_anchor_len; + index_t mm2 = 0; + for(index_t j = i + 1; j < _edits->size(); j++) { + const Edit& edit2 = (*_edits)[j]; + if(edit2.type == EDIT_TYPE_MM || + edit2.type == EDIT_TYPE_READ_GAP || + edit2.type == EDIT_TYPE_REF_GAP) mm2++; + } + left_anchor_len -= (mm * 2); + right_anchor_len -= (mm2 * 2); + int shorter_anchor_len = min(left_anchor_len, right_anchor_len); + if(shorter_anchor_len <= 0) shorter_anchor_len = 1; + assert_gt(shorter_anchor_len, 0); + uint32_t intronLen_thresh = ((edit.splDir == SPL_FW || edit.splDir == SPL_RC) ? + MaxIntronLen(shorter_anchor_len, minAnchorLen) : + MaxIntronLen_noncan(shorter_anchor_len, minAnchorLen_noncan)); + if(intronLen_thresh < maxIntronLen) { + if(edit.splLen > intronLen_thresh) { + score += MIN_I32; + } + + if(edit.splDir == SPL_FW || edit.splDir == SPL_RC) { + float probscore = ssdb.probscore(edit.donor_seq, edit.acceptor_seq); + + float probscore_thresh = 0.8f; + if(edit.splLen >> 16) probscore_thresh = 0.99f; + else if(edit.splLen >> 15) probscore_thresh = 0.97f; + else if(edit.splLen >> 14) probscore_thresh = 0.94f; + else if(edit.splLen >> 13) probscore_thresh = 0.91f; + else if(edit.splLen >> 12) probscore_thresh = 0.88f; + if(probscore < probscore_thresh) score += MIN_I32; + } + if(shorter_anchor_len == left_anchor_len) { + if(_trim5 > 0) score += MIN_I32; + for(int j = (int)i - 1; j >= 0; j--) { + if((*_edits)[j].type == EDIT_TYPE_MM || + (*_edits)[j].type == EDIT_TYPE_READ_GAP || + (*_edits)[j].type == EDIT_TYPE_REF_GAP) + score += MIN_I32; + } + } else { + if(_trim3 > 0) score += MIN_I32; + for(index_t j = i + 1; j < _edits->size(); j++) { + if((*_edits)[j].type == EDIT_TYPE_MM || + (*_edits)[j].type == EDIT_TYPE_READ_GAP || + (*_edits)[j].type == EDIT_TYPE_REF_GAP) + score += MIN_I32; + } + } + } + + if(edit.snpID == std::numeric_limits::max()) { + if(edit.splDir == SPL_FW || edit.splDir == SPL_RC) { + score -= sc.canSpl((int)edit.splLen); + } else { + score -= sc.noncanSpl((int)edit.splLen); + } + } + + // daehwan - for debugging purposes + if(shorter_anchor_len <= 15) { + numsplices += 1; + splicescore += (double)edit.splLen; + } + } + + if(!conflict_splicesites) { + if(whichsense == SPL_UNKNOWN) { + whichsense = edit.splDir; + } else if(edit.splDir != SPL_UNKNOWN) { + assert_neq(whichsense, SPL_UNKNOWN); + if(edit.splDir == SPL_FW || edit.splDir == SPL_SEMI_FW) { + if(whichsense != SPL_FW && whichsense != SPL_SEMI_FW) { + conflict_splicesites = true; + } + } + if(edit.splDir == SPL_RC || edit.splDir == SPL_SEMI_RC) { + if(whichsense != SPL_RC && whichsense != SPL_SEMI_RC) { + conflict_splicesites = true; + } + } + } + } + + toff_base += edit.splLen; + } else if(edit.type == EDIT_TYPE_READ_GAP) { + bool open = true; + if(i > 0 && + (*_edits)[i-1].type == EDIT_TYPE_READ_GAP && + (*_edits)[i-1].pos == edit.pos) { + open = false; + } + if(edit.snpID == std::numeric_limits::max()) { + if(open) score -= sc.readGapOpen(); + else score -= sc.readGapExtend(); + } + toff_base++; + } else if(edit.type == EDIT_TYPE_REF_GAP) { + bool open = true; + if(i > 0 && + (*_edits)[i-1].type == EDIT_TYPE_REF_GAP && + (*_edits)[i-1].pos + 1 == edit.pos) { + open = false; + } + if(edit.snpID == std::numeric_limits::max()) { + if(open) score -= sc.refGapOpen(); + else score -= sc.refGapExtend(); + } + toff_base--; + } +#ifndef NDEBUG + else { + assert(false); + } +#endif + } + + // Penalty for soft-clipping + for(index_t i = 0; i < _trim5; i++) { + score -= sc.sc(qual[i]); + } + + for(index_t i = 0; i < _trim3; i++) { + score -= sc.sc(qual[i]); + } + + if(conflict_splicesites) { + score -= sc.conflictSpl(); + } + + if (numsplices > 1) splicescore /= (double)numsplices; + score += (_len - mm) * sc.match(); + _score = score; + _splicescore = splicescore; + _localscore = localscore; + + return score; +} + +/** + * Encapsulates counters that measure how much work has been done by + * hierarchical indexing + */ +struct HIMetrics { + + HIMetrics() : mutex_m() { + reset(); + } + + void reset() { + anchoratts = 0; + localatts = 0; + localindexatts = 0; + localextatts = 0; + localsearchrecur = 0; + globalgenomecoords = 0; + localgenomecoords = 0; + } + + void init( + uint64_t localatts_, + uint64_t anchoratts_, + uint64_t localindexatts_, + uint64_t localextatts_, + uint64_t localsearchrecur_, + uint64_t globalgenomecoords_, + uint64_t localgenomecoords_) + { + localatts = localatts_; + anchoratts = anchoratts_; + localindexatts = localindexatts_; + localextatts = localextatts_; + localsearchrecur = localsearchrecur_; + globalgenomecoords = globalgenomecoords_; + localgenomecoords = localgenomecoords_; + } + + /** + * Merge (add) the counters in the given HIMetrics object into this + * object. This is the only safe way to update a HIMetrics shared + * by multiple threads. + */ + void merge(const HIMetrics& r, bool getLock = false) { + ThreadSafe ts(&mutex_m, getLock); + localatts += r.localatts; + anchoratts += r.anchoratts; + localindexatts += r.localindexatts; + localextatts += r.localextatts; + localsearchrecur += r.localsearchrecur; + globalgenomecoords += r.globalgenomecoords; + localgenomecoords += r.localgenomecoords; + } + + uint64_t localatts; // # attempts of local search + uint64_t anchoratts; // # attempts of anchor search + uint64_t localindexatts; // # attempts of local index search + uint64_t localextatts; // # attempts of extension search + uint64_t localsearchrecur; + uint64_t globalgenomecoords; + uint64_t localgenomecoords; + + MUTEX_T mutex_m; +}; + +/** + * With a hierarchical indexing, SplicedAligner provides several alignment strategies + * , which enable effective alignment of RNA-seq reads + */ +template +class HI_Aligner { + +public: + + /** + * Initialize with index. + */ + HI_Aligner( + const GFM& gfm, + bool anchorStop = true, + uint64_t threads_rids_mindist = 0) : + _anchorStop(anchorStop), + _gwstate(GW_CAT), + _gwstate_local(GW_CAT), + _thread_rids_mindist(threads_rids_mindist) + { + index_t genomeLen = gfm.gh().len(); + _minK = 0; + while(genomeLen > 0) { + genomeLen >>= 2; + _minK++; + } + _minK_local = 8; + + } + + + HI_Aligner() { + } + + /** + */ + void initRead(Read *rd, bool nofw, bool norc, TAlScore minsc, TAlScore maxpen, bool rightendonly = false) { + assert(rd != NULL); + _rds[0] = rd; + _rds[1] = NULL; + _paired = false; + _rightendonly = rightendonly; + _nofw[0] = nofw; + _nofw[1] = true; + _norc[0] = norc; + _norc[1] = true; + _minsc[0] = minsc; + _minsc[1] = INDEX_MAX; + _maxpen[0] = maxpen; + _maxpen[1] = INDEX_MAX; + for(size_t fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + _hits[0][fwi].init(fw, (index_t)_rds[0]->length()); + } + _genomeHits.clear(); + _genomeHits_rep[0].clear(); + _hits_searched[0].clear(); + assert(!_paired); + } + + /** + */ + void initReads(Read *rds[2], bool nofw[2], bool norc[2], TAlScore minsc[2], TAlScore maxpen[2]) { + assert(rds[0] != NULL && rds[1] != NULL); + _paired = true; + _rightendonly = false; + for(size_t rdi = 0; rdi < 2; rdi++) { + _rds[rdi] = rds[rdi]; + _nofw[rdi] = nofw[rdi]; + _norc[rdi] = norc[rdi]; + _minsc[rdi] = minsc[rdi]; + _maxpen[rdi] = maxpen[rdi]; + for(size_t fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + _hits[rdi][fwi].init(fw, (index_t)_rds[rdi]->length()); + } + _hits_searched[rdi].clear(); + } + _genomeHits.clear(); + _genomeHits_rep[0].clear(); + _genomeHits_rep[1].clear(); + _concordantIdxInspected.first = _concordantIdxInspected.second = 0; + assert(_paired); + assert(!_rightendonly); + } + + /** + * Aligns a read or a pair + * This funcion is called per read or pair + */ + virtual + int go( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const GFM* rgfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const ALTDB& raltdb, + const BitPairReference& ref, + const BitPairReference* rref, + SwAligner& swa, + SpliceSiteDB& ssdb, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) + { + const ReportingParams& rp = sink.reportingParams(); + + index_t rdi; + bool fw; + bool found[2][2] = {{true, true}, {this->_paired, this->_paired}}; + // given read and its reverse complement + // (and mate and the reverse complement of mate in case of pair alignment), + // pick up one with best partial alignment + while(nextBWT(sc, pepol, tpol, gpol, gfm, altdb, ref, rdi, fw, wlm, prm, him, rnd, sink)) { + // given the partial alignment, try to extend it to full alignments + index_t fwi = (fw == true ? 0 : 1); + found[rdi][fwi] = align(sc, pepol, tpol, gpol, gfm, altdb, repeatdb, ref, swa, ssdb, rdi, fw, wlm, prm, swm, him, rnd, sink); + if(!found[0][0] && !found[0][1] && !found[1][0] && !found[1][1]) { + break; + } + + // try to combine this alignment with some of mate alignments + // to produce pair alignment + if(this->_paired) { + pairReads(sc, pepol, tpol, gpol, gfm, altdb, repeatdb, ref, wlm, prm, him, rnd, sink); + // if(sink.bestPair() >= _minsc[0] + _minsc[1]) break; + } + } + + // if no concordant pair is found, try to use alignment of one-end + // as an anchor to align the other-end + if(this->_paired) { + if(sink.numPair() == 0 && + (sink.bestUnp1() >= _minsc[0] || sink.bestUnp2() >= _minsc[1])) { + bool mate_found = false; + const EList *rs[2] = {NULL, NULL}; + sink.getUnp1(rs[0]); assert(rs[0] != NULL); + sink.getUnp2(rs[1]); assert(rs[1] != NULL); + index_t rs_size[2] = {(index_t)rs[0]->size(), (index_t)rs[1]->size()}; + for(index_t i = 0; i < 2; i++) { + for(index_t j = 0; j < rs_size[i]; j++) { + const AlnRes& res = (*rs[i])[j]; + bool fw = (res.orient() == 1); + mate_found |= alignMate( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + i, + fw, + wlm, + prm, + swm, + him, + rnd, + sink, + (index_t)res.refid(), + (index_t)res.refoff()); + } + } + + if(mate_found) { + pairReads( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + wlm, + prm, + him, + rnd, + sink); + } + } + } + + + // Determine whether reads map to repetitive sequences + bool repeat[2][2] = {{false, false}, {false, false}}; + bool perform_repeat_alignment = false; + + index_t indexIdx[2] = {0, 0}; + +#if 1 + if(rgfm != NULL && !((RFM*)rgfm)->empty()) { + + // use repeat index to decide whether a read or a pair is from repetitive sequences + indexIdx[0] = ((RFM*)rgfm)->getLocalRFM_idx((*_rds)[0].length()); + if(_paired) { + indexIdx[1] = ((RFM*)rgfm)->getLocalRFM_idx((*_rds)[1].length()); + } + LocalRFM& rfm = ((RFM*)rgfm)->getLocalRFM(indexIdx[0]); + bool skip_repeat[2][2] = {{false, false}, {false, false}}; + if(_paired) { + const EList *rs[2] = {NULL, NULL}; + sink.getPair(rs[0], rs[1]); + assert_eq(rs[0]->size(), rs[1]->size()); + TAlScore bestScore[2][2] = {{_minsc[rdi], _minsc[rdi]}, {_minsc[rdi], _minsc[rdi]}}; + for(size_t r = 0; r < rs[0]->size(); r++) { + const AlnRes& rs1 = (*rs[0])[r]; + const AlnRes& rs2 = (*rs[1])[r]; + TAlScore score = rs1.score().score() + rs2.score().score(); + int fwi[2] = {rs1.fw() ? 0 : 1, rs2.fw() ? 0 : 1}; + if(score > bestScore[fwi[0]][fwi[1]]) { + bestScore[fwi[0]][fwi[1]] = score; + } + } + for(index_t fwi = 0; fwi < 2; fwi++) { + for(index_t fwi2 = 0; fwi2 < 2; fwi2++) { + if(bestScore[fwi][fwi2] < 0) + continue; + + ReadBWTHit& hit = _hits[0][fwi]; + bool unique = false; + for(size_t hi = 0; hi < hit.offsetSize(); hi++) { + BWTHit& partialHit = hit.getPartialHit(hi); + if(partialHit.len() >= _minK + 8 && partialHit.size() == 1) { + unique = true; + break; + } + } + if(!unique) + continue; + + bool unique2 = false; + ReadBWTHit& hit2 = _hits[1][fwi2]; + for(size_t hi = 0; hi < hit2.offsetSize(); hi++) { + BWTHit& partialHit = hit2.getPartialHit(hi); + if(partialHit.len() >= _minK + 8 && partialHit.size() == 1) { + unique2 = true; + break; + } + } + if(!unique2) + continue; + + skip_repeat[0][fwi] = skip_repeat[1][fwi2] = true; + } + } + } else { + const EList *rs = NULL; + if(rdi == 0) sink.getUnp1(rs); + else sink.getUnp2(rs); + + TAlScore bestScore[2] = {_minsc[rdi], _minsc[rdi]}; + for(index_t r = 0; r < rs->size(); r++) { + TAlScore score = (*rs)[r].score().score(); + if((*rs)[r].fw()) { + if(score > bestScore[0]) { + bestScore[0] = score; + } + } else { + if(score > bestScore[1]) { + bestScore[1] = score; + } + } + } + for(index_t fwi = 0; fwi < 2; fwi++) { + if(bestScore[fwi] < 0) + continue; + + ReadBWTHit& hit = _hits[rdi][fwi]; + index_t offsetSize = hit.offsetSize(); + for(size_t hi = 0; hi < offsetSize; hi++) { + BWTHit& partialHit = hit.getPartialHit(hi); + if(partialHit.len() >= _minK + 8 && partialHit.size() == 1) { + skip_repeat[rdi][fwi] = true; + break; + } + } + if(skip_repeat[rdi][fwi]) break; + } + } + + for(size_t rdi = 0; rdi < (_paired ? 2 : 1); rdi++) { + for(size_t fwi = 0; fwi < 2; fwi++) { + if(skip_repeat[rdi][fwi]) continue; + bool fw = (fwi == 0); + _hits[rdi][fwi].init(fw, (index_t)_rds[rdi]->length()); + } + } + + while(nextBWT(sc, pepol, tpol, gpol, rfm, altdb, *rref, rdi, fw, wlm, prm, him, rnd, sink)); + for(size_t rdi = 0; rdi < (_paired ? 2 : 1); rdi++) { + for(size_t fwi = 0; fwi < 2; fwi++) { + if(skip_repeat[rdi][fwi]) continue; + ReadBWTHit& hit = _hits[rdi][fwi]; + index_t offsetSize = hit.offsetSize(); + //assert_gt(offsetSize, 0); + for(size_t hi = 0; hi < offsetSize; hi++) { + BWTHit& partialHit = hit.getPartialHit(hi); + if(partialHit.len() >= (rref->getMinK() << 1)) { + repeat[rdi][fwi] = true; + perform_repeat_alignment = true; + break; + } + } + } + } + } +#else + // use minimizer to decide whether a read or a pair is from repetitive sequences + perform_repeat_alignment = false; + for(size_t rdi = 0; rdi < (_paired ? 2 : 1); rdi++) { + Read& read = *_rds[rdi]; + for(size_t fwi = 0; fwi < 2; fwi++) { + const BTDnaString& seq = (fwi == 0 ? read.patFw : read.patRc); + repeat[rdi][fwi] = repeat_kmertable.isRepeat(seq, _tmp_minimizers); + perform_repeat_alignment |= repeat[rdi][fwi]; + } + } +#endif + + // Handle alignment to repetitive regions + if(rgfm != NULL && + perform_repeat_alignment) { + LocalRFM& rfm = ((RFM*)rgfm)->getLocalRFM(indexIdx[0]); + RB_KmerTable& repeatKmertable = ((RFM*)rgfm)->getKmertable(indexIdx[0]); + + _repeatConcordant.clear(); + index_t prev_align_size[2] = {0, 0}; + for(size_t rdi = 0; rdi < (_paired ? 2 : 1); rdi++) { + const EList *rs = NULL; + if(rdi == 0) sink.getUnp1(rs); + else sink.getUnp2(rs); + prev_align_size[rdi] = rs->size(); + } + + for(size_t rdi = 0; rdi < (_paired ? 2 : 1); rdi++) { + for(size_t fwi = 0; fwi < 2; fwi++) { + if(!repeat[rdi][fwi]) continue; + + // choose candidate partial alignments for further alignment + index_t maxsize = max(rp.khits, rp.kseeds); + +#if 0 + ReadBWTHit& hit = _hits[rdi][fwi]; + if(!hit.done()) continue; + getAnchorHits(rfm, + pepol, + tpol, + gpol, + altdb, + repeatdb, + *rref, + rnd, + rdi, + fwi == 0, // fw + _genomeHits_rep[rdi], + _genomeHits_rep[rdi].size() + maxsize, + _sharedVars, + wlm, + prm, + him, + true); // repeat? +#else + + getRepeatHits(rfm, + pepol, + tpol, + gpol, + raltdb, + repeatdb, + repeatKmertable, + *rref, + rnd, + rdi, + fwi == 0, // fw + indexIdx[0], + _genomeHits_rep[rdi], + _genomeHits_rep[rdi].size() + maxsize, + _sharedVars, + sc, + swa, + ssdb, + swm, + wlm, + prm, + him, + sink); +#endif + } + } + + EList, RepeatCoord > >& positions = _positions; + for(size_t rdi = 0; rdi < (_paired ? 2 : 1); rdi++) { + for(size_t i = 0; i < _genomeHits_rep[rdi].size(); i++) { + if(_genomeHits_rep[rdi][i].len() < (_minK << 1)) continue; + + // DK - debugging purposes +#if 0 + positions.clear(); + repeatdb.getCoords(_genomeHits_rep[rdi][i]._tidx, + _genomeHits_rep[rdi][i]._joinedOff, + _genomeHits_rep[rdi][i]._joinedOff + _genomeHits_rep[rdi][i].len(), + _snpIDs, + raltdb, + positions, + rp.khits * 1000); +#endif + + const EList *rs = NULL; + if(rdi == 0) sink.getUnp2(rs); + else sink.getUnp1(rs); + assert(rs != NULL); + + bool candidate_found = false; + for(size_t j = 0; j < prev_align_size[1-rdi]; j++) { + const AlnRes& res = (*rs)[j]; + if(res.repeat()) + continue; + + TAlScore estScore = res.score().score() + _genomeHits_rep[rdi][i].score(); + if(sink.bestPair() >= estScore && sink.numBestPair().first > rp.khits) + break; + + positions.clear(); + index_t joinedOff = 0; + gfm.textOffToJoined(res.refid(), res.refoff(), joinedOff); + repeatdb.findCoords(joinedOff, + joinedOff + res.refExtent(), + _genomeHits_rep[rdi][i]._tidx, + _genomeHits_rep[rdi][i]._joinedOff, + _genomeHits_rep[rdi][i]._joinedOff + _genomeHits_rep[rdi][i].len(), + _snpIDs, + raltdb, + positions, + rp.khits * 10); + if(positions.size() <= 0) + continue; + + for(size_t p = 0; p < positions.size(); p++) { + if(positions[p].first.tid != res.refid()) continue; + if(positions[p].first.toff + 1000 < res.refoff() || + res.refoff() + 1000 < positions[p].first.toff) continue; + if(sink.bestPair() >= estScore && sink.numBestPair().first > rp.khits) + break; + + candidate_found = true; + + _genomeHits.clear(); + _genomeHits.expand(); + _genomeHits.back() = _genomeHits_rep[rdi][i]; + _genomeHits.back()._tidx = positions[p].first.tid; + _genomeHits.back()._toff = positions[p].first.toff; + _genomeHits.back()._joinedOff = positions[p].first.joinedOff; + if(!positions[p].first.fw) { + _genomeHits.back().reverse(*_rds[rdi]); + _rds[rdi]->oppositeConversion_3N = true; + } else { + _rds[rdi]->oppositeConversion_3N = false; + } + + // extend the partial alignments bidirectionally using + // local search, extension, and (less often) global search + hybridSearch(sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + _genomeHits.back()._fw, + wlm, + prm, + swm, + him, + rnd, + sink); + } + + if(candidate_found) { + pairReads( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + wlm, + prm, + him, + rnd, + sink); + } + } + + if(rdi == 0 && _paired) { + for(size_t j = 0; j < _genomeHits_rep[1].size(); j++) { + if(_genomeHits_rep[1][j].len() < (_minK << 1)) continue; + + TAlScore estScore = _genomeHits_rep[0][i].score() + _genomeHits_rep[1][j].score(); + // if(sink.bestPair() >= estScore && sink.numBestPair().first > rp.khits) + // break; + + positions.clear(); + repeatdb.findCommonCoords(_genomeHits_rep[0][i]._tidx, + _genomeHits_rep[0][i]._joinedOff, + _genomeHits_rep[0][i]._joinedOff + _genomeHits_rep[0][i].len(), + _snpIDs, + _genomeHits_rep[1][j]._tidx, + _genomeHits_rep[1][j]._joinedOff, + _genomeHits_rep[1][j]._joinedOff + _genomeHits_rep[1][j].len(), + _snpIDs2, + raltdb, + positions, + rp.khits * 10); + if(positions.size() <= 0) continue; + + _repeatConcordant.expand(); + _repeatConcordant.back().first = _genomeHits_rep[0][i]._joinedOff; + _repeatConcordant.back().second = _genomeHits_rep[1][j]._joinedOff; + + for(size_t p = 0; p < positions.size(); p++) { + if(sink.bestPair() >= estScore && sink.numBestPair().first > rp.khits) + break; + + _genomeHits.clear(); + _genomeHits.expand(); + _genomeHits.back() = _genomeHits_rep[0][i]; + _genomeHits.back()._tidx = positions[p].first.tid; + _genomeHits.back()._toff = positions[p].first.toff; + _genomeHits.back()._joinedOff = positions[p].first.joinedOff; + if(!positions[p].first.fw) { + _genomeHits.back().reverse(*_rds[0]); + _rds[0]->oppositeConversion_3N = true; + } else { + _rds[0]->oppositeConversion_3N = false; + } + + // extend the partial alignments bidirectionally using + // local search, extension, and (less often) global search + hybridSearch(sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + 0, + _genomeHits.back()._fw, + wlm, + prm, + swm, + him, + rnd, + sink); + + _genomeHits.clear(); + _genomeHits.expand(); + _genomeHits.back() = _genomeHits_rep[1][j]; + _genomeHits.back()._tidx = positions[p].second.tid; + _genomeHits.back()._toff = positions[p].second.toff; + _genomeHits.back()._joinedOff = positions[p].second.joinedOff; + if(!positions[p].second.fw) { + _genomeHits.back().reverse(*_rds[1]); + _rds[1]->oppositeConversion_3N = true; + } else { + _rds[1]->oppositeConversion_3N = false; + } + + // extend the partial alignments bidirectionally using + // local search, extension, and (less often) global search + hybridSearch(sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + 1, + _genomeHits.back()._fw, + wlm, + prm, + swm, + him, + rnd, + sink); + } + + if(positions.size() > 0) { + pairReads( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + wlm, + prm, + him, + rnd, + sink); + } + } + } // if(rdi == 0) + } // for(size_t i = 0; i < _genomeHits_rep[rdi].size() + + bool align2repeat = false; + if(_paired) { + index_t numBestPair = sink.numBestPair().first; + align2repeat = (numBestPair == 0 || numBestPair > rp.khits); + } else { + const EList *rs = NULL; + if(rdi == 0) sink.getUnp1(rs); + else sink.getUnp2(rs); + assert(rs != NULL); + align2repeat = (rs->size() == 0 || sink.numBestUnp(rdi).first > rp.khits); + } + + _rds[0]->oppositeConversion_3N = false; + if (_paired) { + _rds[1]->oppositeConversion_3N = false; + } + + if(align2repeat) { + for(size_t i = 0; i < _genomeHits_rep[rdi].size(); i++) { + _genomeHits.clear(); + _genomeHits.expand(); + _genomeHits.back() = _genomeHits_rep[rdi][i]; + _genomeHits.back()._repeat = true; + hybridSearch(sc, + pepol, + tpol, + gpol, + rfm, + altdb, + repeatdb, + *rref, + swa, + ssdb, + rdi, + _genomeHits.back()._fw, + wlm, + prm, + swm, + him, + rnd, + sink); + } + + if(_paired && rdi == 1) { + if(sink.numBestUnp(rdi).first > rp.khits) { + pairReads( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + wlm, + prm, + him, + rnd, + sink); + } + } + } + + } // for(size_t rdi = 0 + } // repeat + + return EXTEND_POLICY_FULFILLED; + } + + /** + * Given a read or its reverse complement (or mate), + * align the unmapped portion using the global FM index + */ + virtual + bool nextBWT( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + index_t& rdi, + bool& fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) + { + const ReportingParams& rp = sink.reportingParams(); + + // Pick up a candidate from a read or its reverse complement + // (for pair, also consider mate and its reverse complement) + while(pickNextReadToSearch(rdi, fw)) { + size_t mineFw = 0, mineRc = 0; + index_t fwi = (fw ? 0 : 1); + ReadBWTHit& hit = _hits[rdi][fwi]; + assert(!hit.done()); + bool pseudogeneStop = gfm.gh().linearFM() && !tpol.no_spliced_alignment(); + bool anchorStop = _anchorStop && !gfm.repeat(); + if(!rp.secondary) { + index_t numSearched = hit.numActualPartialSearch(); + int64_t bestScore = 0; + if(rdi == 0) { + bestScore = sink.bestUnp1(); + if(bestScore >= _minsc[rdi]) { + // do not further align this candidate + // unless it may be at least as good as the alignment of its reverse complement + index_t maxmm = (index_t)((-bestScore + sc.mmpMax - 1) / sc.mmpMax); + if(numSearched > maxmm + sink.bestSplicedUnp1() + 1) { + hit.done(true); + if(_paired) { + if(sink.bestUnp2() >= _minsc[1-rdi] && + sink.numPair() > 0) return false; + else continue; + } else { + return false; + } + } + } + } else { + assert(_paired); + assert_eq(rdi, 1); + bestScore = sink.bestUnp2(); + if(bestScore >= _minsc[rdi]) { + // Do not further extend this alignment + // unless it may be at least as good as the previous alignemnt + index_t maxmm = (index_t)((-bestScore + sc.mmpMax - 1) / sc.mmpMax); + if(numSearched > maxmm + sink.bestSplicedUnp2() + 1) { + hit.done(true); + if(_paired) { + if(sink.bestUnp1() >= _minsc[1-rdi] && + sink.numPair() > 0) return false; + else continue; + } else { + return false; + } + } + } + } + + ReadBWTHit& rchit = _hits[rdi][1-fwi]; + if(rchit.done() && bestScore < _minsc[rdi]) { + if(numSearched > rchit.numActualPartialSearch() + (anchorStop ? 1 : 0)) { + hit.done(true); + return false; + } + } + } + + // Align this read beginning from previously stopped base + // stops when it is uniquelly mapped with at least 28bp or + // it may involve processed pseudogene + partialSearch( + gfm, + *_rds[rdi], + sc, + sink.reportingParams(), + fw, + 0, + mineFw, + mineRc, + hit, + rnd, + pseudogeneStop, + anchorStop); + + assert(hit.repOk()); + if(hit.done()) return true; + // Advance hit._cur by 1 + if(!pseudogeneStop) { + if(hit._cur + 1 < hit._len) hit._cur++; + } + if(anchorStop) { + hit.done(true); + return true; + } + // hit.adjustOffset(_minK); + } + + return false; + } + + /** + * Given partial alignments of a read, try to further extend + * the alignment bidirectionally + */ + virtual + bool align( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink); + + /** + * Given the alignment of its mate as an anchor, + * align the read + */ + virtual + bool alignMate( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink, + index_t tidx, + index_t toff); + + /** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ + virtual + void hybridSearch( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) + {} + + /** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ + virtual + int64_t hybridSearch_recur( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + const GenomeHit& hit, + index_t hitoff, + index_t hitlen, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink, + bool alignMate = false, + index_t dep = 0) + { return numeric_limits::min(); } + + /** + * Choose a candidate for alignment from a read or its reverse complement + * (also from a mate or its reverse complement for pair) + */ + bool pickNextReadToSearch(index_t& rdi, bool& fw) { + rdi = 0; fw = true; + bool picked = false; + int64_t maxScore = std::numeric_limits::min(); + for(index_t rdi2 = 0; rdi2 < (_paired ? 2 : 1); rdi2++) { + assert(_rds[rdi2] != NULL); + for(index_t fwi = 0; fwi < 2; fwi++) { + if (fwi == 0 && _nofw[rdi2]) continue; + else if(fwi == 1 && _norc[rdi2]) continue; + + if(_hits[rdi2][fwi].done()) continue; + int64_t curScore = _hits[rdi2][fwi].searchScore((index_t)_minK); + if(_hits[rdi2][fwi].cur() == 0) { + curScore = std::numeric_limits::max(); + } + assert_gt(curScore, std::numeric_limits::min()); + if(curScore > maxScore) { + maxScore = curScore; + rdi = rdi2; + fw = (fwi == 0); + picked = true; + } + } + } + + return picked; + } + + /** + * Align a part of a read without any edits + */ + index_t partialSearch( + const GFM& gfm, // GFM index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + const ReportingParams& rp, + bool fw, // don't align forward read + size_t mineMax, // don't care about edit bounds > this + size_t& mineFw, // minimum # edits for forward read + size_t& mineRc, // minimum # edits for revcomp read + ReadBWTHit& hit, // holds all the seed hits (and exact hit) + RandomSource& rnd, + bool& pseudogeneStop, // stop if mapped to multiple locations due to processed pseudogenes + bool& anchorStop, + index_t maxHitLen = (index_t)INDEX_MAX); + + /** + * Global FM index search + */ + index_t globalGFMSearch( + const GFM& gfm, // GFM index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + const ReportingParams& rp, + bool fw, + index_t hitoff, + index_t& hitlen, + index_t& top, + index_t& bot, + index_t& node_top, + index_t& node_bot, + EList >& node_iedge_count, + RandomSource& rnd, + bool& uniqueStop, + index_t maxHitLen = (index_t)INDEX_MAX); + + /** + * Local FM index search + */ + index_t localGFMSearch( + const LocalGFM& gfm, // GFM index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + const ReportingParams& rp, + bool fw, + index_t rdoff, + index_t& hitlen, + local_index_t& top, + local_index_t& bot, + local_index_t& node_top, + local_index_t& node_bot, + EList >& local_node_iedge_count, + RandomSource& rnd, + bool& uniqueStop, + local_index_t minUniqueLen, + local_index_t maxHitLen = (local_index_t)INDEX_MAX, + local_index_t maxHits = 0); + + /** + * Convert FM offsets to the corresponding genomic offset (chromosome id, offset) + **/ + bool getGenomeCoords( + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + RandomSource& rnd, + index_t top, + index_t bot, + index_t node_top, + index_t node_bot, + const EList >& node_iedge_count, + bool fw, + index_t maxelt, + index_t rdoff, + index_t rdlen, + EList& coords, + WalkMetrics& met, + PerReadMetrics& prm, + HIMetrics& him, + bool rejectStraddle, + bool& straddled); + + /** + * Convert FM offsets to the corresponding genomic offset (chromosome id, offset) + **/ + bool getGenomeCoords_local( + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + RandomSource& rnd, + local_index_t top, + local_index_t bot, + local_index_t node_top, + local_index_t node_bot, + const EList >& node_iedge_count, + bool fw, + index_t rdoff, + index_t rdlen, + EList& coords, + WalkMetrics& met, + PerReadMetrics& prm, + HIMetrics& him, + bool rejectStraddle, + bool& straddled); + + /** + * Given a set of partial alignments for a read, + * choose some that are longer and mapped to fewer places + */ + index_t getAnchorHits( + const GFM& gfm, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + RandomSource& rnd, + index_t rdi, + bool fw, + EList >& genomeHits, + index_t maxGenomeHitSize, + SharedTempVars& sharedVars, + WalkMetrics& wlm, + PerReadMetrics& prm, + HIMetrics& him, + bool repeat = false) + { + index_t fwi = (fw ? 0 : 1); + assert_lt(rdi, 2); + assert(_rds[rdi] != NULL); + ReadBWTHit& hit = _hits[rdi][fwi]; + assert(hit.done()); + index_t offsetSize = hit.offsetSize(); + assert_gt(offsetSize, 0); + for(size_t hi = 0; hi < offsetSize; hi++) { + index_t hj = 0; + for(; hj < offsetSize; hj++) { + BWTHit& partialHit_j = hit.getPartialHit(hj); + if(partialHit_j.empty() || + partialHit_j.hasGenomeCoords() || + partialHit_j.len() <= _minK + 2) continue; + else break; + } + if(hj >= offsetSize) break; + for(index_t hk = hj + 1; hk < offsetSize; hk++) { + BWTHit& partialHit_j = hit.getPartialHit(hj); + BWTHit& partialHit_k = hit.getPartialHit(hk); + if(partialHit_k.empty() || + partialHit_k.hasGenomeCoords() || + partialHit_k.len() <= _minK + 2) continue; + + if(partialHit_j._hit_type == partialHit_k._hit_type) { + if((partialHit_j.size() > partialHit_k.size()) || + (partialHit_j.size() == partialHit_k.size() && partialHit_j.len() < partialHit_k.len())) { + hj = hk; + } + } else { + if(partialHit_k._hit_type > partialHit_j._hit_type) { + hj = hk; + } + } + } + BWTHit& partialHit = hit.getPartialHit(hj); + assert(!partialHit.hasGenomeCoords()); + + // Retrieve genomic coordinates + // If there are too many genomic coordinates to get, + // then we randomly choose and retrieve a small set of them + assert_leq(genomeHits.size(), maxGenomeHitSize); + index_t remainedGenomeHitSize = maxGenomeHitSize - genomeHits.size(); + if(remainedGenomeHitSize <= 0) + break; + index_t expectedNumCoords = partialHit._node_bot - partialHit._node_top; + bool straddled = false; + if(expectedNumCoords <= remainedGenomeHitSize) { + getGenomeCoords( + gfm, + altdb, + ref, + rnd, + partialHit._top, + partialHit._bot, + partialHit._node_top, + partialHit._node_bot, + partialHit._node_iedge_count, + fw, + partialHit._bot - partialHit._top, + hit._len - partialHit._bwoff - partialHit._len, + partialHit._len, + partialHit._coords, + wlm, + prm, + him, + false, // reject straddled + straddled); + } else { + index_t edgeIdx = 0; + index_t top = partialHit._top; + index_t added = 0; + for(index_t node = partialHit._node_top; node < partialHit._node_bot; node++, expectedNumCoords--) { + index_t bot = top + 1; + _tmp_node_iedge_count.clear(); + if(edgeIdx < partialHit._node_iedge_count.size()) { + assert_leq(node - partialHit._node_top, partialHit._node_iedge_count[edgeIdx].first); + if(node - partialHit._node_top == partialHit._node_iedge_count[edgeIdx].first) { + bot += partialHit._node_iedge_count[edgeIdx].second; + _tmp_node_iedge_count.expand(); + _tmp_node_iedge_count.back().first = 0; + _tmp_node_iedge_count.back().second = partialHit._node_iedge_count[edgeIdx].second; + edgeIdx++; + } + } + assert_lt(added, remainedGenomeHitSize); + uint32_t rndi = rnd.nextU32() % expectedNumCoords; + if(rndi < remainedGenomeHitSize - added) { + getGenomeCoords( + gfm, + altdb, + ref, + rnd, + top, + bot, + node, + node + 1, + _tmp_node_iedge_count, + fw, + partialHit._bot - partialHit._top, + hit._len - partialHit._bwoff - partialHit._len, + partialHit._len, + partialHit._coords, + wlm, + prm, + him, + false, // reject straddled + straddled); + added++; + if(added >= remainedGenomeHitSize) break; + } + top = bot; + } + } + + if(!partialHit.hasGenomeCoords()) continue; + EList& coords = partialHit._coords; + assert_gt(coords.size(), 0); + const index_t genomeHit_size = (index_t)genomeHits.size(); + if(genomeHit_size + coords.size() > maxGenomeHitSize) { + coords.shufflePortion(0, coords.size(), rnd); + } + for(index_t k = 0; k < coords.size(); k++) { + const Coord& coord = coords[k]; + if(coord.ref() == numeric_limits::max()) + continue; + index_t len = partialHit._len; + index_t rdoff = hit._len - partialHit._bwoff - len; + bool overlapped = false; + for(index_t l = 0; l < genomeHit_size; l++) { + GenomeHit& genomeHit = genomeHits[l]; + if(genomeHit.ref() != (index_t)coord.ref() || genomeHit.fw() != coord.fw()) continue; + assert_lt(genomeHit.rdoff(), hit._len); + assert_lt(rdoff, hit._len); + index_t hitoff = genomeHit.refoff() + hit._len - genomeHit.rdoff(); + index_t hitoff2 = (index_t)coord.off() + hit._len - rdoff; + int64_t hitoff_diff = (tpol.no_spliced_alignment() ? 0 : tpol.maxIntronLen()); + if(abs((int64_t)hitoff - (int64_t)hitoff2) <= hitoff_diff) { + overlapped = true; + genomeHit._hitcount++; + break; + } + } + if(repeat) { + if(!repeatdb.repeatExist(coord.ref(), coord.off(), coord.off() + len)) { + continue; + } + } + if(!overlapped) { + GenomeHit::adjustWithALT( + rdoff, + len, + coord, + _sharedVars, + genomeHits, + *_rds[rdi], + gfm, + altdb, + ref, + gpol); + } + if(partialHit._hit_type == CANDIDATE_HIT && genomeHits.size() >= maxGenomeHitSize) break; + } + if(partialHit._hit_type == CANDIDATE_HIT && genomeHits.size() >= maxGenomeHitSize) break; + } + + return (index_t)genomeHits.size(); + } + + /** + * + */ + index_t getRepeatHits( + const GFM& gfm, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const RB_KmerTable& repeat_kmertable, + const BitPairReference& ref, + RandomSource& rnd, + index_t rdi, + bool fw, + index_t repID, + EList >& genomeHits, + index_t maxGenomeHitSize, + SharedTempVars& sharedVars, + const Scoring& sc, + SwAligner& swa, + SpliceSiteDB& ssdb, + SwMetrics& swm, + WalkMetrics& wlm, + PerReadMetrics& prm, + HIMetrics& him, + AlnSinkWrap& sink) + { + assert_lt(rdi, 2); + assert(_rds[rdi] != NULL); + Read& rd = *_rds[rdi]; + const BTDnaString& seq = fw ? rd.patFw : rd.patRc; + repeat_kmertable.findAlignments(seq, + _tmp_minimizers, + _tmp_position2D, + _tmp_alignments); + + const TAlScore cushion = sc.mmpMax; + + TAlScore bestScore = _minsc[rdi]; + size_t prev_numHits = genomeHits.size(); + for(index_t i = 0; i < _tmp_alignments.size(); i++) { + const RB_Alignment& coord = _tmp_alignments[i]; + index_t len = seq.length(); + index_t rdoff = 0; + if(!repeatdb.repeatExist(repID, coord.pos, coord.pos + len)) { + continue; + } + + genomeHits.expand(); + GenomeHit& genomeHit = genomeHits.back(); + genomeHit.init(fw, + rdoff, + 0, + 0, // trim5 + 0, // trim3 + repID, // ref, + coord.pos, + coord.pos, + this->_sharedVars); + + index_t maxmm = (index_t)(-bestScore / sc.mmpMax); + index_t leftext = 0, rightext = len; + genomeHit.extend(rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext, + maxmm); + + if(genomeHit.len() < len) { + genomeHits.pop_back(); + continue; + } + + if(genomeHit.score() > bestScore) { + bestScore = genomeHit.score(); + size_t remove_count = 0; + size_t k = prev_numHits; + for(size_t j = prev_numHits; j < genomeHits.size(); j++) { + if(genomeHits[j].score() >= max(_minsc[rdi], bestScore - cushion)) { + assert_leq(k, j); + if(k < j) { + genomeHits[k] = genomeHits[j]; + } + k++; + } else { + remove_count++; + } + } + assert_eq(k + remove_count, genomeHits.size()); + assert_leq(prev_numHits + remove_count, genomeHits.size()); + if(remove_count > 0) { + genomeHits.resize(genomeHits.size() - remove_count); + } + } else if(genomeHit.score() < max(_minsc[rdi], bestScore - cushion)) { + genomeHits.pop_back(); + } + } + + return (index_t)genomeHits.size(); + } + + bool pairReads( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + WalkMetrics& wlm, + PerReadMetrics& prm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink); + + /** + * + **/ + bool reportHit( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + const SpliceSiteDB& ssdb, + AlnSinkWrap& sink, + index_t rdi, + const GenomeHit& hit, + bool alignMate = false, + const GenomeHit* ohit = NULL); + + /** + * check this alignment is already examined + **/ + bool redundant( + AlnSinkWrap& sink, + index_t rdi, + index_t tidx, + index_t toff); + + /** + * check this alignment is already examined + **/ + bool redundant( + AlnSinkWrap& sink, + index_t rdi, + const GenomeHit& hit); + + + /** + * + **/ + bool isSearched( + const GenomeHit& hit, + index_t rdi); + + /** + * + **/ + void addSearched(const GenomeHit& hit, + index_t rdi); + + +protected: + + Read * _rds[2]; + bool _paired; + bool _rightendonly; + bool _nofw[2]; + bool _norc[2]; + TAlScore _minsc[2]; + TAlScore _maxpen[2]; + + bool _anchorStop; + + ReadBWTHit _hits[2][2]; + + EList _offs; + SARangeWithOffs, index_t> _sas; + GroupWalk2S, 16> _gws; + GroupWalkState _gwstate; + + EList _offs_local; + SARangeWithOffs, local_index_t> _sas_local; + GroupWalk2S, 16> _gws_local; + GroupWalkState _gwstate_local; + + // temporary and shared variables used for GenomeHit + // this should be defined before _genomeHits and _hits_searched + SharedTempVars _sharedVars; + + // temporary and shared variables for AlnRes + LinkedEList > _rawEdits; + + // temporary + EList > _genomeHits; + EList > _genomeHits_rep[2]; + EList _snpIDs; + EList _snpIDs2; + EList _genomeHits_done; + ELList _coords; + EList, RepeatCoord > > _positions; + ELList _spliceSites; + + pair _concordantIdxInspected; + EList > _repeatConcordant; + + size_t _minK; // log4 of the size of a genome + size_t _minK_local; // log4 of the size of a local index (8) + + ELList > _local_genomeHits; + EList _anchors_added; + uint64_t max_localindexatts; + + uint64_t bwops_; // Burrows-Wheeler operations + uint64_t bwedits_; // Burrows-Wheeler edits + + // + EList > _hits_searched[2]; + + uint64_t _thread_rids_mindist; + + // + EList > _node_iedge_count; + EList > _tmp_node_iedge_count; + + EList > _local_node_iedge_count; + EList > _tmp_local_node_iedge_count; + + EList > _tmp_minimizers; + ELList _tmp_position2D; + EList _tmp_alignments; + + // For AlnRes::matchesRef + ASSERT_ONLY(EList raw_matches_); + ASSERT_ONLY(BTDnaString tmp_rf_); + ASSERT_ONLY(BTDnaString tmp_rdseq_); + ASSERT_ONLY(BTString tmp_qseq_); +}; + +#define HIER_INIT_LOCS(top, bot, tloc, bloc, e) { \ + if(bot - top == 1) { \ + tloc.initFromRow(top, (e).gh(), (e).gfm()); \ + bloc.invalidate(); \ + } else { \ + SideLocus::initFromTopBot(top, bot, (e).gh(), (e).gfm(), tloc, bloc); \ + assert(bloc.valid()); \ + } \ +} + +#define HIER_SANITY_CHECK_4TUP(t, b, tp, bp) { \ + ASSERT_ONLY(cur_index_t tot = (b[0]-t[0])+(b[1]-t[1])+(b[2]-t[2])+(b[3]-t[3])); \ + ASSERT_ONLY(cur_index_t totp = (bp[0]-tp[0])+(bp[1]-tp[1])+(bp[2]-tp[2])+(bp[3]-tp[3])); \ + assert_eq(tot, totp); \ +} + +#define LOCAL_INIT_LOCS(top, bot, tloc, bloc, e) { \ + if(bot - top == 1) { \ + tloc.initFromRow(top, (e).gh(), (e).gfm()); \ + bloc.invalidate(); \ + } else { \ + SideLocus::initFromTopBot(top, bot, (e).gh(), (e).gfm(), tloc, bloc); \ + assert(bloc.valid()); \ + } \ +} + +/** + * Given partial alignments of a read, try to further extend + * the alignment bidirectionally + */ +template +bool HI_Aligner::align( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) +{ + + const ReportingParams& rp = sink.reportingParams(); + index_t fwi = (fw ? 0 : 1); + assert_lt(rdi, 2); + assert(_rds[rdi] != NULL); + ReadBWTHit& hit = _hits[rdi][fwi]; + assert(hit.done()); + index_t minOff = 0; + if(hit.minWidth(minOff) == std::numeric_limits::max()) return false; + + // Don't try to align if the potential alignment for this read might be + // worse than the best alignment of its reverse complement + int64_t bestScore = (rdi == 0 ? sink.bestUnp1() : sink.bestUnp2()); + index_t num_spliced = (rdi == 0 ? sink.bestSplicedUnp1() : sink.bestSplicedUnp2()); + if(bestScore < _minsc[rdi]) bestScore = _minsc[rdi]; + index_t maxmm = (index_t)((-bestScore + sc.mmpMax - 1) / sc.mmpMax); + index_t numActualPartialSearch = hit.numActualPartialSearch(); + if(!rp.secondary && numActualPartialSearch > maxmm + num_spliced + 1) return true; + + // choose candidate partial alignments for further alignment + const index_t maxsize = max(rp.khits, rp.kseeds); + _genomeHits.clear(); + index_t numHits = getAnchorHits(gfm, + pepol, + tpol, + gpol, + altdb, + repeatdb, + ref, + rnd, + rdi, + fw, + _genomeHits, + maxsize, + _sharedVars, + wlm, + prm, + him, + gfm.repeat()); + if(numHits <= 0) return false; + + // limit the number of local index searches used for alignment of the read + uint64_t add = 0; + if(rp.secondary) add = (-_minsc[rdi] / sc.mmpMax) * numHits * 2; + else add = (-_minsc[rdi] / sc.mmpMax) * numHits; + max_localindexatts = him.localindexatts + max(10, add); + // extend the partial alignments bidirectionally using + // local search, extension, and (less often) global search + hybridSearch(sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + fw, + wlm, + prm, + swm, + him, + rnd, + sink); + + return true; +} + + +/** + * Given the alignment of its mate as an anchor, + * align the read + */ +template +bool HI_Aligner::alignMate( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink, + index_t tidx, + index_t toff) +{ + const ReportingParams& rp = sink.reportingParams(); + + assert_lt(rdi, 2); + index_t ordi = 1 - rdi; + bool ofw = (fw == gMate2fw ? gMate1fw : gMate2fw); + assert(_rds[ordi] != NULL); + const Read& ord = *_rds[ordi]; + index_t rdlen = (index_t)ord.length(); + assert_gt(rdlen, 0); + + _genomeHits.clear(); + if(_coords.size() == 0) { + _coords.expand(); + } + EList& coords = _coords.front(); + + // local search to find anchors + const HGFM* hGFM = (const HGFM*)(&gfm); + const LocalGFM* lGFM = hGFM->getLocalGFM(tidx, toff); + bool first = true; + index_t count = 0; + index_t max_hitlen = 0; + while(count++ < 2) { + if(first) { + first = false; + } else { + if(_genomeHits.size() > 0) break; + if(fw) { + lGFM = hGFM->nextLocalGFM(lGFM); + } else { + lGFM = hGFM->prevLocalGFM(lGFM); + } + if(lGFM == NULL || lGFM->empty()) break; + } + index_t hitoff = rdlen - 1; + while(hitoff >= _minK_local - 1) { + index_t hitlen = 0; + local_index_t top = (local_index_t)INDEX_MAX, bot = (local_index_t)INDEX_MAX; + local_index_t node_top = (local_index_t)INDEX_MAX, node_bot = (local_index_t)INDEX_MAX; + _local_node_iedge_count.clear(); + bool uniqueStop = false; + index_t nelt = localGFMSearch( + *lGFM, // GFM index + ord, // read to align + sc, // scoring scheme + sink.reportingParams(), + ofw, + hitoff, + hitlen, + top, + bot, + node_top, + node_bot, + _local_node_iedge_count, + rnd, + uniqueStop, + _minK_local); + assert_leq(top, bot); + assert_eq(nelt, (index_t)(node_bot - node_top)); + assert_leq(hitlen, hitoff + 1); + if(nelt > 0 && nelt <= rp.kseeds && hitlen > max_hitlen) { + coords.clear(); + bool straddled = false; + getGenomeCoords_local( + *lGFM, + altdb, + ref, + rnd, + top, + bot, + node_top, + node_bot, + _local_node_iedge_count, + ofw, + hitoff - hitlen + 1, + hitlen, + coords, + wlm, + prm, + him, + true, // reject straddled? + straddled); + assert_leq(coords.size(), nelt); + _genomeHits.clear(); + for(index_t ri = 0; ri < coords.size(); ri++) { + const Coord& coord = coords[ri]; + if(tpol.no_spliced_alignment()) { + if(coord.off() + pepol.maxFragLen() * 2 < toff || toff + pepol.maxFragLen() * 2 < coord.off()) + continue; + } + + GenomeHit::adjustWithALT( + hitoff - hitlen + 1, + hitlen, + coord, + _sharedVars, + _genomeHits, + *this->_rds[ordi], + gfm, + altdb, + ref, + gpol); + } + max_hitlen = hitlen; + } + assert_leq(hitlen, hitoff + 1); + if(hitlen > 0) hitoff -= (hitlen - 1); + if(hitoff > 0) hitoff -= 1; + } // while(hitoff >= minHitLen - 1) + } // while(count++ < 2) + + // randomly select + const index_t maxsize = rp.kseeds; + if(_genomeHits.size() > maxsize) { + _genomeHits.shufflePortion(0, _genomeHits.size(), rnd); + _genomeHits.resize(maxsize); + } + + // local search using the anchor + for(index_t hi = 0; hi < _genomeHits.size(); hi++) { + him.anchoratts++; + GenomeHit& genomeHit = _genomeHits[hi]; + index_t leftext = (index_t)INDEX_MAX, rightext = (index_t)INDEX_MAX; + genomeHit.extend( + ord, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + _minsc[ordi], + rnd, + (index_t)_minK_local, + tpol, + gpol, + leftext, + rightext); + hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + ordi, + genomeHit, + genomeHit.rdoff(), + genomeHit.len(), + wlm, + prm, + swm, + him, + rnd, + sink, + true); // alignMate? + } + + return true; +} + + +/** + * convert FM offsets to the corresponding genomic offset (chromosome id, offset) + **/ +template +bool HI_Aligner::getGenomeCoords( + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + RandomSource& rnd, + index_t top, + index_t bot, + index_t node_top, + index_t node_bot, + const EList >& node_iedge_count, + bool fw, + index_t maxelt, + index_t rdoff, + index_t rdlen, + EList& coords, + WalkMetrics& met, + PerReadMetrics& prm, + HIMetrics& him, + bool rejectStraddle, + bool& straddled) +{ + straddled = false; + assert_gt(bot, top); + assert_leq(node_bot - node_top, bot - top); + index_t nelt = node_bot - node_top; + nelt = min(nelt, maxelt); + him.globalgenomecoords += nelt; + _offs.resize(nelt); + _offs.fill((index_t)INDEX_MAX); + _sas.init( + top, + bot, + node_top, + node_bot, + node_iedge_count, + rdlen, + EListSlice(_offs, 0, nelt)); + _gws.init(gfm, ref, _sas, rnd, met); + + for(index_t off = 0; off < nelt; off++) { + WalkResult wr; + index_t tidx = 0, toff = 0, tlen = 0; + _gws.advanceElement( + off, + gfm, // forward Bowtie index for walking left + ref, // bitpair-encoded reference + _sas, // SA range with offsets + _gwstate, // GroupWalk state; scratch space + wr, // put the result here + met, // metrics + prm); // per-read metrics + assert_neq(wr.toff, (index_t)INDEX_MAX); + bool straddled2 = false; + gfm.joinedToTextOff( + wr.elt.len, + wr.toff, + tidx, + toff, + tlen, + rejectStraddle, // reject straddlers? + straddled2); // straddled? + + straddled |= straddled2; + + if(tidx == (index_t)INDEX_MAX) { + // The seed hit straddled a reference boundary so the seed + // hit isn't valid + return false; + } + index_t global_toff = toff, global_tidx = tidx; + + // Coordinate of the seed hit w/r/t the pasted reference string + coords.expand(); + if(!straddled2) { + coords.back().init(global_tidx, (int64_t)global_toff, fw, wr.toff); + } else { + coords.back().init(numeric_limits::max(), (int64_t)global_toff, fw, wr.toff); + } + } + + return true; +} + +/** + * convert FM offsets to the corresponding genomic offset (chromosome id, offset) + **/ +template +bool HI_Aligner::getGenomeCoords_local( + const GFM& gfm, + const ALTDB& altdb, + const BitPairReference& ref, + RandomSource& rnd, + local_index_t top, + local_index_t bot, + local_index_t node_top, + local_index_t node_bot, + const EList >& node_iedge_count, + bool fw, + index_t rdoff, + index_t rdlen, + EList& coords, + WalkMetrics& met, + PerReadMetrics& prm, + HIMetrics& him, + bool rejectStraddle, + bool& straddled) +{ + straddled = false; + assert_gt(bot, top); + assert_leq(node_bot - node_top, bot - top); + index_t nelt = node_bot - node_top; + him.localgenomecoords += nelt; + _offs_local.resize(nelt); + _offs_local.fill((local_index_t)INDEX_MAX); + _sas_local.init( + top, + bot, + node_top, + node_bot, + node_iedge_count, + rdlen, + EListSlice(_offs_local, 0, nelt)); + _gws_local.init(gfm, ref, _sas_local, rnd, met); + + for(local_index_t off = 0; off < nelt; off++) { + WalkResult wr; + local_index_t tidx = 0, toff = 0, tlen = 0; + _gws_local.advanceElement( + off, + gfm, // forward Bowtie index for walking left + ref, // bitpair-encoded reference + _sas_local, // SA range with offsets + _gwstate_local, // GroupWalk state; scratch space + wr, // put the result here + met, // metrics + prm); // per-read metrics + assert_neq(wr.toff, (local_index_t)INDEX_MAX); + bool straddled2 = false; + bool result = gfm.joinedToTextOff( + wr.elt.len, + wr.toff, + tidx, + toff, + tlen, + rejectStraddle, // reject straddlers? + straddled2); // straddled? + if(!result) continue; + + straddled |= straddled2; + + if(tidx == (local_index_t)INDEX_MAX) { + // The seed hit straddled a reference boundary so the seed + // hit isn't valid + return false; + } + LocalGFM* localGFM = (LocalGFM*)&gfm; + index_t global_tidx = localGFM->_tidx; + index_t global_toff = toff + localGFM->_localOffset; + index_t joinedOff = wr.toff + localGFM->_joinedOffset; + if(global_toff < rdoff) continue; + + // Coordinate of the seed hit w/r/t the pasted reference string + coords.expand(); + coords.back().init(global_tidx, (int64_t)global_toff, fw, joinedOff); + } + + return true; +} + + +/** + * examine alignments of left and right reads to produce concordant pair alignment + **/ +template +bool HI_Aligner::pairReads( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + WalkMetrics& wlm, + PerReadMetrics& prm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) +{ + const ReportingParams& rp = sink.reportingParams(); + assert(_paired); + const EList *rs1 = NULL, *rs2 = NULL; + sink.getUnp1(rs1); assert(rs1 != NULL); + sink.getUnp2(rs2); assert(rs2 != NULL); + index_t start_i = _concordantIdxInspected.first, start_j = _concordantIdxInspected.second; + _concordantIdxInspected.first = rs1->size(); + _concordantIdxInspected.second = rs2->size(); + for(index_t i = 0; i < rs1->size(); i++) { + for(index_t j = (i >= start_i ? 0 : start_j); j < rs2->size(); j++) { + if(sink.state().doneConcordant()) { + return true; + } + const AlnRes& r1 = (*rs1)[i]; + Coord left = r1.refcoord(), right = r1.refcoord_right(); + assert_eq(left.ref(), right.ref()); + const AlnRes& r2 = (*rs2)[j]; + Coord left2 = r2.refcoord(), right2 = r2.refcoord_right(); + assert_eq(left2.ref(), right2.ref()); + + if(r1.repeat() != r2.repeat()) + continue; + + bool dna_frag_pass = true; + if(r1.repeat() && r2.repeat()) { + bool found = false; + for(size_t r = 0; r < _repeatConcordant.size(); r++) { + if(_repeatConcordant[r].first == left.off() && + _repeatConcordant[r].second == left2.off()) { + found = true; + break; + } + } + if(!found) { + dna_frag_pass = false; + } + } else{ + if(left.ref() != left2.ref()) continue; + assert_eq(left.orient(), right.orient()); + assert_eq(left2.orient(), right2.orient()); + if(left.orient() == gMate1fw) { + if(left2.orient() != gMate2fw) continue; + } else { + if(left2.orient() == gMate2fw) continue; + Coord temp = left; left = left2; left2 = temp; + temp = right; right = right2; right2 = temp; + } + if(left.off() > left2.off()) continue; + if(right.off() > right2.off()) continue; + if(right.off() + (int)tpol.maxIntronLen() < left2.off()) continue; + assert_geq(r1.score().score(), _minsc[0]); + assert_geq(r2.score().score(), _minsc[1]); + if(tpol.no_spliced_alignment()){ + int pairCl = PE_ALS_DISCORD; + assert_eq(r1.refid(), r2.refid()); + index_t off1, off2, len1, len2; + bool fw1, fw2; + if(r1.refoff() < r2.refoff()) { + off1 = r1.refoff(); off2 = r2.refoff(); + len1 = r1.refExtent(); len2 = r2.refExtent(); + fw1 = r1.fw(); fw2 = r2.fw(); + } else { + off1 = r2.refoff(); off2 = r1.refoff(); + len1 = r2.refExtent(); len2 = r1.refExtent(); + fw1 = r2.fw(); fw2 = r1.fw(); + } + // Check that final mate alignments are consistent with + // paired-end fragment constraints + pairCl = pepol.peClassifyPair( + off1, + len1, + fw1, + off2, + len2, + fw2); + dna_frag_pass = (pairCl != PE_ALS_DISCORD); + } + } + + if(!tpol.no_spliced_alignment() || dna_frag_pass) { + TAlScore threshold = sink.bestPair(); + if(sink.bestUnp1() >= _minsc[0] && sink.bestUnp2() >= _minsc[1]) { + TAlScore tmp = sink.bestUnp1() + sink.bestUnp2() - (r1.readLength() + r2.readLength()) * 0.03 * sc.mm(255); + if(tmp > threshold) { + threshold = tmp; + } + } + if(r1.score().score() + r2.score().score() >= threshold || rp.secondary) { + sink.report(0, &r1, &r2); + } + } + } + } + return true; +} + + +/** + * report read (or pair) alignment + **/ +template +bool HI_Aligner::reportHit( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + const SpliceSiteDB& ssdb, + AlnSinkWrap& sink, + index_t rdi, + const GenomeHit& hit, + bool alignMate, + const GenomeHit* ohit) +{ + assert_lt(rdi, 2); + assert(_rds[rdi] != NULL); + const Read& rd = *_rds[rdi]; + index_t rdlen = (index_t)rd.length(); + if(hit.rdoff() - hit.trim5() > 0 || hit.len() + hit.trim5() + hit.trim3() < rdlen) return false; + if(hit.score() < _minsc[rdi]) return false; + if(!sink.reportingParams().repeat && hit.repeat()) return false; + + // Edits are represented from 5' end of read to 3' end, not an alignment of read + EList& edits = const_cast&>(hit.edits()); + if(hit.trim5() > 0) { + for(size_t i = 0; i < edits.size(); i++) { + edits[i].pos += hit.trim5(); + } + } + if(!hit.fw()) { + Edit::invertPoss(edits, rdlen, false); + } + // in case of multiple exonic alignments, choose the ones near (known) splice sites + // this helps eliminate cases of reads being mapped to pseudogenes + pair spliced = hit.spliced(); // pair + if(tpol.xs_only() && spliced.first) { + if(hit.splicing_dir() == SPL_UNKNOWN) + return false; + } + if(!tpol.no_spliced_alignment() && tpol.avoid_pseudogene()) { + if(!spliced.first) { + assert(!spliced.second); + const index_t max_exon_size = 10000; + index_t left = 0; + if(hit.refoff() > max_exon_size) { + left = hit.refoff() - max_exon_size; + } + index_t right = hit.refoff() + hit.len() + max_exon_size; + spliced.first = ssdb.hasSpliceSites( + hit.ref(), + left, + right, + left, + right, + true); // include novel splice sites + if(altdb.hasExons()) { + spliced.second = ssdb.insideExon(hit.ref(), hit.refoff(), hit.refoff() + hit.len() - 1); + } + } + } + if(tpol.transcriptome_mapping_only() && !spliced.second) + return false; + + AlnScore asc( + hit.score(), // numeric score + hit.ns(), // # Ns + hit.ngaps(), // # gaps + hit.repeat(), + hit.splicescore(), // splice scorehit + spliced.second, // mapped to known transcripts? + spliced.first, // spliced alignment or near splice sites (novel)? + hit.trim5(), // left trim length + hit.trim3()); // right trim length + bool softTrim = hit.trim5() > 0 || hit.trim3() > 0; + AlnRes rs; + rs.init( + rdlen, // # chars after hard trimming + rd.rdid, // read ID + asc, // alignment score + &hit.edits(), // nucleotide edits array + 0, // nucleotide edits first pos + hit.edits().size(), // nucleotide edits last pos + NULL, // ambig base array + 0, // ambig base first pos + 0, // ambig base last pos + hit.coord(), // coord of leftmost aligned char in ref + hit.repeat() ? gfm.plen()[0] : gfm.plen()[hit.ref()], // length of reference aligned to + &_rawEdits, + -1, // # seed mms allowed + -1, // seed length + -1, // seed interval + 0, // minimum score for valid alignment (daehwan) + -1, // nuc5p (for colorspace) + -1, // nuc3p (for colorspace) + false, // soft pre-trimming? + 0, // 5p pre-trimming + 0, // 3p pre-trimming + softTrim, // soft trimming? + hit.fw() ? hit.trim5() : hit.trim3(), // 5p trimming + hit.fw() ? hit.trim3() : hit.trim5(), // 3p trimming + hit.repeat()); // repeat? + if(!hit.fw()) { + Edit::invertPoss(edits, rdlen, false); + } + if(hit.trim5() > 0) { + for(size_t i = 0; i < edits.size(); i++) { + edits[i].pos -= hit.trim5(); + } + } + + + //rs.setRefNs(nrefn); + /*assert(rs.matchesRef( + rd, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + _sharedVars.raw_refbuf, + _sharedVars.destU32, + raw_matches_, + _sharedVars.raw_refbuf2, + _sharedVars.reflens, + _sharedVars.refoffs));*/ + if(ohit == NULL) { + bool done; + if(rdi == 0 && !_rightendonly) { + done = sink.report(0, &rs, NULL, alignMate); + } else { + done = sink.report(0, NULL, &rs, alignMate); + } + return done; + } + + assert(ohit != NULL); + const Read& ord = *_rds[1-rdi]; + index_t ordlen = (index_t)ord.length(); + if(ohit->rdoff() - ohit->trim5() > 0 || ohit->len() + ohit->trim5() + ohit->trim3() < ordlen) return false; + if(ohit->score() < _minsc[1-rdi]) return false; + EList& oedits = const_cast&>(ohit->edits()); + if(ohit->trim5() > 0) { + for(size_t i = 0; i < oedits.size(); i++) { + oedits[i].pos += ohit->trim5(); + } + } + if(!ohit->fw()) { + Edit::invertPoss(oedits, ordlen, false); + } + AlnScore oasc( + ohit->score(), // numeric score + ohit->ns(), // # Ns + ohit->ngaps(), // # gaps + ohit->repeat()); // repeat? + bool osoftTrim = ohit->trim5() > 0 || ohit->trim3() > 0; + AlnRes ors; + ors.init( + ordlen, // # chars after hard trimming + ord.rdid, // read ID + oasc, // alignment score + &ohit->edits(), // nucleotide edits array + 0, // nucleotide edits first pos + ohit->edits().size(), // nucleotide edits last pos + NULL, // ambig base array + 0, // ambig base first pos + 0, // ambig base last pos + ohit->coord(), // coord of leftmost aligned char in ref + gfm.plen()[ohit->ref()], // length of reference aligned to + &_rawEdits, + -1, // # seed mms allowed + -1, // seed length + -1, // seed interval + 0, // minimum score for valid alignment (daehwan) + -1, // nuc5p (for colorspace) + -1, // nuc3p (for colorspace) + false, // soft pre-trimming? + 0, // 5p pre-trimming + 0, // 3p pre-trimming + osoftTrim, // soft trimming? + ohit->fw() ? ohit->trim5() : ohit->trim3(), // 5p trimming + ohit->fw() ? ohit->trim3() : ohit->trim5(), // 3p trimming + ohit->repeat()); // repeat? + if(!ohit->fw()) { + Edit::invertPoss(oedits, ordlen, false); + } + if(ohit->trim5() > 0) { + for(size_t i = 0; i < oedits.size(); i++) { + oedits[i].pos -= ohit->trim5(); + } + } + //rs.setRefNs(nrefn); + assert(ors.matchesRef( + ord, + ref, + tmp_rf_, + tmp_rdseq_, + tmp_qseq_, + _sharedVars.raw_refbuf, + _sharedVars.destU32, + raw_matches_, + _sharedVars.raw_refbuf2, + _sharedVars.reflens, + _sharedVars.refoffs)); + + bool done; + if(rdi == 0) { + done = sink.report(0, &rs, &ors); + } else { + done = sink.report(0, &ors, &rs); + } + return done; +} + +/** + * check this alignment is already examined + **/ +template +bool HI_Aligner::redundant( + AlnSinkWrap& sink, + index_t rdi, + index_t tidx, + index_t toff) +{ + assert_lt(rdi, 2); + const EList* rs = NULL; + if(rdi == 0) sink.getUnp1(rs); + else sink.getUnp2(rs); + assert(rs != NULL); + for(index_t i = 0; i < rs->size(); i++) { + Coord coord_left = (*rs)[i].refcoord(), coord_right = (*rs)[i].refcoord_right(); + assert_eq(coord_left.ref(), coord_right.ref()); + assert_lt(coord_left.off(), coord_right.off()); + assert_eq(coord_left.orient(), coord_right.orient()); + + if(tidx != coord_left.ref()) continue; + if(toff >= coord_left.off() && toff <= coord_right.off()) return true; + } + + return false; +} + + +/** + * check this alignment is already examined + **/ +template +bool HI_Aligner::redundant( + AlnSinkWrap& sink, + index_t rdi, + const GenomeHit& hit) +{ + assert_lt(rdi, 2); + assert(_rds[rdi] != NULL); + index_t rdlen = (index_t)_rds[rdi]->length(); + const EList* rs = NULL; + if(rdi == 0) sink.getUnp1(rs); + else sink.getUnp2(rs); + assert(rs != NULL); + for(index_t i = 0; i < rs->size(); i++) { + const AlnRes& rsi = (*rs)[i]; + if(rsi.refcoord() == hit.coord()) { + const EList& editsi = rsi.ned(); + const EList& edits = hit.edits(); + if(editsi.size() == edits.size()) { + size_t eidx = 0; + if(!hit.fw()) { + Edit::invertPoss(const_cast&>(edits), rdlen, false); + } + // daehwan: this is a temporary solution to compare edits + for(; eidx < editsi.size(); eidx++) { + if(!(editsi[eidx] == edits[eidx])) { + break; + } + } + if(!hit.fw()) { + Edit::invertPoss(const_cast&>(edits), rdlen, false); + } + if(eidx >= editsi.size()) { + assert_eq(eidx, editsi.size()); + return true; + } + } + } + } + + return false; +} + + +/** + * Sweep right-to-left and left-to-right using exact matching. Remember all + * the SA ranges encountered along the way. Report exact matches if there are + * any. Calculate a lower bound on the number of edits in an end-to-end + * alignment. + */ +template +index_t HI_Aligner::partialSearch( + const GFM& gfm, // BWT index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + const ReportingParams& rp, + bool fw, + size_t mineMax, // don't care about edit bounds > this + size_t& mineFw, // minimum # edits for forward read + size_t& mineRc, // minimum # edits for revcomp read + ReadBWTHit& hit, // holds all the seed hits (and exact hit) + RandomSource& rnd, // pseudo-random source + bool& pseudogeneStop, + bool& anchorStop, + index_t maxHitLen) +{ + bool pseudogeneStop_ = pseudogeneStop, anchorStop_ = anchorStop; + pseudogeneStop = anchorStop = false; + const index_t ftabLen = gfm.gh().ftabChars(); + const bool linearFM = gfm.gh().linearFM(); + SideLocus tloc, bloc; + const index_t len = (index_t)read.length(); + const BTDnaString& seq = fw ? read.patFw : read.patRc; + assert(!seq.empty()); + + size_t nelt = 0; + EList >& partialHits = hit._partialHits; + index_t& cur = hit._cur; + assert_lt(cur, hit._len); + + hit._numPartialSearch++; + + index_t offset = cur; + index_t dep = offset; + pair range(0, 0); + pair rangeTemp(0, 0); + pair node_range(0, 0); + pair node_rangeTemp(0, 0); + _node_iedge_count.clear(); + _tmp_node_iedge_count.clear(); + index_t left = len - dep; + assert_gt(left, 0); + if(left < ftabLen + 1) { + cur = hit._len; + partialHits.expand(); + partialHits.back().init((index_t)INDEX_MAX, + (index_t)INDEX_MAX, + (index_t)INDEX_MAX, + (index_t)INDEX_MAX, + _node_iedge_count, + fw, + (index_t)offset, + (index_t)(cur - offset)); + hit.done(true); + return 0; + } + // Does N interfere with use of Ftab? + for(index_t i = 0; i < ftabLen; i++) { + int c = seq[len-dep-1-i]; + if(c > 3) { + cur += (i+1); + partialHits.expand(); + partialHits.back().init((index_t)INDEX_MAX, + (index_t)INDEX_MAX, + (index_t)INDEX_MAX, + (index_t)INDEX_MAX, + _node_iedge_count, + fw, + (index_t)offset, + (index_t)(cur - offset)); + if(cur >= hit._len) { + hit.done(true); + } + return 0; + } + } + + // Use ftab + gfm.ftabLoHi(seq, len - dep - ftabLen, false, range.first, range.second); + dep += ftabLen; + if(range.first >= range.second) { + cur = dep; + partialHits.expand(); + partialHits.back().init((index_t)INDEX_MAX, + (index_t)INDEX_MAX, + (index_t)INDEX_MAX, + (index_t)INDEX_MAX, + _node_iedge_count, + fw, + (index_t)offset, + (index_t)(cur - offset)); + if(cur >= hit._len) { + hit.done(true); + } + return 0; + } + index_t same_range = 0, similar_range = 0; + HIER_INIT_LOCS(range.first, range.second, tloc, bloc, gfm); + // Keep going + while(dep < len && dep - offset < maxHitLen) { + int c = seq[len-dep-1]; + if(c > 3) { + rangeTemp.first = rangeTemp.second = 0; + node_rangeTemp.first = node_rangeTemp.second = 0; + _tmp_node_iedge_count.clear(); + } else { + if(bloc.valid()) { + bwops_ += 2; + if(linearFM) { + rangeTemp = gfm.mapLF(tloc, bloc, c, &node_rangeTemp); + } else { + rangeTemp = gfm.mapGLF(tloc, bloc, c, &node_rangeTemp, &_tmp_node_iedge_count, (index_t)rp.kseeds); + } + } else { + bwops_++; + rangeTemp = gfm.mapGLF1(range.first, tloc, c, &node_rangeTemp); + if(rangeTemp.first + 1 < rangeTemp.second) { + assert_eq(node_rangeTemp.first + 1, node_rangeTemp.second); + _tmp_node_iedge_count.clear(); + _tmp_node_iedge_count.expand(); + _tmp_node_iedge_count.back().first = 0; + _tmp_node_iedge_count.back().second = rangeTemp.second - rangeTemp.first - 1; + } + } + } + if(rangeTemp.first >= rangeTemp.second) { + break; + } + if(pseudogeneStop_) { + if(node_rangeTemp.second - node_rangeTemp.first < node_range.second - node_range.first && node_range.second - node_range.first <= min(5, (index_t)rp.khits)) { + static const index_t minLenForPseudogene = (index_t)_minK + 6; + if(dep - offset >= minLenForPseudogene && similar_range >= 5) { + hit._numUniqueSearch++; + pseudogeneStop = true; + break; + } + } + if(node_rangeTemp.second - node_rangeTemp.first != 1) { + if(node_rangeTemp.second - node_rangeTemp.first + 2 >= node_range.second - node_range.first) similar_range++; + else if(node_rangeTemp.second - node_rangeTemp.first + 4 < node_range.second - node_range.first) similar_range = 0; + } else { + pseudogeneStop_ = false; + } + } + + if(anchorStop_) { + if(node_rangeTemp.second - node_rangeTemp.first != 1 && node_range.second - node_range.first == node_rangeTemp.second - node_rangeTemp.first) { + same_range++; + if(same_range >= 5) { + anchorStop_ = false; + } + } else { + same_range = 0; + } + + if(dep - offset >= _minK + 8 && node_rangeTemp.second - node_rangeTemp.first >= 4) { + anchorStop_ = false; + } + } + + range = rangeTemp; + node_range = node_rangeTemp; + if(_tmp_node_iedge_count.size() > 0) { + _node_iedge_count = _tmp_node_iedge_count; + _tmp_node_iedge_count.clear(); + } else { + _node_iedge_count.clear(); + } + dep++; + + if(anchorStop_) { + if(dep - offset >= _minK + 12 && range.second - range.first == 1) { + hit._numUniqueSearch++; + anchorStop = true; + break; + } + } + + HIER_INIT_LOCS(range.first, range.second, tloc, bloc, gfm); + } + + // Done + if(range.first < range.second) { + assert_leq(node_range.second - node_range.first, range.second - range.first); + assert_gt(dep, offset); + assert_leq(dep, len); + partialHits.expand(); + index_t hit_type = CANDIDATE_HIT; + if(anchorStop) hit_type = ANCHOR_HIT; + else if(pseudogeneStop) hit_type = PSEUDOGENE_HIT; + bool report = node_range.first < node_range.second; + if(node_range.second - node_range.first < range.second - range.first) { + if(_node_iedge_count.size() == 0) report = false; + } + if(report) { +#ifndef NDEBUG + if(node_range.second - node_range.first < range.second - range.first) { + ASSERT_ONLY(index_t add = 0); + for(index_t e = 0; e < _node_iedge_count.size(); e++) { + if(e > 0) { + assert_lt(_node_iedge_count[e-1].first, _node_iedge_count[e].first); + } + assert_gt(_node_iedge_count[e].second, 0); + add += _node_iedge_count[e].second; + } + assert_eq(node_range.second - node_range.first + add, range.second - range.first); + } else { + assert(_node_iedge_count.empty()); + } +#endif + partialHits.back().init(range.first, + range.second, + node_range.first, + node_range.second, + _node_iedge_count, + fw, + (index_t)offset, + (index_t)(dep - offset), + hit_type); + } else { + _node_iedge_count.clear(); + partialHits.back().init(INDEX_MAX, + INDEX_MAX, + INDEX_MAX, + INDEX_MAX, + _node_iedge_count, + fw, + (index_t)offset, + (index_t)(dep - offset), + hit_type); + } + + nelt += (node_range.second - node_range.first); + cur = dep; + if(cur >= hit._len) { + if(hit_type == CANDIDATE_HIT) hit._numUniqueSearch++; + hit.done(true); + } + } + return (index_t)nelt; +} + + +/** + */ +template +index_t HI_Aligner::globalGFMSearch( + const GFM& gfm, // BWT index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + const ReportingParams& rp, + bool fw, + index_t hitoff, + index_t& hitlen, + index_t& top, + index_t& bot, + index_t& node_top, + index_t& node_bot, + EList >& node_iedge_count, + RandomSource& rnd, + bool& uniqueStop, + index_t maxHitLen) +{ + bool uniqueStop_ = uniqueStop; + uniqueStop = false; + const index_t ftabLen = gfm.gh().ftabChars(); + const bool linearFM = gfm.gh().linearFM(); + SideLocus tloc, bloc; + const index_t len = (index_t)read.length(); + + size_t nelt = 0; + const BTDnaString& seq = fw ? read.patFw : read.patRc; + assert(!seq.empty()); + + index_t offset = len - hitoff - 1; + index_t dep = offset; + pair range(0, 0); + pair rangeTemp(0, 0); + pair node_range(0, 0); + pair node_rangeTemp(0, 0); + node_iedge_count.clear(); + _tmp_node_iedge_count.clear(); + index_t left = len - dep; + assert_gt(left, 0); + if(left < ftabLen + 1) { + hitlen = left; + return 0; + } + + // Does N interfere with use of Ftab? + for(index_t i = 0; i < ftabLen; i++) { + int c = seq[len-dep-1-i]; + if(c > 3) { + hitlen = (i+1); + return 0; + } + } + + // Use ftab + gfm.ftabLoHi(seq, len - dep - ftabLen, false, range.first, range.second); + dep += ftabLen; + if(range.first >= range.second) { + hitlen = ftabLen; + return 0; + } + + HIER_INIT_LOCS(range.first, range.second, tloc, bloc, gfm); + // Keep going + while(dep < len) { + int c = seq[len-dep-1]; + if(c > 3) { + rangeTemp.first = rangeTemp.second = 0; + node_rangeTemp.first = node_rangeTemp.second = 0; + _tmp_node_iedge_count.clear(); + } else { + if(bloc.valid()) { + bwops_ += 2; + if(linearFM) { + rangeTemp = gfm.mapLF(tloc, bloc, c, &node_rangeTemp); + } else { + rangeTemp = gfm.mapGLF(tloc, bloc, c, &node_rangeTemp, &_tmp_node_iedge_count, (index_t)rp.kseeds); + } + } else { + bwops_++; + rangeTemp = gfm.mapGLF1(range.first, tloc, c, &node_rangeTemp); + if(rangeTemp.first + 1 < rangeTemp.second) { + assert_eq(node_rangeTemp.first + 1, node_rangeTemp.second); + _tmp_node_iedge_count.clear(); + _tmp_node_iedge_count.expand(); + _tmp_node_iedge_count.back().first = 0; + _tmp_node_iedge_count.back().second = rangeTemp.second - rangeTemp.first - 1; + } + } + } + if(rangeTemp.first >= rangeTemp.second) { + break; + } + + range = rangeTemp; + node_range = node_rangeTemp; + if(_tmp_node_iedge_count.size() > 0) { + node_iedge_count = _tmp_node_iedge_count; + _tmp_node_iedge_count.clear(); + } else { + node_iedge_count.clear(); + } + dep++; + + if(uniqueStop_) { + if(range.second - range.first == 1 && dep - offset >= _minK) { + uniqueStop = true; + break; + } + } + + HIER_INIT_LOCS(range.first, range.second, tloc, bloc, gfm); + } + + // Done + if(node_range.first < node_range.second && node_range.second - node_range.first <= rp.kseeds) { + assert_leq(node_range.second - node_range.first, range.second - range.first); +#ifndef NDEBUG + if(node_range.second - node_range.first < range.second - range.first) { + ASSERT_ONLY(index_t add = 0); + for(index_t e = 0; e < node_iedge_count.size(); e++) { + if(e > 0) { + assert_lt(node_iedge_count[e-1].first, node_iedge_count[e].first); + } + assert_gt(node_iedge_count[e].second, 0); + add += node_iedge_count[e].second; + } + assert_eq(node_range.second - node_range.first + add, range.second - range.first); + } else { + assert(node_iedge_count.empty()); + } +#endif + assert_gt(dep, offset); + assert_leq(dep, len); + top = range.first; bot = range.second; + node_top = node_range.first; node_bot = node_range.second; + nelt += (node_bot - node_top); + hitlen = dep - offset; + } + return (index_t)nelt; +} + + +/** + * + **/ +template +index_t HI_Aligner::localGFMSearch( + const LocalGFM& gfm, // GFM index + const Read& read, // read to align + const Scoring& sc, // scoring scheme + const ReportingParams& rp, + bool fw, + index_t rdoff, + index_t& hitlen, + local_index_t& top, + local_index_t& bot, + local_index_t& node_top, + local_index_t& node_bot, + EList >& local_node_iedge_count, + RandomSource& rnd, + bool& uniqueStop, + local_index_t minUniqueLen, + local_index_t maxHitLen, + local_index_t maxHits) +{ + maxHits = max(maxHits, rp.kseeds); + bool uniqueStop_ = uniqueStop; + uniqueStop = false; + const local_index_t ftabLen = (local_index_t)gfm.gh().ftabChars(); + const bool linearFM = gfm.gh().linearFM(); + SideLocus tloc, bloc; + const local_index_t len = (local_index_t)read.length(); + size_t nelt = 0; + + const BTDnaString& seq = fw ? read.patFw : read.patRc; + assert(!seq.empty()); + + local_index_t offset = len - rdoff - 1; + local_index_t dep = offset; + pair range(0, 0); + pair rangeTemp(0, 0); + pair node_range(0, 0); + pair node_rangeTemp(0, 0); + top = bot = node_top = node_bot = 0; + local_node_iedge_count.clear(); + _tmp_local_node_iedge_count.clear(); + local_index_t left = len - dep; + assert_gt(left, 0); + if(left < ftabLen + 1) { + hitlen = left; + return 0; + } + // Does N interfere with use of Ftab? + for(local_index_t i = 0; i < ftabLen; i++) { + int c = seq[len-dep-1-i]; + if(c > 3) { + hitlen = i + 1; + return 0; + } + } + + gfm.ftabLoHi(seq, len - dep - ftabLen, false, range.first, range.second); + dep += ftabLen; + if(range.first >= range.second) { + hitlen = ftabLen; + return 0; + } + LOCAL_INIT_LOCS(range.first, range.second, tloc, bloc, gfm); + // Keep going + while(dep < len) { + int c = seq[len-dep-1]; + if(c > 3) { + rangeTemp.first = rangeTemp.second = 0; + node_rangeTemp.first = node_rangeTemp.second = 0; + _tmp_local_node_iedge_count.clear(); + } else { + if(bloc.valid()) { + bwops_ += 2; + if(linearFM) { + rangeTemp = gfm.mapLF(tloc, bloc, c, &node_rangeTemp); + } else { + rangeTemp = gfm.mapGLF(tloc, bloc, c, &node_rangeTemp, &_tmp_local_node_iedge_count, rp.kseeds); + } + } else { + bwops_++; + rangeTemp = gfm.mapGLF1(range.first, tloc, c, &node_rangeTemp); + if(rangeTemp.first + 1 < rangeTemp.second) { + assert_eq(node_rangeTemp.first + 1, node_rangeTemp.second); + _tmp_local_node_iedge_count.clear(); + _tmp_local_node_iedge_count.expand(); + _tmp_local_node_iedge_count.back().first = 0; + _tmp_local_node_iedge_count.back().second = rangeTemp.second - rangeTemp.first - 1; + } + } + } + if(rangeTemp.first >= rangeTemp.second) { + break; + } + + range = rangeTemp; + node_range = node_rangeTemp; + if(_tmp_local_node_iedge_count.size() > 0) { + local_node_iedge_count = _tmp_local_node_iedge_count; + _tmp_local_node_iedge_count.clear(); + } else { + local_node_iedge_count.clear(); + } + dep++; + + if(uniqueStop_) { + if(range.second - range.first == 1 && dep - offset >= minUniqueLen) { + uniqueStop = true; + break; + } + } + + if(dep - offset >= maxHitLen) break; + LOCAL_INIT_LOCS(range.first, range.second, tloc, bloc, gfm); + } + + // Done + if(node_range.first < node_range.second && node_range.second - node_range.first <= maxHits) { + assert_leq(node_range.second - node_range.first, range.second - range.first); +#ifndef NDEBUG + if(node_range.second - node_range.first < range.second - range.first) { + ASSERT_ONLY(index_t add = 0); + for(index_t e = 0; e < local_node_iedge_count.size(); e++) { + if(e > 0) { + assert_lt(local_node_iedge_count[e-1].first, local_node_iedge_count[e].first); + } + assert_gt(local_node_iedge_count[e].second, 0); + add += local_node_iedge_count[e].second; + } + assert_eq(node_range.second - node_range.first + add, range.second - range.first); + } else { + assert(local_node_iedge_count.empty()); + } +#endif + assert_gt(dep, offset); + assert_leq(dep, len); + top = range.first; bot = range.second; + node_top = node_range.first; node_bot = node_range.second; + nelt += (node_bot - node_top); + hitlen = dep - offset; + } + + return (index_t)nelt; +} + +/** + * + **/ +template +bool HI_Aligner::isSearched( + const GenomeHit& hit, + index_t rdi) +{ + assert_lt(rdi, 2); + EList >& searchedHits = _hits_searched[rdi]; + for(index_t i = 0; i < searchedHits.size(); i++) { + if(searchedHits[i].contains(hit)) return true; + } + return false; +} + +/** + * + **/ +template +void HI_Aligner::addSearched( + const GenomeHit& hit, + index_t rdi) +{ + assert_lt(rdi, 2); + assert(!isSearched(hit, rdi)); + EList >& searchedHits = _hits_searched[rdi]; + searchedHits.push_back(hit); +} + +#endif /*HI_ALIGNER_H_*/ diff --git a/hier_idx_common.h b/hier_idx_common.h new file mode 100644 index 0000000..1e794e6 --- /dev/null +++ b/hier_idx_common.h @@ -0,0 +1,43 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * Beast is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef HIERGBWT_COMMON_H_ +#define HIERGBWT_COMMON_H_ + +// maximum size of a sequence represented by a local index +static const uint32_t local_index_size = (1 << 16) - (1 << 13); // 1 << 5 is necessary for eftab index +static const uint32_t local_max_gbwt = (1 << 16) - (1 << 11); + +// size of the overlapped sequence between the sequences represented by two consecutive local indexes +static const uint32_t local_index_overlap = 1024; + +// interval between two consecutive local indexes +static const uint32_t local_index_interval = local_index_size - local_index_overlap; + +// line rate in local indexes +static const int32_t local_lineRate_fm = 6; +static const int32_t local_lineRate_gfm = 7; + +// how many rows are marked in a local index, every 2^th row is marked +static const int32_t local_offRate = 3; + +// the look table in a local index 4^ entries +static const int32_t local_ftabChars = 6; + +#endif /*HIERGBWT_COMMON_H_*/ diff --git a/hisat-3n b/hisat-3n new file mode 100644 index 0000000..dcfee89 --- /dev/null +++ b/hisat-3n @@ -0,0 +1,782 @@ +#!/usr/bin/env perl + +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +# hisat-3n: +# +# A wrapper script for hisat-3n. Provides various advantages over running +# hisat directly, including: +# +# 1. Handling compressed inputs +# 2. Redirecting output to various files +# 3. Output directly to bam (not currently supported) + +use strict; +use warnings; +use Getopt::Long qw(GetOptions); +use File::Spec; +use POSIX; + + +my ($vol,$script_path,$prog); +$prog = File::Spec->rel2abs( __FILE__ ); + +while (-f $prog && -l $prog){ + my (undef, $dir, undef) = File::Spec->splitpath($prog); + $prog = File::Spec->rel2abs(readlink($prog), $dir); +} + +($vol,$script_path,$prog) + = File::Spec->splitpath($prog); +my $os_is_nix = ($^O eq "linux") || ($^O eq "darwin"); +my $align_bin_s = $os_is_nix ? 'hisat2-align-s' : 'hisat2-align-s.exe'; +my $build_bin = $os_is_nix ? 'hisat2-build' : 'hisat2-build.exe'; +my $align_bin_l = $os_is_nix ? 'hisat2-align-l' : 'hisat2-align-l.exe'; +my $align_prog_s= File::Spec->catpath($vol,$script_path,$align_bin_s); +my $align_prog_l= File::Spec->catpath($vol,$script_path,$align_bin_l); +my $align_prog = $align_prog_s; +my $read_stat_prog = File::Spec->catpath($vol,$script_path,"hisat2_read_statistics.py"); +my $idx_ext_l = 'ht2l'; +my $idx_ext_s = 'ht2'; +my $idx_ext = $idx_ext_s; +my $seq_in_args = 0; +my $skip_read_stat = 0; +my %signo = (); +my @signame = (); +my $basechange_pair = 'CT'; + +# HISAT-3N basechange type +my %conversion_type = ( + "AT" => 0, "AC" => 0, "CG" => 0, "CT" => 0, "GA" => 0, "TG" => 0, + # need to reverse From,To bases + "CA" => 1, "GC" => 1, "TA" => 1, "TC" => 1, "AG" => 1, "GT" => 1, + ); + +my %convertion_rc = ( + "AT" => "TA", "AC" => "TG", "CG" => "GC", + "CT" => "GA", "GA" => "CT", "TG" => "AC", + ); + +sub getConversion { + my $from = uc $_[0]; + my $to = uc $_[1]; + my $conv_pair = $from.$to; + + my $val = $conversion_type{$conv_pair}; + + if (defined $val) { + if ($val) { + $conv_pair = $to.$from; + } + } else { + return undef; + } + + return $conv_pair; +} + +{ + # Get signal info + use Config; + my $i = 0; + for my $name (split(' ', $Config{sig_name})) { + $signo{$name} = $i; + $signame[$i] = $name; + $i++; + } +} + +(-x "$align_prog") || + Fail("Expected hisat2 to be in same directory with hisat2-align-s and hisat2-align-l:\n$script_path\n"); + +(-x "$read_stat_prog") || ($skip_read_stat = 1); + +# Get description of arguments from HISAT so that we can distinguish HISAT +# args from wrapper args +sub getHt2Desc($) { + my $d = shift; + my $cmd = "'$align_prog' --wrapper basic-0 --arg-desc"; + open(my $fh, "$cmd |") || Fail("Failed to run command '$cmd'\n"); + while(readline $fh) { + chomp; + next if /^\s*$/; + my @ts = split(/\t/); + $d->{$ts[0]} = $ts[1]; + } + close($fh); + $? == 0 || Fail("Description of arguments failed!\n"); +} + +my %desc = (); +my %wrapped = ("1" => 1, "2" => 1); +getHt2Desc(\%desc); + +# Given an option like -1, determine whether it's wrapped (i.e. should be +# handled by this script rather than being passed along to HISAT) +sub isWrapped($) { return defined($wrapped{$_[0]}); } + +my @orig_argv = @ARGV; + +my @ht2w_args = (); # options for wrapper +my @ht2_args = (); # options for HISAT +my $saw_dd = 0; +for(0..$#ARGV) { + if($ARGV[$_] eq "--") { + $saw_dd = 1; + next; + } + push @ht2w_args, $ARGV[$_] if !$saw_dd; + push @ht2_args, $ARGV[$_] if $saw_dd; +} +if(!$saw_dd) { + @ht2_args = @ht2w_args; + @ht2w_args= (); +} + +my $debug = 0; +my %read_fns = (); +my %read_compress = (); +my $cap_out = undef; # Filename for passthrough +my $no_unal = 0; +my $large_idx = 0; +# Remove whitespace +for my $i (0..$#ht2_args) { + $ht2_args[$i]=~ s/^\s+//; $ht2_args[$i] =~ s/\s+$//; +} + +# We've handled arguments that the user has explicitly directed either to the +# wrapper or to hisat, now we capture some of the hisat arguments that +# ought to be handled in the wrapper +for(my $i = 0; $i < scalar(@ht2_args); $i++) { + next unless defined($ht2_args[$i]); + my $arg = $ht2_args[$i]; + my @args = split(/=/, $arg); + if(scalar(@args) > 2) { + $args[1] = join("=", @args[1..$#args]); + } + $arg = $args[0]; + if($arg eq "-U" || $arg eq "--unpaired") { + $ht2_args[$i] = undef; + $arg =~ s/^-U//; $arg =~ s/^--unpaired//; + if($arg ne "") { + # Argument was part of this token + my @args = split(/,/, $arg); + for my $a (@args) { push @ht2w_args, ("-U", $a); } + } else { + # Argument is in the next token + $i < scalar(@ht2_args)-1 || Fail("Argument expected in next token!\n"); + $i++; + my @args = split(/,/, $ht2_args[$i]); + for my $a (@args) { push @ht2w_args, ("-U", $a); } + $ht2_args[$i] = undef; + } + } + if($arg =~ /^--?([12])/ && $arg !~ /^--?12/) { + my $mate = $1; + $ht2_args[$i] = undef; + $arg =~ s/^--?[12]//; + if($arg ne "") { + # Argument was part of this token + my @args = split(/,/, $arg); + for my $a (@args) { push @ht2w_args, ("-$mate", $a); } + } else { + # Argument is in the next token + $i < scalar(@ht2_args)-1 || Fail("Argument expected in next token!\n"); + $i++; + my @args = split(/,/, $ht2_args[$i]); + for my $a (@args) { push @ht2w_args, ("-$mate", $a); } + $ht2_args[$i] = undef; + } + } + if($arg eq "--debug") { + $debug = 1; + $ht2_args[$i] = undef; + } + if($arg eq "--no-unal") { + $no_unal = 1; + $ht2_args[$i] = undef; + } + if($arg eq "--large-index") { + $large_idx = 1; + $ht2_args[$i] = undef; + } + if($arg eq "--skip-read-lengths") { + $skip_read_stat = 1; + $ht2_args[$i] = undef + } + if($arg eq "-c") { + $seq_in_args = 1; + } + if($arg eq "--base-change") { + my $base_args = ""; + if (scalar @args > 1 && $args[1] ne "") { + $base_args = $args[1]; + } else { + Fail("${arg} option takes an argument.\n") if ($i >= scalar(@ht2_args)-1); + $base_args = $ht2_args[$i+1]; + $i++; + } + my @basechange_opt = split(/,/, $base_args); + + Fail("Invalid --base-change option\n") if (scalar @basechange_opt != 2); + $basechange_pair = getConversion($basechange_opt[0], $basechange_opt[1]); + + Fail("Invalid --base-change option\n") unless defined $basechange_pair; + } + + for my $rarg ("un-conc", "al-conc", "al-conc-disc", "un", "al") { + if($arg =~ /^--${rarg}$/ || $arg =~ /^--${rarg}-gz$/ || $arg =~ /^--${rarg}-bz2$/) { + $ht2_args[$i] = undef; + if(scalar(@args) > 1 && $args[1] ne "") { + $read_fns{$rarg} = $args[1]; + } else { + $i < scalar(@ht2_args)-1 || Fail("--${rarg}* option takes an argument.\n"); + $read_fns{$rarg} = $ht2_args[$i+1]; + $ht2_args[$i+1] = undef; + } + $read_compress{$rarg} = ""; + $read_compress{$rarg} = "gzip" if $arg eq "--${rarg}-gz"; + $read_compress{$rarg} = "bzip2" if $arg eq "--${rarg}-bz2"; + last; + } + } +} + +# If the user asked us to redirect some reads to files, or to suppress +# unaligned reads, then we need to capture the output from HISAT and pass it +# through this wrapper. +my $passthru = 0; +if(scalar(keys %read_fns) > 0 || $no_unal) { + $passthru = 1; + push @ht2_args, "--passthrough"; + $cap_out = "-"; + for(my $i = 0; $i < scalar(@ht2_args); $i++) { + next unless defined($ht2_args[$i]); + my $arg = $ht2_args[$i]; + if($arg eq "-S" || $arg eq "--output") { + $i < scalar(@ht2_args)-1 || Fail("-S/--output takes an argument.\n"); + $cap_out = $ht2_args[$i+1]; + $ht2_args[$i] = undef; + $ht2_args[$i+1] = undef; + } + } +} +my @tmp = (); +for (@ht2_args) { push(@tmp, $_) if defined($_); } +@ht2_args = @tmp; + +my @unps = (); +my @mate1s = (); +my @mate2s = (); +my @to_delete = (); +my @to_kills = (); +my $temp_dir = "/tmp"; +my $bam_out = 0; +my $ref_str = undef; +my $no_pipes = 0; +my $keep = 0; +my $verbose = 0; +my $readpipe = undef; +my $log_fName = undef; + +my @ht2w_args_cp = (@ht2w_args>0) ? @ht2w_args : @ht2_args; +Getopt::Long::Configure("pass_through","no_ignore_case"); + +my @old_ARGV = @ARGV; +@ARGV = @ht2w_args_cp; + +GetOptions( + "1=s" => \@mate1s, + "2=s" => \@mate2s, + "reads|U=s" => \@unps, + "temp-directory=s" => \$temp_dir, + "bam" => \$bam_out, + "no-named-pipes" => \$no_pipes, + "ref-string|reference-string=s" => \$ref_str, + "keep" => \$keep, + "verbose" => \$verbose, + "log-file=s" => \$log_fName +); + +@ARGV = @old_ARGV; + +my $old_stderr; + +if ($log_fName) { + open($old_stderr, ">&STDERR") or Fail("Cannot dup STDERR!\n"); + open(STDERR, ">", $log_fName) or Fail("Cannot redirect to log file $log_fName.\n"); +} + +Info("Before arg handling:\n"); +Info(" Wrapper args:\n[ @ht2w_args ]\n"); +Info(" Binary args:\n[ @ht2_args ]\n"); + +# check read lengths +# if read_files have more than 1 files, use first one, +my @read_files = (scalar(@unps) > 0) ? @unps : @mate1s; +if ((scalar(@read_files) > 0) + && ($seq_in_args == 0) + && ($skip_read_stat == 0)) { + Info("Check read length: $read_files[0]\n"); + my $cmd = "'$read_stat_prog' $read_files[0]"; + my $read_len_str = ""; + + open(my $fh, "$cmd |") || Fail("Failed to run command '$cmd'\n"); + while(readline $fh) { + chomp; + next if /^\s*$/; + my @ts = split(/ /); + if (scalar(@ts) > 4) { + $read_len_str = $ts[4]; + } else { + $read_len_str = ""; + } + } + close($fh); + + if (($read_len_str ne "") && ($read_len_str ne "0")) { + Info("Read Length String: $read_len_str\n"); + push @ht2_args, ("--read-lengths", $read_len_str); + } +} + +sub check_file_exist($$$) { + my ($unps, $mate1s, $mate2s) = @_; + for my $fn (@$unps, @$mate1s, @$mate2s) { + if (not -f $fn) { + Fail("Read file '%s' doesn't exist\n", $fn); + return 1; + } + } + return 0; +} + +sub cat_file($$) { + my ($ifn, $ofh) = @_; + my $ifh = undef; + if($ifn =~ /\.gz$/) { + open($ifh, "gzip -dc $ifn |") || + Fail("Could not open gzipped read file: $ifn \n"); + } elsif($ifn =~ /\.bz2/) { + open($ifh, "bzip2 -dc $ifn |") || + Fail("Could not open bzip2ed read file: $ifn \n"); + } else { + open($ifh, $ifn) || Fail("Could not open read file: $ifn \n"); + } + while(readline $ifh) { print {$ofh} $_; } + close($ifh); +} + +# Return non-zero if and only if the input should be wrapped (i.e. because +# it's compressed). +sub wrapInput($$$) { + my ($unps, $mate1s, $mate2s) = @_; + for my $fn (@$unps, @$mate1s, @$mate2s) { + return 1 if $fn =~ /\.gz$/ || $fn =~ /\.bz2$/; + } + return 0; +} + +sub Info { + if ($verbose) { + print STDERR "(INFO): " ,@_; + } +} + +sub Error { + my @msg = @_; + $msg[0] = "(ERR): ".$msg[0]; + printf STDERR @msg; +} + +sub Fail { + Error(@_); + die("Exiting now ...\n"); +} + +sub Extract_IndexName_From { + my $index_opt = $ref_str ? '--index' : '-x'; + for (my $i=0; $i<@_; $i++) { + if ($_[$i] eq $index_opt){ + my $idx_basename = $_[$i+1]; + my @idx_filenames = glob($idx_basename . "*.ht2{,l}"); + unless(@idx_filenames) { + if(exists $ENV{"HISAT2_INDEXES"}) { + @idx_filenames = glob("$ENV{'HISAT2_INDEXES'}/$idx_basename" . "ht2{,l}"); + } + + if(!@idx_filenames) { + Fail("\"" . $idx_basename . "\" does not exist\n"); + } + $idx_basename = "$ENV{'HISAT2_INDEXES'}/$idx_basename" + } + + return $idx_basename; + } + } + Info("Cannot find any index option (--reference-string, --ref-string or -x) in the given command line.\n"); +} + +sub Get_IndexFileName { + my $isLargeIndex = $_[0]; + my $IndexPrefix = $_[1]; + my $IndexFileName = "${IndexPrefix}.3n.1.1."; + + if ($isLargeIndex) { + $IndexFileName = $IndexFileName.$idx_ext_l; + } else { + $IndexFileName = $IndexFileName.$idx_ext_s; + } + + return $IndexFileName; +} + +if($seq_in_args == 0) { + check_file_exist(\@unps, \@mate1s, \@mate2s); +} + +if(wrapInput(\@unps, \@mate1s, \@mate2s)) { + if(scalar(@mate2s) > 0) { + # + # Wrap paired-end inputs + # + # Put reads into temporary files or fork off processes to feed named pipes + scalar(@mate2s) == scalar(@mate1s) || + Fail("Different number of files specified with --reads/-1 as with -2\n"); + # Make a named pipe for delivering mate #1s + my $m1fn = "$temp_dir/$$.inpipe1"; + push @to_delete, $m1fn; + push @ht2_args, "-1 $m1fn"; + # Create named pipe 1 for writing + if(!$no_pipes) { + mkfifo($m1fn, 0700) || Fail("mkfifo($m1fn) failed.\n"); + } + my $pid = 0; + $pid = fork() unless $no_pipes; + push @to_kills, $pid unless $no_pipes; + if($pid == 0) { + # Open named pipe 1 for writing + open(my $ofh, ">$m1fn") || Fail("Can't open '$m1fn' for writing\n"); + for my $ifn (@mate1s) { cat_file($ifn, $ofh); } + close($ofh); + exit 0 unless $no_pipes; + } + # Make a named pipe for delivering mate #2s + my $m2fn = "$temp_dir/$$.inpipe2"; + push @to_delete, $m2fn; + push @ht2_args, "-2 $m2fn"; + # Create named pipe 2 for writing + if(!$no_pipes) { + mkfifo($m2fn, 0700) || Fail("mkfifo($m2fn) failed.\n"); + } + $pid = 0; + $pid = fork() unless $no_pipes; + push @to_kills, $pid unless $no_pipes; + if($pid == 0) { + # Open named pipe 2 for writing + open(my $ofh, ">$m2fn") || Fail("Can't open '$m2fn' for writing.\n"); + for my $ifn (@mate2s) { cat_file($ifn, $ofh); } + close($ofh); + exit 0 unless $no_pipes; + } + } + if(scalar(@unps) > 0) { + # + # Wrap unpaired inputs. + # + # Make a named pipe for delivering unpaired reads + my $ufn = "$temp_dir/$$.unp"; + push @to_delete, $ufn; + push @ht2_args, "-U $ufn"; + # Create named pipe 2 for writing + if(!$no_pipes) { + mkfifo($ufn, 0700) || Fail("mkfifo($ufn) failed.\n"); + } + my $pid = 0; + $pid = fork() unless $no_pipes; + if($pid == 0) { + # Open named pipe 2 for writing + open(my $ofh, ">$ufn") || Fail("Can't open '$ufn' for writing.\n"); + for my $ifn (@unps) { cat_file($ifn, $ofh); } + close($ofh); + exit 0 unless $no_pipes; + } + } +} else { + if(scalar(@mate2s) > 0) { + # Just pass all the mate arguments along to the binary + push @ht2_args, ("-1", join(",", @mate1s)); + push @ht2_args, ("-2", join(",", @mate2s)); + } + if(scalar(@unps) > 0) { + push @ht2_args, ("-U", join(",", @unps)); + } +} + +if(defined($ref_str)) { + my $ofn = "$temp_dir/$$.ref_str.fa"; + open(my $ofh, ">$ofn") || + Fail("could not open temporary fasta file '$ofn' for writing.\n"); + print {$ofh} ">1\n$ref_str\n"; + close($ofh); + push @to_delete, $ofn; + system("$build_bin $ofn $ofn") == 0 || + Fail("hisat2-build returned non-0 exit level.\n"); + push @ht2_args, ("--index", "$ofn"); + push @to_delete, ("$ofn.1.".$idx_ext, "$ofn.2.".$idx_ext, + "$ofn.3.".$idx_ext, "$ofn.4.".$idx_ext, + "$ofn.5.".$idx_ext, "$ofn.6.".$idx_ext, + "$ofn.7.".$idx_ext, "$ofn.8.".$idx_ext); +} + +Info("After arg handling:\n"); +Info(" Binary args:\n[ @ht2_args ]\n"); + +sub find_hisat3n_index { + my $isLargeIndex = $_[0]; + my $IndexName = $_[1]; + + my $basepair = $basechange_pair; + my $rc_basepair = $convertion_rc{$basechange_pair}; + + my @IndexNames = ( + $IndexName.".3n.$basepair.1", + $IndexName.".3n.$rc_basepair.1" + ); + + my @IndexFullName = (); + if ($isLargeIndex) { + for (@IndexNames) { + push @IndexFullName, $_.".$idx_ext_l"; + } + } else { + for (@IndexNames) { + push @IndexFullName, $_.".$idx_ext_s"; + } + } + + if (-f $IndexFullName[0] && -f $IndexFullName[1]) { + return @IndexFullName; + } + + # find old-name-format index file + @IndexNames = ( + $IndexName.".3n.1.1", + $IndexName.".3n.2.1" + ); + @IndexFullName = (); + if ($isLargeIndex) { + for (@IndexNames) { + push @IndexFullName, $_.".$idx_ext_l"; + } + } else { + for (@IndexNames) { + push @IndexFullName, $_.".$idx_ext_s"; + } + } + + if (-f $IndexFullName[0] && -f $IndexFullName[1]) { + return @IndexFullName; + } + + # empty array + return (); +} + +my $index_name = Extract_IndexName_From(@ht2_args); +my $def_index_filename_s = $index_name.".3n.$basechange_pair.1.$idx_ext_s"; +my $def_index_filename_l = $index_name.".3n.$basechange_pair.1.$idx_ext_l"; + +if ($large_idx) { + Info("Using a large index enforced by user.\n"); + $align_prog = $align_prog_l; + $idx_ext = $idx_ext_l; + my @IndexNames = find_hisat3n_index($large_idx, $index_name); + if (scalar @IndexNames == 0) { + Fail("Cannot find the large index $def_index_filename_l\n"); + } + Info("Using large index ($IndexNames[0]).\n"); +} +else { + my @LargeIndexNames = find_hisat3n_index(1, $index_name); + my @SmallIndexNames = find_hisat3n_index(0, $index_name); + + if ((scalar @LargeIndexNames > 0) && (scalar @SmallIndexNames == 0)) { + Info("Cannot find a small index but a large one seems to be present.\n"); + Info("Switching to using the large index ($LargeIndexNames[0]).\n"); + $align_prog = $align_prog_l; + $idx_ext = $idx_ext_l; + } + else { + Info("Using the small index (${def_index_filename_s}).\n") + } +} + +my $debug_str = ($debug ? "-debug" : ""); +push @ht2_args, "--3N"; +# Construct command invoking hisat2-align +my $cmd = "'$align_prog$debug_str' --wrapper basic-0 ".join(" ", @ht2_args); + +# Possibly add read input on an anonymous pipe +$cmd = "$readpipe $cmd" if defined($readpipe); + +Info("$cmd\n"); +my $ret; +if(defined($cap_out)) { + # Open HISAT2 pipe + open(HT, "$cmd |") || Fail("Could not open HISAT2 pipe: '$cmd |'\n"); + # Open output pipe + my $ofh = *STDOUT; + my @fhs_to_close = (); + if($cap_out ne "-") { + open($ofh, ">$cap_out") || + Fail("Could not open output file '$cap_out' for writing.\n"); + } + my %read_fhs = (); + for my $i ("al", "un", "al-conc", "al-conc-disc", "un-conc") { + if(defined($read_fns{$i})) { + my ($vol, $base_spec_dir, $base_fname) = File::Spec->splitpath($read_fns{$i}); + if (-d $read_fns{$i}) { + $base_spec_dir = $read_fns{$i}; + $base_fname = undef; + } + if($i =~ /-conc$/ || $i =~ /-conc-disc$/) { + # Open 2 output files, one for mate 1, one for mate 2 + my ($fn1, $fn2); + if ($base_fname) { + ($fn1, $fn2) = ($base_fname,$base_fname); + } + else { + ($fn1, $fn2) = ($i.'-mate',$i.'-mate'); + } + if($fn1 =~ /%/) { + $fn1 =~ s/%/1/g; $fn2 =~ s/%/2/g; + } elsif($fn1 =~ /\.[^.]*$/) { + $fn1 =~ s/\.([^.]*)$/.1.$1/; + $fn2 =~ s/\.([^.]*)$/.2.$1/; + } else { + $fn1 .= ".1"; + $fn2 .= ".2"; + } + $fn1 = File::Spec->catpath($vol,$base_spec_dir,$fn1); + $fn2 = File::Spec->catpath($vol,$base_spec_dir,$fn2); + $fn1 ne $fn2 || Fail("$fn1\n$fn2\n"); + my ($redir1, $redir2) = (">$fn1", ">$fn2"); + $redir1 = "| gzip -c $redir1" if $read_compress{$i} eq "gzip"; + $redir1 = "| bzip2 -c $redir1" if $read_compress{$i} eq "bzip2"; + $redir2 = "| gzip -c $redir2" if $read_compress{$i} eq "gzip"; + $redir2 = "| bzip2 -c $redir2" if $read_compress{$i} eq "bzip2"; + open($read_fhs{$i}{1}, $redir1) || Fail("Could not open --$i mate-1 output file '$fn1'\n"); + open($read_fhs{$i}{2}, $redir2) || Fail("Could not open --$i mate-2 output file '$fn2'\n"); + push @fhs_to_close, $read_fhs{$i}{1}; + push @fhs_to_close, $read_fhs{$i}{2}; + } else { + my $redir = ">".File::Spec->catpath($vol,$base_spec_dir,$i."-seqs"); + if ($base_fname) { + $redir = ">$read_fns{$i}"; + } + $redir = "| gzip -c $redir" if $read_compress{$i} eq "gzip"; + $redir = "| bzip2 -c $redir" if $read_compress{$i} eq "bzip2"; + open($read_fhs{$i}, $redir) || Fail("Could not open --$i output file '$read_fns{$i}'\n"); + push @fhs_to_close, $read_fhs{$i}; + } + } + } + while() { + chomp; + my $filt = 0; + unless(substr($_, 0, 1) eq "@") { + # If we are supposed to output certain reads to files... + my $tab1_i = index($_, "\t") + 1; + my $tab2_i = index($_, "\t", $tab1_i); + my $fl = substr($_, $tab1_i, $tab2_i - $tab1_i); + my $unal = ($fl & 4) != 0; + my $secondary = ($fl & 256) != 0; + $filt = 1 if $no_unal && $unal; + if($passthru) { + if(scalar(keys %read_fhs) == 0) { + # Next line is read with some whitespace escaped + my $l = ; + } else { + my $mate1 = (($fl & 64) != 0); + my $mate2 = (($fl & 128) != 0); + my $unp = !$mate1 && !$mate2; + my $pair = !$unp; + # Next line is read with some whitespace escaped + my $l = ; + chomp($l); + $l =~ s/%(..)/chr(hex($1))/eg; + if((defined($read_fhs{un}) || defined($read_fhs{al})) && $unp && !$secondary) { + if($unal) { + # Failed to align + print {$read_fhs{un}} $l if defined($read_fhs{un}); + } else { + # Aligned + print {$read_fhs{al}} $l if defined($read_fhs{al}); + } + } + if((defined($read_fhs{"un-conc"}) || defined($read_fhs{"al-conc"}) || defined($read_fhs{"al-conc-disc"})) && $pair && !$secondary) { + my $conc = (($fl & 2) != 0); + my $conc_disc = ($fl & 4) == 0 || ($fl & 8) == 0; + if($conc && $mate1) { + print {$read_fhs{"al-conc"}{1}} $l if defined($read_fhs{"al-conc"}); + } elsif($conc && $mate2) { + print {$read_fhs{"al-conc"}{2}} $l if defined($read_fhs{"al-conc"}); + } elsif(!$conc && $mate1) { + print {$read_fhs{"un-conc"}{1}} $l if defined($read_fhs{"un-conc"}); + } elsif(!$conc && $mate2) { + print {$read_fhs{"un-conc"}{2}} $l if defined($read_fhs{"un-conc"}); + } + if($conc_disc && $mate1) { + print {$read_fhs{"al-conc-disc"}{1}} $l if defined($read_fhs{"al-conc-disc"}); + } elsif($conc_disc && $mate2) { + print {$read_fhs{"al-conc-disc"}{2}} $l if defined($read_fhs{"al-conc-disc"}); + } + } + } + } + } + print {$ofh} "$_\n" if !$filt; + } + for my $k (@fhs_to_close) { close($k); } + close($ofh); + close(HT); + $ret = $?; +} else { + $ret = system($cmd); +} +kill 'TERM', @to_kills; + +if(!$keep) { for(@to_delete) { unlink($_); } } + +if ($ret == -1) { + Error("Failed to execute hisat2-align: $!\n"); + exit 1; +} elsif ($ret & 127) { + my $signm = "(unknown)"; + $signm = $signame[$ret & 127] if defined($signame[$ret & 127]); + my $ad = ""; + $ad = "(core dumped)" if (($ret & 128) != 0); + Error("hisat2-align died with signal %d (%s) $ad\n", ($ret & 127), $signm); + exit 1; +} elsif($ret != 0) { + Error("hisat2-align exited with value %d\n", ($ret >> 8)); +} +exit ($ret >> 8); diff --git a/hisat-3n-build b/hisat-3n-build new file mode 100644 index 0000000..54f511e --- /dev/null +++ b/hisat-3n-build @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +""" + Copyright 2015, Daehwan Kim + + This file is part of HISAT 2. + + HISAT 2 is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + HISAT 2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with HISAT 2. If not, see . +""" + + +import os +import sys +import inspect +import logging +import re + + + +def build_args(): + """ + Parse the wrapper arguments. Returns the options, tuple. + """ + + parsed_args = {} + to_remove = [] + argv = sys.argv[:] + for i, arg in enumerate(argv): + if arg == '--large-index': + parsed_args[arg] = "" + to_remove.append(i) + elif arg == '--debug': + parsed_args[arg] = "" + to_remove.append(i) + elif arg == '--verbose': + parsed_args[arg] = "" + to_remove.append(i) + + for i in reversed(to_remove): + del argv[i] + + return parsed_args, argv + + +def main(): + logging.basicConfig(level=logging.ERROR, + format='%(levelname)s: %(message)s' + ) + delta = 200 + small_index_max_size= 4 * 1024**3 - delta + build_bin_name = "hisat2-build" + build_bin_s = "hisat2-build-s" + build_bin_l = "hisat2-build-l" + curr_script = os.path.realpath(inspect.getsourcefile(main)) + ex_path = os.path.dirname(curr_script) + build_bin_spec = os.path.join(ex_path,build_bin_s) + #repeat_bin_spec = os.path.join(ex_path,"hisat2-repeat") + + options, argv = build_args() + + if '--verbose' in options: + logging.getLogger().setLevel(logging.INFO) + + if '--debug' in options: + build_bin_spec += '-debug' + build_bin_l += '-debug' + + if '--large-index' in options: + build_bin_spec = os.path.join(ex_path,build_bin_l) + elif len(argv) >= 2: + ref_fnames = argv[-2] + tot_size = 0 + for fn in ref_fnames.split(','): + if os.path.exists(fn): + statinfo = os.stat(fn) + tot_size += statinfo.st_size + if tot_size > small_index_max_size: + build_bin_spec = os.path.join(ex_path, build_bin_l) + + + if "--repeat-index" in argv: + #build repeat index first + if argv[1].startswith('-'): + outputName = argv[-1] + else: + outputName = argv[2] + nThread = "1" + repeatLength = "100-300" + repeatCount = "5" + referenceName = "" + base_change = "" + removeRepeatLength = False + for i in range(len(argv)): + if argv[i] == "--base-change": + base_change = argv[i+1] + if argv[i] == "-p": + nThread = argv[i+1] + elif argv[i] == "-f": + referenceName = argv[i+1] + elif argv[i] == "--repeat-index": + if ("--repeat-index" != argv[-1]): + match = re.match(r'\d+-\d+', argv[i+1]) + if match: + repeatLength = argv[i+1] + removeRepeatLength = True + if removeRepeatLength: + argv.remove(repeatLength) + if len(referenceName) == 0: + if argv[1].startswith('-'): + referenceName = argv[-2] + else: + referenceName = argv[1] + cwd = sys.path[0] + + repeatArgv = [] + repeatArgv += [cwd + "/hisat2-repeat"] + repeatArgv += ["-p", nThread] + repeatArgv += ["--repeat-length", repeatLength] + repeatArgv += ["--repeat-count", repeatCount] + repeatArgv += ["--base-change", base_change] + repeatArgv += ["--3N"] + repeatArgv += [referenceName, outputName] + try: + os.system(" ".join(repeatArgv)) + except ValueError: + print("Can not automatically generate repeat database for HISAT-3N. Please manually generate repeat database by using hisat2-repeat.") + + argv.append("--3N") + + argv[0] = build_bin_name + argv.insert(1, 'basic-0') + argv.insert(1, '--wrapper') + logging.info('Command: %s %s' % (build_bin_spec, ' '.join(argv[1:]))) + os.execv(build_bin_spec, argv) + +if __name__ == "__main__": + main() diff --git a/hisat2 b/hisat2 new file mode 100644 index 0000000..0f128b9 --- /dev/null +++ b/hisat2 @@ -0,0 +1,665 @@ +#!/usr/bin/env perl + +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +# hisat2: +# +# A wrapper script for hisat2. Provides various advantages over running +# hisat directly, including: +# +# 1. Handling compressed inputs +# 2. Redirecting output to various files +# 3. Output directly to bam (not currently supported) + +use strict; +use warnings; +use Getopt::Long qw(GetOptions); +use File::Spec; +use POSIX; + + +my ($vol,$script_path,$prog); +$prog = File::Spec->rel2abs( __FILE__ ); + +while (-f $prog && -l $prog){ + my (undef, $dir, undef) = File::Spec->splitpath($prog); + $prog = File::Spec->rel2abs(readlink($prog), $dir); +} + +($vol,$script_path,$prog) + = File::Spec->splitpath($prog); +my $os_is_nix = ($^O eq "linux") || ($^O eq "darwin"); +my $align_bin_s = $os_is_nix ? 'hisat2-align-s' : 'hisat2-align-s.exe'; +my $build_bin = $os_is_nix ? 'hisat2-build' : 'hisat2-build.exe'; +my $align_bin_l = $os_is_nix ? 'hisat2-align-l' : 'hisat2-align-l.exe'; +my $align_prog_s= File::Spec->catpath($vol,$script_path,$align_bin_s); +my $align_prog_l= File::Spec->catpath($vol,$script_path,$align_bin_l); +my $align_prog = $align_prog_s; +my $read_stat_prog = File::Spec->catpath($vol,$script_path,"hisat2_read_statistics.py"); +my $idx_ext_l = 'ht2l'; +my $idx_ext_s = 'ht2'; +my $idx_ext = $idx_ext_s; +my $seq_in_args = 0; +my $skip_read_stat = 0; +my %signo = (); +my @signame = (); + +{ + # Get signal info + use Config; + my $i = 0; + for my $name (split(' ', $Config{sig_name})) { + $signo{$name} = $i; + $signame[$i] = $name; + $i++; + } +} + +(-x "$align_prog") || + Fail("Expected hisat2 to be in same directory with hisat2-align-s and hisat2-align-l:\n$script_path\n"); + +(-x "$read_stat_prog") || ($skip_read_stat = 1); + +# Get description of arguments from HISAT so that we can distinguish HISAT +# args from wrapper args +sub getHt2Desc($) { + my $d = shift; + my $cmd = "'$align_prog' --wrapper basic-0 --arg-desc"; + open(my $fh, "$cmd |") || Fail("Failed to run command '$cmd'\n"); + while(readline $fh) { + chomp; + next if /^\s*$/; + my @ts = split(/\t/); + $d->{$ts[0]} = $ts[1]; + } + close($fh); + $? == 0 || Fail("Description of arguments failed!\n"); +} + +my %desc = (); +my %wrapped = ("1" => 1, "2" => 1); +getHt2Desc(\%desc); + +# Given an option like -1, determine whether it's wrapped (i.e. should be +# handled by this script rather than being passed along to HISAT) +sub isWrapped($) { return defined($wrapped{$_[0]}); } + +my @orig_argv = @ARGV; + +my @ht2w_args = (); # options for wrapper +my @ht2_args = (); # options for HISAT +my $saw_dd = 0; +for(0..$#ARGV) { + if($ARGV[$_] eq "--") { + $saw_dd = 1; + next; + } + push @ht2w_args, $ARGV[$_] if !$saw_dd; + push @ht2_args, $ARGV[$_] if $saw_dd; +} +if(!$saw_dd) { + @ht2_args = @ht2w_args; + @ht2w_args= (); +} + +my $debug = 0; +my %read_fns = (); +my %read_compress = (); +my $cap_out = undef; # Filename for passthrough +my $no_unal = 0; +my $large_idx = 0; +# Remove whitespace +for my $i (0..$#ht2_args) { + $ht2_args[$i]=~ s/^\s+//; $ht2_args[$i] =~ s/\s+$//; +} + +# We've handled arguments that the user has explicitly directed either to the +# wrapper or to hisat, now we capture some of the hisat arguments that +# ought to be handled in the wrapper +for(my $i = 0; $i < scalar(@ht2_args); $i++) { + next unless defined($ht2_args[$i]); + my $arg = $ht2_args[$i]; + my @args = split(/=/, $arg); + if(scalar(@args) > 2) { + $args[1] = join("=", @args[1..$#args]); + } + $arg = $args[0]; + if($arg eq "-U" || $arg eq "--unpaired") { + $ht2_args[$i] = undef; + $arg =~ s/^-U//; $arg =~ s/^--unpaired//; + if($arg ne "") { + # Argument was part of this token + my @args = split(/,/, $arg); + for my $a (@args) { push @ht2w_args, ("-U", $a); } + } else { + # Argument is in the next token + $i < scalar(@ht2_args)-1 || Fail("Argument expected in next token!\n"); + $i++; + my @args = split(/,/, $ht2_args[$i]); + for my $a (@args) { push @ht2w_args, ("-U", $a); } + $ht2_args[$i] = undef; + } + } + if($arg =~ /^--?([12])/ && $arg !~ /^--?12/) { + my $mate = $1; + $ht2_args[$i] = undef; + $arg =~ s/^--?[12]//; + if($arg ne "") { + # Argument was part of this token + my @args = split(/,/, $arg); + for my $a (@args) { push @ht2w_args, ("-$mate", $a); } + } else { + # Argument is in the next token + $i < scalar(@ht2_args)-1 || Fail("Argument expected in next token!\n"); + $i++; + my @args = split(/,/, $ht2_args[$i]); + for my $a (@args) { push @ht2w_args, ("-$mate", $a); } + $ht2_args[$i] = undef; + } + } + if($arg eq "--debug") { + $debug = 1; + $ht2_args[$i] = undef; + } + if($arg eq "--no-unal") { + $no_unal = 1; + $ht2_args[$i] = undef; + } + if($arg eq "--large-index") { + $large_idx = 1; + $ht2_args[$i] = undef; + } + if($arg eq "--skip-read-lengths") { + $skip_read_stat = 1; + $ht2_args[$i] = undef + } + if($arg eq "-c") { + $seq_in_args = 1; + } + for my $rarg ("un-conc", "al-conc", "al-conc-disc", "un", "al") { + if($arg =~ /^--${rarg}$/ || $arg =~ /^--${rarg}-gz$/ || $arg =~ /^--${rarg}-bz2$/) { + $ht2_args[$i] = undef; + if(scalar(@args) > 1 && $args[1] ne "") { + $read_fns{$rarg} = $args[1]; + } else { + $i < scalar(@ht2_args)-1 || Fail("--${rarg}* option takes an argument.\n"); + $read_fns{$rarg} = $ht2_args[$i+1]; + $ht2_args[$i+1] = undef; + } + $read_compress{$rarg} = ""; + $read_compress{$rarg} = "gzip" if $arg eq "--${rarg}-gz"; + $read_compress{$rarg} = "bzip2" if $arg eq "--${rarg}-bz2"; + last; + } + } +} +# If the user asked us to redirect some reads to files, or to suppress +# unaligned reads, then we need to capture the output from HISAT and pass it +# through this wrapper. +my $passthru = 0; +if(scalar(keys %read_fns) > 0 || $no_unal) { + $passthru = 1; + push @ht2_args, "--passthrough"; + $cap_out = "-"; + for(my $i = 0; $i < scalar(@ht2_args); $i++) { + next unless defined($ht2_args[$i]); + my $arg = $ht2_args[$i]; + if($arg eq "-S" || $arg eq "--output") { + $i < scalar(@ht2_args)-1 || Fail("-S/--output takes an argument.\n"); + $cap_out = $ht2_args[$i+1]; + $ht2_args[$i] = undef; + $ht2_args[$i+1] = undef; + } + } +} +my @tmp = (); +for (@ht2_args) { push(@tmp, $_) if defined($_); } +@ht2_args = @tmp; + +my @unps = (); +my @mate1s = (); +my @mate2s = (); +my @to_delete = (); +my @to_kills = (); +my $temp_dir = "/tmp"; +my $bam_out = 0; +my $ref_str = undef; +my $no_pipes = 0; +my $keep = 0; +my $verbose = 0; +my $readpipe = undef; +my $log_fName = undef; +my $help = 0; + +my @ht2w_args_cp = (@ht2w_args>0) ? @ht2w_args : @ht2_args; +Getopt::Long::Configure("pass_through","no_ignore_case"); + +my @old_ARGV = @ARGV; +@ARGV = @ht2w_args_cp; + +GetOptions( + "1=s" => \@mate1s, + "2=s" => \@mate2s, + "reads|U=s" => \@unps, + "temp-directory=s" => \$temp_dir, + "bam" => \$bam_out, + "no-named-pipes" => \$no_pipes, + "ref-string|reference-string=s" => \$ref_str, + "keep" => \$keep, + "verbose" => \$verbose, + "log-file=s" => \$log_fName, + "help|h" => \$help +); + +@ARGV = @old_ARGV; + +my $old_stderr; + +if ($log_fName) { + open($old_stderr, ">&STDERR") or Fail("Cannot dup STDERR!\n"); + open(STDERR, ">", $log_fName) or Fail("Cannot redirect to log file $log_fName.\n"); +} + +Info("Before arg handling:\n"); +Info(" Wrapper args:\n[ @ht2w_args ]\n"); +Info(" Binary args:\n[ @ht2_args ]\n"); + +# check read lengths +# if read_files have more than 1 files, use first one, +my @read_files = (scalar(@unps) > 0) ? @unps : @mate1s; +if ((scalar(@read_files) > 0) + && ($seq_in_args == 0) + && ($skip_read_stat == 0)) { + Info("Check read length: $read_files[0]\n"); + my $cmd = "'$read_stat_prog' $read_files[0]"; + my $read_len_str = ""; + + open(my $fh, "$cmd |") || Fail("Failed to run command '$cmd'\n"); + while(readline $fh) { + chomp; + next if /^\s*$/; + my @ts = split(/ /); + if (scalar(@ts) > 4) { + $read_len_str = $ts[4]; + } else { + $read_len_str = ""; + } + } + close($fh); + + if (($read_len_str ne "") && ($read_len_str ne "0")) { + Info("Read Length String: $read_len_str\n"); + push @ht2_args, ("--read-lengths", $read_len_str); + } +} + +sub check_file_exist($$$) { + my ($unps, $mate1s, $mate2s) = @_; + for my $fn (@$unps, @$mate1s, @$mate2s) { + if (not -f $fn) { + Fail("Read file '%s' doesn't exist\n", $fn); + return 1; + } + } + return 0; +} + +sub cat_file($$) { + my ($ifn, $ofh) = @_; + my $ifh = undef; + if($ifn =~ /\.gz$/) { + open($ifh, "gzip -dc $ifn |") || + Fail("Could not open gzipped read file: $ifn \n"); + } elsif($ifn =~ /\.bz2/) { + open($ifh, "bzip2 -dc $ifn |") || + Fail("Could not open bzip2ed read file: $ifn \n"); + } else { + open($ifh, $ifn) || Fail("Could not open read file: $ifn \n"); + } + while(readline $ifh) { print {$ofh} $_; } + close($ifh); +} + +# Return non-zero if and only if the input should be wrapped (i.e. because +# it's compressed). +sub wrapInput($$$) { + my ($unps, $mate1s, $mate2s) = @_; + for my $fn (@$unps, @$mate1s, @$mate2s) { + return 1 if $fn =~ /\.gz$/ || $fn =~ /\.bz2$/; + } + return 0; +} + +sub Info { + if ($verbose) { + print STDERR "(INFO): " ,@_; + } +} + +sub Error { + my @msg = @_; + $msg[0] = "(ERR): ".$msg[0]; + printf STDERR @msg; +} + +sub Fail { + Error(@_); + die("Exiting now ...\n"); +} + +sub Extract_IndexName_From { + my $index_opt = $ref_str ? '--index' : '-x'; + for (my $i=0; $i<@_; $i++) { + if ($_[$i] eq $index_opt){ + my $idx_basename = $_[$i+1]; + my @idx_filenames = glob($idx_basename . "*.ht2{,l}"); + unless(@idx_filenames) { + if(exists $ENV{"HISAT2_INDEXES"}) { + @idx_filenames = glob("$ENV{'HISAT2_INDEXES'}/$idx_basename" . "ht2{,l}"); + } + + if(!@idx_filenames) { + Fail("\"" . $idx_basename . "\" does not exist\n"); + } + $idx_basename = "$ENV{'HISAT2_INDEXES'}/$idx_basename" + } + + return $idx_basename; + } + } + Info("Cannot find any index option (--reference-string, --ref-string or -x) in the given command line.\n"); +} + +if($seq_in_args == 0) { + check_file_exist(\@unps, \@mate1s, \@mate2s); +} + +if(wrapInput(\@unps, \@mate1s, \@mate2s)) { + if(scalar(@mate2s) > 0) { + # + # Wrap paired-end inputs + # + # Put reads into temporary files or fork off processes to feed named pipes + scalar(@mate2s) == scalar(@mate1s) || + Fail("Different number of files specified with --reads/-1 as with -2\n"); + # Make a named pipe for delivering mate #1s + my $m1fn = "$temp_dir/$$.inpipe1"; + push @to_delete, $m1fn; + push @ht2_args, "-1 $m1fn"; + # Create named pipe 1 for writing + if(!$no_pipes) { + mkfifo($m1fn, 0700) || Fail("mkfifo($m1fn) failed.\n"); + } + my $pid = 0; + $pid = fork() unless $no_pipes; + push @to_kills, $pid unless $no_pipes; + if($pid == 0) { + # Open named pipe 1 for writing + open(my $ofh, ">$m1fn") || Fail("Can't open '$m1fn' for writing\n"); + for my $ifn (@mate1s) { cat_file($ifn, $ofh); } + close($ofh); + exit 0 unless $no_pipes; + } + # Make a named pipe for delivering mate #2s + my $m2fn = "$temp_dir/$$.inpipe2"; + push @to_delete, $m2fn; + push @ht2_args, "-2 $m2fn"; + # Create named pipe 2 for writing + if(!$no_pipes) { + mkfifo($m2fn, 0700) || Fail("mkfifo($m2fn) failed.\n"); + } + $pid = 0; + $pid = fork() unless $no_pipes; + push @to_kills, $pid unless $no_pipes; + if($pid == 0) { + # Open named pipe 2 for writing + open(my $ofh, ">$m2fn") || Fail("Can't open '$m2fn' for writing.\n"); + for my $ifn (@mate2s) { cat_file($ifn, $ofh); } + close($ofh); + exit 0 unless $no_pipes; + } + } + if(scalar(@unps) > 0) { + # + # Wrap unpaired inputs. + # + # Make a named pipe for delivering unpaired reads + my $ufn = "$temp_dir/$$.unp"; + push @to_delete, $ufn; + push @ht2_args, "-U $ufn"; + # Create named pipe 2 for writing + if(!$no_pipes) { + mkfifo($ufn, 0700) || Fail("mkfifo($ufn) failed.\n"); + } + my $pid = 0; + $pid = fork() unless $no_pipes; + if($pid == 0) { + # Open named pipe 2 for writing + open(my $ofh, ">$ufn") || Fail("Can't open '$ufn' for writing.\n"); + for my $ifn (@unps) { cat_file($ifn, $ofh); } + close($ofh); + exit 0 unless $no_pipes; + } + } +} else { + if(scalar(@mate2s) > 0) { + # Just pass all the mate arguments along to the binary + push @ht2_args, ("-1", join(",", @mate1s)); + push @ht2_args, ("-2", join(",", @mate2s)); + } + if(scalar(@unps) > 0) { + push @ht2_args, ("-U", join(",", @unps)); + } +} + +if(defined($ref_str)) { + my $ofn = "$temp_dir/$$.ref_str.fa"; + open(my $ofh, ">$ofn") || + Fail("could not open temporary fasta file '$ofn' for writing.\n"); + print {$ofh} ">1\n$ref_str\n"; + close($ofh); + push @to_delete, $ofn; + system("$build_bin $ofn $ofn") == 0 || + Fail("hisat2-build returned non-0 exit level.\n"); + push @ht2_args, ("--index", "$ofn"); + push @to_delete, ("$ofn.1.".$idx_ext, "$ofn.2.".$idx_ext, + "$ofn.3.".$idx_ext, "$ofn.4.".$idx_ext, + "$ofn.5.".$idx_ext, "$ofn.6.".$idx_ext, + "$ofn.7.".$idx_ext, "$ofn.8.".$idx_ext); +} + +Info("After arg handling:\n"); +Info(" Binary args:\n[ @ht2_args ]\n"); + +my $index_name = Extract_IndexName_From(@ht2_args); + +if ($large_idx) { + Info("Using a large index enforced by user.\n"); + $align_prog = $align_prog_l; + $idx_ext = $idx_ext_l; + if (not -f $index_name.".1.".$idx_ext_l) { + Fail("Cannot find the large index ${index_name}.1.${idx_ext_l}\n"); + } + Info("Using large index (${index_name}.1.${idx_ext_l}).\n"); +} +else { + if ((-f $index_name.".1.".$idx_ext_l) && + (not -f $index_name.".1.".$idx_ext_s)) { + Info("Cannot find a small index but a large one seems to be present.\n"); + Info("Switching to using the large index (${index_name}.1.${idx_ext_l}).\n"); + $align_prog = $align_prog_l; + $idx_ext = $idx_ext_l; + } + else { + Info("Using the small index (${index_name}.1.${idx_ext_s}).\n") + } +} + +my $debug_str = ($debug ? "-debug" : ""); + +# Construct command invoking hisat2-align +my $cmd = "'$align_prog$debug_str' --wrapper basic-0 ".join(" ", @ht2_args); + +# Possibly add read input on an anonymous pipe +$cmd = "$readpipe $cmd" if defined($readpipe); + +Info("$cmd\n"); +my $ret; +if(defined($cap_out)) { + # Open HISAT2 pipe + open(HT, "$cmd |") || Fail("Could not open HISAT2 pipe: '$cmd |'\n"); + # Open output pipe + my $ofh = *STDOUT; + my @fhs_to_close = (); + if($cap_out ne "-") { + open($ofh, ">$cap_out") || + Fail("Could not open output file '$cap_out' for writing.\n"); + } + my %read_fhs = (); + for my $i ("al", "un", "al-conc", "al-conc-disc", "un-conc") { + if(defined($read_fns{$i})) { + my ($vol, $base_spec_dir, $base_fname) = File::Spec->splitpath($read_fns{$i}); + if (-d $read_fns{$i}) { + $base_spec_dir = $read_fns{$i}; + $base_fname = undef; + } + if($i =~ /-conc$/ || $i =~ /-conc-disc$/) { + # Open 2 output files, one for mate 1, one for mate 2 + my ($fn1, $fn2); + if ($base_fname) { + ($fn1, $fn2) = ($base_fname,$base_fname); + } + else { + ($fn1, $fn2) = ($i.'-mate',$i.'-mate'); + } + if($fn1 =~ /%/) { + $fn1 =~ s/%/1/g; $fn2 =~ s/%/2/g; + } elsif($fn1 =~ /\.[^.]*$/) { + $fn1 =~ s/\.([^.]*)$/.1.$1/; + $fn2 =~ s/\.([^.]*)$/.2.$1/; + } else { + $fn1 .= ".1"; + $fn2 .= ".2"; + } + $fn1 = File::Spec->catpath($vol,$base_spec_dir,$fn1); + $fn2 = File::Spec->catpath($vol,$base_spec_dir,$fn2); + $fn1 ne $fn2 || Fail("$fn1\n$fn2\n"); + my ($redir1, $redir2) = (">$fn1", ">$fn2"); + $redir1 = "| gzip -c $redir1" if $read_compress{$i} eq "gzip"; + $redir1 = "| bzip2 -c $redir1" if $read_compress{$i} eq "bzip2"; + $redir2 = "| gzip -c $redir2" if $read_compress{$i} eq "gzip"; + $redir2 = "| bzip2 -c $redir2" if $read_compress{$i} eq "bzip2"; + open($read_fhs{$i}{1}, $redir1) || Fail("Could not open --$i mate-1 output file '$fn1'\n"); + open($read_fhs{$i}{2}, $redir2) || Fail("Could not open --$i mate-2 output file '$fn2'\n"); + push @fhs_to_close, $read_fhs{$i}{1}; + push @fhs_to_close, $read_fhs{$i}{2}; + } else { + my $redir = ">".File::Spec->catpath($vol,$base_spec_dir,$i."-seqs"); + if ($base_fname) { + $redir = ">$read_fns{$i}"; + } + $redir = "| gzip -c $redir" if $read_compress{$i} eq "gzip"; + $redir = "| bzip2 -c $redir" if $read_compress{$i} eq "bzip2"; + open($read_fhs{$i}, $redir) || Fail("Could not open --$i output file '$read_fns{$i}'\n"); + push @fhs_to_close, $read_fhs{$i}; + } + } + } + while() { + chomp; + my $filt = 0; + unless(substr($_, 0, 1) eq "@") { + # If we are supposed to output certain reads to files... + my $tab1_i = index($_, "\t") + 1; + my $tab2_i = index($_, "\t", $tab1_i); + my $fl = substr($_, $tab1_i, $tab2_i - $tab1_i); + my $unal = ($fl & 4) != 0; + my $secondary = ($fl & 256) != 0; + $filt = 1 if $no_unal && $unal; + if($passthru) { + if(scalar(keys %read_fhs) == 0) { + # Next line is read with some whitespace escaped + my $l = ; + } else { + my $mate1 = (($fl & 64) != 0); + my $mate2 = (($fl & 128) != 0); + my $unp = !$mate1 && !$mate2; + my $pair = !$unp; + # Next line is read with some whitespace escaped + my $l = ; + chomp($l); + $l =~ s/%(..)/chr(hex($1))/eg; + if((defined($read_fhs{un}) || defined($read_fhs{al})) && $unp && !$secondary) { + if($unal) { + # Failed to align + print {$read_fhs{un}} $l if defined($read_fhs{un}); + } else { + # Aligned + print {$read_fhs{al}} $l if defined($read_fhs{al}); + } + } + if((defined($read_fhs{"un-conc"}) || defined($read_fhs{"al-conc"}) || defined($read_fhs{"al-conc-disc"})) && $pair && !$secondary) { + my $conc = (($fl & 2) != 0); + my $conc_disc = ($fl & 4) == 0 || ($fl & 8) == 0; + if($conc && $mate1) { + print {$read_fhs{"al-conc"}{1}} $l if defined($read_fhs{"al-conc"}); + } elsif($conc && $mate2) { + print {$read_fhs{"al-conc"}{2}} $l if defined($read_fhs{"al-conc"}); + } elsif(!$conc && $mate1) { + print {$read_fhs{"un-conc"}{1}} $l if defined($read_fhs{"un-conc"}); + } elsif(!$conc && $mate2) { + print {$read_fhs{"un-conc"}{2}} $l if defined($read_fhs{"un-conc"}); + } + if($conc_disc && $mate1) { + print {$read_fhs{"al-conc-disc"}{1}} $l if defined($read_fhs{"al-conc-disc"}); + } elsif($conc_disc && $mate2) { + print {$read_fhs{"al-conc-disc"}{2}} $l if defined($read_fhs{"al-conc-disc"}); + } + } + } + } + } + print {$ofh} "$_\n" if !$filt; + } + for my $k (@fhs_to_close) { close($k); } + close($ofh); + close(HT); + $ret = $?; +} else { + $ret = system($cmd); +} +kill 'TERM', @to_kills; + +if(!$keep) { for(@to_delete) { unlink($_); } } + +if ($ret == -1) { + Error("Failed to execute hisat2-align: $!\n"); + exit 1; +} elsif ($ret & 127) { + my $signm = "(unknown)"; + $signm = $signame[$ret & 127] if defined($signame[$ret & 127]); + my $ad = ""; + $ad = "(core dumped)" if (($ret & 128) != 0); + Error("hisat2-align died with signal %d (%s) $ad\n", ($ret & 127), $signm); + exit 1; +} elsif($ret != 0) { + Error("hisat2-align exited with value %d\n", ($ret >> 8)); +} +exit ($ret >> 8); diff --git a/hisat2-build b/hisat2-build new file mode 100644 index 0000000..35f23e6 --- /dev/null +++ b/hisat2-build @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +""" + Copyright 2015, Daehwan Kim + + This file is part of HISAT 2. + + HISAT 2 is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + HISAT 2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with HISAT 2. If not, see . +""" + + +import os +import sys +import inspect +import logging + + +def build_args(): + """ + Parse the wrapper arguments. Returns the options, tuple. + """ + + parsed_args = {} + to_remove = [] + argv = sys.argv[:] + for i, arg in enumerate(argv): + if arg == '--large-index': + parsed_args[arg] = "" + to_remove.append(i) + elif arg == '--debug': + parsed_args[arg] = "" + to_remove.append(i) + elif arg == '--verbose': + parsed_args[arg] = "" + to_remove.append(i) + + for i in reversed(to_remove): + del argv[i] + + return parsed_args, argv + + +def main(): + logging.basicConfig(level=logging.ERROR, + format='%(levelname)s: %(message)s' + ) + delta = 200 + small_index_max_size= 4 * 1024**3 - delta + build_bin_name = "hisat2-build" + build_bin_s = "hisat2-build-s" + build_bin_l = "hisat2-build-l" + curr_script = os.path.realpath(inspect.getsourcefile(main)) + ex_path = os.path.dirname(curr_script) + build_bin_spec = os.path.join(ex_path,build_bin_s) + + options, argv = build_args() + + if '--verbose' in options: + logging.getLogger().setLevel(logging.INFO) + + if '--debug' in options: + build_bin_spec += '-debug' + build_bin_l += '-debug' + + if '--large-index' in options: + build_bin_spec = os.path.join(ex_path,build_bin_l) + elif len(argv) >= 2: + ref_fnames = argv[-2] + tot_size = 0 + for fn in ref_fnames.split(','): + if os.path.exists(fn): + statinfo = os.stat(fn) + tot_size += statinfo.st_size + if tot_size > small_index_max_size: + build_bin_spec = os.path.join(ex_path,build_bin_l) + + argv[0] = build_bin_name + argv.insert(1, 'basic-0') + argv.insert(1, '--wrapper') + logging.info('Command: %s %s' % (build_bin_spec, ' '.join(argv[1:]))) + os.execv(build_bin_spec, argv) + +if __name__ == "__main__": + main() diff --git a/hisat2-build-new b/hisat2-build-new new file mode 100644 index 0000000..9b13701 --- /dev/null +++ b/hisat2-build-new @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +""" + Copyright 2018, Chanhee Park and Daehwan Kim + + This file is part of HISAT 2. + + HISAT 2 is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + HISAT 2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with HISAT 2. If not, see . +""" + + +import os +import sys +import inspect +import logging + + +def build_args(): + """ + Parse the wrapper arguments. Returns the options, tuple. + """ + + parsed_args = {} + to_remove = [] + argv = sys.argv[:] + for i, arg in enumerate(argv): + if arg == '--large-index': + parsed_args[arg] = "" + to_remove.append(i) + elif arg == '--debug': + parsed_args[arg] = "" + to_remove.append(i) + elif arg == '--verbose': + parsed_args[arg] = "" + to_remove.append(i) + + for i in reversed(to_remove): + del argv[i] + + return parsed_args, argv + + +def main(): + logging.basicConfig(level=logging.ERROR, + format='%(levelname)s: %(message)s' + ) + delta = 200 + small_index_max_size= 4 * 1024**3 - delta + constuct_bin_name = "hisat2-construct-nonrepetitive-genome" + constuct_bin_s = "hisat2-construct-nonrepetitive-genome-s" + constuct_bin_l = "hisat2-construct-nonrepetitive-genome-l" + build_bin_name = "hisat2-build" + build_bin_s = "hisat2-build-s" + build_bin_l = "hisat2-build-l" + curr_script = os.path.realpath(inspect.getsourcefile(main)) + ex_path = os.path.dirname(curr_script) + build_bin_spec = os.path.join(ex_path,build_bin_s) + + options, argv = build_args() + + if '--verbose' in options: + logging.getLogger().setLevel(logging.INFO) + + if '--debug' in options: + build_bin_spec += '-debug' + build_bin_l += '-debug' + + if '--large-index' in options: + build_bin_spec = os.path.join(ex_path,build_bin_l) + elif len(argv) >= 2: + ref_fnames = argv[-2] + tot_size = 0 + for fn in ref_fnames.split(','): + if os.path.exists(fn): + statinfo = os.stat(fn) + tot_size += statinfo.st_size + if tot_size > small_index_max_size: + build_bin_spec = os.path.join(ex_path,build_bin_l) + + argv[0] = build_bin_name + argv.insert(1, 'basic-0') + argv.insert(1, '--wrapper') + logging.info('Command: %s %s' % (build_bin_spec, ' '.join(argv[1:]))) + os.execv(build_bin_spec, argv) + +if __name__ == "__main__": + main() + + diff --git a/hisat2-inspect b/hisat2-inspect new file mode 100644 index 0000000..2b5dea3 --- /dev/null +++ b/hisat2-inspect @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +""" + Copyright 2015, Daehwan Kim + + This file is part of HISAT 2. + + HISAT 2 is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + HISAT 2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with HISAT 2. If not, see . +""" + + +import os +import imp +import inspect +import logging + + +def main(): + logging.basicConfig(level=logging.ERROR, + format='%(levelname)s: %(message)s' + ) + inspect_bin_name = "hisat2-inspect" + inspect_bin_s = "hisat2-inspect-s" + inspect_bin_l = "hisat2-inspect-l" + idx_ext_l = '.1.ht2l'; + idx_ext_s = '.1.ht2'; + curr_script = os.path.realpath(inspect.getsourcefile(main)) + ex_path = os.path.dirname(curr_script) + inspect_bin_spec = os.path.join(ex_path,inspect_bin_s) + bld = imp.load_source('hisat2-build',os.path.join(ex_path,'hisat2-build')) + options,arguments = bld.build_args() + + if '--verbose' in options: + logging.getLogger().setLevel(logging.INFO) + + if '--debug' in options: + inspect_bin_spec += '-debug' + inspect_bin_l += '-debug' + + if '--large-index' in options: + inspect_bin_spec = os.path.join(ex_path,inspect_bin_l) + elif len(arguments) >= 1: + idx_basename = arguments[-1] + large_idx_exists = os.path.exists(idx_basename + idx_ext_l) + small_idx_exists = os.path.exists(idx_basename + idx_ext_s) + if not large_idx_exists and not small_idx_exists: + env_path = os.getenv('HISAT2_INDEXES', '') + large_idx_exists = os.path.exists(env_path + '/' + idx_basename + idx_ext_l) + small_idx_exists = os.path.exists(env_path + '/' + idx_basename + idx_ext_s) + + if large_idx_exists and not small_idx_exists: + inspect_bin_spec = os.path.join(ex_path,inspect_bin_l) + + arguments[0] = inspect_bin_name + arguments.insert(1, 'basic-0') + arguments.insert(1, '--wrapper') + logging.info('Command: %s %s' % (inspect_bin_spec,' '.join(arguments[1:]))) + os.execv(inspect_bin_spec, arguments) + + +if __name__ == "__main__": + main() diff --git a/hisat2.cpp b/hisat2.cpp new file mode 100644 index 0000000..9df7586 --- /dev/null +++ b/hisat2.cpp @@ -0,0 +1,4978 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * This file is edited by Yun (Leo) Zhang for HISAT-3N. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "alphabet.h" +#include "assert_helpers.h" +#include "endian_swap.h" +#include "hgfm.h" +#include "rfm.h" +#include "formats.h" +#include "sequence_io.h" +#include "tokenize.h" +#include "aln_sink.h" +#include "pat.h" +#include "threading.h" +#include "ds.h" +#include "aligner_metrics.h" +#include "sam.h" +#include "aligner_seed.h" +#include "splice_site.h" +#include "spliced_aligner.h" +#include "aligner_seed_policy.h" +#include "aligner_sw.h" +#include "aligner_sw_driver.h" +#include "aligner_cache.h" +#include "util.h" +#include "pe.h" +#include "tp.h" +#include "gp.h" +#include "simple_func.h" +#include "presets.h" +#include "opts.h" +#include "outq.h" +#include "repeat_kmer.h" +#include "hisat2lib/ht2.h" +//#include "utility_3n.h" + + +using namespace std; + +MemoryTally gMemTally; + +static EList mates1; // mated reads (first mate) +static EList mates2; // mated reads (second mate) +static EList mates12; // mated reads (1st/2nd interleaved in 1 file) +static string adjIdxBase; +static string adjIdxBases_3N[2]; +bool gColor; // colorspace (not supported) +int gVerbose; // be talkative +static bool startVerbose; // be talkative at startup +int gQuiet; // print nothing but the alignments +static int sanityCheck; // enable expensive sanity checks +static int format; // default read format is FASTQ +static string origString; // reference text, or filename(s) +static int seed; // srandom() seed +static int timing; // whether to report basic timing data +static int metricsIval; // interval between alignment metrics messages (0 = no messages) +static string metricsFile;// output file to put alignment metrics in +static bool metricsStderr;// output file to put alignment metrics in +static bool metricsPerRead; // report a metrics tuple for every read +static bool allHits; // for multihits, report just one +static bool showVersion; // just print version and quit? +static int ipause; // pause before maching? +static uint32_t qUpto; // max # of queries to read +int gTrim5; // amount to trim from 5' end +int gTrim3; // amount to trim from 3' end +static int offRate; // keep default offRate +static bool solexaQuals; // quality strings are solexa quals, not phred, and subtract 64 (not 33) +static bool phred64Quals; // quality chars are phred, but must subtract 64 (not 33) +static bool integerQuals; // quality strings are space-separated strings of integers, not ASCII +static int nthreads; // number of pthreads operating concurrently +static int outType; // style of output +static bool noRefNames; // true -> print reference indexes; not names +static uint32_t khits; // number of hits per read; >1 is much slower +static uint32_t mhits; // don't report any hits if there are > mhits +static int partitionSz; // output a partitioning key in first field +static bool useSpinlock; // false -> don't use of spinlocks even if they're #defines +static bool fileParallel; // separate threads read separate input files in parallel +static bool useShmem; // use shared memory to hold the index +static bool useMm; // use memory-mapped files to hold the index +static bool mmSweep; // sweep through memory-mapped files immediately after mapping +int gMinInsert; // minimum insert size +int gMaxInsert; // maximum insert size +bool gMate1fw; // -1 mate aligns in fw orientation on fw strand +bool gMate2fw; // -2 mate aligns in rc orientation on fw strand +bool gFlippedMatesOK; // allow mates to be in wrong order +bool gDovetailMatesOK; // allow one mate to extend off the end of the other +bool gContainMatesOK; // allow one mate to contain the other in PE alignment +bool gOlapMatesOK; // allow mates to overlap in PE alignment +bool gExpandToFrag; // incr max frag length to =larger mate len if necessary +bool gReportDiscordant; // find and report discordant paired-end alignments +bool gReportMixed; // find and report unpaired alignments for paired reads +static uint32_t cacheLimit; // ranges w/ size > limit will be cached +static uint32_t cacheSize; // # words per range cache +static uint32_t skipReads; // # reads/read pairs to skip +bool gNofw; // don't align fw orientation of read +bool gNorc; // don't align rc orientation of read +static uint32_t fastaContLen; +static uint32_t fastaContFreq; +static bool hadoopOut; // print Hadoop status and summary messages +static bool fuzzy; +static bool fullRef; +static bool samTruncQname; // whether to truncate QNAME to 255 chars +static bool samOmitSecSeqQual; // omit SEQ/QUAL for 2ndary alignments? +static bool samNoUnal; // don't print records for unaligned reads +static bool samNoHead; // don't print any header lines in SAM output +static bool samNoSQ; // don't print @SQ header lines +static bool sam_print_as; +static bool sam_print_xs; // XS:i +static bool sam_print_xss; // Xs:i and Ys:i +static bool sam_print_yn; // YN:i and Yn:i +static bool sam_print_xn; +static bool sam_print_cs; +static bool sam_print_cq; +static bool sam_print_x0; +static bool sam_print_x1; +static bool sam_print_xm; +static bool sam_print_xo; +static bool sam_print_xg; +static bool sam_print_nm; +static bool sam_print_md; +static bool sam_print_yf; +static bool sam_print_yi; +static bool sam_print_ym; +static bool sam_print_yp; +static bool sam_print_yt; +static bool sam_print_ys; +static bool sam_print_zs; +static bool sam_print_xr; +static bool sam_print_xt; +static bool sam_print_xd; +static bool sam_print_xu; +static bool sam_print_yl; +static bool sam_print_ye; +static bool sam_print_yu; +static bool sam_print_xp; +static bool sam_print_yr; +static bool sam_print_zb; +static bool sam_print_zr; +static bool sam_print_zf; +static bool sam_print_zm; +static bool sam_print_zi; +static bool sam_print_zp; +static bool sam_print_zu; +static bool sam_print_xs_a; +static bool sam_print_nh; +static bool bwaSwLike; +static float bwaSwLikeC; +static float bwaSwLikeT; +static bool qcFilter; +static bool sortByScore; // prioritize alignments to report by score? +bool gReportOverhangs; // false -> filter out alignments that fall off the end of a reference sequence +static string rgid; // ID: setting for @RG header line +static string rgs; // SAM outputs for @RG header line +static string rgs_optflag; // SAM optional flag to add corresponding to @RG ID +static bool msample; // whether to report a random alignment when maxed-out via -m/-M +int gGapBarrier; // # diags on top/bot only to be entered diagonally +static EList qualities; +static EList qualities1; +static EList qualities2; +static string polstr; // temporary holder for policy string +static bool msNoCache; // true -> disable local cache +static int bonusMatchType; // how to reward matches +static int bonusMatch; // constant reward if bonusMatchType=constant +static int penMmcType; // how to penalize mismatches +int penMmcMax; // max mm penalty +static int penMmcMin; // min mm penalty +static int penScMax; // max sc penalty +static int penScMin; // min sc penalty +static int penNType; // how to penalize Ns in the read +static int penN; // constant if N pelanty is a constant +static bool penNCatPair; // concatenate mates before N filtering? +static bool localAlign; // do local alignment in DP steps +static bool noisyHpolymer; // set to true if gap penalties should be reduced to be consistent with a sequencer that under- and overcalls homopolymers +static int penRdGapConst; // constant cost of extending a gap in the read +static int penRfGapConst; // constant cost of extending a gap in the reference +static int penRdGapLinear; // coeff of linear term for cost of gap extension in read +static int penRfGapLinear; // coeff of linear term for cost of gap extension in ref +SimpleFunc scoreMin; // minimum valid score as function of read len +static SimpleFunc nCeil; // max # Ns allowed as function of read len +static SimpleFunc msIval; // interval between seeds as function of read len +static double descConsExp; // how to adjust score minimum as we descent further into index-assisted alignment +static size_t descentLanding; // don't place a search root if it's within this many positions of end +static SimpleFunc descentTotSz; // maximum space a DescentDriver can use in bytes +static SimpleFunc descentTotFmops; // maximum # FM ops a DescentDriver can perform +static int multiseedMms; // mismatches permitted in a multiseed seed +static int multiseedLen; // length of multiseed seeds +static size_t multiseedOff; // offset to begin extracting seeds +static uint32_t seedCacheLocalMB; // # MB to use for non-shared seed alignment cacheing +static uint32_t seedCacheCurrentMB; // # MB to use for current-read seed hit cacheing +static uint32_t exactCacheCurrentMB; // # MB to use for current-read seed hit cacheing +static size_t maxhalf; // max width on one side of DP table +static bool seedSumm; // print summary information about seed hits, not alignments +static bool doUngapped; // do ungapped alignment +static size_t maxIters; // stop after this many extend loop iterations +static size_t maxUg; // stop after this many ungap extends +static size_t maxDp; // stop after this many DPs +static size_t maxItersIncr; // amt to add to maxIters for each -k > 1 +static size_t maxEeStreak; // stop after this many end-to-end fails in a row +static size_t maxUgStreak; // stop after this many ungap fails in a row +static size_t maxDpStreak; // stop after this many dp fails in a row +static size_t maxStreakIncr; // amt to add to streak for each -k > 1 +static size_t maxMateStreak; // stop seed range after this many mate-find fails +static bool doExtend; // extend seed hits +static bool enable8; // use 8-bit SSE where possible? +static size_t cminlen; // longer reads use checkpointing +static size_t cpow2; // checkpoint interval log2 +static bool doTri; // do triangular mini-fills? +static string defaultPreset; // default preset; applied immediately +static bool ignoreQuals; // all mms incur same penalty, regardless of qual +static string wrapper; // type of wrapper script, so we can print correct usage +static EList queries; // list of query files +static string outfile; // write SAM output to this file +static int mapqv; // MAPQ calculation version +static int tighten; // -M tighten mode (0=none, 1=best, 2=secbest+1) +static bool doExactUpFront; // do exact search up front if seeds seem good enough +static bool do1mmUpFront; // do 1mm search up front if seeds seem good enough +static size_t do1mmMinLen; // length below which we disable 1mm e2e search +static int seedBoostThresh; // if average non-zero position has more than this many elements +static size_t maxSeeds; // maximum number of seeds allowed +static size_t nSeedRounds; // # seed rounds +static bool reorder; // true -> reorder SAM recs in -p mode +static float sampleFrac; // only align random fraction of input reads +static bool arbitraryRandom; // pseudo-randoms no longer a function of read properties +static bool bowtie2p5; +static bool useTempSpliceSite; +static int penCanSplice; +static int penNoncanSplice; +static int penConflictSplice; +static SimpleFunc penCanIntronLen; +static SimpleFunc penNoncanIntronLen; +static size_t minIntronLen; +static size_t maxIntronLen; +static string knownSpliceSiteInfile; // +static string novelSpliceSiteInfile; // +static string novelSpliceSiteOutfile; // +static bool secondary; +static bool no_spliced_alignment; +static int rna_strandness; // +static bool splicesite_db_only; // + +static bool anchorStop; +static bool pseudogeneStop; +static bool tranMapOnly; // transcriptome mapping only +static bool tranAssm; // alignments selected for downstream transcript assembly such as StringTie and Cufflinks +static string tranAssm_program; +static bool avoid_pseudogene; + +#ifdef USE_SRA +static EList sra_accs; +#endif + +static string bt2indexs[2]; // read Bowtie 2 index from files with this prefix +static EList > extra_opts; +static size_t extra_opts_cur; + +static EList thread_rids; +static MUTEX_T thread_rids_mutex; +static uint64_t thread_rids_mindist; + +static bool rmChrName; // remove "chr" from reference names (e.g., chr18 to 18) +static bool addChrName; // add "chr" to reference names (e.g., 18 to chr18) + +static size_t max_alts_tried; +static bool use_haplotype; +static bool enable_codis; + +static bool templateLenAdjustment; +static string alignSumFile; // write alignment summary stat. to this file +static bool newAlignSummary; + +static int bowtie2_dp; // Bowtie2's dynamic programming alignment (0: no dynamic programming, 1: conditional dynamic programming, and 2: uncoditional dynamic programming) +static bool fast; // --fast +static bool sensitive; // --sensitive +static bool very_sensitive; // --very-sensitive + +static bool repeat; +static bool use_repeat_index; +static EList readLens; + +// 3N variable +bool threeN = false; // indicator for 3N mode. +bool base_change_entered; // set true once user used --base-change + +char usrInput_convertedFrom; // user input converted from. the nucleotide is replaced by others in sample preparation protocol. for sequence comparison step in HISAT-3N. +char usrInput_convertedTo; // user input converted To. the nucleotide to others in sample preparation protocol. for sequence comparison step in HISAT-3N. +char usrInput_convertedFromComplement; // the complement of usrInput_convertedFrom. for sequence comparison step in HISAT-3N. +char usrInput_convertedToComplement; // the complement of usrInput_convertedTo. for sequence comparison step in HISAT-3N. + +char hs3N_convertedFrom; // the actual converted from by HISAT-3N. use in + strand. +char hs3N_convertedTo; // the actual converted to by HISAT-3N. use in + strand. +char hs3N_convertedFromComplement; // the complement of hs3N_convertedFrom. use in - strand. +char hs3N_convertedToComplement; // the complement of hs3N_convertedTo. use in - strand. + +string threeN_indexTags[2]; + +vector repeatHandles; // the 2 repeat handles helps expand the repeat alignment information. 0 for + strand. 1 for - strand. +struct ht2_index_getrefnames_result *refNameMap; // chromosome names and it's index for repeat alignment. +int repeatLimit; // expand #repeatLimit of qualified position in repeat alignment. +bool uniqueOutputOnly; // only output the unique alignment result. +int nMappingCycle; // =1 for standard HISAT2, =4 for HISAT-3N +bool mappingCycles[4]; // this array will indicate which mapping cycle will be run +int directional3NMapping; // =0 for non-directional mapping, =1 for directional mapping and read1/single-end map to fw reference, =2 for reverse directional mapping and read1/single-end map to rc reference. + +#define DMAX std::numeric_limits::max() + +static void resetOptions() { + mates1.clear(); + mates2.clear(); + mates12.clear(); + adjIdxBase = ""; + adjIdxBases_3N[0] = ""; + adjIdxBases_3N[1] = ""; + gColor = false; + gVerbose = 0; + startVerbose = 0; + gQuiet = false; + sanityCheck = 0; // enable expensive sanity checks + format = FASTQ; // default read format is FASTQ + origString = ""; // reference text, or filename(s) + seed = 0; // srandom() seed + timing = 0; // whether to report basic timing data + metricsIval = 1; // interval between alignment metrics messages (0 = no messages) + metricsFile = ""; // output file to put alignment metrics in + metricsStderr = false; // print metrics to stderr (in addition to --metrics-file if it's specified + metricsPerRead = false; // report a metrics tuple for every read? + allHits = false; // for multihits, report just one + showVersion = false; // just print version and quit? + ipause = 0; // pause before maching? + qUpto = 0xffffffff; // max # of queries to read + gTrim5 = 0; // amount to trim from 5' end + gTrim3 = 0; // amount to trim from 3' end + offRate = -1; // keep default offRate + solexaQuals = false; // quality strings are solexa quals, not phred, and subtract 64 (not 33) + phred64Quals = false; // quality chars are phred, but must subtract 64 (not 33) + integerQuals = false; // quality strings are space-separated strings of integers, not ASCII + nthreads = 1; // number of pthreads operating concurrently + outType = OUTPUT_SAM; // style of output + noRefNames = false; // true -> print reference indexes; not names + khits = 10; // number of hits per read; >1 is much slower + mhits = 0; // stop after finding this many alignments+1 + partitionSz = 0; // output a partitioning key in first field + useSpinlock = true; // false -> don't use of spinlocks even if they're #defines + fileParallel = false; // separate threads read separate input files in parallel + useShmem = false; // use shared memory to hold the index + useMm = false; // use memory-mapped files to hold the index + mmSweep = false; // sweep through memory-mapped files immediately after mapping + gMinInsert = 0; // minimum insert size + gMaxInsert = 1000; // maximum insert size + gMate1fw = true; // -1 mate aligns in fw orientation on fw strand + gMate2fw = false; // -2 mate aligns in rc orientation on fw strand + gFlippedMatesOK = false; // allow mates to be in wrong order + gDovetailMatesOK = false; // allow one mate to extend off the end of the other + gContainMatesOK = true; // allow one mate to contain the other in PE alignment + gOlapMatesOK = true; // allow mates to overlap in PE alignment + gExpandToFrag = true; // incr max frag length to =larger mate len if necessary + gReportDiscordant = true; // find and report discordant paired-end alignments + gReportMixed = true; // find and report unpaired alignments for paired reads + + cacheLimit = 5; // ranges w/ size > limit will be cached + cacheSize = 0; // # words per range cache + skipReads = 0; // # reads/read pairs to skip + gNofw = false; // don't align fw orientation of read + gNorc = false; // don't align rc orientation of read + fastaContLen = 0; + fastaContFreq = 0; + hadoopOut = false; // print Hadoop status and summary messages + fuzzy = false; // reads will have alternate basecalls w/ qualities + fullRef = false; // print entire reference name instead of just up to 1st space + samTruncQname = true; // whether to truncate QNAME to 255 chars + samOmitSecSeqQual = false; // omit SEQ/QUAL for 2ndary alignments? + samNoUnal = false; // omit SAM records for unaligned reads + samNoHead = false; // don't print any header lines in SAM output + samNoSQ = false; // don't print @SQ header lines + sam_print_as = true; + sam_print_xs = true; + sam_print_xss = false; // Xs:i and Ys:i + sam_print_yn = false; // YN:i and Yn:i + sam_print_xn = true; + sam_print_cs = false; + sam_print_cq = false; + sam_print_x0 = true; + sam_print_x1 = true; + sam_print_xm = true; + sam_print_xo = true; + sam_print_xg = true; + sam_print_nm = true; + sam_print_md = true; + sam_print_yf = true; + sam_print_yi = false; + sam_print_ym = false; + sam_print_yp = false; + sam_print_yt = true; + sam_print_ys = true; + sam_print_zs = false; + sam_print_xr = false; + sam_print_xt = false; + sam_print_xd = false; + sam_print_xu = false; + sam_print_yl = false; + sam_print_ye = false; + sam_print_yu = false; + sam_print_xp = false; + sam_print_yr = false; + sam_print_zb = false; + sam_print_zr = false; + sam_print_zf = false; + sam_print_zm = false; + sam_print_zi = false; + sam_print_zp = false; + sam_print_zu = false; + sam_print_xs_a = true; + sam_print_nh = true; + bwaSwLike = false; + bwaSwLikeC = 5.5f; + bwaSwLikeT = 20.0f; + qcFilter = false; // don't believe upstream qc by default + sortByScore = true; // prioritize alignments to report by score? + rgid = ""; // SAM outputs for @RG header line + rgs = ""; // SAM outputs for @RG header line + rgs_optflag = ""; // SAM optional flag to add corresponding to @RG ID + msample = true; + gGapBarrier = 4; // disallow gaps within this many chars of either end of alignment + qualities.clear(); + qualities1.clear(); + qualities2.clear(); + polstr.clear(); + msNoCache = true; // true -> disable local cache + bonusMatchType = DEFAULT_MATCH_BONUS_TYPE; + bonusMatch = DEFAULT_MATCH_BONUS; + penMmcType = DEFAULT_MM_PENALTY_TYPE; + penMmcMax = DEFAULT_MM_PENALTY_MAX; + penMmcMin = DEFAULT_MM_PENALTY_MIN; + penScMax = DEFAULT_SC_PENALTY_MAX; + penScMin = DEFAULT_SC_PENALTY_MIN; + penNType = DEFAULT_N_PENALTY_TYPE; + penN = DEFAULT_N_PENALTY; + penNCatPair = DEFAULT_N_CAT_PAIR; // concatenate mates before N filtering? + localAlign = false; // do local alignment in DP steps + noisyHpolymer = false; + penRdGapConst = DEFAULT_READ_GAP_CONST; + penRfGapConst = DEFAULT_REF_GAP_CONST; + penRdGapLinear = DEFAULT_READ_GAP_LINEAR; + penRfGapLinear = DEFAULT_REF_GAP_LINEAR; + scoreMin.init (SIMPLE_FUNC_LINEAR, 0.0f, -0.2f); + // scoreMin.init (SIMPLE_FUNC_CONST, -18, 0); + nCeil.init (SIMPLE_FUNC_LINEAR, 0.0f, DMAX, 2.0f, 0.1f); + msIval.init (SIMPLE_FUNC_LINEAR, 1.0f, DMAX, DEFAULT_IVAL_B, DEFAULT_IVAL_A); + descConsExp = 2.0; + descentLanding = 20; + descentTotSz.init(SIMPLE_FUNC_LINEAR, 1024.0, DMAX, 0.0, 1024.0); + descentTotFmops.init(SIMPLE_FUNC_LINEAR, 100.0, DMAX, 0.0, 10.0); + multiseedMms = DEFAULT_SEEDMMS; + multiseedLen = DEFAULT_SEEDLEN; + multiseedOff = 0; + seedCacheLocalMB = 32; // # MB to use for non-shared seed alignment cacheing + seedCacheCurrentMB = 20; // # MB to use for current-read seed hit cacheing + exactCacheCurrentMB = 20; // # MB to use for current-read seed hit cacheing + maxhalf = 15; // max width on one side of DP table + seedSumm = false; // print summary information about seed hits, not alignments + doUngapped = true; // do ungapped alignment + maxIters = 400; // max iterations of extend loop + maxUg = 300; // stop after this many ungap extends + maxDp = 300; // stop after this many dp extends + maxItersIncr = 20; // amt to add to maxIters for each -k > 1 + maxEeStreak = 15; // stop after this many end-to-end fails in a row + maxUgStreak = 15; // stop after this many ungap fails in a row + maxDpStreak = 15; // stop after this many dp fails in a row + maxStreakIncr = 10; // amt to add to streak for each -k > 1 + maxMateStreak = 10; // in PE: abort seed range after N mate-find fails + doExtend = true; // do seed extensions + enable8 = true; // use 8-bit SSE where possible? + cminlen = 2000; // longer reads use checkpointing + cpow2 = 4; // checkpoint interval log2 + doTri = false; // do triangular mini-fills? + defaultPreset = "sensitive%LOCAL%"; // default preset; applied immediately + extra_opts.clear(); + extra_opts_cur = 0; + bt2indexs[0].clear(); // read Bowtie 2 index from files with this prefix + bt2indexs[1].clear(); + ignoreQuals = false; // all mms incur same penalty, regardless of qual + wrapper.clear(); // type of wrapper script, so we can print correct usage + queries.clear(); // list of query files + outfile.clear(); // write SAM output to this file + mapqv = 2; // MAPQ calculation version + tighten = 3; // -M tightening mode + doExactUpFront = true; // do exact search up front if seeds seem good enough + do1mmUpFront = true; // do 1mm search up front if seeds seem good enough + seedBoostThresh = 300; // if average non-zero position has more than this many elements + nSeedRounds = 2; // # rounds of seed searches to do for repetitive reads + maxSeeds = 0; // maximum number of seeds allowed + do1mmMinLen = 60; // length below which we disable 1mm search + reorder = false; // reorder SAM records with -p > 1 + sampleFrac = 1.1f; // align all reads + arbitraryRandom = false; // let pseudo-random seeds be a function of read properties + bowtie2p5 = false; + useTempSpliceSite = true; + penCanSplice = 0; + penNoncanSplice = 12; + penConflictSplice = 1000000; + penCanIntronLen.init(SIMPLE_FUNC_LOG, -8, 1); + penNoncanIntronLen.init(SIMPLE_FUNC_LOG, -8, 1); + minIntronLen = 20; + maxIntronLen = 500000; + knownSpliceSiteInfile = ""; + novelSpliceSiteInfile = ""; + novelSpliceSiteOutfile = ""; + secondary = false; // allow secondary alignments + no_spliced_alignment = false; + rna_strandness = RNA_STRANDNESS_UNKNOWN; + splicesite_db_only = false; + anchorStop = true; + pseudogeneStop = true; + tranMapOnly = false; + tranAssm = false; + tranAssm_program = ""; + avoid_pseudogene = false; + +#ifdef USE_SRA + sra_accs.clear(); +#endif + + rmChrName = false; + addChrName = false; + + max_alts_tried = 16; + use_haplotype = false; + enable_codis = false; + + templateLenAdjustment = true; + alignSumFile = ""; + newAlignSummary = false; + + bowtie2_dp = 0; // disable Bowtie2's dynamic programming alignment + fast = false; + sensitive = false; + very_sensitive = false; + + repeat = false; // true iff alignments to repeat sequences are directly reported. + use_repeat_index = true; + readLens.clear(); + + refNameMap = NULL; + threeN = false; + repeatLimit = 1000; + uniqueOutputOnly = false; + base_change_entered = false; + threeN_indexTags[0] = ".3n."; + threeN_indexTags[1] = ".3n."; + nMappingCycle = 1; + directional3NMapping = 0; + for (int i = 0; i < 4; i++){ + mappingCycles[i] = false; + } +} + +static const char *short_options = "fF:qbzhcu:rv:s:aP:t3:5:w:p:k:M:1:2:I:X:CQ:N:i:L:U:x:S:g:O:D:R:"; + +static struct option long_options[] = { + {(char*)"verbose", no_argument, 0, ARG_VERBOSE}, + {(char*)"startverbose", no_argument, 0, ARG_STARTVERBOSE}, + {(char*)"quiet", no_argument, 0, ARG_QUIET}, + {(char*)"sanity", no_argument, 0, ARG_SANITY}, + {(char*)"pause", no_argument, &ipause, 1}, + {(char*)"orig", required_argument, 0, ARG_ORIG}, + {(char*)"all", no_argument, 0, 'a'}, + {(char*)"solexa-quals", no_argument, 0, ARG_SOLEXA_QUALS}, + {(char*)"integer-quals",no_argument, 0, ARG_INTEGER_QUALS}, + {(char*)"int-quals", no_argument, 0, ARG_INTEGER_QUALS}, + {(char*)"metrics", required_argument, 0, ARG_METRIC_IVAL}, + {(char*)"metrics-file", required_argument, 0, ARG_METRIC_FILE}, + {(char*)"metrics-stderr",no_argument, 0, ARG_METRIC_STDERR}, + {(char*)"metrics-per-read", no_argument, 0, ARG_METRIC_PER_READ}, + {(char*)"met-read", no_argument, 0, ARG_METRIC_PER_READ}, + {(char*)"met", required_argument, 0, ARG_METRIC_IVAL}, + {(char*)"met-file", required_argument, 0, ARG_METRIC_FILE}, + {(char*)"met-stderr", no_argument, 0, ARG_METRIC_STDERR}, + {(char*)"time", no_argument, 0, 't'}, + {(char*)"trim3", required_argument, 0, '3'}, + {(char*)"trim5", required_argument, 0, '5'}, + {(char*)"seed", required_argument, 0, ARG_SEED}, + {(char*)"qupto", required_argument, 0, 'u'}, + {(char*)"upto", required_argument, 0, 'u'}, + {(char*)"version", no_argument, 0, ARG_VERSION}, + {(char*)"filepar", no_argument, 0, ARG_FILEPAR}, + {(char*)"help", no_argument, 0, 'h'}, + {(char*)"threads", required_argument, 0, 'p'}, + {(char*)"khits", required_argument, 0, 'k'}, + {(char*)"minins", required_argument, 0, 'I'}, + {(char*)"maxins", required_argument, 0, 'X'}, + {(char*)"quals", required_argument, 0, 'Q'}, + {(char*)"Q1", required_argument, 0, ARG_QUALS1}, + {(char*)"Q2", required_argument, 0, ARG_QUALS2}, + {(char*)"refidx", no_argument, 0, ARG_REFIDX}, + {(char*)"partition", required_argument, 0, ARG_PARTITION}, + {(char*)"ff", no_argument, 0, ARG_FF}, + {(char*)"fr", no_argument, 0, ARG_FR}, + {(char*)"rf", no_argument, 0, ARG_RF}, + {(char*)"cachelim", required_argument, 0, ARG_CACHE_LIM}, + {(char*)"cachesz", required_argument, 0, ARG_CACHE_SZ}, + {(char*)"nofw", no_argument, 0, ARG_NO_FW}, + {(char*)"norc", no_argument, 0, ARG_NO_RC}, + {(char*)"skip", required_argument, 0, 's'}, + {(char*)"12", required_argument, 0, ARG_ONETWO}, + {(char*)"tab5", required_argument, 0, ARG_TAB5}, + {(char*)"tab6", required_argument, 0, ARG_TAB6}, + {(char*)"phred33-quals", no_argument, 0, ARG_PHRED33}, + {(char*)"phred64-quals", no_argument, 0, ARG_PHRED64}, + {(char*)"phred33", no_argument, 0, ARG_PHRED33}, + {(char*)"phred64", no_argument, 0, ARG_PHRED64}, + {(char*)"solexa1.3-quals", no_argument, 0, ARG_PHRED64}, + {(char*)"mm", no_argument, 0, ARG_MM}, + {(char*)"shmem", no_argument, 0, ARG_SHMEM}, + {(char*)"mmsweep", no_argument, 0, ARG_MMSWEEP}, + {(char*)"hadoopout", no_argument, 0, ARG_HADOOPOUT}, + {(char*)"fuzzy", no_argument, 0, ARG_FUZZY}, + {(char*)"fullref", no_argument, 0, ARG_FULLREF}, + {(char*)"usage", no_argument, 0, ARG_USAGE}, + {(char*)"sam-no-qname-trunc", no_argument, 0, ARG_SAM_NO_QNAME_TRUNC}, + {(char*)"sam-omit-sec-seq", no_argument, 0, ARG_SAM_OMIT_SEC_SEQ}, + {(char*)"omit-sec-seq", no_argument, 0, ARG_SAM_OMIT_SEC_SEQ}, + {(char*)"sam-no-head", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-nohead", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-noHD", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-no-hd", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-nosq", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"sam-no-sq", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"sam-noSQ", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"no-head", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"no-hd", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"no-sq", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"no-HD", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"no-SQ", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"no-unal", no_argument, 0, ARG_SAM_NO_UNAL}, + {(char*)"color", no_argument, 0, 'C'}, + {(char*)"sam-RG", required_argument, 0, ARG_SAM_RG}, + {(char*)"sam-rg", required_argument, 0, ARG_SAM_RG}, + {(char*)"sam-rg-id", required_argument, 0, ARG_SAM_RGID}, + {(char*)"RG", required_argument, 0, ARG_SAM_RG}, + {(char*)"rg", required_argument, 0, ARG_SAM_RG}, + {(char*)"rg-id", required_argument, 0, ARG_SAM_RGID}, + {(char*)"snpphred", required_argument, 0, ARG_SNPPHRED}, + {(char*)"snpfrac", required_argument, 0, ARG_SNPFRAC}, + {(char*)"gbar", required_argument, 0, ARG_GAP_BAR}, + {(char*)"qseq", no_argument, 0, ARG_QSEQ}, + {(char*)"policy", required_argument, 0, ARG_ALIGN_POLICY}, + {(char*)"preset", required_argument, 0, 'P'}, + {(char*)"seed-summ", no_argument, 0, ARG_SEED_SUMM}, + {(char*)"seed-summary", no_argument, 0, ARG_SEED_SUMM}, + {(char*)"overhang", no_argument, 0, ARG_OVERHANG}, + {(char*)"no-cache", no_argument, 0, ARG_NO_CACHE}, + {(char*)"cache", no_argument, 0, ARG_USE_CACHE}, + {(char*)"454", no_argument, 0, ARG_NOISY_HPOLY}, + {(char*)"ion-torrent", no_argument, 0, ARG_NOISY_HPOLY}, + {(char*)"no-mixed", no_argument, 0, ARG_NO_MIXED}, + {(char*)"no-discordant",no_argument, 0, ARG_NO_DISCORDANT}, + // {(char*)"local", no_argument, 0, ARG_LOCAL}, + {(char*)"end-to-end", no_argument, 0, ARG_END_TO_END}, + {(char*)"ungapped", no_argument, 0, ARG_UNGAPPED}, + {(char*)"no-ungapped", no_argument, 0, ARG_UNGAPPED_NO}, + {(char*)"sse8", no_argument, 0, ARG_SSE8}, + {(char*)"no-sse8", no_argument, 0, ARG_SSE8_NO}, + {(char*)"scan-narrowed",no_argument, 0, ARG_SCAN_NARROWED}, + {(char*)"qc-filter", no_argument, 0, ARG_QC_FILTER}, + {(char*)"bwa-sw-like", no_argument, 0, ARG_BWA_SW_LIKE}, + {(char*)"multiseed", required_argument, 0, ARG_MULTISEED_IVAL}, + {(char*)"ma", required_argument, 0, ARG_SCORE_MA}, + {(char*)"mp", required_argument, 0, ARG_SCORE_MMP}, + {(char*)"sp", required_argument, 0, ARG_SCORE_SCP}, + {(char*)"no-softclip", no_argument, 0, ARG_NO_SOFTCLIP}, + {(char*)"np", required_argument, 0, ARG_SCORE_NP}, + {(char*)"rdg", required_argument, 0, ARG_SCORE_RDG}, + {(char*)"rfg", required_argument, 0, ARG_SCORE_RFG}, + {(char*)"score-min", required_argument, 0, ARG_SCORE_MIN}, + {(char*)"min-score", required_argument, 0, ARG_SCORE_MIN}, + {(char*)"n-ceil", required_argument, 0, ARG_N_CEIL}, + {(char*)"dpad", required_argument, 0, ARG_DPAD}, + {(char*)"mapq-print-inputs",no_argument, 0, ARG_SAM_PRINT_YI}, + {(char*)"very-fast", no_argument, 0, ARG_PRESET_VERY_FAST}, + {(char*)"fast", no_argument, 0, ARG_PRESET_FAST}, + {(char*)"sensitive", no_argument, 0, ARG_PRESET_SENSITIVE}, + {(char*)"very-sensitive", no_argument, 0, ARG_PRESET_VERY_SENSITIVE}, + // {(char*)"very-fast-local", no_argument, 0, ARG_PRESET_VERY_FAST_LOCAL}, + // {(char*)"fast-local", no_argument, 0, ARG_PRESET_FAST_LOCAL}, + // {(char*)"sensitive-local", no_argument, 0, ARG_PRESET_SENSITIVE_LOCAL}, + // {(char*)"very-sensitive-local", no_argument, 0, ARG_PRESET_VERY_SENSITIVE_LOCAL}, + {(char*)"no-score-priority",no_argument, 0, ARG_NO_SCORE_PRIORITY}, + {(char*)"seedlen", required_argument, 0, 'L'}, + {(char*)"seedmms", required_argument, 0, 'N'}, + {(char*)"seedival", required_argument, 0, 'i'}, + {(char*)"ignore-quals", no_argument, 0, ARG_IGNORE_QUALS}, + {(char*)"index", required_argument, 0, 'x'}, + {(char*)"arg-desc", no_argument, 0, ARG_DESC}, + {(char*)"wrapper", required_argument, 0, ARG_WRAPPER}, + {(char*)"unpaired", required_argument, 0, 'U'}, + {(char*)"output", required_argument, 0, 'S'}, + {(char*)"mapq-v", required_argument, 0, ARG_MAPQ_V}, + {(char*)"dovetail", no_argument, 0, ARG_DOVETAIL}, + {(char*)"no-dovetail", no_argument, 0, ARG_NO_DOVETAIL}, + {(char*)"contain", no_argument, 0, ARG_CONTAIN}, + {(char*)"no-contain", no_argument, 0, ARG_NO_CONTAIN}, + {(char*)"overlap", no_argument, 0, ARG_OVERLAP}, + {(char*)"no-overlap", no_argument, 0, ARG_NO_OVERLAP}, + {(char*)"tighten", required_argument, 0, ARG_TIGHTEN}, + {(char*)"exact-upfront", no_argument, 0, ARG_EXACT_UPFRONT}, + {(char*)"1mm-upfront", no_argument, 0, ARG_1MM_UPFRONT}, + {(char*)"no-exact-upfront", no_argument, 0, ARG_EXACT_UPFRONT_NO}, + {(char*)"no-1mm-upfront", no_argument, 0, ARG_1MM_UPFRONT_NO}, + {(char*)"1mm-minlen", required_argument, 0, ARG_1MM_MINLEN}, + {(char*)"seed-off", required_argument, 0, 'O'}, + {(char*)"seed-boost", required_argument, 0, ARG_SEED_BOOST_THRESH}, + {(char*)"max-seeds", required_argument, 0, ARG_MAX_SEEDS}, + {(char*)"read-times", no_argument, 0, ARG_READ_TIMES}, + {(char*)"show-rand-seed", no_argument, 0, ARG_SHOW_RAND_SEED}, + {(char*)"dp-fail-streak", required_argument, 0, ARG_DP_FAIL_STREAK_THRESH}, + {(char*)"ee-fail-streak", required_argument, 0, ARG_EE_FAIL_STREAK_THRESH}, + {(char*)"ug-fail-streak", required_argument, 0, ARG_UG_FAIL_STREAK_THRESH}, + {(char*)"fail-streak", required_argument, 0, 'D'}, + {(char*)"dp-fails", required_argument, 0, ARG_DP_FAIL_THRESH}, + {(char*)"ug-fails", required_argument, 0, ARG_UG_FAIL_THRESH}, + {(char*)"extends", required_argument, 0, ARG_EXTEND_ITERS}, + {(char*)"no-extend", no_argument, 0, ARG_NO_EXTEND}, + {(char*)"mapq-extra", no_argument, 0, ARG_MAPQ_EX}, + {(char*)"seed-rounds", required_argument, 0, 'R'}, + {(char*)"reorder", no_argument, 0, ARG_REORDER}, + {(char*)"passthrough", no_argument, 0, ARG_READ_PASSTHRU}, + {(char*)"sample", required_argument, 0, ARG_SAMPLE}, + {(char*)"cp-min", required_argument, 0, ARG_CP_MIN}, + {(char*)"cp-ival", required_argument, 0, ARG_CP_IVAL}, + {(char*)"tri", no_argument, 0, ARG_TRI}, + {(char*)"nondeterministic", no_argument, 0, ARG_NON_DETERMINISTIC}, + {(char*)"non-deterministic", no_argument, 0, ARG_NON_DETERMINISTIC}, + // {(char*)"local-seed-cache-sz", required_argument, 0, ARG_LOCAL_SEED_CACHE_SZ}, + {(char*)"seed-cache-sz", required_argument, 0, ARG_CURRENT_SEED_CACHE_SZ}, + {(char*)"no-unal", no_argument, 0, ARG_SAM_NO_UNAL}, + {(char*)"test-25", no_argument, 0, ARG_TEST_25}, + // TODO: following should be a function of read length? + {(char*)"desc-kb", required_argument, 0, ARG_DESC_KB}, + {(char*)"desc-landing", required_argument, 0, ARG_DESC_LANDING}, + {(char*)"desc-exp", required_argument, 0, ARG_DESC_EXP}, + {(char*)"desc-fmops", required_argument, 0, ARG_DESC_FMOPS}, + {(char*)"no-temp-splicesite", no_argument, 0, ARG_NO_TEMPSPLICESITE}, + {(char*)"pen-cansplice", required_argument, 0, ARG_PEN_CANSPLICE}, + {(char*)"pen-noncansplice", required_argument, 0, ARG_PEN_NONCANSPLICE}, + {(char*)"pen-conflictsplice", required_argument, 0, ARG_PEN_CONFLICTSPLICE}, + {(char*)"pen-intronlen", required_argument, 0, ARG_PEN_CANINTRONLEN}, + {(char*)"pen-canintronlen", required_argument, 0, ARG_PEN_CANINTRONLEN}, + {(char*)"pen-noncanintronlen", required_argument, 0, ARG_PEN_NONCANINTRONLEN}, + {(char*)"min-intronlen", required_argument, 0, ARG_MIN_INTRONLEN}, + {(char*)"max-intronlen", required_argument, 0, ARG_MAX_INTRONLEN}, + {(char*)"known-splicesite-infile", required_argument, 0, ARG_KNOWN_SPLICESITE_INFILE}, + {(char*)"novel-splicesite-infile", required_argument, 0, ARG_NOVEL_SPLICESITE_INFILE}, + {(char*)"novel-splicesite-outfile", required_argument, 0, ARG_NOVEL_SPLICESITE_OUTFILE}, + {(char*)"secondary", no_argument, 0, ARG_SECONDARY}, + {(char*)"no-spliced-alignment", no_argument, 0, ARG_NO_SPLICED_ALIGNMENT}, + {(char*)"rna-strandness", required_argument, 0, ARG_RNA_STRANDNESS}, + {(char*)"splicesite-db-only", no_argument, 0, ARG_SPLICESITE_DB_ONLY}, + {(char*)"no-anchorstop", no_argument, 0, ARG_NO_ANCHORSTOP}, + {(char*)"transcriptome-mapping-only", no_argument, 0, ARG_TRANSCRIPTOME_MAPPING_ONLY}, + {(char*)"tmo", no_argument, 0, ARG_TRANSCRIPTOME_MAPPING_ONLY}, + {(char*)"downstream-transcriptome-assembly", no_argument, 0, ARG_TRANSCRIPTOME_ASSEMBLY}, + {(char*)"dta", no_argument, 0, ARG_TRANSCRIPTOME_ASSEMBLY}, + {(char*)"dta-cufflinks", no_argument, 0, ARG_TRANSCRIPTOME_ASSEMBLY_CUFFLINKS}, + {(char*)"avoid-pseudogene",no_argument, 0, ARG_AVOID_PSEUDOGENE}, + {(char*)"no-templatelen-adjustment", no_argument, 0, ARG_NO_TEMPLATELEN_ADJUSTMENT}, +#ifdef USE_SRA + {(char*)"sra-acc", required_argument, 0, ARG_SRA_ACC}, +#endif + {(char*)"remove-chrname", no_argument, 0, ARG_REMOVE_CHRNAME}, + {(char*)"add-chrname", no_argument, 0, ARG_ADD_CHRNAME}, + {(char*)"max-altstried", required_argument, 0, ARG_MAX_ALTSTRIED}, + {(char*)"haplotype", no_argument, 0, ARG_HAPLOTYPE}, + {(char*)"enable-codis", no_argument, 0, ARG_CODIS}, + {(char*)"summary-file", required_argument, 0, ARG_SUMMARY_FILE}, + {(char*)"new-summary", no_argument, 0, ARG_NEW_SUMMARY}, + {(char*)"enable-dp", no_argument, 0, ARG_DP}, + {(char*)"bowtie2-dp", required_argument, 0, ARG_DP}, + {(char*)"repeat", no_argument, 0, ARG_REPEAT}, + {(char*)"no-repeat-index", no_argument, 0, ARG_NO_REPEAT_INDEX}, + {(char*)"read-lengths", required_argument, 0, ARG_READ_LENGTHS}, + {(char*)"base-change", required_argument, 0, ARG_BASE_CHANGE}, + {(char*)"repeat-limit", required_argument, 0, ARG_REPEAT_LIMIT}, + {(char*)"unique-only", no_argument, 0, ARG_UNIQUE_ONLY}, + {(char*)"3N", no_argument, 0, ARG_3N}, + {(char*)"directional-mapping", no_argument, 0, ARG_DIRECTIONAL}, + {(char*)"directional-mapping-reverse", no_argument, 0, ARG_DIRECTIONAL_REVERSE}, + {(char*)0, 0, 0, 0} // terminator +}; + +/** + * Print out a concise description of what options are taken and whether they + * take an argument. + */ +static void printArgDesc(ostream& out) { + // struct option { + // const char *name; + // int has_arg; + // int *flag; + // int val; + // }; + size_t i = 0; + while(long_options[i].name != 0) { + out << long_options[i].name << "\t" + << (long_options[i].has_arg == no_argument ? 0 : 1) + << endl; + i++; + } + size_t solen = strlen(short_options); + for(i = 0; i < solen; i++) { + // Has an option? Does if next char is : + if(i == solen-1) { + assert_neq(':', short_options[i]); + cout << (char)short_options[i] << "\t" << 0 << endl; + } else { + if(short_options[i+1] == ':') { + // Option with argument + cout << (char)short_options[i] << "\t" << 1 << endl; + i++; // skip the ':' + } else { + // Option with no argument + cout << (char)short_options[i] << "\t" << 0 << endl; + } + } + } +} + +/** + * Print a summary usage message to the provided output stream. + */ +static void printUsage(ostream& out) { + out << "HISAT2 version " << string(HISAT2_VERSION).c_str() << " by Daehwan Kim (infphilo@gmail.com, www.ccb.jhu.edu/people/infphilo)" << endl; + string tool_name = "hisat2-align"; + if(wrapper == "basic-0") { + tool_name = "hisat2"; + } + out << "Usage: " << endl +#ifdef USE_SRA + << " " << tool_name.c_str() << " [options]* -x {-1 -2 | -U | --sra-acc } [-S ]" << endl +#else + << " " << tool_name.c_str() << " [options]* -x {-1 -2 | -U } [-S ]" << endl +#endif + << endl + << " Index filename prefix (minus trailing .X." << gfm_ext << ")." << endl + << " Files with #1 mates, paired with files in ." << endl; + if(wrapper == "basic-0") { + out << " Could be gzip'ed (extension: .gz) or bzip2'ed (extension: .bz2)." << endl; + } + out << " Files with #2 mates, paired with files in ." << endl; + if(wrapper == "basic-0") { + out << " Could be gzip'ed (extension: .gz) or bzip2'ed (extension: .bz2)." << endl; + } + out << " Files with unpaired reads." << endl; + if(wrapper == "basic-0") { + out << " Could be gzip'ed (extension: .gz) or bzip2'ed (extension: .bz2)." << endl; + } +#ifdef USE_SRA + out << " Comma-separated list of SRA accession numbers, e.g. --sra-acc SRR353653,SRR353654." << endl; +#endif + out << " File for SAM output (default: stdout)" << endl + << endl + << " , , can be comma-separated lists (no whitespace) and can be" << endl + << " specified many times. E.g. '-U file1.fq,file2.fq -U file3.fq'." << endl + // Wrapper script should write line next + << endl + << "Options (defaults in parentheses):" << endl + << endl + << " Input:" << endl + << " -q query input files are FASTQ .fq/.fastq (default)" << endl + << " --qseq query input files are in Illumina's qseq format" << endl + << " -f query input files are (multi-)FASTA .fa/.mfa" << endl + << " -r query input files are raw one-sequence-per-line" << endl + << " -c , , are sequences themselves, not files" << endl + << " -s/--skip skip the first reads/pairs in the input (none)" << endl + << " -u/--upto stop after first reads/pairs (no limit)" << endl + << " -5/--trim5 trim bases from 5'/left end of reads (0)" << endl + << " -3/--trim3 trim bases from 3'/right end of reads (0)" << endl + << " --phred33 qualities are Phred+33 (default)" << endl + << " --phred64 qualities are Phred+64" << endl + << " --int-quals qualities encoded as space-delimited integers" << endl +#ifdef USE_SRA + << " --sra-acc SRA accession ID" << endl +#endif + << endl + + << " Presets: Same as:" << endl + // << " For --end-to-end:" << endl + // << " --very-fast -D 5 -R 1 -N 0 -L 22 -i S,0,2.50" << endl + // << " --fast -D 10 -R 2 -N 0 -L 22 -i S,0,2.50" << endl + // << " --sensitive -D 15 -R 2 -N 0 -L 22 -i S,1,1.15 (default)" << endl + // << " --very-sensitive -D 20 -R 3 -N 0 -L 20 -i S,1,0.50" << endl + << " --fast --no-repeat-index" << endl + << " --sensitive --bowtie2-dp 1 -k 30 --score-min L,0,-0.5" << endl + << " --very-sensitive --bowtie2-dp 2 -k 50 --score-min L,0,-1" << endl + << endl + << " Alignment:" << endl + //<< " -N max # mismatches in seed alignment; can be 0 or 1 (0)" << endl + //<< " -L length of seed substrings; must be >3, <32 (22)" << endl + //<< " -i interval between seed substrings w/r/t read len (S,1,1.15)" << endl + << " --bowtie2-dp use Bowtie2's dynamic programming alignment algorithm (0) - 0: no dynamic programming, 1: conditional dynamic programming, and 2: unconditional dynamic programming (slowest)" << endl + << " --n-ceil func for max # non-A/C/G/Ts permitted in aln (L,0,0.15)" << endl + //<< " --dpad include extra ref chars on sides of DP table (15)" << endl + //<< " --gbar disallow gaps within nucs of read extremes (4)" << endl + << " --ignore-quals treat all quality values as 30 on Phred scale (off)" << endl + << " --nofw do not align forward (original) version of read (off)" << endl + << " --norc do not align reverse-complement version of read (off)" << endl + << " --no-repeat-index do not use repeat index" << endl + << endl + << " 3N-Alignment:" << endl + << " --base-change the converted nucleotide and converted to nucleotide (C,T)" << endl + << " --directional-mapping make directional mapping, please use this option only if your reads are prepared with a strand specific library (off)" << endl + << " --repeat-limit maximum number of repeat will be expanded for repeat alignment (1000)" << endl + << " --unique-only only output the reads have unique alignment (off)" << endl + << endl + << " Spliced Alignment:" << endl + << " --pen-cansplice penalty for a canonical splice site (0)" << endl + << " --pen-noncansplice penalty for a non-canonical splice site (12)" << endl + // << " --pen-conflictsplice penalty for conflicting splice sites (1000000)" << endl + << " --pen-canintronlen penalty for long introns (G,-8,1) with canonical splice sites" << endl + << " --pen-noncanintronlen penalty for long introns (G,-8,1) with noncanonical splice sites" << endl + << " --min-intronlen minimum intron length (20)" << endl + << " --max-intronlen maximum intron length (500000)" << endl + << " --known-splicesite-infile provide a list of known splice sites" << endl + << " --novel-splicesite-outfile report a list of splice sites" << endl + << " --novel-splicesite-infile provide a list of novel splice sites" << endl + << " --no-temp-splicesite disable the use of splice sites found" << endl + << " --no-spliced-alignment disable spliced alignment" << endl + << " --rna-strandness specify strand-specific information (unstranded)" << endl + << " --tmo reports only those alignments within known transcriptome" << endl + << " --dta reports alignments tailored for transcript assemblers" << endl + << " --dta-cufflinks reports alignments tailored specifically for cufflinks" << endl + << " --avoid-pseudogene tries to avoid aligning reads to pseudogenes (experimental option)" << endl + << " --no-templatelen-adjustment disables template length adjustment for RNA-seq reads" << endl + << endl + << " Scoring:" << endl + //<< " --ma match bonus (0 for --end-to-end, 2 for --local) " << endl + << " --mp , max and min penalties for mismatch; lower qual = lower penalty <6,2>" << endl + << " --sp , max and min penalties for soft-clipping; lower qual = lower penalty <2,1>" << endl + << " --no-softclip no soft-clipping" << endl + << " --np penalty for non-A/C/G/Ts in read/ref (1)" << endl + << " --rdg , read gap open, extend penalties (5,3)" << endl + << " --rfg , reference gap open, extend penalties (5,3)" << endl + << " --score-min min acceptable alignment score w/r/t read length" << endl + << " (L,0.0,-0.2)" << endl + << endl + << " Reporting:" << endl + << " -k It searches for at most distinct, primary alignments for each read. Primary alignments mean " << endl + << " alignments whose alignment score is equal to or higher than any other alignments. The search terminates " << endl + << " when it cannot find more distinct valid alignments, or when it finds , whichever happens first. " << endl + << " The alignment score for a paired-end alignment equals the sum of the alignment scores of " << endl + << " the individual mates. Each reported read or pair alignment beyond the first has the SAM ‘secondary’ bit " << endl + << " (which equals 256) set in its FLAGS field. For reads that have more than distinct, " << endl + << " valid alignments, hisat2 does not guarantee that the alignments reported are the best possible " << endl + << " in terms of alignment score. Default: 5 (linear index) or 10 (graph index)." << endl + << " Note: HISAT2 is not designed with large values for -k in mind, and when aligning reads to long, " << endl + << " repetitive genomes, large -k could make alignment much slower." << endl + << " --max-seeds HISAT2, like other aligners, uses seed-and-extend approaches. HISAT2 tries to extend seeds to " << endl + << " full-length alignments. In HISAT2, --max-seeds is used to control the maximum number of seeds that " << endl + << " will be extended. For DNA-read alignment (--no-spliced-alignment), HISAT2 extends up to these many seeds" << endl + << " and skips the rest of the seeds. For RNA-read alignment, HISAT2 skips extending seeds and reports " << endl + << " no alignments if the number of seeds is larger than the number specified with the option, " << endl + << " to be compatible with previous versions of HISAT2. Large values for --max-seeds may improve alignment " << endl + << " sensitivity, but HISAT2 is not designed with large values for --max-seeds in mind, and when aligning " << endl + << " reads to long, repetitive genomes, large --max-seeds could make alignment much slower. " << endl + << " The default value is the maximum of 5 and the value that comes with -k times 2." << endl + << " -a/--all HISAT2 reports all alignments it can find. Using the option is equivalent to using both --max-seeds " << endl + << " and -k with the maximum value that a 64-bit signed integer can represent (9,223,372,036,854,775,807)." << endl + << " --repeat report alignments to repeat sequences directly" << endl + << endl + //<< " Effort:" << endl + //<< " -D give up extending after failed extends in a row (15)" << endl + //<< " -R for reads w/ repetitive seeds, try sets of seeds (2)" << endl + //<< endl + << " Paired-end:" << endl + << " -I/--minins minimum fragment length (0), only valid with --no-spliced-alignment" << endl + << " -X/--maxins maximum fragment length (500), only valid with --no-spliced-alignment" << endl + << " --fr/--rf/--ff -1, -2 mates align fw/rev, rev/fw, fw/fw (--fr)" << endl + << " --no-mixed suppress unpaired alignments for paired reads" << endl + << " --no-discordant suppress discordant alignments for paired reads" << endl + << endl + << " Output:" << endl; + //if(wrapper == "basic-0") { + // out << " --bam output directly to BAM (by piping through 'samtools view')" << endl; + //} + out << " -t/--time print wall-clock time taken by search phases" << endl; + if(wrapper == "basic-0") { + out << " --un write unpaired reads that didn't align to " << endl + << " --al write unpaired reads that aligned at least once to " << endl + << " --un-conc write pairs that didn't align concordantly to " << endl + << " --al-conc write pairs that aligned concordantly at least once to " << endl + << " (Note: for --un, --al, --un-conc, or --al-conc, add '-gz' to the option name, e.g." << endl + << " --un-gz , to gzip compress output, or add '-bz2' to bzip2 compress output.)" << endl; + } + out << " --summary-file print alignment summary to this file." << endl + << " --new-summary print alignment summary in a new style, which is more machine-friendly." << endl + << " --quiet print nothing to stderr except serious errors" << endl + // << " --refidx refer to ref. seqs by 0-based index rather than name" << endl + << " --met-file send metrics to file at (off)" << endl + << " --met-stderr send metrics to stderr (off)" << endl + << " --met report internal counters & metrics every secs (1)" << endl + // Following is supported in the wrapper instead + // << " --no-unal suppress SAM records for unaligned reads" << endl + << " --no-head suppress header lines, i.e. lines starting with @" << endl + << " --no-sq suppress @SQ header lines" << endl + << " --rg-id set read group id, reflected in @RG line and RG:Z: opt field" << endl + << " --rg add (\"lab:value\") to @RG line of SAM header." << endl + << " Note: @RG line only printed when --rg-id is set." << endl + << " --omit-sec-seq put '*' in SEQ and QUAL fields for secondary alignments." << endl + << endl + << " Performance:" << endl + << " -o/--offrate override offrate of index; must be >= index's offrate" << endl + << " -p/--threads number of alignment threads to launch (1)" << endl + << " --reorder force SAM output order to match order of input reads" << endl +#ifdef BOWTIE_MM + << " --mm use memory-mapped I/O for index; many 'hisat2's can share" << endl +#endif +#ifdef BOWTIE_SHARED_MEM + //<< " --shmem use shared mem for index; many 'hisat2's can share" << endl +#endif + << endl + << " Other:" << endl + << " --qc-filter filter out reads that are bad according to QSEQ filter" << endl + << " --seed seed for random number generator (0)" << endl + << " --non-deterministic seed rand. gen. arbitrarily instead of using read attributes" << endl + << " --remove-chrname remove 'chr' from reference names in alignment" << endl + << " --add-chrname add 'chr' to reference names in alignment " << endl + // << " --verbose verbose output for debugging" << endl + << " --version print version information and quit" << endl + << " -h/--help print this usage message" << endl + ; + if(wrapper.empty()) { + cerr << endl + << "*** Warning ***" << endl + << "'hisat2-align' was run directly. It is recommended that you run the wrapper script 'hisat2' instead." << endl + << endl; + } +} + +/** + * Parse an int out of optarg and enforce that it be at least 'lower'; + * if it is less than 'lower', than output the given error message and + * exit with an error and a usage message. + */ +static int parseInt(int lower, int upper, const char *errmsg, const char *arg) { + long l; + char *endPtr= NULL; + l = strtol(arg, &endPtr, 10); + if (endPtr != NULL) { + if (l < lower || l > upper) { + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + } + return (int32_t)l; + } + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + return -1; +} + +/** + * Upper is maximum int by default. + */ +static int parseInt(int lower, const char *errmsg, const char *arg) { + return parseInt(lower, std::numeric_limits::max(), errmsg, arg); +} + +/** + * Parse a T string 'str'. + */ +template +T parse(const char *s) { + T tmp; + stringstream ss(s); + ss >> tmp; + return tmp; +} + +/** + * Parse a pair of Ts from a string, 'str', delimited with 'delim'. + */ +template +pair parsePair(const char *str, char delim) { + string s(str); + EList ss; + tokenize(s, delim, ss); + pair ret; + ret.first = parse(ss[0].c_str()); + ret.second = parse(ss[1].c_str()); + return ret; +} + +/** + * Parse a pair of Ts from a string, 'str', delimited with 'delim'. + */ +template +void parseTuple(const char *str, char delim, EList& ret) { + string s(str); + EList ss; + tokenize(s, delim, ss); + for(size_t i = 0; i < ss.size(); i++) { + ret.push_back(parse(ss[i].c_str())); + } +} + +static string applyPreset(const string& sorig, Presets& presets) { + string s = sorig; + size_t found = s.find("%LOCAL%"); + if(found != string::npos) { + s.replace(found, strlen("%LOCAL%"), localAlign ? "-local" : ""); + } + if(gVerbose) { + cerr << "Applying preset: '" << s.c_str() << "' using preset menu '" + << presets.name() << "'" << endl; + } + string pol; + presets.apply(s, pol, extra_opts); + return pol; +} + +static bool saw_M; +static bool saw_a; +static bool saw_k; +static EList presetList; + +/** + * TODO: Argument parsing is very, very flawed. The biggest problem is that + * there are two separate worlds of arguments, the ones set via polstr, and + * the ones set directly in variables. This makes for nasty interactions, + * e.g., with the -M option being resolved at an awkward time relative to + * the -k and -a options. + */ +static void parseOption(int next_option, const char *arg) { + switch (next_option) { + case ARG_TEST_25: bowtie2p5 = true; break; + case ARG_DESC_KB: descentTotSz = SimpleFunc::parse(arg, 0.0, 1024.0, 1024.0, DMAX); break; + case ARG_DESC_FMOPS: descentTotFmops = SimpleFunc::parse(arg, 0.0, 10.0, 100.0, DMAX); break; + case ARG_DESC_LANDING: descentLanding = parse(arg); break; + case ARG_DESC_EXP: { + descConsExp = parse(arg); + if(descConsExp < 0.0) { + cerr << "Error: --desc-exp must be greater than or equal to 0" << endl; + throw 1; + } + break; + } + case '1': tokenize(arg, ",", mates1); break; + case '2': tokenize(arg, ",", mates2); break; + case ARG_ONETWO: tokenize(arg, ",", mates12); format = TAB_MATE5; break; + case ARG_TAB5: tokenize(arg, ",", mates12); format = TAB_MATE5; break; + case ARG_TAB6: tokenize(arg, ",", mates12); format = TAB_MATE6; break; + case 'f': format = FASTA; break; + case 'F': { + format = FASTA_CONT; + pair p = parsePair(arg, ','); + fastaContLen = p.first; + fastaContFreq = p.second; + break; + } + case ARG_BWA_SW_LIKE: { + bwaSwLikeC = 5.5f; + bwaSwLikeT = 30; + bwaSwLike = true; + localAlign = true; + // -a INT Score of a match [1] + // -b INT Mismatch penalty [3] + // -q INT Gap open penalty [5] + // -r INT Gap extension penalty. The penalty for a contiguous + // gap of size k is q+k*r. [2] + polstr += ";MA=1;MMP=C3;RDG=5,2;RFG=5,2"; + break; + } + case 'q': format = FASTQ; break; + case 'r': format = RAW; break; + case 'c': format = CMDLINE; break; + case ARG_QSEQ: format = QSEQ; break; + case 'C': { + cerr << "Error: -C specified but Bowtie 2 does not support colorspace input." << endl; + throw 1; + break; + } + case 'I': + gMinInsert = parseInt(0, "-I arg must be positive", arg); + break; + case 'X': + gMaxInsert = parseInt(1, "-X arg must be at least 1", arg); + break; + case ARG_NO_DISCORDANT: gReportDiscordant = false; break; + case ARG_NO_MIXED: gReportMixed = false; break; + case 's': + skipReads = (uint32_t)parseInt(0, "-s arg must be positive", arg); + break; + case ARG_FF: gMate1fw = true; gMate2fw = true; break; + case ARG_RF: gMate1fw = false; gMate2fw = true; break; + case ARG_FR: gMate1fw = true; gMate2fw = false; break; + case ARG_SHMEM: useShmem = true; break; + case ARG_SEED_SUMM: seedSumm = true; break; + case ARG_MM: { +#ifdef BOWTIE_MM + useMm = true; + break; +#else + cerr << "Memory-mapped I/O mode is disabled because bowtie was not compiled with" << endl + << "BOWTIE_MM defined. Memory-mapped I/O is not supported under Windows. If you" << endl + << "would like to use memory-mapped I/O on a platform that supports it, please" << endl + << "refrain from specifying BOWTIE_MM=0 when compiling Bowtie." << endl; + throw 1; +#endif + } + case ARG_MMSWEEP: mmSweep = true; break; + case ARG_HADOOPOUT: hadoopOut = true; break; + case ARG_SOLEXA_QUALS: solexaQuals = true; break; + case ARG_INTEGER_QUALS: integerQuals = true; break; + case ARG_PHRED64: phred64Quals = true; break; + case ARG_PHRED33: solexaQuals = false; phred64Quals = false; break; + case ARG_OVERHANG: gReportOverhangs = true; break; + case ARG_NO_CACHE: msNoCache = true; break; + case ARG_USE_CACHE: msNoCache = false; break; + case ARG_LOCAL_SEED_CACHE_SZ: + seedCacheLocalMB = (uint32_t)parseInt(1, "--local-seed-cache-sz arg must be at least 1", arg); + break; + case ARG_CURRENT_SEED_CACHE_SZ: + seedCacheCurrentMB = (uint32_t)parseInt(1, "--seed-cache-sz arg must be at least 1", arg); + break; + case ARG_REFIDX: noRefNames = true; break; + case ARG_FUZZY: fuzzy = true; break; + case ARG_FULLREF: fullRef = true; break; + case ARG_GAP_BAR: + gGapBarrier = parseInt(1, "--gbar must be no less than 1", arg); + break; + case ARG_SEED: + seed = parseInt(0, "--seed arg must be at least 0", arg); + break; + case ARG_NON_DETERMINISTIC: + arbitraryRandom = true; + break; + case 'u': + qUpto = (uint32_t)parseInt(1, "-u/--qupto arg must be at least 1", arg); + break; + case 'Q': + tokenize(arg, ",", qualities); + integerQuals = true; + break; + case ARG_QUALS1: + tokenize(arg, ",", qualities1); + integerQuals = true; + break; + case ARG_QUALS2: + tokenize(arg, ",", qualities2); + integerQuals = true; + break; + case ARG_CACHE_LIM: + cacheLimit = (uint32_t)parseInt(1, "--cachelim arg must be at least 1", arg); + break; + case ARG_CACHE_SZ: + cacheSize = (uint32_t)parseInt(1, "--cachesz arg must be at least 1", arg); + cacheSize *= (1024 * 1024); // convert from MB to B + break; + case ARG_WRAPPER: wrapper = arg; break; + case 'p': + nthreads = parseInt(1, "-p/--threads arg must be at least 1", arg); + break; + case ARG_FILEPAR: + fileParallel = true; + break; + case '3': gTrim3 = parseInt(0, "-3/--trim3 arg must be at least 0", arg); break; + case '5': gTrim5 = parseInt(0, "-5/--trim5 arg must be at least 0", arg); break; + case 'h': printUsage(cout); throw 0; break; + case ARG_USAGE: printUsage(cout); throw 0; break; + // + // NOTE that unlike in Bowtie 1, -M, -a and -k are mutually + // exclusive here. + // + case 'M': { + msample = true; + mhits = parse(arg); + if(saw_a || saw_k) { + cerr << "Warning: -M, -k and -a are mutually exclusive. " + << "-M will override" << endl; + khits = 1; + } + assert_eq(1, khits); + saw_M = true; + cerr << "Warning: -M is deprecated. Use -D and -R to adjust " << + "effort instead." << endl; + break; + } + case ARG_EXTEND_ITERS: { + maxIters = parse(arg); + break; + } + case ARG_NO_EXTEND: { + doExtend = false; + break; + } + case 'R': { polstr += ";ROUNDS="; polstr += arg; break; } + case 'D': { polstr += ";DPS="; polstr += arg; break; } + case ARG_DP_MATE_STREAK_THRESH: { + maxMateStreak = parse(arg); + break; + } + case ARG_DP_FAIL_STREAK_THRESH: { + maxDpStreak = parse(arg); + break; + } + case ARG_EE_FAIL_STREAK_THRESH: { + maxEeStreak = parse(arg); + break; + } + case ARG_UG_FAIL_STREAK_THRESH: { + maxUgStreak = parse(arg); + break; + } + case ARG_DP_FAIL_THRESH: { + maxDp = parse(arg); + break; + } + case ARG_UG_FAIL_THRESH: { + maxUg = parse(arg); + break; + } + case ARG_MAX_SEEDS: { + maxSeeds = parse(arg); + break; + } + case ARG_SEED_BOOST_THRESH: { + seedBoostThresh = parse(arg); + break; + } + case 'a': { + msample = false; + allHits = true; + mhits = 0; // disable -M + if(saw_M || saw_k) { + cerr << "Warning: -M, -k and -a are mutually exclusive. " + << "-a will override" << endl; + } + saw_a = true; + break; + } + case 'k': { + msample = false; + khits = (uint32_t)parseInt(1, "-k arg must be at least 1", arg); + mhits = 0; // disable -M + if(saw_M || saw_a) { + cerr << "Warning: -M, -k and -a are mutually exclusive. " + << "-k will override" << endl; + } + saw_k = true; + break; + } + case ARG_VERBOSE: gVerbose = 1; break; + case ARG_STARTVERBOSE: startVerbose = true; break; + case ARG_QUIET: gQuiet = true; break; + case ARG_SANITY: sanityCheck = true; break; + case 't': timing = true; break; + case ARG_METRIC_IVAL: { + metricsIval = parseInt(1, "--metrics arg must be at least 1", arg); + break; + } + case ARG_METRIC_FILE: metricsFile = arg; break; + case ARG_METRIC_STDERR: metricsStderr = true; break; + case ARG_METRIC_PER_READ: metricsPerRead = true; break; + case ARG_NO_FW: gNofw = true; break; + case ARG_NO_RC: gNorc = true; break; + case ARG_SAM_NO_QNAME_TRUNC: samTruncQname = false; break; + case ARG_SAM_OMIT_SEC_SEQ: samOmitSecSeqQual = true; break; + case ARG_SAM_NO_UNAL: samNoUnal = true; break; + case ARG_SAM_NOHEAD: samNoHead = true; break; + case ARG_SAM_NOSQ: samNoSQ = true; break; + case ARG_SAM_PRINT_YI: sam_print_yi = true; break; + case ARG_REORDER: reorder = true; break; + case ARG_MAPQ_EX: { + sam_print_zp = true; + sam_print_zu = true; + sam_print_xp = true; + sam_print_xss = true; + sam_print_yn = true; + break; + } + case ARG_SHOW_RAND_SEED: { + sam_print_zs = true; + break; + } + case ARG_SAMPLE: + sampleFrac = parse(arg); + break; + case ARG_CP_MIN: + cminlen = parse(arg); + break; + case ARG_CP_IVAL: + cpow2 = parse(arg); + break; + case ARG_TRI: + doTri = true; + break; + case ARG_READ_PASSTHRU: { + sam_print_xr = true; + break; + } + case ARG_READ_TIMES: { + sam_print_xt = true; + sam_print_xd = true; + sam_print_xu = true; + sam_print_yl = true; + sam_print_ye = true; + sam_print_yu = true; + sam_print_yr = true; + sam_print_zb = true; + sam_print_zr = true; + sam_print_zf = true; + sam_print_zm = true; + sam_print_zi = true; + break; + } + case ARG_SAM_RG: { + string argstr = arg; + if(argstr.substr(0, 3) == "ID:") { + rgid = "\t"; + rgid += argstr; + rgs_optflag = "RG:Z:" + argstr.substr(3); + } else { + rgs += '\t'; + rgs += argstr; + } + break; + } + case ARG_SAM_RGID: { + string argstr = arg; + rgid = "\t"; + rgid = "\tID:" + argstr; + rgs_optflag = "RG:Z:" + argstr; + break; + } + case ARG_PARTITION: partitionSz = parse(arg); break; + case ARG_DPAD: + maxhalf = parseInt(0, "--dpad must be no less than 0", arg); + break; + case ARG_ORIG: + if(arg == NULL || strlen(arg) == 0) { + cerr << "--orig arg must be followed by a string" << endl; + printUsage(cerr); + throw 1; + } + origString = arg; + break; + case ARG_LOCAL: localAlign = true; break; + case ARG_END_TO_END: localAlign = false; break; + case ARG_SSE8: enable8 = true; break; + case ARG_SSE8_NO: enable8 = false; break; + case ARG_UNGAPPED: doUngapped = true; break; + case ARG_UNGAPPED_NO: doUngapped = false; break; + // case ARG_NO_DOVETAIL: gDovetailMatesOK = false; break; + // case ARG_NO_CONTAIN: gContainMatesOK = false; break; + // case ARG_NO_OVERLAP: gOlapMatesOK = false; break; + // case ARG_DOVETAIL: gDovetailMatesOK = true; break; + // case ARG_CONTAIN: gContainMatesOK = true; break; + // case ARG_OVERLAP: gOlapMatesOK = true; break; + case ARG_QC_FILTER: qcFilter = true; break; + case ARG_NO_SCORE_PRIORITY: sortByScore = false; break; + case ARG_IGNORE_QUALS: ignoreQuals = true; break; + case ARG_MAPQ_V: mapqv = parse(arg); break; + case ARG_TIGHTEN: tighten = parse(arg); break; + case ARG_EXACT_UPFRONT: doExactUpFront = true; break; + case ARG_1MM_UPFRONT: do1mmUpFront = true; break; + case ARG_EXACT_UPFRONT_NO: doExactUpFront = false; break; + case ARG_1MM_UPFRONT_NO: do1mmUpFront = false; break; + case ARG_1MM_MINLEN: do1mmMinLen = parse(arg); break; + case ARG_NOISY_HPOLY: noisyHpolymer = true; break; + case 'x' : bt2indexs[0] = arg; break; + case ARG_PRESET_VERY_FAST_LOCAL: localAlign = true; + case ARG_PRESET_VERY_FAST: { + presetList.push_back("very-fast%LOCAL%"); break; + } + case ARG_PRESET_FAST_LOCAL: localAlign = true; + case ARG_PRESET_FAST: { + fast = true; + presetList.push_back("fast%LOCAL%"); break; + } + case ARG_PRESET_SENSITIVE_LOCAL: localAlign = true; + case ARG_PRESET_SENSITIVE: { + sensitive = true; + presetList.push_back("sensitive%LOCAL%"); break; + } + case ARG_PRESET_VERY_SENSITIVE_LOCAL: localAlign = true; + case ARG_PRESET_VERY_SENSITIVE: { + very_sensitive = true; + presetList.push_back("very-sensitive%LOCAL%"); break; + } + case 'P': { presetList.push_back(arg); break; } + case ARG_ALIGN_POLICY: { + if(strlen(arg) > 0) { + polstr += ";"; polstr += arg; + } + break; + } + case 'N': { polstr += ";SEED="; polstr += arg; break; } + case 'L': { + int64_t len = parse(arg); + if(len < 0) { + cerr << "Error: -L argument must be >= 0; was " << arg << endl; + throw 1; + } + if(len > 32) { + cerr << "Error: -L argument must be <= 32; was" << arg << endl; + throw 1; + } + polstr += ";SEEDLEN="; polstr += arg; break; + } + case 'O': + multiseedOff = parse(arg); + break; + case 'i': { + EList args; + tokenize(arg, ",", args); + if(args.size() > 3 || args.size() == 0) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to -i option, got " + << args.size() << endl; + throw 1; + } + // Interval-settings arguments + polstr += (";IVAL=" + args[0]); // Function type + if(args.size() > 1) { + polstr += ("," + args[1]); // Constant term + } + if(args.size() > 2) { + polstr += ("," + args[2]); // Coefficient + } + break; + } + case ARG_MULTISEED_IVAL: { + polstr += ";"; + // Split argument by comma + EList args; + tokenize(arg, ",", args); + if(args.size() > 5 || args.size() == 0) { + cerr << "Error: expected 5 or fewer comma-separated " + << "arguments to --multiseed option, got " + << args.size() << endl; + throw 1; + } + // Seed mm and length arguments + polstr += "SEED="; + polstr += (args[0]); // # mismatches + if(args.size() > 1) polstr += ("," + args[ 1]); // length + if(args.size() > 2) polstr += (";IVAL=" + args[2]); // Func type + if(args.size() > 3) polstr += ("," + args[ 3]); // Constant term + if(args.size() > 4) polstr += ("," + args[ 4]); // Coefficient + break; + } + case ARG_N_CEIL: { + // Split argument by comma + EList args; + tokenize(arg, ",", args); + if(args.size() > 3) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to --n-ceil option, got " + << args.size() << endl; + throw 1; + } + if(args.size() == 0) { + cerr << "Error: expected at least one argument to --n-ceil option" << endl; + throw 1; + } + polstr += ";NCEIL="; + if(args.size() == 3) { + polstr += (args[0] + "," + args[1] + "," + args[2]); + } else { + if(args.size() == 1) { + polstr += ("C," + args[0]); + } else { + polstr += (args[0] + "," + args[1]); + } + } + break; + } + case ARG_SCORE_MA: polstr += ";MA="; polstr += arg; break; + case ARG_SCORE_MMP: { + EList args; + tokenize(arg, ",", args); + if(args.size() > 2 || args.size() == 0) { + cerr << "Error: expected 1 or 2 comma-separated " + << "arguments to --mp option, got " << args.size() << endl; + throw 1; + } + if(args.size() >= 1) { + polstr += ";MMP=Q,"; + polstr += args[0]; + if(args.size() >= 2) { + polstr += ","; + polstr += args[1]; + } + } + break; + } + case ARG_SCORE_SCP: { + EList args; + tokenize(arg, ",", args); + if(args.size() > 2 || args.size() == 0) { + cerr << "Error: expected 1 or 2 comma-separated " + << "arguments to --sp option, got " << args.size() << endl; + throw 1; + } + if(args.size() >= 1) { + polstr += ";SCP=Q,"; + polstr += args[0]; + if(args.size() >= 2) { + polstr += ","; + polstr += args[1]; + } + } + break; + } + case ARG_NO_SOFTCLIP: { + ostringstream convert; + convert << std::numeric_limits::max(); + polstr += ";SCP=Q,"; + polstr += convert.str(); + polstr += ","; + polstr += convert.str(); + break; + } + case ARG_SCORE_NP: polstr += ";NP=C"; polstr += arg; break; + case ARG_SCORE_RDG: polstr += ";RDG="; polstr += arg; break; + case ARG_SCORE_RFG: polstr += ";RFG="; polstr += arg; break; + case ARG_SCORE_MIN: { + polstr += ";"; + EList args; + tokenize(arg, ",", args); + if(args.size() > 3 && args.size() == 0) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to --n-ceil option, got " + << args.size() << endl; + throw 1; + } + polstr += ("MIN=" + args[0]); + if(args.size() > 1) { + polstr += ("," + args[1]); + } + if(args.size() > 2) { + polstr += ("," + args[2]); + } + break; + } + case ARG_DESC: printArgDesc(cout); throw 0; + case 'S': outfile = arg; break; + case 'U': { + EList args; + tokenize(arg, ",", args); + for(size_t i = 0; i < args.size(); i++) { + queries.push_back(args[i]); + } + break; + } + case ARG_VERSION: showVersion = 1; break; + case ARG_NO_TEMPSPLICESITE: useTempSpliceSite = false; break; + case ARG_PEN_CANSPLICE: { + penCanSplice = parseInt(0, "--pen-cansplice arg must be at least 0", arg); + break; + } + case ARG_PEN_NONCANSPLICE: { + penNoncanSplice = parseInt(0, "--pen-noncansplice arg must be at least 0", arg); + break; + } + case ARG_PEN_CONFLICTSPLICE: { + penConflictSplice = parseInt(0, "--pen-conflictsplice arg must be at least 0", arg); + break; + } + case ARG_PEN_CANINTRONLEN: { + polstr += ";"; + EList args; + tokenize(arg, ",", args); + if(args.size() > 3 && args.size() == 0) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to --n-ceil option, got " + << args.size() << endl; + throw 1; + } + polstr += ("CANINTRONLEN=" + args[0]); + if(args.size() > 1) { + polstr += ("," + args[1]); + } + if(args.size() > 2) { + polstr += ("," + args[2]); + } + break; + } + case ARG_PEN_NONCANINTRONLEN: { + polstr += ";"; + EList args; + tokenize(arg, ",", args); + if(args.size() > 3 && args.size() == 0) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to --n-ceil option, got " + << args.size() << endl; + throw 1; + } + polstr += ("NONCANINTRONLEN=" + args[0]); + if(args.size() > 1) { + polstr += ("," + args[1]); + } + if(args.size() > 2) { + polstr += ("," + args[2]); + } + break; + } + case ARG_MIN_INTRONLEN: { + minIntronLen = parseInt(20, "--min-intronlen arg must be at least 20", arg); + break; + } + case ARG_MAX_INTRONLEN: { + maxIntronLen = parseInt(20, "--max-intronlen arg must be at least 20", arg); + break; + } + case ARG_KNOWN_SPLICESITE_INFILE: knownSpliceSiteInfile = arg; break; + case ARG_NOVEL_SPLICESITE_INFILE: novelSpliceSiteInfile = arg; break; + case ARG_NOVEL_SPLICESITE_OUTFILE: novelSpliceSiteOutfile = arg; break; + case ARG_SECONDARY: secondary = true; break; + case ARG_NO_SPLICED_ALIGNMENT: no_spliced_alignment = true; break; + case ARG_RNA_STRANDNESS: { + string strandness = arg; + if(strandness == "F") rna_strandness = RNA_STRANDNESS_F; + else if(strandness == "R") rna_strandness = RNA_STRANDNESS_R; + else if(strandness == "FR") rna_strandness = RNA_STRANDNESS_FR; + else if(strandness == "RF") rna_strandness = RNA_STRANDNESS_RF; + else { + cerr << "Error: should be one of F, R, FR, or RF " << endl; + throw 1; + } + break; + } + case ARG_SPLICESITE_DB_ONLY: { + splicesite_db_only = true; + break; + } + case ARG_NO_ANCHORSTOP: { + anchorStop = false; + break; + } + case ARG_TRANSCRIPTOME_MAPPING_ONLY: { + tranMapOnly = true; + break; + } + case ARG_TRANSCRIPTOME_ASSEMBLY: { + tranAssm = true; + break; + } + case ARG_TRANSCRIPTOME_ASSEMBLY_CUFFLINKS: { + tranAssm = true; + tranAssm_program = "cufflinks"; + break; + } + case ARG_AVOID_PSEUDOGENE: { + avoid_pseudogene = true; + break; + } +#ifdef USE_SRA + case ARG_SRA_ACC: { + tokenize(arg, ",", sra_accs); format = SRA_FASTA; + break; + } +#endif + case ARG_REMOVE_CHRNAME: { + rmChrName = true; + break; + } + case ARG_ADD_CHRNAME: { + addChrName = true; + break; + } + case ARG_MAX_ALTSTRIED: { + max_alts_tried = parseInt(8, "--max-altstried arg must be at least 8", arg); + break; + } + case ARG_HAPLOTYPE: { + use_haplotype = true; + break; + } + case ARG_CODIS: { + enable_codis = true; + break; + } + case ARG_NO_TEMPLATELEN_ADJUSTMENT: { + templateLenAdjustment = false; + break; + } + case ARG_SUMMARY_FILE: { + alignSumFile = arg; + break; + } + case ARG_NEW_SUMMARY: { + newAlignSummary = true; + break; + } + case ARG_DP: { + bowtie2_dp = parseInt(0, "--bowtie2-dp arg must be 0, 1, or 2", arg); + break; + } + case ARG_REPEAT: { + repeat = true; + break; + } + case ARG_NO_REPEAT_INDEX: { + use_repeat_index = false; + break; + } + case ARG_READ_LENGTHS: { + EList str_readLens; + tokenize(arg, ",", str_readLens); + for(size_t i = 0; i < str_readLens.size(); i++) { + int readLen = parseInt(0, "--read-lengths arg must be at least 0", str_readLens[i].c_str()); + readLens.push_back(readLen); + } + readLens.sort(); + break; + } + case ARG_BASE_CHANGE: { + // Split argument by comma + EList args; + tokenize(arg, ",", args); + if(args.size() != 2) { + cerr << "Error: expected 2 comma-separated " + << "arguments to --base-change option, got " << args.size() << endl; + throw 1; + } + base_change_entered = true; + usrInput_convertedFrom = toupper(args[0][0]); + usrInput_convertedTo = toupper(args[1][0]); + + string s = "ACGT"; + if ((s.find(usrInput_convertedFrom) == std::string::npos) || (s.find(usrInput_convertedTo) == std::string::npos)) { + cerr << "Please enter the nucleotide in 'ACGT' for --base-change option." << endl; + throw 1; + } + + if (usrInput_convertedFrom == usrInput_convertedTo) { + cerr << "Please enter two different base for --base-change option. If you wish to align normal reads without nucleotide conversion, please use hisat2." << endl; + throw 1; + } + + break; + } + case ARG_3N: { + threeN = true; + break; + } + case ARG_REPEAT_LIMIT: { + repeatLimit = parseInt(1, "--repeat-limit arg must be at least 1", arg);; + break; + } + case ARG_UNIQUE_ONLY: { + uniqueOutputOnly = true; + break; + } + case ARG_DIRECTIONAL: { + directional3NMapping = 1; + break; + } + case ARG_DIRECTIONAL_REVERSE: { + directional3NMapping = 2; + break; + } + default: + printUsage(cerr); + throw 1; + } +} + +/** + * Read command-line arguments + */ +static void parseOptions(int argc, const char **argv) { + int option_index = 0; + int next_option; + saw_M = false; + saw_a = false; + saw_k = false; + presetList.clear(); + if(startVerbose) { cerr << "Parsing options: "; logTime(cerr, true); } + while(true) { + next_option = getopt_long( + argc, const_cast(argv), + short_options, long_options, &option_index); + const char * arg = optarg; + if(next_option == EOF) { + if(extra_opts_cur < extra_opts.size()) { + next_option = extra_opts[extra_opts_cur].first; + arg = extra_opts[extra_opts_cur].second.c_str(); + extra_opts_cur++; + } else { + break; + } + } + parseOption(next_option, arg); + } + // Now parse all the presets. Might want to pick which presets version to + // use according to other parameters. + auto_ptr presets(new PresetsV0()); + // Apply default preset + if(!defaultPreset.empty()) { + polstr = applyPreset(defaultPreset, *presets.get()) + polstr; + } + // Apply specified presets + for(size_t i = 0; i < presetList.size(); i++) { + polstr += applyPreset(presetList[i], *presets.get()); + } + for(size_t i = 0; i < extra_opts.size(); i++) { + next_option = extra_opts[extra_opts_cur].first; + const char *arg = extra_opts[extra_opts_cur].second.c_str(); + parseOption(next_option, arg); + } + + if (showVersion) { + return; + } + + // Remove initial semicolons + while(!polstr.empty() && polstr[0] == ';') { + polstr = polstr.substr(1); + } + if(gVerbose) { + cerr << "Final policy string: '" << polstr.c_str() << "'" << endl; + } + + if (threeN && !base_change_entered) { + cerr << "--base-change must be set for HISAT-3N" << endl; + printUsage(cerr); + throw 1; + } + if (!threeN && base_change_entered) { + cerr << "Please do not use --base-change for HISAT2. To align nucleotide conversion reads, please use HISAT-3N" << endl; + printUsage(cerr); + throw 1; + } + + if (threeN) { + usrInput_convertedFromComplement = asc2dnacomp[usrInput_convertedFrom]; + usrInput_convertedToComplement = asc2dnacomp[usrInput_convertedTo]; + + getConversion(usrInput_convertedFrom, usrInput_convertedTo, hs3N_convertedFrom, hs3N_convertedTo); + hs3N_convertedFromComplement = asc2dnacomp[hs3N_convertedFrom]; + hs3N_convertedToComplement = asc2dnacomp[hs3N_convertedTo]; + + asc2dna_3N[0][hs3N_convertedFrom] = asc2dna[hs3N_convertedTo]; + asc2dna_3N[0][tolower(hs3N_convertedFrom)] = asc2dna[hs3N_convertedTo]; + asc2dna_3N[1][hs3N_convertedFromComplement] = asc2dna[hs3N_convertedToComplement]; + asc2dna_3N[1][tolower(hs3N_convertedFromComplement)] = asc2dna[hs3N_convertedToComplement]; + + threeN_indexTags[0] += hs3N_convertedFrom; + threeN_indexTags[0] += hs3N_convertedTo; + threeN_indexTags[1] += hs3N_convertedFromComplement; + threeN_indexTags[1] += hs3N_convertedToComplement; + + nMappingCycle = 4; + + if (hs3N_convertedFrom == hs3N_convertedToComplement || directional3NMapping == 1) { + mappingCycles[0] = true; + mappingCycles[1] = true; + } + else if (directional3NMapping == 2) { + mappingCycles[2] = true; + mappingCycles[3] = true; + } + else { + for (int i = 0; i < 4; i++){ + mappingCycles[i] = true; + } + } + } + else + { + nMappingCycle = 1; + mappingCycles[0] = true; + } + + size_t failStreakTmp = 0; + SeedAlignmentPolicy::parseString( + polstr, + localAlign, + noisyHpolymer, + ignoreQuals, + bonusMatchType, + bonusMatch, + penMmcType, + penMmcMax, + penMmcMin, + penScMax, + penScMin, + penNType, + penN, + penRdGapConst, + penRfGapConst, + penRdGapLinear, + penRfGapLinear, + scoreMin, + nCeil, + penNCatPair, + multiseedMms, + multiseedLen, + msIval, + failStreakTmp, + nSeedRounds, + &penCanIntronLen, + &penNoncanIntronLen); + if(failStreakTmp > 0) { + maxEeStreak = failStreakTmp; + maxUgStreak = failStreakTmp; + maxDpStreak = failStreakTmp; + } + if(saw_a || saw_k || true) { + msample = false; + mhits = 0; + } else { + assert_gt(mhits, 0); + msample = true; + } + + if(fast) { + use_repeat_index = false; + } else if(sensitive) { + if(bowtie2_dp == 0) { + bowtie2_dp = 1; + } + + if(khits < 10) { + khits = 10; + saw_k = true; + } + scoreMin.init(SIMPLE_FUNC_LINEAR, 0.0f, -0.5f); + } else if(very_sensitive) { + bowtie2_dp = 2; + if(khits < 30) { + khits = 30; + saw_k = true; + } + scoreMin.init(SIMPLE_FUNC_LINEAR, 0.0f, -1.0f); + } + + if(mates1.size() != mates2.size()) { + cerr << "Error: " << mates1.size() << " mate files/sequences were specified with -1, but " << mates2.size() << endl + << "mate files/sequences were specified with -2. The same number of mate files/" << endl + << "sequences must be specified with -1 and -2." << endl; + throw 1; + } + if(qualities.size() && format != FASTA) { + cerr << "Error: one or more quality files were specified with -Q but -f was not" << endl + << "enabled. -Q works only in combination with -f and -C." << endl; + throw 1; + } + if(qualities1.size() && format != FASTA) { + cerr << "Error: one or more quality files were specified with --Q1 but -f was not" << endl + << "enabled. --Q1 works only in combination with -f and -C." << endl; + throw 1; + } + if(qualities2.size() && format != FASTA) { + cerr << "Error: one or more quality files were specified with --Q2 but -f was not" << endl + << "enabled. --Q2 works only in combination with -f and -C." << endl; + throw 1; + } + if(qualities1.size() > 0 && mates1.size() != qualities1.size()) { + cerr << "Error: " << mates1.size() << " mate files/sequences were specified with -1, but " << qualities1.size() << endl + << "quality files were specified with --Q1. The same number of mate and quality" << endl + << "files must sequences must be specified with -1 and --Q1." << endl; + throw 1; + } + if(qualities2.size() > 0 && mates2.size() != qualities2.size()) { + cerr << "Error: " << mates2.size() << " mate files/sequences were specified with -2, but " << qualities2.size() << endl + << "quality files were specified with --Q2. The same number of mate and quality" << endl + << "files must sequences must be specified with -2 and --Q2." << endl; + throw 1; + } + if(!rgs.empty() && rgid.empty()) { + cerr << "Warning: --rg was specified without --rg-id also " + << "being specified. @RG line is not printed unless --rg-id " + << "is specified." << endl; + } + // Check for duplicate mate input files + if(format != CMDLINE) { + for(size_t i = 0; i < mates1.size(); i++) { + for(size_t j = 0; j < mates2.size(); j++) { + if(mates1[i] == mates2[j] && !gQuiet) { + cerr << "Warning: Same mate file \"" << mates1[i].c_str() << "\" appears as argument to both -1 and -2" << endl; + } + } + } + } + // If both -s and -u are used, we need to adjust qUpto accordingly + // since it uses rdid to know if we've reached the -u limit (and + // rdids are all shifted up by skipReads characters) + if(qUpto + skipReads > qUpto) { + qUpto += skipReads; + } + if(useShmem && useMm && !gQuiet) { + cerr << "Warning: --shmem overrides --mm..." << endl; + useMm = false; + } + if(gGapBarrier < 1) { + cerr << "Warning: --gbar was set less than 1 (=" << gGapBarrier + << "); setting to 1 instead" << endl; + gGapBarrier = 1; + } + if(multiseedMms >= multiseedLen) { + assert_gt(multiseedLen, 0); + cerr << "Warning: seed mismatches (" << multiseedMms + << ") is less than seed length (" << multiseedLen + << "); setting mismatches to " << (multiseedMms-1) + << " instead" << endl; + multiseedMms = multiseedLen-1; + } + sam_print_zm = sam_print_zm && bowtie2p5; +#ifndef NDEBUG + if(!gQuiet) { + cerr << "Warning: Running in debug mode. Please use debug mode only " + << "for diagnosing errors, and not for typical use of HISAT2." + << endl; + } +#endif +} + +static const char *argv0 = NULL; + +/// Create a PatternSourcePerThread for the current thread according +/// to the global params and return a pointer to it +static PatternSourcePerThreadFactory* +createPatsrcFactory(PairedPatternSource& _patsrc, int tid) { + PatternSourcePerThreadFactory *patsrcFact; + patsrcFact = new WrappedPatternSourcePerThreadFactory(_patsrc); + assert(patsrcFact != NULL); + return patsrcFact; +} + +#define PTHREAD_ATTRS (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED) + +typedef TIndexOffU index_t; +typedef uint16_t local_index_t; +static PairedPatternSource* multiseed_patsrc; +static HGFM* multiseed_gfm; +static RFM* multiseed_rgfm; +//static HGFM* multiseed_gfms[2]; +//static RFM* multiseed_rgfms[2]; +static Scoring* multiseed_sc; +static BitPairReference* multiseed_refs; +static BitPairReference* multiseed_rrefs; +//static BitPairReference* multiseed_refss[2]; +//static BitPairReference* multiseed_rrefss[2]; +static AlnSink* multiseed_msink; +static OutFileBuf* multiseed_metricsOfb; +static SpliceSiteDB* ssdb; +static ALTDB* altdb; +static RepeatDB* repeatdb; +static ALTDB* raltdb; + +static ALTDB *altdbs_3N[2]; +static RepeatDB *repeatdbs_3N[2]; +static ALTDB *raltdbs_3N[2]; +static TranscriptomePolicy* multiseed_tpol; +static GraphPolicy* gpol; + + +class reference3N { +public: + const HGFM* multiseed_gfm[2]; + const RFM* multiseed_rgfm[2]; + const BitPairReference* multiseed_rrefs[2]; + + reference3N() { + + } + + void load(EList* >& gfms_3N, + RFM* rgfms_3N[2], + BitPairReference* rrefss[2]) { + for (int i = 0; i < 2; i++) { + multiseed_gfm[i] = gfms_3N[i]; + multiseed_rgfm[i] = rgfms_3N[i]; + multiseed_rrefs[i] = rrefss[i]; + } + } +}; + +reference3N ref3N; + +/** + * Metrics for measuring the work done by the outer read alignment + * loop. + */ +struct OuterLoopMetrics { + + OuterLoopMetrics() { + reset(); + } + + /** + * Set all counters to 0. + */ + void reset() { + reads = bases = srreads = srbases = + freads = fbases = ureads = ubases = 0; + } + + /** + * Sum the counters in m in with the conters in this object. This + * is the only safe way to update an OuterLoopMetrics that's shared + * by multiple threads. + */ + void merge( + const OuterLoopMetrics& m, + bool getLock = false) + { + ThreadSafe ts(&mutex_m, getLock); + reads += m.reads; + bases += m.bases; + srreads += m.srreads; + srbases += m.srbases; + freads += m.freads; + fbases += m.fbases; + ureads += m.ureads; + ubases += m.ubases; + } + + uint64_t reads; // total reads + uint64_t bases; // total bases + uint64_t srreads; // same-read reads + uint64_t srbases; // same-read bases + uint64_t freads; // filtered reads + uint64_t fbases; // filtered bases + uint64_t ureads; // unfiltered reads + uint64_t ubases; // unfiltered bases + MUTEX_T mutex_m; +}; + +/** + * Collection of all relevant performance metrics when aligning in + * multiseed mode. + */ +struct PerfMetrics { + + PerfMetrics() : first(true) { reset(); } + + /** + * Set all counters to 0. + */ + void reset() { + olm.reset(); + sdm.reset(); + wlm.reset(); + swmSeed.reset(); + swmMate.reset(); + rpm.reset(); + dpSse8Seed.reset(); // 8-bit SSE seed extensions + dpSse8Mate.reset(); // 8-bit SSE mate finds + dpSse16Seed.reset(); // 16-bit SSE seed extensions + dpSse16Mate.reset(); // 16-bit SSE mate finds + nbtfiltst = 0; + nbtfiltsc = 0; + nbtfiltdo = 0; + + olmu.reset(); + sdmu.reset(); + wlmu.reset(); + swmuSeed.reset(); + swmuMate.reset(); + rpmu.reset(); + dpSse8uSeed.reset(); // 8-bit SSE seed extensions + dpSse8uMate.reset(); // 8-bit SSE mate finds + dpSse16uSeed.reset(); // 16-bit SSE seed extensions + dpSse16uMate.reset(); // 16-bit SSE mate finds + nbtfiltst_u = 0; + nbtfiltsc_u = 0; + nbtfiltdo_u = 0; + + him.reset(); + } + + /** + * Merge a set of specific metrics into this object. + */ + void merge( + const OuterLoopMetrics *ol, + const SeedSearchMetrics *sd, + const WalkMetrics *wl, + const SwMetrics *swSeed, + const SwMetrics *swMate, + const ReportingMetrics *rm, + const SSEMetrics *dpSse8Ex, + const SSEMetrics *dpSse8Ma, + const SSEMetrics *dpSse16Ex, + const SSEMetrics *dpSse16Ma, + uint64_t nbtfiltst_, + uint64_t nbtfiltsc_, + uint64_t nbtfiltdo_, + const HIMetrics *hi, + bool getLock) + { + ThreadSafe ts(&mutex_m, getLock); + if(ol != NULL) { + olmu.merge(*ol, false); + } + if(sd != NULL) { + sdmu.merge(*sd, false); + } + if(wl != NULL) { + wlmu.merge(*wl, false); + } + if(swSeed != NULL) { + swmuSeed.merge(*swSeed, false); + } + if(swMate != NULL) { + swmuMate.merge(*swMate, false); + } + if(rm != NULL) { + rpmu.merge(*rm, false); + } + if(dpSse8Ex != NULL) { + dpSse8uSeed.merge(*dpSse8Ex, false); + } + if(dpSse8Ma != NULL) { + dpSse8uMate.merge(*dpSse8Ma, false); + } + if(dpSse16Ex != NULL) { + dpSse16uSeed.merge(*dpSse16Ex, false); + } + if(dpSse16Ma != NULL) { + dpSse16uMate.merge(*dpSse16Ma, false); + } + nbtfiltst_u += nbtfiltst_; + nbtfiltsc_u += nbtfiltsc_; + nbtfiltdo_u += nbtfiltdo_; + if(hi != NULL) { + him.merge(*hi, false); + } + } + + /** + * Reports a matrix of results, incl. column labels, to an OutFileBuf. + * Optionally also sends results to stderr (unbuffered). Can optionally + * print a per-read record with the read name at the beginning. + */ + void reportInterval( + OutFileBuf* o, // file to send output to + bool metricsStderr, // additionally output to stderr? + bool total, // true -> report total, otherwise incremental + bool sync, // synchronize output + const BTString *name) // non-NULL name pointer if is per-read record + { + ThreadSafe ts(&mutex_m, sync); + ostringstream stderrSs; + time_t curtime = time(0); + char buf[1024]; + if(first) { + const char *str = + /* 1 */ "Time" "\t" + /* 2 */ "Read" "\t" + /* 3 */ "Base" "\t" + /* 4 */ "SameRead" "\t" + /* 5 */ "SameReadBase" "\t" + /* 6 */ "UnfilteredRead" "\t" + /* 7 */ "UnfilteredBase" "\t" + + /* 8 */ "Paired" "\t" + /* 9 */ "Unpaired" "\t" + /* 10 */ "AlConUni" "\t" + /* 11 */ "AlConRep" "\t" + /* 12 */ "AlConFail" "\t" + /* 13 */ "AlDis" "\t" + /* 14 */ "AlConFailUni" "\t" + /* 15 */ "AlConFailRep" "\t" + /* 16 */ "AlConFailFail" "\t" + /* 17 */ "AlConRepUni" "\t" + /* 18 */ "AlConRepRep" "\t" + /* 19 */ "AlConRepFail" "\t" + /* 20 */ "AlUnpUni" "\t" + /* 21 */ "AlUnpRep" "\t" + /* 22 */ "AlUnpFail" "\t" + + /* 23 */ "SeedSearch" "\t" + /* 24 */ "IntraSCacheHit" "\t" + /* 25 */ "InterSCacheHit" "\t" + /* 26 */ "OutOfMemory" "\t" + /* 27 */ "AlBWOp" "\t" + /* 28 */ "AlBWBranch" "\t" + /* 29 */ "ResBWOp" "\t" + /* 30 */ "ResBWBranch" "\t" + /* 31 */ "ResResolve" "\t" + /* 34 */ "ResReport" "\t" + /* 35 */ "RedundantSHit" "\t" + + /* 36 */ "BestMinEdit0" "\t" + /* 37 */ "BestMinEdit1" "\t" + /* 38 */ "BestMinEdit2" "\t" + + /* 39 */ "ExactAttempts" "\t" + /* 40 */ "ExactSucc" "\t" + /* 41 */ "ExactRanges" "\t" + /* 42 */ "ExactRows" "\t" + /* 43 */ "ExactOOMs" "\t" + + /* 44 */ "1mmAttempts" "\t" + /* 45 */ "1mmSucc" "\t" + /* 46 */ "1mmRanges" "\t" + /* 47 */ "1mmRows" "\t" + /* 48 */ "1mmOOMs" "\t" + + /* 49 */ "UngappedSucc" "\t" + /* 50 */ "UngappedFail" "\t" + /* 51 */ "UngappedNoDec" "\t" + + /* 52 */ "DPExLt10Gaps" "\t" + /* 53 */ "DPExLt5Gaps" "\t" + /* 54 */ "DPExLt3Gaps" "\t" + + /* 55 */ "DPMateLt10Gaps" "\t" + /* 56 */ "DPMateLt5Gaps" "\t" + /* 57 */ "DPMateLt3Gaps" "\t" + + /* 58 */ "DP16ExDps" "\t" + /* 59 */ "DP16ExDpSat" "\t" + /* 60 */ "DP16ExDpFail" "\t" + /* 61 */ "DP16ExDpSucc" "\t" + /* 62 */ "DP16ExCol" "\t" + /* 63 */ "DP16ExCell" "\t" + /* 64 */ "DP16ExInner" "\t" + /* 65 */ "DP16ExFixup" "\t" + /* 66 */ "DP16ExGathSol" "\t" + /* 67 */ "DP16ExBt" "\t" + /* 68 */ "DP16ExBtFail" "\t" + /* 69 */ "DP16ExBtSucc" "\t" + /* 70 */ "DP16ExBtCell" "\t" + /* 71 */ "DP16ExCoreRej" "\t" + /* 72 */ "DP16ExNRej" "\t" + + /* 73 */ "DP8ExDps" "\t" + /* 74 */ "DP8ExDpSat" "\t" + /* 75 */ "DP8ExDpFail" "\t" + /* 76 */ "DP8ExDpSucc" "\t" + /* 77 */ "DP8ExCol" "\t" + /* 78 */ "DP8ExCell" "\t" + /* 79 */ "DP8ExInner" "\t" + /* 80 */ "DP8ExFixup" "\t" + /* 81 */ "DP8ExGathSol" "\t" + /* 82 */ "DP8ExBt" "\t" + /* 83 */ "DP8ExBtFail" "\t" + /* 84 */ "DP8ExBtSucc" "\t" + /* 85 */ "DP8ExBtCell" "\t" + /* 86 */ "DP8ExCoreRej" "\t" + /* 87 */ "DP8ExNRej" "\t" + + /* 88 */ "DP16MateDps" "\t" + /* 89 */ "DP16MateDpSat" "\t" + /* 90 */ "DP16MateDpFail" "\t" + /* 91 */ "DP16MateDpSucc" "\t" + /* 92 */ "DP16MateCol" "\t" + /* 93 */ "DP16MateCell" "\t" + /* 94 */ "DP16MateInner" "\t" + /* 95 */ "DP16MateFixup" "\t" + /* 96 */ "DP16MateGathSol" "\t" + /* 97 */ "DP16MateBt" "\t" + /* 98 */ "DP16MateBtFail" "\t" + /* 99 */ "DP16MateBtSucc" "\t" + /* 100 */ "DP16MateBtCell" "\t" + /* 101 */ "DP16MateCoreRej" "\t" + /* 102 */ "DP16MateNRej" "\t" + + /* 103 */ "DP8MateDps" "\t" + /* 104 */ "DP8MateDpSat" "\t" + /* 105 */ "DP8MateDpFail" "\t" + /* 106 */ "DP8MateDpSucc" "\t" + /* 107 */ "DP8MateCol" "\t" + /* 108 */ "DP8MateCell" "\t" + /* 109 */ "DP8MateInner" "\t" + /* 110 */ "DP8MateFixup" "\t" + /* 111 */ "DP8MateGathSol" "\t" + /* 112 */ "DP8MateBt" "\t" + /* 113 */ "DP8MateBtFail" "\t" + /* 114 */ "DP8MateBtSucc" "\t" + /* 115 */ "DP8MateBtCell" "\t" + /* 116 */ "DP8MateCoreRej" "\t" + /* 117 */ "DP8MateNRej" "\t" + + /* 118 */ "DPBtFiltStart" "\t" + /* 119 */ "DPBtFiltScore" "\t" + /* 120 */ "DpBtFiltDom" "\t" + + /* 121 */ "MemPeak" "\t" + /* 122 */ "UncatMemPeak" "\t" // 0 + /* 123 */ "EbwtMemPeak" "\t" // EBWT_CAT + /* 124 */ "CacheMemPeak" "\t" // CA_CAT + /* 125 */ "ResolveMemPeak" "\t" // GW_CAT + /* 126 */ "AlignMemPeak" "\t" // AL_CAT + /* 127 */ "DPMemPeak" "\t" // DP_CAT + /* 128 */ "MiscMemPeak" "\t" // MISC_CAT + /* 129 */ "DebugMemPeak" "\t" // DEBUG_CAT + + /* 130 */ "LocalSearch" "\t" + /* 131 */ "AnchorSearch" "\t" + /* 132 */ "LocalIndexSearch" "\t" + /* 133 */ "LocalExtSearch" "\t" + /* 134 */ "LocalSearchRecur" "\t" + /* 135 */ "GlobalGenomeCoords" "\t" + /* 136 */ "LocalGenomeCoords" "\t" + + + "\n"; + + if(name != NULL) { + if(o != NULL) o->writeChars("Name\t"); + if(metricsStderr) stderrSs << "Name\t"; + } + + if(o != NULL) o->writeChars(str); + if(metricsStderr) stderrSs << str; + first = false; + } + + if(total) mergeIncrementals(); + + // 0. Read name, if needed + if(name != NULL) { + if(o != NULL) { + o->writeChars(name->toZBuf()); + o->write('\t'); + } + if(metricsStderr) { + stderrSs << (*name) << '\t'; + } + } + + // 1. Current time in secs + itoa10(curtime, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const OuterLoopMetrics& ol = total ? olm : olmu; + + // 2. Reads + itoa10(ol.reads, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 3. Bases + itoa10(ol.bases, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 4. Same-read reads + itoa10(ol.srreads, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 5. Same-read bases + itoa10(ol.srbases, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 6. Unfiltered reads + itoa10(ol.ureads, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 7. Unfiltered bases + itoa10(ol.ubases, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const ReportingMetrics& rp = total ? rpm : rpmu; + + // 8. Paired reads + itoa10(rp.npaired, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 9. Unpaired reads + itoa10(rp.nunpaired, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 10. Pairs with unique concordant alignments + itoa10(rp.nconcord_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 11. Pairs with repetitive concordant alignments + itoa10(rp.nconcord_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 12. Pairs with 0 concordant alignments + itoa10(rp.nconcord_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 13. Pairs with 1 discordant alignment + itoa10(rp.ndiscord, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 14. Mates from unaligned pairs that align uniquely + itoa10(rp.nunp_0_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 15. Mates from unaligned pairs that align repetitively + itoa10(rp.nunp_0_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 16. Mates from unaligned pairs that fail to align + itoa10(rp.nunp_0_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 17. Mates from repetitive pairs that align uniquely + itoa10(rp.nunp_rep_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 18. Mates from repetitive pairs that align repetitively + itoa10(rp.nunp_rep_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 19. Mates from repetitive pairs that fail to align + itoa10(rp.nunp_rep_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 20. Unpaired reads that align uniquely + itoa10(rp.nunp_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 21. Unpaired reads that align repetitively + itoa10(rp.nunp_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 22. Unpaired reads that fail to align + itoa10(rp.nunp_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SeedSearchMetrics& sd = total ? sdm : sdmu; + + // 23. Seed searches + itoa10(sd.seedsearch, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 24. Hits in 'current' cache + itoa10(sd.intrahit, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 25. Hits in 'local' cache + itoa10(sd.interhit, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 26. Out of memory + itoa10(sd.ooms, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 27. Burrows-Wheeler ops in aligner + itoa10(sd.bwops, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 28. Burrows-Wheeler branches (edits) in aligner + itoa10(sd.bweds, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const WalkMetrics& wl = total ? wlm : wlmu; + + // 29. Burrows-Wheeler ops in resolver + itoa10(wl.bwops, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 30. Burrows-Wheeler branches in resolver + itoa10(wl.branches, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 31. Burrows-Wheeler offset resolutions + itoa10(wl.resolves, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 34. Offset reports + itoa10(wl.reports, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 35. Redundant seed hit + itoa10(total ? swmSeed.rshit : swmuSeed.rshit, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 36. # times the best (out of fw/rc) minimum # edits was 0 + itoa10(total ? sdm.bestmin0 : sdmu.bestmin0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 37. # times the best (out of fw/rc) minimum # edits was 1 + itoa10(total ? sdm.bestmin1 : sdmu.bestmin1, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 38. # times the best (out of fw/rc) minimum # edits was 2 + itoa10(total ? sdm.bestmin2 : sdmu.bestmin2, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 39. Exact aligner attempts + itoa10(total ? swmSeed.exatts : swmuSeed.exatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 40. Exact aligner successes + itoa10(total ? swmSeed.exsucc : swmuSeed.exsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 41. Exact aligner ranges + itoa10(total ? swmSeed.exranges : swmuSeed.exranges, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 42. Exact aligner rows + itoa10(total ? swmSeed.exrows : swmuSeed.exrows, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 43. Exact aligner OOMs + itoa10(total ? swmSeed.exooms : swmuSeed.exooms, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 44. 1mm aligner attempts + itoa10(total ? swmSeed.mm1atts : swmuSeed.mm1atts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 45. 1mm aligner successes + itoa10(total ? swmSeed.mm1succ : swmuSeed.mm1succ, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 46. 1mm aligner ranges + itoa10(total ? swmSeed.mm1ranges : swmuSeed.mm1ranges, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 47. 1mm aligner rows + itoa10(total ? swmSeed.mm1rows : swmuSeed.mm1rows, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 48. 1mm aligner OOMs + itoa10(total ? swmSeed.mm1ooms : swmuSeed.mm1ooms, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 49 Ungapped aligner success + itoa10(total ? swmSeed.ungapsucc : swmuSeed.ungapsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 50. Ungapped aligner fail + itoa10(total ? swmSeed.ungapfail : swmuSeed.ungapfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 51. Ungapped aligner no decision + itoa10(total ? swmSeed.ungapnodec : swmuSeed.ungapnodec, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 52. # seed-extend DPs with < 10 gaps + itoa10(total ? swmSeed.sws10 : swmuSeed.sws10, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 53. # seed-extend DPs with < 5 gaps + itoa10(total ? swmSeed.sws5 : swmuSeed.sws5, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 54. # seed-extend DPs with < 3 gaps + itoa10(total ? swmSeed.sws3 : swmuSeed.sws3, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 55. # seed-extend DPs with < 10 gaps + itoa10(total ? swmMate.sws10 : swmuMate.sws10, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 56. # seed-extend DPs with < 5 gaps + itoa10(total ? swmMate.sws5 : swmuMate.sws5, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 57. # seed-extend DPs with < 3 gaps + itoa10(total ? swmMate.sws3 : swmuMate.sws3, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse16s = total ? dpSse16Seed : dpSse16uSeed; + + // 58. 16-bit SSE seed-extend DPs tried + itoa10(dpSse16s.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 59. 16-bit SSE seed-extend DPs saturated + itoa10(dpSse16s.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 60. 16-bit SSE seed-extend DPs failed + itoa10(dpSse16s.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 61. 16-bit SSE seed-extend DPs succeeded + itoa10(dpSse16s.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 62. 16-bit SSE seed-extend DP columns completed + itoa10(dpSse16s.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 63. 16-bit SSE seed-extend DP cells completed + itoa10(dpSse16s.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 64. 16-bit SSE seed-extend DP inner loop iters completed + itoa10(dpSse16s.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 65. 16-bit SSE seed-extend DP fixup loop iters completed + itoa10(dpSse16s.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 66. 16-bit SSE seed-extend DP gather, cells with potential solutions + itoa10(dpSse16s.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 67. 16-bit SSE seed-extend DP backtrace attempts + itoa10(dpSse16s.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 68. 16-bit SSE seed-extend DP failed backtrace attempts + itoa10(dpSse16s.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 69. 16-bit SSE seed-extend DP succesful backtrace attempts + itoa10(dpSse16s.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 70. 16-bit SSE seed-extend DP backtrace cells + itoa10(dpSse16s.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 71. 16-bit SSE seed-extend DP core-diag rejections + itoa10(dpSse16s.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 72. 16-bit SSE seed-extend DP N rejections + itoa10(dpSse16s.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse8s = total ? dpSse8Seed : dpSse8uSeed; + + // 73. 8-bit SSE seed-extend DPs tried + itoa10(dpSse8s.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 74. 8-bit SSE seed-extend DPs saturated + itoa10(dpSse8s.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 75. 8-bit SSE seed-extend DPs failed + itoa10(dpSse8s.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 76. 8-bit SSE seed-extend DPs succeeded + itoa10(dpSse8s.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 77. 8-bit SSE seed-extend DP columns completed + itoa10(dpSse8s.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 78. 8-bit SSE seed-extend DP cells completed + itoa10(dpSse8s.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 79. 8-bit SSE seed-extend DP inner loop iters completed + itoa10(dpSse8s.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 80. 8-bit SSE seed-extend DP fixup loop iters completed + itoa10(dpSse8s.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 81. 16-bit SSE seed-extend DP gather, cells with potential solutions + itoa10(dpSse8s.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 82. 16-bit SSE seed-extend DP backtrace attempts + itoa10(dpSse8s.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 83. 16-bit SSE seed-extend DP failed backtrace attempts + itoa10(dpSse8s.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 84. 16-bit SSE seed-extend DP succesful backtrace attempts + itoa10(dpSse8s.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 85. 16-bit SSE seed-extend DP backtrace cells + itoa10(dpSse8s.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 86. 16-bit SSE seed-extend DP core-diag rejections + itoa10(dpSse8s.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 87. 16-bit SSE seed-extend DP N rejections + itoa10(dpSse8s.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse16m = total ? dpSse16Mate : dpSse16uMate; + + // 88. 16-bit SSE mate-finding DPs tried + itoa10(dpSse16m.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 89. 16-bit SSE mate-finding DPs saturated + itoa10(dpSse16m.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 90. 16-bit SSE mate-finding DPs failed + itoa10(dpSse16m.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 91. 16-bit SSE mate-finding DPs succeeded + itoa10(dpSse16m.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 92. 16-bit SSE mate-finding DP columns completed + itoa10(dpSse16m.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 93. 16-bit SSE mate-finding DP cells completed + itoa10(dpSse16m.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 94. 16-bit SSE mate-finding DP inner loop iters completed + itoa10(dpSse16m.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 95. 16-bit SSE mate-finding DP fixup loop iters completed + itoa10(dpSse16m.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 96. 16-bit SSE mate-finding DP gather, cells with potential solutions + itoa10(dpSse16m.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 97. 16-bit SSE mate-finding DP backtrace attempts + itoa10(dpSse16m.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 98. 16-bit SSE mate-finding DP failed backtrace attempts + itoa10(dpSse16m.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 99. 16-bit SSE mate-finding DP succesful backtrace attempts + itoa10(dpSse16m.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 100. 16-bit SSE mate-finding DP backtrace cells + itoa10(dpSse16m.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 101. 16-bit SSE mate-finding DP core-diag rejections + itoa10(dpSse16m.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 102. 16-bit SSE mate-finding DP N rejections + itoa10(dpSse16m.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse8m = total ? dpSse8Mate : dpSse8uMate; + + // 103. 8-bit SSE mate-finding DPs tried + itoa10(dpSse8m.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 104. 8-bit SSE mate-finding DPs saturated + itoa10(dpSse8m.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 105. 8-bit SSE mate-finding DPs failed + itoa10(dpSse8m.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 106. 8-bit SSE mate-finding DPs succeeded + itoa10(dpSse8m.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 107. 8-bit SSE mate-finding DP columns completed + itoa10(dpSse8m.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 108. 8-bit SSE mate-finding DP cells completed + itoa10(dpSse8m.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 109. 8-bit SSE mate-finding DP inner loop iters completed + itoa10(dpSse8m.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 110. 8-bit SSE mate-finding DP fixup loop iters completed + itoa10(dpSse8m.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 111. 16-bit SSE mate-finding DP gather, cells with potential solutions + itoa10(dpSse8m.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 112. 16-bit SSE mate-finding DP backtrace attempts + itoa10(dpSse8m.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 113. 16-bit SSE mate-finding DP failed backtrace attempts + itoa10(dpSse8m.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 114. 16-bit SSE mate-finding DP succesful backtrace attempts + itoa10(dpSse8m.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 115. 16-bit SSE mate-finding DP backtrace cells + itoa10(dpSse8m.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 116. 16-bit SSE mate-finding DP core rejections + itoa10(dpSse8m.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 117. 16-bit SSE mate-finding N rejections + itoa10(dpSse8m.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 118. Backtrace candidates filtered due to starting cell + itoa10(total ? nbtfiltst : nbtfiltst_u, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 119. Backtrace candidates filtered due to low score + itoa10(total ? nbtfiltsc : nbtfiltsc_u, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 120. Backtrace candidates filtered due to domination + itoa10(total ? nbtfiltdo : nbtfiltdo_u, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 121. Overall memory peak + itoa10(gMemTally.peak() >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 122. Uncategorized memory peak + itoa10(gMemTally.peak(0) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 123. Ebwt memory peak + itoa10(gMemTally.peak(EBWT_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 124. Cache memory peak + itoa10(gMemTally.peak(CA_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 125. Resolver memory peak + itoa10(gMemTally.peak(GW_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 126. Seed aligner memory peak + itoa10(gMemTally.peak(AL_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 127. Dynamic programming aligner memory peak + itoa10(gMemTally.peak(DP_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 128. Miscellaneous memory peak + itoa10(gMemTally.peak(MISC_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 129. Debug memory peak + itoa10(gMemTally.peak(DEBUG_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 130 + itoa10(him.localatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 131 + itoa10(him.anchoratts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 132 + itoa10(him.localindexatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 133 + itoa10(him.localextatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 134 + itoa10(him.localsearchrecur, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 135 + itoa10(him.globalgenomecoords, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 136 + itoa10(him.localgenomecoords, buf); + if(metricsStderr) stderrSs << buf; + if(o != NULL) { o->writeChars(buf); } + + if(o != NULL) { o->write('\n'); } + if(metricsStderr) cerr << stderrSs.str().c_str() << endl; + if(!total) mergeIncrementals(); + } + + void mergeIncrementals() { + olm.merge(olmu, false); + sdm.merge(sdmu, false); + wlm.merge(wlmu, false); + swmSeed.merge(swmuSeed, false); + swmMate.merge(swmuMate, false); + dpSse8Seed.merge(dpSse8uSeed, false); + dpSse8Mate.merge(dpSse8uMate, false); + dpSse16Seed.merge(dpSse16uSeed, false); + dpSse16Mate.merge(dpSse16uMate, false); + nbtfiltst_u += nbtfiltst; + nbtfiltsc_u += nbtfiltsc; + nbtfiltdo_u += nbtfiltdo; + + olmu.reset(); + sdmu.reset(); + wlmu.reset(); + swmuSeed.reset(); + swmuMate.reset(); + rpmu.reset(); + dpSse8uSeed.reset(); + dpSse8uMate.reset(); + dpSse16uSeed.reset(); + dpSse16uMate.reset(); + nbtfiltst_u = 0; + nbtfiltsc_u = 0; + nbtfiltdo_u = 0; + } + + // Total over the whole job + OuterLoopMetrics olm; // overall metrics + SeedSearchMetrics sdm; // metrics related to seed alignment + WalkMetrics wlm; // metrics related to walking left (i.e. resolving reference offsets) + SwMetrics swmSeed; // metrics related to DP seed-extend alignment + SwMetrics swmMate; // metrics related to DP mate-finding alignment + ReportingMetrics rpm; // metrics related to reporting + SSEMetrics dpSse8Seed; // 8-bit SSE seed extensions + SSEMetrics dpSse8Mate; // 8-bit SSE mate finds + SSEMetrics dpSse16Seed; // 16-bit SSE seed extensions + SSEMetrics dpSse16Mate; // 16-bit SSE mate finds + uint64_t nbtfiltst; + uint64_t nbtfiltsc; + uint64_t nbtfiltdo; + + // Just since the last update + OuterLoopMetrics olmu; // overall metrics + SeedSearchMetrics sdmu; // metrics related to seed alignment + WalkMetrics wlmu; // metrics related to walking left (i.e. resolving reference offsets) + SwMetrics swmuSeed; // metrics related to DP seed-extend alignment + SwMetrics swmuMate; // metrics related to DP mate-finding alignment + ReportingMetrics rpmu; // metrics related to reporting + SSEMetrics dpSse8uSeed; // 8-bit SSE seed extensions + SSEMetrics dpSse8uMate; // 8-bit SSE mate finds + SSEMetrics dpSse16uSeed; // 16-bit SSE seed extensions + SSEMetrics dpSse16uMate; // 16-bit SSE mate finds + uint64_t nbtfiltst_u; + uint64_t nbtfiltsc_u; + uint64_t nbtfiltdo_u; + + // + HIMetrics him; + + MUTEX_T mutex_m; // lock for when one ob + bool first; // yet to print first line? + time_t lastElapsed; // used in reportInterval to measure time since last call +}; + +static PerfMetrics metrics; + +// Cyclic rotations +#define ROTL(n, x) (((x) << (n)) | ((x) >> (32-n))) +#define ROTR(n, x) (((x) >> (n)) | ((x) << (32-n))) + +static inline void printMmsSkipMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1, + int seedmms) +{ + ostringstream os; + if(paired) { + os << "Warning: skipping mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because length (" << (mate1 ? ps.bufa().patFw.length() : ps.bufb().patFw.length()) + << ") <= # seed mismatches (" << seedmms << ")" << endl; + } else { + os << "Warning: skipping read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because length (" << (mate1 ? ps.bufa().patFw.length() : ps.bufb().patFw.length()) + << ") <= # seed mismatches (" << seedmms << ")" << endl; + } + cerr << os.str().c_str(); +} + +static inline void printLenSkipMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1) +{ + ostringstream os; + if(paired) { + os << "Warning: skipping mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because it was < 2 characters long" << endl; + } else { + os << "Warning: skipping read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because it was < 2 characters long" << endl; + } + cerr << os.str().c_str(); +} + +static inline void printLocalScoreMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1) +{ + ostringstream os; + if(paired) { + os << "Warning: minimum score function gave negative number in " + << "--local mode for mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } else { + os << "Warning: minimum score function gave negative number in " + << "--local mode for read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } + cerr << os.str().c_str(); +} + +static inline void printEEScoreMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1) +{ + ostringstream os; + if(paired) { + os << "Warning: minimum score function gave positive number in " + << "--end-to-end mode for mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } else { + os << "Warning: minimum score function gave positive number in " + << "--end-to-end mode for read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } + cerr << os.str().c_str(); +} + + +#define MERGE_METRICS(met, sync) { \ + msink.mergeMetrics(rpm); \ + met.merge( \ + &olm, \ + &sdm, \ + &wlm, \ + &swmSeed, \ + &swmMate, \ + &rpm, \ + &sseU8ExtendMet, \ + &sseU8MateMet, \ + &sseI16ExtendMet, \ + &sseI16MateMet, \ + nbtfiltst, \ + nbtfiltsc, \ + nbtfiltdo, \ + &him, \ + sync); \ + olm.reset(); \ + sdm.reset(); \ + wlm.reset(); \ + swmSeed.reset(); \ + swmMate.reset(); \ + rpm.reset(); \ + sseU8ExtendMet.reset(); \ + sseU8MateMet.reset(); \ + sseI16ExtendMet.reset(); \ + sseI16MateMet.reset(); \ + him.reset(); \ +} + +#define MERGE_SW(x) { \ + x.merge( \ + sseU8ExtendMet, \ + sseU8MateMet, \ + sseI16ExtendMet, \ + sseI16MateMet, \ + nbtfiltst, \ + nbtfiltsc, \ + nbtfiltdo); \ + x.resetCounters(); \ +} + + + + + +/** + * Called once per thread. Sets up per-thread pointers to the shared global + * data structures, creates per-thread structures, then enters the alignment + * loop. The general flow of the alignment loop is: + * + * - If it's been a while and we're the master thread, report some alignment + * metrics + * - Get the next read/pair + * - Check if this read/pair is identical to the previous + * + If identical, check whether we can skip any or all alignment stages. If + * we can skip all stages, report the result immediately and move to next + * read/pair + * + If not identical, continue + * - + */ +static void multiseedSearchWorker_hisat2(void *vp) { + int tid = *((int*)vp); + + if (threeN) { + assert(ref3N.multiseed_gfm[0] != NULL); + assert(ref3N.multiseed_gfm[1] != NULL); + } else { + assert(multiseed_gfm != NULL); + } + + assert(multiseedMms == 0); + + // for regular Hisat2 + PairedPatternSource& patsrc = *multiseed_patsrc; + const HGFM& gfm = *multiseed_gfm; + const RFM* rgfm = multiseed_rgfm; + const Scoring& sc = *multiseed_sc; + const BitPairReference& ref = *multiseed_refs; + const BitPairReference* rref = multiseed_rrefs; + AlnSink& msink = *multiseed_msink; + OutFileBuf* metricsOfb = multiseed_metricsOfb; + + // for Hisat-3N + const HGFM* gfm_3N[2]; + const RFM* rgfm_3N[2]; + const BitPairReference* rref_3N[2]; + + for (int i = 0; i < 2; i++) { + gfm_3N[i] = ref3N.multiseed_gfm[i]; + rgfm_3N[i] = ref3N.multiseed_rgfm[i]; + rref_3N[i] = ref3N.multiseed_rrefs[i]; + } + + // Sinks: these are so that we can print tables encoding counts for + // events of interest on a per-read, per-seed, per-join, or per-SW + // level. These in turn can be used to diagnose performance + // problems, or generally characterize performance. + + //const BitPairReference& refs = *multiseed_refs; + auto_ptr patsrcFact(createPatsrcFactory(patsrc, tid)); + auto_ptr ps(patsrcFact->create()); + + // Instantiate an object for holding reporting-related parameters. + if(maxSeeds == 0) { + maxSeeds = max(5, khits * 2); + } + ReportingParams rp( + (allHits ? std::numeric_limits::max() : khits), // -k + (allHits ? std::numeric_limits::max() : maxSeeds), // --max-seeds + mhits, // -m/-M + 0, // penalty gap (not used now) + msample, // true -> -M was specified, otherwise assume -m + gReportDiscordant, // report discordang paired-end alignments? + gReportMixed, // report unpaired alignments for paired reads? + secondary, + localAlign, + bowtie2_dp, + sensitive | very_sensitive, + repeat); + + // Instantiate a mapping quality calculator + auto_ptr bmapq(new_mapq(mapqv, scoreMin, sc)); + + + // Make a per-thread wrapper for the global MHitSink object. + + AlnSinkWrap* msinkwrap; + if (threeN) { + msinkwrap = new AlnSinkWrap3N( + msink, // global sink + rp, // reporting parameters + *bmapq.get(), // MAPQ calculator + (size_t)tid, // thread id + mappingCycles, + secondary, // secondary alignments + no_spliced_alignment ? NULL : ssdb, + thread_rids_mindist); + } else { + msinkwrap = new AlnSinkWrap( + msink, // global sink + rp, // reporting parameters + *bmapq.get(), // MAPQ calculator + (size_t)tid, // thread id + secondary, // secondary alignments + no_spliced_alignment ? NULL : ssdb, + thread_rids_mindist); + } + + SplicedAligner splicedAligner(threeN? *gfm_3N[0]: gfm, + anchorStop, + thread_rids_mindist); + SwAligner sw; + OuterLoopMetrics olm; + SeedSearchMetrics sdm; + WalkMetrics wlm; + SwMetrics swmSeed, swmMate; + ReportingMetrics rpm; + RandomSource rnd, rndArb; + SSEMetrics sseU8ExtendMet; + SSEMetrics sseU8MateMet; + SSEMetrics sseI16ExtendMet; + SSEMetrics sseI16MateMet; + DescentMetrics descm; + uint64_t nbtfiltst = 0; // TODO: find a new home for these + uint64_t nbtfiltsc = 0; // TODO: find a new home for these + uint64_t nbtfiltdo = 0; // TODO: find a new home for these + HIMetrics him; + + ASSERT_ONLY(BTDnaString tmp); + + int pepolFlag; + if(gMate1fw && gMate2fw) { + pepolFlag = PE_POLICY_FF; + } else if(gMate1fw && !gMate2fw) { + pepolFlag = PE_POLICY_FR; + } else if(!gMate1fw && gMate2fw) { + pepolFlag = PE_POLICY_RF; + } else { + pepolFlag = PE_POLICY_RR; + } + assert_geq(gMaxInsert, gMinInsert); + assert_geq(gMinInsert, 0); + PairedEndPolicy pepol( + pepolFlag, + gMaxInsert, + gMinInsert, + localAlign, + gFlippedMatesOK, + gDovetailMatesOK, + gContainMatesOK, + gOlapMatesOK, + gExpandToFrag); + + PerfMetrics metricsPt; // per-thread metrics object; for read-level metrics + BTString nametmp; + + PerReadMetrics prm; + + // Used by thread with threadid == 1 to measure time elapsed + time_t iTime = time(0); + + // Keep track of whether last search was exhaustive for mates 1 and 2 + bool exhaustive[2] = { false, false }; + // Keep track of whether mates 1/2 were filtered out last time through + bool filt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out due Ns last time + bool nfilt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out due to not having + // enough characters to rise about the score threshold. + bool scfilt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out due to not having + // more characters than the number of mismatches permitted in a seed. + bool lenfilt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out by upstream qc + bool qcfilt[2] = { true, true }; + + rndArb.init((uint32_t)time(0)); + int mergei = 0; + int mergeival = 16; + while(true) { + bool success = false, done = false, paired = false; + ps->nextReadPair(success, done, paired, outType != OUTPUT_SAM); + if(!success && done) { + break; + } else if(!success) { + continue; + } + TReadId rdid = ps->rdid(); + if(nthreads > 1 && useTempSpliceSite) { + assert_gt(tid, 0); + assert_leq(tid, thread_rids.size()); + assert(thread_rids[tid - 1] == 0 || rdid > thread_rids[tid - 1]); + thread_rids[tid - 1] = (rdid > 0 ? rdid - 1 : 0); + while(true) { + uint64_t min_rdid = thread_rids[0]; + { + for(size_t i = 1; i < thread_rids.size(); i++) { + if(thread_rids[i] < min_rdid) { + min_rdid = thread_rids[i]; + } + } + } + + if(min_rdid + thread_rids_mindist < rdid) { +#if defined(_TTHREAD_WIN32_) + Sleep(0); +#elif defined(_TTHREAD_POSIX_) + sched_yield(); +#endif + } else break; + } + } + + bool sample = true; + if(arbitraryRandom) { + ps->bufa().seed = rndArb.nextU32(); + ps->bufb().seed = rndArb.nextU32(); + } + if(sampleFrac < 1.0f) { + rnd.init(ROTL(ps->bufa().seed, 2)); + sample = rnd.nextFloat() < sampleFrac; + } + if(rdid >= skipReads && rdid < qUpto && sample) { + // Align this read/pair + bool retry = true; + // + // Check if there is metrics reporting for us to do. + // + if(metricsIval > 0 && + (metricsOfb != NULL || metricsStderr) && + !metricsPerRead && + ++mergei == mergeival) + { + // Do a periodic merge. Update global metrics, in a + // synchronized manner if needed. + MERGE_METRICS(metrics, nthreads > 1); + mergei = 0; + // Check if a progress message should be printed + if(tid == 0) { + // Only thread 1 prints progress messages + time_t curTime = time(0); + if(curTime - iTime >= metricsIval) { + metrics.reportInterval(metricsOfb, metricsStderr, false, true, NULL); + iTime = curTime; + } + } + } + prm.reset(); // per-read metrics + prm.doFmString = false; + if(sam_print_xt) { + gettimeofday(&prm.tv_beg, &prm.tz_beg); + } + // Try to align this read + int mappingCycle = 0; + bool gNofw3N = false; + bool gNorc3N = false; + // for threeN (3N) mode, we need to map the read 4 times. for regular mode, only 1 time. + while(retry || mappingCycle < nMappingCycle) { + + msinkwrap->resetInit_(); + if (threeN) { + ps->changePlan3N(mappingCycle); + gNorc3N = (mappingCycle == threeN_type1conversion_FW || mappingCycle == threeN_type2conversion_FW); + gNofw3N = !gNorc3N; + } + retry = false; + assert_eq(ps->bufa().color, false); + if (!mappingCycles[mappingCycle]) + { + mappingCycle++; + continue; + } + + + olm.reads++; + bool pair = paired; + const size_t rdlen1 = ps->bufa().length(); + const size_t rdlen2 = pair ? ps->bufb().length() : 0; + olm.bases += (rdlen1 + rdlen2); + msinkwrap->nextRead( + &ps->bufa(), + pair ? &ps->bufb() : NULL, + rdid, + sc.qualitiesMatter()); + assert(msinkwrap->inited()); + size_t rdlens[2] = { rdlen1, rdlen2 }; + // Calculate the minimum valid score threshold for the read + TAlScore minsc[2], maxpen[2]; + maxpen[0] = maxpen[1] = 0; + minsc[0] = minsc[1] = std::numeric_limits::max(); + if(bwaSwLike) { + // From BWA-SW manual: "Given an l-long query, the + // threshold for a hit to be retained is + // a*max{T,c*log(l)}." We try to recreate that here. + float a = (float)sc.match(30); + float T = bwaSwLikeT, c = bwaSwLikeC; + minsc[0] = (TAlScore)max(a*T, a*c*log(rdlens[0])); + if(paired) { + minsc[1] = (TAlScore)max(a*T, a*c*log(rdlens[1])); + } + } else { + minsc[0] = scoreMin.f(rdlens[0]); + if(paired) minsc[1] = scoreMin.f(rdlens[1]); + if(localAlign) { + if(minsc[0] < 0) { + if(!gQuiet) printLocalScoreMsg(*ps, paired, true); + minsc[0] = 0; + } + if(paired && minsc[1] < 0) { + if(!gQuiet) printLocalScoreMsg(*ps, paired, false); + minsc[1] = 0; + } + } else { + if(minsc[0] > 0) { + if(!gQuiet) printEEScoreMsg(*ps, paired, true); + minsc[0] = 0; + } + if(paired && minsc[1] > 0) { + if(!gQuiet) printEEScoreMsg(*ps, paired, false); + minsc[1] = 0; + } + } + } + + // N filter; does the read have too many Ns? + size_t readns[2] = {0, 0}; + sc.nFilterPair( + &ps->bufa().patFw, + pair ? &ps->bufb().patFw : NULL, + readns[0], + readns[1], + nfilt[0], + nfilt[1]); + // Score filter; does the read enough character to rise above + // the score threshold? + scfilt[0] = sc.scoreFilter(minsc[0], rdlens[0]); + scfilt[1] = sc.scoreFilter(minsc[1], rdlens[1]); + lenfilt[0] = lenfilt[1] = true; + if(rdlens[0] <= (size_t)multiseedMms || rdlens[0] < 2) { + if(!gQuiet) printMmsSkipMsg(*ps, paired, true, multiseedMms); + lenfilt[0] = false; + } + if((rdlens[1] <= (size_t)multiseedMms || rdlens[1] < 2) && paired) { + if(!gQuiet) printMmsSkipMsg(*ps, paired, false, multiseedMms); + lenfilt[1] = false; + } + if(rdlens[0] < 2) { + if(!gQuiet) printLenSkipMsg(*ps, paired, true); + lenfilt[0] = false; + } + if(rdlens[1] < 2 && paired) { + if(!gQuiet) printLenSkipMsg(*ps, paired, false); + lenfilt[1] = false; + } + qcfilt[0] = qcfilt[1] = true; + if(qcFilter) { + qcfilt[0] = (ps->bufa().filter != '0'); + qcfilt[1] = (ps->bufb().filter != '0'); + } + filt[0] = (nfilt[0] && scfilt[0] && lenfilt[0] && qcfilt[0]); + filt[1] = (nfilt[1] && scfilt[1] && lenfilt[1] && qcfilt[1]); + prm.nFilt += (filt[0] ? 0 : 1) + (filt[1] ? 0 : 1); + Read* rds[2] = { &ps->bufa(), &ps->bufb() }; + // For each mate... + assert(msinkwrap->empty()); + //size_t minedfw[2] = { 0, 0 }; + //size_t minedrc[2] = { 0, 0 }; + // Calcualte nofw / no rc + bool nofw[2] = { false, false }; + bool norc[2] = { false, false }; + if (threeN) { + nofw[0] = paired ? (gMate1fw ? gNofw3N : gNorc3N) : gNofw3N; + norc[0] = paired ? (gMate1fw ? gNorc3N : gNofw3N) : gNorc3N; + nofw[1] = paired ? (gMate2fw ? gNofw3N : gNorc3N) : gNofw3N; + norc[1] = paired ? (gMate2fw ? gNorc3N : gNofw3N) : gNorc3N; + } else { + nofw[0] = paired ? (gMate1fw ? gNofw : gNorc) : gNofw; + norc[0] = paired ? (gMate1fw ? gNorc : gNofw) : gNorc; + nofw[1] = paired ? (gMate2fw ? gNofw : gNorc) : gNofw; + norc[1] = paired ? (gMate2fw ? gNorc : gNofw) : gNorc; + } + + // Calculate nceil + int nceil[2] = { 0, 0 }; + nceil[0] = nCeil.f((double)rdlens[0]); + nceil[0] = min(nceil[0], (int)rdlens[0]); + if(paired) { + nceil[1] = nCeil.f((double)rdlens[1]); + nceil[1] = min(nceil[1], (int)rdlens[1]); + } + exhaustive[0] = exhaustive[1] = false; + //size_t matemap[2] = { 0, 1 }; + bool pairPostFilt = filt[0] && filt[1]; + if(pairPostFilt) { + rnd.init(ps->bufa().seed ^ ps->bufb().seed); + } else { + rnd.init(ps->bufa().seed); + } + // Calculate interval length for both mates + int interval[2] = { 0, 0 }; + for(size_t mate = 0; mate < (pair ? 2:1); mate++) { + interval[mate] = msIval.f((double)rdlens[mate]); + if(filt[0] && filt[1]) { + // Boost interval length by 20% for paired-end reads + interval[mate] = (int)(interval[mate] * 1.2 + 0.5); + } + interval[mate] = max(interval[mate], 1); + } + // Calculate streak length + size_t streak[2] = { maxDpStreak, maxDpStreak }; + size_t mtStreak[2] = { maxMateStreak, maxMateStreak }; + size_t mxDp[2] = { maxDp, maxDp }; + size_t mxUg[2] = { maxUg, maxUg }; + size_t mxIter[2] = { maxIters, maxIters }; + if(allHits) { + streak[0] = streak[1] = std::numeric_limits::max(); + mtStreak[0] = mtStreak[1] = std::numeric_limits::max(); + mxDp[0] = mxDp[1] = std::numeric_limits::max(); + mxUg[0] = mxUg[1] = std::numeric_limits::max(); + mxIter[0] = mxIter[1] = std::numeric_limits::max(); + } else if(khits > 1) { + for(size_t mate = 0; mate < 2; mate++) { + streak[mate] += (khits-1) * maxStreakIncr; + mtStreak[mate] += (khits-1) * maxStreakIncr; + mxDp[mate] += (khits-1) * maxItersIncr; + mxUg[mate] += (khits-1) * maxItersIncr; + mxIter[mate] += (khits-1) * maxItersIncr; + } + } + if(filt[0] && filt[1]) { + streak[0] = (size_t)ceil((double)streak[0] / 2.0); + streak[1] = (size_t)ceil((double)streak[1] / 2.0); + assert_gt(streak[1], 0); + } + assert_gt(streak[0], 0); + // Calculate # seed rounds for each mate + size_t nrounds[2] = { nSeedRounds, nSeedRounds }; + if(filt[0] && filt[1]) { + nrounds[0] = (size_t)ceil((double)nrounds[0] / 2.0); + nrounds[1] = (size_t)ceil((double)nrounds[1] / 2.0); + assert_gt(nrounds[1], 0); + } + assert_gt(nrounds[0], 0); + // Increment counters according to what got filtered + for(size_t mate = 0; mate < (pair ? 2:1); mate++) { + if(!filt[mate]) { + // Mate was rejected by N filter + olm.freads++; // reads filtered out + olm.fbases += rdlens[mate]; // bases filtered out + } else { + //shs[mate].clear(); + //shs[mate].nextRead(mate == 0 ? ps->bufa() : ps->bufb()); + //assert(shs[mate].empty()); + olm.ureads++; // reads passing filter + olm.ubases += rdlens[mate]; // bases passing filter + } + } + //size_t eePeEeltLimit = std::numeric_limits::max(); + // Whether we're done with mate1 / mate2 + bool done[2] = { !filt[0], !filt[1] }; + // size_t nelt[2] = {0, 0}; + if(filt[0] && filt[1]) { + splicedAligner.initReads(rds, nofw, norc, minsc, maxpen); + } else if(filt[0]) { + splicedAligner.initRead(rds[0], nofw[0], norc[0], minsc[0], maxpen[0], false); + } else if(filt[1]) { + splicedAligner.initRead(rds[1], nofw[1], norc[1], minsc[1], maxpen[1], true); + } + if(filt[0] || filt[1]) { + int ret; + int threeN_index; + bool useRepeat; + + if (threeN) { + threeN_index = (mappingCycle == threeN_type1conversion_FW || mappingCycle == threeN_type2conversion_RC) ? 0 : 1; + useRepeat = paired ? (ps->bufa().length() >= 100) && (ps->bufb().length() >= 100) : + ps->bufa().length() >= 80; + } + + ret = splicedAligner.go( + sc, + pepol, + *multiseed_tpol, + *gpol, + threeN ? *gfm_3N[threeN_index] : gfm, + threeN ?(useRepeat ? rgfm_3N[threeN_index] : NULL) : rgfm, + threeN ? *altdbs_3N[threeN_index] : *altdb, + threeN ? *repeatdbs_3N[threeN_index] : *repeatdb, + threeN ? *raltdbs_3N[threeN_index] : *raltdb, + ref, + threeN ? rref_3N[threeN_index] : rref, + sw, + *ssdb, + wlm, + prm, + swmSeed, + him, + rnd, + *msinkwrap); + + MERGE_SW(sw); + // daehwan + size_t mate = 0; + + assert_gt(ret, 0); + // Clear out the exact hits so that we don't try to + // extend them again later! + if(ret == EXTEND_EXHAUSTED_CANDIDATES) { + // Not done yet + } else if(ret == EXTEND_POLICY_FULFILLED) { + // Policy is satisfied for this mate at least + if(msinkwrap->state().doneWithMate(mate == 0)) { + done[mate] = true; + } + if(msinkwrap->state().doneWithMate(mate == 1)) { + done[mate^1] = true; + } + } else if(ret == EXTEND_PERFECT_SCORE) { + // We exhausted this mode at least + done[mate] = true; + } else if(ret == EXTEND_EXCEEDED_HARD_LIMIT) { + // We exceeded a per-read limit + done[mate] = true; + } else if(ret == EXTEND_EXCEEDED_SOFT_LIMIT) { + // Not done yet + } else { + // + cerr << "Bad return value: " << ret << endl; + throw 1; + } + if(!done[mate]) { + TAlScore perfectScore = sc.perfectScore(rdlens[mate]); + if(!done[mate] && minsc[mate] == perfectScore) { + done[mate] = true; + } + } + } + + for(size_t i = 0; i < 2; i++) { + assert_leq(prm.nExIters, mxIter[i]); + assert_leq(prm.nExDps, mxDp[i]); + assert_leq(prm.nMateDps, mxDp[i]); + assert_leq(prm.nExUgs, mxUg[i]); + assert_leq(prm.nMateUgs, mxUg[i]); + assert_leq(prm.nDpFail, streak[i]); + assert_leq(prm.nUgFail, streak[i]); + assert_leq(prm.nEeFail, streak[i]); + } + + msinkwrap->finishRead( + NULL, + NULL, + exhaustive[0], // exhausted seed hits for mate 1? + exhaustive[1], // exhausted seed hits for mate 2? + nfilt[0], + nfilt[1], + scfilt[0], + scfilt[1], + lenfilt[0], + lenfilt[1], + qcfilt[0], + qcfilt[1], + sortByScore, // prioritize by alignment score + rnd, // pseudo-random generator + rpm, // reporting metrics + prm, // per-read metrics + sc, // scoring scheme + !seedSumm, // suppress seed summaries? + seedSumm, //rdid suppress alignments? + templateLenAdjustment); + mappingCycle++; + } + + + } // if(rdid >= skipReads && rdid < qUpto) + else if(rdid >= qUpto) { + break; + } + if(metricsPerRead) { + MERGE_METRICS(metricsPt, nthreads > 1); + nametmp = ps->bufa().name; + metricsPt.reportInterval( + metricsOfb, metricsStderr, true, true, &nametmp); + metricsPt.reset(); + } + } // while(true) + + // One last metrics merge + MERGE_METRICS(metrics, nthreads > 1); + delete msinkwrap; + return; +} + +/** + * Called once per alignment job. Sets up global pointers to the + * shared global data structures, creates per-thread structures, then + * enters the search loop. + */ +static void multiseedSearch( + Scoring& sc, + TranscriptomePolicy& tpol, + GraphPolicy& gp, + PairedPatternSource& patsrc, // pattern source + AlnSink& msink, // hit sink + EList* > gfms_3N, // 3N index of original text + RFM* rgfms_3N[2], // 3N index of repeat sequences + BitPairReference* rrefss[2], // 3N repeat reference + HGFM* gfm, // index of original text + RFM* rgfm, // index of repeat sequences + BitPairReference* refs, // base reference + BitPairReference* rrefs, // repeat reference + OutFileBuf *metricsOfb) +{ + multiseed_patsrc = &patsrc; + multiseed_msink = &msink; + multiseed_sc = ≻ + multiseed_tpol = &tpol; + gpol = &gp; + multiseed_metricsOfb = metricsOfb; + multiseed_refs = refs; + if (threeN) { + ref3N.load(gfms_3N, rgfms_3N, rrefss); + } else { + multiseed_gfm = gfm; + multiseed_rgfm = rgfm; + multiseed_rrefs = rrefs; + } + + AutoArray threads(nthreads); + AutoArray tids(nthreads); + // Start the metrics thread + { + Timer _t(cerr, "Multiseed full-index search: ", timing); + + thread_rids.resize(nthreads); + thread_rids.fill(0); + thread_rids_mindist = (nthreads == 1 || !useTempSpliceSite ? 0 : 1000 * nthreads); + for(int i = 0; i < nthreads; i++) { + // Thread IDs start at 1 + tids[i] = i+1; + threads[i] = new tthread::thread(multiseedSearchWorker_hisat2, (void*)&tids[i]); + } + + for (int i = 0; i < nthreads; i++) + threads[i]->join(); + + } + if(!metricsPerRead && (metricsOfb != NULL || metricsStderr)) { + metrics.reportInterval(metricsOfb, metricsStderr, true, false, NULL); + } +} + +static string argstr; + +extern void initializeCntLut(); +extern void initializeCntBit(); + +template +static void driver( + const char * type, + const string bt2indexBases[2], + const string& outfile) +{ + if(gVerbose || startVerbose) { + cerr << "Entered driver(): "; logTime(cerr, true); + } + + if (gVerbose || startVerbose) { + cerr << "Running in " << ((threeN) ? "3N" : "Regular") << " Mode" << endl; + } + + initializeCntLut(); + initializeCntBit(); + + // Vector of the reference sequences; used for sanity-checking + EList > names, os; + EList nameLens, seqLens; + // Read reference sequences from the command-line or from a FASTA file + if(!origString.empty()) { + // Read fasta file(s) + EList origFiles; + tokenize(origString, ",", origFiles); + parseFastas(origFiles, names, nameLens, os, seqLens); + } + PatternParams pp( + format, // file format + fileParallel, // true -> wrap files with separate PairedPatternSources + seed, // pseudo-random seed + useSpinlock, // use spin locks instead of pthreads + solexaQuals, // true -> qualities are on solexa64 scale + phred64Quals, // true -> qualities are on phred64 scale + integerQuals, // true -> qualities are space-separated numbers + fuzzy, // true -> try to parse fuzzy fastq + fastaContLen, // length of sampled reads for FastaContinuous... + fastaContFreq, // frequency of sampled reads for FastaContinuous... + skipReads // skip the first 'skip' patterns + ); + if(gVerbose || startVerbose) { + cerr << "Creating PatternSource: "; logTime(cerr, true); + } + PairedPatternSource *patsrc = PairedPatternSource::setupPatternSources( + queries, // singles, from argv + mates1, // mate1's, from -1 arg + mates2, // mate2's, from -2 arg + mates12, // both mates on each line, from --12 arg +#ifdef USE_SRA + sra_accs, // SRA accessions +#endif + qualities, // qualities associated with singles + qualities1, // qualities associated with m1 + qualities2, // qualities associated with m2 + pp, // read read-in parameters + nthreads, + gVerbose || startVerbose); // be talkative + // Open hit output file + if(gVerbose || startVerbose) { + cerr << "Opening hit output file: "; logTime(cerr, true); + } + OutFileBuf *fout; + if(!outfile.empty()) { + fout = new OutFileBuf(outfile.c_str(), false); + } else { + fout = new OutFileBuf(); + } + + // Initialize GFM object and read in header + if(gVerbose || startVerbose) { + cerr << "About to initialize fw GFM: "; logTime(cerr, true); + } + + // for 3N + if (threeN) { + for (int i = 0; i < 2; i++) { + altdbs_3N[i] = new ALTDB(); + repeatdbs_3N[i] = new RepeatDB(); + raltdbs_3N[i] = new ALTDB(); + } + } + + EList* >gfms_3N; + RFM* rgfms_3N[2]; + for (int i = 0; i < 2; i++) { + rgfms_3N[i] = NULL; + } + bool rep_index_exists_3N[2]{false}; + bool rep_index_exists = false; + string rep_adjIdxBase_3N[2]; + string rep_adjIdxBase; + + HGFM* gfm; + RFM* rgfm = NULL; + + if (threeN) { + for (int j = 0; j < 2; j++) { + adjIdxBases_3N[j] = adjustEbwtBase(argv0, bt2indexBases[j], gVerbose); + HGFM *tmp_gfm = new HGFM( + adjIdxBases_3N[j], + altdbs_3N[j], + NULL, + NULL, + -1, // fw index + true, // index is for the forward direction + /* overriding: */ offRate, + 0, // amount to add to index offrate or <= 0 to do nothing + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + !no_spliced_alignment, // load splice sites? + gVerbose, // whether to be talkative + startVerbose, // talkative during initialization + false /*passMemExc*/, + sanityCheck, + use_haplotype); //use haplotypes? + + gfms_3N.push_back(tmp_gfm); + + if(sanityCheck && !os.empty()) { + // Sanity check number of patterns and pattern lengths in GFM + // against original strings + assert_eq(os.size(), gfms_3N[j]->nPat()); + + for(size_t i = 0; i < os.size(); i++) { + assert_eq(os[i].length(), gfms_3N[j]->plen()[i]); + } + } + if(sanityCheck && !os.empty()) { + gfms_3N[j]->loadIntoMemory( + -1, // fw index + true, // load SA sample + true, // load ftab + true, // load rstarts + !noRefNames, + startVerbose); + gfms_3N[j]->checkOrigs(os, false); + gfms_3N[j]->evictFromMemory(); + } + { + // Load the other half of the index into memory + assert(!gfms_3N[j]->isInMemory()); + Timer _t(cerr, "Time loading forward index: ", timing); + gfms_3N[j]->loadIntoMemory( + -1, // not the reverse index + true, // load SA samp? (yes, need forward index's SA samp) + true, // load ftab (in forward index) + true, // load rstarts (in forward index) + !noRefNames, // load names? + startVerbose); + } + + + rep_adjIdxBase_3N[j] = adjIdxBases_3N[j] + ".rep"; + { + std::ifstream infile((rep_adjIdxBase_3N[j] + ".1." + gfm_ext.c_str()).c_str()); + rep_index_exists_3N[j] = infile.good(); + } + + if(rep_index_exists_3N[j] && use_repeat_index) { + rgfms_3N[j] = new RFM( + rep_adjIdxBase_3N[j], + raltdbs_3N[j], + repeatdbs_3N[j], + &readLens, + -1, // fw index + true, // index is for the forward direction + /* overriding: */ offRate, + 0, // amount to add to index offrate or <= 0 to do nothing + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + !no_spliced_alignment, // load splice sites? + gVerbose, // whether to be talkative + startVerbose, // talkative during initialization + false /*passMemExc*/, + sanityCheck, + false); //use haplotypes? + + // CP to do +#if 0 + if(sanityCheck && !os.empty()) { + // Sanity check number of patterns and pattern lengths in GFM + // against original strings + assert_eq(os.size(), gfm.nPat()); + for(size_t i = 0; i < os.size(); i++) { + assert_eq(os[i].length(), rgfm->plen()[i]); + } + } + // Sanity-check the restored version of the GFM + if(sanityCheck && !os.empty()) { + rgfm->loadIntoMemory( + -1, // fw index + true, // load SA sample + true, // load ftab + true, // load rstarts + !noRefNames, + startVerbose); + rgfm->checkOrigs(os, false); + rgfm->evictFromMemory(); + } +#endif + { + // Load the other half of the index into memory + assert(!rgfms_3N[j]->isInMemory()); + Timer _t(cerr, "Time loading forward index: ", timing); + rgfms_3N[j]->loadIntoMemory( + -1, // not the reverse index + true, // load SA samp? (yes, need forward index's SA samp) + true, // load ftab (in forward index) + true, // load rstarts (in forward index) + !noRefNames, // load names? + startVerbose); + + repeatdbs_3N[j]->construct(gfms_3N[j]->rstarts(), gfms_3N[j]->nFrag()); + } + + if (threeN) { + ht2_option_t option; + ht2_init_options(&option); + + option.altdb = altdbs_3N[j]; + option.raltdb = raltdbs_3N[j]; + option.repeatdb = repeatdbs_3N[j]; + option.gfm = gfms_3N[j]; + option.rgfm = rgfms_3N[j]; + + ht2_handle_t handle = ht2_init(adjIdxBases_3N[j].c_str(), &option); + + repeatHandles.push_back(handle); + if (refNameMap == NULL) { + ht2_index_getrefnames(repeatHandles[0], &refNameMap); + } + } + } + + + if(!saw_k) { + if(gfms_3N[j]->gh().linearFM()) khits = 5; + else khits = 10; + } + } + } else { + altdb = new ALTDB(); + repeatdb = new RepeatDB(); + raltdb = new ALTDB(); + adjIdxBase = adjustEbwtBase(argv0, bt2indexBases[0], gVerbose); + gfm = new HGFM( + adjIdxBase, + altdb, + NULL, + NULL, + -1, // fw index + true, // index is for the forward direction + /* overriding: */ offRate, + 0, // amount to add to index offrate or <= 0 to do nothing + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + !no_spliced_alignment, // load splice sites? + gVerbose, // whether to be talkative + startVerbose, // talkative during initialization + false /*passMemExc*/, + sanityCheck, + use_haplotype); //use haplotypes? + if(sanityCheck && !os.empty()) { + // Sanity check number of patterns and pattern lengths in GFM + // against original strings + assert_eq(os.size(), gfm->nPat()); + for(size_t i = 0; i < os.size(); i++) { + assert_eq(os[i].length(), gfm->plen()[i]); + } + } + // Sanity-check the restored version of the GFM + if(sanityCheck && !os.empty()) { + gfm->loadIntoMemory( + -1, // fw index + true, // load SA sample + true, // load ftab + true, // load rstarts + !noRefNames, + startVerbose); + gfm->checkOrigs(os, false); + gfm->evictFromMemory(); + } + { + // Load the other half of the index into memory + assert(!gfm->isInMemory()); + Timer _t(cerr, "Time loading forward index: ", timing); + gfm->loadIntoMemory( + -1, // not the reverse index + true, // load SA samp? (yes, need forward index's SA samp) + true, // load ftab (in forward index) + true, // load rstarts (in forward index) + !noRefNames, // load names? + startVerbose); + } + rep_adjIdxBase = adjIdxBase + ".rep"; + + { + std::ifstream infile((rep_adjIdxBase + ".1." + gfm_ext.c_str()).c_str()); + rep_index_exists = infile.good(); + } + if(rep_index_exists && use_repeat_index) { + rgfm = new RFM( + rep_adjIdxBase, + raltdb, + repeatdb, + &readLens, + -1, // fw index + true, // index is for the forward direction + /* overriding: */ offRate, + 0, // amount to add to index offrate or <= 0 to do nothing + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + !no_spliced_alignment, // load splice sites? + gVerbose, // whether to be talkative + startVerbose, // talkative during initialization + false /*passMemExc*/, + sanityCheck, + false); //use haplotypes? + + // CP to do +#if 0 + if(sanityCheck && !os.empty()) { + // Sanity check number of patterns and pattern lengths in GFM + // against original strings + assert_eq(os.size(), gfm.nPat()); + for(size_t i = 0; i < os.size(); i++) { + assert_eq(os[i].length(), rgfm->plen()[i]); + } + } + // Sanity-check the restored version of the GFM + if(sanityCheck && !os.empty()) { + rgfm->loadIntoMemory( + -1, // fw index + true, // load SA sample + true, // load ftab + true, // load rstarts + !noRefNames, + startVerbose); + rgfm->checkOrigs(os, false); + rgfm->evictFromMemory(); + } +#endif + { + // Load the other half of the index into memory + assert(!rgfm->isInMemory()); + Timer _t(cerr, "Time loading forward index: ", timing); + rgfm->loadIntoMemory( + -1, // not the reverse index + true, // load SA samp? (yes, need forward index's SA samp) + true, // load ftab (in forward index) + true, // load rstarts (in forward index) + !noRefNames, // load names? + startVerbose); + + repeatdb->construct(gfm->rstarts(), gfm->nFrag()); + } + } + + if(!saw_k) { + if(gfm->gh().linearFM()) khits = 5; + else khits = 10; + } + } // else threeN + + OutputQueue oq( + *fout, // out file buffer + reorder && nthreads > 1, // whether to reorder when there's >1 thread + nthreads, // # threads + nthreads > 1, // whether to be thread-safe + skipReads); // first read will have this rdid + { + Timer _t(cerr, "Time searching: ", timing); + // Set up penalities + if(bonusMatch > 0 && !localAlign) { + cerr << "Warning: Match bonus always = 0 in --end-to-end mode; ignoring user setting" << endl; + bonusMatch = 0; + } + if(tranAssm) { + penNoncanIntronLen.init(SIMPLE_FUNC_LOG, -8, 2); + } + Scoring sc( + bonusMatch, // constant reward for match + penMmcType, // how to penalize mismatches + penMmcMax, // max mm penalty + penMmcMin, // min mm penalty + penScMax, // max sc penalty + penScMin, // min sc penalty + scoreMin, // min score as function of read len + nCeil, // max # Ns as function of read len + penNType, // how to penalize Ns in the read + penN, // constant if N pelanty is a constant + penNCatPair, // whether to concat mates before N filtering + penRdGapConst, // constant coeff for read gap cost + penRfGapConst, // constant coeff for ref gap cost + penRdGapLinear, // linear coeff for read gap cost + penRfGapLinear, // linear coeff for ref gap cost + gGapBarrier, // # rows at top/bot only entered diagonally + penCanSplice, // canonical splicing penalty + penNoncanSplice,// non-canonical splicing penalty + penConflictSplice, // conflicting splice site penalty + &penCanIntronLen, // penalty as to intron length + &penNoncanIntronLen); // penalty as to intron length + + EList reflens; + // for HISAT-3N + EList refnames_3N[2]; + EList replens_3N[2]; + EList repnames_3N[2]; + EList empty_replens_3N[2]; + EList empty_repnames_3N[2]; + + //for regular hisat2 + EList refnames; + //readEbwtRefnames(adjIdxBase, refnames); + EList replens; + EList repnames; + EList empty_replens; + EList empty_repnames; + + + if (threeN) { + for(size_t i = 0; i < gfms_3N[0]->nPat(); i++) { + reflens.push_back(gfms_3N[0]->plen()[i]); + } + for (int j = 0; j < 2; j++) { + readEbwtRefnames(adjIdxBases_3N[j], refnames_3N[j]); + if (rep_index_exists_3N[j] && use_repeat_index) { + rgfms_3N[j]->getReferenceNames(repnames_3N[j]); + rgfms_3N[j]->getReferenceLens(replens_3N[j]); + } + if(rmChrName && addChrName) { + cerr << "Error: --remove-chrname and --add-chrname cannot be used at the same time" << endl; + throw 1; + } + if(rmChrName) { + for(size_t i = 0; i < refnames_3N[j].size(); i++) { + string& refname = refnames_3N[j][i]; + if(refname.find("chr") == 0) { + refname = refname.substr(3); + } + } + } else if(addChrName) { + for(size_t i = 0; i < refnames_3N[j].size(); i++) { + string& refname = refnames_3N[j][i]; + if(refname.find("chr") != 0) { + refname = string("chr") + refname; + } + } + } + } + } else { + readEbwtRefnames(adjIdxBase, refnames); + for(size_t i = 0; i < gfm->nPat(); i++) { + reflens.push_back(gfm->plen()[i]); + } + if(rep_index_exists && use_repeat_index) { + rgfm->getReferenceNames(repnames); + rgfm->getReferenceLens(replens); + } + if(rmChrName && addChrName) { + cerr << "Error: --remove-chrname and --add-chrname cannot be used at the same time" << endl; + throw 1; + } + if(rmChrName) { + for(size_t i = 0; i < refnames.size(); i++) { + string& refname = refnames[i]; + if(refname.find("chr") == 0) { + refname = refname.substr(3); + } + } + } else if(addChrName) { + for(size_t i = 0; i < refnames.size(); i++) { + string& refname = refnames[i]; + if(refname.find("chr") != 0) { + refname = string("chr") + refname; + } + } + } + } + + SamConfig samc( + threeN ? refnames_3N[0]: refnames, // reference sequence names + reflens, // reference sequence lengths + threeN?(repeat ? repnames_3N[0] : empty_repnames_3N[0]): (repeat ? repnames : empty_repnames), // repeat sequence names + threeN? (repeat ? replens_3N[0] : empty_replens_3N[0]): (repeat ? replens : empty_replens), // repeat sequence lengths + samTruncQname, // whether to truncate QNAME to 255 chars + samOmitSecSeqQual, // omit SEQ/QUAL for 2ndary alignments? + samNoUnal, // omit unaligned-read records? + string("hisat2"), // program id + string("hisat2"), // program name + string(HISAT2_VERSION), // program version + argstr, // command-line + rgs_optflag, // read-group string + rna_strandness, + sam_print_as, + sam_print_xs, + sam_print_xss, + sam_print_yn, + sam_print_xn, + sam_print_cs, + sam_print_cq, + sam_print_x0, + sam_print_x1, + sam_print_xm, + sam_print_xo, + sam_print_xg, + sam_print_nm, + sam_print_md, + sam_print_yf, + sam_print_yi, + sam_print_ym, + sam_print_yp, + sam_print_yt, + sam_print_ys, + sam_print_zs, + sam_print_xr, + sam_print_xt, + sam_print_xd, + sam_print_xu, + sam_print_yl, + sam_print_ye, + sam_print_yu, + sam_print_xp, + sam_print_yr, + sam_print_zb, + sam_print_zr, + sam_print_zf, + sam_print_zm, + sam_print_zi, + sam_print_zp, + sam_print_zu, + sam_print_xs_a, + sam_print_nh); + // Set up hit sink; if sanityCheck && !os.empty() is true, + // then instruct the sink to "retain" hits in a vector in + // memory so that we can easily sanity check them later on + + + AlnSink *mssink = NULL; + + //auto_ptr refss[2]; + auto_ptr refs; + + Timer *_tRef = new Timer(cerr, "Time loading reference: ", timing); + refs = auto_ptr( + new BitPairReference( + threeN ? adjIdxBases_3N[0] : adjIdxBase, + NULL, + false, + sanityCheck, + NULL, + NULL, + false, + useMm, + useShmem, + mmSweep, + gVerbose, + startVerbose) + ); + delete _tRef; + if(!refs->loaded()) throw 1; + + + + + BitPairReference* rrefss[2] = {NULL, }; + BitPairReference* rrefs = NULL; + + if (threeN) { + for (int j = 0; j < 2; j++) { + if (rep_index_exists_3N[j] && use_repeat_index) { + const EList &included = rgfms_3N[j]->getRepeatIncluded(); + rrefss[j] = new BitPairReference( + rep_adjIdxBase_3N[j], + &included, + false, + sanityCheck, + NULL, + NULL, + false, + useMm, + useShmem, + mmSweep, + gVerbose, + startVerbose); + if (!rrefss[j]->loaded()) throw 1; + } + } + } else { + if(rep_index_exists && use_repeat_index) { + const EList& included = rgfm->getRepeatIncluded(); + rrefs = new BitPairReference( + rep_adjIdxBase, + &included, + false, + sanityCheck, + NULL, + NULL, + false, + useMm, + useShmem, + mmSweep, + gVerbose, + startVerbose); + if(!rrefs->loaded()) throw 1; + } + } + + + bool xsOnly = (tranAssm_program == "cufflinks"); + TranscriptomePolicy tpol(minIntronLen, + maxIntronLen, + tranAssm ? 15 : 7, + tranAssm ? 20 : 14, + no_spliced_alignment, + tranMapOnly, + tranAssm, + xsOnly, + avoid_pseudogene); + + GraphPolicy gpol(max_alts_tried, + use_haplotype, + (threeN ? altdbs_3N[0]->haplotypes().size() : altdb->haplotypes().size()) > 0 && use_haplotype, + enable_codis); + + init_junction_prob(); + bool write = novelSpliceSiteOutfile != "" || useTempSpliceSite; + bool read = knownSpliceSiteInfile != "" || novelSpliceSiteInfile != "" || useTempSpliceSite || altdbs_3N[0]->hasSpliceSites(); + ssdb = new SpliceSiteDB( + *(refs.get()), + threeN ? refnames_3N[0] : refnames, + nthreads > 1, // thread-safe + write, // write? + read); // read? + ssdb->read(threeN ? *gfms_3N[0] : *gfm, threeN ? altdbs_3N[0]->alts() : altdb->alts()); + if(knownSpliceSiteInfile != "") { + ifstream ssdb_file(knownSpliceSiteInfile.c_str(), ios::in); + if(ssdb_file.is_open()) { + ssdb->read(ssdb_file, + true); // known splice sites + ssdb_file.close(); + } + } + if(novelSpliceSiteInfile != "") { + ifstream ssdb_file(novelSpliceSiteInfile.c_str(), ios::in); + if(ssdb_file.is_open()) { + ssdb->read(ssdb_file, + false); // novel splice sites + ssdb_file.close(); + } + } + + switch(outType) { + case OUTPUT_SAM: { + if (threeN) { + mssink = new AlnSink3NSam( + oq, // output queue + samc, // settings & routines for SAM output + refnames_3N[0], // reference names + repnames_3N[0], // repeat names + gQuiet, // don't print alignment summary at end + nthreads, + refs.get(), + no_spliced_alignment, + altdbs_3N[0], + ssdb); + } else { + mssink = new AlnSinkSam( + oq, // output queue + samc, // settings & routines for SAM output + refnames, // reference names + repnames, // repeat names + gQuiet, // don't print alignment summary at end + altdb, + ssdb); + }; + + if(!samNoHead) { + bool printHd = true, printSq = true; + BTString buf; + samc.printHeader(buf, rgid, rgs, printHd, !samNoSQ, printSq); + fout->writeString(buf); + } + break; + } + default: + cerr << "Invalid output type: " << outType << endl; + throw 1; + } + if(gVerbose || startVerbose) { + cerr << "Dispatching to search driver: "; logTime(cerr, true); + } + // Set up global constraint + OutFileBuf *metricsOfb = NULL; + if(!metricsFile.empty() && metricsIval > 0) { + metricsOfb = new OutFileBuf(metricsFile); + } + // Do the search for all input reads + assert(patsrc != NULL); + assert(mssink != NULL); + multiseedSearch( + sc, // scoring scheme + tpol, + gpol, + *patsrc, // pattern source + *mssink, // hit sink + gfms_3N, // 3N BWT + rgfms_3N, // 3N + rrefss, // 3N + gfm, // BWT + rgfm, + refs.get(), + rrefs, + metricsOfb); + // Evict any loaded indexes from memory + if (threeN) { + for (int j = 0; j < 2; j++) { + if(gfms_3N[j]->isInMemory()) { + gfms_3N[j]->evictFromMemory(); + } + } + } else { + if(gfm->isInMemory()) { + gfm->evictFromMemory(); + } + } + + if(!gQuiet && !seedSumm) { + size_t repThresh = mhits; + if(repThresh == 0) { + repThresh = std::numeric_limits::max(); + } + mssink->finish(cerr, + repThresh, + gReportDiscordant, + gReportMixed, + newAlignSummary, + hadoopOut); + if(alignSumFile != "") { + ofstream sumfile(alignSumFile.c_str(), ios::out); + if(sumfile.is_open()) { + mssink->finish(sumfile, + repThresh, + gReportDiscordant, + gReportMixed, + newAlignSummary, + false); // hadoopOut + sumfile.close(); + } + } + } + if(ssdb != NULL) { + if(novelSpliceSiteOutfile != "") { + ofstream ssdb_file(novelSpliceSiteOutfile.c_str(), ios::out); + if(ssdb_file.is_open()) { + ssdb->print(ssdb_file); + ssdb_file.close(); + } + } + } + oq.flush(true); + assert_eq(oq.numStarted(), oq.numFinished()); + assert_eq(oq.numStarted(), oq.numFlushed()); + delete patsrc; + delete mssink; + delete ssdb; + delete metricsOfb; + if (threeN) { + for (int i = 0; i < 2; i++) { + if(rep_index_exists_3N[i] && use_repeat_index) { + delete rgfms_3N[i]; + delete rrefss[i]; + delete repeatdbs_3N[i]; + delete raltdbs_3N[i]; + } + delete gfms_3N[i]; + delete altdbs_3N[i]; + } + if(rep_index_exists_3N[0] && use_repeat_index){ + for (int k = 0; k < 2; k++) { + ht2_close(repeatHandles[k]); + } + } + } else { + delete altdb; + delete repeatdb; + delete raltdb; + delete rgfm; + delete rrefs; + delete gfm; + } + if (refNameMap != NULL) { + free(refNameMap); + } + if(fout != NULL) { + delete fout; + } + } +} + +// C++ name mangling is disabled for the bowtie() function to make it +// easier to use Bowtie as a library. +extern "C" { + +/** + * Main bowtie entry function. Parses argc/argv style command-line + * options, sets global configuration variables, and calls the driver() + * function. + */ +int hisat2(int argc, const char **argv) { + try { + // Reset all global state, including getopt state + opterr = optind = 1; + resetOptions(); + for(int i = 0; i < argc; i++) { + argstr += argv[i]; + if(i < argc-1) argstr += " "; + } + if(startVerbose) { cerr << "Entered main(): "; logTime(cerr, true); } + parseOptions(argc, argv); + argv0 = argv[0]; + if(showVersion) { + cout << argv0 << " version " << HISAT2_VERSION << endl; + if(sizeof(void*) == 4) { + cout << "32-bit" << endl; + } else if(sizeof(void*) == 8) { + cout << "64-bit" << endl; + } else { + cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl; + } + cout << "Built on " << BUILD_HOST << endl; + cout << BUILD_TIME << endl; + cout << "Compiler: " << COMPILER_VERSION << endl; + cout << "Options: " << COMPILER_OPTIONS << endl; + cout << "Sizeof {int, long, long long, void*, size_t, off_t}: {" + << sizeof(int) + << ", " << sizeof(long) << ", " << sizeof(long long) + << ", " << sizeof(void *) << ", " << sizeof(size_t) + << ", " << sizeof(off_t) << "}" << endl; + return 0; + } + { + Timer _t(cerr, "Overall time: ", timing); + if(startVerbose) { + cerr << "Parsing index and read arguments: "; logTime(cerr, true); + } + + // Get index basename (but only if it wasn't specified via --index) + if(bt2indexs[0].empty()) { + if(optind >= argc) { + cerr << "No index, query, or output file specified!" << endl; + printUsage(cerr); + return 1; + } + bt2indexs[0] = argv[optind++]; + } + if (threeN) { + bt2indexs[1] = bt2indexs[0]; + if (fileExist(bt2indexs[0] + threeN_indexTags[0] + ".1." + gfm_ext)) { + bt2indexs[0] += threeN_indexTags[0]; + bt2indexs[1] += threeN_indexTags[1]; + } else if (fileExist(bt2indexs[0] + ".3n.1.1." + gfm_ext)) { + bt2indexs[0] += ".3n.1"; + bt2indexs[1] += ".3n.2"; + if (!((usrInput_convertedFrom == 'C' && usrInput_convertedTo == 'T') || + (usrInput_convertedFrom == 'T' && usrInput_convertedTo == 'C'))) { + cerr << "Your current hisat-3n index only support C-to-T or T-to-C base change. Please build new hisat-3n index to support " + << usrInput_convertedFrom << " to " << usrInput_convertedTo << "change." << endl; + printUsage(cerr); + return 1; + } + } else { + cerr << "Index is not exist, please use hisat-3n-build to build index first. Please use the same --base-change argument for both hisat-3n-build and hisat-3n." << endl; + printUsage(cerr); + return 1; + } + } + + // Get query filename + bool got_reads = !queries.empty() || !mates1.empty() || !mates12.empty(); +#ifdef USE_SRA + got_reads = got_reads || !sra_accs.empty(); +#endif + if(minIntronLen > maxIntronLen) { + cerr << "--min-intronlen(" << minIntronLen << ") should not be greater than --max-intronlen(" + << maxIntronLen << ")" << endl; + printUsage(cerr); + return 1; + } + if(optind >= argc) { + if(!got_reads) { + printUsage(cerr); + cerr << "***" << endl +#ifdef USE_SRA + << "Error: Must specify at least one read input with -U/-1/-2/--sra-acc" << endl; +#else + << "Error: Must specify at least one read input with -U/-1/-2" << endl; + +#endif + return 1; + } + } else if(!got_reads) { + // Tokenize the list of query files + tokenize(argv[optind++], ",", queries); + if(queries.empty()) { + cerr << "Tokenized query file list was empty!" << endl; + printUsage(cerr); + return 1; + } + } + + // Get output filename + if(optind < argc && outfile.empty()) { + outfile = argv[optind++]; + cerr << "Warning: Output file '" << outfile.c_str() + << "' was specified without -S. This will not work in " + << "future HISAT 2 versions. Please use -S instead." + << endl; + } + + // Extra parametesr? + if(optind < argc) { + cerr << "Extra parameter(s) specified: "; + for(int i = optind; i < argc; i++) { + cerr << "\"" << argv[i] << "\""; + if(i < argc-1) cerr << ", "; + } + cerr << endl; + if(mates1.size() > 0) { + cerr << "Note that if files are specified using -1/-2, a file cannot" << endl + << "also be specified. Please run HISAT2 separately for mates and singles." << endl; + } + throw 1; + } + + // Optionally summarize + if(gVerbose) { + cout << "Input bt2 file: \"" << bt2indexs[0].c_str() << "\"" << endl; + cout << "Input bt2 file: \"" << bt2indexs[1].c_str() << "\"" << endl; + cout << "Query inputs (DNA, " << file_format_names[format].c_str() << "):" << endl; + for(size_t i = 0; i < queries.size(); i++) { + cout << " " << queries[i].c_str() << endl; + } + cout << "Quality inputs:" << endl; + for(size_t i = 0; i < qualities.size(); i++) { + cout << " " << qualities[i].c_str() << endl; + } + cout << "Output file: \"" << outfile.c_str() << "\"" << endl; + cout << "Local endianness: " << (currentlyBigEndian()? "big":"little") << endl; + cout << "Sanity checking: " << (sanityCheck? "enabled":"disabled") << endl; + #ifdef NDEBUG + cout << "Assertions: disabled" << endl; + #else + cout << "Assertions: enabled" << endl; + #endif + } + if(ipause) { + cout << "Press key to continue..." << endl; + getchar(); + } + driver >("DNA", bt2indexs, outfile); + } + return 0; + } catch(std::exception& e) { + cerr << "Error: Encountered exception: '" << e.what() << "'" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + return 1; + } catch(int e) { + if(e != 0) { + cerr << "Error: Encountered internal HISAT2 exception (#" << e << ")" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + } + return e; + } +} // bowtie() +} // extern "C" diff --git a/hisat2.sln b/hisat2.sln new file mode 100644 index 0000000..a073d42 --- /dev/null +++ b/hisat2.sln @@ -0,0 +1,82 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "codeStubs", "MSVCC\codeStubs.vcxproj", "{08C70FF5-9E0C-42DF-B7BF-C1AF1B0D2CFF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "search", "MSVCC\search.vcxproj", "{43F946A8-9184-456B-A522-7B411C10A4EB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "search64", "MSVCC\search64.vcxproj", "{D281E44B-92E9-4CEA-A666-B05530F65000}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared", "MSVCC\shared.vcxproj", "{8BEEB701-AA26-4D2B-827B-64071F88AFB3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared64", "MSVCC\shared64.vcxproj", "{E1F391B2-4A3F-43CA-9192-14536ABE783E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hisat2-align-l", "MSVCC\hisat2-align-l.vcxproj", "{55F86D23-4245-4050-BD2D-CC5D4FD0C36B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hisat2-align-s", "MSVCC\hisat2-align-s.vcxproj", "{9D5066DB-ACD2-42E9-BFE6-98C8E7DEA7DA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hisat2-build-l", "MSVCC\hisat2-build-l.vcxproj", "{262E4D55-07C3-4B18-B8E2-F3B6AA4C583E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hisat2-build-s", "MSVCC\hisat2-build-s.vcxproj", "{3B90EEC9-CDFF-424E-B3A3-4B7A5326A43F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hisat2-inspect-l", "MSVCC\hisat2-inspect-l.vcxproj", "{E0A17972-1AF6-429A-A902-3913656B5CFC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hisat2-inspect-s", "MSVCC\hisat2-inspect-s.vcxproj", "{DA85C3F8-8CDD-4ED4-AF86-05B5556670F7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {08C70FF5-9E0C-42DF-B7BF-C1AF1B0D2CFF}.Debug|x64.ActiveCfg = Debug|x64 + {08C70FF5-9E0C-42DF-B7BF-C1AF1B0D2CFF}.Debug|x64.Build.0 = Debug|x64 + {08C70FF5-9E0C-42DF-B7BF-C1AF1B0D2CFF}.Release|x64.ActiveCfg = Release|x64 + {08C70FF5-9E0C-42DF-B7BF-C1AF1B0D2CFF}.Release|x64.Build.0 = Release|x64 + {43F946A8-9184-456B-A522-7B411C10A4EB}.Debug|x64.ActiveCfg = Debug|x64 + {43F946A8-9184-456B-A522-7B411C10A4EB}.Debug|x64.Build.0 = Debug|x64 + {43F946A8-9184-456B-A522-7B411C10A4EB}.Release|x64.ActiveCfg = Release|x64 + {43F946A8-9184-456B-A522-7B411C10A4EB}.Release|x64.Build.0 = Release|x64 + {D281E44B-92E9-4CEA-A666-B05530F65000}.Debug|x64.ActiveCfg = Debug|x64 + {D281E44B-92E9-4CEA-A666-B05530F65000}.Debug|x64.Build.0 = Debug|x64 + {D281E44B-92E9-4CEA-A666-B05530F65000}.Release|x64.ActiveCfg = Release|x64 + {D281E44B-92E9-4CEA-A666-B05530F65000}.Release|x64.Build.0 = Release|x64 + {8BEEB701-AA26-4D2B-827B-64071F88AFB3}.Debug|x64.ActiveCfg = Debug|x64 + {8BEEB701-AA26-4D2B-827B-64071F88AFB3}.Debug|x64.Build.0 = Debug|x64 + {8BEEB701-AA26-4D2B-827B-64071F88AFB3}.Release|x64.ActiveCfg = Release|x64 + {8BEEB701-AA26-4D2B-827B-64071F88AFB3}.Release|x64.Build.0 = Release|x64 + {E1F391B2-4A3F-43CA-9192-14536ABE783E}.Debug|x64.ActiveCfg = Debug|x64 + {E1F391B2-4A3F-43CA-9192-14536ABE783E}.Debug|x64.Build.0 = Debug|x64 + {E1F391B2-4A3F-43CA-9192-14536ABE783E}.Release|x64.ActiveCfg = Release|x64 + {E1F391B2-4A3F-43CA-9192-14536ABE783E}.Release|x64.Build.0 = Release|x64 + {55F86D23-4245-4050-BD2D-CC5D4FD0C36B}.Debug|x64.ActiveCfg = Debug|x64 + {55F86D23-4245-4050-BD2D-CC5D4FD0C36B}.Debug|x64.Build.0 = Debug|x64 + {55F86D23-4245-4050-BD2D-CC5D4FD0C36B}.Release|x64.ActiveCfg = Release|x64 + {55F86D23-4245-4050-BD2D-CC5D4FD0C36B}.Release|x64.Build.0 = Release|x64 + {9D5066DB-ACD2-42E9-BFE6-98C8E7DEA7DA}.Debug|x64.ActiveCfg = Debug|x64 + {9D5066DB-ACD2-42E9-BFE6-98C8E7DEA7DA}.Debug|x64.Build.0 = Debug|x64 + {9D5066DB-ACD2-42E9-BFE6-98C8E7DEA7DA}.Release|x64.ActiveCfg = Release|x64 + {9D5066DB-ACD2-42E9-BFE6-98C8E7DEA7DA}.Release|x64.Build.0 = Release|x64 + {262E4D55-07C3-4B18-B8E2-F3B6AA4C583E}.Debug|x64.ActiveCfg = Debug|x64 + {262E4D55-07C3-4B18-B8E2-F3B6AA4C583E}.Debug|x64.Build.0 = Debug|x64 + {262E4D55-07C3-4B18-B8E2-F3B6AA4C583E}.Release|x64.ActiveCfg = Release|x64 + {262E4D55-07C3-4B18-B8E2-F3B6AA4C583E}.Release|x64.Build.0 = Release|x64 + {3B90EEC9-CDFF-424E-B3A3-4B7A5326A43F}.Debug|x64.ActiveCfg = Debug|x64 + {3B90EEC9-CDFF-424E-B3A3-4B7A5326A43F}.Debug|x64.Build.0 = Debug|x64 + {3B90EEC9-CDFF-424E-B3A3-4B7A5326A43F}.Release|x64.ActiveCfg = Release|x64 + {3B90EEC9-CDFF-424E-B3A3-4B7A5326A43F}.Release|x64.Build.0 = Release|x64 + {E0A17972-1AF6-429A-A902-3913656B5CFC}.Debug|x64.ActiveCfg = Debug|x64 + {E0A17972-1AF6-429A-A902-3913656B5CFC}.Debug|x64.Build.0 = Debug|x64 + {E0A17972-1AF6-429A-A902-3913656B5CFC}.Release|x64.ActiveCfg = Release|x64 + {E0A17972-1AF6-429A-A902-3913656B5CFC}.Release|x64.Build.0 = Release|x64 + {DA85C3F8-8CDD-4ED4-AF86-05B5556670F7}.Debug|x64.ActiveCfg = Debug|x64 + {DA85C3F8-8CDD-4ED4-AF86-05B5556670F7}.Debug|x64.Build.0 = Debug|x64 + {DA85C3F8-8CDD-4ED4-AF86-05B5556670F7}.Release|x64.ActiveCfg = Release|x64 + {DA85C3F8-8CDD-4ED4-AF86-05B5556670F7}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/hisat2.xcodeproj/project.pbxproj b/hisat2.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c1b8291 --- /dev/null +++ b/hisat2.xcodeproj/project.pbxproj @@ -0,0 +1,1307 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 606F132420E1528D008903D6 /* hisat2_repeat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 606F132220E1528D008903D6 /* hisat2_repeat.cpp */; }; + 606F132520E1528D008903D6 /* hisat2_repeat_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 606F132320E1528D008903D6 /* hisat2_repeat_main.cpp */; }; + 60A82E9E21274F1B0040293D /* bit_packed_array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 60A82E9C21274F1B0040293D /* bit_packed_array.cpp */; }; + E84A236320D2AF1600C12106 /* repeat_builder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E84A236220D2AF1500C12106 /* repeat_builder.cpp */; }; + E8D9218220C85FE900378C5B /* diff_sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDF1C20B2B600C03464 /* diff_sample.cpp */; }; + E8D9218520C85FE900378C5B /* limit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEC1C20B2B600C03464 /* limit.cpp */; }; + E8D9218620C85FE900378C5B /* multikey_qsort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEF1C20B2B600C03464 /* multikey_qsort.cpp */; }; + E8D9218720C85FE900378C5B /* random_source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF51C20B2B600C03464 /* random_source.cpp */; }; + E8D9218820C85FE900378C5B /* tinythread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D021C20B2B600C03464 /* tinythread.cpp */; }; + E8D9218920C85FE900378C5B /* alphabet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDC1C20B2B600C03464 /* alphabet.cpp */; }; + E8D9218A20C85FE900378C5B /* ccnt_lut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */; }; + E8D9218B20C85FE900378C5B /* ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE11C20B2B600C03464 /* ds.cpp */; }; + E8D9218C20C85FE900378C5B /* edit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE21C20B2B600C03464 /* edit.cpp */; }; + E8D9218D20C85FE900378C5B /* gfm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE31C20B2B600C03464 /* gfm.cpp */; }; + E8D9218E20C85FE900378C5B /* ref_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF91C20B2B600C03464 /* ref_read.cpp */; }; + E8D9218F20C85FE900378C5B /* reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFA1C20B2B600C03464 /* reference.cpp */; }; + E8D9219020C85FE900378C5B /* shmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFC1C20B2B600C03464 /* shmem.cpp */; }; + E8D9219920C878B700378C5B /* aligner_result.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD01C20B2B600C03464 /* aligner_result.cpp */; }; + E8D9219A20C878B700378C5B /* aligner_sw_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD41C20B2B600C03464 /* aligner_sw_driver.cpp */; }; + E8D9219B20C878B700378C5B /* aligner_sw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD51C20B2B600C03464 /* aligner_sw.cpp */; }; + E8D9219C20C878B700378C5B /* aligner_swsse_ee_i16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD61C20B2B600C03464 /* aligner_swsse_ee_i16.cpp */; }; + E8D9219D20C878B700378C5B /* aligner_swsse_ee_u8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD71C20B2B600C03464 /* aligner_swsse_ee_u8.cpp */; }; + E8D9219E20C878B700378C5B /* aligner_swsse_loc_i16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD81C20B2B600C03464 /* aligner_swsse_loc_i16.cpp */; }; + E8D9219F20C878B700378C5B /* aligner_swsse_loc_u8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD91C20B2B600C03464 /* aligner_swsse_loc_u8.cpp */; }; + E8D921A020C878B700378C5B /* aligner_swsse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDA1C20B2B600C03464 /* aligner_swsse.cpp */; }; + E8D921A120C878EC00378C5B /* dp_framer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE01C20B2B600C03464 /* dp_framer.cpp */; }; + E8D921A220C8791000378C5B /* scoring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFB1C20B2B600C03464 /* scoring.cpp */; }; + E8D921A320C8791000378C5B /* simple_func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFD1C20B2B600C03464 /* simple_func.cpp */; }; + E8D921A420C8794400378C5B /* aligner_bt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CCD1C20B2B600C03464 /* aligner_bt.cpp */; }; + E8D921A520C8798500378C5B /* qual.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF41C20B2B600C03464 /* qual.cpp */; }; + E8D921A620C879AB00378C5B /* mask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEE1C20B2B600C03464 /* mask.cpp */; }; + E8EAEDC41C24663D00E62E69 /* alphabet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDC1C20B2B600C03464 /* alphabet.cpp */; }; + E8EAEDC51C24663D00E62E69 /* ccnt_lut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */; }; + E8EAEDC61C24663D00E62E69 /* ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE11C20B2B600C03464 /* ds.cpp */; }; + E8EAEDC71C24663D00E62E69 /* edit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE21C20B2B600C03464 /* edit.cpp */; }; + E8EAEDC81C24663D00E62E69 /* gfm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE31C20B2B600C03464 /* gfm.cpp */; }; + E8EAEDC91C24663D00E62E69 /* ref_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF91C20B2B600C03464 /* ref_read.cpp */; }; + E8EAEDCA1C24663D00E62E69 /* reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFA1C20B2B600C03464 /* reference.cpp */; }; + E8EAEDCB1C24663D00E62E69 /* shmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFC1C20B2B600C03464 /* shmem.cpp */; }; + E8EAEDCC1C24666400E62E69 /* limit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEC1C20B2B600C03464 /* limit.cpp */; }; + E8EAEDCD1C24666400E62E69 /* multikey_qsort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEF1C20B2B600C03464 /* multikey_qsort.cpp */; }; + E8EAEDCE1C24666400E62E69 /* random_source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF51C20B2B600C03464 /* random_source.cpp */; }; + E8EAEDCF1C24666400E62E69 /* tinythread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D021C20B2B600C03464 /* tinythread.cpp */; }; + E8EAEDD01C24667700E62E69 /* hisat2_build_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE61C20B2B600C03464 /* hisat2_build_main.cpp */; }; + E8EAEDD11C24667700E62E69 /* hisat2_build.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE71C20B2B600C03464 /* hisat2_build.cpp */; }; + E8EAEDD41C24675500E62E69 /* hisat2_build_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE61C20B2B600C03464 /* hisat2_build_main.cpp */; }; + E8EAEDD51C24675500E62E69 /* hisat2_build.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE71C20B2B600C03464 /* hisat2_build.cpp */; }; + E8EAEDD61C24675500E62E69 /* limit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEC1C20B2B600C03464 /* limit.cpp */; }; + E8EAEDD71C24675500E62E69 /* multikey_qsort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEF1C20B2B600C03464 /* multikey_qsort.cpp */; }; + E8EAEDD81C24675500E62E69 /* random_source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF51C20B2B600C03464 /* random_source.cpp */; }; + E8EAEDD91C24675500E62E69 /* tinythread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D021C20B2B600C03464 /* tinythread.cpp */; }; + E8EAEDDA1C24675500E62E69 /* alphabet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDC1C20B2B600C03464 /* alphabet.cpp */; }; + E8EAEDDB1C24675500E62E69 /* ccnt_lut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */; }; + E8EAEDDC1C24675500E62E69 /* ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE11C20B2B600C03464 /* ds.cpp */; }; + E8EAEDDD1C24675500E62E69 /* edit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE21C20B2B600C03464 /* edit.cpp */; }; + E8EAEDDE1C24675500E62E69 /* gfm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE31C20B2B600C03464 /* gfm.cpp */; }; + E8EAEDDF1C24675500E62E69 /* ref_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF91C20B2B600C03464 /* ref_read.cpp */; }; + E8EAEDE01C24675500E62E69 /* reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFA1C20B2B600C03464 /* reference.cpp */; }; + E8EAEDE11C24675500E62E69 /* shmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFC1C20B2B600C03464 /* shmem.cpp */; }; + E8EAEDE81C246CDC00E62E69 /* diff_sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDF1C20B2B600C03464 /* diff_sample.cpp */; }; + E8EAEDE91C246DA200E62E69 /* alphabet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDC1C20B2B600C03464 /* alphabet.cpp */; }; + E8EAEDEA1C246DA200E62E69 /* ccnt_lut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */; }; + E8EAEDEB1C246DA200E62E69 /* ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE11C20B2B600C03464 /* ds.cpp */; }; + E8EAEDEC1C246DA200E62E69 /* edit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE21C20B2B600C03464 /* edit.cpp */; }; + E8EAEDED1C246DA200E62E69 /* gfm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE31C20B2B600C03464 /* gfm.cpp */; }; + E8EAEDEE1C246DA200E62E69 /* multikey_qsort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEF1C20B2B600C03464 /* multikey_qsort.cpp */; }; + E8EAEDEF1C246DA200E62E69 /* ref_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF91C20B2B600C03464 /* ref_read.cpp */; }; + E8EAEDF01C246DA200E62E69 /* reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFA1C20B2B600C03464 /* reference.cpp */; }; + E8EAEDF11C246DA200E62E69 /* shmem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFC1C20B2B600C03464 /* shmem.cpp */; }; + E8EAEDF21C246DB200E62E69 /* hisat2_inspect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE81C20B2B600C03464 /* hisat2_inspect.cpp */; }; + E8EAEDF31C246DB200E62E69 /* limit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEC1C20B2B600C03464 /* limit.cpp */; }; + E8EAEDF41C246DB200E62E69 /* random_source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF51C20B2B600C03464 /* random_source.cpp */; }; + E8EAEDF51C246DB200E62E69 /* tinythread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D021C20B2B600C03464 /* tinythread.cpp */; }; + E8EAEDF61C246E3100E62E69 /* hisat2_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE91C20B2B600C03464 /* hisat2_main.cpp */; }; + E8EAEDF71C246E3100E62E69 /* hisat2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEA1C20B2B600C03464 /* hisat2.cpp */; }; + E8EAEDF81C246E3100E62E69 /* pat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF11C20B2B600C03464 /* pat.cpp */; }; + E8EAEDF91C246E3100E62E69 /* qual.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF41C20B2B600C03464 /* qual.cpp */; }; + E8EAEDFA1C246E5100E62E69 /* aligner_cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CCE1C20B2B600C03464 /* aligner_cache.cpp */; }; + E8EAEDFB1C246E5100E62E69 /* aligner_seed_policy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD11C20B2B600C03464 /* aligner_seed_policy.cpp */; }; + E8EAEDFC1C246E5100E62E69 /* aligner_seed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD21C20B2B600C03464 /* aligner_seed.cpp */; }; + E8EAEDFD1C246E5100E62E69 /* aligner_seed2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD31C20B2B600C03464 /* aligner_seed2.cpp */; }; + E8EAEDFE1C246E5100E62E69 /* aligner_sw_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD41C20B2B600C03464 /* aligner_sw_driver.cpp */; }; + E8EAEDFF1C246E5100E62E69 /* aligner_sw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD51C20B2B600C03464 /* aligner_sw.cpp */; }; + E8EAEE001C246E5100E62E69 /* read_qseq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF71C20B2B600C03464 /* read_qseq.cpp */; }; + E8EAEE011C246EB200E62E69 /* aligner_result.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD01C20B2B600C03464 /* aligner_result.cpp */; }; + E8EAEE021C246EB200E62E69 /* aln_sink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDB1C20B2B600C03464 /* aln_sink.cpp */; }; + E8EAEE031C246EB200E62E69 /* dp_framer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE01C20B2B600C03464 /* dp_framer.cpp */; }; + E8EAEE041C246EB200E62E69 /* mask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEE1C20B2B600C03464 /* mask.cpp */; }; + E8EAEE051C246EB200E62E69 /* pe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF21C20B2B600C03464 /* pe.cpp */; }; + E8EAEE061C246EB200E62E69 /* presets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF31C20B2B600C03464 /* presets.cpp */; }; + E8EAEE071C246EB200E62E69 /* ref_coord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF81C20B2B600C03464 /* ref_coord.cpp */; }; + E8EAEE081C246EB200E62E69 /* scoring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFB1C20B2B600C03464 /* scoring.cpp */; }; + E8EAEE091C246EB200E62E69 /* unique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D031C20B2B600C03464 /* unique.cpp */; }; + E8EAEE0A1C246EE900E62E69 /* aligner_bt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CCD1C20B2B600C03464 /* aligner_bt.cpp */; }; + E8EAEE0B1C246EE900E62E69 /* aligner_swsse_ee_i16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD61C20B2B600C03464 /* aligner_swsse_ee_i16.cpp */; }; + E8EAEE0C1C246EE900E62E69 /* aligner_swsse_ee_u8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD71C20B2B600C03464 /* aligner_swsse_ee_u8.cpp */; }; + E8EAEE0D1C246EE900E62E69 /* aligner_swsse_loc_i16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD81C20B2B600C03464 /* aligner_swsse_loc_i16.cpp */; }; + E8EAEE0E1C246EE900E62E69 /* aligner_swsse_loc_u8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD91C20B2B600C03464 /* aligner_swsse_loc_u8.cpp */; }; + E8EAEE0F1C246EE900E62E69 /* aligner_swsse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDA1C20B2B600C03464 /* aligner_swsse.cpp */; }; + E8EAEE101C246EE900E62E69 /* outq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF01C20B2B600C03464 /* outq.cpp */; }; + E8EAEE111C246EE900E62E69 /* random_source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF51C20B2B600C03464 /* random_source.cpp */; }; + E8EAEE121C246EE900E62E69 /* random_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF61C20B2B600C03464 /* random_util.cpp */; }; + E8EAEE131C246EE900E62E69 /* simple_func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFD1C20B2B600C03464 /* simple_func.cpp */; }; + E8EAEE141C246EE900E62E69 /* sse_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D001C20B2B600C03464 /* sse_util.cpp */; }; + E8EAEE151C246EFC00E62E69 /* aligner_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CCF1C20B2B600C03464 /* aligner_driver.cpp */; }; + E8EAEE161C246EFC00E62E69 /* splice_site.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFF1C20B2B600C03464 /* splice_site.cpp */; }; + E8EAEE171C2487FF00E62E69 /* diff_sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDF1C20B2B600C03464 /* diff_sample.cpp */; }; + E8EAEE181C24886400E62E69 /* ccnt_lut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */; }; + E8EAEE191C2488AF00E62E69 /* ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE11C20B2B600C03464 /* ds.cpp */; }; + E8EAEE1A1C2488D600E62E69 /* limit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEC1C20B2B600C03464 /* limit.cpp */; }; + E8EAEE1B1C2488EA00E62E69 /* edit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE21C20B2B600C03464 /* edit.cpp */; }; + E8EAEE1C1C24891800E62E69 /* alphabet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDC1C20B2B600C03464 /* alphabet.cpp */; }; + E8EAEE1D1C24892B00E62E69 /* gfm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE31C20B2B600C03464 /* gfm.cpp */; }; + E8EAEE1E1C24894300E62E69 /* tinythread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D021C20B2B600C03464 /* tinythread.cpp */; }; + E8EAEE1F1C24896600E62E69 /* reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFA1C20B2B600C03464 /* reference.cpp */; }; + E8EAEE201C24899300E62E69 /* ref_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF91C20B2B600C03464 /* ref_read.cpp */; }; + E8FD97B41C81CCED00861B09 /* ref_read.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF91C20B2B600C03464 /* ref_read.cpp */; }; + E8FD97B51C81CCED00861B09 /* reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFA1C20B2B600C03464 /* reference.cpp */; }; + E8FD97B61C81CCED00861B09 /* tinythread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D021C20B2B600C03464 /* tinythread.cpp */; }; + E8FD97B71C81CCED00861B09 /* gfm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE31C20B2B600C03464 /* gfm.cpp */; }; + E8FD97B81C81CCED00861B09 /* alphabet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDC1C20B2B600C03464 /* alphabet.cpp */; }; + E8FD97B91C81CCED00861B09 /* edit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE21C20B2B600C03464 /* edit.cpp */; }; + E8FD97BA1C81CCED00861B09 /* limit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEC1C20B2B600C03464 /* limit.cpp */; }; + E8FD97BB1C81CCED00861B09 /* ds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE11C20B2B600C03464 /* ds.cpp */; }; + E8FD97BC1C81CCED00861B09 /* ccnt_lut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */; }; + E8FD97BD1C81CCED00861B09 /* diff_sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDF1C20B2B600C03464 /* diff_sample.cpp */; }; + E8FD97BE1C81CCED00861B09 /* aligner_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CCF1C20B2B600C03464 /* aligner_driver.cpp */; }; + E8FD97BF1C81CCED00861B09 /* splice_site.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFF1C20B2B600C03464 /* splice_site.cpp */; }; + E8FD97C01C81CCED00861B09 /* aligner_bt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CCD1C20B2B600C03464 /* aligner_bt.cpp */; }; + E8FD97C11C81CCED00861B09 /* aligner_swsse_ee_i16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD61C20B2B600C03464 /* aligner_swsse_ee_i16.cpp */; }; + E8FD97C21C81CCED00861B09 /* aligner_swsse_ee_u8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD71C20B2B600C03464 /* aligner_swsse_ee_u8.cpp */; }; + E8FD97C31C81CCED00861B09 /* aligner_swsse_loc_i16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD81C20B2B600C03464 /* aligner_swsse_loc_i16.cpp */; }; + E8FD97C41C81CCED00861B09 /* aligner_swsse_loc_u8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD91C20B2B600C03464 /* aligner_swsse_loc_u8.cpp */; }; + E8FD97C51C81CCED00861B09 /* aligner_swsse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDA1C20B2B600C03464 /* aligner_swsse.cpp */; }; + E8FD97C61C81CCED00861B09 /* outq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF01C20B2B600C03464 /* outq.cpp */; }; + E8FD97C71C81CCED00861B09 /* random_source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF51C20B2B600C03464 /* random_source.cpp */; }; + E8FD97C81C81CCED00861B09 /* random_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF61C20B2B600C03464 /* random_util.cpp */; }; + E8FD97C91C81CCED00861B09 /* simple_func.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFD1C20B2B600C03464 /* simple_func.cpp */; }; + E8FD97CA1C81CCED00861B09 /* sse_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D001C20B2B600C03464 /* sse_util.cpp */; }; + E8FD97CB1C81CCED00861B09 /* aligner_result.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD01C20B2B600C03464 /* aligner_result.cpp */; }; + E8FD97CC1C81CCED00861B09 /* aln_sink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDB1C20B2B600C03464 /* aln_sink.cpp */; }; + E8FD97CD1C81CCED00861B09 /* dp_framer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE01C20B2B600C03464 /* dp_framer.cpp */; }; + E8FD97CE1C81CCED00861B09 /* mask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEE1C20B2B600C03464 /* mask.cpp */; }; + E8FD97CF1C81CCED00861B09 /* pe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF21C20B2B600C03464 /* pe.cpp */; }; + E8FD97D01C81CCED00861B09 /* presets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF31C20B2B600C03464 /* presets.cpp */; }; + E8FD97D11C81CCED00861B09 /* ref_coord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF81C20B2B600C03464 /* ref_coord.cpp */; }; + E8FD97D21C81CCED00861B09 /* scoring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CFB1C20B2B600C03464 /* scoring.cpp */; }; + E8FD97D31C81CCED00861B09 /* unique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30D031C20B2B600C03464 /* unique.cpp */; }; + E8FD97D41C81CCED00861B09 /* aligner_cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CCE1C20B2B600C03464 /* aligner_cache.cpp */; }; + E8FD97D51C81CCED00861B09 /* aligner_seed_policy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD11C20B2B600C03464 /* aligner_seed_policy.cpp */; }; + E8FD97D61C81CCED00861B09 /* aligner_seed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD21C20B2B600C03464 /* aligner_seed.cpp */; }; + E8FD97D71C81CCED00861B09 /* aligner_seed2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD31C20B2B600C03464 /* aligner_seed2.cpp */; }; + E8FD97D81C81CCED00861B09 /* aligner_sw_driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD41C20B2B600C03464 /* aligner_sw_driver.cpp */; }; + E8FD97D91C81CCED00861B09 /* aligner_sw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CD51C20B2B600C03464 /* aligner_sw.cpp */; }; + E8FD97DA1C81CCED00861B09 /* read_qseq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF71C20B2B600C03464 /* read_qseq.cpp */; }; + E8FD97DB1C81CCED00861B09 /* hisat2_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CE91C20B2B600C03464 /* hisat2_main.cpp */; }; + E8FD97DC1C81CCED00861B09 /* hisat2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CEA1C20B2B600C03464 /* hisat2.cpp */; }; + E8FD97DD1C81CCED00861B09 /* pat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF11C20B2B600C03464 /* pat.cpp */; }; + E8FD97DE1C81CCED00861B09 /* qual.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CF41C20B2B600C03464 /* qual.cpp */; }; + E8FD97E51C8343EF00861B09 /* diff_sample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8C30CDF1C20B2B600C03464 /* diff_sample.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + E8C30C581C20A5DD00C03464 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + E8C30C681C20A64A00C03464 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + E8C30C731C20A65400C03464 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + E8D9219220C85FE900378C5B /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + E8EAEDE31C24675500E62E69 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + E8FD97E01C81CCED00861B09 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 606F132220E1528D008903D6 /* hisat2_repeat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat2_repeat.cpp; sourceTree = ""; }; + 606F132320E1528D008903D6 /* hisat2_repeat_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat2_repeat_main.cpp; sourceTree = ""; }; + 60A82E9C21274F1B0040293D /* bit_packed_array.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bit_packed_array.cpp; sourceTree = ""; }; + 60A82E9D21274F1B0040293D /* bit_packed_array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bit_packed_array.h; sourceTree = ""; }; + E80538341DA83933008894D0 /* gp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gp.h; sourceTree = ""; }; + E84A236120D2AF0600C12106 /* repeat_builder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = repeat_builder.h; sourceTree = ""; }; + E84A236220D2AF1500C12106 /* repeat_builder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = repeat_builder.cpp; sourceTree = ""; }; + E8C30C5A1C20A5DD00C03464 /* hisat2x */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = hisat2x; sourceTree = BUILT_PRODUCTS_DIR; }; + E8C30C6A1C20A64A00C03464 /* hisat2-buildx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "hisat2-buildx"; sourceTree = BUILT_PRODUCTS_DIR; }; + E8C30C751C20A65400C03464 /* hisat2-inspectx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "hisat2-inspectx"; sourceTree = BUILT_PRODUCTS_DIR; }; + E8C30C7C1C20B2B600C03464 /* aligner_bt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_bt.h; sourceTree = ""; }; + E8C30C7D1C20B2B600C03464 /* aligner_cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_cache.h; sourceTree = ""; }; + E8C30C7E1C20B2B600C03464 /* aligner_driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_driver.h; sourceTree = ""; }; + E8C30C7F1C20B2B600C03464 /* aligner_metrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_metrics.h; sourceTree = ""; }; + E8C30C801C20B2B600C03464 /* aligner_report.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_report.h; sourceTree = ""; }; + E8C30C811C20B2B600C03464 /* aligner_result.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_result.h; sourceTree = ""; }; + E8C30C821C20B2B600C03464 /* aligner_seed_policy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_seed_policy.h; sourceTree = ""; }; + E8C30C831C20B2B600C03464 /* aligner_seed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_seed.h; sourceTree = ""; }; + E8C30C841C20B2B600C03464 /* aligner_seed2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_seed2.h; sourceTree = ""; }; + E8C30C851C20B2B600C03464 /* aligner_sw_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_sw_common.h; sourceTree = ""; }; + E8C30C861C20B2B600C03464 /* aligner_sw_driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_sw_driver.h; sourceTree = ""; }; + E8C30C871C20B2B600C03464 /* aligner_sw_nuc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_sw_nuc.h; sourceTree = ""; }; + E8C30C881C20B2B600C03464 /* aligner_sw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_sw.h; sourceTree = ""; }; + E8C30C891C20B2B600C03464 /* aligner_swsse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aligner_swsse.h; sourceTree = ""; }; + E8C30C8A1C20B2B600C03464 /* aln_sink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aln_sink.h; sourceTree = ""; }; + E8C30C8B1C20B2B600C03464 /* alphabet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alphabet.h; sourceTree = ""; }; + E8C30C8C1C20B2B600C03464 /* alt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alt.h; sourceTree = ""; }; + E8C30C8D1C20B2B600C03464 /* assert_helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = assert_helpers.h; sourceTree = ""; }; + E8C30C8E1C20B2B600C03464 /* banded.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = banded.h; sourceTree = ""; }; + E8C30C8F1C20B2B600C03464 /* binary_sa_search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = binary_sa_search.h; sourceTree = ""; }; + E8C30C901C20B2B600C03464 /* bitpack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitpack.h; sourceTree = ""; }; + E8C30C911C20B2B600C03464 /* blockwise_sa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blockwise_sa.h; sourceTree = ""; }; + E8C30C921C20B2B600C03464 /* bp_aligner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bp_aligner.h; sourceTree = ""; }; + E8C30C931C20B2B600C03464 /* btypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = btypes.h; sourceTree = ""; }; + E8C30C951C20B2B600C03464 /* diff_sample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = diff_sample.h; sourceTree = ""; }; + E8C30C961C20B2B600C03464 /* dp_framer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dp_framer.h; sourceTree = ""; }; + E8C30C971C20B2B600C03464 /* ds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ds.h; sourceTree = ""; }; + E8C30C981C20B2B600C03464 /* edit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = edit.h; sourceTree = ""; }; + E8C30C991C20B2B600C03464 /* endian_swap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endian_swap.h; sourceTree = ""; }; + E8C30C9A1C20B2B600C03464 /* fast_mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fast_mutex.h; sourceTree = ""; }; + E8C30C9B1C20B2B600C03464 /* filebuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filebuf.h; sourceTree = ""; }; + E8C30C9C1C20B2B600C03464 /* formats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = formats.h; sourceTree = ""; }; + E8C30C9D1C20B2B600C03464 /* gbwt_graph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gbwt_graph.h; sourceTree = ""; }; + E8C30C9E1C20B2B600C03464 /* gfm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfm.h; sourceTree = ""; }; + E8C30C9F1C20B2B600C03464 /* group_walk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = group_walk.h; sourceTree = ""; }; + E8C30CA01C20B2B600C03464 /* hgfm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hgfm.h; sourceTree = ""; }; + E8C30CA11C20B2B600C03464 /* hi_aligner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hi_aligner.h; sourceTree = ""; }; + E8C30CA21C20B2B600C03464 /* hier_idx_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hier_idx_common.h; sourceTree = ""; }; + E8C30CA31C20B2B600C03464 /* ival_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ival_list.h; sourceTree = ""; }; + E8C30CA41C20B2B600C03464 /* limit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = limit.h; sourceTree = ""; }; + E8C30CA51C20B2B600C03464 /* ls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ls.h; sourceTree = ""; }; + E8C30CA61C20B2B600C03464 /* mask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mask.h; sourceTree = ""; }; + E8C30CA71C20B2B600C03464 /* mem_ids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mem_ids.h; sourceTree = ""; }; + E8C30CA81C20B2B600C03464 /* mm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mm.h; sourceTree = ""; }; + E8C30CA91C20B2B600C03464 /* multikey_qsort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multikey_qsort.h; sourceTree = ""; }; + E8C30CAA1C20B2B600C03464 /* opts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opts.h; sourceTree = ""; }; + E8C30CAB1C20B2B600C03464 /* outq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = outq.h; sourceTree = ""; }; + E8C30CAC1C20B2B600C03464 /* pat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pat.h; sourceTree = ""; }; + E8C30CAD1C20B2B600C03464 /* pe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pe.h; sourceTree = ""; }; + E8C30CAE1C20B2B600C03464 /* presets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = presets.h; sourceTree = ""; }; + E8C30CAF1C20B2B600C03464 /* processor_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = processor_support.h; sourceTree = ""; }; + E8C30CB01C20B2B600C03464 /* qual.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = qual.h; sourceTree = ""; }; + E8C30CB11C20B2B600C03464 /* radix_sort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = radix_sort.h; sourceTree = ""; }; + E8C30CB21C20B2B600C03464 /* random_source.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = random_source.h; sourceTree = ""; }; + E8C30CB31C20B2B600C03464 /* random_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = random_util.h; sourceTree = ""; }; + E8C30CB41C20B2B600C03464 /* read.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = read.h; sourceTree = ""; }; + E8C30CB51C20B2B600C03464 /* ref_coord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ref_coord.h; sourceTree = ""; }; + E8C30CB61C20B2B600C03464 /* ref_read.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ref_read.h; sourceTree = ""; }; + E8C30CB71C20B2B600C03464 /* reference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reference.h; sourceTree = ""; }; + E8C30CB81C20B2B600C03464 /* sam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sam.h; sourceTree = ""; }; + E8C30CB91C20B2B600C03464 /* scoring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scoring.h; sourceTree = ""; }; + E8C30CBA1C20B2B600C03464 /* search_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = search_globals.h; sourceTree = ""; }; + E8C30CBB1C20B2B600C03464 /* sequence_io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sequence_io.h; sourceTree = ""; }; + E8C30CBC1C20B2B600C03464 /* shmem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shmem.h; sourceTree = ""; }; + E8C30CBD1C20B2B600C03464 /* simple_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simple_func.h; sourceTree = ""; }; + E8C30CBE1C20B2B600C03464 /* splice_site_mem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = splice_site_mem.h; sourceTree = ""; }; + E8C30CBF1C20B2B600C03464 /* splice_site.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = splice_site.h; sourceTree = ""; }; + E8C30CC01C20B2B600C03464 /* spliced_aligner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spliced_aligner.h; sourceTree = ""; }; + E8C30CC11C20B2B600C03464 /* sse_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sse_util.h; sourceTree = ""; }; + E8C30CC21C20B2B600C03464 /* sstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sstring.h; sourceTree = ""; }; + E8C30CC31C20B2B600C03464 /* str_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = str_util.h; sourceTree = ""; }; + E8C30CC41C20B2B600C03464 /* threading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threading.h; sourceTree = ""; }; + E8C30CC51C20B2B600C03464 /* timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timer.h; sourceTree = ""; }; + E8C30CC61C20B2B600C03464 /* tinythread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinythread.h; sourceTree = ""; }; + E8C30CC71C20B2B600C03464 /* tokenize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tokenize.h; sourceTree = ""; }; + E8C30CC81C20B2B600C03464 /* tp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tp.h; sourceTree = ""; }; + E8C30CC91C20B2B600C03464 /* unique.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unique.h; sourceTree = ""; }; + E8C30CCA1C20B2B600C03464 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; + E8C30CCB1C20B2B600C03464 /* word_io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = word_io.h; sourceTree = ""; }; + E8C30CCC1C20B2B600C03464 /* zbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zbox.h; sourceTree = ""; }; + E8C30CCD1C20B2B600C03464 /* aligner_bt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_bt.cpp; sourceTree = ""; }; + E8C30CCE1C20B2B600C03464 /* aligner_cache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_cache.cpp; sourceTree = ""; }; + E8C30CCF1C20B2B600C03464 /* aligner_driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_driver.cpp; sourceTree = ""; }; + E8C30CD01C20B2B600C03464 /* aligner_result.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_result.cpp; sourceTree = ""; }; + E8C30CD11C20B2B600C03464 /* aligner_seed_policy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_seed_policy.cpp; sourceTree = ""; }; + E8C30CD21C20B2B600C03464 /* aligner_seed.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_seed.cpp; sourceTree = ""; }; + E8C30CD31C20B2B600C03464 /* aligner_seed2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_seed2.cpp; sourceTree = ""; }; + E8C30CD41C20B2B600C03464 /* aligner_sw_driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_sw_driver.cpp; sourceTree = ""; }; + E8C30CD51C20B2B600C03464 /* aligner_sw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_sw.cpp; sourceTree = ""; }; + E8C30CD61C20B2B600C03464 /* aligner_swsse_ee_i16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_swsse_ee_i16.cpp; sourceTree = ""; }; + E8C30CD71C20B2B600C03464 /* aligner_swsse_ee_u8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_swsse_ee_u8.cpp; sourceTree = ""; }; + E8C30CD81C20B2B600C03464 /* aligner_swsse_loc_i16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_swsse_loc_i16.cpp; sourceTree = ""; }; + E8C30CD91C20B2B600C03464 /* aligner_swsse_loc_u8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_swsse_loc_u8.cpp; sourceTree = ""; }; + E8C30CDA1C20B2B600C03464 /* aligner_swsse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aligner_swsse.cpp; sourceTree = ""; }; + E8C30CDB1C20B2B600C03464 /* aln_sink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aln_sink.cpp; sourceTree = ""; }; + E8C30CDC1C20B2B600C03464 /* alphabet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = alphabet.cpp; sourceTree = ""; }; + E8C30CDD1C20B2B600C03464 /* banded.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = banded.cpp; sourceTree = ""; }; + E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ccnt_lut.cpp; sourceTree = ""; }; + E8C30CDF1C20B2B600C03464 /* diff_sample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = diff_sample.cpp; sourceTree = ""; }; + E8C30CE01C20B2B600C03464 /* dp_framer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dp_framer.cpp; sourceTree = ""; }; + E8C30CE11C20B2B600C03464 /* ds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ds.cpp; sourceTree = ""; }; + E8C30CE21C20B2B600C03464 /* edit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = edit.cpp; sourceTree = ""; }; + E8C30CE31C20B2B600C03464 /* gfm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gfm.cpp; sourceTree = ""; }; + E8C30CE41C20B2B600C03464 /* group_walk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = group_walk.cpp; sourceTree = ""; }; + E8C30CE51C20B2B600C03464 /* hisat_bp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat_bp.cpp; sourceTree = ""; }; + E8C30CE61C20B2B600C03464 /* hisat2_build_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat2_build_main.cpp; sourceTree = ""; }; + E8C30CE71C20B2B600C03464 /* hisat2_build.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat2_build.cpp; sourceTree = ""; }; + E8C30CE81C20B2B600C03464 /* hisat2_inspect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat2_inspect.cpp; sourceTree = ""; }; + E8C30CE91C20B2B600C03464 /* hisat2_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat2_main.cpp; sourceTree = ""; }; + E8C30CEA1C20B2B600C03464 /* hisat2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hisat2.cpp; sourceTree = ""; }; + E8C30CEB1C20B2B600C03464 /* ival_list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ival_list.cpp; sourceTree = ""; }; + E8C30CEC1C20B2B600C03464 /* limit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = limit.cpp; sourceTree = ""; }; + E8C30CED1C20B2B600C03464 /* ls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ls.cpp; sourceTree = ""; }; + E8C30CEE1C20B2B600C03464 /* mask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mask.cpp; sourceTree = ""; }; + E8C30CEF1C20B2B600C03464 /* multikey_qsort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multikey_qsort.cpp; sourceTree = ""; }; + E8C30CF01C20B2B600C03464 /* outq.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = outq.cpp; sourceTree = ""; }; + E8C30CF11C20B2B600C03464 /* pat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pat.cpp; sourceTree = ""; }; + E8C30CF21C20B2B600C03464 /* pe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pe.cpp; sourceTree = ""; }; + E8C30CF31C20B2B600C03464 /* presets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = presets.cpp; sourceTree = ""; }; + E8C30CF41C20B2B600C03464 /* qual.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = qual.cpp; sourceTree = ""; }; + E8C30CF51C20B2B600C03464 /* random_source.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = random_source.cpp; sourceTree = ""; }; + E8C30CF61C20B2B600C03464 /* random_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = random_util.cpp; sourceTree = ""; }; + E8C30CF71C20B2B600C03464 /* read_qseq.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = read_qseq.cpp; sourceTree = ""; }; + E8C30CF81C20B2B600C03464 /* ref_coord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ref_coord.cpp; sourceTree = ""; }; + E8C30CF91C20B2B600C03464 /* ref_read.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ref_read.cpp; sourceTree = ""; }; + E8C30CFA1C20B2B600C03464 /* reference.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reference.cpp; sourceTree = ""; }; + E8C30CFB1C20B2B600C03464 /* scoring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scoring.cpp; sourceTree = ""; }; + E8C30CFC1C20B2B600C03464 /* shmem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shmem.cpp; sourceTree = ""; }; + E8C30CFD1C20B2B600C03464 /* simple_func.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simple_func.cpp; sourceTree = ""; }; + E8C30CFE1C20B2B600C03464 /* splice_site_new.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = splice_site_new.cpp; sourceTree = ""; }; + E8C30CFF1C20B2B600C03464 /* splice_site.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = splice_site.cpp; sourceTree = ""; }; + E8C30D001C20B2B600C03464 /* sse_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sse_util.cpp; sourceTree = ""; }; + E8C30D011C20B2B600C03464 /* sstring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sstring.cpp; sourceTree = ""; }; + E8C30D021C20B2B600C03464 /* tinythread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinythread.cpp; sourceTree = ""; }; + E8C30D031C20B2B600C03464 /* unique.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unique.cpp; sourceTree = ""; }; + E8D9219620C85FE900378C5B /* hisat2-repeatx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "hisat2-repeatx"; sourceTree = BUILT_PRODUCTS_DIR; }; + E8D921A720CC37B300378C5B /* repeat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = repeat.h; sourceTree = ""; }; + E8E2A13C2118D082008F4EA4 /* repeat_kmer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = repeat_kmer.h; sourceTree = ""; }; + E8E2A13D2130695C008F4EA4 /* rfm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rfm.h; sourceTree = ""; }; + E8EAEDE71C24675500E62E69 /* hisat2-buildlx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "hisat2-buildlx"; sourceTree = BUILT_PRODUCTS_DIR; }; + E8FD97E41C81CCED00861B09 /* hisat2lx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = hisat2lx; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E8C30C571C20A5DD00C03464 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8C30C671C20A64A00C03464 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8C30C721C20A65400C03464 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8D9219120C85FE900378C5B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8EAEDE21C24675500E62E69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8FD97DF1C81CCED00861B09 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E8C30C511C20A5DD00C03464 = { + isa = PBXGroup; + children = ( + E8C30C651C20A61400C03464 /* Document */, + E8C30C641C20A60F00C03464 /* Source */, + E8C30C5B1C20A5DD00C03464 /* Products */, + ); + sourceTree = ""; + }; + E8C30C5B1C20A5DD00C03464 /* Products */ = { + isa = PBXGroup; + children = ( + E8C30C5A1C20A5DD00C03464 /* hisat2x */, + E8C30C6A1C20A64A00C03464 /* hisat2-buildx */, + E8C30C751C20A65400C03464 /* hisat2-inspectx */, + E8EAEDE71C24675500E62E69 /* hisat2-buildlx */, + E8FD97E41C81CCED00861B09 /* hisat2lx */, + E8D9219620C85FE900378C5B /* hisat2-repeatx */, + ); + name = Products; + sourceTree = ""; + }; + E8C30C641C20A60F00C03464 /* Source */ = { + isa = PBXGroup; + children = ( + E8C30C7C1C20B2B600C03464 /* aligner_bt.h */, + E8C30C7D1C20B2B600C03464 /* aligner_cache.h */, + E8C30C7E1C20B2B600C03464 /* aligner_driver.h */, + E8C30C7F1C20B2B600C03464 /* aligner_metrics.h */, + E8C30C801C20B2B600C03464 /* aligner_report.h */, + E8C30C811C20B2B600C03464 /* aligner_result.h */, + E8C30C821C20B2B600C03464 /* aligner_seed_policy.h */, + E8C30C831C20B2B600C03464 /* aligner_seed.h */, + E8C30C841C20B2B600C03464 /* aligner_seed2.h */, + E8C30C851C20B2B600C03464 /* aligner_sw_common.h */, + E8C30C861C20B2B600C03464 /* aligner_sw_driver.h */, + E8C30C871C20B2B600C03464 /* aligner_sw_nuc.h */, + E8C30C881C20B2B600C03464 /* aligner_sw.h */, + E8C30C891C20B2B600C03464 /* aligner_swsse.h */, + E8C30C8A1C20B2B600C03464 /* aln_sink.h */, + E8C30C8B1C20B2B600C03464 /* alphabet.h */, + E8C30C8C1C20B2B600C03464 /* alt.h */, + E8C30C8D1C20B2B600C03464 /* assert_helpers.h */, + E8C30C8E1C20B2B600C03464 /* banded.h */, + E8C30C8F1C20B2B600C03464 /* binary_sa_search.h */, + 60A82E9D21274F1B0040293D /* bit_packed_array.h */, + E8C30C901C20B2B600C03464 /* bitpack.h */, + E8C30C911C20B2B600C03464 /* blockwise_sa.h */, + E8C30C921C20B2B600C03464 /* bp_aligner.h */, + E8C30C931C20B2B600C03464 /* btypes.h */, + E8C30C951C20B2B600C03464 /* diff_sample.h */, + E8C30C961C20B2B600C03464 /* dp_framer.h */, + E8C30C971C20B2B600C03464 /* ds.h */, + E8C30C981C20B2B600C03464 /* edit.h */, + E8C30C991C20B2B600C03464 /* endian_swap.h */, + E8C30C9A1C20B2B600C03464 /* fast_mutex.h */, + E8C30C9B1C20B2B600C03464 /* filebuf.h */, + E8C30C9C1C20B2B600C03464 /* formats.h */, + E8C30C9D1C20B2B600C03464 /* gbwt_graph.h */, + E8C30C9E1C20B2B600C03464 /* gfm.h */, + E80538341DA83933008894D0 /* gp.h */, + E8C30C9F1C20B2B600C03464 /* group_walk.h */, + E8C30CA01C20B2B600C03464 /* hgfm.h */, + E8C30CA11C20B2B600C03464 /* hi_aligner.h */, + E8C30CA21C20B2B600C03464 /* hier_idx_common.h */, + E8C30CA31C20B2B600C03464 /* ival_list.h */, + E8C30CA41C20B2B600C03464 /* limit.h */, + E8C30CA51C20B2B600C03464 /* ls.h */, + E8C30CA61C20B2B600C03464 /* mask.h */, + E8C30CA71C20B2B600C03464 /* mem_ids.h */, + E8C30CA81C20B2B600C03464 /* mm.h */, + E8C30CA91C20B2B600C03464 /* multikey_qsort.h */, + E8C30CAA1C20B2B600C03464 /* opts.h */, + E8C30CAB1C20B2B600C03464 /* outq.h */, + E8C30CAC1C20B2B600C03464 /* pat.h */, + E8C30CAD1C20B2B600C03464 /* pe.h */, + E8C30CAE1C20B2B600C03464 /* presets.h */, + E8C30CAF1C20B2B600C03464 /* processor_support.h */, + E8C30CB01C20B2B600C03464 /* qual.h */, + E8C30CB11C20B2B600C03464 /* radix_sort.h */, + E8C30CB21C20B2B600C03464 /* random_source.h */, + E8C30CB31C20B2B600C03464 /* random_util.h */, + E8C30CB41C20B2B600C03464 /* read.h */, + E8C30CB51C20B2B600C03464 /* ref_coord.h */, + E8C30CB61C20B2B600C03464 /* ref_read.h */, + E8C30CB71C20B2B600C03464 /* reference.h */, + E8D921A720CC37B300378C5B /* repeat.h */, + E84A236120D2AF0600C12106 /* repeat_builder.h */, + E8E2A13C2118D082008F4EA4 /* repeat_kmer.h */, + E8E2A13D2130695C008F4EA4 /* rfm.h */, + E8C30CB81C20B2B600C03464 /* sam.h */, + E8C30CB91C20B2B600C03464 /* scoring.h */, + E8C30CBA1C20B2B600C03464 /* search_globals.h */, + E8C30CBB1C20B2B600C03464 /* sequence_io.h */, + E8C30CBC1C20B2B600C03464 /* shmem.h */, + E8C30CBD1C20B2B600C03464 /* simple_func.h */, + E8C30CBE1C20B2B600C03464 /* splice_site_mem.h */, + E8C30CBF1C20B2B600C03464 /* splice_site.h */, + E8C30CC01C20B2B600C03464 /* spliced_aligner.h */, + E8C30CC11C20B2B600C03464 /* sse_util.h */, + E8C30CC21C20B2B600C03464 /* sstring.h */, + E8C30CC31C20B2B600C03464 /* str_util.h */, + E8C30CC41C20B2B600C03464 /* threading.h */, + E8C30CC51C20B2B600C03464 /* timer.h */, + E8C30CC61C20B2B600C03464 /* tinythread.h */, + E8C30CC71C20B2B600C03464 /* tokenize.h */, + E8C30CC81C20B2B600C03464 /* tp.h */, + E8C30CC91C20B2B600C03464 /* unique.h */, + E8C30CCA1C20B2B600C03464 /* util.h */, + E8C30CCB1C20B2B600C03464 /* word_io.h */, + E8C30CCC1C20B2B600C03464 /* zbox.h */, + E8C30CCD1C20B2B600C03464 /* aligner_bt.cpp */, + E8C30CCE1C20B2B600C03464 /* aligner_cache.cpp */, + E8C30CCF1C20B2B600C03464 /* aligner_driver.cpp */, + E8C30CD01C20B2B600C03464 /* aligner_result.cpp */, + E8C30CD11C20B2B600C03464 /* aligner_seed_policy.cpp */, + E8C30CD21C20B2B600C03464 /* aligner_seed.cpp */, + E8C30CD31C20B2B600C03464 /* aligner_seed2.cpp */, + E8C30CD41C20B2B600C03464 /* aligner_sw_driver.cpp */, + E8C30CD51C20B2B600C03464 /* aligner_sw.cpp */, + E8C30CD61C20B2B600C03464 /* aligner_swsse_ee_i16.cpp */, + E8C30CD71C20B2B600C03464 /* aligner_swsse_ee_u8.cpp */, + E8C30CD81C20B2B600C03464 /* aligner_swsse_loc_i16.cpp */, + E8C30CD91C20B2B600C03464 /* aligner_swsse_loc_u8.cpp */, + E8C30CDA1C20B2B600C03464 /* aligner_swsse.cpp */, + E8C30CDB1C20B2B600C03464 /* aln_sink.cpp */, + E8C30CDC1C20B2B600C03464 /* alphabet.cpp */, + E8C30CDD1C20B2B600C03464 /* banded.cpp */, + 60A82E9C21274F1B0040293D /* bit_packed_array.cpp */, + E8C30CDE1C20B2B600C03464 /* ccnt_lut.cpp */, + E8C30CDF1C20B2B600C03464 /* diff_sample.cpp */, + E8C30CE01C20B2B600C03464 /* dp_framer.cpp */, + E8C30CE11C20B2B600C03464 /* ds.cpp */, + E8C30CE21C20B2B600C03464 /* edit.cpp */, + E8C30CE31C20B2B600C03464 /* gfm.cpp */, + E8C30CE41C20B2B600C03464 /* group_walk.cpp */, + E8C30CE51C20B2B600C03464 /* hisat_bp.cpp */, + E8C30CE61C20B2B600C03464 /* hisat2_build_main.cpp */, + E8C30CE71C20B2B600C03464 /* hisat2_build.cpp */, + E8C30CE81C20B2B600C03464 /* hisat2_inspect.cpp */, + E8C30CE91C20B2B600C03464 /* hisat2_main.cpp */, + 606F132320E1528D008903D6 /* hisat2_repeat_main.cpp */, + 606F132220E1528D008903D6 /* hisat2_repeat.cpp */, + E8C30CEA1C20B2B600C03464 /* hisat2.cpp */, + E8C30CEB1C20B2B600C03464 /* ival_list.cpp */, + E8C30CEC1C20B2B600C03464 /* limit.cpp */, + E8C30CED1C20B2B600C03464 /* ls.cpp */, + E8C30CEE1C20B2B600C03464 /* mask.cpp */, + E8C30CEF1C20B2B600C03464 /* multikey_qsort.cpp */, + E8C30CF01C20B2B600C03464 /* outq.cpp */, + E8C30CF11C20B2B600C03464 /* pat.cpp */, + E8C30CF21C20B2B600C03464 /* pe.cpp */, + E8C30CF31C20B2B600C03464 /* presets.cpp */, + E8C30CF41C20B2B600C03464 /* qual.cpp */, + E8C30CF51C20B2B600C03464 /* random_source.cpp */, + E8C30CF61C20B2B600C03464 /* random_util.cpp */, + E8C30CF71C20B2B600C03464 /* read_qseq.cpp */, + E8C30CF81C20B2B600C03464 /* ref_coord.cpp */, + E8C30CF91C20B2B600C03464 /* ref_read.cpp */, + E8C30CFA1C20B2B600C03464 /* reference.cpp */, + E84A236220D2AF1500C12106 /* repeat_builder.cpp */, + E8C30CFB1C20B2B600C03464 /* scoring.cpp */, + E8C30CFC1C20B2B600C03464 /* shmem.cpp */, + E8C30CFD1C20B2B600C03464 /* simple_func.cpp */, + E8C30CFE1C20B2B600C03464 /* splice_site_new.cpp */, + E8C30CFF1C20B2B600C03464 /* splice_site.cpp */, + E8C30D001C20B2B600C03464 /* sse_util.cpp */, + E8C30D011C20B2B600C03464 /* sstring.cpp */, + E8C30D021C20B2B600C03464 /* tinythread.cpp */, + E8C30D031C20B2B600C03464 /* unique.cpp */, + ); + name = Source; + sourceTree = ""; + }; + E8C30C651C20A61400C03464 /* Document */ = { + isa = PBXGroup; + children = ( + ); + name = Document; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E8C30C591C20A5DD00C03464 /* hisat2x */ = { + isa = PBXNativeTarget; + buildConfigurationList = E8C30C611C20A5DD00C03464 /* Build configuration list for PBXNativeTarget "hisat2x" */; + buildPhases = ( + E8C30C561C20A5DD00C03464 /* Sources */, + E8C30C571C20A5DD00C03464 /* Frameworks */, + E8C30C581C20A5DD00C03464 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = hisat2x; + productName = hisat2; + productReference = E8C30C5A1C20A5DD00C03464 /* hisat2x */; + productType = "com.apple.product-type.tool"; + }; + E8C30C691C20A64A00C03464 /* hisat2-buildx */ = { + isa = PBXNativeTarget; + buildConfigurationList = E8C30C6E1C20A64A00C03464 /* Build configuration list for PBXNativeTarget "hisat2-buildx" */; + buildPhases = ( + E8C30C661C20A64A00C03464 /* Sources */, + E8C30C671C20A64A00C03464 /* Frameworks */, + E8C30C681C20A64A00C03464 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "hisat2-buildx"; + productName = "hisat2-buildx"; + productReference = E8C30C6A1C20A64A00C03464 /* hisat2-buildx */; + productType = "com.apple.product-type.tool"; + }; + E8C30C741C20A65400C03464 /* hisat2-inspectx */ = { + isa = PBXNativeTarget; + buildConfigurationList = E8C30C791C20A65400C03464 /* Build configuration list for PBXNativeTarget "hisat2-inspectx" */; + buildPhases = ( + E8C30C711C20A65400C03464 /* Sources */, + E8C30C721C20A65400C03464 /* Frameworks */, + E8C30C731C20A65400C03464 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "hisat2-inspectx"; + productName = "hisat2-inspectx"; + productReference = E8C30C751C20A65400C03464 /* hisat2-inspectx */; + productType = "com.apple.product-type.tool"; + }; + E8D9218020C85FE900378C5B /* hisat2-repeatx */ = { + isa = PBXNativeTarget; + buildConfigurationList = E8D9219320C85FE900378C5B /* Build configuration list for PBXNativeTarget "hisat2-repeatx" */; + buildPhases = ( + E8D9218120C85FE900378C5B /* Sources */, + E8D9219120C85FE900378C5B /* Frameworks */, + E8D9219220C85FE900378C5B /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "hisat2-repeatx"; + productName = "hisat2-buildx"; + productReference = E8D9219620C85FE900378C5B /* hisat2-repeatx */; + productType = "com.apple.product-type.tool"; + }; + E8EAEDD21C24675500E62E69 /* hisat2-buildlx */ = { + isa = PBXNativeTarget; + buildConfigurationList = E8EAEDE41C24675500E62E69 /* Build configuration list for PBXNativeTarget "hisat2-buildlx" */; + buildPhases = ( + E8EAEDD31C24675500E62E69 /* Sources */, + E8EAEDE21C24675500E62E69 /* Frameworks */, + E8EAEDE31C24675500E62E69 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "hisat2-buildlx"; + productName = "hisat2-buildx"; + productReference = E8EAEDE71C24675500E62E69 /* hisat2-buildlx */; + productType = "com.apple.product-type.tool"; + }; + E8FD97B21C81CCED00861B09 /* hisat2lx */ = { + isa = PBXNativeTarget; + buildConfigurationList = E8FD97E11C81CCED00861B09 /* Build configuration list for PBXNativeTarget "hisat2lx" */; + buildPhases = ( + E8FD97B31C81CCED00861B09 /* Sources */, + E8FD97DF1C81CCED00861B09 /* Frameworks */, + E8FD97E01C81CCED00861B09 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = hisat2lx; + productName = hisat2; + productReference = E8FD97E41C81CCED00861B09 /* hisat2lx */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E8C30C521C20A5DD00C03464 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "Daehwan Kim"; + TargetAttributes = { + E8C30C591C20A5DD00C03464 = { + CreatedOnToolsVersion = 7.2; + }; + E8C30C691C20A64A00C03464 = { + CreatedOnToolsVersion = 7.2; + }; + E8C30C741C20A65400C03464 = { + CreatedOnToolsVersion = 7.2; + }; + }; + }; + buildConfigurationList = E8C30C551C20A5DD00C03464 /* Build configuration list for PBXProject "hisat2" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E8C30C511C20A5DD00C03464; + productRefGroup = E8C30C5B1C20A5DD00C03464 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E8C30C591C20A5DD00C03464 /* hisat2x */, + E8C30C691C20A64A00C03464 /* hisat2-buildx */, + E8C30C741C20A65400C03464 /* hisat2-inspectx */, + E8EAEDD21C24675500E62E69 /* hisat2-buildlx */, + E8FD97B21C81CCED00861B09 /* hisat2lx */, + E8D9218020C85FE900378C5B /* hisat2-repeatx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + E8C30C561C20A5DD00C03464 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E8EAEE201C24899300E62E69 /* ref_read.cpp in Sources */, + E8EAEE1F1C24896600E62E69 /* reference.cpp in Sources */, + E8EAEE1E1C24894300E62E69 /* tinythread.cpp in Sources */, + E8EAEE1D1C24892B00E62E69 /* gfm.cpp in Sources */, + E8EAEE1C1C24891800E62E69 /* alphabet.cpp in Sources */, + E8EAEE1B1C2488EA00E62E69 /* edit.cpp in Sources */, + E8EAEE1A1C2488D600E62E69 /* limit.cpp in Sources */, + E8EAEE191C2488AF00E62E69 /* ds.cpp in Sources */, + E8EAEE181C24886400E62E69 /* ccnt_lut.cpp in Sources */, + E8EAEE171C2487FF00E62E69 /* diff_sample.cpp in Sources */, + E8EAEE151C246EFC00E62E69 /* aligner_driver.cpp in Sources */, + E8EAEE161C246EFC00E62E69 /* splice_site.cpp in Sources */, + E8EAEE0A1C246EE900E62E69 /* aligner_bt.cpp in Sources */, + E8EAEE0B1C246EE900E62E69 /* aligner_swsse_ee_i16.cpp in Sources */, + E8EAEE0C1C246EE900E62E69 /* aligner_swsse_ee_u8.cpp in Sources */, + E8EAEE0D1C246EE900E62E69 /* aligner_swsse_loc_i16.cpp in Sources */, + E8EAEE0E1C246EE900E62E69 /* aligner_swsse_loc_u8.cpp in Sources */, + E8EAEE0F1C246EE900E62E69 /* aligner_swsse.cpp in Sources */, + E8EAEE101C246EE900E62E69 /* outq.cpp in Sources */, + E8EAEE111C246EE900E62E69 /* random_source.cpp in Sources */, + E8EAEE121C246EE900E62E69 /* random_util.cpp in Sources */, + E8EAEE131C246EE900E62E69 /* simple_func.cpp in Sources */, + E8EAEE141C246EE900E62E69 /* sse_util.cpp in Sources */, + E8EAEE011C246EB200E62E69 /* aligner_result.cpp in Sources */, + E8EAEE021C246EB200E62E69 /* aln_sink.cpp in Sources */, + E8EAEE031C246EB200E62E69 /* dp_framer.cpp in Sources */, + E8EAEE041C246EB200E62E69 /* mask.cpp in Sources */, + E8EAEE051C246EB200E62E69 /* pe.cpp in Sources */, + E8EAEE061C246EB200E62E69 /* presets.cpp in Sources */, + E8EAEE071C246EB200E62E69 /* ref_coord.cpp in Sources */, + E8EAEE081C246EB200E62E69 /* scoring.cpp in Sources */, + E8EAEE091C246EB200E62E69 /* unique.cpp in Sources */, + E8EAEDFA1C246E5100E62E69 /* aligner_cache.cpp in Sources */, + E8EAEDFB1C246E5100E62E69 /* aligner_seed_policy.cpp in Sources */, + E8EAEDFC1C246E5100E62E69 /* aligner_seed.cpp in Sources */, + E8EAEDFD1C246E5100E62E69 /* aligner_seed2.cpp in Sources */, + E8EAEDFE1C246E5100E62E69 /* aligner_sw_driver.cpp in Sources */, + E8EAEDFF1C246E5100E62E69 /* aligner_sw.cpp in Sources */, + E8EAEE001C246E5100E62E69 /* read_qseq.cpp in Sources */, + E8EAEDF61C246E3100E62E69 /* hisat2_main.cpp in Sources */, + E8EAEDF71C246E3100E62E69 /* hisat2.cpp in Sources */, + E8EAEDF81C246E3100E62E69 /* pat.cpp in Sources */, + E8EAEDF91C246E3100E62E69 /* qual.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8C30C661C20A64A00C03464 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E8EAEDE81C246CDC00E62E69 /* diff_sample.cpp in Sources */, + E8EAEDD01C24667700E62E69 /* hisat2_build_main.cpp in Sources */, + E8EAEDD11C24667700E62E69 /* hisat2_build.cpp in Sources */, + E8EAEDCC1C24666400E62E69 /* limit.cpp in Sources */, + E8EAEDCD1C24666400E62E69 /* multikey_qsort.cpp in Sources */, + E8EAEDCE1C24666400E62E69 /* random_source.cpp in Sources */, + E8EAEDCF1C24666400E62E69 /* tinythread.cpp in Sources */, + E8EAEDC41C24663D00E62E69 /* alphabet.cpp in Sources */, + E8EAEDC51C24663D00E62E69 /* ccnt_lut.cpp in Sources */, + E8EAEDC61C24663D00E62E69 /* ds.cpp in Sources */, + E8EAEDC71C24663D00E62E69 /* edit.cpp in Sources */, + E8EAEDC81C24663D00E62E69 /* gfm.cpp in Sources */, + E8EAEDC91C24663D00E62E69 /* ref_read.cpp in Sources */, + E8EAEDCA1C24663D00E62E69 /* reference.cpp in Sources */, + E8EAEDCB1C24663D00E62E69 /* shmem.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8C30C711C20A65400C03464 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E8EAEDF21C246DB200E62E69 /* hisat2_inspect.cpp in Sources */, + E8EAEDF31C246DB200E62E69 /* limit.cpp in Sources */, + E8EAEDF41C246DB200E62E69 /* random_source.cpp in Sources */, + E8EAEDF51C246DB200E62E69 /* tinythread.cpp in Sources */, + E8EAEDE91C246DA200E62E69 /* alphabet.cpp in Sources */, + E8EAEDEA1C246DA200E62E69 /* ccnt_lut.cpp in Sources */, + E8EAEDEB1C246DA200E62E69 /* ds.cpp in Sources */, + E8EAEDEC1C246DA200E62E69 /* edit.cpp in Sources */, + E8EAEDED1C246DA200E62E69 /* gfm.cpp in Sources */, + E8EAEDEE1C246DA200E62E69 /* multikey_qsort.cpp in Sources */, + E8EAEDEF1C246DA200E62E69 /* ref_read.cpp in Sources */, + E8EAEDF01C246DA200E62E69 /* reference.cpp in Sources */, + E8EAEDF11C246DA200E62E69 /* shmem.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8D9218120C85FE900378C5B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E8D921A620C879AB00378C5B /* mask.cpp in Sources */, + E8D921A520C8798500378C5B /* qual.cpp in Sources */, + E8D921A420C8794400378C5B /* aligner_bt.cpp in Sources */, + E8D921A220C8791000378C5B /* scoring.cpp in Sources */, + E8D921A320C8791000378C5B /* simple_func.cpp in Sources */, + 60A82E9E21274F1B0040293D /* bit_packed_array.cpp in Sources */, + E8D921A120C878EC00378C5B /* dp_framer.cpp in Sources */, + E8D9219920C878B700378C5B /* aligner_result.cpp in Sources */, + E8D9219A20C878B700378C5B /* aligner_sw_driver.cpp in Sources */, + E8D9219B20C878B700378C5B /* aligner_sw.cpp in Sources */, + E8D9219C20C878B700378C5B /* aligner_swsse_ee_i16.cpp in Sources */, + E8D9219D20C878B700378C5B /* aligner_swsse_ee_u8.cpp in Sources */, + E8D9219E20C878B700378C5B /* aligner_swsse_loc_i16.cpp in Sources */, + E8D9219F20C878B700378C5B /* aligner_swsse_loc_u8.cpp in Sources */, + E8D921A020C878B700378C5B /* aligner_swsse.cpp in Sources */, + E8D9218220C85FE900378C5B /* diff_sample.cpp in Sources */, + E8D9218520C85FE900378C5B /* limit.cpp in Sources */, + E8D9218620C85FE900378C5B /* multikey_qsort.cpp in Sources */, + E8D9218720C85FE900378C5B /* random_source.cpp in Sources */, + E8D9218820C85FE900378C5B /* tinythread.cpp in Sources */, + 606F132420E1528D008903D6 /* hisat2_repeat.cpp in Sources */, + 606F132520E1528D008903D6 /* hisat2_repeat_main.cpp in Sources */, + E8D9218920C85FE900378C5B /* alphabet.cpp in Sources */, + E8D9218A20C85FE900378C5B /* ccnt_lut.cpp in Sources */, + E8D9218B20C85FE900378C5B /* ds.cpp in Sources */, + E84A236320D2AF1600C12106 /* repeat_builder.cpp in Sources */, + E8D9218C20C85FE900378C5B /* edit.cpp in Sources */, + E8D9218D20C85FE900378C5B /* gfm.cpp in Sources */, + E8D9218E20C85FE900378C5B /* ref_read.cpp in Sources */, + E8D9218F20C85FE900378C5B /* reference.cpp in Sources */, + E8D9219020C85FE900378C5B /* shmem.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8EAEDD31C24675500E62E69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E8FD97E51C8343EF00861B09 /* diff_sample.cpp in Sources */, + E8EAEDD41C24675500E62E69 /* hisat2_build_main.cpp in Sources */, + E8EAEDD51C24675500E62E69 /* hisat2_build.cpp in Sources */, + E8EAEDD61C24675500E62E69 /* limit.cpp in Sources */, + E8EAEDD71C24675500E62E69 /* multikey_qsort.cpp in Sources */, + E8EAEDD81C24675500E62E69 /* random_source.cpp in Sources */, + E8EAEDD91C24675500E62E69 /* tinythread.cpp in Sources */, + E8EAEDDA1C24675500E62E69 /* alphabet.cpp in Sources */, + E8EAEDDB1C24675500E62E69 /* ccnt_lut.cpp in Sources */, + E8EAEDDC1C24675500E62E69 /* ds.cpp in Sources */, + E8EAEDDD1C24675500E62E69 /* edit.cpp in Sources */, + E8EAEDDE1C24675500E62E69 /* gfm.cpp in Sources */, + E8EAEDDF1C24675500E62E69 /* ref_read.cpp in Sources */, + E8EAEDE01C24675500E62E69 /* reference.cpp in Sources */, + E8EAEDE11C24675500E62E69 /* shmem.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E8FD97B31C81CCED00861B09 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E8FD97B41C81CCED00861B09 /* ref_read.cpp in Sources */, + E8FD97B51C81CCED00861B09 /* reference.cpp in Sources */, + E8FD97B61C81CCED00861B09 /* tinythread.cpp in Sources */, + E8FD97B71C81CCED00861B09 /* gfm.cpp in Sources */, + E8FD97B81C81CCED00861B09 /* alphabet.cpp in Sources */, + E8FD97B91C81CCED00861B09 /* edit.cpp in Sources */, + E8FD97BA1C81CCED00861B09 /* limit.cpp in Sources */, + E8FD97BB1C81CCED00861B09 /* ds.cpp in Sources */, + E8FD97BC1C81CCED00861B09 /* ccnt_lut.cpp in Sources */, + E8FD97BD1C81CCED00861B09 /* diff_sample.cpp in Sources */, + E8FD97BE1C81CCED00861B09 /* aligner_driver.cpp in Sources */, + E8FD97BF1C81CCED00861B09 /* splice_site.cpp in Sources */, + E8FD97C01C81CCED00861B09 /* aligner_bt.cpp in Sources */, + E8FD97C11C81CCED00861B09 /* aligner_swsse_ee_i16.cpp in Sources */, + E8FD97C21C81CCED00861B09 /* aligner_swsse_ee_u8.cpp in Sources */, + E8FD97C31C81CCED00861B09 /* aligner_swsse_loc_i16.cpp in Sources */, + E8FD97C41C81CCED00861B09 /* aligner_swsse_loc_u8.cpp in Sources */, + E8FD97C51C81CCED00861B09 /* aligner_swsse.cpp in Sources */, + E8FD97C61C81CCED00861B09 /* outq.cpp in Sources */, + E8FD97C71C81CCED00861B09 /* random_source.cpp in Sources */, + E8FD97C81C81CCED00861B09 /* random_util.cpp in Sources */, + E8FD97C91C81CCED00861B09 /* simple_func.cpp in Sources */, + E8FD97CA1C81CCED00861B09 /* sse_util.cpp in Sources */, + E8FD97CB1C81CCED00861B09 /* aligner_result.cpp in Sources */, + E8FD97CC1C81CCED00861B09 /* aln_sink.cpp in Sources */, + E8FD97CD1C81CCED00861B09 /* dp_framer.cpp in Sources */, + E8FD97CE1C81CCED00861B09 /* mask.cpp in Sources */, + E8FD97CF1C81CCED00861B09 /* pe.cpp in Sources */, + E8FD97D01C81CCED00861B09 /* presets.cpp in Sources */, + E8FD97D11C81CCED00861B09 /* ref_coord.cpp in Sources */, + E8FD97D21C81CCED00861B09 /* scoring.cpp in Sources */, + E8FD97D31C81CCED00861B09 /* unique.cpp in Sources */, + E8FD97D41C81CCED00861B09 /* aligner_cache.cpp in Sources */, + E8FD97D51C81CCED00861B09 /* aligner_seed_policy.cpp in Sources */, + E8FD97D61C81CCED00861B09 /* aligner_seed.cpp in Sources */, + E8FD97D71C81CCED00861B09 /* aligner_seed2.cpp in Sources */, + E8FD97D81C81CCED00861B09 /* aligner_sw_driver.cpp in Sources */, + E8FD97D91C81CCED00861B09 /* aligner_sw.cpp in Sources */, + E8FD97DA1C81CCED00861B09 /* read_qseq.cpp in Sources */, + E8FD97DB1C81CCED00861B09 /* hisat2_main.cpp in Sources */, + E8FD97DC1C81CCED00861B09 /* hisat2.cpp in Sources */, + E8FD97DD1C81CCED00861B09 /* pat.cpp in Sources */, + E8FD97DE1C81CCED00861B09 /* qual.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E8C30C5F1C20A5DD00C03464 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + BOWTIE_MM, + "MACOS=1", + POPCNT_CAPABILITY, + BOWTIE2, + "HISAT2_VERSION=\"\\\"2.2.0\\\"\"", + "HISAT2_VERSION2=\"\\\"`cat VERSION`\\\"\"", + "BUILD_HOST=\"\\\"`hostname`\\\"\"", + "BUILD_TIME=\"\\\"`date\\\"\"", + "COMPILER_VERSION=\"\\\"`$(CXX) -v 2>&1 | tail -1`\\\"\"", + "COMPILER_OPTIONS=\"\\\"test\\\"\"", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + E8C30C601C20A5DD00C03464 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + NDEBUG, + "DEBUG=0", + BOWTIE_MM, + "MACOS=1", + POPCNT_CAPABILITY, + BOWTIE2, + "HISAT2_VERSION=\"\\\"2.2.0\\\"\"", + "BUILD_HOST=\"\\\"`hostname`\\\"\"", + "BUILD_TIME=\"\\\"`date`\\\"\"", + "COMPILER_VERSION=\"\\\"`$(CXX) -v 2>&1 | tail -1`\\\"\"", + "COMPILER_OPTIONS=\"\\\"test\\\"\"", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + E8C30C621C20A5DD00C03464 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E8C30C631C20A5DD00C03464 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + E8C30C6F1C20A64A00C03464 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E8C30C701C20A64A00C03464 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + E8C30C7A1C20A65400C03464 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E8C30C7B1C20A65400C03464 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + E8D9219420C85FE900378C5B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + BOWTIE_MM, + "MACOS=1", + POPCNT_CAPABILITY, + BOWTIE2, + "HISAT2_VERSION=\"\\\"2.2.0\\\"\"", + "HISAT2_VERSION2=\"\\\"`cat VERSION`\\\"\"", + "BUILD_HOST=\"\\\"`hostname`\\\"\"", + "BUILD_TIME=\"\\\"`date\\\"\"", + "COMPILER_VERSION=\"\\\"`$(CXX) -v 2>&1 | tail -1`\\\"\"", + "COMPILER_OPTIONS=\"\\\"test\\\"\"", + DEBUGLOG, + BOWTIE_64BIT_INDEX, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E8D9219520C85FE900378C5B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + BOWTIE_64BIT_INDEX, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + E8EAEDE51C24675500E62E69 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + BOWTIE_64BIT_INDEX, + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E8EAEDE61C24675500E62E69 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=0", + BOWTIE_MM, + "MACOS=1", + POPCNT_CAPABILITY, + BOWTIE2, + BOWTIE_64BIT_INDEX, + "HISAT2_VERSION=\"\\\"`cat VERSION`\\\"\"", + "BUILD_HOST=\"\\\"`hostname`\\\"\"", + "BUILD_TIME=\"\\\"`date`\\\"\"", + "COMPILER_VERSION=\"\\\"`$(CXX) -v 2>&1 | tail -1`\\\"\"", + "COMPILER_OPTIONS=\"\\\"test\\\"\"", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + E8FD97E21C81CCED00861B09 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + BOWTIE_MM, + "MACOS=1", + POPCNT_CAPABILITY, + BOWTIE2, + "HISAT2_VERSION=\"\\\"2.0.2-beta\\\"\"", + "HISAT2_VERSION2=\"\\\"`cat VERSION`\\\"\"", + "BUILD_HOST=\"\\\"`hostname`\\\"\"", + "BUILD_TIME=\"\\\"`date\\\"\"", + "COMPILER_VERSION=\"\\\"`$(CXX) -v 2>&1 | tail -1`\\\"\"", + "COMPILER_OPTIONS=\"\\\"test\\\"\"", + BOWTIE_64BIT_INDEX, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E8FD97E31C81CCED00861B09 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=0", + BOWTIE_MM, + "MACOS=1", + POPCNT_CAPABILITY, + BOWTIE2, + "HISAT2_VERSION=\"\\\"2.2.0\\\"\"", + "BUILD_HOST=\"\\\"`hostname`\\\"\"", + "BUILD_TIME=\"\\\"`date`\\\"\"", + "COMPILER_VERSION=\"\\\"`$(CXX) -v 2>&1 | tail -1`\\\"\"", + "COMPILER_OPTIONS=\"\\\"test\\\"\"", + BOWTIE_64BIT_INDEX, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E8C30C551C20A5DD00C03464 /* Build configuration list for PBXProject "hisat2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E8C30C5F1C20A5DD00C03464 /* Debug */, + E8C30C601C20A5DD00C03464 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E8C30C611C20A5DD00C03464 /* Build configuration list for PBXNativeTarget "hisat2x" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E8C30C621C20A5DD00C03464 /* Debug */, + E8C30C631C20A5DD00C03464 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E8C30C6E1C20A64A00C03464 /* Build configuration list for PBXNativeTarget "hisat2-buildx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E8C30C6F1C20A64A00C03464 /* Debug */, + E8C30C701C20A64A00C03464 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E8C30C791C20A65400C03464 /* Build configuration list for PBXNativeTarget "hisat2-inspectx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E8C30C7A1C20A65400C03464 /* Debug */, + E8C30C7B1C20A65400C03464 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E8D9219320C85FE900378C5B /* Build configuration list for PBXNativeTarget "hisat2-repeatx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E8D9219420C85FE900378C5B /* Debug */, + E8D9219520C85FE900378C5B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E8EAEDE41C24675500E62E69 /* Build configuration list for PBXNativeTarget "hisat2-buildlx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E8EAEDE51C24675500E62E69 /* Debug */, + E8EAEDE61C24675500E62E69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E8FD97E11C81CCED00861B09 /* Build configuration list for PBXNativeTarget "hisat2lx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E8FD97E21C81CCED00861B09 /* Debug */, + E8FD97E31C81CCED00861B09 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E8C30C521C20A5DD00C03464 /* Project object */; +} diff --git a/hisat2_build.cpp b/hisat2_build.cpp new file mode 100644 index 0000000..4ea2976 --- /dev/null +++ b/hisat2_build.cpp @@ -0,0 +1,970 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include +#include +#include +#include +#include +#include "assert_helpers.h" +#include "endian_swap.h" +#include "formats.h" +#include "sequence_io.h" +#include "tokenize.h" +#include "timer.h" +#include "ref_read.h" +#include "filebuf.h" +#include "reference.h" +#include "ds.h" +#include "gfm.h" +#include "hgfm.h" +#include "rfm.h" +#include "utility_3n.h" + + +/** + * \file Driver for the bowtie-build indexing tool. + */ + +#include +#include +#include +#include +#include + +MemoryTally gMemTally; +// Build parameters +int verbose; +static int sanityCheck; +static int format; +static TIndexOffU bmax; +static TIndexOffU bmaxMultSqrt; +static uint32_t bmaxDivN; +static int dcv; +static int noDc; +static int entireSA; +static int seed; +static int showVersion; +// GFM parameters +static int32_t lineRate; +static bool lineRate_provided; +static int32_t linesPerSide; +static int32_t offRate; +static int32_t ftabChars; +static int32_t localOffRate; +static int32_t localFtabChars; +static int bigEndian; +static bool nsToAs; +static bool autoMem; +static bool packed; +static bool writeRef; +static bool justRef; +static bool reverseEach; +static int nthreads; // number of pthreads operating concurrently +static string wrapper; +static string snp_fname; +static string ht_fname; +static string ss_fname; +static string exon_fname; +static string sv_fname; +static string repeat_ref_fname; +static string repeat_info_fname; +static string repeat_snp_fname; +static string repeat_haplotype_fname; + +bool threeN = false; +bool repeatIndex = false; +bool base_change_entered; +char convertedFrom; +char convertedTo; +char convertedFromComplement; +char convertedToComplement; + +ConvertMatrix3N baseChange; + +static void resetOptions() { + verbose = true; // be talkative (default) + sanityCheck = 0; // do slow sanity checks + format = FASTA; // input sequence format + bmax = OFF_MASK; // max blockwise SA bucket size + bmaxMultSqrt = OFF_MASK; // same, as multplier of sqrt(n) + bmaxDivN = 4; // same, as divisor of n + dcv = 1024; // bwise SA difference-cover sample sz + noDc = 0; // disable difference-cover sample + entireSA = 0; // 1 = disable blockwise SA + seed = 0; // srandom seed + showVersion = 0; // just print version and quit? + // GFM parameters + lineRate = GFM::default_lineRate_gfm; + lineRate_provided = false; + linesPerSide = 1; // 1 64-byte line on a side + offRate = 4; // sample 1 out of 16 SA elts + ftabChars = 10; // 10 chars in initial lookup table + localOffRate = 3; + localFtabChars = 6; + bigEndian = 0; // little endian + nsToAs = false; // convert reference Ns to As prior to indexing + autoMem = true; // automatically adjust memory usage parameters + packed = false; // + writeRef = true; // write compact reference to .3.ht2/.4.ht2 + justRef = false; // *just* write compact reference, don't index + reverseEach = false; + nthreads = 1; + wrapper.clear(); + snp_fname = ""; + ht_fname = ""; + ss_fname = ""; + exon_fname = ""; + sv_fname = ""; + repeat_ref_fname = ""; + repeat_info_fname = ""; + repeat_snp_fname = ""; + repeat_haplotype_fname = ""; + threeN = false; + repeatIndex = false; + base_change_entered = false; + convertedFrom = 'C'; + convertedTo = 'T'; + convertedFromComplement = asc2dnacomp[convertedFrom]; + convertedToComplement = asc2dnacomp[convertedTo]; +} + +// Argument constants for getopts +enum { + ARG_BMAX = 256, + ARG_BMAX_MULT, + ARG_BMAX_DIV, + ARG_DCV, + ARG_SEED, + ARG_CUTOFF, + ARG_PMAP, + ARG_NTOA, + ARG_USAGE, + ARG_REVERSE_EACH, + ARG_SA, + ARG_WRAPPER, + ARG_LOCAL_OFFRATE, + ARG_LOCAL_FTABCHARS, + ARG_SNP, + ARG_HAPLOTYPE, + ARG_SPLICESITE, + ARG_EXON, + ARG_SV, + ARG_REPEAT_REF, + ARG_REPEAT_INFO, + ARG_REPEAT_SNP, + ARG_REPEAT_HAPLOTYPE, + ARG_3N, + ARG_REPEAT_INDEX, + ARG_BASE_CHANGE +}; + +/** + * Print a detailed usage message to the provided output stream. + */ +static void printUsage(ostream& out) { + out << "HISAT2 version " << string(HISAT2_VERSION).c_str() << " by Daehwan Kim (infphilo@gmail.com, http://www.ccb.jhu.edu/people/infphilo)" << endl; + +#ifdef BOWTIE_64BIT_INDEX + string tool_name = "hisat2-build-l"; +#else + string tool_name = "hisat2-build-s"; +#endif + if(wrapper == "basic-0") { + tool_name = "hisat2-build"; + } + + out << "Usage: hisat2-build [options]* " << endl + << " reference_in comma-separated list of files with ref sequences" << endl + << " hisat2_index_base write " << gfm_ext << " data to files with this dir/basename" << endl + << "Options:" << endl + << " -c reference sequences given on cmd line (as" << endl + << " )" << endl; + if(wrapper == "basic-0") { + out << " --large-index force generated index to be 'large', even if ref" << endl + << " has fewer than 4 billion nucleotides" << endl; + } + out << " -a/--noauto disable automatic -p/--bmax/--dcv memory-fitting" << endl + << " -p number of threads" << endl + << " --bmax max bucket sz for blockwise suffix-array builder" << endl + << " --bmaxdivn max bucket sz as divisor of ref len (default: 4)" << endl + << " --dcv diff-cover period for blockwise (default: 1024)" << endl + << " --nodc disable diff-cover (algorithm becomes quadratic)" << endl + << " -r/--noref don't build .3/.4.ht2 (packed reference) portion" << endl + << " -3/--justref just build .3/.4.ht2 (packed reference) portion" << endl + << " -o/--offrate SA is sampled every 2^offRate BWT chars (default: 5)" << endl + << " -t/--ftabchars # of chars consumed in initial lookup (default: 10)" << endl + << " --localoffrate SA (local) is sampled every 2^offRate BWT chars (default: 3)" << endl + << " --localftabchars # of chars consumed in initial lookup in a local index (default: 6)" << endl + << " --snp SNP file name" << endl + << " --haplotype haplotype file name" << endl + << " --ss Splice site file name" << endl + << " --exon Exon file name" << endl + << " --repeat-ref Repeat reference file name" << endl + << " --repeat-info Repeat information file name" << endl + << " --repeat-snp Repeat snp file name" << endl + << " --repeat-haplotype Repeat haplotype file name" << endl + << " --seed seed for random number generator" << endl + << " --base-change the converted nucleotide and converted to nucleotide (default:C,T)" << endl + << " --repeat-index-[,-] automatically build repeat database and repeat index, enter the minimum-maximum repeat length pairs (default: 100-300)" << endl + << " -q/--quiet disable verbose output (for debugging)" << endl + << " -h/--help print detailed description of tool and its options" << endl + << " --usage print this usage message" << endl + << " --version print version information and quit" << endl + ; + + if(wrapper.empty()) { + cerr << endl + << "*** Warning ***" << endl + << "'" << tool_name << "' was run directly. It is recommended " + << "that you run the wrapper script 'hisat2-build' instead." + << endl << endl; + } +} + +static const char *short_options = "qrap:h?nscfl:i:o:t:h:3C"; + +static struct option long_options[] = { + {(char*)"quiet", no_argument, 0, 'q'}, + {(char*)"sanity", no_argument, 0, 's'}, + {(char*)"threads", required_argument, 0, 'p'}, + {(char*)"little", no_argument, &bigEndian, 0}, + {(char*)"big", no_argument, &bigEndian, 1}, + {(char*)"bmax", required_argument, 0, ARG_BMAX}, + {(char*)"bmaxmultsqrt", required_argument, 0, ARG_BMAX_MULT}, + {(char*)"bmaxdivn", required_argument, 0, ARG_BMAX_DIV}, + {(char*)"dcv", required_argument, 0, ARG_DCV}, + {(char*)"nodc", no_argument, &noDc, 1}, + {(char*)"seed", required_argument, 0, ARG_SEED}, + {(char*)"entiresa", no_argument, &entireSA, 1}, + {(char*)"version", no_argument, &showVersion, 1}, + {(char*)"noauto", no_argument, 0, 'a'}, + {(char*)"noblocks", required_argument, 0, 'n'}, + {(char*)"linerate", required_argument, 0, 'l'}, + {(char*)"linesperside", required_argument, 0, 'i'}, + {(char*)"offrate", required_argument, 0, 'o'}, + {(char*)"ftabchars", required_argument, 0, 't'}, + {(char*)"localoffrate", required_argument, 0, ARG_LOCAL_OFFRATE}, + {(char*)"localftabchars", required_argument, 0, ARG_LOCAL_FTABCHARS}, + {(char*)"snp", required_argument, 0, ARG_SNP}, + {(char*)"haplotype", required_argument, 0, ARG_HAPLOTYPE}, + {(char*)"ss", required_argument, 0, ARG_SPLICESITE}, + {(char*)"exon", required_argument, 0, ARG_EXON}, + {(char*)"sv", required_argument, 0, ARG_SV}, + {(char*)"repeat-ref", required_argument, 0, ARG_REPEAT_REF}, + {(char*)"repeat-info", required_argument, 0, ARG_REPEAT_INFO}, + {(char*)"repeat-snp", required_argument, 0, ARG_REPEAT_SNP}, + {(char*)"repeat-haplotype", required_argument, 0, ARG_REPEAT_HAPLOTYPE}, + {(char*)"help", no_argument, 0, 'h'}, + {(char*)"ntoa", no_argument, 0, ARG_NTOA}, + {(char*)"justref", no_argument, 0, '3'}, + {(char*)"noref", no_argument, 0, 'r'}, + {(char*)"sa", no_argument, 0, ARG_SA}, + {(char*)"reverse-each", no_argument, 0, ARG_REVERSE_EACH}, + {(char*)"usage", no_argument, 0, ARG_USAGE}, + {(char*)"wrapper", required_argument, 0, ARG_WRAPPER}, + {(char*)"3N", no_argument, 0, ARG_3N}, + {(char*)"repeat-index", no_argument, 0, ARG_REPEAT_INDEX}, + {(char*)"base-change", required_argument, 0, ARG_BASE_CHANGE}, + {(char*)0, 0, 0, 0} // terminator +}; + +/** + * Parse an int out of optarg and enforce that it be at least 'lower'; + * if it is less than 'lower', then output the given error message and + * exit with an error and a usage message. + */ +template +static T parseNumber(T lower, const char *errmsg) { + char *endPtr= NULL; + T t = (T)strtoll(optarg, &endPtr, 10); + if (endPtr != NULL) { + if (t < lower) { + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + } + return t; + } + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + return -1; +} + +/** + * Read command-line arguments + */ +static void parseOptions(int argc, const char **argv) { + int option_index = 0; + int next_option; + do { + next_option = getopt_long( + argc, const_cast(argv), + short_options, long_options, &option_index); + switch (next_option) { + case ARG_WRAPPER: + wrapper = optarg; + break; + case 'f': format = FASTA; break; + case 'c': format = CMDLINE; break; + //case 'p': packed = true; break; + case 'C': + cerr << "Error: -C specified but Bowtie 2 does not support colorspace input." << endl; + throw 1; + break; + case 'l': + lineRate = parseNumber(3, "-l/--lineRate arg must be at least 3"); + lineRate_provided = true; + break; + case 'i': + linesPerSide = parseNumber(1, "-i/--linesPerSide arg must be at least 1"); + break; + case 'o': + offRate = parseNumber(0, "-o/--offRate arg must be at least 0"); + break; + case ARG_LOCAL_OFFRATE: + localOffRate = parseNumber(0, "-o/--localoffrate arg must be at least 0"); + break; + case '3': + justRef = true; + break; + case 't': + ftabChars = parseNumber(1, "-t/--ftabChars arg must be at least 1"); + break; + case ARG_LOCAL_FTABCHARS: + localFtabChars = parseNumber(1, "-t/--localftabchars arg must be at least 1"); + break; + case 'n': + // all f-s is used to mean "not set", so put 'e' on end + bmax = 0xfffffffe; + break; + case 'h': + case ARG_USAGE: + printUsage(cout); + throw 0; + break; + case ARG_SNP: + snp_fname = optarg; + break; + case ARG_HAPLOTYPE: + ht_fname = optarg; + break; + case ARG_SPLICESITE: + ss_fname = optarg; + break; + case ARG_EXON: + exon_fname = optarg; + break; + case ARG_SV: + sv_fname = optarg; + break; + case ARG_REPEAT_REF: + repeat_ref_fname = optarg; + break; + case ARG_REPEAT_INFO: + repeat_info_fname = optarg; + break; + case ARG_REPEAT_SNP: + repeat_snp_fname = optarg; + break; + case ARG_REPEAT_HAPLOTYPE: + repeat_haplotype_fname = optarg; + break; + case ARG_BMAX: + bmax = parseNumber(1, "--bmax arg must be at least 1"); + bmaxMultSqrt = OFF_MASK; // don't use multSqrt + bmaxDivN = 0xffffffff; // don't use multSqrt + break; + case ARG_BMAX_MULT: + bmaxMultSqrt = parseNumber(1, "--bmaxmultsqrt arg must be at least 1"); + bmax = OFF_MASK; // don't use bmax + bmaxDivN = 0xffffffff; // don't use multSqrt + break; + case ARG_BMAX_DIV: + bmaxDivN = parseNumber(1, "--bmaxdivn arg must be at least 1"); + bmax = OFF_MASK; // don't use bmax + bmaxMultSqrt = OFF_MASK; // don't use multSqrt + break; + case ARG_DCV: + dcv = parseNumber(3, "--dcv arg must be at least 3"); + break; + case ARG_SEED: + seed = parseNumber(0, "--seed arg must be at least 0"); + break; + case ARG_REVERSE_EACH: + reverseEach = true; + break; + case ARG_NTOA: nsToAs = true; break; + case ARG_3N: threeN = true; break; + case ARG_REPEAT_INDEX: repeatIndex = true; break; + case ARG_BASE_CHANGE: { + EList args; + tokenize(optarg, ",", args); + if(args.size() != 2) { + cerr << "Error: expected 2 comma-separated " + << "arguments to --base-change option, got " << args.size() << endl; + throw 1; + } + + getConversion(args[0][0], args[1][0], convertedFrom, convertedTo); + + string s = "ACGT"; + if ((s.find(convertedFrom) == std::string::npos) || (s.find(convertedTo) == std::string::npos)) { + cerr << "Please enter the nucleotide in 'ACGT' for --base-change option." << endl; + throw 1; + } + + if (convertedFrom == convertedTo) { + cerr << "Please enter two different base for --base-change option. If you wish to build index without nucleotide conversion, please use hisat2-build." << endl; + throw 1; + } + + base_change_entered = true; + } + case 'a': autoMem = false; break; + case 'q': verbose = false; break; + case 's': sanityCheck = true; break; + case 'r': writeRef = false; break; + case 'p': + nthreads = parseNumber(1, "-p arg must be at least 1"); + break; + + case -1: /* Done with options. */ + break; + case 0: + if (long_options[option_index].flag != 0) + break; + default: + printUsage(cerr); + throw 1; + } + } while(next_option != -1); + if(bmax < 40) { + cerr << "Warning: specified bmax is very small (" << bmax << "). This can lead to" << endl + << "extremely slow performance and memory exhaustion. Perhaps you meant to specify" << endl + << "a small --bmaxdivn?" << endl; + } +} + +EList filesWritten; + +/** + * Delete all the index files that we tried to create. For when we had to + * abort the index-building process due to an error. + */ +static void deleteIdxFiles( + const string& outfile, + bool doRef, + bool justRef) +{ + + for(size_t i = 0; i < filesWritten.size(); i++) { + cerr << "Deleting \"" << filesWritten[i].c_str() + << "\" file written during aborted indexing attempt." << endl; + remove(filesWritten[i].c_str()); + } +} + +extern void initializeCntLut(); +extern void initializeCntBit(); + + +/** + * Drive the index construction process and optionally sanity-check the + * result. + */ +template +static void driver( + const string& infile, + EList& infiles, + const string& snpfile, + const string& htfile, + const string& ssfile, + const string& exonfile, + const string& svfile, + const string& repeatfile, + const string& outfile, + bool packed, + int reverse, + bool localindex = true, + EList* parent_szs = NULL, + EList* parent_refnames = NULL, + EList* output_szs = NULL, + EList* output_refnames = NULL) +{ + initializeCntLut(); + initializeCntBit(); + EList is(MISC_CAT); + bool bisulfite = false; + bool repeat = parent_szs != NULL; + RefReadInParams refparams(false, reverse, nsToAs, bisulfite); + assert_gt(infiles.size(), 0); + if(format == CMDLINE) { + // Adapt sequence strings to stringstreams open for input + stringstream *ss = new stringstream(); + for(size_t i = 0; i < infiles.size(); i++) { + (*ss) << ">" << i << endl << infiles[i].c_str() << endl; + } + FileBuf *fb = new FileBuf(ss); + assert(fb != NULL); + assert(!fb->eof()); + assert(fb->get() == '>'); + ASSERT_ONLY(fb->reset()); + assert(!fb->eof()); + is.push_back(fb); + } else { + // Adapt sequence files to ifstreams + for(size_t i = 0; i < infiles.size(); i++) { + FILE *f = fopen(infiles[i].c_str(), "r"); + if (f == NULL) { + cerr << "Error: could not open "<< infiles[i].c_str() << endl; + throw 1; + } + FileBuf *fb = new FileBuf(f); + assert(fb != NULL); + if(fb->peek() == -1 || fb->eof()) { + cerr << "Warning: Empty fasta file: '" << infile.c_str() << "'" << endl; + continue; + } + assert(!fb->eof()); + assert(fb->get() == '>'); + ASSERT_ONLY(fb->reset()); + assert(!fb->eof()); + is.push_back(fb); + } + } + if(is.empty()) { + cerr << "Warning: All fasta inputs were empty" << endl; + throw 1; + } + filesWritten.push_back(outfile + ".1." + gfm_ext); + filesWritten.push_back(outfile + ".2." + gfm_ext); + // Vector for the ordered list of "records" comprising the input + // sequences. A record represents a stretch of unambiguous + // characters in one of the input sequences. + EList szs(MISC_CAT); + std::pair sztot; + { + if(verbose) cerr << "Reading reference sizes" << endl; + Timer _t(cerr, " Time reading reference sizes: ", verbose); + if(!reverse && (writeRef || justRef)) { + filesWritten.push_back(outfile + ".3." + gfm_ext); + filesWritten.push_back(outfile + ".4." + gfm_ext); + sztot = BitPairReference::szsFromFasta(is, outfile, bigEndian, refparams, szs, sanityCheck); + if (threeN) { + // save the unchanged reference in .3.ht2 and .4.ht2 + baseChange.restoreNormal(); + EList tmp_szs(MISC_CAT); + BitPairReference::szsFromFasta(is, outfile, bigEndian, refparams, tmp_szs, sanityCheck); + baseChange.restoreConversion(); + } + } else { + assert(false); + sztot = BitPairReference::szsFromFasta(is, string(), bigEndian, refparams, szs, sanityCheck); + } + } + if(justRef) return; + assert_gt(sztot.first, 0); + assert_gt(sztot.second, 0); + assert_gt(szs.size(), 0); + + // Construct index from input strings and parameters + filesWritten.push_back(outfile + ".5." + gfm_ext); + filesWritten.push_back(outfile + ".6." + gfm_ext); + filesWritten.push_back(outfile + ".7." + gfm_ext); + filesWritten.push_back(outfile + ".8." + gfm_ext); + TStr s; + GFM* gfm = NULL; + if(!repeat) { // base index + gfm = new HGFM( + s, + packed, + 1, // TODO: maybe not? + lineRate, + offRate, // suffix-array sampling rate + ftabChars, // number of chars in initial arrow-pair calc + localOffRate, + localFtabChars, + nthreads, + snpfile, + htfile, + ssfile, + exonfile, + svfile, + repeatfile, + outfile, // basename for .?.ht2 files + reverse == 0, // fw + !entireSA, // useBlockwise + bmax, // block size for blockwise SA builder + bmaxMultSqrt, // block size as multiplier of sqrt(len) + bmaxDivN, // block size as divisor of len + noDc? 0 : dcv,// difference-cover period + is, // list of input streams + szs, // list of reference sizes + (TIndexOffU)sztot.first, // total size of all unambiguous ref chars + refparams, // reference read-in parameters + localindex, // create local indexes? + parent_szs, // parent szs + parent_refnames, // parent refence names + seed, // pseudo-random number generator seed + -1, // override offRate + verbose, // be talkative + autoMem, // pass exceptions up to the toplevel so that we can adjust memory settings automatically + sanityCheck); // verify results and internal consistency + } else { // repeat index + gfm = new RFM( + s, + packed, + 1, // TODO: maybe not? + lineRate, + offRate, // suffix-array sampling rate + ftabChars, // number of chars in initial arrow-pair calc + localOffRate, + localFtabChars, + nthreads, + snpfile, + htfile, + ssfile, + exonfile, + svfile, + repeatfile, + outfile, // basename for .?.ht2 files + reverse == 0, // fw + !entireSA, // useBlockwise + bmax, // block size for blockwise SA builder + bmaxMultSqrt, // block size as multiplier of sqrt(len) + bmaxDivN, // block size as divisor of len + noDc? 0 : dcv,// difference-cover period + is, // list of input streams + szs, // list of reference sizes + (TIndexOffU)sztot.first, // total size of all unambiguous ref chars + refparams, // reference read-in parameters + localindex, // create local indexes? + parent_szs, // parent szs + parent_refnames, // parent refence names + seed, // pseudo-random number generator seed + -1, // override offRate + verbose, // be talkative + autoMem, // pass exceptions up to the toplevel so that we can adjust memory settings automatically + sanityCheck); // verify results and internal consistency + } + + if(output_szs != NULL) { + *output_szs = szs; + } + if(output_refnames != NULL) { + *output_refnames = gfm->_refnames_nospace; + } + + // Note that the Ebwt is *not* resident in memory at this time. To + // load it into memory, call ebwt.loadIntoMemory() + if(verbose) { + // Print Ebwt's vital stats + gfm->gh().print(cerr); + } + if(sanityCheck) { + // Try restoring the original string (if there were + // multiple texts, what we'll get back is the joined, + // padded string, not a list) + gfm->loadIntoMemory( + reverse ? (refparams.reverse == REF_READ_REVERSE) : 0, + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + false, + false); + SString s2; + gfm->restore(s2); + gfm->evictFromMemory(); + { + SString joinedss; + GFM<>::join >( + is, // list of input streams + szs, // list of reference sizes + (TIndexOffU)sztot.first, // total size of all unambiguous ref chars + refparams, // reference read-in parameters + seed, // pseudo-random number generator seed + joinedss); + if(refparams.reverse == REF_READ_REVERSE) { + joinedss.reverse(); + } + assert_eq(joinedss.length(), s2.length()); + assert(sstr_eq(joinedss, s2)); + } + if(verbose) { + if(s2.length() < 1000) { + cout << "Passed restore check: " << s2.toZBuf() << endl; + } else { + cout << "Passed restore check: (" << s2.length() << " chars)" << endl; + } + } + } + + delete gfm; +} + +static const char *argv0 = NULL; + +extern "C" { +/** + * main function. Parses command-line arguments. + */ +int hisat2_build(int argc, const char **argv) { + string outfile; + try { + // Reset all global state, including getopt state + opterr = optind = 1; + resetOptions(); + + string infile; + EList infiles(MISC_CAT); + + parseOptions(argc, argv); + argv0 = argv[0]; + if(showVersion) { + cout << argv0 << " version " << string(HISAT2_VERSION).c_str() << endl; + if(sizeof(void*) == 4) { + cout << "32-bit" << endl; + } else if(sizeof(void*) == 8) { + cout << "64-bit" << endl; + } else { + cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl; + } + cout << "Built on " << BUILD_HOST << endl; + cout << BUILD_TIME << endl; + cout << "Compiler: " << COMPILER_VERSION << endl; + cout << "Options: " << COMPILER_OPTIONS << endl; + cout << "Sizeof {int, long, long long, void*, size_t, off_t}: {" + << sizeof(int) + << ", " << sizeof(long) << ", " << sizeof(long long) + << ", " << sizeof(void *) << ", " << sizeof(size_t) + << ", " << sizeof(off_t) << "}" << endl; + return 0; + } + + if (!threeN && base_change_entered) { + cerr << "Please do not use --base-change for hisat2-build. To build hisat-3n index, please use hisat-3n-build." << endl; + printUsage(cerr); + throw 1; + } + if (threeN) { + convertedFromComplement = asc2dnacomp[convertedFrom]; + convertedToComplement = asc2dnacomp[convertedTo]; + } + // Get input filename + if(optind >= argc) { + cerr << "No input sequence or sequence file specified!" << endl; + printUsage(cerr); + return 1; + } + infile = argv[optind++]; + + // Get output filename + if(optind >= argc) { + cerr << "No output file specified!" << endl; + printUsage(cerr); + return 1; + } + outfile = argv[optind++]; + + tokenize(infile, ",", infiles); + if(infiles.size() < 1) { + cerr << "Tokenized input file list was empty!" << endl; + printUsage(cerr); + return 1; + } + + if(!lineRate_provided) { + if(snp_fname == "" && ss_fname == "" && exon_fname == "") { + lineRate = GFM::default_lineRate_fm; + } else { + lineRate = GFM::default_lineRate_gfm; + } + } + + // Optionally summarize + if(verbose) { + cerr << "Settings:" << endl + << " Output files: \"" << outfile.c_str() << (threeN?".3n":"") << ".*." << gfm_ext << "\"" << endl + << " Line rate: " << lineRate << " (line is " << (1< parent_szs(MISC_CAT); + EList parent_refnames; + string dummy_fname = ""; + + int nloop = threeN ? 2 : 1; // if threeN == true, nloop = 2. else one loop + for (int i = 0; i < nloop; i++) { + string tag = ""; + if (threeN) { + tag += ".3n."; + if (i == 0) { + tag += convertedFrom; + tag += convertedTo; + baseChange.convert(convertedFrom, convertedTo); + } else { + tag += convertedFromComplement; + tag += convertedToComplement; + baseChange.convert(convertedFromComplement, convertedToComplement); + } + + string indexFilename = outfile + tag + ".6.ht2"; + if (fileExist(indexFilename)) { + cerr << "*** Find index for " << outfile + tag << ",skip this index building process." << endl; + cerr << " To re-build your hisat-3n index, please delete the old index manually before running hisat-3n-build." << endl; + continue; + } + } + + driver >(infile, + infiles, + snp_fname, + ht_fname, + ss_fname, + exon_fname, + sv_fname, + dummy_fname, + outfile + tag, + false, + REF_READ_FORWARD, + true, // create local indexes + NULL, // no parent szs + NULL, // no parent refnames + &parent_szs, // get parent szs + &parent_refnames); // get parent refnames + + if(repeat_ref_fname.length() > 0) { + string repeat_ref_fname_3N; + string repeat_info_fname_3N; + if (threeN) { + repeat_ref_fname_3N = repeat_ref_fname + tag + ".rep.fa"; + repeat_info_fname_3N = repeat_info_fname + tag + ".rep.info"; + } + EList repeat_infiles(MISC_CAT); + tokenize(repeat_ref_fname_3N, ",", repeat_infiles); + driver >(repeat_ref_fname_3N, + repeat_infiles, + repeat_snp_fname, + repeat_haplotype_fname, + dummy_fname, + dummy_fname, + dummy_fname, + repeat_info_fname_3N, + outfile + tag + ".rep", + false, + REF_READ_FORWARD, + true, // create local index? + &parent_szs, + &parent_refnames); + } else if (repeatIndex) { + string repeat_ref_fname_3N = outfile + tag + ".rep.fa"; + string repeat_info_fname_3N = outfile + tag + ".rep.info"; + EList repeat_infiles(MISC_CAT); + tokenize(repeat_ref_fname_3N, ",", repeat_infiles); + driver >(repeat_ref_fname_3N, + repeat_infiles, + repeat_snp_fname, + repeat_haplotype_fname, + dummy_fname, + dummy_fname, + dummy_fname, + repeat_info_fname_3N, + outfile + tag + ".rep", + false, + REF_READ_FORWARD, + true, // create local index? + &parent_szs, + &parent_refnames); + } + } + } catch(bad_alloc& e) { + if(autoMem) { + cerr << "Switching to a packed string representation." << endl; + packed = true; + } else { + throw e; + } + } + } + return 0; + } catch(std::exception& e) { + cerr << "Error: Encountered exception: '" << e.what() << "'" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + deleteIdxFiles(outfile, writeRef || justRef, justRef); + return 1; + } catch(int e) { + if(e != 0) { + cerr << "Error: Encountered internal HISAT2 exception (#" << e << ")" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + } + deleteIdxFiles(outfile, writeRef || justRef, justRef); + return e; + } +} +} diff --git a/hisat2_build_main.cpp b/hisat2_build_main.cpp new file mode 100644 index 0000000..166814d --- /dev/null +++ b/hisat2_build_main.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include +#include +#include "tokenize.h" +#include "ds.h" +#include "mem_ids.h" + +using namespace std; + +extern "C" { + int hisat2_build(int argc, const char **argv); +} + +/** + * bowtie-build main function. It is placed in a separate source file + * to make it slightly easier to compile as a library. + * + * If the user specifies -A as the first two arguments, main + * will interpret that file as having one set of command-line arguments + * per line, and will dispatch each batch of arguments one at a time to + * bowtie-build. + */ +int main(int argc, const char **argv) { + if(argc > 2 && strcmp(argv[1], "-A") == 0) { + const char *file = argv[2]; + ifstream in; + in.open(file); + char buf[4096]; + int lastret = -1; + while(in.getline(buf, 4095)) { + EList args(MISC_CAT); + args.push_back(string(argv[0])); + tokenize(buf, " \t", args); + const char **myargs = (const char**)malloc(sizeof(char*)*args.size()); + for(size_t i = 0; i < args.size(); i++) { + myargs[i] = args[i].c_str(); + } + if(args.size() == 1) continue; + lastret = hisat2_build((int)args.size(), myargs); + free(myargs); + } + if(lastret == -1) { + cerr << "Warning: No arg strings parsed from " << file << endl; + return 0; + } + return lastret; + } else { + return hisat2_build(argc, argv); + } +} diff --git a/hisat2_extract_exons.py b/hisat2_extract_exons.py new file mode 100644 index 0000000..50602f2 --- /dev/null +++ b/hisat2_extract_exons.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 + +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +from sys import stderr, exit +from collections import defaultdict as dd, Counter +from argparse import ArgumentParser, FileType + + +def extract_exons(gtf_file, verbose = False): + genes = dd(list) + trans = {} + + # Parse valid exon lines from the GTF file into a dict by transcript_id + for line in gtf_file: + line = line.strip() + if not line or line.startswith('#'): + continue + if '#' in line: + line = line.split('#')[0].strip() + + try: + chrom, source, feature, left, right, score, \ + strand, frame, values = line.split('\t') + except ValueError: + continue + left, right = int(left), int(right) + + if feature != 'exon' or left >= right: + continue + + values_dict = {} + for attr in values.split(';')[:-1]: + attr, _, val = attr.strip().partition(' ') + values_dict[attr] = val.strip('"') + + if 'gene_id' not in values_dict or \ + 'transcript_id' not in values_dict: + continue + + transcript_id = values_dict['transcript_id'] + if transcript_id not in trans: + trans[transcript_id] = [chrom, strand, [[left, right]]] + genes[values_dict['gene_id']].append(transcript_id) + else: + trans[transcript_id][2].append([left, right]) + + # Sort exons and merge where separating introns are <=5 bps + for tran, [chrom, strand, exons] in trans.items(): + exons.sort() + tmp_exons = [exons[0]] + for i in range(1, len(exons)): + if exons[i][0] - tmp_exons[-1][1] <= 5: + tmp_exons[-1][1] = exons[i][1] + else: + tmp_exons.append(exons[i]) + trans[tran] = [chrom, strand, tmp_exons] + + # Calculate and print the unique junctions + tmp_exons = set() + for chrom, strand, texons in trans.values(): + for i in range(len(texons)): + tmp_exons.add((chrom, texons[i][0], texons[i][1], strand)) + tmp_exons = sorted(tmp_exons) + if len(tmp_exons) <= 0: + return + + exons = [tmp_exons[0]] + for exon in tmp_exons[1:]: + prev_exon = exons[-1] + if exon[0] != prev_exon[0]: + exons.append(exon) + continue + assert prev_exon[1] <= exon[1] + if prev_exon[2] < exon[1]: + exons.append(exon) + continue + + if prev_exon[2] < exon[2]: + strand = prev_exon[3] + if strand not in "+-": + strand = exon[3] + exons[-1] = (prev_exon[0], prev_exon[1], exon[2], strand) + + for chrom, left, right, strand in exons: + # Zero-based offset + print('{}\t{}\t{}\t{}'.format(chrom, left-1, right-1, strand)) + + # Print some stats if asked + if verbose: + None + """ + exon_lengths, intron_lengths, trans_lengths = \ + Counter(), Counter(), Counter() + for chrom, strand, exons in trans.values(): + tran_len = 0 + for i, exon in enumerate(exons): + exon_len = exon[1]-exon[0]+1 + exon_lengths[exon_len] += 1 + tran_len += exon_len + if i == 0: + continue + intron_lengths[exon[0] - exons[i-1][1]] += 1 + trans_lengths[tran_len] += 1 + + print('genes: {}, genes with multiple isoforms: {}'.format( + len(genes), sum(len(v) > 1 for v in genes.values())), + file=stderr) + print('transcripts: {}, transcript avg. length: {:d}'.format( + len(trans), sum(trans_lengths.elements())/len(trans)), + file=stderr) + print('exons: {}, exon avg. length: {:d}'.format( + sum(exon_lengths.values()), + sum(exon_lengths.elements())/sum(exon_lengths.values())), + file=stderr) + print('introns: {}, intron avg. length: {:d}'.format( + sum(intron_lengths.values()), + sum(intron_lengths.elements())/sum(intron_lengths.values())), + file=stderr) + print('average number of exons per transcript: {:d}'.format( + sum(exon_lengths.values())/len(trans)), + file=stderr) + """ + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Extract exons from a GTF file') + parser.add_argument('gtf_file', + nargs='?', + type=FileType('r'), + help='input GTF file (use "-" for stdin)') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + + args = parser.parse_args() + if not args.gtf_file: + parser.print_help() + exit(1) + extract_exons(args.gtf_file, args.verbose) diff --git a/hisat2_extract_snps_haplotypes_UCSC.py b/hisat2_extract_snps_haplotypes_UCSC.py new file mode 100644 index 0000000..820d127 --- /dev/null +++ b/hisat2_extract_snps_haplotypes_UCSC.py @@ -0,0 +1,578 @@ +#!/usr/bin/env python3 + +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + + +import sys, subprocess +import re +from argparse import ArgumentParser, FileType +from functools import cmp_to_key + + +""" +""" +def reverse_complement(seq): + result = "" + for nt in seq: + base = nt + if nt == 'A': + base = 'T' + elif nt == 'a': + base = 't' + elif nt == 'C': + base = 'G' + elif nt == 'c': + base = 'g' + elif nt == 'G': + base = 'C' + elif nt == 'g': + base = 'c' + elif nt == 'T': + base = 'A' + elif nt == 't': + base = 'a' + + result = base + result + + return result + + +""" +""" +def read_genome(genome_file): + chr_dic = {} + chr_name, sequence = "", "" + for line in genome_file: + if line.startswith(">"): + if chr_name and sequence: + chr_dic[chr_name] = sequence + chr_name = line.strip().split()[0][1:] + sequence = "" + else: + sequence += line.strip() + if chr_name and sequence: + chr_dic[chr_name] = sequence + return chr_dic + + +""" +Compare two variants [chr, pos, type, data, dic] +""" +def compare_vars(a, b): + a_chr, a_pos, a_type, a_data = a[:4] + b_chr, b_pos, b_type, b_data = b[:4] + + # daehwan - for debugging purposes + if a_chr != b_chr: + print(a) + print(b) + + assert a_chr == b_chr + if a_pos != b_pos: + return a_pos - b_pos + if a_type != b_type: + if a_type == 'I': + return -1 + elif b_type == 'I': + return 1 + if a_type == 'S': + return -1 + else: + return 1 + if a_data < b_data: + return -1 + elif a_data > b_data: + return 1 + else: + return 0 + + +""" +""" +def compatible_vars(a, b): + a_chr, a_pos, a_type, a_data = a[:4] + b_chr, b_pos, b_type, b_data = b[:4] + assert a_chr == b_chr + assert a_pos <= b_pos + if a_pos == b_pos: + return False + if a_type == 'D': + if b_pos <= a_pos + a_data: + return False + return True + + +""" +""" +def generate_haplotypes(snp_file, + haplotype_file, + vars, + inter_gap, + intra_gap, + num_haplotypes): + assert len(vars) > 0 + + # Sort variants and remove redundant variants + vars = sorted(vars, key=cmp_to_key(compare_vars)) + tmp_vars = [] + v = 0 + while v < len(vars): + var = vars[v] + for v2 in range(v + 1, len(vars)): + var2 = vars[v2] + if compare_vars(var, var2) == 0: + v += 1 + else: + assert compare_vars(var, var2) < 0 + break + tmp_vars.append(var) + v += 1 + vars = tmp_vars + + # Create new variant ID for variants with the same ID + # e.g. same two variant ID, rs60160543, are split into rs60160543.0 and rs60160543.1 + vars_count = {} + for var in vars: + id = var[4]["id"] + if id not in vars_count: + vars_count[id] = 0 + vars_count[id] += 1 + vars_duplicate = set() + for id, count in vars_count.items(): + if count <= 1: + continue + vars_duplicate.add(id) + vars_count = {} + for var in vars: + id = var[4]["id"] + if id not in vars_count: + vars_count[id] = 0 + else: + vars_count[id] += 1 + if id not in vars_duplicate: + var[4]["id2"] = id + else: + var[4]["id2"] = "%s.%d" % (id, vars_count[id]) + + # variant compatibility + vars_cmpt = [-1 for i in range(len(vars))] + for v in range(len(vars)): + var_chr, var_pos, var_type, var_data = vars[v][:4] + if var_type == 'D': + var_pos += (var_data - 1) + for v2 in range(v + 1, len(vars)): + if vars_cmpt[v2] >= 0: + continue + var2_chr, var2_pos = vars[v2][:2] + if var_chr != var2_chr: + break + if var_pos + inter_gap < var2_pos: + break + vars_cmpt[v2] = v + + # Assign genotypes for those missing genotypes + genotypes_list = [] + for v in range(len(vars)): + var = vars[v] + var_dic = var[4] + freq = var_dic["freq"] + used = [False for i in range(100)] + if vars_cmpt[v] >= 0: + v2 = v - 1 + while v2 >= vars_cmpt[v]: + var2 = vars[v2] + if not compatible_vars(var2, var) or \ + freq >= 0.1: + var2_dic = var2[4] + assert "genotype" in var2_dic + genotype_num = var2_dic["genotype"] + used[genotype_num] = True + v2 -= 1 + + assert False in used + for i in range(len(used)): + if not used[i]: + var_dic["genotype"] = i + break + genotypes_list.append(var_dic["genotype"]) + + # Write SNPs into a file (.snp) + for var in vars: + chr, pos, type, data, var_dic = var + varID = var_dic["id2"] + if type == 'S': + type = "single" + elif type == 'D': + type = "deletion" + else: + assert type == 'I' + type = "insertion" + print("%s\t%s\t%s\t%s\t%s" % (varID, type, chr, pos, data), + file=snp_file) + + # genotypes_list looks like + # Var0: 0 + # Var1: 0 + # Var2: 1 + # Var3: 2 + # Get haplotypes from genotypes_list + + max_genotype_num = max(genotypes_list) + haplotypes = ["" for i in range(max_genotype_num + 1)] + for i in range(len(genotypes_list)): + num = genotypes_list[i] + if haplotypes[num] == "": + haplotypes[num] = str(i) + else: + haplotypes[num] += ("#%d" % i) + haplotypes = set(haplotypes) + + # haplotypes look like + # '8#10#12#23', '8#12#23', '5#8#12#23#30' + + # Split some haplotypes that include large gaps inside + def split_haplotypes(haplotypes): + split_haplotypes = set() + for haplotype in haplotypes: + haplotype = haplotype.split('#') + assert len(haplotype) > 0 + if len(haplotype) == 1: + split_haplotypes.add(haplotype[0]) + continue + prev_s, s = 0, 1 + while s < len(haplotype): + _, prev_locus, prev_type, prev_data, _ = vars[int(haplotype[s-1])] + _, locus, type, data, _ = vars[int(haplotype[s])] + prev_locus, locus = int(prev_locus), int(locus) + if prev_type == 'D': + prev_locus += (int(prev_data) - 1) + if prev_locus + intra_gap < locus: + split_haplotypes.add('#'.join(haplotype[prev_s:s])) + prev_s = s + s += 1 + if s == len(haplotype): + split_haplotypes.add('#'.join(haplotype[prev_s:s])) + return split_haplotypes + + haplotypes2 = sorted(list(split_haplotypes(haplotypes))) + + def cmp_haplotype(a, b): + a = a.split('#') + _, a1_locus, _, _, _ = vars[int(a[0])] + _, a2_locus, a2_type, a2_data, _ = vars[int(a[-1])] + a_begin, a_end = int(a1_locus), int(a2_locus) + if a2_type == 'D': + a_end += (int(a2_data) - 1) + b = b.split('#') + _, b1_locus, _, _, _ = vars[int(b[0])] + _, b2_locus, b2_type, b2_data, _ = vars[int(b[-1])] + b_begin, b_end = int(b1_locus), int(b2_locus) + if b2_type == 'D': + b_end += (int(b2_data) - 1) + if a_begin != b_begin: + return a_begin - b_begin + return a_end - b_end + + haplotypes = sorted(list(haplotypes2), key=cmp_to_key(cmp_haplotype)) + + # Write haplotypes + for h_i in range(len(haplotypes)): + h = haplotypes[h_i].split('#') + chr, h1_locus, _, _, _ = vars[int(h[0])] + _, h2_locus, h2_type, h2_data, _ = vars[int(h[-1])] + h_begin, h_end = int(h1_locus), int(h2_locus) + if h2_type == 'D': + h_end += (int(h2_data) - 1) + assert h_begin <= h_end + h_new_begin = h_begin + for h_j in reversed(range(0, h_i)): + hc = haplotypes[h_j].split('#') + _, hc_begin, hc_type, hc_data, _ = vars[int(hc[-1])] + hc_begin = int(hc_begin) + hc_end = hc_begin + if hc_type == 'D': + hc_end += (int(hc_data) - 1) + if hc_end + inter_gap < h_begin: + break + if h_new_begin > hc_end: + h_new_begin = hc_end + assert h_new_begin <= h_begin + h_add = [] + for id in h: + var_dic = vars[int(id)][4] + h_add.append(var_dic["id2"]) + print("ht%d\t%s\t%d\t%d\t%s" % (num_haplotypes, chr, h_new_begin, h_end, ','.join(h_add)), + file=haplotype_file) + num_haplotypes += 1 + + return num_haplotypes + + +""" +""" +def main(genome_file, + snp_fname, + base_fname, + inter_gap, + intra_gap, + verbose, + testset): + # load genomic sequences + chr_dic = read_genome(genome_file) + + if testset: + ref_testset_file = open(base_fname + ".ref.testset.fa", "w") + alt_testset_file = open(base_fname + ".alt.testset.fa", "w") + + snp_out_file = open(base_fname + ".snp", 'w') + haplotype_out_file = open(base_fname + ".haplotype", 'w') + + # load SNPs + snp_list = [] + prev_chr, curr_right = "", -1 + num_haplotypes = 0 + if snp_fname.endswith(".gz"): + snp_cmd = ["gzip", "-cd", snp_fname] + else: + snp_cmd = ["cat", snp_fname] + snp_proc = subprocess.Popen(snp_cmd, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + ids_seen = set() + for line in snp_proc.stdout: + if not line or line.startswith('#'): + continue + + line = line.strip() + try: + fields = line.split('\t') + """ + id, chr, start, end, rs_id, score, strand, refNCBI, refUCSC, observed, molType, classType, valid, \ + avHet, avHetSE, func, locType, weight, exceptions, submitterCount, submitters, \ + alleleFreqCount, alleles, alleleNs, alleleFreqs, bitfields = fields + """ + id, chr, start, end, rs_id, score, strand, refNCBI, refUCSC, observed, molType, classType = fields[:12] + alleleFreqs = fields[-2].split(',')[:-1] + if len(alleleFreqs) > 0: + try: + float(alleleFreqs[0]) + except ValueError: + alleleFreqs = [] + except ValueError: + continue + + start, end = int(start), int(end) + score = int(score) + + if molType != "genomic": + continue + + if classType not in ["single", "deletion", "insertion"]: + continue + + if classType == "single": + if start + 1 != end: + continue + elif classType == "deletion": + assert start < end + else: + assert classType == "insertion" + if start != end: + continue + + if chr not in chr_dic: + continue + chr_seq = chr_dic[chr] + chr_len = len(chr_seq) + + if start >= len(chr_seq): + continue + + if rs_id in ids_seen: + continue + ids_seen.add(rs_id) + + if (prev_chr != chr or curr_right + inter_gap < start) and \ + len(snp_list) > 0: + num_haplotypes = generate_haplotypes(snp_out_file, + haplotype_out_file, + snp_list, + inter_gap, + intra_gap, + num_haplotypes) + snp_list = [] + + observed = observed.upper() + allele_list = observed.split("/") + if len(alleleFreqs) == 0: + alleleFreqs = [0.0 for i in range(len(allele_list))] + + # Reverse complement alleles if strand is negative + if strand == "-": + tmp_allele_list = [] + for allele in allele_list: + tmp_allele_list.append(reverse_complement(allele)) + allele_list = tmp_allele_list + + if classType == "single": + allele_count = min(len(allele_list), len(alleleFreqs)) + ref_base = chr_seq[start].upper() + if ref_base not in allele_list: + continue + for a in range(allele_count): + allele = allele_list[a] + freq = float(alleleFreqs[a]) + if allele not in "ACGT" or len(allele) != 1: + continue + if allele == ref_base: + continue + snp_list.append([chr, start, 'S', allele, {"id":rs_id, "freq":freq}]) + + if testset: + ref_seq = chr_seq[start-50:start+50] + alt_seq = chr_seq[start-50:start] + allele + chr_seq[start+1:start+50] + print(">%s_single_%d" % (rs_id, start - 50), file=ref_testset_file) + print(ref_seq, file=ref_testset_file) + print(">%s_single_%d_%s" % (rs_id, start - 50, ref_seq), file=alt_testset_file) + print(alt_seq, file=alt_testset_file) + + elif classType == "deletion": + if start > 0: + prev_base = chr_seq[start-1].upper() + if prev_base not in "ACGT": + continue + + if len(allele_list) != 2 or \ + len(allele_list) != len(alleleFreqs): + continue + + freq = 0.0 + if allele_list[0] == "-": + freq = float(alleleFreqs[1]) + else: + if allele_list[1] != "-": + continue + freq = float(alleleFreqs[0]) + + delLen = end - start + snp_list.append([chr, start, 'D', delLen, {"id":rs_id, "freq":freq}]) + if testset and delLen > 0 and delLen <= 10: + ref_seq = chr_seq[start-50:start+50] + alt_seq = chr_seq[start-50:start] + chr_seq[start+delLen:start+50+delLen] + print(">%s_deletion_%d" % (rs_id, start - 50), file=ref_testset_file) + print(ref_seq, file=ref_testset_file) + print(">%s_deletion_%d_%s" % (rs_id, start - 50, ref_seq), file=alt_testset_file) + print(alt_seq, file=alt_testset_file) + else: + assert classType == "insertion" + if start > 0: + prev_base = chr_seq[start-1].upper() + if prev_base not in "ACGT": + continue + allele_count = min(len(allele_list), len(alleleFreqs)) + for a in range(allele_count): + allele = allele_list[a] + freq = float(alleleFreqs[a]) + if allele == "-" or len(allele) <= 0: + continue + if re.match('^[ACGT]+$', allele): + snp_list.append([chr, start, 'I', allele, {"id":rs_id, "freq":freq}]) + insLen = len(allele) + if testset and insLen > 0 and insLen <= 10: + ref_seq = chr_seq[start-50:start+50] + alt_seq = chr_seq[start-50:start] + allele + chr_seq[start:start+50-insLen] + print(">%s_insertion_%d" % (rs_id, start - 50), file=ref_testset_file) + print(ref_seq, file=ref_testset_file) + print(">%s_insertion_%d_%s" % (rs_id, start - 50, ref_seq), file=alt_testset_file) + print(alt_seq, file=alt_testset_file) + + if curr_right < end: + curr_right = end + + if prev_chr != chr: + curr_right = end + prev_chr = chr + + if testset: + ref_testset_file.close() + alt_testset_file.close() + + if len(snp_list) > 0: + generate_haplotypes(snp_out_file, + haplotype_out_file, + snp_list, + inter_gap, + intra_gap, + num_haplotypes) + snp_list = [] + + snp_out_file.close() + haplotype_out_file.close() + + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Extract SNPs and haplotypes from a SNP file downloaded from UCSC (e.g. http://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/snp144.txt.gz)') + parser.add_argument('genome_file', + nargs='?', + type=FileType('r'), + help='input genome file (e.g. genome.fa)') + parser.add_argument('snp_fname', + nargs='?', + type=str, + help='input snp file downloaded from UCSC (plain text or gzipped file is accepted: snp144Common.txt or snp144Common.txt.gz)') + parser.add_argument("base_fname", + nargs='?', + type=str, + help="base filename for SNPs and haplotypes") + parser.add_argument("--inter-gap", + dest="inter_gap", + type=int, + default=30, + help="Maximum distance for variants to be in the same haplotype") + parser.add_argument("--intra-gap", + dest="intra_gap", + type=int, + default=50, + help="Break a haplotype into several haplotypes") + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + parser.add_argument('--testset', + dest='testset', + action='store_true', + help='print test reads') + + args = parser.parse_args() + if not args.genome_file or \ + not args.snp_fname or \ + not args.base_fname: + parser.print_help() + exit(1) + main(args.genome_file, + args.snp_fname, + args.base_fname, + args.inter_gap, + args.intra_gap, + args.verbose, + args.testset) diff --git a/hisat2_extract_snps_haplotypes_VCF.py b/hisat2_extract_snps_haplotypes_VCF.py new file mode 100644 index 0000000..2eb92a4 --- /dev/null +++ b/hisat2_extract_snps_haplotypes_VCF.py @@ -0,0 +1,923 @@ +#!/usr/bin/env python3 +# +# Copyright 2016, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + + +import sys, os, subprocess +from argparse import ArgumentParser, FileType +from functools import cmp_to_key + +digit2str = [str(i) for i in range(10)] + +""" +""" +def read_genome(genome_file): + chr_dic = {} + chr_name, sequence = "", "" + for line in genome_file: + if line.startswith(">"): + if chr_name and sequence: + chr_dic[chr_name] = sequence + chr_name = line.strip().split()[0][1:] + sequence = "" + else: + sequence += line.strip() + if chr_name and sequence: + chr_dic[chr_name] = sequence + return chr_dic + + +""" +Compare two variants [chr, pos, type, data, dic] +""" +def compare_vars(a, b): + a_chr, a_pos, a_type, a_data = a[:4] + b_chr, b_pos, b_type, b_data = b[:4] + assert a_chr == b_chr + if a_pos != b_pos: + return a_pos - b_pos + if a_type != b_type: + if a_type == 'I': + return -1 + elif b_type == 'I': + return 1 + if a_type == 'S': + return -1 + else: + return 1 + if a_data < b_data: + return -1 + elif a_data > b_data: + return 1 + else: + return 0 + + +""" +""" +def compatible_vars(a, b): + a_chr, a_pos, a_type, a_data = a[:4] + b_chr, b_pos, b_type, b_data = b[:4] + assert a_chr == b_chr + assert a_pos <= b_pos + + if a_pos == b_pos: + return False + if a_type == 'D': + if b_pos <= a_pos + a_data: + return False + return True + + +""" +Given a VCF line, the function reports a list of variants [pos, type, data] +type: 'S' for single nucleotide polymorphism, 'D' for deletion, and 'I' for insertion +""" +def extract_vars(chr_dic, chr, pos, ref_allele, alt_alleles, varID): + chr_seq = chr_dic[chr] + vars = [] + assert ',' not in ref_allele + alt_alleles = alt_alleles.split(',') + for a in range(len(alt_alleles)): + alt_allele = alt_allele2 = alt_alleles[a] + if 'N' in alt_allele: + continue + ref_allele2, pos2 = ref_allele, pos + + if chr_seq[pos:pos+len(ref_allele)] != ref_allele: + print("Error: the reference genome you provided seems to be incompatible with the VCF file at %d of chromosome %s where %s is in the reference genome while %s is in the VCF file" % (pos, chr, chr_seq[pos:pos+len(ref_allele)], ref_allele), file=sys.stderr) + + def warning_msg(): + print("Warning) ref allele (%s) and alt allele (%s in %s) at chr%s:%d are excluded." % \ + (ref_allele, alt_allele, ','.join(alt_alleles), chr, pos + 1), file=sys.stderr) + + min_len = min(len(ref_allele2), len(alt_allele2)) + if min_len >= 2: + if len(ref_allele2) != len(alt_allele2): + if ref_allele2[:min_len-1] != alt_allele2[:min_len-1]: + warning_msg() + continue + ref_allele2, alt_allele2 = ref_allele2[min_len-1:], alt_allele2[min_len-1:] + pos2 += (min_len - 1) + else: + if ref_allele2[1:] != alt_allele2[1:]: + warning_msg() + continue + ref_allele2, alt_allele2 = ref_allele2[0], alt_allele2[0] + + type, data = '', '' + if len(ref_allele2) == 1 and len(alt_allele2) == 1: + if ref_allele2 == alt_allele2: + warning_msg() + continue + type = 'S' + data = alt_allele2 + elif len(ref_allele2) == 1: + assert len(alt_allele2) > 1 + if ref_allele2[0] != alt_allele2[0]: + warning_msg() + continue + alt_allele2 = alt_allele2[1:] + pos2 += 1 + type = 'I' + data = alt_allele2 + if len(data) > 32: + continue + elif len(alt_allele2) == 1: + assert len(ref_allele2) > 1 + if ref_allele2[0] != alt_allele2[0]: + warning_msg() + continue + ref_allele2 = ref_allele2[1:] + pos2 += 1 + type = 'D' + data = len(ref_allele2) + else: + warning_msg() + continue + varID2 = varID + if len(alt_alleles) > 1: + varID2 = "%s.%d" % (varID, a) + vars.append([chr, pos2, type, data, {"id":varID, "id2":varID2}]) + + return vars + + +""" +""" +def generate_haplotypes(snp_file, + haplotype_file, + vars, + inter_gap, + intra_gap, + num_genomes, + num_haplotypes): + assert len(vars) > 0 + + # Sort variants and remove redundant variants + vars = sorted(vars, key=cmp_to_key(compare_vars)) + tmp_vars = [] + v = 0 + while v < len(vars): + var = vars[v] + for v2 in range(v + 1, len(vars)): + var2 = vars[v2] + if compare_vars(var, var2) == 0: + v += 1 + if "CLNSIG" not in var[4]: + if "CLNSIG" in var2[4]: + var[4]["CLNSIG"] = var2[4]["CLNSIG"] + if "genotype" not in var[4]: + if "genotype" in var2[4]: + var[4]["genotype"] = var2[4]["genotype"] + else: + assert compare_vars(var, var2) < 0 + break + tmp_vars.append(var) + v += 1 + vars = tmp_vars + + # Write SNPs into a file (.snp) + for var in vars: + chr, pos, type, data, var_dic = var + varID = var_dic["id2"] + if type == 'S': + type = "single" + elif type == 'D': + type = "deletion" + else: + assert type == 'I' + type = "insertion" + print("%s\t%s\t%s\t%s\t%s" % \ + (varID, type, chr, pos, data), file=snp_file) + + # variant compatibility + vars_cmpt = [-1 for i in range(len(vars))] + for v in range(len(vars)): + var_chr, var_pos, var_type, var_data = vars[v][:4] + if var_type == 'D': + var_pos += (var_data - 1) + for v2 in range(v + 1, len(vars)): + if vars_cmpt[v2] >= 0: + continue + var2_chr, var2_pos, var2_type = vars[v2][:3] + assert var_chr == var2_chr + if var_type == 'D' and var2_type == 'D': + if var_pos + 1 < var2_pos: + break + else: + if var_pos < var2_pos: + break + vars_cmpt[v2] = v + + # Assign genotypes for those missing genotypes + genotypes_list = [] + if num_genomes > 0: + max_genotype_num = 1 + for v in range(len(vars)): + var = vars[v] + var_dic = var[4] + if "genotype" not in var_dic: + used = [True, True] + [False for i in range(8)] + if vars_cmpt[v] >= 0: + v2 = v - 1 + while v2 >= vars_cmpt[v]: + var2 = vars[v2] + if not compatible_vars(var2, var): + var2_dic = var2[4] + assert "genotype" in var2_dic + genotype_num = int(var2_dic["genotype"][0]) + used[genotype_num] = True + v2 -= 1 + + assert False in used + for i in range(len(used)): + if not used[i]: + var_dic["genotype"] = ("%d" % i) * (num_genomes * 2) + if i > max_genotype_num: + max_genotype_num = i + break + genotypes_list.append(var_dic["genotype"]) + + num_chromosomes = len(genotypes_list[0]) + # daehwan - for debugging purposes + """ + for v in range(len(vars)): + var = vars[v] + var_chr, var_pos, var_type, var_data, var_dic = var + print v, var_chr, var_pos, var_type, var_data, var_dic["id"], var_dic["id2"], + if "CLNSIG" in var_dic: + print "CLNSIG:", var_dic["CLNSIG"], + if "genotype" in var_dic: + print var_dic["genotype"][:50], + print + """ + + # genotypes_list looks like + # Var0: 000001000 + # Var1: 010000000 + # Var2: 001100000 + # Var3: 222222222 + # Get haplotypes from genotypes_list + haplotypes = set() + cnv_genotypes = ["" for i in range(num_chromosomes)] + for genotypes in genotypes_list: + for i in range(len(genotypes)): + genotype = genotypes[i] + cnv_genotypes[i] += genotype + + cnv_genotypes = set(cnv_genotypes) + for raw_haplotype in cnv_genotypes: + for num in range(1, max_genotype_num + 1): + num_str = str(num) + if num_str not in raw_haplotype: + continue + haplotype = "" + for i in range(len(raw_haplotype)): + if raw_haplotype[i] == num_str: + if haplotype == "": + haplotype = str(i) + else: + haplotype += ("#%d" % i) + assert haplotype != "" + haplotypes.add(haplotype) + + else: + for v in range(len(vars)): + var = vars[v] + var_dic = var[4] + used = [False for i in range(100)] + if vars_cmpt[v] >= 0: + v2 = v - 1 + while v2 >= vars_cmpt[v]: + var2 = vars[v2] + if not compatible_vars(var2, var): + var2_dic = var2[4] + assert "genotype" in var2_dic + genotype_num = var2_dic["genotype"] + used[genotype_num] = True + v2 -= 1 + + assert False in used + for i in range(len(used)): + if not used[i]: + var_dic["genotype"] = i + break + genotypes_list.append(var_dic["genotype"]) + + # genotypes_list looks like + # Var0: 0 + # Var1: 0 + # Var2: 1 + # Var3: 2 + # Get haplotypes from genotypes_list + max_genotype_num = max(genotypes_list) + haplotypes = ["" for i in range(max_genotype_num + 1)] + for i in range(len(genotypes_list)): + num = genotypes_list[i] + if haplotypes[num] == "": + haplotypes[num] = str(i) + else: + haplotypes[num] += ("#%d" % i) + haplotypes = set(haplotypes) + + # haplotypes look like + # '8#10#12#23', '8#12#23', '5#8#12#23#30' + + # Split some haplotypes that include large gaps inside + def split_haplotypes(haplotypes): + split_haplotypes = set() + for haplotype in haplotypes: + haplotype = haplotype.split('#') + assert len(haplotype) > 0 + if len(haplotype) == 1: + split_haplotypes.add(haplotype[0]) + continue + prev_s, s = 0, 1 + while s < len(haplotype): + _, prev_locus, prev_type, prev_data, _ = vars[int(haplotype[s-1])] + _, locus, type, data, _ = vars[int(haplotype[s])] + prev_locus, locus = int(prev_locus), int(locus) + if prev_type == 'D': + prev_locus += (int(prev_data) - 1) + if prev_locus + intra_gap < locus: + split_haplotypes.add('#'.join(haplotype[prev_s:s])) + prev_s = s + s += 1 + if s == len(haplotype): + split_haplotypes.add('#'.join(haplotype[prev_s:s])) + return split_haplotypes + + haplotypes2 = sorted(list(split_haplotypes(haplotypes))) + + def cmp_haplotype(a, b): + a = a.split('#') + _, a1_locus, _, _, _ = vars[int(a[0])] + _, a2_locus, a2_type, a2_data, _ = vars[int(a[-1])] + a_begin, a_end = int(a1_locus), int(a2_locus) + if a2_type == 'D': + a_end += (int(a2_data) - 1) + b = b.split('#') + _, b1_locus, _, _, _ = vars[int(b[0])] + _, b2_locus, b2_type, b2_data, _ = vars[int(b[-1])] + b_begin, b_end = int(b1_locus), int(b2_locus) + if b2_type == 'D': + b_end += (int(b2_data) - 1) + if a_begin != b_begin: + return a_begin - b_begin + return a_end - b_end + + haplotypes = sorted(list(haplotypes2), key=cmp_to_key(cmp_haplotype)) + + # daehwan - for debugging purposes + """ + dis = prev_locus - locus + print "\n[%d, %d]: %d haplotypes" % (i, j, len(haplotypes)), dis + if len(cur_vars) in range(0, 1000): + # print "vars:", sorted(list(cur_vars), cmp=cmp_varKey + print "num:", len(haplotypes) + for haplotype in haplotypes: + print haplotype.split('#') + print "\nnum:", len(haplotypes2) + for haplotype in haplotypes2: + print haplotype.split('#') + """ + + # Write haplotypes + for h_i in range(len(haplotypes)): + h = haplotypes[h_i].split('#') + chr, h1_locus, _, _, _ = vars[int(h[0])] + _, h2_locus, h2_type, h2_data, _ = vars[int(h[-1])] + h_begin, h_end = int(h1_locus), int(h2_locus) + if h2_type == 'D': + h_end += (int(h2_data) - 1) + assert h_begin <= h_end + h_new_begin = h_begin + for h_j in reversed(range(0, h_i)): + hc = haplotypes[h_j].split('#') + _, hc_begin, hc_type, hc_data, _ = vars[int(hc[-1])] + hc_begin = int(hc_begin) + hc_end = hc_begin + if hc_type == 'D': + hc_end += (int(hc_data) - 1) + if hc_end + inter_gap < h_begin: + break + if h_new_begin > hc_end: + h_new_begin = hc_end + assert h_new_begin <= h_begin + h_add = [] + for id in h: + var_dic = vars[int(id)][4] + h_add.append(var_dic["id2"]) + print("ht%d\t%s\t%d\t%d\t%s" % \ + (num_haplotypes, chr, h_new_begin, h_end, ','.join(h_add)), file=haplotype_file) + num_haplotypes += 1 + + return num_haplotypes + + +""" +""" +def main(genome_file, + VCF_fnames, + base_fname, + inter_gap, + intra_gap, + only_rs, + reference_type, + genotype_vcf, + genotype_gene_list, + extra_files, + verbose): + # Load genomic sequences + chr_dic = read_genome(genome_file) + + # GRCh38 - ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502/supporting/GRCh38_positions + # ALL.chr22.phase3_shapeit2_mvncall_integrated_v3plus_nounphased.rsID.genotypes.GRCh38_dbSNP_no_SVs.vcf.gz + # GRCh37 - ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502 + # ALL.chr22.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz + + # List of variants (e.g. ClinVar database) + genotype_var_list = {} + # List of genomic regions to be processed + genotype_ranges = {} + if genotype_vcf != "": + var_set = set() + assert len(genotype_gene_list) > 0 + if genotype_vcf.endswith(".gz"): + vcf_cmd = ["gzip", "-cd", genotype_vcf] + else: + vcf_cmd = ["cat", genotype_vcf] + vcf_proc = subprocess.Popen(vcf_cmd, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + for line in vcf_proc.stdout: + if line.startswith("#"): + continue + + chr, pos, varID, ref_allele, alt_alleles, qual, filter, info = line.strip().split('\t') + pos = int(pos) - 1 + if chr not in chr_dic: + continue + + gene = None + for g in genotype_gene_list: + if info.find(g) != -1: + gene = g + break + if not gene: + continue + + CLNSIG = -1 + for item in info.split(';'): + if not item.startswith("CLNSIG"): + continue + try: + key, value = item.split('=') + CLNSIG = int(value) + except ValueError: + continue + if CLNSIG not in [4, 5]: + continue + if CLNSIG == 4: + CLNSIG = "Likely pathogenic" + else: + CLNSIG = "Pathogenic" + + vars = extract_vars(chr_dic, chr, pos, ref_allele, alt_alleles, varID) + if len(vars) == 0: + continue + + if chr not in genotype_var_list: + genotype_var_list[chr] = [] + genotype_ranges[chr] = {} + if gene not in genotype_ranges[chr]: + genotype_ranges[chr][gene] = [len(chr_dic[chr]), -1] + + for var in vars: + var_chr, var_pos, var_ref_allele, var_alt_allele = var[:4] + var_str = "%s-%d-%s-%s" % (var_chr, var_pos, var_ref_allele, var_alt_allele) + if var_str in var_set: + continue + var[4]["CLNSIG"] = CLNSIG + var[4]["gene"] = gene + + genotype_var_list[chr].append(var) + if var_pos < genotype_ranges[chr][gene][0]: + genotype_ranges[chr][gene][0] = var_pos + if var_pos > genotype_ranges[chr][gene][1]: + genotype_ranges[chr][gene][1] = var_pos + + var_set.add(var_str) + + print("Number of variants in %s is:" % (genotype_vcf), file=sys.stderr) + for chr, vars in genotype_var_list.items(): + vars = sorted(vars, cmp=compare_vars) + print("\tChromosome %s: %d variants" % (chr, len(vars)), file=sys.stderr) + + for chr, gene_ranges in genotype_ranges.items(): + for gene, value in gene_ranges.items(): + gene_ranges[gene] = [value[0] - 100, value[1] + 100] + value = genotype_ranges[chr][gene] + if verbose: + print("%s\t%s\t%d-%d" % (chr, gene, value[0], value[1]), file=sys.stderr) + + if extra_files or True: + clnsig_file = open("%s.clnsig" % base_fname, 'w') + for chr, vars in genotype_var_list.items(): + for var in vars: + varID = var[4]["id2"] + CLNSIG = var[4]["CLNSIG"] + gene = var[4]["gene"] + print("%s\t%s\t%s" % (varID, gene, CLNSIG), file=clnsig_file) + clnsig_file.close() + + SNP_file = open("%s.snp" % base_fname, 'w') + haplotype_file = open("%s.haplotype" % base_fname, 'w') + + # Write reference information and backbone sequences into files + if extra_files: + ref_file = open("%s.ref" % base_fname, 'w') + for chr, gene_ranges in genotype_ranges.items(): + for gene, value in gene_ranges.items(): + left, right = value + if reference_type == "gene": + left, right = 0, right - left + print("%s\t%s\t%d\t%d" % (gene, chr, left, right), file=ref_file) + ref_file.close() + + if reference_type == "gene": + backbone_file = open("%s_backbone.fa" % base_fname, 'w') + for chr, gene_ranges in genotype_ranges.items(): + for gene, value in gene_ranges.items(): + left, right = value + left, right = 0, right - left + print(">%s" % (gene), file=backbone_file) + backbone_seq = chr_dic[chr][value[0]:value[1]+1] + for s in range(0, len(backbone_seq), 60): + print(backbone_seq[s:s+60], file=backbone_file) + backbone_file.close() + elif reference_type == "chromosome": + first = True + for chr in genotype_ranges.keys(): + if first: + os.system("samtools faidx genome.fa %s > %s_backbone.fa" % (chr, base_fname)) + first = False + else: + os.system("samtools faidx genome.fa %s >> %s_backbone.fa" % (chr, base_fname)) + else: + assert reference_type == "genome" + os.system("cp genome.fa %s_backbone.fa" % base_fname) + + num_genomes = 0 + num_haplotypes = 0 + num_unassigned = 0 + unnamed_var_count = 0 + for VCF_fname in VCF_fnames: + empty_VCF_file = False + if VCF_fname == "/dev/null" or \ + not os.path.exists(VCF_fname): + empty_VCF_file = True + + if reference_type != "genome" and \ + len(genotype_gene_list) > 0: + continue + + if not empty_VCF_file: + if VCF_fname.endswith(".gz"): + vcf_cmd = ["gzip", "-cd", VCF_fname] + else: + vcf_cmd = ["cat", VCF_fname] + vcf_proc = subprocess.Popen(vcf_cmd, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + + genomeIDs = [] + vars, genotypes_list = [], [] + prev_varID, prev_chr, prev_pos = "", "", -1 + num_lines = 0 + for line in vcf_proc.stdout: + num_lines += 1 + if line.startswith("##"): + continue + + fields = line.strip().split('\t') + + chr, pos, varID, ref_allele, alt_alleles, qual, filter, info = fields[:8] + if prev_chr != chr: + curr_right = -1 + + if len(fields) >= 9: + format = fields[8] + + genotypes = [] + if len(fields) >= 10: + genotypes = fields[9:] + + if line.startswith("#"): + genomeIDs = genotypes + num_genomes = len(genomeIDs) + continue + + assert len(genotypes) == len(genomeIDs) + + if varID == ".": + unnamed_var_count += 1 + varID = "un%d" % unnamed_var_count + + if only_rs and not varID.startswith("rs"): + continue + + if ';' in varID: + continue + + if varID == prev_varID: + continue + + if chr not in chr_dic: + continue + + chr_seq = chr_dic[chr] + chr_genotype_vars = [] + chr_genotype_ranges = {} + if len(genotype_gene_list) > 0: + assert chr in genotype_var_list + chr_genotype_vars = genotype_var_list[chr] + assert chr in genotype_ranges + chr_genotype_ranges = genotype_ranges[chr] + + pos = int(pos) - 1 + offset = 0 + gene = None + if num_lines % 10000 == 1: + print("\t%s:%d\r" % (chr, pos), file=sys.stderr) + + if chr_genotype_ranges: + skip = True + for gene_, range_ in chr_genotype_ranges.items(): + if pos > range_[0] and pos < range_[1]: + skip = False + break + if skip: + continue + if len(vars) == 0: + for var in chr_genotype_vars: + var_chr, var_pos, var_type, var_data, var_dic = var + if var_pos < range_[0]: + continue + if var_pos > range_[1]: + break + if reference_type == "gene": + var_pos -= range_[0] + vars.append([gene_, var_pos, var_type, var_data, var_dic]) + curr_right = range_[1] + if reference_type == "gene": + offset = range_[0] + gene = gene_ + + if pos == prev_pos: + continue + + if len(vars) > 0 and \ + (curr_right + inter_gap < pos or prev_chr != chr): + num_haplotypes = generate_haplotypes(SNP_file, + haplotype_file, + vars, + inter_gap, + intra_gap, + num_genomes, + num_haplotypes) + vars = [] + + def add_vars(pos, + offset, + gene, + varID, + ref_allele, + alt_alleles, + vars, + genotypes): + tmp_vars = extract_vars(chr_dic, chr, pos, ref_allele, alt_alleles, varID) + max_right = -1 + for v in range(len(tmp_vars)): + var = tmp_vars[v] + _, pos2, type, data = var[:4] + cnv_genotypes = [] + for genotype in genotypes: + P1, P2 = genotype[0], genotype[2] + if P1 == digit2str[v + 1]: + cnv_genotypes.append('1') + else: + cnv_genotypes.append('0') + if P2 == digit2str[v + 1]: + cnv_genotypes.append('1') + else: + cnv_genotypes.append('0') + + # Skip SNPs not present in a given population (e.g. 2,504 genomes in 1000 Genomes Project) + if cnv_genotypes != [] and \ + '1' not in cnv_genotypes: + continue + + tmp_varID = var[4]["id2"] + var_dic = {"id":varID, "id2":tmp_varID, "genotype":''.join(cnv_genotypes)} + if reference_type == "gene": + vars.append([gene, pos2 - offset, type, data, var_dic]) + else: + vars.append([chr, pos2, type, data, var_dic]) + right = pos2 + if type == 'D': + right += (int(data) - 1) + if max_right < right: + max_right = right + return max_right + + right = add_vars(pos, + offset, + gene, + varID, + ref_allele, + alt_alleles, + vars, + genotypes) + if curr_right < right: + curr_right = right + + prev_varID = varID + prev_chr = chr + prev_pos = pos + + if len(vars) > 0: + num_haplotypes = generate_haplotypes(SNP_file, + haplotype_file, + vars, + inter_gap, + intra_gap, + num_genomes, + num_haplotypes) + vars = [] + + else: + for chr in genotype_var_list.keys(): + chr_seq = chr_dic[chr] + chr_genotype_vars = genotype_var_list[chr] + curr_right = -1 + vars = [] + for var in chr_genotype_vars: + var_chr, var_pos, var_type, var_data, var_dic = var + num_genomes = 0 + if len(vars) > 0 and curr_right + inter_gap < var_pos: + num_haplotypes = generate_haplotypes(SNP_file, + haplotype_file, + vars, + inter_gap, + intra_gap, + num_genomes, + num_haplotypes) + vars = [] + vars.append([var_chr, var_pos, var_type, var_data, var_dic]) + curr_right = var_pos + if var_type == 'D': + curr_right += (var_data - 1) + + if len(vars) > 0: + num_haplotypes = generate_haplotypes(SNP_file, + haplotype_file, + vars, + inter_gap, + intra_gap, + num_genomes, + num_haplotypes) + vars = [] + + + SNP_file.close() + haplotype_file.close() + + if genotype_vcf != "": + clnsig_file.close() + + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Extract SNPs and haplotypes from VCF files') + parser.add_argument('genome_file', + nargs='?', + type=FileType('r'), + help='input genome file (e.g. genome.fa)') + parser.add_argument('VCF_fnames', + nargs='?', + type=str, + help='A comma-seperated VCF files (plain text or gzipped file is accepted: GRCh38_dbSNP_no_SVs.vcf or GRCh38_dbSNP_no_SVs.vcf.gz') + parser.add_argument("base_fname", + nargs='?', + type=str, + help="base filename for SNPs and haplotypes") + parser.add_argument("--reference-type", + dest="reference_type", + type=str, + default="genome", + help="Reference type: gene, chromosome, and genome (default: genome)") + parser.add_argument("--inter-gap", + dest="inter_gap", + type=int, + default=30, + help="Maximum distance for variants to be in the same haplotype (default: 30)") + parser.add_argument("--intra-gap", + dest="intra_gap", + type=int, + default=50, + help="Break a haplotype into several haplotypes (default: 50)") + parser.add_argument('--non-rs', + dest='only_rs', + action='store_false', + help='Allow SNP IDs not beginning with rs') + parser.add_argument('--genotype-vcf', + dest='genotype_vcf', + type=str, + default="", + help='VCF file name for genotyping (default: empty)') + parser.add_argument('--genotype-gene-list', + dest='genotype_gene_list', + type=str, + default="", + help='A comma-separated list of genes to be genotyped (default: empty)') + parser.add_argument('--extra-files', + dest='extra_files', + action='store_true', + help='Output extra files such as _backbone.fa and .ref') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + + args = parser.parse_args() + if not args.genome_file or \ + not args.VCF_fnames or \ + not args.base_fname: + parser.print_help() + exit(1) + args.VCF_fnames = args.VCF_fnames.split(',') + + if args.genotype_vcf != "": + if args.genotype_gene_list == "": + genes = set() + if args.genotype_vcf.endswith(".gz"): + vcf_cmd = ["gzip", "-cd", args.genotype_vcf] + else: + vcf_cmd = ["cat", args.genotype_vcf] + vcf_proc = subprocess.Popen(vcf_cmd, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=open("/dev/null", 'w')) + for line in vcf_proc.stdout: + if line.startswith("#"): + continue + + info = line.strip().split()[-1] + if info.find("GENEINFO=") == -1: + continue + gene = info.split("GENEINFO=")[1] + gene = gene.split(':')[0] + genes.add(gene) + args.genotype_gene_list = list(genes) + else: + args.genotype_gene_list = args.genotype_gene_list.split(',') + + if len(args.genotype_gene_list) == 0: + print("Error: please specify --genotype-gene-list.", file=sys.stderr) + sys.exit(1) + + else: + args.genotype_gene_list = [] + + main(args.genome_file, + args.VCF_fnames, + args.base_fname, + args.inter_gap, + args.intra_gap, + args.only_rs, + args.reference_type, + args.genotype_vcf, + args.genotype_gene_list, + args.extra_files, + args.verbose) diff --git a/hisat2_extract_splice_sites.py b/hisat2_extract_splice_sites.py new file mode 100644 index 0000000..cba9234 --- /dev/null +++ b/hisat2_extract_splice_sites.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 + +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +from sys import stderr, exit +from collections import defaultdict as dd, Counter +from argparse import ArgumentParser, FileType + + +def extract_splice_sites(gtf_file, verbose=False): + genes = dd(list) + trans = {} + + # Parse valid exon lines from the GTF file into a dict by transcript_id + for line in gtf_file: + line = line.strip() + if not line or line.startswith('#'): + continue + if '#' in line: + line = line.split('#')[0].strip() + + try: + chrom, source, feature, left, right, score, \ + strand, frame, values = line.split('\t') + except ValueError: + continue + left, right = int(left), int(right) + + if feature != 'exon' or left >= right: + continue + + values_dict = {} + for attr in values.split(';'): + if attr: + attr, _, val = attr.strip().partition(' ') + values_dict[attr] = val.strip('"') + + if 'gene_id' not in values_dict or \ + 'transcript_id' not in values_dict: + continue + + transcript_id = values_dict['transcript_id'] + if transcript_id not in trans: + trans[transcript_id] = [chrom, strand, [[left, right]]] + genes[values_dict['gene_id']].append(transcript_id) + else: + trans[transcript_id][2].append([left, right]) + + # Sort exons and merge where separating introns are <=5 bps + for tran, [chrom, strand, exons] in trans.items(): + exons.sort() + tmp_exons = [exons[0]] + for i in range(1, len(exons)): + if exons[i][0] - tmp_exons[-1][1] <= 5: + tmp_exons[-1][1] = exons[i][1] + else: + tmp_exons.append(exons[i]) + trans[tran] = [chrom, strand, tmp_exons] + + # Calculate and print the unique junctions + junctions = set() + for chrom, strand, exons in trans.values(): + for i in range(1, len(exons)): + junctions.add((chrom, exons[i-1][1], exons[i][0], strand)) + junctions = sorted(junctions) + for chrom, left, right, strand in junctions: + # Zero-based offset + print('{}\t{}\t{}\t{}'.format(chrom, left-1, right-1, strand)) + + # Print some stats if asked + if verbose: + exon_lengths, intron_lengths, trans_lengths = \ + Counter(), Counter(), Counter() + for chrom, strand, exons in trans.values(): + tran_len = 0 + for i, exon in enumerate(exons): + exon_len = exon[1]-exon[0]+1 + exon_lengths[exon_len] += 1 + tran_len += exon_len + if i == 0: + continue + intron_lengths[exon[0] - exons[i-1][1]] += 1 + trans_lengths[tran_len] += 1 + + print('genes: {}, genes with multiple isoforms: {}'.format( + len(genes), sum(len(v) > 1 for v in genes.values())), + file=stderr) + print('transcripts: {}, transcript avg. length: {:.0f}'.format( + len(trans), sum(trans_lengths.elements())//len(trans)), + file=stderr) + print('exons: {}, exon avg. length: {:.0f}'.format( + sum(exon_lengths.values()), + sum(exon_lengths.elements())//sum(exon_lengths.values())), + file=stderr) + print('introns: {}, intron avg. length: {:.0f}'.format( + sum(intron_lengths.values()), + sum(intron_lengths.elements())//sum(intron_lengths.values())), + file=stderr) + print('average number of exons per transcript: {:.0f}'.format( + sum(exon_lengths.values())//len(trans)), + file=stderr) + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Extract splice junctions from a GTF file') + parser.add_argument('gtf_file', + nargs='?', + type=FileType('r'), + help='input GTF file (use "-" for stdin)') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + + args = parser.parse_args() + if not args.gtf_file: + parser.print_help() + exit(1) + extract_splice_sites(args.gtf_file, args.verbose) diff --git a/hisat2_inspect.cpp b/hisat2_inspect.cpp new file mode 100644 index 0000000..f6cb71e --- /dev/null +++ b/hisat2_inspect.cpp @@ -0,0 +1,791 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include +#include +#include +#include + +#include "assert_helpers.h" +#include "endian_swap.h" +#include "hgfm.h" +#include "reference.h" +#include "ds.h" +#include "alt.h" + +using namespace std; + +MemoryTally gMemTally; + +static bool showVersion = false; // just print version and quit? +int verbose = 0; // be talkative +static int names_only = 0; // just print the sequence names in the index +static int snp_only = 0; +static int splicesite_only = 0; +static int splicesite_all_only = 0; +static int exon_only = 0; +static int summarize_only = 0; // just print summary of index and quit +static int across = 60; // number of characters across in FASTA output +static bool refFromGFM = false; // true -> when printing reference, decode it from Gbwt instead of reading it from BitPairReference +static string wrapper; +static const char *short_options = "vhnsea:"; + +enum { + ARG_VERSION = 256, + ARG_WRAPPER, + ARG_USAGE, + ARG_SNP, + ARG_SPLICESITE, + ARG_SPLICESITE_ALL, + ARG_EXON, +}; + +static struct option long_options[] = { + {(char*)"verbose", no_argument, 0, 'v'}, + {(char*)"version", no_argument, 0, ARG_VERSION}, + {(char*)"usage", no_argument, 0, ARG_USAGE}, + {(char*)"names", no_argument, 0, 'n'}, + {(char*)"snp", no_argument, 0, ARG_SNP}, + {(char*)"ss", no_argument, 0, ARG_SPLICESITE}, + {(char*)"ss-all", no_argument, 0, ARG_SPLICESITE_ALL}, + {(char*)"exon", no_argument, 0, ARG_EXON}, + {(char*)"summary", no_argument, 0, 's'}, + {(char*)"help", no_argument, 0, 'h'}, + {(char*)"across", required_argument, 0, 'a'}, + {(char*)"gbwt-ref", no_argument, 0, 'g'}, + {(char*)"wrapper", required_argument, 0, ARG_WRAPPER}, + {(char*)0, 0, 0, 0} // terminator +}; + +/** + * Print a summary usage message to the provided output stream. + */ +static void printUsage(ostream& out) { + out << "HISAT2 version " << string(HISAT2_VERSION).c_str() << " by Daehwan Kim (infphilo@gmail.com, http://www.ccb.jhu.edu/people/infphilo)" << endl; + out + << "Usage: hisat2-inspect [options]* " << endl + << " ht2 filename minus trailing .1." << gfm_ext << "/.2." << gfm_ext << endl + << endl + << " By default, prints FASTA records of the indexed nucleotide sequences to" << endl + << " standard out. With -n, just prints names. With -s, just prints a summary of" << endl + << " the index parameters and sequences. With -e, preserves colors if applicable." << endl + << endl + << "Options:" << endl; + if(wrapper == "basic-0") { + out << " --large-index force inspection of the 'large' index, even if a" << endl + << " 'small' one is present." << endl; + } + out << " -a/--across Number of characters across in FASTA output (default: 60)" << endl + << " -s/--summary Print summary incl. ref names, lengths, index properties" << endl + << " -n/--names Print reference sequence names only" << endl + << " --snp Print SNPs" << endl + << " --ss Print splice sites" << endl + << " --ss-all Print splice sites including those not in the global index" << endl + << " --exon Print exons" << endl + << " -e/--ht2-ref Reconstruct reference from ." << gfm_ext << " (slow, preserves colors)" << endl + << " -v/--verbose Verbose output (for debugging)" << endl + << " -h/--help print detailed description of tool and its options" << endl + << " --usage print this usage message" << endl + ; + if(wrapper.empty()) { + cerr << endl + << "*** Warning ***" << endl + << "'hisat-inspect' was run directly. It is recommended " + << "to use the wrapper script instead." + << endl << endl; + } +} + +/** + * Parse an int out of optarg and enforce that it be at least 'lower'; + * if it is less than 'lower', than output the given error message and + * exit with an error and a usage message. + */ +static int parseInt(int lower, const char *errmsg) { + long l; + char *endPtr= NULL; + l = strtol(optarg, &endPtr, 10); + if (endPtr != NULL) { + if (l < lower) { + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + } + return (int32_t)l; + } + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + return -1; +} + +/** + * Read command-line arguments + */ +static void parseOptions(int argc, char **argv) { + int option_index = 0; + int next_option; + do { + next_option = getopt_long(argc, argv, short_options, long_options, &option_index); + switch (next_option) { + case ARG_WRAPPER: + wrapper = optarg; + break; + case ARG_USAGE: + case 'h': + printUsage(cout); + throw 0; + break; + case 'v': verbose = true; break; + case ARG_VERSION: showVersion = true; break; + case 'g': refFromGFM = true; break; + case 'n': names_only = true; break; + case ARG_SNP: snp_only = true; break; + case ARG_SPLICESITE: splicesite_only = true; break; + case ARG_SPLICESITE_ALL: splicesite_all_only = true; break; + case ARG_EXON: exon_only = true; break; + case 's': summarize_only = true; break; + case 'a': across = parseInt(-1, "-a/--across arg must be at least 1"); break; + case -1: break; /* Done with options. */ + case 0: + if (long_options[option_index].flag != 0) + break; + default: + printUsage(cerr); + throw 1; + } + } while(next_option != -1); +} + +static void print_fasta_record( + ostream& fout, + const string& defline, + const string& seq) +{ + fout << ">"; + fout << defline.c_str() << endl; + + if(across > 0) { + size_t i = 0; + while (i + across < seq.length()) + { + fout << seq.substr(i, across).c_str() << endl; + i += across; + } + if (i < seq.length()) + fout << seq.substr(i).c_str() << endl; + } else { + fout << seq.c_str() << endl; + } +} + +/** + * Given output stream, BitPairReference, reference index, name and + * length, print the whole nucleotide reference with the appropriate + * number of columns. + */ +static void print_ref_sequence( + ostream& fout, + BitPairReference& ref, + const string& name, + size_t refi, + size_t len) +{ + bool newlines = across > 0; + int myacross = across > 0 ? across : 60; + size_t incr = myacross * 1000; + uint32_t *buf = new uint32_t[(incr + 128)/4]; + fout << ">" << name.c_str() << "\n"; + ASSERT_ONLY(SStringExpandable destU32); + for(size_t i = 0; i < len; i += incr) { + size_t amt = min(incr, len-i); + assert_leq(amt, incr); + int off = ref.getStretch(buf, refi, i, amt ASSERT_ONLY(, destU32)); + uint8_t *cb = ((uint8_t*)buf) + off; + for(size_t j = 0; j < amt; j++) { + if(newlines && j > 0 && (j % myacross) == 0) fout << "\n"; + assert_range(0, 4, (int)cb[j]); + fout << "ACGTN"[(int)cb[j]]; + } + fout << "\n"; + } + delete []buf; +} + +/** + * Create a BitPairReference encapsulating the reference portion of the + * index at the given basename. Iterate through the reference + * sequences, sending each one to print_ref_sequence to print. + */ +static void print_ref_sequences( + ostream& fout, + const EList& refnames, + const TIndexOffU* plen, + const string& adjustedGFMFileBase) +{ + BitPairReference ref( + adjustedGFMFileBase, // input basename + NULL, + false, // true -> expect colorspace reference + false, // sanity-check reference + NULL, // infiles + NULL, // originals + false, // infiles are sequences + false, // memory-map + false, // use shared memory + false, // sweep mm-mapped ref + verbose, // be talkative + verbose); // be talkative at startup + assert_eq(ref.numRefs(), refnames.size()); + for(size_t i = 0; i < ref.numRefs(); i++) { + print_ref_sequence( + fout, + ref, + refnames[i], + i, + plen[i]); + } +} + +/** + * Given an index, reconstruct the reference by LF mapping through the + * entire thing. + */ +template +static void print_index_sequences(ostream& fout, GFM& gfm) +{ + EList* refnames = &(gfm.refnames()); + + TStr cat_ref; + gfm.restore(cat_ref); + + TIndexOffU curr_ref = OFF_MASK; + string curr_ref_seq = ""; + TIndexOffU curr_ref_len = OFF_MASK; + TIndexOffU last_text_off = 0; + size_t orig_len = cat_ref.length(); + TIndexOffU tlen = OFF_MASK; + bool first = true; + for(size_t i = 0; i < orig_len; i++) { + TIndexOffU tidx = OFF_MASK; + TIndexOffU textoff = OFF_MASK; + tlen = OFF_MASK; + bool straddled = false; + gfm.joinedToTextOff(1 /* qlen */, (TIndexOffU)i, tidx, textoff, tlen, true, straddled); + + if (tidx != OFF_MASK && textoff < tlen) + { + if (curr_ref != tidx) + { + if (curr_ref != OFF_MASK) + { + // Add trailing gaps, if any exist + if(curr_ref_seq.length() < curr_ref_len) { + curr_ref_seq += string(curr_ref_len - curr_ref_seq.length(), 'N'); + } + print_fasta_record(fout, (*refnames)[curr_ref], curr_ref_seq); + } + curr_ref = tidx; + curr_ref_seq = ""; + curr_ref_len = tlen; + last_text_off = 0; + first = true; + } + + TIndexOffU textoff_adj = textoff; + if(first && textoff > 0) textoff_adj++; + if (textoff_adj - last_text_off > 1) + curr_ref_seq += string(textoff_adj - last_text_off - 1, 'N'); + + curr_ref_seq.push_back("ACGT"[int(cat_ref[i])]); + last_text_off = textoff; + first = false; + } + } + if (curr_ref < refnames->size()) + { + // Add trailing gaps, if any exist + if(curr_ref_seq.length() < curr_ref_len) { + curr_ref_seq += string(curr_ref_len - curr_ref_seq.length(), 'N'); + } + print_fasta_record(fout, (*refnames)[curr_ref], curr_ref_seq); + } + +} + +static char *argv0 = NULL; + +template +static void print_index_sequence_names(const string& fname, ostream& fout) +{ + EList p_refnames; + readEbwtRefnames(fname, p_refnames); + for(size_t i = 0; i < p_refnames.size(); i++) { + cout << p_refnames[i].c_str() << endl; + } +} + +/** + * Print a short summary of what's in the index and its flags. + */ +template +static void print_snps( + const string& fname, + ostream& fout) +{ + ALTDB altdb; + GFM gfm( + fname, + &altdb, + NULL, + NULL, + -1, // don't require entire reverse + true, // index is for the forward direction + -1, // offrate (-1 = index default) + 0, // offrate-plus (0 = index default) + false, // use memory-mapped IO + false, // use shared memory + false, // sweep memory-mapped memory + true, // load names? + false, // load SA sample? + false, // load ftab? + false, // load rstarts? + true, // load splice sites? + verbose, // be talkative? + verbose, // be talkative at startup? + false, // pass up memory exceptions? + false, // sanity check? + false); // use haplotypes? + gfm.loadIntoMemory( + -1, // need entire reverse + true, // load SA sample + true, // load ftab + true, // load rstarts + true, // load names + verbose); // verbose + EList p_refnames; + readEbwtRefnames(fname, p_refnames); + const EList >& alts = altdb.alts(); + const EList& altnames = altdb.altnames(); + assert_eq(alts.size(), altnames.size()); + for(size_t i = 0; i < alts.size(); i++) { + const ALT& alt = alts[i]; + if(!alt.snp()) + continue; + if(alt.deletion() && alt.reversed) + continue; + string type = "single"; + if(alt.type == ALT_SNP_DEL) { + type = "deletion"; + } else if(alt.type == ALT_SNP_INS) { + type = "insertion"; + } + index_t tidx = 0, toff = 0, tlen = 0; + bool straddled2 = false; + gfm.joinedToTextOff( + 1, + alt.pos, + tidx, + toff, + tlen, + true, // reject straddlers? + straddled2); // straddled? + cout << altnames[i] << "\t" + << type << "\t"; + assert_lt(tidx, p_refnames.size()); + cout << p_refnames[tidx] << "\t" + << toff << "\t"; + if(alt.type == ALT_SNP_SGL) { + cout << "ACGT"[alt.seq & 0x3]; + } else if(alt.type == ALT_SNP_DEL) { + cout << alt.len; + } else if(alt.type == ALT_SNP_INS) { + for(index_t i = 0; i < alt.len; i++) { + int nt = (alt.seq >> ((alt.len - i - 1) << 1)) & 0x3; + cout << "ACGT"[nt]; + } + } + cout << endl; + } +} + +/** + * Print a short summary of what's in the index and its flags. + */ +template +static void print_splicesites( + const string& fname, + ostream& fout) +{ + ALTDB altdb; + GFM gfm( + fname, + &altdb, + NULL, + NULL, + -1, // don't require entire reverse + true, // index is for the forward direction + -1, // offrate (-1 = index default) + 0, // offrate-plus (0 = index default) + false, // use memory-mapped IO + false, // use shared memory + false, // sweep memory-mapped memory + true, // load names? + false, // load SA sample? + false, // load ftab? + false, // load rstarts? + true, // load splice sites? + verbose, // be talkative? + verbose, // be talkative at startup? + false, // pass up memory exceptions? + false, // sanity check? + false); // use haplotypes? + gfm.loadIntoMemory( + -1, // need entire reverse + true, // load SA sample + true, // load ftab + true, // load rstarts + true, // load names + verbose); // verbose + EList p_refnames; + readEbwtRefnames(fname, p_refnames); + const EList >& alts = altdb.alts(); + for(size_t i = 0; i < alts.size(); i++) { + const ALT& alt = alts[i]; + if(!alt.splicesite()) continue; + if(alt.left >= alt.right) continue; + if(!splicesite_all_only && alt.excluded) continue; + index_t tidx = 0, toff = 0, tlen = 0; + bool straddled2 = false; + gfm.joinedToTextOff( + 1, + alt.left, + tidx, + toff, + tlen, + true, // reject straddlers? + straddled2); // straddled? + index_t tidx2 = 0, toff2 = 0, tlen2 = 0; + gfm.joinedToTextOff( + 1, + alt.right, + tidx2, + toff2, + tlen2, + true, // reject straddlers? + straddled2); // straddled? + assert_eq(tidx, tidx2); + assert_lt(tidx, p_refnames.size()); + cout << p_refnames[tidx] << "\t" + << toff - 1 << "\t" + << toff2 + 1 << "\t" + << (alt.fw > 0 ? "+" : "-") << endl; + } +} + +/** + * Print a short summary of what's in the index and its flags. + */ +template +static void print_exons( + const string& fname, + ostream& fout) +{ + ALTDB altdb; + GFM gfm( + fname, + &altdb, + NULL, + NULL, + -1, // don't require entire reverse + true, // index is for the forward direction + -1, // offrate (-1 = index default) + 0, // offrate-plus (0 = index default) + false, // use memory-mapped IO + false, // use shared memory + false, // sweep memory-mapped memory + true, // load names? + false, // load SA sample? + false, // load ftab? + false, // load rstarts? + true, // load splice sites? + verbose, // be talkative? + verbose, // be talkative at startup? + false, // pass up memory exceptions? + false, // sanity check? + false); // use haplotypes? + gfm.loadIntoMemory( + -1, // need entire reverse + true, // load SA sample + true, // load ftab + true, // load rstarts + true, // load names + verbose); // verbose + EList p_refnames; + readEbwtRefnames(fname, p_refnames); + const EList >& alts = altdb.alts(); + for(size_t i = 0; i < alts.size(); i++) { + const ALT& alt = alts[i]; + if(!alt.exon()) continue; + index_t tidx = 0, toff = 0, tlen = 0; + bool straddled2 = false; + gfm.joinedToTextOff( + 1, + alt.left, + tidx, + toff, + tlen, + true, // reject straddlers? + straddled2); // straddled? + index_t tidx2 = 0, toff2 = 0, tlen2 = 0; + gfm.joinedToTextOff( + 1, + alt.right, + tidx2, + toff2, + tlen2, + true, // reject straddlers? + straddled2); // straddled? + assert_eq(tidx, tidx2); + assert_lt(tidx, p_refnames.size()); + cout << p_refnames[tidx] << "\t" + << toff - 1 << "\t" + << toff2 + 1 << "\t" + << (alt.fw > 0 ? "+" : "-") << endl; + } +} + +/** + * Print a short summary of what's in the index and its flags. + */ +template +static void print_index_summary( + const string& fname, + ostream& fout) +{ + int major, minor; + string extra_version; + int32_t flags = GFM::readVersionFlags(fname, major, minor, extra_version); + bool entireReverse = false; + ALTDB altdb; + GFM gfm( + fname, + &altdb, + NULL, + NULL, + -1, // don't require entire reverse + true, // index is for the forward direction + -1, // offrate (-1 = index default) + 0, // offrate-plus (0 = index default) + false, // use memory-mapped IO + false, // use shared memory + false, // sweep memory-mapped memory + true, // load names? + false, // load SA sample? + false, // load ftab? + false, // load rstarts? + true, // load splice sites? + verbose, // be talkative? + verbose, // be talkative at startup? + false, // pass up memory exceptions? + false, // sanity check? + false); // use haplotypes? + EList p_refnames; + readEbwtRefnames(fname, p_refnames); + cout << "Index version" << "\t2." << major << '.' << minor; + if(extra_version != "") { + cout << "-" << extra_version; + } + cout << endl; + cout << "Flags" << '\t' << (-flags) << endl; + cout << "2.0-compatible" << '\t' << (entireReverse ? "1" : "0") << endl; + cout << "SA-Sample" << "\t1 in " << (1 << gfm.gh().offRate()) << endl; + cout << "FTab-Chars" << '\t' << gfm.gh().ftabChars() << endl; + assert_eq(gfm.nPat(), p_refnames.size()); + for(size_t i = 0; i < p_refnames.size(); i++) { + cout << "Sequence-" << (i+1) + << '\t' << p_refnames[i].c_str() + << '\t' << gfm.plen()[i] + << endl; + } + index_t numSnps = 0, numSpliceSites = 0, numExons = 0; + const EList >& alts = altdb.alts(); + for(size_t i = 0; i < alts.size(); i++) { + const ALT& alt = alts[i]; + if(alt.snp()) { + numSnps++; + } else if(alt.splicesite()) { + if(alt.left < alt.right) { + numSpliceSites++; + } + } else if(alt.exon()) { + numExons++; + } + } + cout << "Num. SNPs: " << numSnps << endl; + cout << "Num. Splice Sites: " << numSpliceSites << endl; + cout << "Num. Exons: " << numExons << endl; +} + +extern void initializeCntLut(); +extern void initializeCntBit(); + +static void driver( + const string& ebwtFileBase, + const string& query) +{ + initializeCntLut(); + initializeCntBit(); + + // Adjust + string adjustedEbwtFileBase = adjustEbwtBase(argv0, ebwtFileBase, verbose); + + if (names_only) { + print_index_sequence_names(adjustedEbwtFileBase, cout); + } else if(summarize_only) { + print_index_summary(adjustedEbwtFileBase, cout); + } else if(snp_only) { + print_snps(adjustedEbwtFileBase, cout); + } else if(splicesite_only || splicesite_all_only) { + print_splicesites(adjustedEbwtFileBase, cout); + } else if(exon_only) { + print_exons(adjustedEbwtFileBase, cout); + } else { + // Initialize Ebwt object + ALTDB altdb; + HGFM gfm( + adjustedEbwtFileBase, + &altdb, + NULL, + NULL, + -1, // don't care about entire-reverse + true, // index is for the forward direction + -1, // offrate (-1 = index default) + 0, // offrate-plus (0 = index default) + false, // use memory-mapped IO + false, // use shared memory + false, // sweep memory-mapped memory + true, // load names? + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + true, // load splice sites? + false, // be talkative? + false, // be talkative at startup? + false, // pass up memory exceptions? + false, // sanity check? + false); // use haplotypes? + + gfm.loadIntoMemory( + -1, // need entire reverse + true, // load SA sample + true, // load ftab + true, // load rstarts + true, // load names + verbose); // verbose + + // Load whole index into memory + if(refFromGFM) { + print_index_sequences >(cout, gfm); + } else { + EList refnames; + readEbwtRefnames(adjustedEbwtFileBase, refnames); + print_ref_sequences( + cout, + refnames, + gfm.plen(), + adjustedEbwtFileBase); + } + // Evict any loaded indexes from memory + if(gfm.isInMemory()) { + gfm.evictFromMemory(); + } + } +} + +/** + * main function. Parses command-line arguments. + */ +int main(int argc, char **argv) { + try { + string ebwtFile; // read serialized Ebwt from this file + string query; // read query string(s) from this file + EList queries; + string outfile; // write query results to this file + argv0 = argv[0]; + parseOptions(argc, argv); + if(showVersion) { + cout << argv0 << " version " << HISAT2_VERSION << endl; + if(sizeof(void*) == 4) { + cout << "32-bit" << endl; + } else if(sizeof(void*) == 8) { + cout << "64-bit" << endl; + } else { + cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl; + } + cout << "Built on " << BUILD_HOST << endl; + cout << BUILD_TIME << endl; + cout << "Compiler: " << COMPILER_VERSION << endl; + cout << "Options: " << COMPILER_OPTIONS << endl; + cout << "Sizeof {int, long, long long, void*, size_t, off_t}: {" + << sizeof(int) + << ", " << sizeof(long) << ", " << sizeof(long long) + << ", " << sizeof(void *) << ", " << sizeof(size_t) + << ", " << sizeof(off_t) << "}" << endl; + return 0; + } + + // Get input filename + if(optind >= argc) { + cerr << "No index name given!" << endl; + printUsage(cerr); + return 1; + } + ebwtFile = argv[optind++]; + + // Optionally summarize + if(verbose) { + cout << "Input ht2 file: \"" << ebwtFile.c_str() << "\"" << endl; + cout << "Output file: \"" << outfile.c_str() << "\"" << endl; + cout << "Local endianness: " << (currentlyBigEndian()? "big":"little") << endl; +#ifdef NDEBUG + cout << "Assertions: disabled" << endl; +#else + cout << "Assertions: enabled" << endl; +#endif + } + driver(ebwtFile, query); + return 0; + } catch(std::exception& e) { + cerr << "Error: Encountered exception: '" << e.what() << "'" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + return 1; + } catch(int e) { + if(e != 0) { + cerr << "Error: Encountered internal HISAT2 exception (#" << e << ")" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + } + return e; + } +} + diff --git a/hisat2_main.cpp b/hisat2_main.cpp new file mode 100644 index 0000000..0d74204 --- /dev/null +++ b/hisat2_main.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include +#include +#include "tokenize.h" +#include "ds.h" + +using namespace std; + +extern "C" { + int hisat2(int argc, const char **argv); +} + +/** + * Bowtie main function. It is placed in a separate source file to + * make it slightly easier to compile Bowtie as a library. + * + * If the user specifies -A as the first two arguments, main + * will interpret that file as having one set of command-line arguments + * per line, and will dispatch each batch of arguments one at a time to + * bowtie. + */ +int main(int argc, const char **argv) { + if(argc > 2 && strcmp(argv[1], "-A") == 0) { + const char *file = argv[2]; + ifstream in; + in.open(file); + char buf[4096]; + int lastret = -1; + while(in.getline(buf, 4095)) { + EList args; + args.push_back(string(argv[0])); + tokenize(buf, " \t", args); + const char **myargs = (const char**)malloc(sizeof(char*)*args.size()); + for(size_t i = 0; i < args.size(); i++) { + myargs[i] = args[i].c_str(); + } + if(args.size() == 1) continue; + lastret = hisat2((int)args.size(), myargs); + free(myargs); + } + if(lastret == -1) { + cerr << "Warning: No arg strings parsed from " << file << endl; + return 0; + } + return lastret; + } else { + return hisat2(argc, argv); + } +} diff --git a/hisat2_read_statistics.py b/hisat2_read_statistics.py new file mode 100644 index 0000000..9d6e946 --- /dev/null +++ b/hisat2_read_statistics.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 + +# +# Copyright 2018, Chanhee Park and Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +import os, sys, math, gzip, bz2 +from argparse import ArgumentParser, FileType +""" +""" +COMPRESSION_NON = 0 +COMPRESSION_GZIP = 1 +COMPRESSION_BZIP2 = 2 + +SEQUENCE_UNKNOWN = -1 +SEQUENCE_FASTA = 0 +SEQUENCE_FASTQ = 1 + +FASTA_EXTENSIONS = ["fa", "fasta", "fna"] +FASTQ_EXTENSIONS = ["fq", "fastq"] + +MAX_SKIP_LINES = 10000 +""" +""" +def parser_FQ(fp): + # skip empty line + skip_line_count = 0 + while skip_line_count < MAX_SKIP_LINES: + line = fp.readline() + + if line == "": + # end of file + return + + if line[0] == '@': + break + + skip_line_count += 1 + + if skip_line_count == MAX_SKIP_LINES: + raise ValueError("Invalid file format") + + while True: + id = line[1:].split()[0] + seq = "" + + line = fp.readline() + if line == "": + return + + seq = line.strip() + yield id, seq + + line = fp.readline() # '+' + line = fp.readline() # quality + line = fp.readline() # next ID + if line == "": + return + +""" +""" +def parser_FA(fp): + # skip empty line + skip_line_count = 0 + while skip_line_count < MAX_SKIP_LINES: + line = fp.readline() + + if line == "": + # end of file + return + + if line[0] == '>': + break + + skip_line_count += 1 + + if skip_line_count == MAX_SKIP_LINES: + raise ValueError("Invalid file format") + + while True: + id = line[1:].split()[0] + seq = "" + + while True: + line = fp.readline() + if line == "": + break + + if line[0] == '>': + break + + seq += line.strip() + + yield id, seq + + if line == "": + return + + +""" +""" +def parse_type(fname): + compression_type = COMPRESSION_NON + sequence_type = SEQUENCE_UNKNOWN + + ff = fname.split('.') + + ext = ff[-1] + if ext.lower() == "gz": + compression_type = COMPRESSION_GZIP + ext = ff[-2] + elif ext.lower() == "bz2": + compression_type = COMPRESSION_BZIP2 + ext = ff[-2] + + if ext.lower() in FASTA_EXTENSIONS: + sequence_type = SEQUENCE_FASTA + elif ext.lower() in FASTQ_EXTENSIONS: + sequence_type = SEQUENCE_FASTQ + + return sequence_type, compression_type + +""" +""" +def generate_stats(length_map): + mn = 0 # minimun read length + mx = 0 # maximum read length + cnt = 0 # number of reads + avg = 0 # average read length + + sum = 0 + + if len(length_map) == 0: + return cnt, mn, mx, avg + + # sort keys + sorted_map = sorted(length_map) + + mn = sorted_map[0] + mx = sorted_map[-1] + + for k, v in length_map.items(): + sum += k * v + cnt += v + + avg = sum // cnt + + return cnt, mn, mx, avg + +""" +""" +def reads_stat(read_file, read_count): + length_map = {} + try: + sequence_type, compression_type = parse_type(read_file) + + if compression_type == COMPRESSION_GZIP: + fp = gzip.open(read_file, 'rt') + elif compression_type == COMPRESSION_BZIP2: + fp = bz2.open(read_file, 'rt') + else: + assert (compression_type == COMPRESSION_NON) + fp = open(read_file, 'r') + + if sequence_type == SEQUENCE_FASTA: + fstream = parser_FA(fp) + elif sequence_type == SEQUENCE_FASTQ: + fstream = parser_FQ(fp) + else: + raise ValueError("Unsupported file format") + + cnt = 0 + for id, seq in fstream: + l = len(seq) + if l in length_map: + length_map[l] += 1 + else: + length_map[l] = 1 + + cnt += 1 + if read_count > 0 and cnt >= read_count: + break + + fp.close() + + except BaseException as e: + print("Warning: {}".format(e), file=sys.stderr) + + cnt, mn, mx, avg = generate_stats(length_map) + # sort by (read count, read length) + length_map = sorted(length_map.items(), key=lambda t: (t[1], t[0]), reverse=True) + if len(length_map) == 0: + length_map.append((0, 0)) + print(cnt, mn, mx, avg, ",".join([str(k) for (k,v) in length_map])) + + +if __name__ == '__main__': + + parser = ArgumentParser( + description='Compute statistics of reads. Show number of reads and minimum, maximum, average length of reads') + + parser.add_argument('read_file', + nargs='?', + type=str, + help='reads file') + + parser.add_argument('-n', + dest='read_count', + action='store', + type=int, + default=10000, + help='reads count (default: 10000)') + + args = parser.parse_args() + + if not args.read_file: + parser.print_help() + exit(1) + + reads_stat(args.read_file, args.read_count) + diff --git a/hisat2_repeat.cpp b/hisat2_repeat.cpp new file mode 100644 index 0000000..a92d34a --- /dev/null +++ b/hisat2_repeat.cpp @@ -0,0 +1,996 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "assert_helpers.h" +#include "endian_swap.h" +#include "formats.h" +#include "sequence_io.h" +#include "tokenize.h" +#include "timer.h" +#include "ref_read.h" +#include "filebuf.h" +#include "reference.h" +#include "ds.h" +#include "gfm.h" +#include "aligner_sw.h" +#include "aligner_result.h" +#include "search_globals.h" +#include "scoring.h" +#include "mask.h" +#include "repeat_builder.h" +#include "utility_3n.h" + +/** + * \file Driver for the bowtie-build indexing tool. + */ + +#include +#include +#include +#include +#include + +MemoryTally gMemTally; +// Build parameters +int verbose; +static int sanityCheck; +static int format; +static TIndexOffU bmax; +static TIndexOffU bmaxMultSqrt; +static uint32_t bmaxDivN; +static int dcv; +static int noDc; +static int entireSA; +static int seed; +static int showVersion; +// GFM parameters +static int32_t lineRate; +static bool lineRate_provided; +static int32_t linesPerSide; +static int32_t offRate; +static int32_t ftabChars; +static int32_t localOffRate; +static int32_t localFtabChars; +static int bigEndian; +static bool autoMem; +static int nthreads; // number of pthreads operating concurrently +static string wrapper; +static TIndexOffU seed_length; +static TIndexOffU seed_count; +static TIndexOffU repeat_count; +static TIndexOffU min_repeat_length; +static TIndexOffU max_repeat_length; +static EList > repeat_length_pair; +static TIndexOffU max_repeat_edit; +static TIndexOffU max_repeat_matchlen; +static bool symmetric_extend; +static bool repeat_indel; +static bool forward_only; +static bool CGtoTG; +static string repeat_str1; +static string repeat_str2; +TIndexOffU max_seed_mm; +TIndexOffU max_seed_repeat; +TIndexOffU max_seed_extlen; +static bool save_sa; +static bool load_sa; + +bool threeN = false; +char convertedFrom; +char convertedTo; +char convertedFromComplement; +char convertedToComplement; +bool base_change_entered; + +static void resetOptions() { + verbose = true; // be talkative (default) + sanityCheck = 0; // do slow sanity checks + format = FASTA; // input sequence format + bmax = OFF_MASK; // max blockwise SA bucket size + bmaxMultSqrt = OFF_MASK; // same, as multplier of sqrt(n) + bmaxDivN = 4; // same, as divisor of n + dcv = 1024; // bwise SA difference-cover sample sz + noDc = 0; // disable difference-cover sample + entireSA = 0; // 1 = disable blockwise SA + seed = 0; // srandom seed + showVersion = 0; // just print version and quit? + // GFM parameters + lineRate = GFM::default_lineRate_gfm; + lineRate_provided = false; + linesPerSide = 1; // 1 64-byte line on a side + offRate = 4; // sample 1 out of 16 SA elts + ftabChars = 10; // 10 chars in initial lookup table + localOffRate = 3; + localFtabChars = 6; + bigEndian = 0; // little endian + autoMem = true; // automatically adjust memory usage parameters + nthreads = 1; + seed_length = 50; + seed_count = 5; + min_repeat_length = 100; + max_repeat_length = numeric_limits::max(); + repeat_length_pair.clear(); + repeat_count = 5; + max_repeat_edit = 10; + max_repeat_matchlen = min_repeat_length / 2; // half of repeat_length + repeat_indel = false; + symmetric_extend = true; + forward_only = false; + CGtoTG = false; + max_seed_mm = 5; + max_seed_repeat = 5; + max_seed_extlen = 25; + save_sa = false; + load_sa = false; + wrapper.clear(); + threeN = false; + convertedFrom = 'C'; + convertedTo = 'T'; + convertedFromComplement = asc2dnacomp[convertedFrom]; + convertedToComplement = asc2dnacomp[convertedTo]; + base_change_entered = false; +} + +// Argument constants for getopts +enum { + ARG_BMAX = 256, + ARG_BMAX_MULT, + ARG_BMAX_DIV, + ARG_DCV, + ARG_SEED, + ARG_CUTOFF, + ARG_PMAP, + ARG_NTOA, + ARG_USAGE, + ARG_REVERSE_EACH, + ARG_SA, + ARG_SEED_LENGTH, + ARG_SEED_COUNT, + ARG_MIN_REPEAT_LENGTH, + ARG_MAX_REPEAT_LENGTH, + ARG_REPEAT_LENGTH, + ARG_REPEAT_COUNT, + ARG_REPEAT_EDIT, + ARG_REPEAT_MATCHLEN, + ARG_REPEAT_INDEL, + ARG_WRAPPER, + ARG_ASYMMETRIC_EXTEND, + ARG_FORWARD_ONLY, + ARG_CGTOTG, + ARG_REPEAT_STR1, + ARG_REPEAT_STR2, + ARG_MAX_SEED_MM, + ARG_MAX_SEED_REPEAT, + ARG_MAX_SEED_EXTLEN, + ARG_SAVE_SA, + ARG_LOAD_SA, + ARG_3N, + ARG_BASE_CHANGE +}; + +/** + * Print a detailed usage message to the provided output stream. + */ +static void printUsage(ostream& out) { + out << "HISAT2 version " << string(HISAT2_VERSION).c_str() << " by Chanhee Park and Daehwan Kim " << endl; + + string tool_name = "hisat2-repeat"; + out << "Usage: " << tool_name << " [options]* " << endl + << " reference_in comma-separated list of files with ref sequences" << endl + << "Options:" << endl + << " -c reference sequences given on cmd line (as" << endl + << " )" << endl; + if(wrapper == "basic-0") { + out << " --large-index force generated index to be 'large', even if ref" << endl + << " has fewer than 4 billion nucleotides" << endl; + } + out << " -a/--noauto disable automatic -p/--bmax/--dcv memory-fitting" << endl + << " -p number of threads" << endl + << " --bmax max bucket sz for blockwise suffix-array builder" << endl + << " --bmaxdivn max bucket sz as divisor of ref len (default: 4)" << endl + << " --dcv diff-cover period for blockwise (default: 1024)" << endl + << " --nodc disable diff-cover (algorithm becomes quadratic)" << endl + << " --seed-length seed length (default: 50)" << endl + << " --seed-count seed count (default: 5)" << endl + << " --min-repeat-length minimum repeat length (default: 100)" << endl + << " --max-repeat-length maximum repeat length (default: 65535)" << endl + << " --repeat-length -[,-] minimum-maximum repeat length pairs" << endl + << " --repeat-count minimum repeat count (default: 5)" << endl + << " --repeat-edit maximum repeat edit distance (default: 10)" << endl + << " --repeat-matchlen " << endl + << " --repeat-indel" << endl + << " --repeat-str1" << endl + << " --repeat-str2" << endl + << " --asymmetric-extend extend seeds asymmetrically" << endl + << " --forward-only use forward strand only" << endl + << " --CGtoTG change CG to TG" << endl + << " --max-seed-mm " << endl + << " --max-seed-repeat " << endl + << " --max-seed-extlen " << endl + << " --save-sa" << endl + << " --load-sa" << endl + << " --3N make 3N repeat database" << endl + << " --base-change the converted nucleotide and converted to nucleotide (default:C,T)" << endl + << " -q/--quiet disable verbose output (for debugging)" << endl + << " -h/--help print detailed description of tool and its options" << endl + << " --usage print this usage message" << endl + << " --version print version information and quit" << endl + ; +} + +static const char *short_options = "qrap:h?nscfl:i:o:t:h:3C"; + +static struct option long_options[] = { + {(char*)"quiet", no_argument, 0, 'q'}, + {(char*)"sanity", no_argument, 0, 's'}, + {(char*)"threads", required_argument, 0, 'p'}, + {(char*)"little", no_argument, &bigEndian, 0}, + {(char*)"big", no_argument, &bigEndian, 1}, + {(char*)"bmax", required_argument, 0, ARG_BMAX}, + {(char*)"bmaxmultsqrt", required_argument, 0, ARG_BMAX_MULT}, + {(char*)"bmaxdivn", required_argument, 0, ARG_BMAX_DIV}, + {(char*)"dcv", required_argument, 0, ARG_DCV}, + {(char*)"nodc", no_argument, &noDc, 1}, + {(char*)"seed", required_argument, 0, ARG_SEED}, + {(char*)"entiresa", no_argument, &entireSA, 1}, + {(char*)"version", no_argument, &showVersion, 1}, + {(char*)"noauto", no_argument, 0, 'a'}, + {(char*)"noblocks", required_argument, 0, 'n'}, + {(char*)"linerate", required_argument, 0, 'l'}, + {(char*)"linesperside", required_argument, 0, 'i'}, + {(char*)"usage", no_argument, 0, ARG_USAGE}, + {(char*)"seed-length", required_argument, 0, ARG_SEED_LENGTH}, + {(char*)"seed-count", required_argument, 0, ARG_SEED_COUNT}, + {(char*)"min-repeat-length", required_argument, 0, ARG_MIN_REPEAT_LENGTH}, + {(char*)"max-repeat-length", required_argument, 0, ARG_MAX_REPEAT_LENGTH}, + {(char*)"repeat-length", required_argument, 0, ARG_REPEAT_LENGTH}, + {(char*)"repeat-count", required_argument, 0, ARG_REPEAT_COUNT}, + {(char*)"repeat-edit", required_argument, 0, ARG_REPEAT_EDIT}, + {(char*)"repeat-matchlen",required_argument, 0, ARG_REPEAT_MATCHLEN}, + {(char*)"repeat-indel", no_argument, 0, ARG_REPEAT_INDEL}, + {(char*)"wrapper", required_argument, 0, ARG_WRAPPER}, + {(char*)"asymmetric-extend", no_argument, 0, ARG_ASYMMETRIC_EXTEND}, + {(char*)"forward-only", no_argument, 0, ARG_FORWARD_ONLY}, + {(char*)"CGtoTG", no_argument, 0, ARG_CGTOTG}, + {(char*)"repeat-str1", required_argument, 0, ARG_REPEAT_STR1}, + {(char*)"repeat-str2", required_argument, 0, ARG_REPEAT_STR2}, + {(char*)"max-seed-mm", required_argument, 0, ARG_MAX_SEED_MM}, + {(char*)"max-seed-repeat",required_argument, 0, ARG_MAX_SEED_REPEAT}, + {(char*)"max-seed-extlen",required_argument, 0, ARG_MAX_SEED_EXTLEN}, + {(char*)"save-sa", no_argument, 0, ARG_SAVE_SA}, + {(char*)"load-sa", no_argument, 0, ARG_LOAD_SA}, + {(char*)"3N", no_argument, 0, ARG_3N}, + {(char*)"base-change", required_argument, 0, ARG_BASE_CHANGE}, + {(char*)0, 0, 0, 0} // terminator +}; + +/** + * Parse an int out of optarg and enforce that it be at least 'lower'; + * if it is less than 'lower', then output the given error message and + * exit with an error and a usage message. + */ +template +static T parseNumber(const char *str, T lower, const char *errmsg) +{ + char *endPtr= NULL; + T t = (T)strtoll(str, &endPtr, 10); + if(endPtr != NULL) { + if(t < lower) { + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + } + return t; + } + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + return -1; +} + +template +static T parseNumber(T lower, const char *errmsg) { + return parseNumber(optarg, lower, errmsg); +} + +static void parsePair(EList >& repeat_pair) +{ + string tok; + istringstream ss(optarg); + + while(getline(ss, tok, ',')) { + if(tok.empty()) { + continue; + } + + TIndexOffU min_len, max_len; + + size_t pos = tok.find('-'); + if(pos == string::npos) { + // min + min_len = parseNumber(tok.c_str(), 1, "min-repeat-length must be at least 1"); + max_len = numeric_limits::max(); + } else if(pos == tok.length() - 1) { + // min- + min_len = parseNumber(tok.substr(0, pos).c_str(), 1, "min-repeat-length must be at least 1"); + max_len = numeric_limits::max(); + } else if(pos == 0) { + // -max + // not support? + min_len = 100; + max_len = parseNumber(tok.substr(pos + 1).c_str(), 1, "max-repeat-length must be at least 1"); + } else { + min_len = parseNumber(tok.substr(0, pos).c_str(), 1, "min-repeat-length must be at least 1"); + max_len = parseNumber(tok.substr(pos + 1).c_str(), 1, "max-repeat-length must be at least 1"); + } + + if(min_len > max_len) { + printUsage(cerr); + throw 1; + } + if(max_len > numeric_limits::max()) { + printUsage(cerr); + throw 1; + } + + repeat_pair.push_back(pair(min_len, max_len)); + } +} + +/** + * Read command-line arguments + */ +static void parseOptions(int argc, const char **argv) { + int option_index = 0; + int next_option; + bool saw_max_repeat_matchlen = false; + do { + next_option = getopt_long( + argc, const_cast(argv), + short_options, long_options, &option_index); + switch (next_option) { + case ARG_WRAPPER: + wrapper = optarg; + break; + case 'f': format = FASTA; break; + case 'c': format = CMDLINE; break; + //case 'p': packed = true; break; + case 'C': + cerr << "Error: -C specified but Bowtie 2 does not support colorspace input." << endl; + throw 1; + break; + case 'l': + lineRate = parseNumber(3, "-l/--lineRate arg must be at least 3"); + lineRate_provided = true; + break; + case 'i': + linesPerSide = parseNumber(1, "-i/--linesPerSide arg must be at least 1"); + break; + case 'o': + offRate = parseNumber(0, "-o/--offRate arg must be at least 0"); + break; + case 'n': + // all f-s is used to mean "not set", so put 'e' on end + bmax = 0xfffffffe; + break; + case 'h': + case ARG_USAGE: + printUsage(cout); + throw 0; + break; + case ARG_BMAX: + bmax = parseNumber(1, "--bmax arg must be at least 1"); + bmaxMultSqrt = OFF_MASK; // don't use multSqrt + bmaxDivN = 0xffffffff; // don't use multSqrt + break; + case ARG_BMAX_MULT: + bmaxMultSqrt = parseNumber(1, "--bmaxmultsqrt arg must be at least 1"); + bmax = OFF_MASK; // don't use bmax + bmaxDivN = 0xffffffff; // don't use multSqrt + break; + case ARG_BMAX_DIV: + bmaxDivN = parseNumber(1, "--bmaxdivn arg must be at least 1"); + bmax = OFF_MASK; // don't use bmax + bmaxMultSqrt = OFF_MASK; // don't use multSqrt + break; + case ARG_DCV: + dcv = parseNumber(3, "--dcv arg must be at least 3"); + break; + case ARG_SEED: + seed = parseNumber(0, "--seed arg must be at least 0"); + break; + case ARG_SEED_LENGTH: + seed_length = parseNumber(1, "--seed-length arg must be at least 1"); + break; + case ARG_SEED_COUNT: + seed_count = parseNumber(2, "--repeat-count arg must be at least 2"); + break; + case ARG_MIN_REPEAT_LENGTH: + min_repeat_length = parseNumber(1, "--min-repeat-length arg must be at least 1"); + break; + case ARG_MAX_REPEAT_LENGTH: + max_repeat_length = parseNumber(1, "--max-repeat-length arg must be at least 1"); + break; + case ARG_REPEAT_LENGTH: + parsePair(repeat_length_pair); + break; + case ARG_REPEAT_COUNT: + repeat_count = parseNumber(2, "--repeat-count arg must be at least 2"); + break; + case ARG_REPEAT_EDIT: + max_repeat_edit = parseNumber(0, "--repeat-edit arg must be at least 0"); + break; + case ARG_REPEAT_MATCHLEN: + max_repeat_matchlen = parseNumber(0, "--repeat-matchlen arg must be at least 0"); + saw_max_repeat_matchlen = true; + break; + case ARG_REPEAT_INDEL: + repeat_indel = true; + break; + case ARG_ASYMMETRIC_EXTEND: + symmetric_extend = false; + break; + case ARG_FORWARD_ONLY: + forward_only = true; + break; + case ARG_CGTOTG: + CGtoTG = true; + break; + case ARG_REPEAT_STR1: + repeat_str1 = optarg; + break; + case ARG_REPEAT_STR2: + repeat_str2 = optarg; + break; + case ARG_MAX_SEED_MM: + max_seed_mm = parseNumber(1, "--max_seed_mm arg must be at least 1"); + break; + case ARG_MAX_SEED_REPEAT: + max_seed_repeat = parseNumber(5, "--max_seed_repeat arg must be at least 5"); + break; + case ARG_MAX_SEED_EXTLEN: + max_seed_extlen = parseNumber(0, "--max_seed_extlen arg must be at least 0"); + break; + case ARG_SAVE_SA: + save_sa = true; + break; + case ARG_LOAD_SA: + load_sa = true; + break; + case ARG_3N: { + threeN = true; + break; + } + case ARG_BASE_CHANGE: { + EList args; + tokenize(optarg, ",", args); + if(args.size() != 2) { + cerr << "Error: expected 2 comma-separated " + << "arguments to --base-change option, got " << args.size() << endl; + throw 1; + } + getConversion(args[0][0], args[1][0], convertedFrom, convertedTo); + + string s = "ACGT"; + if ((s.find(convertedFrom) == std::string::npos) || (s.find(convertedTo) == std::string::npos)) { + cerr << "Please enter the nucleotide in 'ACGT' for --base-change option." << endl; + throw 1; + } + + if (convertedFrom == convertedTo) { + cerr << "Please enter two different base for --base-change option. If you wish to build the repeat database without nucleotide conversion, please do not use --base-change and --3N options." << endl; + throw 1; + } + + base_change_entered = true; + } + case 'a': autoMem = false; break; + case 'q': verbose = false; break; + case 's': sanityCheck = true; break; + case 'p': + nthreads = parseNumber(1, "-p arg must be at least 1"); + break; + + case -1: /* Done with options. */ + break; + case 0: + if (long_options[option_index].flag != 0) + break; + default: + printUsage(cerr); + throw 1; + } + } while(next_option != -1); + + if(bmax < 40) { + cerr << "Warning: specified bmax is very small (" << bmax << "). This can lead to" << endl + << "extremely slow performance and memory exhaustion. Perhaps you meant to specify" << endl + << "a small --bmaxdivn?" << endl; + } + + if(!saw_max_repeat_matchlen) { + max_repeat_matchlen = min_repeat_length / 2; + } +} + +extern void initializeCntLut(); +extern void initializeCntBit(); + + +ConvertMatrix3N baseChange; +/** + * Drive the index construction process and optionally sanity-check the + * result. + */ +template +static void driver( + const string& infile, + EList& infiles, + const string& outfile, + bool packed, + bool forward_only, + bool CGtoTG) +{ + initializeCntLut(); + initializeCntBit(); + + EList is(MISC_CAT); + bool bisulfite = false; + bool nsToAs = false; + RefReadInParams refparams(false, false /* reverse */, nsToAs, bisulfite); + assert_gt(infiles.size(), 0); + if(format == CMDLINE) { + // Adapt sequence strings to stringstreams open for input + stringstream *ss = new stringstream(); + for(size_t i = 0; i < infiles.size(); i++) { + (*ss) << ">" << i << endl << infiles[i].c_str() << endl; + } + FileBuf *fb = new FileBuf(ss); + assert(fb != NULL); + assert(!fb->eof()); + assert(fb->get() == '>'); + ASSERT_ONLY(fb->reset()); + assert(!fb->eof()); + is.push_back(fb); + } else { + // Adapt sequence files to ifstreams + for(size_t i = 0; i < infiles.size(); i++) { + FILE *f = fopen(infiles[i].c_str(), "r"); + if (f == NULL) { + cerr << "Error: could not open "<< infiles[i].c_str() << endl; + throw 1; + } + FileBuf *fb = new FileBuf(f); + assert(fb != NULL); + if(fb->peek() == -1 || fb->eof()) { + cerr << "Warning: Empty fasta file: '" << infile.c_str() << "'" << endl; + continue; + } + assert(!fb->eof()); + assert(fb->get() == '>'); + ASSERT_ONLY(fb->reset()); + assert(!fb->eof()); + is.push_back(fb); + } + } + if(is.empty()) { + cerr << "Warning: All fasta inputs were empty" << endl; + throw 1; + } + + // Vector for the ordered list of "records" comprising the input + // sequences. A record represents a stretch of unambiguous + // characters in one of the input sequences. + EList szs; + EList ref_names; + std::pair sztot; + { + if(verbose) cerr << "Reading reference sizes" << endl; + Timer _t(cerr, " Time reading reference sizes: ", verbose); + sztot = BitPairReference::szsFromFasta(is, "", bigEndian, refparams, szs, sanityCheck, &ref_names); + } + + assert_gt(sztot.first, 0); + assert_gt(sztot.second, 0); + assert_gt(szs.size(), 0); + + // Compose text strings into single string + cerr << "Calculating joined length" << endl; + TIndexOffU jlen = 0; + for(unsigned int i = 0; i < szs.size(); i++) { + jlen += (TIndexOffU)szs[i].len; + } + // assert_geq(jlen, sztot); + cerr << " Joined length: " << jlen << endl; + TStr s; + { + bool both_strand = forward_only ? false : true; + cerr << "Reserving space for joined string" << endl; + cerr << "Joining reference sequences" << endl; + Timer timer(cerr, " Time to join reference sequences: ", verbose); + GFM::join( + is, + szs, + (TIndexOffU) sztot.first, + refparams, + seed, + s, + both_strand, // include reverse complemented sequence + CGtoTG); //Change CG to TG + } + + TStr sOriginal; + if (threeN) { + baseChange.restoreNormal(); + bool both_strand = forward_only ? false : true; + for (int i = 0; i < is.size(); i++) { + is[i]->reset(); + } + GFM::join( + is, + szs, + (TIndexOffU) sztot.first, + refparams, + seed, + sOriginal, + both_strand, // include reverse complemented sequence + CGtoTG); //Change CG to TG + baseChange.restoreConversion(); + + long long int guessLen = s.length() / 2; + for (TIndexOffU i = 0; i < guessLen; i++) { + int nt = sOriginal[guessLen - i - 1]; + assert_range(0, 3, nt); + s[guessLen + i] = dnacomp[nt]; + } + } else { + sOriginal = s; + } + + // Successfully obtained joined reference string +#ifndef NDEBUG + if(forward_only) { + assert_geq(s.length(), jlen); + } else { + assert_geq(s.length(), jlen << 1); + } +#endif + + + BitPackedArray suffix_array; + + bool sa_file_exist = false; + string sa_fname = outfile + ".rep.sa"; + if(load_sa) { + ifstream fp(sa_fname, std::ifstream::binary); + sa_file_exist = fp.is_open(); + } + + if(load_sa && sa_file_exist) { + cerr << "Load SA from " << sa_fname << endl; + suffix_array.readFile(sa_fname); + } else { + suffix_array.init(s.length() + 1); + + if(bmax != (TIndexOffU) OFF_MASK) { + // VMSG_NL("bmax according to bmax setting: " << bmax); + } else if(bmaxDivN != (uint32_t) OFF_MASK) { + bmax = max(jlen / (bmaxDivN * nthreads), 1); + // VMSG_NL("bmax according to bmaxDivN setting: " << bmax); + } else { + bmax = (uint32_t) sqrt(s.length()); + // VMSG_NL("bmax defaulted to: " << bmax); + } + int iter = 0; + bool first = true; + bool passMemExc = false, sanity = false; + // Look for bmax/dcv parameters that work. + while(true) { + if(!first && bmax < 40 && passMemExc) { + cerr << "Could not find appropriate bmax/dcv settings for building this index." << endl; + cerr << "Please try indexing this reference on a computer with more memory." << endl; + if (sizeof(void *) == 4) { + cerr << "If this computer has more than 4 GB of memory, try using a 64-bit executable;" << endl + << "this executable is 32-bit." << endl; + } + throw 1; + } + if(dcv > 4096) dcv = 4096; + if((iter % 6) == 5 && dcv < 4096 && dcv != 0) { + dcv <<= 1; // double difference-cover period + } else { + bmax -= (bmax >> 2); // reduce by 25% + } + iter++; + + suffix_array.reset(); + + try { + cerr << "Using parameters --bmax " << bmax << endl; + if(dcv == 0) { + cerr << " and *no difference cover*" << endl; + } else { + cerr << " --dcv " << dcv << endl; + } + { + cerr << " Doing ahead-of-time memory usage test" << endl; + // Make a quick-and-dirty attempt to force a bad_alloc iff + // we would have thrown one eventually as part of + // constructing the DifferenceCoverSample + dcv <<= 1; + TIndexOffU sz = (TIndexOffU) DifferenceCoverSample::simulateAllocs(s, dcv >> 1); + if(nthreads > 1) sz *= (nthreads + 1); + AutoArray tmp(sz, EBWT_CAT); + dcv >>= 1; + // Likewise with the KarkkainenBlockwiseSA + sz = (TIndexOffU) KarkkainenBlockwiseSA::simulateAllocs(s, bmax); + AutoArray tmp2(sz, EBWT_CAT); + // Grab another 20 MB out of caution + AutoArray extra(20 * 1024 * 1024, EBWT_CAT); + // If we made it here without throwing bad_alloc, then we + // passed the memory-usage stress test + cerr << " Passed! Constructing with these parameters: --bmax " << bmax << " --dcv " << dcv + << endl; + cerr << "" << endl; + } + cerr << "Constructing suffix-array element generator" << endl; + + KarkkainenBlockwiseSA bsa(s, + bmax, + nthreads, + dcv, + seed, + sanity, + passMemExc, + false /* verbose */, + outfile); + + assert(bsa.suffixItrIsReset()); + assert_eq(bsa.size(), s.length() + 1); + + TIndexOffU count = 0; + + while(count < s.length() + 1) { + TIndexOffU saElt = bsa.nextSuffix(); + count++; + + if(count && (count % 10000000 == 0)) { + cerr << "SA count " << count << endl; + } + + if(saElt == s.length()) { + assert_eq(count, s.length() + 1); + break; + } + + suffix_array.pushBack(saElt); + } + + break; + + } catch (bad_alloc &e) { + if(passMemExc) { + cerr << " Ran out of memory; automatically trying more memory-economical parameters." << endl; + } else { + cerr << "Out of memory while constructing suffix array. Please try using a smaller" << endl + << "number of blocks by specifying a smaller --bmax or a larger --bmaxdivn" << endl; + throw 1; + } + } + first = false; + } + + if(save_sa) { + suffix_array.writeFile(sa_fname); + } + } + + cerr << "suffix_array: " << endl; + suffix_array.dump(); + + + // Build Repeats + { + if(repeat_length_pair.empty()) { + repeat_length_pair.push_back(pair(min_repeat_length, max_repeat_length)); + } + + RepeatParameter rp; + rp.seed_len = seed_length; + rp.seed_count = seed_count; + rp.seed_mm = max_seed_mm; + rp.max_edit = max_repeat_edit; + rp.symmetric_extend = symmetric_extend; + rp.extend_unit_len = max_seed_extlen; + for(size_t i = 0; i < repeat_length_pair.size(); i++) { + rp.min_repeat_len = repeat_length_pair[i].first; + rp.max_repeat_len = repeat_length_pair[i].second; + rp.repeat_count = repeat_count; + rp.append_result = (i != 0); + + RepeatBuilder repeatBuilder(s, + sOriginal, + szs, + ref_names, + forward_only, + outfile); + cerr << "RepeatBuilder: " << outfile << " " << rp.min_repeat_len << "-" << rp.max_repeat_len << endl; + + { + Timer _t(cerr, " Time reading suffix array: ", verbose); + repeatBuilder.readSA(rp, suffix_array); + } + + repeatBuilder.build(rp); + repeatBuilder.saveFile(rp); + } + } +} + +static const char *argv0 = NULL; + +extern "C" { +/** + * main function. Parses command-line arguments. + */ +int hisat2_repeat(int argc, const char **argv) { + string outfile; + try { + // Reset all global state, including getopt state + opterr = optind = 1; + resetOptions(); + + string infile; + EList infiles(MISC_CAT); + + parseOptions(argc, argv); + argv0 = argv[0]; + if(showVersion) { + cout << argv0 << " version " << string(HISAT2_VERSION).c_str() << endl; + if(sizeof(void*) == 4) { + cout << "32-bit" << endl; + } else if(sizeof(void*) == 8) { + cout << "64-bit" << endl; + } else { + cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl; + } + cout << "Built on " << BUILD_HOST << endl; + cout << BUILD_TIME << endl; + cout << "Compiler: " << COMPILER_VERSION << endl; + cout << "Options: " << COMPILER_OPTIONS << endl; + cout << "Sizeof {int, long, long long, void*, size_t, off_t}: {" + << sizeof(int) + << ", " << sizeof(long) << ", " << sizeof(long long) + << ", " << sizeof(void *) << ", " << sizeof(size_t) + << ", " << sizeof(off_t) << "}" << endl; + return 0; + } + + if (!threeN && base_change_entered) { + cerr << "To build hisat-3n repeat database, please add argument --3N. To build the hisat2 repeat database, please remove the argument --base-change." << endl; + printUsage(cerr); + throw 1; + } + if (threeN) { + convertedFromComplement = asc2dnacomp[convertedFrom]; + convertedToComplement = asc2dnacomp[convertedTo]; + } + // Get input filename + if(optind >= argc) { + cerr << "No input sequence or sequence file specified!" << endl; + printUsage(cerr); + return 1; + } + infile = argv[optind++]; + + if(optind >= argc) { + cerr << "No output file specified!" << endl; + printUsage(cerr); + return 1; + } + outfile = argv[optind++]; + + tokenize(infile, ",", infiles); + if(infiles.size() < 1) { + cerr << "Tokenized input file list was empty!" << endl; + printUsage(cerr); + return 1; + } + + // Optionally summarize + if(verbose) { + cerr << "Settings:" << endl; + // << " Output files: \"" << outfile.c_str() << ".*." << gfm_ext << "\"" << endl; + cerr << " Endianness: " << (bigEndian? "big":"little") << endl + << " Actual local endianness: " << (currentlyBigEndian()? "big":"little") << endl + << " Sanity checking: " << (sanityCheck? "enabled":"disabled") << endl; + #ifdef NDEBUG + cerr << " Assertions: disabled" << endl; + #else + cerr << " Assertions: enabled" << endl; + #endif + cerr << " Random seed: " << seed << endl; + cerr << " Sizeofs: void*:" << sizeof(void*) << ", int:" << sizeof(int) << ", long:" << sizeof(long) << ", size_t:" << sizeof(size_t) << endl; + cerr << "Input files DNA, " << file_format_names[format].c_str() << ":" << endl; + for(size_t i = 0; i < infiles.size(); i++) { + cerr << " " << infiles[i].c_str() << endl; + } + } + // Seed random number generator + srand(seed); + { + Timer timer(cerr, "Total time for call to driver() for forward index: ", verbose); + try { + int nloop = threeN ? 2 : 1; // if threeN == true, nloop = 2. else one loop + for (int i = 0; i < nloop; i++) { + string tag = ""; + if (threeN) { + tag += ".3n."; + if (i == 0) { + tag += convertedFrom; + tag += convertedTo; + baseChange.convert(convertedFrom, convertedTo); + } else { + tag += convertedFromComplement; + tag += convertedToComplement; + baseChange.convert(convertedFromComplement, convertedToComplement); + } + + string indexFilename = outfile + tag + ".rep.fa"; + if (fileExist(indexFilename)) { + cerr << "*** Find repeat database for " << outfile + tag << ",skip this repeat database building process." << endl; + cerr << " To re-build your hisat-3n repeat database, please delete the old index manually before running hisat2-repeat or hisat-3n-build." << endl; + continue; + } + } + driver >(infile, infiles, outfile + tag, false, forward_only, CGtoTG); + } + + } catch(bad_alloc& e) { + if(autoMem) { + cerr << "Switching to a packed string representation." << endl; + } else { + throw e; + } + } + } + return 0; + } catch(std::exception& e) { + cerr << "Error: Encountered exception: '" << e.what() << "'" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + return 1; + } catch(int e) { + if(e != 0) { + cerr << "Error: Encountered internal HISAT2 exception (#" << e << ")" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + } + return e; + } +} +} diff --git a/hisat2_repeat_main.cpp b/hisat2_repeat_main.cpp new file mode 100644 index 0000000..a5f3cc0 --- /dev/null +++ b/hisat2_repeat_main.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include +#include +#include "tokenize.h" +#include "ds.h" +#include "mem_ids.h" + +using namespace std; + +extern "C" { + int hisat2_repeat(int argc, const char **argv); +} + +/** + * bowtie-build main function. It is placed in a separate source file + * to make it slightly easier to compile as a library. + * + * If the user specifies -A as the first two arguments, main + * will interpret that file as having one set of command-line arguments + * per line, and will dispatch each batch of arguments one at a time to + * bowtie-build. + */ +int main(int argc, const char **argv) { + if(argc > 2 && strcmp(argv[1], "-A") == 0) { + const char *file = argv[2]; + ifstream in; + in.open(file); + char buf[4096]; + int lastret = -1; + while(in.getline(buf, 4095)) { + EList args(MISC_CAT); + args.push_back(string(argv[0])); + tokenize(buf, " \t", args); + const char **myargs = (const char**)malloc(sizeof(char*)*args.size()); + for(size_t i = 0; i < args.size(); i++) { + myargs[i] = args[i].c_str(); + } + if(args.size() == 1) continue; + lastret = hisat2_repeat((int)args.size(), myargs); + free(myargs); + } + if(lastret == -1) { + cerr << "Warning: No arg strings parsed from " << file << endl; + return 0; + } + return lastret; + } else { + return hisat2_repeat(argc, argv); + } +} diff --git a/hisat2_simulate_reads.py b/hisat2_simulate_reads.py new file mode 100644 index 0000000..c503522 --- /dev/null +++ b/hisat2_simulate_reads.py @@ -0,0 +1,971 @@ +#!/usr/bin/env python3 +# +# Copyright 2015, Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +import os, sys, math, random, re +from collections import defaultdict, Counter +from argparse import ArgumentParser, FileType + + +""" +""" +def reverse_complement(seq): + result = "" + for nt in seq: + base = nt + if nt == 'A': + base = 'T' + elif nt == 'a': + base = 't' + elif nt == 'C': + base = 'G' + elif nt == 'c': + base = 'g' + elif nt == 'G': + base = 'C' + elif nt == 'g': + base = 'c' + elif nt == 'T': + base = 'A' + elif nt == 't': + base = 'a' + + result = base + result + + return result + + +""" +python2 style randint +""" +def myrandint(m, x): + s = x - m + 1 + return m + int(random.random() * s) + +""" +Random source for sequencing errors +""" +class ErrRandomSource: + def __init__(self, prob = 0.0, size = 1 << 20): + self.size = size + self.rands = [] + for i in range(self.size): + if random.random() < prob: + self.rands.append(1) + else: + self.rands.append(0) + self.cur = 0 + + def getRand(self): + assert self.cur < len(self.rands) + rand = self.rands[self.cur] + self.cur = (self.cur + 1) % len(self.rands) + return rand + + +""" +""" +def read_genome(genome_file): + chr_dic = {} + + chr_name, sequence = "", "" + for line in genome_file: + if line[0] == ">": + if chr_name and sequence: + chr_dic[chr_name] = sequence + chr_name = line.strip().split()[0][1:] + sequence = "" + else: + sequence += line[:-1] + + if chr_name and sequence: + chr_dic[chr_name] = sequence + + + chr_filter = [str(x) for x in list(range(1, 23)) + ['X', 'Y']] + #chr_filter = None + + if chr_filter: + for chr_id, chr_seq in chr_dic.items(): + if not chr_id in chr_filter: + chr_dic.pop(chr_id, None) + + return chr_dic + + +""" +""" +def read_transcript(genome_seq, gtf_file, frag_len): + genes = defaultdict(list) + transcripts = {} + + # Parse valid exon lines from the GTF file into a dict by transcript_id + for line in gtf_file: + line = line.strip() + if not line or line.startswith('#'): + continue + if '#' in line: + line = line.split('#')[0].strip() + try: + chrom, source, feature, left, right, score, \ + strand, frame, values = line.split('\t') + except ValueError: + continue + if chrom not in genome_seq: + continue + + # Zero-based offset + left, right = int(left) - 1, int(right) - 1 + if feature != 'exon' or left >= right: + continue + + values_dict = {} + for attr in values.split(';')[:-1]: + attr, _, val = attr.strip().partition(' ') + values_dict[attr] = val.strip('"') + + if 'gene_id' not in values_dict or \ + 'transcript_id' not in values_dict: + continue + + transcript_id = values_dict['transcript_id'] + if transcript_id not in transcripts: + transcripts[transcript_id] = [chrom, strand, [[left, right]]] + genes[values_dict['gene_id']].append(transcript_id) + else: + transcripts[transcript_id][2].append([left, right]) + + # Sort exons and merge where separating introns are <=5 bps + for tran, [chr, strand, exons] in transcripts.items(): + exons.sort() + tmp_exons = [exons[0]] + for i in range(1, len(exons)): + if exons[i][0] - tmp_exons[-1][1] <= 5: + tmp_exons[-1][1] = exons[i][1] + else: + tmp_exons.append(exons[i]) + transcripts[tran] = [chr, strand, tmp_exons] + + tmp_transcripts = {} + for tran, [chr, strand, exons] in transcripts.items(): + exon_lens = [e[1] - e[0] + 1 for e in exons] + transcript_len = sum(exon_lens) + if transcript_len >= frag_len: + tmp_transcripts[tran] = [chr, strand, transcript_len, exons] + + transcripts = tmp_transcripts + + return genes, transcripts + + +""" +""" +def read_snp(snp_file): + snps = defaultdict(list) + for line in snp_file: + line = line.strip() + if not line or line.startswith('#'): + continue + try: + snpID, type, chr, pos, data = line.split('\t') + except ValueError: + continue + + assert type in ["single", "deletion", "insertion"] + if type == "deletion": + data = int(data) + snps[chr].append([snpID, type, int(pos), data]) + + return snps + + +""" +""" +def sanity_check_input(genome_seq, genes, transcripts, snps, frag_len): + num_canon_ss, num_ss = 0, 0 + for transcript, [chr, strand, transcript_len, exons] in transcripts.items(): + assert transcript_len >= frag_len + if len(exons) <= 1: + continue + if chr not in genome_seq: + continue + chr_seq = genome_seq[chr] + for i in range(len(exons) - 1): + left1, right1 = exons[i] + assert left1 < right1 + left2, right2 = exons[i+1] + assert left2 < right2 + assert left1 < left2 and right1 < right2 + donor = chr_seq[right1+1:right1+3] + acceptor = chr_seq[left2-2:left2] + if strand == "-": + donor, acceptor = reverse_complement(acceptor), reverse_complement(donor) + if donor == "GT" and acceptor == "AG": + num_canon_ss += 1 + num_ss += 1 + + if num_ss > 0: + print("GT/AG splice sites: {}/{} ({:.2%})".format(num_canon_ss, num_ss, (float(num_canon_ss) / num_ss)), file=sys.stderr) + + num_alt_single, num_single = 0, 0 + for chr, chr_snps in snps.items(): + if chr not in genome_seq: + continue + chr_seq = genome_seq[chr] + prev_snp = None + for snp in chr_snps: + snpID, type, pos, data = snp + if prev_snp: + assert prev_snp[2] <= pos + prev_snp = snp + if type != "single": + continue + assert pos < len(chr_seq) + if chr_seq[pos] != data: + num_alt_single += 1 + num_single += 1 + + if num_single > 0: + print("Alternative bases: {}/{} ({:.2%})".format(num_alt_single, num_single, (float(num_alt_single) / num_single)), file=sys.stderr) + + +""" +""" +def generate_rna_expr_profile(expr_profile_type, num_transcripts = 10000): + # Modelling and simulating generic RNA-Seq experiments with the flux simulator + # http://nar.oxfordjournals.org/content/suppl/2012/06/29/gks666.DC1/nar-02667-n-2011-File002.pdf + def calc_expr(x, a): + x, a, b = float(x), 9500.0, 9500.0 + k = -0.6 + return (x**k) * math.exp(x/a * (x/b)**2) + + expr_profile = [0.0] * num_transcripts + for i in range(len(expr_profile)): + if expr_profile_type == "flux": + expr_profile[i] = calc_expr(i + 1, num_transcripts) + elif expr_profile_type == "constant": + expr_profile[i] = 1.0 + else: + assert False + + expr_sum = sum(expr_profile) + expr_profile = [expr_profile[i] / expr_sum for i in range(len(expr_profile))] + assert abs(sum(expr_profile) - 1.0) < 0.001 + return expr_profile + + +""" +""" +def generate_dna_expr_profile(genome_seq): + expr_profile = [] + for chr_id, chr_seq in genome_seq.items(): + expr_profile.append(len(chr_seq)) + expr_sum = float(sum(expr_profile)) + expr_profile = [expr_profile[i] / expr_sum for i in range(len(expr_profile))] + assert abs(sum(expr_profile) - 1.0) < 0.001 + return expr_profile + + +""" +""" +def getSNPs(chr_snps, left, right): + low, high = 0, len(chr_snps) + while low < high: + mid = (low + high) // 2 + snpID, type, pos, data = chr_snps[mid] + if pos < left: + low = mid + 1 + else: + high = mid - 1 + + snps = [] + for snp in chr_snps[low:]: + snpID, type, pos, data = snp + pos2 = pos + if type == "deletion": + pos2 += data + if pos2 >= right: + break + if pos >= left: + if len(snps) > 0: + _, prev_type, prev_pos, prev_data = snps[-1] + assert prev_pos <= pos + prev_pos2 = prev_pos + if prev_type == "deletion": + prev_pos2 += prev_data + if pos <= prev_pos2: + continue + snps.append(snp) + + return snps + + +""" +""" +def getSamAlignment(rna, exons, chr_seq, trans_seq, frag_pos, read_len, chr_snps, snp_prob, err_rand_src, max_mismatch): + # Find the genomic position for frag_pos and exon number + tmp_frag_pos, tmp_read_len = frag_pos, read_len + pos, cigars, cigar_descs = exons[0][0], [], [] + e_pos = 0 + prev_e = None + for e_i in range(len(exons)): + e = exons[e_i] + if prev_e: + i_len = e[0] - prev_e[1] - 1 + pos += i_len + e_len = e[1] - e[0] + 1 + if e_len <= tmp_frag_pos: + tmp_frag_pos -= e_len + pos += e_len + else: + pos += tmp_frag_pos + e_pos = tmp_frag_pos + break + prev_e = e + + # Define Cigar and its descriptions + assert e_i < len(exons) + e_len = exons[e_i][1] - exons[e_i][0] + 1 + assert e_pos < e_len + cur_pos = pos + match_len = 0 + prev_e = None + mismatch, remain_trans_len = 0, len(trans_seq) - (frag_pos + read_len) + assert remain_trans_len >= 0 + for e_i in range(e_i, len(exons)): + e = exons[e_i] + if prev_e: + i_len = e[0] - prev_e[1] - 1 + cur_pos += i_len + cigars.append(("{}N".format(i_len))) + cigar_descs.append([]) + tmp_e_left = e_left = e[0] + e_pos + e_pos = 0 + + # Retreive SNPs + if rna: + snps = getSNPs(chr_snps, e_left, e[1]) + else: + snps = getSNPs(chr_snps, frag_pos, frag_pos + read_len) + + if snp_prob < 1.0 and len(snps) > 0: + snps_ = [] + for snp in snps: + if random.random() <= snp_prob: + snps_.append(snp) + snps = snps_ + + # Simulate mismatches due to sequencing errors + mms = [] + for i in range(e_left, min(e[1], e_left + tmp_read_len - 1)): + if err_rand_src.getRand() == 1: + assert i < len(chr_seq) + err_base = "A" + #rand = random.randint(0, 2) + rand = myrandint(0, 2) + if chr_seq[i] == "A": + err_base = "GCT"[rand] + elif chr_seq[i] == "C": + err_base = "AGT"[rand] + elif chr_seq[i] == "G": + err_base = "ACT"[rand] + else: + err_base = "ACG"[rand] + mms.append(["", "single", i, err_base]) + + tmp_diffs = snps + mms +# def diff_sort(a , b): +# return a[2] - b[2] + + tmp_diffs = sorted(tmp_diffs, key=lambda t: t[2]) + diffs = [] + if len(tmp_diffs) > 0: + diffs = tmp_diffs[:1] + for diff in tmp_diffs[1:]: + _, tmp_type, tmp_pos, tmp_data = diff + _, prev_type, prev_pos, prev_data = diffs[-1] + if prev_type == "deletion": + prev_pos += prev_data + if tmp_pos <= prev_pos: + continue + diffs.append(diff) + + cigar_descs.append([]) + prev_diff = None + for diff in diffs: + diff_id, diff_type, diff_pos, diff_data = diff + if prev_diff: + prev_diff_id, prev_diff_type, prev_diff_pos, prev_diff_data = prev_diff + if prev_diff_type == "deletion": + prev_diff_pos += prev_diff_data + assert prev_diff_pos < diff_pos + diff_pos2 = diff_pos + if diff_type == "deletion": + diff_pos2 += diff_data + if e_left + tmp_read_len - 1 < diff_pos2 or e[1] < diff_pos2: + break + + if diff_type == "single": + if mismatch + 1 > max_mismatch: + continue + cigar_descs[-1].append([diff_pos - tmp_e_left, diff_data, diff_id]) + tmp_e_left = diff_pos + 1 + mismatch += 1 + elif diff_type == "deletion": + del_len = diff_data + if mismatch + del_len > max_mismatch: + continue + if len(cigars) <= 0 and diff_pos - e_left <= 0: + continue + if remain_trans_len < del_len: + continue + remain_trans_len -= del_len + if diff_pos - e_left > 0: + cigars.append("{}M".format(diff_pos - e_left)) + cigar_descs[-1].append([diff_pos - tmp_e_left, "", ""]) + cigar_descs.append([]) + cigars.append("{}D".format(del_len)) + cigar_descs[-1].append([0, del_len, diff_id]) + cigar_descs.append([]) + tmp_read_len -= (diff_pos - e_left) + e_left = tmp_e_left = diff_pos + del_len + + elif diff_type == "insertion": + ins_len = len(diff_data) + if mismatch + ins_len > max_mismatch: + continue + if len(cigars) <= 0 and diff_pos - e_left <= 0: + continue + if e_left + tmp_read_len - 1 < diff_pos + ins_len: + break + if diff_pos - e_left > 0: + cigars.append("{}M".format(diff_pos - e_left)) + cigar_descs[-1].append([diff_pos - tmp_e_left, "", ""]) + cigar_descs.append([]) + cigars.append("{}I".format(ins_len)) + cigar_descs[-1].append([0, diff_data, diff_id]) + cigar_descs.append([]) + tmp_read_len -= (diff_pos - e_left) + tmp_read_len -= ins_len + e_left = tmp_e_left = diff_pos + + else: + assert False + prev_diff = diff + + e_right = min(e[1], e_left + tmp_read_len - 1) + e_len = e_right - e_left + 1 + remain_e_len = e_right - tmp_e_left + 1 + if remain_e_len > 0: + cigar_descs[-1].append([remain_e_len, "", ""]) + if e_len < tmp_read_len: + tmp_read_len -= e_len + cigars.append(("{}M".format(e_len))) + else: + assert e_len == tmp_read_len + cigars.append(("{}M".format(tmp_read_len))) + tmp_read_len = 0 + break + prev_e = e + + # Define MD, XM, NM, Zs, read_seq + MD, XM, NM, Zs, read_seq = "", 0, 0, "", "" + assert len(cigars) == len(cigar_descs) + MD_match_len, Zs_match_len = 0, 0 + cur_trans_pos = frag_pos + for c in range(len(cigars)): + cigar = cigars[c] + cigar_len, cigar_op = int(cigar[:-1]), cigar[-1] + cigar_desc = cigar_descs[c] + if cigar_op == 'N': + continue + if cigar_op == 'M': + for add_match_len, alt_base, snp_id in cigar_desc: + MD_match_len += add_match_len + Zs_match_len += add_match_len + assert cur_trans_pos + add_match_len <= len(trans_seq) + read_seq += trans_seq[cur_trans_pos:cur_trans_pos+add_match_len] + cur_trans_pos += add_match_len + if alt_base != "": + if MD_match_len > 0: + MD += ("{}".format(MD_match_len)) + MD_match_len = 0 + MD += trans_seq[cur_trans_pos] + if snp_id != "": + if Zs != "": + Zs += "," + Zs += ("{}|S|{}".format(Zs_match_len, snp_id)) + Zs_match_len = 0 + else: + Zs_match_len += 1 + if snp_id == "": + XM += 1 + NM += 1 + read_seq += alt_base + cur_trans_pos += 1 + elif cigar_op == 'D': + assert len(cigar_desc) == 1 + add_match_len, del_len, snp_id = cigar_desc[0] + MD_match_len += add_match_len + Zs_match_len += add_match_len + if MD_match_len > 0: + MD += ("{}".format(MD_match_len)) + MD_match_len = 0 + MD += ("^{}".format(trans_seq[cur_trans_pos:cur_trans_pos+cigar_len])) + read_seq += trans_seq[cur_trans_pos:cur_trans_pos+add_match_len] + if Zs != "": + Zs += "," + Zs += ("{}|D|{}".format(Zs_match_len, cigar_desc[0][-1])) + Zs_match_len = 0 + cur_trans_pos += cigar_len + elif cigar_op == 'I': + assert len(cigar_desc) == 1 + add_match_len, ins_seq, snp_id = cigar_desc[0] + ins_len = len(ins_seq) + MD_match_len += add_match_len + Zs_match_len += add_match_len + read_seq += trans_seq[cur_trans_pos:cur_trans_pos+add_match_len] + read_seq += ins_seq + if Zs != "": + Zs += "," + Zs += ("{}|I|{}".format(Zs_match_len, cigar_desc[0][-1])) + Zs_match_len = 0 + else: + assert False + + if MD_match_len > 0: + MD += ("{}".format(MD_match_len)) + + if len(read_seq) != read_len: + print("read length differs:", len(read_seq), "vs.", read_len, file=sys.stderr) + print(pos, "".join(cigars), cigar_descs, MD, XM, NM, Zs, file=sys.stderr) + assert False + + return pos, cigars, cigar_descs, MD, XM, NM, Zs, read_seq + + +""" +""" +cigar_re = re.compile('\d+\w') +def samRepOk(genome_seq, read_seq, chr, pos, cigar, XM, NM, MD, Zs, max_mismatch): + assert chr in genome_seq + chr_seq = genome_seq[chr] + assert pos < len(chr_seq) + + # Calculate XM and NM based on Cigar and Zs + cigars = cigar_re.findall(cigar) + cigars = [[int(cigars[i][:-1]), cigars[i][-1]] for i in range(len(cigars))] + ref_pos, read_pos = pos, 0 + ann_ref_seq, ann_ref_rel, ann_read_seq, ann_read_rel = [], [], [], [] + for i in range(len(cigars)): + cigar_len, cigar_op = cigars[i] + if cigar_op == "M": + partial_ref_seq = chr_seq[ref_pos:ref_pos+cigar_len] + partial_read_seq = read_seq[read_pos:read_pos+cigar_len] + assert len(partial_ref_seq) == len(partial_read_seq) + ann_ref_seq += list(partial_ref_seq) + ann_read_seq += list(partial_read_seq) + for j in range(len(partial_ref_seq)): + if partial_ref_seq[j] == partial_read_seq[j]: + ann_ref_rel.append("=") + ann_read_rel.append("=") + else: + ann_ref_rel.append("X") + ann_read_rel.append("X") + ref_pos += cigar_len + read_pos += cigar_len + elif cigar_op == "D": + partial_ref_seq = chr_seq[ref_pos:ref_pos+cigar_len] + ann_ref_rel += list(partial_ref_seq) + ann_ref_seq += list(partial_ref_seq) + ann_read_rel += (["-"] * cigar_len) + ann_read_seq += (["-"] * cigar_len) + ref_pos += cigar_len + elif cigar_op == "I": + partial_read_seq = read_seq[read_pos:read_pos+cigar_len] + ann_ref_rel += (["-"] * cigar_len) + ann_ref_seq += (["-"] * cigar_len) + ann_read_rel += list(partial_read_seq) + ann_read_seq += list(partial_read_seq) + read_pos += cigar_len + elif cigar_op == "N": + ref_pos += cigar_len + else: + assert False + + assert len(ann_ref_seq) == len(ann_read_seq) + assert len(ann_ref_seq) == len(ann_ref_rel) + assert len(ann_ref_seq) == len(ann_read_rel) + ann_Zs_seq = ["0" for i in range(len(ann_ref_seq))] + + Zss, Zs_i, snp_pos_add = [], 0, 0 + if Zs != "": + Zss = Zs.split(',') + Zss = [zs.split('|') for zs in Zss] + + ann_read_pos = 0 + for zs in Zss: + zs_pos, zs_type, zs_id = zs + zs_pos = int(zs_pos) + for i in range(zs_pos): + while ann_read_rel[ann_read_pos] == '-': + ann_read_pos += 1 + ann_read_pos += 1 + if zs_type == "S": + ann_Zs_seq[ann_read_pos] = "1" + ann_read_pos += 1 + elif zs_type == "D": + while ann_read_rel[ann_read_pos] == '-': + ann_Zs_seq[ann_read_pos] = "1" + ann_read_pos += 1 + elif zs_type == "I": + while ann_ref_rel[ann_read_pos] == '-': + ann_Zs_seq[ann_read_pos] = "1" + ann_read_pos += 1 + else: + assert False + + tMD, tXM, tNM = "", 0, 0 + match_len = 0 + i = 0 + while i < len(ann_ref_seq): + if ann_ref_rel[i] == "=": + assert ann_read_rel[i] == "=" + match_len += 1 + i += 1 + continue + assert ann_read_rel[i] != "=" + if ann_ref_rel[i] == "X" and ann_read_rel[i] == "X": + if match_len > 0: + tMD += ("{}".format(match_len)) + match_len = 0 + tMD += ann_ref_seq[i] + if ann_Zs_seq[i] == "0": + tXM += 1 + tNM += 1 + i += 1 + else: + assert ann_ref_rel[i] == "-" or ann_read_rel[i] == "-" + if ann_ref_rel[i] == '-': + while ann_ref_rel[i] == '-': + if ann_Zs_seq[i] == "0": + tNM += 1 + i += 1 + else: + assert ann_read_rel[i] == '-' + del_seq = "" + while ann_read_rel[i] == '-': + del_seq += ann_ref_seq[i] + if ann_Zs_seq[i] == "0": + tNM += 1 + i += 1 + if match_len > 0: + tMD += ("{}".format(match_len)) + match_len = 0 + tMD += ("^{}".format(del_seq)) + + if match_len > 0: + tMD += ("{}".format(match_len)) + + if tMD != MD or tXM != XM or tNM != NM or XM > max_mismatch or XM != NM: + print(chr, pos, cigar, MD, XM, NM, Zs, file=sys.stderr) + print(tMD, tXM, tNM, file=sys.stderr) + assert False + + +""" +""" +def simulate_reads(genome_file, gtf_file, snp_file, base_fname, + rna, paired_end, read_len, frag_len, + num_frag, expr_profile_type, repeat_fname, + error_rate, max_mismatch, + random_seed, snp_prob, sanity_check, verbose): + random.seed(random_seed, version=1) + err_rand_src = ErrRandomSource(error_rate / 100.0) + + if read_len > frag_len: + frag_len = read_len + + genome_seq = read_genome(genome_file) + if rna: + genes, transcripts = read_transcript(genome_seq, gtf_file, frag_len) + else: + genes, transcripts = {}, {} + snps = read_snp(snp_file) + + if sanity_check: + sanity_check_input(genome_seq, genes, transcripts, snps, frag_len) + + if rna: + num_transcripts = min(len(transcripts), 10000) + expr_profile = generate_rna_expr_profile(expr_profile_type, num_transcripts) + else: + expr_profile = generate_dna_expr_profile(genome_seq) + + expr_profile = [int(expr_profile[i] * num_frag) for i in range(len(expr_profile))] + assert num_frag >= sum(expr_profile) + while sum(expr_profile) < num_frag: + for i in range(min(num_frag - sum(expr_profile), len(expr_profile))): + expr_profile[i] += 1 + assert num_frag == sum(expr_profile) + + repeat_loci = {} + if repeat_fname != "" and os.path.exists(repeat_fname): + for line in open(repeat_fname): + if line.startswith('>'): + continue + coords = line.strip().split() + for coord in coords: + chr, pos, strand = coord.split(':') + if chr not in repeat_loci: + repeat_loci[chr] = [] + repeat_loci[chr].append([int(pos), strand]) + + if rna: + transcript_ids = sorted(list(transcripts.keys())) + random.shuffle(transcript_ids, random=random.random) + assert len(transcript_ids) >= len(expr_profile) + else: + chr_ids = list(genome_seq.keys()) + + sam_file = open(base_fname + ".sam", "w") + + # Write SAM header + print("@HD\tVN:1.0\tSO:unsorted", file=sam_file) + for chr in genome_seq.keys(): + print("@SQ\tSN:%s\tLN:%d" % (chr, len(genome_seq[chr])), file=sam_file) + + read_file = open(base_fname + "_1.fa", "w") + if paired_end: + read2_file = open(base_fname + "_2.fa", "w") + + cur_read_id = 1 + for t in range(len(expr_profile)): + t_num_frags = expr_profile[t] + if rna: + transcript_id = transcript_ids[t] + chr, strand, transcript_len, exons = transcripts[transcript_id] + print(transcript_id, t_num_frags, file=sys.stderr) + else: + chr = chr_ids[t] + print(chr, t_num_frags, file=sys.stderr) + + assert chr in genome_seq + chr_seq = genome_seq[chr] + chr_len = len(chr_seq) + if chr in repeat_loci: + chr_repeat_loci = repeat_loci[chr] + else: + chr_repeat_loci = [] + + if rna: + t_seq = "" + for e in exons: + assert e[0] < e[1] + t_seq += chr_seq[e[0]:e[1]+1] + assert len(t_seq) == transcript_len + else: + t_seq = chr_seq + exons = [[0, chr_len - 1]] + + if chr in snps: + chr_snps = snps[chr] + else: + chr_snps = [] + + for f in range(t_num_frags): + if rna: + #frag_pos = random.randint(0, transcript_len - frag_len) + frag_pos = myrandint(0, transcript_len - frag_len) + else: + while True: + if len(chr_repeat_loci): + #locus_id = random.randint(0, len(chr_repeat_loci) - 1) + locus_id = myrandint(0, len(chr_repeat_loci) - 1) + frag_pos = chr_repeat_loci[locus_id][0] + else: + #frag_pos = random.randint(0, chr_len - frag_len) + frag_pos = myrandint(0, chr_len - frag_len) + if 'N' not in chr_seq[frag_pos:frag_pos + frag_len]: + break + + # SAM specification (v1.4) + # http://samtools.sourceforge.net/ + flag, flag2 = 99, 163 # 83, 147 + pos, cigars, cigar_descs, MD, XM, NM, Zs, read_seq = getSamAlignment(rna, exons, chr_seq, t_seq, frag_pos, read_len, chr_snps, snp_prob, err_rand_src, max_mismatch) + pos2, cigars2, cigar2_descs, MD2, XM2, NM2, Zs2, read2_seq = getSamAlignment(rna, exons, chr_seq, t_seq, frag_pos+frag_len-read_len, read_len, chr_snps, snp_prob, err_rand_src, max_mismatch) + swapped = False + if paired_end: + #if random.randint(0, 1) == 1: + if myrandint(0, 1) == 1: + swapped = True + if swapped: + flag, flag2 = flag - 16, flag2 - 16 + pos, pos2 = pos2, pos + cigars, cigars2 = cigars2, cigars + cigar_descs, cigar2_descs = cigar2_descs, cigar_descs + read_seq, read2_seq = read2_seq, read_seq + XM, XM2 = XM2, XM + NM, NM2 = NM2, NM + MD, MD2 = MD2, MD + Zs, Zs2 = Zs2, Zs + + cigar_str, cigar2_str = "".join(cigars), "".join(cigars2) + if sanity_check: + samRepOk(genome_seq, read_seq, chr, pos, cigar_str, XM, NM, MD, Zs, max_mismatch) + samRepOk(genome_seq, read2_seq, chr, pos2, cigar2_str, XM2, NM2, MD2, Zs2, max_mismatch) + + if Zs != "": + Zs = ("\tZs:Z:{}".format(Zs)) + if Zs2 != "": + Zs2 = ("\tZs:Z:{}".format(Zs2)) + + if rna: + XS = "\tXS:A:{}".format(strand) + TI = "\tTI:Z:{}".format(transcript_id) + else: + XS, TI = "", "" + + print(">{}".format(cur_read_id), file=read_file) + if swapped: + print(reverse_complement(read_seq), file=read_file) + else: + print(read_seq, file=read_file) + print("{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:{}\tNM:i:{}\tMD:Z:{}{}{}{}".format(cur_read_id, flag, chr, pos + 1, cigar_str, chr, pos2 + 1, read_seq, XM, NM, MD, Zs, XS, TI), file=sam_file) + if paired_end: + print(">{}".format(cur_read_id), file=read2_file) + if swapped: + print(read2_seq, file=read2_file) + else: + print(reverse_complement(read2_seq), file=read2_file) + print("{}\t{}\t{}\t{}\t255\t{}\t{}\t{}\t0\t{}\t*\tXM:i:{}\tNM:i:{}\tMD:Z:{}{}{}{}".format(cur_read_id, flag2, chr, pos2 + 1, cigar2_str, chr, pos + 1, read2_seq, XM2, NM2, MD2, Zs2, XS, TI), file=sam_file) + + cur_read_id += 1 + + sam_file.close() + read_file.close() + if paired_end: + read2_file.close() + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Simulate reads from GENOME (fasta) and GTF files') + parser.add_argument('genome_file', + nargs='?', + type=FileType('r'), + help='input GENOME file') + parser.add_argument('gtf_file', + nargs='?', + type=FileType('r'), + help='input GTF file') + parser.add_argument('snp_file', + nargs='?', + type=FileType('r'), + help='input SNP file') + parser.add_argument('base_fname', + nargs='?', + type=str, + help='output base filename') + parser.add_argument('-d', '--dna', + dest='rna', + action='store_false', + default=True, + help='DNA-seq reads (default: RNA-seq reads)') + parser.add_argument('--single-end', + dest='paired_end', + action='store_false', + default=True, + help='single-end reads (default: paired-end reads)') + parser.add_argument('-r', '--read-length', + dest='read_len', + action='store', + type=int, + default=100, + help='read length (default: 100)') + parser.add_argument('-f', '--fragment-length', + dest='frag_len', + action='store', + type=int, + default=250, + help='fragment length (default: 250)') + parser.add_argument('-n', '--num-fragment', + dest='num_frag', + action='store', + type=int, + default=1000000, + help='number of fragments (default: 1000000)') + parser.add_argument('-e', '--expr-profile', + dest='expr_profile', + action='store', + type=str, + default='flux', + help='expression profile: flux or constant (default: flux)') + parser.add_argument('--repeat-info', + dest='repeat_fname', + action='store', + type=str, + default='', + help='repeat information filename') + parser.add_argument('--error-rate', + dest='error_rate', + action='store', + type=float, + default=0.0, + help='per-base sequencing error rate (%%) (default: 0.0)') + parser.add_argument('--max-mismatch', + dest='max_mismatch', + action='store', + type=int, + default=3, + help='max mismatches due to sequencing errors (default: 3)') + parser.add_argument('--random-seed', + dest='random_seed', + action='store', + type=int, + default=0, + help='random seeding value (default: 0)') + parser.add_argument('--snp-prob', + dest='snp_prob', + action='store', + type=float, + default=1.0, + help='probability of a read including a snp when the read spans the snp ranging from 0.0 to 1.0 (default: 1.0)') + parser.add_argument('--sanity-check', + dest='sanity_check', + action='store_true', + help='sanity check') + parser.add_argument('-v', '--verbose', + dest='verbose', + action='store_true', + help='also print some statistics to stderr') + parser.add_argument('--version', + action='version', + version='%(prog)s 2.0.0-alpha') + args = parser.parse_args() + if not args.genome_file or not args.gtf_file or not args.snp_file: + parser.print_help() + exit(1) + if not args.rna: + args.expr_profile = "constant" + simulate_reads(args.genome_file, args.gtf_file, args.snp_file, args.base_fname, + args.rna, args.paired_end, args.read_len, args.frag_len, + args.num_frag, args.expr_profile, args.repeat_fname, + args.error_rate, args.max_mismatch, + args.random_seed, args.snp_prob, args.sanity_check, args.verbose) diff --git a/hisat2lib/ht2.h b/hisat2lib/ht2.h new file mode 100644 index 0000000..aee5f53 --- /dev/null +++ b/hisat2lib/ht2.h @@ -0,0 +1,162 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef __HT2_H__ +#define __HT2_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include + +typedef int ht2_error_t; + +enum { + HT2_OK = 0, + + HT2_ERR = -1, + HT2_ERR_NOT_REPEAT = -2, +}; +#define HT2_RET_OK(x) ((x) == HT2_OK) + +typedef void* ht2_handle_t; + +struct ht2_options { + int offRate; + + int useMm; + int useShmem; + int mmSweep; + int noRefNames; + int noSplicedAlignment; + int gVerbose; + int startVerbose; + int sanityCheck; + + int useHaplotype; + + void *altdb; + void *raltdb; + void *repeatdb; + + void *gfm; + void *rgfm; +}; + +typedef struct ht2_options ht2_option_t; + + + +/************************************************************************** + * + * Initialize APIs + * + **************************************************************************/ + +ht2_handle_t ht2_init(const char *name, ht2_option_t *options); +void ht2_close(ht2_handle_t); + +ht2_error_t ht2_init_options(ht2_option_t *options); + + +/************************************************************************** + * + * Index APIs + * + **************************************************************************/ + +const char* ht2_index_getrefnamebyid(ht2_handle_t handle, uint32_t chr_id); + +struct ht2_index_getrefnames_result { + int count; + char* names[0]; +}; + +/** + * @brief + * + * @param handle + * @param result_ptr pointer to result. Caller must relese memory by free(). + * + * @return + */ +ht2_error_t ht2_index_getrefnames(ht2_handle_t handle, struct ht2_index_getrefnames_result **result_ptr); + + +/************************************************************************** + * + * Repeat APIs + * + **************************************************************************/ + +struct ht2_position { + uint32_t chr_id; + int direction; /* 0 - forward, 1 - reverse */ + uint64_t pos; /* 0-based */ +}; + +struct ht2_repeat_expand_result { + int count; + struct ht2_position positions[0]; +}; + + +/** + * @brief + * + * @param handle + * @param repeat_name + * @param repeat_pos repeat position on repeat sequence(0-based) + * @param repeat_len + * @param result_ptr pointer to result. caller must release memory by free(). + * ex) free(result_ptr); + * + * @return + */ +ht2_error_t ht2_repeat_expand(ht2_handle_t handle, + const char *repeat_name, + uint64_t repeat_pos, + uint64_t repeat_len, + struct ht2_repeat_expand_result **result_ptr); + +/************************************************************************** + * + * Alignment APIs + * + **************************************************************************/ +/* TODO */ + + +/************************************************************************** + * + * ETC APIs + * + **************************************************************************/ +/* TODO */ +void ht2_test_1(ht2_handle_t); +void ht2_repeat_dump_repeatmap(ht2_handle_t handle); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __HT2_H__ */ diff --git a/hisat2lib/ht2_alignment.cpp b/hisat2lib/ht2_alignment.cpp new file mode 100644 index 0000000..6cb1e2d --- /dev/null +++ b/hisat2lib/ht2_alignment.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + + diff --git a/hisat2lib/ht2_handle.h b/hisat2lib/ht2_handle.h new file mode 100644 index 0000000..5ffc104 --- /dev/null +++ b/hisat2lib/ht2_handle.h @@ -0,0 +1,47 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef __HT2_HANDLE_H__ +#define __HT2_HANDLE_H__ + +#if 1 +#define EXPORT __attribute__((visibility("default"))) +#else +#define EXPORT +#endif + +typedef TIndexOffU index_t; +typedef uint16_t local_index_t; + +struct ht2_handle { + ALTDB* altdb; + ALTDB* raltdb; + RepeatDB* repeatdb; + + HGFM* gfm; + RFM *rgfm; + + string tmp_str; + + string ht2_idx_name; + + struct ht2_options options; +}; + +#endif /* __HT2_HANDLE_H__ */ diff --git a/hisat2lib/ht2_index.cpp b/hisat2lib/ht2_index.cpp new file mode 100644 index 0000000..35d5a8b --- /dev/null +++ b/hisat2lib/ht2_index.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include + +#include "ds.h" +#include "repeat.h" +#include "rfm.h" + +#include "ht2.h" +#include "ht2_handle.h" + + +EXPORT +const char* ht2_index_getrefnamebyid(ht2_handle_t handle, uint32_t chr_id) +{ + struct ht2_handle *hp = (struct ht2_handle *)handle; + + size_t refname_size = hp->gfm->_refnames.size(); + + if(chr_id < (refname_size - 1)) { + return hp->gfm->_refnames[chr_id].c_str(); + } + + return NULL; +} + + + +EXPORT +ht2_error_t ht2_index_getrefnames(ht2_handle_t handle, struct ht2_index_getrefnames_result **result_ptr) +{ + struct ht2_handle *hp = (struct ht2_handle *)handle; + + size_t refname_size = hp->gfm->_refnames.size(); + if(refname_size == 0) { + return HT2_ERR; + } + + size_t result_hdr_size = sizeof(struct ht2_index_getrefnames_result) + sizeof(char *) * refname_size; + size_t result_buf_size = 0; + + for(size_t i = 0; i < refname_size - 1; i++) { + result_buf_size += strlen(hp->gfm->_refnames[i].c_str()) + 1; + } + + void* ptr = malloc(result_hdr_size + result_buf_size); + char* buf_ptr = (char *)ptr + result_hdr_size; + + memset(ptr, 0, result_hdr_size + result_buf_size); + struct ht2_index_getrefnames_result* result = (struct ht2_index_getrefnames_result *)ptr; + + result->count = refname_size - 1; + result->names[0] = buf_ptr; + for(size_t i = 0; i < refname_size - 1; i++) { + size_t rlen = strlen(hp->gfm->_refnames[i].c_str()); + strcpy(result->names[i], hp->gfm->_refnames[i].c_str()); + result->names[i + 1] = result->names[i] + rlen + 1; + } + + (*result_ptr) = result; + + return HT2_OK; +} diff --git a/hisat2lib/ht2_init.cpp b/hisat2lib/ht2_init.cpp new file mode 100644 index 0000000..1056486 --- /dev/null +++ b/hisat2lib/ht2_init.cpp @@ -0,0 +1,248 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include + +#include "ds.h" +#include "repeat.h" +#include "rfm.h" + +#include "ht2.h" +#include "ht2_handle.h" + +using namespace std; + +#ifdef HISAT2_BUILD_LIB +MemoryTally gMemTally; +#endif + +static const struct ht2_options ht2_default_options = { + .offRate = -1, + + .useMm = false, + .useShmem = false, + .mmSweep = false, + .noRefNames = false, + .noSplicedAlignment = false, + .gVerbose = false, + .startVerbose = false, + .sanityCheck = 0, + + .useHaplotype = false, + + .altdb = NULL, + .raltdb = NULL, + .repeatdb = NULL, + .gfm = NULL, + .rgfm = NULL, +}; + +static int is_external_index(struct ht2_options *opt) +{ + if (opt->altdb != NULL || + opt->raltdb != NULL || + opt->repeatdb != NULL || + opt->gfm != NULL || + opt->rgfm != NULL) { + return 1; + } + + return 0; +} + +static void free_handle(struct ht2_handle *hp) +{ + if (!is_external_index(&hp->options)) { + if(hp->altdb) { + delete hp->altdb; + } + + if(hp->raltdb) { + delete hp->raltdb; + } + + if(hp->repeatdb) { + delete hp->repeatdb; + } + + if(hp->gfm) { + if(hp->gfm->isInMemory()) { + hp->gfm->evictFromMemory(); + } + delete hp->gfm; + } + + if(hp->rgfm) { + if(hp->rgfm->isInMemory()) { + hp->rgfm->evictFromMemory(); + } + delete hp->rgfm; + } + } + + delete hp; +} + +static void init_handle(struct ht2_handle *hp) +{ + + struct ht2_options *opt = &hp->options; + + if (is_external_index(opt)) { + + hp->altdb = (ALTDB *)opt->altdb; + hp->repeatdb = (RepeatDB *)opt->repeatdb; + hp->raltdb = (ALTDB *)opt->raltdb; + + hp->gfm = (HGFM* )opt->gfm; + hp->rgfm = (RFM *)opt->rgfm; + + } else { + + hp->altdb = new ALTDB(); + hp->repeatdb = new RepeatDB(); + hp->raltdb = new ALTDB(); + + hp->gfm = new HGFM( + hp->ht2_idx_name, + hp->altdb, + NULL, + NULL, + -1, + true, + opt->offRate, + 0, + opt->useMm, + opt->useShmem, + opt->mmSweep, + !opt->noRefNames, + true, + true, + true, + !opt->noSplicedAlignment, + opt->gVerbose, + opt->startVerbose, + false, + opt->sanityCheck, + opt->useHaplotype); + + + // Load the other half of the index into memory + assert(!hp->gfm->isInMemory()); + + hp->gfm->loadIntoMemory( + -1, + true, + true, + true, + !opt->noRefNames, + opt->startVerbose); + + hp->rgfm = new RFM( + hp->ht2_idx_name + ".rep", + hp->raltdb, + hp->repeatdb, + NULL, + -1, + true, + opt->offRate, + 0, + opt->useMm, + opt->useShmem, + opt->mmSweep, + !opt->noRefNames, + true, + true, + true, + !opt->noSplicedAlignment, + opt->gVerbose, + opt->startVerbose, + false, + opt->sanityCheck, + false); + + + assert(!hp->rgfm->isInMemory()); + hp->rgfm->loadIntoMemory( + -1, + true, + true, + true, + !opt->noRefNames, + opt->startVerbose); + + hp->repeatdb->construct(hp->gfm->rstarts(), hp->gfm->nFrag()); + } +} + +EXPORT +ht2_handle_t ht2_init(const char *name, ht2_option_t *options) +{ + struct ht2_handle *handle = new ht2_handle; + + handle->ht2_idx_name = name; + if(options) { + memcpy(&handle->options, options, sizeof(struct ht2_options)); + } else { + memcpy(&handle->options, &ht2_default_options, sizeof(struct ht2_options)); + } + + // Init + init_handle(handle); + + handle->tmp_str = name; + + return (ht2_handle_t)handle; +} + +EXPORT +void ht2_close(ht2_handle_t handle) +{ + struct ht2_handle *hp = (struct ht2_handle *)handle; + if(hp == NULL) { + return; + } + + free_handle(hp); +} + + +EXPORT +ht2_error_t ht2_init_options(ht2_option_t *options) +{ + if(options == NULL) { + return HT2_ERR; + } + + memcpy(options, &ht2_default_options, sizeof(ht2_default_options)); + + return HT2_OK; +} + +EXPORT +void ht2_test_1(ht2_handle_t handle) +{ + struct ht2_handle *hp = (struct ht2_handle *)handle; + + size_t refname_size = hp->gfm->_refnames.size(); + cerr << "ht2lib: " << "gfm refnames: " << refname_size << endl; + for(size_t i = 0; i < refname_size; i++) { + cerr << "ht2lib: " << " " << i << " -> " << hp->gfm->_refnames[i] << endl; + } +} diff --git a/hisat2lib/ht2_repeat.cpp b/hisat2lib/ht2_repeat.cpp new file mode 100644 index 0000000..7f40256 --- /dev/null +++ b/hisat2lib/ht2_repeat.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include + +#include "ds.h" +#include "repeat.h" +#include "rfm.h" + +#include "ht2.h" +#include "ht2_handle.h" + +EXPORT +void ht2_repeat_dump_repeatmap(ht2_handle_t handle) +{ + struct ht2_handle *hp = (struct ht2_handle *)handle; + + size_t localRFMSize = hp->rgfm->_localRFMs.size(); + + cerr << "ht2lib: " << "LocalRFM size: " << localRFMSize << endl; + cerr << "ht2lib: " << "Dump repeatMap" << endl; + + // repID -> 0 + const EList >& repeatMap = hp->repeatdb->repeatMap()[0]; + + cerr << repeatMap.size() << endl; + + for(size_t i = 0; i < repeatMap.size(); i++) { + cerr << repeatMap[i].first << ", " << repeatMap[i].second << endl; + } + +} + + +EXPORT +ht2_error_t ht2_repeat_expand(ht2_handle_t handle, + const char *repeat_name, + uint64_t repeat_pos, + uint64_t repeat_len, + struct ht2_repeat_expand_result **result_ptr) +{ + struct ht2_handle *hp = (struct ht2_handle *)handle; + + index_t rep_id = hp->rgfm->getLocalRFM_idx(repeat_name); + + TIndexOffU left = repeat_pos; + TIndexOffU right = left + repeat_len; + + bool ret = hp->repeatdb->repeatExist(rep_id, left, right); + if(!ret) { + return HT2_ERR_NOT_REPEAT; + } + + + /* get coord */ + EList, RepeatCoord > > positions; + + EList snp_id_list; + snp_id_list.clear(); + + hp->repeatdb->getCoords( + rep_id, + left, right, + snp_id_list, + *(hp->raltdb), + positions + ); + + /* build result */ + size_t result_size = sizeof(struct ht2_repeat_expand_result) + positions.size() * sizeof(struct ht2_position); + + struct ht2_repeat_expand_result *result = (struct ht2_repeat_expand_result *)malloc(result_size); + + result->count = positions.size(); + + for(size_t i = 0; i < positions.size(); i++) { + const RepeatCoord& coord = positions[i].first; + + result->positions[i].chr_id = coord.tid; + result->positions[i].pos = coord.toff; + result->positions[i].direction = coord.fw ? 0 : 1; + } + + *(result_ptr) = result; + return HT2_OK; +} + diff --git a/hisat2lib/java_jni/HT2Module.java b/hisat2lib/java_jni/HT2Module.java new file mode 100644 index 0000000..26fbd53 --- /dev/null +++ b/hisat2lib/java_jni/HT2Module.java @@ -0,0 +1,122 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; + +public class HT2Module { + static { + System.loadLibrary("ht2jni"); + } + + public static class HT2Position { + int chr_id; + int direction; + long position; + + HT2Position(int id, int dir, int pos) { + this.chr_id = id; + this.direction = dir; + this.position = pos; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + + "[chr_id=" + chr_id + + ", direction=" + direction + + ", position=" + position + "]"; + } + } + + private native long init(String indexName, Map options); + private native void close(long handle); + private native Map get_options(); + + private native String index_getrefnamebyid(long handle, int id); + private native List index_getrefnames(long handle); + private native List repeat_expand(long handle, String name, long rpos, long rlen); + + private long handle; + + HT2Module() { + handle = 0; + } + + public void initLibrary(String indexName) { + initLibrary(indexName, null); + } + + public void initLibrary(String indexName, Map options) + { + if(handle == 0) { + handle = init(indexName, options); + } + } + + public Map initOption() + { + return get_options(); + } + + public String getRefNameById(int chr_id) + { + if(handle == 0) { + // TODO: Exception + return ""; + } + + // TODO: Exception(OutOfIndex) + return index_getrefnamebyid(handle, chr_id); + } + + public List getRefNames() + { + if(handle == 0) { + // TODO: Exception + return new ArrayList<>(); + } + return index_getrefnames(handle); + } + + public List repeatExpand(String name, long position, long length) + { + if(handle == 0) { + // TODO: Exception + return new ArrayList<>(); + } + return repeat_expand(handle, name, position, length); + } + + public void cleanup() + { + if(handle != 0) { + close(handle); + handle = 0; + } + } + + public void finalize() { + cleanup(); + } + +} diff --git a/hisat2lib/java_jni/HT2ModuleExample.java b/hisat2lib/java_jni/HT2ModuleExample.java new file mode 100644 index 0000000..6bee9a7 --- /dev/null +++ b/hisat2lib/java_jni/HT2ModuleExample.java @@ -0,0 +1,82 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; + +public class HT2ModuleExample { + + public static void main(String[] args) { + HT2Module module = null; + Map ht2Options = null; + String indexPath = "../../evaluation/indexes/HISAT2_22/22_rep"; + //String indexPath = "../../evaluation/indexes/HISAT2/genome_rep"; + + try { + module = new HT2Module(); + + // Get Default Options + //ht2Options = module.InitOption(); + // or + ht2Options = new HashMap<>(); + + //ht2Options.put("gVerbose", 1); + //ht2Options.put("startVerbose", 1); + //ht2Options.put("sanityCheck", 1); + + System.out.println(ht2Options); + + module.initLibrary(indexPath, ht2Options); + //module.initLibrary(indexPath); + + System.out.println("CHR_ID 0: " + module.getRefNameById(0)); + + // in 22_rep, OutOfIndex + System.out.println("CHR_ID 1: " + module.getRefNameById(1)); + + List refnames = module.getRefNames(); + + System.out.println("Refnames size:" + refnames.size()); + for(String name: refnames) { + System.out.println(name); + } + + // repeat for 22_rep + List positions = module.repeatExpand("rep100-300", 8308, 100); + + // repeat for genome_rep + //List positions = module.repeatExpand("rep100-300", 2446692, 100); + + System.out.println("Repeat expand size: " + positions.size()); + for(HT2Module.HT2Position pos: positions) { + String chrName = refnames.get(pos.chr_id).split(" ")[0]; + String direction = pos.direction == 0 ? "+":"-"; + + System.out.println(chrName + ":" + pos.position + ":" + direction); + } + + } finally { + if(module != null) { + module.cleanup(); + } + } + } +} diff --git a/hisat2lib/java_jni/Makefile b/hisat2lib/java_jni/Makefile new file mode 100644 index 0000000..1153d18 --- /dev/null +++ b/hisat2lib/java_jni/Makefile @@ -0,0 +1,72 @@ +# +# Copyright 2018, Chanhee Park and Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +JAVA_HOME := $(JAVA_HOME) + +HISAT2_DIR = ../.. + +CC = gcc + + +MACOS = 0 +ifneq (,$(findstring Darwin,$(shell uname))) +MACOS = 1 +endif + +INCLUDES = -I $(JAVA_HOME)/include +INCLUDES += -I $(JAVA_HOME)/include/linux + +TARGET_LIB = libht2jni.so +SHARED_FLAG = -shared + +ifeq (1,$(MACOS)) +INCLUDES += -I $(JAVA_HOME)/include/darwin +TARGET_LIB = libht2jni.jnilib +SHARED_FLAG = -dynamiclib +endif + +INCLUDES += -I $(HISAT2_DIR)/hisat2lib + +CFLAGS = -fPIC $(INCLUDES) +#CFLAGS += -DDEBUG + +SRCS = ht2module.c + +OBJS = $(SRCS:.c=.o) + +all: lib + +lib: $(TARGET_LIB) + +$(TARGET_LIB): HT2Module.h $(OBJS) + $(CC) $(SHARED_FLAG) -o $@ $(OBJS) $(HISAT2_DIR)/libhisat2lib.a -lstdc++ + +HT2Module.h HT2Module.class: HT2Module.java + javac -h . HT2Module.java + +example: HT2ModuleExample.class + +HT2ModuleExample.class: HT2ModuleExample.java + javac HT2ModuleExample.java + +clean: + rm -f *.class HT2Module.h HT2Module_HT2Position.h *.so *.o $(TARGET_LIB) + +test: all example + java -Djava.library.path=. HT2ModuleExample diff --git a/hisat2lib/java_jni/ht2module.c b/hisat2lib/java_jni/ht2module.c new file mode 100644 index 0000000..692d909 --- /dev/null +++ b/hisat2lib/java_jni/ht2module.c @@ -0,0 +1,432 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include +#include +#include "ht2.h" + +#include "HT2Module.h" + +#define CLASSPATH_INTEGER "java/lang/Integer" +#define CLASSPATH_HASHMAP "java/util/HashMap" +#define CLASSPATH_ARRAYLIST "java/util/ArrayList" +#define CLASSPATH_HT2POSITION "HT2Module$HT2Position" + +#ifdef DEBUG +#define DEBUGLOG(fmt, ...) do { fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); } while(0) +#else +#define DEBUGLOG(fmt, ...) +#endif + +static jint JNI_VERSION = JNI_VERSION_1_2; + +static jclass classInteger; +static jclass classHashMap; +static jclass classArrayList; +static jclass classHT2Position; + +static jmethodID mthIntegerInit; +static jmethodID mthIntegerIntValue; + +static jmethodID mthHashMapInit; +static jmethodID mthHashMapPut; +static jmethodID mthHashMapGet; + +static jmethodID mthArrayListInit; +static jmethodID mthArrayListEnsureCapacity; +static jmethodID mthArrayListAdd; + +static jmethodID mthHT2PositionInit; + +static jobject NewHashMap(JNIEnv *env) +{ + jobject obj = (*env)->NewObject(env, classHashMap, mthHashMapInit); + return obj; +} + +static jobject NewInteger(JNIEnv *env, int value) +{ + jobject obj = (*env)->NewObject(env, classInteger, mthIntegerInit, value); + return obj; +} + +static jobject NewArrayList(JNIEnv *env) +{ + jobject obj = (*env)->NewObject(env, classArrayList, mthArrayListInit); + return obj; +} + +static jobject NewHT2Position(JNIEnv *env, struct ht2_position *htpos) +{ + jobject obj = (*env)->NewObject(env, classHT2Position, mthHT2PositionInit, + htpos->chr_id, htpos->direction, htpos->pos); + return obj; +} + +static int GetInteger(JNIEnv *env, jobject jobjInt, int *val) +{ + int value = (*env)->CallIntMethod(env, jobjInt, mthIntegerIntValue); + *val = value; + return 0; +} + +static void hashmap_put(JNIEnv *env, jobject jobjMap, + const char *key_str, const int val) +{ + jstring keyObj; + jobject valueObj; + + keyObj = (*env)->NewStringUTF(env, key_str); + valueObj = NewInteger(env, val); + + (*env)->CallObjectMethod(env, jobjMap, mthHashMapPut, keyObj, valueObj); + + (*env)->DeleteLocalRef(env, keyObj); + (*env)->DeleteLocalRef(env, valueObj); +} + +static int hashmap_get(JNIEnv *env, jobject jobjMap, + const char *key_str, int *val) +{ + jstring keyObj; + jobject valueObj; + + keyObj = (*env)->NewStringUTF(env, key_str); + valueObj = (*env)->CallObjectMethod(env, jobjMap, mthHashMapGet, keyObj); + + if(valueObj == NULL) { + DEBUGLOG("Can't find key: %s\n", key_str); + (*env)->DeleteLocalRef(env, keyObj); + return -1; + } + + // Integer -> int + int value = 0; + if(GetInteger(env, valueObj, &value) < 0) { + DEBUGLOG("Can't get Integer\n"); + (*env)->DeleteLocalRef(env, keyObj); + (*env)->DeleteLocalRef(env, valueObj); + return -1; + } + + (*env)->DeleteLocalRef(env, keyObj); + (*env)->DeleteLocalRef(env, valueObj); + + *val = value; + + return 0; +} + +static jobject conv_ht2option(JNIEnv *env, ht2_option_t *opts) +{ + jobject hashMap = NewHashMap(env); + +#define HT2_OPT_BUILD(_name) \ + hashmap_put(env, hashMap, #_name , opts->_name) + + HT2_OPT_BUILD(offRate); + HT2_OPT_BUILD(useMm); + HT2_OPT_BUILD(useShmem); + HT2_OPT_BUILD(mmSweep); + HT2_OPT_BUILD(noRefNames); + HT2_OPT_BUILD(noSplicedAlignment); + HT2_OPT_BUILD(gVerbose); + HT2_OPT_BUILD(startVerbose); + HT2_OPT_BUILD(sanityCheck); + HT2_OPT_BUILD(useHaplotype); + + return hashMap; +} + +static void update_ht2option(JNIEnv *env, ht2_option_t *opts, jobject jmapObject) +{ +#define HT2_OPT_UPDATE(_name) \ + do { \ + int value = 0; \ + if(hashmap_get(env, jmapObject, #_name, &value) == 0) { \ + DEBUGLOG("Using %s, %d\n", #_name, value); \ + opts->_name = value; \ + } else { \ + DEBUGLOG("Using default %s, %d\n", #_name, opts->_name); \ + }\ + } while(0) + + HT2_OPT_UPDATE(offRate); + HT2_OPT_UPDATE(useMm); + HT2_OPT_UPDATE(useShmem); + HT2_OPT_UPDATE(mmSweep); + HT2_OPT_UPDATE(noRefNames); + HT2_OPT_UPDATE(noSplicedAlignment); + HT2_OPT_UPDATE(gVerbose); + HT2_OPT_UPDATE(startVerbose); + HT2_OPT_UPDATE(sanityCheck); + HT2_OPT_UPDATE(useHaplotype); +} + + +static void conv_refnames_result(JNIEnv *env, + struct ht2_index_getrefnames_result *result, jobject jobjList) +{ + size_t i; + + // Resize + DEBUGLOG("count: %d\n", result->count); + (*env)->CallVoidMethod(env, jobjList, mthArrayListEnsureCapacity, result->count); + + for(i = 0; i < result->count; i++) { + DEBUGLOG("names[%d] %s\n", i, result->names[i]); + + jobject elem = (*env)->NewStringUTF(env, result->names[i]); + (*env)->CallObjectMethod(env, jobjList, mthArrayListAdd, elem); + (*env)->DeleteLocalRef(env, elem); + } +} + +static void conv_repeat_expand_result(JNIEnv *env, + struct ht2_repeat_expand_result *result, + jobject jobjList) +{ + size_t i; + + // Resize + DEBUGLOG("count: %d\n", result->count); + (*env)->CallVoidMethod(env, jobjList, mthArrayListEnsureCapacity, result->count); + + // Add Items + for(i = 0; i < result->count; i++) { + struct ht2_position *htpos = &result->positions[i]; + + DEBUGLOG("position[%d]: %u, %d, %lu\n", i, htpos->chr_id, htpos->direction, htpos->pos); + + jobject elem = NewHT2Position(env, htpos); + (*env)->CallObjectMethod(env, jobjList, mthArrayListAdd, elem); + (*env)->DeleteLocalRef(env, elem); + } +} + +JNIEXPORT jlong JNICALL Java_HT2Module_init(JNIEnv *env, + jobject thisObj, jstring indexNameObj, jobject optionMap) +{ + DEBUGLOG("Init\n"); + + const char *index_path = (*env)->GetStringUTFChars(env, indexNameObj, NULL); + if(index_path == NULL) { + DEBUGLOG("Can't get string\n"); + return 0; + } + + DEBUGLOG("Index Path: %s\n", index_path); + + ht2_option_t ht2opt; + ht2_init_options(&ht2opt); + if(optionMap != NULL) { + // update options + update_ht2option(env, &ht2opt, optionMap); + } + + ht2_handle_t handle = ht2_init(index_path, &ht2opt); + + DEBUGLOG("Initailzed %p\n", handle); + + (*env)->ReleaseStringUTFChars(env, indexNameObj, index_path); + + return (jlong)handle; +} + + +JNIEXPORT void JNICALL Java_HT2Module_close(JNIEnv *env, + jobject thisObj, jlong handlePtr) +{ + DEBUGLOG("Closing\n"); + + ht2_handle_t handle = (ht2_handle_t)handlePtr; + + DEBUGLOG("Received handle: %p\n", handle); + + ht2_close(handle); +} + +JNIEXPORT jobject JNICALL Java_HT2Module_get_1options(JNIEnv *env, + jobject thisObj) +{ + + DEBUGLOG("get_option\n"); + + // Get Default options + ht2_option_t ht2opt; + ht2_init_options(&ht2opt); + + // convert ht2opt to java hashmap + jobject hashobj = conv_ht2option(env, &ht2opt); + + return hashobj; +} + +JNIEXPORT jstring JNICALL Java_HT2Module_index_1getrefnamebyid(JNIEnv *env, + jobject thisObj, jlong handlePtr, jint chr_id) +{ + DEBUGLOG("index_getrefnamebyid\n"); + ht2_handle_t handle = (ht2_handle_t)handlePtr; + if(handle == NULL) { + DEBUGLOG("Invalid handle\n"); + return NULL; + } + + const char *refname = ht2_index_getrefnamebyid(handle, chr_id); + if(refname == NULL) { + DEBUGLOG("Can't get refname(%d)\n", chr_id); + return NULL; + } + + return (*env)->NewStringUTF(env, refname); +} + +JNIEXPORT jobject JNICALL Java_HT2Module_index_1getrefnames(JNIEnv *env, + jobject thisObj, jlong handlePtr) +{ + DEBUGLOG("index_getrefnames\n"); + + ht2_handle_t handle = (ht2_handle_t)handlePtr; + if(handle == NULL) { + DEBUGLOG("Invalid handle\n"); + return NULL; + } + + struct ht2_index_getrefnames_result *result = NULL; + ht2_error_t ret = ht2_index_getrefnames(handle, &result); + + jobject refnames = NewArrayList(env); + + if(ret == HT2_OK) { + DEBUGLOG("refnames size: %d\n", result->count); + conv_refnames_result(env, result, refnames); + free(result); + } else { + DEBUGLOG("Can't get refnames\n"); + } + + return refnames; +} + +JNIEXPORT jobject JNICALL Java_HT2Module_repeat_1expand(JNIEnv *env, + jobject thisObj, jlong handlePtr, jstring nameObj, jlong rpos, jlong rlen) +{ + DEBUGLOG("repeat_expand\n"); + + ht2_handle_t handle = (ht2_handle_t)handlePtr; + if(handle == NULL) { + DEBUGLOG("Invalid handle\n"); + return NULL; + } + + const char *name = (*env)->GetStringUTFChars(env, nameObj, NULL); + if(name == NULL) { + DEBUGLOG("Can't get string\n"); + return NULL; + } + + DEBUGLOG("Repeat Expand: %s, %lu, %lu\n", name, rpos, rlen); + + + struct ht2_repeat_expand_result *result = NULL; + ht2_error_t ret = ht2_repeat_expand(handle, name, rpos, rlen, &result); + + jobject positions = NewArrayList(env); + + if(ret == HT2_OK) { + DEBUGLOG("expand position size: %d\n", result->count); + conv_repeat_expand_result(env, result, positions); + free(result); + } else { + DEBUGLOG("Can't expand repeat\n"); + } + + (*env)->ReleaseStringUTFChars(env, nameObj, name); + + return positions; +} + +jint JNI_OnLoad(JavaVM *vm, void *reserved) +{ + DEBUGLOG("JNI Loaded\n"); + + JNIEnv *env; + + if((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION) != JNI_OK) { + return JNI_ERR; + } + + // Load Class +#define LOAD_CLASS(_globalRef, _clazz) \ + do { \ + jclass tmpClassRef = (*env)->FindClass(env, _clazz); \ + if(tmpClassRef == NULL) { \ + DEBUGLOG("Can't find class %s\n", _clazz); \ + return JNI_ERR; \ + } \ + _globalRef = (jclass)(*env)->NewGlobalRef(env, tmpClassRef); \ + (*env)->DeleteLocalRef(env, tmpClassRef); \ + } while(0) + + LOAD_CLASS(classInteger, CLASSPATH_INTEGER); + LOAD_CLASS(classHashMap, CLASSPATH_HASHMAP); + LOAD_CLASS(classArrayList, CLASSPATH_ARRAYLIST); + LOAD_CLASS(classHT2Position, CLASSPATH_HT2POSITION); + + + // Load Method + + // Integer + mthIntegerInit = (*env)->GetMethodID(env, classInteger, "", "(I)V"); + mthIntegerIntValue = (*env)->GetMethodID(env, classInteger, "intValue", "()I"); + + // HashMap + mthHashMapInit = (*env)->GetMethodID(env, classHashMap, "", "()V"); + mthHashMapPut = (*env)->GetMethodID(env, classHashMap, "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + mthHashMapGet = (*env)->GetMethodID(env, classHashMap, "get", + "(Ljava/lang/Object;)Ljava/lang/Object;"); + + // ArrayList + mthArrayListInit = (*env)->GetMethodID(env, classArrayList, "", "()V"); + mthArrayListEnsureCapacity = (*env)->GetMethodID(env, classArrayList, "ensureCapacity", "(I)V"); + mthArrayListAdd = (*env)->GetMethodID(env, classArrayList, "add", + "(Ljava/lang/Object;)Z"); + + // HT2Position + mthHT2PositionInit = (*env)->GetMethodID(env, classHT2Position, "", "(III)V"); + + return JNI_VERSION; +} + + +void JNI_OnUnload(JavaVM *vm, void *reserved) +{ + DEBUGLOG("JNI Unload\n"); + JNIEnv *env; + + (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION); + + (*env)->DeleteGlobalRef(env, classInteger); + (*env)->DeleteGlobalRef(env, classHashMap); + (*env)->DeleteGlobalRef(env, classArrayList); + (*env)->DeleteGlobalRef(env, classHT2Position); + +} + diff --git a/hisat2lib/pymodule/Makefile b/hisat2lib/pymodule/Makefile new file mode 100644 index 0000000..63644d4 --- /dev/null +++ b/hisat2lib/pymodule/Makefile @@ -0,0 +1,33 @@ +# +# Copyright 2018, Chanhee Park and Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . +# + +all: lib + +lib: + ARCHFLAGS="-arch x86_64" python ./setup.py build + +install: + python ./setup.py install + +clean: + python ./setup.py clean + rm -rf build test + +test: lib + python ./ht2example.py diff --git a/hisat2lib/pymodule/ht2example.py b/hisat2lib/pymodule/ht2example.py new file mode 100644 index 0000000..632ba0e --- /dev/null +++ b/hisat2lib/pymodule/ht2example.py @@ -0,0 +1,68 @@ +#!/usr/bin/python + +# +# Copyright 2018, Chanhee Park and Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . + +# +# ./setup.py build +# ./setup.py install +# +import ht2py + +# Path to index +ht2_index = '../../evaluation/indexes/HISAT2_22/22_rep' + +# Get default options +ht2_options = ht2py.get_options() + +print ht2_options +ht2_options['gVerbose'] = 1 +ht2_options['startVerbose'] = 1 +# or +ht2_options = {} + +handle = ht2py.init(ht2_index, ht2_options) + +print ht2py.index_getrefnamebyid(handle, 0) + +#print ht2py.index_getrefnamebyid(handle, 0, 1, 3, 5, 7, 9) +# outofindex +#print ht2py.index_getrefnamebyid(handle, 1) +#print ht2py.index_getrefnamebyid(handle, -1) + +refnames = ht2py.index_getrefnames(handle) + +#for name in refnames: +# print name + +# repeat expansion +positions = ht2py.repeat_expand(handle, 'rep100-300', 8308, 100) + +for pos in positions: + chr_id = pos[0] + direction = pos[1] + chr_pos = pos[2] + + chr_dir = '+' + if direction == 1: + chr_dir = '-' + + print refnames[chr_id].split()[0] + ":" + str(chr_pos) + ':' + chr_dir + +# close handle +ht2py.close(handle) diff --git a/hisat2lib/pymodule/ht2module.c b/hisat2lib/pymodule/ht2module.c new file mode 100644 index 0000000..2771e49 --- /dev/null +++ b/hisat2lib/pymodule/ht2module.c @@ -0,0 +1,333 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ +#include +#include + +#include "ht2.h" + +#define HT2_HANDLE_ID "handle" + +#ifdef DEBUG +#define DEBUGLOG(fmt, ...) do { fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); } while(0) +#else +#define DEBUGLOG(fmt, ...) +#endif + +static ht2_handle_t get_handle(PyObject *cap) +{ + return PyCapsule_GetPointer(cap, HT2_HANDLE_ID); +} + +static PyObject *conv_refnames_result(struct ht2_index_getrefnames_result *result) +{ + PyObject *refnames = NULL; + size_t i = 0; + + if(result == NULL) { + return NULL; + } + + refnames = PyList_New(result->count); + for(i = 0; i < result->count; i++) { + PyObject *str = PyString_FromString(result->names[i]); + PyList_SetItem(refnames, i, str); + } + + return refnames; +} + +static PyObject *conv_repeat_expand_result(struct ht2_repeat_expand_result *result) +{ + PyObject *positions = NULL; + size_t i = 0; + + if(result == NULL) { + return NULL; + } + + positions = PyList_New(result->count); + for(i = 0; i < result->count; i++) { + struct ht2_position *htpos = &result->positions[i]; + + PyList_SetItem(positions, i, + Py_BuildValue("(III)", htpos->chr_id, htpos->direction, htpos->pos) + ); + } + + return positions; +} + + +static PyObject *conv_ht2opt(ht2_option_t *opts) +{ + PyObject *py_opt = NULL; + + py_opt = PyDict_New(); + if(py_opt == NULL) { + return NULL; + } +#define HT2_OPT_BUILD(_pobj, _popt, _name, _type) \ + do {\ + if(PyDict_SetItemString((_pobj), #_name, Py_BuildValue((_type), (_popt)->_name)) < 0) {\ + DEBUGLOG("Can't set item %s\n", #_name);\ + } \ + } while(0) + + + HT2_OPT_BUILD(py_opt, opts, offRate, "i"); + HT2_OPT_BUILD(py_opt, opts, useMm, "i"); + HT2_OPT_BUILD(py_opt, opts, useShmem, "i"); + HT2_OPT_BUILD(py_opt, opts, mmSweep, "i"); + HT2_OPT_BUILD(py_opt, opts, noRefNames, "i"); + HT2_OPT_BUILD(py_opt, opts, noSplicedAlignment, "i"); + HT2_OPT_BUILD(py_opt, opts, gVerbose, "i"); + HT2_OPT_BUILD(py_opt, opts, startVerbose, "i"); + HT2_OPT_BUILD(py_opt, opts, sanityCheck, "i"); + HT2_OPT_BUILD(py_opt, opts, useHaplotype, "i"); + + return py_opt; +} + +static void update_ht2_options(ht2_option_t *ht2opt, PyObject *py_opt) +{ +#define HT2_OPT_UPDATE(_pobj, _ht2opt, _name) \ + do {\ + PyObject *p;\ + if((p = PyDict_GetItemString((_pobj), #_name)) != NULL) { \ + (_ht2opt)->_name = PyInt_AsLong(p); \ + DEBUGLOG(#_name " %d\n", (ht2opt)->_name); \ + if(PyErr_Occurred() != NULL) { \ + DEBUGLOG("Error Occurred"); \ + }\ + }\ + } while (0) + + HT2_OPT_UPDATE(py_opt, ht2opt, offRate); + HT2_OPT_UPDATE(py_opt, ht2opt, useMm); + HT2_OPT_UPDATE(py_opt, ht2opt, mmSweep); + HT2_OPT_UPDATE(py_opt, ht2opt, noRefNames); + HT2_OPT_UPDATE(py_opt, ht2opt, noSplicedAlignment); + HT2_OPT_UPDATE(py_opt, ht2opt, gVerbose); + HT2_OPT_UPDATE(py_opt, ht2opt, startVerbose); + HT2_OPT_UPDATE(py_opt, ht2opt, sanityCheck); + HT2_OPT_UPDATE(py_opt, ht2opt, useHaplotype); + +} + +static PyObject *ht2py_get_options(PyObject *self, PyObject *args) +{ + ht2_option_t ht2opt; + + ht2_init_options(&ht2opt); + + + /* convert ht2_option_t to PyObject(map) */ + + PyObject *pobj = conv_ht2opt(&ht2opt); + + return pobj; +} + +static PyObject *ht2py_init(PyObject *self, PyObject *args) +{ + ht2_handle_t handle; + PyObject *popt = NULL; + char *name = NULL; + + if(!PyArg_ParseTuple(args, "sO", &name, &popt)) { + return NULL; + } + + DEBUGLOG("name %s\n", name); + DEBUGLOG("popt %p\n", popt); + + if(!PyDict_CheckExact(popt)) { + // TODO + // exception + DEBUGLOG("Invalid data type\n"); + return NULL; + } + + ht2_option_t ht2opt; + ht2_init_options(&ht2opt); + update_ht2_options(&ht2opt, popt); + + handle = ht2_init(name, &ht2opt); + + DEBUGLOG("handle %p\n", handle); + + PyObject *cap = PyCapsule_New(handle, HT2_HANDLE_ID, NULL); + + return cap; +} + +static PyObject *ht2py_close(PyObject *self, PyObject *args) +{ + ht2_handle_t handle; + PyObject *cap; + + // Parse Args + // ht2py.close(handle) + // + if(!PyArg_ParseTuple(args, "O", &cap)) { + DEBUGLOG("Can't parse args\n"); + return NULL; + } + + handle = get_handle(cap); + if(handle == NULL) { + DEBUGLOG("Can't get handle\n"); + return NULL; + } + + DEBUGLOG("handle %p\n", handle); + + ht2_close(handle); + + Py_RETURN_NONE; +} + + +static PyObject *ht2py_index_getrefnamebyid(PyObject *self, PyObject *args) +{ + PyObject *cap; + uint32_t chr_id; + + // ht2py.index_getrefnamebyid(handle, chr_id) + + if(!PyArg_ParseTuple(args, "Oi", &cap, &chr_id)) { + DEBUGLOG("Can't parse args\n"); + return NULL; + } + + ht2_handle_t handle = get_handle(cap); + if(handle == NULL) { + DEBUGLOG("Can't get handle\n"); + return NULL; + } + + const char *refname = ht2_index_getrefnamebyid(handle, chr_id); + + if(refname == NULL) { + DEBUGLOG("Can't get refname(%u)\n", chr_id); + return Py_BuildValue("s", ""); + } + + return Py_BuildValue("s", refname); +} + +static PyObject *ht2py_index_getrefnames(PyObject *self, PyObject *args) +{ + ht2_handle_t handle; + PyObject *cap; + + // Parse Args + // ht2py.index_getrefnames(handle) + if(!PyArg_ParseTuple(args, "O", &cap)) { + DEBUGLOG("Can't parse args\n"); + return NULL; + } + + handle = get_handle(cap); + if(handle == NULL) { + DEBUGLOG("Can't get handle\n"); + return NULL; + } + + + struct ht2_index_getrefnames_result *result = NULL; + ht2_error_t ret = ht2_index_getrefnames(handle, &result); + + PyObject *refnames = NULL; + + if(ret == HT2_OK) { + /* Build List of names */ + refnames = conv_refnames_result(result); + free(result); + } else { + refnames = PyList_New(0); + } + + return refnames; +} + +static PyObject *ht2py_repeat_expand(PyObject *self, PyObject *args) +{ + PyObject *cap; + char *name = NULL; + uint64_t rpos = 0; + uint64_t rlen = 0; + + // Parse Args + // ht2py.repeat_expand(handle, 'repeat_name', repeat_pos, repeat_len) + if(!PyArg_ParseTuple(args, "OsLL", &cap, &name, &rpos, &rlen)) { + DEBUGLOG("Can't parse args\n"); + return NULL; + } + + //fprintf(stderr, "%s, %lu, %lu\n", name, rpos, rlen); + + ht2_handle_t handle = get_handle(cap); + if(handle == NULL) { + DEBUGLOG("Can't get handle\n"); + return NULL; + } + + + struct ht2_repeat_expand_result *result = NULL; + ht2_error_t ret = ht2_repeat_expand(handle, name, rpos, rlen, &result); + + PyObject *positions = NULL; + if(ret == HT2_OK) { + /* Build list of position */ + positions = conv_repeat_expand_result(result); + free(result); + } else { + DEBUGLOG("error %d, %s, %lu, %lu\n", ret, + name, rpos, rlen); + positions = PyList_New(0); + } + + return positions; +} + + +static PyMethodDef myMethods[] = { + /* Initialize APIs */ + {"get_options", ht2py_get_options, METH_NOARGS, "Get default options"}, + {"init", ht2py_init, METH_VARARGS, "Initialize HT2Lib handle"}, + {"close", ht2py_close, METH_VARARGS, "Release HT2Lib handle"}, + + /* Index APIs */ + {"index_getrefnamebyid", ht2py_index_getrefnamebyid, METH_VARARGS, "Get reference name"}, + {"index_getrefnames", ht2py_index_getrefnames, METH_VARARGS, "Get all reference names"}, + + /* Repeat APIs */ + {"repeat_expand", ht2py_repeat_expand, METH_VARARGS, "Find reference positions"}, + + /* */ + {NULL, NULL, 0, NULL} +}; + + +PyMODINIT_FUNC +initht2py(void) +{ + (void)Py_InitModule("ht2py", myMethods); +} diff --git a/hisat2lib/pymodule/setup.py b/hisat2lib/pymodule/setup.py new file mode 100644 index 0000000..5ce42d8 --- /dev/null +++ b/hisat2lib/pymodule/setup.py @@ -0,0 +1,33 @@ +#!/usr/bin/python + +# +# Copyright 2018, Chanhee Park and Daehwan Kim +# +# This file is part of HISAT 2. +# +# HISAT 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# HISAT 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with HISAT 2. If not, see . + + +from distutils.core import setup, Extension + +module1 = Extension('ht2py', +# define_macros = [('DEBUG', '1')], + include_dirs=['../'], + libraries=['stdc++'], + extra_objects = ['../../libhisat2lib.a'], + sources = ['ht2module.c']) + +setup(name = 'ht2py', + version = '1.0', + ext_modules = [module1]) diff --git a/hisat_3n_table.cpp b/hisat_3n_table.cpp new file mode 100644 index 0000000..0168af2 --- /dev/null +++ b/hisat_3n_table.cpp @@ -0,0 +1,382 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + + +#include +#include +#include "position_3n_table.h" + +using namespace std; + +string alignmentFileName; +bool standardInMode = false; +string refFileName; +string outputFileName; +bool uniqueOnly = false; +bool multipleOnly = false; +bool CG_only = false; +int nThreads = 1; +long long int loadingBlockSize = 1000000; +char convertFrom = '0'; +char convertTo = '0'; +char convertFromComplement; +char convertToComplement; +bool addedChrName = false; +bool removedChrName = false; + + +Positions* positions; + +bool fileExist (string& filename) { + ifstream file(filename); + return file.good(); +} + +enum { + ARG_ADDED_CHRNAME = 256, + ARG_REMOVED_CHRNAME +}; + +static const char *short_options = "s:r:t:b:umcp:h"; +static struct option long_options[] { + {"alignments", required_argument, 0, 'a'}, + {"ref", required_argument, 0, 'r'}, + {"output-name", required_argument, 0, 'o'}, + {"base-change", required_argument, 0, 'b'}, + {"unique-only", no_argument, 0, 'u'}, + {"multiple-only", no_argument, 0, 'm'}, + {"CG-only", no_argument, 0, 'c'}, + {"threads", required_argument, 0, 'p'}, + {"added-chrname", no_argument, 0, ARG_ADDED_CHRNAME }, + {"removed-chrname", no_argument, 0, ARG_REMOVED_CHRNAME }, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; + +static void printHelp(ostream& out) { + out << "hisat-3n-table developed by Yun (Leo) Zhang" << endl; + out << "Usage:" << endl + << "hisat-3n-table [options]* --alignments --ref --output-name --base-change " << endl + << " SORTED SAM filename. Please enter '-' for standard input." << endl + << " reference file (should be FASTA format)." << endl + << " file name to save the 3n table (tsv format). By default, alignments are written to the “standard out†or “stdout†filehandle (i.e. the console)." << endl + << " the char1 is the nucleotide converted from, the char2 is the nucleotide converted to." << endl; + out << "Options (defaults in parentheses):" << endl + << " Input:" << endl + << " -u/--unique-only only count the base which is in unique mapped reads." << endl + << " -m/--multiple-only only count the base which is in multiple mapped reads." << endl + << " -c/--CG-only only count CG and ignore CH in reference." << endl + << " --added-chrname please add this option if you use --add-chrname during HISAT-3N alignment." << endl + << " --removed-chrname please add this option if you use --remove-chrname during HISAT-3N alignment." << endl + << " -p/--threads number of threads to launch (1)." << endl + << " -h/--help print this usage message." << endl; +} + +static void parseOption(int next_option, const char *optarg) { + switch (next_option) { + case 'a': { + alignmentFileName = optarg; + if (alignmentFileName == "-") { + standardInMode = true; + break; + } + if (!fileExist(alignmentFileName)) { + cerr << "The alignment file is not exist." << endl; + throw (1); + } + break; + } + case 'r': { + refFileName = optarg; + if (!fileExist(refFileName)) { + cerr << "reference (FASTA) file is not exist." << endl; + throw (1); + } + break; + } + case 'o': + outputFileName = optarg; + break; + case 'b': { + string arg = optarg; + if (arg.size() != 3 || arg[1] != ',') { + cerr << "Error: expected 2 comma-separated " + << "arguments to --base-change option (e.g. C,T), got " << arg << endl; + throw 1; + } + convertFrom = toupper(arg.front()); + convertTo = toupper(arg.back()); + break; + } + case 'u':{ + uniqueOnly = true; + break; + } + case 'm': { + multipleOnly = true; + break; + } + case 'c': { + CG_only = true; + break; + } + case 'h': { + printHelp(cerr); + throw 0; + } + case 'p': { + nThreads = stoi(optarg); + if (nThreads < 1) { + nThreads = 1; + } + break; + } + case ARG_ADDED_CHRNAME: { + addedChrName = true; + break; + } + case ARG_REMOVED_CHRNAME: { + removedChrName = true; + break; + } + default: + printHelp(cerr); + throw 1; + } +} + +static void parseOptions(int argc, const char **argv) { + int option_index = 0; + int next_option; + while (true) { + next_option = getopt_long(argc, const_cast(argv), short_options, + long_options, &option_index); + if (next_option == -1) + break; + parseOption(next_option, optarg); + } + + // check filenames + if (refFileName.empty() || alignmentFileName.empty()) { + cerr << "No reference or SAM file specified!" << endl; + printHelp(cerr); + throw 1; + } + + // give a warning for CG-only + if (CG_only) { + if (convertFrom != 'C' || convertTo != 'T') { + cerr << "Warning! You are using CG-only mode. The the --base-change option is set to: C,T" << endl; + convertFrom = 'C'; + convertTo = 'T'; + } + } + + // check if --base-change is empty + if (convertFrom == '0' || convertTo == '0') { + cerr << "the --base-change argument is required." << endl; + throw 1; + } + + if(removedChrName && addedChrName) { + cerr << "Error: --removed-chrname and --added-chrname cannot be used at the same time" << endl; + throw 1; + } + + // set complements + convertFromComplement = asc2dnacomp[convertFrom]; + convertToComplement = asc2dnacomp[convertTo]; +} + +/** + * give a SAM line, extract the chromosome and position information. + * return true if the SAM line is mapped. return false if SAM line is not maped. + */ +bool getSAMChromosomePos(string* line, string& chr, long long int& pos) { + int startPosition = 0; + int endPosition = 0; + int count = 0; + + while ((endPosition = line->find("\t", startPosition)) != string::npos) { + if (count == 2) { + chr = line->substr(startPosition, endPosition - startPosition); + } else if (count == 3) { + pos = stoll(line->substr(startPosition, endPosition - startPosition)); + if (chr == "*") { + return false; + } else { + return true; + } + } + startPosition = endPosition + 1; + count++; + } + return false; +} + +/*void opeInFile(ifstream& f) { + if (alignmentFileName == "-") { + f = cin; + } else { + ifstream alignmentFile; + alignmentFile.open(alignmentFileName, ios_base::in); + return alignmentFile; + } +}*/ + + +int hisat_3n_table() +{ + positions = new Positions(refFileName, nThreads, addedChrName, removedChrName); + + // open #nThreads workers + vector workers; + for (int i = 0; i < nThreads; i++) { + workers.push_back(new thread(&Positions::append, positions, i)); + } + + // open a output thread + thread outputThread; + outputThread = thread(&Positions::outputFunction, positions, outputFileName); + + // main function, initially 2 load loadingBlockSize (2,000,000) bp of reference, set reloadPos to 1 loadingBlockSize, then load SAM data. + // when the samPos larger than the reloadPos load 1 loadingBlockSize bp of reference. + // when the samChromosome is different to current chromosome, finish all sam position and output all. + ifstream inputFile; + istream *alignmentFile = &cin; + if (!standardInMode) { + inputFile.open(alignmentFileName, ios_base::in); + alignmentFile = &inputFile; + } + + string* line; // temporary string to get SAM line. + string samChromosome; // the chromosome name of current SAM line. + long long int samPos; // the position of current SAM line. + long long int reloadPos; // the position in reference that we need to reload. + long long int lastPos = 0; // the position on last SAM line. compare lastPos with samPos to make sure the SAM is sorted. + + while (alignmentFile->good()) { + positions->getFreeStringPointer(line); + if (!getline(*alignmentFile, *line)) { + positions->returnLine(line); + break; + } + + if (line->empty() || line->front() == '@') { + positions->returnLine(line); + continue; + } + // limit the linePool size to save memory + while(positions->linePool.size() > 1000 * nThreads) { + this_thread::sleep_for (std::chrono::microseconds(1)); + } + // if the SAM line is empty or unmapped, get the next SAM line. + if (!getSAMChromosomePos(line, samChromosome, samPos)) { + positions->returnLine(line); + continue; + } + // if the samChromosome is different than current positions' chromosome, finish all SAM line. + // then load a new reference chromosome. + if (samChromosome != positions->chromosome) { + // wait all line is processed + while (!positions->linePool.empty() || positions->outputPositionPool.size() > 100000) { + this_thread::sleep_for (std::chrono::microseconds(1)); + } + positions->appendingFinished(); + positions->moveAllToOutput(); + positions->loadNewChromosome(samChromosome); + reloadPos = loadingBlockSize; + lastPos = 0; + } + // if the samPos is larger than reloadPos, load 1 loadingBlockSize bp in from reference. + while (samPos > reloadPos) { + while (!positions->linePool.empty() || positions->outputPositionPool.size() > 100000) { + this_thread::sleep_for (std::chrono::microseconds(1)); + } + positions->appendingFinished(); + positions->moveBlockToOutput(); + positions->loadMore(); + reloadPos += loadingBlockSize; + } + if (lastPos > samPos) { + cerr << "The input alignment file is not sorted. Please use sorted SAM file as alignment file." << endl; + throw 1; + } + positions->linePool.push(line); + lastPos = samPos; + } + //} + if (!standardInMode) { + inputFile.close(); + } + + + // prepare to close everything. + + // make sure linePool is empty + while (!positions->linePool.empty()) { + this_thread::sleep_for (std::chrono::microseconds(100)); + } + // make sure all workers finished their appending work. + positions->appendingFinished(); + // move all position to outputPool + positions->moveAllToOutput(); + // wait until outputPool is empty + while (!positions->outputPositionPool.empty()) { + this_thread::sleep_for (std::chrono::microseconds(100)); + } + // stop all thread and clean + while(positions->freeLinePool.popFront(line)) { + delete line; + } + positions->working = false; + for (int i = 0; i < nThreads; i++){ + workers[i]->join(); + delete workers[i]; + } + outputThread.join(); + delete positions; + return 0; +} + +int main(int argc, const char** argv) +{ + int ret = 0; + + try { + parseOptions(argc, argv); + ret = hisat_3n_table(); + } catch(std::exception& e) { + cerr << "Error: Encountered exception: '" << e.what() << "'" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + return 1; + } catch(int e) { + if (e != 0) { + cerr << "Error: Encountered internal HISAT-3N exception (#" << e << ")" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + } + return e; + } + + return ret; +} diff --git a/hisat_bp.cpp b/hisat_bp.cpp new file mode 100644 index 0000000..a04116c --- /dev/null +++ b/hisat_bp.cpp @@ -0,0 +1,3885 @@ +/* + * Copyright 2014, Daehwan Kim + * + * This file is part of HISAT. + * + * HISAT is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "alphabet.h" +#include "assert_helpers.h" +#include "endian_swap.h" +#include "bt2_idx.h" +#include "bt2_io.h" +#include "bt2_util.h" +#include "hier_idx.h" +#include "formats.h" +#include "sequence_io.h" +#include "tokenize.h" +#include "aln_sink.h" +#include "pat.h" +#include "threading.h" +#include "ds.h" +#include "aligner_metrics.h" +#include "sam.h" +#include "aligner_seed.h" +#include "splice_site.h" +#include "bp_aligner.h" +#include "aligner_seed_policy.h" +#include "aligner_driver.h" +#include "aligner_sw.h" +#include "aligner_sw_driver.h" +#include "aligner_cache.h" +#include "util.h" +#include "pe.h" +#include "simple_func.h" +#include "presets.h" +#include "opts.h" +#include "outq.h" +#include "aligner_seed2.h" + +using namespace std; + +static EList mates1; // mated reads (first mate) +static EList mates2; // mated reads (second mate) +static EList mates12; // mated reads (1st/2nd interleaved in 1 file) +static string adjIdxBase; +bool gColor; // colorspace (not supported) +int gVerbose; // be talkative +static bool startVerbose; // be talkative at startup +int gQuiet; // print nothing but the alignments +static int sanityCheck; // enable expensive sanity checks +static int format; // default read format is FASTQ +static string origString; // reference text, or filename(s) +static int seed; // srandom() seed +static int timing; // whether to report basic timing data +static int metricsIval; // interval between alignment metrics messages (0 = no messages) +static string metricsFile;// output file to put alignment metrics in +static bool metricsStderr;// output file to put alignment metrics in +static bool metricsPerRead; // report a metrics tuple for every read +static bool allHits; // for multihits, report just one +static bool showVersion; // just print version and quit? +static int ipause; // pause before maching? +static uint32_t qUpto; // max # of queries to read +int gTrim5; // amount to trim from 5' end +int gTrim3; // amount to trim from 3' end +static int offRate; // keep default offRate +static bool solexaQuals; // quality strings are solexa quals, not phred, and subtract 64 (not 33) +static bool phred64Quals; // quality chars are phred, but must subtract 64 (not 33) +static bool integerQuals; // quality strings are space-separated strings of integers, not ASCII +static int nthreads; // number of pthreads operating concurrently +static int outType; // style of output +static bool noRefNames; // true -> print reference indexes; not names +static uint32_t khits; // number of hits per read; >1 is much slower +static uint32_t mhits; // don't report any hits if there are > mhits +static int partitionSz; // output a partitioning key in first field +static bool useSpinlock; // false -> don't use of spinlocks even if they're #defines +static bool fileParallel; // separate threads read separate input files in parallel +static bool useShmem; // use shared memory to hold the index +static bool useMm; // use memory-mapped files to hold the index +static bool mmSweep; // sweep through memory-mapped files immediately after mapping +int gMinInsert; // minimum insert size +int gMaxInsert; // maximum insert size +bool gMate1fw; // -1 mate aligns in fw orientation on fw strand +bool gMate2fw; // -2 mate aligns in rc orientation on fw strand +bool gFlippedMatesOK; // allow mates to be in wrong order +bool gDovetailMatesOK; // allow one mate to extend off the end of the other +bool gContainMatesOK; // allow one mate to contain the other in PE alignment +bool gOlapMatesOK; // allow mates to overlap in PE alignment +bool gExpandToFrag; // incr max frag length to =larger mate len if necessary +bool gReportDiscordant; // find and report discordant paired-end alignments +bool gReportMixed; // find and report unpaired alignments for paired reads +static uint32_t cacheLimit; // ranges w/ size > limit will be cached +static uint32_t cacheSize; // # words per range cache +static uint32_t skipReads; // # reads/read pairs to skip +bool gNofw; // don't align fw orientation of read +bool gNorc; // don't align rc orientation of read +static uint32_t fastaContLen; +static uint32_t fastaContFreq; +static bool hadoopOut; // print Hadoop status and summary messages +static bool fuzzy; +static bool fullRef; +static bool samTruncQname; // whether to truncate QNAME to 255 chars +static bool samOmitSecSeqQual; // omit SEQ/QUAL for 2ndary alignments? +static bool samNoUnal; // don't print records for unaligned reads +static bool samNoHead; // don't print any header lines in SAM output +static bool samNoSQ; // don't print @SQ header lines +static bool sam_print_as; +static bool sam_print_xs; // XS:i +static bool sam_print_xss; // Xs:i and Ys:i +static bool sam_print_yn; // YN:i and Yn:i +static bool sam_print_xn; +static bool sam_print_cs; +static bool sam_print_cq; +static bool sam_print_x0; +static bool sam_print_x1; +static bool sam_print_xm; +static bool sam_print_xo; +static bool sam_print_xg; +static bool sam_print_nm; +static bool sam_print_md; +static bool sam_print_yf; +static bool sam_print_yi; +static bool sam_print_ym; +static bool sam_print_yp; +static bool sam_print_yt; +static bool sam_print_ys; +static bool sam_print_zs; +static bool sam_print_xr; +static bool sam_print_xt; +static bool sam_print_xd; +static bool sam_print_xu; +static bool sam_print_yl; +static bool sam_print_ye; +static bool sam_print_yu; +static bool sam_print_xp; +static bool sam_print_yr; +static bool sam_print_zb; +static bool sam_print_zr; +static bool sam_print_zf; +static bool sam_print_zm; +static bool sam_print_zi; +static bool sam_print_zp; +static bool sam_print_zu; +static bool sam_print_xs_a; +static bool bwaSwLike; +static float bwaSwLikeC; +static float bwaSwLikeT; +static bool qcFilter; +static bool sortByScore; // prioritize alignments to report by score? +bool gReportOverhangs; // false -> filter out alignments that fall off the end of a reference sequence +static string rgid; // ID: setting for @RG header line +static string rgs; // SAM outputs for @RG header line +static string rgs_optflag; // SAM optional flag to add corresponding to @RG ID +static bool msample; // whether to report a random alignment when maxed-out via -m/-M +int gGapBarrier; // # diags on top/bot only to be entered diagonally +static EList qualities; +static EList qualities1; +static EList qualities2; +static string polstr; // temporary holder for policy string +static bool msNoCache; // true -> disable local cache +static int bonusMatchType; // how to reward matches +static int bonusMatch; // constant reward if bonusMatchType=constant +static int penMmcType; // how to penalize mismatches +static int penMmcMax; // max mm penalty +static int penMmcMin; // min mm penalty +static int penNType; // how to penalize Ns in the read +static int penN; // constant if N pelanty is a constant +static bool penNCatPair; // concatenate mates before N filtering? +static bool localAlign; // do local alignment in DP steps +static bool noisyHpolymer; // set to true if gap penalties should be reduced to be consistent with a sequencer that under- and overcalls homopolymers +static int penRdGapConst; // constant cost of extending a gap in the read +static int penRfGapConst; // constant cost of extending a gap in the reference +static int penRdGapLinear; // coeff of linear term for cost of gap extension in read +static int penRfGapLinear; // coeff of linear term for cost of gap extension in ref +static SimpleFunc scoreMin; // minimum valid score as function of read len +static SimpleFunc nCeil; // max # Ns allowed as function of read len +static SimpleFunc msIval; // interval between seeds as function of read len +static double descConsExp; // how to adjust score minimum as we descent further into index-assisted alignment +static size_t descentLanding; // don't place a search root if it's within this many positions of end +static SimpleFunc descentTotSz; // maximum space a DescentDriver can use in bytes +static SimpleFunc descentTotFmops; // maximum # FM ops a DescentDriver can perform +static int multiseedMms; // mismatches permitted in a multiseed seed +static int multiseedLen; // length of multiseed seeds +static size_t multiseedOff; // offset to begin extracting seeds +static uint32_t seedCacheLocalMB; // # MB to use for non-shared seed alignment cacheing +static uint32_t seedCacheCurrentMB; // # MB to use for current-read seed hit cacheing +static uint32_t exactCacheCurrentMB; // # MB to use for current-read seed hit cacheing +static size_t maxhalf; // max width on one side of DP table +static bool seedSumm; // print summary information about seed hits, not alignments +static bool doUngapped; // do ungapped alignment +static size_t maxIters; // stop after this many extend loop iterations +static size_t maxUg; // stop after this many ungap extends +static size_t maxDp; // stop after this many DPs +static size_t maxItersIncr; // amt to add to maxIters for each -k > 1 +static size_t maxEeStreak; // stop after this many end-to-end fails in a row +static size_t maxUgStreak; // stop after this many ungap fails in a row +static size_t maxDpStreak; // stop after this many dp fails in a row +static size_t maxStreakIncr; // amt to add to streak for each -k > 1 +static size_t maxMateStreak; // stop seed range after this many mate-find fails +static bool doExtend; // extend seed hits +static bool enable8; // use 8-bit SSE where possible? +static size_t cminlen; // longer reads use checkpointing +static size_t cpow2; // checkpoint interval log2 +static bool doTri; // do triangular mini-fills? +static string defaultPreset; // default preset; applied immediately +static bool ignoreQuals; // all mms incur same penalty, regardless of qual +static string wrapper; // type of wrapper script, so we can print correct usage +static EList queries; // list of query files +static string outfile; // write SAM output to this file +static int mapqv; // MAPQ calculation version +static int tighten; // -M tighten mode (0=none, 1=best, 2=secbest+1) +static bool doExactUpFront; // do exact search up front if seeds seem good enough +static bool do1mmUpFront; // do 1mm search up front if seeds seem good enough +static size_t do1mmMinLen; // length below which we disable 1mm e2e search +static int seedBoostThresh; // if average non-zero position has more than this many elements +static size_t nSeedRounds; // # seed rounds +static bool reorder; // true -> reorder SAM recs in -p mode +static float sampleFrac; // only align random fraction of input reads +static bool arbitraryRandom; // pseudo-randoms no longer a function of read properties +static bool bowtie2p5; +static bool useTempSpliceSite; +static int penCanSplice; +static int penNoncanSplice; +static SimpleFunc penIntronLen; +static string knownSpliceSiteInfile; // +static string novelSpliceSiteInfile; // +static string novelSpliceSiteOutfile; // +static bool no_spliced_alignment; +static int rna_strandness; // + +static string bt2index; // read Bowtie 2 index from files with this prefix +static EList > extra_opts; +static size_t extra_opts_cur; + +static EList thread_rids; +static MUTEX_T thread_rids_mutex; +static uint64_t thread_rids_mindist; + +#define DMAX std::numeric_limits::max() + +static void resetOptions() { + mates1.clear(); + mates2.clear(); + mates12.clear(); + adjIdxBase = ""; + gColor = false; + gVerbose = 0; + startVerbose = 0; + gQuiet = false; + sanityCheck = 0; // enable expensive sanity checks + format = FASTQ; // default read format is FASTQ + origString = ""; // reference text, or filename(s) + seed = 0; // srandom() seed + timing = 0; // whether to report basic timing data + metricsIval = 1; // interval between alignment metrics messages (0 = no messages) + metricsFile = ""; // output file to put alignment metrics in + metricsStderr = false; // print metrics to stderr (in addition to --metrics-file if it's specified + metricsPerRead = false; // report a metrics tuple for every read? + allHits = false; // for multihits, report just one + showVersion = false; // just print version and quit? + ipause = 0; // pause before maching? + qUpto = 0xffffffff; // max # of queries to read + gTrim5 = 0; // amount to trim from 5' end + gTrim3 = 0; // amount to trim from 3' end + offRate = -1; // keep default offRate + solexaQuals = false; // quality strings are solexa quals, not phred, and subtract 64 (not 33) + phred64Quals = false; // quality chars are phred, but must subtract 64 (not 33) + integerQuals = false; // quality strings are space-separated strings of integers, not ASCII + nthreads = 1; // number of pthreads operating concurrently + outType = OUTPUT_SAM; // style of output + noRefNames = false; // true -> print reference indexes; not names + khits = 5; // number of hits per read; >1 is much slower + mhits = 0; // stop after finding this many alignments+1 + partitionSz = 0; // output a partitioning key in first field + useSpinlock = true; // false -> don't use of spinlocks even if they're #defines + fileParallel = false; // separate threads read separate input files in parallel + useShmem = false; // use shared memory to hold the index + useMm = false; // use memory-mapped files to hold the index + mmSweep = false; // sweep through memory-mapped files immediately after mapping + gMinInsert = 0; // minimum insert size + gMaxInsert = 500; // maximum insert size + gMate1fw = true; // -1 mate aligns in fw orientation on fw strand + gMate2fw = false; // -2 mate aligns in rc orientation on fw strand + gFlippedMatesOK = false; // allow mates to be in wrong order + gDovetailMatesOK = false; // allow one mate to extend off the end of the other + gContainMatesOK = true; // allow one mate to contain the other in PE alignment + gOlapMatesOK = true; // allow mates to overlap in PE alignment + gExpandToFrag = true; // incr max frag length to =larger mate len if necessary + gReportDiscordant = true; // find and report discordant paired-end alignments + gReportMixed = true; // find and report unpaired alignments for paired reads + + cacheLimit = 5; // ranges w/ size > limit will be cached + cacheSize = 0; // # words per range cache + skipReads = 0; // # reads/read pairs to skip + gNofw = false; // don't align fw orientation of read + gNorc = false; // don't align rc orientation of read + fastaContLen = 0; + fastaContFreq = 0; + hadoopOut = false; // print Hadoop status and summary messages + fuzzy = false; // reads will have alternate basecalls w/ qualities + fullRef = false; // print entire reference name instead of just up to 1st space + samTruncQname = true; // whether to truncate QNAME to 255 chars + samOmitSecSeqQual = false; // omit SEQ/QUAL for 2ndary alignments? + samNoUnal = false; // omit SAM records for unaligned reads + samNoHead = false; // don't print any header lines in SAM output + samNoSQ = false; // don't print @SQ header lines + sam_print_as = true; + sam_print_xs = true; + sam_print_xss = false; // Xs:i and Ys:i + sam_print_yn = false; // YN:i and Yn:i + sam_print_xn = true; + sam_print_cs = false; + sam_print_cq = false; + sam_print_x0 = true; + sam_print_x1 = true; + sam_print_xm = true; + sam_print_xo = true; + sam_print_xg = true; + sam_print_nm = true; + sam_print_md = true; + sam_print_yf = true; + sam_print_yi = false; + sam_print_ym = false; + sam_print_yp = false; + sam_print_yt = true; + sam_print_ys = true; + sam_print_zs = false; + sam_print_xr = false; + sam_print_xt = false; + sam_print_xd = false; + sam_print_xu = false; + sam_print_yl = false; + sam_print_ye = false; + sam_print_yu = false; + sam_print_xp = false; + sam_print_yr = false; + sam_print_zb = false; + sam_print_zr = false; + sam_print_zf = false; + sam_print_zm = false; + sam_print_zi = false; + sam_print_zp = false; + sam_print_zu = false; + sam_print_xs_a = true; + bwaSwLike = false; + bwaSwLikeC = 5.5f; + bwaSwLikeT = 20.0f; + qcFilter = false; // don't believe upstream qc by default + sortByScore = true; // prioritize alignments to report by score? + rgid = ""; // SAM outputs for @RG header line + rgs = ""; // SAM outputs for @RG header line + rgs_optflag = ""; // SAM optional flag to add corresponding to @RG ID + msample = true; + gGapBarrier = 4; // disallow gaps within this many chars of either end of alignment + qualities.clear(); + qualities1.clear(); + qualities2.clear(); + polstr.clear(); + msNoCache = true; // true -> disable local cache + bonusMatchType = DEFAULT_MATCH_BONUS_TYPE; + bonusMatch = DEFAULT_MATCH_BONUS; + penMmcType = DEFAULT_MM_PENALTY_TYPE; + penMmcMax = DEFAULT_MM_PENALTY_MAX; + penMmcMin = DEFAULT_MM_PENALTY_MIN; + penNType = DEFAULT_N_PENALTY_TYPE; + penN = DEFAULT_N_PENALTY; + penNCatPair = DEFAULT_N_CAT_PAIR; // concatenate mates before N filtering? + localAlign = false; // do local alignment in DP steps + noisyHpolymer = false; + penRdGapConst = DEFAULT_READ_GAP_CONST; + penRfGapConst = DEFAULT_REF_GAP_CONST; + penRdGapLinear = DEFAULT_READ_GAP_LINEAR; + penRfGapLinear = DEFAULT_REF_GAP_LINEAR; + // scoreMin.init (SIMPLE_FUNC_LINEAR, DEFAULT_MIN_CONST, DEFAULT_MIN_LINEAR); + scoreMin.init (SIMPLE_FUNC_CONST, -18, 0); + nCeil.init (SIMPLE_FUNC_LINEAR, 0.0f, DMAX, 2.0f, 0.1f); + msIval.init (SIMPLE_FUNC_LINEAR, 1.0f, DMAX, DEFAULT_IVAL_B, DEFAULT_IVAL_A); + descConsExp = 2.0; + descentLanding = 20; + descentTotSz.init(SIMPLE_FUNC_LINEAR, 1024.0, DMAX, 0.0, 1024.0); + descentTotFmops.init(SIMPLE_FUNC_LINEAR, 100.0, DMAX, 0.0, 10.0); + multiseedMms = DEFAULT_SEEDMMS; + multiseedLen = DEFAULT_SEEDLEN; + multiseedOff = 0; + seedCacheLocalMB = 32; // # MB to use for non-shared seed alignment cacheing + seedCacheCurrentMB = 20; // # MB to use for current-read seed hit cacheing + exactCacheCurrentMB = 20; // # MB to use for current-read seed hit cacheing + maxhalf = 15; // max width on one side of DP table + seedSumm = false; // print summary information about seed hits, not alignments + doUngapped = true; // do ungapped alignment + maxIters = 400; // max iterations of extend loop + maxUg = 300; // stop after this many ungap extends + maxDp = 300; // stop after this many dp extends + maxItersIncr = 20; // amt to add to maxIters for each -k > 1 + maxEeStreak = 15; // stop after this many end-to-end fails in a row + maxUgStreak = 15; // stop after this many ungap fails in a row + maxDpStreak = 15; // stop after this many dp fails in a row + maxStreakIncr = 10; // amt to add to streak for each -k > 1 + maxMateStreak = 10; // in PE: abort seed range after N mate-find fails + doExtend = true; // do seed extensions + enable8 = true; // use 8-bit SSE where possible? + cminlen = 2000; // longer reads use checkpointing + cpow2 = 4; // checkpoint interval log2 + doTri = false; // do triangular mini-fills? + defaultPreset = "sensitive%LOCAL%"; // default preset; applied immediately + extra_opts.clear(); + extra_opts_cur = 0; + bt2index.clear(); // read Bowtie 2 index from files with this prefix + ignoreQuals = false; // all mms incur same penalty, regardless of qual + wrapper.clear(); // type of wrapper script, so we can print correct usage + queries.clear(); // list of query files + outfile.clear(); // write SAM output to this file + mapqv = 2; // MAPQ calculation version + tighten = 3; // -M tightening mode + doExactUpFront = true; // do exact search up front if seeds seem good enough + do1mmUpFront = true; // do 1mm search up front if seeds seem good enough + seedBoostThresh = 300; // if average non-zero position has more than this many elements + nSeedRounds = 2; // # rounds of seed searches to do for repetitive reads + do1mmMinLen = 60; // length below which we disable 1mm search + reorder = false; // reorder SAM records with -p > 1 + sampleFrac = 1.1f; // align all reads + arbitraryRandom = false; // let pseudo-random seeds be a function of read properties + bowtie2p5 = false; + useTempSpliceSite = true; + penCanSplice = 0; + penNoncanSplice = 3; + penIntronLen.init(SIMPLE_FUNC_LOG, -8, 1); + knownSpliceSiteInfile = ""; + novelSpliceSiteInfile = ""; + novelSpliceSiteOutfile = ""; + no_spliced_alignment = false; + rna_strandness = RNA_STRANDNESS_UNKNOWN; +} + +static const char *short_options = "fF:qbzhcu:rv:s:aP:t3:5:w:p:k:M:1:2:I:X:CQ:N:i:L:U:x:S:g:O:D:R:"; + +static struct option long_options[] = { + {(char*)"verbose", no_argument, 0, ARG_VERBOSE}, + {(char*)"startverbose", no_argument, 0, ARG_STARTVERBOSE}, + {(char*)"quiet", no_argument, 0, ARG_QUIET}, + {(char*)"sanity", no_argument, 0, ARG_SANITY}, + {(char*)"pause", no_argument, &ipause, 1}, + {(char*)"orig", required_argument, 0, ARG_ORIG}, + {(char*)"all", no_argument, 0, 'a'}, + {(char*)"solexa-quals", no_argument, 0, ARG_SOLEXA_QUALS}, + {(char*)"integer-quals",no_argument, 0, ARG_INTEGER_QUALS}, + {(char*)"int-quals", no_argument, 0, ARG_INTEGER_QUALS}, + {(char*)"metrics", required_argument, 0, ARG_METRIC_IVAL}, + {(char*)"metrics-file", required_argument, 0, ARG_METRIC_FILE}, + {(char*)"metrics-stderr",no_argument, 0, ARG_METRIC_STDERR}, + {(char*)"metrics-per-read", no_argument, 0, ARG_METRIC_PER_READ}, + {(char*)"met-read", no_argument, 0, ARG_METRIC_PER_READ}, + {(char*)"met", required_argument, 0, ARG_METRIC_IVAL}, + {(char*)"met-file", required_argument, 0, ARG_METRIC_FILE}, + {(char*)"met-stderr", no_argument, 0, ARG_METRIC_STDERR}, + {(char*)"time", no_argument, 0, 't'}, + {(char*)"trim3", required_argument, 0, '3'}, + {(char*)"trim5", required_argument, 0, '5'}, + {(char*)"seed", required_argument, 0, ARG_SEED}, + {(char*)"qupto", required_argument, 0, 'u'}, + {(char*)"upto", required_argument, 0, 'u'}, + {(char*)"version", no_argument, 0, ARG_VERSION}, + {(char*)"filepar", no_argument, 0, ARG_FILEPAR}, + {(char*)"help", no_argument, 0, 'h'}, + {(char*)"threads", required_argument, 0, 'p'}, + {(char*)"khits", required_argument, 0, 'k'}, + {(char*)"minins", required_argument, 0, 'I'}, + {(char*)"maxins", required_argument, 0, 'X'}, + {(char*)"quals", required_argument, 0, 'Q'}, + {(char*)"Q1", required_argument, 0, ARG_QUALS1}, + {(char*)"Q2", required_argument, 0, ARG_QUALS2}, + {(char*)"refidx", no_argument, 0, ARG_REFIDX}, + {(char*)"partition", required_argument, 0, ARG_PARTITION}, + {(char*)"ff", no_argument, 0, ARG_FF}, + {(char*)"fr", no_argument, 0, ARG_FR}, + {(char*)"rf", no_argument, 0, ARG_RF}, + {(char*)"cachelim", required_argument, 0, ARG_CACHE_LIM}, + {(char*)"cachesz", required_argument, 0, ARG_CACHE_SZ}, + {(char*)"nofw", no_argument, 0, ARG_NO_FW}, + {(char*)"norc", no_argument, 0, ARG_NO_RC}, + {(char*)"skip", required_argument, 0, 's'}, + {(char*)"12", required_argument, 0, ARG_ONETWO}, + {(char*)"tab5", required_argument, 0, ARG_TAB5}, + {(char*)"tab6", required_argument, 0, ARG_TAB6}, + {(char*)"phred33-quals", no_argument, 0, ARG_PHRED33}, + {(char*)"phred64-quals", no_argument, 0, ARG_PHRED64}, + {(char*)"phred33", no_argument, 0, ARG_PHRED33}, + {(char*)"phred64", no_argument, 0, ARG_PHRED64}, + {(char*)"solexa1.3-quals", no_argument, 0, ARG_PHRED64}, + {(char*)"mm", no_argument, 0, ARG_MM}, + {(char*)"shmem", no_argument, 0, ARG_SHMEM}, + {(char*)"mmsweep", no_argument, 0, ARG_MMSWEEP}, + {(char*)"hadoopout", no_argument, 0, ARG_HADOOPOUT}, + {(char*)"fuzzy", no_argument, 0, ARG_FUZZY}, + {(char*)"fullref", no_argument, 0, ARG_FULLREF}, + {(char*)"usage", no_argument, 0, ARG_USAGE}, + {(char*)"sam-no-qname-trunc", no_argument, 0, ARG_SAM_NO_QNAME_TRUNC}, + {(char*)"sam-omit-sec-seq", no_argument, 0, ARG_SAM_OMIT_SEC_SEQ}, + {(char*)"omit-sec-seq", no_argument, 0, ARG_SAM_OMIT_SEC_SEQ}, + {(char*)"sam-no-head", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-nohead", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-noHD", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-no-hd", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"sam-nosq", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"sam-no-sq", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"sam-noSQ", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"no-head", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"no-hd", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"no-sq", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"no-HD", no_argument, 0, ARG_SAM_NOHEAD}, + {(char*)"no-SQ", no_argument, 0, ARG_SAM_NOSQ}, + {(char*)"no-unal", no_argument, 0, ARG_SAM_NO_UNAL}, + {(char*)"color", no_argument, 0, 'C'}, + {(char*)"sam-RG", required_argument, 0, ARG_SAM_RG}, + {(char*)"sam-rg", required_argument, 0, ARG_SAM_RG}, + {(char*)"sam-rg-id", required_argument, 0, ARG_SAM_RGID}, + {(char*)"RG", required_argument, 0, ARG_SAM_RG}, + {(char*)"rg", required_argument, 0, ARG_SAM_RG}, + {(char*)"rg-id", required_argument, 0, ARG_SAM_RGID}, + {(char*)"snpphred", required_argument, 0, ARG_SNPPHRED}, + {(char*)"snpfrac", required_argument, 0, ARG_SNPFRAC}, + {(char*)"gbar", required_argument, 0, ARG_GAP_BAR}, + {(char*)"qseq", no_argument, 0, ARG_QSEQ}, + {(char*)"policy", required_argument, 0, ARG_ALIGN_POLICY}, + {(char*)"preset", required_argument, 0, 'P'}, + {(char*)"seed-summ", no_argument, 0, ARG_SEED_SUMM}, + {(char*)"seed-summary", no_argument, 0, ARG_SEED_SUMM}, + {(char*)"overhang", no_argument, 0, ARG_OVERHANG}, + {(char*)"no-cache", no_argument, 0, ARG_NO_CACHE}, + {(char*)"cache", no_argument, 0, ARG_USE_CACHE}, + {(char*)"454", no_argument, 0, ARG_NOISY_HPOLY}, + {(char*)"ion-torrent", no_argument, 0, ARG_NOISY_HPOLY}, + {(char*)"no-mixed", no_argument, 0, ARG_NO_MIXED}, + {(char*)"no-discordant",no_argument, 0, ARG_NO_DISCORDANT}, + {(char*)"local", no_argument, 0, ARG_LOCAL}, + {(char*)"end-to-end", no_argument, 0, ARG_END_TO_END}, + {(char*)"ungapped", no_argument, 0, ARG_UNGAPPED}, + {(char*)"no-ungapped", no_argument, 0, ARG_UNGAPPED_NO}, + {(char*)"sse8", no_argument, 0, ARG_SSE8}, + {(char*)"no-sse8", no_argument, 0, ARG_SSE8_NO}, + {(char*)"scan-narrowed",no_argument, 0, ARG_SCAN_NARROWED}, + {(char*)"qc-filter", no_argument, 0, ARG_QC_FILTER}, + {(char*)"bwa-sw-like", no_argument, 0, ARG_BWA_SW_LIKE}, + {(char*)"multiseed", required_argument, 0, ARG_MULTISEED_IVAL}, + {(char*)"ma", required_argument, 0, ARG_SCORE_MA}, + {(char*)"mp", required_argument, 0, ARG_SCORE_MMP}, + {(char*)"np", required_argument, 0, ARG_SCORE_NP}, + {(char*)"rdg", required_argument, 0, ARG_SCORE_RDG}, + {(char*)"rfg", required_argument, 0, ARG_SCORE_RFG}, + {(char*)"score-min", required_argument, 0, ARG_SCORE_MIN}, + {(char*)"min-score", required_argument, 0, ARG_SCORE_MIN}, + {(char*)"n-ceil", required_argument, 0, ARG_N_CEIL}, + {(char*)"dpad", required_argument, 0, ARG_DPAD}, + {(char*)"mapq-print-inputs",no_argument, 0, ARG_SAM_PRINT_YI}, + {(char*)"very-fast", no_argument, 0, ARG_PRESET_VERY_FAST}, + {(char*)"fast", no_argument, 0, ARG_PRESET_FAST}, + {(char*)"sensitive", no_argument, 0, ARG_PRESET_SENSITIVE}, + {(char*)"very-sensitive", no_argument, 0, ARG_PRESET_VERY_SENSITIVE}, + {(char*)"very-fast-local", no_argument, 0, ARG_PRESET_VERY_FAST_LOCAL}, + {(char*)"fast-local", no_argument, 0, ARG_PRESET_FAST_LOCAL}, + {(char*)"sensitive-local", no_argument, 0, ARG_PRESET_SENSITIVE_LOCAL}, + {(char*)"very-sensitive-local", no_argument, 0, ARG_PRESET_VERY_SENSITIVE_LOCAL}, + {(char*)"no-score-priority",no_argument, 0, ARG_NO_SCORE_PRIORITY}, + {(char*)"seedlen", required_argument, 0, 'L'}, + {(char*)"seedmms", required_argument, 0, 'N'}, + {(char*)"seedival", required_argument, 0, 'i'}, + {(char*)"ignore-quals", no_argument, 0, ARG_IGNORE_QUALS}, + {(char*)"index", required_argument, 0, 'x'}, + {(char*)"arg-desc", no_argument, 0, ARG_DESC}, + {(char*)"wrapper", required_argument, 0, ARG_WRAPPER}, + {(char*)"unpaired", required_argument, 0, 'U'}, + {(char*)"output", required_argument, 0, 'S'}, + {(char*)"mapq-v", required_argument, 0, ARG_MAPQ_V}, + {(char*)"dovetail", no_argument, 0, ARG_DOVETAIL}, + {(char*)"no-dovetail", no_argument, 0, ARG_NO_DOVETAIL}, + {(char*)"contain", no_argument, 0, ARG_CONTAIN}, + {(char*)"no-contain", no_argument, 0, ARG_NO_CONTAIN}, + {(char*)"overlap", no_argument, 0, ARG_OVERLAP}, + {(char*)"no-overlap", no_argument, 0, ARG_NO_OVERLAP}, + {(char*)"tighten", required_argument, 0, ARG_TIGHTEN}, + {(char*)"exact-upfront", no_argument, 0, ARG_EXACT_UPFRONT}, + {(char*)"1mm-upfront", no_argument, 0, ARG_1MM_UPFRONT}, + {(char*)"no-exact-upfront", no_argument, 0, ARG_EXACT_UPFRONT_NO}, + {(char*)"no-1mm-upfront", no_argument, 0, ARG_1MM_UPFRONT_NO}, + {(char*)"1mm-minlen", required_argument, 0, ARG_1MM_MINLEN}, + {(char*)"seed-off", required_argument, 0, 'O'}, + {(char*)"seed-boost", required_argument, 0, ARG_SEED_BOOST_THRESH}, + {(char*)"read-times", no_argument, 0, ARG_READ_TIMES}, + {(char*)"show-rand-seed", no_argument, 0, ARG_SHOW_RAND_SEED}, + {(char*)"dp-fail-streak", required_argument, 0, ARG_DP_FAIL_STREAK_THRESH}, + {(char*)"ee-fail-streak", required_argument, 0, ARG_EE_FAIL_STREAK_THRESH}, + {(char*)"ug-fail-streak", required_argument, 0, ARG_UG_FAIL_STREAK_THRESH}, + {(char*)"fail-streak", required_argument, 0, 'D'}, + {(char*)"dp-fails", required_argument, 0, ARG_DP_FAIL_THRESH}, + {(char*)"ug-fails", required_argument, 0, ARG_UG_FAIL_THRESH}, + {(char*)"extends", required_argument, 0, ARG_EXTEND_ITERS}, + {(char*)"no-extend", no_argument, 0, ARG_NO_EXTEND}, + {(char*)"mapq-extra", no_argument, 0, ARG_MAPQ_EX}, + {(char*)"seed-rounds", required_argument, 0, 'R'}, + {(char*)"reorder", no_argument, 0, ARG_REORDER}, + {(char*)"passthrough", no_argument, 0, ARG_READ_PASSTHRU}, + {(char*)"sample", required_argument, 0, ARG_SAMPLE}, + {(char*)"cp-min", required_argument, 0, ARG_CP_MIN}, + {(char*)"cp-ival", required_argument, 0, ARG_CP_IVAL}, + {(char*)"tri", no_argument, 0, ARG_TRI}, + {(char*)"nondeterministic", no_argument, 0, ARG_NON_DETERMINISTIC}, + {(char*)"non-deterministic", no_argument, 0, ARG_NON_DETERMINISTIC}, + {(char*)"local-seed-cache-sz", required_argument, 0, ARG_LOCAL_SEED_CACHE_SZ}, + {(char*)"seed-cache-sz", required_argument, 0, ARG_CURRENT_SEED_CACHE_SZ}, + {(char*)"no-unal", no_argument, 0, ARG_SAM_NO_UNAL}, + {(char*)"test-25", no_argument, 0, ARG_TEST_25}, + // TODO: following should be a function of read length? + {(char*)"desc-kb", required_argument, 0, ARG_DESC_KB}, + {(char*)"desc-landing", required_argument, 0, ARG_DESC_LANDING}, + {(char*)"desc-exp", required_argument, 0, ARG_DESC_EXP}, + {(char*)"desc-fmops", required_argument, 0, ARG_DESC_FMOPS}, + {(char*)"no-temp-splicesite", no_argument, 0, ARG_NO_TEMPSPLICESITE}, + {(char*)"pen-cansplice", required_argument, 0, ARG_PEN_CANSPLICE}, + {(char*)"pen-noncansplice", required_argument, 0, ARG_PEN_NONCANSPLICE}, + {(char*)"pen-intronlen", required_argument, 0, ARG_PEN_INTRONLEN}, + {(char*)"known-splicesite-infile", required_argument, 0, ARG_KNOWN_SPLICESITE_INFILE}, + {(char*)"novel-splicesite-infile", required_argument, 0, ARG_NOVEL_SPLICESITE_INFILE}, + {(char*)"novel-splicesite-outfile", required_argument, 0, ARG_NOVEL_SPLICESITE_OUTFILE}, + {(char*)"no-spliced-alignment", no_argument, 0, ARG_NO_SPLICED_ALIGNMENT}, + {(char*)"rna-strandness", required_argument, 0, ARG_RNA_STRANDNESS}, + {(char*)0, 0, 0, 0} // terminator +}; + +/** + * Print out a concise description of what options are taken and whether they + * take an argument. + */ +static void printArgDesc(ostream& out) { + // struct option { + // const char *name; + // int has_arg; + // int *flag; + // int val; + // }; + size_t i = 0; + while(long_options[i].name != 0) { + out << long_options[i].name << "\t" + << (long_options[i].has_arg == no_argument ? 0 : 1) + << endl; + i++; + } + size_t solen = strlen(short_options); + for(i = 0; i < solen; i++) { + // Has an option? Does if next char is : + if(i == solen-1) { + assert_neq(':', short_options[i]); + cout << (char)short_options[i] << "\t" << 0 << endl; + } else { + if(short_options[i+1] == ':') { + // Option with argument + cout << (char)short_options[i] << "\t" << 1 << endl; + i++; // skip the ':' + } else { + // Option with no argument + cout << (char)short_options[i] << "\t" << 0 << endl; + } + } + } +} + +/** + * Print a summary usage message to the provided output stream. + */ +static void printUsage(ostream& out) { + out << "HISAT version " << string(HISAT_VERSION).c_str() << " by Daehwan Kim (infphilo@gmail.com, www.ccb.jhu.edu/people/infphilo)" << endl; + string tool_name = "hisat2-align"; + if(wrapper == "basic-0") { + tool_name = "hisat"; + } + out << "Usage: " << endl + << " " << tool_name.c_str() << " [options]* -x {-1 -2 | -U } [-S ]" << endl + << endl + << " Index filename prefix (minus trailing .X." << gfm_ext << ")." << endl + << " Files with #1 mates, paired with files in ." << endl; + if(wrapper == "basic-0") { + out << " Could be gzip'ed (extension: .gz) or bzip2'ed (extension: .bz2)." << endl; + } + out << " Files with #2 mates, paired with files in ." << endl; + if(wrapper == "basic-0") { + out << " Could be gzip'ed (extension: .gz) or bzip2'ed (extension: .bz2)." << endl; + } + out << " Files with unpaired reads." << endl; + if(wrapper == "basic-0") { + out << " Could be gzip'ed (extension: .gz) or bzip2'ed (extension: .bz2)." << endl; + } + out << " File for SAM output (default: stdout)" << endl + << endl + << " , , can be comma-separated lists (no whitespace) and can be" << endl + << " specified many times. E.g. '-U file1.fq,file2.fq -U file3.fq'." << endl + // Wrapper script should write line next + << endl + << "Options (defaults in parentheses):" << endl + << endl + << " Input:" << endl + << " -q query input files are FASTQ .fq/.fastq (default)" << endl + << " --qseq query input files are in Illumina's qseq format" << endl + << " -f query input files are (multi-)FASTA .fa/.mfa" << endl + << " -r query input files are raw one-sequence-per-line" << endl + << " -c , , are sequences themselves, not files" << endl + << " -s/--skip skip the first reads/pairs in the input (none)" << endl + << " -u/--upto stop after first reads/pairs (no limit)" << endl + << " -5/--trim5 trim bases from 5'/left end of reads (0)" << endl + << " -3/--trim3 trim bases from 3'/right end of reads (0)" << endl + << " --phred33 qualities are Phred+33 (default)" << endl + << " --phred64 qualities are Phred+64" << endl + << " --int-quals qualities encoded as space-delimited integers" << endl + << endl + << " Presets: Same as:" << endl + << " For --end-to-end:" << endl + << " --very-fast -D 5 -R 1 -N 0 -L 22 -i S,0,2.50" << endl + << " --fast -D 10 -R 2 -N 0 -L 22 -i S,0,2.50" << endl + << " --sensitive -D 15 -R 2 -N 0 -L 22 -i S,1,1.15 (default)" << endl + << " --very-sensitive -D 20 -R 3 -N 0 -L 20 -i S,1,0.50" << endl + << endl + << " For --local:" << endl + << " --very-fast-local -D 5 -R 1 -N 0 -L 25 -i S,1,2.00" << endl + << " --fast-local -D 10 -R 2 -N 0 -L 22 -i S,1,1.75" << endl + << " --sensitive-local -D 15 -R 2 -N 0 -L 20 -i S,1,0.75 (default)" << endl + << " --very-sensitive-local -D 20 -R 3 -N 0 -L 20 -i S,1,0.50" << endl + << endl + << " Alignment:" << endl + << " -N max # mismatches in seed alignment; can be 0 or 1 (0)" << endl + << " -L length of seed substrings; must be >3, <32 (22)" << endl + << " -i interval between seed substrings w/r/t read len (S,1,1.15)" << endl + << " --n-ceil func for max # non-A/C/G/Ts permitted in aln (L,0,0.15)" << endl + << " --dpad include extra ref chars on sides of DP table (15)" << endl + << " --gbar disallow gaps within nucs of read extremes (4)" << endl + << " --ignore-quals treat all quality values as 30 on Phred scale (off)" << endl + << " --nofw do not align forward (original) version of read (off)" << endl + << " --norc do not align reverse-complement version of read (off)" << endl + << endl + << " Spliced Alignment:" << endl + << " --pen-cansplice penalty for a canonical splice site (0)" << endl + << " --pen-noncansplice penalty for a non-canonical splice site (3)" << endl + << " --pen-intronlen penalty for long introns (G,-8,1)" << endl + << " --known-splicesite-infile provide a list of known splice sites" << endl + << " --novel-splicesite-outfile report a list of splice sites" << endl + << " --novel-splicesite-infile provide a list of novel splice sites" << endl + << " --no-temp-splicesite disable the use of splice sites found" << endl + << " --no-spliced-alignment disable spliced alignment" << endl + << " --rna-strandness Specify strand-specific information (unstranded)" << endl + << endl + << " Scoring:" << endl + << " --ma match bonus (0 for --end-to-end, 2 for --local) " << endl + << " --mp max penalty for mismatch; lower qual = lower penalty (6)" << endl + << " --np penalty for non-A/C/G/Ts in read/ref (1)" << endl + << " --rdg , read gap open, extend penalties (5,3)" << endl + << " --rfg , reference gap open, extend penalties (5,3)" << endl + << " --score-min min acceptable alignment score w/r/t read length" << endl + << " (G,20,8 for local, L,-0.6,-0.6 for end-to-end)" << endl + << endl + << " Reporting:" << endl + << " (default) look for multiple alignments, report best, with MAPQ" << endl + << " OR" << endl + << " -k report up to alns per read; MAPQ not meaningful" << endl + << " OR" << endl + << " -a/--all report all alignments; very slow, MAPQ not meaningful" << endl + << endl + << " Effort:" << endl + << " -D give up extending after failed extends in a row (15)" << endl + << " -R for reads w/ repetitive seeds, try sets of seeds (2)" << endl + << endl + << " Paired-end:" << endl + << " -I/--minins minimum fragment length (0)" << endl + << " -X/--maxins maximum fragment length (500)" << endl + << " --fr/--rf/--ff -1, -2 mates align fw/rev, rev/fw, fw/fw (--fr)" << endl + << " --no-mixed suppress unpaired alignments for paired reads" << endl + << " --no-discordant suppress discordant alignments for paired reads" << endl + << " --no-dovetail not concordant when mates extend past each other" << endl + << " --no-contain not concordant when one mate alignment contains other" << endl + << " --no-overlap not concordant when mates overlap at all" << endl + << endl + << " Output:" << endl; + //if(wrapper == "basic-0") { + // out << " --bam output directly to BAM (by piping through 'samtools view')" << endl; + //} + out << " -t/--time print wall-clock time taken by search phases" << endl; + if(wrapper == "basic-0") { + out << " --un write unpaired reads that didn't align to " << endl + << " --al write unpaired reads that aligned at least once to " << endl + << " --un-conc write pairs that didn't align concordantly to " << endl + << " --al-conc write pairs that aligned concordantly at least once to " << endl + << " (Note: for --un, --al, --un-conc, or --al-conc, add '-gz' to the option name, e.g." << endl + << " --un-gz , to gzip compress output, or add '-bz2' to bzip2 compress output.)" << endl; + } + out << " --quiet print nothing to stderr except serious errors" << endl + // << " --refidx refer to ref. seqs by 0-based index rather than name" << endl + << " --met-file send metrics to file at (off)" << endl + << " --met-stderr send metrics to stderr (off)" << endl + << " --met report internal counters & metrics every secs (1)" << endl + // Following is supported in the wrapper instead + // << " --no-unal supppress SAM records for unaligned reads" << endl + << " --no-head supppress header lines, i.e. lines starting with @" << endl + << " --no-sq supppress @SQ header lines" << endl + << " --rg-id set read group id, reflected in @RG line and RG:Z: opt field" << endl + << " --rg add (\"lab:value\") to @RG line of SAM header." << endl + << " Note: @RG line only printed when --rg-id is set." << endl + << " --omit-sec-seq put '*' in SEQ and QUAL fields for secondary alignments." << endl + << endl + << " Performance:" << endl + << " -o/--offrate override offrate of index; must be >= index's offrate" << endl + << " -p/--threads number of alignment threads to launch (1)" << endl + << " --reorder force SAM output order to match order of input reads" << endl +#ifdef BOWTIE_MM + << " --mm use memory-mapped I/O for index; many 'hisat2's can share" << endl +#endif +#ifdef BOWTIE_SHARED_MEM + //<< " --shmem use shared mem for index; many 'hisat2's can share" << endl +#endif + << endl + << " Other:" << endl + << " --qc-filter filter out reads that are bad according to QSEQ filter" << endl + << " --seed seed for random number generator (0)" << endl + << " --non-deterministic seed rand. gen. arbitrarily instead of using read attributes" << endl + // << " --verbose verbose output for debugging" << endl + << " --version print version information and quit" << endl + << " -h/--help print this usage message" << endl + ; + if(wrapper.empty()) { + cerr << endl + << "*** Warning ***" << endl + << "'hisat2-align' was run directly. It is recommended that you run the wrapper script 'hisat2' instead." << endl + << endl; + } +} + +/** + * Parse an int out of optarg and enforce that it be at least 'lower'; + * if it is less than 'lower', than output the given error message and + * exit with an error and a usage message. + */ +static int parseInt(int lower, int upper, const char *errmsg, const char *arg) { + long l; + char *endPtr= NULL; + l = strtol(arg, &endPtr, 10); + if (endPtr != NULL) { + if (l < lower || l > upper) { + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + } + return (int32_t)l; + } + cerr << errmsg << endl; + printUsage(cerr); + throw 1; + return -1; +} + +/** + * Upper is maximum int by default. + */ +static int parseInt(int lower, const char *errmsg, const char *arg) { + return parseInt(lower, std::numeric_limits::max(), errmsg, arg); +} + +/** + * Parse a T string 'str'. + */ +template +T parse(const char *s) { + T tmp; + stringstream ss(s); + ss >> tmp; + return tmp; +} + +/** + * Parse a pair of Ts from a string, 'str', delimited with 'delim'. + */ +template +pair parsePair(const char *str, char delim) { + string s(str); + EList ss; + tokenize(s, delim, ss); + pair ret; + ret.first = parse(ss[0].c_str()); + ret.second = parse(ss[1].c_str()); + return ret; +} + +/** + * Parse a pair of Ts from a string, 'str', delimited with 'delim'. + */ +template +void parseTuple(const char *str, char delim, EList& ret) { + string s(str); + EList ss; + tokenize(s, delim, ss); + for(size_t i = 0; i < ss.size(); i++) { + ret.push_back(parse(ss[i].c_str())); + } +} + +static string applyPreset(const string& sorig, Presets& presets) { + string s = sorig; + size_t found = s.find("%LOCAL%"); + if(found != string::npos) { + s.replace(found, strlen("%LOCAL%"), localAlign ? "-local" : ""); + } + if(gVerbose) { + cerr << "Applying preset: '" << s.c_str() << "' using preset menu '" + << presets.name() << "'" << endl; + } + string pol; + presets.apply(s, pol, extra_opts); + return pol; +} + +static bool saw_M; +static bool saw_a; +static bool saw_k; +static EList presetList; + +/** + * TODO: Argument parsing is very, very flawed. The biggest problem is that + * there are two separate worlds of arguments, the ones set via polstr, and + * the ones set directly in variables. This makes for nasty interactions, + * e.g., with the -M option being resolved at an awkward time relative to + * the -k and -a options. + */ +static void parseOption(int next_option, const char *arg) { + switch (next_option) { + case ARG_TEST_25: bowtie2p5 = true; break; + case ARG_DESC_KB: descentTotSz = SimpleFunc::parse(arg, 0.0, 1024.0, 1024.0, DMAX); break; + case ARG_DESC_FMOPS: descentTotFmops = SimpleFunc::parse(arg, 0.0, 10.0, 100.0, DMAX); break; + case ARG_DESC_LANDING: descentLanding = parse(arg); break; + case ARG_DESC_EXP: { + descConsExp = parse(arg); + if(descConsExp < 0.0) { + cerr << "Error: --desc-exp must be greater than or equal to 0" << endl; + throw 1; + } + break; + } + case '1': tokenize(arg, ",", mates1); break; + case '2': tokenize(arg, ",", mates2); break; + case ARG_ONETWO: tokenize(arg, ",", mates12); format = TAB_MATE5; break; + case ARG_TAB5: tokenize(arg, ",", mates12); format = TAB_MATE5; break; + case ARG_TAB6: tokenize(arg, ",", mates12); format = TAB_MATE6; break; + case 'f': format = FASTA; break; + case 'F': { + format = FASTA_CONT; + pair p = parsePair(arg, ','); + fastaContLen = p.first; + fastaContFreq = p.second; + break; + } + case ARG_BWA_SW_LIKE: { + bwaSwLikeC = 5.5f; + bwaSwLikeT = 30; + bwaSwLike = true; + localAlign = true; + // -a INT Score of a match [1] + // -b INT Mismatch penalty [3] + // -q INT Gap open penalty [5] + // -r INT Gap extension penalty. The penalty for a contiguous + // gap of size k is q+k*r. [2] + polstr += ";MA=1;MMP=C3;RDG=5,2;RFG=5,2"; + break; + } + case 'q': format = FASTQ; break; + case 'r': format = RAW; break; + case 'c': format = CMDLINE; break; + case ARG_QSEQ: format = QSEQ; break; + case 'C': { + cerr << "Error: -C specified but Bowtie 2 does not support colorspace input." << endl; + throw 1; + break; + } + case 'I': + gMinInsert = parseInt(0, "-I arg must be positive", arg); + break; + case 'X': + gMaxInsert = parseInt(1, "-X arg must be at least 1", arg); + break; + case ARG_NO_DISCORDANT: gReportDiscordant = false; break; + case ARG_NO_MIXED: gReportMixed = false; break; + case 's': + skipReads = (uint32_t)parseInt(0, "-s arg must be positive", arg); + break; + case ARG_FF: gMate1fw = true; gMate2fw = true; break; + case ARG_RF: gMate1fw = false; gMate2fw = true; break; + case ARG_FR: gMate1fw = true; gMate2fw = false; break; + case ARG_SHMEM: useShmem = true; break; + case ARG_SEED_SUMM: seedSumm = true; break; + case ARG_MM: { +#ifdef BOWTIE_MM + useMm = true; + break; +#else + cerr << "Memory-mapped I/O mode is disabled because bowtie was not compiled with" << endl + << "BOWTIE_MM defined. Memory-mapped I/O is not supported under Windows. If you" << endl + << "would like to use memory-mapped I/O on a platform that supports it, please" << endl + << "refrain from specifying BOWTIE_MM=0 when compiling Bowtie." << endl; + throw 1; +#endif + } + case ARG_MMSWEEP: mmSweep = true; break; + case ARG_HADOOPOUT: hadoopOut = true; break; + case ARG_SOLEXA_QUALS: solexaQuals = true; break; + case ARG_INTEGER_QUALS: integerQuals = true; break; + case ARG_PHRED64: phred64Quals = true; break; + case ARG_PHRED33: solexaQuals = false; phred64Quals = false; break; + case ARG_OVERHANG: gReportOverhangs = true; break; + case ARG_NO_CACHE: msNoCache = true; break; + case ARG_USE_CACHE: msNoCache = false; break; + case ARG_LOCAL_SEED_CACHE_SZ: + seedCacheLocalMB = (uint32_t)parseInt(1, "--local-seed-cache-sz arg must be at least 1", arg); + break; + case ARG_CURRENT_SEED_CACHE_SZ: + seedCacheCurrentMB = (uint32_t)parseInt(1, "--seed-cache-sz arg must be at least 1", arg); + break; + case ARG_REFIDX: noRefNames = true; break; + case ARG_FUZZY: fuzzy = true; break; + case ARG_FULLREF: fullRef = true; break; + case ARG_GAP_BAR: + gGapBarrier = parseInt(1, "--gbar must be no less than 1", arg); + break; + case ARG_SEED: + seed = parseInt(0, "--seed arg must be at least 0", arg); + break; + case ARG_NON_DETERMINISTIC: + arbitraryRandom = true; + break; + case 'u': + qUpto = (uint32_t)parseInt(1, "-u/--qupto arg must be at least 1", arg); + break; + case 'Q': + tokenize(arg, ",", qualities); + integerQuals = true; + break; + case ARG_QUALS1: + tokenize(arg, ",", qualities1); + integerQuals = true; + break; + case ARG_QUALS2: + tokenize(arg, ",", qualities2); + integerQuals = true; + break; + case ARG_CACHE_LIM: + cacheLimit = (uint32_t)parseInt(1, "--cachelim arg must be at least 1", arg); + break; + case ARG_CACHE_SZ: + cacheSize = (uint32_t)parseInt(1, "--cachesz arg must be at least 1", arg); + cacheSize *= (1024 * 1024); // convert from MB to B + break; + case ARG_WRAPPER: wrapper = arg; break; + case 'p': + nthreads = parseInt(1, "-p/--threads arg must be at least 1", arg); + break; + case ARG_FILEPAR: + fileParallel = true; + break; + case '3': gTrim3 = parseInt(0, "-3/--trim3 arg must be at least 0", arg); break; + case '5': gTrim5 = parseInt(0, "-5/--trim5 arg must be at least 0", arg); break; + case 'h': printUsage(cout); throw 0; break; + case ARG_USAGE: printUsage(cout); throw 0; break; + // + // NOTE that unlike in Bowtie 1, -M, -a and -k are mutually + // exclusive here. + // + case 'M': { + msample = true; + mhits = parse(arg); + if(saw_a || saw_k) { + cerr << "Warning: -M, -k and -a are mutually exclusive. " + << "-M will override" << endl; + khits = 1; + } + assert_eq(1, khits); + saw_M = true; + cerr << "Warning: -M is deprecated. Use -D and -R to adjust " << + "effort instead." << endl; + break; + } + case ARG_EXTEND_ITERS: { + maxIters = parse(arg); + break; + } + case ARG_NO_EXTEND: { + doExtend = false; + break; + } + case 'R': { polstr += ";ROUNDS="; polstr += arg; break; } + case 'D': { polstr += ";DPS="; polstr += arg; break; } + case ARG_DP_MATE_STREAK_THRESH: { + maxMateStreak = parse(arg); + break; + } + case ARG_DP_FAIL_STREAK_THRESH: { + maxDpStreak = parse(arg); + break; + } + case ARG_EE_FAIL_STREAK_THRESH: { + maxEeStreak = parse(arg); + break; + } + case ARG_UG_FAIL_STREAK_THRESH: { + maxUgStreak = parse(arg); + break; + } + case ARG_DP_FAIL_THRESH: { + maxDp = parse(arg); + break; + } + case ARG_UG_FAIL_THRESH: { + maxUg = parse(arg); + break; + } + case ARG_SEED_BOOST_THRESH: { + seedBoostThresh = parse(arg); + break; + } + case 'a': { + msample = false; + allHits = true; + mhits = 0; // disable -M + if(saw_M || saw_k) { + cerr << "Warning: -M, -k and -a are mutually exclusive. " + << "-a will override" << endl; + } + saw_a = true; + break; + } + case 'k': { + msample = false; + khits = (uint32_t)parseInt(1, "-k arg must be at least 1", arg); + mhits = 0; // disable -M + if(saw_M || saw_a) { + cerr << "Warning: -M, -k and -a are mutually exclusive. " + << "-k will override" << endl; + } + saw_k = true; + break; + } + case ARG_VERBOSE: gVerbose = 1; break; + case ARG_STARTVERBOSE: startVerbose = true; break; + case ARG_QUIET: gQuiet = true; break; + case ARG_SANITY: sanityCheck = true; break; + case 't': timing = true; break; + case ARG_METRIC_IVAL: { + metricsIval = parseInt(1, "--metrics arg must be at least 1", arg); + break; + } + case ARG_METRIC_FILE: metricsFile = arg; break; + case ARG_METRIC_STDERR: metricsStderr = true; break; + case ARG_METRIC_PER_READ: metricsPerRead = true; break; + case ARG_NO_FW: gNofw = true; break; + case ARG_NO_RC: gNorc = true; break; + case ARG_SAM_NO_QNAME_TRUNC: samTruncQname = false; break; + case ARG_SAM_OMIT_SEC_SEQ: samOmitSecSeqQual = true; break; + case ARG_SAM_NO_UNAL: samNoUnal = true; break; + case ARG_SAM_NOHEAD: samNoHead = true; break; + case ARG_SAM_NOSQ: samNoSQ = true; break; + case ARG_SAM_PRINT_YI: sam_print_yi = true; break; + case ARG_REORDER: reorder = true; break; + case ARG_MAPQ_EX: { + sam_print_zp = true; + sam_print_zu = true; + sam_print_xp = true; + sam_print_xss = true; + sam_print_yn = true; + break; + } + case ARG_SHOW_RAND_SEED: { + sam_print_zs = true; + break; + } + case ARG_SAMPLE: + sampleFrac = parse(arg); + break; + case ARG_CP_MIN: + cminlen = parse(arg); + break; + case ARG_CP_IVAL: + cpow2 = parse(arg); + break; + case ARG_TRI: + doTri = true; + break; + case ARG_READ_PASSTHRU: { + sam_print_xr = true; + break; + } + case ARG_READ_TIMES: { + sam_print_xt = true; + sam_print_xd = true; + sam_print_xu = true; + sam_print_yl = true; + sam_print_ye = true; + sam_print_yu = true; + sam_print_yr = true; + sam_print_zb = true; + sam_print_zr = true; + sam_print_zf = true; + sam_print_zm = true; + sam_print_zi = true; + break; + } + case ARG_SAM_RG: { + string argstr = arg; + if(argstr.substr(0, 3) == "ID:") { + rgid = "\t"; + rgid += argstr; + rgs_optflag = "RG:Z:" + argstr.substr(3); + } else { + rgs += '\t'; + rgs += argstr; + } + break; + } + case ARG_SAM_RGID: { + string argstr = arg; + rgid = "\t"; + rgid = "\tID:" + argstr; + rgs_optflag = "RG:Z:" + argstr; + break; + } + case ARG_PARTITION: partitionSz = parse(arg); break; + case ARG_DPAD: + maxhalf = parseInt(0, "--dpad must be no less than 0", arg); + break; + case ARG_ORIG: + if(arg == NULL || strlen(arg) == 0) { + cerr << "--orig arg must be followed by a string" << endl; + printUsage(cerr); + throw 1; + } + origString = arg; + break; + case ARG_LOCAL: localAlign = true; break; + case ARG_END_TO_END: localAlign = false; break; + case ARG_SSE8: enable8 = true; break; + case ARG_SSE8_NO: enable8 = false; break; + case ARG_UNGAPPED: doUngapped = true; break; + case ARG_UNGAPPED_NO: doUngapped = false; break; + case ARG_NO_DOVETAIL: gDovetailMatesOK = false; break; + case ARG_NO_CONTAIN: gContainMatesOK = false; break; + case ARG_NO_OVERLAP: gOlapMatesOK = false; break; + case ARG_DOVETAIL: gDovetailMatesOK = true; break; + case ARG_CONTAIN: gContainMatesOK = true; break; + case ARG_OVERLAP: gOlapMatesOK = true; break; + case ARG_QC_FILTER: qcFilter = true; break; + case ARG_NO_SCORE_PRIORITY: sortByScore = false; break; + case ARG_IGNORE_QUALS: ignoreQuals = true; break; + case ARG_MAPQ_V: mapqv = parse(arg); break; + case ARG_TIGHTEN: tighten = parse(arg); break; + case ARG_EXACT_UPFRONT: doExactUpFront = true; break; + case ARG_1MM_UPFRONT: do1mmUpFront = true; break; + case ARG_EXACT_UPFRONT_NO: doExactUpFront = false; break; + case ARG_1MM_UPFRONT_NO: do1mmUpFront = false; break; + case ARG_1MM_MINLEN: do1mmMinLen = parse(arg); break; + case ARG_NOISY_HPOLY: noisyHpolymer = true; break; + case 'x': bt2index = arg; break; + case ARG_PRESET_VERY_FAST_LOCAL: localAlign = true; + case ARG_PRESET_VERY_FAST: { + presetList.push_back("very-fast%LOCAL%"); break; + } + case ARG_PRESET_FAST_LOCAL: localAlign = true; + case ARG_PRESET_FAST: { + presetList.push_back("fast%LOCAL%"); break; + } + case ARG_PRESET_SENSITIVE_LOCAL: localAlign = true; + case ARG_PRESET_SENSITIVE: { + presetList.push_back("sensitive%LOCAL%"); break; + } + case ARG_PRESET_VERY_SENSITIVE_LOCAL: localAlign = true; + case ARG_PRESET_VERY_SENSITIVE: { + presetList.push_back("very-sensitive%LOCAL%"); break; + } + case 'P': { presetList.push_back(arg); break; } + case ARG_ALIGN_POLICY: { + if(strlen(arg) > 0) { + polstr += ";"; polstr += arg; + } + break; + } + case 'N': { polstr += ";SEED="; polstr += arg; break; } + case 'L': { + int64_t len = parse(arg); + if(len < 0) { + cerr << "Error: -L argument must be >= 0; was " << arg << endl; + throw 1; + } + if(len > 32) { + cerr << "Error: -L argument must be <= 32; was" << arg << endl; + throw 1; + } + polstr += ";SEEDLEN="; polstr += arg; break; + } + case 'O': + multiseedOff = parse(arg); + break; + case 'i': { + EList args; + tokenize(arg, ",", args); + if(args.size() > 3 || args.size() == 0) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to -i option, got " + << args.size() << endl; + throw 1; + } + // Interval-settings arguments + polstr += (";IVAL=" + args[0]); // Function type + if(args.size() > 1) { + polstr += ("," + args[1]); // Constant term + } + if(args.size() > 2) { + polstr += ("," + args[2]); // Coefficient + } + break; + } + case ARG_MULTISEED_IVAL: { + polstr += ";"; + // Split argument by comma + EList args; + tokenize(arg, ",", args); + if(args.size() > 5 || args.size() == 0) { + cerr << "Error: expected 5 or fewer comma-separated " + << "arguments to --multiseed option, got " + << args.size() << endl; + throw 1; + } + // Seed mm and length arguments + polstr += "SEED="; + polstr += (args[0]); // # mismatches + if(args.size() > 1) polstr += ("," + args[ 1]); // length + if(args.size() > 2) polstr += (";IVAL=" + args[2]); // Func type + if(args.size() > 3) polstr += ("," + args[ 3]); // Constant term + if(args.size() > 4) polstr += ("," + args[ 4]); // Coefficient + break; + } + case ARG_N_CEIL: { + // Split argument by comma + EList args; + tokenize(arg, ",", args); + if(args.size() > 3) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to --n-ceil option, got " + << args.size() << endl; + throw 1; + } + if(args.size() == 0) { + cerr << "Error: expected at least one argument to --n-ceil option" << endl; + throw 1; + } + polstr += ";NCEIL="; + if(args.size() == 3) { + polstr += (args[0] + "," + args[1] + "," + args[2]); + } else { + if(args.size() == 1) { + polstr += ("C," + args[0]); + } else { + polstr += (args[0] + "," + args[1]); + } + } + break; + } + case ARG_SCORE_MA: polstr += ";MA="; polstr += arg; break; + case ARG_SCORE_MMP: { + EList args; + tokenize(arg, ",", args); + if(args.size() > 2 || args.size() == 0) { + cerr << "Error: expected 1 or 2 comma-separated " + << "arguments to --mmp option, got " << args.size() << endl; + throw 1; + } + if(args.size() >= 1) { + polstr += ";MMP=Q,"; + polstr += args[0]; + if(args.size() >= 2) { + polstr += ","; + polstr += args[1]; + } + } + break; + } + case ARG_SCORE_NP: polstr += ";NP=C"; polstr += arg; break; + case ARG_SCORE_RDG: polstr += ";RDG="; polstr += arg; break; + case ARG_SCORE_RFG: polstr += ";RFG="; polstr += arg; break; + case ARG_SCORE_MIN: { + polstr += ";"; + EList args; + tokenize(arg, ",", args); + if(args.size() > 3 && args.size() == 0) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to --n-ceil option, got " + << args.size() << endl; + throw 1; + } + polstr += ("MIN=" + args[0]); + if(args.size() > 1) { + polstr += ("," + args[1]); + } + if(args.size() > 2) { + polstr += ("," + args[2]); + } + break; + } + case ARG_DESC: printArgDesc(cout); throw 0; + case 'S': outfile = arg; break; + case 'U': { + EList args; + tokenize(arg, ",", args); + for(size_t i = 0; i < args.size(); i++) { + queries.push_back(args[i]); + } + break; + } + case ARG_VERSION: showVersion = 1; break; + case ARG_NO_TEMPSPLICESITE: useTempSpliceSite = false; break; + case ARG_PEN_CANSPLICE: { + penCanSplice = parseInt(0, "-k arg must be at least 0", arg); + break; + } + case ARG_PEN_NONCANSPLICE: { + penNoncanSplice = parseInt(0, "-k arg must be at least 0", arg); + break; + } + case ARG_PEN_INTRONLEN: { + polstr += ";"; + EList args; + tokenize(arg, ",", args); + if(args.size() > 3 && args.size() == 0) { + cerr << "Error: expected 3 or fewer comma-separated " + << "arguments to --n-ceil option, got " + << args.size() << endl; + throw 1; + } + polstr += ("INTRONLEN=" + args[0]); + if(args.size() > 1) { + polstr += ("," + args[1]); + } + if(args.size() > 2) { + polstr += ("," + args[2]); + } + break; + } + case ARG_KNOWN_SPLICESITE_INFILE: knownSpliceSiteInfile = arg; break; + case ARG_NOVEL_SPLICESITE_INFILE: novelSpliceSiteInfile = arg; break; + case ARG_NOVEL_SPLICESITE_OUTFILE: novelSpliceSiteOutfile = arg; break; + case ARG_NO_SPLICED_ALIGNMENT: no_spliced_alignment = true; break; + case ARG_RNA_STRANDNESS: { + string strandness = arg; + if(strandness == "F") rna_strandness = RNA_STRANDNESS_F; + else if(strandness == "R") rna_strandness = RNA_STRANDNESS_R; + else if(strandness == "FR") rna_strandness = RNA_STRANDNESS_FR; + else if(strandness == "RF") rna_strandness = RNA_STRANDNESS_RF; + else { + // daehwan - throw exception with details + cerr << "Error: should be one of F, R, FR, or RF " << endl; + throw 1; + } + break; + } + default: + printUsage(cerr); + throw 1; + } +} + +/** + * Read command-line arguments + */ +static void parseOptions(int argc, const char **argv) { + int option_index = 0; + int next_option; + saw_M = false; + saw_a = false; + saw_k = true; + presetList.clear(); + if(startVerbose) { cerr << "Parsing options: "; logTime(cerr, true); } + while(true) { + next_option = getopt_long( + argc, const_cast(argv), + short_options, long_options, &option_index); + const char * arg = optarg; + if(next_option == EOF) { + if(extra_opts_cur < extra_opts.size()) { + next_option = extra_opts[extra_opts_cur].first; + arg = extra_opts[extra_opts_cur].second.c_str(); + extra_opts_cur++; + } else { + break; + } + } + parseOption(next_option, arg); + } + // Now parse all the presets. Might want to pick which presets version to + // use according to other parameters. + auto_ptr presets(new PresetsV0()); + // Apply default preset + if(!defaultPreset.empty()) { + polstr = applyPreset(defaultPreset, *presets.get()) + polstr; + } + // Apply specified presets + for(size_t i = 0; i < presetList.size(); i++) { + polstr += applyPreset(presetList[i], *presets.get()); + } + for(size_t i = 0; i < extra_opts.size(); i++) { + next_option = extra_opts[extra_opts_cur].first; + const char *arg = extra_opts[extra_opts_cur].second.c_str(); + parseOption(next_option, arg); + } + // Remove initial semicolons + while(!polstr.empty() && polstr[0] == ';') { + polstr = polstr.substr(1); + } + if(gVerbose) { + cerr << "Final policy string: '" << polstr.c_str() << "'" << endl; + } + size_t failStreakTmp = 0; + SeedAlignmentPolicy::parseString( + polstr, + localAlign, + noisyHpolymer, + ignoreQuals, + bonusMatchType, + bonusMatch, + penMmcType, + penMmcMax, + penMmcMin, + penNType, + penN, + penRdGapConst, + penRfGapConst, + penRdGapLinear, + penRfGapLinear, + scoreMin, + nCeil, + penNCatPair, + multiseedMms, + multiseedLen, + msIval, + failStreakTmp, + nSeedRounds, + &penIntronLen); + if(failStreakTmp > 0) { + maxEeStreak = failStreakTmp; + maxUgStreak = failStreakTmp; + maxDpStreak = failStreakTmp; + } + if(saw_a || saw_k) { + msample = false; + mhits = 0; + } else { + assert_gt(mhits, 0); + msample = true; + } + if(mates1.size() != mates2.size()) { + cerr << "Error: " << mates1.size() << " mate files/sequences were specified with -1, but " << mates2.size() << endl + << "mate files/sequences were specified with -2. The same number of mate files/" << endl + << "sequences must be specified with -1 and -2." << endl; + throw 1; + } + if(qualities.size() && format != FASTA) { + cerr << "Error: one or more quality files were specified with -Q but -f was not" << endl + << "enabled. -Q works only in combination with -f and -C." << endl; + throw 1; + } + if(qualities1.size() && format != FASTA) { + cerr << "Error: one or more quality files were specified with --Q1 but -f was not" << endl + << "enabled. --Q1 works only in combination with -f and -C." << endl; + throw 1; + } + if(qualities2.size() && format != FASTA) { + cerr << "Error: one or more quality files were specified with --Q2 but -f was not" << endl + << "enabled. --Q2 works only in combination with -f and -C." << endl; + throw 1; + } + if(qualities1.size() > 0 && mates1.size() != qualities1.size()) { + cerr << "Error: " << mates1.size() << " mate files/sequences were specified with -1, but " << qualities1.size() << endl + << "quality files were specified with --Q1. The same number of mate and quality" << endl + << "files must sequences must be specified with -1 and --Q1." << endl; + throw 1; + } + if(qualities2.size() > 0 && mates2.size() != qualities2.size()) { + cerr << "Error: " << mates2.size() << " mate files/sequences were specified with -2, but " << qualities2.size() << endl + << "quality files were specified with --Q2. The same number of mate and quality" << endl + << "files must sequences must be specified with -2 and --Q2." << endl; + throw 1; + } + if(!rgs.empty() && rgid.empty()) { + cerr << "Warning: --rg was specified without --rg-id also " + << "being specified. @RG line is not printed unless --rg-id " + << "is specified." << endl; + } + // Check for duplicate mate input files + if(format != CMDLINE) { + for(size_t i = 0; i < mates1.size(); i++) { + for(size_t j = 0; j < mates2.size(); j++) { + if(mates1[i] == mates2[j] && !gQuiet) { + cerr << "Warning: Same mate file \"" << mates1[i].c_str() << "\" appears as argument to both -1 and -2" << endl; + } + } + } + } + // If both -s and -u are used, we need to adjust qUpto accordingly + // since it uses rdid to know if we've reached the -u limit (and + // rdids are all shifted up by skipReads characters) + if(qUpto + skipReads > qUpto) { + qUpto += skipReads; + } + if(useShmem && useMm && !gQuiet) { + cerr << "Warning: --shmem overrides --mm..." << endl; + useMm = false; + } + if(gGapBarrier < 1) { + cerr << "Warning: --gbar was set less than 1 (=" << gGapBarrier + << "); setting to 1 instead" << endl; + gGapBarrier = 1; + } + if(multiseedMms >= multiseedLen) { + assert_gt(multiseedLen, 0); + cerr << "Warning: seed mismatches (" << multiseedMms + << ") is less than seed length (" << multiseedLen + << "); setting mismatches to " << (multiseedMms-1) + << " instead" << endl; + multiseedMms = multiseedLen-1; + } + sam_print_zm = sam_print_zm && bowtie2p5; +#ifndef NDEBUG + if(!gQuiet) { + cerr << "Warning: Running in debug mode. Please use debug mode only " + << "for diagnosing errors, and not for typical use of HISAT." + << endl; + } +#endif +} + +static const char *argv0 = NULL; + +/// Create a PatternSourcePerThread for the current thread according +/// to the global params and return a pointer to it +static PatternSourcePerThreadFactory* +createPatsrcFactory(PairedPatternSource& _patsrc, int tid) { + PatternSourcePerThreadFactory *patsrcFact; + patsrcFact = new WrappedPatternSourcePerThreadFactory(_patsrc); + assert(patsrcFact != NULL); + return patsrcFact; +} + +#define PTHREAD_ATTRS (PTHREAD_CREATE_JOINABLE | PTHREAD_CREATE_DETACHED) + +typedef TIndexOffU index_t; +typedef uint16_t local_index_t; +static PairedPatternSource* multiseed_patsrc; +static HierEbwt* multiseed_ebwtFw; +static HierEbwt* multiseed_ebwtBw; +static Scoring* multiseed_sc; +static BitPairReference* multiseed_refs; +static AlignmentCache* multiseed_ca; // seed cache +static AlnSink* multiseed_msink; +static EList multiseed_refnames; +static OutFileBuf* multiseed_metricsOfb; +static SpliceSiteDB* ssdb; +static MUTEX_T multiseed_mutex; + +/** + * Metrics for measuring the work done by the outer read alignment + * loop. + */ +struct OuterLoopMetrics { + + OuterLoopMetrics() { + reset(); + } + + /** + * Set all counters to 0. + */ + void reset() { + reads = bases = srreads = srbases = + freads = fbases = ureads = ubases = 0; + } + + /** + * Sum the counters in m in with the conters in this object. This + * is the only safe way to update an OuterLoopMetrics that's shared + * by multiple threads. + */ + void merge( + const OuterLoopMetrics& m, + bool getLock = false) + { + ThreadSafe ts(&mutex_m, getLock); + reads += m.reads; + bases += m.bases; + srreads += m.srreads; + srbases += m.srbases; + freads += m.freads; + fbases += m.fbases; + ureads += m.ureads; + ubases += m.ubases; + } + + uint64_t reads; // total reads + uint64_t bases; // total bases + uint64_t srreads; // same-read reads + uint64_t srbases; // same-read bases + uint64_t freads; // filtered reads + uint64_t fbases; // filtered bases + uint64_t ureads; // unfiltered reads + uint64_t ubases; // unfiltered bases + MUTEX_T mutex_m; +}; + +/** + * Collection of all relevant performance metrics when aligning in + * multiseed mode. + */ +struct PerfMetrics { + + PerfMetrics() : first(true) { reset(); } + + /** + * Set all counters to 0. + */ + void reset() { + olm.reset(); + sdm.reset(); + wlm.reset(); + swmSeed.reset(); + swmMate.reset(); + rpm.reset(); + dpSse8Seed.reset(); // 8-bit SSE seed extensions + dpSse8Mate.reset(); // 8-bit SSE mate finds + dpSse16Seed.reset(); // 16-bit SSE seed extensions + dpSse16Mate.reset(); // 16-bit SSE mate finds + nbtfiltst = 0; + nbtfiltsc = 0; + nbtfiltdo = 0; + + olmu.reset(); + sdmu.reset(); + wlmu.reset(); + swmuSeed.reset(); + swmuMate.reset(); + rpmu.reset(); + dpSse8uSeed.reset(); // 8-bit SSE seed extensions + dpSse8uMate.reset(); // 8-bit SSE mate finds + dpSse16uSeed.reset(); // 16-bit SSE seed extensions + dpSse16uMate.reset(); // 16-bit SSE mate finds + nbtfiltst_u = 0; + nbtfiltsc_u = 0; + nbtfiltdo_u = 0; + + him.reset(); + } + + /** + * Merge a set of specific metrics into this object. + */ + void merge( + const OuterLoopMetrics *ol, + const SeedSearchMetrics *sd, + const WalkMetrics *wl, + const SwMetrics *swSeed, + const SwMetrics *swMate, + const ReportingMetrics *rm, + const SSEMetrics *dpSse8Ex, + const SSEMetrics *dpSse8Ma, + const SSEMetrics *dpSse16Ex, + const SSEMetrics *dpSse16Ma, + uint64_t nbtfiltst_, + uint64_t nbtfiltsc_, + uint64_t nbtfiltdo_, + const HIMetrics *hi, + bool getLock) + { + ThreadSafe ts(&mutex_m, getLock); + if(ol != NULL) { + olmu.merge(*ol, false); + } + if(sd != NULL) { + sdmu.merge(*sd, false); + } + if(wl != NULL) { + wlmu.merge(*wl, false); + } + if(swSeed != NULL) { + swmuSeed.merge(*swSeed, false); + } + if(swMate != NULL) { + swmuMate.merge(*swMate, false); + } + if(rm != NULL) { + rpmu.merge(*rm, false); + } + if(dpSse8Ex != NULL) { + dpSse8uSeed.merge(*dpSse8Ex, false); + } + if(dpSse8Ma != NULL) { + dpSse8uMate.merge(*dpSse8Ma, false); + } + if(dpSse16Ex != NULL) { + dpSse16uSeed.merge(*dpSse16Ex, false); + } + if(dpSse16Ma != NULL) { + dpSse16uMate.merge(*dpSse16Ma, false); + } + nbtfiltst_u += nbtfiltst_; + nbtfiltsc_u += nbtfiltsc_; + nbtfiltdo_u += nbtfiltdo_; + if(hi != NULL) { + him.merge(*hi, false); + } + } + + /** + * Reports a matrix of results, incl. column labels, to an OutFileBuf. + * Optionally also sends results to stderr (unbuffered). Can optionally + * print a per-read record with the read name at the beginning. + */ + void reportInterval( + OutFileBuf* o, // file to send output to + bool metricsStderr, // additionally output to stderr? + bool total, // true -> report total, otherwise incremental + bool sync, // synchronize output + const BTString *name) // non-NULL name pointer if is per-read record + { + ThreadSafe ts(&mutex_m, sync); + ostringstream stderrSs; + time_t curtime = time(0); + char buf[1024]; + if(first) { + const char *str = + /* 1 */ "Time" "\t" + /* 2 */ "Read" "\t" + /* 3 */ "Base" "\t" + /* 4 */ "SameRead" "\t" + /* 5 */ "SameReadBase" "\t" + /* 6 */ "UnfilteredRead" "\t" + /* 7 */ "UnfilteredBase" "\t" + + /* 8 */ "Paired" "\t" + /* 9 */ "Unpaired" "\t" + /* 10 */ "AlConUni" "\t" + /* 11 */ "AlConRep" "\t" + /* 12 */ "AlConFail" "\t" + /* 13 */ "AlDis" "\t" + /* 14 */ "AlConFailUni" "\t" + /* 15 */ "AlConFailRep" "\t" + /* 16 */ "AlConFailFail" "\t" + /* 17 */ "AlConRepUni" "\t" + /* 18 */ "AlConRepRep" "\t" + /* 19 */ "AlConRepFail" "\t" + /* 20 */ "AlUnpUni" "\t" + /* 21 */ "AlUnpRep" "\t" + /* 22 */ "AlUnpFail" "\t" + + /* 23 */ "SeedSearch" "\t" + /* 24 */ "IntraSCacheHit" "\t" + /* 25 */ "InterSCacheHit" "\t" + /* 26 */ "OutOfMemory" "\t" + /* 27 */ "AlBWOp" "\t" + /* 28 */ "AlBWBranch" "\t" + /* 29 */ "ResBWOp" "\t" + /* 30 */ "ResBWBranch" "\t" + /* 31 */ "ResResolve" "\t" + /* 34 */ "ResReport" "\t" + /* 35 */ "RedundantSHit" "\t" + + /* 36 */ "BestMinEdit0" "\t" + /* 37 */ "BestMinEdit1" "\t" + /* 38 */ "BestMinEdit2" "\t" + + /* 39 */ "ExactAttempts" "\t" + /* 40 */ "ExactSucc" "\t" + /* 41 */ "ExactRanges" "\t" + /* 42 */ "ExactRows" "\t" + /* 43 */ "ExactOOMs" "\t" + + /* 44 */ "1mmAttempts" "\t" + /* 45 */ "1mmSucc" "\t" + /* 46 */ "1mmRanges" "\t" + /* 47 */ "1mmRows" "\t" + /* 48 */ "1mmOOMs" "\t" + + /* 49 */ "UngappedSucc" "\t" + /* 50 */ "UngappedFail" "\t" + /* 51 */ "UngappedNoDec" "\t" + + /* 52 */ "DPExLt10Gaps" "\t" + /* 53 */ "DPExLt5Gaps" "\t" + /* 54 */ "DPExLt3Gaps" "\t" + + /* 55 */ "DPMateLt10Gaps" "\t" + /* 56 */ "DPMateLt5Gaps" "\t" + /* 57 */ "DPMateLt3Gaps" "\t" + + /* 58 */ "DP16ExDps" "\t" + /* 59 */ "DP16ExDpSat" "\t" + /* 60 */ "DP16ExDpFail" "\t" + /* 61 */ "DP16ExDpSucc" "\t" + /* 62 */ "DP16ExCol" "\t" + /* 63 */ "DP16ExCell" "\t" + /* 64 */ "DP16ExInner" "\t" + /* 65 */ "DP16ExFixup" "\t" + /* 66 */ "DP16ExGathSol" "\t" + /* 67 */ "DP16ExBt" "\t" + /* 68 */ "DP16ExBtFail" "\t" + /* 69 */ "DP16ExBtSucc" "\t" + /* 70 */ "DP16ExBtCell" "\t" + /* 71 */ "DP16ExCoreRej" "\t" + /* 72 */ "DP16ExNRej" "\t" + + /* 73 */ "DP8ExDps" "\t" + /* 74 */ "DP8ExDpSat" "\t" + /* 75 */ "DP8ExDpFail" "\t" + /* 76 */ "DP8ExDpSucc" "\t" + /* 77 */ "DP8ExCol" "\t" + /* 78 */ "DP8ExCell" "\t" + /* 79 */ "DP8ExInner" "\t" + /* 80 */ "DP8ExFixup" "\t" + /* 81 */ "DP8ExGathSol" "\t" + /* 82 */ "DP8ExBt" "\t" + /* 83 */ "DP8ExBtFail" "\t" + /* 84 */ "DP8ExBtSucc" "\t" + /* 85 */ "DP8ExBtCell" "\t" + /* 86 */ "DP8ExCoreRej" "\t" + /* 87 */ "DP8ExNRej" "\t" + + /* 88 */ "DP16MateDps" "\t" + /* 89 */ "DP16MateDpSat" "\t" + /* 90 */ "DP16MateDpFail" "\t" + /* 91 */ "DP16MateDpSucc" "\t" + /* 92 */ "DP16MateCol" "\t" + /* 93 */ "DP16MateCell" "\t" + /* 94 */ "DP16MateInner" "\t" + /* 95 */ "DP16MateFixup" "\t" + /* 96 */ "DP16MateGathSol" "\t" + /* 97 */ "DP16MateBt" "\t" + /* 98 */ "DP16MateBtFail" "\t" + /* 99 */ "DP16MateBtSucc" "\t" + /* 100 */ "DP16MateBtCell" "\t" + /* 101 */ "DP16MateCoreRej" "\t" + /* 102 */ "DP16MateNRej" "\t" + + /* 103 */ "DP8MateDps" "\t" + /* 104 */ "DP8MateDpSat" "\t" + /* 105 */ "DP8MateDpFail" "\t" + /* 106 */ "DP8MateDpSucc" "\t" + /* 107 */ "DP8MateCol" "\t" + /* 108 */ "DP8MateCell" "\t" + /* 109 */ "DP8MateInner" "\t" + /* 110 */ "DP8MateFixup" "\t" + /* 111 */ "DP8MateGathSol" "\t" + /* 112 */ "DP8MateBt" "\t" + /* 113 */ "DP8MateBtFail" "\t" + /* 114 */ "DP8MateBtSucc" "\t" + /* 115 */ "DP8MateBtCell" "\t" + /* 116 */ "DP8MateCoreRej" "\t" + /* 117 */ "DP8MateNRej" "\t" + + /* 118 */ "DPBtFiltStart" "\t" + /* 119 */ "DPBtFiltScore" "\t" + /* 120 */ "DpBtFiltDom" "\t" + + /* 121 */ "MemPeak" "\t" + /* 122 */ "UncatMemPeak" "\t" // 0 + /* 123 */ "EbwtMemPeak" "\t" // EBWT_CAT + /* 124 */ "CacheMemPeak" "\t" // CA_CAT + /* 125 */ "ResolveMemPeak" "\t" // GW_CAT + /* 126 */ "AlignMemPeak" "\t" // AL_CAT + /* 127 */ "DPMemPeak" "\t" // DP_CAT + /* 128 */ "MiscMemPeak" "\t" // MISC_CAT + /* 129 */ "DebugMemPeak" "\t" // DEBUG_CAT + + /* 130 */ "LocalSearch" "\t" + /* 131 */ "AnchorSearch" "\t" + /* 132 */ "LocalIndexSearch" "\t" + /* 133 */ "LocalExtSearch" "\t" + /* 134 */ "LocalSearchRecur" "\t" + /* 135 */ "GlobalGenomeCoords" "\t" + /* 136 */ "LocalGenomeCoords" "\t" + + + "\n"; + + if(name != NULL) { + if(o != NULL) o->writeChars("Name\t"); + if(metricsStderr) stderrSs << "Name\t"; + } + + if(o != NULL) o->writeChars(str); + if(metricsStderr) stderrSs << str; + first = false; + } + + if(total) mergeIncrementals(); + + // 0. Read name, if needed + if(name != NULL) { + if(o != NULL) { + o->writeChars(name->toZBuf()); + o->write('\t'); + } + if(metricsStderr) { + stderrSs << (*name) << '\t'; + } + } + + // 1. Current time in secs + itoa10(curtime, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const OuterLoopMetrics& ol = total ? olm : olmu; + + // 2. Reads + itoa10(ol.reads, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 3. Bases + itoa10(ol.bases, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 4. Same-read reads + itoa10(ol.srreads, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 5. Same-read bases + itoa10(ol.srbases, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 6. Unfiltered reads + itoa10(ol.ureads, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 7. Unfiltered bases + itoa10(ol.ubases, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const ReportingMetrics& rp = total ? rpm : rpmu; + + // 8. Paired reads + itoa10(rp.npaired, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 9. Unpaired reads + itoa10(rp.nunpaired, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 10. Pairs with unique concordant alignments + itoa10(rp.nconcord_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 11. Pairs with repetitive concordant alignments + itoa10(rp.nconcord_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 12. Pairs with 0 concordant alignments + itoa10(rp.nconcord_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 13. Pairs with 1 discordant alignment + itoa10(rp.ndiscord, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 14. Mates from unaligned pairs that align uniquely + itoa10(rp.nunp_0_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 15. Mates from unaligned pairs that align repetitively + itoa10(rp.nunp_0_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 16. Mates from unaligned pairs that fail to align + itoa10(rp.nunp_0_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 17. Mates from repetitive pairs that align uniquely + itoa10(rp.nunp_rep_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 18. Mates from repetitive pairs that align repetitively + itoa10(rp.nunp_rep_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 19. Mates from repetitive pairs that fail to align + itoa10(rp.nunp_rep_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 20. Unpaired reads that align uniquely + itoa10(rp.nunp_uni, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 21. Unpaired reads that align repetitively + itoa10(rp.nunp_rep, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 22. Unpaired reads that fail to align + itoa10(rp.nunp_0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SeedSearchMetrics& sd = total ? sdm : sdmu; + + // 23. Seed searches + itoa10(sd.seedsearch, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 24. Hits in 'current' cache + itoa10(sd.intrahit, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 25. Hits in 'local' cache + itoa10(sd.interhit, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 26. Out of memory + itoa10(sd.ooms, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 27. Burrows-Wheeler ops in aligner + itoa10(sd.bwops, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 28. Burrows-Wheeler branches (edits) in aligner + itoa10(sd.bweds, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const WalkMetrics& wl = total ? wlm : wlmu; + + // 29. Burrows-Wheeler ops in resolver + itoa10(wl.bwops, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 30. Burrows-Wheeler branches in resolver + itoa10(wl.branches, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 31. Burrows-Wheeler offset resolutions + itoa10(wl.resolves, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 34. Offset reports + itoa10(wl.reports, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 35. Redundant seed hit + itoa10(total ? swmSeed.rshit : swmuSeed.rshit, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 36. # times the best (out of fw/rc) minimum # edits was 0 + itoa10(total ? sdm.bestmin0 : sdmu.bestmin0, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 37. # times the best (out of fw/rc) minimum # edits was 1 + itoa10(total ? sdm.bestmin1 : sdmu.bestmin1, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 38. # times the best (out of fw/rc) minimum # edits was 2 + itoa10(total ? sdm.bestmin2 : sdmu.bestmin2, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 39. Exact aligner attempts + itoa10(total ? swmSeed.exatts : swmuSeed.exatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 40. Exact aligner successes + itoa10(total ? swmSeed.exsucc : swmuSeed.exsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 41. Exact aligner ranges + itoa10(total ? swmSeed.exranges : swmuSeed.exranges, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 42. Exact aligner rows + itoa10(total ? swmSeed.exrows : swmuSeed.exrows, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 43. Exact aligner OOMs + itoa10(total ? swmSeed.exooms : swmuSeed.exooms, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 44. 1mm aligner attempts + itoa10(total ? swmSeed.mm1atts : swmuSeed.mm1atts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 45. 1mm aligner successes + itoa10(total ? swmSeed.mm1succ : swmuSeed.mm1succ, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 46. 1mm aligner ranges + itoa10(total ? swmSeed.mm1ranges : swmuSeed.mm1ranges, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 47. 1mm aligner rows + itoa10(total ? swmSeed.mm1rows : swmuSeed.mm1rows, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 48. 1mm aligner OOMs + itoa10(total ? swmSeed.mm1ooms : swmuSeed.mm1ooms, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 49 Ungapped aligner success + itoa10(total ? swmSeed.ungapsucc : swmuSeed.ungapsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 50. Ungapped aligner fail + itoa10(total ? swmSeed.ungapfail : swmuSeed.ungapfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 51. Ungapped aligner no decision + itoa10(total ? swmSeed.ungapnodec : swmuSeed.ungapnodec, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 52. # seed-extend DPs with < 10 gaps + itoa10(total ? swmSeed.sws10 : swmuSeed.sws10, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 53. # seed-extend DPs with < 5 gaps + itoa10(total ? swmSeed.sws5 : swmuSeed.sws5, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 54. # seed-extend DPs with < 3 gaps + itoa10(total ? swmSeed.sws3 : swmuSeed.sws3, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 55. # seed-extend DPs with < 10 gaps + itoa10(total ? swmMate.sws10 : swmuMate.sws10, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 56. # seed-extend DPs with < 5 gaps + itoa10(total ? swmMate.sws5 : swmuMate.sws5, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 57. # seed-extend DPs with < 3 gaps + itoa10(total ? swmMate.sws3 : swmuMate.sws3, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse16s = total ? dpSse16Seed : dpSse16uSeed; + + // 58. 16-bit SSE seed-extend DPs tried + itoa10(dpSse16s.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 59. 16-bit SSE seed-extend DPs saturated + itoa10(dpSse16s.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 60. 16-bit SSE seed-extend DPs failed + itoa10(dpSse16s.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 61. 16-bit SSE seed-extend DPs succeeded + itoa10(dpSse16s.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 62. 16-bit SSE seed-extend DP columns completed + itoa10(dpSse16s.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 63. 16-bit SSE seed-extend DP cells completed + itoa10(dpSse16s.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 64. 16-bit SSE seed-extend DP inner loop iters completed + itoa10(dpSse16s.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 65. 16-bit SSE seed-extend DP fixup loop iters completed + itoa10(dpSse16s.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 66. 16-bit SSE seed-extend DP gather, cells with potential solutions + itoa10(dpSse16s.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 67. 16-bit SSE seed-extend DP backtrace attempts + itoa10(dpSse16s.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 68. 16-bit SSE seed-extend DP failed backtrace attempts + itoa10(dpSse16s.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 69. 16-bit SSE seed-extend DP succesful backtrace attempts + itoa10(dpSse16s.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 70. 16-bit SSE seed-extend DP backtrace cells + itoa10(dpSse16s.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 71. 16-bit SSE seed-extend DP core-diag rejections + itoa10(dpSse16s.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 72. 16-bit SSE seed-extend DP N rejections + itoa10(dpSse16s.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse8s = total ? dpSse8Seed : dpSse8uSeed; + + // 73. 8-bit SSE seed-extend DPs tried + itoa10(dpSse8s.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 74. 8-bit SSE seed-extend DPs saturated + itoa10(dpSse8s.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 75. 8-bit SSE seed-extend DPs failed + itoa10(dpSse8s.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 76. 8-bit SSE seed-extend DPs succeeded + itoa10(dpSse8s.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 77. 8-bit SSE seed-extend DP columns completed + itoa10(dpSse8s.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 78. 8-bit SSE seed-extend DP cells completed + itoa10(dpSse8s.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 79. 8-bit SSE seed-extend DP inner loop iters completed + itoa10(dpSse8s.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 80. 8-bit SSE seed-extend DP fixup loop iters completed + itoa10(dpSse8s.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 81. 16-bit SSE seed-extend DP gather, cells with potential solutions + itoa10(dpSse8s.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 82. 16-bit SSE seed-extend DP backtrace attempts + itoa10(dpSse8s.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 83. 16-bit SSE seed-extend DP failed backtrace attempts + itoa10(dpSse8s.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 84. 16-bit SSE seed-extend DP succesful backtrace attempts + itoa10(dpSse8s.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 85. 16-bit SSE seed-extend DP backtrace cells + itoa10(dpSse8s.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 86. 16-bit SSE seed-extend DP core-diag rejections + itoa10(dpSse8s.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 87. 16-bit SSE seed-extend DP N rejections + itoa10(dpSse8s.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse16m = total ? dpSse16Mate : dpSse16uMate; + + // 88. 16-bit SSE mate-finding DPs tried + itoa10(dpSse16m.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 89. 16-bit SSE mate-finding DPs saturated + itoa10(dpSse16m.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 90. 16-bit SSE mate-finding DPs failed + itoa10(dpSse16m.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 91. 16-bit SSE mate-finding DPs succeeded + itoa10(dpSse16m.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 92. 16-bit SSE mate-finding DP columns completed + itoa10(dpSse16m.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 93. 16-bit SSE mate-finding DP cells completed + itoa10(dpSse16m.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 94. 16-bit SSE mate-finding DP inner loop iters completed + itoa10(dpSse16m.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 95. 16-bit SSE mate-finding DP fixup loop iters completed + itoa10(dpSse16m.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 96. 16-bit SSE mate-finding DP gather, cells with potential solutions + itoa10(dpSse16m.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 97. 16-bit SSE mate-finding DP backtrace attempts + itoa10(dpSse16m.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 98. 16-bit SSE mate-finding DP failed backtrace attempts + itoa10(dpSse16m.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 99. 16-bit SSE mate-finding DP succesful backtrace attempts + itoa10(dpSse16m.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 100. 16-bit SSE mate-finding DP backtrace cells + itoa10(dpSse16m.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 101. 16-bit SSE mate-finding DP core-diag rejections + itoa10(dpSse16m.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 102. 16-bit SSE mate-finding DP N rejections + itoa10(dpSse16m.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + const SSEMetrics& dpSse8m = total ? dpSse8Mate : dpSse8uMate; + + // 103. 8-bit SSE mate-finding DPs tried + itoa10(dpSse8m.dp, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 104. 8-bit SSE mate-finding DPs saturated + itoa10(dpSse8m.dpsat, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 105. 8-bit SSE mate-finding DPs failed + itoa10(dpSse8m.dpfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 106. 8-bit SSE mate-finding DPs succeeded + itoa10(dpSse8m.dpsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 107. 8-bit SSE mate-finding DP columns completed + itoa10(dpSse8m.col, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 108. 8-bit SSE mate-finding DP cells completed + itoa10(dpSse8m.cell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 109. 8-bit SSE mate-finding DP inner loop iters completed + itoa10(dpSse8m.inner, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 110. 8-bit SSE mate-finding DP fixup loop iters completed + itoa10(dpSse8m.fixup, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 111. 16-bit SSE mate-finding DP gather, cells with potential solutions + itoa10(dpSse8m.gathsol, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 112. 16-bit SSE mate-finding DP backtrace attempts + itoa10(dpSse8m.bt, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 113. 16-bit SSE mate-finding DP failed backtrace attempts + itoa10(dpSse8m.btfail, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 114. 16-bit SSE mate-finding DP succesful backtrace attempts + itoa10(dpSse8m.btsucc, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 115. 16-bit SSE mate-finding DP backtrace cells + itoa10(dpSse8m.btcell, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 116. 16-bit SSE mate-finding DP core rejections + itoa10(dpSse8m.corerej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 117. 16-bit SSE mate-finding N rejections + itoa10(dpSse8m.nrej, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 118. Backtrace candidates filtered due to starting cell + itoa10(total ? nbtfiltst : nbtfiltst_u, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 119. Backtrace candidates filtered due to low score + itoa10(total ? nbtfiltsc : nbtfiltsc_u, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 120. Backtrace candidates filtered due to domination + itoa10(total ? nbtfiltdo : nbtfiltdo_u, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 121. Overall memory peak + itoa10(gMemTally.peak() >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 122. Uncategorized memory peak + itoa10(gMemTally.peak(0) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 123. Ebwt memory peak + itoa10(gMemTally.peak(EBWT_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 124. Cache memory peak + itoa10(gMemTally.peak(CA_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 125. Resolver memory peak + itoa10(gMemTally.peak(GW_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 126. Seed aligner memory peak + itoa10(gMemTally.peak(AL_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 127. Dynamic programming aligner memory peak + itoa10(gMemTally.peak(DP_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 128. Miscellaneous memory peak + itoa10(gMemTally.peak(MISC_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 129. Debug memory peak + itoa10(gMemTally.peak(DEBUG_CAT) >> 20, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + + // 130 + itoa10(him.localatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 131 + itoa10(him.anchoratts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 132 + itoa10(him.localindexatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 133 + itoa10(him.localextatts, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 134 + itoa10(him.localsearchrecur, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 135 + itoa10(him.globalgenomecoords, buf); + if(metricsStderr) stderrSs << buf << '\t'; + if(o != NULL) { o->writeChars(buf); o->write('\t'); } + // 136 + itoa10(him.localgenomecoords, buf); + if(metricsStderr) stderrSs << buf; + if(o != NULL) { o->writeChars(buf); } + + if(o != NULL) { o->write('\n'); } + if(metricsStderr) cerr << stderrSs.str().c_str() << endl; + if(!total) mergeIncrementals(); + } + + void mergeIncrementals() { + olm.merge(olmu, false); + sdm.merge(sdmu, false); + wlm.merge(wlmu, false); + swmSeed.merge(swmuSeed, false); + swmMate.merge(swmuMate, false); + dpSse8Seed.merge(dpSse8uSeed, false); + dpSse8Mate.merge(dpSse8uMate, false); + dpSse16Seed.merge(dpSse16uSeed, false); + dpSse16Mate.merge(dpSse16uMate, false); + nbtfiltst_u += nbtfiltst; + nbtfiltsc_u += nbtfiltsc; + nbtfiltdo_u += nbtfiltdo; + + olmu.reset(); + sdmu.reset(); + wlmu.reset(); + swmuSeed.reset(); + swmuMate.reset(); + rpmu.reset(); + dpSse8uSeed.reset(); + dpSse8uMate.reset(); + dpSse16uSeed.reset(); + dpSse16uMate.reset(); + nbtfiltst_u = 0; + nbtfiltsc_u = 0; + nbtfiltdo_u = 0; + } + + // Total over the whole job + OuterLoopMetrics olm; // overall metrics + SeedSearchMetrics sdm; // metrics related to seed alignment + WalkMetrics wlm; // metrics related to walking left (i.e. resolving reference offsets) + SwMetrics swmSeed; // metrics related to DP seed-extend alignment + SwMetrics swmMate; // metrics related to DP mate-finding alignment + ReportingMetrics rpm; // metrics related to reporting + SSEMetrics dpSse8Seed; // 8-bit SSE seed extensions + SSEMetrics dpSse8Mate; // 8-bit SSE mate finds + SSEMetrics dpSse16Seed; // 16-bit SSE seed extensions + SSEMetrics dpSse16Mate; // 16-bit SSE mate finds + uint64_t nbtfiltst; + uint64_t nbtfiltsc; + uint64_t nbtfiltdo; + + // Just since the last update + OuterLoopMetrics olmu; // overall metrics + SeedSearchMetrics sdmu; // metrics related to seed alignment + WalkMetrics wlmu; // metrics related to walking left (i.e. resolving reference offsets) + SwMetrics swmuSeed; // metrics related to DP seed-extend alignment + SwMetrics swmuMate; // metrics related to DP mate-finding alignment + ReportingMetrics rpmu; // metrics related to reporting + SSEMetrics dpSse8uSeed; // 8-bit SSE seed extensions + SSEMetrics dpSse8uMate; // 8-bit SSE mate finds + SSEMetrics dpSse16uSeed; // 16-bit SSE seed extensions + SSEMetrics dpSse16uMate; // 16-bit SSE mate finds + uint64_t nbtfiltst_u; + uint64_t nbtfiltsc_u; + uint64_t nbtfiltdo_u; + + // + HIMetrics him; + + MUTEX_T mutex_m; // lock for when one ob + bool first; // yet to print first line? + time_t lastElapsed; // used in reportInterval to measure time since last call +}; + +static PerfMetrics metrics; + +// Cyclic rotations +#define ROTL(n, x) (((x) << (n)) | ((x) >> (32-n))) +#define ROTR(n, x) (((x) >> (n)) | ((x) << (32-n))) + +static inline void printMmsSkipMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1, + int seedmms) +{ + ostringstream os; + if(paired) { + os << "Warning: skipping mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because length (" << (mate1 ? ps.bufa().patFw.length() : ps.bufb().patFw.length()) + << ") <= # seed mismatches (" << seedmms << ")" << endl; + } else { + os << "Warning: skipping read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because length (" << (mate1 ? ps.bufa().patFw.length() : ps.bufb().patFw.length()) + << ") <= # seed mismatches (" << seedmms << ")" << endl; + } + cerr << os.str().c_str(); +} + +static inline void printLenSkipMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1) +{ + ostringstream os; + if(paired) { + os << "Warning: skipping mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because it was < 2 characters long" << endl; + } else { + os << "Warning: skipping read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "' because it was < 2 characters long" << endl; + } + cerr << os.str().c_str(); +} + +static inline void printLocalScoreMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1) +{ + ostringstream os; + if(paired) { + os << "Warning: minimum score function gave negative number in " + << "--local mode for mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } else { + os << "Warning: minimum score function gave negative number in " + << "--local mode for read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } + cerr << os.str().c_str(); +} + +static inline void printEEScoreMsg( + const PatternSourcePerThread& ps, + bool paired, + bool mate1) +{ + ostringstream os; + if(paired) { + os << "Warning: minimum score function gave positive number in " + << "--end-to-end mode for mate #" << (mate1 ? '1' : '2') + << " of read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } else { + os << "Warning: minimum score function gave positive number in " + << "--end-to-end mode for read '" << (mate1 ? ps.bufa().name : ps.bufb().name) + << "; setting to 0 instead" << endl; + } + cerr << os.str().c_str(); +} + + +#define MERGE_METRICS(met, sync) { \ + msink.mergeMetrics(rpm); \ + met.merge( \ + &olm, \ + &sdm, \ + &wlm, \ + &swmSeed, \ + &swmMate, \ + &rpm, \ + &sseU8ExtendMet, \ + &sseU8MateMet, \ + &sseI16ExtendMet, \ + &sseI16MateMet, \ + nbtfiltst, \ + nbtfiltsc, \ + nbtfiltdo, \ + &him, \ + sync); \ + olm.reset(); \ + sdm.reset(); \ + wlm.reset(); \ + swmSeed.reset(); \ + swmMate.reset(); \ + rpm.reset(); \ + sseU8ExtendMet.reset(); \ + sseU8MateMet.reset(); \ + sseI16ExtendMet.reset(); \ + sseI16MateMet.reset(); \ + him.reset(); \ +} + +#define MERGE_SW(x) { \ + x.merge( \ + sseU8ExtendMet, \ + sseU8MateMet, \ + sseI16ExtendMet, \ + sseI16MateMet, \ + nbtfiltst, \ + nbtfiltsc, \ + nbtfiltdo); \ + x.resetCounters(); \ +} + +/** + * Called once per thread. Sets up per-thread pointers to the shared global + * data structures, creates per-thread structures, then enters the alignment + * loop. The general flow of the alignment loop is: + * + * - If it's been a while and we're the master thread, report some alignment + * metrics + * - Get the next read/pair + * - Check if this read/pair is identical to the previous + * + If identical, check whether we can skip any or all alignment stages. If + * we can skip all stages, report the result immediately and move to next + * read/pair + * + If not identical, continue + * - + */ +static void multiseedSearchWorker_hisat_bp(void *vp) { + int tid = *((int*)vp); + assert(multiseed_ebwtFw != NULL); + assert(multiseedMms == 0 || multiseed_ebwtBw != NULL); + PairedPatternSource& patsrc = *multiseed_patsrc; + const HierEbwt& ebwtFw = *multiseed_ebwtFw; + const HierEbwt& ebwtBw = *multiseed_ebwtBw; + const Scoring& sc = *multiseed_sc; + const BitPairReference& ref = *multiseed_refs; + AlignmentCache& scShared = *multiseed_ca; + AlnSink& msink = *multiseed_msink; + OutFileBuf* metricsOfb = multiseed_metricsOfb; + + // Sinks: these are so that we can print tables encoding counts for + // events of interest on a per-read, per-seed, per-join, or per-SW + // level. These in turn can be used to diagnose performance + // problems, or generally characterize performance. + + //const BitPairReference& refs = *multiseed_refs; + auto_ptr patsrcFact(createPatsrcFactory(patsrc, tid)); + auto_ptr ps(patsrcFact->create()); + + // Thread-local cache for seed alignments + PtrWrap > scLocal; + if(!msNoCache) { + scLocal.init(new AlignmentCache(seedCacheLocalMB * 1024 * 1024, false)); + } + AlignmentCache scCurrent(seedCacheCurrentMB * 1024 * 1024, false); + // Thread-local cache for current seed alignments + + // Interfaces for alignment and seed caches + AlignmentCacheIface ca( + &scCurrent, + scLocal.get(), + msNoCache ? NULL : &scShared); + + // Instantiate an object for holding reporting-related parameters. + ReportingParams rp( + (allHits ? std::numeric_limits::max() : khits), // -k + mhits, // -m/-M + 0, // penalty gap (not used now) + msample, // true -> -M was specified, otherwise assume -m + gReportDiscordant, // report discordang paired-end alignments? + gReportMixed); // report unpaired alignments for paired reads? + + // Instantiate a mapping quality calculator + auto_ptr bmapq(new_mapq(mapqv, scoreMin, sc)); + + // Make a per-thread wrapper for the global MHitSink object. + AlnSinkWrap msinkwrap( + msink, // global sink + rp, // reporting parameters + *bmapq.get(), // MAPQ calculator + (size_t)tid); // thread id + + BP_Aligner bp_Aligner( + ebwtFw, + multiseed_refnames, + &multiseed_mutex, + thread_rids_mindist, + no_spliced_alignment); + SwAligner sw; + OuterLoopMetrics olm; + SeedSearchMetrics sdm; + WalkMetrics wlm; + SwMetrics swmSeed, swmMate; + ReportingMetrics rpm; + RandomSource rnd, rndArb; + SSEMetrics sseU8ExtendMet; + SSEMetrics sseU8MateMet; + SSEMetrics sseI16ExtendMet; + SSEMetrics sseI16MateMet; + DescentMetrics descm; + uint64_t nbtfiltst = 0; // TODO: find a new home for these + uint64_t nbtfiltsc = 0; // TODO: find a new home for these + uint64_t nbtfiltdo = 0; // TODO: find a new home for these + HIMetrics him; + + ASSERT_ONLY(BTDnaString tmp); + + int pepolFlag; + if(gMate1fw && gMate2fw) { + pepolFlag = PE_POLICY_FF; + } else if(gMate1fw && !gMate2fw) { + pepolFlag = PE_POLICY_FR; + } else if(!gMate1fw && gMate2fw) { + pepolFlag = PE_POLICY_RF; + } else { + pepolFlag = PE_POLICY_RR; + } + assert_geq(gMaxInsert, gMinInsert); + assert_geq(gMinInsert, 0); + PairedEndPolicy pepol( + pepolFlag, + gMaxInsert, + gMinInsert, + localAlign, + gFlippedMatesOK, + gDovetailMatesOK, + gContainMatesOK, + gOlapMatesOK, + gExpandToFrag); + + PerfMetrics metricsPt; // per-thread metrics object; for read-level metrics + BTString nametmp; + + PerReadMetrics prm; + + // Used by thread with threadid == 1 to measure time elapsed + time_t iTime = time(0); + + // Keep track of whether last search was exhaustive for mates 1 and 2 + bool exhaustive[2] = { false, false }; + // Keep track of whether mates 1/2 were filtered out last time through + bool filt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out due Ns last time + bool nfilt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out due to not having + // enough characters to rise about the score threshold. + bool scfilt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out due to not having + // more characters than the number of mismatches permitted in a seed. + bool lenfilt[2] = { true, true }; + // Keep track of whether mates 1/2 were filtered out by upstream qc + bool qcfilt[2] = { true, true }; + + rndArb.init((uint32_t)time(0)); + int mergei = 0; + int mergeival = 16; + while(true) { + bool success = false, done = false, paired = false; + ps->nextReadPair(success, done, paired, outType != OUTPUT_SAM); + if(!success && done) { + break; + } else if(!success) { + continue; + } + TReadId rdid = ps->rdid(); + + if(nthreads > 1 && useTempSpliceSite) { + while(true) { + uint64_t min_rdid = 0; + { + // ThreadSafe t(&thread_rids_mutex, nthreads > 1); + assert_gt(thread_rids.size(), 0); + min_rdid = thread_rids[0]; + for(size_t i = 1; i < thread_rids.size(); i++) { + if(thread_rids[i] < min_rdid) { + min_rdid = thread_rids[i]; + } + } + } + + if(min_rdid + thread_rids_mindist < rdid) { +#if defined(_TTHREAD_WIN32_) + Sleep(0); +#elif defined(_TTHREAD_POSIX_) + sched_yield(); +#endif + } else break; + } + } + + bool sample = true; + if(arbitraryRandom) { + ps->bufa().seed = rndArb.nextU32(); + ps->bufb().seed = rndArb.nextU32(); + } + if(sampleFrac < 1.0f) { + rnd.init(ROTL(ps->bufa().seed, 2)); + sample = rnd.nextFloat() < sampleFrac; + } + if(rdid >= skipReads && rdid < qUpto && sample) { + // Align this read/pair + bool retry = true; + // + // Check if there is metrics reporting for us to do. + // + if(metricsIval > 0 && + (metricsOfb != NULL || metricsStderr) && + !metricsPerRead && + ++mergei == mergeival) + { + // Do a periodic merge. Update global metrics, in a + // synchronized manner if needed. + MERGE_METRICS(metrics, nthreads > 1); + mergei = 0; + // Check if a progress message should be printed + if(tid == 0) { + // Only thread 1 prints progress messages + time_t curTime = time(0); + if(curTime - iTime >= metricsIval) { + metrics.reportInterval(metricsOfb, metricsStderr, false, true, NULL); + iTime = curTime; + } + } + } + prm.reset(); // per-read metrics + prm.doFmString = false; + if(sam_print_xt) { + gettimeofday(&prm.tv_beg, &prm.tz_beg); + } + // Try to align this read + while(retry) { + retry = false; + assert_eq(ps->bufa().color, false); + ca.nextRead(); // clear the cache + olm.reads++; + assert(!ca.aligning()); + bool pair = paired; + const size_t rdlen1 = ps->bufa().length(); + const size_t rdlen2 = pair ? ps->bufb().length() : 0; + olm.bases += (rdlen1 + rdlen2); +#if 0 + msinkwrap.nextRead( + &ps->bufa(), + pair ? &ps->bufb() : NULL, + rdid, + sc.qualitiesMatter()); + assert(msinkwrap.inited()); +#endif + size_t rdlens[2] = { rdlen1, rdlen2 }; + // Calculate the minimum valid score threshold for the read + TAlScore minsc[2], maxpen[2]; + maxpen[0] = maxpen[1] = 0; + minsc[0] = minsc[1] = std::numeric_limits::max(); + if(bwaSwLike) { + // From BWA-SW manual: "Given an l-long query, the + // threshold for a hit to be retained is + // a*max{T,c*log(l)}." We try to recreate that here. + float a = (float)sc.match(30); + float T = bwaSwLikeT, c = bwaSwLikeC; + minsc[0] = (TAlScore)max(a*T, a*c*log(rdlens[0])); + if(paired) { + minsc[1] = (TAlScore)max(a*T, a*c*log(rdlens[1])); + } + } else { + minsc[0] = scoreMin.f(rdlens[0]); + if(paired) minsc[1] = scoreMin.f(rdlens[1]); + if(localAlign) { + if(minsc[0] < 0) { + if(!gQuiet) printLocalScoreMsg(*ps, paired, true); + minsc[0] = 0; + } + if(paired && minsc[1] < 0) { + if(!gQuiet) printLocalScoreMsg(*ps, paired, false); + minsc[1] = 0; + } + } else { + if(minsc[0] > 0) { + if(!gQuiet) printEEScoreMsg(*ps, paired, true); + minsc[0] = 0; + } + if(paired && minsc[1] > 0) { + if(!gQuiet) printEEScoreMsg(*ps, paired, false); + minsc[1] = 0; + } + } + } + + // N filter; does the read have too many Ns? + size_t readns[2] = {0, 0}; + sc.nFilterPair( + &ps->bufa().patFw, + pair ? &ps->bufb().patFw : NULL, + readns[0], + readns[1], + nfilt[0], + nfilt[1]); + // Score filter; does the read enough character to rise above + // the score threshold? + scfilt[0] = sc.scoreFilter(minsc[0], rdlens[0]); + scfilt[1] = sc.scoreFilter(minsc[1], rdlens[1]); + lenfilt[0] = lenfilt[1] = true; + if(rdlens[0] <= (size_t)multiseedMms || rdlens[0] < 2) { + if(!gQuiet) printMmsSkipMsg(*ps, paired, true, multiseedMms); + lenfilt[0] = false; + } + if((rdlens[1] <= (size_t)multiseedMms || rdlens[1] < 2) && paired) { + if(!gQuiet) printMmsSkipMsg(*ps, paired, false, multiseedMms); + lenfilt[1] = false; + } + if(rdlens[0] < 2) { + if(!gQuiet) printLenSkipMsg(*ps, paired, true); + lenfilt[0] = false; + } + if(rdlens[1] < 2 && paired) { + if(!gQuiet) printLenSkipMsg(*ps, paired, false); + lenfilt[1] = false; + } + qcfilt[0] = qcfilt[1] = true; + if(qcFilter) { + qcfilt[0] = (ps->bufa().filter != '0'); + qcfilt[1] = (ps->bufb().filter != '0'); + } + filt[0] = (nfilt[0] && scfilt[0] && lenfilt[0] && qcfilt[0]); + filt[1] = (nfilt[1] && scfilt[1] && lenfilt[1] && qcfilt[1]); + prm.nFilt += (filt[0] ? 0 : 1) + (filt[1] ? 0 : 1); + Read* rds[2] = { &ps->bufa(), &ps->bufb() }; + // For each mate... + assert(msinkwrap.empty()); + //size_t minedfw[2] = { 0, 0 }; + //size_t minedrc[2] = { 0, 0 }; + // Calcualte nofw / no rc + bool nofw[2] = { false, false }; + bool norc[2] = { false, false }; + nofw[0] = paired ? (gMate1fw ? gNofw : gNorc) : gNofw; + norc[0] = paired ? (gMate1fw ? gNorc : gNofw) : gNorc; + nofw[1] = paired ? (gMate2fw ? gNofw : gNorc) : gNofw; + norc[1] = paired ? (gMate2fw ? gNorc : gNofw) : gNorc; + // Calculate nceil + int nceil[2] = { 0, 0 }; + nceil[0] = nCeil.f((double)rdlens[0]); + nceil[0] = min(nceil[0], (int)rdlens[0]); + if(paired) { + nceil[1] = nCeil.f((double)rdlens[1]); + nceil[1] = min(nceil[1], (int)rdlens[1]); + } + exhaustive[0] = exhaustive[1] = false; + //size_t matemap[2] = { 0, 1 }; + bool pairPostFilt = filt[0] && filt[1]; + if(pairPostFilt) { + rnd.init(ps->bufa().seed ^ ps->bufb().seed); + } else { + rnd.init(ps->bufa().seed); + } + // Calculate interval length for both mates + int interval[2] = { 0, 0 }; + for(size_t mate = 0; mate < (pair ? 2:1); mate++) { + interval[mate] = msIval.f((double)rdlens[mate]); + if(filt[0] && filt[1]) { + // Boost interval length by 20% for paired-end reads + interval[mate] = (int)(interval[mate] * 1.2 + 0.5); + } + interval[mate] = max(interval[mate], 1); + } + // Calculate streak length + size_t streak[2] = { maxDpStreak, maxDpStreak }; + size_t mtStreak[2] = { maxMateStreak, maxMateStreak }; + size_t mxDp[2] = { maxDp, maxDp }; + size_t mxUg[2] = { maxUg, maxUg }; + size_t mxIter[2] = { maxIters, maxIters }; + if(allHits) { + streak[0] = streak[1] = std::numeric_limits::max(); + mtStreak[0] = mtStreak[1] = std::numeric_limits::max(); + mxDp[0] = mxDp[1] = std::numeric_limits::max(); + mxUg[0] = mxUg[1] = std::numeric_limits::max(); + mxIter[0] = mxIter[1] = std::numeric_limits::max(); + } else if(khits > 1) { + for(size_t mate = 0; mate < 2; mate++) { + streak[mate] += (khits-1) * maxStreakIncr; + mtStreak[mate] += (khits-1) * maxStreakIncr; + mxDp[mate] += (khits-1) * maxItersIncr; + mxUg[mate] += (khits-1) * maxItersIncr; + mxIter[mate] += (khits-1) * maxItersIncr; + } + } + if(filt[0] && filt[1]) { + streak[0] = (size_t)ceil((double)streak[0] / 2.0); + streak[1] = (size_t)ceil((double)streak[1] / 2.0); + assert_gt(streak[1], 0); + } + assert_gt(streak[0], 0); + // Calculate # seed rounds for each mate + size_t nrounds[2] = { nSeedRounds, nSeedRounds }; + if(filt[0] && filt[1]) { + nrounds[0] = (size_t)ceil((double)nrounds[0] / 2.0); + nrounds[1] = (size_t)ceil((double)nrounds[1] / 2.0); + assert_gt(nrounds[1], 0); + } + assert_gt(nrounds[0], 0); + // Increment counters according to what got filtered + for(size_t mate = 0; mate < (pair ? 2:1); mate++) { + if(!filt[mate]) { + // Mate was rejected by N filter + olm.freads++; // reads filtered out + olm.fbases += rdlens[mate]; // bases filtered out + } else { + //shs[mate].clear(); + //shs[mate].nextRead(mate == 0 ? ps->bufa() : ps->bufb()); + //assert(shs[mate].empty()); + olm.ureads++; // reads passing filter + olm.ubases += rdlens[mate]; // bases passing filter + } + } + //size_t eePeEeltLimit = std::numeric_limits::max(); + // Whether we're done with mate1 / mate2 + bool done[2] = { !filt[0], !filt[1] }; + // size_t nelt[2] = {0, 0}; + if(filt[0] && filt[1]) { + bp_Aligner.initReads(rds, nofw, norc, minsc, maxpen); + } else if(filt[0] || filt[1]) { + bp_Aligner.initRead(rds[0], nofw[0], norc[0], minsc[0], maxpen[0], filt[1]); + } + if(filt[0] || filt[1]) { + int ret = bp_Aligner.go(sc, ebwtFw, ebwtBw, ref, sw, *ssdb, wlm, prm, swmSeed, him, rnd, msinkwrap); + MERGE_SW(sw); + // daehwan + size_t mate = 0; + + assert_gt(ret, 0); + // Clear out the exact hits so that we don't try to + // extend them again later! + if(ret == EXTEND_EXHAUSTED_CANDIDATES) { + // Not done yet + } else if(ret == EXTEND_POLICY_FULFILLED) { + // Policy is satisfied for this mate at least + if(msinkwrap.state().doneWithMate(mate == 0)) { + done[mate] = true; + } + if(msinkwrap.state().doneWithMate(mate == 1)) { + done[mate^1] = true; + } + } else if(ret == EXTEND_PERFECT_SCORE) { + // We exhausted this mode at least + done[mate] = true; + } else if(ret == EXTEND_EXCEEDED_HARD_LIMIT) { + // We exceeded a per-read limit + done[mate] = true; + } else if(ret == EXTEND_EXCEEDED_SOFT_LIMIT) { + // Not done yet + } else { + // + cerr << "Bad return value: " << ret << endl; + throw 1; + } + if(!done[mate]) { + TAlScore perfectScore = sc.perfectScore(rdlens[mate]); + if(!done[mate] && minsc[mate] == perfectScore) { + done[mate] = true; + } + } + } + + for(size_t i = 0; i < 2; i++) { + assert_leq(prm.nExIters, mxIter[i]); + assert_leq(prm.nExDps, mxDp[i]); + assert_leq(prm.nMateDps, mxDp[i]); + assert_leq(prm.nExUgs, mxUg[i]); + assert_leq(prm.nMateUgs, mxUg[i]); + assert_leq(prm.nDpFail, streak[i]); + assert_leq(prm.nUgFail, streak[i]); + assert_leq(prm.nEeFail, streak[i]); + } + +#if 0 + // Commit and report paired-end/unpaired alignments + msinkwrap.finishRead( + NULL, + NULL, + exhaustive[0], // exhausted seed hits for mate 1? + exhaustive[1], // exhausted seed hits for mate 2? + nfilt[0], + nfilt[1], + scfilt[0], + scfilt[1], + lenfilt[0], + lenfilt[1], + qcfilt[0], + qcfilt[1], + sortByScore, // prioritize by alignment score + rnd, // pseudo-random generator + rpm, // reporting metrics + prm, // per-read metrics + sc, // scoring scheme + !seedSumm, // suppress seed summaries? + seedSumm); // suppress alignments? + assert(!retry || msinkwrap.empty()); +#endif + + if(nthreads > 1 && useTempSpliceSite) { + // ThreadSafe t(&thread_rids_mutex, nthreads > 1); + assert_gt(tid, 0); + assert_leq(tid, thread_rids.size()); + assert(thread_rids[tid - 1] == 0 || rdid > thread_rids[tid - 1]); + thread_rids[tid - 1] = rdid; + } + } // while(retry) + } // if(rdid >= skipReads && rdid < qUpto) + else if(rdid >= qUpto) { + break; + } + if(metricsPerRead) { + MERGE_METRICS(metricsPt, nthreads > 1); + nametmp = ps->bufa().name; + metricsPt.reportInterval( + metricsOfb, metricsStderr, true, true, &nametmp); + metricsPt.reset(); + } + } // while(true) + + // One last metrics merge + MERGE_METRICS(metrics, nthreads > 1); + + return; +} + +/** + * Called once per alignment job. Sets up global pointers to the + * shared global data structures, creates per-thread structures, then + * enters the search loop. + */ +static void multiseedSearch( + Scoring& sc, + PairedPatternSource& patsrc, // pattern source + AlnSink& msink, // hit sink + HierEbwt& ebwtFw, // index of original text + HierEbwt& ebwtBw, // index of mirror text + BitPairReference* refs, + const EList& refnames, + OutFileBuf *metricsOfb) +{ + multiseed_patsrc = &patsrc; + multiseed_msink = &msink; + multiseed_ebwtFw = &ebwtFw; + multiseed_ebwtBw = &ebwtBw; + multiseed_sc = ≻ + multiseed_refnames = refnames; + multiseed_metricsOfb = metricsOfb; + multiseed_refs = refs; + AutoArray threads(nthreads); + AutoArray tids(nthreads); + { + // Load the other half of the index into memory + assert(!ebwtFw.isInMemory()); + Timer _t(cerr, "Time loading forward index: ", timing); + ebwtFw.loadIntoMemory( + 0, // colorspace? + -1, // not the reverse index + true, // load SA samp? (yes, need forward index's SA samp) + true, // load ftab (in forward index) + true, // load rstarts (in forward index) + !noRefNames, // load names? + startVerbose); + } +#if 0 + if(multiseedMms > 0 || do1mmUpFront) { + // Load the other half of the index into memory + assert(!ebwtBw.isInMemory()); + Timer _t(cerr, "Time loading mirror index: ", timing); + ebwtBw.loadIntoMemory( + 0, // colorspace? + // It's bidirectional search, so we need the reverse to be + // constructed as the reverse of the concatenated strings. + 1, + true, // load SA samp in reverse index + true, // yes, need ftab in reverse index + true, // load rstarts in reverse index + !noRefNames, // load names? + startVerbose); + } +#endif + // Start the metrics thread + { + Timer _t(cerr, "Multiseed full-index search: ", timing); + + thread_rids.resize(nthreads); + thread_rids.fill(0); + thread_rids_mindist = (nthreads == 1 || !useTempSpliceSite ? 0 : 1000 * nthreads); + + for(int i = 0; i < nthreads; i++) { + // Thread IDs start at 1 + tids[i] = i+1; + threads[i] = new tthread::thread(multiseedSearchWorker_hisat_bp, (void*)&tids[i]); + } + + for (int i = 0; i < nthreads; i++) + threads[i]->join(); + + } + if(!metricsPerRead && (metricsOfb != NULL || metricsStderr)) { + metrics.reportInterval(metricsOfb, metricsStderr, true, false, NULL); + } +} + +static string argstr; + +extern void initializeCntLut(); +extern void initializeCntBit(); + +template +static void driver( + const char * type, + const string& bt2indexBase, + const string& outfile) +{ + if(gVerbose || startVerbose) { + cerr << "Entered driver(): "; logTime(cerr, true); + } + + initializeCntLut(); + initializeCntBit(); + + // Vector of the reference sequences; used for sanity-checking + EList > names, os; + EList nameLens, seqLens; + // Read reference sequences from the command-line or from a FASTA file + if(!origString.empty()) { + // Read fasta file(s) + EList origFiles; + tokenize(origString, ",", origFiles); + parseFastas(origFiles, names, nameLens, os, seqLens); + } + PatternParams pp( + format, // file format + fileParallel, // true -> wrap files with separate PairedPatternSources + seed, // pseudo-random seed + useSpinlock, // use spin locks instead of pthreads + solexaQuals, // true -> qualities are on solexa64 scale + phred64Quals, // true -> qualities are on phred64 scale + integerQuals, // true -> qualities are space-separated numbers + fuzzy, // true -> try to parse fuzzy fastq + fastaContLen, // length of sampled reads for FastaContinuous... + fastaContFreq, // frequency of sampled reads for FastaContinuous... + skipReads // skip the first 'skip' patterns + ); + if(gVerbose || startVerbose) { + cerr << "Creating PatternSource: "; logTime(cerr, true); + } + PairedPatternSource *patsrc = PairedPatternSource::setupPatternSources( + queries, // singles, from argv + mates1, // mate1's, from -1 arg + mates2, // mate2's, from -2 arg + mates12, // both mates on each line, from --12 arg + qualities, // qualities associated with singles + qualities1, // qualities associated with m1 + qualities2, // qualities associated with m2 + pp, // read read-in parameters + gVerbose || startVerbose); // be talkative + // Open hit output file + if(gVerbose || startVerbose) { + cerr << "Opening hit output file: "; logTime(cerr, true); + } + OutFileBuf *fout; + if(!outfile.empty()) { + fout = new OutFileBuf(outfile.c_str(), false); + } else { + fout = new OutFileBuf(); + } + // Initialize Ebwt object and read in header + if(gVerbose || startVerbose) { + cerr << "About to initialize fw Ebwt: "; logTime(cerr, true); + } + adjIdxBase = adjustEbwtBase(argv0, bt2indexBase, gVerbose); + HierEbwt ebwt( + adjIdxBase, + 0, // index is colorspace + -1, // fw index + true, // index is for the forward direction + /* overriding: */ offRate, + 0, // amount to add to index offrate or <= 0 to do nothing + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + gVerbose, // whether to be talkative + startVerbose, // talkative during initialization + false /*passMemExc*/, + sanityCheck); + HierEbwt* ebwtBw = NULL; +#if 0 + // We need the mirror index if mismatches are allowed + if(multiseedMms > 0 || do1mmUpFront) { + if(gVerbose || startVerbose) { + cerr << "About to initialize rev Ebwt: "; logTime(cerr, true); + } + ebwtBw = new HierEbwt( + adjIdxBase + ".rev", + 0, // index is colorspace + 1, // TODO: maybe not + false, // index is for the reverse direction + /* overriding: */ offRate, + 0, // amount to add to index offrate or <= 0 to do nothing + useMm, // whether to use memory-mapped files + useShmem, // whether to use shared memory + mmSweep, // sweep memory-mapped files + !noRefNames, // load names? + true, // load SA sample? + true, // load ftab? + true, // load rstarts? + gVerbose, // whether to be talkative + startVerbose, // talkative during initialization + false /*passMemExc*/, + sanityCheck); + } +#endif + if(sanityCheck && !os.empty()) { + // Sanity check number of patterns and pattern lengths in Ebwt + // against original strings + assert_eq(os.size(), ebwt.nPat()); + for(size_t i = 0; i < os.size(); i++) { + assert_eq(os[i].length(), ebwt.plen()[i]); + } + } + // Sanity-check the restored version of the Ebwt + if(sanityCheck && !os.empty()) { + ebwt.loadIntoMemory( + 0, + -1, // fw index + true, // load SA sample + true, // load ftab + true, // load rstarts + !noRefNames, + startVerbose); + ebwt.checkOrigs(os, false, false); + ebwt.evictFromMemory(); + } + OutputQueue oq( + *fout, // out file buffer + reorder && nthreads > 1, // whether to reorder when there's >1 thread + nthreads, // # threads + nthreads > 1, // whether to be thread-safe + skipReads); // first read will have this rdid + { + Timer _t(cerr, "Time searching: ", timing); + // Set up penalities + if(bonusMatch > 0 && !localAlign) { + cerr << "Warning: Match bonus always = 0 in --end-to-end mode; ignoring user setting" << endl; + bonusMatch = 0; + } + Scoring sc( + bonusMatch, // constant reward for match + penMmcType, // how to penalize mismatches + penMmcMax, // max mm pelanty + penMmcMin, // min mm pelanty + scoreMin, // min score as function of read len + nCeil, // max # Ns as function of read len + penNType, // how to penalize Ns in the read + penN, // constant if N pelanty is a constant + penNCatPair, // whether to concat mates before N filtering + penRdGapConst, // constant coeff for read gap cost + penRfGapConst, // constant coeff for ref gap cost + penRdGapLinear, // linear coeff for read gap cost + penRfGapLinear, // linear coeff for ref gap cost + gGapBarrier, // # rows at top/bot only entered diagonally + penCanSplice, // canonical splicing penalty + penNoncanSplice,// non-canonical splicing penalty + &penIntronLen); // penalty as to intron length + EList reflens; + for(size_t i = 0; i < ebwt.nPat(); i++) { + reflens.push_back(ebwt.plen()[i]); + } + EList refnames; + readEbwtRefnames(adjIdxBase, refnames); + SamConfig samc( + refnames, // reference sequence names + reflens, // reference sequence lengths + samTruncQname, // whether to truncate QNAME to 255 chars + samOmitSecSeqQual, // omit SEQ/QUAL for 2ndary alignments? + samNoUnal, // omit unaligned-read records? + string("hisat"), // program id + string("hisat"), // program name + string(HISAT_VERSION), // program version + argstr, // command-line + rgs_optflag, // read-group string + rna_strandness, + sam_print_as, + sam_print_xs, + sam_print_xss, + sam_print_yn, + sam_print_xn, + sam_print_cs, + sam_print_cq, + sam_print_x0, + sam_print_x1, + sam_print_xm, + sam_print_xo, + sam_print_xg, + sam_print_nm, + sam_print_md, + sam_print_yf, + sam_print_yi, + sam_print_ym, + sam_print_yp, + sam_print_yt, + sam_print_ys, + sam_print_zs, + sam_print_xr, + sam_print_xt, + sam_print_xd, + sam_print_xu, + sam_print_yl, + sam_print_ye, + sam_print_yu, + sam_print_xp, + sam_print_yr, + sam_print_zb, + sam_print_zr, + sam_print_zf, + sam_print_zm, + sam_print_zi, + sam_print_zp, + sam_print_zu, + sam_print_xs_a); + // Set up hit sink; if sanityCheck && !os.empty() is true, + // then instruct the sink to "retain" hits in a vector in + // memory so that we can easily sanity check them later on + AlnSink *mssink = NULL; + Timer *_tRef = new Timer(cerr, "Time loading reference: ", timing); + auto_ptr refs( + new BitPairReference( + adjIdxBase, + false, + sanityCheck, + NULL, + NULL, + false, + useMm, + useShmem, + mmSweep, + gVerbose, + startVerbose) + ); + delete _tRef; + if(!refs->loaded()) throw 1; + + init_junction_prob(); + bool write = novelSpliceSiteOutfile != "" || useTempSpliceSite; + bool read = knownSpliceSiteInfile != "" || novelSpliceSiteInfile != "" || useTempSpliceSite; + ssdb = new SpliceSiteDB( + *(refs.get()), + refnames, + nthreads > 1, // thread-safe + write, // write? + read); // read? + if(ssdb != NULL) { + if(knownSpliceSiteInfile != "") { + ifstream ssdb_file(knownSpliceSiteInfile.c_str(), ios::in); + if(ssdb_file.is_open()) { + ssdb->read(ssdb_file, false); // known splice sites + ssdb_file.close(); + } + } + if(novelSpliceSiteInfile != "") { + ifstream ssdb_file(novelSpliceSiteInfile.c_str(), ios::in); + if(ssdb_file.is_open()) { + ssdb->read(ssdb_file, true); // novel splice sites + ssdb_file.close(); + } + } + } + switch(outType) { + case OUTPUT_SAM: { + mssink = new AlnSinkSam( + oq, // output queue + samc, // settings & routines for SAM output + refnames, // reference names + gQuiet, // don't print alignment summary at end + ssdb); +#if 0 + if(!samNoHead) { + bool printHd = true, printSq = true; + BTString buf; + samc.printHeader(buf, rgid, rgs, printHd, !samNoSQ, printSq); + fout->writeString(buf); + } +#endif + break; + } + default: + cerr << "Invalid output type: " << outType << endl; + throw 1; + } + if(gVerbose || startVerbose) { + cerr << "Dispatching to search driver: "; logTime(cerr, true); + } + // Set up global constraint + OutFileBuf *metricsOfb = NULL; + if(!metricsFile.empty() && metricsIval > 0) { + metricsOfb = new OutFileBuf(metricsFile); + } + // Do the search for all input reads + assert(patsrc != NULL); + assert(mssink != NULL); + multiseedSearch( + sc, // scoring scheme + *patsrc, // pattern source + *mssink, // hit sink + ebwt, // BWT + *ebwtBw, // BWT' + refs.get(), + refnames, + metricsOfb); + // Evict any loaded indexes from memory + if(ebwt.isInMemory()) { + ebwt.evictFromMemory(); + } + if(ebwtBw != NULL) { + delete ebwtBw; + } + if(!gQuiet && !seedSumm) { + size_t repThresh = mhits; + if(repThresh == 0) { + repThresh = std::numeric_limits::max(); + } +#if 0 + mssink->finish( + repThresh, + gReportDiscordant, + gReportMixed, + hadoopOut); +#endif + } + if(ssdb != NULL) { + if(novelSpliceSiteOutfile != "") { + ofstream ssdb_file(novelSpliceSiteOutfile.c_str(), ios::out); + if(ssdb_file.is_open()) { + ssdb->print(ssdb_file); + ssdb_file.close(); + } + } + } + oq.flush(true); + assert_eq(oq.numStarted(), oq.numFinished()); + assert_eq(oq.numStarted(), oq.numFlushed()); + delete patsrc; + delete mssink; + delete ssdb; + delete metricsOfb; + if(fout != NULL) { + delete fout; + } + } +} + +// C++ name mangling is disabled for the bowtie() function to make it +// easier to use Bowtie as a library. +extern "C" { + +/** + * Main bowtie entry function. Parses argc/argv style command-line + * options, sets global configuration variables, and calls the driver() + * function. + */ +int hisat(int argc, const char **argv) { + try { + // Reset all global state, including getopt state + opterr = optind = 1; + resetOptions(); + for(int i = 0; i < argc; i++) { + argstr += argv[i]; + if(i < argc-1) argstr += " "; + } + if(startVerbose) { cerr << "Entered main(): "; logTime(cerr, true); } + parseOptions(argc, argv); + argv0 = argv[0]; + if(showVersion) { + cout << argv0 << " version " << HISAT_VERSION << endl; + if(sizeof(void*) == 4) { + cout << "32-bit" << endl; + } else if(sizeof(void*) == 8) { + cout << "64-bit" << endl; + } else { + cout << "Neither 32- nor 64-bit: sizeof(void*) = " << sizeof(void*) << endl; + } + cout << "Built on " << BUILD_HOST << endl; + cout << BUILD_TIME << endl; + cout << "Compiler: " << COMPILER_VERSION << endl; + cout << "Options: " << COMPILER_OPTIONS << endl; + cout << "Sizeof {int, long, long long, void*, size_t, off_t}: {" + << sizeof(int) + << ", " << sizeof(long) << ", " << sizeof(long long) + << ", " << sizeof(void *) << ", " << sizeof(size_t) + << ", " << sizeof(off_t) << "}" << endl; + return 0; + } + { + Timer _t(cerr, "Overall time: ", timing); + if(startVerbose) { + cerr << "Parsing index and read arguments: "; logTime(cerr, true); + } + + // Get index basename (but only if it wasn't specified via --index) + if(bt2index.empty()) { + if(optind >= argc) { + cerr << "No index, query, or output file specified!" << endl; + printUsage(cerr); + return 1; + } + bt2index = argv[optind++]; + } + + // Get query filename + bool got_reads = !queries.empty() || !mates1.empty() || !mates12.empty(); + if(optind >= argc) { + if(!got_reads) { + printUsage(cerr); + cerr << "***" << endl + << "Error: Must specify at least one read input with -U/-1/-2" << endl; + return 1; + } + } else if(!got_reads) { + // Tokenize the list of query files + tokenize(argv[optind++], ",", queries); + if(queries.empty()) { + cerr << "Tokenized query file list was empty!" << endl; + printUsage(cerr); + return 1; + } + } + + // Get output filename + if(optind < argc && outfile.empty()) { + outfile = argv[optind++]; + cerr << "Warning: Output file '" << outfile.c_str() + << "' was specified without -S. This will not work in " + << "future HISAT 2 versions. Please use -S instead." + << endl; + } + + // Extra parametesr? + if(optind < argc) { + cerr << "Extra parameter(s) specified: "; + for(int i = optind; i < argc; i++) { + cerr << "\"" << argv[i] << "\""; + if(i < argc-1) cerr << ", "; + } + cerr << endl; + if(mates1.size() > 0) { + cerr << "Note that if files are specified using -1/-2, a file cannot" << endl + << "also be specified. Please run HISAT2 separately for mates and singles." << endl; + } + throw 1; + } + + // Optionally summarize + if(gVerbose) { + cout << "Input bt2 file: \"" << bt2index.c_str() << "\"" << endl; + cout << "Query inputs (DNA, " << file_format_names[format].c_str() << "):" << endl; + for(size_t i = 0; i < queries.size(); i++) { + cout << " " << queries[i].c_str() << endl; + } + cout << "Quality inputs:" << endl; + for(size_t i = 0; i < qualities.size(); i++) { + cout << " " << qualities[i].c_str() << endl; + } + cout << "Output file: \"" << outfile.c_str() << "\"" << endl; + cout << "Local endianness: " << (currentlyBigEndian()? "big":"little") << endl; + cout << "Sanity checking: " << (sanityCheck? "enabled":"disabled") << endl; + #ifdef NDEBUG + cout << "Assertions: disabled" << endl; + #else + cout << "Assertions: enabled" << endl; + #endif + } + if(ipause) { + cout << "Press key to continue..." << endl; + getchar(); + } + driver >("DNA", bt2index, outfile); + } + return 0; + } catch(std::exception& e) { + cerr << "Error: Encountered exception: '" << e.what() << "'" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + return 1; + } catch(int e) { + if(e != 0) { + cerr << "Error: Encountered internal HISAT2 exception (#" << e << ")" << endl; + cerr << "Command: "; + for(int i = 0; i < argc; i++) cerr << argv[i] << " "; + cerr << endl; + } + return e; + } +} // bowtie() +} // extern "C" diff --git a/ival_list.cpp b/ival_list.cpp new file mode 100644 index 0000000..acbe460 --- /dev/null +++ b/ival_list.cpp @@ -0,0 +1,165 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "ival_list.h" + +#ifdef MAIN_IVAL_DS + +#include +#include "random_source.h" + +using namespace std; + +int main(void) { + cerr << "Case 1 ... "; + { + EIvalMergeList list((size_t)5); + list.add(Interval(0, 10, true, 10)); + list.add(Interval(0, 30, true, 10)); + list.add(Interval(0, 20, true, 10)); + assert(!list.locusPresent(Coord(0, 5, true))); + assert(!list.locusPresent(Coord(0, 9, true))); + assert(list.locusPresent(Coord(0, 10, true))); + assert(list.locusPresent(Coord(0, 11, true))); + assert(list.locusPresent(Coord(0, 19, true))); + assert(list.locusPresent(Coord(0, 20, true))); + assert(list.locusPresent(Coord(0, 21, true))); + assert(list.locusPresent(Coord(0, 29, true))); + assert(list.locusPresent(Coord(0, 30, true))); + assert(list.locusPresent(Coord(0, 31, true))); + assert(list.locusPresent(Coord(0, 39, true))); + assert(!list.locusPresent(Coord(0, 40, true))); + assert(!list.locusPresent(Coord(0, 41, true))); + } + cerr << " PASSED" << endl; + + cerr << "Case 2 ... "; + { + EIvalMergeList list((size_t)5); + list.add(Interval(0, 10, true, 10)); + for(size_t i = 5; i < 45; i++) { + assert(list.locusPresent(Coord(0, i, true)) == (i >= 10 && i < 20)); + } + list.clear(); + list.add(Interval(0, 15, true, 10)); + for(size_t i = 5; i < 45; i++) { + assert(list.locusPresent(Coord(0, i, true)) == (i >= 15 && i < 25)); + } + } + cerr << " PASSED" << endl; + + cerr << "Case 3 ... "; + { + EIvalMergeList list((size_t)5); + for(size_t i = 0; i < 20; i++) { + list.add(Interval(0, 10*i, true, 9)); + } + for(size_t i = 0; i < 200; i++) { + assert(list.locusPresent(Coord(0, i, true)) == ((i % 10) != 9)); + assert(!list.locusPresent(Coord(0, i, false))); + assert(!list.locusPresent(Coord(1, i, true))); + } + } + cerr << " PASSED" << endl; + + cerr << "Case 4 ... "; + { + EIvalMergeList list((size_t)5); + for(int i = 19; i >= 0; i--) { + list.add(Interval(0, 10*i, true, 9)); + } + for(size_t i = 0; i < 200; i++) { + assert(list.locusPresent(Coord(0, i, true)) == ((i % 10) != 9)); + assert(!list.locusPresent(Coord(0, i, false))); + assert(!list.locusPresent(Coord(1, i, true))); + } + } + cerr << " PASSED" << endl; + + cerr << "Random testing (1 ref) ... "; + { + RandomSource rnd(34523); + for(size_t c = 0; c < 10; c++) { + EIvalMergeList list1((size_t)16); + EIvalMergeList list2((size_t)2000); + size_t num_intervals = 20; + uint32_t max_width = 100; + for(size_t i = 0; i < num_intervals; i++) { + uint32_t start = rnd.nextU32() % max_width/2; + uint32_t end = (rnd.nextU32() % (max_width - start - 1) + start)+1; + assert_lt(end, max_width); + assert_gt(end, start); + list1.add(Interval(0, start, false, end-start)); + list2.add(Interval(0, start, false, end-start)); + } + assert_geq(num_intervals, list1.size()); + assert_geq(num_intervals, list2.size()); + assert(list1.repOk()); + assert(list2.repOk()); + for(uint32_t i = 0; i < max_width+1; i++) { + assert(list1.repOk()); + assert(list2.repOk()); + ASSERT_ONLY(bool l1 = list1.locusPresent(Coord(0, i, true))); + ASSERT_ONLY(bool l2 = list2.locusPresent(Coord(0, i, true))); + assert_eq(l1, l2); + } + } + } + cerr << " PASSED" << endl; + + cerr << "Random testing (few refs) ... "; + { + RandomSource rnd(34523); + for(size_t c = 0; c < 10; c++) { + EIvalMergeList list1((size_t)16); + EIvalMergeList list2((size_t)2000); + size_t num_intervals = 20; + uint32_t max_width = 100; + for(size_t i = 0; i < num_intervals; i++) { + uint32_t start = rnd.nextU32() % max_width/2; + uint32_t end = (rnd.nextU32() % (max_width - start - 1) + start)+1; + assert_lt(end, max_width); + assert_gt(end, start); + bool orient = (rnd.nextU2() == 0); + TRefId ref = (TRefId)(rnd.nextU32() % 5); + list1.add(Interval(ref, start, orient, end-start)); + list2.add(Interval(ref, start, orient, end-start)); + } + assert_geq(num_intervals, list1.size()); + assert_geq(num_intervals, list2.size()); + assert(list1.repOk()); + assert(list2.repOk()); + for(uint32_t i = 0; i < max_width+1; i++) { + assert(list1.repOk()); + assert(list2.repOk()); + for(int fwi = 0; fwi < 2; fwi++) { + bool fw = (fwi == 0); + for(TRefId refi = 0; refi < 5; refi++) { + ASSERT_ONLY(bool l1 = list1.locusPresent(Coord(refi, i, fw))); + ASSERT_ONLY(bool l2 = list2.locusPresent(Coord(refi, i, fw))); + assert_eq(l1, l2); + } + } + } + } + } + cerr << " PASSED" << endl; +} + +#endif /*def MAIN_IVAL_DS*/ diff --git a/ival_list.h b/ival_list.h new file mode 100644 index 0000000..0fc40a5 --- /dev/null +++ b/ival_list.h @@ -0,0 +1,299 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef IVAL_LIST_H_ +#define IVAL_LIST_H_ + +#include "ds.h" +#include "ref_coord.h" +#include + +/** + * Encapsulates the "union" of a collection of intervals. Intervals are stored + * in a sorted list. Intervals can be added but not removed. Supports just + * one type of query for now: locusPresent(). + */ +class EIvalMergeList { +public: + + static const size_t DEFAULT_UNSORTED_SZ = 16; + + explicit EIvalMergeList(int cat = 0) : + sorted_(cat), + sortedLhs_(cat), + unsorted_(cat), + unsortedSz_(DEFAULT_UNSORTED_SZ) + { } + + explicit EIvalMergeList(size_t unsortedSz, int cat = 0) : + sorted_(cat), + sortedLhs_(cat), + unsorted_(cat), + unsortedSz_(unsortedSz) + { } + + /** + * Set the maximum size of the unsorted list. + */ + void setUnsortedSize(size_t usz) { + unsortedSz_ = usz; + } + + /** + * Add a new interval to the list. + */ + void add(const Interval& i) { + assert_leq(unsorted_.size(), unsortedSz_); + if(unsorted_.size() < unsortedSz_) { + unsorted_.push_back(i); + } + if(unsorted_.size() == unsortedSz_) { + flush(); + } + } + + /** + * Move all unsorted interval information into the sorted list and re-sort. + * Merge overlapping intervals. + */ + void flush() { + for(size_t i = 0; i < unsorted_.size(); i++) { + sorted_.push_back(unsorted_[i]); + } + sorted_.sort(); + merge(); + sortedLhs_.clear(); + for(size_t i = 0; i < sorted_.size(); i++) { + sortedLhs_.push_back(sorted_[i].upstream()); + } + assert(sortedLhs_.sorted()); + unsorted_.clear(); + } + +#ifndef NDEBUG + /** + * Check that this interval list is internally consistent. + */ + bool repOk() const { + assert_eq(sorted_.size(), sortedLhs_.size()); + return true; + } +#endif + + /** + * Remove all ranges from the list. + */ + void reset() { clear(); } + + /** + * Remove all ranges from the list. + */ + void clear() { + sorted_.clear(); + sortedLhs_.clear(); + unsorted_.clear(); + } + + /** + * Return true iff this locus is present in one of the intervals in the + * list. + */ + bool locusPresent(const Coord& loc) const { + return locusPresentUnsorted(loc) || locusPresentSorted(loc); + } + + /** + * Return the number of intervals added since the last call to reset() or + * clear(). + */ + size_t size() const { + return sorted_.size() + unsorted_.size(); + } + + /** + * Return true iff list is empty. + */ + bool empty() const { + return sorted_.empty() && unsorted_.empty(); + } + +protected: + + /** + * Go through the sorted interval list and merge adjacent entries that + * overlap. + */ + void merge() { + size_t nmerged = 0; + for(size_t i = 1; i < sorted_.size(); i++) { + if(sorted_[i-1].downstream() >= sorted_[i].upstream()) { + nmerged++; + assert_leq(sorted_[i-1].upstream(), sorted_[i].upstream()); + Coord up = std::min(sorted_[i-1].upstream(), sorted_[i].upstream()); + Coord dn = std::max(sorted_[i-1].downstream(), sorted_[i].downstream()); + sorted_[i].setUpstream(up); + sorted_[i].setLength(dn.off() - up.off()); + sorted_[i-1].reset(); + } + } + sorted_.sort(); + assert_lt(nmerged, sorted_.size()); + sorted_.resize(sorted_.size()-nmerged); +#ifndef NDEBUG + for(size_t i = 0; i < sorted_.size(); i++) { + assert(sorted_[i].inited()); + } +#endif + } + + /** + * Return true iff the given locus is present in one of the intervals in + * the sorted list. + */ + bool locusPresentSorted(const Coord& loc) const { + assert(repOk()); + if(sorted_.empty()) { + return false; + } + size_t beg = sortedLhs_.bsearchLoBound(loc); + if(beg == sortedLhs_.size() || sortedLhs_[beg] > loc) { + // Check element before + if(beg == 0) { + return false; + } + return sorted_[beg-1].contains(loc); + } else { + assert_eq(loc, sortedLhs_[beg]); + return true; + } + } + + /** + * Return true iff the given locus is present in one of the intervals in + * the unsorted list. + */ + bool locusPresentUnsorted(const Coord& loc) const { + for(size_t i = 0; i < unsorted_.size(); i++) { + if(unsorted_[i].contains(loc)) { + return true; + } + } + return false; + } + + EList sorted_; // LHS, RHS sorted + EList sortedLhs_; // LHS, index into sorted_, sorted + EList unsorted_; // unsorted + size_t unsortedSz_; // max allowed size of unsorted_ +}; + +/** + * Binned version of the above. We bin using the low bits of the reference + * sequence. + */ +class EIvalMergeListBinned { +public: + + static const size_t NBIN = 7; + + explicit EIvalMergeListBinned(int cat = 0) : bins_(1 << NBIN, cat) { + bins_.resize(1 << NBIN); + } + + explicit EIvalMergeListBinned( + size_t unsortedSz, + int cat = 0) : bins_(1 << NBIN, cat) + { + bins_.resize(1 << NBIN); + for(size_t i = 0; i < (1 << NBIN); i++) { + bins_[i].setUnsortedSize(unsortedSz); + } + } + + /** + * Add a new interval to the list. + */ + void add(const Interval& i) { + size_t bin = i.ref() & ~(0xffffffff << NBIN); + assert_lt(bin, bins_.size()); + bins_[bin].add(i); + } + +#ifndef NDEBUG + /** + * Check that this interval list is internally consistent. + */ + bool repOk() const { + for(size_t i = 0; i < bins_.size(); i++) { + assert(bins_[i].repOk()); + } + return true; + } +#endif + + /** + * Remove all ranges from the list. + */ + void reset() { clear(); } + + /** + * Remove all ranges from the list. + */ + void clear() { + for(size_t i = 0; i < bins_.size(); i++) { + bins_[i].clear(); + } + } + + /** + * Return true iff this locus is present in one of the intervals in the + * list. + */ + bool locusPresent(const Coord& loc) const { + size_t bin = loc.ref() & ~(0xffffffff << NBIN); + assert_lt(bin, bins_.size()); + return bins_[bin].locusPresent(loc); + } + + /** + * Return the number of intervals added since the last call to reset() or + * clear(). + */ + size_t size() const { + // TODO: Keep track of size + size_t sz = 0; + for(size_t i = 0; i < bins_.size(); i++) { + sz += bins_[i].size(); + } + return sz; + } + + /** + * Return true iff list is empty. + */ + bool empty() const { + return size() == 0; + } + +protected: + + EList bins_; +}; + +#endif /*ndef IVAL_LIST_H_*/ diff --git a/li_hla/Makefile b/li_hla/Makefile new file mode 100644 index 0000000..9f77758 --- /dev/null +++ b/li_hla/Makefile @@ -0,0 +1,16 @@ +CXX = g++ +CXXFLAGS= -W +LINKPATH= -I./samtools-0.1.19 -L./samtools-0.1.19 +LINKFLAGS = -lbam -lz -lm -lpthread +DEBUG= +OBJECTS = + +all: hla + +hla: main.o + $(CXX) -o $@ $(LINKPATH) $(CXXFLAGS) $(OBJECTS) main.o $(LINKFLAGS) + +main.o: main.cpp alignments.hpp + +clean: + rm -f *.o *.gch hla diff --git a/li_hla/alignments.hpp b/li_hla/alignments.hpp new file mode 100644 index 0000000..bb5d6f4 --- /dev/null +++ b/li_hla/alignments.hpp @@ -0,0 +1,276 @@ +// The class handles reading the bam file + +#ifndef _LSONG_ALIGNMENT_HEADER +#define _LSONG_ALIGNMENT_HEADER + +#include "samtools-0.1.19/sam.h" +#include +#include +#include +#include + +#include "defs.h" + +class Alignments +{ +private: + samfile_t *fpSam ; + bam1_t *b ; + + char fileName[1024] ; + bool opened ; + std::map chrNameToId ; + int onlyChromId ; // ignore other chromosomes + + void Open() + { + fpSam = samopen( fileName, "rb", 0 ) ; + if ( !fpSam->header ) + { + fprintf( stderr, "Can not open %s.\n", fileName ) ; + exit( 1 ) ; + } + + // Collect the chromosome information + for ( int i = 0 ; i < fpSam->header->n_targets ; ++i ) + { + std::string s( fpSam->header->target_name[i] ) ; + chrNameToId[s] = i ; + } + opened = true ; + } +public: + struct _pair segments[MAX_SEG_COUNT] ; + unsigned int segCnt ; + + Alignments() { b = NULL ; opened = false ; onlyChromId = -1 ; } + ~Alignments() {} + + void Open( char *file ) + { + strcpy( fileName, file ) ; + Open() ; + } + + void Rewind() + { + Close() ; + Open() ; + } + + void Close() + { + samclose( fpSam ) ; + fpSam = NULL ; + } + + bool IsOpened() + { + return opened ; + } + + int Next() + { + int i ; + int start = 0, len = 0 ; + uint32_t *rawCigar ; + + while ( 1 ) + { + while ( 1 ) + { + if ( b ) + bam_destroy1( b ) ; + b = bam_init1() ; + + if ( samread( fpSam, b ) <= 0 ) + return 0 ; + if ( b->core.flag & 0xC ) + continue ; + + if ( onlyChromId != -1 && onlyChromId != GetChromId() ) + { + continue ; + } + + if ( ( b->core.flag & 0x900 ) == 0 ) + break ; + } + // Compute the exons segments from the reads + segCnt = 0 ; + start = b->core.pos ; //+ 1 ; + rawCigar = bam1_cigar( b ) ; + for ( i = 0 ; i < b->core.n_cigar ; ++i ) + { + int op = rawCigar[i] & BAM_CIGAR_MASK ; + int num = rawCigar[i] >> BAM_CIGAR_SHIFT ; + + switch ( op ) + { + case BAM_CMATCH: + case BAM_CDEL: + len += num ; break ; + case BAM_CINS: + case BAM_CSOFT_CLIP: + case BAM_CHARD_CLIP: + case BAM_CPAD: + num = 0 ; break ; + case BAM_CREF_SKIP: + { + segments[ segCnt ].a = start ; + segments[ segCnt ].b = start + len - 1 ; + ++segCnt ; + start = start + len + num ; + len = 0 ; + } break ; + default: + len += num ; break ; + } + } + segments[ segCnt ].a = start ; + segments[ segCnt ].b = start + len - 1 ; + ++segCnt ; + + /*for ( i = 0 ; i < segCnt ; ++i ) + printf( "(%d %d) ", segments[i].a, segments[i].b ) ; + printf( "\n" ) ;*/ + + // Check whether the mates are compatible + int mChrId = b->core.mtid ; + int64_t mPos = b->core.mpos ; + + if ( b->core.mtid == b->core.tid ) + { + for ( i = 0 ; i < segCnt - 1 ; ++i ) + { + if ( mPos >= segments[i].b && mPos <= segments[i + 1].a ) + break ; + } + if ( i < segCnt - 1 ) + continue ; + } + + break ; + } + + return 1 ; + } + + + int GetChromId() + { + return b->core.tid ; + } + + char* GetChromName( int tid ) + { + return fpSam->header->target_name[ tid ] ; + } + + int GetChromIdFromName( const char *s ) + { + std::string ss( s ) ; + if ( chrNameToId.find( ss ) == chrNameToId.end() ) + { + printf( "Unknown genome name: %s\n", s ) ; + exit( 1 ) ; + } + return chrNameToId[ss] ; + } + + int GetChromLength( int tid ) + { + return fpSam->header->target_len[ tid ] ; + } + + void GetMatePosition( int &chrId, int64_t &pos ) + { + chrId = b->core.mtid ; + pos = b->core.mpos ; //+ 1 ; + } + + int GetRepeatPosition( int &chrId, int64_t &pos ) + { + // Look at the CC field. + if ( !bam_aux_get( b, "CC" ) || !bam_aux_get( b, "CP" ) ) + { + chrId = -1 ; + pos = -1 ; + return 0 ; + } + + std::string s( bam_aux2Z( bam_aux_get(b, "CC" ) ) ) ; + chrId = chrNameToId[ s ] ; + pos = bam_aux2i( bam_aux_get( b, "CP" ) ) ;// Possible error for 64bit + return 1 ; + } + + bool IsReverse() + { + if ( b->core.flag & 0x10 ) + return true ; + return false ; + } + + bool IsMateReverse() + { + if ( b->core.flag & 0x20 ) + return true ; + return false ; + } + + char *GetReadId() + { + return bam1_qname( b ) ; + } + + bool IsUnique() + { + if ( bam_aux_get( b, "NH" ) ) + { + if ( bam_aux2i( bam_aux_get( b, "NH" ) ) > 1 ) + return false ; + } + return true ; + } + + int GetFieldI( char *f ) + { + if ( bam_aux_get( b, f ) ) + { + return bam_aux2i( bam_aux_get( b, f ) ) ; + } + return -1 ; + } + + char *GetFieldZ( char *f ) + { + if ( bam_aux_get( b, f ) ) + { + return bam_aux2Z( bam_aux_get( b, f ) ) ; + } + return NULL ; + } + + // -1:minus, 0: unknown, 1:plus + int GetStrand() + { + if ( segCnt == 1 ) + return 0 ; + if ( bam_aux_get( b, "XS" ) ) + { + if ( bam_aux2A( bam_aux_get( b, "XS" ) ) == '-' ) + return -1 ; + else + return 1 ; + } + else + return 0 ; + } + + void OnlyChrom( const char *chr ) + { + onlyChromId = GetChromIdFromName( chr ) ; + } +} ; +#endif diff --git a/li_hla/defs.h b/li_hla/defs.h new file mode 100644 index 0000000..55f0649 --- /dev/null +++ b/li_hla/defs.h @@ -0,0 +1,19 @@ +#ifndef _LSONG_RSCAF_DEFS_HEADER +#define _LSONG_RSCAF_DEFS_HEADER + +#include + +#define MAX_SEG_COUNT 127 + +struct _pair +{ + int64_t a, b ; +} ; + +char nucToNum[26] = { 0, -1, 1, -1, -1, -1, 2, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 3, + -1, -1, -1, -1, -1, -1 } ; + +char numToNuc[26] = {'A', 'C', 'G', 'T'} ; +#endif diff --git a/li_hla/main.cpp b/li_hla/main.cpp new file mode 100644 index 0000000..fcf7b4d --- /dev/null +++ b/li_hla/main.cpp @@ -0,0 +1,484 @@ +//usage: a.out prefix_of_allele_information alignment.bam [-b backbone_id] +#include +#include +#include +#include +#include +#include + +#include "alignments.hpp" + + +struct _compatible +{ + int weight ; + double value ; +} ; + +struct _snpInfo +{ + char type ; // d, s, i + int position ; + char nucleotide ; + int length ; +} ; + +struct _mdComponent +{ + char type ; + int length ; + int num ; +} ; + +struct _result +{ + int a, b ; + double logLikelihood ; +} ; + +std::map snpNameToId ; + +std::map alleleNameToId ; +std::vector alleleIdToName ; + + +std::vector snpInfo ; // When using this, we already convert the snp name into snp id +std::vector< std::vector > snpLink ; // What are the allele ids associate with the snp id +std::map > positionToSnp ; // map of the genomic coordinate to the snp id +std::vector< std::vector > alleleSnpList ; // the list of snp ids associate with this allele +std::vector alleleLength ; +std::vector< struct _pair > alignmentCoords ; + +bool CompResult( struct _result a, struct _result b ) +{ + return a.logLikelihood > b.logLikelihood ; +} + +void Split( const char *s, char delimit, std::vector &fields ) +{ + int i ; + fields.clear() ; + if ( s == NULL ) + return ; + + std::string f ; + for ( i = 0 ; s[i] ; ++i ) + { + if ( s[i] == delimit || s[i] == '\n' ) + { + fields.push_back( f ) ; + f.clear() ; + } + else + f.append( 1, s[i] ) ; + } + fields.push_back( f ) ; + f.clear() ; +} + +int main( int argc, char *argv[] ) +{ + int i, j, k ; + FILE *fp ; + char buffer[10100] ; + std::vector fields ; + int binSize = 50 ; + const char *backboneName = NULL ; + + // the compatilibity between the alignment and allele + // The likelihood of this read from this allele + struct _compatible **compatibility ; + int **snpAllele ; // whether a snp showed up in the allele. + + Alignments alignments ; + alignments.Open( argv[2] ) ; + + for ( i = 3 ; i < argc ; ++i ) + { + if ( !strcmp( argv[i], "-b" ) ) + { + backboneName = argv[i + 1] ; + alignments.OnlyChrom( backboneName ) ; + ++i ; + } + else + { + fprintf( stderr, "Unknown argument %s.\n", argv[i] ) ; + exit( 1 ) ; + } + } + + // Parse the files associate with the snps + // Firstly, read in the snp list have the information + sprintf( buffer, "%s.snp", argv[1] ) ; + fp = fopen( buffer, "r" ) ; + k = 0 ; + while ( fgets( buffer, sizeof( buffer ), fp ) ) + { + Split( buffer, '\t', fields ) ; + if ( backboneName && strcmp( fields[2].c_str(), backboneName ) ) + continue ; + snpNameToId[ fields[0] ] = k ; + struct _snpInfo info ; + info.type = fields[1][0] ; + if ( info.type == 'd' ) + { + info.position = atoi( fields[3].c_str() ) ; + info.length = atoi( fields[4].c_str() ) ; + } + else if ( info.type == 'i' ) + { + info.position = atoi( fields[3].c_str() ) ; + info.length = strlen( fields[4].c_str() ) ; + } + else + { + info.position = atoi( fields[3].c_str() ) ; // notice that the snp file is 0-based index. + info.length = 1 ; + info.nucleotide = fields[4][0] ; + } + snpInfo.push_back( info ) ; + std::vector< int > tmpList ; + snpLink.push_back( tmpList ) ; + for ( int p = 0 ; p < info.length ; ++p ) + { + if ( info.type != 'i' || p == 0 ) + { + if ( positionToSnp.find( info.position + p ) == positionToSnp.end() ) + { + positionToSnp[ info.position + p] = tmpList ; + } + positionToSnp[ info.position + p].push_back( k ) ; + } + } + ++k ; + } + fclose( fp ) ; + // Read in the link file. Determine the id of alleles and the association + // of alleles and snps. + // TODO: obtain the length of each allele and take the length into account in the statistical model + // Add the id for the backbound + int backboneLength = 0 ; + sprintf( buffer, "%s_backbone.fa", argv[1] ) ; + fp = fopen( buffer, "r" ) ; + /*for ( i = 1 ; buffer[i] && buffer[i] != ' ' && buffer[i] != '\n' ; ++i ) + ; + buffer[i] = '\0' ; + std::string backboneName( buffer + 1 ) ; + alleleNameToId[ backboneName ] = 0 ; + alleleIdToName.push_back( backboneName ) ;*/ + bool start = false ; + while ( fgets( buffer, sizeof( buffer ), fp ) ) + { + if ( buffer[0] == '>' ) + { + for ( i = 1 ; buffer[i] && buffer[i] != ' ' && buffer[i] != '\n' ; ++i ) + ; + buffer[i] = '\0' ; + if ( !strcmp( backboneName, buffer + 1 ) ) + { + start = true ; + } + else if ( start ) + break ; + } + if ( start && buffer[0] != '>' ) + { + int len = strlen( buffer ) ; + if ( buffer[len - 1 ] == '\n' ) + backboneLength += len - 1 ; + else + backboneLength += len ; + } + } + fclose( fp ) ; + /*k = 0 ; + if ( k == 0 ) + { + std::vector tmpList ; + alleleSnpList.push_back( tmpList ) ; + alleleLength.push_back( backboneLength ) ; + }*/ + + + // scanning the link file + sprintf( buffer, "%s.link", argv[1] ) ; + fp = fopen( buffer, "r" ) ; + k = 0 ; + while ( fgets( buffer, sizeof( buffer ), fp ) ) + { + std::vector tmpFields ; + Split( buffer, '\t', tmpFields ) ; + // skip the snps from other backbones + if ( snpNameToId.find( tmpFields[0] ) == snpNameToId.end() ) + continue ; + + int snpId = snpNameToId[ tmpFields[0] ] ; + Split( tmpFields[1].c_str(), ' ', fields ) ; + int size = fields.size() ; + + for ( i = 0 ; i < size ; ++i ) + { + if ( alleleNameToId.find( fields[i] ) == alleleNameToId.end() ) + { + //printf( "%s %d\n", fields[i].c_str(), k ) ; + alleleNameToId[ fields[i] ] = k ; + alleleIdToName.push_back( fields[i] ) ; + std::vector tmpList ; + alleleSnpList.push_back( tmpList ) ; + alleleLength.push_back( backboneLength ) ; + ++k ; + } + + int alleleId = alleleNameToId[ fields[i] ] ; + //if ( snpId == 118 ) + // printf( "%s: %s %d\n", tmpFields[0].c_str(), fields[i].c_str(), alleleId ) ; + snpLink[ snpId ].push_back( alleleId ) ; + alleleSnpList[ alleleId ].push_back( snpId ) ; + if ( snpInfo[ snpId ].type == 'd' ) + { + alleleLength[ alleleId ] -= snpInfo[ snpId ].length ; + } + else if ( snpInfo[ snpId ].type == 'i' ) + { + alleleLength[ alleleId ] += snpInfo[ snpId ].length ; + } + } + } + fclose( fp ) ; + int numOfAllele = alleleIdToName.size() ; + int numOfSnps = snpLink.size() ; + snpAllele = new int* [numOfSnps] ; + for ( i = 0 ; i < numOfSnps ; ++i ) + { + snpAllele[i] = new int[numOfAllele] ; + memset( snpAllele[i], 0, sizeof( int ) * numOfAllele ) ; + } + for ( i = 0 ; i < numOfSnps ; ++i ) + { + int size = snpLink[i].size() ; + for ( j = 0 ; j < size ; ++j ) + { + snpAllele[i][ snpLink[i][j] ] = 1 ; + } + } + + // Compute the compatbility score for each alignment and the allele + // Get the number of alignment + int numOfAlignments = 0 ; + while ( alignments.Next() ) + ++numOfAlignments ; + + alignments.Rewind() ; + + compatibility = new struct _compatible*[numOfAlignments] ; + for ( i = 0 ; i < numOfAlignments ; ++i ) + { + compatibility[i] = new struct _compatible[ numOfAllele ] ; + for ( j = 0 ; j < numOfAllele ; ++j ) + { + compatibility[i][j].value = 0 ;//-log( (double)alleleLength[j] ) / log( 10.0 ); + } + } + + i = 0 ; + bool *snpHit = new bool[ numOfSnps ] ; + while ( alignments.Next() ) + { + struct _pair coord = alignments.segments[0] ; + alignmentCoords.push_back( coord ) ; + memset( snpHit, 0, sizeof( bool ) * numOfSnps ) ; + Split( alignments.GetFieldZ( "Zs" ), ',', fields ) ; + int size = fields.size() ; + for ( k = 0 ; k < size ; ++k ) + { + std::vector subfields ; + Split( fields[k].c_str(), '|', subfields ) ; + int snpId = snpNameToId[ subfields[2] ] ; + snpHit[ snpId ] = true ; + } + + for ( k = coord.a ; k <= coord.b ; ++k ) + { + int size = positionToSnp[k].size() ; + for ( int l = 0 ; l < size ; ++l ) + { + // if this SNP is hit. Then other allele don't have this snp + // will deduct its likelihood + //TODO: the deduction can be based on the quality score of the read + int tag = 0 ; + int snpId = positionToSnp[k][l] ; + + if ( snpHit[ snpId ] ) + { + tag = 0 ; + } + else + { + // if this SNP is not hit, then every allele containing this snp + // will deduct its likelihood + tag = 1 ; + } + for ( j = 0 ; j < numOfAllele ; ++j ) + { + if ( snpAllele[ snpId ][j] == tag ) + { + int v = -2 ; + //if ( snpInfo[ snpId ].type == 'd' || snpInfo[ snpId ].type == 'i' ) + // v = -4 * snpInfo[ snpId ].length ; + if ( snpInfo[ snpId ].type == 'd' && snpInfo[ snpId ].position < k + && k != coord.a ) + { + // The penality has already been subtracted. + v = 0 ; + } + compatibility[i][j].value += v ; + /*if ( i == 8 && j == 78 ) + { + printf( "Bad snp %d: %d %d\n", tag, k, positionToSnp[k][l] ) ; + }*/ + } + } + } + } + ++i ; + } + //printf( "%d %d\n", numOfAlignments, numOfAllele ) ; + // Now, let's consider every pair of alleles, and compute its log likelihood + double **logLikelihood ; + logLikelihood = new double *[ numOfAllele] ; + for ( j = 0 ; j < numOfAllele ; ++j ) + { + logLikelihood[j] = new double[ numOfAllele ] ; + //memset( logLikelihood[j], 0, sizeof( double ) * numOfAllele ) ; + for ( k = 0 ; k < numOfAllele ; ++k ) + logLikelihood[j][k] = 0 ; + } + + int prevBin = -1 ; + double assignJBin = 0 ; + double assignKBin = 0 ; + for ( j = 0 ; j < numOfAllele ; ++j ) + { + for ( k = j ; k < numOfAllele ; ++k ) + { + double binAdjust = 0 ; + double averageRead = ( (double)numOfAlignments ) / (double)( alleleLength[j] + alleleLength[k] ) * binSize ; + for ( i = 0 ; i < numOfAlignments ; ++i ) + { + double vj = compatibility[i][j].value ; + double vk = compatibility[i][k].value ; + double weightJ = 0, weightK = 0 ; + if ( vj == vk ) + { + weightJ = weightK = 0.5 ; + } + else if ( vj == vk + 2 ) + { + if ( vj == 0 ) + { + weightJ = 1 ; + } + else + { + weightJ = 0.99 ; + weightK = 0.01 ; + } + } + else if ( vk == vj + 2 ) + { + if ( vk == 0 ) + { + weightK = 1 ; + } + else + { + weightJ = 0.01 ; + weightK = 0.99 ; + } + } + else + { + if ( vk > vj ) + weightK = 1 ; + else + weightJ = 1 ; + } + + double l = weightJ * compatibility[i][j].value + weightK * compatibility[i][k].value ; + if ( alignmentCoords[i].a / binSize != prevBin ) + { + if ( prevBin != -1 && + ( assignJBin > averageRead + 4 * sqrt( averageRead ) + || assignKBin > averageRead + 4 * sqrt( averageRead ) ) ) + { + //if ( j == 8 && k == 78 ) + // printf( "%lf: %lf %lf %d %d\n", averageRead, assignJBin, assignKBin, alleleLength[j], alleleLength[k] ) ; + binAdjust -= 4 ; + } + prevBin = alignmentCoords[i].a / binSize ; + assignJBin = 0 ; + assignKBin = 0 ; + } + assignJBin += weightJ ; + assignKBin += weightK ; + + /*if ( j == 8 && k == 78 && l < 0 ) + { + printf( "Bad alignment %d (%s %s). %lf %lf: %lf\n", i, + alleleIdToName[j].c_str(), alleleIdToName[k].c_str(), + compatibility[i][j].value, compatibility[i][k].value, l ) ; + }*/ + logLikelihood[j][k] += l ; + } + logLikelihood[j][k] += ( -log( (double)alleleLength[j] ) / log(10.0 ) - + log( (double)alleleLength[k] ) / log(10.0) ) ; + logLikelihood[j][k] += binAdjust ; + } + } + + // Find the result + double max ; + int maxj = -1 ; + int maxk = -1 ; + std::vector< struct _result > results ; + for ( j = 0 ; j < numOfAllele ; ++j ) + { + for ( k = j ; k < numOfAllele ; ++k ) + { + if ( maxj == -1 || logLikelihood[j][k] > max ) + { + maxj = j ; + maxk = k ; + max = logLikelihood[j][k] ; + } + struct _result r ; + r.a = j ; + r.b = k ; + r.logLikelihood = logLikelihood[j][k] ; + results.push_back( r ) ; + } + } + + //printf( "%s %s %lf\n", alleleIdToName[ maxj ].c_str(), alleleIdToName[ maxk ].c_str(), max) ; + //printf( "%lf\n", logLikelihood[124][128] ) ; + + if ( results.size() == 0 ) + { + printf( "-1 -1 -1\n" ) ; + exit( 1 ) ; + } + std::sort( results.begin(), results.end(), CompResult ) ; + i = 0 ; + printf( "%s %s %lf\n", alleleIdToName[ results[i].a ].c_str(), alleleIdToName[ results[i].b ].c_str(), + results[i].logLikelihood ) ; + k = results.size() ; + for ( i = 1 ; i < k ; ++i ) + { + if ( results[i].logLikelihood != results[0].logLikelihood ) + break ; + printf( "%s %s %lf\n", alleleIdToName[ results[i].a ].c_str(), alleleIdToName[ results[i].b ].c_str(), + results[i].logLikelihood ) ; + } + return 0 ; +} diff --git a/limit.cpp b/limit.cpp new file mode 100644 index 0000000..1146090 --- /dev/null +++ b/limit.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "limit.h" + +uint8_t MIN_U8 = std::numeric_limits::min(); +uint8_t MAX_U8 = std::numeric_limits::max(); +uint16_t MIN_U16 = std::numeric_limits::min(); +uint16_t MAX_U16 = std::numeric_limits::max(); +uint32_t MIN_U32 = std::numeric_limits::min(); +uint32_t MAX_U32 = std::numeric_limits::max(); +uint64_t MIN_U64 = std::numeric_limits::min(); +uint64_t MAX_U64 = std::numeric_limits::max(); +size_t MIN_SIZE_T = std::numeric_limits::min(); +size_t MAX_SIZE_T = std::numeric_limits::max(); + +int MIN_I = std::numeric_limits::min(); +int MAX_I = std::numeric_limits::max(); +int8_t MIN_I8 = std::numeric_limits::min(); +int8_t MAX_I8 = std::numeric_limits::max(); +int16_t MIN_I16 = std::numeric_limits::min(); +int16_t MAX_I16 = std::numeric_limits::max(); +int32_t MIN_I32 = std::numeric_limits::min(); +int32_t MAX_I32 = std::numeric_limits::max(); +int64_t MIN_I64 = std::numeric_limits::min(); +int64_t MAX_I64 = std::numeric_limits::max(); diff --git a/limit.h b/limit.h new file mode 100644 index 0000000..06ea072 --- /dev/null +++ b/limit.h @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef LIMIT_H_ +#define LIMIT_H_ + +#include +#include + +extern uint8_t MIN_U8; +extern uint8_t MAX_U8; +extern uint16_t MIN_U16; +extern uint16_t MAX_U16; +extern uint32_t MIN_U32; +extern uint32_t MAX_U32; +extern uint64_t MIN_U64; +extern uint64_t MAX_U64; +extern size_t MIN_SIZE_T; +extern size_t MAX_SIZE_T; + +extern int MIN_I; +extern int MAX_I; +extern int8_t MIN_I8; +extern int8_t MAX_I8; +extern int16_t MIN_I16; +extern int16_t MAX_I16; +extern int32_t MIN_I32; +extern int32_t MAX_I32; +extern int64_t MIN_I64; +extern int64_t MAX_I64; + +#endif diff --git a/ls.cpp b/ls.cpp new file mode 100644 index 0000000..96c28c0 --- /dev/null +++ b/ls.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifdef MAIN_LS + +#include +#include +#include "sstring.h" +#include "ls.h" +#include "ds.h" + +using namespace std; + +int main(void) { + cerr << "Test LarssonSadakana for int..."; + { + typedef int T; + const char *t = "banana"; + EList sa; + EList isa; + for(size_t i = 0; i < strlen(t); i++) { + isa.push_back(t[i]); + } + isa.push_back(0); // disregarded + sa.resize(isa.size()); + LarssonSadakane ls; + ls.suffixsort(isa.ptr(), sa.ptr(), (T)sa.size()-1, 'z', 0); + assert_eq((T)'a', t[sa[1]]); assert_eq(5, sa[1]); + assert_eq((T)'a', t[sa[2]]); assert_eq(3, sa[2]); + assert_eq((T)'a', t[sa[3]]); assert_eq(1, sa[3]); + assert_eq((T)'b', t[sa[4]]); assert_eq(0, sa[4]); + assert_eq((T)'n', t[sa[5]]); assert_eq(4, sa[5]); + assert_eq((T)'n', t[sa[6]]); assert_eq(2, sa[6]); + } + cerr << "PASSED" << endl; + + cerr << "Test LarssonSadakana for uint32_t..."; + { + typedef uint32_t T; + const char *t = "banana"; + EList sa; + EList isa; + for(size_t i = 0; i < strlen(t); i++) { + isa.push_back(t[i]); + } + isa.push_back(0); // disregarded + sa.resize(isa.size()); + LarssonSadakane ls; + ls.suffixsort( + (int*)isa.ptr(), + (int*)sa.ptr(), + (int)sa.size()-1, + 'z', + 0); + assert_eq((T)'a', t[sa[1]]); assert_eq(5, sa[1]); + assert_eq((T)'a', t[sa[2]]); assert_eq(3, sa[2]); + assert_eq((T)'a', t[sa[3]]); assert_eq(1, sa[3]); + assert_eq((T)'b', t[sa[4]]); assert_eq(0, sa[4]); + assert_eq((T)'n', t[sa[5]]); assert_eq(4, sa[5]); + assert_eq((T)'n', t[sa[6]]); assert_eq(2, sa[6]); + } + cerr << "PASSED" << endl; + + cerr << "Last elt is < or > others ..."; + { + { + typedef int T; + const char *t = "aaa"; + EList sa; + EList isa; + for(size_t i = 0; i < strlen(t); i++) { + isa.push_back(t[i]); + } + isa.push_back(0); // disregarded + sa.resize(isa.size()); + LarssonSadakane ls; + ls.suffixsort(isa.ptr(), sa.ptr(), (T)sa.size()-1, 'z', 0); + assert_eq(3, sa[0]); + assert_eq(2, sa[1]); + assert_eq(1, sa[2]); + assert_eq(0, sa[3]); + } + + { + typedef int T; + const char *t = "aaa"; + EList sa; + EList isa; + for(size_t i = 0; i < strlen(t); i++) { + isa.push_back(t[i]); + } + isa.push_back('y'); // doesn't matter if this is > others + sa.resize(isa.size()); + LarssonSadakane ls; + ls.suffixsort(isa.ptr(), sa.ptr(), (T)sa.size()-1, 'z', 0); + assert_eq(3, sa[0]); + assert_eq(2, sa[1]); + assert_eq(1, sa[2]); + assert_eq(0, sa[3]); + } + + { + typedef int T; + const char *t = "aaa"; + EList sa; + EList isa; + for(size_t i = 0; i < strlen(t); i++) { + isa.push_back(t[i]); + } + isa.push_back('y'); // breaks ties + isa.push_back(0); // disregarded + sa.resize(isa.size()); + LarssonSadakane ls; + ls.suffixsort(isa.ptr(), sa.ptr(), (T)sa.size()-1, 'z', 0); + assert_eq(4, sa[0]); + assert_eq(0, sa[1]); + assert_eq(1, sa[2]); + assert_eq(2, sa[3]); + assert_eq(3, sa[4]); + } + + } + cerr << "PASSED" << endl; +} + +#endif diff --git a/ls.h b/ls.h new file mode 100644 index 0000000..e333f7c --- /dev/null +++ b/ls.h @@ -0,0 +1,333 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* Code in this file is ultimately based on: + + qsufsort.c + Copyright 1999, N. Jesper Larsson, all rights reserved. + + This file contains an implementation of the algorithm presented in "Faster + Suffix Sorting" by N. Jesper Larsson (jesper@cs.lth.se) and Kunihiko + Sadakane (sada@is.s.u-tokyo.ac.jp). + + This software may be used freely for any purpose. However, when distributed, + the original source must be clearly stated, and, when the source code is + distributed, the copyright notice must be retained and any alterations in + the code must be clearly marked. No warranty is given regarding the quality + of this software.*/ + +#ifndef LS_H_ +#define LS_H_ + +#include +#include +#include + +template +class LarssonSadakane { + T *I, /* group array, ultimately suffix array.*/ + *V, /* inverse array, ultimately inverse of I.*/ + r, /* number of symbols aggregated by transform.*/ + h; /* length of already-sorted prefixes.*/ + + #define LS_KEY(p) (V[*(p)+(h)]) + #define LS_SWAP(p, q) (tmp=*(p), *(p)=*(q), *(q)=tmp) + #define LS_SMED3(a, b, c) (LS_KEY(a)LS_KEY(c) ? (b) : LS_KEY(a)>LS_KEY(c) ? (c) : (a))) + + /* Subroutine for select_sort_split and sort_split. Sets group numbers for a + group whose lowest position in I is pl and highest position is pm.*/ + + inline void update_group(T *pl, T *pm) { + T g; + g=(T)(pm-I); /* group number.*/ + V[*pl]=g; /* update group number of first position.*/ + if (pl==pm) + *pl=-1; /* one element, sorted group.*/ + else + do /* more than one element, unsorted group.*/ + V[*++pl]=g; /* update group numbers.*/ + while (pl>1); /* small arrays, middle element.*/ + if (n>7) { + pl=p; + pn=p+n-1; + if (n>40) { /* big arrays, pseudomedian of 9.*/ + s=n>>3; + pl=LS_SMED3(pl, pl+s, pl+s+s); + pm=LS_SMED3(pm-s, pm, pm+s); + pn=LS_SMED3(pn-s-s, pn-s, pn); + } + pm=LS_SMED3(pl, pm, pn); /* midsize arrays, median of 3.*/ + } + return LS_KEY(pm); + } + + /* Sorting routine called for each unsorted group. Sorts the array of integers + (suffix numbers) of length n starting at p. The algorithm is a ternary-split + quicksort taken from Bentley & McIlroy, "Engineering a Sort Function", + Software -- Practice and Experience 23(11), 1249-1265 (November 1993). This + function is based on Program 7.*/ + + inline void sort_split(T *p, T n) + { + T *pa, *pb, *pc, *pd, *pl, *pm, *pn; + T f, v, s, t, tmp; + + if (n<7) { /* multi-selection sort smallest arrays.*/ + select_sort_split(p, n); + return; + } + + v=choose_pivot(p, n); + pa=pb=p; + pc=pd=p+n-1; + while (1) { /* split-end partition.*/ + while (pb<=pc && (f=LS_KEY(pb))<=v) { + if (f==v) { + LS_SWAP(pa, pb); + ++pa; + } + ++pb; + } + while (pc>=pb && (f=LS_KEY(pc))>=v) { + if (f==v) { + LS_SWAP(pc, pd); + --pd; + } + --pc; + } + if (pb>pc) + break; + LS_SWAP(pb, pc); + ++pb; + --pc; + } + pn=p+n; + if ((s=(T)(pa-p))>(t=(T)(pb-pa))) + s=t; + for (pl=p, pm=pb-s; s; --s, ++pl, ++pm) + LS_SWAP(pl, pm); + if ((s=(T)(pd-pc))>(t=(T)(pn-pd-1))) + s=t; + for (pl=pb, pm=pn-s; s; --s, ++pl, ++pm) + LS_SWAP(pl, pm); + + s=(T)(pb-pa); + t=(T)(pd-pc); + if (s>0) + sort_split(p, s); + update_group(p+s, p+n-t-1); + if (t>0) + sort_split(p+n-t, t); + } + + /* Bucketsort for first iteration. + + Input: x[0...n-1] holds integers in the range 1...k-1, all of which appear + at least once. x[n] is 0. (This is the corresponding output of transform.) k + must be at most n+1. p is array of size n+1 whose contents are disregarded. + + Output: x is V and p is I after the initial sorting stage of the refined + suffix sorting algorithm.*/ + + inline void bucketsort(T *x, T *p, T n, T k) + { + T *pi, i, c, d, g; + + for (pi=p; pi=p; --pi) { + d=x[c=*pi]; /* c is position, d is next in list.*/ + x[c]=g=i; /* last position equals group number.*/ + if (d == 0 || d > 0) { /* if more than one element in group.*/ + p[i--]=c; /* p is permutation for the sorted x.*/ + do { + d=x[c=d]; /* next in linked list.*/ + x[c]=g; /* group number in x.*/ + p[i--]=c; /* permutation in p.*/ + } while (d == 0 || d > 0); + } else + p[i--]=-1; /* one element, sorted group.*/ + } + } + + /* Transforms the alphabet of x by attempting to aggregate several symbols into + one, while preserving the suffix order of x. The alphabet may also be + compacted, so that x on output comprises all integers of the new alphabet + with no skipped numbers. + + Input: x is an array of size n+1 whose first n elements are positive + integers in the range l...k-1. p is array of size n+1, used for temporary + storage. q controls aggregation and compaction by defining the maximum value + for any symbol during transformation: q must be at least k-l; if q<=n, + compaction is guaranteed; if k-l>n, compaction is never done; if q is + INT_MAX, the maximum number of symbols are aggregated into one. + + Output: Returns an integer j in the range 1...q representing the size of the + new alphabet. If j<=n+1, the alphabet is compacted. The global variable r is + set to the number of old symbols grouped into one. Only x[n] is 0.*/ + + inline T transform(T *x, T *p, T n, T k, T l, T q) + { + T b, c, d, e, i, j, m, s; + T *pi, *pj; + + for (s=0, i=k-l; i; i>>=1) + ++s; /* s is number of bits in old symbol.*/ + e=std::numeric_limits::max()>>s; /* e is for overflow checking.*/ + for (b=d=r=0; r=k-l) { /* if bucketing possible,*/ + j=transform(V, I, n, k, l, n); + bucketsort(V, I, n, j); /* bucketsort on first r positions.*/ + } else { + transform(V, I, n, k, l, std::numeric_limits::max()); + for (i=0; i<=n; ++i) + I[i]=i; /* initialize I with suffix numbers.*/ + h=0; + sort_split(I, n+1); /* quicksort on first r positions.*/ + } + h=r; /* number of symbols aggregated by transform.*/ + + while (*I>=-n) { + pi=I; /* pi is first position of group.*/ + sl=0; /* sl is negated length of sorted groups.*/ + do { + if ((s=*pi) <= 0 && (s=*pi) != 0) { + pi-=s; /* skip over sorted group.*/ + sl+=s; /* add negated length to sl.*/ + } else { + if (sl) { + *(pi+sl)=sl; /* combine sorted groups before pi.*/ + sl=0; + } + pk=I+V[s]+1; /* pk-1 is last position of unsorted group.*/ + sort_split(pi, (T)(pk-pi)); + pi=pk; /* next group.*/ + } + } while (pi<=I+n); + if (sl) /* if the array ends with a sorted group.*/ + *(pi+sl)=sl; /* combine sorted groups at end of I.*/ + h=2*h; /* double sorted-depth.*/ + } + + for (i=0; i<=n; ++i) /* reconstruct suffix array from inverse.*/ + I[V[i]]=i; + } +}; + +#endif /*def LS_H_*/ diff --git a/mask.cpp b/mask.cpp new file mode 100644 index 0000000..ffefdc7 --- /dev/null +++ b/mask.cpp @@ -0,0 +1,36 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "mask.h" + +// 5-bit pop count +int alts5[32] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5 +}; + +// Index of lowest set bit +int firsts5[32] = { + -1, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, + 3, 0, 1, 0, 2, 0, 1, 0 +}; diff --git a/mask.h b/mask.h new file mode 100644 index 0000000..e00c194 --- /dev/null +++ b/mask.h @@ -0,0 +1,79 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef MASK_H_ +#define MASK_H_ + +#include +#include "random_source.h" + +// 5-bit pop count +extern int alts5[32]; + +// Index of lowest set bit +extern int firsts5[32]; + +/** + * Return 1 if a 2-bit-encoded base ('i') matches any bit in the mask ('j') and + * the mask < 16. Returns -1 if either the reference or the read character was + * ambiguous. Returns 0 if the characters unambiguously mismatch. + */ +static inline int matchesEx(int i, int j) { + if(j >= 16 || i > 3) { + // read and/or ref was ambiguous + return -1; + } + return (((1 << i) & j) != 0) ? 1 : 0; +} + +/** + * Return 1 if a 2-bit-encoded base ('i') matches any bit in the mask ('j'). + */ +static inline bool matches(int i, int j) { + return ((1 << i) & j) != 0; +} + +/** + * Given a mask with up to 5 bits, return an index corresponding to a + * set bit in the mask, randomly chosen from among all set bits. + */ +static inline int randFromMask(RandomSource& rnd, int mask) { + assert_gt(mask, 0); + if(alts5[mask] == 1) { + // only one to pick from, pick it via lookup table + return firsts5[mask]; + } + assert_gt(mask, 0); + assert_lt(mask, 32); + int r = rnd.nextU32() % alts5[mask]; + assert_geq(r, 0); + assert_lt(r, alts5[mask]); + // could do the following via lookup table too + for(int i = 0; i < 5; i++) { + if((mask & (1 << i)) != 0) { + if(r == 0) return i; + r--; + } + } + std::cerr << "Shouldn't get here" << std::endl; + throw 1; + return -1; +} + +#endif /*ndef MASK_H_*/ diff --git a/mem_ids.h b/mem_ids.h new file mode 100644 index 0000000..352817b --- /dev/null +++ b/mem_ids.h @@ -0,0 +1,35 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +// For holding index data +#define EBWT_CAT ((int) 1) +// For holding index-building data +#define EBWTB_CAT ((int) 2) +// For holding cache data +#define CA_CAT ((int) 3) +// For holding group-walk-left bookkeeping data +#define GW_CAT ((int) 4) +// For holding alignment bookkeeping data +#define AL_CAT ((int) 5) +// For holding dynamic programming bookkeeping data +#define DP_CAT ((int) 6) +// For holding alignment results and other hit objects +#define RES_CAT ((int) 7) +#define MISC_CAT ((int) 9) +#define DEBUG_CAT ((int)10) diff --git a/mm.h b/mm.h new file mode 100644 index 0000000..00a2335 --- /dev/null +++ b/mm.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef MM_H_ +#define MM_H_ + +/** + * mm.h: + * + * Defines that make it easier to handle files in the two different MM + * contexts: i.e. on Linux and Mac where MM is supported and POSIX I/O + * functions work as expected, and on Windows where MM is not supported + * and where there isn't POSIX I/O, + */ +#if 0 +#ifdef BOWTIE_MM +#define MM_FILE_CLOSE(x) if(x > 3) { close(x); } +#define MM_READ_RET ssize_t +// #define MM_READ read +#define MM_SEEK lseek +#define MM_FILE int +#define MM_FILE_INIT -1 +#else +#define MM_FILE_CLOSE(x) if(x != NULL) { fclose(x); } +#define MM_READ_RET size_t +#define MM_SEEK fseek +#define MM_FILE FILE* +#define MM_FILE_INIT NULL +#endif +#endif + +#define MM_READ(file, dest, sz) fread(dest, 1, sz, file) +#define MM_IS_IO_ERR(file_hd, ret, count) is_fread_err(file_hd, ret, count) + +#endif /* MM_H_ */ diff --git a/msvcc/CodeStubs.vcxproj.filters b/msvcc/CodeStubs.vcxproj.filters new file mode 100644 index 0000000..4622db2 --- /dev/null +++ b/msvcc/CodeStubs.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/msvcc/CoreDefs.props b/msvcc/CoreDefs.props new file mode 100644 index 0000000..ed8b7d4 --- /dev/null +++ b/msvcc/CoreDefs.props @@ -0,0 +1,13 @@ + + + + + + + + typeof=decltype;POPCNT_CAPABILITY;ssize_t=SSIZE_T;NOMINMAX;_CRT_SECURE_NO_WARNINGS;_LARGEFILE_SOURCE;_FILE_OFFSET_BITS=64;_GNU_SOURCE;_MBCS;%(PreprocessorDefinitions) + codeStubs + + + + \ No newline at end of file diff --git a/msvcc/SetVersion.vbs b/msvcc/SetVersion.vbs new file mode 100644 index 0000000..89265b1 --- /dev/null +++ b/msvcc/SetVersion.vbs @@ -0,0 +1,14 @@ + +' ask the scripting runtime environemt for access to files +set FS = CreateObject("Scripting.FileSystemObject") +set FileHandler = FS.GetFile("../VERSION") +set inputTextStream = FileHandler.OpenAsTextStream(1) +version = inputTextStream.ReadLine + +WScript.Echo "Version: " & version + +set outputTextStream = FS.CreateTextFile("../version.h",true) +outputTextStream.WriteLine "#define HISAT2_VERSION """ & version & """" +outputTextStream.close + + diff --git a/msvcc/SysDefs.props b/msvcc/SysDefs.props new file mode 100644 index 0000000..b315948 --- /dev/null +++ b/msvcc/SysDefs.props @@ -0,0 +1,17 @@ + + + + + + + + BUILD_TIME="$([System.DateTime]::Now)";BUILD_HOST="$(VisualStudioEdition) OS ver $(OSVersion)";COMPILER_VERSION="MSC $(MSBuildAssemblyVersion)";COMPILER_OPTIONS="$(NuGetRuntimeIdentifier) Runtime vers $(MSBuildRuntimeVersion)" + "version.h" + + + + + + + + \ No newline at end of file diff --git a/msvcc/codeStubs.vcxproj b/msvcc/codeStubs.vcxproj new file mode 100644 index 0000000..b3de4a6 --- /dev/null +++ b/msvcc/codeStubs.vcxproj @@ -0,0 +1,105 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + {08C70FF5-9E0C-42DF-B7BF-C1AF1B0D2CFF} + win32stubs + 8.1 + + + + StaticLibrary + true + v140 + MultiByte + + + StaticLibrary + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + _CRT_SECURE_NO_WARNINGS + + + true + + + cscript.exe SetVersion.vbs + ../version.h; + ../VERSION; + Setting version info + + + + + Level3 + MaxSpeed + true + true + true + _CRT_SECURE_NO_WARNINGS;NDEBUG + MultiThreaded + + + true + true + true + + + cscript.exe SetVersion.vbs + ../version.h; + ../VERSION; + Setting version info + + + + + + + \ No newline at end of file diff --git a/msvcc/codeStubs/getopt.c b/msvcc/codeStubs/getopt.c new file mode 100644 index 0000000..8a03080 --- /dev/null +++ b/msvcc/codeStubs/getopt.c @@ -0,0 +1,1058 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 2005 Free Software Foundation, Inc. + + NOTE: This source is derived from an old version taken from the GNU C + Library (glibc). + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#ifdef _WIN32 +#include +#define ATTRIBUTE_UNUSED +#else +#include "ansidecl.h" +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# if HAVE_STRINGS_H +# include +# endif +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#if HAVE_STDLIB_H && HAVE_DECL_GETENV +# include +#elif !defined(getenv) +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ +extern char *getenv (const char *); +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif + +static char * +my_index (const char *str, int chr) +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (char **argv) +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = (char *) malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (int argc ATTRIBUTE_UNUSED, + char *const *argv ATTRIBUTE_UNUSED, + const char *optstring) +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (int argc, char *const *argv, const char *optstring, + const struct option *longopts, + int *longind, int long_only) +{ + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/msvcc/codeStubs/getopt.h b/msvcc/codeStubs/getopt.h new file mode 100644 index 0000000..0b46fdc --- /dev/null +++ b/msvcc/codeStubs/getopt.h @@ -0,0 +1,154 @@ +/* Declarations for getopt. + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000, + 2002 Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifndef __STDC__ +#define __STDC__ 1 +#define __STDC__UNDEF__ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if defined (__STDC__) && __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if defined (__STDC__) && __STDC__ +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is + undefined, we haven't run the autoconf check so provide the + declaration without arguments. If it is 0, we checked and failed + to find the declaration so provide a fully prototyped one. If it + is 1, we found it so don't provide any declaration at all. */ +#if !HAVE_DECL_GETOPT +#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in unistd.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else +#ifndef __cplusplus +extern int getopt (); +#endif /* __cplusplus */ +#endif +#endif /* !HAVE_DECL_GETOPT */ + +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#ifdef __STDC__UNDEF__ +#undef __STDC__ +#endif + + +#endif /* getopt.h */ diff --git a/msvcc/codeStubs/getopt1.c b/msvcc/codeStubs/getopt1.c new file mode 100644 index 0000000..255b144 --- /dev/null +++ b/msvcc/codeStubs/getopt1.c @@ -0,0 +1,180 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2005 + Free Software Foundation, Inc. + + NOTE: This source is derived from an old version taken from the GNU C + Library (glibc). + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +#include "getopt.h" + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (int argc, char **argv) +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/msvcc/codeStubs/sys/time.cpp b/msvcc/codeStubs/sys/time.cpp new file mode 100644 index 0000000..666835c --- /dev/null +++ b/msvcc/codeStubs/sys/time.cpp @@ -0,0 +1,57 @@ +#include +#include + +/* +* This file is a copy of the public domain code that can be found in +* multiple locations and whose prevenance is unclear +* +* This is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Bowtie 2. If not, see . +*/ + +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + FILETIME ft; + unsigned __int64 tmpres = 0; + static int tzflag; + + if (NULL != tv) + { + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + /*converting file time to unix epoch*/ + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tmpres /= 10; /*convert into microseconds*/ + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + if (NULL != tz) + { + if (!tzflag) + { + _tzset(); + tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} + diff --git a/msvcc/codeStubs/sys/time.h b/msvcc/codeStubs/sys/time.h new file mode 100644 index 0000000..e9c7442 --- /dev/null +++ b/msvcc/codeStubs/sys/time.h @@ -0,0 +1,15 @@ + +#ifndef TIME_STUB_H +#define TIME_STUB_H + +#include //For timeval defn + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +int gettimeofday(struct timeval *tv, struct timezone *tz); + + +#endif \ No newline at end of file diff --git a/msvcc/codeStubs/unistd.h b/msvcc/codeStubs/unistd.h new file mode 100644 index 0000000..e69de29 diff --git a/msvcc/hisat2-align-l.vcxproj b/msvcc/hisat2-align-l.vcxproj new file mode 100644 index 0000000..237a473 --- /dev/null +++ b/msvcc/hisat2-align-l.vcxproj @@ -0,0 +1,121 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + {08c70ff5-9e0c-42df-b7bf-c1af1b0d2cff} + + + {d281e44b-92e9-4cea-a666-b05530f65000} + + + {e1f391b2-4a3f-43ca-9192-14536abe783e} + + + + {55F86D23-4245-4050-BD2D-CC5D4FD0C36B} + hsat2alignl + 8.1 + hisat2-align-l + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + + Level3 + Disabled + true + BOWTIE_64BIT_INDEX;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + "version.h" + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + true + BOWTIE_64BIT_INDEX;NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + "version.h" + + + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/hisat2-align-l.vcxproj.filters b/msvcc/hisat2-align-l.vcxproj.filters new file mode 100644 index 0000000..a8bc380 --- /dev/null +++ b/msvcc/hisat2-align-l.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/hisat2-align-s.vcxproj b/msvcc/hisat2-align-s.vcxproj new file mode 100644 index 0000000..501ce19 --- /dev/null +++ b/msvcc/hisat2-align-s.vcxproj @@ -0,0 +1,124 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + {08c70ff5-9e0c-42df-b7bf-c1af1b0d2cff} + + + {43f946a8-9184-456b-a522-7b411c10a4eb} + + + {8beeb701-aa26-4d2b-827b-64071f88afb3} + + + + {9D5066DB-ACD2-42E9-BFE6-98C8E7DEA7DA} + hsat2alignl + 8.1 + hisat2-align-s + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + + Level3 + Disabled + true + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + "version.h" + + + + + + + + + + + + true + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + "version.h" + + + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/hisat2-align-s.vcxproj.filters b/msvcc/hisat2-align-s.vcxproj.filters new file mode 100644 index 0000000..a8bc380 --- /dev/null +++ b/msvcc/hisat2-align-s.vcxproj.filters @@ -0,0 +1,25 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/hisat2-build-l.vcxproj b/msvcc/hisat2-build-l.vcxproj new file mode 100644 index 0000000..94dac6a --- /dev/null +++ b/msvcc/hisat2-build-l.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + {08c70ff5-9e0c-42df-b7bf-c1af1b0d2cff} + + + {e1f391b2-4a3f-43ca-9192-14536abe783e} + + + + + + + + + {262E4D55-07C3-4B18-B8E2-F3B6AA4C583E} + hsat2alignl + 8.1 + hisat2-build-l + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + + Level3 + Disabled + true + BOWTIE_64BIT_INDEX;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + "version.h" + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + true + BOWTIE_64BIT_INDEX;NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + "version.h" + + + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/hisat2-build-l.vcxproj.filters b/msvcc/hisat2-build-l.vcxproj.filters new file mode 100644 index 0000000..b29b42d --- /dev/null +++ b/msvcc/hisat2-build-l.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/hisat2-build-s.vcxproj b/msvcc/hisat2-build-s.vcxproj new file mode 100644 index 0000000..7a3e5bd --- /dev/null +++ b/msvcc/hisat2-build-s.vcxproj @@ -0,0 +1,122 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + {08c70ff5-9e0c-42df-b7bf-c1af1b0d2cff} + + + {8beeb701-aa26-4d2b-827b-64071f88afb3} + + + + + + + + + {3B90EEC9-CDFF-424E-B3A3-4B7A5326A43F} + hsat2alignl + 8.1 + hisat2-build-s + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + + + Level3 + Disabled + true + MASSIVE_DATA_RLCSA;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + "version.h" + + + + + + + + + + + + true + + + + + Level3 + MaxSpeed + true + true + true + MASSIVE_DATA_RLCSA;NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + "version.h" + + + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/hisat2-build-s.vcxproj.filters b/msvcc/hisat2-build-s.vcxproj.filters new file mode 100644 index 0000000..b29b42d --- /dev/null +++ b/msvcc/hisat2-build-s.vcxproj.filters @@ -0,0 +1,28 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/hisat2-inspect-l.vcxproj b/msvcc/hisat2-inspect-l.vcxproj new file mode 100644 index 0000000..037afc4 --- /dev/null +++ b/msvcc/hisat2-inspect-l.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {E0A17972-1AF6-429A-A902-3913656B5CFC} + hisat2inspectl + 8.1 + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + BOWTIE_64BIT_INDEX;HISAT2_INSPECT_MAIN _MBCS;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(ForcedIncludeFiles) + + + + + Level3 + MaxSpeed + true + true + true + BOWTIE_64BIT_INDEX;HISAT2_INSPECT_MAIN;NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(ForcedIncludeFiles) + MultiThreaded + + + true + true + + + + + {08c70ff5-9e0c-42df-b7bf-c1af1b0d2cff} + + + {e1f391b2-4a3f-43ca-9192-14536abe783e} + + + + + + + + + \ No newline at end of file diff --git a/msvcc/hisat2-inspect-l.vcxproj.filters b/msvcc/hisat2-inspect-l.vcxproj.filters new file mode 100644 index 0000000..4df5e56 --- /dev/null +++ b/msvcc/hisat2-inspect-l.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/hisat2-inspect-s.vcxproj b/msvcc/hisat2-inspect-s.vcxproj new file mode 100644 index 0000000..a026526 --- /dev/null +++ b/msvcc/hisat2-inspect-s.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {DA85C3F8-8CDD-4ED4-AF86-05B5556670F7} + hisat2inspectl + 8.1 + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + BOWTIE_64BIT_INDEX;HISAT2_INSPECT_MAIN _MBCS;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(ForcedIncludeFiles) + + + + + Level3 + MaxSpeed + true + true + true + HISAT2_INSPECT_MAIN;NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(ForcedIncludeFiles) + MultiThreaded + + + true + true + + + + + {08c70ff5-9e0c-42df-b7bf-c1af1b0d2cff} + + + {8beeb701-aa26-4d2b-827b-64071f88afb3} + + + + + + + + + \ No newline at end of file diff --git a/msvcc/hisat2-inspect-s.vcxproj.filters b/msvcc/hisat2-inspect-s.vcxproj.filters new file mode 100644 index 0000000..4df5e56 --- /dev/null +++ b/msvcc/hisat2-inspect-s.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/search.vcxproj b/msvcc/search.vcxproj new file mode 100644 index 0000000..be87c67 --- /dev/null +++ b/msvcc/search.vcxproj @@ -0,0 +1,194 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {43F946A8-9184-456B-A522-7B411C10A4EB} + search + 8.1 + search + + + + StaticLibrary + true + v140 + MultiByte + + + StaticLibrary + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + + + true + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/search.vcxproj.filters b/msvcc/search.vcxproj.filters new file mode 100644 index 0000000..c22b4aa --- /dev/null +++ b/msvcc/search.vcxproj.filters @@ -0,0 +1,336 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/search64.vcxproj b/msvcc/search64.vcxproj new file mode 100644 index 0000000..2a07b48 --- /dev/null +++ b/msvcc/search64.vcxproj @@ -0,0 +1,196 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {D281E44B-92E9-4CEA-A666-B05530F65000} + search + 8.1 + search64 + + + + StaticLibrary + true + v140 + MultiByte + + + StaticLibrary + false + v140 + true + MultiByte + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + BOWTIE_64BIT_INDEX;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + + + true + + + + + Level3 + MaxSpeed + true + true + true + BOWTIE_64BIT_INDEX;NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/search64.vcxproj.filters b/msvcc/search64.vcxproj.filters new file mode 100644 index 0000000..93260ba --- /dev/null +++ b/msvcc/search64.vcxproj.filters @@ -0,0 +1,348 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/msvcc/shared.vcxproj b/msvcc/shared.vcxproj new file mode 100644 index 0000000..8f68cc6 --- /dev/null +++ b/msvcc/shared.vcxproj @@ -0,0 +1,142 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {8BEEB701-AA26-4D2B-827B-64071F88AFB3} + shared + 8.1 + + + + StaticLibrary + true + v140 + MultiByte + + + StaticLibrary + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + + + true + + + + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/shared.vcxproj.filters b/msvcc/shared.vcxproj.filters new file mode 100644 index 0000000..0e994b1 --- /dev/null +++ b/msvcc/shared.vcxproj.filters @@ -0,0 +1,111 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/msvcc/shared64.vcxproj b/msvcc/shared64.vcxproj new file mode 100644 index 0000000..82a1a5d --- /dev/null +++ b/msvcc/shared64.vcxproj @@ -0,0 +1,137 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {E1F391B2-4A3F-43CA-9192-14536ABE783E} + shared + 8.1 + + + + StaticLibrary + true + v140 + MultiByte + + + StaticLibrary + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + $(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + BOWTIE_64BIT_INDEX;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + + + true + + + + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + true + BOWTIE_64BIT_INDEX;NDEBUG;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + MultiThreaded + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/msvcc/shared64.vcxproj.filters b/msvcc/shared64.vcxproj.filters new file mode 100644 index 0000000..63de9bf --- /dev/null +++ b/msvcc/shared64.vcxproj.filters @@ -0,0 +1,96 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/multikey_qsort.cpp b/multikey_qsort.cpp new file mode 100644 index 0000000..6afa98b --- /dev/null +++ b/multikey_qsort.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "multikey_qsort.h" diff --git a/multikey_qsort.h b/multikey_qsort.h new file mode 100644 index 0000000..623f8f2 --- /dev/null +++ b/multikey_qsort.h @@ -0,0 +1,1237 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef MULTIKEY_QSORT_H_ +#define MULTIKEY_QSORT_H_ + +#include +#include "sequence_io.h" +#include "alphabet.h" +#include "assert_helpers.h" +#include "diff_sample.h" +#include "sstring.h" +#include "btypes.h" + +using namespace std; + +/** + * Swap elements a and b in s + */ +template +static inline void swap(TStr& s, size_t slen, TPos a, TPos b) { + assert_lt(a, slen); + assert_lt(b, slen); + swap(s[a], s[b]); +} + +/** + * Swap elements a and b in array s + */ +template +static inline void swap(TVal* s, size_t slen, TPos a, TPos b) { + assert_lt(a, slen); + assert_lt(b, slen); + swap(s[a], s[b]); +} + +/** + * Helper macro for swapping elements a and b in s. Does some additional + * sainty checking w/r/t begin and end (which are parameters to the sorting + * routines below). + */ +#define SWAP(s, a, b) { \ + assert_geq(a, begin); \ + assert_geq(b, begin); \ + assert_lt(a, end); \ + assert_lt(b, end); \ + swap(s, slen, a, b); \ +} + +/** + * Helper macro for swapping the same pair of elements a and b in two different + * strings s and s2. This is a helpful variant if, for example, the caller + * would like to see how their input was permuted by the sort routine (in that + * case, the caller would let s2 be an array s2[] where s2 is the same length + * as s and s2[i] = i). + */ +#define SWAP2(s, s2, a, b) { \ + SWAP(s, a, b); \ + swap(s2, slen, a, b); \ +} + +#define SWAP1(s, s2, a, b) { \ + SWAP(s, a, b); \ +} + +/** + * Helper macro that swaps a range of elements [i, i+n) with another + * range [j, j+n) in s. + */ +#define VECSWAP(s, i, j, n) { \ + if(n > 0) { vecswap(s, slen, i, j, n, begin, end); } \ +} + +/** + * Helper macro that swaps a range of elements [i, i+n) with another + * range [j, j+n) both in s and s2. + */ +#define VECSWAP2(s, s2, i, j, n) { \ + if(n > 0) { vecswap2(s, slen, s2, i, j, n, begin, end); } \ +} + +/** + * Helper function that swaps a range of elements [i, i+n) with another + * range [j, j+n) in s. begin and end represent the current range under + * consideration by the caller (one of the recursive multikey_quicksort + * routines below). + */ +template +static inline void vecswap(TStr& s, size_t slen, TPos i, TPos j, TPos n, TPos begin, TPos end) { + assert_geq(i, begin); + assert_geq(j, begin); + assert_lt(i, end); + assert_lt(j, end); + while(n-- > 0) { + assert_geq(n, 0); + TPos a = i+n; + TPos b = j+n; + assert_geq(a, begin); + assert_geq(b, begin); + assert_lt(a, end); + assert_lt(b, end); + swap(s, slen, a, b); + } +} + +template +static inline void vecswap(TVal *s, size_t slen, TPos i, TPos j, TPos n, TPos begin, TPos end) { + assert_geq(i, begin); + assert_geq(j, begin); + assert_lt(i, end); + assert_lt(j, end); + while(n-- > 0) { + assert_geq(n, 0); + TPos a = i+n; + TPos b = j+n; + assert_geq(a, begin); + assert_geq(b, begin); + assert_lt(a, end); + assert_lt(b, end); + swap(s, slen, a, b); + } +} + +/** + * Helper function that swaps a range of elements [i, i+n) with another range + * [j, j+n) both in s and s2. begin and end represent the current range under + * consideration by the caller (one of the recursive multikey_quicksort + * routines below). + */ +template +static inline void vecswap2( + TStr& s, + size_t slen, + TStr& s2, + TPos i, + TPos j, + TPos n, + TPos begin, + TPos end) +{ + assert_geq(i, begin); + assert_geq(j, begin); + assert_lt(i, end); + assert_lt(j, end); + while(n-- > 0) { + assert_geq(n, 0); + TPos a = i+n; + TPos b = j+n; + assert_geq(a, begin); + assert_geq(b, begin); + assert_lt(a, end); + assert_lt(b, end); + swap(s, slen, a, b); + swap(s2, slen, a, b); + } +} + +template +static inline void vecswap2(TVal* s, size_t slen, TVal* s2, TPos i, TPos j, TPos n, TPos begin, TPos end) { + assert_geq(i, begin); + assert_geq(j, begin); + assert_lt(i, end); + assert_lt(j, end); + while(n-- > 0) { + assert_geq(n, 0); + TPos a = i+n; + TPos b = j+n; + assert_geq(a, begin); + assert_geq(b, begin); + assert_lt(a, end); + assert_lt(b, end); + swap(s, slen, a, b); + swap(s2, slen, a, b); + } +} + +/// Retrieve an int-ized version of the ath character of string s, or, +/// if a goes off the end of s, return a (user-specified) int greater +/// than any TAlphabet character - 'hi'. +#define CHAR_AT(ss, aa) ((length(s[ss]) > aa) ? (int)(s[ss][aa]) : hi) + +/// Retrieve an int-ized version of the ath character of string s, or, +/// if a goes off the end of s, return a (user-specified) int greater +/// than any TAlphabet character - 'hi'. +#define CHAR_AT_SUF(si, off) \ + (((off + s[si]) < hlen) ? ((int)(host[off + s[si]])) : (hi)) + +/// Retrieve an int-ized version of the ath character of string s, or, +/// if a goes off the end of s, return a (user-specified) int greater +/// than any TAlphabet character - 'hi'. + +#define CHAR_AT_SUF_U8(si, off) char_at_suf_u8(host, hlen, s, si, off, hi) + +// Note that CHOOSE_AND_SWAP_RANDOM_PIVOT is unused +#define CHOOSE_AND_SWAP_RANDOM_PIVOT(sw, ch) { \ + /* Note: rand() didn't really cut it here; it seemed to run out of */ \ + /* randomness and, after a time, returned the same thing over and */ \ + /* over again */ \ + a = (rand() % n) + begin; /* choose pivot between begin and end */ \ + assert_lt(a, end); assert_geq(a, begin); \ + sw(s, s2, begin, a); /* move pivot to beginning */ \ +} + +/** + * Ad-hoc DNA-centric way of choose a pretty good pivot without using + * the pseudo-random number generator. We try to get a 1 or 2 if + * possible, since they'll split things more evenly than a 0 or 4. We + * also avoid swapping in the event that we choose the first element. + */ +#define CHOOSE_AND_SWAP_SMART_PIVOT(sw, ch) { \ + a = begin; /* choose first elt */ \ + /* now try to find a better elt */ \ + if(n >= 5) { /* n is the difference between begin and end */ \ + if (ch(begin+1, depth) == 1 || ch(begin+1, depth) == 2) a = begin+1; \ + else if(ch(begin+2, depth) == 1 || ch(begin+2, depth) == 2) a = begin+2; \ + else if(ch(begin+3, depth) == 1 || ch(begin+3, depth) == 2) a = begin+3; \ + else if(ch(begin+4, depth) == 1 || ch(begin+4, depth) == 2) a = begin+4; \ + if(a != begin) sw(s, s2, begin, a); /* move pivot to beginning */ \ + } \ + /* the element at [begin] now holds the pivot value */ \ +} + +#define CHOOSE_AND_SWAP_PIVOT CHOOSE_AND_SWAP_SMART_PIVOT + +#ifndef NDEBUG + +/** + * Assert that the range of chars at depth 'depth' in strings 'begin' + * to 'end' in string-of-suffix-offsets s is parititioned properly + * according to the ternary paritioning strategy of Bentley and McIlroy + * (*prior to* swapping the = regions to the center) + */ +template +bool assertPartitionedSuf( + const THost& host, + TIndexOffU *s, + size_t slen, + int hi, + int pivot, + size_t begin, + size_t end, + size_t depth) +{ + size_t hlen = host.length(); + int state = 0; // 0 -> 1st = section, 1 -> < section, 2 -> > section, 3 -> 2nd = section + for(size_t i = begin; i < end; i++) { + switch(state) { + case 0: + if (CHAR_AT_SUF(i, depth) < pivot) { state = 1; break; } + else if (CHAR_AT_SUF(i, depth) > pivot) { state = 2; break; } + assert_eq(CHAR_AT_SUF(i, depth), pivot); break; + case 1: + if (CHAR_AT_SUF(i, depth) > pivot) { state = 2; break; } + else if (CHAR_AT_SUF(i, depth) == pivot) { state = 3; break; } + assert_lt(CHAR_AT_SUF(i, depth), pivot); break; + case 2: + if (CHAR_AT_SUF(i, depth) == pivot) { state = 3; break; } + assert_gt(CHAR_AT_SUF(i, depth), pivot); break; + case 3: + assert_eq(CHAR_AT_SUF(i, depth), pivot); break; + } + } + return true; +} + +/** + * Assert that the range of chars at depth 'depth' in strings 'begin' + * to 'end' in string-of-suffix-offsets s is parititioned properly + * according to the ternary paritioning strategy of Bentley and McIlroy + * (*after* swapping the = regions to the center) + */ +template +bool assertPartitionedSuf2( + const THost& host, + TIndexOffU *s, + size_t slen, + int hi, + int pivot, + size_t begin, + size_t end, + size_t depth) +{ + size_t hlen = host.length(); + int state = 0; // 0 -> < section, 1 -> = section, 2 -> > section + for(size_t i = begin; i < end; i++) { + switch(state) { + case 0: + if (CHAR_AT_SUF(i, depth) == pivot) { state = 1; break; } + else if (CHAR_AT_SUF(i, depth) > pivot) { state = 2; break; } + assert_lt(CHAR_AT_SUF(i, depth), pivot); break; + case 1: + if (CHAR_AT_SUF(i, depth) > pivot) { state = 2; break; } + assert_eq(CHAR_AT_SUF(i, depth), pivot); break; + case 2: + assert_gt(CHAR_AT_SUF(i, depth), pivot); break; + } + } + return true; +} +#endif + +/** + * Assert that string s of suffix offsets into string 'host' is a seemingly + * legitimate suffix-offset list (at this time, we just check that it doesn't + * list any suffix twice). + */ +static inline void sanityCheckInputSufs(TIndexOffU *s, size_t slen) { + assert_gt(slen, 0); + for(size_t i = 0; i < slen; i++) { + // Actually, it's convenient to allow the caller to provide + // suffix offsets thare are off the end of the host string. + // See, e.g., build() in diff_sample.cpp. + //assert_lt(s[i], length(host)); + for(size_t j = i+1; j < slen; j++) { + assert_neq(s[i], s[j]); + } + } +} + +/** + * Assert that the string s of suffix offsets into 'host' really are in + * lexicographical order up to depth 'upto'. + */ +template +void sanityCheckOrderedSufs( + const T& host, + size_t hlen, + TIndexOffU *s, + size_t slen, + size_t upto, + size_t lower = 0, + size_t upper = OFF_MASK) +{ + assert_lt(s[0], hlen); + upper = min(upper, slen-1); + for(size_t i = lower; i < upper; i++) { + // Allow s[i+t] to point off the end of the string; this is + // convenient for some callers + if(s[i+1] >= hlen) continue; +#ifndef NDEBUG + if(upto == OFF_MASK) { + assert(sstr_suf_lt(host, s[i], hlen, host, s[i+1], hlen, false)); + } else { + if(sstr_suf_upto_lt(host, s[i], host, s[i+1], upto, false)) { + // operator > treats shorter strings as + // lexicographically smaller, but we want to opposite + //assert(isPrefix(suffix(host, s[i+1]), suffix(host, s[i]))); + } + } +#endif + } +} + +/** + * Main multikey quicksort function for suffixes. Based on Bentley & + * Sedgewick's algorithm on p.5 of their paper "Fast Algorithms for + * Sorting and Searching Strings". That algorithm has been extended in + * three ways: + * + * 1. Deal with keys of different lengths by checking bounds and + * considering off-the-end values to be 'hi' (b/c our goal is the + * BWT transform, we're biased toward considring prefixes as + * lexicographically *greater* than their extensions). + * 2. The multikey_qsort_suffixes version takes a single host string + * and a list of suffix offsets as input. This reduces memory + * footprint compared to an approach that treats its input + * generically as a set of strings (not necessarily suffixes), thus + * requiring that we store at least two integers worth of + * information for each string. + * 3. Sorting functions take an extra "upto" parameter that upper- + * bounds the depth to which the function sorts. + * + * TODO: Consult a tie-breaker (like a difference cover sample) if two + * keys share a long prefix. + */ +template +void mkeyQSortSuf( + const T& host, + size_t hlen, + TIndexOffU *s, + size_t slen, + int hi, + size_t begin, + size_t end, + size_t depth, + size_t upto = OFF_MASK) +{ + // Helper for making the recursive call; sanity-checks arguments to + // make sure that the problem actually got smaller. + #define MQS_RECURSE_SUF(nbegin, nend, ndepth) { \ + assert(nbegin > begin || nend < end || ndepth > depth); \ + if(ndepth < upto) { /* don't exceed depth of 'upto' */ \ + mkeyQSortSuf(host, hlen, s, slen, hi, nbegin, nend, ndepth, upto); \ + } \ + } + assert_leq(begin, slen); + assert_leq(end, slen); + size_t a, b, c, d, /*e,*/ r; + size_t n = end - begin; + if(n <= 1) return; // 1-element list already sorted + CHOOSE_AND_SWAP_PIVOT(SWAP1, CHAR_AT_SUF); // pick pivot, swap it into [begin] + int v = CHAR_AT_SUF(begin, depth); // v <- randomly-selected pivot value + #ifndef NDEBUG + { + bool stillInBounds = false; + for(size_t i = begin; i < end; i++) { + if(depth < (hlen-s[i])) { + stillInBounds = true; + break; + } else { /* already fell off this suffix */ } + } + assert(stillInBounds); // >=1 suffix must still be in bounds + } + #endif + a = b = begin; + c = d = end-1; + while(true) { + // Invariant: everything before a is = pivot, everything + // between a and b is < + int bc = 0; // shouldn't have to init but gcc on Mac complains + while(b <= c && v >= (bc = CHAR_AT_SUF(b, depth))) { + if(v == bc) { + SWAP(s, a, b); a++; + } + b++; + } + // Invariant: everything after d is = pivot, everything + // between c and d is > + int cc = 0; // shouldn't have to init but gcc on Mac complains + while(b <= c && v <= (cc = CHAR_AT_SUF(c, depth))) { + if(v == cc) { + SWAP(s, c, d); d--; + } + c--; + } + if(b > c) break; + SWAP(s, b, c); + b++; + c--; + } + assert(a > begin || c < end-1); // there was at least one =s + assert_lt(d-c, n); // they can't all have been > pivot + assert_lt(b-a, n); // they can't all have been < pivot + assert(assertPartitionedSuf(host, s, slen, hi, v, begin, end, depth)); // check pre-=-swap invariant + r = min(a-begin, b-a); VECSWAP(s, begin, b-r, r); // swap left = to center + r = min(d-c, end-d-1); VECSWAP(s, b, end-r, r); // swap right = to center + assert(assertPartitionedSuf2(host, s, slen, hi, v, begin, end, depth)); // check post-=-swap invariant + r = b-a; // r <- # of <'s + if(r > 0) { + MQS_RECURSE_SUF(begin, begin + r, depth); // recurse on <'s + } + // Do not recurse on ='s if the pivot was the off-the-end value; + // they're already fully sorted + if(v != hi) { + MQS_RECURSE_SUF(begin + r, begin + r + (a-begin) + (end-d-1), depth+1); // recurse on ='s + } + r = d-c; // r <- # of >'s excluding those exhausted + if(r > 0 && v < hi-1) { + MQS_RECURSE_SUF(end-r, end, depth); // recurse on >'s + } +} + +/** + * Toplevel function for multikey quicksort over suffixes. + */ +template +void mkeyQSortSuf( + const T& host, + TIndexOffU *s, + size_t slen, + int hi, + bool verbose = false, + bool sanityCheck = false, + size_t upto = OFF_MASK) +{ + size_t hlen = host.length(); + assert_gt(slen, 0); + if(sanityCheck) sanityCheckInputSufs(s, slen); + mkeyQSortSuf(host, hlen, s, slen, hi, (size_t)0, slen, (size_t)0, upto); + if(sanityCheck) sanityCheckOrderedSufs(host, hlen, s, slen, upto); +} + +/** + * Just like mkeyQSortSuf but all swaps are applied to s2 as well as s. + * This is a helpful variant if, for example, the caller would like to + * see how their input was permuted by the sort routine (in that case, + * the caller would let s2 be an array s2[] where s2 is the same length + * as s and s2[i] = i). + */ +struct QSortRange { + size_t begin; + size_t end; + size_t depth; +}; +template +void mkeyQSortSuf2( + const T& host, + size_t hlen, + TIndexOffU *s, + size_t slen, + TIndexOffU *s2, + int hi, + size_t _begin, + size_t _end, + size_t _depth, + size_t upto = OFF_MASK, + EList* boundaries = NULL) +{ + ELList block_list; + while(true) { + size_t begin = 0, end = 0, depth = 0; + if(block_list.size() == 0) { + begin = _begin; + end = _end; + depth = _depth; + } else { + if(block_list.back().size() > 0) { + begin = block_list.back()[0].begin; + end = block_list.back()[0].end; + depth = block_list.back()[0].depth; + block_list.back().erase(0); + } else { + block_list.resize(block_list.size() - 1); + if(block_list.size() == 0) { + break; + } + } + } + if(depth == upto) { + if(boundaries != NULL) { + (*boundaries).push_back(end); + } + continue; + } + assert_leq(begin, slen); + assert_leq(end, slen); + size_t a, b, c, d, /*e,*/ r; + size_t n = end - begin; + if(n <= 1) { // 1-element list already sorted + if(n == 1 && boundaries != NULL) { + boundaries->push_back(end); + } + continue; + } + CHOOSE_AND_SWAP_PIVOT(SWAP2, CHAR_AT_SUF); // pick pivot, swap it into [begin] + int v = CHAR_AT_SUF(begin, depth); // v <- randomly-selected pivot value +#ifndef NDEBUG + { + bool stillInBounds = false; + for(size_t i = begin; i < end; i++) { + if(depth < (hlen-s[i])) { + stillInBounds = true; + break; + } else { /* already fell off this suffix */ } + } + assert(stillInBounds); // >=1 suffix must still be in bounds + } +#endif + a = b = begin; + c = d = /*e =*/ end-1; + while(true) { + // Invariant: everything before a is = pivot, everything + // between a and b is < + int bc = 0; // shouldn't have to init but gcc on Mac complains + while(b <= c && v >= (bc = CHAR_AT_SUF(b, depth))) { + if(v == bc) { + SWAP2(s, s2, a, b); a++; + } + b++; + } + // Invariant: everything after d is = pivot, everything + // between c and d is > + int cc = 0; // shouldn't have to init but gcc on Mac complains + while(b <= c && v <= (cc = CHAR_AT_SUF(c, depth))) { + if(v == cc) { + SWAP2(s, s2, c, d); d--; /*e--;*/ + } + //else if(c == e && v == hi) e--; + c--; + } + if(b > c) break; + SWAP2(s, s2, b, c); + b++; + c--; + } + assert(a > begin || c < end-1); // there was at least one =s + assert_lt(/*e*/d-c, n); // they can't all have been > pivot + assert_lt(b-a, n); // they can't all have been < pivot + assert(assertPartitionedSuf(host, s, slen, hi, v, begin, end, depth)); // check pre-=-swap invariant + r = min(a-begin, b-a); VECSWAP2(s, s2, begin, b-r, r); // swap left = to center + r = min(d-c, end-d-1); VECSWAP2(s, s2, b, end-r, r); // swap right = to center + assert(assertPartitionedSuf2(host, s, slen, hi, v, begin, end, depth)); // check post-=-swap invariant + r = b-a; // r <- # of <'s + block_list.expand(); + block_list.back().clear(); + if(r > 0) { // recurse on <'s + block_list.back().expand(); + block_list.back().back().begin = begin; + block_list.back().back().end = begin + r; + block_list.back().back().depth = depth; + } + // Do not recurse on ='s if the pivot was the off-the-end value; + // they're already fully sorted + //if(v != hi) { // recurse on ='s + block_list.back().expand(); + block_list.back().back().begin = begin + r; + block_list.back().back().end = begin + r + (a-begin) + (end-d-1); + block_list.back().back().depth = depth + 1; + //} + r = d-c; // r <- # of >'s excluding those exhausted + if(r > 0 /*&& v < hi-1*/) { // recurse on >'s + block_list.back().expand(); + block_list.back().back().begin = end - r; + block_list.back().back().end = end; + block_list.back().back().depth = depth; + } + } +} + +/** + * Toplevel function for multikey quicksort over suffixes with double + * swapping. + */ +template +void mkeyQSortSuf2( + const T& host, + TIndexOffU *s, + size_t slen, + TIndexOffU *s2, + int hi, + bool verbose = false, + bool sanityCheck = false, + size_t upto = OFF_MASK, + EList* boundaries = NULL) +{ + size_t hlen = host.length(); + if(sanityCheck) sanityCheckInputSufs(s, slen); + TIndexOffU *sOrig = NULL; + if(sanityCheck) { + sOrig = new TIndexOffU[slen]; + memcpy(sOrig, s, OFF_SIZE * slen); + } + mkeyQSortSuf2(host, hlen, s, slen, s2, hi, (size_t)0, slen, (size_t)0, upto, boundaries); + if(sanityCheck) { + sanityCheckOrderedSufs(host, hlen, s, slen, upto); + for(size_t i = 0; i < slen; i++) { + assert_eq(s[i], sOrig[s2[i]]); + } + delete[] sOrig; + } +} + +// Ugly but necessary; otherwise the compiler chokes dramatically on +// the DifferenceCoverSample<> template args to the next few functions +template +class DifferenceCoverSample; + +/** + * Constant time + */ +template inline +bool sufDcLt( + const T1& host, + const T2& s1, + const T2& s2, + const DifferenceCoverSample& dc, + bool sanityCheck = false) +{ + size_t diff = dc.tieBreakOff(s1, s2); + ASSERT_ONLY(size_t hlen = host.length()); + assert_lt(diff, dc.v()); + assert_lt(diff, hlen-s1); + assert_lt(diff, hlen-s2); + if(sanityCheck) { + for(size_t i = 0; i < diff; i++) { + assert_eq(host[s1+i], host[s2+i]); + } + } + bool ret = dc.breakTie(s1+diff, s2+diff) < 0; +#ifndef NDEBUG + if(sanityCheck && ret != sstr_suf_lt(host, s1, hlen, host, s2, hlen, false)) { + assert(false); + } +#endif + return ret; +} + +/** + * k log(k) + */ +template inline +void qsortSufDc( + const T& host, + size_t hlen, + TIndexOffU* s, + size_t slen, + const DifferenceCoverSample& dc, + size_t begin, + size_t end, + bool sanityCheck = false) +{ + assert_leq(end, slen); + assert_lt(begin, slen); + assert_gt(end, begin); + size_t n = end - begin; + if(n <= 1) return; // 1-element list already sorted + // Note: rand() didn't really cut it here; it seemed to run out of + // randomness and, after a time, returned the same thing over and + // over again + size_t a = (rand() % n) + begin; // choose pivot between begin and end + assert_lt(a, end); + assert_geq(a, begin); + SWAP(s, end-1, a); // move pivot to end + size_t cur = 0; + for(size_t i = begin; i < end-1; i++) { + if(sufDcLt(host, s[i], s[end-1], dc, sanityCheck)) { + if(sanityCheck) + assert(dollarLt(suffix(host, s[i]), suffix(host, s[end-1]))); + assert_lt(begin + cur, end-1); + SWAP(s, i, begin + cur); + cur++; + } + } + // Put pivot into place + assert_lt(cur, end-begin); + SWAP(s, end-1, begin+cur); + if(begin+cur > begin) qsortSufDc(host, hlen, s, slen, dc, begin, begin+cur); + if(end > begin+cur+1) qsortSufDc(host, hlen, s, slen, dc, begin+cur+1, end); +} + +/** + * Toplevel function for multikey quicksort over suffixes. + */ +template +void mkeyQSortSufDcU8( + const T1& host1, + const T2& host, + size_t hlen, + TIndexOffU* s, + size_t slen, + const DifferenceCoverSample& dc, + int hi, + bool verbose = false, + bool sanityCheck = false) +{ + if(sanityCheck) sanityCheckInputSufs(s, slen); + mkeyQSortSufDcU8(host1, host, hlen, s, slen, dc, hi, 0, slen, 0, sanityCheck); + if(sanityCheck) sanityCheckOrderedSufs(host1, hlen, s, slen, OFF_MASK); +} + +/** + * Return a boolean indicating whether s1 < s2 using the difference + * cover to break the tie. + */ +template inline +bool sufDcLtU8( + const T1& host1, + const T2& host, + size_t hlen, + size_t s1, + size_t s2, + const DifferenceCoverSample& dc, + bool sanityCheck = false) +{ + hlen += 0; + size_t diff = dc.tieBreakOff((TIndexOffU)s1, (TIndexOffU)s2); + assert_lt(diff, dc.v()); + assert_lt(diff, hlen-s1); + assert_lt(diff, hlen-s2); + if(sanityCheck) { + for(size_t i = 0; i < diff; i++) { + assert_eq(host[s1+i], host1[s2+i]); + } + } + bool ret = dc.breakTie((TIndexOffU)(s1+diff), (TIndexOffU)(s2+diff)) < 0; + // Sanity-check return value using dollarLt +#ifndef NDEBUG + bool ret2 = sstr_suf_lt(host1, s1, hlen, host, s2, hlen, false); + assert(!sanityCheck || ret == ret2); +#endif + return ret; +} + +/** + * k log(k) + */ +template inline +void qsortSufDcU8( + const T1& host1, + const T2& host, + size_t hlen, + TIndexOffU* s, + size_t slen, + const DifferenceCoverSample& dc, + size_t begin, + size_t end, + bool sanityCheck = false) +{ + assert_leq(end, slen); + assert_lt(begin, slen); + assert_gt(end, begin); + size_t n = end - begin; + if(n <= 1) return; // 1-element list already sorted + // Note: rand() didn't really cut it here; it seemed to run out of + // randomness and, after a time, returned the same thing over and + // over again + size_t a = (rand() % n) + begin; // choose pivot between begin and end + assert_lt(a, end); + assert_geq(a, begin); + SWAP(s, end-1, a); // move pivot to end + size_t cur = 0; + for(size_t i = begin; i < end-1; i++) { + if(sufDcLtU8(host1, host, hlen, s[i], s[end-1], dc, sanityCheck)) { +#ifndef NDEBUG + if(sanityCheck) { + assert(sstr_suf_lt(host1, s[i], hlen, host1, s[end-1], hlen, false)); + } + assert_lt(begin + cur, end-1); +#endif + SWAP(s, i, begin + cur); + cur++; + } + } + // Put pivot into place + assert_lt(cur, end-begin); + SWAP(s, end-1, begin+cur); + if(begin+cur > begin) qsortSufDcU8(host1, host, hlen, s, slen, dc, begin, begin+cur); + if(end > begin+cur+1) qsortSufDcU8(host1, host, hlen, s, slen, dc, begin+cur+1, end); +} + +#define BUCKET_SORT_CUTOFF (4 * 1024 * 1024) +#define SELECTION_SORT_CUTOFF 6 + +/** + * Straightforwardly obtain a uint8_t-ized version of t[off]. This + * works fine as long as TStr is not packed. + */ +template +inline uint8_t get_uint8(const TStr& t, size_t off) { + return t[off]; +} + +/** + * For incomprehensible generic-programming reasons, getting a uint8_t + * version of a character in a packed String<> requires casting first + * to Dna then to uint8_t. + */ +template<> +inline uint8_t get_uint8(const S2bDnaString& t, size_t off) { + return (uint8_t)t[off]; +} + +/** + * Return character at offset 'off' from the 'si'th suffix in the array + * 's' of suffixes. If the character is out-of-bounds, return hi. + */ +template +static inline int char_at_suf_u8( + const TStr& host, + size_t hlen, + TIndexOffU* s, + size_t si, + size_t off, + uint8_t hi) +{ + return ((off+s[si]) < hlen) ? get_uint8(host, off+s[si]) : (hi); +} + +template +static void selectionSortSufDcU8( + const T1& host1, + const T2& host, + size_t hlen, + TIndexOffU* s, + size_t slen, + const DifferenceCoverSample& dc, + uint8_t hi, + size_t begin, + size_t end, + size_t depth, + bool sanityCheck = false) +{ +#define ASSERT_SUF_LT(l, r) \ + if(sanityCheck && \ + !sstr_suf_lt(host1, s[l], hlen, host1, s[r], hlen, false)) { \ + assert(false); \ + } + + assert_gt(end, begin+1); + assert_leq(end-begin, SELECTION_SORT_CUTOFF); + assert_eq(hi, 4); + size_t v = dc.v(); + if(end == begin+2) { + size_t off = dc.tieBreakOff(s[begin], s[begin+1]); + if(off + s[begin] >= hlen || + off + s[begin+1] >= hlen) + { + off = OFF_MASK; + } + if(off != OFF_MASK) { + if(off < depth) { + qsortSufDcU8(host1, host, hlen, s, slen, dc, + begin, end, sanityCheck); + // It's helpful for debugging if we call this here + if(sanityCheck) { + sanityCheckOrderedSufs(host1, hlen, s, slen, + OFF_MASK, begin, end); + } + return; + } + v = off - depth + 1; + } + } + assert_leq(v, dc.v()); + size_t lim = v; + assert_geq(lim, 0); + for(size_t i = begin; i < end-1; i++) { + size_t targ = i; + size_t targoff = depth + s[i]; + for(size_t j = i+1; j < end; j++) { + assert_neq(j, targ); + size_t joff = depth + s[j]; + size_t k; + for(k = 0; k <= lim; k++) { + assert_neq(j, targ); + uint8_t jc = (k + joff < hlen) ? get_uint8(host, k + joff) : hi; + uint8_t tc = (k + targoff < hlen) ? get_uint8(host, k + targoff) : hi; + assert(jc != hi || tc != hi); + if(jc > tc) { + // the jth suffix is greater than the current + // smallest suffix + ASSERT_SUF_LT(targ, j); + break; + } else if(jc < tc) { + // the jth suffix is less than the current smallest + // suffix, so update smallest to be j + ASSERT_SUF_LT(j, targ); + targ = j; + targoff = joff; + break; + } else if(k == lim) { + // Check whether either string ends immediately + // after this character + assert_leq(k + joff + 1, hlen); + assert_leq(k + targoff + 1, hlen); + if(k + joff + 1 == hlen) { + // targ < j + assert_neq(k + targoff + 1, hlen); + ASSERT_SUF_LT(targ, j); + break; + } else if(k + targoff + 1 == hlen) { + // j < targ + ASSERT_SUF_LT(j, targ); + targ = j; + targoff = joff; + break; + } + } else { + // They're equal so far, keep going + } + } + // The jth suffix was equal to the current smallest suffix + // up to the difference-cover period, so disambiguate with + // difference cover + if(k == lim+1) { + assert_neq(j, targ); + if(sufDcLtU8(host1, host, hlen, s[j], s[targ], dc, sanityCheck)) { + // j < targ + assert(!sufDcLtU8(host1, host, hlen, s[targ], s[j], dc, sanityCheck)); + ASSERT_SUF_LT(j, targ); + targ = j; + targoff = joff; + } else { + assert(sufDcLtU8(host1, host, hlen, s[targ], s[j], dc, sanityCheck)); + ASSERT_SUF_LT(targ, j); // ! + } + } + } + if(i != targ) { + ASSERT_SUF_LT(targ, i); + // swap i and targ + TIndexOffU tmp = s[i]; + s[i] = s[targ]; + s[targ] = tmp; + } + for(size_t j = i+1; j < end; j++) { + ASSERT_SUF_LT(i, j); + } + } + if(sanityCheck) { + sanityCheckOrderedSufs(host1, hlen, s, slen, OFF_MASK, begin, end); + } +} + +template +static void bucketSortSufDcU8( + const T1& host1, + const T2& host, + size_t hlen, + TIndexOffU* s, + size_t slen, + const DifferenceCoverSample& dc, + uint8_t hi, + size_t _begin, + size_t _end, + size_t _depth, + bool sanityCheck = false) +{ + // 5 64-element buckets for bucket-sorting A, C, G, T, $ + TIndexOffU* bkts[4]; + for(size_t i = 0; i < 4; i++) { + bkts[i] = new TIndexOffU[4 * 1024 * 1024]; + } + ELList block_list; + bool first = true; + while(true) { + size_t begin = 0, end = 0; + if(first) { + begin = _begin; + end = _end; + first = false; + } else { + if(block_list.size() == 0) { + break; + } + if(block_list.back().size() > 1) { + end = block_list.back().back(); block_list.back().pop_back(); + begin = block_list.back().back(); + } else { + block_list.resize(block_list.size() - 1); + if(block_list.size() == 0) { + break; + } + } + } + size_t depth = block_list.size() + _depth; + assert_leq(end-begin, BUCKET_SORT_CUTOFF); + assert_eq(hi, 4); + if(end <= begin + 1) { // 1-element list already sorted + continue; + } + if(depth > dc.v()) { + // Quicksort the remaining suffixes using difference cover + // for constant-time comparisons; this is O(k*log(k)) where + // k=(end-begin) + qsortSufDcU8(host1, host, hlen, s, slen, dc, begin, end, sanityCheck); + continue; + } + if(end-begin <= SELECTION_SORT_CUTOFF) { + // Bucket sort remaining items + selectionSortSufDcU8(host1, host, hlen, s, slen, dc, hi, + begin, end, depth, sanityCheck); + if(sanityCheck) { + sanityCheckOrderedSufs(host1, hlen, s, slen, + OFF_MASK, begin, end); + } + continue; + } + size_t cnts[] = { 0, 0, 0, 0, 0 }; + for(size_t i = begin; i < end; i++) { + size_t off = depth + s[i]; + uint8_t c = (off < hlen) ? get_uint8(host, off) : hi; + assert_leq(c, 4); + if(c == 0) { + s[begin + cnts[0]++] = s[i]; + } else { + bkts[c-1][cnts[c]++] = s[i]; + } + } + assert_eq(cnts[0] + cnts[1] + cnts[2] + cnts[3] + cnts[4], end - begin); + size_t cur = begin + cnts[0]; + if(cnts[1] > 0) { memcpy(&s[cur], bkts[0], cnts[1] << (OFF_SIZE/4 + 1)); cur += cnts[1]; } + if(cnts[2] > 0) { memcpy(&s[cur], bkts[1], cnts[2] << (OFF_SIZE/4 + 1)); cur += cnts[2]; } + if(cnts[3] > 0) { memcpy(&s[cur], bkts[2], cnts[3] << (OFF_SIZE/4 + 1)); cur += cnts[3]; } + if(cnts[4] > 0) { memcpy(&s[cur], bkts[3], cnts[4] << (OFF_SIZE/4 + 1)); } + // This frame is now totally finished with bkts[][], so recursive + // callees can safely clobber it; we're not done with cnts[], but + // that's local to the stack frame. + block_list.expand(); + block_list.back().clear(); + block_list.back().push_back(begin); + for(size_t i = 0; i < 4; i++) { + if(cnts[i] > 0) { + block_list.back().push_back(block_list.back().back() + cnts[i]); + } + } + } + // Done + + for(size_t i = 0; i < 4; i++) { + delete [] bkts[i]; + } +} + +/** + * Main multikey quicksort function for suffixes. Based on Bentley & + * Sedgewick's algorithm on p.5 of their paper "Fast Algorithms for + * Sorting and Searching Strings". That algorithm has been extended in + * three ways: + * + * 1. Deal with keys of different lengths by checking bounds and + * considering off-the-end values to be 'hi' (b/c our goal is the + * BWT transform, we're biased toward considring prefixes as + * lexicographically *greater* than their extensions). + * 2. The multikey_qsort_suffixes version takes a single host string + * and a list of suffix offsets as input. This reduces memory + * footprint compared to an approach that treats its input + * generically as a set of strings (not necessarily suffixes), thus + * requiring that we store at least two integers worth of + * information for each string. + * 3. Sorting functions take an extra "upto" parameter that upper- + * bounds the depth to which the function sorts. + */ +template +void mkeyQSortSufDcU8( + const T1& host1, + const T2& host, + size_t hlen, + TIndexOffU* s, + size_t slen, + const DifferenceCoverSample& dc, + int hi, + size_t begin, + size_t end, + size_t depth, + bool sanityCheck = false) +{ + // Helper for making the recursive call; sanity-checks arguments to + // make sure that the problem actually got smaller. + #define MQS_RECURSE_SUF_DC_U8(nbegin, nend, ndepth) { \ + assert(nbegin > begin || nend < end || ndepth > depth); \ + mkeyQSortSufDcU8(host1, host, hlen, s, slen, dc, hi, nbegin, nend, ndepth, sanityCheck); \ + } + assert_leq(begin, slen); + assert_leq(end, slen); + size_t n = end - begin; + if(n <= 1) return; // 1-element list already sorted + if(depth > dc.v()) { + // Quicksort the remaining suffixes using difference cover + // for constant-time comparisons; this is O(k*log(k)) where + // k=(end-begin) + qsortSufDcU8(host1, host, hlen, s, slen, dc, begin, end, sanityCheck); + if(sanityCheck) { + sanityCheckOrderedSufs(host1, hlen, s, slen, OFF_MASK, begin, end); + } + return; + } + if(n <= BUCKET_SORT_CUTOFF) { + // Bucket sort remaining items + bucketSortSufDcU8(host1, host, hlen, s, slen, dc, + (uint8_t)hi, begin, end, depth, sanityCheck); + if(sanityCheck) { + sanityCheckOrderedSufs(host1, hlen, s, slen, OFF_MASK, begin, end); + } + return; + } + size_t a, b, c, d, r; + CHOOSE_AND_SWAP_PIVOT(SWAP1, CHAR_AT_SUF_U8); // choose pivot, swap to begin + int v = CHAR_AT_SUF_U8(begin, depth); // v <- pivot value + #ifndef NDEBUG + { + bool stillInBounds = false; + for(size_t i = begin; i < end; i++) { + if(depth < (hlen-s[i])) { + stillInBounds = true; + break; + } else { /* already fell off this suffix */ } + } + assert(stillInBounds); // >=1 suffix must still be in bounds + } + #endif + a = b = begin; + c = d = end-1; + while(true) { + // Invariant: everything before a is = pivot, everything + // between a and b is < + int bc = 0; // shouldn't have to init but gcc on Mac complains + while(b <= c && v >= (bc = CHAR_AT_SUF_U8(b, depth))) { + if(v == bc) { + SWAP(s, a, b); a++; + } + b++; + } + // Invariant: everything after d is = pivot, everything + // between c and d is > + int cc = 0; // shouldn't have to init but gcc on Mac complains + //bool hiLatch = true; + while(b <= c && v <= (cc = CHAR_AT_SUF_U8(c, depth))) { + if(v == cc) { + SWAP(s, c, d); d--; + } + //else if(hiLatch && cc == hi) { } + c--; + } + if(b > c) break; + SWAP(s, b, c); + b++; + c--; + } + assert(a > begin || c < end-1); // there was at least one =s + assert_lt(d-c, n); // they can't all have been > pivot + assert_lt(b-a, n); // they can't all have been < pivot + r = min(a-begin, b-a); VECSWAP(s, begin, b-r, r); // swap left = to center + r = min(d-c, end-d-1); VECSWAP(s, b, end-r, r); // swap right = to center + r = b-a; // r <- # of <'s + if(r > 0) { + MQS_RECURSE_SUF_DC_U8(begin, begin + r, depth); // recurse on <'s + } + // Do not recurse on ='s if the pivot was the off-the-end value; + // they're already fully sorted + if(v != hi) { + MQS_RECURSE_SUF_DC_U8(begin + r, begin + r + (a-begin) + (end-d-1), depth+1); // recurse on ='s + } + r = d-c; // r <- # of >'s excluding those exhausted + if(r > 0 && v < hi-1) { + MQS_RECURSE_SUF_DC_U8(end-r, end, depth); // recurse on >'s + } +} + + +#endif /*MULTIKEY_QSORT_H_*/ diff --git a/opts.h b/opts.h new file mode 100644 index 0000000..ace3a16 --- /dev/null +++ b/opts.h @@ -0,0 +1,200 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef OPTS_H_ +#define OPTS_H_ + +enum { + ARG_ORIG = 256, // --orig + ARG_SEED, // --seed + ARG_SOLEXA_QUALS, // --solexa-quals + ARG_VERBOSE, // --verbose + ARG_STARTVERBOSE, // --startverbose + ARG_QUIET, // --quiet + ARG_METRIC_IVAL, // --met + ARG_METRIC_FILE, // --met-file + ARG_METRIC_STDERR, // --met-stderr + ARG_METRIC_PER_READ, // --met-per-read + ARG_REFIDX, // --refidx + ARG_SANITY, // --sanity + ARG_PARTITION, // --partition + ARG_INTEGER_QUALS, // --int-quals + ARG_FILEPAR, // --filepar + ARG_SHMEM, // --shmem + ARG_MM, // --mm + ARG_MMSWEEP, // --mmsweep + ARG_FF, // --ff + ARG_FR, // --fr + ARG_RF, // --rf + ARG_NO_MIXED, // --no-mixed + ARG_NO_DISCORDANT, // --no-discordant + ARG_CACHE_LIM, // -- + ARG_CACHE_SZ, // -- + ARG_NO_FW, // --nofw + ARG_NO_RC, // --norc + ARG_SKIP, // --skip + ARG_ONETWO, // --12 + ARG_PHRED64, // --phred64 + ARG_PHRED33, // --phred33 + ARG_HADOOPOUT, // --hadoopout + ARG_FUZZY, // --fuzzy + ARG_FULLREF, // --fullref + ARG_USAGE, // --usage + ARG_SNPPHRED, // --snpphred + ARG_SNPFRAC, // --snpfrac + ARG_SAM_NO_QNAME_TRUNC, // --sam-no-qname-trunc + ARG_SAM_OMIT_SEC_SEQ, // --sam-omit-sec-seq + ARG_SAM_NOHEAD, // --sam-noHD/--sam-nohead + ARG_SAM_NOSQ, // --sam-nosq/--sam-noSQ + ARG_SAM_RG, // --sam-rg + ARG_SAM_RGID, // --sam-rg-id + ARG_GAP_BAR, // --gbar + ARG_QUALS1, // --Q1 + ARG_QUALS2, // --Q2 + ARG_QSEQ, // --qseq + ARG_SEED_SUMM, // --seed-summary + ARG_OVERHANG, // --overhang + ARG_NO_CACHE, // --no-cache + ARG_USE_CACHE, // --cache + ARG_NOISY_HPOLY, // --454/--ion-torrent + ARG_LOCAL, // --local + ARG_END_TO_END, // --end-to-end + ARG_SCAN_NARROWED, // --scan-narrowed + ARG_QC_FILTER, // --qc-filter + ARG_BWA_SW_LIKE, // --bwa-sw-like + ARG_MULTISEED_IVAL, // --multiseed + ARG_SCORE_MIN, // --score-min + ARG_SCORE_MA, // --ma + ARG_SCORE_MMP, // --mp + ARG_SCORE_SCP, // --sp + ARG_NO_SOFTCLIP, // --no-softclip + ARG_SCORE_NP, // --nm + ARG_SCORE_RDG, // --rdg + ARG_SCORE_RFG, // --rfg + ARG_N_CEIL, // --n-ceil + ARG_DPAD, // --dpad + ARG_SAM_PRINT_YI, // --mapq-print-inputs + ARG_ALIGN_POLICY, // --policy + ARG_PRESET_VERY_FAST, // --very-fast + ARG_PRESET_FAST, // --fast + ARG_PRESET_SENSITIVE, // --sensitive + ARG_PRESET_VERY_SENSITIVE, // --very-sensitive + ARG_PRESET_VERY_FAST_LOCAL, // --very-fast-local + ARG_PRESET_FAST_LOCAL, // --fast-local + ARG_PRESET_SENSITIVE_LOCAL, // --sensitive-local + ARG_PRESET_VERY_SENSITIVE_LOCAL, // --very-sensitive-local + ARG_NO_SCORE_PRIORITY, // --no-score-priority + ARG_IGNORE_QUALS, // --ignore-quals + ARG_DESC, // --arg-desc + ARG_TAB5, // --tab5 + ARG_TAB6, // --tab6 + ARG_WRAPPER, // --wrapper + ARG_DOVETAIL, // --dovetail + ARG_NO_DOVETAIL, // --no-dovetail + ARG_CONTAIN, // --contain + ARG_NO_CONTAIN, // --no-contain + ARG_OVERLAP, // --overlap + ARG_NO_OVERLAP, // --no-overlap + ARG_MAPQ_V, // --mapq-v + ARG_SSE8, // --sse8 + ARG_SSE8_NO, // --no-sse8 + ARG_UNGAPPED, // --ungapped + ARG_UNGAPPED_NO, // --no-ungapped + ARG_TIGHTEN, // --tighten + ARG_UNGAP_THRESH, // --ungap-thresh + ARG_EXACT_UPFRONT, // --exact-upfront + ARG_1MM_UPFRONT, // --1mm-upfront + ARG_EXACT_UPFRONT_NO, // --no-exact-upfront + ARG_1MM_UPFRONT_NO, // --no-1mm-upfront + ARG_1MM_MINLEN, // --1mm-minlen + ARG_VERSION, // --version + ARG_SEED_OFF, // --seed-off + ARG_SEED_BOOST_THRESH, // --seed-boost + ARG_MAX_SEEDS, + ARG_READ_TIMES, // --read-times + ARG_EXTEND_ITERS, // --extends + ARG_DP_MATE_STREAK_THRESH, // --db-mate-streak + ARG_DP_FAIL_STREAK_THRESH, // --dp-fail-streak + ARG_UG_FAIL_STREAK_THRESH, // --ug-fail-streak + ARG_EE_FAIL_STREAK_THRESH, // --ee-fail-streak + ARG_DP_FAIL_THRESH, // --dp-fails + ARG_UG_FAIL_THRESH, // --ug-fails + ARG_MAPQ_EX, // --mapq-extra + ARG_NO_EXTEND, // --no-extend + ARG_REORDER, // --reorder + ARG_SHOW_RAND_SEED, // --show-rand-seed + ARG_READ_PASSTHRU, // --passthrough + ARG_SAMPLE, // --sample + ARG_CP_MIN, // --cp-min + ARG_CP_IVAL, // --cp-ival + ARG_TRI, // --tri + ARG_LOCAL_SEED_CACHE_SZ, // --local-seed-cache-sz + ARG_CURRENT_SEED_CACHE_SZ, // --seed-cache-sz + ARG_SAM_NO_UNAL, // --no-unal + ARG_NON_DETERMINISTIC, // --non-deterministic + ARG_TEST_25, // --test-25 + ARG_DESC_KB, // --desc-kb + ARG_DESC_LANDING, // --desc-landing + ARG_DESC_EXP, // --desc-exp + ARG_DESC_FMOPS, // --desc-fmops + ARG_NO_TEMPSPLICESITE, + ARG_PEN_CANSPLICE, + ARG_PEN_NONCANSPLICE, + ARG_PEN_CONFLICTSPLICE, + ARG_PEN_CANINTRONLEN, + ARG_PEN_NONCANINTRONLEN, + ARG_MIN_INTRONLEN, + ARG_MAX_INTRONLEN, + ARG_KNOWN_SPLICESITE_INFILE, + ARG_NOVEL_SPLICESITE_INFILE, + ARG_NOVEL_SPLICESITE_OUTFILE, + ARG_SECONDARY, + ARG_NO_SPLICED_ALIGNMENT, + ARG_RNA_STRANDNESS, + ARG_SPLICESITE_DB_ONLY, + ARG_NO_ANCHORSTOP, + ARG_TRANSCRIPTOME_MAPPING_ONLY, + ARG_TRANSCRIPTOME_ASSEMBLY, + ARG_TRANSCRIPTOME_ASSEMBLY_CUFFLINKS, + ARG_AVOID_PSEUDOGENE, +#ifdef USE_SRA + ARG_SRA_ACC, +#endif + ARG_REMOVE_CHRNAME, + ARG_ADD_CHRNAME, + ARG_MAX_ALTSTRIED, + ARG_HAPLOTYPE, + ARG_CODIS, + ARG_NO_TEMPLATELEN_ADJUSTMENT, + ARG_SUMMARY_FILE, + ARG_NEW_SUMMARY, + ARG_DP, + ARG_REPEAT, + ARG_NO_REPEAT_INDEX, + ARG_READ_LENGTHS, + ARG_BASE_CHANGE, // --base-change + ARG_REPEAT_LIMIT, + ARG_UNIQUE_ONLY, + ARG_3N, + ARG_DIRECTIONAL, + ARG_DIRECTIONAL_REVERSE +}; + +#endif + diff --git a/outq.cpp b/outq.cpp new file mode 100644 index 0000000..1141675 --- /dev/null +++ b/outq.cpp @@ -0,0 +1,201 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "outq.h" + +/** + * Caller is telling us that they're about to write output record(s) for + * the read with the given id. + */ +void OutputQueue::beginRead(TReadId rdid, size_t threadId) { + ThreadSafe t(&mutex_m, threadSafe_); + nstarted_++; + if(reorder_) { + assert_geq(rdid, cur_); + assert_eq(lines_.size(), finished_.size()); + assert_eq(lines_.size(), started_.size()); + if(rdid - cur_ >= lines_.size()) { + // Make sure there's enough room in lines_, started_ and finished_ + size_t oldsz = lines_.size(); + lines_.resize(rdid - cur_ + 1); + started_.resize(rdid - cur_ + 1); + finished_.resize(rdid - cur_ + 1); + for(size_t i = oldsz; i < lines_.size(); i++) { + started_[i] = finished_[i] = false; + } + } + started_[rdid - cur_] = true; + finished_[rdid - cur_] = false; + } +} + +/** + * Writer is finished writing to + */ +void OutputQueue::finishRead(const BTString& rec, TReadId rdid, size_t threadId) { + ThreadSafe t(&mutex_m, threadSafe_); + if(reorder_) { + assert_geq(rdid, cur_); + assert_eq(lines_.size(), finished_.size()); + assert_eq(lines_.size(), started_.size()); + assert_lt(rdid - cur_, lines_.size()); + assert(started_[rdid - cur_]); + assert(!finished_[rdid - cur_]); + lines_[rdid - cur_] = rec; + nfinished_++; + finished_[rdid - cur_] = true; + flush(false, false); // don't force; already have lock + } else { + // obuf_ is the OutFileBuf for the output file + obuf_.writeString(rec); + nfinished_++; + nflushed_++; + } +} + +/** + * Write already-finished lines starting from cur_. + */ +void OutputQueue::flush(bool force, bool getLock) { + if(!reorder_) { + return; + } + ThreadSafe t(&mutex_m, getLock && threadSafe_); + size_t nflush = 0; + while(nflush < finished_.size() && finished_[nflush]) { + assert(started_[nflush]); + nflush++; + } + // Waiting until we have several in a row to flush cuts down on copies + // (but requires more buffering) + if(force || nflush >= NFLUSH_THRESH) { + for(size_t i = 0; i < nflush; i++) { + assert(started_[i]); + assert(finished_[i]); + obuf_.writeString(lines_[i]); + } + lines_.erase(0, nflush); + started_.erase(0, nflush); + finished_.erase(0, nflush); + cur_ += nflush; + nflushed_ += nflush; + } +} + +#ifdef OUTQ_MAIN + +#include + +using namespace std; + +int main(void) { + cerr << "Case 1 (one thread) ... "; + { + OutFileBuf ofb; + OutputQueue oq(ofb, false); + assert_eq(0, oq.numFlushed()); + assert_eq(0, oq.numStarted()); + assert_eq(0, oq.numFinished()); + oq.beginRead(1); + assert_eq(0, oq.numFlushed()); + assert_eq(1, oq.numStarted()); + assert_eq(0, oq.numFinished()); + oq.beginRead(3); + assert_eq(0, oq.numFlushed()); + assert_eq(2, oq.numStarted()); + assert_eq(0, oq.numFinished()); + oq.beginRead(2); + assert_eq(0, oq.numFlushed()); + assert_eq(3, oq.numStarted()); + assert_eq(0, oq.numFinished()); + oq.flush(); + assert_eq(0, oq.numFlushed()); + assert_eq(3, oq.numStarted()); + assert_eq(0, oq.numFinished()); + oq.beginRead(0); + assert_eq(0, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(0, oq.numFinished()); + oq.flush(); + assert_eq(0, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(0, oq.numFinished()); + oq.finishRead(0); + assert_eq(0, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(1, oq.numFinished()); + oq.flush(); + assert_eq(0, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(1, oq.numFinished()); + oq.flush(true); + assert_eq(1, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(1, oq.numFinished()); + oq.finishRead(2); + assert_eq(1, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(2, oq.numFinished()); + oq.flush(true); + assert_eq(1, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(2, oq.numFinished()); + oq.finishRead(1); + assert_eq(1, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(3, oq.numFinished()); + oq.flush(true); + assert_eq(3, oq.numFlushed()); + assert_eq(4, oq.numStarted()); + assert_eq(3, oq.numFinished()); + } + cerr << "PASSED" << endl; + + cerr << "Case 2 (one thread) ... "; + { + OutFileBuf ofb; + OutputQueue oq(ofb, false); + BTString& buf1 = oq.beginRead(0); + BTString& buf2 = oq.beginRead(1); + BTString& buf3 = oq.beginRead(2); + BTString& buf4 = oq.beginRead(3); + BTString& buf5 = oq.beginRead(4); + assert_eq(5, oq.numStarted()); + assert_eq(0, oq.numFinished()); + buf1.install("A\n"); + buf2.install("B\n"); + buf3.install("C\n"); + buf4.install("D\n"); + buf5.install("E\n"); + oq.finishRead(4); + oq.finishRead(1); + oq.finishRead(0); + oq.finishRead(2); + oq.finishRead(3); + oq.flush(true); + assert_eq(5, oq.numFlushed()); + assert_eq(5, oq.numStarted()); + assert_eq(5, oq.numFinished()); + ofb.flush(); + } + cerr << "PASSED" << endl; + return 0; +} + +#endif /*def ALN_SINK_MAIN*/ diff --git a/outq.h b/outq.h new file mode 100644 index 0000000..00408cf --- /dev/null +++ b/outq.h @@ -0,0 +1,149 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef OUTQ_H_ +#define OUTQ_H_ + +#include "assert_helpers.h" +#include "ds.h" +#include "sstring.h" +#include "read.h" +#include "threading.h" +#include "mem_ids.h" + +/** + * Encapsulates a list of lines of output. If the earliest as-yet-unreported + * read has id N and Bowtie 2 wants to write a record for read with id N+1, we + * resize the lines_ and committed_ lists to have at least 2 elements (1 for N, + * 1 for N+1) and return the BTString * associated with the 2nd element. When + * the user calls commit() for the read with id N, + */ +class OutputQueue { + + static const size_t NFLUSH_THRESH = 8; + +public: + + OutputQueue( + OutFileBuf& obuf, + bool reorder, + size_t nthreads, + bool threadSafe, + TReadId rdid = 0) : + obuf_(obuf), + cur_(rdid), + nstarted_(0), + nfinished_(0), + nflushed_(0), + lines_(RES_CAT), + started_(RES_CAT), + finished_(RES_CAT), + reorder_(reorder), + threadSafe_(threadSafe), + mutex_m() + { + assert(nthreads <= 1 || threadSafe); + } + + /** + * Caller is telling us that they're about to write output record(s) for + * the read with the given id. + */ + void beginRead(TReadId rdid, size_t threadId); + + /** + * Writer is finished writing to + */ + void finishRead(const BTString& rec, TReadId rdid, size_t threadId); + + /** + * Return the number of records currently being buffered. + */ + size_t size() const { + return lines_.size(); + } + + /** + * Return the number of records that have been flushed so far. + */ + TReadId numFlushed() const { + return nflushed_; + } + + /** + * Return the number of records that have been started so far. + */ + TReadId numStarted() const { + return nstarted_; + } + + /** + * Return the number of records that have been finished so far. + */ + TReadId numFinished() const { + return nfinished_; + } + + /** + * Write already-committed lines starting from cur_. + */ + void flush(bool force = false, bool getLock = true); + +protected: + + OutFileBuf& obuf_; + TReadId cur_; + TReadId nstarted_; + TReadId nfinished_; + TReadId nflushed_; + EList lines_; + EList started_; + EList finished_; + bool reorder_; + bool threadSafe_; + MUTEX_T mutex_m; +}; + +class OutputQueueMark { +public: + OutputQueueMark( + OutputQueue& q, + const BTString& rec, + TReadId rdid, + size_t threadId) : + q_(q), + rec_(rec), + rdid_(rdid), + threadId_(threadId) + { + q_.beginRead(rdid, threadId); + } + + ~OutputQueueMark() { + q_.finishRead(rec_, rdid_, threadId_); + } + +protected: + OutputQueue& q_; + const BTString& rec_; + TReadId rdid_; + size_t threadId_; +}; + +#endif diff --git a/pat.cpp b/pat.cpp new file mode 100644 index 0000000..16dfad2 --- /dev/null +++ b/pat.cpp @@ -0,0 +1,1824 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include +#include +#include "sstring.h" + +#include "pat.h" +#include "filebuf.h" +#include "formats.h" + +#ifdef USE_SRA + +#include "tinythread.h" +#include +#include +#include +#include +#include + +#endif + +using namespace std; + +/** + * Return a new dynamically allocated PatternSource for the given + * format, using the given list of strings as the filenames to read + * from or as the sequences themselves (i.e. if -c was used). + */ +PatternSource* PatternSource::patsrcFromStrings( + const PatternParams& p, + const EList& qs, + size_t nthreads) +{ + switch(p.format) { + case FASTA: return new FastaPatternSource(qs, p); + case FASTA_CONT: return new FastaContinuousPatternSource(qs, p); + case RAW: return new RawPatternSource(qs, p); + case FASTQ: return new FastqPatternSource(qs, p); + case TAB_MATE5: return new TabbedPatternSource(qs, p, false); + case TAB_MATE6: return new TabbedPatternSource(qs, p, true); + case CMDLINE: return new VectorPatternSource(qs, p); + case QSEQ: return new QseqPatternSource(qs, p); +#ifdef USE_SRA + case SRA_FASTA: + case SRA_FASTQ: return new SRAPatternSource(qs, p, nthreads); +#endif + default: { + cerr << "Internal error; bad patsrc format: " << p.format << endl; + throw 1; + } + } +} + +/** + * The main member function for dispensing patterns. + * + * Returns true iff a pair was parsed succesfully. + */ +bool PatternSource::nextReadPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired, + bool fixName) +{ + // nextPatternImpl does the reading from the ultimate source; + // it is implemented in concrete subclasses + success = done = paired = false; + nextReadPairImpl(ra, rb, rdid, endid, success, done, paired); + if(success) { + // Construct reversed versions of fw and rc seqs/quals + ra.finalize(); + if(!rb.empty()) { + rb.finalize(); + } + // Fill in the random-seed field using a combination of + // information from the user-specified seed and the read + // sequence, qualities, and name + ra.seed = genRandSeed(ra.patFw, ra.qual, ra.name, seed_); + if(!rb.empty()) { + rb.seed = genRandSeed(rb.patFw, rb.qual, rb.name, seed_); + } + } + return success; +} + +/** + * The main member function for dispensing patterns. + */ +bool PatternSource::nextRead( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) +{ + // nextPatternImpl does the reading from the ultimate source; + // it is implemented in concrete subclasses + nextReadImpl(r, rdid, endid, success, done); + if(success) { + // Construct the reversed versions of the fw and rc seqs + // and quals + r.finalize(); + // Fill in the random-seed field using a combination of + // information from the user-specified seed and the read + // sequence, qualities, and name + r.seed = genRandSeed(r.patFw, r.qual, r.name, seed_); + } + return success; +} + +/** + * Get the next paired or unpaired read from the wrapped + * PairedPatternSource. + */ +bool WrappedPatternSourcePerThread::nextReadPair( + bool& success, + bool& done, + bool& paired, + bool fixName) +{ + PatternSourcePerThread::nextReadPair(success, done, paired, fixName); + ASSERT_ONLY(TReadId lastRdId = rdid_); + buf1_.reset(); + buf2_.reset(); + patsrc_.nextReadPair(buf1_, buf2_, rdid_, endid_, success, done, paired, fixName); + assert(!success || rdid_ != lastRdId); + return success; +} + +/** + * The main member function for dispensing pairs of reads or + * singleton reads. Returns true iff ra and rb contain a new + * pair; returns false if ra contains a new unpaired read. + */ +bool PairedSoloPatternSource::nextReadPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired, + bool fixName) +{ + uint32_t cur = cur_; + success = false; + while(cur < src_->size()) { + // Patterns from srca_[cur_] are unpaired + do { + (*src_)[cur]->nextReadPair( + ra, rb, rdid, endid, success, done, paired, fixName); + } while(!success && !done); + if(!success) { + assert(done); + // If patFw is empty, that's our signal that the + // input dried up + lock(); + if(cur + 1 > cur_) cur_++; + cur = cur_; + unlock(); + continue; // on to next pair of PatternSources + } + assert(success); + ra.seed = genRandSeed(ra.patFw, ra.qual, ra.name, seed_); + if(!rb.empty()) { + rb.seed = genRandSeed(rb.patFw, rb.qual, rb.name, seed_); + if(fixName) { + ra.fixMateName(1); + rb.fixMateName(2); + } + } + ra.rdid = rdid; + ra.endid = endid; + if(!rb.empty()) { + rb.rdid = rdid; + rb.endid = endid+1; + } + ra.mate = 1; + rb.mate = 2; + return true; // paired + } + assert_leq(cur, src_->size()); + done = (cur == src_->size()); + return false; +} + +/** + * The main member function for dispensing pairs of reads or + * singleton reads. Returns true iff ra and rb contain a new + * pair; returns false if ra contains a new unpaired read. + */ +bool PairedDualPatternSource::nextReadPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired, + bool fixName) +{ + // 'cur' indexes the current pair of PatternSources + uint32_t cur; + { + lock(); + cur = cur_; + unlock(); + } + success = false; + done = true; + while(cur < srca_->size()) { + if((*srcb_)[cur] == NULL) { + paired = false; + // Patterns from srca_ are unpaired + do { + (*srca_)[cur]->nextRead(ra, rdid, endid, success, done); + } while(!success && !done); + if(!success) { + assert(done); + lock(); + if(cur + 1 > cur_) cur_++; + cur = cur_; // Move on to next PatternSource + unlock(); + continue; // on to next pair of PatternSources + } + ra.rdid = rdid; + ra.endid = endid; + ra.mate = 0; + return success; + } else { + paired = true; + // Patterns from srca_[cur_] and srcb_[cur_] are paired + TReadId rdid_a = 0, endid_a = 0; + TReadId rdid_b = 0, endid_b = 0; + bool success_a = false, done_a = false; + bool success_b = false, done_b = false; + // Lock to ensure that this thread gets parallel reads + // in the two mate files + lock(); + do { + (*srca_)[cur]->nextRead(ra, rdid_a, endid_a, success_a, done_a); + } while(!success_a && !done_a); + do { + (*srcb_)[cur]->nextRead(rb, rdid_b, endid_b, success_b, done_b); + } while(!success_b && !done_b); + if(!success_a && success_b) { + cerr << "Error, fewer reads in file specified with -1 than in file specified with -2" << endl; + throw 1; + } else if(!success_a) { + assert(done_a && done_b); + if(cur + 1 > cur_) cur_++; + cur = cur_; // Move on to next PatternSource + unlock(); + continue; // on to next pair of PatternSources + } else if(!success_b) { + cerr << "Error, fewer reads in file specified with -2 than in file specified with -1" << endl; + throw 1; + } + assert_eq(rdid_a, rdid_b); + //assert_eq(endid_a+1, endid_b); + assert_eq(success_a, success_b); + unlock(); + if(fixName) { + ra.fixMateName(1); + rb.fixMateName(2); + } + rdid = rdid_a; + endid = endid_a; + success = success_a; + done = done_a; + ra.rdid = rdid; + ra.endid = endid; + if(!rb.empty()) { + rb.rdid = rdid; + rb.endid = endid+1; + } + ra.mate = 1; + rb.mate = 2; + return success; + } + } + return success; +} + +/** + * Return the number of reads attempted. + */ +pair PairedDualPatternSource::readCnt() const { + uint64_t rets = 0llu, retp = 0llu; + for(size_t i = 0; i < srca_->size(); i++) { + if((*srcb_)[i] == NULL) { + rets += (*srca_)[i]->readCnt(); + } else { + assert_eq((*srca_)[i]->readCnt(), (*srcb_)[i]->readCnt()); + retp += (*srca_)[i]->readCnt(); + } + } + return make_pair(rets, retp); +} + +/** + * Given the values for all of the various arguments used to specify + * the read and quality input, create a list of pattern sources to + * dispense them. + */ +PairedPatternSource* PairedPatternSource::setupPatternSources( + const EList& si, // singles, from argv + const EList& m1, // mate1's, from -1 arg + const EList& m2, // mate2's, from -2 arg + const EList& m12, // both mates on each line, from --12 arg +#ifdef USE_SRA + const EList& sra_accs, +#endif + const EList& q, // qualities associated with singles + const EList& q1, // qualities associated with m1 + const EList& q2, // qualities associated with m2 + const PatternParams& p, // read-in parameters + size_t nthreads, + bool verbose) // be talkative? +{ + EList* a = new EList(); + EList* b = new EList(); + EList* ab = new EList(); + // Create list of pattern sources for paired reads appearing + // interleaved in a single file + for(size_t i = 0; i < m12.size(); i++) { + const EList* qs = &m12; + EList tmp; + if(p.fileParallel) { + // Feed query files one to each PatternSource + qs = &tmp; + tmp.push_back(m12[i]); + assert_eq(1, tmp.size()); + } + ab->push_back(PatternSource::patsrcFromStrings(p, *qs, nthreads)); + if(!p.fileParallel) { + break; + } + } + +#ifdef USE_SRA + for(size_t i = 0; i < sra_accs.size(); i++) { + const EList* qs = &sra_accs; + EList tmp; + if(p.fileParallel) { + // Feed query files one to each PatternSource + qs = &tmp; + tmp.push_back(sra_accs[i]); + assert_eq(1, tmp.size()); + } + ab->push_back(PatternSource::patsrcFromStrings(p, *qs, nthreads)); + if(!p.fileParallel) { + break; + } + } +#endif + + // Create list of pattern sources for paired reads + for(size_t i = 0; i < m1.size(); i++) { + const EList* qs = &m1; + EList tmpSeq; + EList tmpQual; + if(p.fileParallel) { + // Feed query files one to each PatternSource + qs = &tmpSeq; + tmpSeq.push_back(m1[i]); + assert_eq(1, tmpSeq.size()); + } + + PatternSource *patsrc = PatternSource::patsrcFromStrings(p, *qs, nthreads); + patsrc->paired_type = 1; + a->push_back(patsrc); + + if(!p.fileParallel) { + break; + } + } + + // Create list of pattern sources for paired reads + for(size_t i = 0; i < m2.size(); i++) { + const EList* qs = &m2; + EList tmpSeq; + EList tmpQual; + if(p.fileParallel) { + // Feed query files one to each PatternSource + qs = &tmpSeq; + tmpSeq.push_back(m2[i]); + assert_eq(1, tmpSeq.size()); + } + PatternSource *patsrc = PatternSource::patsrcFromStrings(p, *qs, nthreads); + patsrc->paired_type = 2; + b->push_back(patsrc); + + + if(!p.fileParallel) { + break; + } + } + // All mates/mate files must be paired + assert_eq(a->size(), b->size()); + + // Create list of pattern sources for the unpaired reads + for(size_t i = 0; i < si.size(); i++) { + const EList* qs = &si; + PatternSource* patsrc = NULL; + EList tmpSeq; + EList tmpQual; + if(p.fileParallel) { + // Feed query files one to each PatternSource + qs = &tmpSeq; + tmpSeq.push_back(si[i]); + assert_eq(1, tmpSeq.size()); + } + patsrc = PatternSource::patsrcFromStrings(p, *qs, nthreads); + patsrc->paired_type = 1; + assert(patsrc != NULL); + a->push_back(patsrc); + b->push_back(NULL); + if(!p.fileParallel) { + break; + } + } + + PairedPatternSource *patsrc = NULL; +#ifdef USE_SRA + if(m12.size() > 0 || sra_accs.size() > 0) { +#else + if(m12.size() > 0) { +#endif + patsrc = new PairedSoloPatternSource(ab, p); + for(size_t i = 0; i < a->size(); i++) delete (*a)[i]; + for(size_t i = 0; i < b->size(); i++) delete (*b)[i]; + delete a; delete b; + } else { + patsrc = new PairedDualPatternSource(a, b, p); + for(size_t i = 0; i < ab->size(); i++) delete (*ab)[i]; + delete ab; + } + return patsrc; +} + +VectorPatternSource::VectorPatternSource( + const EList& v, + const PatternParams& p) : + PatternSource(p), + cur_(p.skip), + skip_(p.skip), + paired_(false), + v_(), + quals_() +{ + for(size_t i = 0; i < v.size(); i++) { + EList ss; + tokenize(v[i], ":", ss, 2); + assert_gt(ss.size(), 0); + assert_leq(ss.size(), 2); + // Initialize s + string s = ss[0]; + int mytrim5 = gTrim5; + if(gColor && s.length() > 1) { + // This may be a primer character. If so, keep it in the + // 'primer' field of the read buf and parse the rest of the + // read without it. + int c = toupper(s[0]); + if(asc2dnacat[c] > 0) { + // First char is a DNA char + int c2 = toupper(s[1]); + // Second char is a color char + if(asc2colcat[c2] > 0) { + mytrim5 += 2; // trim primer and first color + } + } + } + if(gColor) { + // Convert '0'-'3' to 'A'-'T' + for(size_t i = 0; i < s.length(); i++) { + if(s[i] >= '0' && s[i] <= '4') { + s[i] = "ACGTN"[(int)s[i] - '0']; + } + if(s[i] == '.') s[i] = 'N'; + } + } + if(s.length() <= (size_t)(gTrim3 + mytrim5)) { + // Entire read is trimmed away + s.clear(); + } else { + // Trim on 5' (high-quality) end + if(mytrim5 > 0) { + s.erase(0, mytrim5); + } + // Trim on 3' (low-quality) end + if(gTrim3 > 0) { + s.erase(s.length()-gTrim3); + } + } + // Initialize vq + string vq; + if(ss.size() == 2) { + vq = ss[1]; + } + // Trim qualities + if(vq.length() > (size_t)(gTrim3 + mytrim5)) { + // Trim on 5' (high-quality) end + if(mytrim5 > 0) { + vq.erase(0, mytrim5); + } + // Trim on 3' (low-quality) end + if(gTrim3 > 0) { + vq.erase(vq.length()-gTrim3); + } + } + // Pad quals with Is if necessary; this shouldn't happen + while(vq.length() < s.length()) { + vq.push_back('I'); + } + // Truncate quals to match length of read if necessary; + // this shouldn't happen + if(vq.length() > s.length()) { + vq.erase(s.length()); + } + assert_eq(vq.length(), s.length()); + v_.expand(); + v_.back().installChars(s); + quals_.push_back(BTString(vq)); + trimmed3_.push_back(gTrim3); + trimmed5_.push_back(mytrim5); + ostringstream os; + os << (names_.size()); + names_.push_back(BTString(os.str())); + } + assert_eq(v_.size(), quals_.size()); +} + +bool VectorPatternSource::nextReadImpl( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) +{ + // Let Strings begin at the beginning of the respective bufs + r.reset(); + lock(); + if(cur_ >= v_.size()) { + unlock(); + // Clear all the Strings, as a signal to the caller that + // we're out of reads + r.reset(); + success = false; + done = true; + assert(r.empty()); + return false; + } + // Copy v_*, quals_* strings into the respective Strings + r.color = gColor; + r.patFw = v_[cur_]; + r.patFw_3N = v_[cur_]; + r.qual = quals_[cur_]; + r.trimmed3 = trimmed3_[cur_]; + r.trimmed5 = trimmed5_[cur_]; + ostringstream os; + os << cur_; + r.name = os.str(); + cur_++; + done = cur_ == v_.size(); + rdid = endid = readCnt_; + readCnt_++; + unlock(); + success = true; + return true; +} + +/** + * This is unused, but implementation is given for completeness. + */ +bool VectorPatternSource::nextReadPairImpl( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) +{ + // Let Strings begin at the beginning of the respective bufs + ra.reset(); + rb.reset(); + paired = true; + if(!paired_) { + paired_ = true; + cur_ <<= 1; + } + lock(); + if(cur_ >= v_.size()-1) { + unlock(); + // Clear all the Strings, as a signal to the caller that + // we're out of reads + ra.reset(); + rb.reset(); + assert(ra.empty()); + assert(rb.empty()); + success = false; + done = true; + return false; + } + // Copy v_*, quals_* strings into the respective Strings + ra.patFw = v_[cur_]; + ra.qual = quals_[cur_]; + ra.trimmed3 = trimmed3_[cur_]; + ra.trimmed5 = trimmed5_[cur_]; + cur_++; + rb.patFw = v_[cur_]; + rb.qual = quals_[cur_]; + rb.trimmed3 = trimmed3_[cur_]; + rb.trimmed5 = trimmed5_[cur_]; + ostringstream os; + os << readCnt_; + ra.name = os.str(); + rb.name = os.str(); + ra.color = rb.color = gColor; + cur_++; + done = cur_ >= v_.size()-1; + rdid = endid = readCnt_; + readCnt_++; + unlock(); + success = true; + return true; +} + +/** + * Parse a single quality string from fb and store qualities in r. + * Assume the next character obtained via fb.get() is the first + * character of the quality string. When returning, the next + * character returned by fb.peek() or fb.get() should be the first + * character of the following line. + */ +int parseQuals( + Read& r, + FileBuf& fb, + int firstc, + int readLen, + int trim3, + int trim5, + bool intQuals, + bool phred64, + bool solexa64) +{ + int c = firstc; + assert(c != '\n' && c != '\r'); + r.qual.clear(); + if (intQuals) { + while (c != '\r' && c != '\n' && c != -1) { + bool neg = false; + int num = 0; + while(!isspace(c) && !fb.eof()) { + if(c == '-') { + neg = true; + assert_eq(num, 0); + } else { + if(!isdigit(c)) { + char buf[2048]; + cerr << "Warning: could not parse quality line:" << endl; + fb.getPastNewline(); + cerr << fb.copyLastN(buf); + buf[2047] = '\0'; + cerr << buf; + throw 1; + } + assert(isdigit(c)); + num *= 10; + num += (c - '0'); + } + c = fb.get(); + } + if(neg) num = 0; + // Phred-33 ASCII encode it and add it to the back of the + // quality string + r.qual.append('!' + num); + // Skip over next stretch of whitespace + while(c != '\r' && c != '\n' && isspace(c) && !fb.eof()) { + c = fb.get(); + } + } + } else { + while (c != '\r' && c != '\n' && c != -1) { + r.qual.append(charToPhred33(c, solexa64, phred64)); + c = fb.get(); + while(c != '\r' && c != '\n' && isspace(c) && !fb.eof()) { + c = fb.get(); + } + } + } + if ((int)r.qual.length() < readLen-1 || + ((int)r.qual.length() < readLen && !r.color)) + { + tooFewQualities(r.name); + } + r.qual.trimEnd(trim3); + if(r.qual.length()-trim5 < r.patFw.length()) { + assert(gColor && r.primer != -1); + assert_gt(trim5, 0); + trim5--; + } + r.qual.trimBegin(trim5); + if(r.qual.length() <= 0) return 0; + assert_eq(r.qual.length(), r.patFw.length()); + while(fb.peek() == '\n' || fb.peek() == '\r') fb.get(); + return (int)r.qual.length(); +} + +/// Read another pattern from a FASTA input file +bool FastaPatternSource::read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) +{ + int c, qc = 0; + success = true; + done = false; + assert(fb_.isOpen()); + r.reset(); + r.color = gColor; + // Pick off the first carat + c = fb_.get(); + if(c < 0) { + bail(r); success = false; done = true; return success; + } + while(c == '#' || c == ';' || c == '\r' || c == '\n') { + c = fb_.peekUptoNewline(); + fb_.resetLastN(); + c = fb_.get(); + } + assert_eq(1, fb_.lastNLen()); + + // Pick off the first carat + if(first_) { + if(c != '>') { + cerr << "Error: reads file does not look like a FASTA file" << endl; + throw 1; + } + first_ = false; + } + assert_eq('>', c); + c = fb_.get(); // get next char after '>' + + // Read to the end of the id line, sticking everything after the '>' + // into *name + //bool warning = false; + while(true) { + if(c < 0 || qc < 0) { + bail(r); success = false; done = true; return success; + } + if(c == '\n' || c == '\r') { + // Break at end of line, after consuming all \r's, \n's + while(c == '\n' || c == '\r') { + if(fb_.peek() == '>') { + // Empty sequence + break; + } + c = fb_.get(); + if(c < 0 || qc < 0) { + bail(r); success = false; done = true; return success; + } + } + break; + } + r.name.append(c); + if(fb_.peek() == '>') { + // Empty sequence + break; + } + c = fb_.get(); + } + if(c == '>') { + // Empty sequences! + cerr << "Warning: skipping empty FASTA read with name '" << r.name << "'" << endl; + fb_.resetLastN(); + rdid = endid = readCnt_; + readCnt_++; + success = true; done = false; return success; + } + assert_neq('>', c); + + // _in now points just past the first character of a sequence + // line, and c holds the first character + int begin = 0; + int mytrim5 = gTrim5; + if(gColor) { + // This is the primer character, keep it in the + // 'primer' field of the read buf and keep parsing + c = toupper(c); + if(asc2dnacat[c] > 0) { + // First char is a DNA char + int c2 = toupper(fb_.peek()); + if(asc2colcat[c2] > 0) { + // Second char is a color char + r.primer = c; + r.trimc = c2; + mytrim5 += 2; + } + } + if(c < 0) { + bail(r); success = false; done = true; return success; + } + } + while(c != '>' && c >= 0) { + if(gColor) { + if(c >= '0' && c <= '4') c = "ACGTN"[(int)c - '0']; + if(c == '.') c = 'N'; + } + if(asc2dnacat[c] > 0 && begin++ >= mytrim5) { + r.patFw.append(asc2dna_3N[0][c]); + if (threeN) { + r.patFw_3N.append(asc2dna_3N[1][c]); + r.originalFw.append((asc2dna[c])); + } + r.qual.append('I'); + } + if(fb_.peek() == '>') break; + c = fb_.get(); + } + + r.patFw.trimEnd(gTrim3); + if (threeN) r.patFw_3N.trimEnd(gTrim3); + r.qual.trimEnd(gTrim3); + r.trimmed3 = gTrim3; + r.trimmed5 = mytrim5; + // Set up a default name if one hasn't been set + if(r.name.empty()) { + char cbuf[20]; + itoa10(readCnt_, cbuf); + r.name.install(cbuf); + } + assert_gt(r.name.length(), 0); + r.readOrigBuf.install(fb_.lastN(), fb_.lastNLen()); + fb_.resetLastN(); + rdid = endid = readCnt_; + readCnt_++; + return success; +} + +/// Read another pattern from a FASTQ input file +bool FastqPatternSource::read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) +{ + int c; + int dstLen = 0; + success = true; + done = false; + r.reset(); + r.color = gColor; + r.fuzzy = fuzzy_; + // Pick off the first at + if(first_) { + c = fb_.get(); + if(c != '@') { + c = getOverNewline(fb_); + if(c < 0) { + bail(r); success = false; done = true; return success; + } + } + if(c != '@') { + cerr << "Error: reads file does not look like a FASTQ file" << endl; + throw 1; + } + assert_eq('@', c); + first_ = false; + } + + // Read to the end of the id line, sticking everything after the '@' + // into *name + while(true) { + c = fb_.get(); + if(c < 0) { + bail(r); success = false; done = true; return success; + } + if(c == '\n' || c == '\r') { + // Break at end of line, after consuming all \r's, \n's + while(c == '\n' || c == '\r') { + c = fb_.get(); + if(c < 0) { + bail(r); success = false; done = true; return success; + } + } + break; + } + r.name.append(c); + } + // fb_ now points just past the first character of a + // sequence line, and c holds the first character + int charsRead = 0; + BTDnaString *sbuf = &r.patFw; + int dstLens[] = {0, 0, 0, 0}; + int *dstLenCur = &dstLens[0]; + int mytrim5 = gTrim5; + int altBufIdx = 0; + if(gColor && c != '+') { + // This may be a primer character. If so, keep it in the + // 'primer' field of the read buf and parse the rest of the + // read without it. + c = toupper(c); + if(asc2dnacat[c] > 0) { + // First char is a DNA char + int c2 = toupper(fb_.peek()); + // Second char is a color char + if(asc2colcat[c2] > 0) { + r.primer = c; + r.trimc = c2; + mytrim5 += 2; // trim primer and first color + } + } + if(c < 0) { + bail(r); success = false; done = true; return success; + } + } + int trim5 = 0; + if(c != '+') { + trim5 = mytrim5; + while(c != '+') { + // Convert color numbers to letters if necessary + if(c == '.') c = 'N'; + if(gColor) { + if(c >= '0' && c <= '4') c = "ACGTN"[(int)c - '0']; + } + if(fuzzy_ && c == '-') c = 'A'; + if(isalpha(c)) { + // If it's past the 5'-end trim point + if(charsRead >= trim5) { + r.patFw.append(asc2dna_3N[0][c]); + if (threeN) { + r.patFw_3N.append(asc2dna_3N[1][c]); + r.originalFw.append((asc2dna[c])); + } + (*dstLenCur)++; + } + charsRead++; + } else if(fuzzy_ && c == ' ') { + trim5 = 0; // disable 5' trimming for now + if(charsRead == 0) { + c = fb_.get(); + continue; + } + charsRead = 0; + if(altBufIdx >= 3) { + cerr << "At most 3 alternate sequence strings permitted; offending read: " << r.name << endl; + throw 1; + } + // Move on to the next alternate-sequence buffer + sbuf = &r.altPatFw[altBufIdx++]; + dstLenCur = &dstLens[altBufIdx]; + } + c = fb_.get(); + if(c < 0) { + bail(r); success = false; done = true; return success; + } + } + dstLen = dstLens[0]; + charsRead = dstLen + mytrim5; + } + // Trim from 3' end + if(gTrim3 > 0) { + if((int)r.patFw.length() > gTrim3) { + r.patFw.resize(r.patFw.length() - gTrim3); + dstLen -= gTrim3; + assert_eq((int)r.patFw.length(), dstLen); + } else { + // Trimmed the whole read; we won't be using this read, + // but we proceed anyway so that fb_ is advanced + // properly + r.patFw.clear(); + dstLen = 0; + } + } + assert_eq('+', c); + + // Chew up the optional name on the '+' line + ASSERT_ONLY(int pk =) peekToEndOfLine(fb_); + if(charsRead == 0) { + assert_eq('@', pk); + fb_.get(); + fb_.resetLastN(); + rdid = endid = readCnt_; + readCnt_++; + return success; + } + + // Now read the qualities + if (intQuals_) { + assert(!fuzzy_); + int qualsRead = 0; + char buf[4096]; + if(gColor && r.primer != -1) { + // In case the original quality string is one shorter + mytrim5--; + } + qualToks_.clear(); + tokenizeQualLine(fb_, buf, 4096, qualToks_); + for(unsigned int j = 0; j < qualToks_.size(); ++j) { + char c = intToPhred33(atoi(qualToks_[j].c_str()), solQuals_); + assert_geq(c, 33); + if (qualsRead >= mytrim5) { + r.qual.append(c); + } + ++qualsRead; + } // done reading integer quality lines + if(gColor && r.primer != -1) mytrim5++; + r.qual.trimEnd(gTrim3); + if(r.qual.length() < r.patFw.length()) { + tooFewQualities(r.name); + } else if(r.qual.length() > r.patFw.length() + 1) { + tooManyQualities(r.name); + } + if(r.qual.length() == r.patFw.length()+1 && gColor && r.primer != -1) { + r.qual.remove(0); + } + // Trim qualities on 3' end + if(r.qual.length() > r.patFw.length()) { + r.qual.resize(r.patFw.length()); + assert_eq((int)r.qual.length(), dstLen); + } + peekOverNewline(fb_); + } else { + // Non-integer qualities + altBufIdx = 0; + trim5 = mytrim5; + int qualsRead[4] = {0, 0, 0, 0}; + int *qualsReadCur = &qualsRead[0]; + BTString *qbuf = &r.qual; + if(gColor && r.primer != -1) { + // In case the original quality string is one shorter + trim5--; + } + while(true) { + c = fb_.get(); + if (!fuzzy_ && c == ' ') { + wrongQualityFormat(r.name); + } else if(c == ' ') { + trim5 = 0; // disable 5' trimming for now + if((*qualsReadCur) == 0) continue; + if(altBufIdx >= 3) { + cerr << "At most 3 alternate quality strings permitted; offending read: " << r.name << endl; + throw 1; + } + qbuf = &r.altQual[altBufIdx++]; + qualsReadCur = &qualsRead[altBufIdx]; + continue; + } + if(c < 0) { + break; // let the file end just at the end of a quality line + //bail(r); success = false; done = true; return success; + } + if (c != '\r' && c != '\n') { + if (*qualsReadCur >= trim5) { + c = charToPhred33(c, solQuals_, phred64Quals_); + assert_geq(c, 33); + qbuf->append(c); + } + (*qualsReadCur)++; + } else { + break; + } + } + qualsRead[0] -= gTrim3; + r.qual.trimEnd(gTrim3); + if(r.qual.length() < r.patFw.length()) { + tooFewQualities(r.name); + } else if(r.qual.length() > r.patFw.length()+1) { + tooManyQualities(r.name); + } + if(r.qual.length() == r.patFw.length()+1 && gColor && r.primer != -1) { + r.qual.remove(0); + } + + if(fuzzy_) { + // Trim from 3' end of alternate basecall and quality strings + if(gTrim3 > 0) { + for(int i = 0; i < 3; i++) { + assert_eq(r.altQual[i].length(), r.altPatFw[i].length()); + if((int)r.altQual[i].length() > gTrim3) { + r.altPatFw[i].resize(gTrim3); + r.altQual[i].resize(gTrim3); + } else { + r.altPatFw[i].clear(); + r.altQual[i].clear(); + } + qualsRead[i+1] = dstLens[i+1] = + max(0, dstLens[i+1] - gTrim3); + } + } + // Shift to RHS, and install in Strings + assert_eq(0, r.alts); + for(int i = 1; i < 4; i++) { + if(qualsRead[i] == 0) continue; + if(qualsRead[i] > dstLen) { + // Shift everybody up + int shiftAmt = qualsRead[i] - dstLen; + for(int j = 0; j < dstLen; j++) { + r.altQual[i-1].set(r.altQual[i-1][j+shiftAmt], j); + r.altPatFw[i-1].set(r.altPatFw[i-1][j+shiftAmt], j); + } + r.altQual[i-1].resize(dstLen); + r.altPatFw[i-1].resize(dstLen); + } else if (qualsRead[i] < dstLen) { + r.altQual[i-1].resize(dstLen); + r.altPatFw[i-1].resize(dstLen); + // Shift everybody down + int shiftAmt = dstLen - qualsRead[i]; + for(int j = dstLen-1; j >= shiftAmt; j--) { + r.altQual[i-1].set(r.altQual[i-1][j-shiftAmt], j); + r.altPatFw[i-1].set(r.altPatFw[i-1][j-shiftAmt], j); + } + // Fill in unset positions + for(int j = 0; j < shiftAmt; j++) { + // '!' - indicates no alternate basecall at + // this position + r.altQual[i-1].set(33, j); + } + } + r.alts++; + } + } + + if(c == '\r' || c == '\n') { + c = peekOverNewline(fb_); + } else { + c = peekToEndOfLine(fb_); + } + } + r.readOrigBuf.install(fb_.lastN(), fb_.lastNLen()); + fb_.resetLastN(); + + c = fb_.get(); + // Should either be at end of file or at beginning of next record + assert(c == -1 || c == '@'); + + // Set up a default name if one hasn't been set + if(r.name.empty()) { + char cbuf[20]; + itoa10(readCnt_, cbuf); + r.name.install(cbuf); + } + r.trimmed3 = gTrim3; + r.trimmed5 = mytrim5; + rdid = endid = readCnt_; + readCnt_++; + return success; +} + +/// Read another pattern from a FASTA input file +bool TabbedPatternSource::read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) +{ + r.reset(); + r.color = gColor; + success = true; + done = false; + // fb_ is about to dish out the first character of the + // name field + if(parseName(r, NULL, '\t') == -1) { + peekOverNewline(fb_); // skip rest of line + r.reset(); + success = false; + done = true; + return false; + } + assert_neq('\t', fb_.peek()); + + // fb_ is about to dish out the first character of the + // sequence field + int charsRead = 0; + int mytrim5 = gTrim5; + int dstLen = parseSeq(r, charsRead, mytrim5, '\t'); + assert_neq('\t', fb_.peek()); + if(dstLen < 0) { + peekOverNewline(fb_); // skip rest of line + r.reset(); + success = false; + done = true; + return false; + } + + // fb_ is about to dish out the first character of the + // quality-string field + char ct = 0; + if(parseQuals(r, charsRead, dstLen, mytrim5, ct, '\n') < 0) { + peekOverNewline(fb_); // skip rest of line + r.reset(); + success = false; + done = true; + return false; + } + r.trimmed3 = gTrim3; + r.trimmed5 = mytrim5; + assert_eq(ct, '\n'); + assert_neq('\n', fb_.peek()); + r.readOrigBuf.install(fb_.lastN(), fb_.lastNLen()); + fb_.resetLastN(); + rdid = endid = readCnt_; + readCnt_++; + return true; +} + +/// Read another pair of patterns from a FASTA input file +bool TabbedPatternSource::readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) +{ + success = true; + done = false; + + // Skip over initial vertical whitespace + if(fb_.peek() == '\r' || fb_.peek() == '\n') { + fb_.peekUptoNewline(); + fb_.resetLastN(); + } + + // fb_ is about to dish out the first character of the + // name field + int mytrim5_1 = gTrim5; + if(parseName(ra, &rb, '\t') == -1) { + peekOverNewline(fb_); // skip rest of line + ra.reset(); + rb.reset(); + fb_.resetLastN(); + success = false; + done = true; + return false; + } + assert_neq('\t', fb_.peek()); + + // fb_ is about to dish out the first character of the + // sequence field for the first mate + int charsRead1 = 0; + int dstLen1 = parseSeq(ra, charsRead1, mytrim5_1, '\t'); + if(dstLen1 < 0) { + peekOverNewline(fb_); // skip rest of line + ra.reset(); + rb.reset(); + fb_.resetLastN(); + success = false; + done = true; + return false; + } + assert_neq('\t', fb_.peek()); + + // fb_ is about to dish out the first character of the + // quality-string field + char ct = 0; + if(parseQuals(ra, charsRead1, dstLen1, mytrim5_1, ct, '\t', '\n') < 0) { + peekOverNewline(fb_); // skip rest of line + ra.reset(); + rb.reset(); + fb_.resetLastN(); + success = false; + done = true; + return false; + } + ra.trimmed3 = gTrim3; + ra.trimmed5 = mytrim5_1; + assert(ct == '\t' || ct == '\n' || ct == '\r' || ct == -1); + if(ct == '\r' || ct == '\n' || ct == -1) { + // Only had 3 fields prior to newline, so this must be an unpaired read + rb.reset(); + ra.readOrigBuf.install(fb_.lastN(), fb_.lastNLen()); + fb_.resetLastN(); + success = true; + done = false; + paired = false; + rdid = endid = readCnt_; + readCnt_++; + return success; + } + paired = true; + assert_neq('\t', fb_.peek()); + + // Saw another tab after the third field, so this must be a pair + if(secondName_) { + // The second mate has its own name + if(parseName(rb, NULL, '\t') == -1) { + peekOverNewline(fb_); // skip rest of line + ra.reset(); + rb.reset(); + fb_.resetLastN(); + success = false; + done = true; + return false; + } + assert_neq('\t', fb_.peek()); + } + + // fb_ about to give the first character of the second mate's sequence + int charsRead2 = 0; + int mytrim5_2 = gTrim5; + int dstLen2 = parseSeq(rb, charsRead2, mytrim5_2, '\t'); + if(dstLen2 < 0) { + peekOverNewline(fb_); // skip rest of line + ra.reset(); + rb.reset(); + fb_.resetLastN(); + success = false; + done = true; + return false; + } + assert_neq('\t', fb_.peek()); + + // fb_ is about to dish out the first character of the + // quality-string field + if(parseQuals(rb, charsRead2, dstLen2, mytrim5_2, ct, '\n') < 0) { + peekOverNewline(fb_); // skip rest of line + ra.reset(); + rb.reset(); + fb_.resetLastN(); + success = false; + done = true; + return false; + } + ra.readOrigBuf.install(fb_.lastN(), fb_.lastNLen()); + fb_.resetLastN(); + rb.trimmed3 = gTrim3; + rb.trimmed5 = mytrim5_2; + rdid = endid = readCnt_; + readCnt_++; + return true; +} + +/** + * Parse a name from fb_ and store in r. Assume that the next + * character obtained via fb_.get() is the first character of + * the sequence and the string stops at the next char upto (could + * be tab, newline, etc.). + */ +int TabbedPatternSource::parseName( + Read& r, + Read* r2, + char upto /* = '\t' */) +{ + // Read the name out of the first field + int c = 0; + if(r2 != NULL) r2->name.clear(); + r.name.clear(); + while(true) { + if((c = fb_.get()) < 0) { + return -1; + } + if(c == upto) { + // Finished with first field + break; + } + if(c == '\n' || c == '\r') { + return -1; + } + if(r2 != NULL) r2->name.append(c); + r.name.append(c); + } + // Set up a default name if one hasn't been set + if(r.name.empty()) { + char cbuf[20]; + itoa10(readCnt_, cbuf); + r.name.install(cbuf); + if(r2 != NULL) r2->name.install(cbuf); + } + return (int)r.name.length(); +} + +/** + * Parse a single sequence from fb_ and store in r. Assume + * that the next character obtained via fb_.get() is the first + * character of the sequence and the sequence stops at the next + * char upto (could be tab, newline, etc.). + */ +int TabbedPatternSource::parseSeq( + Read& r, + int& charsRead, + int& trim5, + char upto /*= '\t'*/) +{ + int begin = 0; + int c = fb_.get(); + assert(c != upto); + r.patFw.clear(); + r.color = gColor; + if(gColor) { + // This may be a primer character. If so, keep it in the + // 'primer' field of the read buf and parse the rest of the + // read without it. + c = toupper(c); + if(asc2dnacat[c] > 0) { + // First char is a DNA char + int c2 = toupper(fb_.peek()); + // Second char is a color char + if(asc2colcat[c2] > 0) { + r.primer = c; + r.trimc = c2; + trim5 += 2; // trim primer and first color + } + } + if(c < 0) { return -1; } + } + while(c != upto) { + if(gColor) { + if(c >= '0' && c <= '4') c = "ACGTN"[(int)c - '0']; + if(c == '.') c = 'N'; + } + if(isalpha(c)) { + assert_in(toupper(c), "ACGTN"); + if(begin++ >= trim5) { + assert_neq(0, asc2dnacat[c]); + r.patFw.append(asc2dna_3N[0][c]); + if (threeN) { + r.patFw_3N.append(asc2dna_3N[1][c]); + r.originalFw.append((asc2dna[c])); + } + } + charsRead++; + } + if((c = fb_.get()) < 0) { + return -1; + } + } + r.patFw.trimEnd(gTrim3); + if (threeN) r.patFw_3N.trimEnd(gTrim3); + return (int)r.patFw.length(); +} + +/** + * Parse a single quality string from fb_ and store in r. + * Assume that the next character obtained via fb_.get() is + * the first character of the quality string and the string stops + * at the next char upto (could be tab, newline, etc.). + */ +int TabbedPatternSource::parseQuals( + Read& r, + int charsRead, + int dstLen, + int trim5, + char& c2, + char upto /*= '\t'*/, + char upto2 /*= -1*/) +{ + int qualsRead = 0; + int c = 0; + if (intQuals_) { + char buf[4096]; + while (qualsRead < charsRead) { + qualToks_.clear(); + if(!tokenizeQualLine(fb_, buf, 4096, qualToks_)) break; + for (unsigned int j = 0; j < qualToks_.size(); ++j) { + char c = intToPhred33(atoi(qualToks_[j].c_str()), solQuals_); + assert_geq(c, 33); + if (qualsRead >= trim5) { + r.qual.append(c); + } + ++qualsRead; + } + } // done reading integer quality lines + if (charsRead > qualsRead) tooFewQualities(r.name); + } else { + // Non-integer qualities + while((qualsRead < dstLen + trim5) && c >= 0) { + c = fb_.get(); + c2 = c; + if (c == ' ') wrongQualityFormat(r.name); + if(c < 0) { + // EOF occurred in the middle of a read - abort + return -1; + } + if(!isspace(c) && c != upto && (upto2 == -1 || c != upto2)) { + if (qualsRead >= trim5) { + c = charToPhred33(c, solQuals_, phred64Quals_); + assert_geq(c, 33); + r.qual.append(c); + } + qualsRead++; + } else { + break; + } + } + if(qualsRead < dstLen + trim5) { + tooFewQualities(r.name); + } else if(qualsRead > dstLen + trim5) { + tooManyQualities(r.name); + } + } + r.qual.resize(dstLen); + while(c != upto && (upto2 == -1 || c != upto2) && c != -1) { + c = fb_.get(); + c2 = c; + } + return qualsRead; +} + +void wrongQualityFormat(const BTString& read_name) { + cerr << "Error: Encountered one or more spaces while parsing the quality " + << "string for read " << read_name << ". If this is a FASTQ file " + << "with integer (non-ASCII-encoded) qualities, try re-running with " + << "the --integer-quals option." << endl; + throw 1; +} + +void tooFewQualities(const BTString& read_name) { + cerr << "Error: Read " << read_name << " has more read characters than " + << "quality values." << endl; + throw 1; +} + +void tooManyQualities(const BTString& read_name) { + cerr << "Error: Read " << read_name << " has more quality values than read " + << "characters." << endl; + throw 1; +} + +#ifdef USE_SRA + +struct SRA_Read { + SStringExpandable name; // read name + SDnaStringExpandable<128, 2> patFw; // forward-strand sequence + SStringExpandable qual; // quality values + + void reset() { + name.clear(); + patFw.clear(); + qual.clear(); + } +}; + +static const uint64_t buffer_size_per_thread = 4096; + +struct SRA_Data { + uint64_t read_pos; + uint64_t write_pos; + uint64_t buffer_size; + bool done; + EList > paired_reads; + + ngs::ReadIterator* sra_it; + + SRA_Data() { + read_pos = 0; + write_pos = 0; + buffer_size = buffer_size_per_thread; + done = false; + sra_it = NULL; + } + + bool isFull() { + assert_leq(read_pos, write_pos); + assert_geq(read_pos + buffer_size, write_pos); + return read_pos + buffer_size <= write_pos; + } + + bool isEmpty() { + assert_leq(read_pos, write_pos); + assert_geq(read_pos + buffer_size, write_pos); + return read_pos == write_pos; + } + + pair& getPairForRead() { + assert(!isEmpty()); + return paired_reads[read_pos % buffer_size]; + } + + pair& getPairForWrite() { + assert(!isFull()); + return paired_reads[write_pos % buffer_size]; + } + + void advanceReadPos() { + assert(!isEmpty()); + read_pos++; + } + + void advanceWritePos() { + assert(!isFull()); + write_pos++; + } +}; + +static void SRA_IO_Worker(void *vp) +{ + SRA_Data* sra_data = (SRA_Data*)vp; + assert(sra_data != NULL); + ngs::ReadIterator* sra_it = sra_data->sra_it; + assert(sra_it != NULL); + + while(!sra_data->done) { + while(sra_data->isFull()) { +#if defined(_TTHREAD_WIN32_) + Sleep(1); +#elif defined(_TTHREAD_POSIX_) + const static timespec ts = {0, 1000000}; // 1 millisecond + nanosleep(&ts, NULL); +#endif + } + pair& pair = sra_data->getPairForWrite(); + SRA_Read& ra = pair.first; + SRA_Read& rb = pair.second; + bool exception_thrown = false; + try { + if(!sra_it->nextRead() || !sra_it->nextFragment()) { + ra.reset(); + rb.reset(); + sra_data->done = true; + return; + } + + // Read the name out of the first field + ngs::StringRef rname = sra_it->getReadId(); + ra.name.install(rname.data(), rname.size()); + assert(!ra.name.empty()); + + ngs::StringRef ra_seq = sra_it->getFragmentBases(); + if(gTrim5 + gTrim3 < (int)ra_seq.size()) { + ra.patFw.installChars(ra_seq.data() + gTrim5, ra_seq.size() - gTrim5 - gTrim3); + } + ngs::StringRef ra_qual = sra_it->getFragmentQualities(); + if(ra_seq.size() == ra_qual.size() && gTrim5 + gTrim3 < (int)ra_qual.size()) { + ra.qual.install(ra_qual.data() + gTrim5, ra_qual.size() - gTrim5 - gTrim3); + } else { + ra.qual.resize(ra.patFw.length()); + ra.qual.fill('I'); + } + assert_eq(ra.patFw.length(), ra.qual.length()); + + if(!sra_it->nextFragment()) { + rb.reset(); + } else { + // rb.name = ra.name; + ngs::StringRef rb_seq = sra_it->getFragmentBases(); + if(gTrim5 + gTrim3 < (int)rb_seq.size()) { + rb.patFw.installChars(rb_seq.data() + gTrim5, rb_seq.size() - gTrim5 - gTrim3); + } + ngs::StringRef rb_qual = sra_it->getFragmentQualities(); + if(rb_seq.size() == rb_qual.size() && gTrim5 + gTrim3 < (int)rb_qual.size()) { + rb.qual.install(rb_qual.data() + gTrim5, rb_qual.size() - gTrim5 - gTrim3); + } else { + rb.qual.resize(rb.patFw.length()); + rb.qual.fill('I'); + } + assert_eq(rb.patFw.length(), rb.qual.length()); + } + sra_data->advanceWritePos(); + } catch(ngs::ErrorMsg & x) { + cerr << x.toString () << endl; + exception_thrown = true; + } catch(exception & x) { + cerr << x.what () << endl; + exception_thrown = true; + } catch(...) { + cerr << "unknown exception\n"; + exception_thrown = true; + } + + if(exception_thrown) { + ra.reset(); + rb.reset(); + sra_data->done = true; + cerr << "An error happened while fetching SRA reads. Please rerun HISAT2. You may want to disable the SRA cache if you didn't (see the instructions at https://github.com/ncbi/sra-tools/wiki/Toolkit-Configuration).\n"; + exit(1); + } + } +} + +SRAPatternSource::~SRAPatternSource() { + if(io_thread_) delete io_thread_; + if(sra_data_) delete sra_data_; + if(sra_it_) delete sra_it_; + if(sra_run_) delete sra_run_; +} + +/// Read another pair of patterns from a FASTA input file +bool SRAPatternSource::readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) +{ + assert(sra_run_ != NULL && sra_it_ != NULL); + success = true; + done = false; + while(sra_data_->isEmpty()) { + if(sra_data_->done && sra_data_->isEmpty()) { + ra.reset(); + rb.reset(); + success = false; + done = true; + return false; + } + +#if defined(_TTHREAD_WIN32_) + Sleep(1); +#elif defined(_TTHREAD_POSIX_) + const static timespec ts = {0, 1000000}; // 1 millisecond + nanosleep(&ts, NULL); +#endif + } + + pair& pair = sra_data_->getPairForRead(); + ra.name.install(pair.first.name.buf(), pair.first.name.length()); + ra.patFw.install(pair.first.patFw.buf(), pair.first.patFw.length()); + ra.qual.install(pair.first.qual.buf(), pair.first.qual.length()); + ra.trimmed3 = gTrim3; + ra.trimmed5 = gTrim5; + if(pair.second.patFw.length() > 0) { + rb.name.install(pair.first.name.buf(), pair.first.name.length()); + rb.patFw.install(pair.second.patFw.buf(), pair.second.patFw.length()); + rb.qual.install(pair.second.qual.buf(), pair.second.qual.length()); + rb.trimmed3 = gTrim3; + rb.trimmed5 = gTrim5; + paired = true; + } else { + rb.reset(); + } + sra_data_->advanceReadPos(); + + rdid = endid = readCnt_; + readCnt_++; + + return true; +} + +void SRAPatternSource::open() { + string version = "hisat2-"; + version += HISAT2_VERSION; + ncbi::NGS::setAppVersionString(version.c_str()); + assert(!sra_accs_.empty()); + while(sra_acc_cur_ < sra_accs_.size()) { + // Open read + if(sra_it_) { + delete sra_it_; + sra_it_ = NULL; + } + if(sra_run_) { + delete sra_run_; + sra_run_ = NULL; + } + try { + // open requested accession using SRA implementation of the API + sra_run_ = new ngs::ReadCollection(ncbi::NGS::openReadCollection(sra_accs_[sra_acc_cur_])); + +#if 0 + string run_name = sra_run_->getName(); + cerr << " ReadGroups for " << run_name << endl; + + ngs::ReadGroupIterator it = sra_run_->getReadGroups(); + do { + ngs::Statistics s = it.getStatistics(); + cerr << "Statistics for group <" << it.getName() << ">" << endl; + + // for(string p = s.nextPath(""); p != ""; p = s.nextPath(p)){ + // System.out.println("\t"+p+": "+s.getAsString(p)); + } while(it.nextReadGroup()); + exit(1); +#endif + + // compute window to iterate through + size_t MAX_ROW = sra_run_->getReadCount(); + sra_it_ = new ngs::ReadIterator(sra_run_->getReadRange(1, MAX_ROW, ngs::Read::all)); + + // create a buffer for SRA data + sra_data_ = new SRA_Data; + sra_data_->sra_it = sra_it_; + sra_data_->buffer_size = nthreads_ * buffer_size_per_thread; + sra_data_->paired_reads.resize(sra_data_->buffer_size); + + // create a thread for handling SRA data access + io_thread_ = new tthread::thread(SRA_IO_Worker, (void*)sra_data_); + // io_thread_->join(); + } catch(...) { + if(!errs_[sra_acc_cur_]) { + cerr << "Warning: Could not access \"" << sra_accs_[sra_acc_cur_].c_str() << "\" for reading; skipping..." << endl; + errs_[sra_acc_cur_] = true; + } + sra_acc_cur_++; + continue; + } + return; + } + cerr << "Error: No input SRA accessions were valid" << endl; + exit(1); + return; +} + +#endif diff --git a/pat.h b/pat.h new file mode 100644 index 0000000..b257663 --- /dev/null +++ b/pat.h @@ -0,0 +1,1800 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef PAT_H_ +#define PAT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "alphabet.h" +#include "assert_helpers.h" +#include "tokenize.h" +#include "random_source.h" +#include "threading.h" +#include "filebuf.h" +#include "qual.h" +#include "search_globals.h" +#include "sstring.h" +#include "ds.h" +#include "read.h" +#include "util.h" + +extern bool threeN; +/** + * Classes and routines for reading reads from various input sources. + */ + +using namespace std; + +/** + * Calculate a per-read random seed based on a combination of + * the read data (incl. sequence, name, quals) and the global + * seed in '_randSeed'. + */ +static inline uint32_t genRandSeed(const BTDnaString& qry, + const BTString& qual, + const BTString& name, + uint32_t seed) +{ + // Calculate a per-read random seed based on a combination of + // the read data (incl. sequence, name, quals) and the global + // seed + uint32_t rseed = (seed + 101) * 59 * 61 * 67 * 71 * 73 * 79 * 83; + size_t qlen = qry.length(); + // Throw all the characters of the read into the random seed + for(size_t i = 0; i < qlen; i++) { + int p = (int)qry[i]; + assert_leq(p, 4); + size_t off = ((i & 15) << 1); + rseed ^= (p << off); + } + // Throw all the quality values for the read into the random + // seed + for(size_t i = 0; i < qlen; i++) { + int p = (int)qual[i]; + assert_leq(p, 255); + size_t off = ((i & 3) << 3); + rseed ^= (p << off); + } + // Throw all the characters in the read name into the random + // seed + size_t namelen = name.length(); + for(size_t i = 0; i < namelen; i++) { + int p = (int)name[i]; + if(p == '/') break; + assert_leq(p, 255); + size_t off = ((i & 3) << 3); + rseed ^= (p << off); + } + return rseed; +} + +/** + * Parameters affecting how reads and read in. + */ +struct PatternParams { + PatternParams( + int format_, + bool fileParallel_, + uint32_t seed_, + bool useSpinlock_, + bool solexa64_, + bool phred64_, + bool intQuals_, + bool fuzzy_, + int sampleLen_, + int sampleFreq_, + uint32_t skip_) : + format(format_), + fileParallel(fileParallel_), + seed(seed_), + useSpinlock(useSpinlock_), + solexa64(solexa64_), + phred64(phred64_), + intQuals(intQuals_), + fuzzy(fuzzy_), + sampleLen(sampleLen_), + sampleFreq(sampleFreq_), + skip(skip_) { } + + int format; // file format + bool fileParallel; // true -> wrap files with separate PairedPatternSources + uint32_t seed; // pseudo-random seed + bool useSpinlock; // use spin locks instead of pthreads + bool solexa64; // true -> qualities are on solexa64 scale + bool phred64; // true -> qualities are on phred64 scale + bool intQuals; // true -> qualities are space-separated numbers + bool fuzzy; // true -> try to parse fuzzy fastq + int sampleLen; // length of sampled reads for FastaContinuous... + int sampleFreq; // frequency of sampled reads for FastaContinuous... + uint32_t skip; // skip the first 'skip' patterns +}; + +/** + * Encapsulates a synchronized source of patterns; usually a file. + * Optionally reverses reads and quality strings before returning them, + * though that is usually more efficiently done by the concrete + * subclass. Concrete subclasses should delimit critical sections with + * calls to lock() and unlock(). + */ +class PatternSource { + +public: + + PatternSource(const PatternParams& p) : + seed_(p.seed), + readCnt_(0), + numWrappers_(0), + doLocking_(true), + useSpinlock_(p.useSpinlock), + mutex() + { + } + + virtual ~PatternSource() { } + + /** + * Call this whenever this PatternSource is wrapped by a new + * WrappedPatternSourcePerThread. This helps us keep track of + * whether locks will be contended. + */ + void addWrapper() { + lock(); + numWrappers_++; + unlock(); + } + + /** + * The main member function for dispensing patterns. + * + * Returns true iff a pair was parsed succesfully. + */ + virtual bool nextReadPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired, + bool fixName); + + /** + * The main member function for dispensing patterns. + */ + virtual bool nextRead( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done); + + /** + * Implementation to be provided by concrete subclasses. An + * implementation for this member is only relevant for formats that + * can read in a pair of reads in a single transaction with a + * single input source. If paired-end input is given as a pair of + * parallel files, this member should throw an error and exit. + */ + virtual bool nextReadPairImpl( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) = 0; + + /** + * Implementation to be provided by concrete subclasses. An + * implementation for this member is only relevant for formats + * where individual input sources look like single-end-read + * sources, e.g., formats where paired-end reads are specified in + * parallel read files. + */ + virtual bool nextReadImpl( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) = 0; + + /// Reset state to start over again with the first read + virtual void reset() { readCnt_ = 0; } + + /** + * Concrete subclasses call lock() to enter a critical region. + * What constitutes a critical region depends on the subclass. + */ + void lock() { + if(!doLocking_) return; // no contention + mutex.lock(); + } + + /** + * Concrete subclasses call unlock() to exit a critical region + * What constitutes a critical region depends on the subclass. + */ + void unlock() { + if(!doLocking_) return; // no contention + mutex.unlock(); + } + + /** + * Return a new dynamically allocated PatternSource for the given + * format, using the given list of strings as the filenames to read + * from or as the sequences themselves (i.e. if -c was used). + */ + static PatternSource* patsrcFromStrings( + const PatternParams& p, + const EList& qs, + size_t nthreads = 1); + + /** + * Return the number of reads attempted. + */ + TReadId readCnt() const { return readCnt_ - 1; } + + int paired_type; // 1 - left or unpaird, 2-right +// int align_times = 0; + +protected: + + uint32_t seed_; + + /// The number of reads read by this PatternSource + TReadId readCnt_; + + int numWrappers_; /// # threads that own a wrapper for this PatternSource + bool doLocking_; /// override whether to lock (true = don't override) + /// User can ask to use the normal pthreads-style lock even if + /// spinlocks is enabled and compiled in. This is sometimes better + /// if we expect bad I/O latency on some reads. + bool useSpinlock_; + MUTEX_T mutex; +}; + +/** + * Abstract parent class for synhconized sources of paired-end reads + * (and possibly also single-end reads). + */ +class PairedPatternSource { +public: + PairedPatternSource(const PatternParams& p) : mutex_m(), seed_(p.seed) {} + virtual ~PairedPatternSource() { } + + virtual void addWrapper() = 0; + virtual void reset() = 0; + + virtual bool nextReadPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired, + bool fixName) = 0; + + virtual pair readCnt() const = 0; + + /** + * Lock this PairedPatternSource, usually because one of its shared + * fields is being updated. + */ + void lock() { + mutex_m.lock(); + } + + /** + * Unlock this PairedPatternSource. + */ + void unlock() { + mutex_m.unlock(); + } + + /** + * Given the values for all of the various arguments used to specify + * the read and quality input, create a list of pattern sources to + * dispense them. + */ + static PairedPatternSource* setupPatternSources( + const EList& si, // singles, from argv + const EList& m1, // mate1's, from -1 arg + const EList& m2, // mate2's, from -2 arg + const EList& m12, // both mates on each line, from --12 arg +#ifdef USE_SRA + const EList& sra_accs, +#endif + const EList& q, // qualities associated with singles + const EList& q1, // qualities associated with m1 + const EList& q2, // qualities associated with m2 + const PatternParams& p, // read-in params + size_t nthreads, + bool verbose); // be talkative? + +protected: + + MUTEX_T mutex_m; /// mutex for syncing over critical regions + uint32_t seed_; +}; + +/** + * Encapsulates a synchronized source of both paired-end reads and + * unpaired reads, where the paired-end must come from parallel files. + */ +class PairedSoloPatternSource : public PairedPatternSource { + +public: + + PairedSoloPatternSource( + const EList* src, + const PatternParams& p) : + PairedPatternSource(p), + cur_(0), + src_(src) + { + assert(src_ != NULL); + for(size_t i = 0; i < src_->size(); i++) { + assert((*src_)[i] != NULL); + } + } + + virtual ~PairedSoloPatternSource() { delete src_; } + + /** + * Call this whenever this PairedPatternSource is wrapped by a new + * WrappedPatternSourcePerThread. This helps us keep track of + * whether locks within PatternSources will be contended. + */ + virtual void addWrapper() { + for(size_t i = 0; i < src_->size(); i++) { + (*src_)[i]->addWrapper(); + } + } + + /** + * Reset this object and all the PatternSources under it so that + * the next call to nextReadPair gets the very first read pair. + */ + virtual void reset() { + for(size_t i = 0; i < src_->size(); i++) { + (*src_)[i]->reset(); + } + cur_ = 0; + } + + /** + * The main member function for dispensing pairs of reads or + * singleton reads. Returns true iff ra and rb contain a new + * pair; returns false if ra contains a new unpaired read. + */ + virtual bool nextReadPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired, + bool fixName); + + /** + * Return the number of reads attempted. + */ + virtual pair readCnt() const { + uint64_t ret = 0llu; + for(size_t i = 0; i < src_->size(); i++) ret += (*src_)[i]->readCnt(); + return make_pair(ret, 0llu); + } + +protected: + + volatile uint32_t cur_; // current element in parallel srca_, srcb_ vectors + const EList* src_; /// PatternSources for paired-end reads +}; + +/** + * Encapsulates a synchronized source of both paired-end reads and + * unpaired reads, where the paired-end must come from parallel files. + */ +class PairedDualPatternSource : public PairedPatternSource { + +public: + + PairedDualPatternSource( + const EList* srca, + const EList* srcb, + const PatternParams& p) : + PairedPatternSource(p), cur_(0), srca_(srca), srcb_(srcb) + { + assert(srca_ != NULL); + assert(srcb_ != NULL); + // srca_ and srcb_ must be parallel + assert_eq(srca_->size(), srcb_->size()); + for(size_t i = 0; i < srca_->size(); i++) { + // Can't have NULL first-mate sources. Second-mate sources + // can be NULL, in the case when the corresponding first- + // mate source is unpaired. + assert((*srca_)[i] != NULL); + for(size_t j = 0; j < srcb_->size(); j++) { + assert_neq((*srca_)[i], (*srcb_)[j]); + } + } + } + + virtual ~PairedDualPatternSource() { + delete srca_; + delete srcb_; + } + + /** + * Call this whenever this PairedPatternSource is wrapped by a new + * WrappedPatternSourcePerThread. This helps us keep track of + * whether locks within PatternSources will be contended. + */ + virtual void addWrapper() { + for(size_t i = 0; i < srca_->size(); i++) { + (*srca_)[i]->addWrapper(); + if((*srcb_)[i] != NULL) { + (*srcb_)[i]->addWrapper(); + } + } + } + + /** + * Reset this object and all the PatternSources under it so that + * the next call to nextReadPair gets the very first read pair. + */ + virtual void reset() { + for(size_t i = 0; i < srca_->size(); i++) { + (*srca_)[i]->reset(); + if((*srcb_)[i] != NULL) { + (*srcb_)[i]->reset(); + } + } + cur_ = 0; + } + + /** + * The main member function for dispensing pairs of reads or + * singleton reads. Returns true iff ra and rb contain a new + * pair; returns false if ra contains a new unpaired read. + */ + virtual bool nextReadPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired, + bool fixName); + + /** + * Return the number of reads attempted. + */ + virtual pair readCnt() const; + +protected: + + volatile uint32_t cur_; // current element in parallel srca_, srcb_ vectors + const EList* srca_; /// PatternSources for 1st mates and/or unpaired reads + const EList* srcb_; /// PatternSources for 2nd mates +}; + +/** + * Encapsulates a single thread's interaction with the PatternSource. + * Most notably, this class holds the buffers into which the + * PatterSource will write sequences. This class is *not* threadsafe + * - it doesn't need to be since there's one per thread. PatternSource + * is thread-safe. + */ +class PatternSourcePerThread { + +public: + + PatternSourcePerThread() : + buf1_(), buf2_(), rdid_(0xffffffff), endid_(0xffffffff) { } + + virtual ~PatternSourcePerThread() { } + + /** + * change 3N plan for both mate1 and mate2 + */ + void changePlan3N(int mappingCycle) { + buf1_.changePlan3N(mappingCycle); + buf2_.changePlan3N(3-mappingCycle); + } + + /** + * Read the next read pair. + */ + virtual bool nextReadPair( + bool& success, + bool& done, + bool& paired, + bool fixName) + { + return success; + } + + Read& bufa() { return buf1_; } + Read& bufb() { return buf2_; } + const Read& bufa() const { return buf1_; } + const Read& bufb() const { return buf2_; } + + TReadId rdid() const { return rdid_; } + TReadId endid() const { return endid_; } + virtual void reset() { rdid_ = endid_ = 0xffffffff; } + + /** + * Return the length of mate 1 or mate 2. + */ + size_t length(int mate) const { + return (mate == 1) ? buf1_.length() : buf2_.length(); + } + +protected: + + Read buf1_; // read buffer for mate a + Read buf2_; // read buffer for mate b + TReadId rdid_; // index of read just read + TReadId endid_; // index of read just read +}; + +/** + * Abstract parent factory for PatternSourcePerThreads. + */ +class PatternSourcePerThreadFactory { +public: + virtual ~PatternSourcePerThreadFactory() { } + virtual PatternSourcePerThread* create() const = 0; + virtual EList* create(uint32_t n) const = 0; + + /// Free memory associated with a pattern source + virtual void destroy(PatternSourcePerThread* patsrc) const { + assert(patsrc != NULL); + // Free the PatternSourcePerThread + delete patsrc; + } + + /// Free memory associated with a pattern source list + virtual void destroy(EList* patsrcs) const { + assert(patsrcs != NULL); + // Free all of the PatternSourcePerThreads + for(size_t i = 0; i < patsrcs->size(); i++) { + if((*patsrcs)[i] != NULL) { + delete (*patsrcs)[i]; + (*patsrcs)[i] = NULL; + } + } + // Free the vector + delete patsrcs; + } +}; + +/** + * A per-thread wrapper for a PairedPatternSource. + */ +class WrappedPatternSourcePerThread : public PatternSourcePerThread { +public: + WrappedPatternSourcePerThread(PairedPatternSource& __patsrc) : + patsrc_(__patsrc) + { + patsrc_.addWrapper(); + } + + /** + * Get the next paired or unpaired read from the wrapped + * PairedPatternSource. + */ + virtual bool nextReadPair( + bool& success, + bool& done, + bool& paired, + bool fixName); + +private: + + /// Container for obtaining paired reads from PatternSources + PairedPatternSource& patsrc_; +}; + +/** + * Abstract parent factory for PatternSourcePerThreads. + */ +class WrappedPatternSourcePerThreadFactory : public PatternSourcePerThreadFactory { +public: + WrappedPatternSourcePerThreadFactory(PairedPatternSource& patsrc) : + patsrc_(patsrc) { } + + /** + * Create a new heap-allocated WrappedPatternSourcePerThreads. + */ + virtual PatternSourcePerThread* create() const { + return new WrappedPatternSourcePerThread(patsrc_); + } + + /** + * Create a new heap-allocated vector of heap-allocated + * WrappedPatternSourcePerThreads. + */ + virtual EList* create(uint32_t n) const { + EList* v = new EList; + for(size_t i = 0; i < n; i++) { + v->push_back(new WrappedPatternSourcePerThread(patsrc_)); + assert(v->back() != NULL); + } + return v; + } + +private: + /// Container for obtaining paired reads from PatternSources + PairedPatternSource& patsrc_; +}; + +/// Skip to the end of the current string of newline chars and return +/// the first character after the newline chars, or -1 for EOF +static inline int getOverNewline(FileBuf& in) { + int c; + while(isspace(c = in.get())); + return c; +} + +/// Skip to the end of the current string of newline chars such that +/// the next call to get() returns the first character after the +/// whitespace +static inline int peekOverNewline(FileBuf& in) { + while(true) { + int c = in.peek(); + if(c != '\r' && c != '\n') { + return c; + } + in.get(); + } +} + +/// Skip to the end of the current line; return the first character +/// of the next line or -1 for EOF +static inline int getToEndOfLine(FileBuf& in) { + while(true) { + int c = in.get(); if(c < 0) return -1; + if(c == '\n' || c == '\r') { + while(c == '\n' || c == '\r') { + c = in.get(); if(c < 0) return -1; + } + // c now holds first character of next line + return c; + } + } +} + +/// Skip to the end of the current line such that the next call to +/// get() returns the first character on the next line +static inline int peekToEndOfLine(FileBuf& in) { + while(true) { + int c = in.get(); if(c < 0) return c; + if(c == '\n' || c == '\r') { + c = in.peek(); + while(c == '\n' || c == '\r') { + in.get(); if(c < 0) return c; // consume \r or \n + c = in.peek(); + } + // next get() gets first character of next line + return c; + } + } +} + +extern void wrongQualityFormat(const BTString& read_name); +extern void tooFewQualities(const BTString& read_name); +extern void tooManyQualities(const BTString& read_name); + +/** + * Encapsulates a source of patterns which is an in-memory vector. + */ +class VectorPatternSource : public PatternSource { + +public: + + VectorPatternSource( + const EList& v, + const PatternParams& p); + + virtual ~VectorPatternSource() { } + + virtual bool nextReadImpl( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done); + + /** + * This is unused, but implementation is given for completeness. + */ + virtual bool nextReadPairImpl( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired); + + virtual void reset() { + PatternSource::reset(); + cur_ = skip_; + paired_ = false; + } + +private: + + size_t cur_; + uint32_t skip_; + bool paired_; + EList v_; // forward sequences + EList quals_; // forward qualities + EList names_; // names + EList trimmed3_; // names + EList trimmed5_; // names +}; + +/** + * + */ +class BufferedFilePatternSource : public PatternSource { +public: + BufferedFilePatternSource( + const EList& infiles, + const PatternParams& p) : + PatternSource(p), + infiles_(infiles), + filecur_(0), + fb_(), + skip_(p.skip), + first_(true) + { + assert_gt(infiles.size(), 0); + errs_.resize(infiles_.size()); + errs_.fill(0, infiles_.size(), false); + assert(!fb_.isOpen()); + open(); // open first file in the list + filecur_++; + } + + virtual ~BufferedFilePatternSource() { + if(fb_.isOpen()) fb_.close(); + } + + /** + * Fill Read with the sequence, quality and name for the next + * read in the list of read files. This function gets called by + * all the search threads, so we must handle synchronization. + */ + virtual bool nextReadImpl( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) + { + // We'll be manipulating our file handle/filecur_ state + lock(); + while(true) { + do { read(r, rdid, endid, success, done); } + while(!success && !done); + if(!success && filecur_ < infiles_.size()) { + assert(done); + open(); + resetForNextFile(); // reset state to handle a fresh file + filecur_++; + continue; + } + break; + } + assert(r.repOk()); + // Leaving critical region + unlock(); + return success; + } + + /** + * + */ + virtual bool nextReadPairImpl( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) + { + // We'll be manipulating our file handle/filecur_ state + lock(); + while(true) { + do { readPair(ra, rb, rdid, endid, success, done, paired); } + while(!success && !done); + if(!success && filecur_ < infiles_.size()) { + assert(done); + open(); + resetForNextFile(); // reset state to handle a fresh file + filecur_++; + continue; + } + break; + } + assert(ra.repOk()); + assert(rb.repOk()); + // Leaving critical region + unlock(); + return success; + } + + /** + * Reset state so that we read start reading again from the + * beginning of the first file. Should only be called by the + * master thread. + */ + virtual void reset() { + PatternSource::reset(); + filecur_ = 0; + open(); + filecur_++; + } + +protected: + + /// Read another pattern from the input file; this is overridden + /// to deal with specific file formats + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) = 0; + + /// Read another pattern pair from the input file; this is + /// overridden to deal with specific file formats + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) = 0; + + /// Reset state to handle a fresh file + virtual void resetForNextFile() { } + + void open() { + if(fb_.isOpen()) fb_.close(); + while(filecur_ < infiles_.size()) { + // Open read + FILE *in; + if(infiles_[filecur_] == "-") { + in = stdin; + } else if((in = fopen(infiles_[filecur_].c_str(), "rb")) == NULL) { + if(!errs_[filecur_]) { + cerr << "Warning: Could not open read file \"" << infiles_[filecur_].c_str() << "\" for reading; skipping..." << endl; + errs_[filecur_] = true; + } + filecur_++; + continue; + } + fb_.newFile(in); + return; + } + cerr << "Error: No input read files were valid" << endl; + exit(1); + return; + } + + EList infiles_; // filenames for read files + EList errs_; // whether we've already printed an error for each file + size_t filecur_; // index into infiles_ of next file to read + FileBuf fb_; // read file currently being read from + TReadId skip_; // number of reads to skip + bool first_; +}; + +/** + * Parse a single quality string from fb and store qualities in r. + * Assume the next character obtained via fb.get() is the first + * character of the quality string. When returning, the next + * character returned by fb.peek() or fb.get() should be the first + * character of the following line. + */ +int parseQuals( + Read& r, + FileBuf& fb, + int firstc, + int readLen, + int trim3, + int trim5, + bool intQuals, + bool phred64, + bool solexa64); + +/** + * Synchronized concrete pattern source for a list of FASTA or CSFASTA + * (if color = true) files. + */ +class FastaPatternSource : public BufferedFilePatternSource { +public: + FastaPatternSource(const EList& infiles, + const PatternParams& p) : + BufferedFilePatternSource(infiles, p), + first_(true), solexa64_(p.solexa64), phred64_(p.phred64), intQuals_(p.intQuals) + { } + virtual void reset() { + first_ = true; + BufferedFilePatternSource::reset(); + } +protected: + /** + * Scan to the next FASTA record (starting with >) and return the first + * character of the record (which will always be >). + */ + static int skipToNextFastaRecord(FileBuf& in) { + int c; + while((c = in.get()) != '>') { + if(in.eof()) return -1; + } + return c; + } + + /// Called when we have to bail without having parsed a read. + void bail(Read& r) { + r.reset(); + fb_.resetLastN(); + } + + /// Read another pattern from a FASTA input file + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done); + + /// Read another pair of patterns from a FASTA input file + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) + { + // (For now, we shouldn't ever be here) + cerr << "In FastaPatternSource.readPair()" << endl; + throw 1; + return false; + } + + virtual void resetForNextFile() { + first_ = true; + } + +private: + bool first_; + +public: + bool solexa64_; + bool phred64_; + bool intQuals_; +}; + + +/** + * Tokenize a line of space-separated integer quality values. + */ +static inline bool tokenizeQualLine( + FileBuf& filebuf, + char *buf, + size_t buflen, + EList& toks) +{ + size_t rd = filebuf.gets(buf, buflen); + if(rd == 0) return false; + assert(NULL == strrchr(buf, '\n')); + tokenize(string(buf), " ", toks); + return true; +} + +/** + * Synchronized concrete pattern source for a list of files with tab- + * delimited name, seq, qual fields (or, for paired-end reads, + * basename, seq1, qual1, seq2, qual2). + */ +class TabbedPatternSource : public BufferedFilePatternSource { + +public: + + TabbedPatternSource( + const EList& infiles, + const PatternParams& p, + bool secondName) : + BufferedFilePatternSource(infiles, p), + solQuals_(p.solexa64), + phred64Quals_(p.phred64), + intQuals_(p.intQuals), + secondName_(secondName) { } + +protected: + + /// Read another pattern from a FASTA input file + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done); + + /// Read another pair of patterns from a FASTA input file + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired); + +private: + + /** + * Parse a name from fb_ and store in r. Assume that the next + * character obtained via fb_.get() is the first character of + * the sequence and the string stops at the next char upto (could + * be tab, newline, etc.). + */ + int parseName(Read& r, Read* r2, char upto = '\t'); + + /** + * Parse a single sequence from fb_ and store in r. Assume + * that the next character obtained via fb_.get() is the first + * character of the sequence and the sequence stops at the next + * char upto (could be tab, newline, etc.). + */ + int parseSeq(Read& r, int& charsRead, int& trim5, char upto = '\t'); + + /** + * Parse a single quality string from fb_ and store in r. + * Assume that the next character obtained via fb_.get() is + * the first character of the quality string and the string stops + * at the next char upto (could be tab, newline, etc.). + */ + int parseQuals(Read& r, int charsRead, int dstLen, int trim5, + char& c2, char upto = '\t', char upto2 = -1); + + bool solQuals_; + bool phred64Quals_; + bool intQuals_; + EList qualToks_; + bool secondName_; +}; + +/** + * Synchronized concrete pattern source for Illumina Qseq files. In + * Qseq files, each read appears on a separate line and the tab- + * delimited fields are: + * + * 1. Machine name + * 2. Run number + * 3. Lane number + * 4. Tile number + * 5. X coordinate of spot + * 6. Y coordinate of spot + * 7. Index: "Index sequence or 0. For no indexing, or for a file that + * has not been demultiplexed yet, this field should have a value of + * 0." + * 8. Read number: 1 for unpaired, 1 or 2 for paired + * 9. Sequence + * 10. Quality + * 11. Filter: 1 = passed, 0 = didn't + */ +class QseqPatternSource : public BufferedFilePatternSource { + +public: + + QseqPatternSource( + const EList& infiles, + const PatternParams& p) : + BufferedFilePatternSource(infiles, p), + solQuals_(p.solexa64), + phred64Quals_(p.phred64), + intQuals_(p.intQuals) { } + +protected: + +#define BAIL_UNPAIRED() { \ + peekOverNewline(fb_); \ + r.reset(); \ + success = false; \ + done = true; \ + return success; \ +} + + /** + * Parse a name from fb_ and store in r. Assume that the next + * character obtained via fb_.get() is the first character of + * the sequence and the string stops at the next char upto (could + * be tab, newline, etc.). + */ + int parseName( + Read& r, // buffer for mate 1 + Read* r2, // buffer for mate 2 (NULL if mate2 is read separately) + bool append, // true -> append characters, false -> skip them + bool clearFirst, // clear the name buffer first + bool warnEmpty, // emit a warning if nothing was added to the name + bool useDefault, // if nothing is read, put readCnt_ as a default value + int upto); // stop parsing when we first reach character 'upto' + + /** + * Parse a single sequence from fb_ and store in r. Assume + * that the next character obtained via fb_.get() is the first + * character of the sequence and the sequence stops at the next + * char upto (could be tab, newline, etc.). + */ + int parseSeq( + Read& r, // buffer for read + int& charsRead, + int& trim5, + char upto); + + /** + * Parse a single quality string from fb_ and store in r. + * Assume that the next character obtained via fb_.get() is + * the first character of the quality string and the string stops + * at the next char upto (could be tab, newline, etc.). + */ + int parseQuals( + Read& r, // buffer for read + int charsRead, + int dstLen, + int trim5, + char& c2, + char upto, + char upto2); + + /** + * Read another pattern from a Qseq input file. + */ + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done); + + /** + * Read a pair of patterns from 1 Qseq file. Note: this is never used. + */ + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) + { + // (For now, we shouldn't ever be here) + cerr << "In QseqPatternSource.readPair()" << endl; + throw 1; + return false; + } + + bool solQuals_; + bool phred64Quals_; + bool intQuals_; + EList qualToks_; +}; + +/** + * Synchronized concrete pattern source for a list of FASTA files where + * reads need to be extracted from long continuous sequences. + */ +class FastaContinuousPatternSource : public BufferedFilePatternSource { +public: + FastaContinuousPatternSource(const EList& infiles, const PatternParams& p) : + BufferedFilePatternSource(infiles, p), + length_(p.sampleLen), freq_(p.sampleFreq), + eat_(length_-1), beginning_(true), + bufCur_(0), subReadCnt_(0llu) + { + resetForNextFile(); + } + + virtual void reset() { + BufferedFilePatternSource::reset(); + resetForNextFile(); + } + +protected: + + /// Read another pattern from a FASTA input file + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) + { + success = true; + done = false; + r.reset(); + while(true) { + r.color = gColor; + int c = fb_.get(); + if(c < 0) { success = false; done = true; return success; } + if(c == '>') { + resetForNextFile(); + c = fb_.peek(); + bool sawSpace = false; + while(c != '\n' && c != '\r') { + if(!sawSpace) { + sawSpace = isspace(c); + } + if(!sawSpace) { + nameBuf_.append(c); + } + fb_.get(); + c = fb_.peek(); + } + while(c == '\n' || c == '\r') { + fb_.get(); + c = fb_.peek(); + } + nameBuf_.append('_'); + } else { + int cat = asc2dnacat[c]; + if(cat >= 2) c = 'N'; + if(cat == 0) { + // Encountered non-DNA, non-IUPAC char; skip it + continue; + } else { + // DNA char + buf_[bufCur_++] = c; + if(bufCur_ == 1024) bufCur_ = 0; + if(eat_ > 0) { + eat_--; + // Try to keep readCnt_ aligned with the offset + // into the reference; that lets us see where + // the sampling gaps are by looking at the read + // name + if(!beginning_) readCnt_++; + continue; + } + for(size_t i = 0; i < length_; i++) { + if(length_ - i <= bufCur_) { + c = buf_[bufCur_ - (length_ - i)]; + } else { + // Rotate + c = buf_[bufCur_ - (length_ - i) + 1024]; + } + r.patFw.append(asc2dna[c]); + r.qual.append('I'); + } + // Set up a default name if one hasn't been set + r.name = nameBuf_; + char cbuf[20]; + itoa10(readCnt_ - subReadCnt_, cbuf); + r.name.append(cbuf); + eat_ = freq_-1; + readCnt_++; + beginning_ = false; + rdid = endid = readCnt_-1; + break; + } + } + } + return true; + } + + /// Shouldn't ever be here; it's not sensible to obtain read pairs + // from a continuous input. + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) + { + cerr << "In FastaContinuousPatternSource.readPair()" << endl; + throw 1; + return false; + } + + /** + * Reset state to be read for the next file. + */ + virtual void resetForNextFile() { + eat_ = length_-1; + beginning_ = true; + bufCur_ = 0; + nameBuf_.clear(); + subReadCnt_ = readCnt_; + } + +private: + size_t length_; /// length of reads to generate + size_t freq_; /// frequency to sample reads + size_t eat_; /// number of characters we need to skip before + /// we have flushed all of the ambiguous or + /// non-existent characters out of our read + /// window + bool beginning_; /// skipping over the first read length? + char buf_[1024]; /// read buffer + BTString nameBuf_; /// read buffer for name of fasta record being + /// split into mers + size_t bufCur_; /// buffer cursor; points to where we should + /// insert the next character + uint64_t subReadCnt_;/// number to subtract from readCnt_ to get + /// the pat id to output (so it resets to 0 for + /// each new sequence) +}; + +/** + * Read a FASTQ-format file. + * See: http://maq.sourceforge.net/fastq.shtml + */ +class FastqPatternSource : public BufferedFilePatternSource { + +public: + + FastqPatternSource(const EList& infiles, const PatternParams& p) : + BufferedFilePatternSource(infiles, p), + first_(true), + solQuals_(p.solexa64), + phred64Quals_(p.phred64), + intQuals_(p.intQuals), + fuzzy_(p.fuzzy) + { } + + virtual void reset() { + first_ = true; + fb_.resetLastN(); + BufferedFilePatternSource::reset(); + } + +protected: + + /** + * Scan to the next FASTQ record (starting with @) and return the first + * character of the record (which will always be @). Since the quality + * line may start with @, we keep scanning until we've seen a line + * beginning with @ where the line two lines back began with +. + */ + static int skipToNextFastqRecord(FileBuf& in, bool sawPlus) { + int line = 0; + int plusLine = -1; + int c = in.get(); + int firstc = c; + while(true) { + if(line > 20) { + // If we couldn't find our desired '@' in the first 20 + // lines, it's time to give up + if(firstc == '>') { + // That firstc is '>' may be a hint that this is + // actually a FASTA file, so return it intact + return '>'; + } + // Return an error + return -1; + } + if(c == -1) return -1; + if(c == '\n') { + c = in.get(); + if(c == '@' && sawPlus && plusLine == (line-2)) { + return '@'; + } + else if(c == '+') { + // Saw a '+' at the beginning of a line; remember where + // we saw it + sawPlus = true; + plusLine = line; + } + else if(c == -1) { + return -1; + } + line++; + } + c = in.get(); + } + } + + /// Read another pattern from a FASTQ input file + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done); + + /// Read another read pair from a FASTQ input file + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) + { + // (For now, we shouldn't ever be here) + cerr << "In FastqPatternSource.readPair()" << endl; + throw 1; + return false; + } + + virtual void resetForNextFile() { + first_ = true; + } + +private: + + /** + * Do things we need to do if we have to bail in the middle of a + * read, usually because we reached the end of the input without + * finishing. + */ + void bail(Read& r) { + r.patFw.clear(); + fb_.resetLastN(); + } + + bool first_; + bool solQuals_; + bool phred64Quals_; + bool intQuals_; + bool fuzzy_; + EList qualToks_; +}; + +/** + * Read a Raw-format file (one sequence per line). No quality strings + * allowed. All qualities are assumed to be 'I' (40 on the Phred-33 + * scale). + */ +class RawPatternSource : public BufferedFilePatternSource { + +public: + + RawPatternSource(const EList& infiles, const PatternParams& p) : + BufferedFilePatternSource(infiles, p), first_(true) { } + + virtual void reset() { + first_ = true; + BufferedFilePatternSource::reset(); + } + +protected: + + /// Read another pattern from a Raw input file + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) + { + int c; + success = true; + done = false; + r.reset(); + c = getOverNewline(this->fb_); + if(c < 0) { + bail(r); success = false; done = true; return success; + } + assert(!isspace(c)); + r.color = gColor; + int mytrim5 = gTrim5; + if(first_) { + // Check that the first character is sane for a raw file + int cc = c; + if(gColor) { + if(cc >= '0' && cc <= '4') cc = "ACGTN"[(int)cc - '0']; + if(cc == '.') cc = 'N'; + } + if(asc2dnacat[cc] == 0) { + cerr << "Error: reads file does not look like a Raw file" << endl; + if(c == '>') { + cerr << "Reads file looks like a FASTA file; please use -f" << endl; + } + if(c == '@') { + cerr << "Reads file looks like a FASTQ file; please use -q" << endl; + } + throw 1; + } + first_ = false; + } + if(gColor) { + // This may be a primer character. If so, keep it in the + // 'primer' field of the read buf and parse the rest of the + // read without it. + c = toupper(c); + if(asc2dnacat[c] > 0) { + // First char is a DNA char + int c2 = toupper(fb_.peek()); + // Second char is a color char + if(asc2colcat[c2] > 0) { + r.primer = c; + r.trimc = c2; + mytrim5 += 2; // trim primer and first color + } + } + if(c < 0) { + bail(r); success = false; done = true; return success; + } + } + // _in now points just past the first character of a sequence + // line, and c holds the first character + int chs = 0; + while(!isspace(c) && c >= 0) { + if(gColor) { + if(c >= '0' && c <= '4') c = "ACGTN"[(int)c - '0']; + if(c == '.') c = 'N'; + } + // 5' trimming + if(isalpha(c) && chs >= mytrim5) { + //size_t len = chs - mytrim5; + //if(len >= 1024) tooManyQualities(BTString("(no name)")); + r.patFw.append(asc2dna[c]); + r.qual.append('I'); + } + chs++; + if(isspace(fb_.peek())) break; + c = fb_.get(); + } + // 3' trimming + r.patFw.trimEnd(gTrim3); + r.qual.trimEnd(gTrim3); + c = peekToEndOfLine(fb_); + r.trimmed3 = gTrim3; + r.trimmed5 = mytrim5; + r.readOrigBuf.install(fb_.lastN(), fb_.lastNLen()); + fb_.resetLastN(); + + // Set up name + char cbuf[20]; + itoa10(readCnt_, cbuf); + r.name.install(cbuf); + readCnt_++; + + rdid = endid = readCnt_-1; + return success; + } + + /// Read another read pair from a FASTQ input file + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) + { + // (For now, we shouldn't ever be here) + cerr << "In RawPatternSource.readPair()" << endl; + throw 1; + return false; + } + + virtual void resetForNextFile() { + first_ = true; + } + +private: + + /** + * Do things we need to do if we have to bail in the middle of a + * read, usually because we reached the end of the input without + * finishing. + */ + void bail(Read& r) { + r.patFw.clear(); + fb_.resetLastN(); + } + + bool first_; +}; + +#ifdef USE_SRA + +namespace ngs { + class ReadCollection; + class ReadIterator; +} + +namespace tthread { + class thread; +}; + +struct SRA_Data; + +/** + * + */ +class SRAPatternSource : public PatternSource { +public: + SRAPatternSource( + const EList& sra_accs, + const PatternParams& p, + const size_t nthreads = 1) : + PatternSource(p), + sra_accs_(sra_accs), + sra_acc_cur_(0), + skip_(p.skip), + first_(true), + nthreads_(nthreads), + sra_run_(NULL), + sra_it_(NULL), + sra_data_(NULL), + io_thread_(NULL) + { + assert_gt(sra_accs_.size(), 0); + errs_.resize(sra_accs_.size()); + errs_.fill(0, sra_accs_.size(), false); + open(); // open first file in the list + sra_acc_cur_++; + } + + virtual ~SRAPatternSource(); + + /** + * Fill Read with the sequence, quality and name for the next + * read in the list of read files. This function gets called by + * all the search threads, so we must handle synchronization. + */ + virtual bool nextReadImpl( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) + { + // We'll be manipulating our file handle/filecur_ state + lock(); + while(true) { + do { read(r, rdid, endid, success, done); } + while(!success && !done); + if(!success && sra_acc_cur_ < sra_accs_.size()) { + assert(done); + open(); + resetForNextFile(); // reset state to handle a fresh file + sra_acc_cur_++; + continue; + } + break; + } + assert(r.repOk()); + // Leaving critical region + unlock(); + return success; + } + + /** + * + */ + virtual bool nextReadPairImpl( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired) + { + // We'll be manipulating our file handle/filecur_ state + lock(); + while(true) { + do { readPair(ra, rb, rdid, endid, success, done, paired); } + while(!success && !done); + if(!success && sra_acc_cur_ < sra_accs_.size()) { + assert(done); + open(); + resetForNextFile(); // reset state to handle a fresh file + sra_acc_cur_++; + continue; + } + break; + } + assert(ra.repOk()); + assert(rb.repOk()); + // Leaving critical region + unlock(); + return success; + } + + /** + * Reset state so that we read start reading again from the + * beginning of the first file. Should only be called by the + * master thread. + */ + virtual void reset() { + PatternSource::reset(); + sra_acc_cur_ = 0, + open(); + sra_acc_cur_++; + } + + /// Read another pattern from the input file; this is overridden + /// to deal with specific file formats + virtual bool read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) + { + return true; + } + + /// Read another pattern pair from the input file; this is + /// overridden to deal with specific file formats + virtual bool readPair( + Read& ra, + Read& rb, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done, + bool& paired); + +protected: + + /// Reset state to handle a fresh file + virtual void resetForNextFile() { } + + void open(); + + EList sra_accs_; // filenames for read files + EList errs_; // whether we've already printed an error for each file + size_t sra_acc_cur_; // index into infiles_ of next file to read + TReadId skip_; // number of reads to skip + bool first_; + + size_t nthreads_; + + ngs::ReadCollection* sra_run_; + ngs::ReadIterator* sra_it_; + + SRA_Data* sra_data_; + tthread::thread* io_thread_; +}; + +#endif + +#endif /*PAT_H_*/ diff --git a/pe.cpp b/pe.cpp new file mode 100644 index 0000000..8845898 --- /dev/null +++ b/pe.cpp @@ -0,0 +1,941 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "assert_helpers.h" +#include "pe.h" + +using namespace std; + +/** + * Return a PE_TYPE flag indicating, given a PE_POLICY and coordinates + * for a paired-end alignment, what type of alignment it is, i.e., + * whether it's: + * + * 1. Straightforwardly concordant + * 2. Mates dovetail (one extends beyond the end of the other) + * 3. One mate contains the other but they don't dovetail + * 4. One mate overlaps the other but neither contains the other and + * they don't dovetail + * 5. Discordant + */ +int PairedEndPolicy::peClassifyPair( + int64_t off1, // offset of mate 1 + size_t len1, // length of mate 1 + bool fw1, // whether mate 1 aligned to Watson + int64_t off2, // offset of mate 2 + size_t len2, // length of mate 2 + bool fw2) // whether mate 2 aligned to Watson + const +{ + assert_gt(len1, 0); + assert_gt(len2, 0); + // Expand the maximum fragment length if necessary to accomodate + // the longer mate + size_t maxfrag = maxfrag_; + if(len1 > maxfrag && expandToFit_) maxfrag = len1; + if(len2 > maxfrag && expandToFit_) maxfrag = len2; + size_t minfrag = minfrag_; + if(minfrag < 1) { + minfrag = 1; + } + bool oneLeft = false; + if(pol_ == PE_POLICY_FF) { + if(fw1 != fw2) { + // Bad combination of orientations + return PE_ALS_DISCORD; + } + oneLeft = fw1; + } else if(pol_ == PE_POLICY_RR) { + if(fw1 != fw2) { + // Bad combination of orientations + return PE_ALS_DISCORD; + } + oneLeft = !fw1; + } else if(pol_ == PE_POLICY_FR) { + if(fw1 == fw2) { + // Bad combination of orientations + return PE_ALS_DISCORD; + } + oneLeft = fw1; + } else if(pol_ == PE_POLICY_RF) { + if(fw1 == fw2) { + // Bad combination of orientations + return PE_ALS_DISCORD; + } + oneLeft = !fw1; + } + // Calc implied fragment size + int64_t fraglo = min(off1, off2); + int64_t fraghi = max(off1+len1, off2+len2); + assert_gt(fraghi, fraglo); + size_t frag = (size_t)(fraghi - fraglo); + if(frag > maxfrag || frag < minfrag) { + // Pair is discordant by virtue of the extents + return PE_ALS_DISCORD; + } + int64_t lo1 = off1; + int64_t hi1 = off1 + len1 - 1; + int64_t lo2 = off2; + int64_t hi2 = off2 + len2 - 1; + bool containment = false; + // Check whether one mate entirely contains the other + if((lo1 >= lo2 && hi1 <= hi2) || + (lo2 >= lo1 && hi2 <= hi1)) + { + containment = true; + } + int type = PE_ALS_NORMAL; + // Check whether one mate overlaps the other + bool olap = false; + if((lo1 <= lo2 && hi1 >= lo2) || + (lo1 <= hi2 && hi1 >= hi2) || + containment) + { + // The mates overlap + olap = true; + if(!olapOk_) return PE_ALS_DISCORD; + type = PE_ALS_OVERLAP; + } + // Check if the mates are in the wrong relative orientation, + // without any overlap + if(!olap) { + if((oneLeft && lo2 < lo1) || (!oneLeft && lo1 < lo2)) { + return PE_ALS_DISCORD; + } + } + // If one mate contained the other, report that + if(containment) { + if(!containOk_) return PE_ALS_DISCORD; + type = PE_ALS_CONTAIN; + } + // Check whether there's dovetailing; i.e. does the left mate + // extend past the right end of the right mate, or vice versa + if(( oneLeft && (hi1 > hi2 || lo2 < lo1)) || + (!oneLeft && (hi2 > hi1 || lo1 < lo2))) + { + if(!dovetailOk_) return PE_ALS_DISCORD; + type = PE_ALS_DOVETAIL; + } + return type; +} + +/** + * Given details about how one mate aligns, and some details about the + * reference sequence it aligned to, calculate a window and orientation s.t. + * a paired-end alignment is concordant iff the opposite mate aligns in the + * calculated window with the calculated orientation. The "window" is really a + * cosntraint on which positions the extreme end of the opposite mate can fall. + * This is a different type of constraint from the one placed on seed-extend + * dynamic programming problems. That constraints requires that alignments at + * one point pass through one of a set of "core" columns. + * + * When the opposite mate is to the left, we're constraining where its + * left-hand extreme can fall, i.e., which cells in the top row of the matrix + * it can end in. When the opposite mate is to the right, we're cosntraining + * where its right-hand extreme can fall, i.e., which cells in the bottom row + * of the matrix it can end in. However, in practice we can only constrain + * where we start the backtrace, i.e. where the RHS of the alignment falls. + * See frameFindMateRect for details. + * + * This calculaton does not consider gaps - the dynamic programming framer will + * take gaps into account. + * + * Returns false if no concordant alignments are possible, true otherwise. + */ +bool PairedEndPolicy::otherMate( + bool is1, // true -> mate 1 aligned and we're looking + // for 2, false -> vice versa + bool fw, // orientation of aligned mate + int64_t off, // offset into the reference sequence + int64_t maxalcols, // max # columns spanned by alignment + size_t reflen, // length of reference sequence aligned to + size_t len1, // length of mate 1 + size_t len2, // length of mate 2 + bool& oleft, // out: true iff opp mate must be to right of anchor + int64_t& oll, // out: leftmost Watson off for LHS of opp alignment + int64_t& olr, // out: rightmost Watson off for LHS of opp alignment + int64_t& orl, // out: leftmost Watson off for RHS of opp alignment + int64_t& orr, // out: rightmost Watson off for RHS of opp alignment + bool& ofw) // out: true iff opp mate must be on Watson strand + const +{ + assert_gt(len1, 0); + assert_gt(len2, 0); + assert_gt(maxfrag_, 0); + assert_geq(minfrag_, 0); + assert_geq(maxfrag_, minfrag_); + assert(maxalcols == -1 || maxalcols > 0); + + // Calculate whether opposite mate should align to left or to right + // of given mate, and what strand it should align to + pePolicyMateDir(pol_, is1, fw, oleft, ofw); + + size_t alen = is1 ? len1 : len2; // length of opposite mate + + // Expand the maximum fragment length if necessary to accomodate + // the longer mate + size_t maxfrag = maxfrag_; + size_t minfrag = minfrag_; + if(minfrag < 1) { + minfrag = 1; + } + if(len1 > maxfrag && expandToFit_) maxfrag = len1; + if(len2 > maxfrag && expandToFit_) maxfrag = len2; + if(!expandToFit_ && (len1 > maxfrag || len2 > maxfrag)) { + // Not possible to find a concordant alignment; one of the + // mates is too long + return false; + } + + // Now calculate bounds within which a dynamic programming + // algorithm should search for an alignment for the opposite mate + if(oleft) { + // -----------FRAG MAX---------------- + // -------FRAG MIN------- + // |-alen-| + // Anchor mate + // ^off + // |------| + // Not concordant: LHS not outside min + // |------| + // Concordant + // |------| + // Concordant + // |------| + // Not concordant: LHS outside max + + // -----------FRAG MAX---------------- + // -------FRAG MIN------- + // |-alen-| + // Anchor mate + // ^off + // |------------| + // LHS can't be outside this range + // -----------FRAG MAX---------------- + // |------------------------------------------------------------| + // LHS can't be outside this range, assuming no restrictions on + // flipping, dovetailing, containment, overlap, etc. + // |-------| + // maxalcols + // |-----------------------------------------| + // LHS can't be outside this range, assuming no flipping + // |---------------------------------| + // LHS can't be outside this range, assuming no dovetailing + // |-------------------------| + // LHS can't be outside this range, assuming no overlap + + oll = off + alen - maxfrag; + olr = off + alen - minfrag; + assert_geq(olr, oll); + + orl = oll; + orr = off + maxfrag - 1; + assert_geq(olr, oll); + + // What if overlapping alignments are not allowed? + if(!olapOk_) { + // RHS can't be flush with or to the right of off + orr = min(orr, off-1); + if(orr < olr) olr = orr; + assert_leq(oll, olr); + assert_leq(orl, orr); + assert_geq(orr, olr); + } + // What if dovetail alignments are not allowed? + else if(!dovetailOk_) { + // RHS can't be past off+alen-1 + orr = min(orr, off + alen - 1); + assert_leq(oll, olr); + assert_leq(orl, orr); + } + // What if flipped alignments are not allowed? + else if(!flippingOk_ && maxalcols != -1) { + // RHS can't be right of ??? + orr = min(orr, off + alen - 1 + (maxalcols-1)); + assert_leq(oll, olr); + assert_leq(orl, orr); + } + assert_geq(olr, oll); + assert_geq(orr, orl); + assert_geq(orr, olr); + assert_geq(orl, oll); + } else { + // -----------FRAG MAX---------------- + // -------FRAG MIN------- + // -----------FRAG MAX---------------- + // |-alen-| + // Anchor mate + // ^off + // |------| + // Not concordant: RHS not outside min + // |------| + // Concordant + // |------| + // Concordant + // |------| + // Not concordant: RHS outside max + // + + // -----------FRAG MAX---------------- + // -------FRAG MIN------- + // -----------FRAG MAX---------------- + // |-alen-| + // Anchor mate + // ^off + // |------------| + // RHS can't be outside this range + // |------------------------------------------------------------| + // LHS can't be outside this range, assuming no restrictions on + // dovetailing, containment, overlap, etc. + // |-------| + // maxalcols + // |-----------------------------------------| + // LHS can't be outside this range, assuming no flipping + // |---------------------------------| + // LHS can't be outside this range, assuming no dovetailing + // |-------------------------| + // LHS can't be outside this range, assuming no overlap + + orr = off + (maxfrag - 1); + orl = off + (minfrag - 1); + assert_geq(orr, orl); + + oll = off + alen - maxfrag; + olr = orr; + assert_geq(olr, oll); + + // What if overlapping alignments are not allowed? + if(!olapOk_) { + // LHS can't be left of off+alen + oll = max(oll, off+alen); + if(oll > orl) orl = oll; + assert_leq(oll, olr); + assert_leq(orl, orr); + assert_geq(orl, oll); + } + // What if dovetail alignments are not allowed? + else if(!dovetailOk_) { + // LHS can't be left of off + oll = max(oll, off); + assert_leq(oll, olr); + assert_leq(orl, orr); + } + // What if flipped alignments are not allowed? + else if(!flippingOk_ && maxalcols != -1) { + // LHS can't be left of off - maxalcols + 1 + oll = max(oll, off - maxalcols + 1); + assert_leq(oll, olr); + assert_leq(orl, orr); + } + assert_geq(olr, oll); + assert_geq(orr, orl); + assert_geq(orr, olr); + assert_geq(orl, oll); + } + + // Boundaries and orientation determined + return true; +} + +#ifdef MAIN_PE + +#include +#include + +void testCaseClassify( + const string& name, + int pol, + size_t maxfrag, + size_t minfrag, + bool local, + bool flip, + bool dove, + bool cont, + bool olap, + bool expand, + int64_t off1, + size_t len1, + bool fw1, + int64_t off2, + size_t len2, + bool fw2, + int expect_class) +{ + PairedEndPolicy pepol( + pol, + maxfrag, + minfrag, + local, + flip, + dove, + cont, + olap, + expand); + int ret = pepol.peClassifyPair( + off1, // offset of mate 1 + len1, // length of mate 1 + fw1, // whether mate 1 aligned to Watson + off2, // offset of mate 2 + len2, // length of mate 2 + fw2); // whether mate 2 aligned to Watson + assert_eq(expect_class, ret); + cout << "peClassifyPair: " << name << "...PASSED" << endl; +} + +void testCaseOtherMate( + const string& name, + int pol, + size_t maxfrag, + size_t minfrag, + bool local, + bool flip, + bool dove, + bool cont, + bool olap, + bool expand, + bool is1, + bool fw, + int64_t off, + int64_t maxalcols, + size_t reflen, + size_t len1, + size_t len2, + bool expect_ret, + bool expect_oleft, + int64_t expect_oll, + int64_t expect_olr, + int64_t expect_orl, + int64_t expect_orr, + bool expect_ofw) +{ + PairedEndPolicy pepol( + pol, + maxfrag, + minfrag, + local, + flip, + dove, + cont, + olap, + expand); + int64_t oll = 0, olr = 0; + int64_t orl = 0, orr = 0; + bool oleft = false, ofw = false; + bool ret = pepol.otherMate( + is1, + fw, + off, + maxalcols, + reflen, + len1, + len2, + oleft, + oll, + olr, + orl, + orr, + ofw); + assert(ret == expect_ret); + if(ret) { + assert_eq(expect_oleft, oleft); + assert_eq(expect_oll, oll); + assert_eq(expect_olr, olr); + assert_eq(expect_orl, orl); + assert_eq(expect_orr, orr); + assert_eq(expect_ofw, ofw); + } + cout << "otherMate: " << name << "...PASSED" << endl; +} + +int main(int argc, char **argv) { + + // Set of 8 cases where we look for the opposite mate to the right + // of the anchor mate, with various combinations of policies and + // anchor-mate orientations. + + // |--------| + // |--------| + // ^110 ^119 + // |------------------| + // min frag + // |--------| + // ^120 ^129 + // |----------------------------| + // max frag + // ^ + // 100 + + { + int policies[] = { PE_POLICY_FF, PE_POLICY_RR, PE_POLICY_FR, PE_POLICY_RF, PE_POLICY_FF, PE_POLICY_RR, PE_POLICY_FR, PE_POLICY_RF }; + bool is1[] = { true, true, true, true, false, false, false, false }; + bool fw[] = { true, false, true, false, false, true, true, false }; + bool oleft[] = { false, false, false, false, false, false, false, false }; + bool ofw[] = { true, false, false, true, false, true, false, true }; + + for(int i = 0; i < 8; i++) { + ostringstream oss; + oss << "Simple"; + oss << i; + testCaseOtherMate( + oss.str(), + policies[i], // policy + 30, // maxfrag + 20, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + is1[i], // mate 1 is anchor + fw[i], // anchor aligned to Watson + 100, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + oleft[i], // wheter to look for opposite to left + 80, // expected leftmost pos for opp mate LHS + 129, // expected rightmost pos for opp mate LHS + 119, // expected leftmost pos for opp mate RHS + 129, // expected rightmost pos for opp mate RHS + ofw[i]); // expected orientation in which opposite mate must align + } + } + + // Set of 8 cases where we look for the opposite mate to the left + // of the anchor mate, with various combinations of policies and + // anchor-mate orientations. + + // |--------| + // ^100 ^109 + // |--------| + // ^110 ^119 + // |------------------| + // min frag + // |-Anchor-| + // ^120 ^129 + // |----------------------------| + // max frag + // ^ + // 100 + + { + int policies[] = { PE_POLICY_FF, PE_POLICY_RR, PE_POLICY_FR, PE_POLICY_RF, PE_POLICY_FF, PE_POLICY_RR, PE_POLICY_FR, PE_POLICY_RF }; + bool is1[] = { false, false, false, false, true, true, true, true }; + bool fw[] = { true, false, false, true, false, true, false, true }; + bool oleft[] = { true, true, true, true, true, true, true, true }; + bool ofw[] = { true, false, true, false, false, true, true, false }; + + for(int i = 0; i < 8; i++) { + ostringstream oss; + oss << "Simple"; + oss << (i+8); + testCaseOtherMate( + oss.str(), + policies[i], // policy + 30, // maxfrag + 20, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + is1[i], // mate 1 is anchor + fw[i], // anchor aligned to Watson + 120, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + oleft[i], // wheter to look for opposite to left + 100, // expected leftmost pos for opp mate LHS + 110, // expected rightmost pos for opp mate LHS + 100, // expected leftmost pos for opp mate RHS + 149, // expected rightmost pos for opp mate RHS + ofw[i]); // expected orientation in which opposite mate must align + } + } + + // Case where min frag == max frag and opposite is to the right + + // |----------------------------| + // min frag + // |--------| + // ^120 ^129 + // |----------------------------| + // max frag + // ^ + // 100 + testCaseOtherMate( + "MinFragEqMax1", + PE_POLICY_FR, // policy + 30, // maxfrag + 30, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + false, // mate 1 is anchor + false, // anchor aligned to Watson + 120, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + true, // wheter to look for opposite to left + 100, // expected leftmost pos for opp mate LHS + 100, // expected rightmost pos for opp mate LHS + 100, // expected leftmost pos for opp mate RHS + 149, // expected rightmost pos for opp mate RHS + true); // expected orientation in which opposite mate must align + + // Case where min frag == max frag and opposite is to the right + + // |----------------------------| + // min frag ^129 + // |--------| + // ^100 ^109 + // |----------------------------| + // max frag + testCaseOtherMate( + "MinFragEqMax2", + PE_POLICY_FR, // policy + 30, // maxfrag + 30, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + true, // mate 1 is anchor + true, // anchor aligned to Watson + 100, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + false, // wheter to look for opposite to left + 80, // expected leftmost pos for opp mate LHS + 129, // expected rightmost pos for opp mate LHS + 129, // expected leftmost pos for opp mate RHS + 129, // expected rightmost pos for opp mate RHS + false); // expected orientation in which opposite mate must align + + testCaseOtherMate( + "MinFragEqMax4NoDove1", + PE_POLICY_FR, // policy + 30, // maxfrag + 25, // minfrag + false, // local + true, // flipping OK + false, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + true, // mate 1 is anchor + true, // anchor aligned to Watson + 100, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + false, // wheter to look for opposite to left + 100, // expected leftmost pos for opp mate LHS + 129, // expected rightmost pos for opp mate LHS + 124, // expected leftmost pos for opp mate RHS + 129, // expected rightmost pos for opp mate RHS + false); // expected orientation in which opposite mate must align + + testCaseOtherMate( + "MinFragEqMax4NoCont1", + PE_POLICY_FR, // policy + 30, // maxfrag + 25, // minfrag + false, // local + true, // flipping OK + false, // dovetail OK + false, // containment OK + true, // overlap OK + true, // expand-to-fit + true, // mate 1 is anchor + true, // anchor aligned to Watson + 100, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + false, // wheter to look for opposite to left + 100, // expected leftmost pos for opp mate LHS + 129, // expected rightmost pos for opp mate LHS + 124, // expected leftmost pos for opp mate RHS + 129, // expected rightmost pos for opp mate RHS + false); // expected orientation in which opposite mate must align + + testCaseOtherMate( + "MinFragEqMax4NoOlap1", + PE_POLICY_FR, // policy + 30, // maxfrag + 25, // minfrag + false, // local + true, // flipping OK + false, // dovetail OK + false, // containment OK + false, // overlap OK + true, // expand-to-fit + true, // mate 1 is anchor + true, // anchor aligned to Watson + 100, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + false, // wheter to look for opposite to left + 110, // expected leftmost pos for opp mate LHS + 129, // expected rightmost pos for opp mate LHS + 124, // expected leftmost pos for opp mate RHS + 129, // expected rightmost pos for opp mate RHS + false); // expected orientation in which opposite mate must align + + testCaseOtherMate( + "MinFragEqMax4NoDove2", + PE_POLICY_FR, // policy + 30, // maxfrag + 25, // minfrag + false, // local + true, // flipping OK + false, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + false, // mate 1 is anchor + false, // anchor aligned to Watson + 120, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + true, // whether to look for opposite to left + 100, // expected leftmost pos for opp mate LHS + 105, // expected rightmost pos for opp mate LHS + 100, // expected leftmost pos for opp mate RHS + 129, // expected rightmost pos for opp mate RHS + true); // expected orientation in which opposite mate must align + + testCaseOtherMate( + "MinFragEqMax4NoOlap2", + PE_POLICY_FR, // policy + 30, // maxfrag + 25, // minfrag + false, // local + true, // flipping OK + false, // dovetail OK + false, // containment OK + false, // overlap OK + true, // expand-to-fit + false, // mate 1 is anchor + false, // anchor aligned to Watson + 120, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + true, // whether to look for opposite to left + 100, // expected leftmost pos for opp mate LHS + 105, // expected rightmost pos for opp mate LHS + 100, // expected leftmost pos for opp mate RHS + 119, // expected rightmost pos for opp mate RHS + true); // expected orientation in which opposite mate must align + + { + int olls[] = { 110 }; + int olrs[] = { 299 }; + int orls[] = { 149 }; + int orrs[] = { 299 }; + for(int i = 0; i < 1; i++) { + ostringstream oss; + oss << "Overhang1_"; + oss << (i+1); + testCaseOtherMate( + oss.str(), + PE_POLICY_FR, // policy + 200, // maxfrag + 50, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + false, // overlap OK + true, // expand-to-fit + true, // mate 1 is anchor + true, // anchor aligned to Watson + 100, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + false, // whether to look for opposite to left + olls[i], // expected leftmost pos for opp mate LHS + olrs[i], // expected rightmost pos for opp mate LHS + orls[i], // expected leftmost pos for opp mate RHS + orrs[i], // expected rightmost pos for opp mate RHS + false); // expected orientation in which opposite mate must align + } + } + + { + int olls[] = { -100 }; + int olrs[] = { 50 }; + int orls[] = { -100 }; + int orrs[] = { 89 }; + for(int i = 0; i < 1; i++) { + ostringstream oss; + oss << "Overhang2_"; + oss << (i+1); + testCaseOtherMate( + oss.str(), + PE_POLICY_FR, // policy + 200, // maxfrag + 50, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + false, // overlap OK + true, // expand-to-fit + true, // mate 1 is anchor + false, // anchor aligned to Watson + 90, // anchor's offset into ref + -1, // max # alignment cols + 200, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + true, // whether to look for opposite to left + olls[i], // expected leftmost pos for opp mate LHS + olrs[i], // expected rightmost pos for opp mate LHS + orls[i], // expected leftmost pos for opp mate RHS + orrs[i], // expected rightmost pos for opp mate RHS + true); // expected orientation in which opposite mate must align + } + } + + { + int mate2offs[] = { 150, 149, 149, 100, 99, 299, 1, 250, 250 }; + int mate2lens[] = { 50, 50, 51, 100, 101, 1, 50, 50, 51 }; + int peExpects[] = { PE_ALS_NORMAL, PE_ALS_DISCORD, PE_ALS_OVERLAP, PE_ALS_CONTAIN, PE_ALS_DOVETAIL, PE_ALS_NORMAL, PE_ALS_DISCORD, PE_ALS_NORMAL, PE_ALS_DISCORD }; + + for(int i = 0; i < 9; i++) { + ostringstream oss; + oss << "Simple1_"; + oss << (i); + testCaseClassify( + oss.str(), + PE_POLICY_FR, // policy + 200, // maxfrag + 100, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + 100, // offset of mate 1 + 50, // length of mate 1 + true, // whether mate 1 aligned to Watson + mate2offs[i], // offset of mate 2 + mate2lens[i], // length of mate 2 + false, // whether mate 2 aligned to Watson + peExpects[i]);// expectation for PE_ALS flag returned + } + } + + { + int mate1offs[] = { 200, 201, 200, 200, 200, 100, 400, 100, 99 }; + int mate1lens[] = { 50, 49, 51, 100, 101, 1, 50, 50, 51 }; + int peExpects[] = { PE_ALS_NORMAL, PE_ALS_DISCORD, PE_ALS_OVERLAP, PE_ALS_CONTAIN, PE_ALS_DOVETAIL, PE_ALS_NORMAL, PE_ALS_DISCORD, PE_ALS_NORMAL, PE_ALS_DISCORD }; + + for(int i = 0; i < 9; i++) { + ostringstream oss; + oss << "Simple2_"; + oss << (i); + testCaseClassify( + oss.str(), + PE_POLICY_FR, // policy + 200, // maxfrag + 100, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + mate1offs[i], // offset of mate 1 + mate1lens[i], // length of mate 1 + true, // whether mate 1 aligned to Watson + 250, // offset of mate 2 + 50, // length of mate 2 + false, // whether mate 2 aligned to Watson + peExpects[i]);// expectation for PE_ALS flag returned + } + } + + testCaseOtherMate( + "Regression1", + PE_POLICY_FF, // policy + 50, // maxfrag + 0, // minfrag + false, // local + true, // flipping OK + true, // dovetail OK + true, // containment OK + true, // overlap OK + true, // expand-to-fit + true, // mate 1 is anchor + false, // anchor aligned to Watson + 3, // anchor's offset into ref + -1, // max # alignment cols + 53, // ref length + 10, // mate 1 length + 10, // mate 2 length + true, // expected return val from otherMate + true, // whether to look for opposite to left + -37, // expected leftmost pos for opp mate LHS + 13, // expected rightmost pos for opp mate LHS + -37, // expected leftmost pos for opp mate RHS + 52, // expected rightmost pos for opp mate RHS + false); // expected orientation in which opposite mate must align +} + +#endif /*def MAIN_PE*/ diff --git a/pe.h b/pe.h new file mode 100644 index 0000000..8dd46a4 --- /dev/null +++ b/pe.h @@ -0,0 +1,321 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* + * pe.h + * + * A class encapsulating a paired-end policy and routines for + * identifying intervals according to the policy. For instance, + * contains a routine that, given a policy and details about a match + * for one mate, returns details about where to search for the other + * mate. + */ + +#ifndef PE_H_ +#define PE_H_ + +#include +#include + +// In description below "To the left" = "Upstream of w/r/t the Watson strand" + +// The 4 possible policies describing how mates 1 and 2 should be +// oriented with respect to the reference genome and each other +enum { + // (fw) Both mates from Watson with 1 to the left, or + // (rc) Both mates from Crick with 2 to the left + PE_POLICY_FF = 1, + + // (fw) Both mates from Crick with 1 to the left, or + // (rc) Both mates from Watson with 2 to the left + PE_POLICY_RR, + + // (fw) Mate 1 from Watson and mate 2 from Crick with 1 to the left, or + // (rc) Mate 2 from Watson and mate 1 from Crick with 2 to the left + PE_POLICY_FR, + + // (fw) Mate 1 from Crick and mate 2 from Watson with 1 to the left, or + // (rc) Mate 2 from Crick and mate 1 from Watson with 2 to the left + PE_POLICY_RF +}; + +// Various distinct ways that the mates might align with respect to +// each other in a concordant alignment. We distinguish between them +// because in some cases a user may want to consider some of these +// categories to be discordant, even if the alignment otherwise +// conforms to the paired-end policy. + +enum { + // Describes a paired-end alignment where the mates + // straightforwardly conform to the paired-end policy without any + // overlap between the mates + PE_ALS_NORMAL = 1, + + // Describes a paired-end alignment where the mate overlap, but + // neither contains the other and they do not dovetail, but the + // alignment conforms to the paired-end policy + PE_ALS_OVERLAP, + + // Describes a paired-end alignment where the mates conform to the + // paired-end policy, but one mate strictly contains the other but + // they don't dovetail. We distinguish this from a "normal" + // concordant alignment because some users may wish to categorize + // such an alignment as discordant. + PE_ALS_CONTAIN, + + // Describes a paired-end alignment where the mates conform to the + // paired-end policy, but mates "fall off" each other. E.g. if the + // policy is FR and any of these happen: + // 1: >>>>> >>>>> + // 2: <<<<<< <<<<<< + // And the overall extent is consistent with the minimum fragment + // length, this is a dovetail alignment. We distinguish this from + // a "normal" concordant alignment because some users may wish to + // categorize such an alignment as discordant. + PE_ALS_DOVETAIL, + + // The mates are clearly discordant, owing to their orientations + // and/or implied fragment length + PE_ALS_DISCORD +}; + +/** + * Return true iff the orientations and relative positions of mates 1 + * and 2 are compatible with the given PE_POLICY. + */ +static inline bool pePolicyCompat( + int policy, // PE_POLICY + bool oneLeft, // true iff mate 1 is to the left of mate 2 + bool oneWat, // true iff mate 1 aligned to Watson strand + bool twoWat) // true iff mate 2 aligned to Watson strand +{ + switch(policy) { + case PE_POLICY_FF: + return oneWat == twoWat && oneWat == oneLeft; + case PE_POLICY_RR: + return oneWat == twoWat && oneWat != oneLeft; + case PE_POLICY_FR: + return oneWat != twoWat && oneWat == oneLeft; + case PE_POLICY_RF: + return oneWat != twoWat && oneWat != oneLeft; + default: { + std::cerr << "Bad PE_POLICY: " << policy << std::endl; + throw 1; + } + } + throw 1; +} + +/** + * Given that the given mate aligns in the given orientation, return + * true iff the other mate must appear "to the right" of the given mate + * in order for the alignment to be concordant. + */ +static inline void pePolicyMateDir( + int policy,// in: PE_POLICY + bool is1, // in: true iff mate 1 is the one that already aligned + bool fw, // in: true iff already-aligned mate aligned to Watson + bool& left, // out: set =true iff other mate must be to the left + bool& mfw) // out: set =true iff other mate must align to watson +{ + switch(policy) { + case PE_POLICY_FF: { + left = (is1 != fw); + mfw = fw; + break; + } + case PE_POLICY_RR: { + left = (is1 == fw); + mfw = fw; + break; + } + case PE_POLICY_FR: { + left = !fw; + mfw = !fw; + break; + } + case PE_POLICY_RF: { + left = fw; + mfw = !fw; + break; + } + default: { + std::cerr << "Error: No such PE_POLICY: " << policy << std::endl; + throw 1; + } + } + return; +} + +/** + * Encapsulates paired-end alignment parameters. + */ +class PairedEndPolicy { + +public: + + PairedEndPolicy() { reset(); } + + PairedEndPolicy( + int pol, + size_t maxfrag, + size_t minfrag, + bool local, + bool flippingOk, + bool dovetailOk, + bool containOk, + bool olapOk, + bool expandToFit) + { + init( + pol, + maxfrag, + minfrag, + local, + flippingOk, + dovetailOk, + containOk, + olapOk, + expandToFit); + } + + /** + * Initialize with nonsense values. + */ + void reset() { + init(-1, 0xffffffff, 0xffffffff, false, false, false, false, false, false); + } + + /** + * Initialize given policy, maximum & minimum fragment lengths. + */ + void init( + int pol, + size_t maxfrag, + size_t minfrag, + bool local, + bool flippingOk, + bool dovetailOk, + bool containOk, + bool olapOk, + bool expandToFit) + { + pol_ = pol; + maxfrag_ = maxfrag; + minfrag_ = minfrag; + local_ = local; + flippingOk_ = flippingOk; + dovetailOk_ = dovetailOk; + containOk_ = containOk; + olapOk_ = olapOk; + expandToFit_ = expandToFit; + } + +/** + * Given details about how one mate aligns, and some details about the + * reference sequence it aligned to, calculate a window and orientation s.t. + * a paired-end alignment is concordant iff the opposite mate aligns in the + * calculated window with the calculated orientation. The calculaton does not + * consider gaps. The dynamic programming framer will take gaps into account. + * + * Returns false if no concordant alignments are possible, true otherwise. + */ +bool otherMate( + bool is1, // true -> mate 1 aligned and we're looking + // for 2, false -> vice versa + bool fw, // orientation of aligned mate + int64_t off, // offset into the reference sequence + int64_t maxalcols, // max # columns spanned by alignment + size_t reflen, // length of reference sequence aligned to + size_t len1, // length of mate 1 + size_t len2, // length of mate 2 + bool& oleft, // out: true iff opp mate must be to right of anchor + int64_t& oll, // out: leftmost Watson off for LHS of opp alignment + int64_t& olr, // out: rightmost Watson off for LHS of opp alignment + int64_t& orl, // out: leftmost Watson off for RHS of opp alignment + int64_t& orr, // out: rightmost Watson off for RHS of opp alignment + bool& ofw) // out: true iff opp mate must be on Watson strand + const; + + /** + * Return a PE_TYPE flag indicating, given a PE_POLICY and coordinates + * for a paired-end alignment, qwhat type of alignment it is, i.e., + * whether it's: + * + * 1. Straightforwardly concordant + * 2. Mates dovetail (one extends beyond the end of the other) + * 3. One mate contains the other but they don't dovetail + * 4. One mate overlaps the other but neither contains the other and + * they don't dovetail + * 5. Discordant + */ + int peClassifyPair( + int64_t off1, // offset of mate 1 + size_t len1, // length of mate 1 + bool fw1, // whether mate 1 aligned to Watson + int64_t off2, // offset of mate 2 + size_t len2, // length of mate 2 + bool fw2) // whether mate 2 aligned to Watson + const; + + int policy() const { return pol_; } + size_t maxFragLen() const { return maxfrag_; } + size_t minFragLen() const { return minfrag_; } + +protected: + + // Use local alignment to search for the opposite mate, rather than + // a type of alignment that requires the read to align end-to-end + bool local_; + + // Policy governing how mates should be oriented with respect to + // each other and the reference genome + int pol_; + + // true iff settings are such that mates that violate the expected relative + // orientation but are still consistent with maximum fragment length are OK + bool flippingOk_; + + // true iff settings are such that dovetailed mates should be + // considered concordant. + bool dovetailOk_; + + // true iff paired-end alignments where one mate's alignment is + // strictly contained within the other's should be considered + // concordant + bool containOk_; + + // true iff paired-end alignments where one mate's alignment + // overlaps the other's should be considered concordant + bool olapOk_; + + // What to do when a mate length is > maxfrag_? If expandToFit_ is + // true, we temporarily increase maxfrag_ to equal the mate length. + // Otherwise we say that any paired-end alignment involving the + // long mate is discordant. + bool expandToFit_; + + // Maximum fragment size to consider + size_t maxfrag_; + + // Minimum fragment size to consider + size_t minfrag_; +}; + +#endif /*ndef PE_H_*/ diff --git a/position_3n.cpp b/position_3n.cpp new file mode 100644 index 0000000..701d8b3 --- /dev/null +++ b/position_3n.cpp @@ -0,0 +1,393 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#include "alignment_3n.h" +#include "position_3n.h" + + +/** + * compare the MappingPosition to Alignment. + * if they have same chromosome and location information, return true. + */ +bool MappingPosition::operator==(Alignment* o) { + + BTString* testChromosome; + if (!o->repeat && o->pairToRepeat) { + testChromosome = &o->pairToChromosome; + } else { + testChromosome = &o->chromosomeName; + } + + if (locations[1] == NULL) { + return (*locations[o->pairSegment] == o->location) && + (*chromosome == *testChromosome); + } else { + return (*locations[o->pairSegment] == o->location) && + (*locations[1-(o->pairSegment)] == o->pairToLocation) && + (*chromosome == *testChromosome); + } +} + +/** + * constructor for non-repeat alignment, or original repeat alignment ( with chromosomeName = rep*). + */ +MappingPosition::MappingPosition(Alignment* newAlignment) { + initialize(); + locations[newAlignment->pairSegment] = &newAlignment->location; + locations[1-newAlignment->pairSegment] = &newAlignment->pairToLocation; + segmentExist[newAlignment->pairSegment] = true; + alignments[newAlignment->pairSegment] = newAlignment; + if (!newAlignment->repeat && newAlignment->pairToRepeat) { + chromosome = &newAlignment->pairToChromosome; + } else { + chromosome = &newAlignment->chromosomeName; + } + pairScore = numeric_limits::min(); +} + +/** + * constructor for expanded repeat alignment position. + */ +MappingPosition::MappingPosition (RepeatMappingPosition* repeat0, Alignment* newAlignment0, RepeatMappingPosition* repeat1=NULL, Alignment* newAlignment1=NULL) { + initialize(); + locations[newAlignment0->pairSegment] = &repeat0->repeatLocation; + chromosome = &repeat0->repeatChromosome; + repeats[0] = repeat0; + repeats[1] = repeat1; + alignments[0] = newAlignment0; + alignments[1] = newAlignment1; + segmentExist[0] = true; + if (alignments[1] != NULL) { + locations[newAlignment1->pairSegment] = &repeat1->repeatLocation; + segmentExist[1] = true; + } + AS = repeat0->AS; + repeat = true; +} + +/** + * return true if the is a MappingPosition has same information as input Alignment. + * first check the latest MappingPosition, if not same, search all MappingPositions. + * both mate and opposite mate position should be same to MappingPosition to return true. + */ +bool MappingPositions::positionExist (Alignment* newAlignment) { + findBadAlignment = false; + if (positions.empty()) { + index = 0; + return false; + } + + if (positions[index] == newAlignment) { + return positions[index].segmentExist[newAlignment->pairSegment]; + } + + int segment = newAlignment->pairSegment; + long long int* targetLocations[2]; + targetLocations[segment] = &newAlignment->location; + targetLocations[1-segment] = &newAlignment->pairToLocation; + + return findPosition (targetLocations, + (!newAlignment->repeat && newAlignment->pairToRepeat)?newAlignment->pairToChromosome:newAlignment->chromosomeName, + segment); +} + +/** + * append new Alignment to positions. + * return true if the new Alignment successfully append. + * return false if the new Alignment is exist or it's mate is bad aligned. + */ +bool MappingPositions::append(Alignment* newAlignment) { + if (positionExist(newAlignment)) { // check if position is exist. + return false; + } else { + int segment = newAlignment->pairSegment; + if (!positions.empty() && positions[index] == newAlignment && !findBadAlignment) { + // check if current MappingPosition is same to new Alignment. + positions[index].segmentExist[segment] = true; + if (positions[index].badAlignment) { + return false; + } + positions[index].alignments[segment] = newAlignment; + } else { + // add the new Alignment to positions. + positions.emplace_back(newAlignment); + index = positions.size()-1; + if (oppositeAlignment != NULL) { + positions[index].alignments[1-segment] = oppositeAlignment; + positions[index].segmentExist[1-segment] = true; + } + } + return true; + } +} + +/** + * output paired-end alignment results. + */ +void MappingPositions::outputPair(BTString& o) { + int outputCount = 0; + bool primary = true; // for primary alignment flag. + for (int i = 0; i < positions.size(); i++) { + if (positions[i].pairScore == bestPairScore) { + outputCount++; + assert(positions[i].alignments[0] != NULL); + assert(positions[i].alignments[1] != NULL); + + // change the NH tag + positions[i].alignments[0]->updateNH(nBestPair); + positions[i].alignments[1]->updateNH(nBestPair); + + // get concordant information and change the concordant flag. + bool concordant; + if (!positions[i].alignments[0]->mapped || !positions[i].alignments[1]->mapped) { + concordant = false; + } else { + concordant = Alignment::isConcordant(*positions[i].locations[0], + positions[i].alignments[0]->forward, + positions[i].alignments[0]->readSequence.length(), + *positions[i].locations[1], + positions[i].alignments[1]->forward, + positions[i].alignments[1]->readSequence.length()); + } + + positions[i].alignments[0]->setConcordant(concordant); + positions[i].alignments[1]->setConcordant(concordant); + + positions[i].alignments[0]->setMateMappingFlag(positions[i].alignments[1]->mapped ? positions[i].locations[1] : NULL); + positions[i].alignments[1]->setMateMappingFlag(positions[i].alignments[0]->mapped ? positions[i].locations[0] : NULL); + + if (!positions[i].repeat) { + // output regular alignment result + + // if both mate is outputted before, change the mate 1 status and output mate1. + if (positions[i].alignments[0]->outputted && positions[i].alignments[1]->outputted) { + positions[i].alignments[1]->outputted = false; + } + // change YS tag. + positions[i].alignments[0]->setYS(positions[i].alignments[1]); + positions[i].alignments[1]->setYS(positions[i].alignments[0]); + // output + positions[i].alignments[0]->outputAlignment(o, NULL, positions[i].locations[1], primary); + positions[i].alignments[1]->outputAlignment(o, NULL, positions[i].locations[0], primary); + } else { + //output repeat alignment result. + + // if both mate is outputted before, change the mate 1 status and output mate1. + if (positions[i].repeats[0]->outputted && positions[i].repeats[1]->outputted) { + positions[i].repeats[1]->outputted = false; + } + // change YS tag. + positions[i].alignments[0]->setYS(positions[i].repeats[1]); + positions[i].alignments[1]->setYS(positions[i].repeats[0]); + //output + positions[i].alignments[0]->outputAlignment(o, positions[i].repeats[0], positions[i].locations[1], primary); + positions[i].alignments[1]->outputAlignment(o, positions[i].repeats[1], positions[i].locations[0], primary); + } + primary = false; // after output the first pair for each read, set primary status to false; + } + } + assert(outputCount == nBestPair); +} + +/** + * output single-end alignment results. + */ +void MappingPositions::outputSingle(BTString &o) { + int outputCount = 0; + bool primary = true; // for primary alignment flag. + for (int i = 0; i < positions.size(); i++) { + if (positions[i].AS == bestAS && !positions[i].badAlignment) { + outputCount++; + assert(positions[i].alignments[0] != NULL); + // set NH tag + positions[i].alignments[0]->updateNH(nBestSingle); + + if (!positions[i].repeat) { // output regular alignment result + positions[i].alignments[0]->outputAlignment(o, NULL, NULL, primary); + } else { // output repeat alignment result + positions[i].alignments[0]->outputAlignment(o, positions[i].repeats[0], NULL, primary); + } + primary = false; // after output the first alignment for each read, set primary status to false; + } + } + assert(outputCount == nBestSingle); +} + +bool MappingPositions::updateAS_regular() { + if (isBad()) { return false; } + if (!positions[index].alignments[0]->mapped) { return true; } + int AS = positions[index].alignments[0]->AS; + if (AS > bestAS) { + bestAS = AS; + nBestSingle = 1; + } else if (AS == bestAS) { + nBestSingle++; + } else { + badAligned(); + return false; + } + positions[index].AS = AS; + return true; +} + +/** + * if AS in repeatPosition is larger than bestAS, add it to positions and update BestAS. + */ +bool MappingPositions::updateAS_repeat() { + if (isBad()) { return false; } + Alignment* alignment = positions[index].alignments[0]; + RepeatMappingPosition* repeatPosition; + badAligned(); // label this as bad alignment to avoid directly output. + int AS; + for (int i = 0; i < alignment->repeatPositions.size(); i++) { + repeatPosition = &alignment->repeatPositions.positions[i]; + AS = (repeatPosition->flagInfoIndex == -1)?repeatPosition->AS : alignment->repeatPositions.positions[repeatPosition->flagInfoIndex].AS; + if (AS >= bestAS) { + positions.emplace_back(repeatPosition, alignment); + if (AS > bestAS) { + bestAS = AS; + nBestSingle = 1; + } else { + nBestSingle++; + } + } + } + return true; +} + +/** + * redirect to updateAS_regular() or updateAS_repeat(). + */ +bool MappingPositions::updateAS() { + if (positions[index].alignments[0]->repeat) { + return updateAS_repeat(); + } else { + return updateAS_regular(); + } +} + +/** + * calculate the pairing score for regular (non-repeat) alignment. + */ +bool MappingPositions::updatePairScore_regular() { + if (positions[index].alignments[0]->chromosomeName != positions[index].alignments[1]->chromosomeName) { + badAligned(); + return false; + } + int nPair; + int score; + score = positions[index].alignments[0]->calculatePairScore(positions[index].alignments[1], nPair); + if (score > bestPairScore) { + bestPairScore = score; + nBestPair = nPair; + concordantExist = positions[index].alignments[0]->concordant; + } else if (score == bestPairScore) { + nBestPair += nPair; + } else { // the newPair Score is less than bestPairScore, label it + badAligned(); + return false; + } + positions[index].pairScore = score; + return true; +} + +/** + * calculate the pairing score for repeat alignment + * append to positions if the new pair has better (or equal) pairing score. + */ +bool MappingPositions::updatePairScore_repeat() { + Alignment* alignments[2]; + alignments[0] = positions[index].alignments[0]; + alignments[1] = positions[index].alignments[1]; + if ((!alignments[0]->mapped || !alignments[1]->mapped) && + (bestPairScore >= (numeric_limits::min()/2 - 1))) { + badAligned(); + return false; + } + RepeatMappingPosition *repeatPosition0; + RepeatMappingPosition *repeatPosition1; + RepeatMappingPosition *repeatFlag0; + RepeatMappingPosition *repeatFlag1; + bool forward[2]; + forward[0] = alignments[0]->forward; + forward[1] = alignments[1]->forward; + bool DNA = alignments[0]->DNA; + int score; + bool concordant; + for (int i = 0; i < alignments[0]->repeatPositions.size(); i++) { + repeatPosition0 = &alignments[0]->repeatPositions.positions[i]; + repeatFlag0 = repeatPosition0->flagInfoIndex==-1 ? repeatPosition0 : &alignments[0]->repeatPositions.positions[repeatPosition0->flagInfoIndex]; + for (int j = 0; j < alignments[1]->repeatPositions.size(); j++) { + repeatPosition1 = &alignments[1]->repeatPositions.positions[j]; + if (repeatPosition0->repeatChromosome == repeatPosition1->repeatChromosome) { + repeatFlag1 = repeatPosition1->flagInfoIndex==-1 ? repeatPosition1 : &alignments[1]->repeatPositions.positions[repeatPosition1->flagInfoIndex]; + if (DNA) { + score = Alignment::calculatePairScore_DNA(repeatPosition0->repeatLocation, + repeatFlag0->AS, + forward[0], + alignments[0]->readSequence.length(), + repeatPosition1->repeatLocation, + repeatFlag1->AS, + forward[1], + alignments[1]->readSequence.length(), + concordant); + } else { + score = Alignment::calculatePairScore_RNA(repeatPosition0->repeatLocation, + repeatFlag0->XM, + forward[0], + alignments[0]->readSequence.length(), + repeatPosition1->repeatLocation, + repeatFlag1->XM, + forward[1], + alignments[1]->readSequence.length(), + concordant); + } + if (score >= bestPairScore) { + positions.emplace_back(repeatPosition0, alignments[0], repeatPosition1, alignments[1]); + positions.back().pairScore = score; + if (score > bestPairScore) { + nBestPair = 1; + bestPairScore = score; + concordantExist = concordant; + } else { + nBestPair++; + } + } + } + } + } + return true; +} + +/** + * calculate the pairing score, + * if one of mate is repeat, calculate the pairing score by knn and append the pair has best pairing score to positions. + */ +bool MappingPositions::updatePairScore() { + if (!mateExist()) { return true; } + + assert(positions[index].alignments[0] != NULL); + assert(positions[index].alignments[1] != NULL); + + if (positions[index].alignments[0]->repeat || positions[index].alignments[1]->repeat) { + return updatePairScore_repeat(); + } else { + return updatePairScore_regular(); + } +} \ No newline at end of file diff --git a/position_3n.h b/position_3n.h new file mode 100644 index 0000000..d99c227 --- /dev/null +++ b/position_3n.h @@ -0,0 +1,358 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#ifndef HISAT2_POSITION_3N_H +#define HISAT2_POSITION_3N_H + +#include "sstring.h" +#include "alignment_3n.h" + +class Alignment; +class RepeatMappingPosition; + +/** + * the data structure to store existing mapping positions. + */ +class MappingPosition { +public: + long long int* locations[2] = {NULL}; + BTString* chromosome; + int AS = numeric_limits::min(); + int pairScore; // score to decide which mapping position should be output. + bool segmentExist[2] = {false}; // indicate whether we have the segment alignment information. + bool badAlignment = false; // if the alignment result + bool repeat = false; // whether the mapping position is belong to a expanded repeat alignment + Alignment* alignments[2] = {NULL}; + RepeatMappingPosition* repeats[2] = {NULL}; + + void initialize() { + for (int i = 0; i < 2; i++) { + locations[i] = NULL; + segmentExist[i] = false; + alignments[i] = NULL; + repeats[i] = NULL; + } + chromosome = NULL; + AS = numeric_limits::min(); + pairScore = numeric_limits::min(); + badAlignment = false; + repeat = false; + } + + MappingPosition() { + + } + + /** + * constructor for non-repeat alignment, or original repeat alignment( with chromosomeName = rep*). + */ + MappingPosition (Alignment* newAlignment); + + + /** + * constructor for expanded repeat alignment position. + */ + MappingPosition (RepeatMappingPosition* repeat0, Alignment* newAlignment0, RepeatMappingPosition* repeat1, Alignment* newAlignment1); + + /** + * return true if the MappingPosition has same information as input Alignment + */ + bool operator==(Alignment* o); +}; + +/** + * this is the data structure to store all MappingPosition + */ +class MappingPositions { +public: + vector positions; + int bestPairScore; // the best pairing score, for paired-end alignment output + int nBestPair; // the number of pair have bestPairScore, should equal to NH. + int bestAS; // the best AS score, for single-end alignment output. + int nBestSingle; // the number of alignment have bestAS, should equal to NH. + int index; // the index number on positions. should always point to the last or current MappingPosition. + Alignment* oppositeAlignment; // the temporary pointer point to the opposite mate's Alignment. use in append function. + bool concordantExist; // whether concordant alignment is exist. use for paired-end output statistics. + bool findBadAlignment; + + void initialize() { + positions.clear(); + bestPairScore = numeric_limits::min(); + nBestPair = 0; + bestAS = numeric_limits::min(); + nBestSingle = 0; + index = -1; + oppositeAlignment = NULL; + concordantExist = false; + findBadAlignment = false; + } + + MappingPositions() { + initialize(); + }; + + /** + * return number of MappingPosition in positions. + */ + int size() { + return positions.size(); + } + + /** + * recursively search the positions to find whether there is a Mapping position has target information. + * if the opposite mate is exist, we will save it's Alignment address to oppositeAlignment. + */ + bool findPosition (long long int* inputLocations[2], BTString& chromosome, int& pairSegment) { + oppositeAlignment = NULL; + findBadAlignment = false; + for (int i = 0; i < positions.size(); i++) { + if (positions[i].locations[1-pairSegment] == NULL || + *(positions[i].locations[1-pairSegment]) == *inputLocations[1-pairSegment]) { + if (!positions[i].badAlignment) { + oppositeAlignment = positions[i].alignments[1-pairSegment]; + } + if (*positions[i].locations[pairSegment] == *inputLocations[pairSegment] && + (*positions[i].chromosome == chromosome)) { + index = i; + if (positions[i].badAlignment) + { + findBadAlignment = true; + continue; + } + findBadAlignment = false; + return positions[i].segmentExist[pairSegment]; + } + } + } + return false; + } + + /** + * set current MappingPosition to a bad alignment. + */ + void badAligned() { + positions[index].badAlignment = true; + } + + /** + * return true if current positions is a bad alignment. + */ + bool isBad() { + return positions[index].badAlignment; + } + + /** + * return if both segment is exist for current MappingPosition + */ + bool mateExist() { + return positions[index].segmentExist[0] && positions[index].segmentExist[1]; + } + + /** + * calculate the pairing score, + * if one of mate is repeat, calculate the pairing score by knn and append the pair has best pairing score to positions. + */ + bool updatePairScore(); + + /** + * calculate the pairing score for regular (non-repeat) alignment. + */ + bool updatePairScore_regular(); + + /** + * calculate the pairing score for repeat alignment + * append to positions if the new pair has better (or equal) pairing score. + */ + bool updatePairScore_repeat(); + + /** + * redirect to updateAS_regular() or updateAS_repeat(). + */ + bool updateAS(); + + /** + * if AS is larger than bestAS, update bestAS. + */ + bool updateAS_regular(); + + /** + * if AS in repeatPosition is larger than bestAS, add it to positions and update BestAS. + */ + bool updateAS_repeat(); + + /** + * return true if the is a MappingPosition has same information as input Alignment. + * first check the latest MappingPosition, if not same, search all MappingPositions. + * both mate and opposite mate position should be same to MappingPosition to return true. + */ + bool positionExist(Alignment* newAlignment); + + /** + * return true if the is a MappingPosition has same information as position. + * this function is to check repeat mapping position. + * without checking it's mate, if the repeat mapping location is exist, return true. + */ + bool positionExist (BTString& chromosome, long long int& location, int& segment) { + for (int i = 0; i < positions.size(); i++) { + if ((*(positions[i].locations[segment]) == location) && + (*(positions[i].chromosome) == chromosome)) { + return true; + } + } + return false; + } + + /** + * output paired-end alignment results. + */ + void outputPair(BTString& o); + + /** + * output single-end alignment results. + */ + void outputSingle(BTString& o); + + /** + * append new Alignment to positions. + * return true if the new Alignment successfully append. + * return false if the new Alignment is exist or it's mate is bad aligned. + */ + bool append(Alignment* newAlignment); +}; + +/** + * the data structure to store repeat information. + */ +class RepeatMappingPosition: public MappingPosition { +public: + long long int repeatLocation; + BTString MD; + int XM; + int NM; + int YS; + int Yf; + int Zf; + char YZ; + BTString refSequence; + BTString repeatChromosome; + bool outputted = false; + int flagInfoIndex = -1; + + RepeatMappingPosition() {}; + + /** + * constructor for new repeat information. + */ + RepeatMappingPosition (long long int& inputLocation, + BTString& inputChromosome, + BTString &inputRefSequence, + int &inputAS, + BTString &inputMD, + int &inputXM, + int &inputNM, + int &inputYf, + int &inputZf, + char &repeatYZ) { + repeatLocation = inputLocation; + repeatChromosome = inputChromosome; + refSequence = inputRefSequence; + AS = inputAS; + MD = inputMD; + XM = inputXM; + NM = inputNM; + Yf = inputYf; + Zf = inputZf; + YZ = repeatYZ; + pairScore = numeric_limits::min(); + flagInfoIndex = -1; + } + + /** + * constructor for the repeat which has same reference sequence. + * we save the index for pattern RepeatMappingPosition, because they should have same information except location and chromosome. + */ + RepeatMappingPosition(long long int &inputLocation, + BTString &inputChromosome, + int& inputAS, + int& index) { + repeatLocation = inputLocation; + repeatChromosome = inputChromosome; + AS = inputAS; + flagInfoIndex = index; + } +}; + +/** + * this is the data structure to store all repeatMappingPosition after expansion. + */ +class RepeatMappingPositions { +public: + vector positions; + + void initialize() { + positions.clear(); + } + + /** + * return number of MappingPosition in positions. + */ + int size() { + return positions.size(); + } + + /** + * return true if reference sequence is exist, else, return false. + */ + bool sequenceExist (BTString& refSequence, int &index) { + + for (int i = 0; i < positions.size(); i++) { + if ((positions[i].flagInfoIndex == -1) && (refSequence == positions[i].refSequence)) { + index = i; + return true; + } + } + return false; + } + + /** + * add repeat mapping information. + */ + void append (long long int &location, + BTString &chromosome, + BTString &refSequence, + int &AS, + BTString &MD, + int &XM, + int &NM, + int &Yf, + int &Zf, + char &repeatYZ) { + positions.emplace_back(location, chromosome, refSequence, AS, MD, XM, NM, Yf, Zf, repeatYZ); + } + + /** + * add repeat mapping information. + */ + void append(BTString &chromosome, long long int &location, int &index) { + positions.emplace_back(location, chromosome, positions[index].AS, index); + } +}; + +#endif //HISAT2_POSITION_3N_H + diff --git a/position_3n_table.h b/position_3n_table.h new file mode 100644 index 0000000..2a0c99d --- /dev/null +++ b/position_3n_table.h @@ -0,0 +1,549 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#ifndef POSITION_3N_TABLE_H +#define POSITION_3N_TABLE_H + +#include +#include +#include +#include +#include +#include +#include "alignment_3n_table.h" + +using namespace std; + +extern bool CG_only; +extern long long int loadingBlockSize; + +/** + * store unique information for one base information with readID, and the quality. + */ +class uniqueID +{ +public: + unsigned long long readNameID; + bool isConverted; + char quality; + bool removed; + + uniqueID(unsigned long long InReadNameID, + bool InIsConverted, + char& InQual){ + readNameID = InReadNameID; + isConverted = InIsConverted; + quality = InQual; + removed = false; + } +}; + +/** + * basic class to store reference position information + */ +class Position{ + mutex mutex_; +public: + string chromosome; // reference chromosome name + long long int location; // 1-based position + char strand; // +(REF) or -(REF-RC) + string convertedQualities; // each char is a mapping quality on this position for converted base. + string unconvertedQualities; // each char is a mapping quality on this position for unconverted base. + vector uniqueIDs; // each value represent a readName which contributed the base information. + // readNameIDs is to make sure no read contribute 2 times in same position. + + void initialize() { + chromosome.clear(); + location = -1; + strand = '?'; + convertedQualities.clear(); + unconvertedQualities.clear(); + vector().swap(uniqueIDs); + } + + Position(){ + initialize(); + }; + + /** + * return true if there is mapping information in this reference position. + */ + bool empty() { + return convertedQualities.empty() && unconvertedQualities.empty(); + } + + /** + * set the chromosome, location (position), and strand information. + */ + + void set (string& inputChr, long long int inputLoc) { + chromosome = inputChr; + location = inputLoc + 1; + } + + void set(char inputStrand) { + strand = inputStrand; + } + + /** + * binary search of readNameID in readNameIDs. + * always return a index. + * if cannot find, return the index which has bigger value than input readNameID. + */ + int searchReadNameID (unsigned long long&readNameID, int start, int end) { + if (uniqueIDs.empty()) { + return 0; + } + if (start <= end) { + int middle = (start + end) / 2; + if (uniqueIDs[middle].readNameID == readNameID) { + return middle; + } + if (uniqueIDs[middle].readNameID > readNameID) { + return searchReadNameID(readNameID, start, middle-1); + } + return searchReadNameID(readNameID, middle+1, end); + } + return start; // return the bigger one + } + + + /** + * with a input readNameID, add it into readNameIDs. + * if the input readNameID already exist in readNameIDs, return false. + */ + bool appendReadNameID(PosQuality& InBase, Alignment& InAlignment) { + int idCount = uniqueIDs.size(); + if (idCount == 0 || InAlignment.readNameID > uniqueIDs.back().readNameID) { + uniqueIDs.emplace_back(InAlignment.readNameID, InBase.converted, InBase.qual); + return true; + } + int index = searchReadNameID(InAlignment.readNameID, 0, idCount); + if (uniqueIDs[index].readNameID == InAlignment.readNameID) { + // if the new base is consistent with exist base's conversion status, ignore + // otherwise, delete the exist conversion status + if (uniqueIDs[index].removed) { + return false; + } + if (uniqueIDs[index].isConverted != InBase.converted) { + uniqueIDs[index].removed = true; + if (uniqueIDs[index].isConverted) { + for (int i = 0; i < convertedQualities.size(); i++) { + if (convertedQualities[i] == InBase.qual) { + convertedQualities.erase(convertedQualities.begin()+i); + return false; + } + } + } else { + for (int i = 0; i < unconvertedQualities.size(); i++) { + if (unconvertedQualities[i] == InBase.qual) { + unconvertedQualities.erase(unconvertedQualities.begin()+i); + return false; + } + } + } + } + return false; + } else { + uniqueIDs.emplace(uniqueIDs.begin()+index, InAlignment.readNameID, InBase.converted, InBase.qual); + return true; + } + } + + /** + * append the SAM information into this position. + */ + void appendBase (PosQuality& input, Alignment& a) { + mutex_.lock(); + if (appendReadNameID(input,a)) { + if (input.converted) { + convertedQualities += input.qual; + } else { + unconvertedQualities += input.qual; + } + } + mutex_.unlock(); + } +}; + +/** + * store all reference position in this class. + */ +class Positions{ +public: + vector refPositions; // the pool of all current reference position. + string chromosome; // current reference chromosome name. + long long int location; // current location (position) in reference chromosome. + char lastBase = 'X'; // the last base of reference line. this is for CG_only mode. + SafeQueue linePool; // pool to store unprocessed SAM line. + SafeQueue freeLinePool; // pool to store free string pointer for SAM line. + SafeQueue freePositionPool; // pool to store free position pointer for reference position. + SafeQueue outputPositionPool; // pool to store the reference position which is loaded and ready to output. + bool working; + mutex mutex_; + long long int refCoveredPosition; // this is the last position in reference chromosome we loaded in refPositions. + ifstream refFile; + vector workerLock; // one lock for one worker thread. + int nThreads = 1; + ChromosomeFilePositions chromosomePos; // store the chromosome name and it's streamPos. To quickly find new chromosome in file. + bool addedChrName = false; + bool removedChrName = false; + + Positions(string inputRefFileName, int inputNThreads, bool inputAddedChrName, bool inputRemovedChrName) { + working = true; + nThreads = inputNThreads; + addedChrName = inputAddedChrName; + removedChrName = inputRemovedChrName; + for (int i = 0; i < nThreads; i++) { + workerLock.push_back(new mutex); + } + refFile.open(inputRefFileName, ios_base::in); + LoadChromosomeNamesPos(); + } + + ~Positions() { + for (int i = 0; i < workerLock.size(); i++) { + delete workerLock[i]; + } + Position* pos; + while(freePositionPool.popFront(pos)) { + delete pos; + } + } + + /** + * given the target Position output the corresponding position index in refPositions. + */ + int getIndex(long long int &targetPos) { + int firstPos = refPositions[0]->location; + return targetPos - firstPos; + } + + /** + * given reference line (start with '>'), extract the chromosome information. + * this is important when there is space in chromosome name. the SAM information only contain the first word. + */ + string getChrName(string& inputLine) { + string name; + for (int i = 1; i < inputLine.size(); i++) + { + char c = inputLine[i]; + if (isspace(c)){ + break; + } + name += c; + } + + if(removedChrName) { + if(name.find("chr") == 0) { + name = name.substr(3); + } + } else if(addedChrName) { + if(name.find("chr") != 0) { + name = string("chr") + name; + } + } + return name; + } + + + /** + * Scan the reference file. Record each chromosome and its position in file. + */ + void LoadChromosomeNamesPos() { + string line; + while (refFile.good()) { + getline(refFile, line); + if (line.front() == '>') { // this line is chromosome name + chromosome = getChrName(line); + streampos currentPos = refFile.tellg(); + chromosomePos.append(chromosome, currentPos); + } + } + chromosomePos.sort(); + chromosome.clear(); + } + + /** + * get a fasta line (not header), append the bases to positions. + */ + void appendRefPosition(string& line) { + Position* newPos; + // check the base one by one + char* b; + for (int i = 0; i < line.size(); i++) { + getFreePosition(newPos); + newPos->set(chromosome, location+i); + b = &line[i]; + if (CG_only) { + if (lastBase == 'C' && *b == 'G') { + refPositions.back()->set('+'); + newPos->set('-'); + } + } else { + if (*b == convertFrom) { + newPos->set('+'); + } else if (*b == convertFromComplement) { + newPos->set('-'); + } + } + refPositions.push_back(newPos); + lastBase = *b; + } + location += line.size(); + } + + /** + * if we can go through all the workerLock, that means no worker is appending new position. + */ + void appendingFinished() { + for (int i = 0; i < nThreads; i++) { + workerLock[i]->lock(); + workerLock[i]->unlock(); + } + } + + /** + * the output function for output thread. + */ + void outputFunction(string outputFileName) { + ostream* out_ = &cout; + out_ = &cout; + ofstream tableFile; + if (!outputFileName.empty()) { + tableFile.open(outputFileName, ios_base::out); + out_ = &tableFile; + } + + *out_ << "ref\tpos\tstrand\tconvertedBaseQualities\tconvertedBaseCount\tunconvertedBaseQualities\tunconvertedBaseCount\n"; + Position* pos; + while (working) { + if (outputPositionPool.popFront(pos)) { + *out_ << pos->chromosome << '\t' + << to_string(pos->location) << '\t' + << pos->strand << '\t' + << pos->convertedQualities << '\t' + << to_string(pos->convertedQualities.size()) << '\t' + << pos->unconvertedQualities << '\t' + << to_string(pos->unconvertedQualities.size()) << '\n'; + returnPosition(pos); + } else { + this_thread::sleep_for (std::chrono::microseconds(1)); + } + } + tableFile.close(); + } + + /** + * move the position which position smaller than refCoveredPosition - loadingBlockSize, output it. + */ + void moveBlockToOutput() { + if (refPositions.empty()) { + return; + } + int index; + for (index = 0; index < refPositions.size(); index++) { + if (refPositions[index]->location < refCoveredPosition - loadingBlockSize) { + if (refPositions[index]->empty() || refPositions[index]->strand == '?') { + returnPosition(refPositions[index]); + } else { + outputPositionPool.push(refPositions[index]); + } + } else { + break; + } + } + if (index != 0) { + refPositions.erase(refPositions.begin(), refPositions.begin()+index); + } + } + + /** + * move all the refPosition into output pool. + */ + void moveAllToOutput() { + if (refPositions.empty()) { + return; + } + for (int index = 0; index < refPositions.size(); index++) { + if (refPositions[index]->empty() || refPositions[index]->strand == '?') { + returnPosition(refPositions[index]); + } else { + vector().swap(refPositions[index]->uniqueIDs); + outputPositionPool.push(refPositions[index]); + } + } + refPositions.clear(); + } + + /** + * initially load reference sequence for 2 million bp + */ + void loadNewChromosome(string targetChromosome) { + refFile.clear(); + // find the start position in file based on chromosome name. + streampos startPos = chromosomePos.getChromosomePosInRefFile(targetChromosome); + chromosome = targetChromosome; + refFile.seekg(startPos, ios::beg); + refCoveredPosition = 2 * loadingBlockSize; + string line; + lastBase = 'X'; + location = 0; + while (refFile.good()) { + getline(refFile, line); + if (line.front() == '>') { // this line is chromosome name + return; // meet next chromosome, return it. + } else { + if (line.empty()) { continue; } + // change all base to upper case + for (int i = 0; i < line.size(); i++) { + line[i] = toupper(line[i]); + } + appendRefPosition(line); + if (location >= refCoveredPosition) { + return; + } + } + } + } + + /** + * load more Position (loadingBlockSize bp) to positions + * if we meet next chromosome, return false. Else, return ture. + */ + void loadMore() { + refCoveredPosition += loadingBlockSize; + string line; + while (refFile.good()) { + getline(refFile, line); + if (line.front() == '>') { // meet next chromosome, return. + return ; + } else { + if (line.empty()) { continue; } + + // change all base to upper case + for (int i = 0; i < line.size(); i++) { + line[i] = toupper(line[i]); + } + + appendRefPosition(line); + if (location >= refCoveredPosition) { + return ; + } + } + } + } + + + /** + * add position information from Alignment into ref position. + */ + void appendPositions(Alignment& newAlignment) { + if (!newAlignment.mapped || newAlignment.bases.empty()) { + return; + } + long long int startPos = newAlignment.location; // 1-based position + // find the first reference position in pool. + int index = getIndex(newAlignment.location); + + for (int i = 0; i < newAlignment.sequence.size(); i++) { + PosQuality* b = &newAlignment.bases[i]; + if (b->remove) { + continue; + } + + Position* pos = refPositions[index+b->refPos]; + assert (pos->location == startPos + b->refPos); + + if (pos->strand == '?') { + // this is for CG-only mode. read has a 'C' or 'G' but not 'CG'. + continue; + } + pos->appendBase(newAlignment.bases[i], newAlignment); + } + } + + /** + * get a string pointer from freeLinePool, if freeLinePool is empty, make a new string pointer. + */ + void getFreeStringPointer(string*& newLine) { + if (freeLinePool.popFront(newLine)) { + return; + } else { + newLine = new string(); + } + } + + /** + * get a Position pointer from freePositionPool, if freePositionPool is empty, make a new Position pointer. + */ + void getFreePosition(Position*& newPosition) { + while (outputPositionPool.size() >= 10000) { + this_thread::sleep_for (std::chrono::microseconds(1)); + } + if (freePositionPool.popFront(newPosition)) { + return; + } else { + newPosition = new Position(); + } + } + + /** + * return the line to freeLinePool + */ + void returnLine(string* line) { + line->clear(); + freeLinePool.push(line); + } + + /** + * return the position to freePositionPool. + */ + void returnPosition(Position* pos) { + pos->initialize(); + freePositionPool.push(pos); + } + + /** + * this is the working function. + * it take the SAM line from linePool, parse it. + */ + void append(int threadID) { + string* line; + Alignment newAlignment; + + while (working) { + workerLock[threadID]->lock(); + if(!linePool.popFront(line)) { + workerLock[threadID]->unlock(); + this_thread::sleep_for (std::chrono::nanoseconds(1)); + continue; + } + while (refPositions.empty()) { + this_thread::sleep_for (std::chrono::microseconds(1)); + } + newAlignment.parse(line); + returnLine(line); + appendPositions(newAlignment); + workerLock[threadID]->unlock(); + } + } +}; + +#endif //POSITION_3N_TABLE_H diff --git a/presets.cpp b/presets.cpp new file mode 100644 index 0000000..9fef89c --- /dev/null +++ b/presets.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "presets.h" +#include "opts.h" + +using namespace std; + +void PresetsV0::apply( + const std::string& preset, + std::string& policy, + EList >& opts) +{ + // Presets: Same as: + // For --end-to-end: + // --very-fast -M 5 -R 1 -N 0 -L 22 -i S,1,2.50 + // --fast -M 10 -R 2 -N 0 -L 22 -i S,1,2.50 + // --sensitive -M 15 -R 2 -N 0 -L 22 -i S,1,1.15 + // --very-sensitive -M 25 -R 3 -N 0 -L 19 -i S,1,0.50 + if(preset == "very-fast") { + policy += ";SEED=0,22"; + policy += ";DPS=5"; + policy += ";ROUNDS=1"; + policy += ";IVAL=S,0,2.50"; + } else if(preset == "fast") { + policy += ";SEED=0,22"; + policy += ";DPS=10"; + policy += ";ROUNDS=2"; + policy += ";IVAL=S,0,2.50"; + } else if(preset == "sensitive") { + policy += ";SEED=0,22"; + policy += ";DPS=15"; + policy += ";ROUNDS=2"; + policy += ";IVAL=S,1,1.15"; + } else if(preset == "very-sensitive") { + policy += ";SEED=0,20"; + policy += ";DPS=20"; + policy += ";ROUNDS=3"; + policy += ";IVAL=S,1,0.50"; + } + // For --local: + // --very-fast-local -M 1 -N 0 -L 25 -i S,1,2.00 + // --fast-local -M 2 -N 0 -L 22 -i S,1,1.75 + // --sensitive-local -M 2 -N 0 -L 20 -i S,1,0.75 (default) + // --very-sensitive-local -M 3 -N 0 -L 20 -i S,1,0.50 + else if(preset == "very-fast-local") { + policy += ";SEED=0,25"; + policy += ";DPS=5"; + policy += ";ROUNDS=1"; + policy += ";IVAL=S,1,2.00"; + } else if(preset == "fast-local") { + policy += ";SEED=0,22"; + policy += ";DPS=10"; + policy += ";ROUNDS=2"; + policy += ";IVAL=S,1,1.75"; + } else if(preset == "sensitive-local") { + policy += ";SEED=0,20"; + policy += ";DPS=15"; + policy += ";ROUNDS=2"; + policy += ";IVAL=S,1,0.75"; + } else if(preset == "very-sensitive-local") { + policy += ";SEED=0,20"; + policy += ";DPS=20"; + policy += ";ROUNDS=3"; + policy += ";IVAL=S,1,0.50"; + } + else { + cerr << "Unknown preset: " << preset.c_str() << endl; + } +} diff --git a/presets.h b/presets.h new file mode 100644 index 0000000..dfcec41 --- /dev/null +++ b/presets.h @@ -0,0 +1,67 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/** + * presets.h + * + * Maps simple command-line options to more complicated combinations of + * options for ease-of-use. + */ + +#ifndef PRESETS_H_ +#define PRESETS_H_ + +#include +#include +#include "ds.h" + +class Presets { +public: + + Presets() { } + + virtual ~Presets() { } + + virtual void apply( + const std::string& preset, + std::string& policy, + EList >& opts) = 0; + + virtual const char * name() = 0; +}; + +/** + * Initial collection of presets: 8/14/2011 prior to first Bowtie 2 release. + */ +class PresetsV0 : public Presets { +public: + + PresetsV0() : Presets() { } + + virtual ~PresetsV0() { } + + virtual void apply( + const std::string& preset, + std::string& policy, + EList >& opts); + + virtual const char * name() { return "V0"; } +}; + +#endif /*ndef PRESETS_H_*/ diff --git a/processor_support.h b/processor_support.h new file mode 100644 index 0000000..e731e00 --- /dev/null +++ b/processor_support.h @@ -0,0 +1,73 @@ +#ifndef PROCESSOR_SUPPORT_H_ +#define PROCESSOR_SUPPORT_H_ + +// Utility class ProcessorSupport provides POPCNTenabled() to determine +// processor support for POPCNT instruction. It uses CPUID to +// retrieve the processor capabilities. +// for Intel ICC compiler __cpuid() is an intrinsic +// for Microsoft compiler __cpuid() is provided by #include +// for GCC compiler __get_cpuid() is provided by #include + +// Intel compiler defines __GNUC__, so this is needed to disambiguate + +#if defined(__INTEL_COMPILER) +# define USING_INTEL_COMPILER +#elif defined(__GNUC__) +# define USING_GCC_COMPILER +# include +#elif defined(_MSC_VER) +// __MSC_VER defined by Microsoft compiler +#define USING_MSC_COMPILER +#endif + +struct regs_t {unsigned int EAX, EBX, ECX, EDX;}; +#define BIT(n) ((1< + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/// An array that transforms Phred qualities into their maq-like +/// equivalents by dividing by ten and rounding to the nearest 10, +/// but saturating at 3. +unsigned char qualRounds[] = { + 0, 0, 0, 0, 0, // 0 - 4 + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // 5 - 14 + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, // 15 - 24 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 25 - 34 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 35 - 44 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 45 - 54 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 55 - 64 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 65 - 74 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 75 - 84 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 85 - 94 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 95 - 104 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 105 - 114 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 115 - 124 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 125 - 134 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 135 - 144 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 145 - 154 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 155 - 164 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 165 - 174 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 175 - 184 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 185 - 194 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 195 - 204 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 205 - 214 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 215 - 224 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 225 - 234 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 235 - 244 + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // 245 - 254 + 30 // 255 +}; + +/** + * Lookup table for converting from Solexa-scaled (log-odds) quality + * values to Phred-scaled quality values. + */ +unsigned char solToPhred[] = { + /* -10 */ 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, + /* 0 */ 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, + /* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + /* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + /* 30 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + /* 40 */ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + /* 60 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + /* 70 */ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + /* 80 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + /* 90 */ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + /* 100 */ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + /* 120 */ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + /* 130 */ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + /* 140 */ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + /* 150 */ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + /* 160 */ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + /* 170 */ 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + /* 180 */ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + /* 190 */ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + /* 200 */ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + /* 210 */ 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + /* 220 */ 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + /* 230 */ 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + /* 240 */ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + /* 250 */ 250, 251, 252, 253, 254, 255 +}; diff --git a/qual.h b/qual.h new file mode 100644 index 0000000..7c542bb --- /dev/null +++ b/qual.h @@ -0,0 +1,236 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef QUAL_H_ +#define QUAL_H_ + +#include +#include +#include "search_globals.h" +#include "sstring.h" + +extern unsigned char qualRounds[]; +extern unsigned char solToPhred[]; + +/// Translate a Phred-encoded ASCII character into a Phred quality +static inline uint8_t phredcToPhredq(char c) { + return ((uint8_t)c >= 33 ? ((uint8_t)c - 33) : 0); +} + +/** + * Convert a Solexa-scaled quality value into a Phred-scale quality + * value. + * + * p = probability that base is miscalled + * Qphred = -10 * log10 (p) + * Qsolexa = -10 * log10 (p / (1 - p)) + * See: http://en.wikipedia.org/wiki/FASTQ_format + * + */ +static inline uint8_t solexaToPhred(int sol) { + assert_lt(sol, 256); + if(sol < -10) return 0; + return solToPhred[sol+10]; +} + +class SimplePhredPenalty { +public: + static uint8_t mmPenalty (uint8_t qual) { + return qual; + } + static uint8_t delPenalty(uint8_t qual) { + return qual; + } + static uint8_t insPenalty(uint8_t qual_left, uint8_t qual_right) { + return std::max(qual_left, qual_right); + } +}; + +class MaqPhredPenalty { +public: + static uint8_t mmPenalty (uint8_t qual) { + return qualRounds[qual]; + } + static uint8_t delPenalty(uint8_t qual) { + return qualRounds[qual]; + } + static uint8_t insPenalty(uint8_t qual_left, uint8_t qual_right) { + return qualRounds[std::max(qual_left, qual_right)]; + } +}; + +static inline uint8_t mmPenalty(bool maq, uint8_t qual) { + if(maq) { + return MaqPhredPenalty::mmPenalty(qual); + } else { + return SimplePhredPenalty::mmPenalty(qual); + } +} + +static inline uint8_t delPenalty(bool maq, uint8_t qual) { + if(maq) { + return MaqPhredPenalty::delPenalty(qual); + } else { + return SimplePhredPenalty::delPenalty(qual); + } +} + +static inline uint8_t insPenalty(bool maq, uint8_t qual_left, uint8_t qual_right) { + if(maq) { + return MaqPhredPenalty::insPenalty(qual_left, qual_right); + } else { + return SimplePhredPenalty::insPenalty(qual_left, qual_right); + } +} + +/** + * Take an ASCII-encoded quality value and convert it to a Phred33 + * ASCII char. + */ +inline static char charToPhred33(char c, bool solQuals, bool phred64Quals) { + using namespace std; + if(c == ' ') { + std::cerr << "Saw a space but expected an ASCII-encoded quality value." << endl + << "Are quality values formatted as integers? If so, try --integer-quals." << endl; + throw 1; + } + if (solQuals) { + // Convert solexa-scaled chars to phred + // http://maq.sourceforge.net/fastq.shtml + char cc = solexaToPhred((int)c - 64) + 33; + if (cc < 33) { + std::cerr << "Saw ASCII character " + << ((int)c) + << " but expected 64-based Solexa qual (converts to " << (int)cc << ")." << endl + << "Try not specifying --solexa-quals." << endl; + throw 1; + } + c = cc; + } + else if(phred64Quals) { + if (c < 64) { + cerr << "Saw ASCII character " + << ((int)c) + << " but expected 64-based Phred qual." << endl + << "Try not specifying --solexa1.3-quals/--phred64-quals." << endl; + throw 1; + } + // Convert to 33-based phred + c -= (64-33); + } + else { + // Keep the phred quality + if (c < 33) { + cerr << "Saw ASCII character " + << ((int)c) + << " but expected 33-based Phred qual." << endl; + throw 1; + } + } + return c; +} + +/** + * Take an integer quality value and convert it to a Phred33 ASCII + * char. + */ +inline static char intToPhred33(int iQ, bool solQuals) { + using namespace std; + int pQ; + if (solQuals) { + // Convert from solexa quality to phred + // quality and translate to ASCII + // http://maq.sourceforge.net/qual.shtml + pQ = solexaToPhred((int)iQ) + 33; + } else { + // Keep the phred quality and translate + // to ASCII + pQ = (iQ <= 93 ? iQ : 93) + 33; + } + if (pQ < 33) { + cerr << "Saw negative Phred quality " << ((int)pQ-33) << "." << endl; + throw 1; + } + assert_geq(pQ, 0); + return (int)pQ; +} + +inline static uint8_t roundPenalty(uint8_t p) { + if(gNoMaqRound) return p; + return qualRounds[p]; +} + +/** + * Fill the q[] array with the penalties that are determined by + * subtracting the quality values of the alternate basecalls from + * the quality of the primary basecall. + */ +inline static uint8_t penaltiesAt(size_t off, uint8_t *q, + int alts, + const BTString& qual, + const BTDnaString *altQry, + const BTString *altQual) +{ + uint8_t primQ = qual[off]; // qual of primary call + uint8_t bestPenalty = roundPenalty(phredcToPhredq(primQ)); + // By default, any mismatch incurs a penalty equal to the quality + // of the called base + q[0] = q[1] = q[2] = q[3] = bestPenalty; + for(int i = 0; i < alts; i++) { + uint8_t altQ = altQual[i][off]; // qual of alt call + if(altQ == 33) break; // no alt call + assert_leq(altQ, primQ); + uint8_t pen = roundPenalty(primQ - altQ); + if(pen < bestPenalty) { + bestPenalty = pen; + } + // Get the base + int altC = (int)altQry[i][off]; + assert_lt(altC, 4); + q[altC] = pen; + } + // Return the best penalty so that the caller can evaluate whether + // any of the penalties are within-budget + return bestPenalty; +} + +/** + * Fill the q[] array with the penalties that are determined by + * subtracting the quality values of the alternate basecalls from + * the quality of the primary basecall. + */ +inline static uint8_t loPenaltyAt(size_t off, int alts, + const BTString& qual, + const BTString *altQual) +{ + uint8_t primQ = qual[off]; // qual of primary call + uint8_t bestPenalty = roundPenalty(phredcToPhredq(primQ)); + for(int i = 0; i < alts; i++) { + uint8_t altQ = altQual[i][off]; // qual of alt call + if(altQ == 33) break; // no more alt calls at this position + assert_leq(altQ, primQ); + uint8_t pen = roundPenalty(primQ - altQ); + if(pen < bestPenalty) { + bestPenalty = pen; + } + } + return bestPenalty; +} + +#endif /*QUAL_H_*/ diff --git a/radix_sort.h b/radix_sort.h new file mode 100644 index 0000000..1b1e1e8 --- /dev/null +++ b/radix_sort.h @@ -0,0 +1,297 @@ +#ifndef RADIX_SORT_H_ +#define RADIX_SORT_H_ + +#include + +// in place radix sort using a single thread, should not be called directly +// used for leaves of both in and out of place radix sorts +template +static void _radix_sort(T* begin, T* end, index_t (*hash)(T&), int log_size) { + const int SHIFT = 8; + const int BLOCKS = (1 << (SHIFT + 1)); + const int BLOCKS_MASK = BLOCKS - 1; + + // compute maximum of log_size - 7 and 0 + int right_shift = (log_size - SHIFT) * (log_size > SHIFT); + // count number in each bin + index_t count[BLOCKS] = {0}; + for(T* curr = begin; curr != end; curr++) { + count[(hash(*curr) >> right_shift) & BLOCKS_MASK]++; + } + // sum numbers to create an index + T* index[BLOCKS + 1]; + T* place[BLOCKS]; + index[0] = place[0] = begin; + for(int i = 1; i < BLOCKS; i++) { + index[i] = place[i] = index[i - 1] + count[i - 1]; + } + index[BLOCKS] = end; + //put objects in proper place + for(int bin = 0; bin < BLOCKS; bin++) { + while(place[bin] != index[bin + 1]) { + T curr = *place[bin]; + int x = (hash(curr) >> right_shift) & BLOCKS_MASK; + while(x != bin) { + T temp = *place[x]; + *place[x]++ = curr; + curr = temp; + x = (hash(curr) >> right_shift) & BLOCKS_MASK; + } + *place[bin]++ = curr; + } + } + //sort partitions + for(int bin = 0; bin < BLOCKS; bin++) { + if(index[bin + 1] - index[bin] > 64 && right_shift) { + _radix_sort(index[bin], index[bin + 1], hash, right_shift); + } else if (index[bin + 1] - index[bin] > 1) { + sort(index[bin], index[bin + 1], CMP()); + } + } +} + +template +struct RecurseParams { + index_t (*hash)(T&); + T** begin; + int log_size; + int num; +}; + +//basically used to wrap together calls to bin_sort +template +static void _radix_sort_worker(void* vp) { + RecurseParams* params = (RecurseParams*)vp; + index_t (*hash)(T&) = params->hash; + T** begin = params->begin; + int log_size = params->log_size; + int num = params->num; + for(int i = 0; i < num; i++) { + if(begin[i + 1] - begin[i] > 1) + _radix_sort(begin[i], begin[i + 1], hash, log_size); + } +} + +template +void radix_sort_in_place(T* begin, T* end, index_t (*hash)(T&), index_t maxv, int nthreads = 1) { + const int SHIFT = 8; + const int BLOCKS = (1 << (SHIFT + 1)); + + int log_size = sizeof(maxv) * 8; + while(!((1 << log_size) & maxv)) log_size--; + int right_shift = log_size - SHIFT; + + // {(maxv >> right_shift) + 1 <= BLOCKS}, + int occupied = (maxv >> right_shift) + 1; + time_t start = time(0); + // count number in each bin + index_t count[BLOCKS] = {0}; + for(T* curr = begin; curr != end; curr++) { + count[hash(*curr) >> right_shift]++; + } + + // sum numbers to create an index + T* index[BLOCKS + 1]; + T* place[BLOCKS]; + index[0] = place[0] = begin; + for(int i = 1; i < occupied; i++) { + index[i] = place[i] = index[i - 1] + count[i - 1]; + } + index[occupied] = end; + if(nthreads != 1) cerr << "COUNT NUMBER IN EACH BIN: " << time(0) - start << endl; + start = time(0); + //put objects in proper place + for(int bin = 0; bin < occupied; bin++) { + while(place[bin] != index[bin + 1]) { + T curr = *place[bin]; + int x = hash(curr) >> right_shift; + while(x != bin) { // switched inner loop here, removed branch statement + T temp = *place[x]; + *place[x]++ = curr; + curr = temp; + x = hash(curr) >> right_shift; + } + *place[bin]++ = curr; + } + } + if(nthreads != 1) cerr << "PLACE IN CORRECT BIN: " << time(0) - start << endl; + start = time(0); + //sort partitions + if(nthreads == 1) { + for(int bin = 0; bin < occupied; bin++) { + if(index[bin + 1] - index[bin] > 1) _radix_sort(index[bin], index[bin + 1], hash, right_shift); + } + } else { + AutoArray threads(nthreads); + EList > params; params.resizeExact(nthreads); + int st = 0; + for(int i = 0; i < nthreads; i++) { + params[i].hash = hash; + params[i].begin = index + st; + params[i].log_size = right_shift; + params[i].num = occupied / nthreads; + threads[i] = new tthread::thread(&_radix_sort_worker, (void*)¶ms[i]); + st += params[i].num; + } + //do any remaining bins using main thread + for(int bin = st; bin < occupied; bin++) { + if(index[bin + 1] - index[bin] > 1) _radix_sort(index[bin], index[bin + 1], hash, right_shift); + } + for(int i = 0; i < nthreads; i++) { + threads[i]->join(); + } + } + if(nthreads != 1) cerr << "FINISHED RECURSIVE SORTS: " << time(0) - start << endl; +} + +template +struct CountParams { + T* begin; + T* end; + T* o; + index_t* count; + index_t (*hash)(T&); + int occupied; + int right_shift; +}; + +template +static void _count_worker(void* vp) { + CountParams* params = (CountParams*)vp; + T* begin = params->begin; + T* end = params->end; + index_t (*hash)(T&) = params->hash; + int occupied = params->occupied; + int right_shift = params->right_shift; + + params->count = new index_t[occupied + 1](); + for(T* curr = begin; curr != end; curr++) { + params->count[hash(*curr) >> right_shift]++; + } +} +template +static void _write_worker(void* vp) { + CountParams* params = (CountParams*)vp; + T* begin = params->begin; + T* end = params->end; + T* o = params->o; + index_t* count = params->count; + index_t (*hash)(T&) = params->hash; + int right_shift = params->right_shift; + + for(T* curr = begin; curr != end; curr++) { + o[count[hash(*curr) >> right_shift]++] = *curr; + } +} + +template +void radix_sort_copy(T* begin, T* end, T* o, index_t (*hash)(T&), index_t maxv, int nthreads = 1) { + //set parameters + const int SHIFT = 8; + const int BLOCKS = (1 << (SHIFT + 1)); + int log_size = sizeof(maxv) * 8; + while(!((1 << log_size) & maxv)) log_size--; + int right_shift = log_size - SHIFT; + int occupied = (maxv >> right_shift) + 1; + //count nodes + time_t start = time(0); + EList > cparams; cparams.resizeExact(nthreads); + AutoArray threads1(nthreads); + T* st = begin; + T* en = st + (end - begin) / nthreads; + for(int i = 0; i < nthreads; i++) { + cparams[i].begin = st; + cparams[i].end = en; + cparams[i].hash = hash; + cparams[i].o = o; + cparams[i].occupied = occupied; + cparams[i].right_shift= right_shift; + if(nthreads == 1) { + _count_worker((void*)&cparams[i]); + } else { + threads1[i] = new tthread::thread(&_count_worker, (void*)&cparams[i]); + } + st = en; + if(i + 2 == nthreads) { + en = end; + } else { + en = st + (end - begin) / nthreads; + } + } + if(nthreads > 1) { + for(int i = 0; i < nthreads; i++) { + threads1[i]->join(); + delete threads1[i]; + } + } + if(nthreads != 1) cerr << "COUNT NUMBER IN EACH BIN: " << time(0) - start << endl; + start = time(0); + //transform counts into index + index_t tot = cparams[0].count[0]; + cparams[0].count[0] = 0; + for(int i = 1; i < nthreads; i++) { + tot += cparams[i].count[0]; + cparams[i].count[0] = tot - cparams[i].count[0]; + } + for(int j = 1; j < occupied + 1; j++) { + for(int i = 0; i < nthreads; i++) { + tot += cparams[i].count[j]; + cparams[i].count[j] = tot - cparams[i].count[j]; + } + } + T* index[BLOCKS + 1]; + for(int i = 0; i < occupied + 1; i++) { + index[i] = o + cparams[0].count[i]; + } + //write T's to correct bin + if(nthreads == 1) { + _write_worker((void*)&cparams[0]); + } else { + for(int i = 0; i < nthreads; i++) + threads1[i] = new tthread::thread(&_write_worker, (void*)&cparams[i]); + for(int i = 0; i < nthreads; i++) { + threads1[i]->join(); + } + } + for(int i = 0; i < nthreads; i++) { + delete[] cparams[i].count; + delete threads1[i]; + } + if(nthreads != 1) cerr << "FINISHED FIRST ROUND: " << time(0) - start << endl; + start = time(0); + //sort partitions + if(nthreads == 1) { + for(int bin = 0; bin < occupied; bin++) + if(index[bin + 1] - index[bin] > 1) + _radix_sort(index[bin], index[bin + 1], hash, right_shift); + } else { + AutoArray threads(nthreads); + EList > params; params.resizeExact(nthreads); + int st = 0; + for(int i = 0; i < nthreads; i++) { + params[i].hash = hash; + params[i].begin = index + st; + params[i].log_size = right_shift; + params[i].num = 0; + index_t remaining_elements = (index_t)(index[occupied] - index[st]); + while(params[i].num + st < occupied + && (index_t)(index[params[i].num + st] - index[st]) < remaining_elements / (nthreads - i)) + params[i].num++; + cerr << params[i].num << " " << (index_t)(index[params[i].num + st] - index[st]) << endl; + threads[i] = new tthread::thread(&_radix_sort_worker, (void*)¶ms[i]); + st += params[i].num; + } + //do any remaining bins using main thread + for(int bin = st; bin < occupied; bin++) { + if(index[bin + 1] - index[bin] > 1) + _radix_sort(index[bin], index[bin + 1], hash, right_shift); + } + for(int i = 0; i < nthreads; i++) { + threads[i]->join(); + delete threads[i]; + } + } + if(nthreads != 1) cerr << "FINISHED RECURSIVE SORTS: " << time(0) - start << endl; +} + +#endif //RADIX_SORT_H_ diff --git a/random_source.cpp b/random_source.cpp new file mode 100644 index 0000000..0311f91 --- /dev/null +++ b/random_source.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "random_source.h" +#include "random_util.h" + +#ifdef MERSENNE_TWISTER + +void RandomSource::gen_state() { + for(int i = 0; i < (n - m); ++i) { + state_[i] = state_[i + m] ^ twiddle(state_[i], state_[i + 1]); + } + for(int i = n - m; i < (n - 1); ++i) { + state_[i] = state_[i + m - n] ^ twiddle(state_[i], state_[i + 1]); + } + state_[n - 1] = state_[m - 1] ^ twiddle(state_[n - 1], state_[0]); + p_ = 0; // reset position +} + +void RandomSource::init(uint32_t s) { // init by 32 bit seed + reset(); + state_[0] = s; + for(int i = 1; i < n; ++i) { + state_[i] = 1812433253UL * (state_[i - 1] ^ (state_[i - 1] >> 30)) + i; + } + p_ = n; // force gen_state() to be called for next random number + inited_ = true; +} + +void RandomSource::init(const uint32_t* array, int size) { // init by array + init(19650218UL); + int i = 1, j = 0; + for(int k = ((n > size) ? n : size); k; --k) { + state_[i] = (state_[i] ^ ((state_[i - 1] ^ (state_[i - 1] >> 30)) * 1664525UL)) + array[j] + j; // non linear + ++j; j %= size; + if((++i) == n) { state_[0] = state_[n - 1]; i = 1; } + } + for(int k = n - 1; k; --k) { + state_[i] = (state_[i] ^ ((state_[i - 1] ^ (state_[i - 1] >> 30)) * 1566083941UL)) - i; + if((++i) == n) { state_[0] = state_[n - 1]; i = 1; } + } + state_[0] = 0x80000000UL; // MSB is 1; assuring non-zero initial array + p_ = n; // force gen_state() to be called for next random number + inited_ = true; +} + +#endif + +#ifdef MAIN_RANDOM_SOURCE + +using namespace std; + +int main(void) { + cerr << "Test 1" << endl; + { + RandomSource rnd; + int cnts[32]; + for(size_t i = 0; i < 32; i++) { + cnts[i] = 0; + } + for(uint32_t j = 0; j < 10; j++) { + rnd.init(j); + for(size_t i = 0; i < 10000; i++) { + uint32_t rndi = rnd.nextU32(); + for(size_t i = 0; i < 32; i++) { + if((rndi & 1) != 0) { + cnts[i]++; + } + rndi >>= 1; + } + } + for(size_t i = 0; i < 32; i++) { + cerr << i << ": " << cnts[i] << endl; + } + } + } + + cerr << "Test 2" << endl; + { + int cnts[4][4]; + for(size_t i = 0; i < 4; i++) { + for(size_t j = 0; j < 4; j++) { + cnts[i][j] = 0; + } + } + RandomSource rnd; + Random1toN rn1n; + for(size_t i = 0; i < 100; i++) { + rnd.init((uint32_t)i); + rn1n.init(4, true); + uint32_t ri = rn1n.next(rnd); + cnts[ri][0]++; + ri = rn1n.next(rnd); + cnts[ri][1]++; + ri = rn1n.next(rnd); + cnts[ri][2]++; + ri = rn1n.next(rnd); + cnts[ri][3]++; + } + for(size_t i = 0; i < 4; i++) { + for(size_t j = 0; j < 4; j++) { + cerr << cnts[i][j]; + if(j < 3) { + cerr << ", "; + } + } + cerr << endl; + } + } +} + +#endif diff --git a/random_source.h b/random_source.h new file mode 100644 index 0000000..098d54f --- /dev/null +++ b/random_source.h @@ -0,0 +1,239 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef RANDOM_GEN_H_ +#define RANDOM_GEN_H_ + +#include +#include "assert_helpers.h" + +//#define MERSENNE_TWISTER + +#ifndef MERSENNE_TWISTER + +/** + * Simple pseudo-random linear congruential generator, a la Numerical + * Recipes. + */ +class RandomSource { +public: + static const uint32_t DEFUALT_A = 1664525; + static const uint32_t DEFUALT_C = 1013904223; + + RandomSource() : + a(DEFUALT_A), c(DEFUALT_C), inited_(false) { } + RandomSource(uint32_t _last) : + a(DEFUALT_A), c(DEFUALT_C), last(_last), inited_(true) { } + RandomSource(uint32_t _a, uint32_t _c) : + a(_a), c(_c), inited_(false) { } + + void init(uint32_t seed = 0) { + last = seed; + inited_ = true; + lastOff = 30; + } + + uint32_t nextU32() { + assert(inited_); + uint32_t ret; + last = a * last + c; + ret = last >> 16; + last = a * last + c; + ret ^= last; + lastOff = 0; + return ret; + } + + uint64_t nextU64() { + assert(inited_); + uint64_t first = nextU32(); + first = first << 32; + uint64_t second = nextU32(); + return first | second; + } + + /** + * Return a pseudo-random unsigned 32-bit integer sampled uniformly + * from [lo, hi]. + */ + uint32_t nextU32Range(uint32_t lo, uint32_t hi) { + uint32_t ret = lo; + if(hi > lo) { + ret += (nextU32() % (hi-lo+1)); + } + return ret; + } + + /** + * Get next 2-bit unsigned integer. + */ + uint32_t nextU2() { + assert(inited_); + if(lastOff > 30) { + nextU32(); + } + uint32_t ret = (last >> lastOff) & 3; + lastOff += 2; + return ret; + } + + /** + * Get next boolean. + */ + bool nextBool() { + assert(inited_); + if(lastOff > 31) { + nextU32(); + } + uint32_t ret = (last >> lastOff) & 1; + lastOff++; + return ret; + } + + /** + * Return an unsigned int chosen by picking randomly from among + * options weighted by probabilies supplied as the elements of the + * 'weights' array of length 'numWeights'. The weights should add + * to 1. + */ + uint32_t nextFromProbs( + const float* weights, + size_t numWeights) + { + float f = nextFloat(); + float tot = 0.0f; // total weight seen so far + for(uint32_t i = 0; i < numWeights; i++) { + tot += weights[i]; + if(f < tot) return i; + } + return (uint32_t)(numWeights-1); + } + + float nextFloat() { + assert(inited_); + return (float)nextU32() / (float)0xffffffff; + } + + static uint32_t nextU32(uint32_t last, + uint32_t a = DEFUALT_A, + uint32_t c = DEFUALT_C) + { + return (a * last) + c; + } + + uint32_t currentA() const { return a; } + uint32_t currentC() const { return c; } + uint32_t currentLast() const { return last; } + +private: + uint32_t a; + uint32_t c; + uint32_t last; + uint32_t lastOff; + bool inited_; +}; + +#else + +class RandomSource { // Mersenne Twister random number generator + +public: + + // default constructor: uses default seed only if this is the first instance + RandomSource() { + reset(); + } + + // constructor with 32 bit int as seed + RandomSource(uint32_t s) { + init(s); + } + + // constructor with array of size 32 bit ints as seed + RandomSource(const uint32_t* array, int size) { + init(array, size); + } + + void reset() { + state_[0] = 0; + p_ = 0; + inited_ = false; + } + + virtual ~RandomSource() { } + + // the two seed functions + void init(uint32_t); // seed with 32 bit integer + void init(const uint32_t*, int size); // seed with array + + /** + * Return next 1-bit unsigned integer. + */ + bool nextBool() { + return (nextU32() & 1) == 0; + } + + /** + * Get next unsigned 32-bit integer. + */ + inline uint32_t nextU32() { + assert(inited_); + if(p_ == n) { + gen_state(); // new state vector needed + } + // gen_state() is split off to be non-inline, because it is only called once + // in every 624 calls and otherwise irand() would become too big to get inlined + uint32_t x = state_[p_++]; + x ^= (x >> 11); + x ^= (x << 7) & 0x9D2C5680UL; + x ^= (x << 15) & 0xEFC60000UL; + x ^= (x >> 18); + return x; + } + + /** + * Return next float between 0 and 1. + */ + float nextFloat() { + assert(inited_); + return (float)nextU32() / (float)0xffffffff; + } + +protected: // used by derived classes, otherwise not accessible; use the ()-operator + + static const int n = 624, m = 397; // compile time constants + + // the variables below are static (no duplicates can exist) + uint32_t state_[n]; // state vector array + int p_; // position in state array + + bool inited_; // true if init function has been called + + // private functions used to generate the pseudo random numbers + uint32_t twiddle(uint32_t u, uint32_t v) { + return (((u & 0x80000000UL) | (v & 0x7FFFFFFFUL)) >> 1) ^ ((v & 1UL) ? 0x9908B0DFUL : 0x0UL); + } + + void gen_state(); // generate new state + +}; + +#endif + +#endif /*RANDOM_GEN_H_*/ diff --git a/random_util.cpp b/random_util.cpp new file mode 100644 index 0000000..2c5ed7d --- /dev/null +++ b/random_util.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "random_util.h" + +const size_t Random1toN::SWAPLIST_THRESH = 128; +const size_t Random1toN::CONVERSION_THRESH = 16; +const float Random1toN::CONVERSION_FRAC = 0.10f; diff --git a/random_util.h b/random_util.h new file mode 100644 index 0000000..39f8c04 --- /dev/null +++ b/random_util.h @@ -0,0 +1,221 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef RANDOM_UTIL_H_ +#define RANDOM_UTIL_H_ + +#include +#include "random_source.h" +#include "ds.h" + +/** + * Return a random integer in [1, N]. Each time it's called it samples again + * without replacement. done() indicates when all elements have been given + * out. + */ +class Random1toN { + + typedef uint32_t T; + +public: + + // A set with fewer than this many elements should kick us into swap-list + // mode immediately. Otherwise we start in seen-list mode and then + // possibly proceed to swap-list mode later. + static const size_t SWAPLIST_THRESH; + + // Convert seen-list to swap-list after this many entries in the seen-list. + static const size_t CONVERSION_THRESH; + + // Convert seen-list to swap-list after this (this times n_) many entries + // in the seen-list. + static const float CONVERSION_FRAC; + + Random1toN(int cat = 0) : + sz_(0), n_(0), cur_(0), + list_(SWAPLIST_THRESH, cat), seen_(CONVERSION_THRESH, cat), + thresh_(0) {} + + Random1toN(size_t n, int cat = 0) : + sz_(0), n_(n), cur_(0), + list_(SWAPLIST_THRESH, cat), seen_(CONVERSION_THRESH, cat), + thresh_(0) {} + + /** + * Initialize the set of pseudo-randoms to be given out without replacement. + */ + void init(size_t n, bool withoutReplacement) { + sz_ = n_ = n; + converted_ = false; + swaplist_ = n < SWAPLIST_THRESH || withoutReplacement; + cur_ = 0; + list_.clear(); + seen_.clear(); + thresh_ = std::max(CONVERSION_THRESH, (size_t)(CONVERSION_FRAC * n)); + } + + /** + * Reset in preparation for giving out a fresh collection of pseudo-randoms + * without replacement. + */ + void reset() { + sz_ = n_ = cur_ = 0; swaplist_ = converted_ = false; + list_.clear(); seen_.clear(); + thresh_ = 0; + } + + /** + * Get next pseudo-random element without replacement. + */ + T next(RandomSource& rnd) { + assert(!done()); + if(cur_ == 0 && !converted_) { + // This is the first call to next() + if(n_ == 1) { + // Trivial case: set of 1 + cur_ = 1; + return 0; + } + if(swaplist_) { + // The set is small, so we go immediately to the random + // swapping list + list_.resize(n_); + for(size_t i = 0; i < n_; i++) { + list_[i] = (T)i; + } + } + } + if(swaplist_) { + // Get next pseudo-random using the swap-list + size_t r = cur_ + (rnd.nextU32() % (n_ - cur_)); + if(r != cur_) { + std::swap(list_[cur_], list_[r]); + } + return list_[cur_++]; + } else { + assert(!converted_); + // Get next pseudo-random but reject it if it's in the seen-list + bool again = true; + T rn = 0; + size_t seenSz = seen_.size(); + while(again) { + rn = rnd.nextU32() % (T)n_; + again = false; + for(size_t i = 0; i < seenSz; i++) { + if(seen_[i] == rn) { + again = true; + break; + } + } + } + // Add it to the seen-list + seen_.push_back(rn); + cur_++; + assert_leq(cur_, n_); + // Move on to using the swap-list? + assert_gt(thresh_, 0); + if(seen_.size() >= thresh_ && cur_ < n_) { + // Add all elements not already in the seen list to the + // swap-list + assert(!seen_.empty()); + seen_.sort(); + list_.resize(n_ - cur_); + size_t prev = 0; + size_t cur = 0; + for(size_t i = 0; i <= seenSz; i++) { + // Add all the elements between the previous element and + // this one + for(size_t j = prev; j < seen_[i]; j++) { + list_[cur++] = (T)j; + } + prev = seen_[i]+1; + } + for(size_t j = prev; j < n_; j++) { + list_[cur++] = (T)j; + } + assert_eq(cur, n_ - cur_); + seen_.clear(); + cur_ = 0; + n_ = list_.size(); + converted_ = true; + swaplist_ = true; + } + return rn; + } + } + + /** + * Return true iff the generator was initialized. + */ + bool inited() const { return n_ > 0; } + + /** + * Set so that there are no pseudo-randoms remaining. + */ + void setDone() { assert(inited()); cur_ = n_; } + + /** + * Return true iff all pseudo-randoms have already been given out. + */ + bool done() const { return inited() && cur_ >= n_; } + + /** + * Return the total number of pseudo-randoms we are initialized to give + * out, including ones already given out. + */ + size_t size() const { return n_; } + + /** + * Return the number of pseudo-randoms left to give out. + */ + size_t left() const { return n_ - cur_; } + + /** + * Return the total size occupued by the Descent driver and all its + * constituent parts. + */ + size_t totalSizeBytes() const { + return list_.totalSizeBytes() + + seen_.totalSizeBytes(); + } + + /** + * Return the total capacity of the Descent driver and all its constituent + * parts. + */ + size_t totalCapacityBytes() const { + return list_.totalCapacityBytes() + + seen_.totalCapacityBytes(); + } + +protected: + + size_t sz_; // domain to pick elts from + size_t n_; // number of elements in active list + bool swaplist_; // if small, use swapping + bool converted_; // true iff seen-list was converted to swap-list + size_t cur_; // # times next() was called + EList list_; // pseudo-random swapping list + EList seen_; // prior to swaplist_ mode, list of + // pseudo-randoms given out + size_t thresh_; // conversion threshold for this instantiation, which + // depends both on CONVERSION_THRESH and on n_ +}; + +#endif diff --git a/read.h b/read.h new file mode 100644 index 0000000..00bbd60 --- /dev/null +++ b/read.h @@ -0,0 +1,599 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * This file is edited by Yun (Leo) Zhang for HISAT-3N. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef READ_H_ +#define READ_H_ + +#include +#include +#include "ds.h" +#include "sstring.h" +#include "filebuf.h" +#include "util.h" + + +/** + * the threeN_cycle + */ +/*enum { + threeN_CT_FW = 0, + threeN_CT_RC, + threeN_GA_FW, + threeN_GA_RC +};*/ + +enum { + threeN_type1conversion_FW = 0, + threeN_type1conversion_RC, + threeN_type2conversion_FW, + threeN_type2conversion_RC +}; + +enum rna_strandness_format { + RNA_STRANDNESS_UNKNOWN = 0, + RNA_STRANDNESS_F, + RNA_STRANDNESS_R, + RNA_STRANDNESS_FR, + RNA_STRANDNESS_RF +}; + +typedef uint64_t TReadId; +typedef size_t TReadOff; +typedef int64_t TAlScore; + +extern bool threeN; + +class HitSet; + +/** + * A buffer for keeping all relevant information about a single read. + */ +struct Read { + + Read() { reset(); } + + Read(const char *nm, const char *seq, const char *ql) { init(nm, seq, ql); } + + void reset() { + rdid = 0; + endid = 0; + alts = 0; + trimmed5 = trimmed3 = 0; + readOrigBuf.clear(); + patFw.clear(); + patFw_3N.clear(); + patRc.clear(); + qual.clear(); + patFwRev.clear(); + patRcRev.clear(); + qualRev.clear(); + name.clear(); + originalFw.clear(); + originalRc.clear(); + for(int j = 0; j < 3; j++) { + altPatFw[j].clear(); + altPatFwRev[j].clear(); + altPatRc[j].clear(); + altPatRcRev[j].clear(); + altQual[j].clear(); + altQualRev[j].clear(); + } + color = fuzzy = false; + primer = '?'; + trimc = '?'; + filter = '?'; + seed = 0; + ns_ = 0; + threeN_cycle = 0; + oppositeConversion_3N = false; + } + + /** + * Finish initializing a new read. + */ + void finalize() { + for(size_t i = 0; i < patFw.length(); i++) { + if((int)patFw[i] > 3) { + ns_++; + } + } + constructRevComps(); + constructReverses(); + } + + /** + * change patFw sequence based on current threeN_cycle and newMappingCycle. + * + * There are two types of changes: + * type1conversion: hs3N_convertedFrom to hs3N_convertedTo + * type2conversion: hs3N_convertedFromComplement to hs3N_convertedToComplement + * + * The initial threeN_cycle is 0. There are 4 cycle: 0, 1, 2, 3; + * + * mate 1, mate2 + * initial: threeN_type1conversion_FW(0), threeN_type1conversion_FW(0), + * --------------- type1->type2 change conversion type + * 1st cycle: threeN_type1conversion_FW(0), threeN_type2conversion_RC(3 = 3-0), + * 2nd cycle: threeN_type1conversion_RC(1), threeN_type2conversion_FW(2 = 3-1), + * type1c->type2 type2->type1 change conversion type + * 3rd cycle: threeN_type2conversion_FW(2), threeN_type1conversion_RC(1 = 3-2), + * 4rd cycle: threeN_type2conversion_RC(3), threeN_type1conversion_FW(0 = 3-3), + */ + void changePlan3N(int newMappingCycle) { + if (name.length() == 0) return; + if ((threeN_cycle == threeN_type1conversion_FW && newMappingCycle == threeN_type2conversion_RC) || + (threeN_cycle == threeN_type1conversion_RC && newMappingCycle == threeN_type2conversion_FW) || + (threeN_cycle == threeN_type2conversion_FW && newMappingCycle == threeN_type1conversion_RC)) { + ns_ = 0; + swap(patFw, patFw_3N); + finalize(); + } + threeN_cycle = newMappingCycle; + oppositeConversion_3N = false; + } + + /** + * Simple init function, used for testing. + */ + void init( + const char *nm, + const char *seq, + const char *ql) + { + reset(); + patFw.installChars(seq); + qual.install(ql); + for(size_t i = 0; i < patFw.length(); i++) { + if((int)patFw[i] > 3) { + ns_++; + } + } + constructRevComps(); + constructReverses(); + if(nm != NULL) name.install(nm); + } + + /// Return true iff the read (pair) is empty + bool empty() const { + return patFw.empty(); + } + + /// Return length of the read in the buffer + size_t length() const { + return patFw.length(); + } + + /** + * Return the number of Ns in the read. + */ + size_t ns() const { + return ns_; + } + + /** + * Construct reverse complement of the pattern and the fuzzy + * alternative patters. If read is in colorspace, just reverse + * them. + */ + void constructRevComps() { + if(color) { + patRc.installReverse(patFw); + for(int j = 0; j < alts; j++) { + altPatRc[j].installReverse(altPatFw[j]); + } + if (threeN) originalRc.installReverse(originalFw); + } else { + patRc.installReverseComp(patFw); + for(int j = 0; j < alts; j++) { + altPatRc[j].installReverseComp(altPatFw[j]); + } + if (threeN) originalRc.installReverseComp(originalFw); + } + } + + /** + * Given patFw, patRc, and qual, construct the *Rev versions in + * place. Assumes constructRevComps() was called previously. + */ + void constructReverses() { + patFwRev.installReverse(patFw); + patRcRev.installReverse(patRc); + qualRev.installReverse(qual); + for(int j = 0; j < alts; j++) { + altPatFwRev[j].installReverse(altPatFw[j]); + altPatRcRev[j].installReverse(altPatRc[j]); + altQualRev[j].installReverse(altQual[j]); + } + } + + /** + * Append a "/1" or "/2" string onto the end of the name buf if + * it's not already there. + */ + void fixMateName(int i) { + assert(i == 1 || i == 2); + size_t namelen = name.length(); + bool append = false; + if(namelen < 2) { + // Name is too short to possibly have /1 or /2 on the end + append = true; + } else { + if(i == 1) { + // append = true iff mate name does not already end in /1 + append = + name[namelen-2] != '/' || + name[namelen-1] != '1'; + } else { + // append = true iff mate name does not already end in /2 + append = + name[namelen-2] != '/' || + name[namelen-1] != '2'; + } + } + if(append) { + name.append('/'); + name.append("012"[i]); + } + } + + /** + * Dump basic information about this read to the given ostream. + */ + void dump(std::ostream& os) const { + using namespace std; + os << name << ' '; + if(color) { + os << patFw.toZBufXForm("0123."); + } else { + os << patFw; + } + os << ' '; + // Print out the fuzzy alternative sequences + for(int j = 0; j < 3; j++) { + bool started = false; + if(!altQual[j].empty()) { + for(size_t i = 0; i < length(); i++) { + if(altQual[j][i] != '!') { + started = true; + } + if(started) { + if(altQual[j][i] == '!') { + os << '-'; + } else { + if(color) { + os << "0123."[(int)altPatFw[j][i]]; + } else { + os << altPatFw[j][i]; + } + } + } + } + } + cout << " "; + } + os << qual.toZBuf() << " "; + // Print out the fuzzy alternative quality strings + for(int j = 0; j < 3; j++) { + bool started = false; + if(!altQual[j].empty()) { + for(size_t i = 0; i < length(); i++) { + if(altQual[j][i] != '!') { + started = true; + } + if(started) { + os << altQual[j][i]; + } + } + } + if(j == 2) { + os << endl; + } else { + os << " "; + } + } + } + + /** + * Check whether two reads are the same in the sense that they will + * lead to us finding the same set of alignments. + */ + static bool same( + const BTDnaString& seq1, + const BTString& qual1, + const BTDnaString& seq2, + const BTString& qual2, + bool qualitiesMatter) + { + if(seq1.length() != seq2.length()) { + return false; + } + for(size_t i = 0; i < seq1.length(); i++) { + if(seq1[i] != seq2[i]) return false; + } + if(qualitiesMatter) { + if(qual1.length() != qual2.length()) { + return false; + } + for(size_t i = 0; i < qual1.length(); i++) { + if(qual1[i] != qual2[i]) return false; + } + } + return true; + } + + /** + * Get the nucleotide and quality value at the given offset from 5' end. + * If 'fw' is false, get the reverse complement. + */ + std::pair get(TReadOff off5p, bool fw) const { + assert_lt(off5p, length()); + int c = (int)patFw[off5p]; + int q = qual[off5p]; + assert_geq(q, 33); + return make_pair((!fw && c < 4) ? (c ^ 3) : c, q - 33); + } + + /** + * Get the nucleotide at the given offset from 5' end. + * If 'fw' is false, get the reverse complement. + */ + int getc(TReadOff off5p, bool fw) const { + assert_lt(off5p, length()); + int c = (int)patFw[off5p]; + return (!fw && c < 4) ? (c ^ 3) : c; + } + + /** + * Get the quality value at the given offset from 5' end. + */ + int getq(TReadOff off5p) const { + assert_lt(off5p, length()); + int q = qual[off5p]; + assert_geq(q, 33); + return q-33; + } + +#ifndef NDEBUG + /** + * Check that read info is internally consistent. + */ + bool repOk() const { + if(patFw.empty()) return true; + assert_eq(qual.length(), patFw.length()); + return true; + } +#endif + + BTDnaString patFw; // forward-strand sequence + BTDnaString patFw_3N; + BTDnaString patRc; // reverse-complement sequence + BTDnaString patRc1; + BTString qual; // quality values + BTDnaString originalFw; // the forward-strand sequence from read (without editing) + BTDnaString originalRc; // the reverse-complement sequence from read (without editing) + + BTDnaString altPatFw[3]; + BTDnaString altPatRc[3]; + BTString altQual[3]; + + BTDnaString patFwRev; + BTDnaString patRcRev; + BTString qualRev; + + BTDnaString altPatFwRev[3]; + BTDnaString altPatRcRev[3]; + BTString altQualRev[3]; + + // For remembering the exact input text used to define a read + SStringExpandable readOrigBuf; + + BTString name; // read name + TReadId rdid; // 0-based id based on pair's offset in read file(s) + TReadId endid; // 0-based id based on pair's offset in read file(s) + // and which mate ("end") this is + int mate; // 0 = single-end, 1 = mate1, 2 = mate2 + uint32_t seed; // random seed + size_t ns_; // # Ns + int alts; // number of alternatives + bool fuzzy; // whether to employ fuzziness + bool color; // whether read is in color space + char primer; // primer base, for csfasta files + char trimc; // trimmed color, for csfasta files + char filter; // if read format permits filter char, set it here + int trimmed5; // amount actually trimmed off 5' end + int trimmed3; // amount actually trimmed off 3' end + HitSet *hitset; // holds previously-found hits; for chaining + // for HISAT-3N + int threeN_cycle; + bool oppositeConversion_3N; +}; + +/** + * A string of FmStringOps represent a string of tasks performed by the + * best-first alignment search. We model the search as a series of FM ops + * interspersed with reported alignments. + */ +struct FmStringOp { + bool alignment; // true -> found an alignment + TAlScore pen; // penalty of the FM op or alignment + size_t n; // number of FM ops (only relevant for non-alignment) +}; + +/** + * A string that summarizes the progress of an FM-index-assistet best-first + * search. Useful for trying to figure out what the aligner is spending its + * time doing for a given read. + */ +struct FmString { + + /** + * Add one or more FM index ops to the op string + */ + void add(bool alignment, TAlScore pen, size_t nops) { + if(ops.empty() || ops.back().pen != pen) { + ops.expand(); + ops.back().alignment = alignment; + ops.back().pen = pen; + ops.back().n = 0; + } + ops.back().n++; + } + + /** + * Reset FmString to uninitialized state. + */ + void reset() { + pen = std::numeric_limits::max(); + ops.clear(); + } + + /** + * Print a :Z optional field where certain characters (whitespace, colon + * and percent) are escaped using % escapes. + */ + void print(BTString& o, char *buf) const { + for(size_t i = 0; i < ops.size(); i++) { + if(i > 0) { + o.append(';'); + } + if(ops[i].alignment) { + o.append("A,"); + itoa10(ops[i].pen, buf); + o.append(buf); + } else { + o.append("F,"); + itoa10(ops[i].pen, buf); o.append(buf); + o.append(','); + itoa10(ops[i].n, buf); o.append(buf); + } + } + } + + TAlScore pen; // current penalty + EList ops; // op string +}; + +/** + * Key per-read metrics. These are used for thresholds, allowing us to bail + * for unproductive reads. They also the basis of what's printed when the user + * specifies --read-times. + */ +struct PerReadMetrics { + + PerReadMetrics() { reset(); } + + void reset() { + nExIters = + nExDps = nExDpSuccs = nExDpFails = + nMateDps = nMateDpSuccs = nMateDpFails = + nExUgs = nExUgSuccs = nExUgFails = + nMateUgs = nMateUgSuccs = nMateUgFails = + nExEes = nExEeSuccs = nExEeFails = + nRedundants = + nEeFmops = nSdFmops = nExFmops = + nDpFail = nDpFailStreak = nDpLastSucc = + nUgFail = nUgFailStreak = nUgLastSucc = + nEeFail = nEeFailStreak = nEeLastSucc = + nFilt = 0; + nFtabs = 0; + nRedSkip = 0; + nRedFail = 0; + nRedIns = 0; + doFmString = false; + nSeedRanges = nSeedElts = 0; + nSeedRangesFw = nSeedEltsFw = 0; + nSeedRangesRc = nSeedEltsRc = 0; + seedMedian = seedMean = 0; + bestLtMinscMate1 = + bestLtMinscMate2 = std::numeric_limits::min(); + fmString.reset(); + } + + struct timeval tv_beg; // timer start to measure how long alignment takes + struct timezone tz_beg; // timer start to measure how long alignment takes + + uint64_t nExIters; // iterations of seed hit extend loop + + uint64_t nExDps; // # extend DPs run on this read + uint64_t nExDpSuccs; // # extend DPs run on this read + uint64_t nExDpFails; // # extend DPs run on this read + + uint64_t nExUgs; // # extend ungapped alignments run on this read + uint64_t nExUgSuccs; // # extend ungapped alignments run on this read + uint64_t nExUgFails; // # extend ungapped alignments run on this read + + uint64_t nExEes; // # extend ungapped alignments run on this read + uint64_t nExEeSuccs; // # extend ungapped alignments run on this read + uint64_t nExEeFails; // # extend ungapped alignments run on this read + + uint64_t nMateDps; // # mate DPs run on this read + uint64_t nMateDpSuccs; // # mate DPs run on this read + uint64_t nMateDpFails; // # mate DPs run on this read + + uint64_t nMateUgs; // # mate ungapped alignments run on this read + uint64_t nMateUgSuccs; // # mate ungapped alignments run on this read + uint64_t nMateUgFails; // # mate ungapped alignments run on this read + + uint64_t nRedundants; // # redundant seed hits + + uint64_t nSeedRanges; // # BW ranges found for seeds + uint64_t nSeedElts; // # BW elements found for seeds + + uint64_t nSeedRangesFw; // # BW ranges found for seeds from fw read + uint64_t nSeedEltsFw; // # BW elements found for seeds from fw read + + uint64_t nSeedRangesRc; // # BW ranges found for seeds from fw read + uint64_t nSeedEltsRc; // # BW elements found for seeds from fw read + + uint64_t seedMedian; // median seed hit count + uint64_t seedMean; // rounded mean seed hit count + + uint64_t nEeFmops; // FM Index ops for end-to-end alignment + uint64_t nSdFmops; // FM Index ops used to align seeds + uint64_t nExFmops; // FM Index ops used to resolve offsets + + uint64_t nFtabs; // # ftab lookups + uint64_t nRedSkip; // # times redundant path was detected and aborted + uint64_t nRedFail; // # times a path was deemed non-redundant + uint64_t nRedIns; // # times a path was added to redundancy list + + uint64_t nDpFail; // number of dp failures in a row up until now + uint64_t nDpFailStreak; // longest streak of dp failures + uint64_t nDpLastSucc; // index of last dp attempt that succeeded + + uint64_t nUgFail; // number of ungap failures in a row up until now + uint64_t nUgFailStreak; // longest streak of ungap failures + uint64_t nUgLastSucc; // index of last ungap attempt that succeeded + + uint64_t nEeFail; // number of ungap failures in a row up until now + uint64_t nEeFailStreak; // longest streak of ungap failures + uint64_t nEeLastSucc; // index of last ungap attempt that succeeded + + uint64_t nFilt; // # mates filtered + + TAlScore bestLtMinscMate1; // best invalid score observed for mate 1 + TAlScore bestLtMinscMate2; // best invalid score observed for mate 2 + + // For collecting information to go into an FM string + bool doFmString; + FmString fmString; +}; + +#endif /*READ_H_*/ diff --git a/read_qseq.cpp b/read_qseq.cpp new file mode 100644 index 0000000..ced6c68 --- /dev/null +++ b/read_qseq.cpp @@ -0,0 +1,304 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "pat.h" + +/** + * Parse a name from fb_ and store in r. Assume that the next + * character obtained via fb_.get() is the first character of + * the sequence and the string stops at the next char upto (could + * be tab, newline, etc.). + */ +int QseqPatternSource::parseName( + Read& r, // buffer for mate 1 + Read* r2, // buffer for mate 2 (NULL if mate2 is read separately) + bool append, // true -> append characters, false -> skip them + bool clearFirst, // clear the name buffer first + bool warnEmpty, // emit a warning if nothing was added to the name + bool useDefault, // if nothing is read, put readCnt_ as a default value + int upto) // stop parsing when we first reach character 'upto' +{ + if(clearFirst) { + if(r2 != NULL) r2->name.clear(); + r.name.clear(); + } + while(true) { + int c; + if((c = fb_.get()) < 0) { + // EOF reached in the middle of the name + return -1; + } + if(c == '\n' || c == '\r') { + // EOL reached in the middle of the name + return -1; + } + if(c == upto) { + // Finished with field + break; + } + if(append) { + if(r2 != NULL) r2->name.append(c); + r.name.append(c); + } + } + // Set up a default name if one hasn't been set + if(r.name.empty() && useDefault && append) { + char cbuf[20]; + itoa10(readCnt_, cbuf); + r.name.append(cbuf); + if(r2 != NULL) r2->name.append(cbuf); + } + if(r.name.empty() && warnEmpty) { + cerr << "Warning: read had an empty name field" << endl; + } + return (int)r.name.length(); +} + +/** + * Parse a single sequence from fb_ and store in r. Assume + * that the next character obtained via fb_.get() is the first + * character of the sequence and the sequence stops at the next + * char upto (could be tab, newline, etc.). + */ +int QseqPatternSource::parseSeq( + Read& r, + int& charsRead, + int& trim5, + char upto) +{ + int begin = 0; + int c = fb_.get(); + assert(c != upto); + r.patFw.clear(); + r.color = gColor; + if(gColor) { + // NOTE: clearly this is not relevant for Illumina output, but + // I'm keeping it here in case there's some reason to put SOLiD + // data in this format in the future. + + // This may be a primer character. If so, keep it in the + // 'primer' field of the read buf and parse the rest of the + // read without it. + c = toupper(c); + if(asc2dnacat[c] > 0) { + // First char is a DNA char + int c2 = toupper(fb_.peek()); + // Second char is a color char + if(asc2colcat[c2] > 0) { + r.primer = c; + r.trimc = c2; + trim5 += 2; // trim primer and first color + } + } + if(c < 0) { return -1; } + } + while(c != upto) { + if(c == '.') c = 'N'; + if(gColor) { + if(c >= '0' && c <= '4') c = "ACGTN"[(int)c - '0']; + } + if(isalpha(c)) { + assert_in(toupper(c), "ACGTN"); + if(begin++ >= trim5) { + assert_neq(0, asc2dnacat[c]); + r.patFw.append(asc2dna[c]); + } + charsRead++; + } + if((c = fb_.get()) < 0) { + return -1; + } + } + r.patFw.trimEnd(gTrim3); + return (int)r.patFw.length(); +} + +/** + * Parse a single quality string from fb_ and store in r. + * Assume that the next character obtained via fb_.get() is + * the first character of the quality string and the string stops + * at the next char upto (could be tab, newline, etc.). + */ +int QseqPatternSource::parseQuals( + Read& r, + int charsRead, + int dstLen, + int trim5, + char& c2, + char upto = '\t', + char upto2 = -1) +{ + int qualsRead = 0; + int c = 0; + if (intQuals_) { + // Probably not relevant + char buf[4096]; + while (qualsRead < charsRead) { + qualToks_.clear(); + if(!tokenizeQualLine(fb_, buf, 4096, qualToks_)) break; + for (unsigned int j = 0; j < qualToks_.size(); ++j) { + char c = intToPhred33(atoi(qualToks_[j].c_str()), solQuals_); + assert_geq(c, 33); + if (qualsRead >= trim5) { + r.qual.append(c); + } + ++qualsRead; + } + } // done reading integer quality lines + if (charsRead > qualsRead) tooFewQualities(r.name); + } else { + // Non-integer qualities + while((qualsRead < dstLen + trim5) && c >= 0) { + c = fb_.get(); + c2 = c; + if (c == ' ') wrongQualityFormat(r.name); + if(c < 0) { + // EOF occurred in the middle of a read - abort + return -1; + } + if(!isspace(c) && c != upto && (upto2 == -1 || c != upto2)) { + if (qualsRead >= trim5) { + c = charToPhred33(c, solQuals_, phred64Quals_); + assert_geq(c, 33); + r.qual.append(c); + } + qualsRead++; + } else { + break; + } + } + } + if(r.qual.length() < (size_t)dstLen) { + tooFewQualities(r.name); + } + // TODO: How to detect too many qualities?? + r.qual.resize(dstLen); + while(c != -1 && c != upto && (upto2 == -1 || c != upto2)) { + c = fb_.get(); + c2 = c; + } + return qualsRead; +} + +/** + * Read another pattern from a Qseq input file. + */ +bool QseqPatternSource::read( + Read& r, + TReadId& rdid, + TReadId& endid, + bool& success, + bool& done) +{ + r.reset(); + r.color = gColor; + success = true; + done = false; + readCnt_++; + rdid = endid = readCnt_-1; + peekOverNewline(fb_); + fb_.resetLastN(); + // 1. Machine name + if(parseName(r, NULL, true, true, true, false, '\t') == -1) BAIL_UNPAIRED(); + assert_neq('\t', fb_.peek()); + r.name.append('_'); + // 2. Run number + if(parseName(r, NULL, true, false, true, false, '\t') == -1) BAIL_UNPAIRED(); + assert_neq('\t', fb_.peek()); + r.name.append('_'); + // 3. Lane number + if(parseName(r, NULL, true, false, true, false, '\t') == -1) BAIL_UNPAIRED(); + assert_neq('\t', fb_.peek()); + r.name.append('_'); + // 4. Tile number + if(parseName(r, NULL, true, false, true, false, '\t') == -1) BAIL_UNPAIRED(); + assert_neq('\t', fb_.peek()); + r.name.append('_'); + // 5. X coordinate of spot + if(parseName(r, NULL, true, false, true, false, '\t') == -1) BAIL_UNPAIRED(); + assert_neq('\t', fb_.peek()); + r.name.append('_'); + // 6. Y coordinate of spot + if(parseName(r, NULL, true, false, true, false, '\t') == -1) BAIL_UNPAIRED(); + assert_neq('\t', fb_.peek()); + r.name.append('_'); + // 7. Index + if(parseName(r, NULL, true, false, true, false, '\t') == -1) BAIL_UNPAIRED(); + assert_neq('\t', fb_.peek()); + r.name.append('/'); + // 8. Mate number + if(parseName(r, NULL, true, false, true, false, '\t') == -1) BAIL_UNPAIRED(); + // Empty sequence?? + if(fb_.peek() == '\t') { + // Get tab that separates seq from qual + ASSERT_ONLY(int c =) fb_.get(); + assert_eq('\t', c); + assert_eq('\t', fb_.peek()); + // Get tab that separates qual from filter + ASSERT_ONLY(c =) fb_.get(); + assert_eq('\t', c); + // Next char is first char of filter flag + assert_neq('\t', fb_.peek()); + fb_.resetLastN(); + cerr << "Warning: skipping empty QSEQ read with name '" << r.name << "'" << endl; + } else { + assert_neq('\t', fb_.peek()); + int charsRead = 0; + int mytrim5 = gTrim5; + // 9. Sequence + int dstLen = parseSeq(r, charsRead, mytrim5, '\t'); + assert_neq('\t', fb_.peek()); + if(dstLen < 0) BAIL_UNPAIRED(); + char ct = 0; + // 10. Qualities + if(parseQuals(r, charsRead, dstLen, mytrim5, ct, '\t', -1) < 0) BAIL_UNPAIRED(); + r.trimmed3 = gTrim3; + r.trimmed5 = mytrim5; + if(ct != '\t') { + cerr << "Error: QSEQ with name " << r.name << " did not have tab after qualities" << endl; + throw 1; + } + assert_eq(ct, '\t'); + } + // 11. Filter flag + int filt = fb_.get(); + if(filt == -1) BAIL_UNPAIRED(); + r.filter = filt; + if(filt != '0' && filt != '1') { + // Bad value for filt + } + if(fb_.peek() != -1 && fb_.peek() != '\n') { + // Bad value right after the filt field + } + fb_.get(); + r.readOrigBuf.install(fb_.lastN(), fb_.lastNLen()); + fb_.resetLastN(); + if(r.qual.length() < r.patFw.length()) { + tooFewQualities(r.name); + } else if(r.qual.length() > r.patFw.length()) { + tooManyQualities(r.name); + } +#ifndef NDEBUG + assert_eq(r.patFw.length(), r.qual.length()); + for(size_t i = 0; i < r.qual.length(); i++) { + assert_geq((int)r.qual[i], 33); + } +#endif + return true; +} diff --git a/ref_coord.cpp b/ref_coord.cpp new file mode 100644 index 0000000..738c6fa --- /dev/null +++ b/ref_coord.cpp @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "ref_coord.h" +#include + +using namespace std; + +ostream& operator<<(ostream& out, const Interval& c) { + out << c.upstream() << "+" << c.len(); + return out; +} + +ostream& operator<<(ostream& out, const Coord& c) { + out << c.ref() << ":" << c.off(); + return out; +} diff --git a/ref_coord.h b/ref_coord.h new file mode 100644 index 0000000..2967763 --- /dev/null +++ b/ref_coord.h @@ -0,0 +1,429 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef REF_COORD_H_ +#define REF_COORD_H_ + +#include +#include +#include +#include "assert_helpers.h" + +typedef int64_t TRefId; +typedef int64_t TRefOff; + +/** + * Encapsulates a reference coordinate; i.e. identifiers for (a) a + * reference sequence, and (b) a 0-based offset into that sequence. + */ +class Coord { + +public: + + Coord() { reset(); } + + Coord(const Coord& c) { init(c); } + + Coord(TRefId rf, TRefOff of, bool fw, TRefOff jof = 0) { init(rf, of, fw, jof); } + + /** + * Copy given fields into this Coord. + */ + void init(TRefId rf, TRefOff of, bool fw, TRefOff jof = 0) { + ref_ = rf; + off_ = of; + orient_ = (fw ? 1 : 0); + joinedOff_ = jof; + } + + /** + * Copy contents of given Coord into this one. + */ + void init(const Coord& c) { + ref_ = c.ref_; + off_ = c.off_; + orient_ = c.orient_; + joinedOff_ = c.joinedOff_; + } + + /** + * Return true iff this Coord is identical to the given Coord. + */ + bool operator==(const Coord& o) const { + assert(inited()); + assert(o.inited()); + return ref_ == o.ref_ && off_ == o.off_ && fw() == o.fw(); + } + + /** + * Return true iff this Coord is less than the given Coord. One Coord is + * less than another if (a) its reference id is less, (b) its orientation is + * less, or (c) its offset is less. + */ + bool operator<(const Coord& o) const { + if(ref_ < o.ref_) return true; + if(ref_ > o.ref_) return false; + if(orient_ < o.orient_) return true; + if(orient_ > o.orient_) return false; + if(off_ < o.off_) return true; + if(off_ > o.off_) return false; + return false; + } + + /** + * Return the opposite result from operator<. + */ + bool operator>=(const Coord& o) const { + return !((*this) < o); + } + + /** + * Return true iff this Coord is greater than the given Coord. One Coord + * is greater than another if (a) its reference id is greater, (b) its + * orientation is greater, or (c) its offset is greater. + */ + bool operator>(const Coord& o) const { + if(ref_ > o.ref_) return true; + if(ref_ < o.ref_) return false; + if(orient_ > o.orient_) return true; + if(orient_ < o.orient_) return false; + if(off_ > o.off_) return true; + if(off_ < o.off_) return false; + return false; + } + + /** + * Return the opposite result from operator>. + */ + bool operator<=(const Coord& o) const { + return !((*this) > o); + } + + /** + * Reset this coord to uninitialized state. + */ + void reset() { + ref_ = std::numeric_limits::max(); + off_ = std::numeric_limits::max(); + orient_ = -1; + joinedOff_ = std::numeric_limits::max(); + } + + /** + * Return true iff this Coord is initialized (i.e. ref and off have both + * been set since the last call to reset()). + */ + bool inited() const { + if(ref_ != std::numeric_limits::max() && + off_ != std::numeric_limits::max()) + { + assert(orient_ == 0 || orient_ == 1); + return true; + } + return false; + } + + /** + * Get orientation of the Coord. + */ + bool fw() const { + assert(inited()); + assert(orient_ == 0 || orient_ == 1); + return orient_ == 1; + } + +#ifndef NDEBUG + /** + * Check that coord is internally consistent. + */ + bool repOk() const { + if(ref_ != std::numeric_limits::max() && + off_ != std::numeric_limits::max()) + { + assert(orient_ == 0 || orient_ == 1); + } + return true; + } +#endif + + /** + * Check whether an interval defined by this coord and having + * length 'len' is contained within an interval defined by + * 'inbegin' and 'inend'. + */ + bool within(int64_t len, int64_t inbegin, int64_t inend) const { + return off_ >= inbegin && off_ + len <= inend; + } + + inline TRefId ref() const { return ref_; } + inline TRefOff off() const { return off_; } + inline int orient() const { return orient_; } + inline TRefOff joinedOff() const { return joinedOff_; } + + inline void setRef(TRefId id) { ref_ = id; } + inline void setOff(TRefOff off) { off_ = off; } + inline void setJoinedOff(TRefOff joinedOff) { joinedOff_ = joinedOff; } + + inline void adjustOff(TRefOff off) { off_ += off; } + +protected: + + TRefId ref_; // which reference? + TRefOff off_; // 0-based offset into reference + int orient_; // true -> Watson strand + TRefOff joinedOff_; // offset in a joined ref. sequence +}; + +std::ostream& operator<<(std::ostream& out, const Coord& c); + +/** + * Encapsulates a reference interval, which consists of a Coord and a length. + */ +class Interval { + +public: + + Interval() { reset(); } + + explicit Interval(const Coord& upstream, TRefOff len) { + init(upstream, len); + } + + explicit Interval(TRefId rf, TRefOff of, bool fw, TRefOff len) { + init(rf, of, fw, len); + } + + void init(const Coord& upstream, TRefOff len) { + upstream_ = upstream; + len_ = len; + } + + void init(TRefId rf, TRefOff of, bool fw, TRefOff len) { + upstream_.init(rf, of, fw); + len_ = len; + } + + /** + * Set offset. + */ + void setOff(TRefOff of) { + upstream_.setOff(of); + } + + /** + * Set length. + */ + void setLen(TRefOff len) { + len_ = len; + } + + /** + * Reset this interval to uninitialized state. + */ + void reset() { + upstream_.reset(); + len_ = 0; + } + + /** + * Return true iff this Interval is initialized. + */ + bool inited() const { + if(upstream_.inited()) { + assert_gt(len_, 0); + return true; + } else { + return false; + } + } + + /** + * Return true iff this Interval is equal to the given Interval, + * i.e. if they cover the same set of positions. + */ + bool operator==(const Interval& o) const { + return upstream_ == o.upstream_ && + len_ == o.len_; + } + + /** + * Return true iff this Interval is less than the given Interval. + * One interval is less than another if its upstream location is + * prior to the other's or, if their upstream locations are equal, + * if its length is less than the other's. + */ + bool operator<(const Interval& o) const { + if(upstream_ < o.upstream_) return true; + if(upstream_ > o.upstream_) return false; + if(len_ < o.len_) return true; + return false; + } + + /** + * Return opposite result from operator<. + */ + bool operator>=(const Interval& o) const { + return !((*this) < o); + } + + /** + * Return true iff this Interval is greater than than the given + * Interval. One interval is greater than another if its upstream + * location is after the other's or, if their upstream locations + * are equal, if its length is greater than the other's. + */ + bool operator>(const Interval& o) const { + if(upstream_ > o.upstream_) return true; + if(upstream_ < o.upstream_) return false; + if(len_ > o.len_) return true; + return false; + } + + /** + * Return opposite result from operator>. + */ + bool operator<=(const Interval& o) const { + return !((*this) > o); + } + + /** + * Set upstream Coord. + */ + void setUpstream(const Coord& c) { + upstream_ = c; + } + + /** + * Set length. + */ + void setLength(TRefOff l) { + len_ = l; + } + + inline TRefId ref() const { return upstream_.ref(); } + inline TRefOff off() const { return upstream_.off(); } + inline TRefOff dnoff() const { return upstream_.off() + len_; } + inline int orient() const { return upstream_.orient(); } + + /** + * Return a Coord encoding the coordinate just past the downstream edge of + * the interval. + */ + inline Coord downstream() const { + return Coord( + upstream_.ref(), + upstream_.off() + len_, + upstream_.orient()); + } + + /** + * Return true iff the given Coord is inside this Interval. + */ + inline bool contains(const Coord& c) const { + return + c.ref() == ref() && + c.orient() == orient() && + c.off() >= off() && + c.off() < dnoff(); + } + + /** + * Return true iff the given Coord is inside this Interval, without + * requiring orientations to match. + */ + inline bool containsIgnoreOrient(const Coord& c) const { + return + c.ref() == ref() && + c.off() >= off() && + c.off() < dnoff(); + } + + /** + * Return true iff the given Interval is inside this Interval. + */ + inline bool contains(const Interval& c) const { + return + c.ref() == ref() && + c.orient() == orient() && + c.off() >= off() && + c.dnoff() <= dnoff(); + } + + /** + * Return true iff the given Interval is inside this Interval, without + * requiring orientations to match. + */ + inline bool containsIgnoreOrient(const Interval& c) const { + return + c.ref() == ref() && + c.off() >= off() && + c.dnoff() <= dnoff(); + } + + /** + * Return true iff the given Interval overlaps this Interval. + */ + inline bool overlaps(const Interval& c) const { + return + c.ref() == upstream_.ref() && + c.orient() == upstream_.orient() && + ((off() <= c.off() && dnoff() > c.off()) || + (off() <= c.dnoff() && dnoff() > c.dnoff()) || + (c.off() <= off() && c.dnoff() > off()) || + (c.off() <= dnoff() && c.dnoff() > dnoff())); + } + + /** + * Return true iff the given Interval overlaps this Interval, without + * requiring orientations to match. + */ + inline bool overlapsIgnoreOrient(const Interval& c) const { + return + c.ref() == upstream_.ref() && + ((off() <= c.off() && dnoff() > c.off()) || + (off() <= c.dnoff() && dnoff() > c.dnoff()) || + (c.off() <= off() && c.dnoff() > off()) || + (c.off() <= dnoff() && c.dnoff() > dnoff())); + } + + inline const Coord& upstream() const { return upstream_; } + inline TRefOff len() const { return len_; } + +#ifndef NDEBUG + /** + * Check that the Interval is internally consistent. + */ + bool repOk() const { + assert(upstream_.repOk()); + assert_geq(len_, 0); + return true; + } +#endif + + inline void adjustOff(TRefOff off) { upstream_.adjustOff(off); } + +protected: + + Coord upstream_; + TRefOff len_; +}; + +std::ostream& operator<<(std::ostream& out, const Interval& c); + +#endif /*ndef REF_COORD_H_*/ diff --git a/ref_read.cpp b/ref_read.cpp new file mode 100644 index 0000000..1ffd8fe --- /dev/null +++ b/ref_read.cpp @@ -0,0 +1,454 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "ref_read.h" + +/** + * Reads past the next ambiguous or unambiguous stretch of sequence + * from the given FASTA file and returns its length. Does not do + * anything with the sequence characters themselves; this is purely for + * measuring lengths. + */ +RefRecord fastaRefReadSize( + FileBuf& in, + const RefReadInParams& rparms, + bool first, + BitpairOutFileBuf* bpout, + string* name // put parsed FASTA name here + ) +{ + int c; + static int lastc = '>'; // last character seen + + // RefRecord params + TIndexOffU len = 0; // 'len' counts toward total length + // 'off' counts number of ambiguous characters before first + // unambiguous character + size_t off = 0; + + // Pick off the first carat and any preceding whitespace + if(first) { + assert(!in.eof()); + lastc = '>'; + c = in.getPastWhitespace(); + if(in.eof()) { + // Got eof right away; emit warning + cerr << "Warning: Empty input file" << endl; + lastc = -1; + return RefRecord(0, 0, true); + } + assert(c == '>'); + } + + first = true; + // Skip to the end of the id line; if the next line is either + // another id line or a comment line, keep skipping + if(lastc == '>') { +#if 0 + // Skip to the end of the name line + do { + if((c = in.getPastNewline()) == -1) { + // No more input + cerr << "Warning: Encountered empty reference sequence" << endl; + lastc = -1; + return RefRecord(0, 0, true); + } + if(c == '>') { + cerr << "Warning: Encountered empty reference sequence" << endl; + } + // continue until a non-name, non-comment line + } while (c == '>'); +#else + c = lastc; + // Skip to the end of the name line + do { + // get name + + while (true) { + c = in.get(); + if (c == -1) { + // No more input + cerr << "Warning: Encountered empty reference sequence" << endl; + lastc = -1; + return RefRecord(0, 0, true); + } + + if(c == '\n' || c == '\r') { + while(c == '\r' || c == '\n') c = in.get(); + if (c == -1) { + // No more input + cerr << "Warning: Encountered empty reference sequence" << endl; + lastc = -1; + return RefRecord(0, 0, true); + } + break; + } + + if (name) name->push_back(c); + } + + if (c == '>') { + cerr << "Warning: Encountered empty reference sequence" << endl; + // If there's another name line immediately after this one, + // discard the previous name and start fresh with the new one + if (name) name->clear(); + } + } while (c == '>'); +#endif + } else { + first = false; // not the first in a sequence + off = 1; // The gap has already been consumed, so count it + if((c = in.get()) == -1) { + // Don't emit a warning, since this might legitimately be + // a gap on the end of the final sequence in the file + lastc = -1; + return RefRecord((TIndexOffU)off, (TIndexOffU)len, first); + } + } + + // Now skip to the first DNA character, counting gap characters + // as we go + int lc = -1; // last-DNA char variable for color conversion + while(true) { + int cat = asc2dnacat[c]; + if(rparms.nsToAs && cat >= 2) c = 'A'; + if(cat == 1) { + // This is a DNA character + if(rparms.color) { + if(lc != -1) { + // Got two consecutive unambiguous DNAs + break; // to read-in loop + } + // Keep going; we need two consecutive unambiguous DNAs + lc = asc2dna[(int)c]; + // The 'if(off > 0)' takes care of the case where + // the reference is entirely unambiguous and we don't + // want to incorrectly increment off. + if(off > 0) off++; + } else { + break; // to read-in loop + } + } else if(cat >= 2) { + if(lc != -1 && off == 0) off++; + lc = -1; + off++; // skip over gap character and increment + } else if(c == '>') { + if(off > 0 && lastc == '>') { + cerr << "Warning: Encountered reference sequence with only gaps" << endl; + } else if(lastc == '>') { + cerr << "Warning: Encountered empty reference sequence" << endl; + } + lastc = '>'; + //return RefRecord(off, 0, false); + return RefRecord((TIndexOffU)off, 0, first); + } + c = in.get(); + if(c == -1) { + // End-of-file + if(off > 0 && lastc == '>') { + cerr << "Warning: Encountered reference sequence with only gaps" << endl; + } else if(lastc == '>') { + cerr << "Warning: Encountered empty reference sequence" << endl; + } + lastc = -1; + //return RefRecord(off, 0, false); + return RefRecord((TIndexOffU)off, 0, first); + } + } + assert(!rparms.color || (lc != -1)); + assert_eq(1, asc2dnacat[c]); // C must be unambiguous base + if(off > 0 && rparms.color && first) { + // Handle the case where the first record has ambiguous + // characters but we're in color space; one of those counts is + // spurious + off--; + } + + // in now points just past the first character of a sequence + // line, and c holds the first character + while(c != -1 && c != '>') { + if(rparms.nsToAs && asc2dnacat[c] >= 2) c = 'A'; + uint8_t cat = asc2dnacat[c]; + int cc = toupper(c); + if(rparms.bisulfite && cc == 'C') c = cc = 'T'; + if(cat == 1) { + // It's a DNA character + assert(cc == 'A' || cc == 'C' || cc == 'G' || cc == 'T'); + // Check for overflow + if((TIndexOffU)(len + 1) < len) { + throw RefTooLongException(); + } + // Consume it + len++; + // Output it + if(bpout != NULL) { + if(rparms.color) { + // output color + bpout->write(dinuc2color[asc2dna[(int)c]][lc]); + } else if(!rparms.color) { + // output nucleotide + bpout->write(asc2dna[c]); + } + } + lc = asc2dna[(int)c]; + } else if(cat >= 2) { + // It's an N or a gap + lastc = c; + assert(cc != 'A' && cc != 'C' && cc != 'G' && cc != 'T'); + return RefRecord((TIndexOffU)off, (TIndexOffU)len, first); + } else { + // Not DNA and not a gap, ignore it +#ifndef NDEBUG + if(!isspace(c)) { + cerr << "Unexpected character in sequence: "; + if(isprint(c)) { + cerr << ((char)c) << endl; + } else { + cerr << "(" << c << ")" << endl; + } + } +#endif + } + c = in.get(); + } + lastc = c; + return RefRecord((TIndexOffU)off, (TIndexOffU)len, first); +} + +#if 0 +static void +printRecords(ostream& os, const EList& l) { + for(size_t i = 0; i < l.size(); i++) { + os << l[i].first << ", " << l[i].off << ", " << l[i].len << endl; + } +} +#endif + +/** + * Reverse the 'src' list of RefRecords into the 'dst' list. Don't + * modify 'src'. + */ +void reverseRefRecords( + const EList& src, + EList& dst, + bool recursive, + bool verbose) +{ + dst.clear(); + { + EList cur; + for(int i = (int)src.size()-1; i >= 0; i--) { + bool first = (i == (int)src.size()-1 || src[i+1].first); + // Clause after the || on next line is to deal with empty FASTA + // records at the end of the 'src' list, which would be wrongly + // omitted otherwise. + if(src[i].len || (first && src[i].off == 0)) { + cur.push_back(RefRecord(0, src[i].len, first)); + first = false; + } + if(src[i].off) cur.push_back(RefRecord(src[i].off, 0, first)); + } + for(int i = 0; i < (int)cur.size(); i++) { + assert(cur[i].off == 0 || cur[i].len == 0); + if(i < (int)cur.size()-1 && cur[i].off != 0 && !cur[i+1].first) { + dst.push_back(RefRecord(cur[i].off, cur[i+1].len, cur[i].first)); + i++; + } else { + dst.push_back(cur[i]); + } + } + } + //if(verbose) { + // cout << "Source: " << endl; + // printRecords(cout, src); + // cout << "Dest: " << endl; + // printRecords(cout, dst); + //} +#ifndef NDEBUG + size_t srcnfirst = 0, dstnfirst = 0; + for(size_t i = 0; i < src.size(); i++) { + if(src[i].first) { + srcnfirst++; + } + } + for(size_t i = 0; i < dst.size(); i++) { + if(dst[i].first) { + dstnfirst++; + } + } + assert_eq(srcnfirst, dstnfirst); + if(!recursive) { + EList tmp; + reverseRefRecords(dst, tmp, true); + assert_eq(tmp.size(), src.size()); + for(size_t i = 0; i < src.size(); i++) { + assert_eq(src[i].len, tmp[i].len); + assert_eq(src[i].off, tmp[i].off); + assert_eq(src[i].first, tmp[i].first); + } + } +#endif +} + +/** + * Calculate a vector containing the sizes of all of the patterns in + * all of the given input files, in order. Returns the total size of + * all references combined. Rewinds each istream before returning. + */ +std::pair +fastaRefReadSizes( + EList& in, + EList& recs, + const RefReadInParams& rparms, + BitpairOutFileBuf* bpout, + TIndexOff& numSeqs) +{ + TIndexOffU unambigTot = 0; + size_t bothTot = 0; + assert_gt(in.size(), 0); + // For each input istream + for(size_t i = 0; i < in.size(); i++) { + bool first = true; + assert(!in[i]->eof()); + // For each pattern in this istream + while(!in[i]->eof()) { + RefRecord rec; + try { + rec = fastaRefReadSize(*in[i], rparms, first, bpout); + if((unambigTot + rec.len) < unambigTot) { + throw RefTooLongException(); + } + } + catch(RefTooLongException& e) { + cerr << e.what() << endl; + throw 1; + } + // Add the length of this record. + if(rec.first) numSeqs++; + unambigTot += rec.len; + bothTot += rec.len; + bothTot += rec.off; + first = false; + if(rec.len == 0 && rec.off == 0 && !rec.first) continue; + recs.push_back(rec); + } + // Reset the input stream + in[i]->reset(); + assert(!in[i]->eof()); +#ifndef NDEBUG + // Check that it's really reset + int c = in[i]->get(); + assert_eq('>', c); + in[i]->reset(); + assert(!in[i]->eof()); +#endif + } + + // Remove empty reference sequences + for(int64_t i = 0; (size_t)i < recs.size(); i++) { + const RefRecord& rec = recs[i]; + if(rec.first && rec.len == 0) { + if(i + 1 >= recs.size() || recs[i+1].first) { + bothTot -= rec.len; + bothTot -= rec.off; + recs.erase(i); + i -= 1; + } + } + } + + assert_geq(bothTot, 0); + assert_geq(unambigTot, 0); + return make_pair( + unambigTot, // total number of unambiguous DNA characters read + bothTot); // total number of DNA characters read, incl. ambiguous ones +} + + +std::pair +fastaRefReadFragsNames( + EList& in, + EList& recs, + const RefReadInParams& rparms, + BitpairOutFileBuf* bpout, + TIndexOff& numSeqs, + EList& names) +{ + TIndexOffU unambigTot = 0; + size_t bothTot = 0; + assert_gt(in.size(), 0); + // For each input istream + for(size_t i = 0; i < in.size(); i++) { + bool first = true; + assert(!in[i]->eof()); + // For each pattern in this istream + while(!in[i]->eof()) { + RefRecord rec; + string name; + try { + rec = fastaRefReadSize(*in[i], rparms, first, bpout, &name); + if((unambigTot + rec.len) < unambigTot) { + throw RefTooLongException(); + } + } + catch(RefTooLongException& e) { + cerr << e.what() << endl; + throw 1; + } + // Add the length of this record. + if(rec.first) numSeqs++; + if(rec.first) names.push_back(name); + unambigTot += rec.len; + bothTot += rec.len; + bothTot += rec.off; + first = false; + if(rec.len == 0 && rec.off == 0 && !rec.first) continue; + recs.push_back(rec); + } + // Reset the input stream + in[i]->reset(); + assert(!in[i]->eof()); +#ifndef NDEBUG + // Check that it's really reset + int c = in[i]->get(); + assert_eq('>', c); + in[i]->reset(); + assert(!in[i]->eof()); +#endif + } + + // Remove empty reference sequences + for(int64_t i = 0; (size_t)i < recs.size(); i++) { + const RefRecord& rec = recs[i]; + if(rec.first && rec.len == 0) { + if(i + 1 >= recs.size() || recs[i+1].first) { + bothTot -= rec.len; + bothTot -= rec.off; + recs.erase(i); + i -= 1; + } + } + } + + assert_geq(bothTot, 0); + assert_geq(unambigTot, 0); + return make_pair( + unambigTot, // total number of unambiguous DNA characters read + bothTot); // total number of DNA characters read, incl. ambiguous ones +} diff --git a/ref_read.h b/ref_read.h new file mode 100644 index 0000000..9791e4f --- /dev/null +++ b/ref_read.h @@ -0,0 +1,325 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef REF_READ_H_ +#define REF_READ_H_ + +#include +#include +#include +#include +#include +#include +#include "alphabet.h" +#include "assert_helpers.h" +#include "filebuf.h" +#include "word_io.h" +#include "ds.h" +#include "endian_swap.h" + +using namespace std; + +class RefTooLongException : public exception { + +public: + RefTooLongException() { +#ifdef BOWTIE_64BIT_INDEX + // This should never happen! + msg = "Error: Reference sequence has more than 2^64-1 characters! " + "Please divide the reference into smaller chunks and index each " + "independently."; +#else + msg = "Error: Reference sequence has more than 2^32-1 characters! " + "Please build a large index by passing the --large-index option " + "to bowtie2-build"; +#endif + } + + ~RefTooLongException() throw() {} + + const char* what() const throw() { + return msg.c_str(); + } + +protected: + + string msg; + +}; + +/** + * Encapsulates a stretch of the reference containing only unambiguous + * characters. From an ordered list of RefRecords, one can (almost) + * deduce the "shape" of the reference sequences (almost because we + * lose information about stretches of ambiguous characters at the end + * of reference sequences). + */ +struct RefRecord { + RefRecord() : off(), len(), first() { } + RefRecord(TIndexOffU _off, TIndexOffU _len, bool _first) : + off(_off), len(_len), first(_first) + { } + + RefRecord(FILE *in, bool swap) { + assert(in != NULL); + if(!fread(&off, OFF_SIZE, 1, in)) { + cerr << "Error reading RefRecord offset from FILE" << endl; + throw 1; + } + if(swap) off = endianSwapIndex(off); + if(!fread(&len, OFF_SIZE, 1, in)) { + cerr << "Error reading RefRecord offset from FILE" << endl; + throw 1; + } + if(swap) len = endianSwapIndex(len); + first = fgetc(in) ? true : false; + } + + void write(std::ostream& out, bool be) { + writeIndex(out, off, be); + writeIndex(out, len, be); + out.put(first ? 1 : 0); + } + + TIndexOffU off; /// Offset of the first character in the record + TIndexOffU len; /// Length of the record + bool first; /// Whether this record is the first for a reference sequence +}; + +enum { + REF_READ_FORWARD = 0, // don't reverse reference sequence + REF_READ_REVERSE, // reverse entire reference sequence + REF_READ_REVERSE_EACH, // reverse each unambiguous stretch of reference + REF_READ_REVERSE_REPLACEMENT, // reverse the entire reference sequence and replace specific base by others. +}; + +/** + * Parameters governing treatment of references as they're read in. + */ +struct RefReadInParams { + RefReadInParams(bool col, int r, bool nsToA, bool bisulf) : + color(col), reverse(r), nsToAs(nsToA), bisulfite(bisulf) { } + // extract colors from reference + bool color; + // reverse each reference sequence before passing it along + int reverse; + // convert ambiguous characters to As + bool nsToAs; + // bisulfite-convert the reference + bool bisulfite; +}; + +extern RefRecord +fastaRefReadSize( + FileBuf& in, + const RefReadInParams& rparms, + bool first, + BitpairOutFileBuf* bpout, + string *name = NULL); + +extern std::pair +fastaRefReadSizes( + EList& in, + EList& recs, + const RefReadInParams& rparms, + BitpairOutFileBuf* bpout, + TIndexOff& numSeqs); + +extern std::pair +fastaRefReadFragsNames( + EList& in, + EList& recs, + const RefReadInParams& rparms, + BitpairOutFileBuf* bpout, + TIndexOff& numSeqs, + EList& names); + +extern void +reverseRefRecords( + const EList& src, + EList& dst, + bool recursive = false, + bool verbose = false); + +/** + * Reads the next sequence from the given FASTA file and appends it to + * the end of dst, optionally reversing it. + */ +template +static RefRecord fastaRefReadAppend( + FileBuf& in, // input file + bool first, // true iff this is the first record in the file + TStr& dst, // destination buf for parsed characters + TIndexOffU& dstoff, // index of next character in dst to assign + RefReadInParams& rparms, // + string* name = NULL) // put parsed FASTA name here +{ + int c; + static int lastc = '>'; + if(first) { + c = in.getPastWhitespace(); + if(c != '>') { + cerr << "Reference file does not seem to be a FASTA file" << endl; + throw 1; + } + lastc = c; + } + assert_neq(-1, lastc); + + // RefRecord params + size_t len = 0; + size_t off = 0; + first = true; + + size_t ilen = dstoff; + + // Chew up the id line; if the next line is either + // another id line or a comment line, keep chewing + int lc = -1; // last-DNA char variable for color conversion + c = lastc; + if(c == '>' || c == '#') { + do { + while (c == '#') { + if((c = in.getPastNewline()) == -1) { + lastc = -1; + goto bail; + } + } + assert_eq('>', c); + while(true) { + c = in.get(); + if(c == -1) { + lastc = -1; + goto bail; + } + if(c == '\n' || c == '\r') { + while(c == '\r' || c == '\n') c = in.get(); + if(c == -1) { + lastc = -1; + goto bail; + } + break; + } + if (name) name->push_back(c); + } + // c holds the first character on the line after the name + // line + if(c == '>') { + // If there's another name line immediately after this one, + // discard the previous name and start fresh with the new one + if (name) name->clear(); + } + } while (c == '>' || c == '#'); + } else { + ASSERT_ONLY(int cc = toupper(c)); + assert(cc != 'A' && cc != 'C' && cc != 'G' && cc != 'T'); + first = false; + } + + // Skip over an initial stretch of gaps or ambiguous characters. + // For colorspace we skip until we see two consecutive unambiguous + // characters (i.e. the first unambiguous color). + while(true) { + int cat = asc2dnacat[c]; + if(rparms.nsToAs && cat >= 2) { + c = 'A'; + } + int cc = toupper(c); + if(rparms.bisulfite && cc == 'C') c = cc = 'T'; + if(cat == 1) { + // This is a DNA character + if(rparms.color) { + if(lc != -1) { + // Got two consecutive unambiguous DNAs + break; // to read-in loop + } + // Keep going; we need two consecutive unambiguous DNAs + lc = asc2dna[(int)c]; + // The 'if(off > 0)' takes care of the case where + // the reference is entirely unambiguous and we don't + // want to incorrectly increment off. + if(off > 0) off++; + } else { + break; // to read-in loop + } + } else if(cat >= 2) { + if(lc != -1 && off == 0) { + off++; + } + lc = -1; + off++; // skip it + } else if(c == '>') { + lastc = '>'; + goto bail; + } + c = in.get(); + if(c == -1) { + lastc = -1; + goto bail; + } + } + if(first && rparms.color && off > 0) { + // Handle the case where the first record has ambiguous + // characters but we're in color space; one of those counts is + // spurious + off--; + } + assert(!rparms.color || lc != -1); + assert_eq(1, asc2dnacat[c]); + + // in now points just past the first character of a sequence + // line, and c holds the first character + while(true) { + // Note: can't have a comment in the middle of a sequence, + // though a comment can end a sequence + int cat = asc2dnacat[c]; + assert_neq(2, cat); + if(cat == 1) { + // Consume it + if(!rparms.color || lc != -1) len++; + // Add it to reference buffer + if(rparms.color) { + dst.set((char)dinuc2color[asc2dna[(int)c]][lc], dstoff++); + } else if(!rparms.color) { + dst.set(asc2dna[c], dstoff++); + } + assert_lt((int)dst[dstoff-1], 4); + lc = asc2dna[(int)c]; + } + c = in.get(); + if(rparms.nsToAs && asc2dnacat[c] >= 2) c = 'A'; + if (c == -1 || c == '>' || c == '#' || asc2dnacat[c] >= 2) { + lastc = c; + break; + } + if(rparms.bisulfite && toupper(c) == 'C') c = 'T'; + } + + bail: + // Optionally reverse the portion that we just appended. + // ilen = length of buffer before this last sequence was appended. + if(rparms.reverse == REF_READ_REVERSE_EACH) { + // Find limits of the portion we just appended + size_t nlen = dstoff; + dst.reverseWindow(ilen, nlen); + } + return RefRecord((TIndexOffU)off, (TIndexOffU)len, first); +} + +#endif /*ndef REF_READ_H_*/ diff --git a/reference.cpp b/reference.cpp new file mode 100644 index 0000000..a897a4a --- /dev/null +++ b/reference.cpp @@ -0,0 +1,722 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include +#include "reference.h" +#include "mem_ids.h" + +using namespace std; + +/** + * Load from .3.gfm_ext/.4.gfm_ext HISAT2 index files. + */ +BitPairReference::BitPairReference( + const string& in, + const EList* included, + bool color, + bool sanity, + EList* infiles, + EList >* origs, + bool infilesSeq, + bool useMm, + bool useShmem, + bool mmSweep, + bool verbose, + bool startVerbose) : + buf_(NULL), + sanityBuf_(NULL), + loaded_(true), + sanity_(sanity), + useMm_(useMm), + useShmem_(useShmem), + verbose_(verbose) +{ + string s3 = in + ".3." + gfm_ext; + string s4 = in + ".4." + gfm_ext; + + FILE *f3, *f4; + if((f3 = fopen(s3.c_str(), "rb")) == NULL) { + cerr << "Could not open reference-string index file " << s3 << " for reading." << endl; + cerr << "This is most likely because your index was built with an older version" << endl + << "(<= 0.9.8.1) of bowtie-build. Please re-run bowtie-build to generate a new" << endl + << "index (or download one from the Bowtie website) and try again." << endl; + loaded_ = false; + return; + } + if((f4 = fopen(s4.c_str(), "rb")) == NULL) { + cerr << "Could not open reference-string index file " << s4 << " for reading." << endl; + loaded_ = false; + return; + } +#ifdef BOWTIE_MM + char *mmFile = NULL; + if(useMm_) { + if(verbose_ || startVerbose) { + cerr << " Memory-mapping reference index file " << s4.c_str() << ": "; + logTime(cerr); + } + struct stat sbuf; + if (stat(s4.c_str(), &sbuf) == -1) { + perror("stat"); + cerr << "Error: Could not stat index file " << s4.c_str() << " prior to memory-mapping" << endl; + throw 1; + } + mmFile = (char*)mmap((void *)0, (size_t)sbuf.st_size, + PROT_READ, MAP_SHARED, fileno(f4), 0); + if(mmFile == (void *)(-1) || mmFile == NULL) { + perror("mmap"); + cerr << "Error: Could not memory-map the index file " << s4.c_str() << endl; + throw 1; + } + if(mmSweep) { + TIndexOff sum = 0; + for(off_t i = 0; i < sbuf.st_size; i += 1024) { + sum += (TIndexOff) mmFile[i]; + } + if(startVerbose) { + cerr << " Swept the memory-mapped ref index file; checksum: " << sum << ": "; + logTime(cerr); + } + } + } +#endif + + // Read endianness sentinel, set 'swap' + uint32_t one; + bool swap = false; + one = readIndex(f3, swap); + if(one != 1) { + if(useMm_) { + cerr << "Error: Can't use memory-mapped files when the index is the opposite endianness" << endl; + throw 1; + } + assert_eq(0x1000000, one); + swap = true; // have to endian swap U32s + } + + // Read # records + TIndexOffU sz; + sz = readIndex(f3, swap); + if(sz == 0) { + cerr << "Error: number of reference records is 0 in " << s3.c_str() << endl; + throw 1; + } + + // Read records + nrefs_ = 0; + + // Cumulative count of all unambiguous characters on a per- + // stretch 8-bit alignment (i.e. count of bytes we need to + // allocate in buf_) + TIndexOffU cumsz = 0; + TIndexOffU cumlen = 0; + + EList seq_poss; + TIndexOffU seq_cumpos = 0; + TIndexOffU skips = 0; + // For each unambiguous stretch... + for(TIndexOffU i = 0; i < sz; i++) { + recs_.push_back(RefRecord(f3, swap)); + if(included != NULL && !(*included)[i]) { + seq_cumpos += recs_.back().len; + recs_.pop_back(); + skips++; + continue; + } + seq_poss.push_back(seq_cumpos); + if(recs_.back().first) { + // This is the first record for this reference sequence (and the + // last record for the one before) + refRecOffs_.push_back((TIndexOffU)recs_.size()-1); + // refOffs_ links each reference sequence with the total number of + // unambiguous characters preceding it in the pasted reference + refOffs_.push_back(cumsz); + if(nrefs_ > 0) { + // refLens_ links each reference sequence with the total number + // of ambiguous and unambiguous characters in it. + refLens_.push_back(cumlen); + } + cumlen = 0; + nrefs_++; + } else if(i == 0) { + cerr << "First record in reference index file was not marked as " + << "'first'" << endl; + throw 1; + } + cumUnambig_.push_back(cumsz); + cumRefOff_.push_back(cumlen); + cumsz += recs_.back().len; + cumlen += recs_.back().off; + cumlen += recs_.back().len; + seq_cumpos += recs_.back().len; + } + if(verbose_ || startVerbose) { + cerr << "Read " << nrefs_ << " reference strings from " + << sz << " records: "; + logTime(cerr); + } + // Store a cap entry for the end of the last reference seq + refRecOffs_.push_back((TIndexOffU)recs_.size()); + refOffs_.push_back(cumsz); + refLens_.push_back(cumlen); + cumUnambig_.push_back(cumsz); + cumRefOff_.push_back(cumlen); + bufSz_ = cumsz; + assert_eq(nrefs_, refLens_.size()); + assert_eq(sz, recs_.size() + skips); + if (f3 != NULL) fclose(f3); // done with .3.gfm_ext file + + // Round cumsz up to nearest byte boundary + if((cumsz & 3) != 0) { + cumsz += (4 - (cumsz & 3)); + } + bufAllocSz_ = cumsz >> 2; + assert_eq(0, cumsz & 3); // should be rounded up to nearest 4 + if(useMm_) { +#ifdef BOWTIE_MM + buf_ = (uint8_t*)mmFile; + if(sanity_) { + FILE *ftmp = fopen(s4.c_str(), "rb"); + sanityBuf_ = new uint8_t[cumsz >> 2]; + size_t ret = fread(sanityBuf_, 1, cumsz >> 2, ftmp); + if(ret != (cumsz >> 2)) { + cerr << "Only read " << ret << " bytes (out of " << (cumsz >> 2) << ") from reference index file " << s4.c_str() << endl; + throw 1; + } + fclose(ftmp); + for(size_t i = 0; i < (cumsz >> 2); i++) { + assert_eq(sanityBuf_[i], buf_[i]); + } + } +#else + cerr << "Shouldn't be at " << __FILE__ << ":" << __LINE__ << " without BOWTIE_MM defined" << endl; + throw 1; +#endif + } else { + bool shmemLeader = true; + if(!useShmem_) { + // Allocate a buffer to hold the reference string + try { + buf_ = new uint8_t[cumsz >> 2]; + if(buf_ == NULL) throw std::bad_alloc(); + } catch(std::bad_alloc& e) { + cerr << "Error: Ran out of memory allocating space for the bitpacked reference. Please" << endl + << "re-run on a computer with more memory." << endl; + throw 1; + } + } else { + shmemLeader = ALLOC_SHARED_U8( + (s4 + "[ref]"), (cumsz >> 2), &buf_, + "ref", (verbose_ || startVerbose)); + } + if(shmemLeader) { + // Open the bitpair-encoded reference file + FILE *f4 = fopen(s4.c_str(), "rb"); + if(f4 == NULL) { + cerr << "Could not open reference-string index file " << s4.c_str() << " for reading." << endl; + cerr << "This is most likely because your index was built with an older version" << endl + << "(<= 0.9.8.1) of bowtie-build. Please re-run bowtie-build to generate a new" << endl + << "index (or download one from the Bowtie website) and try again." << endl; + loaded_ = false; + return; + } + if(included == NULL) { + // Read the whole thing in + size_t ret = fread(buf_, 1, cumsz >> 2, f4); + // Didn't read all of it? + if(ret != (cumsz >> 2)) { + cerr << "Only read " << ret << " bytes (out of " << (cumsz >> 2) << ") from reference index file " << s4.c_str() << endl; + throw 1; + } + // Make sure there's no more + char c; + ret = fread(&c, 1, 1, f4); + assert_eq(0, ret); // should have failed + } else { + TIndexOffU buf_pos = 0; + uint8_t four_buf = 0, four_buf2 = 0; + for(size_t i = 0; i < seq_poss.size(); i++) { + TIndexOffU seq_pos = seq_poss[i]; + TIndexOffU cur_len = refLens_[i]; + TIndexOffU seq_pos2 = seq_pos + cur_len; + TIndexOffU left_pad = seq_pos & 3; + assert_eq((seq_pos - left_pad) & 3, 0); + TIndexOffU right_pad = 4 - (seq_pos2 & 3); + if(right_pad == 4) right_pad = 0; + assert_eq((seq_pos2 + right_pad) & 3, 0); + TIndexOffU cur_len2 = left_pad + cur_len + right_pad; + assert_eq(cur_len2 & 3, 0); + uint8_t *buf2_ = new uint8_t[cur_len2 >> 2]; + // Read sequences selectively + fseek(f4, (seq_pos - left_pad) >> 2, SEEK_SET); + size_t ret = fread(buf2_, 1, cur_len2 >> 2, f4); + // Didn't read all of it? + if(ret != (cur_len2 >> 2)) { + cerr << "Only read " << ret << " bytes (out of " << (cur_len2 >> 2) << ") from reference index file " << s4.c_str() << endl; + throw 1; + } + four_buf2 = buf2_[0] >> (left_pad << 1); + for(TIndexOffU j = seq_pos; j < seq_pos2; j++, buf_pos++) { + if((j & 3) == 0) { + four_buf2 = buf2_[(j - (seq_pos - left_pad)) >> 2]; + } + uint8_t nt = four_buf2 & 3; + four_buf2 >>= 2; + four_buf |= (nt << ((buf_pos & 3) << 1)); + if((buf_pos & 3) == 3) { + buf_[buf_pos >> 2] = four_buf; + four_buf = 0; + } + } + delete [] buf2_; + seq_pos += cur_len; + } +#ifndef NDEBUG + TIndexOffU cumsz2 = 0; + for(size_t i = 0; i < refLens_.size(); i++) { + cumsz2 += refLens_[i]; + } + assert_eq(buf_pos, cumsz2); +#endif + if((buf_pos & 3) != 0) { + buf_[buf_pos >> 2] = four_buf; + } + assert_eq(nrefs_, refLens_.size()); + } + fclose(f4); +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) NOTIFY_SHARED(buf_, (cumsz >> 2)); +#endif + } else { +#ifdef BOWTIE_SHARED_MEM + if(useShmem_) WAIT_SHARED(buf_, (cumsz >> 2)); +#endif + } + } + + // Populate byteToU32_ + bool big = currentlyBigEndian(); + for(int i = 0; i < 256; i++) { + uint32_t word = 0; + if(big) { + word |= ((i >> 0) & 3) << 24; + word |= ((i >> 2) & 3) << 16; + word |= ((i >> 4) & 3) << 8; + word |= ((i >> 6) & 3) << 0; + } else { + word |= ((i >> 0) & 3) << 0; + word |= ((i >> 2) & 3) << 8; + word |= ((i >> 4) & 3) << 16; + word |= ((i >> 6) & 3) << 24; + } + byteToU32_[i] = word; + } + +#ifndef NDEBUG + if(sanity_) { + // Compare the sequence we just read from the compact index + // file to the true reference sequence. + EList > *os; // for holding references + EList > osv(DEBUG_CAT); // for holding ref seqs + EList > osn(DEBUG_CAT); // for holding ref names + EList osvLen(DEBUG_CAT); // for holding ref seq lens + EList osnLen(DEBUG_CAT); // for holding ref name lens + SStringExpandable tmp_destU32_; + if(infiles != NULL) { + if(infilesSeq) { + for(size_t i = 0; i < infiles->size(); i++) { + // Remove initial backslash; that's almost + // certainly being used to protect the first + // character of the sequence from getopts (e.g., + // when the first char is -) + if((*infiles)[i].at(0) == '\\') { + (*infiles)[i].erase(0, 1); + } + osv.push_back(SString((*infiles)[i])); + } + } else { + parseFastas(*infiles, osn, osnLen, osv, osvLen); + } + os = &osv; + } else { + assert(origs != NULL); + os = origs; + } + + // Go through the loaded reference files base-by-base and + // sanity check against what we get by calling getBase and + // getStretch + for(size_t i = 0; i < os->size(); i++) { + size_t olen = ((*os)[i]).length(); + size_t olenU32 = (olen + 12) / 4; + uint32_t *buf = new uint32_t[olenU32]; + uint8_t *bufadj = (uint8_t*)buf; + bufadj += getStretch(buf, i, 0, olen, tmp_destU32_); + for(size_t j = 0; j < olen; j++) { + assert_eq((int)(*os)[i][j], (int)bufadj[j]); + assert_eq((int)(*os)[i][j], (int)getBase(i, j)); + } + delete[] buf; + } + } +#endif + + // generate minkRepeat + long long int genomeLen = approxLen(0); + minkRepeat = 0; + while(genomeLen > 0) { + genomeLen >>= 2; + minkRepeat++; + } +} + +BitPairReference::~BitPairReference() { + if(buf_ != NULL && !useMm_ && !useShmem_) delete[] buf_; + if(sanityBuf_ != NULL) delete[] sanityBuf_; +} + +/** + * Return a single base of the reference. Calling this repeatedly + * is not an efficient way to retrieve bases from the reference; + * use loadStretch() instead. + * + * This implementation scans linearly through the records for the + * unambiguous stretches of the target reference sequence. When + * there are many records, binary search would be more appropriate. + */ +int BitPairReference::getBase(size_t tidx, size_t toff) const { + uint64_t reci = refRecOffs_[tidx]; // first record for target reference sequence + uint64_t recf = refRecOffs_[tidx+1]; // last record (exclusive) for target seq + assert_gt(recf, reci); + uint64_t bufOff = refOffs_[tidx]; + uint64_t off = 0; + // For all records pertaining to the target reference sequence... + for(uint64_t i = reci; i < recf; i++) { + assert_geq(toff, off); + off += recs_[i].off; + if(toff < off) { + return 4; + } + assert_geq(toff, off); + uint64_t recOff = off + recs_[i].len; + if(toff < recOff) { + toff -= off; + bufOff += (uint64_t)toff; + assert_lt(bufOff, bufSz_); + const uint64_t bufElt = (bufOff) >> 2; + const uint64_t shift = (bufOff & 3) << 1; + return ((buf_[bufElt] >> shift) & 3); + } + bufOff += recs_[i].len; + off = recOff; + assert_geq(toff, off); + } // end for loop over records + return 4; +} + +/** + * Load a stretch of the reference string into memory at 'dest'. + * + * This implementation scans linearly through the records for the + * unambiguous stretches of the target reference sequence. When + * there are many records, binary search would be more appropriate. + */ +int BitPairReference::getStretchNaive( + uint32_t *destU32, + size_t tidx, + size_t toff, + size_t count) const +{ + uint8_t *dest = (uint8_t*)destU32; + uint64_t reci = refRecOffs_[tidx]; // first record for target reference sequence + uint64_t recf = refRecOffs_[tidx+1]; // last record (exclusive) for target seq + assert_gt(recf, reci); + uint64_t cur = 0; + uint64_t bufOff = refOffs_[tidx]; + uint64_t off = 0; + // For all records pertaining to the target reference sequence... + for(uint64_t i = reci; i < recf; i++) { + assert_geq(toff, off); + off += recs_[i].off; + for(; toff < off && count > 0; toff++) { + dest[cur++] = 4; + count--; + } + if(count == 0) break; + assert_geq(toff, off); + if(toff < off + recs_[i].len) { + bufOff += (TIndexOffU)(toff - off); // move bufOff pointer forward + } else { + bufOff += recs_[i].len; + } + off += recs_[i].len; + for(; toff < off && count > 0; toff++) { + assert_lt(bufOff, bufSz_); + const uint64_t bufElt = (bufOff) >> 2; + const uint64_t shift = (bufOff & 3) << 1; + dest[cur++] = (buf_[bufElt] >> shift) & 3; + bufOff++; + count--; + } + if(count == 0) break; + assert_geq(toff, off); + } // end for loop over records + // In any chars are left after scanning all the records, + // they must be ambiguous + while(count > 0) { + count--; + dest[cur++] = 4; + } + assert_eq(0, count); + return 0; +} + +/** + * Load a stretch of the reference string into memory at 'dest'. + */ +int BitPairReference::getStretch( + uint32_t *destU32, + size_t tidx, + size_t toff, + size_t count + ASSERT_ONLY(, SStringExpandable& destU32_2)) const +{ + ASSERT_ONLY(size_t origCount = count); + ASSERT_ONLY(size_t origToff = toff); + if(count == 0) return 0; + uint8_t *dest = (uint8_t*)destU32; +#ifndef NDEBUG + destU32_2.clear(); + uint8_t *dest_2 = NULL; + int off2; + if((rand() % 10) == 0) { + destU32_2.resize((origCount >> 2) + 2); + off2 = getStretchNaive(destU32_2.wbuf(), tidx, origToff, origCount); + dest_2 = ((uint8_t*)destU32_2.wbuf()) + off2; + } +#endif + destU32[0] = 0x04040404; // Add Ns, which we might end up using later + uint64_t reci = refRecOffs_[tidx]; // first record for target reference sequence + uint64_t recf = refRecOffs_[tidx+1]; // last record (exclusive) for target seq + assert_gt(recf, reci); + uint64_t cur = 4; // keep a cushion of 4 bases at the beginning + uint64_t bufOff = refOffs_[tidx]; + uint64_t off = 0; + int64_t offset = 4; + bool firstStretch = true; + bool binarySearched = false; + uint64_t left = reci; + uint64_t right = recf; + uint64_t mid = 0; + // For all records pertaining to the target reference sequence... + for(uint64_t i = reci; i < recf; i++) { + uint64_t origBufOff = bufOff; + assert_geq(toff, off); + if (firstStretch && recf > reci + 16){ + // binary search finds smallest i s.t. toff >= cumRefOff_[i] + while (left < right-1) { + mid = left + ((right - left) >> 1); + if (cumRefOff_[mid] <= toff) + left = mid; + else + right = mid; + } + off = cumRefOff_[left]; + bufOff = cumUnambig_[left]; + origBufOff = bufOff; + i = left; + assert(cumRefOff_[i+1] == 0 || cumRefOff_[i+1] > toff); + binarySearched = true; + } + off += recs_[i].off; // skip Ns at beginning of stretch + assert_gt(count, 0); + if(toff < off) { + size_t cpycnt = min((size_t)(off - toff), count); + memset(&dest[cur], 4, cpycnt); + count -= cpycnt; + toff += cpycnt; + cur += cpycnt; + if(count == 0) break; + } + assert_geq(toff, off); + if(toff < off + recs_[i].len) { + bufOff += toff - off; // move bufOff pointer forward + } else { + bufOff += recs_[i].len; + } + off += recs_[i].len; + assert(off == cumRefOff_[i+1] || cumRefOff_[i+1] == 0); + assert(!binarySearched || toff < off); + if(toff < off) { + if(firstStretch) { + if(toff + 8 < off && count > 8) { + // We already added some Ns, so we have to do + // a fixup at the beginning of the buffer so + // that we can start clobbering at cur >> 2 + if(cur & 3) { + offset -= (cur & 3); + } + uint64_t curU32 = cur >> 2; + // Do the initial few bases + if(bufOff & 3) { + const uint64_t bufElt = (bufOff) >> 2; + const int64_t low2 = bufOff & 3; + // Lots of cache misses on the following line + destU32[curU32] = byteToU32_[buf_[bufElt]]; + for(int j = 0; j < low2; j++) { + ((char *)(&destU32[curU32]))[j] = 4; + } + curU32++; + offset += low2; + const int64_t chars = 4 - low2; + count -= chars; + bufOff += chars; + toff += chars; + } + assert_eq(0, bufOff & 3); + uint64_t bufOffU32 = bufOff >> 2; + uint64_t countLim = count >> 2; + uint64_t offLim = ((off - (toff + 4)) >> 2); + uint64_t lim = min(countLim, offLim); + // Do the fast thing for as far as possible + for(uint64_t j = 0; j < lim; j++) { + // Lots of cache misses on the following line + destU32[curU32] = byteToU32_[buf_[bufOffU32++]]; +#ifndef NDEBUG + if(dest_2 != NULL) { + assert_eq(dest[(curU32 << 2) + 0], dest_2[(curU32 << 2) - offset + 0]); + assert_eq(dest[(curU32 << 2) + 1], dest_2[(curU32 << 2) - offset + 1]); + assert_eq(dest[(curU32 << 2) + 2], dest_2[(curU32 << 2) - offset + 2]); + assert_eq(dest[(curU32 << 2) + 3], dest_2[(curU32 << 2) - offset + 3]); + } +#endif + curU32++; + } + toff += (lim << 2); + assert_leq(toff, off); + assert_leq((lim << 2), count); + count -= (lim << 2); + bufOff = bufOffU32 << 2; + cur = curU32 << 2; + } + // Do the slow thing for the rest + for(; toff < off && count > 0; toff++) { + assert_lt(bufOff, bufSz_); + const uint64_t bufElt = (bufOff) >> 2; + const uint64_t shift = (bufOff & 3) << 1; + dest[cur++] = (buf_[bufElt] >> shift) & 3; + bufOff++; + count--; + } + firstStretch = false; + } else { + // Do the slow thing + for(; toff < off && count > 0; toff++) { + assert_lt(bufOff, bufSz_); + const uint64_t bufElt = (bufOff) >> 2; + const uint64_t shift = (bufOff & 3) << 1; + dest[cur++] = (buf_[bufElt] >> shift) & 3; + bufOff++; + count--; + } + } + } + if(count == 0) break; + assert_eq(recs_[i].len, bufOff - origBufOff); + assert_geq(toff, off); + } // end for loop over records + // In any chars are left after scanning all the records, + // they must be ambiguous + while(count > 0) { + count--; + dest[cur++] = 4; + } + assert_eq(0, count); + return (int)offset; +} + + +/** + * Parse the input fasta files, populating the szs list and writing the + * .3.gfm_ext and .4.gfm_ext portions of the index as we go. + */ +pair +BitPairReference::szsFromFasta( + EList& is, + const string& outfile, + bool bigEndian, + const RefReadInParams& refparams, + EList& szs, + bool sanity, + EList *names) +{ + RefReadInParams parms = refparams; + std::pair sztot; + if(!outfile.empty()) { + string file3 = outfile + ".3." + gfm_ext; + string file4 = outfile + ".4." + gfm_ext; + // Open output stream for the '.3.gfm_ext' file which will + // hold the size records. + ofstream fout3(file3.c_str(), ios::binary); + if(!fout3.good()) { + cerr << "Could not open index file for writing: \"" << file3.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + BitpairOutFileBuf bpout(file4.c_str()); + // Read in the sizes of all the unambiguous stretches of the genome + // into a vector of RefRecords. The input streams are reset once + // it's done. + writeIndex(fout3, 1, bigEndian); // endianness sentinel + TIndexOff numSeqs = 0; + sztot = fastaRefReadSizes(is, szs, parms, &bpout, numSeqs); + writeIndex(fout3, (TIndexOffU)szs.size(), bigEndian); // write # records + for(size_t i = 0; i < szs.size(); i++) szs[i].write(fout3, bigEndian); + if(sztot.first == 0) { + cerr << "Error: No unambiguous stretches of characters in the input. Aborting..." << endl; + throw 1; + } + assert_gt(sztot.first, 0); + assert_gt(sztot.second, 0); + bpout.close(); + fout3.close(); + } else { + // Read in the sizes of all the unambiguous stretches of the + // genome into a vector of RefRecords + TIndexOff numSeqs = 0; + //sztot = fastaRefReadSizes(is, szs, parms, NULL, numSeqs); + sztot = fastaRefReadFragsNames(is, szs, parms, NULL, numSeqs, *names); +#ifndef NDEBUG + if(parms.color) { + parms.color = false; + EList szs2(EBWTB_CAT); + TIndexOff numSeqs2 = 0; + ASSERT_ONLY(std::pair sztot2 =) + fastaRefReadSizes(is, szs2, parms, NULL, numSeqs2); + assert_eq(numSeqs, numSeqs2); + // One less color than base + assert_geq(sztot2.second, sztot.second + numSeqs); + parms.color = true; + } +#endif + } + return sztot; +} diff --git a/reference.h b/reference.h new file mode 100644 index 0000000..120ca07 --- /dev/null +++ b/reference.h @@ -0,0 +1,196 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef REFERENCE_H_ +#define REFERENCE_H_ + +#include +#include +#include +#include +#ifdef BOWTIE_MM +#include +#include +#endif +#include "endian_swap.h" +#include "ref_read.h" +#include "sequence_io.h" +#include "mm.h" +#include "shmem.h" +#include "timer.h" +#include "sstring.h" +#include "btypes.h" + + +/** + * Concrete reference representation that bulk-loads the reference from + * the bit-pair-compacted binary file and stores it in memory also in + * bit-pair-compacted format. The user may request reference + * characters either on a per-character bases or by "stretch" using + * getBase(...) and getStretch(...) respectively. + * + * Most of the complexity in this class is due to the fact that we want + * to represent references with ambiguous (non-A/C/G/T) characters but + * we don't want to use more than two bits per base. This means we + * need a way to encode the ambiguous stretches of the reference in a + * way that is external to the bitpair sequence. To accomplish this, + * we use the RefRecords vector, which is stored in the .3.ebwt index + * file. The bitpairs themselves are stored in the .4.ebwt index file. + * + * Once it has been loaded, a BitPairReference is read-only, and is + * safe for many threads to access at once. + */ +class BitPairReference { + +public: + /** + * Load from .3.ebwt/.4.ebwt Bowtie index files. + */ + BitPairReference( + const string& in, + const EList* included, + bool color, + bool sanity = false, + EList* infiles = NULL, + EList >* origs = NULL, + bool infilesSeq = false, + bool useMm = false, + bool useShmem = false, + bool mmSweep = false, + bool verbose = false, + bool startVerbose = false); + + ~BitPairReference(); + + /** + * Return a single base of the reference. Calling this repeatedly + * is not an efficient way to retrieve bases from the reference; + * use loadStretch() instead. + * + * This implementation scans linearly through the records for the + * unambiguous stretches of the target reference sequence. When + * there are many records, binary search would be more appropriate. + */ + int getBase(size_t tidx, size_t toff) const; + + /** + * Load a stretch of the reference string into memory at 'dest'. + * + * This implementation scans linearly through the records for the + * unambiguous stretches of the target reference sequence. When + * there are many records, binary search would be more appropriate. + */ + int getStretchNaive( + uint32_t *destU32, + size_t tidx, + size_t toff, + size_t count) const; + + /** + * Load a stretch of the reference string into memory at 'dest'. + * + * This implementation scans linearly through the records for the + * unambiguous stretches of the target reference sequence. When + * there are many records, binary search would be more appropriate. + */ + int getStretch( + uint32_t *destU32, + size_t tidx, + size_t toff, + size_t count + ASSERT_ONLY(, SStringExpandable& destU32_2)) const; + + /** + * Return the number of reference sequences. + */ + TIndexOffU numRefs() const { + return nrefs_; + } + + /** + * Return the approximate length of a reference sequence (it might leave + * off some Ns on the end). + * + * TODO: Is it still true that it might leave off Ns? + */ + TIndexOffU approxLen(TIndexOffU elt) const { + assert_lt(elt, nrefs_); + return refLens_[elt]; + } + + /** + * Return true iff buf_ and all the vectors are populated. + */ + bool loaded() const { + return loaded_; + } + + /** + * Given a reference sequence id, return its offset into the pasted + * reference string; i.e., return the number of unambiguous nucleotides + * preceding it. + */ + TIndexOffU pastedOffset(TIndexOffU idx) const { + return refOffs_[idx]; + } + + /** + * Parse the input fasta files, populating the szs list and writing the + * .3.ebwt and .4.ebwt portions of the index as we go. + */ + static std::pair + szsFromFasta( + EList& is, + const string& outfile, + bool bigEndian, + const RefReadInParams& refparams, + EList& szs, + bool sanity, + EList *names = NULL); + + size_t getMinK() const{ + return minkRepeat; + } + +protected: + + uint32_t byteToU32_[256]; + + EList recs_; /// records describing unambiguous stretches + // following two lists are purely for the binary search in getStretch + EList cumUnambig_; // # unambig ref chars up to each record + EList cumRefOff_; // # ref chars up to each record + EList refLens_; /// approx lens of ref seqs (excludes trailing ambig chars) + EList refOffs_; /// buf_ begin offsets per ref seq + EList refRecOffs_; /// record begin/end offsets per ref seq + uint8_t *buf_; /// the whole reference as a big bitpacked byte array + uint8_t *sanityBuf_;/// for sanity-checking buf_ + TIndexOffU bufSz_; /// size of buf_ + TIndexOffU bufAllocSz_; + TIndexOffU nrefs_; /// the number of reference sequences + bool loaded_; /// whether it's loaded + bool sanity_; /// do sanity checking + bool useMm_; /// load the reference as a memory-mapped file + bool useShmem_; /// load the reference into shared memory + bool verbose_; + size_t minkRepeat; // log4 of the size of repeat genome + ASSERT_ONLY(SStringExpandable tmp_destU32_); +}; + +#endif diff --git a/repeat.h b/repeat.h new file mode 100644 index 0000000..03be227 --- /dev/null +++ b/repeat.h @@ -0,0 +1,627 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef REPEAT_H_ +#define REPEAT_H_ + +#include +#include +#include +#include +#include "assert_helpers.h" +#include "word_io.h" +#include "mem_ids.h" +#include "ref_coord.h" +#include "alt.h" + +using namespace std; + +template +class RepeatCoord { +public: + bool operator< (const RepeatCoord& o) const { + if(joinedOff != o.joinedOff) + return joinedOff < o.joinedOff; + if(fw != o.fw) + return fw; + if(alleleID != o.alleleID) + return alleleID < o.alleleID; + return false; + } + +public: + RepeatCoord() {}; + RepeatCoord(index_t l_tid, index_t l_toff, index_t l_joinedOff, bool l_fw, index_t l_alleleID) : + tid(l_tid), toff(l_toff), joinedOff(l_joinedOff), fw(l_fw) {}; + index_t tid; + index_t toff; + index_t joinedOff; + bool fw; + index_t alleleID; +}; + +template +class RepeatAllele { +public: + RepeatAllele() { + reset(); + } + + void init(index_t allelePos_, + index_t alleleLen_) { + allelePos = allelePos_; + alleleLen = alleleLen_; + } + + void reset() { + allelePos = 0; + alleleLen = 0; + } + + bool operator< (const RepeatAllele& o) const { + if(allelePos != o.allelePos) + return allelePos < o.allelePos; + return alleleLen < o.alleleLen; + } + +#ifndef NDEBUG + bool repOk() const { + return true; + } +#endif + + bool write(ofstream& f_out, bool bigEndian) const { + writeU16(f_out, allelePos, bigEndian); + writeU16(f_out, alleleLen, bigEndian); + return true; + } + + bool read(ifstream& f_in, bool bigEndian) { + allelePos = readU16(f_in, bigEndian); + alleleLen = readU16(f_in, bigEndian); + return true; + } + + bool compatible(index_t left, index_t right) const { + if(left < allelePos || right > allelePos + alleleLen) + return false; + + return true; + } + +public: + uint16_t allelePos; + uint16_t alleleLen; +}; + +// sorting functions +template +struct sort_pair_loci { + bool operator()(const pair, index_t>& a, const pair, index_t>& b) { + return a.first.joinedOff < b.first.joinedOff; + } +}; + +template +struct sort_pair_loci_by_index { + bool operator()(const pair, index_t>& a, const pair, index_t>& b) { + return a.second < b.second; + } +}; + +template +class Repeat { +public: + void init(const string& repName_, + index_t repID_, + index_t repPos_, + index_t repLen_) { + repName = repName_; + repID = repID_; + repPos = repPos_; + repLen = repLen_; + } + + bool write(ofstream& f_out, bool bigEndian) const { + writeIndex(f_out, repID, bigEndian); + writeIndex(f_out, repPos, bigEndian); + writeIndex(f_out, repLen, bigEndian); + writeIndex(f_out, alleles.size(), bigEndian); + for(index_t i = 0; i < alleles.size(); i++) { + alleles[i].write(f_out, bigEndian); + } + writeIndex(f_out, positions.size(), bigEndian); + for(index_t i = 0; i < positions.size(); i++) { + writeIndex(f_out, positions[i].joinedOff, bigEndian); + writeU8(f_out, positions[i].fw); + writeIndex(f_out, positions[i].alleleID, bigEndian); + } + return true; + } + + bool read(ifstream& f_in, bool bigEndian) { + repID = readIndex(f_in, bigEndian); + repPos = readIndex(f_in, bigEndian); + repLen = readIndex(f_in, bigEndian); + index_t numAlleles = readIndex(f_in, bigEndian); + alleles.resizeExact(numAlleles); + for(index_t i = 0; i < numAlleles; i++) { + alleles[i].read(f_in, bigEndian); + } + index_t numPositions = readIndex(f_in, bigEndian); + positions.resizeExact(numPositions); + for(index_t i = 0; i < numPositions; i++) { + positions[i].tid = 0; + positions[i].toff = 0; + positions[i].joinedOff = readIndex(f_in, bigEndian); + positions[i].fw = readU8(f_in); + positions[i].alleleID = readIndex(f_in, bigEndian); + assert_lt(positions[i].alleleID, alleles.size()); + } + return true; + } + +public: + string repName; + index_t repID; + index_t repPos; + index_t repLen; + EList > alleles; + EList > positions; +}; + +template +class RepeatDB { +public: + RepeatDB() {} + + virtual ~RepeatDB() {} + + bool empty() const { return _repeats.size() == 0; } + + EList >& repeats() { return _repeats; } + const EList >& repeats() const { return _repeats; } + + const ELList >& repeatMap() const { return _repeatMap; } + + void write(ofstream& f_out, bool bigEndian) const { + if(_repeats.size() <= 0) { + writeIndex(f_out, 0, bigEndian); + return; + } + EList repeatGroup; + for(index_t i = 0; i < _repeats.size(); i++) { +#ifndef NDEBUG + if(i + 1 < _repeats.size()) { + assert_leq(_repeats[i].repID, _repeats[i+1].repID); + } +#endif + if(_repeats[i].repID > repeatGroup.size()) { + repeatGroup.push_back(i); + assert_eq(_repeats[i].repID, repeatGroup.size()); + } + } + repeatGroup.push_back(_repeats.size()); + assert_eq(_repeats.back().repID + 1, repeatGroup.size()); + writeIndex(f_out, repeatGroup.size(), bigEndian); + streampos filepos = f_out.tellp(); + EList repeatFilePos; + for(index_t i = 0; i < repeatGroup.size(); i++) { + writeIndex(f_out, 0, bigEndian); + } + + for(index_t i = 0; i < repeatGroup.size(); i++) { + index_t begin = (i == 0 ? 0 : repeatGroup[i-1]); + index_t end = repeatGroup[i]; + writeIndex(f_out, end - begin, bigEndian); + for(index_t j = begin; j < end; j++) { + _repeats[j].write(f_out, bigEndian); + } + repeatFilePos.push_back(f_out.tellp()); + } + assert_eq(repeatFilePos.size(), repeatGroup.size()); + + streampos origpos = f_out.tellp(); + f_out.seekp(filepos); + for(index_t i = 0; i < repeatFilePos.size(); i++) { + writeIndex(f_out, repeatFilePos[i], bigEndian); + } + f_out.seekp(origpos); + } + + void read(ifstream& f_in, bool bigEndian, const EList& includeRepeat) { + index_t numRepeatGroup = readIndex(f_in, bigEndian); + EList filePos; filePos.resizeExact(numRepeatGroup); + for(index_t i = 0; i < numRepeatGroup; i++) { + filePos[i] = readIndex(f_in, bigEndian); + } + assert_eq(numRepeatGroup, includeRepeat.size()); + for(index_t i = 0, repID = 0; i < numRepeatGroup; i++) { + if(!includeRepeat[i]) + continue; + if(i > 0) { + f_in.seekg(filePos[i-1]); + } + index_t numRepeats = readIndex(f_in, bigEndian); + index_t repeat_size = _repeats.size(); + _repeats.resizeExact(repeat_size + numRepeats); + for(index_t j = 0; j < numRepeats; j++) { + _repeats[repeat_size+j].read(f_in, bigEndian); + _repeats[repeat_size+j].repID = repID; + } + repID++; + } + f_in.seekg(filePos.back()); + } + + // Build an internal table to enable rapid search of repeats + // and converts joined offsets to chromosome IDs (tid) and loci (toff) + void construct(const index_t* rstarts, index_t rlen) { + _repeatMap.clear(); + if(_repeats.empty()) + return; + for(index_t r = 0; r < _repeats.size(); r++) { + if(_repeats[r].repID >= _repeatMap.size()) { + _repeatMap.expand(); + _repeatMap.back().clear(); + } + EList >& repeatMap = _repeatMap.back(); + repeatMap.expand(); + if(repeatMap.size() == 1) { + repeatMap.back().first = _repeats[r].repLen; + } else { + repeatMap.back().first = repeatMap[repeatMap.size() - 2].first + _repeats[r].repLen; + } + repeatMap.back().second = r; + } + + EList, index_t> > joinedOffList; + for(index_t r = 0; r < _repeats.size(); r++) { + Repeat& repeat = _repeats[r]; + EList >& positions = repeat.positions; + for(index_t p = 0; p < positions.size(); p++) { + joinedOffList.expand(); + joinedOffList.back().first.joinedOff = positions[p].joinedOff; + joinedOffList.back().first.tid = 0; + joinedOffList.back().first.toff = 0; + joinedOffList.back().first.fw = positions[p].fw; + joinedOffList.back().first.alleleID = positions[p].alleleID; + joinedOffList.back().second = joinedOffList.size() - 1; + } + } + + sort(joinedOffList.begin(), joinedOffList.end(), sort_pair_loci()); + + index_t j = 0, r = 0; + while(j < joinedOffList.size() && r < rlen) { + index_t off = joinedOffList[j].first.joinedOff; + index_t lower = rstarts[r*3]; + index_t upper; + if(r == rlen - 1) { + upper = numeric_limits::max(); + } else { + upper = rstarts[(r+1)*3]; + } + assert_gt(upper, lower); + if(off >= upper) { + r++; + continue; + } + assert_geq(off, lower); + joinedOffList[j].first.tid = rstarts[(r*3)+1]; + joinedOffList[j].first.toff = off - lower + rstarts[(r*3)+2]; + j++; + } + + sort(joinedOffList.begin(), joinedOffList.end(), sort_pair_loci_by_index()); + + index_t count = 0; + for(index_t r = 0; r < _repeats.size(); r++) { + Repeat& repeat = _repeats[r]; + EList >& positions = _repeats[r].positions; + for(index_t p = 0; p < positions.size(); p++) { + assert_lt(count, joinedOffList.size()); + assert_eq(positions[p].joinedOff, joinedOffList[count].first.joinedOff); + positions[p] = joinedOffList[count].first; + + RepeatAllele& allele = repeat.alleles[positions[p].alleleID]; + if(positions[p].fw) { + positions[p].joinedOff -= allele.allelePos; + positions[p].toff -= allele.allelePos; + } else { + assert_leq(allele.allelePos + allele.alleleLen, repeat.repLen); + index_t subLen = repeat.repLen - allele.allelePos - allele.alleleLen; + positions[p].joinedOff -= subLen; + positions[p].toff -= subLen; + } + + count++; + } + } + } + + bool repeatExist(index_t repID, index_t left, index_t right) const { + if(repID >= _repeatMap.size()) + return false; + + // Find a repeat corresponding to a given location (left, right) + const EList >& repeatMap = _repeatMap[repID]; + pair repeat(left, numeric_limits::max()); + index_t repeatIdx = repeatMap.bsearchLoBound(repeat); + assert_lt(repeatIdx, repeatMap.size()); + if(right > repeatMap[repeatIdx].first) + return false; + return true; + } + + bool getCoords(index_t repID, + index_t left, // left offset in the repeat sequence + index_t right, // right offset + const EList& snpIDs, // SNP IDs + const ALTDB& altdb, + EList, RepeatCoord > >& near_positions, + index_t max_positions = numeric_limits::max()) const { + near_positions.clear(); + + if(repID >= _repeatMap.size()) + return false; + + // Find a repeat corresponding to a given location (left, right) + const EList >& repeatMap = _repeatMap[repID]; + pair repeat(left, numeric_limits::max()); + index_t repeatIdx = repeatMap.bsearchLoBound(repeat); + assert_lt(repeatIdx, repeatMap.size()); + if(right > repeatMap[repeatIdx].first) + return false; + + index_t repeatIdx_ = repeatMap[repeatIdx].second; + assert_lt(repeatIdx_, _repeats.size()); + + const EList >& alleles = _repeats[repeatIdx_].alleles; + index_t adjLeft = left, adjRight = right; + if(repeatIdx > 0) { + adjLeft -= repeatMap[repeatIdx-1].first; + adjRight -= repeatMap[repeatIdx-1].first; + } + const EList >& positions = _repeats[repeatIdx_].positions; + for(index_t p = 0; p < positions.size(); p++) { + const RepeatCoord& position = positions[p]; + assert_lt(position.alleleID, alleles.size()); + const RepeatAllele& allele = alleles[position.alleleID]; + if(!allele.compatible(adjLeft, adjRight)) + continue; + + near_positions.expand(); + near_positions.back().first = position; + if(positions[p].fw) { + near_positions.back().first.joinedOff += adjLeft; + near_positions.back().first.toff += adjLeft; + } else { + const index_t len = right - left; + assert_leq(adjLeft + len, _repeats[repeatIdx_].repLen); + index_t rc_adjLeft = _repeats[repeatIdx_].repLen - adjLeft - len; + near_positions.back().first.joinedOff += rc_adjLeft; + near_positions.back().first.toff += rc_adjLeft; + } + + if(near_positions.size() >= max_positions) + break; + } + + return near_positions.size() > 0; + } + + bool findCoords(index_t anchor_left, + index_t anchor_right, + index_t repID, + index_t left, // left offset in the repeat sequence + index_t right, // right offset + const EList& snpIDs, // SNP IDs + const ALTDB& altdb, + EList, RepeatCoord > >& near_positions, + index_t max_positions = numeric_limits::max(), + index_t dist = 1000) const { + near_positions.clear(); + + if(repID >= _repeatMap.size()) + return false; + + // Find a repeat corresponding to a given location (left, right) + const EList >& repeatMap = _repeatMap[repID]; + pair repeat(left, numeric_limits::max()); + index_t repeatIdx = repeatMap.bsearchLoBound(repeat); + assert_lt(repeatIdx, repeatMap.size()); + if(right > repeatMap[repeatIdx].first) + return false; + + index_t repeatIdx_ = repeatMap[repeatIdx].second; + assert_lt(repeatIdx_, _repeats.size()); + + const EList >& alleles = _repeats[repeatIdx_].alleles; + index_t adjLeft = left, adjRight = right; + if(repeatIdx > 0) { + adjLeft -= repeatMap[repeatIdx-1].first; + adjRight -= repeatMap[repeatIdx-1].first; + } + const EList >& positions = _repeats[repeatIdx_].positions; + + RepeatCoord cmp; + cmp.joinedOff = (anchor_left >= dist ? anchor_left - dist : 0); + index_t p = positions.bsearchLoBound(cmp); + for(; p < positions.size(); p++) { + const RepeatCoord& position = positions[p]; + index_t pos = positions[p].joinedOff + adjLeft; + if(pos + dist < anchor_left) + continue; + if(anchor_right + dist < pos) + break; + + assert_lt(position.alleleID, alleles.size()); + const RepeatAllele& allele = alleles[position.alleleID]; + if(!allele.compatible(adjLeft, adjRight)) + continue; + + near_positions.expand(); + near_positions.back().first = position; + if(positions[p].fw) { + near_positions.back().first.joinedOff += adjLeft; + near_positions.back().first.toff += adjLeft; + } else { + const index_t len = right - left; + assert_leq(adjLeft + len, _repeats[repeatIdx_].repLen); + index_t rc_adjLeft = _repeats[repeatIdx_].repLen - adjLeft - len; + near_positions.back().first.joinedOff += rc_adjLeft; + near_positions.back().first.toff += rc_adjLeft; + } + + if(near_positions.size() >= max_positions) + break; + } + + return near_positions.size() > 0; + } + + bool findCommonCoords(index_t repID, + index_t left, // left offset in the repeat sequence + index_t right, // right offset + const EList& snpIDs, // SNP IDs + index_t repID2, + index_t left2, // left offset 2 in the repeat sequence + index_t right2, // right offset 2 + const EList& snpIDs2, // SNP IDs + const ALTDB& altdb, + EList, RepeatCoord > >& common_positions, + index_t max_positions = numeric_limits::max(), + index_t dist = 1000) const { + common_positions.clear(); + + if(repID >= _repeatMap.size() || repID2 >= _repeatMap.size()) + return false; + + // Find a repeat corresponding to a given location (left, right) + const EList >& repeatMap = _repeatMap[repID]; + assert_lt(left, right); + pair repeat(left, numeric_limits::max()); + index_t repeatIdx = repeatMap.bsearchLoBound(repeat); + assert_lt(repeatIdx, repeatMap.size()); + if(right > repeatMap[repeatIdx].first) + return false; + index_t repeatIdx_ = repeatMap[repeatIdx].second; + assert_lt(repeatIdx_, _repeats.size()); + const EList >& alleles = _repeats[repeatIdx_].alleles; + index_t adjLeft = left, adjRight = right; + if(repeatIdx > 0) { + adjLeft -= repeatMap[repeatIdx-1].first; + adjRight -= repeatMap[repeatIdx-1].first; + } + + // Find a repeat cooresponding to a given location (left2, right2) + const EList >& repeatMap2 = _repeatMap[repID2]; + assert_lt(left2, right2); + pair repeat2(left2, numeric_limits::max()); + index_t repeatIdx2 = repeatMap2.bsearchLoBound(repeat2); + assert_lt(repeatIdx2, repeatMap2.size()); + if(right2 > repeatMap2[repeatIdx2].first) + return false; + index_t repeatIdx2_ = repeatMap2[repeatIdx2].second; + assert_lt(repeatIdx2_, _repeats.size()); + const EList >& alleles2 = _repeats[repeatIdx2_].alleles; + index_t adjLeft2 = left2, adjRight2 = right2; + if(repeatIdx2 > 0) { + adjLeft2 -= repeatMap2[repeatIdx2-1].first; + adjRight2 -= repeatMap2[repeatIdx2-1].first; + } + + const EList >& positions = _repeats[repeatIdx_].positions; + const EList >& positions2 = _repeats[repeatIdx2_].positions; + index_t jsave = 0; + for(index_t i = 0; i < positions.size(); i++) { + const RepeatAllele& allele = alleles[positions[i].alleleID]; + if(!allele.compatible(adjLeft, adjRight)) + continue; + index_t i_pos = positions[i].joinedOff + adjLeft; + for(index_t j = jsave; j < positions2.size(); j++) { + index_t j_pos = positions2[j].joinedOff + adjLeft2; + if(j_pos + dist < i_pos) { + jsave = j + 1; + continue; + } + if(i_pos + dist < j_pos) + break; + + const RepeatAllele& allele2 = alleles2[positions2[j].alleleID]; + if(!allele2.compatible(adjLeft2, adjRight2)) + continue; + + common_positions.expand(); + common_positions.back().first = positions[i]; + if(positions[i].fw) { + common_positions.back().first.joinedOff += adjLeft; + common_positions.back().first.toff += adjLeft; + } else { + const index_t len = right - left; + assert_leq(adjLeft + len, _repeats[repeatIdx_].repLen); + index_t rc_adjLeft = _repeats[repeatIdx_].repLen - adjLeft - len; + common_positions.back().first.joinedOff += rc_adjLeft; + common_positions.back().first.toff += rc_adjLeft; + } + common_positions.back().second = positions2[j]; + if(positions2[j].fw) { + common_positions.back().second.toff += adjLeft2; + common_positions.back().second.joinedOff += adjLeft2; + } else { + const index_t len = right2 - left2; + assert_leq(adjLeft2 + len, _repeats[repeatIdx2_].repLen); + index_t rc_adjLeft2 = _repeats[repeatIdx2_].repLen - adjLeft2 - len; + common_positions.back().second.joinedOff += rc_adjLeft2; + common_positions.back().second.toff += rc_adjLeft2; + } + + if(common_positions.size() >= max_positions) + break; + } + + if(common_positions.size() >= max_positions) + break; + } + + return common_positions.size() > 0; + } + +private: + pair get_alt_range(const ALTDB& altdb, + index_t left, + index_t right) const { + pair alt_range; + ALT cmp_alt; + cmp_alt.pos = left; + alt_range.first = alt_range.second = (index_t)altdb.alts().bsearchLoBound(cmp_alt); + for(; alt_range.second < altdb.alts().size(); alt_range.second++) { + const ALT& alt = altdb.alts()[alt_range.second]; + if(alt.left > right) break; + } + return alt_range; + } + +private: + EList > _repeats; + ELList > _repeatMap; // pos to repeat id +}; + +#endif /*ifndef REPEAT_H_*/ diff --git a/repeat_builder.cpp b/repeat_builder.cpp new file mode 100644 index 0000000..7496766 --- /dev/null +++ b/repeat_builder.cpp @@ -0,0 +1,4771 @@ + +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#include +#include +#include +#include +#include "timer.h" +#include "aligner_sw.h" +#include "aligner_result.h" +#include "scoring.h" +#include "sstring.h" + +#include "repeat_builder.h" +#include "repeat_kmer.h" +#include "bit_packed_array.h" + +unsigned int levenshtein_distance(const std::string& s1, const std::string& s2) +{ + const std::size_t len1 = s1.size(), len2 = s2.size(); + std::vector col(len2+1), prevCol(len2+1); + + for (unsigned int i = 0; i < prevCol.size(); i++) + prevCol[i] = i; + for (unsigned int i = 0; i < len1; i++) { + col[0] = i+1; + for (unsigned int j = 0; j < len2; j++) + // note that std::min({arg1, arg2, arg3}) works only in C++11, + // for C++98 use std::min(std::min(arg1, arg2), arg3) + col[j+1] = std::min( std::min(prevCol[1 + j] + 1, col[j] + 1), prevCol[j] + (s1[i]==s2[j] ? 0 : 1) ); + col.swap(prevCol); + } + return prevCol[len2]; +} + + +unsigned int hamming_distance(const string& s1, const string& s2) +{ + assert_eq(s1.length(), s2.length()); + + uint32_t cnt = 0; + + for(size_t i = 0; i < s1.length(); i++) { + if(s1[i] != s2[i]) { + cnt++; + } + } + + return cnt; +} + +string reverse(const string& str) +{ + string rev = str; + size_t str_len = str.length(); + + for(size_t i = 0; i < str_len; i++) { + rev[i] = str[str_len - i - 1]; + } + + return rev; +} + +string reverse_complement(const string& str) +{ + string rev = str; + size_t str_len = str.length(); + + for(size_t i = 0; i < str_len; i++) { + char nt = str[str_len - i - 1]; + rev[i] = asc2dnacomp[nt]; + } + + return rev; +} + +template +TIndexOffU getLCP(const TStr& s, + CoordHelper& coordHelper, + TIndexOffU a, + TIndexOffU b, + TIndexOffU max_len = 1000) +{ + TIndexOffU a_end = coordHelper.getEnd(a); + TIndexOffU b_end = coordHelper.getEnd(b); + + assert_leq(a_end, s.length()); + assert_leq(b_end, s.length()); + + TIndexOffU k = 0; + while((a + k) < a_end && (b + k) < b_end && k < max_len) { + if(s[a + k] != s[b + k]) { + break; + } + k++; + } + + return k; +} + +template +bool isSameSequenceUpto(const TStr& s, + CoordHelper& coordHelper, + TIndexOffU a, + TIndexOffU b, + TIndexOffU upto) +{ + TIndexOffU a_end = coordHelper.getEnd(a); + TIndexOffU b_end = coordHelper.getEnd(b); + assert_leq(a_end, s.length()); + assert_leq(b_end, s.length()); + + if(a + upto > a_end || b + upto > b_end) + return false; + + for(int k = upto - 1; k >= 0; k--) { + if(s[a + k] != s[b + k]) { + return false; + } + } + + return true; +} + +bool isSenseDominant(CoordHelper& coordHelper, + const EList& positions, + size_t seed_len) +{ + // count the number of seeds on the sense strand + size_t sense_mer_count = 0; + for(size_t i = 0; i < positions.size(); i++) { + if(positions[i] < coordHelper.forward_length()) + sense_mer_count++; + } + + // there exists two sets of seeds that are essentially the same + // due to sense and antisense strands except palindromic sequences + // choose one and skip the other one + assert_leq(sense_mer_count, positions.size()); + size_t antisense_mer_count = positions.size() - sense_mer_count; + if(sense_mer_count < antisense_mer_count) { + return false; + } else if(sense_mer_count == antisense_mer_count) { + assert_geq(positions.back(), coordHelper.forward_length()); + TIndexOffU sense_pos = coordHelper.length() - positions.back() - seed_len; + if(positions[0] > sense_pos) return false; + } + + return true; +} + +static const Range EMPTY_RANGE = Range(1, 0); + +struct RepeatRange { + RepeatRange() { + forward = true; + }; + RepeatRange(Range r, int id) : + range(r), rg_id(id), forward(true) {}; + RepeatRange(Range r, int id, bool fw) : + range(r), rg_id(id), forward(fw) {}; + + Range range; + int rg_id; + bool forward; +}; + +Range reverseRange(const Range& r, TIndexOffU size) +{ + size_t len = r.second - r.first; + Range rc; + + rc.first = size - r.second; + rc.second = rc.first + len; + + return rc; +} + +string reverseComplement(const string& str) +{ + string rc; + for(TIndexOffU si = str.length(); si > 0; si--) { + rc.push_back(asc2dnacomp[str[si - 1]]); + } + return rc; +} + + +string toMDZ(const EList& edits, const string& read) +{ + StackedAln stk; + BTDnaString btread; + BTString buf; + + btread.install(read.c_str(), true); + + stk.init(btread, edits, 0, 0, 0, 0); + stk.buildMdz(); + stk.writeMdz(&buf, NULL); + + return string(buf.toZBuf()); +} + +string applyEdits(const string& ref, size_t read_len, const EList& edits, const Coord& coord) +{ + string read; + size_t ref_pos = coord.off(); + size_t read_pos = 0; + + for(size_t i = 0; i < edits.size(); i++) { + for(; read_pos < edits[i].pos; read_pos++, ref_pos++) { + read.push_back(ref[ref_pos]); + } + + if(edits[i].type == EDIT_TYPE_READ_GAP) { + // delete on read + ref_pos++; + } else if(edits[i].type == EDIT_TYPE_REF_GAP) { + // insert on read + read.push_back(edits[i].qchr); + read_pos++; + } else if(edits[i].type == EDIT_TYPE_MM) { + assert_eq(ref[ref_pos], edits[i].chr); + read.push_back(edits[i].qchr); + + read_pos++; + ref_pos++; + } else { + assert(false); + } + } + + for(; read_pos < read_len; read_pos++, ref_pos++) { + read.push_back(ref[ref_pos]); + } + + return read; +} + +template +static bool compareRepeatCoordByJoinedOff(const RepeatCoord& a, const RepeatCoord& b) +{ + return a.joinedOff < b.joinedOff; +} + + +template +string getString(const TStr& ref, TIndexOffU start, size_t len) +{ + ASSERT_ONLY(const size_t ref_len = ref.length()); + assert_leq(start + len, ref_len); + + string s; + for(size_t i = 0; i < len; i++) { + char nt = "ACGT"[ref[start + i]]; + s.push_back(nt); + } + + return s; +} + +template +void getString(const TStr& ref, TIndexOffU start, size_t len, string& s) +{ + s.clear(); + ASSERT_ONLY(const size_t ref_len = ref.length()); + assert_leq(start + len, ref_len); + for(size_t i = 0; i < len; i++) { + char nt = "ACGT"[ref[start + i]]; + s.push_back(nt); + } +} + + +template +inline uint8_t getSequenceBase(const TStr& ref, TIndexOffU pos) +{ + assert_lt(pos, ref.length()); + return (uint8_t)ref[pos]; +} + + +template +void dump_tstr(const TStr& s) +{ + static int print_width = 60; + + size_t s_len = s.length(); + + for(size_t i = 0; i < s_len; i += print_width) { + string buf; + for(size_t j = 0; (j < print_width) && (i + j < s_len); j++) { + buf.push_back("ACGTN"[s[i + j]]); + } + cerr << buf << endl; + } + cerr << endl; +} + + +size_t getMaxMatchLen(const EList& edits, const size_t read_len) +{ + size_t max_length = 0; + uint32_t last_edit_pos = 0; + uint32_t len = 0; + + if (edits.size() == 0) { + // no edits --> exact match + return read_len; + } + + for(size_t i = 0; i < edits.size(); i++) { + if (last_edit_pos > edits[i].pos) { + continue; + } + + len = edits[i].pos - last_edit_pos; + if(len > max_length) { + max_length = len; + } + + last_edit_pos = edits[i].pos + 1; + } + + if (last_edit_pos < read_len) { + len = read_len - last_edit_pos; + if(len > max_length) { + max_length = len; + } + } + + return max_length; +} + +int max_index(size_t array[4]) +{ + int max_idx = 0; + + for(size_t i = 1; i < 4; i++) { + if(array[max_idx] < array[i]) { + max_idx = i; + } + } + + return max_idx; +} + +CoordHelper::CoordHelper(TIndexOffU length, + TIndexOffU forward_length, + const EList& szs, + const EList& ref_names) : +length_(length), +forward_length_(forward_length), +szs_(szs), +ref_namelines_(ref_names) +{ + // build ref_names_ from ref_namelines_ + buildNames(); + buildJoinedFragment(); +} + +CoordHelper::~CoordHelper() +{ +} + +void CoordHelper::buildNames() +{ + ref_names_.resize(ref_namelines_.size()); + for(size_t i = 0; i < ref_namelines_.size(); i++) { + string& nameline = ref_namelines_[i]; + + for(size_t j = 0; j < nameline.length(); j++) { + char n = nameline[j]; + if(n == ' ') { + break; + } + ref_names_[i].push_back(n); + } + } +} + +int CoordHelper::mapJoinedOffToSeq(TIndexOffU joinedOff) +{ + /* search from cached_list */ + if(num_cached_ > 0) { + for(size_t i = 0; i < num_cached_; i++) { + Fragments *frag = &cached_[i]; + if(frag->contain(joinedOff)) { + return frag->frag_id; + } + } + /* fall through */ + } + + /* search list */ + int top = 0; + int bot = fraglist_.size() - 1; + int pos = 0; + + Fragments *frag = &fraglist_[pos]; + while((bot - top) > 1) { + pos = top + ((bot - top) >> 1); + frag = &fraglist_[pos]; + + if (joinedOff < frag->joinedOff) { + bot = pos; + } else { + top = pos; + } + } + + frag = &fraglist_[top]; + if (frag->contain(joinedOff)) { + // update cache + if (num_cached_ < CACHE_SIZE_JOINEDFRG) { + cached_[num_cached_] = *frag; + num_cached_++; + } else { + cached_[victim_] = *frag; + victim_++; // round-robin + victim_ %= CACHE_SIZE_JOINEDFRG; + } + + return top; + } + + return -1; +} + +int CoordHelper::getGenomeCoord(TIndexOffU joinedOff, + string& chr_name, + TIndexOffU& pos_in_chr) +{ + int seq_id = mapJoinedOffToSeq(joinedOff); + if (seq_id < 0) { + return -1; + } + + Fragments *frag = &fraglist_[seq_id]; + TIndexOffU offset = joinedOff - frag->joinedOff; + + pos_in_chr = frag->seqOff + offset; + chr_name = ref_names_[frag->seq_id]; + + return 0; +} + +void CoordHelper::buildJoinedFragment() +{ + TIndexOffU acc_joinedOff = 0; + TIndexOffU acc_seqOff = 0; + TIndexOffU seq_id = 0; + TIndexOffU frag_id = 0; + for(size_t i = 0; i < szs_.size(); i++) { + const RefRecord& rec = szs_[i]; + if(rec.len == 0) { + continue; + } + if (rec.first) { + acc_seqOff = 0; + seq_id++; + } + + fraglist_.expand(); + + fraglist_.back().joinedOff = acc_joinedOff; + fraglist_.back().length = rec.len; + + fraglist_.back().frag_id = frag_id++; + fraglist_.back().seq_id = seq_id - 1; + fraglist_.back().first = rec.first; + + acc_seqOff += rec.off; + fraglist_.back().seqOff = acc_seqOff; + + acc_joinedOff += rec.len; + acc_seqOff += rec.len; + } + + // Add Last Fragment(empty) + fraglist_.expand(); + fraglist_.back().joinedOff = acc_joinedOff; + fraglist_.back().length = 0; + fraglist_.back().seqOff = acc_seqOff; + fraglist_.back().first = false; + fraglist_.back().frag_id = frag_id; + fraglist_.back().seq_id = seq_id; +} + +TIndexOffU CoordHelper::getEnd(TIndexOffU e) { + assert_lt(e, length_) + + TIndexOffU end = 0; + if(e < forward_length_) { + int frag_id = mapJoinedOffToSeq(e); + assert_geq(frag_id, 0); + end = fraglist_[frag_id].joinedOff + fraglist_[frag_id].length; + } else { + // ReverseComplement + // a, b are positions w.r.t reverse complement string. + // fragment map is based on forward string + int frag_id = mapJoinedOffToSeq(length_ - e - 1); + assert_geq(frag_id, 0); + end = length_ - fraglist_[frag_id].joinedOff; + } + + assert_leq(end, length_); + return end; +} + +TIndexOffU CoordHelper::getStart(TIndexOffU e) { + assert_lt(e, length_) + + TIndexOffU start = 0; + if(e < forward_length_) { + int frag_id = mapJoinedOffToSeq(e); + assert_geq(frag_id, 0); + start = fraglist_[frag_id].joinedOff; + } else { + // ReverseComplement + // a, b are positions w.r.t reverse complement string. + // fragment map is based on forward string + int frag_id = mapJoinedOffToSeq(length_ - e - 1); + assert_geq(frag_id, 0); + start = length_ - (fraglist_[frag_id].joinedOff + fraglist_[frag_id].length); + } + + assert_leq(start, length_); + return start; +} + +template +void SeedExt::getExtendedSeedSequence(const TStr& s, + string& seq) const +{ + seq.clear(); + TIndexOffU prev_end = orig_pos.first; + for(size_t j = 0; j < left_gaps.size(); j++) { + TIndexOffU curr_end = orig_pos.first - left_gaps[j].first; + assert_leq(curr_end, prev_end); + if(curr_end < prev_end) { + seq = getString(s, curr_end, prev_end - curr_end) + seq; + } + int gap_len = left_gaps[j].second; + assert_neq(gap_len, 0); + if(gap_len > 0) { // deletion + string gap_str(gap_len, '-'); + seq = gap_str + seq; + } else { + curr_end += gap_len; + } + prev_end = curr_end; + } + assert_leq(pos.first, prev_end); + if(pos.first < prev_end) { + seq = getString(s, pos.first, prev_end - pos.first) + seq; + } + if(orig_pos.second - orig_pos.first > 0) + seq += getString(s, orig_pos.first, orig_pos.second - orig_pos.first); + TIndexOffU prev_begin = orig_pos.second; + for(size_t j = 0; j < right_gaps.size(); j++) { + TIndexOffU curr_begin = orig_pos.second + right_gaps[j].first; + assert_leq(prev_begin, curr_begin); + if(prev_begin < curr_begin) { + seq += getString(s, prev_begin, curr_begin - prev_begin); + } + int gap_len = right_gaps[j].second; + assert_neq(gap_len, 0); + if(gap_len > 0) { // deletion + string gap_str(gap_len, '-'); + seq += gap_str; + } else { + curr_begin -= gap_len; + } + prev_begin = curr_begin; + } + assert_leq(prev_begin, pos.second); + if(prev_begin < pos.second) { + seq += getString(s, prev_begin, pos.second - prev_begin); + } +} + +SeedSNP *lookup_add_SNP(EList& repeat_snps, SeedSNP& snp) +{ + for(size_t i = 0; i < repeat_snps.size(); i++) { + if(*repeat_snps[i] == snp) { + return repeat_snps[i]; + } + } + + repeat_snps.expand(); + repeat_snps.back() = new SeedSNP(); + *(repeat_snps.back()) = snp; + return repeat_snps.back(); +} + +template +void SeedExt::generateSNPs(const TStr &s, const string& consensus, EList& repeat_snps) +{ + EList > gaps; + + // Merge Gaps + { + TIndexOffU left_ext_len = getLeftExtLength(); + for(size_t g = 0; g < left_gaps.size(); g++) { + gaps.expand(); + gaps.back().first = left_ext_len - left_gaps[g].first + left_gaps[g].second; + gaps.back().second = left_gaps[g].second; + } + TIndexOffU right_base = orig_pos.second - pos.first; + for(size_t g = 0; g < right_gaps.size(); g++) { + gaps.expand(); + gaps.back().first = right_base + right_gaps[g].first; + gaps.back().second = right_gaps[g].second; + } + gaps.sort(); + } + + // + string con_ref; + string seq_read; + TIndexOffU prev_con_pos = consensus_pos.first; + TIndexOffU prev_seq_pos = pos.first; + + for(size_t g = 0; g < gaps.size(); g++) { + TIndexOffU curr_seq_pos = pos.first + gaps[g].first; + TIndexOffU curr_con_pos = prev_con_pos + (curr_seq_pos - prev_seq_pos); + + con_ref = consensus.substr(prev_con_pos, curr_con_pos - prev_con_pos); + seq_read = getString(s, prev_seq_pos, curr_seq_pos - prev_seq_pos); + for(size_t l = 0; l < con_ref.length(); l++) { + if(seq_read[l] != con_ref[l]) { + // Single + SeedSNP snp; + snp.init(EDIT_TYPE_MM, prev_con_pos + l, 1, seq_read[l]); + + // lookup repeat_snp + snps.expand(); + snps.back() = lookup_add_SNP(repeat_snps, snp); + } + } + + int gap_len = gaps[g].second; + assert_neq(gap_len, 0); + if(gap_len > 0) { + // Deletion (gap on read) + + string gap_str(gap_len, '-'); + + SeedSNP snp; + snp.init(EDIT_TYPE_READ_GAP, curr_con_pos, gap_len, consensus.substr(curr_con_pos, gap_len)); + + snps.expand(); + snps.back() = lookup_add_SNP(repeat_snps, snp); + + curr_con_pos += gap_len; + + } else { + // Insertion (gap on reference) + string gap_str(abs(gap_len), '-'); + + SeedSNP snp; + snp.init(EDIT_TYPE_REF_GAP, curr_con_pos, abs(gap_len), getString(s, curr_seq_pos, abs(gap_len))); + + snps.expand(); + snps.back() = lookup_add_SNP(repeat_snps, snp); + + curr_seq_pos += abs(gap_len); + } + + prev_con_pos = curr_con_pos; + prev_seq_pos = curr_seq_pos; + } + + assert_eq(consensus_pos.second - prev_con_pos, pos.second - prev_seq_pos); + con_ref = consensus.substr(prev_con_pos, consensus_pos.second - prev_con_pos); + seq_read = getString(s, prev_seq_pos, pos.second - prev_seq_pos); + + for(size_t l = 0; l < con_ref.length(); l++) { + if(seq_read[l] != con_ref[l]) { + // Single + + SeedSNP snp; + snp.init(EDIT_TYPE_MM, prev_con_pos + l, 1, seq_read[l]); + + snps.expand(); + snps.back() = lookup_add_SNP(repeat_snps, snp); + } + } +} + +bool seedCmp(const SeedExt& s, const SeedExt& s2) +{ + if(s.getLength() != s2.getLength()) + return s.getLength() > s2.getLength(); + if(s.pos.first != s2.pos.first) + return s.pos.first < s2.pos.first; + if(s.pos.second != s2.pos.second) + return s.pos.second < s2.pos.second; + return false; +} + +template +void RB_Repeat::init(const RepeatParameter& rp, + const TStr& s, + CoordHelper& coordHelper, + const RB_SubSA& subSA, + const RB_RepeatBase& repeatBase) +{ + consensus_ = repeatBase.seq; + assert_geq(consensus_.length(), rp.min_repeat_len); + assert_eq(consensus_.length(), rp.min_repeat_len + repeatBase.nodes.size() - 1); + + EList positions, next_positions; + + const EList& repeat_index = subSA.getRepeatIndex(); + seeds_.clear(); + for(size_t n = 0; n < repeatBase.nodes.size(); n++) { + TIndexOffU idx = repeatBase.nodes[n]; + TIndexOffU saBegin = repeat_index[idx]; + TIndexOffU saEnd = (idx + 1 < repeat_index.size() ? repeat_index[idx+1] : subSA.size()); + + next_positions.clear(); + for(size_t sa = saBegin; sa < saEnd; sa++) { + TIndexOffU left = subSA.get(sa); + TIndexOffU right = left + subSA.seed_len(); + next_positions.push_back(left); + + if(left > 0) { + size_t idx = positions.bsearchLoBound(left - 1); + if(idx < positions.size() && positions[idx] == left - 1) + continue; + } + + seeds_.expand(); + SeedExt& seed = seeds_.back(); + seed.reset(); + seed.orig_pos = pair(left, right); + seed.pos = seed.orig_pos; + seed.consensus_pos.first = n; + seed.consensus_pos.second = n + rp.min_repeat_len; + seed.bound = pair(coordHelper.getStart(left), coordHelper.getEnd(left)); + +#ifndef NDEBUG + string tmp_str = getString(s, seed.pos.first, seed.pos.second - seed.pos.first); + assert_eq(tmp_str, consensus_.substr(n, seed.pos.second - seed.pos.first)); +#endif + + for(size_t p = seed.consensus_pos.second; p < consensus_.length(); p++) { + size_t pos = seed.pos.second; + if(pos >= seed.bound.second) + break; + int nt = getSequenceBase(s, pos); + if("ACGT"[nt] != consensus_[p]) + break; + seed.pos.second++; + seed.consensus_pos.second++; + } + } + positions = next_positions; + } + + internal_update(); +} + +template +void RB_Repeat::extendConsensus(const RepeatParameter& rp, + const TStr& s) +{ + size_t remain = seeds_.size(); + EList left_consensuses, right_consensuses, empty_consensuses; + EList ed_seed_nums; + + const TIndexOffU default_max_ext_len = (rp.max_repeat_len - rp.seed_len) / 2; + const TIndexOffU seed_mm = 1; + string left_ext_consensus = "", right_ext_consensus = ""; + + empty_consensuses.resize(seed_mm + 1); + empty_consensuses.fill(""); + + while(remain >= rp.repeat_count) { + for(size_t i = 0; i < remain; i++) { + seeds_[i].done = false; + seeds_[i].curr_ext_len = 0; + } + + // extend seeds in left or right direction + TIndexOffU max_ext_len = min(default_max_ext_len, (TIndexOffU)(rp.max_repeat_len - consensus_.length())); + get_consensus_seq(s, + seeds_, + 0, // seed begin + remain, // seed end + max_ext_len, + max_ext_len, + seed_mm, + rp, + ed_seed_nums, + &left_consensuses, + &right_consensuses); + + size_t allowed_seed_mm = 0; + left_ext_consensus.clear(); + right_ext_consensus.clear(); + for(int i = 0 /* (int)seed_mm */; i >= 0; i--) { + size_t extlen = (ed_seed_nums[i] < rp.repeat_count ? 0 : (left_consensuses[i].length() + right_consensuses[i].length())); + // if(extlen <= 0 || extlen < max_ext_len * i / seed_mm) + //if(extlen < max_ext_len * 2) + // continue; + if(extlen <= 0) + continue; + + left_ext_consensus = left_consensuses[i]; + right_ext_consensus = right_consensuses[i]; + allowed_seed_mm = (size_t)i; + assert_gt(left_ext_consensus.length(), 0); + assert_gt(right_ext_consensus.length(), 0); + break; + } + size_t num_passed_seeds = 0; + if(left_ext_consensus.length() > 0 && right_ext_consensus.length()) { + consensus_ = reverse(left_ext_consensus) + consensus_; + consensus_ += right_ext_consensus; + +#if 0 + calc_edit_dist(s, + seeds_, + 0, + remain, + left ? consensuses : empty_consensuses, + left ? empty_consensuses : consensuses, + allowed_seed_mm); +#endif + + // update seeds + for(size_t i = 0; i < seeds_.size(); i++) { + SeedExt& seed = seeds_[i]; + + if(i < remain) { + if(seed.ed <= allowed_seed_mm) { + num_passed_seeds++; + seed.done = true; + seed.total_ed += seed.ed; + seed.pos.first -= left_ext_consensus.length(); + seed.pos.second += right_ext_consensus.length(); + seed.consensus_pos.first = 0; + seed.consensus_pos.second = consensus_.length(); + + if(seed.left_gaps.size() > 0 && + seed.left_gaps.back().first >= seed.orig_pos.first - seed.pos.first) { + int gap_len = seed.left_gaps.back().second; + seed.pos.first += gap_len; + } + if(seed.right_gaps.size() > 0 && + seed.right_gaps.back().first >= seed.pos.second - seed.orig_pos.second) { + int gap_len = seed.right_gaps.back().second; + seed.pos.second -= gap_len; + } + } + } + } + + // move up "done" seeds + size_t j = 0; + for(size_t i = 0; i < remain; i++) { + if(!seeds_[i].done) continue; + assert_geq(i, j); + if(i > j) { + SeedExt temp = seeds_[j]; + seeds_[j] = seeds_[i]; + seeds_[i] = temp; + // Find next "undone" seed + j++; + while(j < i && seeds_[j].done) { + j++; + } + assert(j < remain && !seeds_[j].done); + } else { + j = i + 1; + } + } + } + + remain = num_passed_seeds; + break; + } // while(remain >= rp.repeat_count) + +#ifndef NDEBUG + // make sure seed positions are unique + EList > seed_poses; + for(size_t i = 0; i < seeds_.size(); i++) { + seed_poses.expand(); + seed_poses.back() = seeds_[i].orig_pos; + } + seed_poses.sort(); + for(size_t i = 0; i + 1 < seed_poses.size(); i++) { + if(seed_poses[i].first == seed_poses[i+1].first) { + assert_lt(seed_poses[i].second, seed_poses[i+1].second); + } else { + assert_lt(seed_poses[i].first, seed_poses[i+1].first); + } + } + + for(size_t i = 0; i < seeds_.size(); i++) { + assert(seeds_[i].valid()); + } +#endif + + RB_Repeat::internal_update(); + + // check repeats within a repeat sequence + self_repeat_ = false; + for(size_t i = 0; i + 1 < seed_ranges_.size(); i++) { + const RB_AlleleCoord& range = seed_ranges_[i]; + for(size_t j = i + 1; j < seed_ranges_.size(); j++) { + RB_AlleleCoord& range2 = seed_ranges_[j]; + if(range.right <= range2.left) + break; + self_repeat_ = true; + } + } +} + +template +void RB_Repeat::getNextRepeat(const RepeatParameter& rp, + const TStr& s, + RB_Repeat& o) +{ + o.reset(); + + size_t i = 0; + for(i = 0; i < seeds_.size() && seeds_[i].done; i++); + if(i >= seeds_.size()) + return; + + for(size_t j = i; j < seeds_.size(); j++) { + assert(!seeds_[j].done); + o.seeds_.expand(); + o.seeds_.back() = seeds_[j]; + + } + seeds_.resizeExact(i); + internal_update(); + + assert_gt(o.seeds_.size(), 0); + o.consensus_ = getString(s, o.seeds_[0].orig_pos.first, o.seeds_[0].orig_pos.second - o.seeds_[0].orig_pos.first); + for(size_t j = 0; j < o.seeds_.size(); j++) { + o.seeds_[j].pos = o.seeds_[j].orig_pos; + o.seeds_[j].left_gaps.clear(); + o.seeds_[j].right_gaps.clear(); + o.seeds_[j].ed = o.seeds_[j].total_ed = 0; + } +} + +void RB_Repeat::internal_update() +{ + sort(seeds_.begin(), seeds_.end(), seedCmp); + + seed_ranges_.resizeExact(seeds_.size()); + for(size_t i = 0; i < seeds_.size(); i++) { + seed_ranges_[i].left = seeds_[i].pos.first; + seed_ranges_[i].right = seeds_[i].pos.second; + seed_ranges_[i].idx = i; + } + seed_ranges_.sort(); + + // check repeats within a repeat sequence + size_t remove_count = 0; + for(size_t i = 0; i + 1 < seed_ranges_.size(); i++) { + const RB_AlleleCoord& range = seed_ranges_[i]; + if(range.left == numeric_limits::max()) + continue; + for(size_t j = i + 1; j < seed_ranges_.size(); j++) { + RB_AlleleCoord& range2 = seed_ranges_[j]; + if(range2.left == numeric_limits::max()) + continue; + if(range.right <= range2.left) + break; + if(range.right >= range2.right) { + range2.left = numeric_limits::max(); + remove_count++; + } + } + } + + if(remove_count <= 0) + return; + + for(size_t i = 0; i < seed_ranges_.size(); i++) { + if(seed_ranges_[i].left == numeric_limits::max()) + seeds_[seed_ranges_[i].idx].reset(); + } + sort(seeds_.begin(), seeds_.end(), seedCmp); + +#ifndef NDEBUG + for(size_t i = 0; i < seeds_.size(); i++) { + if(i < seeds_.size() - remove_count) { + assert_lt(seeds_[i].pos.first, seeds_[i].pos.second); + } else { + assert_eq(seeds_[i].pos.first, seeds_[i].pos.second); + } + } +#endif + + seeds_.resize(seeds_.size() - remove_count); + seed_ranges_.resize(seeds_.size()); + for(size_t i = 0; i < seeds_.size(); i++) { + seed_ranges_[i].left = seeds_[i].pos.first; + seed_ranges_[i].right = seeds_[i].pos.second; + seed_ranges_[i].idx = i; + } + seed_ranges_.sort(); +} + +bool RB_Repeat::contain(TIndexOffU left, TIndexOffU right) const +{ + size_t l = 0, r = seed_ranges_.size(); + while(l < r) { + size_t m = (l + r) / 2; + const RB_AlleleCoord& coord = seed_ranges_[m]; + if(right <= coord.left) { + r = m; + } else if(left >= coord.right) { + l = m + 1; + } else { + return coord.left <= left && right <= coord.right; + } + } + + return false; +} + +template +void RB_Repeat::saveSeedExtension(const RepeatParameter& rp, + const TStr& s, + CoordHelper& coordHelper, + TIndexOffU grp_id, + ostream& fp, + size_t& total_repeat_seq_len, + size_t& total_allele_seq_len) const +{ + // apply color, which is compatible with linux commands such as cat and less -r +#if 1 + const string red = "\033[31m", reset = "\033[0m", resetline = "\033[4m", redline = "\033[4;31m"; +#else + const string red = "", reset = "", resetline = "", redline = ""; +#endif + bool show_exterior_seq = true; + const size_t max_show_seq_len = 700; + + size_t total_count = 0; + for(size_t i = 0; i < seeds_.size(); i++) { + const SeedExt& seed = seeds_[i]; + size_t ext_len = seed.getLength(); + if(ext_len < rp.min_repeat_len) continue; + total_allele_seq_len += ext_len; + total_count++; + bool sense_strand = seed.pos.first < coordHelper.forward_length(); + + fp << setw(6) << repeat_id_ << " " << setw(5) << seeds_.size(); + fp << " " << setw(4) << i; + fp << " " << setw(4) << ext_len; + fp << " " << (sense_strand ? '+' : '-'); + fp << " " << setw(10) << seed.pos.first << " " << setw(10) << seed.pos.second; + fp << " " << setw(10) << seed.orig_pos.first << " " << setw(10) << seed.orig_pos.second; + + string chr_name; + TIndexOffU pos_in_chr; + if(sense_strand) { + coordHelper.getGenomeCoord(seed.pos.first, chr_name, pos_in_chr); + } else { + coordHelper.getGenomeCoord(s.length() - seed.pos.first - (seed.pos.second - seed.pos.first), chr_name, pos_in_chr); + } + fp << " " << setw(5) << chr_name << ":" << setw(10) << std::left << pos_in_chr << std::right; + + if(sense_strand) { + coordHelper.getGenomeCoord(seed.pos.second, chr_name, pos_in_chr); + } else { + coordHelper.getGenomeCoord(s.length() - seed.pos.second - (seed.pos.second - seed.pos.first), chr_name, pos_in_chr); + } + fp << " " << setw(5) << chr_name << ":" << setw(10) << std::left << pos_in_chr << std::right; + + if(!seed.aligned) { + fp << endl; + continue; + } + + string deststr = ""; + seed.getExtendedSeedSequence(s, deststr); + + // add exterior sequences + if(seed.consensus_pos.first > 0) { + TIndexOffU seq_pos, seq_len; + if(seed.pos.first >= seed.consensus_pos.first) { + seq_pos = seed.pos.first - seed.consensus_pos.first; + seq_len = seed.consensus_pos.first; + } else { + seq_pos = 0; + seq_len = seed.pos.first; + } + deststr = getString(s, seq_pos, seq_len) + deststr; + if(seq_len < seed.consensus_pos.first) { + deststr = string(seed.consensus_pos.first - seq_len, 'N') + deststr; + } + } + if(seed.consensus_pos.second < consensus_.length()) { + deststr += getString(s, seed.pos.second, consensus_.length() - seed.consensus_pos.second); + } + + assert_eq(consensus_.length(), deststr.length()); + fp << " "; + + // print sequence w.r.t. the current group + for(size_t j = 0; j < min(consensus_.length(), max_show_seq_len); j++) { + bool outside = j < seed.consensus_pos.first || j >= seed.consensus_pos.second; + bool different = (consensus_[j] != deststr[j]); + if(outside) { + if(show_exterior_seq) { + if(different) { + fp << redline; + fp << deststr[j]; + fp << reset; + } else { + fp << resetline; + fp << deststr[j]; + fp << reset; + } + } else { + if(j < seed.consensus_pos.first) + fp << " "; + } + } else { + if(different) fp << red; + fp << deststr[j]; + if(different) fp << reset; + } + } + +#if 0 + fp << "\t"; + for(size_t ei = 0; ei < seed.edits.size(); ei++) { + const Edit& edit = seed.edits[ei]; + if(ei > 0) fp << ","; + fp << edit; + if (edit.snpID != std::numeric_limits::max()) { + fp << "@" << edit.snpID; + } + } +#endif + + fp << endl; + } + + if(total_count > 0) fp << setw(5) << total_count << endl << endl; + total_repeat_seq_len += consensus_.length(); +} + +template +size_t calc_edit_dist(const TStr& s, + const SeedExt& seed, + const SeedExt& seed2, + size_t left_ext, + size_t right_ext, + size_t max_ed) +{ + if(seed.bound.first + left_ext > seed.pos.first || + seed.pos.second + right_ext > seed.bound.second || + seed2.bound.first + left_ext > seed2.pos.first || + seed2.pos.second + right_ext > seed2.bound.second) + return max_ed + 1; + + size_t ed = 0; + for(size_t i = 0; i < left_ext; i++) { + int ch = getSequenceBase(s, seed.pos.first - i - 1); + assert_range(0, 3, ch); + int ch2 = getSequenceBase(s, seed2.pos.first - i - 1); + assert_range(0, 3, ch2); + if(ch != ch2) ed++; + if(ed > max_ed) + return ed; + + } + for(size_t i = 0; i < right_ext; i++) { + int ch = getSequenceBase(s, seed.pos.second + i); + assert_range(0, 3, ch); + int ch2 = getSequenceBase(s, seed2.pos.second + i); + assert_range(0, 3, ch2); + if(ch != ch2) ed++; + if(ed > max_ed) + return ed; + } + + return ed; +} + +size_t extract_kmer(const string& seq, size_t offset, size_t k = 5) +{ + assert_leq(offset + k, seq.length()); + size_t kmer = 0; + for(size_t i = 0; i < k; i++) { + kmer = (kmer << 2) | asc2dna[seq[offset + i]]; + } + return kmer; +} + +size_t next_kmer(size_t kmer, char base, size_t k = 5) +{ + kmer &= ((1 << ((k-1)*2))) - 1; + kmer = (kmer << 2) | asc2dna[base]; + return kmer; +} + +void build_kmer_table(const string& consensus, EList >& kmer_table, size_t k = 5) +{ + kmer_table.clear(); + if(consensus.length() < k) + return; + size_t kmer = 0; + for(size_t i = 0; i + k <= consensus.length(); i++) { + if(i == 0) { + kmer = extract_kmer(consensus, i, k); + } else { + kmer = next_kmer(kmer, consensus[i+k-1], k); + } + kmer_table.expand(); + kmer_table.back().first = kmer; + kmer_table.back().second = i; + } + kmer_table.sort(); +} + +void find_gap_pos(const string& s, + const string& s2, + EList& ed, + EList& ed2, + bool del, + size_t gap_len, + size_t max_mm, + size_t& gap_pos, + size_t& mm, + bool debug = false) +{ + assert_eq(s.length(), s2.length()); + size_t seq_len = s.length(); + ed.resizeExact(seq_len); ed.fill(max_mm + 1); + ed2.resizeExact(seq_len); ed2.fill(max_mm + 1); + + // from left to right + for(size_t i = 0; i < seq_len; i++) { + size_t add = (s[i] == s2[i] ? 0 : 1); + if(i == 0) ed[i] = add; + else ed[i] = ed[i-1] + add; + if(ed[i] >= max_mm + 1) break; + } + + // from right to left + size_t s_sub = del ? 0 : gap_len; + size_t s2_sub = del ? gap_len : 0; + for(int i = seq_len - 1; i >= gap_len; i--) { + size_t add = (s[i - s_sub] == s2[i - s2_sub] ? 0 : 1); + if(i == seq_len - 1) ed2[i] = add; + else ed2[i] = ed2[i+1] + add; + if(ed2[i] > max_mm) break; + } + + if(debug) { + cout << s << endl << s2 << endl; + for(size_t i = 0; i < ed.size(); i++) { + cout << (ed[i] % 10); + } + cout << endl; + for(size_t i = 0; i < ed2.size(); i++) { + cout << (ed2[i] % 10); + } + cout << endl; + } + + size_t min_mm = ed2[gap_len]; + int min_mm_i = -1; + assert_eq(ed.size(), ed2.size()); + for(size_t i = 0; i + gap_len + 1 < ed.size(); i++) { + if(ed[i] > max_mm) break; + size_t cur_mm = ed[i] + ed2[i + gap_len + 1]; + if(cur_mm < min_mm) { + min_mm = cur_mm; + min_mm_i = i; + } + } + + mm = min_mm; + if(mm > max_mm) + return; + gap_pos = (size_t)(min_mm_i + 1); +} + +void align_with_one_gap(const string& s, + const EList >& s_kmer_table, + const string& s2, + EList& counts, + size_t max_gap, + size_t max_mm, + size_t& mm, + size_t& gap_pos, + int& gap_len, + size_t k = 5) +{ + mm = max_mm + 1; + assert_eq(s.length(), s2.length()); + counts.resizeExact(max_gap * 2 + 1); + counts.fillZero(); + size_t max_count = 0, max_count_i = 0; + for(size_t i = 0; i + k <= s2.length(); i += 1) { + pair kmer(0, 0); + kmer.first = extract_kmer(s2, i, k); + size_t lb = s_kmer_table.bsearchLoBound(kmer); + while(lb < s_kmer_table.size() && kmer.first == s_kmer_table[lb].first) { + int gap = (int)s_kmer_table[lb].second - (int)i; + if(gap != 0 && abs(gap) < max_gap) { + size_t gap_i = (size_t)(gap + max_gap); + counts[gap_i]++; + if(counts[gap_i] > max_count) { + max_count = counts[gap_i]; + max_count_i = gap_i; + } + } + lb++; + } + } + + if(max_count <= 0) + return; + + assert_lt(max_count_i, counts.size()); + int gap = (int)max_count_i - (int)max_gap; + assert_neq(gap, 0); + size_t abs_gap = abs(gap); + bool del = gap > 0; + + EList ed, ed2; + find_gap_pos(s, + s2, + ed, + ed2, + del, + abs_gap, + max_mm, + gap_pos, + mm); + if(mm > max_mm) + return; + + gap_len = del ? abs_gap : -abs_gap; + +#ifndef NDEBUG + assert_leq(mm, max_mm); + string ds = s, ds2 = s2; + size_t debug_mm = 0; + if(del) ds.erase(gap_pos, abs_gap); + else ds2.erase(gap_pos, abs_gap); + + for(size_t i = 0; i < min(ds.length(), ds2.length()); i++) { + if(ds[i] != ds2[i]) + debug_mm++; + } + assert_eq(debug_mm, mm); +#endif +} + +template +void calc_edit_dist(const TStr& s, + EList& seeds, + size_t sb, + size_t se, + const EList& left_consensuses, + const EList& right_consensuses, + uint32_t max_ed) +{ + string left_consensus = left_consensuses[max_ed]; + string right_consensus = right_consensuses[max_ed]; + + EList > left_kmer_table, right_kmer_table; + build_kmer_table(left_consensus, left_kmer_table); + build_kmer_table(right_consensus, right_kmer_table); + + string left_seq, right_seq; + const size_t max_gap = 10; + EList counts; + + size_t left_ext = left_consensus.length(); + size_t right_ext = right_consensus.length(); + for(size_t i = sb; i < se; i++) { + SeedExt& seed = seeds[i]; + if(seed.bound.first + left_ext > seed.pos.first || + seed.pos.second + right_ext > seed.bound.second) { + seed.ed = max_ed + 1; + continue; + } + + size_t left_ed = 0; + if(left_ext > 0) { + getString(s, seed.pos.first - left_ext, left_ext, left_seq); + reverse(left_seq.begin(), left_seq.end()); + for(size_t j = 0; j < left_ext; j++) { + if(left_seq[j] != left_consensus[j]) left_ed++; + if(left_ed <= max_ed && j < left_consensuses[left_ed].length()) { + seed.curr_ext_len = j + 1; + } + } + + if(left_ed > max_ed) { + size_t gap_pos = 0; + int gap_len = 0; + align_with_one_gap(left_consensus, + left_kmer_table, + left_seq, + counts, + min(left_ed - max_ed, max_gap), + max_ed, + left_ed, + gap_pos, + gap_len); + if(left_ed <= max_ed) { + seed.left_gaps.expand(); + seed.left_gaps.back().first = seed.getLeftExtLength() + gap_pos; + seed.left_gaps.back().second = gap_len; + } + } + } else { + left_seq.clear(); + } + + size_t right_ed = 0; + if(right_ext > 0) { + getString(s, seed.pos.second, right_ext, right_seq); + for(size_t j = 0; j < right_ext; j++) { + if(right_seq[j] != right_consensus[j]) right_ed++; + if(right_ed <= max_ed && j < right_consensuses[right_ed].length()) { + seed.curr_ext_len = j + 1; + } + } + if(right_ed > max_ed) { + size_t gap_pos = 0; + int gap_len = 0; + align_with_one_gap(right_consensus, + right_kmer_table, + right_seq, + counts, + min(right_ed - max_ed, max_gap), + max_ed, + right_ed, + gap_pos, + gap_len); + if(right_ed <= max_ed) { + seed.right_gaps.expand(); + seed.right_gaps.back().first = seed.getRightExtLength() + gap_pos; + seed.right_gaps.back().second = gap_len; + } + } + } else { + right_seq.clear(); + } + + seed.ed = left_ed + right_ed; + } +} + +template +void RB_Repeat::get_consensus_seq(const TStr& s, + EList& seeds, + size_t sb, + size_t se, + size_t min_left_ext, + size_t min_right_ext, + size_t max_ed, + const RepeatParameter& rp, + EList& ed_seed_nums, + EList* left_consensuses, + EList* right_consensuses) const +{ + assert_lt(sb, se); + assert_geq(se - sb, rp.seed_count); + assert_leq(se, seeds.size()); + if(left_consensuses != NULL) { + left_consensuses->clear(); left_consensuses->resize(max_ed + 1); + for(size_t i = 0; i < max_ed + 1; i++) { + (*left_consensuses)[i].clear(); + } + } + if(right_consensuses != NULL) { + right_consensuses->clear(); right_consensuses->resize(max_ed + 1); + for(size_t i = 0; i < max_ed + 1; i++) { + (*right_consensuses)[i].clear(); + } + } + + assert_eq(min_left_ext, min_right_ext); + + EList seqs; + seqs.reserveExact(seeds.size()); + size_t max_i = 0, max_count = 0; + while(min_left_ext > 0) { + seqs.clear(); + max_i = 0; + max_count = 0; + for(size_t i = sb; i < se; i++) { + const SeedExt& seed = seeds[i]; + if(seeds[i].bound.first + min_left_ext > seed.pos.first || + seed.pos.second + min_right_ext > seed.bound.second) + continue; + + seqs.expand(); + if(min_left_ext > 0) { + getString(s, seed.pos.first - min_left_ext, min_left_ext, seqs.back()); + } + if(min_right_ext > 0) { + seqs.back() += getString(s, seed.pos.second, min_right_ext); + } + } + seqs.sort(); + for(size_t i = 0; i + max_count < seqs.size();) { + size_t count = 1; + for(size_t j = i + 1; j < seqs.size(); j++) { + if(seqs[i] == seqs[j]) count++; + else break; + } + if(count >= max_count) { + max_count = count; + max_i = i; + } + i = i + count; + } + if(max_count >= rp.seed_count) + break; + + min_left_ext--; + min_right_ext--; + } + + // update ed + // extend consensus string + ed_seed_nums.resize(max_ed + 1); ed_seed_nums.fillZero(); + EList next_ed_seed_nums; next_ed_seed_nums.resize(max_ed + 1); + + if(max_count < rp.seed_count) + return; + + for(size_t i = sb; i < se; i++) seeds[i].ed = 0; + size_t seed_ext_len = 0; + while(seed_ext_len < max(min_left_ext, min_right_ext)) { + // select base to be used for extension + uint8_t left_ext_base = 0; + if(seed_ext_len < min_left_ext) left_ext_base = seqs[max_i][min_left_ext - seed_ext_len - 1]; + uint8_t right_ext_base = 0; + if(seed_ext_len < min_right_ext) right_ext_base = seqs[max_i][min_left_ext + seed_ext_len]; + + // estimate extended ed + next_ed_seed_nums.fillZero(); + for(size_t i = sb; i < se; i++) { + uint32_t est_ed = seeds[i].ed; + if(seed_ext_len < min_left_ext) { + if(seeds[i].bound.first + seed_ext_len + 1 <= seeds[i].pos.first) { + TIndexOffU left_pos = seeds[i].pos.first - seed_ext_len - 1; + int ch = getSequenceBase(s, left_pos); + assert_range(0, 3, ch); + if ("ACGT"[ch] != left_ext_base) { + est_ed++; + } + } else { + est_ed = max_ed + 1; + } + } + + if(seed_ext_len < min_right_ext) { + TIndexOffU right_pos = seeds[i].pos.second + seed_ext_len; + if(right_pos >= seeds[i].bound.second) { + est_ed = max_ed + 1; + } else { + int ch = getSequenceBase(s, right_pos); + assert_range(0, 3, ch); + if ("ACGT"[ch] != right_ext_base) { + est_ed++; + } + } + } + + if(est_ed <= max_ed) { + next_ed_seed_nums[est_ed]++; + } + } + + for(size_t i = 1; i < next_ed_seed_nums.size(); i++) next_ed_seed_nums[i] += next_ed_seed_nums[i-1]; + if(next_ed_seed_nums[max_ed] < rp.repeat_count) { + break; + } + + for(size_t i = sb; i < se; i++) { + if(seed_ext_len < min_left_ext) { + if(seeds[i].bound.first + seed_ext_len + 1 <= seeds[i].pos.first) { + TIndexOffU left_pos = seeds[i].pos.first - seed_ext_len - 1; + int ch = getSequenceBase(s, left_pos); + assert_range(0, 3, ch); + if ("ACGT"[ch] != left_ext_base) { + seeds[i].ed++; + } + } else { + seeds[i].ed = max_ed + 1; + } + } + + if(seed_ext_len < min_right_ext) { + TIndexOffU right_pos = seeds[i].pos.second + seed_ext_len; + if(right_pos >= seeds[i].bound.second) { + seeds[i].ed = max_ed + 1; + } else { + int ch = getSequenceBase(s, right_pos); + assert_range(0, 3, ch); + if ("ACGT"[ch] != right_ext_base) { + seeds[i].ed++; + } + } + } + } + + for(size_t i = 0; i < next_ed_seed_nums.size(); i++) { + if(next_ed_seed_nums[i] < rp.repeat_count) + continue; + ed_seed_nums[i] = next_ed_seed_nums[i]; + if(seed_ext_len < min_left_ext) { + assert(left_consensuses != NULL); + (*left_consensuses)[i] += left_ext_base; + } + if(seed_ext_len < min_right_ext) { + assert(right_consensuses != NULL); + (*right_consensuses)[i] += right_ext_base; + } + } + + seed_ext_len++; + } +} + +template +void RB_RepeatExt::get_consensus_seq(const TStr& s, + EList& seeds, + size_t sb, + size_t se, + size_t min_left_ext, + size_t min_right_ext, + size_t max_ed, + const RepeatParameter& rp, + EList& ed_seed_nums, + EList* left_consensuses, + EList* right_consensuses) const +{ + assert_lt(sb, se); + assert_leq(se, seeds.size()); + if(left_consensuses != NULL) { + left_consensuses->clear(); left_consensuses->resize(max_ed + 1); + for(size_t i = 0; i < max_ed + 1; i++) { + (*left_consensuses)[i].clear(); + } + } + if(right_consensuses != NULL) { + right_consensuses->clear(); right_consensuses->resize(max_ed + 1); + for(size_t i = 0; i < max_ed + 1; i++) { + (*right_consensuses)[i].clear(); + } + } + + // cluster sequences + EList belongto; + belongto.resizeExact(se - sb); + for(size_t i = 0; i < belongto.size(); i++) belongto[i] = i; + + for(size_t i = 0; i + 1 < belongto.size(); i++) { + for(size_t j = i + 1; j < belongto.size(); j++) { + if(belongto[j] != j) continue; + size_t ed = calc_edit_dist(s, + seeds[sb + i], + seeds[sb + j], + min_left_ext, + min_right_ext, + max_ed + 1); + if(ed <= max_ed + 1) { + belongto[j] = belongto[i]; + } + + } + } + + // find the maximum group that has the most sequences + EList vote; + vote.resizeExact(seeds.size()); + vote.fillZero(); + size_t max_group = 0; + for(size_t i = 0; i < belongto.size(); i++) { + size_t cur_group = belongto[i]; + assert_lt(cur_group, vote.size()); + vote[cur_group]++; + if(cur_group != max_group && vote[cur_group] > vote[max_group]) { + max_group = cur_group; + } + } + + // reuse vote to store seeds + EList& consensus_group = vote; + consensus_group.clear(); + for(size_t i = 0; i < belongto.size(); i++) { + if(belongto[i] == max_group) + consensus_group.push_back(i); + } + + // update ed + // extend consensus string + ed_seed_nums.resize(max_ed + 1); ed_seed_nums.fillZero(); + EList next_ed_seed_nums; next_ed_seed_nums.resize(max_ed + 1); + for(size_t i = sb; i < se; i++) seeds[i].ed = 0; + size_t seed_ext_len = 0; + while(seed_ext_len < max(min_left_ext, min_right_ext)) { + // count base + size_t l_count[4] = {0, }; + size_t r_count[4] = {0, }; + + for(size_t i = 0; i < consensus_group.size(); i++) { + size_t si = sb + consensus_group[i]; + int ch; + if(seed_ext_len < min_left_ext) { + if(seeds[i].bound.first + seed_ext_len + 1 <= seeds[i].pos.first) { + ch = getSequenceBase(s, seeds[si].pos.first - seed_ext_len - 1); + assert_range(0, 3, ch); + l_count[ch]++; + } + } + if(seed_ext_len < min_right_ext) { + if(seeds[i].bound.second + seed_ext_len) { + ch = getSequenceBase(s, seeds[si].pos.second + seed_ext_len); + assert_range(0, 3, ch); + r_count[ch]++; + } + } + } + + // select base to be used for extension + uint8_t left_ext_base = 0; + if(seed_ext_len < min_left_ext) left_ext_base = max_index(l_count); + uint8_t right_ext_base = 0; + if(seed_ext_len < min_right_ext) right_ext_base = max_index(r_count); + + // estimate extended ed + next_ed_seed_nums.fillZero(); + for(size_t i = sb; i < se; i++) { + uint32_t est_ed = seeds[i].ed; + if(seed_ext_len < min_left_ext) { + if(seeds[i].bound.first + seed_ext_len + 1 <= seeds[i].pos.first) { + TIndexOffU left_pos = seeds[i].pos.first - seed_ext_len - 1; + int ch = getSequenceBase(s, left_pos); + assert_range(0, 3, ch); + if (ch != left_ext_base) { + est_ed++; + } + } else { + est_ed = max_ed + 1; + } + } + + if(seed_ext_len < min_right_ext) { + TIndexOffU right_pos = seeds[i].pos.second + seed_ext_len; + if(right_pos >= seeds[i].bound.second) { + est_ed = max_ed + 1; + } else { + int ch = getSequenceBase(s, right_pos); + assert_range(0, 3, ch); + if (ch != right_ext_base) { + est_ed++; + } + } + } + + if(est_ed <= max_ed) { + next_ed_seed_nums[est_ed]++; + } + } + + for(size_t i = 1; i < next_ed_seed_nums.size(); i++) next_ed_seed_nums[i] += next_ed_seed_nums[i-1]; + if(next_ed_seed_nums[max_ed] < rp.repeat_count) { + break; + } + + for(size_t i = sb; i < se; i++) { + if(seed_ext_len < min_left_ext) { + if(seeds[i].bound.first + seed_ext_len + 1 <= seeds[i].pos.first) { + TIndexOffU left_pos = seeds[i].pos.first - seed_ext_len - 1; + int ch = getSequenceBase(s, left_pos); + assert_range(0, 3, ch); + if (ch != left_ext_base) { + seeds[i].ed++; + } + } else { + seeds[i].ed = max_ed + 1; + } + } + + if(seed_ext_len < min_right_ext) { + TIndexOffU right_pos = seeds[i].pos.second + seed_ext_len; + if(right_pos >= seeds[i].bound.second) { + seeds[i].ed = max_ed + 1; + } else { + int ch = getSequenceBase(s, right_pos); + assert_range(0, 3, ch); + if (ch != right_ext_base) { + seeds[i].ed++; + } + } + } + } + + for(size_t i = 0; i < next_ed_seed_nums.size(); i++) { + if(next_ed_seed_nums[i] < rp.repeat_count) + continue; + ed_seed_nums[i] = next_ed_seed_nums[i]; + if(seed_ext_len < min_left_ext) { + assert(left_consensuses != NULL); + (*left_consensuses)[i] += (char)("ACGT"[left_ext_base]); + } + if(seed_ext_len < min_right_ext) { + assert(right_consensuses != NULL); + (*right_consensuses)[i] += (char)("ACGT"[right_ext_base]); + } + } + + seed_ext_len++; + } +} + +EList RB_Repeat::ca_ed_; +EList RB_Repeat::ca_ed2_; +string RB_Repeat::ca_s_; +string RB_Repeat::ca_s2_; + +size_t RB_Repeat::seed_merge_tried = 0; +size_t RB_Repeat::seed_merged = 0; + +template +void RB_RepeatExt::extendConsensus(const RepeatParameter& rp, + const TStr& s) +{ + size_t remain = seeds_.size(); + EList consensuses, empty_consensuses; + EList ed_seed_nums; + bool left = true; + + const TIndexOffU default_max_ext_len = 100; + const TIndexOffU seed_mm = 4; + string ext_consensus = ""; + + empty_consensuses.resize(seed_mm + 1); + empty_consensuses.fill(""); + + while(remain >= rp.repeat_count) { + for(size_t i = 0; i < remain; i++) { + seeds_[i].done = false; + seeds_[i].curr_ext_len = 0; + } + + // extend seeds in left or right direction + TIndexOffU max_ext_len = min(default_max_ext_len, (TIndexOffU)(rp.max_repeat_len - consensus_.length())); + get_consensus_seq(s, + seeds_, + 0, // seed begin + remain, // seed end + left ? max_ext_len : 0, + left ? 0 : max_ext_len, + seed_mm, + rp, + ed_seed_nums, + left ? &consensuses : NULL, + left ? NULL : &consensuses); + + size_t allowed_seed_mm = 0; + ext_consensus.clear(); + for(int i = (int)seed_mm; i >= 0; i--) { + size_t extlen = (ed_seed_nums[i] < rp.repeat_count ? 0 : consensuses[i].length()); + if(extlen <= 0 || extlen < max_ext_len * i / seed_mm) + continue; + + if(i > 0 && consensuses[i].length() <= consensuses[i-1].length() + 5) + continue; + + ext_consensus = consensuses[i]; + allowed_seed_mm = (size_t)i; + assert(ext_consensus.length() > 0); + break; + } + size_t num_passed_seeds = 0; + if(ext_consensus.length() > 0) { + if(left) consensus_ = reverse(ext_consensus) + consensus_; + else consensus_ += ext_consensus; + + calc_edit_dist(s, + seeds_, + 0, + remain, + left ? consensuses : empty_consensuses, + left ? empty_consensuses : consensuses, + allowed_seed_mm); + + // update seeds + for(size_t i = 0; i < seeds_.size(); i++) { + SeedExt& seed = seeds_[i]; + + if(i < remain) { + if(seed.ed <= allowed_seed_mm) { + num_passed_seeds++; + seed.done = true; + seed.total_ed += seed.ed; + if(left) { + if(seed.left_gaps.size() > 0 && + seed.left_gaps.back().first >= seed.orig_pos.first - seed.pos.first) { + int gap_len = seed.left_gaps.back().second; + seed.pos.first += gap_len; + } + seed.pos.first -= ext_consensus.length(); + seed.consensus_pos.first = 0; + seed.consensus_pos.second = consensus_.length(); + } else { + if(seed.right_gaps.size() > 0 && + seed.right_gaps.back().first >= seed.pos.second - seed.orig_pos.second) { + int gap_len = seed.right_gaps.back().second; + seed.pos.second -= gap_len; + } + seed.pos.second += ext_consensus.length(); + seed.consensus_pos.second = consensus_.length(); + } + } else { + if(left) { + assert_leq(seed.curr_ext_len, ext_consensus.length()); + TIndexOffU adjust = ext_consensus.length() - seed.curr_ext_len; + seed.consensus_pos.first += adjust; + seed.consensus_pos.second += ext_consensus.length(); + assert_leq(seed.curr_ext_len, seed.pos.first); + seed.pos.first -= seed.curr_ext_len; + } else { + assert_leq(seed.curr_ext_len, ext_consensus.length()); + seed.consensus_pos.second += seed.curr_ext_len; + seed.pos.second += seed.curr_ext_len; + } + } + } else { + if(left) { + seed.consensus_pos.first += ext_consensus.length(); + seed.consensus_pos.second += ext_consensus.length(); + } + } + } + + // move up "done" seeds + size_t j = 0; + for(size_t i = 0; i < remain; i++) { + if(!seeds_[i].done) continue; + assert_geq(i, j); + if(i > j) { + SeedExt temp = seeds_[j]; + seeds_[j] = seeds_[i]; + seeds_[i] = temp; + // Find next "undone" seed + j++; + while(j < i && seeds_[j].done) { + j++; + } + assert(j < remain && !seeds_[j].done); + } else { + j = i + 1; + } + } + } + + remain = num_passed_seeds; + if(remain < rp.repeat_count) { + if(left) { + left = false; + remain = seeds_.size(); + } + } + } // while(remain >= rp.repeat_count) + +#ifndef NDEBUG + // make sure seed positions are unique + EList > seed_poses; + for(size_t i = 0; i < seeds_.size(); i++) { + seed_poses.expand(); + seed_poses.back() = seeds_[i].orig_pos; + } + seed_poses.sort(); + for(size_t i = 0; i + 1 < seed_poses.size(); i++) { + if(seed_poses[i].first == seed_poses[i+1].first) { + assert_lt(seed_poses[i].second, seed_poses[i+1].second); + } else { + assert_lt(seed_poses[i].first, seed_poses[i+1].first); + } + } + + for(size_t i = 0; i < seeds_.size(); i++) { + assert(seeds_[i].valid()); + } +#endif + + internal_update(); + + // check repeats within a repeat sequence + self_repeat_ = false; + for(size_t i = 0; i + 1 < seed_ranges_.size(); i++) { + const RB_AlleleCoord& range = seed_ranges_[i]; + for(size_t j = i + 1; j < seed_ranges_.size(); j++) { + RB_AlleleCoord& range2 = seed_ranges_[j]; + if(range.right <= range2.left) + break; + self_repeat_ = true; + } + } +} + +bool RB_Repeat::overlap(const RB_Repeat& o, + bool& contain, + bool& left, + size_t& seed_i, + size_t& seed_j, + bool debug) const +{ + contain = left = false; + seed_i = seed_j = 0; + size_t p = 0, p2 = 0; + while(p < seed_ranges_.size() && p2 < o.seed_ranges_.size()) { + const RB_AlleleCoord& range = seed_ranges_[p]; + const SeedExt& seed = seeds_[range.idx]; + Range range_ = seed.getExtendedRange(consensus_.length()); + RB_AlleleCoord ex_range(range_.first, range_.second, p); + bool representative = (float)range.len() >= consensus_.length() * 0.95f; + + const RB_AlleleCoord& range2 = o.seed_ranges_[p2]; + const SeedExt& seed2 = o.seeds_[range2.idx]; + Range range2_ = seed2.getExtendedRange(o.consensus().length()); + RB_AlleleCoord ex_range2(range2_.first, range2_.second, p2); + bool representative2 = (float)range2.len() >= o.consensus_.length() * 0.95f; + + seed_i = range.idx; + seed_j = range2.idx; + + const size_t relax = 5; + if(representative && representative2) { + if(ex_range.overlap_len(ex_range2) > 0) { + if(ex_range.contain(ex_range2, relax)) { + contain = true; + left = true; + } else if(ex_range2.contain(ex_range, relax)) { + contain = true; + left = false; + } else { + left = ex_range.left <= ex_range2.left; + } + return true; + } + } else if(representative) { + if(range2.contain(ex_range, relax)) { + contain = true; + left = false; + return true; + } + } else if(representative2) { + if(range.contain(ex_range2, relax)) { + contain = true; + left = true; + return true; + } + } + + if(range.right <= range2.right) p++; + if(range2.right <= range.right) p2++; + } + return false; +} + +void RB_Repeat::showInfo(const RepeatParameter& rp, + CoordHelper& coordHelper) const +{ + cerr << "\trepeat id: " << repeat_id_ << endl; + cerr << "\tnumber of alleles: " << seeds_.size() << endl; + cerr << "\tconsensus length: " << consensus_.length() << endl; + cerr << consensus_ << endl; + for(size_t i = 0; i < seeds_.size(); i++) { + const SeedExt& seed = seeds_[i]; + size_t ext_len = seed.getLength(); + if(ext_len < rp.min_repeat_len) continue; + bool sense_strand = seed.pos.first < coordHelper.forward_length(); + + cerr << "\t\t" << setw(4) << i << " " << setw(4) << ext_len; + cerr << " " << (sense_strand ? '+' : '-'); + cerr << " " << setw(10) << seed.pos.first << " " << setw(10) << seed.pos.second; + cerr << " " << setw(4) << seed.consensus_pos.first << " " << setw(4) << seed.consensus_pos.second; + cerr << " " << (seed.aligned ? "aligned" : "unaligned"); + cerr << endl; + } +} + +template +void RB_Repeat::generateSNPs(const RepeatParameter& rp, const TStr& s, TIndexOffU grp_id) { + EList& seeds = this->seeds(); + + for(size_t i = 0; i < seeds.size(); i++) { + SeedExt& seed = seeds[i]; + + if(!seed.aligned) { + continue; + } + + if(seed.getLength() < rp.min_repeat_len) { + continue; + } + assert_eq(seed.getLength(), seed.pos.second - seed.pos.first); + seed.generateSNPs(s, consensus(), snps()); + } + if(snps().size() > 0) { + sort(snps_.begin(), snps().end(), SeedSNP::cmpSeedSNPByPos); + } +} + +void RB_Repeat::saveSNPs(ofstream &fp, TIndexOffU grp_id, TIndexOffU& snp_id_base) +{ + string chr_name = "rep" + to_string(repeat_id_); + + for(size_t j = 0; j < snps_.size(); j++) { + SeedSNP& snp = *snps_[j]; + // assign SNPid + snp.id = (snp_id_base++); + + fp << "rps" << snp.id; + fp << "\t"; + + if(snp.type == EDIT_TYPE_MM) { + fp << "single"; + } else if(snp.type == EDIT_TYPE_READ_GAP) { + fp << "deletion"; + } else if(snp.type == EDIT_TYPE_REF_GAP) { + fp << "insertion"; + } else { + assert(false); + } + fp << "\t"; + + fp << chr_name; + fp << "\t"; + + fp << snp.pos; + fp << "\t"; + if(snp.type == EDIT_TYPE_MM || snp.type == EDIT_TYPE_REF_GAP) { + fp << snp.base; + } else if(snp.type == EDIT_TYPE_READ_GAP) { + fp << snp.len; + } else { + assert(false); + } + fp << endl; + } +} + +float RB_RepeatExt::mergeable(const RB_Repeat& o) const +{ + const EList& ranges = seed_ranges(); + const EList& ranges2 = o.seed_ranges(); + size_t num_overlap_bp = 0; + size_t p = 0, p2 = 0; + while(p < ranges.size() && p2 < ranges2.size()) { + const RB_AlleleCoord& range = ranges[p]; + const RB_AlleleCoord& range2 = ranges2[p2]; + TIndexOffU overlap = range.overlap_len(range2); + num_overlap_bp += overlap; + if(range.right <= range2.right) p++; + else p2++; + } + size_t num_total_bp = 0, num_total_bp2 = 0; + for(size_t r = 0; r < ranges.size(); r++) num_total_bp += (ranges[r].right - ranges[r].left); + for(size_t r = 0; r < ranges2.size(); r++) num_total_bp2 += (ranges2[r].right - ranges2[r].left); + float portion = float(num_overlap_bp) / float(min(num_total_bp, num_total_bp2)); + return portion; +} + +inline void get_next_range(const EList& offsets, size_t i, Range& r, float& avg) +{ + r.first = i; + for(; r.first < offsets.size() && offsets[r.first] < 0; r.first++); + r.second = r.first + 1; + avg = 0.0f; + if(r.first < offsets.size()) { + float diff = (float)offsets[r.first] - (float)r.first; + avg += diff; + } + for(; r.second < offsets.size() && + offsets[r.second] >= 0 && + (r.second == 0 || offsets[r.second] >= offsets[r.second - 1]); + r.second++) { + float diff = (float)offsets[r.second] - (float)r.second; + avg += diff; + } + avg /= (float)(r.second - r.first); + return; +} + +template +bool RB_RepeatExt::align(const RepeatParameter& rp, + const TStr& ref, + const string& s, + const EList >& s_kmer_table, + const string& s2, + EList& offsets, + size_t k, + SeedExt& seed, + int consensus_approx_left, + int consensus_approx_right, + size_t left, + size_t right, + bool debug) +{ + RB_Repeat::seed_merge_tried++; + + seed.reset(); + seed.pos.first = left; + seed.pos.second = right; + seed.orig_pos.first = seed.pos.first; + seed.orig_pos.second = seed.orig_pos.first; + seed.consensus_pos.first = 0; + seed.consensus_pos.second = consensus_.length(); + seed.aligned = false; + + { + const int query_len = right - left; + const int consensus_len = consensus_approx_right - consensus_approx_left; + const int abs_gap_len = max(abs(consensus_len - query_len), 5); + + offsets.resize(s2.length()); + offsets.fill(-1); + pair kmer(0, 0); + for(size_t i = 0; i + k <= s2.length(); i++) { + if(i == 0) { + kmer.first = extract_kmer(s2, i, k); + } else { + kmer.first = next_kmer(kmer.first, s2[i+k-1], k); + } + size_t lb = s_kmer_table.bsearchLoBound(kmer); + while(lb < s_kmer_table.size() && kmer.first == s_kmer_table[lb].first) { + int expected = (int)i + consensus_approx_left; + int real = (int)s_kmer_table[lb].second; + int abs_diff = abs(expected - real); + if(abs_diff <= abs_gap_len * 2 || debug) { + if(offsets[i] == -1) { + offsets[i] = (int)s_kmer_table[lb].second; + } else if(offsets[i] >= 0) { + offsets[i] = -2; + } else { + assert_lt(offsets[i], -1); + offsets[i] -= 1; + } + } + lb++; + } + if(offsets[i] > 0 && i + k == s2.length()) { + for(size_t j = i + 1; j < s2.length(); j++) { + offsets[j] = offsets[j-1] + 1; + } + } + } + } + + if(debug) { + cerr << "initial offsets" << endl; + for(size_t j = 0; j < offsets.size(); j++) { + cout << j << ": " << offsets[j] << " " << s2[j] << ": " << (offsets[j] < 0 ? ' ' : s[offsets[j]]) << endl; + } + } + + // remove inconsistent positions + Range range; float range_avg; + get_next_range(offsets, 0, range, range_avg); + while(range.second < offsets.size()) { + Range range2; float range_avg2; + get_next_range(offsets, range.second, range2, range_avg2); + if(range2.first >= offsets.size()) + break; + + assert_leq(range.second, range2.first); + + float abs_diff = abs(range_avg - range_avg2); + if(offsets[range.second - 1] > offsets[range2.first] || + (abs_diff > 10.0f && (range.second - range.first < 5 || range2.second - range2.first < 5)) || + abs_diff > 20.0f) { + if(range.second - range.first < range2.second - range2.first) { + for(size_t i = range.first; i < range.second; i++) { + offsets[i] = -1; + } + range = range2; + range_avg = range_avg2; + } else { + for(size_t i = range2.first; i < range2.second; i++) { + offsets[i] = -1; + } + } + } else { + range = range2; + range_avg = range_avg2; + } + } + + bool weighted_avg_inited = false; + float weighted_avg = -1.0f; + for(size_t i = 0; i < offsets.size(); i++) { + if(offsets[i] < 0) + continue; + + float diff = (float)offsets[i] - (float)i; + if(weighted_avg_inited) { + if(abs(diff - weighted_avg) > 20.0f) { + offsets[i] = -1; + continue; + } + } + + if(weighted_avg < 0.0f) { + weighted_avg = diff; + weighted_avg_inited = true; + } else { + weighted_avg = 0.8f * weighted_avg + 0.2f * diff; + } + } + + if(debug) { + cerr << "after filtering" << endl; + for(size_t j = 0; j < offsets.size(); j++) { + cout << j << ": " << offsets[j] << " " << s2[j] << ": " << (offsets[j] < 0 ? ' ' : s[offsets[j]]) << endl; + } + } + + int i = 0; + while(i < offsets.size()) { + // skip non-negative offsets + for(; i < offsets.size() && offsets[i] >= 0; i++); + if(i >= offsets.size()) break; + int j = i; + for(; j < offsets.size(); j++) { + if(offsets[j] >= 0) + break; + } + assert(i >= offsets.size() || offsets[i] < 0); + assert(j >= offsets.size() || offsets[j] >= 0); + if(i > 0 && j < offsets.size()) { + i -= 1; + int left = offsets[i], right = offsets[j]; + assert_geq(left, 0); + if(left > right) return false; + assert_leq(left, right); + int ref_len = right - left + 1; + int query_len = j - i + 1; + if(query_len == ref_len) { // match + for(size_t i2 = i + 1; i2 < j; i2++) + offsets[i2] = offsets[i2-1] + 1; + } else { // deletion or insertion + bool del = query_len < ref_len; + size_t gap_len = del ? ref_len - query_len : query_len - ref_len; + size_t max_len = max(ref_len, query_len); + const size_t max_mm = max_len / 25 + 1; + const size_t very_max_mm = max(max_len / 2, max_mm); + ca_s_ = s.substr(left, max_len); + ca_s2_ = s2.substr(i, max_len); + + size_t gap_pos = 0, mm = very_max_mm + 1; + find_gap_pos(ca_s_, + ca_s2_, + ca_ed_, + ca_ed2_, + del, + gap_len, + very_max_mm, + gap_pos, + mm, + debug); + + if(mm > very_max_mm) { + return false; + } + + assert_lt(gap_pos, query_len); + if(del) { + for(size_t i2 = i + 1; i2 < j; i2++) { + if(i2 - i == gap_pos) { + offsets[i2] = offsets[i2-1] + gap_len; + } else { + offsets[i2] = offsets[i2-1] + 1; + } + } + } else { + for(size_t i2 = i + 1; i2 < j; i2++) { + if(i2 - i >= gap_pos && i2 - i < gap_pos + gap_len) { + offsets[i2] = offsets[i2-1]; + } else { + offsets[i2] = offsets[i2-1] + 1; + } + } + } + } + } + + i = j; + } + + if(debug) { + cerr << "final offsets" << endl; + for(size_t j = 0; j < offsets.size(); j++) { + cout << j << ": " << offsets[j] << " " << s2[j] << ": " << (offsets[j] < 0 ? ' ' : s[offsets[j]]) << endl; + } + } + +#ifndef NDEBUG + for(size_t i = 1; i < offsets.size(); i++) { + if(offsets[i-1] < 0 || offsets[i] < 0) continue; + assert_leq(offsets[i-1], offsets[i]); + } +#endif + + size_t b, e; + for(b = 0; b < offsets.size() && offsets[b] < 0; b++); + if(b >= offsets.size()) return false; + assert_lt((size_t)b, offsets.size()); + for(e = offsets.size() - 1; e > b && offsets[e] < 0; e--); + if(b == e) return false; + for(size_t p = b; p <= e; p++) { + if(offsets[p] < 0) return false; + } + + // try to fill the ends + if(b > 0) { + int mm = 0, pb = (int)b; + for(int i = pb - 1; i >= 0; i--) { + assert_geq(offsets[i+1], 0); + if(offsets[i+1] == 0) break; + if(s2[i] != s[offsets[i+1] - 1]) + mm++; + if(pb - i < 25 * (mm - 1)) + break; + offsets[i] = offsets[i+1] - 1; + b = (size_t)i; + } + } + if(e + 1 < offsets.size()) { + int mm = 0, prev_end = (int)e; + for(int i = prev_end + 1; i < offsets.size(); i++) { + assert_geq(offsets[i-1], 0); + if(offsets[i-1] + 1 >= s.length()) break; + if(s2[i] != s[offsets[i-1] + 1]) + mm++; + if(i - prev_end < 25 * (mm - 1)) + break; + offsets[i] = offsets[i-1] + 1; + e = (size_t)i; + } + } + + assert_geq(seed.pos.first, (TIndexOffU)b); + seed.pos.first += (TIndexOffU)b; + seed.pos.second = seed.pos.first + e - b + 1; + seed.orig_pos.first = seed.pos.first; + seed.orig_pos.second = seed.pos.first; + seed.consensus_pos.first = offsets[b]; + seed.consensus_pos.second = offsets[e] + 1; + seed.aligned = true; + + for(int p = b; p < e; p++) { + assert_geq(offsets[p], 0); + assert_leq(offsets[p], offsets[p+1]); + if(offsets[p] + 1 == offsets[p+1]) { // match + continue; + } else if(offsets[p] + 1 < offsets[p+1]) { // deletion + seed.right_gaps.expand(); + seed.right_gaps.back().first = p + 1 - b; + seed.right_gaps.back().second = offsets[p+1] - offsets[p] - 1; + } else { + assert_eq(offsets[p], offsets[p+1]); + int p2 = p + 1; + for(; offsets[p2] == offsets[p2+1]; p2++); + seed.right_gaps.expand(); + seed.right_gaps.back().first = p + 1 - b; + seed.right_gaps.back().second = (int)p - (int)p2; + p = p2; + } + } + + if(debug) { + string consensus_str = consensus_.substr(seed.consensus_pos.first, seed.consensus_pos.second - seed.consensus_pos.first); + string seed_str; + seed.getExtendedSeedSequence(ref, seed_str); + assert_eq(consensus_str.length(), seed_str.length()); + cerr << "consensus: " << consensus_str << endl; + cerr << "seed : " << seed_str << endl; + } + + RB_Repeat::seed_merged++; + + return true; +} + +bool RB_RepeatExt::isSelfRepeat(const RepeatParameter& rp, + const string& s, + const EList >& s_kmer_table, + EList& offsets, + size_t k, + bool debug) +{ + offsets.resize(s.length()); + offsets.fill(-1); + pair kmer(0, 0); + for(size_t i = 0; i + k <= s.length(); i++) { + if(i == 0) { + kmer.first = extract_kmer(s, i, k); + } else { + kmer.first = next_kmer(kmer.first, s[i+k-1], k); + } + size_t lb = s_kmer_table.bsearchLoBound(kmer); + while(lb < s_kmer_table.size() && kmer.first == s_kmer_table[lb].first) { + if(offsets[i] == -1) { + offsets[i] = (int)s_kmer_table[lb].second; + } else if(offsets[i] >= 0) { + offsets[i] = -2; + } else { + assert_lt(offsets[i], -1); + offsets[i] -= 1; + } + lb++; + } + if(offsets[i] > 0 && i + k == s.length()) { + for(size_t j = i + 1; j < s.length(); j++) { + offsets[j] = offsets[j-1] + 1; + } + } + } + + if(debug) { + cerr << "offsets" << endl; + for(size_t j = 0; j < offsets.size(); j++) { + cout << j << ": " << offsets[j] << " " << s[j] << ": " << (offsets[j] < 0 ? ' ' : s[offsets[j]]) << endl; + } + } + + const size_t min_repeat_size = 100; + size_t repeat_count = 0; + for(size_t i = 0; i + min_repeat_size < offsets.size(); i++) { + if(offsets[i] >= -1) + continue; + size_t j = i + 1; + for(; j < offsets.size() && offsets[j] <= -2; j++); + if(j - i >= min_repeat_size) + repeat_count++; + i = j; + } + + return repeat_count >= 2; +} + +template +bool RB_RepeatExt::merge(const RepeatParameter& rp, + const TStr& s, + RB_SWAligner& swalginer, + const RB_RepeatExt& o, + bool contain, + size_t seed_i, + size_t seed_j, + bool debug) +{ + // construct a new consensus sequence + string prev_consensus = consensus_; + size_t consensus_add_len = 0; + { + assert_lt(seed_i, seeds_.size()); + assert_lt(seed_j, o.seeds_.size()); + const SeedExt& seed = seeds_[seed_i]; + const SeedExt& oseed = o.seeds_[seed_j]; + + Range range = seed.getExtendedRange(consensus_.length()); + Range orange = oseed.getExtendedRange(o.consensus_.length()); + assert_leq(range.first, orange.first + 10); + + consensus_add_len = (int)orange.first - (int)range.first; + if(!contain) { + if(range.second <= orange.first) { + cerr << "something wrong: " << range.first << "-" << range.second << " "; + cerr << orange.first << "-" << orange.second << " " << o.consensus_.length() << endl; + assert(false); + } + if(range.second > orange.first && + range.second - orange.first < o.consensus_.length()) { + consensus_ += o.consensus_.substr(range.second - orange.first); + } + } + } + + EList > merge_list; + merge_list.reserveExact(o.seed_ranges_.size()); + size_t p = 0, p2 = 0; + const size_t relax = 5; + while(p < seed_ranges_.size() && p2 < o.seed_ranges_.size()) { + const RB_AlleleCoord& range = seed_ranges_[p]; + assert_lt(range.idx, seeds_.size()); + const RB_AlleleCoord& range2 = o.seed_ranges_[p2]; + assert_lt(range2.idx, o.seeds_.size()); + if(range.contain(range2, relax)) { + merge_list.expand(); + merge_list.back().first = p; + merge_list.back().second = p2; + if(debug) { + cerr << p << ":" << range.left << "-" << range.right << " > "; + cerr << p2 << ":" << range2.left << "-" << range2.right << endl; + } + } else if(range2.contain(range, relax)) { + merge_list.expand(); + merge_list.back().first = p; + merge_list.back().second = p2; + if(debug) { + cerr << p << ":" << range.left << "-" << range.right << " < "; + cerr << p2 << ":" << range2.left << "-" << range2.right << endl; + } + } else { + TIndexOffU overlap_len = range.overlap_len(range2); + bool stored = !merge_list.empty() && merge_list.back().first == p; + bool stored2 = !merge_list.empty() && merge_list.back().second == p2; + if(overlap_len > 0) { + if(!stored && !stored2) { + merge_list.expand(); + merge_list.back().first = p; + merge_list.back().second = p2; + + if(debug) { + cerr << p << ":" << range.left << "-" << range.right << " ol "; + cerr << p2 << ":" << range2.left << "-" << range2.right << endl; + } + } + } else { + if(range2.right <= range.left) { + if(!stored2) { + merge_list.expand(); + merge_list.back().first = numeric_limits::max(); + merge_list.back().second = p2; + + if(debug) { + cerr << p << ":" << range.left << "-" << range.right << " <> "; + cerr << p2 << ":" << range2.left << "-" << range2.right << endl; + } + } + } else { + assert_leq(range.right, range2.left); + if(!stored) { + merge_list.expand(); + merge_list.back().first = p; + merge_list.back().second = numeric_limits::max(); + + if(debug) { + cerr << p << ":" << range.left << "-" << range.right << " <> "; + cerr << p2 << ":" << range2.left << "-" << range2.right << endl; + } + } + } + } + } + if(range.right <= range2.right) p++; + if(range2.right <= range.right) p2++; + } + assert(p == seeds_.size() || p2 == o.seeds_.size()); + + while(p < seed_ranges_.size()) { + bool stored = !merge_list.empty() && merge_list.back().first == p; + if(!stored) { + const RB_AlleleCoord& range = seed_ranges_[p]; + merge_list.expand(); + merge_list.back().first = p; + merge_list.back().second = numeric_limits::max(); + + if(debug) { + cerr << p << ":" << range.left << "-" << range.right << " : <> " << endl; + } + } + + p++; + } + + while(p2 < o.seed_ranges_.size()) { + bool stored2 = !merge_list.empty() && merge_list.back().second == p2; + if(!stored2) { + const RB_AlleleCoord& range2 = o.seed_ranges_[p2]; + merge_list.expand(); + merge_list.back().first = numeric_limits::max(); + merge_list.back().second = p2; + + if(debug) { + cerr << ": <> " << p2 << ":" << range2.left << "-" << range2.right << endl; + } + } + + p2++; + } + + assert(!merge_list.empty()); + + if(debug) { + for(size_t i = 0; i < merge_list.size(); i++) { + cerr << "merge list:" << endl; + cerr << "\t" << (merge_list[i].first < seed_ranges_.size() ? (int)merge_list[i].first : -1); + cerr << " " << (merge_list[i].second < o.seed_ranges_.size() ? (int)merge_list[i].second : -1) << endl; + } + } + + const size_t kmer_len = 12; + EList > kmer_table; + build_kmer_table(consensus_, kmer_table, kmer_len); + EList offsets; + + bool self_repeat = isSelfRepeat(rp, + consensus_, + kmer_table, + offsets, + kmer_len, + debug); + if(self_repeat) { + consensus_ = prev_consensus; + return false; + } + + string seq; + for(size_t i = 0; i < merge_list.size(); i++) { + size_t seed_id = (merge_list[i].first < seed_ranges_.size() ? seed_ranges_[merge_list[i].first].idx : merge_list[i].first); + size_t oseed_id = (merge_list[i].second < o.seed_ranges_.size() ? o.seed_ranges_[merge_list[i].second].idx : merge_list[i].second); + + if(seed_id < seeds_.size()) { + if(oseed_id >= o.seeds_.size()) + continue; + else if(seed_ranges_[merge_list[i].first].contain(o.seed_ranges_[merge_list[i].second])) + continue; + } + + const SeedExt* seed = (seed_id < seeds_.size() ? &seeds_[seed_id] : NULL); + const SeedExt* oseed = (oseed_id < o.seeds_.size() ? &o.seeds_[oseed_id] : NULL); + assert(seed != NULL || oseed != NULL); + + size_t left = (seed != NULL ? seed->pos.first : numeric_limits::max()); + size_t right = (seed != NULL ? seed->pos.second : 0); + int consensus_approx_left = (seed != NULL ? seed->consensus_pos.first : numeric_limits::max()); + int consensus_approx_right = (seed != NULL ? seed->consensus_pos.second : 0); + if(oseed != NULL) { + if(oseed->pos.first < left) { + left = oseed->pos.first; + } + if(oseed->pos.second > right) { + right = oseed->pos.second; + } + + int oconsensus_approx_left = oseed->consensus_pos.first + consensus_add_len; + if(oconsensus_approx_left < consensus_approx_left) { + consensus_approx_left = oconsensus_approx_left; + } + int oconsensus_approx_right = oseed->consensus_pos.second + consensus_add_len; + if(oconsensus_approx_right > consensus_approx_right) { + consensus_approx_right = oconsensus_approx_right; + } + } + + getString(s, left, right - left, seq); + if(seed_id >= seeds_.size()) { + seed_id = seeds_.size(); + seeds_.expand(); + } + + /* bool succ = */ align(rp, + s, + consensus_, + kmer_table, + seq, + offsets, + kmer_len, + seeds_[seed_id], + consensus_approx_left, + consensus_approx_right, + left, + right, + debug && right - left == 1080); + } + + while(true) { + internal_update(); + + size_t remove_count = 0; + for(size_t i = 0; i + 1 < seed_ranges_.size(); i++) { + RB_AlleleCoord& range = seed_ranges_[i]; + if(range.left == numeric_limits::max()) + break; + for(size_t j = i + 1; j < seed_ranges_.size(); j++) { + RB_AlleleCoord& range2 = seed_ranges_[j]; + if(range2.left == numeric_limits::max()) + break; + if(range.right <= range2.left) + break; + + getString(s, range.left, range2.right - range.left, seq); + + /* bool succ = */ align(rp, + s, + consensus_, + kmer_table, + seq, + offsets, + kmer_len, + seeds_[range.idx], + seeds_[range.idx].consensus_pos.first, + seeds_[range2.idx].consensus_pos.second, + range.left, + range2.right, + debug && range.left == 692422); + + range.left = seeds_[range.idx].pos.first; + range.right = seeds_[range.idx].pos.second; + seeds_[range2.idx].reset(); + range2.left = numeric_limits::max(); + remove_count++; + } + } + + if(remove_count <= 0) break; + + sort(seeds_.begin(), seeds_.end(), seedCmp); + seeds_.resize(seeds_.size() - remove_count); + } + + return true; +} + +#define DMAX std::numeric_limits::max() + +RB_SWAligner::RB_SWAligner() +{ + rnd_.init(0); +} + +RB_SWAligner::~RB_SWAligner() +{ + if(sc_) { + delete sc_; + } +} + +void RB_SWAligner::init_dyn(const RepeatParameter& rp) +{ + const int MM_PEN = 3; + // const int MM_PEN = 6; + const int GAP_PEN_LIN = 2; + // const int GAP_PEN_LIN = (((MM_PEN) * rpt_edit_ + 1) * 1.0); + const int GAP_PEN_CON = 4; + // const int GAP_PEN_CON = (((MM_PEN) * rpt_edit_ + 1) * 1.0); + const int MAX_PEN = MAX_I16; + + scoreMin_.init(SIMPLE_FUNC_LINEAR, rp.max_edit * MM_PEN * -1.0, 0.0); + nCeil_.init(SIMPLE_FUNC_LINEAR, 0.0, 0.0); + + penCanIntronLen_.init(SIMPLE_FUNC_LOG, -8, 1); + penNoncanIntronLen_.init(SIMPLE_FUNC_LOG, -8, 1); + + sc_ = new Scoring( + DEFAULT_MATCH_BONUS, // constant reward for match + DEFAULT_MM_PENALTY_TYPE, // how to penalize mismatches + MM_PEN, // max mm penalty + MM_PEN, // min mm penalty + MAX_PEN, // max sc penalty + MAX_PEN, // min sc penalty + scoreMin_, // min score as function of read len + nCeil_, // max # Ns as function of read len + DEFAULT_N_PENALTY_TYPE, // how to penalize Ns in the read + DEFAULT_N_PENALTY, // constant if N pelanty is a constant + DEFAULT_N_CAT_PAIR, // whether to concat mates before N filtering + + + GAP_PEN_CON, // constant coeff for read gap cost + GAP_PEN_CON, // constant coeff for ref gap cost + GAP_PEN_LIN, // linear coeff for read gap cost + GAP_PEN_LIN, // linear coeff for ref gap cost + 1 /* gGapBarrier */ // # rows at top/bot only entered diagonally + ); +} + +void RB_SWAligner::makePadString(const string& ref, + const string& read, + string& pad, + size_t len) +{ + pad.resize(len); + + for(size_t i = 0; i < len; i++) { + // shift A->C, C->G, G->T, T->A + pad[i] = "CGTA"[asc2dna[ref[i]]]; + + if(read[i] == pad[i]) { + // shift + pad[i] = "CGTA"[asc2dna[pad[i]]]; + } + } + + int head_len = len / 2; + size_t pad_start = len - head_len; + + for(size_t i = 0; i < head_len; i++) { + if(read[i] == pad[pad_start + i]) { + // shift + pad[pad_start + i] = "CGTA"[asc2dna[pad[pad_start + i]]]; + } + } +} + +int RB_SWAligner::alignStrings(const string &ref, + const string &read, + EList& edits, + Coord& coord) +{ + // Prepare Strings + + // Read -> BTDnaString + // Ref -> bit-encoded string + + //SwAligner swa; + + BTDnaString btread; + BTString btqual; + BTString btref; + BTString btref2; + + BTDnaString btreadrc; + BTString btqualrc; + + + string qual = ""; + for(size_t i = 0; i < read.length(); i++) { + qual.push_back('I'); + } + +#if 0 + cerr << "REF : " << ref << endl; + cerr << "READ: " << read << endl; + cerr << "QUAL: " << qual << endl; +#endif + + btread.install(read.c_str(), true); + btreadrc = btread; + btreadrc.reverseComp(); + + btqual.install(qual.c_str()); + btqualrc = btqual; + + btref.install(ref.c_str()); + + TAlScore min_score = sc_->scoreMin.f((double)btread.length()); + + btref2 = btref; + + size_t nceil = 0; + // size_t nrow = btread.length(); + + // Convert reference string to mask + for(size_t i = 0; i < btref2.length(); i++) { + if(toupper(btref2[i]) == 'N') { + btref2.set(16, i); + } else { + int num = 0; + int alts[] = {4, 4, 4, 4}; + decodeNuc(toupper(btref2[i]), num, alts); + assert_leq(num, 4); + assert_gt(num, 0); + btref2.set(0, i); + for(int j = 0; j < num; j++) { + btref2.set(btref2[i] | (1 << alts[j]), i); + } + } + } + + + bool fw = true; + uint32_t refidx = 0; + + swa.initRead( + btread, // read sequence + btreadrc, + btqual, // read qualities + btqualrc, + 0, // offset of first character within 'read' to consider + btread.length(), // offset of last char (exclusive) in 'read' to consider + *sc_); // local-alignment score floor + + DynProgFramer dpframe(false); + size_t readgaps = 0; + size_t refgaps = 0; + size_t maxhalf = 0; + + DPRect rect; + dpframe.frameSeedExtensionRect( + 0, // ref offset implied by seed hit assuming no gaps + btread.length(), // length of read sequence used in DP table + btref2.length(), // length of reference + readgaps, // max # of read gaps permitted in opp mate alignment + refgaps, // max # of ref gaps permitted in opp mate alignment + (size_t)nceil, // # Ns permitted + maxhalf, // max width in either direction + rect); // DP Rectangle + + assert(rect.repOk()); + + size_t cminlen = 2000, cpow2 = 4; + + swa.initRef( + fw, // whether to align forward or revcomp read + refidx, // reference ID + rect, // DP rectangle + btref2.wbuf(), // reference strings + 0, // offset of first reference char to align to + btref2.length(), // offset of last reference char to align to + btref2.length(), // length of reference sequence + *sc_, // scoring scheme + min_score, // minimum score + true, // use 8-bit SSE if positions + cminlen, // minimum length for using checkpointing scheme + cpow2, // interval b/t checkpointed diags; 1 << this + false, // triangular mini-fills? + false // is this a seed extension? + ); + + + TAlScore best = std::numeric_limits::min(); + bool found = swa.align(rnd_, best); + +#ifdef DEBUGLOG + cerr << "found: " << found << "\t" << best << "\t" << "minsc: " << min_score << endl; +#endif + + if (found) { +#ifdef DEBUGLOG + //cerr << "CP " << "found: " << found << "\t" << best << "\t" << "minsc: " << min_score << endl; + cerr << "REF : " << ref << endl; + cerr << "READ: " << read << endl; +#endif + + SwResult res; + int max_match_len = 0; + res.reset(); + res.alres.init_raw_edits(&rawEdits_); + + found = swa.nextAlignment(res, best, rnd_); + if (found) { + edits = res.alres.ned(); + //const TRefOff ref_off = res.alres.refoff(); + //const Coord& coord = res.alres.refcoord(); + coord = res.alres.refcoord(); + //assert_geq(genomeHit._joinedOff + coord.off(), genomeHit.refoff()); + +#ifdef DEBUGLOG + cerr << "num edits: " << edits.size() << endl; + cerr << "coord: " << coord.off(); + cerr << ", " << coord.ref(); + cerr << ", " << coord.orient(); + cerr << ", " << coord.joinedOff(); + cerr << endl; + Edit::print(cerr, edits); cerr << endl; + Edit::printQAlign(cerr, btread, edits); +#endif + + max_match_len = getMaxMatchLen(edits, btread.length()); +#ifdef DEBUGLOG + cerr << "max match length: " << max_match_len << endl; +#endif + } +#ifdef DEBUGLOG + cerr << "nextAlignment: " << found << endl; + cerr << "-------------------------" << endl; +#endif + } + + return 0; +} + +void RB_SWAligner::doTest(const RepeatParameter& rp, + const string& refstr, + const string& readstr) +{ + init_dyn(rp); + + doTestCase1(refstr, + readstr, + rp.max_edit); +} + +void RB_SWAligner::doTestCase1(const string& refstr, + const string& readstr, + TIndexOffU rpt_edit) +{ + cerr << "doTestCase1----------------" << endl; + EList edits; + Coord coord; + + if (refstr.length() == 0 || + readstr.length() == 0) { + return; + } + + EList ed; + + string pad; + makePadString(refstr, readstr, pad, 5); + + string ref2 = pad + refstr + pad; + string read2 = pad + readstr + pad; + alignStrings(refstr, readstr, edits, coord); + + size_t left = pad.length(); + size_t right = left + readstr.length(); + + edits.reserveExact(ed.size()); + for(size_t i = 0; i < ed.size(); i++) { + if(ed[i].pos >= left && ed[i].pos <= right) { + edits.push_back(ed[i]); + edits.back().pos -= left; + } + } + + +#if 0 + RepeatGroup rg; + + rg.edits = edits; + rg.coord = coord; + rg.seq = readstr; + rg.base_offset = 0; + + string chr_name = "rep"; + + cerr << "REF : " << refstr << endl; + cerr << "READ: " << readstr << endl; + size_t snpids = 0; + rg.buildSNPs(snpids); + rg.writeSNPs(cerr, chr_name); cerr << endl; +#endif +} + + +template +RepeatBuilder::RepeatBuilder(TStr& s, + TStr& sOriginal, + const EList& szs, + const EList& ref_names, + bool forward_only, + const string& filename) : +s_(s), +sOriginal_(sOriginal), +coordHelper_(s.length(), forward_only ? s.length() : s.length() / 2, szs, ref_names), +forward_only_(forward_only), +filename_(filename), +forward_length_(forward_only ? s.length() : s.length() / 2) +{ + cerr << "RepeatBuilder: " << filename_ << endl; +} + +template +RepeatBuilder::~RepeatBuilder() +{ + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++) { + delete it->second; + } + repeat_map_.clear(); +} + +template +void RepeatBuilder::readSA(const RepeatParameter& rp, + BlockwiseSA& sa) +{ + TIndexOffU count = 0; + subSA_.init(s_.length() + 1, rp.min_repeat_len, rp.repeat_count); + + while(count < s_.length() + 1) { + TIndexOffU saElt = sa.nextSuffix(); + count++; + + if(count && (count % 10000000 == 0)) { + cerr << "SA count " << count << endl; + } + + if(saElt == s_.length()) { + assert_eq(count, s_.length() + 1); + break; + } + + subSA_.push_back(s_, coordHelper_, saElt, count == s_.length()); + } + + cerr << "subSA size is " << subSA_.size() << endl; + subSA_.dump(); +#if 0 + for(size_t i = 0; i < subSA_.size(); i++) { + TIndexOffU joinedOff = subSA_[i]; + fp << setw(10) << joinedOff << " " << getString(s_, joinedOff, rp.seed_len) << endl; + } +#endif + cerr << "subSA mem Usage: " << subSA_.getMemUsage() << endl << endl; +} + +template +void RepeatBuilder::readSA(const RepeatParameter &rp, + const BitPackedArray &sa) +{ + TIndexOffU count = 0; + + subSA_.init(s_.length() + 1, rp.min_repeat_len, rp.repeat_count); + + for(size_t i = 0; i < sa.size(); i++) { + TIndexOffU saElt = sa[i]; + count++; + + if(count && (count % 10000000 == 0)) { + cerr << "RB count " << count << endl; + } + + if(saElt == s_.length()) { + assert_eq(count, s_.length() + 1); + break; + } + + subSA_.push_back(s_, coordHelper_, saElt, count == s_.length()); + } + + cerr << "subSA size: " << endl; + subSA_.dump(); +#if 0 + for(size_t i = 0; i < subSA_.size(); i++) { + TIndexOffU joinedOff = subSA_[i]; + fp << setw(10) << joinedOff << " " << getString(s_, joinedOff, rp.seed_len) << endl; + } +#endif + cerr << "subSA mem Usage: " << subSA_.getMemUsage() << endl << endl; +} + +template +void RepeatBuilder::build(const RepeatParameter& rp) +{ + string rpt_len_str; + rpt_len_str = to_string(rp.min_repeat_len) + "-" + to_string(rp.max_repeat_len); + + string seed_filename = filename_ + ".rep." + rpt_len_str + ".seed"; + ofstream fp(seed_filename.c_str()); + + swaligner_.init_dyn(rp); + + RB_RepeatManager* repeat_manager = new RB_RepeatManager; + + EList repeatBases; + subSA_.buildRepeatBase(s_, + coordHelper_, + rp.max_repeat_len, + repeatBases); + + size_t repeat_id = 0; + for(size_t i = 0; i < repeatBases.size(); i++) { + addRepeatGroup(rp, + repeat_id, + *repeat_manager, + repeatBases[i], + fp); + } + + { + // Build and test minimizer-based k-mer table + const size_t window = RB_Minimizer::default_w; + const size_t k = RB_Minimizer::default_k; + RB_KmerTable kmer_table; + EList seqs; + seqs.reserveExact(repeat_map_.size()); + for(map::const_iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++) { + const RB_Repeat& repeat = *(it->second); + assert(repeat.satisfy(rp)); + seqs.expand(); + seqs.back() = repeat.consensus(); + } + kmer_table.build(seqs, + window, + k); + kmer_table.dump(cerr); + cerr << endl; + + string query, rc_query; + string queryOriginal; + EList > minimizers; + size_t total = 0, num_repeat = 0, correct = 0, false_positive = 0, false_negative = 0; + for(size_t i = 0; i + rp.min_repeat_len <= forward_length_; i += 1000) { + if(coordHelper_.getEnd(i) != coordHelper_.getEnd(i + rp.min_repeat_len)) + continue; + query = getString(s_, i, rp.min_repeat_len); + queryOriginal = getString(sOriginal_, i, rp.min_repeat_len); + rc_query = reverseComplement(queryOriginal); + + TIndexOffU idx = subSA_.find_repeat_idx(s_, query); + const EList& test_repeat_index = subSA_.getRepeatIndex(); + bool repeat = (idx < test_repeat_index.size()); + bool est_repeat = kmer_table.isRepeat(query, + rc_query, + minimizers); + + total++; + if(repeat) num_repeat++; + if(repeat == est_repeat) { + correct++; + } else { + if(est_repeat) { + false_positive++; + } else { + false_negative++; + //assert(false); + } + } + } + + cerr << "total: " << total << endl; + cerr << "repeat: " << num_repeat << endl; + cerr << "correct: " << correct << endl; + cerr << "false positive: " << false_positive << endl; + cerr << "false negative: " << false_negative << endl; + cerr << endl; + + ELList position2D; EList alignments; + size_t repeat_total = 0, repeat_aligned = 0; + const EList& test_repeat_index = subSA_.getRepeatIndex(); + size_t interval = 1; + if(test_repeat_index.size() >= 1000) { + interval = test_repeat_index.size() / 1000; + } + size_t total_alignments = 0, max_alignments = 0; + string query2, rc_query2; + string queryOriginal2, rc_queryOriginal2; + for(size_t i = 0; i < test_repeat_index.size(); i += interval) { + TIndexOffU saElt_idx = test_repeat_index[i]; + TIndexOffU saElt_idx_end = (i + 1 < test_repeat_index.size() ? test_repeat_index[i+1] : subSA_.size()); + TIndexOffU saElt_size = saElt_idx_end - saElt_idx; + TIndexOffU saElt = subSA_[saElt_idx]; + query = getString(s_, saElt, rp.min_repeat_len); + query2 = query; + + queryOriginal = getString(sOriginal_, saElt, rp.min_repeat_len); + queryOriginal2 = queryOriginal; + + // introduce three mismatches into a query when the query is at lest 100-bp + if(rp.min_repeat_len >= 100) { + const size_t mid_pos1 = (size_t)(rp.min_repeat_len * 0.1); + if(query2[mid_pos1] == 'A') { + query2[mid_pos1] = 'C'; + queryOriginal2[mid_pos1] ='C'; + } else { + query2[mid_pos1] = 'A'; + queryOriginal2[mid_pos1] = 'A'; + } + const size_t mid_pos2 = (size_t)(rp.min_repeat_len * 0.5); + if(query2[mid_pos2] == 'C') { + query2[mid_pos2] = 'G'; + queryOriginal2[mid_pos2] = 'G'; + } else { + query2[mid_pos2] = 'C'; + queryOriginal2[mid_pos1] = 'G'; + } + const size_t mid_pos3 = (size_t)(rp.min_repeat_len * 0.9); + if(query2[mid_pos3] == 'G') { + query2[mid_pos3] = 'T'; + queryOriginal2[mid_pos3] = 'T'; + } else { + query2[mid_pos3] = 'G'; + queryOriginal2[mid_pos3] = 'G'; + } + } + + repeat_total += saElt_size; + + size_t found = 0; + size_t cur_alignments = 0; + if(kmer_table.isRepeat(query2, minimizers)) { + kmer_table.findAlignments(query2, + minimizers, + position2D, + alignments); + total_alignments += (alignments.size() * saElt_size); + cur_alignments = alignments.size(); + TIndexOffU baseoff = 0; + for(size_t s = 0; s < seqs.size(); s++) { + int spos = seqs[s].find(query); + if(spos != string::npos) { + for(size_t a = 0; a < alignments.size(); a++) { + if(alignments[a].pos == baseoff + spos) { + found++; + } + } + } + baseoff += seqs[s].length(); + } + + assert_leq(found, 1); + } + + rc_query = reverseComplement(queryOriginal); + rc_query2 = reverseComplement(queryOriginal2); + size_t rc_found = 0; + if(kmer_table.isRepeat(rc_query2, minimizers)) { + kmer_table.findAlignments(rc_query2, + minimizers, + position2D, + alignments); + total_alignments += (alignments.size() * saElt_size); + cur_alignments += alignments.size(); + if(cur_alignments > max_alignments) { + max_alignments = cur_alignments; + } + + TIndexOffU baseoff = 0; + for(size_t s = 0; s < seqs.size(); s++) { + int spos = seqs[s].find(rc_query); + if(spos != string::npos) { + for(size_t a = 0; a < alignments.size(); a++) { + if(alignments[a].pos == baseoff + spos) { + rc_found++; + } + } + } + baseoff += seqs[s].length(); + } + assert_leq(rc_found, 1); + } + + if(found + rc_found == 1) { + repeat_aligned += saElt_size; + } + } + + cerr << "num repeats: " << repeat_total << endl; + cerr << "repeat aligned using minimizers: " << repeat_aligned << endl; + cerr << "average number of alignments: " << (float)total_alignments / repeat_total << endl; + cerr << "max alignment: " << max_alignments << endl; + cerr << endl; + } + + cerr << "number of repeats is " << repeat_map_.size() << endl; + + size_t total_rep_seq_len = 0, total_allele_seq_len = 0; + size_t i = 0; + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++, i++) { + RB_Repeat& repeat = *(it->second); + if(!repeat.satisfy(rp)) + continue; + + repeat.saveSeedExtension(rp, + s_, + coordHelper_, + i, + fp, + total_rep_seq_len, + total_allele_seq_len); + } + + size_t total_qual_seeds = 0; + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++, i++) { + RB_Repeat& repeat = *(it->second); + EList& seeds = repeat.seeds(); + for(size_t i = 0; i < seeds.size(); i++) { + if(seeds[i].getLength() < rp.min_repeat_len) + continue; + total_qual_seeds++; + } + } + + cerr << "total repeat sequence length: " << total_rep_seq_len << endl; + cerr << "total allele sequence length: " << total_allele_seq_len << endl; + cerr << "total number of seeds including those that are position-wise different, but sequence-wise identical: " << total_qual_seeds << endl; + cerr << endl; + fp << "total repeat sequence length: " << total_rep_seq_len << endl; + fp << "total allele sequence length: " << total_allele_seq_len << endl; + fp << "total number of seeds including those that are position-wise different, but sequence-wise identical: " << total_qual_seeds << endl; + fp.close(); + + delete repeat_manager; + repeat_manager = NULL; + + // remove non-qualifying repeats + // and update repeat IDs for those remaining + { + map temp_repeat_map; + size_t i = 0; + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++) { + RB_Repeat* repeat = it->second; + if(!repeat->satisfy(rp)) { + delete repeat; + continue; + } + repeat->repeat_id(i); + temp_repeat_map[repeat->repeat_id()] = repeat; + i++; + } + repeat_map_ = temp_repeat_map; + } + + const bool sanity_check = true; + if(sanity_check) { + EList > kmer_table; + string query; + string queryOriginal; + size_t total = 0, match = 0; + EList positions; + const EList& test_repeat_index = subSA_.getRepeatIndex(); + size_t interval = 1; + if(test_repeat_index.size() >= 10000) { + interval = test_repeat_index.size() / 10000; + } + for(size_t i = 0; i < test_repeat_index.size(); i += interval) { + TIndexOffU saElt_idx = test_repeat_index[i]; + TIndexOffU saElt_idx_end = (i + 1 < test_repeat_index.size() ? test_repeat_index[i+1] : subSA_.size()); + positions.clear(); + for(size_t j = saElt_idx; j < saElt_idx_end; j++) { + positions.push_back(subSA_[j]); +#ifndef NDEBUG + if(j > saElt_idx) { + TIndexOffU lcp_len = getLCP(s_, + coordHelper_, + positions[0], + positions.back(), + rp.min_repeat_len); + assert_eq(lcp_len, rp.min_repeat_len); + } + + TIndexOffU saElt = subSA_[j]; + TIndexOffU start = coordHelper_.getStart(saElt); + TIndexOffU start2 = coordHelper_.getStart(saElt + rp.min_repeat_len - 1); + assert_eq(start, start2); +#endif + } + + TIndexOffU saElt = subSA_[saElt_idx]; + size_t true_count = saElt_idx_end - saElt_idx; + getString(s_, saElt, rp.min_repeat_len, query); + getString(sOriginal_, saElt, rp.min_repeat_len, queryOriginal); + total++; + + size_t count = 0, rc_count = 0; + string rc_query = reverse_complement(queryOriginal); + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++) { + RB_Repeat& repeat = *(it->second); + int pos = repeat.consensus().find(query); + if(pos != string::npos) { + for(size_t s = 0; s < repeat.seeds().size(); s++) { + SeedExt& seed = repeat.seeds()[s]; + string seq; + seed.getExtendedSeedSequence(s_, seq); + if(seq.find(query) != string::npos) + count++; + } + } + pos = repeat.consensus().find(rc_query); + if(pos != string::npos) { + for(size_t s = 0; s < repeat.seeds().size(); s++) { + SeedExt& seed = repeat.seeds()[s]; + string seq; + seed.getExtendedSeedSequence(s_, seq); + if(seq.find(rc_query) != string::npos) + rc_count++; + } + } + } + + if(count == true_count || rc_count == true_count) { + match++; + } else if(total - match <= 10) { + cerr << " query: " << query << endl; + cerr << "rc_query: " << rc_query << endl; + cerr << "true count: " << true_count << endl; + cerr << "found count: " << count << endl; + cerr << "rc found count: " << rc_count << endl; + cerr << endl; + } + } + + cerr << "RepeatBuilder: sanity check: " << match << " passed (out of " << total << ")" << endl << endl; + } +} + +template +void RepeatBuilder::writeHaploType(const EList& haplo_lists, + const EList& seeds, + TIndexOffU& hapl_id_base, + const string& seq_name, + ostream &fp) +{ + if(haplo_lists.size() == 0) { + return; + } + + for(size_t i = 0; i < haplo_lists.size(); i++) { + const SeedHP &haploType = haplo_lists[i]; + + fp << "rpht" << hapl_id_base++; + fp << "\t" << seq_name; + fp << "\t" << haploType.range.first; + fp << "\t" << haploType.range.second; + fp << "\t"; + + assert_gt(haploType.snpIDs.size(), 0); + + for (size_t j = 0; j < haploType.snpIDs.size(); j++) { + if(j) { + fp << ","; + } + fp << haploType.snpIDs[j]; + } + fp << endl; + } +} + +template +void RepeatBuilder::writeAllele(TIndexOffU grp_id, + TIndexOffU allele_id, + Range range, + const string& seq_name, + TIndexOffU baseoff, + const EList& seeds, + ostream &fp) +{ + // >rpt_name*0\trep\trep_pos\trep_len\tpos_count\t0 + // chr_name:pos:direction chr_name:pos:direction + // + // >rep1*0 rep 0 100 470 0 + // 22:112123123:+ 22:1232131113:+ + // + size_t snp_size = seeds[range.first].snps.size(); + size_t pos_size = range.second - range.first; + fp << ">"; + fp << "rpt_" << grp_id << "*" << allele_id; + fp << "\t" << seq_name; + fp << "\t" << baseoff + seeds[range.first].consensus_pos.first; + fp << "\t" << seeds[range.first].consensus_pos.second - seeds[range.first].consensus_pos.first; + fp << "\t" << pos_size; + fp << "\t" << snp_size; + + fp << "\t"; + for(size_t i = 0; i < snp_size; i++) { + if(i > 0) {fp << ",";} + fp << "rps" << seeds[range.first].snps[i]->id; + } + fp << endl; + + // print positions + for(size_t i = 0; i < pos_size; i++) { + if(i > 0 && (i % 10 == 0)) { + fp << endl; + } + + if(i % 10 != 0) { + fp << " "; + } + string chr_name; + TIndexOffU pos_in_chr; + TIndexOffU joinedOff = seeds[range.first + i].pos.first; + + bool fw = true; + if(joinedOff < forward_length_) { + fw = true; + } else { + fw = false; + joinedOff = s_.length() - joinedOff - seeds[range.first].getLength(); + } + + coordHelper_.getGenomeCoord(joinedOff, chr_name, pos_in_chr); + + char direction = fw ? '+' : '-'; + fp << chr_name << ":" << pos_in_chr << ":" << direction; + } + + fp << endl; +} + +template +void RepeatBuilder::writeSNPs(ostream& fp, + const string& rep_chr_name, + const ESet& editset) +{ + for(size_t i = 0; i < editset.size(); i++) { + const Edit& ed = editset[i]; + + if(ed.isMismatch()) { + fp << "rps" << ed.snpID; + fp << "\t" << "single"; + fp << "\t" << rep_chr_name; + fp << "\t" << ed.pos; + fp << "\t" << ed.qchr; + fp << endl; + } else { + assert(false); + } + } +} + + +template +void RepeatBuilder::saveFile(const RepeatParameter& rp) +{ + saveRepeats(rp); +} + +bool RB_RepeatManager::checkRedundant(const RepeatParameter& rp, + const map& repeat_map, + const EList& positions, + EList& to_remove) const +{ + to_remove.clear(); + bool replace = false; + for(size_t i = 0; i < positions.size(); i++) { + TIndexOffU seed_pos = positions[i]; + Range seed_range(seed_pos + rp.seed_len, 0); + map >::const_iterator it = range_to_repeats_.upper_bound(seed_range); + if(it == range_to_repeats_.end()) + continue; + + for(map >::const_reverse_iterator rit(it); rit != range_to_repeats_.rend(); rit++) { + Range repeat_range = rit->first; + if(repeat_range.first + rp.max_repeat_len <= seed_pos) + break; + + const EList& repeat_ids = rit->second; + assert_gt(repeat_ids.size(), 0); + for(size_t r = 0; r < repeat_ids.size(); r++) { + size_t repeat_id = repeat_ids[r]; + size_t idx = to_remove.bsearchLoBound(repeat_id); + if(idx < to_remove.size() && to_remove[idx] == repeat_id) + continue; + + bool overlap = seed_pos < repeat_range.second && seed_pos + rp.seed_len > repeat_range.first; + if(!overlap) + continue; + + map::const_iterator it2 = repeat_map.find(repeat_id); + assert(it2 != repeat_map.end()); + const RB_Repeat& repeat = *(it2->second); + const EList& allele_ranges = repeat.seed_ranges(); + size_t num_contain = 0, num_overlap = 0, num_close = 0, num_overlap_bp = 0; + size_t p = 0, p2 = 0; + while(p < positions.size() && p2 < allele_ranges.size()) { + RB_AlleleCoord range; + range.left = positions[p]; + range.right = positions[p] + rp.seed_len; + RB_AlleleCoord range2 = allele_ranges[p2]; + if(range2.contain(range)) { + num_contain++; + num_overlap_bp += rp.seed_len; + } else { + TIndexOffU overlap = range2.overlap_len(range); + if(overlap > 0) { + num_overlap++; + num_overlap_bp += (range2.right - range.left); + } else if(range.right + 10 > range2.left && range2.right + 10 > range.left) { + num_close++; + } + } + if(range.right <= range2.right) p++; + else p2++; + } + + // if the number of matches is >= 90% of positions in the smaller group + if((num_contain + num_overlap) * 10 + num_close * 8 >= min(positions.size(), allele_ranges.size()) * 9) { + if(positions.size() <= allele_ranges.size()) { + return true; + } else { + replace = true; + to_remove.push_back(repeat_id); + to_remove.sort(); + } + } + } + } + + // DK - check this out + if(replace) + break; + } + return false; +} + +void RB_RepeatManager::addRepeat(const RB_Repeat* repeat) +{ + const EList& allele_ranges = repeat->seed_ranges(); + for(size_t i = 0; i < allele_ranges.size(); i++) { + Range allele_range(allele_ranges[i].left, allele_ranges[i].right); + addRepeat(allele_range, repeat->repeat_id()); + } +} + +void RB_RepeatManager::addRepeat(Range range, size_t repeat_id) +{ + if(range_to_repeats_.find(range) == range_to_repeats_.end()) { + range_to_repeats_[range] = EList(); + } + EList& repeat_ids = range_to_repeats_[range]; + size_t idx = repeat_ids.bsearchLoBound(repeat_id); + if(idx < repeat_ids.size() && repeat_ids[idx] == repeat_id) + return; + repeat_ids.push_back(repeat_id); + repeat_ids.sort(); +} + +void RB_RepeatManager::removeRepeat(const RB_Repeat* repeat) +{ + const EList& allele_ranges = repeat->seed_ranges(); + for(size_t p = 0; p < allele_ranges.size(); p++) { + Range range(allele_ranges[p].left, allele_ranges[p].right); + removeRepeat(range, repeat->repeat_id()); + } +} + +void RB_RepeatManager::removeRepeat(Range range, size_t repeat_id) +{ + EList& repeat_ids = range_to_repeats_[range]; + TIndexOffU idx = repeat_ids.bsearchLoBound(repeat_id); + if(idx < repeat_ids.size() && repeat_id == repeat_ids[idx]) { + repeat_ids.erase(idx); + if(repeat_ids.empty()) + range_to_repeats_.erase(range); + } +} + +void RB_RepeatManager::showInfo(const RepeatParameter& rp, + CoordHelper& coordHelper, + const map& repeat_map, + size_t num_case) const +{ + size_t count = 0; + for(map >::const_iterator it = range_to_repeats_.begin(); + it != range_to_repeats_.end(); it++) { + const Range& range = it->first; + if(range.second - range.first < rp.min_repeat_len) continue; + map >::const_iterator jt = it; jt++; + for(; jt != range_to_repeats_.end(); jt++) { + const Range& range2 = jt->first; + if(range2.second - range2.first < rp.min_repeat_len) continue; + if(range.second <= range2.first) + break; + if(count < num_case) { + cerr << "range (" << range.first << ", " << range.second << ") vs. range2 ("; + cerr << range2.first << ", " << range2.second << ")" << endl; + for(size_t i = 0; i < it->second.size(); i++) { + cerr << "\t1 " << it->second[i] << endl; + const RB_Repeat* repeat = repeat_map.find(it->second[i])->second; + repeat->showInfo(rp, coordHelper); + } + for(size_t i = 0; i < jt->second.size(); i++) { + cerr << "\t2 " << jt->second[i] << endl; + const RB_Repeat* repeat = repeat_map.find(jt->second[i])->second; + repeat->showInfo(rp, coordHelper); + } + cerr << endl << endl; + } + count++; + } + } + cerr << "ShowInfo - count: " << count << endl; +} + +template +void RepeatBuilder::reassignSeeds(const RepeatParameter& rp, + size_t repeat_bid, // repeat begin id + size_t repeat_eid, // repeat end id + EList& seeds) +{ + assert_lt(repeat_bid, repeat_eid); + EList updated; + updated.resizeExact(repeat_eid - repeat_bid); + updated.fillZero(); + + string seq; + for(size_t s = 0; s < seeds.size(); s++) { + SeedExt& seed = seeds[s]; + size_t max_repeat_id = repeat_bid; + size_t max_ext_len = 0; + for(size_t i = repeat_bid; i < repeat_eid; i++) { + map::iterator it = repeat_map_.find(i); + assert(it != repeat_map_.end()); + const RB_Repeat& repeat = *(it->second); + const string& consensus = repeat.consensus(); + const size_t ext_len = (consensus.length() - rp.seed_len) / 2; + + if(seed.bound.first + ext_len > seed.pos.first) + continue; + if(seed.pos.second + ext_len > seed.bound.second) + continue; + + getString(s_, seed.pos.first - ext_len, rp.seed_len + ext_len * 2, seq); + assert_eq(consensus.length(), seq.length()); + size_t tmp_ext_len = 0; + for(size_t j = 0; j < ext_len; j++, tmp_ext_len++) { + if(seq[ext_len - j - 1] != consensus[ext_len - j - 1] || + seq[ext_len + rp.seed_len + j] != consensus[ext_len + rp.seed_len + j]) { + break; + } + } + + if(tmp_ext_len > max_ext_len) { + max_repeat_id = i; + max_ext_len = tmp_ext_len; + } + } + if(rp.seed_len + max_ext_len * 2 >= rp.min_repeat_len) { + seed.pos.first -= max_ext_len; + seed.pos.second += max_ext_len; + map::iterator it = repeat_map_.find(max_repeat_id); + assert(it != repeat_map_.end()); + RB_Repeat& repeat = *(it->second); + const string& consensus = repeat.consensus(); + const size_t ext_len = (consensus.length() - rp.seed_len) / 2; + assert_leq(max_ext_len, ext_len); + seed.consensus_pos.first = ext_len - max_ext_len; + seed.consensus_pos.second = consensus.length() - (ext_len - max_ext_len); + assert_leq(seed.consensus_pos.second - seed.consensus_pos.first, consensus.length()); + repeat.addSeed(seed); + updated[max_repeat_id - repeat_bid] = true; + } + } + + for(size_t i = repeat_bid; i < repeat_eid; i++) { + if(!updated[i - repeat_bid]) + continue; + map::iterator it = repeat_map_.find(i); + assert(it != repeat_map_.end()); + RB_Repeat& repeat = *(it->second); + repeat.update(); + } +} + +/** + * TODO + * @brief + * + * @param rpt_seq + * @param rpt_range + */ +template +void RepeatBuilder::addRepeatGroup(const RepeatParameter& rp, + size_t& repeat_id, + RB_RepeatManager& repeat_manager, + const RB_RepeatBase& repeatBase, + ostream& fp) +{ + RB_Repeat* repeat = new RB_Repeat; + repeat->repeat_id(repeat_id); + repeat->init(rp, + s_, + coordHelper_, + subSA_, + repeatBase); + + assert(repeat_map_.find(repeat->repeat_id()) == repeat_map_.end()); + repeat_map_[repeat->repeat_id()] = repeat; + repeat_id++; +} + +template +bool RepeatBuilder::checkSequenceMergeable(const string& ref, + const string& read, + EList& edits, + Coord& coord, + TIndexOffU rpt_len, + TIndexOffU max_edit) +{ + size_t max_matchlen = 0; + EList ed; + + string pad; + swaligner_.makePadString(ref, read, pad, 5); + + string ref2 = pad + ref; + string read2 = pad + read; + + swaligner_.alignStrings(ref2, read2, ed, coord); + + // match should start from pad string + if(coord.off() != 0) { + return false; + } + + // no edits on pad string + if(ed.size() > 0 && ed[0].pos < pad.length()) { + return false; + } + + size_t left = pad.length(); + size_t right = left + read.length(); + + edits.clear(); + edits.reserveExact(ed.size()); + for(size_t i = 0; i < ed.size(); i++) { + if(ed[i].pos >= left && ed[i].pos <= right) { + edits.push_back(ed[i]); + edits.back().pos -= left; + } + } + + max_matchlen = getMaxMatchLen(edits, read.length()); + +#ifdef DEBUGLOG + { + cerr << "After pad removed" << endl; + BTDnaString btread; + btread.install(read.c_str(), true); + Edit::print(cerr, edits); cerr << endl; + Edit::printQAlign(cerr, btread, edits); + } +#endif + + return (max_matchlen >= rpt_len); +} + + +template +void RepeatBuilder::saveRepeats(const RepeatParameter &rp) +{ + ios_base::openmode mode = ios_base::out; + if(rp.append_result) { + mode |= ios_base::app; + } else { + mode |= ios_base::trunc; + } + // Generate SNPs + size_t i = 0; + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++, i++) { + RB_Repeat& repeat = *(it->second); + if(!repeat.satisfy(rp)) + continue; + + // for each repeats + repeat.generateSNPs(rp, s_, i); + } + + // save snp, consensus sequenuce, info + string snp_fname = filename_ + ".rep.snp"; + string info_fname = filename_ + ".rep.info"; + string hapl_fname = filename_ + ".rep.haplotype"; + + ofstream snp_fp(snp_fname.c_str(), mode); + ofstream info_fp(info_fname.c_str(), mode); + ofstream hapl_fp(hapl_fname.c_str(), mode); + + const string repName = "rep" + to_string(rp.min_repeat_len) + "-" + to_string(rp.max_repeat_len); + + i = 0; + TIndexOffU consensus_baseoff = 0; + TIndexOffU snp_id_base = 0; + TIndexOffU hapl_id_base = 0; + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++, i++) { + RB_Repeat& repeat = *(it->second); + if(!repeat.satisfy(rp)) + continue; + + // for each repeats + repeat.saveSNPs(snp_fp, i, snp_id_base); + saveAlleles(rp, + repName, + repeat, + info_fp, + hapl_fp, + i, + hapl_id_base, + consensus_baseoff); + + consensus_baseoff += repeat.consensus().length(); + } + + snp_fp.close(); + info_fp.close(); + hapl_fp.close(); + + // save all consensus sequence + saveConsensus(rp, repName); +} + +template +void RepeatBuilder::saveConsensus(const RepeatParameter &rp, + const string& repName) { + ios_base::openmode mode = ios_base::out; + if(rp.append_result) { + mode |= ios_base::app; + } else { + mode |= ios_base::trunc; + } + + string fa_fname = filename_ + ".rep.fa"; + ofstream fa_fp(fa_fname.c_str(), mode); + + fa_fp << ">" << repName << endl; + + size_t oskip = 0; + for(map::iterator it = repeat_map_.begin(); it != repeat_map_.end(); it++) { + RB_Repeat& repeat = *(it->second); + if(!repeat.satisfy(rp)) + continue; + + // for each repeats + const string& constr = repeat.consensus(); + size_t si = 0; + size_t constr_len = constr.length(); + while(si < constr_len) { + size_t out_len = std::min((size_t)(output_width - oskip), (size_t)(constr_len - si)); + fa_fp << constr.substr(si, out_len); + + if((oskip + out_len) == output_width) { + fa_fp << endl; + oskip = 0; + } else { + // last line + oskip = oskip + out_len; + } + + si += out_len; + } + } + if(oskip) { + fa_fp << endl; + } + + fa_fp.close(); +} + +template +void RepeatBuilder::saveAlleles( + const RepeatParameter& rp, + const string& repName, + RB_Repeat& repeat, + ofstream& fp, + ofstream& hapl_fp, + TIndexOffU grp_id, + TIndexOffU& hapl_id_base, + TIndexOffU baseoff) +{ + const EList& seeds = repeat.seeds(); + EList haplo_lists; + Range range(0, seeds.size()); + + int allele_id = 0; + + for(size_t sb = range.first; sb < range.second;) { + size_t se = sb + 1; + for(; se < range.second; se++) { + if(!(SeedExt::isSameConsensus(seeds[sb], seeds[se]) + && SeedExt::isSameSNPs(seeds[sb], seeds[se]) + && seeds[sb].aligned == seeds[se].aligned)) { + break; + } + } + + if(!seeds[sb].aligned) { + sb = se; + continue; + } + + if(seeds[sb].getLength() < rp.min_repeat_len) { + sb = se; + continue; + } + + // [sb, se) are same alleles + writeAllele(grp_id, allele_id, Range(sb, se), + repName, baseoff, seeds, fp); + generateHaploType(Range(sb, se), seeds, haplo_lists); + + allele_id++; + sb = se; + } + + // sort HaploType List by pos + haplo_lists.sort(); + writeHaploType(haplo_lists, seeds, hapl_id_base, repName, hapl_fp); +} + +template +void RepeatBuilder::generateHaploType(Range range, const EList &seeds, EList &haplo_list) +{ + const EList& snps = seeds[range.first].snps; + if(snps.size() == 0) + return; + + // right-most position + TIndexOffU max_right_pos = seeds[range.first].consensus_pos.second - 1; + +#ifndef NDEBUG + for(size_t i = 0; i < snps.size(); i++) { + assert_leq(snps[i]->pos, max_right_pos); + } +#endif + + // create haplotypes of at least 16 bp long to prevent combinations of SNPs + // break a list of SNPs into several haplotypes if a SNP is far from the next SNP in the list + const TIndexOffU min_ht_len = 16; + size_t eb = 0, ee = 1; + while(ee < snps.size() + 1) { + if(ee == snps.size() || + snps[eb]->pos + (min_ht_len << 1) < snps[ee]->pos) { + TIndexOffU left_pos = snps[eb]->pos; + TIndexOffU right_pos = snps[ee-1]->pos; + + if(snps[ee-1]->type == EDIT_TYPE_READ_GAP) { + right_pos += snps[ee-1]->len; + } + if(left_pos + min_ht_len - 1 > right_pos) { + right_pos = left_pos + min_ht_len - 1; + } + right_pos = min(max_right_pos, right_pos); + assert_leq(left_pos, right_pos); + + SeedHP seedHP; + + seedHP.range.first = left_pos; + seedHP.range.second = right_pos; + for(size_t i = eb; i < ee; i++) { + string snp_ids = "rps" + to_string(snps[i]->id); + seedHP.snpIDs.push_back(snp_ids); + } + + // Add to haplo_list + bool found = false; + for(size_t i = 0; i < haplo_list.size(); i++) { + if(haplo_list[i] == seedHP) { + found = true; + break; + } + } + if(!found) { + // Add + haplo_list.push_back(seedHP); + } + + eb = ee; + } + ee++; + } +} + + +void RB_SubSA::init(TIndexOffU sa_size, + TIndexOffU seed_len, + TIndexOffU seed_count) +{ + assert_gt(sa_size, 1); + sa_size_ = sa_size; + assert_gt(seed_len, 0); + seed_len_ = seed_len; + assert_gt(seed_count, 1); + seed_count_ = seed_count; + temp_suffixes_.clear(); + + repeat_list_.clear(); + repeat_index_.clear(); +} + +template +void RB_SubSA::push_back(const TStr& s, + CoordHelper& coordHelper, + TIndexOffU saElt, + bool lastInput) +{ + if(saElt + seed_len() <= coordHelper.getEnd(saElt)) { + if(seed_count_ == 1) { + repeat_list_.push_back(saElt); + } else { + assert_gt(seed_count_, 1); + + if(temp_suffixes_.empty()) { + temp_suffixes_.push_back(saElt); + return; + } + + TIndexOffU prev_saElt = temp_suffixes_.back(); + + // calculate common prefix length between two text. + // text1 is started from prev_saElt and text2 is started from saElt + bool same = isSameSequenceUpto(s, + coordHelper, + prev_saElt, + saElt, + seed_len_); + + if(same) { + temp_suffixes_.push_back(saElt); + } + + if(!same || lastInput) { + if(temp_suffixes_.size() >= seed_count_) { + repeat_index_.push_back(repeat_list_.size()); + temp_suffixes_.sort(); + for(size_t pi = 0; pi < temp_suffixes_.size(); pi++) { + repeat_list_.push_back(temp_suffixes_[pi]); + } + } + temp_suffixes_.clear(); + if(!lastInput) { + temp_suffixes_.push_back(saElt); + } else { + temp_suffixes_.nullify(); + } + } + } + } + + if(lastInput) { + size_t bit = sizeof(uint32_t) * 8; + size_t num = (repeat_list_.size() + bit - 1) / bit; + done_.resizeExact(num); + done_.fillZero(); + +#ifndef NDEBUG + string prev_seq = ""; + for(size_t i = 0; i < repeat_index_.size(); i++) { + TIndexOffU saBegin = repeat_index_[i]; + TIndexOffU saEnd = (i + 1 < repeat_index_.size() ? repeat_index_[i+1] : repeat_list_.size()); + string seq = getString(s, repeat_list_[saBegin], seed_len()); + for(size_t j = saBegin + 1; j < saEnd; j++) { + string tmp_seq = getString(s, repeat_list_[j], seed_len()); + assert_eq(seq, tmp_seq); + } + if(prev_seq != "" ) { + assert_lt(prev_seq, seq); + } + prev_seq = seq; + } +#endif + } +} + +template +Range RB_SubSA::find(const TStr& s, + const string& seq) const +{ + TIndexOffU i = find_repeat_idx(s, seq); + if(i >= repeat_index_.size()) + return Range(0, 0); + + Range range(repeat_index_[i], + i + 1 < repeat_index_.size() ? repeat_index_[i+1] : repeat_list_.size()); + return range; +} + +template +TIndexOffU RB_SubSA::find_repeat_idx(const TStr& s, + const string& seq) const +{ + assert_eq(seq.length(), seed_len_); + + string temp; + size_t l = 0, r = repeat_index_.size(); + while(l < r) { + size_t m = (r + l) >> 1; + TIndexOffU saElt = repeat_list_[repeat_index_[m]]; + getString(s, saElt, seed_len_, temp); + if(seq == temp) { + return m; + } else if(seq < temp) { + r = m; + } else { + assert(seq > temp); + l = m + 1; + } + } + return repeat_index_.size(); +} + +void RB_SubSA::setDone(TIndexOffU off, TIndexOffU len) +{ + assert_leq(off + len, repeat_list_.size()); + const TIndexOffU bit = sizeof(uint32_t) * 8; + for(TIndexOffU i = off; i < off + len; i++) { + TIndexOffU quotient = i / bit; + TIndexOffU remainder = i % bit; + assert_lt(quotient, done_.size()); + uint32_t num = done_[quotient]; + num = num | (1 << remainder); + done_[quotient] = num; + } +} + +bool RB_SubSA::isDone(TIndexOffU off, TIndexOffU len) const +{ + assert_leq(off + len, repeat_list_.size()); + const TIndexOffU bit = sizeof(uint32_t) * 8; + for(TIndexOffU i = off; i < off + len; i++) { + TIndexOffU quotient = i / bit; + TIndexOffU remainder = i % bit; + assert_lt(quotient, done_.size()); + uint32_t num = done_[quotient]; + num = num & (1 << remainder); + if(num == 0) + return false; + } + + return true; +} + +template +void RB_SubSA::buildRepeatBase(const TStr& s, + CoordHelper& coordHelper, + const size_t max_len, + EList& repeatBases) +{ + if(repeat_index_.empty()) + return; + + done_.fillZero(); + + EList senseDominant; + senseDominant.resizeExact(repeat_index_.size()); + senseDominant.fillZero(); + + EList repeatStack; + EList > size_table; + size_table.reserveExact(repeat_index_.size() / 2 + 1); + for(size_t i = 0; i < repeat_index_.size(); i++) { + TIndexOffU begin = repeat_index_[i]; + TIndexOffU end = (i + 1 < repeat_index_.size() ? repeat_index_[i+1] : repeat_list_.size()); + assert_lt(begin, end); + EList positions; positions.reserveExact(end - begin); + for(size_t j = begin; j < end; j++) positions.push_back(repeat_list_[j]); + + if(!isSenseDominant(coordHelper, positions, seed_len_) && !threeN) + continue; + + senseDominant[i] = 1; + size_table.expand(); + size_table.back().first = end - begin; + size_table.back().second = i; + } + size_table.sort(); + + size_t bundle_count = 0; + string tmp_str; + EList tmp_ranges; tmp_ranges.resizeExact(4); + EList > tmp_sort_ranges; tmp_sort_ranges.resizeExact(4); + for(int64_t i = (int64_t)size_table.size() - 1; i >= 0; i--) { + TIndexOffU idx = size_table[i].second; + ASSERT_ONLY(TIndexOffU num = size_table[i].first); + assert_lt(idx, repeat_index_.size()); +#ifndef NDEBUG + if(idx + 1 < repeat_index_.size()) { + assert_eq(repeat_index_[idx] + num, repeat_index_[idx+1]); + } else { + assert_eq(repeat_index_[idx] + num, repeat_list_.size()); + } +#endif + TIndexOffU saBegin = repeat_index_[idx]; + if(isDone(saBegin)) { + assert(isDone(saBegin, num)); + continue; + } + + ASSERT_ONLY(size_t rb_done = 0); + assert_lt(saBegin, repeat_list_.size()); + repeatStack.push_back(idx); + while(!repeatStack.empty()) { + TIndexOffU idx = repeatStack.back(); + assert(senseDominant[idx]); + repeatStack.pop_back(); + assert_lt(idx, repeat_index_.size()); + TIndexOffU saBegin = repeat_index_[idx]; + TIndexOffU saEnd = (idx + 1 < repeat_index_.size() ? repeat_index_[idx + 1] : repeat_list_.size()); + if(isDone(saBegin)) { + assert(isDone(saBegin, saEnd - saBegin)); + continue; + } + + TIndexOffU saElt = repeat_list_[saBegin]; + size_t ri = repeatBases.size(); + repeatBases.expand(); + repeatBases.back().seq = getString(s, saElt, seed_len_); + repeatBases.back().nodes.clear(); + repeatBases.back().nodes.push_back(idx); + ASSERT_ONLY(rb_done++); + setDone(saBegin, saEnd - saBegin); + bool left = true; + while(repeatBases[ri].seq.length() <= max_len) { + if(left) { + tmp_str = "N"; + tmp_str += repeatBases[ri].seq.substr(0, seed_len_ - 1); + } else { + tmp_str = repeatBases[ri].seq.substr(repeatBases[ri].seq.length() - seed_len_ + 1, seed_len_ - 1); + tmp_str.push_back('N'); + } + assert_eq(tmp_str.length(), seed_len_); + + for(size_t c = 0; c < 4; c++) { + if(left) tmp_str[0] = "ACGT"[c]; + else tmp_str.back() = "ACGT"[c]; + assert_eq(tmp_str.length(), seed_len_); + TIndexOffU idx = find_repeat_idx(s, tmp_str); + size_t num = 0; + if(idx < repeat_index_.size()) { + if(idx + 1 < repeat_index_.size()) { + num = repeat_index_[idx+1] - repeat_index_[idx]; + } else { + num = repeat_list_.size() - repeat_index_[idx]; + } + } + tmp_ranges[c].first = idx; + tmp_ranges[c].second = num; + assert(num == 0 || num >= seed_count_); + tmp_sort_ranges[c].first = num; + tmp_sort_ranges[c].second = c; + if(idx == repeat_index_.size() || + isDone(repeat_index_[idx]) || + !senseDominant[idx]) { +#ifndef NDEBUG + if(idx < repeat_index_.size()) { + assert(isDone(repeat_index_[idx], num) || + !senseDominant[idx]); + } +#endif + tmp_sort_ranges[c].first = 0; + tmp_ranges[c].second = 0; + } + } + tmp_sort_ranges.sort(); + if(tmp_sort_ranges[3].first < seed_count_) { + if(left) { + left = false; + continue; + } else { + break; + } + } + + for(size_t cc = 0; cc < 3; cc++) { + assert_leq(tmp_sort_ranges[cc].first, tmp_sort_ranges[cc+1].first); + if(tmp_sort_ranges[cc].first < seed_count_) + continue; + + size_t c = tmp_sort_ranges[cc].second; + repeatStack.push_back(tmp_ranges[c].first); + } + + size_t c = tmp_sort_ranges[3].second; + if(repeatBases[ri].seq.length() >= max_len) { + assert_eq(repeatBases[ri].seq.length(), max_len); + TIndexOffU idx = tmp_ranges[c].first; + assert(!isDone(repeat_index_[idx])); + repeatStack.push_back(idx); + if(left) { + left = false; + continue; + } else { + break; + } + } else { + TIndexOffU idx = tmp_ranges[c].first; + TIndexOffU num = tmp_ranges[c].second; + setDone(repeat_index_[idx], num); + if(left) { + repeatBases[ri].seq.insert(0, 1, "ACGT"[c]); + repeatBases[ri].nodes.insert(idx, 0); + } else { + repeatBases[ri].seq.push_back("ACGT"[c]); + repeatBases[ri].nodes.push_back(idx); + } + } + } + } + + assert_gt(rb_done, 0); + bundle_count++; + } + + cerr << "Bundle count: " << bundle_count << endl; + +#ifndef NDEBUG + { + set idx_set; + for(size_t i = 0; i < repeatBases.size(); i++) { + const RB_RepeatBase& repeatBase = repeatBases[i]; + for(size_t j = 0; j < repeatBase.nodes.size(); j++) { + assert(idx_set.find(repeatBase.nodes[j]) == idx_set.end()); + idx_set.insert(repeatBase.nodes[j]); + } + } + } +#endif + +#if 0 + { + EList > kmer_table; + string query; + size_t total = 0, match = 0; + size_t interval = 1; + if(repeat_index_.size() >= 10000) { + interval = repeat_index_.size() / 10000; + } + EList positions; + for(size_t i = 0; i < repeat_index_.size(); i += interval) { + TIndexOffU saElt_idx = repeat_index_[i]; + TIndexOffU saElt_idx_end = (i + 1 < repeat_index_.size() ? repeat_index_[i+1] : repeat_list_.size()); + positions.clear(); + for(size_t j = saElt_idx; j < saElt_idx_end; j++) { + positions.push_back(repeat_list_[j]); +#ifndef NDEBUG + if(j > saElt_idx) { + TIndexOffU lcp_len = getLCP(s, + coordHelper, + positions[0], + positions.back(), + seed_len_); + assert_geq(lcp_len, seed_len_); + } + + TIndexOffU saElt = repeat_list_[j]; + TIndexOffU start = coordHelper.getStart(saElt); + TIndexOffU start2 = coordHelper.getStart(saElt + seed_len_ - 1); + assert_eq(start, start2); +#endif + } + + TIndexOffU saElt = repeat_list_[saElt_idx]; + size_t true_count = saElt_idx_end - saElt_idx; + getString(s, saElt, seed_len_, query); + + total++; + + size_t count = 0; + for(size_t r = 0; r < repeatBases.size(); r++) { + const RB_RepeatBase& repeat = repeatBases[r]; + int pos = repeat.seq.find(query); + if(pos != string::npos) { + for(size_t j = 0; j < repeat.nodes.size(); j++) { + TIndexOffU _node = repeat.nodes[j]; + TIndexOffU _saElt_idx = repeat_index_[_node]; + TIndexOffU _saElt_idx_end = (_node + 1 < repeat_index_.size() ? repeat_index_[_node+1] : repeat_list_.size()); + TIndexOffU _saElt = repeat_list_[_saElt_idx]; + string seq = getString(s, _saElt, seed_len()); + if(query == seq) { + count += (_saElt_idx_end - _saElt_idx); + } + } + } + } + + size_t rc_count = 0; + string rc_query = reverse_complement(query); + for(size_t r = 0; r < repeatBases.size(); r++) { + const RB_RepeatBase& repeat = repeatBases[r]; + int pos = repeat.seq.find(rc_query); + if(pos != string::npos) { + for(size_t j = 0; j < repeat.nodes.size(); j++) { + TIndexOffU _node = repeat.nodes[j]; + TIndexOffU _saElt_idx = repeat_index_[_node]; + TIndexOffU _saElt_idx_end = (_node + 1 < repeat_index_.size() ? repeat_index_[_node+1] : repeat_list_.size()); + TIndexOffU _saElt = repeat_list_[_saElt_idx]; + string seq = getString(s, _saElt, seed_len()); + if(rc_query == seq) { + rc_count += (_saElt_idx_end - _saElt_idx); + } + } + } + } + + if(count == true_count || rc_count == true_count) { + match++; + } else if(total - match <= 10) { + cerr << "query: " << query << endl; + cerr << "true count: " << true_count << endl; + cerr << "found count: " << count << endl; + cerr << "rc found count: " << rc_count << endl; + cerr << endl; + } + } + + cerr << "RB_SubSA: sanity check: " << match << " passed (out of " << total << ")" << endl << endl; + } +#endif +} + + +#define write_fp(x) fp.write((const char *)&(x), sizeof((x))) + +void RB_SubSA::writeFile(ofstream& fp) +{ + write_fp(sa_size_); + write_fp(seed_len_); + write_fp(seed_count_); + + size_t sz = temp_suffixes_.size(); + write_fp(sz); + for(size_t i = 0; i < sz; i++) { + write_fp(temp_suffixes_[i]); + } + + sz = repeat_index_.size(); + write_fp(sz); + for(size_t i = 0; i < sz; i++) { + write_fp(repeat_index_[i]); + } + + sz = done_.size(); + write_fp(sz); + for(size_t i = 0; i < sz; i++) { + write_fp(done_[i]); + } +} + +#define read_fp(x) fp.read((char *)&(x), sizeof((x))) + +void RB_SubSA::readFile(ifstream& fp) +{ + TIndexOffU val; + + read_fp(val); + rt_assert_eq(val, sa_size_); + + read_fp(val); + rt_assert_eq(val, seed_len_); + + read_fp(val); + rt_assert_eq(val, seed_count_); + + size_t sz; + read_fp(sz); + temp_suffixes_.resizeExact(sz); + for(size_t i = 0; i < sz; i++) { + read_fp(temp_suffixes_[i]); + } + + size_t val_sz; + + // repeat_index_ + read_fp(val_sz); + repeat_index_.resizeExact(val_sz); + for(size_t i = 0; i < val_sz; i++) { + read_fp(repeat_index_[i]); + } + + // done + read_fp(val_sz); + done_.resizeExact(val_sz); + for(size_t i = 0; i < val_sz; i++) { + read_fp(done_[i]); + } + +} + + +/****************************/ +template class RepeatBuilder >; +template void dump_tstr(const SString& ); +template bool compareRepeatCoordByJoinedOff(const RepeatCoord& , const RepeatCoord&); diff --git a/repeat_builder.h b/repeat_builder.h new file mode 100644 index 0000000..092f33d --- /dev/null +++ b/repeat_builder.h @@ -0,0 +1,964 @@ + /* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef __REPEAT_BUILDER_H__ +#define __REPEAT_BUILDER_H__ + +#include +#include +#include +#include +#include "assert_helpers.h" +#include "word_io.h" +#include "mem_ids.h" +#include "ref_coord.h" +#include "ref_read.h" +#include "edit.h" +#include "ds.h" +#include "repeat.h" +#include "blockwise_sa.h" +#include "simple_func.h" +#include "scoring.h" +#include "aligner_sw.h" +#include "bit_packed_array.h" + +//#define DEBUGLOG + +using namespace std; + +/** + * Encapsulates repeat parameters. + */ +class RepeatParameter { +public: + TIndexOffU seed_len; // seed length + TIndexOffU seed_count; // seed count + TIndexOffU seed_mm; // maximum edit distance allowed during initial seed extension + TIndexOffU repeat_count; // repeat count + TIndexOffU min_repeat_len; // minimum repeat length + TIndexOffU max_repeat_len; // maximum repeat length + TIndexOffU max_edit; // maximum edit distance allowed + bool symmetric_extend; // extend symmetrically + TIndexOffU extend_unit_len; // extend seeds no longer than this length at a time + bool append_result; +}; + +typedef pair Range; + +struct Fragments { + bool contain(TIndexOffU pos) { + if (pos >= joinedOff && pos < (joinedOff + length)) { + return true; + } + return false; + } + + TIndexOffU joinedOff; // index within joined text + TIndexOffU length; + + int frag_id; + int seq_id; + TIndexOffU seqOff; // index within sequence + bool first; +}; + +class CoordHelper { +public: + CoordHelper(TIndexOffU length, + TIndexOffU forward_length, + const EList& szs, + const EList& ref_names); + ~CoordHelper(); + int mapJoinedOffToSeq(TIndexOffU joined_pos); + int getGenomeCoord(TIndexOffU joined_pos, + string& chr_name, + TIndexOffU& pos_in_chr); + + TIndexOffU getEnd(TIndexOffU e); + TIndexOffU getStart(TIndexOffU e); + TIndexOffU forward_length() const { return forward_length_; } + TIndexOffU length() const { return length_; } + +private: + void buildNames(); + void buildJoinedFragment(); + +private: + TIndexOffU length_; + TIndexOffU forward_length_; + EList szs_; + EList ref_names_; + EList ref_namelines_; + + // mapping info from joined string to genome + EList fraglist_; + + // Fragments Cache +#define CACHE_SIZE_JOINEDFRG 10 + Fragments cached_[CACHE_SIZE_JOINEDFRG]; + int num_cached_ = 0; + int victim_ = 0; /* round-robin */ +}; + +struct SeedHP { + bool operator==(const SeedHP &rhs) const { + return range == rhs.range && + snpIDs == rhs.snpIDs; + } + + bool operator!=(const SeedHP &rhs) const { + return !(rhs == *this); + } + + bool operator<(const SeedHP &rhs) const { + return range < rhs.range; + } + + bool operator>(const SeedHP &rhs) const { + return rhs < *this; + } + + bool operator<=(const SeedHP &rhs) const { + return !(rhs < *this); + } + + bool operator>=(const SeedHP &rhs) const { + return !(*this < rhs); + } + + Range range; + EList snpIDs; +}; + +struct SeedSNP { + int type; // EDIT_TYPE_MM, EDIT_TYPE_READ_GAP, EDIT_TYPE_REF_GAP + TIndexOffU pos; + size_t len; + string base; // valid when ty = MM, REF_GAP + TIndexOffU id; + + SeedSNP() {} + + void init(int ty, TIndexOffU po, size_t ln, string bs) { + type = ty; + pos = po; + len = ln; + base = bs; + } + void init(int ty, TIndexOffU po, size_t ln, char bs) { + type = ty; + pos = po; + len = ln; + base.assign(1, bs); + } + + friend ostream &operator<<(ostream &os, const SeedSNP &snp) { + + if(snp.type == EDIT_TYPE_MM) { + os << "single"; + } else if(snp.type == EDIT_TYPE_REF_GAP) { + os << "insertion"; + } else if(snp.type == EDIT_TYPE_READ_GAP) { + os << "deletion"; + } + os << " "; + os << snp.pos << " "; + + if(snp.type == EDIT_TYPE_MM || snp.type == EDIT_TYPE_REF_GAP) { + os << snp.base; + } else if(snp.type == EDIT_TYPE_READ_GAP) { + os << snp.len; + } + return os; + } + + bool operator==(const SeedSNP &rhs) const { + return type == rhs.type && + pos == rhs.pos && + len == rhs.len && + base == rhs.base; + } + + bool operator!=(const SeedSNP &rhs) const { + return !(rhs == *this); + } + + static bool cmpSeedSNPByPos( SeedSNP * const& a, SeedSNP * const& b) { + return a->pos < b->pos; + } + +}; + +class SeedExt { +public: + SeedExt() { + reset(); + }; + + void reset() { + done = false; + curr_ext_len = 0; + ed = total_ed = 0; + orig_pos.first = 0; + orig_pos.second = 0; + pos.first = 0; + pos.second = 0; + bound.first = 0; + bound.second = 0; + consensus_pos.first = 0; + consensus_pos.second = 0; + left_gaps.clear(); + right_gaps.clear(); + aligned = true; + }; + + TIndexOffU getLeftExtLength() const { + assert_leq(pos.first, orig_pos.first); + TIndexOffU len = orig_pos.first - pos.first; + return len; + } + + TIndexOffU getRightExtLength() const { + assert_geq(pos.second, orig_pos.second); + return pos.second - orig_pos.second; + } + + TIndexOffU getLength() const { + TIndexOffU len = orig_pos.second - orig_pos.first; + len += getLeftExtLength(); + len += getRightExtLength(); + return len; + } + + template + void getLeftExtString(const TStr& s, string& seq) + { + seq.clear(); + seq = getString(s, pos.first, orig_pos.first - pos.first); + } + + template + void getRightExtString(const TStr& s, string& seq) + { + seq.clear(); + seq = getString(s, orig_pos.second, pos.second - orig_pos.second); + } + + template + void getExtendedSeedSequence(const TStr& s, + string& seq) const; + + template + void generateSNPs(const TStr& s, const string& consensus, EList& repeat_snps); + + static bool isSameConsensus(const SeedExt& a, const SeedExt& b) { + return (a.consensus_pos == b.consensus_pos); + //&& (a.getLength() == b.getLength()); + } + + static bool isSameSNPs(const SeedExt& a, const SeedExt& b) { + const EList& a_edit = a.snps; + const EList& b_edit = b.snps; + + if(a_edit.size() != b_edit.size()) { + return false; + } + + for(size_t i = 0; i < a_edit.size(); i++) { + if(!(*a_edit[i] == *b_edit[i])) { + return false; + } + } + return true; + } + + static bool isSameAllele(const SeedExt& a, const SeedExt& b) { + const EList& a_edit = a.edits; + const EList& b_edit = b.edits; + + if(a_edit.size() != b_edit.size()) { + return false; + } + + for(size_t i = 0; i < a_edit.size(); i++) { + if(!(a_edit[i] == b_edit[i])) { + return false; + } + } + return true; + } + + static bool sort_by_edits(const SeedExt& a, const SeedExt& b) { + const EList& a_edit = a.edits; + const EList& b_edit = b.edits; + + size_t i = 0; + + while((i < a_edit.size()) + && (i < b_edit.size())) { + + if(!(a_edit[i] == b_edit[i])) { + if(a_edit[i] < b_edit[i]) { + return true; + } else { + return false; + } + } + + i++; + } + + if(a_edit.size() < b_edit.size()) { + return true; + } + + if((a_edit.size() == b_edit.size()) + && (a.pos.first < b.pos.first)) { + return true; + } + return false; + } + + void generateEdits(const string& consensus_merged, const string& seed_ext) + { + size_t ed_done = 0; + size_t ext_len = getLength(); + assert_eq(ext_len, seed_ext.length()); + + edits.clear(); + + for(size_t i = 0; i < ext_len && ed_done < total_ed; i++) { + char con_base = consensus_merged[consensus_pos.first + i]; + char seed_base = seed_ext[i]; + + if (con_base != seed_base) { + edits.expand(); + edits.back().init(consensus_pos.first + i, + con_base, seed_base, EDIT_TYPE_MM); + ed_done++; + } + } + } + + Range getExtendedRange(size_t consensus_len) const + { + assert_leq(consensus_pos.second, consensus_len); + Range range; + range.first = (pos.first < consensus_pos.first ? 0 : pos.first - consensus_pos.first); + range.second = pos.second + (consensus_len - consensus_pos.second); + return range; + } + +#ifndef NDEBUG + bool valid() const { + assert_leq(consensus_pos.first, consensus_pos.second); + TIndexOffU constr_len = consensus_pos.second - consensus_pos.first; + TIndexOffU allele_len = getLength(); + + TIndexOffU cur_off = 0; + for(size_t i = 0; i < left_gaps.size(); i++) { + assert_geq(left_gaps[i].first, cur_off); + cur_off = left_gaps[i].first; + int gap_len = left_gaps[i].second; + assert_neq(gap_len, 0); + if(gap_len > 0) { // deletion + allele_len += gap_len; + } else { + allele_len += gap_len; + cur_off += (-gap_len); + } + } + cur_off = 0; + for(size_t i = 0; i < right_gaps.size(); i++) { + assert_geq(right_gaps[i].first, cur_off); + cur_off = right_gaps[i].first; + int gap_len = right_gaps[i].second; + assert_neq(gap_len, 0); + if(gap_len > 0) { // deletion + allele_len += gap_len; + } else { + allele_len += gap_len; + cur_off += (-gap_len); + } + } + assert_eq(constr_len, allele_len); + return true; + } +#endif + +public: + // seed extended position [first, second) + pair orig_pos; + pair pos; + + // extension bound. the seed must be placed on same fragment + // [first, second) + pair bound; + + // positions relative to consensus sequence + pair consensus_pos; + + // a list of gaps (deletions and insertions) in both directions + // offsets from seed's left and right ("pos" above) + // positive and negative values indicate deletions and insertions, resp. + EList > left_gaps; + EList > right_gaps; + + uint32_t ed; // edit distance + uint32_t total_ed; // total edit distance + bool done; // done flag + uint32_t curr_ext_len; // + + bool aligned; + + EList edits; // edits w.r.t. consensus_merged + + EList snps; +}; + +class RB_AlleleCoord { +public: + RB_AlleleCoord() : + left(0), + right(0), + idx(0) + {} + + RB_AlleleCoord(TIndexOffU l, TIndexOffU r, size_t i) : + left(l), + right(r), + idx(i) + {} + + TIndexOffU len() const { return right - left; } + + bool operator<(const RB_AlleleCoord& o) const + { + if(left != o.left) + return left < o.left; + if(right != o.right) + return right > o.right; + return false; + } + + bool contain(const RB_AlleleCoord& o, size_t relax = 0) const + { + if(o.left + relax >= left && o.right <= right + relax) + return true; + else + return false; + } + + bool contained(const RB_AlleleCoord& o) const + { + return o.contain(*this); + } + + TIndexOffU overlap_len(const RB_AlleleCoord& o) const + { + if(contain(o)) return o.len(); + else if(o.contain(*this)) return len(); + else if(left < o.right && right > o.left) { + if(left <= o.left) { + return right - o.left; + } else { + return o.right - left; + } + } + return 0; + } + +public: + TIndexOffU left; + TIndexOffU right; + size_t idx; +}; + +class RB_RepeatManager; +class RB_SWAligner; +class RB_SubSA; + +class RB_RepeatBase { +public: + string seq; + EList nodes; +}; + +class RB_Repeat { +public: + RB_Repeat() {} + ~RB_Repeat() { + if(snps_.size() > 0) { + for(size_t i = 0; i < snps_.size(); i++) { + delete snps_[i]; + } + } + } + + void repeat_id(size_t repeat_id) { repeat_id_ = repeat_id; } + size_t repeat_id() const { return repeat_id_; } + + void parent_id(size_t parent_id) { parent_id_ = parent_id; } + size_t parent_id() const { return parent_id_; } + + string& consensus() { return consensus_; } + const string& consensus() const { return consensus_; } + + EList& seeds() { return seeds_; } + const EList& seeds() const { return seeds_; } + + EList& seed_ranges() { return seed_ranges_; } + const EList& seed_ranges() const { return seed_ranges_; } + + EList& snps() { return snps_; } + const EList& snps() const { return snps_; } + + template + void init(const RepeatParameter& rp, + const TStr& s, + CoordHelper& coordHelper, + const RB_SubSA& subSA, + const RB_RepeatBase& repeatBase); + + template + void extendConsensus(const RepeatParameter& rp, + const TStr& s); + + template + void getNextRepeat(const RepeatParameter& rp, + const TStr& s, + RB_Repeat& o); + + + template + void saveSeedExtension(const RepeatParameter& rp, + const TStr& s, + CoordHelper& coordHelper, + TIndexOffU seed_grp_id, + ostream& fp, + size_t& total_repeat_seq_len, + size_t& total_allele_seq_len) const; + + void saveSNPs(ofstream& fp, + TIndexOffU grp_id, + TIndexOffU& snp_id_base); + void saveConsensus(ofstream& fp, + TIndexOffU grp_id); + + bool overlap(const RB_Repeat& o, + bool& contain, + bool& left, + size_t& seed_i, + size_t& seed_j, + bool debug = false) const; + + bool satisfy(const RepeatParameter& rp) const + { + if(consensus_.length() < rp.min_repeat_len) + return false; + if(seeds_.size() < rp.repeat_count) + return false; + if(seeds_[rp.repeat_count - 1].getLength() < rp.min_repeat_len) + return false; + return true; + } + + void reset() { + consensus_.clear(); + for(size_t i = 0; i < seeds_.size(); i++) + seeds_[i].reset(); + seeds_.clear(); + seed_ranges_.clear(); + } + + void showInfo(const RepeatParameter& rp, + CoordHelper& coordHelper) const; + + template + void generateSNPs(const RepeatParameter&, const TStr& s, TIndexOffU grp_id); + + bool self_repeat() const { return self_repeat_; } + + void update() { internal_update(); } + void addSeed(const SeedExt& seed) + { + seeds_.expand(); + seeds_.back() = seed; + } + + bool contain(TIndexOffU left, TIndexOffU right) const; + +protected: + template + void get_consensus_seq(const TStr& s, + EList& seeds, + size_t sb, + size_t se, + size_t min_left_ext, + size_t min_right_ext, + size_t max_ed, + const RepeatParameter& rp, + EList& ed_seed_nums, + EList* left_consensuses, + EList* right_consensuses) const; + + void internal_update(); + + +protected: + size_t repeat_id_; + size_t parent_id_; + string consensus_; + EList seeds_; + EList seed_ranges_; + EList snps_; + bool self_repeat_; + + static EList ca_ed_; + static EList ca_ed2_; + static string ca_s_; + static string ca_s2_; + +public: + static size_t seed_merge_tried; + static size_t seed_merged; +}; + +class RB_RepeatExt : public RB_Repeat { +public: + RB_RepeatExt() {} + ~RB_RepeatExt() {} + + template + void extendConsensus(const RepeatParameter& rp, + const TStr& s); + + float mergeable(const RB_Repeat& o) const; + + template + bool merge(const RepeatParameter& rp, + const TStr& s, + RB_SWAligner& swalginer, + const RB_RepeatExt& o, + bool contain, + size_t seed_i, + size_t seed_j, + bool debug = false); + +protected: + template + void get_consensus_seq(const TStr& s, + EList& seeds, + size_t sb, + size_t se, + size_t min_left_ext, + size_t min_right_ext, + size_t max_ed, + const RepeatParameter& rp, + EList& ed_seed_nums, + EList* left_consensuses, + EList* right_consensuses) const; + + template + bool align(const RepeatParameter& rp, + const TStr& ref, + const string& s, + const EList >& s_kmer_table, + const string& s2, + EList& offsets, + size_t k, + SeedExt& seed, + int consensus_approx_left, + int consensus_approx_right, + size_t left, + size_t right, + bool debug); + + bool isSelfRepeat(const RepeatParameter& rp, + const string& s, + const EList >& s_kmer_table, + EList& offsets, + size_t k, + bool debug); + +}; + +// check if a set of seeds are already processed +class RB_RepeatManager { +public: + size_t numCoords() const { return range_to_repeats_.size(); } + + bool checkRedundant(const RepeatParameter& rp, + const map& repeat_map, + const EList& positions, + EList& to_remove) const; + + void addRepeat(const RB_Repeat* repeat); + void addRepeat(Range range, size_t repeat_id); + void removeRepeat(const RB_Repeat* repeat); + void removeRepeat(Range range, size_t repeat_id); + +public: + void showInfo(const RepeatParameter& rp, + CoordHelper& coordHelper, + const map& repeat_map, + size_t num_case = 5) const; + +private: + map > range_to_repeats_; +}; + +class RB_SWAligner { +public: + RB_SWAligner(); + ~RB_SWAligner(); + + void init_dyn(const RepeatParameter& rp); + + int alignStrings(const string &ref, + const string &read, + EList& edits, + Coord& coord); + + void makePadString(const string& ref, + const string& read, + string& pad, + size_t len); + + void doTest(const RepeatParameter& rp, + const string& refstr, + const string& readstr); + + void doTestCase1(const string& refstr, + const string& readstr, + TIndexOffU rpt_edit); + +private: + // + SimpleFunc scoreMin_; + SimpleFunc nCeil_; + SimpleFunc penCanIntronLen_; + SimpleFunc penNoncanIntronLen_; + + Scoring *sc_; + SwAligner swa; + LinkedEList > rawEdits_; + RandomSource rnd_; +}; + +// SA Subset +class RB_SubSA { +public: + RB_SubSA() {} + ~RB_SubSA() {} + + void writeFile(ofstream& fp); + void readFile(ifstream &fp); + + void init(TIndexOffU sa_size, + TIndexOffU seed_len, + TIndexOffU seed_count); + + template + void push_back(const TStr& s, + CoordHelper& coordHelper, + TIndexOffU saElt, + bool lastInput = false); + + inline TIndexOffU seed_len() const { return seed_len_; } + inline TIndexOffU seed_count() const { return seed_count_; } + + inline size_t size() const { return repeat_list_.size(); } + TIndexOffU get(size_t idx) const { return repeat_list_[idx]; } + inline TIndexOffU operator[](size_t i) const { return get(i); } + + const EList& getRepeatIndex() const { return repeat_index_; } + + template + Range find(const TStr& s, + const string& seq) const; + + template + TIndexOffU find_repeat_idx(const TStr& s, + const string& seq) const; + + void setDone(TIndexOffU off, TIndexOffU len = 1); + bool isDone(TIndexOffU off, TIndexOffU len = 1) const; + + void dump() const + { + cerr << "seed length: " << seed_len_ << endl; + cerr << "minimum seed count: " << seed_count_ << endl; + cerr << "number of seed groups: " << repeat_index_.size() << endl; + cerr << "number of seeds: " << repeat_list_.size() << endl; + } + + size_t getMemUsage() const + { + size_t tot = 0; + + tot += repeat_list_.totalCapacityBytes(); + tot += repeat_index_.totalCapacityBytes(); + tot += done_.totalCapacityBytes(); + tot += temp_suffixes_.totalCapacityBytes(); + + return tot; + } + + template + void buildRepeatBase(const TStr& s, + CoordHelper& coordHelper, + const size_t max_len, + EList& repeatBases); + +private: + TIndexOffU sa_size_; + TIndexOffU seed_len_; + TIndexOffU seed_count_; + EList temp_suffixes_; + + // repeat index + EList repeat_list_; + EList repeat_index_; + EList done_; +}; + + +// find and write repeats +template +class RepeatBuilder { + +public: + RepeatBuilder(TStr& s, + TStr& sOriginal, + const EList& szs, + const EList& ref_names, + bool forward_only, + const string& filename); + ~RepeatBuilder(); + + +public: + void readSA(const RepeatParameter& rp, + BlockwiseSA& sa); + + void readSA(const RepeatParameter& rp, + const string& filename); + + void readSA(const RepeatParameter& rp, + const BitPackedArray& sa); + + void writeSA(const RepeatParameter& rp, + const string& filename); + + void build(const RepeatParameter& rp); + + void sortRepeatGroup(); + + void saveRepeats(const RepeatParameter& rp); + void saveConsensus(const RepeatParameter& rp, + const string& repName); + void saveFile(const RepeatParameter& rp); + + void addRepeatGroup(const RepeatParameter& rp, + size_t& repeat_id, + RB_RepeatManager& repeat_manger, + const RB_RepeatBase& repeatBase, + ostream& fp); + + void reassignSeeds(const RepeatParameter& rp, + size_t repeat_bid, + size_t repeat_eid, + EList& seeds); + + bool checkSequenceMergeable(const string& ref, + const string& read, + EList& edits, + Coord& coord, + TIndexOffU rpt_len, + TIndexOffU max_edit = 10); + + void doTest(const RepeatParameter& rp, + const string& refstr, + const string& readstr) + { + swaligner_.doTest(rp, refstr, readstr); + } + +private: + void saveAlleles(const RepeatParameter& rp, + const string& repName, + RB_Repeat& repeat, + ofstream&, + ofstream&, + TIndexOffU grp_id, + TIndexOffU&, + TIndexOffU baseoff); + + void writeAllele(TIndexOffU grp_id, + TIndexOffU allele_id, + Range range, + const string& seq_name, + TIndexOffU baseoff, + const EList& seeds, + ostream &fp); + + + void writeSNPs(ostream& fp, + const string& rep_chr_name, + const ESet& editset); + + void writeHaploType(const EList& haplo_list, + const EList& seeds, + TIndexOffU& hapl_id_base, + const string& seq_name, + ostream& fp); + + void generateHaploType(Range range, + const EList& seeds, + EList& haplo_list); + +private: + const int output_width = 60; + + TStr& s_; + TStr& sOriginal_; + bool forward_only_; + string filename_; + + RB_SubSA subSA_; + + TIndexOffU forward_length_; + + CoordHelper coordHelper_; + + // + RB_SWAligner swaligner_; + + // Seeds + EList consensus_all_; + ELList seeds_; + map repeat_map_; +}; + + +int strcmpPos(const string&, const string&, TIndexOffU&); +template void dump_tstr(TStr& s); + +#endif /* __REPEAT_BUILDER_H__ */ diff --git a/repeat_kmer.h b/repeat_kmer.h new file mode 100644 index 0000000..7969494 --- /dev/null +++ b/repeat_kmer.h @@ -0,0 +1,606 @@ + /* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef __REPEAT_KMER_H__ +#define __REPEAT_KMER_H__ + +#include +#include +#include +#include +#include +#include "assert_helpers.h" +#include "word_io.h" +#include "mem_ids.h" +#include "ds.h" + +template +class RB_Minimizer { +public: + static const size_t default_w = 5; + static const size_t default_k = 31; +public: + static pair + get_minimizer(const TStr& seq, + size_t off, + size_t window, + size_t k) + { + assert_leq(k, 32); + assert_leq(off + window + k - 1, seq.length()); + pair minimizer(get_kmer(seq, off, k), off); + uint64_t kmer = minimizer.first; + for(size_t i = off + 1; i < off + window; i++) { + uint64_t next_kmer = get_next_kmer(kmer, seq[i+k-1], k); + if(minimizer_leq(next_kmer, minimizer.first)) { + minimizer.first = next_kmer; + minimizer.second = i; + } + kmer = next_kmer; + } + return minimizer; + } + + static void + get_minimizer(const TStr& seq, + size_t window, + size_t k, + EList >& minimizers) + { + assert_leq(k, 32); + assert_leq(window + k - 1, seq.length()); + + minimizers.clear(); + pair minimizer = get_minimizer(seq, 0, window, k); + minimizers.push_back(minimizer); + uint64_t kmer = get_kmer(seq, window - 1, k); + for(size_t i = 1; i + window + k - 1 <= seq.length(); i++) { + uint64_t next_kmer = get_next_kmer(kmer, seq[i+window+k-2], k); + if(minimizer.second < i) { + minimizer = get_minimizer(seq, i, window, k); + } else if(minimizer_leq(next_kmer, minimizer.first)) { + minimizer.first = next_kmer; + minimizer.second = i + window - 1; + } + minimizers.push_back(minimizer); + kmer = next_kmer; + } + +#ifndef NDEBUG + assert_eq(minimizers.size() + window + k - 2, seq.length()); + for(size_t i = 0; i + window + k - 1 <= seq.length(); i++) { + pair minimizer = get_minimizer(seq, i, window, k); + assert(minimizer == minimizers[i]); + } +#endif + } + +protected: + static bool + minimizer_leq(uint64_t kmer, uint64_t kmer2) + { +#if 1 + kmer = convert_minimizer(kmer); + kmer2 = convert_minimizer(kmer2); +#endif + return kmer <= kmer2; + } + + // Heng Li's minimap and minaisam paper, 2016 + static uint64_t convert_minimizer(uint64_t x) { + x = (~x) + (x << 21); + x = x ^ (x >> 24); + x = x + (x << 3) + (x << 8); + x = x ^ (x >> 14); + x = x + (x << 2) + (x << 4); + x = x ^ (x >> 28); + x = x + (x << 31); + return x; + } + + static uint64_t + get_kmer(const TStr& seq, + size_t offset, + size_t k) + { + assert_leq(offset + k, seq.length()); + uint64_t kmer = 0; + for(size_t i = 0; i < k; i++) { + size_t c = seq[offset + i]; + if(c > 3) c = asc2dna[c]; + kmer = (kmer << 2 | c); + } + return kmer; + } + + static uint64_t + get_next_kmer(uint64_t kmer, + size_t base, + size_t k) + { + kmer &= (((uint64_t)1 << ((k-1)*2))) - 1; + if(base > 3) base = asc2dna[base]; + kmer = (kmer << 2) | base; + return kmer; + } + + static TStr get_string(uint64_t kmer, size_t k) + { + TStr seq = ""; + for(size_t i = 0; i < k; i++) { + size_t nt = kmer & 0x3; + seq.push_back("ACGT"[nt]); + kmer >>= 2; + } + reverse(seq.begin(), seq.end()); + return seq; + } +}; + +struct RB_Alignment { + TIndexOffU pos; + TIndexOffU off; + TIndexOffU len; + + bool operator<(const RB_Alignment& o) const + { + if(pos != o.pos) + return pos < o.pos; + return len > o.len; + } +}; + +struct RB_Alignment_CMPbyLen { + bool operator()(const RB_Alignment& a, const RB_Alignment& b) + { + if(a.len != b.len) + return a.len > b.len; + return a.pos < b.pos; + } +}; + +class RB_KmerTable { +public: + RB_KmerTable() { w_ = k_ = 0; } + ~RB_KmerTable() {} + +public: + bool isIn(uint64_t kmer) const + { +#if 1 + pair key(kmer, 0); + size_t idx = kmer_table_.bsearchLoBound(key); + return idx < kmer_table_.size() && kmer_table_[idx].first == kmer; +#else + return kmers_.find(kmer) != kmers_.end(); +#endif + } + + template + bool isRepeat(const TStr& query, + const TStr& rc_query, + EList >& minimizers) const + { + return isRepeat(query, minimizers) || isRepeat(rc_query, minimizers); + } + + template + bool isRepeat(const TStr& query, + EList >& minimizers) const + { + RB_Minimizer::get_minimizer(query, w_, k_, minimizers); + + size_t est_count = 0; + uint64_t prev_minimizer = 0; + bool prev_in = false; + for(size_t j = 0; j < minimizers.size(); j++) { + bool curr_in = false; + if(minimizers[j].first == prev_minimizer) { + if(prev_in) est_count++; + curr_in = prev_in; + } else if(isIn(minimizers[j].first)) { + curr_in = true; + est_count++; + +#if 1 + return true; +#endif + } + prev_minimizer = minimizers[j].first; + prev_in = curr_in; + } + +#if 1 + return false; +#else + bool est_repeat = est_count * 10 >= minimizers.size(); + return est_repeat; +#endif + } + + template + void findRepeats(const TStr& query, + EList >& minimizers, + EList& repeats) const + { + repeats.clear(); + RB_Minimizer::get_minimizer(query, w_, k_, minimizers); + for(size_t i = 0; i < minimizers.size(); i++) { + if(i > 0 && minimizers[i].first == minimizers[i-1].first) + continue; + pair minimizer(minimizers[i].first, 0); + size_t j = kmer_table_.bsearchLoBound(minimizer); + for(; j < kmer_table_.size() && minimizer.first == kmer_table_[j].first; j++) { + repeats.push_back(kmer_table_[j].second); + } + } + if(repeats.empty()) + return; + + size_t remove_count = 0; + repeats.sort(); + for(size_t i = 0; i + 1 < repeats.size();) { + size_t j = i + 1; + for(; j < repeats.size(); j++) { + if(repeats[i] == repeats[j]) { + repeats[j] = std::numeric_limits::max(); + remove_count++; + } else break; + } + i = j; + } + repeats.sort(); + assert_lt(remove_count, repeats.size()); + repeats.resize(repeats.size() - remove_count); + } + + template + void findAlignments(const TStr& query, + EList >& minimizers, + ELList& position2D, + EList& alignments, + TIndexOffU max_num_alignment = 1000) const + { + minimizers.clear(); + RB_Minimizer::get_minimizer(query, w_, k_, minimizers); + + position2D.clear(); + for(size_t i = 0; i < minimizers.size(); i++) { + if(i > 0 && minimizers[i].first == minimizers[i-1].first) + continue; + pair minimizer(minimizers[i].first, 0); + size_t idx = kmer_table_.bsearchLoBound(minimizer); + if(idx < kmer_table_.size() && kmer_table_[idx].first == minimizer.first) { + TIndexOffU begin = kmer_table_[idx].second; + TIndexOffU end = (idx + 1 < kmer_table_.size() ? kmer_table_[idx+1].second : pos_list_.size()); + position2D.expand(); + EList& positions = position2D.back(); + positions.clear(); + positions.expand(); + positions.back().pos = begin; // suffix begin + positions.back().off = i; // minimizer index + positions.expand(); + positions.back().pos = end; // suffix end + positions.back().off = i; // minimizer index + } + } + + alignments.clear(); + if(position2D.empty()) + return; + + for(size_t i = 0; i < position2D.size(); i++) { + size_t num_i = 0, num_pos = numeric_limits::max(); + for(size_t j = 0; j < position2D.size(); j++) { + EList& positions = position2D[j]; + if(positions.empty()) + continue; + assert_eq(positions.size(), 2); + TIndexOffU cur_num_pos = positions[1].pos - positions[0].pos; + if(cur_num_pos == 0) + continue; + if(cur_num_pos < num_pos) { + num_i = j; + num_pos = cur_num_pos; + } + } + + if(num_pos > max_num_alignment && alignments.size() > 0) + break; + + if(num_pos > max_num_alignment) + break; + + EList& positions = position2D[num_i]; + TIndexOffU begin = positions[0].pos; + TIndexOffU end = positions[1].pos; + TIndexOffU min_i = positions[0].off; + assert_eq(num_pos, end - begin); + positions.clear(); + for(TIndexOffU j = begin; j < end; j++) { + if(pos_list_[j] < minimizers[min_i].second) + continue; + positions.expand(); + positions.back().pos = pos_list_[j]; + positions.back().off = minimizers[min_i].second; + positions.back().len = k_; + } + + if(i == 0) { + for(size_t j = 0; j < positions.size(); j++) { + alignments.expand(); + alignments.back() = positions[j]; + } + } else { + size_t a = 0, p = 0; + size_t num_alignment = alignments.size(); + while(a < num_alignment && p < positions.size()) { + RB_Alignment& alignment = alignments[a]; + RB_Alignment& position = positions[p]; + if(alignment.pos < position.pos) { + TIndexOffU offDiff = position.off - alignment.off; + if(position.pos - alignment.pos == offDiff) { + alignment.len = min(offDiff, alignment.len) + position.len; + a++; p++; + } else { + a++; + } + } else if(alignment.pos > position.pos) { + TIndexOffU offDiff = alignment.off - position.off; + if(alignment.pos - position.pos == offDiff) { + alignment.pos = position.pos; + alignment.off = position.off; + alignment.len = min(offDiff, position.len) + alignment.len; + assert_geq(alignment.pos, alignment.off); + a++; p++; + } else { + alignments.expand(); + alignments.back() = position; + p++; + } + } else { + assert_eq(alignment.pos, position.pos); + a++; p++; + } + } + + while(p < positions.size()) { + RB_Alignment& position = positions[p]; + alignments.expand(); + alignments.back() = position; + p++; + } + + if(i + 1 < position2D.size()) { + alignments.sort(); + } + } + + positions.clear(); + + if(alignments.size() >= max_num_alignment) { + break; + } + } + + if(alignments.empty()) + return; + + for(size_t i = 0; i < alignments.size(); i++) { + alignments[i].pos -= alignments[i].off; + } + alignments.sort(); + + // remove duplicates + size_t remove_count = 0; + for(size_t i = 0; i + 1 + remove_count < alignments.size(); i++) { + size_t j = i + 1 + remove_count; + for(; j < alignments.size(); j++) { + if(alignments[i].pos != alignments[j].pos) { + assert_geq(j, i + 1); + if(j > i + 1) { + alignments[i+1] = alignments[j]; + } + break; + } else { + remove_count++; + } + } + } + + assert_lt(remove_count, alignments.size()); + if(remove_count > 0) { + alignments.resize(alignments.size() - remove_count); + } + if(alignments.size() > 1) { + sort(alignments.begin(), alignments.end(), RB_Alignment_CMPbyLen()); + } + } + + bool write(ofstream& f_out, bool bigEndian) const { + writeIndex(f_out, w_, bigEndian); + writeIndex(f_out, k_, bigEndian); + writeIndex(f_out, kmer_table_.size(), bigEndian); + for(size_t i = 0; i < kmer_table_.size(); i++) { + writeIndex(f_out, kmer_table_[i].first, bigEndian); + if(sizeof(TIndexOffU) == 4) { + writeU32(f_out, kmer_table_[i].second, bigEndian); + } else { + assert_eq(sizeof(TIndexOffU), 8); + writeIndex(f_out, kmer_table_[i].second, bigEndian); + } + } + writeIndex(f_out, pos_list_.size(), bigEndian); + for(size_t i = 0; i < pos_list_.size(); i++) { + if(sizeof(TIndexOffU) == 4) { + writeU32(f_out, pos_list_[i], bigEndian); + } else { + assert_eq(sizeof(TIndexOffU), 8); + writeIndex(f_out, pos_list_[i], bigEndian); + } + } + return true; + } + + bool read(ifstream& f_in, bool bigEndian) { + w_ = readIndex(f_in, bigEndian); + k_ = readIndex(f_in, bigEndian); + size_t kmer_size = readIndex(f_in, bigEndian); + kmer_table_.reserveExact(kmer_size); + while(kmer_table_.size() < kmer_size) { + kmer_table_.expand(); + kmer_table_.back().first = readIndex(f_in, bigEndian); + if(sizeof(TIndexOffU) == 4) { + kmer_table_.back().second = readU32(f_in, bigEndian); + } else { + assert_eq(sizeof(TIndexOffU), 8); + kmer_table_.back().second = readIndex(f_in, bigEndian); + } + +#if 0 + kmers_.insert(kmer_table_.back().first); +#endif + } + size_t pos_size = readIndex(f_in, bigEndian); + pos_list_.reserveExact(pos_size); + while(pos_list_.size() < pos_size) { + pos_list_.expand(); + if(sizeof(TIndexOffU) == 4) { + pos_list_.back() = readU32(f_in, bigEndian); + } else { + assert_eq(sizeof(TIndexOffU), 8); + pos_list_.back() = readIndex(f_in, bigEndian); + } + } + return true; + } + +public: + template + void build(const EList& seqs, + size_t w, + size_t k) + { + w_ = w; + k_ = k; + kmer_table_.clear(); + pos_list_.clear(); + + EList > tmp_table; + set tmp_kmers; + + TIndexOffU baseoff = 0; + EList > minimizers; + for(size_t s = 0; s < seqs.size(); s++) { + const TStr& seq = seqs[s]; + RB_Minimizer::get_minimizer(seq, + w_, + k_, + minimizers); + for(size_t i = 0; i < minimizers.size(); i++) { + if(!tmp_table.empty() && + tmp_table.back().first == minimizers[i].first && + tmp_table.back().second == baseoff + minimizers[i].second) + continue; + + tmp_table.expand(); + tmp_table.back().first = minimizers[i].first; + tmp_table.back().second = baseoff + minimizers[i].second; + tmp_kmers.insert(minimizers[i].first); +#if 0 + kmers_.insert(minimizers[i].first); +#endif + } + baseoff += seq.length(); + } + tmp_table.sort(); + + kmer_table_.reserveExact(tmp_kmers.size()); + pos_list_.reserveExact(tmp_table.size()); + for(size_t i = 0; i < tmp_table.size(); i++) { +#ifndef NDEBUG + if(!pos_list_.empty()) { + assert_neq(pos_list_.back(), tmp_table[i].second); + } +#endif + if(kmer_table_.empty() || kmer_table_.back().first != tmp_table[i].first) { + kmer_table_.expand(); + kmer_table_.back().first = tmp_table[i].first; + kmer_table_.back().second = pos_list_.size(); + } + pos_list_.push_back(tmp_table[i].second); + } + assert_eq(kmer_table_.size(), tmp_kmers.size()); + assert_eq(pos_list_.size(), tmp_table.size()); + } + + void dump(ostream& o) const + { + o << "window : " << w_ << endl; + o << "k length : " << k_ << endl; + o << "number of kmer : " << kmer_table_.size() << endl; + o << "number of pos : " << pos_list_.size() << endl; + + EList counts, counts_10; + counts.resizeExact(10); counts_10.resizeExact(10); + counts.fillZero(); counts_10.fillZero(); + for(size_t i = 0; i < kmer_table_.size(); i++) { + size_t count = 0; + if(i + 1 < kmer_table_.size()) { + count = kmer_table_[i+1].second - kmer_table_[i].second; + } else { + count = pos_list_.size() - kmer_table_[i].second; + } + assert_gt(count, 0); + count -= 1; + if(count < counts.size()) { + counts[count]++; + } + size_t count_10 = count / 10; + if(count_10 < counts_10.size()) { + counts_10[count_10]++; + } else { + counts_10.back()++; + } + } + for(size_t i = 0; i < counts.size(); i++) { + o << "\t" << i + 1 << ": " << counts[i] << endl; + } + for(size_t i = 1; i < counts_10.size(); i++) { + o << "\t" << i * 10 + 1; + if(i + 1 < counts_10.size()) { + o << " to " << (i+1) * 10 << ": "; + } else { + o << " or more: "; + } + o << counts_10[i] << endl; + } + } + +private: + size_t w_; + size_t k_; + EList > kmer_table_; + EList pos_list_; + + unordered_set kmers_; +}; + + +#endif /* __REPEAT_KMER_H__ */ diff --git a/rfm.h b/rfm.h new file mode 100644 index 0000000..5c5dbfb --- /dev/null +++ b/rfm.h @@ -0,0 +1,1136 @@ +/* + * Copyright 2018, Chanhee Park and Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef RFM_H_ +#define RFM_H_ + +#include "hgfm.h" + +/** + * Extended Burrows-Wheeler transform data. + * LocalEbwt is a specialized Ebwt index that represents ~64K bps + * and therefore uses two bytes as offsets within 64K bps. + * This class has only two additional member variables to denote the genomic sequenuce it represents: + * (1) the contig index and (2) the offset within the contig. + * + */ +template +class LocalRFM : public GFM { + typedef GFM PARENT_CLASS; +public: + /// Construct an Ebwt from the given input file + LocalRFM(const string& in, + ALTDB* altdb, + FILE *in1, + FILE *in2, + char *mmFile1, + char *mmFile2, + bool switchEndian, + size_t& bytesRead, + size_t& bytesRead2, + int needEntireReverse, + bool fw, + int32_t overrideOffRate, // = -1, + int32_t offRatePlus, // = -1, + bool useMm, // = false, + bool useShmem, // = false, + bool mmSweep, // = false, + bool loadNames, // = false, + bool loadSASamp, // = true, + bool loadFtab, // = true, + bool loadRstarts, // = true, + bool verbose, // = false, + bool startVerbose, // = false, + bool passMemExc, // = false, + bool sanityCheck, // = false) + bool useHaplotype) : // = false + GFM(in, + altdb, + NULL, + NULL, + needEntireReverse, + fw, + overrideOffRate, + offRatePlus, + useMm, + useShmem, + mmSweep, + loadNames, + loadSASamp, + loadFtab, + loadRstarts, + true, // load Splice Sites + verbose, + startVerbose, + passMemExc, + sanityCheck, + useHaplotype, + true) + { + this->_in1 = in1; + this->_in2 = in2; + + this->_repeat = true; + bool subIndex = true; + PARENT_CLASS::readIntoMemory( + needEntireReverse, + loadSASamp, + loadFtab, + loadRstarts, + false, //justHeader + &(this->_gh), + mmSweep, + loadNames, + startVerbose, + subIndex); + + // If the offRate has been overridden, reflect that in the + // _eh._offRate field + if(offRatePlus > 0 && this->_overrideOffRate == -1) { + this->_overrideOffRate = this->_gh._offRate + offRatePlus; + } + if(this->_overrideOffRate > this->_gh._offRate) { + this->_gh.setOffRate(this->_overrideOffRate); + assert_eq(this->_overrideOffRate, this->_gh._offRate); + } + assert(this->repOk()); + } + + + /// Construct an Ebwt from the given header parameters and string + /// vector, optionally using a blockwise suffix sorter with the + /// given 'bmax' and 'dcv' parameters. The string vector is + /// ultimately joined and the joined string is passed to buildToDisk(). + template + LocalRFM( + TStr& s, + InorderBlockwiseSA* sa, + PathGraph* pg, + EList >& alts, + index_t local_size, + const EList& refnames, + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + const string& file, // base filename for EBWT files + bool fw, + int dcv, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + uint32_t seed, + ostream& out1, + ostream& out2, + int32_t overrideOffRate = -1, + bool verbose = false, + bool passMemExc = false, + bool sanityCheck = false) : + GFM(packed, + needEntireReverse, + lineRate, + offRate, + ftabChars, + file, + fw, + dcv, + szs, + sztot, + refparams, + seed, + overrideOffRate, + verbose, + passMemExc, + sanityCheck) + { + const GFMParams& gh = this->_gh; + assert(gh.repOk()); + uint32_t be = this->toBe(); + assert(out1.good()); + assert(out2.good()); + assert_eq(refnames.size(), 1); + this->_refnames.push_back(refnames[0]); + + writeIndex(out1, gh._len, be); // length of string (and bwt and suffix array) + streampos headerPos = out1.tellp(); + writeIndex(out1, 0, be); // gbwtLen + writeIndex(out1, 0, be); // num of nodes + writeI32(out1, lineRate, be); + writeI32(out1, 0, be); + writeI32(out1, offRate, be); + writeI32(out1, ftabChars, be); + writeIndex(out1, 0, be); // eftabLen + writeI32(out1, 0, be); // flag + if(gh._len > 0) { + assert_gt(szs.size(), 0); + assert_gt(sztot, 0); + // Not every fragment represents a distinct sequence - many + // fragments may correspond to a single sequence. Count the + // number of sequences here by counting the number of "first" + // fragments. + this->_nPat = 0; + this->_nFrag = 0; + for(size_t i = 0; i < szs.size(); i++) { + if(szs[i].len > 0) this->_nFrag++; + if(szs[i].first && szs[i].len > 0) this->_nPat++; + } + assert_eq(this->_nPat, 1); + assert_geq(this->_nFrag, this->_nPat); + this->_rstarts.reset(); + writeIndex(out1, this->_nPat, be); + assert_eq(this->_nPat, 1); + this->_plen.init(new index_t[this->_nPat], this->_nPat); + // For each pattern, set plen + int npat = -1; + for(size_t i = 0; i < szs.size(); i++) { + if(szs[i].first && szs[i].len > 0) { + if(npat >= 0) { + writeIndex(out1, this->plen()[npat], be); + } + npat++; + this->plen()[npat] = (szs[i].len + szs[i].off); + } else { + this->plen()[npat] += (szs[i].len + szs[i].off); + } + } + assert_eq((index_t)npat, this->_nPat-1); + writeIndex(out1, this->plen()[npat], be); + // Write the number of fragments + writeIndex(out1, this->_nFrag, be); + + if(refparams.reverse == REF_READ_REVERSE) { + EList tmp(EBWT_CAT); + reverseRefRecords(szs, tmp, false, verbose); + this->szsToDisk(tmp, out1, refparams.reverse); + } else { + this->szsToDisk(szs, out1, refparams.reverse); + } + + if(alts.empty()) { + assert(pg == NULL); + PARENT_CLASS::buildToDisk(*sa, s, out1, out2, headerPos); + } else { + assert(pg != NULL); + // Re-initialize GFM parameters to reflect real number of edges (gbwt string) + this->_gh.init( + this->_gh.len(), + pg->getNumEdges(), + pg->getNumNodes(), + this->_gh.lineRate(), + this->_gh.offRate(), + this->_gh.ftabChars(), + 0, + this->_gh.entireReverse()); + PARENT_CLASS::buildToDisk(*pg, s, out1, out2, headerPos); + } + } + + // Now write reference sequence names on the end + assert_eq(this->_refnames.size(), this->_nPat); + for(index_t i = 0; i < this->_refnames.size(); i++) { + out1 << this->_refnames[i].c_str(); + if(i + 1 < this->_refnames.size()) cout << endl; + else out1 << '\0'; + } + out1.flush(); out2.flush(); + if(out1.fail() || out2.fail()) { + cerr << "An error occurred writing the index to disk. Please check if the disk is full." << endl; + throw 1; + } + } + + /** + * Sanity-check various pieces of the Ebwt + */ + void sanityCheckAll(int reverse) const { + if(this->_gh._len > 0) { + PARENT_CLASS::sanityCheckAll(reverse); + } + } + + bool empty() const { return this->_gh._len == 0; } +}; + +/** + * Extended Burrows-Wheeler transform data. + * RFM is a specialized Ebwt index that represents one global index and a large set of local indexes. + * + */ +template +class RFM : public GFM { + typedef GFM PARENT_CLASS; +public: + /// Construct a GFM from the given input file + RFM(const string& in, + ALTDB* altdb, + RepeatDB* repeatdb, + EList* readLens, + int needEntireReverse, + bool fw, + int32_t overrideOffRate, // = -1, + int32_t offRatePlus, // = -1, + bool useMm, // = false, + bool useShmem, // = false, + bool mmSweep, // = false, + bool loadNames, // = false, + bool loadSASamp, // = true, + bool loadFtab, // = true, + bool loadRstarts, // = true, + bool loadSpliceSites, // = true, + bool verbose, // = false, + bool startVerbose, // = false, + bool passMemExc, // = false, + bool sanityCheck, // = false + bool useHaplotype, // = false + bool skipLoading = false) : + GFM(in, + altdb, + repeatdb, + readLens, + needEntireReverse, + fw, + overrideOffRate, + offRatePlus, + useMm, + useShmem, + mmSweep, + loadNames, + loadSASamp, + loadFtab, + loadRstarts, + loadSpliceSites, + verbose, + startVerbose, + passMemExc, + sanityCheck, + useHaplotype, + skipLoading), + _in1(NULL), + _in2(NULL) + { + _in1Str = in + ".1." + gfm_ext; + _in2Str = in + ".2." + gfm_ext; + } + + /// Construct a HGFM from the given header parameters and string + /// vector, optionally using a blockwise suffix sorter with the + /// given 'bmax' and 'dcv' parameters. The string vector is + /// ultimately joined and the joined string is passed to buildToDisk(). + template + RFM( + TStr& s, + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + int32_t localOffRate, + int32_t localFtabChars, + int nthreads, + const string& snpfile, + const string& htfile, + const string& ssfile, + const string& exonfile, + const string& svfile, + const string& repeatfile, + const string& outfile, // base filename for GFM files + bool fw, + bool useBlockwise, + TIndexOffU bmax, + TIndexOffU bmaxSqrtMult, + TIndexOffU bmaxDivN, + int dcv, + EList& is, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + bool localIndex, // create local indexes? + EList* parent_szs, + EList* parent_refnames, + uint32_t seed, + int32_t overrideOffRate = -1, + bool verbose = false, + bool passMemExc = false, + bool sanityCheck = false); + + RFM() { + clearLocalRFMs(); + } + + /** + * Load this Ebwt into memory by reading it in from the _in1 and + * _in2 streams. + */ + void loadIntoMemory( + int needEntireReverse, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool loadNames, + bool verbose) + { + readIntoMemory( + needEntireReverse, // require reverse index to be concatenated reference reversed + loadSASamp, // load the SA sample portion? + loadFtab, // load the ftab (_ftab[] and _eftab[])? + loadRstarts, // load the r-starts (_rstarts[])? + false, // stop after loading the header portion? + NULL, // params + false, // mmSweep + loadNames, // loadNames + verbose); // startVerbose + } + + // I/O + void readIntoMemory( + int needEntireRev, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool justHeader, + GFMParams *params, + bool mmSweep, + bool loadNames, + bool startVerbose); + + /** + * Frees memory associated with the Ebwt. + */ + void evictFromMemory() { + assert(PARENT_CLASS::isInMemory()); + clearLocalRFMs(); + PARENT_CLASS::evictFromMemory(); + } + + /** + * Sanity-check various pieces of the Ebwt + */ + void sanityCheckAll(int reverse) const { + PARENT_CLASS::sanityCheckAll(reverse); + for(size_t i = 0; i < _localRFMs.size(); i++) { + assert(_localRFMs[i] != NULL); + _localRFMs[i]->sanityCheckAll(reverse); + } + } + + void getReferenceNames(EList& refnames) { + for(size_t i = 0; i < _localRFMs.size(); i++) { + assert_eq(_localRFMs[i]->refnames().size(), 1); + refnames.push_back(_localRFMs[i]->refnames()[0]); + } + } + + void getReferenceLens(EList& reflens) { + for(size_t i = 0; i < _localRFMs.size(); i++) { + reflens.push_back(_localRFMs[i]->plen()[0]); + } + } + + index_t getLocalRFM_idx(index_t readLen) { + for(size_t i = 0; i < this->_repeatLens.size(); i++) { + if(this->_repeatLens[i].first >= readLen) { + return i; + } + } + return this->_repeatLens.size() - 1; + } + + index_t getLocalRFM_idx(const char *refname) { + for(size_t i = 0; i < this->_repeatLens.size(); i++) { + assert_eq(_localRFMs[i]->refnames().size(), 1); + + string& ref = _localRFMs[i]->refnames()[0]; + if(ref.compare(refname) == 0) { + return i; + } + } + return this->_repeatLens.size() - 1; + } + + bool empty() const { return _localRFMs.empty(); } + + LocalRFM& getLocalRFM(index_t idx) { + assert_lt(idx, this->_repeatLens.size()); + return *_localRFMs[idx]; + } + + RB_KmerTable& getKmertable(index_t idx) { + assert_lt(idx, this->_repeat_kmertables.size()); + return this->_repeat_kmertables[idx]; + } + + void clearLocalRFMs() { + for(size_t i = 0; i < _localRFMs.size(); i++) { + assert(_localRFMs[i] != NULL); + delete _localRFMs[i]; + } + _localRFMs.clear(); + } + + +public: + EList _refLens; /// approx lens of ref seqs (excludes trailing ambig chars) + EList*> _localRFMs; + + EList > _localRFMFilePos; + + FILE *_in1; // input fd for primary index file + FILE *_in2; // input fd for secondary index file + string _in1Str; + string _in2Str; + + char *mmFile1_; + char *mmFile2_; + +private: + struct WorkerParam { + // input + SString s; + EList > alts; + EList > haplotypes; + bool bigEndian; + index_t local_offset; + index_t curr_sztot; + EList conv_local_szs; + index_t local_sztot; + index_t index_size; + string file; + InorderBlockwiseSA >* sa; + index_t dcv; + index_t seed; + EList refnames; + + // output + RefGraph* rg; + PathGraph* pg; + + int threads; + }; + static void build_worker(void* vp); +}; + + +template +void RFM::build_worker(void* vp) +{ + WorkerParam& tParam = *(WorkerParam*)vp; + if(tParam.alts.empty()) { + tParam.sa = NULL; + tParam.sa = new KarkkainenBlockwiseSA >( + tParam.s, + (index_t)(tParam.s.length()+1), + tParam.threads, + tParam.dcv, + tParam.seed, + false, /* this->_sanity */ + false, /* this->_passMemExc */ + false); /* this->_verbose */ + assert(tParam.sa->suffixItrIsReset()); + assert_eq(tParam.sa->size(), tParam.s.length()+1); + } else { + while(true) { + tParam.rg = NULL, tParam.pg = NULL; + bool exploded = false; + try { + tParam.rg = new RefGraph( + tParam.s, + tParam.conv_local_szs, + tParam.alts, + tParam.haplotypes, + tParam.file, + tParam.threads, /* num threads */ + false); /* verbose? */ + tParam.pg = new PathGraph( + *tParam.rg, + tParam.file, + local_max_gbwt, + 1, /* num threads */ + false); /* verbose? */ + } catch (const NongraphException& err) { + cerr << "Warning: no variants or splice sites in this graph (" << tParam.curr_sztot << ")" << endl; + delete tParam.rg; + delete tParam.pg; + tParam.alts.clear(); + continue; + } catch (const ExplosionException& err) { + exploded = true; + } + + if(!exploded) { + if(!tParam.pg->generateEdges(*tParam.rg)) { + cerr << "An error occurred - generateEdges" << endl; + throw 1; + } + exploded = tParam.pg->getNumEdges() > local_max_gbwt; + } + if(exploded) { + cerr << "Warning: a local graph exploded (offset: " << tParam.curr_sztot << ", length: " << tParam.local_sztot << ")" << endl; + + delete tParam.pg; tParam.pg = NULL; + delete tParam.rg; tParam.rg = NULL; + if(tParam.alts.size() <= 1) { + tParam.alts.clear(); + } else { + for(index_t s = 2; s < tParam.alts.size(); s += 2) { + tParam.alts[s >> 1] = tParam.alts[s]; + } + tParam.alts.resize(tParam.alts.size() >> 1); + tParam.haplotypes.clear(); + for(index_t a = 0; a < tParam.alts.size(); a++) { + const ALT& alt = tParam.alts[a]; + if(!alt.snp()) continue; + tParam.haplotypes.expand(); + tParam.haplotypes.back().left = alt.pos; + if(alt.deletion()) { + tParam.haplotypes.back().right = alt.pos + alt.len - 1; + } else { + tParam.haplotypes.back().right = alt.pos; + } + tParam.haplotypes.back().alts.clear(); + tParam.haplotypes.back().alts.push_back(a); + } + } + continue; + } + + break; + } + } +} + +/// Construct a GFM from the given header parameters and string +/// vector, optionally using a blockwise suffix sorter with the +/// given 'bmax' and 'dcv' parameters. The string vector is +/// ultimately joined and the joined string is passed to buildToDisk(). +template +template +RFM::RFM( + TStr& s, + bool packed, + int needEntireReverse, + int32_t lineRate, + int32_t offRate, + int32_t ftabChars, + int32_t localOffRate, + int32_t localFtabChars, + int nthreads, + const string& snpfile, + const string& htfile, + const string& ssfile, + const string& exonfile, + const string& svfile, + const string& repeatfile, + const string& outfile, // base filename for EBWT files + bool fw, + bool useBlockwise, + TIndexOffU bmax, + TIndexOffU bmaxSqrtMult, + TIndexOffU bmaxDivN, + int dcv, + EList& is, + EList& szs, + index_t sztot, + const RefReadInParams& refparams, + bool localIndex, + EList* parent_szs, + EList* parent_refnames, + uint32_t seed, + int32_t overrideOffRate, + bool verbose, + bool passMemExc, + bool sanityCheck) : + GFM(s, + packed, + needEntireReverse, + lineRate, + offRate, + ftabChars, + nthreads, + snpfile, + htfile, + ssfile, + exonfile, + svfile, + repeatfile, + outfile, + fw, + useBlockwise, + bmax, + bmaxSqrtMult, + bmaxDivN, + dcv, + is, + szs, + sztot, + refparams, + parent_szs, + parent_refnames, + seed, + overrideOffRate, + verbose, + passMemExc, + sanityCheck), + _in1(NULL), + _in2(NULL) +{ + _in1Str = outfile + ".1." + gfm_ext; + _in2Str = outfile + ".2." + gfm_ext; + + // Open output files + ofstream fout1(_in1Str.c_str(), ios::binary); + if(!fout1.good()) { + cerr << "Could not open index file for writing: \"" << _in1Str.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + ofstream fout2(_in2Str.c_str(), ios::binary); + if(!fout2.good()) { + cerr << "Could not open index file for writing: \"" << _in2Str.c_str() << "\"" << endl + << "Please make sure the directory exists and that permissions allow writing by" << endl + << "HISAT2." << endl; + throw 1; + } + + // Split the whole genome into a set of local indexes + uint32_t be = this->toBe(); + assert(fout1.good()); + assert(fout2.good()); + + // When building an Ebwt, these header parameters are known + // "up-front", i.e., they can be written to disk immediately, + // before we join() or buildToDisk() + writeI32(fout1, 1, be); // endian hint for priamry stream + writeI32(fout2, 1, be); // endian hint for secondary stream + int version = GFM::getIndexVersion(); + writeI32(fout1, version, be); // version + index_t nLocalRFMs = this->_repeatLens.size(); + writeIndex(fout1, nLocalRFMs, be); // number of local Ebwts + for(size_t i = 0; i < this->_repeatLens.size(); i++) { + writeIndex(fout1, this->_repeatLens[i].first, be); + writeIndex(fout1, this->_repeatLens[i].second, be); + } + streampos filepos = fout1.tellp(); + _localRFMFilePos.resizeExact(szs.size()); + for(size_t i = 0; i < _localRFMFilePos.size(); i++) { + writeIndex(fout1, 0, be); + writeIndex(fout1, 0, be); + } + + assert_gt(this->_nthreads, 0); + WorkerParam tParam; + tParam.rg = NULL; + tParam.pg = NULL; + tParam.sa = NULL; + tParam.file = outfile; + tParam.dcv = 1024; + tParam.seed = seed; + tParam.threads = this->_nthreads; + + // build local FM indexes + assert_eq(szs.size(), this->_refnames.size()); + index_t curr_sztot = 0; + EList > alts; + for(size_t tidx = 0; tidx < szs.size(); tidx++) { + assert(szs[tidx].first); + index_t refLen = szs[tidx].len; + _localRFMs.expand(); + assert_lt(tidx, _localRFMs.size()); + + tParam.index_size = refLen; + tParam.conv_local_szs.clear(); + tParam.conv_local_szs.push_back(szs[tidx]); + tParam.refnames.clear(); + tParam.refnames.push_back(this->_refnames[tidx]); + + // Extract sequence corresponding to this local index + tParam.s.resize(refLen); + if(refparams.reverse == REF_READ_REVERSE) { + tParam.s.install(s.buf() + s.length() - curr_sztot - refLen, refLen); + } else { + tParam.s.install(s.buf() + curr_sztot, refLen); + } + +#if 0 + // Extract ALTs corresponding to this local index + map alt_map; + tParam.alts.clear(); + ALT alt; + alt.pos = curr_sztot; + index_t alt_i = (index_t)this->_alts.bsearchLoBound(alt); + for(; alt_i < this->_alts.size(); alt_i++) { + const ALT& alt = this->_alts[alt_i]; + if(alt.snp()) { + if(alt.mismatch()) { + if(curr_sztot + local_sztot <= alt.pos) break; + } else if(alt.insertion()) { + if(curr_sztot + local_sztot < alt.pos) break; + } else { + assert(alt.deletion()); + if(curr_sztot + local_sztot < alt.pos + alt.len) break; + } + if(curr_sztot <= alt.pos) { + alt_map[alt_i] = (index_t)tParam.alts.size(); + tParam.alts.push_back(alt); + tParam.alts.back().pos -= curr_sztot; + } + } else if(alt.splicesite()) { + if(alt.excluded) continue; + if(curr_sztot + local_sztot <= alt.right + 1) continue; + if(curr_sztot <= alt.left) { + tParam.alts.push_back(alt); + tParam.alts.back().left -= curr_sztot; + tParam.alts.back().right -= curr_sztot; + } + } else { + assert(alt.exon()); + } + } + + // Extract haplotypes + tParam.haplotypes.clear(); + Haplotype haplotype; + haplotype.left = curr_sztot; + index_t haplotpye_i = (index_t)this->_haplotypes.bsearchLoBound(haplotype); + for(; haplotpye_i < this->_haplotypes.size(); haplotpye_i++) { + const Haplotype& haplotype = this->_haplotypes[haplotpye_i]; + if(curr_sztot + local_sztot <= haplotype.right) continue; + if(curr_sztot <= haplotype.left) { + tParam.haplotypes.push_back(haplotype); + tParam.haplotypes.back().left -= curr_sztot; + tParam.haplotypes.back().right -= curr_sztot; + for(index_t a = 0; a < tParam.haplotypes.back().alts.size(); a++) { + index_t alt_i = tParam.haplotypes.back().alts[a]; + if(alt_map.find(alt_i) == alt_map.end()) { + assert(false); + tParam.haplotypes.pop_back(); + break; + } + tParam.haplotypes.back().alts[a] = alt_map[alt_i]; + } + } + } +#endif + + tParam.local_offset = 0; + tParam.curr_sztot = curr_sztot; + tParam.local_sztot = refLen; + + assert(tParam.rg == NULL); + assert(tParam.pg == NULL); + assert(tParam.sa == NULL); + curr_sztot += refLen; + + build_worker(&tParam); + + LocalRFM( + tParam.s, + tParam.sa, + tParam.pg, + tParam.alts, + tParam.index_size, + tParam.refnames, + packed, + needEntireReverse, + lineRate, + offRate, // suffix-array sampling rate + ftabChars, // number of chars in initial arrow-pair calc + outfile, // basename for .?.ebwt files + fw, // fw + dcv, // difference-cover period + tParam.conv_local_szs, // list of reference sizes + tParam.local_sztot, // total size of all unambiguous ref chars + refparams, // reference read-in parameters + seed, // pseudo-random number generator seed + fout1, + fout2, + -1, // override offRate + false, // be silent + passMemExc, // pass exceptions up to the toplevel so that we can adjust memory settings automatically + sanityCheck); // verify results and internal consistency + if(tParam.rg != NULL) { + assert(tParam.pg != NULL); + delete tParam.rg; tParam.rg = NULL; + delete tParam.pg; tParam.pg = NULL; + } + if(tParam.sa != NULL) { + delete tParam.sa; tParam.sa = NULL; + } + + _localRFMFilePos[tidx].first = fout1.tellp(); + _localRFMFilePos[tidx].second = fout2.tellp(); + } + assert_eq(curr_sztot, sztot); + + streampos origpos = fout1.tellp(); + fout1.seekp(filepos); + for(size_t i = 0; i < _localRFMFilePos.size(); i++) { + writeIndex(fout1, _localRFMFilePos[i].first, be); + writeIndex(fout1, _localRFMFilePos[i].second, be); + } + fout1.seekp(origpos); + + fout1 << '\0'; + fout1.flush(); fout2.flush(); + if(fout1.fail() || fout2.fail()) { + cerr << "An error occurred writing the index to disk. Please check if the disk is full." << endl; + throw 1; + } + VMSG_NL("Returning from initFromVector"); + + // Close output files + fout1.flush(); + int64_t tellpSz1 = (int64_t)fout1.tellp(); + VMSG_NL("Wrote " << fout1.tellp() << " bytes to primary GFM file: " << _in1Str.c_str()); + fout1.close(); + bool err = false; + if(tellpSz1 > fileSize(_in1Str.c_str())) { + err = true; + cerr << "Index is corrupt: File size for " << _in1Str.c_str() << " should have been " << tellpSz1 + << " but is actually " << fileSize(_in1Str.c_str()) << "." << endl; + } + fout2.flush(); + int64_t tellpSz2 = (int64_t)fout2.tellp(); + VMSG_NL("Wrote " << fout2.tellp() << " bytes to secondary GFM file: " << _in2Str.c_str()); + fout2.close(); + if(tellpSz2 > fileSize(_in2Str.c_str())) { + err = true; + cerr << "Index is corrupt: File size for " << _in2Str.c_str() << " should have been " << tellpSz2 + << " but is actually " << fileSize(_in2Str.c_str()) << "." << endl; + } + if(err) { + cerr << "Please check if there is a problem with the disk or if disk is full." << endl; + throw 1; + } + // Reopen as input streams + VMSG_NL("Re-opening _in1 and _in2 as input streams"); + if(this->_sanity) { + VMSG_NL("Sanity-checking ht2"); + assert(!this->isInMemory()); + readIntoMemory( + fw ? -1 : needEntireReverse, // 1 -> need the reverse to be reverse-of-concat + true, // load SA sample (_offs[])? + true, // load ftab (_ftab[] & _eftab[])? + true, // load r-starts (_rstarts[])? + false, // just load header? + NULL, // Params object to fill + false, // mm sweep? + true, // load names? + false); // verbose startup? + sanityCheckAll(refparams.reverse); + evictFromMemory(); + assert(!this->isInMemory()); + } + VMSG_NL("Returning from HGFM constructor"); +} + + +/** + * Read an Ebwt from file with given filename. + */ +template +void RFM::readIntoMemory( + int needEntireRev, + bool loadSASamp, + bool loadFtab, + bool loadRstarts, + bool justHeader, + GFMParams *params, + bool mmSweep, + bool loadNames, + bool startVerbose) +{ + bool switchEndian; // dummy; caller doesn't care +#ifdef BOWTIE_MM + char *mmFile[] = { NULL, NULL }; +#endif + if(_in1Str.length() > 0) { + if(this->_verbose || startVerbose) { + cerr << " About to open input files: "; + logTime(cerr); + } + // Initialize our primary and secondary input-stream fields + if(_in1 != NULL) fclose(_in1); + if(this->_verbose || startVerbose) cerr << "Opening \"" << _in1Str.c_str() << "\"" << endl; + if((_in1 = fopen(_in1Str.c_str(), "rb")) == NULL) { + cerr << "Could not open index file " << _in1Str.c_str() << endl; + } + if(loadSASamp) { + if(_in2 != NULL) fclose(_in2); + if(this->_verbose || startVerbose) cerr << "Opening \"" << _in2Str.c_str() << "\"" << endl; + if((_in2 = fopen(_in2Str.c_str(), "rb")) == NULL) { + cerr << "Could not open index file " << _in2Str.c_str() << endl; + } + } + if(this->_verbose || startVerbose) { + cerr << " Finished opening input files: "; + logTime(cerr); + } + +#ifdef BOWTIE_MM + if(this->_useMm /*&& !justHeader*/) { + const char *names[] = {_in1Str.c_str(), _in2Str.c_str()}; + int fds[] = { fileno(_in1), fileno(_in2) }; + for(int i = 0; i < (loadSASamp ? 2 : 1); i++) { + if(this->_verbose || startVerbose) { + cerr << " ¯ " << (i+1) << ": "; + logTime(cerr); + } + struct stat sbuf; + if (stat(names[i], &sbuf) == -1) { + perror("stat"); + cerr << "Error: Could not stat index file " << names[i] << " prior to memory-mapping" << endl; + throw 1; + } + mmFile[i] = (char*)mmap((void *)0, (size_t)sbuf.st_size, + PROT_READ, MAP_SHARED, fds[(size_t)i], 0); + if(mmFile[i] == (void *)(-1)) { + perror("mmap"); + cerr << "Error: Could not memory-map the index file " << names[i] << endl; + throw 1; + } + if(mmSweep) { + int sum = 0; + for(off_t j = 0; j < sbuf.st_size; j += 1024) { + sum += (int) mmFile[i][j]; + } + if(startVerbose) { + cerr << " Swept the memory-mapped ebwt index file 1; checksum: " << sum << ": "; + logTime(cerr); + } + } + } + mmFile1_ = mmFile[0]; + mmFile2_ = loadSASamp ? mmFile[1] : NULL; + } +#endif + } +#ifdef BOWTIE_MM + else if(this->_useMm && !justHeader) { + mmFile[0] = mmFile1_; + mmFile[1] = mmFile2_; + } + if(this->_useMm && !justHeader) { + assert(mmFile[0] == mmFile1_); + assert(mmFile[1] == mmFile2_); + } +#endif + + if(this->_verbose || startVerbose) { + cerr << " Reading header: "; + logTime(cerr); + } + + // Read endianness hints from both streams + size_t bytesRead = 0, bytesRead2 = 4; + switchEndian = false; + uint32_t one = readU32(_in1, switchEndian); // 1st word of primary stream + bytesRead += 4; + if(loadSASamp) { +#ifndef NDEBUG + assert_eq(one, readU32(_in2, switchEndian)); // should match! +#else + readU32(_in2, switchEndian); +#endif + } + if(one != 1) { + assert_eq((1u<<24), one); + assert_eq(1, endianSwapU32(one)); + switchEndian = true; + } + + // Can't switch endianness and use memory-mapped files; in order to + // support this, someone has to modify the file to switch + // endiannesses appropriately, and we can't do this inside Bowtie + // or we might be setting up a race condition with other processes. + if(switchEndian && this->_useMm) { + cerr << "Error: Can't use memory-mapped files when the index is the opposite endianness" << endl; + throw 1; + } + + readI32(_in1, switchEndian); bytesRead += 4; + index_t nlocalRFMs = readIndex(_in1, switchEndian); bytesRead += sizeof(index_t); + + EList > localRFMLens; + localRFMLens.resizeExact(nlocalRFMs); + for(size_t i = 0; i < localRFMLens.size(); i++) { + localRFMLens[i].first = readIndex(_in1, switchEndian); + localRFMLens[i].second = readIndex(_in1, switchEndian); + } + + _localRFMFilePos.resizeExact(nlocalRFMs); + for(size_t i = 0; i < _localRFMFilePos.size(); i++) { + _localRFMFilePos[i].first = readIndex(_in1, switchEndian); + _localRFMFilePos[i].second = readIndex(_in1, switchEndian); + } + + clearLocalRFMs(); + + assert_eq(this->_repeatIncluded.size(), nlocalRFMs); + string base = ""; + for(size_t i = 0; i < nlocalRFMs; i++) { + if(!this->_repeatIncluded[i]) + continue; + if(i > 0) { + fseek(_in1, _localRFMFilePos[i-1].first, SEEK_SET); + fseek(_in2, _localRFMFilePos[i-1].second, SEEK_SET); + } + LocalRFM *localRFM = new LocalRFM(base, + NULL, + _in1, + _in2, + mmFile1_, + mmFile2_, + switchEndian, + bytesRead, + bytesRead2, + needEntireRev, + this->fw_, + -1, // overrideOffRate + -1, // offRatePlus + this->_useMm, + this->useShmem_, + mmSweep, + loadNames, + loadSASamp, + loadFtab, + loadRstarts, + false, // _verbose + false, + this->_passMemExc, + this->_sanity, + false); // use haplotypes? + + _localRFMs.push_back(localRFM); + } + + fseek(_in1, _localRFMFilePos.back().first, SEEK_SET); + fseek(_in2, _localRFMFilePos.back().second, SEEK_SET); + +#ifdef BOWTIE_MM + fseek(_in1, 0, SEEK_SET); + fseek(_in2, 0, SEEK_SET); +#else + rewind(_in1); + rewind(_in2); +#endif +} + +#endif /*RFM_H_*/ diff --git a/sam.h b/sam.h new file mode 100644 index 0000000..ad9fb2c --- /dev/null +++ b/sam.h @@ -0,0 +1,2013 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SAM_H_ +#define SAM_H_ + +#include +#include +#include "ds.h" +#include "read.h" +#include "util.h" +#include "aligner_result.h" +#include "scoring.h" +#include "alt.h" +#include "filebuf.h" +#include "alignment_3n.h" + +enum { + // Comments use language from v1.4-r962 spec + SAM_FLAG_PAIRED = 1, // templ. having mult. frag.s in sequencing + SAM_FLAG_MAPPED_PAIRED = 2, // each frag properly aligned + SAM_FLAG_UNMAPPED = 4, // fragment unmapped + SAM_FLAG_MATE_UNMAPPED = 8, // next fragment in template unmapped + SAM_FLAG_QUERY_STRAND = 16, // SEQ is reverse comp'ed from original + SAM_FLAG_MATE_STRAND = 32, // next fragment SEQ reverse comp'ed + SAM_FLAG_FIRST_IN_PAIR = 64, // first fragment in template + SAM_FLAG_SECOND_IN_PAIR = 128, // last fragment in template + SAM_FLAG_NOT_PRIMARY = 256, // secondary alignment + SAM_FLAG_FAILS_CHECKS = 512, // not passing quality controls + SAM_FLAG_DUPLICATE = 1024 // PCR or optical duplicate +}; + +class AlnRes; +class AlnFlags; +class AlnSetSumm; + +/** + * Encapsulates all the various ways that a user may wish to customize SAM + * output. + */ +template +class SamConfig { + + typedef EList StrList; + typedef EList LenList; + +public: + + SamConfig( + const StrList& refnames, // reference sequence names + const LenList& reflens, // reference sequence lengths + const StrList& repnames, // repeat sequence names + const LenList& replens, // repeat sequence lengths + bool truncQname, // truncate read name to 255? + bool omitsec, // omit secondary SEQ/QUAL + bool noUnal, // omit unaligned reads + const std::string& pg_id, // id + const std::string& pg_pn, // name + const std::string& pg_vn, // version + const std::string& pg_cl, // command-line + const std::string& rgs, // read groups string + int rna_strandness, + bool print_as, + bool print_xs, + bool print_xss, + bool print_yn, + bool print_xn, + bool print_cs, + bool print_cq, + bool print_x0, + bool print_x1, + bool print_xm, + bool print_xo, + bool print_xg, + bool print_nm, + bool print_md, + bool print_yf, + bool print_yi, + bool print_ym, + bool print_yp, + bool print_yt, + bool print_ys, + bool print_zs, + bool print_xr, + bool print_xt, + bool print_xd, + bool print_xu, + bool print_ye, // streak of failed DPs at end + bool print_yl, // longest streak of failed DPs + bool print_yu, // index of last succeeded DP + bool print_xp, // print seed hit information + bool print_yr, // # redundant seed hits + bool print_zb, // # Ftab lookups + bool print_zr, // # redundant path checks + bool print_zf, // # FM Index ops + bool print_zm, // FM Index op string for best-first search + bool print_zi, // # seed extend loop iters + bool print_zp, + bool print_zu, + bool print_xs_a, + bool print_nh) : + truncQname_(truncQname), + omitsec_(omitsec), + noUnal_(noUnal), + pg_id_(pg_id), + pg_pn_(pg_pn), + pg_vn_(pg_vn), + pg_cl_(pg_cl), + rgs_(rgs), + refnames_(refnames), + reflens_(reflens), + repnames_(repnames), + replens_(replens), + rna_strandness_(rna_strandness), + print_as_(print_as), // alignment score of best alignment + print_xs_(print_xs), // alignment score of second-best alignment + print_xss_(print_xss), + print_yn_(print_yn), // minimum valid score and perfect score + print_xn_(print_xn), + print_cs_(print_cs), + print_cq_(print_cq), + print_x0_(print_x0), + print_x1_(print_x1), + print_xm_(print_xm), + print_xo_(print_xo), + print_xg_(print_xg), + print_nm_(print_nm), + print_md_(print_md), + print_yf_(print_yf), + print_yi_(print_yi), + print_ym_(print_ym), + print_yp_(print_yp), + print_yt_(print_yt), + print_ys_(print_ys), + print_zs_(print_zs), + print_xr_(print_xr), + print_xt_(print_xt), // time elapsed in microseconds + print_xd_(print_xd), // DP extend attempts + print_xu_(print_xu), // ungapped extend attempts + print_ye_(print_ye), // streak of failed DPs at end + print_yl_(print_yl), // longest streak of failed DPs + print_yu_(print_yu), // index of last succeeded DP + print_xp_(print_xp), // print seed hit information + print_yr_(print_yr), // index of last succeeded DP + print_zb_(print_zb), // # Ftab lookups + print_zr_(print_zr), // # redundant path checks + print_zf_(print_zf), // # FM Index ops + print_zm_(print_zm), // FM Index op string for best-first search + print_zi_(print_zi), // # seed extend loop iters + print_zp_(print_zp), // # seed extend loop iters + print_zu_(print_zu), // # seed extend loop iters + print_xs_a_(print_xs_a), + print_nh_(print_nh) + { + assert_eq(refnames_.size(), reflens_.size()); + } + + /** + * Print a reference name in a way that doesn't violate SAM's character + * constraints. \*|[!-()+-<>-~][!-~]* + */ + void printRefName( + BTString& o, + const std::string& name) + const; + + /** + * Print a :Z optional field where certain characters (whitespace, colon + * and percent) are escaped using % escapes. + */ + template + void printOptFieldEscapedZ(BTString& o, const T& s) const { + size_t len = s.length(); + for(size_t i = 0; i < len; i++) { + if(s[i] < 33 || s[i] > 126 || s[i] == ':' || s[i] == '%') { + // percent-encode it + o.append('%'); + int ms = s[i] >> 4; + int ls = s[i] & 15; + assert_range(0, 15, ms); + assert_range(0, 15, ls); + o.append("0123456789ABCDEF"[ms]); + o.append("0123456789ABCDEF"[ls]); + } else { + o.append(s[i]); + } + } + } + + /** + * Print a :Z optional field where newline characters are escaped using % + * escapes. + */ + template + void printOptFieldNewlineEscapedZ(BTString& o, const T& s) const { + size_t len = s.length(); + for(size_t i = 0; i < len; i++) { + if(s[i] == 10 || s[i] == 13 || s[i] == '%') { + // percent-encode it + o.append('%'); + int ms = s[i] >> 4; + int ls = s[i] & 15; + assert_range(0, 15, ms); + assert_range(0, 15, ls); + o.append("0123456789ABCDEF"[ms]); + o.append("0123456789ABCDEF"[ls]); + } else { + o.append(s[i]); + } + } + } + + /** + * Print a read name in a way that doesn't violate SAM's character + * constraints. [!-?A-~]{1,255} (i.e. [33, 63], [65, 126]) + */ + template + void printReadName( + BTString& o, + const TStr& name, + bool omitSlashMate) + const + { + size_t namelen = name.length(); + if(omitSlashMate && + namelen >= 2 && + name[namelen-2] == '/' && + (name[namelen-1] == '1' || name[namelen-1] == '2' || name[namelen-1] == '3')) + { + namelen -= 2; + } + if(truncQname_ && namelen > 255) { + namelen = 255; + } + for(size_t i = 0; i < namelen; i++) { + if(truncQname_ && isspace(name[i])) { + return; + } + o.append(name[i]); + } + } + + /** + * Print a reference name given a reference index. + */ + void printRefNameFromIndex( + BTString& o, + size_t i, + bool repeat = false) + const; + + /** + * Print SAM header to given output buffer. + */ + void printHeader( + BTString& o, + const std::string& rgid, + const std::string& rgs, + bool printHd, + bool printSq, + bool printPg) + const; + + /** + * Print the @HD header line to the given string. + */ + void printHdLine(BTString& o, const char *samver) const; + + /** + * Print the @SQ header lines to the given string. + */ + void printSqLines(BTString& o) const; + + /** + * Print the @PG header line to the given string. + */ + void printPgLine(BTString& o) const; + + /** + * Print the optional flags to the given string. + */ + void printAlignedOptFlags( + BTString& o, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // the read + AlnRes& res, // individual alignment result + StackedAln& staln, // stacked alignment + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metics + const Scoring& sc, // scoring scheme + const char *mapqInp, // inputs to MAPQ calculation + const ALTDB* altdb) + const; + + /** + * Print the optional flags to the given string. + */ + void printAlignedOptFlags( + Alignment* newAlignment, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // the read + AlnRes& res, // individual alignment result + StackedAln& staln, // stacked alignment + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metics + const Scoring& sc, // scoring scheme + const char *mapqInp, // inputs to MAPQ calculation + const ALTDB* altdb) + const; + /** + * Print the optional flags to the given string. + */ + void printEmptyOptFlags( + BTString& o, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // the read + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc) // scoring scheme + const; + + void printEmptyOptFlags( + Alignment* newAlignment, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // the read + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc) // scoring scheme + const; + + /** + * Return true iff we should try to obey the SAM spec's recommendations + * that: + * + * SEQ and QUAL of secondary alignments should be set to ‘*’ to reduce the + * file size. + */ + bool omitSecondarySeqQual() const { + return omitsec_; + } + + bool omitUnalignedReads() const { + return noUnal_; + } + +protected: + + bool truncQname_; // truncate QNAME to 255 chars? + bool omitsec_; // omit secondary + bool noUnal_; // omit unaligned reads + + std::string pg_id_; // @PG ID: Program record identifier + std::string pg_pn_; // @PG PN: Program name + std::string pg_vn_; // @PG VN: Program version + std::string pg_cl_; // @PG CL: Program command-line + std::string rgs_; // Read-group string to add to all records + const StrList& refnames_; // reference sequence names + const LenList& reflens_; // reference sequence lengths + + const StrList& repnames_; // repeat sequence names + const LenList& replens_; // repeat sequence lengths + + int rna_strandness_; + + // Which alignment flags to print? + + // Following are printed by BWA-SW + bool print_as_; // AS:i: Alignment score generated by aligner + bool print_xs_; // XS:i: Suboptimal alignment score + bool print_xss_;// Xs:i: Best invalid alignment score found + bool print_yn_; // YN:i:, Yn:i: minimum valid score and perfect score + bool print_xn_; // XN:i: Number of ambiguous bases in the referenece + + // Other optional flags + bool print_cs_; // CS:Z: Color read sequence on the original strand + bool print_cq_; // CQ:Z: Color read quality on the original strand + + // Following are printed by BWA + bool print_x0_; // X0:i: Number of best hits + bool print_x1_; // X1:i: Number of sub-optimal best hits + bool print_xm_; // XM:i: Number of mismatches in the alignment + bool print_xo_; // XO:i: Number of gap opens + bool print_xg_; // XG:i: Number of gap extensions (incl. opens) + bool print_nm_; // NM:i: Edit dist. to the ref, Ns count, clipping doesn't + bool print_md_; // MD:Z: String for mms. [0-9]+(([A-Z]|\^[A-Z]+)[0-9]+)*2 + + // Following are Bowtie2-specific + bool print_yf_; // YF:i: Read was filtered out? + bool print_yi_; // YI:Z: Summary of inputs to MAPQ calculation + bool print_ym_; // YM:i: Read was repetitive when aligned unpaired? + bool print_yp_; // YP:i: Read was repetitive when aligned paired? + bool print_yt_; // YT:Z: String representing alignment type + bool print_ys_; // YS:i: Score of other mate + bool print_zs_; // ZS:i: Pseudo-random seed + + bool print_xr_; // XR:Z: Original read string + bool print_xt_; // XT:i: Time taken to align + bool print_xd_; // XD:i: DP problems + bool print_xu_; // XU:i: ungapped alignment + bool print_ye_; // YE:i: streak of failed DPs at end + bool print_yl_; // YL:i: longest streak of failed DPs + bool print_yu_; // YU:i: index of last succeeded DP + bool print_xp_; // XP:BI: seed hit information + bool print_yr_; // YR:i: # redundant seed hits + bool print_zb_; // ZB:i: # Ftab lookups + bool print_zr_; // ZR:i: # redundant path checks + bool print_zf_; // ZF:i: # FM Index ops + bool print_zm_; // ZM:i: FM ops string for best-first search + bool print_zi_; // ZI:i: # extend loop iters + bool print_zp_; // ZP:i: Score of best/second-best paired-end alignment + bool print_zu_; // ZU:i: Score of best/second-best unpaired alignment + + bool print_xs_a_; // XS:A:[+=] Sense/anti-sense strand splice sites correspond to + bool print_nh_; // NH:i: # alignments +}; + +/** + * Print a reference name in a way that doesn't violate SAM's character + * constraints. \*|[!-()+-<>-~][!-~]* (i.e. [33, 63], [65, 126]) + */ +template +void SamConfig::printRefName( + BTString& o, + const std::string& name) const +{ + size_t namelen = name.length(); + for(size_t i = 0; i < namelen; i++) { + if(isspace(name[i])) { + return; + } + o.append(name[i]); + } +} + +/** + * Print a reference name given a reference index. + */ +template +void SamConfig::printRefNameFromIndex(BTString& o, size_t i, bool repeat) const { + if(repeat) { + printRefName(o, repnames_[i]); + } else { + printRefName(o, refnames_[i]); + } +} + +/** + * Print SAM header to given output buffer. + */ +template +void SamConfig::printHeader( + BTString& o, + const string& rgid, + const string& rgs, + bool printHd, + bool printSq, + bool printPg) const +{ + if(printHd) printHdLine(o, "1.0"); + if(printSq) printSqLines(o); + if(!rgid.empty()) { + o.append("@RG"); + o.append(rgid.c_str()); + o.append(rgs.c_str()); + o.append('\n'); + } + if(printPg) printPgLine(o); +} + +/** + * Print the @HD header line to the given string. + */ +template +void SamConfig::printHdLine(BTString& o, const char *samver) const { + o.append("@HD\tVN:"); + o.append(samver); + o.append("\tSO:unsorted\n"); +} + +/** + * Print the @SQ header lines to the given string. + */ +template +void SamConfig::printSqLines(BTString& o) const { + char buf[1024]; + for(size_t i = 0; i < refnames_.size(); i++) { + o.append("@SQ\tSN:"); + printRefName(o, refnames_[i]); + o.append("\tLN:"); + itoa10(reflens_[i], buf); + o.append(buf); + o.append('\n'); + } + if (!threeN) { + for(size_t i = 0; i < repnames_.size(); i++) { + o.append("@SQ\tSN:"); + printRefName(o, repnames_[i]); + o.append("\tLN:"); + itoa10(replens_[i], buf); + o.append(buf); + o.append('\n'); + } + } +} + +/** + * Print the @PG header line to the given string. + */ +template +void SamConfig::printPgLine(BTString& o) const { + o.append("@PG\tID:"); + o.append(pg_id_.c_str()); + o.append("\tPN:"); + o.append(pg_pn_.c_str()); + o.append("\tVN:"); + o.append(pg_vn_.c_str()); + o.append("\tCL:\""); + o.append(pg_cl_.c_str()); + o.append('"'); + o.append('\n'); +} + +#define WRITE_SEP() { \ +if(!first) o.append('\t'); \ +first = false; \ +} + +/** + * Print the optional flags to the given string. + */ +template +void SamConfig::printAlignedOptFlags( + BTString& o, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // the read + AlnRes& res, // individual alignment result + StackedAln& staln, // stacked alignment buffer + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc, // scoring scheme + const char *mapqInp, // inputs to MAPQ calculation + const ALTDB* altdb) +const +{ + char buf[1024]; + if(print_as_) { + // AS:i: Alignment score generated by aligner + itoa10(res.score().score(), buf); + WRITE_SEP(); + o.append("AS:i:"); + o.append(buf); + } + + // Do not output suboptimal alignment score, which conflicts with Cufflinks and StringTie + if(print_xs_) { + // XS:i: Suboptimal alignment score + // Use ZS:i: to avoid conflict with XS:A: + AlnScore sco = summ.secbestMate(rd.mate < 2); + if(sco.valid()) { + itoa10(sco.score(), buf); + WRITE_SEP(); + o.append("ZS:i:"); + o.append(buf); + } + } + if(print_xn_) { + // XN:i: Number of ambiguous bases in the referenece + itoa10(res.refNs(), buf); + WRITE_SEP(); + o.append("XN:i:"); + o.append(buf); + } + if(print_x0_) { + // X0:i: Number of best hits + } + if(print_x1_) { + // X1:i: Number of sub-optimal best hits + } + size_t num_mm = 0; + size_t num_go = 0; + size_t num_gx = 0; + for(size_t i = 0; i < res.ned().size(); i++) { + if(res.ned()[i].isMismatch()) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_mm++; + } + } else if(res.ned()[i].isReadGap()) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_go++; + num_gx++; + } + while(i < res.ned().size()-1 && + res.ned()[i+1].pos == res.ned()[i].pos && + res.ned()[i+1].isReadGap()) + { + i++; + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_gx++; + } + } + } else if(res.ned()[i].isRefGap()) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_go++; + num_gx++; + } + while(i < res.ned().size()-1 && + res.ned()[i+1].pos == res.ned()[i].pos+1 && + res.ned()[i+1].isRefGap()) + { + i++; + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_gx++; + } + } + } + } + if(print_xm_) { + // XM:i: Number of mismatches in the alignment + itoa10(num_mm, buf); + WRITE_SEP(); + o.append("XM:i:"); + o.append(buf); + } + if(print_xo_) { + // XO:i: Number of gap opens + itoa10(num_go, buf); + WRITE_SEP(); + o.append("XO:i:"); + o.append(buf); + } + if(print_xg_) { + // XG:i: Number of gap extensions (incl. opens) + itoa10(num_gx, buf); + WRITE_SEP(); + o.append("XG:i:"); + o.append(buf); + } + if(print_nm_) { + // NM:i: Edit dist. to the ref, Ns count, clipping doesn't + size_t NM = 0; + for(size_t i = 0; i < res.ned().size(); i++) { + if(res.ned()[i].type != EDIT_TYPE_SPL) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + NM++; + } + } + } + itoa10(NM, buf); + WRITE_SEP(); + o.append("NM:i:"); + o.append(buf); + } + if(print_md_) { + // MD:Z: String for mms. [0-9]+(([A-Z]|\^[A-Z]+)[0-9]+)*2 + WRITE_SEP(); + o.append("MD:Z:"); + staln.buildMdz(); + staln.writeMdz( + &o, // output buffer + NULL); // no char buffer + } + if(print_ys_ && summ.paired()) { + // YS:i: Alignment score of opposite mate + assert(res.oscore().valid()); + itoa10(res.oscore().score(), buf); + WRITE_SEP(); + o.append("YS:i:"); + o.append(buf); + } + if(print_yn_) { + // YN:i: Minimum valid score for this mate + TAlScore mn = sc.scoreMin.f(rd.length()); + itoa10(mn, buf); + WRITE_SEP(); + o.append("YN:i:"); + o.append(buf); + // Yn:i: Perfect score for this mate + TAlScore pe = sc.perfectScore(rd.length()); + itoa10(pe, buf); + WRITE_SEP(); + o.append("Yn:i:"); + o.append(buf); + } + if(print_xss_) { + // Xs:i: Best invalid alignment score of this mate + bool one = true; + if(flags.partOfPair() && !flags.readMate1()) { + one = false; + } + TAlScore bst = one ? prm.bestLtMinscMate1 : prm.bestLtMinscMate2; + if(bst > std::numeric_limits::min()) { + itoa10(bst, buf); + WRITE_SEP(); + o.append("Xs:i:"); + o.append(buf); + } + if(flags.partOfPair()) { + // Ys:i: Best invalid alignment score of opposite mate + bst = one ? prm.bestLtMinscMate2 : prm.bestLtMinscMate1; + if(bst > std::numeric_limits::min()) { + itoa10(bst, buf); + WRITE_SEP(); + o.append("Ys:i:"); + o.append(buf); + } + } + } + if(print_zs_) { + // ZS:i: Pseudo-random seed for read + itoa10(rd.seed, buf); + WRITE_SEP(); + o.append("ZS:i:"); + o.append(buf); + } + if(print_yt_) { + // YT:Z: String representing alignment type + WRITE_SEP(); + flags.printYT(o); + } + if(print_yp_ && flags.partOfPair() && flags.canMax()) { + // YP:i: Read was repetitive when aligned paired? + WRITE_SEP(); + flags.printYP(o); + } + if(print_ym_ && flags.canMax() && (flags.isMixedMode() || !flags.partOfPair())) { + // YM:i: Read was repetitive when aligned unpaired? + WRITE_SEP(); + flags.printYM(o); + } + if(print_yf_ && flags.filtered()) { + // YF:i: Read was filtered? + first = flags.printYF(o, first) && first; + } + if(print_yi_) { + // Print MAPQ calibration info + if(mapqInp[0] != '\0') { + // YI:i: Suboptimal alignment score + WRITE_SEP(); + o.append("YI:Z:"); + o.append(mapqInp); + } + } + if(flags.partOfPair() && print_zp_) { + // ZP:i: Score of best concordant paired-end alignment + WRITE_SEP(); + o.append("ZP:Z:"); + if(summ.bestPaired().valid()) { + itoa10(summ.bestPaired().score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + // Zp:i: Second-best concordant paired-end alignment score + WRITE_SEP(); + o.append("Zp:Z:"); + if(summ.secbestPaired().valid()) { + itoa10(summ.secbestPaired().score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + } + if(print_zu_) { + // ZU:i: Score of best unpaired alignment + AlnScore best = (rd.mate <= 1 ? summ.best1() : summ.best2()); + AlnScore secbest = (rd.mate <= 1 ? summ.secbest1() : summ.secbest2()); + WRITE_SEP(); + o.append("ZU:i:"); + if(best.valid()) { + itoa10(best.score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + // Zu:i: Score of second-best unpaired alignment + WRITE_SEP(); + o.append("Zu:i:"); + if(secbest.valid()) { + itoa10(secbest.score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + } + if(!rgs_.empty()) { + WRITE_SEP(); + o.append(rgs_.c_str()); + } + if(print_xt_) { + // XT:i: Timing + WRITE_SEP(); + struct timeval tv_end; + struct timezone tz_end; + gettimeofday(&tv_end, &tz_end); + size_t total_usecs = + (tv_end.tv_sec - prm.tv_beg.tv_sec) * 1000000 + + (tv_end.tv_usec - prm.tv_beg.tv_usec); + itoa10(total_usecs, buf); + o.append("XT:i:"); + o.append(buf); + } + if(print_xd_) { + // XD:i: Extend DPs + WRITE_SEP(); + itoa10(prm.nExDps, buf); + o.append("XD:i:"); + o.append(buf); + // Xd:i: Mate DPs + WRITE_SEP(); + itoa10(prm.nMateDps, buf); + o.append("Xd:i:"); + o.append(buf); + } + if(print_xu_) { + // XU:i: Extend ungapped tries + WRITE_SEP(); + itoa10(prm.nExUgs, buf); + o.append("XU:i:"); + o.append(buf); + // Xu:i: Mate ungapped tries + WRITE_SEP(); + itoa10(prm.nMateUgs, buf); + o.append("Xu:i:"); + o.append(buf); + } + if(print_ye_) { + // YE:i: Streak of failed DPs at end + WRITE_SEP(); + itoa10(prm.nDpFail, buf); + o.append("YE:i:"); + o.append(buf); + // Ye:i: Streak of failed ungaps at end + WRITE_SEP(); + itoa10(prm.nUgFail, buf); + o.append("Ye:i:"); + o.append(buf); + } + if(print_yl_) { + // YL:i: Longest streak of failed DPs + WRITE_SEP(); + itoa10(prm.nDpFailStreak, buf); + o.append("YL:i:"); + o.append(buf); + // Yl:i: Longest streak of failed ungaps + WRITE_SEP(); + itoa10(prm.nUgFailStreak, buf); + o.append("Yl:i:"); + o.append(buf); + } + if(print_yu_) { + // YU:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nDpLastSucc, buf); + o.append("YU:i:"); + o.append(buf); + // Yu:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nUgLastSucc, buf); + o.append("Yu:i:"); + o.append(buf); + } + if(print_xp_) { + // XP:Z: String describing seed hits + WRITE_SEP(); + o.append("XP:B:I,"); + itoa10(prm.nSeedElts, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsFw, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsRc, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMean, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMedian, buf); + o.append(buf); + } + if(print_yr_) { + // YR:i: Redundant seed hits + WRITE_SEP(); + itoa10(prm.nRedundants, buf); + o.append("YR:i:"); + o.append(buf); + } + if(print_zb_) { + // ZB:i: Ftab ops for seed alignment + WRITE_SEP(); + itoa10(prm.nFtabs, buf); + o.append("ZB:i:"); + o.append(buf); + } + if(print_zr_) { + // ZR:Z: Redundant path skips in seed alignment + WRITE_SEP(); + o.append("ZR:Z:"); + itoa10(prm.nRedSkip, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedFail, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedIns, buf); o.append(buf); + } + if(print_zf_) { + // ZF:i: FM Index ops for seed alignment + WRITE_SEP(); + itoa10(prm.nSdFmops, buf); + o.append("ZF:i:"); + o.append(buf); + // Zf:i: FM Index ops for offset resolution + WRITE_SEP(); + itoa10(prm.nExFmops, buf); + o.append("Zf:i:"); + o.append(buf); + } + if(print_zm_) { + // ZM:Z: Print FM index op string for best-first search + WRITE_SEP(); + o.append("ZM:Z:"); + prm.fmString.print(o, buf); + } + if(print_zi_) { + // ZI:i: Seed extend loop iterations + WRITE_SEP(); + itoa10(prm.nExIters, buf); + o.append("ZI:i:"); + o.append(buf); + } + if(print_xs_a_) { + if(rna_strandness_ == RNA_STRANDNESS_UNKNOWN) { + uint8_t whichsense = res.spliced_whichsense_transcript(); + if(whichsense != SPL_UNKNOWN) { + WRITE_SEP(); + o.append("XS:A:"); + if(whichsense == SPL_FW || whichsense == SPL_SEMI_FW) { + o.append('+'); + } else { + assert(whichsense == SPL_RC || whichsense == SPL_SEMI_RC); + o.append('-'); + } + } + } else { + WRITE_SEP(); + o.append("XS:A:"); + char strandness = '+'; + if(res.readMate1()) { + if(res.orient()) { + if(rna_strandness_ == RNA_STRANDNESS_R || rna_strandness_ == RNA_STRANDNESS_RF) { + strandness = '-'; + } + } else { + if(rna_strandness_ == RNA_STRANDNESS_F || rna_strandness_ == RNA_STRANDNESS_FR) { + strandness = '-'; + } + } + } else { + assert(res.readMate2()); + assert(rna_strandness_ == RNA_STRANDNESS_FR || rna_strandness_ == RNA_STRANDNESS_RF); + if(res.orient()) { + if(rna_strandness_ == RNA_STRANDNESS_FR) { + strandness = '-'; + } + } else { + if(rna_strandness_ == RNA_STRANDNESS_RF) { + strandness = '-'; + } + } + } + o.append(strandness); + } + } + if(print_nh_) { + if(flags.alignedPaired()) { + WRITE_SEP(); + itoa10(summ.numAlnsPaired(), buf); + o.append("NH:i:"); + o.append(buf); + } else if(flags.alignedUnpaired() || flags.alignedUnpairedMate()) { + WRITE_SEP(); + itoa10((flags.alignedUnpaired() || flags.readMate1()) ? + summ.numAlns1() : summ.numAlns2(), buf); + o.append("NH:i:"); + o.append(buf); + } + } + + bool snp_first = true; + index_t prev_snp_idx = INDEX_MAX; + size_t len_trimmed = rd.length() - res.trimmed5p(true) - res.trimmed3p(true); + if(!res.fw()) { + Edit::invertPoss(const_cast&>(res.ned()), len_trimmed, false); + } + for(size_t i = 0; i < res.ned().size(); i++) { + if(res.ned()[i].snpID >= altdb->alts().size()) + continue; + index_t snp_idx = res.ned()[i].snpID; + assert_lt(snp_idx, altdb->alts().size()); + const ALT& snp = altdb->alts()[snp_idx]; + const string& snpID = altdb->altnames()[snp_idx]; + if(snp_idx == prev_snp_idx) continue; + if(snp_first) { + WRITE_SEP(); + o.append("Zs:Z:"); + } + if(!snp_first) o.append(","); + uint64_t pos = res.ned()[i].pos; + size_t j = i; + while(j > 0) { + if(res.ned()[j-1].snpID < altdb->alts().size()) { + const ALT& snp2 = altdb->alts()[res.ned()[j-1].snpID]; + if(snp2.type == ALT_SNP_SGL) { + pos -= (res.ned()[j-1].pos + 1); + } else if(snp2.type == ALT_SNP_DEL) { + pos -= res.ned()[j-1].pos; + } else if(snp2.type == ALT_SNP_INS) { + pos -= (res.ned()[j-1].pos + snp.len); + } + break; + } + j--; + } + itoa10(pos, buf); + o.append(buf); + o.append("|"); + if(snp.type == ALT_SNP_SGL) { + o.append("S"); + } else if(snp.type == ALT_SNP_DEL) { + o.append("D"); + } else { + assert_eq(snp.type, ALT_SNP_INS); + o.append("I"); + } + o.append("|"); + o.append(snpID.c_str()); + + if(snp_first) snp_first = false; + prev_snp_idx = snp_idx; + } + if(!res.fw()) { + Edit::invertPoss(const_cast&>(res.ned()), len_trimmed, false); + } + + if(print_xr_) { + // Original read string + o.append("\n"); + printOptFieldNewlineEscapedZ(o, rd.readOrigBuf); + } +} + +template +void SamConfig::printAlignedOptFlags( + Alignment* newAlignment, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // the read + AlnRes& res, // individual alignment result + StackedAln& staln, // stacked alignment buffer + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc, // scoring scheme + const char *mapqInp, // inputs to MAPQ calculation + const ALTDB* altdb) +const +{ + BTString &o = newAlignment->unChangedTags; + char buf[1024]; + if(print_as_) { + // AS:i: Alignment score generated by aligner + //itoa10(res.score().score(), buf); + newAlignment->AS = res.score().score(); + } + + // Do not output suboptimal alignment score, which conflicts with Cufflinks and StringTie + if(print_xs_) { + // XS:i: Suboptimal alignment score + // Use ZS:i: to avoid conflict with XS:A: + AlnScore sco = summ.secbestMate(rd.mate < 2); + if(sco.valid()) { + itoa10(sco.score(), buf); + WRITE_SEP(); + o.append("ZS:i:"); + o.append(buf); + } + } + if(print_xn_) { + // XN:i: Number of ambiguous bases in the referenece + itoa10(res.refNs(), buf); + WRITE_SEP(); + o.append("XN:i:"); + o.append(buf); + } + if(print_x0_) { + // X0:i: Number of best hits + } + if(print_x1_) { + // X1:i: Number of sub-optimal best hits + } + size_t num_mm = 0; + size_t num_go = 0; + size_t num_gx = 0; + for(size_t i = 0; i < res.ned().size(); i++) { + if(res.ned()[i].isMismatch()) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_mm++; + } + } else if(res.ned()[i].isReadGap()) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_go++; + num_gx++; + } + while(i < res.ned().size()-1 && + res.ned()[i+1].pos == res.ned()[i].pos && + res.ned()[i+1].isReadGap()) + { + i++; + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_gx++; + } + } + } else if(res.ned()[i].isRefGap()) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_go++; + num_gx++; + } + while(i < res.ned().size()-1 && + res.ned()[i+1].pos == res.ned()[i].pos+1 && + res.ned()[i+1].isRefGap()) + { + i++; + if(res.ned()[i].snpID >= altdb->alts().size()) { + num_gx++; + } + } + } + } + if(print_xm_) { + // XM:i: Number of mismatches in the alignment + //itoa10(num_mm, buf); + /*WRITE_SEP(); + o.append("XM:i:"); + o.append(buf);*/ + newAlignment->XM = num_mm; + } + if(print_xo_) { + // XO:i: Number of gap opens + itoa10(num_go, buf); + WRITE_SEP(); + o.append("XO:i:"); + o.append(buf); + } + if(print_xg_) { + // XG:i: Number of gap extensions (incl. opens) + itoa10(num_gx, buf); + WRITE_SEP(); + o.append("XG:i:"); + o.append(buf); + } + if(print_nm_) { + // NM:i: Edit dist. to the ref, Ns count, clipping doesn't + size_t NM = 0; + for(size_t i = 0; i < res.ned().size(); i++) { + if(res.ned()[i].type != EDIT_TYPE_SPL) { + if(res.ned()[i].snpID >= altdb->alts().size()) { + NM++; + } + } + } + newAlignment->NM = NM; + } + if(print_md_) { + // MD:Z: String for mms. [0-9]+(([A-Z]|\^[A-Z]+)[0-9]+)*2 + /*WRITE_SEP(); + o.append("MD:Z:");*/ + staln.buildMdz(); + staln.writeMdz( + &newAlignment->MD, // output buffer + NULL); // no char buffer + } + if(print_ys_ && summ.paired()) { + // YS:i: Alignment score of opposite mate + assert(res.oscore().valid()); + newAlignment->YS = res.oscore().score(); + } + if(print_yn_) { + // YN:i: Minimum valid score for this mate + TAlScore mn = sc.scoreMin.f(rd.length()); + itoa10(mn, buf); + WRITE_SEP(); + o.append("YN:i:"); + o.append(buf); + // Yn:i: Perfect score for this mate + TAlScore pe = sc.perfectScore(rd.length()); + itoa10(pe, buf); + WRITE_SEP(); + o.append("Yn:i:"); + o.append(buf); + } + if(print_xss_) { + // Xs:i: Best invalid alignment score of this mate + bool one = true; + if(flags.partOfPair() && !flags.readMate1()) { + one = false; + } + TAlScore bst = one ? prm.bestLtMinscMate1 : prm.bestLtMinscMate2; + if(bst > std::numeric_limits::min()) { + itoa10(bst, buf); + WRITE_SEP(); + o.append("Xs:i:"); + o.append(buf); + } + if(flags.partOfPair()) { + // Ys:i: Best invalid alignment score of opposite mate + bst = one ? prm.bestLtMinscMate2 : prm.bestLtMinscMate1; + if(bst > std::numeric_limits::min()) { + itoa10(bst, buf); + WRITE_SEP(); + o.append("Ys:i:"); + o.append(buf); + } + } + } + if(print_zs_) { + // ZS:i: Pseudo-random seed for read + itoa10(rd.seed, buf); + WRITE_SEP(); + o.append("ZS:i:"); + o.append(buf); + } + if(print_yt_ && !threeN) { + // YT:Z: String representing alignment type + WRITE_SEP(); + flags.printYT(o); + } + if(print_yp_ && flags.partOfPair() && flags.canMax()) { + // YP:i: Read was repetitive when aligned paired? + WRITE_SEP(); + flags.printYP(o); + } + if(print_ym_ && flags.canMax() && (flags.isMixedMode() || !flags.partOfPair())) { + // YM:i: Read was repetitive when aligned unpaired? + WRITE_SEP(); + flags.printYM(o); + } + if(print_yf_ && flags.filtered()) { + // YF:i: Read was filtered? + first = flags.printYF(o, first) && first; + } + if(print_yi_) { + // Print MAPQ calibration info + if(mapqInp[0] != '\0') { + // YI:i: Suboptimal alignment score + WRITE_SEP(); + o.append("YI:Z:"); + o.append(mapqInp); + } + } + if(flags.partOfPair() && print_zp_) { + // ZP:i: Score of best concordant paired-end alignment + WRITE_SEP(); + o.append("ZP:Z:"); + if(summ.bestPaired().valid()) { + itoa10(summ.bestPaired().score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + // Zp:i: Second-best concordant paired-end alignment score + WRITE_SEP(); + o.append("Zp:Z:"); + if(summ.secbestPaired().valid()) { + itoa10(summ.secbestPaired().score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + } + if(print_zu_) { + // ZU:i: Score of best unpaired alignment + AlnScore best = (rd.mate <= 1 ? summ.best1() : summ.best2()); + AlnScore secbest = (rd.mate <= 1 ? summ.secbest1() : summ.secbest2()); + WRITE_SEP(); + o.append("ZU:i:"); + if(best.valid()) { + itoa10(best.score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + // Zu:i: Score of second-best unpaired alignment + WRITE_SEP(); + o.append("Zu:i:"); + if(secbest.valid()) { + itoa10(secbest.score(), buf); + o.append(buf); + } else { + o.append("NA"); + } + } + if(!rgs_.empty()) { + WRITE_SEP(); + o.append(rgs_.c_str()); + } + if(print_xt_) { + // XT:i: Timing + WRITE_SEP(); + struct timeval tv_end; + struct timezone tz_end; + gettimeofday(&tv_end, &tz_end); + size_t total_usecs = + (tv_end.tv_sec - prm.tv_beg.tv_sec) * 1000000 + + (tv_end.tv_usec - prm.tv_beg.tv_usec); + itoa10(total_usecs, buf); + o.append("XT:i:"); + o.append(buf); + } + if(print_xd_) { + // XD:i: Extend DPs + WRITE_SEP(); + itoa10(prm.nExDps, buf); + o.append("XD:i:"); + o.append(buf); + // Xd:i: Mate DPs + WRITE_SEP(); + itoa10(prm.nMateDps, buf); + o.append("Xd:i:"); + o.append(buf); + } + if(print_xu_) { + // XU:i: Extend ungapped tries + WRITE_SEP(); + itoa10(prm.nExUgs, buf); + o.append("XU:i:"); + o.append(buf); + // Xu:i: Mate ungapped tries + WRITE_SEP(); + itoa10(prm.nMateUgs, buf); + o.append("Xu:i:"); + o.append(buf); + } + if(print_ye_) { + // YE:i: Streak of failed DPs at end + WRITE_SEP(); + itoa10(prm.nDpFail, buf); + o.append("YE:i:"); + o.append(buf); + // Ye:i: Streak of failed ungaps at end + WRITE_SEP(); + itoa10(prm.nUgFail, buf); + o.append("Ye:i:"); + o.append(buf); + } + if(print_yl_) { + // YL:i: Longest streak of failed DPs + WRITE_SEP(); + itoa10(prm.nDpFailStreak, buf); + o.append("YL:i:"); + o.append(buf); + // Yl:i: Longest streak of failed ungaps + WRITE_SEP(); + itoa10(prm.nUgFailStreak, buf); + o.append("Yl:i:"); + o.append(buf); + } + if(print_yu_) { + // YU:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nDpLastSucc, buf); + o.append("YU:i:"); + o.append(buf); + // Yu:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nUgLastSucc, buf); + o.append("Yu:i:"); + o.append(buf); + } + if(print_xp_) { + // XP:Z: String describing seed hits + WRITE_SEP(); + o.append("XP:B:I,"); + itoa10(prm.nSeedElts, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsFw, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsRc, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMean, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMedian, buf); + o.append(buf); + } + if(print_yr_) { + // YR:i: Redundant seed hits + WRITE_SEP(); + itoa10(prm.nRedundants, buf); + o.append("YR:i:"); + o.append(buf); + } + if(print_zb_) { + // ZB:i: Ftab ops for seed alignment + WRITE_SEP(); + itoa10(prm.nFtabs, buf); + o.append("ZB:i:"); + o.append(buf); + } + if(print_zr_) { + // ZR:Z: Redundant path skips in seed alignment + WRITE_SEP(); + o.append("ZR:Z:"); + itoa10(prm.nRedSkip, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedFail, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedIns, buf); o.append(buf); + } + if(print_zf_) { + // ZF:i: FM Index ops for seed alignment + WRITE_SEP(); + itoa10(prm.nSdFmops, buf); + o.append("ZF:i:"); + o.append(buf); + // Zf:i: FM Index ops for offset resolution + WRITE_SEP(); + itoa10(prm.nExFmops, buf); + o.append("Zf:i:"); + o.append(buf); + } + if(print_zm_) { + // ZM:Z: Print FM index op string for best-first search + WRITE_SEP(); + o.append("ZM:Z:"); + prm.fmString.print(o, buf); + } + if(print_zi_) { + // ZI:i: Seed extend loop iterations + WRITE_SEP(); + itoa10(prm.nExIters, buf); + o.append("ZI:i:"); + o.append(buf); + } + if(print_xs_a_) { + if(rna_strandness_ == RNA_STRANDNESS_UNKNOWN) { + uint8_t whichsense = res.spliced_whichsense_transcript(); + if(whichsense != SPL_UNKNOWN) { + WRITE_SEP(); + o.append("XS:A:"); + if(whichsense == SPL_FW || whichsense == SPL_SEMI_FW) { + o.append('+'); + } else { + assert(whichsense == SPL_RC || whichsense == SPL_SEMI_RC); + o.append('-'); + } + } + } else { + WRITE_SEP(); + o.append("XS:A:"); + char strandness = '+'; + if(res.readMate1()) { + if(res.orient()) { + if(rna_strandness_ == RNA_STRANDNESS_R || rna_strandness_ == RNA_STRANDNESS_RF) { + strandness = '-'; + } + } else { + if(rna_strandness_ == RNA_STRANDNESS_F || rna_strandness_ == RNA_STRANDNESS_FR) { + strandness = '-'; + } + } + } else { + assert(res.readMate2()); + assert(rna_strandness_ == RNA_STRANDNESS_FR || rna_strandness_ == RNA_STRANDNESS_RF); + if(res.orient()) { + if(rna_strandness_ == RNA_STRANDNESS_FR) { + strandness = '-'; + } + } else { + if(rna_strandness_ == RNA_STRANDNESS_RF) { + strandness = '-'; + } + } + } + o.append(strandness); + } + } + if(print_nh_) { + if(flags.alignedPaired()) { + /*WRITE_SEP(); + itoa10(summ.numAlnsPaired(), buf); + o.append("NH:i:"); + o.append(buf);*/ + newAlignment->NH = summ.numAlnsPaired(); + } else if(flags.alignedUnpaired() || flags.alignedUnpairedMate()) { + /*WRITE_SEP(); + itoa10((flags.alignedUnpaired() || flags.readMate1()) ? + summ.numAlns1() : summ.numAlns2(), buf); + o.append("NH:i:"); + o.append(buf);*/ + newAlignment->NH = (flags.alignedUnpaired() || flags.readMate1()) ? summ.numAlns1() : summ.numAlns2(); + } + } + + bool snp_first = true; + index_t prev_snp_idx = INDEX_MAX; + size_t len_trimmed = rd.length() - res.trimmed5p(true) - res.trimmed3p(true); + if(!res.fw()) { + Edit::invertPoss(const_cast&>(res.ned()), len_trimmed, false); + } + for(size_t i = 0; i < res.ned().size(); i++) { + if(res.ned()[i].snpID >= altdb->alts().size()) + continue; + index_t snp_idx = res.ned()[i].snpID; + assert_lt(snp_idx, altdb->alts().size()); + const ALT& snp = altdb->alts()[snp_idx]; + const string& snpID = altdb->altnames()[snp_idx]; + if(snp_idx == prev_snp_idx) continue; + if(snp_first) { + WRITE_SEP(); + o.append("Zs:Z:"); + } + if(!snp_first) o.append(","); + uint64_t pos = res.ned()[i].pos; + size_t j = i; + while(j > 0) { + if(res.ned()[j-1].snpID < altdb->alts().size()) { + const ALT& snp2 = altdb->alts()[res.ned()[j-1].snpID]; + if(snp2.type == ALT_SNP_SGL) { + pos -= (res.ned()[j-1].pos + 1); + } else if(snp2.type == ALT_SNP_DEL) { + pos -= res.ned()[j-1].pos; + } else if(snp2.type == ALT_SNP_INS) { + pos -= (res.ned()[j-1].pos + snp.len); + } + break; + } + j--; + } + itoa10(pos, buf); + o.append(buf); + o.append("|"); + if(snp.type == ALT_SNP_SGL) { + o.append("S"); + } else if(snp.type == ALT_SNP_DEL) { + o.append("D"); + } else { + assert_eq(snp.type, ALT_SNP_INS); + o.append("I"); + } + o.append("|"); + o.append(snpID.c_str()); + + if(snp_first) snp_first = false; + prev_snp_idx = snp_idx; + } + if(!res.fw()) { + Edit::invertPoss(const_cast&>(res.ned()), len_trimmed, false); + } + + if(print_xr_) { + // Original read string + newAlignment->passThroughLine.append("\n"); + printOptFieldNewlineEscapedZ(newAlignment->passThroughLine, rd.readOrigBuf); + } +} + +/** + * Print the optional flags to the given string. + */ +template +void SamConfig::printEmptyOptFlags( + BTString& o, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // read + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc) // scoring scheme +const +{ + char buf[1024]; + if(print_yn_) { + // YN:i: Minimum valid score for this mate + TAlScore mn = sc.scoreMin.f(rd.length()); + itoa10(mn, buf); + WRITE_SEP(); + o.append("YN:i:"); + o.append(buf); + // Yn:i: Perfect score for this mate + TAlScore pe = sc.perfectScore(rd.length()); + itoa10(pe, buf); + WRITE_SEP(); + o.append("Yn:i:"); + o.append(buf); + } + if(print_zs_) { + // ZS:i: Pseudo-random seed for read + itoa10(rd.seed, buf); + WRITE_SEP(); + o.append("ZS:i:"); + o.append(buf); + } + if(print_yt_&& !threeN) { + // YT:Z: String representing alignment type + WRITE_SEP(); + flags.printYT(o); + } + if(print_yp_ && flags.partOfPair() && flags.canMax()) { + // YP:i: Read was repetitive when aligned paired? + WRITE_SEP(); + flags.printYP(o); + } + if(print_ym_ && flags.canMax() && (flags.isMixedMode() || !flags.partOfPair())) { + // YM:i: Read was repetitive when aligned unpaired? + WRITE_SEP(); + flags.printYM(o); + } + if(print_yf_ && flags.filtered()) { + // YM:i: Read was repetitive when aligned unpaired? + first = flags.printYF(o, first) && first; + } + if(!rgs_.empty()) { + WRITE_SEP(); + o.append(rgs_.c_str()); + } + if(print_xt_) { + // XT:i: Timing + WRITE_SEP(); + struct timeval tv_end; + struct timezone tz_end; + gettimeofday(&tv_end, &tz_end); + size_t total_usecs = + (tv_end.tv_sec - prm.tv_beg.tv_sec) * 1000000 + + (tv_end.tv_usec - prm.tv_beg.tv_usec); + itoa10(total_usecs, buf); + o.append("XT:i:"); + o.append(buf); + } + if(print_xd_) { + // XD:i: Extend DPs + WRITE_SEP(); + itoa10(prm.nExDps, buf); + o.append("XD:i:"); + o.append(buf); + // Xd:i: Mate DPs + WRITE_SEP(); + itoa10(prm.nMateDps, buf); + o.append("Xd:i:"); + o.append(buf); + } + if(print_xu_) { + // XU:i: Extend ungapped tries + WRITE_SEP(); + itoa10(prm.nExUgs, buf); + o.append("XU:i:"); + o.append(buf); + // Xu:i: Mate ungapped tries + WRITE_SEP(); + itoa10(prm.nMateUgs, buf); + o.append("Xu:i:"); + o.append(buf); + } + if(print_ye_) { + // YE:i: Streak of failed DPs at end + WRITE_SEP(); + itoa10(prm.nDpFail, buf); + o.append("YE:i:"); + o.append(buf); + // Ye:i: Streak of failed ungaps at end + WRITE_SEP(); + itoa10(prm.nUgFail, buf); + o.append("Ye:i:"); + o.append(buf); + } + if(print_yl_) { + // YL:i: Longest streak of failed DPs + WRITE_SEP(); + itoa10(prm.nDpFailStreak, buf); + o.append("YL:i:"); + o.append(buf); + // Yl:i: Longest streak of failed ungaps + WRITE_SEP(); + itoa10(prm.nUgFailStreak, buf); + o.append("Yl:i:"); + o.append(buf); + } + if(print_yu_) { + // YU:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nDpLastSucc, buf); + o.append("YU:i:"); + o.append(buf); + // Yu:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nUgLastSucc, buf); + o.append("Yu:i:"); + o.append(buf); + } + if(print_xp_) { + // XP:Z: String describing seed hits + WRITE_SEP(); + o.append("XP:B:I,"); + itoa10(prm.nSeedElts, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsFw, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsRc, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMean, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMedian, buf); + o.append(buf); + } + if(print_yr_) { + // YR:i: Redundant seed hits + WRITE_SEP(); + itoa10(prm.nRedundants, buf); + o.append("YR:i:"); + o.append(buf); + } + if(print_zb_) { + // ZB:i: Ftab ops for seed alignment + WRITE_SEP(); + itoa10(prm.nFtabs, buf); + o.append("ZB:i:"); + o.append(buf); + } + if(print_zr_) { + // ZR:Z: Redundant path skips in seed alignment + WRITE_SEP(); + o.append("ZR:Z:"); + itoa10(prm.nRedSkip, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedFail, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedIns, buf); o.append(buf); + } + if(print_zf_) { + // ZF:i: FM Index ops for seed alignment + WRITE_SEP(); + itoa10(prm.nSdFmops, buf); + o.append("ZF:i:"); + o.append(buf); + // Zf:i: FM Index ops for offset resolution + WRITE_SEP(); + itoa10(prm.nExFmops, buf); + o.append("Zf:i:"); + o.append(buf); + } + if(print_zm_) { + // ZM:Z: Print FM index op string for best-first search + WRITE_SEP(); + o.append("ZM:Z:"); + prm.fmString.print(o, buf); + } + if(print_zi_) { + // ZI:i: Seed extend loop iterations + WRITE_SEP(); + itoa10(prm.nExIters, buf); + o.append("ZI:i:"); + o.append(buf); + } + if(print_xr_) { + // Original read string + o.append("\n"); + printOptFieldNewlineEscapedZ(o, rd.readOrigBuf); + } +} + +/** + * Print the optional flags to the given string. This function is for HISAT-3N. + */ + +template +void SamConfig::printEmptyOptFlags( + Alignment* newAlignment, // output buffer + bool first, // first opt flag printed is first overall? + const Read& rd, // read + const AlnFlags& flags, // alignment flags + const AlnSetSumm& summ, // summary of alignments for this read + const SeedAlSumm& ssm, // seed alignment summary + const PerReadMetrics& prm, // per-read metrics + const Scoring& sc) // scoring scheme +const +{ + char buf[1024]; + BTString &o = newAlignment->unChangedTags; + if(print_yn_) { + // YN:i: Minimum valid score for this mate + TAlScore mn = sc.scoreMin.f(rd.length()); + itoa10(mn, buf); + WRITE_SEP(); + o.append("YN:i:"); + o.append(buf); + // Yn:i: Perfect score for this mate + TAlScore pe = sc.perfectScore(rd.length()); + itoa10(pe, buf); + WRITE_SEP(); + o.append("Yn:i:"); + o.append(buf); + } + if(print_zs_) { + // ZS:i: Pseudo-random seed for read + itoa10(rd.seed, buf); + WRITE_SEP(); + o.append("ZS:i:"); + o.append(buf); + } + if(print_yt_&& !threeN) { + // YT:Z: String representing alignment type + WRITE_SEP(); + flags.printYT(o); + } + if(print_yp_ && flags.partOfPair() && flags.canMax()) { + // YP:i: Read was repetitive when aligned paired? + WRITE_SEP(); + flags.printYP(o); + } + if(print_ym_ && flags.canMax() && (flags.isMixedMode() || !flags.partOfPair())) { + // YM:i: Read was repetitive when aligned unpaired? + WRITE_SEP(); + flags.printYM(o); + } + if(print_yf_ && flags.filtered()) { + // YM:i: Read was repetitive when aligned unpaired? + first = flags.printYF(o, first) && first; + } + if(!rgs_.empty()) { + WRITE_SEP(); + o.append(rgs_.c_str()); + } + if(print_xt_) { + // XT:i: Timing + WRITE_SEP(); + struct timeval tv_end; + struct timezone tz_end; + gettimeofday(&tv_end, &tz_end); + size_t total_usecs = + (tv_end.tv_sec - prm.tv_beg.tv_sec) * 1000000 + + (tv_end.tv_usec - prm.tv_beg.tv_usec); + itoa10(total_usecs, buf); + o.append("XT:i:"); + o.append(buf); + } + if(print_xd_) { + // XD:i: Extend DPs + WRITE_SEP(); + itoa10(prm.nExDps, buf); + o.append("XD:i:"); + o.append(buf); + // Xd:i: Mate DPs + WRITE_SEP(); + itoa10(prm.nMateDps, buf); + o.append("Xd:i:"); + o.append(buf); + } + if(print_xu_) { + // XU:i: Extend ungapped tries + WRITE_SEP(); + itoa10(prm.nExUgs, buf); + o.append("XU:i:"); + o.append(buf); + // Xu:i: Mate ungapped tries + WRITE_SEP(); + itoa10(prm.nMateUgs, buf); + o.append("Xu:i:"); + o.append(buf); + } + if(print_ye_) { + // YE:i: Streak of failed DPs at end + WRITE_SEP(); + itoa10(prm.nDpFail, buf); + o.append("YE:i:"); + o.append(buf); + // Ye:i: Streak of failed ungaps at end + WRITE_SEP(); + itoa10(prm.nUgFail, buf); + o.append("Ye:i:"); + o.append(buf); + } + if(print_yl_) { + // YL:i: Longest streak of failed DPs + WRITE_SEP(); + itoa10(prm.nDpFailStreak, buf); + o.append("YL:i:"); + o.append(buf); + // Yl:i: Longest streak of failed ungaps + WRITE_SEP(); + itoa10(prm.nUgFailStreak, buf); + o.append("Yl:i:"); + o.append(buf); + } + if(print_yu_) { + // YU:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nDpLastSucc, buf); + o.append("YU:i:"); + o.append(buf); + // Yu:i: Index of last succesful DP + WRITE_SEP(); + itoa10(prm.nUgLastSucc, buf); + o.append("Yu:i:"); + o.append(buf); + } + if(print_xp_) { + // XP:Z: String describing seed hits + WRITE_SEP(); + o.append("XP:B:I,"); + itoa10(prm.nSeedElts, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsFw, buf); + o.append(buf); + o.append(','); + itoa10(prm.nSeedEltsRc, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMean, buf); + o.append(buf); + o.append(','); + itoa10(prm.seedMedian, buf); + o.append(buf); + } + if(print_yr_) { + // YR:i: Redundant seed hits + WRITE_SEP(); + itoa10(prm.nRedundants, buf); + o.append("YR:i:"); + o.append(buf); + } + if(print_zb_) { + // ZB:i: Ftab ops for seed alignment + WRITE_SEP(); + itoa10(prm.nFtabs, buf); + o.append("ZB:i:"); + o.append(buf); + } + if(print_zr_) { + // ZR:Z: Redundant path skips in seed alignment + WRITE_SEP(); + o.append("ZR:Z:"); + itoa10(prm.nRedSkip, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedFail, buf); o.append(buf); + o.append(','); + itoa10(prm.nRedIns, buf); o.append(buf); + } + if(print_zf_) { + // ZF:i: FM Index ops for seed alignment + WRITE_SEP(); + itoa10(prm.nSdFmops, buf); + o.append("ZF:i:"); + o.append(buf); + // Zf:i: FM Index ops for offset resolution + WRITE_SEP(); + itoa10(prm.nExFmops, buf); + o.append("Zf:i:"); + o.append(buf); + } + if(print_zm_) { + // ZM:Z: Print FM index op string for best-first search + WRITE_SEP(); + o.append("ZM:Z:"); + prm.fmString.print(o, buf); + } + if(print_zi_) { + // ZI:i: Seed extend loop iterations + WRITE_SEP(); + itoa10(prm.nExIters, buf); + o.append("ZI:i:"); + o.append(buf); + } + if(print_xr_) { + // Original read string + newAlignment->passThroughLine.append("\n"); + printOptFieldNewlineEscapedZ(newAlignment->passThroughLine, rd.readOrigBuf); + } +} + +#endif /* SAM_H_ */ diff --git a/scoring.cpp b/scoring.cpp new file mode 100644 index 0000000..1348821 --- /dev/null +++ b/scoring.cpp @@ -0,0 +1,286 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "scoring.h" + +using namespace std; + +/** + * Return true iff a read of length 'rdlen' passes the score filter, i.e., + * has enough characters to rise above the minimum score threshold. + */ +bool Scoring::scoreFilter( + int64_t minsc, + size_t rdlen) const +{ + int64_t sc = (int64_t)(rdlen * match(30)); + return sc >= minsc; +} + +/** + * Given the score floor for valid alignments and the length of the read, + * calculate the maximum possible number of read gaps that could occur in a + * valid alignment. + */ +int Scoring::maxReadGaps( + int64_t minsc, + size_t rdlen) const +{ + // Score if all characters match. TODO: remove assumption that match bonus + // is independent of quality value. + int64_t sc = (int64_t)(rdlen * match(30)); + assert_geq(sc, minsc); + // Now convert matches to read gaps until sc calls below minsc + bool first = true; + int num = 0; + while(sc >= minsc) { + if(first) { + first = false; + // Subtract both penalties + sc -= readGapOpen(); + } else { + // Subtract just the extension penalty + sc -= readGapExtend(); + } + num++; + } + assert_gt(num, 0); + return num-1; +} + +/** + * Given the score floor for valid alignments and the length of the read, + * calculate the maximum possible number of reference gaps that could occur + * in a valid alignment. + */ +int Scoring::maxRefGaps( + int64_t minsc, + size_t rdlen) const +{ + // Score if all characters match. TODO: remove assumption that match bonus + // is independent of quality value. + int64_t sc = (int64_t)(rdlen * match(30)); + assert_geq(sc, minsc); + // Now convert matches to read gaps until sc calls below minsc + bool first = true; + int num = 0; + while(sc >= minsc) { + sc -= match(30); + if(first) { + first = false; + // Subtract both penalties + sc -= refGapOpen(); + } else { + // Subtract just the extension penalty + sc -= refGapExtend(); + } + num++; + } + assert_gt(num, 0); + return num-1; +} + +/** + * Given a read sequence, return true iff the read passes the N filter. + * The N filter rejects reads with more than the number of Ns. + */ +bool Scoring::nFilter(const BTDnaString& rd, size_t& ns) const { + size_t rdlen = rd.length(); + size_t maxns = nCeil.f((double)rdlen); + assert_geq(rd.length(), 0); + for(size_t i = 0; i < rdlen; i++) { + if(rd[i] == 4) { + ns++; + if(ns > maxns) { + return false; // doesn't pass + } + } + } + return true; // passes +} + +/** + * Given a read sequence, return true iff the read passes the N filter. + * The N filter rejects reads with more than the number of Ns. + * + * For paired-end reads, there is a question of how to apply the filter. + * The filter could be applied to both mates separately, which might then + * prevent paired-end alignment. Or the filter could be applied to the + * reads as though they're concatenated together. The latter approach has + * pros and cons. The pro is that we can use paired-end information to + * recover alignments for mates that would not have passed the N filter on + * their own. The con is that we might not want to do that, since the + * non-N portion of the bad mate might contain particularly unreliable + * information. + */ +void Scoring::nFilterPair( + const BTDnaString* rd1, // mate 1 + const BTDnaString* rd2, // mate 2 + size_t& ns1, // # Ns in mate 1 + size_t& ns2, // # Ns in mate 2 + bool& filt1, // true -> mate 1 rejected by filter + bool& filt2) // true -> mate 2 rejected by filter + const +{ + // Both fail to pass by default + filt1 = filt2 = false; + if(rd1 != NULL && rd2 != NULL && ncatpair) { + size_t rdlen1 = rd1->length(); + size_t rdlen2 = rd2->length(); + size_t maxns = nCeil.f((double)(rdlen1 + rdlen2)); + for(size_t i = 0; i < rdlen1; i++) { + if((*rd1)[i] == 4) ns1++; + if(ns1 > maxns) { + // doesn't pass + return; + } + } + for(size_t i = 0; i < rdlen2; i++) { + if((*rd2)[i] == 4) ns2++; + if(ns2 > maxns) { + // doesn't pass + return; + } + } + // Both pass + filt1 = filt2 = true; + } else { + if(rd1 != NULL) filt1 = nFilter(*rd1, ns1); + if(rd2 != NULL) filt2 = nFilter(*rd2, ns2); + } +} + +#ifdef SCORING_MAIN + +int main() { + { + cout << "Case 1: Simple 1 ... "; + Scoring sc = Scoring::base1(); + assert_eq(COST_MODEL_CONSTANT, sc.matchType); + + assert_eq(0, sc.maxRefGaps(0, 10)); // 10 - 1 - 15 = -6 + assert_eq(0, sc.maxRefGaps(0, 11)); // 11 - 1 - 15 = -5 + assert_eq(0, sc.maxRefGaps(0, 12)); // 12 - 1 - 15 = -4 + assert_eq(0, sc.maxRefGaps(0, 13)); // 13 - 1 - 15 = -3 + assert_eq(0, sc.maxRefGaps(0, 14)); // 14 - 1 - 15 = -2 + assert_eq(0, sc.maxRefGaps(0, 15)); // 15 - 1 - 15 = -1 + assert_eq(1, sc.maxRefGaps(0, 16)); // 16 - 1 - 15 = 0 + assert_eq(1, sc.maxRefGaps(0, 17)); // 17 - 2 - 19 = -4 + assert_eq(1, sc.maxRefGaps(0, 18)); // 18 - 2 - 19 = -3 + assert_eq(1, sc.maxRefGaps(0, 19)); // 19 - 2 - 19 = -2 + assert_eq(1, sc.maxRefGaps(0, 20)); // 20 - 2 - 19 = -1 + assert_eq(2, sc.maxRefGaps(0, 21)); // 21 - 2 - 19 = 0 + + assert_eq(0, sc.maxReadGaps(0, 10)); // 10 - 0 - 15 = -5 + assert_eq(0, sc.maxReadGaps(0, 11)); // 11 - 0 - 15 = -4 + assert_eq(0, sc.maxReadGaps(0, 12)); // 12 - 0 - 15 = -3 + assert_eq(0, sc.maxReadGaps(0, 13)); // 13 - 0 - 15 = -2 + assert_eq(0, sc.maxReadGaps(0, 14)); // 14 - 0 - 15 = -1 + assert_eq(1, sc.maxReadGaps(0, 15)); // 15 - 0 - 15 = 0 + assert_eq(1, sc.maxReadGaps(0, 16)); // 16 - 0 - 19 = -3 + assert_eq(1, sc.maxReadGaps(0, 17)); // 17 - 0 - 19 = -2 + assert_eq(1, sc.maxReadGaps(0, 18)); // 18 - 0 - 19 = -1 + assert_eq(2, sc.maxReadGaps(0, 19)); // 19 - 0 - 19 = 0 + assert_eq(2, sc.maxReadGaps(0, 20)); // 20 - 0 - 23 = -3 + assert_eq(2, sc.maxReadGaps(0, 21)); // 21 - 0 - 23 = -2 + + // N ceiling: const=2, linear=0.1 + assert_eq(1, sc.nCeil(1)); + assert_eq(2, sc.nCeil(3)); + assert_eq(2, sc.nCeil(5)); + assert_eq(2, sc.nCeil(7)); + assert_eq(2, sc.nCeil(9)); + assert_eq(3, sc.nCeil(10)); + for(int i = 0; i < 30; i++) { + assert_eq(3, sc.n(i)); + assert_eq(3, sc.mm(i)); + } + assert_eq(5, sc.gapbar); + cout << "PASSED" << endl; + } + { + cout << "Case 2: Simple 2 ... "; + Scoring sc( + 4, // reward for a match + COST_MODEL_QUAL, // how to penalize mismatches + 0, // constant if mm pelanty is a constant + 30, // penalty for nuc mm in decoded colorspace als + -3.0f, // constant coeff for minimum score + -3.0f, // linear coeff for minimum score + DEFAULT_FLOOR_CONST, // constant coeff for score floor + DEFAULT_FLOOR_LINEAR, // linear coeff for score floor + 3.0f, // max # ref Ns allowed in alignment; const coeff + 0.4f, // max # ref Ns allowed in alignment; linear coeff + COST_MODEL_QUAL, // how to penalize Ns in the read + 0, // constant if N pelanty is a constant + true, // whether to concatenate mates before N filtering + 25, // constant coeff for cost of gap in the read + 25, // constant coeff for cost of gap in the ref + 10, // coeff of linear term for cost of gap in read + 10, // coeff of linear term for cost of gap in ref + 5, // 5 rows @ top/bot diagonal-entrance-only + -1, // no restriction on row + false // score prioritized over row + ); + + assert_eq(COST_MODEL_CONSTANT, sc.matchType); + assert_eq(4, sc.matchConst); + assert_eq(COST_MODEL_QUAL, sc.mmcostType); + assert_eq(COST_MODEL_QUAL, sc.npenType); + + assert_eq(0, sc.maxRefGaps(0, 8)); // 32 - 4 - 35 = -7 + assert_eq(0, sc.maxRefGaps(0, 9)); // 36 - 4 - 35 = -3 + assert_eq(1, sc.maxRefGaps(0, 10)); // 40 - 4 - 35 = 1 + assert_eq(1, sc.maxRefGaps(0, 11)); // 44 - 8 - 45 = -9 + assert_eq(1, sc.maxRefGaps(0, 12)); // 48 - 8 - 45 = -5 + assert_eq(1, sc.maxRefGaps(0, 13)); // 52 - 8 - 45 = -1 + assert_eq(2, sc.maxRefGaps(0, 14)); // 56 - 8 - 45 = 3 + + assert_eq(0, sc.maxReadGaps(0, 8)); // 32 - 0 - 35 = -3 + assert_eq(1, sc.maxReadGaps(0, 9)); // 36 - 0 - 35 = 1 + assert_eq(1, sc.maxReadGaps(0, 10)); // 40 - 0 - 45 = -5 + assert_eq(1, sc.maxReadGaps(0, 11)); // 44 - 0 - 45 = -1 + assert_eq(2, sc.maxReadGaps(0, 12)); // 48 - 0 - 45 = 3 + assert_eq(2, sc.maxReadGaps(0, 13)); // 52 - 0 - 55 = -3 + assert_eq(3, sc.maxReadGaps(0, 14)); // 56 - 0 - 55 = 1 + + // N ceiling: const=3, linear=0.4 + assert_eq(1, sc.nCeil(1)); + assert_eq(2, sc.nCeil(2)); + assert_eq(3, sc.nCeil(3)); + assert_eq(4, sc.nCeil(4)); + assert_eq(5, sc.nCeil(5)); + assert_eq(5, sc.nCeil(6)); + assert_eq(5, sc.nCeil(7)); + assert_eq(6, sc.nCeil(8)); + assert_eq(6, sc.nCeil(9)); + + for(int i = 0; i < 256; i++) { + assert_eq(i, sc.n(i)); + assert_eq(i, sc.mm(i)); + } + + assert_eq(5, sc.gapbar); + + cout << "PASSED" << endl; + } +} + +#endif /*def SCORING_MAIN*/ diff --git a/scoring.h b/scoring.h new file mode 100644 index 0000000..67aafaa --- /dev/null +++ b/scoring.h @@ -0,0 +1,546 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SCORING_H_ +#define SCORING_H_ + +#include +#include "qual.h" +#include "simple_func.h" +#include "limit.h" + +// Default type of bonus to added for matches +#define DEFAULT_MATCH_BONUS_TYPE COST_MODEL_CONSTANT +// When match bonus type is constant, use this constant +#define DEFAULT_MATCH_BONUS 0 +// Same settings but different defaults for --local mode +#define DEFAULT_MATCH_BONUS_TYPE_LOCAL COST_MODEL_CONSTANT +#define DEFAULT_MATCH_BONUS_LOCAL 2 + +// Default type of penalty to assess against mismatches +#define DEFAULT_MM_PENALTY_TYPE COST_MODEL_QUAL +// Default type of penalty to assess against mismatches +#define DEFAULT_MM_PENALTY_TYPE_IGNORE_QUALS COST_MODEL_CONSTANT +// When mismatch penalty type is constant, use this constant +#define DEFAULT_MM_PENALTY_MAX 6 +#define DEFAULT_MM_PENALTY_MIN 2 +// When softclip penalty type is constant, use this constant +#define DEFAULT_SC_PENALTY_MAX 2 +#define DEFAULT_SC_PENALTY_MIN 1 + +// Default type of penalty to assess against mismatches +#define DEFAULT_N_PENALTY_TYPE COST_MODEL_CONSTANT +// When mismatch penalty type is constant, use this constant +#define DEFAULT_N_PENALTY 1 + +// Constant coefficient b in linear function f(x) = ax + b determining +// minimum valid score f when read length is x +#define DEFAULT_MIN_CONST (-0.6f) +// Linear coefficient a +#define DEFAULT_MIN_LINEAR (-0.6f) +// Different defaults for --local mode +#define DEFAULT_MIN_CONST_LOCAL (0.0f) +#define DEFAULT_MIN_LINEAR_LOCAL (10.0f) + +// Constant coefficient b in linear function f(x) = ax + b determining +// maximum permitted number of Ns f in a read before it is filtered & +// the maximum number of Ns in an alignment before it is considered +// invalid. +#define DEFAULT_N_CEIL_CONST 0.0f +// Linear coefficient a +#define DEFAULT_N_CEIL_LINEAR 0.15f + +// Default for whether to concatenate mates before the N filter (as opposed to +// filting each mate separately) +#define DEFAULT_N_CAT_PAIR false + +// Default read gap penalties for when homopolymer calling is reliable +#define DEFAULT_READ_GAP_CONST 5 +#define DEFAULT_READ_GAP_LINEAR 3 + +// Default read gap penalties for when homopolymer calling is not reliable +#define DEFAULT_READ_GAP_CONST_BADHPOLY 3 +#define DEFAULT_READ_GAP_LINEAR_BADHPOLY 1 + +// Default reference gap penalties for when homopolymer calling is reliable +#define DEFAULT_REF_GAP_CONST 5 +#define DEFAULT_REF_GAP_LINEAR 3 + +// Default reference gap penalties for when homopolymer calling is not reliable +#define DEFAULT_REF_GAP_CONST_BADHPOLY 3 +#define DEFAULT_REF_GAP_LINEAR_BADHPOLY 1 + +enum { + COST_MODEL_ROUNDED_QUAL = 1, + COST_MODEL_QUAL, + COST_MODEL_CONSTANT +}; + +/** + * How to penalize various types of sequence dissimilarity, and other settings + * that govern how dynamic programming tables should be filled in and how to + * backtrace to find solutions. + */ +class Scoring { + + /** + * Init an array that maps quality to penalty or bonus according to 'type' + * and 'cons' + */ + template + void initPens( + T *pens, // array to fill + int type, // penalty type; qual | rounded qual | constant + int consMin, // constant for when penalty type is constant + int consMax) // constant for when penalty type is constant + { + if(type == COST_MODEL_ROUNDED_QUAL) { + for(int i = 0; i < 256; i++) { + pens[i] = (T)qualRounds[i]; + } + } else if(type == COST_MODEL_QUAL) { + assert_neq(consMin, 0); + assert_neq(consMax, 0); + for(int i = 0; i < 256; i++) { + int ii = min(i, 40); // TODO: Bit hacky, this + float frac = (float)ii / 40.0f; + pens[i] = consMin + (T)(frac * (consMax-consMin)); + assert_gt(pens[i], 0); + //if(pens[i] == 0) { + // pens[i] = ((consMax > 0) ? (T)1 : (T)-1); + //} + } + } else if(type == COST_MODEL_CONSTANT) { + for(int i = 0; i < 256; i++) { + pens[i] = (T)consMax; + } + } else { + throw 1; + } + } + +public: + + Scoring( + int mat, // reward for a match + int mmcType, // how to penalize mismatches + int mmpMax_, // maximum mismatch penalty + int mmpMin_, // minimum mismatch penalty + int scpMax_, // maximum softclip penalty + int scpMin_, // minimum softclip penalty + const SimpleFunc& scoreMin_, // minimum score for valid alignment; const coeff + const SimpleFunc& nCeil_, // max # ref Ns allowed in alignment; const coeff + int nType, // how to penalize Ns in the read + int n, // constant if N pelanty is a constant + bool ncat, // whether to concatenate mates before N filtering + int rdGpConst, // constant coeff for cost of gap in the read + int rfGpConst, // constant coeff for cost of gap in the ref + int rdGpLinear, // coeff of linear term for cost of gap in read + int rfGpLinear, // coeff of linear term for cost of gap in ref + int gapbar_, // # rows at top/bot can only be entered diagonally + int cp_ = 0, // canonical splicing penalty + int ncp_ = 12, // non-canonical splicing penalty + int csp_ = 24, // conflicting splice site penalty + const SimpleFunc* icp_ = NULL, // penalty as to intron length + const SimpleFunc* incp_ = NULL) // penalty as to intron length + { + matchType = COST_MODEL_CONSTANT; + matchConst = mat; + mmcostType = mmcType; + mmpMax = mmpMax_; + mmpMin = mmpMin_; + scpMax = scpMax_; + scpMin = scpMin_; + scoreMin = scoreMin_; + nCeil = nCeil_; + npenType = nType; + npen = n; + ncatpair = ncat; + rdGapConst = rdGpConst; + rfGapConst = rfGpConst; + rdGapLinear = rdGpLinear; + rfGapLinear = rfGpLinear; + qualsMatter_ = mmcostType != COST_MODEL_CONSTANT; + gapbar = gapbar_; + monotone = matchType == COST_MODEL_CONSTANT && matchConst == 0; + initPens(mmpens, mmcostType, mmpMin_, mmpMax_); + initPens(npens, npenType, npen, npen); + initPens(matchBonuses, matchType, matchConst, matchConst); + cp = cp_; + ncp = ncp_; + csp = csp_; + if(icp_ != NULL) icp = *icp_; + if(incp_ != NULL) incp = *incp_; + assert(repOk()); + } + + /** + * Set a constant match bonus. + */ + void setMatchBonus(int bonus) { + matchType = COST_MODEL_CONSTANT; + matchConst = bonus; + initPens(matchBonuses, matchType, matchConst, matchConst); + assert(repOk()); + } + + /** + * Set the mismatch penalty. + */ + void setMmPen(int mmType_, int mmpMax_, int mmpMin_) { + mmcostType = mmType_; + mmpMax = mmpMax_; + mmpMin = mmpMin_; + initPens(mmpens, mmcostType, mmpMin, mmpMax); + } + + /** + * Set the N penalty. + */ + void setNPen(int nType, int n) { + npenType = nType; + npen = n; + initPens(npens, npenType, npen, npen); + } + +#ifndef NDEBUG + /** + * Check that scoring scheme is internally consistent. + */ + bool repOk() const { + assert_geq(matchConst, 0); + assert_gt(rdGapConst, 0); + assert_gt(rdGapLinear, 0); + assert_gt(rfGapConst, 0); + assert_gt(rfGapLinear, 0); + return true; + } +#endif + + /** + * Return a linear function of x where 'cnst' is the constant coefficiant + * and 'lin' is the linear coefficient. + */ + static float linearFunc(int64_t x, float cnst, float lin) { + return (float)((double)cnst + ((double)lin * x)); + } + + /** + * Return the penalty incurred by a mismatch at an alignment column + * with read character 'rdc' reference mask 'refm' and quality 'q'. + * + * qs should be clamped to 63 on the high end before this query. + */ + inline int mm(int rdc, int refm, int q) const { + assert_range(0, 255, q); + return (rdc > 3 || refm > 15) ? npens[q] : mmpens[q]; + } + + /** + * Return the score of the given read character with the given quality + * aligning to the given reference mask. Take Ns into account. + */ + inline int score(int rdc, int refm, int q) const { + assert_range(0, 255, q); + if(rdc > 3 || refm > 15) { + return -npens[q]; + } + if((refm & (1 << rdc)) != 0) { + return (int)matchBonuses[q]; + } else { + return -mmpens[q]; + } + } + + /** + * Return the score of the given read character with the given quality + * aligning to the given reference mask. Take Ns into account. Increment + * a counter if it's an N. + */ + inline int score(int rdc, int refm, int q, int& ns) const { + assert_range(0, 255, q); + if(rdc > 3 || refm > 15) { + ns++; + return -npens[q]; + } + if((refm & (1 << rdc)) != 0) { + return (int)matchBonuses[q]; + } else { + return -mmpens[q]; + } + } + + /** + * Return the penalty incurred by a mismatch at an alignment column + * with read character 'rdc' and quality 'q'. We assume the + * reference character is non-N. + */ + inline int mm(int rdc, int q) const { + assert_range(0, 255, q); + return (rdc > 3) ? npens[q] : mmpens[q]; + } + + /** + * Return the marginal penalty incurred by a mismatch at a read + * position with quality 'q'. + */ + inline int mm(int q) const { + assert_geq(q, 0); + return q < 255 ? mmpens[q] : mmpens[255]; + } + + /** + * Return the marginal penalty incurred by a mismatch at a read + * position with quality 'q'. + */ + inline int sc(int q) const { + assert_geq(q, 0); + if(q <= 33) return scpMin; + q -= 33; + if(q > 40) q = 40; + return (int)((q / 40.0f) * (scpMax - scpMin) + scpMin); + } + + /** + * Return the marginal penalty incurred by a mismatch at a read + * position with quality 30. + */ + inline int64_t match() const { + return match(30); + } + + /** + * Return the marginal penalty incurred by a mismatch at a read + * position with quality 'q'. + */ + inline int64_t match(int q) const { + assert_geq(q, 0); + return (int64_t)((q < 255 ? matchBonuses[q] : matchBonuses[255]) + 0.5f); + } + + /** + * Return the best score achievable by a read of length 'rdlen'. + */ + inline int64_t perfectScore(size_t rdlen) const { + if(monotone) { + return 0; + } else { + return rdlen * match(30); + } + } + + /** + * Return true iff the penalities are such that two reads with the + * same sequence but different qualities might yield different + * alignments. + */ + inline bool qualitiesMatter() const { return qualsMatter_; } + + /** + * Return the marginal penalty incurred by an N mismatch at a read + * position with quality 'q'. + */ + inline int n(int q) const { + assert_geq(q, 0); + return q < 255 ? npens[q] : npens[255]; + } + + + /** + * Return the marginal penalty incurred by a gap in the read, + * given that this is the 'ext'th extension of the gap (0 = open, + * 1 = first, etc). + */ + inline int ins(int ext) const { + assert_geq(ext, 0); + if(ext == 0) return readGapOpen(); + return readGapExtend(); + } + + /** + * Return the marginal penalty incurred by a gap in the reference, + * given that this is the 'ext'th extension of the gap (0 = open, + * 1 = first, etc). + */ + inline int del(int ext) const { + assert_geq(ext, 0); + if(ext == 0) return refGapOpen(); + return refGapExtend(); + } + + /** + * Return true iff a read of length 'rdlen' passes the score filter, i.e., + * has enough characters to rise above the minimum score threshold. + */ + bool scoreFilter( + int64_t minsc, + size_t rdlen) const; + + /** + * Given the score floor for valid alignments and the length of the read, + * calculate the maximum possible number of read gaps that could occur in a + * valid alignment. + */ + int maxReadGaps( + int64_t minsc, + size_t rdlen) const; + + /** + * Given the score floor for valid alignments and the length of the read, + * calculate the maximum possible number of reference gaps that could occur + * in a valid alignment. + */ + int maxRefGaps( + int64_t minsc, + size_t rdlen) const; + + /** + * Given a read sequence, return true iff the read passes the N filter. + * The N filter rejects reads with more than the number of Ns calculated by + * taking nCeilConst + nCeilLinear * read length. + */ + bool nFilter(const BTDnaString& rd, size_t& ns) const; + + /** + * Given a read sequence, return true iff the read passes the N filter. + * The N filter rejects reads with more than the number of Ns calculated by + * taking nCeilConst + nCeilLinear * read length. + * + * For paired-end reads, there is a question of how to apply the filter. + * The filter could be applied to both mates separately, which might then + * prevent paired-end alignment. Or the filter could be applied to the + * reads as though they're concatenated together. The latter approach has + * pros and cons. The pro is that we can use paired-end information to + * recover alignments for mates that would not have passed the N filter on + * their own. The con is that we might not want to do that, since the + * non-N portion of the bad mate might contain particularly unreliable + * information. + */ + void nFilterPair( + const BTDnaString* rd1, // mate 1 + const BTDnaString* rd2, // mate 2 + size_t& ns1, // # Ns in mate 1 + size_t& ns2, // # Ns in mate 2 + bool& filt1, // true -> mate 1 rejected by filter + bool& filt2) // true -> mate 2 rejected by filter + const; + + /** + * The penalty associated with opening a new read gap. + */ + inline int readGapOpen() const { + return rdGapConst + rdGapLinear; + } + + /** + * The penalty associated with opening a new ref gap. + */ + inline int refGapOpen() const { + return rfGapConst + rfGapLinear; + } + + /** + * The penalty associated with extending a read gap by one character. + */ + inline int readGapExtend() const { + return rdGapLinear; + } + + /** + * The penalty associated with extending a ref gap by one character. + */ + inline int refGapExtend() const { + return rfGapLinear; + } + + // avg. known score: -22.96, avg. random score: -33.70 + inline int64_t canSpl(int intronlen = 0, int minanchor = 100, float probscore = 0.0f) const { + int penintron = (intronlen > 0 ? icp.f((double)intronlen) : 0); + if(penintron < 0) penintron = 0; + if(minanchor < 10 && probscore < -24.0f + (10 - minanchor)) { + return MAX_I32; + } + return penintron + cp; + } + + inline int64_t noncanSpl(int intronlen = 0, int minanchor = 100, float probscore = 0.0f) const { + if(minanchor < 14) return MAX_I32; + int penintron = (intronlen > 0 ? incp.f((double)intronlen) : 0); + if(penintron < 0) penintron = 0; + return penintron + ncp; + } + + inline int conflictSpl() const { return (int)csp; } + + int matchType; // how to reward matches + int matchConst; // reward for a match + int mmcostType; // based on qual? rounded? just a constant? + int mmpMax; // maximum mismatch penalty + int mmpMin; // minimum mismatch penalty + int scpMax; // maximum softclip penalty + int scpMin; // minimum softclip penalty + SimpleFunc scoreMin; // minimum score for valid alignment, constant coeff + SimpleFunc nCeil; // max # Ns involved in alignment, constant coeff + int npenType; // N: based on qual? rounded? just a constant? + int npen; // N: if mmcosttype=constant, this is the const + bool ncatpair; // true -> do N filtering on concated pair + int rdGapConst; // constant term coeffecient in extend cost + int rfGapConst; // constant term coeffecient in extend cost + int rdGapLinear; // linear term coeffecient in extend cost + int rfGapLinear; // linear term coeffecient in extend cost + int gapbar; // # rows at top/bot can only be entered diagonally + bool monotone; // scores can only go down? + float matchBonuses[256]; // map from qualities to match bonus + int mmpens[256]; // map from qualities to mm penalty + int npens[256]; // map from N qualities to penalty + int64_t cp; // canonical splicing penalty + int64_t ncp; // non-canonical splicing penalty + int64_t csp; // conflicting splice site penalty + SimpleFunc icp; // intron length penalty + SimpleFunc incp; // intron length penalty + + static Scoring base1() { + const double DMAX = std::numeric_limits::max(); + SimpleFunc scoreMin(SIMPLE_FUNC_LINEAR, 0.0f, DMAX, 37.0f, 0.3f); + SimpleFunc nCeil(SIMPLE_FUNC_LINEAR, 0.0f, DMAX, 2.0f, 0.1f); + return Scoring( + 1, // reward for a match + COST_MODEL_CONSTANT, // how to penalize mismatches + 3, // max mismatch penalty + 3, // min mismatch penalty + 2, // max softclip penalty + 2, // min softclip penalty + scoreMin, // score min: 37 + 0.3x + nCeil, // n ceiling: 2 + 0.1x + COST_MODEL_CONSTANT, // how to penalize Ns in the read + 3, // constant if N pelanty is a constant + false, // concatenate mates before N filtering? + 11, // constant coeff for gap in read + 11, // constant coeff for gap in ref + 4, // linear coeff for gap in read + 4, // linear coeff for gap in ref + 5); // 5 rows @ top/bot diagonal-entrance-only + } + +protected: + + bool qualsMatter_; +}; + +#endif /*SCORING_H_*/ diff --git a/scripts/convert_quals.pl b/scripts/convert_quals.pl new file mode 100644 index 0000000..abf344b --- /dev/null +++ b/scripts/convert_quals.pl @@ -0,0 +1,133 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +# +# convert_quals.pl +# +# Modify scale/encoding of quality values in a FASTQ file. +# +# Author: Ben Langmead +# Date: 5/5/2009 +# +# p = probability that base is miscalled +# Qphred = -10 * log10 (p) +# Qsolexa = -10 * log10 (p / (1 - p)) +# See: http://en.wikipedia.org/wiki/FASTQ_format +# + +use strict; +use warnings; +use Getopt::Long; + +my $inphred = 33; +my $insolexa = 0; +my $outphred = 0; +my $outsolexa = 64; + +# Default: convert 33-based Phred quals into 64-based Solexa qualss + +my $result = + GetOptions ("inphred=i" => \$inphred, + "insolexa=i" => \$insolexa, + "outphred=i" => \$outphred, + "outsolexa=i" => \$outsolexa); +$result == 1 || die "One or more errors parsing script arguments"; + +if($inphred > 0) { + $inphred >= 33 || die "Input base must be >= 33, was $inphred"; +} else { + $insolexa >= 33 || die "Input base must be >= 33, was $insolexa"; +} + +sub log10($) { + return log(shift) / log(10.0); +} + +sub round { + my($number) = shift; + return int($number + .5 * ($number <=> 0)); +} + +# Convert from phred qual to probability of miscall +sub phredToP($) { + my $phred = shift; + my $p = (10.0 ** (($phred) / -10.0)); + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p, from sol $phred"; + return $p; +} + +# Convert from solexa qual to probability of miscall +sub solToP($) { + my $sol = shift; + my $x = (10.0 ** (($sol) / -10.0)); + my $p = $x / (1.0 + $x); + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p, from x $x, phred $sol"; + return $p; +} + +# Convert from probability of miscall to phred qual +sub pToPhred($) { + my $p = shift; + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p"; + return round(-10.0 * log10($p)); +} + +# Convert from probability of miscall to solexa qual +sub pToSol($) { + my $p = shift; + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p"; + return 0.0 if $p == 1.0; + return round(-10.0 * log10($p / (1.0 - $p))); +} + +while(<>) { + my $name = $_; print $name; + my $seq = <>; print $seq; + my $name2 = <>; print $name2; + my $quals = <>; + chomp($quals); + my @qual = split(//, $quals); + for(my $i = 0; $i <= $#qual; $i++) { + my $co = ord($qual[$i]); + my $p; + # Convert input qual to p + if($inphred > 0) { + $co -= $inphred; + $co >= 0 || die "Bad Phred input quality: $co"; + $p = phredToP($co); + } else { + $co -= $insolexa; + $p = solToP($co); + } + # Convert p to output qual + if($outphred > 0) { + $co = pToPhred($p); + $co >= 0 || die "Bad Phred output quality: $co"; + $co += $outphred; + } else { + $co = pToSol($p); + $co += $outsolexa; + } + $co >= 33 || die "Error: Output qual " . $co . " char is less than 33. Try a larger output base."; + print chr($co); + } + print "\n"; +} diff --git a/scripts/gen_2b_occ_lookup.pl b/scripts/gen_2b_occ_lookup.pl new file mode 100644 index 0000000..a6e8ff5 --- /dev/null +++ b/scripts/gen_2b_occ_lookup.pl @@ -0,0 +1,106 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +# +# Generate lookup table that, given two packed DNA bytes (eight bases) +# and a character (A, C, G or T), returns how many times that character +# occurs in that packed pair of bytes. Useful for quickly counting +# character occurrences in long strings. The LUT is indexed first by +# character (0 - 3) then by byte (0 - 2^16-1). +# +# See ebwt.h. +# + +my @as = (); +my @cs = (); +my @gs = (); +my @ts = (); + +# Compile character arrays +my $i; +for($i = 0; $i < (256*256); $i++) { + + my $b01 = ($i >> 0) & 3; + my $b23 = ($i >> 2) & 3; + my $b45 = ($i >> 4) & 3; + my $b67 = ($i >> 6) & 3; + my $b89 = ($i >> 8) & 3; + my $b1011 = ($i >> 10) & 3; + my $b1213 = ($i >> 12) & 3; + my $b1415 = ($i >> 14) & 3; + + my $a = ($b01 == 0) + ($b23 == 0) + ($b45 == 0) + ($b67 == 0) + + ($b89 == 0) + ($b1011 == 0) + ($b1213 == 0) + ($b1415 == 0); + my $c = ($b01 == 1) + ($b23 == 1) + ($b45 == 1) + ($b67 == 1) + + ($b89 == 1) + ($b1011 == 1) + ($b1213 == 1) + ($b1415 == 1); + my $g = ($b01 == 2) + ($b23 == 2) + ($b45 == 2) + ($b67 == 2) + + ($b89 == 2) + ($b1011 == 2) + ($b1213 == 2) + ($b1415 == 2); + my $t = ($b01 == 3) + ($b23 == 3) + ($b45 == 3) + ($b67 == 3) + + ($b89 == 3) + ($b1011 == 3) + ($b1213 == 3) + ($b1415 == 3); + + push @as, $a; + push @cs, $c; + push @gs, $g; + push @ts, $t; +} + +my $entsPerLine = 16; + +# Count occurrences in all 4 bit pairs + +print "uint8_t cCntLUT_16b_4[4][256*256] = {\n"; + +# Print As array +print "\t/* As */ {\n"; +for($i = 0; $i < (256*256); $i++) { + print "\t\t" if(($i % $entsPerLine) == 0); + print "$as[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t},\n"; + +# Print Cs array +print "\t/* Cs */ {\n"; +for($i = 0; $i < (256*256); $i++) { + print "\t\t" if(($i % $entsPerLine) == 0); + print "$cs[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t},\n"; + +# Print Gs array +print "\t/* Gs */ {\n"; +for($i = 0; $i < (256*256); $i++) { + print "\t\t" if(($i % $entsPerLine) == 0); + print "$gs[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t},\n"; + +# Print Ts array +print "\t/* Ts */ {\n"; +for($i = 0; $i < (256*256); $i++) { + print "\t\t" if(($i % $entsPerLine) == 0); + print "$ts[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t}\n"; +print "};\n"; diff --git a/scripts/gen_occ_lookup.pl b/scripts/gen_occ_lookup.pl new file mode 100644 index 0000000..daba33f --- /dev/null +++ b/scripts/gen_occ_lookup.pl @@ -0,0 +1,257 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +# +# Generate lookup table that, given a packed DNA byte (four bases) and +# a character (A, C, G or T), returns how many times that character +# occurs in that packed byte. Useful for quickly counting character +# occurrences in long strings. The LUT is indexed first by character +# (0-3) then by byte (0-255). +# +# Larger lookup tables are also possible, though they seem +# counterproductive. E.g., looking up eight bases at a time yields a +# 256K LUT, which doesn't fit in L1. A four-base LUT is 1KB, easily +# fitting in L1. +# +# See ebwt.h. +# + +my @as4 = (), @as3 = (), @as2 = (), @as1 = (); +my @cs4 = (), @cs3 = (), @cs2 = (), @cs1 = (); +my @gs4 = (), @gs3 = (), @gs2 = (), @gs1 = (); +my @ts4 = (), @ts3 = (), @ts2 = (), @ts1 = (); + +# Compile character arrays +my $i; +for($i = 0; $i < 256; $i++) { + my $b01 = ($i >> 0) & 3; + my $b23 = ($i >> 2) & 3; + my $b45 = ($i >> 4) & 3; + my $b67 = ($i >> 6) & 3; + + my $a4 = ($b01 == 0) + ($b23 == 0) + ($b45 == 0) + ($b67 == 0); + my $c4 = ($b01 == 1) + ($b23 == 1) + ($b45 == 1) + ($b67 == 1); + my $g4 = ($b01 == 2) + ($b23 == 2) + ($b45 == 2) + ($b67 == 2); + my $t4 = ($b01 == 3) + ($b23 == 3) + ($b45 == 3) + ($b67 == 3); + + push @as4, $a4; + push @cs4, $c4; + push @gs4, $g4; + push @ts4, $t4; + + my $a3 = ($b01 == 0) + ($b23 == 0) + ($b45 == 0); + my $c3 = ($b01 == 1) + ($b23 == 1) + ($b45 == 1); + my $g3 = ($b01 == 2) + ($b23 == 2) + ($b45 == 2); + my $t3 = ($b01 == 3) + ($b23 == 3) + ($b45 == 3); + + push @as3, $a3; + push @cs3, $c3; + push @gs3, $g3; + push @ts3, $t3; + + my $a2 = ($b01 == 0) + ($b23 == 0); + my $c2 = ($b01 == 1) + ($b23 == 1); + my $g2 = ($b01 == 2) + ($b23 == 2); + my $t2 = ($b01 == 3) + ($b23 == 3); + + push @as2, $a2; + push @cs2, $c2; + push @gs2, $g2; + push @ts2, $t2; + + my $a1 = ($b01 == 0) + 0; + my $c1 = ($b01 == 1) + 0; + my $g1 = ($b01 == 2) + 0; + my $t1 = ($b01 == 3) + 0; + + push @as1, $a1; + push @cs1, $c1; + push @gs1, $g1; + push @ts1, $t1; +} + +my $entsPerLine = 16; + +print "#include \n\n"; +print "/* Generated by gen_lookup_tables.pl */\n\n"; + +# Count occurrences in all 4 bit pairs + +print "uint8_t cCntLUT_4[4][4][256] = {\n"; +print "\t/* All 4 bit pairs */ {\n"; + +# Print As array +print "\t\t/* As */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$as4[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Cs array +print "\t\t/* Cs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$cs4[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Gs array +print "\t\t/* Gs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$gs4[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Ts array +print "\t\t/* Ts */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$ts4[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t}\n\t},\n"; + +# Count occurrences in low 1 bit pair + +print "\t/* Least significant 1 bit pair */ {\n"; + +# Print As array +print "\t\t/* As */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$as1[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Cs array +print "\t\t/* Cs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$cs1[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Gs array +print "\t\t/* Gs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$gs1[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Ts array +print "\t\t/* Ts */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$ts1[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t}\n\t},\n"; + +# Count occurrences in low 2 bit pairs + +print "\t/* Least significant 2 bit pairs */ {\n"; + +# Print As array +print "\t\t/* As */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$as2[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Cs array +print "\t\t/* Cs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$cs2[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Gs array +print "\t\t/* Gs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$gs2[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Ts array +print "\t\t/* Ts */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$ts2[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t}\n\t},\n"; + +# Count occurrences in low 3 bit pairs + +print "\t/* Least significant 3 bit pairs */ {\n"; + +# Print As array +print "\t\t/* As */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$as3[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Cs array +print "\t\t/* Cs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$cs3[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Gs array +print "\t\t/* Gs */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$gs3[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t},\n"; + +# Print Ts array +print "\t\t/* Ts */ {\n"; +for($i = 0; $i < 256; $i++) { + print "\t\t\t" if(($i % $entsPerLine) == 0); + print "$ts3[$i], "; + print "\n" if(($i % $entsPerLine) == ($entsPerLine-1)); +} +print "\t\t}\n\t}\n"; + +print "};\n"; diff --git a/scripts/gen_solqual_lookup.pl b/scripts/gen_solqual_lookup.pl new file mode 100644 index 0000000..a1d5cd1 --- /dev/null +++ b/scripts/gen_solqual_lookup.pl @@ -0,0 +1,80 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +use warnings; +use strict; + +sub log10($) { + return log(shift) / log(10.0); +} + +sub round { + my($number) = shift; + return int($number + .5 * ($number <=> 0)); +} + +# Convert from solexa qual to probability of miscall +sub phredToP($) { + my $sol = shift; + my $p = (10.0 ** (($sol) / -10.0)); + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p, from sol $sol"; + return $p; +} + +# Convert from phred qual to probability of miscall +sub solToP($) { + my $phred = shift; + my $x = (10.0 ** (($phred) / -10.0)); + my $p = $x / (1.0 + $x); + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p, from x $x, phred $phred"; + return $p; +} + +# Convert from probability of miscall to phred qual +sub pToPhred($) { + my $p = shift; + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p"; + return round(-10.0 * log10($p)); +} + +# Convert from probability of miscall to solexa qual +sub pToSol($) { + my $p = shift; + ($p >= 0.0 && $p <= 1.0) || die "Bad prob: $p"; + return 0 if($p == 1.0); + return round(-10.0 * log10($p / (1.0 - $p))); +} + +# Print conversion table from Phred to Solexa +print "uint8_t solToPhred[] = {"; +my $cols = 10; +my $cnt = 0; +for(my $i = -10; $i < 256; $i++) { + # Solexa qual = $i + my $p = solToP($i); + my $ph = pToPhred($p); + print "\n\t/* $i */ " if($cnt == 0); + $cnt++; + $cnt = 0 if($cnt == 10); + print "$ph"; + print ", " if($i < 255); +} +print "\n};\n"; diff --git a/scripts/infer_fraglen.pl b/scripts/infer_fraglen.pl new file mode 100644 index 0000000..caf2f77 --- /dev/null +++ b/scripts/infer_fraglen.pl @@ -0,0 +1,132 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +## +# infer_fraglen.pl +# +# Infer fragment length by looking for unique alignments for mates +# (separately), then piecing those together and building a distribution. +# + +use strict; +use warnings; +use Getopt::Long; +use FindBin qw($Bin); + +my $m1 = ""; +my $m2 = ""; +my $index = ""; +my $bowtie_args = ""; +my $bowtie2 = "$Bin/../bowtie2"; +my $debug = 0; +my $binsz = 10; +my $mapq_cutoff = 30; +my $upto = undef; + +sub dieusage { + my $msg = shift; + my $exitlevel = shift; + $exitlevel = $exitlevel || 1; + print STDERR "$msg\n"; + exit $exitlevel; +} + +## +# Given a basename, return true iff all index files exist. +# +sub checkIndex($) { + my $idx = shift; + my $ext = "bt2"; + return -f "$idx.1.$ext" && + -f "$idx.2.$ext" && + -f "$idx.3.$ext" && + -f "$idx.4.$ext" && + -f "$idx.rev.1.$ext" && + -f "$idx.rev.2.$ext"; +} + +GetOptions ( + "bowtie2=s" => \$bowtie2, + "index=s" => \$index, + "m1=s" => \$m1, + "m2=s" => \$m2, + "upto=i" => \$upto, + "mapq_cutoff=i" => \$mapq_cutoff, + "debug" => \$debug, + "bowtie-args=s" => \$bowtie_args) || dieusage("Bad option", 1); + +die "Must specify --m1" if $m1 eq ""; +die "Must specify --m2" if $m2 eq ""; +die "Must specify --index" if $index eq ""; +$m1 =~ s/^~/$ENV{HOME}/; +$m2 =~ s/^~/$ENV{HOME}/; +$index =~ s/^~/$ENV{HOME}/; +die "Bad bowtie path: $bowtie2" if system("$bowtie2 --version >/dev/null 2>/dev/null") != 0; +die "Bad index: $index" if !checkIndex($index); + +# Hash holding all the observed fragment orientations and lengths +my %fragments = (); +my $m1cmd = ($m1 =~ /\.gz$/) ? "gzip -dc $m1" : "cat $m1"; +my $m2cmd = ($m2 =~ /\.gz$/) ? "gzip -dc $m2" : "cat $m2"; +my $cmd1 = "$m1cmd | $bowtie2 $bowtie_args --sam-nohead -x $index - > .infer_fraglen.tmp"; +my $cmd2 = "$m2cmd | $bowtie2 $bowtie_args --sam-nohead -x $index - |"; +my $tot = 0; +system($cmd1) == 0 || die "Error running '$cmd1'"; +open (M1, ".infer_fraglen.tmp") || die "Could not open '.infer_fraglen.tmp'"; +open (M2, $cmd2) || die "Could not open '$cmd2'"; +while() { + my $lm1 = $_; + my $lm2 = ; + chomp($lm1); chomp($lm2); + my @lms1 = split(/\t/, $lm1); + my @lms2 = split(/\t/, $lm2); + my ($name1, $flags1, $chr1, $off1, $mapq1, $slen1) = ($lms1[0], $lms1[1], $lms1[2], $lms1[3], $lms1[4], length($lms1[9])); + my ($name2, $flags2, $chr2, $off2, $mapq2, $slen2) = ($lms2[0], $lms2[1], $lms2[2], $lms2[3], $lms2[4], length($lms2[9])); + # One or both mates didn't align uniquely? + next if $chr1 eq "*" || $chr2 eq "*"; + # Mates aligned to different chromosomes? + next if $chr1 ne $chr2; + # MAPQs too low? + next if $mapq1 < $mapq_cutoff || $mapq2 < $mapq_cutoff; + # This pairing can be used as an observation of fragment orientation and length + my $fw1 = (($flags1 & 16) == 0) ? "F" : "R"; + my $fw2 = (($flags2 & 16) == 0) ? "F" : "R"; + my $frag = $off2 - $off1; + # This can overestimate if one mate is entirely subsumed in the other + if($frag > 0) { $frag += $slen2; } + else { $frag -= $slen1; } + # Install into bin + $frag = int(($frag + ($binsz/2))/$binsz); # Round to nearest bin + $fragments{"$fw1$fw2"}{$frag}++; + $tot++; +} +close(M1); +close(M2); +unlink(".infer_fraglen.tmp"); # ditch temporary file + +# Print out the bins +for my $k (keys %fragments) { + for my $k2 (sort {$a <=> $b} keys %{$fragments{$k}}) { + print "$k, ".($k2*$binsz).", ".$fragments{$k}{$k2}."\n"; + } +} + +print STDERR "DONE\n"; diff --git a/scripts/make_a_thaliana_tair.sh b/scripts/make_a_thaliana_tair.sh new file mode 100644 index 0000000..2a74bdf --- /dev/null +++ b/scripts/make_a_thaliana_tair.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# +# Downloads sequence for A. thaliana from TAIR v10 and build Bowtie 2 index. +# + +GENOMES_MIRROR=ftp://ftp.arabidopsis.org/home/tair + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +BOWTIE_BUILD_EXE=./bowtie2-build +if [ ! -x "$BOWTIE_BUILD_EXE" ] ; then + if ! which bowtie2-build ; then + echo "Could not find bowtie2-build in current directory or in PATH" + exit 1 + else + BOWTIE_BUILD_EXE=`which bowtie2-build` + fi +fi + +FC= +for c in 1 2 3 4 5 C M ; do + if [ ! -f TAIR10_chr$c.fas ] ; then + FN=TAIR10_chr$c.fas + F=${GENOMES_MIRROR}/Sequences/whole_chromosomes/${FN} + [ -n "$FC" ] && FC="$FC,$FN" + [ -z "$FC" ] && FC=$FN + get $F || (echo "Error getting $F" && exit 1) + fi + + if [ ! -f TAIR10_chr$c.fas ] ; then + echo "Could not find chr$c.fas file!" + exit 2 + fi +done + +CMD="${BOWTIE_BUILD_EXE} $* $FC a_thaliana" +echo $CMD +if $CMD ; then + echo "a_thaliana index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_b_taurus_UMD3.sh b/scripts/make_b_taurus_UMD3.sh new file mode 100644 index 0000000..94b3a57 --- /dev/null +++ b/scripts/make_b_taurus_UMD3.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Builds an index from UMD Freeze 3.0 of the Bos Taurus (cow) genome. +# + +BASE_CHRS="\ +Chr1 \ +Chr2 \ +Chr3 \ +Chr4 \ +Chr5 \ +Chr6 \ +Chr7 \ +Chr8 \ +Chr9 \ +Chr10 \ +Chr11 \ +Chr12 \ +Chr13 \ +Chr14 \ +Chr15 \ +Chr16 \ +Chr17 \ +Chr18 \ +Chr19 \ +Chr20 \ +Chr21 \ +Chr22 \ +Chr23 \ +Chr24 \ +Chr25 \ +Chr26 \ +Chr27 \ +Chr28 \ +Chr29 \ +ChrX \ +ChrU \ +ChrY-contigs \ +ChrY-contigs.SHOTGUN_ONLY" + +CHRS_TO_INDEX=$BASE_CHRS + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +BOWTIE_BUILD_EXE=./bowtie2-build +if [ ! -x "$BOWTIE_BUILD_EXE" ] ; then + if ! which bowtie2-build ; then + echo "Could not find bowtie2-build in current directory or in PATH" + exit 1 + else + BOWTIE_BUILD_EXE=`which bowtie2-build` + fi +fi + +FTP_BASE=ftp://ftp.cbcb.umd.edu/pub/data/Bos_taurus/Bos_taurus_UMD_3.0 +OUTPUT=b_taurus + +INPUTS= +for c in $CHRS_TO_INDEX ; do + if [ ! -f ${c}.fa ] ; then + F=${c}.fa.gz + get ${FTP_BASE}/$F || (echo "Error getting $F" && exit 1) + gunzip $F || (echo "Error unzipping $F" && exit 1) + fi + [ -n "$INPUTS" ] && INPUTS=$INPUTS,${c}.fa + [ -z "$INPUTS" ] && INPUTS=${c}.fa +done + +CMD="$BOWTIE_BUILD_EXE $* $INPUTS $OUTPUT" +echo $CMD +if $CMD ; then + echo "$OUTPUT index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_bdgp6.sh b/scripts/make_bdgp6.sh new file mode 100644 index 0000000..52c5ee5 --- /dev/null +++ b/scripts/make_bdgp6.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Downloads sequence for the BDGP6 release 84 version of drosophila melanogaster (fly) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/drosophila_melanogaster/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +F=Drosophila_melanogaster.BDGP6.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_bdgp6_tran.sh b/scripts/make_bdgp6_tran.sh new file mode 100644 index 0000000..6a2d7d2 --- /dev/null +++ b/scripts/make_bdgp6_tran.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Downloads sequence for the BDGP6 release 84 version of drosophila melanogaster (fly) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/drosophila_melanogaster/dna +ENSEMBL_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/drosophila_melanogaster +GTF_FILE=Drosophila_melanogaster.BDGP6.${ENSEMBL_RELEASE}.gtf + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Drosophila_melanogaster.BDGP6.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --ss genome.ss --exon genome.exon genome_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_canFam2.sh b/scripts/make_canFam2.sh new file mode 100644 index 0000000..272c563 --- /dev/null +++ b/scripts/make_canFam2.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# +# Downloads sequence for the canFam2 version of C. familiaris (dog) +# from UCSC. +# + +i=2 +BASE_CHRS=chr1 +while [ $i -lt 39 ] ; do + BASE_CHRS="$BASE_CHRS chr$i" + i=`expr $i + 1` +done +BASE_CHRS="$BASE_CHRS chrX chrM chrUn" +CHRS_TO_INDEX=$BASE_CHRS + +CANFAM2_BASE=ftp://hgdownload.cse.ucsc.edu/goldenPath/canFam2/chromosomes + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +BOWTIE_BUILD_EXE=./bowtie2-build +if [ ! -x "$BOWTIE_BUILD_EXE" ] ; then + if ! which bowtie2-build ; then + echo "Could not find bowtie2-build in current directory or in PATH" + exit 1 + else + BOWTIE_BUILD_EXE=`which bowtie2-build` + fi +fi + +INPUTS= +for c in $CHRS_TO_INDEX ; do + if [ ! -f ${c}.fa ] ; then + F=${c}.fa.gz + get ${CANFAM2_BASE}/$F || (echo "Error getting $F" && exit 1) + gunzip $F || (echo "Error unzipping $F" && exit 1) + fi + [ -n "$INPUTS" ] && INPUTS=$INPUTS,${c}.fa + [ -z "$INPUTS" ] && INPUTS=${c}.fa +done + +CMD="${BOWTIE_BUILD_EXE} $* ${INPUTS} canFam2" +echo Running $CMD +if $CMD ; then + echo "canFam2 index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_ce10.sh b/scripts/make_ce10.sh new file mode 100644 index 0000000..f3e9a86 --- /dev/null +++ b/scripts/make_ce10.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +CE10_BASE=ftp://hgdownload.cse.ucsc.edu/goldenPath/ce10/bigZips +F=chromFa.tar.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget -O `basename $1` $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${CE10_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzfO $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo "Running $CMD" +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi + diff --git a/scripts/make_dm6.sh b/scripts/make_dm6.sh new file mode 100644 index 0000000..dcb0cac --- /dev/null +++ b/scripts/make_dm6.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# +# Downloads sequence for a D. melanogaster from flybase. Currently set +# to download 5.22, but F, REL, and IDX_NAME can be edited to reflect a +# different version number. (But note that you will usually also have +# to change the date in REL.) +# + +DM6_BASE=ftp://hgdownload.cse.ucsc.edu/goldenPath/dm6/bigZips +F=dm6.fa.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget -O `basename $1` $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${DM6_BASE}/$F || (echo "Error getting $F" && exit 1) +gzip -cd $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo "Running $CMD" +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi + diff --git a/scripts/make_e_coli.sh b/scripts/make_e_coli.sh new file mode 100644 index 0000000..4ca9046 --- /dev/null +++ b/scripts/make_e_coli.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# +# Downloads the sequence for a strain of e. coli from NCBI and builds a +# Bowtie index for it +# + +GENOMES_MIRROR=ftp://ftp.ncbi.nlm.nih.gov/genomes + +BOWTIE_BUILD_EXE=./bowtie2-build +if [ ! -x "$BOWTIE_BUILD_EXE" ] ; then + if ! which bowtie2-build ; then + echo "Could not find bowtie2-build in current directory or in PATH" + exit 1 + else + BOWTIE_BUILD_EXE=`which bowtie2-build` + fi +fi + +if [ ! -f NC_008253.fna ] ; then + if ! which wget > /dev/null ; then + echo wget not found, looking for curl... + if ! which curl > /dev/null ; then + echo curl not found either, aborting... + else + # Use curl + curl ${GENOMES_MIRROR}/Bacteria/Escherichia_coli_536_uid58531/NC_008253.fna -o NC_008253.fna + fi + else + # Use wget + wget ${GENOMES_MIRROR}/Bacteria/Escherichia_coli_536_uid58531/NC_008253.fna + fi +fi + +if [ ! -f NC_008253.fna ] ; then + echo "Could not find NC_008253.fna file!" + exit 2 +fi + +CMD="${BOWTIE_BUILD_EXE} $* -t 8 NC_008253.fna e_coli" +echo $CMD +if $CMD ; then + echo "e_coli index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch37.sh b/scripts/make_grch37.sh new file mode 100644 index 0000000..ac93294 --- /dev/null +++ b/scripts/make_grch37.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh37 release 75 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh37 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=75 +ENSEMBL_GRCh37_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh37_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch37_snp.sh b/scripts/make_grch37_snp.sh new file mode 100644 index 0000000..26ac48d --- /dev/null +++ b/scripts/make_grch37_snp.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh37 release 75 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh37 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=75 +ENSEMBL_GRCh37_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg19/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh37_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype genome_snp" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch37_snp_tran.sh b/scripts/make_grch37_snp_tran.sh new file mode 100644 index 0000000..679b7c9 --- /dev/null +++ b/scripts/make_grch37_snp_tran.sh @@ -0,0 +1,112 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh37 release 75 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh37 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=75 +ENSEMBL_GRCh37_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna +ENSEMBL_GRCh37_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/homo_sapiens +GTF_FILE=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.gtf + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg19/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh37_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCh37_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype --ss genome.ss --exon genome.exon genome_snp_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch37_snp_tran_ercc.sh b/scripts/make_grch37_snp_tran_ercc.sh new file mode 100644 index 0000000..08d87f2 --- /dev/null +++ b/scripts/make_grch37_snp_tran_ercc.sh @@ -0,0 +1,117 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh37 release 75 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh37 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=75 +ENSEMBL_GRCh37_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna +ENSEMBL_GRCh37_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/homo_sapiens +GTF_FILE=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.gtf + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg19/database/${SNP_FILE} +ERCC_FILE=ERCC92 +ERCC_FTP=https://tools.thermofisher.com/content/sfs/manuals/${ERCC_FILE}.zip + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh37_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa + get ${ERCC_FTP} || (echo "Error getting ${ERCC_FILE}.zip" && exit 1) + unzip ${ERCC_FILE}.zip + cat ${ERCC_FILE}.fa >> genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCh37_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + cat ${ERCC_FILE}.gtf >> ${GTF_FILE} + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype --ss genome.ss --exon genome.exon genome_snp_tran_ercc" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch37_tran.sh b/scripts/make_grch37_tran.sh new file mode 100644 index 0000000..3ccf023 --- /dev/null +++ b/scripts/make_grch37_tran.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh37 release 75 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh37 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=75 +ENSEMBL_GRCh37_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna +ENSEMBL_GRCh37_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/homo_sapiens +GTF_FILE=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.gtf + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh37.${ENSEMBL_RELEASE}.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh37_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCh37_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --ss genome.ss --exon genome.exon genome_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch38.sh b/scripts/make_grch38.sh new file mode 100644 index 0000000..5e7b6a1 --- /dev/null +++ b/scripts/make_grch38.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh38 release 84 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh38 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCh38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch38_rep.sh b/scripts/make_grch38_rep.sh new file mode 100644 index 0000000..83a3baa --- /dev/null +++ b/scripts/make_grch38_rep.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh38 release 84 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh38 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCh38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_REPEAT_EXE=./hisat2-repeat +if [ ! -x "$HISAT2_REPEAT_EXE" ]; then + if ! which hisat2-repeat ; then + echo "Could not find hisat2-repeat in current directory or in PATH" + exit 1 + else + HISAT2_REPEAT_EXE=`which hisat2-repeat` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +# Build repeat +CMD="${HISAT2_REPEAT_EXE} -p 4 --repeat-count 5 --repeat-length 51-300,76-300,100-300,101-300,151-300 genome.fa genome_rep" +echo Running $CMD +$CMD +[[ "$?" -eq 0 ]] || { echo "Index building failed; see error message"; exit 1; }; + +CMD="${HISAT2_BUILD_EXE} -p 4 --repeat-ref genome_rep.rep.fa --repeat-info genome_rep.rep.info genome.fa genome_rep" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch38_snp.sh b/scripts/make_grch38_snp.sh new file mode 100644 index 0000000..be72089 --- /dev/null +++ b/scripts/make_grch38_snp.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh38 release 84 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh38 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCh38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype genome_snp" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch38_snp_rep.sh b/scripts/make_grch38_snp_rep.sh new file mode 100644 index 0000000..bb24b91 --- /dev/null +++ b/scripts/make_grch38_snp_rep.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh38 release 84 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh38 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCh38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +HISAT2_REPEAT_EXE=./hisat2-repeat +if [ ! -x "$HISAT2_REPEAT_EXE" ]; then + if ! which hisat2-repeat ; then + echo "Could not find hisat2-repeat in current directory or in PATH" + exit 1 + else + HISAT2_REPEAT_EXE=`which hisat2-repeat` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +# Build repeat +CMD="${HISAT2_REPEAT_EXE} -p 4 --repeat-count 5 --repeat-length 51-300,76-300,100-300,101-300,151-300 genome.fa genome_rep" +echo Running $CMD +$CMD +[[ "$?" -eq 0 ]] || { echo "Index building failed; see error message"; exit 1; }; + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype --repeat-ref genome_rep.rep.fa --repeat-info genome_rep.rep.info genome_snp_rep" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch38_snp_tran.sh b/scripts/make_grch38_snp_tran.sh new file mode 100644 index 0000000..06ec20a --- /dev/null +++ b/scripts/make_grch38_snp_tran.sh @@ -0,0 +1,112 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh38 release 84 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh38 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCh38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna +ENSEMBL_GRCh38_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/homo_sapiens +GTF_FILE=Homo_sapiens.GRCh38.${ENSEMBL_RELEASE}.gtf + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCh38_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype --ss genome.ss --exon genome.exon genome_snp_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch38_snp_tran_ercc.sh b/scripts/make_grch38_snp_tran_ercc.sh new file mode 100644 index 0000000..90b3d51 --- /dev/null +++ b/scripts/make_grch38_snp_tran_ercc.sh @@ -0,0 +1,117 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh38 release 84 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh38 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCh37_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna +ENSEMBL_GRCh37_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/homo_sapiens +GTF_FILE=Homo_sapiens.GRCh38.${ENSEMBL_RELEASE}.gtf + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg19/database/${SNP_FILE} +ERCC_FILE=ERCC92 +ERCC_FTP=https://tools.thermofisher.com/content/sfs/manuals/${ERCC_FILE}.zip + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh37_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa + get ${ERCC_FTP} || (echo "Error getting ${ERCC_FILE}.zip" && exit 1) + unzip ${ERCC_FILE}.zip + cat ${ERCC_FILE}.fa >> genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCh37_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + cat ${ERCC_FILE}.gtf >> ${GTF_FILE} + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype --ss genome.ss --exon genome.exon genome_snp_tran_ercc" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grch38_tran.sh b/scripts/make_grch38_tran.sh new file mode 100644 index 0000000..783aba4 --- /dev/null +++ b/scripts/make_grch38_tran.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCh38 release 84 version of H. sapiens (human) from +# Ensembl. +# +# Note that Ensembl's GRCh38 build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCh38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/homo_sapiens/dna +ENSEMBL_GRCh38_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/homo_sapiens +GTF_FILE=Homo_sapiens.GRCh38.${ENSEMBL_RELEASE}.gtf + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Homo_sapiens.GRCh38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCh38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCh38_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --ss genome.ss --exon genome.exon genome_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grcm38.sh b/scripts/make_grcm38.sh new file mode 100644 index 0000000..abc0322 --- /dev/null +++ b/scripts/make_grcm38.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCm38 release 81 version of M. Musculus (mouse) from +# Ensembl. +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCm38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/mus_musculus/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +F=Mus_musculus.GRCm38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCm38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grcm38_snp.sh b/scripts/make_grcm38_snp.sh new file mode 100644 index 0000000..fe52421 --- /dev/null +++ b/scripts/make_grcm38_snp.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCm37 release 81 version of M. Musculus (mouse) from +# Ensembl. +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCm38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/mus_musculus/dna + +DBSNP_RELEASE=142 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/mm10/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +rm -f genome.fa +F=Mus_musculus.GRCm38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCm38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype genome_snp" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grcm38_snp_tran.sh b/scripts/make_grcm38_snp_tran.sh new file mode 100644 index 0000000..a2b97c3 --- /dev/null +++ b/scripts/make_grcm38_snp_tran.sh @@ -0,0 +1,107 @@ +#!/bin/sh + +# +# Downloads sequence for the GRCm38 release 81 version of M. Musculus (mouse) from +# Ensembl. +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCm38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/mus_musculus/dna +ENSEMBL_GRCm38_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/mus_musculus +GTF_FILE=Mus_musculus.GRCm38.${ENSEMBL_RELEASE}.gtf + +DBSNP_RELEASE=142 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/mm10/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Mus_musculus.GRCm38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCm38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + gunzip ${SNP_FILE}.gz || (echo "Error unzipping ${SNP_FILE}" && exit 1) + awk 'BEGIN{OFS="\t"} {if($2 ~ /^chr/) {$2 = substr($2, 4)}; if($2 == "M") {$2 = "MT"} print}' ${SNP_FILE} > ${SNP_FILE}.tmp + mv ${SNP_FILE}.tmp ${SNP_FILE} + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE} genome +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCm38_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype --ss genome.ss --exon genome.exon genome_snp_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_grcm38_tran.sh b/scripts/make_grcm38_tran.sh new file mode 100644 index 0000000..4bfd7be --- /dev/null +++ b/scripts/make_grcm38_tran.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +# + +# Downloads sequence for the GRCm38 release 81 version of M. musculus (mouse) from +# Ensembl. +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_GRCm38_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/mus_musculus/dna +ENSEMBL_GRCm38_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/mus_musculus +GTF_FILE=Mus_musculus.GRCm38.${ENSEMBL_RELEASE}.gtf + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Mus_musculus.GRCm38.dna.primary_assembly.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_GRCm38_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GRCm38_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --ss genome.ss --exon genome.exon genome_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_hg19.sh b/scripts/make_hg19.sh new file mode 100644 index 0000000..1816e38 --- /dev/null +++ b/scripts/make_hg19.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# Downloads sequence for the HG19 version of H. sapiens (human) from +# UCSC. +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +UCSC_HG19_BASE=http://hgdownload.cse.ucsc.edu/goldenPath/hg19/bigZips +F=chromFa.tar.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${UCSC_HG19_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzfO $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_hg38.sh b/scripts/make_hg38.sh new file mode 100644 index 0000000..bc35479 --- /dev/null +++ b/scripts/make_hg38.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# Downloads sequence for the HG38 version of H. sapiens (human) from +# UCSC. +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +UCSC_HG38_BASE=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/bigZips +F=hg38.chromFa.tar.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${UCSC_HG38_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzfO $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_hg38_allsnp.sh b/scripts/make_hg38_allsnp.sh new file mode 100644 index 0000000..66d64d9 --- /dev/null +++ b/scripts/make_hg38_allsnp.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +# +# Downloads sequence for the HG38 version of H. spiens (human) from +# UCSC. +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +UCSC_HG38_BASE=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/bigZips +F=hg38.chromFa.tar.gz + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}.txt +UCSC_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +rm -f genome.fa +get ${UCSC_HG38_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzf $F || (echo "Error unzipping $F" && exit 1) +for i in {1..22}; do cat chroms/chr$i.fa >> genome.fa; done +cat chroms/chr[XYM].fa >> genome.fa +rm $F + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE}.gz genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 --large-index genome.fa --snp genome.snp --haplotype genome.haplotype genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_hg38_snp.sh b/scripts/make_hg38_snp.sh new file mode 100644 index 0000000..1dad607 --- /dev/null +++ b/scripts/make_hg38_snp.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +# +# Downloads sequence for the HG38 version of H. spiens (human) from +# UCSC. +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +UCSC_HG38_BASE=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/bigZips +F=hg38.chromFa.tar.gz + +DBSNP_RELEASE=144 +SNP_FILE=snp${DBSNP_RELEASE}Common.txt +UCSC_COMMON_SNP=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/${SNP_FILE} + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SNP_SCRIPT=./hisat2_extract_snps_haplotypes_UCSC.py +if [ ! -x "$HISAT2_SNP_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_UCSC.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_UCSC.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_UCSC.py` + fi +fi + +rm -f genome.fa +get ${UCSC_HG38_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzf $F || (echo "Error unzipping $F" && exit 1) +for i in {1..22}; do cat chroms/chr$i.fa >> genome.fa; done +cat chroms/chr[XYM].fa >> genome.fa +rm $F + +if [ ! -f $SNP_FILE ] ; then + get ${UCSC_COMMON_SNP}.gz || (echo "Error getting ${UCSC_COMMON_SNP}" && exit 1) + ${HISAT2_SNP_SCRIPT} genome.fa ${SNP_FILE}.gz genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_hg38_snp_tran.sh b/scripts/make_hg38_snp_tran.sh new file mode 100644 index 0000000..f1b4162 --- /dev/null +++ b/scripts/make_hg38_snp_tran.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# Downloads sequence for the HG38 version of H. spiens (human) from +# UCSC. +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +UCSC_HG38_BASE=http://hgdownload.cse.ucsc.edu/goldenPath/hg38/bigZips +F=hg38.chromFa.tar.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${UCSC_HG38_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzfO $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_mm10.sh b/scripts/make_mm10.sh new file mode 100644 index 0000000..d05af5b --- /dev/null +++ b/scripts/make_mm10.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# Downloads sequence for the MM10 version of M. musculus (mouse) from +# UCSC. +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +UCSC_MM10_BASE=http://hgdownload.cse.ucsc.edu/goldenPath/mm10/bigZips +F=chromFa.tar.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${UCSC_MM10_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzfO $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_mm9.sh b/scripts/make_mm9.sh new file mode 100644 index 0000000..e39c92c --- /dev/null +++ b/scripts/make_mm9.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +# +# Downloads sequence for the mm9 version of M. musculus (mouse) from +# UCSC. +# +# Note that UCSC's mm9 build has two categories of compressed fasta +# files: +# +# 1. The base files, named chr??.fa.gz +# 2. The unplaced-sequence files, named chr??_random.fa.gz +# +# By default, this script indexes all these files. To change which +# categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +BASE_CHRS="\ +chr1 \ +chr2 \ +chr3 \ +chr4 \ +chr5 \ +chr6 \ +chr7 \ +chr8 \ +chr9 \ +chr10 \ +chr11 \ +chr12 \ +chr13 \ +chr14 \ +chr15 \ +chr16 \ +chr17 \ +chr18 \ +chr19 \ +chrX \ +chrY \ +chrM" + +RANDOM_CHRS="\ +chr1_random \ +chr3_random \ +chr4_random \ +chr5_random \ +chr7_random \ +chr8_random \ +chr9_random \ +chr13_random \ +chr16_random \ +chr17_random \ +chrX_random \ +chrY_random \ +chrUn_random" + +CHRS_TO_INDEX="$BASE_CHRS $RANDOM_CHRS" + +UCSC_MM9_BASE=ftp://hgdownload.cse.ucsc.edu/goldenPath/mm9/chromosomes + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +BOWTIE_BUILD_EXE=./bowtie2-build +if [ ! -x "$BOWTIE_BUILD_EXE" ] ; then + if ! which bowtie2-build ; then + echo "Could not find bowtie2-build in current directory or in PATH" + exit 1 + else + BOWTIE_BUILD_EXE=`which bowtie2-build` + fi +fi + +INPUTS= +for c in $CHRS_TO_INDEX ; do + if [ ! -f ${c}.fa ] ; then + F=${c}.fa.gz + get ${UCSC_MM9_BASE}/$F || (echo "Error getting $F" && exit 1) + gunzip $F || (echo "Error unzipping $F" && exit 1) + fi + [ -n "$INPUTS" ] && INPUTS=$INPUTS,${c}.fa + [ -z "$INPUTS" ] && INPUTS=${c}.fa +done + +CMD="${BOWTIE_BUILD_EXE} $* ${INPUTS} mm9" +echo Running $CMD +if $CMD ; then + echo "mm9 index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_r64.sh b/scripts/make_r64.sh new file mode 100644 index 0000000..b0089af --- /dev/null +++ b/scripts/make_r64.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Downloads sequence for the R64-1-1 release 84 version of saccharomyces cerevisiae (yeast) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/saccharomyces_cerevisiae/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +F=Saccharomyces_cerevisiae.R64-1-1.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_r64_tran.sh b/scripts/make_r64_tran.sh new file mode 100644 index 0000000..7310a7d --- /dev/null +++ b/scripts/make_r64_tran.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Downloads sequence for the R64-1-1 release 84 version of saccharomyces cerevisiae (yeast) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/saccharomyces_cerevisiae/dna +ENSEMBL_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/saccharomyces_cerevisiae +GTF_FILE=Saccharomyces_cerevisiae.R64-1-1.${ENSEMBL_RELEASE}.gtf + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Saccharomyces_cerevisiae.R64-1-1.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --ss genome.ss --exon genome.exon genome_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_rn4.sh b/scripts/make_rn4.sh new file mode 100644 index 0000000..7ac9209 --- /dev/null +++ b/scripts/make_rn4.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +# +# Downloads sequence for the rn4 version of R. norvegicus (rat) from +# UCSC. +# +# Note that UCSC's rn4 build has two categories of compressed fasta +# files: +# +# 1. The base files, named chr??.fa.gz +# 2. The unplaced-sequence files, named chr??_random.fa.gz +# +# By default, this script indexes all these files. To change which +# categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +i=2 +BASE_CHRS=chr1 +while [ $i -lt 21 ] ; do + BASE_CHRS="$BASE_CHRS chr$i" + i=`expr $i + 1` +done +BASE_CHRS="$BASE_CHRS chrX chrM chrUn" + +RANDOM_CHRS="\ +chr1_random \ +chr2_random \ +chr3_random \ +chr4_random \ +chr5_random \ +chr6_random \ +chr7_random \ +chr8_random \ +chr9_random \ +chr10_random \ +chr11_random \ +chr12_random \ +chr13_random \ +chr14_random \ +chr15_random \ +chr16_random \ +chr17_random \ +chr18_random \ +chr19_random \ +chr20_random \ +chrX_random \ +chrUn_random" + +CHRS_TO_INDEX="$BASE_CHRS $RANDOM_CHRS" + +RN4_BASE=ftp://hgdownload.cse.ucsc.edu/goldenPath/rn4/chromosomes + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +BOWTIE_BUILD_EXE=./bowtie2-build +if [ ! -x "$BOWTIE_BUILD_EXE" ] ; then + if ! which bowtie2-build ; then + echo "Could not find bowtie2-build in current directory or in PATH" + exit 1 + else + BOWTIE_BUILD_EXE=`which bowtie2-build` + fi +fi + +INPUTS= +for c in $CHRS_TO_INDEX ; do + if [ ! -f ${c}.fa ] ; then + F=${c}.fa.gz + get ${RN4_BASE}/$F || (echo "Error getting $F" && exit 1) + gunzip $F || (echo "Error unzipping $F" && exit 1) + fi + [ -n "$INPUTS" ] && INPUTS=$INPUTS,${c}.fa + [ -z "$INPUTS" ] && INPUTS=${c}.fa +done + +CMD="${BOWTIE_BUILD_EXE} $* ${INPUTS} rn4" +echo Running $CMD +if $CMD ; then + echo "rn4 index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_rn6.sh b/scripts/make_rn6.sh new file mode 100644 index 0000000..7baa90e --- /dev/null +++ b/scripts/make_rn6.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Downloads sequence for the rn6 version of R. norvegicus (rat) from +# UCSC. +# +# Note that UCSC's rn6 build has two categories of compressed fasta +# files: +# +# 1. The base files, named chr??.fa.gz +# 2. The unplaced-sequence files, named chr??_random.fa.gz +# +# By default, this script indexes all these files. To change which +# categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +RN6_BASE=ftp://hgdownload.cse.ucsc.edu/goldenPath/rn6/bigZips +F=rn6.fa.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${RN6_BASE}/$F || (echo "Error getting $F" && exit 1) +gzip -cd $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_rnor6.sh b/scripts/make_rnor6.sh new file mode 100644 index 0000000..294ea12 --- /dev/null +++ b/scripts/make_rnor6.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Downloads sequence for the RNor_6.0 release 84 version of rattus_norvegicus (rat) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_RNOR6_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/rattus_norvegicus/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +F=Rattus_norvegicus.Rnor_6.0.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_RNOR6_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_rnor6_tran.sh b/scripts/make_rnor6_tran.sh new file mode 100644 index 0000000..8392a0b --- /dev/null +++ b/scripts/make_rnor6_tran.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Downloads sequence for the RNor_6.0 release 84 version of rattus_norvegicus (rat) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_RNOR6_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/rattus_norvegicus/dna +ENSEMBL_RNOR6_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/rattus_norvegicus +GTF_FILE=Rattus_norvegicus.Rnor_6.0.${ENSEMBL_RELEASE}.gtf + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Rattus_norvegicus.Rnor_6.0.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_RNOR6_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_RNOR6_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --ss genome.ss --exon genome.exon genome_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_sc3.sh b/scripts/make_sc3.sh new file mode 100644 index 0000000..bb5c393 --- /dev/null +++ b/scripts/make_sc3.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +SC3_BASE=ftp://hgdownload.cse.ucsc.edu/goldenPath/sacCer3/bigZips +F=chromFa.tar.gz + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +get ${SC3_BASE}/$F || (echo "Error getting $F" && exit 1) +tar xvzfO $F > genome.fa || (echo "Error unzipping $F" && exit 1) +rm $F + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_wbcel235.sh b/scripts/make_wbcel235.sh new file mode 100644 index 0000000..2c23a0d --- /dev/null +++ b/scripts/make_wbcel235.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Downloads sequence for the WBcel235 release 84 version of caenorhabditis elegans (worm) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/caenorhabditis_elegans/dna + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +rm -f genome.fa +F=Caenorhabditis_elegans.WBcel235.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa genome" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_wbcel235_tran.sh b/scripts/make_wbcel235_tran.sh new file mode 100644 index 0000000..eb7e208 --- /dev/null +++ b/scripts/make_wbcel235_tran.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Downloads sequence for the WBcel235 release 84 version of caenorhabditis elegans (worm) from +# Ensembl. +# +# Note that Ensembl's build has three categories of compressed fasta +# files: +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=84 +ENSEMBL_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/fasta/caenorhabditis_elegans/dna +ENSEMBL_GTF_BASE=ftp://ftp.ensembl.org/pub/release-${ENSEMBL_RELEASE}/gtf/caenorhabditis_elegans +GTF_FILE=Caenorhabditis_elegans.WBcel235.${ENSEMBL_RELEASE}.gtf + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Caenorhabditis_elegans.WBcel235.dna.toplevel.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --ss genome.ss --exon genome.exon genome_tran" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/make_zm3_snp_tran_ercc.sh b/scripts/make_zm3_snp_tran_ercc.sh new file mode 100644 index 0000000..adefca5 --- /dev/null +++ b/scripts/make_zm3_snp_tran_ercc.sh @@ -0,0 +1,110 @@ +#!/bin/sh + +# +# Downloads sequence for Zea mays AGPv3.31 from +# Ensembl. +# +# The base files, named ??.fa.gz +# +# By default, this script builds and index for just the base files, +# since alignments to those sequences are the most useful. To change +# which categories are built by this script, edit the CHRS_TO_INDEX +# variable below. +# + +ENSEMBL_RELEASE=31 +ENSEMBL_DNA_BASE=ftp://ftp.ensemblgenomes.org/pub/plants/release-${ENSEMBL_RELEASE}/fasta/zea_mays/dna/ +ENSEMBL_GTF_BASE=ftp://ftp.ensemblgenomes.org/pub/plants/release-${ENSEMBL_RELEASE}/gtf/zea_mays/ +GTF_FILE=Zea_mays.AGPv3.31.gtf + +ENSEMBL_VCF_BASE=ftp://ftp.ensemblgenomes.org/pub/plants/release-${ENSEMBL_RELEASE}/vcf/zea_mays/ +VCF_FILE=zea_mays.vcf.gz +ERCC_FILE=ERCC92 +ERCC_FTP=https://tools.thermofisher.com/content/sfs/manuals/${ERCC_FILE}.zip + +get() { + file=$1 + if ! wget --version >/dev/null 2>/dev/null ; then + if ! curl --version >/dev/null 2>/dev/null ; then + echo "Please install wget or curl somewhere in your PATH" + exit 1 + fi + curl -o `basename $1` $1 + return $? + else + wget $1 + return $? + fi +} + +HISAT2_BUILD_EXE=./hisat2-build +if [ ! -x "$HISAT2_BUILD_EXE" ] ; then + if ! which hisat2-build ; then + echo "Could not find hisat2-build in current directory or in PATH" + exit 1 + else + HISAT2_BUILD_EXE=`which hisat2-build` + fi +fi + +HISAT2_VCF_SCRIPT=./hisat2_extract_snps_haplotypes_VCF.py +if [ ! -x "$HISAT2_VCF_SCRIPT" ] ; then + if ! which hisat2_extract_snps_haplotypes_VCF.py ; then + echo "Could not find hisat2_extract_snps_haplotypes_VCF.py in current directory or in PATH" + exit 1 + else + HISAT2_SNP_SCRIPT=`which hisat2_extract_snps_haplotypes_VCF.py` + fi +fi + +HISAT2_SS_SCRIPT=./hisat2_extract_splice_sites.py +if [ ! -x "$HISAT2_SS_SCRIPT" ] ; then + if ! which hisat2_extract_splice_sites.py ; then + echo "Could not find hisat2_extract_splice_sites.py in current directory or in PATH" + exit 1 + else + HISAT2_SS_SCRIPT=`which hisat2_extract_splice_sites.py` + fi +fi + +HISAT2_EXON_SCRIPT=./hisat2_extract_exons.py +if [ ! -x "$HISAT2_EXON_SCRIPT" ] ; then + if ! which hisat2_extract_exons.py ; then + echo "Could not find hisat2_extract_exons.py in current directory or in PATH" + exit 1 + else + HISAT2_EXON_SCRIPT=`which hisat2_extract_exons.py` + fi +fi + +rm -f genome.fa +F=Zea_mays.AGPv3.31.dna.genome.fa +if [ ! -f $F ] ; then + get ${ENSEMBL_DNA_BASE}/$F.gz || (echo "Error getting $F" && exit 1) + gunzip $F.gz || (echo "Error unzipping $F" && exit 1) + mv $F genome.fa + get ${ERCC_FTP} || (echo "Error getting ${ERCC_FILE}.zip" && exit 1) + unzip ${ERCC_FILE}.zip + cat ${ERCC_FILE}.fa >> genome.fa +fi + +if [ ! -f $GTF_FILE ] ; then + get ${ENSEMBL_GTF_BASE}/${GTF_FILE}.gz || (echo "Error getting ${GTF_FILE}" && exit 1) + gunzip ${GTF_FILE}.gz || (echo "Error unzipping ${GTF_FILE}" && exit 1) + cat ${ERCC_FILE}.gtf >> ${GTF_FILE} + ${HISAT2_SS_SCRIPT} ${GTF_FILE} > genome.ss + ${HISAT2_EXON_SCRIPT} ${GTF_FILE} > genome.exon +fi + +if [ ! -f $VCF_FILE ] ; then + get ${ENSEMBL_VCF_BASE}/${VCF_FILE} || (echo "Error getting ${ENSEMBL_VCF_BASE}/${VCF_FILE}" && exit 1) + ${HISAT2_VCF_SCRIPT} --non-rs genome.fa ${VCF_FILE} genome +fi + +CMD="${HISAT2_BUILD_EXE} -p 4 genome.fa --snp genome.snp --haplotype genome.haplotype --ss genome.ss --exon genome.exon genome_snp_tran_ercc" +echo Running $CMD +if $CMD ; then + echo "genome index built; you may remove fasta files" +else + echo "Index building failed; see error message" +fi diff --git a/scripts/sa.py b/scripts/sa.py new file mode 100644 index 0000000..d27857d --- /dev/null +++ b/scripts/sa.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +""" +sa.py + +Parse and possibly sanity-check a .sa file output by bowtie2-build in --sa +mode. These files have a very simple format: first is a uint32_t containing +the length of the suffix array, the rest is an array of that many uint32_ts +containing the suffix array. +""" + +import sys +import struct + +def loadBowtieSa(fh): + """ Load a .sa file from handle into an array of ints """ + nsa = struct.unpack('I', fh.read(4))[0] + return [ struct.unpack('I', fh.read(4))[0] for i in xrange(0, nsa) ] + +def loadBowtieSaFilename(fn): + """ Load a .sa file from filename into an array of ints """ + with open(fn, 'rb') as fh: + return loadBowtieSa(fh) + +def loadFasta(fns): + """ Load the concatenation of all the A/C/G/T characters """ + falist = [] + dna = set(['A', 'C', 'G', 'T', 'a', 'c', 'g', 't']) + for fn in fns: + with open(fn, 'r') as fh: + for line in fh: + if line[0] == '>': + continue + for c in line: + if c in dna: + falist.append(c) + return ''.join(falist) + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(\ + description='Parse suffix array built from bowtie2-build') + + parser.add_argument(\ + '--sa', metavar='string', required=True, type=str, + help='Suffix array file') + parser.add_argument(\ + '--fa', metavar='string', type=str, nargs='+', help='FASTA file') + + args = parser.parse_args() + + def go(): + ref = None + if args.fa is not None: + ref = loadFasta(args.fa) + sas = loadBowtieSaFilename(args.sa) + # Suffix array is in sas; note that $ is considered greater than all + # other characters + if ref is not None: + for i in xrange(1, len(sas)): + sa1, sa2 = sas[i-1], sas[i] + assert sa1 != sa2 + # Sanity check that suffixes are really in order + while sa1 < len(ref) and sa2 < len(ref): + if ref[sa1] < ref[sa2]: + break + assert ref[sa1] == ref[sa2] + sa1 += 1 + sa2 += 1 + else: + # Note: Bowtie treats $ as greater than all other + # characters; so if these strings are tied up to the end of + # one or the other, the longer string is prior + assert sa1 < sa2, "%d, %d" % (sas[i-1], sas[i]) + assert sas[-1] == len(ref) + + go() + \ No newline at end of file diff --git a/scripts/sim/AlignmentCheck.pm b/scripts/sim/AlignmentCheck.pm new file mode 100644 index 0000000..fb259c4 --- /dev/null +++ b/scripts/sim/AlignmentCheck.pm @@ -0,0 +1,859 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +## +# AlignmentCheck.pm +# +# Read in fasta files containing reference sequences that might be +# aligned to, then read in alignment files, checking each alignment to +# be sure it's sane and consistent with the reference sequence it +# aligns to. +# + +package AlignmentCheck; +use strict; +use warnings; +use FindBin qw($Bin); +use lib $Bin; +use DNA; +use Data::Dumper; + +## +# Parse a fasta file into the %ref hash +# +sub parseFasta($$) { + my ($fa, $ref) = @_; + print STDERR "Parsing FASTA file $fa...\n"; + my $fapipe = "$fa"; + $fapipe = "gzip -dc $fa |" if $fa =~ /\.gz$/; + open(FA, $fapipe) || die "Could not open '$fapipe' for reading"; + my $name = ""; + my $bases = 0; + while() { + chomp; + if(/^>/) { + $name = substr($_, 1); + $name =~ s/\s.*//; + print STDERR " parsing sequence $name...\n"; + $ref->{std}{$name} = ""; + } else { + $name ne "" || die "sequence before name"; + $bases += length($_); + $ref->{std}{$name} .= $_; + } + } + print STDERR "Parsed $bases reference bases\n"; + close(FA); +} + +## +# Create a new alignment checker +# +sub new { + my ( + $class, + $name, # name of checker + $fas, # list of fasta files containing reference sequences + # or hash of the references themselves (former if it's + # an array ref latter if it's a hash ref) + $format, # alignment format + $bisC, # whether alignment was w/r/t ref w/ all Cs converted to Ys + $bisCpG, # whether alignment was w/r/t ref w/ all CpGs converted to YpGs + ) = @_; + (defined($fas)) || die "Must specify non-empty list of fasta files"; + # Set defaults for format, bisC, bisCpG, name + $format = "bowtie" unless defined($format); + $bisC = 0 unless defined($bisC); + $bisCpG = 0 unless defined($bisCpG); + $name = "noname" unless defined($name); + # Parse all the fasta files into the ref hash + my %ref = (); + if(ref($fas) eq "HASH") { + for (keys %$fas) { + $ref{std}{$_} = $fas->{$_} + } + } else { + ref($fas) eq "ARRAY" || die; + foreach (@$fas) { parseFasta($_, \%ref); } + } + return bless { + _name => $name, + _fas => $fas, + _format => $format, + _bisC => $bisC, + _bisCpG => $bisCpG, + _refs => \%ref, + _nals => 0, + _nedits => 0 + }, $class; +} +sub name { return $_[0]->{_name} } +sub fas { return $_[0]->{_fas} } +sub format { return $_[0]->{_format} } +sub bisC { return $_[0]->{_bisC} } +sub bisCpG { return $_[0]->{_bisCpG} } +sub refs { return $_[0]->{_refs} } +sub nals { return $_[0]->{_nals} } +sub nedits { return $_[0]->{_nedits} } +sub nrefs { return scalar(keys %{$_[0]->{_refs}}); } + +## +# Given a sequence that represents the read oriented s.t. the Watson- +# upstream end is on the left, and given a set of edits to apply to the +# read, also oriented assuming that Watson-upstream is on the left, +# return the string corresponding to the read mutated to match the +# reference. +# +my $nedits = 0; +sub applyEdits($$$) { + my ($seq, $edits, $line) = @_; + my $rfseq = $seq; + my $lpos = length($seq)+1; + $nedits += scalar(@$edits); + foreach (reverse @$edits) { + next unless defined($_); + #print STDERR "Applying edit at $_->{pos}\n"; + # Apply the edit + $_->{pos} <= $lpos || die "Edit position $_->{pos} was greater than previous $lpos"; + if($_->{qchr} eq "-") { + # Insert + $_->{pos} <= length($rfseq) || die "Read gap pos $_->{pos} was not <= string len ".length($rfseq)."\n$line"; + substr($rfseq, $_->{pos}, 0) = $_->{chr}; + } elsif($_->{chr} eq "-") { + # Deletion + $_->{pos} < length($rfseq) || die "Ref gap pos $_->{pos} was not < string len ".length($rfseq)."\n$line"; + my $dc = substr($rfseq, $_->{pos}, 1); + $dc eq $_->{qchr} || + die "Edit: $_->{pos}:$_->{chr}>$_->{qchr} but ref char was $dc". + "\n$rfseq\n$line"; + substr($rfseq, $_->{pos}, 1) = ""; + } else { + # Mismatch + $_->{pos} < length($rfseq) || die "Mismatch pos $_->{pos} was not < string len ".length($rfseq)."\n$line"; + substr($rfseq, $_->{pos}, 1) eq $_->{qchr} || + die "Edit: $_->{pos}:$_->{chr}>$_->{qchr}\n$rfseq\n$line"; + substr($rfseq, $_->{pos}, 1) = $_->{chr}; + } + } + return $rfseq; +} + +## +# Given a list of Bowtie edits, invert them by reversing the list and +# changing the poss to be with respect to the other end of the read. +# +sub invertEdits($$) { + my ($edits, $len) = @_; + @$edits = reverse @$edits; + for (@$edits) { + next unless defined($_); + defined($_->{qchr}) || die; + if($_->{qchr} eq "-") { + $_->{pos} = $len - $_->{pos}; + length($_->{chr}) >= 1 || die; + $_->{chr} = reverse $_->{chr}; + } else { + $_->{pos} = $len - $_->{pos} - 1; + length($_->{chr}) == 1 || die; + } + } +} + +## +# Given an edit string, parses it into a list of hashes and returns +# the list. +# +sub parseEdits($) { + my $editstr = shift; + return undef if (!defined($editstr) || $editstr eq "-" || $editstr eq ""); + my @edits = (); + # For each edit + for (split(/,/, $editstr)) { + # Parse pos + my ($pos, $ed) = split(/:/); + defined($ed) || die; + # Parse chr, qchr + my ($chr, $qchr) = split(/>/, $ed); + push @edits, { pos => $pos, chr => $chr, qchr => $qchr }; + } + return \@edits; +} + +## +# Given an edit string, possibly with 4 semicolon-delimited fields, +# parse it into a set of 4 lists of hashes and return the set as an +# array ref. +# +sub parseAllEdits($) { + my $editstr = shift; + return [ undef, undef, undef, undef ] if ($editstr eq "-" || $editstr eq ""); + my @editls = split(/;/, $editstr, -1); + if(scalar(@editls) > 1) { + scalar(@editls) == 4 || die; + return [ + parseEdits($editls[0]), + parseEdits($editls[1]), + parseEdits($editls[2]), + parseEdits($editls[3]) ]; + } else { + scalar(@editls) == 1 || die; + return [ + parseEdits($editls[0]), + undef, + undef, + undef ]; + } +} + +## +# Given array refs for two lists of edits, one corresponding to the +# nucleotide edit list and the other corresponding to the resolved +# ambiguous base list, eliminate any edits that appear in both lists. +# Really this shouldn't happen, but I observe that merman does report +# an edit in both categories if the reference base is being resolved to +# an incompatible nucleotide, e.g. R>C. +# +sub removeDups($$) { + my ($ned, $aed) = @_; + return unless (defined($ned) && defined($aed)); + for my $i (0..scalar(@$ned)-1) { + next unless defined($ned->[$i]); + for my $j (0..scalar(@$aed)-1) { + next unless defined($aed->[$j]); + if($ned->[$i]->{qchr} eq $aed->[$j]->{qchr} && + $ned->[$i]->{chr} eq $aed->[$j]->{chr} && + $ned->[$i]->{pos} eq $aed->[$j]->{pos}) + { + #print STDERR " Eliminated a duplicate edit\n"; + $aed->[$j] = undef; + } + } + } +} + +## +# Take all the references in %ref and make both Watson and Crick +# versions where the sequence is in-silico bisulfite treated. +# +sub bisulfiteC($) { + my $ref = shift; + for(keys %{$ref->{std}}) { + $ref->{bisc_fw}{$_} = $ref->{std}{$_}; + $ref->{bisc_fw}{$_} = s/C/Y/g; + $ref->{bisc_rc}{$_} = $ref->{std}{$_}; + $ref->{bisc_rc}{$_} = s/G/R/g; + } +} + +## +# Take all the references in %ref and make both Watson and Crick +# versions where the sequence is in-silico bisulfite treated. +# +sub bisulfiteCpG($) { + my $ref = shift; + for(keys %{$ref->{std}}) { + $ref->{biscpg_fw}{$_} = $ref->{std}{$_}; + $ref->{biscpg_fw}{$_} =~ s/CG/YG/g; + $ref->{biscpg_fw}{$_} =~ s/C/T/g; + $ref->{biscpg_rc}{$_} = $ref->{std}{$_}; + $ref->{biscpg_rc}{$_} =~ s/CG/CR/g; + $ref->{biscpg_rc}{$_} =~ s/G/A/g; + } +} + +## +# Given a Bowtie orientation string, return true iff the 5' end of the +# read is at the left of the printed sequence. +# +sub fivePrimeLeft($) { + return ($_[0] eq "+" || $_[0] eq "W" || $_[0] eq "CR"); +} + +## +# Given the orientation of the read and the state of the global +# bisulfite variables, determine which version of the reference to +# compare against. +# +sub calcRefType { + my ($self, $orient) = @_; + if($self->bisC || $self->bisCpG) { + if($orient eq "W" || $orient eq "WR" || $orient eq "+") { + return $self->bisC ? "bisc_fw" : "biscpg_fw"; + } else { + $orient eq "C" || $orient eq "CR" || $orient eq "-" || die; + return $self->bisC ? "bisc_rc" : "biscpg_rc"; + } + } else { + return "std"; + } +} + +## +# Parse a CIGAR string into parallel arrays of CIGAR operations (M, I, D) +# +sub cigarParse($$$) { + my ($cigar, $ops, $runs) = @_; + my $i = 0; + while($i < length($cigar)) { + substr($cigar, $i) =~ /^([0-9]+)/; + defined($1) || die "Could not parse number at pos $i: '$cigar'"; + $i += length($1); + $i < length($cigar) || die; + push @$runs, $1; + my $op = substr($cigar, $i, 1); + defined($op) || die "Could not parse operation at pos $i: '$cigar'"; + push @$ops, $op; + $i++; + } +} + +## +# Trim a read sequence according to the soft clipping in the CIGAR string. +# +sub cigarTrim($$) { + my ($seq, $cigar) = @_; + my @ops = (); + my @runs = (); + cigarParse($cigar, \@ops, \@runs); + my ($trimup, $trimdn) = (0, 0); + if($ops[0] eq 'S') { + $runs[0] < length($seq) || die "Soft clipped entire alignment!"; + $seq = substr($seq, $runs[0]); + $trimup = $runs[0]; + } + if(scalar(@ops) > 1 && $ops[-1] eq 'S') { + $runs[-1] < length($seq) || die "Soft clipped entire alignment!"; + $seq = substr($seq, 0, -$runs[-1]); + $trimdn = $runs[-1]; + } + return ($seq, $trimup, $trimdn); +} + +## +# Parse a CIGAR string into a string of operators. Operators are expanded into +# runs where appropriate. = and X are collapsed into M. +# +sub parse_cigar($) { + my ($cigar) = @_; + my $ret = ""; + my $i = 0; + my ($rdlen, $rflen) = (0, 0); + while($i < length($cigar)) { + substr($cigar, $i) =~ /^([0-9]+)/; + defined($1) || die "Could not parse number at pos $i: '$cigar'"; + my $runlen = $1; + $i += length($1); + $i < length($cigar) || die; + my $op = substr($cigar, $i, 1); + defined($op) || die "Could not parse operation at pos $i: '$cigar'"; + if($op eq "X" || $op eq "=") { + $op = "M"; + } + $rdlen += $runlen if $op ne "D"; + $rflen += $runlen if $op ne "I"; + $ret .= ($op x $runlen); + $i++; + } + return ($ret, $rdlen, $rflen); +} + +## +# Parse an MD:Z string into a string with length equal to query length. Each +# position contains either a space, if the read matches the reference at that +# position, or a character, if the reference contains a character that doesn't +# match its opposite in the alignment. In the latter case, the character in +# the string is the reference character. +# +sub parse_md($) { + my ($md) = @_; + my $i = 0; + my $ret = ""; + while($i < length($md)) { + # Starts with a number? + my $ch = substr($md, $i, 1); + if($ch =~ /[0-9]/) { + # Parse the number off the beginning + substr($md, $i) =~ /^([0-9]+)/; + defined($1) || die "Could not parse number at pos $i: '$md'"; + my $runlen = $1; + $ret .= (" " x $runlen) if $runlen > 0; + $i += length($runlen); + } elsif($ch eq "^") { + # Read gap + $i++; + substr($md, $i) =~ /^([A-Za-z]+)/; + defined($1) || die "Could not parse read gap at pos $i: '$md'"; + my $chrs = $1; + $i += length($chrs); + $ret .= $chrs; + } else { + # DNA character + $ch =~ /[ACGTN.]/i || die "Bad char '$ch' at pos $i: '$md'"; + $ret .= $ch; + $i++; + } + } + return $ret; +} + +## +# Given a read sequence (with characters in upstream-to-downstream order with +# respect to the reference - NOT necessarily 5'-to-3') and a CIGAR string and +# an MD:Z string, build the alignment strings. The alignment strings will only +# contain the portion of the read that aligned. Any portions that were either +# hard-trimmed or soft-trimmed are trimmed from this function's result. +# +# For now, I'm assuming that the MD:Z string only describes aligned characters, +# i.e. *after* trimming. +# +sub _read_md_cigar_to_al($$$) { + my ($seq, $md, $cigar) = @_; + my $alread = ""; + my $alref = ""; + $cigar ne "*" || die "CIGAR string was star!"; + $seq ne "" || die "Empty sequence given to _read_md_cigar_to_al"; + my $parsed_md = parse_md($md); + my ($parsed_cig, $cigar_rdlen, $cigar_rflen) = parse_cigar($cigar); + my ($rdoff, $mdoff) = (0, 0); + my ($htriml, $striml, $htrimr, $strimr) = (0, 0, 0, 0); + my $nonsh = 0; # have I seen a non-S, non-H CIGAR op? + my $nonh = 0; # have I seen a non-H CIGAR op? + for(my $i = 0; $i < length($parsed_cig); $i++) { + my $cigop = substr($parsed_cig, $i, 1); + $nonh++ if $cigop ne "H"; + $nonsh++ if ($cigop ne "H" && $cigop ne "S"); + if($cigop eq "S") { + if($nonsh) { + $strimr++; + } else { + $striml++; + } + $rdoff++; + next; + } + if($cigop eq "H") { + if($nonh) { + $htrimr++; + } else { + $htriml++; + } + next; + } + $cigop = "M" if $cigop eq "=" || $cigop eq "X"; + if($cigop eq "P") { + # Padding + $alread .= "-"; + $alref .= "-"; + } elsif($cigop eq "M") { + my $rdc = substr($seq, $rdoff, 1); + $mdoff < length($parsed_md) || + die "Bad mdoff ($mdoff)\nlength(parsed_md)=".length($parsed_md)."\nseq:\n$seq\ncigar:\n$cigar\nmd:\n$md\nparsed md:\n$parsed_md"; + my $rfc = substr($parsed_md, $mdoff, 1); + $rfc = $rdc if $rfc eq " "; + $alread .= $rdc; + $alref .= $rfc; + $rdoff++; + $mdoff++; + } elsif($cigop eq "D") { + # Read gap + # Read: AAA-AAA + # Ref: AAAAAAA + my $rfc = substr($parsed_md, $mdoff, 1); + $rfc ne " " || + die "Must have a ref character opposite a gap in the read:\n". + "cig: $parsed_cig ($i)\nmd: $parsed_md ($mdoff)\n"; + $alread .= "-"; + $alref .= $rfc; + $mdoff++; + } else { + # Reference gap + # Read: AAAAAAA + # Ref: AAA-AAA + $cigop eq "I" || die "Unsupported cigop: $cigop in cigar $cigar"; + my $rdc = substr($seq, $rdoff, 1); + $alread .= $rdc; + $alref .= "-"; + $rdoff++; + # $mdoff SHOULD NOT be incremented here + } + $rdoff <= length($seq) || + die "Bad rdoff:$rdoff for seq '$seq' cigop=$cigop\nseq: $seq\ncigar=$cigar\nmd=$md"; + } + return ($alread, $alref, $htriml, $striml, $htrimr, $strimr); +} + +## +# Parse a line from a Bowtie alignment file and check that the +# alignment is sane and consistent with the reference. +# +sub parseBowtieLines { + my ($self, $lines) = @_; + for my $line (@$lines) { + chomp($line); + my ($rdname, $orient, $refname, $off, $seq, $qual, $oms, $editstr, + $flags) = split(/\t/, $line, -1); + next if $refname eq "*"; + $flags =~ /XC:([^,\s]+)/; + my $cigar = $1; + defined($cigar) || + die "Could not parse CIGAR string from flags: '$flags'"; + defined($editstr) || die "Failed to get 8 tokens from line:\n$_"; + $off == int($off) || die "Offset field (col 4) must be an integer:\n$_"; + $oms == int($oms) || die "OMS field (col 7) must be an integer:\n$_"; + my $reftype = $self->calcRefType($orient); + defined($self->refs->{$reftype}{$refname}) || + die "No such refname as $refname for reftype $reftype:\n". + Dumper($self->refs->{$reftype}); + my $edits4 = parseAllEdits($editstr); + my ($ned, $aed) = ($edits4->[0], $edits4->[1]); + removeDups($ned, $aed); + my $fpl = fivePrimeLeft($orient); + # Trim seq according to CIGAR string + my $rfseq = $seq; + my ($trimup, $trimdn); + ($rfseq, $trimup, $trimdn) = cigarTrim($rfseq, $cigar); + invertEdits($ned, length($rfseq)) unless ($fpl || !defined($ned)); + invertEdits($aed, length($rfseq)) unless ($fpl || !defined($aed)); + $rfseq = applyEdits($rfseq, $ned, $line) if defined($ned); + $rfseq = applyEdits($rfseq, $aed, $line) if defined($aed); + # Check if our alignment falls off the end of the reference, in + # which case we need to pad the reference string with Ns + my $exoff = $off; + my $padleft = ""; + my $exlen = length($rfseq); + my $tlen = length($self->refs->{$reftype}{$refname}); + if($exoff < 0) { + # Alignment hangs off LHS; pad it + my $npad = -$exoff; + $padleft = "N" x $npad; + $exlen += $exoff; + $exlen >= 0 || + die "Read was entirely off the LHS of the reference\n". + "Referemce len=$tlen\n". + "Alignment referemce len=$tlen\n". + "$line\n"; + $exoff = 0; + } + my $padright = ""; + my $roverhang = $off + length($rfseq) - $tlen; + if($roverhang > 0) { + $padright = "N" x $roverhang; + $exlen -= $roverhang; + $exlen >= 0 || + die "Read was entirely off the RHS of the reference\n". + "Referemce len=$tlen\n". + "Alignment referemce len=$tlen\n". + "$line\n"; + } + my $refsub = substr($self->refs->{$reftype}{$refname}, $exoff, $exlen); + length($refsub) == $exlen || + die "Tried to extract ref substring of length $exlen, got ". + "\"$refsub\" from \"".$self->refs->{$reftype}{$refname}."\"". + "\n$line\n". + "\noff=$off, rfseq=$rfseq\n"; + $refsub = DNA::iupacSubN($refsub); + my $trueRfseq = $padleft . $refsub . $padright; + length($trueRfseq) == length($rfseq) || + die "Different lengths for edited read and ref:\n". + " Read: $seq\n". + "Edited read: $rfseq\n". + " Ref: $trueRfseq\n"; + $rfseq eq $trueRfseq || + die "Did not match:\n". + " Read: $seq\n". + "Edited read: $rfseq\n". + " Ref: $trueRfseq\n"; + $self->{_nals}++; + } +} + +## +# Parse a line from a SAM alignment file and check that the +# alignment is sane and consistent with the reference. +# +sub parseSamLines { + my ($self, $lines) = @_; + my ($lastseq, $lastqual) = ("", ""); + my $idx = 0; + for my $line (@$lines) { + $idx++; + print STDERR "Processing line...\n"; + chomp($line); + next if $line =~ /^\@/; + my @toks = split(/\t/, $line, -1); + my ( + $qname, #1 + $flag, #2 + $rname, #3 + $pos, #4 + $mapq, #5 + $cigar, #6 + $rnext, #7 + $pnext, #8 + $tlen, #9 + $seq, #10 + $qual) = @toks; + defined($qual) || die "Not enough SAM tokens:\n$line\n"; + my @opt_flags_list = @toks[11..$#toks]; + my %opt_flags = (); + next if $cigar eq "*"; # Failed to align + # Get the read sequence & qualities from previous record if necessary + if($seq eq "*") { + $lastseq ne "" || die "Line #$idx:\n$line"; + $seq = $lastseq; + $qual = $lastqual; + } else { + $lastseq = $seq; + $lastqual = $qual; + } + $seq ne "*" || die; + my ($parsed_cigar, $rdlen_cigar, $rflen_cigar) = parse_cigar($cigar); + length($seq) == $rdlen_cigar || + die "Sequence length and parsed cigar string length ($rdlen_cigar) mismatch:\n". + "$seq\n$parsed_cigar\nLine:\n$line"; + # Stick optional flags into a hash + for my $fl (@opt_flags_list) { + my @fs = split(/:/, $fl, -1); + scalar(@fs) > 2 || die "Bad optional flag: $fl\n$line\n"; + $opt_flags{$fs[0]}{type} = $fs[1]; + $opt_flags{$fs[0]}{value} = join(":", @fs[2..$#fs]); + } + defined($opt_flags{"MD"}) || die "No MD:Z flag:\n$line\n"; + $opt_flags{"MD"}{type} eq "Z" || die "Bad type for MD:Z flag\n$line\n"; + my $md = $opt_flags{"MD"}{value}; + $pos == int($pos) || die "POS field (col 4) must be an int:\n$line\n"; + $pnext == int($pnext) || die "PNEXT field (col 8) must be an int:\n$line\n"; + $tlen == int($tlen) || die "TLEN field (col 9) must be an int:\n$line\n"; + $mapq == int($mapq) || die "MAPQ field (col 5) must be an int:\n$line\n"; + # TODO: deal with bisulfite strands?? + my $fw = (($flag & 0x10) == 0); + my $orient = $fw ? "+" : "-"; + my $reftype = $self->calcRefType($orient); + defined($self->refs->{$reftype}{$rname}) || + die "No such refname as $rname for reftype $reftype:\n$line\n". + Dumper($self->refs->{$reftype}); + my $exoff = $pos-1; # expected 0-based reference offset + my ($alread, $alref, $htriml, $striml, $htrimr, $strimr) = + _read_md_cigar_to_al($seq, $md, $cigar); + print STDERR "$alread\n$alref\n"; + my $rfseq = $alref; + $rfseq =~ s/[ -]//g; # remove spaces & gaps + my $exlen = length($rfseq); + my $refsub = substr($self->refs->{$reftype}{$rname}, $exoff, $exlen); + length($refsub) == $exlen || + die "Tried to extract ref substring of length $exlen from:\n". + $self->refs->{$reftype}{$rname}. + "\ngot string of length ".length($refsub).":\n". + $refsub. + "\nfrom:\n". + $line. + "\nexlen is the length of:\n$rfseq\npos=$pos, rfseq=$rfseq\n"; + $refsub = DNA::iupacSubN($refsub); + my $trueRfseq = $refsub; + length($trueRfseq) == length($rfseq) || + die "Different lengths for edited read and ref:\n". + " Read: $seq\n". + "Edited read: $rfseq\n". + " Ref: $trueRfseq\n"; + $rfseq eq $trueRfseq || + die "Did not match:\n". + " Read: $seq\n". + "Edited read: $rfseq\n". + " Ref: $trueRfseq\n". + "$line"; + $self->{_nals}++; + } +} + +## +# Parse lines from a Bowtie alignment file and check that the +# alignments are sane and consistent with the reference. +# +sub parseBowtie { + my ($self, $fh) = @_; + while(<$fh>) { + $self->parseBowtieLines([$_]); + } +} + +## +# Parse lines from a SAM alignment file and check that alignments are +# sane and consistent with the reference. +# +sub parseSam { + my ($self, $fh) = @_; + my @lines = (); + while(<$fh>) { push @lines, $_; } + $self->parseSamLines(\@lines); +} + +## +# Parse lines from an alignment file of the type given by self->format +# +sub parseLines { + my ($self, $lines) = @_; + if($self->format eq "bowtie") { + $self->parseBowtieLines($lines); + } else { + $self->format eq "sam" || die; + $self->parseSamLines($lines); + } +} + +## +# Parse lines from an alignment file of the type given by self->format +# +sub parse { + my ($self, $fh) = @_; + if($self->format eq "bowtie") { + $self->parseBowtie($fh); + } else { + $self->format eq "sam" || die; + $self->parseSam($fh); + } +} + +## +# Print summary of how many alignments and edits were checked. +# +sub printSummary { + my $self = shift; + print STDERR "--- Summary ---\n"; + print STDERR "Read ".scalar(keys %{$self->refs})." reference strings\n"; + print STDERR "Checked $self->{_nals} alignments, $self->{_nedits} edits\n"; + print STDERR "---------------\n"; + print STDERR "PASSED\n"; +} + +## +# Check the given batch of alignments. We check that they're +# internally consistent in some basic ways, and we check that the +# sequence and edits are consistent with the reference. +# +# The $als argument is either a list of (possibly compressed) filenames +# of files containing alignments, or a list of alignment strings. If +# the former, $filenames is non-zero. +# +sub checkAlignments { + my ($self, $als, $filenames) = @_; + if($self->bisC) { + print STDERR "Generating all-C bisulfite-treated references\n"; + bisulfiteC($self->refs); + } + if($self->bisCpG) { + print STDERR "Generating all-CpG bisulfite-treated references\n"; + bisulfiteCpG($self->refs); + } + if($filenames) { + foreach (@$als) { + my $alnpipe = $_; + print STDERR "Processing alignment file '$_'\n"; + $alnpipe = "gzip -dc $_ |" if ($_ =~ /\.gz$/); + my $alnfh = undef; + open($alnfh, $alnpipe) || die "Could not open '$alnpipe' for reading"; + $self->parse($alnfh); + close($alnfh); + } + } else { + $self->parseLines($als); + } +} + +## +# Check simple alignments +# +sub test1 { + my $ac = AlignmentCheck->new( + "AlignmentCheck.pm test1 checker", + { "r1" => "TTGTTCGT" }, + "bowtie", + 0, + 0 + ); + $ac->checkAlignments([ + "0\t+\tr1\t1\tTGTTCGT\tIIIIIII\t40\t-", + "1\t+\tr1\t0\tTTGTTCG\tIIIIIII\t40\t-", + "2\t+\tr1\t2\tGTTCGTA\tIIIIIII\t40\t6:N>A", + "3\t+\tr1\t-1\tATTGTTC\tIIIIIII\t40\t0:N>A"], 0); + return 1; +} + +## +# Check simple alignments from files +# +sub test2 { + open(TMP, ">/tmp/.AlignmentCheck.pm.fa") || die; + print TMP ">r1\n"; + print TMP "TTGTTCGT\n"; + close(TMP); + my $ac = AlignmentCheck->new( + "AlignmentCheck.pm test1 checker", + [ "/tmp/.AlignmentCheck.pm.fa" ], + "bowtie", + 0, + 0 + ); + $ac->checkAlignments([ + "0\t+\tr1\t1\tTGTTCGT\tIIIIIII\t40\t-", + "1\t+\tr1\t0\tTTGTTCG\tIIIIIII\t40\t-", + "2\t+\tr1\t2\tGTTCGTA\tIIIIIII\t40\t6:N>A", + "3\t+\tr1\t-1\tATTGTTC\tIIIIIII\t40\t0:N>A"], 0); + return 1; +} + +if($0 =~ /[^0-9a-zA-Z_]?AlignmentCheck\.pm$/) { + my @fas = (); + my @als = (); + my $format = "sam"; + my $bisC = 0; + my $bisCpG = 0; + my $test = 0; + + use Getopt::Long; + GetOptions ( + "test" => \$test, + "fasta|ref=s" => \@fas, + "als|aln=s" => \@als, + "format=s" => \$format, + "bis-C|bisulfite-C" => \$bisC, + "bis-CpG|bisulfite-CpG" => \$bisCpG, + "bowtie" => sub {$format = "bowtie"}, + "sam" => sub {$format = "sam"}) || die; + + if($test) { + use Test; + print "Running unit tests\n"; + # Run unit tests + Test::shouldSucceed("test1", \&test1); + Test::shouldSucceed("test2", \&test2); + exit 0; + } + + my $ac = AlignmentCheck->new( + "AlignmentCheck.pm checker", + \@fas, + $format, + $bisC, + $bisCpG); + $ac->checkAlignments(\@als, 1); +} + +1; diff --git a/scripts/sim/DNA.pm b/scripts/sim/DNA.pm new file mode 100644 index 0000000..bf6b4e2 --- /dev/null +++ b/scripts/sim/DNA.pm @@ -0,0 +1,287 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package DNA; +use strict; +use warnings; +use Carp; +use FindBin qw($Bin); +use lib $Bin; +use Test; + +## +# Set up uppercase IUPAC characters minus N +# +my %iupac_u_nn = ( + "R" => 1, + "Y" => 1, + "M" => 1, + "K" => 1, + "S" => 1, + "W" => 1, + "B" => 1, + "V" => 1, + "H" => 1, + "D" => 1 +); + +## +# Return true iff arg is an IUPAC code and not ACGT or N. +# +sub isIUPAC($) { + return defined($iupac_u_nn{$_[0]}); +} + +## +# Replace IUPAC characters with Ns. +# +sub iupacSubN($) { + $_[0] =~ tr/RYMKSWBVHDrymkswbvhd/NNNNNNNNNNnnnnnnnnnn/; + return $_[0]; +} + +my %compat = ( + "A" => "A", + "T" => "T", + "C" => "C", + "G" => "G", + "R" => "AG", + "Y" => "CT", + "M" => "AC", + "K" => "GT", + "S" => "CG", + "W" => "AT", + "B" => "CGT", + "V" => "ACG", + "H" => "ACT", + "D" => "AGT", + "N" => "ACGT" +); + +## +# Pick a random character that's compatible with input character. +# +sub pickCompat($) { + my $c = uc $_[0]; + defined($compat{$c}) || die "Bad input $c"; + my $cc = $compat{$c}; + if(length($cc) == 1) { + return $cc; + } else { + length($cc) > 1 || die; + return substr($cc, int(rand(length($cc))), 1); + } +} + +my %incompat = ( + "A" => "CGT", + "T" => "ACG", + "C" => "AGT", + "G" => "ACT", + "R" => "CT", + "Y" => "AG", + "M" => "GT", + "K" => "AC", + "S" => "AT", + "W" => "CG", + "B" => "A", + "V" => "T", + "H" => "G", + "D" => "C", + "N" => "ACGT" +); + +## +# Pick a random character that's compatible with input character. +# +sub pickIncompat($) { + my $c = uc $_[0]; + defined($incompat{$c}) || die "Bad input $c"; + my $cc = $incompat{$c}; + if(length($cc) == 1) { + return $cc; + } else { + length($cc) > 1 || die; + return substr($cc, int(rand(length($cc))), 1); + } +} + +## +# Set up lowercase IUPAC characters minus N +# +my %iupac_l_nn = ( + "r" => 1, + "y" => 1, + "m" => 1, + "k" => 1, + "s" => 1, + "w" => 1, + "b" => 1, + "v" => 1, + "h" => 1, + "d" => 1 +); + +my %revcompMap = ( + "A" => "T", + "T" => "A", + "C" => "G", + "G" => "C", + "R" => "Y", + "Y" => "R", + "M" => "K", + "K" => "M", + "S" => "S", + "W" => "W", + "B" => "V", + "V" => "B", + "H" => "D", + "D" => "H", + "N" => "N", + "a" => "t", + "t" => "a", + "c" => "g", + "g" => "c", + "r" => "y", + "y" => "r", + "m" => "k", + "k" => "m", + "s" => "s", + "w" => "w", + "b" => "v", + "v" => "b", + "h" => "d", + "d" => "h", + "n" => "n" +); + +my %unambigSet = ( + "A" => 1, "a" => 1, + "C" => 1, "c" => 1, + "G" => 1, "g" => 1, + "T" => 1, "t" => 1 +); + +## +# Return the complement, incl. if it's IUPAC. +# +sub comp($) { + my $s = uc shift; + return $s =~ tr/ACGTRYMKSWBVHDN/TGCAYRKMSWVBDHN/; +} + +## +# Return the reverse complement of a string. +# +sub revcomp($) { + my $s = uc shift; + $s = reverse $s; + $s =~ tr/ACGTRYMKSWBVHDN/TGCAYRKMSWVBDHN/; + return $s; +} + +## +# Return true iff it's unambiguous. +# +sub unambig($) { + return $unambigSet{$_[0]}; +} + +## +# Manipulate DNA in an integer-indexed fashion. +# +sub plus($$) { + my ($c, $amt) = @_; + my %ctoi = ("A" => 0, "C" => 1, "G" => 2, "T" => 3); + my %itoc = (0 => "A", 1 => "C", 2 => "G", 3 => "T"); + $c = uc $c; + defined($ctoi{$c}) || die "Not an unambiguous nucleotide: $c"; + return $itoc{($ctoi{$c}+$amt) % 4}; +} + +my %dinucToColorMap = ( + "AA" => "0", + "AC" => "1", + "AG" => "2", + "AT" => "3", + "CC" => "0", + "CG" => "3", + "CT" => "2", + "GG" => "0", + "GT" => "1", + "TT" => "0", + + "AN" => ".", + "CN" => ".", + "GN" => ".", + "NT" => ".", + "NN" => ".", +); + +sub dinucToColor($$) { + my ($n1, $n2) = @_; + if(ord($n2) < ord($n1)) { + my $tmp = $n1; + $n1 = $n2; + $n2 = $tmp; + } + ord($n1) <= ord($n2) || die; + defined($dinucToColorMap{"$n1$n2"}) || + die "Bad nucleotide dinuc: '$n1$n2'"; + return $dinucToColorMap{"$n1$n2"}; +} + +sub test1 { + plus("A", 1) eq "C" || die; + plus("C", 1) eq "G" || die; + plus("G", 1) eq "T" || die; + plus("T", 1) eq "A" || die; + return 1; +} + +sub test2 { + plus("A", 2) eq "G" || die; + plus("C", 2) eq "T" || die; + plus("G", 2) eq "A" || die; + plus("T", 2) eq "C" || die; + return 1; +} + +sub test3 { + revcomp("ACGT") eq "ACGT" || die; + return 1; +} + +sub test4 { + revcomp("ACGTYR") eq "YRACGT" || die; + return 1; +} + +if($0 =~ /[^0-9a-zA-Z_]?DNA\.pm$/) { + print "Running unit tests\n"; + # Run unit tests + Test::shouldSucceed("test1", \&test1); + Test::shouldSucceed("test2", \&test2); + Test::shouldSucceed("test3", \&test3); + Test::shouldSucceed("test4", \&test4); +} + +1; diff --git a/scripts/sim/Mutate.pm b/scripts/sim/Mutate.pm new file mode 100644 index 0000000..2157f73 --- /dev/null +++ b/scripts/sim/Mutate.pm @@ -0,0 +1,301 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package Mutate; +use strict; +use Carp; +use FindBin qw($Bin); +use lib $Bin; +use DNA; +use Test; +use List::Util qw(max min); +use Math::Random; + +## +# Default SNP rate generator. Doesn't generate the SNP per se, just +# the rate. +# +sub defaultSNPGen() { + return Math::Random::random_uniform(1, 0, 0.05); +} + +## +# Default read gap rate generator. Doesn't generate the gaps or +# lengths, just the rate. +# +sub defaultRdGapGen() { + return Math::Random::random_uniform(1, 0, 0.005); +} + +## +# Default reference gap rate generator. Doesn't generate the gaps or +# lengths, just the rate. +# +sub defaultRfGapGen() { + return Math::Random::random_uniform(1, 0, 0.005); +} + +## +# Default rearrangement rate generator. +# +sub defaultRearrGen() { + return Math::Random::random_uniform(1, 0, 0.005); +} + +## +# Default function for generating gap lengths when introducing a gap. +# +sub defaultGapLenGen() { + return int(Math::Random::random_exponential(1, 3))+1; +} + +## +# Default function for generating random sequence to insert into a gap. +# +sub defaultSeqGen($) { + my $len = shift; + ($len == int($len) && $len > 0) || + die "Bad length for sequence generator: $len"; + my $ret = ""; + for (1..$len) { + $ret .= substr("ACGT", int(rand(4)), 1); + } + return $ret; +} + +## +# Create a new DNA mutator +# +sub new { + my ( + $class, + $name, # name + $snp, # SNP rate + $rdgap, # read gap rate + $rfgap, # ref gap rate + $rearr, # rearrangement rate + $gaplen, # gap length + $seqgen, # DNA generator + ) = @_; + $name = "noname" unless defined($name); + $snp = \&defaultSNPGen unless defined($snp); + $rdgap = \&defaultRdGapGen unless defined($rdgap); + $rfgap = \&defaultRfGapGen unless defined($rfgap); + $rearr = \&defaultRearrGen unless defined($rearr); + $gaplen = \&defaultGapLenGen unless defined($gaplen); + $seqgen = \&defaultSeqGen unless defined($seqgen); + return bless { + _name => $name, + _snp => $snp, + _rdgap => $rdgap, + _rfgap => $rfgap, + _rearr => $rearr, + _gaplen => $gaplen, + _seqgen => $seqgen, + }, $class; +} +sub snp { return $_[0]->{_snp} } +sub rdgap { return $_[0]->{_rdgap} } +sub rfgap { return $_[0]->{_rfgap} } +sub rearr { return $_[0]->{_rearr} } +sub gaplen { return $_[0]->{_gaplen} } +sub seqgen { return $_[0]->{_seqgen} } + +## +# Given a sequence (i.e. a key $srcchr into the reference hash), +# mutate that string. Note that rearrangement mutations can affect +# more than one sequence at a time. +# +# Returns a list containing counts for: +# +# 1: number of SNPs added +# 2: number of read gaps added +# 3: number of ref gaps added +# 4: number of rearrangements added +# +sub mutateSeq { + my ($self, $srcchr, $ref) = @_; + my ($nsnp, $nrfgap, $nrdgap, $nrearr) = (0, 0, 0, 0); + my $mutseq = $ref->{$srcchr}; + # Calculate # SNPs to add + my $len = length($mutseq); + my $snpRate = $self->snp->(); + my $rfgapRate = $self->rfgap->(); + my $rdgapRate = $self->rdgap->(); + my $rearrRate = $self->rearr->(); + $nsnp = Math::Random::random_binomial(1, $len, $snpRate); + $nrfgap = Math::Random::random_binomial(1, $len, $rfgapRate); + $nrdgap = Math::Random::random_binomial(1, $len, $rdgapRate); + $nrearr = Math::Random::random_binomial(1, $len, $rearrRate); + print STDERR " Introducing $nsnp SNPs, $nrfgap/$nrdgap ref/read gaps, and $nrearr rearrangements\n"; + $nsnp = min($nsnp, $len); + # Add the SNPs + for (1..$nsnp) { + my $off = int(rand($len)); # where to mutate + my $add = int(rand(3))+1; # how to mutate + my $c = substr($mutseq, $off, 1); + $c eq "A" || $c eq "C" || $c eq "G" || $c eq "T" || $c eq "N" || die "Bad char '$c' in:\n$ref->{$srcchr}"; + substr($mutseq, $off, 1) = DNA::plus(substr($mutseq, $off, 1), $add); + } + print STDERR " Finished SNPs\n"; + # Calculate # ref gaps to add + for (1..$nrfgap) { + my $off = int(rand($len)); # where to mutate + my $gaplen = $self->gaplen->(); # how many gap positions in ref + # Insert characters into the subject genome + my $insseq = $self->seqgen->($gaplen); + substr($mutseq, $off, 0) = $insseq; + $len = length($mutseq); + } + print STDERR " Finished ref gaps\n"; + # Calculate # read gaps to add + for (1..$nrdgap) { + my $off = int(rand($len)); # where to mutate + my $gaplen = $self->gaplen->(); # how many gap positions in ref + # Delete characters from subject genome + substr($mutseq, $off, $gaplen) = ""; + $len = length($mutseq); + } + print STDERR " Finished read gaps\n"; + $ref->{$srcchr} = $mutseq; + return ($nsnp, $nrfgap, $nrdgap, $nrearr); + + my $totlen = 0; + for (keys %$ref) { $totlen += length($ref->{$_}); } + # Calculate # rearrangements to add + for (1..$nrearr) { + # Pick two loci, at least one on this reference sequence and + # then cross them over somehow + my $off = int(rand($len)); + my @refkeys = keys %$ref; + my $ochr = $refkeys[int(rand(scalar(@refkeys)))]; + my $oseq = $ref->{$ochr}; + my $ooff = int(rand(length($oseq))); + my $srcleft = int(rand(2)); + my $dstleft = int(rand(2)); + my $srcrc = int(rand(2)); + my $dstrc = int(rand(2)); + # Check that the source and dest don't overlap + next if $srcchr eq $ochr; + # Get the sequence to move + my $presrclen = length($mutseq); + my $predstlen = length($oseq); + my $srcseq; + if($srcleft) { + $srcseq = substr($mutseq, 0, $off); + } else { + $srcseq = substr($mutseq, $off); + } + my $dstseq; + if($dstleft) { + $dstseq = substr($oseq, 0, $ooff); + } else { + $dstseq = substr($oseq, $ooff); + } + # Delete the sequence from the source + length($srcseq) <= length($mutseq) || die; + length($dstseq) <= length($oseq) || die; + if($srcleft) { + substr($mutseq, 0, length($srcseq)) = ""; + } else { + substr($mutseq, -length($srcseq)) = ""; + } + if($dstleft) { + substr($oseq, 0, length($dstseq)) = ""; + } else { + substr($oseq, -length($dstseq)) = ""; + } + # Possibly reverse the pieces we broke off + my $len1 = length($srcseq); + my $len2 = length($dstseq); + $srcseq = DNA::revcomp($srcseq) if $srcrc; + $dstseq = DNA::revcomp($dstseq) if $dstrc; + length($srcseq) == $len1 || die "$srcseq"; + length($dstseq) == $len2 || die; + # Mutate the current chromosome + if($srcleft) { + $mutseq = $dstseq . $mutseq; + } else { + $mutseq = $mutseq . $dstseq; + } + # Mutate the other chromosome + if($dstleft) { + $oseq = $srcseq . $oseq; + } else { + $oseq = $oseq . $srcseq; + } + my $postsrclen = length($mutseq); + my $postdstlen = length($oseq); + ($presrclen + $presrclen) == ($postsrclen + $postsrclen) || + die "from $srcchr to $ochr: $presrclen + $presrclen != $postsrclen + $postsrclen"; + $ref->{$srcchr} = $mutseq; + $ref->{$ochr} = $oseq; + my $ntotlen = 0; + for (keys %$ref) { $ntotlen += length($ref->{$_}); } + $totlen == $ntotlen || die "Total length changed after rearrangements from $srcchr to $ochr ($totlen -> $ntotlen)"; + } + print STDERR " Finished rearrangements\n"; + $ref->{$srcchr} = $mutseq; + return ($nsnp, $nrfgap, $nrdgap, $nrearr); +} + +sub test1 { + my $mut = Mutate->new("UnitTest mutator"); + my %refs = ( + "r1" => "TATGACGGTCGAAACCAGGCGA", + "r2" => "TATATTTAGTCTCGTCTGGCTGTCTCGGCTGCGCGCGAGTAAAGACCGGCCTGATC"); + $mut->mutateSeq("r1", \%refs); + $mut->mutateSeq("r2", \%refs); + return 1; +} + +sub test2 { + my $mut = Mutate->new( + "UnitTest mutator", + \&defaultSNPGen, + \&defaultRdGapGen, + \&defaultRfGapGen, + sub { return 0.1 }, + \&defaultGapLenGen, + \&defaultSeqGen); + my %refs = ( + "r1" => "TATGACGGTCGAAACCAGGCGA", + "r2" => "TATATTTAGTCTCGTCTGGCTGTCTCGGCTGCGCGCGAGTAAAGACCGGCCTGATC", + "r3" => "TATATTTAGTCTCGTCTGGCTGTCTCGGCTGCGCGCGAGTAAAGACCGGCCTGATC". + "ATTGGTGTCGCGGCGCGCGTATATATATATATATATAGCCTGCTACGTCAGCTAGC", + "r4" => "TATATTTAGTCTCGTCTGGCTGTCTCGGCTGCGCGCGAGTAAAGACCGGCCTGATC". + "ATTGGTGTCGCGGCGCGCGTATATATATATATATATAGCCTGCTACGTCAGCTAGC". + "ATATAACAAAAAAACCCCACACGACGCGGACTCTAGCACTATCGGACTATCATCGG"); + $mut->mutateSeq("r1", \%refs); + $mut->mutateSeq("r2", \%refs); + $mut->mutateSeq("r3", \%refs); + $mut->mutateSeq("r4", \%refs); + return 1; +} + +if($0 =~ /[^0-9a-zA-Z_]?Mutate\.pm$/) { + print "Running unit tests\n"; + # Run unit tests + Test::shouldSucceed("test1", \&test1); + Test::shouldSucceed("test2", \&test2); +} + +1; diff --git a/scripts/sim/RandDNA.pm b/scripts/sim/RandDNA.pm new file mode 100644 index 0000000..a924992 --- /dev/null +++ b/scripts/sim/RandDNA.pm @@ -0,0 +1,191 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package RandDNA; +use strict; +use Carp; +use FindBin qw($Bin); +use lib $Bin; +use DNA; +use Test; +use Math::Random; + +## +# Create a new random DNA generator +# +sub new { + my ( + $class, + $name, # name of generator + $n, # N fraction + $iupac, # Non-A/C/G/T/N IUPAC fraction (after N fraction removed) + $at, # AT fraction (after N/IUPAC fractions removed) + $a, # A fraction (of AT) + $c, # C fraction (of CG) + ) = @_; + $name = "noname" unless defined($name); + return bless { + _name => $name, + _n => $n || croak("No N frac"), + _iupac => $iupac || croak("No IUPAC frac"), + _at => $at || rand(), + _a => $a || rand(), + _c => $c || rand() + }, $class; +} +sub name { return $_[0]->{_name} } +sub nFrac { return $_[0]->{_n} } +sub iupacFrac { return $_[0]->{_iupac} } +sub atFrac { return $_[0]->{_at} } +sub aFrac { return $_[0]->{_a} } +sub cFrac { return $_[0]->{_c} } + +## +# Return a random IUPAC character. +# +sub randIUPAC() { + my @iu = ( + "R", + "Y", + "M", + "K", + "S", + "W", + "B", + "V", + "H", + "D" + ); + my $iui = int(rand(scalar(@iu))); + defined($iu[$iui]) || die "Bad index $iui"; + return $iu[$iui]; +} + +## +# Given parameters controlling character frequencies, build a palette +# of short sequences that can be composed to make longer sequences. +# +sub genBuildingBlocks { + my ($self, $arr, $num, $bbrnd) = @_; + defined($arr) || die; + $num = 30 unless defined($num); + # Random generator for length + $bbrnd = sub { return int(rand(100))+1 } unless defined($bbrnd); + for my $i (1..$num) { + my $seq = ""; + # Generate length + my $len = $bbrnd->(); + $len > 0 || die "Bad length: $len"; + # Generate characters + for my $j (1..$len) { + my $c = ""; + if(rand() < $self->nFrac()) { + $c = "N"; + } elsif(rand() < $self->iupacFrac()) { + $c = randIUPAC(); + defined($c) || die; + } else { + $c = (rand() < $self->atFrac()) ? "AT" : "CG"; + if($c eq "AT") { + $c = (rand() < $self->aFrac()) ? "A" : "T"; + } else { + $c = (rand() < $self->cFrac()) ? "C" : "G"; + } + } + $seq .= $c; + } + # Add to return list + push @$arr, $seq; + } +} + +## +# Use this generator to generate another random sequence. +# +sub nextSeq { + my ($self, $len, $bbsr, $runrnd) = @_; + my $seq = ""; + # Generate building blocks + my @bbs = (); + if(defined($bbsr)) { + @bbs = @$bbsr; + } else { + $self->genBuildingBlocks(\@bbs); + } + scalar(@bbs) > 0 || die; + # Random generator for run length + my $defaultRnd = sub { + # Mean of exp is 1/lambda + return int(Math::Random::random_exponential(1, 2))+1; + }; + $runrnd = $defaultRnd unless defined($runrnd); + # Build the sequence by repeatedly inserting runs of building blocks + while(length($seq) < $len * 5) { + # Choose building block + my $bbi = int(rand(scalar(@bbs))); + # Choose how many times to add it + my $runlen = $runrnd->(); + # Choose insert point + my $insat = int(rand(length($seq))); + # Repeatedly insert building lock + for my $i (1..$runlen) { + substr($seq, $insat, 0) = $bbs[$bbi]; + } + } + # Return chopped out piece + return substr($seq, $len * 2, $len); +} + +sub test1 { + my $rd = RandDNA->new( + "randtest1", # name + 0.02, # n frac + 0.01, # IUPAC frac + 0.4, # AT frac + 0.45, # A/AT frac + 0.35); # C/CG frac + my $seq = $rd->nextSeq(200, undef); + length($seq) == 200 || die; + return 1; +} + +sub test2 { + my @bb = ("AAA", "CCCC"); + my $rd = RandDNA->new( + "randtest2", # name + 0.02, # n frac + 0.01, # IUPAC frac + 0.4, # AT frac + 0.45, # A/AT frac + 0.35); # C/CG frac + my $seq = $rd->nextSeq(300, \@bb); + length($seq) == 300 || die; + return 1; +} + +if($0 =~ /[^0-9a-zA-Z_]?RandDNA\.pm$/) { + print "Running unit tests\n"; + # Run unit tests + Test::shouldSucceed("test1", \&test1); + Test::shouldSucceed("test2", \&test2); +} + +1; diff --git a/scripts/sim/SampleRead.pm b/scripts/sim/SampleRead.pm new file mode 100644 index 0000000..1defeed --- /dev/null +++ b/scripts/sim/SampleRead.pm @@ -0,0 +1,244 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package SampleRead; +use strict; +use Carp; +use FindBin qw($Bin); +use lib $Bin; +use DNA; +use Test; +use List::Util qw(max min); +use Math::Random; + +## +# Default sequencing miscall rate generator. +# +sub defaultSeqMmGen() { + return Math::Random::random_uniform(1, 0, 0.1); +} + +## +# Default random generator for read length. +# +sub defaultFragLenGen() { + return int(Math::Random::random_normal(1, 200, 40))+1; +} + +## +# Default random generator for read length. +# +sub defaultReadLenGen() { + my $r = int(rand(3)); + if($r == 0) { + return int(Math::Random::random_exponential(1, 60))+1; + } elsif($r == 1) { + return int(Math::Random::random_exponential(1, 20))+1; + } else { + return int(Math::Random::random_exponential(1, 150))+1; + } +} + +## +# Create a new read sampler +# +sub new { + my ( + $class, + $name, # name of simulator + $fraglengen, # paired-end fragment length generator + $m1lengen, # random mate1 length generator + $m2lengen, # random mate2 length generator + ) = @_; + $fraglengen = \&defaultFragLenGen unless defined($fraglengen); + $m1lengen = \&defaultReadLenGen unless defined($m1lengen); + $m2lengen = \&defaultReadLenGen unless defined($m2lengen); + $name = "noname" unless defined($name); + return bless { + _name => $name, + _fraglengen => $fraglengen, + _m1lengen => $m1lengen, + _m2lengen => $m2lengen, + }, $class; +} +sub name { return $_[0]->{_name} } +sub fraglengen { return $_[0]->{_fraglengen} } +sub m1lengen { return $_[0]->{_m1lengen} } +sub m2lengen { return $_[0]->{_m2lengen} } + +## +# Generate a set of reads from a subject genome encoded in a hash ref. +# +sub genReads { + my ( + $self, + $num, # number of reads/fragments to generate + $color, # colorize? + $refs, # hash ref holding reference sequences + $seqs, # put generated read sequences here + $quals, # put generated quality sequences here + $lengen) = @_; # length generator + + ref($refs) eq "HASH" || die "Reference input must be hash ref, is ".ref($refs); + ref($seqs) eq "ARRAY" || die "seqs input must be array ref, is ".ref($seqs); + ref($quals) eq "ARRAY" || die "quals input must be array ref, is".ref($quals); + $lengen = $self->m1lengen() unless defined($lengen); + my $totreflen = 0; + my @keys = keys %$refs; + for (@keys) { $totreflen += length($refs->{$_}); } + for(1..$num) { + if(rand() < 0.05 && scalar(@$seqs) > 0) { + # Clone a previous read + my $ci = int(rand(scalar(@$seqs))); + push @$seqs, $seqs->[$ci]; + push @$quals, $quals->[$ci]; + } else { + while(1) { + my $ro = int(rand($totreflen)); + my $len = $lengen->(); + $len = 1 if $len < 1; + my $key = undef; + my $rflen = 0; + for (@keys) { + $rflen = length($refs->{$_}); + if($ro < $rflen) { + $key = $_; + last; + } + $ro -= $rflen; + } + defined($key) || die; + $rflen > 0 || die; + # If we are overhanging the end, discard and try again + next if $ro + $len > $rflen; + my $rfseq = substr($refs->{$key}, $ro, $len); + length($rfseq) == $len || die; + my $rc = int(rand(2)); + # Possibly reverse-complement it + $rfseq = DNA::revcomp($rfseq) if $rc == 1; + # Possible colorize + if($color) { + my $cseq = ""; + for(0..$len-2) { + my ($c1, $c2) = (substr($rfseq, $_, 1), substr($rfseq, $_+1, 1)); + my $col = DNA::dinucToColor($c1, $c2); + $cseq .= $col; + } + $rfseq = $cseq; + $len = length($rfseq); + } + push @$seqs, $rfseq; + # TODO: generate interesting qualities + push @$quals, "I" x $len; + last; + } + } + # Simulate next read + } +} + +## +# Generate a set of read pairs from a subject genome encoded in a hash +# ref. First we extract unpaired fragments, then take sequences from +# either end to make the mates. +# +sub genReadPairs { + my ( + $self, + $num, # number of reads/fragments to generate + $color, # colorize? + $refs, # hash ref holding reference sequences + $m1fw, # orientation of mate 1 when fragment comes from Watson strand + $m2fw, # orientation of mate 2 when fragment comes from Watson strand + $seq1s, # put generated mate1 sequences here + $seq2s, # put generated mate2 sequences here + $qual1s, # put generated mate1 quality sequences here + $qual2s) = @_; # put generated mate2 quality sequences here + + # First simulate fragments + ref($refs) eq "HASH" || die "Reference input must be hash ref"; + ref($seq1s) eq "ARRAY" || die "seq1s input must be array ref"; + ref($seq2s) eq "ARRAY" || die "seq2s input must be array ref"; + ref($qual1s) eq "ARRAY" || die "qual1s input must be array ref"; + ref($qual2s) eq "ARRAY" || die "qual2s input must be array ref"; + my @fragseqs = (); + my @fragquals = (); + $self->genReads( + $num, + $color, + $refs, + \@fragseqs, + \@fragquals, + $self->fraglengen); + scalar(@fragseqs) == scalar(@fragquals) || die; + # For each fragment + for (1..scalar(@fragseqs)) { + # Take mates from either end + my $m1len = $self->m1lengen->(); + my $m2len = $self->m2lengen->(); + $m1len = min($m1len, length($fragseqs[$_-1])); + $m2len = min($m2len, length($fragseqs[$_-1])); + my $m1seq = substr($fragseqs [$_-1], 0, $m1len); + my $m2seq = substr($fragseqs [$_-1], -$m2len); + my $m1qual = substr($fragquals[$_-1], 0, $m1len); + my $m2qual = substr($fragquals[$_-1], -$m2len); + if(!$m1fw) { + $m1seq = DNA::revcomp($m1seq); + $m1qual = reverse $m1qual; + } + if(!$m2fw) { + $m2seq = DNA::revcomp($m2seq); + $m2qual = reverse $m2qual; + } + # Commit new pair to the list + push @$seq1s, $m1seq; + push @$seq2s, $m2seq; + push @$qual1s, $m1qual; + push @$qual2s, $m2qual; + # Simulate next pair + } +} + +sub test1 { + my $samp = SampleRead->new("UnitTest read sampler"); + my %refs = ( + "r1" => "TATGACGGTCGAAACCAGGCGA", + "r2" => "TATATTTAGTCTCGTCTGGCTGTCTCGGCTGCGCGCGAGTAAAGACCGGCCTGATC"); + my @seqs = (); + my @quals = (); + $samp->genReads(10, 0, \%refs, \@seqs, \@quals, \&defaultReadLenGen); + scalar(@seqs) == 10 || die; + scalar(@quals) == 10 || die; + return 1; +} + +sub test2 { + return 1; +} + +if($0 =~ /[^0-9a-zA-Z_]?SampleRead\.pm$/) { + print "Running unit tests\n"; + # Run unit tests + Test::shouldSucceed("test1", \&test1); + Test::shouldSucceed("test2", \&test2); +} + +1; diff --git a/scripts/sim/Sim.pm b/scripts/sim/Sim.pm new file mode 100644 index 0000000..458e867 --- /dev/null +++ b/scripts/sim/Sim.pm @@ -0,0 +1,1052 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package Sim; +use strict; +use Carp; +use FindBin qw($Bin); +use lib $Bin; +use DNA; +use Test; +use RandDNA; +use SampleRead; +use Mutate; +use AlignmentCheck; +use Math::Random; +use List::Util qw(max min); +use POSIX; + +## +# Replacement for "die" that additionally writes error message to file so that +# run.pl can read it later. +# +sub mydie($) { + my $fn = ".run.pl.child.$$"; + open(EO, ">$fn") || die "Could not open $fn for writing"; + print EO "$_[0]\n"; + close(EO); + confess $_[0]; +} + +# Generates random printable strings of a given length +sub randStr($) { + my $len = shift; + my @chars = ('a'..'z', 'A'..'Z', '0'..'9', '_'); + my $str = ""; + foreach (1..$len) { + $str .= $chars[int(rand(scalar(@chars)))]; + } + return $str; +} + +## +# Default random generator for number of reference per test case. +# +sub defaultRefNumGen() { return int(Math::Random::random_exponential(1, 8))+1; } + +## +# Default random generator for reference length. +# +sub defaultRefLenGen() { + return int(Math::Random::random_exponential(1, 50000))+1; +} + +## +# Default random generator for number of reference per test case. +# +sub defaultReadNumGen() { + return int(Math::Random::random_exponential(1, 10000))+1; +} + +## +# Default random generator for read length. +# +sub defaultFragLenGen() { + return int(Math::Random::random_normal(1, 200, 40))+1; +} + +## +# Default random generator for reference length. +# +sub defaultReadLenGen() { + my $r = int(rand(3)); + if($r == 0) { + return int(Math::Random::random_exponential(1, 60))+1; + } elsif($r == 1) { + return int(Math::Random::random_exponential(1, 20))+1; + } else { + return int(Math::Random::random_exponential(1, 150))+1; + } +} + +## +# Default random generator for fraction of reference characters = N. +# +sub defaultNGen() { + return Math::Random::random_uniform(1, 0, 0.05); +} + +## +# Default random generator for fraction of reference characters = an +# ambiguous IUPAC code. +# +sub defaultIupacGen() { + return Math::Random::random_uniform(1, 0, 0.01); +} + +## +# Default random generator for AT/ACGT fraction. +# +sub defaultAtGen() { + return min(max(Math::Random::random_normal(1, 0.5, 0.18), 0), 1); +} + +## +# Default random generator for A/AT fraction. +# +sub defaultAGen() { + return min(max(Math::Random::random_normal(1, 0.5, 0.18), 0), 1); +} + +## +# Default random generator for C/CG fraction. +# +sub defaultCGen() { + return min(max(Math::Random::random_normal(1, 0.5, 0.18), 0), 1); +} + +## +# Default SNP rate generator. Doesn't generate the SNP per se, just +# the rate. +# +sub defaultSNPGen() { + return Math::Random::random_uniform(1, 0, 0.05); +} + +## +# Default read gap rate generator. Doesn't generate the gaps or +# lengths, just the rate. +# +sub defaultRdGapGen() { + return Math::Random::random_uniform(1, 0, 0.005); +} + +## +# Default reference gap rate generator. Doesn't generate the gaps or +# lengths, just the rate. +# +sub defaultRfGapGen() { + return Math::Random::random_uniform(1, 0, 0.005); +} + +## +# Default rearrangement rate generator. +# +sub defaultRearrGen() { + return Math::Random::random_uniform(1, 0, 0.005); +} + +## +# Default function for generating gap lengths when introducing a gap. +# +sub defaultGapLenGen($) { + return int(Math::Random::random_exponential(1, 3))+1; +} + +## +# Default function for generating random sequence to insert into a gap. +# +sub defaultSeqGen($) { + my $len = shift; + ($len == int($len) && $len > 0) || + mydie("Bad length for sequence generator: $len"); + my $ret = ""; + for (1..$len) { + $ret .= substr("ACGT", int(rand(4)), 1); + } + return $ret; +} + +## +# Default sequencing miscall rate generator. +# +sub defaultSeqMmGen() { + return Math::Random::random_uniform(1, 0, 0.1); +} + +## +# Create a new test case simulator +# +sub new { + my ( + $class, + $name, # name of simulator + $rfnumgen, # number of reference sequences + $rflengen, # reference length + $rdnumgen, # number of read sequences per run + $rdlengen, # read length generator + $fraglengen, # fragment length generator + $ngen, # N fraction + $iupacgen, # Non-A/C/G/T/N IUPAC fraction (after N fraction removed) + $atgen, # AT fraction (after N/IUPAC fractions removed) + $agen, # A fraction (of AT) + $cgen, # C fraction (of CG) + $snpgen, # SNP rate gen + $rdgapgen, # read gap generator + $rfgapgen, # ref gap generator + $rearrgen, # rearrangement generator + $gaplengen, # gap length generator + $seqgen, # gap filler sequence generator + $seqmm, # sequencing error generator + ) = @_; + $rfnumgen = \&defaultRefNumGen unless defined($rfnumgen); + $rflengen = \&defaultRefLenGen unless defined($rflengen); + $rdnumgen = \&defaultReadNumGen unless defined($rdnumgen); + $rdlengen = \&defaultReadLenGen unless defined($rdlengen); + $fraglengen = \&defaultFragLenGen unless defined($fraglengen); + $ngen = \&defaultNGen unless defined($ngen); + $iupacgen = \&defaultIupacGen unless defined($iupacgen); + $atgen = \&defaultAtGen unless defined($atgen); + $agen = \&defaultAGen unless defined($agen); + $cgen = \&defaultCGen unless defined($cgen); + $snpgen = \&defaultSNPGen unless defined($snpgen); + $rdgapgen = \&defaultRdGapGen unless defined($rdgapgen); + $rfgapgen = \&defaultRfGapGen unless defined($rfgapgen); + $rearrgen = \&defaultRearrGen unless defined($rearrgen); + $gaplengen = \&defaultGapLenGen unless defined($gaplengen); + $seqgen = \&defaultSeqGen unless defined($seqgen); + $seqmm = \&defaultSeqMmGen unless defined($seqmm); + $name = "noname" unless defined($name); + return bless { + _name => $name, + _rfnumgen => $rfnumgen, + _rflengen => $rflengen, + _rdnumgen => $rdnumgen, + _rdlengen => $rdlengen, + _fraglengen => $fraglengen, + _ngen => $ngen, + _iupacgen => $iupacgen, + _atgen => $atgen, + _agen => $agen, + _cgen => $cgen, + _snpgen => $snpgen, + _rdgapgen => $rdgapgen, + _rfgapgen => $rfgapgen, + _rearrgen => $rearrgen, + _gaplengen => $gaplengen, + _seqgen => $seqgen, + _seqmm => $seqmm, + }, $class; +} +sub rfnumgen { return $_[0]->{_rfnumgen} } +sub rflengen { return $_[0]->{_rflengen} } +sub rdnumgen { return $_[0]->{_rdnumgen} } +sub rdlengen { return $_[0]->{_rdlengen} } +sub fraglengen { return $_[0]->{_fraglengen} } +sub ngen { return $_[0]->{_ngen} } +sub iupacgen { return $_[0]->{_iupacgen} } +sub atgen { return $_[0]->{_atgen} } +sub agen { return $_[0]->{_agen} } +sub cgen { return $_[0]->{_cgen} } +sub snpgen { return $_[0]->{_snpgen} } +sub rdgapgen { return $_[0]->{_rdgapgen} } +sub rfgapgen { return $_[0]->{_rfgapgen} } +sub rearrgen { return $_[0]->{_rearrgen} } +sub gaplengen { return $_[0]->{_gaplengen} } +sub seqgen { return $_[0]->{_seqgen} } +sub seqmm { return $_[0]->{_seqmm} } + +## +# Generate DNA generator. +# +sub genDNAgen { + my $self = shift; + my $nfrac = $self->ngen->(); + my $iupacfrac = $self->iupacgen->(); + my $atfrac = $self->atgen->(); + my $afrac = $self->agen->(); + my $cfrac = $self->cgen->(); + my $refdnagen = RandDNA->new( + "Sim.pm gen", + $nfrac, + $iupacfrac, + $atfrac, + $afrac, + $cfrac); + printf STDERR "Created DNA generator\n"; + printf STDERR " N frac: %0.3f\n", $nfrac; + printf STDERR " IUPAC frac: %0.3f\n", $iupacfrac; + printf STDERR " AT/ACGT frac: %0.3f\n", $atfrac; + printf STDERR " A/AT frac: %0.3f\n", $afrac; + printf STDERR " C/CG frac: %0.3f\n", $cfrac; + return $refdnagen; +} + +## +# Generate and print reference sequences to file of given name. Also, +# install reference sequences into hash ref $ref. To allow for +# "overhang" (alignment that hang off the end of the reference), we +# actually write out a little bit less than the full reference sequence +# for each sequence. +# +sub genRef { + my ($self, $ref, $refdnagen, $conf, $tmpfn) = @_; + # Get a generator for reference length + my $reflen = $self->rflengen; + # Generate the number of references + my $refnum = $self->rfnumgen->(); + $refnum = sqrt($refnum) if $conf->{small}; + $refnum = 1 if $refnum <= 0; + $refnum = sqrt($refnum) if $conf->{small}; + $refnum = 1 if $refnum <= 0; + $refnum = ceil($refnum); + $refnum = $conf->{numrefs} if defined($conf->{numrefs}); + # Open output file + open (FA, ">$tmpfn") || + mydie("Could not open temporary fasta file '$tmpfn' for writing"); + my %ccnt = (); + print STDERR "Generating $refnum references\n"; + for (1..$refnum) { + # Randomly generate length + my $len = $reflen->(); + $len = sqrt($len) if $conf->{small}; + $len = 1 if $len <= 0; + $len = ceil($len); + my $seq = $refdnagen->nextSeq($len); + length($seq) >= $len || die; + my $name = "Sim.pm.$_"; + $ref->{$name} = $seq; + # Select amount to trim from LHS + my $trimleft = int(Math::Random::random_exponential(1, 200)); + # Select amount to trim from RHS + my $trimright = int(Math::Random::random_exponential(1, 200)); + # Make sure we're leaving some sequence after trimming + while($trimleft + $trimright > $len) { + if(int(rand(2))) { + $trimleft = int($trimleft*0.5); + } else { + $trimright = int($trimright*0.5); + } + } + # Trim the sequence + substr($seq, 0, $trimleft) = ""; + $seq = substr($seq, 0, length($seq)-$trimright); + my $trimlen = length($seq); + $trimlen == $len - $trimleft - $trimright || + mydie("Unexpected trim combo: $len, $trimleft, $trimright, $trimlen"); + print STDERR " Generated reference '$name' of untrimmed length $len, trimmed length $trimlen\n"; + print FA ">$name\n"; + my $buf = ""; + length($seq) >= $trimlen || die; + for my $i (1..$trimlen) { + my $c = substr($seq, $i-1, 1); + defined($c) || die; + $ccnt{$c}++; + $buf .= $c; + $ref->{$name} .= $c; + if($i % 60 == 0) { + print FA "$buf\n"; + $buf = ""; + } + } + print FA "$buf\n" if $buf ne ""; + } + close(FA); + print STDERR "Wrote references to $tmpfn\n"; + for my $k (sort keys %ccnt) { + print STDERR " $k: $ccnt{$k}\n"; + } +} + +## +# Generate a hash of key/value arguments to pass to bowtie2. +# +sub genBuildArgs { + my ($self) = @_; + my %args = (); + my $r1 = int(rand(3)); + if($r1 == 0) { + $args{"--bmaxdivn"} = int(Math::Random::random_exponential(1, 4))+1; + } elsif($r1 == 1) { + $args{"--bmax"} = int(Math::Random::random_exponential(1, 10000))+100; + } + my $r2 = int(rand(2)); + if($r2 == 0) { + $args{"--dcv"} = 2 ** (int(rand(10))+4); + } + my $r3 = int(rand(5)); + if($r3 == 0) { + $args{"--packed"} = ""; + } + my $r4 = int(rand(3)); + if($r4 == 0) { + $args{"--offrate"} = int(rand(8))+1; + } + return \%args; +} + +## +# Given a fasta filename, an index basename, and a path to the +# bowtie2-build executable, build nucleotide-space and colorpace +# indexes for the sequences in the fasta file. +# +sub build { + my ($self, $fa, $idx, $conf, $args) = @_; + my $argstr = ""; + for (keys %$args) { + $argstr .= " $_"; + if($args->{$_} ne "") { + $argstr .= " ".$args->{$_}; + } + } + $argstr .= " --sanity"; + # Build nucleotide index + my $cmd = "$conf->{bowtie2_build_debug} $argstr $fa $idx"; + print STDERR "$cmd\n"; + system($cmd); + $? == 0 || mydie("Error running '$cmd'; exitlevel=$?"); + print STDERR "Built nucleotide index '$idx'\n"; + # Build colorspace index + unless($conf->{no_color}) { + $cmd = "$conf->{bowtie2_build_debug} $argstr -C $fa ${idx}.c"; + print STDERR "$cmd\n"; + system($cmd); + $? == 0 || mydie("Error running '$cmd'; exitlevel=$?"); + print STDERR "Built colorspace index '$idx'\n"; + } +} + +## +# Given a hash of sequences, flatten all IUPAC codes into unambiguous +# nucleotides. +# +sub flattenIUPAC() { + my ($self, $h) = @_; + for my $c (keys %$h) { + my $len = length($h->{$c}); + for my $i (0..$len-1) { + my $ch = uc substr($h->{$c}, $i, 1); + my $nc = $ch; + if(DNA::isIUPAC($ch) || $ch eq "N") { + if(rand() < $self->snpgen->()) { + $nc = DNA::pickIncompat($ch); + defined($nc) || mydie("Couldn't find incompatible base for $ch"); + } else { + $nc = DNA::pickCompat($ch); + defined($nc) || mydie("Couldn't find compatible base for $ch"); + } + } + if($ch ne $nc) { + substr($h->{$c}, $i, 1) = $nc; + } + } + } +} + +## +# Mutate reference genome into a subject genome. +# +sub mutate() { + my ($self, $refs) = @_; + my %subj = %$refs; + $self->flattenIUPAC(\%subj); + print STDERR "Flattened IUPAC characters\n"; + my $mutator = Mutate->new( + "Sim.pm mutator", + $self->snpgen, + $self->rdgapgen, + $self->rfgapgen, + $self->rearrgen, + $self->gaplengen, + $self->seqgen); + my ($nsnp, $nrfgap, $nrdgap, $nrearr) = (0, 0, 0, 0); + for(keys %subj) { + print STDERR " Mutating sequence $_\n"; + my ($nsnp_, $nrfgap_, $nrdgap_, $nrearr_) = $mutator->mutateSeq($_, \%subj); + $nsnp += $nsnp_; + $nrfgap += $nrfgap_; + $nrdgap += $nrdgap_; + $nrearr += $nrearr_; + } + print STDERR "Mutated reference genome to subject genome\n"; + print STDERR " SNPs introduced: $nsnp\n"; + print STDERR " Reference gaps introduced: $nrfgap\n"; + print STDERR " Read gaps introduced: $nrdgap\n"; + print STDERR " Rearrangements introduced: $nrearr\n"; + return \%subj; +} + +sub dumpFastq { + my ($self, $input, $fh1, $fh2) = @_; + for (1..scalar(@{$input->{seq1s}})) { + my $seq1 = $input->{seq1s}->[$_-1]; + my $qual1 = $input->{qual1s}->[$_-1]; + print {$fh1} "\@$_\n"; + print {$fh1} "$seq1\n"; + print {$fh1} "+$_\n"; + print {$fh1} "$qual1\n"; + if($input->{paired}) { + my $seq2 = $input->{seq2s}->[$_-1]; + my $qual2 = $input->{qual2s}->[$_-1]; + print {$fh2} "\@$_\n"; + print {$fh2} "$seq2\n"; + print {$fh2} "+$_\n"; + print {$fh2} "$qual2\n"; + } + } +} + +sub dumpQseq { + my ($self, $input, $fh1, $fh2) = @_; + for (1..scalar(@{$input->{seq1s}})) { + my $seq1 = $input->{seq1s}->[$_-1]; + my $qual1 = $input->{qual1s}->[$_-1]; + print {$fh1} "R\t1\t1\t1\t$_\t$_\t1\t1\t$seq1\t$qual1\t1\n"; + if($input->{paired}) { + my $seq2 = $input->{seq2s}->[$_-1]; + my $qual2 = $input->{qual2s}->[$_-1]; + print {$fh2} "R\t1\t1\t1\t$_\t$_\t1\t1\t$seq2\t$qual2\t1\n"; + } + } +} + +sub dumpFasta { + my ($self, $input, $fh1, $fh2) = @_; + for (1..scalar(@{$input->{seq1s}})) { + my $seq1 = $input->{seq1s}->[$_-1]; + print {$fh1} ">$_\n"; + print {$fh1} "$seq1\n"; + if($input->{paired}) { + my $seq2 = $input->{seq2s}->[$_-1]; + print {$fh2} ">$_\n"; + print {$fh2} "$seq2\n"; + } + } +} + +sub dumpRaw { + my ($self, $input, $fh1, $fh2) = @_; + for (1..scalar(@{$input->{seq1s}})) { + my $seq1 = $input->{seq1s}->[$_-1]; + print {$fh1} "$seq1\n"; + if($input->{paired}) { + my $seq2 = $input->{seq2s}->[$_-1]; + print {$fh2} "$seq2\n"; + } + } +} + +## +# Generate the input (reads plus paired/fragment information) +# +sub genInput { + my ($self, $refs, $conf) = @_; + # Select whether we're doing colorspace + my $color = int(rand(2)); + $color = 0 if $conf->{no_color}; + # Select whether we're doing unpaired or paired-end. + my $paired = int(rand(2)); + $paired = 0 if $conf->{no_paired}; + # Select format for read file + my @formats = ("fastq", "qseq", "fasta", "raw"); + my @format_arg = ( "-q", "--qseq", "-f", "-r"); + my $formati = int(rand(scalar(@formats))); + my $format = $formats[$formati]; + my $format_arg = $format_arg[$formati]; + my $tmprdfn1 = "$conf->{tempdir}/Sim.pm.$conf->{randstr}_1.$format"; + my $tmprdfn2 = "$conf->{tempdir}/Sim.pm.$conf->{randstr}_2.$format"; + # Generate reads from the subject genome; no sequencing error yet + my %input = ( + seq1s => [], + seq2s => [], + qual1s => [], + qual2s => [], + mate1fw => 1, + mate2fw => 0, + paired => $paired, + color => $color, + format => $format, + format_arg => $format_arg, + file1 => $tmprdfn1, + file2 => $tmprdfn2 ); + my $read_sampler = SampleRead->new( + "Sim.pm read sampler", + $self->fraglengen, + $self->rdlengen, + $self->rdlengen); + print STDERR "Created read sampler\n"; + my $numreads = $self->rdnumgen->(); + $numreads = ceil(sqrt($numreads)) if $conf->{small}; + $numreads == int($numreads) || mydie("numreads $numreads not a number"); + my $tmp = int(rand(3)); + if($tmp == 0) { + $input{mate2fw} = 1; + } elsif($tmp == 1) { + $input{mate1fw} = 0; + $input{mate2fw} = 1; + } + print STDERR "Sampling $numreads reads\n"; + ref($refs) eq "HASH" || mydie("Reference input must be hash ref"); + if($paired) { + $read_sampler->genReadPairs( + $numreads, # number of reads/fragments to generate + $input{color}, # colorize? + $refs, # hash ref holding reference sequences + $input{mate1fw}, # orientation of mate 1 when fragment comes from Watson strand + $input{mate2fw}, # orientation of mate 2 when fragment comes from Watson strand + $input{seq1s}, # put generated mate1 sequences here + $input{seq2s}, # put generated mate2 sequences here + $input{qual1s}, # put generated mate1 quality sequences here + $input{qual2s}); # put generated mate2 quality sequences here + } else { + $read_sampler->genReads( + $numreads, # number of reads/fragments to generate + $input{color}, # colorize? + $refs, # hash ref holding reference sequences + $input{seq1s}, # put generated sequences here + $input{qual1s}); # put generated quality sequences here + } + # TODO: with some probability, sort the reads + print STDERR "Dumping reads to temporary files $tmprdfn1 & $tmprdfn2\n"; + # Dump reads to output file + my ($fh1, $fh2); + open($fh1, ">$tmprdfn1") || mydie("Could not open '$tmprdfn1' for writing"); + open($fh2, ">$tmprdfn2") || mydie("Could not open '$tmprdfn2' for writing"); + if($format eq "fastq") { + $self->dumpFastq(\%input, $fh1, $fh2); + } elsif($format eq "qseq") { + $self->dumpQseq(\%input, $fh1, $fh2); + } elsif($format eq "fasta") { + $self->dumpFasta(\%input, $fh1, $fh2); + } elsif($format eq "raw") { + $self->dumpRaw(\%input, $fh1, $fh2); + } + close($fh1); + close($fh2); + return \%input; +} + +## +# Mutate reads according to sequencing error model. +# +sub mutateSeq { + my ($self, $input) = @_; + return $input; +} + +## +# Generate a setting for MA (match bonus). +# +sub genPolicyMA($) { + my $local = shift; + return "" if ($local || int(rand(2)) == 0); + return "MA=".Math::Random::random_uniform(1, 1, 40).";"; +} + +## +# Generate a setting for MMP (mismatch penalty). +# +sub genPolicyMMP() { + return "" if int(rand(2)) == 0; + my $op = substr("CQR", int(rand(3)), 1); + if($op eq "C") { + $op .= Math::Random::random_uniform(1, 1, 40); + } + return "MMP=$op;"; +} + +## +# Generate a setting for NP (penalty for a mismatch involving an N). +# +sub genPolicyNP() { + return "" if int(rand(2)) == 0; + my $op = substr("CQR", int(rand(3)), 1); + if($op eq "C") { + $op .= int(Math::Random::random_exponential(1, 3))+1; + } + return "NP=$op;"; +} + +## +# Generate a setting for RDG (read gap open and extend penalties). +# +sub genPolicyRDG() { + return undef if int(rand(2)) == 0; + my $op = Math::Random::random_uniform(1, 1, 50); + if(int(rand(2)) == 0) { + $op .= ","; + $op .= Math::Random::random_uniform(1, 1, 20); + } + return "$op"; +} + +## +# Generate a setting for RFG (ref gap open and extend penalties). +# +sub genPolicyRFG() { + return undef if int(rand(2)) == 0; + my $op = Math::Random::random_uniform(1, 1, 50); + if(int(rand(2)) == 0) { + $op .= ","; + $op .= Math::Random::random_uniform(1, 1, 20); + } + return "$op"; +} + +## +# Generate a setting for MIN (function determining minimum acceptable score). +# +sub genPolicyMIN($) { + my $local = shift; + return undef if ($local || int(rand(2)) == 0); + my $xx = Math::Random::random_uniform(1, 1, 10); + my $yy = Math::Random::random_uniform(1, 1, 10); + if(!$local) { + $xx = -$xx if int(rand(2)) == 0; + $yy = -$yy; + } + return "L,$xx,$yy"; +} + +## +# Generate a setting for NCEIL (function determining maximum number of Ns +# allowed). +# +sub genPolicyNCEIL() { + return undef if int(rand(2)) == 0; + my $xx = Math::Random::random_uniform(1, 0, 1.5); + my $yy = Math::Random::random_uniform(1, 0, 1.5); + return "$xx,$yy"; +} + +## +# Generate a setting for SEED (# mismatches, length, interval). +# +sub genPolicySEED() { + return undef if int(rand(2)) == 0; + # Pick a number of mismatches + my $sd = substr("012", int(rand(2)), 1); + if(rand() < 0.9) { + # Length + $sd .= ",".int(Math::Random::random_uniform(1, 12, 32)); + } + return $sd; +} + +## +# Generate a setting for -D (# DP fails in a row). +# +sub genPolicyFailStreak() { + return undef if int(rand(2)) == 0; + return int(Math::Random::random_uniform(1, 2, 50)); +} + +## +# Generate a setting for -R (# seeding rounds). +# +sub genPolicySeedRounds() { + return undef if int(rand(2)) == 0; + return int(Math::Random::random_uniform(1, 1, 5)); +} + +## +# Generate a setting for IVAL. Interval between seeds is a function of the +# read length OR sqaure root of read length OR cube root of read length. +# +sub genPolicyIVAL() { + return "" if int(rand(2)) == 0; + # Pick a number of mismatches + my $iv = substr("LSC", int(rand(3)), 1); + if($iv eq "L") { + if(rand() < 0.9) { + # Multiplier + $iv .= ",".Math::Random::random_uniform(1, 0.0, 0.5); + } + if(rand() < 0.3) { + # Offset + $iv .= ",".Math::Random::random_uniform(1, 0.0, 4.0); + } + } elsif($iv eq "S") { + if(rand() < 0.9) { + # Multiplier + $iv .= ",".Math::Random::random_uniform(1, 0.0, 3.0); + } + if(rand() < 0.3) { + # Offset + $iv .= ",".Math::Random::random_uniform(1, 0.0, 7.0); + } + } elsif($iv eq "C") { + if(rand() < 0.9) { + # Multiplier + $iv .= ",".Math::Random::random_uniform(1, 0.0, 5.0); + } + if(rand() < 0.3) { + # Offset + $iv .= ",".Math::Random::random_uniform(1, 0.0, 14.0); + } + } + return "IVAL=$iv;"; +} + +## +# Generate a random but meaningful string of policy arguments to specify using +# the -P option. +# +sub genPolicyArg($) { + my $local = shift; + my $args = ""; + $args .= genPolicyMA($local); + $args .= genPolicyMMP(); + $args .= genPolicyNP(); + $args .= genPolicyIVAL(); + if($args ne "") { + return substr($args, 0, -1); + } else { return ""; } +} + +## +# Generate a hash of key/value arguments to pass to bowtie2. +# +sub genAlignArgs { + my ($self, $input, $color, $conf) = @_; + my %args = (); + my $local = int(rand(2)) == 0; + $args{"-u"} = $conf->{maxreads} if defined($conf->{maxreads}); + $args{"--mm"} = "" if int(rand(2)) == 0; + #$args{"--overhang"} = "" if int(rand(2)) == 0; + $args{"--trim3"} = int(rand(10)) if int(rand(2)) == 0; + $args{"--trim5"} = int(rand(10)) if int(rand(2)) == 0; + $args{"--nofw"} = "" if int(rand(4)) == 0; + $args{"--norc"} = "" if int(rand(4)) == 0; + $args{"--col-keepends"} = "" if ($color && int(rand(3)) == 0); + $args{"--gbar"} = int(Math::Random::random_exponential(1, 3))+1 if int(rand(4)) == 0; + $args{"--local"} = "" if $local; + my $rep = int(rand(5)); + if($rep == 0) { + $args{"-a"} = ""; + } elsif($rep == 1) { + $args{"-k"} = int(Math::Random::random_exponential(1, 3))+2; + } elsif($rep == 2) { + $args{"-M"} = int(Math::Random::random_exponential(1, 3))+2; + } + $args{"--rdg"} = genPolicyRDG(); + $args{"--rfg"} = genPolicyRFG(); + $args{"--score-min"} = genPolicyMIN($local); + $args{"--n-ceil"} = genPolicyNCEIL(); + $args{"-N"} = genPolicySEED(); + $args{"-D"} = genPolicyFailStreak(); + $args{"-R"} = genPolicySeedRounds(); + $args{"--policy"} = ("\"".genPolicyArg($local)."\"") if rand() < 0.9; + $args{"--cp-min"} = int(Math::Random::random_exponential(1, 3)) + 2; + $args{"--cp-ival"} = int(Math::Random::random_exponential(1, 1)) + 1; + return \%args; +} + +## +# Align the given input set against the given index using the given +# bowtie2 binary and arguments. Sanity-check the SAM output. +# +sub align { + my ($self, $fa, $idx, $input, $conf, $args) = @_; + my $argstr = ""; + for (keys %$args) { + if(defined($args->{$_})) { + $argstr .= " $_"; + if($args->{$_} ne "") { + $argstr .= " ".$args->{$_}; + } + } + } + $argstr .= " -C" if $input->{color}; + $argstr .= " ".$input->{format_arg}; + $idx .= ".c" if $input->{color}; + my $inputfn; + if($input->{paired}) { + $inputfn = "-1 $input->{file1} -2 $input->{file2}"; + } else { + $inputfn = $input->{file1}; + } + # Create object that will help us sanity-check alignments + my $ac = AlignmentCheck->new( + "Sim.pm alignment checker", # name + [ $fa ], # fasta + "sam", # SAM-formatted alignments + 0, # no bis-C + 0 # no bis-CpG + ); + $ac->nrefs() > 0 || mydie("No references"); + # Run normal (non-debug) Bowtie + defined($conf->{tempdir}) || mydie("No tmp dir"); + my $als = "$conf->{tempdir}/Sim.pm.$conf->{randstr}.als"; + my $als_debug = "$conf->{tempdir}/Sim.pm.$conf->{randstr}.debug.als"; + my $als_px = "$conf->{tempdir}/Sim.pm.$conf->{randstr}.px.als"; + my $als_px_reord = "$conf->{tempdir}/Sim.pm.$conf->{randstr}.px.reord.als"; + my $cmd = "$conf->{bowtie2_debug} $argstr $idx $inputfn"; + print "$cmd\n"; + open(ALSDEB, ">$als_debug") || mydie("Could not open '$als_debug' for writing"); + open(ALSDEBCMD, "$cmd |") || mydie("Could not open pipe '$cmd |'"); + my $ival = 50; + my $nals = 0; + my @lines = (); + while() { + # Remove @PG line because CL: tag can legitimately differ + print ALSDEB $_ unless /^\@PG/; + push @lines, $_; + $nals++; + print STDERR " Read $nals alignments...\n" if ($nals % $ival) == 0; + } + close(ALSDEBCMD); + $ac->checkAlignments(\@lines, 0); + $? == 0 || mydie("bowtie2-align-debug exited with exitlevel $?:\n$cmd\n"); + close(ALSDEB); + $ac->printSummary(); + # With some probability, also run debug Bowtie and check that + # results are identical + if(int(rand(3)) == 0) { + print STDERR "ALSO checking that bowtie2 and bowtie2-align-debug match up\n"; + # Remove @PG line because CL: tag can legitimately differ + $cmd = "$conf->{bowtie2} $argstr $idx $inputfn | grep -v '^\@PG' > $als"; + print "$cmd\n"; + system($cmd); + $? == 0 || + mydie("Command '$cmd' failed with exitlevel $?"); + $cmd = "diff -uw $als $als_debug"; + print "$cmd\n"; + system($cmd); + $? == 0 || + mydie("diff found a difference between bowtie2 and bowtie2-align-debug ". + "output for same input (above)\n"); + } + # With some probability, also run debug Bowtie in -p X mode with X > 1 and + # without the --reorder argument and check that results are identical + if(int(rand(3)) == 0) { + print STDERR "ALSO checking that bowtie2 and bowtie2 -p X w/ X > 1 match up\n"; + my $p = int(rand(3))+2; + $cmd = "$conf->{bowtie2} $argstr -p $p $idx $inputfn | grep -v '^\@PG' > $als_px"; + print "$cmd\n"; + system($cmd); + $? == 0 || + mydie("Command '$cmd' failed with exitlevel $?"); + # Sort the $als_px and $als_debug files to guarantee that reads and + # alignments for a given read appear in the same order in both + $cmd = "sort -k 1,1 -n -k 2,2 -k 3,3 -k 4,4 < $als_px | grep -v '^\@PG' > $als_px.sorted"; + print "$cmd\n"; + system($cmd); + $? == 0 || + mydie("Failed to sort alignment file $als_px\n"); + # Sort the $als_px and $als_debug files to guarantee that reads and + # alignments for a given read appear in the same order in both + $cmd = "sort -k 1,1 -n -k 2,2 -k 3,3 -k 4,4 < $als_debug | grep -v '^\@PG' > $als_debug.sorted"; + print "$cmd\n"; + system($cmd); + $? == 0 || + mydie("Failed to sort alignment file $als_debug\n"); + $cmd = "diff -uw $als_debug.sorted $als_px.sorted"; + print "$cmd\n"; + system($cmd); + $? == 0 || + mydie("diff found a difference between bowtie2-align-debug and bowtie2 ". + "-p output for same input (above)\n"); + } + + # With some probability, also run debug Bowtie in -p X mode with X > 1 and + # with the --reorder argument and check that results are identical + if(int(rand(3)) == 0) { + print STDERR "ALSO checking that bowtie2 and bowtie2 -p X --reorder w/ X > 1 match up\n"; + my $p = int(rand(3))+2; + $cmd = "$conf->{bowtie2} $argstr -p $p $idx --reorder $inputfn | grep -v '^\@PG' > $als_px_reord"; + print "$cmd\n"; + system($cmd); + $? == 0 || mydie("Command '$cmd' failed with exitlevel $?"); + $cmd = "diff -uw $als_debug $als_px_reord"; + print "$cmd\n"; + system($cmd); + $? == 0 || + mydie("diff found a difference between bowtie2-align-debug and bowtie2 ". + "-p --reorder output for same input (above)\n"); + } +} + +## +# Generate a new test case +# +# Possible key/value pairs in $conf hash: +# +# 1. bowtie2_build: path to bowtie2-build binary +# 2. bowtie2: path to bowtie2 binary +# 3. bowtie2_build_debug: path to bowtie2-build-debug binary +# 4. bowtie2_debug: path to bowtie2-debug binary +# 5. tempdir: temporary directory for reference/reads/index +# 6. no_paired: defined & non-0 -> don't generate paired-end datasets +# 7. no_color: defined & non-0 -> don't generate colorspace datasets +# 8. single_thread: defined & non-0 -> don't use -p X where X > 1 +# +sub nextCase { + my ($self, $conf) = @_; + + $conf->{bowtie2_build} = "bowtie2-build" unless defined($conf->{bowtie2_build}); + $conf->{bowtie2} = "bowtie2-align" unless defined($conf->{bowtie2}); + $conf->{bowtie2_build_debug} = "bowtie2-build-debug" unless defined($conf->{bowtie2_build_debug}); + $conf->{bowtie2_debug} = "bowtie2-align-debug" unless defined($conf->{bowtie2_debug}); + $conf->{tempdir} = "/tmp" unless defined($conf->{tempdir}); + srand(time ^ $$); + $conf->{randstr} = randStr(8); + + print "*** TEST CASE ***\n"; + + # Generate the references + my $refdnagen = $self->genDNAgen(); + # Generate references and write them to a temporary fasta file + my $tmpfn = "$conf->{tempdir}/Sim.pm.$conf->{randstr}.fa"; + my %refs = (); + $self->genRef(\%refs, $refdnagen, $conf, $tmpfn); + # Run bowtie2-build + my $tmpidxfn = "$conf->{tempdir}/Sim.pm.$conf->{randstr}"; + my $buildArgs = $self->genBuildArgs(); + $self->build($tmpfn, $tmpidxfn, $conf, $buildArgs); + my $numruns = 10; + $numruns *= 10 if $conf->{small}; # Lots of short runs + # For each batch of reads / bowtie options + for(1..$numruns) { + print "*** Run $_ of $numruns\n"; + # Generate mutated version of the reference as our subject genome + my $subj = $self->mutate(\%refs); + # Generate all the input, including reads, pairedness, + # fragment information, whether it's colorspace, etc + my $input = $self->genInput($subj, $conf); + # Mutate the input + my $mutinput = $self->mutateSeq($input); + # Select Bowtie arguments + my $args = $self->genAlignArgs($mutinput, $input->{color}, $conf); + $self->align($tmpfn, $tmpidxfn, $mutinput, $conf, $args); + # Sanity check output. Possible sanity checks are: + # 1. Check alignments & edits against reference + # 2. Compare bowtie2 and bowtie2-debug + # 3. Compare -p X>1 and -p 1 + } +} + +if($0 =~ /Sim\.pm$/) { + print "Running unit tests\n"; + # Run unit tests +} + +1; diff --git a/scripts/sim/Test.pm b/scripts/sim/Test.pm new file mode 100644 index 0000000..82b3793 --- /dev/null +++ b/scripts/sim/Test.pm @@ -0,0 +1,47 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package Test; +use strict; +use Carp; + +sub test($$) { + my ($name, $f) = @_; + print "Test \"$name\"..."; + $f->(); + print "PASSED\n"; +} + +sub shouldSucceed($$) { + my ($name, $f) = @_; + print "Test \"$name\"..."; + $f->() || die ""; + print "PASSED\n"; +} + +sub shouldFail($$) { + my ($name, $f) = @_; + print "Test \"$name\"..."; + $f->() && die ""; + print "PASSED\n"; +} + +1; diff --git a/scripts/sim/contrib/ForkManager.pm b/scripts/sim/contrib/ForkManager.pm new file mode 100644 index 0000000..331c59c --- /dev/null +++ b/scripts/sim/contrib/ForkManager.pm @@ -0,0 +1,412 @@ +=head1 NAME + +Parallel::ForkManager - A simple parallel processing fork manager + +=head1 SYNOPSIS + + use Parallel::ForkManager; + + $pm = new Parallel::ForkManager($MAX_PROCESSES); + + foreach $data (@all_data) { + # Forks and returns the pid for the child: + my $pid = $pm->start and next; + + ... do some work with $data in the child process ... + + $pm->finish; # Terminates the child process + } + +=head1 DESCRIPTION + +This module is intended for use in operations that can be done in parallel +where the number of processes to be forked off should be limited. Typical +use is a downloader which will be retrieving hundreds/thousands of files. + +The code for a downloader would look something like this: + + use LWP::Simple; + use Parallel::ForkManager; + + ... + + @links=( + ["http://www.foo.bar/rulez.data","rulez_data.txt"], + ["http://new.host/more_data.doc","more_data.doc"], + ... + ); + + ... + + # Max 30 processes for parallel download + my $pm = new Parallel::ForkManager(30); + + foreach my $linkarray (@links) { + $pm->start and next; # do the fork + + my ($link,$fn) = @$linkarray; + warn "Cannot get $fn from $link" + if getstore($link,$fn) != RC_OK; + + $pm->finish; # do the exit in the child process + } + $pm->wait_all_children; + +First you need to instantiate the ForkManager with the "new" constructor. +You must specify the maximum number of processes to be created. If you +specify 0, then NO fork will be done; this is good for debugging purposes. + +Next, use $pm->start to do the fork. $pm returns 0 for the child process, +and child pid for the parent process (see also L). +The "and next" skips the internal loop in the parent process. NOTE: +$pm->start dies if the fork fails. + +$pm->finish terminates the child process (assuming a fork was done in the +"start"). + +NOTE: You cannot use $pm->start if you are already in the child process. +If you want to manage another set of subprocesses in the child process, +you must instantiate another Parallel::ForkManager object! + +=head1 METHODS + +=over 5 + +=item new $processes + +Instantiate a new Parallel::ForkManager object. You must specify the maximum +number of children to fork off. If you specify 0 (zero), then no children +will be forked. This is intended for debugging purposes. + +=item start [ $process_identifier ] + +This method does the fork. It returns the pid of the child process for +the parent, and 0 for the child process. If the $processes parameter +for the constructor is 0 then, assuming you're in the child process, +$pm->start simply returns 0. + +An optional $process_identifier can be provided to this method... It is used by +the "run_on_finish" callback (see CALLBACKS) for identifying the finished +process. + +=item finish [ $exit_code ] + +Closes the child process by exiting and accepts an optional exit code +(default exit code is 0) which can be retrieved in the parent via callback. +If you use the program in debug mode ($processes == 0), this method doesn't +do anything. + +=item set_max_procs $processes + +Allows you to set a new maximum number of children to maintain. Returns +the previous setting. + +=item wait_all_children + +You can call this method to wait for all the processes which have been +forked. This is a blocking wait. + +=back + +=head1 CALLBACKS + +You can define callbacks in the code, which are called on events like starting +a process or upon finish. + +The callbacks can be defined with the following methods: + +=over 4 + +=item run_on_finish $code [, $pid ] + +You can define a subroutine which is called when a child is terminated. It is +called in the parent process. + +The paremeters of the $code are the following: + + - pid of the process, which is terminated + - exit code of the program + - identification of the process (if provided in the "start" method) + - exit signal (0-127: signal name) + - core dump (1 if there was core dump at exit) + +=item run_on_start $code + +You can define a subroutine which is called when a child is started. It called +after the successful startup of a child in the parent process. + +The parameters of the $code are the following: + + - pid of the process which has been started + - identification of the process (if provided in the "start" method) + +=item run_on_wait $code, [$period] + +You can define a subroutine which is called when the child process needs to wait +for the startup. If $period is not defined, then one call is done per +child. If $period is defined, then $code is called periodically and the +module waits for $period seconds betwen the two calls. Note, $period can be +fractional number also. The exact "$period seconds" is not guarranteed, +signals can shorten and the process scheduler can make it longer (on busy +systems). + +The $code called in the "start" and the "wait_all_children" method also. + +No parameters are passed to the $code on the call. + +=back + +=head1 EXAMPLE + +=head2 Parallel get + +This small example can be used to get URLs in parallel. + + use Parallel::ForkManager; + use LWP::Simple; + my $pm=new Parallel::ForkManager(10); + for my $link (@ARGV) { + $pm->start and next; + my ($fn)= $link =~ /^.*\/(.*?)$/; + if (!$fn) { + warn "Cannot determine filename from $fn\n"; + } else { + $0.=" ".$fn; + print "Getting $fn from $link\n"; + my $rc=getstore($link,$fn); + print "$link downloaded. response code: $rc\n"; + }; + $pm->finish; + }; + +=head2 Callbacks + +Example of a program using callbacks to get child exit codes: + + use strict; + use Parallel::ForkManager; + + my $max_procs = 5; + my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara ); + # hash to resolve PID's back to child specific information + + my $pm = new Parallel::ForkManager($max_procs); + + # Setup a callback for when a child finishes up so we can + # get it's exit code + $pm->run_on_finish( + sub { my ($pid, $exit_code, $ident) = @_; + print "** $ident just got out of the pool ". + "with PID $pid and exit code: $exit_code\n"; + } + ); + + $pm->run_on_start( + sub { my ($pid,$ident)=@_; + print "** $ident started, pid: $pid\n"; + } + ); + + $pm->run_on_wait( + sub { + print "** Have to wait for one children ...\n" + }, + 0.5 + ); + + foreach my $child ( 0 .. $#names ) { + my $pid = $pm->start($names[$child]) and next; + + # This code is the child process + print "This is $names[$child], Child number $child\n"; + sleep ( 2 * $child ); + print "$names[$child], Child $child is about to get out...\n"; + sleep 1; + $pm->finish($child); # pass an exit code to finish + } + + print "Waiting for Children...\n"; + $pm->wait_all_children; + print "Everybody is out of the pool!\n"; + +=head1 BUGS AND LIMITATIONS + +Do not use Parallel::ForkManager in an environment, where other child +processes can affect the run of the main program, so using this module +is not recommended in an environment where fork() / wait() is already used. + +If you want to use more than one copies of the Parallel::ForkManager, then +you have to make sure that all children processes are terminated, before you +use the second object in the main program. + +You are free to use a new copy of Parallel::ForkManager in the child +processes, although I don't think it makes sense. + +=head1 COPYRIGHT + +Copyright (c) 2000 Szabó, Balázs (dLux) + +All right reserved. This program is free software; you can redistribute it +and/or modify it under the same terms as Perl itself. + +=head1 AUTHOR + + dLux (Szabó, Balázs) + +=head1 CREDITS + + Noah Robin (documentation tweaks) + Chuck Hirstius (callback exit status, example) + Grant Hopwood (win32 port) + Mark Southern (bugfix) + +=cut + +package Parallel::ForkManager; +use POSIX ":sys_wait_h"; +use strict; +use vars qw($VERSION); +$VERSION='0.7.5'; + +sub new { my ($c,$processes)=@_; + my $h={ + max_proc => $processes, + processes => {}, + in_child => 0, + }; + return bless($h,ref($c)||$c); +}; + +sub start { my ($s,$identification)=@_; + die "Cannot start another process while you are in the child process" + if $s->{in_child}; + while ($s->{max_proc} && ( keys %{ $s->{processes} } ) >= $s->{max_proc}) { + $s->on_wait; + $s->wait_one_child(defined $s->{on_wait_period} ? &WNOHANG : undef); + }; + $s->wait_children; + if ($s->{max_proc}) { + my $pid=fork(); + die "Cannot fork: $!" if !defined $pid; + if ($pid) { + $s->{processes}->{$pid}=$identification; + $s->on_start($pid,$identification); + } else { + $s->{in_child}=1 if !$pid; + } + return $pid; + } else { + $s->{processes}->{$$}=$identification; + $s->on_start($$,$identification); + return 0; # Simulating the child which returns 0 + } +} + +sub finish { my ($s, $x)=@_; + if ( $s->{in_child} ) { + exit ($x || 0); + } + if ($s->{max_proc} == 0) { # max_proc == 0 + $s->on_finish($$, $x ,$s->{processes}->{$$}, 0, 0); + delete $s->{processes}->{$$}; + } + return 0; +} + +sub wait_children { my ($s)=@_; + return if !keys %{$s->{processes}}; + my $kid; + do { + $kid = $s->wait_one_child(&WNOHANG); + } while $kid > 0 || $kid < -1; # AS 5.6/Win32 returns negative PIDs +}; + +sub wait_one_child { my ($s,$par)=@_; + my $kid; + while (1) { + $kid = $s->_waitpid(-1,$par||=0); + last if $kid == 0 || $kid == -1; # AS 5.6/Win32 returns negative PIDs + redo if !exists $s->{processes}->{$kid}; + my $id = delete $s->{processes}->{$kid}; + $s->on_finish( $kid, $? >> 8 , $id, $? & 0x7f, $? & 0x80 ? 1 : 0); + last; + } + $kid; +}; + +sub wait_all_children { my ($s)=@_; + while (keys %{ $s->{processes} }) { + $s->on_wait; + $s->wait_one_child(defined $s->{on_wait_period} ? &WNOHANG : undef); + }; +} + +sub run_on_finish { my ($s,$code,$pid)=@_; + $s->{on_finish}->{$pid || 0}=$code; +} + +sub on_finish { my ($s,$pid,@par)=@_; + my $code=$s->{on_finish}->{$pid} || $s->{on_finish}->{0} or return 0; + $code->($pid,@par); +}; + +sub run_on_wait { my ($s,$code, $period)=@_; + $s->{on_wait}=$code; + $s->{on_wait_period} = $period; +} + +sub on_wait { my ($s)=@_; + if(ref($s->{on_wait}) eq 'CODE') { + $s->{on_wait}->(); + if (defined $s->{on_wait_period}) { + local $SIG{CHLD} = sub { } if ! defined $SIG{CHLD}; + select undef, undef, undef, $s->{on_wait_period} + }; + }; +}; + +sub run_on_start { my ($s,$code)=@_; + $s->{on_start}=$code; +} + +sub on_start { my ($s,@par)=@_; + $s->{on_start}->(@par) if ref($s->{on_start}) eq 'CODE'; +}; + +sub set_max_procs { my ($s, $mp)=@_; + $s->{max_proc} = $mp; +} + +# OS dependant code follows... + +sub _waitpid { # Call waitpid() in the standard Unix fashion. + return waitpid($_[1],$_[2]); +} + +# On ActiveState Perl 5.6/Win32 build 625, waitpid(-1, &WNOHANG) always +# blocks unless an actual PID other than -1 is given. +sub _NT_waitpid { my ($s, $pid, $par) = @_; + if ($par == &WNOHANG) { # Need to nonblock on each of our PIDs in the pool. + my @pids = keys %{ $s->{processes} }; + # Simulate -1 (no processes awaiting cleanup.) + return -1 unless scalar(@pids); + # Check each PID in the pool. + my $kid; + foreach $pid (@pids) { + $kid = waitpid($pid, $par); + return $kid if $kid != 0; # AS 5.6/Win32 returns negative PIDs. + } + return $kid; + } else { # Normal waitpid() call. + return waitpid($pid, $par); + } +} + +{ + local $^W = 0; + if ($^O eq 'NT' or $^O eq 'MSWin32') { + *_waitpid = \&_NT_waitpid; + } +} + +1; diff --git a/scripts/sim/run.pl b/scripts/sim/run.pl new file mode 100644 index 0000000..02bf282 --- /dev/null +++ b/scripts/sim/run.pl @@ -0,0 +1,135 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +use strict; +use warnings; +use Getopt::Long; +use FindBin qw($Bin); +use lib "$Bin"; +use lib "$Bin/contrib"; +use Sim; +use ForkManager; + +# Simulator configuration +my %conf = ( + bowtie2_build => "bowtie2-build", + bowtie2 => "bowtie2", + bowtie2_build_debug => "bowtie2-build-debug", + bowtie2_debug => "bowtie2-debug", + tempdir => "/tmp", + no_color => 1, + small => 1 +); + +# Number of parallel processes to use +my $cpus = 1; + +my $usage = qq! +run.pl [options*] + +Options: + + --bowtie2 Path to bowtie2 release binary + --bowtie2-debug Path to bowtie2 debug binary + --bowtie2-build Path to bowtie2-build release binary + --bowtie2-build-debug Path to bowtie2-build debug binary + --tempdir Put temporary files here + --cases Each thread runs around cases (def: 5) + --cpus / -p Run test cases in threads at once + --maxreads Handle at most reads per case + --numrefs Generate refs per case + --die-with-child Kill parent as soon as 1 child dies + --no-die-with-child Don\'t kill parent as soon as 1 child dies + --small Make small test cases + --help Print this usage message + +!; + +my $help = 0; +my $ncases = 5; +my $dieWithChild = 1; + +GetOptions( + "bowtie2=s" => \$conf{bowtie2}, + "bowtie2-debug=s" => \$conf{bowtie2_debug}, + "bowtie2-build=s" => \$conf{bowtie2_build}, + "bowtie2-build-debug=s" => \$conf{bowtie2_build_debug}, + "tempdir|tmpdir=s" => \$conf{tempdir}, + "cases-per-thread=i" => \$ncases, + "small" => \$conf{small}, + "large" => sub { $conf{small} = 0 }, + "no-paired" => \$conf{no_paired}, + "color" => sub { $conf{no_color} = 0 }, + "no-color" => \$conf{no_color}, + "help" => \$help, + "die-with-child" => \$dieWithChild, + "no-die-with-child" => sub { $dieWithChild = 0 }, + "p|cpus=i" => \$cpus, + "u|qupto|maxreads=i" => \$conf{maxreads}, + "numrefs|num-refs=i" => \$conf{numrefs}, +) || die "Bad options;"; + +if($help) { + print $usage; + exit 0; +} + +my $sim = Sim->new(); +my $pm = new Parallel::ForkManager($cpus); + +# Callback for when a child finishes so we can get its exit code +my @childFailed = (); +my @childFailedPid = (); + +$pm->run_on_finish(sub { + my ($pid, $exit_code, $ident) = @_; + if($exit_code != 0) { + push @childFailed, $exit_code; + push @childFailedPid, $pid; + !$dieWithChild || die "Dying with child with PID $pid"; + } +}); + +my $totcases = $ncases * $cpus; +for(1..$totcases) { + my $childPid = $pm->start; + if($childPid != 0) { + next; # spawn the next child + } + $sim->nextCase(\%conf); + $pm->finish; +} +$pm->wait_all_children; +for(@childFailedPid) { + print STDERR "Error message from child with pid $_:\n"; + my $fn = ".run.pl.child.$_"; + if(open(ER, $fn)) { + print STDERR "---------\n"; + while() { + print STDERR $_; + } + print STDERR "---------\n"; + close(ER); + } else { + print STDERR "(could not open $fn)\n"; + } +} +print STDERR "PASSED\n"; diff --git a/scripts/sim/run.sh b/scripts/sim/run.sh new file mode 100644 index 0000000..6e6c2ae --- /dev/null +++ b/scripts/sim/run.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +CPUS=$1 +shift +make -j $CPUS bowtie2-align bowtie2-align-debug bowtie2-build bowtie2-build-debug && \ +perl scripts/sim/run.pl \ + --bowtie2=./bowtie2-align \ + --bowtie2-debug=./bowtie2-align-debug \ + --bowtie2-build=./bowtie2-build \ + --bowtie2-build-debug=./bowtie2-build-debug \ + --cpus=$CPUS \ + $* diff --git a/scripts/sim/unit.sh b/scripts/sim/unit.sh new file mode 100644 index 0000000..f4fdcf8 --- /dev/null +++ b/scripts/sim/unit.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +d=`dirname $0` +for i in `ls $d/*.pm` ; do echo $i ; perl $i --test ; done diff --git a/scripts/test/DNA.pm b/scripts/test/DNA.pm new file mode 100644 index 0000000..06a6ec7 --- /dev/null +++ b/scripts/test/DNA.pm @@ -0,0 +1,129 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package DNA; +use strict; +use warnings; +use Carp; + +my %revcompMap = ( + "A" => "T", "a" => "t", + "T" => "A", "t" => "a", + "C" => "G", "c" => "g", + "G" => "C", "g" => "c", + "R" => "Y", "r" => "y", + "Y" => "R", "y" => "r", + "M" => "K", "m" => "k", + "K" => "M", "k" => "m", + "S" => "S", "s" => "s", + "W" => "W", "w" => "w", + "B" => "V", "b" => "v", + "V" => "B", "v" => "b", + "H" => "D", "h" => "d", + "D" => "H", "d" => "h", + "N" => "N", "n" => "n" +); + +my %compat = ( + "A" => "A", + "T" => "T", + "C" => "C", + "G" => "G", + "R" => "AG", + "Y" => "CT", + "M" => "AC", + "K" => "GT", + "S" => "CG", + "W" => "AT", + "B" => "CGT", + "V" => "ACG", + "H" => "ACT", + "D" => "AGT", + "N" => "N" +); + +my %incompat = ( + "A" => "CGT", + "T" => "ACG", + "C" => "AGT", + "G" => "ACT", + "R" => "CT", + "Y" => "AG", + "M" => "GT", + "K" => "AC", + "S" => "AT", + "W" => "CG", + "B" => "A", + "V" => "T", + "H" => "G", + "D" => "C", + "N" => "N" +); + +my %unambigSet = ( + "A" => 1, "a" => 1, + "C" => 1, "c" => 1, + "G" => 1, "g" => 1, + "T" => 1, "t" => 1 +); + +## +# Return the complement, incl. if it's IUPAC. +# +sub comp($) { + my $ret = $revcompMap{$_[0]} || die "Can't reverse-complement '$_[0]'"; + return $ret; +} + +## +# Return the complement, incl. if it's IUPAC. +# +sub revcomp { + my ($ret, $color) = @_; + $ret = reverse $ret; + unless($color) { + for(my $i = 0; $i < length($ret); $i++) { + substr($ret, $i, 1) = comp(substr($ret, $i, 1)); + } + } + return $ret; +} + +## +# Return true iff it's unambiguous. +# +sub unambig($) { + return $unambigSet{$_[0]}; +} + +## +# Manipulate DNA in an integer-indexed fashion. +# +sub plus($$) { + my ($c, $amt) = @_; + my %ctoi = ("A" => 0, "C" => 1, "G" => 2, "T" => 3); + my %itoc = (0 => "A", 1 => "C", 2 => "G", 3 => "T"); + $c = uc $c; + defined($ctoi{$c}) || die; + return $itoc{($ctoi{$c}+$amt) % 4}; +} + +1; diff --git a/scripts/test/Read.pm b/scripts/test/Read.pm new file mode 100644 index 0000000..819a077 --- /dev/null +++ b/scripts/test/Read.pm @@ -0,0 +1,178 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +package Read; +use strict; +use Carp; +use FindBin qw($Bin); +use lib $Bin; +use DNA; +use Test; + +sub new { + my ($class, $name, $seq, $qual, $color, $fw, $orig) = @_; + $name = "noname" unless defined($name); + return bless { + _name => $name, + _seq => $seq || croak("No sequence"), + _qual => $qual || croak("No qualities"), + _color => $color || 0, + _fw => $fw || croak("No orientation"), + _orig => $orig || croak("No original read string") + }, $class; +} +sub name { return $_[0]->{_name} } +sub seq { return $_[0]->{_seq} } +sub qual { return $_[0]->{_qual} } +sub color { return $_[0]->{_color} } +sub fw { return $_[0]->{_fw} } +sub orig { return $_[0]->{_orig} } +sub len { return length($_[0]->seq()) } + +## +# Obtain a character from the read. +# +sub at { + my ($self, $off, $ori) = @_; + my ($c, $q) = ""; + if($ori eq "RtL") { + $c = uc substr($self->seq(), -$off-1, 1); + $q = substr($self->qual(), -$off-1, 1); + } else { + $c = uc substr($self->seq(), $off, 1); + $q = substr($self->qual(), $off, 1); + } + length($c) == 1 || die; + return ($c, $q); +} + +## +# Load a set of FASTQ reads into the given reads array. +# +sub fromFastq { + my ($fh, $color, $reads) = @_; + $reads = [] unless defined($reads); + while(<$fh>) { + my $l1 = $_; + my $l2 = <$fh>; defined($l2) || croak("Name line followed by EOF"); + my $l3 = <$fh>; defined($l3) || croak("Sequence line followed by EOF"); + my $l4 = <$fh>; defined($l4) || croak("Name2 line followed by EOF"); + my $orig = "$l1$l2$l3$l4"; + chomp($l1); chomp($l2); chomp($l3); chomp($l4); + push @{$reads}, Read->new(substr($l1, 1), $l2, $l4, $color, "FW", $orig); + } + return $reads; +} + +## +# Load a set of FASTQ reads into the given reads array. +# +sub fromFastqs { + my ($fqs, $color, $reads) = @_; + $reads = [] unless defined($reads); + for my $f (@$fqs) { + my $fqfh; + open($fqfh, $f =~ /\.gz$/ ? "gzip -dc $f |" : "$f") || croak("Could not open $f for reading"); + fromFastq($fqfh, $color, $reads); + close($fqfh); + } + return $reads; +} + +## +# Load a set of FASTA reads into the given reads array. +# +sub fromFasta { + my ($fh, $color, $reads) = @_; + $reads = [] unless defined($reads); + while(<$fh>) { + my $l1 = $_; + my $l2 = <$fh>; defined($l2) || croak("Name line followed by EOF"); + my $orig = "$l1$l2"; + chomp($l1); chomp($l2); + my $qual = "I" x length($l2); + push @{$reads}, Read->new(substr($l1, 1), $l2, $qual, $color, "FW", $orig); + } + return $reads; +} + +## +# Load a set of FASTA reads into the given reads array. +# +sub fromFastas { + my ($fas, $color, $reads) = @_; + $reads = [] unless defined($reads); + for my $f (@$fas) { + my $fafh; + open($fafh, $f =~ /\.gz$/ ? "gzip -dc $f |" : "$f") || croak("Could not open $f for reading"); + fromFasta($fafh, $color, $reads); + close($fafh); + } + return $reads; +} + +## +# Load a set of FASTA reads into the given reads array. +# +sub fromStrings { + my ($strs, $color, $reads) = @_; + $reads = [] unless defined($reads); + my $idx = 0; + for my $str (@$strs) { + my $qual = "I" x length($str); + push @{$reads}, new Read($idx, $str, $qual, $color, "FW", $str); + $idx++; + } + return $reads; +} + +sub test1 { + my $r = new Read("blah", "TTACGAACCACAACGTATCG", "I"x20, 0, "FW", "?"); + my ($c, $q) = $r->at(0, "LtR"); + ($c eq "T" && $q eq "I") || croak("Expected (T, I), got ($c, $q)\n"); + ($c, $q) = $r->at(0, "RtL"); + ($c eq "G" && $q eq "I") || croak("Expected (G, I), got ($c, $q)\n"); + ($c, $q) = $r->at(1, "LtR"); + ($c eq "T" && $q eq "I") || croak("Expected (T, I), got ($c, $q)\n"); + ($c, $q) = $r->at(1, "RtL"); + ($c eq "C" && $q eq "I") || croak("Expected (C, I), got ($c, $q)\n"); + return 1; +} + +sub test2 { + my $rs = fromStrings(["ACGATGCTACG", "TGACGATGCTAG"], 0); + $rs->[0]->seq() eq "ACGATGCTACG" || croak($rs->[0]->seq()); + $rs->[0]->qual() eq "IIIIIIIIIII" || croak($rs->[0]->qual()); + $rs->[0]->name() eq "0" || croak($rs->[0]->name()); + $rs->[1]->seq() eq "TGACGATGCTAG" || croak($rs->[1]->seq()); + $rs->[1]->qual() eq "IIIIIIIIIIII" || croak($rs->[1]->qual()); + $rs->[1]->name() eq "1" || croak($rs->[1]->name()); + return 1; +} + +if($0 =~ /Read\.pm$/) { + print "Running unit tests\n"; + # Run unit tests + print "Test \"test1\"..."; test1(); print "PASSED\n"; + print "Test \"test2\"..."; test2(); print "PASSED\n"; +} + +1; diff --git a/scripts/test/args.pl b/scripts/test/args.pl new file mode 100644 index 0000000..15740f9 --- /dev/null +++ b/scripts/test/args.pl @@ -0,0 +1,134 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +## +# args.pl +# +# Basic tests to ensure that bad combinations of arguments are rejected +# and good ones are accepted. +# + +my $bowtie2 = "./bowtie2"; +my $bowtie2_d = "./bowtie2-debug"; +if(system("$bowtie2 --version") != 0) { + print STDERR "Could not execute ./bowtie2; looking in PATH...\n"; + $bowtie2 = `which bowtie2`; + chomp($bowtie2); + if(system("$bowtie2 --version") != 0) { + die "Could not find bowtie2 in current directory or in PATH\n"; + } +} +if(system("$bowtie2_d --version") != 0) { + print STDERR "Could not execute ./bowtie2-debug; looking in PATH...\n"; + $bowtie2_d = `which bowtie2-debug`; + chomp($bowtie2_d); + if(system("$bowtie2_d --version") != 0) { + die "Could not find bowtie2-debug in current directory or in PATH\n"; + } +} + +if(! -f "e_coli_c.1.ebwt") { + print STDERR "Making colorspace e_coli index\n"; + my $bowtie2_build = "./bowtie2-build"; + if(system("$bowtie2_build --version") != 0) { + print STDERR "Could not execute ./bowtie2-build; looking in PATH...\n"; + $bowtie2_build = `which $bowtie2_build`; + chomp($bowtie2_build); + if(system("$bowtie2_build --version") != 0) { + die "Could not find bowtie2-build in current directory or in PATH\n"; + } + } + system("$bowtie2_build -C genomes/NC_008253.fna e_coli_c") && die; +} else { + print STDERR "Colorspace e_coli index already present...\n"; +} + +open TMP, ">.args.pl.1.fa" || die; +print TMP ">\nT0120012002012030303023\n"; +close(TMP); +open TMP, ">.args.pl.1.qv" || die; +print TMP ">\n10 11 12 10 10 11 12 10 10 12 10 22 33 23 13 10 12 23 24 25 26 27\n"; +close(TMP); +open TMP, ">.args.pl.2.qv" || die; +print TMP ">\n9 10 11 12 10 10 11 12 10 10 12 10 22 33 23 13 10 12 23 24 25 26 27\n"; +close(TMP); + +my @bad = ( + "-N 6", + "-N 5", + "-N 4", + "-N 3" +); + +my @badEx = ( + "e_coli -f .args.pl.1.fa -Q .args.pl.1.qv", + "e_coli_c -f .args.pl.1.fa -Q .args.pl.1.qv" +); + +my @good = ( + "-N 0", + "-N 1", + "-N 2" +); + +my @goodEx = ( + "-C e_coli_c -f .args.pl.1.fa -Q .args.pl.1.qv", + "-C e_coli_c -f .args.pl.1.fa -Q .args.pl.2.qv" +); + +sub run($) { + my $cmd = shift; + print "$cmd\n"; + return system($cmd); +} + +print "Bad:\n"; +for my $a (@bad) { + run("$bowtie2 $a e_coli reads/e_coli_1000.fq /dev/null") != 0 || + die "bowtie2 should have rejected: \"$a\"\n"; + run("$bowtie2_d $a e_coli reads/e_coli_1000.fq /dev/null") != 0 || + die "bowtie2-debug should have rejected: \"$a\"\n"; + print "PASSED: bad args \"$a\"\n"; +} +print "\nBadEx:\n"; +for my $a (@badEx) { + run("$bowtie2 $a /dev/null") != 0 || + die "bowtie2 should have rejected: \"$a\"\n"; + run("$bowtie2_d $a /dev/null") != 0 || + die "bowtie2-debug should have rejected: \"$a\"\n"; + print "PASSED: bad args \"$a\"\n"; +} +print "\nGood:\n"; +for my $a (@good) { + run("$bowtie2 $a e_coli reads/e_coli_1000.fq /dev/null") == 0 || + die "bowtie2 should have accepted: \"$a\"\n"; + run("$bowtie2_d $a e_coli reads/e_coli_1000.fq /dev/null") == 0 || + die "bowtie2-debug should have accepted: \"$a\"\n"; + print "PASSED: good args \"$a\"\n"; +} +print "\nGoodEx:\n"; +for my $a (@goodEx) { + run("$bowtie2 $a /dev/null") == 0 || + die "bowtie2 should have accepted: \"$a\"\n"; + run("$bowtie2_d $a /dev/null") == 0 || + die "bowtie2-debug should have accepted: \"$a\"\n"; + print "PASSED: good args \"$a\"\n"; +} diff --git a/scripts/test/simple_tests.pl b/scripts/test/simple_tests.pl new file mode 100644 index 0000000..2bae3de --- /dev/null +++ b/scripts/test/simple_tests.pl @@ -0,0 +1,4805 @@ +#!/usr/bin/perl -w + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +## +# Give simple tests with known results to bowtie2. +# + +use strict; +use warnings; +use Getopt::Long; +use FindBin qw($Bin); +use lib $Bin; +use List::Util qw(max min); +use Data::Dumper; +use DNA; +use Clone qw(clone); +use Test::Deep; + +my $bowtie2 = ""; +my $bowtie2_build = ""; +my $skipColor = 1; + +GetOptions( + "bowtie2=s" => \$bowtie2, + "bowtie2-build=s" => \$bowtie2_build, + "skip-color" => \$skipColor) || die "Bad options"; + +if(! -x $bowtie2 || ! -x $bowtie2_build) { + my $bowtie2_dir = `dirname $bowtie2`; + my $bowtie2_exe = `basename $bowtie2`; + my $bowtie2_build_exe = `basename $bowtie2_build`; + chomp($bowtie2_dir); + chomp($bowtie2_exe); + chomp($bowtie2_build_exe); + system("make -C $bowtie2_dir $bowtie2_exe $bowtie2_build_exe") && die; +} + +(-x $bowtie2) || die "Cannot run '$bowtie2'"; +(-x $bowtie2_build) || die "Cannot run '$bowtie2_build'"; + +my @cases = ( + + { name => "Left-align insertion", + ref => [ "GCGATATCTACGACTGCTACGTACAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGACAGC" ], + norc => 1, + reads => [ "ACAAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGA" ], + # ref: AC-AAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGA + # read: ACAAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGA + # 0123456789012345678901234567890123456789 + cigar => [ "2M1I40M" ], + samoptflags => [ { + "MD:Z:42" => 1, + "YT:Z:UU" => 1, + "NM:i:1" => 1, + "XG:i:1" => 1, + "XO:i:1" => 1, + "AS:i:-8" => 1 } ], + report => "", + args => "" + }, + + { name => "Left-align deletion", + ref => [ "GCGATATCTACGACTGCTACGTACAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGACAGC" ], + norc => 1, + reads => [ "ACGTACAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGA" ], + # ref: ACGTACAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGA + # read: ACGTAC-AAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGA + # 012345678901234567890123456789012345678 + cigar => [ "6M1D39M" ], + samoptflags => [ { + "MD:Z:6^A39" => 1, + "YT:Z:UU" => 1, + "NM:i:1" => 1, + "XG:i:1" => 1, + "XO:i:1" => 1, + "AS:i:-8" => 1 } ], + report => "", + args => "" + }, + + { name => "Left-align insertion with mismatch at LHS", + ref => [ "GCGATATCTACGACTGCTACGCCCAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGACAGC" ], + norc => 1, + reads => [ "TATCTACGACTGCTACGCCCTAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGAC" ], + # ref: GCGATATCTACGACTGCTACGCCCAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGACAGC + # read: TATCTACGACTGCTACGCCC-TAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGAC + # 01234567890123456789-012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 + cigar => [ "20M1D45M" ], + samoptflags => [ { + "MD:Z:20^A0A44" => 1, + "YT:Z:UU" => 1, + "NM:i:2" => 1, + "XG:i:1" => 1, + "XO:i:1" => 1, + "XM:i:1" => 1, + "AS:i:-14" => 1 } ], + report => "", + args => "" + }, + + # This won't necessarily pass because the original location of the deletion + # might + #{ name => "Left-align deletion with mismatch at LHS", + # ref => [ "GCGATATCTACGACTGCTACGCCCAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGACAGC" ], + # norc => 1, + # reads => [ "TATCTACGACTGCTACGCCAAAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGAC" ], + # # ref: GCGATATCTACGACTGCTACGCCC-AAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGACAGC + # # read: TATCTACGACTGCTACGCCAAAAAAAAAAAAAAAAGTGTTTACGTTGCTAGACTCGATCGATCTGAC + # # 01234567890123456789-012345678901234567890123456789012345678901234 + # # 0 1 0 1 2 3 4 + # cigar => [ "20M1I45M" ], + # samoptflags => [ { + # "MD:Z:19C45" => 1, + # "YT:Z:UU" => 1, + # "NM:i:2" => 1, + # "XG:i:1" => 1, + # "XO:i:1" => 1, + # "XM:i:1" => 1, + # "AS:i:-14" => 1 } ], + # report => "", + # args => "" + #}, + + { name => "Flags for when mates align non-concordantly, with many alignments for one", + # 012345678 + ref => [ "CAGCGGCTAGCTATCGATCGTCCGGCAGCTATCATTATGATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGGATAGATCGCTCGCCTGACCTATATCGCTCGCGATTACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGATCGAGGATAGATCGCTCGCCTGACCTATATCGCTCGCGATTACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGATCGAGGATAGATCGCTCGCCTGACCTATATCGCTCGCGATTACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGATCG" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 + # 0 1 2 3 4 5 6 7 8 9 0 1 + # 0 1 + norc => 1, + mate1s => [ "GCGGCTAGCTATCGATCGTCCGGCAGCTATCATTATGA" ], + mate2s => [ "ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA" ], + # 981 1064 1147 + # ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA + samflags_map => [{ 981 => (1 | 128), 1064 => (1 | 128), 1147 => (1 | 128), 2 => (1 | 64) }], + report => "", + args => "" + }, + + { name => "Flags for when mates align non-concordantly, with many alignments for one", + # 012345678 + ref => [ "CAGCGGCTAGCTATCGATCGTCCGGCAGCTATCATTATGATNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAGGATAGATCGCTCGCCTGACCTATATCGCTCGCGATTACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGATCGAG" ], + # 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 + # 0 1 2 3 4 5 6 7 8 9 0 1 + # 0 1 + norc => 1, + mate1s => [ "GCGGCTAGCTATCGATCGTCCGGCAGCTATCATTATGA" ], + mate2s => [ "ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA" ], + tlen_map => [{ 2 => 1021, 981 => -1021 }], + samflags_map => [{ 981 => (1 | 128), 2 => (1 | 64) }], + report => "", + args => "" + }, + + { name => "Flags for when mates align non-concordantly, with many alignments for one", + # 012345678 + ref => [ "CAGCGGCTAGCTATCGATCGTCCGGCAGCTATCATTATGATAGGATAGATCGCTCGCCTGACCTATATCGCTCGCGATTACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGATCGAGGATAGATCGCTCGCCTGACCTATATCGCTCGCGATTACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGATCGAGGATAGATCGCTCGCCTGACCTATATCGCTCGCGATTACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGATCG" ], + # 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 + # 0 * 1 * 2 * + # 0 1 + norc => 1, + mate1s => [ "GCGGCTAGCTATCGATCGTCCGGCAGCTATCATTATGA" ], + mate2s => [ "TCGTCGTGATGCGTCAGCTCGGATAGCCAGTACGTAGCTCGT" ], + # 981 1064 1147 + # ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA ACGAGCTACGTACTGGCTATCCGAGCTGACGCATCACGACGA + samflags_map => [{ 79 => (1 | 2 | 16 | 128), 162 => (1 | 2 | 16 | 128), 245 => (1 | 2 | 16 | 128), 2 => (1 | 2 | 32 | 64) }], + report => "", + args => "" + }, + + # Checking MD:Z strings for alignment + { name => "MD:Z 1", + ref => [ "CACGATCGACTTGA"."C"."TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + reads => [ "CACGATCGACTTGG". "TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + hits => [ { 0 => 1 } ], + samoptflags => [ { + "AS:i:-14" => 1, # alignment score + "XM:i:1" => 1, # num mismatches + "XO:i:1" => 1, # num gap opens + "XG:i:1" => 1, # num gap extensions + "NM:i:2" => 1, # num edits + "MD:Z:13^A0C39" => 1, # mismatching positions/bases + "YT:Z:UU" => 1, # type of alignment (concordant/discordant/etc) + } ] }, + { name => "MD:Z 2", + ref => [ "CACGATCGACTTGA"."A"."TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + reads => [ "CACGATCGACTTGG". "TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + # 0123456789012 012345678901234567890123456789012345678 + hits => [ { 0 => 1 } ], + samoptflags => [ { + "AS:i:-14" => 1, # alignment score + "XM:i:1" => 1, # num mismatches + "XO:i:1" => 1, # num gap opens + "XG:i:1" => 1, # num gap extensions + "NM:i:2" => 1, # num edits + "MD:Z:13^A0A39" => 1, # mismatching positions/bases + "YT:Z:UU" => 1, # type of alignment (concordant/discordant/etc) + } ] }, + { name => "MD:Z 3", + ref => [ "CACGATCGACTTGT"."AA"."TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + reads => [ "CACGATCGACTTGC". "TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + # 0123456789012 012345678901234567890123456789012345678 + hits => [ { 0 => 1 } ], + samoptflags => [ { + "AS:i:-17" => 1, # alignment score + "XM:i:1" => 1, # num mismatches + "XO:i:1" => 1, # num gap opens + "XG:i:2" => 1, # num gap extensions + "NM:i:3" => 1, # num edits + "MD:Z:13^TA0A39" => 1, # mismatching positions/bases + "YT:Z:UU" => 1, # type of alignment (concordant/discordant/etc) + } ] }, + { name => "MD:Z 4", + ref => [ "CACGATCGACTTGN"."NN"."TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + reads => [ "CACGATCGACTTGC". "TCATCGACGCTATCATTAATATATATAAGCCCGCATCTA" ], + # 0123456789012 012345678901234567890123456789012345678 + hits => [ { 0 => 1 } ], + samoptflags => [ { + "AS:i:-12" => 1, # alignment score + "XN:i:3" => 1, # num ambiguous ref bases + "XM:i:1" => 1, # num mismatches + "XO:i:1" => 1, # num gap opens + "XG:i:2" => 1, # num gap extensions + "NM:i:3" => 1, # num edits + "MD:Z:13^NN0N39" => 1, # mismatching positions/bases + "YT:Z:UU" => 1, # type of alignment (concordant/discordant/etc) + } ] }, + + # + # Local alignment + # + + # Local alignment for a short perfect hit where hit spans the read + { name => "Local alignment 1", + ref => [ "TTGT" ], + reads => [ "TTGT" ], + args => "--local --policy \"MIN=L,0.0,0.75\"", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:4=" ], + cigar => [ "4M" ], + samoptflags => [ { + "AS:i:8" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:4" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YP:i:0" => 1, # read aligned repetitively in paired fashion + "YT:Z:UU" => 1, # type of alignment (concordant/discordant/etc) + } ] }, + + # T T G A T T G A + # T x T x + # T x T + # G x G + # T T + + # Local alignment for a short hit where hit is trimmed at one end + { name => "Local alignment 2", + ref => [ "TTGA" ], + reads => [ "TTGT" ], + args => "--local --policy \"MIN=L,0.0,0.75\\;SEED=0,3\\;IVAL=C,1,0\"", + report => "-a", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:3=1S" ], + cigar => [ "3M1S" ], + samoptflags => [ { + "AS:i:6" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:3" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YP:i:0" => 1, # read aligned repetitively in paired fashion + "YT:Z:UU" => 1, # type of alignment (concordant/discordant/etc) + } ] }, + + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + # T T G T T C G T T T G T T C G T + # 0 T x + # 1 T x + # 2 G x + # 3 T x + # 4 T x + # 5 C x + # 6 G x + # 7 T x + # 8 T x + # 9 T x + # 0 G x + # 1 T x + # 2 T x + # + # Score=130 + + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + # T T G T T C G T T T G T T C G T + # 0 T x + # 1 T x + # 2 G x + # 3 T x + # 4 T x + # 5 C x + # 6 G x + # 7 T x + # 8 T + # 9 T + # 0 G + # 1 T + # 2 T + # + # Score=80 + + # Local alignment for a perfect hit + { name => "Local alignment 3", + # TTGTTCGT + # TTGTTCGT + ref => [ "TTGTTCGTTTGTTCGT" ], + # 0123456789012345 + # TTGTTCGTTTGTT + # TTGTTCGT----- + reads => [ "TTGTTCGTTTGTT" ], + args => "--local -L 8 -i C,1,0 --score-min=C,12", + report => "-a", + hits => [ { 0 => 1, 8 => 1 } ], + flags_map => [{ + 0 => "XM:0,XP:0,XT:UU,XC:13=", + 8 => "XM:0,XP:0,XT:UU,XC:8=" + }], + cigar_map => [{ + 0 => "13M", + 8 => "8M5S" + }], + samoptflags_map => [{ + 0 => { "AS:i:26" => 1, "XS:i:16" => 1, "YT:Z:UU" => 1, "MD:Z:13" => 1 }, + 8 => { "AS:i:16" => 1, "XS:i:16" => 1, "YT:Z:UU" => 1, "MD:Z:8" => 1 } + }] + }, + + # 1 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + # T T G T T C G T T T G T T C G T + # 0 T x + # 1 T x + # 2 G x + # 3 T x + # 4 T x + # 5 C x + # 6 G x + # 7 T x + # 8 T + # 9 T + # 10 G + # 1 T + + # Local alignment for a hit that should be trimmed from the right end + { name => "Local alignment 4", + ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGTTTGT" ], + args => "--local --policy \"SEED=0,3\\;IVAL=C,1,0\" --score-min=C,12", + report => "-a", + hits => [ { 0 => 1, 8 => 1 } ], + flags_map => [{ + 0 => "XM:0,XP:0,XT:UU,XC:12=", + 8 => "XM:0,XP:0,XT:UU,XC:8=4S" + }], + cigar_map => [{ + 0 => "12M", + 8 => "8M4S" + }], + samoptflags_map => [{ + 0 => { "AS:i:24" => 1, "XS:i:16" => 1, "YT:Z:UU" => 1, "MD:Z:12" => 1 }, + 8 => { "AS:i:16" => 1, "XS:i:16" => 1, "YT:Z:UU" => 1, "MD:Z:8" => 1 } + }] + }, + + # + # Test some common featuers for the manual. E.g. when more than one + # alignment is reported in -k mode, what order are they reported in? They + # should be in order by alignment score. + # + + { name => "Alignment order -k", + # 012345678 + ref => [ "GCGCATGCACATATCANNNNNGCGCATGCACATATCTNNNNNNNNGCGCATGCACATATTTNNNNNNNNNGCGCATGGTGTTATCA" ], + reads => [ "GCGCATGCACATATCA" ], + quals => [ "GOAIYEFGFIWDSFIU" ], + args => "--min-score C,-24,0 -L 4", + report => "-k 4" + }, + + { name => "Alignment order -a", + # 012345678 + ref => [ "GCGCATGCACATATCANNNNNGCGCATGCACATATCTNNNNNNNNGCGCATGCACATATTTNNNNNNNNNGCGCATGGTGTTATCA" ], + reads => [ "GCGCATGCACATATCA" ], + quals => [ "GOAIYEFGFIWDSFIU" ], + args => "--min-score C,-24,0 -L 4", + report => "-a" + }, + + # + # What order are mates reported in? Should be reporting in mate1/mate2 + # order. + # + + { name => "Mate reporting order, -a", + # 012345678 + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAAATAGACGACTCGATCGCGGATTAGGGGTAGACCCCCCCCCGACTNNNNNNNNNNAGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAAATAGACGACTCGATCGCGGATTAGGGGTAGACCCCCCCCCGACTNNNNNNNNNNAGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAAATAGACGACTCGATCGCGGATTAGGGGTAGACCCCCCCCCGACTNNNNNNNNCGGTAATACGGCCATCGCGGCGGCATTACTCGGCGACTGCACGAGCAGATATTGGGGGTCTAATATAACGTCTCATTAAAACGCTCTAGTCAGCTCATTGGCTCTA" ], + mate1s => [ "CTATCATCACGCGGATATT", "GGGGGGGGTCTACCCCTAA", "ATACGGCCATCGCGGCGGCATTACTCGGCG" ], + mate2s => [ "GGGGGGGGTCTACCCCTAA", "CTATCATCACGCGGATATT", "AGCCAATGAGCTGACTAGAGCGTTTT" ], + quals => [ "GOAIYEFGFIWDSFIU" ], + args => "", + report => "-a" + }, + + { name => "Mate reporting order, -M 1", + # 012345678 + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAAATAGACGACTCGATCGCGGATTAGGGGTAGACCCCCCCCCGACTNNNNNNNNNNAGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAAATAGACGACTCGATCGCGGATTAGGGGTAGACCCCCCCCCGACTNNNNNNNNNNAGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAAATAGACGACTCGATCGCGGATTAGGGGTAGACCCCCCCCCGACTNNNNNNNNCGGTAATACGGCCATCGCGGCGGCATTACTCGGCGACTGCACGAGCAGATATTGGGGGTCTAATATAACGTCTCATTAAAACGCTCTAGTCAGCTCATTGGCTCTA" ], + mate1s => [ "CTATCATCACGCGGATATT", "GGGGGGGGTCTACCCCTAA", "ATACGGCCATCGCGGCGGCATTACTCGGCG" ], + mate2s => [ "GGGGGGGGTCTACCCCTAA", "CTATCATCACGCGGATATT", "AGCCAATGAGCTGACTAGAGCGTTTT" ], + quals => [ "GOAIYEFGFIWDSFIU" ], + args => "", + report => "-M 1" + }, + + # + # Test dovetailing, containment, and overlapping + # + { name => "Non-overlapping; no args", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATA" ], + mate2s => [ "CGCATCGACATTAATATCC" ], + pairhits => [{ "1,23" => 1 }], + mate1fw => 1, mate2fw => 1, + report => "-M 1" + }, + { name => "Non-overlapping; --no-discordant", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATA" ], + mate2s => [ "CGCATCGACATTAATATCC" ], + pairhits => [{ "1,23" => 1 }], + mate1fw => 1, mate2fw => 1, + report => "-M 1 --no-discordant" + }, + { name => "Non-overlapping; --no-discordant --no-mixed", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATA" ], + mate2s => [ "CGCATCGACATTAATATCC" ], + pairhits => [{ "1,23" => 1 }], + mate1fw => 1, mate2fw => 1, + report => "-M 1 --no-discordant --no-mixed" + }, + { name => "Non-overlapping; --no-discordant --no-mixed", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATA" ], + mate2s => [ "CGCATCGACATTAATATCC" ], + pairhits => [{ "1,23" => 1 }], + mate1fw => 1, mate2fw => 1, + report => "-M 1 --no-discordant --no-mixed" + }, + { name => "Non-overlapping; --no-dovetail", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATA" ], + mate2s => [ "CGCATCGACATTAATATCC" ], + pairhits => [{ "1,23" => 1 }], + mate1fw => 1, mate2fw => 1, + args => "--no-dovetail", + report => "-M 1" + }, + { name => "Non-overlapping; --un-conc=.tmp.simple_tests.pl", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATA" ], + mate2s => [ "CGCATCGACATTAATATCC" ], + pairhits => [{ "1,23" => 1 }], + mate1fw => 1, mate2fw => 1, + args => "--un-conc=.tmp.simple_tests.pl", + report => "-M 1" + }, + { name => "Non-overlapping; --no-overlap", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATA" ], + mate2s => [ "CGCATCGACATTAATATCC" ], + pairhits => [{ "1,23" => 1 }], + mate1fw => 1, mate2fw => 1, + args => "--no-overlap", + report => "-M 1" + }, + + { name => "Overlapping; no args", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATATTA" ], + mate2s => [ "TTAGCGCATCGACATTAATATCC" ], + pairhits => [{ "1,19" => 1 }], + mate1fw => 1, mate2fw => 1, + args => "", + report => "-M 1" + }, + { name => "Overlapping; --no-dovetail", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATATTA" ], + mate2s => [ "TTAGCGCATCGACATTAATATCC" ], + pairhits => [{ "1,19" => 1 }], + mate1fw => 1, mate2fw => 1, + args => "--no-dovetail", + report => "-M 1" + }, + { name => "Overlapping; --no-contain", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATATTA" ], + mate2s => [ "TTAGCGCATCGACATTAATATCC" ], + pairhits => [{ "1,19" => 1 }], + mate1fw => 1, mate2fw => 1, + args => "--no-contain", + report => "-M 1" + }, + { name => "Overlapping; --no-overlap", + ref => [ "AGCTATCATCACGCGGATATTAGCGCATCGACATTAATATCCCCAAA" ], + # 01234567890123456789012345678901234567890123456 + mate1s => [ "GCTATCATCACGCGGATATTA" ], + mate2s => [ "TTAGCGCATCGACATTAATATCC" ], + pairhits => [], + mate1fw => 1, mate2fw => 1, + args => "--no-overlap", + report => "-M 1" + }, + + # + # Test XS:i with quality scaling + # + + { name => "Scoring params 1", + # 012345678 + ref => [ "ACTATTGCGCGCATGCACATATCAATTAAGCCGTCTCTCTAAAGAGACCCCAATCTCGCGCGCTAGACGTCAGTAGTTTAATTTTATAAACACCTCGCTGCGGGG" ], + reads => [ "GCGCATGCACATATCAATTAAGCCGTCTCTCTAAAGAGACCCCAATCTCGCGCGCTAGACGTCAGTAGTTTAATTTTATAAACACCTC" ], + quals => [ "GOAIYEFGFIWDSFIUYWEHRIWQWLFNSLDKkjdfglduhiuevhsiuqkAUHFIUEHGIUDJFHSKseuweyriwfskdgbiuuhh" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 7 8 + args => "", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "88M" ], + samoptflags => [ { + "AS:i:0" => 1, + "YT:Z:UU" => 1, + "MD:Z:88" => 1 } ], + }, + + { name => "Scoring params 2", + # 012345678 + ref => [ "ACTATTGCGCGCATGCACATATCAATTAAGCCGTCTCTCTAAAGAGACCCCAATCTCGCGCGCTAGACGTCAGTAGTTT"."TTTATAAACACCTCGCTGCGGGG" ], + reads => [ "NCGCATGCACATtTCAATTAAGCCGTCTCTCTAAAGA". "CCAATCTCGCGCGCTAGACGTCAGTAGTTTAAATTTATAAACACCTC" ], + # * -1 * -6 **** -5 -3 -3 -3 -3 *** -5 -3 -3 -3 + quals => [ "GOAIYEFGFIWDSFIUYWEHRIWQWLFNSLDKkjdfg". "iuevhsiuqkAUHFIUEHGIUDJFHSKseuweyriwfskdgbiuuhh" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 7 8 + args => "--ignore-quals --score-min C,-40,0 -N 1 -L 20", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "37M4D30M3I14M" ], + # 37M4D30M13I4M + samoptflags => [ { + "AS:i:-38" => 1, + "YT:Z:UU" => 1, + "MD:Z:0G11A24^GACC44" => 1, + "NM:i:9" => 1, + "XM:i:2" => 1, + "XG:i:7" => 1, + "XO:i:2" => 1 } ], + }, + + { name => "Scoring params 3", + # 012345678 + ref => [ "ACTATTGCGCGCATGCACATATCAATTAAGCCGTCTCTCTAAAGAGACCCCAATCTCGCGCGCTAGACGTCAGTAGTTT"."TTTATAAACACCTCGCTGCGGGG" ], + reads => [ "NCGCATGCACATtTCAATTAAGCCGTCTCTCTAAAGA". "CCAATCTCGCGCGCTAGACGTCAGTAGTTTAAATTTATAAACACCTC" ], + # * -1 * -6 **** -5 -3 -3 -3 -3 *** -1 -2 -2 -2 + quals => [ "GOAIYEFGFIWDSFIUYWEHRIWQWLFNSLDKkjdfg". "iuevhsiuqkAUHFIUEHGIUDJFHSKseuweyriwfskdgbiuuhh" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 7 8 + args => "--ignore-quals --rfg 1,2 --score-min C,-40,0 -N 1 -L 20", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "37M4D30M3I14M" ], + samoptflags => [ { + "AS:i:-31" => 1, + "YT:Z:UU" => 1, + "MD:Z:0G11A24^GACC44" => 1, + "NM:i:9" => 1, + "XM:i:2" => 1, + "XG:i:7" => 1, + "XO:i:2" => 1 } ], + }, + + { name => "Scoring params 4", + # 012345678 + ref => [ "ACTATTGCGCGCATGCACATATCAATTAAGCCGTCTCTCTAAAGAGACCCCAATCTCGCGCGCTAGACGTCAGTAGTTT"."TTTATAAACACCTCGCTGCGGGG" ], + reads => [ "NCGCATGCACATtTCAATTAAGCCGTCTCTCTAAAGA". "CCAATCTCGCGCGCTAGACGTCAGTAGTTTAAATTTATAAACACCTC" ], + # * -1 * -6 **** -1 -2 -2 -2 -2 *** -5 -3 -3 -3 + quals => [ "GOAIYEFGFIWDSFIUYWEHRIWQWLFNSLDKkjdfg". "iuevhsiuqkAUHFIUEHGIUDJFHSKseuweyriwfskdgbiuuhh" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 7 8 + args => "--ignore-quals --rdg 1,2 --score-min C,-40,0 -N 1 -L 20", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "37M4D30M3I14M" ], + samoptflags => [ { + "AS:i:-30" => 1, + "YT:Z:UU" => 1, + "MD:Z:0G11A24^GACC44" => 1, + "NM:i:9" => 1, + "XM:i:2" => 1, + "XG:i:7" => 1, + "XO:i:2" => 1 } ], + }, + + { name => "Scoring params 5", + # 012345678 + ref => [ "ACTATTGCGCGCATGCACATATCAATTAAGCCGTCTCTCTAAAGAGACCCCAATCTCGCGCGCTAGACGTCAGTAGTTT"."TTTATAAACACCTCGCTGCGGGG" ], + reads => [ "NCGCATGCACATtTCAATTAAGCCGTCTCTCTAAAGA". "CCAATCTCGCGCGCTAGACGTCAGTAGTTTAAATTTATAAACACCTC" ], + # * -1 * -8 **** -5 -3 -3 -3 -3 *** -5 -3 -3 -3 + quals => [ "GOAIYEFGFIWDSFIUYWEHRIWQWLFNSLDKkjdfg". "iuevhsiuqkAUHFIUEHGIUDJFHSKseuweyriwfskdgbiuuhh" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 7 8 + args => "--ignore-quals --mp 8 --score-min C,-40,0 -N 1 -L 20", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "37M4D30M3I14M" ], + samoptflags => [ { + "AS:i:-40" => 1, + "YT:Z:UU" => 1, + "MD:Z:0G11A24^GACC44" => 1, + "NM:i:9" => 1, + "XM:i:2" => 1, + "XG:i:7" => 1, + "XO:i:2" => 1 } ], + }, + + { name => "Scoring params 6", + # 012345678 + ref => [ "ACTATTGCGCGCATGCACATATCAATTAAGCCGTCTCTCTAAAGAGACCCCAATCTCGCGCGCTAGACGTCAGTAGTTT"."TTTATAAACACCTCGCTGCGGGG" ], + reads => [ "NCGCATGCACATtTCAATTAAGCCGTCTCTCTAAAGA". "CCAATCTCGCGCGCTAGACGTCAGTAGTTTAAATTTATAAACACCTC" ], + # * -4 * -6 **** -5 -3 -3 -3 -3 *** -5 -3 -3 -3 + quals => [ "GOAIYEFGFIWDSFIUYWEHRIWQWLFNSLDKkjdfg". "iuevhsiuqkAUHFIUEHGIUDJFHSKseuweyriwfskdgbiuuhh" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 7 8 + args => "--ignore-quals --np 4 --score-min C,-41,0 -N 1 -L 20", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "37M4D30M3I14M" ], + samoptflags => [ { + "AS:i:-41" => 1, + "YT:Z:UU" => 1, + "MD:Z:0G11A24^GACC44" => 1, + "NM:i:9" => 1, + "XM:i:2" => 1, + "XG:i:7" => 1, + "XO:i:2" => 1 } ], + }, + + # + # Test XS:i with quality scaling + # + + { name => "Q XS:i 1a", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIIIA" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-5" => 1, "XS:i:-5" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1a ! --mp 3,3", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIII!" ], + args => "-L 6 --mp 3,3 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-3" => 1, "XS:i:-3" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1a ! --mp 3,6", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIII!" ], + args => "-L 6 --mp 6,3 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-3" => 1, "XS:i:-3" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1a I --mp 3,3", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIIII" ], + args => "-L 6 --mp 3,3 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-3" => 1, "XS:i:-3" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1a I --mp 3,6", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIIII" ], + args => "-L 6 --mp 6,3 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-6" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1a --ignore-quals", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIIIA" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6 --ignore-quals", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-6" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1b", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIII5" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-4" => 1, "XS:i:-4" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1b --ignore-quals", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIII5" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6 --ignore-quals", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-6" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1c", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIII4" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-3" => 1, "XS:i:-3" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "Q XS:i 1c --ignore-quals", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + quals => [ "IIIIIII4" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6 --ignore-quals", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-6" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + # One mate aligns. Ensuring that the unmapped mate gets reference + # information filled in from the other mate. + { ref => [ "CATCGACTGAGACTCGTACGACAATTACGCGCATTATTCGCATCACCAGCGCGGCGCGCGCCCCCTAT" ], + # 01234567890123456789012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 5 6 + # ATCACCAGCGTTTCGCGCGAAACCTA + mate1s => [ "ATCGACTGAGACTCGTACGACAATTAC" ], + mate2s => [ "TAGGTTTCGCGCGAAACGCTGGTGAT" ], + pairhits_orig => [{ "1,1" => 1}] + }, + + { ref => [ "TTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,4,C,1,0", + report => "-M 1" + }, + + # Testing that DEFAULT is -M 1 + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGT" ], + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ + { "YM:i:1" => 1, "YT:Z:UU" => 1, "MD:Z:8" => 1, "YM:i:1" => 1 } + ], + }, + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGT" ], + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ + { "YM:i:1" => 1, "YT:Z:UU" => 1, "MD:Z:8" => 1, "YM:i:1" => 1 } + ], + }, + + # + # Test XS:i + # + + { name => "XS:i 1", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6", + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:-6" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:7A0" => 1, + "NM:i:1" => 1, "XM:i:1" => 1 } ], + }, + + { name => "XS:i 2", + ref => [ "TTGTTCGATTGTTCGA" ], + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,7,C,1 --score-min=C,-5", + report => "", + cigar => [ "*" ], + samoptflags => [{ "YT:Z:UU" => 1, "YM:i:0" => 1 }], + }, + + { name => "XS:i 3a", + ref => [ "TTGTTCGATTGTTCGT" ], + # TTGTTCGT + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:0" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:8" => 1, + "NM:i:0" => 1, "XM:i:0" => 1 } ], + }, + + { name => "XS:i 3b", + ref => [ "TTGTTCGATTGTTCGT" ], + # TTGTTCGT + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6 --seed=52", + report => "-M 1", + hits => [ { 8 => 1 } ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:0" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:8" => 1, + "NM:i:0" => 1, "XM:i:0" => 1 } ], + }, + + { name => "XS:i 3c", + ref => [ "TTGTTCGATTGTTCGT" ], + # TTGTTCGT + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,7,C,1 --score-min=C,-6 --seed=53", + report => "-M 2", + hits => [ { 8 => 1 } ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:0" => 1, "XS:i:-6" => 1, + "YM:i:0" => 1, "YT:Z:UU" => 1, + "MD:Z:8" => 1, + "NM:i:0" => 1, "XM:i:0" => 1 } ], + }, + + { name => "XS:i 4a", + ref => [ "TTGTTCAATTGTTCGATTGTTCGT" ], + # |||||| ||||||| |||||||| + # TTGTTCGT||||||| |||||||| + # TTGTTCGT|||||||| + # TTGTTCGT + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,6,C,1 --score-min=C,-12 --seed=53", + report => "-M 2", + hits => [ { 16 => 1 } ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:0" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:8" => 1, + "NM:i:0" => 1, "XM:i:0" => 1 } ], + }, + + { name => "XS:i 4b", + ref => [ "TTGTTCAATTGTTCGATTGTTCGT" ], + # |||||| ||||||| |||||||| + # TTGTTCGT||||||| |||||||| + # TTGTTCGT|||||||| + # TTGTTCGT + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,6,C,1 --score-min=C,-12 --seed=54", + report => "-M 3", + hits => [ { 16 => 1 } ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:0" => 1, "XS:i:-6" => 1, + "YM:i:0" => 1, "YT:Z:UU" => 1, + "MD:Z:8" => 1, + "NM:i:0" => 1, "XM:i:0" => 1 } ], + }, + + { name => "XS:i 5a", + ref => [ "TTGTTCAATTGTTCGATTGTTCGTTTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAA" ], + # |||||| ||||||| |||||||||||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| + # TTGTTCGT||||||| ||||||||TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| + # TTGTTCGT|||||||| TTGTTCGT TTGTTCGT TTGTTCGT TTGTTCGT TTGTTCGT TTGTTCGT + # TTGTTCGT + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,6,C,1,1 --score-min=C,-12 --seed=54", + report => "-M 1", + hits => [ { 16 => 1 } ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:0" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:8" => 1, + "NM:i:0" => 1, "XM:i:0" => 1 } ], + }, + + { name => "XS:i 5b", + ref => [ "TTGTTCAATTGTTCGATTGTTCGTTTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAATTGTTCAA" ], + # |||||| ||||||| |||||||||||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| |||||| + # TTGTTCGT||||||| ||||||||TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| TTGTTCGT|||||| + # TTGTTCGT|||||||| TTGTTCGT TTGTTCGT TTGTTCGT TTGTTCGT TTGTTCGT TTGTTCGT + # TTGTTCGT + reads => [ "TTGTTCGT" ], + args => "--multiseed=0,5,C,1,1 --score-min=C,-12 --seed=55", + report => "-M 1", + hits => [ { 16 => 1 } ], + cigar => [ "8M" ], + samoptflags => [ { + "AS:i:0" => 1, "XS:i:-6" => 1, + "YM:i:1" => 1, "YT:Z:UU" => 1, + "MD:Z:8" => 1, + "NM:i:0" => 1, "XM:i:0" => 1 } ], + }, + + # Testing BWA-SW-like scoring + # + # a*max{T,c*log(l)} = 1 * max(30, 5.5 * log(56)) = 1 * max(30, 22.139) = 30 + # + { name => "BWA-SW-like 1", + ref => [ "GTTTAGATTCCACTACGCTAACCATCGAGAACTCGTCTCAGAGTTTCGATAGGAAAATCTGCGA" ], + # |||||||||||||||||||||||||||||||||||||||||||||||||||||||| + reads => [ "TAGATTCCACTACGCTAACCATCGAGAACTCGTCTCAGAGTTTCGATAGGAAAATC" ], + # 01234567890123456789012345678901234567890123456789012345 + # 1 2 3 4 5 + args => "--bwa-sw-like", + hits => [{ 3 => 1 }], + samoptflags => [{ "AS:i:56" => 1, "NM:i:0" => 1, + "MD:Z:56" => 1, "YT:Z:UU" => 1 }] + }, + { name => "BWA-SW-like 2", + # 0123 + ref => [ "GTTTAGATTCCACTACGCTAACCATCGAGAACTCGTCTCAGAGTTTCGATAGGAAAATCTGCGA" ], + # |||||||||||||||||||||||||| |||||||||||||||||||||||||||| + reads => [ "TAGATTCCACTACGCTAACCATCGAGTTCTCGTCTCAGAGTTTCGATAGGAAAATC" ], + # 01234567890123456789012345678901234567890123456789012345 + # 1 2 3 4 5 + args => "--bwa-sw-like -L 18", + hits => [{ 3 => 1 }], + # Tot matches = 54 + # Tot penalties = 6 + samoptflags => [{ "AS:i:48" => 1, "NM:i:2" => 1, "XM:i:2" => 1, + "MD:Z:26A0A28" => 1, "YT:Z:UU" => 1 }] + }, + { name => "BWA-SW-like 3", + # 0123 + ref => [ "GTTTAGATTCCACTACGCTAACCATCGAGAACTCGTCTCAGAGTTTCGATAGGAAAATCTGCGA" ], + # |||||||||||||||||||||||||| ||||||||||||||||||||||||||| + reads => [ "TAGATTCCACTACGCTAACCATCGAG"."TCGTCTCAGAGTTTCGATAGGAAAATC" ], + # 01234567890123456789012345678901234567890123456789012345 + # 1 2 3 4 5 + args => "--bwa-sw-like -i C,1,0", + hits => [{ 3 => 1 }], + # Tot matches = 53 + # Tot penalties = 11 + samoptflags => [{ "AS:i:42" => 1, "NM:i:3" => 1, "XM:i:0" => 1, + "XO:i:1" => 1, "XG:i:3" => 1, + "MD:Z:26^AAC27" => 1, "YT:Z:UU" => 1 }] + }, + + # Some tricky SAM FLAGS field tests + + { name => "SAM paired-end where both mates align 1", + ref => [ "GCACTATCTACGCTTCGGCGTCGGCGAAAAAACGCACGACCGGGTGTGTGACAATCATATATAGCGCGC" ], + # 012345678901234567890123456789012345678901234567890123456789012345678 + # 0 1 2 3 4 5 6 + mate1s => [ "CTATCTACGCTTCGGCGTCGGTGA" ], + mate2s => [ "GATTGTCACACACCCGGTCGT" ], + # ----------------------------------------------------- + # 01234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 + # 0x1 template having multiple fragments in sequencing + # 0x2 each fragment properly aligned according to the aligner + # 0x4 fragment unmapped + # 0x8 next fragment in the template unmapped + # 0x10 SEQ being reverse complemented + # 0x20 SEQ of the next fragment in the template being reversed + # 0x40 the first fragment in the template + # 0x80 the last fragment in the template + pairhits => [{ "3,35" => 1 }], + norc => 1, + samflags_map => [{ 3 => (1 | 2 | 32 | 64), 35 => (1 | 2 | 16 | 128) }], + tlen_map => [{ 3 => 53, 35 => -53 }] }, + + { name => "SAM paired-end where both mates align 2", + ref => [ "GCACTATCTACGCTTCGGCGTCGGCGAAAAAACGCACGACCGGGTGTGTGACAATCATATATAGCGCGC" ], + # 012345678901234567890123456789012345678901234567890123456789012345678 + # 0 1 2 3 4 5 6 + mate1s => [ "TCACCGACGCCGAAGCGTAGATAG" ], + mate2s => [ "ACGACCGGGTGTGTGACAATC" ], + # ----------------------------------------------------- + # 01234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 + # 0x1 template having multiple fragments in sequencing + # 0x2 each fragment properly aligned according to the aligner + # 0x4 fragment unmapped + # 0x8 next fragment in the template unmapped + # 0x10 SEQ being reverse complemented + # 0x20 SEQ of the next fragment in the template being reversed + # 0x40 the first fragment in the template + # 0x80 the last fragment in the template + mate1fw => 0, + mate2fw => 1, + pairhits => [{ "3,35" => 1 }], + norc => 1, + samflags_map => [{ 3 => (1 | 2 | 16 | 64), 35 => (1 | 2 | 32 | 128) }], + tlen_map => [{ 3 => 53, 35 => -53 }] }, + + { name => "SAM paired-end where both mates align 3", + ref => [ "GCACTATCTACGCTTCGGCGTCGGCGAAAAAACGCACGACCGGGTGTGTGACAATCATATATAGCGCGC" ], + # 012345678901234567890123456789012345678901234567890123456789012345678 + # 0 1 2 3 4 5 6 + mate1s => [ "CTATCTACGCTTCGGCGTCGGTGA" ], + mate2s => [ "ACGACCGGGTGTGTGACAATC" ], + # ----------------------------------------------------- + # 01234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 + # 0x1 template having multiple fragments in sequencing + # 0x2 each fragment properly aligned according to the aligner + # 0x4 fragment unmapped + # 0x8 next fragment in the template unmapped + # 0x10 SEQ being reverse complemented + # 0x20 SEQ of the next fragment in the template being reversed + # 0x40 the first fragment in the template + # 0x80 the last fragment in the template + mate1fw => 1, + mate2fw => 1, + pairhits => [{ "3,35" => 1 }], + norc => 1, + samflags_map => [{ 3 => (1 | 2 | 64), 35 => (1 | 2 | 128) }], + tlen_map => [{ 3 => 53, 35 => -53 }] }, + + { name => "SAM paired-end where mate #1 aligns but mate #2 doesn't", + ref => [ "GCACTATCTACGCTTCGGCGTCGGCGAAAAAACGCACGACCGGGTGTGTGACAATCATATATAGCGCGC" ], + # 012345678901234567890123456789012345678901234567890123456789012345678 + # 0 1 2 3 4 5 6 + mate1s => [ "CTATCTACGCTTCGGCGTCGGCGA" ], + mate2s => [ "GATTGTCTTTTCCCGGAAAAATCGT" ], + # 0x1 template having multiple fragments in sequencing + # 0x2 each fragment properly aligned according to the aligner + # 0x4 fragment unmapped + # 0x8 next fragment in the template unmapped + # 0x10 SEQ being reverse complemented + # 0x20 SEQ of the next fragment in the template being reversed + # 0x40 the first fragment in the template + # 0x80 the last fragment in the template + pairhits => [{ "*,3" => 1 }], + norc => 1, + samflags_map => [{ 3 => (1 | 8 | 64), "*" => (1 | 4 | 128) }] }, + + { name => "SAM paired-end where neither mate aligns", + ref => [ "GCACTATCTACGCTTCGGCGTCGGCGAAAAAACGCACGACCGGGTGTGTGACAATCATATATAGCGCGC" ], + # 012345678901234567890123456789012345678901234567890123456789012345678 + # 0 1 2 3 4 5 6 + mate1s => [ "CTATATACGAAAAAGCGTCGGCGA" ], + mate2s => [ "GATTGTCTTTTCCCGGAAAAATCGT" ], + # 0x1 template having multiple fragments in sequencing + # 0x2 each fragment properly aligned according to the aligner + # 0x4 fragment unmapped + # 0x8 next fragment in the template unmapped + # 0x10 SEQ being reverse complemented + # 0x20 SEQ of the next fragment in the template being reversed + # 0x40 the first fragment in the template + # 0x80 the last fragment in the template + pairhits => [{ "*,*" => 1 }], + norc => 1, + samoptflags_flagmap => [{ + (1 | 4 | 8 | 64) => { "YT:Z:UP" => 1 }, + (1 | 4 | 8 | 128) => { "YT:Z:UP" => 1 } + }] }, + + { name => "SAM paired-end where both mates align, but discordantly", + ref => [ "GCACTATCTACGCTTCGGCGTCGGCGAAAAAACGCACGACCGGGTGTGTGACAATCATATATAGCGCGC" ], + # 012345678901234567890123456789012345678901234567890123456789012345678 + # 0 1 2 3 4 5 6 + mate1s => [ "CTATCTACGCTTCGGCGTCGGCGA" ], + mate2s => [ "ACGACCGGGTGTGTGACAATC" ], + # ----------------------------------------------------- + # 01234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 + # 0x1 template having multiple fragments in sequencing + # 0x2 each fragment properly aligned according to the aligner + # 0x4 fragment unmapped + # 0x8 next fragment in the template unmapped + # 0x10 SEQ being reverse complemented + # 0x20 SEQ of the next fragment in the template being reversed + # 0x40 the first fragment in the template + # 0x80 the last fragment in the template + pairhits => [{ "3,35" => 1 }], + norc => 1, + samflags_map => [{ 3 => (1 | 64), 35 => (1 | 128) }], + # Which TLEN is right? Depends on criteria for when to infer TLEN. If + # criterion is mates are concordant, then it should be 0 here. If the + # criterion is that both mates align to the same chromosome, should be + # +-53 + #tlen_map => [{ 3 => 0, 35 => 0 }] }, + tlen_map => [{ 3 => 53, 35 => -53 }] }, + + { name => "matchesRef regression 4", + ref => [ "CCGGGTCGTCACGCCCCGCTTGCGTCANGCCCCTCACCCTCCCTTTGTCGGCTCCCACCCCTCCCCATCCGTTGTCCCCGCCCCCGCCCGCCGGGTCGTCACGCCCCGCTTGCGTCANGC", + "GCTCGGAATTCGTGCTCCGNCCCGTACGGTT" ], + # + # NNNNNGA------A-------------------G-NTTT + # |||||||||||||||||||||||||||||||||| + # CCAAT-ATTTTTAATTTCCTCTATTTTTCTCTCGTCTTG + args => "--policy \"NP=Q\\;RDG=46.3220993654702\\;RFG=41.3796024365659\\;MIN=L,5.57015383125426,-3.28597145122829\\;NCEIL=L,0.263054599454459,0.130843661549367\\;SEED=1,29\\;IVAL=L,0.0169183264663712,3.75762168662522\" --overhang --trim5 6", + reads => [ "CTTTGCACCCCTCCCTTGTCGGCTCCCACCCATCCCCATCCGTTGTCCCCGCCCCCGCCCGCCGGTCGTCACTCCCCGTTTGCGTCATGCCCCTCACCCTCCCTTTGTCGGCTCGCACCCCTCCCCATCCGTTGTCCCCGCCCCCGCTCTCGGGGTCTTCACGCCCCGCTTGCTTCATGCCCCTCACTCGCACCCCG" ], + }, + + { name => "matchesRef regression 3", + ref => [ "GAAGNTTTTCCAATATTTTTAATTTCCTCTATTTTTCTCTCGTCTTGNTCTAC" ], + # + # NNNNNGA------A-------------------G-NTTT + # |||||||||||||||||||||||||||||||||| + # CCAAT-ATTTTTAATTTCCTCTATTTTTCTCTCGTCTTG + args => "--policy \"MMP=R\\;MIN=L,8.8,-8.1\" --overhang", + reads => [ "CAAGACGAGAGAAAAATAGAGGAAATTAAAAATATTGG" ], + }, + + { name => "matchesRef regression 2", + ref => ["GTTGTCGGCAGCTCTGGATATGTGNTCTCGGGTTTATNTCGTTGTCG", + "CCTTGTTNTTAATGCTGCCTGGTTTNG"], + args => "--policy \"RDG=2.02030755427021,2.81949533273331\\;MIN=L,-6.52134769703939,-3.39889659588514\\;IVAL=L,0.127835912101927\" --overhang --trim5 5", + mate1s => ["TCTGGCGGTTGCGAAGGCCCCTGGCGGTTGCTATGTCCTCTGGCGGTTGCGTTGTCGGCAGCTCG"], + mate2s => ["AGAACACATATCCAGAGCTGCCGACAACGAAATGAACCCGAGAGCACAAATCCAGAG"] }, + + # Regression test for an issue observed once + { name => "matchesRef regression 1", + # 0 1 2 3 4 5 6 7 + # 01234567890123456789012345678901234567890123456789012345678901234567890 + ref => [ "AGGTCGACCGAAAGGCCTAGAGGTCGACCGACAATCTGACCATGGGGCGAGGAGCGAGTAC" ], + # |||||||||||||||||||||||||||||||||||||||||||||||||| + reads => [ "AAGGCCTAGAGGTCGACCGACAATCTGACCATGGGGCGAGGAGCGAGTACTGGTCTGGGG" ], + # 012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 + args => "--overhang" }, + + # 1 discordant alignment and one concordant alignment. Discordant because + # the fragment is too long. + + { name => "Discordant with different chromosomes", + ref => [ "TTTATAAAAATATTTCCCCCCCC", + "CCCCCCTGTCGCTACCGCCCCCCCCCCC" ], + # ATAAAAATAT GTCGCTACCG + # ATAAAAATAT TGTCGCTACC + # 01234567890123456789012 + # 0 1 2 + # 0123456789012345678901234567 + # 0 1 2 + mate1s => [ "ATAAAAATAT", "ATAAAAATAT" ], + mate2s => [ "GTCGCTACCG", "TGTCGCTACC" ], + mate1fw => 1, + mate2fw => 1, + args => "-I 0 -X 35", + # Not really any way to flag an alignment as discordant + pairhits => [ { "3,7" => 1 }, { "3,6" => 1 } ], + rnext_map => [ { 3 => 1, 7 => 0 }, { 3 => 1, 6 => 0 } ], + pnext_map => [ { 3 => 7, 7 => 3 }, { 3 => 6, 6 => 3 } ] }, + + { name => "Fastq 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\@r0\nCATCGATCAGTATCTG\n+\nIIIIIIIIIIIIIIII", + hits => [{ 2 => 1 }] }, + + { name => "Tabbed 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "r0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII", + hits => [{ 2 => 1 }] }, + + { name => "Fasta 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => ">r0\nCATCGATCAGTATCTG", + hits => [{ 2 => 1 }] }, + + { name => "Qseq 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "X", "Y", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1"), + hits => [{ 2 => 1 }] }, + + { name => "Raw 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + raw => "CATCGATCAGTATCTG", + hits => [{ 2 => 1 }] }, + + # Like Fastq 1 but with extra newline + { name => "Fastq 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\@r0\nCATCGATCAGTATCTG\n+\nIIIIIIIIIIIIIIII\n", + hits => [{ 2 => 1 }] }, + + { name => "Tabbed 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "r0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n", + hits => [{ 2 => 1 }] }, + + { name => "Fasta 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => ">r0\nCATCGATCAGTATCTG\n", + hits => [{ 2 => 1 }] }, + + { name => "Qseq 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "X", "Y", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n", + hits => [{ 2 => 1 }] }, + + { name => "Raw 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + raw => "CATCGATCAGTATCTG\n", + hits => [{ 2 => 1 }] }, + + # Like Fastq 1 but with many extra newlines + { name => "Fastq 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }] }, + + { name => "Tabbed 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }] }, + + { name => "Fasta 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => "\n\n\r\n>r0\nCATCGATCAGTATCTG\r\n\n", + hits => [{ 2 => 1 }] }, + + { name => "Qseq 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "X", "Y", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n\n", + hits => [{ 2 => 1 }] }, + + { name => "Raw 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + raw => "\n\n\nCATCGATCAGTATCTG\n\n", + hits => [{ 2 => 1 }] }, + + # Quality string length doesn't match (too short by 1) + { name => "Fastq 4", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIII\n\n", + should_abort => 1}, + + { name => "Tabbed 4", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIII\n\n", + should_abort => 1}, + + { name => "Qseq 4", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "X", "Y", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIII", + "1")."\n\n", + should_abort => 1}, + + # Name line doesn't start with @ + { name => "Fastq 5", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\n\n\r\nr0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIII\n\n", + should_abort => 1, + hits => [{ }] }, + + # Name line doesn't start with > + { name => "Fasta 5", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => "\n\n\r\nr0\nCATCGATCAGTATCTG\r", + should_abort => 1, + hits => [{ }] }, + + # Name line doesn't start with @ (2) + { name => "Fastq 6", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIII\n\n", + should_abort => 1, + hits => [{ }] }, + + # Name line doesn't start with > (2) + { name => "Fasta 6", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => "r0\nCATCGATCAGTATCTG\r", + should_abort => 1, + hits => [{ }] }, + + # Part of sequence is trimmed + { name => "Fastq 7", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIIII\n\n", + args => "--trim3 4", + norc => 1, + hits => [{ 2 => 1 }] }, + + { name => "Tabbed 7", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n\n", + args => "--trim3 4", + norc => 1, + hits => [{ 2 => 1 }] }, + + { name => "Fasta 7", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => "\n\n\r\n\>r0\nCATCGATCAGTATCTG\r\n", + args => "--trim3 4", + norc => 1, + hits => [{ 2 => 1 }] }, + + { name => "Qseq 7", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "X", "Y", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n\n", + args => "--trim3 4", + norc => 1, + hits => [{ 2 => 1 }] }, + + { name => "Raw 7", + ref => [ "AGCATCGATCAGTATCTGA" ], + raw => "\n\n\r\nCATCGATCAGTATCTG\r\n", + args => "--trim3 4", + norc => 1, + hits => [{ 2 => 1 }] }, + + # Whole sequence is trimmed + { name => "Fastq 8", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIIII\n\n", + args => "--trim5 16", + hits => [{ "*" => 1 }] }, + + { name => "Tabbed 8", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n\n", + args => "--trim5 16", + hits => [{ "*" => 1 }] }, + + { name => "Fasta 8", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => "\n\n\r\n\>r0\nCATCGATCAGTATCTG\r\n", + args => "--trim3 16", + hits => [{ "*" => 1 }] }, + + { name => "Qseq 8", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "X", "Y", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n\n", + args => "--trim3 16", + hits => [{ "*" => 1 }] }, + + { name => "Raw 8", + ref => [ "AGCATCGATCAGTATCTGA" ], + raw => "\n\n\r\nCATCGATCAGTATCTG\r\n", + args => "--trim3 16", + hits => [{ "*" => 1 }] }, + + # Sequence is skipped + { name => "Fastq 9", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIIII\n\n", + args => "-s 1", + hits => [{ }] }, + + { name => "Tabbed 9", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n\n", + args => "-s 1", + hits => [{ }] }, + + { name => "Fasta 9", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => "\n\n\r\n>r0\nCATCGATCAGTATCTG\r\n", + args => "-s 1", + hits => [{ }] }, + + { name => "Qseq 9", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "X", "Y", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n\n", + args => "-s 1", + hits => [{ }] }, + + { name => "Raw 9", + ref => [ "AGCATCGATCAGTATCTGA" ], + raw => "CATCGATCAGTATCTG\n", + args => "-s 1", + hits => [{ }] }, + + # Like Fastq 1 but with many extra newlines + { name => "Fastq multiread 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIIII\n\n". + "\n\n\r\n\@r1\nATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Tabbed multiread 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n\n". + "\n\n\r\nr1\tATCGATCAGTATCTG\tIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Fasta multiread 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + fasta => "\n\n\r\n>r0\nCATCGATCAGTATCTG\n\n". + "\n\n\r\n>r1\nATCGATCAGTATCTG\n\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Qseq multiread 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "10", "10", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n\n". + join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "12", "15", + "Index", + "0", # Mate + "ATCGATCAGTATCTG", + "IIIIIIIIIIIIIII", + "1")."\n\n", + idx_map => { "MachName_RunNum_Lane_Tile_10_10_Index" => 0, + "MachName_RunNum_Lane_Tile_12_15_Index" => 1 }, + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Raw multiread 1", + ref => [ "AGCATCGATCAGTATCTGA" ], + raw => "\n\n\r\nCATCGATCAGTATCTG\n\n". + "\n\n\r\nATCGATCAGTATCTG\n\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + # Like Fastq multiread 1 but with -u 1 + { name => "Fastq multiread 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 1", + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIIII\n\n". + "\n\n\r\n\@r1\nATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }] }, + + { name => "Tabbed multiread 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 1", + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n\n". + "\n\n\r\nr1\tATCGATCAGTATCTG\tIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }] }, + + { name => "Fasta multiread 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 1", + fasta => "\n\n\r\n>r0\nCATCGATCAGTATCTG\r\n". + "\n\n\r\n>r1\nATCGATCAGTATCTG\r\n", + hits => [{ 2 => 1 }] }, + + { name => "Qseq multiread 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 1", + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "10", "10", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n\n". + join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "12", "15", + "Index", + "0", # Mate + "ATCGATCAGTATCTG", + "IIIIIIIIIIIIIII", + "1")."\n\n", + idx_map => { "MachName_RunNum_Lane_Tile_10_10_Index" => 0, + "MachName_RunNum_Lane_Tile_12_15_Index" => 1 }, + hits => [{ 2 => 1 }] }, + + { name => "Raw multiread 2", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 1", + raw => "\n\n\r\nCATCGATCAGTATCTG\r\n". + "\n\n\r\nATCGATCAGTATCTG\r\n", + hits => [{ 2 => 1 }] }, + + # Like Fastq multiread 1 but with -u 2 + { name => "Fastq multiread 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 2", + fastq => "\n\n\r\n\@r0\nCATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIIII\n\n". + "\n\n\r\n\@r1\nATCGATCAGTATCTG\r\n+\n\nIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Tabbed multiread 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 2", + tabbed => "\n\n\r\nr0\tCATCGATCAGTATCTG\tIIIIIIIIIIIIIIII\n\n". + "\n\n\r\nr1\tATCGATCAGTATCTG\tIIIIIIIIIIIIIII\n\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Fasta multiread 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 2", + fasta => "\n\n\r\n>r0\nCATCGATCAGTATCTG\r\n". + "\n\n\r\n>r1\nATCGATCAGTATCTG\r\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Qseq multiread 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 2", + qseq => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "10", "10", + "Index", + "0", # Mate + "CATCGATCAGTATCTG", + "IIIIIIIIIIIIIIII", + "1")."\n\n". + join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "12", "15", + "Index", + "0", # Mate + "ATCGATCAGTATCTG", + "IIIIIIIIIIIIIII", + "1")."\n\n", + idx_map => { "MachName_RunNum_Lane_Tile_10_10_Index" => 0, + "MachName_RunNum_Lane_Tile_12_15_Index" => 1 }, + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + { name => "Raw multiread 3", + ref => [ "AGCATCGATCAGTATCTGA" ], + args => "-u 2", + raw => "\n\n\r\nCATCGATCAGTATCTG\r\n". + "\n\n\r\nATCGATCAGTATCTG\r\n", + hits => [{ 2 => 1 }, { 3 => 1 }] }, + + # Paired-end reads that should align + { name => "Fastq paired 1", + ref => [ "AGCATCGATCAAAAACTGA" ], + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + fastq1 => "\n\n\r\n\@r0\nAGCATCGATC\r\n+\n\nIIIIIIIIII\n\n". + "\n\n\@r1\nTCAGTTTTTGA\r\n+\n\nIIIIIIIIIII\n\n", + fastq2 => "\n\n\r\n\@r0\nTCAGTTTTTGA\n+\n\nIIIIIIIIIII\n\n". + "\n\n\r\n\@r1\nAGCATCGATC\r\n+\n\nIIIIIIIIII", + pairhits => [ { "0,8" => 1 }, { "0,8" => 1 } ] }, + + { name => "Tabbed paired 1", + ref => [ "AGCATCGATCAAAAACTGA" ], + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + tabbed => "\n\n\r\nr0\tAGCATCGATC\tIIIIIIIIII\tTCAGTTTTTGA\tIIIIIIIIIII\n\n". + "\n\nr1\tTCAGTTTTTGA\tIIIIIIIIIII\tAGCATCGATC\tIIIIIIIIII\n\n", + paired => 1, + pairhits => [ { "0,8" => 1 }, { "0,8" => 1 } ] }, + + { name => "Fasta paired 1", + ref => [ "AGCATCGATCAAAAACTGA" ], + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + fasta1 => "\n\n\r\n>r0\nAGCATCGATC\r\n". + "\n\n>r1\nTCAGTTTTTGA\r\n", + fasta2 => "\n\n\r\n>r0\nTCAGTTTTTGA\n". + "\n\n\r\n>r1\nAGCATCGATC", + pairhits => [ { "0,8" => 1 }, { "0,8" => 1 } ] }, + + { name => "Qseq paired 1", + ref => [ "AGCATCGATCAAAAACTGA" ], + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + qseq1 => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "10", "10", + "Index", + "1", # Mate + "AGCATCGATC", + "ABCBGACBCB", + "1")."\n\n". + join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "12", "15", + "Index", + "1", # Mate + "TCAGTTTTTGA", + "95849456875", + "1")."\n\n", + qseq2 => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "10", "10", + "Index", + "2", # Mate + "TCAGTTTTTGA", + "ABCBGACBCBA", + "1")."\n\n". + join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "12", "15", + "Index", + "2", # Mate + "AGCATCGATC", + "AGGCBBGCBG", + "1")."\n\n", + idx_map => { "MachName_RunNum_Lane_Tile_10_10_Index" => 0, + "MachName_RunNum_Lane_Tile_12_15_Index" => 1 }, + pairhits => [ { "0,8" => 1 }, { "0,8" => 1 } ] }, + + { name => "Raw paired 1", + ref => [ "AGCATCGATCAAAAACTGA" ], + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + raw1 => "\n\n\r\nAGCATCGATC\r\n". + "\n\nTCAGTTTTTGA\r\n", + raw2 => "\n\n\r\nTCAGTTTTTGA\n". + "\n\n\r\nAGCATCGATC", + pairhits => [ { "0,8" => 1 }, { "0,8" => 1 } ] }, + + # Paired-end reads that should align + { name => "Fastq paired 2", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-s 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + fastq1 => "\@r0\nAGCATCGATC\r\n+\n\nIIIIIIIIII\n\n". + "\n\n\@r1\nTCAGTTTTTGA\n+\n\nIIIIIIIIIII\n\n", + fastq2 => "\n\n\r\n\@r0\nTCAGTTTTTGA\n+\n\nIIIIIIIIIII\n\n". + "\n\n\r\n\@r1\nAGCATCGATC\r\n+\n\nIIIIIIIIII", + pairhits => [ { }, { "0,8" => 1 } ] }, + + { name => "Tabbed paired 2", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-s 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + tabbed => "r0\tAGCATCGATC\tIIIIIIIIII\tTCAGTTTTTGA\tIIIIIIIIIII\n\n". + "\nr1\tTCAGTTTTTGA\tIIIIIIIIIII\tAGCATCGATC\tIIIIIIIIII", + paired => 1, + pairhits => [ { }, { "0,8" => 1 } ] }, + + { name => "Fasta paired 2", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-s 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + fasta1 => ">r0\nAGCATCGATC\r\n". + "\n\n>r1\nTCAGTTTTTGA\n", + fasta2 => "\n\n\r\n>r0\nTCAGTTTTTGA\n". + "\n\n\r\n>r1\nAGCATCGATC", + pairhits => [ { }, { "0,8" => 1 } ] }, + + { name => "Qseq paired 1", + ref => [ "AGCATCGATCAAAAACTGA" ], + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + args => "-s 1", + qseq1 => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "10", "10", + "Index", + "1", # Mate + "AGCATCGATC", + "ABCBGACBCB", + "1")."\n\n". + join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "12", "15", + "Index", + "1", # Mate + "TCAGTTTTTGA", + "95849456875", + "1")."\n\n", + qseq2 => "\n\n\n".join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "10", "10", + "Index", + "2", # Mate + "TCAGTTTTTGA", + "ABCBGACBCBA", + "1")."\n\n". + join("\t", "MachName", + "RunNum", + "Lane", + "Tile", + "12", "15", + "Index", + "2", # Mate + "AGCATCGATC", + "AGGCBBGCBG", + "1")."\n\n", + idx_map => { "MachName_RunNum_Lane_Tile_10_10_Index" => 0, + "MachName_RunNum_Lane_Tile_12_15_Index" => 1 }, + pairhits => [ { }, { "0,8" => 1 } ] }, + + { name => "Raw paired 2", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-s 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + raw1 => "AGCATCGATC\r\n". + "\n\nTCAGTTTTTGA\n", + raw2 => "\n\n\r\nTCAGTTTTTGA\n". + "\n\n\r\nAGCATCGATC", + pairhits => [ { }, { "0,8" => 1 } ] }, + + # Paired-end reads that should align + { name => "Fastq paired 3", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-u 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + fastq1 => "\n\n\r\n\@r0\nAGCATCGATC\r\n+\n\nIIIIIIIIII\n\n". + "\n\n\@r1\nTCAGTTTTTGA\r\n+\n\nIIIIIIIIIII\n\n", + fastq2 => "\n\n\r\n\@r0\nTCAGTTTTTGA\n+\n\nIIIIIIIIIII\n\n". + "\n\n\r\n\@r1\nAGCATCGATC\r\n+\nIIIIIIIIII", + pairhits => [ { "0,8" => 1 }, { } ] }, + + { name => "Tabbed paired 3", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-u 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + tabbed => "\n\n\r\nr0\tAGCATCGATC\tIIIIIIIIII\tTCAGTTTTTGA\tIIIIIIIIIII\n\n". + "\n\nr1\tTCAGTTTTTGA\tIIIIIIIIIII\tAGCATCGATC\tIIIIIIIIII", + paired => 1, + pairhits => [ { "0,8" => 1 }, { } ] }, + + { name => "Fasta paired 3", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-u 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + fasta1 => "\n\n\r\n>r0\nAGCATCGATC\r\n". + "\n\n>r1\nTCAGTTTTTGA\r\n", + fasta2 => "\n\n\r\n>r0\nTCAGTTTTTGA\n". + "\n\n\r\n>r1\nAGCATCGATC", + pairhits => [ { "0,8" => 1 }, { } ] }, + + { name => "Raw paired 3", + ref => [ "AGCATCGATCAAAAACTGA" ], + args => "-u 1", + # AGCATCGATC + # TCAAAAACTGA + # 0123456789012345678 + raw1 => "\n\n\r\nAGCATCGATC\r\n". + "\n\nTCAGTTTTTGA\r\n", + raw2 => "\n\n\r\nTCAGTTTTTGA\n". + "\n\n\r\nAGCATCGATC", + pairhits => [ { "0,8" => 1 }, { } ] }, + + # Paired-end reads that should align + #{ name => "Fastq paired 4", + # ref => [ "AGCATCGATCAAAAACTGA" ], + # args => "-s 1 -L 4 -i C,1,0", + # # AGCATCGATC + # # TCAAAAACTGA + # # 0123456789012345678 + # fastq1 => "\n\n\r\n\@r0\nAGCATCGATC\r\n+\n\nIIIIIIIIII\n\n". + # #"\n\n\@r1\nTC\r\n+\n\nII\n\n". + # "\n\n\@r2\nTCAGTTTTTGA\r\n+\n\nIIIIIIIIIII\n\n", + # fastq2 => "\n\n\r\n\@r0\nTCAGTTTTTGA\n+\n\nIIIIIIIIIII\n\n". + # #"\n\n\r\n\@r1\nAG\r\n+\nII". + # "\n\@r2\nAGCATCGATC\r\n+\nIIIIIIIIII", + # paired => 1, + # pairhits => [ { }, { "*,*" => 1 }, { "0,8" => 1 } ], + # pairhits => [ { "0,8" => 1 } ], + # samoptflags_map => [ + # { }, + # { "*" => { "YT:Z:UP" => 1, "YF:Z:LN" => 1 } }, + ## { 0 => { "MD:Z:10" => 1, "YT:Z:CP" => 1 }, + # 8 => { "MD:Z:11" => 1, "YT:Z:CP" => 1 } }] + #}, + + #{ name => "Tabbed paired 4", + # ref => [ "AGCATCGATCAAAAACTGA" ], + # args => "-s 1 -L 4 -i C,1,0", + # # AGCATCGATC + # # TCAAAAACTGA + # # 0123456789012345678 + # tabbed => "\n\n\r\nr0\tAGCATCGATC\tIIIIIIIIII\tTCAGTTTTTGA\tIIIIIIIIIII\n\n". + # "\n\nr1\tTC\tII\tAG\tII". + # "\n\nr2\tTCAGTTTTTGA\tIIIIIIIIIII\tAGCATCGATC\tIIIIIIIIII\n\n", + # paired => 1, + # #pairhits => [ { }, { "*,*" => 1 }, { "0,8" => 1 } ], + # pairhits => [ { }, { "0,8" => 1 } ], + # samoptflags_map => [ + # { }, + # #{ "*" => { "YT:Z:UP" => 1, "YF:Z:LN" => 1 } }, + # { 0 => { "MD:Z:10" => 1, "YT:Z:CP" => 1 }, +# 8 => { "MD:Z:11" => 1, "YT:Z:CP" => 1 } }] + #}, + + #{ name => "Fasta paired 4", + # ref => [ "AGCATCGATCAAAAACTGA" ], + # args => "-s 1 -L 4 -i C,1,0", + # # AGCATCGATC + # # TCAAAAACTGA + # # 0123456789012345678 + # fasta1 => "\n\n\r\n>r0\nAGCATCGATC\r\n". + # # "\n\n>r1\nTC\r\n". + # "\n\n>r2\nTCAGTTTTTGA\r\n", + # fasta2 => "\n\n\r\n>r0\nTCAGTTTTTGA\n\n". + # # "\n\n\r\n>r1\nAG". + # "\n>r2\nAGCATCGATC", + # # pairhits => [ { }, { "*,*" => 1 }, { "0,8" => 1 } ], + # pairhits => [ { }, { "0,8" => 1 } ], + # samoptflags_map => [ + # { }, + # #{ "*" => { "YT:Z:UP" => 1, "YF:Z:LN" => 1 } }, + # { 0 => { "MD:Z:10" => 1, "YT:Z:CP" => 1 }, + # 8 => { "MD:Z:11" => 1, "YT:Z:CP" => 1 } }] + #}, + + #{ name => "Raw paired 4", + # ref => [ "AGCATCGATCAAAAACTGA" ], + # args => "-s 1 -L 4 -i C,1,0", + # # AGCATCGATC + # # TCAAAAACTGA + # # 0123456789012345678 + # raw1 => "\n\n\r\nAGCATCGATC\r\n". + ## "\n\nTC\r\n". + # "\n\nTCAGTTTTTGA\r\n", + # raw2 => "\n\n\r\nTCAGTTTTTGA\n\n". + # "\n\n\r\nAG". + # "\nAGCATCGATC", + # pairhits => [ { }, { "*,*" => 1 }, { "0,8" => 1 } ], + # pairhits => [ { }, { "0,8" => 1 } ], + # samoptflags_map => [ + # { }, + # { "*" => { "YT:Z:UP" => 1, "YF:Z:LN" => 1 } }, + # { 0 => { "MD:Z:10" => 1, "YT:Z:CP" => 1 }, +# 8 => { "MD:Z:11" => 1, "YT:Z:CP" => 1 } }] + #}, + + # + # Check that skipping of empty reads is handled correctly. A read that is + # empty or becomes empty after --trim3/--trim5 are applied should still + # count as a first-class read that gets propagated up into the alignment + # loop. And it should be counted in the -s/-u totals. + # + + { ref => [ "AGCATCGATCAGTATCTGA" ], + reads => [ "", "ATCGATCAGTA" ], + args => "-s 1", + hits => [ {}, { 3 => 1 }] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + mate1s => [ "", "AGCATCGATC" ], + mate2s => [ "", "TCAGATACTG" ], + args => "-s 1", + pairhits => [ {}, { "0,9" => 1 }] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + reads => [ "", "ATCGATCAGTA" ], + args => "-s 2", + hits => [ {}, {} ] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + mate1s => [ "", "AGCATCGATC" ], + mate2s => [ "", "TCAGATACTG" ], + args => "-s 2", + pairhits => [ {}, {} ] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + reads => [ "", "ATCGATCAGTA", "AGTATCTGA" ], + args => "-s 1 -u 1", + hits => [ {}, { 3 => 1 }] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + reads => [ "AC", "ATCGATCAGTA" ], + args => "-s 1 --trim3 2", + norc => 1, + hits => [ {}, { 3 => 1 }] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + reads => [ "AC", "ATCGATCAGTA" ], + args => "-s 1 --trim3 2", + nofw => 1, + hits => [ {}, { 5 => 1 }] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + reads => [ "AC", "ATCGATCAGTA" ], + args => "-s 1 --trim5 2", + nofw => 1, + hits => [ {}, { 3 => 1 }] }, + + { ref => [ "AGCATCGATCAGTATCTGA" ], + reads => [ "AC", "ATCGATCAGTA" ], + args => "-s 1 --trim5 2", + norc => 1, + hits => [ {}, { 5 => 1 }] }, + + # + # Alignment with overhang + # + + { ref => [ "TGC" ], + reads => [ "ATGC" ], + args => "--overhang --policy \"SEED=0,3\\;IVAL=C,1,0\\;NCEIL=L,1,0\"", + hits => [ { 0 => 1 } ], + cigar => [ "1S3M" ], + samoptflags => [ + { "AS:i:-1" => 1, "YT:Z:UU" => 1, "MD:Z:3" => 1, "XN:i:1" => 1 } ] + }, + + { ref => [ "TTGTTCGT" ], + reads => [ "TTGTTCG" ], + args => "--policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,2,0\"", + hits => [ { 0 => 1 } ], + cigar => [ "7M" ], + samoptflags => [ { "AS:i:0" => 1, "YT:Z:UU" => 1, "MD:Z:7" => 1 } ] + }, + + { ref => [ "TTGTTCGT" ], + reads => [ "TTGTTCG" ], + args => "", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:7=" ], + cigar => [ "7M" ], + samoptflags => [ { "AS:i:0" => 1, "YT:Z:UU" => 1, "MD:Z:7" => 1 } ] + }, + + { ref => [ "TTGTTCGT" ], + reads => [ "TGTTCGT", "TTGTTCG" ], + args => "--overhang", + hits => [ { 1 => 1 }, { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:7=", "XM:0,XP:0,XT:UU,XC:7=" ], + cigar => [ "7M", "7M" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:7" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:7" => 1 } + ] + }, + + { ref => [ "TTGTTCGT" ], + reads => [ "TGTTCGT", "TTGTTCG" ], + args => "", + hits => [ { 1 => 1 }, { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:7=", "XM:0,XP:0,XT:UU,XC:7=" ], + cigar => [ "7M", "7M" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:7" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:7" => 1 } + ] + }, + + # Reads 1 and 2 don't have overhang, reads 3 and 4 overhang opposite ends + { ref => [ "TTGTTCGT" ], + # TGTTCGT + # GTTCGTA + # ATTGTTC + reads => [ "TGTTCGT", "GTTCGTA", "ATTGTTC" ], + args => "--overhang --policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,2,0\"", + hits => [ { 1 => 1 }, { 2 => 1 }, { 0 => 1 } ], + cigar => [ "7M", "6M1S", "1S6M" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:7" => 1 }, + { "AS:i:-1" => 1, "XN:i:1" => 1, "YT:Z:UU" => 1, "MD:Z:6" => 1 }, + { "AS:i:-1" => 1, "XN:i:1" => 1, "YT:Z:UU" => 1, "MD:Z:6" => 1 } + ]}, + + # Same as previous case but --overhang not specified + { ref => [ "TTGTTCGT" ], + reads => [ "TGTTCGT", "TTGTTCG", "GTTCGTA", "ATTGTTC" ], + args => "--policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,2,0\"", + hits => [ { 1 => 1 }, { 0 => 1 } ], # only the internal hits + cigar => [ "7M", "7M", "*", "*" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:7" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:7" => 1 }, + { "YT:Z:UU" => 1 }, + { "YT:Z:UU" => 1 } + ] + }, + + # A simple case that should align with or without overhang, with or without + # a special NCEIL setting. + { ref => [ "TTGTTCGT" ], + reads => [ "TTGTTCG" ], + args => "--overhang --policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,2,0\"", + hits => [ { 0 => 1 } ]}, + + { ref => [ "TTGTTCGT" ], + reads => [ "TTGTTCG" ], + args => "--overhang", + hits => [ { 0 => 1 } ]}, + + # + # Testing the various -M/-m/-k/-a alignment modes in both unpaired and + # paired-end modes. Ensuring that SAM optional flags such as YM:i, YP:i + # are set properly in all cases. + # + + # + # Paired-end + # + + { name => "P.M.58.G.b Unpaired -M 5 w/ 8 hits global, but mate #1 has just 1", + # 0 1 2 3 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGT" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 + # 0 1 2 3 4 5 6 7 8 9 + # 0 0 0 0 0 0 0 0 0 0 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + args => "-X 1000", + report => "-M 5", + pairhits => [{ "12,78" => 1, "12,249" => 1, "12,315" => 1, + "12,486" => 1, "12,552" => 1, "12,723" => 1, + "12,789" => 1, "12,960" => 1 }], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 78 => "28M", + 249 => "28M", 315 => "28M", + 486 => "28M", 552 => "28M", + 723 => "28M", 789 => "28M", + 960 => "28M" + }], + samoptflags_map => [ { + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 249 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 315 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 486 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 552 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 723 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 789 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 960 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + } ] }, + + { name => "P.M.58.L.b Unpaired -M 5 w/ 8 hits local, but mate #1 has just 1", + # 0 1 2 3 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGT" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 + # 0 1 2 3 4 5 6 7 8 9 + # 0 0 0 0 0 0 0 0 0 0 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + args => "-X 1000 --local", + report => "-M 5", + pairhits => [{ "12,78" => 1, "12,249" => 1, "12,315" => 1, + "12,486" => 1, "12,552" => 1, "12,723" => 1, + "12,789" => 1, "12,960" => 1 }], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 78 => "28M", + 249 => "28M", 315 => "28M", + 486 => "28M", 552 => "28M", + 723 => "28M", 789 => "28M", + 960 => "28M" + }], + samoptflags_map => [ { + 12 => { "AS:i:66" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 249 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 315 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 486 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 552 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 723 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 789 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 960 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + } ] }, + + { name => "P.k.58.G.b Unpaired -k 5 w/ 8 hits global, but mate #1 has just 1", + # 0 1 2 3 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGT" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 + # 0 1 2 3 4 5 6 7 8 9 + # 0 0 0 0 0 0 0 0 0 0 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + args => "-X 1000", + report => "-k 5", + pairhits => [{ "12,78" => 1, "12,249" => 1, "12,315" => 1, + "12,486" => 1, "12,552" => 1, "12,723" => 1, + "12,789" => 1, "12,960" => 1 }], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 78 => "28M", + 249 => "28M", 315 => "28M", + 486 => "28M", 552 => "28M", + 723 => "28M", 789 => "28M", + 960 => "28M" + }], + samoptflags_map => [ { + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 249 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 315 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 486 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 552 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 723 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 789 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 960 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + } ] }, + + { name => "P.k.58.L.b Unpaired -k 5 w/ 8 hits local, but mate #1 has just 1", + # 0 1 2 3 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACACACACCCCTATAGCTCGGAGCTGACTGGATCGACGACGT" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 + # 0 1 2 3 4 5 6 7 8 9 + # 0 0 0 0 0 0 0 0 0 0 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + args => "-X 1000 --local", + report => "-k 5", + pairhits => [{ "12,78" => 1, "12,249" => 1, "12,315" => 1, + "12,486" => 1, "12,552" => 1, "12,723" => 1, + "12,789" => 1, "12,960" => 1 }], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 78 => "28M", + 249 => "28M", 315 => "28M", + 486 => "28M", 552 => "28M", + 723 => "28M", 789 => "28M", + 960 => "28M" + }], + samoptflags_map => [ { + 12 => { "AS:i:66" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 249 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 315 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 486 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 552 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 723 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 789 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 960 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + } ] }, + + { name => "P.M.22.G. Paired -M 2 w/ 2 paired hit, 2 unpaired hits each, global", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 + # 0 1 2 3 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + args => "-X 150", + report => "-M 2", + pairhits => [ { "12,78" => 1, "249,315" => 1 } ], + cigar_map => [{ + 12 => "33M", 249 => "33M", + 78 => "28M", 315 => "28M" + }], + hits_are_superset => [ 1 ], + samoptflags_map => [{ + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 249 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 315 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + }] + }, + + { name => "P.M.22.L. Paired -M 2 w/ 2 paired hit, 2 unpaired hits each, local", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 + # 0 1 2 3 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + args => "--local -X 150", + report => "-M 2", + pairhits => [ { "12,78" => 1, "249,315" => 1 } ], + cigar_map => [{ + 12 => "33M", 249 => "33M", + 78 => "28M", 315 => "28M" + }], + hits_are_superset => [ 1 ], + samoptflags_map => [{ + 12 => { "AS:i:66" => 1, "XS:i:66" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:56" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 249 => { "AS:i:66" => 1, "XS:i:66" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 315 => { "AS:i:56" => 1, "XS:i:56" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + }] + }, + + { name => "P.k.2.G. Paired -k 1 w/ 2 paired hit, 2 unpaired hits each, global", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 + # 0 1 2 3 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + args => "-X 150", + report => "-k 1", + pairhits => [ { "12,78" => 1, "249,315" => 1 } ], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 249 => "33M", + 78 => "28M", 315 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 249 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 315 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YT:Z:CP" => 1, "YS:i:0" => 1 }, + }] + }, + + { name => "P.k.2.L. Paired -k 1 w/ 2 paired hit, 2 unpaired hits each, local", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 + # 0 1 2 3 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + args => "--local -X 150", + report => "-k 1", + pairhits => [ { "12,78" => 1, "249,315" => 1 } ], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 249 => "33M", + 78 => "28M", 315 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:66" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 249 => { "AS:i:66" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 315 => { "AS:i:56" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YT:Z:CP" => 1, "YS:i:66" => 1 }, + }] + }, + + { name => "P.M.2.G. Paired -M 1 w/ 2 paired hit, 2 unpaired hits each, global", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 + # 0 1 2 3 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + report => "-M 1 -X 150", + pairhits => [ { "12,78" => 1, "249,315" => 1 } ], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 249 => "33M", + 78 => "28M", 315 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 249 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 315 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + }] + }, + + { name => "P.M.2.L. Paired -M 1 w/ 2 paired hit, 2 unpaired hits each, local", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 + # 0 1 2 3 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + report => "-M 1 --local -X 150", + pairhits => [ { "12,78" => 1, "249,315" => 1 } ], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 249 => "33M", + 78 => "28M", 315 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:66" => 1, "XS:i:66" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:56" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 249 => { "AS:i:66" => 1, "XS:i:66" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 315 => { "AS:i:56" => 1, "XS:i:56" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + }] + }, + + { name => "P.k.1.G. Paired -k w/ 1 paired hit, 1 unpaired hit each, global", + # 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + report => "-k 1 -X 150", + pairhits => [ { "12,78" => 1 } ], + cigar_map => [{ + 12 => "33M", + 78 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + }] + }, + + { name => "P.k.1.L. Paired -k 1 w/ 1 paired hit, 1 unpaired hit each, local", + # 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + args => "--local -X 150", + report => "-k 1", + pairhits => [ { "12,78" => 1 } ], + cigar_map => [{ + 12 => "33M", + 78 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:66" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + }] + }, + + { name => "P.M.1.G. Paired -M w/ 1 paired hit, 1 unpaired hit each, global", + # 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + args => "-X 150", + report => "-M 1", + pairhits => [ { "12,78" => 1 } ], + cigar_map => [{ + 12 => "33M", + 78 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + }] + }, + + { name => "P.M.1.L. Paired -M w/ 1 paired hit, 1 unpaired hit each, local", + # 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + mate1fw => 1, mate2fw => 0, + args => "-X 150 --local", + report => "-M 1", + pairhits => [ { "12,78" => 1 } ], + cigar_map => [{ + 12 => "33M", + 78 => "28M" + }], + samoptflags_map => [{ + 12 => { "AS:i:66" => 1, "XS:i:0" => 1, "MD:Z:33" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:0" => 1, "MD:Z:28" => 1, + "YM:i:0" => 1, "YP:i:0" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + }] + }, + + { name => "P.M.58.G. Unpaired -M 5 w/ 8 hits global", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGA" ], + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 + # 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + args => "-X 150", + report => "-M 5", + pairhits => [ { "12,78" => 1, "249,315" => 1, "486,552" => 1, + "723,789" => 1, "960,1026" => 1, "1197,1263" => 1, + "1434,1500" => 1, "1671,1737" => 1, "1908,1974" => 1, + "2145,2211" => 1, "2382,2448" => 1 } ], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 78 => "28M", + 249 => "33M", 315 => "28M", + 486 => "33M", 552 => "28M", + 723 => "33M", 789 => "28M", + 960 => "33M", 1026 => "28M", + 1197 => "33M", 1263 => "28M", + 1434 => "33M", 1500 => "28M", + 1671 => "33M", 1737 => "28M", + 1908 => "33M", 1974 => "28M", + 2145 => "33M", 2211 => "28M", + 2382 => "33M", 2448 => "28M", + }], + samoptflags_map => [ { + 12 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 78 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 249 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 315 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 486 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 552 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 723 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 789 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 960 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1026 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1197 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1263 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1434 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1500 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1671 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1737 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1908 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 1974 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 2145 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 2211 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 2382 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + 2448 => { "AS:i:0" => 1, "XS:i:0" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:0" => 1 }, + } ] }, + + { name => "P.M.58.L. Unpaired -M 5 w/ 8 hits local", + # 0 1 2 3 0 1 2 0 1 2 3 0 1 2 + # 012345678901234567890123456789012 0123456789012345678901234567 012345678901234567890123456789012 0123456789012345678901234567 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG CAGCGTACGGTATCTAGCTATGGGCATCGATCG ACACACCCCTATAGCTCGGAGCTGACTG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGAGCGGTATCTACAGCCACTCATCACACACCCCTATAGCTCGGAGCTGACTGGGTTACTGGGGGGGATGCGTATCGACTATCGACAATATGACGCGTCGGTCACCCCATAATATGCAAAAATTATAGCTCACGACGCGTACTAATAGAAAACGCGCTATCAGCCTCCGACGCGGCGGTATCGAAGACGCAGTC" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 + # 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 + mate1s => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + mate2s => [ "CAGTCAGCTCCGAGCTATAGGGGTGTGT" ], # rev comped + args => "--local -X 150", + report => "-M 5", + pairhits => [ { "12,78" => 1, "249,315" => 1, "486,552" => 1, + "723,789" => 1, "960,1026" => 1, "1197,1263" => 1, + "1434,1500" => 1, "1671,1737" => 1 } ], + hits_are_superset => [ 1 ], + cigar_map => [{ + 12 => "33M", 78 => "28M", + 249 => "33M", 315 => "28M", + 486 => "33M", 552 => "28M", + 723 => "33M", 789 => "28M", + 960 => "33M", 1026 => "28M", + 1197 => "33M", 1263 => "28M", + 1434 => "33M", 1500 => "28M", + 1671 => "33M", 1737 => "28M" + }], + samoptflags_map => [ { + 12 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 78 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 249 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 315 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 486 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 552 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 723 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 789 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 960 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 1026 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 1197 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 1263 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 1434 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 1500 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + 1671 => { "AS:i:66" => 1, "XS:i:66" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:33" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:56" => 1 }, + 1737 => { "AS:i:56" => 1, "XS:i:56" => 1, "XN:i:0" => 1, "XM:i:0" => 1, + "XO:i:0" => 1, "XG:i:0" => 1, "NM:i:0" => 1, "MD:Z:28" => 1, + "YM:i:1" => 1, "YP:i:1" => 1, "YT:Z:CP" => 1, "YS:i:66" => 1 }, + } ] }, + + # + # Unpaired + # + + { name => "U.M.1.G. Unpaired -M w/ 1 hit global", + # 0 1 2 3 + # 012345678901234567890123456789012 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG + # CAGCGTACGGTATCTAGCTATG + # GGTATCTAGCTATGGGCATCGA + # AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGA + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGA" ], + # 01234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 + reads => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + report => "-M 1", + hits => [ { 12 => 1 } ], + cigar => [ "33M" ], + samoptflags => [{ + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:33" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + }] + }, + + { name => "U.M.1.L. Unpaired -M w/ 1 hit local", + # 0 1 2 3 + # 012345678901234567890123456789012 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGA" ], + # 01234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 + reads => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + args => "--local", + report => "-M 1", + hits => [ { 12 => 1 } ], + cigar => [ "33M" ], + samoptflags => [{ + "AS:i:66" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:33" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + }] + }, + + { name => "U.k.1.G. Unpaired -k 1 w/ 1 hit global", + # 0 1 2 3 + # 012345678901234567890123456789012 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGA" ], + # 01234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 + reads => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + report => "-k 1", + hits => [ { 12 => 1 } ], + cigar => [ "33M" ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:33" => 1, # mismatching positions/bases + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.M.1.L. Unpaired -m w/ 1 hit local", + # 0 1 2 3 + # 012345678901234567890123456789012 + # CAGCGTACGGTATCTAGCTATGGGCATCGATCG + ref => [ "AGACGCAGTCACCAGCGTACGGTATCTAGCTATGGGCATCGATCGACGACGTACGA" ], + # 01234567890123456789012345678901234567890123456789012345 + # 0 1 2 3 4 5 + reads => [ "CAGCGTACGGTATCTAGCTATGGGCATCGATCG" ], + args => "--local", + report => "-k 1", + hits => [ { 12 => 1 } ], + cigar => [ "33M" ], + samoptflags => [ { + "AS:i:66" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:33" => 1, # mismatching positions/bases + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.M.2.G. Unpaired -M 1 w/ 2 hit global", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + args => "", + report => "-M 1", + hits => [ { 6 => 1, 48 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:1" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.M.2.L. Unpaired -M 1 w/ 2 hit local", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + args => "--local", + report => "-M 1", + hits => [ { 6 => 1, 48 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:60" => 1, # alignment score + "XS:i:60" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:1" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.k.2.G. Unpaired -k 1 w/ 2 hit global", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + report => "-k 1", + hits => [ { 6 => 1, 48 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.k.2.L. Unpaired -k 1 w/ 2 hit local", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + report => "-k 1", + hits => [ { 6 => 1, 48 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.M.22.G. Unpaired -M 2 w/ 2 hit global", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + report => "-M 2", + hits => [ { 6 => 1, 48 => 1 } ], + cigar => [ "30M" ], + hits_are_superset => [ 1 ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.M.22.L. Unpaired -M 2 w/ 2 hit local", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + report => "-M 2 --local", + hits => [ { 6 => 1, 48 => 1 } ], + cigar => [ "30M" ], + hits_are_superset => [ 1 ], + samoptflags => [ { + "AS:i:60" => 1, # alignment score + "XS:i:60" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.k.22.G. Unpaired -k 2 w/ 2 hit global", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + report => "-k 2", + hits => [ { 6 => 1, 48 => 1 } ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.k.22.L. Unpaired -k 2 w/ 2 hit local", + # 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + # 0 1 2 3 4 5 6 7 8 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + args => "--local", + report => "-k 2", + hits => [ { 6 => 1, 48 => 1 } ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:60" => 1, # alignment score + "XS:i:60" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.M.58.G. Unpaired -M 5 w/ 8 hits global", + # 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + # 0 1 2 3 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + args => "-X 150", + report => "-M 5", + hits => [ { 6 => 1, 48 => 1, 91 => 1, 133 => 1, 176 => 1, 218 => 1, 261 => 1, 303 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:1" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.M.58.L. Unpaired -M 5 w/ 8 hits global", + # 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + # 0 1 2 3 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + args => "--local", + report => "-M 5", + hits => [ { 6 => 1, 48 => 1, 91 => 1, 133 => 1, 176 => 1, 218 => 1, 261 => 1, 303 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:60" => 1, # alignment score + "XS:i:60" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:1" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.k.58.G. Unpaired -k 5 w/ 8 hits global", + # 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + # 0 1 2 3 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + report => "-k 5", + hits => [ { 6 => 1, 48 => 1, 91 => 1, 133 => 1, 176 => 1, 218 => 1, 261 => 1, 303 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:0" => 1, # alignment score + "XS:i:0" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + { name => "U.k.58.L. Unpaired -k 5 w/ 8 hits local", + # 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 + # 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 012345678901234567890123456789 + # AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA AGATTACGGATCTACGATTCGAGTCGGTCA + ref => [ "AGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGAAGACGCAGATTACGGATCTACGATTCGAGTCGGTCAGTCACCAGCGTAAGATTACGGATCTACGATTCGAGTCGGTCAAGTGCGA" ], + # 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + # 0 1 2 3 + reads => [ "AGATTACGGATCTACGATTCGAGTCGGTCA" ], + args => "--local", + report => "-k 5", + hits => [ { 6 => 1, 48 => 1, 91 => 1, 133 => 1, 176 => 1, 218 => 1, 261 => 1, 303 => 1 } ], + hits_are_superset => [ 1 ], + cigar => [ "30M" ], + samoptflags => [ { + "AS:i:60" => 1, # alignment score + "XS:i:60" => 1, # suboptimal alignment score + "XN:i:0" => 1, # num ambiguous ref bases + "XM:i:0" => 1, # num mismatches + "XO:i:0" => 1, # num gap opens + "XG:i:0" => 1, # num gap extensions + "NM:i:0" => 1, # num edits + "MD:Z:30" => 1, # mismatching positions/bases + "YM:i:0" => 1, # read aligned repetitively in unpaired fashion + "YT:Z:UU" => 1, # unpaired read aligned in unpaired fashion + } ] }, + + # Following cases depend on this being the case: + # + # static const float DEFAULT_CEIL_CONST = 3.0f; + # static const float DEFAULT_CEIL_LINEAR = 3.0f; + + # Just enough budget for hits, so it should align + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCAT" ], # budget = 3 + 8 * 3 = 27 + args => "-L 6 -i C,1,0 --policy \"MMP=C27\\;MIN=L,-3,-3\\;RDG=25,15\\;RFG=25,15\"", # penalty = 27 + report => "-a", + hits => [ { 0 => 1, 8 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:6=1X1=" ], + cigar => [ "8M" ], + samoptflags => [ { "AS:i:-27" => 1, "XS:i:-27" => 1, "NM:i:1" => 1, + "XM:i:1" => 1, "YT:Z:UU" => 1, "MD:Z:6G1" => 1 } ] }, + + # Not quite enough budget for hits, so it should NOT align + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCAT" ], # budget = 3 + 8 * 3 = 27 + args => "-L 6 -i C,1,0 --policy \"MMP=C28\\;MIN=L,-3,-3\\;RDG=25,15\\;RFG=25,15\"", # penalty = 28 + report => "-a", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ], + samoptflags => [ { "YT:Z:UU" => 1 } ] }, + + # Check that using a seed of length 1 with 1-mismatch doesn't crash. + # Perhaps we should disallow it though? + + { ref => [ "AAAAAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCCCCCCCCCCCCCCC" ], + reads => [ "AA", "AA", "AA", "AA", "CC", "CC", "CC", "CC", "AA", "AA", "AA", "AA", "CC", "CC", "CC", "CC" ], + names => [ "r1", "r1", "r1", "r1", "r2", "r2", "r2", "r2", "r3", "r3", "r3", "r3", "r4", "r4", "r4", "r4" ], + args => "--policy \"SEED=1,1\"", + check_random => 1, + report => "-k 1" }, + + # + # Gap penalties + # + + # Alignment with 1 read gap + { name => "Gap penalties 1", + ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCTTTGTT" ], # budget = 3 + 12 * 3 = 39 + args => "--policy \"MMP=C30\\;SEED=0,3\\;IVAL=C,1,0\\;RDG=29,10\\;RFG=25,15\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:6=1D6=" ], + cigar => [ "6M1D6M" ], + samoptflags => [{ + "AS:i:-39" => 1, "NM:i:1" => 1, "XO:i:1" => 1, "XG:i:1" => 1, + "YT:Z:UU" => 1, "MD:Z:6^G6" => 1 }] + }, + + # Alignment with 1 read gap, but not enough budget + { name => "Gap penalties 2", + ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCTTTGTT" ], # budget = 3 + 12 * 3 = 39 + args => "--policy \"MMP=C30\\;SEED=0,3\\;IVAL=C,1,0\\;RDG=30,10\\;RFG=25,15\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ], + samoptflags => [{ "YT:Z:UU" => 1 }] + }, + + # Alignment with 1 reference gap + { name => "Gap penalties 3", + ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGATTTGTT" ], # budget = 3 + 14 * 3 = 45 + args => "--policy \"MMP=C30\\;SEED=0,3\\;IVAL=C,1,0\\;RDG=25,15\\;RFG=30,15\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:7=1I6=" ], + cigar => [ "7M1I6M" ], + samoptflags => [{ "AS:i:-45" => 1, "NM:i:1" => 1, "XO:i:1" => 1, + "XG:i:1" => 1, "YT:Z:UU" => 1, "MD:Z:13" => 1 }] + }, + + # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + # T T G T T C G T T T G T T C G T + # 0 1 1 0 2 3 1 0 0 1 1 0 2 3 1 + # 0 T x + # 0 0 x + # 1 T x + # 1 1 x + # 2 G x + # 2 1 x + # 3 T x + # 3 0 x + # 4 T x + # 4 2 x + # 5 C x + # 5 3 x + # 6 G + # 6 2 x + # 7 A + # 7 3 x + # 8 T x + # 8 0 x + # 9 T x + # 9 0 x + # 0 T x + # 0 1 x + # 1 G x + # 1 1 x + # 2 T x + # 2 0 x + # 3 T + # + + # Alignment with 1 reference gap, but not enough budget + { name => "Gap penalties 4", + ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGATTTGTT" ], # budget = 3 + 14 * 3 = 45 + args => "--policy \"MMP=C30\\;SEED=0,3\\;IVAL=C,1,0\\;RDG=25,15\\;RFG=30,16\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ], + samoptflags => [ { "YT:Z:UU" => 1 } ] }, + + # Alignment with 1 reference gap, but not enough budget + { name => "Gap penalties 5", + ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGATTTGTT" ], # budget = 3 + 14 * 3 = 45 + args => "--policy \"MMP=C30\\;SEED=0,3\\;IVAL=C,1,0\\;RDG=25,15\\;RFG=31,15\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ], + samoptflags => [ { "YT:Z:UU" => 1 } ] }, + + # Alignment with 1 reference gap and 1 read gap + { name => "Gap penalties 6", + ref => [ "ATTGTTCGTTTGTTCGTA" ], + reads => [ "ATTGTTGTTTGATTCGTA" ], # budget = 3 + 18 * 3 = 57 + args => "--policy \"MMP=C30\\;SEED=0,3\\;IVAL=C,1,0\\;RDG=19,10\\;RFG=18,10\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:6=1D5=1I6=" ], + cigar => [ "6M1D5M1I6M" ] }, + + # Alignment with 1 reference gap and 1 read gap, but not enough budget + { name => "Gap penalties 7", + ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTGTTTGATTCGT" ], # budget = 3 + 16 * 3 = 51 + args => "--policy \"MMP=C30\\;SEED=0,3\\;IVAL=C,1,0\\;RDG=16,10\\;RFG=16,10\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ] }, + + # Experiment with N filtering + + { name => "N filtering 1", + ref => [ "GAGACTTTATACGCATCGAACTATCGCTCTA" ], + reads => [ "ATACGCATCGAAC" ], + # 0123456789012345678901234567890 + # 1 2 3 + args => "--policy \"NCEIL=L,0,0\"", + report => "-a", + hits => [ { 8 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:13=" ] }, + + { name => "N filtering 2", + ref => [ "GAGACTTTATNCGCATCGAACTATCGCTCTA" ], + reads => [ "ATACGCATCGAAC" ], + # 0123456789012345678901234567890 + # 1 2 3 + args => "--policy \"NCEIL=L,0,0\"", + report => "-a", + hits => [ { "*" => 1 } ] }, + + { name => "N filtering 3", + ref => [ "GAGACTTTATACGCATCGAANTATCGCTCTA" ], + reads => [ "ATACGCATCGAAC" ], + # 0123456789012345678901234567890 + # 1 2 3 + args => "--policy \"NCEIL=L,0,0\"", + report => "-a", + hits => [ { "*" => 1 } ] }, + + { name => "N filtering 4", + ref => [ "GAGACTTTNTACGCATCGAACTATCGCTCTA" ], + reads => [ "ATACGCATCGAAC" ], + # 0123456789012345678901234567890 + # 1 2 3 + args => "--policy \"NCEIL=L,0,0\"", + report => "-a", + hits => [ { "*" => 1 } ] }, + + { name => "N filtering 5", + ref => [ "GAGACTTTATNCGCATCGAACTATCGCTCTA" ], + reads => [ "ATACGCATCGAAC" ], + # 0123456789012345678901234567890 + # 1 2 3 + args => "--policy \"NCEIL=L,0,0.1\\;SEED=0,10\\;IVAL=C,1,0\"", + report => "-a", + hits => [ { 8 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:2=1X10=" ] }, + + { name => "N filtering 6", + ref => [ "GAGACTTTNTACGCATCGAANTATCGCTCTA" ], + reads => [ "ATACGCATCGAAC" ], + # 0123456789012345678901234567890 + # 1 2 3 + args => "--policy \"NCEIL=L,0,0.1\\;SEED=0,10\\;IVAL=C,1,0\"", + report => "-a", + hits => [ { "*" => 1 } ] }, + + # No discordant alignment because one mate is repetitive. + + # Alignment with 1 reference gap + { ref => [ "TTTTGTTCGTTTG" ], + reads => [ "TTTTGTTCGATTTG" ], # budget = 3 + 14 * 3 = 45 + args => "--policy \"SEED=0,8\\;IVAL=C,1,0\\;MMP=C30\\;RDG=25,15\\;RFG=25,20\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:9=1I4=" ], + cigar => [ "9M1I4M" ], + samoptflags => [ + { "AS:i:-45" => 1, "NM:i:1" => 1, "XO:i:1" => 1, "XG:i:1" => 1, + "YT:Z:UU" => 1, "MD:Z:13" => 1 }, + ] + }, + + # TTGTTCGTTTGTT + # Tx + # T x + # G x + # T x + # T x + # C x + # G x + # A x + # T x + # T x + # T x + # G x + # T x + # T x + + # Alignment with 1 reference gap + { ref => [ "TTGTTCGTTTGTT" ], + reads => [ "TTGTTCGATTTGTT" ], # budget = 3 + 14 * 3 = 45 + args => "--policy \"SEED=0,3\\;IVAL=C,1,0\\;MMP=C30\\;RDG=25,15\\;RFG=25,20\\;MIN=L,-3,-3\"", + report => "-a", + hits => [ { 0 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:7=1I6=" ], + cigar => [ "7M1I6M" ], + samoptflags => [ + { "AS:i:-45" => 1, "NM:i:1" => 1, "XO:i:1" => 1, "XG:i:1" => 1, + "YT:Z:UU" => 1, "MD:Z:13" => 1 }, + ] + }, + + { ref => [ "ACNCA" ], + reads => [ "CA" ], + args => "", + report => "-a --policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,0,0\"", + hits => [ { 3 => 1 } ], + edits => [ ], + flags => [ "XM:0,XP:0,XT:UU,XC:2=" ], + cigar => [ "2M" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + ] + }, + + { name => "N ceil = 0, 2 legit hits (1)", + ref => [ "ACNCA" ], + reads => [ "AC" ], + args => "", + report => "-a --policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,0,0\"", + hits => [ { 0 => 1 } ], + edits => [ ], + flags => [ ] }, + + { name => "N ceil = 0, 2 legit hits (2)", + ref => [ "ACNCANNNNNNNNCGNNNNNNNNCG" ], + # 0123456789012345678901234 + # 0 1 2 + reads => [ "CG" ], + args => "", + report => "-a --policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,0,0\"", + hits => [ { 13 => 2, 23 => 2 } ], + edits => [ ], + cigar => [ "2M", "2M" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + ] + }, + + { ref => [ "ACNCANNNNNNAACGNNNNNNNACGAANNNNCGAAAN" ], + # 0123456789012345678901234567890123456 + # 0 1 2 3 + reads => [ "CG" ], + args => "", + report => "-a --policy \"SEED=0,2\\;IVAL=C,1,0\\;NCEIL=L,0,0\"", + hits => [ { 13 => 2, 23 => 2, 31 => 2 } ], + edits => [ ], + flags => [ "XM:0,XP:0,XT:UU,XC:2=", + "XM:0,XP:0,XT:UU,XC:2=", + "XM:0,XP:0,XT:UU,XC:2=" ], + cigar => [ "2M", "2M", "2M" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + ] + }, + + { ref => [ "ACNCANNNNNNAACGNNNNNNNACGAANNNNCGAAAN" ], + # 0123456789012345678901234567890123456 + # 0 1 2 3 + reads => [ "CG" ], + args => "", + report => "-a --policy \"SEED=0,1\\;IVAL=C,1,0\\;NCEIL=L,0,0\"", + hits => [ { 13 => 2, 23 => 2, 31 => 2 } ], + edits => [ ], + flags => [ "XM:0,XP:0,XT:UU,XC:2=", + "XM:0,XP:0,XT:UU,XC:2=", + "XM:0,XP:0,XT:UU,XC:2=" ], + cigar => [ "2M", "2M", "2M" ], + samoptflags => [ + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + { "YT:Z:UU" => 1, "MD:Z:2" => 1 }, + ] + }, + + # + # Alignment involving ambiguous reference character + # + + # First read has non-compatible unambiguous charcacter (G for Y), + # second read has compatible one + { ref => [ "TTGTTYGT" ], + reads => [ "TTGTTGGT", "TTGTTCGT" ], + args => "", + report => "-a --policy \"SEED=0,5\\;IVAL=C,1,0\\;NCEIL=L,2,0\"", + hits => [ { 0 => 1 }, { 0 => 1 } ], + norc => 1, + edits => [ "5:N>G", "5:N>C" ], + flags => [ "XM:0,XP:0,XT:UU,XC:5=1X2=", "XM:0,XP:0,XT:UU,XC:5=1X2=" ], + cigar => [ "8M", "8M" ], + samoptflags => [ + { "AS:i:-1" => 1, "NM:i:1" => 1, "XM:i:1" => 1, "XN:i:1" => 1, + "YT:Z:UU" => 1, "MD:Z:5N2" => 1 }, + { "AS:i:-1" => 1, "NM:i:1" => 1, "XM:i:1" => 1, "XN:i:1" => 1, + "YT:Z:UU" => 1, "MD:Z:5N2" => 1 }, + ] + }, + + # + # Alignment with multi-character read gap + # + + # Relatively small example with a read gap extend + { ref => [ "ATAACCTTCG" ], + reads => [ "ATAATTCG" ], # 3 * 19 + 3 = 60 + # ^ + # 4:CC>- + args => "", + report => "-a --overhang --gbar 3 --policy \"MMP=C30\\;RDG=5,5\\;SEED=0,4\\;IVAL=C,1,0\\;RFG=25,20\\;MIN=L,-3,-3\"", + hits => [ { 0 => 1 } ], + edits => [ "4:CC>-" ], + flags => [ "XM:0,XP:0,XT:UU,XC:4=2D4=" ], + cigar => [ "4M2D4M" ], + samoptflags => [ + { "AS:i:-15" => 1, "NM:i:2" => 1, + "XO:i:1" => 1, "XG:i:2" => 3, "YT:Z:UU" => 1, "MD:Z:4^CC4" => 1 } + ] + }, + + # Reads 1 and 2 don't have overhang, reads 3 and 4 overhang opposite ends + { ref => [ "ATATGCCCCATGCCCCCCTCCG" ], + reads => [ "ATATGCCCCCCCCCCTCCG" ], # 3 * 19 + 3 = 60 + # ^ + # 9:ATG>- + args => "--policy \"SEED=0,8\\;IVAL=C,1,0\\;MMP=C30\\;RDG=5,5\\;RFG=25,15\\;MIN=L,-3,-3\"", + hits => [ { 0 => 1 } ], + edits => [ "9:ATG>-" ], + norc => 1, + flags => [ "XM:0,XP:0,XT:UU,XC:9=3D10=" ], + cigar => [ "9M3D10M" ], + samoptflags => [ + { "AS:i:-20" => 1, "NM:i:3" => 1, + "XO:i:1" => 1, "XG:i:3" => 3, "YT:Z:UU" => 1, "MD:Z:9^ATG10" => 1 } + ] + }, + + # Reads 1 and 2 don't have overhang, reads 3 and 4 overhang opposite ends + { ref => [ "ATATGCCCCATGCCCCCCTCCG" ], + reads => [ "CGGAGGGGGGGGGGCATAT" ], + # ATATGCCCCCCCCCCTCCG + # ^ + # 10:GTA>- + args => "", + report => "-a --overhang --policy \"SEED=0,8\\;IVAL=C,1,0\\;MMP=C30\\;RDG=5,5\\;RFG=25,20\\;MIN=L,-3,-3\"", + hits => [ { 0 => 1 } ], + edits => [ "10:GTA>-" ], + norc => 1, + flags => [ "XM:0,XP:0,XT:UU,XC:9=3D10=" ], + cigar => [ "9M3D10M" ], + samoptflags => [ + { "AS:i:-20" => 1, "NM:i:3" => 1, + "XO:i:1" => 1, "XG:i:3" => 3, "YT:Z:UU" => 1, "MD:Z:9^ATG10" => 1 } + ] + }, + + # 1 discordant alignment and one concordant alignment. Discordant because + # the fragment is too long. + + { name => "Simple paired-end 13", + ref => [ "TTTATAAAAATATTTCCCCCCCCCCCCCCTGTCGCTACCGCCCCCCCCCCC" ], + # 012345678901234567890123456789012345678901234567890 + # 0 1 2 3 4 5 + # ATAAAAATAT GTCGCTACCG + # ATAAAAATAT TGTCGCTACC + # ATAAAAATAT CTGTCGCTAC + # ATAAAAATAT CCTGTCGCTA + # TAAAAATATT GTCGCTACCG + # TAAAAATATT TGTCGCTACC + # TAAAAATATT CTGTCGCTAC + # TAAAAATATT CCTGTCGCTA + # 012345678901234567890123456789012345678901234567890 + # 0 1 2 3 4 5 + # ----------------------------------- + # 012345678901234567890123456789012345678901234567 + # 0 1 2 3 4 + mate1s => [ "ATAAAAATAT", "ATAAAAATAT", "ATAAAAATAT", "ATAAAAATAT", + "TAAAAATATT", "TAAAAATATT", "TAAAAATATT", "TAAAAATATT", ], + mate2s => [ "GTCGCTACCG", "TGTCGCTACC", "CTGTCGCTAC", "CCTGTCGCTA", + "GTCGCTACCG", "TGTCGCTACC", "CTGTCGCTAC", "CCTGTCGCTA" ], + mate1fw => 1, mate2fw => 1, + args => "-I 0 -X 35", + # Not really any way to flag an alignment as discordant + pairhits => [ { "3,30" => 1 }, { "3,29" => 1 }, { "3,28" => 1 }, { "3,27" => 1 }, + { "4,30" => 1 }, { "4,29" => 1 }, { "4,28" => 1 }, { "4,27" => 1 } ], + flags => [ "XM:0,XP:0,XT:DP,XC:10=", "XM:0,XP:0,XT:DP,XC:10=", + "XM:0,XP:0,XT:CP,XC:10=", "XM:0,XP:0,XT:CP,XC:10=", + "XM:0,XP:0,XT:DP,XC:10=", "XM:0,XP:0,XT:CP,XC:10=", + "XM:0,XP:0,XT:CP,XC:10=", "XM:0,XP:0,XT:CP,XC:10=" ] }, + + # 1 discordant alignment and one concordant alignment. Discordant because + # the fragment is too long. + + { name => "Simple paired-end 12", + ref => [ "TTTATAAAAATATTTCCCCCCCCCCCCCCGGGCCCGCCCGCCCCCCCCCCC" ], + # ATAAAAATAT GGCCCGCCCG + # ATAAAAATAT CCGGGCCCGC + # 012345678901234567890123456789012345678901234567890 + # 0 1 2 3 4 5 + # ------------------------------------- + # 012345678901234567890123456789012345678901234567 + mate1s => [ "ATAAAAATAT", "ATAAAAATAT" ], + mate2s => [ "GGCCCGCCCG", "CCGGGCCCGC" ], + mate1fw => 1, mate2fw => 1, + args => "-I 0 -X 36", + # Not really any way to flag an alignment as discordant + pairhits => [ { "3,30" => 1 }, { "3,27" => 1 } ], + flags => [ "XM:0,XP:0,XT:DP,XC:10=", "XM:0,XP:0,XT:CP,XC:10=" ] }, + + # 1 discordant alignment. Discordant because the fragment is too long. + + { name => "Simple paired-end 11", + ref => [ "TTTATAAAAATATTTCCCCCCCCCCCCCCCCGATCGCCCGCCCCCCCCCCC" ], + # ATAAAAATAT CGATCGCCCG + # 012345678901234567890123456789012345678901234567890 + # 0 1 2 3 4 5 + # ------------------------------------- + # 012345678901234567890123456789012345678901234567 + mate1s => [ "ATAAAAATAT" ], + mate2s => [ "CGATCGCCCG" ], + mate1fw => 1, mate2fw => 1, + args => "-I 0 -X 36", + # Not really any way to flag an alignment as discordant + pairhits => [ { "3,30" => 1 } ], + flags => [ "XM:0,XP:0,XT:DP,XC:10=" ] }, + + # 1 discordant alignment. Discordant because the fragment is too short. + + { name => "Simple paired-end 10", + ref => [ "TTTATAAAAATATTTCCCCCCGATCGCCCGCCCCCCCCCCC" ], + # ATAAAAATAT CGATCGCCCG + # 01234567890123456789012345678901234567890 + # 0 1 2 3 4 + # --------------------------- + # 012345678901234567890123456 + mate1s => [ "ATAAAAATAT" ], + mate2s => [ "CGATCGCCCG" ], + mate1fw => 1, mate2fw => 1, + args => "-I 28 -X 80", + # Not really any way to flag an alignment as discordant + pairhits => [ { "3,20" => 1 } ], + flags => [ "XM:0,XP:0,XT:DP,XC:10=" ] }, + + # Like 6, but with -M limit + + { name => "Simple paired-end 9", + ref => [ "CCCATATATATATCCTCCCATATATATATCCCTCCCCATATATATATCCCTTTTCCTTTCGCGCGCGCGTTTCCCCCCCCC" ], + # ATATATATAT ATATATATAT ATATATATAT CGCGCGCGCG + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890 + # 0 1 2 3 4 5 6 7 8 + mate1s => [ "ATATATATAT" ], + mate2s => [ "CGCGCGCGCG" ], + mate1fw => 1, mate2fw => 0, + args => "-I 0 -X 80", + report => "-M 2", + lines => 2, + pairhits => [ { "3,59" => 1, "19,59" => 1, "37,59" => 1 } ], + hits_are_superset => [ 1 ], + flags => [ "XM:1,XP:1,XT:CP,XC:10=", "XM:1,XP:1,XT:CP,XC:10=" ] }, + + # Like 6, but without -m limit + + { name => "Simple paired-end 8", + ref => [ "CCCATATATATATCCTCCCATATATATATCCCTTCCCATATATATATCCCTTTTTTTTTCGCGCGCGCGTTTCCCCCCCCC" ], + # ATATATATAT ATATATATAT ATATATATAT CGCGCGCGCG + # 012345678901234567890123456789012345678901234567890123456789012345678901234567890 + # 0 1 2 3 4 5 6 7 8 + mate1s => [ "ATATATATAT" ], + mate2s => [ "CGCGCGCGCG" ], + mate1fw => 1, mate2fw => 0, + args => "-I 0 -X 80", + pairhits => [ { "3,59" => 1, "19,59" => 1, "37,59" => 1 } ], + flags => [ "XM:0,XP:0,XT:CP,XC:10=" ] }, + + # Paired-end read, but only one mate aligns + + { name => "Simple paired-end 2; no --no-mixed", + ref => [ "CCCATATATATATCCCTTTTTTTCCCCCCCCCCTTCGCGCGCGCGTTTCCCCC" ], + # ATATATATAT CGCGCGCGCG + # 01234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 + mate1s => [ "ATATATATAT" ], + mate2s => [ "CCCCCGGGGG" ], + mate1fw => 1, mate2fw => 1, + args => "-I 0 -X 50 --nofw", + nofw => 1, + pairhits => [ { "*,3" => 1 } ], + flags_map => [ { 3 => "XM:0,XP:0,XT:UP,XC:10=", + "*" => "XM:0,XP:0,XT:UP" } ], + cigar_map => [{ + 3 => "10M", + "*" => "*" + }], + samoptflags_map => [{ + 3 => { + "MD:Z:10" => 1, # mismatching positions/bases + "YT:Z:UP" => 1, # type of alignment (concordant/discordant/etc) + }, + "*" => { + "YT:Z:UP" => 1, # type of alignment (concordant/discordant/etc) + } + }] + }, + + { name => "Simple paired-end 2; --no-mixed", + ref => [ "CCCATATATATATCCCTTTTTTTCCCCCCCCTTTTCGCGCGCGCGTTTCCCCC" ], + # ATATATATAT CGCGCGCGCG + # 01234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 + mate1s => [ "ATATATATAT" ], + mate2s => [ "CCCCCGGGGG" ], + mate1fw => 1, mate2fw => 1, + args => "-I 0 -X 50 --no-mixed", + pairhits => [ { "*,*" => 1 } ] }, + + # Simple paired-end alignment + + { name => "Simple paired-end 1", + ref => [ "CCCATATATATATCCCTTTTTTTCCCCCCCCTTTTCGCGCGCGCGTTTTCCCC" ], + # ATATATATAT CGCGCGCGCG + # 01234567890123456789012345678901234567890123456789012 + # 0 1 2 3 4 5 + mate1s => [ "ATATATATAT" ], + mate2s => [ "CGCGCGCGCG" ], + mate1fw => 1, mate2fw => 1, + args => "-I 0 -X 50", + pairhits => [ { "3,35" => 1 } ], + flags => [ "XM:0,XP:0,XT:CP,XC:10=" ], + cigar_map => [{ + 3 => "10M", + 35 => "10M" + }], + samoptflags_map => [{ + 3 => { + "MD:Z:10" => 1, # mismatching positions/bases + "YT:Z:CP" => 1, # type of alignment (concordant/discordant/etc) + }, + 35 => { + "MD:Z:10" => 1, # mismatching positions/bases + "YT:Z:CP" => 1, # type of alignment (concordant/discordant/etc) + } + }] + }, + + # Check that pseudo-random generation is always the same for + # same-sequence, same-name reads + + { ref => [ "AAAAAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCCCCCCCCCCCCCCC" ], + reads => [ "AA", "AA", "AA", "AA", "CC", "CC", "CC", "CC", "AA", "AA", "AA", "AA", "CC", "CC", "CC", "CC" ], + names => [ "r1", "r1", "r1", "r1", "r2", "r2", "r2", "r2", "r3", "r3", "r3", "r3", "r4", "r4", "r4", "r4" ], + args => "", + check_random => 1, + report => "-k 1" }, + + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTGTTCGT" ], + report => "-M 1", + hits => [ { 0 => 1, 8 => 1 } ], + flags => [ "XM:1,XP:0,XT:UU,XC:8=" ], + hits_are_superset => [ 1 ], + cigar => [ "8M" ], + samoptflags => [ + { "YM:i:1" => 1, "YT:Z:UU" => 1, "MD:Z:8" => 1, "YM:i:1" => 1 } + ], + }, + + # Read 3 overhangs right end + { ref => [ "TTGTTCGT" ], + reads => [ "GTTCGTA" ], + args => "--overhang --policy \"SEED=0,3\\;IVAL=C,1,0\\;NCEIL=L,2,0\"", + hits => [ { 2 => 1 } ], + flags => [ "XM:0,XP:0,XT:UU,XC:6=1X" ] }, + + # Mess with arguments + + # Default should be 1-mismatch, so this shouldn't align + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTATTAGT" ], + args => "", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ], + samoptflags => [{ "YT:Z:UU" => 1 }], + }, + + # Shouldn't align with 0 mismatches either + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTATTAGT" ], + args => "--policy SEED=0", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ], + samoptflags => [{ "YT:Z:UU" => 1 }], + }, + + # Should align with 0 mismatches if we can wedge a seed into the 2 + # matching characters between the two mismatches. Here we fail to + # wedge a length-3 seed in (there's no room) + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTATTAGT" ], + args => "--policy \"SEED=0,3\\;IVAL=C,1,0\\;MMP=C1\"", + hits => [ { "*" => 1 } ], + flags => [ "XM:0,XP:0,XT:UU" ], + cigar => [ "*" ], + samoptflags => [{ "YT:Z:UU" => 1 }], + }, + + # Should align with 0 mismatches if we can wedge a seed into the 2 + # matching characters between the two mismatches. Here we wedge a + # length-2 seed in + { ref => [ "TTGTTCGTTTGTTCGT" ], + reads => [ "TTATTAGT" ], + args => "--policy \"SEED=0,2\\;IVAL=C,1,0\\;MMP=C1\"", + # + # TTGTTCGTTTGTTCGT TTGTTCGTTTGTTCGT TTGTTCGTTTGTTCGT + # || || || || | | || || + # TTATTAGT TTATTAGT TTATTAGT + # + # TTGTTCGTTTGTTCGT TTGTTCGTTTGTTCGT TTGTTCGTTTGTTCGT + # || | || | || || || + # TTATTAGT TTATTAGT TTATTAGT + # + hits => [ { 0 => 1, 3 => 1, 4 => 1, + 5 => 1, 7 => 1, 8 => 1} ], + flag_map => [ { 0 => "XM:0,XP:0,XT:UU,XC:2=1X2=1X2=", + 3 => "XM:0,XP:0,XT:UU,XC:2=2X1=3X", + 4 => "XM:0,XP:0,XT:UU,XC:1=2X2=1X2=", + 5 => "XM:0,XP:0,XT:UU,XC:3X2=2X1=", + 7 => "XM:0,XP:0,XT:UU,XC:2=2X1=3X", + 8 => "XM:0,XP:0,XT:UU,XC:2=1X2=1X2="} ], + cigar_map => [ { 0 => "8M", 3 => "8M", 4 => "8M", + 5 => "8M", 7 => "8M", 8 => "8M" } ], + samoptflags_map => [{ + 0 => { "AS:i:-2" => 1, "XS:i:-2" => 1, "NM:i:2" => 1, "XM:i:2" => 1, + "YT:Z:UU" => 1, "MD:Z:2G2C2" => 1 }, + 3 => { "AS:i:-5" => 1, "XS:i:-2" => 1, "NM:i:5" => 1, "XM:i:5" => 1, + "YT:Z:UU" => 1, "MD:Z:2C0G1T0T0G0" => 1 }, + 4 => { "AS:i:-3" => 1, "XS:i:-2" => 1, "NM:i:3" => 1, "XM:i:3" => 1, + "YT:Z:UU" => 1, "MD:Z:1C0G2T2" => 1 }, + 5 => { "AS:i:-5" => 1, "XS:i:-2" => 1, "NM:i:5" => 1, "XM:i:5" => 1, + "YT:Z:UU" => 1, "MD:Z:0C0G0T2G0T1" => 1 }, + 7 => { "AS:i:-5" => 1, "XS:i:-2" => 1, "NM:i:5" => 1, "XM:i:5" => 1, + "YT:Z:UU" => 1, "MD:Z:2T0G1T0C0G0" => 1 }, + 8 => { "AS:i:-2" => 1, "XS:i:-2" => 1, "NM:i:2" => 1, "XM:i:2" => 1, + "YT:Z:UU" => 1, "MD:Z:2G2C2" => 1 }, + }], + }, +); + +## +# Take a list of reference sequences and write them to a temporary +# FASTA file of the given name. +# +sub writeFasta($$) { + my ($l, $fa) = @_; + open(FA, ">$fa") || die "Could not open $fa for writing"; + my $idx = 0; + for(my $i = 0; $i < scalar(@$l); $i++) { + print FA ">$idx\n".$l->[$i]."\n"; + $idx++; + } + close(FA); +} + +## +# Take a lists of named reads/mates and write them to appropriate +# files. +# +sub writeReads($$$$$$$$$) { + my ( + $reads, + $quals, + $mate1s, + $qual1s, + $mate2s, + $qual2s, + $names, + $fq1, + $fq2) = @_; + + open(FQ1, ">$fq1") || die "Could not open '$fq1' for writing"; + open(FQ2, ">$fq2") || die "Could not open '$fq2' for writing"; + my $pe = (defined($mate1s) && $mate1s ne ""); + if($pe) { + for (0..scalar(@$mate1s)-1) { + my $m1 = $mate1s->[$_]; + my $m2 = $mate2s->[$_]; + my $q1 = $qual1s->[$_]; + my $q2 = $qual2s->[$_]; + my $nm = $names->[$_]; + defined($m1) || die; + defined($m2) || die; + $q1 = $q1 || ("I" x length($m1)); + $q2 = $q2 || ("I" x length($m2)); + $nm = $nm || "r$_"; + print FQ1 "\@$nm/1\n$m1\n+\n$q1\n"; + print FQ2 "\@$nm/2\n$m2\n+\n$q2\n"; + } + } else { + for (0..scalar(@$reads)-1) { + my $read = $reads->[$_]; + defined($read) || die; + my $qual = $quals->[$_]; + my $nm = $names->[$_]; + $qual = $qual || ("I" x length($read)); + $nm = $nm || "r$_"; + print FQ1 "\@$nm\n$read\n+\n$qual\n"; + } + } + close(FQ1); + close(FQ2); +} + +## +# Run bowtie2 with given arguments +# +sub runbowtie2($$$$$$$$$$$$$$$$$$$$$) { + + my ( + $do_build, + $args, + $color, + $fa, + $reportargs, #5 + $read_file_format, + $read_file, + $mate1_file, + $mate2_file, + $reads, + $quals, + $mate1s, + $qual1s, + $mate2s, + $qual2s, + $names, + $ls, + $rawls, + $header_ls, + $raw_header_ls, + $should_abort) = @_; + + $args .= " --quiet"; + $reportargs = "-a" unless defined($reportargs); + $args .= " -C" if $color; + $args .= " $reportargs"; + # Write the reference to a fasta file + print "References:\n"; + open(FA, $fa) || die; + while() { print $_; } + close(FA); + if($do_build) { + my $build_args = ($color ? "-C" : ""); + my $cmd = "$bowtie2_build --quiet --sanity $build_args $fa .simple_tests.tmp"; + print "$cmd\n"; + system($cmd); + ($? == 0) || die "Bad exitlevel from bowtie2-build: $?"; + } + my $pe = (defined($mate1s) && $mate1s ne ""); + $pe = $pe || (defined($mate1_file)); + my $mate1arg; + my $mate2arg; + my $readarg; + my $formatarg = "-c"; + my ($readstr, $m1str, $m2str) = (undef, undef, undef); + $readstr = join(",", @$reads) if defined($reads); + $m1str = join(",", @$mate1s) if defined($mate1s); + $m2str = join(",", @$mate2s) if defined($mate2s); + if(defined($read_file) || defined($mate1_file)) { + defined($read_file_format) || die; + my $ext = ""; + if($read_file_format eq "fastq") { + $formatarg = "-q"; + $ext = ".fq"; + } elsif($read_file_format eq "tabbed") { + $formatarg = "--12"; + $ext = ".tab"; + } elsif($read_file_format eq "fasta") { + $formatarg = "-f"; + $ext = ".fa"; + } elsif($read_file_format eq "qseq") { + $formatarg = "--qseq"; + $ext = "_qseq.txt"; + } elsif($read_file_format eq "raw") { + $formatarg = "-r"; + $ext = ".raw"; + } else { + die "Bad format: $read_file_format"; + } + if(defined($read_file)) { + # Unpaired + open(RD, ">.simple_tests$ext") || die; + print RD $read_file; + close(RD); + $readarg = ".simple_tests$ext"; + } else { + defined($mate1_file) || die; + defined($mate2_file) || die; + # Paired + open(M1, ">.simple_tests.1$ext") || die; + print M1 $mate1_file; + close(M1); + open(M2, ">.simple_tests.2$ext") || die; + print M2 $mate2_file; + close(M2); + $mate1arg = ".simple_tests.1$ext"; + $mate2arg = ".simple_tests.2$ext"; + } + } else { + writeReads( + $reads, + $quals, + $mate1s, + $qual1s, + $mate2s, + $qual2s, + $names, + ".simple_tests.1.fq", + ".simple_tests.2.fq"); + $mate1arg = ".simple_tests.1.fq"; + $mate2arg = ".simple_tests.2.fq"; + $formatarg = "-q"; + $readarg = $mate1arg; + } + my $cmd; + if($pe) { + # Paired-end case + $cmd = "$bowtie2 --debug $args .simple_tests.tmp $formatarg -1 $mate1arg -2 $mate2arg"; + } else { + # Unpaired case + $cmd = "$bowtie2 --debug $args .simple_tests.tmp $formatarg $readarg"; + } + print "$cmd\n"; + open(BT, "$cmd |") || die "Could not open pipe '$cmd |'"; + while() { + print $_; + chomp; + if(substr($_, 0, 1) eq "@") { + push @$header_ls, [ split(/\t/, $_, -1) ]; + push @$raw_header_ls, $_; + } else { + push @$ls, [ split(/\t/, $_, -1) ]; + push @$rawls, $_; + } + } + close(BT); + ($? == 0 || $should_abort) || die "bowtie2 aborted with exitlevel $?\n"; + ($? != 0 || !$should_abort) || die "bowtie2 failed to abort!\n"; +} + +## +# Compare a hash ref of expected SAM flags with a hash ref of observed SAM +# flags. +# +sub matchSamOptionalFlags($$) { + my ($flags, $ex_flags) = @_; + my %ex = (); + for(keys %$ex_flags) { + my ($nm, $ty, $vl) = split(/:/, $_); + defined($vl) || die "Could not parse optional flag field \"$_\""; + ($ex{$nm}{ty}, $ex{$nm}{vl}) = ($ty, $vl); + } + for(keys %$flags) { + my ($ex_ty, $ex_vl); + if(defined($ex{$_})) { + ($ex_ty, $ex_vl) = ($ex{$_}{ty}, $ex{$_}{vl}); + } else { + ($ex_ty, $ex_vl) = ("i", "0"); + } + defined($ex_ty) || die; + defined($ex_vl) || die; + my ($ty, $vl) = ($flags->{$_}{ty}, $flags->{$_}{vl}); + defined($ty) || die; + defined($vl) || die; + $ex_ty eq $ty || + die "Expected SAM optional flag $_ to have type $ex_ty, had $ty"; + $ex_vl eq $vl || + die "Expected SAM optional flag $_ to have value $ex_vl, had $vl"; + } + return 1; +} + +my $tmpfafn = ".simple_tests.pl.fa"; +my $last_ref = undef; +for (my $ci = 0; $ci < scalar(@cases); $ci++) { + my $c = $cases[$ci]; + last unless defined($c); + # If there's any skipping of cases to be done, do it here prior to the + # eq_deeply check + my $color = 0; + $color = $c->{color} if defined($c->{color}); + next if ($color && $skipColor); + my $do_build = 0; + unless(defined($last_ref) && eq_deeply($c->{ref}, $last_ref)) { + writeFasta($c->{ref}, $tmpfafn); + $do_build = 1; + } + $last_ref = $c->{ref}; + # For each set of arguments... + my $case_args = $c->{args}; + $case_args = "" unless defined($case_args); + my $first = 1; # did we build the index yet? + # Forward, then reverse-complemented + my $fwlo = ($c->{nofw} ? 1 : 0); + my $fwhi = ($c->{norc} ? 0 : 1); + for(my $fwi = $fwlo; $fwi <= $fwhi; $fwi++) { + my $fw = ($fwi == 0); + my $sam = 1; + + my $reads = $c->{reads}; + my $quals = $c->{quals}; + my $m1s = $c->{mate1s}; + my $q1s = $c->{qual1s}; + my $m2s = $c->{mate2s}; + my $q2s = $c->{qual2s}; + + my $read_file = undef; + my $mate1_file = undef; + my $mate2_file = undef; + + $read_file = $c->{fastq} if defined($c->{fastq}); + $read_file = $c->{tabbed} if defined($c->{tabbed}); + $read_file = $c->{fasta} if defined($c->{fasta}); + $read_file = $c->{qseq} if defined($c->{qseq}); + $read_file = $c->{raw} if defined($c->{raw}); + + $mate1_file = $c->{fastq1} if defined($c->{fastq1}); + $mate1_file = $c->{tabbed1} if defined($c->{tabbed1}); + $mate1_file = $c->{fasta1} if defined($c->{fasta1}); + $mate1_file = $c->{qseq1} if defined($c->{qseq1}); + $mate1_file = $c->{raw1} if defined($c->{raw1}); + + $mate2_file = $c->{fastq2} if defined($c->{fastq2}); + $mate2_file = $c->{tabbed2} if defined($c->{tabbed2}); + $mate2_file = $c->{fasta2} if defined($c->{fasta2}); + $mate2_file = $c->{qseq2} if defined($c->{qseq2}); + $mate2_file = $c->{raw2} if defined($c->{raw2}); + + my $read_file_format = undef; + if(!defined($reads) && !defined($m1s) && !defined($m2s)) { + defined($read_file) || defined($mate1_file) || die; + $read_file_format = "fastq" if defined($c->{fastq}) || defined($c->{fastq1}); + $read_file_format = "tabbed" if defined($c->{tabbed}) || defined($c->{tabbed}); + $read_file_format = "fasta" if defined($c->{fasta}) || defined($c->{fasta1}); + $read_file_format = "qseq" if defined($c->{qseq}) || defined($c->{qseq1}); + $read_file_format = "raw" if defined($c->{raw}) || defined($c->{raw1}); + next unless $fw; + } + # Run bowtie2 + my @lines = (); + my @rawlines = (); + my @header_lines = (); + my @header_rawlines = (); + print $c->{name}." " if defined($c->{name}); + print "(fw:".($fw ? 1 : 0).", sam:$sam)\n"; + my $mate1fw = 1; + my $mate2fw = 0; + $mate1fw = $c->{mate1fw} if defined($c->{mate1fw}); + $mate2fw = $c->{mate2fw} if defined($c->{mate2fw}); + if(!$fw) { + # Reverse-complement the reads + my @s = (); @s = @$reads if defined($reads); + my @q = (); @q = @$quals if defined($quals); + # Reverse-complement mates and switch mate1 with mate2 + my @m1 = (); @m1 = @$m1s if defined($m1s); + my @m2 = (); @m2 = @$m2s if defined($m2s); + my @q1 = (); @q1 = @$q1s if defined($q1s); + my @q2 = (); @q2 = @$q2s if defined($q2s); + for(0..scalar(@s)-1) { + $s[$_] = DNA::revcomp($s[$_], $color); + $q[$_] = reverse $q[$_] if $_ < scalar(@q); + } + if($mate1fw == $mate2fw) { + for(0..$#m1) { $m1[$_] = DNA::revcomp($m1[$_], $color); } + for(0..$#m2) { $m2[$_] = DNA::revcomp($m2[$_], $color); } + for(0..$#q1) { $q1[$_] = reverse $q1[$_]; } + for(0..$#q2) { $q2[$_] = reverse $q2[$_]; } + } + $reads = \@s if defined($reads); + $quals = \@q if defined($quals); + $m1s = \@m2 if defined($m1s); + $q1s = \@q2 if defined($q1s); + $m2s = \@m1 if defined($m2s); + $q2s = \@q1 if defined($q2s); + } + my $a = $case_args; + if(defined($m2s)) { + $a .= " --"; + $a .= ($mate1fw ? "f" : "r"); + $a .= ($mate2fw ? "f" : "r"); + } + runbowtie2( + $do_build && $first, + "$a", + $color, + $tmpfafn, + $c->{report}, + $read_file_format, # formate of read/mate files + $read_file, # read file + $mate1_file, # mate #1 file + $mate2_file, # mate #2 file + $reads, # read list + $quals, # quality list + $m1s, # mate #1 sequence list + $q1s, # mate #1 quality list + $m2s, # mate #2 sequence list + $q2s, # mate #2 quality list + $c->{names}, + \@lines, + \@rawlines, + \@header_lines, + \@header_rawlines, + $c->{should_abort}); + $first = 0; + my $pe = defined($c->{mate1s}) && $c->{mate1s} ne ""; + $pe = $pe || defined($mate1_file); + $pe = $pe || $c->{paired}; + my ($lastchr, $lastoff, $lastoff_orig) = ("", -1, -1); + # Keep temporary copies of hits and pairhits so that we can + # restore for the next orientation + my $hitstmp = []; + $hitstmp = clone($c->{hits}) if defined($c->{hits}); + my $pairhitstmp = []; + $pairhitstmp = clone($c->{pairhits}) if defined($c->{pairhits}); + my $pairhits_orig_tmp = []; + $pairhits_orig_tmp = clone($c->{pairhits_orig}) if defined($c->{pairhits_orig}); + # Record map from already-seen read name, read sequence and + # quality to the place on the reference where it's reported. + # This allows us to check that the pseudo-random generator + # isn't mistakenly yielding different alignments for identical + # reads. + my %seenNameSeqQual = (); + if(defined($c->{lines})) { + my $l = scalar(@lines); + $l == $c->{lines} || die "Expected $c->{lines} lines, got $l"; + } + for my $li (0 .. scalar(@lines)-1) { + my $l = $lines[$li]; + my ($readname, $orient, $chr, $off_orig, $off, $seq, $qual, $mapq, + $oms, $editstr, $flagstr, $samflags, $cigar, $rnext, $pnext, + $tlen); + my %samoptflags = (); + if($sam) { + scalar(@$l) >= 11 || + die "Bad number of fields; expected at least 11 got ". + scalar(@$l).":\n$rawlines[$li]\n"; + ($readname, $samflags, $chr, $off) = @$l[0..3]; + ($seq, $qual) = @$l[9..10]; + $orient = ((($samflags >> 4) & 1) == 0) ? "+" : "-"; + $mapq = $l->[4]; # mapping quality + $cigar = $l->[5]; # CIGAR string + $rnext = $l->[6]; # ref seq of next frag in template + $pnext = $l->[7]; # position of next frag in template + $tlen = $l->[8]; # template length + if($pnext == 0) { $pnext = "*"; } else { $pnext--; } + for(my $m = 11; $m < scalar(@$l); $m++) { + next if $l->[$m] eq ""; + my ($nm, $ty, $vl) = split(/:/, $l->[$m]); + defined($vl) || + die "Could not parse optional flag field $m: ". + "\"$l->[$m]\""; + $samoptflags{$nm}{ty} = $ty; + $samoptflags{$nm}{vl} = $vl; + } + if($off > 0) { $off--; } + else { $off = "*"; } + $off_orig = $off; + $off = "*" if $cigar eq "*"; + } else { + scalar(@$l) == 9 || + die "Bad number of fields; expected 9 got ". + scalar(@$l).":\n$rawlines[$li]\n"; + ($readname, $orient, $chr, $off, $seq, + $qual, $oms, $editstr, $flagstr) = @$l; + $off_orig = $off; + } + if($c->{check_random}) { + my $rsqKey = "$readname\t$orient\t$seq\t$qual"; + my $rsqVal = "$chr\t$off"; + if(defined($seenNameSeqQual{$rsqKey})) { + $seenNameSeqQual{$rsqKey} eq $rsqVal || + die "Two hits for read/seq/qual:\n$rsqKey\n". + "had different alignments:\n". + "$seenNameSeqQual{$rsqKey}\n$rsqVal\n"; + } + $seenNameSeqQual{$rsqKey} = $rsqVal; + } + $readname ne "" || die "readname was blank:\n".Dumper($c); + my $rdi = $readname; + $rdi = substr($rdi, 1) if substr($rdi, 0, 1) eq "r"; + my $mate = 0; + if($readname =~ /\//) { + ($rdi, $mate) = split(/\//, $readname); + defined($rdi) || die; + } + $rdi = $c->{idx_map}{$rdi} if defined($c->{idx_map}{$rdi}); + $rdi ne "" || die "rdi was blank:\nreadname=$readname\n".Dumper($c); + if($rdi != int($rdi)) { + # Read name has non-numeric characters. Figure out + # what number it is by scanning the names list. + my $found = 0; + for(my $i = 0; $i < scalar(@{$c->{names}}); $i++) { + if($c->{names}->[$i] eq $readname) { + $rdi = $i; + $found = 1; + last; + } + } + $found || die "No specified name matched reported name $readname"; + } + # Check that the sequence printed in the alignment is sane + if($color) { + # It's a decoded nucleotide sequence + my $dseq = $c->{dec_seq}->[$rdi]; + if(defined($dseq)) { + $seq eq $dseq || die "Expected decoded sequence '$seq' from alignment to match '$dseq'"; + } + my $dqual = $c->{dec_qual}->[$rdi]; + if(defined($dqual)) { + $qual eq $dqual || die "Expected decoded qualities '$qual' from alignment to match '$dqual'"; + } + } else { + + } + # Make simply-named copies of some portions of the test case + # 'hits' + my %hits = (); + %hits = %{$c->{hits}->[$rdi]} if + defined($c->{hits}->[$rdi]); + # 'flags' + my $flags = undef; + $flags = $c->{flags}->[$rdi] if + defined($c->{flags}->[$rdi]); + # 'samflags' + my $ex_samflags = undef; + $ex_samflags = $c->{ex_samflags}->[$rdi] if + defined($c->{ex_samflags}->[$rdi]); + # 'samflags_map' + my $ex_samflags_map = undef; + $ex_samflags_map = $c->{samflags_map}->[$rdi] if + defined($c->{samflags_map}->[$rdi]); + # 'samoptflags' + my $ex_samoptflags = undef; + $ex_samoptflags = $c->{samoptflags}->[$rdi] if + defined($c->{samoptflags}->[$rdi]); + # 'cigar' + my $ex_cigar = undef; + $ex_cigar = $c->{cigar}->[$rdi] if + defined($c->{cigar}->[$rdi]); + # 'cigar_map' + my $ex_cigar_map = undef; + $ex_cigar_map = $c->{cigar_map}->[$rdi] if + defined($c->{cigar_map}->[$rdi]); + # 'mapq_hi' - boolean indicating whether mapq is hi/lo + my $ex_mapq_hi = undef; + $ex_mapq_hi = $c->{mapq_hi}->[$rdi] if + defined($c->{mapq_hi}->[$rdi]); + # 'mapq' + my $ex_mapq = undef; + $ex_mapq = $c->{mapq}->[$rdi] if + defined($c->{mapq}->[$rdi]); + # 'mapq_map' + my $ex_mapq_map = undef; + $ex_mapq_map = $c->{mapq_map}->[$rdi] if + defined($c->{mapq_map}->[$rdi]); + # 'rnext_map' + my $ex_rnext_map = undef; + $ex_rnext_map = $c->{rnext_map}->[$rdi] if + defined($c->{rnext_map}) && defined($c->{rnext_map}->[$rdi]); + # 'pnext_map' + my $ex_pnext_map = undef; + $ex_pnext_map = $c->{pnext_map}->[$rdi] if + defined($c->{pnext_map}) && defined($c->{pnext_map}->[$rdi]); + # 'tlen_map' + my $ex_tlen_map = undef; + $ex_tlen_map = $c->{tlen_map}->[$rdi] if + defined($c->{tlen_map}) && defined($c->{tlen_map}->[$rdi]); + # 'flags_fw' + my $flags_fw = undef; + $flags_fw = $c->{flags_fw}->[$rdi] if + defined($c->{flags_fw}->[$rdi]); + # 'flags_rc' + my $flags_rc = undef; + $flags_rc = $c->{flags_rc}->[$rdi] if + defined($c->{flags_rc}->[$rdi]); + # 'pairhits' + my %pairhits = (); + %pairhits = %{$c->{pairhits}->[$rdi]} if + defined($c->{pairhits}->[$rdi]); + # 'pairhits_orig' + my %pairhits_orig = (); + %pairhits_orig = %{$c->{pairhits_orig}->[$rdi]} if + defined($c->{pairhits_orig}->[$rdi]); + # 'pairflags' + my %pairflags = (); + %pairflags = %{$c->{pairflags}->[$rdi]} if + defined($c->{pairflags}->[$rdi]); + # 'hits_are_superset' + my $hits_are_superset = 0; + $hits_are_superset = $c->{hits_are_superset}->[$rdi] if + defined($ci); + # edits + my $ex_edits = undef; + $ex_edits = $c->{edits}->[$rdi] if + defined($c->{edits}->[$rdi]); + if(!$sam) { + # Bowtie flags + if(defined($flags)) { + $flagstr eq $flags || + die "Expected flags=\"$flags\", got \"$flagstr\""; + } + if(defined($flags_fw) && $fw) { + $flagstr eq $flags_fw || + die "Expected flags=\"$flags_fw\", got \"$flagstr\""; + } + if(defined($flags_rc) && !$fw) { + $flagstr eq $flags_rc || + die "Expected flags=\"$flags_rc\", got \"$flagstr\""; + } + if(defined($c->{flag_map})) { + if(defined($c->{flag_map}->[$rdi]->{$off})) { + $flagstr eq $c->{flag_map}->[$rdi]->{$off} || + die "Expected flags=\"$c->{flag_map}->[$rdi]->{$off}\"". + " at offset $off, got \"$flagstr\""; + } + } + } + if($sam) { + # SAM flags + if(defined($ex_samflags)) { + $samflags eq $ex_samflags || + die "Expected flags $ex_samflags, got $samflags"; + } + if(defined($ex_samflags_map)) { + if(defined($c->{samflags_map}->[$rdi]->{$off})) { + my $ex = $c->{samflags_map}->[$rdi]->{$off}; + $samflags eq $ex || die + "Expected FLAGS value $ex at offset $off, got $samflags" + } else { + die "Expected to see alignment with offset $off parsing samflags_map"; + } + } + # CIGAR string + if(defined($ex_cigar)) { + $cigar eq $ex_cigar || + die "Expected CIGAR string $ex_cigar, got $cigar"; + } + if(defined($ex_cigar_map)) { + if(defined($c->{cigar_map}->[$rdi]->{$off})) { + my $ex = $c->{cigar_map}->[$rdi]->{$off}; + $cigar eq $ex || die + "Expected CIGAR string $ex at offset $off, got $cigar" + } else { + die "Expected to see alignment with offset $off parsing cigar_map"; + } + } + # MAPQ + if(defined($ex_mapq)) { + $mapq eq $ex_mapq || + die "Expected MAPQ $ex_mapq, got $mapq"; + } + if(defined($ex_mapq_map)) { + if(defined($c->{mapq_map}->[$rdi]->{$off})) { + my $ex = $c->{mapq_map}->[$rdi]->{$off}; + $mapq eq $ex || die + "Expected MAPQ string $ex at offset $off, got $mapq" + } else { + die "Expected to see alignment with offset $off parsing mapq_map"; + } + } + # MAPQ + if(defined($ex_mapq_hi)) { + if($ex_mapq_hi == 0) { + $mapq < 20 || die "Expected MAPQ < 20, got $mapq"; + } else { + $mapq >= 20 || die "Expected MAPQ >= 20, got $mapq"; + } + } + if(defined($ex_mapq_map)) { + if(defined($c->{mapq_map}->[$rdi]->{$off})) { + my $ex = $c->{mapq_map}->[$rdi]->{$off}; + $mapq eq $ex || die + "Expected MAPQ string $ex at offset $off, got $mapq" + } else { + die "Expected to see alignment with offset $off parsing mapq_map"; + } + } + # SAM optional flags + if(defined($ex_samoptflags)) { + matchSamOptionalFlags(\%samoptflags, $ex_samoptflags); + } + if(defined($c->{samoptflags_map})) { + if(defined($c->{samoptflags_map}->[$rdi]->{$off})) { + matchSamOptionalFlags( + \%samoptflags, + $c->{samoptflags_map}->[$rdi]->{$off}); + } else { + die "Expected to see alignment with offset $off parsing samoptflags_map"; + } + } + if(defined($c->{samoptflags_flagmap})) { + if(defined($c->{samoptflags_flagmap}->[$rdi]->{$samflags})) { + matchSamOptionalFlags( + \%samoptflags, + $c->{samoptflags_flagmap}->[$rdi]->{$samflags}); + } else { + die "Expected to see alignment with flag $samflags parsing samoptflags_flagmap"; + } + } + # RNEXT map + if(defined($c->{rnext_map})) { + if(defined($c->{rnext_map}->[$rdi]->{$off})) { + my $ex = $c->{rnext_map}->[$rdi]->{$off}; + $rnext eq $ex || die + "Expected RNEXT '$ex' at offset $off, got '$rnext'" + } else { + die "Expected to see alignment with offset $off parsing rnext_map".Dumper($c); + } + } + # PNEXT map + if(defined($c->{pnext_map})) { + if(defined($c->{pnext_map}->[$rdi]->{$off})) { + my $ex = $c->{pnext_map}->[$rdi]->{$off}; + $pnext eq $ex || die + "Expected PNEXT '$ex' at offset $off, got '$pnext'" + } else { + die "Expected to see alignment with offset $off parsing pnext_map"; + } + } + # TLEN map + if(defined($c->{tlen_map})) { + if(defined($c->{tlen_map}->[$rdi]->{$off})) { + my $ex = $c->{tlen_map}->[$rdi]->{$off}; + $tlen eq $ex || die + "Expected TLEN '$ex' at offset $off, got '$tlen'" + } else { + die "Expected to see alignment with offset $off parsing tlen_map"; + } + } + } + if($pe && $lastchr ne "") { + my $offkey_orig = $lastoff.",".$off_orig; + $offkey_orig = $off_orig.",".$lastoff_orig if $off_orig eq "*"; + + my $offkey = $lastoff.",".$off; + $offkey = $off.",".$lastoff if $off eq "*"; + + if($lastoff ne "*" && $off ne "*") { + $offkey = min($lastoff, $off).",".max($lastoff, $off); + } + if(defined($c->{pairhits}->[$rdi])) { + defined($pairhits{$offkey}) || + die "No such paired off as $offkey in pairhits list: ".Dumper(\%pairhits)."\n"; + $c->{pairhits}->[$rdi]->{$offkey}--; + delete $c->{pairhits}->[$rdi]->{$offkey} if $c->{pairhits}->[$rdi]->{$offkey} == 0; + %pairhits = %{$c->{pairhits}->[$rdi]}; + } + if(defined($c->{pairhits_orig}->[$rdi])) { + defined($pairhits_orig{$offkey_orig}) || + die "No such paired off as $offkey in pairhits_orig list: ".Dumper(\%pairhits_orig)."\n"; + $c->{pairhits_orig}->[$rdi]->{$offkey_orig}--; + delete $c->{pairhits_orig}->[$rdi]->{$offkey_orig} if $c->{pairhits_orig}->[$rdi]->{$offkey_orig} == 0; + %pairhits_orig = %{$c->{pairhits_orig}->[$rdi]}; + } + ($lastchr, $lastoff, $lastoff_orig) = ("", -1, -1); + } elsif($pe) { + # Found an unpaired alignment from aligning a pair + my $foundSe = + defined($c->{pairhits}->[$rdi]) && + $c->{pairhits}->[$rdi]->{$off}; + if($foundSe) { + $c->{pairhits}->[$rdi]->{$off}--; + delete $c->{pairhits}->[$rdi]->{$off} + if $c->{pairhits}->[$rdi]->{$off} == 0; + %pairhits = %{$c->{pairhits}->[$rdi]}; + } else { + ($lastchr, $lastoff) = ($chr, $off); + } + # Found an unpaired alignment from aligning a pair + $foundSe = + defined($c->{pairhits_orig}->[$rdi]) && + $c->{pairhits_orig}->[$rdi]->{$off_orig}; + if($foundSe) { + $c->{pairhits_orig}->[$rdi]->{$off_orig}--; + delete $c->{pairhits_orig}->[$rdi]->{$off_orig} + if $c->{pairhits_orig}->[$rdi]->{$off_orig} == 0; + %pairhits_orig = %{$c->{pairhits_orig}->[$rdi]}; + } else { + ($lastchr, $lastoff, $lastoff_orig) = ($chr, $off, $off_orig); + } + } else { + if(defined($c->{hits}->[$rdi])) { + defined($hits{$off}) || + die "No such off as $off in hits list: ".Dumper(\%hits)."\n"; + $c->{hits}->[$rdi]->{$off}--; + delete $c->{hits}->[$rdi]->{$off} if $c->{hits}->[$rdi]->{$off} == 0; + %hits = %{$c->{hits}->[$rdi]}; + } + } + if(!$sam && defined($ex_edits)) { + my $eds = $l->[7]; + $eds eq $ex_edits || + die "For edit string, expected \"$ex_edits\" got \"$eds\"\n"; + } + } + # Go through all the per-read + my $klim = 0; + $klim = scalar(@{$c->{hits}}) if defined($c->{hits}); + $klim = max($klim, scalar(@{$c->{pairhits}})) if defined($c->{pairhits}); + for (my $k = 0; $k < $klim; $k++) { + # For each read + my %hits = %{$c->{hits}->[$k]} if defined($c->{hits}->[$k]); + my %pairhits = %{$c->{pairhits}->[$k]} if defined($c->{pairhits}->[$k]); + my %pairhits_orig = %{$c->{pairhits_orig}->[$k]} if defined($c->{pairhits_orig}->[$k]); + my $hits_are_superset = $c->{hits_are_superset}->[$k]; + # Check if there are any hits left over + my $hitsLeft = scalar(keys %hits); + if($hitsLeft != 0 && !$hits_are_superset) { + print Dumper(\%hits); + die "Had $hitsLeft hit(s) left over at position $k"; + } + my $pairhitsLeft = scalar(keys %pairhits); + if($pairhitsLeft != 0 && !$hits_are_superset) { + print Dumper(\%pairhits); + die "Had $pairhitsLeft hit(s) left over at position $k"; + } + my $pairhits_orig_Left = scalar(keys %pairhits_orig); + if($pairhits_orig_Left != 0 && !$hits_are_superset) { + print Dumper(\%pairhits_orig); + die "Had $pairhits_orig_Left hit(s) left over at position $k"; + } + } + + $c->{hits} = $hitstmp; + $c->{pairhits} = $pairhitstmp; + $c->{pairhits_orig} = $pairhits_orig_tmp; + } + $last_ref = undef if $first; +} +print "PASSED\n"; diff --git a/scripts/test/simple_tests.sh b/scripts/test/simple_tests.sh new file mode 100644 index 0000000..0ba1cb0 --- /dev/null +++ b/scripts/test/simple_tests.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +# +# Copyright 2011, Ben Langmead +# +# This file is part of Bowtie 2. +# +# Bowtie 2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bowtie 2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bowtie 2. If not, see . +# + +# simple_tests.sh + +make $* bowtie2-align bowtie2-align-debug bowtie2-build bowtie2-build-debug && \ +perl scripts/test/simple_tests.pl \ + --bowtie2=./bowtie2 \ + --bowtie2-build=./bowtie2-build-debug diff --git a/scripts/validate_repeat.py b/scripts/validate_repeat.py new file mode 100644 index 0000000..70c469c --- /dev/null +++ b/scripts/validate_repeat.py @@ -0,0 +1,230 @@ +#!/usr/bin/python +import sys, subprocess +import re +from argparse import ArgumentParser, FileType +from collections import defaultdict, Counter + +flag_include_N = True + +""" +""" +def read_genome(genome_file): + chr_dic = {} + chr_name, sequence = "", "" + for line in genome_file: + if line.startswith(">"): + if chr_name and sequence: + chr_dic[chr_name] = sequence + chr_name = line.strip().split()[0][1:] + sequence = "" + else: + line = line.strip() + if not flag_include_N: + # remove N-bases + line = line.replace('N', '') + + sequence += line; + + if chr_name and sequence: + chr_dic[chr_name] = sequence + return chr_dic + +""" +""" +def reverse_complement(seq): + result = "" + for nt in seq: + base = nt + if nt == 'A': + base = 'T' + elif nt == 'a': + base = 't' + elif nt == 'C': + base = 'G' + elif nt == 'c': + base = 'g' + elif nt == 'G': + base = 'C' + elif nt == 'g': + base = 'c' + elif nt == 'T': + base = 'A' + elif nt == 't': + base = 'a' + + result = base + result + + return result + + +""" +""" +def read_snp(snp_file): + snps = defaultdict(dict) + for line in snp_file: + line = line.strip() + if not line or line.startswith('#'): + continue + try: + snpID, type, chr, pos, data = line.split('\t') + except ValueError: + continue + + assert type in ["single", "deletion", "insertion"] + if type == "deletion": + data = int(data) + + snps[chr][snpID] = [snpID, type, int(pos), data]; + + return snps + + +def indelCount(snp_list, snp_id_list): + indel = 0 + + for snp_id in snp_id_list: + snp = snp_list[snp_id] + + if snp[1] == 'deletion': + indel -= int(snp[3]) + elif snp[1] == 'insertion': + indel += len(snp[3]) + + return indel + +def applySNPs(snp_list, ref_sqn, snp_id_list, base_pos): + + ref_pos = 0 + read_pos = 0 + read = "" + + for snp_id in snp_id_list: + snp = snp_list[snp_id] + + pos = snp[2] - base_pos; + + while ref_pos < pos: + read += ref_sqn[ref_pos] + ref_pos += 1 + + + if snp[1] == 'single': + read += snp[3] + ref_pos += 1 + elif snp[1] == 'deletion': + ref_pos += int(snp[3]) + elif snp[1] == 'insertion': + read += snp[3] + + #print snp_id, snp_list[snp_id] + + while ref_pos < len(ref_sqn): + read += ref_sqn[ref_pos] + ref_pos += 1 + + return read + + +def main(genome_file, rpt_name): + # load genome sequeuce + chr_dic = read_genome(genome_file) + + rpt_fa_name = rpt_name + ".rep.fa" + rpt_info_name = rpt_name + ".rep.info" + rpt_snp_name = rpt_name + ".rep.snp" + + # load repeat sequence + fp = open(rpt_fa_name, 'r') + rpt_dic = read_genome(fp) + fp.close() + + # load repeat snp + fp = open(rpt_snp_name, 'r') + rpt_snps = read_snp(fp) + fp.close() + + # Validates + # load repeat info + fp = open(rpt_info_name, 'r') + repeat_sequence = "" + repeat_length = 0 + snp_cnt = 0 + indel = 0 + snp_id_list = [] + + for line in fp: + line = line.strip() + + if line.startswith('>'): + line = line[1:] + fields = line.split() + + #print fields + + name, rpt_seq_name, rpt_pos, rpt_len, pos_cnt, snp_cnt = fields[0:6] + + snp_cnt = int(snp_cnt) + rpt_pos = int(rpt_pos) + rpt_len = int(rpt_len) + + if snp_cnt > 0: + snp_id_list = fields[6].split(',') + else: + snp_id_list = [] + + #print name, snp_cnt, snp_list + + # make repeat_sequence (with snp) + + + repeat_sequence = rpt_dic[rpt_seq_name][rpt_pos:rpt_pos + rpt_len] + indel = 0 + + if snp_cnt > 0: + # apply snps + repeat_sequence = applySNPs(rpt_snps[rpt_seq_name], repeat_sequence, snp_id_list, rpt_pos) + # in/del count + indel = indelCount(rpt_snps[rpt_seq_name], snp_id_list) + + #repeat_length = rpt_len + indel + repeat_length = len(repeat_sequence) + + #print repeat_sequence + + else: + coords = line.split() + for coord in coords: + chr, pos, strand = coord.split(':') + pos = int(pos) + + # get string + seq = chr_dic[chr][pos:pos + repeat_length] + if strand == '-': + seq = reverse_complement(seq) + + if seq != repeat_sequence: + print 'Mismatch', seq, repeat_sequence, snp_cnt, coord, snp_id_list, repeat_length + + fp.close() + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Validate repeat files') + + parser.add_argument('genome_file', + nargs='?', + type=FileType('r'), + help='input genome file (e.g. genome.fa)') + + parser.add_argument('-r', + dest='rpt_name', + type=str, + help='Repeat Name') + + args = parser.parse_args() + if not args.genome_file or not args.rpt_name: + parser.print_help() + exit(1) + + main(args.genome_file, args.rpt_name) diff --git a/search_globals.h b/search_globals.h new file mode 100644 index 0000000..bd2704f --- /dev/null +++ b/search_globals.h @@ -0,0 +1,48 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SEARCH_GLOBALS_H_ +#define SEARCH_GLOBALS_H_ + +#include + +// declared in ebwt_search.cpp +extern bool gColor; +extern bool gColorExEnds; +extern bool gReportOverhangs; +extern bool gColorSeq; +extern bool gColorEdit; +extern bool gColorQual; +extern bool gNoMaqRound; +extern bool gStrandFix; +extern bool gRangeMode; +extern int gVerbose; +extern int gQuiet; +extern bool gNofw; +extern bool gNorc; +extern bool gMate1fw; +extern bool gMate2fw; +extern int gMinInsert; +extern int gMaxInsert; +extern int gTrim5; +extern int gTrim3; +extern int gGapBarrier; +extern int gAllowRedundant; + +#endif /* SEARCH_GLOBALS_H_ */ diff --git a/sequence_io.h b/sequence_io.h new file mode 100644 index 0000000..5a2cd6f --- /dev/null +++ b/sequence_io.h @@ -0,0 +1,125 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SEQUENCE_IO_H_ +#define SEQUENCE_IO_H_ + +#include +#include +#include +#include +#include "assert_helpers.h" +#include "ds.h" +#include "filebuf.h" +#include "sstring.h" + +using namespace std; + +/** + * Parse the fasta file 'infile'. Store + */ +template +static void parseFastaLens( + const TFnStr& infile, // filename + EList& namelens, // destination for fasta name lengths + EList& seqlens) // destination for fasta sequence lengths +{ + FILE *in = fopen(sstr_to_cstr(infile), "r"); + if(in == NULL) { + cerr << "Could not open sequence file" << endl; + throw 1; + } + FileBuf fb(in); + while(!fb.eof()) { + namelens.expand(); namelens.back() = 0; + seqlens.expand(); seqlens.back() = 0; + fb.parseFastaRecordLength(namelens.back(), seqlens.back()); + if(seqlens.back() == 0) { + // Couldn't read a record. We're probably done with this file. + namelens.pop_back(); + seqlens.pop_back(); + continue; + } + } + fb.close(); +} + +/** + * Parse the fasta file 'infile'. Store each name record in 'names', each + * sequence record in 'seqs', and the lengths of each + */ +template +static void parseFasta( + const TFnStr& infile, // filename + EList& names, // destination for fasta names + EList& namelens, // destination for fasta name lengths + EList& seqs, // destination for fasta sequences + EList& seqlens) // destination for fasta sequence lengths +{ + assert_eq(namelens.size(), seqlens.size()); + assert_eq(names.size(), namelens.size()); + assert_eq(seqs.size(), seqlens.size()); + size_t cur = namelens.size(); + parseFastaLens(infile, namelens, seqlens); + FILE *in = fopen(sstr_to_cstr(infile), "r"); + if(in == NULL) { + cerr << "Could not open sequence file" << endl; + throw 1; + } + FileBuf fb(in); + while(!fb.eof()) { + // Add a new empty record to the end + names.expand(); + seqs.expand(); + names.back() = new char[namelens[cur]+1]; + seqs.back() = new char[seqlens[cur]+1]; + fb.parseFastaRecord(names.back(), seqs.back()); + if(seqs.back().empty()) { + // Couldn't read a record. We're probably done with this file. + names.pop_back(); + seqs.pop_back(); + continue; + } + } + fb.close(); +} + +/** + * Read a set of FASTA sequence files of the given format and alphabet type. + * Store all of the extracted sequences in vector ss. + */ +template +static void parseFastas( + const EList& infiles, // filenames + EList& names, // destination for fasta names + EList& namelens, // destination for fasta name lengths + EList& seqs, // destination for fasta sequences + EList& seqlens) // destination for fasta sequence lengths +{ + for(size_t i = 0; i < infiles.size(); i++) { + parseFasta( + infiles[i], + names, + namelens, + seqs, + seqlens); + } +} + +#endif /*SEQUENCE_IO_H_*/ diff --git a/shmem.cpp b/shmem.cpp new file mode 100644 index 0000000..a4853e7 --- /dev/null +++ b/shmem.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifdef BOWTIE_SHARED_MEM + +#include +#include +#include +#include +#include +#include "shmem.h" + +using namespace std; + +/** + * Notify other users of a shared-memory chunk that the leader has + * finished initializing it. + */ +void notifySharedMem(void *mem, size_t len) { + ((volatile uint32_t*)((char*)mem + len))[0] = SHMEM_INIT; +} + +/** + * Wait until the leader of a shared-memory chunk has finished + * initializing it. + */ +void waitSharedMem(void *mem, size_t len) { + while(((volatile uint32_t*)((char*)mem + len))[0] != SHMEM_INIT) { + sleep(1); + } +} + +#endif diff --git a/shmem.h b/shmem.h new file mode 100644 index 0000000..b36f3ad --- /dev/null +++ b/shmem.h @@ -0,0 +1,161 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SHMEM_H_ +#define SHMEM_H_ + +#ifdef BOWTIE_SHARED_MEM + +#include +#include +#include +#include +#include +#include +#include +#include "str_util.h" +#include "btypes.h" + +extern void notifySharedMem(void *mem, size_t len); + +extern void waitSharedMem(void *mem, size_t len); + +#define ALLOC_SHARED_U allocSharedMem +#define ALLOC_SHARED_U8 allocSharedMem +#define ALLOC_SHARED_U32 allocSharedMem +#define FREE_SHARED shmdt +#define NOTIFY_SHARED notifySharedMem +#define WAIT_SHARED waitSharedMem + +#define SHMEM_UNINIT 0xafba4242 +#define SHMEM_INIT 0xffaa6161 + +/** + * Tries to allocate a shared-memory chunk for a given file of a given size. + */ +template +bool allocSharedMem(std::string fname, + size_t len, + T ** dst, + const char *memName, + bool verbose) +{ + using namespace std; + int shmid = -1; + // Calculate key given string + key_t key = (key_t)hash_string(fname); + shmid_ds ds; + int ret; + // Reserve 4 bytes at the end for silly synchronization + size_t shmemLen = len + 4; + if(verbose) { + cerr << "Reading " << len << "+4 bytes into shared memory for " << memName << endl; + } + T *ptr = NULL; + while(true) { + // Create the shrared-memory block + if((shmid = shmget(key, shmemLen, IPC_CREAT | 0666)) < 0) { + if(errno == ENOMEM) { + cerr << "Out of memory allocating shared area " << memName << endl; + } else if(errno == EACCES) { + cerr << "EACCES" << endl; + } else if(errno == EEXIST) { + cerr << "EEXIST" << endl; + } else if(errno == EINVAL) { + cerr << "Warning: shared-memory chunk's segment size doesn't match expected size (" << (shmemLen) << ")" << endl + << "Deleteing old shared memory block and trying again." << endl; + shmid = shmget(key, 0, 0); + if((ret = shmctl(shmid, IPC_RMID, &ds)) < 0) { + cerr << "shmctl returned " << ret + << " for IPC_RMID, errno is " << errno + << ", shmid is " << shmid << endl; + throw 1; + } else { + cerr << "Deleted shared mem chunk with shmid " << shmid << endl; + } + continue; + } else if(errno == ENOENT) { + cerr << "ENOENT" << endl; + } else if(errno == ENOSPC) { + cerr << "ENOSPC" << endl; + } else { + cerr << "shmget returned " << shmid << " for and errno is " << errno << endl; + } + throw 1; + } + ptr = (T*)shmat(shmid, 0, 0); + if(ptr == (void*)-1) { + cerr << "Failed to attach " << memName << " to shared memory with shmat()." << endl; + throw 1; + } + if(ptr == NULL) { + cerr << memName << " pointer returned by shmat() was NULL." << endl; + throw 1; + } + // Did I create it, or did I just attach to one created by + // another process? + if((ret = shmctl(shmid, IPC_STAT, &ds)) < 0) { + cerr << "shmctl returned " << ret << " for IPC_STAT and errno is " << errno << endl; + throw 1; + } + if(ds.shm_segsz != shmemLen) { + cerr << "Warning: shared-memory chunk's segment size (" << ds.shm_segsz + << ") doesn't match expected size (" << shmemLen << ")" << endl + << "Deleteing old shared memory block and trying again." << endl; + if((ret = shmctl(shmid, IPC_RMID, &ds)) < 0) { + cerr << "shmctl returned " << ret << " for IPC_RMID and errno is " << errno << endl; + throw 1; + } + } else { + break; + } + } // while(true) + *dst = ptr; + bool initid = (((volatile uint32_t*)((char*)ptr + len))[0] == SHMEM_INIT); + if(ds.shm_cpid == getpid() && !initid) { + if(verbose) { + cerr << " I (pid = " << getpid() << ") created the " + << "shared memory for " << memName << endl; + } + // Set this value just off the end of the chunk to + // indicate that the data hasn't been read yet. + ((volatile uint32_t*)((char*)ptr + len))[0] = SHMEM_UNINIT; + return true; + } else { + if(verbose) { + cerr << " I (pid = " << getpid() + << ") did not create the shared memory for " + << memName << ". Pid " << ds.shm_cpid << " did." << endl; + } + return false; + } +} + +#else + +#define ALLOC_SHARED_U(...) 0 +#define ALLOC_SHARED_U8(...) 0 +#define ALLOC_SHARED_U32(...) 0 +#define FREE_SHARED(...) +#define NOTIFY_SHARED(...) +#define WAIT_SHARED(...) + +#endif /*BOWTIE_SHARED_MEM*/ + +#endif /* SHMEM_H_ */ diff --git a/simple_func.cpp b/simple_func.cpp new file mode 100644 index 0000000..a5b0859 --- /dev/null +++ b/simple_func.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include +#include "simple_func.h" +#include "ds.h" +#include "mem_ids.h" + +int SimpleFunc::parseType(const std::string& otype) { + string type = otype; + if(type == "C" || type == "Constant") { + return SIMPLE_FUNC_CONST; + } else if(type == "L" || type == "Linear") { + return SIMPLE_FUNC_LINEAR; + } else if(type == "S" || type == "Sqrt") { + return SIMPLE_FUNC_SQRT; + } else if(type == "G" || type == "Log") { + return SIMPLE_FUNC_LOG; + } + std::cerr << "Error: Bad function type '" << otype.c_str() + << "'. Should be C (constant), L (linear), " + << "S (square root) or G (natural log)." << std::endl; + throw 1; +} + +SimpleFunc SimpleFunc::parse( + const std::string& s, + double defaultConst, + double defaultLinear, + double defaultMin, + double defaultMax) +{ + // Separate value into comma-separated tokens + EList ctoks(MISC_CAT); + string ctok; + istringstream css(s); + SimpleFunc fv; + while(getline(css, ctok, ',')) { + ctoks.push_back(ctok); + } + if(ctoks.size() >= 1) { + fv.setType(parseType(ctoks[0])); + } + if(ctoks.size() >= 2) { + double co; + istringstream tmpss(ctoks[1]); + tmpss >> co; + fv.setConst(co); + } else { + fv.setConst(defaultConst); + } + if(ctoks.size() >= 3) { + double ce; + istringstream tmpss(ctoks[2]); + tmpss >> ce; + fv.setCoeff(ce); + } else { + fv.setCoeff(defaultLinear); + } + if(ctoks.size() >= 4) { + double mn; + istringstream tmpss(ctoks[3]); + tmpss >> mn; + fv.setMin(mn); + } else { + fv.setMin(defaultMin); + } + if(ctoks.size() >= 5) { + double mx; + istringstream tmpss(ctoks[4]); + tmpss >> mx; + fv.setMax(mx); + } else { + fv.setMax(defaultMax); + } + return fv; +} diff --git a/simple_func.h b/simple_func.h new file mode 100644 index 0000000..ca76869 --- /dev/null +++ b/simple_func.h @@ -0,0 +1,125 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SIMPLE_FUNC_H_ +#define SIMPLE_FUNC_H_ + +#include +#include +#include +#include "tokenize.h" + +#define SIMPLE_FUNC_CONST 1 +#define SIMPLE_FUNC_LINEAR 2 +#define SIMPLE_FUNC_SQRT 3 +#define SIMPLE_FUNC_LOG 4 + +/** + * A simple function of one argument, parmeterized by I, X, C and L: min + * value, max value, constant term, and coefficient respectively: + * + * 1. Constant: f(x) = max(I, min(X, C + L * 0)) + * 2. Linear: f(x) = max(I, min(X, C + L * x)) + * 3. Square root: f(x) = max(I, min(X, C + L * sqrt(x))) + * 4. Log: f(x) = max(I, min(X, C + L * ln(x))) + * + * Clearly, the return value of the Constant function doesn't depend on x. + */ +class SimpleFunc { + +public: + + SimpleFunc() : type_(0), I_(0.0), X_(0.0), C_(0.0), L_(0.0) { } + + SimpleFunc(int type, double I, double X, double C, double L) { + init(type, I, X, C, L); + } + + void init(int type, double I, double X, double C, double L) { + type_ = type; I_ = I; X_ = X; C_ = C; L_ = L; + } + + void init(int type, double C, double L) { + type_ = type; C_ = C; L_ = L; + I_ = -std::numeric_limits::max(); + X_ = std::numeric_limits::max(); + } + + void setType (int type ) { type_ = type; } + void setMin (double mn) { I_ = mn; } + void setMax (double mx) { X_ = mx; } + void setConst(double co) { C_ = co; } + void setCoeff(double ce) { L_ = ce; } + + int getType () const { return type_; } + double getMin () const { return I_; } + double getMax () const { return X_; } + double getConst() const { return C_; } + double getCoeff() const { return L_; } + + void mult(double x) { + if(I_ < std::numeric_limits::max()) { + I_ *= x; X_ *= x; C_ *= x; L_ *= x; + } + } + + bool initialized() const { return type_ != 0; } + void reset() { type_ = 0; } + + template + T f(double x) const { + assert(type_ >= SIMPLE_FUNC_CONST && type_ <= SIMPLE_FUNC_LOG); + double X; + if(type_ == SIMPLE_FUNC_CONST) { + X = 0.0; + } else if(type_ == SIMPLE_FUNC_LINEAR) { + X = x; + } else if(type_ == SIMPLE_FUNC_SQRT) { + X = sqrt(x); + } else if(type_ == SIMPLE_FUNC_LOG) { + X = log(x); + } else { + throw 1; + } + double ret = std::max(I_, std::min(X_, C_ + L_ * X)); + if(ret == std::numeric_limits::max()) { + return std::numeric_limits::max(); + } else if(ret == std::numeric_limits::min()) { + return std::numeric_limits::min(); + } else { + return (T)ret; + } + } + + static int parseType(const std::string& otype); + + static SimpleFunc parse( + const std::string& s, + double defaultConst = 0.0, + double defaultLinear = 0.0, + double defaultMin = 0.0, + double defaultMax = std::numeric_limits::max()); + +protected: + + int type_; + double I_, X_, C_, L_; +}; + +#endif /*ndef SIMPLE_FUNC_H_*/ diff --git a/splice_site.cpp b/splice_site.cpp new file mode 100644 index 0000000..069b2df --- /dev/null +++ b/splice_site.cpp @@ -0,0 +1,850 @@ +/* + * Copyright 2013, Daehwan Kim + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "edit.h" +#include "splice_site.h" +#include "aligner_report.h" +#include "aligner_result.h" + +#if defined(NEW_PROB_MODEL) + +#include "splice_site_mem.h" + +#else + +float donor_prob[4][donor_len] = { + {0.340f, 0.604f, 0.092f, 0.001f, 0.001f, 0.526f, 0.713f, 0.071f, 0.160f}, + {0.363f, 0.129f, 0.033f, 0.001f, 0.001f, 0.028f, 0.076f, 0.055f, 0.165f}, + {0.183f, 0.125f, 0.803f, 1.000f, 0.001f, 0.419f, 0.118f, 0.814f, 0.209f}, + {0.114f, 0.142f, 0.073f, 0.001f, 1.000f, 0.025f, 0.093f, 0.059f, 0.462f} +}; + +float acceptor_prob[4][acceptor_len] = { + {0.090f, 0.084f, 0.075f, 0.068f, 0.076f, 0.080f, 0.097f, 0.092f, 0.076f, 0.078f, 0.237f, 0.042f, 1.000f, 0.001f, 0.239f}, + {0.310f, 0.310f, 0.307f, 0.293f, 0.326f, 0.330f, 0.373f, 0.385f, 0.410f, 0.352f, 0.309f, 0.708f, 0.001f, 0.001f, 0.138f}, + {0.125f, 0.115f, 0.106f, 0.104f, 0.110f, 0.113f, 0.113f, 0.085f, 0.066f, 0.064f, 0.212f, 0.003f, 0.001f, 1.000f, 0.520f}, + {0.463f, 0.440f, 0.470f, 0.494f, 0.471f, 0.463f, 0.408f, 0.429f, 0.445f, 0.504f, 0.240f, 0.246f, 0.001f, 0.001f, 0.104f} +}; + +float donor_prob_sum[1 << (donor_len << 1)]; +float acceptor_prob_sum1[1 << (acceptor_len1 << 1)]; +float acceptor_prob_sum2[1 << (acceptor_len2 << 1)]; + +#endif + +void init_junction_prob() +{ +#if !defined(NEW_PROB_MODEL) + for(size_t i = 0; i < donor_len; i++) { + ASSERT_ONLY(float sum = 0.0f); + for(size_t j = 0; j < 4; j++) { + float prob = donor_prob[j][i]; + assert_gt(prob, 0.0f); + ASSERT_ONLY(sum += prob); + donor_prob[j][i] = log(prob / background_prob[j]); + } + assert_range(0.9f, 1.05f, sum); + } + for(size_t i = 0; i < acceptor_len; i++) { + ASSERT_ONLY(float sum = 0.0f); + for(size_t j = 0; j < 4; j++) { + float prob = acceptor_prob[j][i]; + assert_gt(prob, 0.0f); + ASSERT_ONLY(sum += prob); + acceptor_prob[j][i] = log(prob / background_prob[j]); + } + assert_range(0.9f, 1.05f, sum); + } + + const size_t donor_elms = 1 << (donor_len << 1); + for(size_t i = 0; i < donor_elms; i++) { + float sum = 0.0f; + for(size_t j = 0; j < donor_len; j++) { + int base = (i >> (j << 1)) & 0x3; + sum += donor_prob[base][donor_len - j - 1]; + } + donor_prob_sum[i] = exp(-sum); + } + + const size_t acceptor_elms1 = 1 << (acceptor_len1 << 1); + for(size_t i = 0; i < acceptor_elms1; i++) { + float sum = 0.0f; + for(size_t j = 0; j < acceptor_len1; j++) { + int base = (i >> (j << 1)) & 0x3; + sum += acceptor_prob[base][acceptor_len1 - j - 1]; + } + acceptor_prob_sum1[i] = exp(-sum); + } + + const size_t acceptor_elms2 = 1 << (acceptor_len2 << 1); + for(size_t i = 0; i < acceptor_elms2; i++) { + float sum = 0.0f; + for(size_t j = 0; j < acceptor_len2; j++) { + int base = (i >> (j << 1)) & 0x3; + sum += acceptor_prob[base][acceptor_len - j - 1]; + } + acceptor_prob_sum2[i] = exp(-sum); + } +#endif +} + +ostream& operator<<(ostream& out, const SpliceSite& s) +{ + out << s.ref() << "\t" + << s.left() << "\t" + << s.right() << "\t"; + if(s.splDir() == SPL_FW || s.splDir() == SPL_SEMI_FW) { + out << "+"; + } else if(s.splDir() == SPL_RC || s.splDir() == SPL_SEMI_RC) { + out << "-"; + } else { + out << "."; + } + out << endl; + return out; +} + +SpliceSiteDB::SpliceSiteDB( + const BitPairReference& refs, + const EList& refnames, + bool threadSafe, + bool write, + bool read) : +_numRefs(refs.numRefs()), +_write(write), +_read(read), +_threadSafe(threadSafe), +_empty(true) +{ + for(size_t r = 0; r < refnames.size(); r++) { + const string& refname = refnames[r]; + _refnames.expand(); + size_t i = 0; + for(; i < refname.size(); i++) { + if(isspace(refname[i])) { + break; + } + } + _refnames.back() = refname.substr(0, i); + } + + assert_gt(_numRefs, 0); + assert_eq(_numRefs, _refnames.size()); + for(uint64_t i = 0; i < _numRefs; i++) { + _fwIndex.push_back(new RedBlack(16 << 10, CA_CAT)); + _bwIndex.push_back(new RedBlack(16 << 10, CA_CAT)); + _pool.expand(); + _spliceSites.expand(); + _mutex.push_back(MUTEX_T()); + } + + donorstr.resize(donor_exonic_len + donor_intronic_len); + acceptorstr.resize(acceptor_intronic_len + acceptor_exonic_len); +} + +SpliceSiteDB::~SpliceSiteDB() { + assert_eq(_fwIndex.size(), _bwIndex.size()); + assert_eq(_fwIndex.size(), _pool.size()); + for(uint64_t i = 0; i < _numRefs; i++) { + delete _fwIndex[i]; + delete _bwIndex[i]; + + EList& pool = _pool[i]; + for(size_t j = 0; j < pool.size(); j++) { + delete pool[j]; + } + } +} + +size_t SpliceSiteDB::size(uint64_t ref) const { + if(!_read) return 0; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + assert_lt(ref, _fwIndex.size()); + assert_eq(_fwIndex.size(), _bwIndex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + return _fwIndex.size(); +} + +bool SpliceSiteDB::empty(uint64_t ref) const { + return size(ref) == 0; +} + +bool SpliceSiteDB::addSpliceSite( + const Read& rd, + const AlnRes& rs, + uint32_t minAnchorLen) +{ + if(!_write) return false; + if(rs.trimmed5p(true) + rs.trimmed3p(true) > 0) return false; + + _empty = false; + + Coord coord = rs.refcoord(); + uint64_t ref = coord.ref(); + assert_lt(ref, _numRefs); + const EList& edits = rs.ned(); + if(!coord.orient()) { + Edit::invertPoss(const_cast&>(edits), rd.length(), false); + } + // daehwan - for debugging purposes + uint32_t editdist = 0; + for(size_t i = 0; i < edits.size(); i++) { + const Edit& edit = edits[i]; + if(edit.isGap() || edit.isMismatch()) editdist++; + } + + SpliceSitePos ssp; + uint32_t refoff = (uint32_t)coord.off(); + uint32_t leftAnchorLen = 0, rightAnchorLen = 0; + size_t eidx = 0; + size_t last_eidx = 0; + uint32_t mm = 0; + for(size_t i = 0; i < rd.length(); i++, refoff++) { + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + refoff++; + } else if(edits[eidx].isRefGap()) { + assert_gt(refoff, 0); + refoff--; + } + if(edits[eidx].isGap() || edits[eidx].isMismatch()) mm++; + if(edits[eidx].isSpliced()) { + assert_gt(refoff, 0); + if(ssp.inited()) { + assert(edits[last_eidx].isSpliced()); + assert_lt(edits[last_eidx].pos, edits[eidx].pos); + rightAnchorLen = edits[eidx].pos - edits[last_eidx].pos; + uint32_t minLeftAnchorLen = minAnchorLen + mm * 2 + (edits[eidx].splDir == SPL_UNKNOWN ? 6 : 0); + uint32_t mm2 = 0; + for(size_t j = eidx + 1; j < edits.size(); j++) { + if(edits[j].isGap() || edits[j].isMismatch()) mm2++; + } + uint32_t minRightAnchorLen = minAnchorLen + mm2 * 2 + (edits[eidx].splDir == SPL_UNKNOWN ? 6 : 0); + if(leftAnchorLen >= minLeftAnchorLen && rightAnchorLen >= minRightAnchorLen) { + bool added = false; + assert_lt(ref, _mutex.size()); + ThreadSafe t(&_mutex[ref], _threadSafe && _write); + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + Node *cur = _fwIndex[ref]->add(pool(ref), ssp, &added); + if(added) { + assert_lt(ref, _spliceSites.size()); + _spliceSites[ref].expand(); + _spliceSites[ref].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.splDir()); + _spliceSites[ref].back()._readid = rd.rdid; + _spliceSites[ref].back()._leftext = leftAnchorLen; + _spliceSites[ref].back()._rightext = rightAnchorLen; + _spliceSites[ref].back()._editdist = editdist; + _spliceSites[ref].back()._numreads = 1; + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.splDir()); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + cur = _bwIndex[ref]->add(pool(ref), rssp, &added); + assert(added); + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + assert_eq(_fwIndex[ref]->size(), _bwIndex[ref]->size()); + } else { + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + assert_lt(cur->payload, _spliceSites[ref].size()); + if(leftAnchorLen > _spliceSites[ref][cur->payload]._leftext) _spliceSites[ref][cur->payload]._leftext = leftAnchorLen; + if(rightAnchorLen > _spliceSites[ref][cur->payload]._rightext) _spliceSites[ref][cur->payload]._rightext = rightAnchorLen; + if(editdist < _spliceSites[ref][cur->payload]._editdist) _spliceSites[ref][cur->payload]._editdist = editdist; + _spliceSites[ref][cur->payload]._numreads += 1; + if(rd.rdid < _spliceSites[ref][cur->payload]._readid) { + _spliceSites[ref][cur->payload]._readid = rd.rdid; + } + } + } + leftAnchorLen = rightAnchorLen; + rightAnchorLen = 0; + } else { + leftAnchorLen = edits[eidx].pos; + } + ssp.init((uint32_t)coord.ref(), refoff - 1, refoff + edits[eidx].splLen, edits[eidx].splDir); + refoff += edits[eidx].splLen; + last_eidx = eidx; + } + eidx++; + } + } + if(ssp.inited()) { + assert(edits[last_eidx].isSpliced()); + assert_lt(edits[last_eidx].pos, rd.length()); + rightAnchorLen = (uint32_t)(rd.length() - edits[last_eidx].pos); + uint32_t minLeftAnchorLen = minAnchorLen + mm * 2 + (edits[last_eidx].splDir == SPL_UNKNOWN ? 6 : 0); + uint32_t mm2 = 0; + for(size_t j = last_eidx + 1; j < edits.size(); j++) { + if(edits[j].isGap() || edits[j].isMismatch()) mm2++; + } + uint32_t minRightAnchorLen = minAnchorLen + mm2 * 2 + (edits[last_eidx].splDir == SPL_UNKNOWN ? 6 : 0); + if(leftAnchorLen >= minLeftAnchorLen && rightAnchorLen >= minRightAnchorLen) { + bool added = false; + assert_lt(ref, _mutex.size()); + ThreadSafe t(&_mutex[ref], _threadSafe && _write); + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + Node *cur = _fwIndex[ref]->add(pool(ref), ssp, &added); + if(added) { + assert_lt(ref, _spliceSites.size()); + _spliceSites[ref].expand(); + _spliceSites[ref].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.splDir()); + _spliceSites[ref].back()._readid = rd.rdid; + _spliceSites[ref].back()._leftext = leftAnchorLen; + _spliceSites[ref].back()._rightext = rightAnchorLen; + _spliceSites[ref].back()._editdist = editdist; + _spliceSites[ref].back()._numreads = 1; + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.splDir()); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + cur = _bwIndex[ref]->add(pool(ref), rssp, &added); + assert(added); + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + assert_eq(_fwIndex[ref]->size(), _bwIndex[ref]->size()); + } else { + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + assert_lt(cur->payload, _spliceSites[ref].size()); + if(leftAnchorLen > _spliceSites[ref][cur->payload]._leftext) _spliceSites[ref][cur->payload]._leftext = leftAnchorLen; + if(rightAnchorLen > _spliceSites[ref][cur->payload]._rightext) _spliceSites[ref][cur->payload]._rightext = rightAnchorLen; + if(editdist < _spliceSites[ref][cur->payload]._editdist) _spliceSites[ref][cur->payload]._editdist = editdist; + _spliceSites[ref][cur->payload]._numreads += 1; + if(rd.rdid < _spliceSites[ref][cur->payload]._readid) { + _spliceSites[ref][cur->payload]._readid = rd.rdid; + } + } + } + } + if(!coord.orient()) { + Edit::invertPoss(const_cast&>(edits), rd.length(), false); + } + + return true; +} + +bool SpliceSiteDB::getSpliceSite(SpliceSite& ss) const +{ + if(!_read) return false; + + uint64_t ref = ss.ref(); + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + const Node *cur = _fwIndex[ref]->lookup(ss); + if(cur == NULL) return false; + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + ss = _spliceSites[ref][cur->payload]; + return true; +} + +void SpliceSiteDB::getLeftSpliceSites(uint32_t ref, uint32_t left, uint32_t range, EList& spliceSites) const +{ + if(!_read) return; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + assert_gt(range, 0); + assert_geq(left + 1, range); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + const Node *cur = _bwIndex[ref]->root(); + if(cur != NULL) getSpliceSites_recur(cur, left + 1 - range, left, spliceSites); +} + +void SpliceSiteDB::getRightSpliceSites(uint32_t ref, uint32_t right, uint32_t range, EList& spliceSites) const +{ + if(!_read) return; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + assert_gt(range, 0); + assert_gt(right + range, range); + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + const Node *cur = _fwIndex[ref]->root(); + if(cur != NULL) getSpliceSites_recur(cur, right, right + range - 1, spliceSites); + +} + +void SpliceSiteDB::getSpliceSites_recur( + const RedBlackNode *node, + uint32_t left, + uint32_t right, + EList& spliceSites) const +{ + assert(node != NULL); + if(node->key.left() >= left && node->left != NULL) { + getSpliceSites_recur( + node->left, + left, + right, + spliceSites); + } + + if(node->key.left() >= left && node->key.left() <= right) { + uint32_t ref = node->key.ref(); + assert_lt(ref, _spliceSites.size()); + assert_lt(node->payload, _spliceSites[ref].size()); + ASSERT_ONLY(const SpliceSite& ss = _spliceSites[ref][node->payload]); + assert_eq(ss.ref(), node->key.ref()); + assert(ss.left() == node->key.left() || + ss.right() == node->key.left()); + spliceSites.push_back(_spliceSites[ref][node->payload]); + } + + if(node->key.left() <= right && node->right != NULL) { + getSpliceSites_recur( + node->right, + left, + right, + spliceSites); + } +} + +bool SpliceSiteDB::hasSpliceSites( + uint32_t ref, + uint32_t left1, + uint32_t right1, + uint32_t left2, + uint32_t right2, + bool includeNovel) const +{ + if(!_read) return false; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + + if(left1 < right1) { + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + const Node *cur = _bwIndex[ref]->root(); + if(cur != NULL) { + if(hasSpliceSites_recur(cur, left1, right1, includeNovel)) + return true; + } + } + + if(left2 < right2) { + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + const Node *cur = _fwIndex[ref]->root(); + if(cur != NULL) { + return hasSpliceSites_recur(cur, left2, right2, includeNovel); + } + } + return false; +} + +bool SpliceSiteDB::hasSpliceSites_recur( + const RedBlackNode *node, + uint32_t left, + uint32_t right, + bool includeNovel) const +{ + assert(node != NULL); + if(node->key.left() >= left && node->key.left() <= right) { + uint32_t ref = node->key.ref(); + assert_lt(ref, _spliceSites.size()); + assert_lt(node->payload, _spliceSites[ref].size()); + const SpliceSite& ss = _spliceSites[ref][node->payload]; + if(includeNovel || ss._known) + return true; + } + + if(node->key.left() >= left && node->left != NULL) { + if(hasSpliceSites_recur( + node->left, + left, + right, + includeNovel)) + return true; + } + + if(node->key.left() <= right && node->right != NULL) { + if(hasSpliceSites_recur( + node->right, + left, + right, + includeNovel)) + return true; + } + + return false; +} + +bool SpliceSiteDB::insideExon( + uint32_t ref, + uint32_t left, + uint32_t right) const +{ + if(_exons.empty()) return false; + assert_lt(ref, _numRefs); + assert_lt(left, right); + + Exon e(ref, left + 1, 0, true); + size_t i = _exons.bsearchLoBound(e); + for(; i > 0; i--) { + const Exon& e = _exons[i-1]; + if(e.right() < left) break; + if(e.left() <= left && right <= e.right()) + return true; + } + return false; +} + +void calculate_splicesite_read_dist_impl(const RedBlackNode *node, + const EList &spliceSites, + EList& splicesite_read_dist) { + if(node == NULL) return; + calculate_splicesite_read_dist_impl(node->left, spliceSites, splicesite_read_dist); + assert_lt(node->payload, spliceSites.size()); + const SpliceSite& ss = spliceSites[node->payload]; + if(ss.numreads() < splicesite_read_dist.size()) + splicesite_read_dist[ss.numreads()] += 1; + else + splicesite_read_dist.back() += 1; + calculate_splicesite_read_dist_impl(node->right, spliceSites, splicesite_read_dist); +} + +uint32_t calculate_splicesite_read_dist(const EList* >& fwIndex, + const ELList &spliceSites, + EList& splicesite_read_dist) { + for(size_t i = 0; i < fwIndex.size(); i++) { + assert(fwIndex[i] != NULL); + const RedBlackNode *root = fwIndex[i]->root(); + assert_lt(i, spliceSites.size()); + if(root != NULL) calculate_splicesite_read_dist_impl(root, spliceSites[i], splicesite_read_dist); + } + + for(size_t i = 1; i < splicesite_read_dist.size(); i++) { + splicesite_read_dist[i] += splicesite_read_dist[i-1]; + } + + for(size_t i = 0; i < splicesite_read_dist.size(); i++) { + float cmf_i = float(splicesite_read_dist[i]) / splicesite_read_dist.back(); + if(cmf_i > 0.7) + return (uint32_t)i; + } + + return 0; +} + +void SpliceSiteDB::print(ofstream& out) +{ + EList splicesite_read_dist; + for(size_t i = 0; i < 100; i++) { + splicesite_read_dist.push_back(0); + } + uint32_t numreads_cutoff = calculate_splicesite_read_dist(_fwIndex, _spliceSites, splicesite_read_dist); + size_t numsplicesites = 0; + for(size_t i = 0; i < _spliceSites.size(); i++) { + numsplicesites += _spliceSites[i].size(); + } + uint32_t numreads_cutoff2 = (uint32_t)(numsplicesites / 100000); + + EList ss_list; + for(size_t i = 0; i < _fwIndex.size(); i++) { + assert(_fwIndex[i] != NULL); + const Node *root = _fwIndex[i]->root(); + if(root != NULL) print_recur(root, out, numreads_cutoff, numreads_cutoff2, ss_list); + } + print_impl(out, ss_list); +} + +void SpliceSiteDB::print_recur( + const RedBlackNode *node, + ofstream& out, + const uint32_t numreads_cutoff, + const uint32_t numreads_cutoff2, + EList& ss_list) +{ + if(node == NULL) return; + print_recur(node->left, out, numreads_cutoff, numreads_cutoff2, ss_list); + const SpliceSitePos& ssp = node->key; + assert_lt(ssp.ref(), _spliceSites.size()); + assert_lt(node->payload, _spliceSites[ssp.ref()].size()); + const SpliceSite& ss = _spliceSites[ssp.ref()][node->payload]; + if(ss.numreads() >= numreads_cutoff || + (ss.editdist() == 0 && ss.numreads() >= numreads_cutoff2)) print_impl(out, ss_list, &ss); + print_recur(node->right, out, numreads_cutoff, numreads_cutoff2, ss_list); +} + +void SpliceSiteDB::print_impl( + ofstream& out, + EList& ss_list, + const SpliceSite* ss) +{ + size_t i = 0; + while(i < ss_list.size()) { + const SpliceSite& tmp_ss = ss_list[i]; + bool do_print = true; + if(ss != NULL) { + if(tmp_ss.ref() == ss->ref()) { + assert_leq(tmp_ss.left(), ss->left()); + if(ss->left() < tmp_ss.left() + 10) { + do_print = false; + if(abs(((int)ss->left() - (int)tmp_ss.left()) - ((int)ss->right() - (int)tmp_ss.right())) <= 10) { + if(tmp_ss.numreads() < ss->numreads()) { + ss_list.erase(i); + ss_list.push_back(*ss); + } + return; + } + } + } + } + + if(!do_print) { + i++; + continue; + } + + assert_lt(tmp_ss.ref(), _refnames.size()); + out << _refnames[tmp_ss.ref()] << "\t" + << tmp_ss.left() << "\t" + << tmp_ss.right() << "\t"; + if(tmp_ss.splDir() == SPL_FW || tmp_ss.splDir() == SPL_SEMI_FW) { + out << "+"; + } else if(tmp_ss.splDir() == SPL_RC || tmp_ss.splDir() == SPL_SEMI_RC) { + out << "-"; + } else { + out << "."; + } + out << endl; + ss_list.erase(i); + } + + if(ss != NULL) ss_list.push_back(*ss); +} + +void SpliceSiteDB::read(const GFM& gfm, const EList >& alts) +{ + EList exons; + _empty = false; + assert_eq(_numRefs, _refnames.size()); + for(size_t i = 0; i < alts.size(); i++) { + const ALT& alt = alts[i]; + if(!alt.splicesite() && !alt.exon()) continue; + if(alt.left > alt.right) continue; + TIndexOffU ref = 0, left = 0, tlen = 0; + char fw = alt.fw; + bool straddled2 = false; + gfm.joinedToTextOff( + 1, + alt.left, + ref, + left, + tlen, + true, // reject straddlers? + straddled2); // straddled? + assert_lt(ref, _spliceSites.size()); + TIndexOffU right = left + (alt.right - alt.left); + if(alt.splicesite()) { + left -= 1; right += 1; + _spliceSites[ref].expand(); + _spliceSites[ref].back().init(ref, + left, + right, + fw ? SPL_FW : SPL_RC, + alt.exon(), + true, // from file? + true); // known splice site? + assert_gt(_spliceSites[ref].size(), 0); + bool added = false; + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + Node *cur = _fwIndex[ref]->add(pool(ref), _spliceSites[ref].back(), &added); + if(!added) { + _spliceSites[ref].pop_back(); + continue; + } + assert(added); + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + + added = false; + SpliceSitePos rssp(ref, + right, + left, + fw ? SPL_FW : SPL_RC); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + cur = _bwIndex[ref]->add(pool(ref), rssp, &added); + assert(added); + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + } else { + assert(alt.exon()); + // Given some relaxation + if(left >= 10) left -= 10; + else left = 0; + if(right + 10 < tlen) right += 10; + else right = tlen - 1; + exons.expand(); + exons.back().init(ref, left, right, fw == '+' ? SPL_FW : SPL_RC); + } + } + if(exons.size() > 0) { + _exons.resizeExact(exons.size()); _exons.clear(); + _exons.push_back_array(exons.begin(), exons.size()); + _exons.sort(); + } +} + +void SpliceSiteDB::read(ifstream& in, bool known) +{ + _empty = false; + assert_eq(_numRefs, _refnames.size()); + while(!in.eof()) { + string refname; + uint32_t left = 0, right = 0; + char fw = 0; + in >> refname >> left >> right >> fw; + uint32_t ref = 0; + for(; ref < _refnames.size(); ref++) { + if(_refnames[ref] == refname) break; + } + if(ref >= _numRefs) continue; + assert_lt(ref, _spliceSites.size()); + _spliceSites[ref].expand(); + _spliceSites[ref].back().init(ref, + left, + right, + fw == '+' ? SPL_FW : SPL_RC, + false, // exon? + true, // from file? + known); // known splice site? + assert_gt(_spliceSites[ref].size(), 0); + + bool added = false; + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + Node *cur = _fwIndex[ref]->add(pool(ref), _spliceSites[ref].back(), &added); + if(!added) { + _spliceSites[ref].pop_back(); + continue; + } + + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + added = false; + SpliceSitePos rssp(ref, + right, + left, + fw == '+' ? SPL_FW : SPL_RC); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + cur = _bwIndex[ref]->add(pool(ref), rssp, &added); + assert(added); + assert(cur != NULL); + cur->payload = (uint32_t)_spliceSites[ref].size() - 1; + } +} + +Pool& SpliceSiteDB::pool(uint64_t ref) { + assert_lt(ref, _numRefs); + assert_lt(ref, _pool.size()); + EList& pool = _pool[ref]; + if(pool.size() <= 0 || pool.back()->full()) { + pool.push_back(new Pool(1 << 20 /* 1MB */, 16 << 10 /* 16KB */, CA_CAT)); + } + assert(pool.back() != NULL); + return *pool.back(); +} + +float SpliceSiteDB::probscore( + int64_t donor_seq, + int64_t acceptor_seq) +{ + float probscore = 0.0f; +#if defined(NEW_PROB_MODEL) + float donor_probscore = 0.0f; + assert_leq(donor_seq, 0x3ffff); + int64_t donor_exonic_seq = (donor_seq >> 4) & (~0xff); + int64_t donor_intronic_seq = donor_seq & 0xff; + int64_t donor_rest_seq = donor_exonic_seq | donor_intronic_seq; + int donor_seq3 = (donor_seq >> 10) & 0x3; + int donor_seq4 = (donor_seq >> 8) & 0x3; + donor_probscore = donor_cons1[donor_seq3] * donor_cons2[donor_seq4] / (background_bp_prob[donor_seq3] * background_bp_prob[donor_seq4]) * donor_me2x5[donor_rest_seq]; + + float acceptor_probscore = 0.0f; + assert_leq(acceptor_seq, 0x3fffffffffff); + int64_t acceptor_intronic_seq = (acceptor_seq >> 4) & (~0x3f); + int64_t acceptor_exonic_seq = acceptor_seq & 0x3f; + int64_t acceptor_rest_seq = acceptor_intronic_seq | acceptor_exonic_seq; + int acceptor_seq18 = (acceptor_seq >> 8) & 0x3; + int acceptor_seq19 = (acceptor_seq >> 6) & 0x3; + acceptor_probscore = acceptor_cons1[acceptor_seq18] * acceptor_cons2[acceptor_seq19] / (background_bp_prob[acceptor_seq18] * background_bp_prob[acceptor_seq19]); + + int64_t acceptor_seq1 = acceptor_rest_seq >> 28 & 0x3fff; // [0, 7] + acceptor_probscore *= acceptor_me2x3acc1[acceptor_seq1]; + int64_t acceptor_seq2 = (acceptor_rest_seq >> 14) & 0x3fff; // [7, 7] + acceptor_probscore *= acceptor_me2x3acc2[acceptor_seq2]; + int64_t acceptor_seq3 = acceptor_rest_seq & 0x3fff; // [14, 7] + acceptor_probscore *= acceptor_me2x3acc3[acceptor_seq3]; + int64_t acceptor_seq4 = (acceptor_rest_seq >> 20) & 0x3fff; // [4, 7] + acceptor_probscore *= acceptor_me2x3acc4[acceptor_seq4]; + int64_t acceptor_seq5 = (acceptor_rest_seq >> 6) & 0x3fff; // [11, 7] + acceptor_probscore *= acceptor_me2x3acc5[acceptor_seq5]; + int64_t acceptor_seq6 = acceptor_seq1 & 0x3f; // [4, 3] + acceptor_probscore /= acceptor_me2x3acc6[acceptor_seq6]; + int64_t acceptor_seq7 = acceptor_seq4 & 0xff; // [7, 4] + acceptor_probscore /= acceptor_me2x3acc7[acceptor_seq7]; + int64_t acceptor_seq8 = acceptor_seq2 & 0x3f; // [11, 3] + acceptor_probscore /= acceptor_me2x3acc8[acceptor_seq8]; + int64_t acceptor_seq9 = acceptor_seq5 & 0xff; // [14, 4] + acceptor_probscore /= acceptor_me2x3acc9[acceptor_seq9]; + + donor_probscore /= (1.0f + donor_probscore); + acceptor_probscore /= (1.0f + acceptor_probscore); + probscore = (donor_probscore + acceptor_probscore) / 2.0; + +#else + assert_lt(donor_seq, (int)(1 << (donor_len << 1))); + probscore = donor_prob_sum[donor_seq]; + + int acceptor_seq1 = (int)(acceptor_seq >> (acceptor_len2 << 1)); + assert_lt(acceptor_seq1, (int)(1 << (acceptor_len1 << 1))); + probscore *= acceptor_prob_sum1[acceptor_seq1]; + + int acceptor_seq2 = acceptor_seq % (1 << (acceptor_len2 << 1)); + probscore *= acceptor_prob_sum2[acceptor_seq2]; + + probscore = 1.0 / (1.0 + probscore); +#endif + return probscore; +} + diff --git a/splice_site.h b/splice_site.h new file mode 100644 index 0000000..b0a5f43 --- /dev/null +++ b/splice_site.h @@ -0,0 +1,615 @@ +/* + * Copyright 2013, Daehwan Kim + * + * This file is part of HISAT. + * + * HISAT is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT. If not, see . + */ + +#ifndef SPLICE_SITE_H_ +#define SPLICE_SITE_H_ + +#include +#include +#include +#include +#include "assert_helpers.h" +#include "mem_ids.h" +#include "ref_coord.h" +#include "ds.h" +#include "read.h" +#include "reference.h" +#include "hier_idx_common.h" +#include "gfm.h" +#include "alt.h" + +enum { + SPL_UNKNOWN = 1, + SPL_FW, + SPL_RC, + SPL_SEMI_FW, + SPL_SEMI_RC, +}; + +using namespace std; + +// #define NEW_PROB_MODEL +// the following parameters are borrowed from Yeo and Burge 2004 in Journal of Computational Biology +const size_t donor_exonic_len = 3; +const size_t donor_intronic_len = 6; +const size_t donor_len = donor_exonic_len + donor_intronic_len; + +#if defined(NEW_PROB_MODEL) +const size_t acceptor_intronic_len = 20; +const size_t acceptor_exonic_len = 3; +const size_t acceptor_len = acceptor_intronic_len + acceptor_exonic_len; +#else +// the following parameters are borrowed from Ch 3. in Bioinformatics - From Genomes to Drugs. Volume I: Basic Technologies (Victor Solovyev) +const size_t acceptor_intronic_len = 14; +const size_t acceptor_exonic_len = 1; +const size_t acceptor_len = acceptor_intronic_len + acceptor_exonic_len; +const size_t acceptor_len1 = acceptor_len / 2; +const size_t acceptor_len2 = acceptor_len - acceptor_len1; + +// the following parameters are borrowed from Yeo and Burge 2004 in Journal of Computational Biology +const float background_prob[4] = {0.27f, 0.23f, 0.23f, 0.27f}; + +extern float donor_prob[4][donor_len]; +extern float acceptor_prob[4][acceptor_len]; + +extern float donor_prob_sum[1 << (donor_len << 1)]; +extern float acceptor_prob_sum1[1 << (acceptor_len1 << 1)]; +extern float acceptor_prob_sum2[1 << (acceptor_len2 << 1)]; + +#endif +const size_t intronic_len = max(donor_intronic_len, acceptor_intronic_len); + +extern void init_junction_prob(); + +/** + * + */ +class SpliceSitePos { + +public: + + SpliceSitePos() { reset(); } + + SpliceSitePos(const SpliceSitePos& c) { init(c); } + + SpliceSitePos(uint32_t ref, uint32_t left, uint32_t right, uint8_t splDir, bool exon = false) + { + init(ref, left, right, splDir, exon); + } + + /** + * Copy given fields into this Coord. + */ + void init(uint32_t ref, uint32_t left, uint32_t right, uint8_t splDir, bool exon = false) { + _ref = ref; + _left = left; + _right = right; + _splDir = splDir; + _exon = exon; + } + + /** + * Copy contents of given Coord into this one. + */ + void init(const SpliceSitePos& c) { + _ref = c._ref; + _left = c._left; + _right = c._right; + _splDir = c._splDir; + _exon = c._exon; + } + + /** + * Return true iff this Coord is identical to the given Coord. + */ + bool operator==(const SpliceSitePos& o) const { + assert(inited()); + assert(o.inited()); + return _ref == o._ref && + _left == o._left && + _right == o._right && + _splDir == o._splDir && + _exon == o._exon; + + } + + /** + * Return true iff this Coord is less than the given Coord. One Coord is + * less than another if (a) its reference id is less, (b) its orientation is + * less, or (c) its offset is less. + */ + bool operator<(const SpliceSitePos& o) const { + if(_ref < o._ref) return true; + if(_ref > o._ref) return false; + if(_left < o._left) return true; + if(_left > o._left) return false; + if(_right < o._right) return true; + if(_right > o._right) return false; + if(_splDir < o._splDir) return true; + if(_splDir > o._splDir) return false; + if(_exon != o._exon) return _exon; + return false; + } + + /** + * Return the opposite result from operator<. + */ + bool operator>=(const SpliceSitePos& o) const { + return !((*this) < o); + } + + /** + * Return true iff this Coord is greater than the given Coord. One Coord + * is greater than another if (a) its reference id is greater, (b) its + * orientation is greater, or (c) its offset is greater. + */ + bool operator>(const SpliceSitePos& o) const { + if(_ref > o._ref) return true; + if(_ref < o._ref) return false; + if(_left > o._left) return true; + if(_left < o._left) return false; + if(_right > o._right) return true; + if(_right < o._right) return false; + if(_splDir > o._splDir) return true; + if(_splDir < o._splDir) return false; + if(_exon != o._exon) return !_exon; + return false; + } + + /** + * Return the opposite result from operator>. + */ + bool operator<=(const SpliceSitePos& o) const { + return !((*this) > o); + } + + /** + * Reset this coord to uninitialized state. + */ + virtual void reset() { + _ref = std::numeric_limits::max(); + _left = std::numeric_limits::max(); + _right = std::numeric_limits::max(); + _splDir = SPL_UNKNOWN; + _exon = false; + } + + /** + * Return true iff this Coord is initialized (i.e. ref and off have both + * been set since the last call to reset()). + */ + bool inited() const { + if(_ref != std::numeric_limits::max() && + _left != std::numeric_limits::max() && + _right != std::numeric_limits::max()) + { + return true; + } + return false; + } + +#ifndef NDEBUG + /** + * Check that coord is internally consistent. + */ + bool repOk() const { + if(_ref == std::numeric_limits::max() || + _left == std::numeric_limits::max() || + _right == std::numeric_limits::max()) { + return false; + } + return true; + } +#endif + + /** + * Check whether an interval defined by this coord and having + * length 'len' is contained within an interval defined by + * 'inbegin' and 'inend'. + */ +#if 0 + bool within(int64_t len, int64_t inbegin, int64_t inend) const { + return off_ >= inbegin && off_ + len <= inend; + } +#endif + + uint32_t ref() const { return _ref; } + uint32_t left() const { return _left; } + uint32_t right() const { return _right; } + uint8_t splDir() const { return _splDir; } + bool canonical() const { return _splDir == SPL_FW || _splDir == SPL_RC; } + uint32_t intron_len() const { return _right - _left - 1; } + bool exon() const { return _exon; } + +protected: + + uint32_t _ref; // which reference? + uint32_t _left; // 0-based offset of the right most base of the left flanking exon + uint32_t _right; // 0-based offset of the left most base of the right flanking exon + uint8_t _splDir; + bool _exon; +}; + +/** + * + */ +class SpliceSite : public SpliceSitePos { + +public: + + SpliceSite() { reset(); } + + SpliceSite(const SpliceSite& c) { init(c); } + + SpliceSite(uint32_t ref, + uint32_t left, + uint32_t right, + uint8_t splDir, + bool exon = false, + bool fromFile = false, + bool known = false) + { + init(ref, left, right, splDir, exon, fromFile, known); + } + + /** + * Copy given fields into this Coord. + */ + void init(uint32_t ref, + uint32_t left, + uint32_t right, + uint8_t splDir, + bool exon = false, + bool fromFile = false, + bool known = false) + { + SpliceSitePos::init(ref, left, right, splDir, exon); + + // _donordint = 0; + // _acceptordint = 0; + // _leftseq = 0; + // _rightseq = 0; + _leftext = 0; + _rightext = 0; + _numreads = 0; + _editdist = 0; + // _probscore = 0.0f; + _readid = 0; + _exon = exon; + _fromfile = fromFile; + _known = known; + } + + /** + * Copy contents of given Coord into this one. + */ + void init(const SpliceSite& c) { + SpliceSitePos::init(c); + + // _donordint = c._donordint; + // _acceptordint = c._acceptordint; + // _leftseq = c._leftseq; + // _rightseq = c._rightseq; + _leftext = c._leftext; + _rightext = c._rightext; + _numreads = c._numreads; + _editdist = c._editdist; + // _probscore = c._probscore; + _readid = c._readid; + _fromfile = c._fromfile; + _known = c._known; + } + + /** + * Reset this coord to uninitialized state. + */ + virtual void reset() { + SpliceSitePos::reset(); + + // _donordint = 0; + // _acceptordint = 0; + // _leftseq = 0; + // _rightseq = 0; + _leftext = 0; + _rightext = 0; + _numreads = 0; + _editdist = 0; + // _probscore = 0.0; + _readid = 0; + _fromfile = false; + _known = false; + } + + // uint8_t donordint() const { return _donordint; } + // uint8_t acceptordint() const { return _acceptordint; } + // uint64_t leftseq() const { return _leftseq; } + // uint64_t rightseq() const { return _rightseq; } + + uint32_t leftext() const { return _leftext; } + uint32_t rightext() const { return _rightext; } + + uint64_t numreads() const { return _numreads; } + uint32_t editdist() const { return _editdist; } + // float probscore() const { return _probscore; } + +public: + + // uint8_t _donordint; // 3' dinucleotide on Watson strand + // uint8_t _acceptordint; // 5' dinucleotide on Watson strand + // uint64_t _leftseq; // left 32bp flanking seq on Watson strand + // uint64_t _rightseq; // right 32bp flanking seq on Watson strand + + uint32_t _leftext; + uint32_t _rightext; + + uint64_t _numreads; // number of reads spanning this splice site + + uint32_t _editdist; + + // float _probscore; + + uint64_t _readid; + bool _fromfile; + bool _known; +}; + +std::ostream& operator<<(std::ostream& out, const SpliceSite& c); + +/** + * + */ +class Exon { +public: + + Exon() { reset(); } + + Exon(const Exon& c) { init(c); } + + Exon(uint32_t ref, uint32_t left, uint32_t right, bool fw) + { + init(ref, left, right, fw); + } + + /** + * Copy given fields into this Coord. + */ + void init(uint32_t ref, uint32_t left, uint32_t right, bool fw) { + _ref = ref; + _left = left; + _right = right; + _fw = fw; + } + + /** + * Copy contents of given Coord into this one. + */ + void init(const Exon& c) { + _ref = c._ref; + _left = c._left; + _right = c._right; + _fw = c._fw; + } + + /** + * Return true iff this Coord is identical to the given Coord. + */ + bool operator==(const Exon& o) const { + assert(inited()); + assert(o.inited()); + return _ref == o._ref && + _left == o._left && + _right == o._right && + _fw == o._fw; + } + + /** + * Return true iff this Coord is less than the given Coord. One Coord is + * less than another if (a) its reference id is less, (b) its orientation is + * less, or (c) its offset is less. + */ + bool operator<(const Exon& o) const { + if(_ref < o._ref) return true; + if(_ref > o._ref) return false; + if(_left < o._left) return true; + if(_left > o._left) return false; + if(_right < o._right) return true; + if(_right > o._right) return false; + if(_fw != o._fw) return _fw; + return false; + } + + /** + * Return the opposite result from operator<. + */ + bool operator>=(const Exon& o) const { + return !((*this) < o); + } + + /** + * Return true iff this Coord is greater than the given Coord. One Coord + * is greater than another if (a) its reference id is greater, (b) its + * orientation is greater, or (c) its offset is greater. + */ + bool operator>(const Exon& o) const { + if(_ref > o._ref) return true; + if(_ref < o._ref) return false; + if(_left > o._left) return true; + if(_left < o._left) return false; + if(_right > o._right) return true; + if(_right < o._right) return false; + if(_fw != o._fw) return !_fw; + return false; + } + + /** + * Return the opposite result from operator>. + */ + bool operator<=(const Exon& o) const { + return !((*this) > o); + } + + /** + * Reset this coord to uninitialized state. + */ + void reset() { + _ref = std::numeric_limits::max(); + _left = std::numeric_limits::max(); + _right = std::numeric_limits::max(); + _fw = true; + } + + /** + * Return true iff this Coord is initialized (i.e. ref and off have both + * been set since the last call to reset()). + */ + bool inited() const { + if(_ref != std::numeric_limits::max() && + _left != std::numeric_limits::max() && + _right != std::numeric_limits::max()) + { + return true; + } + return false; + } + +#ifndef NDEBUG + /** + * Check that coord is internally consistent. + */ + bool repOk() const { + if(_ref == std::numeric_limits::max() || + _left == std::numeric_limits::max() || + _right == std::numeric_limits::max()) { + return false; + } + return true; + } +#endif + + uint32_t ref() const { return _ref; } + uint32_t left() const { return _left; } + uint32_t right() const { return _right; } + bool fw() const { return _fw; } + +protected: + uint32_t _ref; // which reference? + uint32_t _left; // 0-based offset of the right most base of the left flanking exon + uint32_t _right; // 0-based offset of the left most base of the right flanking exon + bool _fw; // true -> Watson strand +}; + +class AlnRes; + +class SpliceSiteDB { +public: + typedef RedBlackNode Node; + +public: + SpliceSiteDB( + const BitPairReference& refs, + const EList& refnames, + bool threadSafe = true, + bool write = false, + bool read = false); + ~SpliceSiteDB(); + + bool addSpliceSite( + const Read& rd, + const AlnRes& rs, + uint32_t minAnchorLen = 15); + + static float probscore( + int64_t donor_seq, + int64_t acceptor_seq); + + size_t size(uint64_t ref) const; + bool empty(uint64_t ref) const; + + bool empty() { return _empty; } + + bool write() const { return _write; } + bool read() const { return _read; } + + bool getSpliceSite(SpliceSite& ss) const; + void getLeftSpliceSites(uint32_t ref, uint32_t left, uint32_t range, EList& spliceSites) const; + void getRightSpliceSites(uint32_t ref, uint32_t right, uint32_t range, EList& spliceSites) const; + bool hasSpliceSites(uint32_t ref, uint32_t left1, uint32_t right1, uint32_t left2, uint32_t right2, bool includeNovel = false) const; + bool insideExon(uint32_t ref, uint32_t left, uint32_t right) const; + + void print(ofstream& out); + void read(const GFM& gfm, const EList >& alts); + void read(ifstream& in, bool known = false); + +private: + void getSpliceSites_recur( + const RedBlackNode *node, + uint32_t left, + uint32_t right, + EList& spliceSites) const; + + bool hasSpliceSites_recur( + const RedBlackNode *node, + uint32_t left, + uint32_t right, + bool includeNovel) const; + + const RedBlackNode* getSpliceSite_temp(const SpliceSitePos& ssp) const; + + void print_recur( + const RedBlackNode *node, + ofstream& out, + const uint32_t numreads_cutoff, + const uint32_t numreads_cutoff2, + EList& ss_list); + + Pool& pool(uint64_t ref); + + void print_impl( + ofstream& out, + EList& ss_list, + const SpliceSite* ss = NULL); + +private: + uint64_t _numRefs; + EList _refnames; + + EList* > _fwIndex; + EList* > _bwIndex; + + ELList _spliceSites; + + ELList _pool; // dispenses memory pages + + bool _write; + bool _read; + + EList _mutex; + bool _threadSafe; + + SStringExpandable raw_refbuf; + ASSERT_ONLY(SStringExpandable destU32); + BTDnaString donorstr; + BTDnaString acceptorstr; + + bool _empty; + + EList _exons; +}; + +#endif /*ifndef SPLICE_SITE_H_*/ diff --git a/splice_site_mem.h b/splice_site_mem.h new file mode 100644 index 0000000..2d1d1e7 --- /dev/null +++ b/splice_site_mem.h @@ -0,0 +1,6224 @@ +#ifndef SPLICE_SITE_MEM_H_ +#define SPLICE_SITE_MEM_H_ + +static const float background_bp_prob[4] = {0.27f, 0.23f, 0.23f, 0.27f}; +static const float donor_cons1[4] = {0.004f, 0.0032f, 0.9896f, 0.0032f}; +static const float donor_cons2[4] = {0.0034f, 0.0039f, 0.0042f, 0.9884f}; +static const float acceptor_cons1[4] = {0.9903f, 0.0032f, 0.0034f, 0.0030f}; +static const float acceptor_cons2[4] = {0.0027f, 0.0037f, 0.9905f, 0.0030f}; + +static const float donor_me2x5[16384] = { +0.143596f, 0.204157f, 0.192979f, 1.061763f, 0.231687f, 0.483900f, 0.466345f, 1.279266f, 7.648993f, 10.067296f, 6.140895f, 53.603145f, 0.119893f, 0.098323f, 0.141841f, 0.789030f, +0.017593f, 0.048968f, 0.034133f, 0.188161f, 0.040230f, 0.164498f, 0.116904f, 0.321303f, 1.594035f, 4.107312f, 1.847533f, 16.157861f, 0.022057f, 0.035412f, 0.037672f, 0.209963f, +0.007744f, 0.021649f, 0.006671f, 0.075685f, 0.008285f, 0.034023f, 0.010689f, 0.060461f, 0.786409f, 2.035123f, 0.404707f, 7.283977f, 0.003849f, 0.006207f, 0.002919f, 0.033480f, +0.019657f, 0.048412f, 0.030548f, 0.172960f, 0.023873f, 0.086370f, 0.055565f, 0.156854f, 0.930388f, 2.121214f, 0.863749f, 7.758677f, 0.014753f, 0.020958f, 0.020183f, 0.115538f, +0.000036f, 0.000079f, 0.000033f, 0.000718f, 0.000041f, 0.000132f, 0.000057f, 0.000609f, 0.013171f, 0.027007f, 0.007361f, 0.251065f, 0.000045f, 0.000058f, 0.000037f, 0.000809f, +0.000001f, 0.000004f, 0.000001f, 0.000026f, 0.000001f, 0.000009f, 0.000003f, 0.000032f, 0.000570f, 0.002290f, 0.000460f, 0.015726f, 0.000002f, 0.000004f, 0.000002f, 0.000045f, +0.000001f, 0.000005f, 0.000001f, 0.000029f, 0.000001f, 0.000005f, 0.000001f, 0.000016f, 0.000759f, 0.003059f, 0.000272f, 0.019118f, 0.000001f, 0.000002f, 0.000000f, 0.000019f, +0.000002f, 0.000009f, 0.000003f, 0.000057f, 0.000002f, 0.000011f, 0.000003f, 0.000036f, 0.000778f, 0.002763f, 0.000503f, 0.017645f, 0.000003f, 0.000006f, 0.000003f, 0.000058f, +0.005656f, 0.019340f, 0.010995f, 0.107534f, 0.010056f, 0.050509f, 0.029277f, 0.142761f, 1.189892f, 3.766273f, 1.381765f, 21.439941f, 0.003482f, 0.006868f, 0.005959f, 0.058922f, +0.000416f, 0.002786f, 0.001168f, 0.011444f, 0.001049f, 0.010311f, 0.004407f, 0.021532f, 0.148908f, 0.922725f, 0.249638f, 3.880905f, 0.000385f, 0.001485f, 0.000950f, 0.009416f, +0.000106f, 0.000710f, 0.000132f, 0.002652f, 0.000124f, 0.001229f, 0.000232f, 0.002335f, 0.042330f, 0.263445f, 0.031510f, 1.008098f, 0.000039f, 0.000150f, 0.000042f, 0.000865f, +0.000125f, 0.000743f, 0.000282f, 0.002838f, 0.000168f, 0.001461f, 0.000565f, 0.002836f, 0.023448f, 0.128565f, 0.031487f, 0.502760f, 0.000069f, 0.000237f, 0.000137f, 0.001398f, +0.000345f, 0.000440f, 0.000464f, 0.010163f, 0.000033f, 0.000062f, 0.000067f, 0.000728f, 0.043093f, 0.050775f, 0.034547f, 1.201494f, 0.000144f, 0.000106f, 0.000171f, 0.003780f, +0.000047f, 0.000117f, 0.000091f, 0.002005f, 0.000006f, 0.000023f, 0.000019f, 0.000204f, 0.009996f, 0.023059f, 0.011570f, 0.403146f, 0.000030f, 0.000042f, 0.000050f, 0.001120f, +0.000029f, 0.000072f, 0.000025f, 0.001123f, 0.000002f, 0.000007f, 0.000002f, 0.000053f, 0.006867f, 0.015910f, 0.003529f, 0.253063f, 0.000007f, 0.000010f, 0.000005f, 0.000249f, +0.000066f, 0.000145f, 0.000102f, 0.002301f, 0.000005f, 0.000015f, 0.000011f, 0.000124f, 0.007286f, 0.014872f, 0.006755f, 0.241743f, 0.000025f, 0.000031f, 0.000034f, 0.000769f, +0.009874f, 0.008446f, 0.012943f, 0.086116f, 1.028860f, 1.292943f, 2.020043f, 6.700973f, 13.092332f, 10.367984f, 10.252782f, 108.224270f, 0.271467f, 0.133951f, 0.313275f, 2.107366f, +0.001717f, 0.002876f, 0.003250f, 0.021663f, 0.253596f, 0.623901f, 0.718808f, 2.389038f, 3.872948f, 6.004407f, 4.378581f, 46.307291f, 0.070892f, 0.068483f, 0.118107f, 0.796016f, +0.000362f, 0.000609f, 0.000304f, 0.004171f, 0.024999f, 0.061770f, 0.031462f, 0.215197f, 0.914634f, 1.424157f, 0.459131f, 9.992836f, 0.005922f, 0.005746f, 0.004381f, 0.060761f, +0.001131f, 0.001676f, 0.001715f, 0.011741f, 0.088727f, 0.193148f, 0.201444f, 0.687660f, 1.332838f, 1.828380f, 1.206975f, 13.110603f, 0.027958f, 0.023897f, 0.037309f, 0.258268f, +0.000014f, 0.000019f, 0.000013f, 0.000342f, 0.001058f, 0.002070f, 0.001445f, 0.018734f, 0.132319f, 0.163239f, 0.072129f, 2.975054f, 0.000601f, 0.000462f, 0.000482f, 0.012681f, +0.000001f, 0.000001f, 0.000001f, 0.000018f, 0.000054f, 0.000208f, 0.000107f, 0.001388f, 0.008134f, 0.019645f, 0.006401f, 0.264521f, 0.000033f, 0.000049f, 0.000038f, 0.000995f, +0.000000f, 0.000001f, 0.000000f, 0.000009f, 0.000014f, 0.000055f, 0.000013f, 0.000337f, 0.005180f, 0.012565f, 0.001810f, 0.153938f, 0.000007f, 0.000011f, 0.000004f, 0.000205f, +0.000001f, 0.000002f, 0.000001f, 0.000023f, 0.000044f, 0.000150f, 0.000070f, 0.000933f, 0.006540f, 0.013977f, 0.004123f, 0.174993f, 0.000030f, 0.000040f, 0.000028f, 0.000755f, +0.000424f, 0.000872f, 0.000804f, 0.009508f, 0.048683f, 0.147128f, 0.138255f, 0.815245f, 2.220356f, 4.228586f, 2.515052f, 47.191117f, 0.008596f, 0.010200f, 0.014348f, 0.171564f, +0.000044f, 0.000178f, 0.000121f, 0.001436f, 0.007206f, 0.042633f, 0.029543f, 0.174538f, 0.394424f, 1.470576f, 0.644992f, 12.125531f, 0.001348f, 0.003131f, 0.003248f, 0.038916f, +0.000005f, 0.000022f, 0.000007f, 0.000159f, 0.000409f, 0.002432f, 0.000745f, 0.009059f, 0.053673f, 0.200983f, 0.038971f, 1.507736f, 0.000065f, 0.000151f, 0.000069f, 0.001712f, +0.000008f, 0.000028f, 0.000017f, 0.000210f, 0.000680f, 0.003561f, 0.002234f, 0.013554f, 0.036620f, 0.120811f, 0.047967f, 0.926186f, 0.000143f, 0.000295f, 0.000277f, 0.003406f, +0.000002f, 0.000001f, 0.000002f, 0.000057f, 0.000010f, 0.000011f, 0.000020f, 0.000264f, 0.005100f, 0.003615f, 0.003988f, 0.167719f, 0.000023f, 0.000010f, 0.000026f, 0.000698f, +0.000000f, 0.000000f, 0.000001f, 0.000016f, 0.000003f, 0.000006f, 0.000008f, 0.000105f, 0.001679f, 0.002331f, 0.001896f, 0.079883f, 0.000007f, 0.000006f, 0.000011f, 0.000293f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000000f, 0.000001f, 0.000000f, 0.000013f, 0.000552f, 0.000770f, 0.000277f, 0.024003f, 0.000001f, 0.000001f, 0.000001f, 0.000031f, +0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000001f, 0.000002f, 0.000003f, 0.000038f, 0.000722f, 0.000886f, 0.000653f, 0.028243f, 0.000003f, 0.000002f, 0.000004f, 0.000119f, +21.087740f, 17.884734f, 33.983089f, 30.001875f, 30.794886f, 38.367558f, 74.327616f, 32.716865f, 96.319545f, 75.623049f, 92.727039f, 129.877440f, 22.803677f, 11.155706f, 32.350456f, 28.876139f, +7.196053f, 11.948074f, 16.741476f, 14.808539f, 14.893460f, 36.327235f, 51.895990f, 22.886975f, 55.907610f, 85.933372f, 77.701565f, 109.041030f, 11.684721f, 11.190815f, 23.930992f, 21.401897f, +5.105855f, 8.514407f, 5.274309f, 9.601089f, 4.943664f, 12.110663f, 7.648645f, 6.941859f, 44.457961f, 68.631388f, 27.435065f, 79.232364f, 3.286688f, 3.161432f, 2.988811f, 5.500807f, +8.617404f, 12.660210f, 16.058510f, 14.589219f, 9.471986f, 20.442712f, 26.436794f, 11.974895f, 34.973513f, 47.565386f, 38.933860f, 56.117203f, 8.376484f, 7.098487f, 13.741478f, 12.622157f, +0.224340f, 0.296405f, 0.251652f, 0.868142f, 0.230635f, 0.447648f, 0.387487f, 0.666474f, 7.092942f, 8.675464f, 4.753135f, 26.014280f, 0.367579f, 0.280137f, 0.362985f, 1.266052f, +0.015908f, 0.041147f, 0.025762f, 0.089042f, 0.023178f, 0.088074f, 0.056219f, 0.096882f, 0.855508f, 2.048525f, 0.827646f, 4.538465f, 0.039139f, 0.058395f, 0.055797f, 0.194987f, +0.030439f, 0.079076f, 0.021887f, 0.155686f, 0.020748f, 0.079182f, 0.022345f, 0.079246f, 1.834633f, 4.412133f, 0.788074f, 8.893401f, 0.029689f, 0.044488f, 0.018793f, 0.135153f, +0.044512f, 0.101876f, 0.057739f, 0.204976f, 0.034444f, 0.115808f, 0.066918f, 0.118444f, 1.250488f, 2.649462f, 0.969013f, 5.457610f, 0.065560f, 0.086550f, 0.074863f, 0.268704f, +1.443648f, 2.944485f, 3.365064f, 5.280921f, 2.322943f, 6.960168f, 8.109783f, 6.345439f, 26.041123f, 49.169426f, 36.261952f, 90.283603f, 1.151068f, 1.354219f, 2.361979f, 3.747706f, +0.295829f, 1.181246f, 0.995497f, 1.565269f, 0.674639f, 3.957341f, 3.400234f, 2.665594f, 9.076784f, 33.552007f, 18.246950f, 45.517779f, 0.354185f, 0.815773f, 1.049233f, 1.667994f, +0.120948f, 0.485045f, 0.180716f, 0.584766f, 0.129036f, 0.760194f, 0.288765f, 0.465872f, 4.159065f, 15.440613f, 3.712374f, 19.058065f, 0.057406f, 0.132793f, 0.075508f, 0.247032f, +0.095576f, 0.337681f, 0.257618f, 0.416038f, 0.115755f, 0.600805f, 0.467313f, 0.376271f, 1.531878f, 5.010390f, 2.466674f, 6.319914f, 0.068501f, 0.139604f, 0.162543f, 0.265399f, +0.412315f, 0.313054f, 0.663504f, 2.333879f, 0.035808f, 0.039940f, 0.086304f, 0.151357f, 4.410267f, 3.099863f, 4.239736f, 23.660012f, 0.223138f, 0.097724f, 0.316104f, 1.124185f, +0.156618f, 0.232800f, 0.363850f, 1.282300f, 0.019277f, 0.042094f, 0.067075f, 0.117860f, 2.849501f, 3.921005f, 3.954662f, 22.111508f, 0.127272f, 0.109123f, 0.260290f, 0.927466f, +0.154738f, 0.231004f, 0.159616f, 1.157655f, 0.008910f, 0.019540f, 0.013766f, 0.049778f, 3.155214f, 4.360536f, 1.944316f, 22.372388f, 0.049849f, 0.042926f, 0.045266f, 0.331935f, +0.234212f, 0.308044f, 0.435833f, 1.577597f, 0.015310f, 0.029581f, 0.042670f, 0.077008f, 2.225993f, 2.710274f, 2.474535f, 14.210571f, 0.113937f, 0.086438f, 0.186645f, 0.683072f, +0.036979f, 0.059113f, 0.094671f, 0.327429f, 0.578785f, 1.359172f, 2.219282f, 3.826934f, 2.983161f, 4.414563f, 4.562388f, 25.034352f, 0.022719f, 0.020948f, 0.051202f, 0.179045f, +0.003656f, 0.011441f, 0.013511f, 0.046821f, 0.081095f, 0.372820f, 0.448903f, 0.775576f, 0.501638f, 1.453291f, 1.107573f, 6.089051f, 0.003373f, 0.006088f, 0.010973f, 0.038444f, +0.001295f, 0.004071f, 0.002126f, 0.015159f, 0.013442f, 0.062067f, 0.033039f, 0.117474f, 0.199204f, 0.579618f, 0.195289f, 2.209485f, 0.000474f, 0.000859f, 0.000684f, 0.004934f, +0.005193f, 0.014380f, 0.015374f, 0.054717f, 0.061178f, 0.248867f, 0.271262f, 0.481359f, 0.372237f, 0.954207f, 0.658311f, 3.717211f, 0.002868f, 0.004581f, 0.007474f, 0.026895f, +0.000019f, 0.000047f, 0.000034f, 0.000456f, 0.000209f, 0.000764f, 0.000557f, 0.003754f, 0.010577f, 0.024384f, 0.011260f, 0.241434f, 0.000018f, 0.000025f, 0.000028f, 0.000378f, +0.000000f, 0.000002f, 0.000001f, 0.000014f, 0.000006f, 0.000044f, 0.000023f, 0.000158f, 0.000370f, 0.001668f, 0.000568f, 0.012203f, 0.000001f, 0.000002f, 0.000001f, 0.000017f, +0.000000f, 0.000002f, 0.000000f, 0.000012f, 0.000003f, 0.000020f, 0.000005f, 0.000065f, 0.000396f, 0.001794f, 0.000270f, 0.011941f, 0.000000f, 0.000001f, 0.000000f, 0.000006f, +0.000001f, 0.000006f, 0.000003f, 0.000037f, 0.000011f, 0.000068f, 0.000033f, 0.000229f, 0.000641f, 0.002559f, 0.000789f, 0.017406f, 0.000001f, 0.000003f, 0.000002f, 0.000028f, +0.002055f, 0.007900f, 0.007609f, 0.046783f, 0.035439f, 0.200142f, 0.196553f, 0.602490f, 0.654683f, 2.329900f, 1.448256f, 14.126038f, 0.000931f, 0.002064f, 0.003035f, 0.018862f, +0.000122f, 0.000918f, 0.000652f, 0.004017f, 0.002982f, 0.032967f, 0.023875f, 0.073323f, 0.066109f, 0.460594f, 0.211126f, 2.063238f, 0.000083f, 0.000360f, 0.000391f, 0.002432f, +0.000025f, 0.000188f, 0.000059f, 0.000749f, 0.000285f, 0.003162f, 0.001013f, 0.006399f, 0.015127f, 0.105850f, 0.021450f, 0.431396f, 0.000007f, 0.000029f, 0.000014f, 0.000180f, +0.000047f, 0.000311f, 0.000200f, 0.001267f, 0.000607f, 0.005937f, 0.003892f, 0.012277f, 0.013235f, 0.081589f, 0.033855f, 0.339814f, 0.000019f, 0.000073f, 0.000072f, 0.000459f, +0.000003f, 0.000004f, 0.000007f, 0.000100f, 0.000003f, 0.000006f, 0.000010f, 0.000069f, 0.000536f, 0.000710f, 0.000818f, 0.017891f, 0.000001f, 0.000001f, 0.000002f, 0.000027f, +0.000000f, 0.000001f, 0.000001f, 0.000016f, 0.000000f, 0.000002f, 0.000002f, 0.000016f, 0.000100f, 0.000260f, 0.000221f, 0.004844f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, +0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000055f, 0.000144f, 0.000054f, 0.002447f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000001f, 0.000001f, 0.000002f, 0.000023f, 0.000000f, 0.000001f, 0.000002f, 0.000012f, 0.000093f, 0.000213f, 0.000164f, 0.003693f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, +0.019499f, 0.020735f, 0.022501f, 0.237798f, 0.024483f, 0.038246f, 0.042315f, 0.222967f, 3.952008f, 3.890416f, 2.724379f, 45.679610f, 0.012357f, 0.007580f, 0.012553f, 0.134133f, +0.002053f, 0.004275f, 0.003421f, 0.036220f, 0.003654f, 0.011175f, 0.009117f, 0.048132f, 0.707871f, 1.364217f, 0.704483f, 11.834727f, 0.001954f, 0.002346f, 0.002866f, 0.030678f, +0.000548f, 0.001146f, 0.000406f, 0.008838f, 0.000456f, 0.001402f, 0.000506f, 0.005494f, 0.211845f, 0.410043f, 0.093612f, 3.236357f, 0.000207f, 0.000249f, 0.000135f, 0.002967f, +0.001696f, 0.003124f, 0.002263f, 0.024613f, 0.001603f, 0.004337f, 0.003203f, 0.017370f, 0.305428f, 0.520834f, 0.243475f, 4.200982f, 0.000966f, 0.001027f, 0.001135f, 0.012480f, +0.000002f, 0.000003f, 0.000001f, 0.000058f, 0.000002f, 0.000004f, 0.000002f, 0.000038f, 0.002463f, 0.003777f, 0.001182f, 0.077429f, 0.000002f, 0.000002f, 0.000001f, 0.000050f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000092f, 0.000275f, 0.000064f, 0.004168f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000074f, 0.000223f, 0.000023f, 0.003074f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000092f, 0.000246f, 0.000051f, 0.003457f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000865f, 0.002212f, 0.001444f, 0.027121f, 0.001197f, 0.004496f, 0.002992f, 0.028021f, 0.692321f, 1.639010f, 0.690330f, 20.575120f, 0.000404f, 0.000596f, 0.000594f, 0.011280f, +0.000055f, 0.000274f, 0.000132f, 0.002481f, 0.000107f, 0.000789f, 0.000387f, 0.003632f, 0.074466f, 0.345132f, 0.107195f, 3.201062f, 0.000038f, 0.000111f, 0.000081f, 0.001549f, +0.000008f, 0.000042f, 0.000009f, 0.000349f, 0.000008f, 0.000057f, 0.000012f, 0.000239f, 0.012841f, 0.059775f, 0.008208f, 0.504403f, 0.000002f, 0.000007f, 0.000002f, 0.000086f, +0.000012f, 0.000054f, 0.000024f, 0.000455f, 0.000013f, 0.000083f, 0.000037f, 0.000354f, 0.008668f, 0.035549f, 0.009995f, 0.306557f, 0.000005f, 0.000013f, 0.000009f, 0.000170f, +0.000012f, 0.000011f, 0.000014f, 0.000577f, 0.000001f, 0.000001f, 0.000002f, 0.000032f, 0.005644f, 0.004974f, 0.003885f, 0.259533f, 0.000004f, 0.000002f, 0.000004f, 0.000163f, +0.000001f, 0.000003f, 0.000002f, 0.000098f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.001125f, 0.001941f, 0.001118f, 0.074847f, 0.000001f, 0.000001f, 0.000001f, 0.000041f, +0.000001f, 0.000001f, 0.000000f, 0.000033f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000469f, 0.000813f, 0.000207f, 0.028501f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, +0.000001f, 0.000002f, 0.000002f, 0.000083f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000606f, 0.000926f, 0.000483f, 0.033178f, 0.000000f, 0.000000f, 0.000000f, 0.000021f, +0.001269f, 0.000812f, 0.001429f, 0.018259f, 0.102928f, 0.096744f, 0.173524f, 1.105688f, 6.403900f, 3.793073f, 4.306173f, 87.311341f, 0.026488f, 0.009776f, 0.026247f, 0.339154f, +0.000190f, 0.000238f, 0.000308f, 0.003948f, 0.021805f, 0.040124f, 0.053071f, 0.338813f, 1.628216f, 1.888035f, 1.580613f, 32.109815f, 0.005945f, 0.004296f, 0.008505f, 0.110109f, +0.000024f, 0.000031f, 0.000017f, 0.000461f, 0.001304f, 0.002410f, 0.001409f, 0.018513f, 0.233255f, 0.271651f, 0.100541f, 4.203303f, 0.000301f, 0.000219f, 0.000191f, 0.005098f, +0.000092f, 0.000102f, 0.000120f, 0.001582f, 0.005640f, 0.009183f, 0.010995f, 0.072094f, 0.414225f, 0.425006f, 0.322092f, 6.720473f, 0.001733f, 0.001108f, 0.001986f, 0.026409f, +0.000001f, 0.000001f, 0.000001f, 0.000026f, 0.000038f, 0.000056f, 0.000045f, 0.001119f, 0.023423f, 0.021613f, 0.010963f, 0.868612f, 0.000021f, 0.000012f, 0.000015f, 0.000739f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000005f, 0.000003f, 0.000071f, 0.001237f, 0.002235f, 0.000836f, 0.066380f, 0.000001f, 0.000001f, 0.000001f, 0.000050f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000010f, 0.000478f, 0.000867f, 0.000143f, 0.023433f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000003f, 0.000001f, 0.000035f, 0.000736f, 0.001176f, 0.000398f, 0.032463f, 0.000001f, 0.000001f, 0.000001f, 0.000028f, +0.000061f, 0.000094f, 0.000100f, 0.002270f, 0.005485f, 0.012397f, 0.013374f, 0.151485f, 1.223030f, 1.742125f, 1.189552f, 42.873926f, 0.000944f, 0.000838f, 0.001354f, 0.031094f, +0.000006f, 0.000017f, 0.000013f, 0.000295f, 0.000698f, 0.003088f, 0.002456f, 0.027875f, 0.186733f, 0.520731f, 0.262200f, 9.468390f, 0.000127f, 0.000221f, 0.000263f, 0.006062f, +0.000000f, 0.000001f, 0.000000f, 0.000020f, 0.000024f, 0.000107f, 0.000038f, 0.000878f, 0.015414f, 0.043172f, 0.009610f, 0.714191f, 0.000004f, 0.000006f, 0.000003f, 0.000162f, +0.000001f, 0.000002f, 0.000001f, 0.000032f, 0.000049f, 0.000191f, 0.000137f, 0.001600f, 0.012816f, 0.031624f, 0.014415f, 0.534641f, 0.000010f, 0.000015f, 0.000017f, 0.000392f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000632f, 0.000335f, 0.000425f, 0.034298f, 0.000001f, 0.000000f, 0.000001f, 0.000028f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000179f, 0.000186f, 0.000173f, 0.014040f, 0.000000f, 0.000000f, 0.000000f, 0.000010f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000036f, 0.000037f, 0.000015f, 0.002559f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000057f, 0.000052f, 0.000044f, 0.003670f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +5.883660f, 3.732242f, 8.141462f, 13.806528f, 6.686468f, 6.230917f, 13.857669f, 11.716778f, 102.254810f, 60.047269f, 84.527496f, 227.416240f, 4.829313f, 1.767043f, 5.882782f, 10.086437f, +1.725656f, 2.143027f, 3.447274f, 5.857208f, 2.779433f, 5.070635f, 8.316031f, 7.044777f, 51.013235f, 58.646675f, 60.878462f, 164.104410f, 2.126872f, 1.523541f, 3.740293f, 6.425304f, +0.742749f, 0.926398f, 0.658811f, 2.303627f, 0.559658f, 1.025442f, 0.743499f, 1.296189f, 24.607926f, 28.413038f, 13.039277f, 72.334638f, 0.362907f, 0.261090f, 0.283372f, 1.001800f, +1.527654f, 1.678646f, 2.444420f, 4.265789f, 1.306744f, 2.109392f, 3.131698f, 2.724829f, 23.590641f, 23.997232f, 22.550174f, 62.433122f, 1.127128f, 0.714409f, 1.587694f, 2.801326f, +0.022652f, 0.022385f, 0.021819f, 0.144581f, 0.018123f, 0.026309f, 0.026145f, 0.086378f, 2.725090f, 2.492968f, 1.568037f, 16.484824f, 0.028172f, 0.016058f, 0.023888f, 0.160042f, +0.001381f, 0.002671f, 0.001920f, 0.012746f, 0.001565f, 0.004449f, 0.003260f, 0.010792f, 0.282501f, 0.505950f, 0.234673f, 2.471862f, 0.002578f, 0.002877f, 0.003156f, 0.021185f, +0.001602f, 0.003114f, 0.000989f, 0.013518f, 0.000850f, 0.002426f, 0.000786f, 0.005355f, 0.367501f, 0.661040f, 0.135550f, 2.938301f, 0.001186f, 0.001330f, 0.000645f, 0.008908f, +0.002856f, 0.004888f, 0.003181f, 0.021690f, 0.001720f, 0.004325f, 0.002869f, 0.009754f, 0.305256f, 0.483740f, 0.203113f, 2.197385f, 0.003193f, 0.003152f, 0.003130f, 0.021582f, +0.453592f, 0.691964f, 0.907862f, 2.736732f, 0.567994f, 1.272900f, 1.702692f, 2.559086f, 31.132643f, 43.966405f, 37.224543f, 178.026050f, 0.274516f, 0.241560f, 0.483688f, 1.474182f, +0.079889f, 0.238592f, 0.230839f, 0.697195f, 0.141781f, 0.622043f, 0.613590f, 0.923973f, 9.326760f, 25.786173f, 16.099448f, 77.143294f, 0.072601f, 0.125069f, 0.184673f, 0.563926f, +0.019813f, 0.059431f, 0.025420f, 0.158001f, 0.016450f, 0.072486f, 0.031610f, 0.097959f, 2.592435f, 7.198571f, 1.986945f, 19.593366f, 0.007138f, 0.012350f, 0.008062f, 0.050663f, +0.019080f, 0.050421f, 0.044160f, 0.136989f, 0.017984f, 0.069813f, 0.062340f, 0.096417f, 1.163622f, 2.846612f, 1.608872f, 7.918023f, 0.010380f, 0.015822f, 0.021149f, 0.066331f, +0.029160f, 0.016559f, 0.040292f, 0.272241f, 0.001971f, 0.001644f, 0.004079f, 0.013740f, 1.186788f, 0.623908f, 0.979646f, 10.501258f, 0.011978f, 0.003924f, 0.014570f, 0.099535f, +0.009520f, 0.010584f, 0.018991f, 0.128560f, 0.000912f, 0.001489f, 0.002724f, 0.009196f, 0.659052f, 0.678293f, 0.785383f, 8.435041f, 0.005872f, 0.003766f, 0.010312f, 0.070579f, +0.005706f, 0.006371f, 0.005054f, 0.070406f, 0.000256f, 0.000419f, 0.000339f, 0.002356f, 0.442683f, 0.457587f, 0.234236f, 5.177198f, 0.001395f, 0.000899f, 0.001088f, 0.015323f, +0.010524f, 0.010353f, 0.016816f, 0.116924f, 0.000535f, 0.000774f, 0.001281f, 0.004442f, 0.380595f, 0.346595f, 0.363291f, 4.007457f, 0.003886f, 0.002205f, 0.005466f, 0.038427f, +0.005764f, 0.006891f, 0.012670f, 0.084173f, 0.070203f, 0.123305f, 0.231138f, 0.765608f, 1.769152f, 1.958149f, 2.323285f, 24.487426f, 0.002688f, 0.001854f, 0.005201f, 0.034937f, +0.000490f, 0.001146f, 0.001554f, 0.010345f, 0.008454f, 0.029070f, 0.040184f, 0.133359f, 0.255694f, 0.554055f, 0.484758f, 5.119162f, 0.000343f, 0.000463f, 0.000958f, 0.006448f, +0.000105f, 0.000247f, 0.000148f, 0.002032f, 0.000850f, 0.002936f, 0.001794f, 0.012253f, 0.061595f, 0.134047f, 0.051849f, 1.126818f, 0.000029f, 0.000040f, 0.000036f, 0.000502f, +0.000514f, 0.001065f, 0.001307f, 0.008937f, 0.004715f, 0.014345f, 0.017951f, 0.061187f, 0.140262f, 0.268925f, 0.212997f, 2.310229f, 0.000216f, 0.000258f, 0.000482f, 0.003334f, +0.000001f, 0.000002f, 0.000002f, 0.000042f, 0.000009f, 0.000025f, 0.000021f, 0.000272f, 0.002270f, 0.003914f, 0.002075f, 0.085465f, 0.000001f, 0.000001f, 0.000001f, 0.000027f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000001f, 0.000001f, 0.000010f, 0.000068f, 0.000230f, 0.000090f, 0.003713f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000044f, 0.000150f, 0.000026f, 0.002204f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000001f, 0.000001f, 0.000011f, 0.000087f, 0.000261f, 0.000092f, 0.003915f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000361f, 0.001037f, 0.001147f, 0.013543f, 0.004841f, 0.020447f, 0.023053f, 0.135735f, 0.437226f, 1.163810f, 0.830506f, 15.560163f, 0.000124f, 0.000206f, 0.000347f, 0.004145f, +0.000018f, 0.000104f, 0.000084f, 0.001000f, 0.000350f, 0.002895f, 0.002407f, 0.014198f, 0.037947f, 0.197745f, 0.104059f, 1.953374f, 0.000010f, 0.000031f, 0.000038f, 0.000459f, +0.000002f, 0.000013f, 0.000005f, 0.000113f, 0.000020f, 0.000168f, 0.000062f, 0.000752f, 0.005267f, 0.027567f, 0.006413f, 0.247757f, 0.000000f, 0.000002f, 0.000001f, 0.000021f, +0.000005f, 0.000026f, 0.000019f, 0.000233f, 0.000053f, 0.000385f, 0.000290f, 0.001757f, 0.005616f, 0.025895f, 0.012335f, 0.237829f, 0.000002f, 0.000005f, 0.000005f, 0.000064f, +0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000081f, 0.000080f, 0.000106f, 0.004436f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000013f, 0.000025f, 0.000025f, 0.001032f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000008f, 0.000004f, 0.000316f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000009f, 0.000015f, 0.000013f, 0.000582f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.011136f, 0.017969f, 0.015051f, 0.144626f, 0.016183f, 0.038363f, 0.032760f, 0.156952f, 3.374181f, 5.040423f, 2.724399f, 41.533249f, 0.016767f, 0.015607f, 0.019950f, 0.193821f, +0.000662f, 0.002090f, 0.001291f, 0.012429f, 0.001363f, 0.006324f, 0.003982f, 0.019116f, 0.340995f, 0.997237f, 0.397482f, 6.071219f, 0.001496f, 0.002726f, 0.002569f, 0.025011f, +0.000193f, 0.000612f, 0.000167f, 0.003311f, 0.000186f, 0.000866f, 0.000241f, 0.002382f, 0.111409f, 0.327229f, 0.057662f, 1.812512f, 0.000173f, 0.000316f, 0.000132f, 0.002641f, +0.000815f, 0.002278f, 0.001274f, 0.012596f, 0.000892f, 0.003661f, 0.002087f, 0.010289f, 0.219431f, 0.567818f, 0.204879f, 3.214132f, 0.001103f, 0.001779f, 0.001518f, 0.015174f, +0.000001f, 0.000001f, 0.000001f, 0.000020f, 0.000001f, 0.000002f, 0.000001f, 0.000015f, 0.001197f, 0.002786f, 0.000673f, 0.040083f, 0.000001f, 0.000002f, 0.000001f, 0.000041f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000025f, 0.000115f, 0.000020f, 0.001218f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000022f, 0.000101f, 0.000008f, 0.000980f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000038f, 0.000152f, 0.000025f, 0.001506f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000275f, 0.001067f, 0.000538f, 0.009185f, 0.000440f, 0.002511f, 0.001290f, 0.010984f, 0.329159f, 1.182497f, 0.384421f, 10.417490f, 0.000305f, 0.000684f, 0.000526f, 0.009077f, +0.000010f, 0.000075f, 0.000028f, 0.000474f, 0.000022f, 0.000249f, 0.000094f, 0.000803f, 0.019976f, 0.140491f, 0.033680f, 0.914448f, 0.000016f, 0.000072f, 0.000041f, 0.000703f, +0.000002f, 0.000013f, 0.000002f, 0.000073f, 0.000002f, 0.000020f, 0.000003f, 0.000058f, 0.003761f, 0.026564f, 0.002815f, 0.157307f, 0.000001f, 0.000005f, 0.000001f, 0.000043f, +0.000003f, 0.000022f, 0.000007f, 0.000130f, 0.000004f, 0.000039f, 0.000013f, 0.000117f, 0.003468f, 0.021581f, 0.004684f, 0.130608f, 0.000003f, 0.000013f, 0.000006f, 0.000115f, +0.000003f, 0.000005f, 0.000005f, 0.000176f, 0.000000f, 0.000001f, 0.000001f, 0.000011f, 0.002415f, 0.003230f, 0.001947f, 0.118269f, 0.000003f, 0.000002f, 0.000003f, 0.000118f, +0.000000f, 0.000001f, 0.000000f, 0.000017f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000272f, 0.000711f, 0.000316f, 0.019244f, 0.000000f, 0.000000f, 0.000000f, 0.000017f, +0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000124f, 0.000325f, 0.000064f, 0.008000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000001f, 0.000001f, 0.000021f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000218f, 0.000506f, 0.000204f, 0.012723f, 0.000000f, 0.000000f, 0.000000f, 0.000013f, +0.000624f, 0.000606f, 0.000823f, 0.009558f, 0.058561f, 0.083525f, 0.115634f, 0.669929f, 4.706149f, 4.229924f, 3.706510f, 68.330523f, 0.030936f, 0.017326f, 0.035905f, 0.421824f, +0.000053f, 0.000100f, 0.000100f, 0.001166f, 0.007000f, 0.019545f, 0.019954f, 0.115824f, 0.675114f, 1.187942f, 0.767615f, 14.178356f, 0.003918f, 0.004295f, 0.006564f, 0.077268f, +0.000007f, 0.000014f, 0.000006f, 0.000149f, 0.000457f, 0.001282f, 0.000578f, 0.006909f, 0.105585f, 0.186596f, 0.053305f, 2.026216f, 0.000217f, 0.000239f, 0.000161f, 0.003906f, +0.000038f, 0.000064f, 0.000058f, 0.000697f, 0.002700f, 0.006671f, 0.006165f, 0.036757f, 0.256151f, 0.398819f, 0.233288f, 4.425712f, 0.001703f, 0.001653f, 0.002286f, 0.027640f, +0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000012f, 0.000028f, 0.000017f, 0.000386f, 0.009800f, 0.013723f, 0.005373f, 0.387043f, 0.000014f, 0.000012f, 0.000011f, 0.000523f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000014f, 0.000292f, 0.000801f, 0.000231f, 0.016688f, 0.000000f, 0.000001f, 0.000000f, 0.000020f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000123f, 0.000339f, 0.000043f, 0.006432f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000010f, 0.000259f, 0.000628f, 0.000164f, 0.012172f, 0.000000f, 0.000001f, 0.000000f, 0.000017f, +0.000017f, 0.000039f, 0.000032f, 0.000662f, 0.001738f, 0.005960f, 0.004963f, 0.051111f, 0.500501f, 1.081852f, 0.570170f, 18.684623f, 0.000614f, 0.000827f, 0.001031f, 0.021535f, +0.000001f, 0.000004f, 0.000002f, 0.000048f, 0.000125f, 0.000838f, 0.000514f, 0.005306f, 0.043115f, 0.182451f, 0.070909f, 2.328152f, 0.000047f, 0.000123f, 0.000113f, 0.002369f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000005f, 0.000032f, 0.000009f, 0.000182f, 0.003885f, 0.016514f, 0.002837f, 0.191715f, 0.000001f, 0.000004f, 0.000002f, 0.000069f, +0.000000f, 0.000001f, 0.000000f, 0.000008f, 0.000013f, 0.000077f, 0.000043f, 0.000454f, 0.004413f, 0.016525f, 0.005814f, 0.196062f, 0.000005f, 0.000013f, 0.000011f, 0.000229f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000233f, 0.000187f, 0.000183f, 0.013453f, 0.000000f, 0.000000f, 0.000000f, 0.000018f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000037f, 0.000059f, 0.000042f, 0.003107f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000013f, 0.000004f, 0.000618f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000018f, 0.000025f, 0.000016f, 0.001211f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +1.443791f, 1.389783f, 2.339979f, 3.607981f, 1.899073f, 2.685451f, 4.609860f, 3.543856f, 37.512581f, 33.427714f, 36.319829f, 88.845948f, 2.815587f, 1.563331f, 4.017161f, 6.262456f, +0.238922f, 0.450245f, 0.559023f, 0.863604f, 0.445395f, 1.233025f, 1.560839f, 1.202207f, 10.558935f, 18.420481f, 14.758886f, 36.172664f, 0.699631f, 0.760506f, 1.441074f, 2.250840f, +0.112266f, 0.212484f, 0.116633f, 0.370803f, 0.097908f, 0.272225f, 0.152345f, 0.241483f, 5.560564f, 9.742758f, 3.451040f, 17.406571f, 0.130325f, 0.142280f, 0.119191f, 0.383123f, +0.315443f, 0.525988f, 0.591187f, 0.938034f, 0.312302f, 0.765001f, 0.876631f, 0.693500f, 7.282361f, 11.241228f, 8.153332f, 20.524410f, 0.552963f, 0.531851f, 0.912311f, 1.463557f, +0.003165f, 0.004746f, 0.003570f, 0.021512f, 0.002931f, 0.006456f, 0.004952f, 0.014875f, 0.569197f, 0.790167f, 0.383611f, 3.666820f, 0.009352f, 0.008089f, 0.009288f, 0.056576f, +0.000109f, 0.000319f, 0.000177f, 0.001070f, 0.000143f, 0.000616f, 0.000348f, 0.001049f, 0.033293f, 0.090480f, 0.032392f, 0.310223f, 0.000483f, 0.000818f, 0.000692f, 0.004225f, +0.000138f, 0.000407f, 0.000100f, 0.001239f, 0.000085f, 0.000367f, 0.000092f, 0.000568f, 0.047282f, 0.129057f, 0.020426f, 0.402580f, 0.000243f, 0.000413f, 0.000154f, 0.001940f, +0.000336f, 0.000872f, 0.000438f, 0.002716f, 0.000234f, 0.000893f, 0.000457f, 0.001413f, 0.053652f, 0.129019f, 0.041813f, 0.411292f, 0.000892f, 0.001336f, 0.001024f, 0.006420f, +0.061983f, 0.143485f, 0.145304f, 0.398253f, 0.089833f, 0.305497f, 0.315414f, 0.431023f, 6.359984f, 13.629546f, 8.906814f, 38.729945f, 0.089125f, 0.119008f, 0.183928f, 0.509688f, +0.006159f, 0.027914f, 0.020845f, 0.057243f, 0.012652f, 0.084232f, 0.064131f, 0.087805f, 1.075016f, 4.510157f, 2.173442f, 9.469028f, 0.013299f, 0.034765f, 0.039622f, 0.110007f, +0.001668f, 0.007591f, 0.002506f, 0.014162f, 0.001603f, 0.010716f, 0.003607f, 0.010163f, 0.326211f, 1.374540f, 0.292839f, 2.625569f, 0.001427f, 0.003748f, 0.001888f, 0.010789f, +0.002194f, 0.008798f, 0.005947f, 0.016775f, 0.002393f, 0.014099f, 0.009717f, 0.013665f, 0.200028f, 0.742554f, 0.323932f, 1.449504f, 0.002836f, 0.006559f, 0.006767f, 0.019298f, +0.003586f, 0.003090f, 0.005804f, 0.035656f, 0.000281f, 0.000355f, 0.000680f, 0.002083f, 0.218209f, 0.174076f, 0.210970f, 2.056189f, 0.003500f, 0.001740f, 0.004987f, 0.030973f, +0.000661f, 0.001114f, 0.001543f, 0.009500f, 0.000073f, 0.000182f, 0.000256f, 0.000787f, 0.068369f, 0.106778f, 0.095428f, 0.931865f, 0.000968f, 0.000942f, 0.001991f, 0.012392f, +0.000432f, 0.000732f, 0.000448f, 0.005680f, 0.000022f, 0.000056f, 0.000035f, 0.000220f, 0.050135f, 0.078640f, 0.031071f, 0.624406f, 0.000251f, 0.000245f, 0.000229f, 0.002937f, +0.001089f, 0.001626f, 0.002038f, 0.012886f, 0.000064f, 0.000141f, 0.000180f, 0.000567f, 0.058885f, 0.081373f, 0.065833f, 0.660283f, 0.000956f, 0.000823f, 0.001574f, 0.010062f, +0.003296f, 0.005979f, 0.008485f, 0.051254f, 0.046460f, 0.123830f, 0.179163f, 0.539578f, 1.512300f, 2.540030f, 2.326098f, 22.291478f, 0.003651f, 0.003821f, 0.008276f, 0.050544f, +0.000158f, 0.000561f, 0.000587f, 0.003554f, 0.003157f, 0.016472f, 0.017574f, 0.053029f, 0.123321f, 0.405499f, 0.273839f, 2.629291f, 0.000263f, 0.000539f, 0.000860f, 0.005263f, +0.000037f, 0.000132f, 0.000061f, 0.000762f, 0.000347f, 0.001816f, 0.000857f, 0.005319f, 0.032431f, 0.107103f, 0.031976f, 0.631830f, 0.000024f, 0.000050f, 0.000036f, 0.000447f, +0.000247f, 0.000778f, 0.000737f, 0.004579f, 0.002626f, 0.012122f, 0.011708f, 0.036286f, 0.100891f, 0.293538f, 0.179448f, 1.769661f, 0.000246f, 0.000447f, 0.000646f, 0.004059f, +0.000000f, 0.000001f, 0.000001f, 0.000015f, 0.000003f, 0.000014f, 0.000009f, 0.000109f, 0.001105f, 0.002891f, 0.001183f, 0.044297f, 0.000001f, 0.000001f, 0.000001f, 0.000022f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000019f, 0.000096f, 0.000029f, 0.001086f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000013f, 0.000068f, 0.000009f, 0.000704f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000001f, 0.000000f, 0.000004f, 0.000036f, 0.000162f, 0.000044f, 0.001707f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000115f, 0.000501f, 0.000428f, 0.004592f, 0.001784f, 0.011435f, 0.009951f, 0.053270f, 0.208126f, 0.840664f, 0.463037f, 7.887816f, 0.000094f, 0.000236f, 0.000308f, 0.003339f, +0.000003f, 0.000028f, 0.000018f, 0.000191f, 0.000073f, 0.000913f, 0.000586f, 0.003144f, 0.010192f, 0.080592f, 0.032734f, 0.558692f, 0.000004f, 0.000020f, 0.000019f, 0.000209f, +0.000000f, 0.000004f, 0.000001f, 0.000024f, 0.000005f, 0.000058f, 0.000016f, 0.000182f, 0.001544f, 0.012265f, 0.002202f, 0.077361f, 0.000000f, 0.000001f, 0.000000f, 0.000010f, +0.000001f, 0.000011f, 0.000006f, 0.000066f, 0.000016f, 0.000181f, 0.000105f, 0.000580f, 0.002249f, 0.015739f, 0.005787f, 0.101449f, 0.000001f, 0.000004f, 0.000004f, 0.000043f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000035f, 0.000052f, 0.000053f, 0.002024f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000009f, 0.000007f, 0.000266f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000001f, 0.000089f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000008f, 0.000006f, 0.000223f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.005649f, 0.008779f, 0.007132f, 0.089865f, 0.006571f, 0.015002f, 0.012425f, 0.078059f, 1.693550f, 2.436380f, 1.277219f, 25.532425f, 0.005202f, 0.004663f, 0.005782f, 0.073655f, +0.000379f, 0.001152f, 0.000690f, 0.008712f, 0.000624f, 0.002790f, 0.001704f, 0.010725f, 0.193067f, 0.543759f, 0.210205f, 4.210195f, 0.000524f, 0.000919f, 0.000840f, 0.010722f, +0.000094f, 0.000287f, 0.000076f, 0.001973f, 0.000072f, 0.000325f, 0.000088f, 0.001136f, 0.053620f, 0.151674f, 0.025922f, 1.068457f, 0.000051f, 0.000091f, 0.000037f, 0.000962f, +0.000283f, 0.000761f, 0.000413f, 0.005351f, 0.000247f, 0.000979f, 0.000541f, 0.003498f, 0.075294f, 0.187636f, 0.065663f, 1.350797f, 0.000234f, 0.000363f, 0.000301f, 0.003942f, +0.000000f, 0.000001f, 0.000000f, 0.000014f, 0.000000f, 0.000001f, 0.000000f, 0.000009f, 0.000668f, 0.001497f, 0.000351f, 0.027394f, 0.000000f, 0.000001f, 0.000000f, 0.000017f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000016f, 0.000069f, 0.000012f, 0.000939f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, 0.000052f, 0.000004f, 0.000642f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000056f, 0.000009f, 0.000704f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000173f, 0.000647f, 0.000316f, 0.007076f, 0.000222f, 0.001217f, 0.000606f, 0.006772f, 0.204815f, 0.708603f, 0.223423f, 7.939340f, 0.000117f, 0.000253f, 0.000189f, 0.004276f, +0.000007f, 0.000051f, 0.000018f, 0.000412f, 0.000013f, 0.000136f, 0.000050f, 0.000559f, 0.014021f, 0.094969f, 0.022081f, 0.786159f, 0.000007f, 0.000030f, 0.000016f, 0.000374f, +0.000001f, 0.000007f, 0.000001f, 0.000054f, 0.000001f, 0.000009f, 0.000001f, 0.000034f, 0.002244f, 0.015264f, 0.001569f, 0.114961f, 0.000000f, 0.000002f, 0.000000f, 0.000019f, +0.000001f, 0.000009f, 0.000003f, 0.000068f, 0.000001f, 0.000013f, 0.000004f, 0.000049f, 0.001475f, 0.008841f, 0.001861f, 0.068049f, 0.000001f, 0.000003f, 0.000002f, 0.000037f, +0.000005f, 0.000007f, 0.000006f, 0.000306f, 0.000000f, 0.000001f, 0.000001f, 0.000016f, 0.003395f, 0.004372f, 0.002556f, 0.203620f, 0.000002f, 0.000002f, 0.000002f, 0.000126f, +0.000000f, 0.000001f, 0.000001f, 0.000033f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000431f, 0.001086f, 0.000468f, 0.037375f, 0.000000f, 0.000000f, 0.000000f, 0.000020f, +0.000000f, 0.000000f, 0.000000f, 0.000010f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000167f, 0.000422f, 0.000080f, 0.013207f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000001f, 0.000000f, 0.000025f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000210f, 0.000468f, 0.000183f, 0.014974f, 0.000000f, 0.000000f, 0.000000f, 0.000009f, +0.000665f, 0.000621f, 0.000818f, 0.012470f, 0.049925f, 0.068577f, 0.092080f, 0.699534f, 4.959286f, 4.292740f, 3.648243f, 88.193099f, 0.020153f, 0.010869f, 0.021846f, 0.336558f, +0.000063f, 0.000116f, 0.000112f, 0.001716f, 0.006732f, 0.018102f, 0.017924f, 0.136430f, 0.802529f, 1.359965f, 0.852300f, 20.643154f, 0.002879f, 0.003040f, 0.004506f, 0.069544f, +0.000007f, 0.000014f, 0.000006f, 0.000186f, 0.000374f, 0.001009f, 0.000442f, 0.006918f, 0.106693f, 0.181587f, 0.050311f, 2.507760f, 0.000135f, 0.000144f, 0.000094f, 0.002988f, +0.000028f, 0.000045f, 0.000040f, 0.000621f, 0.001574f, 0.003744f, 0.003356f, 0.026239f, 0.184536f, 0.276699f, 0.156979f, 3.905110f, 0.000759f, 0.000709f, 0.000951f, 0.015076f, +0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000012f, 0.000025f, 0.000015f, 0.000448f, 0.011481f, 0.015482f, 0.005879f, 0.555362f, 0.000010f, 0.000009f, 0.000008f, 0.000464f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000018f, 0.000386f, 0.001019f, 0.000285f, 0.027012f, 0.000000f, 0.000000f, 0.000000f, 0.000020f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000138f, 0.000367f, 0.000045f, 0.008849f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000008f, 0.000207f, 0.000485f, 0.000123f, 0.011940f, 0.000000f, 0.000000f, 0.000000f, 0.000010f, +0.000022f, 0.000050f, 0.000040f, 0.001070f, 0.001837f, 0.006067f, 0.004899f, 0.066164f, 0.653859f, 1.361116f, 0.695741f, 29.897121f, 0.000496f, 0.000643f, 0.000778f, 0.021301f, +0.000001f, 0.000006f, 0.000003f, 0.000088f, 0.000149f, 0.000962f, 0.000573f, 0.007749f, 0.063539f, 0.258943f, 0.097605f, 4.202296f, 0.000043f, 0.000108f, 0.000096f, 0.002643f, +0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000005f, 0.000031f, 0.000008f, 0.000226f, 0.004867f, 0.019923f, 0.003320f, 0.294158f, 0.000001f, 0.000003f, 0.000001f, 0.000065f, +0.000000f, 0.000001f, 0.000000f, 0.000009f, 0.000009f, 0.000054f, 0.000029f, 0.000402f, 0.003942f, 0.014214f, 0.004850f, 0.214471f, 0.000003f, 0.000007f, 0.000005f, 0.000155f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000010f, 0.000687f, 0.000533f, 0.000505f, 0.048628f, 0.000001f, 0.000000f, 0.000001f, 0.000040f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000124f, 0.000188f, 0.000131f, 0.012670f, 0.000000f, 0.000000f, 0.000000f, 0.000009f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000023f, 0.000035f, 0.000011f, 0.002143f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000036f, 0.000048f, 0.000030f, 0.002993f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +1.760054f, 1.631611f, 2.664394f, 5.387062f, 1.853002f, 2.523479f, 4.201332f, 4.235227f, 45.242902f, 38.826538f, 40.914995f, 131.243450f, 2.099186f, 1.122488f, 2.797476f, 5.718645f, +0.328554f, 0.596278f, 0.718036f, 1.454563f, 0.490241f, 1.307027f, 1.604676f, 1.620728f, 14.365604f, 24.135327f, 18.755239f, 60.276885f, 0.588412f, 0.615975f, 1.132044f, 2.318586f, +0.131236f, 0.239208f, 0.127347f, 0.530898f, 0.091608f, 0.245296f, 0.133140f, 0.276737f, 6.430918f, 10.851366f, 3.727941f, 24.656634f, 0.093173f, 0.097962f, 0.079592f, 0.335481f, +0.262889f, 0.422159f, 0.460195f, 0.957495f, 0.208324f, 0.491445f, 0.546193f, 0.566601f, 6.004489f, 8.926187f, 6.279194f, 20.727201f, 0.281844f, 0.261066f, 0.434330f, 0.913667f, +0.004289f, 0.006194f, 0.004520f, 0.035708f, 0.003179f, 0.006744f, 0.005017f, 0.019763f, 0.763191f, 1.020324f, 0.480426f, 6.021803f, 0.007751f, 0.006457f, 0.007190f, 0.057435f, +0.000166f, 0.000470f, 0.000253f, 0.002003f, 0.000175f, 0.000726f, 0.000398f, 0.001572f, 0.050356f, 0.131796f, 0.045762f, 0.574699f, 0.000451f, 0.000736f, 0.000605f, 0.004839f, +0.000179f, 0.000509f, 0.000121f, 0.001972f, 0.000088f, 0.000367f, 0.000089f, 0.000724f, 0.060792f, 0.159801f, 0.024530f, 0.633972f, 0.000193f, 0.000316f, 0.000115f, 0.001888f, +0.000311f, 0.000778f, 0.000379f, 0.003082f, 0.000174f, 0.000638f, 0.000317f, 0.001284f, 0.049180f, 0.113895f, 0.035799f, 0.461761f, 0.000505f, 0.000729f, 0.000542f, 0.004456f, +0.093673f, 0.208835f, 0.205111f, 0.737178f, 0.108666f, 0.355889f, 0.356373f, 0.638595f, 9.509443f, 19.625861f, 12.439028f, 70.927112f, 0.082377f, 0.105933f, 0.158789f, 0.577004f, +0.010501f, 0.045830f, 0.033193f, 0.119528f, 0.017264f, 0.110692f, 0.081738f, 0.146749f, 1.813193f, 7.326033f, 3.424067f, 19.561450f, 0.013866f, 0.034908f, 0.038586f, 0.140483f, +0.002417f, 0.010594f, 0.003392f, 0.025138f, 0.001859f, 0.011970f, 0.003908f, 0.014438f, 0.467711f, 1.897952f, 0.392169f, 4.610722f, 0.001265f, 0.003199f, 0.001563f, 0.011713f, +0.002267f, 0.008754f, 0.005739f, 0.021227f, 0.001979f, 0.011229f, 0.007506f, 0.013841f, 0.204466f, 0.730980f, 0.309277f, 1.814742f, 0.001792f, 0.003992f, 0.003994f, 0.014935f, +0.012244f, 0.010161f, 0.018509f, 0.149100f, 0.000767f, 0.000935f, 0.001736f, 0.006971f, 0.737052f, 0.566258f, 0.665597f, 8.506593f, 0.007308f, 0.003499f, 0.009726f, 0.079212f, +0.002544f, 0.004134f, 0.005552f, 0.044813f, 0.000226f, 0.000539f, 0.000738f, 0.002970f, 0.260507f, 0.391819f, 0.339625f, 4.348865f, 0.002280f, 0.002137f, 0.004381f, 0.035749f, +0.001415f, 0.002309f, 0.001371f, 0.022775f, 0.000059f, 0.000141f, 0.000085f, 0.000706f, 0.162386f, 0.245300f, 0.094000f, 2.477081f, 0.000503f, 0.000473f, 0.000429f, 0.007203f, +0.002542f, 0.003655f, 0.004444f, 0.036838f, 0.000120f, 0.000253f, 0.000314f, 0.001296f, 0.135975f, 0.180961f, 0.141993f, 1.867466f, 0.001364f, 0.001131f, 0.002099f, 0.017592f, +0.002887f, 0.005045f, 0.006944f, 0.055002f, 0.032581f, 0.083630f, 0.117355f, 0.463457f, 1.310890f, 2.120391f, 1.883310f, 23.666499f, 0.001957f, 0.001972f, 0.004142f, 0.033172f, +0.000156f, 0.000534f, 0.000542f, 0.004302f, 0.002497f, 0.012549f, 0.012986f, 0.051381f, 0.120586f, 0.381854f, 0.250103f, 3.148938f, 0.000159f, 0.000313f, 0.000486f, 0.003896f, +0.000031f, 0.000107f, 0.000048f, 0.000784f, 0.000233f, 0.001176f, 0.000538f, 0.004381f, 0.026957f, 0.085735f, 0.024825f, 0.643244f, 0.000013f, 0.000025f, 0.000017f, 0.000282f, +0.000148f, 0.000449f, 0.000412f, 0.003360f, 0.001259f, 0.005597f, 0.005243f, 0.021307f, 0.059787f, 0.167522f, 0.099326f, 1.284444f, 0.000090f, 0.000158f, 0.000221f, 0.001821f, +0.000000f, 0.000001f, 0.000001f, 0.000018f, 0.000003f, 0.000011f, 0.000007f, 0.000104f, 0.001065f, 0.002683f, 0.001065f, 0.052284f, 0.000000f, 0.000001f, 0.000001f, 0.000016f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000020f, 0.000100f, 0.000029f, 0.001446f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000012f, 0.000061f, 0.000008f, 0.000796f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000024f, 0.000103f, 0.000027f, 0.001378f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000125f, 0.000524f, 0.000434f, 0.006109f, 0.001551f, 0.009574f, 0.008080f, 0.056724f, 0.223655f, 0.870011f, 0.464766f, 10.381913f, 0.000062f, 0.000151f, 0.000191f, 0.002717f, +0.000004f, 0.000033f, 0.000020f, 0.000287f, 0.000071f, 0.000863f, 0.000537f, 0.003776f, 0.012355f, 0.094085f, 0.037064f, 0.829513f, 0.000003f, 0.000014f, 0.000013f, 0.000192f, +0.000000f, 0.000004f, 0.000001f, 0.000030f, 0.000004f, 0.000047f, 0.000013f, 0.000186f, 0.001591f, 0.012172f, 0.002120f, 0.097638f, 0.000000f, 0.000001f, 0.000000f, 0.000008f, +0.000001f, 0.000008f, 0.000004f, 0.000060f, 0.000010f, 0.000104f, 0.000058f, 0.000422f, 0.001653f, 0.011136f, 0.003971f, 0.091285f, 0.000000f, 0.000002f, 0.000002f, 0.000024f, +0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000084f, 0.000121f, 0.000120f, 0.006018f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000009f, 0.000024f, 0.000018f, 0.000891f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000008f, 0.000002f, 0.000254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000013f, 0.000009f, 0.000454f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.235649f, 0.231419f, 0.409699f, 1.377262f, 0.316991f, 0.457313f, 0.825440f, 1.383481f, 12.383959f, 11.258506f, 12.862312f, 68.598140f, 0.176751f, 0.100123f, 0.270523f, 0.919451f, +0.029861f, 0.057410f, 0.074950f, 0.252439f, 0.056930f, 0.160790f, 0.214015f, 0.359390f, 2.669267f, 4.750776f, 4.002381f, 21.386739f, 0.033632f, 0.037297f, 0.074312f, 0.253057f, +0.013955f, 0.026945f, 0.015552f, 0.107796f, 0.012446f, 0.035305f, 0.020775f, 0.071795f, 1.398008f, 2.498989f, 0.930751f, 10.235197f, 0.006231f, 0.006940f, 0.006113f, 0.042838f, +0.035896f, 0.061065f, 0.072167f, 0.249651f, 0.036345f, 0.090828f, 0.109440f, 0.188758f, 1.676164f, 2.639670f, 2.013132f, 11.048593f, 0.024202f, 0.023748f, 0.042834f, 0.149815f, +0.000077f, 0.000119f, 0.000094f, 0.001232f, 0.000073f, 0.000165f, 0.000133f, 0.000871f, 0.028191f, 0.039926f, 0.020381f, 0.424740f, 0.000088f, 0.000078f, 0.000094f, 0.001246f, +0.000002f, 0.000006f, 0.000004f, 0.000047f, 0.000003f, 0.000012f, 0.000007f, 0.000047f, 0.001263f, 0.003501f, 0.001318f, 0.027517f, 0.000003f, 0.000006f, 0.000005f, 0.000071f, +0.000003f, 0.000008f, 0.000002f, 0.000054f, 0.000002f, 0.000007f, 0.000002f, 0.000025f, 0.001783f, 0.004966f, 0.000826f, 0.035514f, 0.000002f, 0.000003f, 0.000001f, 0.000033f, +0.000006f, 0.000015f, 0.000008f, 0.000108f, 0.000004f, 0.000016f, 0.000009f, 0.000058f, 0.001853f, 0.004545f, 0.001549f, 0.033216f, 0.000006f, 0.000009f, 0.000007f, 0.000099f, +0.011748f, 0.027746f, 0.029544f, 0.176544f, 0.017413f, 0.060415f, 0.065587f, 0.195406f, 2.438254f, 5.330844f, 3.663010f, 34.726567f, 0.006497f, 0.008851f, 0.014384f, 0.086902f, +0.000894f, 0.004133f, 0.003246f, 0.019432f, 0.001878f, 0.012756f, 0.010212f, 0.030482f, 0.315593f, 1.350813f, 0.684468f, 6.501448f, 0.000742f, 0.001980f, 0.002373f, 0.014363f, +0.000241f, 0.001118f, 0.000388f, 0.004781f, 0.000237f, 0.001614f, 0.000571f, 0.003509f, 0.095242f, 0.409431f, 0.091718f, 1.792861f, 0.000079f, 0.000212f, 0.000112f, 0.001401f, +0.000290f, 0.001186f, 0.000843f, 0.005185f, 0.000323f, 0.001944f, 0.001409f, 0.004319f, 0.053466f, 0.202490f, 0.092882f, 0.906142f, 0.000144f, 0.000340f, 0.000369f, 0.002294f, +0.000436f, 0.000383f, 0.000757f, 0.010138f, 0.000035f, 0.000045f, 0.000091f, 0.000606f, 0.053657f, 0.043670f, 0.055651f, 1.182530f, 0.000164f, 0.000083f, 0.000250f, 0.003387f, +0.000061f, 0.000106f, 0.000154f, 0.002068f, 0.000007f, 0.000018f, 0.000026f, 0.000175f, 0.012874f, 0.020513f, 0.019276f, 0.410385f, 0.000035f, 0.000034f, 0.000076f, 0.001038f, +0.000040f, 0.000069f, 0.000045f, 0.001230f, 0.000002f, 0.000005f, 0.000004f, 0.000049f, 0.009389f, 0.015025f, 0.006242f, 0.273480f, 0.000009f, 0.000009f, 0.000009f, 0.000245f, +0.000092f, 0.000141f, 0.000185f, 0.002555f, 0.000006f, 0.000012f, 0.000017f, 0.000115f, 0.010095f, 0.014233f, 0.012108f, 0.264753f, 0.000031f, 0.000027f, 0.000055f, 0.000767f, +0.008469f, 0.005004f, 0.014363f, 0.058388f, 0.735788f, 0.638688f, 1.868913f, 3.787922f, 11.079567f, 6.060557f, 11.224824f, 72.393137f, 0.209188f, 0.071298f, 0.312303f, 1.283588f, +0.001523f, 0.001762f, 0.003730f, 0.015191f, 0.187576f, 0.318760f, 0.687828f, 1.396770f, 3.389899f, 3.630177f, 4.958045f, 32.037658f, 0.056501f, 0.037701f, 0.121777f, 0.501472f, +0.000341f, 0.000396f, 0.000370f, 0.003105f, 0.019630f, 0.033504f, 0.031961f, 0.133569f, 0.849883f, 0.914076f, 0.551925f, 7.339511f, 0.005011f, 0.003358f, 0.004795f, 0.040636f, +0.001080f, 0.001105f, 0.002117f, 0.008858f, 0.070607f, 0.106168f, 0.207387f, 0.432548f, 1.255107f, 1.189275f, 1.470393f, 9.758710f, 0.023973f, 0.014154f, 0.041387f, 0.175046f, +0.000016f, 0.000015f, 0.000019f, 0.000307f, 0.001000f, 0.001352f, 0.001768f, 0.014000f, 0.148028f, 0.126142f, 0.104391f, 2.630773f, 0.000612f, 0.000325f, 0.000636f, 0.010210f, +0.000001f, 0.000001f, 0.000001f, 0.000017f, 0.000053f, 0.000140f, 0.000135f, 0.001073f, 0.009411f, 0.015701f, 0.009581f, 0.241929f, 0.000034f, 0.000036f, 0.000052f, 0.000829f, +0.000000f, 0.000001f, 0.000000f, 0.000009f, 0.000015f, 0.000040f, 0.000017f, 0.000277f, 0.006363f, 0.010661f, 0.002876f, 0.149465f, 0.000008f, 0.000009f, 0.000005f, 0.000181f, +0.000001f, 0.000002f, 0.000001f, 0.000023f, 0.000047f, 0.000109f, 0.000095f, 0.000776f, 0.008142f, 0.012019f, 0.006640f, 0.172190f, 0.000034f, 0.000031f, 0.000041f, 0.000676f, +0.000460f, 0.000654f, 0.001129f, 0.008159f, 0.044065f, 0.091986f, 0.161892f, 0.583267f, 2.378180f, 3.128458f, 3.484988f, 39.952996f, 0.008383f, 0.006871f, 0.018103f, 0.132260f, +0.000050f, 0.000138f, 0.000176f, 0.001275f, 0.006746f, 0.027568f, 0.035779f, 0.129154f, 0.436943f, 1.125281f, 0.924374f, 10.617655f, 0.001360f, 0.002182f, 0.004239f, 0.031029f, +0.000006f, 0.000018f, 0.000010f, 0.000150f, 0.000407f, 0.001670f, 0.000958f, 0.007117f, 0.063122f, 0.163268f, 0.059293f, 1.401586f, 0.000069f, 0.000112f, 0.000096f, 0.001449f, +0.000010f, 0.000023f, 0.000027f, 0.000201f, 0.000685f, 0.002477f, 0.002910f, 0.010790f, 0.043646f, 0.099458f, 0.073960f, 0.872538f, 0.000156f, 0.000221f, 0.000389f, 0.002922f, +0.000001f, 0.000001f, 0.000002f, 0.000030f, 0.000006f, 0.000004f, 0.000014f, 0.000115f, 0.003319f, 0.001625f, 0.003358f, 0.086283f, 0.000013f, 0.000004f, 0.000020f, 0.000327f, +0.000000f, 0.000000f, 0.000001f, 0.000009f, 0.000002f, 0.000002f, 0.000006f, 0.000047f, 0.001130f, 0.001084f, 0.001651f, 0.042504f, 0.000004f, 0.000002f, 0.000009f, 0.000142f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000395f, 0.000380f, 0.000256f, 0.013559f, 0.000000f, 0.000000f, 0.000000f, 0.000016f, +0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000001f, 0.000001f, 0.000002f, 0.000018f, 0.000523f, 0.000443f, 0.000611f, 0.016168f, 0.000002f, 0.000001f, 0.000004f, 0.000062f, +24.539969f, 14.376040f, 51.160990f, 27.596817f, 29.877612f, 25.712497f, 93.293089f, 25.090290f, 110.583720f, 59.971320f, 137.725780f, 117.862900f, 23.839366f, 8.055631f, 43.752438f, 23.861386f, +8.661184f, 9.933300f, 26.068064f, 14.088412f, 14.945191f, 25.179736f, 67.370839f, 18.153531f, 66.387528f, 70.483941f, 119.365130f, 102.346320f, 12.634184f, 8.358017f, 33.475072f, 18.291440f, +6.524064f, 7.514790f, 8.718618f, 9.696986f, 5.266496f, 8.911556f, 10.541190f, 5.845417f, 56.044366f, 59.761002f, 44.742512f, 78.949931f, 3.772716f, 2.506642f, 4.438396f, 4.991015f, +11.158807f, 11.323868f, 26.901622f, 14.932763f, 10.225994f, 15.244584f, 36.923689f, 10.218864f, 44.680001f, 41.973722f, 64.347764f, 56.667848f, 9.744261f, 5.703817f, 20.680100f, 11.606135f, +0.345117f, 0.314962f, 0.500833f, 1.055643f, 0.295806f, 0.396581f, 0.642942f, 0.675668f, 10.765114f, 9.094895f, 9.332643f, 31.208355f, 0.507992f, 0.267416f, 0.648972f, 1.383005f, +0.025311f, 0.045222f, 0.053028f, 0.111985f, 0.030747f, 0.080701f, 0.096480f, 0.101585f, 1.342936f, 2.221188f, 1.680768f, 5.631277f, 0.055944f, 0.057654f, 0.103178f, 0.220301f, +0.051416f, 0.092262f, 0.047829f, 0.207865f, 0.029219f, 0.077024f, 0.040710f, 0.088212f, 3.057363f, 5.078776f, 1.699014f, 11.714746f, 0.045051f, 0.046630f, 0.036892f, 0.162108f, +0.076197f, 0.120460f, 0.127868f, 0.277349f, 0.049158f, 0.114165f, 0.123554f, 0.133616f, 2.111879f, 3.090722f, 2.117147f, 7.285488f, 0.100818f, 0.091935f, 0.148938f, 0.326621f, +2.126286f, 2.995591f, 6.411885f, 6.148037f, 2.852476f, 5.903588f, 12.883233f, 6.159023f, 37.840132f, 49.351565f, 68.167332f, 103.697620f, 1.523025f, 1.237677f, 4.043099f, 3.919567f, +0.450651f, 1.242947f, 1.961875f, 1.884755f, 0.856828f, 3.471671f, 5.586800f, 2.675982f, 13.641554f, 34.830774f, 35.477601f, 54.072886f, 0.484703f, 0.771129f, 1.857587f, 1.804289f, +0.195599f, 0.541827f, 0.378090f, 0.747507f, 0.173980f, 0.707988f, 0.503693f, 0.496503f, 6.635819f, 17.016723f, 7.662708f, 24.034994f, 0.083400f, 0.133260f, 0.141918f, 0.283682f, +0.156641f, 0.382276f, 0.546217f, 0.538961f, 0.158169f, 0.567058f, 0.826077f, 0.406395f, 2.476934f, 5.595957f, 5.159816f, 8.077332f, 0.100856f, 0.141975f, 0.309602f, 0.308866f, +0.369014f, 0.193529f, 0.768226f, 1.651042f, 0.026719f, 0.020585f, 0.083311f, 0.089270f, 3.894129f, 1.890605f, 4.843021f, 16.513048f, 0.179404f, 0.054272f, 0.328792f, 0.714435f, +0.144975f, 0.148849f, 0.435718f, 0.938227f, 0.014877f, 0.022439f, 0.066968f, 0.071897f, 2.602274f, 2.473401f, 4.672245f, 15.961343f, 0.105835f, 0.062679f, 0.280019f, 0.609625f, +0.152060f, 0.156802f, 0.202921f, 0.899217f, 0.007300f, 0.011058f, 0.014590f, 0.032236f, 3.059006f, 2.920141f, 2.438655f, 17.144722f, 0.044007f, 0.026176f, 0.051698f, 0.231625f, +0.233249f, 0.211902f, 0.561516f, 1.241861f, 0.012712f, 0.016965f, 0.045834f, 0.050540f, 2.187089f, 1.839368f, 3.145347f, 11.036224f, 0.101934f, 0.053416f, 0.216025f, 0.483046f, +0.038207f, 0.042188f, 0.126542f, 0.267407f, 0.498575f, 0.808723f, 2.473187f, 2.605736f, 3.040875f, 3.108296f, 6.016532f, 20.170898f, 0.021087f, 0.013431f, 0.061483f, 0.131360f, +0.003907f, 0.008445f, 0.018679f, 0.039549f, 0.072251f, 0.229437f, 0.517412f, 0.546189f, 0.528873f, 1.058342f, 1.510655f, 5.074314f, 0.003238f, 0.004037f, 0.013628f, 0.029172f, +0.001470f, 0.003190f, 0.003120f, 0.013594f, 0.012714f, 0.040550f, 0.040428f, 0.087827f, 0.222959f, 0.448108f, 0.282773f, 1.954725f, 0.000483f, 0.000605f, 0.000902f, 0.003975f, +0.005970f, 0.011420f, 0.022866f, 0.049725f, 0.058642f, 0.164774f, 0.336381f, 0.364708f, 0.422220f, 0.747609f, 0.966013f, 3.332752f, 0.002962f, 0.003268f, 0.009987f, 0.021957f, +0.000026f, 0.000045f, 0.000060f, 0.000493f, 0.000238f, 0.000601f, 0.000821f, 0.003379f, 0.014253f, 0.022697f, 0.019630f, 0.257160f, 0.000022f, 0.000021f, 0.000044f, 0.000367f, +0.000001f, 0.000002f, 0.000002f, 0.000015f, 0.000007f, 0.000035f, 0.000036f, 0.000147f, 0.000515f, 0.001606f, 0.001024f, 0.013443f, 0.000001f, 0.000001f, 0.000002f, 0.000017f, +0.000001f, 0.000002f, 0.000001f, 0.000014f, 0.000003f, 0.000017f, 0.000008f, 0.000064f, 0.000586f, 0.001834f, 0.000517f, 0.013965f, 0.000000f, 0.000001f, 0.000000f, 0.000006f, +0.000002f, 0.000006f, 0.000005f, 0.000044f, 0.000014f, 0.000059f, 0.000054f, 0.000230f, 0.000961f, 0.002651f, 0.001530f, 0.020630f, 0.000001f, 0.000003f, 0.000003f, 0.000030f, +0.002687f, 0.007136f, 0.012873f, 0.048357f, 0.038638f, 0.150723f, 0.277231f, 0.519213f, 0.844635f, 2.076292f, 2.417219f, 14.405401f, 0.001094f, 0.001675f, 0.004612f, 0.017515f, +0.000165f, 0.000858f, 0.001141f, 0.004295f, 0.003362f, 0.025678f, 0.034829f, 0.065354f, 0.088214f, 0.424529f, 0.364461f, 2.176173f, 0.000101f, 0.000302f, 0.000614f, 0.002336f, +0.000036f, 0.000187f, 0.000110f, 0.000851f, 0.000341f, 0.002615f, 0.001568f, 0.006055f, 0.021429f, 0.103574f, 0.039310f, 0.483044f, 0.000009f, 0.000026f, 0.000023f, 0.000183f, +0.000068f, 0.000313f, 0.000377f, 0.001457f, 0.000736f, 0.004975f, 0.006109f, 0.011773f, 0.019000f, 0.080906f, 0.062877f, 0.385605f, 0.000025f, 0.000066f, 0.000121f, 0.000474f, +0.000002f, 0.000002f, 0.000007f, 0.000063f, 0.000002f, 0.000003f, 0.000009f, 0.000036f, 0.000420f, 0.000384f, 0.000830f, 0.011086f, 0.000001f, 0.000000f, 0.000002f, 0.000015f, +0.000000f, 0.000000f, 0.000001f, 0.000010f, 0.000000f, 0.000001f, 0.000002f, 0.000008f, 0.000081f, 0.000146f, 0.000232f, 0.003104f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000048f, 0.000086f, 0.000060f, 0.001665f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000001f, 0.000002f, 0.000016f, 0.000000f, 0.000001f, 0.000002f, 0.000007f, 0.000081f, 0.000129f, 0.000185f, 0.002546f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.018963f, 0.013928f, 0.028309f, 0.182797f, 0.019851f, 0.021420f, 0.044385f, 0.142898f, 3.791790f, 2.578310f, 3.381629f, 34.643010f, 0.010796f, 0.004574f, 0.014188f, 0.092628f, +0.002065f, 0.002970f, 0.004451f, 0.028797f, 0.003064f, 0.006473f, 0.009891f, 0.031905f, 0.702456f, 0.935107f, 0.904415f, 9.283040f, 0.001766f, 0.001464f, 0.003350f, 0.021912f, +0.000585f, 0.000846f, 0.000560f, 0.007460f, 0.000406f, 0.000862f, 0.000582f, 0.003866f, 0.223177f, 0.298383f, 0.127584f, 2.694977f, 0.000198f, 0.000165f, 0.000167f, 0.002250f, +0.001835f, 0.002335f, 0.003168f, 0.021053f, 0.001446f, 0.002703f, 0.003739f, 0.012388f, 0.326086f, 0.384092f, 0.336287f, 3.545205f, 0.000939f, 0.000689f, 0.001427f, 0.009590f, +0.000002f, 0.000003f, 0.000002f, 0.000059f, 0.000002f, 0.000003f, 0.000003f, 0.000033f, 0.003124f, 0.003309f, 0.001939f, 0.077627f, 0.000002f, 0.000001f, 0.000002f, 0.000045f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000120f, 0.000249f, 0.000108f, 0.004322f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000103f, 0.000215f, 0.000041f, 0.003384f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000130f, 0.000239f, 0.000094f, 0.003857f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.001065f, 0.001881f, 0.002299f, 0.026387f, 0.001228f, 0.003187f, 0.003972f, 0.022729f, 0.840718f, 1.374793f, 1.084505f, 19.749299f, 0.000447f, 0.000455f, 0.000850f, 0.009859f, +0.000070f, 0.000241f, 0.000217f, 0.002496f, 0.000114f, 0.000578f, 0.000531f, 0.003047f, 0.093528f, 0.299419f, 0.174176f, 3.177915f, 0.000044f, 0.000088f, 0.000120f, 0.001400f, +0.000011f, 0.000040f, 0.000016f, 0.000373f, 0.000009f, 0.000044f, 0.000018f, 0.000213f, 0.017122f, 0.055053f, 0.014158f, 0.531609f, 0.000003f, 0.000006f, 0.000003f, 0.000083f, +0.000017f, 0.000051f, 0.000042f, 0.000492f, 0.000014f, 0.000065f, 0.000054f, 0.000319f, 0.011713f, 0.033180f, 0.017473f, 0.327429f, 0.000006f, 0.000011f, 0.000014f, 0.000165f, +0.000009f, 0.000006f, 0.000013f, 0.000341f, 0.000001f, 0.000001f, 0.000001f, 0.000016f, 0.004164f, 0.002535f, 0.003709f, 0.151375f, 0.000003f, 0.000001f, 0.000003f, 0.000086f, +0.000001f, 0.000001f, 0.000002f, 0.000060f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000859f, 0.001023f, 0.001104f, 0.045152f, 0.000000f, 0.000000f, 0.000001f, 0.000023f, +0.000000f, 0.000001f, 0.000000f, 0.000022f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000380f, 0.000455f, 0.000217f, 0.018253f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000001f, 0.000001f, 0.000002f, 0.000055f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000498f, 0.000525f, 0.000513f, 0.021533f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, +0.000645f, 0.000285f, 0.000940f, 0.007336f, 0.043621f, 0.028321f, 0.095139f, 0.370396f, 3.211601f, 1.313957f, 2.793835f, 34.611020f, 0.012096f, 0.003084f, 0.015506f, 0.122420f, +0.000100f, 0.000086f, 0.000210f, 0.001641f, 0.009558f, 0.012149f, 0.030095f, 0.117391f, 0.844555f, 0.676455f, 1.060654f, 13.164993f, 0.002808f, 0.001401f, 0.005197f, 0.041107f, +0.000014f, 0.000012f, 0.000013f, 0.000203f, 0.000607f, 0.000775f, 0.000848f, 0.006810f, 0.128444f, 0.103325f, 0.071624f, 1.829533f, 0.000151f, 0.000076f, 0.000124f, 0.002021f, +0.000052f, 0.000040f, 0.000088f, 0.000707f, 0.002660f, 0.002991f, 0.006708f, 0.026874f, 0.231159f, 0.163826f, 0.232534f, 2.964428f, 0.000881f, 0.000389f, 0.001306f, 0.010607f, +0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000021f, 0.000022f, 0.000033f, 0.000495f, 0.015528f, 0.009897f, 0.009403f, 0.455182f, 0.000013f, 0.000005f, 0.000011f, 0.000352f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000033f, 0.000849f, 0.001059f, 0.000742f, 0.035978f, 0.000001f, 0.000000f, 0.000001f, 0.000025f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000348f, 0.000436f, 0.000135f, 0.013483f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000017f, 0.000543f, 0.000599f, 0.000380f, 0.018930f, 0.000000f, 0.000000f, 0.000000f, 0.000015f, +0.000039f, 0.000042f, 0.000083f, 0.001155f, 0.002942f, 0.004593f, 0.009281f, 0.064227f, 0.776302f, 0.763810f, 0.976807f, 21.510634f, 0.000546f, 0.000335f, 0.001012f, 0.014205f, +0.000004f, 0.000008f, 0.000011f, 0.000155f, 0.000387f, 0.001183f, 0.001763f, 0.012224f, 0.122589f, 0.236134f, 0.222688f, 4.913320f, 0.000076f, 0.000091f, 0.000204f, 0.002864f, +0.000000f, 0.000001f, 0.000000f, 0.000011f, 0.000014f, 0.000043f, 0.000029f, 0.000409f, 0.010743f, 0.020783f, 0.008665f, 0.393441f, 0.000002f, 0.000003f, 0.000003f, 0.000081f, +0.000001f, 0.000001f, 0.000001f, 0.000018f, 0.000029f, 0.000079f, 0.000106f, 0.000755f, 0.009052f, 0.015429f, 0.013171f, 0.298483f, 0.000006f, 0.000007f, 0.000014f, 0.000199f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000244f, 0.000089f, 0.000212f, 0.010456f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000071f, 0.000051f, 0.000090f, 0.004427f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000015f, 0.000011f, 0.000008f, 0.000857f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000024f, 0.000015f, 0.000025f, 0.001245f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +4.057542f, 1.777860f, 7.263562f, 7.526035f, 3.844458f, 2.474589f, 10.307672f, 5.324924f, 69.571535f, 28.219790f, 74.400866f, 122.302770f, 2.991895f, 0.756172f, 4.714939f, 4.939303f, +1.230860f, 1.055831f, 3.180987f, 3.302262f, 1.652850f, 2.082823f, 6.397727f, 3.311396f, 35.897955f, 28.506439f, 55.422038f, 91.279604f, 1.362829f, 0.674321f, 3.100543f, 3.254319f, +0.562423f, 0.484542f, 0.645378f, 1.378795f, 0.353319f, 0.447165f, 0.607235f, 0.646813f, 18.383520f, 14.661686f, 12.601986f, 42.713651f, 0.246866f, 0.122679f, 0.249377f, 0.538660f, +1.172297f, 0.889783f, 2.426726f, 2.587489f, 0.836038f, 0.932193f, 2.592074f, 1.377976f, 17.860140f, 12.549284f, 22.086516f, 37.361711f, 0.777019f, 0.340187f, 1.415981f, 1.526471f, +0.020651f, 0.014096f, 0.025733f, 0.104186f, 0.013775f, 0.013813f, 0.025708f, 0.051895f, 2.451005f, 1.548791f, 1.824534f, 11.719646f, 0.023072f, 0.009084f, 0.025310f, 0.103604f, +0.001302f, 0.001740f, 0.002342f, 0.009499f, 0.001231f, 0.002416f, 0.003316f, 0.006706f, 0.262799f, 0.325104f, 0.282421f, 1.817579f, 0.002184f, 0.001683f, 0.003458f, 0.014184f, +0.001604f, 0.002153f, 0.001281f, 0.010696f, 0.000709f, 0.001399f, 0.000849f, 0.003532f, 0.362934f, 0.450931f, 0.173181f, 2.293677f, 0.001067f, 0.000826f, 0.000750f, 0.006332f, +0.002897f, 0.003425f, 0.004174f, 0.017392f, 0.001454f, 0.002526f, 0.003139f, 0.006521f, 0.305510f, 0.334415f, 0.262984f, 1.738335f, 0.002909f, 0.001984f, 0.003691f, 0.015546f, +0.395911f, 0.417184f, 1.025141f, 1.888125f, 0.413331f, 0.639825f, 1.602961f, 1.471995f, 26.808972f, 26.151573f, 41.469212f, 121.175430f, 0.215251f, 0.130833f, 0.490653f, 0.913682f, +0.072120f, 0.148778f, 0.269595f, 0.497498f, 0.106712f, 0.323390f, 0.597453f, 0.549693f, 8.306802f, 15.863632f, 18.550098f, 54.308500f, 0.058878f, 0.070061f, 0.193755f, 0.361498f, +0.018989f, 0.039342f, 0.031517f, 0.119692f, 0.013144f, 0.040006f, 0.032675f, 0.061869f, 2.451194f, 4.701416f, 2.430454f, 14.643528f, 0.006146f, 0.007345f, 0.008980f, 0.034478f, +0.018532f, 0.033826f, 0.055487f, 0.105168f, 0.014562f, 0.039048f, 0.065305f, 0.061713f, 1.114995f, 1.884094f, 1.994412f, 5.997151f, 0.009057f, 0.009536f, 0.023872f, 0.045746f, +0.015466f, 0.006067f, 0.027646f, 0.114131f, 0.000871f, 0.000502f, 0.002333f, 0.004802f, 0.620997f, 0.225502f, 0.663159f, 4.343349f, 0.005707f, 0.001291f, 0.008981f, 0.037486f, +0.005222f, 0.004010f, 0.013477f, 0.055744f, 0.000417f, 0.000470f, 0.001612f, 0.003324f, 0.356677f, 0.253563f, 0.549882f, 3.608357f, 0.002894f, 0.001282f, 0.006574f, 0.027492f, +0.003323f, 0.002563f, 0.003807f, 0.032409f, 0.000124f, 0.000141f, 0.000213f, 0.000904f, 0.254340f, 0.181597f, 0.174103f, 2.351168f, 0.000730f, 0.000325f, 0.000736f, 0.006336f, +0.006211f, 0.004220f, 0.012839f, 0.054544f, 0.000263f, 0.000263f, 0.000816f, 0.001727f, 0.221604f, 0.139395f, 0.273653f, 1.844375f, 0.002060f, 0.000808f, 0.003749f, 0.016104f, +0.003529f, 0.002914f, 0.010036f, 0.040738f, 0.035838f, 0.043479f, 0.152647f, 0.308928f, 1.068706f, 0.817056f, 1.815633f, 11.692378f, 0.001478f, 0.000704f, 0.003701f, 0.015190f, +0.000310f, 0.000501f, 0.001273f, 0.005178f, 0.004464f, 0.010602f, 0.027448f, 0.055656f, 0.159755f, 0.239110f, 0.391823f, 2.528120f, 0.000195f, 0.000182f, 0.000705f, 0.002899f, +0.000071f, 0.000115f, 0.000129f, 0.001080f, 0.000476f, 0.001137f, 0.001301f, 0.005429f, 0.040855f, 0.061414f, 0.044491f, 0.590771f, 0.000018f, 0.000017f, 0.000028f, 0.000240f, +0.000350f, 0.000501f, 0.001152f, 0.004813f, 0.002678f, 0.005629f, 0.013191f, 0.027473f, 0.094282f, 0.124863f, 0.185223f, 1.227473f, 0.000132f, 0.000109f, 0.000382f, 0.001613f, +0.000001f, 0.000001f, 0.000002f, 0.000027f, 0.000006f, 0.000012f, 0.000018f, 0.000145f, 0.001813f, 0.002159f, 0.002144f, 0.053947f, 0.000001f, 0.000000f, 0.000001f, 0.000015f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000001f, 0.000001f, 0.000005f, 0.000056f, 0.000131f, 0.000096f, 0.002424f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000039f, 0.000091f, 0.000029f, 0.001527f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000001f, 0.000001f, 0.000006f, 0.000078f, 0.000160f, 0.000106f, 0.002750f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000280f, 0.000555f, 0.001150f, 0.008296f, 0.003128f, 0.009125f, 0.019269f, 0.069320f, 0.334284f, 0.614617f, 0.821456f, 9.403515f, 0.000086f, 0.000099f, 0.000313f, 0.002281f, +0.000015f, 0.000057f, 0.000088f, 0.000633f, 0.000234f, 0.001336f, 0.002081f, 0.007499f, 0.030007f, 0.108011f, 0.106454f, 1.220958f, 0.000007f, 0.000015f, 0.000036f, 0.000261f, +0.000002f, 0.000008f, 0.000005f, 0.000076f, 0.000014f, 0.000083f, 0.000057f, 0.000422f, 0.004422f, 0.015985f, 0.006965f, 0.164402f, 0.000000f, 0.000001f, 0.000001f, 0.000012f, +0.000004f, 0.000015f, 0.000021f, 0.000159f, 0.000038f, 0.000191f, 0.000270f, 0.000999f, 0.004778f, 0.015217f, 0.013577f, 0.159933f, 0.000001f, 0.000002f, 0.000005f, 0.000039f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000037f, 0.000026f, 0.000063f, 0.001629f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000008f, 0.000015f, 0.000392f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000003f, 0.000002f, 0.000128f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000005f, 0.000009f, 0.000238f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.024761f, 0.027599f, 0.043295f, 0.254189f, 0.030001f, 0.049124f, 0.078568f, 0.229986f, 7.401957f, 7.637613f, 7.731806f, 72.017974f, 0.033493f, 0.021533f, 0.051555f, 0.306026f, +0.001522f, 0.003320f, 0.003841f, 0.022594f, 0.002613f, 0.008376f, 0.009879f, 0.028972f, 0.773688f, 1.562889f, 1.166721f, 10.888291f, 0.003090f, 0.003890f, 0.006868f, 0.040845f, +0.000471f, 0.001032f, 0.000528f, 0.006389f, 0.000378f, 0.001218f, 0.000635f, 0.003833f, 0.268351f, 0.544438f, 0.179681f, 3.450892f, 0.000379f, 0.000479f, 0.000374f, 0.004579f, +0.002017f, 0.003894f, 0.004077f, 0.024635f, 0.001839f, 0.005216f, 0.005569f, 0.016777f, 0.535641f, 0.957408f, 0.647000f, 6.201630f, 0.002452f, 0.002731f, 0.004364f, 0.026660f, +0.000002f, 0.000003f, 0.000002f, 0.000047f, 0.000001f, 0.000004f, 0.000003f, 0.000030f, 0.003472f, 0.005581f, 0.002524f, 0.091881f, 0.000003f, 0.000003f, 0.000004f, 0.000085f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000075f, 0.000237f, 0.000079f, 0.002887f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000071f, 0.000223f, 0.000033f, 0.002467f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000122f, 0.000340f, 0.000103f, 0.003842f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000774f, 0.002075f, 0.001958f, 0.020433f, 0.001033f, 0.004070f, 0.003915f, 0.020370f, 0.913903f, 2.267811f, 1.380810f, 22.862533f, 0.000772f, 0.001194f, 0.001719f, 0.018138f, +0.000029f, 0.000150f, 0.000104f, 0.001091f, 0.000054f, 0.000417f, 0.000296f, 0.001541f, 0.057363f, 0.278672f, 0.125122f, 2.075673f, 0.000043f, 0.000129f, 0.000138f, 0.001454f, +0.000005f, 0.000027f, 0.000008f, 0.000178f, 0.000005f, 0.000035f, 0.000011f, 0.000117f, 0.011465f, 0.055937f, 0.011103f, 0.379067f, 0.000003f, 0.000009f, 0.000004f, 0.000094f, +0.000010f, 0.000047f, 0.000030f, 0.000321f, 0.000010f, 0.000070f, 0.000045f, 0.000241f, 0.010714f, 0.046056f, 0.018720f, 0.318955f, 0.000009f, 0.000025f, 0.000024f, 0.000256f, +0.000006f, 0.000006f, 0.000010f, 0.000238f, 0.000000f, 0.000001f, 0.000001f, 0.000013f, 0.004074f, 0.003764f, 0.004250f, 0.157719f, 0.000004f, 0.000002f, 0.000006f, 0.000143f, +0.000000f, 0.000001f, 0.000001f, 0.000024f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000474f, 0.000857f, 0.000714f, 0.026543f, 0.000000f, 0.000000f, 0.000001f, 0.000021f, +0.000000f, 0.000000f, 0.000000f, 0.000009f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000229f, 0.000416f, 0.000153f, 0.011714f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000001f, 0.000001f, 0.000001f, 0.000032f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000410f, 0.000656f, 0.000494f, 0.018879f, 0.000000f, 0.000000f, 0.000001f, 0.000017f, +0.000725f, 0.000486f, 0.001237f, 0.008781f, 0.056745f, 0.055905f, 0.144956f, 0.513115f, 5.396280f, 3.350226f, 5.498271f, 61.931317f, 0.032301f, 0.012495f, 0.048498f, 0.348129f, +0.000063f, 0.000083f, 0.000156f, 0.001108f, 0.007015f, 0.013530f, 0.025871f, 0.091754f, 0.800654f, 0.973140f, 1.177724f, 13.291087f, 0.004231f, 0.003204f, 0.009171f, 0.065955f, +0.000009f, 0.000012f, 0.000010f, 0.000150f, 0.000486f, 0.000942f, 0.000796f, 0.005811f, 0.132934f, 0.162275f, 0.086823f, 2.016447f, 0.000248f, 0.000189f, 0.000239f, 0.003539f, +0.000049f, 0.000057f, 0.000097f, 0.000712f, 0.002911f, 0.004969f, 0.008600f, 0.031327f, 0.326831f, 0.351491f, 0.385080f, 4.463507f, 0.001979f, 0.001326f, 0.003436f, 0.025383f, +0.000000f, 0.000000f, 0.000000f, 0.000009f, 0.000016f, 0.000024f, 0.000028f, 0.000391f, 0.014856f, 0.014368f, 0.010536f, 0.463735f, 0.000019f, 0.000012f, 0.000020f, 0.000571f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000015f, 0.000458f, 0.000867f, 0.000469f, 0.020681f, 0.000001f, 0.000001f, 0.000001f, 0.000022f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000205f, 0.000390f, 0.000093f, 0.008461f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000012f, 0.000437f, 0.000732f, 0.000358f, 0.016228f, 0.000001f, 0.000001f, 0.000001f, 0.000020f, +0.000025f, 0.000040f, 0.000061f, 0.000770f, 0.002131f, 0.005049f, 0.007874f, 0.049547f, 0.726358f, 1.084490f, 1.070487f, 21.433650f, 0.000812f, 0.000755f, 0.001763f, 0.022495f, +0.000001f, 0.000004f, 0.000005f, 0.000058f, 0.000158f, 0.000734f, 0.000844f, 0.005320f, 0.064717f, 0.189166f, 0.137694f, 2.762245f, 0.000064f, 0.000116f, 0.000200f, 0.002559f, +0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000006f, 0.000029f, 0.000015f, 0.000194f, 0.006191f, 0.018176f, 0.005849f, 0.241476f, 0.000002f, 0.000004f, 0.000003f, 0.000079f, +0.000000f, 0.000001f, 0.000001f, 0.000010f, 0.000018f, 0.000073f, 0.000076f, 0.000490f, 0.007127f, 0.018433f, 0.012146f, 0.250266f, 0.000008f, 0.000013f, 0.000020f, 0.000266f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000205f, 0.000114f, 0.000209f, 0.009377f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000034f, 0.000037f, 0.000050f, 0.002240f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000009f, 0.000005f, 0.000473f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000017f, 0.000017f, 0.000020f, 0.000939f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +2.276520f, 1.513654f, 4.773215f, 4.496740f, 2.496502f, 2.438484f, 7.839895f, 3.682418f, 58.354794f, 35.918570f, 73.092905f, 109.245580f, 3.988245f, 1.529595f, 7.361466f, 7.011718f, +0.389638f, 0.507186f, 1.179417f, 1.113235f, 0.605584f, 1.158013f, 2.745485f, 1.292038f, 16.988638f, 20.471621f, 30.720207f, 46.002957f, 1.024993f, 0.769604f, 2.731303f, 2.606531f, +0.194367f, 0.254104f, 0.261232f, 0.507437f, 0.141324f, 0.271416f, 0.284483f, 0.275518f, 9.497822f, 11.494766f, 7.625837f, 23.500938f, 0.202697f, 0.152854f, 0.239825f, 0.471003f, +0.553459f, 0.637459f, 1.341904f, 1.300917f, 0.456838f, 0.772969f, 1.658961f, 0.801864f, 12.605762f, 13.440742f, 18.258464f, 28.082391f, 0.871578f, 0.579046f, 1.860308f, 1.823418f, +0.006597f, 0.006833f, 0.009628f, 0.035443f, 0.005093f, 0.007750f, 0.011133f, 0.020433f, 1.170518f, 1.122398f, 1.020560f, 5.960347f, 0.017511f, 0.010463f, 0.022499f, 0.083739f, +0.000235f, 0.000476f, 0.000494f, 0.001823f, 0.000257f, 0.000765f, 0.000810f, 0.001490f, 0.070811f, 0.132929f, 0.089131f, 0.521548f, 0.000935f, 0.001094f, 0.001735f, 0.006469f, +0.000316f, 0.000643f, 0.000295f, 0.002241f, 0.000162f, 0.000483f, 0.000226f, 0.000857f, 0.106761f, 0.201287f, 0.059667f, 0.718522f, 0.000499f, 0.000586f, 0.000411f, 0.003152f, +0.000779f, 0.001397f, 0.001314f, 0.004979f, 0.000453f, 0.001193f, 0.001144f, 0.002160f, 0.122772f, 0.203929f, 0.123781f, 0.743926f, 0.001858f, 0.001923f, 0.002761f, 0.010573f, +0.123695f, 0.197790f, 0.375138f, 0.628216f, 0.149466f, 0.351096f, 0.678921f, 0.566856f, 12.521954f, 18.535747f, 22.686649f, 60.273942f, 0.159782f, 0.147373f, 0.426589f, 0.722272f, +0.012713f, 0.039798f, 0.055663f, 0.093393f, 0.021772f, 0.100123f, 0.142772f, 0.119435f, 2.189123f, 6.343940f, 5.725785f, 15.241474f, 0.024659f, 0.044527f, 0.095045f, 0.161233f, +0.003654f, 0.011489f, 0.007104f, 0.024530f, 0.002928f, 0.013522f, 0.008524f, 0.014675f, 0.705213f, 2.052541f, 0.818999f, 4.486540f, 0.002810f, 0.005096f, 0.004809f, 0.016788f, +0.004872f, 0.013495f, 0.017086f, 0.029444f, 0.004431f, 0.018030f, 0.023275f, 0.019998f, 0.438232f, 1.123710f, 0.918119f, 2.510148f, 0.005657f, 0.009038f, 0.017465f, 0.030430f, +0.004349f, 0.002589f, 0.009106f, 0.034178f, 0.000284f, 0.000248f, 0.000889f, 0.001664f, 0.261060f, 0.143854f, 0.326528f, 1.944455f, 0.003813f, 0.001309f, 0.007028f, 0.026671f, +0.000829f, 0.000966f, 0.002504f, 0.009418f, 0.000077f, 0.000131f, 0.000347f, 0.000650f, 0.084600f, 0.091264f, 0.152763f, 0.911438f, 0.001091f, 0.000733f, 0.002903f, 0.011036f, +0.000576f, 0.000674f, 0.000772f, 0.005978f, 0.000025f, 0.000043f, 0.000050f, 0.000193f, 0.065859f, 0.071356f, 0.052803f, 0.648348f, 0.000300f, 0.000203f, 0.000355f, 0.002777f, +0.001470f, 0.001515f, 0.003558f, 0.013744f, 0.000072f, 0.000109f, 0.000262f, 0.000504f, 0.078391f, 0.074827f, 0.113382f, 0.694804f, 0.001158f, 0.000689f, 0.002469f, 0.009641f, +0.004614f, 0.005782f, 0.015368f, 0.056717f, 0.054227f, 0.099833f, 0.270530f, 0.497802f, 2.088733f, 2.423240f, 4.156285f, 24.336084f, 0.004592f, 0.003320f, 0.013465f, 0.050245f, +0.000229f, 0.000561f, 0.001100f, 0.004068f, 0.003811f, 0.013735f, 0.027446f, 0.050601f, 0.176166f, 0.400117f, 0.506070f, 2.968857f, 0.000342f, 0.000484f, 0.001447f, 0.005411f, +0.000057f, 0.000140f, 0.000122f, 0.000926f, 0.000444f, 0.001608f, 0.001420f, 0.005388f, 0.049183f, 0.112192f, 0.062734f, 0.757387f, 0.000034f, 0.000048f, 0.000063f, 0.000488f, +0.000385f, 0.000837f, 0.001485f, 0.005639f, 0.003410f, 0.010875f, 0.019673f, 0.037251f, 0.155058f, 0.311616f, 0.356790f, 2.149805f, 0.000345f, 0.000432f, 0.001169f, 0.004490f, +0.000001f, 0.000001f, 0.000001f, 0.000022f, 0.000005f, 0.000015f, 0.000018f, 0.000133f, 0.002017f, 0.003646f, 0.002794f, 0.063930f, 0.000001f, 0.000001f, 0.000002f, 0.000029f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000035f, 0.000125f, 0.000071f, 0.001621f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000027f, 0.000095f, 0.000024f, 0.001115f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000001f, 0.000001f, 0.000005f, 0.000073f, 0.000228f, 0.000116f, 0.002742f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000203f, 0.000613f, 0.000980f, 0.006432f, 0.002635f, 0.011668f, 0.019017f, 0.062202f, 0.363820f, 1.015071f, 1.047150f, 10.898956f, 0.000149f, 0.000260f, 0.000633f, 0.004201f, +0.000006f, 0.000036f, 0.000042f, 0.000277f, 0.000111f, 0.000964f, 0.001159f, 0.003797f, 0.018426f, 0.100647f, 0.076565f, 0.798435f, 0.000007f, 0.000023f, 0.000041f, 0.000272f, +0.000001f, 0.000005f, 0.000003f, 0.000036f, 0.000007f, 0.000065f, 0.000035f, 0.000233f, 0.002964f, 0.016262f, 0.005469f, 0.117369f, 0.000000f, 0.000001f, 0.000001f, 0.000014f, +0.000003f, 0.000014f, 0.000015f, 0.000104f, 0.000027f, 0.000206f, 0.000224f, 0.000754f, 0.004376f, 0.021147f, 0.014563f, 0.155981f, 0.000002f, 0.000005f, 0.000009f, 0.000061f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000037f, 0.000038f, 0.000073f, 0.001699f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000007f, 0.000010f, 0.000231f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000002f, 0.000082f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000007f, 0.000009f, 0.000209f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.007918f, 0.008499f, 0.012931f, 0.099554f, 0.007679f, 0.012108f, 0.018783f, 0.072097f, 2.341719f, 2.326990f, 2.284726f, 27.905854f, 0.006550f, 0.004056f, 0.009417f, 0.073303f, +0.000549f, 0.001153f, 0.001294f, 0.009982f, 0.000754f, 0.002329f, 0.002664f, 0.010245f, 0.276111f, 0.537149f, 0.388911f, 4.759316f, 0.000682f, 0.000826f, 0.001415f, 0.011036f, +0.000144f, 0.000305f, 0.000151f, 0.002400f, 0.000093f, 0.000288f, 0.000146f, 0.001152f, 0.081409f, 0.159062f, 0.050914f, 1.282231f, 0.000071f, 0.000087f, 0.000066f, 0.001052f, +0.000441f, 0.000820f, 0.000833f, 0.006596f, 0.000322f, 0.000879f, 0.000910f, 0.003595f, 0.115849f, 0.199418f, 0.130704f, 1.642823f, 0.000328f, 0.000352f, 0.000545f, 0.004366f, +0.000001f, 0.000001f, 0.000001f, 0.000020f, 0.000000f, 0.000001f, 0.000001f, 0.000010f, 0.001221f, 0.001890f, 0.000829f, 0.039580f, 0.000001f, 0.000001f, 0.000001f, 0.000023f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000030f, 0.000091f, 0.000029f, 0.001403f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000024f, 0.000072f, 0.000010f, 0.001019f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000029f, 0.000079f, 0.000023f, 0.001131f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000307f, 0.000792f, 0.000725f, 0.009921f, 0.000328f, 0.001244f, 0.001160f, 0.007917f, 0.358437f, 0.856582f, 0.505839f, 10.982575f, 0.000187f, 0.000279f, 0.000389f, 0.005386f, +0.000013f, 0.000065f, 0.000044f, 0.000597f, 0.000019f, 0.000144f, 0.000099f, 0.000676f, 0.025379f, 0.118737f, 0.051706f, 1.124783f, 0.000012f, 0.000034f, 0.000035f, 0.000487f, +0.000002f, 0.000010f, 0.000003f, 0.000083f, 0.000001f, 0.000010f, 0.000003f, 0.000044f, 0.004312f, 0.020260f, 0.003900f, 0.174613f, 0.000001f, 0.000002f, 0.000001f, 0.000027f, +0.000003f, 0.000012f, 0.000008f, 0.000106f, 0.000002f, 0.000015f, 0.000009f, 0.000064f, 0.002873f, 0.011893f, 0.004688f, 0.104746f, 0.000002f, 0.000004f, 0.000004f, 0.000052f, +0.000005f, 0.000005f, 0.000009f, 0.000261f, 0.000000f, 0.000000f, 0.000001f, 0.000011f, 0.003610f, 0.003211f, 0.003517f, 0.171156f, 0.000002f, 0.000001f, 0.000003f, 0.000096f, +0.000000f, 0.000001f, 0.000001f, 0.000029f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000474f, 0.000825f, 0.000666f, 0.032493f, 0.000000f, 0.000000f, 0.000001f, 0.000016f, +0.000000f, 0.000000f, 0.000000f, 0.000010f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000195f, 0.000340f, 0.000121f, 0.012190f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000001f, 0.000001f, 0.000024f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000248f, 0.000383f, 0.000280f, 0.014006f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000487f, 0.000314f, 0.000776f, 0.007221f, 0.030493f, 0.028932f, 0.072757f, 0.337718f, 3.584317f, 2.143061f, 3.411170f, 50.383549f, 0.013263f, 0.004941f, 0.018600f, 0.175076f, +0.000048f, 0.000061f, 0.000110f, 0.001028f, 0.004252f, 0.007899f, 0.014648f, 0.068123f, 0.599912f, 0.702209f, 0.824235f, 12.197456f, 0.001960f, 0.001429f, 0.003967f, 0.037417f, +0.000006f, 0.000008f, 0.000006f, 0.000118f, 0.000251f, 0.000467f, 0.000383f, 0.003667f, 0.084670f, 0.099539f, 0.051652f, 1.573061f, 0.000098f, 0.000072f, 0.000088f, 0.001707f, +0.000023f, 0.000025f, 0.000042f, 0.000400f, 0.001070f, 0.001758f, 0.002951f, 0.014096f, 0.148411f, 0.153711f, 0.163327f, 2.482474f, 0.000556f, 0.000359f, 0.000901f, 0.008727f, +0.000000f, 0.000000f, 0.000000f, 0.000009f, 0.000009f, 0.000014f, 0.000016f, 0.000286f, 0.010970f, 0.010218f, 0.007267f, 0.419417f, 0.000009f, 0.000005f, 0.000009f, 0.000319f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000012f, 0.000382f, 0.000696f, 0.000365f, 0.021099f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000145f, 0.000266f, 0.000062f, 0.007338f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000221f, 0.000356f, 0.000169f, 0.010034f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000021f, 0.000032f, 0.000047f, 0.000784f, 0.001420f, 0.003239f, 0.004900f, 0.040428f, 0.598119f, 0.860026f, 0.823349f, 21.617223f, 0.000413f, 0.000370f, 0.000838f, 0.014025f, +0.000001f, 0.000004f, 0.000004f, 0.000067f, 0.000119f, 0.000531f, 0.000592f, 0.004897f, 0.060115f, 0.169223f, 0.119467f, 3.142650f, 0.000037f, 0.000064f, 0.000107f, 0.001800f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000004f, 0.000018f, 0.000009f, 0.000152f, 0.004889f, 0.013822f, 0.004314f, 0.233538f, 0.000001f, 0.000002f, 0.000001f, 0.000047f, +0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000008f, 0.000032f, 0.000032f, 0.000273f, 0.004012f, 0.009994f, 0.006387f, 0.172558f, 0.000003f, 0.000004f, 0.000007f, 0.000113f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000382f, 0.000204f, 0.000363f, 0.021365f, 0.000000f, 0.000000f, 0.000000f, 0.000016f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000071f, 0.000075f, 0.000098f, 0.005758f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000015f, 0.000009f, 0.001034f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000022f, 0.000020f, 0.000024f, 0.001463f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +1.749249f, 1.120095f, 3.425753f, 4.231986f, 1.535411f, 1.444313f, 4.503681f, 2.773909f, 44.361767f, 26.296606f, 51.900643f, 101.719130f, 1.874229f, 0.692254f, 3.231244f, 4.035813f, +0.337731f, 0.423376f, 0.954867f, 1.181854f, 0.420143f, 0.773722f, 1.779128f, 1.097904f, 14.568709f, 16.906857f, 24.606607f, 48.318620f, 0.543365f, 0.392904f, 1.352402f, 1.692389f, +0.143213f, 0.180310f, 0.179784f, 0.457941f, 0.083347f, 0.154155f, 0.156709f, 0.199016f, 6.923678f, 8.069766f, 5.192363f, 20.982843f, 0.091342f, 0.066335f, 0.100944f, 0.259963f, +0.290734f, 0.322486f, 0.658410f, 0.837001f, 0.192081f, 0.312992f, 0.651515f, 0.412943f, 6.551360f, 6.727198f, 8.863221f, 17.875694f, 0.280012f, 0.179156f, 0.558240f, 0.717503f, +0.005635f, 0.005621f, 0.007682f, 0.037083f, 0.003482f, 0.005103f, 0.007110f, 0.017112f, 0.989253f, 0.913534f, 0.805625f, 6.169743f, 0.009149f, 0.005264f, 0.010979f, 0.053583f, +0.000226f, 0.000442f, 0.000445f, 0.002152f, 0.000198f, 0.000568f, 0.000584f, 0.001407f, 0.067509f, 0.122047f, 0.079369f, 0.609004f, 0.000551f, 0.000621f, 0.000955f, 0.004669f, +0.000259f, 0.000507f, 0.000226f, 0.002249f, 0.000106f, 0.000305f, 0.000139f, 0.000688f, 0.086521f, 0.157099f, 0.045166f, 0.713208f, 0.000250f, 0.000283f, 0.000192f, 0.001934f, +0.000455f, 0.000786f, 0.000717f, 0.003561f, 0.000212f, 0.000537f, 0.000499f, 0.001237f, 0.070935f, 0.113472f, 0.066801f, 0.526448f, 0.000664f, 0.000661f, 0.000921f, 0.004625f, +0.117831f, 0.181450f, 0.333781f, 0.732961f, 0.113962f, 0.257805f, 0.483507f, 0.529368f, 11.801297f, 16.823481f, 19.970677f, 69.574990f, 0.093088f, 0.082686f, 0.232135f, 0.515386f, +0.013661f, 0.041185f, 0.055868f, 0.122918f, 0.018726f, 0.082934f, 0.114698f, 0.125819f, 2.327327f, 6.495237f, 5.685749f, 19.846364f, 0.016206f, 0.028182f, 0.058343f, 0.129783f, +0.003338f, 0.010107f, 0.006061f, 0.027444f, 0.002141f, 0.009521f, 0.005821f, 0.013142f, 0.637321f, 1.786398f, 0.691331f, 4.966104f, 0.001570f, 0.002742f, 0.002509f, 0.011487f, +0.003173f, 0.008464f, 0.010393f, 0.023486f, 0.002310f, 0.009051f, 0.011332f, 0.012767f, 0.282353f, 0.697253f, 0.552524f, 1.980857f, 0.002253f, 0.003467f, 0.006497f, 0.014844f, +0.009359f, 0.005365f, 0.018302f, 0.090082f, 0.000489f, 0.000411f, 0.001431f, 0.003511f, 0.555808f, 0.294954f, 0.649338f, 5.070484f, 0.005018f, 0.001659f, 0.008639f, 0.042993f, +0.002011f, 0.002257f, 0.005679f, 0.028003f, 0.000149f, 0.000245f, 0.000629f, 0.001547f, 0.203182f, 0.211088f, 0.342686f, 2.681072f, 0.001619f, 0.001048f, 0.004025f, 0.020068f, +0.001188f, 0.001339f, 0.001489f, 0.015109f, 0.000041f, 0.000068f, 0.000077f, 0.000390f, 0.134456f, 0.140295f, 0.100691f, 1.621211f, 0.000379f, 0.000246f, 0.000418f, 0.004292f, +0.002162f, 0.002147f, 0.004890f, 0.024766f, 0.000085f, 0.000124f, 0.000288f, 0.000727f, 0.114099f, 0.104887f, 0.154143f, 1.238636f, 0.001042f, 0.000597f, 0.002075f, 0.010625f, +0.002548f, 0.003075f, 0.007927f, 0.038363f, 0.023970f, 0.042498f, 0.111694f, 0.269507f, 1.141222f, 1.275065f, 2.121082f, 16.285615f, 0.001551f, 0.001080f, 0.004248f, 0.020785f, +0.000143f, 0.000337f, 0.000640f, 0.003104f, 0.001900f, 0.006596f, 0.012783f, 0.030903f, 0.108577f, 0.237494f, 0.291336f, 2.241162f, 0.000130f, 0.000178f, 0.000515f, 0.002525f, +0.000030f, 0.000072f, 0.000060f, 0.000601f, 0.000188f, 0.000656f, 0.000562f, 0.002797f, 0.025768f, 0.056608f, 0.030700f, 0.486017f, 0.000011f, 0.000015f, 0.000019f, 0.000194f, +0.000146f, 0.000304f, 0.000524f, 0.002607f, 0.001030f, 0.003165f, 0.005553f, 0.013788f, 0.057918f, 0.112095f, 0.124479f, 0.983519f, 0.000080f, 0.000096f, 0.000252f, 0.001270f, +0.000000f, 0.000001f, 0.000001f, 0.000016f, 0.000003f, 0.000007f, 0.000008f, 0.000080f, 0.001225f, 0.002133f, 0.001585f, 0.047561f, 0.000000f, 0.000000f, 0.000001f, 0.000013f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000024f, 0.000083f, 0.000045f, 0.001360f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000016f, 0.000053f, 0.000013f, 0.000795f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000030f, 0.000091f, 0.000045f, 0.001395f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000139f, 0.000404f, 0.000627f, 0.005393f, 0.001444f, 0.006158f, 0.009734f, 0.041749f, 0.246433f, 0.662151f, 0.662501f, 9.041985f, 0.000063f, 0.000105f, 0.000248f, 0.002155f, +0.000005f, 0.000027f, 0.000030f, 0.000262f, 0.000069f, 0.000574f, 0.000669f, 0.002875f, 0.014079f, 0.074062f, 0.054643f, 0.747220f, 0.000003f, 0.000010f, 0.000018f, 0.000157f, +0.000001f, 0.000003f, 0.000002f, 0.000029f, 0.000004f, 0.000033f, 0.000017f, 0.000150f, 0.001925f, 0.010172f, 0.003318f, 0.093371f, 0.000000f, 0.000001f, 0.000000f, 0.000007f, +0.000001f, 0.000006f, 0.000007f, 0.000059f, 0.000010f, 0.000074f, 0.000078f, 0.000346f, 0.002026f, 0.009431f, 0.006299f, 0.088467f, 0.000001f, 0.000002f, 0.000002f, 0.000021f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000056f, 0.000056f, 0.000104f, 0.003185f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000012f, 0.000016f, 0.000488f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000004f, 0.000002f, 0.000147f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000007f, 0.000008f, 0.000267f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.068940f, 0.107256f, 0.112069f, 0.763365f, 0.132477f, 0.302777f, 0.322545f, 1.095401f, 5.449895f, 7.849200f, 5.292483f, 57.193660f, 0.083617f, 0.075039f, 0.119660f, 0.824080f, +0.005469f, 0.016658f, 0.012835f, 0.087597f, 0.014895f, 0.066648f, 0.052356f, 0.178150f, 0.735429f, 2.073619f, 1.031048f, 11.163492f, 0.009961f, 0.017500f, 0.020579f, 0.141997f, +0.002267f, 0.006934f, 0.002362f, 0.033172f, 0.002888f, 0.012978f, 0.004507f, 0.031561f, 0.341582f, 0.967309f, 0.212633f, 4.737923f, 0.001637f, 0.002888f, 0.001501f, 0.021317f, +0.009088f, 0.024492f, 0.017084f, 0.119747f, 0.013145f, 0.052041f, 0.037008f, 0.129337f, 0.638355f, 1.592618f, 0.716853f, 7.971863f, 0.009908f, 0.015403f, 0.016397f, 0.116202f, +0.000008f, 0.000020f, 0.000009f, 0.000248f, 0.000011f, 0.000040f, 0.000019f, 0.000250f, 0.004505f, 0.010107f, 0.003045f, 0.128580f, 0.000015f, 0.000021f, 0.000015f, 0.000406f, +0.000000f, 0.000001f, 0.000000f, 0.000006f, 0.000000f, 0.000002f, 0.000001f, 0.000008f, 0.000126f, 0.000555f, 0.000123f, 0.005215f, 0.000000f, 0.000001f, 0.000001f, 0.000015f, +0.000000f, 0.000001f, 0.000000f, 0.000006f, 0.000000f, 0.000001f, 0.000000f, 0.000004f, 0.000158f, 0.000698f, 0.000069f, 0.005969f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, +0.000001f, 0.000002f, 0.000001f, 0.000019f, 0.000001f, 0.000003f, 0.000001f, 0.000014f, 0.000256f, 0.000996f, 0.000200f, 0.008702f, 0.000001f, 0.000002f, 0.000001f, 0.000028f, +0.001892f, 0.007079f, 0.004449f, 0.053868f, 0.004006f, 0.022020f, 0.014109f, 0.085173f, 0.590708f, 2.046002f, 0.829744f, 15.939069f, 0.001692f, 0.003652f, 0.003503f, 0.042878f, +0.000090f, 0.000660f, 0.000306f, 0.003712f, 0.000271f, 0.002911f, 0.001375f, 0.008318f, 0.047868f, 0.324583f, 0.097069f, 1.868233f, 0.000121f, 0.000511f, 0.000362f, 0.004437f, +0.000022f, 0.000158f, 0.000032f, 0.000810f, 0.000030f, 0.000327f, 0.000068f, 0.000849f, 0.012811f, 0.087246f, 0.011535f, 0.456882f, 0.000011f, 0.000049f, 0.000015f, 0.000384f, +0.000040f, 0.000262f, 0.000110f, 0.001369f, 0.000064f, 0.000613f, 0.000262f, 0.001629f, 0.011210f, 0.067256f, 0.018208f, 0.359927f, 0.000032f, 0.000121f, 0.000078f, 0.000980f, +0.000060f, 0.000083f, 0.000097f, 0.002639f, 0.000007f, 0.000014f, 0.000017f, 0.000225f, 0.011090f, 0.014300f, 0.010755f, 0.463059f, 0.000036f, 0.000029f, 0.000052f, 0.001426f, +0.000005f, 0.000014f, 0.000012f, 0.000337f, 0.000001f, 0.000003f, 0.000003f, 0.000041f, 0.001666f, 0.004205f, 0.002332f, 0.100609f, 0.000005f, 0.000008f, 0.000010f, 0.000273f, +0.000003f, 0.000008f, 0.000003f, 0.000178f, 0.000000f, 0.000001f, 0.000000f, 0.000010f, 0.001077f, 0.002731f, 0.000670f, 0.059457f, 0.000001f, 0.000002f, 0.000001f, 0.000057f, +0.000011f, 0.000026f, 0.000021f, 0.000575f, 0.000001f, 0.000003f, 0.000003f, 0.000037f, 0.001806f, 0.004033f, 0.002025f, 0.089719f, 0.000006f, 0.000008f, 0.000010f, 0.000279f, +0.005100f, 0.004774f, 0.008087f, 0.066611f, 0.632926f, 0.870370f, 1.503144f, 6.173163f, 10.035947f, 8.696888f, 9.506641f, 124.233770f, 0.203693f, 0.109985f, 0.284334f, 2.367955f, +0.000574f, 0.001053f, 0.001315f, 0.010850f, 0.101018f, 0.271956f, 0.346347f, 1.425120f, 1.922393f, 3.261362f, 2.628921f, 34.420970f, 0.034444f, 0.036411f, 0.069412f, 0.579180f, +0.000114f, 0.000210f, 0.000116f, 0.001967f, 0.009375f, 0.025349f, 0.014272f, 0.120856f, 0.427416f, 0.728266f, 0.259528f, 6.993037f, 0.002709f, 0.002876f, 0.002424f, 0.041622f, +0.000563f, 0.000912f, 0.001032f, 0.008745f, 0.052561f, 0.125207f, 0.144348f, 0.610039f, 0.983861f, 1.476900f, 1.077701f, 14.492809f, 0.020202f, 0.018895f, 0.032609f, 0.279459f, +0.000004f, 0.000005f, 0.000004f, 0.000127f, 0.000312f, 0.000669f, 0.000516f, 0.008284f, 0.048685f, 0.065724f, 0.032101f, 1.639230f, 0.000216f, 0.000182f, 0.000210f, 0.006839f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000010f, 0.000043f, 0.000025f, 0.000397f, 0.001938f, 0.005122f, 0.001845f, 0.094377f, 0.000008f, 0.000013f, 0.000011f, 0.000348f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000003f, 0.000011f, 0.000003f, 0.000091f, 0.001162f, 0.003084f, 0.000491f, 0.051707f, 0.000002f, 0.000003f, 0.000001f, 0.000067f, +0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000013f, 0.000047f, 0.000024f, 0.000397f, 0.002317f, 0.005419f, 0.001767f, 0.092850f, 0.000010f, 0.000015f, 0.000012f, 0.000392f, +0.000153f, 0.000344f, 0.000350f, 0.005124f, 0.020867f, 0.069008f, 0.071681f, 0.523287f, 1.185894f, 2.471424f, 1.624853f, 37.744795f, 0.004494f, 0.005835f, 0.009073f, 0.134320f, +0.000010f, 0.000045f, 0.000034f, 0.000501f, 0.002000f, 0.012948f, 0.009918f, 0.072544f, 0.136410f, 0.556542f, 0.269824f, 6.279953f, 0.000456f, 0.001160f, 0.001330f, 0.019729f, +0.000001f, 0.000005f, 0.000002f, 0.000052f, 0.000107f, 0.000695f, 0.000236f, 0.003545f, 0.017476f, 0.071610f, 0.015349f, 0.735164f, 0.000021f, 0.000053f, 0.000027f, 0.000817f, +0.000003f, 0.000011f, 0.000007f, 0.000109f, 0.000281f, 0.001608f, 0.001115f, 0.008378f, 0.018835f, 0.067994f, 0.029842f, 0.713361f, 0.000072f, 0.000162f, 0.000169f, 0.002568f, +0.000000f, 0.000000f, 0.000000f, 0.000016f, 0.000002f, 0.000003f, 0.000005f, 0.000088f, 0.001412f, 0.001095f, 0.001336f, 0.069543f, 0.000006f, 0.000003f, 0.000009f, 0.000283f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000001f, 0.000001f, 0.000023f, 0.000301f, 0.000457f, 0.000411f, 0.021448f, 0.000001f, 0.000001f, 0.000002f, 0.000077f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000093f, 0.000142f, 0.000057f, 0.006067f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000001f, 0.000001f, 0.000012f, 0.000192f, 0.000259f, 0.000210f, 0.011277f, 0.000001f, 0.000001f, 0.000001f, 0.000046f, +10.030623f, 9.309129f, 19.552601f, 21.370745f, 17.445536f, 23.784745f, 50.933032f, 27.755622f, 67.993187f, 58.416260f, 79.177418f, 137.296140f, 15.757024f, 8.435193f, 27.039182f, 29.880098f, +2.216414f, 4.027012f, 6.237263f, 6.830342f, 5.463364f, 14.582276f, 23.027246f, 12.572636f, 25.555280f, 42.983350f, 42.961887f, 74.640287f, 5.228131f, 5.479217f, 12.951873f, 14.340162f, +1.480568f, 2.701735f, 1.849989f, 4.169210f, 1.707327f, 4.576822f, 3.195185f, 3.590186f, 19.132096f, 32.319465f, 14.281130f, 51.060985f, 1.384490f, 1.457283f, 1.522907f, 3.470015f, +3.947199f, 6.345737f, 8.897366f, 10.007329f, 5.167272f, 12.203577f, 17.445060f, 9.782852f, 23.774144f, 35.382219f, 32.013772f, 57.126176f, 5.573728f, 5.168662f, 11.060153f, 12.577405f, +0.051219f, 0.074053f, 0.069498f, 0.296819f, 0.062713f, 0.133199f, 0.127449f, 0.271389f, 2.403297f, 3.216639f, 1.948072f, 13.199778f, 0.121913f, 0.101671f, 0.145624f, 0.628817f, +0.002352f, 0.006657f, 0.004607f, 0.019713f, 0.004081f, 0.016969f, 0.011973f, 0.025545f, 0.187700f, 0.491824f, 0.219648f, 1.491154f, 0.008406f, 0.013723f, 0.014495f, 0.062710f, +0.004237f, 0.012044f, 0.003685f, 0.032450f, 0.003439f, 0.014363f, 0.004480f, 0.019672f, 0.378959f, 0.997287f, 0.196904f, 2.750962f, 0.006003f, 0.009843f, 0.004596f, 0.040922f, +0.009786f, 0.024510f, 0.015355f, 0.067487f, 0.009019f, 0.033183f, 0.021195f, 0.046445f, 0.408014f, 0.945980f, 0.382445f, 2.666685f, 0.020939f, 0.030249f, 0.028922f, 0.128517f, +0.478455f, 1.067868f, 1.349015f, 2.620974f, 0.916909f, 3.006324f, 3.872046f, 3.750789f, 12.808327f, 26.464059f, 21.573860f, 66.499051f, 0.554182f, 0.713458f, 1.375533f, 2.702029f, +0.063486f, 0.277401f, 0.258418f, 0.503038f, 0.172432f, 1.106823f, 1.051233f, 1.020267f, 2.890836f, 11.693339f, 7.029520f, 21.709316f, 0.110418f, 0.278297f, 0.395663f, 0.778714f, +0.024437f, 0.107239f, 0.044165f, 0.176928f, 0.031050f, 0.200171f, 0.084050f, 0.167876f, 1.247069f, 5.066263f, 1.346450f, 8.557502f, 0.016849f, 0.042650f, 0.026807f, 0.108578f, +0.030503f, 0.117932f, 0.099452f, 0.198839f, 0.043999f, 0.249899f, 0.214859f, 0.214179f, 0.725557f, 2.596854f, 1.413198f, 4.482619f, 0.031759f, 0.070826f, 0.091155f, 0.184263f, +0.070841f, 0.058858f, 0.137893f, 0.600492f, 0.007327f, 0.008943f, 0.021362f, 0.046381f, 1.124536f, 0.864927f, 1.307649f, 9.034351f, 0.055693f, 0.026691f, 0.095433f, 0.420183f, +0.017424f, 0.028342f, 0.048964f, 0.213637f, 0.002554f, 0.006103f, 0.010751f, 0.023386f, 0.470475f, 0.708424f, 0.789806f, 5.467127f, 0.020569f, 0.019299f, 0.050885f, 0.224470f, +0.016207f, 0.026477f, 0.020223f, 0.181581f, 0.001111f, 0.002667f, 0.002077f, 0.009299f, 0.490455f, 0.741718f, 0.365579f, 5.207827f, 0.007585f, 0.007147f, 0.008331f, 0.075634f, +0.038751f, 0.055771f, 0.087224f, 0.390877f, 0.003017f, 0.006378f, 0.010171f, 0.022724f, 0.546571f, 0.728224f, 0.734955f, 5.225260f, 0.027385f, 0.022734f, 0.054263f, 0.245856f, +0.023394f, 0.040922f, 0.072444f, 0.310194f, 0.436082f, 1.120607f, 2.022584f, 4.317926f, 2.800738f, 4.535365f, 5.181218f, 35.197017f, 0.020879f, 0.021067f, 0.056917f, 0.246405f, +0.001498f, 0.005128f, 0.006695f, 0.028722f, 0.039564f, 0.199039f, 0.264915f, 0.566640f, 0.304961f, 0.966798f, 0.814462f, 5.543422f, 0.002007f, 0.003964f, 0.007898f, 0.034259f, +0.000500f, 0.001718f, 0.000992f, 0.008755f, 0.006174f, 0.031196f, 0.018356f, 0.080803f, 0.114013f, 0.363018f, 0.135201f, 1.893749f, 0.000265f, 0.000527f, 0.000464f, 0.004140f, +0.003164f, 0.009586f, 0.011329f, 0.049917f, 0.044388f, 0.197588f, 0.238066f, 0.523008f, 0.336535f, 0.944021f, 0.719922f, 5.032701f, 0.002538f, 0.004436f, 0.008001f, 0.035643f, +0.000006f, 0.000016f, 0.000012f, 0.000207f, 0.000075f, 0.000302f, 0.000244f, 0.002033f, 0.004766f, 0.012024f, 0.006138f, 0.162929f, 0.000008f, 0.000012f, 0.000015f, 0.000250f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000001f, 0.000011f, 0.000007f, 0.000055f, 0.000108f, 0.000533f, 0.000200f, 0.005332f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000001f, 0.000005f, 0.000001f, 0.000021f, 0.000109f, 0.000539f, 0.000090f, 0.004912f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000002f, 0.000001f, 0.000016f, 0.000004f, 0.000026f, 0.000014f, 0.000120f, 0.000278f, 0.001215f, 0.000414f, 0.011312f, 0.000000f, 0.000001f, 0.000001f, 0.000018f, +0.000906f, 0.003810f, 0.004057f, 0.030881f, 0.018605f, 0.114974f, 0.124812f, 0.473648f, 0.428261f, 1.667798f, 1.145954f, 13.837949f, 0.000596f, 0.001446f, 0.002350f, 0.018087f, +0.000035f, 0.000287f, 0.000225f, 0.001717f, 0.001014f, 0.012263f, 0.009817f, 0.037325f, 0.028002f, 0.213493f, 0.108174f, 1.308758f, 0.000034f, 0.000163f, 0.000196f, 0.001510f, +0.000007f, 0.000055f, 0.000019f, 0.000302f, 0.000091f, 0.001108f, 0.000392f, 0.003067f, 0.006032f, 0.046191f, 0.010347f, 0.257626f, 0.000003f, 0.000013f, 0.000007f, 0.000105f, +0.000020f, 0.000145f, 0.000103f, 0.000805f, 0.000307f, 0.003284f, 0.002380f, 0.009295f, 0.008337f, 0.056241f, 0.025796f, 0.320558f, 0.000012f, 0.000049f, 0.000054f, 0.000424f, +0.000001f, 0.000001f, 0.000002f, 0.000034f, 0.000001f, 0.000002f, 0.000003f, 0.000028f, 0.000182f, 0.000263f, 0.000336f, 0.009086f, 0.000000f, 0.000000f, 0.000001f, 0.000014f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000022f, 0.000063f, 0.000059f, 0.001593f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000011f, 0.000033f, 0.000014f, 0.000758f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000000f, 0.000000f, 0.000001f, 0.000005f, 0.000030f, 0.000076f, 0.000065f, 0.001806f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.006535f, 0.007605f, 0.009122f, 0.119356f, 0.009773f, 0.016707f, 0.020432f, 0.133286f, 1.965775f, 2.117584f, 1.639182f, 34.026089f, 0.006017f, 0.004038f, 0.007393f, 0.097801f, +0.000446f, 0.001015f, 0.000898f, 0.011772f, 0.000944f, 0.003161f, 0.002851f, 0.018631f, 0.227997f, 0.480825f, 0.274466f, 5.708296f, 0.000616f, 0.000809f, 0.001093f, 0.014484f, +0.000112f, 0.000256f, 0.000100f, 0.002704f, 0.000111f, 0.000373f, 0.000149f, 0.002002f, 0.064239f, 0.136062f, 0.034336f, 1.469629f, 0.000061f, 0.000081f, 0.000048f, 0.001319f, +0.000547f, 0.001103f, 0.000884f, 0.011896f, 0.000616f, 0.001824f, 0.001490f, 0.009999f, 0.146298f, 0.272997f, 0.141068f, 3.013388f, 0.000453f, 0.000527f, 0.000644f, 0.008762f, +0.000000f, 0.000001f, 0.000000f, 0.000014f, 0.000000f, 0.000001f, 0.000000f, 0.000011f, 0.000588f, 0.000987f, 0.000341f, 0.027684f, 0.000000f, 0.000000f, 0.000000f, 0.000017f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000047f, 0.000012f, 0.000965f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000036f, 0.000004f, 0.000670f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000021f, 0.000062f, 0.000014f, 0.001190f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000202f, 0.000565f, 0.000408f, 0.009485f, 0.000333f, 0.001368f, 0.001006f, 0.011671f, 0.239942f, 0.621596f, 0.289400f, 10.678587f, 0.000137f, 0.000221f, 0.000244f, 0.005731f, +0.000008f, 0.000045f, 0.000024f, 0.000562f, 0.000019f, 0.000155f, 0.000084f, 0.000980f, 0.016712f, 0.084756f, 0.029099f, 1.075781f, 0.000008f, 0.000027f, 0.000022f, 0.000510f, +0.000001f, 0.000007f, 0.000002f, 0.000074f, 0.000001f, 0.000011f, 0.000003f, 0.000061f, 0.002713f, 0.013820f, 0.002098f, 0.159592f, 0.000000f, 0.000002f, 0.000001f, 0.000027f, +0.000003f, 0.000013f, 0.000006f, 0.000153f, 0.000003f, 0.000024f, 0.000012f, 0.000142f, 0.002893f, 0.012983f, 0.004035f, 0.153213f, 0.000002f, 0.000005f, 0.000003f, 0.000083f, +0.000001f, 0.000001f, 0.000002f, 0.000105f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.001014f, 0.000978f, 0.000844f, 0.069830f, 0.000001f, 0.000000f, 0.000001f, 0.000043f, +0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000131f, 0.000247f, 0.000157f, 0.013040f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000051f, 0.000097f, 0.000027f, 0.004675f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000105f, 0.000175f, 0.000101f, 0.008596f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, +0.000458f, 0.000320f, 0.000623f, 0.009860f, 0.044204f, 0.045465f, 0.090143f, 0.711106f, 3.427032f, 2.221229f, 2.787462f, 69.970954f, 0.013875f, 0.005604f, 0.016631f, 0.266049f, +0.000044f, 0.000061f, 0.000087f, 0.001380f, 0.006064f, 0.012210f, 0.017852f, 0.141098f, 0.564215f, 0.715930f, 0.662525f, 16.662633f, 0.002017f, 0.001594f, 0.003490f, 0.055930f, +0.000005f, 0.000007f, 0.000005f, 0.000152f, 0.000341f, 0.000690f, 0.000446f, 0.007259f, 0.076097f, 0.096978f, 0.039675f, 2.053523f, 0.000096f, 0.000076f, 0.000074f, 0.002438f, +0.000032f, 0.000039f, 0.000051f, 0.000822f, 0.002332f, 0.004156f, 0.005500f, 0.044649f, 0.213464f, 0.239669f, 0.200776f, 5.186346f, 0.000874f, 0.000612f, 0.001212f, 0.019950f, +0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000008f, 0.000013f, 0.000011f, 0.000345f, 0.006016f, 0.006075f, 0.003406f, 0.334120f, 0.000005f, 0.000003f, 0.000004f, 0.000278f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000014f, 0.000206f, 0.000407f, 0.000168f, 0.016534f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000075f, 0.000149f, 0.000027f, 0.005495f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000011f, 0.000182f, 0.000318f, 0.000119f, 0.012025f, 0.000000f, 0.000000f, 0.000000f, 0.000010f, +0.000015f, 0.000026f, 0.000030f, 0.000854f, 0.001641f, 0.004059f, 0.004841f, 0.067882f, 0.456029f, 0.710826f, 0.536516f, 23.939884f, 0.000345f, 0.000335f, 0.000598f, 0.016995f, +0.000001f, 0.000003f, 0.000003f, 0.000072f, 0.000135f, 0.000655f, 0.000576f, 0.008088f, 0.045085f, 0.137580f, 0.076576f, 3.423448f, 0.000030f, 0.000057f, 0.000075f, 0.002145f, +0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000004f, 0.000021f, 0.000008f, 0.000240f, 0.003504f, 0.010739f, 0.002642f, 0.243111f, 0.000001f, 0.000002f, 0.000001f, 0.000054f, +0.000000f, 0.000001f, 0.000000f, 0.000012f, 0.000014f, 0.000060f, 0.000048f, 0.000691f, 0.004602f, 0.012426f, 0.006261f, 0.287479f, 0.000004f, 0.000006f, 0.000007f, 0.000206f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000122f, 0.000071f, 0.000099f, 0.009928f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000022f, 0.000025f, 0.000026f, 0.002632f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000005f, 0.000002f, 0.000452f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000011f, 0.000010f, 0.001023f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +1.953789f, 1.356214f, 3.270213f, 6.865748f, 2.644444f, 2.696611f, 6.629360f, 6.939361f, 50.392641f, 32.382087f, 50.387742f, 167.833310f, 2.329629f, 0.932776f, 3.432639f, 7.286399f, +0.371059f, 0.504249f, 0.896620f, 1.886049f, 0.711791f, 1.420978f, 2.576063f, 2.701701f, 16.278884f, 20.479235f, 23.498994f, 78.421591f, 0.664357f, 0.520766f, 1.413219f, 3.005574f, +0.150360f, 0.205219f, 0.161323f, 0.698357f, 0.134934f, 0.270545f, 0.216832f, 0.467995f, 7.392990f, 9.340955f, 4.738514f, 32.543545f, 0.106723f, 0.084020f, 0.100801f, 0.441182f, +0.488506f, 0.587398f, 0.945506f, 2.042760f, 0.497671f, 0.879100f, 1.442700f, 1.554050f, 11.195345f, 12.461984f, 12.944685f, 44.369664f, 0.523588f, 0.363155f, 0.892127f, 1.948736f, +0.003611f, 0.003904f, 0.004207f, 0.034510f, 0.003440f, 0.005465f, 0.006003f, 0.024555f, 0.644605f, 0.645295f, 0.448656f, 5.839439f, 0.006523f, 0.004069f, 0.006690f, 0.055493f, +0.000142f, 0.000302f, 0.000240f, 0.001970f, 0.000192f, 0.000598f, 0.000485f, 0.001987f, 0.043271f, 0.084802f, 0.043479f, 0.566982f, 0.000387f, 0.000472f, 0.000572f, 0.004757f, +0.000156f, 0.000331f, 0.000116f, 0.001967f, 0.000098f, 0.000307f, 0.000110f, 0.000928f, 0.052995f, 0.104311f, 0.023644f, 0.634519f, 0.000167f, 0.000205f, 0.000110f, 0.001883f, +0.000438f, 0.000821f, 0.000591f, 0.004985f, 0.000314f, 0.000865f, 0.000634f, 0.002670f, 0.069533f, 0.120578f, 0.055964f, 0.749562f, 0.000712f, 0.000769f, 0.000844f, 0.007206f, +0.104949f, 0.175196f, 0.254083f, 0.948239f, 0.156518f, 0.383833f, 0.567544f, 1.056034f, 10.690077f, 16.520164f, 15.461020f, 91.542361f, 0.092268f, 0.088846f, 0.196649f, 0.742006f, +0.011969f, 0.039116f, 0.041833f, 0.156422f, 0.025299f, 0.121458f, 0.132434f, 0.246895f, 2.073741f, 6.273920f, 4.329906f, 25.685934f, 0.015801f, 0.029786f, 0.048617f, 0.183797f, +0.002795f, 0.009173f, 0.004337f, 0.033374f, 0.002763f, 0.013325f, 0.006423f, 0.024643f, 0.542669f, 1.648927f, 0.503102f, 6.141993f, 0.001463f, 0.002769f, 0.001998f, 0.015546f, +0.004251f, 0.012293f, 0.011902f, 0.045707f, 0.004772f, 0.020272f, 0.020010f, 0.038315f, 0.384761f, 1.029998f, 0.643494f, 3.920756f, 0.003360f, 0.005604f, 0.008280f, 0.032150f, +0.003498f, 0.002174f, 0.005846f, 0.048901f, 0.000282f, 0.000257f, 0.000705f, 0.002939f, 0.211258f, 0.121532f, 0.210937f, 2.799339f, 0.002087f, 0.000748f, 0.003071f, 0.025972f, +0.000739f, 0.000900f, 0.001784f, 0.014953f, 0.000084f, 0.000151f, 0.000305f, 0.001274f, 0.075966f, 0.085555f, 0.109503f, 1.455996f, 0.000663f, 0.000465f, 0.001407f, 0.011925f, +0.000417f, 0.000510f, 0.000447f, 0.007710f, 0.000022f, 0.000040f, 0.000036f, 0.000307f, 0.048039f, 0.054338f, 0.030747f, 0.841338f, 0.000148f, 0.000104f, 0.000140f, 0.002437f, +0.001216f, 0.001309f, 0.002350f, 0.020224f, 0.000074f, 0.000116f, 0.000213f, 0.000915f, 0.065241f, 0.065014f, 0.075328f, 1.028720f, 0.000652f, 0.000405f, 0.001109f, 0.009656f, +0.002545f, 0.003330f, 0.006768f, 0.055670f, 0.036926f, 0.070973f, 0.147061f, 0.603063f, 1.159560f, 1.404437f, 1.841935f, 24.035034f, 0.001724f, 0.001301f, 0.004036f, 0.033566f, +0.000140f, 0.000359f, 0.000538f, 0.004430f, 0.002879f, 0.010835f, 0.016555f, 0.068020f, 0.108519f, 0.257317f, 0.248860f, 3.253562f, 0.000142f, 0.000210f, 0.000481f, 0.004011f, +0.000028f, 0.000073f, 0.000048f, 0.000819f, 0.000273f, 0.001030f, 0.000696f, 0.005884f, 0.024611f, 0.058610f, 0.025060f, 0.674244f, 0.000011f, 0.000017f, 0.000017f, 0.000294f, +0.000219f, 0.000496f, 0.000673f, 0.005692f, 0.002388f, 0.007951f, 0.010998f, 0.046412f, 0.088528f, 0.185739f, 0.162614f, 2.183589f, 0.000133f, 0.000174f, 0.000361f, 0.003085f, +0.000000f, 0.000000f, 0.000000f, 0.000013f, 0.000002f, 0.000007f, 0.000006f, 0.000103f, 0.000714f, 0.001348f, 0.000790f, 0.040264f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000014f, 0.000051f, 0.000022f, 0.001133f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000008f, 0.000032f, 0.000006f, 0.000633f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000026f, 0.000087f, 0.000034f, 0.001776f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000111f, 0.000349f, 0.000427f, 0.006241f, 0.001774f, 0.008200f, 0.010220f, 0.074495f, 0.199671f, 0.581595f, 0.458771f, 10.641363f, 0.000055f, 0.000101f, 0.000188f, 0.002775f, +0.000004f, 0.000023f, 0.000020f, 0.000298f, 0.000083f, 0.000752f, 0.000691f, 0.005046f, 0.011221f, 0.063989f, 0.037221f, 0.865022f, 0.000003f, 0.000010f, 0.000013f, 0.000199f, +0.000000f, 0.000003f, 0.000001f, 0.000032f, 0.000005f, 0.000041f, 0.000017f, 0.000252f, 0.001466f, 0.008398f, 0.002160f, 0.103293f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000002f, 0.000008f, 0.000007f, 0.000103f, 0.000019f, 0.000149f, 0.000124f, 0.000929f, 0.002470f, 0.012461f, 0.006562f, 0.156626f, 0.000001f, 0.000002f, 0.000003f, 0.000041f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000019f, 0.000021f, 0.000030f, 0.001573f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000004f, 0.000005f, 0.000237f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000068f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000004f, 0.000004f, 0.000199f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.002908f, 0.005136f, 0.004755f, 0.056567f, 0.005034f, 0.013058f, 0.012327f, 0.073113f, 1.307874f, 2.137928f, 1.277357f, 24.108343f, 0.006362f, 0.006480f, 0.009156f, 0.110126f, +0.000112f, 0.000387f, 0.000264f, 0.003148f, 0.000274f, 0.001394f, 0.000970f, 0.005766f, 0.085586f, 0.273895f, 0.120675f, 2.281949f, 0.000368f, 0.000733f, 0.000764f, 0.009202f, +0.000031f, 0.000107f, 0.000032f, 0.000789f, 0.000035f, 0.000180f, 0.000055f, 0.000677f, 0.026326f, 0.084613f, 0.016481f, 0.641378f, 0.000040f, 0.000080f, 0.000037f, 0.000915f, +0.000205f, 0.000627f, 0.000388f, 0.004744f, 0.000267f, 0.001200f, 0.000756f, 0.004615f, 0.081905f, 0.231926f, 0.092502f, 1.796593f, 0.000403f, 0.000711f, 0.000671f, 0.008302f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000223f, 0.000567f, 0.000151f, 0.011168f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000015f, 0.000003f, 0.000220f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000013f, 0.000001f, 0.000166f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000030f, 0.000005f, 0.000404f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000050f, 0.000213f, 0.000118f, 0.002503f, 0.000095f, 0.000596f, 0.000338f, 0.003565f, 0.088897f, 0.349468f, 0.125583f, 4.213239f, 0.000081f, 0.000198f, 0.000168f, 0.003593f, +0.000001f, 0.000010f, 0.000004f, 0.000084f, 0.000003f, 0.000038f, 0.000016f, 0.000169f, 0.003493f, 0.026885f, 0.007124f, 0.239481f, 0.000003f, 0.000013f, 0.000008f, 0.000180f, +0.000000f, 0.000002f, 0.000000f, 0.000012f, 0.000000f, 0.000003f, 0.000001f, 0.000011f, 0.000619f, 0.004786f, 0.000561f, 0.038785f, 0.000000f, 0.000001f, 0.000000f, 0.000010f, +0.000001f, 0.000004f, 0.000002f, 0.000034f, 0.000001f, 0.000009f, 0.000003f, 0.000036f, 0.000902f, 0.006142f, 0.001473f, 0.050867f, 0.000001f, 0.000004f, 0.000002f, 0.000044f, +0.000000f, 0.000001f, 0.000001f, 0.000025f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000338f, 0.000495f, 0.000330f, 0.024797f, 0.000000f, 0.000000f, 0.000001f, 0.000024f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000025f, 0.000071f, 0.000035f, 0.002613f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000030f, 0.000007f, 0.001023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000029f, 0.000075f, 0.000033f, 0.002569f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000175f, 0.000186f, 0.000280f, 0.004022f, 0.019598f, 0.030588f, 0.046810f, 0.335747f, 1.962550f, 1.930263f, 1.869667f, 42.672059f, 0.012628f, 0.007739f, 0.017728f, 0.257857f, +0.000010f, 0.000020f, 0.000022f, 0.000318f, 0.001517f, 0.004635f, 0.005230f, 0.037587f, 0.182302f, 0.351025f, 0.250727f, 5.733420f, 0.001036f, 0.001242f, 0.002099f, 0.030585f, +0.000001f, 0.000003f, 0.000001f, 0.000038f, 0.000093f, 0.000286f, 0.000143f, 0.002111f, 0.026842f, 0.051910f, 0.016392f, 0.771394f, 0.000054f, 0.000065f, 0.000049f, 0.001456f, +0.000010f, 0.000019f, 0.000019f, 0.000282f, 0.000870f, 0.002353f, 0.002403f, 0.017739f, 0.102865f, 0.175256f, 0.113320f, 2.661500f, 0.000670f, 0.000711f, 0.001087f, 0.016270f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000002f, 0.000005f, 0.000003f, 0.000093f, 0.001962f, 0.003006f, 0.001301f, 0.116016f, 0.000003f, 0.000003f, 0.000003f, 0.000153f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000038f, 0.000114f, 0.000036f, 0.003239f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000015f, 0.000045f, 0.000006f, 0.001175f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000050f, 0.000133f, 0.000038f, 0.003513f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, +0.000003f, 0.000008f, 0.000008f, 0.000194f, 0.000405f, 0.001521f, 0.001400f, 0.017848f, 0.145426f, 0.343980f, 0.200394f, 8.130085f, 0.000175f, 0.000257f, 0.000355f, 0.009172f, +0.000000f, 0.000001f, 0.000000f, 0.000009f, 0.000019f, 0.000138f, 0.000094f, 0.001200f, 0.008112f, 0.037564f, 0.016138f, 0.655965f, 0.000009f, 0.000025f, 0.000025f, 0.000653f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000005f, 0.000001f, 0.000039f, 0.000688f, 0.003201f, 0.000608f, 0.050854f, 0.000000f, 0.000001f, 0.000000f, 0.000018f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000003f, 0.000019f, 0.000012f, 0.000153f, 0.001235f, 0.005060f, 0.001968f, 0.082152f, 0.000002f, 0.000004f, 0.000004f, 0.000094f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000035f, 0.000031f, 0.000033f, 0.003035f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000006f, 0.000005f, 0.000454f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000000f, 0.000085f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000004f, 0.000003f, 0.000263f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.373608f, 0.393538f, 0.732432f, 1.398136f, 0.585277f, 0.905660f, 1.718506f, 1.635570f, 14.405942f, 14.047531f, 16.871454f, 51.094719f, 1.058406f, 0.643077f, 1.826612f, 3.525344f, +0.040034f, 0.082556f, 0.113304f, 0.216700f, 0.088884f, 0.269264f, 0.376773f, 0.359278f, 2.625691f, 5.012485f, 4.439367f, 13.470311f, 0.170299f, 0.202569f, 0.424299f, 0.820465f, +0.017710f, 0.036680f, 0.022256f, 0.087597f, 0.018395f, 0.055968f, 0.034622f, 0.067943f, 1.301804f, 2.495957f, 0.977283f, 6.102581f, 0.029866f, 0.035679f, 0.033039f, 0.131479f, +0.078605f, 0.143427f, 0.178195f, 0.350041f, 0.092685f, 0.248442f, 0.314698f, 0.308215f, 2.693095f, 4.549059f, 3.647190f, 11.366410f, 0.200168f, 0.210677f, 0.399470f, 0.793379f, +0.000393f, 0.000645f, 0.000536f, 0.004001f, 0.000434f, 0.001045f, 0.000886f, 0.003295f, 0.104920f, 0.159383f, 0.085532f, 1.012181f, 0.001687f, 0.001597f, 0.002027f, 0.015287f, +0.000009f, 0.000028f, 0.000017f, 0.000129f, 0.000014f, 0.000065f, 0.000040f, 0.000150f, 0.003974f, 0.011818f, 0.004677f, 0.055450f, 0.000056f, 0.000105f, 0.000098f, 0.000739f, +0.000010f, 0.000034f, 0.000009f, 0.000140f, 0.000008f, 0.000036f, 0.000010f, 0.000077f, 0.005313f, 0.015870f, 0.002776f, 0.067746f, 0.000027f, 0.000050f, 0.000021f, 0.000319f, +0.000040f, 0.000114f, 0.000063f, 0.000486f, 0.000033f, 0.000139f, 0.000079f, 0.000302f, 0.009523f, 0.025061f, 0.008978f, 0.109329f, 0.000155f, 0.000254f, 0.000215f, 0.001670f, +0.011175f, 0.028309f, 0.031689f, 0.107529f, 0.019290f, 0.071785f, 0.081927f, 0.138604f, 1.701777f, 3.990770f, 2.882788f, 15.519116f, 0.023343f, 0.034109f, 0.058272f, 0.199914f, +0.000719f, 0.003566f, 0.002944f, 0.010008f, 0.001759f, 0.012816f, 0.010786f, 0.018283f, 0.186260f, 0.855117f, 0.455509f, 2.456882f, 0.002255f, 0.006452f, 0.008128f, 0.027939f, +0.000183f, 0.000913f, 0.000333f, 0.002331f, 0.000210f, 0.001535f, 0.000571f, 0.001992f, 0.053212f, 0.245355f, 0.057781f, 0.641365f, 0.000228f, 0.000655f, 0.000365f, 0.002580f, +0.000381f, 0.001672f, 0.001249f, 0.004361f, 0.000495f, 0.003190f, 0.002431f, 0.004232f, 0.051541f, 0.209372f, 0.100962f, 0.559312f, 0.000715f, 0.001810f, 0.002065f, 0.007289f, +0.000335f, 0.000316f, 0.000656f, 0.004991f, 0.000031f, 0.000043f, 0.000092f, 0.000347f, 0.030269f, 0.026423f, 0.035399f, 0.427129f, 0.000475f, 0.000259f, 0.000819f, 0.006298f, +0.000040f, 0.000074f, 0.000113f, 0.000861f, 0.000005f, 0.000014f, 0.000022f, 0.000085f, 0.006141f, 0.010495f, 0.010368f, 0.125345f, 0.000085f, 0.000091f, 0.000212f, 0.001632f, +0.000025f, 0.000046f, 0.000031f, 0.000485f, 0.000002f, 0.000004f, 0.000003f, 0.000022f, 0.004240f, 0.007277f, 0.003178f, 0.079072f, 0.000021f, 0.000022f, 0.000023f, 0.000364f, +0.000098f, 0.000160f, 0.000222f, 0.001737f, 0.000007f, 0.000016f, 0.000023f, 0.000091f, 0.007866f, 0.011894f, 0.010637f, 0.132081f, 0.000125f, 0.000118f, 0.000249f, 0.001970f, +0.001134f, 0.002252f, 0.003532f, 0.026416f, 0.019043f, 0.055542f, 0.088829f, 0.331201f, 0.772409f, 1.419636f, 1.437082f, 17.049910f, 0.001825f, 0.002091f, 0.005005f, 0.037841f, +0.000035f, 0.000137f, 0.000158f, 0.001186f, 0.000838f, 0.004784f, 0.005642f, 0.021077f, 0.040786f, 0.146753f, 0.109549f, 1.302209f, 0.000085f, 0.000191f, 0.000337f, 0.002551f, +0.000008f, 0.000030f, 0.000016f, 0.000239f, 0.000087f, 0.000497f, 0.000259f, 0.001990f, 0.010098f, 0.036492f, 0.012043f, 0.294609f, 0.000007f, 0.000017f, 0.000013f, 0.000204f, +0.000082f, 0.000282f, 0.000295f, 0.002273f, 0.001036f, 0.005236f, 0.005590f, 0.021448f, 0.049622f, 0.157985f, 0.106759f, 1.303430f, 0.000119f, 0.000235f, 0.000376f, 0.002927f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000001f, 0.000003f, 0.000002f, 0.000032f, 0.000271f, 0.000776f, 0.000351f, 0.016263f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000017f, 0.000006f, 0.000258f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000011f, 0.000002f, 0.000157f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000008f, 0.000042f, 0.000013f, 0.000604f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000028f, 0.000131f, 0.000124f, 0.001649f, 0.000509f, 0.003574f, 0.003437f, 0.022783f, 0.074066f, 0.327372f, 0.199320f, 4.203605f, 0.000033f, 0.000090f, 0.000130f, 0.001742f, +0.000001f, 0.000005f, 0.000003f, 0.000044f, 0.000013f, 0.000185f, 0.000131f, 0.000871f, 0.002349f, 0.020322f, 0.009124f, 0.192795f, 0.000001f, 0.000005f, 0.000005f, 0.000071f, +0.000000f, 0.000001f, 0.000000f, 0.000005f, 0.000001f, 0.000011f, 0.000003f, 0.000047f, 0.000335f, 0.002912f, 0.000578f, 0.025133f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000003f, 0.000002f, 0.000023f, 0.000004f, 0.000055f, 0.000035f, 0.000239f, 0.000771f, 0.005902f, 0.002399f, 0.052063f, 0.000000f, 0.000002f, 0.000002f, 0.000022f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000010f, 0.000012f, 0.000559f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000048f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000015f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000001f, 0.000059f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.001626f, 0.002765f, 0.002483f, 0.038729f, 0.002252f, 0.005627f, 0.005151f, 0.040066f, 0.723305f, 1.138668f, 0.659831f, 16.330100f, 0.002175f, 0.002133f, 0.002924f, 0.046113f, +0.000071f, 0.000235f, 0.000156f, 0.002431f, 0.000139f, 0.000678f, 0.000457f, 0.003565f, 0.053394f, 0.164557f, 0.070318f, 1.743644f, 0.000142f, 0.000272f, 0.000275f, 0.004347f, +0.000016f, 0.000055f, 0.000016f, 0.000518f, 0.000015f, 0.000074f, 0.000022f, 0.000355f, 0.013961f, 0.043214f, 0.008164f, 0.416597f, 0.000013f, 0.000025f, 0.000011f, 0.000367f, +0.000078f, 0.000231f, 0.000138f, 0.002221f, 0.000082f, 0.000353f, 0.000216f, 0.001729f, 0.030967f, 0.084447f, 0.032667f, 0.831958f, 0.000094f, 0.000160f, 0.000146f, 0.002377f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000137f, 0.000336f, 0.000087f, 0.008410f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000010f, 0.000002f, 0.000187f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000007f, 0.000001f, 0.000120f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000012f, 0.000002f, 0.000208f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000035f, 0.000142f, 0.000077f, 0.002125f, 0.000053f, 0.000318f, 0.000175f, 0.002422f, 0.060949f, 0.230747f, 0.080422f, 3.538043f, 0.000034f, 0.000081f, 0.000067f, 0.001865f, +0.000001f, 0.000007f, 0.000003f, 0.000080f, 0.000002f, 0.000023f, 0.000009f, 0.000129f, 0.002702f, 0.020025f, 0.005147f, 0.226855f, 0.000001f, 0.000006f, 0.000004f, 0.000106f, +0.000000f, 0.000001f, 0.000000f, 0.000010f, 0.000000f, 0.000001f, 0.000000f, 0.000007f, 0.000407f, 0.003030f, 0.000344f, 0.031231f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, +0.000000f, 0.000002f, 0.000001f, 0.000020f, 0.000000f, 0.000003f, 0.000001f, 0.000017f, 0.000423f, 0.002772f, 0.000645f, 0.029202f, 0.000000f, 0.000001f, 0.000001f, 0.000016f, +0.000001f, 0.000001f, 0.000001f, 0.000048f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000524f, 0.000738f, 0.000477f, 0.047041f, 0.000000f, 0.000000f, 0.000000f, 0.000028f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000043f, 0.000119f, 0.000057f, 0.005591f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000016f, 0.000043f, 0.000009f, 0.001860f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000031f, 0.000076f, 0.000033f, 0.003331f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000206f, 0.000211f, 0.000306f, 0.005782f, 0.018410f, 0.027672f, 0.041072f, 0.386294f, 2.278767f, 2.158460f, 2.027722f, 60.686092f, 0.009064f, 0.005350f, 0.011886f, 0.226690f, +0.000013f, 0.000025f, 0.000027f, 0.000515f, 0.001607f, 0.004730f, 0.005177f, 0.048784f, 0.238782f, 0.442788f, 0.306744f, 9.197915f, 0.000838f, 0.000969f, 0.001587f, 0.030331f, +0.000001f, 0.000003f, 0.000001f, 0.000053f, 0.000084f, 0.000248f, 0.000120f, 0.002329f, 0.029887f, 0.055662f, 0.017047f, 1.051967f, 0.000037f, 0.000043f, 0.000031f, 0.001227f, +0.000008f, 0.000015f, 0.000014f, 0.000277f, 0.000559f, 0.001455f, 0.001442f, 0.013953f, 0.081654f, 0.133977f, 0.084020f, 2.587630f, 0.000329f, 0.000336f, 0.000498f, 0.009779f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000002f, 0.000005f, 0.000003f, 0.000119f, 0.002532f, 0.003737f, 0.001568f, 0.183426f, 0.000002f, 0.000002f, 0.000002f, 0.000150f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000055f, 0.000159f, 0.000049f, 0.005777f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000019f, 0.000054f, 0.000007f, 0.001782f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000044f, 0.000113f, 0.000032f, 0.003798f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000005f, 0.000012f, 0.000010f, 0.000346f, 0.000472f, 0.001706f, 0.001523f, 0.025457f, 0.209337f, 0.476855f, 0.269435f, 14.333949f, 0.000155f, 0.000221f, 0.000295f, 0.009997f, +0.000000f, 0.000001f, 0.000001f, 0.000019f, 0.000025f, 0.000175f, 0.000115f, 0.001931f, 0.013172f, 0.058743f, 0.024476f, 1.304613f, 0.000009f, 0.000024f, 0.000024f, 0.000803f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000005f, 0.000002f, 0.000053f, 0.000950f, 0.004255f, 0.000784f, 0.085976f, 0.000000f, 0.000001f, 0.000000f, 0.000019f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000002f, 0.000015f, 0.000009f, 0.000149f, 0.001215f, 0.004795f, 0.001809f, 0.099019f, 0.000001f, 0.000002f, 0.000002f, 0.000070f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000114f, 0.000097f, 0.000101f, 0.012086f, 0.000000f, 0.000000f, 0.000000f, 0.000010f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000013f, 0.000022f, 0.000017f, 0.002039f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000004f, 0.000001f, 0.000325f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000008f, 0.000006f, 0.000716f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.501838f, 0.509076f, 0.918924f, 2.300186f, 0.629247f, 0.937721f, 1.725742f, 2.153751f, 19.144367f, 17.978261f, 20.941934f, 83.165222f, 0.869481f, 0.508767f, 1.401584f, 3.547118f, +0.060660f, 0.120469f, 0.160356f, 0.402163f, 0.107799f, 0.314497f, 0.426810f, 0.533688f, 3.936163f, 7.236538f, 6.216064f, 24.732814f, 0.157815f, 0.180784f, 0.367261f, 0.931246f, +0.022811f, 0.045499f, 0.026775f, 0.138192f, 0.018964f, 0.055568f, 0.033340f, 0.085792f, 1.658919f, 3.063128f, 1.163229f, 9.524881f, 0.023527f, 0.027068f, 0.024310f, 0.126856f, +0.072181f, 0.126840f, 0.152840f, 0.393697f, 0.068124f, 0.175858f, 0.216048f, 0.277466f, 2.446701f, 3.980150f, 3.094943f, 12.647923f, 0.112417f, 0.113947f, 0.209550f, 0.545739f, +0.000587f, 0.000928f, 0.000748f, 0.007318f, 0.000518f, 0.001203f, 0.000989f, 0.004824f, 0.155008f, 0.226771f, 0.118030f, 1.831558f, 0.001541f, 0.001405f, 0.001729f, 0.017100f, +0.000015f, 0.000046f, 0.000027f, 0.000266f, 0.000018f, 0.000084f, 0.000051f, 0.000248f, 0.006623f, 0.018968f, 0.007280f, 0.113186f, 0.000058f, 0.000104f, 0.000094f, 0.000933f, +0.000015f, 0.000046f, 0.000012f, 0.000246f, 0.000009f, 0.000040f, 0.000011f, 0.000108f, 0.007527f, 0.021652f, 0.003674f, 0.117551f, 0.000023f, 0.000042f, 0.000017f, 0.000343f, +0.000041f, 0.000112f, 0.000060f, 0.000608f, 0.000027f, 0.000110f, 0.000060f, 0.000302f, 0.009619f, 0.024376f, 0.008469f, 0.135247f, 0.000097f, 0.000153f, 0.000126f, 0.001277f, +0.018610f, 0.045399f, 0.049289f, 0.219313f, 0.025711f, 0.092145f, 0.101994f, 0.226270f, 2.803673f, 6.331834f, 4.436110f, 31.315380f, 0.023774f, 0.033454f, 0.055431f, 0.249369f, +0.001351f, 0.006451f, 0.005165f, 0.023026f, 0.002645f, 0.018558f, 0.015148f, 0.033669f, 0.346159f, 1.530482f, 0.790709f, 5.592492f, 0.002591f, 0.007139f, 0.008722f, 0.039314f, +0.000293f, 0.001404f, 0.000497f, 0.004559f, 0.000268f, 0.001889f, 0.000682f, 0.003119f, 0.084064f, 0.373291f, 0.085261f, 1.241013f, 0.000223f, 0.000616f, 0.000333f, 0.003086f, +0.000434f, 0.001833f, 0.001328f, 0.006081f, 0.000451f, 0.002800f, 0.002069f, 0.004723f, 0.058051f, 0.227102f, 0.106213f, 0.771569f, 0.000498f, 0.001214f, 0.001343f, 0.006216f, +0.001261f, 0.001145f, 0.002306f, 0.022996f, 0.000094f, 0.000125f, 0.000258f, 0.001281f, 0.112654f, 0.094709f, 0.123056f, 1.947050f, 0.001093f, 0.000573f, 0.001760f, 0.017747f, +0.000170f, 0.000302f, 0.000448f, 0.004475f, 0.000018f, 0.000047f, 0.000071f, 0.000353f, 0.025783f, 0.042435f, 0.040658f, 0.644550f, 0.000221f, 0.000227f, 0.000513f, 0.005186f, +0.000089f, 0.000159f, 0.000104f, 0.002141f, 0.000004f, 0.000012f, 0.000008f, 0.000079f, 0.015131f, 0.025011f, 0.010594f, 0.345640f, 0.000046f, 0.000047f, 0.000047f, 0.000984f, +0.000252f, 0.000397f, 0.000533f, 0.005471f, 0.000014f, 0.000033f, 0.000045f, 0.000229f, 0.020013f, 0.029146f, 0.025280f, 0.411613f, 0.000197f, 0.000178f, 0.000366f, 0.003796f, +0.001095f, 0.002094f, 0.003185f, 0.031234f, 0.014715f, 0.041332f, 0.064112f, 0.313453f, 0.737738f, 1.305810f, 1.282038f, 19.945409f, 0.001078f, 0.001189f, 0.002760f, 0.027365f, +0.000038f, 0.000144f, 0.000161f, 0.001582f, 0.000730f, 0.004016f, 0.004594f, 0.022502f, 0.043943f, 0.152272f, 0.110244f, 1.718429f, 0.000057f, 0.000122f, 0.000210f, 0.002081f, +0.000007f, 0.000027f, 0.000013f, 0.000271f, 0.000064f, 0.000354f, 0.000179f, 0.001806f, 0.009249f, 0.032187f, 0.010302f, 0.330481f, 0.000004f, 0.000009f, 0.000007f, 0.000142f, +0.000054f, 0.000179f, 0.000182f, 0.001837f, 0.000547f, 0.002664f, 0.002758f, 0.013877f, 0.032401f, 0.099346f, 0.065111f, 1.042410f, 0.000048f, 0.000091f, 0.000142f, 0.001447f, +0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000001f, 0.000003f, 0.000002f, 0.000034f, 0.000288f, 0.000793f, 0.000348f, 0.021150f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000004f, 0.000019f, 0.000006f, 0.000379f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000011f, 0.000002f, 0.000196f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000006f, 0.000029f, 0.000009f, 0.000537f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000033f, 0.000152f, 0.000139f, 0.002417f, 0.000488f, 0.003297f, 0.003076f, 0.026731f, 0.087699f, 0.373311f, 0.220443f, 6.096321f, 0.000024f, 0.000063f, 0.000089f, 0.001562f, +0.000001f, 0.000006f, 0.000004f, 0.000074f, 0.000015f, 0.000192f, 0.000132f, 0.001152f, 0.003137f, 0.026141f, 0.011383f, 0.315408f, 0.000001f, 0.000004f, 0.000004f, 0.000071f, +0.000000f, 0.000001f, 0.000000f, 0.000007f, 0.000001f, 0.000010f, 0.000003f, 0.000053f, 0.000380f, 0.003184f, 0.000613f, 0.034952f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000002f, 0.000001f, 0.000023f, 0.000003f, 0.000034f, 0.000021f, 0.000192f, 0.000624f, 0.004601f, 0.001814f, 0.051618f, 0.000000f, 0.000001f, 0.000001f, 0.000013f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000017f, 0.000027f, 0.000030f, 0.001832f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000004f, 0.000003f, 0.000176f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000047f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000002f, 0.000133f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.022480f, 0.034207f, 0.035268f, 0.176851f, 0.029065f, 0.064972f, 0.068297f, 0.170749f, 2.280677f, 3.212719f, 2.137542f, 17.005023f, 0.030674f, 0.026923f, 0.042364f, 0.214781f, +0.001166f, 0.003473f, 0.002641f, 0.013268f, 0.002137f, 0.009350f, 0.007248f, 0.018155f, 0.201205f, 0.554880f, 0.272243f, 2.169964f, 0.002389f, 0.004105f, 0.004763f, 0.024195f, +0.000594f, 0.001777f, 0.000597f, 0.006176f, 0.000509f, 0.002238f, 0.000767f, 0.003954f, 0.114881f, 0.318194f, 0.069018f, 1.132130f, 0.000482f, 0.000833f, 0.000427f, 0.004465f, +0.001903f, 0.005017f, 0.003453f, 0.017818f, 0.001852f, 0.007172f, 0.005033f, 0.012949f, 0.171575f, 0.418673f, 0.185952f, 1.522318f, 0.002334f, 0.003549f, 0.003728f, 0.019452f, +0.000003f, 0.000007f, 0.000003f, 0.000062f, 0.000003f, 0.000009f, 0.000004f, 0.000042f, 0.002024f, 0.004442f, 0.001320f, 0.041048f, 0.000006f, 0.000008f, 0.000006f, 0.000113f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000037f, 0.000159f, 0.000035f, 0.001088f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000057f, 0.000247f, 0.000024f, 0.001531f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000074f, 0.000281f, 0.000056f, 0.001784f, 0.000000f, 0.000001f, 0.000000f, 0.000005f, +0.000715f, 0.002615f, 0.001621f, 0.014453f, 0.001018f, 0.005472f, 0.003460f, 0.015376f, 0.286290f, 0.969863f, 0.388111f, 5.488444f, 0.000719f, 0.001517f, 0.001436f, 0.012942f, +0.000022f, 0.000159f, 0.000073f, 0.000651f, 0.000045f, 0.000473f, 0.000220f, 0.000982f, 0.015167f, 0.100589f, 0.029683f, 0.420572f, 0.000034f, 0.000139f, 0.000097f, 0.000876f, +0.000007f, 0.000047f, 0.000010f, 0.000175f, 0.000006f, 0.000065f, 0.000013f, 0.000123f, 0.004990f, 0.033238f, 0.004336f, 0.126436f, 0.000004f, 0.000016f, 0.000005f, 0.000093f, +0.000010f, 0.000062f, 0.000026f, 0.000236f, 0.000011f, 0.000098f, 0.000041f, 0.000189f, 0.003489f, 0.020476f, 0.005470f, 0.079601f, 0.000009f, 0.000032f, 0.000020f, 0.000190f, +0.000017f, 0.000023f, 0.000026f, 0.000518f, 0.000001f, 0.000003f, 0.000003f, 0.000030f, 0.003934f, 0.004962f, 0.003682f, 0.116715f, 0.000011f, 0.000009f, 0.000016f, 0.000315f, +0.000001f, 0.000003f, 0.000002f, 0.000043f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000386f, 0.000954f, 0.000522f, 0.016579f, 0.000001f, 0.000002f, 0.000002f, 0.000040f, +0.000001f, 0.000002f, 0.000001f, 0.000028f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000307f, 0.000762f, 0.000184f, 0.012044f, 0.000000f, 0.000000f, 0.000000f, 0.000010f, +0.000002f, 0.000005f, 0.000004f, 0.000073f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000411f, 0.000899f, 0.000445f, 0.014524f, 0.000001f, 0.000002f, 0.000002f, 0.000040f, +0.001771f, 0.001621f, 0.002710f, 0.016430f, 0.147843f, 0.198849f, 0.338866f, 1.024494f, 4.471477f, 3.789906f, 4.087888f, 39.326566f, 0.079555f, 0.042014f, 0.107176f, 0.657077f, +0.000130f, 0.000234f, 0.000288f, 0.001750f, 0.015427f, 0.040620f, 0.051046f, 0.154624f, 0.559961f, 0.929151f, 0.739048f, 7.123484f, 0.008795f, 0.009093f, 0.017105f, 0.105070f, +0.000032f, 0.000057f, 0.000031f, 0.000390f, 0.001760f, 0.004654f, 0.002586f, 0.016119f, 0.153046f, 0.255055f, 0.089688f, 1.779062f, 0.000850f, 0.000883f, 0.000734f, 0.009282f, +0.000125f, 0.000199f, 0.000222f, 0.001385f, 0.007886f, 0.018372f, 0.020900f, 0.065024f, 0.281541f, 0.413363f, 0.297637f, 2.946556f, 0.005067f, 0.004636f, 0.007894f, 0.049805f, +0.000001f, 0.000002f, 0.000001f, 0.000034f, 0.000078f, 0.000164f, 0.000125f, 0.001476f, 0.023290f, 0.030752f, 0.014821f, 0.557150f, 0.000091f, 0.000075f, 0.000085f, 0.002038f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000007f, 0.000004f, 0.000046f, 0.000606f, 0.001567f, 0.000557f, 0.020971f, 0.000002f, 0.000003f, 0.000003f, 0.000068f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000001f, 0.000013f, 0.000447f, 0.001160f, 0.000182f, 0.014124f, 0.000001f, 0.000001f, 0.000000f, 0.000016f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000007f, 0.000004f, 0.000045f, 0.000712f, 0.001629f, 0.000524f, 0.020269f, 0.000003f, 0.000004f, 0.000003f, 0.000075f, +0.000061f, 0.000135f, 0.000136f, 0.001464f, 0.005645f, 0.018259f, 0.018715f, 0.100577f, 0.611921f, 1.247292f, 0.809176f, 13.837591f, 0.002033f, 0.002582f, 0.003961f, 0.043166f, +0.000003f, 0.000012f, 0.000009f, 0.000094f, 0.000354f, 0.002240f, 0.001693f, 0.009116f, 0.046017f, 0.183629f, 0.087848f, 1.505159f, 0.000135f, 0.000336f, 0.000380f, 0.004145f, +0.000000f, 0.000002f, 0.000001f, 0.000012f, 0.000023f, 0.000148f, 0.000049f, 0.000548f, 0.007247f, 0.029045f, 0.006143f, 0.216604f, 0.000008f, 0.000019f, 0.000009f, 0.000211f, +0.000001f, 0.000003f, 0.000002f, 0.000020f, 0.000049f, 0.000273f, 0.000187f, 0.001034f, 0.006242f, 0.022040f, 0.009545f, 0.167969f, 0.000021f, 0.000046f, 0.000047f, 0.000530f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000001f, 0.000001f, 0.000012f, 0.000533f, 0.000405f, 0.000487f, 0.018662f, 0.000002f, 0.000001f, 0.000003f, 0.000067f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000074f, 0.000110f, 0.000098f, 0.003763f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000028f, 0.000042f, 0.000017f, 0.001309f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000047f, 0.000061f, 0.000049f, 0.001944f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, +4.128192f, 3.747249f, 7.766324f, 6.248925f, 4.830865f, 6.441848f, 13.611917f, 5.460661f, 35.912903f, 30.177995f, 40.361351f, 51.522498f, 7.295512f, 3.819866f, 12.082431f, 9.829178f, +0.596356f, 1.059765f, 1.619676f, 1.305722f, 0.989062f, 2.582025f, 4.023321f, 1.617124f, 8.824472f, 14.517097f, 14.317613f, 18.311965f, 1.582527f, 1.622163f, 3.783695f, 3.083985f, +0.489710f, 0.874028f, 0.590553f, 0.979757f, 0.379958f, 0.996220f, 0.686270f, 0.567662f, 8.121320f, 13.418374f, 5.850676f, 15.399504f, 0.515170f, 0.530366f, 0.546907f, 0.917372f, +1.043367f, 1.640594f, 2.269806f, 1.879403f, 0.919005f, 2.122831f, 2.994391f, 1.236163f, 8.065029f, 11.739719f, 10.481350f, 13.768606f, 1.657461f, 1.503306f, 3.174226f, 2.657310f, +0.022633f, 0.032006f, 0.029639f, 0.093189f, 0.018646f, 0.038735f, 0.036571f, 0.057329f, 1.362944f, 1.784203f, 1.066240f, 5.318517f, 0.060606f, 0.049435f, 0.069868f, 0.222098f, +0.000679f, 0.001881f, 0.001284f, 0.004046f, 0.000793f, 0.003226f, 0.002246f, 0.003528f, 0.069592f, 0.178351f, 0.078596f, 0.392798f, 0.002732f, 0.004362f, 0.004547f, 0.014480f, +0.001505f, 0.004183f, 0.001263f, 0.008188f, 0.000822f, 0.003357f, 0.001033f, 0.003340f, 0.172719f, 0.444571f, 0.086613f, 0.890815f, 0.002398f, 0.003846f, 0.001772f, 0.011616f, +0.002778f, 0.006804f, 0.004206f, 0.013608f, 0.001722f, 0.006198f, 0.003906f, 0.006301f, 0.148615f, 0.337008f, 0.134442f, 0.690100f, 0.006685f, 0.009446f, 0.008912f, 0.029154f, +0.228050f, 0.497826f, 0.620561f, 0.887575f, 0.294051f, 0.942985f, 1.198443f, 0.854621f, 7.834913f, 15.833245f, 12.736472f, 28.900865f, 0.297160f, 0.374178f, 0.711850f, 1.029395f, +0.019783f, 0.084546f, 0.077716f, 0.111370f, 0.036152f, 0.226971f, 0.212715f, 0.151980f, 1.156081f, 4.573778f, 2.713125f, 6.168290f, 0.038708f, 0.095420f, 0.133865f, 0.193951f, +0.009361f, 0.040178f, 0.016328f, 0.048153f, 0.008003f, 0.050460f, 0.020907f, 0.030741f, 0.613072f, 2.436016f, 0.638837f, 2.988970f, 0.007261f, 0.017977f, 0.011149f, 0.033244f, +0.009338f, 0.035311f, 0.029383f, 0.043247f, 0.009063f, 0.050344f, 0.042712f, 0.031343f, 0.285056f, 0.997877f, 0.535846f, 1.251249f, 0.010937f, 0.023857f, 0.030298f, 0.045087f, +0.024716f, 0.020085f, 0.046432f, 0.148851f, 0.001720f, 0.002053f, 0.004840f, 0.007736f, 0.503521f, 0.378787f, 0.565086f, 2.874054f, 0.021860f, 0.010246f, 0.036151f, 0.117174f, +0.003974f, 0.006323f, 0.010779f, 0.034621f, 0.000392f, 0.000916f, 0.001592f, 0.002550f, 0.137722f, 0.202830f, 0.223135f, 1.137051f, 0.005278f, 0.004844f, 0.012602f, 0.040924f, +0.004544f, 0.007261f, 0.005472f, 0.036174f, 0.000210f, 0.000492f, 0.000378f, 0.001246f, 0.176491f, 0.261056f, 0.126965f, 1.331476f, 0.002393f, 0.002205f, 0.002536f, 0.016951f, +0.008683f, 0.012223f, 0.018863f, 0.062230f, 0.000455f, 0.000941f, 0.001480f, 0.002434f, 0.157184f, 0.204832f, 0.203986f, 1.067633f, 0.006903f, 0.005605f, 0.013202f, 0.044034f, +0.004790f, 0.008195f, 0.014315f, 0.045123f, 0.060075f, 0.150990f, 0.268912f, 0.422623f, 0.735938f, 1.165608f, 1.313953f, 6.570953f, 0.004809f, 0.004746f, 0.012653f, 0.040324f, +0.000200f, 0.000671f, 0.000865f, 0.002732f, 0.003563f, 0.017533f, 0.023027f, 0.036258f, 0.052389f, 0.162442f, 0.135034f, 0.676586f, 0.000302f, 0.000584f, 0.001148f, 0.003665f, +0.000082f, 0.000277f, 0.000157f, 0.001024f, 0.000684f, 0.003378f, 0.001961f, 0.006356f, 0.024077f, 0.074980f, 0.027555f, 0.284134f, 0.000049f, 0.000095f, 0.000083f, 0.000544f, +0.000416f, 0.001233f, 0.001438f, 0.004664f, 0.003927f, 0.017099f, 0.020329f, 0.032878f, 0.056796f, 0.155825f, 0.117260f, 0.603448f, 0.000375f, 0.000642f, 0.001142f, 0.003746f, +0.000001f, 0.000003f, 0.000003f, 0.000032f, 0.000011f, 0.000044f, 0.000035f, 0.000214f, 0.001345f, 0.003318f, 0.001671f, 0.032659f, 0.000002f, 0.000003f, 0.000004f, 0.000044f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000004f, 0.000020f, 0.000096f, 0.000036f, 0.000699f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000002f, 0.000025f, 0.000120f, 0.000020f, 0.000791f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000002f, 0.000001f, 0.000008f, 0.000050f, 0.000215f, 0.000072f, 0.001456f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000215f, 0.000884f, 0.000928f, 0.005202f, 0.002968f, 0.017941f, 0.019218f, 0.053690f, 0.130327f, 0.496410f, 0.336567f, 2.991927f, 0.000159f, 0.000377f, 0.000605f, 0.003428f, +0.000005f, 0.000043f, 0.000034f, 0.000189f, 0.000106f, 0.001251f, 0.000988f, 0.002766f, 0.005571f, 0.041543f, 0.020771f, 0.184996f, 0.000006f, 0.000028f, 0.000033f, 0.000187f, +0.000001f, 0.000010f, 0.000004f, 0.000041f, 0.000012f, 0.000139f, 0.000049f, 0.000279f, 0.001475f, 0.011049f, 0.002442f, 0.044766f, 0.000001f, 0.000003f, 0.000001f, 0.000016f, +0.000003f, 0.000022f, 0.000015f, 0.000087f, 0.000031f, 0.000329f, 0.000235f, 0.000677f, 0.001629f, 0.010751f, 0.004866f, 0.044515f, 0.000002f, 0.000008f, 0.000009f, 0.000052f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000040f, 0.000057f, 0.000072f, 0.001438f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000009f, 0.000008f, 0.000165f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000006f, 0.000002f, 0.000096f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000011f, 0.000009f, 0.000184f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.007529f, 0.008569f, 0.010143f, 0.097693f, 0.007575f, 0.012666f, 0.015285f, 0.073403f, 2.906381f, 3.062181f, 2.338973f, 35.742443f, 0.007798f, 0.005119f, 0.009247f, 0.090056f, +0.000336f, 0.000748f, 0.000653f, 0.006299f, 0.000479f, 0.001567f, 0.001394f, 0.006708f, 0.220379f, 0.454569f, 0.256041f, 3.920142f, 0.000522f, 0.000671f, 0.000894f, 0.008719f, +0.000104f, 0.000232f, 0.000090f, 0.001779f, 0.000069f, 0.000227f, 0.000089f, 0.000886f, 0.076330f, 0.158127f, 0.039376f, 1.240678f, 0.000064f, 0.000083f, 0.000049f, 0.000976f, +0.000405f, 0.000799f, 0.000631f, 0.006254f, 0.000307f, 0.000888f, 0.000716f, 0.003537f, 0.138923f, 0.253550f, 0.129283f, 2.033028f, 0.000377f, 0.000429f, 0.000517f, 0.005182f, +0.000000f, 0.000001f, 0.000000f, 0.000012f, 0.000000f, 0.000001f, 0.000000f, 0.000007f, 0.000933f, 0.001532f, 0.000523f, 0.031223f, 0.000001f, 0.000001f, 0.000000f, 0.000017f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000015f, 0.000047f, 0.000012f, 0.000712f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000044f, 0.000005f, 0.000607f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000022f, 0.000062f, 0.000014f, 0.000862f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000269f, 0.000738f, 0.000525f, 0.008991f, 0.000299f, 0.001201f, 0.000872f, 0.007444f, 0.410848f, 1.041011f, 0.478248f, 12.991014f, 0.000206f, 0.000325f, 0.000353f, 0.006111f, +0.000007f, 0.000039f, 0.000020f, 0.000348f, 0.000011f, 0.000089f, 0.000048f, 0.000408f, 0.018707f, 0.092798f, 0.031438f, 0.855611f, 0.000008f, 0.000026f, 0.000020f, 0.000355f, +0.000001f, 0.000007f, 0.000002f, 0.000057f, 0.000001f, 0.000007f, 0.000002f, 0.000031f, 0.003734f, 0.018601f, 0.002786f, 0.156034f, 0.000001f, 0.000002f, 0.000001f, 0.000023f, +0.000002f, 0.000011f, 0.000005f, 0.000093f, 0.000002f, 0.000014f, 0.000007f, 0.000058f, 0.003182f, 0.013965f, 0.004283f, 0.119713f, 0.000002f, 0.000004f, 0.000003f, 0.000057f, +0.000001f, 0.000001f, 0.000002f, 0.000073f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.001271f, 0.001199f, 0.001021f, 0.062183f, 0.000001f, 0.000000f, 0.000001f, 0.000033f, +0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000107f, 0.000198f, 0.000124f, 0.007592f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000052f, 0.000096f, 0.000027f, 0.003346f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000084f, 0.000138f, 0.000078f, 0.004917f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000561f, 0.000384f, 0.000738f, 0.008592f, 0.036480f, 0.036698f, 0.071796f, 0.416945f, 5.394532f, 3.419800f, 4.234710f, 78.254084f, 0.019146f, 0.007563f, 0.022148f, 0.260824f, +0.000036f, 0.000048f, 0.000067f, 0.000786f, 0.003272f, 0.006443f, 0.009296f, 0.054086f, 0.580635f, 0.720611f, 0.658021f, 12.183050f, 0.001819f, 0.001407f, 0.003038f, 0.035847f, +0.000005f, 0.000007f, 0.000004f, 0.000106f, 0.000226f, 0.000448f, 0.000286f, 0.003420f, 0.096268f, 0.119994f, 0.048441f, 1.845729f, 0.000107f, 0.000083f, 0.000079f, 0.001921f, +0.000025f, 0.000030f, 0.000038f, 0.000460f, 0.001236f, 0.002154f, 0.002814f, 0.016814f, 0.215812f, 0.236993f, 0.195903f, 3.725349f, 0.000775f, 0.000530f, 0.001037f, 0.012561f, +0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000007f, 0.000011f, 0.000010f, 0.000217f, 0.010169f, 0.010042f, 0.005556f, 0.401216f, 0.000008f, 0.000005f, 0.000006f, 0.000293f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000227f, 0.000440f, 0.000179f, 0.012980f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000102f, 0.000197f, 0.000036f, 0.005303f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000198f, 0.000338f, 0.000125f, 0.009274f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, +0.000022f, 0.000036f, 0.000042f, 0.000862f, 0.001569f, 0.003795f, 0.004465f, 0.046095f, 0.831352f, 1.267440f, 0.943962f, 31.007593f, 0.000551f, 0.000523f, 0.000922f, 0.019296f, +0.000001f, 0.000003f, 0.000002f, 0.000047f, 0.000084f, 0.000400f, 0.000347f, 0.003591f, 0.053734f, 0.160377f, 0.088082f, 2.898897f, 0.000031f, 0.000058f, 0.000076f, 0.001593f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000003f, 0.000016f, 0.000006f, 0.000131f, 0.005133f, 0.015388f, 0.003736f, 0.253064f, 0.000001f, 0.000002f, 0.000001f, 0.000049f, +0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000009f, 0.000036f, 0.000028f, 0.000301f, 0.005388f, 0.014230f, 0.007075f, 0.239149f, 0.000004f, 0.000006f, 0.000007f, 0.000151f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000163f, 0.000093f, 0.000128f, 0.009413f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000020f, 0.000022f, 0.000022f, 0.001631f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, 0.000005f, 0.000002f, 0.000344f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000009f, 0.000009f, 0.000008f, 0.000623f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +2.840877f, 1.928744f, 4.589127f, 7.092776f, 2.587129f, 2.580316f, 6.259421f, 4.823436f, 94.036158f, 59.102306f, 90.746952f, 222.515210f, 3.810756f, 1.492358f, 5.419157f, 8.468197f, +0.352729f, 0.468829f, 0.822593f, 1.273809f, 0.455259f, 0.888926f, 1.590165f, 1.227715f, 19.859839f, 24.436346f, 27.668112f, 67.973572f, 0.710475f, 0.544706f, 1.458599f, 2.283643f, +0.175706f, 0.234554f, 0.181941f, 0.579809f, 0.106093f, 0.208053f, 0.164538f, 0.261431f, 11.087327f, 13.701550f, 6.858488f, 34.675709f, 0.140301f, 0.108033f, 0.127893f, 0.412074f, +0.456206f, 0.536531f, 0.852186f, 1.355382f, 0.312710f, 0.540268f, 0.874892f, 0.693774f, 13.417803f, 14.608405f, 14.973204f, 37.781915f, 0.550085f, 0.373167f, 0.904579f, 1.454612f, +0.005637f, 0.005962f, 0.006338f, 0.038279f, 0.003614f, 0.005615f, 0.006086f, 0.018326f, 1.291538f, 1.264570f, 0.867573f, 8.312621f, 0.011457f, 0.006989f, 0.011341f, 0.069247f, +0.000145f, 0.000301f, 0.000236f, 0.001429f, 0.000132f, 0.000402f, 0.000321f, 0.000969f, 0.056680f, 0.108647f, 0.054966f, 0.527666f, 0.000444f, 0.000530f, 0.000634f, 0.003880f, +0.000195f, 0.000406f, 0.000141f, 0.001754f, 0.000083f, 0.000254f, 0.000090f, 0.000557f, 0.085335f, 0.164284f, 0.036744f, 0.725923f, 0.000236f, 0.000284f, 0.000150f, 0.001888f, +0.000440f, 0.000805f, 0.000571f, 0.003552f, 0.000212f, 0.000571f, 0.000413f, 0.001280f, 0.089479f, 0.151764f, 0.069505f, 0.685315f, 0.000803f, 0.000849f, 0.000919f, 0.005775f, +0.176730f, 0.288554f, 0.412939f, 1.134496f, 0.177339f, 0.425357f, 0.620610f, 0.850103f, 23.102855f, 34.919711f, 32.247964f, 140.559580f, 0.174796f, 0.164623f, 0.359545f, 0.998717f, +0.013177f, 0.042119f, 0.044448f, 0.122351f, 0.018740f, 0.087996f, 0.094677f, 0.129936f, 2.929962f, 8.669982f, 5.904259f, 25.784375f, 0.019570f, 0.036082f, 0.058113f, 0.161732f, +0.003782f, 0.012142f, 0.005665f, 0.032090f, 0.002516f, 0.011867f, 0.005645f, 0.015943f, 0.942537f, 2.801152f, 0.843333f, 7.579262f, 0.002227f, 0.004124f, 0.002936f, 0.016816f, +0.004598f, 0.013004f, 0.012423f, 0.035123f, 0.003473f, 0.014429f, 0.014053f, 0.019809f, 0.534062f, 1.398327f, 0.862034f, 3.866555f, 0.004088f, 0.006669f, 0.009723f, 0.027793f, +0.004311f, 0.002620f, 0.006955f, 0.042825f, 0.000233f, 0.000208f, 0.000564f, 0.001732f, 0.334196f, 0.188039f, 0.322047f, 3.146271f, 0.002894f, 0.001015f, 0.004110f, 0.025588f, +0.000596f, 0.000709f, 0.001388f, 0.008561f, 0.000046f, 0.000080f, 0.000160f, 0.000491f, 0.078565f, 0.086542f, 0.109299f, 1.069852f, 0.000601f, 0.000412f, 0.001231f, 0.007681f, +0.000413f, 0.000494f, 0.000427f, 0.005426f, 0.000015f, 0.000026f, 0.000023f, 0.000146f, 0.061075f, 0.067568f, 0.037726f, 0.759959f, 0.000165f, 0.000114f, 0.000150f, 0.001930f, +0.000962f, 0.001013f, 0.001795f, 0.011376f, 0.000039f, 0.000061f, 0.000110f, 0.000346f, 0.066286f, 0.064607f, 0.073865f, 0.742599f, 0.000581f, 0.000353f, 0.000954f, 0.006110f, +0.001841f, 0.002356f, 0.004725f, 0.028611f, 0.017972f, 0.033786f, 0.069079f, 0.208537f, 1.076477f, 1.275221f, 1.650310f, 15.852941f, 0.001403f, 0.001036f, 0.003170f, 0.019407f, +0.000066f, 0.000166f, 0.000245f, 0.001489f, 0.000916f, 0.003372f, 0.005084f, 0.015377f, 0.065863f, 0.152748f, 0.145770f, 1.402967f, 0.000076f, 0.000110f, 0.000247f, 0.001516f, +0.000016f, 0.000041f, 0.000027f, 0.000338f, 0.000107f, 0.000394f, 0.000263f, 0.001635f, 0.018362f, 0.042770f, 0.018045f, 0.357406f, 0.000007f, 0.000011f, 0.000011f, 0.000137f, +0.000102f, 0.000225f, 0.000302f, 0.001879f, 0.000747f, 0.002431f, 0.003318f, 0.010308f, 0.052785f, 0.108318f, 0.093576f, 0.925022f, 0.000070f, 0.000089f, 0.000182f, 0.001146f, +0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000001f, 0.000004f, 0.000003f, 0.000038f, 0.000712f, 0.001314f, 0.000760f, 0.028515f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000009f, 0.000033f, 0.000014f, 0.000524f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000025f, 0.000005f, 0.000360f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000017f, 0.000054f, 0.000021f, 0.000808f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000093f, 0.000286f, 0.000345f, 0.003715f, 0.001000f, 0.004521f, 0.005560f, 0.029834f, 0.214676f, 0.611590f, 0.476041f, 8.128668f, 0.000052f, 0.000093f, 0.000171f, 0.001858f, +0.000002f, 0.000012f, 0.000011f, 0.000116f, 0.000031f, 0.000271f, 0.000246f, 0.001321f, 0.007887f, 0.043991f, 0.025250f, 0.431989f, 0.000002f, 0.000006f, 0.000008f, 0.000087f, +0.000000f, 0.000002f, 0.000001f, 0.000015f, 0.000002f, 0.000018f, 0.000007f, 0.000081f, 0.001267f, 0.007098f, 0.001801f, 0.063412f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, +0.000001f, 0.000004f, 0.000004f, 0.000040f, 0.000007f, 0.000053f, 0.000043f, 0.000239f, 0.001705f, 0.008416f, 0.004373f, 0.076843f, 0.000000f, 0.000001f, 0.000002f, 0.000018f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000015f, 0.000016f, 0.000023f, 0.000879f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000002f, 0.000087f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000031f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000002f, 0.000071f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.003794f, 0.006552f, 0.005986f, 0.052423f, 0.004418f, 0.011209f, 0.010441f, 0.045589f, 2.189400f, 3.500450f, 2.063719f, 28.673458f, 0.009335f, 0.009300f, 0.012967f, 0.114815f, +0.000095f, 0.000323f, 0.000217f, 0.001907f, 0.000157f, 0.000782f, 0.000537f, 0.002351f, 0.093667f, 0.293182f, 0.127462f, 1.774360f, 0.000353f, 0.000688f, 0.000707f, 0.006272f, +0.000032f, 0.000109f, 0.000033f, 0.000588f, 0.000025f, 0.000124f, 0.000038f, 0.000339f, 0.035417f, 0.111340f, 0.021400f, 0.613064f, 0.000047f, 0.000092f, 0.000042f, 0.000767f, +0.000172f, 0.000514f, 0.000313f, 0.002824f, 0.000151f, 0.000662f, 0.000411f, 0.001848f, 0.088062f, 0.243892f, 0.095986f, 1.372393f, 0.000380f, 0.000656f, 0.000610f, 0.005559f, +0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000400f, 0.000997f, 0.000263f, 0.014261f, 0.000000f, 0.000001f, 0.000000f, 0.000013f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000017f, 0.000003f, 0.000183f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000018f, 0.000002f, 0.000171f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000034f, 0.000006f, 0.000331f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000076f, 0.000314f, 0.000173f, 0.002687f, 0.000097f, 0.000592f, 0.000332f, 0.002574f, 0.172346f, 0.662667f, 0.234977f, 5.803444f, 0.000137f, 0.000329f, 0.000276f, 0.004339f, +0.000001f, 0.000009f, 0.000004f, 0.000059f, 0.000002f, 0.000025f, 0.000010f, 0.000080f, 0.004428f, 0.033329f, 0.008715f, 0.215657f, 0.000003f, 0.000015f, 0.000009f, 0.000142f, +0.000000f, 0.000002f, 0.000000f, 0.000010f, 0.000000f, 0.000002f, 0.000000f, 0.000007f, 0.000965f, 0.007293f, 0.000843f, 0.042935f, 0.000000f, 0.000001f, 0.000000f, 0.000010f, +0.000001f, 0.000004f, 0.000001f, 0.000023f, 0.000001f, 0.000006f, 0.000002f, 0.000017f, 0.001123f, 0.007480f, 0.001771f, 0.045001f, 0.000001f, 0.000004f, 0.000002f, 0.000034f, +0.000000f, 0.000001f, 0.000001f, 0.000020f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000480f, 0.000687f, 0.000452f, 0.025002f, 0.000000f, 0.000000f, 0.000001f, 0.000021f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000023f, 0.000064f, 0.000031f, 0.001722f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, 0.000034f, 0.000007f, 0.000829f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000027f, 0.000067f, 0.000029f, 0.001663f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000243f, 0.000253f, 0.000375f, 0.003969f, 0.018312f, 0.027955f, 0.042213f, 0.222893f, 3.497816f, 3.364839f, 3.216027f, 54.034762f, 0.019729f, 0.011826f, 0.026731f, 0.286223f, +0.000009f, 0.000018f, 0.000019f, 0.000205f, 0.000927f, 0.002769f, 0.003084f, 0.016314f, 0.212417f, 0.400045f, 0.281955f, 4.746422f, 0.001058f, 0.001241f, 0.002069f, 0.022195f, +0.000001f, 0.000003f, 0.000001f, 0.000030f, 0.000070f, 0.000210f, 0.000103f, 0.001126f, 0.038448f, 0.072724f, 0.022660f, 0.785028f, 0.000068f, 0.000080f, 0.000059f, 0.001298f, +0.000009f, 0.000017f, 0.000016f, 0.000179f, 0.000522f, 0.001381f, 0.001392f, 0.007564f, 0.117749f, 0.196217f, 0.125192f, 2.164574f, 0.000672f, 0.000698f, 0.001053f, 0.011599f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000002f, 0.000005f, 0.000003f, 0.000066f, 0.003754f, 0.005626f, 0.002403f, 0.157737f, 0.000005f, 0.000004f, 0.000004f, 0.000183f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000047f, 0.000139f, 0.000044f, 0.002879f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000023f, 0.000068f, 0.000009f, 0.001284f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000061f, 0.000159f, 0.000045f, 0.003068f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000005f, 0.000013f, 0.000012f, 0.000222f, 0.000438f, 0.001610f, 0.001462f, 0.013722f, 0.300176f, 0.694445f, 0.399206f, 11.922890f, 0.000316f, 0.000456f, 0.000620f, 0.011791f, +0.000000f, 0.000001f, 0.000000f, 0.000007f, 0.000013f, 0.000096f, 0.000064f, 0.000603f, 0.010947f, 0.049579f, 0.021017f, 0.628913f, 0.000010f, 0.000029f, 0.000029f, 0.000549f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000004f, 0.000001f, 0.000024f, 0.001142f, 0.005193f, 0.000973f, 0.059937f, 0.000000f, 0.000001f, 0.000000f, 0.000019f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000002f, 0.000013f, 0.000008f, 0.000075f, 0.001637f, 0.006561f, 0.002518f, 0.077379f, 0.000002f, 0.000004f, 0.000004f, 0.000077f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000053f, 0.000046f, 0.000049f, 0.003258f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000006f, 0.000005f, 0.000319f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000001f, 0.000073f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000004f, 0.000003f, 0.000181f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.615080f, 0.633686f, 1.163756f, 1.635378f, 0.648314f, 0.981207f, 1.837190f, 1.287202f, 30.437582f, 29.029524f, 34.403300f, 76.700467f, 1.960275f, 1.164929f, 3.265054f, 4.638952f, +0.043089f, 0.086908f, 0.117696f, 0.165711f, 0.064368f, 0.190720f, 0.263334f, 0.184855f, 3.626895f, 6.771986f, 5.918226f, 13.219732f, 0.206205f, 0.239901f, 0.495837f, 0.705832f, +0.023432f, 0.047467f, 0.028419f, 0.082345f, 0.016376f, 0.048732f, 0.029747f, 0.042973f, 2.210513f, 4.145302f, 1.601575f, 7.362316f, 0.044455f, 0.051944f, 0.047463f, 0.139045f, +0.083115f, 0.148331f, 0.181847f, 0.262968f, 0.065940f, 0.172877f, 0.216080f, 0.155793f, 3.654567f, 6.037786f, 4.776636f, 10.958761f, 0.238109f, 0.245115f, 0.458611f, 0.670525f, +0.000695f, 0.001115f, 0.000915f, 0.005025f, 0.000516f, 0.001216f, 0.001017f, 0.002785f, 0.238019f, 0.353645f, 0.187268f, 1.631419f, 0.003355f, 0.003106f, 0.003890f, 0.021598f, +0.000010f, 0.000032f, 0.000019f, 0.000106f, 0.000011f, 0.000049f, 0.000030f, 0.000083f, 0.005894f, 0.017143f, 0.006694f, 0.058429f, 0.000073f, 0.000133f, 0.000123f, 0.000683f, +0.000015f, 0.000047f, 0.000013f, 0.000142f, 0.000007f, 0.000034f, 0.000009f, 0.000052f, 0.009687f, 0.028299f, 0.004885f, 0.087754f, 0.000043f, 0.000078f, 0.000032f, 0.000363f, +0.000046f, 0.000127f, 0.000069f, 0.000392f, 0.000025f, 0.000104f, 0.000058f, 0.000164f, 0.013876f, 0.035714f, 0.012624f, 0.113177f, 0.000198f, 0.000317f, 0.000265f, 0.001516f, +0.021308f, 0.052793f, 0.058313f, 0.145664f, 0.024747f, 0.090072f, 0.101435f, 0.126331f, 4.164166f, 9.551099f, 6.807964f, 26.980241f, 0.050071f, 0.071559f, 0.120631f, 0.304662f, +0.000896f, 0.004348f, 0.003541f, 0.008863f, 0.001475f, 0.010513f, 0.008731f, 0.010895f, 0.297967f, 1.337966f, 0.703274f, 2.792455f, 0.003163f, 0.008849f, 0.011001f, 0.027837f, +0.000281f, 0.001368f, 0.000493f, 0.002538f, 0.000216f, 0.001548f, 0.000568f, 0.001459f, 0.104643f, 0.471922f, 0.109664f, 0.896114f, 0.000393f, 0.001104f, 0.000607f, 0.003160f, +0.000466f, 0.002002f, 0.001476f, 0.003795f, 0.000408f, 0.002571f, 0.001933f, 0.002477f, 0.081002f, 0.321833f, 0.153137f, 0.624524f, 0.000985f, 0.002439f, 0.002745f, 0.007134f, +0.000468f, 0.000431f, 0.000884f, 0.004949f, 0.000029f, 0.000040f, 0.000083f, 0.000232f, 0.054215f, 0.046290f, 0.061192f, 0.543551f, 0.000746f, 0.000397f, 0.001241f, 0.007026f, +0.000036f, 0.000066f, 0.000100f, 0.000558f, 0.000003f, 0.000009f, 0.000013f, 0.000037f, 0.007191f, 0.012020f, 0.011717f, 0.104283f, 0.000087f, 0.000091f, 0.000210f, 0.001190f, +0.000028f, 0.000050f, 0.000033f, 0.000386f, 0.000001f, 0.000003f, 0.000002f, 0.000012f, 0.006103f, 0.010246f, 0.004415f, 0.080870f, 0.000026f, 0.000027f, 0.000028f, 0.000326f, +0.000088f, 0.000140f, 0.000192f, 0.001106f, 0.000004f, 0.000010f, 0.000014f, 0.000039f, 0.009049f, 0.013383f, 0.011810f, 0.107954f, 0.000126f, 0.000116f, 0.000242f, 0.001412f, +0.000929f, 0.001804f, 0.002792f, 0.015371f, 0.010494f, 0.029936f, 0.047244f, 0.129674f, 0.811895f, 1.459488f, 1.457850f, 12.732915f, 0.001682f, 0.001884f, 0.004451f, 0.024773f, +0.000019f, 0.000072f, 0.000082f, 0.000451f, 0.000302f, 0.001686f, 0.001962f, 0.005395f, 0.028027f, 0.098636f, 0.072654f, 0.635784f, 0.000051f, 0.000112f, 0.000196f, 0.001092f, +0.000005f, 0.000020f, 0.000010f, 0.000112f, 0.000038f, 0.000215f, 0.000111f, 0.000626f, 0.008530f, 0.030151f, 0.009819f, 0.176820f, 0.000006f, 0.000012f, 0.000009f, 0.000107f, +0.000043f, 0.000145f, 0.000150f, 0.000849f, 0.000367f, 0.001813f, 0.001910f, 0.005394f, 0.033500f, 0.104317f, 0.069559f, 0.625187f, 0.000070f, 0.000136f, 0.000215f, 0.001231f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000002f, 0.000001f, 0.000014f, 0.000306f, 0.000856f, 0.000382f, 0.013040f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000012f, 0.000004f, 0.000135f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000010f, 0.000001f, 0.000101f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000030f, 0.000009f, 0.000311f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000026f, 0.000122f, 0.000114f, 0.001111f, 0.000325f, 0.002231f, 0.002117f, 0.010331f, 0.090163f, 0.389783f, 0.234174f, 3.635670f, 0.000035f, 0.000094f, 0.000133f, 0.001321f, +0.000000f, 0.000003f, 0.000002f, 0.000020f, 0.000006f, 0.000075f, 0.000053f, 0.000258f, 0.001869f, 0.015819f, 0.007008f, 0.109014f, 0.000001f, 0.000003f, 0.000004f, 0.000035f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000006f, 0.000002f, 0.000017f, 0.000328f, 0.002786f, 0.000546f, 0.017470f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000002f, 0.000001f, 0.000010f, 0.000002f, 0.000022f, 0.000014f, 0.000070f, 0.000603f, 0.004514f, 0.001810f, 0.028921f, 0.000000f, 0.000001f, 0.000001f, 0.000011f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000009f, 0.000010f, 0.000354f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000020f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000024f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.001531f, 0.002547f, 0.002257f, 0.025915f, 0.001427f, 0.003487f, 0.003150f, 0.018039f, 0.874254f, 1.346123f, 0.769712f, 14.023580f, 0.002304f, 0.002211f, 0.002990f, 0.034713f, +0.000043f, 0.000141f, 0.000092f, 0.001064f, 0.000057f, 0.000275f, 0.000183f, 0.001049f, 0.042192f, 0.127183f, 0.053627f, 0.978928f, 0.000098f, 0.000184f, 0.000184f, 0.002139f, +0.000012f, 0.000041f, 0.000012f, 0.000279f, 0.000008f, 0.000037f, 0.000011f, 0.000129f, 0.013562f, 0.041057f, 0.007654f, 0.287518f, 0.000011f, 0.000021f, 0.000009f, 0.000222f, +0.000047f, 0.000137f, 0.000081f, 0.000954f, 0.000033f, 0.000141f, 0.000085f, 0.000500f, 0.024040f, 0.064119f, 0.024475f, 0.458868f, 0.000064f, 0.000107f, 0.000096f, 0.001149f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000178f, 0.000426f, 0.000109f, 0.007754f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000008f, 0.000002f, 0.000112f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000007f, 0.000001f, 0.000089f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000010f, 0.000002f, 0.000123f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000038f, 0.000151f, 0.000081f, 0.001647f, 0.000039f, 0.000228f, 0.000124f, 0.001263f, 0.085318f, 0.315923f, 0.108650f, 3.518762f, 0.000042f, 0.000097f, 0.000079f, 0.001626f, +0.000001f, 0.000005f, 0.000002f, 0.000041f, 0.000001f, 0.000011f, 0.000004f, 0.000044f, 0.002473f, 0.017924f, 0.004546f, 0.147502f, 0.000001f, 0.000005f, 0.000003f, 0.000060f, +0.000000f, 0.000001f, 0.000000f, 0.000006f, 0.000000f, 0.000001f, 0.000000f, 0.000003f, 0.000458f, 0.003334f, 0.000374f, 0.024963f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, +0.000000f, 0.000001f, 0.000000f, 0.000010f, 0.000000f, 0.000001f, 0.000001f, 0.000006f, 0.000380f, 0.002438f, 0.000560f, 0.018653f, 0.000000f, 0.000001f, 0.000000f, 0.000009f, +0.000000f, 0.000001f, 0.000001f, 0.000027f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000537f, 0.000740f, 0.000472f, 0.034245f, 0.000000f, 0.000000f, 0.000000f, 0.000018f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000029f, 0.000078f, 0.000037f, 0.002661f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000013f, 0.000035f, 0.000007f, 0.001088f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000021f, 0.000049f, 0.000021f, 0.001558f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000206f, 0.000206f, 0.000297f, 0.004119f, 0.012421f, 0.018260f, 0.026743f, 0.185166f, 2.932469f, 2.716746f, 2.518379f, 55.485052f, 0.010225f, 0.005902f, 0.012940f, 0.181684f, +0.000008f, 0.000016f, 0.000017f, 0.000240f, 0.000709f, 0.002041f, 0.002204f, 0.015288f, 0.200889f, 0.364354f, 0.249064f, 5.497933f, 0.000618f, 0.000699f, 0.001130f, 0.015893f, +0.000001f, 0.000002f, 0.000001f, 0.000030f, 0.000046f, 0.000132f, 0.000063f, 0.000897f, 0.030909f, 0.056304f, 0.017015f, 0.772980f, 0.000034f, 0.000038f, 0.000027f, 0.000790f, +0.000005f, 0.000009f, 0.000009f, 0.000127f, 0.000242f, 0.000617f, 0.000603f, 0.004296f, 0.067488f, 0.108306f, 0.067021f, 1.519516f, 0.000238f, 0.000238f, 0.000348f, 0.005034f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000002f, 0.000003f, 0.000002f, 0.000061f, 0.003499f, 0.005050f, 0.002092f, 0.180066f, 0.000003f, 0.000002f, 0.000002f, 0.000129f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000050f, 0.000141f, 0.000043f, 0.003708f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000021f, 0.000059f, 0.000008f, 0.001406f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000039f, 0.000098f, 0.000027f, 0.002394f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, +0.000006f, 0.000013f, 0.000012f, 0.000285f, 0.000369f, 0.001304f, 0.001148f, 0.014132f, 0.311987f, 0.695101f, 0.387547f, 15.177824f, 0.000203f, 0.000282f, 0.000372f, 0.009279f, +0.000000f, 0.000001f, 0.000000f, 0.000010f, 0.000013f, 0.000087f, 0.000057f, 0.000701f, 0.012834f, 0.055981f, 0.023016f, 0.903126f, 0.000007f, 0.000020f, 0.000019f, 0.000487f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000003f, 0.000001f, 0.000024f, 0.001138f, 0.004985f, 0.000906f, 0.073165f, 0.000000f, 0.000001f, 0.000000f, 0.000014f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000007f, 0.000004f, 0.000053f, 0.001163f, 0.004489f, 0.001671f, 0.067341f, 0.000001f, 0.000002f, 0.000002f, 0.000042f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000124f, 0.000103f, 0.000107f, 0.009368f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000009f, 0.000015f, 0.000012f, 0.001033f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000003f, 0.000001f, 0.000202f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000006f, 0.000004f, 0.000357f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.596535f, 0.591870f, 1.054219f, 1.942625f, 0.503271f, 0.733544f, 1.332097f, 1.223855f, 29.205627f, 26.825310f, 30.833405f, 90.140684f, 1.162738f, 0.665446f, 1.808924f, 3.370164f, +0.047141f, 0.091567f, 0.120271f, 0.222050f, 0.056366f, 0.160839f, 0.215386f, 0.198265f, 3.925741f, 7.059129f, 5.983335f, 17.525716f, 0.137973f, 0.154588f, 0.309884f, 0.578446f, +0.021792f, 0.042513f, 0.024687f, 0.093797f, 0.012190f, 0.034935f, 0.020682f, 0.039180f, 2.033900f, 3.673173f, 1.376414f, 8.296937f, 0.025285f, 0.028453f, 0.025215f, 0.096865f, +0.055108f, 0.094714f, 0.112617f, 0.213552f, 0.034994f, 0.088355f, 0.107109f, 0.101265f, 2.397302f, 3.814282f, 2.926669f, 8.804693f, 0.096554f, 0.095722f, 0.173702f, 0.333025f, +0.000749f, 0.001158f, 0.000922f, 0.006636f, 0.000445f, 0.001010f, 0.000820f, 0.002943f, 0.253901f, 0.363304f, 0.186587f, 2.131500f, 0.002213f, 0.001973f, 0.002396f, 0.017444f, +0.000012f, 0.000037f, 0.000022f, 0.000158f, 0.000010f, 0.000046f, 0.000028f, 0.000099f, 0.007092f, 0.019866f, 0.007524f, 0.086115f, 0.000055f, 0.000095f, 0.000085f, 0.000622f, +0.000015f, 0.000047f, 0.000012f, 0.000180f, 0.000006f, 0.000027f, 0.000007f, 0.000053f, 0.009909f, 0.027877f, 0.004668f, 0.109943f, 0.000027f, 0.000047f, 0.000019f, 0.000281f, +0.000034f, 0.000090f, 0.000048f, 0.000354f, 0.000015f, 0.000059f, 0.000032f, 0.000118f, 0.010119f, 0.025082f, 0.008599f, 0.101090f, 0.000089f, 0.000138f, 0.000112f, 0.000837f, +0.025619f, 0.061130f, 0.065488f, 0.214510f, 0.023816f, 0.083479f, 0.091179f, 0.148908f, 4.953470f, 10.941667f, 7.564215f, 39.309171f, 0.036819f, 0.050676f, 0.082854f, 0.274394f, +0.001216f, 0.005679f, 0.004486f, 0.014724f, 0.001602f, 0.010992f, 0.008853f, 0.014486f, 0.399835f, 1.729042f, 0.881458f, 4.589490f, 0.002624f, 0.007069f, 0.008523f, 0.028282f, +0.000324f, 0.001519f, 0.000531f, 0.003584f, 0.000200f, 0.001376f, 0.000490f, 0.001649f, 0.119364f, 0.518419f, 0.116840f, 1.251963f, 0.000277f, 0.000750f, 0.000400f, 0.002729f, +0.000383f, 0.001585f, 0.001133f, 0.003820f, 0.000268f, 0.001629f, 0.001188f, 0.001996f, 0.065873f, 0.252053f, 0.116320f, 0.622053f, 0.000495f, 0.001181f, 0.001289f, 0.004393f, +0.001271f, 0.001129f, 0.002242f, 0.016464f, 0.000064f, 0.000083f, 0.000169f, 0.000617f, 0.145690f, 0.119797f, 0.153592f, 1.789021f, 0.001240f, 0.000635f, 0.001926f, 0.014294f, +0.000112f, 0.000194f, 0.000285f, 0.002095f, 0.000008f, 0.000020f, 0.000030f, 0.000111f, 0.021799f, 0.035091f, 0.033177f, 0.387184f, 0.000164f, 0.000164f, 0.000367f, 0.002731f, +0.000072f, 0.000126f, 0.000081f, 0.001232f, 0.000002f, 0.000006f, 0.000004f, 0.000031f, 0.015726f, 0.025426f, 0.010627f, 0.255235f, 0.000042f, 0.000042f, 0.000042f, 0.000637f, +0.000163f, 0.000251f, 0.000333f, 0.002516f, 0.000006f, 0.000014f, 0.000019f, 0.000071f, 0.016623f, 0.023678f, 0.020265f, 0.242909f, 0.000143f, 0.000127f, 0.000257f, 0.001963f, +0.000648f, 0.001211f, 0.001818f, 0.013123f, 0.005855f, 0.016085f, 0.024620f, 0.088612f, 0.559901f, 0.969306f, 0.939052f, 10.754886f, 0.000717f, 0.000773f, 0.001772f, 0.012935f, +0.000015f, 0.000054f, 0.000060f, 0.000435f, 0.000190f, 0.001022f, 0.001153f, 0.004159f, 0.021803f, 0.073897f, 0.052792f, 0.605784f, 0.000025f, 0.000052f, 0.000088f, 0.000643f, +0.000003f, 0.000013f, 0.000006f, 0.000092f, 0.000021f, 0.000111f, 0.000055f, 0.000410f, 0.005641f, 0.019202f, 0.006065f, 0.143215f, 0.000002f, 0.000005f, 0.000004f, 0.000054f, +0.000021f, 0.000067f, 0.000067f, 0.000496f, 0.000140f, 0.000666f, 0.000680f, 0.002520f, 0.015794f, 0.047364f, 0.030631f, 0.361009f, 0.000020f, 0.000038f, 0.000058f, 0.000439f, +0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000000f, 0.000001f, 0.000001f, 0.000010f, 0.000234f, 0.000632f, 0.000274f, 0.012245f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000010f, 0.000003f, 0.000143f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000007f, 0.000001f, 0.000091f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000015f, 0.000004f, 0.000200f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000023f, 0.000102f, 0.000092f, 0.001176f, 0.000225f, 0.001486f, 0.001368f, 0.008752f, 0.077084f, 0.320928f, 0.187000f, 3.807040f, 0.000018f, 0.000048f, 0.000066f, 0.000855f, +0.000000f, 0.000003f, 0.000002f, 0.000023f, 0.000004f, 0.000057f, 0.000038f, 0.000247f, 0.001803f, 0.014692f, 0.006313f, 0.128770f, 0.000000f, 0.000002f, 0.000002f, 0.000026f, +0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000000f, 0.000004f, 0.000001f, 0.000014f, 0.000269f, 0.002200f, 0.000418f, 0.017542f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.000000f, 0.000001f, 0.000001f, 0.000007f, 0.000001f, 0.000010f, 0.000006f, 0.000040f, 0.000352f, 0.002541f, 0.000988f, 0.020703f, 0.000000f, 0.000000f, 0.000000f, 0.000005f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000017f, 0.000018f, 0.000837f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000053f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000017f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000039f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +}; + +static const float acceptor_me2x3acc1[16384] = { +0.194114f, 0.254369f, 0.059224f, 0.479611f, 0.184195f, 0.431590f, 0.364757f, 0.677230f, 0.039156f, 0.074210f, 0.046061f, 0.142616f, 0.263375f, 0.540027f, 0.492918f, 0.741151f, +0.196628f, 0.370974f, 0.085338f, 0.772998f, 0.163797f, 0.552574f, 0.461409f, 0.958220f, 0.116240f, 0.317182f, 0.194511f, 0.673638f, 0.250918f, 0.740738f, 0.668017f, 1.123481f, +0.052415f, 0.117194f, 0.024461f, 0.180371f, 0.066584f, 0.266197f, 0.201679f, 0.340960f, 0.037786f, 0.122190f, 0.067988f, 0.191682f, 0.081306f, 0.284450f, 0.232751f, 0.318665f, +0.304223f, 0.440426f, 0.084923f, 0.930491f, 0.255470f, 0.661310f, 0.462862f, 1.162744f, 0.211373f, 0.442572f, 0.227494f, 0.953032f, 0.335322f, 0.759586f, 0.574182f, 1.168105f, +0.145656f, 0.232551f, 0.041391f, 0.372302f, 0.134074f, 0.382754f, 0.247288f, 0.509960f, 0.039260f, 0.090656f, 0.043015f, 0.147930f, 0.246315f, 0.615336f, 0.429361f, 0.717061f, +0.207366f, 0.476669f, 0.083824f, 0.843342f, 0.167569f, 0.688744f, 0.439648f, 1.014110f, 0.163806f, 0.544582f, 0.255300f, 0.982053f, 0.329812f, 1.186261f, 0.817813f, 1.527686f, +0.121829f, 0.331880f, 0.052954f, 0.433706f, 0.150127f, 0.731262f, 0.423528f, 0.795293f, 0.117358f, 0.462374f, 0.196672f, 0.615874f, 0.235539f, 1.003979f, 0.628002f, 0.955004f, +0.292668f, 0.516223f, 0.076092f, 0.926038f, 0.238406f, 0.751906f, 0.402310f, 1.122523f, 0.271717f, 0.693156f, 0.272375f, 1.267379f, 0.402058f, 1.109644f, 0.641221f, 1.448911f, +0.050828f, 0.081012f, 0.015369f, 0.126731f, 0.072420f, 0.206391f, 0.142132f, 0.268697f, 0.018783f, 0.043298f, 0.021898f, 0.069037f, 0.110917f, 0.276615f, 0.205733f, 0.314974f, +0.067112f, 0.154005f, 0.028867f, 0.266243f, 0.083945f, 0.344441f, 0.234358f, 0.495561f, 0.072683f, 0.241225f, 0.120539f, 0.425059f, 0.137740f, 0.494574f, 0.363432f, 0.622358f, +0.036190f, 0.098419f, 0.016738f, 0.125675f, 0.069030f, 0.335666f, 0.207222f, 0.356712f, 0.047796f, 0.187988f, 0.085231f, 0.244672f, 0.090289f, 0.384196f, 0.256158f, 0.357099f, +0.128070f, 0.225511f, 0.035431f, 0.395288f, 0.161483f, 0.508429f, 0.289965f, 0.741681f, 0.163015f, 0.415145f, 0.173882f, 0.741704f, 0.227034f, 0.625525f, 0.385289f, 0.798100f, +0.181327f, 0.197654f, 0.051343f, 0.382130f, 0.162262f, 0.316260f, 0.298206f, 0.508848f, 0.033636f, 0.053028f, 0.036721f, 0.104494f, 0.317780f, 0.542005f, 0.551954f, 0.762736f, +0.185977f, 0.291874f, 0.074909f, 0.623605f, 0.146101f, 0.409990f, 0.381952f, 0.728999f, 0.101106f, 0.229489f, 0.157014f, 0.499759f, 0.306545f, 0.752769f, 0.757400f, 1.170692f, +0.137800f, 0.256290f, 0.059681f, 0.404458f, 0.165079f, 0.548985f, 0.464044f, 0.721011f, 0.091354f, 0.245734f, 0.152547f, 0.395267f, 0.276097f, 0.803487f, 0.733508f, 0.922968f, +0.325774f, 0.392314f, 0.084396f, 0.849869f, 0.257985f, 0.555515f, 0.433793f, 1.001508f, 0.208150f, 0.362533f, 0.207909f, 0.800479f, 0.463802f, 0.873942f, 0.737048f, 1.378058f, +0.238641f, 0.435520f, 0.076985f, 0.625056f, 0.257179f, 0.839233f, 0.538490f, 1.002384f, 0.052200f, 0.137781f, 0.064927f, 0.201551f, 0.405784f, 1.158756f, 0.802996f, 1.210514f, +0.262777f, 0.690465f, 0.120588f, 1.095123f, 0.248610f, 1.168038f, 0.740484f, 1.541765f, 0.168456f, 0.640166f, 0.298051f, 1.034899f, 0.420250f, 1.727808f, 1.182990f, 1.994727f, +0.070265f, 0.218797f, 0.034671f, 0.256324f, 0.101372f, 0.564427f, 0.324660f, 0.550295f, 0.054929f, 0.247376f, 0.104501f, 0.295387f, 0.136596f, 0.665542f, 0.413450f, 0.567532f, +0.392706f, 0.791780f, 0.115909f, 1.273298f, 0.374527f, 1.350221f, 0.717486f, 1.807051f, 0.295878f, 0.862784f, 0.336706f, 1.414204f, 0.542464f, 1.711359f, 0.982147f, 2.003241f, +0.171132f, 0.380517f, 0.051419f, 0.463701f, 0.178902f, 0.711285f, 0.348891f, 0.721353f, 0.050020f, 0.160857f, 0.057946f, 0.199796f, 0.362680f, 1.261832f, 0.668458f, 1.119263f, +0.264845f, 0.847867f, 0.113199f, 1.141831f, 0.243062f, 1.391353f, 0.674291f, 1.559378f, 0.226868f, 1.050416f, 0.373861f, 1.441848f, 0.527905f, 2.644385f, 1.384080f, 2.592180f, +0.156080f, 0.592148f, 0.071731f, 0.589022f, 0.218435f, 1.481805f, 0.651574f, 1.226682f, 0.163040f, 0.894602f, 0.288896f, 0.907016f, 0.378173f, 2.244954f, 1.066121f, 1.625455f, +0.361048f, 0.886915f, 0.099254f, 1.211045f, 0.334021f, 1.467157f, 0.595986f, 1.667228f, 0.363489f, 1.291404f, 0.385267f, 1.797316f, 0.621599f, 2.389248f, 1.048209f, 2.374685f, +0.124872f, 0.277183f, 0.039924f, 0.330054f, 0.202063f, 0.801998f, 0.419312f, 0.794753f, 0.050040f, 0.160646f, 0.061684f, 0.194972f, 0.341499f, 1.186109f, 0.669754f, 1.028041f, +0.179231f, 0.572805f, 0.081515f, 0.753764f, 0.254610f, 1.454968f, 0.751591f, 1.593392f, 0.210491f, 0.972925f, 0.369102f, 1.304946f, 0.461008f, 2.305337f, 1.286143f, 2.208158f, +0.096950f, 0.367187f, 0.047411f, 0.356897f, 0.210019f, 1.422280f, 0.666616f, 1.150486f, 0.138845f, 0.760547f, 0.261792f, 0.753470f, 0.303124f, 1.796368f, 0.909311f, 1.270919f, +0.330366f, 0.810160f, 0.096639f, 1.080946f, 0.473089f, 2.074448f, 0.898216f, 2.303435f, 0.455997f, 1.617298f, 0.514289f, 2.199416f, 0.733960f, 2.816313f, 1.317000f, 2.735148f, +0.230008f, 0.349173f, 0.068862f, 0.513845f, 0.233756f, 0.634522f, 0.454236f, 0.777101f, 0.046267f, 0.101584f, 0.053407f, 0.152370f, 0.505171f, 1.199972f, 0.927753f, 1.285370f, +0.256445f, 0.560512f, 0.109216f, 0.911560f, 0.228800f, 0.894192f, 0.632455f, 1.210240f, 0.151180f, 0.477902f, 0.248243f, 0.792180f, 0.529737f, 1.811692f, 1.383917f, 2.144627f, +0.190599f, 0.493697f, 0.087282f, 0.593045f, 0.259318f, 1.201039f, 0.770759f, 1.200673f, 0.137021f, 0.513311f, 0.241925f, 0.628481f, 0.478594f, 1.939724f, 1.344399f, 1.696033f, +0.433894f, 0.727706f, 0.118853f, 1.199945f, 0.390238f, 1.170273f, 0.693802f, 1.605950f, 0.300629f, 0.729217f, 0.317501f, 1.225592f, 0.774163f, 2.031601f, 1.300811f, 2.438428f, +0.071432f, 0.135133f, 0.021986f, 0.200242f, 0.083200f, 0.281432f, 0.166209f, 0.347063f, 0.018481f, 0.050564f, 0.021931f, 0.076369f, 0.130629f, 0.386669f, 0.246630f, 0.417061f, +0.066959f, 0.182377f, 0.029317f, 0.298658f, 0.068467f, 0.333445f, 0.194567f, 0.454431f, 0.050770f, 0.199995f, 0.085705f, 0.333817f, 0.115167f, 0.490816f, 0.309307f, 0.585046f, +0.020121f, 0.064948f, 0.009473f, 0.078559f, 0.031374f, 0.181079f, 0.095868f, 0.182280f, 0.018605f, 0.086852f, 0.033770f, 0.107077f, 0.042068f, 0.212467f, 0.121486f, 0.187063f, +0.107373f, 0.224407f, 0.030237f, 0.372602f, 0.110675f, 0.413595f, 0.202288f, 0.571510f, 0.095684f, 0.289224f, 0.103888f, 0.489470f, 0.159512f, 0.521636f, 0.275543f, 0.630439f, +0.045260f, 0.104318f, 0.012975f, 0.131252f, 0.051137f, 0.210749f, 0.095147f, 0.220675f, 0.015647f, 0.052158f, 0.017294f, 0.066889f, 0.103157f, 0.372032f, 0.181400f, 0.340717f, +0.059628f, 0.197874f, 0.024316f, 0.275134f, 0.059144f, 0.350942f, 0.156542f, 0.406100f, 0.060413f, 0.289948f, 0.094985f, 0.410924f, 0.127822f, 0.663711f, 0.319743f, 0.671742f, +0.039491f, 0.155304f, 0.017316f, 0.159502f, 0.059732f, 0.420032f, 0.169996f, 0.359009f, 0.048791f, 0.277512f, 0.082486f, 0.290502f, 0.102904f, 0.633220f, 0.276783f, 0.473375f, +0.087222f, 0.222098f, 0.022877f, 0.313117f, 0.087211f, 0.397081f, 0.148465f, 0.465886f, 0.103860f, 0.382494f, 0.105029f, 0.549629f, 0.161497f, 0.643457f, 0.259831f, 0.660309f, +0.032530f, 0.074849f, 0.009923f, 0.092021f, 0.056891f, 0.234062f, 0.112637f, 0.239482f, 0.015418f, 0.051308f, 0.018133f, 0.064294f, 0.095675f, 0.344459f, 0.179025f, 0.308252f, +0.039747f, 0.131674f, 0.017247f, 0.178901f, 0.061025f, 0.361482f, 0.171870f, 0.408732f, 0.055211f, 0.264529f, 0.092369f, 0.366327f, 0.109950f, 0.569933f, 0.292660f, 0.563640f, +0.024162f, 0.094858f, 0.011273f, 0.095195f, 0.056569f, 0.397110f, 0.171312f, 0.331657f, 0.040927f, 0.232387f, 0.073625f, 0.237703f, 0.081245f, 0.499088f, 0.232531f, 0.364571f, +0.078612f, 0.199834f, 0.021940f, 0.275286f, 0.121668f, 0.553018f, 0.220395f, 0.634009f, 0.128338f, 0.471831f, 0.138099f, 0.662502f, 0.187828f, 0.747091f, 0.321562f, 0.749129f, +0.076356f, 0.120156f, 0.021811f, 0.182566f, 0.083869f, 0.235988f, 0.155493f, 0.298403f, 0.018167f, 0.041346f, 0.020007f, 0.064031f, 0.180357f, 0.444089f, 0.316022f, 0.491146f, +0.072472f, 0.164197f, 0.029448f, 0.275708f, 0.069883f, 0.283106f, 0.184304f, 0.395616f, 0.050533f, 0.165584f, 0.079167f, 0.283391f, 0.161002f, 0.570768f, 0.401301f, 0.697606f, +0.060533f, 0.162530f, 0.026448f, 0.201578f, 0.089010f, 0.427335f, 0.252415f, 0.441082f, 0.051470f, 0.199872f, 0.086704f, 0.252666f, 0.163467f, 0.686764f, 0.438108f, 0.619990f, +0.131572f, 0.228739f, 0.034386f, 0.389429f, 0.127893f, 0.397566f, 0.216942f, 0.563297f, 0.107823f, 0.271106f, 0.108646f, 0.470448f, 0.252468f, 0.686779f, 0.404742f, 0.851082f, +0.254579f, 0.420878f, 0.067651f, 0.623936f, 0.315714f, 0.933283f, 0.544539f, 1.151427f, 0.057210f, 0.136790f, 0.058615f, 0.206692f, 0.412654f, 1.067467f, 0.672662f, 1.151872f, +0.257672f, 0.613327f, 0.097404f, 1.004814f, 0.280530f, 1.193958f, 0.688285f, 1.627880f, 0.169700f, 0.584199f, 0.247332f, 0.975524f, 0.392826f, 1.463052f, 0.910890f, 1.744695f, +0.064821f, 0.182847f, 0.026347f, 0.221263f, 0.107616f, 0.542796f, 0.283909f, 0.546635f, 0.052059f, 0.212385f, 0.081584f, 0.261956f, 0.120124f, 0.530196f, 0.299506f, 0.467007f, +0.374581f, 0.684154f, 0.091073f, 1.136453f, 0.411096f, 1.342566f, 0.648732f, 1.855980f, 0.289940f, 0.765894f, 0.271793f, 1.296732f, 0.493245f, 1.409626f, 0.735631f, 1.704385f, +0.206179f, 0.415299f, 0.051031f, 0.522753f, 0.248034f, 0.893329f, 0.398454f, 0.935810f, 0.061912f, 0.180361f, 0.059081f, 0.231399f, 0.416536f, 1.312808f, 0.632404f, 1.202828f, +0.293298f, 0.850581f, 0.103264f, 1.183210f, 0.309753f, 1.606227f, 0.707844f, 1.859487f, 0.258111f, 1.082596f, 0.350378f, 1.534958f, 0.557296f, 2.528867f, 1.203603f, 2.560581f, +0.162615f, 0.558876f, 0.061562f, 0.574233f, 0.261889f, 1.609376f, 0.643503f, 1.376165f, 0.174511f, 0.867425f, 0.254721f, 0.908425f, 0.375593f, 2.019788f, 0.872219f, 1.510585f, +0.388937f, 0.865503f, 0.088075f, 1.220728f, 0.414067f, 1.647573f, 0.608591f, 1.933904f, 0.402276f, 1.294690f, 0.351225f, 1.861230f, 0.638321f, 2.222600f, 0.886684f, 2.281802f, +0.179228f, 0.360395f, 0.047203f, 0.443272f, 0.333742f, 1.199963f, 0.570496f, 1.228284f, 0.073786f, 0.214585f, 0.074925f, 0.269014f, 0.467245f, 1.470114f, 0.754853f, 1.316160f, +0.236460f, 0.684575f, 0.088588f, 0.930513f, 0.386546f, 2.001013f, 0.939937f, 2.263555f, 0.285295f, 1.194569f, 0.412097f, 1.654994f, 0.579782f, 2.626411f, 1.332411f, 2.598545f, +0.120333f, 0.412856f, 0.048475f, 0.414502f, 0.299972f, 1.840257f, 0.784314f, 1.537611f, 0.177047f, 0.878526f, 0.274983f, 0.899015f, 0.358653f, 1.925397f, 0.886255f, 1.407067f, +0.423972f, 0.941855f, 0.102162f, 1.298043f, 0.698661f, 2.775221f, 1.092689f, 3.183046f, 0.601203f, 1.931614f, 0.558546f, 2.713375f, 0.897900f, 3.121101f, 1.327191f, 3.130975f, +0.282684f, 0.388752f, 0.069716f, 0.590928f, 0.330601f, 0.812942f, 0.529194f, 1.028400f, 0.058419f, 0.116191f, 0.055548f, 0.180020f, 0.591850f, 1.273549f, 0.895361f, 1.409110f, +0.289705f, 0.573611f, 0.101635f, 0.963586f, 0.297440f, 1.053041f, 0.677275f, 1.472170f, 0.175458f, 0.502445f, 0.237327f, 0.860292f, 0.570474f, 1.767384f, 1.227658f, 2.161077f, +0.202572f, 0.475324f, 0.076415f, 0.589780f, 0.317157f, 1.330664f, 0.776517f, 1.374068f, 0.149611f, 0.507723f, 0.217595f, 0.642112f, 0.484886f, 1.780260f, 1.121999f, 1.607865f, +0.476809f, 0.724415f, 0.107588f, 1.233857f, 0.493482f, 1.340603f, 0.722720f, 1.900279f, 0.339398f, 0.745771f, 0.295267f, 1.294692f, 0.810973f, 1.927895f, 1.122484f, 2.390160f, +0.230052f, 0.301463f, 0.070189f, 0.568405f, 0.279227f, 0.654260f, 0.552945f, 1.026632f, 0.054683f, 0.103637f, 0.064326f, 0.199170f, 0.343024f, 0.703341f, 0.641985f, 0.965288f, +0.311947f, 0.588545f, 0.135388f, 1.226351f, 0.332394f, 1.121339f, 0.936339f, 1.944517f, 0.217310f, 0.592967f, 0.363636f, 1.259359f, 0.437472f, 1.291464f, 1.164676f, 1.958770f, +0.064795f, 0.144873f, 0.030238f, 0.222971f, 0.105284f, 0.420916f, 0.318900f, 0.539134f, 0.055043f, 0.177993f, 0.099038f, 0.279222f, 0.110456f, 0.386429f, 0.316195f, 0.432910f, +0.503707f, 0.729221f, 0.140608f, 1.540629f, 0.541048f, 1.400559f, 0.980274f, 2.462522f, 0.412404f, 0.863489f, 0.443856f, 1.859429f, 0.610140f, 1.382114f, 1.044761f, 2.125442f, +0.233699f, 0.373118f, 0.066410f, 0.597343f, 0.275159f, 0.785520f, 0.507505f, 1.046585f, 0.074228f, 0.171400f, 0.081327f, 0.279687f, 0.434310f, 1.084980f, 0.757062f, 1.264344f, +0.445382f, 1.023793f, 0.180038f, 1.811339f, 0.460361f, 1.892185f, 1.207844f, 2.786064f, 0.414584f, 1.378306f, 0.646148f, 2.485518f, 0.778474f, 2.799995f, 1.930329f, 3.605879f, +0.203889f, 0.555421f, 0.088621f, 0.725833f, 0.321374f, 1.565397f, 0.906639f, 1.702468f, 0.231441f, 0.911846f, 0.387856f, 1.214562f, 0.433197f, 1.846492f, 1.155005f, 1.756419f, +0.656025f, 1.157131f, 0.170563f, 2.075746f, 0.683553f, 2.155852f, 1.153497f, 3.218479f, 0.717708f, 1.830891f, 0.719448f, 3.347636f, 0.990409f, 2.733444f, 1.579553f, 3.569178f, +0.069707f, 0.111102f, 0.021078f, 0.173801f, 0.127039f, 0.362051f, 0.249328f, 0.471349f, 0.030355f, 0.069972f, 0.035389f, 0.111568f, 0.167166f, 0.416896f, 0.310067f, 0.474708f, +0.123207f, 0.282731f, 0.052996f, 0.488783f, 0.197125f, 0.808840f, 0.550336f, 1.163711f, 0.157238f, 0.521851f, 0.260766f, 0.919545f, 0.277894f, 0.997815f, 0.733233f, 1.255622f, +0.051770f, 0.140787f, 0.023944f, 0.179776f, 0.126308f, 0.614188f, 0.379166f, 0.652696f, 0.080568f, 0.316884f, 0.143671f, 0.412433f, 0.141938f, 0.603974f, 0.402692f, 0.561376f, +0.245377f, 0.432070f, 0.067885f, 0.757358f, 0.395753f, 1.246029f, 0.710630f, 1.817669f, 0.368045f, 0.937288f, 0.392580f, 1.674573f, 0.478035f, 1.317082f, 0.811251f, 1.680452f, +0.398167f, 0.434019f, 0.112742f, 0.839099f, 0.455751f, 0.888293f, 0.837584f, 1.429224f, 0.087036f, 0.137212f, 0.095018f, 0.270384f, 0.766850f, 1.307938f, 1.331945f, 1.840593f, +0.546677f, 0.857957f, 0.220194f, 1.833072f, 0.549330f, 1.541534f, 1.436115f, 2.740989f, 0.350212f, 0.794912f, 0.543870f, 1.731081f, 0.990251f, 2.431719f, 2.446676f, 3.781761f, +0.315620f, 0.587014f, 0.136695f, 0.926380f, 0.483636f, 1.608373f, 1.359520f, 2.112359f, 0.246565f, 0.663235f, 0.411724f, 1.066824f, 0.694959f, 2.022443f, 1.846298f, 2.323185f, +0.999393f, 1.203519f, 0.258907f, 2.607183f, 1.012334f, 2.179845f, 1.702206f, 3.929924f, 0.752460f, 1.310549f, 0.751587f, 2.893715f, 1.563627f, 2.946345f, 2.484830f, 4.645885f, +0.302687f, 0.552404f, 0.097646f, 0.792808f, 0.417248f, 1.361577f, 0.873649f, 1.626273f, 0.078021f, 0.205933f, 0.097042f, 0.301245f, 0.565622f, 1.615186f, 1.119294f, 1.687331f, +0.446174f, 1.172353f, 0.204749f, 1.859430f, 0.539939f, 2.536787f, 1.608210f, 3.348462f, 0.337046f, 1.280843f, 0.596340f, 2.070625f, 0.784162f, 3.223991f, 2.207391f, 3.722045f, +0.092961f, 0.289471f, 0.045870f, 0.339119f, 0.171551f, 0.955170f, 0.549417f, 0.931256f, 0.085635f, 0.385663f, 0.162918f, 0.460511f, 0.198602f, 0.967653f, 0.601129f, 0.825153f, +0.695880f, 1.403043f, 0.205392f, 2.256299f, 0.848907f, 3.060423f, 1.626261f, 4.095879f, 0.617825f, 1.801587f, 0.703078f, 2.953009f, 1.056377f, 3.332643f, 1.912601f, 3.901044f, +0.293859f, 0.653406f, 0.088294f, 0.796245f, 0.392947f, 1.562293f, 0.766316f, 1.584406f, 0.101213f, 0.325487f, 0.117252f, 0.404279f, 0.684406f, 2.381175f, 1.261432f, 2.112135f, +0.608792f, 1.948965f, 0.260207f, 2.624690f, 0.714667f, 4.090946f, 1.982592f, 4.584984f, 0.614519f, 2.845273f, 1.012682f, 3.905548f, 1.333562f, 6.680086f, 3.496379f, 6.548210f, +0.279556f, 1.060603f, 0.128478f, 1.055003f, 0.500443f, 3.394872f, 1.492779f, 2.810375f, 0.344114f, 1.888159f, 0.609748f, 1.914360f, 0.744378f, 4.418866f, 2.098505f, 3.199472f, +0.866144f, 2.127686f, 0.238107f, 2.905266f, 1.024967f, 4.502072f, 1.828825f, 5.116002f, 1.027552f, 3.650684f, 1.089114f, 5.080852f, 1.638767f, 6.298951f, 2.763470f, 6.260556f, +0.183280f, 0.406834f, 0.058598f, 0.484436f, 0.379356f, 1.505684f, 0.787223f, 1.492083f, 0.086547f, 0.277848f, 0.106687f, 0.337217f, 0.550835f, 1.913182f, 1.080307f, 1.658219f, +0.352153f, 1.125446f, 0.160161f, 1.480996f, 0.639888f, 3.656637f, 1.888903f, 4.004525f, 0.487347f, 2.252598f, 0.854577f, 3.021322f, 0.995423f, 4.977758f, 2.777081f, 4.767925f, +0.148426f, 0.562149f, 0.072585f, 0.546396f, 0.411276f, 2.785219f, 1.305419f, 2.252970f, 0.250485f, 1.372070f, 0.472288f, 1.359304f, 0.509995f, 3.022321f, 1.529882f, 2.138273f, +0.677428f, 1.661262f, 0.198162f, 2.216520f, 1.240854f, 5.441021f, 2.355908f, 6.041625f, 1.101834f, 3.907904f, 1.242686f, 5.314487f, 1.653946f, 6.346435f, 2.967800f, 6.163532f, +0.540536f, 0.820585f, 0.161831f, 1.207576f, 0.702677f, 1.907390f, 1.365445f, 2.335987f, 0.128128f, 0.281316f, 0.147900f, 0.421959f, 1.304676f, 3.099097f, 2.396054f, 3.319651f, +0.806761f, 1.763336f, 0.343588f, 2.867716f, 0.920696f, 3.598249f, 2.545013f, 4.870036f, 0.560444f, 1.771640f, 0.920267f, 2.936706f, 1.831439f, 6.263488f, 4.784557f, 7.414530f, +0.467216f, 1.210199f, 0.213955f, 1.453732f, 0.813092f, 3.765855f, 2.416712f, 3.764709f, 0.395796f, 1.482733f, 0.698818f, 1.815410f, 1.289275f, 5.225378f, 3.621645f, 4.568904f, +1.424570f, 2.389220f, 0.390220f, 3.939683f, 1.638853f, 4.914702f, 2.913708f, 6.744384f, 1.163102f, 2.821260f, 1.228377f, 4.741681f, 2.793276f, 7.330266f, 4.693484f, 8.798148f, +0.149690f, 0.283178f, 0.046073f, 0.419618f, 0.223014f, 0.754368f, 0.445516f, 0.930288f, 0.045636f, 0.124861f, 0.054156f, 0.188584f, 0.300829f, 0.890471f, 0.567972f, 0.960462f, +0.187836f, 0.511608f, 0.082240f, 0.837802f, 0.245673f, 1.196467f, 0.698144f, 1.630592f, 0.167827f, 0.661110f, 0.283307f, 1.103473f, 0.355038f, 1.513098f, 0.953538f, 1.803590f, +0.043981f, 0.141963f, 0.020706f, 0.171714f, 0.087720f, 0.506279f, 0.268038f, 0.509637f, 0.047920f, 0.223706f, 0.086981f, 0.275799f, 0.101052f, 0.510370f, 0.291823f, 0.449348f, +0.314349f, 0.656981f, 0.088522f, 1.090841f, 0.414454f, 1.548824f, 0.757524f, 2.140181f, 0.330098f, 0.997783f, 0.358402f, 1.688607f, 0.513206f, 1.678284f, 0.886516f, 2.028339f, +0.128401f, 0.295949f, 0.036809f, 0.372360f, 0.185567f, 0.764777f, 0.345276f, 0.800795f, 0.052308f, 0.174368f, 0.057815f, 0.223613f, 0.321616f, 1.159898f, 0.565559f, 1.062265f, +0.226451f, 0.751474f, 0.092345f, 1.044890f, 0.287308f, 1.704794f, 0.760444f, 1.972736f, 0.270359f, 1.297575f, 0.425077f, 1.838965f, 0.533474f, 2.770042f, 1.334469f, 2.803560f, +0.116860f, 0.459574f, 0.051241f, 0.471997f, 0.226095f, 1.589879f, 0.643461f, 1.358901f, 0.170137f, 0.967698f, 0.287632f, 1.012996f, 0.334647f, 2.059244f, 0.900103f, 1.539424f, +0.345700f, 0.880280f, 0.090672f, 1.241029f, 0.442138f, 2.013094f, 0.752678f, 2.361920f, 0.485078f, 1.786431f, 0.490536f, 2.567034f, 0.703430f, 2.802697f, 1.131744f, 2.876098f, +0.078882f, 0.181504f, 0.024062f, 0.223145f, 0.176462f, 0.726006f, 0.349374f, 0.742818f, 0.044057f, 0.146614f, 0.051816f, 0.183722f, 0.254965f, 0.917951f, 0.477085f, 0.821462f, +0.129024f, 0.427434f, 0.055987f, 0.580739f, 0.253386f, 1.500944f, 0.713638f, 1.697136f, 0.211192f, 1.011875f, 0.353330f, 1.401274f, 0.392232f, 2.033165f, 1.044030f, 2.010719f, +0.061114f, 0.239932f, 0.028515f, 0.240784f, 0.183023f, 1.284797f, 0.554257f, 1.073035f, 0.121987f, 0.692647f, 0.219446f, 0.708492f, 0.225836f, 1.387305f, 0.646361f, 1.013392f, +0.266322f, 0.676996f, 0.074328f, 0.932615f, 0.527233f, 2.396440f, 0.955059f, 2.747406f, 0.512340f, 1.883608f, 0.551307f, 2.644788f, 0.699294f, 2.781457f, 1.197189f, 2.789042f, +0.296466f, 0.466528f, 0.084684f, 0.708846f, 0.416528f, 1.172013f, 0.772240f, 1.481993f, 0.083117f, 0.189168f, 0.091539f, 0.292958f, 0.769569f, 1.894890f, 1.348439f, 2.095677f, +0.376679f, 0.853425f, 0.153057f, 1.433010f, 0.464602f, 1.882175f, 1.225305f, 2.630170f, 0.309498f, 1.014156f, 0.484874f, 1.735692f, 0.919631f, 3.260177f, 2.292199f, 3.984662f, +0.245153f, 0.658233f, 0.107110f, 0.816376f, 0.461102f, 2.213731f, 1.307591f, 2.284944f, 0.245634f, 0.953860f, 0.413782f, 1.205812f, 0.727544f, 3.056577f, 1.949885f, 2.759386f, +0.713696f, 1.240766f, 0.186522f, 2.112409f, 0.887377f, 2.758478f, 1.505234f, 3.908387f, 0.689202f, 1.732910f, 0.694464f, 3.007101f, 1.505006f, 4.094003f, 2.412734f, 5.073442f, +0.240658f, 0.397863f, 0.063952f, 0.589817f, 0.381752f, 1.128498f, 0.658440f, 1.392272f, 0.063728f, 0.152377f, 0.065294f, 0.230243f, 0.428692f, 1.108953f, 0.698804f, 1.196638f, +0.326071f, 0.776135f, 0.123260f, 1.271542f, 0.454082f, 1.932611f, 1.114099f, 2.634983f, 0.253054f, 0.871148f, 0.368817f, 1.454686f, 0.546295f, 2.034633f, 1.266754f, 2.426308f, +0.063915f, 0.180293f, 0.025979f, 0.218173f, 0.135731f, 0.684602f, 0.358080f, 0.689443f, 0.060489f, 0.246775f, 0.094794f, 0.304372f, 0.130167f, 0.574525f, 0.324547f, 0.506053f, +0.494698f, 0.903542f, 0.120277f, 1.500880f, 0.694461f, 2.267986f, 1.095898f, 3.135292f, 0.451221f, 1.191927f, 0.422979f, 2.018047f, 0.715877f, 2.045878f, 1.067668f, 2.473681f, +0.263865f, 0.531493f, 0.065308f, 0.669011f, 0.406030f, 1.462374f, 0.652266f, 1.531914f, 0.093368f, 0.271998f, 0.089099f, 0.348968f, 0.585828f, 1.846371f, 0.889431f, 1.691693f, +0.502474f, 1.457203f, 0.176911f, 2.027058f, 0.678782f, 3.519828f, 1.551143f, 4.074811f, 0.521072f, 2.185532f, 0.707338f, 3.098755f, 1.049232f, 4.761147f, 2.266047f, 4.820856f, +0.217075f, 0.746046f, 0.082179f, 0.766547f, 0.447175f, 2.748007f, 1.098781f, 2.349800f, 0.274512f, 1.364485f, 0.400683f, 1.428978f, 0.550996f, 2.963038f, 1.279550f, 2.216035f, +0.695398f, 1.547470f, 0.157473f, 2.182592f, 0.946967f, 3.767980f, 1.391840f, 4.422816f, 0.847548f, 2.727759f, 0.739990f, 3.921392f, 1.254221f, 4.367132f, 1.742223f, 4.483457f, +0.196058f, 0.394238f, 0.051635f, 0.484897f, 0.466981f, 1.679023f, 0.798254f, 1.718651f, 0.095113f, 0.276608f, 0.096580f, 0.346769f, 0.561700f, 1.767303f, 0.907450f, 1.582226f, +0.346261f, 1.002461f, 0.129724f, 1.362601f, 0.724032f, 3.748058f, 1.760577f, 4.239820f, 0.492296f, 2.061312f, 0.711102f, 2.855807f, 0.933024f, 4.226590f, 2.144202f, 4.181747f, +0.137302f, 0.471076f, 0.055310f, 0.472954f, 0.437808f, 2.685844f, 1.144701f, 2.244134f, 0.238050f, 1.181227f, 0.369730f, 1.208775f, 0.449726f, 2.414314f, 1.111302f, 1.764364f, +0.647938f, 1.439394f, 0.156129f, 1.983741f, 1.365754f, 5.425046f, 2.136005f, 6.222269f, 1.082688f, 3.478584f, 1.005868f, 4.886432f, 1.508013f, 5.241852f, 2.229002f, 5.258436f, +0.495123f, 0.680900f, 0.122108f, 1.035013f, 0.740671f, 1.821296f, 1.185594f, 2.304004f, 0.120572f, 0.239812f, 0.114648f, 0.371551f, 1.139211f, 2.451365f, 1.723417f, 2.712297f, +0.679258f, 1.344919f, 0.238298f, 2.259276f, 0.892047f, 3.158159f, 2.031204f, 4.415164f, 0.484774f, 1.388206f, 0.655712f, 2.376899f, 1.469927f, 4.553977f, 3.163277f, 5.568397f, +0.370088f, 0.868390f, 0.139605f, 1.077493f, 0.741154f, 3.109590f, 1.814619f, 3.211020f, 0.322088f, 1.093045f, 0.468446f, 1.382363f, 0.973522f, 3.574285f, 2.252673f, 3.228163f, +1.166735f, 1.772621f, 0.263263f, 3.019208f, 1.544579f, 4.196029f, 2.262081f, 5.947790f, 0.978641f, 2.150404f, 0.851391f, 3.733199f, 2.180799f, 5.184333f, 3.018487f, 6.427416f, +0.071176f, 0.093269f, 0.021716f, 0.175859f, 0.080048f, 0.187560f, 0.158516f, 0.294310f, 0.015816f, 0.029975f, 0.018605f, 0.057606f, 0.105376f, 0.216063f, 0.197215f, 0.296532f, +0.099120f, 0.187009f, 0.043019f, 0.389670f, 0.097863f, 0.330144f, 0.275676f, 0.572503f, 0.064550f, 0.176137f, 0.108016f, 0.374084f, 0.138020f, 0.407449f, 0.367448f, 0.617980f, +0.024064f, 0.053803f, 0.011230f, 0.082808f, 0.036230f, 0.144844f, 0.109739f, 0.185525f, 0.019110f, 0.061796f, 0.034384f, 0.096941f, 0.040730f, 0.142495f, 0.116597f, 0.159635f, +0.141717f, 0.205166f, 0.039560f, 0.433455f, 0.141047f, 0.365116f, 0.255551f, 0.641962f, 0.108469f, 0.227112f, 0.116741f, 0.489060f, 0.170445f, 0.386099f, 0.291858f, 0.593750f, +0.073057f, 0.116640f, 0.020760f, 0.186735f, 0.079702f, 0.227533f, 0.147003f, 0.303152f, 0.021692f, 0.050090f, 0.023767f, 0.081736f, 0.134807f, 0.336770f, 0.234987f, 0.392443f, +0.142992f, 0.328693f, 0.057802f, 0.581538f, 0.136950f, 0.562893f, 0.359313f, 0.828807f, 0.124431f, 0.413677f, 0.193932f, 0.745990f, 0.248160f, 0.892575f, 0.615345f, 1.149473f, +0.076509f, 0.208421f, 0.033255f, 0.272367f, 0.111741f, 0.544286f, 0.315237f, 0.591945f, 0.081189f, 0.319873f, 0.136059f, 0.426065f, 0.161404f, 0.687978f, 0.430340f, 0.654418f, +0.186493f, 0.328946f, 0.048487f, 0.590087f, 0.180052f, 0.567864f, 0.303838f, 0.847766f, 0.190733f, 0.486566f, 0.191196f, 0.889646f, 0.279554f, 0.771544f, 0.445846f, 1.007440f, +0.023719f, 0.037804f, 0.007172f, 0.059138f, 0.040053f, 0.114148f, 0.078609f, 0.148608f, 0.009656f, 0.022258f, 0.011257f, 0.035489f, 0.056477f, 0.140848f, 0.104756f, 0.160380f, +0.043055f, 0.098802f, 0.018520f, 0.170808f, 0.063829f, 0.261901f, 0.178198f, 0.376808f, 0.051367f, 0.170481f, 0.085188f, 0.300401f, 0.096423f, 0.346218f, 0.254415f, 0.435671f, +0.021145f, 0.057503f, 0.009780f, 0.073428f, 0.047802f, 0.232443f, 0.143498f, 0.247016f, 0.030763f, 0.120995f, 0.054858f, 0.157479f, 0.057562f, 0.244939f, 0.163310f, 0.227664f, +0.075926f, 0.133693f, 0.021005f, 0.234345f, 0.113465f, 0.357245f, 0.203742f, 0.521138f, 0.106462f, 0.271122f, 0.113559f, 0.484391f, 0.146867f, 0.404647f, 0.249240f, 0.516285f, +0.106184f, 0.115745f, 0.030066f, 0.223773f, 0.112618f, 0.219500f, 0.206970f, 0.353166f, 0.021698f, 0.034208f, 0.023688f, 0.067408f, 0.203055f, 0.346330f, 0.352687f, 0.487373f, +0.149727f, 0.234983f, 0.060308f, 0.502054f, 0.139408f, 0.391208f, 0.364455f, 0.695603f, 0.089668f, 0.203529f, 0.139252f, 0.443226f, 0.269293f, 0.661291f, 0.665359f, 1.028427f, +0.101036f, 0.187914f, 0.043758f, 0.296551f, 0.143454f, 0.477068f, 0.403255f, 0.626559f, 0.073787f, 0.198479f, 0.123212f, 0.319257f, 0.220891f, 0.642829f, 0.586842f, 0.738419f, +0.242365f, 0.291868f, 0.062788f, 0.632274f, 0.227479f, 0.489827f, 0.382498f, 0.883083f, 0.170590f, 0.297115f, 0.170392f, 0.656035f, 0.376509f, 0.709457f, 0.598328f, 1.118693f, +0.082246f, 0.150100f, 0.026533f, 0.215423f, 0.105051f, 0.342807f, 0.219960f, 0.409450f, 0.019818f, 0.052310f, 0.024650f, 0.076521f, 0.152601f, 0.435767f, 0.301979f, 0.455232f, +0.124510f, 0.327158f, 0.057137f, 0.518895f, 0.139614f, 0.655945f, 0.415840f, 0.865822f, 0.087928f, 0.334143f, 0.155572f, 0.540180f, 0.217277f, 0.893310f, 0.611628f, 1.031312f, +0.030321f, 0.094416f, 0.014961f, 0.110609f, 0.051846f, 0.288671f, 0.166045f, 0.281444f, 0.026111f, 0.117594f, 0.049676f, 0.140416f, 0.064318f, 0.313377f, 0.194678f, 0.267228f, +0.171948f, 0.346684f, 0.050751f, 0.557518f, 0.194360f, 0.700693f, 0.372337f, 0.937764f, 0.142714f, 0.416155f, 0.162407f, 0.682126f, 0.259173f, 0.817636f, 0.469241f, 0.957089f, +0.080679f, 0.179392f, 0.024241f, 0.218608f, 0.099963f, 0.397435f, 0.194945f, 0.403060f, 0.025977f, 0.083539f, 0.030094f, 0.103762f, 0.186570f, 0.649113f, 0.343869f, 0.575772f, +0.171658f, 0.549541f, 0.073369f, 0.740072f, 0.186717f, 1.068817f, 0.517980f, 1.197892f, 0.161983f, 0.749993f, 0.266935f, 1.029474f, 0.373352f, 1.870195f, 0.978866f, 1.833274f, +0.092131f, 0.349533f, 0.042341f, 0.347688f, 0.152818f, 1.036675f, 0.455843f, 0.858191f, 0.106017f, 0.581717f, 0.187855f, 0.589789f, 0.243578f, 1.445957f, 0.686680f, 1.046942f, +0.216247f, 0.531211f, 0.059447f, 0.725345f, 0.237112f, 1.041490f, 0.423073f, 1.183514f, 0.239828f, 0.852061f, 0.254197f, 1.185859f, 0.406242f, 1.561479f, 0.685051f, 1.551961f, +0.054771f, 0.121576f, 0.017511f, 0.144767f, 0.105042f, 0.416917f, 0.217979f, 0.413151f, 0.024178f, 0.077620f, 0.029804f, 0.094206f, 0.163442f, 0.567672f, 0.320544f, 0.492020f, +0.108079f, 0.345408f, 0.049155f, 0.454529f, 0.181969f, 1.039858f, 0.537158f, 1.138789f, 0.139825f, 0.646293f, 0.245187f, 0.866847f, 0.303337f, 1.516879f, 0.846264f, 1.452937f, +0.053242f, 0.201651f, 0.026037f, 0.196000f, 0.136699f, 0.925745f, 0.433892f, 0.748837f, 0.083998f, 0.460110f, 0.158377f, 0.455829f, 0.181645f, 1.076459f, 0.544898f, 0.761588f, +0.184092f, 0.451450f, 0.053851f, 0.602342f, 0.312447f, 1.370047f, 0.593217f, 1.521279f, 0.279914f, 0.992779f, 0.315697f, 1.350113f, 0.446274f, 1.712419f, 0.800783f, 1.663068f, +0.126601f, 0.192192f, 0.037903f, 0.282830f, 0.152493f, 0.413938f, 0.296326f, 0.506951f, 0.028054f, 0.061595f, 0.032383f, 0.092389f, 0.303405f, 0.720702f, 0.557208f, 0.771992f, +0.194058f, 0.424153f, 0.082647f, 0.689801f, 0.205205f, 0.801978f, 0.567233f, 1.085434f, 0.126025f, 0.398383f, 0.206937f, 0.660367f, 0.437410f, 1.495935f, 1.142716f, 1.770843f, +0.131355f, 0.340239f, 0.060152f, 0.408707f, 0.211812f, 0.981013f, 0.629559f, 0.980714f, 0.104025f, 0.389698f, 0.183666f, 0.477133f, 0.359900f, 1.458660f, 1.010979f, 1.275406f, +0.303413f, 0.508870f, 0.083111f, 0.839097f, 0.323426f, 0.969911f, 0.575017f, 1.330996f, 0.231583f, 0.561735f, 0.244579f, 0.944105f, 0.590709f, 1.550170f, 0.992556f, 1.860591f, +0.049383f, 0.093420f, 0.015199f, 0.138431f, 0.068170f, 0.230594f, 0.136185f, 0.284369f, 0.014074f, 0.038507f, 0.016702f, 0.058160f, 0.098539f, 0.291682f, 0.186044f, 0.314608f, +0.063641f, 0.173338f, 0.027864f, 0.283856f, 0.077126f, 0.375614f, 0.219172f, 0.511901f, 0.053157f, 0.209396f, 0.089733f, 0.349507f, 0.119438f, 0.509018f, 0.320778f, 0.606742f, +0.017417f, 0.056218f, 0.008199f, 0.067999f, 0.032187f, 0.185768f, 0.098351f, 0.187000f, 0.017740f, 0.082816f, 0.032200f, 0.102100f, 0.039733f, 0.200674f, 0.114743f, 0.176681f, +0.094305f, 0.197094f, 0.026557f, 0.327252f, 0.115208f, 0.430532f, 0.210572f, 0.594914f, 0.092576f, 0.279830f, 0.100514f, 0.473572f, 0.152869f, 0.499913f, 0.264068f, 0.604185f, +0.042800f, 0.098649f, 0.012270f, 0.124120f, 0.057314f, 0.236209f, 0.106642f, 0.247333f, 0.016300f, 0.054335f, 0.018016f, 0.069681f, 0.106445f, 0.383889f, 0.187182f, 0.351576f, +0.077523f, 0.257257f, 0.031613f, 0.357704f, 0.091135f, 0.540766f, 0.241215f, 0.625758f, 0.086523f, 0.415263f, 0.136037f, 0.588524f, 0.181333f, 0.941562f, 0.453598f, 0.952955f, +0.046758f, 0.183886f, 0.020503f, 0.188857f, 0.083824f, 0.589442f, 0.238561f, 0.503808f, 0.063640f, 0.361968f, 0.107589f, 0.378912f, 0.132950f, 0.818107f, 0.357598f, 0.611590f, +0.104789f, 0.266832f, 0.027484f, 0.376183f, 0.124182f, 0.565411f, 0.211402f, 0.663385f, 0.137457f, 0.506221f, 0.139003f, 0.727421f, 0.211713f, 0.843532f, 0.340623f, 0.865624f, +0.028620f, 0.065853f, 0.008730f, 0.080961f, 0.059323f, 0.244070f, 0.117453f, 0.249722f, 0.014943f, 0.049728f, 0.017575f, 0.062314f, 0.091850f, 0.330688f, 0.171868f, 0.295928f, +0.048077f, 0.159270f, 0.020862f, 0.216395f, 0.087485f, 0.518220f, 0.246393f, 0.585958f, 0.073567f, 0.352477f, 0.123079f, 0.488120f, 0.145117f, 0.752225f, 0.386267f, 0.743920f, +0.026616f, 0.104495f, 0.012419f, 0.104866f, 0.073857f, 0.518471f, 0.223666f, 0.433015f, 0.049666f, 0.282004f, 0.089345f, 0.288455f, 0.097658f, 0.599911f, 0.279505f, 0.438220f, +0.087869f, 0.223365f, 0.024524f, 0.307703f, 0.161182f, 0.732621f, 0.291973f, 0.839916f, 0.158025f, 0.580974f, 0.170044f, 0.815751f, 0.229086f, 0.911193f, 0.392194f, 0.913678f, +0.084303f, 0.132662f, 0.024081f, 0.201568f, 0.109748f, 0.308806f, 0.203473f, 0.390480f, 0.022095f, 0.050287f, 0.024334f, 0.077878f, 0.217283f, 0.535011f, 0.380723f, 0.591701f, +0.110006f, 0.249236f, 0.044699f, 0.418499f, 0.125722f, 0.509318f, 0.331569f, 0.711726f, 0.084497f, 0.276877f, 0.132377f, 0.473866f, 0.266666f, 0.945356f, 0.664671f, 1.155436f, +0.083680f, 0.224680f, 0.036561f, 0.278660f, 0.145837f, 0.700154f, 0.413562f, 0.722677f, 0.078381f, 0.304374f, 0.132036f, 0.384771f, 0.246577f, 1.035927f, 0.660850f, 0.935204f, +0.184553f, 0.320847f, 0.048232f, 0.546244f, 0.212618f, 0.660940f, 0.360658f, 0.936461f, 0.166607f, 0.418911f, 0.167879f, 0.726932f, 0.386416f, 1.051152f, 0.619479f, 1.302627f, +0.082191f, 0.135880f, 0.021841f, 0.201437f, 0.120806f, 0.357114f, 0.208364f, 0.440586f, 0.020347f, 0.048650f, 0.020847f, 0.073510f, 0.145371f, 0.376049f, 0.236966f, 0.405783f, +0.114369f, 0.272230f, 0.043233f, 0.445994f, 0.147576f, 0.628097f, 0.362081f, 0.856367f, 0.082975f, 0.285646f, 0.120933f, 0.476986f, 0.190254f, 0.708587f, 0.441164f, 0.844993f, +0.026203f, 0.073913f, 0.010650f, 0.089441f, 0.051559f, 0.260052f, 0.136020f, 0.261891f, 0.023182f, 0.094575f, 0.036329f, 0.116649f, 0.052984f, 0.233860f, 0.132107f, 0.205988f, +0.153639f, 0.280614f, 0.037355f, 0.466130f, 0.199845f, 0.652658f, 0.315366f, 0.902242f, 0.131005f, 0.346058f, 0.122805f, 0.585909f, 0.220754f, 0.630885f, 0.329235f, 0.762806f, +0.091054f, 0.183407f, 0.022537f, 0.230862f, 0.129826f, 0.467585f, 0.208558f, 0.489820f, 0.030120f, 0.087745f, 0.028743f, 0.112575f, 0.200723f, 0.632626f, 0.304747f, 0.579628f, +0.178077f, 0.516434f, 0.062697f, 0.718391f, 0.222899f, 1.155846f, 0.509367f, 1.338092f, 0.172635f, 0.724085f, 0.234347f, 1.026643f, 0.369212f, 1.675388f, 0.797393f, 1.696398f, +0.089918f, 0.309030f, 0.034041f, 0.317522f, 0.171631f, 1.054718f, 0.421725f, 0.901881f, 0.106300f, 0.528373f, 0.155158f, 0.553347f, 0.226617f, 1.218655f, 0.526260f, 0.911423f, +0.218218f, 0.485602f, 0.049416f, 0.684905f, 0.275345f, 1.095596f, 0.404698f, 1.285999f, 0.248633f, 0.800205f, 0.217081f, 1.150365f, 0.390788f, 1.360702f, 0.542838f, 1.396947f, +0.073640f, 0.148078f, 0.019394f, 0.182129f, 0.162523f, 0.584348f, 0.277815f, 0.598140f, 0.033397f, 0.097126f, 0.033912f, 0.121761f, 0.209481f, 0.659099f, 0.338425f, 0.590077f, +0.133571f, 0.386700f, 0.050041f, 0.525625f, 0.258791f, 1.339668f, 0.629283f, 1.515439f, 0.177530f, 0.743341f, 0.256435f, 1.029849f, 0.357362f, 1.618849f, 0.821262f, 1.601673f, +0.061905f, 0.212392f, 0.024938f, 0.213239f, 0.182900f, 1.122048f, 0.478215f, 0.937518f, 0.100335f, 0.497872f, 0.155836f, 0.509483f, 0.201328f, 1.080811f, 0.497494f, 0.789849f, +0.221311f, 0.491643f, 0.053328f, 0.677572f, 0.432242f, 1.716949f, 0.676015f, 1.969259f, 0.345709f, 1.110734f, 0.321180f, 1.560269f, 0.511428f, 1.777723f, 0.755944f, 1.783347f, +0.145755f, 0.200444f, 0.035946f, 0.304689f, 0.202032f, 0.496792f, 0.323393f, 0.628460f, 0.033182f, 0.065996f, 0.031551f, 0.102251f, 0.332984f, 0.716518f, 0.503744f, 0.792787f, +0.205363f, 0.406614f, 0.072046f, 0.683055f, 0.249895f, 0.884717f, 0.569015f, 1.236851f, 0.137014f, 0.392354f, 0.185326f, 0.671792f, 0.441257f, 1.367056f, 0.949582f, 1.671574f, +0.130777f, 0.306860f, 0.049332f, 0.380751f, 0.242671f, 1.018154f, 0.594149f, 1.051364f, 0.106399f, 0.361079f, 0.154748f, 0.456652f, 0.341571f, 1.254078f, 0.790376f, 1.132637f, +0.312336f, 0.474532f, 0.070476f, 0.808244f, 0.383128f, 1.040811f, 0.561102f, 1.475330f, 0.244912f, 0.538155f, 0.213067f, 0.934261f, 0.579661f, 1.378007f, 0.802321f, 1.708422f, +0.232215f, 0.304297f, 0.070849f, 0.573750f, 0.280382f, 0.656966f, 0.555233f, 1.030879f, 0.047375f, 0.089786f, 0.055729f, 0.172552f, 0.306063f, 0.627554f, 0.572810f, 0.861276f, +0.364753f, 0.688174f, 0.158306f, 1.433946f, 0.386634f, 1.304318f, 1.089130f, 2.261821f, 0.218086f, 0.595086f, 0.364935f, 1.263859f, 0.452157f, 1.334816f, 1.203772f, 2.024522f, +0.079495f, 0.177742f, 0.037098f, 0.273559f, 0.128497f, 0.513719f, 0.389211f, 0.658003f, 0.057961f, 0.187429f, 0.104288f, 0.294024f, 0.119788f, 0.419076f, 0.342909f, 0.469484f, +0.515465f, 0.746243f, 0.143890f, 1.576591f, 0.550788f, 1.425774f, 0.997923f, 2.506857f, 0.362222f, 0.758418f, 0.389847f, 1.633171f, 0.551914f, 1.250218f, 0.945059f, 1.922610f, +0.186872f, 0.298355f, 0.053103f, 0.477652f, 0.218877f, 0.624846f, 0.403698f, 0.832512f, 0.050943f, 0.117633f, 0.055815f, 0.191951f, 0.306978f, 0.766885f, 0.535106f, 0.893663f, +0.412547f, 0.948317f, 0.166765f, 1.677803f, 0.424198f, 1.743546f, 1.112962f, 2.567206f, 0.329598f, 1.095766f, 0.513694f, 1.976010f, 0.637391f, 2.292554f, 1.580496f, 2.952388f, +0.198162f, 0.539819f, 0.086132f, 0.705444f, 0.310717f, 1.513487f, 0.876574f, 1.646012f, 0.193062f, 0.760638f, 0.323540f, 1.013156f, 0.372162f, 1.586332f, 0.992272f, 1.508950f, +0.531820f, 0.938052f, 0.138270f, 1.682746f, 0.551245f, 1.738567f, 0.930227f, 2.595513f, 0.499370f, 1.273907f, 0.500581f, 2.329235f, 0.709708f, 1.958733f, 1.131877f, 2.557604f, +0.040615f, 0.064734f, 0.012281f, 0.101267f, 0.073634f, 0.209851f, 0.144515f, 0.273202f, 0.015180f, 0.034992f, 0.017697f, 0.055794f, 0.086096f, 0.214715f, 0.159695f, 0.244490f, +0.083158f, 0.190828f, 0.035769f, 0.329901f, 0.132354f, 0.543073f, 0.369508f, 0.781342f, 0.091087f, 0.302304f, 0.151060f, 0.532686f, 0.165794f, 0.595303f, 0.437452f, 0.749113f, +0.036663f, 0.099704f, 0.016957f, 0.127316f, 0.088984f, 0.432695f, 0.267122f, 0.459824f, 0.048972f, 0.192612f, 0.087327f, 0.250690f, 0.088853f, 0.378086f, 0.252084f, 0.351420f, +0.144946f, 0.255226f, 0.040100f, 0.447375f, 0.232553f, 0.732195f, 0.417582f, 1.068103f, 0.186596f, 0.475198f, 0.199035f, 0.848995f, 0.249604f, 0.687708f, 0.423591f, 0.877439f, +0.339413f, 0.369974f, 0.096106f, 0.715280f, 0.386473f, 0.753265f, 0.710264f, 1.211969f, 0.063678f, 0.100389f, 0.069518f, 0.197822f, 0.577822f, 0.985533f, 1.003622f, 1.386889f, +0.539818f, 0.847192f, 0.217432f, 1.810073f, 0.539608f, 1.514251f, 1.410698f, 2.692478f, 0.296810f, 0.673700f, 0.460938f, 1.467117f, 0.864336f, 2.122515f, 2.135570f, 3.300893f, +0.327014f, 0.608204f, 0.141629f, 0.959821f, 0.498480f, 1.657738f, 1.401248f, 2.177194f, 0.219262f, 0.589793f, 0.366132f, 0.948691f, 0.636475f, 1.852244f, 1.690923f, 2.127677f, +0.863685f, 1.040094f, 0.223750f, 2.253154f, 0.870305f, 1.874017f, 1.463389f, 3.378562f, 0.558128f, 0.972084f, 0.557480f, 2.146378f, 1.194465f, 2.250733f, 1.898178f, 3.549023f, +0.217452f, 0.396849f, 0.070150f, 0.569557f, 0.298189f, 0.973059f, 0.624358f, 1.162226f, 0.048107f, 0.126977f, 0.059836f, 0.185746f, 0.359183f, 1.025681f, 0.710777f, 1.071495f, +0.371301f, 0.975620f, 0.170390f, 1.547399f, 0.446988f, 2.100075f, 1.331354f, 2.772019f, 0.240736f, 0.914849f, 0.425939f, 1.478954f, 0.576832f, 2.371577f, 1.623763f, 2.737947f, +0.081172f, 0.252762f, 0.040053f, 0.296114f, 0.149014f, 0.829690f, 0.477240f, 0.808917f, 0.064179f, 0.289032f, 0.122097f, 0.345126f, 0.153289f, 0.746874f, 0.463976f, 0.636887f, +0.506827f, 1.021872f, 0.149592f, 1.643319f, 0.615055f, 2.217354f, 1.178267f, 2.967568f, 0.386209f, 1.126189f, 0.439501f, 1.845955f, 0.680088f, 2.145532f, 1.231319f, 2.511465f, +0.167236f, 0.371856f, 0.050249f, 0.453147f, 0.222461f, 0.884469f, 0.433839f, 0.896988f, 0.049438f, 0.158985f, 0.057272f, 0.197471f, 0.344292f, 1.197855f, 0.634566f, 1.062514f, +0.401342f, 1.284841f, 0.171539f, 1.730309f, 0.468681f, 2.682858f, 1.300191f, 3.006850f, 0.347706f, 1.609905f, 0.572993f, 2.209828f, 0.777105f, 3.892679f, 2.037441f, 3.815831f, +0.193374f, 0.733640f, 0.088871f, 0.729766f, 0.344360f, 2.336048f, 1.027198f, 1.933850f, 0.204297f, 1.120984f, 0.362002f, 1.136539f, 0.455139f, 2.701854f, 1.283101f, 1.956272f, +0.499734f, 1.227598f, 0.137379f, 1.676233f, 0.588284f, 2.583980f, 1.049661f, 2.936348f, 0.508842f, 1.807813f, 0.539328f, 2.516030f, 0.835770f, 3.212459f, 1.409367f, 3.192878f, +0.076003f, 0.168708f, 0.024300f, 0.200888f, 0.156493f, 0.621127f, 0.324746f, 0.615516f, 0.030804f, 0.098891f, 0.037972f, 0.120021f, 0.201911f, 0.701286f, 0.395992f, 0.607828f, +0.169162f, 0.540625f, 0.076936f, 0.711419f, 0.305777f, 1.747358f, 0.902630f, 1.913599f, 0.200928f, 0.928723f, 0.352333f, 1.245660f, 0.422669f, 2.113617f, 1.179183f, 2.024520f, +0.074811f, 0.283340f, 0.036585f, 0.275400f, 0.206214f, 1.396509f, 0.654537f, 1.129640f, 0.108360f, 0.593558f, 0.204312f, 0.588035f, 0.227218f, 1.346535f, 0.681608f, 0.952665f, +0.284799f, 0.698414f, 0.083310f, 0.931850f, 0.518948f, 2.275533f, 0.985284f, 2.526717f, 0.397577f, 1.410098f, 0.448401f, 1.917638f, 0.614634f, 2.358442f, 1.102885f, 2.290473f, +0.327938f, 0.497841f, 0.098182f, 0.732625f, 0.424083f, 1.151158f, 0.824081f, 1.409827f, 0.066718f, 0.146485f, 0.077014f, 0.219719f, 0.699666f, 1.661970f, 1.284945f, 1.780248f, +0.566978f, 1.239242f, 0.241468f, 2.015380f, 0.643673f, 2.515593f, 1.779259f, 3.404719f, 0.338052f, 1.068630f, 0.555093f, 1.771382f, 1.137717f, 3.890971f, 2.972237f, 4.606015f, +0.344527f, 0.892405f, 0.157771f, 1.071988f, 0.596449f, 2.762468f, 1.772795f, 2.761627f, 0.250500f, 0.938424f, 0.442283f, 1.148976f, 0.840372f, 3.405995f, 2.360653f, 2.978093f, +0.876208f, 1.469535f, 0.240012f, 2.423176f, 1.002748f, 3.007109f, 1.782781f, 4.126619f, 0.614006f, 1.489353f, 0.648464f, 2.503150f, 1.518653f, 3.985330f, 2.551761f, 4.783391f, +0.200458f, 0.379219f, 0.061699f, 0.561933f, 0.297092f, 1.004945f, 0.593502f, 1.239300f, 0.052453f, 0.143512f, 0.062246f, 0.216754f, 0.356099f, 1.054075f, 0.672324f, 1.136926f, +0.291382f, 0.793636f, 0.127576f, 1.299648f, 0.379115f, 1.846349f, 1.077353f, 2.516275f, 0.223448f, 0.880215f, 0.377201f, 1.469188f, 0.486834f, 2.074782f, 1.307505f, 2.473109f, +0.071588f, 0.231071f, 0.033702f, 0.279496f, 0.142035f, 0.819762f, 0.434005f, 0.825199f, 0.066945f, 0.312520f, 0.121513f, 0.385295f, 0.145390f, 0.734303f, 0.419864f, 0.646507f, +0.426776f, 0.891950f, 0.120182f, 1.480979f, 0.559748f, 2.091788f, 1.023086f, 2.890455f, 0.384646f, 1.162665f, 0.417627f, 1.967646f, 0.615885f, 2.014067f, 1.063886f, 2.434158f, +0.136214f, 0.313957f, 0.039049f, 0.395019f, 0.195832f, 0.807081f, 0.364375f, 0.845092f, 0.047627f, 0.158764f, 0.052641f, 0.203602f, 0.301587f, 1.087664f, 0.530338f, 0.996112f, +0.278280f, 0.923467f, 0.113480f, 1.284040f, 0.351224f, 2.084049f, 0.929615f, 2.411598f, 0.285154f, 1.368583f, 0.448338f, 1.939600f, 0.579485f, 3.008950f, 1.449563f, 3.045359f, +0.150681f, 0.592580f, 0.066071f, 0.608599f, 0.290009f, 2.039316f, 0.825358f, 1.743045f, 0.188288f, 1.070934f, 0.318317f, 1.121065f, 0.381416f, 2.347042f, 1.025901f, 1.754572f, +0.371800f, 0.946742f, 0.097517f, 1.334728f, 0.473039f, 2.153788f, 0.805283f, 2.526994f, 0.447768f, 1.649027f, 0.452807f, 2.369589f, 0.668733f, 2.664450f, 1.075919f, 2.734231f, +0.060976f, 0.140302f, 0.018600f, 0.172491f, 0.135693f, 0.558276f, 0.268657f, 0.571204f, 0.029230f, 0.097271f, 0.034377f, 0.121891f, 0.174213f, 0.627221f, 0.325984f, 0.561292f, +0.115533f, 0.382739f, 0.050133f, 0.520014f, 0.225707f, 1.336985f, 0.635682f, 1.511746f, 0.162309f, 0.777663f, 0.271547f, 1.076930f, 0.310454f, 1.609264f, 0.826357f, 1.591498f, +0.057420f, 0.225427f, 0.026791f, 0.226227f, 0.171061f, 1.200829f, 0.518033f, 1.002906f, 0.098370f, 0.558549f, 0.176961f, 0.571326f, 0.187557f, 1.152156f, 0.536802f, 0.841621f, +0.208710f, 0.530546f, 0.058249f, 0.730868f, 0.411025f, 1.868235f, 0.744552f, 2.141844f, 0.344609f, 1.266946f, 0.370818f, 1.778928f, 0.484415f, 1.926770f, 0.829316f, 1.932024f, +0.335278f, 0.527603f, 0.095771f, 0.801643f, 0.468600f, 1.318530f, 0.868781f, 1.667261f, 0.080677f, 0.183615f, 0.088852f, 0.284358f, 0.769304f, 1.894237f, 1.347973f, 2.094954f, +0.493463f, 1.118017f, 0.200511f, 1.877294f, 0.605469f, 2.452851f, 1.596819f, 3.427639f, 0.347994f, 1.140299f, 0.545183f, 1.951580f, 1.064921f, 3.775244f, 2.654338f, 4.614189f, +0.336980f, 0.904788f, 0.147231f, 1.122168f, 0.630512f, 3.027057f, 1.788000f, 3.124434f, 0.289793f, 1.125338f, 0.488168f, 1.422584f, 0.883990f, 3.713844f, 2.369176f, 3.352747f, +0.818275f, 1.422577f, 0.213853f, 2.421943f, 1.012098f, 3.146181f, 1.716794f, 4.457709f, 0.678208f, 1.705268f, 0.683387f, 2.959134f, 1.525264f, 4.149110f, 2.445210f, 5.141732f, +0.237338f, 0.392375f, 0.063070f, 0.581681f, 0.374522f, 1.107124f, 0.645969f, 1.365902f, 0.053942f, 0.128979f, 0.055268f, 0.194888f, 0.373709f, 0.966721f, 0.609177f, 1.043160f, +0.372505f, 0.886662f, 0.140813f, 1.452619f, 0.516040f, 2.196310f, 1.266115f, 2.994519f, 0.248122f, 0.854169f, 0.361629f, 1.426334f, 0.551657f, 2.054603f, 1.279188f, 2.450122f, +0.076615f, 0.216115f, 0.031141f, 0.261520f, 0.161850f, 0.816341f, 0.426986f, 0.822114f, 0.062231f, 0.253885f, 0.097526f, 0.313142f, 0.137920f, 0.608745f, 0.343878f, 0.536194f, +0.494612f, 0.903384f, 0.120256f, 1.500617f, 0.690717f, 2.255759f, 1.089989f, 3.118388f, 0.387207f, 1.022832f, 0.362972f, 1.731753f, 0.632679f, 1.808108f, 0.943585f, 2.186193f, +0.206145f, 0.415229f, 0.051022f, 0.522665f, 0.315556f, 1.136520f, 0.506925f, 1.190565f, 0.062606f, 0.182384f, 0.059744f, 0.233995f, 0.404559f, 1.275059f, 0.614220f, 1.168242f, +0.454734f, 1.318755f, 0.160103f, 1.834468f, 0.611086f, 3.168793f, 1.396447f, 3.668427f, 0.404737f, 1.697587f, 0.549417f, 2.406923f, 0.839337f, 3.808699f, 1.812733f, 3.856463f, +0.206129f, 0.708426f, 0.078035f, 0.727893f, 0.422411f, 2.595821f, 1.037930f, 2.219667f, 0.223728f, 1.112060f, 0.326558f, 1.164622f, 0.462485f, 2.487063f, 1.074006f, 1.860057f, +0.550783f, 1.225658f, 0.124725f, 1.728700f, 0.746123f, 2.968821f, 1.096641f, 3.484771f, 0.576159f, 1.854316f, 0.503042f, 2.665742f, 0.878096f, 3.057484f, 1.219752f, 3.138925f, +0.111610f, 0.224427f, 0.029394f, 0.276036f, 0.264450f, 0.950827f, 0.452050f, 0.973268f, 0.046471f, 0.135149f, 0.047189f, 0.169429f, 0.282645f, 0.889300f, 0.456625f, 0.796170f, +0.228336f, 0.661055f, 0.085544f, 0.898543f, 0.474959f, 2.458696f, 1.154924f, 2.781288f, 0.278630f, 1.166661f, 0.402470f, 1.616330f, 0.543856f, 2.463662f, 1.249847f, 2.437524f, +0.095002f, 0.325946f, 0.038270f, 0.327246f, 0.301347f, 1.848688f, 0.787907f, 1.544656f, 0.141369f, 0.701486f, 0.219568f, 0.717845f, 0.275057f, 1.476622f, 0.679685f, 1.079105f, +0.373944f, 0.830716f, 0.090107f, 1.144875f, 0.784104f, 3.114618f, 1.226320f, 3.572318f, 0.536299f, 1.723084f, 0.498247f, 2.420448f, 0.769306f, 2.674106f, 1.137115f, 2.682567f, +0.412362f, 0.567086f, 0.101697f, 0.862008f, 0.613648f, 1.508949f, 0.982268f, 1.908874f, 0.086188f, 0.171423f, 0.081953f, 0.265592f, 0.838669f, 1.804656f, 1.268752f, 1.996750f, +0.655321f, 1.297525f, 0.229900f, 2.179659f, 0.856121f, 3.030970f, 1.949401f, 4.237352f, 0.401411f, 1.149487f, 0.542954f, 1.968163f, 1.253534f, 3.883570f, 2.697599f, 4.748653f, +0.374635f, 0.879060f, 0.141320f, 1.090733f, 0.746346f, 3.131377f, 1.827332f, 3.233517f, 0.279840f, 0.949670f, 0.407000f, 1.201038f, 0.871105f, 3.198261f, 2.015686f, 2.888552f, +0.985132f, 1.496711f, 0.222286f, 2.549266f, 1.297360f, 3.524431f, 1.900023f, 4.995813f, 0.709213f, 1.558379f, 0.616996f, 2.705417f, 1.627642f, 3.869332f, 2.252851f, 4.797109f, +0.167408f, 0.219374f, 0.051077f, 0.413628f, 0.158854f, 0.372213f, 0.314575f, 0.584059f, 0.033769f, 0.064000f, 0.039724f, 0.122995f, 0.227141f, 0.465732f, 0.425104f, 0.639186f, +0.224094f, 0.422794f, 0.097259f, 0.880975f, 0.186677f, 0.629761f, 0.525862f, 1.092070f, 0.132477f, 0.361487f, 0.221681f, 0.767736f, 0.285968f, 0.844209f, 0.761329f, 1.280415f, +0.050903f, 0.113812f, 0.023755f, 0.175166f, 0.064663f, 0.258514f, 0.195859f, 0.331121f, 0.036696f, 0.118664f, 0.066026f, 0.186150f, 0.078960f, 0.276241f, 0.226034f, 0.309468f, +0.311615f, 0.451127f, 0.086986f, 0.953098f, 0.261677f, 0.677377f, 0.474108f, 1.190994f, 0.216509f, 0.453325f, 0.233021f, 0.976187f, 0.343469f, 0.778041f, 0.588133f, 1.196486f, +0.169161f, 0.270078f, 0.048070f, 0.432381f, 0.155710f, 0.444519f, 0.287193f, 0.592253f, 0.045596f, 0.105285f, 0.049956f, 0.171802f, 0.286063f, 0.714633f, 0.498647f, 0.832774f, +0.318253f, 0.731564f, 0.128648f, 1.294314f, 0.257175f, 1.057045f, 0.674747f, 1.556399f, 0.251401f, 0.835794f, 0.391819f, 1.507199f, 0.506177f, 1.820607f, 1.255134f, 2.344607f, +0.159326f, 0.434024f, 0.069251f, 0.567189f, 0.196333f, 0.956326f, 0.553880f, 1.040064f, 0.153478f, 0.604681f, 0.257203f, 0.805424f, 0.308032f, 1.312978f, 0.821286f, 1.248930f, +0.403693f, 0.712055f, 0.104958f, 1.277336f, 0.328846f, 1.037146f, 0.554929f, 1.548358f, 0.374794f, 0.956109f, 0.375702f, 1.748166f, 0.554580f, 1.530594f, 0.884472f, 1.998564f, +0.050982f, 0.081258f, 0.015416f, 0.127115f, 0.072640f, 0.207016f, 0.142563f, 0.269511f, 0.018840f, 0.043429f, 0.021965f, 0.069247f, 0.111253f, 0.277454f, 0.206357f, 0.315929f, +0.088957f, 0.204134f, 0.038264f, 0.352905f, 0.111269f, 0.456556f, 0.310642f, 0.656866f, 0.096341f, 0.319744f, 0.159774f, 0.563415f, 0.182574f, 0.655557f, 0.481729f, 0.824935f, +0.040876f, 0.111162f, 0.018905f, 0.141946f, 0.077968f, 0.379127f, 0.234052f, 0.402897f, 0.053984f, 0.212328f, 0.096266f, 0.276351f, 0.101979f, 0.433940f, 0.289324f, 0.403335f, +0.152569f, 0.268650f, 0.042209f, 0.470905f, 0.192374f, 0.605690f, 0.345435f, 0.883562f, 0.194199f, 0.494561f, 0.207145f, 0.883589f, 0.270465f, 0.745185f, 0.458993f, 0.950774f, +0.191110f, 0.208318f, 0.054113f, 0.402746f, 0.171016f, 0.333322f, 0.314294f, 0.536301f, 0.035451f, 0.055889f, 0.038702f, 0.110132f, 0.334925f, 0.571247f, 0.581732f, 0.803886f, +0.259028f, 0.406519f, 0.104333f, 0.868550f, 0.203488f, 0.571029f, 0.531979f, 1.015342f, 0.140819f, 0.319630f, 0.218687f, 0.696059f, 0.426952f, 1.048449f, 1.054898f, 1.630527f, +0.163543f, 0.304169f, 0.070830f, 0.480016f, 0.195918f, 0.651543f, 0.550734f, 0.855705f, 0.108421f, 0.291641f, 0.181045f, 0.469108f, 0.327676f, 0.953590f, 0.870537f, 1.095391f, +0.407795f, 0.491088f, 0.105645f, 1.063843f, 0.322939f, 0.695379f, 0.543010f, 1.253661f, 0.260557f, 0.453809f, 0.260255f, 1.002018f, 0.580575f, 1.093978f, 0.922617f, 1.725017f, +0.235787f, 0.430312f, 0.076065f, 0.617582f, 0.254104f, 0.829199f, 0.532051f, 0.990399f, 0.051576f, 0.136134f, 0.064150f, 0.199141f, 0.400933f, 1.144901f, 0.793395f, 1.196040f, +0.343106f, 0.901534f, 0.157451f, 1.429893f, 0.324607f, 1.525098f, 0.966844f, 2.013071f, 0.219951f, 0.835860f, 0.389163f, 1.351260f, 0.548717f, 2.255986f, 1.544620f, 2.604499f, +0.078177f, 0.243433f, 0.038575f, 0.285186f, 0.112787f, 0.627980f, 0.361216f, 0.612257f, 0.061114f, 0.275230f, 0.116267f, 0.328646f, 0.151977f, 0.740480f, 0.460004f, 0.631434f, +0.460839f, 0.929150f, 0.136019f, 1.494209f, 0.439506f, 1.584477f, 0.841966f, 2.120565f, 0.347211f, 1.012473f, 0.395122f, 1.659561f, 0.636579f, 2.008271f, 1.152545f, 2.350792f, +0.227697f, 0.506292f, 0.068415f, 0.616971f, 0.238035f, 0.946391f, 0.464212f, 0.959786f, 0.066553f, 0.214025f, 0.077099f, 0.265836f, 0.482559f, 1.678913f, 0.889407f, 1.489219f, +0.465676f, 1.490799f, 0.199037f, 2.007674f, 0.427374f, 2.446407f, 1.185601f, 2.741845f, 0.398900f, 1.846939f, 0.657358f, 2.535191f, 0.928212f, 4.649604f, 2.433618f, 4.557812f, +0.233849f, 0.887195f, 0.107472f, 0.882511f, 0.327273f, 2.220136f, 0.976229f, 1.837895f, 0.244277f, 1.340351f, 0.432843f, 1.358950f, 0.566603f, 3.363535f, 1.597332f, 2.435361f, +0.570553f, 1.401566f, 0.156848f, 1.913780f, 0.527845f, 2.318506f, 0.941820f, 2.634672f, 0.574412f, 2.040769f, 0.608826f, 2.840247f, 0.982295f, 3.775661f, 1.656455f, 3.752647f, +0.143494f, 0.318520f, 0.045878f, 0.379276f, 0.232197f, 0.921602f, 0.481845f, 0.913277f, 0.057502f, 0.184604f, 0.070883f, 0.224049f, 0.392428f, 1.362997f, 0.769636f, 1.181355f, +0.272175f, 0.869844f, 0.123787f, 1.144644f, 0.386644f, 2.209472f, 1.141344f, 2.419678f, 0.319645f, 1.477454f, 0.560508f, 1.981652f, 0.700073f, 3.500816f, 1.953098f, 3.353242f, +0.125452f, 0.475137f, 0.061350f, 0.461823f, 0.271763f, 1.840422f, 0.862597f, 1.488721f, 0.179665f, 0.984143f, 0.338757f, 0.974986f, 0.392241f, 2.324488f, 1.176643f, 1.644561f, +0.450890f, 1.105722f, 0.131895f, 1.475296f, 0.645681f, 2.831248f, 1.225903f, 3.143774f, 0.622354f, 2.207320f, 0.701912f, 3.001806f, 1.001723f, 3.843760f, 1.797468f, 3.732984f, +0.277727f, 0.421616f, 0.083149f, 0.620452f, 0.282253f, 0.766166f, 0.548476f, 0.938326f, 0.055866f, 0.122660f, 0.064488f, 0.183983f, 0.609979f, 1.448929f, 1.120234f, 1.552045f, +0.409200f, 0.894387f, 0.174272f, 1.454542f, 0.365087f, 1.426827f, 1.009184f, 1.931134f, 0.241233f, 0.762570f, 0.396112f, 1.264051f, 0.845282f, 2.890848f, 2.208263f, 3.422100f, +0.259155f, 0.671272f, 0.118676f, 0.806355f, 0.352591f, 1.633033f, 1.047988f, 1.632536f, 0.186306f, 0.697940f, 0.328942f, 0.854535f, 0.650737f, 2.637413f, 1.827958f, 2.306069f, +0.622250f, 1.043608f, 0.170448f, 1.720848f, 0.559643f, 1.678295f, 0.994986f, 2.303103f, 0.431134f, 1.045775f, 0.455330f, 1.757629f, 1.110232f, 2.913531f, 1.865500f, 3.496965f, +0.073437f, 0.138926f, 0.022603f, 0.205862f, 0.085535f, 0.289332f, 0.170874f, 0.356805f, 0.019000f, 0.051983f, 0.022547f, 0.078513f, 0.134295f, 0.397523f, 0.253553f, 0.428768f, +0.090970f, 0.247775f, 0.039830f, 0.405753f, 0.093018f, 0.453014f, 0.264335f, 0.617384f, 0.068976f, 0.271711f, 0.116437f, 0.453519f, 0.156464f, 0.666816f, 0.420220f, 0.794835f, +0.023294f, 0.075188f, 0.010966f, 0.090945f, 0.036321f, 0.209629f, 0.110983f, 0.211020f, 0.021538f, 0.100546f, 0.039094f, 0.123959f, 0.048701f, 0.245966f, 0.140640f, 0.216558f, +0.131106f, 0.274009f, 0.036920f, 0.454960f, 0.135138f, 0.505014f, 0.247000f, 0.697833f, 0.116834f, 0.353152f, 0.126851f, 0.597659f, 0.194770f, 0.636936f, 0.336447f, 0.769787f, +0.062659f, 0.144421f, 0.017963f, 0.181710f, 0.070796f, 0.291769f, 0.131726f, 0.305510f, 0.021662f, 0.072210f, 0.023942f, 0.092603f, 0.142814f, 0.515054f, 0.251137f, 0.471701f, +0.109090f, 0.362014f, 0.044486f, 0.503364f, 0.108205f, 0.642057f, 0.286397f, 0.742969f, 0.110526f, 0.530466f, 0.173777f, 0.751794f, 0.233854f, 1.214274f, 0.584977f, 1.228967f, +0.061564f, 0.242113f, 0.026995f, 0.248658f, 0.093120f, 0.654813f, 0.265018f, 0.559681f, 0.076063f, 0.432630f, 0.128592f, 0.452881f, 0.160423f, 0.987165f, 0.431493f, 0.737972f, +0.143417f, 0.365194f, 0.037616f, 0.514855f, 0.143400f, 0.652915f, 0.244119f, 0.766051f, 0.170776f, 0.628930f, 0.172698f, 0.903749f, 0.265548f, 1.058029f, 0.427238f, 1.085738f, +0.038895f, 0.089496f, 0.011865f, 0.110028f, 0.068023f, 0.279864f, 0.134678f, 0.286344f, 0.018435f, 0.061348f, 0.021682f, 0.076876f, 0.114397f, 0.411865f, 0.214058f, 0.368572f, +0.062804f, 0.208057f, 0.027252f, 0.282679f, 0.096424f, 0.571173f, 0.271570f, 0.645833f, 0.087238f, 0.417978f, 0.145951f, 0.578829f, 0.173730f, 0.900544f, 0.462429f, 0.890601f, +0.032532f, 0.127718f, 0.015179f, 0.128172f, 0.076166f, 0.534674f, 0.230656f, 0.446548f, 0.055105f, 0.312889f, 0.099130f, 0.320047f, 0.109390f, 0.671979f, 0.313082f, 0.490864f, +0.111638f, 0.283786f, 0.031157f, 0.390937f, 0.172781f, 0.785345f, 0.312986f, 0.900362f, 0.182254f, 0.670052f, 0.196115f, 0.940825f, 0.266737f, 1.060951f, 0.456652f, 1.063844f, +0.095932f, 0.150962f, 0.027403f, 0.229373f, 0.105372f, 0.296491f, 0.195358f, 0.374909f, 0.022824f, 0.051946f, 0.025137f, 0.080447f, 0.226598f, 0.557947f, 0.397045f, 0.617068f, +0.120326f, 0.272617f, 0.048892f, 0.457758f, 0.116027f, 0.470042f, 0.306000f, 0.656842f, 0.083899f, 0.274919f, 0.131440f, 0.470515f, 0.267312f, 0.947648f, 0.666282f, 1.158236f, +0.085640f, 0.229942f, 0.037417f, 0.285186f, 0.125929f, 0.604579f, 0.357108f, 0.624027f, 0.072818f, 0.282772f, 0.122666f, 0.357463f, 0.231268f, 0.971611f, 0.619821f, 0.877141f, +0.196332f, 0.341325f, 0.051311f, 0.581107f, 0.190843f, 0.593249f, 0.323722f, 0.840553f, 0.160893f, 0.404546f, 0.162122f, 0.702004f, 0.376734f, 1.024813f, 0.603957f, 1.269987f, +0.284882f, 0.470976f, 0.075704f, 0.698204f, 0.353294f, 1.044373f, 0.609356f, 1.288484f, 0.064019f, 0.153073f, 0.065592f, 0.231295f, 0.461774f, 1.194529f, 0.752730f, 1.288981f, +0.381043f, 0.906983f, 0.144040f, 1.485911f, 0.414845f, 1.765617f, 1.017831f, 2.407298f, 0.250951f, 0.863908f, 0.365752f, 1.442597f, 0.580909f, 2.163550f, 1.347017f, 2.580042f, +0.081681f, 0.230406f, 0.033200f, 0.278813f, 0.135607f, 0.683977f, 0.357753f, 0.688813f, 0.065599f, 0.267626f, 0.102804f, 0.330090f, 0.151368f, 0.668099f, 0.377407f, 0.588475f, +0.497844f, 0.909288f, 0.121042f, 1.510424f, 0.546375f, 1.784364f, 0.862210f, 2.466726f, 0.385350f, 1.017926f, 0.361231f, 1.723447f, 0.655556f, 1.873490f, 0.977705f, 2.265247f, +0.310698f, 0.625826f, 0.076900f, 0.787752f, 0.373770f, 1.346185f, 0.600442f, 1.410199f, 0.093297f, 0.271791f, 0.089031f, 0.348703f, 0.627690f, 1.978309f, 0.952988f, 1.812578f, +0.584073f, 1.693844f, 0.205640f, 2.356240f, 0.616841f, 3.198636f, 1.409598f, 3.702975f, 0.514002f, 2.155878f, 0.697741f, 3.056711f, 1.109797f, 5.035978f, 2.396851f, 5.099133f, +0.275940f, 0.948354f, 0.104464f, 0.974414f, 0.444398f, 2.730942f, 1.091957f, 2.335208f, 0.296128f, 1.471930f, 0.432235f, 1.541502f, 0.637341f, 3.427368f, 1.480065f, 2.563304f, +0.696110f, 1.549054f, 0.157635f, 2.184826f, 0.741087f, 2.948784f, 1.089240f, 3.461251f, 0.719983f, 2.317203f, 0.628614f, 3.331182f, 1.142450f, 3.977951f, 1.586963f, 4.083910f, +0.233262f, 0.469047f, 0.061434f, 0.576909f, 0.434357f, 1.561725f, 0.742488f, 1.598584f, 0.096031f, 0.279278f, 0.097513f, 0.350116f, 0.608109f, 1.913320f, 0.982425f, 1.712952f, +0.406685f, 1.177396f, 0.152362f, 1.600382f, 0.664817f, 3.441528f, 1.616591f, 3.893072f, 0.490677f, 2.054530f, 0.708763f, 2.846411f, 0.997164f, 4.517144f, 2.291604f, 4.469219f, +0.176354f, 0.605059f, 0.071042f, 0.607471f, 0.439622f, 2.696976f, 1.149446f, 2.253435f, 0.259470f, 1.287518f, 0.402999f, 1.317545f, 0.525621f, 2.821752f, 1.298844f, 2.062118f, +0.655359f, 1.455880f, 0.157917f, 2.006462f, 1.079961f, 4.289822f, 1.689033f, 4.920222f, 0.929315f, 2.985810f, 0.863377f, 4.194223f, 1.387937f, 4.824469f, 2.051517f, 4.839732f, +0.386584f, 0.531636f, 0.095340f, 0.808123f, 0.452113f, 1.111737f, 0.723698f, 1.406387f, 0.079890f, 0.158897f, 0.075965f, 0.246186f, 0.809384f, 1.741640f, 1.224449f, 1.927026f, +0.523556f, 1.036633f, 0.183675f, 1.741397f, 0.537534f, 1.903060f, 1.223974f, 2.660513f, 0.317089f, 0.908022f, 0.428899f, 1.554723f, 1.030964f, 3.194025f, 2.218629f, 3.905509f, +0.311950f, 0.731972f, 0.117674f, 0.908227f, 0.488403f, 2.049147f, 1.195791f, 2.115986f, 0.230393f, 0.781865f, 0.335084f, 0.988816f, 0.746697f, 2.741498f, 1.727814f, 2.476020f, +0.774447f, 1.176618f, 0.174747f, 2.004068f, 0.801530f, 2.177449f, 1.173864f, 3.086492f, 0.551260f, 1.211304f, 0.479582f, 2.102880f, 1.317207f, 3.131347f, 1.823172f, 3.882172f, +0.143729f, 0.188344f, 0.043852f, 0.355121f, 0.174452f, 0.408760f, 0.345462f, 0.641406f, 0.034164f, 0.064749f, 0.040189f, 0.124435f, 0.214310f, 0.439424f, 0.401091f, 0.603081f, +0.257552f, 0.485918f, 0.111780f, 1.012506f, 0.274433f, 0.925806f, 0.773065f, 1.605443f, 0.179416f, 0.489569f, 0.300227f, 1.039759f, 0.361188f, 1.066265f, 0.961586f, 1.617210f, +0.045585f, 0.101922f, 0.021273f, 0.156866f, 0.074070f, 0.296125f, 0.224354f, 0.379295f, 0.038724f, 0.125223f, 0.069676f, 0.196440f, 0.077709f, 0.271863f, 0.222451f, 0.304563f, +0.373768f, 0.541106f, 0.104336f, 1.143198f, 0.401475f, 1.039261f, 0.727396f, 1.827274f, 0.306017f, 0.640738f, 0.329356f, 1.379759f, 0.452744f, 1.025575f, 0.775248f, 1.577149f, +0.196620f, 0.313917f, 0.055873f, 0.502565f, 0.231501f, 0.660885f, 0.426982f, 0.880529f, 0.062451f, 0.144205f, 0.068423f, 0.235310f, 0.365400f, 0.912831f, 0.636943f, 1.063737f, +0.495183f, 1.138272f, 0.200169f, 2.013879f, 0.511838f, 2.103765f, 1.342902f, 3.097595f, 0.460942f, 1.532425f, 0.718399f, 2.763444f, 0.865521f, 3.113085f, 2.146174f, 4.009081f, +0.193163f, 0.526203f, 0.083959f, 0.687650f, 0.304468f, 1.483049f, 0.858945f, 1.612909f, 0.219266f, 0.863878f, 0.367453f, 1.150670f, 0.410409f, 1.749356f, 1.094246f, 1.664022f, +0.655533f, 1.156263f, 0.170435f, 2.074189f, 0.683040f, 2.154235f, 1.152631f, 3.216064f, 0.717169f, 1.829518f, 0.718908f, 3.345124f, 0.989666f, 2.731393f, 1.578368f, 3.566500f, +0.050651f, 0.080730f, 0.015316f, 0.126289f, 0.092311f, 0.263077f, 0.181169f, 0.342495f, 0.022057f, 0.050844f, 0.025714f, 0.081069f, 0.121468f, 0.302928f, 0.225304f, 0.344936f, +0.118308f, 0.271488f, 0.050889f, 0.469347f, 0.189286f, 0.776676f, 0.528452f, 1.117436f, 0.150985f, 0.501099f, 0.250397f, 0.882978f, 0.266844f, 0.958136f, 0.704076f, 1.205692f, +0.042359f, 0.115196f, 0.019592f, 0.147098f, 0.103349f, 0.502546f, 0.310245f, 0.534054f, 0.065923f, 0.259283f, 0.117555f, 0.337465f, 0.116138f, 0.494188f, 0.329494f, 0.459334f, +0.211764f, 0.372882f, 0.058586f, 0.653610f, 0.341540f, 1.075340f, 0.613283f, 1.568673f, 0.317628f, 0.808893f, 0.338802f, 1.445179f, 0.412551f, 1.136660f, 0.700121f, 1.450252f, +0.304007f, 0.331381f, 0.086080f, 0.640666f, 0.347974f, 0.678226f, 0.639509f, 1.091236f, 0.066453f, 0.104764f, 0.072548f, 0.206443f, 0.585502f, 0.998632f, 1.016962f, 1.405323f, +0.551587f, 0.865662f, 0.222172f, 1.849536f, 0.554264f, 1.555379f, 1.449014f, 2.765607f, 0.353358f, 0.802052f, 0.548754f, 1.746628f, 0.999145f, 2.453560f, 2.468651f, 3.815727f, +0.271360f, 0.504695f, 0.117526f, 0.796471f, 0.415814f, 1.382825f, 1.168869f, 1.816136f, 0.211988f, 0.570228f, 0.353986f, 0.917220f, 0.597503f, 1.738828f, 1.587385f, 1.997396f, +0.906275f, 1.091382f, 0.234784f, 2.364259f, 0.918010f, 1.976739f, 1.543603f, 3.563754f, 0.682350f, 1.188439f, 0.681558f, 2.624094f, 1.417936f, 2.671820f, 2.253307f, 4.213006f, +0.216654f, 0.395395f, 0.069892f, 0.567469f, 0.298654f, 0.974577f, 0.625332f, 1.164038f, 0.055845f, 0.147401f, 0.069460f, 0.215623f, 0.404855f, 1.156103f, 0.801157f, 1.207742f, +0.422030f, 1.108912f, 0.193669f, 1.758808f, 0.510721f, 2.399510f, 1.521182f, 3.167262f, 0.318807f, 1.211531f, 0.564070f, 1.958575f, 0.741728f, 3.049527f, 2.087939f, 3.520629f, +0.074927f, 0.233314f, 0.036971f, 0.273331f, 0.138270f, 0.769868f, 0.442831f, 0.750594f, 0.069022f, 0.310845f, 0.131312f, 0.371173f, 0.160073f, 0.779930f, 0.484511f, 0.665074f, +0.591580f, 1.192752f, 0.174608f, 1.918119f, 0.721671f, 2.601720f, 1.382513f, 3.481979f, 0.525224f, 1.531561f, 0.597699f, 2.510405f, 0.898044f, 2.833139f, 1.625936f, 3.316346f, +0.283246f, 0.629807f, 0.085105f, 0.767487f, 0.378755f, 1.505868f, 0.738639f, 1.527182f, 0.097558f, 0.313731f, 0.113017f, 0.389678f, 0.659687f, 2.295174f, 1.215873f, 2.035851f, +0.775457f, 2.482522f, 0.331442f, 3.343237f, 0.910317f, 5.210902f, 2.525356f, 5.840190f, 0.782753f, 3.624207f, 1.289918f, 4.974749f, 1.698644f, 8.508857f, 4.453563f, 8.340877f, +0.303428f, 1.151169f, 0.139449f, 1.145091f, 0.543176f, 3.684764f, 1.620250f, 3.050357f, 0.373498f, 2.049392f, 0.661815f, 2.077830f, 0.807941f, 4.796199f, 2.277699f, 3.472679f, +0.991561f, 2.435775f, 0.272585f, 3.325948f, 1.173382f, 5.153971f, 2.093639f, 5.856797f, 1.176341f, 4.179302f, 1.246818f, 5.816558f, 1.876060f, 7.211038f, 3.163620f, 7.167084f, +0.152575f, 0.338676f, 0.048781f, 0.403277f, 0.315802f, 1.253435f, 0.655339f, 1.242112f, 0.072048f, 0.231299f, 0.088813f, 0.280723f, 0.458553f, 1.592665f, 0.899322f, 1.380416f, +0.387404f, 1.238105f, 0.176194f, 1.629245f, 0.703942f, 4.022671f, 2.077985f, 4.405384f, 0.536131f, 2.478086f, 0.940121f, 3.323760f, 1.095066f, 5.476039f, 3.055071f, 5.245201f, +0.139136f, 0.526964f, 0.068042f, 0.512197f, 0.385535f, 2.610895f, 1.223714f, 2.111959f, 0.234808f, 1.286194f, 0.442727f, 1.274226f, 0.478075f, 2.833156f, 1.434128f, 2.004440f, +0.669786f, 1.642522f, 0.195927f, 2.191516f, 1.226856f, 5.379643f, 2.329333f, 5.973473f, 1.089404f, 3.863821f, 1.228668f, 5.254537f, 1.635289f, 6.274844f, 2.934322f, 6.094005f, +0.472823f, 0.717790f, 0.141559f, 1.056303f, 0.614653f, 1.668451f, 1.194396f, 2.043357f, 0.112077f, 0.246076f, 0.129373f, 0.369100f, 1.141239f, 2.710872f, 2.095900f, 2.903797f, +0.932575f, 2.038327f, 0.397171f, 3.314934f, 1.064278f, 4.159393f, 2.941906f, 5.629514f, 0.647845f, 2.047926f, 1.063782f, 3.394683f, 2.117051f, 7.240274f, 5.530705f, 8.570820f, +0.460208f, 1.192045f, 0.210746f, 1.431925f, 0.800896f, 3.709365f, 2.380460f, 3.708236f, 0.389859f, 1.460491f, 0.688335f, 1.788178f, 1.269935f, 5.146994f, 3.567318f, 4.500367f, +1.480004f, 2.482191f, 0.405405f, 4.092987f, 1.702625f, 5.105947f, 3.027089f, 7.006828f, 1.208362f, 2.931044f, 1.276176f, 4.926193f, 2.901970f, 7.615507f, 4.876121f, 9.140509f, +0.111484f, 0.210901f, 0.034313f, 0.312517f, 0.166093f, 0.561828f, 0.331805f, 0.692847f, 0.033988f, 0.092992f, 0.040334f, 0.140451f, 0.224047f, 0.663193f, 0.423006f, 0.715320f, +0.184869f, 0.503526f, 0.080941f, 0.824568f, 0.241792f, 1.177568f, 0.687116f, 1.604834f, 0.165176f, 0.650666f, 0.278832f, 1.086042f, 0.349430f, 1.489196f, 0.938476f, 1.775100f, +0.036885f, 0.119058f, 0.017365f, 0.144009f, 0.073567f, 0.424592f, 0.224791f, 0.427409f, 0.040188f, 0.187612f, 0.072947f, 0.231300f, 0.084748f, 0.428024f, 0.244738f, 0.376847f, +0.278060f, 0.581137f, 0.078303f, 0.964910f, 0.366608f, 1.370021f, 0.670072f, 1.893110f, 0.291990f, 0.882595f, 0.317026f, 1.493668f, 0.453959f, 1.484536f, 0.784173f, 1.794179f, +0.128777f, 0.296816f, 0.036917f, 0.373451f, 0.186111f, 0.767018f, 0.346287f, 0.803142f, 0.052461f, 0.174879f, 0.057984f, 0.224268f, 0.322559f, 1.163296f, 0.567216f, 1.065378f, +0.300130f, 0.995977f, 0.122391f, 1.384861f, 0.380788f, 2.259474f, 1.007866f, 2.614595f, 0.358324f, 1.719761f, 0.563382f, 2.437300f, 0.707048f, 3.671317f, 1.768658f, 3.715740f, +0.131977f, 0.519024f, 0.057870f, 0.533054f, 0.255343f, 1.795547f, 0.726699f, 1.534690f, 0.192146f, 1.092880f, 0.324840f, 1.144038f, 0.377937f, 2.325629f, 1.016542f, 1.738565f, +0.411789f, 1.048568f, 0.108006f, 1.478284f, 0.526664f, 2.397949f, 0.896572f, 2.813463f, 0.577813f, 2.127954f, 0.584315f, 3.057789f, 0.837909f, 3.338505f, 1.348106f, 3.425939f, +0.068327f, 0.157217f, 0.020843f, 0.193286f, 0.152850f, 0.628861f, 0.302625f, 0.643423f, 0.038162f, 0.126996f, 0.044883f, 0.159138f, 0.220849f, 0.795122f, 0.413247f, 0.711544f, +0.147690f, 0.489269f, 0.064086f, 0.664753f, 0.290043f, 1.718081f, 0.816878f, 1.942655f, 0.241744f, 1.158260f, 0.404444f, 1.603992f, 0.448974f, 2.327297f, 1.195067f, 2.301603f, +0.059610f, 0.234026f, 0.027813f, 0.234857f, 0.178517f, 1.253173f, 0.540614f, 1.046622f, 0.118984f, 0.675598f, 0.214044f, 0.691053f, 0.220277f, 1.353157f, 0.630451f, 0.988448f, +0.273985f, 0.696475f, 0.076467f, 0.959449f, 0.542403f, 2.465392f, 0.982539f, 2.826457f, 0.527082f, 1.937805f, 0.567170f, 2.720886f, 0.719415f, 2.861487f, 1.231635f, 2.869291f, +0.269833f, 0.424618f, 0.077077f, 0.645167f, 0.379110f, 1.066725f, 0.702866f, 1.348858f, 0.075651f, 0.172174f, 0.083316f, 0.266641f, 0.700435f, 1.724663f, 1.227302f, 1.907412f, +0.453061f, 1.026480f, 0.184094f, 1.723592f, 0.558812f, 2.263836f, 1.473769f, 3.163508f, 0.372257f, 1.219803f, 0.583195f, 2.087650f, 1.106111f, 3.921266f, 2.757004f, 4.792660f, +0.251258f, 0.674624f, 0.109778f, 0.836705f, 0.472585f, 2.268857f, 1.340152f, 2.341844f, 0.251751f, 0.977613f, 0.424086f, 1.235839f, 0.745661f, 3.132691f, 1.998441f, 2.828100f, +0.771505f, 1.341268f, 0.201630f, 2.283513f, 0.959254f, 2.981913f, 1.627157f, 4.224964f, 0.745027f, 1.873274f, 0.750715f, 3.250674f, 1.626911f, 4.425616f, 2.608164f, 5.484388f, +0.195092f, 0.322533f, 0.051844f, 0.478143f, 0.309472f, 0.914832f, 0.533773f, 1.128663f, 0.051662f, 0.123526f, 0.052932f, 0.186650f, 0.347525f, 0.898987f, 0.566494f, 0.970070f, +0.349315f, 0.831462f, 0.132046f, 1.362184f, 0.486451f, 2.070377f, 1.193518f, 2.822818f, 0.271093f, 0.933248f, 0.395108f, 1.558384f, 0.585237f, 2.179672f, 1.357055f, 2.599268f, +0.058346f, 0.164582f, 0.023715f, 0.199160f, 0.123903f, 0.624943f, 0.326875f, 0.629362f, 0.055217f, 0.225270f, 0.086534f, 0.277848f, 0.118824f, 0.524459f, 0.296265f, 0.461953f, +0.476306f, 0.869949f, 0.115805f, 1.445079f, 0.668641f, 2.183665f, 1.055153f, 3.018725f, 0.434445f, 1.147612f, 0.407253f, 1.943018f, 0.689261f, 1.969814f, 1.027973f, 2.381712f, +0.288053f, 0.580214f, 0.071295f, 0.730338f, 0.443250f, 1.596427f, 0.712058f, 1.672342f, 0.101927f, 0.296931f, 0.097266f, 0.380957f, 0.639530f, 2.015626f, 0.970964f, 1.846768f, +0.724885f, 2.102208f, 0.255218f, 2.924299f, 0.979232f, 5.077817f, 2.237729f, 5.878454f, 0.751715f, 3.152918f, 1.020429f, 4.470363f, 1.513656f, 6.868584f, 3.269072f, 6.954721f, +0.266848f, 0.917104f, 0.101022f, 0.942305f, 0.549706f, 3.378086f, 1.350715f, 2.888575f, 0.337453f, 1.677342f, 0.492554f, 1.756623f, 0.677332f, 3.642421f, 1.572932f, 2.724140f, +0.901632f, 2.006404f, 0.204175f, 2.829884f, 1.227810f, 4.885451f, 1.804618f, 5.734491f, 1.098905f, 3.536731f, 0.959450f, 5.084360f, 1.626185f, 5.662293f, 2.258914f, 5.813117f, +0.184850f, 0.371700f, 0.048683f, 0.457176f, 0.440284f, 1.583036f, 0.752620f, 1.620399f, 0.089675f, 0.260795f, 0.091059f, 0.326945f, 0.529589f, 1.666270f, 0.855573f, 1.491773f, +0.431422f, 1.249012f, 0.161629f, 1.697727f, 0.902104f, 4.669877f, 2.193584f, 5.282587f, 0.613375f, 2.568283f, 0.885995f, 3.558182f, 1.162497f, 5.266103f, 2.671560f, 5.210231f, +0.145772f, 0.500135f, 0.058722f, 0.502129f, 0.464815f, 2.851525f, 1.215314f, 2.382568f, 0.252734f, 1.254093f, 0.392537f, 1.283340f, 0.477468f, 2.563245f, 1.179854f, 1.873202f, +0.725559f, 1.611830f, 0.174833f, 2.221389f, 1.529368f, 6.074954f, 2.391894f, 6.967683f, 1.212391f, 3.895311f, 1.126369f, 5.471816f, 1.688669f, 5.869814f, 2.496031f, 5.888384f, +0.490516f, 0.674565f, 0.120972f, 1.025383f, 0.733780f, 1.804351f, 1.174563f, 2.282568f, 0.119451f, 0.237581f, 0.113581f, 0.368094f, 1.128612f, 2.428557f, 1.707382f, 2.687061f, +0.889283f, 1.760765f, 0.311979f, 2.957838f, 1.167866f, 4.134654f, 2.659248f, 5.780323f, 0.634665f, 1.817436f, 0.858456f, 3.111831f, 1.924425f, 5.962056f, 4.141355f, 7.290132f, +0.412864f, 0.968762f, 0.155741f, 1.202034f, 0.826820f, 3.469010f, 2.024360f, 3.582164f, 0.359317f, 1.219384f, 0.522591f, 1.542142f, 1.086046f, 3.987417f, 2.513047f, 3.601288f, +1.372833f, 2.085746f, 0.309767f, 3.552537f, 1.817421f, 4.937239f, 2.661668f, 6.998440f, 1.151513f, 2.530263f, 1.001786f, 4.392652f, 2.566027f, 6.100122f, 3.551689f, 7.562790f, +0.111522f, 0.146140f, 0.034026f, 0.275546f, 0.125423f, 0.293880f, 0.248371f, 0.461142f, 0.024782f, 0.046966f, 0.029151f, 0.090260f, 0.165108f, 0.338541f, 0.309008f, 0.464624f, +0.205238f, 0.387219f, 0.089075f, 0.806847f, 0.202635f, 0.683593f, 0.570813f, 1.185420f, 0.133657f, 0.364708f, 0.223656f, 0.774575f, 0.285782f, 0.843661f, 0.760835f, 1.279584f, +0.042457f, 0.094929f, 0.019814f, 0.146104f, 0.063923f, 0.255560f, 0.193620f, 0.327336f, 0.033717f, 0.109032f, 0.060667f, 0.171041f, 0.071864f, 0.251415f, 0.205720f, 0.281657f, +0.263729f, 0.381803f, 0.073619f, 0.806637f, 0.262482f, 0.679462f, 0.475567f, 1.194659f, 0.201855f, 0.422643f, 0.217250f, 0.910117f, 0.317189f, 0.718510f, 0.543133f, 1.104939f, +0.154149f, 0.246110f, 0.043804f, 0.394009f, 0.168171f, 0.480091f, 0.310175f, 0.639648f, 0.045771f, 0.105689f, 0.050148f, 0.172461f, 0.284440f, 0.710580f, 0.495819f, 0.828051f, +0.398709f, 0.916507f, 0.161171f, 1.621523f, 0.381862f, 1.569535f, 1.001886f, 2.310992f, 0.346955f, 1.153470f, 0.540746f, 2.080070f, 0.691953f, 2.488799f, 1.715788f, 3.205115f, +0.181783f, 0.495202f, 0.079013f, 0.647138f, 0.265495f, 1.293209f, 0.748995f, 1.406446f, 0.192903f, 0.760010f, 0.323273f, 1.012320f, 0.383491f, 1.634620f, 1.022477f, 1.554882f, +0.467356f, 0.824346f, 0.121510f, 1.478772f, 0.451215f, 1.423082f, 0.761425f, 2.124523f, 0.477982f, 1.219346f, 0.479141f, 2.229475f, 0.700569f, 1.933509f, 1.117301f, 2.524668f, +0.043223f, 0.068891f, 0.013070f, 0.107769f, 0.072990f, 0.208014f, 0.143250f, 0.270810f, 0.017595f, 0.040560f, 0.020514f, 0.064672f, 0.102919f, 0.256670f, 0.190899f, 0.292263f, +0.103685f, 0.237932f, 0.044599f, 0.411335f, 0.153711f, 0.630705f, 0.429133f, 0.907420f, 0.123701f, 0.410547f, 0.205148f, 0.723419f, 0.232203f, 0.833755f, 0.612676f, 1.049174f, +0.043390f, 0.117999f, 0.020068f, 0.150677f, 0.098091f, 0.476982f, 0.294463f, 0.506887f, 0.063127f, 0.248287f, 0.112570f, 0.323153f, 0.118120f, 0.502624f, 0.335118f, 0.467175f, +0.164330f, 0.289359f, 0.045463f, 0.507205f, 0.245579f, 0.773205f, 0.440971f, 1.127928f, 0.230421f, 0.586805f, 0.245781f, 1.048394f, 0.317872f, 0.875800f, 0.539445f, 1.117424f, +0.203324f, 0.221632f, 0.057572f, 0.428486f, 0.215643f, 0.420305f, 0.396311f, 0.676252f, 0.041549f, 0.065502f, 0.045359f, 0.129075f, 0.388815f, 0.663163f, 0.675335f, 0.933234f, +0.378875f, 0.594607f, 0.152606f, 1.270412f, 0.352762f, 0.989924f, 0.922227f, 1.760175f, 0.226900f, 0.515017f, 0.352368f, 1.121552f, 0.681426f, 1.673351f, 1.683644f, 2.602363f, +0.217855f, 0.405182f, 0.094353f, 0.639427f, 0.309317f, 1.028661f, 0.869503f, 1.350994f, 0.159100f, 0.427964f, 0.265672f, 0.688386f, 0.476289f, 1.386076f, 1.265356f, 1.592189f, +0.551194f, 0.663776f, 0.142795f, 1.437937f, 0.517340f, 1.113981f, 0.869890f, 2.008336f, 0.387962f, 0.675708f, 0.387512f, 1.491975f, 0.856270f, 1.613470f, 1.360736f, 2.544168f, +0.147639f, 0.269442f, 0.047628f, 0.386702f, 0.188576f, 0.615367f, 0.394847f, 0.734997f, 0.035576f, 0.093901f, 0.044249f, 0.137362f, 0.273932f, 0.782240f, 0.542077f, 0.817180f, +0.295361f, 0.776082f, 0.135541f, 1.230918f, 0.331190f, 1.556027f, 0.986451f, 2.053896f, 0.208581f, 0.792652f, 0.369046f, 1.281410f, 0.515423f, 2.119102f, 1.450900f, 2.446469f, +0.061290f, 0.190849f, 0.030242f, 0.223583f, 0.104800f, 0.583513f, 0.335639f, 0.568904f, 0.052781f, 0.237701f, 0.100414f, 0.283834f, 0.130011f, 0.633454f, 0.393516f, 0.540169f, +0.366596f, 0.739135f, 0.108202f, 1.188637f, 0.414378f, 1.493888f, 0.793829f, 1.999326f, 0.304268f, 0.887249f, 0.346253f, 1.454303f, 0.552561f, 1.743213f, 1.000428f, 2.040528f, +0.195027f, 0.433649f, 0.058599f, 0.528448f, 0.241642f, 0.960731f, 0.471245f, 0.974329f, 0.062796f, 0.201942f, 0.072746f, 0.250827f, 0.451001f, 1.569118f, 0.831243f, 1.391829f, +0.548359f, 1.755497f, 0.234377f, 2.364146f, 0.596463f, 3.414316f, 1.654678f, 3.826642f, 0.517451f, 2.395838f, 0.852720f, 3.288634f, 1.192665f, 5.974302f, 3.126969f, 5.856359f, +0.250785f, 0.951450f, 0.115256f, 0.946426f, 0.415979f, 2.821891f, 1.240831f, 2.336045f, 0.288584f, 1.583467f, 0.511353f, 1.605440f, 0.663034f, 3.935980f, 1.869184f, 2.849839f, +0.620854f, 1.525132f, 0.170676f, 2.082503f, 0.680759f, 2.990170f, 1.214663f, 3.397928f, 0.688558f, 2.446309f, 0.729811f, 3.404659f, 1.166342f, 4.483084f, 1.966814f, 4.455758f, +0.114348f, 0.253821f, 0.036559f, 0.302237f, 0.219302f, 0.870420f, 0.455085f, 0.862557f, 0.050478f, 0.162052f, 0.062224f, 0.196679f, 0.341226f, 1.185159f, 0.669218f, 1.027217f, +0.298184f, 0.952965f, 0.135615f, 1.254024f, 0.502042f, 2.868916f, 1.481992f, 3.141861f, 0.385769f, 1.783090f, 0.676458f, 2.391589f, 0.836891f, 4.184995f, 2.334800f, 4.008580f, +0.125170f, 0.474068f, 0.061212f, 0.460783f, 0.321371f, 2.176368f, 1.020053f, 1.760469f, 0.197473f, 1.081690f, 0.372334f, 1.071626f, 0.427035f, 2.530688f, 1.281020f, 1.790446f, +0.456477f, 1.119422f, 0.133529f, 1.493576f, 0.774747f, 3.397190f, 1.470950f, 3.772187f, 0.694079f, 2.461711f, 0.782807f, 3.347761f, 1.106588f, 4.246142f, 1.985635f, 4.123769f, +0.277729f, 0.421619f, 0.083150f, 0.620456f, 0.334531f, 0.908072f, 0.650062f, 1.112118f, 0.061543f, 0.135123f, 0.071040f, 0.202677f, 0.665592f, 1.581032f, 1.222369f, 1.693550f, +0.562578f, 1.229625f, 0.239594f, 1.999741f, 0.594891f, 2.324945f, 1.644415f, 3.146687f, 0.365349f, 1.154916f, 0.599914f, 1.914412f, 1.268058f, 4.336733f, 3.312747f, 5.133695f, +0.324483f, 0.840487f, 0.148593f, 1.009622f, 0.523237f, 2.423382f, 1.555189f, 2.422645f, 0.256970f, 0.962664f, 0.453707f, 1.178655f, 0.889055f, 3.603306f, 2.497407f, 3.150616f, +0.790542f, 1.325859f, 0.216546f, 2.186263f, 0.842684f, 2.527098f, 1.498204f, 3.467905f, 0.603387f, 1.463597f, 0.637250f, 2.459862f, 1.539089f, 4.038961f, 2.586100f, 4.847762f, +0.092237f, 0.174490f, 0.028389f, 0.258563f, 0.127329f, 0.430704f, 0.254366f, 0.531146f, 0.026288f, 0.071924f, 0.031196f, 0.108631f, 0.184052f, 0.544805f, 0.347495f, 0.587627f, +0.157084f, 0.427849f, 0.068776f, 0.700639f, 0.190368f, 0.927124f, 0.540981f, 1.263521f, 0.131206f, 0.516849f, 0.221487f, 0.862685f, 0.294807f, 1.256404f, 0.791772f, 1.497614f, +0.036632f, 0.118240f, 0.017246f, 0.143020f, 0.067697f, 0.390719f, 0.206857f, 0.393310f, 0.037312f, 0.174183f, 0.067725f, 0.214744f, 0.083569f, 0.422070f, 0.241334f, 0.371606f, +0.209204f, 0.437230f, 0.058913f, 0.725969f, 0.255574f, 0.955086f, 0.467129f, 1.319748f, 0.205370f, 0.620769f, 0.222979f, 1.050565f, 0.339123f, 1.108999f, 0.585804f, 1.340313f, +0.107653f, 0.248128f, 0.030861f, 0.312193f, 0.144160f, 0.594125f, 0.268231f, 0.622106f, 0.040998f, 0.136667f, 0.045314f, 0.175264f, 0.267736f, 0.965579f, 0.470810f, 0.884303f, +0.257676f, 0.855094f, 0.105079f, 1.188970f, 0.302923f, 1.797446f, 0.801772f, 2.079950f, 0.287593f, 1.380289f, 0.452173f, 1.956191f, 0.602730f, 3.129649f, 1.507709f, 3.167518f, +0.132436f, 0.520826f, 0.058070f, 0.534904f, 0.237417f, 1.669495f, 0.675683f, 1.426951f, 0.180249f, 1.025214f, 0.304728f, 1.073204f, 0.376559f, 2.317149f, 1.012835f, 1.732225f, +0.313042f, 0.797122f, 0.082106f, 1.123792f, 0.370976f, 1.689085f, 0.631534f, 1.981768f, 0.410632f, 1.512264f, 0.415253f, 2.173065f, 0.632461f, 2.519932f, 1.017562f, 2.585928f, +0.062172f, 0.143054f, 0.018965f, 0.175874f, 0.128869f, 0.530200f, 0.255146f, 0.542477f, 0.032461f, 0.108026f, 0.038178f, 0.135367f, 0.199528f, 0.718362f, 0.373353f, 0.642854f, +0.138016f, 0.457220f, 0.059888f, 0.621208f, 0.251144f, 1.487663f, 0.707323f, 1.682119f, 0.211189f, 1.011860f, 0.353324f, 1.401253f, 0.416589f, 2.159424f, 1.108864f, 2.135583f, +0.065108f, 0.255612f, 0.030378f, 0.256520f, 0.180668f, 1.268270f, 0.547127f, 1.059231f, 0.121491f, 0.689831f, 0.218554f, 0.705612f, 0.238889f, 1.467487f, 0.683718f, 1.071963f, +0.226708f, 0.576296f, 0.063272f, 0.793893f, 0.415859f, 1.890210f, 0.753310f, 2.167038f, 0.407714f, 1.498952f, 0.438723f, 2.104690f, 0.591056f, 2.350937f, 1.011886f, 2.357348f, +0.192431f, 0.302816f, 0.054967f, 0.460100f, 0.250512f, 0.704883f, 0.464448f, 0.891314f, 0.050435f, 0.114785f, 0.055545f, 0.177764f, 0.495972f, 1.221220f, 0.869042f, 1.350622f, +0.331828f, 0.751808f, 0.134833f, 1.262382f, 0.379233f, 1.536333f, 1.000160f, 2.146887f, 0.254880f, 0.835187f, 0.399308f, 1.429393f, 0.804385f, 2.851620f, 2.004947f, 3.485315f, +0.215088f, 0.577508f, 0.093974f, 0.716257f, 0.374852f, 1.799647f, 1.063002f, 1.857539f, 0.201467f, 0.782349f, 0.339381f, 0.988998f, 0.633792f, 2.662703f, 1.698621f, 2.403809f, +0.500332f, 0.869831f, 0.130760f, 1.480891f, 0.576417f, 1.791836f, 0.977761f, 2.538788f, 0.451678f, 1.135686f, 0.455127f, 1.970745f, 1.047592f, 2.849720f, 1.679436f, 3.531480f, +0.167099f, 0.276253f, 0.044405f, 0.409535f, 0.245606f, 0.726036f, 0.423617f, 0.895739f, 0.041366f, 0.098908f, 0.042382f, 0.149451f, 0.295548f, 0.764532f, 0.481768f, 0.824984f, +0.307274f, 0.731395f, 0.116154f, 1.198244f, 0.396490f, 1.687496f, 0.972797f, 2.300786f, 0.222928f, 0.767439f, 0.324910f, 1.281508f, 0.511153f, 1.903749f, 1.185266f, 2.270228f, +0.059987f, 0.169212f, 0.024383f, 0.204763f, 0.118036f, 0.595351f, 0.311398f, 0.599561f, 0.053072f, 0.216516f, 0.083171f, 0.267051f, 0.121300f, 0.535389f, 0.302439f, 0.471581f, +0.370987f, 0.677589f, 0.090199f, 1.125548f, 0.482558f, 1.575950f, 0.761504f, 2.178612f, 0.316333f, 0.835613f, 0.296534f, 1.414773f, 0.533047f, 1.523375f, 0.794993f, 1.841920f, +0.249289f, 0.502132f, 0.061701f, 0.632054f, 0.355437f, 1.280156f, 0.570991f, 1.341031f, 0.082462f, 0.240228f, 0.078692f, 0.308208f, 0.549541f, 1.732003f, 0.834338f, 1.586906f, +0.644281f, 1.868451f, 0.226838f, 2.599128f, 0.806446f, 4.181834f, 1.842881f, 4.841198f, 0.624592f, 2.619727f, 0.847864f, 3.714379f, 1.335802f, 6.061528f, 2.884957f, 6.137544f, +0.277210f, 0.952718f, 0.104945f, 0.978897f, 0.529127f, 3.251623f, 1.300150f, 2.780438f, 0.327715f, 1.628938f, 0.478341f, 1.705932f, 0.698644f, 3.757031f, 1.622425f, 2.809856f, +0.709576f, 1.579019f, 0.160684f, 2.227089f, 0.895332f, 3.562522f, 1.315946f, 4.181651f, 0.808475f, 2.602007f, 0.705876f, 3.740613f, 1.270715f, 4.424563f, 1.765134f, 4.542418f, +0.174125f, 0.350134f, 0.045859f, 0.430651f, 0.384290f, 1.381711f, 0.656904f, 1.414321f, 0.078968f, 0.229657f, 0.080187f, 0.287908f, 0.495325f, 1.558463f, 0.800218f, 1.395257f, +0.417370f, 1.208329f, 0.156365f, 1.642428f, 0.808647f, 4.186081f, 1.966330f, 4.735315f, 0.554730f, 2.322730f, 0.801285f, 3.217984f, 1.116655f, 5.058440f, 2.566210f, 5.004772f, +0.164829f, 0.565517f, 0.066399f, 0.567772f, 0.486992f, 2.987577f, 1.273299f, 2.496245f, 0.267153f, 1.325639f, 0.414931f, 1.356555f, 0.536057f, 2.877778f, 1.324633f, 2.103060f, +0.621519f, 1.380704f, 0.149763f, 1.902857f, 1.213884f, 4.821790f, 1.898485f, 5.530363f, 0.970871f, 3.119328f, 0.901985f, 4.381778f, 1.436267f, 4.992462f, 2.122953f, 5.008257f, +0.362139f, 0.498018f, 0.089311f, 0.757021f, 0.501963f, 1.234316f, 0.803493f, 1.561454f, 0.082442f, 0.163972f, 0.078391f, 0.254049f, 0.827323f, 1.780242f, 1.251588f, 1.969737f, +0.674276f, 1.335055f, 0.236550f, 2.242705f, 0.820492f, 2.904830f, 1.868273f, 4.061006f, 0.449862f, 1.288232f, 0.608490f, 2.205724f, 1.448798f, 4.488515f, 3.117806f, 5.488354f, +0.365885f, 0.858528f, 0.138020f, 1.065257f, 0.678941f, 2.848570f, 1.662299f, 2.941485f, 0.297682f, 1.010219f, 0.432949f, 1.277613f, 0.955640f, 3.508634f, 2.211297f, 3.168869f, +0.921677f, 1.400304f, 0.207968f, 2.385061f, 1.130577f, 3.071346f, 1.655764f, 4.353573f, 0.722715f, 1.588049f, 0.628743f, 2.756925f, 1.710532f, 4.066383f, 2.367581f, 5.041408f, +0.196952f, 0.258088f, 0.060090f, 0.486623f, 0.237805f, 0.557203f, 0.470918f, 0.874335f, 0.040181f, 0.076152f, 0.047266f, 0.146349f, 0.259586f, 0.532257f, 0.485826f, 0.730487f, +0.408822f, 0.771317f, 0.177433f, 1.607192f, 0.433346f, 1.461903f, 1.220716f, 2.535089f, 0.244435f, 0.666983f, 0.409026f, 1.416555f, 0.506785f, 1.496085f, 1.349209f, 2.269120f, +0.075923f, 0.169755f, 0.035431f, 0.261266f, 0.122723f, 0.490635f, 0.371721f, 0.628434f, 0.055357f, 0.179007f, 0.099602f, 0.280812f, 0.114405f, 0.400244f, 0.327500f, 0.448387f, +0.519248f, 0.751719f, 0.144946f, 1.588161f, 0.554830f, 1.436237f, 1.005246f, 2.525253f, 0.364880f, 0.763984f, 0.392708f, 1.645155f, 0.555964f, 1.259393f, 0.951994f, 1.936719f, +0.213435f, 0.340765f, 0.060652f, 0.545547f, 0.249989f, 0.713664f, 0.461081f, 0.950848f, 0.058185f, 0.134354f, 0.063749f, 0.219235f, 0.350614f, 0.875892f, 0.611168f, 1.020692f, +0.622672f, 1.431328f, 0.251704f, 2.532366f, 0.640257f, 2.631594f, 1.679832f, 3.874773f, 0.497474f, 1.653877f, 0.775336f, 2.982460f, 0.962037f, 3.460231f, 2.385498f, 4.456141f, +0.254860f, 0.694274f, 0.110776f, 0.907288f, 0.399621f, 1.946532f, 1.127382f, 2.116975f, 0.248302f, 0.978275f, 0.416112f, 1.303044f, 0.478647f, 2.040219f, 1.276184f, 1.940696f, +0.721424f, 1.272485f, 0.187566f, 2.282677f, 0.747774f, 2.358400f, 1.261870f, 3.520862f, 0.677405f, 1.728079f, 0.679048f, 3.159651f, 0.962733f, 2.657059f, 1.535413f, 3.469439f, +0.040064f, 0.063856f, 0.012114f, 0.099892f, 0.072635f, 0.207003f, 0.142553f, 0.269494f, 0.014974f, 0.034517f, 0.017457f, 0.055036f, 0.084927f, 0.211800f, 0.157527f, 0.241171f, +0.108401f, 0.248754f, 0.046627f, 0.430044f, 0.172530f, 0.707925f, 0.481674f, 1.018521f, 0.118736f, 0.394070f, 0.196915f, 0.694385f, 0.216121f, 0.776010f, 0.570243f, 0.976509f, +0.040724f, 0.110749f, 0.018835f, 0.141420f, 0.098841f, 0.480627f, 0.296713f, 0.510761f, 0.054396f, 0.213949f, 0.097001f, 0.278460f, 0.098696f, 0.419969f, 0.280009f, 0.390349f, +0.169814f, 0.299016f, 0.046980f, 0.524132f, 0.272453f, 0.857820f, 0.489228f, 1.251361f, 0.218611f, 0.556729f, 0.233184f, 0.994660f, 0.292429f, 0.805700f, 0.496267f, 1.027985f, +0.351802f, 0.383479f, 0.099614f, 0.741389f, 0.400580f, 0.780760f, 0.736190f, 1.256209f, 0.066003f, 0.104054f, 0.072056f, 0.205043f, 0.598914f, 1.021507f, 1.040256f, 1.437513f, +0.739405f, 1.160425f, 0.297823f, 2.479312f, 0.739117f, 2.074116f, 1.932276f, 3.687969f, 0.406550f, 0.922787f, 0.631360f, 2.009555f, 1.183907f, 2.907274f, 2.925156f, 4.521334f, +0.381679f, 0.709874f, 0.165305f, 1.120270f, 0.581809f, 1.934855f, 1.635488f, 2.541145f, 0.255915f, 0.688386f, 0.427337f, 1.107279f, 0.742871f, 2.161874f, 1.973586f, 2.483351f, +1.063239f, 1.280407f, 0.275448f, 2.773744f, 1.071389f, 2.307007f, 1.801504f, 4.159177f, 0.687083f, 1.196683f, 0.686286f, 2.642297f, 1.470446f, 2.770763f, 2.336752f, 4.369022f, +0.211295f, 0.385613f, 0.068163f, 0.553430f, 0.289746f, 0.945507f, 0.606680f, 1.129318f, 0.046745f, 0.123382f, 0.058141f, 0.180487f, 0.349013f, 0.996639f, 0.690652f, 1.041156f, +0.476779f, 1.252770f, 0.218794f, 1.986977f, 0.573966f, 2.696654f, 1.709558f, 3.559481f, 0.309124f, 1.174735f, 0.546938f, 1.899089f, 0.740696f, 3.045283f, 2.085034f, 3.515730f, +0.088817f, 0.276566f, 0.043825f, 0.324002f, 0.163048f, 0.907828f, 0.522186f, 0.885099f, 0.070223f, 0.316252f, 0.133596f, 0.377629f, 0.167725f, 0.817213f, 0.507672f, 0.696867f, +0.584912f, 1.179308f, 0.172640f, 1.896500f, 0.709814f, 2.558975f, 1.359799f, 3.424772f, 0.445710f, 1.299697f, 0.507213f, 2.130355f, 0.784867f, 2.476087f, 1.421024f, 2.898398f, +0.218830f, 0.486576f, 0.065751f, 0.592946f, 0.291092f, 1.157335f, 0.567681f, 1.173716f, 0.064690f, 0.208033f, 0.074941f, 0.258393f, 0.450508f, 1.567402f, 0.830334f, 1.390307f, +0.693993f, 2.221726f, 0.296623f, 2.992021f, 0.810436f, 4.639153f, 2.248269f, 5.199394f, 0.601247f, 2.783821f, 0.990810f, 3.821197f, 1.343757f, 6.731155f, 3.523108f, 6.598270f, +0.284929f, 1.080988f, 0.130948f, 1.075281f, 0.507401f, 3.442072f, 1.513534f, 2.849449f, 0.301024f, 1.651725f, 0.533396f, 1.674645f, 0.670629f, 3.981072f, 1.890598f, 2.882488f, +0.776640f, 1.907821f, 0.213502f, 2.605048f, 0.914257f, 4.015786f, 1.631287f, 4.563404f, 0.790796f, 2.809538f, 0.838174f, 3.910185f, 1.298877f, 4.992511f, 2.190310f, 4.962079f, +0.085892f, 0.190658f, 0.027461f, 0.227025f, 0.176853f, 0.701940f, 0.366998f, 0.695599f, 0.034811f, 0.111757f, 0.042912f, 0.135637f, 0.228181f, 0.792529f, 0.447513f, 0.686911f, +0.252632f, 0.807385f, 0.114898f, 1.062454f, 0.456656f, 2.609555f, 1.348014f, 2.857825f, 0.300072f, 1.386982f, 0.526185f, 1.860305f, 0.631226f, 3.156537f, 1.761026f, 3.023476f, +0.095202f, 0.360570f, 0.046557f, 0.350466f, 0.262422f, 1.777157f, 0.832945f, 1.437546f, 0.137896f, 0.755345f, 0.260001f, 0.748317f, 0.289151f, 1.713560f, 0.867395f, 1.212333f, +0.382263f, 0.937427f, 0.111820f, 1.250752f, 0.696544f, 3.054276f, 1.322471f, 3.391420f, 0.533637f, 1.892667f, 0.601855f, 2.573900f, 0.824977f, 3.165558f, 1.480318f, 3.074327f, +0.389420f, 0.591176f, 0.116589f, 0.869977f, 0.503590f, 1.366976f, 0.978578f, 1.674140f, 0.079226f, 0.173948f, 0.091452f, 0.260912f, 0.830838f, 1.973554f, 1.525845f, 2.114006f, +0.889726f, 1.944673f, 0.378922f, 3.162624f, 1.010081f, 3.947580f, 2.792092f, 5.342837f, 0.530487f, 1.676941f, 0.871076f, 2.779731f, 1.785356f, 6.105884f, 4.664167f, 7.227963f, +0.460692f, 1.193300f, 0.210968f, 1.433434f, 0.797557f, 3.693899f, 2.370535f, 3.692775f, 0.334962f, 1.254836f, 0.591409f, 1.536381f, 1.123724f, 4.554406f, 3.156603f, 3.982227f, +1.235772f, 2.072578f, 0.338504f, 3.417559f, 1.414240f, 4.241117f, 2.514369f, 5.820032f, 0.865971f, 2.100529f, 0.914570f, 3.530351f, 2.141852f, 5.620764f, 3.598910f, 6.746319f, +0.202673f, 0.383409f, 0.062380f, 0.568142f, 0.300374f, 1.016048f, 0.600060f, 1.252993f, 0.053032f, 0.145098f, 0.062933f, 0.219149f, 0.360034f, 1.065721f, 0.679752f, 1.149487f, +0.389314f, 1.060372f, 0.170454f, 1.736452f, 0.506533f, 2.466895f, 1.439444f, 3.361979f, 0.298548f, 1.176050f, 0.503976f, 1.962972f, 0.650455f, 2.772102f, 1.746949f, 3.304304f, +0.081503f, 0.263074f, 0.038370f, 0.318207f, 0.161707f, 0.933301f, 0.494115f, 0.939492f, 0.076217f, 0.355805f, 0.138343f, 0.438659f, 0.165527f, 0.836006f, 0.478017f, 0.736050f, +0.512480f, 1.071070f, 0.144317f, 1.778387f, 0.672155f, 2.511857f, 1.228540f, 3.470911f, 0.461890f, 1.396149f, 0.501494f, 2.362785f, 0.739566f, 2.418528f, 1.277533f, 2.922982f, +0.185458f, 0.427458f, 0.053165f, 0.537824f, 0.266628f, 1.098853f, 0.496102f, 1.150605f, 0.064844f, 0.216159f, 0.071671f, 0.277207f, 0.410616f, 1.480871f, 0.722063f, 1.356221f, +0.500691f, 1.661532f, 0.204178f, 2.310286f, 0.631933f, 3.749689f, 1.672594f, 4.339027f, 0.513058f, 2.462399f, 0.806665f, 3.489792f, 1.042628f, 5.413803f, 2.608101f, 5.479310f, +0.231017f, 0.908514f, 0.101296f, 0.933073f, 0.444628f, 3.126577f, 1.265398f, 2.672349f, 0.288673f, 1.641903f, 0.488028f, 1.718761f, 0.584769f, 3.598367f, 1.572860f, 2.690022f, +0.601226f, 1.530944f, 0.157692f, 2.158343f, 0.764935f, 3.482818f, 1.302195f, 4.086316f, 0.724071f, 2.666586f, 0.732218f, 3.831782f, 1.081385f, 4.308592f, 1.739833f, 4.421433f, +0.071701f, 0.164980f, 0.021872f, 0.202831f, 0.159560f, 0.656470f, 0.315911f, 0.671672f, 0.034371f, 0.114380f, 0.040424f, 0.143330f, 0.204855f, 0.737541f, 0.383321f, 0.660017f, +0.179530f, 0.594749f, 0.077903f, 0.808064f, 0.350733f, 2.077579f, 0.987805f, 2.349144f, 0.252216f, 1.208433f, 0.421964f, 1.673473f, 0.482423f, 2.500681f, 1.284099f, 2.473073f, +0.076031f, 0.298493f, 0.035474f, 0.299553f, 0.226506f, 1.590045f, 0.685939f, 1.327971f, 0.130254f, 0.739587f, 0.234318f, 0.756506f, 0.248348f, 1.525595f, 0.710792f, 1.114410f, +0.291484f, 0.740959f, 0.081351f, 1.020729f, 0.574036f, 2.609173f, 1.039840f, 2.991295f, 0.481280f, 1.769414f, 0.517884f, 2.484448f, 0.676533f, 2.690923f, 1.158221f, 2.698261f, +0.414263f, 0.651898f, 0.118333f, 0.990497f, 0.578994f, 1.629154f, 1.073451f, 2.060041f, 0.099684f, 0.226872f, 0.109784f, 0.351349f, 0.950539f, 2.340488f, 1.665534f, 2.588491f, +0.805733f, 1.825515f, 0.327397f, 3.065274f, 0.988619f, 4.005053f, 2.607309f, 5.596701f, 0.568209f, 1.861896f, 0.890183f, 3.186570f, 1.738819f, 6.164275f, 4.334042f, 7.534117f, +0.468855f, 1.258871f, 0.204848f, 1.561320f, 0.877258f, 4.211675f, 2.487722f, 4.347160f, 0.403201f, 1.565731f, 0.679210f, 1.979302f, 1.229933f, 5.167230f, 3.296337f, 4.664821f, +1.200817f, 2.087628f, 0.313828f, 3.554195f, 1.485251f, 4.617012f, 2.519390f, 6.541676f, 0.995269f, 2.502476f, 1.002868f, 4.342522f, 2.238321f, 6.088808f, 3.588340f, 7.545479f, +0.261192f, 0.431811f, 0.069409f, 0.640143f, 0.412163f, 1.218396f, 0.710893f, 1.503183f, 0.059364f, 0.141942f, 0.060823f, 0.214475f, 0.411269f, 1.063882f, 0.670403f, 1.148003f, +0.541738f, 1.289482f, 0.204786f, 2.112558f, 0.750482f, 3.194116f, 1.841324f, 4.354959f, 0.360846f, 1.242226f, 0.525920f, 2.074332f, 0.802280f, 2.988030f, 1.860335f, 3.563237f, +0.094944f, 0.267818f, 0.038591f, 0.324086f, 0.200570f, 1.011640f, 0.529137f, 1.018794f, 0.077119f, 0.314624f, 0.120857f, 0.388057f, 0.170916f, 0.754379f, 0.426146f, 0.664471f, +0.646490f, 1.180782f, 0.157182f, 1.961404f, 0.902812f, 2.948424f, 1.424687f, 4.075938f, 0.506105f, 1.336909f, 0.474429f, 2.263515f, 0.826952f, 2.363316f, 1.233327f, 2.857497f, +0.305503f, 0.615362f, 0.075614f, 0.774580f, 0.467649f, 1.684301f, 0.751253f, 1.764395f, 0.092781f, 0.270289f, 0.088539f, 0.346776f, 0.599548f, 1.889614f, 0.910262f, 1.731313f, +0.890564f, 2.582686f, 0.313550f, 3.592673f, 1.196768f, 6.205851f, 2.734839f, 7.184349f, 0.792647f, 3.324601f, 1.075993f, 4.713784f, 1.643781f, 7.459060f, 3.550107f, 7.552603f, +0.343988f, 1.182222f, 0.130226f, 1.214708f, 0.704920f, 4.331911f, 1.732099f, 3.704183f, 0.373357f, 1.855807f, 0.544961f, 1.943524f, 0.771796f, 4.150415f, 1.792303f, 3.104065f, +0.969457f, 2.157333f, 0.219534f, 3.042758f, 1.313283f, 5.225548f, 1.930245f, 6.133694f, 1.014121f, 3.263862f, 0.885425f, 4.692087f, 1.545574f, 5.381609f, 2.146938f, 5.524956f, +0.142852f, 0.287251f, 0.037623f, 0.353307f, 0.338478f, 1.216992f, 0.578592f, 1.245715f, 0.059480f, 0.172981f, 0.060398f, 0.216857f, 0.361766f, 1.138242f, 0.584448f, 1.019042f, +0.386211f, 1.118121f, 0.144691f, 1.519812f, 0.803354f, 4.158683f, 1.953460f, 4.704322f, 0.471280f, 1.973312f, 0.680744f, 2.733890f, 0.919888f, 4.167084f, 2.114014f, 4.122873f, +0.136925f, 0.469779f, 0.055158f, 0.471652f, 0.434325f, 2.664477f, 1.135595f, 2.226282f, 0.203752f, 1.011037f, 0.316459f, 1.034616f, 0.396435f, 2.128225f, 0.979616f, 1.555293f, +0.568457f, 1.262828f, 0.136977f, 1.740402f, 1.191970f, 4.734741f, 1.864211f, 5.430522f, 0.815265f, 2.619376f, 0.757419f, 3.679487f, 1.169474f, 4.065090f, 1.728605f, 4.077951f, +0.554589f, 0.762678f, 0.136773f, 1.159321f, 0.825300f, 2.029396f, 1.321059f, 2.567258f, 0.115914f, 0.230547f, 0.110219f, 0.357196f, 1.127932f, 2.427095f, 1.706354f, 2.685444f, +1.164692f, 2.306071f, 0.408599f, 3.873875f, 1.521572f, 5.386898f, 3.464642f, 7.530983f, 0.713422f, 2.042966f, 0.964984f, 3.497986f, 2.227887f, 6.902210f, 4.794403f, 8.439710f, +0.567365f, 1.331290f, 0.214023f, 1.651858f, 1.130303f, 4.742307f, 2.767400f, 4.896993f, 0.423803f, 1.438226f, 0.616380f, 1.818909f, 1.319243f, 4.843600f, 3.052652f, 4.374561f, +1.573591f, 2.390758f, 0.355067f, 4.072046f, 2.072326f, 5.629717f, 3.034983f, 7.980014f, 1.132854f, 2.489262f, 0.985553f, 4.321472f, 2.599898f, 6.180641f, 3.598570f, 7.662616f, +0.148224f, 0.194234f, 0.045223f, 0.366227f, 0.140650f, 0.329558f, 0.278525f, 0.517127f, 0.029899f, 0.056666f, 0.035172f, 0.108900f, 0.201111f, 0.412360f, 0.376388f, 0.565937f, +0.136090f, 0.256759f, 0.059064f, 0.535007f, 0.113367f, 0.382447f, 0.319351f, 0.663203f, 0.080452f, 0.219528f, 0.134625f, 0.466239f, 0.173666f, 0.512679f, 0.462348f, 0.777583f, +0.035985f, 0.080458f, 0.016793f, 0.123831f, 0.045713f, 0.182754f, 0.138461f, 0.234083f, 0.025942f, 0.083888f, 0.046677f, 0.131597f, 0.055820f, 0.195286f, 0.159793f, 0.218776f, +0.253532f, 0.367040f, 0.070773f, 0.775448f, 0.212902f, 0.551119f, 0.385738f, 0.969002f, 0.176153f, 0.368829f, 0.189588f, 0.794233f, 0.279449f, 0.633020f, 0.478509f, 0.973470f, +0.154229f, 0.246238f, 0.043827f, 0.394215f, 0.141966f, 0.405281f, 0.261842f, 0.539975f, 0.041571f, 0.095992f, 0.045547f, 0.156637f, 0.260812f, 0.651553f, 0.454631f, 0.759265f, +0.199019f, 0.457482f, 0.080450f, 0.809397f, 0.160824f, 0.661022f, 0.421952f, 0.973292f, 0.157213f, 0.522662f, 0.245024f, 0.942525f, 0.316537f, 1.138513f, 0.784896f, 1.466196f, +0.115983f, 0.315953f, 0.050412f, 0.412892f, 0.142923f, 0.696168f, 0.403203f, 0.757127f, 0.111726f, 0.440185f, 0.187234f, 0.586318f, 0.224235f, 0.955797f, 0.597864f, 0.909173f, +0.338215f, 0.596560f, 0.087934f, 1.070153f, 0.275508f, 0.868922f, 0.464920f, 1.297216f, 0.314002f, 0.801028f, 0.314764f, 1.464615f, 0.464628f, 1.282333f, 0.741011f, 1.674398f, +0.039597f, 0.063112f, 0.011973f, 0.098729f, 0.056418f, 0.160786f, 0.110726f, 0.209325f, 0.014633f, 0.033731f, 0.017060f, 0.053783f, 0.086409f, 0.215495f, 0.160274f, 0.245378f, +0.047389f, 0.108747f, 0.020384f, 0.188001f, 0.059275f, 0.243218f, 0.165486f, 0.349927f, 0.051323f, 0.170334f, 0.085115f, 0.300144f, 0.097261f, 0.349230f, 0.256628f, 0.439461f, +0.025349f, 0.068935f, 0.011724f, 0.088026f, 0.048351f, 0.235110f, 0.145144f, 0.249851f, 0.033478f, 0.131672f, 0.059698f, 0.171375f, 0.063241f, 0.269102f, 0.179421f, 0.250123f, +0.108890f, 0.191737f, 0.030125f, 0.336088f, 0.137299f, 0.432285f, 0.246539f, 0.630604f, 0.138601f, 0.352971f, 0.147841f, 0.630623f, 0.193033f, 0.531844f, 0.327587f, 0.678574f, +0.182021f, 0.198411f, 0.051540f, 0.383592f, 0.162883f, 0.317470f, 0.299347f, 0.510795f, 0.033765f, 0.053231f, 0.036862f, 0.104894f, 0.318996f, 0.544080f, 0.554066f, 0.765655f, +0.169215f, 0.265567f, 0.068158f, 0.567399f, 0.132933f, 0.373037f, 0.347527f, 0.663295f, 0.091993f, 0.208806f, 0.142862f, 0.454716f, 0.278916f, 0.684922f, 0.689135f, 1.065178f, +0.124369f, 0.231310f, 0.053864f, 0.365036f, 0.148989f, 0.495477f, 0.418815f, 0.650736f, 0.082450f, 0.221783f, 0.137679f, 0.356741f, 0.249187f, 0.725173f, 0.662015f, 0.833009f, +0.356907f, 0.429806f, 0.092462f, 0.931087f, 0.282639f, 0.608603f, 0.475249f, 1.097218f, 0.228043f, 0.397179f, 0.227778f, 0.876977f, 0.508125f, 0.957461f, 0.807485f, 1.509754f, +0.243180f, 0.443803f, 0.078449f, 0.636945f, 0.262070f, 0.855195f, 0.548732f, 1.021449f, 0.053193f, 0.140402f, 0.066162f, 0.205384f, 0.413502f, 1.180795f, 0.818269f, 1.233538f, +0.242711f, 0.637741f, 0.111380f, 1.011500f, 0.229626f, 1.078847f, 0.683941f, 1.424038f, 0.155592f, 0.591284f, 0.275292f, 0.955875f, 0.388160f, 1.595875f, 1.092658f, 1.842411f, +0.064376f, 0.200460f, 0.031765f, 0.234842f, 0.092877f, 0.517124f, 0.297451f, 0.504177f, 0.050326f, 0.226644f, 0.095743f, 0.270631f, 0.125148f, 0.609765f, 0.378800f, 0.519968f, +0.436747f, 0.880576f, 0.128908f, 1.416095f, 0.416529f, 1.501645f, 0.797950f, 2.009707f, 0.329060f, 0.959543f, 0.374466f, 1.572803f, 0.603300f, 1.903283f, 1.092292f, 2.227898f, +0.241818f, 0.537692f, 0.072658f, 0.655235f, 0.252798f, 1.005085f, 0.493002f, 1.019311f, 0.070681f, 0.227299f, 0.081881f, 0.282323f, 0.512487f, 1.783038f, 0.944568f, 1.581579f, +0.339213f, 1.085944f, 0.144984f, 1.462451f, 0.311313f, 1.782038f, 0.863628f, 1.997244f, 0.290571f, 1.345367f, 0.478840f, 1.846711f, 0.676138f, 3.386914f, 1.772722f, 3.320051f, +0.198294f, 0.752305f, 0.091132f, 0.748333f, 0.277514f, 1.882584f, 0.827802f, 1.558458f, 0.207136f, 1.136562f, 0.367033f, 1.152334f, 0.480455f, 2.852138f, 1.354471f, 2.065085f, +0.556805f, 1.367794f, 0.153068f, 1.867665f, 0.515125f, 2.262639f, 0.919126f, 2.571186f, 0.560571f, 1.991594f, 0.594155f, 2.771808f, 0.958625f, 3.684681f, 1.616540f, 3.662222f, +0.129822f, 0.288170f, 0.041507f, 0.343137f, 0.210072f, 0.833787f, 0.435932f, 0.826255f, 0.052023f, 0.167014f, 0.064129f, 0.202701f, 0.355035f, 1.233123f, 0.696301f, 1.068789f, +0.168895f, 0.539770f, 0.076814f, 0.710293f, 0.239926f, 1.371058f, 0.708245f, 1.501499f, 0.198352f, 0.916814f, 0.347815f, 1.229687f, 0.434420f, 2.172384f, 1.211968f, 2.080809f, +0.090622f, 0.343220f, 0.044317f, 0.333602f, 0.196311f, 1.329447f, 0.623105f, 1.075393f, 0.129783f, 0.710905f, 0.244704f, 0.704291f, 0.283339f, 1.679117f, 0.849960f, 1.187965f, +0.374849f, 0.919246f, 0.109651f, 1.226493f, 0.536790f, 2.353769f, 1.019159f, 2.613589f, 0.517396f, 1.835064f, 0.583538f, 2.495563f, 0.832787f, 3.195525f, 1.494332f, 3.103431f, +0.308122f, 0.467758f, 0.092249f, 0.688355f, 0.313144f, 0.850016f, 0.608502f, 1.041017f, 0.061980f, 0.136084f, 0.071545f, 0.204118f, 0.676736f, 1.607502f, 1.242834f, 1.721904f, +0.311383f, 0.680590f, 0.132614f, 1.106845f, 0.277816f, 1.085755f, 0.767946f, 1.469510f, 0.183568f, 0.580283f, 0.301424f, 0.961889f, 0.643223f, 2.199812f, 1.680394f, 2.604072f, +0.229565f, 0.594627f, 0.105126f, 0.714287f, 0.312333f, 1.446577f, 0.928331f, 1.446137f, 0.165034f, 0.618251f, 0.291384f, 0.756966f, 0.576438f, 2.336279f, 1.619246f, 2.042768f, +0.634372f, 1.063938f, 0.173768f, 1.754371f, 0.570545f, 1.710989f, 1.014369f, 2.347969f, 0.439533f, 1.066147f, 0.464200f, 1.791868f, 1.131860f, 2.970289f, 1.901841f, 3.565088f, +0.076664f, 0.145030f, 0.023596f, 0.214907f, 0.089293f, 0.302044f, 0.178382f, 0.372482f, 0.019834f, 0.054267f, 0.023537f, 0.081963f, 0.140196f, 0.414989f, 0.264693f, 0.447607f, +0.065137f, 0.177414f, 0.028519f, 0.290531f, 0.066604f, 0.324371f, 0.189272f, 0.442065f, 0.049389f, 0.194553f, 0.083372f, 0.324733f, 0.112033f, 0.477459f, 0.300890f, 0.569124f, +0.019416f, 0.062671f, 0.009141f, 0.075804f, 0.030274f, 0.174730f, 0.092507f, 0.175889f, 0.017952f, 0.083807f, 0.032586f, 0.103322f, 0.040593f, 0.205018f, 0.117226f, 0.180505f, +0.125769f, 0.262853f, 0.035417f, 0.436437f, 0.129636f, 0.484453f, 0.236944f, 0.669423f, 0.112077f, 0.338774f, 0.121687f, 0.573327f, 0.186840f, 0.611004f, 0.322750f, 0.738447f, +0.067357f, 0.155250f, 0.019309f, 0.195334f, 0.076104f, 0.313646f, 0.141602f, 0.328417f, 0.023286f, 0.077624f, 0.025737f, 0.099546f, 0.153522f, 0.553673f, 0.269967f, 0.507069f, +0.080434f, 0.266920f, 0.032801f, 0.371141f, 0.079782f, 0.473401f, 0.211166f, 0.547806f, 0.081493f, 0.391124f, 0.128129f, 0.554313f, 0.172425f, 0.895309f, 0.431315f, 0.906142f, +0.052841f, 0.207807f, 0.023170f, 0.213424f, 0.079926f, 0.562030f, 0.227466f, 0.480378f, 0.065286f, 0.371329f, 0.110371f, 0.388711f, 0.137693f, 0.847290f, 0.370354f, 0.633406f, +0.141670f, 0.360743f, 0.037158f, 0.508580f, 0.141653f, 0.644958f, 0.241144f, 0.756715f, 0.168695f, 0.621266f, 0.170593f, 0.892735f, 0.262311f, 1.045135f, 0.422031f, 1.072506f, +0.035618f, 0.081956f, 0.010865f, 0.100759f, 0.062292f, 0.256287f, 0.123332f, 0.262221f, 0.016882f, 0.056180f, 0.019855f, 0.070399f, 0.104760f, 0.377167f, 0.196024f, 0.337522f, +0.039448f, 0.130682f, 0.017117f, 0.177554f, 0.060565f, 0.358759f, 0.170575f, 0.405653f, 0.054795f, 0.262536f, 0.091673f, 0.363567f, 0.109121f, 0.565640f, 0.290456f, 0.559395f, +0.023786f, 0.093384f, 0.011098f, 0.093716f, 0.055690f, 0.390940f, 0.168650f, 0.326505f, 0.040292f, 0.228777f, 0.072482f, 0.234010f, 0.079983f, 0.491334f, 0.228918f, 0.358907f, +0.093943f, 0.238805f, 0.026219f, 0.328973f, 0.145395f, 0.660868f, 0.263377f, 0.757654f, 0.153366f, 0.563848f, 0.165031f, 0.791704f, 0.224459f, 0.892789f, 0.384273f, 0.895224f, +0.107730f, 0.169527f, 0.030773f, 0.257581f, 0.118330f, 0.332954f, 0.219384f, 0.421015f, 0.025631f, 0.058334f, 0.028228f, 0.090340f, 0.254465f, 0.626563f, 0.445874f, 0.692955f, +0.092680f, 0.209981f, 0.037659f, 0.352585f, 0.089369f, 0.362047f, 0.235694f, 0.505928f, 0.064623f, 0.211755f, 0.101241f, 0.362411f, 0.205896f, 0.729919f, 0.513199f, 0.892124f, +0.076787f, 0.206173f, 0.033549f, 0.255707f, 0.112912f, 0.542085f, 0.320195f, 0.559523f, 0.065291f, 0.253543f, 0.109986f, 0.320513f, 0.207363f, 0.871178f, 0.555751f, 0.786473f, +0.202599f, 0.352220f, 0.052948f, 0.599657f, 0.196935f, 0.612187f, 0.334055f, 0.867385f, 0.166029f, 0.417459f, 0.167297f, 0.724413f, 0.388760f, 1.057527f, 0.623236f, 1.310527f, +0.205142f, 0.339147f, 0.054514f, 0.502772f, 0.254405f, 0.752046f, 0.438793f, 0.927829f, 0.046100f, 0.110227f, 0.047233f, 0.166554f, 0.332520f, 0.860173f, 0.542036f, 0.928187f, +0.188199f, 0.447965f, 0.071142f, 0.733901f, 0.204895f, 0.872049f, 0.502714f, 1.188980f, 0.123946f, 0.426690f, 0.180647f, 0.712508f, 0.286915f, 1.068591f, 0.665301f, 1.274299f, +0.046962f, 0.132472f, 0.019088f, 0.160304f, 0.077967f, 0.393253f, 0.205691f, 0.396034f, 0.037717f, 0.153872f, 0.059107f, 0.189785f, 0.087029f, 0.384124f, 0.216991f, 0.338344f, +0.329425f, 0.601679f, 0.080094f, 0.999453f, 0.361538f, 1.180719f, 0.570527f, 1.632241f, 0.254987f, 0.673565f, 0.239028f, 1.140411f, 0.433784f, 1.239695f, 0.646951f, 1.498921f, +0.230384f, 0.464054f, 0.057022f, 0.584123f, 0.277153f, 0.998204f, 0.445231f, 1.045672f, 0.069180f, 0.201535f, 0.066017f, 0.258565f, 0.465436f, 1.466929f, 0.706646f, 1.344037f, +0.297055f, 0.861478f, 0.104587f, 1.198368f, 0.313721f, 1.626804f, 0.716912f, 1.883308f, 0.261418f, 1.096465f, 0.354866f, 1.554622f, 0.564435f, 2.561264f, 1.219022f, 2.593384f, +0.163370f, 0.561471f, 0.061848f, 0.576900f, 0.263105f, 1.616849f, 0.646491f, 1.382555f, 0.175322f, 0.871453f, 0.255904f, 0.912643f, 0.377337f, 2.029166f, 0.876269f, 1.517599f, +0.474315f, 1.055494f, 0.107409f, 1.488696f, 0.504962f, 2.009241f, 0.742186f, 2.358426f, 0.490582f, 1.578895f, 0.428325f, 2.269799f, 0.778442f, 2.710495f, 1.081325f, 2.782693f, +0.147345f, 0.296285f, 0.038806f, 0.364419f, 0.274373f, 0.986502f, 0.469011f, 1.009786f, 0.060660f, 0.176413f, 0.061596f, 0.221160f, 0.384127f, 1.208597f, 0.620573f, 1.082029f, +0.176201f, 0.510120f, 0.066012f, 0.693383f, 0.288039f, 1.491079f, 0.700406f, 1.686716f, 0.212591f, 0.890147f, 0.307079f, 1.233239f, 0.432032f, 1.957102f, 0.992862f, 1.936338f, +0.088945f, 0.305164f, 0.035830f, 0.306381f, 0.221725f, 1.360232f, 0.579728f, 1.136530f, 0.130865f, 0.649365f, 0.203255f, 0.664510f, 0.265099f, 1.423163f, 0.655078f, 1.040038f, +0.380406f, 0.845072f, 0.091664f, 1.164660f, 0.626869f, 2.490047f, 0.980407f, 2.855965f, 0.539425f, 1.733127f, 0.501151f, 2.434556f, 0.805634f, 2.800385f, 1.190813f, 2.809244f, +0.299455f, 0.411814f, 0.073852f, 0.625985f, 0.350214f, 0.861170f, 0.560589f, 1.089410f, 0.061884f, 0.123084f, 0.058843f, 0.190700f, 0.626962f, 1.349103f, 0.948478f, 1.492706f, +0.278167f, 0.550766f, 0.097587f, 0.925210f, 0.285594f, 1.011102f, 0.650301f, 1.413539f, 0.168471f, 0.482435f, 0.227876f, 0.826029f, 0.547754f, 1.696996f, 1.178765f, 2.075010f, +0.192936f, 0.452713f, 0.072780f, 0.561724f, 0.302070f, 1.267365f, 0.739578f, 1.308705f, 0.142494f, 0.483571f, 0.207244f, 0.611568f, 0.461821f, 1.695574f, 1.068626f, 1.531380f, +0.551256f, 0.837523f, 0.124386f, 1.426506f, 0.570533f, 1.549920f, 0.835562f, 2.196981f, 0.392390f, 0.862213f, 0.341369f, 1.496841f, 0.937595f, 2.228909f, 1.297744f, 2.763350f, +0.098139f, 0.128602f, 0.029942f, 0.242478f, 0.119117f, 0.279104f, 0.235883f, 0.437955f, 0.023328f, 0.044211f, 0.027441f, 0.084965f, 0.146332f, 0.300041f, 0.273867f, 0.411786f, +0.120619f, 0.227570f, 0.052350f, 0.474188f, 0.128525f, 0.433583f, 0.362050f, 0.751878f, 0.084026f, 0.229280f, 0.140605f, 0.486951f, 0.169155f, 0.499365f, 0.450340f, 0.757389f, +0.024852f, 0.055566f, 0.011598f, 0.085520f, 0.040381f, 0.161441f, 0.122313f, 0.206783f, 0.021112f, 0.068269f, 0.037986f, 0.107095f, 0.042365f, 0.148214f, 0.121276f, 0.166042f, +0.234516f, 0.339511f, 0.065464f, 0.717287f, 0.251901f, 0.652073f, 0.456396f, 1.146502f, 0.192007f, 0.402023f, 0.206651f, 0.865714f, 0.284069f, 0.643485f, 0.486420f, 0.989564f, +0.138245f, 0.220718f, 0.039285f, 0.353358f, 0.162770f, 0.464674f, 0.300215f, 0.619107f, 0.043910f, 0.101391f, 0.048109f, 0.165448f, 0.256916f, 0.641819f, 0.447840f, 0.747923f, +0.238806f, 0.548939f, 0.096533f, 0.971207f, 0.246837f, 1.014555f, 0.647624f, 1.493836f, 0.222292f, 0.739022f, 0.346453f, 1.332689f, 0.417403f, 1.501306f, 1.035007f, 1.933406f, +0.108440f, 0.295405f, 0.047134f, 0.386040f, 0.170926f, 0.832569f, 0.482203f, 0.905471f, 0.123094f, 0.484972f, 0.206284f, 0.645975f, 0.230399f, 0.982071f, 0.614299f, 0.934165f, +0.423537f, 0.747057f, 0.110117f, 1.340125f, 0.441309f, 1.391842f, 0.744710f, 2.077886f, 0.463360f, 1.182044f, 0.464484f, 2.161271f, 0.639419f, 1.764742f, 1.019777f, 2.304301f, +0.030338f, 0.048354f, 0.009174f, 0.075643f, 0.055291f, 0.157574f, 0.108514f, 0.205143f, 0.013211f, 0.030454f, 0.015402f, 0.048557f, 0.072755f, 0.181444f, 0.134949f, 0.206605f, +0.048604f, 0.111534f, 0.020906f, 0.192820f, 0.077763f, 0.319078f, 0.217101f, 0.459071f, 0.062028f, 0.205864f, 0.102869f, 0.362750f, 0.109626f, 0.393627f, 0.289252f, 0.495329f, +0.020258f, 0.055091f, 0.009369f, 0.070348f, 0.049425f, 0.240337f, 0.148371f, 0.255405f, 0.031527f, 0.123999f, 0.056219f, 0.161388f, 0.055541f, 0.236340f, 0.157576f, 0.219671f, +0.116554f, 0.205233f, 0.032245f, 0.359745f, 0.187982f, 0.591864f, 0.337549f, 0.863393f, 0.174821f, 0.445212f, 0.186476f, 0.795422f, 0.227067f, 0.625614f, 0.385344f, 0.798215f, +0.223295f, 0.243401f, 0.063226f, 0.470572f, 0.255588f, 0.498160f, 0.469723f, 0.801518f, 0.048810f, 0.076950f, 0.053287f, 0.151633f, 0.430054f, 0.733500f, 0.746963f, 1.032216f, +0.277884f, 0.436113f, 0.111928f, 0.931779f, 0.279233f, 0.783586f, 0.730000f, 1.393288f, 0.178018f, 0.404066f, 0.276458f, 0.879935f, 0.503360f, 1.236081f, 1.243684f, 1.922328f, +0.159141f, 0.295982f, 0.068924f, 0.467096f, 0.243857f, 0.810968f, 0.685492f, 1.065086f, 0.124322f, 0.334414f, 0.207598f, 0.537910f, 0.350410f, 1.019749f, 0.930934f, 1.171388f, +0.611686f, 0.736624f, 0.158466f, 1.595747f, 0.619607f, 1.334192f, 1.041849f, 2.405341f, 0.460549f, 0.802132f, 0.460015f, 1.771122f, 0.957030f, 1.803334f, 1.520860f, 2.843551f, +0.172318f, 0.314480f, 0.055590f, 0.451341f, 0.237537f, 0.775138f, 0.497363f, 0.925828f, 0.044417f, 0.117236f, 0.055245f, 0.171497f, 0.322005f, 0.919516f, 0.637207f, 0.960588f, +0.230230f, 0.604945f, 0.105652f, 0.959483f, 0.278614f, 1.309005f, 0.829851f, 1.727837f, 0.173919f, 0.660927f, 0.307717f, 1.068461f, 0.404635f, 1.663608f, 1.139034f, 1.920609f, +0.047582f, 0.148165f, 0.023479f, 0.173577f, 0.087808f, 0.488902f, 0.281218f, 0.476661f, 0.043832f, 0.197401f, 0.083389f, 0.235712f, 0.101654f, 0.495291f, 0.307687f, 0.422353f, +0.432365f, 0.871741f, 0.127615f, 1.401887f, 0.527444f, 1.901507f, 1.010431f, 2.544857f, 0.383868f, 1.119365f, 0.436837f, 1.834768f, 0.656350f, 2.070643f, 1.188340f, 2.423803f, +0.231981f, 0.515818f, 0.069702f, 0.628579f, 0.310204f, 1.233319f, 0.604952f, 1.250776f, 0.079901f, 0.256949f, 0.092562f, 0.319150f, 0.540290f, 1.879769f, 0.995811f, 1.667381f, +0.435615f, 1.394561f, 0.186188f, 1.878070f, 0.511372f, 2.927234f, 1.418623f, 3.280738f, 0.439713f, 2.035905f, 0.724614f, 2.794575f, 0.954217f, 4.779866f, 2.501798f, 4.685504f, +0.198420f, 0.752783f, 0.091190f, 0.748809f, 0.355199f, 2.409576f, 1.059529f, 1.994718f, 0.244241f, 1.340158f, 0.432781f, 1.358754f, 0.528337f, 3.136376f, 1.489454f, 2.270887f, +0.746247f, 1.833160f, 0.205147f, 2.503103f, 0.883086f, 3.878869f, 1.575669f, 4.407816f, 0.885312f, 3.145336f, 0.938353f, 4.377531f, 1.411920f, 5.427014f, 2.380935f, 5.393935f, +0.106451f, 0.236294f, 0.034035f, 0.281366f, 0.220335f, 0.874520f, 0.457229f, 0.866620f, 0.050268f, 0.161377f, 0.061965f, 0.195860f, 0.319932f, 1.111200f, 0.627455f, 0.963114f, +0.185391f, 0.592490f, 0.084317f, 0.779669f, 0.336869f, 1.925033f, 0.994411f, 2.108178f, 0.256563f, 1.185878f, 0.449891f, 1.590572f, 0.524039f, 2.620536f, 1.461991f, 2.510069f, +0.077509f, 0.293556f, 0.037904f, 0.285330f, 0.214770f, 1.454451f, 0.681695f, 1.176509f, 0.130804f, 0.716500f, 0.246630f, 0.709833f, 0.266321f, 1.578267f, 0.798910f, 1.116614f, +0.429416f, 1.053061f, 0.125613f, 1.405034f, 0.786567f, 3.449020f, 1.493392f, 3.829738f, 0.698444f, 2.477190f, 0.787729f, 3.368811f, 1.048424f, 4.022955f, 1.881265f, 3.907014f, +0.404538f, 0.614127f, 0.121115f, 0.903752f, 0.525885f, 1.427494f, 1.021901f, 1.748256f, 0.095891f, 0.210538f, 0.110689f, 0.315794f, 0.976422f, 2.319369f, 1.793211f, 2.484432f, +0.547268f, 1.196163f, 0.233074f, 1.945321f, 0.624556f, 2.440880f, 1.726415f, 3.303600f, 0.380178f, 1.201796f, 0.624265f, 1.992121f, 1.242361f, 4.248851f, 3.245615f, 5.029663f, +0.314381f, 0.814321f, 0.143966f, 0.978190f, 0.547115f, 2.533975f, 1.626162f, 2.533204f, 0.266324f, 0.997704f, 0.470222f, 1.221557f, 0.867530f, 3.516062f, 2.436939f, 3.074332f, +1.163585f, 1.951509f, 0.318731f, 3.217923f, 1.338611f, 4.014316f, 2.379909f, 5.508795f, 0.950019f, 2.304398f, 1.003335f, 3.872992f, 2.281540f, 5.987342f, 3.833626f, 7.186304f, +0.089752f, 0.169789f, 0.027625f, 0.251597f, 0.133716f, 0.452308f, 0.267125f, 0.557787f, 0.027363f, 0.074865f, 0.032471f, 0.113072f, 0.180372f, 0.533913f, 0.340547f, 0.575879f, +0.102082f, 0.278041f, 0.044695f, 0.455316f, 0.133515f, 0.650238f, 0.379417f, 0.886169f, 0.091208f, 0.359290f, 0.153967f, 0.599699f, 0.192951f, 0.822315f, 0.518214f, 0.980187f, +0.023710f, 0.076530f, 0.011162f, 0.092568f, 0.047288f, 0.272926f, 0.144495f, 0.274736f, 0.025833f, 0.120596f, 0.046890f, 0.148678f, 0.054475f, 0.275131f, 0.157316f, 0.242236f, +0.205704f, 0.429916f, 0.057927f, 0.713826f, 0.271211f, 1.013520f, 0.495709f, 1.400493f, 0.216010f, 0.652930f, 0.234531f, 1.104992f, 0.335832f, 1.098237f, 0.580119f, 1.327306f, +0.106757f, 0.246062f, 0.030604f, 0.309593f, 0.154287f, 0.635860f, 0.287073f, 0.665807f, 0.043490f, 0.144975f, 0.048069f, 0.185919f, 0.267402f, 0.964377f, 0.470224f, 0.883202f, +0.170656f, 0.566319f, 0.069592f, 0.787442f, 0.216519f, 1.284753f, 0.573079f, 1.486677f, 0.203745f, 0.977868f, 0.320343f, 1.385866f, 0.402033f, 2.087537f, 1.005672f, 2.112797f, +0.087357f, 0.343547f, 0.038304f, 0.352834f, 0.169014f, 1.188490f, 0.481009f, 1.015826f, 0.127183f, 0.723388f, 0.215015f, 0.757250f, 0.250160f, 1.539356f, 0.672859f, 1.150773f, +0.313694f, 0.798781f, 0.082277f, 1.126131f, 0.401203f, 1.826716f, 0.682993f, 2.143247f, 0.440168f, 1.621038f, 0.445121f, 2.329370f, 0.638305f, 2.543214f, 1.026964f, 2.609820f, +0.048254f, 0.111029f, 0.014719f, 0.136501f, 0.107944f, 0.444110f, 0.213717f, 0.454394f, 0.026950f, 0.089686f, 0.031697f, 0.112385f, 0.155966f, 0.561525f, 0.291840f, 0.502502f, +0.071539f, 0.236995f, 0.031043f, 0.321997f, 0.140493f, 0.832214f, 0.395684f, 0.940994f, 0.117097f, 0.561044f, 0.195907f, 0.776951f, 0.217477f, 1.127309f, 0.578873f, 1.114863f, +0.033612f, 0.131960f, 0.015683f, 0.132428f, 0.100660f, 0.706624f, 0.304835f, 0.590157f, 0.067092f, 0.380948f, 0.120693f, 0.389663f, 0.124207f, 0.763003f, 0.355491f, 0.557354f, +0.177802f, 0.451976f, 0.049623f, 0.622633f, 0.351992f, 1.599912f, 0.637617f, 1.834224f, 0.342049f, 1.257535f, 0.368064f, 1.765714f, 0.466863f, 1.856957f, 0.799268f, 1.862021f, +0.233681f, 0.367728f, 0.066750f, 0.558728f, 0.328317f, 0.923807f, 0.608697f, 1.168140f, 0.065515f, 0.149107f, 0.072153f, 0.230916f, 0.606592f, 1.493595f, 1.062870f, 1.651859f, +0.269117f, 0.609726f, 0.109351f, 1.023808f, 0.331933f, 1.344712f, 0.875414f, 1.879114f, 0.221119f, 0.724560f, 0.346416f, 1.240058f, 0.657026f, 2.329220f, 1.637652f, 2.846826f, +0.173736f, 0.466479f, 0.075907f, 0.578553f, 0.326776f, 1.568837f, 0.926669f, 1.619305f, 0.174077f, 0.675986f, 0.293241f, 0.854540f, 0.515599f, 2.166149f, 1.381853f, 1.955534f, +0.613963f, 1.067378f, 0.160457f, 1.817216f, 0.763373f, 2.373001f, 1.294888f, 3.362219f, 0.592891f, 1.490748f, 0.597418f, 2.586881f, 1.294693f, 3.521897f, 2.075572f, 4.364466f, +0.108339f, 0.179110f, 0.028790f, 0.265523f, 0.171857f, 0.508026f, 0.296416f, 0.626772f, 0.028689f, 0.068597f, 0.029394f, 0.103651f, 0.192988f, 0.499227f, 0.314587f, 0.538702f, +0.133051f, 0.316696f, 0.050295f, 0.518844f, 0.185285f, 0.788588f, 0.454601f, 1.075186f, 0.103257f, 0.355466f, 0.150493f, 0.593575f, 0.222912f, 0.830218f, 0.516890f, 0.990038f, +0.025870f, 0.072974f, 0.010515f, 0.088306f, 0.054937f, 0.277094f, 0.144934f, 0.279054f, 0.024483f, 0.099883f, 0.038368f, 0.123195f, 0.052685f, 0.232540f, 0.131361f, 0.204826f, +0.243056f, 0.443929f, 0.059095f, 0.737413f, 0.341203f, 1.114309f, 0.538437f, 1.540434f, 0.221694f, 0.585619f, 0.207818f, 0.991508f, 0.351725f, 1.005182f, 0.524567f, 1.215371f, +0.164719f, 0.331787f, 0.040769f, 0.417633f, 0.253466f, 0.912894f, 0.407180f, 0.956304f, 0.058285f, 0.169796f, 0.055620f, 0.217845f, 0.365706f, 1.152606f, 0.555232f, 1.056047f, +0.284312f, 0.824522f, 0.100101f, 1.146961f, 0.384072f, 1.991608f, 0.877676f, 2.305631f, 0.294836f, 1.236629f, 0.400230f, 1.753354f, 0.593682f, 2.693978f, 1.282187f, 2.727762f, +0.121836f, 0.418728f, 0.046124f, 0.430234f, 0.250983f, 1.542353f, 0.616704f, 1.318854f, 0.154073f, 0.765834f, 0.224888f, 0.802032f, 0.309253f, 1.663042f, 0.718163f, 1.243777f, +0.473778f, 1.054299f, 0.107287f, 1.487010f, 0.645173f, 2.567143f, 0.948267f, 3.013286f, 0.577438f, 1.858435f, 0.504159f, 2.671663f, 0.854507f, 2.975348f, 1.186985f, 3.054601f, +0.090047f, 0.181068f, 0.023715f, 0.222707f, 0.214478f, 0.771154f, 0.366628f, 0.789354f, 0.043684f, 0.127043f, 0.044358f, 0.159267f, 0.257982f, 0.811700f, 0.416780f, 0.726696f, +0.144148f, 0.417323f, 0.054004f, 0.567249f, 0.301413f, 1.560311f, 0.732926f, 1.765031f, 0.204942f, 0.858121f, 0.296031f, 1.188869f, 0.388416f, 1.759524f, 0.892628f, 1.740856f, +0.056698f, 0.194527f, 0.022840f, 0.195302f, 0.180789f, 1.109096f, 0.472695f, 0.926696f, 0.098301f, 0.487777f, 0.152677f, 0.499153f, 0.185710f, 0.996970f, 0.458903f, 0.728579f, +0.324786f, 0.721512f, 0.078261f, 0.994372f, 0.684599f, 2.719365f, 1.070696f, 3.118982f, 0.542709f, 1.743679f, 0.504202f, 2.449379f, 0.755908f, 2.627537f, 1.117312f, 2.635850f, +0.293019f, 0.402964f, 0.072265f, 0.612533f, 0.438338f, 1.077864f, 0.701648f, 1.363536f, 0.071356f, 0.141924f, 0.067850f, 0.219888f, 0.674198f, 1.450746f, 1.019938f, 1.605168f, +0.364367f, 0.721440f, 0.127828f, 1.211918f, 0.478511f, 1.694096f, 1.089576f, 2.368377f, 0.260042f, 0.744660f, 0.351736f, 1.275013f, 0.788497f, 2.442839f, 1.696841f, 2.986993f, +0.196921f, 0.462064f, 0.074283f, 0.573326f, 0.394363f, 1.654591f, 0.965546f, 1.708561f, 0.171381f, 0.581602f, 0.249257f, 0.735545f, 0.518004f, 1.901852f, 1.198632f, 1.717683f, +0.753590f, 1.144930f, 0.170041f, 1.950096f, 0.997638f, 2.710201f, 1.461071f, 3.841658f, 0.632101f, 1.388939f, 0.549911f, 2.411261f, 1.408571f, 3.348543f, 1.949631f, 4.151447f, +0.051926f, 0.068044f, 0.015843f, 0.128296f, 0.058398f, 0.136833f, 0.115644f, 0.214711f, 0.011538f, 0.021868f, 0.013573f, 0.042026f, 0.076876f, 0.157627f, 0.143876f, 0.216333f, +0.065544f, 0.123661f, 0.028447f, 0.257672f, 0.064713f, 0.218310f, 0.182293f, 0.378572f, 0.042684f, 0.116472f, 0.071426f, 0.247366f, 0.091267f, 0.269429f, 0.242978f, 0.408644f, +0.015784f, 0.035291f, 0.007366f, 0.054316f, 0.023764f, 0.095007f, 0.071980f, 0.121690f, 0.012535f, 0.040534f, 0.022554f, 0.063586f, 0.026716f, 0.093466f, 0.076479f, 0.104709f, +0.112837f, 0.163356f, 0.031498f, 0.345122f, 0.112304f, 0.290710f, 0.203473f, 0.511139f, 0.086364f, 0.180829f, 0.092951f, 0.389396f, 0.135710f, 0.307417f, 0.232381f, 0.472752f, +0.073907f, 0.117998f, 0.021002f, 0.188909f, 0.080630f, 0.230181f, 0.148714f, 0.306681f, 0.021945f, 0.050673f, 0.024044f, 0.082687f, 0.136376f, 0.340690f, 0.237722f, 0.397012f, +0.131117f, 0.301396f, 0.053002f, 0.533243f, 0.125577f, 0.516146f, 0.329473f, 0.759977f, 0.114097f, 0.379322f, 0.177826f, 0.684037f, 0.227551f, 0.818449f, 0.564242f, 1.054012f, +0.069589f, 0.189571f, 0.030247f, 0.247734f, 0.101635f, 0.495059f, 0.286726f, 0.538408f, 0.073846f, 0.290943f, 0.123753f, 0.387531f, 0.146806f, 0.625756f, 0.391419f, 0.595232f, +0.205906f, 0.363187f, 0.053534f, 0.651511f, 0.198794f, 0.626976f, 0.335466f, 0.936014f, 0.210588f, 0.537214f, 0.211098f, 0.982253f, 0.308654f, 0.851857f, 0.492256f, 1.112308f, +0.017654f, 0.028137f, 0.005338f, 0.044017f, 0.029812f, 0.084961f, 0.058508f, 0.110609f, 0.007187f, 0.016566f, 0.008379f, 0.026414f, 0.042036f, 0.104834f, 0.077970f, 0.119371f, +0.029047f, 0.066655f, 0.012494f, 0.115233f, 0.043061f, 0.176688f, 0.120219f, 0.254208f, 0.034654f, 0.115012f, 0.057471f, 0.202661f, 0.065050f, 0.233571f, 0.171637f, 0.293920f, +0.014150f, 0.038481f, 0.006545f, 0.049138f, 0.031989f, 0.155550f, 0.096028f, 0.165302f, 0.020587f, 0.080970f, 0.036710f, 0.105384f, 0.038520f, 0.163912f, 0.109286f, 0.152352f, +0.061676f, 0.108602f, 0.017063f, 0.190363f, 0.092170f, 0.290198f, 0.165505f, 0.423332f, 0.086481f, 0.220239f, 0.092246f, 0.393481f, 0.119303f, 0.328704f, 0.202463f, 0.419390f, +0.101837f, 0.111007f, 0.028836f, 0.214613f, 0.108008f, 0.210515f, 0.198497f, 0.338709f, 0.020810f, 0.032807f, 0.022719f, 0.064649f, 0.194743f, 0.332153f, 0.338250f, 0.467422f, +0.130158f, 0.204270f, 0.052426f, 0.436434f, 0.121187f, 0.340076f, 0.316819f, 0.604686f, 0.077948f, 0.176927f, 0.121052f, 0.385295f, 0.234095f, 0.574859f, 0.578395f, 0.894009f, +0.087122f, 0.162035f, 0.037732f, 0.255712f, 0.123699f, 0.411370f, 0.347722f, 0.540274f, 0.063625f, 0.171146f, 0.106244f, 0.275291f, 0.190472f, 0.554303f, 0.506026f, 0.636729f, +0.253686f, 0.305502f, 0.065721f, 0.661809f, 0.238105f, 0.512709f, 0.400366f, 0.924334f, 0.178559f, 0.310994f, 0.178352f, 0.686680f, 0.394097f, 0.742598f, 0.626277f, 1.170950f, +0.080074f, 0.146134f, 0.025832f, 0.209731f, 0.102276f, 0.333750f, 0.214149f, 0.398632f, 0.019295f, 0.050928f, 0.023999f, 0.074499f, 0.148570f, 0.424254f, 0.294000f, 0.443205f, +0.109874f, 0.288702f, 0.050421f, 0.457901f, 0.123203f, 0.578841f, 0.366959f, 0.764048f, 0.077592f, 0.294866f, 0.137285f, 0.476684f, 0.191737f, 0.788305f, 0.539734f, 0.910085f, +0.026541f, 0.082645f, 0.013096f, 0.096821f, 0.045383f, 0.252685f, 0.145345f, 0.246359f, 0.022856f, 0.102934f, 0.043483f, 0.122912f, 0.056300f, 0.274311f, 0.170409f, 0.233915f, +0.182704f, 0.368370f, 0.053926f, 0.592394f, 0.206518f, 0.744525f, 0.395629f, 0.996425f, 0.151641f, 0.442187f, 0.172566f, 0.724796f, 0.275386f, 0.868783f, 0.498594f, 1.016959f, +0.108920f, 0.242187f, 0.032727f, 0.295131f, 0.134954f, 0.536555f, 0.263184f, 0.544149f, 0.035070f, 0.112782f, 0.040628f, 0.140083f, 0.251878f, 0.876331f, 0.464238f, 0.777317f, +0.210055f, 0.672463f, 0.089781f, 0.905613f, 0.228482f, 1.307892f, 0.633843f, 1.465838f, 0.198215f, 0.917753f, 0.326644f, 1.259748f, 0.456864f, 2.288524f, 1.197821f, 2.243344f, +0.111829f, 0.424268f, 0.051395f, 0.422028f, 0.185492f, 1.258331f, 0.553308f, 1.041684f, 0.128685f, 0.706096f, 0.228021f, 0.715894f, 0.295658f, 1.755123f, 0.833502f, 1.270793f, +0.318623f, 0.782698f, 0.087591f, 1.068741f, 0.349366f, 1.534556f, 0.623365f, 1.743818f, 0.353368f, 1.255447f, 0.374539f, 1.747272f, 0.598567f, 2.300720f, 1.009370f, 2.286696f, +0.054402f, 0.120759f, 0.017394f, 0.143793f, 0.104336f, 0.414114f, 0.216513f, 0.410374f, 0.024016f, 0.077099f, 0.029604f, 0.093573f, 0.162343f, 0.563856f, 0.318390f, 0.488713f, +0.097304f, 0.310974f, 0.044254f, 0.409217f, 0.163828f, 0.936192f, 0.483608f, 1.025261f, 0.125885f, 0.581863f, 0.220744f, 0.780430f, 0.273096f, 1.365659f, 0.761898f, 1.308091f, +0.047548f, 0.180084f, 0.023252f, 0.175037f, 0.122079f, 0.826734f, 0.387487f, 0.668747f, 0.075014f, 0.410900f, 0.141438f, 0.407077f, 0.162217f, 0.961329f, 0.486620f, 0.680134f, +0.199565f, 0.489395f, 0.058377f, 0.652970f, 0.338709f, 1.485203f, 0.643078f, 1.649146f, 0.303441f, 1.076225f, 0.342232f, 1.463593f, 0.483785f, 1.856352f, 0.868091f, 1.802853f, +0.162034f, 0.245983f, 0.048511f, 0.361989f, 0.195173f, 0.529791f, 0.379262f, 0.648837f, 0.035906f, 0.078834f, 0.041446f, 0.118247f, 0.388323f, 0.922412f, 0.713159f, 0.988058f, +0.225125f, 0.492054f, 0.095877f, 0.800228f, 0.238055f, 0.930364f, 0.658039f, 1.259197f, 0.146200f, 0.462158f, 0.240065f, 0.766083f, 0.507434f, 1.735413f, 1.325649f, 2.054330f, +0.151154f, 0.391523f, 0.069219f, 0.470311f, 0.243739f, 1.128882f, 0.724452f, 1.128538f, 0.119704f, 0.448437f, 0.211350f, 0.549052f, 0.414148f, 1.678525f, 1.163365f, 1.467648f, +0.423822f, 0.710814f, 0.116094f, 1.172091f, 0.451777f, 1.354818f, 0.803211f, 1.859200f, 0.323486f, 0.784658f, 0.341640f, 1.318772f, 0.825131f, 2.165352f, 1.386450f, 2.598963f, +0.050636f, 0.095791f, 0.015585f, 0.141945f, 0.069901f, 0.236447f, 0.139641f, 0.291587f, 0.014431f, 0.039485f, 0.017126f, 0.059636f, 0.101040f, 0.299086f, 0.190767f, 0.322594f, +0.059148f, 0.161102f, 0.025897f, 0.263818f, 0.071681f, 0.349099f, 0.203701f, 0.475765f, 0.049404f, 0.194614f, 0.083398f, 0.324835f, 0.111006f, 0.473085f, 0.298133f, 0.563910f, +0.016057f, 0.051828f, 0.007559f, 0.062689f, 0.029674f, 0.171262f, 0.090671f, 0.172398f, 0.016355f, 0.076349f, 0.029686f, 0.094128f, 0.036630f, 0.185004f, 0.105783f, 0.162884f, +0.105535f, 0.220566f, 0.029719f, 0.366224f, 0.128928f, 0.481805f, 0.235649f, 0.665763f, 0.103601f, 0.313155f, 0.112485f, 0.529971f, 0.171075f, 0.559448f, 0.295516f, 0.676137f, +0.060857f, 0.140267f, 0.017446f, 0.176483f, 0.081494f, 0.335860f, 0.151631f, 0.351678f, 0.023176f, 0.077258f, 0.025616f, 0.099077f, 0.151351f, 0.545844f, 0.266150f, 0.499898f, +0.099910f, 0.331551f, 0.040743f, 0.461006f, 0.117454f, 0.696934f, 0.310876f, 0.806471f, 0.111510f, 0.535188f, 0.175324f, 0.758485f, 0.233700f, 1.213477f, 0.584593f, 1.228160f, +0.059776f, 0.235079f, 0.026211f, 0.241434f, 0.107161f, 0.753542f, 0.304976f, 0.644067f, 0.081357f, 0.462740f, 0.137542f, 0.484401f, 0.169963f, 1.045867f, 0.457152f, 0.781856f, +0.162614f, 0.414075f, 0.042651f, 0.583768f, 0.192708f, 0.877417f, 0.328059f, 1.029455f, 0.213308f, 0.785565f, 0.215708f, 1.128827f, 0.328540f, 1.309012f, 0.528586f, 1.343294f, +0.029940f, 0.068891f, 0.009133f, 0.084696f, 0.062060f, 0.255328f, 0.122871f, 0.261241f, 0.015632f, 0.052022f, 0.018385f, 0.065189f, 0.096087f, 0.345942f, 0.179796f, 0.309579f, +0.045587f, 0.151022f, 0.019781f, 0.205188f, 0.082954f, 0.491382f, 0.233632f, 0.555612f, 0.069757f, 0.334222f, 0.116705f, 0.462841f, 0.137601f, 0.713268f, 0.366263f, 0.705394f, +0.025034f, 0.098284f, 0.011681f, 0.098633f, 0.069468f, 0.487655f, 0.210373f, 0.407279f, 0.046714f, 0.265243f, 0.084035f, 0.271311f, 0.091854f, 0.564255f, 0.262893f, 0.412174f, +0.100323f, 0.255023f, 0.027999f, 0.351314f, 0.184026f, 0.836457f, 0.333355f, 0.958959f, 0.180422f, 0.663318f, 0.194144f, 0.931369f, 0.261555f, 1.040338f, 0.447780f, 1.043176f, +0.113639f, 0.178826f, 0.032461f, 0.271709f, 0.147939f, 0.416264f, 0.274277f, 0.526360f, 0.029784f, 0.067786f, 0.032802f, 0.104978f, 0.292893f, 0.721184f, 0.513208f, 0.797602f, +0.134407f, 0.304519f, 0.054614f, 0.511327f, 0.153608f, 0.622291f, 0.405114f, 0.869595f, 0.103239f, 0.338292f, 0.161739f, 0.578975f, 0.325816f, 1.155047f, 0.812102f, 1.411725f, +0.101417f, 0.272303f, 0.044310f, 0.337725f, 0.176748f, 0.848558f, 0.501220f, 0.875855f, 0.094995f, 0.368888f, 0.160023f, 0.466326f, 0.298841f, 1.255501f, 0.800923f, 1.133429f, +0.271510f, 0.472021f, 0.070958f, 0.803618f, 0.312798f, 0.972355f, 0.530590f, 1.377695f, 0.245107f, 0.616290f, 0.246978f, 1.069442f, 0.568485f, 1.546425f, 0.911360f, 1.916388f, +0.063276f, 0.104611f, 0.016815f, 0.155082f, 0.093005f, 0.274933f, 0.160414f, 0.339196f, 0.015664f, 0.037454f, 0.016049f, 0.056594f, 0.111917f, 0.289511f, 0.182434f, 0.312402f, +0.079809f, 0.189966f, 0.030169f, 0.311222f, 0.102981f, 0.438296f, 0.252666f, 0.597587f, 0.057902f, 0.199328f, 0.084389f, 0.332848f, 0.132762f, 0.494464f, 0.307851f, 0.589650f, +0.018137f, 0.051161f, 0.007372f, 0.061910f, 0.035688f, 0.180005f, 0.094151f, 0.181278f, 0.016046f, 0.065464f, 0.025147f, 0.080743f, 0.036675f, 0.161875f, 0.091443f, 0.142583f, +0.129093f, 0.235782f, 0.031387f, 0.391658f, 0.167916f, 0.548385f, 0.264981f, 0.758094f, 0.110075f, 0.290769f, 0.103185f, 0.492300f, 0.185485f, 0.530091f, 0.276635f, 0.640935f, +0.097207f, 0.195800f, 0.024059f, 0.246461f, 0.138598f, 0.499181f, 0.222651f, 0.522918f, 0.032155f, 0.093674f, 0.030685f, 0.120182f, 0.214286f, 0.675373f, 0.325339f, 0.618794f, +0.172316f, 0.499726f, 0.060669f, 0.695149f, 0.215688f, 1.118452f, 0.492887f, 1.294802f, 0.167050f, 0.700659f, 0.226765f, 0.993429f, 0.357267f, 1.621185f, 0.771596f, 1.641516f, +0.086307f, 0.296620f, 0.032674f, 0.304771f, 0.164739f, 1.012365f, 0.404790f, 0.865665f, 0.102031f, 0.507156f, 0.148927f, 0.531127f, 0.217517f, 1.169719f, 0.505128f, 0.874825f, +0.254254f, 0.565792f, 0.057576f, 0.798007f, 0.320814f, 1.276517f, 0.471528f, 1.498363f, 0.289692f, 0.932347f, 0.252929f, 1.340331f, 0.455321f, 1.585402f, 0.632480f, 1.627632f, +0.057841f, 0.116308f, 0.015233f, 0.143054f, 0.127654f, 0.458977f, 0.218210f, 0.469809f, 0.026232f, 0.076287f, 0.026637f, 0.095637f, 0.164537f, 0.517691f, 0.265816f, 0.463477f, +0.095093f, 0.275305f, 0.035626f, 0.374210f, 0.184242f, 0.953756f, 0.448008f, 1.078893f, 0.126389f, 0.529210f, 0.182565f, 0.733185f, 0.254418f, 1.152514f, 0.584685f, 1.140286f, +0.043717f, 0.149990f, 0.017611f, 0.150588f, 0.129163f, 0.792383f, 0.337712f, 0.662069f, 0.070856f, 0.351594f, 0.110050f, 0.359793f, 0.142176f, 0.763261f, 0.351327f, 0.557786f, +0.189715f, 0.421453f, 0.045714f, 0.580837f, 0.370532f, 1.471826f, 0.579503f, 1.688114f, 0.296353f, 0.952158f, 0.275326f, 1.337515f, 0.438413f, 1.523923f, 0.648020f, 1.528744f, +0.147517f, 0.202867f, 0.036381f, 0.308372f, 0.204474f, 0.502798f, 0.327302f, 0.636057f, 0.033583f, 0.066794f, 0.031932f, 0.103487f, 0.337009f, 0.725180f, 0.509833f, 0.802370f, +0.188391f, 0.373011f, 0.066092f, 0.626606f, 0.229243f, 0.811602f, 0.521991f, 1.134635f, 0.125690f, 0.359929f, 0.170011f, 0.616274f, 0.404790f, 1.254080f, 0.871107f, 1.533432f, +0.119002f, 0.279231f, 0.044890f, 0.346468f, 0.220821f, 0.926479f, 0.540652f, 0.956699f, 0.096819f, 0.328567f, 0.140814f, 0.415535f, 0.310816f, 1.141161f, 0.719210f, 1.030655f, +0.345001f, 0.524160f, 0.077846f, 0.892772f, 0.423196f, 1.149661f, 0.619783f, 1.629622f, 0.270526f, 0.594436f, 0.235350f, 1.031968f, 0.640283f, 1.522122f, 0.886229f, 1.887091f, +0.154099f, 0.201933f, 0.047016f, 0.380743f, 0.186063f, 0.435966f, 0.368455f, 0.684096f, 0.031438f, 0.059583f, 0.036982f, 0.114506f, 0.203105f, 0.416448f, 0.380119f, 0.571547f, +0.219396f, 0.413931f, 0.095220f, 0.862508f, 0.232557f, 0.784538f, 0.655104f, 1.360469f, 0.131177f, 0.357940f, 0.219506f, 0.760202f, 0.271969f, 0.802882f, 0.724060f, 1.217735f, +0.047430f, 0.106048f, 0.022134f, 0.163217f, 0.076667f, 0.306507f, 0.232219f, 0.392592f, 0.034582f, 0.111828f, 0.062223f, 0.175427f, 0.071470f, 0.250038f, 0.204594f, 0.280114f, +0.373326f, 0.540467f, 0.104213f, 1.141849f, 0.398909f, 1.032619f, 0.722747f, 1.815595f, 0.262340f, 0.549285f, 0.282347f, 1.182826f, 0.399724f, 0.905473f, 0.684460f, 1.392453f, +0.171962f, 0.274549f, 0.048866f, 0.439539f, 0.201412f, 0.574989f, 0.371486f, 0.766084f, 0.046878f, 0.108247f, 0.051361f, 0.176635f, 0.282484f, 0.705694f, 0.492409f, 0.822356f, +0.344097f, 0.790970f, 0.139095f, 1.399419f, 0.353814f, 1.454253f, 0.928297f, 2.141250f, 0.274911f, 0.913954f, 0.428461f, 1.648146f, 0.531634f, 1.912169f, 1.318257f, 2.462522f, +0.163949f, 0.446620f, 0.071261f, 0.583650f, 0.257072f, 1.252186f, 0.725235f, 1.361831f, 0.159730f, 0.629316f, 0.267681f, 0.838237f, 0.307909f, 1.312455f, 0.820958f, 1.248433f, +0.534110f, 0.942091f, 0.138866f, 1.689990f, 0.553618f, 1.746052f, 0.934232f, 2.606687f, 0.501520f, 1.279391f, 0.502736f, 2.339263f, 0.712764f, 1.967166f, 1.136750f, 2.568615f, +0.027498f, 0.043827f, 0.008315f, 0.068561f, 0.049853f, 0.142076f, 0.097841f, 0.184966f, 0.010277f, 0.023691f, 0.011982f, 0.037774f, 0.058290f, 0.145369f, 0.108118f, 0.165527f, +0.051031f, 0.117104f, 0.021950f, 0.202448f, 0.081220f, 0.333263f, 0.226753f, 0.479480f, 0.055896f, 0.185513f, 0.092700f, 0.326889f, 0.101741f, 0.365315f, 0.268448f, 0.459702f, +0.022317f, 0.060691f, 0.010322f, 0.077499f, 0.054166f, 0.263387f, 0.162601f, 0.279901f, 0.029810f, 0.117245f, 0.053157f, 0.152598f, 0.054086f, 0.230146f, 0.153447f, 0.213914f, +0.107101f, 0.188587f, 0.029630f, 0.330567f, 0.171835f, 0.541022f, 0.308553f, 0.789226f, 0.137877f, 0.351126f, 0.147068f, 0.627326f, 0.184433f, 0.508150f, 0.312993f, 0.648344f, +0.296098f, 0.322760f, 0.083841f, 0.623999f, 0.337153f, 0.657136f, 0.619623f, 1.057303f, 0.055552f, 0.087578f, 0.060647f, 0.172577f, 0.504083f, 0.859763f, 0.875543f, 1.209899f, +0.426850f, 0.669900f, 0.171930f, 1.431279f, 0.426684f, 1.197364f, 1.115481f, 2.129023f, 0.234697f, 0.532715f, 0.364477f, 1.160093f, 0.683456f, 1.678336f, 1.688659f, 2.610116f, +0.256494f, 0.477047f, 0.111087f, 0.752839f, 0.390985f, 1.300253f, 1.099073f, 1.707690f, 0.171979f, 0.462606f, 0.287177f, 0.744109f, 0.499221f, 1.452814f, 1.326281f, 1.668851f, +0.822324f, 0.990284f, 0.213035f, 2.145252f, 0.828627f, 1.784271f, 1.393308f, 3.216764f, 0.531399f, 0.925531f, 0.530783f, 2.043588f, 1.137263f, 2.142946f, 1.807275f, 3.379061f, +0.192572f, 0.351445f, 0.062124f, 0.504392f, 0.264072f, 0.861729f, 0.552924f, 1.029253f, 0.042603f, 0.112449f, 0.052990f, 0.164495f, 0.318088f, 0.908330f, 0.629456f, 0.948902f, +0.298043f, 0.783128f, 0.136772f, 1.242094f, 0.358796f, 1.685725f, 1.068674f, 2.225093f, 0.193239f, 0.734347f, 0.341900f, 1.187153f, 0.463022f, 1.903659f, 1.303391f, 2.197744f, +0.064631f, 0.201255f, 0.031891f, 0.235774f, 0.118649f, 0.660620f, 0.379991f, 0.644080f, 0.051101f, 0.230134f, 0.097217f, 0.274798f, 0.122052f, 0.594680f, 0.369429f, 0.507105f, +0.489859f, 0.987660f, 0.144584f, 1.588302f, 0.594463f, 2.143119f, 1.138820f, 2.868216f, 0.373279f, 1.088485f, 0.424787f, 1.784153f, 0.657319f, 2.073701f, 1.190095f, 2.427382f, +0.205371f, 0.456649f, 0.061707f, 0.556476f, 0.273188f, 1.086152f, 0.532766f, 1.101525f, 0.060711f, 0.195238f, 0.070331f, 0.242500f, 0.422799f, 1.470998f, 0.779264f, 1.304795f, +0.446727f, 1.430138f, 0.190938f, 1.925981f, 0.521682f, 2.986249f, 1.447224f, 3.346880f, 0.387026f, 1.791962f, 0.637790f, 2.459727f, 0.864984f, 4.332883f, 2.267845f, 4.247344f, +0.213506f, 0.810018f, 0.098123f, 0.805741f, 0.380211f, 2.579252f, 1.134138f, 2.135181f, 0.225567f, 1.237689f, 0.399690f, 1.254864f, 0.502524f, 2.983141f, 1.416684f, 2.159938f, +0.669771f, 1.645294f, 0.184123f, 2.246580f, 0.788450f, 3.463193f, 1.406813f, 3.935455f, 0.681978f, 2.422931f, 0.722837f, 3.372122f, 1.120144f, 4.305515f, 1.888912f, 4.279271f, +0.068669f, 0.152428f, 0.021955f, 0.181503f, 0.141392f, 0.561191f, 0.293410f, 0.556121f, 0.027831f, 0.089348f, 0.034308f, 0.108440f, 0.182428f, 0.633615f, 0.357780f, 0.549176f, +0.138533f, 0.442738f, 0.063006f, 0.582608f, 0.250412f, 1.430977f, 0.739198f, 1.567119f, 0.164548f, 0.760567f, 0.288539f, 1.020118f, 0.346139f, 1.730921f, 0.965677f, 1.657956f, +0.060772f, 0.230166f, 0.029719f, 0.223717f, 0.167515f, 1.134432f, 0.531703f, 0.917645f, 0.088025f, 0.482168f, 0.165969f, 0.477681f, 0.184577f, 1.093836f, 0.553694f, 0.773882f, +0.280833f, 0.688688f, 0.082150f, 0.918874f, 0.511721f, 2.243847f, 0.971564f, 2.491533f, 0.392041f, 1.390463f, 0.442157f, 1.890936f, 0.606076f, 2.325602f, 1.087527f, 2.258578f, +0.381787f, 0.579589f, 0.114304f, 0.852926f, 0.493720f, 1.340184f, 0.959399f, 1.641327f, 0.077673f, 0.170539f, 0.089660f, 0.255798f, 0.814554f, 1.934873f, 1.495940f, 2.072573f, +0.598295f, 1.307693f, 0.254806f, 2.126703f, 0.679228f, 2.654547f, 1.877540f, 3.592785f, 0.356725f, 1.127657f, 0.585754f, 1.869227f, 1.200561f, 4.105896f, 3.136415f, 4.860437f, +0.360626f, 0.934105f, 0.165143f, 1.122079f, 0.624320f, 2.891550f, 1.855633f, 2.890670f, 0.262205f, 0.982274f, 0.462950f, 1.202665f, 0.879641f, 3.565147f, 2.470960f, 3.117251f, +1.113311f, 1.867192f, 0.304960f, 3.078889f, 1.274093f, 3.820835f, 2.265203f, 5.243284f, 0.780156f, 1.892373f, 0.823939f, 3.180504f, 1.929601f, 5.063763f, 3.242269f, 6.077779f, +0.186969f, 0.353701f, 0.057547f, 0.524119f, 0.277100f, 0.937320f, 0.553564f, 1.155905f, 0.048923f, 0.133855f, 0.058057f, 0.202168f, 0.332136f, 0.983144f, 0.627082f, 1.060420f, +0.246337f, 0.670946f, 0.107854f, 1.098733f, 0.320506f, 1.560917f, 0.910802f, 2.127278f, 0.188905f, 0.744141f, 0.318888f, 1.242062f, 0.411573f, 1.754036f, 1.105375f, 2.090785f, +0.060033f, 0.193773f, 0.028262f, 0.234383f, 0.119109f, 0.687444f, 0.363952f, 0.692004f, 0.056139f, 0.262076f, 0.101900f, 0.323104f, 0.121923f, 0.615779f, 0.352094f, 0.542154f, +0.434435f, 0.907958f, 0.122339f, 1.507559f, 0.569794f, 2.129330f, 1.041447f, 2.942331f, 0.391549f, 1.183531f, 0.425122f, 2.002960f, 0.626939f, 2.050213f, 1.082979f, 2.477845f, +0.176175f, 0.406062f, 0.050504f, 0.510904f, 0.253283f, 1.043852f, 0.471270f, 1.093014f, 0.061599f, 0.205340f, 0.068084f, 0.263332f, 0.390063f, 1.406749f, 0.685922f, 1.288338f, +0.326230f, 1.082590f, 0.133034f, 1.505293f, 0.411743f, 2.443152f, 1.089797f, 2.827141f, 0.334288f, 1.604404f, 0.525591f, 2.273813f, 0.679336f, 3.527423f, 1.699337f, 3.570105f, +0.175221f, 0.689086f, 0.076831f, 0.707713f, 0.337239f, 2.371432f, 0.959773f, 2.026911f, 0.218951f, 1.245343f, 0.370157f, 1.303638f, 0.443533f, 2.729273f, 1.192976f, 2.040316f, +0.524821f, 1.336390f, 0.137652f, 1.884058f, 0.667726f, 3.040217f, 1.136711f, 3.567022f, 0.632055f, 2.327713f, 0.639167f, 3.344835f, 0.943961f, 3.761051f, 1.518733f, 3.859552f, +0.058024f, 0.133509f, 0.017700f, 0.164139f, 0.129123f, 0.531243f, 0.255648f, 0.543545f, 0.027814f, 0.092561f, 0.032713f, 0.115989f, 0.165778f, 0.596850f, 0.310200f, 0.534113f, +0.099649f, 0.330117f, 0.043240f, 0.448518f, 0.194675f, 1.153166f, 0.548284f, 1.303899f, 0.139993f, 0.670744f, 0.234212f, 0.928865f, 0.267770f, 1.388010f, 0.712743f, 1.372686f, +0.049126f, 0.192866f, 0.022921f, 0.193550f, 0.146352f, 1.027377f, 0.443207f, 0.858043f, 0.084161f, 0.477870f, 0.151400f, 0.488802f, 0.160465f, 0.985734f, 0.459265f, 0.720055f, +0.216754f, 0.550994f, 0.060494f, 0.759037f, 0.426866f, 1.940241f, 0.773249f, 2.224396f, 0.357891f, 1.315777f, 0.385111f, 1.847492f, 0.503085f, 2.001032f, 0.861280f, 2.006489f, +0.411100f, 0.646920f, 0.117429f, 0.982935f, 0.574573f, 1.616715f, 1.065255f, 2.044312f, 0.098923f, 0.225139f, 0.108946f, 0.348666f, 0.943281f, 2.322618f, 1.652817f, 2.568727f, +0.548426f, 1.242546f, 0.222844f, 2.086394f, 0.672909f, 2.726060f, 1.774678f, 3.809423f, 0.386755f, 1.267309f, 0.605908f, 2.168955f, 1.183536f, 4.195746f, 2.949988f, 5.128135f, +0.371494f, 0.997458f, 0.162310f, 1.237102f, 0.695089f, 3.337093f, 1.971130f, 3.444444f, 0.319474f, 1.240597f, 0.538167f, 1.568287f, 0.974530f, 4.094221f, 2.611831f, 3.696141f, +1.095021f, 1.903702f, 0.286179f, 3.241060f, 1.354396f, 4.210240f, 2.297424f, 5.965335f, 0.907583f, 2.282001f, 0.914513f, 3.959933f, 2.041118f, 5.552366f, 3.272196f, 6.880700f, +0.166206f, 0.274778f, 0.044167f, 0.407347f, 0.262275f, 0.775312f, 0.452368f, 0.956533f, 0.037776f, 0.090323f, 0.038704f, 0.136479f, 0.261706f, 0.676989f, 0.426603f, 0.730518f, +0.236447f, 0.562806f, 0.089381f, 0.922045f, 0.327555f, 1.394102f, 0.803663f, 1.900762f, 0.157495f, 0.542181f, 0.229543f, 0.905361f, 0.350162f, 1.304153f, 0.811961f, 1.555208f, +0.048239f, 0.136072f, 0.019607f, 0.164661f, 0.101905f, 0.513992f, 0.268843f, 0.517626f, 0.039183f, 0.159853f, 0.061405f, 0.197163f, 0.086838f, 0.383283f, 0.216515f, 0.337603f, +0.378028f, 0.690450f, 0.091911f, 1.146911f, 0.527910f, 1.724060f, 0.833071f, 2.383362f, 0.295940f, 0.781743f, 0.277417f, 1.323567f, 0.483552f, 1.381924f, 0.721175f, 1.670891f, +0.200184f, 0.403222f, 0.049547f, 0.507552f, 0.306432f, 1.103656f, 0.492266f, 1.156138f, 0.060796f, 0.177110f, 0.058016f, 0.227229f, 0.392860f, 1.238189f, 0.596459f, 1.134460f, +0.400253f, 1.160757f, 0.140921f, 1.614683f, 0.537873f, 2.789144f, 1.229140f, 3.228918f, 0.356246f, 1.494202f, 0.483592f, 2.118553f, 0.738777f, 3.352384f, 1.595552f, 3.394425f, +0.179970f, 0.618522f, 0.068132f, 0.635518f, 0.368804f, 2.266394f, 0.906210f, 1.937976f, 0.195335f, 0.970932f, 0.285116f, 1.016824f, 0.403793f, 2.171438f, 0.937708f, 1.624003f, +0.583736f, 1.298989f, 0.132188f, 1.832128f, 0.790763f, 3.146445f, 1.162253f, 3.693264f, 0.610630f, 1.965260f, 0.533139f, 2.825233f, 0.930632f, 3.240413f, 1.292730f, 3.326727f, +0.079741f, 0.160344f, 0.021001f, 0.197217f, 0.188940f, 0.679330f, 0.322972f, 0.695363f, 0.033202f, 0.096559f, 0.033714f, 0.121051f, 0.201939f, 0.635371f, 0.326241f, 0.568833f, +0.147868f, 0.428092f, 0.055398f, 0.581887f, 0.307578f, 1.592225f, 0.747917f, 1.801132f, 0.180438f, 0.755517f, 0.260635f, 1.046718f, 0.352195f, 1.595442f, 0.809387f, 1.578514f, +0.061026f, 0.209377f, 0.024584f, 0.210212f, 0.193575f, 1.187537f, 0.506126f, 0.992236f, 0.090811f, 0.450611f, 0.141043f, 0.461120f, 0.176688f, 0.948533f, 0.436607f, 0.693182f, +0.291585f, 0.647756f, 0.070261f, 0.892723f, 0.611410f, 2.428642f, 0.956230f, 2.785537f, 0.418183f, 1.343585f, 0.388511f, 1.887359f, 0.599871f, 2.085151f, 0.886672f, 2.091748f, +0.379627f, 0.522068f, 0.093624f, 0.793578f, 0.564934f, 1.389161f, 0.904291f, 1.757338f, 0.079346f, 0.157814f, 0.075447f, 0.244508f, 0.772092f, 1.661394f, 1.168033f, 1.838239f, +0.546831f, 1.082715f, 0.191840f, 1.818810f, 0.714388f, 2.529183f, 1.626672f, 3.535845f, 0.334956f, 0.959186f, 0.453066f, 1.642327f, 1.046007f, 3.240632f, 2.251003f, 3.962499f, +0.310092f, 0.727614f, 0.116973f, 0.902819f, 0.617764f, 2.591896f, 1.512515f, 2.676439f, 0.231628f, 0.786059f, 0.336881f, 0.994120f, 0.721029f, 2.647258f, 1.668419f, 2.390906f, +0.989811f, 1.503820f, 0.223342f, 2.561374f, 1.303522f, 3.541170f, 1.909047f, 5.019540f, 0.712581f, 1.565780f, 0.619926f, 2.718266f, 1.635372f, 3.887709f, 2.263551f, 4.819892f, +0.323132f, 0.423436f, 0.098588f, 0.798385f, 0.306621f, 0.718447f, 0.607193f, 1.127351f, 0.065181f, 0.123533f, 0.076675f, 0.237406f, 0.438428f, 0.898958f, 0.820537f, 1.233759f, +0.273041f, 0.515142f, 0.118502f, 1.073400f, 0.227452f, 0.767315f, 0.640722f, 1.330603f, 0.161413f, 0.440445f, 0.270101f, 0.935427f, 0.348430f, 1.028603f, 0.927621f, 1.560087f, +0.065452f, 0.146342f, 0.030544f, 0.225232f, 0.083145f, 0.332404f, 0.251841f, 0.425764f, 0.047184f, 0.152581f, 0.084898f, 0.239356f, 0.101529f, 0.355198f, 0.290640f, 0.397922f, +0.419613f, 0.607477f, 0.117133f, 1.283420f, 0.352368f, 0.912141f, 0.638422f, 1.603765f, 0.291546f, 0.610437f, 0.313781f, 1.314510f, 0.462508f, 1.047691f, 0.791966f, 1.611160f, +0.320376f, 0.511503f, 0.091041f, 0.818890f, 0.294901f, 0.841878f, 0.543916f, 1.121673f, 0.086354f, 0.199400f, 0.094612f, 0.325377f, 0.541776f, 1.353450f, 0.944391f, 1.577197f, +0.380475f, 0.874594f, 0.153801f, 1.547369f, 0.307456f, 1.263711f, 0.806668f, 1.860694f, 0.300553f, 0.999202f, 0.468425f, 1.801875f, 0.605141f, 2.176558f, 1.500528f, 2.803006f, +0.201013f, 0.547585f, 0.087371f, 0.715593f, 0.247703f, 1.206546f, 0.698801f, 1.312194f, 0.193635f, 0.762895f, 0.324499f, 1.016162f, 0.388628f, 1.656515f, 1.036173f, 1.575710f, +0.533382f, 0.940807f, 0.138676f, 1.687688f, 0.434490f, 1.370335f, 0.733203f, 2.045778f, 0.495198f, 1.263264f, 0.496399f, 2.309776f, 0.732742f, 2.022306f, 1.168614f, 2.640614f, +0.078857f, 0.125686f, 0.023845f, 0.196616f, 0.112355f, 0.320203f, 0.220509f, 0.416867f, 0.029141f, 0.067174f, 0.033974f, 0.107107f, 0.172081f, 0.429153f, 0.319183f, 0.488665f, +0.086855f, 0.199311f, 0.037360f, 0.344568f, 0.108640f, 0.445770f, 0.303302f, 0.641347f, 0.094065f, 0.312189f, 0.155999f, 0.550103f, 0.178261f, 0.640069f, 0.470348f, 0.805445f, +0.042118f, 0.114539f, 0.019480f, 0.146260f, 0.080337f, 0.390647f, 0.241164f, 0.415139f, 0.055625f, 0.218780f, 0.099192f, 0.284748f, 0.105078f, 0.447126f, 0.298116f, 0.415591f, +0.164633f, 0.289892f, 0.045547f, 0.508139f, 0.207585f, 0.653581f, 0.372748f, 0.953425f, 0.209554f, 0.533665f, 0.223524f, 0.953453f, 0.291850f, 0.804106f, 0.495286f, 1.025951f, +0.292258f, 0.318574f, 0.082754f, 0.615905f, 0.261528f, 0.509738f, 0.480639f, 0.820146f, 0.054214f, 0.085469f, 0.059186f, 0.168421f, 0.512189f, 0.873589f, 0.889623f, 1.229356f, +0.250048f, 0.392427f, 0.100716f, 0.838442f, 0.196434f, 0.551234f, 0.513538f, 0.980145f, 0.135937f, 0.308550f, 0.211107f, 0.671930f, 0.412152f, 1.012105f, 1.018330f, 1.574005f, +0.166607f, 0.309868f, 0.072157f, 0.489010f, 0.199589f, 0.663751f, 0.561053f, 0.871738f, 0.110452f, 0.297105f, 0.184437f, 0.477898f, 0.333816f, 0.971457f, 0.886848f, 1.115915f, +0.435064f, 0.523926f, 0.112710f, 1.134981f, 0.344533f, 0.741878f, 0.579321f, 1.337492f, 0.277981f, 0.484155f, 0.277658f, 1.069022f, 0.619397f, 1.167131f, 0.984312f, 1.840367f, +0.326398f, 0.595677f, 0.105296f, 0.854913f, 0.351753f, 1.147851f, 0.736513f, 1.370998f, 0.071396f, 0.188448f, 0.088803f, 0.275669f, 0.555007f, 1.584874f, 1.098288f, 1.655665f, +0.299813f, 0.787779f, 0.137584f, 1.249470f, 0.283649f, 1.332661f, 0.844847f, 1.759062f, 0.192198f, 0.730391f, 0.340058f, 1.180758f, 0.479480f, 1.971326f, 1.349720f, 2.275864f, +0.072091f, 0.224484f, 0.035572f, 0.262987f, 0.104007f, 0.579097f, 0.333099f, 0.564599f, 0.056357f, 0.253806f, 0.107217f, 0.303064f, 0.140147f, 0.682841f, 0.424197f, 0.582283f, +0.445045f, 0.897306f, 0.131357f, 1.443000f, 0.424443f, 1.530175f, 0.813111f, 2.047890f, 0.335312f, 0.977774f, 0.381581f, 1.602685f, 0.614762f, 1.939444f, 1.113045f, 2.270227f, +0.309271f, 0.687676f, 0.092925f, 0.838007f, 0.323314f, 1.285444f, 0.630520f, 1.303638f, 0.090396f, 0.290702f, 0.104721f, 0.361074f, 0.655441f, 2.280399f, 1.208046f, 2.022746f, +0.399265f, 1.278195f, 0.170652f, 1.721358f, 0.366426f, 2.097523f, 1.016521f, 2.350828f, 0.342013f, 1.583546f, 0.563612f, 2.173646f, 0.795839f, 3.986520f, 2.086558f, 3.907820f, +0.211591f, 0.802751f, 0.097243f, 0.798513f, 0.296123f, 2.008823f, 0.883312f, 1.662963f, 0.221026f, 1.212776f, 0.391645f, 1.229605f, 0.512673f, 3.043392f, 1.445297f, 2.203562f, +0.540639f, 1.328081f, 0.148624f, 1.813439f, 0.500169f, 2.196946f, 0.892440f, 2.496534f, 0.544295f, 1.933770f, 0.576905f, 2.691331f, 0.930793f, 3.577701f, 1.569606f, 3.555893f, +0.159177f, 0.353331f, 0.050892f, 0.420727f, 0.257574f, 1.022323f, 0.534505f, 1.013089f, 0.063787f, 0.204779f, 0.078630f, 0.248535f, 0.435316f, 1.511958f, 0.853749f, 1.310464f, +0.190585f, 0.609090f, 0.086679f, 0.801513f, 0.270739f, 1.547136f, 0.799202f, 1.694329f, 0.223825f, 1.034557f, 0.392484f, 1.387610f, 0.490211f, 2.451373f, 1.367616f, 2.348038f, +0.092705f, 0.351110f, 0.045336f, 0.341271f, 0.200824f, 1.360008f, 0.637429f, 1.100113f, 0.132766f, 0.727247f, 0.250330f, 0.720480f, 0.289852f, 1.717716f, 0.869498f, 1.215273f, +0.348935f, 0.855695f, 0.102071f, 1.141701f, 0.499679f, 2.191043f, 0.948700f, 2.432901f, 0.481627f, 1.708198f, 0.543195f, 2.323035f, 0.775213f, 2.974605f, 1.391023f, 2.888878f, +0.304596f, 0.462406f, 0.091193f, 0.680479f, 0.309561f, 0.840291f, 0.601540f, 1.029106f, 0.061271f, 0.134527f, 0.070727f, 0.201783f, 0.668993f, 1.589110f, 1.228614f, 1.702202f, +0.283294f, 0.619195f, 0.120651f, 1.006998f, 0.252754f, 0.987810f, 0.698670f, 1.336948f, 0.167008f, 0.527936f, 0.274233f, 0.875118f, 0.585199f, 2.001370f, 1.528808f, 2.369162f, +0.189341f, 0.490438f, 0.086706f, 0.589131f, 0.257607f, 1.193111f, 0.765671f, 1.192748f, 0.136117f, 0.509922f, 0.240328f, 0.624333f, 0.475436f, 1.926922f, 1.335526f, 1.684839f, +0.476102f, 0.798495f, 0.130414f, 1.316672f, 0.428199f, 1.284113f, 0.761293f, 1.762172f, 0.329874f, 0.800153f, 0.348387f, 1.344814f, 0.849471f, 2.229229f, 1.427349f, 2.675631f, +0.085535f, 0.161812f, 0.026327f, 0.239776f, 0.099626f, 0.336996f, 0.199024f, 0.415584f, 0.022130f, 0.060547f, 0.026261f, 0.091447f, 0.156419f, 0.463010f, 0.295323f, 0.499403f, +0.066884f, 0.182172f, 0.029284f, 0.298322f, 0.068390f, 0.333070f, 0.194348f, 0.453920f, 0.050713f, 0.199770f, 0.085608f, 0.333442f, 0.115037f, 0.490264f, 0.308959f, 0.584387f, +0.018074f, 0.058338f, 0.008509f, 0.070564f, 0.028182f, 0.162652f, 0.086113f, 0.163731f, 0.016711f, 0.078014f, 0.030333f, 0.096180f, 0.037787f, 0.190846f, 0.109123f, 0.168028f, +0.106532f, 0.222649f, 0.030000f, 0.369683f, 0.109808f, 0.410355f, 0.200703f, 0.567033f, 0.094935f, 0.286958f, 0.103075f, 0.485636f, 0.158263f, 0.517550f, 0.273384f, 0.625500f, +0.071609f, 0.165050f, 0.020528f, 0.207665f, 0.080908f, 0.333445f, 0.150541f, 0.349149f, 0.024756f, 0.082524f, 0.027362f, 0.105830f, 0.163214f, 0.588624f, 0.287009f, 0.539077f, +0.078698f, 0.261159f, 0.032093f, 0.363130f, 0.078060f, 0.463184f, 0.206609f, 0.535982f, 0.079734f, 0.382682f, 0.125364f, 0.542349f, 0.168704f, 0.875985f, 0.422006f, 0.886585f, +0.046870f, 0.184324f, 0.020552f, 0.189307f, 0.070894f, 0.498518f, 0.201762f, 0.426093f, 0.057908f, 0.329367f, 0.097899f, 0.344785f, 0.122133f, 0.751542f, 0.328502f, 0.561828f, +0.114344f, 0.291163f, 0.029991f, 0.410485f, 0.114331f, 0.520559f, 0.194632f, 0.610760f, 0.136157f, 0.501436f, 0.137689f, 0.720545f, 0.211717f, 0.843549f, 0.340630f, 0.865641f, +0.036303f, 0.083531f, 0.011074f, 0.102695f, 0.063490f, 0.261212f, 0.125702f, 0.267261f, 0.017206f, 0.057260f, 0.020237f, 0.071752f, 0.106773f, 0.384416f, 0.199792f, 0.344009f, +0.037002f, 0.122581f, 0.016056f, 0.166547f, 0.056810f, 0.336519f, 0.160001f, 0.380506f, 0.051398f, 0.246261f, 0.085990f, 0.341030f, 0.102357f, 0.530575f, 0.272450f, 0.524717f, +0.020227f, 0.079411f, 0.009438f, 0.079693f, 0.047357f, 0.332442f, 0.143414f, 0.277648f, 0.034262f, 0.194543f, 0.061636f, 0.198994f, 0.068015f, 0.417812f, 0.194663f, 0.305202f, +0.072692f, 0.184784f, 0.020288f, 0.254555f, 0.112505f, 0.511371f, 0.203798f, 0.586263f, 0.118673f, 0.436298f, 0.127699f, 0.612610f, 0.173683f, 0.690829f, 0.297345f, 0.692713f, +0.088527f, 0.139308f, 0.025287f, 0.211666f, 0.097237f, 0.273603f, 0.180277f, 0.345967f, 0.021062f, 0.047936f, 0.023196f, 0.074237f, 0.209105f, 0.514875f, 0.366394f, 0.569432f, +0.070091f, 0.158802f, 0.028480f, 0.266649f, 0.067587f, 0.273805f, 0.178248f, 0.382617f, 0.048872f, 0.160143f, 0.076565f, 0.274080f, 0.155712f, 0.552015f, 0.388116f, 0.674685f, +0.052646f, 0.141353f, 0.023002f, 0.175314f, 0.077413f, 0.371656f, 0.219527f, 0.383611f, 0.044764f, 0.173830f, 0.075407f, 0.219745f, 0.142169f, 0.597283f, 0.381025f, 0.539209f, +0.126394f, 0.219738f, 0.033033f, 0.374104f, 0.122861f, 0.381922f, 0.208405f, 0.541131f, 0.103580f, 0.260438f, 0.104371f, 0.451935f, 0.242534f, 0.659753f, 0.388815f, 0.817591f, +0.471845f, 0.780071f, 0.125387f, 1.156424f, 0.585156f, 1.729779f, 1.009267f, 2.134095f, 0.106034f, 0.253532f, 0.108640f, 0.383090f, 0.764828f, 1.978480f, 1.246734f, 2.134919f, +0.398386f, 0.948264f, 0.150596f, 1.553541f, 0.433727f, 1.845978f, 1.064158f, 2.516865f, 0.262373f, 0.903229f, 0.382399f, 1.508257f, 0.607348f, 2.262023f, 1.408326f, 2.697472f, +0.090122f, 0.254219f, 0.036631f, 0.307629f, 0.149622f, 0.754667f, 0.394728f, 0.760003f, 0.072379f, 0.295285f, 0.113429f, 0.364205f, 0.167012f, 0.737148f, 0.416413f, 0.649294f, +0.575250f, 1.050665f, 0.139862f, 1.745267f, 0.631326f, 2.061799f, 0.996268f, 2.850257f, 0.445265f, 1.176195f, 0.417396f, 1.991412f, 0.757483f, 2.164784f, 1.129720f, 2.617451f, +0.504927f, 1.017055f, 0.124973f, 1.280208f, 0.607429f, 2.187739f, 0.975802f, 2.291772f, 0.151620f, 0.441698f, 0.144688f, 0.566690f, 1.020085f, 3.215030f, 1.548739f, 2.945693f, +0.599174f, 1.737639f, 0.210957f, 2.417161f, 0.632790f, 3.281337f, 1.446043f, 3.798717f, 0.527291f, 2.211619f, 0.715781f, 3.135742f, 1.138491f, 5.166184f, 2.458822f, 5.230972f, +0.298734f, 1.026692f, 0.113094f, 1.054905f, 0.481108f, 2.956531f, 1.182158f, 2.528107f, 0.320589f, 1.593518f, 0.467940f, 1.668837f, 0.689989f, 3.710485f, 1.602325f, 2.775046f, +0.789218f, 1.756247f, 0.178719f, 2.477057f, 0.840211f, 3.343197f, 1.234930f, 3.924209f, 0.816284f, 2.627139f, 0.712694f, 3.776742f, 1.295258f, 4.510020f, 1.799227f, 4.630151f, +0.309597f, 0.622542f, 0.081538f, 0.765702f, 0.576501f, 2.072800f, 0.985467f, 2.121722f, 0.127457f, 0.370672f, 0.129424f, 0.464691f, 0.807113f, 2.539456f, 1.303924f, 2.273517f, +0.340727f, 0.986440f, 0.127651f, 1.340824f, 0.556994f, 2.883364f, 1.354404f, 3.261674f, 0.411096f, 1.721316f, 0.593812f, 2.384766f, 0.835439f, 3.784532f, 1.919940f, 3.744379f, +0.155925f, 0.534970f, 0.062812f, 0.537103f, 0.388697f, 2.384565f, 1.016297f, 1.992403f, 0.229414f, 1.138375f, 0.356317f, 1.164924f, 0.464734f, 2.494888f, 1.148389f, 1.823247f, +0.606821f, 1.348052f, 0.146221f, 1.857856f, 0.999976f, 3.972102f, 1.563937f, 4.555812f, 0.860486f, 2.764670f, 0.799432f, 3.883584f, 1.285141f, 4.467151f, 1.899574f, 4.481284f, +0.507293f, 0.697637f, 0.125109f, 1.060455f, 0.593283f, 1.458871f, 0.949669f, 1.845524f, 0.104835f, 0.208512f, 0.099684f, 0.323056f, 1.062110f, 2.285457f, 1.606776f, 2.528729f, +0.433684f, 0.858687f, 0.152145f, 1.442474f, 0.445263f, 1.576386f, 1.013870f, 2.203817f, 0.262659f, 0.752153f, 0.355276f, 1.287844f, 0.853991f, 2.645747f, 1.837785f, 3.235100f, +0.272696f, 0.639865f, 0.102867f, 0.793941f, 0.426945f, 1.791294f, 1.045320f, 1.849723f, 0.201402f, 0.683480f, 0.292919f, 0.864390f, 0.652737f, 2.396525f, 1.510396f, 2.164453f, +0.708981f, 1.077156f, 0.159975f, 1.834660f, 0.733774f, 1.993384f, 1.074634f, 2.825583f, 0.504661f, 1.108910f, 0.439041f, 1.925118f, 1.205860f, 2.866647f, 1.669055f, 3.554003f, +0.290119f, 0.380175f, 0.088516f, 0.716816f, 0.352134f, 0.825087f, 0.697320f, 1.294686f, 0.068961f, 0.130697f, 0.081122f, 0.251173f, 0.432588f, 0.886984f, 0.809608f, 1.217325f, +0.328164f, 0.619141f, 0.142426f, 1.290103f, 0.349674f, 1.179633f, 0.985015f, 2.045604f, 0.228607f, 0.623793f, 0.382539f, 1.324827f, 0.460214f, 1.358601f, 1.225222f, 2.060597f, +0.061296f, 0.137050f, 0.028605f, 0.210931f, 0.099599f, 0.398186f, 0.301679f, 0.510020f, 0.052071f, 0.168382f, 0.093690f, 0.264144f, 0.104491f, 0.365561f, 0.299120f, 0.409532f, +0.526334f, 0.761978f, 0.146924f, 1.609834f, 0.565351f, 1.463472f, 1.024308f, 2.573139f, 0.430929f, 0.902277f, 0.463794f, 1.942955f, 0.637547f, 1.444199f, 1.091692f, 2.220917f, +0.389416f, 0.621731f, 0.110660f, 0.995359f, 0.458501f, 1.308921f, 0.845662f, 1.743937f, 0.123687f, 0.285605f, 0.135516f, 0.466045f, 0.723695f, 1.807914f, 1.261501f, 2.106791f, +0.619083f, 1.423077f, 0.250254f, 2.517769f, 0.639905f, 2.630146f, 1.678909f, 3.872641f, 0.576274f, 1.915851f, 0.898149f, 3.454882f, 1.082082f, 3.892006f, 2.683166f, 5.012189f, +0.254854f, 0.694256f, 0.110773f, 0.907265f, 0.401706f, 1.956690f, 1.133266f, 2.128023f, 0.289293f, 1.139774f, 0.484806f, 1.518159f, 0.541481f, 2.308048f, 1.443715f, 2.195460f, +0.905754f, 1.597615f, 0.235491f, 2.865919f, 0.943760f, 2.976519f, 1.592597f, 4.443654f, 0.990917f, 2.527855f, 0.993319f, 4.621977f, 1.367427f, 3.773982f, 2.180840f, 4.927854f, +0.081929f, 0.130582f, 0.024774f, 0.204275f, 0.149314f, 0.425531f, 0.293044f, 0.553993f, 0.035677f, 0.082241f, 0.041594f, 0.131130f, 0.196476f, 0.489993f, 0.364433f, 0.557941f, +0.120798f, 0.277202f, 0.051960f, 0.479224f, 0.193269f, 0.793021f, 0.539573f, 1.140951f, 0.154162f, 0.511644f, 0.255666f, 0.901560f, 0.272459f, 0.978300f, 0.718893f, 1.231065f, +0.045644f, 0.124127f, 0.021110f, 0.158502f, 0.111361f, 0.541508f, 0.334297f, 0.575459f, 0.071034f, 0.279385f, 0.126669f, 0.363628f, 0.125142f, 0.532502f, 0.355039f, 0.494945f, +0.238963f, 0.420774f, 0.066110f, 0.737558f, 0.385406f, 1.213454f, 0.692052f, 1.770150f, 0.358423f, 0.912785f, 0.382317f, 1.630794f, 0.465538f, 1.282650f, 0.790042f, 1.636520f, +0.486178f, 0.529955f, 0.137662f, 1.024573f, 0.556490f, 1.084641f, 1.022724f, 1.745140f, 0.106274f, 0.167542f, 0.116020f, 0.330150f, 0.936354f, 1.597044f, 1.626357f, 2.247437f, +0.556827f, 0.873887f, 0.224283f, 1.867108f, 0.559530f, 1.570156f, 1.462780f, 2.791882f, 0.356715f, 0.809671f, 0.553968f, 1.763222f, 1.008637f, 2.476870f, 2.492104f, 3.851978f, +0.289092f, 0.537674f, 0.125205f, 0.848516f, 0.442985f, 1.473186f, 1.245250f, 1.934812f, 0.225841f, 0.607489f, 0.377118f, 0.977156f, 0.636547f, 1.852453f, 1.691114f, 2.127917f, +1.011112f, 1.217632f, 0.261943f, 2.637756f, 1.024205f, 2.205407f, 1.722167f, 3.976008f, 0.761284f, 1.325917f, 0.760401f, 2.927649f, 1.581963f, 2.980895f, 2.513969f, 4.700365f, +0.313634f, 0.572382f, 0.101178f, 0.821481f, 0.432338f, 1.410819f, 0.905245f, 1.685088f, 0.080842f, 0.213380f, 0.100552f, 0.312140f, 0.586078f, 1.673600f, 1.159773f, 1.748354f, +0.385650f, 1.013322f, 0.176975f, 1.607197f, 0.466696f, 2.192670f, 1.390055f, 2.894240f, 0.291325f, 1.107096f, 0.515446f, 1.789743f, 0.677790f, 2.786654f, 1.907956f, 3.217147f, +0.072256f, 0.224996f, 0.035653f, 0.263586f, 0.133341f, 0.742422f, 0.427044f, 0.723835f, 0.066561f, 0.299763f, 0.126631f, 0.357940f, 0.154367f, 0.752125f, 0.467238f, 0.641364f, +0.597444f, 1.204574f, 0.176338f, 1.937132f, 0.728824f, 2.627508f, 1.396217f, 3.516492f, 0.530430f, 1.546742f, 0.603623f, 2.535288f, 0.906946f, 2.861221f, 1.642052f, 3.349218f, +0.402323f, 0.894579f, 0.120884f, 1.090141f, 0.537984f, 2.138938f, 1.049165f, 2.169213f, 0.138571f, 0.445625f, 0.160529f, 0.553500f, 0.937021f, 3.260071f, 1.727028f, 2.891728f, +0.695287f, 2.225869f, 0.297176f, 2.997601f, 0.816205f, 4.672179f, 2.264275f, 5.236409f, 0.701829f, 3.249523f, 1.156562f, 4.460440f, 1.523032f, 7.629179f, 3.993137f, 7.478566f, +0.287108f, 1.089255f, 0.131949f, 1.083504f, 0.513963f, 3.486585f, 1.533107f, 2.886298f, 0.353410f, 1.939168f, 0.626220f, 1.966077f, 0.764487f, 4.538242f, 2.155196f, 3.285906f, +0.982560f, 2.413663f, 0.270110f, 3.295756f, 1.162731f, 5.107184f, 2.074633f, 5.803630f, 1.165662f, 4.141363f, 1.235500f, 5.763756f, 1.859029f, 7.145577f, 3.134901f, 7.102022f, +0.176993f, 0.392879f, 0.056588f, 0.467819f, 0.366344f, 1.454036f, 0.760220f, 1.440902f, 0.083578f, 0.268317f, 0.103027f, 0.325650f, 0.531940f, 1.847557f, 1.043250f, 1.601339f, +0.283683f, 0.906621f, 0.129020f, 1.193041f, 0.515473f, 2.945664f, 1.521637f, 3.225911f, 0.392590f, 1.814618f, 0.688419f, 2.433875f, 0.801879f, 4.009915f, 2.237123f, 3.840881f, +0.107521f, 0.407224f, 0.052581f, 0.395813f, 0.297931f, 2.017632f, 0.945654f, 1.632067f, 0.181453f, 0.993937f, 0.342128f, 0.984689f, 0.369444f, 2.189390f, 1.108257f, 1.548979f, +0.542048f, 1.329269f, 0.158561f, 1.773562f, 0.992877f, 4.353666f, 1.885095f, 4.834243f, 0.881639f, 3.126934f, 0.994343f, 4.252419f, 1.323415f, 5.078139f, 2.374704f, 4.931788f, +0.542293f, 0.823252f, 0.162357f, 1.211501f, 0.704961f, 1.913590f, 1.369883f, 2.343579f, 0.128544f, 0.282231f, 0.148381f, 0.423330f, 1.308916f, 3.109169f, 2.403842f, 3.330440f, +0.675172f, 1.475722f, 0.287546f, 2.399968f, 0.770523f, 3.011345f, 2.129900f, 4.075693f, 0.469031f, 1.482671f, 0.770164f, 2.457705f, 1.532716f, 5.241861f, 4.004157f, 6.205159f, +0.351616f, 0.910767f, 0.161018f, 1.094044f, 0.611914f, 2.834092f, 1.818760f, 2.833230f, 0.297866f, 1.115869f, 0.525914f, 1.366234f, 0.970277f, 3.932495f, 2.725564f, 3.438448f, +1.184204f, 1.986089f, 0.324379f, 3.274944f, 1.362331f, 4.085449f, 2.422081f, 5.606411f, 0.966853f, 2.345232f, 1.021114f, 3.941622f, 2.321969f, 6.093437f, 3.901557f, 7.313645f, +0.135791f, 0.256884f, 0.041795f, 0.380655f, 0.202306f, 0.684322f, 0.404148f, 0.843907f, 0.041398f, 0.113267f, 0.049127f, 0.171073f, 0.272896f, 0.807788f, 0.515234f, 0.871280f, +0.142140f, 0.387146f, 0.062233f, 0.633985f, 0.185907f, 0.905396f, 0.528303f, 1.233908f, 0.126999f, 0.500278f, 0.214385f, 0.835025f, 0.268666f, 1.144997f, 0.721565f, 1.364820f, +0.029929f, 0.096604f, 0.014090f, 0.116849f, 0.059692f, 0.344515f, 0.182396f, 0.346801f, 0.032609f, 0.152229f, 0.059189f, 0.187677f, 0.068764f, 0.347299f, 0.198581f, 0.305775f, +0.236278f, 0.493815f, 0.066537f, 0.819922f, 0.311521f, 1.164160f, 0.569387f, 1.608649f, 0.248115f, 0.749975f, 0.269390f, 1.269228f, 0.385747f, 1.261468f, 0.666342f, 1.524584f, +0.153905f, 0.354732f, 0.044120f, 0.446321f, 0.222426f, 0.916682f, 0.413857f, 0.959855f, 0.062697f, 0.209002f, 0.069298f, 0.268029f, 0.385498f, 1.390284f, 0.677894f, 1.273260f, +0.226422f, 0.751377f, 0.092333f, 1.044756f, 0.287271f, 1.704574f, 0.760346f, 1.972481f, 0.270324f, 1.297408f, 0.425022f, 1.838728f, 0.533406f, 2.769685f, 1.334297f, 2.803199f, +0.105073f, 0.413219f, 0.046073f, 0.424389f, 0.203290f, 1.429517f, 0.578558f, 1.221837f, 0.152976f, 0.870092f, 0.258620f, 0.910821f, 0.300893f, 1.851539f, 0.809315f, 1.384150f, +0.343334f, 0.874255f, 0.090051f, 1.232536f, 0.439112f, 1.999316f, 0.747527f, 2.345755f, 0.481758f, 1.774205f, 0.487179f, 2.549464f, 0.698616f, 2.783514f, 1.123998f, 2.856414f, +0.066691f, 0.153453f, 0.020344f, 0.188659f, 0.149190f, 0.613805f, 0.295379f, 0.628018f, 0.037248f, 0.123955f, 0.043808f, 0.155328f, 0.215561f, 0.776084f, 0.403353f, 0.694508f, +0.090996f, 0.301452f, 0.039485f, 0.409572f, 0.178703f, 1.058557f, 0.503301f, 1.196923f, 0.148945f, 0.713636f, 0.249189f, 0.988263f, 0.276626f, 1.433912f, 0.736313f, 1.418081f, +0.038759f, 0.152167f, 0.018084f, 0.152707f, 0.116074f, 0.814827f, 0.351513f, 0.680526f, 0.077365f, 0.439281f, 0.139174f, 0.449331f, 0.143227f, 0.879838f, 0.409926f, 0.642700f, +0.186565f, 0.474252f, 0.052069f, 0.653319f, 0.369340f, 1.678764f, 0.669042f, 1.924624f, 0.358907f, 1.319513f, 0.386204f, 1.852738f, 0.489872f, 1.948477f, 0.838660f, 1.953791f, +0.260395f, 0.409766f, 0.074381f, 0.622600f, 0.365849f, 1.029413f, 0.678282f, 1.301678f, 0.073005f, 0.166152f, 0.080402f, 0.257314f, 0.675935f, 1.664338f, 1.184374f, 1.840695f, +0.275987f, 0.625292f, 0.112143f, 1.049946f, 0.340407f, 1.379042f, 0.897763f, 1.927087f, 0.226765f, 0.743057f, 0.355260f, 1.271716f, 0.673800f, 2.388684f, 1.679461f, 2.919504f, +0.161523f, 0.433689f, 0.070572f, 0.537884f, 0.303806f, 1.458558f, 0.861530f, 1.505478f, 0.161841f, 0.628468f, 0.272628f, 0.794471f, 0.479355f, 2.013882f, 1.284718f, 1.818073f, +0.519403f, 0.902986f, 0.135744f, 1.537337f, 0.645802f, 2.007522f, 1.095456f, 2.844385f, 0.501577f, 1.261150f, 0.505406f, 2.188462f, 1.095290f, 2.979471f, 1.755902f, 3.692272f, +0.337912f, 0.558647f, 0.089796f, 0.828173f, 0.536025f, 1.584545f, 0.924528f, 1.954914f, 0.089482f, 0.213955f, 0.091681f, 0.323289f, 0.601934f, 1.557101f, 0.981203f, 1.680221f, +0.381923f, 0.909078f, 0.144373f, 1.489342f, 0.531860f, 2.263644f, 1.304931f, 3.086324f, 0.296399f, 1.020365f, 0.431991f, 1.703857f, 0.639868f, 2.383141f, 1.483734f, 2.841905f, +0.067321f, 0.189900f, 0.027363f, 0.229797f, 0.142963f, 0.721079f, 0.377159f, 0.726178f, 0.063712f, 0.259923f, 0.099845f, 0.320590f, 0.137103f, 0.605137f, 0.341840f, 0.533016f, +0.575543f, 1.051200f, 0.139933f, 1.746156f, 0.807951f, 2.638624f, 1.274991f, 3.647666f, 0.524960f, 1.386714f, 0.492103f, 2.347839f, 0.832866f, 2.380218f, 1.242147f, 2.877933f, +0.489544f, 0.986069f, 0.121165f, 1.241205f, 0.753301f, 2.713117f, 1.210138f, 2.842133f, 0.173224f, 0.504633f, 0.165303f, 0.647434f, 1.086877f, 3.425542f, 1.650146f, 3.138569f, +0.777649f, 2.255227f, 0.273795f, 3.137157f, 1.050510f, 5.447430f, 2.400613f, 6.306345f, 0.806432f, 3.382418f, 1.094706f, 4.795760f, 1.623834f, 7.368546f, 3.507027f, 7.460953f, +0.302108f, 1.038286f, 0.114371f, 1.066817f, 0.622342f, 3.824452f, 1.529193f, 3.270259f, 0.382043f, 1.898978f, 0.557638f, 1.988735f, 0.766831f, 4.123715f, 1.780773f, 3.084097f, +1.068998f, 2.378843f, 0.242076f, 3.355182f, 1.455722f, 5.792315f, 2.139601f, 6.798959f, 1.302890f, 4.193238f, 1.137548f, 6.028147f, 1.928047f, 6.713359f, 2.678226f, 6.892179f, +0.256567f, 0.515910f, 0.067571f, 0.634549f, 0.611104f, 2.197214f, 1.044617f, 2.249072f, 0.124467f, 0.361977f, 0.126388f, 0.453791f, 0.735056f, 2.312740f, 1.187513f, 2.070543f, +0.377989f, 1.094317f, 0.141611f, 1.487457f, 0.790375f, 4.091496f, 1.921901f, 4.628320f, 0.537406f, 2.250192f, 0.776261f, 3.117488f, 1.018517f, 4.613877f, 2.340677f, 4.564925f, +0.134783f, 0.462432f, 0.054296f, 0.464276f, 0.429774f, 2.636561f, 1.123697f, 2.202956f, 0.233682f, 1.159552f, 0.362945f, 1.186595f, 0.441474f, 2.370013f, 1.090910f, 1.731990f, +0.702559f, 1.560734f, 0.169290f, 2.150969f, 1.480886f, 5.882374f, 2.316069f, 6.746802f, 1.173958f, 3.771827f, 1.090662f, 5.298356f, 1.635137f, 5.683737f, 2.416905f, 5.701719f, +0.673126f, 0.925693f, 0.166007f, 1.407115f, 1.006953f, 2.476078f, 1.611832f, 3.132327f, 0.163920f, 0.326028f, 0.155866f, 0.505129f, 1.548774f, 3.332665f, 2.343009f, 3.687406f, +0.770333f, 1.525247f, 0.270249f, 2.562200f, 1.011653f, 3.581605f, 2.303548f, 5.007151f, 0.549773f, 1.574337f, 0.743630f, 2.695594f, 1.667015f, 5.164575f, 3.587410f, 6.315009f, +0.377424f, 0.885604f, 0.142373f, 1.098852f, 0.755846f, 3.171232f, 1.850590f, 3.274673f, 0.328473f, 1.114713f, 0.477733f, 1.409765f, 0.992820f, 3.645139f, 2.297329f, 3.292156f, +1.314284f, 1.996793f, 0.296556f, 3.401027f, 1.739911f, 4.726674f, 2.548152f, 6.699968f, 1.102403f, 2.422351f, 0.959061f, 4.205312f, 2.456591f, 5.839962f, 3.400216f, 7.240250f, +0.282075f, 0.369634f, 0.086062f, 0.696942f, 0.317235f, 0.743315f, 0.628210f, 1.166373f, 0.062680f, 0.118793f, 0.073733f, 0.228297f, 0.417612f, 0.856276f, 0.781579f, 1.175181f, +0.327685f, 0.618237f, 0.142218f, 1.288219f, 0.323528f, 1.091430f, 0.911364f, 1.892651f, 0.213398f, 0.582295f, 0.357091f, 1.236693f, 0.456282f, 1.346996f, 1.214756f, 2.042995f, +0.071538f, 0.159949f, 0.033385f, 0.246175f, 0.107707f, 0.430601f, 0.326237f, 0.551539f, 0.056812f, 0.183712f, 0.102220f, 0.288193f, 0.121086f, 0.423618f, 0.346625f, 0.474572f, +0.465361f, 0.673706f, 0.129904f, 1.423343f, 0.463160f, 1.198937f, 0.839156f, 2.108023f, 0.356182f, 0.745771f, 0.383346f, 1.605937f, 0.559693f, 1.267840f, 0.958379f, 1.949709f, +0.382560f, 0.610785f, 0.108712f, 0.977835f, 0.417359f, 1.191470f, 0.769779f, 1.587451f, 0.113592f, 0.262295f, 0.124455f, 0.428007f, 0.705912f, 1.763487f, 1.230502f, 2.055020f, +0.624612f, 1.435788f, 0.252489f, 2.540257f, 0.598220f, 2.458813f, 1.569541f, 3.620369f, 0.543536f, 1.807011f, 0.847125f, 3.258609f, 1.084004f, 3.898919f, 2.687931f, 5.021091f, +0.300533f, 0.818693f, 0.130628f, 1.069881f, 0.438929f, 2.137998f, 1.238275f, 2.325206f, 0.318916f, 1.256486f, 0.534450f, 1.673617f, 0.634006f, 2.702435f, 1.690409f, 2.570608f, +0.809161f, 1.427240f, 0.210377f, 2.560287f, 0.781215f, 2.463867f, 1.318301f, 3.678314f, 0.827560f, 2.111127f, 0.829566f, 3.860024f, 1.212936f, 3.347600f, 1.934450f, 4.371108f, +0.087606f, 0.139631f, 0.026490f, 0.218431f, 0.147939f, 0.421613f, 0.290345f, 0.548891f, 0.035663f, 0.082209f, 0.041578f, 0.131080f, 0.208601f, 0.520231f, 0.386923f, 0.592373f, +0.132658f, 0.304418f, 0.057061f, 0.526275f, 0.196662f, 0.806943f, 0.549045f, 1.160981f, 0.158267f, 0.525267f, 0.262473f, 0.925564f, 0.297087f, 1.066731f, 0.783876f, 1.342345f, +0.058586f, 0.159323f, 0.027096f, 0.203446f, 0.132444f, 0.644024f, 0.397585f, 0.684403f, 0.085235f, 0.335239f, 0.151993f, 0.436323f, 0.159487f, 0.678647f, 0.452479f, 0.630783f, +0.232363f, 0.409154f, 0.064285f, 0.717189f, 0.347248f, 1.093312f, 0.623534f, 1.594891f, 0.325815f, 0.829742f, 0.347535f, 1.482429f, 0.449471f, 1.238381f, 0.762775f, 1.580038f, +0.407448f, 0.444136f, 0.115370f, 0.858658f, 0.432135f, 0.842262f, 0.794181f, 1.355163f, 0.083261f, 0.131262f, 0.090897f, 0.258658f, 0.779160f, 1.328934f, 1.353326f, 1.870139f, +0.479263f, 0.752157f, 0.193041f, 1.607026f, 0.446232f, 1.252218f, 1.166585f, 2.226560f, 0.287020f, 0.651478f, 0.445734f, 1.418724f, 0.861980f, 2.116730f, 2.129750f, 3.291897f, +0.290823f, 0.540894f, 0.125955f, 0.853598f, 0.412921f, 1.373203f, 1.160736f, 1.803498f, 0.212390f, 0.571307f, 0.354656f, 0.918956f, 0.635818f, 1.850330f, 1.689176f, 2.125479f, +0.770577f, 0.927968f, 0.199629f, 2.010255f, 0.723248f, 1.557361f, 1.216118f, 2.807680f, 0.542376f, 0.944649f, 0.541747f, 2.085801f, 1.197076f, 2.255653f, 1.902328f, 3.556781f, +0.267812f, 0.488756f, 0.086396f, 0.701461f, 0.342069f, 1.116250f, 0.716236f, 1.333254f, 0.064533f, 0.170333f, 0.080266f, 0.249169f, 0.496902f, 1.418950f, 0.983306f, 1.482330f, +0.338202f, 0.888649f, 0.155201f, 1.409456f, 0.379228f, 1.781720f, 1.129531f, 2.351802f, 0.238835f, 0.907622f, 0.422575f, 1.467272f, 0.590183f, 2.426467f, 1.661345f, 2.801317f, +0.074062f, 0.230620f, 0.036545f, 0.270175f, 0.126639f, 0.705110f, 0.405582f, 0.687457f, 0.063780f, 0.287235f, 0.121339f, 0.342981f, 0.157103f, 0.765458f, 0.475520f, 0.652733f, +0.463919f, 0.935361f, 0.136928f, 1.504197f, 0.524387f, 1.890486f, 1.004575f, 2.530108f, 0.385045f, 1.122796f, 0.438176f, 1.840392f, 0.699255f, 2.206002f, 1.266022f, 2.582248f, +0.347118f, 0.771830f, 0.104297f, 0.940558f, 0.430087f, 1.709955f, 0.838746f, 1.734158f, 0.111767f, 0.359426f, 0.129478f, 0.446434f, 0.802715f, 2.792793f, 1.479487f, 2.477246f, +0.616089f, 1.972325f, 0.263325f, 2.656151f, 0.670135f, 3.836032f, 1.859053f, 4.299285f, 0.581363f, 2.691757f, 0.958043f, 3.694826f, 1.339975f, 6.712211f, 3.513193f, 6.579701f, +0.297347f, 1.128102f, 0.136655f, 1.122146f, 0.493212f, 3.345821f, 1.471211f, 2.769769f, 0.342164f, 1.877463f, 0.606294f, 1.903516f, 0.786136f, 4.666758f, 2.216228f, 3.378957f, +0.770906f, 1.893733f, 0.211925f, 2.585812f, 0.845288f, 3.712849f, 1.508228f, 4.219156f, 0.854973f, 3.037545f, 0.906196f, 4.227513f, 1.448229f, 5.566577f, 2.442164f, 5.532647f, +0.166216f, 0.368955f, 0.053143f, 0.439332f, 0.318778f, 1.265244f, 0.661513f, 1.253815f, 0.073375f, 0.235560f, 0.090449f, 0.285893f, 0.496006f, 1.722749f, 0.972776f, 1.493164f, +0.273605f, 0.874414f, 0.124437f, 1.150659f, 0.460660f, 2.632439f, 1.359835f, 2.882886f, 0.353971f, 1.636115f, 0.620699f, 2.194457f, 0.767908f, 3.840037f, 2.142349f, 3.678164f, +0.121206f, 0.459055f, 0.059273f, 0.446191f, 0.311194f, 2.107448f, 0.987751f, 1.704719f, 0.191220f, 1.047436f, 0.360543f, 1.037690f, 0.413512f, 2.450547f, 1.240453f, 1.733747f, +0.462906f, 1.135187f, 0.135410f, 1.514610f, 0.785658f, 3.445033f, 1.491665f, 3.825311f, 0.703854f, 2.496379f, 0.793831f, 3.394907f, 1.122172f, 4.305940f, 2.013598f, 4.181843f, +0.399143f, 0.605937f, 0.119500f, 0.891699f, 0.480777f, 1.305050f, 0.934248f, 1.598299f, 0.088447f, 0.194194f, 0.102096f, 0.291280f, 0.956567f, 2.272207f, 1.756748f, 2.433914f, +0.510370f, 1.115514f, 0.217359f, 1.814162f, 0.539685f, 2.109187f, 1.491811f, 2.854670f, 0.331444f, 1.047738f, 0.544241f, 1.736752f, 1.150380f, 3.934279f, 3.005319f, 4.657281f, +0.310655f, 0.804669f, 0.142260f, 0.966597f, 0.500939f, 2.320108f, 1.488914f, 2.319402f, 0.246019f, 0.921640f, 0.434372f, 1.128426f, 0.851168f, 3.449749f, 2.390978f, 3.016350f, +0.792611f, 1.329329f, 0.217113f, 2.191986f, 0.844890f, 2.533713f, 1.502126f, 3.476983f, 0.604967f, 1.467429f, 0.638918f, 2.466301f, 1.543118f, 4.049534f, 2.592870f, 4.860451f, +0.140778f, 0.266318f, 0.043330f, 0.394635f, 0.194337f, 0.657368f, 0.388230f, 0.810667f, 0.040122f, 0.109776f, 0.047613f, 0.165800f, 0.280912f, 0.831515f, 0.530368f, 0.896873f, +0.151341f, 0.412206f, 0.066262f, 0.675024f, 0.183408f, 0.893228f, 0.521203f, 1.217325f, 0.126409f, 0.497953f, 0.213389f, 0.831145f, 0.284028f, 1.210469f, 0.762824f, 1.442860f, +0.037245f, 0.120219f, 0.017534f, 0.145414f, 0.068830f, 0.397258f, 0.210319f, 0.399893f, 0.037936f, 0.177098f, 0.068859f, 0.218338f, 0.084967f, 0.429134f, 0.245373f, 0.377825f, +0.222755f, 0.465551f, 0.062729f, 0.772993f, 0.272129f, 1.016951f, 0.497387f, 1.405233f, 0.218672f, 0.660979f, 0.237422f, 1.118614f, 0.361089f, 1.180833f, 0.623749f, 1.427130f, +0.161218f, 0.371588f, 0.046216f, 0.467529f, 0.215889f, 0.889740f, 0.401693f, 0.931644f, 0.061397f, 0.204667f, 0.067861f, 0.262470f, 0.400951f, 1.446016f, 0.705068f, 1.324300f, +0.243588f, 0.808340f, 0.099333f, 1.123961f, 0.286360f, 1.699168f, 0.757934f, 1.966226f, 0.271868f, 1.304820f, 0.427450f, 1.849233f, 0.569775f, 2.958530f, 1.425273f, 2.994328f, +0.132120f, 0.519585f, 0.057932f, 0.533630f, 0.236852f, 1.665518f, 0.674073f, 1.423552f, 0.179820f, 1.022772f, 0.304002f, 1.070648f, 0.375662f, 2.311629f, 1.010422f, 1.728099f, +0.327052f, 0.832795f, 0.085780f, 1.174084f, 0.387578f, 1.764676f, 0.659797f, 2.070457f, 0.429009f, 1.579941f, 0.433836f, 2.270315f, 0.660765f, 2.632705f, 1.063100f, 2.701654f, +0.076040f, 0.174964f, 0.023195f, 0.215105f, 0.157615f, 0.648466f, 0.312059f, 0.663482f, 0.039702f, 0.132122f, 0.046694f, 0.165562f, 0.244035f, 0.878599f, 0.456633f, 0.786248f, +0.106554f, 0.352994f, 0.046237f, 0.479601f, 0.193894f, 1.148542f, 0.546085f, 1.298671f, 0.163047f, 0.781201f, 0.272782f, 1.081830f, 0.321625f, 1.667172f, 0.856092f, 1.648766f, +0.053047f, 0.208261f, 0.024751f, 0.209000f, 0.147200f, 1.033328f, 0.445773f, 0.863012f, 0.098985f, 0.562042f, 0.178068f, 0.574900f, 0.194635f, 1.195640f, 0.557062f, 0.873386f, +0.193438f, 0.491724f, 0.053987f, 0.677388f, 0.354831f, 1.612819f, 0.642760f, 1.849021f, 0.347881f, 1.278978f, 0.374340f, 1.795823f, 0.504317f, 2.005933f, 0.863390f, 2.011403f, +0.232694f, 0.366174f, 0.066468f, 0.556367f, 0.302927f, 0.852366f, 0.561625f, 1.077804f, 0.060987f, 0.138802f, 0.067167f, 0.214958f, 0.599745f, 1.476736f, 1.050872f, 1.633214f, +0.253290f, 0.573867f, 0.102920f, 0.963597f, 0.289475f, 1.172708f, 0.763439f, 1.638753f, 0.194554f, 0.637512f, 0.304798f, 1.091078f, 0.614000f, 2.176687f, 1.530408f, 2.660397f, +0.173262f, 0.465207f, 0.075700f, 0.576975f, 0.301959f, 1.449691f, 0.856293f, 1.496326f, 0.162291f, 0.630215f, 0.273386f, 0.796680f, 0.510546f, 2.144920f, 1.368311f, 1.936370f, +0.422081f, 0.733791f, 0.110309f, 1.249282f, 0.486267f, 1.511596f, 0.824841f, 2.141725f, 0.381036f, 0.958067f, 0.383946f, 1.662523f, 0.883750f, 2.404028f, 1.416775f, 2.979161f, +0.362667f, 0.599574f, 0.096375f, 0.888845f, 0.533058f, 1.575773f, 0.919410f, 1.944092f, 0.089780f, 0.214667f, 0.091986f, 0.324364f, 0.641450f, 1.659323f, 1.045618f, 1.790526f, +0.420975f, 1.002034f, 0.159135f, 1.641632f, 0.543204f, 2.311922f, 1.332762f, 3.152148f, 0.305419f, 1.051416f, 0.445137f, 1.755706f, 0.700295f, 2.608195f, 1.623852f, 3.110283f, +0.086730f, 0.244650f, 0.035253f, 0.296051f, 0.170659f, 0.860771f, 0.450225f, 0.866858f, 0.076732f, 0.313043f, 0.120250f, 0.386107f, 0.175378f, 0.774076f, 0.437273f, 0.681821f, +0.561723f, 1.025959f, 0.136573f, 1.704227f, 0.730656f, 2.386194f, 1.153016f, 3.298704f, 0.478969f, 1.265228f, 0.448991f, 2.142152f, 0.807103f, 2.306589f, 1.203723f, 2.788908f, +0.530877f, 1.069324f, 0.131395f, 1.346000f, 0.756927f, 2.726177f, 1.215963f, 2.855815f, 0.175609f, 0.511581f, 0.167579f, 0.656348f, 1.170283f, 3.688416f, 1.776778f, 3.379421f, +0.866087f, 2.511702f, 0.304932f, 3.493930f, 1.084081f, 5.621514f, 2.477329f, 6.507877f, 0.839620f, 3.521620f, 1.139758f, 4.993127f, 1.795678f, 8.148329f, 3.878161f, 8.250515f, +0.393260f, 1.351558f, 0.148879f, 1.388697f, 0.750638f, 4.612864f, 1.844437f, 3.944424f, 0.464908f, 2.310867f, 0.678590f, 2.420092f, 0.991120f, 5.329851f, 2.301627f, 3.986158f, +1.054188f, 2.345885f, 0.238722f, 3.308697f, 1.330158f, 5.292696f, 1.955049f, 6.212511f, 1.201119f, 3.865698f, 1.048692f, 5.557279f, 1.887850f, 6.573395f, 2.622389f, 6.748488f, +0.302841f, 0.608959f, 0.079759f, 0.748995f, 0.668364f, 2.403092f, 1.142497f, 2.459809f, 0.137343f, 0.399422f, 0.139462f, 0.500734f, 0.861477f, 2.710503f, 1.391751f, 2.426651f, +0.458215f, 1.326580f, 0.171667f, 1.803162f, 0.887784f, 4.595748f, 2.158763f, 5.198732f, 0.609018f, 2.550041f, 0.879702f, 3.532909f, 1.225936f, 5.553479f, 2.817350f, 5.494559f, +0.190970f, 0.655206f, 0.076930f, 0.657819f, 0.564227f, 3.461398f, 1.475241f, 2.892142f, 0.309522f, 1.535881f, 0.480738f, 1.571700f, 0.621074f, 3.334185f, 1.534716f, 2.436600f, +0.754112f, 1.675260f, 0.181713f, 2.308807f, 1.472851f, 5.850457f, 2.303502f, 6.710195f, 1.177994f, 3.784796f, 1.094412f, 5.316574f, 1.742675f, 6.057539f, 2.575858f, 6.076704f, +0.622716f, 0.856368f, 0.153575f, 1.301737f, 0.863151f, 2.122470f, 1.381647f, 2.685000f, 0.141763f, 0.281959f, 0.134797f, 0.436850f, 1.422625f, 3.061217f, 2.152170f, 3.387064f, +0.731894f, 1.449138f, 0.256764f, 2.434348f, 0.890604f, 3.153052f, 2.027920f, 4.408025f, 0.488304f, 1.398314f, 0.660486f, 2.394206f, 1.572600f, 4.872066f, 3.384227f, 5.957341f, +0.419120f, 0.983442f, 0.158101f, 1.220250f, 0.777725f, 3.263031f, 1.904160f, 3.369466f, 0.340994f, 1.157203f, 0.495943f, 1.463503f, 1.094684f, 4.019133f, 2.533036f, 3.629933f, +1.105661f, 1.679831f, 0.249482f, 2.861164f, 1.356262f, 3.684445f, 1.986286f, 5.222630f, 0.866983f, 1.905054f, 0.754252f, 3.307260f, 2.051986f, 4.878111f, 2.840195f, 6.047769f, +0.445386f, 0.583638f, 0.135888f, 1.100445f, 0.537770f, 1.260054f, 1.064930f, 1.977214f, 0.090865f, 0.172209f, 0.106888f, 0.330952f, 0.587024f, 1.203642f, 1.098642f, 1.651918f, +0.583587f, 1.101043f, 0.253282f, 2.294240f, 0.618594f, 2.086842f, 1.742552f, 3.618797f, 0.348926f, 0.952107f, 0.583877f, 2.022109f, 0.723427f, 2.135636f, 1.925973f, 3.239131f, +0.114375f, 0.255727f, 0.053375f, 0.393585f, 0.184876f, 0.739117f, 0.559979f, 0.946705f, 0.083392f, 0.269665f, 0.150045f, 0.423029f, 0.172345f, 0.602948f, 0.493362f, 0.675473f, +0.819179f, 1.185931f, 0.228671f, 2.505524f, 0.875314f, 2.265844f, 1.585902f, 3.983904f, 0.575644f, 1.205280f, 0.619546f, 2.595439f, 0.877103f, 1.986851f, 1.501891f, 3.055418f, +0.473585f, 0.756112f, 0.134578f, 1.210497f, 0.554693f, 1.583528f, 1.023078f, 2.109809f, 0.129104f, 0.298113f, 0.141450f, 0.486455f, 0.777966f, 1.943491f, 1.356102f, 2.264781f, +0.872140f, 2.004777f, 0.352548f, 3.546937f, 0.896770f, 3.685919f, 2.352843f, 5.427167f, 0.696783f, 2.316489f, 1.085968f, 4.177357f, 1.347469f, 4.846543f, 3.341227f, 6.241456f, +0.376715f, 1.026223f, 0.163741f, 1.341084f, 0.590689f, 2.877215f, 1.666411f, 3.129152f, 0.367021f, 1.446012f, 0.615065f, 1.926062f, 0.707499f, 3.015698f, 1.886359f, 2.868590f, +1.116737f, 1.969757f, 0.290345f, 3.533494f, 1.157525f, 3.650711f, 1.953326f, 5.450157f, 1.048597f, 2.674998f, 1.051139f, 4.891016f, 1.490272f, 4.113023f, 2.376759f, 5.370555f, +0.072602f, 0.115716f, 0.021953f, 0.181019f, 0.131625f, 0.375120f, 0.258328f, 0.488362f, 0.027135f, 0.062550f, 0.031635f, 0.099734f, 0.153901f, 0.383814f, 0.285462f, 0.437038f, +0.124000f, 0.284551f, 0.053337f, 0.491928f, 0.197358f, 0.809798f, 0.550988f, 1.165089f, 0.135823f, 0.450778f, 0.225251f, 0.794309f, 0.247221f, 0.887680f, 0.652302f, 1.117032f, +0.049162f, 0.133694f, 0.022738f, 0.170719f, 0.119319f, 0.580205f, 0.358187f, 0.616582f, 0.065666f, 0.258275f, 0.117098f, 0.336152f, 0.119144f, 0.506979f, 0.338022f, 0.471223f, +0.214682f, 0.378021f, 0.059393f, 0.662617f, 0.344440f, 1.084471f, 0.618491f, 1.581994f, 0.276372f, 0.703827f, 0.294796f, 1.257467f, 0.369694f, 1.018581f, 0.627390f, 1.299597f, +0.630310f, 0.687065f, 0.178474f, 1.328318f, 0.717704f, 1.398858f, 1.319003f, 2.250700f, 0.118254f, 0.186429f, 0.129100f, 0.367368f, 1.073050f, 1.830194f, 1.863786f, 2.575536f, +0.836244f, 1.312405f, 0.336828f, 2.804027f, 0.835920f, 2.345762f, 2.185346f, 4.170981f, 0.459796f, 1.043644f, 0.714049f, 2.272745f, 1.338963f, 3.288038f, 3.308262f, 5.113492f, +0.455547f, 0.847259f, 0.197297f, 1.337080f, 0.694409f, 2.309315f, 1.952010f, 3.032944f, 0.305443f, 0.821612f, 0.510041f, 1.321576f, 0.886643f, 2.580271f, 2.355543f, 2.963964f, +1.328969f, 1.600412f, 0.344289f, 3.466972f, 1.339156f, 2.883586f, 2.251745f, 5.198659f, 0.858802f, 1.495764f, 0.857806f, 3.302673f, 1.837947f, 3.463246f, 2.920764f, 5.460950f, +0.342680f, 0.625390f, 0.110548f, 0.897558f, 0.469912f, 1.533433f, 0.983919f, 1.831538f, 0.075811f, 0.200101f, 0.094294f, 0.292716f, 0.566032f, 1.616359f, 1.120106f, 1.688556f, +0.488104f, 1.282527f, 0.223991f, 2.034173f, 0.587599f, 2.760707f, 1.750165f, 3.644027f, 0.316466f, 1.202638f, 0.559929f, 1.944197f, 0.758289f, 3.117616f, 2.134559f, 3.599237f, +0.095957f, 0.298798f, 0.047348f, 0.350047f, 0.176155f, 0.980805f, 0.564162f, 0.956249f, 0.075868f, 0.341674f, 0.144336f, 0.407985f, 0.181208f, 0.882905f, 0.548482f, 0.752885f, +0.661788f, 1.334305f, 0.195330f, 2.145758f, 0.803106f, 2.895303f, 1.538519f, 3.874892f, 0.504290f, 1.470518f, 0.573877f, 2.410349f, 0.888022f, 2.801521f, 1.607790f, 3.279336f, +0.348227f, 0.774296f, 0.104630f, 0.943563f, 0.463218f, 1.841682f, 0.903359f, 1.867749f, 0.102942f, 0.331046f, 0.119254f, 0.411184f, 0.716900f, 2.494228f, 1.321322f, 2.212415f, +0.697118f, 2.231729f, 0.297959f, 3.005493f, 0.814085f, 4.660040f, 2.258392f, 5.222804f, 0.603954f, 2.796355f, 0.995271f, 3.838402f, 1.349807f, 6.761461f, 3.538971f, 6.627979f, +0.302045f, 1.145924f, 0.138814f, 1.139874f, 0.537881f, 3.648841f, 1.604454f, 3.020618f, 0.319107f, 1.750946f, 0.565437f, 1.775242f, 0.710915f, 4.220219f, 2.004168f, 3.055641f, +0.862192f, 2.117978f, 0.237020f, 2.892010f, 1.014968f, 4.458149f, 1.810983f, 5.066089f, 0.877907f, 3.119025f, 0.930504f, 4.340914f, 1.441956f, 5.542465f, 2.431585f, 5.508681f, +0.111628f, 0.247784f, 0.035690f, 0.295047f, 0.229843f, 0.912258f, 0.476960f, 0.904018f, 0.045242f, 0.145242f, 0.055769f, 0.176277f, 0.296550f, 1.029990f, 0.581599f, 0.892726f, +0.207253f, 0.662360f, 0.094260f, 0.871612f, 0.374630f, 2.140817f, 1.105878f, 2.344492f, 0.246172f, 1.137847f, 0.431669f, 1.526150f, 0.517843f, 2.589548f, 1.444704f, 2.480388f, +0.082422f, 0.312167f, 0.040307f, 0.303419f, 0.227194f, 1.538589f, 0.721129f, 1.244568f, 0.119385f, 0.653946f, 0.225098f, 0.647862f, 0.250335f, 1.483530f, 0.750955f, 1.049588f, +0.346584f, 0.849931f, 0.101383f, 1.134011f, 0.631531f, 2.769199f, 1.199036f, 3.074876f, 0.483830f, 1.716012f, 0.545680f, 2.333661f, 0.747976f, 2.870095f, 1.342150f, 2.787380f, +0.500377f, 0.759620f, 0.149808f, 1.117860f, 0.647078f, 1.756469f, 1.257405f, 2.151153f, 0.101800f, 0.223511f, 0.117509f, 0.335253f, 1.067570f, 2.535880f, 1.960605f, 2.716351f, +0.721658f, 1.577326f, 0.307344f, 2.565207f, 0.819277f, 3.201887f, 2.264669f, 4.333581f, 0.430279f, 1.360169f, 0.706531f, 2.254643f, 1.448104f, 4.952489f, 3.783111f, 5.862609f, +0.394339f, 1.021430f, 0.180582f, 1.226977f, 0.682685f, 3.161869f, 2.029109f, 3.160907f, 0.286717f, 1.074103f, 0.506229f, 1.315097f, 0.961874f, 3.898438f, 2.701959f, 3.408670f, +1.107762f, 1.857885f, 0.303440f, 3.063542f, 1.267742f, 3.801790f, 2.253912f, 5.217149f, 0.776267f, 1.882941f, 0.819832f, 3.164651f, 1.919983f, 5.038523f, 3.226108f, 6.047485f, +0.276565f, 0.523196f, 0.085123f, 0.775280f, 0.409887f, 1.386488f, 0.818835f, 1.709820f, 0.072367f, 0.197999f, 0.085878f, 0.299048f, 0.491298f, 1.454271f, 0.927582f, 1.568577f, +0.335349f, 0.913388f, 0.146826f, 1.495752f, 0.436319f, 2.124945f, 1.239915f, 2.895956f, 0.257165f, 1.013031f, 0.434117f, 1.690873f, 0.560292f, 2.387846f, 1.504795f, 2.846276f, +0.074089f, 0.239144f, 0.034880f, 0.289262f, 0.146998f, 0.848404f, 0.449169f, 0.854031f, 0.069284f, 0.323439f, 0.125759f, 0.398757f, 0.150470f, 0.759959f, 0.434534f, 0.669095f, +0.487873f, 1.019642f, 0.137387f, 1.692997f, 0.639881f, 2.391249f, 1.169551f, 3.304254f, 0.439712f, 1.329112f, 0.477414f, 2.249335f, 0.704056f, 2.302401f, 1.216192f, 2.782633f, +0.248315f, 0.572336f, 0.071185f, 0.720108f, 0.356997f, 1.471286f, 0.664245f, 1.540580f, 0.086822f, 0.289422f, 0.095963f, 0.371161f, 0.549786f, 1.982782f, 0.966792f, 1.815885f, +0.423177f, 1.404306f, 0.172569f, 1.952625f, 0.534102f, 3.169190f, 1.413655f, 3.667290f, 0.433630f, 2.081188f, 0.681783f, 2.949528f, 0.881216f, 4.575677f, 2.204334f, 4.631043f, +0.206054f, 0.810343f, 0.090351f, 0.832248f, 0.396582f, 2.788727f, 1.128662f, 2.383581f, 0.257480f, 1.464483f, 0.435293f, 1.533036f, 0.521580f, 3.209537f, 1.402901f, 2.399345f, +0.561596f, 1.430030f, 0.147297f, 2.016074f, 0.714513f, 3.253244f, 1.216360f, 3.816962f, 0.676343f, 2.490815f, 0.683953f, 3.579206f, 1.010104f, 4.024587f, 1.625150f, 4.129989f, +0.078405f, 0.180406f, 0.023917f, 0.221796f, 0.174480f, 0.717852f, 0.345449f, 0.734475f, 0.037585f, 0.125075f, 0.044204f, 0.156732f, 0.224010f, 0.806504f, 0.419163f, 0.721730f, +0.123923f, 0.410533f, 0.053773f, 0.557777f, 0.242098f, 1.434077f, 0.681846f, 1.621529f, 0.174096f, 0.834137f, 0.291266f, 1.155137f, 0.332999f, 1.726130f, 0.886367f, 1.707072f, +0.055385f, 0.217437f, 0.025841f, 0.218209f, 0.164998f, 1.158266f, 0.499671f, 0.967358f, 0.094883f, 0.538751f, 0.170688f, 0.551076f, 0.180909f, 1.111318f, 0.517775f, 0.811790f, +0.222363f, 0.565252f, 0.062060f, 0.778679f, 0.437912f, 1.990448f, 0.793258f, 2.281956f, 0.367152f, 1.349825f, 0.395076f, 1.895299f, 0.516103f, 2.052812f, 0.883567f, 2.058410f, +0.447876f, 0.704792f, 0.127934f, 1.070866f, 0.625973f, 1.761342f, 1.160550f, 2.227191f, 0.107772f, 0.245280f, 0.118692f, 0.379857f, 1.027665f, 2.530394f, 1.800674f, 2.798519f, +0.549880f, 1.245840f, 0.223435f, 2.091925f, 0.674693f, 2.733286f, 1.779383f, 3.819522f, 0.387780f, 1.270669f, 0.607514f, 2.174705f, 1.186673f, 4.206869f, 2.957808f, 5.141730f, +0.337675f, 0.906655f, 0.147535f, 1.124483f, 0.631812f, 3.033302f, 1.791689f, 3.130880f, 0.290390f, 1.127660f, 0.489175f, 1.425519f, 0.885814f, 3.721505f, 2.374064f, 3.359664f, +0.905705f, 1.574574f, 0.236702f, 2.680718f, 1.120236f, 3.482338f, 1.900226f, 4.933997f, 0.750672f, 1.887469f, 0.756404f, 3.275306f, 1.688232f, 4.592426f, 2.706471f, 5.691106f, +0.506835f, 0.837917f, 0.134686f, 1.242180f, 0.799792f, 2.364266f, 1.379469f, 2.916887f, 0.115194f, 0.275434f, 0.118025f, 0.416183f, 0.798056f, 2.064435f, 1.300899f, 2.227670f, +0.663579f, 1.579495f, 0.250843f, 2.587686f, 0.919270f, 3.912494f, 2.255450f, 5.334418f, 0.442003f, 1.521612f, 0.644203f, 2.540863f, 0.982718f, 3.660058f, 2.278737f, 4.364633f, +0.122731f, 0.346200f, 0.049885f, 0.418935f, 0.259271f, 1.307714f, 0.683998f, 1.316962f, 0.099690f, 0.406704f, 0.156228f, 0.501629f, 0.220937f, 0.975161f, 0.550865f, 0.858940f, +0.875181f, 1.598474f, 0.212784f, 2.655236f, 1.222175f, 3.991407f, 1.928660f, 5.517769f, 0.685136f, 1.809830f, 0.642254f, 3.064216f, 1.119480f, 3.199321f, 1.669607f, 3.868314f, +0.581673f, 1.171640f, 0.143968f, 1.474790f, 0.890396f, 3.206886f, 1.430375f, 3.359383f, 0.176654f, 0.514627f, 0.168577f, 0.660257f, 1.141532f, 3.597799f, 1.733126f, 3.296395f, +1.070346f, 3.104064f, 0.376848f, 4.317941f, 1.438364f, 7.458652f, 3.286933f, 8.634684f, 0.952662f, 3.995753f, 1.293209f, 5.665375f, 1.975618f, 8.964852f, 4.266782f, 9.077278f, +0.436302f, 1.499484f, 0.165173f, 1.540689f, 0.894092f, 5.494428f, 2.196927f, 4.698242f, 0.473552f, 2.353834f, 0.691207f, 2.465090f, 0.978917f, 5.264224f, 2.273287f, 3.937076f, +1.287717f, 2.865558f, 0.291605f, 4.041656f, 1.744416f, 6.941028f, 2.563920f, 8.147307f, 1.347044f, 4.335345f, 1.176099f, 6.232438f, 2.052966f, 7.148322f, 2.851750f, 7.338728f, +0.222133f, 0.446670f, 0.058503f, 0.549386f, 0.526327f, 1.892402f, 0.899701f, 1.937067f, 0.092491f, 0.268983f, 0.093918f, 0.337209f, 0.562541f, 1.769948f, 0.908808f, 1.584594f, +0.379093f, 1.097513f, 0.142024f, 1.491801f, 0.788548f, 4.082037f, 1.917457f, 4.617619f, 0.462594f, 1.936943f, 0.668198f, 2.683503f, 0.902934f, 4.090283f, 2.075052f, 4.046886f, +0.141836f, 0.486630f, 0.057137f, 0.488570f, 0.449904f, 2.760050f, 1.176328f, 2.306137f, 0.211060f, 1.047302f, 0.327811f, 1.071727f, 0.410654f, 2.204564f, 1.014754f, 1.611080f, +0.616669f, 1.369929f, 0.148594f, 1.888007f, 1.293062f, 5.136299f, 2.022317f, 5.891090f, 0.884408f, 2.841528f, 0.821657f, 3.991548f, 1.268658f, 4.409854f, 1.875210f, 4.423806f, +0.852626f, 1.172543f, 0.210276f, 1.782344f, 1.268818f, 3.120000f, 2.031001f, 3.946911f, 0.178207f, 0.354444f, 0.169451f, 0.549155f, 1.734087f, 3.731424f, 2.623354f, 4.128609f, +1.130301f, 2.237977f, 0.396533f, 3.759487f, 1.476643f, 5.227833f, 3.362337f, 7.308607f, 0.692356f, 1.982641f, 0.936490f, 3.394697f, 2.162102f, 6.698401f, 4.652834f, 8.190502f, +0.581071f, 1.363451f, 0.219193f, 1.691763f, 1.157608f, 4.856871f, 2.834254f, 5.015293f, 0.434041f, 1.472970f, 0.631271f, 1.862850f, 1.351113f, 4.960611f, 3.126397f, 4.480241f, +1.687749f, 2.564198f, 0.380825f, 4.367457f, 2.222665f, 6.038130f, 3.255159f, 8.558932f, 1.215038f, 2.669848f, 1.057051f, 4.634978f, 2.788510f, 6.629022f, 3.859632f, 8.218508f, +}; + +static const float acceptor_me2x3acc2[16384] = { +0.028739f, 0.051428f, 0.000313f, 0.073324f, 0.034680f, 0.087951f, 0.021917f, 0.102035f, 0.000252f, 0.000765f, 0.000211f, 0.001303f, 0.086087f, 0.188764f, 0.066268f, 0.215400f, +0.034283f, 0.056280f, 0.000377f, 0.081658f, 0.058641f, 0.136431f, 0.037455f, 0.161069f, 0.023430f, 0.065190f, 0.019763f, 0.112954f, 0.091516f, 0.184088f, 0.071197f, 0.213767f, +0.000407f, 0.000736f, 0.000005f, 0.000961f, 0.000959f, 0.002458f, 0.000722f, 0.002610f, 0.000251f, 0.000770f, 0.000250f, 0.001200f, 0.001973f, 0.004369f, 0.001807f, 0.004564f, +0.056136f, 0.110463f, 0.000789f, 0.143996f, 0.140495f, 0.391797f, 0.114664f, 0.415578f, 0.037582f, 0.125335f, 0.040506f, 0.195116f, 0.152611f, 0.367964f, 0.151713f, 0.383898f, +0.035291f, 0.086949f, 0.000364f, 0.110031f, 0.040326f, 0.140805f, 0.024134f, 0.144985f, 0.000333f, 0.001390f, 0.000263f, 0.002100f, 0.096583f, 0.291575f, 0.070407f, 0.295308f, +0.059092f, 0.133562f, 0.000615f, 0.171997f, 0.095713f, 0.306585f, 0.057892f, 0.321253f, 0.043382f, 0.166183f, 0.034652f, 0.255569f, 0.144117f, 0.399132f, 0.106178f, 0.411368f, +0.026513f, 0.065985f, 0.000325f, 0.076430f, 0.059155f, 0.208640f, 0.042131f, 0.196639f, 0.017575f, 0.074131f, 0.016530f, 0.102541f, 0.117347f, 0.357850f, 0.101800f, 0.331735f, +0.084513f, 0.228965f, 0.001124f, 0.264913f, 0.200288f, 0.768999f, 0.154800f, 0.723963f, 0.060777f, 0.279067f, 0.062035f, 0.385591f, 0.209909f, 0.696825f, 0.197614f, 0.645258f, +0.000302f, 0.001475f, 0.000005f, 0.001613f, 0.000400f, 0.002769f, 0.000416f, 0.002464f, 0.000003f, 0.000028f, 0.000005f, 0.000037f, 0.001070f, 0.006402f, 0.001353f, 0.005604f, +0.000430f, 0.001928f, 0.000008f, 0.002146f, 0.000808f, 0.005130f, 0.000848f, 0.004646f, 0.000376f, 0.002852f, 0.000521f, 0.003791f, 0.001358f, 0.007457f, 0.001737f, 0.006643f, +0.000177f, 0.000874f, 0.000004f, 0.000875f, 0.000458f, 0.003203f, 0.000566f, 0.002609f, 0.000140f, 0.001167f, 0.000228f, 0.001395f, 0.001014f, 0.006133f, 0.001527f, 0.004914f, +0.000826f, 0.004438f, 0.000019f, 0.004438f, 0.002270f, 0.017278f, 0.003045f, 0.014059f, 0.000707f, 0.006432f, 0.001252f, 0.007681f, 0.002656f, 0.017481f, 0.004340f, 0.013991f, +0.091342f, 0.202450f, 0.001093f, 0.214612f, 0.085940f, 0.269942f, 0.059752f, 0.232843f, 0.000775f, 0.002911f, 0.000711f, 0.003685f, 0.256620f, 0.696928f, 0.217328f, 0.591287f, +0.156262f, 0.317725f, 0.001890f, 0.342749f, 0.208397f, 0.600508f, 0.146437f, 0.527108f, 0.103177f, 0.355557f, 0.095746f, 0.458055f, 0.391221f, 0.974695f, 0.334848f, 0.841529f, +0.064571f, 0.144564f, 0.000920f, 0.140269f, 0.118620f, 0.376366f, 0.098146f, 0.297145f, 0.038496f, 0.146072f, 0.042064f, 0.169259f, 0.293377f, 0.804820f, 0.295672f, 0.624993f, +0.163052f, 0.397389f, 0.002520f, 0.385156f, 0.318167f, 1.098934f, 0.285680f, 0.866659f, 0.105462f, 0.435623f, 0.125055f, 0.504214f, 0.415736f, 1.241521f, 0.454686f, 0.963052f, +0.026316f, 0.066875f, 0.000385f, 0.071194f, 0.027083f, 0.097539f, 0.023015f, 0.084491f, 0.000232f, 0.000998f, 0.000260f, 0.001268f, 0.068795f, 0.214218f, 0.071208f, 0.182519f, +0.047793f, 0.111420f, 0.000706f, 0.120706f, 0.069721f, 0.230352f, 0.059878f, 0.203055f, 0.032741f, 0.129366f, 0.037134f, 0.167367f, 0.111340f, 0.318055f, 0.116473f, 0.275767f, +0.000575f, 0.001475f, 0.000010f, 0.001438f, 0.001155f, 0.004202f, 0.001168f, 0.003331f, 0.000356f, 0.001547f, 0.000475f, 0.001800f, 0.002430f, 0.007643f, 0.002993f, 0.005961f, +0.074404f, 0.207915f, 0.001405f, 0.202370f, 0.158812f, 0.628929f, 0.174283f, 0.498102f, 0.049930f, 0.236471f, 0.072362f, 0.274867f, 0.176525f, 0.604427f, 0.235963f, 0.470846f, +0.054146f, 0.189449f, 0.000750f, 0.179006f, 0.052768f, 0.261648f, 0.042464f, 0.201163f, 0.000512f, 0.003036f, 0.000544f, 0.003425f, 0.129323f, 0.554431f, 0.126764f, 0.419274f, +0.138031f, 0.443047f, 0.001932f, 0.426005f, 0.190673f, 0.867340f, 0.155075f, 0.678594f, 0.101575f, 0.552570f, 0.109099f, 0.634505f, 0.293786f, 1.155453f, 0.291040f, 0.889184f, +0.062705f, 0.221615f, 0.001034f, 0.191664f, 0.119315f, 0.597617f, 0.114264f, 0.420552f, 0.041664f, 0.249567f, 0.052693f, 0.257758f, 0.242201f, 1.048876f, 0.282525f, 0.726005f, +0.187688f, 0.722103f, 0.003357f, 0.623820f, 0.379347f, 2.068363f, 0.394237f, 1.453927f, 0.135296f, 0.882213f, 0.185688f, 0.910157f, 0.406828f, 1.917883f, 0.514992f, 1.326040f, +0.016347f, 0.113386f, 0.000393f, 0.092596f, 0.018467f, 0.181521f, 0.025793f, 0.120620f, 0.000184f, 0.002160f, 0.000339f, 0.002107f, 0.050532f, 0.429464f, 0.085970f, 0.280696f, +0.035459f, 0.225629f, 0.000862f, 0.187508f, 0.056779f, 0.512010f, 0.080149f, 0.346225f, 0.031026f, 0.334591f, 0.057839f, 0.332064f, 0.097679f, 0.761570f, 0.167950f, 0.506534f, +0.014776f, 0.103528f, 0.000423f, 0.077385f, 0.032592f, 0.323613f, 0.054173f, 0.196826f, 0.011674f, 0.138621f, 0.025625f, 0.123741f, 0.073868f, 0.634155f, 0.149554f, 0.379377f, +0.064742f, 0.493788f, 0.002010f, 0.368689f, 0.151681f, 1.639505f, 0.273598f, 0.996066f, 0.055491f, 0.717295f, 0.132184f, 0.639588f, 0.181625f, 1.697372f, 0.399048f, 1.014311f, +0.080868f, 0.254532f, 0.001301f, 0.201467f, 0.064889f, 0.289445f, 0.060664f, 0.186416f, 0.000688f, 0.003668f, 0.000849f, 0.003467f, 0.198274f, 0.764682f, 0.225784f, 0.484414f, +0.210619f, 0.608155f, 0.003425f, 0.489853f, 0.239556f, 0.980286f, 0.226344f, 0.642480f, 0.139400f, 0.682192f, 0.173941f, 0.656207f, 0.460188f, 1.628172f, 0.529620f, 1.049605f, +0.088118f, 0.280163f, 0.001687f, 0.202973f, 0.138058f, 0.622059f, 0.153596f, 0.366703f, 0.052660f, 0.283761f, 0.077371f, 0.245506f, 0.349402f, 1.361186f, 0.473493f, 0.789258f, +0.208946f, 0.723173f, 0.004342f, 0.523345f, 0.347723f, 1.705565f, 0.419819f, 1.004315f, 0.135468f, 0.794642f, 0.215996f, 0.686752f, 0.464936f, 1.971734f, 0.683739f, 1.142007f, +0.000383f, 0.000697f, 0.000006f, 0.001236f, 0.000447f, 0.001154f, 0.000387f, 0.001666f, 0.000005f, 0.000014f, 0.000005f, 0.000030f, 0.001259f, 0.002809f, 0.001326f, 0.003989f, +0.000625f, 0.001044f, 0.000009f, 0.001886f, 0.001036f, 0.002452f, 0.000905f, 0.003603f, 0.000582f, 0.001647f, 0.000671f, 0.003551f, 0.001833f, 0.003753f, 0.001952f, 0.005424f, +0.000008f, 0.000015f, 0.000000f, 0.000025f, 0.000019f, 0.000049f, 0.000020f, 0.000065f, 0.000007f, 0.000022f, 0.000009f, 0.000042f, 0.000044f, 0.000100f, 0.000055f, 0.000129f, +0.000883f, 0.001769f, 0.000017f, 0.002870f, 0.002141f, 0.006077f, 0.002392f, 0.008022f, 0.000805f, 0.002732f, 0.001188f, 0.005293f, 0.002638f, 0.006474f, 0.003590f, 0.008406f, +0.000702f, 0.001760f, 0.000010f, 0.002771f, 0.000777f, 0.002760f, 0.000636f, 0.003537f, 0.000009f, 0.000038f, 0.000010f, 0.000072f, 0.002110f, 0.006482f, 0.002105f, 0.008171f, +0.001610f, 0.003703f, 0.000023f, 0.005935f, 0.002526f, 0.008233f, 0.002091f, 0.010736f, 0.001609f, 0.006271f, 0.001759f, 0.012004f, 0.004314f, 0.012158f, 0.004350f, 0.015595f, +0.000808f, 0.002046f, 0.000014f, 0.002949f, 0.001745f, 0.006265f, 0.001702f, 0.007348f, 0.000729f, 0.003128f, 0.000938f, 0.005385f, 0.003928f, 0.012188f, 0.004664f, 0.014062f, +0.001987f, 0.005479f, 0.000036f, 0.007889f, 0.004561f, 0.017820f, 0.004825f, 0.020880f, 0.001945f, 0.009089f, 0.002718f, 0.015629f, 0.005422f, 0.018317f, 0.006987f, 0.021110f, +0.000168f, 0.000834f, 0.000004f, 0.001135f, 0.000215f, 0.001516f, 0.000306f, 0.001679f, 0.000003f, 0.000022f, 0.000005f, 0.000035f, 0.000653f, 0.003977f, 0.001131f, 0.004332f, +0.000328f, 0.001494f, 0.000008f, 0.002069f, 0.000596f, 0.003849f, 0.000856f, 0.004338f, 0.000389f, 0.003008f, 0.000739f, 0.004975f, 0.001136f, 0.006346f, 0.001988f, 0.007036f, +0.000151f, 0.000757f, 0.000004f, 0.000943f, 0.000378f, 0.002687f, 0.000639f, 0.002724f, 0.000162f, 0.001376f, 0.000361f, 0.002047f, 0.000949f, 0.005836f, 0.001955f, 0.005820f, +0.000543f, 0.002967f, 0.000017f, 0.003693f, 0.001444f, 0.011187f, 0.002652f, 0.011329f, 0.000632f, 0.005852f, 0.001532f, 0.008698f, 0.001917f, 0.012839f, 0.004288f, 0.012789f, +0.002140f, 0.004828f, 0.000035f, 0.006369f, 0.001950f, 0.006234f, 0.001856f, 0.006693f, 0.000025f, 0.000094f, 0.000031f, 0.000149f, 0.006606f, 0.018258f, 0.007658f, 0.019279f, +0.005017f, 0.010381f, 0.000083f, 0.013937f, 0.006480f, 0.019001f, 0.006233f, 0.020758f, 0.004509f, 0.015811f, 0.005727f, 0.025351f, 0.013799f, 0.034985f, 0.016166f, 0.037592f, +0.002318f, 0.005281f, 0.000045f, 0.006378f, 0.004124f, 0.013316f, 0.004671f, 0.013084f, 0.001881f, 0.007263f, 0.002813f, 0.010475f, 0.011571f, 0.032301f, 0.015962f, 0.031219f, +0.004518f, 0.011204f, 0.000096f, 0.013515f, 0.008537f, 0.030008f, 0.010493f, 0.029453f, 0.003977f, 0.016717f, 0.006455f, 0.024082f, 0.012655f, 0.038456f, 0.018944f, 0.037126f, +0.051204f, 0.124938f, 0.000859f, 0.177101f, 0.062222f, 0.215159f, 0.060612f, 0.248166f, 0.000471f, 0.001948f, 0.000606f, 0.003298f, 0.120455f, 0.360131f, 0.142925f, 0.408566f, +0.064977f, 0.145444f, 0.001101f, 0.209803f, 0.111920f, 0.355038f, 0.110186f, 0.416723f, 0.046539f, 0.176557f, 0.060508f, 0.304147f, 0.136214f, 0.373602f, 0.163346f, 0.431320f, +0.000826f, 0.002036f, 0.000016f, 0.002641f, 0.001960f, 0.006846f, 0.002272f, 0.007227f, 0.000534f, 0.002231f, 0.000818f, 0.003458f, 0.003143f, 0.009491f, 0.004437f, 0.009855f, +0.097248f, 0.260922f, 0.002106f, 0.338160f, 0.245088f, 0.931919f, 0.308324f, 0.982755f, 0.068231f, 0.310267f, 0.113356f, 0.480209f, 0.207619f, 0.682565f, 0.318142f, 0.707995f, +0.123843f, 0.416040f, 0.001966f, 0.523432f, 0.142502f, 0.678440f, 0.131459f, 0.694533f, 0.001224f, 0.006970f, 0.001491f, 0.010472f, 0.266168f, 1.095634f, 0.299083f, 1.103229f, +0.220589f, 0.679821f, 0.003540f, 0.870383f, 0.359788f, 1.571398f, 0.335440f, 1.637032f, 0.169718f, 0.886471f, 0.208965f, 1.355387f, 0.422487f, 1.595411f, 0.479789f, 1.634793f, +0.105928f, 0.359457f, 0.002002f, 0.413942f, 0.237989f, 1.144517f, 0.261266f, 1.072431f, 0.073587f, 0.423221f, 0.106686f, 0.582025f, 0.368181f, 1.530900f, 0.492330f, 1.410954f, +0.288361f, 1.065216f, 0.005913f, 1.225316f, 0.688157f, 3.602606f, 0.819830f, 3.371965f, 0.217329f, 1.360643f, 0.341926f, 1.869123f, 0.562453f, 2.545868f, 0.816190f, 2.343803f, +0.029090f, 0.193726f, 0.000802f, 0.210656f, 0.038800f, 0.366191f, 0.062123f, 0.324003f, 0.000342f, 0.003859f, 0.000723f, 0.005011f, 0.080916f, 0.660285f, 0.157807f, 0.574634f, +0.044089f, 0.269356f, 0.001228f, 0.298059f, 0.083355f, 0.721709f, 0.134884f, 0.649819f, 0.040332f, 0.417618f, 0.086190f, 0.551871f, 0.109287f, 0.818122f, 0.215410f, 0.724548f, +0.019421f, 0.130645f, 0.000637f, 0.130030f, 0.050577f, 0.482183f, 0.096370f, 0.390498f, 0.016041f, 0.182893f, 0.040365f, 0.217385f, 0.087364f, 0.720122f, 0.202761f, 0.573629f, +0.077388f, 0.566718f, 0.002754f, 0.563426f, 0.214078f, 2.221724f, 0.442657f, 1.797280f, 0.069349f, 0.860709f, 0.189371f, 1.021902f, 0.195362f, 1.752986f, 0.492044f, 1.394835f, +0.171461f, 0.518168f, 0.003163f, 0.546113f, 0.162447f, 0.695738f, 0.174095f, 0.596641f, 0.001524f, 0.007807f, 0.002157f, 0.009826f, 0.378295f, 1.400827f, 0.493826f, 1.181600f, +0.312025f, 0.865059f, 0.005817f, 0.927784f, 0.419036f, 1.646399f, 0.453866f, 1.436787f, 0.215918f, 1.014543f, 0.308847f, 1.299435f, 0.613483f, 2.084043f, 0.809371f, 1.788885f, +0.137994f, 0.421254f, 0.003029f, 0.406369f, 0.255274f, 1.104375f, 0.325567f, 0.866861f, 0.086220f, 0.446086f, 0.145219f, 0.513900f, 0.492375f, 1.841731f, 0.764890f, 1.421929f, +0.297591f, 0.988932f, 0.007089f, 0.952935f, 0.584750f, 2.753875f, 0.809309f, 2.159218f, 0.201723f, 1.136130f, 0.368705f, 1.307397f, 0.595873f, 2.426320f, 1.004539f, 1.871195f, +0.047557f, 0.085104f, 0.000517f, 0.121339f, 0.078073f, 0.197998f, 0.049340f, 0.229704f, 0.000441f, 0.001336f, 0.000368f, 0.002275f, 0.126792f, 0.278017f, 0.097602f, 0.317246f, +0.046567f, 0.076447f, 0.000512f, 0.110918f, 0.108363f, 0.252109f, 0.069212f, 0.297636f, 0.033582f, 0.093436f, 0.028326f, 0.161897f, 0.110637f, 0.222552f, 0.086073f, 0.258432f, +0.000479f, 0.000866f, 0.000006f, 0.001130f, 0.001536f, 0.003934f, 0.001155f, 0.004178f, 0.000312f, 0.000956f, 0.000310f, 0.001490f, 0.002066f, 0.004576f, 0.001893f, 0.004779f, +0.078339f, 0.154152f, 0.001100f, 0.200948f, 0.266726f, 0.743814f, 0.217687f, 0.788962f, 0.055340f, 0.184561f, 0.059647f, 0.287315f, 0.189548f, 0.457024f, 0.188432f, 0.476814f, +0.067036f, 0.165163f, 0.000691f, 0.209008f, 0.104209f, 0.363863f, 0.062367f, 0.374666f, 0.000667f, 0.002786f, 0.000527f, 0.004210f, 0.163286f, 0.492947f, 0.119032f, 0.499258f, +0.092136f, 0.208250f, 0.000959f, 0.268179f, 0.203022f, 0.650316f, 0.122798f, 0.681428f, 0.071374f, 0.273414f, 0.057012f, 0.420478f, 0.199994f, 0.553885f, 0.147345f, 0.570865f, +0.035811f, 0.089124f, 0.000439f, 0.103231f, 0.108695f, 0.383369f, 0.077414f, 0.361318f, 0.025048f, 0.105652f, 0.023559f, 0.146143f, 0.141066f, 0.430180f, 0.122377f, 0.398787f, +0.135380f, 0.366775f, 0.001801f, 0.424361f, 0.436472f, 1.675822f, 0.337344f, 1.577679f, 0.102731f, 0.471707f, 0.104857f, 0.651764f, 0.299270f, 0.993471f, 0.281741f, 0.919951f, +0.000415f, 0.002027f, 0.000007f, 0.002217f, 0.000748f, 0.005176f, 0.000777f, 0.004606f, 0.000005f, 0.000041f, 0.000007f, 0.000053f, 0.001308f, 0.007829f, 0.001655f, 0.006853f, +0.000485f, 0.002174f, 0.000009f, 0.002420f, 0.001240f, 0.007871f, 0.001301f, 0.007128f, 0.000447f, 0.003394f, 0.000620f, 0.004512f, 0.001363f, 0.007485f, 0.001743f, 0.006668f, +0.000173f, 0.000854f, 0.000004f, 0.000855f, 0.000609f, 0.004256f, 0.000753f, 0.003467f, 0.000144f, 0.001203f, 0.000235f, 0.001438f, 0.000882f, 0.005333f, 0.001328f, 0.004273f, +0.000957f, 0.005142f, 0.000022f, 0.005142f, 0.003578f, 0.027236f, 0.004800f, 0.022161f, 0.000864f, 0.007864f, 0.001530f, 0.009391f, 0.002739f, 0.018027f, 0.004476f, 0.014428f, +0.168930f, 0.374418f, 0.002022f, 0.396911f, 0.216224f, 0.679172f, 0.150335f, 0.585830f, 0.001512f, 0.005680f, 0.001388f, 0.007191f, 0.422406f, 1.147167f, 0.357730f, 0.973279f, +0.237216f, 0.482329f, 0.002869f, 0.520318f, 0.430383f, 1.240170f, 0.302421f, 1.088586f, 0.165276f, 0.569552f, 0.153371f, 0.733740f, 0.528584f, 1.316924f, 0.452419f, 1.137001f, +0.084913f, 0.190107f, 0.001209f, 0.184459f, 0.212210f, 0.673317f, 0.175583f, 0.531590f, 0.053418f, 0.202693f, 0.058369f, 0.234868f, 0.343371f, 0.941970f, 0.346058f, 0.731498f, +0.254301f, 0.619779f, 0.003930f, 0.600700f, 0.675066f, 2.331647f, 0.606138f, 1.838821f, 0.173560f, 0.716908f, 0.205804f, 0.829789f, 0.577083f, 1.723355f, 0.631149f, 1.336812f, +0.060412f, 0.153524f, 0.000884f, 0.163438f, 0.084583f, 0.304622f, 0.071876f, 0.263872f, 0.000561f, 0.002416f, 0.000630f, 0.003072f, 0.140562f, 0.437691f, 0.145492f, 0.372922f, +0.090059f, 0.209956f, 0.001331f, 0.227455f, 0.178731f, 0.590510f, 0.153498f, 0.520534f, 0.065101f, 0.257227f, 0.073837f, 0.332786f, 0.186732f, 0.533416f, 0.195339f, 0.462495f, +0.000938f, 0.002408f, 0.000016f, 0.002347f, 0.002565f, 0.009331f, 0.002594f, 0.007398f, 0.000612f, 0.002664f, 0.000818f, 0.003100f, 0.003530f, 0.011104f, 0.004349f, 0.008660f, +0.144041f, 0.402512f, 0.002721f, 0.391778f, 0.418260f, 1.656399f, 0.459005f, 1.311843f, 0.101997f, 0.483062f, 0.147821f, 0.561496f, 0.304157f, 1.041446f, 0.406572f, 0.811283f, +0.142685f, 0.499232f, 0.001976f, 0.471713f, 0.189168f, 0.937989f, 0.152229f, 0.721155f, 0.001423f, 0.008441f, 0.001513f, 0.009524f, 0.303310f, 1.300342f, 0.297308f, 0.983348f, +0.298566f, 0.958325f, 0.004180f, 0.921463f, 0.561077f, 2.552250f, 0.456327f, 1.996843f, 0.231837f, 1.261195f, 0.249009f, 1.448206f, 0.565581f, 2.224413f, 0.560295f, 1.711808f, +0.117492f, 0.415250f, 0.001937f, 0.359129f, 0.304142f, 1.523361f, 0.291264f, 1.072012f, 0.082376f, 0.493434f, 0.104182f, 0.509627f, 0.403911f, 1.749175f, 0.471157f, 1.210734f, +0.417088f, 1.604688f, 0.007461f, 1.386280f, 1.146828f, 6.253006f, 1.191843f, 4.395464f, 0.317254f, 2.068696f, 0.435419f, 2.134223f, 0.804642f, 3.793268f, 1.018574f, 2.622698f, +0.031159f, 0.216123f, 0.000749f, 0.176496f, 0.047885f, 0.470696f, 0.066882f, 0.312774f, 0.000370f, 0.004345f, 0.000682f, 0.004237f, 0.085725f, 0.728566f, 0.145844f, 0.476188f, +0.055479f, 0.353013f, 0.001348f, 0.293370f, 0.120852f, 1.089795f, 0.170595f, 0.736928f, 0.051222f, 0.552386f, 0.095487f, 0.548214f, 0.136018f, 1.060489f, 0.233871f, 0.705351f, +0.020027f, 0.140314f, 0.000573f, 0.104882f, 0.060093f, 0.596676f, 0.099883f, 0.362906f, 0.016695f, 0.198245f, 0.036647f, 0.176965f, 0.089105f, 0.764959f, 0.180402f, 0.457628f, +0.104067f, 0.793717f, 0.003231f, 0.592632f, 0.331686f, 3.585154f, 0.598285f, 2.178127f, 0.094119f, 1.216619f, 0.224200f, 1.084818f, 0.259837f, 2.428296f, 0.570887f, 1.451095f, +0.207479f, 0.653042f, 0.003339f, 0.516895f, 0.226485f, 1.010265f, 0.211738f, 0.650657f, 0.001862f, 0.009931f, 0.002298f, 0.009387f, 0.452756f, 1.746143f, 0.515576f, 1.106154f, +0.443557f, 1.280758f, 0.007214f, 1.031616f, 0.686326f, 2.808508f, 0.648472f, 1.840697f, 0.309776f, 1.515972f, 0.386534f, 1.458227f, 0.862556f, 3.051776f, 0.992697f, 1.967334f, +0.160755f, 0.511104f, 0.003078f, 0.370285f, 0.342633f, 1.543835f, 0.381196f, 0.910088f, 0.101371f, 0.546239f, 0.148940f, 0.472599f, 0.567315f, 2.210121f, 0.768797f, 1.281496f, +0.452080f, 1.564671f, 0.009395f, 1.132320f, 1.023492f, 5.020184f, 1.235700f, 2.956115f, 0.309279f, 1.814195f, 0.493126f, 1.567880f, 0.895310f, 3.796899f, 1.316652f, 2.199124f, +0.023864f, 0.043458f, 0.000355f, 0.077115f, 0.037942f, 0.097919f, 0.032822f, 0.141382f, 0.000301f, 0.000929f, 0.000344f, 0.001968f, 0.069898f, 0.155966f, 0.073649f, 0.221500f, +0.032016f, 0.053485f, 0.000482f, 0.096581f, 0.072153f, 0.170824f, 0.063080f, 0.250995f, 0.031425f, 0.088975f, 0.036282f, 0.191872f, 0.083565f, 0.171058f, 0.088988f, 0.247216f, +0.000368f, 0.000678f, 0.000007f, 0.001101f, 0.001143f, 0.002981f, 0.001177f, 0.003940f, 0.000326f, 0.001018f, 0.000444f, 0.001974f, 0.001745f, 0.003933f, 0.002188f, 0.005112f, +0.046480f, 0.093073f, 0.000894f, 0.151000f, 0.153264f, 0.434937f, 0.171217f, 0.574164f, 0.044690f, 0.151669f, 0.065932f, 0.293855f, 0.123551f, 0.303147f, 0.168120f, 0.393624f, +0.050260f, 0.126014f, 0.000709f, 0.198466f, 0.075668f, 0.268863f, 0.061987f, 0.344552f, 0.000681f, 0.002893f, 0.000737f, 0.005441f, 0.134494f, 0.413185f, 0.134203f, 0.520820f, +0.094646f, 0.217692f, 0.001349f, 0.348900f, 0.201977f, 0.658371f, 0.167221f, 0.858588f, 0.099791f, 0.389010f, 0.109109f, 0.744564f, 0.225698f, 0.636089f, 0.227607f, 0.815925f, +0.041133f, 0.104174f, 0.000690f, 0.150173f, 0.120913f, 0.433980f, 0.117875f, 0.509049f, 0.039159f, 0.168084f, 0.050415f, 0.289363f, 0.178007f, 0.552401f, 0.211375f, 0.637328f, +0.120013f, 0.330872f, 0.002185f, 0.476445f, 0.374728f, 1.464117f, 0.396436f, 1.715475f, 0.123953f, 0.579181f, 0.173178f, 0.995979f, 0.291457f, 0.984588f, 0.375578f, 1.134704f, +0.008693f, 0.043205f, 0.000213f, 0.058811f, 0.015170f, 0.106854f, 0.021569f, 0.118351f, 0.000140f, 0.001179f, 0.000263f, 0.001917f, 0.030105f, 0.183347f, 0.052139f, 0.199745f, +0.013929f, 0.063509f, 0.000345f, 0.087974f, 0.034455f, 0.222643f, 0.049511f, 0.250947f, 0.017461f, 0.134939f, 0.033137f, 0.223223f, 0.042988f, 0.240174f, 0.075243f, 0.266267f, +0.005553f, 0.027878f, 0.000162f, 0.034734f, 0.018921f, 0.134624f, 0.032014f, 0.136481f, 0.006285f, 0.053483f, 0.014045f, 0.079578f, 0.031101f, 0.191327f, 0.064098f, 0.190785f, +0.023715f, 0.129614f, 0.000750f, 0.161311f, 0.085835f, 0.664832f, 0.157608f, 0.673256f, 0.029123f, 0.269767f, 0.070622f, 0.400945f, 0.074540f, 0.499183f, 0.166715f, 0.497218f, +0.149244f, 0.336616f, 0.002445f, 0.444108f, 0.185004f, 0.591352f, 0.176067f, 0.634828f, 0.001818f, 0.006950f, 0.002285f, 0.010951f, 0.409977f, 1.133039f, 0.475253f, 1.196392f, +0.287136f, 0.594121f, 0.004754f, 0.797661f, 0.504530f, 1.479453f, 0.485271f, 1.616221f, 0.272292f, 0.954877f, 0.345868f, 1.530997f, 0.702907f, 1.782102f, 0.823501f, 1.914921f, +0.114927f, 0.261840f, 0.002240f, 0.316196f, 0.278166f, 0.898143f, 0.315036f, 0.882513f, 0.098405f, 0.379978f, 0.147182f, 0.547976f, 0.510568f, 1.425329f, 0.704333f, 1.377557f, +0.265639f, 0.658824f, 0.005620f, 0.794710f, 0.682935f, 2.400403f, 0.839353f, 2.356019f, 0.246761f, 1.037240f, 0.400516f, 1.494174f, 0.662252f, 2.012556f, 0.991419f, 1.942950f, +0.095690f, 0.233483f, 0.001604f, 0.330964f, 0.158188f, 0.547003f, 0.154095f, 0.630917f, 0.000929f, 0.003842f, 0.001195f, 0.006504f, 0.200347f, 0.598991f, 0.237722f, 0.679550f, +0.099671f, 0.223105f, 0.001689f, 0.321829f, 0.233557f, 0.740899f, 0.229938f, 0.869623f, 0.075329f, 0.285778f, 0.097940f, 0.492298f, 0.185967f, 0.510061f, 0.223009f, 0.588861f, +0.001098f, 0.002705f, 0.000022f, 0.003510f, 0.003543f, 0.012375f, 0.004107f, 0.013065f, 0.000749f, 0.003129f, 0.001147f, 0.004848f, 0.003717f, 0.011224f, 0.005248f, 0.011655f, +0.153258f, 0.411199f, 0.003319f, 0.532922f, 0.525452f, 1.997976f, 0.661027f, 2.106966f, 0.113463f, 0.515952f, 0.188503f, 0.798553f, 0.291212f, 0.957383f, 0.446234f, 0.993051f, +0.265663f, 0.892469f, 0.004218f, 1.122843f, 0.415864f, 1.979887f, 0.383635f, 2.026851f, 0.002771f, 0.015776f, 0.003376f, 0.023703f, 0.508176f, 2.091818f, 0.571018f, 2.106319f, +0.388414f, 1.197035f, 0.006233f, 1.532577f, 0.861846f, 3.764163f, 0.803522f, 3.921386f, 0.315334f, 1.647056f, 0.388256f, 2.518297f, 0.662103f, 2.500256f, 0.751904f, 2.561973f, +0.161573f, 0.548284f, 0.003053f, 0.631389f, 0.493839f, 2.374929f, 0.542140f, 2.225347f, 0.118439f, 0.681173f, 0.171711f, 0.936767f, 0.499826f, 2.078283f, 0.668366f, 1.915449f, +0.521647f, 1.926983f, 0.010697f, 2.216606f, 1.693552f, 8.865998f, 2.017598f, 8.298391f, 0.414848f, 2.597265f, 0.652685f, 3.567877f, 0.905580f, 4.098983f, 1.314110f, 3.773647f, +0.045137f, 0.300593f, 0.001244f, 0.326862f, 0.081901f, 0.772984f, 0.131135f, 0.683929f, 0.000560f, 0.006318f, 0.001184f, 0.008204f, 0.111744f, 0.911849f, 0.217931f, 0.793565f, +0.056153f, 0.343062f, 0.001564f, 0.379618f, 0.144427f, 1.250482f, 0.233710f, 1.125921f, 0.054204f, 0.561250f, 0.115834f, 0.741676f, 0.123884f, 0.927391f, 0.244180f, 0.821320f, +0.021427f, 0.144140f, 0.000703f, 0.143461f, 0.075913f, 0.723725f, 0.144645f, 0.586111f, 0.018675f, 0.212921f, 0.046993f, 0.253077f, 0.085787f, 0.707126f, 0.199102f, 0.563277f, +0.101263f, 0.741550f, 0.003604f, 0.737243f, 0.381079f, 3.954886f, 0.787972f, 3.199335f, 0.095751f, 1.188397f, 0.261468f, 1.410960f, 0.227516f, 2.041511f, 0.573030f, 1.624412f, +0.358106f, 1.082227f, 0.006606f, 1.140591f, 0.461562f, 1.976805f, 0.494658f, 1.695240f, 0.003359f, 0.017206f, 0.004754f, 0.021656f, 0.703198f, 2.603947f, 0.917955f, 2.196435f, +0.534922f, 1.483019f, 0.009973f, 1.590553f, 0.977289f, 3.839784f, 1.058520f, 3.350919f, 0.390590f, 1.835284f, 0.558697f, 2.350648f, 0.936060f, 3.179858f, 1.234948f, 2.729503f, +0.204931f, 0.625592f, 0.004499f, 0.603488f, 0.515732f, 2.231179f, 0.657746f, 1.751328f, 0.135110f, 0.699033f, 0.227563f, 0.805300f, 0.650793f, 2.434296f, 1.010988f, 1.879426f, +0.524143f, 1.741791f, 0.012486f, 1.678389f, 1.401105f, 6.598486f, 1.939163f, 5.173643f, 0.374902f, 2.111492f, 0.685236f, 2.429791f, 0.934079f, 3.803449f, 1.574694f, 2.933247f, +0.000875f, 0.001566f, 0.000010f, 0.002233f, 0.001468f, 0.003722f, 0.000927f, 0.004318f, 0.000010f, 0.000029f, 0.000008f, 0.000050f, 0.002960f, 0.006490f, 0.002279f, 0.007406f, +0.001133f, 0.001860f, 0.000012f, 0.002699f, 0.002692f, 0.006264f, 0.001720f, 0.007395f, 0.000980f, 0.002725f, 0.000826f, 0.004722f, 0.003414f, 0.006867f, 0.002656f, 0.007974f, +0.000013f, 0.000023f, 0.000000f, 0.000030f, 0.000042f, 0.000108f, 0.000032f, 0.000115f, 0.000010f, 0.000031f, 0.000010f, 0.000048f, 0.000070f, 0.000156f, 0.000065f, 0.000163f, +0.002086f, 0.004105f, 0.000029f, 0.005351f, 0.007254f, 0.020229f, 0.005920f, 0.021457f, 0.001767f, 0.005893f, 0.001904f, 0.009173f, 0.006402f, 0.015436f, 0.006364f, 0.016104f, +0.001527f, 0.003763f, 0.000016f, 0.004762f, 0.002425f, 0.008466f, 0.001451f, 0.008717f, 0.000018f, 0.000076f, 0.000014f, 0.000115f, 0.004718f, 0.014243f, 0.003439f, 0.014426f, +0.002774f, 0.006271f, 0.000029f, 0.008075f, 0.006243f, 0.019999f, 0.003776f, 0.020955f, 0.002577f, 0.009871f, 0.002058f, 0.015180f, 0.007638f, 0.021153f, 0.005627f, 0.021802f, +0.001192f, 0.002966f, 0.000015f, 0.003436f, 0.003694f, 0.013030f, 0.002631f, 0.012280f, 0.000999f, 0.004216f, 0.000940f, 0.005831f, 0.005954f, 0.018158f, 0.005165f, 0.016833f, +0.004462f, 0.012089f, 0.000059f, 0.013987f, 0.014692f, 0.056409f, 0.011355f, 0.053105f, 0.004060f, 0.018640f, 0.004144f, 0.025755f, 0.012510f, 0.041530f, 0.011777f, 0.038456f, +0.000014f, 0.000069f, 0.000000f, 0.000075f, 0.000026f, 0.000179f, 0.000027f, 0.000160f, 0.000000f, 0.000002f, 0.000000f, 0.000002f, 0.000056f, 0.000337f, 0.000071f, 0.000295f, +0.000022f, 0.000097f, 0.000000f, 0.000109f, 0.000057f, 0.000360f, 0.000060f, 0.000326f, 0.000024f, 0.000182f, 0.000033f, 0.000243f, 0.000078f, 0.000426f, 0.000099f, 0.000379f, +0.000009f, 0.000042f, 0.000000f, 0.000042f, 0.000031f, 0.000215f, 0.000038f, 0.000175f, 0.000009f, 0.000071f, 0.000014f, 0.000085f, 0.000055f, 0.000335f, 0.000083f, 0.000269f, +0.000047f, 0.000252f, 0.000001f, 0.000252f, 0.000179f, 0.001365f, 0.000241f, 0.001111f, 0.000051f, 0.000463f, 0.000090f, 0.000553f, 0.000171f, 0.001122f, 0.000279f, 0.000898f, +0.003783f, 0.008386f, 0.000045f, 0.008889f, 0.004946f, 0.015534f, 0.003439f, 0.013399f, 0.000041f, 0.000153f, 0.000037f, 0.000193f, 0.011998f, 0.032585f, 0.010161f, 0.027646f, +0.007022f, 0.014278f, 0.000085f, 0.015403f, 0.013011f, 0.037493f, 0.009143f, 0.032910f, 0.005866f, 0.020214f, 0.005443f, 0.026041f, 0.019845f, 0.049443f, 0.016986f, 0.042688f, +0.002778f, 0.006220f, 0.000040f, 0.006035f, 0.007091f, 0.022497f, 0.005867f, 0.017762f, 0.002095f, 0.007951f, 0.002290f, 0.009213f, 0.014248f, 0.039087f, 0.014360f, 0.030354f, +0.008240f, 0.020082f, 0.000127f, 0.019464f, 0.022338f, 0.077156f, 0.020057f, 0.060848f, 0.006742f, 0.027850f, 0.007995f, 0.032235f, 0.023715f, 0.070821f, 0.025937f, 0.054936f, +0.001094f, 0.002780f, 0.000016f, 0.002959f, 0.001564f, 0.005632f, 0.001329f, 0.004879f, 0.000012f, 0.000052f, 0.000014f, 0.000067f, 0.003228f, 0.010050f, 0.003341f, 0.008563f, +0.002155f, 0.005024f, 0.000032f, 0.005443f, 0.004368f, 0.014432f, 0.003751f, 0.012721f, 0.001868f, 0.007380f, 0.002118f, 0.009548f, 0.005667f, 0.016190f, 0.005929f, 0.014037f, +0.000025f, 0.000064f, 0.000000f, 0.000062f, 0.000069f, 0.000252f, 0.000070f, 0.000200f, 0.000019f, 0.000084f, 0.000026f, 0.000098f, 0.000118f, 0.000372f, 0.000146f, 0.000290f, +0.003773f, 0.010543f, 0.000071f, 0.010262f, 0.011189f, 0.044309f, 0.012278f, 0.035092f, 0.003203f, 0.015170f, 0.004642f, 0.017633f, 0.010104f, 0.034598f, 0.013507f, 0.026952f, +0.003197f, 0.011187f, 0.000044f, 0.010570f, 0.004329f, 0.021466f, 0.003484f, 0.016504f, 0.000038f, 0.000227f, 0.000041f, 0.000256f, 0.008620f, 0.036956f, 0.008450f, 0.027947f, +0.008843f, 0.028384f, 0.000124f, 0.027293f, 0.016972f, 0.077201f, 0.013803f, 0.060401f, 0.008233f, 0.044786f, 0.008842f, 0.051427f, 0.021246f, 0.083560f, 0.021048f, 0.064304f, +0.003846f, 0.013593f, 0.000063f, 0.011756f, 0.010168f, 0.050928f, 0.009737f, 0.035838f, 0.003233f, 0.019366f, 0.004089f, 0.020001f, 0.016769f, 0.072622f, 0.019561f, 0.050267f, +0.013522f, 0.052024f, 0.000242f, 0.044943f, 0.037970f, 0.207029f, 0.039460f, 0.145528f, 0.012331f, 0.080408f, 0.016924f, 0.082955f, 0.033085f, 0.155969f, 0.041881f, 0.107839f, +0.001040f, 0.007211f, 0.000025f, 0.005889f, 0.001632f, 0.016039f, 0.002279f, 0.010658f, 0.000015f, 0.000174f, 0.000027f, 0.000170f, 0.003628f, 0.030831f, 0.006172f, 0.020151f, +0.002447f, 0.015568f, 0.000059f, 0.012938f, 0.005443f, 0.049083f, 0.007683f, 0.033190f, 0.002708f, 0.029207f, 0.005049f, 0.028986f, 0.007608f, 0.059317f, 0.013081f, 0.039453f, +0.000976f, 0.006839f, 0.000028f, 0.005112f, 0.002991f, 0.029701f, 0.004972f, 0.018065f, 0.000976f, 0.011585f, 0.002142f, 0.010341f, 0.005508f, 0.047289f, 0.011152f, 0.028290f, +0.005024f, 0.038314f, 0.000156f, 0.028608f, 0.016351f, 0.176740f, 0.029494f, 0.107377f, 0.005447f, 0.070411f, 0.012975f, 0.062783f, 0.015908f, 0.148667f, 0.034951f, 0.088840f, +0.004571f, 0.014386f, 0.000074f, 0.011387f, 0.005095f, 0.022729f, 0.004764f, 0.014638f, 0.000049f, 0.000262f, 0.000061f, 0.000248f, 0.012650f, 0.048786f, 0.014405f, 0.030905f, +0.012915f, 0.037293f, 0.000210f, 0.030038f, 0.020409f, 0.083515f, 0.019283f, 0.054736f, 0.010814f, 0.052922f, 0.013494f, 0.050906f, 0.031854f, 0.112700f, 0.036660f, 0.072652f, +0.005173f, 0.016448f, 0.000099f, 0.011916f, 0.011261f, 0.050738f, 0.012528f, 0.029910f, 0.003911f, 0.021076f, 0.005747f, 0.018234f, 0.023155f, 0.090206f, 0.031378f, 0.052304f, +0.014408f, 0.049868f, 0.000299f, 0.036088f, 0.033313f, 0.163399f, 0.040220f, 0.096217f, 0.011818f, 0.069322f, 0.018843f, 0.059910f, 0.036190f, 0.153476f, 0.053221f, 0.088892f, +0.000322f, 0.000586f, 0.000005f, 0.001039f, 0.000522f, 0.001347f, 0.000452f, 0.001945f, 0.000005f, 0.000015f, 0.000006f, 0.000032f, 0.001194f, 0.002665f, 0.001259f, 0.003785f, +0.000570f, 0.000953f, 0.000009f, 0.001720f, 0.001312f, 0.003107f, 0.001147f, 0.004565f, 0.000671f, 0.001900f, 0.000775f, 0.004097f, 0.001887f, 0.003864f, 0.002010f, 0.005584f, +0.000007f, 0.000013f, 0.000000f, 0.000022f, 0.000023f, 0.000060f, 0.000024f, 0.000079f, 0.000008f, 0.000024f, 0.000010f, 0.000047f, 0.000044f, 0.000098f, 0.000055f, 0.000128f, +0.000906f, 0.001814f, 0.000017f, 0.002943f, 0.003051f, 0.008658f, 0.003408f, 0.011430f, 0.001044f, 0.003545f, 0.001541f, 0.006868f, 0.003054f, 0.007495f, 0.004156f, 0.009731f, +0.000838f, 0.002101f, 0.000012f, 0.003310f, 0.001289f, 0.004579f, 0.001056f, 0.005868f, 0.000014f, 0.000058f, 0.000015f, 0.000109f, 0.002845f, 0.008739f, 0.002838f, 0.011015f, +0.002086f, 0.004798f, 0.000030f, 0.007690f, 0.004547f, 0.014820f, 0.003764f, 0.019327f, 0.002637f, 0.010280f, 0.002883f, 0.019676f, 0.006310f, 0.017782f, 0.006363f, 0.022810f, +0.001002f, 0.002538f, 0.000017f, 0.003658f, 0.003008f, 0.010797f, 0.002933f, 0.012665f, 0.001144f, 0.004909f, 0.001472f, 0.008452f, 0.005500f, 0.017068f, 0.006531f, 0.019692f, +0.002895f, 0.007983f, 0.000053f, 0.011495f, 0.009233f, 0.036075f, 0.009768f, 0.042268f, 0.003585f, 0.016753f, 0.005009f, 0.028809f, 0.008918f, 0.030128f, 0.011492f, 0.034721f, +0.000216f, 0.001073f, 0.000005f, 0.001460f, 0.000385f, 0.002710f, 0.000547f, 0.003001f, 0.000004f, 0.000035f, 0.000008f, 0.000057f, 0.000948f, 0.005774f, 0.001642f, 0.006290f, +0.000457f, 0.002084f, 0.000011f, 0.002887f, 0.001155f, 0.007462f, 0.001659f, 0.008411f, 0.000687f, 0.005310f, 0.001304f, 0.008784f, 0.001789f, 0.009997f, 0.003132f, 0.011083f, +0.000201f, 0.001011f, 0.000006f, 0.001260f, 0.000701f, 0.004987f, 0.001186f, 0.005056f, 0.000273f, 0.002326f, 0.000611f, 0.003461f, 0.001431f, 0.008802f, 0.002949f, 0.008777f, +0.000852f, 0.004656f, 0.000027f, 0.005795f, 0.003149f, 0.024391f, 0.005782f, 0.024700f, 0.001254f, 0.011619f, 0.003042f, 0.017269f, 0.003396f, 0.022743f, 0.007596f, 0.022654f, +0.002447f, 0.005519f, 0.000040f, 0.007281f, 0.003097f, 0.009901f, 0.002948f, 0.010629f, 0.000036f, 0.000137f, 0.000045f, 0.000215f, 0.008524f, 0.023559f, 0.009882f, 0.024876f, +0.006222f, 0.012874f, 0.000103f, 0.017285f, 0.011165f, 0.032739f, 0.010739f, 0.035766f, 0.007074f, 0.024807f, 0.008985f, 0.039775f, 0.019318f, 0.048976f, 0.022632f, 0.052627f, +0.002752f, 0.006271f, 0.000054f, 0.007573f, 0.006803f, 0.021967f, 0.007705f, 0.021584f, 0.002826f, 0.010910f, 0.004226f, 0.015734f, 0.015508f, 0.043293f, 0.021394f, 0.041842f, +0.006300f, 0.015626f, 0.000133f, 0.018849f, 0.016542f, 0.058143f, 0.020331f, 0.057068f, 0.007017f, 0.029495f, 0.011389f, 0.042489f, 0.019921f, 0.060540f, 0.029823f, 0.058446f, +0.002303f, 0.005620f, 0.000039f, 0.007966f, 0.003888f, 0.013445f, 0.003788f, 0.015508f, 0.000027f, 0.000111f, 0.000034f, 0.000188f, 0.006116f, 0.018284f, 0.007257f, 0.020743f, +0.003171f, 0.007097f, 0.000054f, 0.010238f, 0.007588f, 0.024071f, 0.007470f, 0.028253f, 0.002873f, 0.010900f, 0.003735f, 0.018777f, 0.007503f, 0.020579f, 0.008998f, 0.023759f, +0.000039f, 0.000095f, 0.000001f, 0.000123f, 0.000127f, 0.000444f, 0.000147f, 0.000469f, 0.000032f, 0.000132f, 0.000048f, 0.000204f, 0.000166f, 0.000501f, 0.000234f, 0.000520f, +0.005337f, 0.014318f, 0.000116f, 0.018557f, 0.018685f, 0.071049f, 0.023507f, 0.074925f, 0.004737f, 0.021540f, 0.007869f, 0.033337f, 0.012861f, 0.042280f, 0.019707f, 0.043856f, +0.007914f, 0.026586f, 0.000126f, 0.033449f, 0.012651f, 0.060233f, 0.011671f, 0.061661f, 0.000099f, 0.000563f, 0.000121f, 0.000847f, 0.019199f, 0.079031f, 0.021574f, 0.079579f, +0.015293f, 0.047132f, 0.000245f, 0.060344f, 0.034655f, 0.151360f, 0.032310f, 0.157682f, 0.014886f, 0.077752f, 0.018328f, 0.118880f, 0.033064f, 0.124856f, 0.037548f, 0.127938f, +0.007031f, 0.023860f, 0.000133f, 0.027476f, 0.021947f, 0.105546f, 0.024094f, 0.098898f, 0.006179f, 0.035539f, 0.008959f, 0.048875f, 0.027586f, 0.114704f, 0.036888f, 0.105717f, +0.022482f, 0.083048f, 0.000461f, 0.095530f, 0.074539f, 0.390222f, 0.088801f, 0.365240f, 0.021435f, 0.134202f, 0.033725f, 0.184354f, 0.049499f, 0.224049f, 0.071829f, 0.206267f, +0.002002f, 0.013333f, 0.000055f, 0.014498f, 0.003710f, 0.035014f, 0.005940f, 0.030980f, 0.000030f, 0.000336f, 0.000063f, 0.000436f, 0.006286f, 0.051296f, 0.012260f, 0.044642f, +0.003292f, 0.020113f, 0.000092f, 0.022256f, 0.008647f, 0.074870f, 0.013993f, 0.067412f, 0.003810f, 0.039450f, 0.008142f, 0.052132f, 0.009211f, 0.068956f, 0.018156f, 0.061069f, +0.001388f, 0.009340f, 0.000046f, 0.009296f, 0.005023f, 0.047891f, 0.009572f, 0.038784f, 0.001451f, 0.016541f, 0.003651f, 0.019660f, 0.007050f, 0.058111f, 0.016362f, 0.046290f, +0.006498f, 0.047586f, 0.000231f, 0.047309f, 0.024974f, 0.259181f, 0.051639f, 0.209667f, 0.007367f, 0.091430f, 0.020116f, 0.108553f, 0.018517f, 0.166152f, 0.046637f, 0.132206f, +0.010487f, 0.031693f, 0.000193f, 0.033402f, 0.013804f, 0.059121f, 0.014794f, 0.050700f, 0.000118f, 0.000604f, 0.000167f, 0.000760f, 0.026118f, 0.096715f, 0.034094f, 0.081579f, +0.020706f, 0.057404f, 0.000386f, 0.061567f, 0.038632f, 0.151787f, 0.041844f, 0.132463f, 0.018126f, 0.085171f, 0.025928f, 0.109088f, 0.045953f, 0.156106f, 0.060626f, 0.133997f, +0.008767f, 0.026763f, 0.000192f, 0.025818f, 0.022532f, 0.097479f, 0.028737f, 0.076515f, 0.006930f, 0.035854f, 0.011672f, 0.041304f, 0.035311f, 0.132080f, 0.054854f, 0.101974f, +0.022207f, 0.073796f, 0.000529f, 0.071110f, 0.060624f, 0.285506f, 0.083904f, 0.223855f, 0.019044f, 0.107256f, 0.034807f, 0.123424f, 0.050192f, 0.204377f, 0.084616f, 0.157617f, +0.048474f, 0.086744f, 0.000527f, 0.123678f, 0.065505f, 0.166124f, 0.041397f, 0.192725f, 0.000420f, 0.001274f, 0.000351f, 0.002170f, 0.132829f, 0.291256f, 0.102249f, 0.332353f, +0.071728f, 0.117753f, 0.000789f, 0.170849f, 0.137395f, 0.319653f, 0.087754f, 0.377377f, 0.048394f, 0.134648f, 0.040820f, 0.233304f, 0.175156f, 0.352333f, 0.136268f, 0.409137f, +0.000576f, 0.001042f, 0.000007f, 0.001359f, 0.001520f, 0.003895f, 0.001143f, 0.004136f, 0.000351f, 0.001075f, 0.000349f, 0.001676f, 0.002553f, 0.005656f, 0.002339f, 0.005907f, +0.085202f, 0.167657f, 0.001197f, 0.218553f, 0.238790f, 0.665910f, 0.194887f, 0.706329f, 0.056310f, 0.187795f, 0.060692f, 0.292350f, 0.211886f, 0.510884f, 0.210639f, 0.533007f, +0.061546f, 0.151637f, 0.000634f, 0.191891f, 0.078755f, 0.274984f, 0.047133f, 0.283148f, 0.000573f, 0.002393f, 0.000453f, 0.003616f, 0.154082f, 0.465160f, 0.112323f, 0.471116f, +0.127833f, 0.288932f, 0.001331f, 0.372080f, 0.231863f, 0.742701f, 0.140243f, 0.778232f, 0.092645f, 0.354898f, 0.074003f, 0.545791f, 0.285194f, 0.789844f, 0.210116f, 0.814059f, +0.038789f, 0.096535f, 0.000476f, 0.111816f, 0.096912f, 0.341812f, 0.069022f, 0.322151f, 0.025383f, 0.107064f, 0.023874f, 0.148096f, 0.157045f, 0.478910f, 0.136239f, 0.443960f, +0.132626f, 0.359312f, 0.001764f, 0.415726f, 0.351971f, 1.351382f, 0.272034f, 1.272239f, 0.094156f, 0.432331f, 0.096104f, 0.597358f, 0.301333f, 1.000318f, 0.283682f, 0.926292f, +0.000503f, 0.002459f, 0.000009f, 0.002689f, 0.000747f, 0.005169f, 0.000776f, 0.004600f, 0.000006f, 0.000046f, 0.000008f, 0.000060f, 0.001631f, 0.009762f, 0.002064f, 0.008546f, +0.000890f, 0.003987f, 0.000016f, 0.004437f, 0.001871f, 0.011879f, 0.001964f, 0.010758f, 0.000767f, 0.005822f, 0.001063f, 0.007739f, 0.002569f, 0.014105f, 0.003285f, 0.012565f, +0.000248f, 0.001222f, 0.000005f, 0.001223f, 0.000717f, 0.005015f, 0.000887f, 0.004085f, 0.000193f, 0.001611f, 0.000315f, 0.001926f, 0.001298f, 0.007845f, 0.001954f, 0.006286f, +0.001240f, 0.006657f, 0.000029f, 0.006657f, 0.003813f, 0.029023f, 0.005115f, 0.023615f, 0.001046f, 0.009524f, 0.001854f, 0.011374f, 0.003645f, 0.023987f, 0.005956f, 0.019197f, +0.171470f, 0.380046f, 0.002052f, 0.402877f, 0.180660f, 0.567463f, 0.125608f, 0.489474f, 0.001436f, 0.005394f, 0.001318f, 0.006829f, 0.440678f, 1.196790f, 0.373204f, 1.015380f, +0.363868f, 0.739849f, 0.004401f, 0.798121f, 0.543416f, 1.565882f, 0.381848f, 1.374486f, 0.237181f, 0.817345f, 0.220098f, 1.052965f, 0.833345f, 2.076212f, 0.713265f, 1.792552f, +0.101684f, 0.227656f, 0.001448f, 0.220892f, 0.209183f, 0.663710f, 0.173078f, 0.524006f, 0.059847f, 0.227087f, 0.065393f, 0.263134f, 0.422626f, 1.159389f, 0.425932f, 0.900337f, +0.275428f, 0.671270f, 0.004257f, 0.650606f, 0.601846f, 2.078747f, 0.540394f, 1.639374f, 0.175866f, 0.726435f, 0.208538f, 0.840815f, 0.642407f, 1.918433f, 0.702593f, 1.488134f, +0.092645f, 0.235435f, 0.001355f, 0.250638f, 0.106771f, 0.384532f, 0.090731f, 0.333093f, 0.000805f, 0.003467f, 0.000903f, 0.004408f, 0.221551f, 0.689878f, 0.229321f, 0.587792f, +0.208709f, 0.486566f, 0.003085f, 0.527118f, 0.340950f, 1.126468f, 0.292815f, 0.992980f, 0.141148f, 0.557702f, 0.160087f, 0.721525f, 0.444777f, 1.270548f, 0.465280f, 1.101619f, +0.001697f, 0.004357f, 0.000030f, 0.004246f, 0.003820f, 0.013896f, 0.003863f, 0.011018f, 0.001037f, 0.004510f, 0.001384f, 0.005248f, 0.006565f, 0.020649f, 0.008086f, 0.016103f, +0.235701f, 0.658647f, 0.004452f, 0.641082f, 0.563377f, 2.231093f, 0.618258f, 1.766991f, 0.156147f, 0.739520f, 0.226299f, 0.859595f, 0.511545f, 1.751549f, 0.683790f, 1.364451f, +0.197093f, 0.689597f, 0.002730f, 0.651584f, 0.215089f, 1.066520f, 0.173089f, 0.819974f, 0.001839f, 0.010908f, 0.001955f, 0.012308f, 0.430617f, 1.846127f, 0.422096f, 1.396084f, +0.623236f, 2.000441f, 0.008725f, 1.923494f, 0.964081f, 4.385450f, 0.784092f, 3.431112f, 0.452761f, 2.463017f, 0.486296f, 2.828234f, 1.213441f, 4.772428f, 1.202100f, 3.672645f, +0.191471f, 0.676711f, 0.003156f, 0.585254f, 0.407988f, 2.043502f, 0.390714f, 1.438043f, 0.125594f, 0.752307f, 0.158840f, 0.776996f, 0.676536f, 2.929803f, 0.789171f, 2.027934f, +0.614754f, 2.365181f, 0.010997f, 2.043264f, 1.391394f, 7.586488f, 1.446009f, 5.332817f, 0.437476f, 2.852613f, 0.600418f, 2.942971f, 1.218955f, 5.746435f, 1.543041f, 3.973134f, +0.056877f, 0.394501f, 0.001367f, 0.322168f, 0.071949f, 0.707238f, 0.100493f, 0.469954f, 0.000631f, 0.007420f, 0.001164f, 0.007236f, 0.160830f, 1.366870f, 0.273619f, 0.893381f, +0.153036f, 0.973772f, 0.003718f, 0.809248f, 0.274410f, 2.474513f, 0.387358f, 1.673285f, 0.132188f, 1.425548f, 0.246425f, 1.414781f, 0.385633f, 3.006659f, 0.663063f, 1.999784f, +0.043128f, 0.302168f, 0.001234f, 0.225865f, 0.106524f, 1.057705f, 0.177059f, 0.643310f, 0.033636f, 0.399414f, 0.073834f, 0.356539f, 0.197224f, 1.693156f, 0.399300f, 1.012912f, +0.202694f, 1.545942f, 0.006293f, 1.154285f, 0.531782f, 5.747959f, 0.959210f, 3.492118f, 0.171505f, 2.216943f, 0.408540f, 1.976774f, 0.520164f, 4.861167f, 1.142850f, 2.904923f, +0.316851f, 0.997293f, 0.005099f, 0.789376f, 0.284708f, 1.269974f, 0.266170f, 0.817922f, 0.002660f, 0.014188f, 0.003284f, 0.013411f, 0.710652f, 2.740769f, 0.809255f, 1.736234f, +1.023648f, 2.955754f, 0.016648f, 2.380780f, 1.303797f, 5.335254f, 1.231887f, 3.496727f, 0.668839f, 3.273142f, 0.834567f, 3.148464f, 2.045973f, 7.238776f, 2.354667f, 4.666493f, +0.289632f, 0.920855f, 0.005546f, 0.667142f, 0.508147f, 2.289610f, 0.565339f, 1.349721f, 0.170871f, 0.920742f, 0.251053f, 0.796614f, 1.050552f, 4.092697f, 1.423657f, 2.373073f, +0.736678f, 2.549677f, 0.015309f, 1.845148f, 1.372856f, 6.733798f, 1.657500f, 3.965170f, 0.471504f, 2.765786f, 0.751783f, 2.390273f, 1.499502f, 6.359202f, 2.205183f, 3.683182f, +0.030926f, 0.056317f, 0.000460f, 0.099933f, 0.040474f, 0.104453f, 0.035012f, 0.150815f, 0.000365f, 0.001126f, 0.000417f, 0.002386f, 0.093099f, 0.207737f, 0.098097f, 0.295025f, +0.062699f, 0.104744f, 0.000943f, 0.189141f, 0.116312f, 0.275373f, 0.101686f, 0.404610f, 0.057576f, 0.163018f, 0.066475f, 0.351542f, 0.168202f, 0.344309f, 0.179118f, 0.497601f, +0.000563f, 0.001036f, 0.000010f, 0.001683f, 0.001439f, 0.003752f, 0.001481f, 0.004958f, 0.000467f, 0.001456f, 0.000635f, 0.002824f, 0.002742f, 0.006180f, 0.003438f, 0.008033f, +0.064271f, 0.128699f, 0.001236f, 0.208800f, 0.174450f, 0.495062f, 0.194885f, 0.653536f, 0.057814f, 0.196211f, 0.085295f, 0.380154f, 0.175594f, 0.430843f, 0.238939f, 0.559432f, +0.058668f, 0.147092f, 0.000827f, 0.231664f, 0.072705f, 0.258334f, 0.059559f, 0.331060f, 0.000743f, 0.003159f, 0.000804f, 0.005942f, 0.161357f, 0.495712f, 0.161007f, 0.624845f, +0.166953f, 0.384004f, 0.002379f, 0.615452f, 0.293273f, 0.955965f, 0.242807f, 1.246682f, 0.164687f, 0.641987f, 0.180064f, 1.228760f, 0.409196f, 1.153245f, 0.412658f, 1.479293f, +0.056645f, 0.143461f, 0.000951f, 0.206808f, 0.137065f, 0.491951f, 0.133621f, 0.577048f, 0.050452f, 0.216557f, 0.064954f, 0.372812f, 0.251955f, 0.781880f, 0.299185f, 0.902087f, +0.149479f, 0.412110f, 0.002722f, 0.593426f, 0.384192f, 1.501093f, 0.406448f, 1.758800f, 0.144438f, 0.674902f, 0.201799f, 1.160584f, 0.373112f, 1.260433f, 0.480801f, 1.452605f, +0.013408f, 0.066644f, 0.000328f, 0.090717f, 0.019261f, 0.135674f, 0.027386f, 0.150272f, 0.000202f, 0.001702f, 0.000379f, 0.002767f, 0.047729f, 0.290678f, 0.082661f, 0.316675f, +0.032468f, 0.148042f, 0.000803f, 0.205070f, 0.066111f, 0.427204f, 0.095000f, 0.481513f, 0.038080f, 0.294278f, 0.072265f, 0.486809f, 0.102992f, 0.575418f, 0.180269f, 0.637934f, +0.010105f, 0.050734f, 0.000294f, 0.063210f, 0.028343f, 0.201664f, 0.047957f, 0.204446f, 0.010701f, 0.091058f, 0.023912f, 0.135486f, 0.058171f, 0.357862f, 0.119891f, 0.356848f, +0.039034f, 0.213334f, 0.001234f, 0.265505f, 0.116292f, 0.900737f, 0.213533f, 0.912149f, 0.044846f, 0.415403f, 0.108747f, 0.617398f, 0.126098f, 0.844460f, 0.282030f, 0.841136f, +0.192601f, 0.434406f, 0.003155f, 0.573126f, 0.196527f, 0.628183f, 0.187033f, 0.674366f, 0.002195f, 0.008392f, 0.002759f, 0.013222f, 0.543792f, 1.502858f, 0.630373f, 1.586889f, +0.559976f, 1.158660f, 0.009271f, 1.555608f, 0.809928f, 2.374985f, 0.779011f, 2.594540f, 0.496808f, 1.742214f, 0.631051f, 2.793369f, 1.408934f, 3.572114f, 1.650656f, 3.838342f, +0.174979f, 0.398656f, 0.003411f, 0.481414f, 0.348614f, 1.125606f, 0.394822f, 1.106017f, 0.140170f, 0.541245f, 0.209647f, 0.780542f, 0.798965f, 2.230432f, 1.102179f, 2.155675f, +0.365793f, 0.907219f, 0.007738f, 1.094337f, 0.774106f, 2.720851f, 0.951405f, 2.670542f, 0.317900f, 1.336270f, 0.515983f, 1.924935f, 0.937296f, 2.848405f, 1.403172f, 2.749890f, +0.121444f, 0.296324f, 0.002036f, 0.420043f, 0.165258f, 0.571453f, 0.160983f, 0.659118f, 0.001103f, 0.004562f, 0.001419f, 0.007723f, 0.261340f, 0.781347f, 0.310093f, 0.886432f, +0.191162f, 0.427899f, 0.003239f, 0.617245f, 0.368725f, 1.169686f, 0.363012f, 1.372907f, 0.135166f, 0.512783f, 0.175738f, 0.883350f, 0.366588f, 1.005461f, 0.439607f, 1.160797f, +0.001643f, 0.004051f, 0.000033f, 0.005256f, 0.004367f, 0.015252f, 0.005062f, 0.016102f, 0.001049f, 0.004383f, 0.001606f, 0.006791f, 0.005720f, 0.017273f, 0.008076f, 0.017937f, +0.207547f, 0.556859f, 0.004494f, 0.721700f, 0.585740f, 2.227211f, 0.736869f, 2.348706f, 0.143754f, 0.653694f, 0.238827f, 1.011740f, 0.405334f, 1.332570f, 0.621108f, 1.382216f, +0.303699f, 1.020246f, 0.004822f, 1.283603f, 0.391328f, 1.863073f, 0.361001f, 1.907267f, 0.002963f, 0.016873f, 0.003610f, 0.025351f, 0.597086f, 2.457800f, 0.670923f, 2.474839f, +0.671006f, 2.067940f, 0.010768f, 2.647607f, 1.225572f, 5.352762f, 1.142634f, 5.576338f, 0.509653f, 2.662025f, 0.627512f, 4.070151f, 1.175622f, 4.439428f, 1.335073f, 4.549011f, +0.217911f, 0.739465f, 0.004118f, 0.851549f, 0.548246f, 2.636581f, 0.601869f, 2.470519f, 0.149444f, 0.859492f, 0.216662f, 1.181997f, 0.692855f, 2.880901f, 0.926484f, 2.655182f, +0.636310f, 2.350553f, 0.013048f, 2.703838f, 1.700470f, 8.902214f, 2.025840f, 8.332289f, 0.473427f, 2.964019f, 0.744849f, 4.071689f, 1.135351f, 5.139012f, 1.647537f, 4.731128f, +0.068186f, 0.454093f, 0.001879f, 0.493776f, 0.101844f, 0.961200f, 0.163065f, 0.850462f, 0.000791f, 0.008929f, 0.001673f, 0.011595f, 0.173500f, 1.415792f, 0.338373f, 1.232138f, +0.128191f, 0.783172f, 0.003570f, 0.866627f, 0.271402f, 2.349854f, 0.439177f, 2.115785f, 0.115768f, 1.198710f, 0.247396f, 1.584061f, 0.290677f, 2.176002f, 0.572937f, 1.927119f, +0.038188f, 0.256892f, 0.001252f, 0.255683f, 0.111369f, 1.061740f, 0.212202f, 0.859854f, 0.031139f, 0.355024f, 0.078355f, 0.421980f, 0.157144f, 1.295312f, 0.364715f, 1.031810f, +0.163228f, 1.195326f, 0.005809f, 1.188383f, 0.505638f, 5.247571f, 1.045527f, 4.245062f, 0.144399f, 1.792174f, 0.394310f, 2.127812f, 0.376938f, 3.382276f, 0.949368f, 2.691247f, +0.452597f, 1.367787f, 0.008349f, 1.441551f, 0.480185f, 2.056563f, 0.514616f, 1.763638f, 0.003972f, 0.020345f, 0.005622f, 0.025606f, 0.913459f, 3.382543f, 1.192430f, 2.853182f, +1.021669f, 2.832478f, 0.019047f, 3.037861f, 1.536460f, 6.036773f, 1.664168f, 5.268195f, 0.697933f, 3.279409f, 0.998317f, 4.200296f, 1.837532f, 6.242215f, 2.424263f, 5.358147f, +0.305569f, 0.932807f, 0.006708f, 0.899848f, 0.632999f, 2.738505f, 0.807305f, 2.149545f, 0.188479f, 0.975149f, 0.317450f, 1.123392f, 0.997367f, 3.730659f, 1.549381f, 2.880298f, +0.706856f, 2.348967f, 0.016839f, 2.263463f, 1.555355f, 7.324926f, 2.152650f, 5.743220f, 0.473010f, 2.664052f, 0.864556f, 3.065647f, 1.294719f, 5.271930f, 2.182671f, 4.065750f, +0.060585f, 0.108418f, 0.000659f, 0.154579f, 0.073111f, 0.185414f, 0.046204f, 0.215104f, 0.000532f, 0.001613f, 0.000444f, 0.002747f, 0.181486f, 0.397944f, 0.139704f, 0.454096f, +0.090159f, 0.148010f, 0.000991f, 0.214750f, 0.154220f, 0.358797f, 0.098501f, 0.423590f, 0.061618f, 0.171440f, 0.051974f, 0.297055f, 0.240675f, 0.484129f, 0.187240f, 0.562181f, +0.000728f, 0.001316f, 0.000009f, 0.001717f, 0.001715f, 0.004393f, 0.001290f, 0.004665f, 0.000449f, 0.001376f, 0.000446f, 0.002144f, 0.003526f, 0.007810f, 0.003230f, 0.008157f, +0.104947f, 0.206511f, 0.001474f, 0.269203f, 0.262657f, 0.732468f, 0.214366f, 0.776927f, 0.070259f, 0.234316f, 0.075727f, 0.364771f, 0.285308f, 0.687913f, 0.283628f, 0.717701f, +0.061109f, 0.150560f, 0.000630f, 0.190528f, 0.069828f, 0.243817f, 0.041791f, 0.251055f, 0.000576f, 0.002407f, 0.000456f, 0.003637f, 0.167241f, 0.504889f, 0.121916f, 0.511353f, +0.127646f, 0.288509f, 0.001329f, 0.371535f, 0.206751f, 0.662261f, 0.125054f, 0.693944f, 0.093709f, 0.358974f, 0.074853f, 0.552060f, 0.311310f, 0.862173f, 0.229356f, 0.888605f, +0.038925f, 0.096874f, 0.000477f, 0.112208f, 0.086846f, 0.306308f, 0.061853f, 0.288689f, 0.025802f, 0.108833f, 0.024268f, 0.150542f, 0.172280f, 0.525366f, 0.149455f, 0.487026f, +0.129776f, 0.351593f, 0.001726f, 0.406794f, 0.307557f, 1.180856f, 0.237707f, 1.111700f, 0.093328f, 0.428529f, 0.095259f, 0.592104f, 0.322331f, 1.070026f, 0.303451f, 0.990841f, +0.000608f, 0.002969f, 0.000011f, 0.003247f, 0.000805f, 0.005574f, 0.000836f, 0.004960f, 0.000007f, 0.000056f, 0.000009f, 0.000074f, 0.002153f, 0.012886f, 0.002724f, 0.011280f, +0.001080f, 0.004841f, 0.000020f, 0.005388f, 0.002029f, 0.012882f, 0.002130f, 0.011666f, 0.000943f, 0.007162f, 0.001308f, 0.009520f, 0.003410f, 0.018724f, 0.004361f, 0.016679f, +0.000302f, 0.001491f, 0.000006f, 0.001493f, 0.000782f, 0.005465f, 0.000966f, 0.004452f, 0.000238f, 0.001992f, 0.000389f, 0.002381f, 0.001731f, 0.010466f, 0.002607f, 0.008386f, +0.001475f, 0.007922f, 0.000034f, 0.007922f, 0.004052f, 0.030842f, 0.005436f, 0.025095f, 0.001261f, 0.011481f, 0.002234f, 0.013710f, 0.004742f, 0.031204f, 0.007748f, 0.024973f, +0.146126f, 0.323874f, 0.001749f, 0.343330f, 0.137484f, 0.431845f, 0.095589f, 0.372495f, 0.001240f, 0.004656f, 0.001138f, 0.005895f, 0.410534f, 1.114925f, 0.347675f, 0.945924f, +0.311848f, 0.634076f, 0.003772f, 0.684017f, 0.415894f, 1.198420f, 0.292240f, 1.051938f, 0.205909f, 0.709577f, 0.191078f, 0.914131f, 0.780751f, 1.945176f, 0.668249f, 1.679419f, +0.087581f, 0.196080f, 0.001247f, 0.190254f, 0.160891f, 0.510486f, 0.133121f, 0.403034f, 0.052214f, 0.198126f, 0.057054f, 0.229576f, 0.397923f, 1.091622f, 0.401036f, 0.847712f, +0.231319f, 0.563767f, 0.003575f, 0.546412f, 0.451376f, 1.559032f, 0.405288f, 1.229509f, 0.149617f, 0.618008f, 0.177412f, 0.715317f, 0.589795f, 1.761317f, 0.645052f, 1.366258f, +0.067482f, 0.171491f, 0.000987f, 0.182565f, 0.069451f, 0.250124f, 0.059017f, 0.216664f, 0.000594f, 0.002558f, 0.000667f, 0.003252f, 0.176414f, 0.549328f, 0.182601f, 0.468040f, +0.152887f, 0.356428f, 0.002260f, 0.386134f, 0.223034f, 0.736886f, 0.191547f, 0.649564f, 0.104737f, 0.413836f, 0.118791f, 0.535398f, 0.356173f, 1.017442f, 0.372591f, 0.882166f, +0.001250f, 0.003208f, 0.000022f, 0.003126f, 0.002511f, 0.009135f, 0.002539f, 0.007243f, 0.000773f, 0.003363f, 0.001032f, 0.003913f, 0.005283f, 0.016618f, 0.006508f, 0.012960f, +0.169198f, 0.472810f, 0.003196f, 0.460201f, 0.361147f, 1.430219f, 0.396328f, 1.132712f, 0.113544f, 0.537748f, 0.164555f, 0.625062f, 0.401427f, 1.374500f, 0.536593f, 1.070731f, +0.114048f, 0.399035f, 0.001580f, 0.377039f, 0.111144f, 0.551107f, 0.089441f, 0.423709f, 0.001078f, 0.006394f, 0.001146f, 0.007215f, 0.272393f, 1.167795f, 0.267003f, 0.883113f, +0.362684f, 1.164129f, 0.005077f, 1.119350f, 0.501003f, 2.278981f, 0.407468f, 1.783042f, 0.266894f, 1.451906f, 0.286663f, 1.667195f, 0.771939f, 3.036012f, 0.764724f, 2.336378f, +0.111978f, 0.395762f, 0.001846f, 0.342275f, 0.213074f, 1.067229f, 0.204052f, 0.751025f, 0.074404f, 0.445679f, 0.094099f, 0.460305f, 0.432525f, 1.873088f, 0.504535f, 1.296504f, +0.350574f, 1.348786f, 0.006271f, 1.165208f, 0.708566f, 3.863412f, 0.736379f, 2.715732f, 0.252713f, 1.647849f, 0.346839f, 1.700046f, 0.759898f, 3.582335f, 0.961933f, 2.476857f, +0.040025f, 0.277616f, 0.000962f, 0.226715f, 0.045214f, 0.444440f, 0.063152f, 0.295328f, 0.000450f, 0.005289f, 0.000830f, 0.005158f, 0.123724f, 1.051509f, 0.210490f, 0.687262f, +0.108306f, 0.689150f, 0.002632f, 0.572714f, 0.173423f, 1.563858f, 0.244805f, 1.057493f, 0.094764f, 1.021960f, 0.176659f, 1.014241f, 0.298345f, 2.326104f, 0.512980f, 1.547135f, +0.030674f, 0.214912f, 0.000878f, 0.160643f, 0.067657f, 0.671781f, 0.112456f, 0.408586f, 0.024233f, 0.287760f, 0.053194f, 0.256871f, 0.153342f, 1.316430f, 0.310456f, 0.787540f, +0.140572f, 1.072144f, 0.004364f, 0.800521f, 0.329340f, 3.559793f, 0.594053f, 2.162719f, 0.120485f, 1.557436f, 0.287006f, 1.388714f, 0.394356f, 3.685439f, 0.866439f, 2.202335f, +0.157364f, 0.495306f, 0.002532f, 0.392044f, 0.126270f, 0.563245f, 0.118049f, 0.362756f, 0.001338f, 0.007138f, 0.001652f, 0.006747f, 0.385830f, 1.488031f, 0.439364f, 0.942644f, +0.511282f, 1.476312f, 0.008315f, 1.189129f, 0.581529f, 2.379668f, 0.549455f, 1.559635f, 0.338398f, 1.656039f, 0.422247f, 1.592959f, 1.117117f, 3.952428f, 1.285666f, 2.547941f, +0.145383f, 0.462229f, 0.002784f, 0.334876f, 0.227775f, 1.026310f, 0.253411f, 0.605008f, 0.086882f, 0.468166f, 0.127652f, 0.405051f, 0.576464f, 2.245765f, 0.781196f, 1.302164f, +0.360571f, 1.247954f, 0.007493f, 0.903119f, 0.600053f, 2.943235f, 0.724467f, 1.733113f, 0.233773f, 1.371286f, 0.372736f, 1.185105f, 0.802324f, 3.402554f, 1.179905f, 1.970723f, +0.001129f, 0.002056f, 0.000017f, 0.003648f, 0.001319f, 0.003405f, 0.001141f, 0.004917f, 0.000013f, 0.000042f, 0.000015f, 0.000088f, 0.003715f, 0.008290f, 0.003915f, 0.011774f, +0.002302f, 0.003846f, 0.000035f, 0.006944f, 0.003813f, 0.009028f, 0.003334f, 0.013265f, 0.002141f, 0.006063f, 0.002472f, 0.013074f, 0.006751f, 0.013819f, 0.007189f, 0.019971f, +0.000021f, 0.000038f, 0.000000f, 0.000062f, 0.000047f, 0.000124f, 0.000049f, 0.000163f, 0.000017f, 0.000054f, 0.000024f, 0.000106f, 0.000111f, 0.000249f, 0.000139f, 0.000324f, +0.002312f, 0.004630f, 0.000044f, 0.007512f, 0.005605f, 0.015905f, 0.006261f, 0.020997f, 0.002107f, 0.007151f, 0.003108f, 0.013854f, 0.006906f, 0.016945f, 0.009397f, 0.022002f, +0.001701f, 0.004266f, 0.000024f, 0.006719f, 0.001883f, 0.006690f, 0.001542f, 0.008574f, 0.000022f, 0.000093f, 0.000024f, 0.000175f, 0.005116f, 0.015716f, 0.005104f, 0.019810f, +0.004869f, 0.011200f, 0.000069f, 0.017950f, 0.007638f, 0.024898f, 0.006324f, 0.032470f, 0.004866f, 0.018967f, 0.005320f, 0.036303f, 0.013047f, 0.036769f, 0.013157f, 0.047165f, +0.001660f, 0.004205f, 0.000028f, 0.006062f, 0.003588f, 0.012877f, 0.003497f, 0.015104f, 0.001498f, 0.006430f, 0.001929f, 0.011069f, 0.008073f, 0.025053f, 0.009586f, 0.028905f, +0.004272f, 0.011779f, 0.000078f, 0.016961f, 0.009806f, 0.038312f, 0.010374f, 0.044890f, 0.004182f, 0.019540f, 0.005842f, 0.033601f, 0.011658f, 0.039381f, 0.015022f, 0.045385f, +0.000473f, 0.002350f, 0.000012f, 0.003200f, 0.000607f, 0.004273f, 0.000863f, 0.004733f, 0.000007f, 0.000061f, 0.000014f, 0.000099f, 0.001840f, 0.011207f, 0.003187f, 0.012210f, +0.001152f, 0.005251f, 0.000028f, 0.007274f, 0.002094f, 0.013531f, 0.003009f, 0.015252f, 0.001368f, 0.010573f, 0.002596f, 0.017491f, 0.003993f, 0.022311f, 0.006990f, 0.024735f, +0.000360f, 0.001808f, 0.000010f, 0.002253f, 0.000902f, 0.006419f, 0.001527f, 0.006508f, 0.000386f, 0.003288f, 0.000863f, 0.004892f, 0.002267f, 0.013945f, 0.004672f, 0.013905f, +0.001357f, 0.007415f, 0.000043f, 0.009228f, 0.003610f, 0.027958f, 0.006628f, 0.028312f, 0.001579f, 0.014626f, 0.003829f, 0.021738f, 0.004791f, 0.032087f, 0.010716f, 0.031961f, +0.004794f, 0.010813f, 0.000079f, 0.014266f, 0.004368f, 0.013963f, 0.004157f, 0.014990f, 0.000055f, 0.000212f, 0.000070f, 0.000333f, 0.014797f, 0.040894f, 0.017153f, 0.043180f, +0.014018f, 0.029004f, 0.000232f, 0.038941f, 0.018105f, 0.053091f, 0.017414f, 0.057999f, 0.012598f, 0.044178f, 0.016002f, 0.070833f, 0.038556f, 0.097751f, 0.045170f, 0.105037f, +0.004402f, 0.010029f, 0.000086f, 0.012111f, 0.007832f, 0.025287f, 0.008870f, 0.024847f, 0.003572f, 0.013793f, 0.005343f, 0.019891f, 0.021973f, 0.061340f, 0.030311f, 0.059284f, +0.008973f, 0.022255f, 0.000190f, 0.026845f, 0.016958f, 0.059603f, 0.020841f, 0.058501f, 0.007899f, 0.033205f, 0.012822f, 0.047833f, 0.025135f, 0.076384f, 0.037628f, 0.073742f, +0.136094f, 0.332070f, 0.002282f, 0.470713f, 0.165378f, 0.571866f, 0.161100f, 0.659594f, 0.001252f, 0.005179f, 0.001611f, 0.008767f, 0.320153f, 0.957184f, 0.379877f, 1.085917f, +0.215439f, 0.482239f, 0.003651f, 0.695631f, 0.371087f, 1.177179f, 0.365337f, 1.381702f, 0.154307f, 0.585398f, 0.200624f, 1.008441f, 0.451636f, 1.238728f, 0.541596f, 1.430101f, +0.001861f, 0.004588f, 0.000037f, 0.005952f, 0.004416f, 0.015427f, 0.005120f, 0.016286f, 0.001204f, 0.005029f, 0.001843f, 0.007791f, 0.007082f, 0.021387f, 0.009999f, 0.022208f, +0.229214f, 0.614994f, 0.004963f, 0.797044f, 0.577672f, 2.196536f, 0.726720f, 2.316357f, 0.160820f, 0.731300f, 0.267181f, 1.131854f, 0.489358f, 1.608808f, 0.749863f, 1.668746f, +0.270365f, 0.908265f, 0.004293f, 1.142717f, 0.311100f, 1.481116f, 0.286990f, 1.516250f, 0.002672f, 0.015216f, 0.003256f, 0.022861f, 0.581077f, 2.391901f, 0.652934f, 2.408483f, +0.600750f, 1.851421f, 0.009641f, 2.370395f, 0.979845f, 4.279534f, 0.913536f, 4.458283f, 0.462208f, 2.414210f, 0.569095f, 3.691251f, 1.150598f, 4.344933f, 1.306655f, 4.452183f, +0.196066f, 0.665336f, 0.003705f, 0.766183f, 0.440504f, 2.118437f, 0.483589f, 1.985010f, 0.136206f, 0.783359f, 0.197470f, 1.077296f, 0.681482f, 2.833611f, 0.911275f, 2.611597f, +0.558264f, 2.062248f, 0.011448f, 2.372201f, 1.332266f, 6.974614f, 1.587184f, 6.528095f, 0.420746f, 2.634193f, 0.661965f, 3.618605f, 1.088905f, 4.928778f, 1.580137f, 4.537581f, +0.073821f, 0.491625f, 0.002034f, 0.534587f, 0.098463f, 0.929296f, 0.157653f, 0.822233f, 0.000868f, 0.009793f, 0.001835f, 0.012716f, 0.205342f, 1.675626f, 0.400473f, 1.458267f, +0.139574f, 0.852718f, 0.003888f, 0.943583f, 0.263883f, 2.284759f, 0.427011f, 2.057173f, 0.127682f, 1.322081f, 0.272859f, 1.747092f, 0.345977f, 2.589978f, 0.681936f, 2.293747f, +0.041786f, 0.281096f, 0.001370f, 0.279773f, 0.108822f, 1.037464f, 0.207350f, 0.840194f, 0.034515f, 0.393512f, 0.086850f, 0.467726f, 0.187971f, 1.549413f, 0.436261f, 1.234220f, +0.174159f, 1.275376f, 0.006199f, 1.267968f, 0.481773f, 4.999900f, 0.996181f, 4.044707f, 0.156067f, 1.936991f, 0.426172f, 2.299750f, 0.439653f, 3.945024f, 1.107325f, 3.139021f, +0.345824f, 1.045107f, 0.006379f, 1.101470f, 0.327644f, 1.403253f, 0.351137f, 1.203381f, 0.003074f, 0.015747f, 0.004351f, 0.019819f, 0.762993f, 2.825366f, 0.996011f, 2.383203f, +0.785077f, 2.176549f, 0.014636f, 2.334370f, 1.054325f, 4.142457f, 1.141959f, 3.615057f, 0.543264f, 2.552661f, 0.777080f, 3.269471f, 1.543567f, 5.243599f, 2.036434f, 4.500962f, +0.235976f, 0.720360f, 0.005180f, 0.694907f, 0.436528f, 1.888524f, 0.556733f, 1.482367f, 0.147440f, 0.762824f, 0.248330f, 0.878789f, 0.841979f, 3.149431f, 1.307991f, 2.431554f, +0.532275f, 1.768815f, 0.012680f, 1.704429f, 1.045891f, 4.925611f, 1.447539f, 3.862000f, 0.360804f, 2.032095f, 0.659469f, 2.338425f, 1.065786f, 4.339743f, 1.796729f, 3.346840f, +0.131161f, 0.234713f, 0.001427f, 0.334649f, 0.215324f, 0.546074f, 0.136079f, 0.633517f, 0.001215f, 0.003686f, 0.001014f, 0.006275f, 0.349688f, 0.766762f, 0.269183f, 0.874955f, +0.160214f, 0.263017f, 0.001761f, 0.381614f, 0.372822f, 0.867383f, 0.238123f, 1.024018f, 0.115539f, 0.321467f, 0.097456f, 0.557007f, 0.380648f, 0.765690f, 0.296136f, 0.889135f, +0.001120f, 0.002025f, 0.000015f, 0.002643f, 0.003591f, 0.009200f, 0.002701f, 0.009769f, 0.000730f, 0.002235f, 0.000725f, 0.003483f, 0.004831f, 0.010700f, 0.004425f, 0.011175f, +0.191598f, 0.377019f, 0.002692f, 0.491473f, 0.652349f, 1.819196f, 0.532411f, 1.929617f, 0.135349f, 0.451392f, 0.145882f, 0.702704f, 0.463590f, 1.117773f, 0.460861f, 1.166176f, +0.151859f, 0.374150f, 0.001564f, 0.473474f, 0.236069f, 0.824272f, 0.141282f, 0.848744f, 0.001511f, 0.006311f, 0.001194f, 0.009537f, 0.369897f, 1.116691f, 0.269648f, 1.130987f, +0.260373f, 0.588505f, 0.002711f, 0.757862f, 0.573731f, 1.837764f, 0.347023f, 1.925685f, 0.201700f, 0.772655f, 0.161114f, 1.188251f, 0.565175f, 1.565253f, 0.416391f, 1.613239f, +0.068780f, 0.171176f, 0.000843f, 0.198271f, 0.208765f, 0.736318f, 0.148684f, 0.693964f, 0.048108f, 0.202921f, 0.045249f, 0.280690f, 0.270938f, 0.826225f, 0.235043f, 0.765929f, +0.271966f, 0.736815f, 0.003618f, 0.852498f, 0.876828f, 3.366557f, 0.677691f, 3.169397f, 0.206376f, 0.947612f, 0.210647f, 1.309327f, 0.601203f, 1.995782f, 0.565988f, 1.848088f, +0.001093f, 0.005337f, 0.000020f, 0.005837f, 0.001969f, 0.013629f, 0.002045f, 0.012129f, 0.000013f, 0.000107f, 0.000018f, 0.000140f, 0.003445f, 0.020616f, 0.004358f, 0.018046f, +0.001594f, 0.007143f, 0.000029f, 0.007950f, 0.004072f, 0.025856f, 0.004275f, 0.023417f, 0.001468f, 0.011151f, 0.002036f, 0.014821f, 0.004479f, 0.024589f, 0.005727f, 0.021903f, +0.000386f, 0.001906f, 0.000008f, 0.001908f, 0.001359f, 0.009503f, 0.001680f, 0.007741f, 0.000321f, 0.002686f, 0.000524f, 0.003212f, 0.001969f, 0.011906f, 0.002965f, 0.009539f, +0.002236f, 0.012009f, 0.000052f, 0.012008f, 0.008356f, 0.063601f, 0.011209f, 0.051750f, 0.002017f, 0.018363f, 0.003574f, 0.021929f, 0.006397f, 0.042098f, 0.010453f, 0.033692f, +0.353552f, 0.783613f, 0.004231f, 0.830688f, 0.452531f, 1.421428f, 0.314633f, 1.226074f, 0.003165f, 0.011888f, 0.002906f, 0.015049f, 0.884047f, 2.400888f, 0.748687f, 2.036960f, +0.619330f, 1.259276f, 0.007491f, 1.358460f, 1.123654f, 3.237866f, 0.789569f, 2.842106f, 0.431505f, 1.487000f, 0.400426f, 1.915665f, 1.380041f, 3.438258f, 1.181185f, 2.968511f, +0.150672f, 0.337333f, 0.002146f, 0.327311f, 0.376554f, 1.194759f, 0.311561f, 0.943273f, 0.094787f, 0.359666f, 0.103572f, 0.416758f, 0.609291f, 1.671467f, 0.614058f, 1.297998f, +0.471975f, 1.150290f, 0.007294f, 1.114881f, 1.252902f, 4.327464f, 1.124973f, 3.412793f, 0.322121f, 1.330559f, 0.381965f, 1.540061f, 1.071048f, 3.198493f, 1.171393f, 2.481080f, +0.202670f, 0.515039f, 0.002964f, 0.548298f, 0.283756f, 1.021936f, 0.241128f, 0.885230f, 0.001882f, 0.008107f, 0.002112f, 0.010306f, 0.471554f, 1.468353f, 0.488092f, 1.251069f, +0.376897f, 0.878666f, 0.005571f, 0.951897f, 0.747988f, 2.471284f, 0.642388f, 2.178433f, 0.272449f, 1.076494f, 0.309006f, 1.392710f, 0.781472f, 2.232347f, 0.817494f, 1.935540f, +0.002669f, 0.006850f, 0.000046f, 0.006675f, 0.007295f, 0.026539f, 0.007377f, 0.021042f, 0.001742f, 0.007578f, 0.002326f, 0.008818f, 0.010041f, 0.031584f, 0.012369f, 0.024631f, +0.428525f, 1.197476f, 0.008095f, 1.165542f, 1.244329f, 4.927804f, 1.365544f, 3.902745f, 0.303441f, 1.437114f, 0.439768f, 1.670457f, 0.904871f, 3.098311f, 1.209555f, 2.413574f, +0.393174f, 1.375651f, 0.005446f, 1.299821f, 0.521258f, 2.584662f, 0.419474f, 1.987169f, 0.003922f, 0.023259f, 0.004168f, 0.026245f, 0.835781f, 3.583137f, 0.819244f, 2.709651f, +1.026310f, 3.294211f, 0.014367f, 3.167499f, 1.928685f, 8.773274f, 1.568608f, 6.864082f, 0.796933f, 4.335316f, 0.855961f, 4.978159f, 1.944165f, 7.646346f, 1.925995f, 5.884282f, +0.274493f, 0.970132f, 0.004525f, 0.839019f, 0.710554f, 3.558971f, 0.680470f, 2.504501f, 0.192453f, 1.152790f, 0.243397f, 1.190623f, 0.943642f, 4.086531f, 1.100747f, 2.828592f, +1.019199f, 3.921228f, 0.018232f, 3.387524f, 2.802398f, 15.279900f, 2.912398f, 10.740790f, 0.775245f, 5.055082f, 1.063993f, 5.215204f, 1.966230f, 9.269260f, 2.488994f, 6.408845f, +0.099807f, 0.692269f, 0.002399f, 0.565340f, 0.153382f, 1.507697f, 0.214232f, 1.001855f, 0.001184f, 0.013917f, 0.002184f, 0.013572f, 0.274589f, 2.333689f, 0.467157f, 1.525290f, +0.221684f, 1.410578f, 0.005386f, 1.172254f, 0.482904f, 4.354630f, 0.681669f, 2.944635f, 0.204673f, 2.207238f, 0.381551f, 2.190567f, 0.543503f, 4.237529f, 0.934509f, 2.818459f, +0.054388f, 0.381057f, 0.001556f, 0.284833f, 0.163197f, 1.620421f, 0.271258f, 0.985562f, 0.045340f, 0.538385f, 0.099524f, 0.480591f, 0.241986f, 2.077435f, 0.489926f, 1.242803f, +0.295605f, 2.254577f, 0.009178f, 1.683390f, 0.942165f, 10.183740f, 1.699446f, 6.187035f, 0.267347f, 3.455843f, 0.636846f, 3.081460f, 0.738075f, 6.897650f, 1.621623f, 4.121879f, +0.528192f, 1.662493f, 0.008500f, 1.315895f, 0.576579f, 2.571898f, 0.539036f, 1.656421f, 0.004739f, 0.025281f, 0.005851f, 0.023897f, 1.152611f, 4.445271f, 1.312535f, 2.816009f, +1.408641f, 4.067410f, 0.022909f, 3.276189f, 2.179624f, 8.919215f, 2.059408f, 5.845656f, 0.983781f, 4.814400f, 1.227547f, 4.631013f, 2.739292f, 9.691783f, 3.152593f, 6.247829f, +0.346975f, 1.103171f, 0.006645f, 0.799226f, 0.739543f, 3.332230f, 0.822777f, 1.964344f, 0.218800f, 1.179009f, 0.321473f, 1.020063f, 1.224498f, 4.770348f, 1.659380f, 2.765995f, +1.020609f, 3.532376f, 0.021210f, 2.556307f, 2.310620f, 11.333490f, 2.789697f, 6.673681f, 0.698223f, 4.095698f, 1.113273f, 3.539622f, 2.021239f, 8.571822f, 2.972454f, 4.964708f, +0.092148f, 0.167806f, 0.001372f, 0.297766f, 0.146508f, 0.378101f, 0.126736f, 0.545925f, 0.001162f, 0.003586f, 0.001327f, 0.007600f, 0.269899f, 0.602240f, 0.284386f, 0.855289f, +0.154218f, 0.257635f, 0.002321f, 0.465226f, 0.347556f, 0.822852f, 0.303853f, 1.209028f, 0.151372f, 0.428590f, 0.174769f, 0.924238f, 0.402529f, 0.823978f, 0.428653f, 1.190827f, +0.001206f, 0.002218f, 0.000021f, 0.003603f, 0.003744f, 0.009759f, 0.003854f, 0.012897f, 0.001069f, 0.003332f, 0.001453f, 0.006463f, 0.005712f, 0.012875f, 0.007162f, 0.016736f, +0.159158f, 0.318704f, 0.003060f, 0.517060f, 0.524812f, 1.489332f, 0.586288f, 1.966080f, 0.153029f, 0.519350f, 0.225767f, 1.006230f, 0.423068f, 1.038048f, 0.575686f, 1.347864f, +0.159407f, 0.399669f, 0.002248f, 0.629460f, 0.239990f, 0.852734f, 0.196599f, 1.092792f, 0.002159f, 0.009175f, 0.002336f, 0.017257f, 0.426567f, 1.310471f, 0.425642f, 1.651849f, +0.374469f, 0.861307f, 0.005336f, 1.380435f, 0.799128f, 2.604870f, 0.661616f, 3.397032f, 0.394828f, 1.539132f, 0.431694f, 2.945892f, 0.892982f, 2.516707f, 0.900536f, 3.228235f, +0.110608f, 0.280128f, 0.001856f, 0.403823f, 0.325141f, 1.166992f, 0.316971f, 1.368856f, 0.105300f, 0.451986f, 0.135568f, 0.778111f, 0.478670f, 1.485432f, 0.568398f, 1.713804f, +0.337548f, 0.930610f, 0.006147f, 1.340049f, 1.053959f, 4.117975f, 1.115016f, 4.824947f, 0.348629f, 1.629005f, 0.487080f, 2.801292f, 0.819752f, 2.769254f, 1.056352f, 3.191468f, +0.032048f, 0.159288f, 0.000784f, 0.216826f, 0.055928f, 0.393950f, 0.079520f, 0.436339f, 0.000516f, 0.004348f, 0.000969f, 0.007068f, 0.110993f, 0.675965f, 0.192225f, 0.736421f, +0.064060f, 0.292093f, 0.001584f, 0.404612f, 0.158465f, 1.023983f, 0.227710f, 1.154160f, 0.080309f, 0.620614f, 0.152402f, 1.026649f, 0.197710f, 1.104609f, 0.346056f, 1.224618f, +0.017357f, 0.087143f, 0.000506f, 0.108574f, 0.059143f, 0.420813f, 0.100071f, 0.426617f, 0.019647f, 0.167180f, 0.043902f, 0.248749f, 0.097216f, 0.598057f, 0.200361f, 0.596363f, +0.077536f, 0.423768f, 0.002451f, 0.527400f, 0.280633f, 2.173641f, 0.515294f, 2.201182f, 0.095218f, 0.881994f, 0.230894f, 1.310874f, 0.243706f, 1.632060f, 0.545069f, 1.625635f, +0.437313f, 0.986346f, 0.007164f, 1.301318f, 0.542096f, 1.732771f, 0.515908f, 1.860163f, 0.005328f, 0.020366f, 0.006696f, 0.032088f, 1.201310f, 3.320014f, 1.392579f, 3.505651f, +1.049580f, 2.171712f, 0.017376f, 2.915722f, 1.844227f, 5.407901f, 1.773828f, 5.907834f, 0.995319f, 3.490399f, 1.264266f, 5.596312f, 2.569363f, 6.514186f, 3.010173f, 6.999686f, +0.285518f, 0.650499f, 0.005566f, 0.785536f, 0.691059f, 2.231291f, 0.782656f, 2.192460f, 0.244472f, 0.943994f, 0.365649f, 1.361357f, 1.268424f, 3.540998f, 1.749801f, 3.422316f, +0.690261f, 1.711947f, 0.014602f, 2.065044f, 1.774599f, 6.237416f, 2.181048f, 6.122086f, 0.641205f, 2.695255f, 1.040736f, 3.882592f, 1.720853f, 5.229602f, 2.576189f, 5.048730f, +0.332726f, 0.811852f, 0.005579f, 1.150810f, 0.550041f, 1.902007f, 0.535811f, 2.193787f, 0.003231f, 0.013360f, 0.004156f, 0.022616f, 0.696635f, 2.082776f, 0.826591f, 2.362891f, +0.432339f, 0.967751f, 0.007326f, 1.395982f, 1.013087f, 3.213761f, 0.997390f, 3.772121f, 0.326752f, 1.239606f, 0.424830f, 2.135418f, 0.806658f, 2.212466f, 0.967334f, 2.554274f, +0.003236f, 0.007975f, 0.000065f, 0.010348f, 0.010445f, 0.036483f, 0.012108f, 0.038515f, 0.002208f, 0.009224f, 0.003381f, 0.014292f, 0.010957f, 0.033089f, 0.015471f, 0.034360f, +0.472575f, 1.267943f, 0.010233f, 1.643279f, 1.620246f, 6.160810f, 2.038294f, 6.496883f, 0.349866f, 1.590950f, 0.581254f, 2.462357f, 0.897958f, 2.952115f, 1.375976f, 3.062100f, +0.758747f, 2.548934f, 0.012048f, 3.206892f, 1.187726f, 5.654646f, 1.095679f, 5.788779f, 0.007914f, 0.045058f, 0.009641f, 0.067698f, 1.451374f, 5.974327f, 1.630855f, 6.015744f, +1.383863f, 4.264857f, 0.022208f, 5.460343f, 3.070627f, 13.411150f, 2.862829f, 13.971320f, 1.123489f, 5.868216f, 1.383298f, 8.972316f, 2.358973f, 8.908041f, 2.678922f, 9.127928f, +0.391244f, 1.327658f, 0.007393f, 1.528895f, 1.195819f, 5.750839f, 1.312781f, 5.388630f, 0.286797f, 1.649445f, 0.415795f, 2.268362f, 1.210318f, 5.032519f, 1.618433f, 4.638220f, +1.321195f, 4.880548f, 0.027092f, 5.614088f, 4.289327f, 22.455270f, 5.110052f, 21.017670f, 1.050702f, 6.578199f, 1.653082f, 9.036506f, 2.293599f, 10.381660f, 3.328299f, 9.557668f, +0.149851f, 0.997958f, 0.004130f, 1.085170f, 0.271910f, 2.566275f, 0.435362f, 2.270619f, 0.001858f, 0.020975f, 0.003929f, 0.027238f, 0.370985f, 3.027304f, 0.723523f, 2.634606f, +0.232561f, 1.420815f, 0.006478f, 1.572217f, 0.598156f, 5.178967f, 0.967926f, 4.663089f, 0.224489f, 2.324460f, 0.479735f, 3.071707f, 0.513073f, 3.840859f, 1.011291f, 3.401557f, +0.060312f, 0.405726f, 0.001978f, 0.403817f, 0.213681f, 2.037146f, 0.407149f, 1.649790f, 0.052567f, 0.599332f, 0.132275f, 0.712363f, 0.241474f, 1.990423f, 0.560434f, 1.585517f, +0.298131f, 2.183227f, 0.010611f, 2.170546f, 1.121951f, 11.643740f, 2.319901f, 9.419293f, 0.281905f, 3.498809f, 0.769799f, 4.154064f, 0.669840f, 6.010496f, 1.687080f, 4.782499f, +0.944908f, 2.855591f, 0.017430f, 3.009593f, 1.217889f, 5.216046f, 1.305216f, 4.473102f, 0.008864f, 0.045400f, 0.012545f, 0.057142f, 1.855477f, 6.870838f, 2.422140f, 5.795567f, +1.760763f, 4.881541f, 0.032826f, 5.235502f, 3.216869f, 12.639130f, 3.484251f, 11.029960f, 1.285676f, 6.041065f, 1.839019f, 7.737449f, 3.081158f, 10.466900f, 4.064984f, 8.984497f, +0.458460f, 1.399536f, 0.010064f, 1.350086f, 1.153765f, 4.991460f, 1.471471f, 3.917966f, 0.302261f, 1.563834f, 0.509091f, 1.801569f, 1.455915f, 5.445861f, 2.261722f, 4.204539f, +1.226459f, 4.075673f, 0.029217f, 3.927316f, 3.278489f, 15.440010f, 4.537510f, 12.105970f, 0.877244f, 4.940747f, 1.603405f, 5.685545f, 2.185681f, 8.899812f, 3.684677f, 6.863598f, +0.027976f, 0.050063f, 0.000304f, 0.071378f, 0.046903f, 0.118949f, 0.029641f, 0.137996f, 0.000311f, 0.000942f, 0.000259f, 0.001605f, 0.094596f, 0.207421f, 0.072818f, 0.236689f, +0.045168f, 0.074150f, 0.000497f, 0.107585f, 0.107340f, 0.249730f, 0.068558f, 0.294827f, 0.039052f, 0.108657f, 0.032940f, 0.188269f, 0.136103f, 0.273776f, 0.105885f, 0.317915f, +0.000349f, 0.000631f, 0.000005f, 0.000824f, 0.001143f, 0.002928f, 0.000859f, 0.003109f, 0.000273f, 0.000835f, 0.000271f, 0.001301f, 0.001909f, 0.004228f, 0.001749f, 0.004416f, +0.059124f, 0.116341f, 0.000831f, 0.151659f, 0.205580f, 0.573298f, 0.167783f, 0.608096f, 0.050074f, 0.166999f, 0.053971f, 0.259976f, 0.181434f, 0.437460f, 0.180366f, 0.456403f, +0.040090f, 0.098773f, 0.000413f, 0.124993f, 0.063645f, 0.222225f, 0.038090f, 0.228823f, 0.000478f, 0.001997f, 0.000378f, 0.003019f, 0.123847f, 0.373886f, 0.090283f, 0.378673f, +0.090853f, 0.205349f, 0.000946f, 0.264443f, 0.204448f, 0.654883f, 0.123661f, 0.686214f, 0.084380f, 0.323235f, 0.067401f, 0.497098f, 0.250115f, 0.692695f, 0.184272f, 0.713932f, +0.026525f, 0.066014f, 0.000325f, 0.076463f, 0.082221f, 0.289994f, 0.058558f, 0.273313f, 0.022244f, 0.093823f, 0.020921f, 0.129781f, 0.132519f, 0.404116f, 0.114962f, 0.374624f, +0.103872f, 0.281411f, 0.001382f, 0.325594f, 0.342003f, 1.313112f, 0.264331f, 1.236210f, 0.094501f, 0.433916f, 0.096457f, 0.599547f, 0.291220f, 0.966746f, 0.274162f, 0.895204f, +0.000430f, 0.002098f, 0.000008f, 0.002294f, 0.000790f, 0.005471f, 0.000821f, 0.004869f, 0.000006f, 0.000050f, 0.000008f, 0.000066f, 0.001717f, 0.010278f, 0.002173f, 0.008997f, +0.000828f, 0.003711f, 0.000015f, 0.004131f, 0.002161f, 0.013719f, 0.002268f, 0.012425f, 0.000915f, 0.006946f, 0.001268f, 0.009232f, 0.002951f, 0.016202f, 0.003774f, 0.014433f, +0.000222f, 0.001094f, 0.000005f, 0.001096f, 0.000797f, 0.005573f, 0.000985f, 0.004539f, 0.000221f, 0.001849f, 0.000361f, 0.002211f, 0.001434f, 0.008671f, 0.002160f, 0.006947f, +0.001272f, 0.006829f, 0.000029f, 0.006829f, 0.004853f, 0.036937f, 0.006510f, 0.030055f, 0.001375f, 0.012520f, 0.002437f, 0.014951f, 0.004614f, 0.030363f, 0.007539f, 0.024300f, +0.091755f, 0.203366f, 0.001098f, 0.215583f, 0.119938f, 0.376734f, 0.083390f, 0.324957f, 0.000985f, 0.003699f, 0.000904f, 0.004683f, 0.290984f, 0.790251f, 0.246430f, 0.670465f, +0.212447f, 0.431966f, 0.002570f, 0.465989f, 0.393635f, 1.134279f, 0.276599f, 0.995638f, 0.177463f, 0.611549f, 0.164681f, 0.787844f, 0.600394f, 1.495833f, 0.513881f, 1.291467f, +0.057123f, 0.127890f, 0.000814f, 0.124091f, 0.145793f, 0.462584f, 0.120630f, 0.365214f, 0.043084f, 0.163482f, 0.047077f, 0.189432f, 0.292967f, 0.803696f, 0.295259f, 0.624120f, +0.177210f, 0.431895f, 0.002739f, 0.418599f, 0.480419f, 1.659343f, 0.431365f, 1.308617f, 0.145005f, 0.598958f, 0.171943f, 0.693266f, 0.510029f, 1.523112f, 0.557813f, 1.181482f, +0.042520f, 0.108054f, 0.000622f, 0.115031f, 0.060796f, 0.218955f, 0.051663f, 0.189665f, 0.000473f, 0.002039f, 0.000531f, 0.002592f, 0.125472f, 0.390702f, 0.129873f, 0.332887f, +0.104514f, 0.243655f, 0.001545f, 0.263962f, 0.211825f, 0.699851f, 0.181920f, 0.616918f, 0.090579f, 0.357894f, 0.102733f, 0.463024f, 0.274840f, 0.785107f, 0.287509f, 0.680721f, +0.000818f, 0.002099f, 0.000014f, 0.002046f, 0.002283f, 0.008307f, 0.002309f, 0.006586f, 0.000640f, 0.002784f, 0.000855f, 0.003240f, 0.003903f, 0.012277f, 0.004808f, 0.009574f, +0.130067f, 0.363462f, 0.002457f, 0.353769f, 0.385709f, 1.527490f, 0.423283f, 1.209748f, 0.110423f, 0.522969f, 0.160032f, 0.607882f, 0.348333f, 1.192707f, 0.465623f, 0.929114f, +0.102094f, 0.357209f, 0.001414f, 0.337519f, 0.138229f, 0.685410f, 0.111238f, 0.526965f, 0.001221f, 0.007241f, 0.001298f, 0.008171f, 0.275247f, 1.180032f, 0.269801f, 0.892367f, +0.352244f, 1.130621f, 0.004931f, 1.087131f, 0.676019f, 3.075103f, 0.549809f, 2.405915f, 0.327929f, 1.783932f, 0.352218f, 2.048454f, 0.846282f, 3.328401f, 0.838372f, 2.561387f, +0.104123f, 0.367998f, 0.001716f, 0.318263f, 0.275261f, 1.378706f, 0.263607f, 0.970216f, 0.087525f, 0.524272f, 0.110693f, 0.541478f, 0.453982f, 1.966011f, 0.529564f, 1.360822f, +0.382883f, 1.473090f, 0.006849f, 1.272593f, 1.075151f, 5.862190f, 1.117353f, 4.120745f, 0.349171f, 2.276812f, 0.479223f, 2.348931f, 0.936823f, 4.416399f, 1.185898f, 3.053536f, +0.038589f, 0.267655f, 0.000928f, 0.218580f, 0.060563f, 0.595315f, 0.084590f, 0.395582f, 0.000549f, 0.006451f, 0.001012f, 0.006291f, 0.134648f, 1.144351f, 0.229075f, 0.747943f, +0.113289f, 0.720856f, 0.002753f, 0.599063f, 0.252026f, 2.272663f, 0.355760f, 1.536792f, 0.125402f, 1.352360f, 0.233773f, 1.342146f, 0.352265f, 2.746503f, 0.605691f, 1.826750f, +0.030719f, 0.215224f, 0.000879f, 0.160876f, 0.094134f, 0.934676f, 0.156464f, 0.568483f, 0.030702f, 0.364573f, 0.067394f, 0.325438f, 0.173343f, 1.488142f, 0.350951f, 0.890265f, +0.165350f, 1.261125f, 0.005134f, 0.941624f, 0.538211f, 5.817449f, 0.970807f, 3.534336f, 0.179292f, 2.317601f, 0.427090f, 2.066528f, 0.523612f, 4.893394f, 1.150426f, 2.924181f, +0.134832f, 0.424386f, 0.002170f, 0.335910f, 0.150311f, 0.670482f, 0.140524f, 0.431822f, 0.001450f, 0.007737f, 0.001791f, 0.007314f, 0.373164f, 1.439181f, 0.424941f, 0.911699f, +0.475284f, 1.372367f, 0.007730f, 1.105405f, 0.751046f, 3.073346f, 0.709622f, 2.014272f, 0.397963f, 1.947540f, 0.496572f, 1.873356f, 1.172214f, 4.147365f, 1.349076f, 2.673608f, +0.129390f, 0.411382f, 0.002478f, 0.298038f, 0.281642f, 1.269022f, 0.313341f, 0.748086f, 0.097823f, 0.527122f, 0.143727f, 0.456059f, 0.579130f, 2.256150f, 0.784809f, 1.308186f, +0.376924f, 1.304551f, 0.007833f, 0.944076f, 0.871475f, 4.274547f, 1.052164f, 2.517050f, 0.309158f, 1.813484f, 0.492933f, 1.567266f, 0.946734f, 4.014979f, 1.392276f, 2.325433f, +0.014387f, 0.026199f, 0.000214f, 0.046490f, 0.023360f, 0.060287f, 0.020208f, 0.087046f, 0.000218f, 0.000671f, 0.000248f, 0.001423f, 0.053444f, 0.119253f, 0.056313f, 0.169361f, +0.031825f, 0.053167f, 0.000479f, 0.096006f, 0.073247f, 0.173416f, 0.064037f, 0.254802f, 0.037452f, 0.106040f, 0.043240f, 0.228670f, 0.105353f, 0.215658f, 0.112191f, 0.311673f, +0.000275f, 0.000506f, 0.000005f, 0.000822f, 0.000872f, 0.002273f, 0.000898f, 0.003004f, 0.000292f, 0.000911f, 0.000397f, 0.001767f, 0.001652f, 0.003724f, 0.002072f, 0.004841f, +0.035950f, 0.071989f, 0.000691f, 0.116793f, 0.121063f, 0.343558f, 0.135244f, 0.453534f, 0.041442f, 0.140646f, 0.061140f, 0.272499f, 0.121200f, 0.297379f, 0.164922f, 0.386134f, +0.030804f, 0.077232f, 0.000434f, 0.121637f, 0.047361f, 0.168284f, 0.038798f, 0.215659f, 0.000500f, 0.002126f, 0.000541f, 0.003998f, 0.104544f, 0.321175f, 0.104318f, 0.404841f, +0.095646f, 0.219992f, 0.001363f, 0.352586f, 0.208448f, 0.679466f, 0.172579f, 0.886097f, 0.120906f, 0.471322f, 0.132196f, 0.902107f, 0.289273f, 0.815264f, 0.291720f, 1.045757f, +0.031224f, 0.079078f, 0.000524f, 0.113996f, 0.093735f, 0.336433f, 0.091380f, 0.394629f, 0.035639f, 0.152973f, 0.045882f, 0.263349f, 0.171376f, 0.531824f, 0.203502f, 0.613587f, +0.094368f, 0.260171f, 0.001718f, 0.374638f, 0.300917f, 1.175729f, 0.318350f, 1.377577f, 0.116855f, 0.546016f, 0.163261f, 0.938948f, 0.290663f, 0.981906f, 0.374555f, 1.131612f, +0.009221f, 0.045832f, 0.000226f, 0.062387f, 0.016434f, 0.115760f, 0.023367f, 0.128216f, 0.000178f, 0.001500f, 0.000334f, 0.002438f, 0.040504f, 0.246674f, 0.070147f, 0.268736f, +0.024363f, 0.111085f, 0.000603f, 0.153877f, 0.061546f, 0.397704f, 0.088440f, 0.448263f, 0.036618f, 0.282975f, 0.069489f, 0.468111f, 0.095363f, 0.532795f, 0.166916f, 0.590679f, +0.007296f, 0.036628f, 0.000212f, 0.045636f, 0.025387f, 0.180637f, 0.042956f, 0.183128f, 0.009901f, 0.084248f, 0.022124f, 0.125354f, 0.051825f, 0.318818f, 0.106810f, 0.317915f, +0.032276f, 0.176402f, 0.001020f, 0.219542f, 0.119302f, 0.924053f, 0.219060f, 0.935761f, 0.047521f, 0.440184f, 0.115234f, 0.654229f, 0.128665f, 0.861646f, 0.287770f, 0.858254f, +0.083076f, 0.187376f, 0.001361f, 0.247211f, 0.105170f, 0.336170f, 0.100090f, 0.360884f, 0.001213f, 0.004639f, 0.001525f, 0.007308f, 0.289438f, 0.799910f, 0.335522f, 0.844636f, +0.263543f, 0.545304f, 0.004363f, 0.732120f, 0.472915f, 1.386747f, 0.454863f, 1.514945f, 0.299634f, 1.050759f, 0.380598f, 1.684729f, 0.818235f, 2.074496f, 0.958614f, 2.229107f, +0.079235f, 0.180523f, 0.001545f, 0.217998f, 0.195854f, 0.632374f, 0.221814f, 0.621369f, 0.081341f, 0.314085f, 0.121658f, 0.452949f, 0.446443f, 1.246314f, 0.615872f, 1.204542f, +0.189710f, 0.470509f, 0.004013f, 0.567554f, 0.498093f, 1.750713f, 0.612175f, 1.718342f, 0.211284f, 0.888116f, 0.342934f, 1.279356f, 0.599843f, 1.822899f, 0.897990f, 1.759852f, +0.092796f, 0.226422f, 0.001556f, 0.320956f, 0.156664f, 0.541734f, 0.152611f, 0.624839f, 0.001080f, 0.004467f, 0.001390f, 0.007562f, 0.246413f, 0.736716f, 0.292381f, 0.835798f, +0.159374f, 0.356744f, 0.002701f, 0.514604f, 0.381393f, 1.209870f, 0.375483f, 1.420074f, 0.144412f, 0.547859f, 0.187759f, 0.943774f, 0.377136f, 1.034393f, 0.452257f, 1.194199f, +0.001318f, 0.003249f, 0.000026f, 0.004216f, 0.004346f, 0.015180f, 0.005038f, 0.016025f, 0.001079f, 0.004506f, 0.001651f, 0.006981f, 0.005662f, 0.017098f, 0.007994f, 0.017755f, +0.190680f, 0.511604f, 0.004129f, 0.663049f, 0.667649f, 2.538661f, 0.839912f, 2.677145f, 0.169250f, 0.769632f, 0.281185f, 1.191180f, 0.459523f, 1.510720f, 0.704144f, 1.567004f, +0.261911f, 0.879862f, 0.004159f, 1.106982f, 0.418702f, 1.993398f, 0.386253f, 2.040683f, 0.003275f, 0.018647f, 0.003990f, 0.028017f, 0.635407f, 2.615540f, 0.713983f, 2.633672f, +0.631394f, 1.945862f, 0.010132f, 2.491309f, 1.430761f, 6.248937f, 1.333937f, 6.509945f, 0.614565f, 3.210005f, 0.756685f, 4.907995f, 1.365044f, 5.154731f, 1.550186f, 5.281971f, +0.197290f, 0.669489f, 0.003728f, 0.770965f, 0.615822f, 2.961561f, 0.676054f, 2.775031f, 0.173390f, 0.997210f, 0.251379f, 1.371391f, 0.774056f, 3.218537f, 1.035066f, 2.966364f, +0.659806f, 2.437349f, 0.013530f, 2.803680f, 2.187614f, 11.452490f, 2.606195f, 10.719290f, 0.629101f, 3.938657f, 0.989773f, 5.410553f, 1.452723f, 6.575552f, 2.108083f, 6.053650f, +0.077020f, 0.512926f, 0.002123f, 0.557750f, 0.142725f, 1.347031f, 0.228521f, 1.191842f, 0.001145f, 0.012925f, 0.002421f, 0.016784f, 0.241833f, 1.973396f, 0.471640f, 1.717410f, +0.157990f, 0.965230f, 0.004401f, 1.068085f, 0.414992f, 3.593097f, 0.671534f, 3.235188f, 0.182844f, 1.893247f, 0.390739f, 2.501872f, 0.442068f, 3.309314f, 0.871336f, 2.930808f, +0.045284f, 0.304632f, 0.001485f, 0.303198f, 0.163848f, 1.562058f, 0.312196f, 1.265039f, 0.047320f, 0.539513f, 0.119073f, 0.641263f, 0.229947f, 1.895415f, 0.533683f, 1.509836f, +0.221688f, 1.623431f, 0.007890f, 1.614002f, 0.852003f, 8.842192f, 1.761720f, 7.152958f, 0.251322f, 3.119228f, 0.686285f, 3.703395f, 0.631717f, 5.668412f, 1.591061f, 4.510306f, +0.320651f, 0.969034f, 0.005915f, 1.021294f, 0.422069f, 1.807661f, 0.452333f, 1.550188f, 0.003606f, 0.018471f, 0.005104f, 0.023248f, 0.798574f, 2.957121f, 1.042458f, 2.494338f, +0.789760f, 2.189533f, 0.014724f, 2.348296f, 1.473534f, 5.789538f, 1.596013f, 5.052438f, 0.691382f, 3.248627f, 0.988946f, 4.160871f, 1.752769f, 5.954271f, 2.312435f, 5.110983f, +0.227272f, 0.693790f, 0.004989f, 0.669276f, 0.584109f, 2.526992f, 0.744951f, 1.983522f, 0.179646f, 0.929451f, 0.302574f, 1.070747f, 0.915369f, 3.423944f, 1.421999f, 2.643495f, +0.602129f, 2.000946f, 0.014344f, 1.928111f, 1.643775f, 7.741337f, 2.275025f, 6.069713f, 0.516355f, 2.908176f, 0.943781f, 3.346572f, 1.360940f, 5.541573f, 2.294308f, 4.273701f, +0.125678f, 0.224900f, 0.001367f, 0.320657f, 0.169833f, 0.430707f, 0.107330f, 0.499676f, 0.001089f, 0.003304f, 0.000909f, 0.005625f, 0.344385f, 0.755133f, 0.265101f, 0.861686f, +0.231992f, 0.380851f, 0.002550f, 0.552581f, 0.444377f, 1.033858f, 0.283825f, 1.220555f, 0.156521f, 0.435493f, 0.132023f, 0.754579f, 0.566508f, 1.139556f, 0.440731f, 1.323278f, +0.001267f, 0.002289f, 0.000016f, 0.002988f, 0.003342f, 0.008561f, 0.002513f, 0.009091f, 0.000772f, 0.002364f, 0.000766f, 0.003684f, 0.005613f, 0.012432f, 0.005142f, 0.012985f, +0.195896f, 0.385475f, 0.002752f, 0.502495f, 0.549023f, 1.531054f, 0.448082f, 1.623985f, 0.129468f, 0.431777f, 0.139543f, 0.672168f, 0.487167f, 1.174620f, 0.484299f, 1.225485f, +0.131067f, 0.322922f, 0.001350f, 0.408646f, 0.167714f, 0.585599f, 0.100373f, 0.602984f, 0.001220f, 0.005096f, 0.000965f, 0.007701f, 0.328128f, 0.990593f, 0.239200f, 1.003275f, +0.339600f, 0.767576f, 0.003536f, 0.988464f, 0.615967f, 1.973054f, 0.372569f, 2.067447f, 0.246121f, 0.942820f, 0.196597f, 1.449945f, 0.757643f, 2.098296f, 0.558191f, 2.162624f, +0.070035f, 0.174299f, 0.000859f, 0.201888f, 0.174980f, 0.617157f, 0.124622f, 0.581658f, 0.045830f, 0.193309f, 0.043105f, 0.267394f, 0.283552f, 0.864693f, 0.245986f, 0.801590f, +0.250464f, 0.678563f, 0.003332f, 0.785101f, 0.664698f, 2.552091f, 0.513738f, 2.402630f, 0.177813f, 0.816460f, 0.181493f, 1.128113f, 0.569068f, 1.889106f, 0.535736f, 1.749306f, +0.001246f, 0.006087f, 0.000022f, 0.006658f, 0.001849f, 0.012795f, 0.001920f, 0.011387f, 0.000014f, 0.000114f, 0.000019f, 0.000149f, 0.004038f, 0.024167f, 0.005109f, 0.021154f, +0.002748f, 0.012311f, 0.000050f, 0.013703f, 0.005777f, 0.036684f, 0.006065f, 0.033222f, 0.002368f, 0.017980f, 0.003283f, 0.023899f, 0.007934f, 0.043558f, 0.010145f, 0.038801f, +0.000520f, 0.002564f, 0.000011f, 0.002567f, 0.001505f, 0.010525f, 0.001861f, 0.008574f, 0.000404f, 0.003382f, 0.000660f, 0.004043f, 0.002724f, 0.016466f, 0.004101f, 0.013192f, +0.002721f, 0.014614f, 0.000063f, 0.014614f, 0.008371f, 0.063713f, 0.011229f, 0.051841f, 0.002297f, 0.020908f, 0.004069f, 0.024968f, 0.008002f, 0.052657f, 0.013074f, 0.042143f, +0.337359f, 0.747724f, 0.004037f, 0.792643f, 0.355440f, 1.116459f, 0.247128f, 0.963019f, 0.002825f, 0.010612f, 0.002594f, 0.013435f, 0.867014f, 2.354631f, 0.734262f, 1.997715f, +0.893062f, 1.815852f, 0.010801f, 1.958873f, 1.333738f, 3.843232f, 0.937190f, 3.373479f, 0.582128f, 2.006056f, 0.540200f, 2.584352f, 2.045327f, 5.095763f, 1.750607f, 4.399562f, +0.169619f, 0.379752f, 0.002416f, 0.368469f, 0.348936f, 1.107131f, 0.288710f, 0.874091f, 0.099830f, 0.378802f, 0.109082f, 0.438931f, 0.704980f, 1.933970f, 0.710495f, 1.501848f, +0.480551f, 1.171192f, 0.007427f, 1.135138f, 1.050064f, 3.626871f, 0.942846f, 2.860281f, 0.306840f, 1.267439f, 0.363845f, 1.467003f, 1.120832f, 3.347165f, 1.225842f, 2.596406f, +0.292175f, 0.742495f, 0.004274f, 0.790442f, 0.336727f, 1.212707f, 0.286140f, 1.050480f, 0.002539f, 0.010934f, 0.002849f, 0.013900f, 0.698710f, 2.175682f, 0.723214f, 1.853729f, +0.821101f, 1.914245f, 0.012138f, 2.073783f, 1.341362f, 4.431740f, 1.151990f, 3.906573f, 0.555304f, 2.194106f, 0.629814f, 2.838616f, 1.749839f, 4.998578f, 1.830499f, 4.333980f, +0.004539f, 0.011651f, 0.000079f, 0.011353f, 0.010213f, 0.037156f, 0.010328f, 0.029459f, 0.002772f, 0.012058f, 0.003701f, 0.014031f, 0.017553f, 0.055212f, 0.021622f, 0.043058f, +0.659190f, 1.842049f, 0.012452f, 1.792926f, 1.575607f, 6.239734f, 1.729093f, 4.941774f, 0.436698f, 2.068227f, 0.632894f, 2.404043f, 1.430646f, 4.898586f, 1.912368f, 3.815982f, +0.510550f, 1.786328f, 0.007072f, 1.687861f, 0.557166f, 2.762708f, 0.448369f, 2.124056f, 0.004765f, 0.028256f, 0.005064f, 0.031884f, 1.115467f, 4.782199f, 1.093396f, 3.616409f, +2.013962f, 6.464340f, 0.028193f, 6.215688f, 3.115388f, 14.171400f, 2.533759f, 11.087490f, 1.463076f, 7.959136f, 1.571444f, 9.139321f, 3.921183f, 15.421900f, 3.884535f, 11.868000f, +0.420519f, 1.486226f, 0.006932f, 1.285363f, 0.896044f, 4.488038f, 0.858106f, 3.158299f, 0.275836f, 1.652253f, 0.348852f, 1.706477f, 1.485842f, 6.434575f, 1.733216f, 4.453848f, +1.412189f, 5.433201f, 0.025261f, 4.693707f, 3.196257f, 17.427390f, 3.321717f, 12.250340f, 1.004952f, 6.552912f, 1.379256f, 6.760479f, 2.800136f, 13.200490f, 3.544613f, 9.126930f, +0.171265f, 1.187905f, 0.004117f, 0.970100f, 0.216650f, 2.129606f, 0.302601f, 1.415109f, 0.001901f, 0.022342f, 0.003506f, 0.021789f, 0.484284f, 4.115865f, 0.823912f, 2.690113f, +0.574859f, 3.657832f, 0.013967f, 3.039823f, 1.030780f, 9.295144f, 1.455052f, 6.285448f, 0.496546f, 5.354863f, 0.925659f, 5.314418f, 1.448572f, 11.294070f, 2.490701f, 7.511896f, +0.110105f, 0.771433f, 0.003150f, 0.576632f, 0.271955f, 2.700312f, 0.452031f, 1.642366f, 0.085873f, 1.019701f, 0.188498f, 0.910241f, 0.503512f, 4.322614f, 1.019410f, 2.585957f, +0.541253f, 4.128124f, 0.016804f, 3.082282f, 1.420015f, 15.348750f, 2.561375f, 9.324990f, 0.457968f, 5.919895f, 1.090924f, 5.278573f, 1.388991f, 12.980760f, 3.051748f, 7.757006f, +0.758287f, 2.386719f, 0.012202f, 1.889134f, 0.681362f, 3.039300f, 0.636997f, 1.957449f, 0.006365f, 0.033955f, 0.007859f, 0.032096f, 1.700730f, 6.559202f, 1.936706f, 4.155151f, +3.056059f, 8.824279f, 0.049701f, 7.107718f, 3.892432f, 15.928180f, 3.677747f, 10.439330f, 1.996790f, 9.771830f, 2.491564f, 9.399609f, 6.108166f, 21.611070f, 7.029759f, 13.931620f, +0.587680f, 1.868467f, 0.011254f, 1.353668f, 1.031060f, 4.645747f, 1.147104f, 2.738660f, 0.346706f, 1.868237f, 0.509401f, 1.616374f, 2.131629f, 8.304312f, 2.888681f, 4.815098f, +1.563441f, 5.411145f, 0.032490f, 3.915933f, 2.913593f, 14.291050f, 3.517690f, 8.415227f, 1.000666f, 5.869790f, 1.595499f, 5.072845f, 3.182374f, 13.496050f, 4.680029f, 7.816768f, +0.112259f, 0.204428f, 0.001671f, 0.362752f, 0.146917f, 0.379158f, 0.127090f, 0.547451f, 0.001324f, 0.004087f, 0.001513f, 0.008662f, 0.337945f, 0.754075f, 0.356085f, 1.070923f, +0.283915f, 0.474307f, 0.004272f, 0.856481f, 0.526691f, 1.246963f, 0.460464f, 1.832180f, 0.260719f, 0.738190f, 0.301016f, 1.591878f, 0.761662f, 1.559123f, 0.811092f, 2.253272f, +0.001733f, 0.003188f, 0.000031f, 0.005178f, 0.004429f, 0.011546f, 0.004559f, 0.015259f, 0.001437f, 0.004480f, 0.001954f, 0.008690f, 0.008438f, 0.019019f, 0.010581f, 0.024723f, +0.206891f, 0.414287f, 0.003978f, 0.672134f, 0.561561f, 1.593619f, 0.627341f, 2.103750f, 0.186107f, 0.631608f, 0.274566f, 1.223727f, 0.565244f, 1.386895f, 0.769150f, 1.800827f, +0.174921f, 0.438564f, 0.002466f, 0.690719f, 0.216773f, 0.770238f, 0.177580f, 0.987071f, 0.002217f, 0.009420f, 0.002398f, 0.017717f, 0.481096f, 1.477991f, 0.480052f, 1.863008f, +0.620967f, 1.428272f, 0.008849f, 2.289122f, 1.090806f, 3.555635f, 0.903102f, 4.636932f, 0.612538f, 2.387819f, 0.669733f, 4.570274f, 1.521972f, 4.289403f, 1.534847f, 5.502110f, +0.143193f, 0.362653f, 0.002403f, 0.522787f, 0.346484f, 1.243599f, 0.337778f, 1.458713f, 0.127537f, 0.547433f, 0.164196f, 0.942428f, 0.636915f, 1.976506f, 0.756307f, 2.280376f, +0.395229f, 1.089636f, 0.007197f, 1.569042f, 1.015818f, 3.968952f, 1.074665f, 4.650339f, 0.381901f, 1.784468f, 0.533564f, 3.068632f, 0.986524f, 3.332637f, 1.271259f, 3.840746f, +0.046472f, 0.230978f, 0.001137f, 0.314412f, 0.066757f, 0.470226f, 0.094917f, 0.520822f, 0.000700f, 0.005899f, 0.001315f, 0.009589f, 0.165422f, 1.007448f, 0.286490f, 1.097551f, +0.140377f, 0.640070f, 0.003472f, 0.886636f, 0.285837f, 1.847047f, 0.410740f, 2.081857f, 0.164643f, 1.272333f, 0.312443f, 2.104754f, 0.445294f, 2.487864f, 0.779408f, 2.758155f, +0.029694f, 0.149081f, 0.000865f, 0.185744f, 0.083285f, 0.592591f, 0.140921f, 0.600764f, 0.031446f, 0.267574f, 0.070266f, 0.398126f, 0.170937f, 1.051579f, 0.352299f, 1.048600f, +0.119970f, 0.655686f, 0.003792f, 0.816034f, 0.357424f, 2.768432f, 0.656298f, 2.803509f, 0.137834f, 1.276749f, 0.334236f, 1.897584f, 0.387566f, 2.595465f, 0.866824f, 2.585248f, +0.530535f, 1.196606f, 0.008691f, 1.578720f, 0.541348f, 1.730378f, 0.515196f, 1.857594f, 0.006047f, 0.023116f, 0.007600f, 0.036420f, 1.497918f, 4.139738f, 1.736412f, 4.371209f, +1.924229f, 3.981473f, 0.031857f, 5.345491f, 2.783133f, 8.161094f, 2.676894f, 8.915545f, 1.707168f, 5.986721f, 2.168464f, 9.598775f, 4.841480f, 12.274760f, 5.672104f, 13.189590f, +0.408654f, 0.931041f, 0.007966f, 1.124317f, 0.814172f, 2.628797f, 0.922086f, 2.583048f, 0.327359f, 1.264050f, 0.489620f, 1.822918f, 1.865942f, 5.209062f, 2.574083f, 5.034472f, +0.893544f, 2.216117f, 0.018903f, 2.673201f, 1.890953f, 6.646383f, 2.324052f, 6.523490f, 0.776554f, 3.264185f, 1.260421f, 4.702152f, 2.289589f, 6.957966f, 3.427609f, 6.717317f, +0.396972f, 0.968610f, 0.006656f, 1.373016f, 0.540189f, 1.867938f, 0.526214f, 2.154492f, 0.003606f, 0.014912f, 0.004639f, 0.025244f, 0.854257f, 2.554030f, 1.013618f, 2.897525f, +0.779500f, 1.744840f, 0.013209f, 2.516934f, 1.503547f, 4.769620f, 1.480250f, 5.598295f, 0.551167f, 2.090971f, 0.716605f, 3.602031f, 1.494833f, 4.099962f, 1.792584f, 4.733373f, +0.004555f, 0.011226f, 0.000091f, 0.014565f, 0.012102f, 0.042270f, 0.014029f, 0.044626f, 0.002908f, 0.012147f, 0.004452f, 0.018821f, 0.015851f, 0.047871f, 0.022382f, 0.049709f, +0.601622f, 1.614183f, 0.013027f, 2.092012f, 1.697900f, 6.456081f, 2.135984f, 6.808261f, 0.416703f, 1.894882f, 0.692295f, 2.932760f, 1.174953f, 3.862758f, 1.800425f, 4.006670f, +0.815395f, 2.739239f, 0.012947f, 3.446321f, 1.050669f, 5.002131f, 0.969244f, 5.120786f, 0.007957f, 0.045301f, 0.009693f, 0.068064f, 1.603106f, 6.598902f, 1.801350f, 6.644649f, +2.247420f, 6.926210f, 0.036066f, 8.867703f, 4.104843f, 17.928150f, 3.827057f, 18.676980f, 1.706995f, 8.915995f, 2.101742f, 13.632270f, 3.937544f, 14.869100f, 4.471596f, 15.236130f, +0.496044f, 1.683289f, 0.009373f, 1.938430f, 1.248004f, 6.001804f, 1.370070f, 5.623788f, 0.340188f, 1.956513f, 0.493201f, 2.690649f, 1.577187f, 6.557963f, 2.109009f, 6.044146f, +1.515023f, 5.596554f, 0.031067f, 6.437709f, 4.048737f, 21.195740f, 4.823427f, 19.838780f, 1.127208f, 7.057187f, 1.773450f, 9.694495f, 2.703217f, 12.235740f, 3.922706f, 11.264590f, +0.212807f, 1.417222f, 0.005865f, 1.541072f, 0.317854f, 2.999900f, 0.508926f, 2.654286f, 0.002469f, 0.027868f, 0.005221f, 0.036188f, 0.541494f, 4.418680f, 1.056060f, 3.845496f, +0.499093f, 3.049177f, 0.013901f, 3.374097f, 1.056666f, 9.148849f, 1.709880f, 8.237530f, 0.450726f, 4.667019f, 0.963206f, 6.167334f, 1.131712f, 8.471977f, 2.230655f, 7.502987f, +0.101049f, 0.679766f, 0.003314f, 0.676566f, 0.294694f, 2.809484f, 0.561510f, 2.275271f, 0.082397f, 0.939434f, 0.207337f, 1.116607f, 0.415822f, 3.427543f, 0.965078f, 2.730287f, +0.451766f, 3.308301f, 0.016079f, 3.289085f, 1.399452f, 14.523690f, 2.893701f, 11.749050f, 0.399652f, 4.960195f, 1.091330f, 5.889138f, 1.043250f, 9.361116f, 2.627562f, 7.448558f, +1.122664f, 3.392782f, 0.020709f, 3.575755f, 1.191093f, 5.101285f, 1.276499f, 4.374687f, 0.009853f, 0.050465f, 0.013945f, 0.063517f, 2.265827f, 8.390367f, 2.957811f, 7.077293f, +3.161408f, 8.764692f, 0.058939f, 9.400221f, 4.754352f, 18.679920f, 5.149528f, 16.301670f, 2.159651f, 10.147660f, 3.089147f, 12.997210f, 5.685976f, 19.315630f, 7.501530f, 16.580010f, +0.642632f, 1.961756f, 0.014107f, 1.892441f, 1.331240f, 5.759260f, 1.697817f, 4.520638f, 0.396383f, 2.050804f, 0.667619f, 2.362568f, 2.097530f, 7.845826f, 3.258452f, 6.057460f, +1.554869f, 5.167019f, 0.037041f, 4.978936f, 3.421312f, 16.112630f, 4.735180f, 12.633350f, 1.040480f, 5.860111f, 1.901763f, 6.743499f, 2.847992f, 11.596660f, 4.801218f, 8.943424f, +0.015396f, 0.027551f, 0.000167f, 0.039281f, 0.018579f, 0.047117f, 0.011741f, 0.054662f, 0.000135f, 0.000410f, 0.000113f, 0.000698f, 0.046119f, 0.101125f, 0.035501f, 0.115394f, +0.029089f, 0.047754f, 0.000320f, 0.069287f, 0.049757f, 0.115762f, 0.031780f, 0.136666f, 0.019880f, 0.055313f, 0.016769f, 0.095842f, 0.077651f, 0.156199f, 0.060411f, 0.181382f, +0.000342f, 0.000618f, 0.000004f, 0.000806f, 0.000805f, 0.002063f, 0.000606f, 0.002190f, 0.000211f, 0.000646f, 0.000209f, 0.001007f, 0.001656f, 0.003667f, 0.001517f, 0.003830f, +0.045868f, 0.090257f, 0.000644f, 0.117656f, 0.114796f, 0.320129f, 0.093690f, 0.339560f, 0.030707f, 0.102409f, 0.033097f, 0.159425f, 0.124695f, 0.300656f, 0.123961f, 0.313675f, +0.015907f, 0.039192f, 0.000164f, 0.049596f, 0.018177f, 0.063467f, 0.010878f, 0.065352f, 0.000150f, 0.000626f, 0.000119f, 0.000947f, 0.043534f, 0.131426f, 0.031736f, 0.133109f, +0.042187f, 0.095352f, 0.000439f, 0.122791f, 0.068331f, 0.218875f, 0.041330f, 0.229347f, 0.030971f, 0.118640f, 0.024739f, 0.182454f, 0.102887f, 0.284946f, 0.075802f, 0.293681f, +0.018721f, 0.046592f, 0.000229f, 0.053967f, 0.041769f, 0.147320f, 0.029748f, 0.138846f, 0.012410f, 0.052344f, 0.011672f, 0.072404f, 0.082858f, 0.252677f, 0.071881f, 0.234237f, +0.058101f, 0.157408f, 0.000773f, 0.182122f, 0.137693f, 0.528669f, 0.106422f, 0.497708f, 0.041783f, 0.191852f, 0.042647f, 0.265085f, 0.144308f, 0.479051f, 0.135855f, 0.443599f, +0.000123f, 0.000603f, 0.000002f, 0.000659f, 0.000163f, 0.001131f, 0.000170f, 0.001007f, 0.000001f, 0.000011f, 0.000002f, 0.000015f, 0.000437f, 0.002615f, 0.000553f, 0.002289f, +0.000278f, 0.001247f, 0.000005f, 0.001388f, 0.000523f, 0.003319f, 0.000549f, 0.003006f, 0.000243f, 0.001846f, 0.000337f, 0.002453f, 0.000879f, 0.004825f, 0.001124f, 0.004298f, +0.000113f, 0.000559f, 0.000002f, 0.000560f, 0.000293f, 0.002049f, 0.000362f, 0.001669f, 0.000089f, 0.000747f, 0.000146f, 0.000893f, 0.000649f, 0.003925f, 0.000977f, 0.003144f, +0.000515f, 0.002765f, 0.000012f, 0.002765f, 0.001414f, 0.010765f, 0.001897f, 0.008759f, 0.000440f, 0.004007f, 0.000780f, 0.004785f, 0.001655f, 0.010892f, 0.002704f, 0.008717f, +0.044706f, 0.099087f, 0.000535f, 0.105040f, 0.042063f, 0.132121f, 0.029245f, 0.113963f, 0.000379f, 0.001425f, 0.000348f, 0.001803f, 0.125601f, 0.341106f, 0.106370f, 0.289401f, +0.121134f, 0.246301f, 0.001465f, 0.265700f, 0.161550f, 0.465515f, 0.113518f, 0.408616f, 0.079983f, 0.275629f, 0.074223f, 0.355085f, 0.303275f, 0.755585f, 0.259575f, 0.652355f, +0.049507f, 0.110839f, 0.000705f, 0.107546f, 0.090948f, 0.288565f, 0.075250f, 0.227825f, 0.029516f, 0.111996f, 0.032251f, 0.129774f, 0.224936f, 0.617067f, 0.226696f, 0.479191f, +0.121718f, 0.296649f, 0.001881f, 0.287517f, 0.237510f, 0.820349f, 0.213259f, 0.646957f, 0.078727f, 0.325191f, 0.093353f, 0.376393f, 0.310345f, 0.926790f, 0.339421f, 0.718913f, +0.012459f, 0.031661f, 0.000182f, 0.033706f, 0.012822f, 0.046179f, 0.010896f, 0.040001f, 0.000110f, 0.000472f, 0.000123f, 0.000600f, 0.032570f, 0.101419f, 0.033712f, 0.086411f, +0.035838f, 0.083549f, 0.000530f, 0.090512f, 0.052280f, 0.172730f, 0.044900f, 0.152261f, 0.024551f, 0.097005f, 0.027845f, 0.125500f, 0.083489f, 0.238494f, 0.087337f, 0.206784f, +0.000426f, 0.001094f, 0.000007f, 0.001066f, 0.000857f, 0.003116f, 0.000866f, 0.002471f, 0.000264f, 0.001147f, 0.000352f, 0.001335f, 0.001802f, 0.005669f, 0.002220f, 0.004421f, +0.053726f, 0.150132f, 0.001015f, 0.146128f, 0.114675f, 0.454139f, 0.125846f, 0.359671f, 0.036054f, 0.170752f, 0.052251f, 0.198477f, 0.127465f, 0.436446f, 0.170385f, 0.339990f, +0.021569f, 0.075465f, 0.000299f, 0.071306f, 0.021019f, 0.104225f, 0.016915f, 0.080132f, 0.000204f, 0.001209f, 0.000217f, 0.001364f, 0.051515f, 0.220853f, 0.050495f, 0.167014f, +0.087086f, 0.279524f, 0.001219f, 0.268772f, 0.120298f, 0.547216f, 0.097839f, 0.428134f, 0.064085f, 0.348623f, 0.068832f, 0.400317f, 0.185353f, 0.728990f, 0.183621f, 0.560998f, +0.039128f, 0.138289f, 0.000645f, 0.119599f, 0.074453f, 0.372916f, 0.071301f, 0.262426f, 0.025999f, 0.155731f, 0.032881f, 0.160842f, 0.151135f, 0.654503f, 0.176297f, 0.453030f, +0.114030f, 0.438713f, 0.002040f, 0.379001f, 0.230472f, 1.256632f, 0.239518f, 0.883332f, 0.082199f, 0.535987f, 0.112815f, 0.552965f, 0.247168f, 1.165208f, 0.312883f, 0.805634f, +0.005902f, 0.040934f, 0.000142f, 0.033428f, 0.006667f, 0.065532f, 0.009312f, 0.043545f, 0.000066f, 0.000780f, 0.000122f, 0.000761f, 0.018243f, 0.155042f, 0.031036f, 0.101335f, +0.020275f, 0.129012f, 0.000493f, 0.107215f, 0.032466f, 0.292762f, 0.045829f, 0.197968f, 0.017740f, 0.191316f, 0.033072f, 0.189871f, 0.055852f, 0.435459f, 0.096032f, 0.289632f, +0.008357f, 0.058548f, 0.000239f, 0.043764f, 0.018432f, 0.183013f, 0.030636f, 0.111311f, 0.006602f, 0.078394f, 0.014492f, 0.069979f, 0.041775f, 0.358634f, 0.084577f, 0.214549f, +0.035648f, 0.271888f, 0.001107f, 0.203007f, 0.083518f, 0.902739f, 0.150648f, 0.548450f, 0.030554f, 0.394955f, 0.072783f, 0.352168f, 0.100006f, 0.934601f, 0.219723f, 0.558497f, +0.034978f, 0.110095f, 0.000563f, 0.087142f, 0.028067f, 0.125196f, 0.026239f, 0.080632f, 0.000297f, 0.001587f, 0.000367f, 0.001500f, 0.085761f, 0.330754f, 0.097660f, 0.209528f, +0.144290f, 0.416632f, 0.002347f, 0.335586f, 0.164114f, 0.671570f, 0.155062f, 0.440147f, 0.095500f, 0.467353f, 0.119163f, 0.449551f, 0.315263f, 1.115420f, 0.362830f, 0.719058f, +0.059707f, 0.189831f, 0.001143f, 0.137529f, 0.093544f, 0.421491f, 0.104072f, 0.248468f, 0.035681f, 0.192269f, 0.052425f, 0.166349f, 0.236746f, 0.922304f, 0.320826f, 0.534781f, +0.137843f, 0.477081f, 0.002865f, 0.345254f, 0.229395f, 1.125172f, 0.276957f, 0.662553f, 0.089369f, 0.524230f, 0.142494f, 0.453055f, 0.306721f, 1.300765f, 0.451067f, 0.753389f, +0.000319f, 0.000582f, 0.000005f, 0.001032f, 0.000373f, 0.000963f, 0.000323f, 0.001391f, 0.000004f, 0.000012f, 0.000004f, 0.000025f, 0.001051f, 0.002345f, 0.001107f, 0.003331f, +0.000827f, 0.001381f, 0.000012f, 0.002494f, 0.001370f, 0.003243f, 0.001197f, 0.004764f, 0.000769f, 0.002177f, 0.000888f, 0.004696f, 0.002425f, 0.004963f, 0.002582f, 0.007173f, +0.000011f, 0.000020f, 0.000000f, 0.000032f, 0.000025f, 0.000065f, 0.000026f, 0.000085f, 0.000009f, 0.000028f, 0.000012f, 0.000055f, 0.000058f, 0.000130f, 0.000072f, 0.000169f, +0.001125f, 0.002253f, 0.000022f, 0.003655f, 0.002727f, 0.007738f, 0.003046f, 0.010216f, 0.001025f, 0.003479f, 0.001512f, 0.006741f, 0.003360f, 0.008244f, 0.004572f, 0.010705f, +0.000493f, 0.001236f, 0.000007f, 0.001947f, 0.000546f, 0.001939f, 0.000447f, 0.002484f, 0.000006f, 0.000027f, 0.000007f, 0.000051f, 0.001482f, 0.004554f, 0.001479f, 0.005740f, +0.001791f, 0.004121f, 0.000026f, 0.006604f, 0.002810f, 0.009160f, 0.002327f, 0.011946f, 0.001790f, 0.006978f, 0.001957f, 0.013356f, 0.004800f, 0.013528f, 0.004841f, 0.017352f, +0.000889f, 0.002251f, 0.000015f, 0.003245f, 0.001921f, 0.006894f, 0.001873f, 0.008087f, 0.000802f, 0.003443f, 0.001033f, 0.005926f, 0.004322f, 0.013413f, 0.005133f, 0.015476f, +0.002129f, 0.005870f, 0.000039f, 0.008453f, 0.004887f, 0.019094f, 0.005170f, 0.022372f, 0.002084f, 0.009738f, 0.002912f, 0.016746f, 0.005810f, 0.019627f, 0.007487f, 0.022619f, +0.000107f, 0.000531f, 0.000003f, 0.000723f, 0.000137f, 0.000965f, 0.000195f, 0.001069f, 0.000002f, 0.000014f, 0.000003f, 0.000022f, 0.000416f, 0.002532f, 0.000720f, 0.002758f, +0.000330f, 0.001506f, 0.000008f, 0.002086f, 0.000601f, 0.003881f, 0.000863f, 0.004375f, 0.000392f, 0.003033f, 0.000745f, 0.005017f, 0.001145f, 0.006400f, 0.002005f, 0.007095f, +0.000150f, 0.000755f, 0.000004f, 0.000941f, 0.000377f, 0.002680f, 0.000637f, 0.002717f, 0.000161f, 0.001372f, 0.000360f, 0.002042f, 0.000946f, 0.005821f, 0.001950f, 0.005804f, +0.000527f, 0.002881f, 0.000017f, 0.003586f, 0.001403f, 0.010864f, 0.002575f, 0.011001f, 0.000614f, 0.005683f, 0.001488f, 0.008447f, 0.001862f, 0.012468f, 0.004164f, 0.012419f, +0.001633f, 0.003683f, 0.000027f, 0.004859f, 0.001488f, 0.004756f, 0.001416f, 0.005105f, 0.000019f, 0.000072f, 0.000024f, 0.000114f, 0.005040f, 0.013928f, 0.005842f, 0.014706f, +0.006061f, 0.012542f, 0.000100f, 0.016839f, 0.007829f, 0.022957f, 0.007530f, 0.025080f, 0.005447f, 0.019103f, 0.006919f, 0.030629f, 0.016672f, 0.042269f, 0.019532f, 0.045419f, +0.002770f, 0.006311f, 0.000054f, 0.007621f, 0.004928f, 0.015912f, 0.005582f, 0.015636f, 0.002248f, 0.008679f, 0.003362f, 0.012517f, 0.013827f, 0.038599f, 0.019074f, 0.037305f, +0.005256f, 0.013036f, 0.000111f, 0.015725f, 0.009933f, 0.034913f, 0.012208f, 0.034268f, 0.004627f, 0.019450f, 0.007510f, 0.028018f, 0.014723f, 0.044743f, 0.022041f, 0.043195f, +0.030336f, 0.074020f, 0.000509f, 0.104924f, 0.036864f, 0.127472f, 0.035910f, 0.147027f, 0.000279f, 0.001154f, 0.000359f, 0.001954f, 0.071364f, 0.213361f, 0.084677f, 0.242056f, +0.060971f, 0.136478f, 0.001033f, 0.196870f, 0.105021f, 0.333153f, 0.103394f, 0.391035f, 0.043670f, 0.165673f, 0.056779f, 0.285398f, 0.127817f, 0.350572f, 0.153277f, 0.404732f, +0.000767f, 0.001889f, 0.000015f, 0.002452f, 0.001819f, 0.006353f, 0.002109f, 0.006707f, 0.000496f, 0.002071f, 0.000759f, 0.003209f, 0.002917f, 0.008808f, 0.004118f, 0.009146f, +0.087874f, 0.235771f, 0.001903f, 0.305564f, 0.221463f, 0.842090f, 0.278604f, 0.888026f, 0.061654f, 0.280360f, 0.102430f, 0.433921f, 0.187606f, 0.616772f, 0.287476f, 0.639750f, +0.061734f, 0.207388f, 0.000980f, 0.260921f, 0.071035f, 0.338189f, 0.065530f, 0.346211f, 0.000610f, 0.003474f, 0.000743f, 0.005220f, 0.132680f, 0.546153f, 0.149087f, 0.549939f, +0.174159f, 0.536732f, 0.002795f, 0.687184f, 0.284060f, 1.240648f, 0.264836f, 1.292468f, 0.133995f, 0.699886f, 0.164982f, 1.070103f, 0.333561f, 1.259607f, 0.378803f, 1.290700f, +0.082716f, 0.280691f, 0.001563f, 0.323236f, 0.185839f, 0.893723f, 0.204016f, 0.837433f, 0.057462f, 0.330482f, 0.083309f, 0.454488f, 0.287502f, 1.195440f, 0.384447f, 1.101777f, +0.219235f, 0.809864f, 0.004496f, 0.931586f, 0.523193f, 2.738996f, 0.623302f, 2.563644f, 0.165231f, 1.034472f, 0.259960f, 1.421060f, 0.427623f, 1.935577f, 0.620535f, 1.781951f, +0.013142f, 0.087519f, 0.000362f, 0.095168f, 0.017529f, 0.165434f, 0.028065f, 0.146375f, 0.000154f, 0.001743f, 0.000327f, 0.002264f, 0.036555f, 0.298296f, 0.071293f, 0.259602f, +0.031547f, 0.192734f, 0.000879f, 0.213271f, 0.059644f, 0.516408f, 0.096514f, 0.464968f, 0.028859f, 0.298820f, 0.061672f, 0.394883f, 0.078199f, 0.585394f, 0.154133f, 0.518439f, +0.013744f, 0.092458f, 0.000451f, 0.092022f, 0.035794f, 0.341241f, 0.068201f, 0.276355f, 0.011352f, 0.129433f, 0.028566f, 0.153843f, 0.061827f, 0.509630f, 0.143494f, 0.405957f, +0.053323f, 0.390490f, 0.001898f, 0.388221f, 0.147508f, 1.530850f, 0.305007f, 1.238393f, 0.047784f, 0.593061f, 0.130484f, 0.704129f, 0.134611f, 1.207872f, 0.339036f, 0.961093f, +0.092807f, 0.280471f, 0.001712f, 0.295597f, 0.087928f, 0.376585f, 0.094233f, 0.322947f, 0.000825f, 0.004226f, 0.001168f, 0.005319f, 0.204761f, 0.758232f, 0.267295f, 0.639570f, +0.267498f, 0.741613f, 0.004987f, 0.795387f, 0.359239f, 1.411454f, 0.389098f, 1.231754f, 0.185106f, 0.869765f, 0.264774f, 1.114003f, 0.525938f, 1.786645f, 0.693872f, 1.533607f, +0.117007f, 0.357185f, 0.002569f, 0.344565f, 0.216449f, 0.936411f, 0.276052f, 0.735021f, 0.073107f, 0.378241f, 0.123133f, 0.435741f, 0.417490f, 1.561623f, 0.648558f, 1.205669f, +0.245677f, 0.816414f, 0.005853f, 0.786696f, 0.482741f, 2.273464f, 0.668126f, 1.782544f, 0.166533f, 0.937933f, 0.304384f, 1.079323f, 0.491924f, 2.003051f, 0.829298f, 1.544767f, +0.036121f, 0.064639f, 0.000393f, 0.092161f, 0.059299f, 0.150387f, 0.037475f, 0.174468f, 0.000335f, 0.001015f, 0.000279f, 0.001728f, 0.096303f, 0.211163f, 0.074132f, 0.240959f, +0.056020f, 0.091965f, 0.000616f, 0.133433f, 0.130359f, 0.303285f, 0.083261f, 0.358052f, 0.040399f, 0.112403f, 0.034076f, 0.194760f, 0.133095f, 0.267727f, 0.103545f, 0.310890f, +0.000570f, 0.001031f, 0.000007f, 0.001345f, 0.001827f, 0.004681f, 0.001374f, 0.004971f, 0.000371f, 0.001137f, 0.000369f, 0.001772f, 0.002458f, 0.005444f, 0.002252f, 0.005686f, +0.090751f, 0.178575f, 0.001275f, 0.232786f, 0.308986f, 0.861664f, 0.252177f, 0.913964f, 0.064108f, 0.213802f, 0.069097f, 0.332836f, 0.219580f, 0.529434f, 0.218287f, 0.552360f, +0.042840f, 0.105549f, 0.000441f, 0.133569f, 0.066596f, 0.232530f, 0.039856f, 0.239434f, 0.000426f, 0.001780f, 0.000337f, 0.002690f, 0.104349f, 0.315022f, 0.076069f, 0.319055f, +0.093258f, 0.210785f, 0.000971f, 0.271444f, 0.205494f, 0.658233f, 0.124293f, 0.689724f, 0.072243f, 0.276742f, 0.057706f, 0.425597f, 0.202429f, 0.560628f, 0.149139f, 0.577815f, +0.035850f, 0.089221f, 0.000439f, 0.103344f, 0.108813f, 0.383788f, 0.077498f, 0.361712f, 0.025075f, 0.105768f, 0.023585f, 0.146303f, 0.141220f, 0.430649f, 0.122510f, 0.399222f, +0.131954f, 0.357493f, 0.001755f, 0.413621f, 0.425426f, 1.633410f, 0.328807f, 1.537751f, 0.100131f, 0.459769f, 0.102204f, 0.635269f, 0.291696f, 0.968328f, 0.274610f, 0.896668f, +0.000240f, 0.001174f, 0.000004f, 0.001284f, 0.000433f, 0.002998f, 0.000450f, 0.002668f, 0.000003f, 0.000024f, 0.000004f, 0.000031f, 0.000758f, 0.004534f, 0.000959f, 0.003969f, +0.000445f, 0.001995f, 0.000008f, 0.002220f, 0.001137f, 0.007220f, 0.001194f, 0.006539f, 0.000410f, 0.003114f, 0.000568f, 0.004139f, 0.001251f, 0.006866f, 0.001599f, 0.006116f, +0.000157f, 0.000774f, 0.000003f, 0.000775f, 0.000552f, 0.003862f, 0.000683f, 0.003146f, 0.000131f, 0.001092f, 0.000213f, 0.001305f, 0.000800f, 0.004838f, 0.001205f, 0.003876f, +0.000846f, 0.004543f, 0.000020f, 0.004542f, 0.003161f, 0.024059f, 0.004240f, 0.019576f, 0.000763f, 0.006946f, 0.001352f, 0.008295f, 0.002420f, 0.015925f, 0.003954f, 0.012745f, +0.117224f, 0.259817f, 0.001403f, 0.275425f, 0.150042f, 0.471292f, 0.104320f, 0.406520f, 0.001049f, 0.003942f, 0.000963f, 0.004990f, 0.293117f, 0.796044f, 0.248236f, 0.675379f, +0.260717f, 0.530112f, 0.003153f, 0.571865f, 0.473020f, 1.363031f, 0.332381f, 1.196429f, 0.181649f, 0.625976f, 0.168566f, 0.806429f, 0.580950f, 1.447389f, 0.497239f, 1.249641f, +0.092303f, 0.206653f, 0.001315f, 0.200513f, 0.230680f, 0.731918f, 0.190864f, 0.577856f, 0.058067f, 0.220334f, 0.063449f, 0.255309f, 0.373256f, 1.023953f, 0.376176f, 0.795163f, +0.269144f, 0.655954f, 0.004160f, 0.635762f, 0.714468f, 2.467740f, 0.641517f, 1.946148f, 0.183690f, 0.758753f, 0.217816f, 0.878221f, 0.610766f, 1.823943f, 0.667988f, 1.414838f, +0.040551f, 0.103050f, 0.000593f, 0.109704f, 0.056774f, 0.204471f, 0.048245f, 0.177118f, 0.000377f, 0.001622f, 0.000423f, 0.002062f, 0.094349f, 0.293791f, 0.097658f, 0.250316f, +0.095744f, 0.223210f, 0.001415f, 0.241813f, 0.190013f, 0.627786f, 0.163187f, 0.553392f, 0.069211f, 0.273464f, 0.078497f, 0.353793f, 0.198519f, 0.567088f, 0.207670f, 0.491690f, +0.000987f, 0.002532f, 0.000017f, 0.002468f, 0.002697f, 0.009811f, 0.002727f, 0.007779f, 0.000644f, 0.002801f, 0.000860f, 0.003260f, 0.003712f, 0.011676f, 0.004572f, 0.009106f, +0.147463f, 0.412074f, 0.002785f, 0.401085f, 0.428197f, 1.695749f, 0.469909f, 1.343007f, 0.104420f, 0.494538f, 0.151333f, 0.574835f, 0.311383f, 1.066187f, 0.416231f, 0.830556f, +0.080583f, 0.281947f, 0.001116f, 0.266405f, 0.106835f, 0.529740f, 0.085973f, 0.407280f, 0.000804f, 0.004767f, 0.000854f, 0.005379f, 0.171297f, 0.734382f, 0.167908f, 0.555357f, +0.267066f, 0.857218f, 0.003739f, 0.824245f, 0.501882f, 2.282978f, 0.408183f, 1.786169f, 0.207378f, 1.128134f, 0.222738f, 1.295415f, 0.505910f, 1.989729f, 0.501182f, 1.531206f, +0.103946f, 0.367372f, 0.001713f, 0.317722f, 0.269075f, 1.347721f, 0.257682f, 0.948411f, 0.072879f, 0.436542f, 0.092170f, 0.450868f, 0.357341f, 1.547498f, 0.416834f, 1.071139f, +0.359268f, 1.382233f, 0.006427f, 1.194102f, 0.987846f, 5.386165f, 1.026621f, 3.786130f, 0.273274f, 1.781917f, 0.375058f, 1.838360f, 0.693096f, 3.267415f, 0.877371f, 2.259119f, +0.015949f, 0.110620f, 0.000383f, 0.090338f, 0.024509f, 0.240920f, 0.034233f, 0.160090f, 0.000189f, 0.002224f, 0.000349f, 0.002169f, 0.043877f, 0.372908f, 0.074649f, 0.243731f, +0.044975f, 0.286179f, 0.001093f, 0.237827f, 0.097972f, 0.883469f, 0.138297f, 0.597409f, 0.041524f, 0.447806f, 0.077409f, 0.444423f, 0.110266f, 0.859712f, 0.189594f, 0.571810f, +0.016057f, 0.112504f, 0.000459f, 0.084094f, 0.048182f, 0.478414f, 0.080086f, 0.290978f, 0.013386f, 0.158953f, 0.029383f, 0.141890f, 0.071444f, 0.613342f, 0.144646f, 0.366926f, +0.081240f, 0.619619f, 0.002522f, 0.462641f, 0.258932f, 2.798767f, 0.467054f, 1.700364f, 0.073474f, 0.949759f, 0.175022f, 0.846868f, 0.202843f, 1.895660f, 0.445666f, 1.132804f, +0.127235f, 0.400475f, 0.002047f, 0.316983f, 0.138891f, 0.619540f, 0.129847f, 0.399012f, 0.001142f, 0.006090f, 0.001409f, 0.005756f, 0.277650f, 1.070813f, 0.316174f, 0.678343f, +0.430821f, 1.243984f, 0.007007f, 1.001995f, 0.666620f, 2.727868f, 0.629853f, 1.787846f, 0.300881f, 1.472444f, 0.375435f, 1.416357f, 0.837790f, 2.964152f, 0.964195f, 1.910847f, +0.154430f, 0.490993f, 0.002957f, 0.355715f, 0.329151f, 1.483088f, 0.366197f, 0.874278f, 0.097382f, 0.524746f, 0.143079f, 0.454003f, 0.544992f, 2.123157f, 0.738547f, 1.231072f, +0.422839f, 1.463467f, 0.008787f, 1.059081f, 0.957292f, 4.695476f, 1.155774f, 2.764912f, 0.289274f, 1.696851f, 0.461230f, 1.466469f, 0.837401f, 3.551314f, 1.231490f, 2.056883f, +0.028250f, 0.051445f, 0.000421f, 0.091287f, 0.044915f, 0.115916f, 0.038854f, 0.167366f, 0.000356f, 0.001099f, 0.000407f, 0.002330f, 0.082744f, 0.184630f, 0.087185f, 0.262209f, +0.060028f, 0.100281f, 0.000903f, 0.181084f, 0.135282f, 0.320285f, 0.118271f, 0.470600f, 0.058920f, 0.166823f, 0.068027f, 0.359748f, 0.156680f, 0.320723f, 0.166848f, 0.463515f, +0.000683f, 0.001256f, 0.000012f, 0.002041f, 0.002120f, 0.005528f, 0.002183f, 0.007306f, 0.000605f, 0.001887f, 0.000823f, 0.003661f, 0.003236f, 0.007293f, 0.004057f, 0.009480f, +0.083919f, 0.168043f, 0.001614f, 0.272631f, 0.276719f, 0.785282f, 0.309133f, 1.036658f, 0.080688f, 0.273839f, 0.119040f, 0.530556f, 0.223072f, 0.547333f, 0.303543f, 0.710690f, +0.050060f, 0.125512f, 0.000706f, 0.197676f, 0.075366f, 0.267792f, 0.061740f, 0.343180f, 0.000678f, 0.002881f, 0.000734f, 0.005420f, 0.133959f, 0.411540f, 0.133668f, 0.518746f, +0.149308f, 0.343419f, 0.002128f, 0.550405f, 0.318627f, 1.038609f, 0.263798f, 1.354459f, 0.157425f, 0.613680f, 0.172124f, 1.174581f, 0.356048f, 1.003457f, 0.359060f, 1.287156f, +0.064178f, 0.162539f, 0.001077f, 0.234311f, 0.188657f, 0.677126f, 0.183917f, 0.794254f, 0.061099f, 0.262256f, 0.078661f, 0.451485f, 0.277739f, 0.861895f, 0.329803f, 0.994404f, +0.182314f, 0.502635f, 0.003320f, 0.723779f, 0.569258f, 2.224176f, 0.602236f, 2.606021f, 0.188300f, 0.879848f, 0.263079f, 1.513017f, 0.442760f, 1.495713f, 0.570550f, 1.723756f, +0.007847f, 0.039000f, 0.000192f, 0.053088f, 0.013694f, 0.096455f, 0.019470f, 0.106834f, 0.000126f, 0.001065f, 0.000237f, 0.001731f, 0.027176f, 0.165504f, 0.047065f, 0.180307f, +0.019914f, 0.090800f, 0.000493f, 0.125778f, 0.049261f, 0.318317f, 0.070786f, 0.358783f, 0.024965f, 0.192925f, 0.047376f, 0.319145f, 0.061460f, 0.343380f, 0.107575f, 0.380686f, +0.007852f, 0.039422f, 0.000229f, 0.049117f, 0.026755f, 0.190366f, 0.045270f, 0.192992f, 0.008888f, 0.075629f, 0.019860f, 0.112528f, 0.043978f, 0.270548f, 0.090639f, 0.269782f, +0.032651f, 0.178449f, 0.001032f, 0.222088f, 0.118175f, 0.915321f, 0.216990f, 0.926918f, 0.040096f, 0.371408f, 0.097230f, 0.552009f, 0.102625f, 0.687261f, 0.229529f, 0.684555f, +0.161411f, 0.364058f, 0.002644f, 0.480314f, 0.200087f, 0.639562f, 0.190421f, 0.686582f, 0.001966f, 0.007517f, 0.002472f, 0.011844f, 0.443401f, 1.225410f, 0.513998f, 1.293928f, +0.491856f, 1.017713f, 0.008143f, 1.366372f, 0.864246f, 2.534262f, 0.831255f, 2.768542f, 0.466429f, 1.635679f, 0.592463f, 2.622556f, 1.204061f, 3.052692f, 1.410634f, 3.280208f, +0.194711f, 0.443613f, 0.003796f, 0.535704f, 0.471274f, 1.521649f, 0.533739f, 1.495168f, 0.166720f, 0.643765f, 0.249358f, 0.928390f, 0.865013f, 2.414815f, 1.193293f, 2.333879f, +0.438183f, 1.086757f, 0.009270f, 1.310905f, 1.126529f, 3.959558f, 1.384546f, 3.886346f, 0.407042f, 1.710968f, 0.660667f, 2.464699f, 1.092411f, 3.319790f, 1.635384f, 3.204972f, +0.080377f, 0.196119f, 0.001348f, 0.278000f, 0.132873f, 0.459467f, 0.129436f, 0.529952f, 0.000780f, 0.003227f, 0.001004f, 0.005463f, 0.168286f, 0.503135f, 0.199679f, 0.570802f, +0.132601f, 0.296816f, 0.002247f, 0.428157f, 0.310721f, 0.985682f, 0.305906f, 1.156935f, 0.100217f, 0.380195f, 0.130298f, 0.654947f, 0.247408f, 0.678578f, 0.296688f, 0.783413f, +0.001444f, 0.003560f, 0.000029f, 0.004619f, 0.004662f, 0.016283f, 0.005404f, 0.017191f, 0.000986f, 0.004117f, 0.001509f, 0.006379f, 0.004890f, 0.014769f, 0.006905f, 0.015336f, +0.196342f, 0.526796f, 0.004252f, 0.682737f, 0.673168f, 2.559648f, 0.846855f, 2.699277f, 0.145360f, 0.660996f, 0.241495f, 1.023042f, 0.373077f, 1.226523f, 0.571680f, 1.272219f, +0.187754f, 0.630741f, 0.002981f, 0.793555f, 0.293906f, 1.399260f, 0.271129f, 1.432451f, 0.001958f, 0.011150f, 0.002386f, 0.016752f, 0.359147f, 1.478366f, 0.403560f, 1.488614f, +0.434778f, 1.339920f, 0.006977f, 1.715514f, 0.964720f, 4.213475f, 0.899435f, 4.389465f, 0.352974f, 1.843658f, 0.434600f, 2.818894f, 0.741135f, 2.798701f, 0.841655f, 2.867784f, +0.178878f, 0.607010f, 0.003380f, 0.699016f, 0.546733f, 2.629304f, 0.600208f, 2.463701f, 0.131124f, 0.754132f, 0.190103f, 1.037103f, 0.553362f, 2.300885f, 0.739954f, 2.120611f, +0.562290f, 2.077122f, 0.011530f, 2.389311f, 1.825503f, 9.556782f, 2.174797f, 8.944952f, 0.447170f, 2.799629f, 0.703538f, 3.845864f, 0.976137f, 4.418351f, 1.416497f, 4.067667f, +0.028910f, 0.192533f, 0.000797f, 0.209359f, 0.052459f, 0.495104f, 0.083993f, 0.438064f, 0.000359f, 0.004047f, 0.000758f, 0.005255f, 0.071573f, 0.584049f, 0.139587f, 0.508287f, +0.056965f, 0.348026f, 0.001587f, 0.385112f, 0.146517f, 1.268579f, 0.237092f, 1.142216f, 0.054988f, 0.569372f, 0.117510f, 0.752409f, 0.125676f, 0.940812f, 0.247714f, 0.833206f, +0.021499f, 0.144625f, 0.000705f, 0.143944f, 0.076169f, 0.726159f, 0.145132f, 0.588083f, 0.018738f, 0.213638f, 0.047151f, 0.253928f, 0.086076f, 0.709505f, 0.199772f, 0.565172f, +0.098924f, 0.724423f, 0.003521f, 0.720216f, 0.372278f, 3.863547f, 0.769773f, 3.125445f, 0.093540f, 1.160951f, 0.255429f, 1.378373f, 0.222262f, 1.994362f, 0.559795f, 1.586896f, +0.274814f, 0.830511f, 0.005069f, 0.875301f, 0.354207f, 1.517019f, 0.379605f, 1.300943f, 0.002578f, 0.013204f, 0.003649f, 0.016619f, 0.539641f, 1.998293f, 0.704448f, 1.685565f, +0.650177f, 1.802552f, 0.012121f, 1.933255f, 1.187857f, 4.667109f, 1.286591f, 4.072912f, 0.474747f, 2.230717f, 0.679074f, 2.857122f, 1.137745f, 3.864994f, 1.501031f, 3.317605f, +0.246359f, 0.752057f, 0.005408f, 0.725484f, 0.619989f, 2.682217f, 0.790711f, 2.105363f, 0.162423f, 0.840344f, 0.273566f, 0.968094f, 0.782352f, 2.926394f, 1.215361f, 2.259356f, +0.613484f, 2.038682f, 0.014615f, 1.964473f, 1.639925f, 7.723205f, 2.269696f, 6.055497f, 0.438804f, 2.471398f, 0.802035f, 2.843952f, 1.093294f, 4.451752f, 1.843103f, 3.433223f, +0.007730f, 0.013833f, 0.000084f, 0.019722f, 0.012960f, 0.032866f, 0.008190f, 0.038129f, 0.000086f, 0.000260f, 0.000072f, 0.000443f, 0.026137f, 0.057311f, 0.020120f, 0.065398f, +0.015845f, 0.026012f, 0.000174f, 0.037742f, 0.037656f, 0.087607f, 0.024051f, 0.103428f, 0.013700f, 0.038118f, 0.011556f, 0.066046f, 0.047746f, 0.096043f, 0.037145f, 0.111527f, +0.000178f, 0.000322f, 0.000002f, 0.000420f, 0.000583f, 0.001495f, 0.000439f, 0.001587f, 0.000139f, 0.000426f, 0.000138f, 0.000664f, 0.000975f, 0.002159f, 0.000893f, 0.002255f, +0.028096f, 0.055287f, 0.000395f, 0.072070f, 0.097695f, 0.272439f, 0.079733f, 0.288976f, 0.023796f, 0.079360f, 0.025648f, 0.123544f, 0.086220f, 0.207887f, 0.085712f, 0.216889f, +0.011347f, 0.027956f, 0.000117f, 0.035377f, 0.018014f, 0.062897f, 0.010781f, 0.064765f, 0.000135f, 0.000565f, 0.000107f, 0.000854f, 0.035053f, 0.105823f, 0.025553f, 0.107177f, +0.032648f, 0.073793f, 0.000340f, 0.095028f, 0.073469f, 0.235334f, 0.044438f, 0.246593f, 0.030322f, 0.116156f, 0.024221f, 0.178633f, 0.089880f, 0.248922f, 0.066219f, 0.256553f, +0.013871f, 0.034522f, 0.000170f, 0.039986f, 0.042997f, 0.151651f, 0.030623f, 0.142928f, 0.011632f, 0.049064f, 0.010941f, 0.067868f, 0.069300f, 0.211330f, 0.060119f, 0.195908f, +0.050564f, 0.136988f, 0.000673f, 0.158496f, 0.166483f, 0.639208f, 0.128673f, 0.601773f, 0.046002f, 0.211225f, 0.046954f, 0.291853f, 0.141762f, 0.470601f, 0.133459f, 0.435775f, +0.000095f, 0.000463f, 0.000002f, 0.000506f, 0.000174f, 0.001207f, 0.000181f, 0.001074f, 0.000001f, 0.000011f, 0.000002f, 0.000015f, 0.000379f, 0.002268f, 0.000479f, 0.001985f, +0.000232f, 0.001040f, 0.000004f, 0.001157f, 0.000605f, 0.003844f, 0.000635f, 0.003481f, 0.000256f, 0.001946f, 0.000355f, 0.002587f, 0.000827f, 0.004539f, 0.001057f, 0.004044f, +0.000090f, 0.000446f, 0.000002f, 0.000447f, 0.000325f, 0.002272f, 0.000402f, 0.001851f, 0.000090f, 0.000754f, 0.000147f, 0.000901f, 0.000585f, 0.003535f, 0.000880f, 0.002832f, +0.000483f, 0.002592f, 0.000011f, 0.002592f, 0.001842f, 0.014019f, 0.002471f, 0.011407f, 0.000522f, 0.004752f, 0.000925f, 0.005674f, 0.001751f, 0.011523f, 0.002861f, 0.009223f, +0.030523f, 0.067651f, 0.000365f, 0.071715f, 0.039898f, 0.125323f, 0.027740f, 0.108099f, 0.000328f, 0.001230f, 0.000301f, 0.001558f, 0.096798f, 0.262883f, 0.081977f, 0.223035f, +0.089728f, 0.182443f, 0.001085f, 0.196813f, 0.166254f, 0.479069f, 0.116823f, 0.420513f, 0.074952f, 0.258291f, 0.069554f, 0.332750f, 0.253580f, 0.631773f, 0.217040f, 0.545458f, +0.035110f, 0.078605f, 0.000500f, 0.076270f, 0.089609f, 0.284318f, 0.074142f, 0.224471f, 0.026481f, 0.100481f, 0.028935f, 0.116431f, 0.180066f, 0.493975f, 0.181475f, 0.383602f, +0.101388f, 0.247101f, 0.001567f, 0.239494f, 0.274863f, 0.949364f, 0.246798f, 0.748703f, 0.082962f, 0.342684f, 0.098374f, 0.396641f, 0.291805f, 0.871422f, 0.319144f, 0.675965f, +0.008535f, 0.021691f, 0.000125f, 0.023092f, 0.012204f, 0.043954f, 0.010371f, 0.038074f, 0.000095f, 0.000409f, 0.000107f, 0.000520f, 0.025188f, 0.078430f, 0.026071f, 0.066824f, +0.026638f, 0.062100f, 0.000394f, 0.067276f, 0.053988f, 0.178372f, 0.046366f, 0.157234f, 0.023086f, 0.091217f, 0.026184f, 0.118011f, 0.070049f, 0.200101f, 0.073278f, 0.173496f, +0.000303f, 0.000779f, 0.000005f, 0.000759f, 0.000847f, 0.003081f, 0.000856f, 0.002443f, 0.000237f, 0.001033f, 0.000317f, 0.001202f, 0.001448f, 0.004553f, 0.001783f, 0.003551f, +0.044906f, 0.125487f, 0.000848f, 0.122140f, 0.133168f, 0.527373f, 0.146140f, 0.417671f, 0.038124f, 0.180557f, 0.055252f, 0.209874f, 0.120264f, 0.411787f, 0.160758f, 0.320781f, +0.020994f, 0.073453f, 0.000291f, 0.069404f, 0.028424f, 0.140942f, 0.022874f, 0.108360f, 0.000251f, 0.001489f, 0.000267f, 0.001680f, 0.056599f, 0.242652f, 0.055480f, 0.183499f, +0.091963f, 0.295181f, 0.001287f, 0.283827f, 0.176494f, 0.802843f, 0.143543f, 0.628133f, 0.085615f, 0.465746f, 0.091956f, 0.534807f, 0.220946f, 0.868974f, 0.218881f, 0.668723f, +0.039560f, 0.139815f, 0.000652f, 0.120919f, 0.104581f, 0.523815f, 0.100153f, 0.368617f, 0.033254f, 0.199188f, 0.042056f, 0.205725f, 0.172482f, 0.746951f, 0.201199f, 0.517020f, +0.135412f, 0.520978f, 0.002422f, 0.450070f, 0.380242f, 2.073243f, 0.395167f, 1.457357f, 0.123489f, 0.805225f, 0.169484f, 0.830731f, 0.331320f, 1.561919f, 0.419409f, 1.079924f, +0.006187f, 0.042911f, 0.000149f, 0.035043f, 0.009709f, 0.095441f, 0.013561f, 0.063420f, 0.000088f, 0.001034f, 0.000162f, 0.001009f, 0.021587f, 0.183463f, 0.036726f, 0.119911f, +0.023060f, 0.146730f, 0.000560f, 0.121939f, 0.051300f, 0.462601f, 0.072415f, 0.312814f, 0.025526f, 0.275273f, 0.047585f, 0.273194f, 0.071704f, 0.559051f, 0.123288f, 0.371835f, +0.009099f, 0.063753f, 0.000260f, 0.047654f, 0.027884f, 0.276865f, 0.046347f, 0.168393f, 0.009094f, 0.107992f, 0.019963f, 0.096400f, 0.051347f, 0.440809f, 0.103957f, 0.263709f, +0.045593f, 0.347735f, 0.001416f, 0.259638f, 0.148403f, 1.604069f, 0.267684f, 0.974537f, 0.049437f, 0.639042f, 0.117763f, 0.569812f, 0.144378f, 1.349275f, 0.317212f, 0.806296f, +0.032587f, 0.102567f, 0.000524f, 0.081184f, 0.036328f, 0.162044f, 0.033962f, 0.104364f, 0.000351f, 0.001870f, 0.000433f, 0.001768f, 0.090187f, 0.347826f, 0.102701f, 0.220342f, +0.145841f, 0.421113f, 0.002372f, 0.339195f, 0.230459f, 0.943060f, 0.217748f, 0.618082f, 0.122116f, 0.597605f, 0.152374f, 0.574842f, 0.359695f, 1.272624f, 0.413966f, 0.820400f, +0.057778f, 0.183699f, 0.001106f, 0.133087f, 0.125765f, 0.566673f, 0.139920f, 0.334053f, 0.043682f, 0.235382f, 0.064180f, 0.203650f, 0.258606f, 1.007468f, 0.350451f, 0.584161f, +0.156675f, 0.542260f, 0.003256f, 0.392423f, 0.362245f, 1.776794f, 0.437351f, 1.046258f, 0.128507f, 0.753808f, 0.204897f, 0.651463f, 0.393527f, 1.668900f, 0.578725f, 0.966609f, +0.004425f, 0.008059f, 0.000066f, 0.014300f, 0.007185f, 0.018543f, 0.006216f, 0.026774f, 0.000067f, 0.000206f, 0.000076f, 0.000438f, 0.016439f, 0.036680f, 0.017321f, 0.052093f, +0.012428f, 0.020763f, 0.000187f, 0.037493f, 0.028605f, 0.067723f, 0.025008f, 0.099506f, 0.014626f, 0.041411f, 0.016886f, 0.089301f, 0.041143f, 0.084219f, 0.043813f, 0.121715f, +0.000156f, 0.000288f, 0.000003f, 0.000467f, 0.000496f, 0.001292f, 0.000510f, 0.001707f, 0.000166f, 0.000518f, 0.000226f, 0.001004f, 0.000939f, 0.002117f, 0.001177f, 0.002751f, +0.019018f, 0.038083f, 0.000366f, 0.061785f, 0.064044f, 0.181746f, 0.071546f, 0.239925f, 0.021923f, 0.074404f, 0.032344f, 0.144155f, 0.064116f, 0.157317f, 0.087246f, 0.204270f, +0.009706f, 0.024334f, 0.000137f, 0.038325f, 0.014922f, 0.053022f, 0.012224f, 0.067949f, 0.000158f, 0.000670f, 0.000171f, 0.001260f, 0.032939f, 0.101195f, 0.032868f, 0.127556f, +0.038262f, 0.088004f, 0.000545f, 0.141047f, 0.083386f, 0.271810f, 0.069037f, 0.354469f, 0.048367f, 0.188545f, 0.052883f, 0.360874f, 0.115719f, 0.326133f, 0.116698f, 0.418339f, +0.018177f, 0.046035f, 0.000305f, 0.066362f, 0.054568f, 0.195854f, 0.053197f, 0.229732f, 0.020747f, 0.089053f, 0.026710f, 0.153308f, 0.099766f, 0.309599f, 0.118468f, 0.357198f, +0.051138f, 0.140986f, 0.000931f, 0.203015f, 0.163066f, 0.637123f, 0.172513f, 0.746504f, 0.063323f, 0.295884f, 0.088471f, 0.508812f, 0.157509f, 0.532091f, 0.202970f, 0.613217f, +0.002265f, 0.011259f, 0.000055f, 0.015325f, 0.004037f, 0.028436f, 0.005740f, 0.031496f, 0.000044f, 0.000368f, 0.000082f, 0.000599f, 0.009950f, 0.060595f, 0.017232f, 0.066015f, +0.007598f, 0.034646f, 0.000188f, 0.047992f, 0.019195f, 0.124039f, 0.027583f, 0.139808f, 0.011421f, 0.088256f, 0.021673f, 0.145998f, 0.029743f, 0.166172f, 0.052059f, 0.184225f, +0.003311f, 0.016625f, 0.000096f, 0.020713f, 0.011523f, 0.081986f, 0.019497f, 0.083117f, 0.004494f, 0.038238f, 0.010041f, 0.056894f, 0.023522f, 0.144703f, 0.048478f, 0.144292f, +0.013636f, 0.074528f, 0.000431f, 0.092754f, 0.050404f, 0.390403f, 0.092551f, 0.395350f, 0.020077f, 0.185973f, 0.048685f, 0.276405f, 0.054360f, 0.364037f, 0.121580f, 0.362604f, +0.030764f, 0.069388f, 0.000504f, 0.091546f, 0.038946f, 0.124489f, 0.037065f, 0.133641f, 0.000449f, 0.001718f, 0.000565f, 0.002706f, 0.107184f, 0.296219f, 0.124249f, 0.312782f, +0.123910f, 0.256385f, 0.002051f, 0.344220f, 0.222350f, 0.652005f, 0.213862f, 0.712280f, 0.140878f, 0.494034f, 0.178945f, 0.792107f, 0.384708f, 0.975363f, 0.450711f, 1.048057f, +0.054214f, 0.123516f, 0.001057f, 0.149156f, 0.134005f, 0.432677f, 0.151767f, 0.425147f, 0.055654f, 0.214900f, 0.083240f, 0.309912f, 0.305461f, 0.852740f, 0.421386f, 0.824159f, +0.120827f, 0.299669f, 0.002556f, 0.361477f, 0.317237f, 1.115034f, 0.389896f, 1.094417f, 0.134567f, 0.565643f, 0.218416f, 0.814825f, 0.382042f, 1.161009f, 0.571932f, 1.120854f, +0.022491f, 0.054877f, 0.000377f, 0.077789f, 0.037970f, 0.131298f, 0.036988f, 0.151440f, 0.000262f, 0.001083f, 0.000337f, 0.001833f, 0.059722f, 0.178556f, 0.070863f, 0.202570f, +0.049042f, 0.109777f, 0.000831f, 0.158353f, 0.117362f, 0.372300f, 0.115543f, 0.436984f, 0.044438f, 0.168587f, 0.057777f, 0.290417f, 0.116052f, 0.318302f, 0.139168f, 0.367478f, +0.000590f, 0.001455f, 0.000012f, 0.001888f, 0.001946f, 0.006798f, 0.002256f, 0.007176f, 0.000483f, 0.002018f, 0.000739f, 0.003126f, 0.002535f, 0.007657f, 0.003580f, 0.007951f, +0.079484f, 0.213259f, 0.001721f, 0.276388f, 0.278305f, 1.058225f, 0.350112f, 1.115952f, 0.070551f, 0.320816f, 0.117210f, 0.496536f, 0.191549f, 0.629734f, 0.293518f, 0.653196f, +0.065024f, 0.218443f, 0.001032f, 0.274830f, 0.103951f, 0.494901f, 0.095895f, 0.506640f, 0.000813f, 0.004630f, 0.000991f, 0.006956f, 0.157752f, 0.649360f, 0.177260f, 0.653861f, +0.199024f, 0.613363f, 0.003194f, 0.785295f, 0.450996f, 1.969751f, 0.420476f, 2.052025f, 0.193719f, 1.011838f, 0.238518f, 1.547068f, 0.430281f, 1.624842f, 0.488640f, 1.664950f, +0.090499f, 0.307103f, 0.001710f, 0.353651f, 0.282485f, 1.358505f, 0.310115f, 1.272941f, 0.079536f, 0.457433f, 0.115310f, 0.629074f, 0.355069f, 1.476383f, 0.474798f, 1.360709f, +0.281735f, 1.040740f, 0.005777f, 1.197162f, 0.934104f, 4.890174f, 1.112836f, 4.577102f, 0.268624f, 1.681793f, 0.422630f, 2.310288f, 0.620308f, 2.807738f, 0.900144f, 2.584888f, +0.014908f, 0.099284f, 0.000411f, 0.107960f, 0.027626f, 0.260736f, 0.044233f, 0.230697f, 0.000222f, 0.002502f, 0.000469f, 0.003249f, 0.046810f, 0.381978f, 0.091292f, 0.332428f, +0.038827f, 0.237212f, 0.001081f, 0.262489f, 0.101987f, 0.883028f, 0.165034f, 0.795069f, 0.044935f, 0.465278f, 0.096027f, 0.614852f, 0.108641f, 0.813286f, 0.214137f, 0.720266f, +0.016195f, 0.108947f, 0.000531f, 0.108435f, 0.058598f, 0.558648f, 0.111653f, 0.452423f, 0.016923f, 0.192949f, 0.042585f, 0.229339f, 0.082237f, 0.677868f, 0.190864f, 0.539971f, +0.073802f, 0.540454f, 0.002627f, 0.537315f, 0.283639f, 2.943639f, 0.586491f, 2.381279f, 0.083667f, 1.038417f, 0.228470f, 1.232891f, 0.210304f, 1.887061f, 0.529677f, 1.501518f, +0.093565f, 0.282761f, 0.001726f, 0.298010f, 0.123158f, 0.527470f, 0.131989f, 0.452340f, 0.001052f, 0.005390f, 0.001489f, 0.006784f, 0.233021f, 0.862878f, 0.304186f, 0.727840f, +0.292588f, 0.811173f, 0.005455f, 0.869991f, 0.545911f, 2.144894f, 0.591287f, 1.871815f, 0.256141f, 1.203544f, 0.366382f, 1.541509f, 0.649362f, 2.205924f, 0.856705f, 1.893505f, +0.122530f, 0.374046f, 0.002690f, 0.360830f, 0.314913f, 1.362389f, 0.401629f, 1.069385f, 0.096853f, 0.501099f, 0.163128f, 0.577277f, 0.493507f, 1.845967f, 0.766649f, 1.425200f, +0.302183f, 1.004192f, 0.007199f, 0.967638f, 0.824942f, 3.885054f, 1.141740f, 3.046136f, 0.259137f, 1.459492f, 0.473644f, 1.679505f, 0.682999f, 2.781085f, 1.151417f, 2.144792f, +0.050497f, 0.090365f, 0.000549f, 0.128840f, 0.068239f, 0.173058f, 0.043125f, 0.200769f, 0.000438f, 0.001327f, 0.000365f, 0.002260f, 0.138373f, 0.303412f, 0.106517f, 0.346225f, +0.118349f, 0.194288f, 0.001301f, 0.281894f, 0.226695f, 0.527414f, 0.144791f, 0.622655f, 0.079848f, 0.222163f, 0.067351f, 0.384942f, 0.288999f, 0.581334f, 0.224835f, 0.675058f, +0.000940f, 0.001700f, 0.000012f, 0.002218f, 0.002481f, 0.006356f, 0.001866f, 0.006749f, 0.000573f, 0.001755f, 0.000569f, 0.002735f, 0.004167f, 0.009229f, 0.003817f, 0.009640f, +0.135374f, 0.266383f, 0.001902f, 0.347249f, 0.379403f, 1.058034f, 0.309647f, 1.122254f, 0.089469f, 0.298379f, 0.096431f, 0.464502f, 0.336657f, 0.811721f, 0.334675f, 0.846871f, +0.053945f, 0.132910f, 0.000556f, 0.168193f, 0.069028f, 0.241024f, 0.041312f, 0.248179f, 0.000502f, 0.002097f, 0.000397f, 0.003170f, 0.135053f, 0.407714f, 0.098451f, 0.412933f, +0.177463f, 0.401109f, 0.001848f, 0.516538f, 0.321883f, 1.031051f, 0.194692f, 1.080378f, 0.128614f, 0.492686f, 0.102735f, 0.757692f, 0.395919f, 1.096498f, 0.291692f, 1.130114f, +0.053259f, 0.132548f, 0.000653f, 0.153528f, 0.133065f, 0.469324f, 0.094770f, 0.442328f, 0.034852f, 0.147004f, 0.032780f, 0.203342f, 0.215630f, 0.657564f, 0.187062f, 0.609577f, +0.177299f, 0.480342f, 0.002359f, 0.555758f, 0.470527f, 1.806577f, 0.363666f, 1.700776f, 0.125871f, 0.577956f, 0.128476f, 0.798570f, 0.402833f, 1.337263f, 0.379237f, 1.238301f, +0.000400f, 0.001953f, 0.000007f, 0.002136f, 0.000593f, 0.004106f, 0.000616f, 0.003654f, 0.000004f, 0.000037f, 0.000006f, 0.000048f, 0.001296f, 0.007755f, 0.001640f, 0.006788f, +0.001119f, 0.005016f, 0.000020f, 0.005583f, 0.002354f, 0.014946f, 0.002471f, 0.013535f, 0.000965f, 0.007326f, 0.001337f, 0.009737f, 0.003232f, 0.017746f, 0.004133f, 0.015808f, +0.000308f, 0.001520f, 0.000007f, 0.001522f, 0.000893f, 0.006240f, 0.001103f, 0.005083f, 0.000240f, 0.002005f, 0.000391f, 0.002397f, 0.001615f, 0.009762f, 0.002431f, 0.007822f, +0.001502f, 0.008066f, 0.000035f, 0.008065f, 0.004620f, 0.035163f, 0.006197f, 0.028611f, 0.001268f, 0.011539f, 0.002246f, 0.013780f, 0.004416f, 0.029061f, 0.007216f, 0.023259f, +0.163196f, 0.361708f, 0.001953f, 0.383437f, 0.171942f, 0.540082f, 0.119547f, 0.465855f, 0.001367f, 0.005134f, 0.001255f, 0.006499f, 0.419414f, 1.139041f, 0.355195f, 0.966385f, +0.548504f, 1.115266f, 0.006634f, 1.203107f, 0.819159f, 2.360449f, 0.575606f, 2.071934f, 0.357533f, 1.232086f, 0.331782f, 1.587265f, 1.256205f, 3.129732f, 1.075194f, 2.702137f, +0.151603f, 0.339417f, 0.002159f, 0.329332f, 0.311874f, 0.989538f, 0.258045f, 0.781250f, 0.089227f, 0.338568f, 0.097496f, 0.392311f, 0.630101f, 1.728554f, 0.635030f, 1.342330f, +0.399812f, 0.974418f, 0.006179f, 0.944422f, 0.873641f, 3.017514f, 0.784437f, 2.379720f, 0.255288f, 1.054494f, 0.302715f, 1.220529f, 0.932519f, 2.784802f, 1.019886f, 2.160178f, +0.085291f, 0.216747f, 0.001248f, 0.230743f, 0.098296f, 0.354009f, 0.083529f, 0.306653f, 0.000741f, 0.003192f, 0.000832f, 0.004058f, 0.203965f, 0.635118f, 0.211118f, 0.541134f, +0.304325f, 0.709476f, 0.004499f, 0.768606f, 0.497149f, 1.642535f, 0.426962f, 1.447892f, 0.205812f, 0.813201f, 0.233428f, 1.052075f, 0.648542f, 1.852622f, 0.678437f, 1.606302f, +0.002448f, 0.006284f, 0.000043f, 0.006123f, 0.005509f, 0.020040f, 0.005571f, 0.015889f, 0.001495f, 0.006504f, 0.001996f, 0.007568f, 0.009468f, 0.029779f, 0.011662f, 0.023224f, +0.330956f, 0.924827f, 0.006252f, 0.900164f, 0.791056f, 3.132748f, 0.868116f, 2.481088f, 0.219251f, 1.038383f, 0.317753f, 1.206984f, 0.718276f, 2.459405f, 0.960132f, 1.915869f, +0.152668f, 0.534160f, 0.002115f, 0.504715f, 0.166607f, 0.826123f, 0.134074f, 0.635149f, 0.001425f, 0.008449f, 0.001514f, 0.009534f, 0.333554f, 1.430005f, 0.326954f, 1.081403f, +0.764614f, 2.454231f, 0.010704f, 2.359829f, 1.182778f, 5.380267f, 0.961959f, 4.209443f, 0.555467f, 3.021740f, 0.596610f, 3.469806f, 1.488704f, 5.855030f, 1.474790f, 4.505767f, +0.232333f, 0.821129f, 0.003830f, 0.710154f, 0.495058f, 2.479609f, 0.474097f, 1.744937f, 0.152397f, 0.912858f, 0.192738f, 0.942816f, 0.820917f, 3.555056f, 0.957589f, 2.460719f, +0.726279f, 2.794256f, 0.012992f, 2.413940f, 1.643812f, 8.962779f, 1.708335f, 6.300261f, 0.516840f, 3.370115f, 0.709342f, 3.476865f, 1.440090f, 6.788916f, 1.822969f, 4.693914f, +0.039928f, 0.276944f, 0.000960f, 0.226166f, 0.050509f, 0.496489f, 0.070547f, 0.329913f, 0.000443f, 0.005209f, 0.000817f, 0.005080f, 0.112904f, 0.959558f, 0.192084f, 0.627163f, +0.170158f, 1.082718f, 0.004134f, 0.899787f, 0.305111f, 2.751361f, 0.430695f, 1.860491f, 0.146978f, 1.585038f, 0.273995f, 1.573067f, 0.428777f, 3.343043f, 0.737247f, 2.223519f, +0.047428f, 0.332296f, 0.001357f, 0.248385f, 0.117145f, 1.163163f, 0.194713f, 0.707452f, 0.036990f, 0.439238f, 0.081196f, 0.392087f, 0.216888f, 1.861972f, 0.439113f, 1.113905f, +0.217025f, 1.655249f, 0.006738f, 1.235899f, 0.569382f, 6.154371f, 1.027032f, 3.739030f, 0.183631f, 2.373693f, 0.437426f, 2.116543f, 0.556942f, 5.204878f, 1.223656f, 3.110317f, +0.266502f, 0.838818f, 0.004288f, 0.663941f, 0.239466f, 1.068169f, 0.223874f, 0.687950f, 0.002237f, 0.011934f, 0.002762f, 0.011280f, 0.597726f, 2.305247f, 0.680660f, 1.460338f, +1.363671f, 3.937560f, 0.022178f, 3.171598f, 1.736877f, 7.107454f, 1.641080f, 4.658227f, 0.891005f, 4.360375f, 1.111783f, 4.194283f, 2.725579f, 9.643265f, 3.136811f, 6.216552f, +0.381614f, 1.213301f, 0.007308f, 0.879014f, 0.669525f, 3.016747f, 0.744880f, 1.778367f, 0.225136f, 1.213152f, 0.330783f, 1.049603f, 1.384188f, 5.392460f, 1.875784f, 3.126716f, +0.945037f, 3.270817f, 0.019639f, 2.367022f, 1.761149f, 8.638358f, 2.126300f, 5.086663f, 0.604862f, 3.548050f, 0.964414f, 3.066329f, 1.923615f, 8.157813f, 2.828887f, 4.724918f, +0.050212f, 0.091438f, 0.000748f, 0.162254f, 0.065714f, 0.169592f, 0.056845f, 0.244867f, 0.000592f, 0.001828f, 0.000677f, 0.003874f, 0.151158f, 0.337287f, 0.159272f, 0.479008f, +0.161234f, 0.269355f, 0.002426f, 0.486390f, 0.299104f, 0.708141f, 0.261494f, 1.040482f, 0.148060f, 0.419212f, 0.170945f, 0.904016f, 0.432542f, 0.885414f, 0.460614f, 1.279617f, +0.001432f, 0.002635f, 0.000025f, 0.004279f, 0.003660f, 0.009542f, 0.003768f, 0.012610f, 0.001188f, 0.003703f, 0.001615f, 0.007182f, 0.006973f, 0.015718f, 0.008744f, 0.020431f, +0.159158f, 0.318704f, 0.003060f, 0.517061f, 0.431999f, 1.225942f, 0.482602f, 1.618377f, 0.143168f, 0.485884f, 0.211219f, 0.941391f, 0.434832f, 1.066913f, 0.591694f, 1.385344f, +0.080145f, 0.200941f, 0.001130f, 0.316474f, 0.099321f, 0.352907f, 0.081363f, 0.452256f, 0.001016f, 0.004316f, 0.001099f, 0.008117f, 0.220428f, 0.677186f, 0.219950f, 0.853592f, +0.361232f, 0.830861f, 0.005148f, 1.331638f, 0.634548f, 2.068400f, 0.525357f, 2.697417f, 0.356328f, 1.389052f, 0.389600f, 2.658640f, 0.885369f, 2.495250f, 0.892858f, 3.200712f, +0.121220f, 0.307004f, 0.002034f, 0.442565f, 0.293316f, 1.052769f, 0.285946f, 1.234874f, 0.107967f, 0.463430f, 0.139000f, 0.797812f, 0.539180f, 1.673211f, 0.640251f, 1.930453f, +0.311448f, 0.858654f, 0.005671f, 1.236435f, 0.800484f, 3.127608f, 0.846856f, 3.664554f, 0.300945f, 1.406194f, 0.420458f, 2.418139f, 0.777400f, 2.626180f, 1.001775f, 3.026579f, +0.016601f, 0.082510f, 0.000406f, 0.112314f, 0.023847f, 0.167974f, 0.033906f, 0.186048f, 0.000250f, 0.002107f, 0.000470f, 0.003425f, 0.059092f, 0.359881f, 0.102340f, 0.392068f, +0.063667f, 0.290299f, 0.001575f, 0.402126f, 0.129639f, 0.837713f, 0.186288f, 0.944210f, 0.074672f, 0.577057f, 0.141706f, 0.954594f, 0.201960f, 1.128351f, 0.353494f, 1.250939f, +0.019598f, 0.098395f, 0.000571f, 0.122594f, 0.054969f, 0.391118f, 0.093010f, 0.396512f, 0.020755f, 0.176603f, 0.046377f, 0.262769f, 0.112821f, 0.694056f, 0.232522f, 0.692090f, +0.073707f, 0.402840f, 0.002330f, 0.501354f, 0.219594f, 1.700867f, 0.403216f, 1.722418f, 0.084683f, 0.784408f, 0.205348f, 1.165837f, 0.238112f, 1.594600f, 0.532559f, 1.588323f, +0.285698f, 0.644382f, 0.004680f, 0.850155f, 0.291520f, 0.931823f, 0.277437f, 1.000330f, 0.003256f, 0.012448f, 0.004093f, 0.019613f, 0.806642f, 2.229284f, 0.935073f, 2.353934f, +1.315621f, 2.722186f, 0.021781f, 3.654783f, 1.902865f, 5.579848f, 1.830228f, 6.095677f, 1.167213f, 4.093201f, 1.482608f, 6.562810f, 3.310184f, 8.392414f, 3.878093f, 9.017897f, +0.406598f, 0.926357f, 0.007926f, 1.118660f, 0.810075f, 2.615570f, 0.917447f, 2.570052f, 0.325712f, 1.257690f, 0.487157f, 1.813746f, 1.856554f, 5.182854f, 2.561132f, 5.009141f, +0.827578f, 2.052513f, 0.017507f, 2.475853f, 1.751354f, 6.155715f, 2.152480f, 6.041895f, 0.719225f, 3.023207f, 1.167371f, 4.355017f, 2.120561f, 6.444296f, 3.174567f, 6.221413f, +0.139911f, 0.341383f, 0.002346f, 0.483915f, 0.190388f, 0.658348f, 0.185462f, 0.759343f, 0.001271f, 0.005256f, 0.001635f, 0.008897f, 0.301080f, 0.900159f, 0.357246f, 1.021222f, +0.348811f, 0.780782f, 0.005911f, 1.126280f, 0.672808f, 2.134313f, 0.662383f, 2.505130f, 0.246637f, 0.935670f, 0.320667f, 1.611840f, 0.668909f, 1.834654f, 0.802147f, 2.118093f, +0.002966f, 0.007310f, 0.000059f, 0.009485f, 0.007880f, 0.027526f, 0.009135f, 0.029060f, 0.001894f, 0.007910f, 0.002899f, 0.012256f, 0.010322f, 0.031173f, 0.014575f, 0.032370f, +0.364684f, 0.978467f, 0.007897f, 1.268113f, 1.029214f, 3.913475f, 1.294767f, 4.126955f, 0.252592f, 1.148618f, 0.419648f, 1.777748f, 0.712220f, 2.341483f, 1.091361f, 2.428718f, +0.294383f, 0.988949f, 0.004674f, 1.244227f, 0.379324f, 1.805922f, 0.349927f, 1.848760f, 0.002873f, 0.016355f, 0.003500f, 0.024573f, 0.578770f, 2.382406f, 0.650342f, 2.398921f, +1.030172f, 3.174834f, 0.016532f, 4.064776f, 1.881577f, 8.217902f, 1.754245f, 8.561150f, 0.782452f, 4.086911f, 0.963396f, 6.248757f, 1.804890f, 6.815694f, 2.049689f, 6.983933f, +0.330888f, 1.122844f, 0.006252f, 1.293037f, 0.832486f, 4.003525f, 0.913910f, 3.751368f, 0.226924f, 1.305099f, 0.328992f, 1.794807f, 1.052068f, 4.374513f, 1.406822f, 4.031770f, +0.940727f, 3.475084f, 0.019291f, 3.997385f, 2.513993f, 13.161130f, 2.995024f, 12.318550f, 0.699920f, 4.382039f, 1.101193f, 6.019630f, 1.678516f, 7.597572f, 2.435737f, 6.994553f, +0.059901f, 0.398917f, 0.001651f, 0.433778f, 0.089469f, 0.844405f, 0.143251f, 0.747123f, 0.000695f, 0.007844f, 0.001470f, 0.010186f, 0.152419f, 1.243761f, 0.297258f, 1.082422f, +0.178364f, 1.089703f, 0.004968f, 1.205822f, 0.377627f, 3.269581f, 0.611070f, 2.943897f, 0.161079f, 1.667882f, 0.344227f, 2.204058f, 0.404447f, 3.027683f, 0.797183f, 2.681389f, +0.052552f, 0.353525f, 0.001724f, 0.351861f, 0.153261f, 1.461125f, 0.292024f, 1.183298f, 0.042852f, 0.488571f, 0.107830f, 0.580712f, 0.216256f, 1.782559f, 0.501907f, 1.419938f, +0.218705f, 1.601584f, 0.007784f, 1.592281f, 0.677490f, 7.031073f, 1.400872f, 5.687840f, 0.193476f, 2.401284f, 0.528324f, 2.850995f, 0.505049f, 4.531817f, 1.272031f, 3.605927f, +0.476377f, 1.439649f, 0.008788f, 1.517289f, 0.505413f, 2.164613f, 0.541653f, 1.856298f, 0.004181f, 0.021414f, 0.005917f, 0.026952f, 0.961452f, 3.560260f, 1.255079f, 3.003087f, +1.703188f, 4.721922f, 0.031753f, 5.064309f, 2.561377f, 10.063690f, 2.774275f, 8.782419f, 1.163498f, 5.466984f, 1.664258f, 7.002162f, 3.063283f, 10.406170f, 4.041401f, 8.932374f, +0.503825f, 1.538022f, 0.011060f, 1.483679f, 1.043696f, 4.515275f, 1.331093f, 3.544192f, 0.310766f, 1.607835f, 0.523415f, 1.852260f, 1.644469f, 6.151148f, 2.554634f, 4.749064f, +1.134737f, 3.770868f, 0.027032f, 3.633606f, 2.496859f, 11.758930f, 3.455714f, 9.219766f, 0.759338f, 4.276684f, 1.387898f, 4.921376f, 2.078452f, 8.463190f, 3.503908f, 6.526872f, +0.080934f, 0.144832f, 0.000880f, 0.206498f, 0.097667f, 0.247690f, 0.061723f, 0.287353f, 0.000711f, 0.002155f, 0.000593f, 0.003670f, 0.242442f, 0.531603f, 0.186627f, 0.606615f, +0.114702f, 0.188301f, 0.001261f, 0.273208f, 0.196201f, 0.456468f, 0.125314f, 0.538898f, 0.078391f, 0.218110f, 0.066122f, 0.377919f, 0.306191f, 0.615917f, 0.238210f, 0.715217f, +0.001175f, 0.002124f, 0.000015f, 0.002772f, 0.002769f, 0.007093f, 0.002082f, 0.007532f, 0.000725f, 0.002222f, 0.000720f, 0.003462f, 0.005693f, 0.012609f, 0.005215f, 0.013169f, +0.157937f, 0.310783f, 0.002219f, 0.405128f, 0.395278f, 1.102306f, 0.322604f, 1.169214f, 0.105735f, 0.352627f, 0.113963f, 0.548952f, 0.429366f, 1.035254f, 0.426838f, 1.080083f, +0.078451f, 0.193287f, 0.000808f, 0.244598f, 0.089645f, 0.313009f, 0.053650f, 0.322302f, 0.000740f, 0.003090f, 0.000585f, 0.004669f, 0.214702f, 0.648170f, 0.156514f, 0.656469f, +0.156061f, 0.352735f, 0.001625f, 0.454243f, 0.252776f, 0.809688f, 0.152892f, 0.848425f, 0.114570f, 0.438886f, 0.091517f, 0.674955f, 0.380611f, 1.054103f, 0.280414f, 1.086419f, +0.060394f, 0.150304f, 0.000740f, 0.174095f, 0.134746f, 0.475252f, 0.095967f, 0.447915f, 0.040033f, 0.168859f, 0.037653f, 0.233574f, 0.267300f, 0.815131f, 0.231886f, 0.755645f, +0.187688f, 0.508488f, 0.002497f, 0.588323f, 0.444801f, 1.707803f, 0.343782f, 1.607787f, 0.134974f, 0.619756f, 0.137767f, 0.856325f, 0.466169f, 1.547517f, 0.438864f, 1.432996f, +0.000721f, 0.003523f, 0.000013f, 0.003853f, 0.000955f, 0.006613f, 0.000992f, 0.005885f, 0.000008f, 0.000067f, 0.000011f, 0.000087f, 0.002555f, 0.015290f, 0.003232f, 0.013384f, +0.001221f, 0.005471f, 0.000022f, 0.006089f, 0.002292f, 0.014556f, 0.002406f, 0.013182f, 0.001066f, 0.008093f, 0.001478f, 0.010757f, 0.003854f, 0.021158f, 0.004928f, 0.018847f, +0.000433f, 0.002138f, 0.000009f, 0.002141f, 0.001121f, 0.007837f, 0.001386f, 0.006384f, 0.000342f, 0.002856f, 0.000558f, 0.003415f, 0.002483f, 0.015008f, 0.003738f, 0.012025f, +0.001972f, 0.010589f, 0.000046f, 0.010589f, 0.005416f, 0.041225f, 0.007266f, 0.033543f, 0.001686f, 0.015345f, 0.002987f, 0.018326f, 0.006338f, 0.041708f, 0.010356f, 0.033381f, +0.209801f, 0.465004f, 0.002511f, 0.492938f, 0.197393f, 0.620025f, 0.137242f, 0.534812f, 0.001780f, 0.006685f, 0.001634f, 0.008463f, 0.589427f, 1.600761f, 0.499177f, 1.358117f, +0.426402f, 0.866997f, 0.005157f, 0.935284f, 0.568668f, 1.638647f, 0.399592f, 1.438357f, 0.281547f, 0.970233f, 0.261269f, 1.249927f, 1.067552f, 2.659717f, 0.913724f, 2.296337f, +0.151971f, 0.340241f, 0.002164f, 0.330132f, 0.279180f, 0.885803f, 0.230993f, 0.699350f, 0.090603f, 0.343791f, 0.099001f, 0.398363f, 0.690481f, 1.894197f, 0.695883f, 1.470962f, +0.374144f, 0.911860f, 0.005782f, 0.883790f, 0.730075f, 2.521643f, 0.655530f, 1.988658f, 0.241996f, 0.999593f, 0.286954f, 1.156983f, 0.953958f, 2.848827f, 1.043334f, 2.209843f, +0.081931f, 0.208209f, 0.001198f, 0.221655f, 0.084321f, 0.303678f, 0.071653f, 0.263055f, 0.000721f, 0.003106f, 0.000809f, 0.003948f, 0.214187f, 0.666946f, 0.221698f, 0.568253f, +0.176777f, 0.412123f, 0.002613f, 0.446470f, 0.257885f, 0.852030f, 0.221477f, 0.751063f, 0.121103f, 0.478501f, 0.137353f, 0.619058f, 0.411828f, 1.176425f, 0.430812f, 1.020011f, +0.001834f, 0.004707f, 0.000032f, 0.004587f, 0.003685f, 0.013405f, 0.003726f, 0.010628f, 0.001134f, 0.004935f, 0.001515f, 0.005742f, 0.007752f, 0.024384f, 0.009549f, 0.019016f, +0.231421f, 0.646685f, 0.004371f, 0.629440f, 0.493959f, 1.956182f, 0.542078f, 1.549266f, 0.155299f, 0.735505f, 0.225070f, 0.854929f, 0.549051f, 1.879972f, 0.733926f, 1.464492f, +0.133068f, 0.465583f, 0.001843f, 0.439919f, 0.129680f, 0.643017f, 0.104358f, 0.494372f, 0.001258f, 0.007460f, 0.001337f, 0.008418f, 0.317820f, 1.362551f, 0.311532f, 1.030393f, +0.403005f, 1.293549f, 0.005642f, 1.243793f, 0.556701f, 2.532344f, 0.452768f, 1.981269f, 0.296566f, 1.613320f, 0.318532f, 1.852544f, 0.857758f, 3.373537f, 0.849741f, 2.596122f, +0.157904f, 0.558075f, 0.002603f, 0.482652f, 0.300461f, 1.504929f, 0.287740f, 1.059041f, 0.104919f, 0.628464f, 0.132692f, 0.649089f, 0.609915f, 2.641294f, 0.711458f, 1.828236f, +0.460802f, 1.772872f, 0.008243f, 1.531572f, 0.931354f, 5.078146f, 0.967911f, 3.569612f, 0.332172f, 2.165966f, 0.455892f, 2.234574f, 0.998825f, 4.708693f, 1.264385f, 3.255630f, +0.043161f, 0.299370f, 0.001038f, 0.244480f, 0.048757f, 0.479266f, 0.068100f, 0.318469f, 0.000485f, 0.005703f, 0.000895f, 0.005562f, 0.133418f, 1.133904f, 0.226984f, 0.741115f, +0.111227f, 0.707738f, 0.002703f, 0.588162f, 0.178101f, 1.606040f, 0.251408f, 1.086016f, 0.097321f, 1.049525f, 0.181424f, 1.041598f, 0.306392f, 2.388846f, 0.526816f, 1.588866f, +0.039977f, 0.280089f, 0.001144f, 0.209362f, 0.088175f, 0.875514f, 0.146561f, 0.532500f, 0.031583f, 0.375030f, 0.069327f, 0.334773f, 0.199846f, 1.715668f, 0.404609f, 1.026380f, +0.170770f, 1.302459f, 0.005302f, 0.972487f, 0.400088f, 4.324500f, 0.721666f, 2.627309f, 0.146367f, 1.892001f, 0.348660f, 1.687034f, 0.479071f, 4.477136f, 1.052565f, 2.675435f, +0.205343f, 0.646320f, 0.003304f, 0.511574f, 0.164769f, 0.734972f, 0.154041f, 0.473356f, 0.001746f, 0.009314f, 0.002156f, 0.008804f, 0.503466f, 1.941717f, 0.573322f, 1.230047f, +0.635375f, 1.834627f, 0.010333f, 1.477743f, 0.722672f, 2.957237f, 0.682813f, 1.938174f, 0.420530f, 2.057976f, 0.524731f, 1.979585f, 1.388252f, 4.911721f, 1.597710f, 3.166351f, +0.229276f, 0.728959f, 0.004391f, 0.528117f, 0.359214f, 1.618545f, 0.399643f, 0.954130f, 0.137017f, 0.738322f, 0.201314f, 0.638786f, 0.909114f, 3.541689f, 1.231987f, 2.053581f, +0.530045f, 1.834512f, 0.011015f, 1.327598f, 0.882087f, 4.326601f, 1.064977f, 2.547702f, 0.343650f, 2.015811f, 0.547928f, 1.742123f, 1.179428f, 5.001806f, 1.734478f, 2.896993f, +0.001478f, 0.002692f, 0.000022f, 0.004777f, 0.001728f, 0.004459f, 0.001495f, 0.006438f, 0.000018f, 0.000055f, 0.000020f, 0.000116f, 0.004865f, 0.010856f, 0.005126f, 0.015417f, +0.002871f, 0.004795f, 0.000043f, 0.008659f, 0.004755f, 0.011258f, 0.004157f, 0.016542f, 0.002670f, 0.007560f, 0.003083f, 0.016303f, 0.008418f, 0.017232f, 0.008965f, 0.024904f, +0.000033f, 0.000060f, 0.000001f, 0.000098f, 0.000075f, 0.000196f, 0.000077f, 0.000259f, 0.000028f, 0.000086f, 0.000038f, 0.000167f, 0.000175f, 0.000394f, 0.000219f, 0.000513f, +0.003411f, 0.006830f, 0.000066f, 0.011081f, 0.008268f, 0.023462f, 0.009236f, 0.030973f, 0.003108f, 0.010548f, 0.004585f, 0.020437f, 0.010187f, 0.024996f, 0.013862f, 0.032456f, +0.002141f, 0.005368f, 0.000030f, 0.008454f, 0.002369f, 0.008419f, 0.001941f, 0.010789f, 0.000027f, 0.000117f, 0.000030f, 0.000220f, 0.006437f, 0.019776f, 0.006423f, 0.024928f, +0.005835f, 0.013422f, 0.000083f, 0.021512f, 0.009154f, 0.029838f, 0.007579f, 0.038912f, 0.005831f, 0.022730f, 0.006375f, 0.043505f, 0.015635f, 0.044064f, 0.015767f, 0.056522f, +0.002525f, 0.006395f, 0.000042f, 0.009219f, 0.005456f, 0.019583f, 0.005319f, 0.022971f, 0.002278f, 0.009779f, 0.002933f, 0.016834f, 0.012278f, 0.038101f, 0.014579f, 0.043959f, +0.006056f, 0.016697f, 0.000110f, 0.024044f, 0.013901f, 0.054312f, 0.014706f, 0.063636f, 0.005928f, 0.027699f, 0.008282f, 0.047633f, 0.016526f, 0.055827f, 0.021295f, 0.064338f, +0.000550f, 0.002734f, 0.000013f, 0.003721f, 0.000706f, 0.004970f, 0.001003f, 0.005504f, 0.000008f, 0.000071f, 0.000016f, 0.000115f, 0.002140f, 0.013034f, 0.003707f, 0.014200f, +0.001276f, 0.005816f, 0.000032f, 0.008056f, 0.002319f, 0.014987f, 0.003333f, 0.016893f, 0.001515f, 0.011711f, 0.002876f, 0.019373f, 0.004423f, 0.024712f, 0.007742f, 0.027397f, +0.000506f, 0.002542f, 0.000015f, 0.003167f, 0.001268f, 0.009023f, 0.002146f, 0.009147f, 0.000543f, 0.004621f, 0.001214f, 0.006876f, 0.003186f, 0.019601f, 0.006567f, 0.019545f, +0.001778f, 0.009715f, 0.000056f, 0.012091f, 0.004729f, 0.036630f, 0.008684f, 0.037094f, 0.002069f, 0.019163f, 0.005017f, 0.028481f, 0.006278f, 0.042040f, 0.014040f, 0.041874f, +0.006747f, 0.015217f, 0.000111f, 0.020077f, 0.006148f, 0.019651f, 0.005851f, 0.021096f, 0.000078f, 0.000298f, 0.000098f, 0.000469f, 0.020824f, 0.057551f, 0.024140f, 0.060769f, +0.018787f, 0.038874f, 0.000311f, 0.052192f, 0.024266f, 0.071156f, 0.023340f, 0.077734f, 0.016884f, 0.059210f, 0.021447f, 0.094934f, 0.051675f, 0.131013f, 0.060540f, 0.140777f, +0.007487f, 0.017058f, 0.000146f, 0.020599f, 0.013321f, 0.043010f, 0.015086f, 0.042262f, 0.006076f, 0.023460f, 0.009087f, 0.033832f, 0.037372f, 0.104330f, 0.051555f, 0.100833f, +0.014226f, 0.035283f, 0.000301f, 0.042560f, 0.026885f, 0.094496f, 0.033042f, 0.092748f, 0.012524f, 0.052644f, 0.020328f, 0.075835f, 0.039849f, 0.121100f, 0.059656f, 0.116912f, +0.177968f, 0.434240f, 0.002984f, 0.615541f, 0.216261f, 0.747817f, 0.210666f, 0.862537f, 0.001638f, 0.006772f, 0.002107f, 0.011464f, 0.418658f, 1.251688f, 0.496757f, 1.420029f, +0.268300f, 0.600564f, 0.004547f, 0.866314f, 0.462139f, 1.466016f, 0.454978f, 1.720723f, 0.192169f, 0.729034f, 0.249850f, 1.255877f, 0.562452f, 1.542668f, 0.674485f, 1.780997f, +0.002942f, 0.007251f, 0.000059f, 0.009407f, 0.006980f, 0.024380f, 0.008091f, 0.025739f, 0.001903f, 0.007947f, 0.002913f, 0.012314f, 0.011192f, 0.033800f, 0.015803f, 0.035098f, +0.337668f, 0.905981f, 0.007312f, 1.174169f, 0.851001f, 3.235838f, 1.070572f, 3.412353f, 0.236913f, 1.077319f, 0.393599f, 1.667396f, 0.720901f, 2.370024f, 1.104664f, 2.458322f, +0.339765f, 1.141408f, 0.005395f, 1.436041f, 0.390956f, 1.861304f, 0.360658f, 1.905456f, 0.003358f, 0.019121f, 0.004091f, 0.028729f, 0.730234f, 3.005879f, 0.820536f, 3.026717f, +0.718981f, 2.215792f, 0.011538f, 2.836903f, 1.172685f, 5.121773f, 1.093326f, 5.335701f, 0.553174f, 2.889342f, 0.681097f, 4.417712f, 1.377043f, 5.200043f, 1.563813f, 5.328401f, +0.297785f, 1.010511f, 0.005627f, 1.163678f, 0.669037f, 3.217480f, 0.734475f, 3.014831f, 0.206870f, 1.189765f, 0.299918f, 1.636197f, 1.035034f, 4.303685f, 1.384044f, 3.966491f, +0.790342f, 2.919556f, 0.016207f, 3.358362f, 1.886110f, 9.874069f, 2.247001f, 9.241925f, 0.595657f, 3.729268f, 0.937154f, 5.122915f, 1.541579f, 6.977747f, 2.237025f, 6.423924f, +0.085741f, 0.571003f, 0.002363f, 0.620903f, 0.114362f, 1.079342f, 0.183108f, 0.954993f, 0.001008f, 0.011374f, 0.002131f, 0.014770f, 0.238497f, 1.946177f, 0.465134f, 1.693722f, +0.154385f, 0.943205f, 0.004300f, 1.043713f, 0.291886f, 2.527209f, 0.472324f, 2.275474f, 0.141232f, 1.462375f, 0.301813f, 1.932487f, 0.382691f, 2.864818f, 0.754301f, 2.537152f, +0.058655f, 0.394577f, 0.001924f, 0.392720f, 0.152755f, 1.456299f, 0.291059f, 1.179389f, 0.048449f, 0.552376f, 0.121912f, 0.656551f, 0.263857f, 2.174926f, 0.612384f, 1.732486f, +0.227877f, 1.668750f, 0.008110f, 1.659057f, 0.630370f, 6.542058f, 1.303440f, 5.292247f, 0.204204f, 2.534432f, 0.557619f, 3.009079f, 0.575259f, 5.161817f, 1.448865f, 4.107212f, +0.486038f, 1.468848f, 0.008966f, 1.548063f, 0.460487f, 1.972204f, 0.493506f, 1.691294f, 0.004321f, 0.022131f, 0.006115f, 0.027855f, 1.072350f, 3.970915f, 1.399845f, 3.349476f, +1.050809f, 2.913265f, 0.019590f, 3.124506f, 1.411192f, 5.544592f, 1.528488f, 4.838677f, 0.727148f, 3.416684f, 1.040106f, 4.376118f, 2.066032f, 7.018447f, 2.725724f, 6.024443f, +0.400825f, 1.223595f, 0.008799f, 1.180361f, 0.741482f, 3.207824f, 0.945659f, 2.517930f, 0.250440f, 1.295724f, 0.421810f, 1.492701f, 1.430176f, 5.349585f, 2.221737f, 4.130208f, +0.842752f, 2.800567f, 0.020077f, 2.698625f, 1.655961f, 7.798727f, 2.291891f, 6.114711f, 0.571262f, 3.217419f, 1.044139f, 3.702432f, 1.687460f, 6.871121f, 2.844764f, 5.299058f, +0.170010f, 0.304233f, 0.001849f, 0.433767f, 0.279100f, 0.707814f, 0.176383f, 0.821156f, 0.001575f, 0.004777f, 0.001315f, 0.008134f, 0.453261f, 0.993866f, 0.348911f, 1.134106f, +0.197772f, 0.324673f, 0.002174f, 0.471072f, 0.460220f, 1.070716f, 0.293944f, 1.264069f, 0.142624f, 0.396826f, 0.120301f, 0.687581f, 0.469880f, 0.945183f, 0.365557f, 1.097568f, +0.001755f, 0.003173f, 0.000023f, 0.004140f, 0.005626f, 0.014412f, 0.004231f, 0.015304f, 0.001143f, 0.003501f, 0.001135f, 0.005457f, 0.007568f, 0.016762f, 0.006932f, 0.017507f, +0.279774f, 0.550527f, 0.003930f, 0.717654f, 0.952567f, 2.656409f, 0.777432f, 2.817646f, 0.197638f, 0.659127f, 0.213018f, 1.026096f, 0.676939f, 1.632184f, 0.672954f, 1.702862f, +0.189163f, 0.466059f, 0.001949f, 0.589782f, 0.294059f, 1.026753f, 0.175988f, 1.057235f, 0.001883f, 0.007861f, 0.001488f, 0.011880f, 0.460761f, 1.391003f, 0.335887f, 1.408811f, +0.308878f, 0.698138f, 0.003216f, 0.899044f, 0.680611f, 2.180121f, 0.411669f, 2.284421f, 0.239274f, 0.916592f, 0.191128f, 1.409610f, 0.670461f, 1.856843f, 0.493960f, 1.913769f, +0.103545f, 0.257697f, 0.001269f, 0.298487f, 0.314286f, 1.108493f, 0.223837f, 1.044731f, 0.072425f, 0.305489f, 0.068120f, 0.422565f, 0.407884f, 1.243843f, 0.353846f, 1.153071f, +0.381643f, 1.033954f, 0.005077f, 1.196290f, 1.230431f, 4.724207f, 0.950987f, 4.447537f, 0.289603f, 1.329760f, 0.295596f, 1.837347f, 0.843653f, 2.800632f, 0.794237f, 2.593377f, +0.001258f, 0.006144f, 0.000022f, 0.006720f, 0.002267f, 0.015691f, 0.002355f, 0.013964f, 0.000015f, 0.000123f, 0.000020f, 0.000161f, 0.003966f, 0.023734f, 0.005018f, 0.020776f, +0.001748f, 0.007832f, 0.000032f, 0.008717f, 0.004464f, 0.028349f, 0.004687f, 0.025674f, 0.001610f, 0.012226f, 0.002232f, 0.016250f, 0.004910f, 0.026959f, 0.006279f, 0.024015f, +0.000537f, 0.002652f, 0.000011f, 0.002655f, 0.001891f, 0.013222f, 0.002338f, 0.010770f, 0.000447f, 0.003738f, 0.000730f, 0.004468f, 0.002740f, 0.016565f, 0.004126f, 0.013273f, +0.002900f, 0.015574f, 0.000067f, 0.015574f, 0.010837f, 0.082486f, 0.014538f, 0.067117f, 0.002616f, 0.023816f, 0.004635f, 0.028441f, 0.008297f, 0.054598f, 0.013556f, 0.043697f, +0.492533f, 1.091653f, 0.005894f, 1.157232f, 0.630422f, 1.980194f, 0.438316f, 1.708046f, 0.004409f, 0.016561f, 0.004048f, 0.020965f, 1.231567f, 3.344681f, 1.042996f, 2.837692f, +0.821676f, 1.670704f, 0.009938f, 1.802292f, 1.490772f, 4.295734f, 1.047535f, 3.770672f, 0.572486f, 1.972829f, 0.531252f, 2.541547f, 1.830924f, 4.561597f, 1.567099f, 3.938375f, +0.253681f, 0.567955f, 0.003613f, 0.551081f, 0.633990f, 2.011570f, 0.524563f, 1.588154f, 0.159589f, 0.605555f, 0.174380f, 0.701679f, 1.025840f, 2.814186f, 1.033865f, 2.185390f, +0.740712f, 1.805253f, 0.011448f, 1.749681f, 1.966291f, 6.791474f, 1.765521f, 5.356000f, 0.505534f, 2.088165f, 0.599451f, 2.416955f, 1.680890f, 5.019680f, 1.838372f, 3.893780f, +0.238754f, 0.606738f, 0.003492f, 0.645918f, 0.334277f, 1.203884f, 0.284058f, 1.042838f, 0.002217f, 0.009550f, 0.002488f, 0.012141f, 0.555511f, 1.729782f, 0.574994f, 1.473812f, +0.422844f, 0.985781f, 0.006251f, 1.067939f, 0.839172f, 2.772549f, 0.720699f, 2.443998f, 0.305662f, 1.207726f, 0.346676f, 1.562490f, 0.876738f, 2.504484f, 0.917152f, 2.171495f, +0.003799f, 0.009753f, 0.000066f, 0.009504f, 0.010387f, 0.037786f, 0.010503f, 0.029959f, 0.002480f, 0.010789f, 0.003312f, 0.012555f, 0.014296f, 0.044968f, 0.017610f, 0.035069f, +0.568702f, 1.589189f, 0.010742f, 1.546809f, 1.651368f, 6.539765f, 1.812234f, 5.179393f, 0.402701f, 1.907217f, 0.583623f, 2.216889f, 1.200868f, 4.111816f, 1.605220f, 3.203091f, +0.445116f, 1.557387f, 0.006166f, 1.471540f, 0.590121f, 2.926120f, 0.474890f, 2.249693f, 0.004440f, 0.026331f, 0.004719f, 0.029712f, 0.946195f, 4.056503f, 0.927473f, 3.067621f, +1.106528f, 3.551694f, 0.015490f, 3.415077f, 2.079435f, 9.459011f, 1.691213f, 7.400592f, 0.859223f, 4.674173f, 0.922864f, 5.367262f, 2.096125f, 8.243999f, 2.076534f, 6.344209f, +0.375571f, 1.327368f, 0.006191f, 1.147975f, 0.972205f, 4.869507f, 0.931042f, 3.426744f, 0.263321f, 1.577287f, 0.333024f, 1.629051f, 1.291124f, 5.591332f, 1.506080f, 3.870177f, +1.299856f, 5.001016f, 0.023252f, 4.320346f, 3.574094f, 19.487520f, 3.714385f, 13.698480f, 0.988725f, 6.447099f, 1.356985f, 6.651314f, 2.507670f, 11.821740f, 3.174388f, 8.173648f, +0.104430f, 0.724336f, 0.002511f, 0.591528f, 0.160487f, 1.577537f, 0.224156f, 1.048263f, 0.001239f, 0.014561f, 0.002285f, 0.014201f, 0.287308f, 2.441791f, 0.488796f, 1.595944f, +0.220900f, 1.405589f, 0.005367f, 1.168107f, 0.481196f, 4.339227f, 0.679258f, 2.934219f, 0.203949f, 2.199431f, 0.380201f, 2.182819f, 0.541581f, 4.222540f, 0.931204f, 2.808489f, +0.068776f, 0.481868f, 0.001968f, 0.360187f, 0.206371f, 2.049111f, 0.343020f, 1.246297f, 0.057334f, 0.680817f, 0.125853f, 0.607734f, 0.306005f, 2.627029f, 0.619537f, 1.571592f, +0.348438f, 2.657531f, 0.010818f, 1.984257f, 1.110555f, 12.003850f, 2.003183f, 7.292824f, 0.315129f, 4.073494f, 0.750668f, 3.632199f, 0.869989f, 8.130445f, 1.911450f, 4.858570f, +0.668757f, 2.104921f, 0.010761f, 1.666085f, 0.730020f, 3.256340f, 0.682486f, 2.097233f, 0.006000f, 0.032009f, 0.007408f, 0.030256f, 1.459347f, 5.628262f, 1.661832f, 3.565415f, +1.698526f, 4.904443f, 0.027623f, 3.950396f, 2.628169f, 10.754700f, 2.483214f, 7.048634f, 1.186234f, 5.805155f, 1.480164f, 5.584030f, 3.303011f, 11.686260f, 3.801365f, 7.533570f, +0.530942f, 1.688073f, 0.010167f, 1.222976f, 1.131648f, 5.098977f, 1.259014f, 3.005839f, 0.334807f, 1.804119f, 0.491918f, 1.560900f, 1.873726f, 7.299585f, 2.539183f, 4.232526f, +1.455738f, 5.038378f, 0.030252f, 3.646170f, 3.295735f, 16.165440f, 3.979064f, 9.518954f, 0.995905f, 5.841868f, 1.587909f, 5.048714f, 2.882979f, 12.226350f, 4.239737f, 7.081374f, +0.117076f, 0.213201f, 0.001743f, 0.378319f, 0.186141f, 0.480386f, 0.161020f, 0.693610f, 0.001476f, 0.004557f, 0.001687f, 0.009656f, 0.342913f, 0.765159f, 0.361318f, 1.086664f, +0.186601f, 0.311733f, 0.002808f, 0.562914f, 0.420535f, 0.995634f, 0.367656f, 1.462899f, 0.183157f, 0.518585f, 0.211467f, 1.118308f, 0.487052f, 0.996996f, 0.518661f, 1.440876f, +0.001852f, 0.003406f, 0.000033f, 0.005532f, 0.005748f, 0.014985f, 0.005918f, 0.019804f, 0.001641f, 0.005116f, 0.002231f, 0.009924f, 0.008771f, 0.019770f, 0.010998f, 0.025698f, +0.227802f, 0.456160f, 0.004380f, 0.740067f, 0.751163f, 2.131678f, 0.839153f, 2.814047f, 0.219030f, 0.743345f, 0.323140f, 1.440215f, 0.605536f, 1.485757f, 0.823978f, 1.929195f, +0.194633f, 0.487989f, 0.002744f, 0.768560f, 0.293024f, 1.041173f, 0.240044f, 1.334280f, 0.002636f, 0.011203f, 0.002852f, 0.021071f, 0.520831f, 1.600063f, 0.519701f, 2.016879f, +0.435433f, 1.001529f, 0.006205f, 1.605171f, 0.929227f, 3.028945f, 0.769327f, 3.950072f, 0.459106f, 1.789705f, 0.501974f, 3.425486f, 1.038360f, 2.926429f, 1.047144f, 3.753795f, +0.163219f, 0.413370f, 0.002739f, 0.595899f, 0.479793f, 1.722066f, 0.467736f, 2.019945f, 0.155386f, 0.666970f, 0.200050f, 1.148215f, 0.706347f, 2.191970f, 0.838754f, 2.528966f, +0.464294f, 1.280045f, 0.008455f, 1.843225f, 1.449711f, 5.664235f, 1.533694f, 6.636667f, 0.479536f, 2.240680f, 0.669974f, 3.853150f, 1.127561f, 3.809082f, 1.453002f, 4.389833f, +0.036165f, 0.179751f, 0.000885f, 0.244680f, 0.063113f, 0.444557f, 0.089736f, 0.492392f, 0.000582f, 0.004907f, 0.001094f, 0.007976f, 0.125251f, 0.762800f, 0.216919f, 0.831023f, +0.068845f, 0.313909f, 0.001703f, 0.434831f, 0.170300f, 1.100462f, 0.244717f, 1.240362f, 0.086307f, 0.666967f, 0.163785f, 1.103327f, 0.212477f, 1.187110f, 0.371903f, 1.316082f, +0.023672f, 0.118848f, 0.000689f, 0.148076f, 0.080661f, 0.573915f, 0.136480f, 0.581831f, 0.026795f, 0.228004f, 0.059875f, 0.339250f, 0.132585f, 0.815646f, 0.273257f, 0.813335f, +0.098569f, 0.538719f, 0.003115f, 0.670463f, 0.356757f, 2.763264f, 0.655073f, 2.798276f, 0.121046f, 1.121243f, 0.293527f, 1.666462f, 0.309814f, 2.074773f, 0.692925f, 2.066606f, +0.597159f, 1.346873f, 0.009782f, 1.776974f, 0.740242f, 2.366129f, 0.704482f, 2.540085f, 0.007275f, 0.027810f, 0.009144f, 0.043817f, 1.640410f, 4.533539f, 1.901591f, 4.787029f, +1.364924f, 2.824199f, 0.022597f, 3.791746f, 2.398321f, 7.032695f, 2.306772f, 7.682831f, 1.294361f, 4.539084f, 1.644112f, 7.277714f, 3.341324f, 8.471362f, 3.914574f, 9.102728f, +0.471197f, 1.073535f, 0.009185f, 1.296391f, 1.140472f, 3.682356f, 1.291636f, 3.618272f, 0.403459f, 1.557897f, 0.603439f, 2.246682f, 2.093312f, 5.843799f, 2.887741f, 5.647934f, +1.061839f, 2.633513f, 0.022463f, 3.176687f, 2.729892f, 9.595109f, 3.355138f, 9.417694f, 0.986375f, 4.146150f, 1.600980f, 5.972649f, 2.647214f, 8.044773f, 3.962989f, 7.766535f, +0.422173f, 1.030100f, 0.007079f, 1.460180f, 0.697908f, 2.413320f, 0.679852f, 2.783539f, 0.004099f, 0.016951f, 0.005273f, 0.028696f, 0.883910f, 2.642684f, 1.048802f, 2.998103f, +0.522424f, 1.169397f, 0.008853f, 1.686857f, 1.224180f, 3.883399f, 1.205211f, 4.558102f, 0.394836f, 1.497897f, 0.513350f, 2.580367f, 0.974738f, 2.673468f, 1.168893f, 3.086497f, +0.004962f, 0.012230f, 0.000099f, 0.015868f, 0.016016f, 0.055945f, 0.018567f, 0.059062f, 0.003386f, 0.014145f, 0.005184f, 0.021917f, 0.016802f, 0.050741f, 0.023724f, 0.052690f, +0.675493f, 1.812384f, 0.014627f, 2.348885f, 2.315963f, 8.806197f, 2.913515f, 9.286575f, 0.500094f, 2.274088f, 0.830838f, 3.519668f, 1.283532f, 4.219722f, 1.966805f, 4.376933f, +0.925182f, 3.108055f, 0.014691f, 3.910340f, 1.448260f, 6.895022f, 1.336022f, 7.058577f, 0.009650f, 0.054941f, 0.011756f, 0.082548f, 1.769741f, 7.284826f, 1.988591f, 7.335328f, +1.607011f, 4.952567f, 0.025789f, 6.340826f, 3.565767f, 15.573710f, 3.324462f, 16.224200f, 1.304652f, 6.814469f, 1.606356f, 10.419100f, 2.739358f, 10.344470f, 3.110899f, 10.599810f, +0.576568f, 1.956539f, 0.010895f, 2.253098f, 1.762252f, 8.474880f, 1.934615f, 7.941101f, 0.422645f, 2.430750f, 0.612748f, 3.342832f, 1.783618f, 7.416307f, 2.385048f, 6.835239f, +1.814868f, 6.704194f, 0.037216f, 7.711826f, 5.892060f, 30.845820f, 7.019453f, 28.871050f, 1.443303f, 9.036182f, 2.270766f, 12.413050f, 3.150616f, 14.260830f, 4.571938f, 13.128950f, +0.168876f, 1.124656f, 0.004654f, 1.222939f, 0.306430f, 2.892081f, 0.490634f, 2.558889f, 0.002094f, 0.023638f, 0.004428f, 0.030696f, 0.418084f, 3.411640f, 0.815379f, 2.969087f, +0.249597f, 1.524897f, 0.006952f, 1.687390f, 0.641974f, 5.558352f, 1.038832f, 5.004683f, 0.240934f, 2.494738f, 0.514878f, 3.296725f, 0.550659f, 4.122221f, 1.085373f, 3.650738f, +0.082146f, 0.552602f, 0.002694f, 0.550001f, 0.291036f, 2.774607f, 0.554539f, 2.247026f, 0.071597f, 0.816295f, 0.180160f, 0.970244f, 0.328889f, 2.710971f, 0.763316f, 2.159485f, +0.378497f, 2.771750f, 0.013471f, 2.755650f, 1.424390f, 14.782490f, 2.945265f, 11.958410f, 0.357897f, 4.441966f, 0.977310f, 5.273855f, 0.850406f, 7.630716f, 2.141858f, 6.071694f, +1.288569f, 3.894161f, 0.023770f, 4.104172f, 1.660831f, 7.113105f, 1.779919f, 6.099955f, 0.012088f, 0.061912f, 0.017108f, 0.077924f, 2.530308f, 9.369741f, 3.303064f, 7.903397f, +2.286727f, 6.339726f, 0.042632f, 6.799419f, 4.177793f, 16.414610f, 4.525046f, 14.324770f, 1.669725f, 7.845615f, 2.388360f, 10.048730f, 4.001543f, 13.593500f, 5.279252f, 11.668290f, +0.755599f, 2.306610f, 0.016587f, 2.225110f, 1.901548f, 8.226547f, 2.425167f, 6.457295f, 0.498164f, 2.577394f, 0.839045f, 2.969211f, 2.399529f, 8.975457f, 3.727599f, 6.929604f, +1.884164f, 6.261307f, 0.044886f, 6.033392f, 5.036622f, 23.719910f, 6.970810f, 18.597960f, 1.347678f, 7.590289f, 2.463252f, 8.734494f, 3.357782f, 13.672450f, 5.660634f, 10.544290f, +0.051774f, 0.092650f, 0.000563f, 0.132098f, 0.086803f, 0.220136f, 0.054857f, 0.255387f, 0.000575f, 0.001744f, 0.000480f, 0.002970f, 0.175067f, 0.383871f, 0.134763f, 0.438036f, +0.079608f, 0.130689f, 0.000875f, 0.189618f, 0.189186f, 0.440148f, 0.120834f, 0.519631f, 0.068830f, 0.191507f, 0.058057f, 0.331824f, 0.239880f, 0.482530f, 0.186622f, 0.560324f, +0.000781f, 0.001411f, 0.000010f, 0.001842f, 0.002556f, 0.006548f, 0.001922f, 0.006953f, 0.000610f, 0.001867f, 0.000605f, 0.002910f, 0.004270f, 0.009457f, 0.003911f, 0.009878f, +0.123265f, 0.242556f, 0.001732f, 0.316190f, 0.428609f, 1.195256f, 0.349807f, 1.267805f, 0.104399f, 0.348173f, 0.112523f, 0.542018f, 0.378267f, 0.912050f, 0.376041f, 0.951545f, +0.071300f, 0.175670f, 0.000734f, 0.222304f, 0.113194f, 0.395233f, 0.067744f, 0.406967f, 0.000851f, 0.003552f, 0.000672f, 0.005369f, 0.220266f, 0.664966f, 0.160570f, 0.673479f, +0.153884f, 0.347815f, 0.001602f, 0.447907f, 0.346288f, 1.109225f, 0.209453f, 1.162291f, 0.142921f, 0.547488f, 0.114162f, 0.841972f, 0.423639f, 1.173270f, 0.312115f, 1.209240f, +0.057015f, 0.141895f, 0.000699f, 0.164355f, 0.176731f, 0.623335f, 0.125870f, 0.587480f, 0.047812f, 0.201671f, 0.044970f, 0.278960f, 0.284845f, 0.868636f, 0.247108f, 0.805245f, +0.208116f, 0.563832f, 0.002769f, 0.652356f, 0.685232f, 2.630931f, 0.529609f, 2.476853f, 0.189340f, 0.869387f, 0.193259f, 1.201244f, 0.583483f, 1.936959f, 0.549306f, 1.793618f, +0.000706f, 0.003448f, 0.000013f, 0.003772f, 0.001299f, 0.008993f, 0.001350f, 0.008004f, 0.000010f, 0.000083f, 0.000014f, 0.000108f, 0.002823f, 0.016894f, 0.003572f, 0.014788f, +0.001297f, 0.005810f, 0.000023f, 0.006466f, 0.003382f, 0.021476f, 0.003551f, 0.019450f, 0.001432f, 0.010873f, 0.001985f, 0.014452f, 0.004620f, 0.025363f, 0.005907f, 0.022593f, +0.000441f, 0.002174f, 0.000009f, 0.002176f, 0.001583f, 0.011071f, 0.001957f, 0.009018f, 0.000439f, 0.003674f, 0.000717f, 0.004392f, 0.002849f, 0.017225f, 0.004290f, 0.013801f, +0.002355f, 0.012646f, 0.000054f, 0.012646f, 0.008986f, 0.068399f, 0.012055f, 0.055654f, 0.002547f, 0.023184f, 0.004512f, 0.027687f, 0.008544f, 0.056225f, 0.013960f, 0.044998f, +0.182506f, 0.404508f, 0.002184f, 0.428808f, 0.238565f, 0.749346f, 0.165868f, 0.646359f, 0.001959f, 0.007357f, 0.001798f, 0.009314f, 0.578784f, 1.571857f, 0.490164f, 1.333594f, +0.402434f, 0.818263f, 0.004867f, 0.882711f, 0.745653f, 2.148638f, 0.523955f, 1.886013f, 0.336163f, 1.158443f, 0.311951f, 1.492394f, 1.137313f, 2.833521f, 0.973433f, 2.446396f, +0.137319f, 0.307437f, 0.001956f, 0.298304f, 0.350475f, 1.112014f, 0.289983f, 0.877946f, 0.103571f, 0.392997f, 0.113170f, 0.455379f, 0.704269f, 1.932021f, 0.709779f, 1.500334f, +0.397086f, 0.967772f, 0.006137f, 0.937981f, 1.076503f, 3.718189f, 0.966585f, 2.932298f, 0.324921f, 1.342121f, 0.385284f, 1.553444f, 1.142854f, 3.412929f, 1.249927f, 2.647419f, +0.071518f, 0.181746f, 0.001046f, 0.193483f, 0.102259f, 0.368283f, 0.086897f, 0.319017f, 0.000796f, 0.003430f, 0.000894f, 0.004360f, 0.211044f, 0.657161f, 0.218446f, 0.559916f, +0.167415f, 0.390298f, 0.002475f, 0.422826f, 0.339312f, 1.121056f, 0.291408f, 0.988209f, 0.145094f, 0.573292f, 0.164563f, 0.741694f, 0.440252f, 1.257622f, 0.460546f, 1.090412f, +0.001663f, 0.004268f, 0.000029f, 0.004159f, 0.004642f, 0.016886f, 0.004694f, 0.013388f, 0.001301f, 0.005660f, 0.001738f, 0.006587f, 0.007934f, 0.024957f, 0.009773f, 0.019463f, +0.246457f, 0.688704f, 0.004655f, 0.670338f, 0.730859f, 2.894355f, 0.802055f, 2.292285f, 0.209234f, 0.990944f, 0.303237f, 1.151843f, 0.660038f, 2.259994f, 0.882283f, 1.760527f, +0.165026f, 0.577399f, 0.002286f, 0.545571f, 0.223436f, 1.107908f, 0.179806f, 0.851794f, 0.001974f, 0.011704f, 0.002098f, 0.013207f, 0.444914f, 1.907423f, 0.436111f, 1.442437f, +0.542242f, 1.740467f, 0.007591f, 1.673520f, 1.040658f, 4.733785f, 0.846372f, 3.703644f, 0.504810f, 2.746168f, 0.542201f, 3.153371f, 1.302758f, 5.123709f, 1.290582f, 3.942975f, +0.203410f, 0.718905f, 0.003353f, 0.621745f, 0.537737f, 2.693377f, 0.514969f, 1.895370f, 0.170985f, 1.024194f, 0.216246f, 1.057807f, 0.886878f, 3.840707f, 1.034532f, 2.658439f, +0.697216f, 2.682442f, 0.012472f, 2.317344f, 1.957809f, 10.674830f, 2.034657f, 7.503724f, 0.635827f, 4.145990f, 0.872648f, 4.277316f, 1.705920f, 8.042098f, 2.159475f, 5.560375f, +0.057649f, 0.399857f, 0.001386f, 0.326543f, 0.090477f, 0.889358f, 0.126371f, 0.590973f, 0.000820f, 0.009637f, 0.001512f, 0.009399f, 0.201154f, 1.709580f, 0.342223f, 1.117374f, +0.161180f, 1.025591f, 0.003916f, 0.852312f, 0.358567f, 3.233411f, 0.506155f, 2.186457f, 0.178414f, 1.924059f, 0.332599f, 1.909527f, 0.501182f, 3.907563f, 0.861742f, 2.598992f, +0.055463f, 0.388592f, 0.001587f, 0.290465f, 0.169960f, 1.687576f, 0.282499f, 1.026407f, 0.055434f, 0.658245f, 0.121681f, 0.587585f, 0.312975f, 2.686870f, 0.633650f, 1.607391f, +0.278281f, 2.122443f, 0.008640f, 1.584731f, 0.905796f, 9.790629f, 1.633845f, 5.948205f, 0.301744f, 3.900469f, 0.718782f, 3.477918f, 0.881227f, 8.235467f, 1.936140f, 4.921328f, +0.243744f, 0.767188f, 0.003922f, 0.607244f, 0.271727f, 1.212071f, 0.254034f, 0.780630f, 0.002622f, 0.013987f, 0.003237f, 0.013221f, 0.674591f, 2.601695f, 0.768191f, 1.648133f, +0.818256f, 2.362691f, 0.013307f, 1.903084f, 1.293013f, 5.291125f, 1.221698f, 3.467805f, 0.685140f, 3.352919f, 0.854908f, 3.225202f, 2.018104f, 7.140174f, 2.322593f, 4.602929f, +0.282692f, 0.898789f, 0.005413f, 0.651155f, 0.615333f, 2.772568f, 0.684589f, 1.634424f, 0.213724f, 1.151659f, 0.314016f, 0.996400f, 1.265287f, 4.929252f, 1.714656f, 2.858133f, +0.767612f, 2.656744f, 0.015952f, 1.922630f, 1.774776f, 8.705200f, 2.142753f, 5.126023f, 0.629606f, 3.693197f, 1.003867f, 3.191770f, 1.928042f, 8.176586f, 2.835397f, 4.735792f, +0.026099f, 0.047527f, 0.000389f, 0.084335f, 0.042376f, 0.109363f, 0.036657f, 0.157905f, 0.000395f, 0.001218f, 0.000451f, 0.002581f, 0.096950f, 0.216330f, 0.102154f, 0.307227f, +0.054981f, 0.091851f, 0.000827f, 0.165860f, 0.126542f, 0.299593f, 0.110630f, 0.440196f, 0.064702f, 0.183194f, 0.074702f, 0.395051f, 0.182008f, 0.372571f, 0.193820f, 0.538446f, +0.000603f, 0.001109f, 0.000011f, 0.001802f, 0.001912f, 0.004984f, 0.001968f, 0.006586f, 0.000641f, 0.001998f, 0.000871f, 0.003874f, 0.003623f, 0.008165f, 0.004542f, 0.010614f, +0.073468f, 0.147116f, 0.001413f, 0.238678f, 0.247404f, 0.702094f, 0.276385f, 0.926840f, 0.084691f, 0.287424f, 0.124946f, 0.556879f, 0.247684f, 0.607722f, 0.337033f, 0.789103f, +0.053701f, 0.134639f, 0.000757f, 0.212051f, 0.082565f, 0.293372f, 0.067637f, 0.375961f, 0.000872f, 0.003706f, 0.000943f, 0.006970f, 0.182254f, 0.559907f, 0.181858f, 0.705763f, +0.158795f, 0.365239f, 0.002263f, 0.585377f, 0.346073f, 1.128075f, 0.286522f, 1.471132f, 0.200733f, 0.782506f, 0.219476f, 1.497712f, 0.480262f, 1.353532f, 0.484325f, 1.736205f, +0.065786f, 0.166610f, 0.001104f, 0.240180f, 0.197492f, 0.708836f, 0.192529f, 0.831449f, 0.075087f, 0.322301f, 0.096670f, 0.554854f, 0.361075f, 1.120507f, 0.428760f, 1.292775f, +0.185331f, 0.510953f, 0.003375f, 0.735757f, 0.590976f, 2.309029f, 0.625211f, 2.705442f, 0.229493f, 1.072328f, 0.320631f, 1.844012f, 0.570837f, 1.928379f, 0.735594f, 2.222388f, +0.014857f, 0.073845f, 0.000364f, 0.100519f, 0.026479f, 0.186513f, 0.037648f, 0.206582f, 0.000287f, 0.002417f, 0.000539f, 0.003929f, 0.065260f, 0.397444f, 0.113022f, 0.432990f, +0.037383f, 0.170453f, 0.000925f, 0.236114f, 0.094438f, 0.610250f, 0.135705f, 0.687829f, 0.056187f, 0.434206f, 0.106627f, 0.718284f, 0.146328f, 0.817537f, 0.256121f, 0.906357f, +0.014206f, 0.071325f, 0.000414f, 0.088866f, 0.049436f, 0.351746f, 0.083647f, 0.356598f, 0.019280f, 0.164053f, 0.043081f, 0.244096f, 0.100916f, 0.620822f, 0.207987f, 0.619063f, +0.058584f, 0.320187f, 0.001852f, 0.398489f, 0.216544f, 1.677244f, 0.397616f, 1.698496f, 0.086255f, 0.798975f, 0.209161f, 1.187487f, 0.233539f, 1.563970f, 0.522329f, 1.557813f, +0.161972f, 0.365323f, 0.002653f, 0.481982f, 0.205048f, 0.655421f, 0.195142f, 0.703608f, 0.002366f, 0.009044f, 0.002973f, 0.014249f, 0.564311f, 1.559564f, 0.654159f, 1.646766f, +0.489339f, 1.012503f, 0.008101f, 1.359378f, 0.878094f, 2.574870f, 0.844575f, 2.812903f, 0.556350f, 1.951018f, 0.706683f, 3.128153f, 1.519273f, 3.851860f, 1.779926f, 4.138937f, +0.186704f, 0.425370f, 0.003640f, 0.513673f, 0.461496f, 1.490077f, 0.522665f, 1.464145f, 0.191665f, 0.740084f, 0.286666f, 1.067294f, 1.051963f, 2.936716f, 1.451192f, 2.838287f, +0.416679f, 1.033423f, 0.008815f, 1.246571f, 1.094008f, 3.845254f, 1.344577f, 3.774155f, 0.464063f, 1.950652f, 0.753218f, 2.809970f, 1.317492f, 4.003803f, 1.972340f, 3.865327f, +0.168111f, 0.410191f, 0.002819f, 0.581450f, 0.283816f, 0.981417f, 0.276473f, 1.131973f, 0.001957f, 0.008093f, 0.002518f, 0.013700f, 0.446407f, 1.334652f, 0.529683f, 1.514151f, +0.274967f, 0.615488f, 0.004660f, 0.887843f, 0.658014f, 2.087383f, 0.647819f, 2.450046f, 0.249153f, 0.945218f, 0.323939f, 1.628288f, 0.650672f, 1.784633f, 0.780277f, 2.060345f, +0.002886f, 0.007114f, 0.000058f, 0.009231f, 0.009515f, 0.033235f, 0.011030f, 0.035087f, 0.002362f, 0.009865f, 0.003615f, 0.015285f, 0.012396f, 0.037436f, 0.017503f, 0.038873f, +0.389153f, 1.044118f, 0.008427f, 1.353198f, 1.362584f, 5.181079f, 1.714151f, 5.463707f, 0.345417f, 1.570719f, 0.573863f, 2.431045f, 0.937826f, 3.083184f, 1.437066f, 3.198052f, +0.455982f, 1.531827f, 0.007240f, 1.927239f, 0.728954f, 3.470477f, 0.672461f, 3.552799f, 0.005702f, 0.032465f, 0.006947f, 0.048778f, 1.106234f, 4.553617f, 1.243033f, 4.585185f, +1.046867f, 3.226286f, 0.016800f, 4.130649f, 2.372236f, 10.360890f, 2.211700f, 10.793640f, 1.018964f, 5.322264f, 1.254602f, 8.137572f, 2.263276f, 8.546666f, 2.570245f, 8.757633f, +0.415119f, 1.408674f, 0.007844f, 1.622191f, 1.295753f, 6.231432f, 1.422489f, 5.838953f, 0.364829f, 2.098235f, 0.528927f, 2.885549f, 1.628695f, 6.772138f, 2.177887f, 6.241540f, +1.294074f, 4.780361f, 0.026536f, 5.498843f, 4.290557f, 22.461710f, 5.111517f, 21.023700f, 1.233853f, 7.724867f, 1.941236f, 10.611690f, 2.849218f, 12.896600f, 4.134572f, 11.872990f, +0.123930f, 0.825328f, 0.003415f, 0.897453f, 0.229652f, 2.167454f, 0.367703f, 1.917744f, 0.001843f, 0.020797f, 0.003896f, 0.027007f, 0.389123f, 3.175311f, 0.758896f, 2.763414f, +0.242101f, 1.479104f, 0.006743f, 1.636717f, 0.635928f, 5.506006f, 1.029048f, 4.957552f, 0.280187f, 2.901183f, 0.598762f, 3.833831f, 0.677418f, 5.071141f, 1.335222f, 4.491125f, +0.088063f, 0.592407f, 0.002888f, 0.589619f, 0.318630f, 3.037676f, 0.607117f, 2.460073f, 0.092022f, 1.049172f, 0.231557f, 1.247040f, 0.447170f, 3.685943f, 1.037834f, 2.936121f, +0.401849f, 2.942753f, 0.014302f, 2.925660f, 1.544405f, 16.028020f, 3.193425f, 12.965990f, 0.455564f, 5.654146f, 1.244011f, 6.713051f, 1.145097f, 10.274990f, 2.884076f, 8.175718f, +0.624332f, 1.886783f, 0.011517f, 1.988537f, 0.821799f, 3.519652f, 0.880726f, 3.018333f, 0.007022f, 0.035965f, 0.009938f, 0.045266f, 1.554883f, 5.757736f, 2.029744f, 4.856663f, +1.464447f, 4.060036f, 0.027302f, 4.354429f, 2.732365f, 10.735500f, 2.959476f, 9.368701f, 1.282024f, 6.023908f, 1.833796f, 7.715474f, 3.250148f, 11.040960f, 4.287932f, 9.477262f, +0.534811f, 1.632612f, 0.011740f, 1.574927f, 1.374512f, 5.946464f, 1.753004f, 4.667581f, 0.422739f, 2.187164f, 0.712010f, 2.519659f, 2.154026f, 8.057151f, 3.346217f, 6.220616f, +1.320747f, 4.389004f, 0.031464f, 4.229242f, 3.605561f, 16.980350f, 4.990185f, 13.313700f, 1.132607f, 6.378980f, 2.070150f, 7.340585f, 2.985174f, 12.155240f, 5.032482f, 9.374209f, +0.134803f, 0.241230f, 0.001466f, 0.343940f, 0.182164f, 0.461980f, 0.115123f, 0.535957f, 0.001168f, 0.003544f, 0.000975f, 0.006034f, 0.369390f, 0.809963f, 0.284349f, 0.924252f, +0.236979f, 0.389038f, 0.002605f, 0.564460f, 0.453930f, 1.056083f, 0.289927f, 1.246793f, 0.159886f, 0.444855f, 0.134862f, 0.770800f, 0.578686f, 1.164053f, 0.450206f, 1.351724f, +0.001642f, 0.002968f, 0.000021f, 0.003873f, 0.004332f, 0.011098f, 0.003258f, 0.011784f, 0.001000f, 0.003064f, 0.000993f, 0.004776f, 0.007276f, 0.016116f, 0.006665f, 0.016832f, +0.236708f, 0.465785f, 0.003325f, 0.607185f, 0.663407f, 1.850033f, 0.541436f, 1.962326f, 0.156441f, 0.521733f, 0.168615f, 0.812208f, 0.588663f, 1.419341f, 0.585198f, 1.480802f, +0.135102f, 0.332863f, 0.001392f, 0.421227f, 0.172877f, 0.603627f, 0.103463f, 0.621548f, 0.001258f, 0.005253f, 0.000994f, 0.007938f, 0.338230f, 1.021090f, 0.246564f, 1.034163f, +0.333374f, 0.753504f, 0.003471f, 0.970344f, 0.604675f, 1.936883f, 0.365739f, 2.029546f, 0.241609f, 0.925536f, 0.192993f, 1.423364f, 0.743754f, 2.059829f, 0.547959f, 2.122978f, +0.087248f, 0.217138f, 0.001070f, 0.251508f, 0.217986f, 0.768842f, 0.155252f, 0.724617f, 0.057093f, 0.240820f, 0.053700f, 0.333113f, 0.353243f, 1.077216f, 0.306444f, 0.998603f, +0.290846f, 0.787965f, 0.003869f, 0.911679f, 0.771864f, 2.963553f, 0.596566f, 2.789995f, 0.206482f, 0.948094f, 0.210755f, 1.309994f, 0.660817f, 2.193678f, 0.622110f, 2.031339f, +0.001187f, 0.005799f, 0.000021f, 0.006343f, 0.001761f, 0.012190f, 0.001829f, 0.010848f, 0.000013f, 0.000109f, 0.000018f, 0.000142f, 0.003847f, 0.023023f, 0.004867f, 0.020153f, +0.002493f, 0.011170f, 0.000045f, 0.012432f, 0.005241f, 0.033282f, 0.005502f, 0.030142f, 0.002148f, 0.016313f, 0.002978f, 0.021683f, 0.007198f, 0.039519f, 0.009204f, 0.035203f, +0.000598f, 0.002953f, 0.000013f, 0.002956f, 0.001733f, 0.012119f, 0.002143f, 0.009872f, 0.000466f, 0.003894f, 0.000760f, 0.004655f, 0.003136f, 0.018958f, 0.004722f, 0.015190f, +0.002920f, 0.015684f, 0.000067f, 0.015684f, 0.008984f, 0.068378f, 0.012051f, 0.055638f, 0.002465f, 0.022439f, 0.004367f, 0.026796f, 0.008588f, 0.056513f, 0.014032f, 0.045229f, +0.388910f, 0.861981f, 0.004654f, 0.913764f, 0.409754f, 1.287062f, 0.284891f, 1.110174f, 0.003257f, 0.012234f, 0.002990f, 0.015488f, 0.999500f, 2.714435f, 0.846462f, 2.302979f, +0.980469f, 1.993575f, 0.011859f, 2.150594f, 1.464275f, 4.219381f, 1.028916f, 3.703652f, 0.639102f, 2.202394f, 0.593071f, 2.837290f, 2.245509f, 5.594501f, 1.921945f, 4.830161f, +0.236321f, 0.529088f, 0.003366f, 0.513369f, 0.486155f, 1.542509f, 0.402245f, 1.217826f, 0.139088f, 0.527765f, 0.151979f, 0.611541f, 0.982212f, 2.694501f, 0.989896f, 2.092447f, +0.624085f, 1.521011f, 0.009645f, 1.474189f, 1.363704f, 4.710168f, 1.224462f, 3.714608f, 0.398489f, 1.646006f, 0.472520f, 1.905177f, 1.455609f, 4.346918f, 1.591984f, 3.371917f, +0.284825f, 0.723816f, 0.004166f, 0.770557f, 0.328255f, 1.182199f, 0.278942f, 1.024053f, 0.002475f, 0.010658f, 0.002777f, 0.013551f, 0.681132f, 2.120948f, 0.705020f, 1.807094f, +0.762302f, 1.777165f, 0.011269f, 1.925279f, 1.245307f, 4.114382f, 1.069496f, 3.626822f, 0.515539f, 2.036986f, 0.584713f, 2.635341f, 1.624532f, 4.640628f, 1.699416f, 4.023622f, +0.005347f, 0.013727f, 0.000093f, 0.013376f, 0.012033f, 0.043776f, 0.012169f, 0.034708f, 0.003265f, 0.014206f, 0.004361f, 0.016531f, 0.020681f, 0.065049f, 0.025474f, 0.050729f, +0.723924f, 2.022943f, 0.013674f, 1.968995f, 1.730335f, 6.852491f, 1.898894f, 5.427068f, 0.479583f, 2.271332f, 0.695045f, 2.640126f, 1.571139f, 5.379639f, 2.100167f, 4.190721f, +0.478300f, 1.673491f, 0.006625f, 1.581243f, 0.521971f, 2.588195f, 0.420047f, 1.989885f, 0.004464f, 0.026471f, 0.004744f, 0.029870f, 1.045006f, 4.480120f, 1.024329f, 3.387970f, +1.796838f, 5.767424f, 0.025154f, 5.545580f, 2.779520f, 12.643590f, 2.260596f, 9.892159f, 1.305343f, 7.101067f, 1.402028f, 8.154017f, 3.498443f, 13.759280f, 3.465746f, 10.588520f, +0.476123f, 1.682748f, 0.007848f, 1.455325f, 1.014527f, 5.081486f, 0.971572f, 3.575917f, 0.312310f, 1.870728f, 0.394980f, 1.932122f, 1.682313f, 7.285411f, 1.962397f, 5.042775f, +1.490399f, 5.734105f, 0.026660f, 4.953656f, 3.373274f, 18.392560f, 3.505682f, 12.928790f, 1.060609f, 6.915828f, 1.455643f, 7.134890f, 2.955214f, 13.931560f, 3.740922f, 9.632401f, +0.148289f, 1.028539f, 0.003565f, 0.839954f, 0.187585f, 1.843904f, 0.262005f, 1.225262f, 0.001646f, 0.019344f, 0.003035f, 0.018866f, 0.419314f, 3.563692f, 0.713378f, 2.329215f, +0.474019f, 3.016189f, 0.011517f, 2.506588f, 0.849964f, 7.664624f, 1.199812f, 5.182878f, 0.409444f, 4.415532f, 0.763284f, 4.382182f, 1.194469f, 9.312908f, 2.053791f, 6.194186f, +0.115218f, 0.807253f, 0.003296f, 0.603406f, 0.284583f, 2.825694f, 0.473020f, 1.718625f, 0.089860f, 1.067048f, 0.197251f, 0.952505f, 0.526891f, 4.523323f, 1.066744f, 2.706030f, +0.527943f, 4.026610f, 0.016391f, 3.006486f, 1.385095f, 14.971310f, 2.498389f, 9.095681f, 0.446706f, 5.774320f, 1.064097f, 5.148769f, 1.354835f, 12.661550f, 2.976703f, 7.566255f, +0.794481f, 2.500639f, 0.012785f, 1.979303f, 0.713884f, 3.184368f, 0.667402f, 2.050880f, 0.006669f, 0.035576f, 0.008234f, 0.033628f, 1.781907f, 6.872278f, 2.029147f, 4.353480f, +3.049349f, 8.804904f, 0.049592f, 7.092112f, 3.883886f, 15.893210f, 3.669672f, 10.416410f, 1.992406f, 9.750374f, 2.486093f, 9.378970f, 6.094754f, 21.563610f, 7.014324f, 13.901030f, +0.744154f, 2.365959f, 0.014250f, 1.714092f, 1.305587f, 5.882709f, 1.452529f, 3.467847f, 0.439019f, 2.365668f, 0.645033f, 2.046745f, 2.699190f, 10.515390f, 3.657812f, 6.097151f, +1.845351f, 6.386850f, 0.038349f, 4.622030f, 3.438954f, 16.867920f, 4.151978f, 9.932609f, 1.181099f, 6.928195f, 1.883189f, 5.987549f, 3.756200f, 15.929570f, 5.523903f, 9.226239f, +0.118026f, 0.214930f, 0.001757f, 0.381387f, 0.154465f, 0.398636f, 0.133619f, 0.575574f, 0.001392f, 0.004297f, 0.001591f, 0.009107f, 0.355306f, 0.792812f, 0.374377f, 1.125937f, +0.284276f, 0.474909f, 0.004278f, 0.857570f, 0.527361f, 1.248548f, 0.461049f, 1.834509f, 0.261050f, 0.739128f, 0.301399f, 1.593901f, 0.762630f, 1.561104f, 0.812123f, 2.256136f, +0.002202f, 0.004051f, 0.000039f, 0.006580f, 0.005628f, 0.014671f, 0.005793f, 0.019388f, 0.001826f, 0.005693f, 0.002482f, 0.011042f, 0.010722f, 0.024167f, 0.013444f, 0.031414f, +0.245045f, 0.490688f, 0.004712f, 0.796085f, 0.665121f, 1.887505f, 0.743032f, 2.491712f, 0.220427f, 0.748085f, 0.325200f, 1.449400f, 0.669483f, 1.642658f, 0.910993f, 2.132926f, +0.176736f, 0.443115f, 0.002492f, 0.697887f, 0.219022f, 0.778230f, 0.179422f, 0.997314f, 0.002240f, 0.009517f, 0.002423f, 0.017901f, 0.486088f, 1.493328f, 0.485034f, 1.882340f, +0.597514f, 1.374327f, 0.008515f, 2.202663f, 1.049606f, 3.421340f, 0.868992f, 4.461797f, 0.589403f, 2.297632f, 0.644437f, 4.397656f, 1.464488f, 4.127394f, 1.476876f, 5.294298f, +0.174855f, 0.442839f, 0.002934f, 0.638381f, 0.423096f, 1.518573f, 0.412465f, 1.781252f, 0.155737f, 0.668477f, 0.200502f, 1.150810f, 0.777744f, 2.413535f, 0.923535f, 2.784595f, +0.449863f, 1.240260f, 0.008192f, 1.785936f, 1.156238f, 4.517592f, 1.223220f, 5.293169f, 0.434692f, 2.031140f, 0.607320f, 3.492818f, 1.122895f, 3.793317f, 1.446988f, 4.371664f, +0.043396f, 0.215691f, 0.001062f, 0.293602f, 0.062339f, 0.439103f, 0.088635f, 0.486351f, 0.000654f, 0.005508f, 0.001228f, 0.008954f, 0.154473f, 0.940769f, 0.267528f, 1.024909f, +0.124840f, 0.569225f, 0.003088f, 0.788499f, 0.254199f, 1.642608f, 0.365278f, 1.851429f, 0.146420f, 1.131506f, 0.277861f, 1.871791f, 0.396007f, 2.212498f, 0.693140f, 2.452871f, +0.033512f, 0.168250f, 0.000976f, 0.209627f, 0.093994f, 0.668786f, 0.159041f, 0.678010f, 0.035489f, 0.301979f, 0.079301f, 0.449318f, 0.192916f, 1.186791f, 0.397598f, 1.183429f, +0.126206f, 0.689769f, 0.003989f, 0.858453f, 0.376004f, 2.912340f, 0.690414f, 2.949241f, 0.144999f, 1.343117f, 0.351610f, 1.996224f, 0.407712f, 2.730382f, 0.911883f, 2.719634f, +0.599494f, 1.352141f, 0.009820f, 1.783924f, 0.611712f, 1.955294f, 0.582161f, 2.099046f, 0.006833f, 0.026120f, 0.008588f, 0.041154f, 1.692618f, 4.677824f, 1.962112f, 4.939382f, +2.070731f, 4.284602f, 0.034282f, 5.752470f, 2.995027f, 8.782438f, 2.880699f, 9.594329f, 1.837143f, 6.442520f, 2.333560f, 10.329580f, 5.210086f, 13.209290f, 6.103949f, 14.193780f, +0.558083f, 1.271488f, 0.010879f, 1.535437f, 1.111883f, 3.590047f, 1.259258f, 3.527570f, 0.447062f, 1.726265f, 0.668655f, 2.489489f, 2.548247f, 7.113818f, 3.515327f, 6.875386f, +1.137456f, 2.821055f, 0.024063f, 3.402911f, 2.407131f, 8.460659f, 2.958453f, 8.304220f, 0.988532f, 4.155216f, 1.604481f, 5.985708f, 2.914583f, 8.857296f, 4.363251f, 8.550956f, +0.416808f, 1.017010f, 0.006989f, 1.441624f, 0.567181f, 1.961277f, 0.552508f, 2.262150f, 0.003786f, 0.015658f, 0.004871f, 0.026505f, 0.896944f, 2.681652f, 1.064267f, 3.042312f, +0.779450f, 1.744728f, 0.013208f, 2.516773f, 1.503451f, 4.769313f, 1.480155f, 5.597936f, 0.551131f, 2.090837f, 0.716559f, 3.601800f, 1.494737f, 4.099699f, 1.792469f, 4.733069f, +0.005780f, 0.014245f, 0.000115f, 0.018483f, 0.015357f, 0.053640f, 0.017802f, 0.056628f, 0.003690f, 0.015414f, 0.005649f, 0.023883f, 0.020114f, 0.060746f, 0.028402f, 0.063079f, +0.711619f, 1.909312f, 0.015409f, 2.474506f, 2.008336f, 7.636480f, 2.526517f, 8.053051f, 0.492891f, 2.241333f, 0.818871f, 3.468972f, 1.389775f, 4.569006f, 2.129606f, 4.739230f, +0.822758f, 2.763973f, 0.013064f, 3.477440f, 1.060156f, 5.047298f, 0.977995f, 5.167024f, 0.008028f, 0.045710f, 0.009781f, 0.068679f, 1.617581f, 6.658487f, 1.817615f, 6.704647f, +2.159652f, 6.655723f, 0.034657f, 8.521395f, 3.944538f, 17.228010f, 3.677600f, 17.947600f, 1.640333f, 8.567801f, 2.019664f, 13.099890f, 3.783772f, 14.288420f, 4.296968f, 14.641120f, +0.604918f, 2.052743f, 0.011431f, 2.363883f, 1.521921f, 7.319102f, 1.670778f, 6.858118f, 0.414853f, 2.385936f, 0.601451f, 3.281203f, 1.923353f, 7.997330f, 2.571902f, 7.370738f, +1.722149f, 6.361689f, 0.035314f, 7.317842f, 4.602261f, 24.093520f, 5.482863f, 22.551040f, 1.281315f, 8.022012f, 2.015908f, 11.019880f, 3.072788f, 13.908550f, 4.459000f, 12.804630f, +0.198457f, 1.321657f, 0.005469f, 1.437156f, 0.296421f, 2.797614f, 0.474608f, 2.475305f, 0.002303f, 0.025989f, 0.004869f, 0.033748f, 0.504980f, 4.120724f, 0.984849f, 3.586190f, +0.443259f, 2.708066f, 0.012346f, 2.996637f, 0.938457f, 8.125368f, 1.518596f, 7.315998f, 0.400303f, 4.144920f, 0.855452f, 5.477394f, 1.005107f, 7.524218f, 1.981112f, 6.663628f, +0.113890f, 0.766148f, 0.003735f, 0.762541f, 0.332142f, 3.166501f, 0.632864f, 2.564402f, 0.092868f, 1.058813f, 0.233685f, 1.258500f, 0.468663f, 3.863100f, 1.087715f, 3.077240f, +0.474616f, 3.475632f, 0.016892f, 3.455443f, 1.470235f, 15.258280f, 3.040062f, 12.343300f, 0.419866f, 5.211077f, 1.146528f, 6.187004f, 1.096017f, 9.834592f, 2.760461f, 7.825298f, +1.266897f, 3.828666f, 0.023370f, 4.035146f, 1.344118f, 5.756667f, 1.440496f, 4.936720f, 0.011119f, 0.056949f, 0.015736f, 0.071677f, 2.556927f, 9.468311f, 3.337812f, 7.986541f, +3.397565f, 9.419414f, 0.063342f, 10.102420f, 5.109502f, 20.075310f, 5.534197f, 17.519400f, 2.320977f, 10.905680f, 3.319906f, 13.968100f, 6.110718f, 20.758510f, 8.061894f, 17.818540f, +0.876448f, 2.675523f, 0.019240f, 2.580989f, 1.815600f, 7.854714f, 2.315552f, 6.165431f, 0.540604f, 2.796970f, 0.910526f, 3.222167f, 2.860697f, 10.700460f, 4.444009f, 8.261411f, +1.976665f, 6.568699f, 0.047089f, 6.329595f, 4.349427f, 20.483570f, 6.019714f, 16.060460f, 1.322736f, 7.449810f, 2.417663f, 8.572838f, 3.620580f, 14.742530f, 6.103666f, 11.369550f, +}; + +static const float acceptor_me2x3acc3[16384] = { +0.036350f, 0.044079f, 0.017386f, 0.046962f, 0.031088f, 0.045756f, 0.024587f, 0.034370f, 0.025195f, 0.034486f, 0.017536f, 0.034052f, 0.076383f, 0.099866f, 0.073811f, 0.086068f, +0.047550f, 0.057744f, 0.028229f, 0.064311f, 0.043775f, 0.064522f, 0.042972f, 0.050664f, 0.064784f, 0.088804f, 0.055968f, 0.091663f, 0.081233f, 0.106361f, 0.097434f, 0.095823f, +0.243824f, 0.254641f, 0.117527f, 0.282971f, 0.147646f, 0.187151f, 0.117680f, 0.146631f, 0.160177f, 0.188823f, 0.112355f, 0.194472f, 0.391222f, 0.440520f, 0.380999f, 0.395997f, +0.023217f, 0.027583f, 0.011848f, 0.035175f, 0.032216f, 0.046454f, 0.027185f, 0.041768f, 0.034881f, 0.046775f, 0.025903f, 0.055285f, 0.052301f, 0.066993f, 0.053925f, 0.069110f, +0.845246f, 1.058768f, 0.485224f, 0.886728f, 0.769988f, 1.170633f, 0.730911f, 0.691241f, 0.573267f, 0.810543f, 0.478904f, 0.629150f, 1.393519f, 1.882007f, 1.616261f, 1.275036f, +0.529473f, 0.664187f, 0.377275f, 0.581493f, 0.519190f, 0.790481f, 0.611732f, 0.487938f, 0.705887f, 0.999501f, 0.731951f, 0.811009f, 0.709682f, 0.959845f, 1.021687f, 0.679778f, +2.480488f, 2.675926f, 1.435063f, 2.337585f, 1.599884f, 2.094809f, 1.530535f, 1.290199f, 1.594530f, 1.941649f, 1.342452f, 1.571999f, 3.122639f, 3.632029f, 3.650020f, 2.566577f, +0.344638f, 0.422943f, 0.211095f, 0.423992f, 0.509371f, 0.758703f, 0.515904f, 0.536249f, 0.506656f, 0.701830f, 0.451605f, 0.652073f, 0.609120f, 0.805956f, 0.753799f, 0.653580f, +0.000004f, 0.000005f, 0.000008f, 0.000022f, 0.000003f, 0.000004f, 0.000009f, 0.000013f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000003f, 0.000011f, 0.000013f, +0.000003f, 0.000004f, 0.000008f, 0.000020f, 0.000002f, 0.000004f, 0.000010f, 0.000013f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000002f, 0.000009f, 0.000009f, +0.000022f, 0.000023f, 0.000046f, 0.000113f, 0.000011f, 0.000014f, 0.000038f, 0.000048f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000011f, 0.000012f, 0.000046f, 0.000049f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.441540f, 0.580346f, 0.242142f, 0.576465f, 0.392887f, 0.626763f, 0.356277f, 0.438944f, 0.287594f, 0.426675f, 0.229515f, 0.392801f, 0.643154f, 0.911428f, 0.712614f, 0.732353f, +0.289517f, 0.381084f, 0.197074f, 0.395705f, 0.277302f, 0.443015f, 0.312126f, 0.324331f, 0.370682f, 0.550742f, 0.367189f, 0.530015f, 0.342855f, 0.486571f, 0.471526f, 0.408705f, +1.929791f, 2.184471f, 1.066560f, 2.263273f, 1.215789f, 1.670371f, 1.111102f, 1.220176f, 1.191355f, 1.522222f, 0.958182f, 1.461696f, 2.146398f, 2.619611f, 2.396761f, 2.195528f, +0.175285f, 0.225716f, 0.102565f, 0.268371f, 0.253054f, 0.395503f, 0.244844f, 0.331544f, 0.247474f, 0.359707f, 0.210726f, 0.396378f, 0.273716f, 0.380021f, 0.323589f, 0.365504f, +0.019208f, 0.024062f, 0.010894f, 0.022668f, 0.014719f, 0.022378f, 0.013803f, 0.014864f, 0.014026f, 0.019833f, 0.011577f, 0.017316f, 0.037260f, 0.050324f, 0.042695f, 0.038350f, +0.016945f, 0.021258f, 0.011929f, 0.020935f, 0.013977f, 0.021281f, 0.016270f, 0.014776f, 0.024323f, 0.034443f, 0.024918f, 0.031436f, 0.026723f, 0.036145f, 0.038009f, 0.028794f, +0.137628f, 0.148482f, 0.078666f, 0.145900f, 0.074667f, 0.097772f, 0.070571f, 0.067735f, 0.095254f, 0.115998f, 0.079231f, 0.105638f, 0.203849f, 0.237119f, 0.235411f, 0.188478f, +0.013467f, 0.016528f, 0.008149f, 0.018637f, 0.016742f, 0.024939f, 0.016753f, 0.019827f, 0.021315f, 0.029529f, 0.018771f, 0.030860f, 0.028004f, 0.037056f, 0.034239f, 0.033802f, +0.439889f, 0.569215f, 0.299447f, 0.421534f, 0.359023f, 0.563863f, 0.404129f, 0.294408f, 0.314317f, 0.459095f, 0.311371f, 0.315099f, 0.669467f, 0.934012f, 0.920758f, 0.559527f, +0.185830f, 0.240811f, 0.157017f, 0.186422f, 0.163258f, 0.256777f, 0.228102f, 0.140151f, 0.261010f, 0.381786f, 0.320939f, 0.273924f, 0.229928f, 0.321250f, 0.392521f, 0.201176f, +1.378923f, 1.536710f, 0.946001f, 1.187005f, 0.796836f, 1.077804f, 0.903945f, 0.586975f, 0.933870f, 1.174734f, 0.932331f, 0.840985f, 1.602435f, 1.925409f, 2.221119f, 1.203082f, +0.196878f, 0.249591f, 0.142997f, 0.221244f, 0.260703f, 0.401141f, 0.313111f, 0.250703f, 0.304928f, 0.436346f, 0.322300f, 0.358478f, 0.321212f, 0.439051f, 0.471370f, 0.314825f, +0.000025f, 0.000032f, 0.000061f, 0.000131f, 0.000016f, 0.000024f, 0.000064f, 0.000070f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000015f, 0.000020f, 0.000074f, 0.000068f, +0.000014f, 0.000018f, 0.000043f, 0.000077f, 0.000010f, 0.000015f, 0.000048f, 0.000044f, 0.000000f, 0.000001f, 0.000002f, 0.000002f, 0.000007f, 0.000009f, 0.000042f, 0.000033f, +0.000152f, 0.000164f, 0.000372f, 0.000706f, 0.000067f, 0.000089f, 0.000274f, 0.000269f, 0.000002f, 0.000003f, 0.000008f, 0.000011f, 0.000069f, 0.000081f, 0.000344f, 0.000281f, +0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000001f, 0.000002f, 0.000005f, 0.000006f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000004f, 0.000004f, +0.425449f, 0.577669f, 0.276672f, 0.507379f, 0.339174f, 0.558950f, 0.364721f, 0.346135f, 0.291949f, 0.447446f, 0.276285f, 0.364236f, 0.572068f, 0.837472f, 0.751632f, 0.595026f, +0.188132f, 0.255814f, 0.151858f, 0.234878f, 0.161443f, 0.266440f, 0.215484f, 0.172479f, 0.253771f, 0.389496f, 0.298090f, 0.331444f, 0.205662f, 0.301513f, 0.335404f, 0.223942f, +1.986234f, 2.322637f, 1.301736f, 2.127841f, 1.121130f, 1.591204f, 1.214981f, 1.027785f, 1.291850f, 1.705156f, 1.232074f, 1.447805f, 2.039324f, 2.571151f, 2.700340f, 1.905447f, +0.185394f, 0.246620f, 0.128638f, 0.259279f, 0.239795f, 0.387161f, 0.275128f, 0.286980f, 0.275760f, 0.414061f, 0.278443f, 0.403453f, 0.267243f, 0.383291f, 0.374643f, 0.325972f, +0.004930f, 0.005477f, 0.002425f, 0.006531f, 0.004481f, 0.006043f, 0.003645f, 0.005080f, 0.003602f, 0.004518f, 0.002579f, 0.004992f, 0.009529f, 0.011416f, 0.009473f, 0.011011f, +0.004830f, 0.005374f, 0.002950f, 0.006698f, 0.004725f, 0.006382f, 0.004772f, 0.005608f, 0.006937f, 0.008713f, 0.006165f, 0.010065f, 0.007590f, 0.009106f, 0.009365f, 0.009181f, +0.023858f, 0.022830f, 0.011830f, 0.028393f, 0.015354f, 0.017832f, 0.012589f, 0.015636f, 0.016524f, 0.017848f, 0.011923f, 0.020572f, 0.035215f, 0.036332f, 0.035279f, 0.036551f, +0.002212f, 0.002408f, 0.001161f, 0.003436f, 0.003262f, 0.004309f, 0.002831f, 0.004336f, 0.003503f, 0.004304f, 0.002676f, 0.005694f, 0.004583f, 0.005379f, 0.004861f, 0.006210f, +0.164161f, 0.188414f, 0.096944f, 0.176597f, 0.158929f, 0.221392f, 0.155193f, 0.146303f, 0.117379f, 0.152066f, 0.100872f, 0.132097f, 0.248967f, 0.308086f, 0.297050f, 0.233591f, +0.077016f, 0.088522f, 0.056453f, 0.086734f, 0.080259f, 0.111965f, 0.097279f, 0.077346f, 0.108247f, 0.140439f, 0.115466f, 0.127530f, 0.094960f, 0.117680f, 0.140633f, 0.093272f, +0.347589f, 0.343578f, 0.206866f, 0.335893f, 0.238258f, 0.285842f, 0.234473f, 0.197025f, 0.235562f, 0.262825f, 0.204015f, 0.238139f, 0.402523f, 0.428984f, 0.484009f, 0.339256f, +0.047018f, 0.052870f, 0.029626f, 0.059315f, 0.073853f, 0.100792f, 0.076947f, 0.079727f, 0.072872f, 0.092492f, 0.066818f, 0.096172f, 0.076444f, 0.092678f, 0.097317f, 0.084110f, +0.000000f, 0.000001f, 0.000001f, 0.000003f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, +0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, +0.000002f, 0.000002f, 0.000004f, 0.000010f, 0.000001f, 0.000001f, 0.000003f, 0.000004f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000004f, 0.000004f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.068159f, 0.082084f, 0.038451f, 0.091249f, 0.064454f, 0.094212f, 0.060126f, 0.073841f, 0.046803f, 0.063623f, 0.038423f, 0.065550f, 0.091328f, 0.118587f, 0.104096f, 0.106639f, +0.033472f, 0.040369f, 0.023438f, 0.046911f, 0.034071f, 0.049874f, 0.039450f, 0.040863f, 0.045180f, 0.061506f, 0.046039f, 0.066243f, 0.036463f, 0.047414f, 0.051587f, 0.044571f, +0.214933f, 0.222926f, 0.122199f, 0.258484f, 0.143906f, 0.181158f, 0.135290f, 0.148098f, 0.139887f, 0.163771f, 0.115737f, 0.175994f, 0.219909f, 0.245919f, 0.252607f, 0.230662f, +0.019007f, 0.022426f, 0.011441f, 0.029841f, 0.029162f, 0.041761f, 0.029025f, 0.039178f, 0.028291f, 0.037677f, 0.024781f, 0.046465f, 0.027303f, 0.034733f, 0.033204f, 0.037386f, +0.022710f, 0.028287f, 0.010148f, 0.033733f, 0.015326f, 0.023169f, 0.011325f, 0.019480f, 0.020172f, 0.028361f, 0.013118f, 0.031346f, 0.048390f, 0.064985f, 0.043689f, 0.062689f, +0.018143f, 0.022631f, 0.010063f, 0.028212f, 0.013179f, 0.019953f, 0.012088f, 0.017537f, 0.031678f, 0.044603f, 0.025570f, 0.051533f, 0.031429f, 0.042269f, 0.035222f, 0.042625f, +0.151193f, 0.162189f, 0.068091f, 0.201740f, 0.072241f, 0.094057f, 0.053798f, 0.082486f, 0.127289f, 0.154129f, 0.083422f, 0.177682f, 0.245993f, 0.284514f, 0.223831f, 0.286277f, +0.014170f, 0.017292f, 0.006756f, 0.024683f, 0.015515f, 0.022979f, 0.012232f, 0.023126f, 0.027283f, 0.037580f, 0.018930f, 0.049717f, 0.032368f, 0.042587f, 0.031181f, 0.049175f, +0.387044f, 0.497985f, 0.207595f, 0.466834f, 0.278207f, 0.434453f, 0.246743f, 0.287149f, 0.336411f, 0.488571f, 0.262579f, 0.424485f, 0.647045f, 0.897597f, 0.701182f, 0.680674f, +0.148070f, 0.190789f, 0.098578f, 0.186966f, 0.114566f, 0.179168f, 0.126122f, 0.123791f, 0.252986f, 0.367945f, 0.245098f, 0.334181f, 0.201249f, 0.279582f, 0.270698f, 0.221631f, +1.127349f, 1.249205f, 0.609382f, 1.221471f, 0.573742f, 0.771633f, 0.512824f, 0.531960f, 0.928732f, 1.161627f, 0.730556f, 1.052700f, 1.439090f, 1.719308f, 1.571660f, 1.359925f, +0.154169f, 0.194336f, 0.088228f, 0.218065f, 0.179794f, 0.275074f, 0.170140f, 0.217621f, 0.290458f, 0.413276f, 0.241895f, 0.429794f, 0.276300f, 0.375516f, 0.319471f, 0.340856f, +0.000007f, 0.000009f, 0.000013f, 0.000046f, 0.000004f, 0.000006f, 0.000012f, 0.000022f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000005f, 0.000006f, 0.000018f, 0.000026f, +0.000004f, 0.000004f, 0.000008f, 0.000024f, 0.000002f, 0.000003f, 0.000008f, 0.000012f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000003f, 0.000009f, 0.000011f, +0.000039f, 0.000042f, 0.000076f, 0.000229f, 0.000015f, 0.000020f, 0.000049f, 0.000077f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000020f, 0.000023f, 0.000077f, 0.000100f, +0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, +0.310022f, 0.418551f, 0.158851f, 0.465362f, 0.217669f, 0.356674f, 0.184423f, 0.279597f, 0.258785f, 0.394362f, 0.192961f, 0.406375f, 0.457913f, 0.666544f, 0.474045f, 0.599492f, +0.124150f, 0.167853f, 0.078958f, 0.195091f, 0.093828f, 0.153969f, 0.098675f, 0.126171f, 0.203709f, 0.310881f, 0.188536f, 0.334881f, 0.149082f, 0.217321f, 0.191566f, 0.204324f, +1.344863f, 1.563696f, 0.694464f, 1.813422f, 0.668547f, 0.943464f, 0.570855f, 0.771420f, 1.064009f, 1.396434f, 0.799557f, 1.500913f, 1.516780f, 1.901461f, 1.582466f, 1.783799f, +0.120233f, 0.159031f, 0.065732f, 0.211646f, 0.136962f, 0.219874f, 0.123815f, 0.206311f, 0.217544f, 0.324790f, 0.173074f, 0.400609f, 0.190382f, 0.271501f, 0.210289f, 0.292288f, +0.041624f, 0.050475f, 0.019908f, 0.053776f, 0.044059f, 0.064847f, 0.034845f, 0.048710f, 0.035672f, 0.048827f, 0.024828f, 0.048212f, 0.097631f, 0.127647f, 0.094344f, 0.110010f, +0.046012f, 0.055876f, 0.027315f, 0.062231f, 0.052425f, 0.077271f, 0.051463f, 0.060675f, 0.077511f, 0.106249f, 0.066963f, 0.109670f, 0.087740f, 0.114881f, 0.105239f, 0.103499f, +0.209913f, 0.219226f, 0.101181f, 0.243616f, 0.157318f, 0.199411f, 0.125389f, 0.156236f, 0.170505f, 0.200998f, 0.119600f, 0.207011f, 0.375953f, 0.423327f, 0.366129f, 0.380542f, +0.021525f, 0.025573f, 0.010985f, 0.032612f, 0.036966f, 0.053303f, 0.031193f, 0.047926f, 0.039985f, 0.053620f, 0.029694f, 0.063374f, 0.054124f, 0.069329f, 0.055805f, 0.071519f, +0.737929f, 0.924342f, 0.423617f, 0.774144f, 0.831970f, 1.264867f, 0.789747f, 0.746884f, 0.618818f, 0.874947f, 0.516956f, 0.679140f, 1.357974f, 1.834002f, 1.575035f, 1.242513f, +0.390616f, 0.490001f, 0.278333f, 0.428994f, 0.474050f, 0.721755f, 0.558547f, 0.445516f, 0.643896f, 0.911724f, 0.667670f, 0.739785f, 0.584410f, 0.790414f, 0.841340f, 0.559784f, +1.628124f, 1.756404f, 0.941936f, 1.534326f, 1.299664f, 1.701715f, 1.243329f, 1.048092f, 1.294067f, 1.575777f, 1.089489f, 1.275782f, 2.287805f, 2.661011f, 2.674192f, 1.880406f, +0.243606f, 0.298955f, 0.149211f, 0.299696f, 0.445605f, 0.663724f, 0.451321f, 0.469118f, 0.442803f, 0.613380f, 0.394690f, 0.569893f, 0.480588f, 0.635890f, 0.594739f, 0.515667f, +0.000025f, 0.000030f, 0.000051f, 0.000141f, 0.000022f, 0.000032f, 0.000073f, 0.000105f, 0.000000f, 0.000001f, 0.000001f, 0.000003f, 0.000018f, 0.000024f, 0.000075f, 0.000089f, +0.000017f, 0.000021f, 0.000045f, 0.000104f, 0.000016f, 0.000024f, 0.000069f, 0.000083f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000010f, 0.000014f, 0.000053f, 0.000053f, +0.000105f, 0.000110f, 0.000217f, 0.000535f, 0.000064f, 0.000082f, 0.000221f, 0.000281f, 0.000002f, 0.000002f, 0.000006f, 0.000010f, 0.000058f, 0.000066f, 0.000243f, 0.000258f, +0.000001f, 0.000001f, 0.000002f, 0.000005f, 0.000001f, 0.000002f, 0.000004f, 0.000006f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000003f, 0.000003f, +0.537709f, 0.706748f, 0.294881f, 0.702023f, 0.592158f, 0.944654f, 0.536980f, 0.661574f, 0.433043f, 0.642464f, 0.345591f, 0.591458f, 0.874258f, 1.238931f, 0.968677f, 0.995509f, +0.297939f, 0.392169f, 0.202807f, 0.407216f, 0.353182f, 0.564239f, 0.397534f, 0.413079f, 0.471659f, 0.700769f, 0.467214f, 0.674395f, 0.393831f, 0.558916f, 0.541633f, 0.469471f, +1.766879f, 2.000059f, 0.976521f, 2.072208f, 1.377675f, 1.892787f, 1.259049f, 1.382647f, 1.348688f, 1.723250f, 1.084722f, 1.654730f, 2.193581f, 2.677196f, 2.449447f, 2.243791f, +0.172829f, 0.222553f, 0.101128f, 0.264610f, 0.308799f, 0.482627f, 0.298779f, 0.404579f, 0.301699f, 0.438523f, 0.256898f, 0.483229f, 0.301243f, 0.418239f, 0.356132f, 0.402262f, +0.027198f, 0.034071f, 0.015425f, 0.032096f, 0.025793f, 0.039216f, 0.024189f, 0.026047f, 0.024556f, 0.034722f, 0.020267f, 0.030316f, 0.058888f, 0.079536f, 0.067479f, 0.060611f, +0.020275f, 0.025435f, 0.014273f, 0.025048f, 0.020697f, 0.031514f, 0.024093f, 0.021881f, 0.035984f, 0.050955f, 0.036864f, 0.046507f, 0.035690f, 0.048274f, 0.050763f, 0.038456f, +0.146509f, 0.158064f, 0.083742f, 0.155315f, 0.098374f, 0.128815f, 0.092978f, 0.089242f, 0.125376f, 0.152680f, 0.104286f, 0.139044f, 0.242223f, 0.281756f, 0.279726f, 0.223958f, +0.015438f, 0.018947f, 0.009342f, 0.021365f, 0.023754f, 0.035383f, 0.023769f, 0.028131f, 0.030214f, 0.041855f, 0.026607f, 0.043742f, 0.035835f, 0.047418f, 0.043813f, 0.043253f, +0.474865f, 0.614474f, 0.323257f, 0.455051f, 0.479669f, 0.753344f, 0.539932f, 0.393341f, 0.419536f, 0.612778f, 0.415603f, 0.420580f, 0.806683f, 1.125451f, 1.109480f, 0.674209f, +0.169518f, 0.219674f, 0.143235f, 0.170059f, 0.184319f, 0.289901f, 0.257527f, 0.158230f, 0.294397f, 0.430622f, 0.361991f, 0.308962f, 0.234121f, 0.327109f, 0.399680f, 0.204845f, +1.119143f, 1.247204f, 0.767781f, 0.963381f, 0.800400f, 1.082625f, 0.907987f, 0.589600f, 0.937143f, 1.178851f, 0.935599f, 0.843933f, 1.451688f, 1.744278f, 2.012170f, 1.089903f, +0.172074f, 0.218147f, 0.124982f, 0.193371f, 0.282005f, 0.433919f, 0.338695f, 0.271188f, 0.329526f, 0.471546f, 0.348300f, 0.387396f, 0.313370f, 0.428333f, 0.459863f, 0.307139f, +0.000196f, 0.000247f, 0.000477f, 0.001016f, 0.000152f, 0.000232f, 0.000613f, 0.000675f, 0.000004f, 0.000005f, 0.000014f, 0.000021f, 0.000131f, 0.000178f, 0.000644f, 0.000592f, +0.000093f, 0.000117f, 0.000281f, 0.000504f, 0.000078f, 0.000119f, 0.000389f, 0.000361f, 0.000004f, 0.000005f, 0.000016f, 0.000020f, 0.000050f, 0.000069f, 0.000308f, 0.000239f, +0.000885f, 0.000959f, 0.002173f, 0.004121f, 0.000487f, 0.000640f, 0.001977f, 0.001940f, 0.000016f, 0.000020f, 0.000059f, 0.000080f, 0.000452f, 0.000527f, 0.002240f, 0.001834f, +0.000007f, 0.000008f, 0.000017f, 0.000041f, 0.000008f, 0.000013f, 0.000036f, 0.000044f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000005f, 0.000006f, 0.000025f, 0.000025f, +0.640649f, 0.869866f, 0.416618f, 0.764022f, 0.632103f, 1.041690f, 0.679715f, 0.645077f, 0.543569f, 0.833081f, 0.514404f, 0.678156f, 0.961542f, 1.407637f, 1.263356f, 1.000129f, +0.239393f, 0.325516f, 0.193235f, 0.298876f, 0.254250f, 0.419604f, 0.339355f, 0.271630f, 0.399267f, 0.612809f, 0.468996f, 0.521473f, 0.292112f, 0.428254f, 0.476390f, 0.318076f, +2.248652f, 2.629500f, 1.473720f, 2.408968f, 1.570869f, 2.229512f, 1.702369f, 1.440080f, 1.808331f, 2.386875f, 1.724657f, 2.026636f, 2.577063f, 3.249126f, 3.412380f, 2.407886f, +0.226027f, 0.300672f, 0.156832f, 0.316106f, 0.361825f, 0.584184f, 0.415137f, 0.433020f, 0.415691f, 0.624171f, 0.419735f, 0.608180f, 0.363679f, 0.521604f, 0.509835f, 0.443601f, +0.049872f, 0.055413f, 0.024538f, 0.066070f, 0.056101f, 0.075657f, 0.045643f, 0.063601f, 0.045059f, 0.056511f, 0.032262f, 0.062448f, 0.107606f, 0.128909f, 0.106967f, 0.124333f, +0.041288f, 0.045942f, 0.025215f, 0.057262f, 0.049995f, 0.067519f, 0.050487f, 0.059334f, 0.073327f, 0.092098f, 0.065167f, 0.106389f, 0.072426f, 0.086890f, 0.089365f, 0.087607f, +0.181463f, 0.173645f, 0.089979f, 0.215953f, 0.144530f, 0.167861f, 0.118503f, 0.147186f, 0.155393f, 0.167844f, 0.112128f, 0.193460f, 0.298966f, 0.308452f, 0.299511f, 0.310310f, +0.018116f, 0.019721f, 0.009510f, 0.028145f, 0.033064f, 0.043685f, 0.028702f, 0.043957f, 0.035478f, 0.043593f, 0.027103f, 0.057662f, 0.041904f, 0.049181f, 0.044445f, 0.056779f, +1.266162f, 1.453215f, 0.747718f, 1.362077f, 1.517095f, 2.113355f, 1.481436f, 1.396571f, 1.119390f, 1.450184f, 0.961972f, 1.259746f, 2.143413f, 2.652389f, 2.557375f, 2.011039f, +0.501966f, 0.576958f, 0.367942f, 0.565302f, 0.647410f, 0.903167f, 0.784702f, 0.623912f, 0.872337f, 1.131761f, 0.930509f, 1.027731f, 0.690847f, 0.856135f, 1.023118f, 0.678563f, +2.015591f, 1.992334f, 1.199571f, 1.947770f, 1.709922f, 2.051422f, 1.682756f, 1.414000f, 1.688946f, 1.884415f, 1.462755f, 1.707420f, 2.605397f, 2.776670f, 3.132833f, 2.195894f, +0.293614f, 0.330155f, 0.185003f, 0.370404f, 0.570782f, 0.778987f, 0.594696f, 0.616179f, 0.562657f, 0.714144f, 0.515917f, 0.742561f, 0.532847f, 0.646002f, 0.678337f, 0.586278f, +0.000025f, 0.000028f, 0.000053f, 0.000147f, 0.000023f, 0.000032f, 0.000081f, 0.000116f, 0.000000f, 0.000001f, 0.000002f, 0.000003f, 0.000017f, 0.000020f, 0.000072f, 0.000085f, +0.000013f, 0.000015f, 0.000035f, 0.000081f, 0.000013f, 0.000018f, 0.000057f, 0.000069f, 0.000001f, 0.000001f, 0.000002f, 0.000003f, 0.000007f, 0.000009f, 0.000038f, 0.000038f, +0.000077f, 0.000074f, 0.000164f, 0.000403f, 0.000050f, 0.000059f, 0.000177f, 0.000225f, 0.000001f, 0.000002f, 0.000004f, 0.000008f, 0.000039f, 0.000041f, 0.000169f, 0.000179f, +0.000001f, 0.000001f, 0.000001f, 0.000004f, 0.000001f, 0.000001f, 0.000003f, 0.000005f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000002f, +0.733306f, 0.883131f, 0.413690f, 0.981734f, 0.858233f, 1.254481f, 0.800601f, 0.983222f, 0.622605f, 0.846357f, 0.511134f, 0.871988f, 1.096774f, 1.424123f, 1.250105f, 1.280642f, +0.304309f, 0.367015f, 0.213089f, 0.426498f, 0.383369f, 0.561182f, 0.443898f, 0.459787f, 0.507879f, 0.691400f, 0.517532f, 0.744649f, 0.370031f, 0.481168f, 0.523507f, 0.452316f, +1.738541f, 1.803199f, 0.988438f, 2.090819f, 1.440640f, 1.813564f, 1.354381f, 1.482602f, 1.399051f, 1.637923f, 1.157525f, 1.760169f, 1.985508f, 2.220348f, 2.280741f, 2.082598f, +0.165565f, 0.195348f, 0.099658f, 0.259934f, 0.314382f, 0.450212f, 0.312913f, 0.422368f, 0.304699f, 0.405800f, 0.266899f, 0.500443f, 0.265466f, 0.337707f, 0.322844f, 0.363502f, +0.039616f, 0.049345f, 0.017703f, 0.058845f, 0.033087f, 0.050021f, 0.024449f, 0.042057f, 0.043509f, 0.061172f, 0.028294f, 0.067610f, 0.094222f, 0.126536f, 0.085070f, 0.122065f, +0.026744f, 0.033361f, 0.014835f, 0.041588f, 0.024044f, 0.036402f, 0.022053f, 0.031995f, 0.057739f, 0.081296f, 0.046605f, 0.093926f, 0.051714f, 0.069550f, 0.057955f, 0.070136f, +0.198291f, 0.212713f, 0.089302f, 0.264585f, 0.117260f, 0.152671f, 0.087323f, 0.133890f, 0.206414f, 0.249937f, 0.135278f, 0.288130f, 0.360116f, 0.416508f, 0.327673f, 0.419089f, +0.020013f, 0.024423f, 0.009542f, 0.034861f, 0.027120f, 0.040167f, 0.021382f, 0.040425f, 0.047644f, 0.065627f, 0.033058f, 0.086820f, 0.051028f, 0.067139f, 0.049157f, 0.077524f, +0.514755f, 0.662304f, 0.276094f, 0.620873f, 0.457932f, 0.715115f, 0.406142f, 0.472651f, 0.553204f, 0.803420f, 0.431791f, 0.698034f, 0.960556f, 1.332506f, 1.040923f, 1.010477f, +0.166412f, 0.214422f, 0.110789f, 0.210126f, 0.159355f, 0.249212f, 0.175427f, 0.172186f, 0.351549f, 0.511295f, 0.340588f, 0.464377f, 0.252462f, 0.350729f, 0.339584f, 0.278031f, +1.127243f, 1.249088f, 0.609325f, 1.221357f, 0.710016f, 0.954909f, 0.634629f, 0.658310f, 1.148216f, 1.436150f, 0.903206f, 1.301481f, 1.606180f, 1.918934f, 1.754143f, 1.517823f, +0.166008f, 0.209260f, 0.095004f, 0.234811f, 0.239607f, 0.366585f, 0.226742f, 0.290019f, 0.386714f, 0.550233f, 0.322057f, 0.572225f, 0.332094f, 0.451344f, 0.383982f, 0.409686f, +0.000067f, 0.000084f, 0.000129f, 0.000437f, 0.000046f, 0.000070f, 0.000146f, 0.000256f, 0.000002f, 0.000002f, 0.000004f, 0.000011f, 0.000049f, 0.000066f, 0.000191f, 0.000280f, +0.000029f, 0.000036f, 0.000069f, 0.000197f, 0.000021f, 0.000032f, 0.000084f, 0.000124f, 0.000001f, 0.000002f, 0.000005f, 0.000010f, 0.000017f, 0.000023f, 0.000083f, 0.000102f, +0.000281f, 0.000303f, 0.000544f, 0.001649f, 0.000136f, 0.000178f, 0.000436f, 0.000684f, 0.000006f, 0.000008f, 0.000018f, 0.000039f, 0.000158f, 0.000183f, 0.000616f, 0.000806f, +0.000002f, 0.000003f, 0.000004f, 0.000016f, 0.000002f, 0.000003f, 0.000008f, 0.000015f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000002f, 0.000007f, 0.000011f, +0.575148f, 0.776489f, 0.294698f, 0.863332f, 0.499777f, 0.818937f, 0.423443f, 0.641966f, 0.593608f, 0.904599f, 0.442618f, 0.932153f, 0.948237f, 1.380266f, 0.981644f, 1.241415f, +0.194629f, 0.263143f, 0.123783f, 0.305843f, 0.182048f, 0.298736f, 0.191451f, 0.244802f, 0.394861f, 0.602601f, 0.365451f, 0.649121f, 0.260877f, 0.380285f, 0.335218f, 0.357543f, +1.875786f, 2.181010f, 0.968625f, 2.529324f, 1.154064f, 1.628633f, 0.985424f, 1.331646f, 1.834951f, 2.408240f, 1.378887f, 2.588420f, 2.361430f, 2.960329f, 2.463695f, 2.777144f, +0.180594f, 0.238869f, 0.098732f, 0.317899f, 0.254607f, 0.408738f, 0.230167f, 0.383524f, 0.404017f, 0.603192f, 0.321428f, 0.744000f, 0.319191f, 0.455194f, 0.352567f, 0.490046f, +0.000585f, 0.000709f, 0.000280f, 0.000755f, 0.000573f, 0.000844f, 0.000453f, 0.000634f, 0.000446f, 0.000611f, 0.000311f, 0.000603f, 0.002206f, 0.002884f, 0.002131f, 0.002485f, +0.000790f, 0.000959f, 0.000469f, 0.001068f, 0.000834f, 0.001229f, 0.000818f, 0.000965f, 0.001186f, 0.001625f, 0.001024f, 0.001678f, 0.002423f, 0.003172f, 0.002906f, 0.002858f, +0.003562f, 0.003720f, 0.001717f, 0.004133f, 0.002473f, 0.003135f, 0.001971f, 0.002456f, 0.002578f, 0.003039f, 0.001808f, 0.003130f, 0.010262f, 0.011555f, 0.009993f, 0.010387f, +0.000437f, 0.000519f, 0.000223f, 0.000662f, 0.000695f, 0.001003f, 0.000587f, 0.000902f, 0.000724f, 0.000970f, 0.000537f, 0.001147f, 0.001768f, 0.002265f, 0.001823f, 0.002336f, +0.016567f, 0.020752f, 0.009510f, 0.017380f, 0.017304f, 0.026308f, 0.016426f, 0.015535f, 0.012381f, 0.017506f, 0.010343f, 0.013588f, 0.049044f, 0.066236f, 0.056883f, 0.044874f, +0.010718f, 0.013445f, 0.007637f, 0.011771f, 0.012051f, 0.018348f, 0.014199f, 0.011326f, 0.015746f, 0.022295f, 0.016327f, 0.018091f, 0.025797f, 0.034890f, 0.037138f, 0.024710f, +0.044160f, 0.047639f, 0.025548f, 0.041616f, 0.032658f, 0.042761f, 0.031243f, 0.026337f, 0.031280f, 0.038090f, 0.026335f, 0.030838f, 0.099823f, 0.116107f, 0.116682f, 0.082047f, +0.007908f, 0.009704f, 0.004843f, 0.009728f, 0.013401f, 0.019960f, 0.013573f, 0.014108f, 0.012810f, 0.017744f, 0.011418f, 0.016486f, 0.025096f, 0.033205f, 0.031057f, 0.026928f, +0.000002f, 0.000003f, 0.000005f, 0.000012f, 0.000002f, 0.000003f, 0.000006f, 0.000009f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000003f, 0.000011f, 0.000013f, +0.000002f, 0.000002f, 0.000005f, 0.000011f, 0.000002f, 0.000002f, 0.000007f, 0.000008f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000002f, 0.000009f, 0.000009f, +0.000011f, 0.000012f, 0.000023f, 0.000057f, 0.000006f, 0.000008f, 0.000022f, 0.000028f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000010f, 0.000011f, 0.000042f, 0.000044f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, +0.009855f, 0.012953f, 0.005404f, 0.012866f, 0.010055f, 0.016040f, 0.009118f, 0.011233f, 0.007073f, 0.010494f, 0.005645f, 0.009661f, 0.025776f, 0.036528f, 0.028560f, 0.029351f, +0.006674f, 0.008785f, 0.004543f, 0.009122f, 0.007330f, 0.011710f, 0.008250f, 0.008573f, 0.009416f, 0.013990f, 0.009327f, 0.013463f, 0.014192f, 0.020141f, 0.019518f, 0.016918f, +0.039123f, 0.044286f, 0.021623f, 0.045884f, 0.028262f, 0.038829f, 0.025828f, 0.028364f, 0.026614f, 0.034005f, 0.021405f, 0.032653f, 0.078136f, 0.095363f, 0.087250f, 0.079924f, +0.004580f, 0.005898f, 0.002680f, 0.007012f, 0.007581f, 0.011849f, 0.007335f, 0.009933f, 0.007125f, 0.010356f, 0.006067f, 0.011412f, 0.012842f, 0.017829f, 0.015182f, 0.017148f, +0.000367f, 0.000459f, 0.000208f, 0.000433f, 0.000322f, 0.000490f, 0.000302f, 0.000325f, 0.000295f, 0.000417f, 0.000244f, 0.000364f, 0.001277f, 0.001725f, 0.001464f, 0.001315f, +0.000334f, 0.000419f, 0.000235f, 0.000413f, 0.000316f, 0.000481f, 0.000368f, 0.000334f, 0.000528f, 0.000748f, 0.000541f, 0.000683f, 0.000946f, 0.001280f, 0.001346f, 0.001019f, +0.002387f, 0.002575f, 0.001364f, 0.002530f, 0.001485f, 0.001944f, 0.001403f, 0.001347f, 0.001820f, 0.002216f, 0.001514f, 0.002018f, 0.006347f, 0.007383f, 0.007330f, 0.005869f, +0.000301f, 0.000369f, 0.000182f, 0.000417f, 0.000429f, 0.000639f, 0.000429f, 0.000508f, 0.000525f, 0.000727f, 0.000462f, 0.000760f, 0.001124f, 0.001487f, 0.001374f, 0.001356f, +0.010235f, 0.013244f, 0.006967f, 0.009808f, 0.009578f, 0.015043f, 0.010781f, 0.007854f, 0.008058f, 0.011770f, 0.007983f, 0.008079f, 0.027970f, 0.039022f, 0.038468f, 0.023376f, +0.004466f, 0.005787f, 0.003773f, 0.004480f, 0.004498f, 0.007075f, 0.006285f, 0.003862f, 0.006911f, 0.010110f, 0.008498f, 0.007253f, 0.009921f, 0.013862f, 0.016937f, 0.008681f, +0.029142f, 0.032476f, 0.019993f, 0.025086f, 0.019309f, 0.026118f, 0.021905f, 0.014224f, 0.021747f, 0.027357f, 0.021712f, 0.019584f, 0.060810f, 0.073066f, 0.084288f, 0.045655f, +0.005362f, 0.006798f, 0.003895f, 0.006026f, 0.008142f, 0.012528f, 0.009779f, 0.007830f, 0.009152f, 0.013096f, 0.009673f, 0.010759f, 0.015710f, 0.021473f, 0.023054f, 0.015398f, +0.000017f, 0.000021f, 0.000041f, 0.000086f, 0.000012f, 0.000018f, 0.000048f, 0.000053f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000018f, 0.000024f, 0.000088f, 0.000081f, +0.000010f, 0.000012f, 0.000029f, 0.000052f, 0.000007f, 0.000011f, 0.000037f, 0.000035f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000008f, 0.000011f, 0.000052f, 0.000040f, +0.000091f, 0.000098f, 0.000223f, 0.000423f, 0.000046f, 0.000061f, 0.000188f, 0.000184f, 0.000001f, 0.000002f, 0.000005f, 0.000007f, 0.000075f, 0.000087f, 0.000370f, 0.000303f, +0.000001f, 0.000001f, 0.000002f, 0.000005f, 0.000001f, 0.000001f, 0.000004f, 0.000005f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000005f, 0.000005f, +0.011272f, 0.015306f, 0.007331f, 0.013443f, 0.010304f, 0.016981f, 0.011080f, 0.010516f, 0.008524f, 0.013063f, 0.008066f, 0.010634f, 0.027217f, 0.039844f, 0.035760f, 0.028309f, +0.005148f, 0.007000f, 0.004156f, 0.006427f, 0.005066f, 0.008360f, 0.006761f, 0.005412f, 0.007652f, 0.011745f, 0.008989f, 0.009994f, 0.010106f, 0.014816f, 0.016481f, 0.011004f, +0.047801f, 0.055897f, 0.031328f, 0.051209f, 0.030937f, 0.043909f, 0.033527f, 0.028361f, 0.034258f, 0.045219f, 0.032673f, 0.038394f, 0.088128f, 0.111110f, 0.116693f, 0.082342f, +0.005750f, 0.007649f, 0.003990f, 0.008042f, 0.008528f, 0.013769f, 0.009785f, 0.010206f, 0.009425f, 0.014152f, 0.009517f, 0.013789f, 0.014884f, 0.021347f, 0.020866f, 0.018155f, +0.000472f, 0.000525f, 0.000232f, 0.000625f, 0.000492f, 0.000664f, 0.000400f, 0.000558f, 0.000380f, 0.000477f, 0.000272f, 0.000527f, 0.001639f, 0.001963f, 0.001629f, 0.001893f, +0.000478f, 0.000532f, 0.000292f, 0.000663f, 0.000536f, 0.000724f, 0.000541f, 0.000636f, 0.000756f, 0.000950f, 0.000672f, 0.001097f, 0.001348f, 0.001617f, 0.001663f, 0.001631f, +0.002075f, 0.001986f, 0.001029f, 0.002470f, 0.001531f, 0.001779f, 0.001256f, 0.001560f, 0.001584f, 0.001711f, 0.001143f, 0.001972f, 0.005500f, 0.005675f, 0.005510f, 0.005709f, +0.000248f, 0.000270f, 0.000130f, 0.000385f, 0.000419f, 0.000554f, 0.000364f, 0.000557f, 0.000433f, 0.000532f, 0.000331f, 0.000703f, 0.000923f, 0.001083f, 0.000979f, 0.001250f, +0.019160f, 0.021991f, 0.011315f, 0.020612f, 0.021269f, 0.029628f, 0.020769f, 0.019579f, 0.015096f, 0.019557f, 0.012973f, 0.016989f, 0.052178f, 0.064568f, 0.062256f, 0.048956f, +0.009284f, 0.010671f, 0.006805f, 0.010455f, 0.011093f, 0.015476f, 0.013446f, 0.010691f, 0.014379f, 0.018655f, 0.015338f, 0.016940f, 0.020555f, 0.025473f, 0.030441f, 0.020189f, +0.036850f, 0.036424f, 0.021931f, 0.035610f, 0.028962f, 0.034746f, 0.028502f, 0.023950f, 0.027518f, 0.030703f, 0.023833f, 0.027819f, 0.076626f, 0.081663f, 0.092138f, 0.064582f, +0.006424f, 0.007224f, 0.004048f, 0.008104f, 0.011570f, 0.015791f, 0.012055f, 0.012490f, 0.010971f, 0.013925f, 0.010060f, 0.014479f, 0.018755f, 0.022738f, 0.023876f, 0.020636f, +0.000002f, 0.000002f, 0.000003f, 0.000009f, 0.000001f, 0.000002f, 0.000004f, 0.000006f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000002f, 0.000007f, 0.000008f, +0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000001f, 0.000001f, 0.000004f, 0.000005f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000004f, 0.000004f, +0.000006f, 0.000005f, 0.000012f, 0.000029f, 0.000003f, 0.000004f, 0.000012f, 0.000015f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000005f, 0.000005f, 0.000020f, 0.000021f, +0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.009059f, 0.010910f, 0.005111f, 0.012128f, 0.009823f, 0.014358f, 0.009163f, 0.011253f, 0.006855f, 0.009318f, 0.005627f, 0.009600f, 0.021796f, 0.028302f, 0.024844f, 0.025451f, +0.004595f, 0.005542f, 0.003217f, 0.006440f, 0.005363f, 0.007850f, 0.006210f, 0.006432f, 0.006834f, 0.009304f, 0.006964f, 0.010020f, 0.008988f, 0.011687f, 0.012716f, 0.010987f, +0.025948f, 0.026913f, 0.014753f, 0.031206f, 0.019920f, 0.025077f, 0.018728f, 0.020501f, 0.018609f, 0.021786f, 0.015396f, 0.023412f, 0.047672f, 0.053310f, 0.054760f, 0.050003f, +0.002957f, 0.003489f, 0.001780f, 0.004643f, 0.005203f, 0.007450f, 0.005178f, 0.006990f, 0.004850f, 0.006460f, 0.004249f, 0.007966f, 0.007628f, 0.009704f, 0.009277f, 0.010445f, +0.000348f, 0.000434f, 0.000156f, 0.000517f, 0.000270f, 0.000408f, 0.000199f, 0.000343f, 0.000341f, 0.000479f, 0.000222f, 0.000530f, 0.001333f, 0.001790f, 0.001203f, 0.001727f, +0.000287f, 0.000359f, 0.000159f, 0.000447f, 0.000239f, 0.000362f, 0.000220f, 0.000319f, 0.000553f, 0.000779f, 0.000446f, 0.000900f, 0.000894f, 0.001203f, 0.001002f, 0.001213f, +0.002107f, 0.002260f, 0.000949f, 0.002811f, 0.001154f, 0.001503f, 0.000859f, 0.001318f, 0.001954f, 0.002366f, 0.001281f, 0.002728f, 0.006155f, 0.007118f, 0.005600f, 0.007163f, +0.000254f, 0.000311f, 0.000121f, 0.000443f, 0.000319f, 0.000473f, 0.000252f, 0.000476f, 0.000540f, 0.000744f, 0.000375f, 0.000984f, 0.001044f, 0.001373f, 0.001005f, 0.001586f, +0.007236f, 0.009310f, 0.003881f, 0.008728f, 0.005964f, 0.009313f, 0.005289f, 0.006156f, 0.006931f, 0.010065f, 0.005409f, 0.008745f, 0.021722f, 0.030133f, 0.023539f, 0.022851f, +0.002859f, 0.003684f, 0.001904f, 0.003610f, 0.002537f, 0.003967f, 0.002792f, 0.002741f, 0.005383f, 0.007829f, 0.005215f, 0.007111f, 0.006978f, 0.009694f, 0.009386f, 0.007685f, +0.019144f, 0.021214f, 0.010348f, 0.020743f, 0.011172f, 0.015025f, 0.009986f, 0.010358f, 0.017379f, 0.021737f, 0.013671f, 0.019699f, 0.043882f, 0.052427f, 0.047925f, 0.041468f, +0.003374f, 0.004253f, 0.001931f, 0.004773f, 0.004512f, 0.006903f, 0.004270f, 0.005461f, 0.007005f, 0.009967f, 0.005834f, 0.010365f, 0.010859f, 0.014758f, 0.012555f, 0.013396f, +0.000004f, 0.000005f, 0.000007f, 0.000024f, 0.000002f, 0.000004f, 0.000007f, 0.000013f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000004f, 0.000006f, 0.000017f, 0.000025f, +0.000002f, 0.000002f, 0.000005f, 0.000013f, 0.000001f, 0.000002f, 0.000005f, 0.000008f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000003f, 0.000009f, 0.000011f, +0.000019f, 0.000020f, 0.000036f, 0.000110f, 0.000008f, 0.000011f, 0.000027f, 0.000042f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000017f, 0.000020f, 0.000066f, 0.000087f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, +0.006600f, 0.008911f, 0.003382f, 0.009908f, 0.005314f, 0.008707f, 0.004502f, 0.006825f, 0.006071f, 0.009252f, 0.004527f, 0.009533f, 0.017506f, 0.025482f, 0.018122f, 0.022918f, +0.002730f, 0.003691f, 0.001736f, 0.004290f, 0.002366f, 0.003882f, 0.002488f, 0.003181f, 0.004936f, 0.007533f, 0.004568f, 0.008114f, 0.005886f, 0.008581f, 0.007564f, 0.008068f, +0.026007f, 0.030239f, 0.013430f, 0.035068f, 0.014824f, 0.020920f, 0.012658f, 0.017105f, 0.022673f, 0.029757f, 0.017038f, 0.031983f, 0.052669f, 0.066027f, 0.054950f, 0.061941f, +0.002997f, 0.003964f, 0.001638f, 0.005275f, 0.003914f, 0.006283f, 0.003538f, 0.005896f, 0.005974f, 0.008920f, 0.004753f, 0.011002f, 0.008520f, 0.012151f, 0.009411f, 0.013081f, +0.048876f, 0.059269f, 0.023377f, 0.063145f, 0.038519f, 0.056692f, 0.030464f, 0.042585f, 0.032304f, 0.044217f, 0.022484f, 0.043660f, 0.111628f, 0.145947f, 0.107869f, 0.125782f, +0.079289f, 0.096289f, 0.047071f, 0.107239f, 0.067262f, 0.099141f, 0.066029f, 0.077848f, 0.103012f, 0.141205f, 0.088994f, 0.145752f, 0.147225f, 0.192767f, 0.176588f, 0.173668f, +0.295126f, 0.308219f, 0.142255f, 0.342511f, 0.164678f, 0.208740f, 0.131255f, 0.163546f, 0.184877f, 0.217940f, 0.129681f, 0.224460f, 0.514680f, 0.579535f, 0.501230f, 0.520962f, +0.026937f, 0.032002f, 0.013746f, 0.040811f, 0.034443f, 0.049665f, 0.029064f, 0.044654f, 0.038590f, 0.051750f, 0.028658f, 0.061164f, 0.065953f, 0.084481f, 0.068001f, 0.087150f, +0.828230f, 1.037454f, 0.475456f, 0.868877f, 0.695237f, 1.056988f, 0.659953f, 0.624135f, 0.535644f, 0.757347f, 0.447474f, 0.587859f, 1.484100f, 2.004341f, 1.721321f, 1.357916f, +0.643406f, 0.807109f, 0.458458f, 0.706620f, 0.581365f, 0.885145f, 0.684990f, 0.546371f, 0.817952f, 1.158179f, 0.848154f, 0.939762f, 0.937321f, 1.267726f, 1.349405f, 0.897824f, +2.187975f, 2.360366f, 1.265832f, 2.061925f, 1.300394f, 1.702671f, 1.244027f, 1.048680f, 1.341185f, 1.633153f, 1.129158f, 1.322235f, 2.993709f, 3.482067f, 3.499315f, 2.460606f, +0.291395f, 0.357602f, 0.178482f, 0.358488f, 0.396857f, 0.591113f, 0.401946f, 0.417797f, 0.408490f, 0.565850f, 0.364106f, 0.525733f, 0.559761f, 0.740648f, 0.692717f, 0.600619f, +0.000058f, 0.000070f, 0.000119f, 0.000328f, 0.000037f, 0.000055f, 0.000127f, 0.000181f, 0.000001f, 0.000001f, 0.000002f, 0.000005f, 0.000041f, 0.000054f, 0.000169f, 0.000202f, +0.000060f, 0.000073f, 0.000152f, 0.000355f, 0.000042f, 0.000061f, 0.000175f, 0.000211f, 0.000002f, 0.000002f, 0.000006f, 0.000010f, 0.000034f, 0.000045f, 0.000176f, 0.000177f, +0.000293f, 0.000307f, 0.000606f, 0.001493f, 0.000134f, 0.000170f, 0.000458f, 0.000584f, 0.000004f, 0.000005f, 0.000012f, 0.000021f, 0.000158f, 0.000178f, 0.000659f, 0.000701f, +0.000002f, 0.000002f, 0.000004f, 0.000013f, 0.000002f, 0.000003f, 0.000007f, 0.000011f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000006f, 0.000008f, +0.582809f, 0.766025f, 0.319614f, 0.760904f, 0.477865f, 0.762326f, 0.433337f, 0.533883f, 0.361982f, 0.537037f, 0.288881f, 0.494401f, 0.922686f, 1.307559f, 1.022335f, 1.050653f, +0.473920f, 0.623808f, 0.322597f, 0.647742f, 0.418278f, 0.668235f, 0.470805f, 0.489215f, 0.578606f, 0.859666f, 0.573153f, 0.827312f, 0.609991f, 0.865684f, 0.838915f, 0.727147f, +2.293001f, 2.595614f, 1.267299f, 2.689247f, 1.331169f, 1.828891f, 1.216547f, 1.335972f, 1.349851f, 1.724737f, 1.085657f, 1.656158f, 2.771957f, 3.383086f, 3.095287f, 2.835406f, +0.199642f, 0.257081f, 0.116817f, 0.305663f, 0.265583f, 0.415085f, 0.256966f, 0.347959f, 0.268774f, 0.390666f, 0.228862f, 0.430494f, 0.338836f, 0.470432f, 0.400574f, 0.452461f, +0.046959f, 0.058826f, 0.026633f, 0.055417f, 0.033157f, 0.050413f, 0.031096f, 0.033484f, 0.032698f, 0.046235f, 0.026987f, 0.040368f, 0.099004f, 0.133718f, 0.113448f, 0.101901f, +0.051375f, 0.064451f, 0.036167f, 0.063470f, 0.039047f, 0.059454f, 0.045453f, 0.041280f, 0.070319f, 0.099575f, 0.072038f, 0.090883f, 0.088059f, 0.119107f, 0.125248f, 0.094884f, +0.302882f, 0.326769f, 0.173122f, 0.321087f, 0.151418f, 0.198273f, 0.143113f, 0.137361f, 0.199894f, 0.243427f, 0.166269f, 0.221686f, 0.487595f, 0.567175f, 0.563090f, 0.450827f, +0.028408f, 0.034865f, 0.017191f, 0.039315f, 0.032544f, 0.048477f, 0.032565f, 0.038541f, 0.042877f, 0.059398f, 0.037759f, 0.062077f, 0.064208f, 0.084962f, 0.078503f, 0.077500f, +0.783695f, 1.014099f, 0.533488f, 0.750995f, 0.589396f, 0.925676f, 0.663446f, 0.483320f, 0.533978f, 0.779933f, 0.528972f, 0.535306f, 1.296330f, 1.808585f, 1.782921f, 1.083446f, +0.410575f, 0.532053f, 0.346917f, 0.411885f, 0.332380f, 0.522775f, 0.464395f, 0.285335f, 0.549904f, 0.804358f, 0.676163f, 0.577110f, 0.552143f, 0.771443f, 0.942592f, 0.483100f, +2.211472f, 2.464526f, 1.517166f, 1.903680f, 1.177583f, 1.592805f, 1.335871f, 0.867445f, 1.428166f, 1.796519f, 1.425813f, 1.286117f, 2.793216f, 3.356193f, 3.871648f, 2.097100f, +0.302657f, 0.383693f, 0.219827f, 0.340115f, 0.369301f, 0.568241f, 0.443540f, 0.355136f, 0.446994f, 0.639640f, 0.472460f, 0.525493f, 0.536695f, 0.733587f, 0.787587f, 0.526025f, +0.000672f, 0.000845f, 0.001636f, 0.003480f, 0.000388f, 0.000593f, 0.001565f, 0.001723f, 0.000010f, 0.000014f, 0.000036f, 0.000055f, 0.000437f, 0.000592f, 0.002150f, 0.001974f, +0.000467f, 0.000589f, 0.001413f, 0.002536f, 0.000291f, 0.000445f, 0.001455f, 0.001351f, 0.000014f, 0.000020f, 0.000061f, 0.000079f, 0.000247f, 0.000336f, 0.001510f, 0.001170f, +0.003631f, 0.003933f, 0.008914f, 0.016905f, 0.001487f, 0.001955f, 0.006037f, 0.005925f, 0.000052f, 0.000063f, 0.000185f, 0.000253f, 0.001804f, 0.002106f, 0.008946f, 0.007324f, +0.000025f, 0.000030f, 0.000064f, 0.000149f, 0.000023f, 0.000034f, 0.000099f, 0.000120f, 0.000001f, 0.000001f, 0.000003f, 0.000005f, 0.000017f, 0.000023f, 0.000090f, 0.000091f, +1.021033f, 1.386346f, 0.663984f, 1.217659f, 0.750060f, 1.236081f, 0.806557f, 0.765455f, 0.668115f, 1.023962f, 0.632268f, 0.833539f, 1.492187f, 2.184467f, 1.960562f, 1.552069f, +0.559925f, 0.761361f, 0.451963f, 0.699052f, 0.442759f, 0.730714f, 0.590965f, 0.473026f, 0.720209f, 1.105403f, 0.845988f, 0.940648f, 0.665279f, 0.975338f, 1.084968f, 0.724411f, +4.291018f, 5.017776f, 2.812244f, 4.596942f, 2.231860f, 3.167647f, 2.418692f, 2.046037f, 2.661295f, 3.512731f, 2.538153f, 2.982572f, 4.788490f, 6.037263f, 6.340607f, 4.474138f, +0.383918f, 0.510705f, 0.266385f, 0.536921f, 0.457578f, 0.738781f, 0.524998f, 0.547614f, 0.544534f, 0.817632f, 0.549831f, 0.796684f, 0.601493f, 0.862688f, 0.843224f, 0.733677f, +0.062173f, 0.069081f, 0.030590f, 0.082367f, 0.052073f, 0.070224f, 0.042365f, 0.059033f, 0.043321f, 0.054332f, 0.031018f, 0.060040f, 0.130622f, 0.156482f, 0.129847f, 0.150927f, +0.075539f, 0.084053f, 0.046132f, 0.104764f, 0.068102f, 0.091973f, 0.068772f, 0.080824f, 0.103463f, 0.129949f, 0.091950f, 0.150113f, 0.129025f, 0.154793f, 0.159201f, 0.156070f, +0.270865f, 0.259196f, 0.134308f, 0.322348f, 0.160624f, 0.186554f, 0.131699f, 0.163576f, 0.178885f, 0.193218f, 0.129079f, 0.222707f, 0.434533f, 0.448320f, 0.435324f, 0.451021f, +0.024070f, 0.026201f, 0.012636f, 0.037394f, 0.032707f, 0.043214f, 0.028392f, 0.043483f, 0.036353f, 0.044668f, 0.027772f, 0.059084f, 0.054212f, 0.063627f, 0.057499f, 0.073457f, +1.508767f, 1.731662f, 0.890987f, 1.623061f, 1.345969f, 1.874971f, 1.314331f, 1.239040f, 1.028707f, 1.332703f, 0.884042f, 1.157693f, 2.486993f, 3.077555f, 2.967311f, 2.333399f, +0.877823f, 1.008965f, 0.643444f, 0.988582f, 0.842948f, 1.175951f, 1.021706f, 0.812352f, 1.176504f, 1.526385f, 1.254960f, 1.386081f, 1.176385f, 1.457839f, 1.742182f, 1.155467f, +2.875770f, 2.842588f, 1.711504f, 2.779006f, 1.816423f, 2.179193f, 1.787565f, 1.502070f, 1.858423f, 2.073507f, 1.609535f, 1.878751f, 3.619605f, 3.857550f, 4.352357f, 3.050694f, +0.372879f, 0.419284f, 0.234948f, 0.470399f, 0.539697f, 0.736563f, 0.562308f, 0.582622f, 0.551077f, 0.699446f, 0.505298f, 0.727278f, 0.658914f, 0.798841f, 0.838826f, 0.724987f, +0.000062f, 0.000070f, 0.000132f, 0.000364f, 0.000043f, 0.000058f, 0.000150f, 0.000213f, 0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000041f, 0.000049f, 0.000173f, 0.000206f, +0.000048f, 0.000054f, 0.000127f, 0.000294f, 0.000036f, 0.000048f, 0.000155f, 0.000186f, 0.000001f, 0.000002f, 0.000005f, 0.000009f, 0.000025f, 0.000031f, 0.000135f, 0.000135f, +0.000228f, 0.000219f, 0.000486f, 0.001193f, 0.000111f, 0.000129f, 0.000391f, 0.000496f, 0.000003f, 0.000004f, 0.000010f, 0.000018f, 0.000113f, 0.000117f, 0.000486f, 0.000515f, +0.000001f, 0.000002f, 0.000003f, 0.000010f, 0.000002f, 0.000002f, 0.000006f, 0.000009f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000005f, 0.000006f, +0.843841f, 1.016250f, 0.476048f, 1.129716f, 0.735309f, 1.074802f, 0.685931f, 0.842396f, 0.552542f, 0.751114f, 0.453615f, 0.773861f, 1.228933f, 1.595726f, 1.400740f, 1.434957f, +0.513913f, 0.619810f, 0.359861f, 0.720264f, 0.482037f, 0.705614f, 0.558144f, 0.578122f, 0.661472f, 0.900495f, 0.674045f, 0.969846f, 0.608482f, 0.791237f, 0.860860f, 0.743793f, +2.395406f, 2.484494f, 1.361895f, 2.880784f, 1.477877f, 1.860442f, 1.389389f, 1.520925f, 1.486637f, 1.740462f, 1.229990f, 1.870362f, 2.663798f, 2.978864f, 3.059888f, 2.794055f, +0.203049f, 0.239575f, 0.122221f, 0.318784f, 0.287065f, 0.411092f, 0.285723f, 0.385668f, 0.288191f, 0.383815f, 0.252440f, 0.473332f, 0.317014f, 0.403282f, 0.385533f, 0.434086f, +0.090902f, 0.113226f, 0.040622f, 0.135024f, 0.056527f, 0.085457f, 0.041770f, 0.071851f, 0.076995f, 0.108252f, 0.050070f, 0.119644f, 0.210520f, 0.282719f, 0.190071f, 0.272730f, +0.090062f, 0.112341f, 0.049955f, 0.140046f, 0.060284f, 0.091269f, 0.055292f, 0.080218f, 0.149950f, 0.211129f, 0.121037f, 0.243932f, 0.169570f, 0.228055f, 0.190032f, 0.229976f, +0.544789f, 0.584411f, 0.245350f, 0.726925f, 0.239862f, 0.312299f, 0.178624f, 0.273880f, 0.437361f, 0.529580f, 0.286636f, 0.610507f, 0.963391f, 1.114253f, 0.876598f, 1.121156f, +0.048942f, 0.059725f, 0.023336f, 0.085253f, 0.049378f, 0.073135f, 0.038931f, 0.073603f, 0.089856f, 0.123772f, 0.062347f, 0.163743f, 0.121510f, 0.159872f, 0.117055f, 0.184603f, +1.128999f, 1.452613f, 0.605550f, 1.361744f, 0.747795f, 1.167771f, 0.663223f, 0.771831f, 0.935740f, 1.358979f, 0.730372f, 1.180719f, 2.051402f, 2.845756f, 2.223038f, 2.158017f, +0.535643f, 0.690177f, 0.356605f, 0.676349f, 0.381897f, 0.597241f, 0.420415f, 0.412647f, 0.872680f, 1.269231f, 0.845471f, 1.152761f, 0.791268f, 1.099256f, 1.064326f, 0.871406f, +2.960255f, 3.280231f, 1.600149f, 3.207407f, 1.388252f, 1.867078f, 1.240853f, 1.287155f, 2.325477f, 2.908630f, 1.829260f, 2.635884f, 4.107156f, 4.906898f, 4.485512f, 3.881220f, +0.388043f, 0.489144f, 0.222071f, 0.548869f, 0.417003f, 0.637991f, 0.394613f, 0.504737f, 0.697136f, 0.991916f, 0.580578f, 1.031561f, 0.755870f, 1.027292f, 0.873972f, 0.932475f, +0.000305f, 0.000382f, 0.000586f, 0.001991f, 0.000156f, 0.000236f, 0.000494f, 0.000868f, 0.000006f, 0.000008f, 0.000016f, 0.000038f, 0.000218f, 0.000294f, 0.000846f, 0.001241f, +0.000192f, 0.000241f, 0.000458f, 0.001314f, 0.000106f, 0.000160f, 0.000416f, 0.000617f, 0.000007f, 0.000010f, 0.000024f, 0.000050f, 0.000112f, 0.000151f, 0.000538f, 0.000666f, +0.001534f, 0.001652f, 0.002967f, 0.008988f, 0.000553f, 0.000723f, 0.001770f, 0.002774f, 0.000027f, 0.000032f, 0.000075f, 0.000163f, 0.000837f, 0.000972f, 0.003271f, 0.004278f, +0.000010f, 0.000012f, 0.000020f, 0.000076f, 0.000008f, 0.000012f, 0.000028f, 0.000054f, 0.000000f, 0.000001f, 0.000001f, 0.000003f, 0.000008f, 0.000010f, 0.000031f, 0.000051f, +1.218191f, 1.644639f, 0.624184f, 1.828578f, 0.788135f, 1.291441f, 0.667758f, 1.012363f, 0.969644f, 1.477639f, 0.723005f, 1.522648f, 1.955634f, 2.846646f, 2.024531f, 2.560282f, +0.604981f, 0.817948f, 0.384764f, 0.950677f, 0.421316f, 0.691371f, 0.443080f, 0.566549f, 0.946577f, 1.444578f, 0.876074f, 1.556098f, 0.789596f, 1.151010f, 1.014605f, 1.082177f, +4.757045f, 5.531101f, 2.456458f, 6.414434f, 2.179078f, 3.075147f, 1.860655f, 2.514384f, 3.588851f, 4.710106f, 2.696868f, 5.062509f, 5.831288f, 7.310202f, 6.083818f, 6.857845f, +0.407660f, 0.539204f, 0.222869f, 0.717599f, 0.427910f, 0.686953f, 0.386835f, 0.644578f, 0.703347f, 1.050089f, 0.559569f, 1.295220f, 0.701583f, 1.000519f, 0.774944f, 1.077124f, +0.075643f, 0.091728f, 0.036179f, 0.097727f, 0.064694f, 0.095218f, 0.051165f, 0.071523f, 0.052429f, 0.071764f, 0.036492f, 0.070861f, 0.158951f, 0.207820f, 0.153599f, 0.179106f, +0.080989f, 0.098353f, 0.048080f, 0.109537f, 0.074559f, 0.109896f, 0.073192f, 0.086293f, 0.110343f, 0.151254f, 0.095328f, 0.156125f, 0.138359f, 0.181159f, 0.165954f, 0.163210f, +0.455765f, 0.475984f, 0.219686f, 0.528941f, 0.275986f, 0.349830f, 0.219972f, 0.274089f, 0.299409f, 0.352954f, 0.210019f, 0.363514f, 0.731287f, 0.823437f, 0.712178f, 0.740213f, +0.039308f, 0.046699f, 0.020059f, 0.059553f, 0.054543f, 0.078649f, 0.046026f, 0.070715f, 0.059055f, 0.079193f, 0.043856f, 0.093600f, 0.088548f, 0.113423f, 0.091297f, 0.117006f, +2.226413f, 2.788840f, 1.278100f, 2.335679f, 2.028182f, 3.083498f, 1.925249f, 1.820758f, 1.510010f, 2.135005f, 1.261453f, 1.657207f, 3.670587f, 4.957286f, 4.257299f, 3.358498f, +1.141498f, 1.431931f, 0.813373f, 1.253649f, 1.119329f, 1.704211f, 1.318843f, 1.051953f, 1.521833f, 2.154839f, 1.578024f, 1.748466f, 1.530015f, 2.069345f, 2.202671f, 1.465543f, +5.868896f, 6.331307f, 3.395395f, 5.530785f, 3.785366f, 4.956370f, 3.621285f, 3.052643f, 3.772697f, 4.593989f, 3.176274f, 3.719389f, 7.388242f, 8.593471f, 8.636039f, 6.072585f, +0.738564f, 0.906372f, 0.452378f, 0.908619f, 1.091589f, 1.625910f, 1.105589f, 1.149188f, 1.085769f, 1.504031f, 0.967795f, 1.397400f, 1.305351f, 1.727173f, 1.615401f, 1.400629f, +0.000043f, 0.000052f, 0.000088f, 0.000243f, 0.000030f, 0.000044f, 0.000102f, 0.000146f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000028f, 0.000036f, 0.000115f, 0.000137f, +0.000029f, 0.000036f, 0.000074f, 0.000173f, 0.000022f, 0.000033f, 0.000093f, 0.000112f, 0.000001f, 0.000001f, 0.000003f, 0.000005f, 0.000015f, 0.000020f, 0.000079f, 0.000080f, +0.000216f, 0.000227f, 0.000448f, 0.001102f, 0.000107f, 0.000137f, 0.000367f, 0.000468f, 0.000003f, 0.000004f, 0.000009f, 0.000016f, 0.000107f, 0.000121f, 0.000448f, 0.000476f, +0.000001f, 0.000002f, 0.000003f, 0.000009f, 0.000002f, 0.000002f, 0.000006f, 0.000009f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000004f, 0.000005f, +0.970578f, 1.275696f, 0.532268f, 1.267167f, 0.863630f, 1.377728f, 0.783157f, 0.964871f, 0.632179f, 0.937902f, 0.504513f, 0.863441f, 1.413759f, 2.003470f, 1.566444f, 1.609834f, +0.520888f, 0.685630f, 0.354568f, 0.711937f, 0.498911f, 0.797054f, 0.561564f, 0.583523f, 0.666917f, 0.990873f, 0.660631f, 0.953581f, 0.616851f, 0.875419f, 0.848350f, 0.735325f, +3.810373f, 4.313239f, 2.105922f, 4.468833f, 2.400575f, 3.298148f, 2.193871f, 2.409238f, 2.352330f, 3.005628f, 1.891931f, 2.886118f, 4.238063f, 5.172422f, 4.732404f, 4.335070f, +0.313479f, 0.403669f, 0.183427f, 0.479953f, 0.452560f, 0.707313f, 0.437876f, 0.592930f, 0.442581f, 0.643296f, 0.376860f, 0.708879f, 0.489511f, 0.679626f, 0.578704f, 0.653664f, +0.041395f, 0.051856f, 0.023478f, 0.048851f, 0.031719f, 0.048227f, 0.029747f, 0.032032f, 0.030228f, 0.042742f, 0.024948f, 0.037318f, 0.080297f, 0.108452f, 0.092012f, 0.082647f, +0.029889f, 0.037497f, 0.021041f, 0.036926f, 0.024653f, 0.037538f, 0.028698f, 0.026063f, 0.042903f, 0.060753f, 0.043952f, 0.055449f, 0.047136f, 0.063756f, 0.067043f, 0.050790f, +0.266418f, 0.287429f, 0.152280f, 0.282431f, 0.144539f, 0.189266f, 0.136611f, 0.131121f, 0.184391f, 0.224547f, 0.153373f, 0.204492f, 0.394608f, 0.459012f, 0.455706f, 0.364852f, +0.023612f, 0.028979f, 0.014288f, 0.032677f, 0.029354f, 0.043726f, 0.029373f, 0.034763f, 0.037373f, 0.051773f, 0.032912f, 0.054108f, 0.049100f, 0.064972f, 0.060032f, 0.059265f, +1.199936f, 1.552713f, 0.816836f, 1.149867f, 0.979348f, 1.538115f, 1.102389f, 0.803091f, 0.857400f, 1.252326f, 0.849361f, 0.859532f, 1.826181f, 2.547811f, 2.511657f, 1.526285f, +0.414896f, 0.537651f, 0.350567f, 0.416219f, 0.364501f, 0.573297f, 0.509275f, 0.312910f, 0.582749f, 0.852402f, 0.716550f, 0.611581f, 0.513352f, 0.717245f, 0.876370f, 0.449159f, +3.378714f, 3.765333f, 2.317945f, 2.908466f, 1.952453f, 2.640897f, 2.214896f, 1.438239f, 2.288221f, 2.878398f, 2.284451f, 2.060629f, 3.926377f, 4.717746f, 5.442311f, 2.947859f, +0.436931f, 0.553919f, 0.317354f, 0.491009f, 0.578578f, 0.890254f, 0.694887f, 0.556386f, 0.676727f, 0.968384f, 0.715282f, 0.795571f, 0.712866f, 0.974388f, 1.046114f, 0.698693f, +0.000283f, 0.000356f, 0.000689f, 0.001467f, 0.000178f, 0.000271f, 0.000716f, 0.000788f, 0.000004f, 0.000006f, 0.000016f, 0.000024f, 0.000169f, 0.000230f, 0.000834f, 0.000766f, +0.000130f, 0.000164f, 0.000393f, 0.000705f, 0.000088f, 0.000134f, 0.000439f, 0.000408f, 0.000004f, 0.000006f, 0.000018f, 0.000023f, 0.000063f, 0.000086f, 0.000386f, 0.000299f, +0.001527f, 0.001654f, 0.003749f, 0.007109f, 0.000679f, 0.000892f, 0.002755f, 0.002704f, 0.000023f, 0.000028f, 0.000082f, 0.000111f, 0.000698f, 0.000815f, 0.003461f, 0.002834f, +0.000010f, 0.000012f, 0.000025f, 0.000059f, 0.000010f, 0.000015f, 0.000043f, 0.000052f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000006f, 0.000008f, 0.000033f, 0.000033f, +0.968501f, 1.315018f, 0.629822f, 1.155010f, 0.772103f, 1.272407f, 0.830260f, 0.787950f, 0.664600f, 1.018575f, 0.628942f, 0.829154f, 1.302269f, 1.906440f, 1.711032f, 1.354530f, +0.350530f, 0.476635f, 0.282943f, 0.437627f, 0.300803f, 0.496434f, 0.401491f, 0.321365f, 0.472828f, 0.725713f, 0.555404f, 0.617549f, 0.383192f, 0.561782f, 0.624927f, 0.417252f, +4.061437f, 4.749312f, 2.661781f, 4.350994f, 2.292479f, 3.253682f, 2.484385f, 2.101608f, 2.641566f, 3.486690f, 2.519337f, 2.960461f, 4.169995f, 5.257472f, 5.521635f, 3.896246f, +0.343361f, 0.456754f, 0.238244f, 0.480200f, 0.444115f, 0.717045f, 0.509552f, 0.531503f, 0.510724f, 0.766865f, 0.515692f, 0.747218f, 0.494949f, 0.709877f, 0.693861f, 0.603719f, +0.010920f, 0.012134f, 0.005373f, 0.014467f, 0.009926f, 0.013386f, 0.008075f, 0.011252f, 0.007980f, 0.010008f, 0.005713f, 0.011059f, 0.021109f, 0.025288f, 0.020984f, 0.024390f, +0.008757f, 0.009744f, 0.005348f, 0.012145f, 0.008567f, 0.011570f, 0.008652f, 0.010168f, 0.012578f, 0.015798f, 0.011178f, 0.018249f, 0.013761f, 0.016510f, 0.016980f, 0.016646f, +0.047473f, 0.045428f, 0.023539f, 0.056496f, 0.030551f, 0.035483f, 0.025049f, 0.031112f, 0.032879f, 0.035513f, 0.023724f, 0.040933f, 0.070070f, 0.072293f, 0.070198f, 0.072729f, +0.003986f, 0.004339f, 0.002093f, 0.006193f, 0.005878f, 0.007766f, 0.005103f, 0.007815f, 0.006314f, 0.007758f, 0.004823f, 0.010261f, 0.008260f, 0.009695f, 0.008761f, 0.011193f, +0.460295f, 0.528296f, 0.271822f, 0.495163f, 0.445623f, 0.620765f, 0.435149f, 0.410221f, 0.329120f, 0.426380f, 0.282837f, 0.370387f, 0.698081f, 0.863848f, 0.832903f, 0.654968f, +0.176749f, 0.203154f, 0.129557f, 0.199050f, 0.184191f, 0.256955f, 0.223251f, 0.177506f, 0.248423f, 0.322301f, 0.264989f, 0.292676f, 0.217930f, 0.270070f, 0.322745f, 0.214054f, +0.875442f, 0.865340f, 0.521016f, 0.845985f, 0.600080f, 0.719926f, 0.590546f, 0.496229f, 0.593290f, 0.661954f, 0.513834f, 0.599779f, 1.013799f, 1.080444f, 1.219032f, 0.854455f, +0.107259f, 0.120608f, 0.067583f, 0.135311f, 0.168475f, 0.229930f, 0.175533f, 0.181874f, 0.166237f, 0.210993f, 0.152427f, 0.219389f, 0.174386f, 0.211419f, 0.222001f, 0.191873f, +0.000005f, 0.000006f, 0.000011f, 0.000031f, 0.000004f, 0.000005f, 0.000014f, 0.000019f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000004f, 0.000013f, 0.000016f, +0.000003f, 0.000003f, 0.000007f, 0.000016f, 0.000002f, 0.000003f, 0.000009f, 0.000011f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000007f, 0.000007f, +0.000019f, 0.000018f, 0.000041f, 0.000100f, 0.000010f, 0.000012f, 0.000036f, 0.000045f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000009f, 0.000009f, 0.000037f, 0.000040f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, +0.159487f, 0.192072f, 0.089973f, 0.213517f, 0.150817f, 0.220450f, 0.140690f, 0.172782f, 0.109516f, 0.148874f, 0.089908f, 0.153382f, 0.213702f, 0.277485f, 0.243578f, 0.249528f, +0.064104f, 0.077314f, 0.044888f, 0.089844f, 0.065253f, 0.095518f, 0.075555f, 0.078260f, 0.086529f, 0.117795f, 0.088173f, 0.126867f, 0.069833f, 0.090808f, 0.098798f, 0.085363f, +0.451753f, 0.468555f, 0.256842f, 0.543292f, 0.302468f, 0.380765f, 0.284358f, 0.311279f, 0.294020f, 0.344220f, 0.243261f, 0.369911f, 0.462212f, 0.516881f, 0.530940f, 0.484814f, +0.036184f, 0.042693f, 0.021780f, 0.056808f, 0.055516f, 0.079501f, 0.055256f, 0.074584f, 0.053857f, 0.071728f, 0.047176f, 0.088456f, 0.051977f, 0.066121f, 0.063211f, 0.071172f, +0.032611f, 0.040619f, 0.014573f, 0.048439f, 0.022007f, 0.033270f, 0.016262f, 0.027973f, 0.028967f, 0.040726f, 0.018837f, 0.045012f, 0.069486f, 0.093317f, 0.062737f, 0.090020f, +0.021324f, 0.026599f, 0.011828f, 0.033158f, 0.015490f, 0.023451f, 0.014207f, 0.020612f, 0.037232f, 0.052423f, 0.030053f, 0.060568f, 0.036939f, 0.049680f, 0.041397f, 0.050098f, +0.195018f, 0.209201f, 0.087828f, 0.260217f, 0.093181f, 0.121321f, 0.069391f, 0.106396f, 0.164186f, 0.198805f, 0.107603f, 0.229185f, 0.317297f, 0.366984f, 0.288711f, 0.369258f, +0.016555f, 0.020202f, 0.007893f, 0.028837f, 0.018126f, 0.026846f, 0.014291f, 0.027018f, 0.031874f, 0.043904f, 0.022116f, 0.058083f, 0.037815f, 0.049754f, 0.036429f, 0.057451f, +0.703495f, 0.905143f, 0.377327f, 0.848522f, 0.505672f, 0.789667f, 0.448483f, 0.521926f, 0.611465f, 0.888033f, 0.477266f, 0.771548f, 1.176077f, 1.631483f, 1.274476f, 1.237200f, +0.220282f, 0.283833f, 0.146653f, 0.278147f, 0.170438f, 0.266545f, 0.187629f, 0.184162f, 0.376363f, 0.547385f, 0.364629f, 0.497154f, 0.299394f, 0.415929f, 0.402712f, 0.329717f, +1.840585f, 2.039535f, 0.994918f, 1.994256f, 0.936729f, 1.259819f, 0.837271f, 0.868514f, 1.516310f, 1.896550f, 1.192755f, 1.718708f, 2.349554f, 2.807058f, 2.565998f, 2.220304f, +0.227982f, 0.287380f, 0.130470f, 0.322469f, 0.265875f, 0.406774f, 0.251599f, 0.321813f, 0.429522f, 0.611144f, 0.357708f, 0.635570f, 0.408586f, 0.555304f, 0.472427f, 0.504051f, +0.000052f, 0.000065f, 0.000100f, 0.000342f, 0.000029f, 0.000044f, 0.000092f, 0.000162f, 0.000001f, 0.000001f, 0.000003f, 0.000007f, 0.000034f, 0.000046f, 0.000133f, 0.000196f, +0.000022f, 0.000027f, 0.000052f, 0.000149f, 0.000013f, 0.000020f, 0.000051f, 0.000076f, 0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000012f, 0.000016f, 0.000056f, 0.000069f, +0.000263f, 0.000283f, 0.000508f, 0.001538f, 0.000103f, 0.000134f, 0.000329f, 0.000515f, 0.000005f, 0.000006f, 0.000013f, 0.000029f, 0.000132f, 0.000153f, 0.000515f, 0.000674f, +0.000002f, 0.000002f, 0.000003f, 0.000012f, 0.000001f, 0.000002f, 0.000005f, 0.000009f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000005f, 0.000008f, +0.470253f, 0.634874f, 0.240951f, 0.705879f, 0.330169f, 0.541016f, 0.279740f, 0.424104f, 0.392535f, 0.598183f, 0.292690f, 0.616404f, 0.694579f, 1.011039f, 0.719050f, 0.909331f, +0.154132f, 0.208390f, 0.098027f, 0.242206f, 0.116487f, 0.191153f, 0.122505f, 0.156642f, 0.252905f, 0.385960f, 0.234068f, 0.415756f, 0.185086f, 0.269804f, 0.237830f, 0.253669f, +1.832371f, 2.130530f, 0.946205f, 2.470782f, 0.910894f, 1.285467f, 0.777787f, 1.051058f, 1.449708f, 1.902637f, 1.089394f, 2.044989f, 2.066608f, 2.590735f, 2.156104f, 2.430420f, +0.148377f, 0.196255f, 0.081118f, 0.261187f, 0.169021f, 0.271341f, 0.152796f, 0.254603f, 0.268465f, 0.400815f, 0.213585f, 0.494381f, 0.234945f, 0.335051f, 0.259512f, 0.360705f, +0.309617f, 0.375455f, 0.148085f, 0.400008f, 0.327728f, 0.482353f, 0.259191f, 0.362322f, 0.265340f, 0.363192f, 0.184680f, 0.358621f, 0.726214f, 0.949485f, 0.701762f, 0.818296f, +0.280126f, 0.340185f, 0.166301f, 0.378870f, 0.319170f, 0.470438f, 0.313317f, 0.369400f, 0.471898f, 0.646861f, 0.407682f, 0.667689f, 0.534174f, 0.699416f, 0.640714f, 0.630119f, +1.402535f, 1.464757f, 0.676043f, 1.627722f, 1.051118f, 1.332362f, 0.837786f, 1.043893f, 1.139232f, 1.342966f, 0.799107f, 1.383146f, 2.511931f, 2.828462f, 2.446291f, 2.542591f, +0.130263f, 0.154759f, 0.066476f, 0.197357f, 0.223707f, 0.322576f, 0.188773f, 0.290033f, 0.241977f, 0.324495f, 0.179699f, 0.383525f, 0.327545f, 0.419560f, 0.337715f, 0.432815f, +6.947791f, 8.702914f, 3.988465f, 7.288769f, 7.833216f, 11.909050f, 7.435672f, 7.032106f, 5.826327f, 8.237849f, 4.867278f, 6.394279f, 12.785670f, 17.267600f, 14.829360f, 11.698580f, +3.010170f, 3.776050f, 2.144892f, 3.305917f, 3.653135f, 5.562004f, 4.304287f, 3.433242f, 4.962000f, 7.025939f, 5.145213f, 5.700945f, 4.503587f, 6.091100f, 6.483545f, 4.313815f, +13.769440f, 14.854330f, 7.966178f, 12.976170f, 10.991570f, 14.391820f, 10.515130f, 8.863966f, 10.944240f, 13.326730f, 9.214072f, 10.789600f, 19.348530f, 22.504810f, 22.616290f, 15.903050f, +1.866041f, 2.290021f, 1.142970f, 2.295700f, 3.413380f, 5.084189f, 3.457158f, 3.593489f, 3.391912f, 4.698549f, 3.023363f, 4.365437f, 3.681352f, 4.870977f, 4.555757f, 3.950057f, +0.000961f, 0.001170f, 0.001974f, 0.005452f, 0.000833f, 0.001231f, 0.002830f, 0.004045f, 0.000018f, 0.000024f, 0.000053f, 0.000106f, 0.000695f, 0.000913f, 0.002886f, 0.003441f, +0.000553f, 0.000674f, 0.001410f, 0.003285f, 0.000516f, 0.000764f, 0.002177f, 0.002624f, 0.000020f, 0.000028f, 0.000075f, 0.000125f, 0.000325f, 0.000428f, 0.001677f, 0.001686f, +0.003649f, 0.003827f, 0.007555f, 0.018599f, 0.002241f, 0.002852f, 0.007670f, 0.009772f, 0.000064f, 0.000076f, 0.000193f, 0.000342f, 0.002017f, 0.002280f, 0.008435f, 0.008964f, +0.000024f, 0.000029f, 0.000053f, 0.000162f, 0.000034f, 0.000050f, 0.000124f, 0.000195f, 0.000001f, 0.000001f, 0.000003f, 0.000007f, 0.000019f, 0.000024f, 0.000084f, 0.000110f, +4.224910f, 5.553086f, 2.316954f, 5.515960f, 4.652723f, 7.422377f, 4.219181f, 5.198149f, 3.402521f, 5.047993f, 2.715395f, 4.647225f, 6.869253f, 9.734575f, 7.611129f, 7.821954f, +1.916048f, 2.522040f, 1.304252f, 2.618806f, 2.271315f, 3.628624f, 2.556547f, 2.656515f, 3.033243f, 4.506650f, 3.004656f, 4.337041f, 2.532731f, 3.594390f, 3.483244f, 3.019174f, +12.470200f, 14.115930f, 6.892046f, 14.625140f, 9.723295f, 13.358830f, 8.886060f, 9.758383f, 9.518709f, 12.162280f, 7.655701f, 11.678680f, 15.481760f, 18.895000f, 17.287600f, 15.836130f, +1.104810f, 1.422671f, 0.646460f, 1.691521f, 1.974000f, 3.085199f, 1.909953f, 2.586277f, 1.928617f, 2.803265f, 1.642225f, 3.089053f, 1.925700f, 2.673600f, 2.276580f, 2.571467f, +0.209508f, 0.262451f, 0.118824f, 0.247244f, 0.198685f, 0.302087f, 0.186333f, 0.200646f, 0.189160f, 0.267472f, 0.156122f, 0.233531f, 0.453624f, 0.612681f, 0.519803f, 0.466900f, +0.127832f, 0.160368f, 0.089991f, 0.157928f, 0.130493f, 0.198693f, 0.151903f, 0.137957f, 0.226874f, 0.321265f, 0.232422f, 0.293220f, 0.225022f, 0.304364f, 0.320055f, 0.242464f, +1.013751f, 1.093701f, 0.579442f, 1.074683f, 0.680686f, 0.891319f, 0.643349f, 0.617495f, 0.867523f, 1.056450f, 0.721592f, 0.962097f, 1.676029f, 1.949571f, 1.935529f, 1.549646f, +0.096754f, 0.118746f, 0.058550f, 0.133900f, 0.148869f, 0.221754f, 0.148965f, 0.176301f, 0.189353f, 0.262314f, 0.166749f, 0.274141f, 0.224581f, 0.297175f, 0.274582f, 0.271074f, +4.630146f, 5.991390f, 3.151894f, 4.436947f, 4.676983f, 7.345436f, 5.264580f, 3.835246f, 4.090663f, 5.974858f, 4.052312f, 4.100838f, 7.865519f, 10.973640f, 10.817920f, 6.573840f, +1.352852f, 1.753122f, 1.143096f, 1.357167f, 1.470967f, 2.313573f, 2.055209f, 1.262768f, 2.349454f, 3.436605f, 2.888893f, 2.465694f, 1.868417f, 2.610513f, 3.189669f, 1.634778f, +9.801819f, 10.923420f, 6.724476f, 8.437606f, 7.010163f, 9.481977f, 7.952448f, 5.163907f, 8.207805f, 10.324760f, 8.194282f, 7.391436f, 12.714350f, 15.276950f, 17.623240f, 9.545726f, +1.365028f, 1.730513f, 0.991455f, 1.533973f, 2.237087f, 3.442190f, 2.686799f, 2.151279f, 2.614062f, 3.740676f, 2.762991f, 3.073132f, 2.485900f, 3.397875f, 3.647999f, 2.436474f, +0.007855f, 0.009879f, 0.019133f, 0.040705f, 0.006102f, 0.009315f, 0.024580f, 0.027062f, 0.000153f, 0.000218f, 0.000544f, 0.000832f, 0.005247f, 0.007116f, 0.025825f, 0.023718f, +0.003049f, 0.003841f, 0.009219f, 0.016543f, 0.002550f, 0.003898f, 0.012749f, 0.011839f, 0.000117f, 0.000166f, 0.000515f, 0.000665f, 0.001656f, 0.002249f, 0.010117f, 0.007837f, +0.031865f, 0.034515f, 0.078224f, 0.148340f, 0.017528f, 0.023044f, 0.071153f, 0.069827f, 0.000590f, 0.000721f, 0.002108f, 0.002873f, 0.016255f, 0.018983f, 0.080623f, 0.065999f, +0.000219f, 0.000270f, 0.000569f, 0.001330f, 0.000276f, 0.000413f, 0.001186f, 0.001435f, 0.000009f, 0.000013f, 0.000035f, 0.000059f, 0.000157f, 0.000208f, 0.000823f, 0.000831f, +5.212938f, 7.078063f, 3.390005f, 6.216820f, 5.143397f, 8.476192f, 5.530812f, 5.248964f, 4.422999f, 6.778751f, 4.185687f, 5.518129f, 7.824029f, 11.453890f, 10.279880f, 8.138012f, +1.594347f, 2.167921f, 1.286933f, 1.990499f, 1.693291f, 2.794545f, 2.260090f, 1.809042f, 2.659100f, 4.081278f, 3.123489f, 3.472986f, 1.945456f, 2.852151f, 3.172737f, 2.118374f, +16.435430f, 19.219060f, 10.771440f, 17.607180f, 11.481510f, 16.295540f, 12.442640f, 10.525560f, 13.217110f, 17.445710f, 12.605540f, 14.812710f, 18.835790f, 23.747910f, 24.941130f, 17.599270f, +1.496322f, 1.990477f, 1.038239f, 2.092653f, 2.395314f, 3.867350f, 2.748248f, 2.866636f, 2.751912f, 4.132069f, 2.778683f, 4.026205f, 2.407588f, 3.453066f, 3.375158f, 2.936679f, +0.394890f, 0.438765f, 0.194291f, 0.523148f, 0.444215f, 0.599057f, 0.361402f, 0.503594f, 0.356777f, 0.447460f, 0.255449f, 0.494464f, 0.852030f, 1.020708f, 0.846974f, 0.984478f, +0.267580f, 0.297741f, 0.163412f, 0.371104f, 0.324006f, 0.437579f, 0.327194f, 0.384532f, 0.475218f, 0.596868f, 0.422334f, 0.689484f, 0.469379f, 0.563117f, 0.579154f, 0.567764f, +1.290638f, 1.235035f, 0.639963f, 1.535946f, 1.027952f, 1.193896f, 0.842838f, 1.046844f, 1.105216f, 1.193776f, 0.797498f, 1.375967f, 2.126369f, 2.193835f, 2.130241f, 2.207051f, +0.116704f, 0.127041f, 0.061266f, 0.181310f, 0.212998f, 0.281417f, 0.184895f, 0.283170f, 0.228551f, 0.280828f, 0.174601f, 0.371456f, 0.269945f, 0.316827f, 0.286316f, 0.365774f, +12.690050f, 14.564790f, 7.493976f, 13.651360f, 15.205020f, 21.181020f, 14.847630f, 13.997080f, 11.219040f, 14.534410f, 9.641323f, 12.625750f, 21.482270f, 26.583460f, 25.631180f, 20.155550f, +4.117730f, 4.732900f, 3.018298f, 4.637284f, 5.310836f, 7.408858f, 6.437068f, 5.118074f, 7.155954f, 9.284063f, 7.633153f, 8.430681f, 5.667156f, 7.023041f, 8.392842f, 5.566384f, +18.145680f, 17.936300f, 10.799330f, 17.535110f, 15.393850f, 18.468260f, 15.149280f, 12.729760f, 15.205010f, 16.964750f, 13.168690f, 15.371320f, 23.455500f, 24.997420f, 28.203830f, 19.768890f, +2.394157f, 2.692115f, 1.508537f, 3.020309f, 4.654214f, 6.351938f, 4.849207f, 5.024387f, 4.587963f, 5.823204f, 4.206836f, 6.054916f, 4.344888f, 5.267568f, 5.531228f, 4.780569f, +0.001041f, 0.001161f, 0.002199f, 0.006055f, 0.000959f, 0.001299f, 0.003351f, 0.004775f, 0.000020f, 0.000026f, 0.000063f, 0.000124f, 0.000693f, 0.000833f, 0.002958f, 0.003516f, +0.000449f, 0.000501f, 0.001177f, 0.002733f, 0.000445f, 0.000604f, 0.001930f, 0.002320f, 0.000017f, 0.000022f, 0.000066f, 0.000110f, 0.000243f, 0.000293f, 0.001287f, 0.001290f, +0.002852f, 0.002740f, 0.006073f, 0.014904f, 0.001861f, 0.002170f, 0.006553f, 0.008322f, 0.000053f, 0.000057f, 0.000164f, 0.000289f, 0.001450f, 0.001502f, 0.006238f, 0.006608f, +0.000019f, 0.000020f, 0.000042f, 0.000127f, 0.000028f, 0.000037f, 0.000103f, 0.000162f, 0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000013f, 0.000016f, 0.000060f, 0.000079f, +6.133343f, 7.386472f, 3.460087f, 8.211186f, 7.178230f, 10.492430f, 6.696197f, 8.223635f, 5.207445f, 7.078894f, 4.275104f, 7.293275f, 9.173376f, 11.911310f, 10.455830f, 10.711240f, +2.083226f, 2.512493f, 1.458752f, 2.919700f, 2.624446f, 3.841714f, 3.038812f, 3.147585f, 3.476812f, 4.733155f, 3.542897f, 5.097679f, 2.533138f, 3.293956f, 3.583798f, 3.096442f, +13.061520f, 13.547290f, 7.426055f, 15.708150f, 10.823410f, 13.625160f, 10.175360f, 11.138670f, 10.510960f, 12.305580f, 8.696391f, 13.224010f, 14.916960f, 16.681290f, 17.135020f, 15.646390f, +1.126632f, 1.329297f, 0.678151f, 1.768793f, 2.139302f, 3.063592f, 2.129303f, 2.874120f, 2.073407f, 2.761376f, 1.816189f, 3.405406f, 1.806438f, 2.298019f, 2.196884f, 2.473548f, +0.203340f, 0.253277f, 0.090867f, 0.302038f, 0.169831f, 0.256749f, 0.125494f, 0.215871f, 0.223325f, 0.313986f, 0.145229f, 0.347028f, 0.483624f, 0.649486f, 0.436647f, 0.626539f, +0.112357f, 0.140152f, 0.062321f, 0.174715f, 0.101012f, 0.152930f, 0.092648f, 0.134414f, 0.242566f, 0.341532f, 0.195795f, 0.394595f, 0.217257f, 0.292189f, 0.243474f, 0.294651f, +0.914231f, 0.980723f, 0.411731f, 1.219880f, 0.540631f, 0.703898f, 0.402605f, 0.617305f, 0.951680f, 1.152345f, 0.623708f, 1.328439f, 1.660333f, 1.920331f, 1.510751f, 1.932228f, +0.083575f, 0.101988f, 0.039849f, 0.145580f, 0.113251f, 0.167738f, 0.089289f, 0.168812f, 0.198960f, 0.274055f, 0.138050f, 0.362559f, 0.213093f, 0.280370f, 0.205280f, 0.323740f, +3.344346f, 4.302962f, 1.793774f, 4.033789f, 2.975166f, 4.646077f, 2.638691f, 3.070796f, 3.594147f, 5.219791f, 2.805333f, 4.535102f, 6.240695f, 8.657247f, 6.762838f, 6.565035f, +0.884918f, 1.140219f, 0.589135f, 1.117374f, 0.847392f, 1.325221f, 0.932862f, 0.915625f, 1.869413f, 2.718888f, 1.811128f, 2.469391f, 1.342504f, 1.865052f, 1.805788f, 1.478472f, +6.578467f, 7.289539f, 3.555952f, 7.127703f, 4.143573f, 5.572745f, 3.703626f, 3.841826f, 6.700861f, 8.381214f, 5.271012f, 7.595297f, 9.373489f, 11.198690f, 10.236990f, 8.857850f, +0.877490f, 1.106111f, 0.502173f, 1.241168f, 1.266520f, 1.937704f, 1.198516f, 1.532986f, 2.044099f, 2.908435f, 1.702335f, 3.024681f, 1.755387f, 2.385723f, 2.029661f, 2.165527f, +0.001790f, 0.002239f, 0.003436f, 0.011679f, 0.001225f, 0.001859f, 0.003888f, 0.006838f, 0.000043f, 0.000060f, 0.000119f, 0.000290f, 0.001314f, 0.001772f, 0.005095f, 0.007475f, +0.000629f, 0.000788f, 0.001500f, 0.004298f, 0.000464f, 0.000705f, 0.001826f, 0.002709f, 0.000029f, 0.000042f, 0.000102f, 0.000210f, 0.000376f, 0.000507f, 0.001808f, 0.002237f, +0.006749f, 0.007269f, 0.013054f, 0.039546f, 0.003270f, 0.004274f, 0.010458f, 0.016395f, 0.000152f, 0.000185f, 0.000428f, 0.000932f, 0.003782f, 0.004392f, 0.014780f, 0.019328f, +0.000044f, 0.000054f, 0.000091f, 0.000340f, 0.000049f, 0.000073f, 0.000167f, 0.000323f, 0.000002f, 0.000003f, 0.000007f, 0.000018f, 0.000035f, 0.000046f, 0.000145f, 0.000233f, +3.118375f, 4.210014f, 1.597812f, 4.680868f, 2.709721f, 4.440161f, 2.295847f, 3.480652f, 3.218460f, 4.904609f, 2.399814f, 5.054003f, 5.141208f, 7.483608f, 5.322334f, 6.730781f, +0.863704f, 1.167747f, 0.549310f, 1.357239f, 0.807872f, 1.325700f, 0.849603f, 1.086355f, 1.752274f, 2.674158f, 1.621761f, 2.880600f, 1.157690f, 1.687589f, 1.487594f, 1.586667f, +9.135415f, 10.621910f, 4.717375f, 12.318260f, 5.620499f, 7.931733f, 4.799191f, 6.485356f, 8.936540f, 11.728560f, 6.715427f, 12.606070f, 11.500590f, 14.417330f, 11.998630f, 13.525190f, +0.796626f, 1.053683f, 0.435518f, 1.402294f, 1.123106f, 1.802998f, 1.015299f, 1.691778f, 1.782172f, 2.660762f, 1.417861f, 3.281886f, 1.407994f, 2.007922f, 1.555221f, 2.161660f, +0.034844f, 0.042253f, 0.016665f, 0.045017f, 0.034170f, 0.050291f, 0.027024f, 0.037777f, 0.026612f, 0.036426f, 0.018522f, 0.035968f, 0.131474f, 0.171895f, 0.127047f, 0.148144f, +0.038531f, 0.046792f, 0.022874f, 0.052113f, 0.040673f, 0.059949f, 0.039927f, 0.047074f, 0.057846f, 0.079294f, 0.049975f, 0.081847f, 0.118198f, 0.154761f, 0.141772f, 0.139428f, +0.190693f, 0.199153f, 0.091917f, 0.221311f, 0.132403f, 0.167830f, 0.105531f, 0.131493f, 0.138040f, 0.162727f, 0.096828f, 0.167596f, 0.549415f, 0.618648f, 0.535058f, 0.556122f, +0.021196f, 0.025182f, 0.010817f, 0.032114f, 0.033724f, 0.048629f, 0.028458f, 0.043723f, 0.035090f, 0.047056f, 0.026059f, 0.055617f, 0.085739f, 0.109826f, 0.088402f, 0.113295f, +1.249919f, 1.565669f, 0.717532f, 1.311262f, 1.305569f, 1.984892f, 1.239310f, 1.172048f, 0.934119f, 1.320752f, 0.780358f, 1.025178f, 3.700241f, 4.997336f, 4.291694f, 3.385631f, +0.661879f, 0.830281f, 0.471621f, 0.726908f, 0.744180f, 1.133035f, 0.876826f, 0.699385f, 0.972336f, 1.376779f, 1.008238f, 1.117138f, 1.593005f, 2.154539f, 2.293355f, 1.525879f, +2.992750f, 3.228549f, 1.731427f, 2.820335f, 2.213291f, 2.897974f, 2.117354f, 1.784871f, 2.119884f, 2.581369f, 1.784753f, 2.089930f, 6.765085f, 7.868660f, 7.907637f, 5.560397f, +0.485391f, 0.595676f, 0.297307f, 0.597153f, 0.822583f, 1.225228f, 0.833133f, 0.865988f, 0.786299f, 1.089198f, 0.700863f, 1.011977f, 1.540456f, 2.038252f, 1.906349f, 1.652895f, +0.000681f, 0.000829f, 0.001399f, 0.003864f, 0.000547f, 0.000809f, 0.001859f, 0.002656f, 0.000011f, 0.000015f, 0.000034f, 0.000067f, 0.000793f, 0.001041f, 0.003291f, 0.003923f, +0.000479f, 0.000584f, 0.001222f, 0.002846f, 0.000414f, 0.000613f, 0.001747f, 0.002106f, 0.000016f, 0.000021f, 0.000058f, 0.000097f, 0.000454f, 0.000596f, 0.002336f, 0.002349f, +0.003125f, 0.003277f, 0.006469f, 0.015926f, 0.001778f, 0.002262f, 0.006085f, 0.007752f, 0.000049f, 0.000058f, 0.000147f, 0.000261f, 0.002778f, 0.003141f, 0.011620f, 0.012348f, +0.000025f, 0.000030f, 0.000055f, 0.000166f, 0.000033f, 0.000047f, 0.000118f, 0.000186f, 0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000031f, 0.000040f, 0.000138f, 0.000181f, +0.620495f, 0.815559f, 0.340282f, 0.810107f, 0.633072f, 1.009924f, 0.574082f, 0.707285f, 0.445343f, 0.660712f, 0.355407f, 0.608257f, 1.622938f, 2.299902f, 1.798214f, 1.848024f, +0.343938f, 0.452715f, 0.234118f, 0.470085f, 0.377725f, 0.603448f, 0.425159f, 0.441784f, 0.485236f, 0.720941f, 0.480663f, 0.693808f, 0.731364f, 1.037934f, 1.005839f, 0.871832f, +2.212654f, 2.504664f, 1.222893f, 2.595016f, 1.598373f, 2.196003f, 1.460743f, 1.604141f, 1.505187f, 1.923213f, 1.210591f, 1.846742f, 4.419077f, 5.393344f, 4.934532f, 4.520228f, +0.234609f, 0.302107f, 0.137277f, 0.359198f, 0.388354f, 0.606966f, 0.375754f, 0.508811f, 0.364985f, 0.530509f, 0.310786f, 0.584594f, 0.657834f, 0.913323f, 0.777697f, 0.878433f, +0.022636f, 0.028356f, 0.012838f, 0.026713f, 0.019888f, 0.030238f, 0.018651f, 0.020084f, 0.018214f, 0.025754f, 0.015032f, 0.022486f, 0.078842f, 0.106488f, 0.090345f, 0.081150f, +0.016881f, 0.021177f, 0.011884f, 0.020855f, 0.015965f, 0.024308f, 0.018584f, 0.016878f, 0.026700f, 0.037808f, 0.027352f, 0.034507f, 0.047802f, 0.064656f, 0.067989f, 0.051507f, +0.132326f, 0.142761f, 0.075635f, 0.140279f, 0.082316f, 0.107788f, 0.077801f, 0.074674f, 0.100917f, 0.122895f, 0.083941f, 0.111919f, 0.351937f, 0.409376f, 0.406428f, 0.325399f, +0.015115f, 0.018550f, 0.009147f, 0.020918f, 0.021546f, 0.032094f, 0.021559f, 0.025516f, 0.026362f, 0.036519f, 0.023215f, 0.038166f, 0.056438f, 0.074681f, 0.069004f, 0.068122f, +0.799688f, 1.034793f, 0.544374f, 0.766320f, 0.748370f, 1.175352f, 0.842392f, 0.613682f, 0.629639f, 0.919657f, 0.623736f, 0.631205f, 2.185367f, 3.048932f, 3.005667f, 1.826485f, +0.285580f, 0.370075f, 0.241302f, 0.286491f, 0.287677f, 0.452466f, 0.401938f, 0.246960f, 0.441995f, 0.646517f, 0.543478f, 0.463863f, 0.634487f, 0.886493f, 1.083165f, 0.555147f, +2.045274f, 2.279310f, 1.403147f, 1.760613f, 1.355181f, 1.833024f, 1.537341f, 0.998269f, 1.526315f, 1.919981f, 1.523800f, 1.374504f, 4.267860f, 5.128055f, 5.915637f, 3.204239f, +0.340881f, 0.432152f, 0.247591f, 0.383071f, 0.517569f, 0.796380f, 0.621614f, 0.497717f, 0.581767f, 0.832499f, 0.614912f, 0.683935f, 0.998656f, 1.365022f, 1.465504f, 0.978800f, +0.005345f, 0.006722f, 0.013019f, 0.027697f, 0.003847f, 0.005872f, 0.015495f, 0.017060f, 0.000093f, 0.000132f, 0.000330f, 0.000504f, 0.005744f, 0.007789f, 0.028268f, 0.025962f, +0.002536f, 0.003194f, 0.007667f, 0.013758f, 0.001965f, 0.003004f, 0.009823f, 0.009122f, 0.000087f, 0.000123f, 0.000382f, 0.000493f, 0.002216f, 0.003009f, 0.013536f, 0.010484f, +0.026195f, 0.028373f, 0.064306f, 0.121945f, 0.013350f, 0.017550f, 0.054191f, 0.053181f, 0.000432f, 0.000528f, 0.001544f, 0.002105f, 0.021497f, 0.025105f, 0.106620f, 0.087281f, +0.000215f, 0.000265f, 0.000560f, 0.001309f, 0.000251f, 0.000376f, 0.001081f, 0.001308f, 0.000008f, 0.000011f, 0.000031f, 0.000052f, 0.000248f, 0.000330f, 0.001303f, 0.001315f, +0.735012f, 0.997990f, 0.477983f, 0.876557f, 0.671872f, 1.107228f, 0.722479f, 0.685662f, 0.555777f, 0.851792f, 0.525958f, 0.693387f, 1.774652f, 2.597980f, 2.331690f, 1.845870f, +0.274756f, 0.373600f, 0.221779f, 0.343025f, 0.270346f, 0.446169f, 0.360840f, 0.288826f, 0.408386f, 0.626805f, 0.479707f, 0.533383f, 0.539332f, 0.790692f, 0.879567f, 0.587270f, +2.799702f, 3.273879f, 1.834866f, 2.999304f, 1.811983f, 2.571721f, 1.963666f, 1.661118f, 2.006502f, 2.648448f, 1.913658f, 2.248731f, 5.161616f, 6.507694f, 6.834676f, 4.822769f, +0.305051f, 0.405793f, 0.211663f, 0.426623f, 0.452412f, 0.730441f, 0.519072f, 0.541432f, 0.499981f, 0.750736f, 0.504845f, 0.731502f, 0.789588f, 1.132461f, 1.106910f, 0.963108f, +0.029955f, 0.033283f, 0.014738f, 0.039684f, 0.031218f, 0.042100f, 0.025399f, 0.035391f, 0.024119f, 0.030250f, 0.017269f, 0.033427f, 0.103973f, 0.124557f, 0.103356f, 0.120135f, +0.024808f, 0.027605f, 0.015151f, 0.034407f, 0.027831f, 0.037586f, 0.028104f, 0.033030f, 0.039265f, 0.049317f, 0.034896f, 0.056969f, 0.070007f, 0.083988f, 0.086380f, 0.084681f, +0.118282f, 0.113186f, 0.058650f, 0.140763f, 0.087279f, 0.101369f, 0.071562f, 0.088883f, 0.090268f, 0.097501f, 0.065135f, 0.112381f, 0.313489f, 0.323436f, 0.314060f, 0.325384f, +0.012800f, 0.013934f, 0.006720f, 0.019886f, 0.021644f, 0.028596f, 0.018788f, 0.028774f, 0.022340f, 0.027450f, 0.017067f, 0.036309f, 0.047629f, 0.055901f, 0.050518f, 0.064538f, +1.538826f, 1.766161f, 0.908737f, 1.655396f, 1.708196f, 2.379564f, 1.668045f, 1.572491f, 1.212422f, 1.570709f, 1.041922f, 1.364444f, 4.190611f, 5.185716f, 4.999952f, 3.931805f, +0.610290f, 0.701465f, 0.447343f, 0.687293f, 0.729232f, 1.017312f, 0.883875f, 0.702764f, 0.945188f, 1.226277f, 1.008218f, 1.113559f, 1.351184f, 1.674460f, 2.001053f, 1.327158f, +2.658387f, 2.627714f, 1.582129f, 2.568938f, 2.089377f, 2.506660f, 2.056182f, 1.727786f, 1.985199f, 2.214954f, 1.719332f, 2.006913f, 5.527910f, 5.891303f, 6.646979f, 4.659062f, +0.419773f, 0.472014f, 0.264495f, 0.529557f, 0.756019f, 1.031792f, 0.787693f, 0.816148f, 0.716892f, 0.909905f, 0.657339f, 0.946111f, 1.225494f, 1.485740f, 1.560107f, 1.348380f, +0.000497f, 0.000555f, 0.001051f, 0.002892f, 0.000425f, 0.000575f, 0.001483f, 0.002113f, 0.000009f, 0.000011f, 0.000027f, 0.000053f, 0.000532f, 0.000640f, 0.002273f, 0.002702f, +0.000262f, 0.000293f, 0.000687f, 0.001596f, 0.000241f, 0.000326f, 0.001044f, 0.001255f, 0.000009f, 0.000011f, 0.000034f, 0.000057f, 0.000228f, 0.000275f, 0.001209f, 0.001212f, +0.001646f, 0.001581f, 0.003505f, 0.008602f, 0.000995f, 0.001160f, 0.003504f, 0.004450f, 0.000027f, 0.000029f, 0.000084f, 0.000149f, 0.001346f, 0.001394f, 0.005792f, 0.006135f, +0.000013f, 0.000014f, 0.000029f, 0.000087f, 0.000018f, 0.000024f, 0.000066f, 0.000104f, 0.000000f, 0.000001f, 0.000002f, 0.000003f, 0.000015f, 0.000017f, 0.000067f, 0.000088f, +0.607169f, 0.731222f, 0.342530f, 0.812864f, 0.658346f, 0.962305f, 0.614136f, 0.754224f, 0.459419f, 0.624525f, 0.377165f, 0.643438f, 1.460873f, 1.896892f, 1.665106f, 1.705780f, +0.252058f, 0.303997f, 0.176500f, 0.353266f, 0.294189f, 0.430639f, 0.340638f, 0.352831f, 0.374902f, 0.510372f, 0.382028f, 0.549679f, 0.493054f, 0.641141f, 0.697556f, 0.602696f, +1.562156f, 1.620255f, 0.888156f, 1.878694f, 1.199277f, 1.509723f, 1.127470f, 1.234209f, 1.120329f, 1.311612f, 0.926920f, 1.409504f, 2.870004f, 3.209459f, 3.296755f, 3.010344f, +0.161261f, 0.190270f, 0.097067f, 0.253177f, 0.283690f, 0.406259f, 0.282364f, 0.381133f, 0.264487f, 0.352245f, 0.231676f, 0.434399f, 0.415951f, 0.529142f, 0.505854f, 0.569559f, +0.014329f, 0.017848f, 0.006403f, 0.021284f, 0.011087f, 0.016762f, 0.008193f, 0.014093f, 0.014025f, 0.019718f, 0.009120f, 0.021793f, 0.054824f, 0.073626f, 0.049498f, 0.071024f, +0.009677f, 0.012071f, 0.005368f, 0.015048f, 0.008060f, 0.012203f, 0.007393f, 0.010725f, 0.018618f, 0.026215f, 0.015028f, 0.030288f, 0.030101f, 0.040483f, 0.033734f, 0.040824f, +0.077833f, 0.083494f, 0.035053f, 0.103854f, 0.042642f, 0.055519f, 0.031755f, 0.048689f, 0.072206f, 0.087430f, 0.047322f, 0.100791f, 0.227391f, 0.262999f, 0.206905f, 0.264629f, +0.008515f, 0.010391f, 0.004060f, 0.014833f, 0.010690f, 0.015834f, 0.008428f, 0.015935f, 0.018066f, 0.024885f, 0.012535f, 0.032921f, 0.034927f, 0.045954f, 0.033647f, 0.053063f, +0.376732f, 0.484717f, 0.202064f, 0.454396f, 0.310496f, 0.484877f, 0.275381f, 0.320477f, 0.360819f, 0.524018f, 0.281629f, 0.455282f, 1.130902f, 1.568815f, 1.225522f, 1.189677f, +0.121836f, 0.156986f, 0.081113f, 0.153841f, 0.108089f, 0.169039f, 0.118991f, 0.116793f, 0.229377f, 0.333608f, 0.222226f, 0.302995f, 0.297344f, 0.413081f, 0.399955f, 0.327459f, +0.895292f, 0.992064f, 0.483945f, 0.970039f, 0.522443f, 0.702641f, 0.466973f, 0.484398f, 0.812723f, 1.016527f, 0.639302f, 0.921206f, 2.052165f, 2.451761f, 2.241213f, 1.939274f, +0.142922f, 0.180158f, 0.081792f, 0.202156f, 0.191114f, 0.292394f, 0.180853f, 0.231323f, 0.296709f, 0.422171f, 0.247100f, 0.439044f, 0.459939f, 0.625097f, 0.531803f, 0.567402f, +0.000795f, 0.000994f, 0.001525f, 0.005183f, 0.000504f, 0.000765f, 0.001599f, 0.002812f, 0.000017f, 0.000024f, 0.000047f, 0.000115f, 0.000938f, 0.001265f, 0.003637f, 0.005337f, +0.000341f, 0.000428f, 0.000813f, 0.002331f, 0.000233f, 0.000354f, 0.000918f, 0.001361f, 0.000014f, 0.000020f, 0.000049f, 0.000102f, 0.000328f, 0.000442f, 0.001577f, 0.001952f, +0.003619f, 0.003897f, 0.006999f, 0.021204f, 0.001624f, 0.002123f, 0.005195f, 0.008144f, 0.000073f, 0.000088f, 0.000204f, 0.000445f, 0.003262f, 0.003788f, 0.012748f, 0.016671f, +0.000028f, 0.000035f, 0.000058f, 0.000218f, 0.000029f, 0.000044f, 0.000099f, 0.000192f, 0.000001f, 0.000002f, 0.000004f, 0.000010f, 0.000036f, 0.000048f, 0.000149f, 0.000241f, +0.286771f, 0.387160f, 0.146937f, 0.430460f, 0.230864f, 0.378294f, 0.195602f, 0.296546f, 0.263771f, 0.401960f, 0.196678f, 0.414204f, 0.760577f, 1.107105f, 0.787372f, 0.995734f, +0.097079f, 0.131252f, 0.061741f, 0.152551f, 0.084125f, 0.138048f, 0.088471f, 0.113124f, 0.175523f, 0.267867f, 0.162449f, 0.288545f, 0.209326f, 0.305138f, 0.268977f, 0.286890f, +1.014972f, 1.180126f, 0.524114f, 1.368595f, 0.578529f, 0.816429f, 0.493990f, 0.667550f, 0.884845f, 1.161295f, 0.664923f, 1.248181f, 2.055497f, 2.576806f, 2.144513f, 2.417353f, +0.105925f, 0.140104f, 0.057909f, 0.186458f, 0.138353f, 0.222107f, 0.125072f, 0.208406f, 0.211185f, 0.315298f, 0.168015f, 0.388900f, 0.301172f, 0.429497f, 0.332664f, 0.462382f, +0.177993f, 0.215843f, 0.085131f, 0.229958f, 0.140275f, 0.206458f, 0.110940f, 0.155082f, 0.117641f, 0.161025f, 0.081880f, 0.158998f, 0.406517f, 0.531499f, 0.392830f, 0.458062f, +0.236337f, 0.287007f, 0.140305f, 0.319645f, 0.200488f, 0.295508f, 0.196812f, 0.232041f, 0.307046f, 0.420887f, 0.265263f, 0.434439f, 0.438830f, 0.574578f, 0.526353f, 0.517649f, +0.965408f, 1.008238f, 0.465341f, 1.120412f, 0.538689f, 0.682824f, 0.429358f, 0.534986f, 0.604765f, 0.712918f, 0.424209f, 0.734248f, 1.683607f, 1.895760f, 1.639612f, 1.704157f, +0.079810f, 0.094818f, 0.040729f, 0.120917f, 0.102048f, 0.147149f, 0.086113f, 0.132304f, 0.114337f, 0.153328f, 0.084910f, 0.181221f, 0.195408f, 0.250303f, 0.201476f, 0.258211f, +3.817794f, 4.782230f, 2.191652f, 4.005161f, 3.204754f, 4.872273f, 3.042109f, 2.877001f, 2.469094f, 3.491055f, 2.062666f, 2.709783f, 6.841082f, 9.239177f, 7.934572f, 6.259424f, +2.427481f, 3.045107f, 1.729698f, 2.665979f, 2.193408f, 3.339527f, 2.584371f, 2.061380f, 3.086019f, 4.369645f, 3.199964f, 3.545591f, 3.536378f, 4.782951f, 5.091113f, 3.387363f, +9.059423f, 9.773217f, 5.241244f, 8.537504f, 5.384347f, 7.049997f, 5.150957f, 4.342115f, 5.553247f, 6.762153f, 4.675338f, 5.474780f, 12.395600f, 14.417680f, 14.489090f, 10.188270f, +1.092810f, 1.341106f, 0.669358f, 1.344432f, 1.488323f, 2.216839f, 1.507411f, 1.566855f, 1.531952f, 2.122093f, 1.365498f, 1.971644f, 2.099261f, 2.777635f, 2.597883f, 2.252488f, +0.001096f, 0.001334f, 0.002251f, 0.006218f, 0.000708f, 0.001046f, 0.002404f, 0.003436f, 0.000016f, 0.000022f, 0.000047f, 0.000093f, 0.000772f, 0.001014f, 0.003206f, 0.003822f, +0.000926f, 0.001129f, 0.002361f, 0.005499f, 0.000644f, 0.000952f, 0.002713f, 0.003271f, 0.000026f, 0.000036f, 0.000097f, 0.000162f, 0.000530f, 0.000697f, 0.002733f, 0.002748f, +0.004984f, 0.005226f, 0.010318f, 0.025401f, 0.002278f, 0.002900f, 0.007799f, 0.009936f, 0.000068f, 0.000080f, 0.000204f, 0.000360f, 0.002682f, 0.003032f, 0.011218f, 0.011921f, +0.000030f, 0.000035f, 0.000065f, 0.000197f, 0.000031f, 0.000045f, 0.000113f, 0.000177f, 0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000022f, 0.000029f, 0.000099f, 0.000130f, +2.241948f, 2.946745f, 1.229492f, 2.927044f, 1.838249f, 2.932514f, 1.666960f, 2.053741f, 1.392470f, 2.065874f, 1.111266f, 1.901862f, 3.549385f, 5.029914f, 3.932717f, 4.041651f, +1.492153f, 1.964080f, 1.015708f, 2.039438f, 1.316962f, 2.103962f, 1.482346f, 1.540310f, 1.821761f, 2.706687f, 1.804591f, 2.604820f, 1.920576f, 2.725635f, 2.641353f, 2.289447f, +7.923192f, 8.968837f, 4.379000f, 9.292375f, 4.599696f, 6.319517f, 4.203634f, 4.616294f, 4.664250f, 5.959623f, 3.751360f, 5.722657f, 9.578170f, 11.689850f, 10.695400f, 9.797409f, +0.624818f, 0.804583f, 0.365601f, 0.956629f, 0.831193f, 1.299087f, 0.804225f, 1.089005f, 0.841180f, 1.222664f, 0.716268f, 1.347313f, 1.060450f, 1.472305f, 1.253673f, 1.416062f, +0.177101f, 0.221854f, 0.100444f, 0.209000f, 0.125047f, 0.190126f, 0.117273f, 0.126281f, 0.123318f, 0.174371f, 0.101780f, 0.152244f, 0.373380f, 0.504300f, 0.427853f, 0.384307f, +0.158584f, 0.198946f, 0.111639f, 0.195919f, 0.120530f, 0.183523f, 0.140305f, 0.127424f, 0.217061f, 0.307368f, 0.222368f, 0.280537f, 0.271819f, 0.367660f, 0.386615f, 0.292888f, +1.026053f, 1.106972f, 0.586473f, 1.087723f, 0.512949f, 0.671676f, 0.484812f, 0.465330f, 0.677168f, 0.824639f, 0.563257f, 0.750990f, 1.651791f, 1.921378f, 1.907539f, 1.527236f, +0.087166f, 0.106978f, 0.052748f, 0.120631f, 0.099855f, 0.148744f, 0.099920f, 0.118255f, 0.131561f, 0.182254f, 0.115856f, 0.190471f, 0.197009f, 0.260691f, 0.240871f, 0.237794f, +3.741116f, 4.840989f, 2.546702f, 3.585013f, 2.813592f, 4.418887f, 3.167080f, 2.307218f, 2.549044f, 3.723155f, 2.525145f, 2.555384f, 6.188271f, 8.633617f, 8.511103f, 5.172030f, +1.604190f, 2.078823f, 1.355464f, 1.609307f, 1.298665f, 2.042573f, 1.814473f, 1.114854f, 2.148570f, 3.142766f, 2.641885f, 2.254871f, 2.157320f, 3.014163f, 3.682871f, 1.887555f, +9.482695f, 10.567780f, 6.505543f, 8.162897f, 5.049426f, 6.829877f, 5.728155f, 3.719567f, 6.123915f, 7.703394f, 6.113826f, 5.514815f, 11.977190f, 14.391210f, 16.601460f, 8.992273f, +1.175455f, 1.490182f, 0.853763f, 1.320937f, 1.434287f, 2.206927f, 1.722616f, 1.379272f, 1.736030f, 2.484228f, 1.834936f, 2.040904f, 2.084411f, 2.849096f, 3.058824f, 2.042968f, +0.013173f, 0.016568f, 0.032089f, 0.068269f, 0.007620f, 0.011632f, 0.030693f, 0.033793f, 0.000198f, 0.000282f, 0.000704f, 0.001076f, 0.008570f, 0.011620f, 0.042175f, 0.038733f, +0.007505f, 0.009453f, 0.022693f, 0.040718f, 0.004673f, 0.007144f, 0.023365f, 0.021696f, 0.000222f, 0.000316f, 0.000978f, 0.001261f, 0.003969f, 0.005390f, 0.024248f, 0.018782f, +0.063989f, 0.069311f, 0.157087f, 0.297889f, 0.026208f, 0.034454f, 0.106385f, 0.104403f, 0.000914f, 0.001117f, 0.003264f, 0.004450f, 0.031785f, 0.037120f, 0.157650f, 0.129054f, +0.000391f, 0.000482f, 0.001017f, 0.002377f, 0.000367f, 0.000549f, 0.001578f, 0.001909f, 0.000013f, 0.000018f, 0.000048f, 0.000081f, 0.000273f, 0.000362f, 0.001433f, 0.001446f, +4.067536f, 5.522850f, 2.645143f, 4.850842f, 2.988049f, 4.924232f, 3.213117f, 3.049378f, 2.661599f, 4.079205f, 2.518794f, 3.320609f, 5.944492f, 8.702362f, 7.810380f, 6.183048f, +1.825705f, 2.482511f, 1.473682f, 2.279343f, 1.443671f, 2.382581f, 1.926914f, 1.542358f, 2.348332f, 3.604301f, 2.758448f, 3.067100f, 2.169225f, 3.180209f, 3.537670f, 2.362032f, +15.354960f, 17.955580f, 10.063320f, 16.449670f, 7.986476f, 11.335090f, 8.655035f, 7.321528f, 9.523162f, 12.569940f, 9.082511f, 10.672820f, 17.135110f, 21.603710f, 22.689190f, 16.010230f, +1.244319f, 1.655251f, 0.863384f, 1.740219f, 1.483058f, 2.394468f, 1.701576f, 1.774876f, 1.764893f, 2.650034f, 1.782062f, 2.582140f, 1.949505f, 2.796064f, 2.732979f, 2.377928f, +0.241019f, 0.267798f, 0.118584f, 0.319301f, 0.201864f, 0.272228f, 0.164231f, 0.228847f, 0.167938f, 0.210623f, 0.120242f, 0.232749f, 0.506368f, 0.606614f, 0.503363f, 0.585082f, +0.239678f, 0.266694f, 0.146372f, 0.332407f, 0.216081f, 0.291823f, 0.218207f, 0.256446f, 0.328280f, 0.412316f, 0.291748f, 0.476295f, 0.409387f, 0.491144f, 0.505131f, 0.495197f, +0.943189f, 0.902555f, 0.467680f, 1.122459f, 0.559314f, 0.649605f, 0.458593f, 0.569594f, 0.622900f, 0.672813f, 0.449470f, 0.775496f, 1.513102f, 1.561111f, 1.515858f, 1.570515f, +0.075914f, 0.082637f, 0.039852f, 0.117939f, 0.103157f, 0.136293f, 0.089546f, 0.137142f, 0.114655f, 0.140881f, 0.087590f, 0.186345f, 0.170980f, 0.200674f, 0.181349f, 0.231676f, +7.403310f, 8.497022f, 4.371947f, 7.964131f, 6.604479f, 9.200220f, 6.449239f, 6.079793f, 5.047719f, 6.539386f, 4.337867f, 5.680635f, 12.203320f, 15.101130f, 14.560180f, 11.449660f, +3.525489f, 4.052182f, 2.584185f, 3.970317f, 3.385426f, 4.722823f, 4.103350f, 3.262548f, 4.725047f, 6.130229f, 5.040140f, 5.566744f, 4.724568f, 5.854937f, 6.996906f, 4.640557f, +12.675190f, 12.528940f, 7.543589f, 12.248690f, 8.006030f, 9.604968f, 7.878834f, 6.620495f, 8.191150f, 9.139148f, 7.094156f, 8.280747f, 15.953700f, 17.002460f, 19.183360f, 13.446180f, +1.488583f, 1.673840f, 0.937943f, 1.877898f, 2.154545f, 2.940462f, 2.244813f, 2.325907f, 2.199974f, 2.792284f, 2.017219f, 2.903392f, 2.630477f, 3.189085f, 3.348710f, 2.894246f, +0.001260f, 0.001406f, 0.002663f, 0.007332f, 0.000865f, 0.001171f, 0.003022f, 0.004305f, 0.000019f, 0.000024f, 0.000058f, 0.000116f, 0.000817f, 0.000983f, 0.003488f, 0.004145f, +0.000797f, 0.000891f, 0.002092f, 0.004856f, 0.000589f, 0.000799f, 0.002554f, 0.003069f, 0.000024f, 0.000030f, 0.000090f, 0.000151f, 0.000420f, 0.000506f, 0.002227f, 0.002232f, +0.004135f, 0.003973f, 0.008806f, 0.021610f, 0.002009f, 0.002342f, 0.007074f, 0.008984f, 0.000059f, 0.000064f, 0.000183f, 0.000323f, 0.002047f, 0.002120f, 0.008807f, 0.009329f, +0.000024f, 0.000026f, 0.000054f, 0.000163f, 0.000027f, 0.000035f, 0.000099f, 0.000156f, 0.000001f, 0.000001f, 0.000003f, 0.000006f, 0.000017f, 0.000020f, 0.000076f, 0.000099f, +3.455431f, 4.161424f, 1.949360f, 4.626055f, 3.011003f, 4.401187f, 2.808808f, 3.449512f, 2.262594f, 3.075724f, 1.857499f, 3.168871f, 5.032335f, 6.534312f, 5.735866f, 5.875980f, +1.722425f, 2.077345f, 1.206106f, 2.414027f, 1.615587f, 2.364927f, 1.870668f, 1.937627f, 2.216982f, 3.018086f, 2.259121f, 3.250525f, 2.039380f, 2.651900f, 2.885246f, 2.492885f, +8.810837f, 9.138522f, 5.009354f, 10.596160f, 5.435962f, 6.843119f, 5.110484f, 5.594300f, 5.468181f, 6.401808f, 4.524178f, 6.879608f, 9.798044f, 10.956930f, 11.254950f, 10.277160f, +0.676464f, 0.798150f, 0.407183f, 1.062037f, 0.956365f, 1.369565f, 0.951895f, 1.284863f, 0.960118f, 1.278691f, 0.841010f, 1.576917f, 1.056140f, 1.343544f, 1.284415f, 1.446167f, +0.228433f, 0.284531f, 0.102080f, 0.339311f, 0.142050f, 0.214750f, 0.104965f, 0.180559f, 0.193486f, 0.272033f, 0.125825f, 0.300661f, 0.529028f, 0.710461f, 0.477641f, 0.685360f, +0.185240f, 0.231065f, 0.102748f, 0.288048f, 0.123993f, 0.187723f, 0.113725f, 0.164994f, 0.308420f, 0.434253f, 0.248950f, 0.501722f, 0.348774f, 0.469066f, 0.390861f, 0.473018f, +1.229731f, 1.319169f, 0.553819f, 1.640859f, 0.541431f, 0.704941f, 0.403202f, 0.618219f, 0.987239f, 1.195401f, 0.647012f, 1.378074f, 2.174626f, 2.515159f, 1.978710f, 2.530742f, +0.100062f, 0.122107f, 0.047710f, 0.174299f, 0.100954f, 0.149525f, 0.079594f, 0.150482f, 0.183711f, 0.253051f, 0.127469f, 0.334772f, 0.248427f, 0.326859f, 0.239318f, 0.377420f, +3.591150f, 4.620509f, 1.926149f, 4.331472f, 2.378605f, 3.714476f, 2.109598f, 2.455060f, 2.976427f, 4.322674f, 2.323185f, 3.755662f, 6.525153f, 9.051854f, 7.071096f, 6.864277f, +1.394519f, 1.796840f, 0.928402f, 1.760840f, 0.994248f, 1.554886f, 1.094529f, 1.074305f, 2.271976f, 3.304378f, 2.201140f, 3.001154f, 2.060024f, 2.861856f, 2.770917f, 2.268661f, +8.457960f, 9.372188f, 4.571901f, 9.164115f, 3.966475f, 5.334564f, 3.545332f, 3.677625f, 6.644290f, 8.310457f, 5.226512f, 7.531175f, 11.734850f, 14.019860f, 12.815880f, 11.089310f, +1.004205f, 1.265840f, 0.574689f, 1.420400f, 1.079148f, 1.651036f, 1.021205f, 1.306193f, 1.804094f, 2.566945f, 1.502458f, 2.669542f, 1.956089f, 2.658494f, 2.261722f, 2.413121f, +0.003991f, 0.004991f, 0.007659f, 0.026031f, 0.002033f, 0.003086f, 0.006452f, 0.011348f, 0.000073f, 0.000103f, 0.000204f, 0.000499f, 0.002852f, 0.003845f, 0.011058f, 0.016223f, +0.002059f, 0.002579f, 0.004905f, 0.014060f, 0.001129f, 0.001716f, 0.004448f, 0.006598f, 0.000074f, 0.000105f, 0.000257f, 0.000530f, 0.001196f, 0.001615f, 0.005757f, 0.007124f, +0.018012f, 0.019399f, 0.034839f, 0.105541f, 0.006497f, 0.008493f, 0.020780f, 0.032577f, 0.000313f, 0.000380f, 0.000881f, 0.001918f, 0.009828f, 0.011412f, 0.038407f, 0.050226f, +0.000105f, 0.000129f, 0.000216f, 0.000807f, 0.000087f, 0.000130f, 0.000295f, 0.000571f, 0.000004f, 0.000006f, 0.000012f, 0.000034f, 0.000081f, 0.000107f, 0.000334f, 0.000539f, +3.233650f, 4.365643f, 1.656877f, 4.853903f, 2.092079f, 3.428091f, 1.772542f, 2.687287f, 2.573889f, 3.922348f, 1.919196f, 4.041823f, 5.191171f, 7.556333f, 5.374056f, 6.796191f, +1.314403f, 1.777102f, 0.835951f, 2.065475f, 0.915366f, 1.502096f, 0.962650f, 1.230904f, 2.056567f, 3.138541f, 1.903389f, 3.380832f, 1.715502f, 2.500725f, 2.204366f, 2.351175f, +11.342570f, 13.188210f, 5.857114f, 15.294410f, 5.195736f, 7.332300f, 4.436497f, 5.995231f, 8.557162f, 11.230650f, 6.430341f, 12.070910f, 13.903970f, 17.430250f, 14.506100f, 16.351670f, +0.880394f, 1.164482f, 0.481314f, 1.549750f, 0.924129f, 1.483566f, 0.835421f, 1.392050f, 1.518970f, 2.267805f, 1.208463f, 2.797197f, 1.515161f, 2.160751f, 1.673594f, 2.326191f, +0.021046f, 0.025521f, 0.010066f, 0.027190f, 0.018000f, 0.026492f, 0.014236f, 0.019900f, 0.014587f, 0.019967f, 0.010153f, 0.019715f, 0.044225f, 0.057821f, 0.042736f, 0.049832f, +0.031997f, 0.038857f, 0.018995f, 0.043276f, 0.029457f, 0.043418f, 0.028917f, 0.034093f, 0.043594f, 0.059757f, 0.037662f, 0.061682f, 0.054663f, 0.071572f, 0.065565f, 0.064481f, +0.140039f, 0.146252f, 0.067501f, 0.162524f, 0.084800f, 0.107490f, 0.067589f, 0.084217f, 0.091997f, 0.108450f, 0.064531f, 0.111694f, 0.224697f, 0.253011f, 0.218825f, 0.227439f, +0.016690f, 0.019829f, 0.008517f, 0.025287f, 0.023160f, 0.033395f, 0.019543f, 0.030026f, 0.025075f, 0.033626f, 0.018622f, 0.039743f, 0.037598f, 0.048160f, 0.038766f, 0.049682f, +0.439727f, 0.550810f, 0.252431f, 0.461308f, 0.400576f, 0.609006f, 0.380246f, 0.359609f, 0.298235f, 0.421674f, 0.249143f, 0.327307f, 0.724959f, 0.979089f, 0.840838f, 0.663320f, +0.320138f, 0.401591f, 0.228114f, 0.351591f, 0.313920f, 0.477953f, 0.369875f, 0.295024f, 0.426804f, 0.604333f, 0.442563f, 0.490364f, 0.429099f, 0.580356f, 0.617748f, 0.411017f, +1.280099f, 1.380958f, 0.740589f, 1.206351f, 0.825648f, 1.081062f, 0.789859f, 0.665830f, 0.822885f, 1.002021f, 0.692795f, 0.811257f, 1.611492f, 1.874371f, 1.883656f, 1.324526f, +0.222616f, 0.273196f, 0.136354f, 0.273873f, 0.329024f, 0.490077f, 0.333244f, 0.346385f, 0.327269f, 0.453341f, 0.291710f, 0.421200f, 0.393455f, 0.520599f, 0.486909f, 0.422174f, +0.000023f, 0.000029f, 0.000048f, 0.000133f, 0.000016f, 0.000024f, 0.000056f, 0.000080f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000015f, 0.000020f, 0.000063f, 0.000075f, +0.000023f, 0.000028f, 0.000058f, 0.000135f, 0.000017f, 0.000025f, 0.000072f, 0.000087f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000012f, 0.000016f, 0.000062f, 0.000062f, +0.000131f, 0.000137f, 0.000271f, 0.000666f, 0.000065f, 0.000083f, 0.000222f, 0.000283f, 0.000002f, 0.000002f, 0.000006f, 0.000010f, 0.000065f, 0.000073f, 0.000271f, 0.000288f, +0.000001f, 0.000001f, 0.000002f, 0.000007f, 0.000001f, 0.000002f, 0.000005f, 0.000007f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000003f, 0.000005f, +0.241574f, 0.317516f, 0.132480f, 0.315394f, 0.214955f, 0.342912f, 0.194925f, 0.240153f, 0.157347f, 0.233441f, 0.125572f, 0.214908f, 0.351880f, 0.498657f, 0.389883f, 0.400682f, +0.184097f, 0.242322f, 0.125315f, 0.251619f, 0.176330f, 0.281702f, 0.198473f, 0.206234f, 0.235708f, 0.350204f, 0.233486f, 0.337024f, 0.218013f, 0.309399f, 0.299832f, 0.259885f, +1.047359f, 1.185582f, 0.578856f, 1.228350f, 0.659847f, 0.906564f, 0.603031f, 0.662229f, 0.646586f, 0.826159f, 0.520036f, 0.793309f, 1.164919f, 1.421746f, 1.300798f, 1.191583f, +0.119074f, 0.153333f, 0.069674f, 0.182309f, 0.171903f, 0.268671f, 0.166326f, 0.225223f, 0.168113f, 0.244354f, 0.143149f, 0.269266f, 0.185939f, 0.258154f, 0.219819f, 0.248292f, +0.010686f, 0.013386f, 0.006060f, 0.012610f, 0.008188f, 0.012449f, 0.007679f, 0.008269f, 0.007803f, 0.011033f, 0.006440f, 0.009633f, 0.020728f, 0.027996f, 0.023752f, 0.021334f, +0.010956f, 0.013744f, 0.007713f, 0.013535f, 0.009037f, 0.013759f, 0.010519f, 0.009554f, 0.015726f, 0.022269f, 0.016111f, 0.020325f, 0.017278f, 0.023370f, 0.024575f, 0.018617f, +0.075950f, 0.081939f, 0.043411f, 0.080515f, 0.041205f, 0.053955f, 0.038945f, 0.037380f, 0.052566f, 0.064013f, 0.043723f, 0.058296f, 0.112494f, 0.130854f, 0.129911f, 0.104011f, +0.009302f, 0.011416f, 0.005629f, 0.012873f, 0.011564f, 0.017226f, 0.011572f, 0.013695f, 0.014723f, 0.020396f, 0.012966f, 0.021316f, 0.019343f, 0.025596f, 0.023650f, 0.023348f, +0.219882f, 0.284526f, 0.149681f, 0.210707f, 0.179460f, 0.281851f, 0.202007f, 0.147162f, 0.157114f, 0.229482f, 0.155641f, 0.157505f, 0.334638f, 0.466873f, 0.460248f, 0.279683f, +0.107958f, 0.139899f, 0.091219f, 0.108302f, 0.094845f, 0.149174f, 0.132516f, 0.081421f, 0.151634f, 0.221799f, 0.186449f, 0.159136f, 0.133576f, 0.186630f, 0.228035f, 0.116873f, +0.683741f, 0.761980f, 0.469076f, 0.588578f, 0.395112f, 0.534431f, 0.448222f, 0.291052f, 0.463061f, 0.582493f, 0.462298f, 0.417004f, 0.794570f, 0.954717f, 1.101345f, 0.596550f, +0.122190f, 0.154906f, 0.088749f, 0.137313f, 0.161802f, 0.248963f, 0.194328f, 0.155595f, 0.189249f, 0.270813f, 0.200031f, 0.222485f, 0.199356f, 0.272491f, 0.292550f, 0.195392f, +0.000144f, 0.000181f, 0.000350f, 0.000745f, 0.000090f, 0.000138f, 0.000363f, 0.000400f, 0.000002f, 0.000003f, 0.000008f, 0.000012f, 0.000086f, 0.000117f, 0.000423f, 0.000389f, +0.000094f, 0.000118f, 0.000283f, 0.000509f, 0.000063f, 0.000097f, 0.000317f, 0.000294f, 0.000003f, 0.000004f, 0.000013f, 0.000017f, 0.000046f, 0.000062f, 0.000279f, 0.000216f, +0.000856f, 0.000927f, 0.002102f, 0.003986f, 0.000381f, 0.000500f, 0.001545f, 0.001516f, 0.000013f, 0.000016f, 0.000046f, 0.000062f, 0.000391f, 0.000457f, 0.001941f, 0.001589f, +0.000008f, 0.000009f, 0.000020f, 0.000046f, 0.000008f, 0.000011f, 0.000033f, 0.000040f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000005f, 0.000006f, 0.000025f, 0.000026f, +0.223652f, 0.303672f, 0.145442f, 0.266722f, 0.178298f, 0.293831f, 0.191728f, 0.181958f, 0.153473f, 0.235215f, 0.145239f, 0.191473f, 0.300727f, 0.440246f, 0.395121f, 0.312796f, +0.114943f, 0.156294f, 0.092780f, 0.143503f, 0.098637f, 0.162786f, 0.131653f, 0.105379f, 0.155046f, 0.237969f, 0.182123f, 0.202501f, 0.125653f, 0.184215f, 0.204921f, 0.136821f, +1.035765f, 1.211189f, 0.678819f, 1.109609f, 0.584638f, 0.829767f, 0.633578f, 0.535961f, 0.673663f, 0.889190f, 0.642492f, 0.754989f, 1.063449f, 1.340782f, 1.408151f, 0.993637f, +0.121008f, 0.160970f, 0.083962f, 0.169233f, 0.156516f, 0.252702f, 0.179577f, 0.187313f, 0.179990f, 0.270260f, 0.181741f, 0.263336f, 0.174431f, 0.250176f, 0.244531f, 0.212763f, +0.004201f, 0.004668f, 0.002067f, 0.005566f, 0.003818f, 0.005150f, 0.003107f, 0.004329f, 0.003070f, 0.003850f, 0.002198f, 0.004255f, 0.008121f, 0.009728f, 0.008073f, 0.009383f, +0.004784f, 0.005323f, 0.002921f, 0.006634f, 0.004680f, 0.006321f, 0.004726f, 0.005554f, 0.006871f, 0.008630f, 0.006106f, 0.009969f, 0.007518f, 0.009019f, 0.009276f, 0.009093f, +0.020169f, 0.019300f, 0.010001f, 0.024003f, 0.012980f, 0.015075f, 0.010642f, 0.013218f, 0.013969f, 0.015088f, 0.010079f, 0.017391f, 0.029770f, 0.030714f, 0.029824f, 0.030899f, +0.002340f, 0.002548f, 0.001229f, 0.003636f, 0.003451f, 0.004560f, 0.002996f, 0.004588f, 0.003707f, 0.004555f, 0.002832f, 0.006025f, 0.004850f, 0.005692f, 0.005144f, 0.006571f, +0.125703f, 0.144273f, 0.074232f, 0.135225f, 0.121696f, 0.169526f, 0.118835f, 0.112028f, 0.089880f, 0.116441f, 0.077240f, 0.101150f, 0.190640f, 0.235910f, 0.227459f, 0.178867f, +0.068541f, 0.078780f, 0.050240f, 0.077189f, 0.071427f, 0.099644f, 0.086574f, 0.068834f, 0.096335f, 0.124984f, 0.102759f, 0.113496f, 0.084510f, 0.104729f, 0.125156f, 0.083007f, +0.264025f, 0.260979f, 0.157134f, 0.255141f, 0.180978f, 0.217123f, 0.178103f, 0.149658f, 0.178931f, 0.199639f, 0.154968f, 0.180888f, 0.305752f, 0.325852f, 0.367649f, 0.257696f, +0.044703f, 0.050266f, 0.028167f, 0.056394f, 0.070216f, 0.095828f, 0.073157f, 0.075800f, 0.069283f, 0.087936f, 0.063527f, 0.091435f, 0.072679f, 0.088113f, 0.092524f, 0.079967f, +0.000004f, 0.000004f, 0.000008f, 0.000023f, 0.000003f, 0.000004f, 0.000010f, 0.000015f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000003f, 0.000010f, 0.000012f, +0.000003f, 0.000003f, 0.000008f, 0.000018f, 0.000002f, 0.000003f, 0.000010f, 0.000012f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000007f, 0.000007f, +0.000016f, 0.000015f, 0.000034f, 0.000084f, 0.000008f, 0.000010f, 0.000030f, 0.000038f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000007f, 0.000008f, 0.000031f, 0.000033f, +0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, +0.054888f, 0.066102f, 0.030964f, 0.073482f, 0.051904f, 0.075868f, 0.048419f, 0.059463f, 0.037690f, 0.051235f, 0.030942f, 0.052787f, 0.073546f, 0.095497f, 0.083828f, 0.085876f, +0.031327f, 0.037782f, 0.021936f, 0.043906f, 0.031888f, 0.046679f, 0.036923f, 0.038245f, 0.042286f, 0.057565f, 0.043089f, 0.061999f, 0.034127f, 0.044377f, 0.048282f, 0.041716f, +0.171696f, 0.178082f, 0.097617f, 0.206487f, 0.114958f, 0.144716f, 0.108075f, 0.118306f, 0.111747f, 0.130826f, 0.092455f, 0.140591f, 0.175671f, 0.196449f, 0.201792f, 0.184261f, +0.019005f, 0.022423f, 0.011439f, 0.029837f, 0.029158f, 0.041755f, 0.029021f, 0.039173f, 0.028287f, 0.037673f, 0.024778f, 0.046459f, 0.027299f, 0.034728f, 0.033200f, 0.037381f, +0.013775f, 0.017158f, 0.006156f, 0.020461f, 0.009296f, 0.014054f, 0.006869f, 0.011816f, 0.012236f, 0.017203f, 0.007957f, 0.019013f, 0.029352f, 0.039418f, 0.026500f, 0.038025f, +0.012790f, 0.015954f, 0.007094f, 0.019889f, 0.009291f, 0.014066f, 0.008522f, 0.012363f, 0.022332f, 0.031444f, 0.018026f, 0.036329f, 0.022157f, 0.029799f, 0.024830f, 0.030050f, +0.090974f, 0.097590f, 0.040971f, 0.121388f, 0.043468f, 0.056595f, 0.032370f, 0.049633f, 0.076591f, 0.092740f, 0.050196f, 0.106912f, 0.148016f, 0.171194f, 0.134681f, 0.172255f, +0.010672f, 0.013023f, 0.005088f, 0.018590f, 0.011685f, 0.017306f, 0.009212f, 0.017417f, 0.020547f, 0.028303f, 0.014257f, 0.037443f, 0.024378f, 0.032074f, 0.023484f, 0.037035f, +0.210946f, 0.271411f, 0.113143f, 0.254433f, 0.151628f, 0.236785f, 0.134480f, 0.156502f, 0.183351f, 0.266281f, 0.143110f, 0.231352f, 0.352652f, 0.489208f, 0.382157f, 0.370980f, +0.093793f, 0.120853f, 0.062443f, 0.118432f, 0.072571f, 0.113492f, 0.079890f, 0.078414f, 0.160251f, 0.233070f, 0.155255f, 0.211683f, 0.127479f, 0.177098f, 0.171470f, 0.140390f, +0.609503f, 0.675384f, 0.329463f, 0.660390f, 0.310194f, 0.417184f, 0.277259f, 0.287605f, 0.502120f, 0.628035f, 0.394976f, 0.569144f, 0.778046f, 0.929546f, 0.849720f, 0.735245f, +0.104328f, 0.131509f, 0.059705f, 0.147567f, 0.121668f, 0.186146f, 0.115136f, 0.147267f, 0.196556f, 0.279669f, 0.163693f, 0.290847f, 0.186975f, 0.254116f, 0.216190f, 0.230661f, +0.000044f, 0.000054f, 0.000083f, 0.000284f, 0.000024f, 0.000037f, 0.000076f, 0.000134f, 0.000001f, 0.000001f, 0.000002f, 0.000006f, 0.000029f, 0.000039f, 0.000111f, 0.000163f, +0.000026f, 0.000032f, 0.000061f, 0.000175f, 0.000015f, 0.000023f, 0.000060f, 0.000089f, 0.000001f, 0.000001f, 0.000003f, 0.000007f, 0.000014f, 0.000019f, 0.000066f, 0.000082f, +0.000241f, 0.000259f, 0.000466f, 0.001411f, 0.000094f, 0.000123f, 0.000302f, 0.000473f, 0.000004f, 0.000005f, 0.000012f, 0.000027f, 0.000121f, 0.000140f, 0.000473f, 0.000618f, +0.000002f, 0.000002f, 0.000004f, 0.000016f, 0.000002f, 0.000003f, 0.000006f, 0.000012f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000006f, 0.000010f, +0.177699f, 0.239905f, 0.091050f, 0.266736f, 0.124764f, 0.204438f, 0.105708f, 0.160259f, 0.148330f, 0.226040f, 0.110601f, 0.232926f, 0.262466f, 0.382049f, 0.271713f, 0.343616f, +0.082704f, 0.111818f, 0.052600f, 0.129963f, 0.062505f, 0.102569f, 0.065734f, 0.084051f, 0.135704f, 0.207099f, 0.125596f, 0.223086f, 0.099314f, 0.144772f, 0.127615f, 0.136114f, +0.764670f, 0.889096f, 0.394863f, 1.031087f, 0.380127f, 0.536441f, 0.324580f, 0.438619f, 0.604981f, 0.793993f, 0.454617f, 0.853398f, 0.862420f, 1.081145f, 0.899768f, 1.014243f, +0.085567f, 0.113178f, 0.046780f, 0.150623f, 0.097473f, 0.156479f, 0.088116f, 0.146826f, 0.154821f, 0.231146f, 0.123172f, 0.285104f, 0.135490f, 0.193220f, 0.149657f, 0.208015f, +0.031166f, 0.037793f, 0.014906f, 0.040264f, 0.032989f, 0.048553f, 0.026090f, 0.036471f, 0.026709f, 0.036559f, 0.018590f, 0.036098f, 0.073100f, 0.095574f, 0.070639f, 0.082369f, +0.040040f, 0.048624f, 0.023770f, 0.054154f, 0.045620f, 0.067242f, 0.044784f, 0.052800f, 0.067450f, 0.092459f, 0.058272f, 0.095436f, 0.076352f, 0.099970f, 0.091580f, 0.090066f, +0.155911f, 0.162827f, 0.075151f, 0.180943f, 0.116846f, 0.148110f, 0.093131f, 0.116043f, 0.126641f, 0.149289f, 0.088831f, 0.153755f, 0.279235f, 0.314422f, 0.271938f, 0.282643f, +0.020011f, 0.023774f, 0.010212f, 0.030318f, 0.034365f, 0.049553f, 0.028999f, 0.044554f, 0.037172f, 0.049848f, 0.027605f, 0.058916f, 0.050317f, 0.064452f, 0.051879f, 0.066488f, +0.496452f, 0.621864f, 0.284994f, 0.520817f, 0.559720f, 0.850957f, 0.531313f, 0.502477f, 0.416318f, 0.588633f, 0.347790f, 0.456901f, 0.913596f, 1.233851f, 1.059627f, 0.835918f, +0.305425f, 0.383135f, 0.217630f, 0.335433f, 0.370663f, 0.564346f, 0.436732f, 0.348352f, 0.503467f, 0.712883f, 0.522056f, 0.578443f, 0.456954f, 0.618030f, 0.657850f, 0.437699f, +1.086565f, 1.172176f, 0.628622f, 1.023968f, 0.867360f, 1.135678f, 0.829764f, 0.699468f, 0.863625f, 1.051631f, 0.727095f, 0.851422f, 1.526819f, 1.775886f, 1.784683f, 1.254932f, +0.203489f, 0.249724f, 0.124639f, 0.250343f, 0.372225f, 0.554424f, 0.376999f, 0.391865f, 0.369884f, 0.512371f, 0.329694f, 0.476045f, 0.401447f, 0.531174f, 0.496799f, 0.430749f, +0.000190f, 0.000232f, 0.000391f, 0.001079f, 0.000165f, 0.000244f, 0.000560f, 0.000801f, 0.000004f, 0.000005f, 0.000011f, 0.000021f, 0.000138f, 0.000181f, 0.000571f, 0.000681f, +0.000156f, 0.000190f, 0.000397f, 0.000924f, 0.000145f, 0.000215f, 0.000612f, 0.000738f, 0.000006f, 0.000008f, 0.000021f, 0.000035f, 0.000092f, 0.000120f, 0.000471f, 0.000474f, +0.000798f, 0.000837f, 0.001652f, 0.004067f, 0.000490f, 0.000623f, 0.001677f, 0.002137f, 0.000014f, 0.000017f, 0.000042f, 0.000075f, 0.000441f, 0.000499f, 0.001844f, 0.001960f, +0.000007f, 0.000009f, 0.000016f, 0.000049f, 0.000010f, 0.000015f, 0.000038f, 0.000059f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000006f, 0.000007f, 0.000025f, 0.000033f, +0.380443f, 0.500042f, 0.208636f, 0.496699f, 0.418966f, 0.668367f, 0.379927f, 0.468081f, 0.306389f, 0.454559f, 0.244515f, 0.418471f, 0.618559f, 0.876575f, 0.685363f, 0.704348f, +0.244998f, 0.322483f, 0.166770f, 0.334856f, 0.290424f, 0.463978f, 0.326896f, 0.339678f, 0.387849f, 0.576248f, 0.384194f, 0.554560f, 0.323850f, 0.459601f, 0.445389f, 0.386050f, +1.240093f, 1.403752f, 0.685376f, 1.454390f, 0.966928f, 1.328462f, 0.883670f, 0.970418f, 0.946583f, 1.209472f, 0.761317f, 1.161381f, 1.539576f, 1.879004f, 1.719157f, 1.574816f, +0.151827f, 0.195509f, 0.088839f, 0.232455f, 0.271274f, 0.423980f, 0.262473f, 0.355416f, 0.265038f, 0.385235f, 0.225681f, 0.424509f, 0.264637f, 0.367416f, 0.312856f, 0.353380f, +0.019566f, 0.024511f, 0.011097f, 0.023090f, 0.018555f, 0.028212f, 0.017402f, 0.018739f, 0.017666f, 0.024979f, 0.014580f, 0.021810f, 0.042364f, 0.057219f, 0.048545f, 0.043604f, +0.016952f, 0.021267f, 0.011934f, 0.020943f, 0.017305f, 0.026349f, 0.020144f, 0.018295f, 0.030087f, 0.042604f, 0.030822f, 0.038885f, 0.029841f, 0.040363f, 0.042444f, 0.032154f, +0.104555f, 0.112801f, 0.059762f, 0.110840f, 0.070204f, 0.091928f, 0.066353f, 0.063687f, 0.089474f, 0.108959f, 0.074423f, 0.099228f, 0.172861f, 0.201073f, 0.199625f, 0.159826f, +0.013790f, 0.016924f, 0.008345f, 0.019084f, 0.021218f, 0.031606f, 0.021231f, 0.025128f, 0.026988f, 0.037387f, 0.023766f, 0.039072f, 0.032009f, 0.042355f, 0.039135f, 0.038635f, +0.306958f, 0.397202f, 0.208956f, 0.294150f, 0.310063f, 0.486969f, 0.349018f, 0.254259f, 0.271192f, 0.396106f, 0.268650f, 0.271867f, 0.521448f, 0.727503f, 0.717179f, 0.435816f, +0.127356f, 0.165036f, 0.107609f, 0.127762f, 0.138475f, 0.217796f, 0.193474f, 0.118875f, 0.221174f, 0.323517f, 0.271956f, 0.232117f, 0.175890f, 0.245750f, 0.300271f, 0.153896f, +0.717628f, 0.799745f, 0.492324f, 0.617749f, 0.513240f, 0.694211f, 0.582229f, 0.378069f, 0.600924f, 0.755915f, 0.599934f, 0.541155f, 0.930866f, 1.118484f, 1.290264f, 0.698879f, +0.138107f, 0.175085f, 0.100311f, 0.155200f, 0.226337f, 0.348264f, 0.271837f, 0.217656f, 0.264478f, 0.378463f, 0.279546f, 0.310924f, 0.251511f, 0.343780f, 0.369087f, 0.246510f, +0.001443f, 0.001815f, 0.003515f, 0.007477f, 0.001121f, 0.001711f, 0.004515f, 0.004971f, 0.000028f, 0.000040f, 0.000100f, 0.000153f, 0.000964f, 0.001307f, 0.004744f, 0.004357f, +0.000795f, 0.001002f, 0.002405f, 0.004315f, 0.000665f, 0.001017f, 0.003326f, 0.003088f, 0.000031f, 0.000043f, 0.000134f, 0.000173f, 0.000432f, 0.000587f, 0.002639f, 0.002044f, +0.006464f, 0.007002f, 0.015869f, 0.030093f, 0.003556f, 0.004675f, 0.014434f, 0.014165f, 0.000120f, 0.000146f, 0.000428f, 0.000583f, 0.003298f, 0.003851f, 0.016355f, 0.013389f, +0.000061f, 0.000076f, 0.000159f, 0.000373f, 0.000077f, 0.000116f, 0.000332f, 0.000402f, 0.000003f, 0.000004f, 0.000010f, 0.000017f, 0.000044f, 0.000058f, 0.000231f, 0.000233f, +0.435520f, 0.591343f, 0.283221f, 0.519390f, 0.429710f, 0.708151f, 0.462077f, 0.438529f, 0.369523f, 0.566337f, 0.349697f, 0.461017f, 0.653665f, 0.956925f, 0.858841f, 0.679897f, +0.189143f, 0.257189f, 0.152674f, 0.236141f, 0.200882f, 0.331527f, 0.268123f, 0.214614f, 0.315459f, 0.484178f, 0.370551f, 0.412013f, 0.230797f, 0.338361f, 0.376394f, 0.251311f, +1.516405f, 1.773234f, 0.993820f, 1.624515f, 1.059334f, 1.503497f, 1.148012f, 0.971135f, 1.219469f, 1.609617f, 1.163042f, 1.366686f, 1.737873f, 2.191086f, 2.301178f, 1.623786f, +0.190783f, 0.253788f, 0.132377f, 0.266816f, 0.305406f, 0.493092f, 0.350405f, 0.365500f, 0.350872f, 0.526845f, 0.354286f, 0.513347f, 0.306971f, 0.440271f, 0.430337f, 0.374431f, +0.054962f, 0.061068f, 0.027042f, 0.072813f, 0.061827f, 0.083378f, 0.050301f, 0.070091f, 0.049657f, 0.062278f, 0.035554f, 0.068821f, 0.118587f, 0.142064f, 0.117884f, 0.137022f, +0.052884f, 0.058844f, 0.032296f, 0.073344f, 0.064035f, 0.086482f, 0.064665f, 0.075998f, 0.093920f, 0.117963f, 0.083469f, 0.136267f, 0.092766f, 0.111293f, 0.114462f, 0.112211f, +0.198380f, 0.189833f, 0.098367f, 0.236085f, 0.158003f, 0.183510f, 0.129550f, 0.160907f, 0.169879f, 0.183491f, 0.122581f, 0.211495f, 0.326837f, 0.337207f, 0.327432f, 0.339238f, +0.024789f, 0.026985f, 0.013013f, 0.038512f, 0.045243f, 0.059776f, 0.039274f, 0.060148f, 0.048546f, 0.059650f, 0.037087f, 0.078901f, 0.057339f, 0.067297f, 0.060816f, 0.077694f, +1.253790f, 1.439016f, 0.740412f, 1.348768f, 1.502272f, 2.092706f, 1.466961f, 1.382926f, 1.108452f, 1.436014f, 0.952573f, 1.247437f, 2.122470f, 2.626473f, 2.532387f, 1.991389f, +0.577700f, 0.664006f, 0.423455f, 0.650592f, 0.745088f, 1.039432f, 0.903094f, 0.718045f, 1.003951f, 1.302516f, 1.070900f, 1.182790f, 0.795079f, 0.985304f, 1.177481f, 0.780941f, +1.979902f, 1.957057f, 1.178331f, 1.913282f, 1.679646f, 2.015099f, 1.652960f, 1.388964f, 1.659041f, 1.851049f, 1.436855f, 1.677188f, 2.559265f, 2.727505f, 3.077362f, 2.157013f, +0.360997f, 0.405924f, 0.227461f, 0.455410f, 0.701775f, 0.957762f, 0.731176f, 0.757590f, 0.691785f, 0.878038f, 0.634318f, 0.912976f, 0.655134f, 0.794258f, 0.834013f, 0.720827f, +0.000285f, 0.000318f, 0.000602f, 0.001657f, 0.000263f, 0.000355f, 0.000917f, 0.001307f, 0.000006f, 0.000007f, 0.000017f, 0.000034f, 0.000190f, 0.000228f, 0.000810f, 0.000962f, +0.000174f, 0.000195f, 0.000457f, 0.001062f, 0.000173f, 0.000235f, 0.000750f, 0.000902f, 0.000007f, 0.000008f, 0.000026f, 0.000043f, 0.000094f, 0.000114f, 0.000500f, 0.000501f, +0.000862f, 0.000828f, 0.001836f, 0.004506f, 0.000563f, 0.000656f, 0.001981f, 0.002516f, 0.000016f, 0.000017f, 0.000050f, 0.000087f, 0.000438f, 0.000454f, 0.001886f, 0.001998f, +0.000008f, 0.000008f, 0.000017f, 0.000053f, 0.000012f, 0.000015f, 0.000043f, 0.000068f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000006f, 0.000007f, 0.000025f, 0.000033f, +0.763660f, 0.919686f, 0.430814f, 1.022371f, 0.893758f, 1.306407f, 0.833740f, 1.023921f, 0.648377f, 0.881390f, 0.532291f, 0.908082f, 1.142173f, 1.483072f, 1.301851f, 1.333652f, +0.368318f, 0.444213f, 0.257910f, 0.516208f, 0.464006f, 0.679221f, 0.537267f, 0.556498f, 0.614706f, 0.836829f, 0.626390f, 0.901278f, 0.447863f, 0.582377f, 0.633621f, 0.547456f, +1.795996f, 1.862791f, 1.021104f, 2.159916f, 1.488249f, 1.873498f, 1.399140f, 1.531599f, 1.445286f, 1.692052f, 1.195778f, 1.818339f, 2.051125f, 2.293725f, 2.356114f, 2.151423f, +0.214079f, 0.252589f, 0.128860f, 0.336101f, 0.406504f, 0.582135f, 0.404604f, 0.546132f, 0.393983f, 0.524709f, 0.345107f, 0.647085f, 0.343254f, 0.436663f, 0.417445f, 0.470016f, +0.031075f, 0.038706f, 0.013886f, 0.046158f, 0.025954f, 0.039237f, 0.019178f, 0.032990f, 0.034129f, 0.047984f, 0.022194f, 0.053033f, 0.073908f, 0.099256f, 0.066729f, 0.095749f, +0.024382f, 0.030414f, 0.013524f, 0.037914f, 0.021920f, 0.033187f, 0.020105f, 0.029168f, 0.052638f, 0.074114f, 0.042488f, 0.085629f, 0.047146f, 0.063406f, 0.052835f, 0.063941f, +0.154295f, 0.165516f, 0.069488f, 0.205879f, 0.091242f, 0.118797f, 0.067948f, 0.104182f, 0.160615f, 0.194481f, 0.105263f, 0.224200f, 0.280214f, 0.324094f, 0.254969f, 0.326102f, +0.019492f, 0.023786f, 0.009294f, 0.033953f, 0.026413f, 0.039121f, 0.020825f, 0.039371f, 0.046402f, 0.063917f, 0.032197f, 0.084558f, 0.049699f, 0.065389f, 0.047877f, 0.075504f, +0.362806f, 0.466800f, 0.194595f, 0.437599f, 0.322756f, 0.504022f, 0.286254f, 0.333130f, 0.389905f, 0.566261f, 0.304332f, 0.491983f, 0.677012f, 0.939168f, 0.733656f, 0.712197f, +0.136317f, 0.175645f, 0.090753f, 0.172125f, 0.130536f, 0.204143f, 0.143702f, 0.141047f, 0.287973f, 0.418830f, 0.278995f, 0.380397f, 0.206806f, 0.287301f, 0.278172f, 0.227751f, +0.788129f, 0.873318f, 0.426018f, 0.853929f, 0.496418f, 0.667639f, 0.443710f, 0.460267f, 0.802792f, 1.004105f, 0.631490f, 0.909949f, 1.122984f, 1.341651f, 1.226435f, 1.061208f, +0.145276f, 0.183127f, 0.083139f, 0.205487f, 0.209684f, 0.320805f, 0.198425f, 0.253800f, 0.338419f, 0.481518f, 0.281837f, 0.500764f, 0.290621f, 0.394978f, 0.336029f, 0.358523f, +0.000538f, 0.000673f, 0.001033f, 0.003510f, 0.000368f, 0.000559f, 0.001169f, 0.002055f, 0.000013f, 0.000018f, 0.000036f, 0.000087f, 0.000395f, 0.000533f, 0.001532f, 0.002247f, +0.000269f, 0.000336f, 0.000640f, 0.001835f, 0.000198f, 0.000301f, 0.000780f, 0.001156f, 0.000013f, 0.000018f, 0.000044f, 0.000090f, 0.000160f, 0.000216f, 0.000772f, 0.000955f, +0.002240f, 0.002413f, 0.004334f, 0.013128f, 0.001085f, 0.001419f, 0.003472f, 0.005442f, 0.000050f, 0.000061f, 0.000142f, 0.000309f, 0.001255f, 0.001458f, 0.004906f, 0.006416f, +0.000020f, 0.000025f, 0.000042f, 0.000156f, 0.000023f, 0.000034f, 0.000077f, 0.000148f, 0.000001f, 0.000001f, 0.000003f, 0.000008f, 0.000016f, 0.000021f, 0.000066f, 0.000107f, +0.426317f, 0.575557f, 0.218439f, 0.639928f, 0.370450f, 0.607020f, 0.313868f, 0.475845f, 0.440000f, 0.670516f, 0.328082f, 0.690940f, 0.702861f, 1.023094f, 0.727623f, 0.920174f, +0.167669f, 0.226692f, 0.106636f, 0.263478f, 0.156830f, 0.257355f, 0.164932f, 0.210892f, 0.340165f, 0.519129f, 0.314829f, 0.559205f, 0.224740f, 0.327608f, 0.288784f, 0.308016f, +1.379246f, 1.603674f, 0.712220f, 1.859786f, 0.848572f, 1.197517f, 0.724572f, 0.979146f, 1.349220f, 1.770754f, 1.013881f, 1.903239f, 1.736335f, 2.176699f, 1.811529f, 2.042005f, +0.166207f, 0.219839f, 0.090866f, 0.292573f, 0.234323f, 0.376175f, 0.211830f, 0.352970f, 0.371830f, 0.555137f, 0.295820f, 0.684728f, 0.293762f, 0.418930f, 0.324479f, 0.451006f, +0.009544f, 0.011573f, 0.004565f, 0.012330f, 0.009359f, 0.013775f, 0.007402f, 0.010347f, 0.007289f, 0.009977f, 0.005073f, 0.009851f, 0.036011f, 0.047082f, 0.034798f, 0.040577f, +0.014986f, 0.018199f, 0.008897f, 0.020268f, 0.015819f, 0.023316f, 0.015529f, 0.018308f, 0.022498f, 0.030840f, 0.019437f, 0.031833f, 0.045971f, 0.060192f, 0.055140f, 0.054228f, +0.057681f, 0.060240f, 0.027803f, 0.066942f, 0.040050f, 0.050765f, 0.031921f, 0.039774f, 0.041755f, 0.049222f, 0.029289f, 0.050695f, 0.166188f, 0.187130f, 0.161846f, 0.168217f, +0.008860f, 0.010526f, 0.004521f, 0.013424f, 0.014097f, 0.020327f, 0.011896f, 0.018276f, 0.014668f, 0.019670f, 0.010893f, 0.023248f, 0.035839f, 0.045908f, 0.036952f, 0.047358f, +0.243025f, 0.304417f, 0.139511f, 0.254952f, 0.253845f, 0.385927f, 0.240962f, 0.227884f, 0.181623f, 0.256797f, 0.151727f, 0.199328f, 0.719446f, 0.971643f, 0.834444f, 0.658276f, +0.182739f, 0.229233f, 0.130210f, 0.200693f, 0.205461f, 0.312821f, 0.242083f, 0.193094f, 0.268453f, 0.380116f, 0.278365f, 0.308431f, 0.439814f, 0.594848f, 0.633174f, 0.421281f, +0.642610f, 0.693242f, 0.371776f, 0.605589f, 0.475243f, 0.622260f, 0.454643f, 0.383252f, 0.455187f, 0.554278f, 0.383227f, 0.448755f, 1.452616f, 1.689578f, 1.697947f, 1.193942f, +0.144029f, 0.176754f, 0.088219f, 0.177192f, 0.244083f, 0.363559f, 0.247214f, 0.256963f, 0.233317f, 0.323195f, 0.207966f, 0.300282f, 0.457096f, 0.604806f, 0.565667f, 0.490460f, +0.000367f, 0.000447f, 0.000754f, 0.002082f, 0.000295f, 0.000436f, 0.001001f, 0.001431f, 0.000006f, 0.000008f, 0.000018f, 0.000036f, 0.000427f, 0.000561f, 0.001773f, 0.002114f, +0.000367f, 0.000447f, 0.000935f, 0.002177f, 0.000317f, 0.000469f, 0.001337f, 0.001611f, 0.000012f, 0.000016f, 0.000044f, 0.000074f, 0.000347f, 0.000456f, 0.001787f, 0.001797f, +0.001859f, 0.001949f, 0.003849f, 0.009475f, 0.001058f, 0.001346f, 0.003620f, 0.004612f, 0.000029f, 0.000034f, 0.000088f, 0.000155f, 0.001653f, 0.001869f, 0.006913f, 0.007347f, +0.000021f, 0.000025f, 0.000045f, 0.000137f, 0.000027f, 0.000039f, 0.000097f, 0.000153f, 0.000001f, 0.000001f, 0.000002f, 0.000005f, 0.000026f, 0.000033f, 0.000114f, 0.000149f, +0.152037f, 0.199832f, 0.083377f, 0.198496f, 0.155118f, 0.247456f, 0.140664f, 0.173302f, 0.109120f, 0.161891f, 0.087084f, 0.149038f, 0.397659f, 0.563532f, 0.440607f, 0.452811f, +0.119667f, 0.157514f, 0.081457f, 0.163557f, 0.131422f, 0.209958f, 0.147926f, 0.153710f, 0.168829f, 0.250838f, 0.167237f, 0.241397f, 0.254464f, 0.361129f, 0.349963f, 0.303337f, +0.598732f, 0.677748f, 0.330908f, 0.702197f, 0.432511f, 0.594226f, 0.395269f, 0.434071f, 0.407295f, 0.520410f, 0.327579f, 0.499718f, 1.195777f, 1.459408f, 1.335256f, 1.223148f, +0.087729f, 0.112969f, 0.051333f, 0.134318f, 0.145221f, 0.226968f, 0.140509f, 0.190264f, 0.136482f, 0.198378f, 0.116215f, 0.218602f, 0.245989f, 0.341526f, 0.290811f, 0.328479f, +0.005752f, 0.007206f, 0.003262f, 0.006788f, 0.005054f, 0.007684f, 0.004740f, 0.005104f, 0.004628f, 0.006545f, 0.003820f, 0.005714f, 0.020036f, 0.027061f, 0.022959f, 0.020622f, +0.006091f, 0.007642f, 0.004288f, 0.007525f, 0.005761f, 0.008772f, 0.006706f, 0.006090f, 0.009635f, 0.013643f, 0.009870f, 0.012452f, 0.017249f, 0.023331f, 0.024534f, 0.018586f, +0.037136f, 0.040065f, 0.021226f, 0.039368f, 0.023101f, 0.030250f, 0.021834f, 0.020957f, 0.028322f, 0.034489f, 0.023557f, 0.031409f, 0.098768f, 0.114888f, 0.114061f, 0.091321f, +0.005862f, 0.007194f, 0.003547f, 0.008112f, 0.008356f, 0.012447f, 0.008361f, 0.009896f, 0.010224f, 0.014163f, 0.009003f, 0.014802f, 0.021888f, 0.028963f, 0.026761f, 0.026419f, +0.144259f, 0.186670f, 0.098202f, 0.138239f, 0.135001f, 0.212026f, 0.151962f, 0.110704f, 0.113583f, 0.165900f, 0.112518f, 0.113865f, 0.394227f, 0.550008f, 0.542204f, 0.329487f, +0.073153f, 0.094797f, 0.061811f, 0.073387f, 0.073690f, 0.115902f, 0.102959f, 0.063260f, 0.113220f, 0.165609f, 0.139215f, 0.118821f, 0.162528f, 0.227081f, 0.277460f, 0.142204f, +0.407457f, 0.454082f, 0.279533f, 0.350747f, 0.269978f, 0.365173f, 0.306267f, 0.198874f, 0.304071f, 0.382497f, 0.303570f, 0.273827f, 0.850239f, 1.021606f, 1.178507f, 0.638345f, +0.093846f, 0.118973f, 0.068163f, 0.105461f, 0.142489f, 0.219246f, 0.171132f, 0.137023f, 0.160163f, 0.229190f, 0.169287f, 0.188289f, 0.274933f, 0.375795f, 0.403458f, 0.269467f, +0.002671f, 0.003360f, 0.006507f, 0.013844f, 0.001923f, 0.002935f, 0.007745f, 0.008527f, 0.000047f, 0.000066f, 0.000165f, 0.000252f, 0.002871f, 0.003893f, 0.014130f, 0.012977f, +0.001800f, 0.002267f, 0.005442f, 0.009765f, 0.001395f, 0.002132f, 0.006972f, 0.006474f, 0.000062f, 0.000088f, 0.000271f, 0.000350f, 0.001573f, 0.002136f, 0.009607f, 0.007441f, +0.014460f, 0.015662f, 0.035497f, 0.067314f, 0.007369f, 0.009688f, 0.029913f, 0.029356f, 0.000239f, 0.000292f, 0.000852f, 0.001162f, 0.011866f, 0.013858f, 0.058855f, 0.048179f, +0.000164f, 0.000202f, 0.000427f, 0.000998f, 0.000192f, 0.000287f, 0.000824f, 0.000998f, 0.000006f, 0.000009f, 0.000023f, 0.000039f, 0.000189f, 0.000251f, 0.000994f, 0.001003f, +0.167093f, 0.226876f, 0.108661f, 0.199270f, 0.152739f, 0.251710f, 0.164243f, 0.155874f, 0.126347f, 0.193641f, 0.119568f, 0.157630f, 0.403437f, 0.590607f, 0.530070f, 0.419627f, +0.088694f, 0.120602f, 0.071592f, 0.110732f, 0.087270f, 0.144028f, 0.116482f, 0.093236f, 0.131831f, 0.202339f, 0.154854f, 0.172181f, 0.174101f, 0.255243f, 0.283933f, 0.189576f, +0.702884f, 0.821929f, 0.460655f, 0.752995f, 0.454910f, 0.645648f, 0.492992f, 0.417035f, 0.503746f, 0.664911f, 0.480437f, 0.564559f, 1.295858f, 1.633800f, 1.715891f, 1.210788f, +0.105834f, 0.140785f, 0.073434f, 0.148012f, 0.156959f, 0.253418f, 0.180086f, 0.187844f, 0.173463f, 0.260459f, 0.175150f, 0.253786f, 0.273938f, 0.392894f, 0.384030f, 0.334139f, +0.011345f, 0.012605f, 0.005582f, 0.015029f, 0.011823f, 0.015944f, 0.009619f, 0.013404f, 0.009134f, 0.011456f, 0.006540f, 0.012660f, 0.039377f, 0.047172f, 0.039143f, 0.045498f, +0.013341f, 0.014845f, 0.008148f, 0.018503f, 0.014967f, 0.020213f, 0.015114f, 0.017763f, 0.021116f, 0.026522f, 0.018766f, 0.030637f, 0.037648f, 0.045167f, 0.046453f, 0.045540f, +0.049471f, 0.047339f, 0.024530f, 0.058873f, 0.036504f, 0.042397f, 0.029930f, 0.037175f, 0.037754f, 0.040779f, 0.027242f, 0.047003f, 0.131115f, 0.135275f, 0.131354f, 0.136090f, +0.007398f, 0.008053f, 0.003884f, 0.011494f, 0.012509f, 0.016528f, 0.010859f, 0.016631f, 0.012912f, 0.015865f, 0.009864f, 0.020986f, 0.027529f, 0.032310f, 0.029198f, 0.037301f, +0.413703f, 0.474820f, 0.244308f, 0.445042f, 0.459237f, 0.639730f, 0.448443f, 0.422754f, 0.325952f, 0.422275f, 0.280114f, 0.366822f, 1.126618f, 1.394145f, 1.344204f, 1.057039f, +0.232980f, 0.267786f, 0.170774f, 0.262376f, 0.278387f, 0.388362f, 0.337422f, 0.268282f, 0.360828f, 0.468135f, 0.384891f, 0.425105f, 0.515819f, 0.639230f, 0.763908f, 0.506647f, +0.789272f, 0.780165f, 0.469732f, 0.762714f, 0.620333f, 0.744224f, 0.610478f, 0.512977f, 0.589403f, 0.657617f, 0.510467f, 0.595850f, 1.641229f, 1.749120f, 1.973479f, 1.383269f, +0.172228f, 0.193662f, 0.108519f, 0.217271f, 0.310186f, 0.423332f, 0.323181f, 0.334856f, 0.294132f, 0.373323f, 0.269698f, 0.388178f, 0.502806f, 0.609582f, 0.640093f, 0.553224f, +0.000370f, 0.000413f, 0.000783f, 0.002155f, 0.000316f, 0.000428f, 0.001105f, 0.001574f, 0.000006f, 0.000008f, 0.000020f, 0.000039f, 0.000397f, 0.000477f, 0.001693f, 0.002013f, +0.000277f, 0.000310f, 0.000727f, 0.001688f, 0.000255f, 0.000345f, 0.001105f, 0.001327f, 0.000009f, 0.000012f, 0.000036f, 0.000060f, 0.000241f, 0.000291f, 0.001279f, 0.001282f, +0.001354f, 0.001301f, 0.002884f, 0.007076f, 0.000819f, 0.000955f, 0.002883f, 0.003661f, 0.000022f, 0.000024f, 0.000069f, 0.000122f, 0.001107f, 0.001147f, 0.004765f, 0.005047f, +0.000015f, 0.000016f, 0.000033f, 0.000099f, 0.000020f, 0.000027f, 0.000075f, 0.000118f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000017f, 0.000020f, 0.000076f, 0.000100f, +0.205707f, 0.247736f, 0.116048f, 0.275396f, 0.223046f, 0.326026f, 0.208068f, 0.255529f, 0.155650f, 0.211588f, 0.127782f, 0.217995f, 0.494940f, 0.642663f, 0.564134f, 0.577914f, +0.121262f, 0.146249f, 0.084912f, 0.169952f, 0.141531f, 0.207175f, 0.163876f, 0.169742f, 0.180361f, 0.245534f, 0.183789f, 0.264443f, 0.237202f, 0.308445f, 0.335585f, 0.289949f, +0.584486f, 0.606224f, 0.332306f, 0.702919f, 0.448713f, 0.564867f, 0.421847f, 0.461783f, 0.419175f, 0.490744f, 0.346810f, 0.527370f, 1.073821f, 1.200829f, 1.233491f, 1.126330f, +0.083380f, 0.098378f, 0.050188f, 0.130905f, 0.146681f, 0.210055f, 0.145996f, 0.197064f, 0.136752f, 0.182127f, 0.119787f, 0.224605f, 0.215066f, 0.273591f, 0.261551f, 0.294489f, +0.005958f, 0.007422f, 0.002663f, 0.008851f, 0.004611f, 0.006970f, 0.003407f, 0.005860f, 0.005832f, 0.008200f, 0.003793f, 0.009063f, 0.022798f, 0.030616f, 0.020583f, 0.029535f, +0.005714f, 0.007128f, 0.003169f, 0.008885f, 0.004759f, 0.007206f, 0.004365f, 0.006333f, 0.010994f, 0.015479f, 0.008874f, 0.017884f, 0.017774f, 0.023905f, 0.019919f, 0.024106f, +0.035743f, 0.038343f, 0.016097f, 0.047693f, 0.019582f, 0.025496f, 0.014583f, 0.022360f, 0.033159f, 0.040151f, 0.021732f, 0.046286f, 0.104425f, 0.120778f, 0.095018f, 0.121526f, +0.005404f, 0.006595f, 0.002577f, 0.009413f, 0.006784f, 0.010048f, 0.005349f, 0.010113f, 0.011465f, 0.015792f, 0.007955f, 0.020892f, 0.022166f, 0.029164f, 0.021353f, 0.033675f, +0.111207f, 0.143084f, 0.059647f, 0.134133f, 0.091655f, 0.143131f, 0.081290f, 0.094601f, 0.106510f, 0.154685f, 0.083134f, 0.134394f, 0.333830f, 0.463098f, 0.361761f, 0.351180f, +0.051069f, 0.065803f, 0.034000f, 0.064485f, 0.045307f, 0.070855f, 0.049877f, 0.048955f, 0.096147f, 0.139837f, 0.093149f, 0.127005f, 0.124636f, 0.173149f, 0.167647f, 0.137259f, +0.291860f, 0.323407f, 0.157763f, 0.316227f, 0.170314f, 0.229057f, 0.152230f, 0.157911f, 0.264943f, 0.331382f, 0.208409f, 0.300308f, 0.668994f, 0.799260f, 0.730623f, 0.632193f, +0.064386f, 0.081161f, 0.036847f, 0.091070f, 0.086096f, 0.131722f, 0.081473f, 0.104210f, 0.133666f, 0.190186f, 0.111318f, 0.197788f, 0.207201f, 0.281604f, 0.239575f, 0.255612f, +0.000650f, 0.000813f, 0.001247f, 0.004239f, 0.000412f, 0.000625f, 0.001308f, 0.002300f, 0.000014f, 0.000019f, 0.000038f, 0.000094f, 0.000767f, 0.001034f, 0.002975f, 0.004365f, +0.000397f, 0.000497f, 0.000945f, 0.002708f, 0.000271f, 0.000411f, 0.001066f, 0.001581f, 0.000017f, 0.000023f, 0.000057f, 0.000118f, 0.000381f, 0.000514f, 0.001832f, 0.002267f, +0.003269f, 0.003520f, 0.006322f, 0.019153f, 0.001467f, 0.001918f, 0.004692f, 0.007356f, 0.000066f, 0.000080f, 0.000185f, 0.000402f, 0.002947f, 0.003422f, 0.011515f, 0.015058f, +0.000036f, 0.000044f, 0.000073f, 0.000272f, 0.000037f, 0.000054f, 0.000124f, 0.000239f, 0.000002f, 0.000002f, 0.000005f, 0.000013f, 0.000045f, 0.000059f, 0.000186f, 0.000300f, +0.106679f, 0.144023f, 0.054661f, 0.160131f, 0.085881f, 0.140725f, 0.072764f, 0.110315f, 0.098123f, 0.149529f, 0.073164f, 0.154084f, 0.282934f, 0.411843f, 0.292902f, 0.370412f, +0.051280f, 0.069332f, 0.032614f, 0.080583f, 0.044438f, 0.072921f, 0.046733f, 0.059756f, 0.092717f, 0.141496f, 0.085811f, 0.152419f, 0.110573f, 0.161184f, 0.142082f, 0.151545f, +0.416970f, 0.484819f, 0.215316f, 0.562246f, 0.237671f, 0.335405f, 0.202941f, 0.274243f, 0.363512f, 0.477083f, 0.273164f, 0.512777f, 0.844439f, 1.058603f, 0.881008f, 0.993096f, +0.060135f, 0.079540f, 0.032876f, 0.105856f, 0.078545f, 0.126094f, 0.071006f, 0.118316f, 0.119894f, 0.179000f, 0.095385f, 0.220785f, 0.170980f, 0.243833f, 0.188859f, 0.262502f, +0.033065f, 0.040096f, 0.015814f, 0.042718f, 0.026058f, 0.038352f, 0.020609f, 0.028809f, 0.021853f, 0.029912f, 0.015210f, 0.029536f, 0.075516f, 0.098733f, 0.072973f, 0.085091f, +0.062341f, 0.075707f, 0.037010f, 0.084316f, 0.052885f, 0.077949f, 0.051915f, 0.061208f, 0.080993f, 0.111022f, 0.069971f, 0.114597f, 0.115755f, 0.151562f, 0.138842f, 0.136546f, +0.198052f, 0.206838f, 0.095464f, 0.229851f, 0.110511f, 0.140080f, 0.088082f, 0.109752f, 0.124067f, 0.146254f, 0.087026f, 0.150630f, 0.345389f, 0.388912f, 0.336364f, 0.349605f, +0.022626f, 0.026881f, 0.011546f, 0.034280f, 0.028930f, 0.041716f, 0.024413f, 0.037508f, 0.032414f, 0.043468f, 0.024072f, 0.051376f, 0.055398f, 0.070960f, 0.057118f, 0.073202f, +0.503442f, 0.630620f, 0.289007f, 0.528150f, 0.422602f, 0.642493f, 0.401155f, 0.379382f, 0.325593f, 0.460356f, 0.271998f, 0.357332f, 0.902115f, 1.218345f, 1.046310f, 0.825413f, +0.454544f, 0.570194f, 0.323885f, 0.499203f, 0.410714f, 0.625324f, 0.483922f, 0.385992f, 0.577855f, 0.818214f, 0.599191f, 0.663910f, 0.662185f, 0.895605f, 0.953308f, 0.634282f, +1.319309f, 1.423258f, 0.763274f, 1.243303f, 0.784114f, 1.026680f, 0.750126f, 0.632335f, 0.808710f, 0.984761f, 0.680862f, 0.797283f, 1.805152f, 2.099623f, 2.110023f, 1.483701f, +0.219923f, 0.269892f, 0.134706f, 0.270561f, 0.299519f, 0.446130f, 0.303360f, 0.315323f, 0.308299f, 0.427062f, 0.274801f, 0.396785f, 0.422467f, 0.558987f, 0.522813f, 0.453304f, +0.000400f, 0.000488f, 0.000823f, 0.002272f, 0.000259f, 0.000382f, 0.000878f, 0.001255f, 0.000006f, 0.000008f, 0.000017f, 0.000034f, 0.000282f, 0.000370f, 0.001171f, 0.001396f, +0.000480f, 0.000586f, 0.001225f, 0.002853f, 0.000334f, 0.000494f, 0.001408f, 0.001697f, 0.000014f, 0.000019f, 0.000050f, 0.000084f, 0.000275f, 0.000362f, 0.001418f, 0.001426f, +0.002011f, 0.002109f, 0.004163f, 0.010250f, 0.000919f, 0.001170f, 0.003147f, 0.004009f, 0.000027f, 0.000032f, 0.000082f, 0.000145f, 0.001082f, 0.001223f, 0.004526f, 0.004810f, +0.000017f, 0.000020f, 0.000036f, 0.000110f, 0.000017f, 0.000025f, 0.000063f, 0.000099f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000012f, 0.000016f, 0.000055f, 0.000072f, +0.372567f, 0.489689f, 0.204317f, 0.486416f, 0.305480f, 0.487324f, 0.277015f, 0.341290f, 0.231400f, 0.343307f, 0.184670f, 0.316051f, 0.589836f, 0.835870f, 0.653538f, 0.671641f, +0.352107f, 0.463469f, 0.239679f, 0.481251f, 0.310767f, 0.496478f, 0.349793f, 0.363471f, 0.429886f, 0.638704f, 0.425834f, 0.614666f, 0.453203f, 0.643175f, 0.623287f, 0.540247f, +1.454077f, 1.645975f, 0.803641f, 1.705352f, 0.844144f, 1.159768f, 0.771458f, 0.847190f, 0.855991f, 1.093720f, 0.688456f, 1.050231f, 1.757801f, 2.145341f, 1.962836f, 1.798036f, +0.158461f, 0.204051f, 0.092721f, 0.242612f, 0.210800f, 0.329463f, 0.203960f, 0.276184f, 0.213333f, 0.310081f, 0.181653f, 0.341693f, 0.268942f, 0.373393f, 0.317945f, 0.359129f, +0.030523f, 0.038237f, 0.017312f, 0.036021f, 0.021552f, 0.032768f, 0.020212f, 0.021765f, 0.021254f, 0.030053f, 0.017542f, 0.026239f, 0.064352f, 0.086916f, 0.073741f, 0.066236f, +0.038811f, 0.048689f, 0.027322f, 0.047948f, 0.029498f, 0.044914f, 0.034338f, 0.031185f, 0.053122f, 0.075224f, 0.054421f, 0.068657f, 0.066524f, 0.089979f, 0.094618f, 0.071680f, +0.195295f, 0.210697f, 0.111627f, 0.207033f, 0.097633f, 0.127844f, 0.092277f, 0.088569f, 0.128889f, 0.156959f, 0.107208f, 0.142941f, 0.314396f, 0.365708f, 0.363074f, 0.290688f, +0.022927f, 0.028138f, 0.013874f, 0.031729f, 0.026265f, 0.039124f, 0.026282f, 0.031105f, 0.034604f, 0.047938f, 0.030473f, 0.050099f, 0.051819f, 0.068569f, 0.063356f, 0.062547f, +0.457711f, 0.592276f, 0.311579f, 0.438612f, 0.344232f, 0.540634f, 0.387480f, 0.282279f, 0.311866f, 0.455514f, 0.308942f, 0.312641f, 0.757111f, 1.056289f, 1.041300f, 0.632778f, +0.278695f, 0.361153f, 0.235484f, 0.279584f, 0.225616f, 0.354855f, 0.315227f, 0.193683f, 0.373270f, 0.545991f, 0.458973f, 0.391738f, 0.374790f, 0.523649f, 0.639823f, 0.327924f, +1.281242f, 1.427851f, 0.878988f, 1.102919f, 0.682246f, 0.922809f, 0.773952f, 0.502564f, 0.827425f, 1.040834f, 0.826061f, 0.745127f, 1.618281f, 1.944449f, 2.243083f, 1.214979f, +0.219475f, 0.278240f, 0.159411f, 0.246639f, 0.267803f, 0.412067f, 0.321639f, 0.257531f, 0.324143f, 0.463844f, 0.342611f, 0.381068f, 0.389192f, 0.531970f, 0.571129f, 0.381454f, +0.004466f, 0.005617f, 0.010878f, 0.023143f, 0.002583f, 0.003943f, 0.010405f, 0.011456f, 0.000067f, 0.000096f, 0.000238f, 0.000365f, 0.002905f, 0.003939f, 0.014297f, 0.013131f, +0.003613f, 0.004551f, 0.010924f, 0.019601f, 0.002250f, 0.003439f, 0.011247f, 0.010444f, 0.000107f, 0.000152f, 0.000471f, 0.000607f, 0.001911f, 0.002595f, 0.011672f, 0.009041f, +0.023956f, 0.025948f, 0.058810f, 0.111523f, 0.009812f, 0.012899f, 0.039828f, 0.039086f, 0.000342f, 0.000418f, 0.001222f, 0.001666f, 0.011900f, 0.013897f, 0.059021f, 0.048315f, +0.000202f, 0.000249f, 0.000526f, 0.001230f, 0.000190f, 0.000284f, 0.000816f, 0.000988f, 0.000007f, 0.000009f, 0.000025f, 0.000042f, 0.000141f, 0.000188f, 0.000741f, 0.000748f, +0.627138f, 0.851520f, 0.407831f, 0.747908f, 0.460701f, 0.759224f, 0.495402f, 0.470157f, 0.410369f, 0.628937f, 0.388351f, 0.511975f, 0.916529f, 1.341740f, 1.204214f, 0.953310f, +0.399710f, 0.543508f, 0.322640f, 0.499028f, 0.316070f, 0.521630f, 0.421869f, 0.337676f, 0.514132f, 0.789107f, 0.603920f, 0.671495f, 0.474919f, 0.696259f, 0.774519f, 0.517131f, +2.614502f, 3.057313f, 1.713490f, 2.800900f, 1.359864f, 1.930036f, 1.473700f, 1.246643f, 1.621517f, 2.140294f, 1.546487f, 1.817270f, 2.917610f, 3.678482f, 3.863309f, 2.726076f, +0.292788f, 0.389480f, 0.203154f, 0.409473f, 0.348963f, 0.563418f, 0.400380f, 0.417628f, 0.415278f, 0.623552f, 0.419318f, 0.607576f, 0.458718f, 0.657913f, 0.643069f, 0.559526f, +0.061907f, 0.068786f, 0.030459f, 0.082014f, 0.051850f, 0.069923f, 0.042184f, 0.058781f, 0.043136f, 0.054100f, 0.030885f, 0.059783f, 0.130064f, 0.155812f, 0.129292f, 0.150282f, +0.087418f, 0.097272f, 0.053387f, 0.121240f, 0.078812f, 0.106437f, 0.079587f, 0.093534f, 0.119734f, 0.150385f, 0.106410f, 0.173720f, 0.149316f, 0.179136f, 0.184237f, 0.180614f, +0.267545f, 0.256019f, 0.132662f, 0.318397f, 0.158655f, 0.184267f, 0.130085f, 0.161571f, 0.176692f, 0.190851f, 0.127497f, 0.219977f, 0.429207f, 0.442825f, 0.429989f, 0.445493f, +0.029758f, 0.032393f, 0.015622f, 0.046231f, 0.040437f, 0.053426f, 0.035102f, 0.053759f, 0.044944f, 0.055224f, 0.034335f, 0.073046f, 0.067023f, 0.078663f, 0.071088f, 0.090816f, +1.349875f, 1.549296f, 0.797155f, 1.452132f, 1.204221f, 1.677513f, 1.175916f, 1.108553f, 0.920371f, 1.192353f, 0.790941f, 1.035773f, 2.225081f, 2.753450f, 2.654816f, 2.087663f, +0.912790f, 1.049156f, 0.669075f, 1.027961f, 0.876525f, 1.222793f, 1.062404f, 0.844711f, 1.223369f, 1.587186f, 1.304950f, 1.441294f, 1.223245f, 1.515910f, 1.811579f, 1.201493f, +2.552297f, 2.522848f, 1.518990f, 2.466417f, 1.612108f, 1.934073f, 1.586495f, 1.333114f, 1.649384f, 1.840274f, 1.428491f, 1.667425f, 3.212464f, 3.423644f, 3.862794f, 2.707545f, +0.414220f, 0.465770f, 0.260996f, 0.522552f, 0.599533f, 0.818226f, 0.624651f, 0.647217f, 0.612174f, 0.776993f, 0.561320f, 0.807911f, 0.731968f, 0.887409f, 0.931827f, 0.805366f, +0.000637f, 0.000710f, 0.001345f, 0.003704f, 0.000437f, 0.000592f, 0.001527f, 0.002175f, 0.000010f, 0.000012f, 0.000030f, 0.000058f, 0.000413f, 0.000496f, 0.001762f, 0.002094f, +0.000572f, 0.000639f, 0.001500f, 0.003484f, 0.000423f, 0.000573f, 0.001833f, 0.002202f, 0.000017f, 0.000021f, 0.000065f, 0.000108f, 0.000301f, 0.000363f, 0.001598f, 0.001601f, +0.002307f, 0.002216f, 0.004913f, 0.012057f, 0.001121f, 0.001307f, 0.003947f, 0.005012f, 0.000033f, 0.000036f, 0.000102f, 0.000180f, 0.001142f, 0.001183f, 0.004914f, 0.005205f, +0.000018f, 0.000020f, 0.000042f, 0.000126f, 0.000021f, 0.000027f, 0.000077f, 0.000120f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000013f, 0.000015f, 0.000058f, 0.000076f, +0.793983f, 0.956205f, 0.447920f, 1.062967f, 0.691863f, 1.011297f, 0.645403f, 0.792623f, 0.519895f, 0.706735f, 0.426813f, 0.728138f, 1.156321f, 1.501443f, 1.317977f, 1.350173f, +0.561995f, 0.677799f, 0.393530f, 0.787652f, 0.527136f, 0.771632f, 0.610364f, 0.632212f, 0.723360f, 0.984746f, 0.737109f, 1.060586f, 0.665412f, 0.865266f, 0.941403f, 0.813382f, +2.235811f, 2.318964f, 1.271159f, 2.688851f, 1.379413f, 1.736489f, 1.296821f, 1.419593f, 1.387589f, 1.624504f, 1.148042f, 1.745749f, 2.486322f, 2.780397f, 2.856022f, 2.607901f, +0.237216f, 0.279888f, 0.142787f, 0.372425f, 0.335369f, 0.480266f, 0.333801f, 0.450563f, 0.336685f, 0.448399f, 0.294917f, 0.552978f, 0.370357f, 0.471141f, 0.450406f, 0.507128f, +0.064424f, 0.080246f, 0.028789f, 0.095695f, 0.040062f, 0.060565f, 0.029603f, 0.050923f, 0.054568f, 0.076721f, 0.035486f, 0.084795f, 0.149201f, 0.200370f, 0.134708f, 0.193291f, +0.074184f, 0.092536f, 0.041148f, 0.115356f, 0.049656f, 0.075178f, 0.045544f, 0.066076f, 0.123514f, 0.173907f, 0.099698f, 0.200927f, 0.139675f, 0.187849f, 0.156530f, 0.189432f, +0.383011f, 0.410867f, 0.172492f, 0.511060f, 0.168634f, 0.219560f, 0.125581f, 0.192550f, 0.307484f, 0.372318f, 0.201518f, 0.429214f, 0.677307f, 0.783369f, 0.616287f, 0.788222f, +0.043068f, 0.052556f, 0.020535f, 0.075020f, 0.043451f, 0.064357f, 0.034258f, 0.064769f, 0.079071f, 0.108916f, 0.054864f, 0.144089f, 0.106925f, 0.140683f, 0.103005f, 0.162445f, +0.718958f, 0.925038f, 0.385620f, 0.867172f, 0.476203f, 0.743648f, 0.422347f, 0.491509f, 0.595888f, 0.865410f, 0.465108f, 0.751893f, 1.306352f, 1.812204f, 1.415652f, 1.374246f, +0.396440f, 0.510814f, 0.263930f, 0.500579f, 0.282649f, 0.442030f, 0.311158f, 0.305408f, 0.645887f, 0.939383f, 0.625750f, 0.853182f, 0.585633f, 0.813581f, 0.787729f, 0.644945f, +1.870012f, 2.072143f, 1.010824f, 2.026139f, 0.876967f, 1.179445f, 0.783855f, 0.813104f, 1.469019f, 1.837400f, 1.155555f, 1.665104f, 2.594516f, 3.099718f, 2.833526f, 2.451791f, +0.306819f, 0.386757f, 0.175587f, 0.433980f, 0.329716f, 0.504448f, 0.312013f, 0.399086f, 0.551212f, 0.784289f, 0.459052f, 0.815636f, 0.597652f, 0.812260f, 0.691033f, 0.737291f, +0.002214f, 0.002768f, 0.004249f, 0.014440f, 0.001128f, 0.001712f, 0.003579f, 0.006295f, 0.000041f, 0.000057f, 0.000113f, 0.000277f, 0.001582f, 0.002133f, 0.006134f, 0.008999f, +0.001622f, 0.002031f, 0.003864f, 0.011075f, 0.000889f, 0.001352f, 0.003504f, 0.005197f, 0.000058f, 0.000083f, 0.000203f, 0.000417f, 0.000942f, 0.001272f, 0.004535f, 0.005612f, +0.011034f, 0.011884f, 0.021343f, 0.064656f, 0.003980f, 0.005203f, 0.012730f, 0.019957f, 0.000192f, 0.000233f, 0.000539f, 0.001175f, 0.006021f, 0.006991f, 0.023529f, 0.030769f, +0.000089f, 0.000109f, 0.000183f, 0.000683f, 0.000074f, 0.000110f, 0.000250f, 0.000483f, 0.000004f, 0.000005f, 0.000011f, 0.000028f, 0.000068f, 0.000090f, 0.000283f, 0.000456f, +0.815838f, 1.101436f, 0.418024f, 1.224622f, 0.527824f, 0.864895f, 0.447206f, 0.677993f, 0.649383f, 0.989594f, 0.484206f, 1.019737f, 1.309713f, 1.906435f, 1.355854f, 1.714654f, +0.470894f, 0.636659f, 0.299485f, 0.739970f, 0.327936f, 0.538136f, 0.344876f, 0.440980f, 0.736779f, 1.124403f, 0.681902f, 1.211206f, 0.614590f, 0.895901f, 0.789729f, 0.842324f, +3.160323f, 3.674564f, 1.631938f, 4.261402f, 1.447661f, 2.042961f, 1.236118f, 1.670421f, 2.384238f, 3.129139f, 1.791653f, 3.363256f, 3.873992f, 4.856502f, 4.041759f, 4.555981f, +0.338983f, 0.448367f, 0.185323f, 0.596709f, 0.355822f, 0.571225f, 0.321667f, 0.535988f, 0.584857f, 0.873185f, 0.465301f, 1.077020f, 0.583391f, 0.831966f, 0.644393f, 0.895666f, +0.131035f, 0.158899f, 0.062672f, 0.169290f, 0.112068f, 0.164943f, 0.088632f, 0.123898f, 0.090822f, 0.124315f, 0.063213f, 0.122751f, 0.275347f, 0.360001f, 0.266076f, 0.310260f, +0.165189f, 0.200605f, 0.098067f, 0.223418f, 0.152075f, 0.224150f, 0.149286f, 0.176008f, 0.225062f, 0.308506f, 0.194435f, 0.318440f, 0.282204f, 0.369501f, 0.338489f, 0.332892f, +0.716717f, 0.748513f, 0.345468f, 0.831791f, 0.434003f, 0.550128f, 0.345919f, 0.431020f, 0.470839f, 0.555041f, 0.330267f, 0.571647f, 1.149991f, 1.294903f, 1.119940f, 1.164028f, +0.079260f, 0.094165f, 0.040448f, 0.120084f, 0.109982f, 0.158589f, 0.092807f, 0.142590f, 0.119079f, 0.159686f, 0.088431f, 0.188735f, 0.178549f, 0.228708f, 0.184093f, 0.235933f, +2.296289f, 2.876369f, 1.318213f, 2.408985f, 2.091837f, 3.180274f, 1.985674f, 1.877903f, 1.557403f, 2.202013f, 1.301044f, 1.709219f, 3.785789f, 5.112872f, 4.390916f, 3.463905f, +1.386233f, 1.738933f, 0.987758f, 1.522429f, 1.359310f, 2.069589f, 1.601600f, 1.277489f, 1.848111f, 2.616831f, 1.916349f, 2.123333f, 1.858047f, 2.513008f, 2.674919f, 1.779752f, +5.495001f, 5.927953f, 3.179081f, 5.178430f, 3.544208f, 4.640610f, 3.390581f, 2.858166f, 3.532347f, 4.301316f, 2.973921f, 3.482435f, 6.917552f, 8.045999f, 8.085855f, 5.685714f, +0.886691f, 1.088155f, 0.543108f, 1.090853f, 1.310520f, 1.952004f, 1.327328f, 1.379670f, 1.303533f, 1.805681f, 1.161897f, 1.677665f, 1.567153f, 2.073577f, 1.939388f, 1.681541f, +0.000122f, 0.000149f, 0.000251f, 0.000693f, 0.000086f, 0.000126f, 0.000291f, 0.000415f, 0.000002f, 0.000003f, 0.000005f, 0.000011f, 0.000079f, 0.000104f, 0.000329f, 0.000392f, +0.000098f, 0.000119f, 0.000250f, 0.000582f, 0.000074f, 0.000109f, 0.000311f, 0.000375f, 0.000003f, 0.000004f, 0.000011f, 0.000018f, 0.000052f, 0.000068f, 0.000266f, 0.000267f, +0.000560f, 0.000587f, 0.001159f, 0.002854f, 0.000278f, 0.000354f, 0.000951f, 0.001212f, 0.000008f, 0.000009f, 0.000024f, 0.000042f, 0.000277f, 0.000313f, 0.001160f, 0.001232f, +0.000004f, 0.000005f, 0.000010f, 0.000030f, 0.000005f, 0.000007f, 0.000018f, 0.000029f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000004f, 0.000014f, 0.000018f, +0.856945f, 1.126341f, 0.469951f, 1.118811f, 0.762519f, 1.216428f, 0.691467f, 0.851906f, 0.558165f, 0.828095f, 0.445445f, 0.762352f, 1.248239f, 1.768909f, 1.383049f, 1.421359f, +0.541511f, 0.712775f, 0.368606f, 0.740123f, 0.518664f, 0.828610f, 0.583797f, 0.606626f, 0.693321f, 1.030103f, 0.686786f, 0.991335f, 0.641273f, 0.910078f, 0.881937f, 0.764437f, +3.054081f, 3.457137f, 1.687934f, 3.581848f, 1.924103f, 2.643524f, 1.758426f, 1.931047f, 1.885434f, 2.409064f, 1.516416f, 2.313275f, 3.396882f, 4.145787f, 3.793105f, 3.474635f, +0.322177f, 0.414869f, 0.188516f, 0.493270f, 0.465117f, 0.726939f, 0.450026f, 0.609382f, 0.454861f, 0.661146f, 0.387316f, 0.728548f, 0.503093f, 0.698484f, 0.594761f, 0.671801f, +0.071499f, 0.089567f, 0.040551f, 0.084377f, 0.054786f, 0.083299f, 0.051380f, 0.055327f, 0.052210f, 0.073825f, 0.043091f, 0.064457f, 0.138691f, 0.187321f, 0.158925f, 0.142750f, +0.060786f, 0.076257f, 0.042792f, 0.075097f, 0.050137f, 0.076340f, 0.058363f, 0.053005f, 0.087252f, 0.123553f, 0.089386f, 0.112768f, 0.095861f, 0.129661f, 0.136346f, 0.103291f, +0.417736f, 0.450681f, 0.238771f, 0.442844f, 0.226634f, 0.296764f, 0.214203f, 0.205595f, 0.289120f, 0.352084f, 0.240485f, 0.320639f, 0.618736f, 0.719719f, 0.714535f, 0.572079f, +0.047472f, 0.058262f, 0.028728f, 0.065698f, 0.059018f, 0.087912f, 0.059056f, 0.069893f, 0.075140f, 0.104092f, 0.066170f, 0.108785f, 0.098718f, 0.130628f, 0.120697f, 0.119155f, +1.233989f, 1.596777f, 0.840017f, 1.182500f, 1.007141f, 1.581765f, 1.133674f, 0.825882f, 0.881732f, 1.287866f, 0.873466f, 0.883925f, 1.878006f, 2.620116f, 2.582936f, 1.569599f, +0.502380f, 0.651020f, 0.424487f, 0.503982f, 0.441360f, 0.694182f, 0.616660f, 0.378890f, 0.705627f, 1.032138f, 0.867640f, 0.740538f, 0.621597f, 0.868482f, 1.061159f, 0.543868f, +3.154243f, 3.515176f, 2.163948f, 2.715237f, 1.822738f, 2.465444f, 2.067745f, 1.342687f, 2.136199f, 2.687167f, 2.132679f, 1.923727f, 3.665521f, 4.404313f, 5.080741f, 2.752012f, +0.523034f, 0.663075f, 0.379893f, 0.587768f, 0.692594f, 1.065690f, 0.831823f, 0.666028f, 0.810084f, 1.159216f, 0.856237f, 0.952348f, 0.853345f, 1.166402f, 1.252264f, 0.836379f, +0.000805f, 0.001012f, 0.001961f, 0.004172f, 0.000505f, 0.000771f, 0.002035f, 0.002241f, 0.000013f, 0.000018f, 0.000045f, 0.000069f, 0.000482f, 0.000653f, 0.002371f, 0.002178f, +0.000435f, 0.000548f, 0.001317f, 0.002362f, 0.000294f, 0.000450f, 0.001471f, 0.001366f, 0.000014f, 0.000019f, 0.000060f, 0.000077f, 0.000212f, 0.000288f, 0.001294f, 0.001003f, +0.003943f, 0.004271f, 0.009680f, 0.018357f, 0.001753f, 0.002304f, 0.007114f, 0.006982f, 0.000059f, 0.000072f, 0.000211f, 0.000288f, 0.001802f, 0.002105f, 0.008938f, 0.007317f, +0.000032f, 0.000040f, 0.000084f, 0.000196f, 0.000033f, 0.000049f, 0.000141f, 0.000171f, 0.000001f, 0.000002f, 0.000004f, 0.000007f, 0.000021f, 0.000027f, 0.000109f, 0.000110f, +0.852619f, 1.157675f, 0.554463f, 1.016812f, 0.679720f, 1.120162f, 0.730919f, 0.693671f, 0.585080f, 0.896702f, 0.553688f, 0.729945f, 1.146452f, 1.678333f, 1.506306f, 1.192459f, +0.363346f, 0.494061f, 0.293287f, 0.453628f, 0.311801f, 0.514584f, 0.416170f, 0.333115f, 0.490115f, 0.752246f, 0.575710f, 0.640128f, 0.397202f, 0.582322f, 0.647776f, 0.432507f, +3.245825f, 3.795562f, 2.127246f, 3.477233f, 1.832106f, 2.600282f, 1.985474f, 1.679566f, 2.111090f, 2.786498f, 2.013407f, 2.365946f, 3.332582f, 4.201674f, 4.412789f, 3.113807f, +0.351859f, 0.468059f, 0.244141f, 0.492086f, 0.455107f, 0.734793f, 0.522165f, 0.544658f, 0.523365f, 0.785846f, 0.528456f, 0.765713f, 0.507200f, 0.727447f, 0.711035f, 0.618662f, +0.017202f, 0.019113f, 0.008463f, 0.022789f, 0.015635f, 0.021085f, 0.012720f, 0.017725f, 0.012570f, 0.015764f, 0.009000f, 0.017420f, 0.033251f, 0.039834f, 0.033054f, 0.038420f, +0.016241f, 0.018072f, 0.009918f, 0.022525f, 0.015890f, 0.021460f, 0.016046f, 0.018858f, 0.023328f, 0.029300f, 0.020732f, 0.033846f, 0.025523f, 0.030621f, 0.031493f, 0.030873f, +0.067885f, 0.064960f, 0.033661f, 0.080787f, 0.043687f, 0.050739f, 0.035819f, 0.044489f, 0.047015f, 0.050783f, 0.033925f, 0.058533f, 0.100198f, 0.103377f, 0.100380f, 0.104000f, +0.007309f, 0.007956f, 0.003837f, 0.011355f, 0.010778f, 0.014240f, 0.009356f, 0.014329f, 0.011576f, 0.014224f, 0.008844f, 0.018815f, 0.015146f, 0.017776f, 0.016064f, 0.020523f, +0.431695f, 0.495470f, 0.254933f, 0.464397f, 0.417934f, 0.582194f, 0.408111f, 0.384732f, 0.308671f, 0.399887f, 0.265263f, 0.347374f, 0.654706f, 0.810173f, 0.781151f, 0.614272f, +0.195181f, 0.224340f, 0.143067f, 0.219807f, 0.203399f, 0.283751f, 0.246533f, 0.196017f, 0.274329f, 0.355912f, 0.292623f, 0.323197f, 0.240656f, 0.298234f, 0.356402f, 0.236377f, +0.745347f, 0.736746f, 0.443590f, 0.720267f, 0.510905f, 0.612941f, 0.502788f, 0.422487f, 0.505124f, 0.563584f, 0.437476f, 0.510649f, 0.863143f, 0.919884f, 1.037878f, 0.727479f, +0.117095f, 0.131667f, 0.073780f, 0.147719f, 0.183924f, 0.251014f, 0.191630f, 0.198553f, 0.181481f, 0.230342f, 0.166405f, 0.239508f, 0.190378f, 0.230806f, 0.242359f, 0.209468f, +0.000014f, 0.000015f, 0.000029f, 0.000079f, 0.000010f, 0.000014f, 0.000035f, 0.000050f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000008f, 0.000010f, 0.000035f, 0.000041f, +0.000008f, 0.000009f, 0.000021f, 0.000050f, 0.000007f, 0.000009f, 0.000028f, 0.000034f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000004f, 0.000005f, 0.000021f, 0.000021f, +0.000045f, 0.000043f, 0.000096f, 0.000235f, 0.000024f, 0.000028f, 0.000084f, 0.000106f, 0.000001f, 0.000001f, 0.000002f, 0.000004f, 0.000021f, 0.000021f, 0.000088f, 0.000094f, +0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000000f, 0.000001f, 0.000002f, 0.000002f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, +0.128046f, 0.154208f, 0.072236f, 0.171425f, 0.121086f, 0.176992f, 0.112955f, 0.138720f, 0.087927f, 0.119526f, 0.072184f, 0.123145f, 0.171574f, 0.222783f, 0.195560f, 0.200337f, +0.060600f, 0.073087f, 0.042434f, 0.084932f, 0.061685f, 0.090296f, 0.071424f, 0.073981f, 0.081798f, 0.111355f, 0.083353f, 0.119931f, 0.066016f, 0.085843f, 0.093397f, 0.080696f, +0.329256f, 0.341502f, 0.187197f, 0.395973f, 0.220451f, 0.277517f, 0.207252f, 0.226873f, 0.214293f, 0.250882f, 0.177299f, 0.269606f, 0.336879f, 0.376724f, 0.386971f, 0.353352f, +0.033816f, 0.039899f, 0.020355f, 0.053091f, 0.051882f, 0.074298f, 0.051640f, 0.069703f, 0.050333f, 0.067034f, 0.044089f, 0.082668f, 0.048575f, 0.061794f, 0.059075f, 0.066514f, +0.090023f, 0.112131f, 0.040229f, 0.133719f, 0.060751f, 0.091843f, 0.044891f, 0.077221f, 0.079964f, 0.112426f, 0.052001f, 0.124257f, 0.191819f, 0.257605f, 0.173187f, 0.248503f, +0.069310f, 0.086456f, 0.038444f, 0.107777f, 0.050348f, 0.076225f, 0.046178f, 0.066996f, 0.121019f, 0.170394f, 0.097684f, 0.196867f, 0.120067f, 0.161478f, 0.134555f, 0.162838f, +0.488719f, 0.524263f, 0.220098f, 0.652109f, 0.233513f, 0.304033f, 0.173896f, 0.266631f, 0.411453f, 0.498209f, 0.269656f, 0.574342f, 0.795153f, 0.919670f, 0.723517f, 0.925367f, +0.053196f, 0.064916f, 0.025364f, 0.092662f, 0.058244f, 0.086266f, 0.045921f, 0.086819f, 0.102422f, 0.141080f, 0.071066f, 0.186641f, 0.121514f, 0.159878f, 0.117058f, 0.184609f, +1.156272f, 1.487703f, 0.620178f, 1.394640f, 0.831128f, 1.297905f, 0.737132f, 0.857843f, 1.005011f, 1.459581f, 0.784439f, 1.268125f, 1.933013f, 2.681523f, 2.094743f, 2.033475f, +0.426302f, 0.549291f, 0.283811f, 0.538285f, 0.329842f, 0.515834f, 0.363111f, 0.356401f, 0.728359f, 1.059331f, 0.705650f, 0.962122f, 0.579405f, 0.804930f, 0.779352f, 0.638087f, +2.746283f, 3.043131f, 1.484487f, 2.975570f, 1.397666f, 1.879739f, 1.249268f, 1.295884f, 2.262441f, 2.829786f, 1.779675f, 2.564434f, 3.505700f, 4.188328f, 3.828650f, 3.312850f, +0.436176f, 0.549818f, 0.249616f, 0.616951f, 0.508675f, 0.778243f, 0.481362f, 0.615696f, 0.821766f, 1.169246f, 0.684370f, 1.215978f, 0.781711f, 1.062413f, 0.903851f, 0.964355f, +0.000238f, 0.000298f, 0.000457f, 0.001553f, 0.000132f, 0.000200f, 0.000418f, 0.000735f, 0.000005f, 0.000006f, 0.000013f, 0.000031f, 0.000157f, 0.000211f, 0.000607f, 0.000890f, +0.000117f, 0.000146f, 0.000278f, 0.000796f, 0.000069f, 0.000105f, 0.000273f, 0.000406f, 0.000004f, 0.000006f, 0.000015f, 0.000031f, 0.000062f, 0.000084f, 0.000300f, 0.000371f, +0.001083f, 0.001167f, 0.002096f, 0.006349f, 0.000424f, 0.000554f, 0.001356f, 0.002127f, 0.000020f, 0.000024f, 0.000056f, 0.000121f, 0.000544f, 0.000632f, 0.002126f, 0.002780f, +0.000008f, 0.000010f, 0.000017f, 0.000065f, 0.000008f, 0.000011f, 0.000026f, 0.000050f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000006f, 0.000008f, 0.000025f, 0.000040f, +0.661657f, 0.893281f, 0.339024f, 0.993186f, 0.464555f, 0.761221f, 0.393600f, 0.596723f, 0.552305f, 0.841657f, 0.411821f, 0.867293f, 0.977288f, 1.422553f, 1.011718f, 1.279448f, +0.255349f, 0.345238f, 0.162400f, 0.401260f, 0.192983f, 0.316682f, 0.202952f, 0.259507f, 0.418984f, 0.639415f, 0.387778f, 0.688777f, 0.306630f, 0.446981f, 0.394010f, 0.420251f, +2.340477f, 2.721314f, 1.208583f, 3.155916f, 1.163480f, 1.641920f, 0.993464f, 1.342510f, 1.851704f, 2.430228f, 1.391477f, 2.612053f, 2.639667f, 3.309131f, 2.753980f, 3.104362f, +0.243013f, 0.321430f, 0.132856f, 0.427775f, 0.276824f, 0.444405f, 0.250252f, 0.416991f, 0.439695f, 0.656460f, 0.349813f, 0.809702f, 0.384795f, 0.548751f, 0.425031f, 0.590767f, +0.265164f, 0.321549f, 0.126824f, 0.342577f, 0.280674f, 0.413098f, 0.221977f, 0.310301f, 0.227243f, 0.311047f, 0.158165f, 0.307131f, 0.621947f, 0.813162f, 0.601006f, 0.700808f, +0.282476f, 0.343039f, 0.167696f, 0.382049f, 0.321848f, 0.474386f, 0.315946f, 0.372500f, 0.475857f, 0.652288f, 0.411103f, 0.673292f, 0.538657f, 0.705284f, 0.646090f, 0.635406f, +1.090418f, 1.138793f, 0.525598f, 1.265492f, 0.817205f, 1.035861f, 0.651347f, 0.811587f, 0.885710f, 1.044105f, 0.621275f, 1.075344f, 1.952932f, 2.199022f, 1.901899f, 1.976769f, +0.129859f, 0.154279f, 0.066270f, 0.196745f, 0.223014f, 0.321576f, 0.188188f, 0.289134f, 0.241227f, 0.323490f, 0.179143f, 0.382337f, 0.326530f, 0.418260f, 0.336668f, 0.431474f, +3.542748f, 4.437703f, 2.033758f, 3.716616f, 3.994235f, 6.072541f, 3.791523f, 3.585741f, 2.970902f, 4.200562f, 2.481874f, 3.260507f, 6.519543f, 8.804924f, 7.561637f, 5.965224f, +1.807277f, 2.267103f, 1.287772f, 1.984840f, 2.193306f, 3.339372f, 2.584251f, 2.061285f, 2.979136f, 4.218305f, 3.089135f, 3.422791f, 2.703909f, 3.657036f, 3.892657f, 2.589972f, +6.373824f, 6.876020f, 3.687516f, 6.006625f, 5.087961f, 6.661924f, 4.867418f, 4.103099f, 5.066050f, 6.168897f, 4.265162f, 4.994468f, 8.956366f, 10.417400f, 10.469000f, 7.361467f, +1.107588f, 1.359241f, 0.678409f, 1.362611f, 2.026010f, 3.017718f, 2.051994f, 2.132914f, 2.013267f, 2.788821f, 1.794516f, 2.591103f, 2.185064f, 2.891166f, 2.704067f, 2.344554f, +0.001355f, 0.001650f, 0.002784f, 0.007689f, 0.001175f, 0.001737f, 0.003992f, 0.005706f, 0.000025f, 0.000035f, 0.000075f, 0.000149f, 0.000981f, 0.001288f, 0.004071f, 0.004853f, +0.000919f, 0.001120f, 0.002342f, 0.005456f, 0.000857f, 0.001269f, 0.003615f, 0.004358f, 0.000033f, 0.000046f, 0.000124f, 0.000208f, 0.000541f, 0.000711f, 0.002784f, 0.002800f, +0.004673f, 0.004899f, 0.009673f, 0.023814f, 0.002869f, 0.003651f, 0.009821f, 0.012512f, 0.000082f, 0.000097f, 0.000247f, 0.000438f, 0.002582f, 0.002919f, 0.010801f, 0.011478f, +0.000040f, 0.000048f, 0.000088f, 0.000266f, 0.000056f, 0.000082f, 0.000204f, 0.000321f, 0.000002f, 0.000002f, 0.000005f, 0.000011f, 0.000031f, 0.000040f, 0.000138f, 0.000180f, +1.844220f, 2.423983f, 1.011376f, 2.407777f, 2.030965f, 3.239950f, 1.841719f, 2.269049f, 1.485238f, 2.203505f, 1.185300f, 2.028565f, 2.998505f, 4.249250f, 3.322342f, 3.414370f, +0.984785f, 1.296245f, 0.670343f, 1.345980f, 1.167381f, 1.864993f, 1.313981f, 1.365361f, 1.558987f, 2.316269f, 1.544294f, 2.229096f, 1.301740f, 1.847398f, 1.790273f, 1.551756f, +4.941503f, 5.593647f, 2.731076f, 5.795430f, 3.853001f, 5.293635f, 3.521234f, 3.866905f, 3.771931f, 4.819485f, 3.033686f, 4.627853f, 6.134879f, 7.487426f, 6.850470f, 6.275303f, +0.561366f, 0.722875f, 0.328474f, 0.859481f, 1.003011f, 1.567624f, 0.970468f, 1.314116f, 0.979952f, 1.424370f, 0.834433f, 1.569582f, 0.978470f, 1.358486f, 1.156755f, 1.306591f, +0.178905f, 0.224114f, 0.101467f, 0.211129f, 0.169663f, 0.257961f, 0.159115f, 0.171337f, 0.161529f, 0.228401f, 0.133317f, 0.199418f, 0.387362f, 0.523185f, 0.443875f, 0.398699f, +0.128529f, 0.161242f, 0.090482f, 0.158789f, 0.131204f, 0.199776f, 0.152731f, 0.138709f, 0.228111f, 0.323016f, 0.233689f, 0.294819f, 0.226249f, 0.306023f, 0.321800f, 0.243786f, +0.785856f, 0.847832f, 0.449181f, 0.833090f, 0.527666f, 0.690947f, 0.498722f, 0.478680f, 0.672500f, 0.818956f, 0.559375f, 0.745814f, 1.299251f, 1.511300f, 1.500415f, 1.201280f, +0.096173f, 0.118033f, 0.058199f, 0.133096f, 0.147975f, 0.220423f, 0.148070f, 0.175242f, 0.188216f, 0.260739f, 0.165748f, 0.272495f, 0.223233f, 0.295391f, 0.272933f, 0.269447f, +2.354076f, 3.046165f, 1.602498f, 2.255850f, 2.377889f, 3.734594f, 2.676638f, 1.949930f, 2.079790f, 3.037760f, 2.060292f, 2.084964f, 3.999017f, 5.579262f, 5.500090f, 3.342297f, +0.809872f, 1.049489f, 0.684303f, 0.812455f, 0.880580f, 1.384998f, 1.230331f, 0.755944f, 1.406478f, 2.057290f, 1.729407f, 1.476064f, 1.118509f, 1.562758f, 1.909464f, 0.978644f, +4.524004f, 5.041676f, 3.103664f, 3.894355f, 3.235522f, 4.376382f, 3.670431f, 2.383388f, 3.788291f, 4.765366f, 3.782050f, 3.411498f, 5.868277f, 7.051039f, 8.133958f, 4.405805f, +0.807850f, 1.024151f, 0.586762f, 0.907835f, 1.323951f, 2.037155f, 1.590100f, 1.273169f, 1.547053f, 2.213805f, 1.635192f, 1.818739f, 1.471204f, 2.010928f, 2.158957f, 1.441953f, +0.011046f, 0.013892f, 0.026907f, 0.057244f, 0.008582f, 0.013100f, 0.034567f, 0.038058f, 0.000216f, 0.000306f, 0.000765f, 0.001170f, 0.007380f, 0.010007f, 0.036318f, 0.033354f, +0.005049f, 0.006359f, 0.015266f, 0.027393f, 0.004223f, 0.006455f, 0.021111f, 0.019604f, 0.000194f, 0.000276f, 0.000853f, 0.001100f, 0.002742f, 0.003724f, 0.016753f, 0.012976f, +0.040680f, 0.044063f, 0.099865f, 0.189379f, 0.022378f, 0.029419f, 0.090838f, 0.089146f, 0.000753f, 0.000921f, 0.002691f, 0.003668f, 0.020752f, 0.024235f, 0.102928f, 0.084258f, +0.000358f, 0.000441f, 0.000931f, 0.002177f, 0.000452f, 0.000675f, 0.001941f, 0.002349f, 0.000015f, 0.000021f, 0.000057f, 0.000096f, 0.000257f, 0.000341f, 0.001347f, 0.001360f, +2.268873f, 3.080648f, 1.475462f, 2.705801f, 2.238606f, 3.689167f, 2.407224f, 2.284553f, 1.925061f, 2.950375f, 1.821774f, 2.401704f, 3.405321f, 4.985176f, 4.474201f, 3.541979f, +0.817053f, 1.110992f, 0.659513f, 1.020069f, 0.867759f, 1.432117f, 1.158226f, 0.927078f, 1.362706f, 2.091528f, 1.600691f, 1.779797f, 0.996986f, 1.461639f, 1.625929f, 1.085601f, +6.493803f, 7.593641f, 4.255903f, 6.956772f, 4.536458f, 6.438529f, 4.916211f, 4.158755f, 5.222214f, 6.892972f, 4.980574f, 5.852651f, 7.442210f, 9.383036f, 9.854490f, 6.953648f, +0.758082f, 1.008436f, 0.526003f, 1.060201f, 1.213538f, 1.959316f, 1.392345f, 1.452324f, 1.394201f, 2.093431f, 1.407764f, 2.039797f, 1.219757f, 1.749427f, 1.709957f, 1.487810f, +0.307528f, 0.341696f, 0.151307f, 0.407411f, 0.345941f, 0.466527f, 0.281448f, 0.392183f, 0.277847f, 0.348468f, 0.198936f, 0.385073f, 0.663534f, 0.794895f, 0.659597f, 0.766680f, +0.245359f, 0.273015f, 0.149842f, 0.340286f, 0.297099f, 0.401241f, 0.300022f, 0.352599f, 0.435754f, 0.547302f, 0.387262f, 0.632226f, 0.430400f, 0.516354f, 0.531059f, 0.520615f, +0.912438f, 0.873129f, 0.452433f, 1.085863f, 0.726728f, 0.844045f, 0.595858f, 0.740084f, 0.781351f, 0.843960f, 0.563805f, 0.972763f, 1.503272f, 1.550968f, 1.506009f, 1.560311f, +0.105793f, 0.115164f, 0.055538f, 0.164359f, 0.193084f, 0.255107f, 0.167609f, 0.256696f, 0.207184f, 0.254573f, 0.158277f, 0.336728f, 0.244707f, 0.287206f, 0.259548f, 0.331577f, +5.884053f, 6.753321f, 3.474765f, 6.329786f, 7.050182f, 9.821097f, 6.884466f, 6.490088f, 5.201981f, 6.739235f, 4.470436f, 5.854240f, 9.960779f, 12.326070f, 11.884530f, 9.345616f, +2.248076f, 2.583929f, 1.647841f, 2.531727f, 2.899453f, 4.044869f, 3.514320f, 2.794215f, 3.906796f, 5.068638f, 4.167323f, 4.602734f, 3.093986f, 3.834232f, 4.582076f, 3.038970f, +7.637949f, 7.549820f, 4.545697f, 7.380948f, 6.479639f, 7.773731f, 6.376693f, 5.358263f, 6.400151f, 7.140869f, 5.543016f, 6.470158f, 9.872983f, 10.522010f, 11.871670f, 8.321199f, +1.292198f, 1.453015f, 0.814203f, 1.630152f, 2.512019f, 3.428332f, 2.617263f, 2.711813f, 2.476262f, 3.142958f, 2.270556f, 3.268020f, 2.345067f, 2.843065f, 2.985370f, 2.580217f, +0.001335f, 0.001489f, 0.002821f, 0.007765f, 0.001230f, 0.001665f, 0.004298f, 0.006124f, 0.000026f, 0.000033f, 0.000080f, 0.000159f, 0.000889f, 0.001069f, 0.003794f, 0.004509f, +0.000678f, 0.000757f, 0.001777f, 0.004127f, 0.000672f, 0.000911f, 0.002915f, 0.003503f, 0.000026f, 0.000033f, 0.000099f, 0.000166f, 0.000367f, 0.000442f, 0.001943f, 0.001948f, +0.003320f, 0.003190f, 0.007071f, 0.017352f, 0.002167f, 0.002526f, 0.007629f, 0.009689f, 0.000062f, 0.000067f, 0.000191f, 0.000336f, 0.001688f, 0.001748f, 0.007263f, 0.007693f, +0.000028f, 0.000030f, 0.000062f, 0.000189f, 0.000041f, 0.000055f, 0.000154f, 0.000242f, 0.000001f, 0.000001f, 0.000004f, 0.000008f, 0.000020f, 0.000023f, 0.000090f, 0.000118f, +2.434514f, 2.931919f, 1.373416f, 3.259274f, 2.849262f, 4.164769f, 2.657928f, 3.264215f, 2.066996f, 2.809832f, 1.696921f, 2.894926f, 3.641197f, 4.727967f, 4.150243f, 4.251624f, +0.973624f, 1.174248f, 0.681768f, 1.364562f, 1.226571f, 1.795477f, 1.420230f, 1.471067f, 1.624936f, 2.212104f, 1.655821f, 2.382470f, 1.183896f, 1.539475f, 1.674937f, 1.447164f, +4.706509f, 4.881550f, 2.675861f, 5.660183f, 3.900042f, 4.909610f, 3.666527f, 4.013643f, 3.787456f, 4.434120f, 3.133606f, 4.765061f, 5.375090f, 6.010839f, 6.174332f, 5.637927f, +0.520547f, 0.614187f, 0.313332f, 0.817251f, 0.988440f, 1.415498f, 0.983820f, 1.327955f, 0.957994f, 1.275863f, 0.839150f, 1.573429f, 0.834644f, 1.061774f, 1.015045f, 1.142875f, +0.277518f, 0.345670f, 0.124015f, 0.412220f, 0.231785f, 0.350409f, 0.171273f, 0.294619f, 0.304793f, 0.428525f, 0.198207f, 0.473622f, 0.660047f, 0.886414f, 0.595933f, 0.855096f, +0.180554f, 0.225220f, 0.100149f, 0.280762f, 0.162324f, 0.245754f, 0.148882f, 0.215999f, 0.389796f, 0.548831f, 0.314636f, 0.634101f, 0.349125f, 0.469539f, 0.391254f, 0.473494f, +1.132696f, 1.215077f, 0.510119f, 1.511383f, 0.669820f, 0.872101f, 0.498812f, 0.764816f, 1.179094f, 1.427709f, 0.772749f, 1.645882f, 2.057086f, 2.379213f, 1.871760f, 2.393953f, +0.132772f, 0.162024f, 0.063306f, 0.231276f, 0.179917f, 0.266478f, 0.141850f, 0.268184f, 0.316079f, 0.435380f, 0.219314f, 0.575983f, 0.338532f, 0.445412f, 0.326120f, 0.514312f, +2.717583f, 3.496545f, 1.457603f, 3.277817f, 2.417590f, 3.775356f, 2.144175f, 2.495299f, 2.920568f, 4.241551f, 2.279586f, 3.685179f, 5.071127f, 7.034793f, 5.495415f, 5.334683f, +0.846671f, 1.090937f, 0.563672f, 1.069080f, 0.810767f, 1.267943f, 0.892542f, 0.876050f, 1.788615f, 2.601374f, 1.732849f, 2.362661f, 1.284479f, 1.784443f, 1.727740f, 1.414570f, +4.852736f, 5.377272f, 2.623118f, 5.257891f, 3.056588f, 4.110845f, 2.732053f, 2.833999f, 4.943022f, 6.182568f, 3.888266f, 5.602821f, 6.914539f, 8.260934f, 7.551515f, 6.534168f, +0.829998f, 1.046245f, 0.474994f, 1.173993f, 1.197973f, 1.832831f, 1.133650f, 1.450017f, 1.933467f, 2.751024f, 1.610200f, 2.860978f, 1.660382f, 2.256602f, 1.919811f, 2.048323f, +0.004024f, 0.005032f, 0.007724f, 0.026249f, 0.002754f, 0.004179f, 0.008739f, 0.015370f, 0.000096f, 0.000135f, 0.000267f, 0.000653f, 0.002953f, 0.003982f, 0.011452f, 0.016801f, +0.001666f, 0.002086f, 0.003969f, 0.011375f, 0.001227f, 0.001865f, 0.004833f, 0.007170f, 0.000078f, 0.000110f, 0.000270f, 0.000556f, 0.000994f, 0.001342f, 0.004784f, 0.005919f, +0.013771f, 0.014831f, 0.026637f, 0.080691f, 0.006672f, 0.008721f, 0.021338f, 0.033452f, 0.000310f, 0.000377f, 0.000873f, 0.001901f, 0.007717f, 0.008961f, 0.030157f, 0.039436f, +0.000116f, 0.000142f, 0.000238f, 0.000889f, 0.000129f, 0.000192f, 0.000437f, 0.000844f, 0.000006f, 0.000008f, 0.000018f, 0.000048f, 0.000091f, 0.000121f, 0.000378f, 0.000610f, +2.169210f, 2.928578f, 1.111473f, 3.256115f, 1.884942f, 3.088674f, 1.597041f, 2.421218f, 2.238831f, 3.411753f, 1.669363f, 3.515675f, 3.576337f, 5.205761f, 3.702332f, 4.682079f, +0.707421f, 0.956449f, 0.449915f, 1.111654f, 0.661692f, 1.085822f, 0.695872f, 0.889785f, 1.435210f, 2.190284f, 1.328312f, 2.359371f, 0.948212f, 1.382229f, 1.218422f, 1.299568f, +5.768886f, 6.707586f, 2.978956f, 7.778807f, 3.549266f, 5.008778f, 3.030621f, 4.095411f, 5.643299f, 7.406420f, 4.240698f, 7.960556f, 7.262460f, 9.104343f, 7.576968f, 8.540965f, +0.645047f, 0.853192f, 0.352649f, 1.135470f, 0.909405f, 1.459930f, 0.822111f, 1.369872f, 1.443066f, 2.154481f, 1.148075f, 2.657419f, 1.140085f, 1.625861f, 1.259299f, 1.750347f, +0.062672f, 0.075999f, 0.029975f, 0.080969f, 0.061459f, 0.090456f, 0.048606f, 0.067946f, 0.047865f, 0.065517f, 0.033315f, 0.064693f, 0.236474f, 0.309177f, 0.228512f, 0.266458f, +0.081601f, 0.099096f, 0.048443f, 0.110365f, 0.086136f, 0.126960f, 0.084557f, 0.099692f, 0.122507f, 0.167928f, 0.105836f, 0.173335f, 0.250319f, 0.327753f, 0.300245f, 0.295280f, +0.311366f, 0.325179f, 0.150083f, 0.361358f, 0.216189f, 0.274034f, 0.172312f, 0.214703f, 0.225394f, 0.265702f, 0.158101f, 0.273651f, 0.897090f, 1.010134f, 0.873648f, 0.908040f, +0.044378f, 0.052723f, 0.022647f, 0.067235f, 0.070607f, 0.101813f, 0.059582f, 0.091542f, 0.073467f, 0.098521f, 0.054559f, 0.116443f, 0.179510f, 0.229939f, 0.185084f, 0.237203f, +1.338541f, 1.676678f, 0.768406f, 1.404233f, 1.398136f, 2.125624f, 1.327179f, 1.255148f, 1.000350f, 1.414396f, 0.835686f, 1.097865f, 3.962594f, 5.351655f, 4.595982f, 3.625678f, +0.834580f, 1.046923f, 0.594679f, 0.916577f, 0.938356f, 1.428673f, 1.105612f, 0.881873f, 1.226044f, 1.736016f, 1.271314f, 1.408628f, 2.008661f, 2.716714f, 2.891750f, 1.924021f, +2.909447f, 3.138682f, 1.683233f, 2.741832f, 2.151685f, 2.817309f, 2.058418f, 1.735189f, 2.060877f, 2.509517f, 1.735075f, 2.031757f, 6.576779f, 7.649637f, 7.687529f, 5.405624f, +0.605069f, 0.742545f, 0.370611f, 0.744387f, 1.025399f, 1.527320f, 1.038550f, 1.079505f, 0.980168f, 1.357750f, 0.873668f, 1.261490f, 1.920269f, 2.540803f, 2.376377f, 2.060432f, +0.002017f, 0.002456f, 0.004144f, 0.011445f, 0.001621f, 0.002395f, 0.005505f, 0.007869f, 0.000033f, 0.000046f, 0.000100f, 0.000198f, 0.002349f, 0.003083f, 0.009748f, 0.011622f, +0.001671f, 0.002038f, 0.004261f, 0.009926f, 0.001445f, 0.002139f, 0.006094f, 0.007346f, 0.000054f, 0.000075f, 0.000201f, 0.000337f, 0.001582f, 0.002079f, 0.008149f, 0.008194f, +0.008403f, 0.008811f, 0.017396f, 0.042826f, 0.004780f, 0.006083f, 0.016363f, 0.020846f, 0.000132f, 0.000156f, 0.000396f, 0.000702f, 0.007470f, 0.008445f, 0.031246f, 0.033205f, +0.000086f, 0.000103f, 0.000189f, 0.000573f, 0.000112f, 0.000163f, 0.000407f, 0.000640f, 0.000003f, 0.000004f, 0.000010f, 0.000021f, 0.000108f, 0.000138f, 0.000476f, 0.000624f, +0.568840f, 0.747665f, 0.311953f, 0.742666f, 0.580369f, 0.925849f, 0.526290f, 0.648404f, 0.408268f, 0.605708f, 0.325820f, 0.557620f, 1.487829f, 2.108437f, 1.648514f, 1.694177f, +0.371254f, 0.488671f, 0.252712f, 0.507421f, 0.407724f, 0.651375f, 0.458926f, 0.476872f, 0.523774f, 0.778199f, 0.518838f, 0.748911f, 0.789450f, 1.120369f, 1.085725f, 0.941074f, +1.841430f, 2.084449f, 1.017724f, 2.159642f, 1.330209f, 1.827573f, 1.215670f, 1.335009f, 1.252657f, 1.600550f, 1.007486f, 1.536908f, 3.677675f, 4.488486f, 4.106650f, 3.761855f, +0.250356f, 0.322386f, 0.146492f, 0.383309f, 0.414422f, 0.647708f, 0.400976f, 0.542964f, 0.389484f, 0.566119f, 0.331647f, 0.623834f, 0.701990f, 0.974628f, 0.829899f, 0.937397f, +0.040595f, 0.050853f, 0.023024f, 0.047907f, 0.035667f, 0.054229f, 0.033449f, 0.036018f, 0.032664f, 0.046187f, 0.026959f, 0.040326f, 0.141396f, 0.190975f, 0.162025f, 0.145534f, +0.035645f, 0.044718f, 0.025094f, 0.044037f, 0.033711f, 0.051330f, 0.039242f, 0.035639f, 0.056379f, 0.079836f, 0.057758f, 0.072867f, 0.100939f, 0.136530f, 0.143568f, 0.108763f, +0.215433f, 0.232423f, 0.123137f, 0.228381f, 0.134015f, 0.175484f, 0.126663f, 0.121573f, 0.164298f, 0.200079f, 0.136661f, 0.182210f, 0.572971f, 0.666485f, 0.661685f, 0.529766f, +0.031553f, 0.038725f, 0.019094f, 0.043667f, 0.044978f, 0.066999f, 0.045007f, 0.053266f, 0.055032f, 0.076237f, 0.048462f, 0.079674f, 0.117819f, 0.155903f, 0.144050f, 0.142210f, +0.853891f, 1.104931f, 0.581272f, 0.818261f, 0.799094f, 1.255018f, 0.899489f, 0.655278f, 0.672316f, 0.981991f, 0.666013f, 0.673989f, 2.333492f, 3.255590f, 3.209392f, 1.950285f, +0.359046f, 0.465277f, 0.303377f, 0.360191f, 0.361682f, 0.568863f, 0.505336f, 0.310490f, 0.555698f, 0.812834f, 0.683288f, 0.583192f, 0.797709f, 1.114543f, 1.361811f, 0.697959f, +1.982548f, 2.209407f, 1.360115f, 1.706618f, 1.313620f, 1.776808f, 1.490193f, 0.967654f, 1.479505f, 1.861098f, 1.477067f, 1.332350f, 4.136971f, 4.970785f, 5.734214f, 3.105970f, +0.423690f, 0.537132f, 0.307737f, 0.476129f, 0.643301f, 0.989842f, 0.772621f, 0.618625f, 0.723094f, 1.034734f, 0.764290f, 0.850081f, 1.241256f, 1.696622f, 1.821513f, 1.216577f, +0.015785f, 0.019853f, 0.038451f, 0.081804f, 0.011362f, 0.017344f, 0.045765f, 0.050387f, 0.000275f, 0.000390f, 0.000974f, 0.001490f, 0.016965f, 0.023004f, 0.083491f, 0.076678f, +0.008819f, 0.011108f, 0.026664f, 0.047845f, 0.006833f, 0.010445f, 0.034161f, 0.031722f, 0.000302f, 0.000429f, 0.001328f, 0.001713f, 0.007706f, 0.010464f, 0.047071f, 0.036461f, +0.070234f, 0.076075f, 0.172417f, 0.326961f, 0.035794f, 0.047056f, 0.145297f, 0.142590f, 0.001159f, 0.001417f, 0.004140f, 0.005644f, 0.057637f, 0.067311f, 0.285871f, 0.234018f, +0.000740f, 0.000912f, 0.001924f, 0.004499f, 0.000865f, 0.001293f, 0.003715f, 0.004496f, 0.000028f, 0.000039f, 0.000106f, 0.000178f, 0.000853f, 0.001133f, 0.004479f, 0.004521f, +0.671859f, 0.912241f, 0.436914f, 0.801242f, 0.614144f, 1.012094f, 0.660403f, 0.626749f, 0.508024f, 0.778605f, 0.480767f, 0.633811f, 1.622172f, 2.374758f, 2.131348f, 1.687271f, +0.295713f, 0.402097f, 0.238695f, 0.369190f, 0.290967f, 0.480201f, 0.388363f, 0.310857f, 0.439536f, 0.674615f, 0.516297f, 0.574067f, 0.580470f, 0.851003f, 0.946657f, 0.632064f, +2.323196f, 2.716669f, 1.522574f, 2.488826f, 1.503585f, 2.134017f, 1.629453f, 1.378398f, 1.664998f, 2.197685f, 1.587956f, 1.866000f, 4.283115f, 5.400092f, 5.671422f, 4.001940f, +0.324578f, 0.431769f, 0.225212f, 0.453933f, 0.481372f, 0.777199f, 0.552299f, 0.576091f, 0.531987f, 0.798793f, 0.537162f, 0.778327f, 0.840132f, 1.204953f, 1.177767f, 1.024759f, +0.048993f, 0.054436f, 0.024105f, 0.064906f, 0.051060f, 0.068858f, 0.041541f, 0.057885f, 0.039448f, 0.049475f, 0.028245f, 0.054672f, 0.170053f, 0.203719f, 0.169044f, 0.196488f, +0.047775f, 0.053160f, 0.029177f, 0.066259f, 0.053595f, 0.072382f, 0.054123f, 0.063607f, 0.075616f, 0.094973f, 0.067201f, 0.109710f, 0.134817f, 0.161741f, 0.166347f, 0.163076f, +0.175619f, 0.168053f, 0.087081f, 0.208999f, 0.129588f, 0.150508f, 0.106252f, 0.131970f, 0.134025f, 0.144765f, 0.096710f, 0.166858f, 0.465455f, 0.480223f, 0.466302f, 0.483116f, +0.024369f, 0.026528f, 0.012793f, 0.037860f, 0.041206f, 0.054442f, 0.035769f, 0.054781f, 0.042532f, 0.052260f, 0.032492f, 0.069125f, 0.090678f, 0.106427f, 0.096178f, 0.122869f, +1.498507f, 1.719886f, 0.884927f, 1.612023f, 1.663440f, 2.317217f, 1.624340f, 1.531290f, 1.180656f, 1.529555f, 1.014622f, 1.328694f, 4.080812f, 5.049844f, 4.868948f, 3.828787f, +0.699754f, 0.804294f, 0.512920f, 0.788045f, 0.836132f, 1.166443f, 1.013445f, 0.805784f, 1.083746f, 1.406041f, 1.156016f, 1.276799f, 1.549259f, 1.919924f, 2.294393f, 1.521710f, +2.350054f, 2.322939f, 1.398626f, 2.270980f, 1.847041f, 2.215926f, 1.817696f, 1.527389f, 1.754946f, 1.958053f, 1.519916f, 1.774142f, 4.886756f, 5.208001f, 5.876030f, 4.118681f, +0.475824f, 0.535042f, 0.299813f, 0.600269f, 0.856969f, 1.169567f, 0.892873f, 0.925128f, 0.812618f, 1.031403f, 0.745113f, 1.072444f, 1.389133f, 1.684130f, 1.768426f, 1.528428f, +0.001339f, 0.001494f, 0.002830f, 0.007791f, 0.001143f, 0.001548f, 0.003995f, 0.005692f, 0.000023f, 0.000029f, 0.000072f, 0.000142f, 0.001434f, 0.001725f, 0.006123f, 0.007277f, +0.000831f, 0.000928f, 0.002179f, 0.005061f, 0.000764f, 0.001035f, 0.003312f, 0.003980f, 0.000028f, 0.000036f, 0.000109f, 0.000181f, 0.000723f, 0.000871f, 0.003834f, 0.003843f, +0.004025f, 0.003867f, 0.008571f, 0.021034f, 0.002433f, 0.002837f, 0.008568f, 0.010881f, 0.000066f, 0.000072f, 0.000206f, 0.000363f, 0.003291f, 0.003409f, 0.014162f, 0.015002f, +0.000040f, 0.000044f, 0.000091f, 0.000274f, 0.000056f, 0.000074f, 0.000208f, 0.000325f, 0.000002f, 0.000002f, 0.000005f, 0.000011f, 0.000046f, 0.000054f, 0.000210f, 0.000275f, +0.506151f, 0.609565f, 0.285542f, 0.677624f, 0.548814f, 0.802202f, 0.511960f, 0.628740f, 0.382983f, 0.520620f, 0.314414f, 0.536386f, 1.217821f, 1.581298f, 1.388074f, 1.421982f, +0.247407f, 0.298387f, 0.173243f, 0.346748f, 0.288760f, 0.422693f, 0.334352f, 0.346320f, 0.367984f, 0.500954f, 0.374978f, 0.539535f, 0.483955f, 0.629309f, 0.684684f, 0.591574f, +1.182186f, 1.226153f, 0.672126f, 1.421731f, 0.907572f, 1.142506f, 0.853231f, 0.934007f, 0.847826f, 0.992583f, 0.701461f, 1.066664f, 2.171920f, 2.428808f, 2.494871f, 2.278125f, +0.156482f, 0.184631f, 0.094191f, 0.245674f, 0.275282f, 0.394219f, 0.273996f, 0.369838f, 0.256649f, 0.341806f, 0.224810f, 0.421525f, 0.403623f, 0.513460f, 0.490863f, 0.552679f, +0.041071f, 0.051157f, 0.018353f, 0.061006f, 0.031780f, 0.048045f, 0.023483f, 0.040395f, 0.040200f, 0.056519f, 0.026142f, 0.062467f, 0.157141f, 0.211034f, 0.141877f, 0.203578f, +0.032659f, 0.040738f, 0.018115f, 0.050785f, 0.027202f, 0.041183f, 0.024950f, 0.036197f, 0.062836f, 0.088472f, 0.050720f, 0.102218f, 0.101589f, 0.136628f, 0.113848f, 0.137779f, +0.202524f, 0.217254f, 0.091208f, 0.270233f, 0.110955f, 0.144462f, 0.082628f, 0.126691f, 0.187882f, 0.227497f, 0.123133f, 0.262261f, 0.591680f, 0.684334f, 0.538375f, 0.688574f, +0.028411f, 0.034670f, 0.013546f, 0.049489f, 0.035668f, 0.052828f, 0.028121f, 0.053166f, 0.060276f, 0.083027f, 0.041823f, 0.109840f, 0.116534f, 0.153325f, 0.112261f, 0.177043f, +0.642924f, 0.827210f, 0.344839f, 0.775464f, 0.529888f, 0.827484f, 0.469961f, 0.546920f, 0.615767f, 0.894281f, 0.480624f, 0.776976f, 1.929979f, 2.677314f, 2.091455f, 2.030283f, +0.244818f, 0.315449f, 0.162988f, 0.309129f, 0.217195f, 0.339667f, 0.239101f, 0.234684f, 0.460912f, 0.670354f, 0.446542f, 0.608840f, 0.597485f, 0.830047f, 0.803672f, 0.657998f, +1.387019f, 1.536943f, 0.749745f, 1.502821f, 0.809389f, 1.088558f, 0.723452f, 0.750447f, 1.259101f, 1.574842f, 0.990431f, 1.427167f, 3.179291f, 3.798360f, 3.472171f, 3.004397f, +0.283916f, 0.357887f, 0.162480f, 0.401585f, 0.379650f, 0.580844f, 0.359266f, 0.459526f, 0.589415f, 0.838646f, 0.490868f, 0.872166f, 0.913674f, 1.241762f, 1.056433f, 1.127151f, +0.003751f, 0.004691f, 0.007199f, 0.024466f, 0.002378f, 0.003609f, 0.007546f, 0.013272f, 0.000079f, 0.000112f, 0.000222f, 0.000542f, 0.004428f, 0.005970f, 0.017171f, 0.025191f, +0.001898f, 0.002377f, 0.004521f, 0.012959f, 0.001295f, 0.001968f, 0.005101f, 0.007567f, 0.000079f, 0.000112f, 0.000274f, 0.000564f, 0.001821f, 0.002459f, 0.008767f, 0.010848f, +0.015507f, 0.016701f, 0.029994f, 0.090863f, 0.006960f, 0.009098f, 0.022261f, 0.034899f, 0.000311f, 0.000378f, 0.000876f, 0.001908f, 0.013979f, 0.016232f, 0.054628f, 0.071438f, +0.000157f, 0.000192f, 0.000321f, 0.001198f, 0.000161f, 0.000239f, 0.000545f, 0.001054f, 0.000007f, 0.000010f, 0.000021f, 0.000058f, 0.000198f, 0.000262f, 0.000820f, 0.001322f, +0.418952f, 0.565613f, 0.214665f, 0.628872f, 0.337276f, 0.552662f, 0.285761f, 0.433233f, 0.385351f, 0.587236f, 0.287333f, 0.605123f, 1.111149f, 1.617403f, 1.150295f, 1.454697f, +0.166991f, 0.225776f, 0.106205f, 0.262412f, 0.144709f, 0.237464f, 0.152184f, 0.194592f, 0.301928f, 0.460774f, 0.279439f, 0.496345f, 0.360074f, 0.524887f, 0.462683f, 0.493498f, +1.346089f, 1.565121f, 0.695098f, 1.815076f, 0.767264f, 1.082775f, 0.655146f, 0.885327f, 1.173511f, 1.540148f, 0.881843f, 1.655379f, 2.726068f, 3.417444f, 2.844123f, 3.205973f, +0.180131f, 0.238257f, 0.098478f, 0.317084f, 0.235278f, 0.377707f, 0.212693f, 0.354407f, 0.359134f, 0.536183f, 0.285720f, 0.661349f, 0.512161f, 0.730387f, 0.565716f, 0.786309f, +0.413275f, 0.501156f, 0.197663f, 0.533929f, 0.325699f, 0.479367f, 0.257586f, 0.360079f, 0.273145f, 0.373876f, 0.190113f, 0.369170f, 0.943875f, 1.234065f, 0.912095f, 1.063556f, +0.646110f, 0.784636f, 0.383573f, 0.873864f, 0.548106f, 0.807876f, 0.538055f, 0.634365f, 0.839418f, 1.150644f, 0.725190f, 1.187694f, 1.199698f, 1.570812f, 1.438973f, 1.415178f, +2.034871f, 2.125147f, 0.980839f, 2.361585f, 1.135439f, 1.439245f, 0.904993f, 1.127634f, 1.274713f, 1.502677f, 0.894140f, 1.547635f, 3.548678f, 3.995850f, 3.455946f, 3.591992f, +0.215703f, 0.256266f, 0.110077f, 0.326804f, 0.275806f, 0.397700f, 0.232737f, 0.357579f, 0.309020f, 0.414401f, 0.229488f, 0.489786f, 0.528131f, 0.676496f, 0.544529f, 0.697869f, +5.277797f, 6.611053f, 3.029784f, 5.536817f, 4.430318f, 6.735530f, 4.205474f, 3.977226f, 3.413327f, 4.826105f, 2.851472f, 3.746059f, 9.457252f, 12.772430f, 10.968910f, 8.653157f, +3.951263f, 4.956586f, 2.815467f, 4.339471f, 3.570257f, 5.435820f, 4.206636f, 3.355353f, 5.023179f, 7.112567f, 5.208651f, 5.771236f, 5.756240f, 7.785313f, 8.286915f, 5.513684f, +11.369230f, 12.265020f, 6.577563f, 10.714240f, 6.757152f, 8.847479f, 6.464256f, 5.449189f, 6.969114f, 8.486245f, 5.867372f, 6.870641f, 15.556010f, 18.093640f, 18.183260f, 12.785890f, +1.758524f, 2.158075f, 1.077115f, 2.163427f, 2.394973f, 3.567285f, 2.425690f, 2.521346f, 2.465181f, 3.414822f, 2.197326f, 3.172722f, 3.378080f, 4.469704f, 4.180451f, 3.624650f, +0.004191f, 0.005102f, 0.008609f, 0.023777f, 0.002706f, 0.003998f, 0.009191f, 0.013137f, 0.000060f, 0.000082f, 0.000179f, 0.000356f, 0.002953f, 0.003877f, 0.012257f, 0.014614f, +0.004169f, 0.005083f, 0.010630f, 0.024760f, 0.002897f, 0.004287f, 0.012215f, 0.014725f, 0.000117f, 0.000161f, 0.000435f, 0.000728f, 0.002388f, 0.003140f, 0.012304f, 0.012372f, +0.017301f, 0.018141f, 0.035817f, 0.088174f, 0.007909f, 0.010065f, 0.027074f, 0.034492f, 0.000234f, 0.000278f, 0.000706f, 0.001250f, 0.009310f, 0.010525f, 0.038939f, 0.041381f, +0.000132f, 0.000157f, 0.000289f, 0.000878f, 0.000138f, 0.000200f, 0.000501f, 0.000787f, 0.000004f, 0.000006f, 0.000013f, 0.000028f, 0.000100f, 0.000128f, 0.000442f, 0.000579f, +2.653185f, 3.487261f, 1.455015f, 3.463946f, 2.175435f, 3.470419f, 1.972727f, 2.430455f, 1.647889f, 2.444814f, 1.315104f, 2.250716f, 4.200442f, 5.952542f, 4.654087f, 4.783004f, +2.079195f, 2.736787f, 1.415307f, 2.841792f, 1.835081f, 2.931702f, 2.065530f, 2.146298f, 2.538477f, 3.771550f, 2.514553f, 3.629606f, 2.676168f, 3.797953f, 3.680513f, 3.190161f, +8.512017f, 9.635371f, 4.704432f, 9.982953f, 4.941529f, 6.789163f, 4.516033f, 4.959361f, 5.010882f, 6.402522f, 4.030149f, 6.147945f, 10.289990f, 12.558600f, 11.490240f, 10.525520f, +0.860714f, 1.108347f, 0.503632f, 1.317798f, 1.145005f, 1.789548f, 1.107855f, 1.500152f, 1.158762f, 1.684273f, 0.986691f, 1.855982f, 1.460816f, 2.028165f, 1.726989f, 1.950687f, +0.410004f, 0.513613f, 0.232537f, 0.483853f, 0.289496f, 0.440158f, 0.271498f, 0.292352f, 0.285491f, 0.403684f, 0.235629f, 0.352459f, 0.864407f, 1.167500f, 0.990517f, 0.889706f, +0.432281f, 0.542304f, 0.304316f, 0.534054f, 0.328550f, 0.500262f, 0.382456f, 0.347343f, 0.591683f, 0.837851f, 0.606150f, 0.764711f, 0.740947f, 1.002201f, 1.053868f, 0.798378f, +2.156393f, 2.326456f, 1.232555f, 2.286002f, 1.078034f, 1.411621f, 1.018901f, 0.977955f, 1.423162f, 1.733095f, 1.183764f, 1.578310f, 3.471470f, 4.038043f, 4.008958f, 3.209699f, +0.234897f, 0.288288f, 0.142147f, 0.325080f, 0.269093f, 0.400838f, 0.269266f, 0.318678f, 0.354534f, 0.491143f, 0.312212f, 0.513287f, 0.530906f, 0.702517f, 0.649106f, 0.640815f, +5.156721f, 6.672776f, 3.510351f, 4.941551f, 3.878231f, 6.090955f, 4.365476f, 3.180249f, 3.513579f, 5.131965f, 3.480638f, 3.522319f, 8.529858f, 11.900500f, 11.731630f, 7.129081f, +2.603565f, 3.373883f, 2.199888f, 2.611869f, 2.107704f, 3.315050f, 2.944848f, 1.809383f, 3.487081f, 5.100639f, 4.287720f, 3.659605f, 3.501282f, 4.891919f, 5.977217f, 3.063460f, +11.865740f, 13.223510f, 8.140413f, 10.214270f, 6.318369f, 8.546254f, 7.167665f, 4.654310f, 7.662881f, 9.639290f, 7.650257f, 6.900712f, 14.987110f, 18.007780f, 20.773470f, 11.252070f, +1.886001f, 2.390975f, 1.369851f, 2.119424f, 2.301293f, 3.540984f, 2.763913f, 2.213022f, 2.785436f, 3.985909f, 2.944129f, 3.274602f, 3.344409f, 4.571335f, 4.907840f, 3.277914f, +0.050226f, 0.063169f, 0.122345f, 0.260287f, 0.029054f, 0.044350f, 0.117024f, 0.128843f, 0.000757f, 0.001074f, 0.002682f, 0.004102f, 0.032673f, 0.044305f, 0.160800f, 0.147678f, +0.033693f, 0.042437f, 0.101872f, 0.182794f, 0.020980f, 0.032071f, 0.104888f, 0.097398f, 0.000998f, 0.001419f, 0.004390f, 0.005663f, 0.017819f, 0.024198f, 0.108854f, 0.084317f, +0.221477f, 0.239895f, 0.543701f, 1.031040f, 0.090709f, 0.119251f, 0.368214f, 0.361354f, 0.003162f, 0.003867f, 0.011298f, 0.015402f, 0.110013f, 0.128478f, 0.545651f, 0.446676f, +0.001736f, 0.002139f, 0.004512f, 0.010551f, 0.001629f, 0.002437f, 0.007003f, 0.008474f, 0.000057f, 0.000079f, 0.000214f, 0.000360f, 0.001211f, 0.001609f, 0.006358f, 0.006418f, +4.799606f, 6.516847f, 3.121213f, 5.723891f, 3.525835f, 5.810489f, 3.791410f, 3.598202f, 3.140631f, 4.813376f, 2.972124f, 3.918248f, 7.014374f, 10.268600f, 9.216083f, 7.295866f, +2.536558f, 3.449097f, 2.047472f, 3.166824f, 2.005776f, 3.310259f, 2.677174f, 2.142888f, 3.262674f, 5.007665f, 3.832472f, 4.261300f, 3.013830f, 4.418450f, 4.915091f, 3.281709f, +16.448000f, 19.233760f, 10.779680f, 17.620650f, 8.554996f, 12.141980f, 9.271147f, 7.842713f, 10.201070f, 13.464730f, 9.729053f, 11.432570f, 18.354870f, 23.141570f, 24.304330f, 17.149930f, +1.709107f, 2.273534f, 1.185883f, 2.390240f, 2.037022f, 3.288870f, 2.337163f, 2.437843f, 2.424130f, 3.639896f, 2.447712f, 3.546642f, 2.677700f, 3.840472f, 3.753824f, 3.266151f, +0.508870f, 0.565409f, 0.250370f, 0.674148f, 0.426200f, 0.574762f, 0.346745f, 0.483170f, 0.354572f, 0.444694f, 0.253871f, 0.491409f, 1.069107f, 1.280759f, 1.062763f, 1.235299f, +0.595832f, 0.662992f, 0.363877f, 0.826353f, 0.537170f, 0.725463f, 0.542455f, 0.637517f, 0.816093f, 1.025003f, 0.725275f, 1.184052f, 1.017721f, 1.220967f, 1.255740f, 1.231043f, +1.807775f, 1.729893f, 0.896385f, 2.151374f, 1.072016f, 1.245074f, 0.878968f, 1.091719f, 1.193889f, 1.289555f, 0.861483f, 1.486363f, 2.900106f, 2.992122f, 2.905387f, 3.010146f, +0.186569f, 0.203093f, 0.097942f, 0.289851f, 0.253522f, 0.334958f, 0.220073f, 0.337046f, 0.281782f, 0.346234f, 0.215266f, 0.457970f, 0.420207f, 0.493185f, 0.445690f, 0.569377f, +9.306487f, 10.681360f, 5.495848f, 10.011480f, 8.302299f, 11.565330f, 8.107152f, 7.642733f, 6.345342f, 8.220473f, 5.453008f, 7.140963f, 15.340440f, 18.983190f, 18.303180f, 14.393040f, +5.218182f, 5.997755f, 3.824930f, 5.876586f, 5.010870f, 6.990392f, 6.073491f, 4.828995f, 6.993684f, 9.073535f, 7.460062f, 8.239505f, 6.992975f, 8.666067f, 10.356330f, 6.868628f, +14.464540f, 14.297640f, 8.608516f, 13.977840f, 9.136240f, 10.960900f, 8.991087f, 7.555109f, 9.347493f, 10.429320f, 8.095637f, 9.449739f, 18.205880f, 19.402690f, 21.891470f, 15.344370f, +2.178193f, 2.449274f, 1.372460f, 2.747863f, 3.152673f, 4.302678f, 3.284758f, 3.403421f, 3.219146f, 4.085853f, 2.951728f, 4.248434f, 3.849087f, 4.666479f, 4.900053f, 4.235052f, +0.004382f, 0.004888f, 0.009260f, 0.025494f, 0.003007f, 0.004071f, 0.010506f, 0.014969f, 0.000066f, 0.000083f, 0.000203f, 0.000402f, 0.002841f, 0.003417f, 0.012128f, 0.014414f, +0.003265f, 0.003647f, 0.008563f, 0.019883f, 0.002411f, 0.003269f, 0.010458f, 0.012567f, 0.000097f, 0.000122f, 0.000369f, 0.000616f, 0.001721f, 0.002072f, 0.009118f, 0.009139f, +0.013052f, 0.012540f, 0.027796f, 0.068211f, 0.006341f, 0.007394f, 0.022330f, 0.028357f, 0.000186f, 0.000202f, 0.000578f, 0.001020f, 0.006461f, 0.006692f, 0.027799f, 0.029448f, +0.000097f, 0.000106f, 0.000219f, 0.000661f, 0.000108f, 0.000143f, 0.000402f, 0.000630f, 0.000003f, 0.000004f, 0.000010f, 0.000023f, 0.000067f, 0.000079f, 0.000307f, 0.000401f, +3.718466f, 4.478201f, 2.097749f, 4.978200f, 3.240207f, 4.736215f, 3.022620f, 3.712096f, 2.434828f, 3.309855f, 1.998896f, 3.410092f, 5.415407f, 7.031718f, 6.172492f, 6.323272f, +2.182437f, 2.632148f, 1.528224f, 3.058748f, 2.047067f, 2.996535f, 2.370272f, 2.455115f, 2.809078f, 3.824135f, 2.862471f, 4.118651f, 2.584043f, 3.360151f, 3.655817f, 3.158667f, +8.607343f, 8.927460f, 4.893659f, 10.351440f, 5.310414f, 6.685071f, 4.992453f, 5.465095f, 5.341889f, 6.253954f, 4.419688f, 6.720718f, 9.571750f, 10.703870f, 10.995010f, 10.039800f, +0.847364f, 0.999792f, 0.510051f, 1.330347f, 1.197978f, 1.715567f, 1.192378f, 1.609465f, 1.202678f, 1.601734f, 1.053479f, 1.975303f, 1.322959f, 1.682972f, 1.608905f, 1.811522f, +0.845225f, 1.052795f, 0.377708f, 1.255483f, 0.525600f, 0.794595f, 0.388383f, 0.668085f, 0.715918f, 1.006551f, 0.465563f, 1.112476f, 1.957457f, 2.628779f, 1.767319f, 2.535902f, +0.807025f, 1.006670f, 0.447637f, 1.254928f, 0.540196f, 0.817844f, 0.495463f, 0.718821f, 1.343679f, 1.891892f, 1.084591f, 2.185829f, 1.519488f, 2.043563f, 1.702847f, 2.060777f, +4.130608f, 4.431027f, 1.860253f, 5.511567f, 1.818642f, 2.367863f, 1.354336f, 2.076569f, 3.316088f, 4.015294f, 2.173283f, 4.628886f, 7.304466f, 8.448302f, 6.646395f, 8.500643f, +0.430970f, 0.525918f, 0.205487f, 0.750708f, 0.434810f, 0.644006f, 0.342814f, 0.648130f, 0.791248f, 1.089896f, 0.549013f, 1.441871f, 1.069980f, 1.407789f, 1.030749f, 1.625557f, +7.911370f, 10.179070f, 4.243343f, 9.542314f, 5.240112f, 8.183059f, 4.647485f, 5.408544f, 6.557124f, 9.522932f, 5.118020f, 8.273793f, 14.375030f, 19.941400f, 15.577760f, 15.122130f, +3.617284f, 4.660877f, 2.408210f, 4.567494f, 2.579008f, 4.033264f, 2.839132f, 2.786672f, 5.893344f, 8.571322f, 5.709601f, 7.784782f, 5.343556f, 7.423452f, 7.187564f, 5.884748f, +16.915090f, 18.743450f, 9.143352f, 18.327330f, 7.932559f, 10.668600f, 7.090315f, 7.354888f, 13.287920f, 16.620090f, 10.452510f, 15.061610f, 23.468550f, 28.038330f, 25.630500f, 22.177540f, +2.575157f, 3.246088f, 1.473719f, 3.642438f, 2.767341f, 4.233875f, 2.618753f, 3.349569f, 4.626373f, 6.582611f, 3.852865f, 6.845708f, 5.016147f, 6.817377f, 5.799903f, 6.188149f, +0.024318f, 0.030411f, 0.046673f, 0.158622f, 0.012389f, 0.018804f, 0.039317f, 0.069151f, 0.000446f, 0.000629f, 0.001245f, 0.003041f, 0.017377f, 0.023430f, 0.067383f, 0.098859f, +0.014773f, 0.018501f, 0.035194f, 0.100880f, 0.008101f, 0.012314f, 0.031913f, 0.047340f, 0.000532f, 0.000752f, 0.001845f, 0.003802f, 0.008583f, 0.011589f, 0.041309f, 0.051115f, +0.099639f, 0.107311f, 0.192725f, 0.583830f, 0.035940f, 0.046980f, 0.114950f, 0.180208f, 0.001731f, 0.002104f, 0.004871f, 0.010609f, 0.054367f, 0.063130f, 0.212462f, 0.277839f, +0.000748f, 0.000917f, 0.001532f, 0.005723f, 0.000618f, 0.000920f, 0.002094f, 0.004048f, 0.000030f, 0.000041f, 0.000089f, 0.000238f, 0.000573f, 0.000757f, 0.002371f, 0.003824f, +6.098357f, 8.233190f, 3.124713f, 9.154001f, 3.945464f, 6.465054f, 3.342846f, 5.067970f, 4.854111f, 7.397176f, 3.619422f, 7.622495f, 9.790056f, 14.250530f, 10.134960f, 12.816970f, +2.918692f, 3.946138f, 1.856269f, 4.586483f, 2.032613f, 3.335475f, 2.137610f, 2.733280f, 4.566702f, 6.969276f, 4.226565f, 7.507295f, 3.809353f, 5.552975f, 4.894896f, 5.220894f, +19.418780f, 22.578560f, 10.027530f, 26.184420f, 8.895234f, 12.553090f, 7.595397f, 10.263990f, 14.650080f, 19.227170f, 11.008910f, 20.665710f, 23.803950f, 29.841040f, 24.834810f, 27.994470f, +1.932682f, 2.556324f, 1.056604f, 3.402083f, 2.028690f, 3.256792f, 1.833954f, 3.055892f, 3.334514f, 4.978391f, 2.652873f, 6.140537f, 3.326151f, 4.743382f, 3.673952f, 5.106563f, +}; + +static const float acceptor_me2x3acc4[16384] = { +0.034748f, 0.053536f, 0.000903f, 0.143367f, 0.038723f, 0.115762f, 0.066831f, 0.172192f, 0.000570f, 0.001446f, 0.000683f, 0.004695f, 0.103045f, 0.319651f, 0.153655f, 0.431369f, +0.031342f, 0.057415f, 0.000667f, 0.141258f, 0.049473f, 0.175853f, 0.069935f, 0.240318f, 0.019452f, 0.058702f, 0.019117f, 0.175139f, 0.108159f, 0.398928f, 0.132097f, 0.494599f, +0.001270f, 0.002731f, 0.000050f, 0.006952f, 0.001982f, 0.008271f, 0.005189f, 0.011695f, 0.000587f, 0.002081f, 0.001069f, 0.006425f, 0.005728f, 0.024805f, 0.012958f, 0.031821f, +0.055800f, 0.093433f, 0.001475f, 0.254089f, 0.136888f, 0.444747f, 0.240457f, 0.671810f, 0.045152f, 0.124550f, 0.055143f, 0.410743f, 0.239982f, 0.809049f, 0.364211f, 1.108744f, +0.031725f, 0.047173f, 0.000821f, 0.104089f, 0.043776f, 0.126302f, 0.075239f, 0.154798f, 0.000747f, 0.001829f, 0.000892f, 0.004895f, 0.122122f, 0.365610f, 0.181345f, 0.406533f, +0.035930f, 0.063523f, 0.000761f, 0.128773f, 0.070226f, 0.240910f, 0.098859f, 0.271266f, 0.032022f, 0.093267f, 0.031341f, 0.229277f, 0.160948f, 0.572919f, 0.195754f, 0.585271f, +0.017237f, 0.035780f, 0.000676f, 0.075049f, 0.033314f, 0.134182f, 0.086870f, 0.156333f, 0.011451f, 0.039159f, 0.020760f, 0.099604f, 0.100942f, 0.421881f, 0.227413f, 0.445931f, +0.061330f, 0.099109f, 0.001615f, 0.222078f, 0.186295f, 0.584149f, 0.325885f, 0.727045f, 0.071266f, 0.189723f, 0.086673f, 0.515528f, 0.342379f, 1.113986f, 0.517458f, 1.257883f, +0.004423f, 0.007235f, 0.000101f, 0.018111f, 0.004154f, 0.013185f, 0.006277f, 0.018334f, 0.000114f, 0.000307f, 0.000120f, 0.000931f, 0.015410f, 0.050752f, 0.020118f, 0.064025f, +0.005178f, 0.010071f, 0.000096f, 0.023162f, 0.006889f, 0.025998f, 0.008526f, 0.033212f, 0.005044f, 0.016160f, 0.004340f, 0.045071f, 0.020994f, 0.082213f, 0.022449f, 0.095285f, +0.002654f, 0.006061f, 0.000092f, 0.014423f, 0.003492f, 0.015471f, 0.008005f, 0.020450f, 0.001927f, 0.007249f, 0.003071f, 0.020920f, 0.014068f, 0.064682f, 0.027865f, 0.077567f, +0.011676f, 0.020757f, 0.000270f, 0.052768f, 0.024141f, 0.083276f, 0.037128f, 0.117591f, 0.014828f, 0.043427f, 0.015855f, 0.133877f, 0.058997f, 0.211174f, 0.078393f, 0.270532f, +0.065421f, 0.088787f, 0.001523f, 0.230012f, 0.084845f, 0.223429f, 0.131239f, 0.321508f, 0.001515f, 0.003387f, 0.001629f, 0.010641f, 0.255104f, 0.697073f, 0.340922f, 0.910024f, +0.077558f, 0.125152f, 0.001479f, 0.297870f, 0.142476f, 0.446105f, 0.180505f, 0.589759f, 0.068001f, 0.180770f, 0.059896f, 0.521745f, 0.351936f, 1.143423f, 0.385224f, 1.371411f, +0.051527f, 0.097624f, 0.001820f, 0.240414f, 0.093602f, 0.344106f, 0.219662f, 0.470700f, 0.033676f, 0.105110f, 0.054945f, 0.313901f, 0.305678f, 1.166054f, 0.619776f, 1.447082f, +0.105237f, 0.155220f, 0.002494f, 0.408352f, 0.300451f, 0.859873f, 0.473005f, 1.256520f, 0.120302f, 0.292315f, 0.131674f, 0.932566f, 0.595132f, 1.767350f, 0.809483f, 2.343045f, +0.043054f, 0.125193f, 0.001437f, 0.200584f, 0.037671f, 0.212547f, 0.083547f, 0.189157f, 0.000584f, 0.002795f, 0.000900f, 0.005431f, 0.094915f, 0.555685f, 0.181868f, 0.448661f, +0.040118f, 0.138704f, 0.001097f, 0.204170f, 0.049721f, 0.333559f, 0.090318f, 0.272725f, 0.020586f, 0.117250f, 0.025998f, 0.209295f, 0.102920f, 0.716435f, 0.161523f, 0.531438f, +0.001965f, 0.007975f, 0.000099f, 0.012147f, 0.002408f, 0.018966f, 0.008102f, 0.016045f, 0.000751f, 0.005025f, 0.001758f, 0.009282f, 0.006589f, 0.053856f, 0.019156f, 0.041335f, +0.062594f, 0.197808f, 0.002127f, 0.321844f, 0.120565f, 0.739290f, 0.272143f, 0.668136f, 0.041876f, 0.218012f, 0.065718f, 0.430155f, 0.200121f, 1.273318f, 0.390276f, 1.044022f, +0.051858f, 0.145530f, 0.001724f, 0.192122f, 0.056183f, 0.305933f, 0.124084f, 0.224335f, 0.001009f, 0.004666f, 0.001550f, 0.007470f, 0.148396f, 0.838482f, 0.283164f, 0.557812f, +0.060673f, 0.202451f, 0.001652f, 0.245544f, 0.093110f, 0.602838f, 0.168431f, 0.406123f, 0.044708f, 0.245758f, 0.056227f, 0.361459f, 0.202043f, 1.357374f, 0.315771f, 0.829620f, +0.035189f, 0.137859f, 0.001775f, 0.173005f, 0.053399f, 0.405931f, 0.178929f, 0.282959f, 0.019328f, 0.124745f, 0.045027f, 0.189840f, 0.153194f, 1.208391f, 0.443497f, 0.764190f, +0.090760f, 0.276809f, 0.003071f, 0.371096f, 0.216460f, 1.280997f, 0.486572f, 0.953900f, 0.087195f, 0.438109f, 0.136270f, 0.712247f, 0.376656f, 2.312943f, 0.731505f, 1.562580f, +0.045130f, 0.139328f, 0.001319f, 0.208679f, 0.033281f, 0.199370f, 0.064624f, 0.165862f, 0.000960f, 0.004882f, 0.001296f, 0.008868f, 0.116891f, 0.726591f, 0.196100f, 0.548404f, +0.054583f, 0.200362f, 0.001307f, 0.275703f, 0.057016f, 0.406110f, 0.090679f, 0.310397f, 0.043957f, 0.265821f, 0.048604f, 0.443564f, 0.164518f, 1.215922f, 0.226060f, 0.843146f, +0.033823f, 0.145773f, 0.001500f, 0.207546f, 0.034937f, 0.292173f, 0.102923f, 0.231062f, 0.020304f, 0.144162f, 0.041586f, 0.248904f, 0.133278f, 1.156537f, 0.339224f, 0.829794f, +0.107861f, 0.361900f, 0.003208f, 0.550441f, 0.175103f, 1.139995f, 0.346055f, 0.963106f, 0.113253f, 0.626001f, 0.155610f, 1.154623f, 0.405160f, 2.737056f, 0.691798f, 2.097866f, +0.081419f, 0.208546f, 0.002436f, 0.323237f, 0.082907f, 0.412052f, 0.164791f, 0.354749f, 0.001559f, 0.006578f, 0.002154f, 0.012364f, 0.236017f, 1.217171f, 0.405308f, 0.950699f, +0.099715f, 0.303683f, 0.002443f, 0.432441f, 0.143826f, 0.849924f, 0.234148f, 0.672256f, 0.072285f, 0.362665f, 0.081815f, 0.626259f, 0.336371f, 2.062579f, 0.473123f, 1.480089f, +0.080091f, 0.286386f, 0.003635f, 0.421960f, 0.114234f, 0.792587f, 0.344482f, 0.648657f, 0.043278f, 0.254939f, 0.090735f, 0.455512f, 0.353209f, 2.542926f, 0.920252f, 1.888100f, +0.118573f, 0.330074f, 0.003610f, 0.519534f, 0.265796f, 1.435677f, 0.537707f, 1.255187f, 0.112069f, 0.513936f, 0.157622f, 0.980969f, 0.498480f, 2.793865f, 0.871260f, 2.216052f, +0.004387f, 0.011568f, 0.000139f, 0.027394f, 0.005143f, 0.026314f, 0.010857f, 0.034613f, 0.000060f, 0.000259f, 0.000087f, 0.000742f, 0.010342f, 0.054906f, 0.018863f, 0.065523f, +0.004439f, 0.013917f, 0.000116f, 0.030279f, 0.007371f, 0.044842f, 0.012745f, 0.054190f, 0.002280f, 0.011776f, 0.002741f, 0.031068f, 0.012177f, 0.076868f, 0.018191f, 0.084276f, +0.000190f, 0.000701f, 0.000009f, 0.001577f, 0.000313f, 0.002233f, 0.001001f, 0.002792f, 0.000073f, 0.000442f, 0.000162f, 0.001207f, 0.000683f, 0.005060f, 0.001889f, 0.005740f, +0.007728f, 0.022146f, 0.000250f, 0.053258f, 0.019943f, 0.110897f, 0.042851f, 0.148134f, 0.005175f, 0.024431f, 0.007731f, 0.071249f, 0.026419f, 0.152441f, 0.049045f, 0.184739f, +0.006234f, 0.015866f, 0.000197f, 0.030958f, 0.009050f, 0.044688f, 0.019026f, 0.048434f, 0.000121f, 0.000509f, 0.000178f, 0.001205f, 0.019077f, 0.097751f, 0.034651f, 0.096116f, +0.007921f, 0.023967f, 0.000205f, 0.042964f, 0.016286f, 0.095620f, 0.028043f, 0.095211f, 0.005842f, 0.029122f, 0.006994f, 0.063307f, 0.028204f, 0.171832f, 0.041960f, 0.155227f, +0.004023f, 0.014291f, 0.000193f, 0.026508f, 0.008179f, 0.056383f, 0.026087f, 0.058090f, 0.002212f, 0.012944f, 0.004904f, 0.029116f, 0.018727f, 0.133955f, 0.051606f, 0.125209f, +0.013220f, 0.036565f, 0.000426f, 0.072454f, 0.042246f, 0.226720f, 0.090395f, 0.249532f, 0.012713f, 0.057928f, 0.018913f, 0.139193f, 0.058669f, 0.326712f, 0.108461f, 0.326231f, +0.005292f, 0.014816f, 0.000147f, 0.032799f, 0.005229f, 0.028406f, 0.009665f, 0.034929f, 0.000113f, 0.000520f, 0.000145f, 0.001395f, 0.014657f, 0.082623f, 0.023407f, 0.092171f, +0.006950f, 0.023136f, 0.000158f, 0.047055f, 0.009727f, 0.062831f, 0.014726f, 0.070979f, 0.005603f, 0.030724f, 0.005897f, 0.075776f, 0.022401f, 0.150140f, 0.029300f, 0.153878f, +0.003771f, 0.014740f, 0.000159f, 0.031019f, 0.005219f, 0.039584f, 0.014637f, 0.046269f, 0.002266f, 0.014591f, 0.004418f, 0.037235f, 0.015891f, 0.125054f, 0.038502f, 0.132614f, +0.015325f, 0.046630f, 0.000434f, 0.104826f, 0.033334f, 0.196802f, 0.062709f, 0.245744f, 0.016106f, 0.080735f, 0.021066f, 0.220096f, 0.061557f, 0.377111f, 0.100051f, 0.427214f, +0.012751f, 0.029619f, 0.000363f, 0.067854f, 0.017397f, 0.078410f, 0.032916f, 0.099776f, 0.000244f, 0.000935f, 0.000321f, 0.002598f, 0.039526f, 0.184855f, 0.064613f, 0.213406f, +0.016958f, 0.046835f, 0.000396f, 0.098573f, 0.032772f, 0.175623f, 0.050786f, 0.205314f, 0.012305f, 0.055985f, 0.013257f, 0.142889f, 0.061170f, 0.340149f, 0.081901f, 0.360770f, +0.011927f, 0.038677f, 0.000515f, 0.084227f, 0.022793f, 0.143415f, 0.065429f, 0.173479f, 0.006451f, 0.034462f, 0.012875f, 0.091011f, 0.056247f, 0.367231f, 0.139499f, 0.403008f, +0.022501f, 0.056801f, 0.000652f, 0.132142f, 0.067578f, 0.331019f, 0.130136f, 0.427748f, 0.021287f, 0.088525f, 0.028499f, 0.249745f, 0.101150f, 0.514115f, 0.168290f, 0.602723f, +0.057900f, 0.090182f, 0.001353f, 0.218290f, 0.056994f, 0.172248f, 0.088483f, 0.231589f, 0.000790f, 0.002027f, 0.000853f, 0.005950f, 0.100644f, 0.315616f, 0.134995f, 0.384985f, +0.060025f, 0.111161f, 0.001149f, 0.247203f, 0.083693f, 0.300743f, 0.106422f, 0.371487f, 0.031006f, 0.094596f, 0.027411f, 0.255103f, 0.121416f, 0.452721f, 0.133389f, 0.507343f, +0.002512f, 0.005461f, 0.000089f, 0.012566f, 0.003463f, 0.014611f, 0.008157f, 0.018674f, 0.000967f, 0.003464f, 0.001584f, 0.009666f, 0.006642f, 0.029078f, 0.013516f, 0.033717f, +0.108103f, 0.182989f, 0.002571f, 0.449802f, 0.234251f, 0.769401f, 0.370141f, 1.050505f, 0.072806f, 0.203029f, 0.079982f, 0.605198f, 0.272512f, 0.928766f, 0.372027f, 1.150468f, +0.077081f, 0.115868f, 0.001794f, 0.231091f, 0.093950f, 0.274028f, 0.145250f, 0.303571f, 0.001510f, 0.003740f, 0.001623f, 0.009045f, 0.173918f, 0.526372f, 0.232311f, 0.529033f, +0.100336f, 0.179331f, 0.001912f, 0.328594f, 0.173225f, 0.600749f, 0.219354f, 0.611428f, 0.074429f, 0.219149f, 0.065526f, 0.486951f, 0.263446f, 0.948031f, 0.288223f, 0.875383f, +0.049720f, 0.104338f, 0.001755f, 0.197815f, 0.084883f, 0.345634f, 0.199103f, 0.363984f, 0.027493f, 0.095045f, 0.044834f, 0.218518f, 0.170671f, 0.721111f, 0.345874f, 0.688956f, +0.173247f, 0.283029f, 0.004103f, 0.573235f, 0.464844f, 1.473518f, 0.731453f, 1.657697f, 0.167557f, 0.450950f, 0.183307f, 1.107573f, 0.566900f, 1.864676f, 0.770705f, 1.903163f, +0.068183f, 0.112754f, 0.001395f, 0.255132f, 0.056568f, 0.181513f, 0.076891f, 0.228134f, 0.001460f, 0.003978f, 0.001380f, 0.010914f, 0.139246f, 0.463628f, 0.163527f, 0.528660f, +0.091748f, 0.180398f, 0.001537f, 0.375018f, 0.107819f, 0.411354f, 0.120036f, 0.474991f, 0.074381f, 0.240935f, 0.057573f, 0.607385f, 0.218042f, 0.863197f, 0.209729f, 0.904278f, +0.048575f, 0.112141f, 0.001508f, 0.241212f, 0.056449f, 0.252863f, 0.116410f, 0.302112f, 0.029355f, 0.111644f, 0.042088f, 0.291213f, 0.150923f, 0.701512f, 0.268902f, 0.760399f, +0.209275f, 0.376114f, 0.004358f, 0.864246f, 0.382213f, 1.332879f, 0.528768f, 1.701208f, 0.221207f, 0.654941f, 0.212763f, 1.825000f, 0.619824f, 2.242863f, 0.740851f, 2.597122f, +0.119703f, 0.164232f, 0.002507f, 0.384569f, 0.137129f, 0.365062f, 0.190801f, 0.474822f, 0.002307f, 0.005215f, 0.002232f, 0.014809f, 0.273597f, 0.755783f, 0.328900f, 0.891834f, +0.163105f, 0.266074f, 0.002798f, 0.572406f, 0.264666f, 0.837758f, 0.301621f, 1.001079f, 0.119027f, 0.319878f, 0.094307f, 0.834502f, 0.433822f, 1.424887f, 0.427146f, 1.544732f, +0.111933f, 0.214390f, 0.003556f, 0.477221f, 0.179609f, 0.667509f, 0.379148f, 0.825317f, 0.060889f, 0.192126f, 0.089363f, 0.518614f, 0.389221f, 1.500981f, 0.709873f, 1.683689f, +0.223875f, 0.333816f, 0.004772f, 0.793791f, 0.564579f, 1.633467f, 0.799524f, 2.157533f, 0.213010f, 0.523242f, 0.209722f, 1.508841f, 0.742089f, 2.227872f, 0.907956f, 2.669687f, +0.048066f, 0.074055f, 0.001249f, 0.198315f, 0.060726f, 0.181539f, 0.104806f, 0.270035f, 0.000979f, 0.002484f, 0.001174f, 0.008067f, 0.165131f, 0.512242f, 0.246232f, 0.691271f, +0.040667f, 0.074498f, 0.000865f, 0.183287f, 0.072776f, 0.258684f, 0.102876f, 0.353513f, 0.031350f, 0.094608f, 0.030810f, 0.282267f, 0.162583f, 0.599661f, 0.198566f, 0.743472f, +0.001383f, 0.002974f, 0.000054f, 0.007570f, 0.002447f, 0.010211f, 0.006406f, 0.014438f, 0.000794f, 0.002815f, 0.001446f, 0.008690f, 0.007226f, 0.031293f, 0.016348f, 0.040144f, +0.067005f, 0.112194f, 0.001771f, 0.305108f, 0.186351f, 0.605451f, 0.327344f, 0.914561f, 0.067345f, 0.185766f, 0.082245f, 0.612624f, 0.333840f, 1.125471f, 0.506655f, 1.542378f, +0.054657f, 0.081271f, 0.001414f, 0.179326f, 0.085502f, 0.246690f, 0.146955f, 0.302347f, 0.001598f, 0.003915f, 0.001910f, 0.010475f, 0.243740f, 0.729712f, 0.361941f, 0.811388f, +0.058065f, 0.102657f, 0.001230f, 0.208103f, 0.128662f, 0.441375f, 0.181121f, 0.496990f, 0.064278f, 0.187213f, 0.062910f, 0.460225f, 0.301323f, 1.072603f, 0.366484f, 1.095726f, +0.023378f, 0.048527f, 0.000917f, 0.101787f, 0.051224f, 0.206322f, 0.133573f, 0.240380f, 0.019291f, 0.065969f, 0.034973f, 0.167798f, 0.158605f, 0.662877f, 0.357321f, 0.700664f, +0.091723f, 0.148223f, 0.002415f, 0.332128f, 0.315864f, 0.990429f, 0.552541f, 1.232711f, 0.132385f, 0.352435f, 0.161005f, 0.957658f, 0.593199f, 1.930070f, 0.896537f, 2.179383f, +0.006819f, 0.011155f, 0.000155f, 0.027924f, 0.007261f, 0.023047f, 0.010972f, 0.032047f, 0.000218f, 0.000587f, 0.000229f, 0.001783f, 0.027524f, 0.090652f, 0.035934f, 0.114359f, +0.007489f, 0.014565f, 0.000139f, 0.033498f, 0.011295f, 0.042626f, 0.013979f, 0.054455f, 0.009060f, 0.029030f, 0.007796f, 0.080965f, 0.035175f, 0.137744f, 0.037613f, 0.159644f, +0.003221f, 0.007356f, 0.000111f, 0.017506f, 0.004805f, 0.021289f, 0.011015f, 0.028141f, 0.002905f, 0.010929f, 0.004630f, 0.031540f, 0.019781f, 0.090952f, 0.039182f, 0.109070f, +0.015627f, 0.027781f, 0.000362f, 0.070625f, 0.036631f, 0.126359f, 0.056337f, 0.178427f, 0.024650f, 0.072194f, 0.026357f, 0.222561f, 0.091477f, 0.327431f, 0.121551f, 0.419466f, +0.095542f, 0.129665f, 0.002224f, 0.335913f, 0.140476f, 0.369926f, 0.217289f, 0.532313f, 0.002748f, 0.006144f, 0.002955f, 0.019303f, 0.431605f, 1.179362f, 0.576798f, 1.539650f, +0.106246f, 0.171445f, 0.002026f, 0.408052f, 0.221274f, 0.692827f, 0.280335f, 0.915931f, 0.115707f, 0.307590f, 0.101916f, 0.887778f, 0.558527f, 1.814631f, 0.611356f, 2.176452f, +0.059241f, 0.112239f, 0.002092f, 0.276405f, 0.122004f, 0.448516f, 0.286312f, 0.613521f, 0.048091f, 0.150103f, 0.078464f, 0.448266f, 0.407140f, 1.553093f, 0.825493f, 1.927401f, +0.133416f, 0.196781f, 0.003161f, 0.517691f, 0.431827f, 1.235862f, 0.679832f, 1.805948f, 0.189438f, 0.460304f, 0.207346f, 1.468499f, 0.874062f, 2.595684f, 1.188877f, 3.441199f, +0.098037f, 0.285071f, 0.003272f, 0.456743f, 0.097248f, 0.548692f, 0.215676f, 0.488310f, 0.001650f, 0.007906f, 0.002545f, 0.015361f, 0.250380f, 1.465869f, 0.479758f, 1.183545f, +0.085690f, 0.296261f, 0.002343f, 0.436093f, 0.120401f, 0.807715f, 0.218706f, 0.660406f, 0.054615f, 0.311068f, 0.068973f, 0.555267f, 0.254670f, 1.772783f, 0.399680f, 1.315017f, +0.003522f, 0.014297f, 0.000178f, 0.021775f, 0.004893f, 0.038544f, 0.016465f, 0.032608f, 0.001673f, 0.011190f, 0.003914f, 0.020667f, 0.013684f, 0.111843f, 0.039781f, 0.085842f, +0.123728f, 0.391001f, 0.004203f, 0.636179f, 0.270180f, 1.656716f, 0.609860f, 1.497263f, 0.102816f, 0.535269f, 0.161352f, 1.056127f, 0.458268f, 2.915840f, 0.893715f, 2.390764f, +0.147069f, 0.412726f, 0.004889f, 0.544859f, 0.180639f, 0.983634f, 0.398955f, 0.721281f, 0.003555f, 0.016437f, 0.005459f, 0.026314f, 0.487554f, 2.754826f, 0.930332f, 1.832686f, +0.161406f, 0.538568f, 0.004394f, 0.653204f, 0.280811f, 1.818109f, 0.507972f, 1.224834f, 0.147728f, 0.812054f, 0.185791f, 1.194362f, 0.622670f, 4.183233f, 0.973163f, 2.556772f, +0.078563f, 0.307789f, 0.003962f, 0.386256f, 0.135162f, 1.027470f, 0.452896f, 0.716210f, 0.053600f, 0.345938f, 0.124867f, 0.526458f, 0.396235f, 3.125486f, 1.147098f, 1.976566f, +0.223440f, 0.681473f, 0.007559f, 0.913597f, 0.604149f, 3.575324f, 1.358045f, 2.662378f, 0.266636f, 1.339699f, 0.416702f, 2.177989f, 1.074250f, 6.596684f, 2.086306f, 4.456592f, +0.114540f, 0.353616f, 0.003347f, 0.529629f, 0.095762f, 0.573656f, 0.185945f, 0.477243f, 0.003026f, 0.015391f, 0.004085f, 0.027955f, 0.343690f, 2.136368f, 0.576585f, 1.612452f, +0.129946f, 0.477003f, 0.003110f, 0.656367f, 0.153888f, 1.096095f, 0.244744f, 0.837765f, 0.129985f, 0.786052f, 0.143726f, 1.311654f, 0.453745f, 3.353545f, 0.623478f, 2.325417f, +0.067579f, 0.291259f, 0.002996f, 0.414685f, 0.079139f, 0.661825f, 0.233140f, 0.523396f, 0.050390f, 0.357776f, 0.103206f, 0.617721f, 0.308499f, 2.677043f, 0.785203f, 1.920729f, +0.237639f, 0.797337f, 0.007069f, 1.212732f, 0.437368f, 2.847447f, 0.864367f, 2.405620f, 0.309928f, 1.713113f, 0.425841f, 3.159738f, 1.034123f, 6.986022f, 1.765736f, 5.354563f, +0.195735f, 0.501354f, 0.005856f, 0.777079f, 0.225962f, 1.123040f, 0.449134f, 0.966860f, 0.004655f, 0.019643f, 0.006433f, 0.036920f, 0.657324f, 3.389908f, 1.128812f, 2.647764f, +0.224863f, 0.684821f, 0.005510f, 0.975177f, 0.367699f, 2.172877f, 0.598612f, 1.718659f, 0.202470f, 1.015826f, 0.229165f, 1.754154f, 0.878755f, 5.388393f, 1.236012f, 3.866665f, +0.151578f, 0.542007f, 0.006880f, 0.798592f, 0.245102f, 1.700590f, 0.739127f, 1.391771f, 0.101737f, 0.599305f, 0.213298f, 1.070805f, 0.774423f, 5.575450f, 2.017683f, 4.139721f, +0.247451f, 0.688834f, 0.007534f, 1.084222f, 0.628856f, 3.396720f, 1.272180f, 2.969694f, 0.290500f, 1.332204f, 0.408582f, 2.542825f, 1.205160f, 6.754638f, 2.106417f, 5.357679f, +0.036548f, 0.096374f, 0.001161f, 0.228224f, 0.048574f, 0.248534f, 0.102545f, 0.326916f, 0.000616f, 0.002675f, 0.000904f, 0.007683f, 0.099811f, 0.529920f, 0.182052f, 0.632388f, +0.034688f, 0.108758f, 0.000903f, 0.236618f, 0.065302f, 0.397278f, 0.112916f, 0.480098f, 0.022129f, 0.114302f, 0.026603f, 0.301566f, 0.110239f, 0.695906f, 0.164689f, 0.762973f, +0.001248f, 0.004596f, 0.000060f, 0.010346f, 0.002324f, 0.016601f, 0.007444f, 0.020758f, 0.000594f, 0.003600f, 0.001322f, 0.009829f, 0.005187f, 0.038446f, 0.014354f, 0.043614f, +0.055887f, 0.160162f, 0.001807f, 0.385161f, 0.163511f, 0.909242f, 0.351333f, 1.214542f, 0.046485f, 0.219465f, 0.069442f, 0.640018f, 0.221347f, 1.277185f, 0.410910f, 1.547782f, +0.064688f, 0.164627f, 0.002047f, 0.321223f, 0.106455f, 0.525684f, 0.223806f, 0.569742f, 0.001565f, 0.006563f, 0.002288f, 0.015528f, 0.229317f, 1.175016f, 0.416529f, 1.155369f, +0.077091f, 0.233270f, 0.001998f, 0.418168f, 0.179700f, 1.055092f, 0.309434f, 1.050583f, 0.070625f, 0.352060f, 0.084550f, 0.765334f, 0.318017f, 1.937496f, 0.473120f, 1.750265f, +0.032859f, 0.116740f, 0.001577f, 0.216533f, 0.075741f, 0.522139f, 0.241587f, 0.537948f, 0.022439f, 0.131334f, 0.049760f, 0.295410f, 0.177211f, 1.267632f, 0.488353f, 1.184868f, +0.119080f, 0.329354f, 0.003835f, 0.652608f, 0.431393f, 2.315159f, 0.923075f, 2.548111f, 0.142236f, 0.648089f, 0.211597f, 1.557277f, 0.612200f, 3.409179f, 1.131773f, 3.404161f, +0.049141f, 0.137581f, 0.001367f, 0.304565f, 0.055047f, 0.299039f, 0.101746f, 0.367704f, 0.001300f, 0.005994f, 0.001670f, 0.016091f, 0.157676f, 0.888814f, 0.251800f, 0.991527f, +0.060538f, 0.201523f, 0.001379f, 0.409859f, 0.096056f, 0.620445f, 0.145420f, 0.700907f, 0.060614f, 0.332406f, 0.063798f, 0.819822f, 0.226042f, 1.515019f, 0.295660f, 1.552737f, +0.027569f, 0.107753f, 0.001164f, 0.226753f, 0.043257f, 0.328054f, 0.121304f, 0.383456f, 0.020576f, 0.132488f, 0.040117f, 0.338096f, 0.134579f, 1.059049f, 0.326062f, 1.123078f, +0.123532f, 0.375874f, 0.003498f, 0.844982f, 0.304622f, 1.798483f, 0.573068f, 2.245746f, 0.161264f, 0.808348f, 0.210920f, 2.203670f, 0.574838f, 3.521594f, 0.934313f, 3.989481f, +0.112157f, 0.260519f, 0.003194f, 0.596819f, 0.173478f, 0.781881f, 0.328230f, 0.994930f, 0.002670f, 0.010217f, 0.003512f, 0.028383f, 0.402761f, 1.883615f, 0.658390f, 2.174535f, +0.139912f, 0.386412f, 0.003263f, 0.813280f, 0.306536f, 1.642707f, 0.475037f, 1.920426f, 0.126099f, 0.573728f, 0.135860f, 1.464324f, 0.584675f, 3.251192f, 0.782823f, 3.448284f, +0.082588f, 0.267809f, 0.003568f, 0.583215f, 0.178929f, 1.125826f, 0.513627f, 1.361829f, 0.055485f, 0.296402f, 0.110733f, 0.782757f, 0.451203f, 2.945847f, 1.119027f, 3.232841f, +0.171800f, 0.433695f, 0.004979f, 1.008952f, 0.584972f, 2.865365f, 1.126486f, 3.702668f, 0.201879f, 0.839562f, 0.270283f, 2.368544f, 0.894720f, 4.547585f, 1.488608f, 5.331366f, +0.112315f, 0.174936f, 0.002624f, 0.423442f, 0.125340f, 0.378802f, 0.194589f, 0.509301f, 0.001903f, 0.004884f, 0.002054f, 0.014336f, 0.226171f, 0.709267f, 0.303368f, 0.865157f, +0.109220f, 0.202267f, 0.002090f, 0.449806f, 0.172647f, 0.620391f, 0.219534f, 0.766327f, 0.070078f, 0.213797f, 0.061952f, 0.576560f, 0.255941f, 0.954321f, 0.281180f, 1.069463f, +0.003836f, 0.008340f, 0.000136f, 0.019190f, 0.005995f, 0.025295f, 0.014122f, 0.032329f, 0.001834f, 0.006571f, 0.003004f, 0.018335f, 0.011750f, 0.051442f, 0.023912f, 0.059649f, +0.182035f, 0.308137f, 0.004329f, 0.757427f, 0.447197f, 1.468827f, 0.706619f, 2.005471f, 0.152281f, 0.424653f, 0.167289f, 1.265825f, 0.531614f, 1.811832f, 0.725748f, 2.244328f, +0.186226f, 0.279935f, 0.004333f, 0.558310f, 0.257328f, 0.750561f, 0.397840f, 0.831481f, 0.004532f, 0.011223f, 0.004871f, 0.027144f, 0.486776f, 1.473256f, 0.650211f, 1.480701f, +0.227385f, 0.406406f, 0.004334f, 0.744671f, 0.445055f, 1.543465f, 0.563572f, 1.570903f, 0.209509f, 0.616881f, 0.184448f, 1.370716f, 0.691654f, 2.488973f, 0.756704f, 2.298240f, +0.094566f, 0.198447f, 0.003338f, 0.376238f, 0.183031f, 0.745277f, 0.429318f, 0.784845f, 0.064950f, 0.224536f, 0.105918f, 0.516234f, 0.376059f, 1.588903f, 0.762101f, 1.518051f, +0.363345f, 0.593586f, 0.008605f, 1.202224f, 1.105246f, 3.503541f, 1.739155f, 3.941460f, 0.436489f, 1.174731f, 0.477517f, 2.885242f, 1.377373f, 4.530528f, 1.872550f, 4.624039f, +0.147420f, 0.243786f, 0.003016f, 0.551624f, 0.138659f, 0.444923f, 0.188474f, 0.559201f, 0.003921f, 0.010682f, 0.003705f, 0.029311f, 0.348782f, 1.161290f, 0.409601f, 1.324180f, +0.186074f, 0.365866f, 0.003118f, 0.760576f, 0.247905f, 0.945813f, 0.275995f, 1.092131f, 0.187375f, 0.606943f, 0.145032f, 1.530071f, 0.512300f, 2.028117f, 0.492768f, 2.124639f, +0.082681f, 0.190876f, 0.002566f, 0.410569f, 0.108928f, 0.487946f, 0.224635f, 0.582982f, 0.062063f, 0.236037f, 0.088982f, 0.615682f, 0.297602f, 1.383298f, 0.530243f, 1.499415f, +0.392785f, 0.705923f, 0.008179f, 1.622093f, 0.813284f, 2.836143f, 1.125131f, 3.619886f, 0.515698f, 1.526855f, 0.496012f, 4.254597f, 1.347718f, 4.876787f, 1.610876f, 5.647072f, +0.245151f, 0.336346f, 0.005134f, 0.787594f, 0.318389f, 0.847607f, 0.443003f, 1.102448f, 0.005869f, 0.013266f, 0.005678f, 0.037670f, 0.649131f, 1.793157f, 0.780341f, 2.115949f, +0.313334f, 0.511144f, 0.005374f, 1.099626f, 0.576420f, 1.824561f, 0.656902f, 2.180261f, 0.284018f, 0.763276f, 0.225032f, 1.991249f, 0.965484f, 3.171128f, 0.950626f, 3.437847f, +0.180466f, 0.345655f, 0.005734f, 0.769410f, 0.328295f, 1.220097f, 0.693021f, 1.508545f, 0.121937f, 0.384753f, 0.178959f, 1.038580f, 0.726988f, 2.803536f, 1.325903f, 3.144798f, +0.398010f, 0.593467f, 0.008483f, 1.411221f, 1.137922f, 3.292290f, 1.611459f, 4.348559f, 0.470377f, 1.155443f, 0.463115f, 3.331882f, 1.528401f, 4.588510f, 1.870020f, 5.498469f, +0.005820f, 0.008967f, 0.000151f, 0.024014f, 0.009671f, 0.028912f, 0.016691f, 0.043006f, 0.000129f, 0.000328f, 0.000155f, 0.001065f, 0.022861f, 0.070915f, 0.034089f, 0.095700f, +0.008098f, 0.014834f, 0.000172f, 0.036497f, 0.019059f, 0.067747f, 0.026942f, 0.092582f, 0.006804f, 0.020533f, 0.006687f, 0.061262f, 0.037013f, 0.136516f, 0.045205f, 0.169255f, +0.000211f, 0.000453f, 0.000008f, 0.001153f, 0.000490f, 0.002045f, 0.001283f, 0.002891f, 0.000132f, 0.000467f, 0.000240f, 0.001442f, 0.001258f, 0.005447f, 0.002846f, 0.006988f, +0.010701f, 0.017918f, 0.000283f, 0.048728f, 0.039143f, 0.127175f, 0.068759f, 0.192104f, 0.011723f, 0.032337f, 0.014317f, 0.106641f, 0.060956f, 0.205501f, 0.092511f, 0.281625f, +0.007071f, 0.010513f, 0.000183f, 0.023198f, 0.014547f, 0.041972f, 0.025003f, 0.051441f, 0.000225f, 0.000552f, 0.000269f, 0.001477f, 0.036049f, 0.107923f, 0.053530f, 0.120002f, +0.012352f, 0.021838f, 0.000262f, 0.044269f, 0.035997f, 0.123488f, 0.050674f, 0.139048f, 0.014903f, 0.043407f, 0.014586f, 0.106708f, 0.073284f, 0.260864f, 0.089131f, 0.266487f, +0.003803f, 0.007894f, 0.000149f, 0.016557f, 0.010959f, 0.044140f, 0.028576f, 0.051426f, 0.003420f, 0.011696f, 0.006200f, 0.029750f, 0.029496f, 0.123276f, 0.066451f, 0.130303f, +0.015649f, 0.025289f, 0.000412f, 0.056666f, 0.070879f, 0.222251f, 0.123989f, 0.276618f, 0.024619f, 0.065540f, 0.029941f, 0.178090f, 0.115712f, 0.376487f, 0.174882f, 0.425119f, +0.000850f, 0.001390f, 0.000019f, 0.003481f, 0.001190f, 0.003779f, 0.001799f, 0.005254f, 0.000030f, 0.000080f, 0.000031f, 0.000242f, 0.003923f, 0.012919f, 0.005121f, 0.016298f, +0.001535f, 0.002986f, 0.000029f, 0.006867f, 0.003045f, 0.011492f, 0.003769f, 0.014681f, 0.002024f, 0.006486f, 0.001742f, 0.018089f, 0.008243f, 0.032281f, 0.008815f, 0.037414f, +0.000505f, 0.001153f, 0.000017f, 0.002744f, 0.000990f, 0.004389f, 0.002271f, 0.005801f, 0.000496f, 0.001867f, 0.000791f, 0.005388f, 0.003545f, 0.016299f, 0.007022f, 0.019546f, +0.002569f, 0.004567f, 0.000059f, 0.011611f, 0.007921f, 0.027323f, 0.012182f, 0.038582f, 0.004417f, 0.012937f, 0.004723f, 0.039882f, 0.017195f, 0.061546f, 0.022848f, 0.078846f, +0.012238f, 0.016609f, 0.000285f, 0.043028f, 0.023666f, 0.062322f, 0.036607f, 0.089680f, 0.000384f, 0.000858f, 0.000413f, 0.002695f, 0.063208f, 0.172716f, 0.084471f, 0.225479f, +0.022380f, 0.036113f, 0.000427f, 0.085952f, 0.061301f, 0.191940f, 0.077664f, 0.253748f, 0.026565f, 0.070619f, 0.023399f, 0.203823f, 0.134506f, 0.437005f, 0.147229f, 0.524139f, +0.009542f, 0.018078f, 0.000337f, 0.044520f, 0.025845f, 0.095014f, 0.060653f, 0.129969f, 0.008443f, 0.026352f, 0.013775f, 0.078696f, 0.074974f, 0.285999f, 0.152013f, 0.354927f, +0.022540f, 0.033245f, 0.000534f, 0.087461f, 0.095952f, 0.274608f, 0.151058f, 0.401281f, 0.034883f, 0.084761f, 0.038181f, 0.270412f, 0.168827f, 0.501363f, 0.229635f, 0.664677f, +0.009921f, 0.028847f, 0.000331f, 0.046219f, 0.012943f, 0.073027f, 0.028705f, 0.064990f, 0.000182f, 0.000872f, 0.000281f, 0.001694f, 0.028967f, 0.169592f, 0.055505f, 0.136929f, +0.014259f, 0.049299f, 0.000390f, 0.072568f, 0.026351f, 0.176776f, 0.047866f, 0.144536f, 0.009906f, 0.056420f, 0.012510f, 0.100711f, 0.048451f, 0.337271f, 0.076039f, 0.250181f, +0.000448f, 0.001819f, 0.000023f, 0.002771f, 0.000819f, 0.006450f, 0.002756f, 0.005457f, 0.000232f, 0.001552f, 0.000543f, 0.002866f, 0.001991f, 0.016271f, 0.005787f, 0.012488f, +0.016513f, 0.052185f, 0.000561f, 0.084908f, 0.047427f, 0.290815f, 0.107053f, 0.262825f, 0.014957f, 0.077866f, 0.023472f, 0.153636f, 0.069927f, 0.444928f, 0.136372f, 0.364807f, +0.015899f, 0.044618f, 0.000529f, 0.058903f, 0.025684f, 0.139857f, 0.056725f, 0.102554f, 0.000419f, 0.001937f, 0.000643f, 0.003101f, 0.060260f, 0.340488f, 0.114986f, 0.226514f, +0.028693f, 0.095742f, 0.000781f, 0.116121f, 0.065656f, 0.425092f, 0.118769f, 0.286378f, 0.028624f, 0.157346f, 0.035999f, 0.231424f, 0.126555f, 0.850222f, 0.197791f, 0.519652f, +0.010680f, 0.041839f, 0.000539f, 0.052506f, 0.024165f, 0.183697f, 0.080971f, 0.128048f, 0.007942f, 0.051255f, 0.018501f, 0.078002f, 0.061580f, 0.485744f, 0.178275f, 0.307186f, +0.031859f, 0.097166f, 0.001078f, 0.130263f, 0.113295f, 0.670473f, 0.254671f, 0.499270f, 0.041437f, 0.208200f, 0.064759f, 0.338478f, 0.175117f, 1.075348f, 0.340096f, 0.726484f, +0.011932f, 0.036837f, 0.000349f, 0.055173f, 0.013120f, 0.078597f, 0.025477f, 0.065387f, 0.000344f, 0.001748f, 0.000464f, 0.003174f, 0.040934f, 0.254442f, 0.068671f, 0.192043f, +0.022260f, 0.081713f, 0.000533f, 0.112438f, 0.034672f, 0.246954f, 0.055142f, 0.188751f, 0.024270f, 0.146767f, 0.026836f, 0.244904f, 0.088866f, 0.656795f, 0.122109f, 0.455435f, +0.008852f, 0.038152f, 0.000392f, 0.054320f, 0.013634f, 0.114020f, 0.040166f, 0.090171f, 0.007194f, 0.051081f, 0.014735f, 0.088194f, 0.046201f, 0.400914f, 0.117592f, 0.287648f, +0.032650f, 0.109550f, 0.000971f, 0.166623f, 0.079035f, 0.514549f, 0.156196f, 0.434708f, 0.046413f, 0.256546f, 0.063772f, 0.473184f, 0.162443f, 1.097383f, 0.277367f, 0.841109f, +0.020953f, 0.053668f, 0.000627f, 0.083184f, 0.031813f, 0.158113f, 0.063234f, 0.136125f, 0.000543f, 0.002292f, 0.000751f, 0.004308f, 0.080447f, 0.414876f, 0.138150f, 0.324048f, +0.039583f, 0.120549f, 0.000970f, 0.171660f, 0.085129f, 0.503062f, 0.138590f, 0.397902f, 0.038847f, 0.194901f, 0.043969f, 0.336560f, 0.176852f, 1.084433f, 0.248752f, 0.778180f, +0.020403f, 0.072956f, 0.000926f, 0.107493f, 0.043391f, 0.301062f, 0.130850f, 0.246390f, 0.014926f, 0.087925f, 0.031293f, 0.157100f, 0.119177f, 0.858012f, 0.310503f, 0.637066f, +0.034936f, 0.097253f, 0.001064f, 0.153076f, 0.116772f, 0.630737f, 0.236231f, 0.551443f, 0.044704f, 0.205007f, 0.062875f, 0.391304f, 0.194532f, 1.090306f, 0.340009f, 0.864815f, +0.002725f, 0.007186f, 0.000087f, 0.017018f, 0.004764f, 0.024374f, 0.010057f, 0.032061f, 0.000050f, 0.000217f, 0.000073f, 0.000624f, 0.008509f, 0.045177f, 0.015520f, 0.053912f, +0.004253f, 0.013336f, 0.000111f, 0.029014f, 0.010531f, 0.064070f, 0.018210f, 0.077427f, 0.002958f, 0.015276f, 0.003556f, 0.040304f, 0.015454f, 0.097559f, 0.023088f, 0.106961f, +0.000117f, 0.000431f, 0.000006f, 0.000970f, 0.000287f, 0.002047f, 0.000918f, 0.002560f, 0.000061f, 0.000368f, 0.000135f, 0.001004f, 0.000556f, 0.004121f, 0.001539f, 0.004675f, +0.005496f, 0.015751f, 0.000178f, 0.037880f, 0.021150f, 0.117609f, 0.045445f, 0.157100f, 0.004983f, 0.023525f, 0.007444f, 0.068606f, 0.024888f, 0.143606f, 0.046203f, 0.174032f, +0.005153f, 0.013114f, 0.000163f, 0.025589f, 0.011153f, 0.055077f, 0.023449f, 0.059693f, 0.000136f, 0.000570f, 0.000199f, 0.001348f, 0.020885f, 0.107015f, 0.037936f, 0.105226f, +0.010099f, 0.030557f, 0.000262f, 0.054778f, 0.030960f, 0.181781f, 0.053312f, 0.181004f, 0.010084f, 0.050267f, 0.012072f, 0.109274f, 0.047628f, 0.290172f, 0.070858f, 0.262131f, +0.003291f, 0.011694f, 0.000158f, 0.021690f, 0.009978f, 0.068788f, 0.031827f, 0.070871f, 0.002450f, 0.014339f, 0.005433f, 0.032252f, 0.020294f, 0.145170f, 0.055927f, 0.135692f, +0.012511f, 0.034604f, 0.000403f, 0.068567f, 0.059612f, 0.319920f, 0.127555f, 0.352110f, 0.016288f, 0.074217f, 0.024231f, 0.178334f, 0.073538f, 0.409513f, 0.135949f, 0.408910f, +0.003772f, 0.010561f, 0.000105f, 0.023379f, 0.005558f, 0.030191f, 0.010272f, 0.037123f, 0.000109f, 0.000502f, 0.000140f, 0.001346f, 0.013838f, 0.078004f, 0.022098f, 0.087018f, +0.007642f, 0.025438f, 0.000174f, 0.051736f, 0.015947f, 0.103007f, 0.024143f, 0.116365f, 0.008340f, 0.045734f, 0.008778f, 0.112795f, 0.032622f, 0.218644f, 0.042669f, 0.224087f, +0.002661f, 0.010401f, 0.000112f, 0.021887f, 0.005491f, 0.041646f, 0.015400f, 0.048680f, 0.002165f, 0.013938f, 0.004221f, 0.035570f, 0.014851f, 0.116871f, 0.035982f, 0.123937f, +0.012507f, 0.038055f, 0.000354f, 0.085549f, 0.040563f, 0.239481f, 0.076308f, 0.299038f, 0.017795f, 0.089201f, 0.023275f, 0.243176f, 0.066538f, 0.407626f, 0.108147f, 0.461784f, +0.008847f, 0.020550f, 0.000252f, 0.047077f, 0.017997f, 0.081116f, 0.034052f, 0.103219f, 0.000230f, 0.000878f, 0.000302f, 0.002440f, 0.036322f, 0.169870f, 0.059376f, 0.196106f, +0.018148f, 0.050122f, 0.000423f, 0.105492f, 0.052295f, 0.280247f, 0.081042f, 0.327626f, 0.017828f, 0.081114f, 0.019208f, 0.207027f, 0.086707f, 0.482148f, 0.116092f, 0.511377f, +0.008192f, 0.026563f, 0.000354f, 0.057847f, 0.023342f, 0.146866f, 0.067004f, 0.177653f, 0.005998f, 0.032044f, 0.011971f, 0.084622f, 0.051166f, 0.334055f, 0.126896f, 0.366600f, +0.017873f, 0.045120f, 0.000518f, 0.104967f, 0.080042f, 0.392070f, 0.154138f, 0.506638f, 0.022892f, 0.095202f, 0.030649f, 0.268580f, 0.106421f, 0.540906f, 0.177060f, 0.634131f, +0.013235f, 0.020614f, 0.000309f, 0.049898f, 0.019426f, 0.058708f, 0.030158f, 0.078934f, 0.000244f, 0.000627f, 0.000264f, 0.001841f, 0.030471f, 0.095555f, 0.040871f, 0.116557f, +0.021164f, 0.039195f, 0.000405f, 0.087162f, 0.044001f, 0.158112f, 0.055950f, 0.195305f, 0.014801f, 0.045156f, 0.013085f, 0.121774f, 0.056702f, 0.211423f, 0.062293f, 0.236932f, +0.000568f, 0.001236f, 0.000020f, 0.002843f, 0.001168f, 0.004930f, 0.002752f, 0.006300f, 0.000296f, 0.001061f, 0.000485f, 0.002961f, 0.001991f, 0.008715f, 0.004051f, 0.010105f, +0.028292f, 0.047890f, 0.000673f, 0.117718f, 0.091412f, 0.300244f, 0.144440f, 0.409939f, 0.025796f, 0.071936f, 0.028339f, 0.214430f, 0.094462f, 0.321943f, 0.128958f, 0.398793f, +0.023444f, 0.035240f, 0.000546f, 0.070285f, 0.042606f, 0.124271f, 0.065871f, 0.137669f, 0.000622f, 0.001540f, 0.000668f, 0.003724f, 0.070060f, 0.212041f, 0.093583f, 0.213113f, +0.047072f, 0.084131f, 0.000897f, 0.154157f, 0.121175f, 0.420237f, 0.153443f, 0.427708f, 0.047272f, 0.139190f, 0.041618f, 0.309281f, 0.163698f, 0.589081f, 0.179094f, 0.543940f, +0.014969f, 0.031413f, 0.000528f, 0.059557f, 0.038106f, 0.155162f, 0.089381f, 0.163400f, 0.011206f, 0.038740f, 0.018274f, 0.089068f, 0.068058f, 0.287556f, 0.137923f, 0.274733f, +0.060328f, 0.098556f, 0.001429f, 0.199612f, 0.241357f, 0.765081f, 0.379786f, 0.860711f, 0.078992f, 0.212592f, 0.086417f, 0.522145f, 0.261463f, 0.860017f, 0.355461f, 0.877767f, +0.017883f, 0.029573f, 0.000366f, 0.066917f, 0.022123f, 0.070986f, 0.030070f, 0.089219f, 0.000518f, 0.001412f, 0.000490f, 0.003875f, 0.048373f, 0.161060f, 0.056808f, 0.183651f, +0.037118f, 0.072984f, 0.000622f, 0.151721f, 0.065041f, 0.248146f, 0.072411f, 0.286535f, 0.040740f, 0.131965f, 0.031534f, 0.332677f, 0.116838f, 0.462544f, 0.112383f, 0.484557f, +0.012612f, 0.029116f, 0.000391f, 0.062627f, 0.021853f, 0.097891f, 0.045066f, 0.116957f, 0.010318f, 0.039243f, 0.014794f, 0.102362f, 0.051900f, 0.241238f, 0.092471f, 0.261488f, +0.062844f, 0.112944f, 0.001309f, 0.259526f, 0.171139f, 0.596807f, 0.236760f, 0.761729f, 0.089931f, 0.266264f, 0.086498f, 0.741946f, 0.246526f, 0.892066f, 0.294663f, 1.032967f, +0.030559f, 0.041927f, 0.000640f, 0.098177f, 0.052199f, 0.138964f, 0.072630f, 0.180745f, 0.000797f, 0.001802f, 0.000771f, 0.005118f, 0.092512f, 0.255554f, 0.111212f, 0.301557f, +0.064229f, 0.104777f, 0.001102f, 0.225406f, 0.155403f, 0.491903f, 0.177101f, 0.587799f, 0.063456f, 0.170534f, 0.050277f, 0.444892f, 0.226268f, 0.743177f, 0.222786f, 0.805684f, +0.028287f, 0.054179f, 0.000899f, 0.120600f, 0.067679f, 0.251527f, 0.142869f, 0.310992f, 0.020832f, 0.065733f, 0.030574f, 0.177435f, 0.130279f, 0.502405f, 0.237607f, 0.563561f, +0.065436f, 0.097571f, 0.001395f, 0.232017f, 0.246057f, 0.711905f, 0.348452f, 0.940306f, 0.084290f, 0.207053f, 0.082989f, 0.597065f, 0.287289f, 0.862488f, 0.351502f, 1.033530f, +0.068702f, 0.105849f, 0.001785f, 0.283457f, 0.080701f, 0.241255f, 0.139281f, 0.358862f, 0.001501f, 0.003809f, 0.001801f, 0.012371f, 0.174331f, 0.540782f, 0.259951f, 0.729786f, +0.065544f, 0.120069f, 0.001395f, 0.295407f, 0.109056f, 0.387642f, 0.154162f, 0.529745f, 0.054212f, 0.163605f, 0.053280f, 0.488120f, 0.193543f, 0.713851f, 0.236378f, 0.885047f, +0.002346f, 0.005046f, 0.000092f, 0.012846f, 0.003860f, 0.016110f, 0.010108f, 0.022779f, 0.001446f, 0.005125f, 0.002633f, 0.015822f, 0.009057f, 0.039221f, 0.020489f, 0.050315f, +0.088589f, 0.148335f, 0.002342f, 0.403393f, 0.229077f, 0.744266f, 0.402396f, 1.124248f, 0.095534f, 0.263524f, 0.116672f, 0.869057f, 0.326007f, 1.099065f, 0.494768f, 1.506190f, +0.077551f, 0.115313f, 0.002006f, 0.254439f, 0.112795f, 0.325435f, 0.193864f, 0.398858f, 0.002433f, 0.005960f, 0.002907f, 0.015947f, 0.255435f, 0.764723f, 0.379307f, 0.850318f, +0.092898f, 0.164241f, 0.001968f, 0.332945f, 0.191389f, 0.656561f, 0.269425f, 0.739291f, 0.110340f, 0.321373f, 0.107992f, 0.790029f, 0.356074f, 1.267495f, 0.433074f, 1.294821f, +0.039379f, 0.081743f, 0.001546f, 0.171458f, 0.080226f, 0.323135f, 0.209197f, 0.376477f, 0.034866f, 0.119229f, 0.063208f, 0.303270f, 0.197331f, 0.824729f, 0.444567f, 0.871743f, +0.120381f, 0.194535f, 0.003169f, 0.435899f, 0.385438f, 1.208588f, 0.674248f, 1.504237f, 0.186423f, 0.496294f, 0.226725f, 1.348561f, 0.575037f, 1.870974f, 0.869086f, 2.112654f, +0.005848f, 0.009565f, 0.000133f, 0.023946f, 0.005789f, 0.018375f, 0.008748f, 0.025551f, 0.000200f, 0.000540f, 0.000211f, 0.001640f, 0.017433f, 0.057417f, 0.022760f, 0.072433f, +0.007241f, 0.014084f, 0.000135f, 0.032391f, 0.010155f, 0.038323f, 0.012568f, 0.048957f, 0.009400f, 0.030118f, 0.008088f, 0.084000f, 0.025122f, 0.098377f, 0.026863f, 0.114018f, +0.003280f, 0.007489f, 0.000113f, 0.017822f, 0.004548f, 0.020152f, 0.010426f, 0.026637f, 0.003173f, 0.011938f, 0.005058f, 0.034452f, 0.014875f, 0.068392f, 0.029463f, 0.082016f, +0.012396f, 0.022037f, 0.000287f, 0.056021f, 0.027015f, 0.093191f, 0.041549f, 0.131592f, 0.020979f, 0.061443f, 0.022432f, 0.189418f, 0.053594f, 0.191834f, 0.071214f, 0.245756f, +0.141021f, 0.191387f, 0.003283f, 0.495810f, 0.192782f, 0.507665f, 0.298195f, 0.730515f, 0.004352f, 0.009731f, 0.004681f, 0.030570f, 0.470531f, 1.285729f, 0.628820f, 1.678511f, +0.176831f, 0.285344f, 0.003372f, 0.679139f, 0.342411f, 1.072117f, 0.433805f, 1.417360f, 0.206625f, 0.549281f, 0.181998f, 1.585355f, 0.686597f, 2.230722f, 0.751539f, 2.675507f, +0.103809f, 0.196678f, 0.003667f, 0.484350f, 0.198775f, 0.730745f, 0.466475f, 0.999580f, 0.090419f, 0.282217f, 0.147525f, 0.842808f, 0.526953f, 2.010137f, 1.068419f, 2.494596f, +0.182154f, 0.268667f, 0.004316f, 0.706808f, 0.548168f, 1.568825f, 0.862991f, 2.292503f, 0.277509f, 0.674301f, 0.303742f, 2.151212f, 0.881428f, 2.617557f, 1.198895f, 3.470197f, +0.130382f, 0.379123f, 0.004352f, 0.607434f, 0.120250f, 0.678470f, 0.266688f, 0.603806f, 0.002355f, 0.011281f, 0.003631f, 0.021919f, 0.245947f, 1.439914f, 0.471263f, 1.162589f, +0.128502f, 0.444281f, 0.003513f, 0.653976f, 0.167875f, 1.126198f, 0.304942f, 0.920805f, 0.087876f, 0.500514f, 0.110979f, 0.893436f, 0.282081f, 1.963595f, 0.442699f, 1.456558f, +0.005561f, 0.022573f, 0.000282f, 0.034380f, 0.007184f, 0.056583f, 0.024171f, 0.047869f, 0.002835f, 0.018956f, 0.006631f, 0.035012f, 0.015958f, 0.130430f, 0.046392f, 0.100108f, +0.152207f, 0.481002f, 0.005171f, 0.782617f, 0.309027f, 1.894924f, 0.697547f, 1.712545f, 0.135709f, 0.706514f, 0.212972f, 1.394006f, 0.416393f, 2.649398f, 0.812050f, 2.172302f, +0.194158f, 0.544872f, 0.006454f, 0.719313f, 0.221727f, 1.207371f, 0.489701f, 0.885344f, 0.005036f, 0.023283f, 0.007733f, 0.037273f, 0.475412f, 2.686219f, 0.907163f, 1.787044f, +0.240274f, 0.801731f, 0.006542f, 0.972383f, 0.388666f, 2.516416f, 0.703076f, 1.695272f, 0.235956f, 1.297037f, 0.296751f, 1.907670f, 0.684636f, 4.599538f, 1.070010f, 2.811215f, +0.123134f, 0.482405f, 0.006210f, 0.605389f, 0.196964f, 1.497278f, 0.659982f, 1.043695f, 0.090137f, 0.581751f, 0.209984f, 0.885323f, 0.458697f, 3.618184f, 1.327926f, 2.288150f, +0.272858f, 0.832194f, 0.009231f, 1.115656f, 0.685952f, 4.059429f, 1.541927f, 3.022869f, 0.349360f, 1.755342f, 0.545984f, 2.853712f, 0.968935f, 5.949973f, 1.881773f, 4.019687f, +0.091391f, 0.282149f, 0.002671f, 0.422588f, 0.071041f, 0.425570f, 0.137945f, 0.354046f, 0.002591f, 0.013177f, 0.003497f, 0.023932f, 0.202547f, 1.259029f, 0.339800f, 0.950269f, +0.116913f, 0.429163f, 0.002799f, 0.590538f, 0.128730f, 0.916902f, 0.204732f, 0.700804f, 0.125479f, 0.758807f, 0.138744f, 1.266190f, 0.301527f, 2.228531f, 0.414320f, 1.545309f, +0.064015f, 0.275900f, 0.002838f, 0.392817f, 0.069700f, 0.582893f, 0.205335f, 0.460974f, 0.051214f, 0.363631f, 0.104895f, 0.627832f, 0.215843f, 1.873014f, 0.549373f, 1.343852f, +0.175390f, 0.588478f, 0.005217f, 0.895061f, 0.300130f, 1.953969f, 0.593144f, 1.650779f, 0.245430f, 1.356603f, 0.337221f, 2.502177f, 0.563734f, 3.808305f, 0.962560f, 2.918944f, +0.268814f, 0.688538f, 0.008042f, 1.067205f, 0.288531f, 1.434010f, 0.573499f, 1.234584f, 0.006859f, 0.028944f, 0.009479f, 0.054403f, 0.666770f, 3.438624f, 1.145034f, 2.685814f, +0.348222f, 1.060511f, 0.008532f, 1.510154f, 0.529425f, 3.128579f, 0.861900f, 2.474581f, 0.336416f, 1.687858f, 0.380772f, 2.914637f, 1.005123f, 6.163265f, 1.413756f, 4.422707f, +0.247141f, 0.883718f, 0.011217f, 1.302068f, 0.371560f, 2.577997f, 1.120475f, 2.109846f, 0.177978f, 1.048421f, 0.373143f, 1.873260f, 0.932611f, 6.714328f, 2.429829f, 4.985328f, +0.314351f, 0.875064f, 0.009571f, 1.377347f, 0.742763f, 4.011981f, 1.502615f, 3.507605f, 0.395958f, 1.815828f, 0.556907f, 3.465935f, 1.130794f, 6.337835f, 1.976438f, 5.027077f, +0.055903f, 0.147414f, 0.001776f, 0.349092f, 0.069081f, 0.353459f, 0.145838f, 0.464931f, 0.001011f, 0.004391f, 0.001483f, 0.012609f, 0.112764f, 0.598692f, 0.205678f, 0.714458f, +0.059829f, 0.187583f, 0.001557f, 0.408114f, 0.104722f, 0.637092f, 0.181077f, 0.769907f, 0.040953f, 0.211527f, 0.049232f, 0.558080f, 0.140438f, 0.886540f, 0.209803f, 0.971980f, +0.002267f, 0.008346f, 0.000109f, 0.018788f, 0.003924f, 0.028030f, 0.012569f, 0.035048f, 0.001157f, 0.007015f, 0.002576f, 0.019151f, 0.006957f, 0.051567f, 0.019253f, 0.058498f, +0.079074f, 0.226610f, 0.002557f, 0.544960f, 0.215101f, 1.196120f, 0.462183f, 1.597747f, 0.070570f, 0.333170f, 0.105420f, 0.971612f, 0.231318f, 1.334717f, 0.429420f, 1.617503f, +0.098223f, 0.249969f, 0.003108f, 0.487745f, 0.150288f, 0.742136f, 0.315959f, 0.804336f, 0.002550f, 0.010691f, 0.003727f, 0.025298f, 0.257178f, 1.317779f, 0.467137f, 1.295745f, +0.131990f, 0.399392f, 0.003421f, 0.715964f, 0.286063f, 1.679594f, 0.492585f, 1.672416f, 0.129741f, 0.646749f, 0.155322f, 1.405951f, 0.402164f, 2.450162f, 0.598309f, 2.213388f, +0.059233f, 0.210441f, 0.002844f, 0.390333f, 0.126946f, 0.875127f, 0.404910f, 0.901624f, 0.043401f, 0.254020f, 0.096244f, 0.571367f, 0.235948f, 1.687789f, 0.650217f, 1.577593f, +0.167250f, 0.462584f, 0.005386f, 0.916600f, 0.563345f, 3.023307f, 1.205419f, 3.327512f, 0.214346f, 0.976654f, 0.318872f, 2.346779f, 0.635088f, 3.536640f, 1.174087f, 3.531434f, +0.045096f, 0.126257f, 0.001255f, 0.279497f, 0.046968f, 0.255152f, 0.086814f, 0.313740f, 0.001280f, 0.005902f, 0.001644f, 0.015844f, 0.106875f, 0.602452f, 0.170674f, 0.672072f, +0.062644f, 0.208535f, 0.001427f, 0.424118f, 0.092417f, 0.596939f, 0.139911f, 0.674352f, 0.067298f, 0.369063f, 0.070834f, 0.910229f, 0.172765f, 1.157936f, 0.225974f, 1.186763f, +0.030036f, 0.117396f, 0.001268f, 0.247045f, 0.043818f, 0.332309f, 0.122878f, 0.388431f, 0.024053f, 0.154874f, 0.046895f, 0.395223f, 0.108297f, 0.852224f, 0.262384f, 0.903748f, +0.104862f, 0.319067f, 0.002969f, 0.717278f, 0.240422f, 1.419450f, 0.452293f, 1.772451f, 0.146877f, 0.736236f, 0.192104f, 2.007083f, 0.360411f, 2.207968f, 0.585795f, 2.501323f, +0.177158f, 0.411504f, 0.005045f, 0.942708f, 0.254773f, 1.148284f, 0.482044f, 1.461171f, 0.004525f, 0.017315f, 0.005952f, 0.048103f, 0.469889f, 2.197559f, 0.768125f, 2.536968f, +0.249198f, 0.688241f, 0.005812f, 1.448538f, 0.507627f, 2.720343f, 0.786667f, 3.180249f, 0.240979f, 1.096413f, 0.259634f, 2.798374f, 0.769162f, 4.277067f, 1.029833f, 4.536348f, +0.154875f, 0.502211f, 0.006691f, 1.093677f, 0.311972f, 1.962934f, 0.895535f, 2.374418f, 0.111639f, 0.596377f, 0.222801f, 1.574948f, 0.624951f, 4.080229f, 1.549940f, 4.477739f, +0.251015f, 0.633667f, 0.007275f, 1.474169f, 0.794668f, 3.892519f, 1.530301f, 5.029972f, 0.316480f, 1.316159f, 0.423715f, 3.713104f, 0.965556f, 4.907626f, 1.606464f, 5.753460f, +0.142540f, 0.222013f, 0.003331f, 0.537393f, 0.147898f, 0.446976f, 0.229610f, 0.600962f, 0.002592f, 0.006650f, 0.002798f, 0.019521f, 0.212007f, 0.664847f, 0.284368f, 0.810974f, +0.156299f, 0.289453f, 0.002991f, 0.643693f, 0.229713f, 0.825454f, 0.292098f, 1.019627f, 0.107600f, 0.328272f, 0.095124f, 0.885271f, 0.270524f, 1.008699f, 0.297201f, 1.130401f, +0.005779f, 0.012566f, 0.000205f, 0.028913f, 0.008399f, 0.035435f, 0.019782f, 0.045289f, 0.002966f, 0.010623f, 0.004856f, 0.029641f, 0.013077f, 0.057248f, 0.026611f, 0.066381f, +0.213695f, 0.361729f, 0.005082f, 0.889162f, 0.488104f, 1.603190f, 0.771257f, 2.188924f, 0.191807f, 0.534876f, 0.210711f, 1.594384f, 0.460947f, 1.570984f, 0.629274f, 1.945988f, +0.234609f, 0.352664f, 0.005459f, 0.703363f, 0.301414f, 0.879152f, 0.466001f, 0.973936f, 0.006126f, 0.015170f, 0.006585f, 0.036691f, 0.452947f, 1.370869f, 0.605023f, 1.377797f, +0.323013f, 0.577323f, 0.006156f, 1.057848f, 0.587824f, 2.038589f, 0.744358f, 2.074828f, 0.319330f, 0.940241f, 0.281132f, 2.089226f, 0.725707f, 2.611516f, 0.793960f, 2.411393f, +0.141438f, 0.296807f, 0.004993f, 0.562720f, 0.254524f, 1.036386f, 0.597012f, 1.091410f, 0.104228f, 0.360326f, 0.169972f, 0.828430f, 0.415431f, 1.755258f, 0.841892f, 1.676989f, +0.423414f, 0.691719f, 0.010028f, 1.400978f, 1.197509f, 3.796009f, 1.884336f, 4.270484f, 0.545756f, 1.468803f, 0.597055f, 3.607508f, 1.185527f, 3.899498f, 1.611734f, 3.979983f, +0.112246f, 0.185620f, 0.002296f, 0.420010f, 0.098161f, 0.314974f, 0.133426f, 0.395875f, 0.003203f, 0.008727f, 0.003027f, 0.023945f, 0.196148f, 0.653087f, 0.230351f, 0.744693f, +0.159756f, 0.314118f, 0.002677f, 0.653001f, 0.197893f, 0.755007f, 0.220316f, 0.871807f, 0.172608f, 0.559111f, 0.133602f, 1.409489f, 0.324869f, 1.286109f, 0.312484f, 1.347318f, +0.074739f, 0.172542f, 0.002320f, 0.371132f, 0.091550f, 0.410099f, 0.188797f, 0.489972f, 0.060194f, 0.228929f, 0.086303f, 0.597142f, 0.198698f, 0.923574f, 0.354023f, 1.001101f, +0.276639f, 0.497183f, 0.005760f, 1.142443f, 0.532568f, 1.857208f, 0.736776f, 2.370431f, 0.389702f, 1.153812f, 0.374826f, 3.215110f, 0.701086f, 2.536916f, 0.837981f, 2.937619f, +0.321283f, 0.440799f, 0.006728f, 1.032181f, 0.387958f, 1.032813f, 0.539802f, 1.343339f, 0.008253f, 0.018654f, 0.007984f, 0.052970f, 0.628347f, 1.735744f, 0.755356f, 2.048200f, +0.463037f, 0.755356f, 0.007942f, 1.625000f, 0.791992f, 2.506922f, 0.902575f, 2.995648f, 0.450332f, 1.210233f, 0.356805f, 3.157279f, 1.053822f, 3.461273f, 1.037604f, 3.752396f, +0.280786f, 0.537802f, 0.008921f, 1.197120f, 0.474917f, 1.765012f, 1.002536f, 2.182286f, 0.203561f, 0.642304f, 0.298753f, 1.733797f, 0.835450f, 3.221805f, 1.523718f, 3.613981f, +0.482492f, 0.719436f, 0.010284f, 1.710767f, 1.282573f, 3.710801f, 1.816305f, 4.901341f, 0.611816f, 1.502875f, 0.602370f, 4.333752f, 1.368506f, 4.108479f, 1.674386f, 4.923241f, +0.051370f, 0.079146f, 0.001334f, 0.211948f, 0.057246f, 0.171137f, 0.098801f, 0.254563f, 0.000842f, 0.002137f, 0.001010f, 0.006941f, 0.152338f, 0.472559f, 0.227157f, 0.637719f, +0.088653f, 0.162402f, 0.001886f, 0.399558f, 0.139938f, 0.497414f, 0.197817f, 0.679758f, 0.055020f, 0.166043f, 0.054074f, 0.495394f, 0.305936f, 1.128395f, 0.373646f, 1.399008f, +0.002172f, 0.004671f, 0.000086f, 0.011890f, 0.003390f, 0.014146f, 0.008876f, 0.020003f, 0.001005f, 0.003560f, 0.001829f, 0.010989f, 0.009797f, 0.042427f, 0.022164f, 0.054427f, +0.097919f, 0.163957f, 0.002589f, 0.445876f, 0.240212f, 0.780443f, 0.421955f, 1.178895f, 0.079233f, 0.218560f, 0.096764f, 0.720773f, 0.421121f, 1.419722f, 0.639119f, 1.945627f, +0.048214f, 0.071691f, 0.001247f, 0.158188f, 0.066528f, 0.191947f, 0.114344f, 0.235253f, 0.001135f, 0.002780f, 0.001356f, 0.007439f, 0.185594f, 0.555632f, 0.275597f, 0.617824f, +0.104476f, 0.184710f, 0.002214f, 0.374440f, 0.204199f, 0.700505f, 0.287458f, 0.788773f, 0.093112f, 0.271195f, 0.091131f, 0.666678f, 0.467997f, 1.665902f, 0.569201f, 1.701816f, +0.030307f, 0.062911f, 0.001189f, 0.131957f, 0.058576f, 0.235931f, 0.152742f, 0.274877f, 0.020134f, 0.068852f, 0.036502f, 0.175133f, 0.177485f, 0.741787f, 0.399857f, 0.784072f, +0.110635f, 0.178786f, 0.002913f, 0.400610f, 0.336060f, 1.053758f, 0.587871f, 1.311531f, 0.128558f, 0.342246f, 0.156350f, 0.929972f, 0.617625f, 2.009541f, 0.933452f, 2.269120f, +0.005320f, 0.008703f, 0.000121f, 0.021786f, 0.004997f, 0.015860f, 0.007551f, 0.022054f, 0.000137f, 0.000369f, 0.000144f, 0.001120f, 0.018536f, 0.061050f, 0.024200f, 0.077016f, +0.011917f, 0.023179f, 0.000222f, 0.053308f, 0.015855f, 0.059835f, 0.019623f, 0.076438f, 0.011608f, 0.037193f, 0.009988f, 0.103732f, 0.048318f, 0.189215f, 0.051667f, 0.219299f, +0.003694f, 0.008435f, 0.000127f, 0.020072f, 0.004859f, 0.021531f, 0.011140f, 0.028461f, 0.002682f, 0.010089f, 0.004274f, 0.029115f, 0.019578f, 0.090019f, 0.038779f, 0.107951f, +0.016671f, 0.029637f, 0.000386f, 0.075344f, 0.034470f, 0.118904f, 0.053013f, 0.167900f, 0.021172f, 0.062006f, 0.022638f, 0.191153f, 0.084238f, 0.301520f, 0.111932f, 0.386273f, +0.090127f, 0.122316f, 0.002098f, 0.316875f, 0.116886f, 0.307805f, 0.180800f, 0.442923f, 0.002087f, 0.004666f, 0.002245f, 0.014660f, 0.351442f, 0.960317f, 0.469668f, 1.253688f, +0.204432f, 0.329883f, 0.003898f, 0.785145f, 0.375548f, 1.175873f, 0.475788f, 1.554527f, 0.179241f, 0.476486f, 0.157878f, 1.375250f, 0.927655f, 3.013910f, 1.015399f, 3.614856f, +0.082128f, 0.155601f, 0.002901f, 0.383191f, 0.149191f, 0.548465f, 0.350115f, 0.750240f, 0.053676f, 0.167534f, 0.087576f, 0.500320f, 0.487215f, 1.858553f, 0.987850f, 2.306479f, +0.172090f, 0.253824f, 0.004078f, 0.667758f, 0.491313f, 1.406109f, 0.773482f, 2.054727f, 0.196724f, 0.478008f, 0.215321f, 1.524981f, 0.973190f, 2.890061f, 1.323708f, 3.831467f, +0.081725f, 0.237638f, 0.002728f, 0.380746f, 0.071507f, 0.403453f, 0.158587f, 0.359054f, 0.001108f, 0.005306f, 0.001708f, 0.010309f, 0.180165f, 1.054789f, 0.345218f, 0.851639f, +0.145702f, 0.503747f, 0.003983f, 0.741510f, 0.180579f, 1.211426f, 0.328020f, 0.990489f, 0.074764f, 0.425830f, 0.094419f, 0.760121f, 0.373786f, 2.601962f, 0.586621f, 1.930086f, +0.004315f, 0.017515f, 0.000219f, 0.026676f, 0.005288f, 0.041651f, 0.017793f, 0.035237f, 0.001650f, 0.011037f, 0.003861f, 0.020384f, 0.014471f, 0.118274f, 0.042069f, 0.090778f, +0.141032f, 0.445686f, 0.004791f, 0.725155f, 0.271647f, 1.665712f, 0.613171f, 1.505394f, 0.094353f, 0.491208f, 0.148070f, 0.969192f, 0.450898f, 2.868945f, 0.879342f, 2.352314f, +0.101191f, 0.283975f, 0.003364f, 0.374889f, 0.109630f, 0.596970f, 0.242127f, 0.437748f, 0.001969f, 0.009105f, 0.003024f, 0.014576f, 0.289567f, 1.636138f, 0.552540f, 1.088463f, +0.226522f, 0.755846f, 0.006167f, 0.916731f, 0.347623f, 2.250680f, 0.628831f, 1.516250f, 0.166916f, 0.917531f, 0.209923f, 1.349497f, 0.754324f, 5.067717f, 1.178924f, 3.097364f, +0.079442f, 0.311230f, 0.004006f, 0.390574f, 0.120554f, 0.916428f, 0.403950f, 0.638807f, 0.043635f, 0.281624f, 0.101653f, 0.428583f, 0.345851f, 2.728057f, 1.001236f, 1.725231f, +0.210217f, 0.641143f, 0.007112f, 0.859530f, 0.501362f, 2.967034f, 1.126993f, 2.209413f, 0.201961f, 1.014744f, 0.315627f, 1.649699f, 0.872407f, 5.357218f, 1.694305f, 3.619233f, +0.069702f, 0.215191f, 0.002037f, 0.322302f, 0.051402f, 0.307924f, 0.099811f, 0.256172f, 0.001483f, 0.007541f, 0.002002f, 0.013696f, 0.180537f, 1.122211f, 0.302874f, 0.847004f, +0.161298f, 0.592089f, 0.003861f, 0.814728f, 0.168489f, 1.200092f, 0.267965f, 0.917252f, 0.129897f, 0.785525f, 0.143629f, 1.310774f, 0.486167f, 3.593166f, 0.668028f, 2.491575f, +0.060438f, 0.260484f, 0.002680f, 0.370868f, 0.062430f, 0.522090f, 0.183916f, 0.412889f, 0.036281f, 0.257605f, 0.074310f, 0.444771f, 0.238156f, 2.066636f, 0.606165f, 1.482773f, +0.197741f, 0.663470f, 0.005882f, 1.009122f, 0.321016f, 2.089949f, 0.634422f, 1.765659f, 0.207626f, 1.147645f, 0.285279f, 2.116766f, 0.742778f, 5.017836f, 1.268272f, 3.846011f, +0.144018f, 0.368888f, 0.004308f, 0.571761f, 0.146651f, 0.728863f, 0.291492f, 0.627501f, 0.002758f, 0.011636f, 0.003811f, 0.021870f, 0.417481f, 2.153005f, 0.716934f, 1.681653f, +0.337476f, 1.027783f, 0.008269f, 1.463550f, 0.486763f, 2.876474f, 0.792447f, 2.275176f, 0.244640f, 1.227400f, 0.276895f, 2.119506f, 1.138412f, 6.980571f, 1.601233f, 5.009199f, +0.163906f, 0.586090f, 0.007439f, 0.863544f, 0.233780f, 1.622035f, 0.704985f, 1.327482f, 0.088569f, 0.521736f, 0.185691f, 0.932208f, 0.722845f, 5.204118f, 1.883303f, 3.864011f, +0.248959f, 0.693031f, 0.007580f, 1.090827f, 0.558072f, 3.014382f, 1.128982f, 2.635422f, 0.235302f, 1.079074f, 0.330948f, 2.059666f, 1.046622f, 5.866068f, 1.829319f, 4.652879f, +0.008856f, 0.023354f, 0.000281f, 0.055305f, 0.010383f, 0.053124f, 0.021919f, 0.069878f, 0.000120f, 0.000522f, 0.000176f, 0.001499f, 0.020878f, 0.110846f, 0.038081f, 0.132280f, +0.017146f, 0.053757f, 0.000446f, 0.116957f, 0.028471f, 0.173210f, 0.049230f, 0.209319f, 0.008806f, 0.045486f, 0.010587f, 0.120006f, 0.047035f, 0.296917f, 0.070267f, 0.325532f, +0.000445f, 0.001637f, 0.000021f, 0.003685f, 0.000730f, 0.005215f, 0.002338f, 0.006521f, 0.000170f, 0.001032f, 0.000379f, 0.002818f, 0.001595f, 0.011819f, 0.004413f, 0.013407f, +0.018518f, 0.053070f, 0.000599f, 0.127624f, 0.047790f, 0.265748f, 0.102686f, 0.354980f, 0.012401f, 0.058546f, 0.018525f, 0.170736f, 0.063310f, 0.365302f, 0.117529f, 0.442698f, +0.012938f, 0.032928f, 0.000409f, 0.064249f, 0.018781f, 0.092743f, 0.039485f, 0.100516f, 0.000252f, 0.001057f, 0.000368f, 0.002500f, 0.039591f, 0.202866f, 0.071913f, 0.199474f, +0.031451f, 0.095168f, 0.000815f, 0.170602f, 0.064667f, 0.379685f, 0.111353f, 0.378062f, 0.023197f, 0.115636f, 0.027771f, 0.251377f, 0.111993f, 0.682308f, 0.166614f, 0.616373f, +0.009659f, 0.034315f, 0.000464f, 0.063649f, 0.019638f, 0.135380f, 0.062639f, 0.139479f, 0.005310f, 0.031081f, 0.011776f, 0.069909f, 0.044964f, 0.321639f, 0.123911f, 0.300639f, +0.032568f, 0.090076f, 0.001049f, 0.178483f, 0.104068f, 0.558505f, 0.222681f, 0.614702f, 0.031318f, 0.142700f, 0.046591f, 0.342890f, 0.144526f, 0.804827f, 0.267185f, 0.803643f, +0.008693f, 0.024338f, 0.000242f, 0.053878f, 0.008589f, 0.046662f, 0.015876f, 0.057376f, 0.000185f, 0.000854f, 0.000238f, 0.002292f, 0.024077f, 0.135721f, 0.038450f, 0.151406f, +0.021844f, 0.072716f, 0.000498f, 0.147890f, 0.030572f, 0.197474f, 0.046284f, 0.223083f, 0.017608f, 0.096564f, 0.018533f, 0.238159f, 0.070405f, 0.471879f, 0.092088f, 0.483627f, +0.007167f, 0.028014f, 0.000303f, 0.058951f, 0.009920f, 0.075229f, 0.027817f, 0.087934f, 0.004307f, 0.027731f, 0.008397f, 0.070766f, 0.030201f, 0.237664f, 0.073173f, 0.252033f, +0.029881f, 0.090920f, 0.000846f, 0.204393f, 0.064995f, 0.383730f, 0.122272f, 0.479159f, 0.031405f, 0.157420f, 0.041075f, 0.429149f, 0.120025f, 0.735301f, 0.195082f, 0.832994f, +0.023989f, 0.055722f, 0.000683f, 0.127653f, 0.032729f, 0.147513f, 0.061925f, 0.187708f, 0.000460f, 0.001759f, 0.000605f, 0.004888f, 0.074361f, 0.347767f, 0.121557f, 0.401479f, +0.061041f, 0.168583f, 0.001424f, 0.354816f, 0.117963f, 0.632156f, 0.182807f, 0.739030f, 0.044291f, 0.201517f, 0.047720f, 0.514332f, 0.220184f, 1.224373f, 0.294805f, 1.298596f, +0.025961f, 0.084183f, 0.001122f, 0.183327f, 0.049611f, 0.312156f, 0.142412f, 0.377592f, 0.014042f, 0.075011f, 0.028023f, 0.198093f, 0.122427f, 0.799313f, 0.303632f, 0.877184f, +0.050246f, 0.126841f, 0.001456f, 0.295085f, 0.150908f, 0.739193f, 0.290606f, 0.955196f, 0.047535f, 0.197684f, 0.063641f, 0.557701f, 0.225877f, 1.148062f, 0.375807f, 1.345931f, +0.127782f, 0.199026f, 0.002986f, 0.481751f, 0.125782f, 0.380139f, 0.195276f, 0.511099f, 0.001743f, 0.004473f, 0.001882f, 0.013131f, 0.222113f, 0.696541f, 0.297924f, 0.849634f, +0.253458f, 0.469385f, 0.004851f, 1.043829f, 0.353398f, 1.269904f, 0.449372f, 1.568625f, 0.130926f, 0.399438f, 0.115746f, 1.077188f, 0.512685f, 1.911640f, 0.563242f, 2.142285f, +0.006413f, 0.013944f, 0.000227f, 0.032086f, 0.008842f, 0.037306f, 0.020827f, 0.047680f, 0.002469f, 0.008845f, 0.004044f, 0.024682f, 0.016959f, 0.074245f, 0.034512f, 0.086090f, +0.283186f, 0.479359f, 0.006735f, 1.178306f, 0.613645f, 2.015529f, 0.969624f, 2.751912f, 0.190724f, 0.531856f, 0.209521f, 1.585381f, 0.713874f, 2.433002f, 0.974564f, 3.013776f, +0.174874f, 0.262870f, 0.004069f, 0.524276f, 0.213143f, 0.621687f, 0.329529f, 0.688712f, 0.003426f, 0.008485f, 0.003683f, 0.020521f, 0.394568f, 1.194181f, 0.527043f, 1.200216f, +0.435532f, 0.778429f, 0.008301f, 1.426341f, 0.751924f, 2.607695f, 0.952158f, 2.654051f, 0.323075f, 0.951268f, 0.284430f, 2.113730f, 1.143550f, 4.115159f, 1.251101f, 3.799810f, +0.130506f, 0.273866f, 0.004607f, 0.519226f, 0.222802f, 0.907221f, 0.522607f, 0.955387f, 0.072163f, 0.249473f, 0.117681f, 0.573567f, 0.447979f, 1.892776f, 0.907851f, 1.808375f, +0.466543f, 0.762177f, 0.011049f, 1.543681f, 1.251792f, 3.968081f, 1.969753f, 4.464063f, 0.451220f, 1.214377f, 0.493633f, 2.982617f, 1.526621f, 5.021444f, 2.075455f, 5.125087f, +0.122437f, 0.202472f, 0.002505f, 0.458143f, 0.101579f, 0.325944f, 0.138073f, 0.409663f, 0.002622f, 0.007143f, 0.002478f, 0.019599f, 0.250046f, 0.832541f, 0.293647f, 0.949318f, +0.315223f, 0.619803f, 0.005282f, 1.288471f, 0.370440f, 1.413313f, 0.412415f, 1.631953f, 0.255556f, 0.827795f, 0.197805f, 2.086826f, 0.749140f, 2.965734f, 0.720579f, 3.106879f, +0.100919f, 0.232980f, 0.003132f, 0.501134f, 0.117276f, 0.525340f, 0.241850f, 0.627659f, 0.060988f, 0.231947f, 0.087441f, 0.605016f, 0.313553f, 1.457440f, 0.558663f, 1.579780f, +0.446068f, 0.801683f, 0.009288f, 1.842133f, 0.814683f, 2.841020f, 1.127065f, 3.626110f, 0.471502f, 1.396001f, 0.453503f, 3.889971f, 1.321149f, 4.780644f, 1.579118f, 5.535743f, +0.246178f, 0.337756f, 0.005155f, 0.790894f, 0.282016f, 0.750777f, 0.392395f, 0.976506f, 0.004745f, 0.010725f, 0.004590f, 0.030455f, 0.562673f, 1.554324f, 0.676407f, 1.834123f, +0.641797f, 1.046969f, 0.011008f, 2.252348f, 1.041430f, 3.296475f, 1.186840f, 3.939125f, 0.468359f, 1.258679f, 0.371088f, 3.283665f, 1.707037f, 5.606756f, 1.680767f, 6.078332f, +0.266331f, 0.510116f, 0.008462f, 1.135492f, 0.427357f, 1.588259f, 0.902139f, 1.963745f, 0.144879f, 0.457142f, 0.212629f, 1.233982f, 0.926106f, 3.571408f, 1.689060f, 4.006140f, +0.546510f, 0.814892f, 0.011648f, 1.937755f, 1.378216f, 3.987519f, 1.951749f, 5.266839f, 0.519987f, 1.277306f, 0.511959f, 3.683292f, 1.811542f, 5.438547f, 2.216448f, 6.517078f, +0.065496f, 0.100910f, 0.001701f, 0.270230f, 0.082747f, 0.247371f, 0.142812f, 0.367959f, 0.001334f, 0.003385f, 0.001600f, 0.010992f, 0.225013f, 0.697999f, 0.335525f, 0.941950f, +0.106026f, 0.194227f, 0.002256f, 0.477858f, 0.189738f, 0.674427f, 0.268214f, 0.921661f, 0.081733f, 0.246658f, 0.080327f, 0.735912f, 0.423879f, 1.563407f, 0.517692f, 1.938345f, +0.002180f, 0.004688f, 0.000086f, 0.011934f, 0.003857f, 0.016097f, 0.010100f, 0.022762f, 0.001252f, 0.004438f, 0.002280f, 0.013700f, 0.011392f, 0.049334f, 0.025773f, 0.063288f, +0.108376f, 0.181466f, 0.002865f, 0.493493f, 0.301411f, 0.979280f, 0.529458f, 1.479246f, 0.108926f, 0.300465f, 0.133027f, 0.990882f, 0.539965f, 1.820380f, 0.819483f, 2.494700f, +0.076562f, 0.113843f, 0.001981f, 0.251196f, 0.119769f, 0.345557f, 0.205851f, 0.423520f, 0.002239f, 0.005484f, 0.002675f, 0.014673f, 0.341425f, 1.022161f, 0.506998f, 1.136571f, +0.155621f, 0.275133f, 0.003297f, 0.557743f, 0.344830f, 1.182939f, 0.485428f, 1.331996f, 0.172273f, 0.501754f, 0.168606f, 1.233461f, 0.807583f, 2.874709f, 0.982223f, 2.936684f, +0.037887f, 0.078646f, 0.001487f, 0.164961f, 0.083017f, 0.334375f, 0.216474f, 0.389572f, 0.031264f, 0.106912f, 0.056678f, 0.271941f, 0.257042f, 1.074289f, 0.579091f, 1.135529f, +0.152508f, 0.246452f, 0.004015f, 0.552232f, 0.525190f, 1.646796f, 0.918716f, 2.049640f, 0.220118f, 0.585997f, 0.267705f, 1.592308f, 0.986318f, 3.209146f, 1.490680f, 3.623682f, +0.007560f, 0.012367f, 0.000172f, 0.030960f, 0.008051f, 0.025553f, 0.012165f, 0.035531f, 0.000242f, 0.000651f, 0.000254f, 0.001976f, 0.030517f, 0.100508f, 0.039841f, 0.126793f, +0.015886f, 0.030898f, 0.000296f, 0.071061f, 0.023961f, 0.090426f, 0.029655f, 0.115518f, 0.019220f, 0.061583f, 0.016538f, 0.171755f, 0.074618f, 0.292204f, 0.079790f, 0.338662f, +0.004132f, 0.009436f, 0.000143f, 0.022456f, 0.006163f, 0.027309f, 0.014129f, 0.036098f, 0.003727f, 0.014020f, 0.005940f, 0.040458f, 0.025375f, 0.116670f, 0.050261f, 0.139911f, +0.020566f, 0.036562f, 0.000476f, 0.092946f, 0.048208f, 0.166296f, 0.074142f, 0.234820f, 0.032441f, 0.095011f, 0.034688f, 0.292903f, 0.120388f, 0.430918f, 0.159968f, 0.552042f, +0.121320f, 0.164649f, 0.002824f, 0.426543f, 0.178377f, 0.469733f, 0.275914f, 0.675932f, 0.003490f, 0.007802f, 0.003753f, 0.024511f, 0.548052f, 1.497556f, 0.732419f, 1.955049f, +0.258129f, 0.416532f, 0.004922f, 0.991375f, 0.537592f, 1.683245f, 0.681083f, 2.225283f, 0.281114f, 0.747300f, 0.247609f, 2.156884f, 1.356960f, 4.408703f, 1.485310f, 5.287758f, +0.087031f, 0.164891f, 0.003074f, 0.406070f, 0.179237f, 0.658921f, 0.420625f, 0.901332f, 0.070652f, 0.220519f, 0.115273f, 0.658553f, 0.598135f, 2.281671f, 1.212743f, 2.831572f, +0.201090f, 0.296598f, 0.004765f, 0.780288f, 0.650868f, 1.862747f, 1.024673f, 2.722006f, 0.285529f, 0.693790f, 0.312521f, 2.213388f, 1.317426f, 3.912331f, 1.791928f, 5.186730f, +0.171525f, 0.498758f, 0.005725f, 0.799113f, 0.170145f, 0.959987f, 0.377345f, 0.854343f, 0.002888f, 0.013832f, 0.004452f, 0.026875f, 0.438063f, 2.564671f, 0.839380f, 2.070720f, +0.286848f, 0.991741f, 0.007842f, 1.459831f, 0.403044f, 2.703844f, 0.732124f, 2.210724f, 0.182824f, 1.041307f, 0.230888f, 1.858769f, 0.852513f, 5.934431f, 1.337937f, 4.402048f, +0.007129f, 0.028940f, 0.000361f, 0.044077f, 0.009905f, 0.078021f, 0.033329f, 0.066005f, 0.003387f, 0.022650f, 0.007923f, 0.041835f, 0.027700f, 0.226395f, 0.080525f, 0.173762f, +0.256951f, 0.812012f, 0.008729f, 1.321187f, 0.561097f, 3.440588f, 1.266528f, 3.109445f, 0.213523f, 1.111621f, 0.335087f, 2.193314f, 0.951710f, 6.055478f, 1.856025f, 4.965025f, +0.264513f, 0.742313f, 0.008793f, 0.979963f, 0.324890f, 1.769126f, 0.717545f, 1.297269f, 0.006395f, 0.029563f, 0.009819f, 0.047327f, 0.876896f, 4.954725f, 1.673260f, 3.296199f, +0.555432f, 1.853330f, 0.015122f, 2.247819f, 0.966333f, 6.256512f, 1.748044f, 4.214921f, 0.508364f, 2.794457f, 0.639347f, 4.110062f, 2.142742f, 14.395420f, 3.348867f, 8.798411f, +0.163480f, 0.640469f, 0.008245f, 0.803749f, 0.281254f, 2.138033f, 0.942419f, 1.490340f, 0.111535f, 0.719853f, 0.259832f, 1.095491f, 0.824514f, 6.503736f, 2.386965f, 4.112981f, +0.477018f, 1.454864f, 0.016139f, 1.950421f, 1.289786f, 7.632889f, 2.899264f, 5.683860f, 0.569237f, 2.860098f, 0.889609f, 4.649746f, 2.293396f, 14.083130f, 4.454013f, 9.514291f, +0.163057f, 0.503403f, 0.004765f, 0.753973f, 0.136325f, 0.816648f, 0.264709f, 0.679396f, 0.004308f, 0.021911f, 0.005816f, 0.039796f, 0.489273f, 3.041305f, 0.820819f, 2.295465f, +0.353942f, 1.299248f, 0.008472f, 1.787794f, 0.419156f, 2.985512f, 0.666626f, 2.281880f, 0.354048f, 2.141027f, 0.391476f, 3.572646f, 1.235899f, 9.134291f, 1.698212f, 6.333906f, +0.111305f, 0.479715f, 0.004935f, 0.683003f, 0.130345f, 1.090051f, 0.383990f, 0.862054f, 0.082994f, 0.589270f, 0.169984f, 1.017411f, 0.508109f, 4.409193f, 1.293260f, 3.163514f, +0.401558f, 1.347330f, 0.011944f, 2.049259f, 0.739059f, 4.811579f, 1.460596f, 4.064985f, 0.523712f, 2.894796f, 0.719581f, 5.339285f, 1.747448f, 11.804890f, 2.983719f, 9.048072f, +0.319125f, 0.817405f, 0.009547f, 1.266945f, 0.368407f, 1.830998f, 0.732265f, 1.576364f, 0.007590f, 0.032025f, 0.010488f, 0.060195f, 1.071697f, 5.526889f, 1.840410f, 4.316900f, +0.701452f, 2.136273f, 0.017187f, 3.042026f, 1.147023f, 6.778208f, 1.867347f, 5.361292f, 0.631596f, 3.168830f, 0.714872f, 5.472015f, 2.741242f, 16.808890f, 3.855693f, 12.061910f, +0.285922f, 1.022392f, 0.012977f, 1.506390f, 0.462338f, 3.207837f, 1.394222f, 2.625310f, 0.191907f, 1.130475f, 0.402346f, 2.019868f, 1.460800f, 10.517020f, 3.805973f, 7.808792f, +0.478885f, 1.333079f, 0.014581f, 2.098260f, 1.217005f, 6.573562f, 2.462009f, 5.747151f, 0.562194f, 2.578171f, 0.790715f, 4.921046f, 2.332307f, 13.072030f, 4.076480f, 10.368540f, +0.068008f, 0.179333f, 0.002161f, 0.424679f, 0.090386f, 0.462472f, 0.190817f, 0.608325f, 0.001146f, 0.004978f, 0.001682f, 0.014296f, 0.185729f, 0.986077f, 0.338762f, 1.176748f, +0.123499f, 0.387210f, 0.003214f, 0.842431f, 0.232496f, 1.414429f, 0.402014f, 1.709295f, 0.078788f, 0.406949f, 0.094715f, 1.073668f, 0.392485f, 2.477635f, 0.586342f, 2.716415f, +0.002688f, 0.009894f, 0.000130f, 0.022274f, 0.005004f, 0.035740f, 0.016026f, 0.044690f, 0.001278f, 0.007751f, 0.002846f, 0.021161f, 0.011167f, 0.082770f, 0.030903f, 0.093895f, +0.123441f, 0.353758f, 0.003992f, 0.850729f, 0.361157f, 2.008296f, 0.776009f, 2.682631f, 0.102675f, 0.484745f, 0.153381f, 1.413646f, 0.488902f, 2.820993f, 0.907601f, 3.418677f, +0.123741f, 0.314913f, 0.003915f, 0.614463f, 0.203636f, 1.005572f, 0.428115f, 1.089852f, 0.002994f, 0.012553f, 0.004377f, 0.029704f, 0.438657f, 2.247671f, 0.796771f, 2.210088f, +0.282148f, 0.853759f, 0.007312f, 1.530478f, 0.657694f, 3.861588f, 1.132513f, 3.845086f, 0.258484f, 1.288525f, 0.309449f, 2.801089f, 1.163927f, 7.091150f, 1.731599f, 6.405891f, +0.072721f, 0.258361f, 0.003491f, 0.479218f, 0.167627f, 1.155567f, 0.534665f, 1.190554f, 0.049661f, 0.290661f, 0.110127f, 0.653784f, 0.392194f, 2.805447f, 1.080793f, 2.622279f, +0.270381f, 0.747826f, 0.008708f, 1.481800f, 0.979513f, 5.256758f, 2.095916f, 5.785693f, 0.322959f, 1.471539f, 0.480449f, 3.535925f, 1.390049f, 7.740819f, 2.569782f, 7.729423f, +0.074403f, 0.208307f, 0.002070f, 0.461134f, 0.083345f, 0.452767f, 0.154052f, 0.556732f, 0.001968f, 0.009075f, 0.002529f, 0.024363f, 0.238733f, 1.345731f, 0.381244f, 1.501246f, +0.175373f, 0.583794f, 0.003996f, 1.187322f, 0.278265f, 1.797371f, 0.421268f, 2.030461f, 0.175593f, 0.962948f, 0.184817f, 2.374946f, 0.654823f, 4.388866f, 0.856499f, 4.498131f, +0.048294f, 0.188755f, 0.002038f, 0.397210f, 0.075774f, 0.574662f, 0.212492f, 0.671712f, 0.036044f, 0.232082f, 0.070274f, 0.592252f, 0.235746f, 1.855169f, 0.571173f, 1.967329f, +0.222012f, 0.675518f, 0.006286f, 1.518599f, 0.547465f, 3.232227f, 1.029915f, 4.036046f, 0.289822f, 1.452760f, 0.379064f, 3.960428f, 1.033096f, 6.328996f, 1.679144f, 7.169880f, +0.194484f, 0.451747f, 0.005538f, 1.034901f, 0.300816f, 1.355804f, 0.569160f, 1.725236f, 0.004630f, 0.017716f, 0.006090f, 0.049217f, 0.698398f, 3.266243f, 1.141667f, 3.770707f, +0.464193f, 1.282018f, 0.010827f, 2.698257f, 1.017007f, 5.450084f, 1.576052f, 6.371486f, 0.418363f, 1.903483f, 0.450750f, 4.858256f, 1.939803f, 10.786630f, 2.597207f, 11.440530f, +0.165690f, 0.537281f, 0.007159f, 1.170050f, 0.358970f, 2.258642f, 1.030444f, 2.732114f, 0.111314f, 0.594645f, 0.222154f, 1.570374f, 0.905207f, 5.909986f, 2.245002f, 6.485756f, +0.353612f, 0.892665f, 0.010249f, 2.076706f, 1.204036f, 5.897723f, 2.318625f, 7.621128f, 0.415523f, 1.728053f, 0.556317f, 4.875126f, 1.841584f, 9.360204f, 3.063972f, 10.973440f, +0.228469f, 0.355850f, 0.005338f, 0.861353f, 0.254962f, 0.770548f, 0.395827f, 1.036006f, 0.003872f, 0.009935f, 0.004179f, 0.029162f, 0.460071f, 1.442771f, 0.617102f, 1.759878f, +0.425086f, 0.787227f, 0.008135f, 1.750652f, 0.671945f, 2.414572f, 0.854429f, 2.982555f, 0.272743f, 0.832102f, 0.241119f, 2.243980f, 0.996125f, 3.714232f, 1.094355f, 4.162365f, +0.009027f, 0.019628f, 0.000320f, 0.045163f, 0.014110f, 0.059531f, 0.033234f, 0.076086f, 0.004317f, 0.015465f, 0.007070f, 0.043152f, 0.027654f, 0.121068f, 0.056276f, 0.140382f, +0.439532f, 0.744011f, 0.010453f, 1.828843f, 1.079777f, 3.546552f, 1.706164f, 4.842304f, 0.367689f, 1.025344f, 0.403928f, 3.056394f, 1.283608f, 4.374752f, 1.752352f, 5.419034f, +0.389419f, 0.585374f, 0.009062f, 1.167486f, 0.538099f, 1.569504f, 0.831927f, 1.738717f, 0.009477f, 0.023469f, 0.010187f, 0.056761f, 1.017902f, 3.080736f, 1.359661f, 3.096305f, +0.909755f, 1.626011f, 0.017339f, 2.979391f, 1.780645f, 6.175327f, 2.254823f, 6.285104f, 0.838234f, 2.468109f, 0.737966f, 5.484169f, 2.767272f, 9.958257f, 3.027535f, 9.195146f, +0.228787f, 0.480110f, 0.008077f, 0.910245f, 0.442814f, 1.803075f, 1.038666f, 1.898804f, 0.157135f, 0.543229f, 0.256250f, 1.248944f, 0.909812f, 3.844090f, 1.843780f, 3.672677f, +0.901869f, 1.473358f, 0.021359f, 2.984075f, 2.743363f, 8.696243f, 4.316809f, 9.783213f, 1.083423f, 2.915835f, 1.185260f, 7.161545f, 3.418819f, 11.245360f, 4.647912f, 11.477460f, +0.244000f, 0.403500f, 0.004992f, 0.913016f, 0.229500f, 0.736410f, 0.311951f, 0.925556f, 0.006490f, 0.017680f, 0.006133f, 0.048513f, 0.577284f, 1.922098f, 0.677946f, 2.191703f, +0.589260f, 1.158626f, 0.009874f, 2.408598f, 0.785068f, 2.995209f, 0.874024f, 3.458570f, 0.593380f, 1.922073f, 0.459288f, 4.845439f, 1.622354f, 6.422654f, 1.560501f, 6.728320f, +0.158329f, 0.365516f, 0.004914f, 0.786215f, 0.208591f, 0.934387f, 0.430162f, 1.116375f, 0.118847f, 0.451995f, 0.170396f, 1.178993f, 0.569890f, 2.648930f, 1.015382f, 2.871286f, +0.771682f, 1.386885f, 0.016068f, 3.186829f, 1.597811f, 5.572000f, 2.210477f, 7.111771f, 1.013160f, 2.999720f, 0.974484f, 8.358749f, 2.647781f, 9.581130f, 3.164791f, 11.094460f, +0.464705f, 0.637574f, 0.009732f, 1.492953f, 0.603533f, 1.606712f, 0.839751f, 2.089787f, 0.011126f, 0.025147f, 0.010763f, 0.071407f, 1.230485f, 3.399085f, 1.479205f, 4.010964f, +1.136418f, 1.853848f, 0.019492f, 3.988188f, 2.090592f, 6.617425f, 2.382492f, 7.907496f, 1.030092f, 2.768295f, 0.816158f, 7.221979f, 3.501674f, 11.501230f, 3.447785f, 12.468580f, +0.395786f, 0.758065f, 0.012575f, 1.687414f, 0.719993f, 2.675827f, 1.519883f, 3.308429f, 0.267423f, 0.843812f, 0.392480f, 2.277738f, 1.594376f, 6.148508f, 2.907872f, 6.896939f, +0.895543f, 1.335328f, 0.019088f, 3.175316f, 2.560380f, 7.407813f, 3.625861f, 9.784469f, 1.058371f, 2.599802f, 1.042031f, 7.496895f, 3.438976f, 10.324370f, 4.207636f, 12.371820f, +0.027051f, 0.041678f, 0.000703f, 0.111610f, 0.044949f, 0.134375f, 0.077577f, 0.199880f, 0.000600f, 0.001524f, 0.000720f, 0.004948f, 0.106251f, 0.329596f, 0.158435f, 0.444790f, +0.072011f, 0.131915f, 0.001532f, 0.324550f, 0.169487f, 0.602446f, 0.239588f, 0.823293f, 0.060505f, 0.182594f, 0.059464f, 0.544775f, 0.329141f, 1.213983f, 0.401987f, 1.505122f, +0.001132f, 0.002435f, 0.000045f, 0.006198f, 0.002635f, 0.010995f, 0.006899f, 0.015547f, 0.000709f, 0.002512f, 0.001291f, 0.007755f, 0.006764f, 0.029293f, 0.015303f, 0.037578f, +0.059036f, 0.098851f, 0.001561f, 0.268823f, 0.215946f, 0.701605f, 0.379330f, 1.059806f, 0.064673f, 0.178397f, 0.078983f, 0.588324f, 0.336286f, 1.133719f, 0.510368f, 1.553682f, +0.033782f, 0.050231f, 0.000874f, 0.110836f, 0.069504f, 0.200533f, 0.119459f, 0.245777f, 0.001077f, 0.002637f, 0.001286f, 0.007057f, 0.172235f, 0.515637f, 0.255759f, 0.573352f, +0.112914f, 0.199628f, 0.002392f, 0.404683f, 0.329068f, 1.128867f, 0.463240f, 1.271110f, 0.136240f, 0.396807f, 0.133341f, 0.975471f, 0.669924f, 2.384690f, 0.814794f, 2.436100f, +0.021020f, 0.043634f, 0.000825f, 0.091523f, 0.060578f, 0.243996f, 0.157963f, 0.284274f, 0.018906f, 0.064652f, 0.034275f, 0.164450f, 0.163047f, 0.681442f, 0.367329f, 0.720288f, +0.088752f, 0.143422f, 0.002337f, 0.321370f, 0.401975f, 1.260442f, 0.703177f, 1.568775f, 0.139620f, 0.371695f, 0.169804f, 1.009994f, 0.656233f, 2.135159f, 0.991803f, 2.410965f, +0.003215f, 0.005258f, 0.000073f, 0.013164f, 0.004502f, 0.014289f, 0.006803f, 0.019869f, 0.000112f, 0.000302f, 0.000118f, 0.000916f, 0.014834f, 0.048858f, 0.019367f, 0.061635f, +0.011107f, 0.021603f, 0.000207f, 0.049684f, 0.022033f, 0.083153f, 0.027270f, 0.106227f, 0.014647f, 0.046930f, 0.012603f, 0.130889f, 0.059647f, 0.233577f, 0.063781f, 0.270713f, +0.002209f, 0.005045f, 0.000076f, 0.012006f, 0.004334f, 0.019203f, 0.009935f, 0.025382f, 0.002172f, 0.008170f, 0.003461f, 0.023576f, 0.015510f, 0.071314f, 0.030721f, 0.085520f, +0.011533f, 0.020503f, 0.000267f, 0.052122f, 0.035556f, 0.122650f, 0.054683f, 0.173190f, 0.019829f, 0.058073f, 0.021202f, 0.179028f, 0.077185f, 0.276274f, 0.102560f, 0.353930f, +0.053006f, 0.071937f, 0.001234f, 0.186360f, 0.102501f, 0.269924f, 0.158549f, 0.388412f, 0.001662f, 0.003716f, 0.001787f, 0.011673f, 0.273760f, 0.748050f, 0.365854f, 0.976575f, +0.185456f, 0.299262f, 0.003536f, 0.712265f, 0.507991f, 1.590563f, 0.643582f, 2.102756f, 0.220138f, 0.585203f, 0.193901f, 1.689035f, 1.114624f, 3.621362f, 1.220052f, 4.343428f, +0.047813f, 0.090588f, 0.001689f, 0.223087f, 0.129509f, 0.476109f, 0.303927f, 0.651266f, 0.042306f, 0.132047f, 0.069025f, 0.394342f, 0.375690f, 1.433125f, 0.761728f, 1.778519f, +0.115877f, 0.170913f, 0.002746f, 0.449636f, 0.493287f, 1.411758f, 0.776590f, 2.062982f, 0.179335f, 0.435756f, 0.196288f, 1.390184f, 0.867941f, 2.577505f, 1.180551f, 3.417099f, +0.059203f, 0.172150f, 0.001976f, 0.275819f, 0.077239f, 0.435794f, 0.171299f, 0.387836f, 0.001086f, 0.005204f, 0.001675f, 0.010110f, 0.172866f, 1.012057f, 0.331232f, 0.817137f, +0.162810f, 0.562895f, 0.004451f, 0.828576f, 0.300872f, 2.018416f, 0.546530f, 1.650303f, 0.113102f, 0.644193f, 0.142836f, 1.149908f, 0.553207f, 3.850932f, 0.868205f, 2.856548f, +0.003094f, 0.012560f, 0.000157f, 0.019130f, 0.005654f, 0.044536f, 0.019025f, 0.037677f, 0.001602f, 0.010715f, 0.003748f, 0.019790f, 0.013745f, 0.112337f, 0.039957f, 0.086221f, +0.116972f, 0.369653f, 0.003974f, 0.601446f, 0.335946f, 2.059988f, 0.758310f, 1.861722f, 0.105946f, 0.551566f, 0.166264f, 1.088282f, 0.495329f, 3.151651f, 0.965992f, 2.584111f, +0.097535f, 0.273716f, 0.003242f, 0.361346f, 0.157561f, 0.857970f, 0.347986f, 0.629134f, 0.002570f, 0.011881f, 0.003946f, 0.019021f, 0.369674f, 2.088768f, 0.705398f, 1.389582f, +0.336789f, 1.123775f, 0.009169f, 1.362975f, 0.770643f, 4.989518f, 1.394051f, 3.361365f, 0.335977f, 1.846852f, 0.422544f, 2.716334f, 1.485436f, 9.979487f, 2.321570f, 6.099414f, +0.075799f, 0.296958f, 0.003823f, 0.372664f, 0.171512f, 1.303799f, 0.574699f, 0.908828f, 0.056366f, 0.363788f, 0.131310f, 0.553622f, 0.437071f, 3.447598f, 1.265318f, 2.180271f, +0.231987f, 0.707542f, 0.007849f, 0.948545f, 0.824986f, 4.882228f, 1.854458f, 3.635570f, 0.301738f, 1.516068f, 0.471560f, 2.464716f, 1.275163f, 7.830437f, 2.476500f, 5.290092f, +0.057937f, 0.178869f, 0.001693f, 0.267901f, 0.063708f, 0.381640f, 0.123705f, 0.317498f, 0.001668f, 0.008486f, 0.002252f, 0.015412f, 0.198759f, 1.235480f, 0.333444f, 0.932495f, +0.206807f, 0.759143f, 0.004950f, 1.044598f, 0.322112f, 2.294300f, 0.512288f, 1.753574f, 0.225477f, 1.363522f, 0.249313f, 2.275254f, 0.825604f, 6.101882f, 1.134438f, 4.231171f, +0.049730f, 0.214331f, 0.002205f, 0.305158f, 0.076594f, 0.640542f, 0.225643f, 0.506566f, 0.040416f, 0.286962f, 0.082778f, 0.495457f, 0.259547f, 2.252257f, 0.660609f, 1.615953f, +0.188184f, 0.631406f, 0.005598f, 0.960354f, 0.455526f, 2.965664f, 0.900253f, 2.505493f, 0.267507f, 1.478634f, 0.367555f, 2.727256f, 0.936259f, 6.324903f, 1.598637f, 4.847836f, +0.116519f, 0.298452f, 0.003486f, 0.462588f, 0.176915f, 0.879274f, 0.351645f, 0.756995f, 0.003020f, 0.012745f, 0.004174f, 0.023955f, 0.447369f, 2.307143f, 0.768260f, 1.802046f, +0.421160f, 1.282645f, 0.010320f, 1.826471f, 0.905778f, 5.352594f, 1.474600f, 4.233688f, 0.413330f, 2.073752f, 0.467828f, 3.581008f, 1.881717f, 11.538410f, 2.646729f, 8.279866f, +0.131271f, 0.469394f, 0.005958f, 0.691603f, 0.279176f, 1.937009f, 0.841882f, 1.585258f, 0.096033f, 0.565703f, 0.201339f, 1.010767f, 0.766775f, 5.520387f, 1.997757f, 4.098838f, +0.230613f, 0.641961f, 0.007022f, 1.010443f, 0.770805f, 4.163448f, 1.559344f, 3.640030f, 0.295085f, 1.353233f, 0.415031f, 2.582964f, 1.284091f, 7.197025f, 2.244374f, 5.708574f, +0.017297f, 0.045611f, 0.000550f, 0.108012f, 0.030235f, 0.154702f, 0.063830f, 0.203491f, 0.000318f, 0.001380f, 0.000466f, 0.003963f, 0.054007f, 0.286733f, 0.098506f, 0.342177f, +0.051652f, 0.161946f, 0.001344f, 0.352337f, 0.127891f, 0.778045f, 0.221139f, 0.940244f, 0.035916f, 0.185512f, 0.043177f, 0.489443f, 0.187674f, 1.184727f, 0.280370f, 1.298904f, +0.000860f, 0.003164f, 0.000041f, 0.007123f, 0.002105f, 0.015033f, 0.006741f, 0.018798f, 0.000446f, 0.002702f, 0.000992f, 0.007376f, 0.004083f, 0.030264f, 0.011299f, 0.034332f, +0.041408f, 0.118668f, 0.001339f, 0.285376f, 0.159339f, 0.886041f, 0.342368f, 1.183551f, 0.037540f, 0.177234f, 0.056080f, 0.516863f, 0.187502f, 1.081897f, 0.348080f, 1.311118f, +0.033622f, 0.085565f, 0.001064f, 0.166957f, 0.072771f, 0.359352f, 0.152992f, 0.389470f, 0.000887f, 0.003718f, 0.001296f, 0.008797f, 0.136267f, 0.698228f, 0.247513f, 0.686554f, +0.126066f, 0.381466f, 0.003267f, 0.683830f, 0.386495f, 2.269271f, 0.665524f, 2.259574f, 0.125882f, 0.627512f, 0.150702f, 1.364130f, 0.594571f, 3.622386f, 0.884556f, 3.272334f, +0.024846f, 0.088271f, 0.001193f, 0.163728f, 0.075324f, 0.519261f, 0.240255f, 0.534982f, 0.018493f, 0.108239f, 0.041010f, 0.243463f, 0.153196f, 1.095847f, 0.422173f, 1.024299f, +0.096895f, 0.267993f, 0.003121f, 0.531023f, 0.461672f, 2.477658f, 0.987864f, 2.726960f, 0.126148f, 0.574783f, 0.187663f, 1.381131f, 0.569523f, 3.171523f, 1.052876f, 3.166854f, +0.019481f, 0.054540f, 0.000542f, 0.120737f, 0.028701f, 0.155915f, 0.053049f, 0.191716f, 0.000562f, 0.002590f, 0.000722f, 0.006953f, 0.071463f, 0.402836f, 0.114123f, 0.449389f, +0.075507f, 0.251354f, 0.001720f, 0.511204f, 0.157574f, 1.017802f, 0.238553f, 1.149794f, 0.082403f, 0.451894f, 0.086732f, 1.114520f, 0.322335f, 2.160407f, 0.421609f, 2.214192f, +0.015900f, 0.062143f, 0.000671f, 0.130772f, 0.032811f, 0.248833f, 0.092011f, 0.290856f, 0.012934f, 0.083281f, 0.025217f, 0.212525f, 0.088736f, 0.698291f, 0.214991f, 0.740509f, +0.076666f, 0.233274f, 0.002171f, 0.524411f, 0.248648f, 1.468014f, 0.467767f, 1.833093f, 0.109086f, 0.546803f, 0.142676f, 1.490662f, 0.407875f, 2.498739f, 0.662940f, 2.830727f, +0.052326f, 0.121542f, 0.001490f, 0.278439f, 0.106446f, 0.479764f, 0.201403f, 0.610491f, 0.001358f, 0.005195f, 0.001786f, 0.014433f, 0.214828f, 1.004700f, 0.351178f, 1.159874f, +0.205373f, 0.567203f, 0.004790f, 1.193788f, 0.591790f, 3.171369f, 0.917095f, 3.707527f, 0.201746f, 0.917912f, 0.217364f, 2.342786f, 0.981203f, 5.456160f, 1.313735f, 5.786919f, +0.056054f, 0.181767f, 0.002422f, 0.395839f, 0.159724f, 1.004988f, 0.458498f, 1.215660f, 0.041046f, 0.219270f, 0.081917f, 0.579062f, 0.350122f, 2.285902f, 0.868336f, 2.508602f, +0.125480f, 0.316764f, 0.003637f, 0.736923f, 0.561935f, 2.752523f, 1.082124f, 3.556852f, 0.160713f, 0.668363f, 0.215168f, 1.885563f, 0.747129f, 3.797427f, 1.243051f, 4.451917f, +0.091829f, 0.143027f, 0.002146f, 0.346204f, 0.134780f, 0.407334f, 0.209246f, 0.547662f, 0.001696f, 0.004352f, 0.001831f, 0.012775f, 0.211414f, 0.662988f, 0.283573f, 0.808706f, +0.280958f, 0.520312f, 0.005377f, 1.157081f, 0.584114f, 2.098959f, 0.742745f, 2.592701f, 0.196483f, 0.599445f, 0.173702f, 1.616558f, 0.752723f, 2.806664f, 0.826951f, 3.145296f, +0.004562f, 0.009920f, 0.000162f, 0.022825f, 0.009379f, 0.039571f, 0.022091f, 0.050575f, 0.002378f, 0.008519f, 0.003894f, 0.023771f, 0.015979f, 0.069955f, 0.032518f, 0.081116f, +0.233001f, 0.394408f, 0.005541f, 0.969490f, 0.752837f, 2.472709f, 1.189563f, 3.376127f, 0.212450f, 0.592441f, 0.233388f, 1.765975f, 0.777959f, 2.651415f, 1.062052f, 3.284326f, +0.167211f, 0.251352f, 0.003891f, 0.501302f, 0.303886f, 0.886360f, 0.469822f, 0.981921f, 0.004435f, 0.010984f, 0.004767f, 0.026565f, 0.499702f, 1.512376f, 0.667477f, 1.520019f, +0.642371f, 1.148113f, 0.012243f, 2.103725f, 1.653630f, 5.734835f, 2.093984f, 5.836782f, 0.645111f, 1.899476f, 0.567944f, 4.220659f, 2.233935f, 8.038998f, 2.444037f, 7.422961f, +0.123527f, 0.259222f, 0.004361f, 0.491462f, 0.314450f, 1.280397f, 0.737576f, 1.348376f, 0.092472f, 0.319685f, 0.150801f, 0.734992f, 0.561617f, 2.372914f, 1.138145f, 2.267102f, +0.510749f, 0.834396f, 0.012096f, 1.689950f, 2.043371f, 6.477323f, 3.215339f, 7.286943f, 0.668760f, 1.799846f, 0.731621f, 4.420579f, 2.213592f, 7.281063f, 3.009396f, 7.431344f, +0.100959f, 0.166954f, 0.002065f, 0.377773f, 0.124892f, 0.400749f, 0.169761f, 0.503681f, 0.002927f, 0.007973f, 0.002766f, 0.021879f, 0.273086f, 0.909255f, 0.320705f, 1.036793f, +0.400935f, 0.788333f, 0.006718f, 1.638818f, 0.702543f, 2.680360f, 0.782149f, 3.095014f, 0.440056f, 1.425425f, 0.340612f, 3.593418f, 1.262029f, 4.996181f, 1.213913f, 5.233959f, +0.082375f, 0.190170f, 0.002557f, 0.409051f, 0.142736f, 0.639385f, 0.294353f, 0.763916f, 0.067396f, 0.256318f, 0.096628f, 0.668583f, 0.338988f, 1.575665f, 0.603981f, 1.707930f, +0.421122f, 0.756850f, 0.008769f, 1.739114f, 1.146817f, 3.999264f, 1.586554f, 5.104424f, 0.602637f, 1.784260f, 0.579632f, 4.971859f, 1.651995f, 5.977826f, 1.974566f, 6.922019f, +0.197583f, 0.271083f, 0.004138f, 0.634772f, 0.337499f, 0.898481f, 0.469593f, 1.168619f, 0.005156f, 0.011654f, 0.004988f, 0.033092f, 0.598143f, 1.652306f, 0.719046f, 1.949743f, +0.794552f, 1.296160f, 0.013628f, 2.788432f, 1.922443f, 6.085177f, 2.190865f, 7.271485f, 0.784998f, 2.109624f, 0.621966f, 5.503626f, 2.799094f, 9.193611f, 2.756018f, 9.966871f, +0.211599f, 0.405285f, 0.006723f, 0.902144f, 0.506270f, 1.881534f, 1.068720f, 2.326354f, 0.155834f, 0.491709f, 0.228707f, 1.327291f, 0.974546f, 3.758213f, 1.777407f, 4.215683f, +0.502197f, 0.748817f, 0.010704f, 1.780633f, 1.888389f, 5.463577f, 2.674227f, 7.216462f, 0.646895f, 1.589044f, 0.636907f, 4.582231f, 2.204824f, 6.619242f, 2.697633f, 7.931919f, +0.101998f, 0.157147f, 0.002650f, 0.420830f, 0.119811f, 0.358175f, 0.206782f, 0.532778f, 0.002228f, 0.005656f, 0.002674f, 0.018367f, 0.258817f, 0.802862f, 0.385932f, 1.083463f, +0.186183f, 0.341066f, 0.003961f, 0.839124f, 0.309781f, 1.101124f, 0.437908f, 1.504779f, 0.153994f, 0.464731f, 0.151345f, 1.386539f, 0.549772f, 2.027744f, 0.671448f, 2.514040f, +0.004030f, 0.008667f, 0.000159f, 0.022064f, 0.006630f, 0.027671f, 0.017361f, 0.039127f, 0.002485f, 0.008804f, 0.004523f, 0.027177f, 0.015557f, 0.067369f, 0.035194f, 0.086424f, +0.156116f, 0.261403f, 0.004127f, 0.710878f, 0.403690f, 1.311582f, 0.709121f, 1.981203f, 0.168354f, 0.464395f, 0.205604f, 1.531494f, 0.574506f, 1.936825f, 0.871904f, 2.654280f, +0.118357f, 0.175989f, 0.003062f, 0.388321f, 0.172146f, 0.496674f, 0.295873f, 0.608732f, 0.003713f, 0.009096f, 0.004437f, 0.024338f, 0.389841f, 1.167109f, 0.578893f, 1.297743f, +0.271270f, 0.479596f, 0.005748f, 0.972226f, 0.558871f, 1.917210f, 0.786742f, 2.158789f, 0.322202f, 0.938433f, 0.315345f, 2.306947f, 1.039763f, 3.701186f, 1.264612f, 3.780979f, +0.069534f, 0.144338f, 0.002729f, 0.302751f, 0.141659f, 0.570573f, 0.369389f, 0.664761f, 0.061564f, 0.210528f, 0.111610f, 0.535498f, 0.348435f, 1.456260f, 0.784991f, 1.539275f, +0.218079f, 0.352414f, 0.005742f, 0.789664f, 0.698250f, 2.189446f, 1.221450f, 2.725034f, 0.337718f, 0.899072f, 0.410729f, 2.443016f, 1.041721f, 3.389407f, 1.574413f, 3.827228f, +0.007064f, 0.011555f, 0.000161f, 0.028926f, 0.006993f, 0.022197f, 0.010568f, 0.030866f, 0.000242f, 0.000653f, 0.000254f, 0.001981f, 0.021059f, 0.069360f, 0.027494f, 0.087499f, +0.016736f, 0.032551f, 0.000312f, 0.074865f, 0.023470f, 0.088575f, 0.029048f, 0.113154f, 0.021726f, 0.069612f, 0.018694f, 0.194148f, 0.058063f, 0.227377f, 0.062088f, 0.263528f, +0.004584f, 0.010467f, 0.000158f, 0.024908f, 0.006356f, 0.028164f, 0.014572f, 0.037228f, 0.004435f, 0.016685f, 0.007069f, 0.048150f, 0.020789f, 0.095585f, 0.041177f, 0.114626f, +0.017774f, 0.031598f, 0.000411f, 0.080328f, 0.038737f, 0.133625f, 0.059576f, 0.188687f, 0.030082f, 0.088102f, 0.032166f, 0.271603f, 0.076848f, 0.275069f, 0.102113f, 0.352386f, +0.195101f, 0.264781f, 0.004542f, 0.685947f, 0.266711f, 0.702348f, 0.412549f, 1.010659f, 0.006021f, 0.013463f, 0.006475f, 0.042294f, 0.650974f, 1.778789f, 0.869964f, 2.322198f, +0.468080f, 0.755320f, 0.008925f, 1.797715f, 0.906378f, 2.837946f, 1.148304f, 3.751820f, 0.546947f, 1.453974f, 0.481758f, 4.196512f, 1.817455f, 5.904830f, 1.989361f, 7.082198f, +0.166161f, 0.314812f, 0.005869f, 0.775273f, 0.318167f, 1.169664f, 0.746661f, 1.599974f, 0.144729f, 0.451729f, 0.236135f, 1.349037f, 0.843464f, 3.217515f, 1.710159f, 3.992962f, +0.299131f, 0.441203f, 0.007088f, 1.160713f, 0.900196f, 2.576308f, 1.417194f, 3.764724f, 0.455722f, 1.107330f, 0.498802f, 3.532697f, 1.447471f, 4.298524f, 1.968813f, 5.698721f, +0.248539f, 0.722697f, 0.008296f, 1.157911f, 0.229224f, 1.293321f, 0.508370f, 1.150995f, 0.004489f, 0.021505f, 0.006922f, 0.041782f, 0.468832f, 2.744811f, 0.898337f, 2.216165f, +0.468678f, 1.620392f, 0.012814f, 2.385199f, 0.612277f, 4.107500f, 1.112194f, 3.358385f, 0.320504f, 1.825490f, 0.404764f, 3.258565f, 1.028813f, 7.161679f, 1.614624f, 5.312397f, +0.012264f, 0.049783f, 0.000621f, 0.075823f, 0.015843f, 0.124790f, 0.053308f, 0.105571f, 0.006252f, 0.041807f, 0.014624f, 0.077216f, 0.035195f, 0.287656f, 0.102315f, 0.220782f, +0.344398f, 1.088357f, 0.011700f, 1.770816f, 0.699231f, 4.287616f, 1.578330f, 3.874950f, 0.307067f, 1.598618f, 0.481888f, 3.154198f, 0.942166f, 5.994754f, 1.837413f, 4.915236f, +0.380470f, 1.067726f, 0.012647f, 1.409556f, 0.434493f, 2.365950f, 0.959613f, 1.734909f, 0.009869f, 0.045625f, 0.015153f, 0.073040f, 0.931611f, 5.263882f, 1.777665f, 3.501870f, +0.900863f, 3.005941f, 0.024527f, 3.645769f, 1.457231f, 9.434829f, 2.636053f, 6.356106f, 0.884671f, 4.862997f, 1.112611f, 7.152453f, 2.566915f, 17.245110f, 4.011801f, 10.540130f, +0.279167f, 1.093697f, 0.014079f, 1.372523f, 0.446551f, 3.394589f, 1.496294f, 2.366237f, 0.204357f, 1.318930f, 0.476070f, 2.007182f, 1.039946f, 8.203052f, 3.010638f, 5.187633f, +0.634673f, 1.935697f, 0.021472f, 2.595037f, 1.595536f, 9.442302f, 3.586548f, 7.031247f, 0.812619f, 4.082957f, 1.269969f, 6.637784f, 2.253761f, 13.839740f, 4.377037f, 9.349862f, +0.141751f, 0.437624f, 0.004143f, 0.655452f, 0.110188f, 0.660077f, 0.213958f, 0.549139f, 0.004018f, 0.020437f, 0.005425f, 0.037120f, 0.314159f, 1.952805f, 0.527043f, 1.473906f, +0.346955f, 1.273597f, 0.008305f, 1.752499f, 0.382023f, 2.721027f, 0.607570f, 2.079730f, 0.372376f, 2.251859f, 0.411741f, 3.757587f, 0.894822f, 6.613461f, 1.229549f, 4.585910f, +0.114875f, 0.495102f, 0.005093f, 0.704910f, 0.125077f, 1.046000f, 0.368472f, 0.827218f, 0.091904f, 0.652536f, 0.188234f, 1.126643f, 0.387331f, 3.361121f, 0.985850f, 2.411541f, +0.322906f, 1.083431f, 0.009605f, 1.647875f, 0.552561f, 3.597402f, 1.092022f, 3.039207f, 0.451854f, 2.497608f, 0.620849f, 4.606694f, 1.037876f, 7.011374f, 1.772144f, 5.373994f, +0.477511f, 1.223094f, 0.014285f, 1.895746f, 0.512536f, 2.547325f, 1.018743f, 2.193072f, 0.012185f, 0.051416f, 0.016838f, 0.096640f, 1.184426f, 6.108250f, 2.033999f, 4.770986f, +1.183519f, 3.604410f, 0.028999f, 5.132634f, 1.799382f, 10.633250f, 2.929383f, 8.410478f, 1.143393f, 5.736607f, 1.294150f, 9.906118f, 3.416162f, 20.947390f, 4.805001f, 15.031670f, +0.507921f, 1.816209f, 0.023053f, 2.675998f, 0.763627f, 5.298275f, 2.302789f, 4.336136f, 0.365779f, 2.154706f, 0.766879f, 3.849908f, 1.916694f, 13.799230f, 4.993762f, 10.245800f, +0.662820f, 1.845102f, 0.020182f, 2.904182f, 1.566141f, 8.459394f, 3.168313f, 7.395901f, 0.834891f, 3.828733f, 1.174257f, 7.308038f, 2.384317f, 13.363530f, 4.167384f, 10.599760f, +0.113339f, 0.298867f, 0.003601f, 0.707749f, 0.140054f, 0.716603f, 0.295671f, 0.942602f, 0.002049f, 0.008902f, 0.003008f, 0.025563f, 0.228619f, 1.213789f, 0.416992f, 1.448491f, +0.232080f, 0.727646f, 0.006040f, 1.583099f, 0.406222f, 2.471319f, 0.702408f, 2.986516f, 0.158858f, 0.820527f, 0.190973f, 2.164824f, 0.544766f, 3.438942f, 0.813839f, 3.770366f, +0.005318f, 0.019576f, 0.000256f, 0.044069f, 0.009205f, 0.065747f, 0.029481f, 0.082211f, 0.002713f, 0.016455f, 0.006042f, 0.044921f, 0.016319f, 0.120957f, 0.045160f, 0.137215f, +0.190291f, 0.545340f, 0.006154f, 1.311451f, 0.517644f, 2.878475f, 1.112248f, 3.844995f, 0.169826f, 0.801776f, 0.253695f, 2.338193f, 0.556668f, 3.212009f, 1.033402f, 3.892537f, +0.204710f, 0.520973f, 0.006477f, 1.016531f, 0.313222f, 1.546720f, 0.658505f, 1.676355f, 0.005315f, 0.022283f, 0.007768f, 0.052725f, 0.535998f, 2.746446f, 0.973581f, 2.700523f, +0.526328f, 1.592630f, 0.013641f, 2.855003f, 1.140716f, 6.697604f, 1.964250f, 6.668982f, 0.517359f, 2.579000f, 0.619367f, 5.606415f, 1.603685f, 9.770345f, 2.385836f, 8.826180f, +0.142827f, 0.507432f, 0.006857f, 0.941204f, 0.306103f, 2.110180f, 0.976352f, 2.174070f, 0.104652f, 0.612514f, 0.232072f, 1.377729f, 0.568938f, 4.069737f, 1.567858f, 3.804023f, +0.413755f, 1.144372f, 0.013325f, 2.267547f, 1.393641f, 7.479260f, 2.982048f, 8.231824f, 0.530265f, 2.416114f, 0.788847f, 5.805621f, 1.571125f, 8.749180f, 2.904537f, 8.736301f, +0.074392f, 0.208277f, 0.002070f, 0.461067f, 0.077480f, 0.420907f, 0.143211f, 0.517555f, 0.002111f, 0.009736f, 0.002713f, 0.026136f, 0.176305f, 0.993823f, 0.281549f, 1.108671f, +0.197722f, 0.658191f, 0.004505f, 1.338629f, 0.291692f, 1.884098f, 0.441595f, 2.128435f, 0.212411f, 1.164860f, 0.223570f, 2.872926f, 0.545293f, 3.654753f, 0.713234f, 3.745741f, +0.057326f, 0.224058f, 0.002420f, 0.471502f, 0.083629f, 0.634234f, 0.234520f, 0.741345f, 0.045907f, 0.295586f, 0.089502f, 0.754308f, 0.206691f, 1.626523f, 0.500777f, 1.724860f, +0.205331f, 0.624764f, 0.005814f, 1.404502f, 0.470771f, 2.779425f, 0.885635f, 3.470637f, 0.287601f, 1.441624f, 0.376159f, 3.930069f, 0.705722f, 4.323423f, 1.147046f, 4.897842f, +0.334701f, 0.777445f, 0.009531f, 1.781037f, 0.481336f, 2.169427f, 0.910715f, 2.760556f, 0.008549f, 0.032713f, 0.011245f, 0.090879f, 0.887751f, 4.151799f, 1.451200f, 4.793035f, +0.900798f, 2.487844f, 0.021010f, 5.236153f, 1.834961f, 9.833456f, 2.843632f, 11.495920f, 0.871086f, 3.963300f, 0.938520f, 10.115520f, 2.780357f, 15.460680f, 3.722625f, 16.397930f, +0.338529f, 1.097745f, 0.014626f, 2.390588f, 0.681917f, 4.290633f, 1.957484f, 5.190065f, 0.244023f, 1.303577f, 0.487004f, 3.442564f, 1.366035f, 8.918672f, 3.387899f, 9.787559f, +0.562916f, 1.421035f, 0.016315f, 3.305911f, 1.782090f, 8.729203f, 3.431789f, 11.280010f, 0.709726f, 2.951564f, 0.950206f, 8.326855f, 2.165317f, 11.005640f, 3.602590f, 12.902470f, +0.315911f, 0.492045f, 0.007382f, 1.191019f, 0.327784f, 0.990630f, 0.508882f, 1.331906f, 0.005744f, 0.014739f, 0.006200f, 0.043265f, 0.469869f, 1.473495f, 0.630243f, 1.797355f, +0.662780f, 1.227417f, 0.012684f, 2.729557f, 0.974093f, 3.500311f, 1.238632f, 4.323694f, 0.456273f, 1.392028f, 0.403369f, 3.753965f, 1.147149f, 4.277354f, 1.260272f, 4.793429f, +0.014818f, 0.032220f, 0.000525f, 0.074138f, 0.021536f, 0.090862f, 0.050725f, 0.116129f, 0.007604f, 0.027239f, 0.012452f, 0.076005f, 0.033530f, 0.146793f, 0.068234f, 0.170212f, +0.562173f, 0.951609f, 0.013370f, 2.339139f, 1.284068f, 4.217548f, 2.028964f, 5.758451f, 0.504591f, 1.407111f, 0.554322f, 4.194381f, 1.212623f, 4.132823f, 1.655445f, 5.119355f, +0.534516f, 0.803483f, 0.012438f, 1.602488f, 0.686720f, 2.002994f, 1.061701f, 2.218943f, 0.013957f, 0.034563f, 0.015002f, 0.083593f, 1.031960f, 3.123284f, 1.378440f, 3.139069f, +1.408065f, 2.516644f, 0.026836f, 4.611326f, 2.562416f, 8.886530f, 3.244775f, 9.044503f, 1.392009f, 4.098657f, 1.225500f, 9.107265f, 3.163471f, 11.384010f, 3.460997f, 10.511640f, +0.372821f, 0.782366f, 0.013162f, 1.483296f, 0.670910f, 2.731851f, 1.573690f, 2.876891f, 0.274740f, 0.949797f, 0.448035f, 2.183691f, 1.095052f, 4.626756f, 2.219177f, 4.420442f, +1.145062f, 1.870655f, 0.027119f, 3.788743f, 3.238492f, 10.265760f, 5.095917f, 11.548910f, 1.475918f, 3.972166f, 1.614648f, 9.755985f, 3.206087f, 10.545630f, 4.358702f, 10.763290f, +0.202416f, 0.334733f, 0.004141f, 0.757415f, 0.177016f, 0.568001f, 0.240611f, 0.713892f, 0.005777f, 0.015737f, 0.005459f, 0.043181f, 0.353719f, 1.177728f, 0.415398f, 1.342923f, +0.551211f, 1.083812f, 0.009236f, 2.253072f, 0.682797f, 2.605024f, 0.760165f, 3.008023f, 0.595556f, 1.929121f, 0.460972f, 4.863206f, 1.120908f, 4.437506f, 1.078173f, 4.648695f, +0.155934f, 0.359988f, 0.004840f, 0.774324f, 0.191008f, 0.855623f, 0.393902f, 1.022270f, 0.125588f, 0.477633f, 0.180061f, 1.245867f, 0.414559f, 1.926930f, 0.738627f, 2.088680f, +0.592156f, 1.064237f, 0.012330f, 2.445438f, 1.139980f, 3.975419f, 1.577095f, 5.073990f, 0.834171f, 2.469776f, 0.802327f, 6.882054f, 1.500699f, 5.430357f, 1.793728f, 6.288077f, +0.663545f, 0.910382f, 0.013896f, 2.131764f, 0.801250f, 2.133068f, 1.114853f, 2.774398f, 0.017045f, 0.038526f, 0.016489f, 0.109399f, 1.297726f, 3.584831f, 1.560037f, 4.230146f, +1.829725f, 2.984846f, 0.031384f, 6.421307f, 3.129616f, 9.906284f, 3.566590f, 11.837520f, 1.779519f, 4.782325f, 1.409941f, 12.476220f, 4.164255f, 13.677470f, 4.100169f, 14.827860f, +0.670932f, 1.285065f, 0.021317f, 2.860491f, 1.134804f, 4.217458f, 2.395537f, 5.214523f, 0.486404f, 1.534771f, 0.713863f, 4.142871f, 1.996289f, 7.698433f, 3.640892f, 8.635528f, +1.182827f, 1.763694f, 0.025211f, 4.193938f, 3.144224f, 9.097016f, 4.452666f, 12.015620f, 1.499864f, 3.684293f, 1.476708f, 10.624180f, 3.354887f, 10.071920f, 4.104752f, 12.069310f, +0.021178f, 0.032628f, 0.000550f, 0.087376f, 0.023600f, 0.070552f, 0.040731f, 0.104944f, 0.000347f, 0.000881f, 0.000417f, 0.002861f, 0.062802f, 0.194815f, 0.093646f, 0.262902f, +0.020440f, 0.037443f, 0.000435f, 0.092122f, 0.032264f, 0.114683f, 0.045608f, 0.156724f, 0.012685f, 0.038283f, 0.012467f, 0.114217f, 0.070536f, 0.260161f, 0.086147f, 0.322554f, +0.000745f, 0.001601f, 0.000029f, 0.004076f, 0.001162f, 0.004850f, 0.003043f, 0.006858f, 0.000344f, 0.001220f, 0.000627f, 0.003767f, 0.003359f, 0.014546f, 0.007599f, 0.018660f, +0.037789f, 0.063274f, 0.000999f, 0.172072f, 0.092702f, 0.301187f, 0.162840f, 0.454957f, 0.030578f, 0.084346f, 0.037343f, 0.278160f, 0.162518f, 0.547897f, 0.246648f, 0.750853f, +0.023057f, 0.034285f, 0.000596f, 0.075649f, 0.031815f, 0.091794f, 0.054682f, 0.112504f, 0.000543f, 0.001330f, 0.000649f, 0.003558f, 0.088756f, 0.265718f, 0.131797f, 0.295459f, +0.027943f, 0.049401f, 0.000592f, 0.100145f, 0.054614f, 0.187353f, 0.076882f, 0.210961f, 0.024903f, 0.072532f, 0.024373f, 0.178306f, 0.125168f, 0.445553f, 0.152235f, 0.455158f, +0.012053f, 0.025020f, 0.000473f, 0.052480f, 0.023296f, 0.093831f, 0.060746f, 0.109321f, 0.008008f, 0.027383f, 0.014517f, 0.069652f, 0.070587f, 0.295014f, 0.159026f, 0.311831f, +0.049529f, 0.080038f, 0.001304f, 0.179343f, 0.150446f, 0.471741f, 0.263176f, 0.587140f, 0.057552f, 0.153215f, 0.069994f, 0.416326f, 0.276495f, 0.899622f, 0.417884f, 1.015830f, +0.002411f, 0.003943f, 0.000055f, 0.009872f, 0.002264f, 0.007187f, 0.003421f, 0.009993f, 0.000062f, 0.000167f, 0.000065f, 0.000507f, 0.008399f, 0.027663f, 0.010965f, 0.034897f, +0.003020f, 0.005874f, 0.000056f, 0.013509f, 0.004018f, 0.015163f, 0.004973f, 0.019370f, 0.002942f, 0.009425f, 0.002531f, 0.026287f, 0.012245f, 0.047950f, 0.013093f, 0.055573f, +0.001392f, 0.003178f, 0.000048f, 0.007564f, 0.001831f, 0.008114f, 0.004198f, 0.010725f, 0.001011f, 0.003802f, 0.001611f, 0.010971f, 0.007378f, 0.033922f, 0.014613f, 0.040679f, +0.007071f, 0.012571f, 0.000164f, 0.031959f, 0.014621f, 0.050436f, 0.022487f, 0.071219f, 0.008980f, 0.026301f, 0.009602f, 0.081082f, 0.035731f, 0.127897f, 0.047479f, 0.163846f, +0.040074f, 0.054387f, 0.000933f, 0.140895f, 0.051972f, 0.136863f, 0.080391f, 0.196941f, 0.000928f, 0.002075f, 0.000998f, 0.006518f, 0.156265f, 0.426996f, 0.208834f, 0.557440f, +0.050836f, 0.082032f, 0.000969f, 0.195243f, 0.093388f, 0.292406f, 0.118315f, 0.386566f, 0.044572f, 0.118488f, 0.039260f, 0.341985f, 0.230681f, 0.749472f, 0.252500f, 0.898910f, +0.030369f, 0.057538f, 0.001073f, 0.141695f, 0.055167f, 0.202810f, 0.129465f, 0.277421f, 0.019848f, 0.061950f, 0.032384f, 0.185007f, 0.180161f, 0.687250f, 0.365284f, 0.852882f, +0.071630f, 0.105650f, 0.001697f, 0.277944f, 0.204502f, 0.585272f, 0.321951f, 0.855250f, 0.081884f, 0.198964f, 0.089624f, 0.634751f, 0.405076f, 1.202946f, 0.550974f, 1.594793f, +0.039850f, 0.115875f, 0.001330f, 0.185656f, 0.034868f, 0.196729f, 0.077329f, 0.175079f, 0.000540f, 0.002587f, 0.000833f, 0.005027f, 0.087851f, 0.514328f, 0.168332f, 0.415269f, +0.039734f, 0.137374f, 0.001086f, 0.202212f, 0.049245f, 0.330360f, 0.089452f, 0.270110f, 0.020388f, 0.116125f, 0.025748f, 0.207288f, 0.101933f, 0.709564f, 0.159974f, 0.526341f, +0.001750f, 0.007103f, 0.000089f, 0.010818f, 0.002144f, 0.016890f, 0.007215f, 0.014289f, 0.000669f, 0.004475f, 0.001566f, 0.008266f, 0.005868f, 0.047962f, 0.017059f, 0.036812f, +0.064376f, 0.203439f, 0.002187f, 0.331006f, 0.123997f, 0.760335f, 0.279890f, 0.687155f, 0.043068f, 0.224218f, 0.067588f, 0.442400f, 0.205818f, 1.309565f, 0.401386f, 1.073742f, +0.057238f, 0.160628f, 0.001903f, 0.212053f, 0.062011f, 0.337672f, 0.136957f, 0.247609f, 0.001114f, 0.005150f, 0.001711f, 0.008245f, 0.163791f, 0.925470f, 0.312540f, 0.615681f, +0.071659f, 0.239107f, 0.001951f, 0.290002f, 0.109968f, 0.711988f, 0.198927f, 0.479656f, 0.052803f, 0.290255f, 0.066408f, 0.426904f, 0.238625f, 1.603139f, 0.372945f, 0.979831f, +0.037370f, 0.146404f, 0.001885f, 0.183729f, 0.056709f, 0.431093f, 0.190021f, 0.300499f, 0.020526f, 0.132478f, 0.047818f, 0.201608f, 0.162690f, 1.283295f, 0.470988f, 0.811559f, +0.111311f, 0.339490f, 0.003766f, 0.455128f, 0.265475f, 1.571068f, 0.596752f, 1.169902f, 0.106940f, 0.537315f, 0.167127f, 0.873529f, 0.461946f, 2.836690f, 0.897148f, 1.916413f, +0.037357f, 0.115331f, 0.001092f, 0.172737f, 0.027549f, 0.165031f, 0.053493f, 0.137295f, 0.000795f, 0.004041f, 0.001073f, 0.007340f, 0.096758f, 0.601446f, 0.162324f, 0.453949f, +0.048347f, 0.177470f, 0.001157f, 0.244203f, 0.050502f, 0.359710f, 0.080319f, 0.274933f, 0.038935f, 0.235450f, 0.043051f, 0.392885f, 0.145722f, 1.076999f, 0.200232f, 0.746814f, +0.026938f, 0.116100f, 0.001194f, 0.165300f, 0.027826f, 0.232701f, 0.081973f, 0.184029f, 0.016171f, 0.114817f, 0.033121f, 0.198239f, 0.106149f, 0.921121f, 0.270174f, 0.660887f, +0.099208f, 0.332869f, 0.002951f, 0.506286f, 0.161057f, 1.048546f, 0.318295f, 0.885847f, 0.104168f, 0.575784f, 0.143127f, 1.062001f, 0.372658f, 2.517494f, 0.636304f, 1.929579f, +0.075742f, 0.194005f, 0.002266f, 0.300700f, 0.077127f, 0.383322f, 0.153301f, 0.330014f, 0.001450f, 0.006119f, 0.002004f, 0.011502f, 0.219561f, 1.132304f, 0.377048f, 0.884412f, +0.099261f, 0.302299f, 0.002432f, 0.430469f, 0.143170f, 0.846048f, 0.233080f, 0.669190f, 0.071955f, 0.361011f, 0.081442f, 0.623404f, 0.334837f, 2.053173f, 0.470965f, 1.473340f, +0.071688f, 0.256338f, 0.003254f, 0.377688f, 0.102248f, 0.709429f, 0.308339f, 0.580600f, 0.038737f, 0.228191f, 0.081215f, 0.407720f, 0.316151f, 2.276124f, 0.823700f, 1.690002f, +0.122568f, 0.341193f, 0.003732f, 0.537037f, 0.274750f, 1.484044f, 0.555822f, 1.297474f, 0.115844f, 0.531251f, 0.162933f, 1.014017f, 0.515274f, 2.887989f, 0.900612f, 2.290710f, +0.004101f, 0.010815f, 0.000130f, 0.025610f, 0.004808f, 0.024600f, 0.010150f, 0.032358f, 0.000056f, 0.000242f, 0.000082f, 0.000694f, 0.009668f, 0.051330f, 0.017634f, 0.061255f, +0.004440f, 0.013922f, 0.000116f, 0.030289f, 0.007373f, 0.044858f, 0.012750f, 0.054209f, 0.002281f, 0.011780f, 0.002742f, 0.031079f, 0.012181f, 0.076895f, 0.018198f, 0.084306f, +0.000171f, 0.000630f, 0.000008f, 0.001419f, 0.000281f, 0.002008f, 0.000901f, 0.002511f, 0.000066f, 0.000398f, 0.000146f, 0.001085f, 0.000614f, 0.004551f, 0.001699f, 0.005163f, +0.008027f, 0.023005f, 0.000260f, 0.055324f, 0.020717f, 0.115199f, 0.044513f, 0.153880f, 0.005376f, 0.025379f, 0.008030f, 0.074012f, 0.027444f, 0.158355f, 0.050948f, 0.191905f, +0.006950f, 0.017688f, 0.000220f, 0.034513f, 0.010089f, 0.049820f, 0.021210f, 0.053995f, 0.000135f, 0.000568f, 0.000198f, 0.001343f, 0.021268f, 0.108975f, 0.038630f, 0.107152f, +0.009449f, 0.028591f, 0.000245f, 0.051253f, 0.019427f, 0.114066f, 0.033453f, 0.113579f, 0.006969f, 0.034740f, 0.008343f, 0.075520f, 0.033645f, 0.204981f, 0.050055f, 0.185172f, +0.004315f, 0.015330f, 0.000207f, 0.028434f, 0.008773f, 0.060479f, 0.027983f, 0.062310f, 0.002372f, 0.013885f, 0.005261f, 0.031231f, 0.020087f, 0.143686f, 0.055355f, 0.134305f, +0.016377f, 0.045296f, 0.000527f, 0.089752f, 0.052332f, 0.280850f, 0.111977f, 0.309109f, 0.015749f, 0.071758f, 0.023429f, 0.172425f, 0.072676f, 0.404715f, 0.134357f, 0.404120f, +0.004425f, 0.012387f, 0.000123f, 0.027422f, 0.004372f, 0.023750f, 0.008081f, 0.029203f, 0.000094f, 0.000434f, 0.000121f, 0.001166f, 0.012255f, 0.069079f, 0.019570f, 0.077062f, +0.006218f, 0.020699f, 0.000142f, 0.042097f, 0.008702f, 0.056211f, 0.013175f, 0.063501f, 0.005012f, 0.027487f, 0.005276f, 0.067792f, 0.020041f, 0.134321f, 0.026213f, 0.137665f, +0.003034f, 0.011858f, 0.000128f, 0.024953f, 0.004199f, 0.031843f, 0.011775f, 0.037221f, 0.001823f, 0.011738f, 0.003554f, 0.029954f, 0.012784f, 0.100598f, 0.030972f, 0.106680f, +0.014237f, 0.043320f, 0.000403f, 0.097385f, 0.030968f, 0.182832f, 0.058257f, 0.228300f, 0.014963f, 0.075004f, 0.019571f, 0.204472f, 0.057187f, 0.350341f, 0.092949f, 0.396888f, +0.011981f, 0.027830f, 0.000341f, 0.063756f, 0.016347f, 0.073676f, 0.030929f, 0.093751f, 0.000230f, 0.000879f, 0.000302f, 0.002441f, 0.037139f, 0.173692f, 0.060712f, 0.200519f, +0.017050f, 0.047089f, 0.000398f, 0.099109f, 0.032950f, 0.176577f, 0.051062f, 0.206429f, 0.012372f, 0.056289f, 0.013329f, 0.143666f, 0.061503f, 0.341997f, 0.082346f, 0.362730f, +0.010783f, 0.034966f, 0.000466f, 0.076147f, 0.020607f, 0.129657f, 0.059152f, 0.156836f, 0.005832f, 0.031156f, 0.011640f, 0.082280f, 0.050851f, 0.332001f, 0.126116f, 0.364346f, +0.023492f, 0.059304f, 0.000681f, 0.137965f, 0.070556f, 0.345605f, 0.135871f, 0.446597f, 0.022225f, 0.092426f, 0.029755f, 0.260750f, 0.105607f, 0.536770f, 0.175706f, 0.629282f, +0.045805f, 0.071343f, 0.001070f, 0.172689f, 0.045088f, 0.136266f, 0.069999f, 0.183210f, 0.000625f, 0.001604f, 0.000675f, 0.004707f, 0.079619f, 0.249684f, 0.106795f, 0.304561f, +0.050812f, 0.094100f, 0.000972f, 0.209261f, 0.070847f, 0.254584f, 0.090088f, 0.314470f, 0.026247f, 0.080077f, 0.023204f, 0.215949f, 0.102780f, 0.383235f, 0.112916f, 0.429474f, +0.001912f, 0.004157f, 0.000068f, 0.009565f, 0.002636f, 0.011121f, 0.006209f, 0.014214f, 0.000736f, 0.002637f, 0.001205f, 0.007358f, 0.005056f, 0.022133f, 0.010288f, 0.025664f, +0.095027f, 0.160855f, 0.002260f, 0.395395f, 0.205916f, 0.676336f, 0.325369f, 0.923438f, 0.064000f, 0.178471f, 0.070307f, 0.531994f, 0.239549f, 0.816424f, 0.327027f, 1.011310f, +0.072717f, 0.109308f, 0.001692f, 0.218007f, 0.088630f, 0.258513f, 0.137027f, 0.286384f, 0.001425f, 0.003528f, 0.001531f, 0.008533f, 0.164071f, 0.496571f, 0.219158f, 0.499080f, +0.101286f, 0.181028f, 0.001930f, 0.331704f, 0.174865f, 0.606435f, 0.221430f, 0.617215f, 0.075133f, 0.221223f, 0.066146f, 0.491560f, 0.265939f, 0.957005f, 0.290951f, 0.883668f, +0.045131f, 0.094707f, 0.001593f, 0.179555f, 0.077048f, 0.313729f, 0.180724f, 0.330385f, 0.024955f, 0.086271f, 0.040696f, 0.198347f, 0.154917f, 0.654547f, 0.313947f, 0.625360f, +0.181607f, 0.296686f, 0.004301f, 0.600895f, 0.487274f, 1.544620f, 0.766748f, 1.737687f, 0.175643f, 0.472710f, 0.192152f, 1.161017f, 0.594255f, 1.954654f, 0.807894f, 1.994998f, +0.048239f, 0.079773f, 0.000987f, 0.180506f, 0.040022f, 0.128420f, 0.054400f, 0.161405f, 0.001033f, 0.002814f, 0.000976f, 0.007722f, 0.098517f, 0.328017f, 0.115695f, 0.374026f, +0.069458f, 0.136572f, 0.001164f, 0.283911f, 0.081625f, 0.311419f, 0.090874f, 0.359596f, 0.056311f, 0.182402f, 0.043586f, 0.459825f, 0.165071f, 0.653490f, 0.158777f, 0.684591f, +0.033067f, 0.076338f, 0.001026f, 0.164201f, 0.038427f, 0.172132f, 0.079244f, 0.205657f, 0.019983f, 0.075999f, 0.028651f, 0.198238f, 0.102738f, 0.477542f, 0.183050f, 0.517628f, +0.164521f, 0.295681f, 0.003426f, 0.679425f, 0.300476f, 1.047840f, 0.415690f, 1.337401f, 0.173902f, 0.514880f, 0.167263f, 1.434720f, 0.487273f, 1.763222f, 0.582419f, 2.041722f, +0.095178f, 0.130584f, 0.001993f, 0.305777f, 0.109034f, 0.290267f, 0.151709f, 0.377539f, 0.001835f, 0.004147f, 0.001775f, 0.011775f, 0.217542f, 0.600936f, 0.261514f, 0.709112f, +0.138772f, 0.226380f, 0.002380f, 0.487011f, 0.225182f, 0.712776f, 0.256623f, 0.851732f, 0.101270f, 0.272156f, 0.080238f, 0.710006f, 0.369102f, 1.212313f, 0.363422f, 1.314279f, +0.085633f, 0.164016f, 0.002721f, 0.365091f, 0.137407f, 0.510668f, 0.290062f, 0.631397f, 0.046582f, 0.146983f, 0.068366f, 0.396759f, 0.297768f, 1.148304f, 0.543078f, 1.288082f, +0.197795f, 0.294929f, 0.004216f, 0.701319f, 0.498809f, 1.443178f, 0.706384f, 1.906194f, 0.188196f, 0.462287f, 0.185290f, 1.333070f, 0.655640f, 1.968339f, 0.802185f, 2.358685f, +0.045023f, 0.069367f, 0.001170f, 0.185761f, 0.056882f, 0.170047f, 0.098172f, 0.252941f, 0.000917f, 0.002327f, 0.001100f, 0.007556f, 0.154678f, 0.479817f, 0.230646f, 0.647513f, +0.040761f, 0.074670f, 0.000867f, 0.183711f, 0.072944f, 0.259282f, 0.103114f, 0.354330f, 0.031422f, 0.094827f, 0.030881f, 0.282920f, 0.162959f, 0.601048f, 0.199025f, 0.745192f, +0.001246f, 0.002680f, 0.000049f, 0.006823f, 0.002205f, 0.009203f, 0.005774f, 0.013012f, 0.000716f, 0.002537f, 0.001303f, 0.007832f, 0.006513f, 0.028203f, 0.014734f, 0.036180f, +0.069740f, 0.116774f, 0.001844f, 0.317564f, 0.193959f, 0.630170f, 0.340708f, 0.951900f, 0.070094f, 0.193351f, 0.085603f, 0.637636f, 0.347470f, 1.171421f, 0.527341f, 1.605349f, +0.061053f, 0.090781f, 0.001579f, 0.200309f, 0.095507f, 0.275555f, 0.164150f, 0.337724f, 0.001785f, 0.004373f, 0.002133f, 0.011701f, 0.272260f, 0.815095f, 0.404292f, 0.906328f, +0.069402f, 0.122701f, 0.001470f, 0.248736f, 0.153783f, 0.527555f, 0.216486f, 0.594030f, 0.076828f, 0.223767f, 0.075193f, 0.550086f, 0.360158f, 1.282033f, 0.438041f, 1.309671f, +0.025125f, 0.052155f, 0.000986f, 0.109396f, 0.055053f, 0.221744f, 0.143557f, 0.258349f, 0.020733f, 0.070900f, 0.037587f, 0.180341f, 0.170460f, 0.712427f, 0.384031f, 0.753039f, +0.113844f, 0.183972f, 0.002997f, 0.412231f, 0.392044f, 1.229302f, 0.685804f, 1.530018f, 0.164314f, 0.437436f, 0.199837f, 1.188628f, 0.736268f, 2.395567f, 1.112765f, 2.705011f, +0.005712f, 0.009344f, 0.000130f, 0.023392f, 0.006083f, 0.019307f, 0.009191f, 0.026846f, 0.000183f, 0.000492f, 0.000192f, 0.001493f, 0.023057f, 0.075940f, 0.030102f, 0.095800f, +0.006713f, 0.013056f, 0.000125f, 0.030027f, 0.010125f, 0.038210f, 0.012531f, 0.048813f, 0.008121f, 0.026022f, 0.006988f, 0.072576f, 0.031530f, 0.123473f, 0.033716f, 0.143104f, +0.002596f, 0.005929f, 0.000090f, 0.014110f, 0.003873f, 0.017160f, 0.008878f, 0.022682f, 0.002342f, 0.008809f, 0.003732f, 0.025422f, 0.015944f, 0.073309f, 0.031581f, 0.087913f, +0.014546f, 0.025860f, 0.000337f, 0.065740f, 0.034097f, 0.117619f, 0.052440f, 0.166086f, 0.022945f, 0.067201f, 0.024535f, 0.207167f, 0.085150f, 0.304784f, 0.113144f, 0.390454f, +0.089949f, 0.122074f, 0.002094f, 0.316248f, 0.132252f, 0.348269f, 0.204568f, 0.501149f, 0.002587f, 0.005785f, 0.002782f, 0.018173f, 0.406337f, 1.110318f, 0.543030f, 1.449513f, +0.107033f, 0.172715f, 0.002041f, 0.411073f, 0.222912f, 0.697956f, 0.282411f, 0.922712f, 0.116564f, 0.309867f, 0.102671f, 0.894350f, 0.562663f, 1.828066f, 0.615883f, 2.192565f, +0.053663f, 0.101670f, 0.001895f, 0.250378f, 0.110516f, 0.406283f, 0.259353f, 0.555751f, 0.043563f, 0.135969f, 0.071076f, 0.406056f, 0.368803f, 1.406851f, 0.747763f, 1.745914f, +0.139568f, 0.205856f, 0.003307f, 0.541564f, 0.451739f, 1.292851f, 0.711181f, 1.889226f, 0.198174f, 0.481530f, 0.216907f, 1.536216f, 0.914368f, 2.715378f, 1.243699f, 3.599883f, +0.139462f, 0.405527f, 0.004655f, 0.649738f, 0.138340f, 0.780540f, 0.306810f, 0.694644f, 0.002348f, 0.011246f, 0.003620f, 0.021851f, 0.356177f, 2.085267f, 0.682478f, 1.683648f, +0.130436f, 0.450967f, 0.003566f, 0.663818f, 0.183273f, 1.229499f, 0.332913f, 1.005266f, 0.083134f, 0.473506f, 0.104990f, 0.845224f, 0.387657f, 2.698520f, 0.608390f, 2.001711f, +0.004821f, 0.019568f, 0.000244f, 0.029804f, 0.006698f, 0.052756f, 0.022536f, 0.044631f, 0.002290f, 0.015316f, 0.005358f, 0.028288f, 0.018730f, 0.153083f, 0.054449f, 0.117494f, +0.195574f, 0.618049f, 0.006644f, 1.005598f, 0.427069f, 2.618743f, 0.963995f, 2.366700f, 0.162519f, 0.846091f, 0.255046f, 1.669403f, 0.724377f, 4.609021f, 1.412681f, 3.779042f, +0.249486f, 0.700140f, 0.008293f, 0.924288f, 0.306432f, 1.668617f, 0.676779f, 1.223567f, 0.006031f, 0.027883f, 0.009261f, 0.044638f, 0.827077f, 4.673232f, 1.578197f, 3.108932f, +0.292985f, 0.977613f, 0.007977f, 1.185702f, 0.509731f, 3.300248f, 0.922076f, 2.223329f, 0.268157f, 1.474048f, 0.337249f, 2.168017f, 1.130275f, 7.593442f, 1.766494f, 4.641075f, +0.128231f, 0.502373f, 0.006467f, 0.630448f, 0.220611f, 1.677038f, 0.739218f, 1.168998f, 0.087486f, 0.564641f, 0.203808f, 0.859286f, 0.646735f, 5.101424f, 1.872296f, 3.226155f, +0.421175f, 1.284548f, 0.014249f, 1.722093f, 1.138795f, 6.739335f, 2.559858f, 5.018472f, 0.502598f, 2.525277f, 0.785466f, 4.105417f, 2.024917f, 12.434470f, 3.932598f, 8.400489f, +0.145719f, 0.449876f, 0.004259f, 0.673803f, 0.121829f, 0.729814f, 0.236563f, 0.607156f, 0.003850f, 0.019581f, 0.005197f, 0.035565f, 0.437248f, 2.717923f, 0.733541f, 2.051389f, +0.176899f, 0.649360f, 0.004234f, 0.893534f, 0.209493f, 1.492150f, 0.333178f, 1.140477f, 0.176952f, 1.070079f, 0.195659f, 1.785598f, 0.617699f, 4.565292f, 0.848762f, 3.165668f, +0.082722f, 0.356526f, 0.003668f, 0.507610f, 0.096873f, 0.810130f, 0.285383f, 0.640682f, 0.061681f, 0.437948f, 0.126332f, 0.756144f, 0.377629f, 3.276929f, 0.961156f, 2.351136f, +0.335936f, 1.127149f, 0.009992f, 1.714369f, 0.618282f, 4.025272f, 1.221906f, 3.400686f, 0.438127f, 2.421728f, 0.601987f, 4.466739f, 1.461880f, 9.875737f, 2.496120f, 7.569437f, +0.279856f, 0.716822f, 0.008372f, 1.111044f, 0.323074f, 1.605690f, 0.642158f, 1.382389f, 0.006656f, 0.028085f, 0.009197f, 0.052787f, 0.939822f, 4.846792f, 1.613943f, 3.785695f, +0.344023f, 1.047724f, 0.008429f, 1.491946f, 0.562552f, 3.324337f, 0.915830f, 2.629418f, 0.309763f, 1.554136f, 0.350605f, 2.683722f, 1.344428f, 8.243831f, 1.891004f, 5.915703f, +0.208522f, 0.745627f, 0.009464f, 1.098605f, 0.337181f, 2.339465f, 1.016802f, 1.914631f, 0.139957f, 0.824452f, 0.293430f, 1.473084f, 1.065357f, 7.670029f, 2.775684f, 5.694927f, +0.393129f, 1.094359f, 0.011970f, 1.722516f, 0.999071f, 5.396407f, 2.021127f, 4.717985f, 0.461520f, 2.116487f, 0.649118f, 4.039814f, 1.914651f, 10.731170f, 3.346488f, 8.511804f, +0.052513f, 0.138472f, 0.001669f, 0.327918f, 0.069792f, 0.357100f, 0.147340f, 0.469721f, 0.000885f, 0.003844f, 0.001299f, 0.011039f, 0.143411f, 0.761404f, 0.261577f, 0.908631f, +0.053332f, 0.167212f, 0.001388f, 0.363794f, 0.100401f, 0.610804f, 0.173605f, 0.738139f, 0.034023f, 0.175736f, 0.040902f, 0.463651f, 0.169490f, 1.069937f, 0.253205f, 1.173051f, +0.001726f, 0.006354f, 0.000083f, 0.014303f, 0.003213f, 0.022951f, 0.010291f, 0.028697f, 0.000821f, 0.004978f, 0.001828f, 0.013588f, 0.007171f, 0.053150f, 0.019844f, 0.060295f, +0.089226f, 0.255706f, 0.002886f, 0.614930f, 0.261054f, 1.451651f, 0.560921f, 1.939079f, 0.074216f, 0.350387f, 0.110868f, 1.021822f, 0.353392f, 2.039091f, 0.656038f, 2.471114f, +0.110838f, 0.282074f, 0.003507f, 0.550387f, 0.182401f, 0.900711f, 0.383472f, 0.976202f, 0.002682f, 0.011244f, 0.003920f, 0.026606f, 0.392913f, 2.013283f, 0.713684f, 1.979620f, +0.141340f, 0.427685f, 0.003663f, 0.766683f, 0.329468f, 1.934437f, 0.567325f, 1.926171f, 0.129486f, 0.645478f, 0.155017f, 1.403187f, 0.583062f, 3.552265f, 0.867433f, 3.208989f, +0.054170f, 0.192456f, 0.002601f, 0.356974f, 0.124866f, 0.860791f, 0.398276f, 0.886853f, 0.036993f, 0.216516f, 0.082034f, 0.487009f, 0.292148f, 2.089801f, 0.805091f, 1.953357f, +0.226714f, 0.627051f, 0.007301f, 1.242487f, 0.821320f, 4.407785f, 1.757424f, 4.851297f, 0.270801f, 1.233884f, 0.402856f, 2.964869f, 1.165555f, 6.490668f, 2.154760f, 6.481113f, +0.063146f, 0.176789f, 0.001757f, 0.391362f, 0.070734f, 0.384261f, 0.130743f, 0.472495f, 0.001670f, 0.007702f, 0.002146f, 0.020677f, 0.202612f, 1.142115f, 0.323560f, 1.274100f, +0.083240f, 0.277095f, 0.001897f, 0.563555f, 0.132077f, 0.853111f, 0.199952f, 0.963746f, 0.083344f, 0.457058f, 0.087723f, 1.127254f, 0.310808f, 2.083150f, 0.406532f, 2.135012f, +0.034086f, 0.133223f, 0.001439f, 0.280351f, 0.053482f, 0.405597f, 0.149977f, 0.474095f, 0.025440f, 0.163804f, 0.049599f, 0.418012f, 0.166390f, 1.309380f, 0.403134f, 1.388543f, +0.176383f, 0.536685f, 0.004994f, 1.206494f, 0.434949f, 2.567934f, 0.818245f, 3.206550f, 0.230258f, 1.154186f, 0.301158f, 3.146473f, 0.820772f, 5.028249f, 1.334043f, 5.696313f, +0.161969f, 0.376222f, 0.004612f, 0.861880f, 0.250524f, 1.129133f, 0.474005f, 1.436801f, 0.003856f, 0.014754f, 0.005072f, 0.040988f, 0.581636f, 2.720173f, 0.950796f, 3.140297f, +0.216204f, 0.597116f, 0.005043f, 1.256747f, 0.473684f, 2.538445f, 0.734066f, 2.967599f, 0.194858f, 0.886571f, 0.209942f, 2.262794f, 0.903488f, 5.024009f, 1.209682f, 5.328570f, +0.114756f, 0.372118f, 0.004958f, 0.810370f, 0.248620f, 1.564322f, 0.713679f, 1.892246f, 0.077096f, 0.411847f, 0.153863f, 1.087631f, 0.626941f, 4.093221f, 1.554875f, 4.491996f, +0.275680f, 0.695932f, 0.007990f, 1.619024f, 0.938680f, 4.597934f, 1.807627f, 5.941520f, 0.323947f, 1.347210f, 0.433711f, 3.800705f, 1.435720f, 7.297324f, 2.388708f, 8.555025f, +0.136561f, 0.212699f, 0.003191f, 0.514849f, 0.152396f, 0.460573f, 0.236594f, 0.619243f, 0.002314f, 0.005938f, 0.002498f, 0.017431f, 0.274994f, 0.862375f, 0.368855f, 1.051916f, +0.142099f, 0.263157f, 0.002720f, 0.585214f, 0.224620f, 0.807152f, 0.285621f, 0.997019f, 0.091174f, 0.278158f, 0.080602f, 0.750126f, 0.332988f, 1.241607f, 0.365825f, 1.391410f, +0.004487f, 0.009757f, 0.000159f, 0.022450f, 0.007014f, 0.029592f, 0.016520f, 0.037821f, 0.002146f, 0.007687f, 0.003514f, 0.021450f, 0.013746f, 0.060181f, 0.027974f, 0.069782f, +0.245935f, 0.416301f, 0.005849f, 1.023305f, 0.604175f, 1.984428f, 0.954662f, 2.709448f, 0.205736f, 0.573718f, 0.226012f, 1.710166f, 0.718226f, 2.447836f, 0.980506f, 3.032150f, +0.270012f, 0.405882f, 0.006283f, 0.809502f, 0.373103f, 1.088250f, 0.576835f, 1.205578f, 0.006571f, 0.016273f, 0.007063f, 0.039357f, 0.705785f, 2.136096f, 0.942751f, 2.146892f, +0.352783f, 0.630531f, 0.006724f, 1.155342f, 0.690495f, 2.394655f, 0.874370f, 2.437224f, 0.325048f, 0.957078f, 0.286167f, 2.126639f, 1.073087f, 3.861591f, 1.174011f, 3.565673f, +0.131925f, 0.276846f, 0.004657f, 0.524875f, 0.255339f, 1.039707f, 0.598926f, 1.094907f, 0.090609f, 0.313242f, 0.147761f, 0.720179f, 0.524625f, 2.216617f, 1.063178f, 2.117775f, +0.585383f, 0.956324f, 0.013864f, 1.936896f, 1.780656f, 5.644538f, 2.801945f, 6.350066f, 0.703225f, 1.892604f, 0.769326f, 4.648400f, 2.219079f, 7.299112f, 3.016856f, 7.449766f, +0.160301f, 0.265087f, 0.003279f, 0.599824f, 0.150775f, 0.483799f, 0.204942f, 0.608063f, 0.004264f, 0.011615f, 0.004029f, 0.031872f, 0.379258f, 1.262762f, 0.445391f, 1.439884f, +0.216506f, 0.425702f, 0.003628f, 0.884966f, 0.288449f, 1.100499f, 0.321133f, 1.270746f, 0.218020f, 0.706207f, 0.168751f, 1.780309f, 0.596085f, 2.359809f, 0.573359f, 2.472117f, +0.086504f, 0.199702f, 0.002685f, 0.429554f, 0.113965f, 0.510509f, 0.235022f, 0.609939f, 0.064933f, 0.246951f, 0.093097f, 0.644151f, 0.311364f, 1.447262f, 0.554761f, 1.568748f, +0.474585f, 0.852936f, 0.009882f, 1.959905f, 0.982656f, 3.426788f, 1.359446f, 4.373750f, 0.623095f, 1.844832f, 0.599309f, 5.140643f, 1.628389f, 5.892409f, 1.946351f, 6.823110f, +0.299585f, 0.411029f, 0.006274f, 0.962473f, 0.389084f, 1.035810f, 0.541369f, 1.347238f, 0.007173f, 0.016212f, 0.006938f, 0.046035f, 0.793265f, 2.191312f, 0.953609f, 2.585777f, +0.409729f, 0.668394f, 0.007028f, 1.437919f, 0.753751f, 2.385876f, 0.858994f, 2.851003f, 0.371394f, 0.998093f, 0.294261f, 2.603844f, 1.262509f, 4.146705f, 1.243080f, 4.495478f, +0.212194f, 0.406424f, 0.006742f, 0.904679f, 0.386012f, 1.434601f, 0.814860f, 1.773760f, 0.143375f, 0.452396f, 0.210422f, 1.221171f, 0.854799f, 3.296421f, 1.559007f, 3.697680f, +0.540454f, 0.805862f, 0.011519f, 1.916283f, 1.545173f, 4.470566f, 2.188183f, 5.904863f, 0.638720f, 1.568963f, 0.628859f, 4.524327f, 2.075400f, 6.230690f, 2.539281f, 7.466313f, +0.012855f, 0.019806f, 0.000334f, 0.053039f, 0.021360f, 0.063857f, 0.036866f, 0.094986f, 0.000285f, 0.000724f, 0.000342f, 0.002352f, 0.050492f, 0.156629f, 0.075291f, 0.211371f, +0.019138f, 0.035059f, 0.000407f, 0.086256f, 0.045045f, 0.160112f, 0.063675f, 0.218807f, 0.016080f, 0.048528f, 0.015804f, 0.144785f, 0.087476f, 0.322641f, 0.106836f, 0.400017f, +0.000447f, 0.000962f, 0.000018f, 0.002449f, 0.001041f, 0.004345f, 0.002726f, 0.006144f, 0.000280f, 0.000993f, 0.000510f, 0.003065f, 0.002673f, 0.011577f, 0.006048f, 0.014851f, +0.026263f, 0.043975f, 0.000694f, 0.119588f, 0.096065f, 0.312114f, 0.168748f, 0.471462f, 0.028770f, 0.079361f, 0.035136f, 0.261720f, 0.149599f, 0.504343f, 0.227041f, 0.691166f, +0.018623f, 0.027691f, 0.000482f, 0.061099f, 0.038315f, 0.110546f, 0.065853f, 0.135487f, 0.000593f, 0.001454f, 0.000709f, 0.003890f, 0.094946f, 0.284251f, 0.140990f, 0.316067f, +0.034812f, 0.061546f, 0.000738f, 0.124764f, 0.101452f, 0.348030f, 0.142817f, 0.391884f, 0.042003f, 0.122336f, 0.041109f, 0.300738f, 0.206538f, 0.735201f, 0.251202f, 0.751051f, +0.009637f, 0.020004f, 0.000378f, 0.041959f, 0.027772f, 0.111859f, 0.072418f, 0.130325f, 0.008667f, 0.029640f, 0.015713f, 0.075391f, 0.074748f, 0.312404f, 0.168400f, 0.330213f, +0.045800f, 0.074012f, 0.001206f, 0.165842f, 0.207438f, 0.650446f, 0.362871f, 0.809559f, 0.072050f, 0.191812f, 0.087627f, 0.521203f, 0.338646f, 1.101839f, 0.511815f, 1.244168f, +0.001679f, 0.002747f, 0.000038f, 0.006876f, 0.002351f, 0.007464f, 0.003553f, 0.010378f, 0.000058f, 0.000158f, 0.000061f, 0.000478f, 0.007748f, 0.025519f, 0.010116f, 0.032193f, +0.003245f, 0.006310f, 0.000060f, 0.014513f, 0.006436f, 0.024290f, 0.007966f, 0.031030f, 0.004279f, 0.013709f, 0.003682f, 0.038235f, 0.017424f, 0.068231f, 0.018631f, 0.079079f, +0.000960f, 0.002191f, 0.000033f, 0.005215f, 0.001882f, 0.008341f, 0.004316f, 0.011026f, 0.000943f, 0.003549f, 0.001504f, 0.010241f, 0.006737f, 0.030977f, 0.013345f, 0.037148f, +0.005639f, 0.010025f, 0.000131f, 0.025485f, 0.017385f, 0.059970f, 0.026738f, 0.084682f, 0.009695f, 0.028395f, 0.010367f, 0.087536f, 0.037740f, 0.135085f, 0.050147f, 0.173055f, +0.027168f, 0.036871f, 0.000632f, 0.095518f, 0.052537f, 0.138349f, 0.081264f, 0.199079f, 0.000852f, 0.001904f, 0.000916f, 0.005983f, 0.140315f, 0.383411f, 0.187517f, 0.500540f, +0.053161f, 0.085783f, 0.001014f, 0.204170f, 0.145615f, 0.455933f, 0.184482f, 0.602752f, 0.063102f, 0.167748f, 0.055581f, 0.484160f, 0.319505f, 1.038059f, 0.349726f, 1.245038f, +0.020380f, 0.038613f, 0.000720f, 0.095091f, 0.055203f, 0.202941f, 0.129549f, 0.277602f, 0.018033f, 0.056285f, 0.029422f, 0.168088f, 0.160138f, 0.610869f, 0.324686f, 0.758094f, +0.055598f, 0.082005f, 0.001317f, 0.215737f, 0.236681f, 0.677367f, 0.372611f, 0.989827f, 0.086046f, 0.209077f, 0.094180f, 0.667016f, 0.416441f, 1.236697f, 0.566433f, 1.639538f, +0.033277f, 0.096762f, 0.001111f, 0.155033f, 0.043414f, 0.244952f, 0.096284f, 0.217995f, 0.000611f, 0.002925f, 0.000941f, 0.005683f, 0.097165f, 0.568859f, 0.186179f, 0.459297f, +0.051180f, 0.176947f, 0.001399f, 0.260464f, 0.094579f, 0.634492f, 0.171802f, 0.518775f, 0.035554f, 0.202503f, 0.044901f, 0.361475f, 0.173901f, 1.210546f, 0.272922f, 0.897960f, +0.001446f, 0.005871f, 0.000073f, 0.008942f, 0.002643f, 0.020818f, 0.008893f, 0.017612f, 0.000749f, 0.005009f, 0.001752f, 0.009251f, 0.006425f, 0.052511f, 0.018678f, 0.040303f, +0.061548f, 0.194502f, 0.002091f, 0.316465f, 0.176766f, 1.083912f, 0.399003f, 0.979590f, 0.055746f, 0.290220f, 0.087484f, 0.572626f, 0.260630f, 1.658317f, 0.508280f, 1.359692f, +0.063596f, 0.178471f, 0.002114f, 0.235608f, 0.102734f, 0.559421f, 0.226897f, 0.410213f, 0.001676f, 0.007747f, 0.002573f, 0.012402f, 0.241038f, 1.361937f, 0.459940f, 0.906048f, +0.122812f, 0.409791f, 0.003344f, 0.497017f, 0.281019f, 1.819458f, 0.508349f, 1.225742f, 0.122516f, 0.673466f, 0.154083f, 0.990528f, 0.541673f, 3.639081f, 0.846574f, 2.224188f, +0.041102f, 0.161025f, 0.002073f, 0.202076f, 0.093002f, 0.706982f, 0.311629f, 0.492810f, 0.030564f, 0.197263f, 0.071203f, 0.300200f, 0.237001f, 1.869452f, 0.686116f, 1.182246f, +0.141599f, 0.431866f, 0.004791f, 0.578969f, 0.503552f, 2.979994f, 1.131916f, 2.219064f, 0.184174f, 0.925371f, 0.287829f, 1.504403f, 0.778329f, 4.779509f, 1.511595f, 3.228943f, +0.035794f, 0.110505f, 0.001046f, 0.165509f, 0.039359f, 0.235776f, 0.076425f, 0.196150f, 0.001031f, 0.005242f, 0.001392f, 0.009522f, 0.122793f, 0.763277f, 0.206001f, 0.576093f, +0.071454f, 0.262293f, 0.001710f, 0.360921f, 0.111294f, 0.792708f, 0.177001f, 0.605881f, 0.077905f, 0.471113f, 0.086141f, 0.786127f, 0.285256f, 2.108272f, 0.391962f, 1.461919f, +0.025550f, 0.110119f, 0.001133f, 0.156784f, 0.039352f, 0.329098f, 0.115931f, 0.260263f, 0.020765f, 0.147435f, 0.042530f, 0.254556f, 0.133350f, 1.157164f, 0.339408f, 0.830244f, +0.108833f, 0.365162f, 0.003237f, 0.555403f, 0.263445f, 1.715136f, 0.520644f, 1.449005f, 0.154708f, 0.855140f, 0.212569f, 1.577257f, 0.541468f, 3.657889f, 0.924542f, 2.803655f, +0.070638f, 0.180933f, 0.002113f, 0.280438f, 0.107252f, 0.533049f, 0.213180f, 0.458918f, 0.001831f, 0.007726f, 0.002530f, 0.014523f, 0.271212f, 1.398677f, 0.465748f, 1.092468f, +0.142793f, 0.434876f, 0.003499f, 0.619259f, 0.307101f, 1.814778f, 0.499958f, 1.435417f, 0.140138f, 0.703098f, 0.158615f, 1.214128f, 0.637990f, 3.912058f, 0.897364f, 2.807259f, +0.066182f, 0.236652f, 0.003004f, 0.348683f, 0.140751f, 0.976574f, 0.424448f, 0.799233f, 0.048416f, 0.285208f, 0.101508f, 0.509594f, 0.386582f, 2.783191f, 1.007201f, 2.066494f, +0.130875f, 0.364319f, 0.003985f, 0.573436f, 0.437439f, 2.362796f, 0.884942f, 2.065751f, 0.167464f, 0.767972f, 0.235534f, 1.465856f, 0.728734f, 4.084379f, 1.273703f, 3.239669f, +0.009233f, 0.024347f, 0.000293f, 0.057656f, 0.016139f, 0.082579f, 0.034072f, 0.108622f, 0.000170f, 0.000737f, 0.000249f, 0.002115f, 0.028828f, 0.153057f, 0.052582f, 0.182652f, +0.015420f, 0.048346f, 0.000401f, 0.105184f, 0.038179f, 0.232271f, 0.066017f, 0.280692f, 0.010722f, 0.055381f, 0.012890f, 0.146114f, 0.056027f, 0.353678f, 0.083699f, 0.387763f, +0.000382f, 0.001405f, 0.000018f, 0.003162f, 0.000934f, 0.006674f, 0.002992f, 0.008345f, 0.000198f, 0.001199f, 0.000440f, 0.003274f, 0.001813f, 0.013435f, 0.005016f, 0.015241f, +0.020691f, 0.059298f, 0.000669f, 0.142601f, 0.079621f, 0.442749f, 0.171079f, 0.591413f, 0.018759f, 0.088563f, 0.028023f, 0.258273f, 0.093693f, 0.540617f, 0.173933f, 0.655157f, +0.020819f, 0.052983f, 0.000659f, 0.103382f, 0.045061f, 0.222516f, 0.094735f, 0.241166f, 0.000549f, 0.002302f, 0.000803f, 0.005447f, 0.084378f, 0.432353f, 0.153264f, 0.425124f, +0.043657f, 0.132103f, 0.001131f, 0.236813f, 0.133845f, 0.785858f, 0.230474f, 0.782500f, 0.043593f, 0.217310f, 0.052189f, 0.472404f, 0.205902f, 1.254448f, 0.306326f, 1.133223f, +0.012794f, 0.045456f, 0.000614f, 0.084313f, 0.038789f, 0.267398f, 0.123721f, 0.275494f, 0.009523f, 0.055739f, 0.021119f, 0.125373f, 0.078890f, 0.564315f, 0.217401f, 0.527471f, +0.056166f, 0.155344f, 0.001809f, 0.307812f, 0.267612f, 1.436193f, 0.572623f, 1.580703f, 0.073122f, 0.333177f, 0.108780f, 0.800583f, 0.330128f, 1.838398f, 0.610308f, 1.835691f, +0.011429f, 0.031999f, 0.000318f, 0.070837f, 0.016839f, 0.091476f, 0.031124f, 0.112481f, 0.000329f, 0.001520f, 0.000423f, 0.004079f, 0.041928f, 0.236346f, 0.066957f, 0.263659f, +0.024776f, 0.082475f, 0.000565f, 0.167738f, 0.051704f, 0.333965f, 0.078275f, 0.377275f, 0.027038f, 0.148277f, 0.028459f, 0.365700f, 0.105766f, 0.708880f, 0.138340f, 0.726528f, +0.007758f, 0.030321f, 0.000327f, 0.063807f, 0.016009f, 0.121411f, 0.044894f, 0.141916f, 0.006311f, 0.040635f, 0.012304f, 0.103696f, 0.043296f, 0.340712f, 0.104899f, 0.361311f, +0.042107f, 0.128120f, 0.001192f, 0.288020f, 0.136564f, 0.806272f, 0.256910f, 1.006783f, 0.059913f, 0.300318f, 0.078361f, 0.818710f, 0.224015f, 1.372372f, 0.364104f, 1.554709f, +0.030125f, 0.069975f, 0.000858f, 0.160305f, 0.061284f, 0.276213f, 0.115953f, 0.351476f, 0.000782f, 0.002991f, 0.001028f, 0.008309f, 0.123683f, 0.578434f, 0.202183f, 0.667772f, +0.066127f, 0.182630f, 0.001542f, 0.384380f, 0.190547f, 1.021129f, 0.295289f, 1.193763f, 0.064959f, 0.295553f, 0.069988f, 0.754339f, 0.315931f, 1.756794f, 0.423001f, 1.863293f, +0.026838f, 0.087029f, 0.001160f, 0.189525f, 0.076475f, 0.481181f, 0.219526f, 0.582050f, 0.019653f, 0.104985f, 0.039221f, 0.277251f, 0.167636f, 1.094474f, 0.415753f, 1.201101f, +0.067627f, 0.170719f, 0.001960f, 0.397164f, 0.302854f, 1.483469f, 0.583209f, 1.916961f, 0.086616f, 0.360213f, 0.115964f, 1.016222f, 0.402664f, 2.046619f, 0.669941f, 2.399355f, +0.037944f, 0.059100f, 0.000887f, 0.143054f, 0.055692f, 0.168313f, 0.086462f, 0.226298f, 0.000701f, 0.001798f, 0.000757f, 0.005279f, 0.087358f, 0.273951f, 0.117174f, 0.334163f, +0.064927f, 0.120240f, 0.001243f, 0.267392f, 0.134984f, 0.485052f, 0.171642f, 0.599151f, 0.045406f, 0.138527f, 0.040141f, 0.373573f, 0.173948f, 0.648597f, 0.191101f, 0.726852f, +0.001568f, 0.003409f, 0.000056f, 0.007844f, 0.003223f, 0.013598f, 0.007591f, 0.017379f, 0.000817f, 0.002927f, 0.001338f, 0.008168f, 0.005491f, 0.024039f, 0.011174f, 0.027874f, +0.090127f, 0.152561f, 0.002143f, 0.375009f, 0.291205f, 0.956469f, 0.460135f, 1.305921f, 0.082178f, 0.229162f, 0.090277f, 0.683097f, 0.300923f, 1.025595f, 0.410812f, 1.270411f, +0.080150f, 0.120481f, 0.001865f, 0.240290f, 0.145662f, 0.424860f, 0.225200f, 0.470665f, 0.002126f, 0.005265f, 0.002285f, 0.012733f, 0.239523f, 0.724929f, 0.319942f, 0.728592f, +0.172202f, 0.307777f, 0.003282f, 0.563950f, 0.443292f, 1.537351f, 0.561339f, 1.564680f, 0.172936f, 0.509197f, 0.152250f, 1.131442f, 0.598856f, 2.155033f, 0.655179f, 1.989891f, +0.049241f, 0.103333f, 0.001738f, 0.195910f, 0.125348f, 0.510400f, 0.294017f, 0.537498f, 0.036862f, 0.127435f, 0.060113f, 0.292987f, 0.223875f, 0.945906f, 0.453695f, 0.903727f, +0.229178f, 0.374402f, 0.005428f, 0.758298f, 0.916881f, 2.906440f, 1.442755f, 3.269725f, 0.300079f, 0.807609f, 0.328286f, 1.983558f, 0.993261f, 3.267086f, 1.350347f, 3.334519f, +0.045852f, 0.075825f, 0.000938f, 0.171572f, 0.056722f, 0.182007f, 0.077100f, 0.228755f, 0.001329f, 0.003621f, 0.001256f, 0.009937f, 0.124027f, 0.412953f, 0.145653f, 0.470877f, +0.101837f, 0.200236f, 0.001706f, 0.416258f, 0.178445f, 0.680808f, 0.198665f, 0.786130f, 0.111774f, 0.362056f, 0.086515f, 0.912724f, 0.320554f, 1.269024f, 0.308332f, 1.329419f, +0.031113f, 0.071827f, 0.000966f, 0.154498f, 0.053911f, 0.241495f, 0.111177f, 0.288530f, 0.025455f, 0.096811f, 0.036496f, 0.252523f, 0.128035f, 0.595127f, 0.228123f, 0.645083f, +0.179041f, 0.321777f, 0.003728f, 0.739390f, 0.487573f, 1.700299f, 0.674528f, 2.170161f, 0.256213f, 0.758584f, 0.246432f, 2.113801f, 0.702350f, 2.541491f, 0.839493f, 2.942917f, +0.088056f, 0.120813f, 0.001844f, 0.282897f, 0.150412f, 0.400424f, 0.209283f, 0.520816f, 0.002298f, 0.005194f, 0.002223f, 0.014748f, 0.266573f, 0.736380f, 0.320456f, 0.868938f, +0.198039f, 0.323062f, 0.003397f, 0.695005f, 0.479161f, 1.516705f, 0.546064f, 1.812387f, 0.195658f, 0.525815f, 0.155023f, 1.371756f, 0.697662f, 2.291469f, 0.686926f, 2.484201f, +0.078425f, 0.150211f, 0.002492f, 0.334363f, 0.187639f, 0.697355f, 0.396101f, 0.862220f, 0.057757f, 0.182243f, 0.084766f, 0.491936f, 0.361197f, 1.392911f, 0.658763f, 1.562464f, +0.209515f, 0.312404f, 0.004466f, 0.742876f, 0.787831f, 2.279390f, 1.115681f, 3.010690f, 0.269883f, 0.662945f, 0.265716f, 1.911695f, 0.919847f, 2.761531f, 1.125446f, 3.309177f, +0.056729f, 0.087402f, 0.001474f, 0.234057f, 0.066637f, 0.199210f, 0.115008f, 0.296320f, 0.001239f, 0.003146f, 0.001487f, 0.010215f, 0.143949f, 0.446536f, 0.214648f, 0.602600f, +0.057912f, 0.106089f, 0.001232f, 0.261010f, 0.096358f, 0.342506f, 0.136212f, 0.468063f, 0.047900f, 0.144555f, 0.047076f, 0.431285f, 0.171007f, 0.630732f, 0.208855f, 0.781995f, +0.001864f, 0.004009f, 0.000073f, 0.010206f, 0.003067f, 0.012799f, 0.008030f, 0.018098f, 0.001149f, 0.004072f, 0.002092f, 0.012570f, 0.007196f, 0.031161f, 0.016279f, 0.039974f, +0.081282f, 0.136099f, 0.002149f, 0.370119f, 0.210181f, 0.682875f, 0.369204f, 1.031513f, 0.087654f, 0.241787f, 0.107048f, 0.797372f, 0.299116f, 1.008407f, 0.453956f, 1.381950f, +0.076362f, 0.113545f, 0.001975f, 0.250538f, 0.111066f, 0.320446f, 0.190892f, 0.392744f, 0.002396f, 0.005868f, 0.002863f, 0.015702f, 0.251519f, 0.753000f, 0.373492f, 0.837283f, +0.097882f, 0.173051f, 0.002074f, 0.350806f, 0.201656f, 0.691782f, 0.283878f, 0.778950f, 0.116260f, 0.338612f, 0.113785f, 0.832410f, 0.375175f, 1.335490f, 0.456307f, 1.364281f, +0.037309f, 0.077445f, 0.001464f, 0.162443f, 0.076008f, 0.306144f, 0.198197f, 0.356681f, 0.033032f, 0.112960f, 0.059885f, 0.287324f, 0.186954f, 0.781363f, 0.421191f, 0.825905f, +0.131712f, 0.212846f, 0.003468f, 0.476931f, 0.421720f, 1.322354f, 0.737716f, 1.645832f, 0.203971f, 0.543010f, 0.248067f, 1.475502f, 0.629165f, 2.047091f, 0.950894f, 2.311521f, +0.004318f, 0.007064f, 0.000098f, 0.017683f, 0.004275f, 0.013570f, 0.006460f, 0.018868f, 0.000148f, 0.000399f, 0.000156f, 0.001211f, 0.012874f, 0.042400f, 0.016807f, 0.053489f, +0.005722f, 0.011129f, 0.000107f, 0.025595f, 0.008024f, 0.030282f, 0.009931f, 0.038685f, 0.007428f, 0.023799f, 0.006391f, 0.066376f, 0.019851f, 0.077737f, 0.021227f, 0.090096f, +0.002330f, 0.005321f, 0.000080f, 0.012663f, 0.003231f, 0.014318f, 0.007408f, 0.018926f, 0.002255f, 0.008483f, 0.003594f, 0.024479f, 0.010569f, 0.048594f, 0.020934f, 0.058274f, +0.010171f, 0.018082f, 0.000235f, 0.045968f, 0.022168f, 0.076468f, 0.034093f, 0.107978f, 0.017215f, 0.050417f, 0.018407f, 0.155427f, 0.043977f, 0.157411f, 0.058435f, 0.201656f, +0.117036f, 0.158835f, 0.002725f, 0.411481f, 0.159993f, 0.421320f, 0.247477f, 0.606266f, 0.003612f, 0.008076f, 0.003884f, 0.025371f, 0.390502f, 1.067047f, 0.521867f, 1.393023f, +0.157035f, 0.253400f, 0.002994f, 0.603110f, 0.304078f, 0.952094f, 0.385241f, 1.258687f, 0.183493f, 0.487789f, 0.161623f, 1.407875f, 0.609732f, 1.980993f, 0.667404f, 2.375985f, +0.082893f, 0.157051f, 0.002928f, 0.386763f, 0.158725f, 0.583513f, 0.372489f, 0.798183f, 0.072201f, 0.225355f, 0.117801f, 0.672998f, 0.420781f, 1.605131f, 0.853152f, 1.991980f, +0.167977f, 0.247758f, 0.003980f, 0.651800f, 0.505506f, 1.446729f, 0.795827f, 2.114085f, 0.255911f, 0.621823f, 0.280103f, 1.983790f, 0.812829f, 2.413841f, 1.105589f, 3.200123f, +0.163500f, 0.475424f, 0.005458f, 0.761728f, 0.150794f, 0.850807f, 0.334429f, 0.757178f, 0.002953f, 0.014147f, 0.004554f, 0.027486f, 0.308419f, 1.805664f, 0.590968f, 1.457896f, +0.172431f, 0.596158f, 0.004714f, 0.877537f, 0.225263f, 1.511188f, 0.409187f, 1.235582f, 0.117916f, 0.671615f, 0.148917f, 1.198857f, 0.378510f, 2.634850f, 0.594036f, 1.954482f, +0.006709f, 0.027236f, 0.000340f, 0.041482f, 0.008668f, 0.068271f, 0.029164f, 0.057757f, 0.003420f, 0.022872f, 0.008001f, 0.042244f, 0.019255f, 0.157372f, 0.055975f, 0.120786f, +0.212087f, 0.670234f, 0.007205f, 1.090506f, 0.430602f, 2.640406f, 0.971970f, 2.386277f, 0.189098f, 0.984464f, 0.296757f, 1.942423f, 0.580206f, 3.691699f, 1.131519f, 3.026908f, +0.290344f, 0.814802f, 0.009651f, 1.075659f, 0.331570f, 1.805502f, 0.732299f, 1.323942f, 0.007531f, 0.034817f, 0.011564f, 0.055739f, 0.710930f, 4.016970f, 1.356571f, 2.672345f, +0.384474f, 1.282890f, 0.010468f, 1.555959f, 0.621924f, 4.026641f, 1.125027f, 2.712689f, 0.377564f, 2.075453f, 0.474845f, 3.052558f, 1.095520f, 7.359949f, 1.712175f, 4.498365f, +0.177169f, 0.694097f, 0.008935f, 0.871049f, 0.283396f, 2.154321f, 0.949598f, 1.501694f, 0.129692f, 0.837037f, 0.302130f, 1.273825f, 0.659985f, 5.205933f, 1.910652f, 3.292246f, +0.453391f, 1.382802f, 0.015339f, 1.853814f, 1.139802f, 6.745290f, 2.562120f, 5.022906f, 0.580510f, 2.916739f, 0.907226f, 4.741828f, 1.610017f, 9.886685f, 3.126820f, 6.679253f, +0.102494f, 0.316427f, 0.002995f, 0.473928f, 0.079672f, 0.477272f, 0.154703f, 0.397058f, 0.002905f, 0.014777f, 0.003922f, 0.026840f, 0.227155f, 1.411987f, 0.381082f, 1.065716f, +0.140301f, 0.515016f, 0.003358f, 0.708673f, 0.154482f, 1.100326f, 0.245689f, 0.840998f, 0.150581f, 0.910604f, 0.166499f, 1.519488f, 0.361847f, 2.674343f, 0.497204f, 1.854445f, +0.069076f, 0.297712f, 0.003063f, 0.423874f, 0.075211f, 0.628976f, 0.221568f, 0.497419f, 0.055263f, 0.392380f, 0.113188f, 0.677468f, 0.232908f, 2.021095f, 0.592807f, 1.450098f, +0.218564f, 0.733337f, 0.006501f, 1.115389f, 0.374009f, 2.434956f, 0.739152f, 2.057133f, 0.305845f, 1.690543f, 0.420231f, 3.118111f, 0.702502f, 4.745755f, 1.199503f, 3.637469f, +0.338807f, 0.867817f, 0.010136f, 1.345081f, 0.363658f, 1.807393f, 0.722825f, 1.556041f, 0.008645f, 0.036481f, 0.011947f, 0.068569f, 0.840381f, 4.333962f, 1.443175f, 3.385138f, +0.469634f, 1.430273f, 0.011507f, 2.036691f, 0.714016f, 4.219402f, 1.162414f, 3.337378f, 0.453712f, 2.276354f, 0.513534f, 3.930866f, 1.355574f, 8.312176f, 1.906682f, 5.964747f, +0.299706f, 1.071679f, 0.013603f, 1.579009f, 0.450589f, 3.126320f, 1.358792f, 2.558597f, 0.215833f, 1.271414f, 0.452508f, 2.271691f, 1.130972f, 8.142423f, 2.946638f, 6.045676f, +0.440245f, 1.225516f, 0.013405f, 1.928956f, 1.040230f, 5.618725f, 2.104392f, 4.912354f, 0.554534f, 2.543042f, 0.779941f, 4.853995f, 1.583662f, 8.876052f, 2.767975f, 7.040354f, +0.070807f, 0.186714f, 0.002250f, 0.442159f, 0.087497f, 0.447690f, 0.184718f, 0.588881f, 0.001280f, 0.005561f, 0.001879f, 0.015970f, 0.142827f, 0.758302f, 0.260511f, 0.904930f, +0.081087f, 0.254235f, 0.002110f, 0.553125f, 0.141931f, 0.863464f, 0.245417f, 1.043471f, 0.055504f, 0.286687f, 0.066725f, 0.756376f, 0.190338f, 1.201546f, 0.284351f, 1.317343f, +0.002763f, 0.010171f, 0.000133f, 0.022896f, 0.004782f, 0.034159f, 0.015317f, 0.042713f, 0.001410f, 0.008549f, 0.003139f, 0.023339f, 0.008479f, 0.062843f, 0.023463f, 0.071291f, +0.111288f, 0.318931f, 0.003599f, 0.766975f, 0.302733f, 1.683417f, 0.650475f, 2.248666f, 0.099319f, 0.468902f, 0.148368f, 1.367444f, 0.325556f, 1.878477f, 0.604364f, 2.276470f, +0.148356f, 0.377556f, 0.004694f, 0.736695f, 0.226997f, 1.120930f, 0.477228f, 1.214878f, 0.003852f, 0.016149f, 0.005630f, 0.038210f, 0.388445f, 1.990388f, 0.705568f, 1.957108f, +0.213324f, 0.645503f, 0.005529f, 1.157151f, 0.462339f, 2.714581f, 0.796123f, 2.702980f, 0.209689f, 1.045285f, 0.251033f, 2.272315f, 0.649983f, 3.959982f, 0.966994f, 3.577306f, +0.086081f, 0.305827f, 0.004132f, 0.567259f, 0.184486f, 1.271795f, 0.588442f, 1.310301f, 0.063073f, 0.369159f, 0.139868f, 0.830350f, 0.342896f, 2.452809f, 0.944940f, 2.292665f, +0.280699f, 0.776362f, 0.009040f, 1.538344f, 0.945470f, 5.074062f, 2.023074f, 5.584614f, 0.359741f, 1.639134f, 0.535168f, 3.938635f, 1.065879f, 5.935598f, 1.970489f, 5.926860f, +0.051083f, 0.143017f, 0.001421f, 0.316600f, 0.053203f, 0.289023f, 0.098338f, 0.355388f, 0.001449f, 0.006685f, 0.001863f, 0.017947f, 0.121063f, 0.682425f, 0.193330f, 0.761288f, +0.075931f, 0.252764f, 0.001730f, 0.514071f, 0.112018f, 0.723546f, 0.169585f, 0.817379f, 0.081572f, 0.447339f, 0.085857f, 1.103284f, 0.209407f, 1.403527f, 0.273902f, 1.438469f, +0.032736f, 0.127949f, 0.001382f, 0.269253f, 0.047757f, 0.362181f, 0.133924f, 0.423347f, 0.026215f, 0.168795f, 0.051111f, 0.430750f, 0.118032f, 0.928832f, 0.285970f, 0.984988f, +0.131987f, 0.401599f, 0.003737f, 0.902815f, 0.302612f, 1.786617f, 0.569287f, 2.230929f, 0.184870f, 0.926677f, 0.241795f, 2.526252f, 0.453639f, 2.779100f, 0.737322f, 3.148338f, +0.225528f, 0.523857f, 0.006422f, 1.200095f, 0.324333f, 1.461799f, 0.613657f, 1.860113f, 0.005760f, 0.022043f, 0.007577f, 0.061236f, 0.598182f, 2.797557f, 0.977845f, 3.229633f, +0.339458f, 0.937524f, 0.007918f, 1.973202f, 0.691490f, 3.705658f, 1.071600f, 4.332143f, 0.328262f, 1.493537f, 0.353674f, 3.811952f, 1.047755f, 5.826232f, 1.402841f, 6.179425f, +0.189701f, 0.615141f, 0.008196f, 1.339609f, 0.382125f, 2.404333f, 1.096911f, 2.908346f, 0.136742f, 0.730483f, 0.272902f, 1.929102f, 0.765482f, 4.997738f, 1.898470f, 5.484635f, +0.355072f, 0.896350f, 0.010291f, 2.085279f, 1.124094f, 5.506144f, 2.164679f, 7.115123f, 0.447676f, 1.861766f, 0.599364f, 5.252353f, 1.365823f, 6.942058f, 2.272415f, 8.138528f, +0.152777f, 0.237957f, 0.003570f, 0.575986f, 0.158519f, 0.479076f, 0.246099f, 0.644120f, 0.002778f, 0.007128f, 0.002998f, 0.020923f, 0.227232f, 0.712593f, 0.304790f, 0.869215f, +0.179258f, 0.331972f, 0.003431f, 0.738247f, 0.263457f, 0.946708f, 0.335005f, 1.169404f, 0.123406f, 0.376494f, 0.109097f, 1.015313f, 0.310263f, 1.156871f, 0.340858f, 1.296451f, +0.005960f, 0.012958f, 0.000211f, 0.029817f, 0.008661f, 0.036543f, 0.020401f, 0.046705f, 0.003058f, 0.010955f, 0.005008f, 0.030568f, 0.013485f, 0.059038f, 0.027443f, 0.068456f, +0.254503f, 0.430806f, 0.006053f, 1.058960f, 0.581315f, 1.909341f, 0.918539f, 2.606928f, 0.228435f, 0.637018f, 0.250949f, 1.898853f, 0.548971f, 1.870985f, 0.749442f, 2.317601f, +0.299862f, 0.450752f, 0.006978f, 0.898992f, 0.385248f, 1.123675f, 0.595612f, 1.244822f, 0.007830f, 0.019390f, 0.008416f, 0.046896f, 0.578927f, 1.752155f, 0.773301f, 1.761010f, +0.441774f, 0.789586f, 0.008420f, 1.446783f, 0.803947f, 2.788109f, 1.018034f, 2.837672f, 0.436737f, 1.285935f, 0.384495f, 2.857363f, 0.992525f, 3.571683f, 1.085872f, 3.297981f, +0.173937f, 0.365007f, 0.006141f, 0.692021f, 0.313008f, 1.274526f, 0.734194f, 1.342194f, 0.128178f, 0.443121f, 0.209028f, 1.018786f, 0.510889f, 2.158581f, 1.035342f, 2.062327f, +0.601340f, 0.982393f, 0.014242f, 1.989695f, 1.700725f, 5.391163f, 2.676170f, 6.065021f, 0.775093f, 2.086021f, 0.847948f, 5.123449f, 1.683707f, 5.538139f, 2.289014f, 5.652446f, +0.107593f, 0.177926f, 0.002201f, 0.402601f, 0.094092f, 0.301918f, 0.127896f, 0.379466f, 0.003070f, 0.008365f, 0.002902f, 0.022953f, 0.188018f, 0.626016f, 0.220803f, 0.713825f, +0.163861f, 0.322189f, 0.002746f, 0.669780f, 0.202978f, 0.774406f, 0.225977f, 0.894207f, 0.177043f, 0.573477f, 0.137035f, 1.445705f, 0.333217f, 1.319155f, 0.320513f, 1.381936f, +0.068931f, 0.159133f, 0.002139f, 0.342290f, 0.084435f, 0.378228f, 0.174124f, 0.451894f, 0.055516f, 0.211138f, 0.079596f, 0.550735f, 0.183256f, 0.851799f, 0.326510f, 0.923300f, +0.294650f, 0.529553f, 0.006135f, 1.216823f, 0.567241f, 1.978125f, 0.784745f, 2.524762f, 0.415074f, 1.228933f, 0.399229f, 3.424434f, 0.746731f, 2.702086f, 0.892539f, 3.128878f, +0.346104f, 0.474854f, 0.007248f, 1.111926f, 0.417931f, 1.112607f, 0.581506f, 1.447123f, 0.008891f, 0.020095f, 0.008601f, 0.057062f, 0.676893f, 1.869844f, 0.813714f, 2.206440f, +0.533752f, 0.870713f, 0.009155f, 1.873168f, 0.912945f, 2.889776f, 1.040415f, 3.453139f, 0.519106f, 1.395058f, 0.411296f, 3.639454f, 1.214760f, 3.989875f, 1.196066f, 4.325457f, +0.291036f, 0.557433f, 0.009247f, 1.240818f, 0.492253f, 1.829441f, 1.039131f, 2.261946f, 0.210991f, 0.665750f, 0.309658f, 1.797086f, 0.865946f, 3.339411f, 1.579339f, 3.745902f, +0.577549f, 0.861173f, 0.012310f, 2.047808f, 1.535255f, 4.441873f, 2.174139f, 5.866963f, 0.732351f, 1.798959f, 0.721044f, 5.187552f, 1.638118f, 4.917897f, 2.004260f, 5.893177f, +0.094125f, 0.145017f, 0.002445f, 0.388349f, 0.104891f, 0.313573f, 0.181032f, 0.466432f, 0.001543f, 0.003916f, 0.001851f, 0.012718f, 0.279128f, 0.865865f, 0.416217f, 1.168486f, +0.084524f, 0.154838f, 0.001798f, 0.380947f, 0.133420f, 0.474244f, 0.188603f, 0.648095f, 0.052457f, 0.158309f, 0.051555f, 0.472318f, 0.291686f, 1.075835f, 0.356242f, 1.333843f, +0.003213f, 0.006910f, 0.000127f, 0.017591f, 0.005015f, 0.020929f, 0.013131f, 0.029594f, 0.001486f, 0.005266f, 0.002706f, 0.016258f, 0.014495f, 0.062770f, 0.032791f, 0.080523f, +0.120348f, 0.201513f, 0.003182f, 0.548009f, 0.295235f, 0.959213f, 0.518609f, 1.448934f, 0.097382f, 0.268624f, 0.118929f, 0.885874f, 0.517584f, 1.744925f, 0.785516f, 2.391295f, +0.105395f, 0.156715f, 0.002726f, 0.345794f, 0.145429f, 0.419590f, 0.249953f, 0.514257f, 0.002481f, 0.006077f, 0.002965f, 0.016262f, 0.405703f, 1.214597f, 0.602447f, 1.350546f, +0.118837f, 0.210100f, 0.002518f, 0.425909f, 0.232268f, 0.796795f, 0.326971f, 0.897196f, 0.105911f, 0.308473f, 0.103657f, 0.758318f, 0.532327f, 1.894893f, 0.647442f, 1.935744f, +0.053494f, 0.111042f, 0.002099f, 0.232913f, 0.103390f, 0.416433f, 0.269599f, 0.485177f, 0.035538f, 0.121529f, 0.064428f, 0.309121f, 0.313273f, 1.309302f, 0.705774f, 1.383939f, +0.162225f, 0.262154f, 0.004271f, 0.587417f, 0.492767f, 1.545130f, 0.861999f, 1.923105f, 0.188505f, 0.501837f, 0.229257f, 1.363623f, 0.905626f, 2.946601f, 1.368725f, 3.327223f, +0.011812f, 0.019321f, 0.000269f, 0.048368f, 0.011094f, 0.035213f, 0.016764f, 0.048963f, 0.000304f, 0.000819f, 0.000319f, 0.002486f, 0.041154f, 0.135540f, 0.053728f, 0.170987f, +0.013767f, 0.026777f, 0.000256f, 0.061584f, 0.018316f, 0.069124f, 0.022669f, 0.088305f, 0.013410f, 0.042967f, 0.011539f, 0.119836f, 0.055820f, 0.218590f, 0.059689f, 0.253344f, +0.006621f, 0.015121f, 0.000228f, 0.035982f, 0.008711f, 0.038599f, 0.019971f, 0.051021f, 0.004808f, 0.018086f, 0.007663f, 0.052193f, 0.035098f, 0.161373f, 0.069519f, 0.193520f, +0.024827f, 0.044137f, 0.000575f, 0.112204f, 0.051333f, 0.177076f, 0.078949f, 0.250043f, 0.031530f, 0.092341f, 0.033713f, 0.284671f, 0.125450f, 0.449035f, 0.166693f, 0.575251f, +0.183165f, 0.248582f, 0.004264f, 0.643982f, 0.237548f, 0.625551f, 0.367439f, 0.900149f, 0.004242f, 0.009484f, 0.004562f, 0.029793f, 0.714234f, 1.951647f, 0.954504f, 2.547863f, +0.216185f, 0.348849f, 0.004122f, 0.830285f, 0.397139f, 1.243476f, 0.503142f, 1.643900f, 0.189546f, 0.503880f, 0.166955f, 1.454315f, 0.980988f, 3.187186f, 1.073776f, 3.822681f, +0.134770f, 0.255337f, 0.004760f, 0.628808f, 0.244820f, 0.900018f, 0.574531f, 1.231128f, 0.088081f, 0.274919f, 0.143710f, 0.821015f, 0.799509f, 3.049845f, 1.621039f, 3.784882f, +0.234596f, 0.346018f, 0.005559f, 0.910301f, 0.669768f, 1.916836f, 1.054427f, 2.801046f, 0.268178f, 0.651630f, 0.293530f, 2.078885f, 1.326672f, 3.939791f, 1.804506f, 5.223135f, +0.124801f, 0.362896f, 0.004166f, 0.581434f, 0.109197f, 0.616111f, 0.242177f, 0.548309f, 0.001691f, 0.008103f, 0.002608f, 0.015743f, 0.275129f, 1.610763f, 0.527180f, 1.300533f, +0.115777f, 0.400284f, 0.003165f, 0.589214f, 0.143491f, 0.962616f, 0.260649f, 0.787057f, 0.059408f, 0.338370f, 0.075027f, 0.604003f, 0.297015f, 2.067555f, 0.466137f, 1.533673f, +0.005320f, 0.021597f, 0.000269f, 0.032893f, 0.006520f, 0.051359f, 0.021939f, 0.043449f, 0.002035f, 0.013609f, 0.004760f, 0.025135f, 0.017844f, 0.145839f, 0.051873f, 0.111934f, +0.144465f, 0.456535f, 0.004908f, 0.742807f, 0.278260f, 1.706261f, 0.628098f, 1.542040f, 0.096649f, 0.503166f, 0.151674f, 0.992785f, 0.461874f, 2.938784f, 0.900748f, 2.409576f, +0.184356f, 0.517364f, 0.006128f, 0.682998f, 0.199732f, 1.087600f, 0.441123f, 0.797518f, 0.003588f, 0.016588f, 0.005509f, 0.026556f, 0.527552f, 2.980826f, 1.006655f, 1.983036f, +0.214743f, 0.716540f, 0.005847f, 0.869059f, 0.329545f, 2.133639f, 0.596130f, 1.437402f, 0.158236f, 0.869817f, 0.199007f, 1.279319f, 0.715097f, 4.804183f, 1.117617f, 2.936293f, +0.116864f, 0.457840f, 0.005894f, 0.574561f, 0.177343f, 1.348128f, 0.594239f, 0.939728f, 0.064190f, 0.414288f, 0.149538f, 0.630475f, 0.508770f, 4.013158f, 1.472887f, 2.537932f, +0.256900f, 0.783522f, 0.008691f, 1.050406f, 0.612699f, 3.625924f, 1.377265f, 2.700058f, 0.246811f, 1.240088f, 0.385719f, 2.016048f, 1.066143f, 6.546897f, 2.070560f, 4.422957f, +0.128974f, 0.398180f, 0.003769f, 0.596374f, 0.095113f, 0.569770f, 0.184686f, 0.474010f, 0.002743f, 0.013953f, 0.003704f, 0.025342f, 0.334058f, 2.076493f, 0.560426f, 1.567261f, +0.155301f, 0.570077f, 0.003717f, 0.784438f, 0.162225f, 1.155476f, 0.258003f, 0.883151f, 0.125068f, 0.756321f, 0.138290f, 1.262043f, 0.468093f, 3.459582f, 0.643192f, 2.398945f, +0.090299f, 0.389182f, 0.004004f, 0.554105f, 0.093275f, 0.780040f, 0.274783f, 0.616886f, 0.054207f, 0.384881f, 0.111025f, 0.664521f, 0.355823f, 3.087706f, 0.905655f, 2.215372f, +0.245432f, 0.823486f, 0.007300f, 1.252504f, 0.398439f, 2.594006f, 0.787433f, 2.191504f, 0.257702f, 1.424437f, 0.354083f, 2.627292f, 0.921922f, 6.228046f, 1.574156f, 4.773598f, +0.243936f, 0.624817f, 0.007298f, 0.968441f, 0.248396f, 1.234537f, 0.493724f, 1.062852f, 0.004671f, 0.019708f, 0.006454f, 0.037044f, 0.707123f, 3.646729f, 1.214332f, 2.848360f, +0.297434f, 0.905838f, 0.007288f, 1.289901f, 0.429009f, 2.535183f, 0.698424f, 2.005228f, 0.215613f, 1.081771f, 0.244042f, 1.868029f, 1.003340f, 6.152333f, 1.411248f, 4.414862f, +0.224166f, 0.801566f, 0.010174f, 1.181025f, 0.319729f, 2.218374f, 0.964172f, 1.815529f, 0.121131f, 0.713551f, 0.253959f, 1.274933f, 0.988598f, 7.117406f, 2.575697f, 5.284609f, +0.282856f, 0.787391f, 0.008612f, 1.239350f, 0.634056f, 3.424809f, 1.282700f, 2.994251f, 0.267340f, 1.225996f, 0.376008f, 2.340102f, 1.189126f, 6.664769f, 2.078391f, 5.286396f, +0.010688f, 0.028185f, 0.000340f, 0.066744f, 0.012530f, 0.064112f, 0.026453f, 0.084332f, 0.000145f, 0.000630f, 0.000213f, 0.001809f, 0.025197f, 0.133774f, 0.045958f, 0.159641f, +0.010767f, 0.033758f, 0.000280f, 0.073446f, 0.017879f, 0.108771f, 0.030915f, 0.131447f, 0.005530f, 0.028564f, 0.006648f, 0.075361f, 0.029537f, 0.186457f, 0.044126f, 0.204426f, +0.000433f, 0.001595f, 0.000021f, 0.003590f, 0.000711f, 0.005082f, 0.002279f, 0.006354f, 0.000166f, 0.001006f, 0.000369f, 0.002746f, 0.001554f, 0.011517f, 0.004300f, 0.013065f, +0.014991f, 0.042962f, 0.000485f, 0.103315f, 0.038688f, 0.215131f, 0.083127f, 0.287366f, 0.010039f, 0.047395f, 0.014996f, 0.138216f, 0.051251f, 0.295722f, 0.095143f, 0.358377f, +0.018629f, 0.047409f, 0.000589f, 0.092506f, 0.027041f, 0.133532f, 0.056850f, 0.144724f, 0.000363f, 0.001522f, 0.000530f, 0.003600f, 0.057004f, 0.292087f, 0.103541f, 0.287203f, +0.023563f, 0.071299f, 0.000611f, 0.127814f, 0.048448f, 0.284457f, 0.083425f, 0.283242f, 0.017379f, 0.086633f, 0.020806f, 0.188330f, 0.083904f, 0.511181f, 0.124826f, 0.461782f, +0.011229f, 0.039894f, 0.000539f, 0.073997f, 0.022831f, 0.157389f, 0.072822f, 0.162154f, 0.006174f, 0.036133f, 0.013690f, 0.081275f, 0.052274f, 0.373928f, 0.144055f, 0.349514f, +0.031453f, 0.086994f, 0.001013f, 0.172378f, 0.100508f, 0.539399f, 0.215063f, 0.593673f, 0.030247f, 0.137818f, 0.044997f, 0.331159f, 0.139582f, 0.777294f, 0.258045f, 0.776150f, +0.012712f, 0.035590f, 0.000354f, 0.078787f, 0.012560f, 0.068234f, 0.023216f, 0.083902f, 0.000271f, 0.001248f, 0.000348f, 0.003351f, 0.035208f, 0.198468f, 0.056226f, 0.221404f, +0.016621f, 0.055330f, 0.000379f, 0.112531f, 0.023263f, 0.150260f, 0.035218f, 0.169746f, 0.013398f, 0.073477f, 0.014102f, 0.181218f, 0.053572f, 0.359057f, 0.070071f, 0.367996f, +0.008463f, 0.033077f, 0.000357f, 0.069607f, 0.011713f, 0.088827f, 0.032845f, 0.103828f, 0.005085f, 0.032743f, 0.009914f, 0.083557f, 0.035660f, 0.280623f, 0.086399f, 0.297589f, +0.029310f, 0.089183f, 0.000830f, 0.200488f, 0.063753f, 0.376398f, 0.119935f, 0.470004f, 0.030805f, 0.154412f, 0.040290f, 0.420949f, 0.117732f, 0.721252f, 0.191355f, 0.817079f, +0.032112f, 0.074589f, 0.000914f, 0.170874f, 0.043811f, 0.197459f, 0.082892f, 0.251262f, 0.000615f, 0.002355f, 0.000810f, 0.006542f, 0.099538f, 0.465515f, 0.162714f, 0.537413f, +0.042516f, 0.117422f, 0.000992f, 0.247138f, 0.082164f, 0.440312f, 0.127329f, 0.514751f, 0.030850f, 0.140361f, 0.033238f, 0.358244f, 0.153363f, 0.852804f, 0.205338f, 0.904502f, +0.028059f, 0.090988f, 0.001212f, 0.198148f, 0.053622f, 0.337390f, 0.153925f, 0.408116f, 0.015177f, 0.081075f, 0.030289f, 0.214107f, 0.132324f, 0.863929f, 0.328177f, 0.948095f, +0.045115f, 0.113890f, 0.001308f, 0.264955f, 0.135499f, 0.663716f, 0.260933f, 0.857664f, 0.042681f, 0.177499f, 0.057143f, 0.500755f, 0.202813f, 1.030836f, 0.337434f, 1.208502f, +0.191721f, 0.298614f, 0.004480f, 0.722810f, 0.188721f, 0.570353f, 0.292988f, 0.766843f, 0.002616f, 0.006712f, 0.002823f, 0.019702f, 0.333254f, 1.045077f, 0.447000f, 1.274774f, +0.197879f, 0.366455f, 0.003787f, 0.814932f, 0.275903f, 0.991431f, 0.350831f, 1.224647f, 0.102216f, 0.311847f, 0.090364f, 0.840975f, 0.400260f, 1.492443f, 0.439731f, 1.672511f, +0.007769f, 0.016893f, 0.000275f, 0.038871f, 0.010712f, 0.045195f, 0.025231f, 0.057764f, 0.002992f, 0.010716f, 0.004899f, 0.029901f, 0.020546f, 0.089947f, 0.041810f, 0.104297f, +0.285005f, 0.482438f, 0.006778f, 1.185875f, 0.617586f, 2.028476f, 0.975853f, 2.769590f, 0.191949f, 0.535273f, 0.210867f, 1.595565f, 0.718460f, 2.448631f, 0.980824f, 3.033136f, +0.313024f, 0.470537f, 0.007284f, 0.938452f, 0.381526f, 1.112817f, 0.589857f, 1.232793f, 0.006133f, 0.015188f, 0.006592f, 0.036733f, 0.706275f, 2.137579f, 0.943406f, 2.148382f, +0.405661f, 0.725040f, 0.007731f, 1.328514f, 0.700353f, 2.428843f, 0.886853f, 2.472020f, 0.300917f, 0.886024f, 0.264922f, 1.968757f, 1.065118f, 3.832916f, 1.165293f, 3.539196f, +0.188624f, 0.395829f, 0.006659f, 0.750456f, 0.322024f, 1.311238f, 0.755342f, 1.380854f, 0.104300f, 0.360572f, 0.170088f, 0.828996f, 0.647479f, 2.735695f, 1.312149f, 2.613706f, +0.560174f, 0.915141f, 0.013267f, 1.853486f, 1.503017f, 4.764444f, 2.365067f, 5.359967f, 0.541777f, 1.458094f, 0.592701f, 3.581205f, 1.833003f, 6.029209f, 2.491983f, 6.153653f, +0.222589f, 0.368093f, 0.004554f, 0.832899f, 0.184670f, 0.592563f, 0.251016f, 0.744762f, 0.004766f, 0.012985f, 0.004504f, 0.035630f, 0.454580f, 1.513550f, 0.533847f, 1.725850f, +0.298194f, 0.586321f, 0.004997f, 1.218867f, 0.350429f, 1.336965f, 0.390136f, 1.543795f, 0.241751f, 0.783077f, 0.187120f, 1.974095f, 0.708672f, 2.805524f, 0.681653f, 2.939045f, +0.148143f, 0.342000f, 0.004598f, 0.735633f, 0.172154f, 0.771166f, 0.355021f, 0.921364f, 0.089526f, 0.340484f, 0.128358f, 0.888125f, 0.460276f, 2.139430f, 0.820082f, 2.319018f, +0.543966f, 0.977628f, 0.011326f, 2.246425f, 0.993481f, 3.464537f, 1.374422f, 4.421930f, 0.574982f, 1.702381f, 0.553033f, 4.743701f, 1.611100f, 5.829849f, 1.925687f, 6.750669f, +0.409679f, 0.562078f, 0.008579f, 1.316171f, 0.469319f, 1.249410f, 0.653007f, 1.625059f, 0.007897f, 0.017848f, 0.007639f, 0.050682f, 0.936375f, 2.586638f, 1.125646f, 3.052266f, +0.555754f, 0.906605f, 0.009532f, 1.950383f, 0.901809f, 2.854528f, 1.027724f, 3.411019f, 0.405567f, 1.089932f, 0.321337f, 2.843435f, 1.478181f, 4.855077f, 1.455432f, 5.263429f, +0.357876f, 0.685455f, 0.011370f, 1.525788f, 0.574250f, 2.134182f, 1.212225f, 2.638732f, 0.194677f, 0.614273f, 0.285715f, 1.658131f, 1.244431f, 4.798987f, 2.269630f, 5.383147f, +0.610059f, 0.909648f, 0.013003f, 2.163079f, 1.538476f, 4.451192f, 2.178700f, 5.879272f, 0.580452f, 1.425832f, 0.571491f, 4.111588f, 2.022190f, 6.070946f, 2.474178f, 7.274890f, +0.118107f, 0.181966f, 0.003068f, 0.487296f, 0.149214f, 0.446075f, 0.257528f, 0.663527f, 0.002405f, 0.006104f, 0.002886f, 0.019821f, 0.405757f, 1.258675f, 0.605039f, 1.698583f, +0.099486f, 0.182247f, 0.002117f, 0.448382f, 0.178034f, 0.632826f, 0.251669f, 0.864810f, 0.076691f, 0.231443f, 0.075372f, 0.690518f, 0.397732f, 1.466970f, 0.485759f, 1.818781f, +0.003174f, 0.006826f, 0.000125f, 0.017377f, 0.005616f, 0.023438f, 0.014706f, 0.033142f, 0.001824f, 0.006462f, 0.003320f, 0.019948f, 0.016588f, 0.071833f, 0.037526f, 0.092150f, +0.131090f, 0.219500f, 0.003466f, 0.596924f, 0.364584f, 1.184527f, 0.640427f, 1.789282f, 0.131755f, 0.363440f, 0.160908f, 1.198561f, 0.653137f, 2.201914f, 0.991239f, 3.017566f, +0.164712f, 0.244915f, 0.004261f, 0.540408f, 0.257664f, 0.743411f, 0.442856f, 0.911137f, 0.004816f, 0.011797f, 0.005755f, 0.031567f, 0.734523f, 2.199020f, 1.090726f, 2.445156f, +0.174208f, 0.307994f, 0.003691f, 0.624359f, 0.386016f, 1.324228f, 0.543407f, 1.491088f, 0.192849f, 0.561683f, 0.188744f, 1.380784f, 0.904040f, 3.218060f, 1.099538f, 3.287437f, +0.065814f, 0.136616f, 0.002583f, 0.286555f, 0.144208f, 0.580843f, 0.376038f, 0.676727f, 0.054308f, 0.185717f, 0.098456f, 0.472390f, 0.446509f, 1.866151f, 1.005941f, 1.972532f, +0.220081f, 0.355649f, 0.005794f, 0.796913f, 0.757889f, 2.376452f, 1.325777f, 2.957786f, 0.317647f, 0.845638f, 0.386319f, 2.297821f, 1.423333f, 4.631042f, 2.151165f, 5.229249f, +0.016520f, 0.027023f, 0.000376f, 0.067647f, 0.017590f, 0.055832f, 0.026581f, 0.077635f, 0.000528f, 0.001423f, 0.000555f, 0.004319f, 0.066679f, 0.219609f, 0.087052f, 0.277042f, +0.018061f, 0.035129f, 0.000336f, 0.080793f, 0.027242f, 0.102809f, 0.033716f, 0.131337f, 0.021852f, 0.070016f, 0.018803f, 0.195276f, 0.084836f, 0.332220f, 0.090716f, 0.385040f, +0.007290f, 0.016648f, 0.000252f, 0.039618f, 0.010873f, 0.048181f, 0.024928f, 0.063686f, 0.006575f, 0.024735f, 0.010479f, 0.071379f, 0.044768f, 0.205838f, 0.088674f, 0.246842f, +0.030142f, 0.053586f, 0.000698f, 0.136226f, 0.070656f, 0.243730f, 0.108666f, 0.344163f, 0.047547f, 0.139253f, 0.050840f, 0.429291f, 0.176447f, 0.631572f, 0.234456f, 0.809096f, +0.242651f, 0.329315f, 0.005649f, 0.853128f, 0.356772f, 0.939512f, 0.551856f, 1.351930f, 0.006980f, 0.015605f, 0.007506f, 0.049025f, 1.096159f, 2.995259f, 1.464910f, 3.910292f, +0.268645f, 0.433501f, 0.005123f, 1.031763f, 0.559493f, 1.751819f, 0.708830f, 2.315940f, 0.292567f, 0.777744f, 0.257697f, 2.244754f, 1.412242f, 4.588310f, 1.545820f, 5.503177f, +0.140554f, 0.266296f, 0.004964f, 0.655796f, 0.289465f, 1.064145f, 0.679303f, 1.455635f, 0.114101f, 0.356134f, 0.186164f, 1.063552f, 0.965977f, 3.684857f, 1.958558f, 4.572937f, +0.269788f, 0.397923f, 0.006393f, 1.046853f, 0.873221f, 2.499107f, 1.374727f, 3.651911f, 0.383073f, 0.930806f, 0.419286f, 2.969535f, 1.767491f, 5.248880f, 2.404095f, 6.958644f, +0.257785f, 0.749584f, 0.008605f, 1.200988f, 0.255711f, 1.442767f, 0.567113f, 1.283994f, 0.004340f, 0.020788f, 0.006691f, 0.040390f, 0.658365f, 3.854449f, 1.261506f, 3.112089f, +0.224323f, 0.775567f, 0.006133f, 1.141626f, 0.315191f, 2.114476f, 0.572540f, 1.728843f, 0.142973f, 0.814329f, 0.180560f, 1.453606f, 0.666687f, 4.640879f, 1.046302f, 3.442516f, +0.008651f, 0.035119f, 0.000438f, 0.053488f, 0.012020f, 0.094680f, 0.040446f, 0.080099f, 0.004110f, 0.027487f, 0.009615f, 0.050767f, 0.033614f, 0.274735f, 0.097719f, 0.210864f, +0.259037f, 0.818601f, 0.008800f, 1.331908f, 0.565650f, 3.468510f, 1.276806f, 3.134679f, 0.215256f, 1.120642f, 0.337807f, 2.211113f, 0.959433f, 6.104620f, 1.871087f, 5.005318f, +0.474274f, 1.330970f, 0.015765f, 1.757078f, 0.582529f, 3.172053f, 1.286562f, 2.326009f, 0.011465f, 0.053006f, 0.017605f, 0.084858f, 1.572279f, 8.883849f, 3.000164f, 5.910103f, +0.518206f, 1.729118f, 0.014109f, 2.097169f, 0.901569f, 5.837197f, 1.630889f, 3.932434f, 0.474293f, 2.607170f, 0.596498f, 3.834603f, 1.999134f, 13.430630f, 3.124423f, 8.208736f, +0.236681f, 0.927248f, 0.011936f, 1.163639f, 0.407189f, 3.095367f, 1.364400f, 2.157661f, 0.161476f, 1.042178f, 0.376176f, 1.586013f, 1.193702f, 9.415873f, 3.455761f, 5.954624f, +0.573715f, 1.749780f, 0.019410f, 2.345792f, 1.551239f, 9.180155f, 3.486975f, 6.836038f, 0.684627f, 3.439870f, 1.069942f, 5.592298f, 2.758291f, 16.937930f, 5.356888f, 11.442940f, +0.296934f, 0.916720f, 0.008678f, 1.373018f, 0.248254f, 1.487154f, 0.482048f, 1.237211f, 0.007845f, 0.039901f, 0.010591f, 0.072471f, 0.890988f, 5.538353f, 1.494748f, 4.180146f, +0.335385f, 1.231128f, 0.008028f, 1.694060f, 0.397180f, 2.828980f, 0.631675f, 2.162240f, 0.335485f, 2.028772f, 0.370951f, 3.385331f, 1.171100f, 8.655377f, 1.609174f, 6.001817f, +0.163663f, 0.705375f, 0.007257f, 1.004291f, 0.191659f, 1.602815f, 0.564621f, 1.267568f, 0.122034f, 0.866466f, 0.249945f, 1.496005f, 0.747126f, 6.483298f, 1.901615f, 4.651645f, +0.490511f, 1.645789f, 0.014590f, 2.503209f, 0.902774f, 5.877436f, 1.784146f, 4.965456f, 0.639724f, 3.536048f, 0.878982f, 6.522038f, 2.134541f, 14.419900f, 3.644669f, 11.052390f, +0.531967f, 1.362576f, 0.015914f, 2.111937f, 0.614117f, 3.052188f, 1.220651f, 2.627724f, 0.012651f, 0.053385f, 0.017483f, 0.100342f, 1.786468f, 9.213063f, 3.067876f, 7.196069f, +0.608431f, 1.852979f, 0.014908f, 2.638619f, 0.994915f, 5.879341f, 1.619715f, 4.650324f, 0.547839f, 2.748607f, 0.620072f, 4.746365f, 2.377722f, 14.579840f, 3.344384f, 10.462370f, +0.384846f, 1.376122f, 0.017467f, 2.027575f, 0.622298f, 4.317692f, 1.876598f, 3.533622f, 0.258304f, 1.521599f, 0.541551f, 2.718708f, 1.966211f, 14.155720f, 5.122774f, 10.510500f, +0.535468f, 1.490592f, 0.016304f, 2.346184f, 1.360803f, 7.350275f, 2.752913f, 6.426218f, 0.628622f, 2.882800f, 0.884143f, 5.502503f, 2.607886f, 14.616580f, 4.558145f, 11.593660f, +0.080775f, 0.212998f, 0.002567f, 0.504403f, 0.107355f, 0.549292f, 0.226639f, 0.722525f, 0.001361f, 0.005913f, 0.001998f, 0.016980f, 0.220595f, 1.171192f, 0.402358f, 1.397657f, +0.076326f, 0.239307f, 0.001986f, 0.520645f, 0.143689f, 0.874156f, 0.248456f, 1.056391f, 0.048693f, 0.251506f, 0.058537f, 0.663556f, 0.242566f, 1.531246f, 0.362376f, 1.678819f, +0.002578f, 0.009489f, 0.000124f, 0.021361f, 0.004799f, 0.034276f, 0.015370f, 0.042859f, 0.001226f, 0.007434f, 0.002730f, 0.020294f, 0.010710f, 0.079379f, 0.029637f, 0.090049f, +0.098346f, 0.281840f, 0.003180f, 0.677779f, 0.287735f, 1.600016f, 0.618249f, 2.137262f, 0.081802f, 0.386198f, 0.122199f, 1.126257f, 0.389510f, 2.247496f, 0.723089f, 2.723672f, +0.175341f, 0.446230f, 0.005548f, 0.870691f, 0.288551f, 1.424890f, 0.606637f, 1.544314f, 0.004243f, 0.017788f, 0.006202f, 0.042090f, 0.621574f, 3.184937f, 1.129021f, 3.131683f, +0.208035f, 0.629498f, 0.005392f, 1.128459f, 0.484934f, 2.847243f, 0.835030f, 2.835076f, 0.190587f, 0.950061f, 0.228164f, 2.065311f, 0.858192f, 5.228478f, 1.276750f, 4.723220f, +0.083204f, 0.295605f, 0.003994f, 0.548299f, 0.191790f, 1.322146f, 0.611739f, 1.362176f, 0.056820f, 0.332560f, 0.126002f, 0.748029f, 0.448730f, 3.209862f, 1.236593f, 3.000289f, +0.256995f, 0.710801f, 0.008277f, 1.408436f, 0.931017f, 4.996497f, 1.992148f, 5.499245f, 0.306969f, 1.398683f, 0.456662f, 3.360863f, 1.321228f, 7.357573f, 2.442553f, 7.346742f, +0.107078f, 0.299786f, 0.002979f, 0.663643f, 0.119946f, 0.651601f, 0.221704f, 0.801222f, 0.002832f, 0.013061f, 0.003639f, 0.035062f, 0.343574f, 1.936714f, 0.548669f, 2.160525f, +0.131329f, 0.437177f, 0.002992f, 0.889132f, 0.208380f, 1.345970f, 0.315469f, 1.520521f, 0.131494f, 0.721108f, 0.138402f, 1.778490f, 0.490368f, 3.286625f, 0.641393f, 3.368448f, +0.056120f, 0.219342f, 0.002369f, 0.461577f, 0.088053f, 0.667784f, 0.246926f, 0.780561f, 0.041885f, 0.269690f, 0.081661f, 0.688225f, 0.273948f, 2.155792f, 0.663729f, 2.286128f, +0.214320f, 0.652115f, 0.006068f, 1.465986f, 0.528498f, 3.120245f, 0.994233f, 3.896215f, 0.279781f, 1.402429f, 0.365932f, 3.823217f, 0.997304f, 6.109725f, 1.620969f, 6.921476f, +0.256208f, 0.595121f, 0.007296f, 1.363354f, 0.396288f, 1.786105f, 0.749799f, 2.272786f, 0.006099f, 0.023339f, 0.008023f, 0.064837f, 0.920053f, 4.302871f, 1.504005f, 4.967440f, +0.318199f, 0.878809f, 0.007422f, 1.849625f, 0.697147f, 3.735971f, 1.080366f, 4.367582f, 0.286783f, 1.304816f, 0.308984f, 3.330280f, 1.329714f, 7.394115f, 1.780356f, 7.842356f, +0.176247f, 0.571515f, 0.007615f, 1.244602f, 0.381842f, 2.402555f, 1.096100f, 2.906195f, 0.118407f, 0.632534f, 0.236309f, 1.670433f, 0.962884f, 6.286551f, 2.388046f, 6.899008f, +0.312476f, 0.788820f, 0.009057f, 1.835120f, 1.063969f, 5.211633f, 2.048896f, 6.734552f, 0.367185f, 1.527026f, 0.491600f, 4.307996f, 1.627350f, 8.271319f, 2.707536f, 9.696888f, +0.337360f, 0.525452f, 0.007883f, 1.271883f, 0.376481f, 1.137800f, 0.584483f, 1.529778f, 0.005717f, 0.014670f, 0.006171f, 0.043061f, 0.679346f, 2.130412f, 0.911219f, 2.598656f, +0.326613f, 0.604862f, 0.006251f, 1.345106f, 0.516286f, 1.855226f, 0.656497f, 2.291634f, 0.209561f, 0.639342f, 0.185263f, 1.724152f, 0.765368f, 2.853814f, 0.840843f, 3.198135f, +0.010763f, 0.023402f, 0.000382f, 0.053847f, 0.016823f, 0.070978f, 0.039625f, 0.090717f, 0.005147f, 0.018439f, 0.008429f, 0.051450f, 0.032972f, 0.144348f, 0.067098f, 0.167377f, +0.435348f, 0.736927f, 0.010353f, 1.811432f, 1.069498f, 3.512789f, 1.689921f, 4.796205f, 0.364189f, 1.015583f, 0.400082f, 3.027297f, 1.271388f, 4.333105f, 1.735669f, 5.367445f, +0.686016f, 1.031218f, 0.015963f, 2.056689f, 0.947937f, 2.764900f, 1.465555f, 3.062993f, 0.016695f, 0.041343f, 0.017945f, 0.099992f, 1.793176f, 5.427146f, 2.395233f, 5.454574f, +0.833935f, 1.490497f, 0.015894f, 2.731084f, 1.632243f, 5.660666f, 2.066902f, 5.761294f, 0.768374f, 2.262413f, 0.676462f, 5.027110f, 2.536643f, 9.128320f, 2.775216f, 8.428808f, +0.325435f, 0.682926f, 0.011489f, 1.294767f, 0.629875f, 2.564762f, 1.477437f, 2.700930f, 0.223515f, 0.772709f, 0.364500f, 1.776545f, 1.294151f, 5.467978f, 2.622661f, 5.224153f, +1.065713f, 1.741024f, 0.025239f, 3.526195f, 3.241753f, 10.276100f, 5.101049f, 11.560540f, 1.280249f, 3.445559f, 1.400587f, 8.462591f, 4.039919f, 13.288310f, 5.492304f, 13.562590f, +0.436562f, 0.721937f, 0.008931f, 1.633558f, 0.410618f, 1.317576f, 0.558138f, 1.655995f, 0.011611f, 0.031633f, 0.010973f, 0.086800f, 1.032870f, 3.438996f, 1.212974f, 3.921370f, +0.548597f, 1.078674f, 0.009192f, 2.242390f, 0.730893f, 2.788520f, 0.813710f, 3.219906f, 0.552433f, 1.789437f, 0.427594f, 4.511072f, 1.510401f, 5.979449f, 1.452816f, 6.264023f, +0.228735f, 0.528054f, 0.007100f, 1.135830f, 0.301348f, 1.349892f, 0.621448f, 1.612807f, 0.171696f, 0.652990f, 0.246168f, 1.703270f, 0.823310f, 3.826862f, 1.466905f, 4.148096f, +0.926134f, 1.664471f, 0.019284f, 3.824675f, 1.917613f, 6.687239f, 2.652905f, 8.535197f, 1.215945f, 3.600116f, 1.169528f, 10.031760f, 3.177736f, 11.498800f, 3.798225f, 13.315020f, +0.761090f, 1.044214f, 0.015938f, 2.445147f, 0.988462f, 2.631460f, 1.375338f, 3.422636f, 0.018222f, 0.041185f, 0.017627f, 0.116950f, 2.015279f, 5.566996f, 2.422630f, 6.569126f, +0.968472f, 1.579877f, 0.016612f, 3.398794f, 1.781634f, 5.639470f, 2.030396f, 6.738889f, 0.877860f, 2.359183f, 0.695542f, 6.154681f, 2.984180f, 9.801525f, 2.938255f, 10.625920f, +0.523401f, 1.002493f, 0.016629f, 2.231499f, 0.952145f, 3.538612f, 2.009949f, 4.375189f, 0.353650f, 1.115889f, 0.519030f, 3.012164f, 2.108462f, 8.131014f, 3.845477f, 9.120766f, +0.983840f, 1.466988f, 0.020970f, 3.488393f, 2.812826f, 8.138200f, 3.983360f, 10.749190f, 1.162723f, 2.856134f, 1.144772f, 8.236065f, 3.778049f, 11.342320f, 4.622496f, 13.591640f, +0.055140f, 0.084953f, 0.001432f, 0.227500f, 0.091622f, 0.273903f, 0.158130f, 0.407425f, 0.001224f, 0.003106f, 0.001468f, 0.010086f, 0.216577f, 0.671831f, 0.322946f, 0.906637f, +0.076377f, 0.139914f, 0.001625f, 0.344231f, 0.179765f, 0.638979f, 0.254116f, 0.873218f, 0.064174f, 0.193667f, 0.063070f, 0.577811f, 0.349101f, 1.287600f, 0.426364f, 1.596394f, +0.001863f, 0.004007f, 0.000073f, 0.010201f, 0.004336f, 0.018097f, 0.011354f, 0.025589f, 0.001167f, 0.004135f, 0.002124f, 0.012764f, 0.011133f, 0.048212f, 0.025186f, 0.061848f, +0.080719f, 0.135157f, 0.002134f, 0.367557f, 0.295259f, 0.959291f, 0.518651f, 1.449052f, 0.088426f, 0.243919f, 0.107992f, 0.804403f, 0.459798f, 1.550112f, 0.697816f, 2.124318f, +0.082151f, 0.122153f, 0.002125f, 0.269531f, 0.169021f, 0.487658f, 0.290501f, 0.597681f, 0.002618f, 0.006413f, 0.003128f, 0.017160f, 0.418841f, 1.253929f, 0.621956f, 1.394281f, +0.142879f, 0.252605f, 0.003027f, 0.512075f, 0.416394f, 1.428440f, 0.586172f, 1.608431f, 0.172395f, 0.502110f, 0.168726f, 1.234336f, 0.847705f, 3.017527f, 1.031021f, 3.082580f, +0.041275f, 0.085678f, 0.001620f, 0.179712f, 0.118949f, 0.479102f, 0.310171f, 0.558191f, 0.037123f, 0.126949f, 0.067301f, 0.322908f, 0.320152f, 1.338054f, 0.721273f, 1.414330f, +0.144772f, 0.233951f, 0.003812f, 0.524220f, 0.655704f, 2.056039f, 1.147025f, 2.558993f, 0.227748f, 0.606311f, 0.276985f, 1.647506f, 1.070450f, 3.482881f, 1.617833f, 3.932776f, +0.007939f, 0.012987f, 0.000181f, 0.032512f, 0.011119f, 0.035292f, 0.016802f, 0.049074f, 0.000277f, 0.000745f, 0.000291f, 0.002262f, 0.036639f, 0.120670f, 0.047833f, 0.152228f, +0.014274f, 0.027763f, 0.000266f, 0.063852f, 0.028317f, 0.106865f, 0.035046f, 0.136519f, 0.018823f, 0.060313f, 0.016197f, 0.168214f, 0.076656f, 0.300184f, 0.081969f, 0.347911f, +0.004406f, 0.010061f, 0.000152f, 0.023942f, 0.008643f, 0.038295f, 0.019814f, 0.050620f, 0.004331f, 0.016292f, 0.006903f, 0.047017f, 0.030932f, 0.142219f, 0.061267f, 0.170549f, +0.019107f, 0.033967f, 0.000442f, 0.086351f, 0.058905f, 0.203197f, 0.090594f, 0.286927f, 0.032850f, 0.096210f, 0.035126f, 0.296597f, 0.127873f, 0.457707f, 0.169913f, 0.586361f, +0.119837f, 0.162637f, 0.002790f, 0.421332f, 0.231739f, 0.610255f, 0.358455f, 0.878139f, 0.003757f, 0.008400f, 0.004040f, 0.026390f, 0.618928f, 1.691225f, 0.827138f, 2.207883f, +0.218173f, 0.352057f, 0.004160f, 0.837920f, 0.597609f, 1.871164f, 0.757120f, 2.473716f, 0.258974f, 0.688443f, 0.228108f, 1.987009f, 1.311261f, 4.260229f, 1.435288f, 5.109679f, +0.087284f, 0.165370f, 0.003083f, 0.407250f, 0.236422f, 0.869147f, 0.554825f, 1.188899f, 0.077231f, 0.241054f, 0.126007f, 0.719879f, 0.685830f, 2.616198f, 1.390550f, 3.246723f, +0.175731f, 0.259194f, 0.004164f, 0.681886f, 0.748083f, 2.140969f, 1.177720f, 3.128568f, 0.271967f, 0.660835f, 0.297676f, 2.108252f, 1.316255f, 3.908856f, 1.790337f, 5.182123f, +0.100576f, 0.292453f, 0.003357f, 0.468570f, 0.131215f, 0.740340f, 0.291008f, 0.658867f, 0.001845f, 0.008840f, 0.002845f, 0.017176f, 0.293670f, 1.719313f, 0.562706f, 1.388176f, +0.143920f, 0.497586f, 0.003935f, 0.732440f, 0.265963f, 1.784230f, 0.483119f, 1.458827f, 0.099979f, 0.569451f, 0.126264f, 1.016491f, 0.489021f, 3.404129f, 0.767472f, 2.525118f, +0.004244f, 0.017229f, 0.000215f, 0.026241f, 0.007756f, 0.061091f, 0.026097f, 0.051683f, 0.002198f, 0.014698f, 0.005141f, 0.027146f, 0.018854f, 0.154095f, 0.054809f, 0.118271f, +0.133295f, 0.421235f, 0.004528f, 0.685371f, 0.382824f, 2.347437f, 0.864124f, 2.121506f, 0.120730f, 0.628531f, 0.189465f, 1.240140f, 0.564447f, 3.591429f, 1.100786f, 2.944695f, +0.197680f, 0.554755f, 0.006571f, 0.732358f, 0.319337f, 1.738891f, 0.705282f, 1.275098f, 0.005209f, 0.024081f, 0.007998f, 0.038551f, 0.749237f, 4.233415f, 1.429666f, 2.816338f, +0.355180f, 1.185142f, 0.009670f, 1.437405f, 0.812726f, 5.261986f, 1.470177f, 3.544923f, 0.354324f, 1.947705f, 0.445618f, 2.864668f, 1.566552f, 10.524450f, 2.448346f, 6.432491f, +0.124045f, 0.485972f, 0.006256f, 0.609865f, 0.280680f, 2.133670f, 0.940496f, 1.487299f, 0.092243f, 0.595341f, 0.214889f, 0.906004f, 0.715268f, 5.642004f, 2.070697f, 3.568019f, +0.315387f, 0.961905f, 0.010670f, 1.289550f, 1.121571f, 6.637404f, 2.521141f, 4.942568f, 0.410214f, 2.061099f, 0.641087f, 3.350789f, 1.733588f, 10.645500f, 3.366809f, 7.191896f, +0.119261f, 0.368192f, 0.003485f, 0.551460f, 0.131139f, 0.785585f, 0.254640f, 0.653553f, 0.003434f, 0.017467f, 0.004636f, 0.031726f, 0.409135f, 2.543170f, 0.686377f, 1.919492f, +0.221511f, 0.813119f, 0.005302f, 1.118870f, 0.345015f, 2.457425f, 0.548712f, 1.878254f, 0.241508f, 1.460469f, 0.267039f, 2.437026f, 0.884305f, 6.535729f, 1.215098f, 4.532009f, +0.082655f, 0.356238f, 0.003665f, 0.507201f, 0.127306f, 1.064642f, 0.375040f, 0.841960f, 0.067175f, 0.476958f, 0.137586f, 0.823497f, 0.431391f, 3.743466f, 1.097996f, 2.685867f, +0.259838f, 0.871822f, 0.007729f, 1.326022f, 0.628974f, 4.094880f, 1.243036f, 3.459493f, 0.369364f, 2.041644f, 0.507507f, 3.765695f, 1.292753f, 8.733195f, 2.207339f, 6.693715f, +0.219553f, 0.562363f, 0.006568f, 0.871639f, 0.333355f, 1.656787f, 0.662593f, 1.426379f, 0.005691f, 0.024015f, 0.007865f, 0.045138f, 0.842962f, 4.347273f, 1.447607f, 3.395535f, +0.412934f, 1.257591f, 0.010118f, 1.790794f, 0.888085f, 5.248040f, 1.445797f, 4.150990f, 0.405257f, 2.033245f, 0.458690f, 3.511059f, 1.844961f, 11.313030f, 2.595029f, 8.118132f, +0.199722f, 0.714160f, 0.009065f, 1.052242f, 0.424754f, 2.947067f, 1.280884f, 2.411895f, 0.146109f, 0.860691f, 0.306328f, 1.537834f, 1.166611f, 8.399009f, 3.039493f, 6.236189f, +0.291478f, 0.811391f, 0.008875f, 1.277126f, 0.974241f, 5.262293f, 1.970896f, 4.600731f, 0.372966f, 1.710387f, 0.524569f, 3.264677f, 1.622996f, 9.096512f, 2.836724f, 7.215219f, +0.023222f, 0.061236f, 0.000738f, 0.145013f, 0.040593f, 0.207698f, 0.085696f, 0.273201f, 0.000427f, 0.001853f, 0.000626f, 0.005321f, 0.072507f, 0.384959f, 0.132251f, 0.459396f, +0.036084f, 0.113135f, 0.000939f, 0.246141f, 0.089344f, 0.543540f, 0.154487f, 0.656852f, 0.025091f, 0.129598f, 0.030163f, 0.341923f, 0.131108f, 0.827647f, 0.195866f, 0.907410f, +0.000932f, 0.003430f, 0.000045f, 0.007722f, 0.002282f, 0.016297f, 0.007308f, 0.020378f, 0.000483f, 0.002929f, 0.001076f, 0.007996f, 0.004426f, 0.032808f, 0.012249f, 0.037218f, +0.037291f, 0.106868f, 0.001206f, 0.257000f, 0.143495f, 0.797939f, 0.308325f, 1.065867f, 0.033808f, 0.159611f, 0.050504f, 0.465469f, 0.168858f, 0.974320f, 0.313469f, 1.180749f, +0.053853f, 0.137052f, 0.001704f, 0.267418f, 0.116560f, 0.575583f, 0.245050f, 0.623824f, 0.001420f, 0.005955f, 0.002076f, 0.014090f, 0.218261f, 1.118368f, 0.396448f, 1.099668f, +0.105069f, 0.317932f, 0.002723f, 0.569935f, 0.322123f, 1.891316f, 0.554679f, 1.883234f, 0.104916f, 0.522997f, 0.125602f, 1.136930f, 0.495543f, 3.019065f, 0.737230f, 2.727315f, +0.032133f, 0.114162f, 0.001543f, 0.211752f, 0.097417f, 0.671566f, 0.310725f, 0.691899f, 0.023918f, 0.139987f, 0.053039f, 0.314874f, 0.198131f, 1.417272f, 0.546001f, 1.324738f, +0.104104f, 0.287933f, 0.003353f, 0.570532f, 0.496021f, 2.662000f, 1.061363f, 2.929851f, 0.135533f, 0.617548f, 0.201626f, 1.483890f, 0.611896f, 3.407490f, 1.131212f, 3.402474f, +0.031691f, 0.088725f, 0.000882f, 0.196411f, 0.046689f, 0.253638f, 0.086299f, 0.311878f, 0.000913f, 0.004213f, 0.001174f, 0.011310f, 0.116254f, 0.655322f, 0.185652f, 0.731052f, +0.063916f, 0.212766f, 0.001456f, 0.432724f, 0.133383f, 0.861549f, 0.201930f, 0.973278f, 0.069752f, 0.382520f, 0.073417f, 0.943419f, 0.272850f, 1.828742f, 0.356884f, 1.874270f, +0.020885f, 0.081627f, 0.000881f, 0.171774f, 0.043098f, 0.326851f, 0.120859f, 0.382051f, 0.016990f, 0.109393f, 0.033124f, 0.279160f, 0.116557f, 0.917231f, 0.282399f, 0.972686f, +0.083659f, 0.254549f, 0.002369f, 0.572239f, 0.271326f, 1.601903f, 0.510430f, 2.000279f, 0.119035f, 0.596674f, 0.155688f, 1.626616f, 0.445074f, 2.726634f, 0.723402f, 3.088900f, +0.077919f, 0.180990f, 0.002219f, 0.414628f, 0.158511f, 0.714425f, 0.299912f, 0.909092f, 0.002022f, 0.007736f, 0.002659f, 0.021492f, 0.319904f, 1.496117f, 0.522946f, 1.727189f, +0.159134f, 0.439499f, 0.003712f, 0.925011f, 0.458550f, 2.457346f, 0.710614f, 2.872789f, 0.156324f, 0.711247f, 0.168425f, 1.815315f, 0.760289f, 4.227723f, 1.017952f, 4.484013f, +0.067399f, 0.218555f, 0.002912f, 0.475952f, 0.192051f, 1.208387f, 0.551293f, 1.461697f, 0.049354f, 0.263648f, 0.098497f, 0.696258f, 0.420983f, 2.748543f, 1.044078f, 3.016316f, +0.125338f, 0.316405f, 0.003633f, 0.736089f, 0.561299f, 2.749410f, 1.080900f, 3.552829f, 0.160531f, 0.667607f, 0.214925f, 1.883430f, 0.746284f, 3.793132f, 1.241645f, 4.446882f, +0.153272f, 0.238728f, 0.003581f, 0.577853f, 0.224964f, 0.679885f, 0.349254f, 0.914109f, 0.002831f, 0.007264f, 0.003056f, 0.021324f, 0.352873f, 1.106601f, 0.473315f, 1.349820f, +0.244015f, 0.451897f, 0.004670f, 1.004939f, 0.507310f, 1.822971f, 0.645083f, 2.251791f, 0.170648f, 0.520625f, 0.150862f, 1.403999f, 0.653749f, 2.437621f, 0.718216f, 2.731727f, +0.006148f, 0.013369f, 0.000218f, 0.030762f, 0.012640f, 0.053331f, 0.029773f, 0.068162f, 0.003205f, 0.011481f, 0.005249f, 0.032036f, 0.021536f, 0.094280f, 0.043825f, 0.109322f, +0.260869f, 0.441582f, 0.006204f, 1.085446f, 0.842880f, 2.768458f, 1.331841f, 3.779928f, 0.237860f, 0.663300f, 0.261302f, 1.977194f, 0.871007f, 2.968538f, 1.189078f, 3.677147f, +0.332967f, 0.500516f, 0.007748f, 0.998242f, 0.605127f, 1.765006f, 0.935554f, 1.955297f, 0.008832f, 0.021872f, 0.009493f, 0.052898f, 0.995055f, 3.011591f, 1.329144f, 3.026810f, +0.665599f, 1.189628f, 0.012686f, 2.179794f, 1.713424f, 5.942204f, 2.169701f, 6.047837f, 0.668438f, 1.968160f, 0.588481f, 4.373276f, 2.314712f, 8.329684f, 2.532412f, 7.691372f, +0.198616f, 0.416796f, 0.007012f, 0.790209f, 0.505596f, 2.058718f, 1.185930f, 2.168020f, 0.148684f, 0.514013f, 0.242469f, 1.181775f, 0.903010f, 3.815349f, 1.829994f, 3.645217f, +0.682218f, 1.114521f, 0.016157f, 2.257302f, 2.729373f, 8.651895f, 4.294795f, 9.733322f, 0.893277f, 2.404092f, 0.977241f, 5.904659f, 2.956740f, 9.725466f, 4.019713f, 9.926201f, +0.204182f, 0.337654f, 0.004177f, 0.764023f, 0.252587f, 0.810490f, 0.343332f, 1.018664f, 0.005919f, 0.016126f, 0.005594f, 0.044249f, 0.552300f, 1.838913f, 0.648606f, 2.096850f, +0.421929f, 0.829613f, 0.007070f, 1.724632f, 0.739331f, 2.820713f, 0.823105f, 3.257079f, 0.463099f, 1.500065f, 0.358448f, 3.781581f, 1.328113f, 5.257798f, 1.277478f, 5.508027f, +0.134520f, 0.310552f, 0.004175f, 0.667988f, 0.233090f, 1.044129f, 0.480684f, 1.247491f, 0.110058f, 0.418572f, 0.157796f, 1.091810f, 0.553575f, 2.573092f, 0.986312f, 2.789083f, +0.571298f, 1.026750f, 0.011896f, 2.359299f, 1.555783f, 5.425439f, 2.152334f, 6.924710f, 0.817543f, 2.420544f, 0.786334f, 6.744870f, 2.241111f, 8.109575f, 2.678714f, 9.390476f, +0.365786f, 0.501857f, 0.007660f, 1.175156f, 0.624813f, 1.663362f, 0.869360f, 2.163469f, 0.009545f, 0.021575f, 0.009234f, 0.061263f, 1.107344f, 3.058922f, 1.331174f, 3.609568f, +0.765404f, 1.248610f, 0.013128f, 2.686139f, 1.851918f, 5.861942f, 2.110493f, 7.004731f, 0.756200f, 2.032233f, 0.599150f, 5.301726f, 2.696410f, 8.856344f, 2.654913f, 9.601237f, +0.316307f, 0.605835f, 0.010050f, 1.348559f, 0.756791f, 2.812588f, 1.597563f, 3.477522f, 0.232946f, 0.735026f, 0.341880f, 1.984085f, 1.456788f, 5.617918f, 2.656934f, 6.301762f, +0.623636f, 0.929893f, 0.013292f, 2.211219f, 2.345033f, 6.784760f, 3.320899f, 8.961521f, 0.803324f, 1.973301f, 0.790922f, 5.690290f, 2.737986f, 8.219883f, 3.349965f, 9.849988f, +0.161370f, 0.248620f, 0.004192f, 0.665793f, 0.189552f, 0.566667f, 0.327148f, 0.842904f, 0.003525f, 0.008948f, 0.004230f, 0.029058f, 0.409473f, 1.270203f, 0.610581f, 1.714140f, +0.153272f, 0.280776f, 0.003261f, 0.690794f, 0.255022f, 0.906482f, 0.360500f, 1.238783f, 0.126773f, 0.382582f, 0.124592f, 1.141445f, 0.452591f, 1.669305f, 0.552758f, 2.069640f, +0.005148f, 0.011072f, 0.000203f, 0.028187f, 0.008470f, 0.035349f, 0.022178f, 0.049983f, 0.003174f, 0.011246f, 0.005778f, 0.034718f, 0.019873f, 0.086061f, 0.044959f, 0.110403f, +0.165676f, 0.277410f, 0.004380f, 0.754409f, 0.428410f, 1.391897f, 0.752544f, 2.102523f, 0.178663f, 0.492833f, 0.218194f, 1.625276f, 0.609686f, 2.055427f, 0.925295f, 2.816816f, +0.223397f, 0.332176f, 0.005779f, 0.732949f, 0.324922f, 0.937464f, 0.558454f, 1.148971f, 0.007008f, 0.017168f, 0.008375f, 0.045937f, 0.735819f, 2.202899f, 1.092650f, 2.449469f, +0.266425f, 0.471030f, 0.005645f, 0.954862f, 0.548890f, 1.882969f, 0.772691f, 2.120233f, 0.316448f, 0.921673f, 0.309713f, 2.265746f, 1.021193f, 3.635084f, 1.242026f, 3.713451f, +0.105973f, 0.219978f, 0.004159f, 0.461408f, 0.215895f, 0.869582f, 0.562967f, 1.013129f, 0.093826f, 0.320855f, 0.170099f, 0.816125f, 0.531033f, 2.219413f, 1.196366f, 2.345932f, +0.276106f, 0.446185f, 0.007269f, 0.999781f, 0.884043f, 2.772022f, 1.546459f, 3.450123f, 0.427580f, 1.138301f, 0.520018f, 3.093064f, 1.318906f, 4.291274f, 1.993340f, 4.845592f, +0.013541f, 0.022151f, 0.000308f, 0.055452f, 0.013406f, 0.042552f, 0.020258f, 0.059169f, 0.000464f, 0.001251f, 0.000488f, 0.003798f, 0.040371f, 0.132962f, 0.052706f, 0.167735f, +0.016694f, 0.032470f, 0.000311f, 0.074678f, 0.023411f, 0.088353f, 0.028975f, 0.112871f, 0.021671f, 0.069438f, 0.018648f, 0.193663f, 0.057918f, 0.226808f, 0.061933f, 0.262869f, +0.007095f, 0.016202f, 0.000245f, 0.038555f, 0.009839f, 0.043595f, 0.022555f, 0.057625f, 0.006865f, 0.025827f, 0.010942f, 0.074531f, 0.032179f, 0.147954f, 0.063738f, 0.177428f, +0.022855f, 0.040631f, 0.000529f, 0.103292f, 0.049811f, 0.171826f, 0.076608f, 0.242630f, 0.038682f, 0.113289f, 0.041361f, 0.349250f, 0.098817f, 0.353706f, 0.131305f, 0.453127f, +0.342361f, 0.464635f, 0.007970f, 1.203693f, 0.468021f, 1.232473f, 0.723936f, 1.773492f, 0.010566f, 0.023624f, 0.011363f, 0.074216f, 1.142322f, 3.121399f, 1.526602f, 4.074966f, +0.427401f, 0.689678f, 0.008150f, 1.641481f, 0.827608f, 2.591310f, 1.048509f, 3.425763f, 0.499413f, 1.327614f, 0.439890f, 3.831807f, 1.659506f, 5.391662f, 1.816473f, 6.466709f, +0.235435f, 0.446059f, 0.008316f, 1.098489f, 0.450813f, 1.657303f, 1.057948f, 2.267011f, 0.205068f, 0.640057f, 0.334581f, 1.911457f, 1.195109f, 4.558915f, 2.423134f, 5.657650f, +0.352100f, 0.519329f, 0.008343f, 1.366247f, 1.059599f, 3.032509f, 1.668145f, 4.431364f, 0.536419f, 1.303412f, 0.587128f, 4.158251f, 1.703783f, 5.059687f, 2.317441f, 6.707825f, +0.327716f, 0.952929f, 0.010939f, 1.526789f, 0.302248f, 1.705338f, 0.670323f, 1.517670f, 0.005919f, 0.028355f, 0.009127f, 0.055093f, 0.618189f, 3.619232f, 1.184523f, 2.922174f, +0.321565f, 1.111769f, 0.008791f, 1.636512f, 0.420090f, 2.818201f, 0.763089f, 2.304225f, 0.219901f, 1.252489f, 0.277713f, 2.235737f, 0.705880f, 4.913707f, 1.107812f, 3.644894f, +0.013057f, 0.053004f, 0.000661f, 0.080728f, 0.016868f, 0.132862f, 0.056756f, 0.112400f, 0.006656f, 0.044511f, 0.015570f, 0.082210f, 0.037472f, 0.306262f, 0.108933f, 0.235062f, +0.304610f, 0.962620f, 0.010349f, 1.566235f, 0.618449f, 3.792271f, 1.395987f, 3.427280f, 0.271592f, 1.413931f, 0.426216f, 2.789796f, 0.833318f, 5.302185f, 1.625138f, 4.347383f, +0.598516f, 1.679634f, 0.019895f, 2.217365f, 0.683499f, 3.721864f, 1.509562f, 2.729176f, 0.015524f, 0.071772f, 0.023838f, 0.114900f, 1.465512f, 8.280586f, 2.796436f, 5.508774f, +0.737401f, 2.460514f, 0.020077f, 2.984245f, 1.192817f, 7.722882f, 2.157741f, 5.202792f, 0.724148f, 3.980608f, 0.910728f, 5.854642f, 2.101149f, 14.115990f, 3.283860f, 8.627622f, +0.354598f, 1.389210f, 0.017883f, 1.743374f, 0.567208f, 4.311796f, 1.900587f, 3.005586f, 0.259573f, 1.675301f, 0.604703f, 2.549515f, 1.320936f, 10.419490f, 3.824102f, 6.589314f, +0.669706f, 2.042546f, 0.022658f, 2.738280f, 1.683608f, 9.963509f, 3.784523f, 7.419365f, 0.857474f, 4.308332f, 1.340070f, 7.004183f, 2.378166f, 14.603680f, 4.618646f, 9.865965f, +0.226474f, 0.699190f, 0.006619f, 1.047212f, 0.176047f, 1.054601f, 0.341840f, 0.877357f, 0.006420f, 0.032653f, 0.008667f, 0.059306f, 0.501931f, 3.119988f, 0.842055f, 2.354852f, +0.288441f, 1.058807f, 0.006904f, 1.456942f, 0.317595f, 2.262129f, 0.505104f, 1.728985f, 0.309575f, 1.872085f, 0.342301f, 3.123874f, 0.743912f, 5.498108f, 1.022187f, 3.812501f, +0.148195f, 0.638711f, 0.006571f, 0.909377f, 0.161357f, 1.349404f, 0.475352f, 1.067161f, 0.118562f, 0.841811f, 0.242833f, 1.453438f, 0.499680f, 4.336049f, 1.271806f, 3.111035f, +0.346059f, 1.161114f, 0.010293f, 1.766029f, 0.592180f, 3.855339f, 1.170321f, 3.257121f, 0.484253f, 2.676688f, 0.665364f, 4.936998f, 1.112292f, 7.514095f, 1.899208f, 5.759314f, +0.698362f, 1.788778f, 0.020892f, 2.772533f, 0.749585f, 3.725469f, 1.489914f, 3.207373f, 0.017820f, 0.075196f, 0.024626f, 0.141337f, 1.732227f, 8.933331f, 2.974728f, 6.977579f, +0.900663f, 2.742971f, 0.022069f, 3.905956f, 1.369338f, 8.091951f, 2.229273f, 6.400409f, 0.870127f, 4.365582f, 0.984853f, 7.538598f, 2.599713f, 15.941050f, 3.656626f, 11.439170f, +0.599804f, 2.144759f, 0.027223f, 3.160083f, 0.901767f, 6.256728f, 2.719361f, 5.120539f, 0.431947f, 2.544490f, 0.905607f, 4.546352f, 2.263422f, 16.295490f, 5.897128f, 12.099260f, +0.650237f, 1.810075f, 0.019798f, 2.849049f, 1.536409f, 8.298802f, 3.108166f, 7.255498f, 0.819042f, 3.756049f, 1.151965f, 7.169303f, 2.339053f, 13.109840f, 4.088271f, 10.398530f, +0.118105f, 0.311436f, 0.003753f, 0.737513f, 0.145944f, 0.746739f, 0.308106f, 0.982243f, 0.002135f, 0.009276f, 0.003134f, 0.026638f, 0.238233f, 1.264835f, 0.434528f, 1.509407f, +0.125840f, 0.394549f, 0.003275f, 0.858399f, 0.220264f, 1.340016f, 0.380864f, 1.619369f, 0.086137f, 0.444912f, 0.103551f, 1.173826f, 0.295387f, 1.864686f, 0.441286f, 2.044394f, +0.004475f, 0.016472f, 0.000216f, 0.037080f, 0.007745f, 0.055320f, 0.024806f, 0.069173f, 0.002283f, 0.013846f, 0.005084f, 0.037797f, 0.013731f, 0.101774f, 0.037998f, 0.115454f, +0.133012f, 0.381186f, 0.004302f, 0.916689f, 0.361827f, 2.012021f, 0.777449f, 2.687608f, 0.118707f, 0.560433f, 0.177330f, 1.634370f, 0.389105f, 2.245157f, 0.722336f, 2.720839f, +0.254496f, 0.647674f, 0.008053f, 1.263753f, 0.389398f, 1.922885f, 0.818655f, 2.084046f, 0.006607f, 0.027702f, 0.009658f, 0.065547f, 0.666353f, 3.414385f, 1.210357f, 3.357294f, +0.340477f, 1.030260f, 0.008824f, 1.846879f, 0.737920f, 4.332628f, 1.270658f, 4.314113f, 0.334676f, 1.668335f, 0.400664f, 3.626746f, 1.037411f, 6.320360f, 1.543379f, 5.709587f, +0.143373f, 0.509373f, 0.006883f, 0.944803f, 0.307273f, 2.118249f, 0.980085f, 2.182383f, 0.105052f, 0.614856f, 0.232959f, 1.382997f, 0.571114f, 4.085299f, 1.573853f, 3.818569f, +0.345036f, 0.954307f, 0.011112f, 1.890938f, 1.162176f, 6.237056f, 2.486770f, 6.864629f, 0.442195f, 2.014830f, 0.657830f, 4.841386f, 1.310182f, 7.296059f, 2.422132f, 7.285319f, +0.093931f, 0.262980f, 0.002613f, 0.582163f, 0.097829f, 0.531455f, 0.180825f, 0.653487f, 0.002665f, 0.012293f, 0.003425f, 0.033001f, 0.222610f, 1.254843f, 0.355496f, 1.399856f, +0.129905f, 0.432437f, 0.002960f, 0.879491f, 0.191644f, 1.237869f, 0.290132f, 1.398400f, 0.139556f, 0.765323f, 0.146888f, 1.887537f, 0.358262f, 2.401204f, 0.468601f, 2.460984f, +0.058446f, 0.228432f, 0.002467f, 0.480706f, 0.085262f, 0.646615f, 0.239098f, 0.755817f, 0.046803f, 0.301357f, 0.091249f, 0.769034f, 0.210726f, 1.658276f, 0.510553f, 1.758533f, +0.173906f, 0.529147f, 0.004924f, 1.189549f, 0.398722f, 2.354047f, 0.750092f, 2.939472f, 0.243585f, 1.220990f, 0.318589f, 3.328590f, 0.597714f, 3.661743f, 0.971496f, 4.148250f, +0.386848f, 0.898572f, 0.011016f, 2.058525f, 0.556329f, 2.507427f, 1.052606f, 3.190655f, 0.009881f, 0.037810f, 0.012997f, 0.105038f, 1.026063f, 4.798655f, 1.677299f, 5.539796f, +0.541753f, 1.496225f, 0.012636f, 3.149097f, 1.103572f, 5.913980f, 1.710201f, 6.913809f, 0.523883f, 2.383585f, 0.564439f, 6.083619f, 1.672146f, 9.298273f, 2.238840f, 9.861945f, +0.315933f, 1.024474f, 0.013650f, 2.231023f, 0.636401f, 4.004245f, 1.826828f, 4.843643f, 0.227735f, 1.216567f, 0.454498f, 3.212782f, 1.274856f, 8.323376f, 3.161767f, 9.134267f, +0.436422f, 1.101710f, 0.012649f, 2.563031f, 1.381632f, 6.767642f, 2.660623f, 8.745250f, 0.550241f, 2.288311f, 0.736683f, 6.455706f, 1.678743f, 8.532534f, 2.793042f, 10.003120f, +0.409265f, 0.637447f, 0.009563f, 1.542972f, 0.424646f, 1.283367f, 0.659260f, 1.725493f, 0.007442f, 0.019095f, 0.008032f, 0.056049f, 0.608718f, 1.908922f, 0.816484f, 2.328484f, +0.446786f, 0.827413f, 0.008551f, 1.840018f, 0.656644f, 2.359590f, 0.834972f, 2.914640f, 0.307578f, 0.938378f, 0.271915f, 2.530581f, 0.773303f, 2.883402f, 0.849560f, 3.231292f, +0.015501f, 0.033704f, 0.000550f, 0.077553f, 0.022528f, 0.095046f, 0.053062f, 0.121478f, 0.007954f, 0.028493f, 0.013026f, 0.079506f, 0.035075f, 0.153554f, 0.071377f, 0.178052f, +0.488528f, 0.826947f, 0.011618f, 2.032708f, 1.115853f, 3.665042f, 1.763167f, 5.004085f, 0.438489f, 1.222777f, 0.481705f, 3.644910f, 1.053768f, 3.591417f, 1.438579f, 4.448712f, +0.826135f, 1.241844f, 0.019224f, 2.476768f, 1.061378f, 3.095779f, 1.640940f, 3.429545f, 0.021572f, 0.053420f, 0.023187f, 0.129200f, 1.594973f, 4.827273f, 2.130483f, 4.851669f, +1.132410f, 2.023963f, 0.021582f, 3.708572f, 2.060774f, 7.146823f, 2.609549f, 7.273870f, 1.119497f, 3.296267f, 0.985585f, 7.324345f, 2.544162f, 9.155376f, 2.783441f, 8.453790f, +0.465272f, 0.976374f, 0.016426f, 1.851119f, 0.837280f, 3.409287f, 1.963928f, 3.590293f, 0.342869f, 1.185325f, 0.559138f, 2.725196f, 1.366600f, 5.774083f, 2.769482f, 5.516609f, +1.187132f, 1.939383f, 0.028115f, 3.927942f, 3.357474f, 10.642930f, 5.283141f, 11.973220f, 1.530144f, 4.118104f, 1.673971f, 10.114420f, 3.323879f, 10.933080f, 4.518841f, 11.158740f, +0.317742f, 0.525447f, 0.006500f, 1.188950f, 0.277870f, 0.891617f, 0.377698f, 1.120629f, 0.009068f, 0.024703f, 0.008569f, 0.067784f, 0.555250f, 1.848734f, 0.652070f, 2.108049f, +0.450233f, 0.885267f, 0.007544f, 1.840327f, 0.557714f, 2.127805f, 0.620909f, 2.456977f, 0.486455f, 1.575721f, 0.376526f, 3.972306f, 0.915567f, 3.624590f, 0.880660f, 3.797091f, +0.197645f, 0.456282f, 0.006135f, 0.981451f, 0.242102f, 1.084496f, 0.499268f, 1.295720f, 0.159182f, 0.605397f, 0.228226f, 1.579128f, 0.525451f, 2.442370f, 0.936204f, 2.647388f, +0.623513f, 1.120592f, 0.012983f, 2.574932f, 1.200345f, 4.185930f, 1.660607f, 5.342674f, 0.878343f, 2.600558f, 0.844813f, 7.246480f, 1.580166f, 5.717911f, 1.888712f, 6.621050f, +0.953460f, 1.308144f, 0.019967f, 3.063171f, 1.151331f, 3.065045f, 1.601953f, 3.986583f, 0.024493f, 0.055359f, 0.023693f, 0.157198f, 1.864726f, 5.151109f, 2.241646f, 6.078375f, +1.368070f, 2.231744f, 0.023466f, 4.801158f, 2.339988f, 7.406847f, 2.666710f, 8.850816f, 1.330531f, 3.575705f, 1.054201f, 9.328364f, 3.113579f, 10.226530f, 3.065663f, 11.086670f, +0.778443f, 1.490985f, 0.024733f, 3.318859f, 1.316646f, 4.893268f, 2.779400f, 6.050104f, 0.564346f, 1.780705f, 0.828253f, 4.806729f, 2.316176f, 8.932038f, 4.224312f, 10.019290f, +1.140074f, 1.699945f, 0.024300f, 4.042348f, 3.030576f, 8.768203f, 4.291724f, 11.581320f, 1.445651f, 3.551124f, 1.423332f, 10.240170f, 3.233625f, 9.707871f, 3.956386f, 11.633060f, +}; + +static const float acceptor_me2x3acc5[16384] = { +0.008602f, 0.120562f, 0.000004f, 0.088841f, 0.006477f, 0.082328f, 0.000037f, 0.118493f, 0.001347f, 0.025650f, 0.000001f, 0.015608f, 0.008022f, 0.078301f, 0.000010f, 0.090715f, +0.010717f, 0.107252f, 0.000027f, 0.114039f, 0.009805f, 0.088994f, 0.000306f, 0.184821f, 0.014729f, 0.200307f, 0.000034f, 0.175875f, 0.015004f, 0.104573f, 0.000102f, 0.174814f, +0.000185f, 0.002733f, 0.000003f, 0.002511f, 0.000165f, 0.002207f, 0.000029f, 0.003960f, 0.000166f, 0.003334f, 0.000002f, 0.002529f, 0.000169f, 0.001734f, 0.000006f, 0.002506f, +0.016295f, 0.164076f, 0.000076f, 0.163631f, 0.022160f, 0.202370f, 0.001262f, 0.394198f, 0.024095f, 0.329686f, 0.000100f, 0.271508f, 0.044644f, 0.313057f, 0.000552f, 0.490855f, +0.008946f, 0.158159f, 0.000028f, 0.102085f, 0.007099f, 0.113822f, 0.000273f, 0.143496f, 0.001548f, 0.037199f, 0.000004f, 0.019827f, 0.006010f, 0.073990f, 0.000050f, 0.075084f, +0.039041f, 0.492823f, 0.000677f, 0.458992f, 0.037644f, 0.430968f, 0.007995f, 0.783978f, 0.059318f, 1.017524f, 0.000920f, 0.782561f, 0.039372f, 0.346120f, 0.001816f, 0.506814f, +0.005822f, 0.108483f, 0.000565f, 0.087313f, 0.005463f, 0.092327f, 0.006493f, 0.145141f, 0.005778f, 0.146299f, 0.000501f, 0.097233f, 0.003822f, 0.049596f, 0.000987f, 0.062757f, +0.030575f, 0.388328f, 0.000968f, 0.339225f, 0.043822f, 0.504779f, 0.016995f, 0.861261f, 0.049981f, 0.862619f, 0.001415f, 0.622252f, 0.060339f, 0.533702f, 0.005083f, 0.732984f, +0.000359f, 0.005415f, 0.000002f, 0.003942f, 0.000256f, 0.003504f, 0.000022f, 0.004983f, 0.000085f, 0.001739f, 0.000001f, 0.001045f, 0.000352f, 0.003695f, 0.000006f, 0.004230f, +0.000553f, 0.005954f, 0.000021f, 0.006254f, 0.000480f, 0.004682f, 0.000224f, 0.009606f, 0.001147f, 0.016780f, 0.000039f, 0.014555f, 0.000814f, 0.006100f, 0.000083f, 0.010074f, +0.000241f, 0.003826f, 0.000051f, 0.003473f, 0.000203f, 0.002928f, 0.000532f, 0.005191f, 0.000326f, 0.007042f, 0.000062f, 0.005279f, 0.000231f, 0.002551f, 0.000131f, 0.003641f, +0.000820f, 0.008879f, 0.000057f, 0.008748f, 0.001057f, 0.010378f, 0.000902f, 0.019971f, 0.001830f, 0.026922f, 0.000114f, 0.021903f, 0.002361f, 0.017801f, 0.000438f, 0.027573f, +0.021364f, 0.239581f, 0.000096f, 0.128936f, 0.017000f, 0.172901f, 0.000940f, 0.181746f, 0.003462f, 0.052760f, 0.000014f, 0.023447f, 0.022598f, 0.176486f, 0.000271f, 0.149328f, +0.047887f, 0.383459f, 0.001195f, 0.297774f, 0.046302f, 0.336264f, 0.014157f, 0.510028f, 0.068124f, 0.741289f, 0.001521f, 0.475352f, 0.076044f, 0.424067f, 0.005050f, 0.517738f, +0.014583f, 0.172370f, 0.002037f, 0.115672f, 0.013723f, 0.147108f, 0.023477f, 0.192819f, 0.013550f, 0.217648f, 0.001693f, 0.120609f, 0.015074f, 0.124085f, 0.005601f, 0.130917f, +0.098077f, 0.790184f, 0.004471f, 0.575534f, 0.140961f, 1.030003f, 0.078699f, 1.465299f, 0.150112f, 1.643474f, 0.006120f, 0.988473f, 0.304774f, 1.710042f, 0.036958f, 1.958200f, +0.023448f, 0.425815f, 0.000002f, 0.192385f, 0.012998f, 0.214069f, 0.000013f, 0.188907f, 0.002727f, 0.067285f, 0.000000f, 0.025103f, 0.014411f, 0.182256f, 0.000003f, 0.129462f, +0.030761f, 0.398883f, 0.000014f, 0.260041f, 0.020720f, 0.243668f, 0.000114f, 0.310269f, 0.031400f, 0.553300f, 0.000013f, 0.297863f, 0.028383f, 0.256310f, 0.000034f, 0.262706f, +0.000456f, 0.008735f, 0.000001f, 0.004921f, 0.000299f, 0.005193f, 0.000009f, 0.005715f, 0.000304f, 0.007914f, 0.000001f, 0.003682f, 0.000274f, 0.003654f, 0.000002f, 0.003236f, +0.038821f, 0.506482f, 0.000032f, 0.309696f, 0.038868f, 0.459901f, 0.000391f, 0.549263f, 0.042634f, 0.755866f, 0.000031f, 0.381658f, 0.070094f, 0.636866f, 0.000153f, 0.612247f, +0.042977f, 0.984438f, 0.000024f, 0.389587f, 0.025107f, 0.521579f, 0.000170f, 0.403164f, 0.005525f, 0.171969f, 0.000003f, 0.056199f, 0.019026f, 0.303508f, 0.000028f, 0.188840f, +0.197487f, 3.230102f, 0.000605f, 1.844500f, 0.140188f, 2.079541f, 0.005261f, 2.319395f, 0.222858f, 4.953288f, 0.000611f, 2.335689f, 0.131253f, 1.495054f, 0.001070f, 1.342229f, +0.025313f, 0.611129f, 0.000434f, 0.301575f, 0.017488f, 0.382910f, 0.003672f, 0.369067f, 0.018658f, 0.612116f, 0.000286f, 0.249434f, 0.010951f, 0.184127f, 0.000499f, 0.142852f, +0.128371f, 2.112536f, 0.000718f, 1.131464f, 0.135454f, 2.021639f, 0.009282f, 2.114878f, 0.155856f, 3.485356f, 0.000780f, 1.541498f, 0.166957f, 1.913410f, 0.002485f, 1.611210f, +0.012231f, 0.238836f, 0.000015f, 0.106602f, 0.006425f, 0.113788f, 0.000096f, 0.099199f, 0.002146f, 0.056951f, 0.000002f, 0.020990f, 0.007899f, 0.107416f, 0.000026f, 0.075377f, +0.019831f, 0.276523f, 0.000134f, 0.178091f, 0.012659f, 0.160084f, 0.001046f, 0.201374f, 0.030548f, 0.578822f, 0.000184f, 0.307833f, 0.019227f, 0.186706f, 0.000345f, 0.189050f, +0.007420f, 0.152711f, 0.000280f, 0.084993f, 0.004609f, 0.086040f, 0.002131f, 0.093531f, 0.007465f, 0.208790f, 0.000252f, 0.095957f, 0.004683f, 0.067119f, 0.000470f, 0.058730f, +0.024396f, 0.342259f, 0.000300f, 0.206747f, 0.023147f, 0.294523f, 0.003492f, 0.347495f, 0.040430f, 0.770787f, 0.000445f, 0.384484f, 0.046285f, 0.452216f, 0.001517f, 0.429475f, +0.062235f, 0.904301f, 0.000050f, 0.298389f, 0.036458f, 0.480456f, 0.000356f, 0.309648f, 0.007491f, 0.147907f, 0.000005f, 0.040301f, 0.043384f, 0.439010f, 0.000092f, 0.227747f, +0.146893f, 1.524084f, 0.000648f, 0.725647f, 0.104564f, 0.983940f, 0.005649f, 0.915019f, 0.155205f, 2.188273f, 0.000612f, 0.860354f, 0.153727f, 1.110782f, 0.001804f, 0.831482f, +0.038448f, 0.588839f, 0.000949f, 0.242278f, 0.026636f, 0.369973f, 0.008052f, 0.297325f, 0.026534f, 0.552221f, 0.000586f, 0.187624f, 0.026192f, 0.279358f, 0.001720f, 0.180711f, +0.249707f, 2.606741f, 0.002011f, 1.164096f, 0.264217f, 2.501532f, 0.026066f, 2.181934f, 0.283858f, 4.026763f, 0.002045f, 1.484930f, 0.511382f, 3.717760f, 0.010958f, 2.610235f, +0.000101f, 0.001933f, 0.000000f, 0.001329f, 0.000074f, 0.001281f, 0.000000f, 0.001721f, 0.000012f, 0.000312f, 0.000000f, 0.000177f, 0.000087f, 0.001166f, 0.000000f, 0.001261f, +0.000144f, 0.001961f, 0.000000f, 0.001946f, 0.000127f, 0.001579f, 0.000001f, 0.003061f, 0.000150f, 0.002782f, 0.000000f, 0.002280f, 0.000187f, 0.001776f, 0.000000f, 0.002771f, +0.000002f, 0.000050f, 0.000000f, 0.000043f, 0.000002f, 0.000039f, 0.000000f, 0.000066f, 0.000002f, 0.000047f, 0.000000f, 0.000033f, 0.000002f, 0.000030f, 0.000000f, 0.000040f, +0.000221f, 0.003041f, 0.000000f, 0.002831f, 0.000292f, 0.003639f, 0.000005f, 0.006617f, 0.000248f, 0.004640f, 0.000000f, 0.003567f, 0.000563f, 0.005389f, 0.000002f, 0.007887f, +0.000092f, 0.002219f, 0.000000f, 0.001337f, 0.000071f, 0.001550f, 0.000001f, 0.001824f, 0.000012f, 0.000396f, 0.000000f, 0.000197f, 0.000057f, 0.000964f, 0.000000f, 0.000913f, +0.000458f, 0.007888f, 0.000002f, 0.006857f, 0.000428f, 0.006694f, 0.000028f, 0.011366f, 0.000528f, 0.012368f, 0.000002f, 0.008879f, 0.000429f, 0.005145f, 0.000006f, 0.007033f, +0.000069f, 0.001748f, 0.000002f, 0.001314f, 0.000063f, 0.001444f, 0.000022f, 0.002119f, 0.000052f, 0.001791f, 0.000001f, 0.001111f, 0.000042f, 0.000742f, 0.000003f, 0.000877f, +0.000363f, 0.006299f, 0.000003f, 0.005137f, 0.000505f, 0.007946f, 0.000059f, 0.012656f, 0.000451f, 0.010627f, 0.000004f, 0.007156f, 0.000666f, 0.008041f, 0.000017f, 0.010309f, +0.000063f, 0.001291f, 0.000000f, 0.000877f, 0.000043f, 0.000811f, 0.000001f, 0.001076f, 0.000011f, 0.000315f, 0.000000f, 0.000177f, 0.000057f, 0.000818f, 0.000000f, 0.000874f, +0.000110f, 0.001619f, 0.000001f, 0.001587f, 0.000093f, 0.001235f, 0.000013f, 0.002366f, 0.000174f, 0.003465f, 0.000002f, 0.002805f, 0.000151f, 0.001540f, 0.000005f, 0.002374f, +0.000048f, 0.001047f, 0.000003f, 0.000887f, 0.000040f, 0.000778f, 0.000031f, 0.001287f, 0.000050f, 0.001464f, 0.000003f, 0.001025f, 0.000043f, 0.000649f, 0.000007f, 0.000864f, +0.000165f, 0.002447f, 0.000003f, 0.002250f, 0.000207f, 0.002775f, 0.000053f, 0.004985f, 0.000280f, 0.005634f, 0.000005f, 0.004279f, 0.000442f, 0.004556f, 0.000025f, 0.006587f, +0.000256f, 0.003928f, 0.000000f, 0.001973f, 0.000198f, 0.002751f, 0.000003f, 0.002699f, 0.000032f, 0.000657f, 0.000000f, 0.000272f, 0.000252f, 0.002687f, 0.000001f, 0.002122f, +0.000656f, 0.007170f, 0.000005f, 0.005197f, 0.000615f, 0.006102f, 0.000057f, 0.008639f, 0.000708f, 0.010527f, 0.000005f, 0.006301f, 0.000967f, 0.007365f, 0.000019f, 0.008393f, +0.000201f, 0.003246f, 0.000008f, 0.002033f, 0.000184f, 0.002688f, 0.000095f, 0.003289f, 0.000142f, 0.003112f, 0.000005f, 0.001610f, 0.000193f, 0.002170f, 0.000022f, 0.002137f, +0.001361f, 0.014975f, 0.000019f, 0.010182f, 0.001899f, 0.018943f, 0.000321f, 0.025155f, 0.001582f, 0.023655f, 0.000020f, 0.013280f, 0.003929f, 0.030101f, 0.000144f, 0.032175f, +0.048065f, 0.526778f, 0.000004f, 0.266123f, 0.027016f, 0.268534f, 0.000026f, 0.264972f, 0.004941f, 0.073584f, 0.000000f, 0.030697f, 0.029348f, 0.224004f, 0.000006f, 0.177918f, +0.062734f, 0.490950f, 0.000027f, 0.357880f, 0.042847f, 0.304108f, 0.000226f, 0.432986f, 0.056609f, 0.602015f, 0.000022f, 0.362382f, 0.057507f, 0.313418f, 0.000066f, 0.359197f, +0.000683f, 0.007895f, 0.000002f, 0.004974f, 0.000454f, 0.004760f, 0.000013f, 0.005856f, 0.000403f, 0.006324f, 0.000001f, 0.003289f, 0.000408f, 0.003281f, 0.000003f, 0.003249f, +0.070282f, 0.553397f, 0.000055f, 0.378366f, 0.071352f, 0.509538f, 0.000686f, 0.680450f, 0.068233f, 0.730084f, 0.000048f, 0.412199f, 0.126075f, 0.691333f, 0.000263f, 0.743139f, +0.076511f, 1.057705f, 0.000041f, 0.468043f, 0.045323f, 0.568246f, 0.000294f, 0.491136f, 0.008695f, 0.163336f, 0.000004f, 0.059684f, 0.033652f, 0.323977f, 0.000047f, 0.225394f, +0.349789f, 3.452846f, 0.001025f, 2.204672f, 0.251779f, 2.254072f, 0.009036f, 2.811121f, 0.348941f, 4.680688f, 0.000915f, 2.467946f, 0.230965f, 1.587759f, 0.001800f, 1.593892f, +0.032924f, 0.479731f, 0.000540f, 0.264707f, 0.023064f, 0.304791f, 0.004632f, 0.328483f, 0.021453f, 0.424770f, 0.000315f, 0.193544f, 0.014151f, 0.143598f, 0.000617f, 0.124573f, +0.201845f, 2.004687f, 0.001080f, 1.200571f, 0.215963f, 1.945295f, 0.014153f, 2.275472f, 0.216635f, 2.923780f, 0.001037f, 1.445922f, 0.260807f, 1.803920f, 0.003712f, 1.698502f, +0.033638f, 0.396442f, 0.000039f, 0.197856f, 0.017918f, 0.191521f, 0.000256f, 0.186694f, 0.005218f, 0.083567f, 0.000005f, 0.034440f, 0.021583f, 0.177140f, 0.000067f, 0.138993f, +0.054265f, 0.456663f, 0.000350f, 0.328859f, 0.035124f, 0.268072f, 0.002775f, 0.377060f, 0.073893f, 0.845016f, 0.000426f, 0.502503f, 0.052270f, 0.306330f, 0.000897f, 0.346826f, +0.014909f, 0.185199f, 0.000538f, 0.115254f, 0.009392f, 0.105805f, 0.004152f, 0.128608f, 0.013261f, 0.223837f, 0.000428f, 0.115029f, 0.009348f, 0.080868f, 0.000898f, 0.079123f, +0.059261f, 0.501765f, 0.000698f, 0.338914f, 0.057016f, 0.437829f, 0.008225f, 0.577615f, 0.086819f, 0.998931f, 0.000915f, 0.557165f, 0.111701f, 0.658656f, 0.003500f, 0.699447f, +0.123079f, 1.079335f, 0.000094f, 0.398228f, 0.073112f, 0.581482f, 0.000683f, 0.419041f, 0.013096f, 0.156059f, 0.000009f, 0.047547f, 0.085240f, 0.520577f, 0.000173f, 0.301973f, +0.289025f, 1.809827f, 0.001219f, 0.963514f, 0.208620f, 1.184776f, 0.010779f, 1.231976f, 0.269957f, 2.297126f, 0.001019f, 1.009868f, 0.300506f, 1.310460f, 0.003372f, 1.096863f, +0.055554f, 0.513486f, 0.001311f, 0.236238f, 0.039026f, 0.327145f, 0.011282f, 0.293972f, 0.033892f, 0.425696f, 0.000715f, 0.161726f, 0.037599f, 0.242025f, 0.002361f, 0.175060f, +0.436161f, 2.747941f, 0.003360f, 1.372153f, 0.467969f, 2.673960f, 0.044148f, 2.607925f, 0.438301f, 3.752500f, 0.003020f, 1.547302f, 0.887419f, 3.893656f, 0.018184f, 3.056753f, +0.016101f, 0.225655f, 0.000007f, 0.166283f, 0.010485f, 0.133276f, 0.000059f, 0.191823f, 0.002168f, 0.041288f, 0.000001f, 0.025124f, 0.012140f, 0.118493f, 0.000015f, 0.137278f, +0.019346f, 0.193609f, 0.000049f, 0.205861f, 0.015309f, 0.138948f, 0.000477f, 0.288567f, 0.022866f, 0.310968f, 0.000052f, 0.273038f, 0.021899f, 0.152627f, 0.000148f, 0.255145f, +0.000426f, 0.006296f, 0.000006f, 0.005785f, 0.000328f, 0.004398f, 0.000057f, 0.007892f, 0.000329f, 0.006605f, 0.000004f, 0.005012f, 0.000314f, 0.003231f, 0.000012f, 0.004667f, +0.028736f, 0.289346f, 0.000134f, 0.288562f, 0.033800f, 0.308668f, 0.001924f, 0.601256f, 0.036542f, 0.500003f, 0.000152f, 0.411769f, 0.063654f, 0.446359f, 0.000787f, 0.699866f, +0.012635f, 0.223371f, 0.000040f, 0.144177f, 0.008672f, 0.139038f, 0.000333f, 0.175286f, 0.001881f, 0.045182f, 0.000005f, 0.024082f, 0.006863f, 0.084488f, 0.000057f, 0.085737f, +0.053179f, 0.671292f, 0.000922f, 0.625209f, 0.044350f, 0.507735f, 0.009420f, 0.923626f, 0.069487f, 1.191965f, 0.001078f, 0.916721f, 0.043361f, 0.381185f, 0.002000f, 0.558158f, +0.010122f, 0.188602f, 0.000982f, 0.151797f, 0.008215f, 0.138831f, 0.009763f, 0.218245f, 0.008639f, 0.218738f, 0.000750f, 0.145377f, 0.005372f, 0.069713f, 0.001387f, 0.088214f, +0.040686f, 0.516739f, 0.001288f, 0.451398f, 0.050436f, 0.580958f, 0.019560f, 0.991240f, 0.057197f, 0.987163f, 0.001620f, 0.712093f, 0.064917f, 0.574194f, 0.005468f, 0.788597f, +0.000738f, 0.011118f, 0.000005f, 0.008093f, 0.000455f, 0.006223f, 0.000038f, 0.008848f, 0.000150f, 0.003070f, 0.000001f, 0.001845f, 0.000584f, 0.006134f, 0.000011f, 0.007021f, +0.001096f, 0.011790f, 0.000042f, 0.012384f, 0.000822f, 0.008018f, 0.000384f, 0.016451f, 0.001954f, 0.028575f, 0.000067f, 0.024786f, 0.001303f, 0.009766f, 0.000132f, 0.016128f, +0.000609f, 0.009669f, 0.000130f, 0.008777f, 0.000444f, 0.006400f, 0.001162f, 0.011347f, 0.000709f, 0.015306f, 0.000135f, 0.011473f, 0.000471f, 0.005213f, 0.000268f, 0.007440f, +0.001586f, 0.017175f, 0.000111f, 0.016921f, 0.001768f, 0.017363f, 0.001510f, 0.033413f, 0.003044f, 0.044787f, 0.000190f, 0.036437f, 0.003692f, 0.027840f, 0.000685f, 0.043124f, +0.036557f, 0.409966f, 0.000165f, 0.220633f, 0.025160f, 0.255895f, 0.001391f, 0.268986f, 0.005095f, 0.077642f, 0.000021f, 0.034505f, 0.031265f, 0.244170f, 0.000375f, 0.206597f, +0.079031f, 0.632848f, 0.001973f, 0.491437f, 0.066093f, 0.479992f, 0.020208f, 0.728026f, 0.096689f, 1.052124f, 0.002159f, 0.674674f, 0.101469f, 0.565852f, 0.006739f, 0.690842f, +0.030718f, 0.363083f, 0.004291f, 0.243655f, 0.025001f, 0.268012f, 0.042772f, 0.351291f, 0.024547f, 0.394273f, 0.003067f, 0.218487f, 0.025673f, 0.211327f, 0.009540f, 0.222961f, +0.158125f, 1.273972f, 0.007208f, 0.927903f, 0.196564f, 1.436292f, 0.109742f, 2.043291f, 0.208135f, 2.278732f, 0.008486f, 1.370551f, 0.397281f, 2.229089f, 0.048176f, 2.552569f, +0.056658f, 1.028896f, 0.000005f, 0.464860f, 0.027164f, 0.447379f, 0.000027f, 0.394795f, 0.005666f, 0.139820f, 0.000000f, 0.052165f, 0.028154f, 0.356059f, 0.000006f, 0.252918f, +0.071688f, 0.929572f, 0.000032f, 0.606009f, 0.041763f, 0.491142f, 0.000230f, 0.625386f, 0.062932f, 1.108910f, 0.000025f, 0.596969f, 0.053479f, 0.482939f, 0.000064f, 0.494989f, +0.001357f, 0.025982f, 0.000003f, 0.014638f, 0.000770f, 0.013360f, 0.000024f, 0.014701f, 0.000778f, 0.020245f, 0.000002f, 0.009418f, 0.000659f, 0.008787f, 0.000004f, 0.007783f, +0.088380f, 1.153063f, 0.000073f, 0.705056f, 0.076533f, 0.905576f, 0.000770f, 1.081535f, 0.083473f, 1.479898f, 0.000061f, 0.747242f, 0.129021f, 1.172263f, 0.000282f, 1.126947f, +0.078359f, 1.794891f, 0.000043f, 0.710321f, 0.039593f, 0.822511f, 0.000269f, 0.635775f, 0.008663f, 0.269648f, 0.000004f, 0.088120f, 0.028047f, 0.447413f, 0.000041f, 0.278377f, +0.347276f, 5.680052f, 0.001064f, 3.243506f, 0.213216f, 3.162828f, 0.008002f, 3.527628f, 0.337026f, 7.490797f, 0.000924f, 3.532234f, 0.186610f, 2.125599f, 0.001521f, 1.908320f, +0.056813f, 1.371618f, 0.000974f, 0.676855f, 0.033947f, 0.743309f, 0.007129f, 0.716435f, 0.036013f, 1.181496f, 0.000552f, 0.481453f, 0.019872f, 0.334123f, 0.000906f, 0.259224f, +0.220524f, 3.629038f, 0.001234f, 1.943696f, 0.201256f, 3.003745f, 0.013792f, 3.142278f, 0.230255f, 5.149119f, 0.001152f, 2.277344f, 0.231889f, 2.657565f, 0.003452f, 2.237836f, +0.032417f, 0.633031f, 0.000040f, 0.282546f, 0.014729f, 0.260852f, 0.000220f, 0.227407f, 0.004892f, 0.129814f, 0.000005f, 0.047846f, 0.016926f, 0.230188f, 0.000055f, 0.161531f, +0.050695f, 0.706874f, 0.000342f, 0.455253f, 0.027988f, 0.353940f, 0.002312f, 0.445231f, 0.067156f, 1.272492f, 0.000405f, 0.676744f, 0.039738f, 0.385885f, 0.000713f, 0.390730f, +0.024208f, 0.498250f, 0.000914f, 0.277305f, 0.013007f, 0.242799f, 0.006013f, 0.263939f, 0.020946f, 0.585845f, 0.000707f, 0.269248f, 0.012352f, 0.177054f, 0.001240f, 0.154926f, +0.060923f, 0.854707f, 0.000750f, 0.516300f, 0.049996f, 0.636141f, 0.007542f, 0.750556f, 0.086830f, 1.655372f, 0.000957f, 0.825733f, 0.093452f, 0.913055f, 0.003062f, 0.867140f, +0.137481f, 1.997666f, 0.000110f, 0.659164f, 0.069659f, 0.917984f, 0.000680f, 0.591631f, 0.014231f, 0.280994f, 0.000010f, 0.076564f, 0.077486f, 0.784103f, 0.000164f, 0.406772f, +0.312965f, 3.247172f, 0.001381f, 1.546044f, 0.192686f, 1.813164f, 0.010411f, 1.686159f, 0.284380f, 4.009555f, 0.001122f, 1.576419f, 0.264811f, 1.913435f, 0.003108f, 1.432312f, +0.104553f, 1.601243f, 0.002581f, 0.658830f, 0.062648f, 0.870165f, 0.018938f, 0.699299f, 0.062053f, 1.291432f, 0.001370f, 0.438780f, 0.057587f, 0.614199f, 0.003781f, 0.397313f, +0.519730f, 5.425572f, 0.004186f, 2.422905f, 0.475642f, 4.503246f, 0.046924f, 3.927908f, 0.508097f, 7.207789f, 0.003660f, 2.657981f, 0.860561f, 6.256299f, 0.018440f, 4.392540f, +0.010795f, 0.206582f, 0.000002f, 0.142097f, 0.006822f, 0.118399f, 0.000012f, 0.159069f, 0.001104f, 0.028706f, 0.000000f, 0.016305f, 0.007560f, 0.100752f, 0.000003f, 0.108957f, +0.014795f, 0.202168f, 0.000011f, 0.200656f, 0.011361f, 0.140795f, 0.000107f, 0.272943f, 0.013280f, 0.246609f, 0.000009f, 0.202119f, 0.015554f, 0.148024f, 0.000032f, 0.230983f, +0.000328f, 0.006620f, 0.000001f, 0.005678f, 0.000245f, 0.004487f, 0.000013f, 0.007517f, 0.000192f, 0.005275f, 0.000001f, 0.003736f, 0.000225f, 0.003155f, 0.000003f, 0.004255f, +0.022273f, 0.306228f, 0.000031f, 0.285075f, 0.025423f, 0.317006f, 0.000438f, 0.576404f, 0.021510f, 0.401888f, 0.000027f, 0.308943f, 0.045824f, 0.438762f, 0.000171f, 0.642170f, +0.007415f, 0.178996f, 0.000007f, 0.107846f, 0.004939f, 0.108118f, 0.000057f, 0.127234f, 0.000838f, 0.027497f, 0.000001f, 0.013681f, 0.003741f, 0.062882f, 0.000009f, 0.059565f, +0.035598f, 0.613575f, 0.000187f, 0.533425f, 0.028808f, 0.450341f, 0.001850f, 0.764702f, 0.035326f, 0.827418f, 0.000166f, 0.594005f, 0.026958f, 0.323600f, 0.000376f, 0.442305f, +0.006823f, 0.173590f, 0.000200f, 0.130416f, 0.005374f, 0.123997f, 0.001931f, 0.181954f, 0.004422f, 0.152899f, 0.000116f, 0.094857f, 0.003363f, 0.059595f, 0.000263f, 0.070392f, +0.027603f, 0.478706f, 0.000264f, 0.390346f, 0.033205f, 0.522265f, 0.003894f, 0.831795f, 0.029471f, 0.694531f, 0.000252f, 0.467661f, 0.040907f, 0.494052f, 0.001042f, 0.633374f, +0.007354f, 0.151331f, 0.000015f, 0.102834f, 0.004404f, 0.082195f, 0.000113f, 0.109094f, 0.001135f, 0.031733f, 0.000002f, 0.017806f, 0.005411f, 0.077553f, 0.000030f, 0.082854f, +0.012457f, 0.183043f, 0.000144f, 0.179477f, 0.009065f, 0.120807f, 0.001282f, 0.231362f, 0.016874f, 0.336937f, 0.000174f, 0.272811f, 0.013761f, 0.140825f, 0.000423f, 0.217091f, +0.006969f, 0.151159f, 0.000450f, 0.128082f, 0.004936f, 0.097092f, 0.003905f, 0.160688f, 0.006166f, 0.181740f, 0.000356f, 0.127164f, 0.005012f, 0.075701f, 0.000861f, 0.100848f, +0.018280f, 0.270266f, 0.000385f, 0.248553f, 0.019774f, 0.265141f, 0.005105f, 0.476268f, 0.026641f, 0.535243f, 0.000502f, 0.406479f, 0.039519f, 0.406894f, 0.002216f, 0.588325f, +0.025065f, 0.383805f, 0.000034f, 0.192808f, 0.016740f, 0.232474f, 0.000280f, 0.228104f, 0.002653f, 0.055204f, 0.000003f, 0.022900f, 0.019909f, 0.212311f, 0.000072f, 0.167685f, +0.061805f, 0.675776f, 0.000467f, 0.489850f, 0.050157f, 0.497377f, 0.004638f, 0.704191f, 0.057426f, 0.853248f, 0.000388f, 0.510734f, 0.073701f, 0.561207f, 0.001480f, 0.639573f, +0.024190f, 0.390418f, 0.001022f, 0.244562f, 0.019105f, 0.279656f, 0.009884f, 0.342160f, 0.014681f, 0.321978f, 0.000555f, 0.166550f, 0.018777f, 0.211054f, 0.002110f, 0.207855f, +0.125333f, 1.378813f, 0.001728f, 0.937432f, 0.151189f, 1.508467f, 0.025526f, 2.003158f, 0.125290f, 1.873024f, 0.001545f, 1.051567f, 0.292471f, 2.240724f, 0.010726f, 2.395137f, +0.100808f, 1.104836f, 0.000008f, 0.558152f, 0.049007f, 0.487126f, 0.000047f, 0.480664f, 0.008912f, 0.132724f, 0.000001f, 0.055369f, 0.049767f, 0.379853f, 0.000010f, 0.301702f, +0.126900f, 0.993102f, 0.000055f, 0.723927f, 0.074963f, 0.532056f, 0.000395f, 0.757535f, 0.098479f, 1.047279f, 0.000038f, 0.630409f, 0.094052f, 0.512589f, 0.000108f, 0.587459f, +0.001765f, 0.020384f, 0.000004f, 0.012841f, 0.001014f, 0.010628f, 0.000030f, 0.013077f, 0.000894f, 0.014040f, 0.000002f, 0.007304f, 0.000851f, 0.006849f, 0.000005f, 0.006783f, +0.138885f, 1.093567f, 0.000109f, 0.747688f, 0.121952f, 0.870877f, 0.001173f, 1.162992f, 0.115958f, 1.240735f, 0.000081f, 0.700508f, 0.201431f, 1.104547f, 0.000421f, 1.187317f, +0.121086f, 1.673918f, 0.000064f, 0.740722f, 0.062038f, 0.777817f, 0.000403f, 0.672269f, 0.011834f, 0.222305f, 0.000006f, 0.081232f, 0.043059f, 0.414545f, 0.000061f, 0.288403f, +0.533903f, 5.270271f, 0.001565f, 3.365115f, 0.332390f, 2.975744f, 0.011929f, 3.711140f, 0.458042f, 6.144178f, 0.001200f, 3.239588f, 0.285030f, 1.959426f, 0.002222f, 1.966995f, +0.064141f, 0.934582f, 0.001052f, 0.515685f, 0.038863f, 0.513562f, 0.007804f, 0.553484f, 0.035942f, 0.711659f, 0.000527f, 0.324263f, 0.022290f, 0.226182f, 0.000972f, 0.196215f, +0.300971f, 2.989191f, 0.001610f, 1.790173f, 0.278521f, 2.508791f, 0.018252f, 2.934611f, 0.277801f, 3.749299f, 0.001329f, 1.854174f, 0.314424f, 2.174768f, 0.004475f, 2.047678f, +0.077389f, 0.912062f, 0.000090f, 0.455191f, 0.035654f, 0.381095f, 0.000509f, 0.371489f, 0.010324f, 0.165339f, 0.000011f, 0.068140f, 0.040146f, 0.329495f, 0.000125f, 0.258539f, +0.120407f, 1.013273f, 0.000777f, 0.729695f, 0.067407f, 0.514463f, 0.005326f, 0.723625f, 0.141005f, 1.612480f, 0.000814f, 0.958889f, 0.093771f, 0.549553f, 0.001609f, 0.622202f, +0.042223f, 0.524487f, 0.001524f, 0.326400f, 0.023005f, 0.259164f, 0.010169f, 0.315017f, 0.032296f, 0.545162f, 0.001043f, 0.280156f, 0.021405f, 0.185166f, 0.002055f, 0.181169f, +0.128455f, 1.087634f, 0.001513f, 0.734636f, 0.106893f, 0.820840f, 0.015421f, 1.082911f, 0.161844f, 1.862157f, 0.001705f, 1.038639f, 0.195762f, 1.154328f, 0.006134f, 1.225818f, +0.236001f, 2.069598f, 0.000180f, 0.763592f, 0.121252f, 0.964357f, 0.001133f, 0.694957f, 0.021595f, 0.257345f, 0.000015f, 0.078406f, 0.132149f, 0.807055f, 0.000268f, 0.468151f, +0.534504f, 3.346979f, 0.002255f, 1.781862f, 0.333691f, 1.895066f, 0.017241f, 1.970562f, 0.429348f, 3.653416f, 0.001620f, 1.606124f, 0.449322f, 1.959424f, 0.005042f, 1.640049f, +0.131128f, 1.212017f, 0.003095f, 0.557609f, 0.079671f, 0.667871f, 0.023031f, 0.600148f, 0.068798f, 0.864128f, 0.001452f, 0.328290f, 0.071754f, 0.461878f, 0.004505f, 0.334084f, +0.787978f, 4.964491f, 0.006070f, 2.478963f, 0.731234f, 4.178248f, 0.068984f, 4.075063f, 0.680986f, 5.830240f, 0.004691f, 2.404035f, 1.296238f, 5.687396f, 0.026561f, 4.464946f, +0.000070f, 0.000975f, 0.000000f, 0.000719f, 0.000062f, 0.000785f, 0.000000f, 0.001129f, 0.000011f, 0.000204f, 0.000000f, 0.000124f, 0.000079f, 0.000767f, 0.000000f, 0.000889f, +0.000165f, 0.001654f, 0.000000f, 0.001759f, 0.000178f, 0.001618f, 0.000006f, 0.003360f, 0.000223f, 0.003034f, 0.000001f, 0.002664f, 0.000280f, 0.001954f, 0.000002f, 0.003266f, +0.000002f, 0.000024f, 0.000000f, 0.000022f, 0.000002f, 0.000023f, 0.000000f, 0.000041f, 0.000001f, 0.000029f, 0.000000f, 0.000022f, 0.000002f, 0.000018f, 0.000000f, 0.000027f, +0.000153f, 0.001545f, 0.000001f, 0.001541f, 0.000246f, 0.002246f, 0.000014f, 0.004375f, 0.000223f, 0.003049f, 0.000001f, 0.002511f, 0.000509f, 0.003571f, 0.000006f, 0.005600f, +0.000064f, 0.001138f, 0.000000f, 0.000735f, 0.000060f, 0.000965f, 0.000002f, 0.001217f, 0.000011f, 0.000263f, 0.000000f, 0.000140f, 0.000052f, 0.000645f, 0.000000f, 0.000654f, +0.000536f, 0.006763f, 0.000009f, 0.006299f, 0.000609f, 0.006969f, 0.000129f, 0.012677f, 0.000799f, 0.013710f, 0.000012f, 0.010544f, 0.000654f, 0.005753f, 0.000030f, 0.008424f, +0.000045f, 0.000844f, 0.000004f, 0.000680f, 0.000050f, 0.000847f, 0.000060f, 0.001331f, 0.000044f, 0.001118f, 0.000004f, 0.000743f, 0.000036f, 0.000468f, 0.000009f, 0.000592f, +0.000256f, 0.003254f, 0.000008f, 0.002842f, 0.000433f, 0.004984f, 0.000168f, 0.008503f, 0.000411f, 0.007096f, 0.000012f, 0.005119f, 0.000612f, 0.005416f, 0.000052f, 0.007439f, +0.000005f, 0.000072f, 0.000000f, 0.000053f, 0.000004f, 0.000055f, 0.000000f, 0.000078f, 0.000001f, 0.000023f, 0.000000f, 0.000014f, 0.000006f, 0.000060f, 0.000000f, 0.000068f, +0.000014f, 0.000151f, 0.000001f, 0.000159f, 0.000014f, 0.000140f, 0.000007f, 0.000288f, 0.000029f, 0.000419f, 0.000001f, 0.000364f, 0.000025f, 0.000188f, 0.000003f, 0.000310f, +0.000003f, 0.000055f, 0.000001f, 0.000050f, 0.000003f, 0.000050f, 0.000009f, 0.000088f, 0.000005f, 0.000100f, 0.000001f, 0.000075f, 0.000004f, 0.000045f, 0.000002f, 0.000064f, +0.000013f, 0.000138f, 0.000001f, 0.000136f, 0.000019f, 0.000190f, 0.000017f, 0.000366f, 0.000028f, 0.000411f, 0.000002f, 0.000334f, 0.000044f, 0.000335f, 0.000008f, 0.000519f, +0.000170f, 0.001909f, 0.000001f, 0.001027f, 0.000160f, 0.001623f, 0.000009f, 0.001706f, 0.000027f, 0.000413f, 0.000000f, 0.000183f, 0.000218f, 0.001703f, 0.000003f, 0.001441f, +0.000728f, 0.005827f, 0.000018f, 0.004525f, 0.000829f, 0.006021f, 0.000253f, 0.009132f, 0.001016f, 0.011059f, 0.000023f, 0.007092f, 0.001400f, 0.007805f, 0.000093f, 0.009529f, +0.000126f, 0.001485f, 0.000018f, 0.000997f, 0.000139f, 0.001494f, 0.000238f, 0.001958f, 0.000115f, 0.001841f, 0.000014f, 0.001020f, 0.000157f, 0.001295f, 0.000058f, 0.001366f, +0.000910f, 0.007331f, 0.000041f, 0.005340f, 0.001541f, 0.011260f, 0.000860f, 0.016019f, 0.001367f, 0.014971f, 0.000056f, 0.009004f, 0.003425f, 0.019216f, 0.000415f, 0.022005f, +0.000290f, 0.005262f, 0.000000f, 0.002377f, 0.000189f, 0.003117f, 0.000000f, 0.002751f, 0.000033f, 0.000816f, 0.000000f, 0.000305f, 0.000216f, 0.002728f, 0.000000f, 0.001938f, +0.000725f, 0.009402f, 0.000000f, 0.006129f, 0.000575f, 0.006767f, 0.000003f, 0.008617f, 0.000727f, 0.012804f, 0.000000f, 0.006893f, 0.000810f, 0.007317f, 0.000001f, 0.007500f, +0.000006f, 0.000117f, 0.000000f, 0.000066f, 0.000005f, 0.000082f, 0.000000f, 0.000090f, 0.000004f, 0.000104f, 0.000000f, 0.000048f, 0.000004f, 0.000059f, 0.000000f, 0.000052f, +0.000559f, 0.007289f, 0.000000f, 0.004457f, 0.000659f, 0.007799f, 0.000007f, 0.009314f, 0.000602f, 0.010680f, 0.000000f, 0.005393f, 0.001222f, 0.011101f, 0.000003f, 0.010672f, +0.000472f, 0.010822f, 0.000000f, 0.004283f, 0.000325f, 0.006756f, 0.000002f, 0.005222f, 0.000060f, 0.001856f, 0.000000f, 0.000607f, 0.000253f, 0.004041f, 0.000000f, 0.002514f, +0.004141f, 0.067726f, 0.000013f, 0.038674f, 0.003464f, 0.051377f, 0.000130f, 0.057303f, 0.004588f, 0.101968f, 0.000013f, 0.048082f, 0.003333f, 0.037967f, 0.000027f, 0.034086f, +0.000301f, 0.007267f, 0.000005f, 0.003586f, 0.000245f, 0.005365f, 0.000051f, 0.005171f, 0.000218f, 0.007146f, 0.000003f, 0.002912f, 0.000158f, 0.002652f, 0.000007f, 0.002057f, +0.001643f, 0.027045f, 0.000009f, 0.014485f, 0.002043f, 0.030497f, 0.000140f, 0.031903f, 0.001959f, 0.043809f, 0.000010f, 0.019376f, 0.002589f, 0.029669f, 0.000039f, 0.024984f, +0.000249f, 0.004868f, 0.000000f, 0.002173f, 0.000154f, 0.002733f, 0.000002f, 0.002383f, 0.000043f, 0.001140f, 0.000000f, 0.000420f, 0.000195f, 0.002652f, 0.000001f, 0.001861f, +0.000771f, 0.010750f, 0.000005f, 0.006923f, 0.000580f, 0.007333f, 0.000048f, 0.009224f, 0.001166f, 0.022093f, 0.000007f, 0.011749f, 0.000905f, 0.008791f, 0.000016f, 0.008901f, +0.000164f, 0.003367f, 0.000006f, 0.001874f, 0.000120f, 0.002235f, 0.000055f, 0.002430f, 0.000162f, 0.004519f, 0.000005f, 0.002077f, 0.000125f, 0.001792f, 0.000013f, 0.001568f, +0.000579f, 0.008124f, 0.000007f, 0.004907f, 0.000647f, 0.008238f, 0.000098f, 0.009719f, 0.000942f, 0.017963f, 0.000010f, 0.008960f, 0.001331f, 0.013001f, 0.000044f, 0.012347f, +0.000758f, 0.011008f, 0.000001f, 0.003632f, 0.000523f, 0.006891f, 0.000005f, 0.004441f, 0.000090f, 0.001768f, 0.000000f, 0.000482f, 0.000640f, 0.006473f, 0.000001f, 0.003358f, +0.003410f, 0.035384f, 0.000015f, 0.016847f, 0.002861f, 0.026917f, 0.000155f, 0.025032f, 0.003538f, 0.049880f, 0.000014f, 0.019611f, 0.004323f, 0.031235f, 0.000051f, 0.023381f, +0.000506f, 0.007753f, 0.000012f, 0.003190f, 0.000413f, 0.005740f, 0.000125f, 0.004613f, 0.000343f, 0.007139f, 0.000008f, 0.002425f, 0.000418f, 0.004455f, 0.000027f, 0.002882f, +0.003540f, 0.036952f, 0.000029f, 0.016502f, 0.004413f, 0.041784f, 0.000435f, 0.036446f, 0.003951f, 0.056044f, 0.000028f, 0.020667f, 0.008780f, 0.063832f, 0.000188f, 0.044817f, +0.000059f, 0.001127f, 0.000000f, 0.000775f, 0.000051f, 0.000880f, 0.000000f, 0.001182f, 0.000007f, 0.000179f, 0.000000f, 0.000102f, 0.000062f, 0.000823f, 0.000000f, 0.000890f, +0.000160f, 0.002181f, 0.000000f, 0.002164f, 0.000167f, 0.002069f, 0.000002f, 0.004011f, 0.000164f, 0.003037f, 0.000000f, 0.002489f, 0.000251f, 0.002392f, 0.000001f, 0.003732f, +0.000002f, 0.000032f, 0.000000f, 0.000027f, 0.000002f, 0.000029f, 0.000000f, 0.000049f, 0.000001f, 0.000029f, 0.000000f, 0.000020f, 0.000002f, 0.000023f, 0.000000f, 0.000031f, +0.000150f, 0.002065f, 0.000000f, 0.001922f, 0.000234f, 0.002912f, 0.000004f, 0.005294f, 0.000166f, 0.003093f, 0.000000f, 0.002378f, 0.000463f, 0.004431f, 0.000002f, 0.006486f, +0.000048f, 0.001151f, 0.000000f, 0.000693f, 0.000043f, 0.000947f, 0.000001f, 0.001115f, 0.000006f, 0.000202f, 0.000000f, 0.000100f, 0.000036f, 0.000606f, 0.000000f, 0.000574f, +0.000453f, 0.007802f, 0.000002f, 0.006783f, 0.000499f, 0.007802f, 0.000032f, 0.013248f, 0.000513f, 0.012012f, 0.000002f, 0.008624f, 0.000514f, 0.006165f, 0.000007f, 0.008426f, +0.000039f, 0.000981f, 0.000001f, 0.000737f, 0.000041f, 0.000955f, 0.000015f, 0.001401f, 0.000029f, 0.000986f, 0.000001f, 0.000612f, 0.000028f, 0.000504f, 0.000002f, 0.000596f, +0.000219f, 0.003805f, 0.000002f, 0.003102f, 0.000360f, 0.005655f, 0.000042f, 0.009007f, 0.000267f, 0.006302f, 0.000002f, 0.004243f, 0.000487f, 0.005882f, 0.000012f, 0.007541f, +0.000060f, 0.001241f, 0.000000f, 0.000843f, 0.000049f, 0.000918f, 0.000001f, 0.001219f, 0.000011f, 0.000297f, 0.000000f, 0.000167f, 0.000066f, 0.000953f, 0.000000f, 0.001018f, +0.000202f, 0.002969f, 0.000002f, 0.002911f, 0.000200f, 0.002669f, 0.000028f, 0.005112f, 0.000312f, 0.006239f, 0.000003f, 0.005051f, 0.000334f, 0.003422f, 0.000010f, 0.005275f, +0.000050f, 0.001089f, 0.000003f, 0.000923f, 0.000048f, 0.000953f, 0.000038f, 0.001578f, 0.000051f, 0.001495f, 0.000003f, 0.001046f, 0.000054f, 0.000817f, 0.000009f, 0.001089f, +0.000185f, 0.002740f, 0.000004f, 0.002520f, 0.000273f, 0.003662f, 0.000071f, 0.006577f, 0.000308f, 0.006194f, 0.000006f, 0.004704f, 0.000600f, 0.006179f, 0.000034f, 0.008934f, +0.000147f, 0.002256f, 0.000000f, 0.001133f, 0.000134f, 0.001861f, 0.000002f, 0.001826f, 0.000018f, 0.000370f, 0.000000f, 0.000154f, 0.000175f, 0.001869f, 0.000001f, 0.001476f, +0.000718f, 0.007853f, 0.000005f, 0.005693f, 0.000794f, 0.007875f, 0.000073f, 0.011149f, 0.000762f, 0.011321f, 0.000005f, 0.006776f, 0.001283f, 0.009770f, 0.000026f, 0.011135f, +0.000125f, 0.002016f, 0.000005f, 0.001263f, 0.000134f, 0.001967f, 0.000070f, 0.002407f, 0.000087f, 0.001898f, 0.000003f, 0.000982f, 0.000145f, 0.001633f, 0.000016f, 0.001608f, +0.000910f, 0.010015f, 0.000013f, 0.006809f, 0.001496f, 0.014927f, 0.000253f, 0.019823f, 0.001039f, 0.015532f, 0.000013f, 0.008720f, 0.003182f, 0.024382f, 0.000117f, 0.026062f, +0.000731f, 0.008016f, 0.000000f, 0.004049f, 0.000484f, 0.004815f, 0.000000f, 0.004751f, 0.000074f, 0.001099f, 0.000000f, 0.000459f, 0.000541f, 0.004128f, 0.000000f, 0.003279f, +0.001821f, 0.014248f, 0.000001f, 0.010386f, 0.001465f, 0.010400f, 0.000008f, 0.014807f, 0.001613f, 0.017154f, 0.000001f, 0.010326f, 0.002021f, 0.011017f, 0.000002f, 0.012626f, +0.000011f, 0.000130f, 0.000000f, 0.000082f, 0.000009f, 0.000092f, 0.000000f, 0.000114f, 0.000007f, 0.000102f, 0.000000f, 0.000053f, 0.000008f, 0.000065f, 0.000000f, 0.000065f, +0.001245f, 0.009806f, 0.000001f, 0.006705f, 0.001490f, 0.010639f, 0.000014f, 0.014208f, 0.001187f, 0.012702f, 0.000001f, 0.007172f, 0.002706f, 0.014838f, 0.000006f, 0.015950f, +0.001036f, 0.014317f, 0.000001f, 0.006336f, 0.000723f, 0.009064f, 0.000005f, 0.007834f, 0.000116f, 0.002171f, 0.000000f, 0.000793f, 0.000552f, 0.005312f, 0.000001f, 0.003695f, +0.009031f, 0.089143f, 0.000026f, 0.056918f, 0.007659f, 0.068572f, 0.000275f, 0.085518f, 0.008845f, 0.118645f, 0.000023f, 0.062557f, 0.007222f, 0.049649f, 0.000056f, 0.049841f, +0.000482f, 0.007024f, 0.000008f, 0.003876f, 0.000398f, 0.005258f, 0.000080f, 0.005667f, 0.000308f, 0.006106f, 0.000005f, 0.002782f, 0.000251f, 0.002547f, 0.000011f, 0.002209f, +0.003182f, 0.031601f, 0.000017f, 0.018925f, 0.004011f, 0.036133f, 0.000263f, 0.042266f, 0.003353f, 0.045251f, 0.000016f, 0.022379f, 0.004980f, 0.034442f, 0.000071f, 0.032429f, +0.000844f, 0.009950f, 0.000001f, 0.004966f, 0.000530f, 0.005664f, 0.000008f, 0.005521f, 0.000129f, 0.002059f, 0.000000f, 0.000849f, 0.000656f, 0.005385f, 0.000002f, 0.004225f, +0.002598f, 0.021859f, 0.000017f, 0.015742f, 0.001981f, 0.015120f, 0.000157f, 0.021268f, 0.003473f, 0.039713f, 0.000020f, 0.023616f, 0.003030f, 0.017760f, 0.000052f, 0.020108f, +0.000405f, 0.005028f, 0.000015f, 0.003129f, 0.000300f, 0.003384f, 0.000133f, 0.004114f, 0.000353f, 0.005966f, 0.000011f, 0.003066f, 0.000307f, 0.002659f, 0.000030f, 0.002602f, +0.001732f, 0.014665f, 0.000020f, 0.009905f, 0.001964f, 0.015078f, 0.000283f, 0.019893f, 0.002491f, 0.028665f, 0.000026f, 0.015988f, 0.003954f, 0.023316f, 0.000124f, 0.024760f, +0.001845f, 0.016178f, 0.000001f, 0.005969f, 0.001291f, 0.010270f, 0.000012f, 0.007401f, 0.000193f, 0.002297f, 0.000000f, 0.000700f, 0.001547f, 0.009451f, 0.000003f, 0.005482f, +0.008262f, 0.051737f, 0.000035f, 0.027544f, 0.007027f, 0.039909f, 0.000363f, 0.041499f, 0.007577f, 0.064474f, 0.000029f, 0.028344f, 0.010405f, 0.045374f, 0.000117f, 0.037978f, +0.000901f, 0.008325f, 0.000021f, 0.003830f, 0.000746f, 0.006250f, 0.000216f, 0.005616f, 0.000539f, 0.006776f, 0.000011f, 0.002574f, 0.000738f, 0.004752f, 0.000046f, 0.003438f, +0.007613f, 0.047964f, 0.000059f, 0.023951f, 0.009625f, 0.054997f, 0.000908f, 0.053638f, 0.007511f, 0.064308f, 0.000052f, 0.026517f, 0.018761f, 0.082317f, 0.000384f, 0.064624f, +0.023781f, 0.333295f, 0.000011f, 0.245602f, 0.016065f, 0.204207f, 0.000091f, 0.293913f, 0.003021f, 0.057538f, 0.000001f, 0.035012f, 0.019309f, 0.188469f, 0.000024f, 0.218348f, +0.029034f, 0.290563f, 0.000074f, 0.308950f, 0.023834f, 0.216322f, 0.000743f, 0.449256f, 0.032379f, 0.440337f, 0.000074f, 0.386627f, 0.035392f, 0.246666f, 0.000240f, 0.412348f, +0.000455f, 0.006727f, 0.000006f, 0.006181f, 0.000364f, 0.004874f, 0.000063f, 0.008748f, 0.000332f, 0.006659f, 0.000004f, 0.005053f, 0.000361f, 0.003718f, 0.000014f, 0.005370f, +0.042448f, 0.427418f, 0.000197f, 0.426261f, 0.051796f, 0.473001f, 0.002949f, 0.921360f, 0.050931f, 0.696888f, 0.000212f, 0.573911f, 0.101257f, 0.710043f, 0.001252f, 1.113306f, +0.021978f, 0.388527f, 0.000069f, 0.250778f, 0.015647f, 0.250878f, 0.000601f, 0.316283f, 0.003087f, 0.074150f, 0.000009f, 0.039522f, 0.012854f, 0.158253f, 0.000107f, 0.160593f, +0.093986f, 1.186412f, 0.001630f, 1.104968f, 0.081311f, 0.930884f, 0.017270f, 1.693382f, 0.115873f, 1.987662f, 0.001797f, 1.528677f, 0.082525f, 0.725477f, 0.003807f, 1.062296f, +0.012736f, 0.237314f, 0.001236f, 0.191002f, 0.010724f, 0.181216f, 0.012744f, 0.284876f, 0.010256f, 0.259689f, 0.000890f, 0.172595f, 0.007280f, 0.094462f, 0.001879f, 0.119530f, +0.070776f, 0.898912f, 0.002241f, 0.785246f, 0.091016f, 1.048397f, 0.035298f, 1.788790f, 0.093880f, 1.620279f, 0.002659f, 1.168793f, 0.121611f, 1.075645f, 0.010244f, 1.477288f, +0.001136f, 0.017128f, 0.000008f, 0.012469f, 0.000728f, 0.009945f, 0.000062f, 0.014141f, 0.000218f, 0.004462f, 0.000001f, 0.002682f, 0.000970f, 0.010177f, 0.000018f, 0.011648f, +0.001715f, 0.018455f, 0.000065f, 0.019386f, 0.001334f, 0.013021f, 0.000624f, 0.026715f, 0.002886f, 0.042205f, 0.000099f, 0.036608f, 0.002197f, 0.016462f, 0.000223f, 0.027187f, +0.000678f, 0.010775f, 0.000145f, 0.009781f, 0.000514f, 0.007399f, 0.001344f, 0.013118f, 0.000746f, 0.016095f, 0.000142f, 0.012065f, 0.000566f, 0.006257f, 0.000321f, 0.008929f, +0.002444f, 0.026463f, 0.000170f, 0.026072f, 0.002826f, 0.027753f, 0.002413f, 0.053406f, 0.004425f, 0.065109f, 0.000276f, 0.052971f, 0.006126f, 0.046193f, 0.001136f, 0.071551f, +0.068374f, 0.766772f, 0.000309f, 0.412657f, 0.048816f, 0.496496f, 0.002699f, 0.521895f, 0.008991f, 0.137016f, 0.000036f, 0.060891f, 0.062970f, 0.491786f, 0.000756f, 0.416108f, +0.150192f, 1.202675f, 0.003750f, 0.933935f, 0.130298f, 0.946275f, 0.039840f, 1.435260f, 0.173373f, 1.886560f, 0.003871f, 1.209757f, 0.207657f, 1.158021f, 0.013791f, 1.413814f, +0.041562f, 0.491255f, 0.005805f, 0.329667f, 0.035091f, 0.376174f, 0.060033f, 0.493063f, 0.031337f, 0.503330f, 0.003915f, 0.278920f, 0.037406f, 0.307907f, 0.013899f, 0.324859f, +0.295781f, 2.383040f, 0.013483f, 1.735698f, 0.381426f, 2.787073f, 0.212950f, 3.964934f, 0.367342f, 4.021788f, 0.014977f, 2.418917f, 0.800264f, 4.490169f, 0.097044f, 5.141772f, +0.080402f, 1.460075f, 0.000007f, 0.659669f, 0.039988f, 0.658589f, 0.000040f, 0.581179f, 0.007586f, 0.187209f, 0.000001f, 0.069845f, 0.043024f, 0.544114f, 0.000009f, 0.386499f, +0.103366f, 1.340347f, 0.000046f, 0.873803f, 0.062468f, 0.734641f, 0.000344f, 0.935441f, 0.085617f, 1.508638f, 0.000034f, 0.812157f, 0.083039f, 0.749877f, 0.000099f, 0.768588f, +0.001394f, 0.026672f, 0.000004f, 0.015027f, 0.000820f, 0.014228f, 0.000025f, 0.015656f, 0.000754f, 0.019609f, 0.000002f, 0.009122f, 0.000729f, 0.009714f, 0.000005f, 0.008604f, +0.125433f, 1.636474f, 0.000103f, 1.000644f, 0.112678f, 1.333262f, 0.001133f, 1.592323f, 0.111778f, 1.981721f, 0.000082f, 1.000627f, 0.197187f, 1.791617f, 0.000431f, 1.722358f, +0.130950f, 2.999523f, 0.000073f, 1.187050f, 0.068638f, 1.425905f, 0.000466f, 1.102179f, 0.013659f, 0.425174f, 0.000007f, 0.138945f, 0.050474f, 0.805169f, 0.000074f, 0.500969f, +0.589684f, 9.644877f, 0.001807f, 5.507559f, 0.375577f, 5.571272f, 0.014096f, 6.213863f, 0.539960f, 12.001270f, 0.001480f, 5.659115f, 0.341228f, 3.886778f, 0.002782f, 3.489471f, +0.068682f, 1.658172f, 0.001178f, 0.818261f, 0.042573f, 0.932180f, 0.008940f, 0.898478f, 0.041078f, 1.347669f, 0.000630f, 0.549167f, 0.025871f, 0.434977f, 0.001180f, 0.337471f, +0.368572f, 6.065380f, 0.002062f, 3.248589f, 0.348940f, 5.207915f, 0.023912f, 5.448106f, 0.363103f, 8.119961f, 0.001817f, 3.591284f, 0.417359f, 4.783155f, 0.006212f, 4.027714f, +0.047982f, 0.936977f, 0.000059f, 0.418209f, 0.022615f, 0.400527f, 0.000338f, 0.349174f, 0.006832f, 0.181293f, 0.000007f, 0.066820f, 0.026979f, 0.366903f, 0.000088f, 0.257468f, +0.076242f, 1.063106f, 0.000514f, 0.684679f, 0.043666f, 0.552203f, 0.003608f, 0.694631f, 0.095296f, 1.805692f, 0.000575f, 0.960314f, 0.064359f, 0.624966f, 0.001155f, 0.632811f, +0.025920f, 0.533498f, 0.000978f, 0.296922f, 0.014448f, 0.269692f, 0.006679f, 0.293173f, 0.021161f, 0.591866f, 0.000714f, 0.272015f, 0.014243f, 0.204153f, 0.001430f, 0.178638f, +0.090185f, 1.265242f, 0.001111f, 0.764290f, 0.076776f, 0.976886f, 0.011583f, 1.152587f, 0.121277f, 2.312099f, 0.001336f, 1.153321f, 0.148974f, 1.455516f, 0.004882f, 1.382322f, +0.247049f, 3.589733f, 0.000197f, 1.184494f, 0.129853f, 1.711233f, 0.001269f, 1.102871f, 0.024128f, 0.476422f, 0.000017f, 0.129814f, 0.149944f, 1.517317f, 0.000318f, 0.787145f, +0.571433f, 5.928908f, 0.002521f, 2.822872f, 0.364968f, 3.434322f, 0.019719f, 3.193760f, 0.489918f, 6.907490f, 0.001933f, 2.715787f, 0.520679f, 3.762247f, 0.006110f, 2.816250f, +0.135912f, 2.081510f, 0.003355f, 0.856436f, 0.084481f, 1.173431f, 0.025539f, 0.943016f, 0.076110f, 1.583972f, 0.001680f, 0.538174f, 0.080613f, 0.859795f, 0.005293f, 0.556184f, +0.934048f, 9.750728f, 0.007524f, 4.354396f, 0.886761f, 8.395597f, 0.087482f, 7.322970f, 0.861575f, 12.222170f, 0.006207f, 4.507109f, 1.665471f, 12.108020f, 0.035687f, 8.501024f, +0.020501f, 0.392336f, 0.000003f, 0.269869f, 0.013440f, 0.233264f, 0.000023f, 0.313391f, 0.001978f, 0.051439f, 0.000000f, 0.029218f, 0.015461f, 0.206055f, 0.000006f, 0.222836f, +0.028550f, 0.390130f, 0.000022f, 0.387213f, 0.022742f, 0.281850f, 0.000214f, 0.546391f, 0.024180f, 0.449013f, 0.000017f, 0.368009f, 0.032323f, 0.307605f, 0.000066f, 0.480000f, +0.000451f, 0.009096f, 0.000002f, 0.007801f, 0.000350f, 0.006395f, 0.000018f, 0.010714f, 0.000249f, 0.006838f, 0.000001f, 0.004843f, 0.000332f, 0.004668f, 0.000004f, 0.006295f, +0.042305f, 0.581652f, 0.000059f, 0.541474f, 0.050093f, 0.624627f, 0.000862f, 1.135742f, 0.038550f, 0.720242f, 0.000048f, 0.553671f, 0.093729f, 0.897451f, 0.000350f, 1.313508f, +0.016584f, 0.400332f, 0.000016f, 0.241202f, 0.011458f, 0.250847f, 0.000133f, 0.295199f, 0.001769f, 0.058025f, 0.000002f, 0.028869f, 0.009009f, 0.151449f, 0.000023f, 0.143461f, +0.080896f, 1.394358f, 0.000424f, 1.212217f, 0.067914f, 1.061653f, 0.004362f, 1.802742f, 0.075744f, 1.774133f, 0.000355f, 1.273654f, 0.065972f, 0.791915f, 0.000920f, 1.082411f, +0.011039f, 0.280855f, 0.000324f, 0.211003f, 0.009019f, 0.208115f, 0.003241f, 0.305389f, 0.006751f, 0.233409f, 0.000177f, 0.144805f, 0.005860f, 0.103832f, 0.000457f, 0.122643f, +0.061743f, 1.070773f, 0.000591f, 0.873128f, 0.077050f, 1.211865f, 0.009037f, 1.930098f, 0.062199f, 1.465801f, 0.000533f, 0.986994f, 0.098535f, 1.190050f, 0.002510f, 1.525644f, +0.014567f, 0.299773f, 0.000030f, 0.203705f, 0.009050f, 0.168907f, 0.000231f, 0.224182f, 0.002121f, 0.059310f, 0.000004f, 0.033281f, 0.011543f, 0.165435f, 0.000064f, 0.176743f, +0.025073f, 0.368426f, 0.000289f, 0.361247f, 0.018928f, 0.252245f, 0.002676f, 0.483083f, 0.032045f, 0.639881f, 0.000331f, 0.518098f, 0.029828f, 0.305240f, 0.000916f, 0.470547f, +0.009987f, 0.216611f, 0.000645f, 0.183542f, 0.007337f, 0.144334f, 0.005805f, 0.238872f, 0.008337f, 0.245727f, 0.000482f, 0.171936f, 0.007734f, 0.116820f, 0.001329f, 0.155624f, +0.036216f, 0.535438f, 0.000763f, 0.492422f, 0.040639f, 0.544917f, 0.010493f, 0.978822f, 0.049800f, 1.000515f, 0.000939f, 0.759821f, 0.084311f, 0.868089f, 0.004728f, 1.255162f, +0.060278f, 0.923023f, 0.000082f, 0.463689f, 0.041762f, 0.579976f, 0.000698f, 0.569075f, 0.006020f, 0.125263f, 0.000007f, 0.051963f, 0.051561f, 0.549842f, 0.000187f, 0.434270f, +0.151027f, 1.651333f, 0.001140f, 1.197002f, 0.127144f, 1.260815f, 0.011756f, 1.785075f, 0.132402f, 1.967260f, 0.000894f, 1.177554f, 0.193941f, 1.476789f, 0.003895f, 1.683007f, +0.042085f, 0.679224f, 0.001778f, 0.425474f, 0.034481f, 0.504711f, 0.017839f, 0.617515f, 0.024098f, 0.528523f, 0.000910f, 0.273390f, 0.035179f, 0.395404f, 0.003953f, 0.389411f, +0.301454f, 3.316340f, 0.004156f, 2.254725f, 0.377232f, 3.763779f, 0.063691f, 4.998083f, 0.284332f, 4.250615f, 0.003506f, 2.386411f, 0.757530f, 5.803716f, 0.027780f, 6.203661f, +0.129744f, 1.421973f, 0.000010f, 0.718367f, 0.065432f, 0.650384f, 0.000062f, 0.641755f, 0.010822f, 0.161175f, 0.000001f, 0.067238f, 0.068977f, 0.526469f, 0.000014f, 0.418153f, +0.165953f, 1.298726f, 0.000071f, 0.946713f, 0.101696f, 0.721797f, 0.000536f, 1.027687f, 0.121512f, 1.292232f, 0.000047f, 0.777858f, 0.132451f, 0.721867f, 0.000152f, 0.827305f, +0.001643f, 0.018979f, 0.000004f, 0.011955f, 0.000980f, 0.010265f, 0.000029f, 0.012631f, 0.000786f, 0.012334f, 0.000002f, 0.006416f, 0.000854f, 0.006867f, 0.000005f, 0.006801f, +0.178772f, 1.407638f, 0.000140f, 0.962423f, 0.162843f, 1.162885f, 0.001566f, 1.552948f, 0.140832f, 1.506883f, 0.000099f, 0.850773f, 0.279213f, 1.531066f, 0.000583f, 1.645798f, +0.183526f, 2.537102f, 0.000097f, 1.122688f, 0.097543f, 1.222970f, 0.000633f, 1.057016f, 0.016923f, 0.317912f, 0.000008f, 0.116168f, 0.070280f, 0.676612f, 0.000099f, 0.470726f, +0.822236f, 8.116466f, 0.002409f, 5.182435f, 0.531026f, 4.754053f, 0.019058f, 5.928923f, 0.665571f, 8.927964f, 0.001744f, 4.707370f, 0.472703f, 3.249577f, 0.003685f, 3.262129f, +0.070327f, 1.024716f, 0.001153f, 0.565419f, 0.044203f, 0.584135f, 0.008876f, 0.629543f, 0.037183f, 0.736228f, 0.000545f, 0.335458f, 0.026318f, 0.267059f, 0.001148f, 0.231676f, +0.456227f, 4.531163f, 0.002441f, 2.713632f, 0.437974f, 3.945073f, 0.028702f, 4.614675f, 0.397323f, 5.362419f, 0.001901f, 2.651924f, 0.513258f, 3.550037f, 0.007306f, 3.342579f, +0.103890f, 1.224385f, 0.000121f, 0.611065f, 0.049652f, 0.530714f, 0.000709f, 0.517338f, 0.013077f, 0.209423f, 0.000014f, 0.086308f, 0.058036f, 0.476329f, 0.000180f, 0.373752f, +0.164239f, 1.382134f, 0.001059f, 0.995325f, 0.095381f, 0.727967f, 0.007536f, 1.023933f, 0.181473f, 2.075260f, 0.001047f, 1.234089f, 0.137739f, 0.807230f, 0.002364f, 0.913944f, +0.041004f, 0.509343f, 0.001480f, 0.316975f, 0.023175f, 0.261087f, 0.010245f, 0.317354f, 0.029593f, 0.499524f, 0.000955f, 0.256702f, 0.022385f, 0.193643f, 0.002149f, 0.189463f, +0.172463f, 1.460255f, 0.002031f, 0.986320f, 0.148878f, 1.143243f, 0.021478f, 1.508248f, 0.205021f, 2.358939f, 0.002160f, 1.315725f, 0.283034f, 1.668933f, 0.008869f, 1.772294f, +0.384629f, 3.372989f, 0.000293f, 1.244486f, 0.204999f, 1.630427f, 0.001915f, 1.174955f, 0.033208f, 0.395730f, 0.000023f, 0.120568f, 0.231929f, 1.416433f, 0.000471f, 0.821634f, +0.885136f, 5.542582f, 0.003734f, 2.950754f, 0.573242f, 3.255501f, 0.029617f, 3.385194f, 0.670846f, 5.708378f, 0.002531f, 2.509532f, 0.801274f, 3.494230f, 0.008992f, 2.924690f, +0.154599f, 1.428958f, 0.003649f, 0.657416f, 0.097442f, 0.816842f, 0.028169f, 0.734013f, 0.076532f, 0.961266f, 0.001616f, 0.365194f, 0.091101f, 0.586412f, 0.005720f, 0.424161f, +1.284385f, 8.092000f, 0.009893f, 4.040650f, 1.236436f, 7.064961f, 0.116645f, 6.890487f, 1.047307f, 8.966483f, 0.007215f, 3.697230f, 2.275253f, 9.982943f, 0.046622f, 7.837207f, +0.033462f, 0.468986f, 0.000015f, 0.345591f, 0.025195f, 0.320254f, 0.000142f, 0.460938f, 0.005239f, 0.099778f, 0.000002f, 0.060715f, 0.031207f, 0.304591f, 0.000038f, 0.352880f, +0.033557f, 0.335829f, 0.000085f, 0.357081f, 0.030702f, 0.278659f, 0.000957f, 0.578717f, 0.046120f, 0.627206f, 0.000105f, 0.550703f, 0.046982f, 0.327442f, 0.000318f, 0.547381f, +0.000824f, 0.012165f, 0.000012f, 0.011178f, 0.000733f, 0.009824f, 0.000128f, 0.017631f, 0.000739f, 0.014840f, 0.000009f, 0.011260f, 0.000751f, 0.007721f, 0.000028f, 0.011154f, +0.059606f, 0.600177f, 0.000277f, 0.598553f, 0.081061f, 0.740257f, 0.004615f, 1.441949f, 0.088137f, 1.205971f, 0.000366f, 0.993158f, 0.163305f, 1.145141f, 0.002019f, 1.795514f, +0.031243f, 0.552327f, 0.000098f, 0.356504f, 0.024792f, 0.397494f, 0.000952f, 0.501123f, 0.005408f, 0.129908f, 0.000015f, 0.069241f, 0.020988f, 0.258389f, 0.000175f, 0.262211f, +0.109745f, 1.385344f, 0.001903f, 1.290245f, 0.105819f, 1.211467f, 0.022475f, 2.203793f, 0.166745f, 2.860302f, 0.002586f, 2.199811f, 0.110676f, 0.972957f, 0.005106f, 1.424674f, +0.023268f, 0.433556f, 0.002258f, 0.348947f, 0.021835f, 0.368988f, 0.025948f, 0.580058f, 0.023092f, 0.584686f, 0.002004f, 0.388594f, 0.015275f, 0.198210f, 0.003943f, 0.250811f, +0.100406f, 1.275229f, 0.003179f, 1.113979f, 0.143907f, 1.657641f, 0.055810f, 2.828290f, 0.164131f, 2.832749f, 0.004648f, 2.043411f, 0.198148f, 1.752619f, 0.016691f, 2.407043f, +0.001455f, 0.021936f, 0.000010f, 0.015969f, 0.001039f, 0.014196f, 0.000088f, 0.020184f, 0.000344f, 0.007043f, 0.000002f, 0.004234f, 0.001426f, 0.014970f, 0.000026f, 0.017133f, +0.001804f, 0.019414f, 0.000069f, 0.020393f, 0.001564f, 0.015266f, 0.000731f, 0.031321f, 0.003742f, 0.054715f, 0.000128f, 0.047460f, 0.002654f, 0.019890f, 0.000270f, 0.032848f, +0.001116f, 0.017735f, 0.000238f, 0.016099f, 0.000942f, 0.013572f, 0.002465f, 0.024064f, 0.001512f, 0.032647f, 0.000289f, 0.024472f, 0.001069f, 0.011828f, 0.000608f, 0.016880f, +0.003124f, 0.033821f, 0.000218f, 0.033321f, 0.004026f, 0.039532f, 0.003437f, 0.076073f, 0.006970f, 0.102551f, 0.000435f, 0.083433f, 0.008992f, 0.067806f, 0.001668f, 0.105030f, +0.073133f, 0.820138f, 0.000330f, 0.441377f, 0.058194f, 0.591875f, 0.003217f, 0.622154f, 0.011852f, 0.180609f, 0.000048f, 0.080264f, 0.077358f, 0.604149f, 0.000929f, 0.511180f, +0.131951f, 1.056615f, 0.003294f, 0.820512f, 0.127585f, 0.926572f, 0.039010f, 1.405375f, 0.187714f, 2.042612f, 0.004191f, 1.309825f, 0.209537f, 1.168509f, 0.013916f, 1.426619f, +0.057130f, 0.675266f, 0.007980f, 0.453151f, 0.053760f, 0.576302f, 0.091971f, 0.755377f, 0.053084f, 0.852644f, 0.006632f, 0.472493f, 0.059055f, 0.486110f, 0.021944f, 0.512873f, +0.315709f, 2.543596f, 0.014391f, 1.852640f, 0.453754f, 3.315575f, 0.253331f, 4.716789f, 0.483208f, 5.290335f, 0.019700f, 3.181888f, 0.981065f, 5.504616f, 0.118969f, 6.303434f, +0.076210f, 1.383946f, 0.000006f, 0.625273f, 0.042244f, 0.695748f, 0.000042f, 0.613970f, 0.008862f, 0.218685f, 0.000001f, 0.081588f, 0.046839f, 0.592354f, 0.000010f, 0.420765f, +0.080477f, 1.043539f, 0.000036f, 0.680307f, 0.054206f, 0.637471f, 0.000299f, 0.811712f, 0.082148f, 1.447517f, 0.000033f, 0.779254f, 0.074254f, 0.670547f, 0.000089f, 0.687279f, +0.001697f, 0.032490f, 0.000004f, 0.018304f, 0.001113f, 0.019316f, 0.000034f, 0.021255f, 0.001132f, 0.029437f, 0.000003f, 0.013695f, 0.001020f, 0.013590f, 0.000007f, 0.012037f, +0.118646f, 1.547923f, 0.000097f, 0.946499f, 0.118789f, 1.405560f, 0.001195f, 1.678669f, 0.130300f, 2.310095f, 0.000096f, 1.166432f, 0.214224f, 1.946404f, 0.000468f, 1.871161f, +0.125398f, 2.872369f, 0.000069f, 1.136729f, 0.073257f, 1.521851f, 0.000497f, 1.176343f, 0.016120f, 0.501767f, 0.000008f, 0.163975f, 0.055514f, 0.885569f, 0.000082f, 0.550994f, +0.463826f, 7.586342f, 0.001421f, 4.332064f, 0.329252f, 4.884091f, 0.012357f, 5.447422f, 0.523413f, 11.633490f, 0.001435f, 5.485691f, 0.308267f, 3.511341f, 0.002513f, 3.152411f, +0.084523f, 2.040633f, 0.001449f, 1.006995f, 0.058393f, 1.278583f, 0.012262f, 1.232356f, 0.062300f, 2.043928f, 0.000955f, 0.832889f, 0.036567f, 0.614822f, 0.001668f, 0.477001f, +0.352214f, 5.796186f, 0.001971f, 3.104411f, 0.371645f, 5.546792f, 0.025468f, 5.802612f, 0.427624f, 9.562807f, 0.002140f, 4.229424f, 0.458081f, 5.249843f, 0.006818f, 4.420695f, +0.041395f, 0.808343f, 0.000050f, 0.360795f, 0.021745f, 0.385117f, 0.000325f, 0.335739f, 0.007264f, 0.192750f, 0.000008f, 0.071042f, 0.026733f, 0.363551f, 0.000087f, 0.255116f, +0.054027f, 0.753340f, 0.000364f, 0.485178f, 0.034487f, 0.436121f, 0.002849f, 0.548608f, 0.083222f, 1.576905f, 0.000502f, 0.838638f, 0.052381f, 0.508650f, 0.000940f, 0.515035f, +0.028738f, 0.591489f, 0.001085f, 0.329198f, 0.017853f, 0.333254f, 0.008253f, 0.362269f, 0.028914f, 0.808695f, 0.000976f, 0.371667f, 0.018137f, 0.259967f, 0.001821f, 0.227476f, +0.077642f, 1.089273f, 0.000956f, 0.657993f, 0.073669f, 0.937348f, 0.011114f, 1.105938f, 0.128674f, 2.453108f, 0.001418f, 1.223659f, 0.147306f, 1.439222f, 0.004827f, 1.366847f, +0.177998f, 2.586402f, 0.000142f, 0.853428f, 0.104275f, 1.374158f, 0.001019f, 0.885630f, 0.021424f, 0.423031f, 0.000015f, 0.115266f, 0.124082f, 1.255619f, 0.000263f, 0.651382f, +0.338179f, 3.508781f, 0.001492f, 1.670601f, 0.240730f, 2.265250f, 0.013006f, 2.106578f, 0.357316f, 5.037893f, 0.001410f, 1.980726f, 0.353915f, 2.557269f, 0.004153f, 1.914257f, +0.125846f, 1.927346f, 0.003106f, 0.793005f, 0.087184f, 1.210967f, 0.026356f, 0.973181f, 0.086850f, 1.807489f, 0.001917f, 0.614117f, 0.085731f, 0.914373f, 0.005629f, 0.591490f, +0.671583f, 7.010795f, 0.005410f, 3.130820f, 0.710608f, 6.727836f, 0.070104f, 5.868283f, 0.763432f, 10.829930f, 0.005500f, 3.993699f, 1.375355f, 9.998865f, 0.029471f, 7.020191f, +0.000383f, 0.007329f, 0.000000f, 0.005041f, 0.000280f, 0.004856f, 0.000000f, 0.006525f, 0.000046f, 0.001184f, 0.000000f, 0.000673f, 0.000332f, 0.004421f, 0.000000f, 0.004781f, +0.000438f, 0.005986f, 0.000000f, 0.005941f, 0.000389f, 0.004820f, 0.000004f, 0.009344f, 0.000457f, 0.008490f, 0.000000f, 0.006959f, 0.000570f, 0.005421f, 0.000001f, 0.008459f, +0.000011f, 0.000218f, 0.000000f, 0.000187f, 0.000009f, 0.000171f, 0.000000f, 0.000287f, 0.000007f, 0.000202f, 0.000000f, 0.000143f, 0.000009f, 0.000129f, 0.000000f, 0.000174f, +0.000789f, 0.010843f, 0.000001f, 0.010094f, 0.001041f, 0.012977f, 0.000018f, 0.023596f, 0.000886f, 0.016546f, 0.000001f, 0.012720f, 0.002007f, 0.019215f, 0.000008f, 0.028122f, +0.000313f, 0.007555f, 0.000000f, 0.004552f, 0.000241f, 0.005276f, 0.000003f, 0.006209f, 0.000041f, 0.001350f, 0.000000f, 0.000671f, 0.000195f, 0.003283f, 0.000000f, 0.003110f, +0.001254f, 0.021614f, 0.000007f, 0.018791f, 0.001173f, 0.018342f, 0.000075f, 0.031145f, 0.001447f, 0.033892f, 0.000007f, 0.024331f, 0.001175f, 0.014099f, 0.000016f, 0.019271f, +0.000268f, 0.006812f, 0.000008f, 0.005117f, 0.000244f, 0.005626f, 0.000088f, 0.008255f, 0.000202f, 0.006976f, 0.000005f, 0.004328f, 0.000163f, 0.002892f, 0.000013f, 0.003416f, +0.001163f, 0.020166f, 0.000011f, 0.016444f, 0.001617f, 0.025437f, 0.000190f, 0.040513f, 0.001444f, 0.034020f, 0.000012f, 0.022908f, 0.002131f, 0.025741f, 0.000054f, 0.033000f, +0.000248f, 0.005097f, 0.000001f, 0.003463f, 0.000171f, 0.003201f, 0.000004f, 0.004248f, 0.000044f, 0.001243f, 0.000000f, 0.000697f, 0.000225f, 0.003231f, 0.000001f, 0.003451f, +0.000350f, 0.005145f, 0.000004f, 0.005045f, 0.000295f, 0.003926f, 0.000042f, 0.007519f, 0.000552f, 0.011013f, 0.000006f, 0.008917f, 0.000478f, 0.004896f, 0.000015f, 0.007547f, +0.000218f, 0.004733f, 0.000014f, 0.004010f, 0.000179f, 0.003515f, 0.000141f, 0.005817f, 0.000224f, 0.006617f, 0.000013f, 0.004630f, 0.000194f, 0.002932f, 0.000033f, 0.003905f, +0.000614f, 0.009085f, 0.000013f, 0.008355f, 0.000768f, 0.010304f, 0.000198f, 0.018509f, 0.001041f, 0.020920f, 0.000020f, 0.015887f, 0.001643f, 0.016916f, 0.000092f, 0.024459f, +0.000856f, 0.013106f, 0.000001f, 0.006584f, 0.000661f, 0.009178f, 0.000011f, 0.009006f, 0.000105f, 0.002192f, 0.000000f, 0.000909f, 0.000841f, 0.008967f, 0.000003f, 0.007082f, +0.001761f, 0.019260f, 0.000013f, 0.013961f, 0.001653f, 0.016389f, 0.000153f, 0.023204f, 0.001903f, 0.028276f, 0.000013f, 0.016926f, 0.002598f, 0.019782f, 0.000052f, 0.022545f, +0.000768f, 0.012394f, 0.000032f, 0.007764f, 0.000701f, 0.010265f, 0.000363f, 0.012559f, 0.000542f, 0.011886f, 0.000020f, 0.006148f, 0.000737f, 0.008287f, 0.000083f, 0.008161f, +0.004272f, 0.046992f, 0.000059f, 0.031949f, 0.005958f, 0.059440f, 0.001006f, 0.078933f, 0.004965f, 0.074227f, 0.000061f, 0.041673f, 0.012328f, 0.094453f, 0.000452f, 0.100962f, +0.159710f, 1.750391f, 0.000012f, 0.884281f, 0.089769f, 0.892292f, 0.000086f, 0.880455f, 0.016417f, 0.244506f, 0.000001f, 0.102001f, 0.097520f, 0.744327f, 0.000020f, 0.591189f, +0.167794f, 1.313134f, 0.000072f, 0.957216f, 0.114602f, 0.813393f, 0.000604f, 1.158100f, 0.151412f, 1.610197f, 0.000058f, 0.969257f, 0.153814f, 0.838294f, 0.000176f, 0.960737f, +0.002599f, 0.030023f, 0.000006f, 0.018913f, 0.001728f, 0.018099f, 0.000051f, 0.022269f, 0.001532f, 0.024046f, 0.000003f, 0.012509f, 0.001551f, 0.012476f, 0.000010f, 0.012357f, +0.219604f, 1.729144f, 0.000172f, 1.182242f, 0.222947f, 1.592101f, 0.002145f, 2.126134f, 0.213201f, 2.281218f, 0.000150f, 1.287956f, 0.393933f, 2.160139f, 0.000823f, 2.322011f, +0.228236f, 3.155193f, 0.000121f, 1.396198f, 0.135201f, 1.695108f, 0.000877f, 1.465087f, 0.025937f, 0.487239f, 0.000012f, 0.178042f, 0.100384f, 0.966440f, 0.000141f, 0.672363f, +0.839909f, 8.290918f, 0.002461f, 5.293824f, 0.604568f, 5.412442f, 0.021698f, 6.750020f, 0.837871f, 11.239190f, 0.002196f, 5.925992f, 0.554589f, 3.812501f, 0.004323f, 3.827228f, +0.112398f, 1.637717f, 0.001843f, 0.903661f, 0.078738f, 1.040500f, 0.015811f, 1.121383f, 0.073236f, 1.450089f, 0.001074f, 0.660725f, 0.048310f, 0.490219f, 0.002107f, 0.425269f, +0.566194f, 5.623335f, 0.003030f, 3.367714f, 0.605796f, 5.456735f, 0.039699f, 6.382914f, 0.607681f, 8.201478f, 0.002908f, 4.055949f, 0.731590f, 5.060165f, 0.010413f, 4.764457f, +0.116397f, 1.371782f, 0.000136f, 0.684627f, 0.062001f, 0.662706f, 0.000886f, 0.646004f, 0.018055f, 0.289160f, 0.000019f, 0.119170f, 0.074681f, 0.612945f, 0.000232f, 0.480947f, +0.151144f, 1.271934f, 0.000975f, 0.915966f, 0.097829f, 0.746655f, 0.007729f, 1.050219f, 0.205813f, 2.353608f, 0.001187f, 1.399613f, 0.145585f, 0.853216f, 0.002498f, 0.966010f, +0.059039f, 0.733372f, 0.002131f, 0.456393f, 0.037190f, 0.418979f, 0.016441f, 0.509275f, 0.052510f, 0.886374f, 0.001695f, 0.455503f, 0.037018f, 0.320230f, 0.003554f, 0.313318f, +0.192824f, 1.632645f, 0.002271f, 1.102760f, 0.185518f, 1.424608f, 0.026764f, 1.879445f, 0.282493f, 3.250326f, 0.002976f, 1.812906f, 0.363454f, 2.143136f, 0.011389f, 2.275864f, +0.359895f, 3.156085f, 0.000275f, 1.164458f, 0.213786f, 1.700312f, 0.001997f, 1.225318f, 0.038293f, 0.456332f, 0.000026f, 0.139032f, 0.249251f, 1.522219f, 0.000506f, 0.882998f, +0.680286f, 4.259843f, 0.002870f, 2.267851f, 0.491036f, 2.788643f, 0.025370f, 2.899737f, 0.635406f, 5.406813f, 0.002397f, 2.376957f, 0.707311f, 3.084469f, 0.007938f, 2.581718f, +0.185904f, 1.718307f, 0.004388f, 0.790536f, 0.130594f, 1.094744f, 0.037752f, 0.983736f, 0.113415f, 1.424530f, 0.002394f, 0.541192f, 0.125820f, 0.809900f, 0.007900f, 0.585814f, +1.199293f, 7.555896f, 0.009238f, 3.772952f, 1.286754f, 7.352474f, 0.121392f, 7.170900f, 1.205178f, 10.318090f, 0.008303f, 4.254550f, 2.440099f, 10.706220f, 0.050000f, 8.405024f, +0.087034f, 1.219811f, 0.000040f, 0.898866f, 0.056679f, 0.720443f, 0.000320f, 1.036924f, 0.011719f, 0.223186f, 0.000005f, 0.135809f, 0.065625f, 0.640528f, 0.000080f, 0.742076f, +0.084179f, 0.842437f, 0.000214f, 0.895748f, 0.066612f, 0.604594f, 0.002077f, 1.255617f, 0.099496f, 1.353093f, 0.000227f, 1.188050f, 0.095289f, 0.664113f, 0.000645f, 1.110191f, +0.002637f, 0.038949f, 0.000038f, 0.035789f, 0.002031f, 0.027204f, 0.000354f, 0.048824f, 0.002036f, 0.040862f, 0.000026f, 0.031004f, 0.001943f, 0.019987f, 0.000074f, 0.028874f, +0.146069f, 1.470788f, 0.000679f, 1.466806f, 0.171813f, 1.569007f, 0.009781f, 3.056274f, 0.185749f, 2.541591f, 0.000772f, 2.093087f, 0.323563f, 2.268913f, 0.004001f, 3.557524f, +0.061318f, 1.083997f, 0.000192f, 0.699675f, 0.042084f, 0.674737f, 0.001616f, 0.850644f, 0.009127f, 0.219262f, 0.000026f, 0.116867f, 0.033303f, 0.410010f, 0.000278f, 0.416074f, +0.207733f, 2.622260f, 0.003602f, 2.442250f, 0.173242f, 1.983360f, 0.036796f, 3.607952f, 0.271437f, 4.656163f, 0.004210f, 3.580977f, 0.169380f, 1.489019f, 0.007814f, 2.180329f, +0.056214f, 1.047435f, 0.005454f, 0.843027f, 0.045625f, 0.771020f, 0.054220f, 1.212062f, 0.047977f, 1.214795f, 0.004164f, 0.807377f, 0.029836f, 0.387164f, 0.007701f, 0.489911f, +0.185664f, 2.358075f, 0.005879f, 2.059901f, 0.230157f, 2.651134f, 0.089260f, 4.523403f, 0.261011f, 4.504802f, 0.007392f, 3.249552f, 0.296243f, 2.620267f, 0.024954f, 3.598667f, +0.004153f, 0.062583f, 0.000029f, 0.045559f, 0.002563f, 0.035029f, 0.000217f, 0.049807f, 0.000844f, 0.017280f, 0.000005f, 0.010387f, 0.003290f, 0.034531f, 0.000060f, 0.039522f, +0.004964f, 0.053421f, 0.000190f, 0.056114f, 0.003723f, 0.036333f, 0.001741f, 0.074543f, 0.008854f, 0.129479f, 0.000302f, 0.112311f, 0.005904f, 0.044251f, 0.000600f, 0.073079f, +0.003921f, 0.062285f, 0.000838f, 0.056539f, 0.002862f, 0.041228f, 0.007487f, 0.073096f, 0.004568f, 0.098605f, 0.000873f, 0.073913f, 0.003036f, 0.033585f, 0.001725f, 0.047930f, +0.008396f, 0.090913f, 0.000585f, 0.089570f, 0.009360f, 0.091911f, 0.007991f, 0.176867f, 0.016112f, 0.237073f, 0.001005f, 0.192876f, 0.019543f, 0.147368f, 0.003624f, 0.228269f, +0.173902f, 1.950198f, 0.000785f, 1.049546f, 0.119686f, 1.217290f, 0.006617f, 1.279562f, 0.024236f, 0.369343f, 0.000098f, 0.164139f, 0.148725f, 1.161514f, 0.001786f, 0.982776f, +0.302616f, 2.423231f, 0.007555f, 1.881756f, 0.253075f, 1.837931f, 0.077380f, 2.787677f, 0.370231f, 4.028677f, 0.008267f, 2.583389f, 0.388533f, 2.166700f, 0.025803f, 2.645298f, +0.167226f, 1.976593f, 0.023359f, 1.326434f, 0.136105f, 1.459031f, 0.232845f, 1.912395f, 0.133631f, 2.146388f, 0.016694f, 1.189421f, 0.139760f, 1.150442f, 0.051933f, 1.213782f, +0.707321f, 5.698726f, 0.032243f, 4.150692f, 0.879270f, 6.424811f, 0.490896f, 9.140038f, 0.931027f, 10.193210f, 0.037958f, 6.130739f, 1.777116f, 9.971146f, 0.215502f, 11.418140f, +0.255893f, 4.646945f, 0.000021f, 2.099511f, 0.122683f, 2.020562f, 0.000122f, 1.783066f, 0.025590f, 0.631487f, 0.000002f, 0.235599f, 0.127157f, 1.608119f, 0.000028f, 1.142289f, +0.260618f, 3.379430f, 0.000117f, 2.203128f, 0.151828f, 1.785531f, 0.000836f, 2.273571f, 0.228786f, 4.031407f, 0.000092f, 2.170261f, 0.194422f, 1.755708f, 0.000233f, 1.799517f, +0.007016f, 0.134293f, 0.000018f, 0.075657f, 0.003978f, 0.069054f, 0.000123f, 0.075985f, 0.004023f, 0.104638f, 0.000009f, 0.048679f, 0.003407f, 0.045416f, 0.000023f, 0.040226f, +0.375351f, 4.897059f, 0.000308f, 2.994374f, 0.325037f, 3.845984f, 0.003270f, 4.593281f, 0.354510f, 6.285129f, 0.000260f, 3.173539f, 0.547951f, 4.978604f, 0.001197f, 4.786143f, +0.317716f, 7.277588f, 0.000176f, 2.880077f, 0.160533f, 3.334966f, 0.001089f, 2.577822f, 0.035125f, 1.093320f, 0.000017f, 0.357292f, 0.113721f, 1.814088f, 0.000168f, 1.128710f, +1.133414f, 18.538130f, 0.003473f, 10.585920f, 0.695880f, 10.322600f, 0.026117f, 11.513210f, 1.099959f, 24.447910f, 0.003015f, 11.528250f, 0.609045f, 6.937374f, 0.004965f, 6.228234f, +0.263618f, 6.364472f, 0.004520f, 3.140688f, 0.157519f, 3.449041f, 0.033077f, 3.324341f, 0.167103f, 5.482283f, 0.002562f, 2.233999f, 0.092210f, 1.550369f, 0.004206f, 1.202832f, +0.840797f, 13.836530f, 0.004705f, 7.410783f, 0.767335f, 11.452460f, 0.052585f, 11.980650f, 0.877900f, 19.632190f, 0.004393f, 8.682894f, 0.884129f, 10.132570f, 0.013160f, 8.532258f, +0.152464f, 2.977270f, 0.000186f, 1.328871f, 0.069272f, 1.226837f, 0.001035f, 1.069538f, 0.023008f, 0.610541f, 0.000025f, 0.225029f, 0.079608f, 1.082620f, 0.000258f, 0.759711f, +0.191920f, 2.676085f, 0.001295f, 1.723496f, 0.105957f, 1.339948f, 0.008754f, 1.685556f, 0.254240f, 4.817398f, 0.001534f, 2.562017f, 0.150442f, 1.460885f, 0.002700f, 1.479224f, +0.130295f, 2.681759f, 0.004918f, 1.492554f, 0.070009f, 1.306834f, 0.032363f, 1.420613f, 0.112740f, 3.153231f, 0.003806f, 1.449190f, 0.066485f, 0.952971f, 0.006676f, 0.833868f, +0.269438f, 3.780045f, 0.003319f, 2.283398f, 0.221114f, 2.813411f, 0.033358f, 3.319424f, 0.384016f, 7.321081f, 0.004231f, 3.651901f, 0.413304f, 4.038094f, 0.013543f, 3.835029f, +0.546416f, 7.939687f, 0.000436f, 2.619836f, 0.276859f, 3.648513f, 0.002705f, 2.351427f, 0.056560f, 1.116807f, 0.000040f, 0.304304f, 0.307968f, 3.116403f, 0.000653f, 1.616709f, +1.001246f, 10.388430f, 0.004417f, 4.946142f, 0.616447f, 5.800721f, 0.033306f, 5.394401f, 0.909797f, 12.827470f, 0.003590f, 5.043320f, 0.847191f, 6.121511f, 0.009942f, 4.582289f, +0.475552f, 7.283118f, 0.011738f, 2.996635f, 0.284948f, 3.957874f, 0.086139f, 3.180704f, 0.282244f, 5.873969f, 0.006231f, 1.995754f, 0.261928f, 2.793634f, 0.017198f, 1.807147f, +1.942427f, 20.277410f, 0.015646f, 9.055308f, 1.777655f, 16.830320f, 0.175371f, 14.680070f, 1.898951f, 26.938220f, 0.013680f, 9.933878f, 3.216240f, 23.382140f, 0.068917f, 16.416580f, +0.056883f, 1.088580f, 0.000008f, 0.748780f, 0.035947f, 0.623901f, 0.000061f, 0.838213f, 0.005817f, 0.151265f, 0.000001f, 0.085920f, 0.039836f, 0.530911f, 0.000015f, 0.574148f, +0.062753f, 0.857523f, 0.000048f, 0.851110f, 0.048187f, 0.597201f, 0.000454f, 1.157724f, 0.056330f, 1.046022f, 0.000039f, 0.857313f, 0.065976f, 0.627865f, 0.000135f, 0.979746f, +0.001979f, 0.039924f, 0.000009f, 0.034243f, 0.001479f, 0.027059f, 0.000078f, 0.045332f, 0.001160f, 0.031809f, 0.000004f, 0.022529f, 0.001355f, 0.019028f, 0.000016f, 0.025659f, +0.110365f, 1.517399f, 0.000155f, 1.412583f, 0.125973f, 1.570806f, 0.002169f, 2.856154f, 0.106587f, 1.991408f, 0.000134f, 1.530853f, 0.227063f, 2.174119f, 0.000849f, 3.182036f, +0.035079f, 0.846770f, 0.000033f, 0.510183f, 0.023363f, 0.511470f, 0.000271f, 0.601901f, 0.003966f, 0.130079f, 0.000003f, 0.064718f, 0.017695f, 0.297473f, 0.000045f, 0.281783f, +0.135552f, 2.336435f, 0.000711f, 2.031233f, 0.109699f, 1.714855f, 0.007046f, 2.911913f, 0.134517f, 3.150729f, 0.000631f, 2.261914f, 0.102654f, 1.232236f, 0.001432f, 1.684254f, +0.036937f, 0.939777f, 0.001084f, 0.706043f, 0.029092f, 0.671292f, 0.010455f, 0.985059f, 0.023942f, 0.827762f, 0.000628f, 0.513536f, 0.018209f, 0.322633f, 0.001421f, 0.381085f, +0.122792f, 2.129497f, 0.001176f, 1.736431f, 0.147712f, 2.323267f, 0.017324f, 3.700193f, 0.131101f, 3.089584f, 0.001123f, 2.080365f, 0.181973f, 2.197762f, 0.004636f, 2.817530f, +0.040353f, 0.830410f, 0.000084f, 0.564288f, 0.024166f, 0.451037f, 0.000618f, 0.598639f, 0.006227f, 0.174129f, 0.000012f, 0.097710f, 0.029694f, 0.425561f, 0.000165f, 0.454650f, +0.055022f, 0.808507f, 0.000635f, 0.792753f, 0.040040f, 0.533608f, 0.005662f, 1.021930f, 0.074532f, 1.488257f, 0.000770f, 1.205011f, 0.060784f, 0.622030f, 0.001867f, 0.958898f, +0.043764f, 0.949245f, 0.002827f, 0.804327f, 0.030995f, 0.609719f, 0.024522f, 1.009087f, 0.038721f, 1.141290f, 0.002237f, 0.798563f, 0.031472f, 0.475389f, 0.005408f, 0.633302f, +0.094326f, 1.394578f, 0.001988f, 1.282541f, 0.102034f, 1.368137f, 0.026344f, 2.457553f, 0.137469f, 2.761867f, 0.002592f, 2.097443f, 0.203918f, 2.099586f, 0.011436f, 3.035774f, +0.116229f, 1.779769f, 0.000159f, 0.894084f, 0.077625f, 1.078020f, 0.001298f, 1.057757f, 0.012302f, 0.255988f, 0.000015f, 0.106192f, 0.092322f, 0.984521f, 0.000335f, 0.777583f, +0.230696f, 2.522436f, 0.001742f, 1.828438f, 0.187217f, 1.856532f, 0.017311f, 2.628497f, 0.214351f, 3.184877f, 0.001447f, 1.906390f, 0.275101f, 2.094787f, 0.005525f, 2.387302f, +0.128373f, 2.071868f, 0.005423f, 1.297843f, 0.101389f, 1.484080f, 0.052455f, 1.815776f, 0.077908f, 1.708669f, 0.002943f, 0.883847f, 0.099648f, 1.120019f, 0.011198f, 1.103045f, +0.546520f, 6.012353f, 0.007534f, 4.087699f, 0.659265f, 6.577716f, 0.111309f, 8.734830f, 0.546332f, 8.167377f, 0.006736f, 4.585388f, 1.275326f, 9.770743f, 0.046769f, 10.444060f, +0.465479f, 5.101561f, 0.000036f, 2.577259f, 0.226291f, 2.249298f, 0.000216f, 2.219458f, 0.041150f, 0.612852f, 0.000003f, 0.255664f, 0.229800f, 1.753963f, 0.000048f, 1.393102f, +0.471662f, 3.691165f, 0.000203f, 2.690694f, 0.278623f, 1.977547f, 0.001468f, 2.815609f, 0.366026f, 3.892528f, 0.000141f, 2.343104f, 0.349574f, 1.905194f, 0.000400f, 2.183471f, +0.009325f, 0.107715f, 0.000022f, 0.067854f, 0.005361f, 0.056163f, 0.000158f, 0.069103f, 0.004726f, 0.074194f, 0.000010f, 0.038595f, 0.004499f, 0.036191f, 0.000029f, 0.035843f, +0.603040f, 4.748285f, 0.000474f, 3.246474f, 0.529517f, 3.781362f, 0.005094f, 5.049732f, 0.503492f, 5.387295f, 0.000354f, 3.041620f, 0.874615f, 4.795963f, 0.001827f, 5.155353f, +0.501940f, 6.938935f, 0.000266f, 3.070534f, 0.257168f, 3.224305f, 0.001669f, 2.786776f, 0.049055f, 0.921526f, 0.000023f, 0.336735f, 0.178493f, 1.718424f, 0.000252f, 1.195526f, +1.781498f, 17.585550f, 0.005220f, 11.228530f, 1.109100f, 9.929297f, 0.039805f, 12.383120f, 1.528370f, 20.501550f, 0.004006f, 10.809680f, 0.951071f, 6.538103f, 0.007414f, 6.563358f, +0.304281f, 4.433594f, 0.004989f, 2.446374f, 0.184363f, 2.436303f, 0.037022f, 2.625688f, 0.170507f, 3.376060f, 0.002500f, 1.538282f, 0.105742f, 1.072989f, 0.004612f, 0.930829f, +1.173193f, 11.651950f, 0.006277f, 6.978144f, 1.085683f, 9.779338f, 0.071148f, 11.439200f, 1.082875f, 14.614870f, 0.005182f, 7.227621f, 1.225633f, 8.477305f, 0.017446f, 7.981905f, +0.372120f, 4.385581f, 0.000434f, 2.188750f, 0.171441f, 1.832463f, 0.002449f, 1.786278f, 0.049642f, 0.795022f, 0.000052f, 0.327648f, 0.193037f, 1.584352f, 0.000599f, 1.243164f, +0.466037f, 3.921870f, 0.003006f, 2.824282f, 0.260898f, 1.991226f, 0.020613f, 2.800788f, 0.545758f, 6.241099f, 0.003149f, 3.711376f, 0.362940f, 2.127043f, 0.006228f, 2.408233f, +0.232345f, 2.886136f, 0.008386f, 1.796105f, 0.126589f, 1.426123f, 0.055960f, 1.733471f, 0.177720f, 2.999908f, 0.005737f, 1.541636f, 0.117785f, 1.018928f, 0.011310f, 0.996932f, +0.580818f, 4.917810f, 0.006841f, 3.321704f, 0.483324f, 3.711482f, 0.069726f, 4.896451f, 0.731789f, 8.419866f, 0.007709f, 4.696274f, 0.885153f, 5.219370f, 0.027736f, 5.542615f, +0.958966f, 8.409609f, 0.000731f, 3.102780f, 0.492694f, 3.918571f, 0.004603f, 2.823890f, 0.087750f, 1.045697f, 0.000060f, 0.318596f, 0.536972f, 3.279388f, 0.001090f, 1.902284f, +1.748256f, 10.947300f, 0.007375f, 5.828113f, 1.091437f, 6.198381f, 0.056390f, 6.445314f, 1.404312f, 11.949590f, 0.005298f, 5.253310f, 1.469644f, 6.408884f, 0.016492f, 5.364272f, +0.609769f, 5.636092f, 0.014392f, 2.592979f, 0.370486f, 3.105718f, 0.107100f, 2.790794f, 0.319924f, 4.018347f, 0.006754f, 1.526607f, 0.333669f, 2.147816f, 0.020951f, 1.553551f, +3.010858f, 18.969280f, 0.023192f, 9.472097f, 2.794038f, 15.965050f, 0.263588f, 15.570780f, 2.602042f, 22.277300f, 0.017926f, 9.185796f, 4.952913f, 21.731490f, 0.101490f, 17.060520f, +0.019918f, 0.279155f, 0.000009f, 0.205706f, 0.017671f, 0.224620f, 0.000100f, 0.323293f, 0.003062f, 0.058311f, 0.000001f, 0.035483f, 0.022498f, 0.219594f, 0.000028f, 0.254408f, +0.038096f, 0.381252f, 0.000097f, 0.405378f, 0.041070f, 0.372765f, 0.001280f, 0.774155f, 0.051406f, 0.699096f, 0.000117f, 0.613824f, 0.064602f, 0.450242f, 0.000437f, 0.752665f, +0.000530f, 0.007832f, 0.000008f, 0.007197f, 0.000556f, 0.007453f, 0.000097f, 0.013376f, 0.000467f, 0.009381f, 0.000006f, 0.007118f, 0.000585f, 0.006021f, 0.000022f, 0.008698f, +0.041317f, 0.416025f, 0.000192f, 0.414899f, 0.066210f, 0.604632f, 0.003769f, 1.177765f, 0.059983f, 0.820749f, 0.000249f, 0.675914f, 0.137106f, 0.961429f, 0.001695f, 1.507465f, +0.016543f, 0.292460f, 0.000052f, 0.188771f, 0.015469f, 0.248010f, 0.000594f, 0.312667f, 0.002811f, 0.067536f, 0.000008f, 0.035997f, 0.013460f, 0.165715f, 0.000112f, 0.168166f, +0.110832f, 1.399058f, 0.001922f, 1.303017f, 0.125924f, 1.441644f, 0.026746f, 2.622511f, 0.165335f, 2.836110f, 0.002564f, 2.181205f, 0.135379f, 1.190118f, 0.006245f, 1.742657f, +0.013327f, 0.248314f, 0.001293f, 0.199855f, 0.014736f, 0.249021f, 0.017512f, 0.391467f, 0.012985f, 0.328784f, 0.001127f, 0.218517f, 0.010596f, 0.137499f, 0.002735f, 0.173988f, +0.061913f, 0.786345f, 0.001960f, 0.686913f, 0.104563f, 1.204436f, 0.040551f, 2.055025f, 0.099369f, 1.715007f, 0.002814f, 1.237125f, 0.147990f, 1.308973f, 0.012466f, 1.797740f, +0.001429f, 0.021535f, 0.000010f, 0.015677f, 0.001201f, 0.016422f, 0.000102f, 0.023350f, 0.000331f, 0.006788f, 0.000002f, 0.004081f, 0.001696f, 0.017801f, 0.000031f, 0.020373f, +0.003378f, 0.036352f, 0.000129f, 0.038185f, 0.003451f, 0.033683f, 0.001614f, 0.069107f, 0.006878f, 0.100589f, 0.000235f, 0.087251f, 0.006019f, 0.045109f, 0.000611f, 0.074497f, +0.001186f, 0.018833f, 0.000253f, 0.017095f, 0.001179f, 0.016983f, 0.003084f, 0.030111f, 0.001577f, 0.034038f, 0.000301f, 0.025514f, 0.001375f, 0.015212f, 0.000781f, 0.021710f, +0.003571f, 0.038667f, 0.000249f, 0.038096f, 0.005423f, 0.053257f, 0.004630f, 0.102484f, 0.007824f, 0.115114f, 0.000488f, 0.093653f, 0.012452f, 0.093895f, 0.002309f, 0.145441f, +0.042879f, 0.480855f, 0.000194f, 0.258784f, 0.040205f, 0.408908f, 0.002223f, 0.429827f, 0.006822f, 0.103968f, 0.000028f, 0.046204f, 0.054935f, 0.429032f, 0.000660f, 0.363011f, +0.147554f, 1.181550f, 0.003684f, 0.917530f, 0.168114f, 1.220908f, 0.051402f, 1.851809f, 0.206094f, 2.242613f, 0.004602f, 1.438076f, 0.283802f, 1.582653f, 0.018848f, 1.932242f, +0.036231f, 0.428241f, 0.005061f, 0.287380f, 0.040174f, 0.430657f, 0.068728f, 0.564475f, 0.033053f, 0.530901f, 0.004129f, 0.294199f, 0.045361f, 0.373392f, 0.016856f, 0.393950f, +0.215561f, 1.736722f, 0.009826f, 1.264949f, 0.365066f, 2.667531f, 0.203816f, 3.794871f, 0.323929f, 3.546486f, 0.013207f, 2.133045f, 0.811331f, 4.552264f, 0.098386f, 5.212878f, +0.069309f, 1.258625f, 0.000006f, 0.568653f, 0.045270f, 0.745586f, 0.000045f, 0.657950f, 0.007913f, 0.195267f, 0.000001f, 0.072851f, 0.051594f, 0.652494f, 0.000011f, 0.463484f, +0.139590f, 1.810065f, 0.000063f, 1.180023f, 0.110789f, 1.302910f, 0.000610f, 1.659035f, 0.139899f, 2.465142f, 0.000056f, 1.327081f, 0.156000f, 1.408746f, 0.000187f, 1.443898f, +0.001670f, 0.031961f, 0.000004f, 0.018006f, 0.001290f, 0.022390f, 0.000040f, 0.024637f, 0.001093f, 0.028431f, 0.000002f, 0.013226f, 0.001215f, 0.016192f, 0.000008f, 0.014342f, +0.125656f, 1.639386f, 0.000103f, 1.002425f, 0.148243f, 1.754082f, 0.001491f, 2.094910f, 0.135491f, 2.402121f, 0.000100f, 1.212899f, 0.274801f, 2.496798f, 0.000600f, 2.400278f, +0.101450f, 2.323818f, 0.000056f, 0.919642f, 0.069836f, 1.450783f, 0.000474f, 1.121409f, 0.012804f, 0.398562f, 0.000006f, 0.130248f, 0.054398f, 0.867766f, 0.000080f, 0.539917f, +0.715690f, 11.705830f, 0.002193f, 6.684436f, 0.598642f, 8.880186f, 0.022467f, 9.904427f, 0.792953f, 17.624340f, 0.002173f, 8.310636f, 0.576123f, 6.562377f, 0.004696f, 5.891570f, +0.073965f, 1.785715f, 0.001268f, 0.881200f, 0.060211f, 1.318392f, 0.012644f, 1.270726f, 0.053527f, 1.756087f, 0.000821f, 0.715595f, 0.038758f, 0.651650f, 0.001768f, 0.505574f, +0.331836f, 5.460834f, 0.001857f, 2.924797f, 0.412585f, 6.157819f, 0.028274f, 6.441820f, 0.395559f, 8.845758f, 0.001980f, 3.912289f, 0.522729f, 5.990750f, 0.007781f, 5.044585f, +0.062092f, 1.212519f, 0.000076f, 0.541194f, 0.038435f, 0.680697f, 0.000574f, 0.593421f, 0.010697f, 0.283870f, 0.000012f, 0.104627f, 0.048569f, 0.660505f, 0.000158f, 0.463498f, +0.154565f, 2.155221f, 0.001043f, 1.388040f, 0.116257f, 1.470199f, 0.009605f, 1.849403f, 0.233761f, 4.429342f, 0.001410f, 2.355638f, 0.181505f, 1.762535f, 0.003257f, 1.784660f, +0.046627f, 0.959677f, 0.001760f, 0.534116f, 0.034131f, 0.637122f, 0.015778f, 0.692592f, 0.046059f, 1.288237f, 0.001555f, 0.592059f, 0.035641f, 0.510875f, 0.003579f, 0.447026f, +0.135627f, 1.902761f, 0.001671f, 1.149394f, 0.151635f, 1.929376f, 0.022876f, 2.276389f, 0.220684f, 4.207239f, 0.002431f, 2.098655f, 0.311664f, 3.045043f, 0.010212f, 2.891916f, +0.159454f, 2.316941f, 0.000127f, 0.764515f, 0.110070f, 1.450521f, 0.001075f, 0.934845f, 0.018843f, 0.372070f, 0.000013f, 0.101380f, 0.134632f, 1.362370f, 0.000286f, 0.706762f, +0.577796f, 5.994922f, 0.002549f, 2.854302f, 0.484647f, 4.560494f, 0.026185f, 4.241048f, 0.599394f, 8.451022f, 0.002365f, 3.322651f, 0.732394f, 5.292025f, 0.008595f, 3.961373f, +0.121940f, 1.867516f, 0.003010f, 0.768388f, 0.099542f, 1.382628f, 0.030092f, 1.111135f, 0.082624f, 1.719544f, 0.001824f, 0.584237f, 0.100614f, 1.073115f, 0.006606f, 0.694177f, +0.700605f, 7.313769f, 0.005643f, 3.266119f, 0.873520f, 8.270234f, 0.086176f, 7.213623f, 0.781947f, 11.092580f, 0.005633f, 4.090556f, 1.737829f, 12.634060f, 0.037238f, 8.870358f, +0.016431f, 0.314450f, 0.000002f, 0.216294f, 0.014146f, 0.245529f, 0.000024f, 0.329869f, 0.001918f, 0.049884f, 0.000000f, 0.028335f, 0.017238f, 0.229743f, 0.000006f, 0.248453f, +0.035847f, 0.489845f, 0.000028f, 0.486181f, 0.037501f, 0.464761f, 0.000354f, 0.900978f, 0.036736f, 0.682163f, 0.000025f, 0.559097f, 0.056459f, 0.537289f, 0.000116f, 0.838408f, +0.000502f, 0.010133f, 0.000002f, 0.008692f, 0.000511f, 0.009357f, 0.000027f, 0.015676f, 0.000336f, 0.009217f, 0.000001f, 0.006528f, 0.000515f, 0.007235f, 0.000006f, 0.009757f, +0.039404f, 0.541761f, 0.000055f, 0.504338f, 0.061275f, 0.764059f, 0.001055f, 1.389268f, 0.043446f, 0.811713f, 0.000055f, 0.623988f, 0.121446f, 1.162842f, 0.000454f, 1.701934f, +0.011946f, 0.288365f, 0.000011f, 0.173741f, 0.010839f, 0.237297f, 0.000126f, 0.279253f, 0.001542f, 0.050573f, 0.000001f, 0.025162f, 0.009027f, 0.151759f, 0.000023f, 0.143755f, +0.091286f, 1.573446f, 0.000479f, 1.367911f, 0.100646f, 1.573338f, 0.006465f, 2.671610f, 0.103421f, 2.422389f, 0.000485f, 1.739038f, 0.103563f, 1.243145f, 0.001445f, 1.699165f, +0.011053f, 0.281214f, 0.000324f, 0.211272f, 0.011860f, 0.273665f, 0.004262f, 0.401579f, 0.008179f, 0.282782f, 0.000215f, 0.175435f, 0.008163f, 0.144627f, 0.000637f, 0.170830f, +0.051685f, 0.896335f, 0.000495f, 0.730888f, 0.084704f, 1.332260f, 0.009934f, 2.121849f, 0.062999f, 1.484664f, 0.000540f, 0.999695f, 0.114744f, 1.385811f, 0.002923f, 1.776609f, +0.017527f, 0.360682f, 0.000037f, 0.245094f, 0.014300f, 0.266895f, 0.000366f, 0.354237f, 0.003088f, 0.086345f, 0.000006f, 0.048451f, 0.019321f, 0.276900f, 0.000107f, 0.295828f, +0.047259f, 0.694444f, 0.000546f, 0.680913f, 0.046854f, 0.624414f, 0.006625f, 1.195835f, 0.073085f, 1.459374f, 0.000755f, 1.181625f, 0.078212f, 0.800377f, 0.002402f, 1.233832f, +0.016703f, 0.362281f, 0.001079f, 0.306973f, 0.016116f, 0.317025f, 0.012750f, 0.524677f, 0.016871f, 0.497277f, 0.000975f, 0.347945f, 0.017994f, 0.271798f, 0.003092f, 0.362083f, +0.050639f, 0.748672f, 0.001067f, 0.688526f, 0.074626f, 1.000634f, 0.019267f, 1.797415f, 0.084254f, 1.692726f, 0.001589f, 1.285506f, 0.163997f, 1.688544f, 0.009197f, 2.441453f, +0.036173f, 0.553907f, 0.000049f, 0.278261f, 0.032913f, 0.457085f, 0.000550f, 0.448493f, 0.004371f, 0.090955f, 0.000005f, 0.037731f, 0.043044f, 0.459017f, 0.000156f, 0.362535f, +0.141983f, 1.552442f, 0.001072f, 1.125319f, 0.156977f, 1.556662f, 0.014515f, 2.203937f, 0.150611f, 2.237807f, 0.001017f, 1.339497f, 0.253640f, 1.931367f, 0.005094f, 2.201063f, +0.035106f, 0.566593f, 0.001483f, 0.354920f, 0.037774f, 0.552920f, 0.019543f, 0.676500f, 0.024323f, 0.533460f, 0.000919f, 0.275944f, 0.040823f, 0.458843f, 0.004587f, 0.451889f, +0.210231f, 2.312784f, 0.002898f, 1.572424f, 0.345499f, 3.447166f, 0.058333f, 4.577639f, 0.239929f, 3.586807f, 0.002958f, 2.013731f, 0.734923f, 5.630513f, 0.026951f, 6.018523f, +0.178847f, 1.960126f, 0.000014f, 0.990237f, 0.118453f, 1.177401f, 0.000113f, 1.161781f, 0.018050f, 0.268826f, 0.000001f, 0.112146f, 0.132270f, 1.009558f, 0.000027f, 0.801851f, +0.358372f, 2.804569f, 0.000154f, 2.044405f, 0.288414f, 2.047038f, 0.001519f, 2.914550f, 0.317504f, 3.376520f, 0.000122f, 2.032493f, 0.397898f, 2.168561f, 0.000455f, 2.485306f, +0.003148f, 0.036366f, 0.000008f, 0.022908f, 0.002466f, 0.025832f, 0.000073f, 0.031784f, 0.001822f, 0.028597f, 0.000004f, 0.014876f, 0.002275f, 0.018304f, 0.000015f, 0.018128f, +0.286381f, 2.254940f, 0.000225f, 1.541736f, 0.342590f, 2.446487f, 0.003295f, 3.267104f, 0.272977f, 2.920812f, 0.000192f, 1.649065f, 0.622221f, 3.411958f, 0.001300f, 3.667637f, +0.227362f, 3.143109f, 0.000120f, 1.390851f, 0.158701f, 1.989753f, 0.001030f, 1.719750f, 0.025368f, 0.476551f, 0.000012f, 0.174136f, 0.121120f, 1.166076f, 0.000171f, 0.811251f, +1.595783f, 15.752310f, 0.004676f, 10.057990f, 1.353491f, 12.117230f, 0.048576f, 15.111760f, 1.562974f, 20.965730f, 0.004096f, 11.054420f, 1.276237f, 8.773441f, 0.009949f, 8.807330f, +0.121109f, 1.764647f, 0.001986f, 0.973699f, 0.099970f, 1.321082f, 0.020075f, 1.423775f, 0.077478f, 1.534076f, 0.001136f, 0.698993f, 0.063049f, 0.639775f, 0.002750f, 0.555011f, +0.656831f, 6.523526f, 0.003514f, 3.906822f, 0.828101f, 7.459156f, 0.054268f, 8.725209f, 0.692145f, 9.341435f, 0.003312f, 4.619701f, 1.027955f, 7.110029f, 0.014632f, 6.694530f, +0.214984f, 2.533666f, 0.000251f, 1.264499f, 0.134937f, 1.442294f, 0.001928f, 1.405943f, 0.032742f, 0.524368f, 0.000034f, 0.216105f, 0.167067f, 1.371209f, 0.000518f, 1.075921f, +0.532432f, 4.480611f, 0.003435f, 3.226652f, 0.406079f, 3.099282f, 0.032084f, 4.359340f, 0.711835f, 8.140288f, 0.004107f, 4.840761f, 0.621167f, 3.640407f, 0.010660f, 4.121661f, +0.117948f, 1.465124f, 0.004257f, 0.911778f, 0.087549f, 0.986304f, 0.038702f, 1.198866f, 0.102998f, 1.738602f, 0.003325f, 0.893458f, 0.089573f, 0.774873f, 0.008601f, 0.758146f, +0.414743f, 3.511649f, 0.004885f, 2.371922f, 0.470191f, 3.610631f, 0.067832f, 4.763402f, 0.596568f, 6.864031f, 0.006285f, 3.828490f, 0.946863f, 5.583251f, 0.029670f, 5.929033f, +0.396978f, 3.481285f, 0.000303f, 1.284443f, 0.277868f, 2.209978f, 0.002596f, 1.592605f, 0.041471f, 0.494202f, 0.000028f, 0.150570f, 0.333001f, 2.033698f, 0.000676f, 1.179693f, +1.431168f, 8.961746f, 0.006037f, 4.771045f, 1.217253f, 6.912901f, 0.062891f, 7.188299f, 1.312453f, 11.167950f, 0.004952f, 4.909682f, 1.802302f, 7.859551f, 0.020226f, 6.578488f, +0.221802f, 2.050110f, 0.005235f, 0.943187f, 0.183598f, 1.539067f, 0.053075f, 1.383004f, 0.132856f, 1.668711f, 0.002805f, 0.633959f, 0.181821f, 1.170377f, 0.011416f, 0.846553f, +1.540534f, 9.705809f, 0.011866f, 4.846487f, 1.947645f, 11.128780f, 0.183740f, 10.853950f, 1.519952f, 13.013020f, 0.010471f, 5.365775f, 3.796395f, 16.657130f, 0.077792f, 13.076840f, +0.086537f, 1.212838f, 0.000040f, 0.893728f, 0.058461f, 0.743095f, 0.000330f, 1.069527f, 0.010994f, 0.209378f, 0.000005f, 0.127407f, 0.070265f, 0.685824f, 0.000086f, 0.794553f, +0.085044f, 0.851095f, 0.000216f, 0.904954f, 0.069812f, 0.633635f, 0.002176f, 1.315928f, 0.094842f, 1.289801f, 0.000216f, 1.132478f, 0.103668f, 0.722514f, 0.000702f, 1.207820f, +0.001896f, 0.028015f, 0.000027f, 0.025742f, 0.001515f, 0.020299f, 0.000264f, 0.036430f, 0.001381f, 0.027731f, 0.000018f, 0.021041f, 0.001505f, 0.015481f, 0.000057f, 0.022365f, +0.145252f, 1.462557f, 0.000675f, 1.458597f, 0.177237f, 1.618534f, 0.010089f, 3.152748f, 0.174279f, 2.384640f, 0.000724f, 1.963833f, 0.346486f, 2.429654f, 0.004284f, 3.809556f, +0.071797f, 1.269254f, 0.000225f, 0.819252f, 0.051118f, 0.819577f, 0.001963f, 1.033244f, 0.010083f, 0.242237f, 0.000028f, 0.129112f, 0.041992f, 0.516986f, 0.000350f, 0.524632f, +0.247147f, 3.119800f, 0.004286f, 2.905635f, 0.213815f, 2.447862f, 0.045413f, 4.452933f, 0.304702f, 5.226774f, 0.004726f, 4.019825f, 0.217008f, 1.907722f, 0.010011f, 2.793425f, +0.047616f, 0.887217f, 0.004620f, 0.714076f, 0.040091f, 0.677490f, 0.047643f, 1.065031f, 0.038343f, 0.970869f, 0.003328f, 0.645259f, 0.027215f, 0.353152f, 0.007025f, 0.446873f, +0.217421f, 2.761408f, 0.006885f, 2.412234f, 0.279597f, 3.220617f, 0.108433f, 5.495063f, 0.288394f, 4.977408f, 0.008167f, 3.590468f, 0.373581f, 3.304323f, 0.031469f, 4.538148f, +0.004307f, 0.064904f, 0.000030f, 0.047248f, 0.002757f, 0.037686f, 0.000233f, 0.053584f, 0.000826f, 0.016908f, 0.000005f, 0.010164f, 0.003674f, 0.038564f, 0.000067f, 0.044138f, +0.005231f, 0.056292f, 0.000200f, 0.059131f, 0.004069f, 0.039717f, 0.001903f, 0.081486f, 0.008803f, 0.128734f, 0.000301f, 0.111665f, 0.006700f, 0.050214f, 0.000680f, 0.082927f, +0.002942f, 0.046728f, 0.000628f, 0.042417f, 0.002227f, 0.032086f, 0.005827f, 0.056888f, 0.003234f, 0.069798f, 0.000618f, 0.052320f, 0.002453f, 0.027133f, 0.001394f, 0.038723f, +0.008709f, 0.094295f, 0.000607f, 0.092902f, 0.010071f, 0.098892f, 0.008598f, 0.190303f, 0.015768f, 0.232006f, 0.000983f, 0.188754f, 0.021829f, 0.164600f, 0.004048f, 0.254961f, +0.218953f, 2.455414f, 0.000988f, 1.321439f, 0.156323f, 1.589916f, 0.008642f, 1.671251f, 0.028792f, 0.438764f, 0.000116f, 0.194990f, 0.201648f, 1.574832f, 0.002421f, 1.332491f, +0.387140f, 3.100065f, 0.009665f, 2.407350f, 0.335861f, 2.439157f, 0.102693f, 3.699584f, 0.446893f, 4.862875f, 0.009978f, 3.118319f, 0.535264f, 2.984962f, 0.035548f, 3.644304f, +0.152311f, 1.800301f, 0.021275f, 1.208129f, 0.128599f, 1.378563f, 0.220003f, 1.806924f, 0.114839f, 1.844551f, 0.014347f, 1.022158f, 0.137080f, 1.128384f, 0.050937f, 1.190509f, +0.890666f, 7.175890f, 0.040601f, 5.226591f, 1.148562f, 8.392530f, 0.641242f, 11.939340f, 1.106153f, 12.110540f, 0.045098f, 7.283925f, 2.409783f, 13.520950f, 0.292222f, 15.483080f, +0.244449f, 4.439133f, 0.000020f, 2.005620f, 0.121577f, 2.002337f, 0.000121f, 1.766984f, 0.023065f, 0.569180f, 0.000002f, 0.212354f, 0.130808f, 1.654294f, 0.000028f, 1.175089f, +0.252968f, 3.280229f, 0.000114f, 2.138457f, 0.152878f, 1.797888f, 0.000842f, 2.289305f, 0.209530f, 3.692088f, 0.000084f, 1.987592f, 0.203221f, 1.835173f, 0.000243f, 1.880965f, +0.004849f, 0.092803f, 0.000012f, 0.052283f, 0.002852f, 0.049503f, 0.000088f, 0.054472f, 0.002623f, 0.068227f, 0.000006f, 0.031740f, 0.002535f, 0.033797f, 0.000017f, 0.029935f, +0.358608f, 4.678624f, 0.000295f, 2.860809f, 0.322144f, 3.811753f, 0.003240f, 4.552398f, 0.319570f, 5.665674f, 0.000235f, 2.860759f, 0.563752f, 5.122175f, 0.001232f, 4.924164f, +0.357421f, 8.187070f, 0.000198f, 3.240001f, 0.187345f, 3.891947f, 0.001271f, 3.008350f, 0.037283f, 1.160494f, 0.000018f, 0.379244f, 0.137767f, 2.197674f, 0.000203f, 1.367374f, +1.295566f, 21.190300f, 0.003970f, 12.100400f, 0.825163f, 12.240380f, 0.030969f, 13.652180f, 1.186321f, 26.367410f, 0.003251f, 12.433370f, 0.749695f, 8.539457f, 0.006111f, 7.666553f, +0.214534f, 5.179471f, 0.003678f, 2.555923f, 0.132981f, 2.911762f, 0.027925f, 2.806488f, 0.128311f, 4.209583f, 0.001968f, 1.715381f, 0.080810f, 1.358696f, 0.003686f, 1.054125f, +0.945985f, 15.567560f, 0.005293f, 8.337912f, 0.895598f, 13.366770f, 0.061374f, 13.983250f, 0.931950f, 20.840900f, 0.004664f, 9.217482f, 1.071205f, 12.276570f, 0.015945f, 10.337640f, +0.151914f, 2.966531f, 0.000185f, 1.324078f, 0.071602f, 1.268096f, 0.001070f, 1.105507f, 0.021630f, 0.573985f, 0.000024f, 0.211555f, 0.085418f, 1.161638f, 0.000277f, 0.815160f, +0.194303f, 2.709322f, 0.001311f, 1.744902f, 0.111282f, 1.407288f, 0.009194f, 1.770265f, 0.242862f, 4.601803f, 0.001465f, 2.447357f, 0.164018f, 1.592725f, 0.002943f, 1.612719f, +0.093916f, 1.933003f, 0.003545f, 1.075828f, 0.052348f, 0.977164f, 0.024199f, 1.062241f, 0.076673f, 2.144486f, 0.002588f, 0.985581f, 0.051606f, 0.739701f, 0.005182f, 0.647253f, +0.268498f, 3.766863f, 0.003307f, 2.275436f, 0.228578f, 2.908375f, 0.034483f, 3.431469f, 0.361066f, 6.883554f, 0.003978f, 3.433654f, 0.443523f, 4.333346f, 0.014533f, 4.115433f, +0.660982f, 9.604382f, 0.000527f, 3.169131f, 0.347424f, 4.578428f, 0.003394f, 2.950747f, 0.064555f, 1.274673f, 0.000046f, 0.347319f, 0.401177f, 4.059604f, 0.000851f, 2.106017f, +1.230658f, 12.768690f, 0.005429f, 6.079429f, 0.786007f, 7.396268f, 0.042467f, 6.878186f, 1.055104f, 14.876190f, 0.004163f, 5.848807f, 1.121351f, 8.102497f, 0.013159f, 6.065167f, +0.416146f, 6.373316f, 0.010271f, 2.622297f, 0.258671f, 3.592895f, 0.078196f, 2.887392f, 0.233038f, 4.849918f, 0.005144f, 1.647820f, 0.246828f, 2.632581f, 0.016207f, 1.702964f, +2.349974f, 24.531870f, 0.018929f, 10.955230f, 2.231003f, 21.122500f, 0.220096f, 18.423870f, 2.167637f, 30.749770f, 0.015616f, 11.339440f, 4.190161f, 30.462570f, 0.089786f, 21.387740f, +0.072723f, 1.391724f, 0.000010f, 0.957299f, 0.047674f, 0.827452f, 0.000081f, 1.111685f, 0.007016f, 0.182468f, 0.000001f, 0.103643f, 0.054844f, 0.730935f, 0.000020f, 0.790461f, +0.081519f, 1.113958f, 0.000063f, 1.105627f, 0.064937f, 0.804781f, 0.000612f, 1.560136f, 0.069043f, 1.282089f, 0.000048f, 1.050793f, 0.092294f, 0.878320f, 0.000189f, 1.370567f, +0.001831f, 0.036924f, 0.000008f, 0.031670f, 0.001419f, 0.025961f, 0.000075f, 0.043492f, 0.001013f, 0.027757f, 0.000004f, 0.019660f, 0.001349f, 0.018951f, 0.000015f, 0.025555f, +0.141116f, 1.940192f, 0.000198f, 1.806172f, 0.167092f, 2.083541f, 0.002877f, 3.788447f, 0.128589f, 2.402480f, 0.000162f, 1.846857f, 0.312648f, 2.993590f, 0.001169f, 4.381412f, +0.052814f, 1.274878f, 0.000050f, 0.768120f, 0.036489f, 0.798836f, 0.000424f, 0.940076f, 0.005633f, 0.184784f, 0.000005f, 0.091936f, 0.028690f, 0.482297f, 0.000072f, 0.456859f, +0.207367f, 3.574268f, 0.001088f, 3.107372f, 0.174089f, 2.721419f, 0.011182f, 4.621110f, 0.194162f, 4.547776f, 0.000911f, 3.264857f, 0.169112f, 2.029978f, 0.002359f, 2.774629f, +0.040230f, 1.023552f, 0.001180f, 0.768982f, 0.032870f, 0.758457f, 0.011813f, 1.112966f, 0.024604f, 0.850639f, 0.000646f, 0.527729f, 0.021357f, 0.378406f, 0.001667f, 0.446963f, +0.184895f, 3.206509f, 0.001771f, 2.614646f, 0.230731f, 3.629017f, 0.027061f, 5.779820f, 0.186258f, 4.389449f, 0.001595f, 2.955626f, 0.295070f, 3.563692f, 0.007517f, 4.568652f, +0.053810f, 1.107351f, 0.000112f, 0.752478f, 0.033430f, 0.623935f, 0.000855f, 0.828118f, 0.007834f, 0.219088f, 0.000015f, 0.122938f, 0.042641f, 0.611109f, 0.000237f, 0.652881f, +0.074551f, 1.095486f, 0.000861f, 1.074140f, 0.056280f, 0.750032f, 0.007958f, 1.436411f, 0.095283f, 1.902636f, 0.000984f, 1.540525f, 0.088691f, 0.907608f, 0.002724f, 1.399135f, +0.042217f, 0.915700f, 0.002727f, 0.775903f, 0.031017f, 0.610154f, 0.024539f, 1.009806f, 0.035243f, 1.038785f, 0.002036f, 0.726840f, 0.032693f, 0.493843f, 0.005618f, 0.657885f, +0.125800f, 1.859893f, 0.002652f, 1.710474f, 0.141164f, 1.892819f, 0.036447f, 3.400028f, 0.172984f, 3.475381f, 0.003261f, 2.639307f, 0.292864f, 3.015385f, 0.016424f, 4.359921f, +0.188166f, 2.881324f, 0.000257f, 1.447459f, 0.130365f, 1.810463f, 0.002180f, 1.776433f, 0.018792f, 0.391024f, 0.000023f, 0.162210f, 0.160953f, 1.716396f, 0.000584f, 1.355624f, +0.379489f, 4.149336f, 0.002865f, 3.007729f, 0.319476f, 3.168075f, 0.029541f, 4.485392f, 0.332689f, 4.943172f, 0.002246f, 2.958863f, 0.487320f, 3.710755f, 0.009787f, 4.228924f, +0.150343f, 2.426456f, 0.006351f, 1.519962f, 0.123178f, 1.803027f, 0.063728f, 2.206008f, 0.086089f, 1.888091f, 0.003252f, 0.976657f, 0.125673f, 1.412537f, 0.014122f, 1.391129f, +0.884885f, 9.734753f, 0.012198f, 6.618498f, 1.107324f, 11.048160f, 0.186958f, 14.671330f, 0.834626f, 12.477220f, 0.010290f, 7.005050f, 2.223647f, 17.036170f, 0.081546f, 18.210170f, +0.403293f, 4.420010f, 0.000031f, 2.232946f, 0.203386f, 2.021630f, 0.000194f, 1.994810f, 0.033639f, 0.500991f, 0.000002f, 0.208999f, 0.214404f, 1.636457f, 0.000044f, 1.299772f, +0.415223f, 3.249480f, 0.000179f, 2.368725f, 0.254450f, 1.805974f, 0.001340f, 2.571326f, 0.304030f, 3.233231f, 0.000117f, 1.946241f, 0.331401f, 1.806149f, 0.000379f, 2.069959f, +0.005844f, 0.067511f, 0.000014f, 0.042528f, 0.003486f, 0.036516f, 0.000103f, 0.044930f, 0.002795f, 0.043876f, 0.000006f, 0.022824f, 0.003036f, 0.024426f, 0.000019f, 0.024192f, +0.522539f, 4.114426f, 0.000410f, 2.813095f, 0.475978f, 3.399031f, 0.004579f, 4.539157f, 0.411642f, 4.404512f, 0.000289f, 2.486749f, 0.816119f, 4.475198f, 0.001705f, 4.810552f, +0.512132f, 7.079840f, 0.000271f, 3.132886f, 0.272197f, 3.412724f, 0.001766f, 2.949628f, 0.047224f, 0.887141f, 0.000022f, 0.324170f, 0.196117f, 1.888100f, 0.000276f, 1.313571f, +1.846912f, 18.231260f, 0.005412f, 11.640820f, 1.192795f, 10.678590f, 0.042809f, 13.317590f, 1.495010f, 20.054050f, 0.003918f, 10.573730f, 1.061788f, 7.299222f, 0.008277f, 7.327417f, +0.224588f, 3.272417f, 0.003682f, 1.805658f, 0.141163f, 1.865428f, 0.028347f, 2.010436f, 0.118743f, 2.351134f, 0.001741f, 1.071281f, 0.084047f, 0.852849f, 0.003666f, 0.739855f, +1.197161f, 11.889990f, 0.006406f, 7.120701f, 1.149265f, 10.352060f, 0.075314f, 12.109130f, 1.042596f, 14.071240f, 0.004989f, 6.958775f, 1.346813f, 9.315468f, 0.019170f, 8.771086f, +0.336282f, 3.963213f, 0.000392f, 1.977955f, 0.160719f, 1.717868f, 0.002296f, 1.674572f, 0.042327f, 0.677882f, 0.000044f, 0.279371f, 0.187856f, 1.541828f, 0.000583f, 1.209797f, +0.427928f, 3.601171f, 0.002761f, 2.593335f, 0.248516f, 1.896730f, 0.019635f, 2.667873f, 0.472830f, 5.407121f, 0.002728f, 3.215437f, 0.358880f, 2.103249f, 0.006159f, 2.381294f, +0.151892f, 1.886771f, 0.005482f, 1.174178f, 0.085848f, 0.967150f, 0.037950f, 1.175583f, 0.109621f, 1.850397f, 0.003539f, 0.950909f, 0.082920f, 0.717315f, 0.007962f, 0.701830f, +0.524944f, 4.444718f, 0.006183f, 3.002158f, 0.453153f, 3.479800f, 0.065374f, 4.590800f, 0.624041f, 7.180129f, 0.006574f, 4.004797f, 0.861499f, 5.079893f, 0.026995f, 5.394501f, +1.052104f, 9.226384f, 0.000802f, 3.404134f, 0.560748f, 4.459825f, 0.005238f, 3.213941f, 0.090836f, 1.082471f, 0.000062f, 0.329800f, 0.634412f, 3.874472f, 0.001287f, 2.247476f, +1.948906f, 12.203740f, 0.008221f, 6.497015f, 1.262174f, 7.168010f, 0.065212f, 7.453570f, 1.477080f, 12.568790f, 0.005573f, 5.525524f, 1.764258f, 7.693647f, 0.019799f, 6.439626f, +0.483953f, 4.473174f, 0.011423f, 2.057959f, 0.305031f, 2.557020f, 0.088179f, 2.297735f, 0.239574f, 3.009122f, 0.005057f, 1.143193f, 0.285179f, 1.835688f, 0.017906f, 1.327783f, +3.303681f, 20.814150f, 0.025447f, 10.393310f, 3.180348f, 18.172410f, 0.300033f, 17.723630f, 2.693871f, 23.063490f, 0.018559f, 9.509973f, 5.852382f, 25.678010f, 0.119921f, 20.158780f, +0.005545f, 0.077720f, 0.000003f, 0.057271f, 0.004175f, 0.053072f, 0.000024f, 0.076386f, 0.000868f, 0.016535f, 0.000000f, 0.010062f, 0.005172f, 0.050477f, 0.000006f, 0.058479f, +0.005449f, 0.054528f, 0.000014f, 0.057979f, 0.004985f, 0.045246f, 0.000155f, 0.093966f, 0.007488f, 0.101839f, 0.000017f, 0.089417f, 0.007628f, 0.053166f, 0.000052f, 0.088878f, +0.000188f, 0.002775f, 0.000003f, 0.002550f, 0.000167f, 0.002241f, 0.000029f, 0.004022f, 0.000169f, 0.003385f, 0.000002f, 0.002569f, 0.000171f, 0.001761f, 0.000006f, 0.002544f, +0.008632f, 0.086920f, 0.000040f, 0.086685f, 0.011740f, 0.107207f, 0.000668f, 0.208829f, 0.012764f, 0.174653f, 0.000053f, 0.143833f, 0.023650f, 0.165844f, 0.000292f, 0.260033f, +0.007607f, 0.134479f, 0.000024f, 0.086800f, 0.006036f, 0.096780f, 0.000232f, 0.122012f, 0.001317f, 0.031629f, 0.000004f, 0.016858f, 0.005110f, 0.062912f, 0.000043f, 0.063842f, +0.026180f, 0.330479f, 0.000454f, 0.307793f, 0.025243f, 0.289000f, 0.005362f, 0.525723f, 0.039778f, 0.682335f, 0.000617f, 0.524773f, 0.026402f, 0.232102f, 0.001218f, 0.339861f, +0.007799f, 0.145310f, 0.000757f, 0.116952f, 0.007318f, 0.123669f, 0.008697f, 0.194411f, 0.007739f, 0.195962f, 0.000672f, 0.130240f, 0.005119f, 0.066432f, 0.001321f, 0.084061f, +0.021364f, 0.271339f, 0.000676f, 0.237029f, 0.030620f, 0.352707f, 0.011875f, 0.601794f, 0.034923f, 0.602742f, 0.000989f, 0.434790f, 0.042161f, 0.372916f, 0.003551f, 0.512162f, +0.000195f, 0.002932f, 0.000001f, 0.002134f, 0.000139f, 0.001897f, 0.000012f, 0.002698f, 0.000046f, 0.000941f, 0.000000f, 0.000566f, 0.000191f, 0.002001f, 0.000004f, 0.002290f, +0.000236f, 0.002542f, 0.000009f, 0.002671f, 0.000205f, 0.001999f, 0.000096f, 0.004102f, 0.000490f, 0.007166f, 0.000017f, 0.006215f, 0.000348f, 0.002605f, 0.000035f, 0.004302f, +0.000205f, 0.003263f, 0.000044f, 0.002962f, 0.000173f, 0.002497f, 0.000453f, 0.004428f, 0.000278f, 0.006007f, 0.000053f, 0.004503f, 0.000197f, 0.002176f, 0.000112f, 0.003106f, +0.000365f, 0.003951f, 0.000025f, 0.003892f, 0.000470f, 0.004618f, 0.000401f, 0.008886f, 0.000814f, 0.011979f, 0.000051f, 0.009746f, 0.001050f, 0.007920f, 0.000195f, 0.012269f, +0.018109f, 0.203080f, 0.000082f, 0.109292f, 0.014410f, 0.146558f, 0.000797f, 0.154056f, 0.002935f, 0.044722f, 0.000012f, 0.019875f, 0.019155f, 0.149597f, 0.000230f, 0.126577f, +0.032013f, 0.256346f, 0.000799f, 0.199065f, 0.030953f, 0.224796f, 0.009464f, 0.340958f, 0.045541f, 0.495559f, 0.001017f, 0.317777f, 0.050836f, 0.283492f, 0.003376f, 0.346112f, +0.019473f, 0.230169f, 0.002720f, 0.154460f, 0.018325f, 0.196437f, 0.031349f, 0.257476f, 0.018094f, 0.290630f, 0.002260f, 0.161053f, 0.020129f, 0.165694f, 0.007480f, 0.174817f, +0.068318f, 0.550421f, 0.003114f, 0.400902f, 0.098190f, 0.717473f, 0.054819f, 1.020689f, 0.104564f, 1.144801f, 0.004263f, 0.688544f, 0.212297f, 1.191170f, 0.025744f, 1.364030f, +0.014425f, 0.261958f, 0.000001f, 0.118354f, 0.007996f, 0.131693f, 0.000008f, 0.116214f, 0.001677f, 0.041393f, 0.000000f, 0.015443f, 0.008866f, 0.112123f, 0.000002f, 0.079644f, +0.014925f, 0.193531f, 0.000007f, 0.126167f, 0.010053f, 0.118223f, 0.000055f, 0.150537f, 0.015235f, 0.268451f, 0.000006f, 0.144518f, 0.013771f, 0.124357f, 0.000016f, 0.127460f, +0.000442f, 0.008466f, 0.000001f, 0.004769f, 0.000290f, 0.005033f, 0.000009f, 0.005538f, 0.000295f, 0.007670f, 0.000001f, 0.003568f, 0.000266f, 0.003541f, 0.000002f, 0.003136f, +0.019626f, 0.256052f, 0.000016f, 0.156567f, 0.019650f, 0.232503f, 0.000198f, 0.277680f, 0.021554f, 0.382128f, 0.000016f, 0.192947f, 0.035436f, 0.321968f, 0.000077f, 0.309521f, +0.034873f, 0.798797f, 0.000019f, 0.316121f, 0.020372f, 0.423222f, 0.000138f, 0.327137f, 0.004483f, 0.139540f, 0.000002f, 0.045601f, 0.015438f, 0.246274f, 0.000023f, 0.153230f, +0.126381f, 2.067081f, 0.000387f, 1.180375f, 0.089713f, 1.330788f, 0.003367f, 1.484281f, 0.142617f, 3.169823f, 0.000391f, 1.494708f, 0.083995f, 0.956749f, 0.000685f, 0.858950f, +0.032357f, 0.781184f, 0.000555f, 0.385492f, 0.022354f, 0.489460f, 0.004694f, 0.471764f, 0.023849f, 0.782446f, 0.000366f, 0.318842f, 0.013998f, 0.235363f, 0.000638f, 0.182603f, +0.085599f, 1.408657f, 0.000479f, 0.754470f, 0.090322f, 1.348046f, 0.006190f, 1.410219f, 0.103926f, 2.324065f, 0.000520f, 1.027884f, 0.111328f, 1.275878f, 0.001657f, 1.074369f, +0.006320f, 0.123410f, 0.000008f, 0.055083f, 0.003320f, 0.058796f, 0.000050f, 0.051257f, 0.001109f, 0.029427f, 0.000001f, 0.010846f, 0.004081f, 0.055503f, 0.000013f, 0.038949f, +0.008082f, 0.112687f, 0.000055f, 0.072575f, 0.005159f, 0.065236f, 0.000426f, 0.082063f, 0.012449f, 0.235879f, 0.000075f, 0.125446f, 0.007835f, 0.076086f, 0.000141f, 0.077041f, +0.006040f, 0.124307f, 0.000228f, 0.069184f, 0.003752f, 0.070036f, 0.001734f, 0.076134f, 0.006076f, 0.169954f, 0.000205f, 0.078109f, 0.003812f, 0.054634f, 0.000383f, 0.047806f, +0.010359f, 0.145331f, 0.000128f, 0.087790f, 0.009829f, 0.125061f, 0.001483f, 0.147554f, 0.017168f, 0.327294f, 0.000189f, 0.163261f, 0.019654f, 0.192021f, 0.000644f, 0.182365f, +0.050343f, 0.731501f, 0.000040f, 0.241371f, 0.029492f, 0.388647f, 0.000288f, 0.250479f, 0.006059f, 0.119644f, 0.000004f, 0.032600f, 0.035094f, 0.355121f, 0.000074f, 0.184228f, +0.093712f, 0.972309f, 0.000413f, 0.462936f, 0.066708f, 0.627718f, 0.003604f, 0.583748f, 0.099015f, 1.396038f, 0.000391f, 0.548874f, 0.098073f, 0.708638f, 0.001151f, 0.530455f, +0.048995f, 0.750363f, 0.001209f, 0.308736f, 0.033943f, 0.471459f, 0.010261f, 0.378883f, 0.033813f, 0.703700f, 0.000746f, 0.239091f, 0.033377f, 0.355988f, 0.002192f, 0.230281f, +0.165991f, 1.732819f, 0.001337f, 0.773827f, 0.175637f, 1.662882f, 0.017327f, 1.450431f, 0.188693f, 2.676773f, 0.001359f, 0.987100f, 0.339939f, 2.471364f, 0.007284f, 1.735142f, +0.000080f, 0.001532f, 0.000000f, 0.001054f, 0.000058f, 0.001015f, 0.000000f, 0.001364f, 0.000010f, 0.000247f, 0.000000f, 0.000141f, 0.000069f, 0.000924f, 0.000000f, 0.000999f, +0.000090f, 0.001226f, 0.000000f, 0.001217f, 0.000080f, 0.000987f, 0.000001f, 0.001913f, 0.000094f, 0.001739f, 0.000000f, 0.001425f, 0.000117f, 0.001110f, 0.000000f, 0.001732f, +0.000003f, 0.000063f, 0.000000f, 0.000054f, 0.000003f, 0.000049f, 0.000000f, 0.000082f, 0.000002f, 0.000058f, 0.000000f, 0.000041f, 0.000003f, 0.000037f, 0.000000f, 0.000050f, +0.000144f, 0.001980f, 0.000000f, 0.001844f, 0.000190f, 0.002370f, 0.000003f, 0.004310f, 0.000162f, 0.003022f, 0.000000f, 0.002323f, 0.000367f, 0.003510f, 0.000001f, 0.005137f, +0.000096f, 0.002320f, 0.000000f, 0.001398f, 0.000074f, 0.001620f, 0.000001f, 0.001907f, 0.000013f, 0.000414f, 0.000000f, 0.000206f, 0.000060f, 0.001008f, 0.000000f, 0.000955f, +0.000377f, 0.006503f, 0.000002f, 0.005653f, 0.000353f, 0.005518f, 0.000023f, 0.009371f, 0.000435f, 0.010197f, 0.000002f, 0.007320f, 0.000353f, 0.004242f, 0.000005f, 0.005798f, +0.000113f, 0.002879f, 0.000003f, 0.002163f, 0.000103f, 0.002378f, 0.000037f, 0.003489f, 0.000085f, 0.002949f, 0.000002f, 0.001829f, 0.000069f, 0.001223f, 0.000005f, 0.001444f, +0.000312f, 0.005412f, 0.000003f, 0.004413f, 0.000434f, 0.006826f, 0.000051f, 0.010872f, 0.000387f, 0.009129f, 0.000003f, 0.006147f, 0.000572f, 0.006908f, 0.000015f, 0.008856f, +0.000042f, 0.000859f, 0.000000f, 0.000584f, 0.000029f, 0.000540f, 0.000001f, 0.000716f, 0.000007f, 0.000209f, 0.000000f, 0.000118f, 0.000038f, 0.000545f, 0.000000f, 0.000582f, +0.000058f, 0.000850f, 0.000001f, 0.000833f, 0.000049f, 0.000648f, 0.000007f, 0.001242f, 0.000091f, 0.001819f, 0.000001f, 0.001473f, 0.000079f, 0.000809f, 0.000002f, 0.001247f, +0.000051f, 0.001098f, 0.000003f, 0.000931f, 0.000041f, 0.000816f, 0.000033f, 0.001350f, 0.000052f, 0.001535f, 0.000003f, 0.001074f, 0.000045f, 0.000680f, 0.000008f, 0.000906f, +0.000091f, 0.001338f, 0.000002f, 0.001231f, 0.000113f, 0.001518f, 0.000029f, 0.002727f, 0.000153f, 0.003082f, 0.000003f, 0.002341f, 0.000242f, 0.002492f, 0.000014f, 0.003603f, +0.000267f, 0.004093f, 0.000000f, 0.002056f, 0.000206f, 0.002866f, 0.000003f, 0.002812f, 0.000033f, 0.000685f, 0.000000f, 0.000284f, 0.000263f, 0.002800f, 0.000001f, 0.002212f, +0.000539f, 0.005893f, 0.000004f, 0.004272f, 0.000506f, 0.005015f, 0.000047f, 0.007100f, 0.000582f, 0.008652f, 0.000004f, 0.005179f, 0.000795f, 0.006053f, 0.000016f, 0.006898f, +0.000330f, 0.005328f, 0.000014f, 0.003338f, 0.000301f, 0.004413f, 0.000156f, 0.005399f, 0.000233f, 0.005110f, 0.000009f, 0.002643f, 0.000317f, 0.003563f, 0.000036f, 0.003509f, +0.001166f, 0.012825f, 0.000016f, 0.008719f, 0.001626f, 0.016222f, 0.000275f, 0.021542f, 0.001355f, 0.020258f, 0.000017f, 0.011373f, 0.003365f, 0.025778f, 0.000123f, 0.027554f, +0.026737f, 0.293036f, 0.000002f, 0.148039f, 0.015028f, 0.149380f, 0.000014f, 0.147398f, 0.002748f, 0.040933f, 0.000000f, 0.017076f, 0.016326f, 0.124609f, 0.000003f, 0.098972f, +0.027523f, 0.215389f, 0.000012f, 0.157009f, 0.018798f, 0.133418f, 0.000099f, 0.189959f, 0.024836f, 0.264115f, 0.000010f, 0.158984f, 0.025230f, 0.137502f, 0.000029f, 0.157586f, +0.000599f, 0.006919f, 0.000001f, 0.004358f, 0.000398f, 0.004171f, 0.000012f, 0.005132f, 0.000353f, 0.005542f, 0.000001f, 0.002883f, 0.000357f, 0.002875f, 0.000002f, 0.002848f, +0.032129f, 0.252978f, 0.000025f, 0.172965f, 0.032618f, 0.232929f, 0.000314f, 0.311059f, 0.031192f, 0.333748f, 0.000022f, 0.188431f, 0.057633f, 0.316034f, 0.000120f, 0.339716f, +0.056138f, 0.776059f, 0.000030f, 0.343412f, 0.033254f, 0.416933f, 0.000216f, 0.360356f, 0.006379f, 0.119843f, 0.000003f, 0.043792f, 0.024691f, 0.237708f, 0.000035f, 0.165376f, +0.202409f, 1.998023f, 0.000593f, 1.275755f, 0.145695f, 1.304341f, 0.005229f, 1.626683f, 0.201918f, 2.708526f, 0.000529f, 1.428101f, 0.133650f, 0.918772f, 0.001042f, 0.922321f, +0.038056f, 0.554498f, 0.000624f, 0.305962f, 0.026659f, 0.352293f, 0.005353f, 0.379678f, 0.024796f, 0.490971f, 0.000364f, 0.223708f, 0.016357f, 0.165978f, 0.000713f, 0.143988f, +0.121703f, 1.208731f, 0.000651f, 0.723887f, 0.130215f, 1.172920f, 0.008533f, 1.372002f, 0.130620f, 1.762900f, 0.000625f, 0.871822f, 0.157254f, 1.087678f, 0.002238f, 1.024116f, +0.015717f, 0.185230f, 0.000018f, 0.092444f, 0.008372f, 0.089485f, 0.000120f, 0.087229f, 0.002438f, 0.039045f, 0.000003f, 0.016091f, 0.010084f, 0.082765f, 0.000031f, 0.064942f, +0.019996f, 0.168275f, 0.000129f, 0.121181f, 0.012943f, 0.098782f, 0.001023f, 0.138943f, 0.027229f, 0.311380f, 0.000157f, 0.185167f, 0.019261f, 0.112879f, 0.000331f, 0.127802f, +0.010974f, 0.136315f, 0.000396f, 0.084832f, 0.006913f, 0.077878f, 0.003056f, 0.094661f, 0.009760f, 0.164754f, 0.000315f, 0.084666f, 0.006881f, 0.059523f, 0.000661f, 0.058238f, +0.022754f, 0.192657f, 0.000268f, 0.130129f, 0.021892f, 0.168108f, 0.003158f, 0.221780f, 0.033335f, 0.383549f, 0.000351f, 0.213929f, 0.042889f, 0.252897f, 0.001344f, 0.268559f, +0.090026f, 0.789479f, 0.000069f, 0.291283f, 0.053477f, 0.425324f, 0.000500f, 0.306507f, 0.009579f, 0.114149f, 0.000007f, 0.034778f, 0.062349f, 0.380775f, 0.000127f, 0.220878f, +0.166730f, 1.044034f, 0.000703f, 0.555822f, 0.120347f, 0.683461f, 0.006218f, 0.710689f, 0.155730f, 1.325141f, 0.000588f, 0.582562f, 0.173353f, 0.755964f, 0.001945f, 0.632746f, +0.064014f, 0.591677f, 0.001511f, 0.272211f, 0.044968f, 0.376962f, 0.012999f, 0.338737f, 0.039053f, 0.490519f, 0.000824f, 0.186353f, 0.043325f, 0.278879f, 0.002720f, 0.201718f, +0.262171f, 1.651751f, 0.002019f, 0.824784f, 0.281290f, 1.607282f, 0.026537f, 1.567590f, 0.263457f, 2.255579f, 0.001815f, 0.930063f, 0.533416f, 2.340426f, 0.010930f, 1.837374f, +0.019864f, 0.278401f, 0.000009f, 0.205151f, 0.012936f, 0.164429f, 0.000073f, 0.236661f, 0.002675f, 0.050938f, 0.000001f, 0.030996f, 0.014978f, 0.146190f, 0.000018f, 0.169367f, +0.018824f, 0.188385f, 0.000048f, 0.200306f, 0.014896f, 0.135199f, 0.000464f, 0.280780f, 0.022249f, 0.302577f, 0.000051f, 0.265670f, 0.021308f, 0.148508f, 0.000144f, 0.248259f, +0.000828f, 0.012237f, 0.000012f, 0.011244f, 0.000638f, 0.008547f, 0.000111f, 0.015339f, 0.000640f, 0.012838f, 0.000008f, 0.009741f, 0.000610f, 0.006279f, 0.000023f, 0.009071f, +0.029134f, 0.293357f, 0.000135f, 0.292563f, 0.034269f, 0.312947f, 0.001951f, 0.609591f, 0.037049f, 0.506934f, 0.000154f, 0.417478f, 0.064536f, 0.452547f, 0.000798f, 0.709568f, +0.020561f, 0.363488f, 0.000064f, 0.234617f, 0.014112f, 0.226254f, 0.000542f, 0.285240f, 0.003061f, 0.073524f, 0.000009f, 0.039188f, 0.011167f, 0.137485f, 0.000093f, 0.139519f, +0.068249f, 0.861524f, 0.001184f, 0.802383f, 0.056917f, 0.651618f, 0.012089f, 1.185366f, 0.089179f, 1.529748f, 0.001383f, 1.176504f, 0.055648f, 0.489206f, 0.002567f, 0.716331f, +0.025948f, 0.483484f, 0.002518f, 0.389132f, 0.021060f, 0.355894f, 0.025027f, 0.559474f, 0.022146f, 0.560736f, 0.001922f, 0.372676f, 0.013772f, 0.178711f, 0.003555f, 0.226137f, +0.054407f, 0.691014f, 0.001723f, 0.603637f, 0.067446f, 0.776893f, 0.026157f, 1.325546f, 0.076487f, 1.320095f, 0.002166f, 0.952254f, 0.086811f, 0.767847f, 0.007313f, 1.054559f, +0.000764f, 0.011521f, 0.000005f, 0.008387f, 0.000472f, 0.006448f, 0.000040f, 0.009169f, 0.000155f, 0.003181f, 0.000001f, 0.001912f, 0.000606f, 0.006357f, 0.000011f, 0.007275f, +0.000895f, 0.009635f, 0.000034f, 0.010121f, 0.000671f, 0.006553f, 0.000314f, 0.013445f, 0.001597f, 0.023353f, 0.000055f, 0.020257f, 0.001065f, 0.007981f, 0.000108f, 0.013181f, +0.000994f, 0.015783f, 0.000212f, 0.014327f, 0.000725f, 0.010447f, 0.001897f, 0.018523f, 0.001158f, 0.024987f, 0.000221f, 0.018730f, 0.000769f, 0.008510f, 0.000437f, 0.012146f, +0.001351f, 0.014626f, 0.000094f, 0.014410f, 0.001506f, 0.014786f, 0.001286f, 0.028453f, 0.002592f, 0.038139f, 0.000162f, 0.031029f, 0.003144f, 0.023708f, 0.000583f, 0.036723f, +0.059305f, 0.665065f, 0.000268f, 0.357921f, 0.040816f, 0.415126f, 0.002256f, 0.436362f, 0.008265f, 0.125955f, 0.000033f, 0.055975f, 0.050719f, 0.396105f, 0.000609f, 0.335151f, +0.101113f, 0.809673f, 0.002524f, 0.628750f, 0.084560f, 0.614107f, 0.025855f, 0.931445f, 0.123705f, 1.346100f, 0.002762f, 0.863186f, 0.129820f, 0.723958f, 0.008622f, 0.883872f, +0.078502f, 0.927888f, 0.010965f, 0.622678f, 0.063893f, 0.684924f, 0.109306f, 0.897751f, 0.062732f, 1.007596f, 0.007837f, 0.558360f, 0.065609f, 0.540061f, 0.024379f, 0.569795f, +0.210799f, 1.698362f, 0.009609f, 1.237010f, 0.262044f, 1.914754f, 0.146299f, 2.723959f, 0.277469f, 3.037831f, 0.011312f, 1.827113f, 0.529625f, 2.971650f, 0.064225f, 3.402889f, +0.066708f, 1.211395f, 0.000005f, 0.547314f, 0.031982f, 0.526733f, 0.000032f, 0.464821f, 0.006671f, 0.164620f, 0.000000f, 0.061418f, 0.033148f, 0.419215f, 0.000007f, 0.297779f, +0.066566f, 0.863159f, 0.000030f, 0.562713f, 0.038779f, 0.456052f, 0.000214f, 0.580705f, 0.058436f, 1.029684f, 0.000024f, 0.554319f, 0.049658f, 0.448435f, 0.000059f, 0.459625f, +0.002518f, 0.048191f, 0.000006f, 0.027149f, 0.001427f, 0.024780f, 0.000044f, 0.027267f, 0.001444f, 0.037549f, 0.000003f, 0.017468f, 0.001223f, 0.016297f, 0.000008f, 0.014435f, +0.085511f, 1.115631f, 0.000070f, 0.682168f, 0.074049f, 0.876179f, 0.000745f, 1.046425f, 0.080763f, 1.431856f, 0.000059f, 0.722985f, 0.124832f, 1.134208f, 0.000273f, 1.090363f, +0.121686f, 2.787335f, 0.000067f, 1.103077f, 0.061485f, 1.277300f, 0.000417f, 0.987312f, 0.013453f, 0.418744f, 0.000007f, 0.136844f, 0.043556f, 0.694800f, 0.000064f, 0.432299f, +0.425323f, 6.956597f, 0.001303f, 3.972458f, 0.261135f, 3.873648f, 0.009801f, 4.320434f, 0.412769f, 9.174293f, 0.001131f, 4.326075f, 0.228549f, 2.603310f, 0.001863f, 2.337200f, +0.138985f, 3.355496f, 0.002383f, 1.655843f, 0.083048f, 1.818414f, 0.017439f, 1.752669f, 0.088101f, 2.890386f, 0.001351f, 1.177815f, 0.048615f, 0.817390f, 0.002217f, 0.634161f, +0.281423f, 4.631226f, 0.001575f, 2.480463f, 0.256835f, 3.833252f, 0.017601f, 4.010043f, 0.293842f, 6.571088f, 0.001470f, 2.906251f, 0.295927f, 3.391473f, 0.004405f, 2.855832f, +0.032057f, 0.626005f, 0.000039f, 0.279411f, 0.014565f, 0.257957f, 0.000218f, 0.224883f, 0.004838f, 0.128373f, 0.000005f, 0.047315f, 0.016739f, 0.227633f, 0.000054f, 0.159738f, +0.039537f, 0.551301f, 0.000267f, 0.355058f, 0.021828f, 0.276043f, 0.001803f, 0.347242f, 0.052376f, 0.992434f, 0.000316f, 0.527802f, 0.030992f, 0.300957f, 0.000556f, 0.304735f, +0.037712f, 0.776197f, 0.001423f, 0.431999f, 0.020263f, 0.378245f, 0.009367f, 0.411176f, 0.032631f, 0.912659f, 0.001102f, 0.419448f, 0.019243f, 0.275824f, 0.001932f, 0.241351f, +0.049509f, 0.694582f, 0.000610f, 0.419574f, 0.040630f, 0.516964f, 0.006129f, 0.609943f, 0.070563f, 1.345247f, 0.000777f, 0.671036f, 0.075944f, 0.741999f, 0.002489f, 0.704686f, +0.212838f, 3.092631f, 0.000170f, 1.020467f, 0.107841f, 1.421153f, 0.001053f, 0.915917f, 0.022031f, 0.435014f, 0.000016f, 0.118531f, 0.119958f, 1.213887f, 0.000255f, 0.629733f, +0.382116f, 3.964643f, 0.001686f, 1.887646f, 0.235261f, 2.213787f, 0.012711f, 2.058720f, 0.347215f, 4.895477f, 0.001370f, 1.924733f, 0.323322f, 2.336214f, 0.003794f, 1.748785f, +0.254985f, 3.905123f, 0.006294f, 1.606761f, 0.152785f, 2.122166f, 0.046187f, 1.705457f, 0.151336f, 3.149554f, 0.003341f, 1.070100f, 0.140443f, 1.497914f, 0.009222f, 0.968971f, +0.661206f, 6.902464f, 0.005326f, 3.082443f, 0.605117f, 5.729071f, 0.059697f, 4.997122f, 0.646406f, 9.169818f, 0.004657f, 3.381509f, 1.094814f, 7.959322f, 0.023460f, 5.588231f, +0.016373f, 0.313344f, 0.000002f, 0.215534f, 0.010347f, 0.179588f, 0.000018f, 0.241277f, 0.001674f, 0.043541f, 0.000000f, 0.024732f, 0.011467f, 0.152821f, 0.000004f, 0.165266f, +0.017698f, 0.241844f, 0.000014f, 0.240036f, 0.013590f, 0.168427f, 0.000128f, 0.326509f, 0.015887f, 0.295006f, 0.000011f, 0.241785f, 0.018607f, 0.177074f, 0.000038f, 0.276314f, +0.000784f, 0.015819f, 0.000003f, 0.013568f, 0.000586f, 0.010722f, 0.000031f, 0.017962f, 0.000460f, 0.012604f, 0.000002f, 0.008927f, 0.000537f, 0.007540f, 0.000006f, 0.010167f, +0.027763f, 0.381705f, 0.000039f, 0.355338f, 0.031689f, 0.395139f, 0.000546f, 0.718472f, 0.026812f, 0.500943f, 0.000034f, 0.385089f, 0.057118f, 0.546904f, 0.000214f, 0.800447f, +0.014835f, 0.358104f, 0.000014f, 0.215760f, 0.009880f, 0.216304f, 0.000115f, 0.254548f, 0.001677f, 0.055011f, 0.000001f, 0.027370f, 0.007484f, 0.125803f, 0.000019f, 0.119168f, +0.056167f, 0.968116f, 0.000295f, 0.841653f, 0.045454f, 0.710560f, 0.002920f, 1.206568f, 0.055738f, 1.305523f, 0.000261f, 0.937237f, 0.042535f, 0.510584f, 0.000593f, 0.697880f, +0.021503f, 0.547094f, 0.000631f, 0.411025f, 0.016936f, 0.390794f, 0.006087f, 0.573455f, 0.013938f, 0.481884f, 0.000366f, 0.298956f, 0.010600f, 0.187822f, 0.000827f, 0.221850f, +0.045382f, 0.787025f, 0.000435f, 0.641754f, 0.054592f, 0.858638f, 0.006403f, 1.367526f, 0.048453f, 1.141856f, 0.000415f, 0.768866f, 0.067254f, 0.812254f, 0.001713f, 1.041309f, +0.009369f, 0.192795f, 0.000020f, 0.131010f, 0.005611f, 0.104716f, 0.000143f, 0.138985f, 0.001446f, 0.040427f, 0.000003f, 0.022685f, 0.006894f, 0.098802f, 0.000038f, 0.105555f, +0.012516f, 0.183914f, 0.000144f, 0.180331f, 0.009108f, 0.121382f, 0.001288f, 0.232462f, 0.016954f, 0.338540f, 0.000175f, 0.274109f, 0.013827f, 0.141496f, 0.000425f, 0.218124f, +0.013987f, 0.303371f, 0.000903f, 0.257056f, 0.009906f, 0.194861f, 0.007837f, 0.322496f, 0.012375f, 0.364747f, 0.000715f, 0.255214f, 0.010058f, 0.151930f, 0.001728f, 0.202398f, +0.019138f, 0.282952f, 0.000403f, 0.260220f, 0.020702f, 0.277587f, 0.005345f, 0.498623f, 0.027892f, 0.560367f, 0.000526f, 0.425559f, 0.041374f, 0.425994f, 0.002320f, 0.615941f, +0.049990f, 0.765475f, 0.000068f, 0.384543f, 0.033386f, 0.463654f, 0.000558f, 0.454939f, 0.005291f, 0.110100f, 0.000006f, 0.045673f, 0.039708f, 0.423441f, 0.000144f, 0.334437f, +0.097216f, 1.062959f, 0.000734f, 0.770507f, 0.078894f, 0.782346f, 0.007295f, 1.107654f, 0.090328f, 1.342113f, 0.000610f, 0.803357f, 0.115928f, 0.882747f, 0.002328f, 1.006014f, +0.076003f, 1.226654f, 0.003211f, 0.768391f, 0.060027f, 0.878653f, 0.031056f, 1.075034f, 0.046125f, 1.011622f, 0.001743f, 0.523284f, 0.058997f, 0.663110f, 0.006630f, 0.653060f, +0.205419f, 2.259846f, 0.002832f, 1.536432f, 0.247796f, 2.472347f, 0.041837f, 3.283136f, 0.205348f, 3.069849f, 0.002532f, 1.723497f, 0.479353f, 3.672501f, 0.017579f, 3.925580f, +0.107323f, 1.176235f, 0.000008f, 0.594222f, 0.052174f, 0.518606f, 0.000050f, 0.511726f, 0.009488f, 0.141301f, 0.000001f, 0.058947f, 0.052983f, 0.404400f, 0.000011f, 0.321199f, +0.106550f, 0.833842f, 0.000046f, 0.607833f, 0.062942f, 0.446732f, 0.000332f, 0.636052f, 0.082686f, 0.879330f, 0.000032f, 0.529312f, 0.078969f, 0.430387f, 0.000090f, 0.493250f, +0.002959f, 0.034187f, 0.000007f, 0.021536f, 0.001701f, 0.017825f, 0.000050f, 0.021932f, 0.001500f, 0.023548f, 0.000003f, 0.012249f, 0.001428f, 0.011486f, 0.000009f, 0.011376f, +0.121508f, 0.956742f, 0.000095f, 0.654139f, 0.106694f, 0.761915f, 0.001026f, 1.017481f, 0.101450f, 1.085497f, 0.000071f, 0.612862f, 0.176228f, 0.966349f, 0.000368f, 1.038763f, +0.170030f, 2.350538f, 0.000090f, 1.040132f, 0.087115f, 1.092221f, 0.000565f, 0.944010f, 0.016617f, 0.312163f, 0.000008f, 0.114068f, 0.060464f, 0.582110f, 0.000085f, 0.404980f, +0.591274f, 5.836594f, 0.001733f, 3.726717f, 0.368107f, 3.295506f, 0.013211f, 4.109924f, 0.507262f, 6.804407f, 0.001329f, 3.587701f, 0.315658f, 2.169978f, 0.002461f, 2.178360f, +0.141887f, 2.067393f, 0.002326f, 1.140748f, 0.085969f, 1.136052f, 0.017263f, 1.224363f, 0.079508f, 1.574263f, 0.001166f, 0.717304f, 0.049308f, 0.500337f, 0.002151f, 0.434047f, +0.347305f, 3.449371f, 0.001858f, 2.065767f, 0.321399f, 2.895015f, 0.021062f, 3.386390f, 0.320568f, 4.326497f, 0.001534f, 2.139620f, 0.362829f, 2.509569f, 0.005164f, 2.362914f, +0.069202f, 0.815567f, 0.000081f, 0.407032f, 0.031882f, 0.340775f, 0.000455f, 0.332186f, 0.009232f, 0.147847f, 0.000010f, 0.060931f, 0.035898f, 0.294635f, 0.000111f, 0.231186f, +0.084915f, 0.714587f, 0.000548f, 0.514600f, 0.047537f, 0.362813f, 0.003756f, 0.510319f, 0.099440f, 1.137163f, 0.000574f, 0.676234f, 0.066130f, 0.387559f, 0.001135f, 0.438794f, +0.059478f, 0.738826f, 0.002147f, 0.459787f, 0.032406f, 0.365075f, 0.014325f, 0.443754f, 0.045495f, 0.767950f, 0.001469f, 0.394645f, 0.030152f, 0.260837f, 0.002895f, 0.255206f, +0.094393f, 0.799229f, 0.001112f, 0.539834f, 0.078548f, 0.603180f, 0.011332f, 0.795758f, 0.118928f, 1.368374f, 0.001253f, 0.763226f, 0.143853f, 0.848238f, 0.004508f, 0.900771f, +0.330370f, 2.897166f, 0.000252f, 1.068928f, 0.169736f, 1.349973f, 0.001586f, 0.972849f, 0.030230f, 0.360249f, 0.000021f, 0.109758f, 0.184991f, 1.129771f, 0.000375f, 0.655350f, +0.590108f, 3.695164f, 0.002489f, 1.967228f, 0.368405f, 2.092208f, 0.019034f, 2.175558f, 0.474013f, 4.033479f, 0.001788f, 1.773208f, 0.496065f, 2.163262f, 0.005567f, 1.810662f, +0.289172f, 2.672811f, 0.006825f, 1.229671f, 0.175696f, 1.472828f, 0.050790f, 1.323482f, 0.151718f, 1.905626f, 0.003203f, 0.723965f, 0.158236f, 1.018561f, 0.009936f, 0.736742f, +0.906473f, 5.711041f, 0.006982f, 2.851744f, 0.841195f, 4.806564f, 0.079358f, 4.687863f, 0.783391f, 6.706979f, 0.005397f, 2.765548f, 1.491163f, 6.542654f, 0.030555f, 5.136375f, +0.003088f, 0.043274f, 0.000001f, 0.031889f, 0.002739f, 0.034821f, 0.000015f, 0.050117f, 0.000475f, 0.009039f, 0.000000f, 0.005501f, 0.003488f, 0.034041f, 0.000004f, 0.039438f, +0.005786f, 0.057907f, 0.000015f, 0.061571f, 0.006238f, 0.056618f, 0.000194f, 0.117583f, 0.007808f, 0.106182f, 0.000018f, 0.093231f, 0.009812f, 0.068385f, 0.000066f, 0.114319f, +0.000113f, 0.001671f, 0.000002f, 0.001536f, 0.000119f, 0.001590f, 0.000021f, 0.002854f, 0.000100f, 0.002002f, 0.000001f, 0.001519f, 0.000125f, 0.001285f, 0.000005f, 0.001856f, +0.005597f, 0.056360f, 0.000026f, 0.056208f, 0.008970f, 0.081912f, 0.000511f, 0.159556f, 0.008126f, 0.111190f, 0.000034f, 0.091568f, 0.018574f, 0.130248f, 0.000230f, 0.204221f, +0.003768f, 0.066610f, 0.000012f, 0.042994f, 0.003523f, 0.056486f, 0.000135f, 0.071212f, 0.000640f, 0.015382f, 0.000002f, 0.008199f, 0.003066f, 0.037743f, 0.000026f, 0.038301f, +0.024732f, 0.312202f, 0.000429f, 0.290770f, 0.028100f, 0.321705f, 0.005968f, 0.585217f, 0.036895f, 0.632882f, 0.000572f, 0.486739f, 0.030210f, 0.265576f, 0.001394f, 0.388876f, +0.004178f, 0.077851f, 0.000405f, 0.062658f, 0.004620f, 0.078073f, 0.005490f, 0.122732f, 0.004071f, 0.103080f, 0.000353f, 0.068509f, 0.003322f, 0.043108f, 0.000858f, 0.054549f, +0.012323f, 0.156513f, 0.000390f, 0.136722f, 0.020812f, 0.239729f, 0.008071f, 0.409029f, 0.019778f, 0.341353f, 0.000560f, 0.246236f, 0.029456f, 0.260536f, 0.002481f, 0.357820f, +0.000179f, 0.002693f, 0.000001f, 0.001960f, 0.000150f, 0.002053f, 0.000013f, 0.002920f, 0.000041f, 0.000849f, 0.000000f, 0.000510f, 0.000212f, 0.002226f, 0.000004f, 0.002547f, +0.000414f, 0.004453f, 0.000016f, 0.004678f, 0.000423f, 0.004126f, 0.000198f, 0.008466f, 0.000843f, 0.012323f, 0.000029f, 0.010689f, 0.000737f, 0.005526f, 0.000075f, 0.009126f, +0.000204f, 0.003241f, 0.000044f, 0.002942f, 0.000203f, 0.002923f, 0.000531f, 0.005183f, 0.000271f, 0.005858f, 0.000052f, 0.004391f, 0.000237f, 0.002618f, 0.000134f, 0.003737f, +0.000390f, 0.004225f, 0.000027f, 0.004163f, 0.000593f, 0.005819f, 0.000506f, 0.011198f, 0.000855f, 0.012578f, 0.000053f, 0.010233f, 0.001361f, 0.010260f, 0.000252f, 0.015892f, +0.009932f, 0.111380f, 0.000045f, 0.059942f, 0.009313f, 0.094715f, 0.000515f, 0.099560f, 0.001580f, 0.024082f, 0.000006f, 0.010702f, 0.012725f, 0.099376f, 0.000153f, 0.084084f, +0.033487f, 0.268148f, 0.000836f, 0.208230f, 0.038153f, 0.277080f, 0.011666f, 0.420261f, 0.046772f, 0.508952f, 0.001044f, 0.326366f, 0.064408f, 0.359177f, 0.004277f, 0.438515f, +0.011552f, 0.136544f, 0.001614f, 0.091631f, 0.012809f, 0.137315f, 0.021914f, 0.179983f, 0.010539f, 0.169278f, 0.001317f, 0.093805f, 0.014463f, 0.119056f, 0.005374f, 0.125611f, +0.043634f, 0.351553f, 0.001989f, 0.256055f, 0.073898f, 0.539970f, 0.041257f, 0.768170f, 0.065571f, 0.717891f, 0.002673f, 0.431778f, 0.164232f, 0.921484f, 0.019916f, 1.055208f, +0.012272f, 0.222855f, 0.000001f, 0.100687f, 0.008016f, 0.132015f, 0.000008f, 0.116498f, 0.001401f, 0.034574f, 0.000000f, 0.012899f, 0.009135f, 0.115532f, 0.000002f, 0.082066f, +0.024216f, 0.314014f, 0.000011f, 0.204713f, 0.019220f, 0.226032f, 0.000106f, 0.287813f, 0.024270f, 0.427659f, 0.000010f, 0.230225f, 0.027063f, 0.244393f, 0.000032f, 0.250491f, +0.000407f, 0.007790f, 0.000001f, 0.004389f, 0.000314f, 0.005457f, 0.000010f, 0.006005f, 0.000266f, 0.006930f, 0.000001f, 0.003224f, 0.000296f, 0.003947f, 0.000002f, 0.003496f, +0.019444f, 0.253673f, 0.000016f, 0.155112f, 0.022939f, 0.271421f, 0.000231f, 0.324159f, 0.020965f, 0.371696f, 0.000015f, 0.187680f, 0.042522f, 0.386346f, 0.000093f, 0.371411f, +0.026391f, 0.604521f, 0.000015f, 0.239237f, 0.018167f, 0.377409f, 0.000123f, 0.291725f, 0.003331f, 0.103683f, 0.000002f, 0.033883f, 0.014151f, 0.225742f, 0.000021f, 0.140455f, +0.182416f, 2.983603f, 0.000559f, 1.703741f, 0.152583f, 2.263397f, 0.005727f, 2.524458f, 0.202109f, 4.492122f, 0.000554f, 2.118229f, 0.146843f, 1.672630f, 0.001197f, 1.501654f, +0.026487f, 0.639461f, 0.000454f, 0.315556f, 0.021562f, 0.472114f, 0.004528f, 0.455045f, 0.019168f, 0.628852f, 0.000294f, 0.256253f, 0.013879f, 0.233355f, 0.000633f, 0.181045f, +0.075440f, 1.241468f, 0.000422f, 0.664924f, 0.093797f, 1.399921f, 0.006428f, 1.464486f, 0.089927f, 2.010998f, 0.000450f, 0.889421f, 0.118837f, 1.361939f, 0.001769f, 1.146838f, +0.008868f, 0.173163f, 0.000011f, 0.077290f, 0.005489f, 0.097212f, 0.000082f, 0.084748f, 0.001528f, 0.040540f, 0.000002f, 0.014942f, 0.006936f, 0.094329f, 0.000023f, 0.066194f, +0.021628f, 0.301570f, 0.000146f, 0.194222f, 0.016267f, 0.205718f, 0.001344f, 0.258779f, 0.032709f, 0.619778f, 0.000197f, 0.329614f, 0.025397f, 0.246624f, 0.000456f, 0.249720f, +0.009166f, 0.188663f, 0.000346f, 0.105002f, 0.006710f, 0.125251f, 0.003102f, 0.136156f, 0.009055f, 0.253254f, 0.000306f, 0.116393f, 0.007007f, 0.100433f, 0.000704f, 0.087881f, +0.016927f, 0.237476f, 0.000209f, 0.143451f, 0.018925f, 0.240797f, 0.002855f, 0.284106f, 0.027543f, 0.525088f, 0.000303f, 0.261924f, 0.038897f, 0.380039f, 0.001275f, 0.360928f, +0.042186f, 0.612982f, 0.000034f, 0.202264f, 0.029121f, 0.383757f, 0.000284f, 0.247327f, 0.004985f, 0.098437f, 0.000004f, 0.026822f, 0.035619f, 0.360436f, 0.000076f, 0.186985f, +0.149774f, 1.553980f, 0.000661f, 0.739881f, 0.125628f, 1.182153f, 0.006788f, 1.099348f, 0.155373f, 2.190640f, 0.000613f, 0.861284f, 0.189848f, 1.371778f, 0.002228f, 1.026851f, +0.044409f, 0.680126f, 0.001096f, 0.279838f, 0.036252f, 0.503536f, 0.010959f, 0.404662f, 0.030091f, 0.626237f, 0.000664f, 0.212772f, 0.036642f, 0.390815f, 0.002406f, 0.252811f, +0.161984f, 1.690989f, 0.001305f, 0.755147f, 0.201963f, 1.912130f, 0.019924f, 1.667835f, 0.180791f, 2.564674f, 0.001302f, 0.945762f, 0.401797f, 2.921074f, 0.008610f, 2.050883f, +0.003212f, 0.061478f, 0.000000f, 0.042288f, 0.002766f, 0.048003f, 0.000005f, 0.064493f, 0.000375f, 0.009753f, 0.000000f, 0.005540f, 0.003370f, 0.044917f, 0.000001f, 0.048575f, +0.006867f, 0.093833f, 0.000005f, 0.093131f, 0.007184f, 0.089028f, 0.000068f, 0.172589f, 0.007037f, 0.130673f, 0.000005f, 0.107099f, 0.010815f, 0.102921f, 0.000022f, 0.160603f, +0.000135f, 0.002727f, 0.000001f, 0.002339f, 0.000138f, 0.002518f, 0.000007f, 0.004219f, 0.000091f, 0.002481f, 0.000000f, 0.001757f, 0.000139f, 0.001947f, 0.000002f, 0.002626f, +0.006732f, 0.092564f, 0.000009f, 0.086170f, 0.010469f, 0.130546f, 0.000180f, 0.237368f, 0.007423f, 0.138688f, 0.000009f, 0.106613f, 0.020750f, 0.198681f, 0.000078f, 0.290789f, +0.003431f, 0.082831f, 0.000003f, 0.049906f, 0.003114f, 0.068162f, 0.000036f, 0.080214f, 0.000443f, 0.014527f, 0.000000f, 0.007228f, 0.002593f, 0.043592f, 0.000007f, 0.041293f, +0.025691f, 0.442826f, 0.000135f, 0.384981f, 0.028326f, 0.442796f, 0.001819f, 0.751890f, 0.029106f, 0.681750f, 0.000137f, 0.489430f, 0.029147f, 0.349867f, 0.000407f, 0.478208f, +0.004370f, 0.111194f, 0.000128f, 0.083539f, 0.004690f, 0.108209f, 0.001685f, 0.158787f, 0.003234f, 0.111814f, 0.000085f, 0.069368f, 0.003228f, 0.057187f, 0.000252f, 0.067547f, +0.012974f, 0.225004f, 0.000124f, 0.183472f, 0.021263f, 0.334432f, 0.002494f, 0.532640f, 0.015814f, 0.372690f, 0.000135f, 0.250950f, 0.028804f, 0.347875f, 0.000734f, 0.445976f, +0.002764f, 0.056877f, 0.000006f, 0.038649f, 0.002255f, 0.042087f, 0.000058f, 0.055860f, 0.000487f, 0.013616f, 0.000001f, 0.007640f, 0.003047f, 0.043665f, 0.000017f, 0.046650f, +0.007302f, 0.107294f, 0.000084f, 0.105204f, 0.007239f, 0.096474f, 0.001024f, 0.184761f, 0.011292f, 0.225479f, 0.000117f, 0.182566f, 0.012084f, 0.123661f, 0.000371f, 0.190632f, +0.003626f, 0.078641f, 0.000234f, 0.066635f, 0.003498f, 0.068817f, 0.002768f, 0.113893f, 0.003662f, 0.107945f, 0.000212f, 0.075529f, 0.003906f, 0.059000f, 0.000671f, 0.078598f, +0.006978f, 0.103174f, 0.000147f, 0.094885f, 0.010284f, 0.137896f, 0.002655f, 0.247700f, 0.011611f, 0.233273f, 0.000219f, 0.177154f, 0.022600f, 0.232697f, 0.001267f, 0.336454f, +0.010567f, 0.161813f, 0.000014f, 0.081288f, 0.009615f, 0.133528f, 0.000161f, 0.131018f, 0.001277f, 0.026571f, 0.000002f, 0.011022f, 0.012574f, 0.134092f, 0.000046f, 0.105907f, +0.040639f, 0.444344f, 0.000307f, 0.322092f, 0.044931f, 0.445552f, 0.004155f, 0.630818f, 0.043108f, 0.640512f, 0.000291f, 0.383395f, 0.072597f, 0.552802f, 0.001458f, 0.629995f, +0.014117f, 0.227845f, 0.000596f, 0.142725f, 0.015190f, 0.222347f, 0.007859f, 0.272042f, 0.009781f, 0.214521f, 0.000370f, 0.110966f, 0.016416f, 0.184515f, 0.001845f, 0.181719f, +0.053671f, 0.590442f, 0.000740f, 0.401432f, 0.088204f, 0.880044f, 0.014892f, 1.168648f, 0.061253f, 0.915694f, 0.000755f, 0.514096f, 0.187622f, 1.437442f, 0.006881f, 1.536499f, +0.028008f, 0.306961f, 0.000002f, 0.155074f, 0.018550f, 0.184384f, 0.000018f, 0.181938f, 0.002827f, 0.042099f, 0.000000f, 0.017562f, 0.020714f, 0.158099f, 0.000004f, 0.125572f, +0.054987f, 0.430323f, 0.000024f, 0.313686f, 0.044253f, 0.314090f, 0.000233f, 0.447198f, 0.048717f, 0.518081f, 0.000019f, 0.311858f, 0.061052f, 0.332736f, 0.000070f, 0.381336f, +0.000679f, 0.007839f, 0.000002f, 0.004938f, 0.000532f, 0.005569f, 0.000016f, 0.006852f, 0.000393f, 0.006165f, 0.000001f, 0.003207f, 0.000490f, 0.003946f, 0.000003f, 0.003908f, +0.039193f, 0.308603f, 0.000031f, 0.210997f, 0.046886f, 0.334818f, 0.000451f, 0.447125f, 0.037359f, 0.399732f, 0.000026f, 0.225686f, 0.085155f, 0.466949f, 0.000178f, 0.501940f, +0.052312f, 0.723172f, 0.000028f, 0.320010f, 0.036514f, 0.457806f, 0.000237f, 0.395683f, 0.005837f, 0.109646f, 0.000003f, 0.040066f, 0.027868f, 0.268293f, 0.000039f, 0.186654f, +0.359737f, 3.551042f, 0.001054f, 2.267371f, 0.305117f, 2.731586f, 0.010951f, 3.406643f, 0.352341f, 4.726301f, 0.000923f, 2.491996f, 0.287702f, 1.977796f, 0.002243f, 1.985435f, +0.038358f, 0.558898f, 0.000629f, 0.308390f, 0.031663f, 0.418413f, 0.006358f, 0.450937f, 0.024539f, 0.485872f, 0.000360f, 0.221385f, 0.019969f, 0.202629f, 0.000871f, 0.175783f, +0.132070f, 1.311691f, 0.000707f, 0.785548f, 0.166507f, 1.499819f, 0.010912f, 1.754386f, 0.139170f, 1.878291f, 0.000666f, 0.928888f, 0.206692f, 1.429620f, 0.002942f, 1.346075f, +0.027155f, 0.320029f, 0.000032f, 0.159720f, 0.017044f, 0.182177f, 0.000243f, 0.177586f, 0.004136f, 0.066233f, 0.000004f, 0.027296f, 0.021102f, 0.173199f, 0.000065f, 0.135900f, +0.065892f, 0.554507f, 0.000425f, 0.399321f, 0.050255f, 0.383558f, 0.003971f, 0.539499f, 0.088094f, 1.007417f, 0.000508f, 0.599078f, 0.076874f, 0.450526f, 0.001319f, 0.510084f, +0.020508f, 0.254746f, 0.000740f, 0.158534f, 0.015222f, 0.171492f, 0.006729f, 0.208451f, 0.017909f, 0.302297f, 0.000578f, 0.155349f, 0.015574f, 0.134730f, 0.001495f, 0.131822f, +0.045781f, 0.387631f, 0.000539f, 0.261823f, 0.051902f, 0.398557f, 0.007488f, 0.525805f, 0.065852f, 0.757682f, 0.000694f, 0.422605f, 0.104519f, 0.616304f, 0.003275f, 0.654472f, +0.092891f, 0.814601f, 0.000071f, 0.300552f, 0.065019f, 0.517123f, 0.000607f, 0.372661f, 0.009704f, 0.115640f, 0.000007f, 0.035233f, 0.077920f, 0.475874f, 0.000158f, 0.276041f, +0.328114f, 2.054600f, 0.001384f, 1.093826f, 0.279071f, 1.584875f, 0.014419f, 1.648013f, 0.300897f, 2.560401f, 0.001135f, 1.125610f, 0.413202f, 1.801907f, 0.004637f, 1.508206f, +0.071443f, 0.660351f, 0.001686f, 0.303806f, 0.059138f, 0.495742f, 0.017096f, 0.445473f, 0.042794f, 0.537501f, 0.000903f, 0.204202f, 0.058566f, 0.376985f, 0.003677f, 0.272679f, +0.315024f, 1.984742f, 0.002427f, 0.991059f, 0.398274f, 2.275726f, 0.037573f, 2.219526f, 0.310815f, 2.661034f, 0.002141f, 1.097248f, 0.776325f, 3.406219f, 0.015908f, 2.674086f, +0.028455f, 0.398803f, 0.000013f, 0.293874f, 0.019223f, 0.244343f, 0.000108f, 0.351680f, 0.003615f, 0.068847f, 0.000001f, 0.041894f, 0.023105f, 0.225512f, 0.000028f, 0.261263f, +0.027399f, 0.274197f, 0.000070f, 0.291549f, 0.022491f, 0.204138f, 0.000701f, 0.423953f, 0.030555f, 0.415535f, 0.000070f, 0.364851f, 0.033399f, 0.232772f, 0.000226f, 0.389123f, +0.000858f, 0.012681f, 0.000012f, 0.011652f, 0.000686f, 0.009188f, 0.000120f, 0.016490f, 0.000625f, 0.012552f, 0.000008f, 0.009524f, 0.000681f, 0.007007f, 0.000026f, 0.010123f, +0.041739f, 0.420277f, 0.000194f, 0.419139f, 0.050930f, 0.465098f, 0.002899f, 0.905967f, 0.050080f, 0.685245f, 0.000208f, 0.564323f, 0.099565f, 0.698180f, 0.001231f, 1.094706f, +0.034685f, 0.613180f, 0.000109f, 0.395783f, 0.024695f, 0.395940f, 0.000948f, 0.499163f, 0.004871f, 0.117025f, 0.000014f, 0.062374f, 0.020287f, 0.249757f, 0.000169f, 0.253451f, +0.116984f, 1.476710f, 0.002029f, 1.375339f, 0.101206f, 1.158659f, 0.021496f, 2.107729f, 0.144226f, 2.474015f, 0.002237f, 1.902724f, 0.102718f, 0.902992f, 0.004739f, 1.322226f, +0.031665f, 0.590014f, 0.003072f, 0.474872f, 0.026661f, 0.450542f, 0.031683f, 0.708263f, 0.025499f, 0.645643f, 0.002213f, 0.429107f, 0.018099f, 0.234852f, 0.004672f, 0.297178f, +0.091793f, 1.165835f, 0.002907f, 1.018417f, 0.118043f, 1.359708f, 0.045779f, 2.319953f, 0.121757f, 2.101405f, 0.003448f, 1.515854f, 0.157722f, 1.395047f, 0.013286f, 1.915954f, +0.001142f, 0.017213f, 0.000008f, 0.012531f, 0.000731f, 0.009995f, 0.000062f, 0.014211f, 0.000219f, 0.004484f, 0.000001f, 0.002696f, 0.000974f, 0.010228f, 0.000018f, 0.011706f, +0.001359f, 0.014628f, 0.000052f, 0.015365f, 0.001057f, 0.010321f, 0.000494f, 0.021174f, 0.002287f, 0.033452f, 0.000078f, 0.029016f, 0.001741f, 0.013048f, 0.000177f, 0.021549f, +0.001074f, 0.017060f, 0.000229f, 0.015486f, 0.000813f, 0.011714f, 0.002127f, 0.020769f, 0.001180f, 0.025482f, 0.000226f, 0.019101f, 0.000895f, 0.009906f, 0.000509f, 0.014137f, +0.002018f, 0.021855f, 0.000141f, 0.021532f, 0.002334f, 0.022921f, 0.001993f, 0.044107f, 0.003655f, 0.053773f, 0.000228f, 0.043748f, 0.005059f, 0.038150f, 0.000938f, 0.059093f, +0.107576f, 1.206389f, 0.000486f, 0.649247f, 0.076804f, 0.781154f, 0.004246f, 0.821115f, 0.014146f, 0.215573f, 0.000057f, 0.095802f, 0.099073f, 0.773743f, 0.001190f, 0.654677f, +0.186363f, 1.492322f, 0.004653f, 1.158860f, 0.161678f, 1.174171f, 0.049435f, 1.780921f, 0.215127f, 2.340911f, 0.004803f, 1.501109f, 0.257668f, 1.436913f, 0.017112f, 1.754310f, +0.103012f, 1.217588f, 0.014389f, 0.817088f, 0.086974f, 0.932356f, 0.148793f, 1.222067f, 0.077669f, 1.247516f, 0.009703f, 0.691311f, 0.092711f, 0.763154f, 0.034450f, 0.805170f, +0.382423f, 3.081097f, 0.017433f, 2.244130f, 0.493156f, 3.603483f, 0.275329f, 5.126371f, 0.474946f, 5.199878f, 0.019364f, 3.127483f, 1.034683f, 5.805460f, 0.125471f, 6.647936f, +0.091809f, 1.667222f, 0.000007f, 0.753258f, 0.045661f, 0.752025f, 0.000045f, 0.663633f, 0.008663f, 0.213769f, 0.000001f, 0.079754f, 0.049128f, 0.621309f, 0.000011f, 0.441333f, +0.093087f, 1.207059f, 0.000042f, 0.786910f, 0.056256f, 0.661587f, 0.000310f, 0.842419f, 0.077103f, 1.358615f, 0.000031f, 0.731395f, 0.074782f, 0.675307f, 0.000089f, 0.692158f, +0.002507f, 0.047979f, 0.000006f, 0.027030f, 0.001474f, 0.025593f, 0.000045f, 0.028162f, 0.001356f, 0.035273f, 0.000003f, 0.016410f, 0.001311f, 0.017473f, 0.000009f, 0.015476f, +0.117702f, 1.535608f, 0.000097f, 0.938968f, 0.105733f, 1.251085f, 0.001064f, 1.494178f, 0.104889f, 1.859575f, 0.000077f, 0.938952f, 0.185034f, 1.681189f, 0.000404f, 1.616199f, +0.197224f, 4.517593f, 0.000109f, 1.787820f, 0.103376f, 2.147561f, 0.000702f, 1.659996f, 0.020572f, 0.640356f, 0.000010f, 0.209265f, 0.076020f, 1.212668f, 0.000112f, 0.754512f, +0.700434f, 11.456320f, 0.002146f, 6.541953f, 0.446116f, 6.617633f, 0.016743f, 7.380911f, 0.641372f, 14.255270f, 0.001758f, 6.721974f, 0.405315f, 4.616768f, 0.003304f, 4.144842f, +0.162955f, 3.934202f, 0.002794f, 1.941418f, 0.101009f, 2.211705f, 0.021211f, 2.131741f, 0.097462f, 3.197499f, 0.001495f, 1.302962f, 0.061381f, 1.032033f, 0.002800f, 0.800688f, +0.456174f, 7.506995f, 0.002552f, 4.020712f, 0.431876f, 6.445729f, 0.029596f, 6.743009f, 0.449406f, 10.049910f, 0.002249f, 4.444858f, 0.516557f, 5.920012f, 0.007689f, 4.985019f, +0.046019f, 0.898640f, 0.000056f, 0.401098f, 0.021690f, 0.384140f, 0.000324f, 0.334887f, 0.006552f, 0.173875f, 0.000007f, 0.064086f, 0.025875f, 0.351891f, 0.000084f, 0.246933f, +0.057670f, 0.804131f, 0.000389f, 0.517890f, 0.033029f, 0.417685f, 0.002729f, 0.525417f, 0.072082f, 1.365822f, 0.000435f, 0.726379f, 0.048681f, 0.472723f, 0.000874f, 0.478657f, +0.039163f, 0.806050f, 0.001478f, 0.448613f, 0.021829f, 0.407471f, 0.010091f, 0.442948f, 0.031972f, 0.894237f, 0.001079f, 0.410981f, 0.021519f, 0.308451f, 0.002161f, 0.269900f, +0.071080f, 0.997203f, 0.000876f, 0.602377f, 0.060512f, 0.769935f, 0.009129f, 0.908414f, 0.095585f, 1.822286f, 0.001053f, 0.908992f, 0.117414f, 1.147168f, 0.003847f, 1.089480f, +0.370930f, 5.389782f, 0.000296f, 1.778451f, 0.194967f, 2.569320f, 0.001905f, 1.655899f, 0.036227f, 0.715321f, 0.000026f, 0.194908f, 0.225132f, 2.278166f, 0.000478f, 1.181853f, +0.676656f, 7.020649f, 0.002985f, 3.342672f, 0.432172f, 4.066713f, 0.023350f, 3.781855f, 0.580131f, 8.179425f, 0.002289f, 3.215868f, 0.616556f, 4.455022f, 0.007235f, 3.334830f, +0.321470f, 4.923340f, 0.007935f, 2.025705f, 0.199821f, 2.775485f, 0.060406f, 2.230490f, 0.180020f, 3.746526f, 0.003974f, 1.272929f, 0.190672f, 2.033650f, 0.012520f, 1.315528f, +1.152476f, 12.030940f, 0.009283f, 5.372671f, 1.094130f, 10.358910f, 0.107939f, 9.035447f, 1.063054f, 15.080320f, 0.007658f, 5.561096f, 2.054942f, 14.939470f, 0.044033f, 10.488990f, +0.030159f, 0.577153f, 0.000004f, 0.396995f, 0.019771f, 0.343147f, 0.000034f, 0.461020f, 0.002910f, 0.075670f, 0.000000f, 0.042981f, 0.022744f, 0.303121f, 0.000008f, 0.327807f, +0.033123f, 0.452622f, 0.000025f, 0.449237f, 0.026385f, 0.326998f, 0.000249f, 0.633913f, 0.028054f, 0.520937f, 0.000019f, 0.426957f, 0.037501f, 0.356878f, 0.000077f, 0.556887f, +0.001045f, 0.021078f, 0.000005f, 0.018079f, 0.000810f, 0.014820f, 0.000043f, 0.024828f, 0.000578f, 0.015846f, 0.000002f, 0.011223f, 0.000770f, 0.010818f, 0.000009f, 0.014588f, +0.051142f, 0.703153f, 0.000072f, 0.654582f, 0.060557f, 0.755104f, 0.001043f, 1.372986f, 0.046602f, 0.870692f, 0.000059f, 0.669327f, 0.113308f, 1.084918f, 0.000424f, 1.587884f, +0.032179f, 0.776766f, 0.000031f, 0.468005f, 0.022232f, 0.486720f, 0.000258f, 0.572775f, 0.003432f, 0.112586f, 0.000003f, 0.056015f, 0.017480f, 0.293857f, 0.000044f, 0.278358f, +0.123791f, 2.133721f, 0.000649f, 1.854999f, 0.103925f, 1.624598f, 0.006675f, 2.758651f, 0.115908f, 2.714873f, 0.000544f, 1.949013f, 0.100955f, 1.211830f, 0.001408f, 1.656362f, +0.033742f, 0.858468f, 0.000990f, 0.644956f, 0.027568f, 0.636129f, 0.009908f, 0.933461f, 0.020635f, 0.713443f, 0.000542f, 0.442613f, 0.017912f, 0.317375f, 0.001398f, 0.374874f, +0.098450f, 1.707343f, 0.000943f, 1.392199f, 0.122855f, 1.932312f, 0.014409f, 3.077532f, 0.099175f, 2.337213f, 0.000849f, 1.573757f, 0.157113f, 1.897529f, 0.004002f, 2.432631f, +0.017999f, 0.370395f, 0.000038f, 0.251694f, 0.011182f, 0.208698f, 0.000286f, 0.276995f, 0.002621f, 0.073282f, 0.000005f, 0.041121f, 0.014263f, 0.204408f, 0.000079f, 0.218380f, +0.024432f, 0.359017f, 0.000282f, 0.352022f, 0.018444f, 0.245804f, 0.002608f, 0.470747f, 0.031227f, 0.623540f, 0.000322f, 0.504868f, 0.029066f, 0.297445f, 0.000893f, 0.458531f, +0.019439f, 0.421624f, 0.001256f, 0.357256f, 0.014281f, 0.280938f, 0.011299f, 0.464954f, 0.016227f, 0.478297f, 0.000938f, 0.334665f, 0.015053f, 0.227384f, 0.002587f, 0.302916f, +0.036773f, 0.543669f, 0.000775f, 0.499992f, 0.041264f, 0.553294f, 0.010654f, 0.993869f, 0.050565f, 1.015895f, 0.000953f, 0.771501f, 0.085608f, 0.881433f, 0.004801f, 1.274457f, +0.116597f, 1.785404f, 0.000159f, 0.896914f, 0.080780f, 1.121848f, 0.001351f, 1.100761f, 0.011644f, 0.242297f, 0.000014f, 0.100513f, 0.099734f, 1.063560f, 0.000362f, 0.840009f, +0.230395f, 2.519139f, 0.001739f, 1.826048f, 0.193960f, 1.923397f, 0.017935f, 2.723165f, 0.201982f, 3.001092f, 0.001364f, 1.796381f, 0.295861f, 2.252869f, 0.005942f, 2.567459f, +0.128239f, 2.069710f, 0.005417f, 1.296491f, 0.105068f, 1.537939f, 0.054358f, 1.881673f, 0.073431f, 1.610497f, 0.002774f, 0.833066f, 0.107196f, 1.204861f, 0.012046f, 1.186600f, +0.479179f, 5.271525f, 0.006606f, 3.584023f, 0.599634f, 5.982758f, 0.101241f, 7.944760f, 0.451964f, 6.756613f, 0.005572f, 3.793347f, 1.204141f, 9.225362f, 0.044159f, 9.861100f, +0.133964f, 1.468220f, 0.000010f, 0.741731f, 0.067560f, 0.671536f, 0.000064f, 0.662628f, 0.011174f, 0.166417f, 0.000001f, 0.069424f, 0.071220f, 0.543591f, 0.000015f, 0.431753f, +0.135138f, 1.057575f, 0.000058f, 0.770924f, 0.082813f, 0.587772f, 0.000436f, 0.836863f, 0.098950f, 1.052286f, 0.000038f, 0.633423f, 0.107857f, 0.587828f, 0.000123f, 0.673688f, +0.002672f, 0.030870f, 0.000006f, 0.019446f, 0.001594f, 0.016697f, 0.000047f, 0.020544f, 0.001278f, 0.020062f, 0.000003f, 0.010436f, 0.001388f, 0.011169f, 0.000009f, 0.011062f, +0.151689f, 1.194385f, 0.000119f, 0.816619f, 0.138173f, 0.986711f, 0.001329f, 1.317680f, 0.119496f, 1.278594f, 0.000084f, 0.721883f, 0.236913f, 1.299114f, 0.000495f, 1.396464f, +0.249939f, 3.455213f, 0.000132f, 1.528959f, 0.132842f, 1.665530f, 0.000862f, 1.439523f, 0.023047f, 0.432956f, 0.000011f, 0.158206f, 0.095712f, 0.921460f, 0.000135f, 0.641069f, +0.883134f, 8.717606f, 0.002588f, 5.566268f, 0.570357f, 5.106158f, 0.020470f, 6.368044f, 0.714866f, 9.589207f, 0.001874f, 5.056018f, 0.507713f, 3.490254f, 0.003958f, 3.503736f, +0.150880f, 2.198430f, 0.002474f, 1.213052f, 0.094834f, 1.253206f, 0.019043f, 1.350623f, 0.079772f, 1.579507f, 0.001170f, 0.719693f, 0.056463f, 0.572949f, 0.002463f, 0.497039f, +0.510588f, 5.071072f, 0.002732f, 3.036974f, 0.490161f, 4.415146f, 0.032121f, 5.164535f, 0.444666f, 6.001376f, 0.002128f, 2.967913f, 0.574415f, 3.973041f, 0.008176f, 3.740862f, +0.090098f, 1.061835f, 0.000105f, 0.529939f, 0.043060f, 0.460256f, 0.000615f, 0.448656f, 0.011340f, 0.181620f, 0.000012f, 0.074850f, 0.050331f, 0.413091f, 0.000156f, 0.324132f, +0.112334f, 0.945328f, 0.000725f, 0.680765f, 0.065237f, 0.497902f, 0.005154f, 0.700332f, 0.124121f, 1.419400f, 0.000716f, 0.844070f, 0.094208f, 0.552115f, 0.001617f, 0.625103f, +0.056019f, 0.695859f, 0.002022f, 0.433048f, 0.031662f, 0.356694f, 0.013996f, 0.433566f, 0.040429f, 0.682444f, 0.001305f, 0.350704f, 0.030582f, 0.264553f, 0.002936f, 0.258842f, +0.122911f, 1.040689f, 0.001448f, 0.702927f, 0.106102f, 0.814762f, 0.015307f, 1.074892f, 0.146113f, 1.681159f, 0.001539f, 0.937685f, 0.201712f, 1.189409f, 0.006321f, 1.263071f, +0.522196f, 4.579373f, 0.000398f, 1.689589f, 0.278319f, 2.213565f, 0.002600f, 1.595190f, 0.045085f, 0.537268f, 0.000031f, 0.163691f, 0.314881f, 1.923034f, 0.000639f, 1.115500f, +0.947752f, 5.934670f, 0.003998f, 3.159494f, 0.613794f, 3.485798f, 0.031712f, 3.624666f, 0.718303f, 6.112195f, 0.002710f, 2.687059f, 0.857957f, 3.741415f, 0.009628f, 3.131585f, +0.330651f, 3.056208f, 0.007804f, 1.406060f, 0.208406f, 1.747034f, 0.060246f, 1.569882f, 0.163684f, 2.055923f, 0.003455f, 0.781064f, 0.194843f, 1.254197f, 0.012234f, 0.907182f, +1.432978f, 9.028179f, 0.011038f, 4.508120f, 1.379482f, 7.882320f, 0.130140f, 7.687661f, 1.168472f, 10.003830f, 0.008050f, 4.124970f, 2.538482f, 11.137890f, 0.052016f, 8.743909f, +0.039881f, 0.558942f, 0.000018f, 0.411878f, 0.030028f, 0.381682f, 0.000169f, 0.549350f, 0.006244f, 0.118916f, 0.000003f, 0.072361f, 0.037192f, 0.363015f, 0.000046f, 0.420566f, +0.030630f, 0.306531f, 0.000078f, 0.325929f, 0.028023f, 0.254349f, 0.000874f, 0.528229f, 0.042097f, 0.572488f, 0.000096f, 0.502659f, 0.042883f, 0.298876f, 0.000290f, 0.499628f, +0.000921f, 0.013603f, 0.000013f, 0.012499f, 0.000820f, 0.010985f, 0.000143f, 0.019715f, 0.000827f, 0.016594f, 0.000011f, 0.012591f, 0.000839f, 0.008634f, 0.000032f, 0.012472f, +0.047218f, 0.475439f, 0.000219f, 0.474152f, 0.064214f, 0.586405f, 0.003655f, 1.142260f, 0.069819f, 0.955327f, 0.000290f, 0.786744f, 0.129364f, 0.907139f, 0.001600f, 1.422341f, +0.048359f, 0.854909f, 0.000152f, 0.551809f, 0.038374f, 0.615254f, 0.001474f, 0.775654f, 0.008370f, 0.201075f, 0.000023f, 0.107173f, 0.032485f, 0.399942f, 0.000271f, 0.405857f, +0.130095f, 1.642218f, 0.002256f, 1.529485f, 0.125440f, 1.436100f, 0.026643f, 2.612426f, 0.197663f, 3.390666f, 0.003066f, 2.607705f, 0.131198f, 1.153365f, 0.006053f, 1.688841f, +0.033790f, 0.629614f, 0.003279f, 0.506744f, 0.031709f, 0.535847f, 0.037682f, 0.842365f, 0.033534f, 0.849087f, 0.002910f, 0.564320f, 0.022182f, 0.287842f, 0.005726f, 0.364230f, +0.103298f, 1.311958f, 0.003271f, 1.146064f, 0.148052f, 1.705384f, 0.057418f, 2.909750f, 0.168858f, 2.914337f, 0.004782f, 2.102265f, 0.203855f, 1.803098f, 0.017172f, 2.476370f, +0.001333f, 0.020096f, 0.000009f, 0.014629f, 0.000951f, 0.013005f, 0.000080f, 0.018491f, 0.000315f, 0.006452f, 0.000002f, 0.003878f, 0.001307f, 0.013714f, 0.000024f, 0.015696f, +0.001266f, 0.013621f, 0.000048f, 0.014308f, 0.001097f, 0.010711f, 0.000513f, 0.021976f, 0.002625f, 0.038389f, 0.000090f, 0.033299f, 0.001862f, 0.013955f, 0.000189f, 0.023047f, +0.000960f, 0.015243f, 0.000205f, 0.013837f, 0.000810f, 0.011666f, 0.002118f, 0.020683f, 0.001300f, 0.028061f, 0.000248f, 0.021034f, 0.000919f, 0.010166f, 0.000522f, 0.014508f, +0.001902f, 0.020594f, 0.000133f, 0.020290f, 0.002451f, 0.024072f, 0.002093f, 0.046322f, 0.004244f, 0.062445f, 0.000265f, 0.050803f, 0.005476f, 0.041288f, 0.001015f, 0.063954f, +0.068670f, 0.770088f, 0.000310f, 0.414441f, 0.054643f, 0.555755f, 0.003021f, 0.584186f, 0.011128f, 0.169588f, 0.000045f, 0.075366f, 0.072637f, 0.567280f, 0.000872f, 0.479985f, +0.094889f, 0.759836f, 0.002369f, 0.590049f, 0.091749f, 0.666319f, 0.028053f, 1.010637f, 0.134989f, 1.468889f, 0.003014f, 0.941925f, 0.150683f, 0.840302f, 0.010007f, 1.025914f, +0.050329f, 0.594887f, 0.007030f, 0.399211f, 0.047361f, 0.507703f, 0.081023f, 0.665461f, 0.046766f, 0.751150f, 0.005842f, 0.416250f, 0.052025f, 0.428246f, 0.019332f, 0.451824f, +0.197038f, 1.587486f, 0.008982f, 1.156252f, 0.283193f, 2.069286f, 0.158106f, 2.943799f, 0.301576f, 3.301755f, 0.012295f, 1.985851f, 0.612293f, 3.435490f, 0.074250f, 3.934041f, +0.115556f, 2.098468f, 0.000009f, 0.948097f, 0.064054f, 1.054957f, 0.000064f, 0.930959f, 0.013437f, 0.331590f, 0.000001f, 0.123712f, 0.071021f, 0.898182f, 0.000015f, 0.638003f, +0.093455f, 1.211829f, 0.000042f, 0.790019f, 0.062947f, 0.740275f, 0.000347f, 0.942615f, 0.095396f, 1.680956f, 0.000038f, 0.904923f, 0.086229f, 0.778685f, 0.000103f, 0.798115f, +0.002415f, 0.046221f, 0.000006f, 0.026040f, 0.001583f, 0.027479f, 0.000049f, 0.030238f, 0.001610f, 0.041877f, 0.000004f, 0.019482f, 0.001450f, 0.019333f, 0.000010f, 0.017124f, +0.119576f, 1.560057f, 0.000098f, 0.953919f, 0.119720f, 1.416579f, 0.001204f, 1.691828f, 0.131322f, 2.328204f, 0.000096f, 1.175576f, 0.215903f, 1.961663f, 0.000472f, 1.885830f, +0.246940f, 5.656400f, 0.000137f, 2.238498f, 0.144260f, 2.996899f, 0.000979f, 2.316507f, 0.031744f, 0.988101f, 0.000016f, 0.322907f, 0.109322f, 1.743903f, 0.000161f, 1.085042f, +0.699527f, 11.441470f, 0.002144f, 6.533476f, 0.496567f, 7.366025f, 0.018637f, 8.215623f, 0.789395f, 17.545240f, 0.002163f, 8.273338f, 0.464918f, 5.295689f, 0.003790f, 4.754363f, +0.156164f, 3.770251f, 0.002678f, 1.860513f, 0.107887f, 2.362296f, 0.022655f, 2.276888f, 0.115105f, 3.776340f, 0.001765f, 1.538837f, 0.067561f, 1.135938f, 0.003082f, 0.881301f, +0.461014f, 7.586657f, 0.002580f, 4.063378f, 0.486448f, 7.260223f, 0.033336f, 7.595067f, 0.559719f, 12.516800f, 0.002801f, 5.535914f, 0.599584f, 6.871545f, 0.008925f, 5.786269f, +0.048247f, 0.942153f, 0.000059f, 0.420519f, 0.025345f, 0.448868f, 0.000379f, 0.391316f, 0.008466f, 0.224657f, 0.000009f, 0.082803f, 0.031158f, 0.423732f, 0.000101f, 0.297347f, +0.048227f, 0.672460f, 0.000325f, 0.433089f, 0.030784f, 0.389298f, 0.002543f, 0.489708f, 0.074287f, 1.407605f, 0.000448f, 0.748601f, 0.046757f, 0.454040f, 0.000839f, 0.459740f, +0.031426f, 0.646812f, 0.001186f, 0.359988f, 0.019523f, 0.364424f, 0.009025f, 0.396152f, 0.031618f, 0.884333f, 0.001067f, 0.406430f, 0.019833f, 0.284282f, 0.001991f, 0.248752f, +0.060149f, 0.843861f, 0.000741f, 0.509748f, 0.057071f, 0.726164f, 0.008610f, 0.856771f, 0.099684f, 1.900425f, 0.001098f, 0.947970f, 0.114118f, 1.114966f, 0.003739f, 1.058897f, +0.212641f, 3.089767f, 0.000170f, 1.019522f, 0.124569f, 1.641596f, 0.001217f, 1.057991f, 0.025594f, 0.505362f, 0.000018f, 0.137699f, 0.148231f, 1.499987f, 0.000315f, 0.778154f, +0.309405f, 3.210227f, 0.001365f, 1.528453f, 0.220247f, 2.072505f, 0.011900f, 1.927334f, 0.326913f, 4.609229f, 0.001290f, 1.812190f, 0.323801f, 2.339676f, 0.003800f, 1.751377f, +0.141051f, 2.160205f, 0.003481f, 0.888815f, 0.097717f, 1.357274f, 0.029540f, 1.090759f, 0.097343f, 2.025867f, 0.002149f, 0.688314f, 0.096088f, 1.024846f, 0.006309f, 0.662953f, +0.533258f, 5.566796f, 0.004295f, 2.485971f, 0.564246f, 5.342117f, 0.055665f, 4.659605f, 0.606189f, 8.599308f, 0.004367f, 3.171125f, 1.092076f, 7.939419f, 0.023401f, 5.574257f, +0.000622f, 0.011898f, 0.000000f, 0.008184f, 0.000454f, 0.007884f, 0.000001f, 0.010593f, 0.000074f, 0.001922f, 0.000000f, 0.001092f, 0.000539f, 0.007177f, 0.000000f, 0.007762f, +0.000545f, 0.007443f, 0.000000f, 0.007387f, 0.000484f, 0.005993f, 0.000005f, 0.011618f, 0.000569f, 0.010557f, 0.000000f, 0.008652f, 0.000708f, 0.006740f, 0.000001f, 0.010517f, +0.000016f, 0.000333f, 0.000000f, 0.000285f, 0.000014f, 0.000261f, 0.000001f, 0.000437f, 0.000011f, 0.000308f, 0.000000f, 0.000218f, 0.000014f, 0.000196f, 0.000000f, 0.000264f, +0.000851f, 0.011700f, 0.000001f, 0.010892f, 0.001123f, 0.014004f, 0.000019f, 0.025463f, 0.000956f, 0.017855f, 0.000001f, 0.013726f, 0.002165f, 0.020734f, 0.000008f, 0.030347f, +0.000660f, 0.015930f, 0.000001f, 0.009598f, 0.000508f, 0.011125f, 0.000006f, 0.013092f, 0.000087f, 0.002845f, 0.000000f, 0.001416f, 0.000412f, 0.006922f, 0.000001f, 0.006556f, +0.002025f, 0.034903f, 0.000011f, 0.030343f, 0.001895f, 0.029618f, 0.000122f, 0.050293f, 0.002337f, 0.054729f, 0.000011f, 0.039290f, 0.001897f, 0.022767f, 0.000026f, 0.031119f, +0.000530f, 0.013475f, 0.000016f, 0.010123f, 0.000482f, 0.011128f, 0.000173f, 0.016330f, 0.000399f, 0.013801f, 0.000010f, 0.008562f, 0.000323f, 0.005722f, 0.000025f, 0.006758f, +0.001630f, 0.028261f, 0.000016f, 0.023045f, 0.002266f, 0.035648f, 0.000266f, 0.056776f, 0.002023f, 0.047678f, 0.000017f, 0.032104f, 0.002987f, 0.036075f, 0.000076f, 0.046248f, +0.000309f, 0.006360f, 0.000001f, 0.004322f, 0.000214f, 0.003994f, 0.000005f, 0.005301f, 0.000055f, 0.001551f, 0.000000f, 0.000870f, 0.000281f, 0.004031f, 0.000002f, 0.004307f, +0.000335f, 0.004917f, 0.000004f, 0.004822f, 0.000282f, 0.003752f, 0.000040f, 0.007186f, 0.000527f, 0.010525f, 0.000005f, 0.008522f, 0.000457f, 0.004679f, 0.000014f, 0.007213f, +0.000255f, 0.005541f, 0.000017f, 0.004695f, 0.000209f, 0.004115f, 0.000166f, 0.006811f, 0.000263f, 0.007747f, 0.000015f, 0.005421f, 0.000227f, 0.003432f, 0.000039f, 0.004573f, +0.000510f, 0.007535f, 0.000011f, 0.006930f, 0.000637f, 0.008547f, 0.000165f, 0.015353f, 0.000864f, 0.017353f, 0.000016f, 0.013178f, 0.001363f, 0.014032f, 0.000076f, 0.020288f, +0.001095f, 0.016764f, 0.000001f, 0.008422f, 0.000845f, 0.011740f, 0.000014f, 0.011519f, 0.000135f, 0.002804f, 0.000000f, 0.001163f, 0.001076f, 0.011470f, 0.000004f, 0.009059f, +0.001726f, 0.018867f, 0.000013f, 0.013676f, 0.001619f, 0.016055f, 0.000150f, 0.022731f, 0.001864f, 0.027699f, 0.000013f, 0.016580f, 0.002545f, 0.019379f, 0.000051f, 0.022085f, +0.000922f, 0.014874f, 0.000039f, 0.009317f, 0.000842f, 0.012318f, 0.000435f, 0.015072f, 0.000650f, 0.014264f, 0.000025f, 0.007378f, 0.000885f, 0.009945f, 0.000099f, 0.009794f, +0.003632f, 0.039951f, 0.000050f, 0.027162f, 0.005065f, 0.050534f, 0.000855f, 0.067107f, 0.004221f, 0.063105f, 0.000052f, 0.035429f, 0.010481f, 0.080301f, 0.000384f, 0.085835f, +0.224501f, 2.460486f, 0.000017f, 1.243014f, 0.126187f, 1.254275f, 0.000120f, 1.237636f, 0.023077f, 0.343696f, 0.000002f, 0.143380f, 0.137081f, 1.046284f, 0.000028f, 0.831021f, +0.180639f, 1.413659f, 0.000078f, 1.030494f, 0.123375f, 0.875661f, 0.000650f, 1.246756f, 0.163003f, 1.733463f, 0.000063f, 1.043457f, 0.165589f, 0.902468f, 0.000189f, 1.034284f, +0.003428f, 0.039596f, 0.000008f, 0.024943f, 0.002278f, 0.023870f, 0.000067f, 0.029370f, 0.002020f, 0.031713f, 0.000004f, 0.016497f, 0.002045f, 0.016454f, 0.000013f, 0.016296f, +0.205180f, 1.615568f, 0.000161f, 1.104588f, 0.208304f, 1.487527f, 0.002004f, 1.986482f, 0.199197f, 2.131379f, 0.000140f, 1.203358f, 0.368059f, 2.018253f, 0.000769f, 2.169493f, +0.416665f, 5.760081f, 0.000221f, 2.548882f, 0.246821f, 3.094567f, 0.001602f, 2.674644f, 0.047350f, 0.889498f, 0.000022f, 0.325031f, 0.183260f, 1.764321f, 0.000258f, 1.227457f, +1.174314f, 11.591910f, 0.003441f, 7.401534f, 0.845274f, 7.567380f, 0.030337f, 9.437507f, 1.171465f, 15.714020f, 0.003070f, 8.285397f, 0.775396f, 5.330430f, 0.006044f, 5.351020f, +0.192516f, 2.805091f, 0.003156f, 1.547796f, 0.134863f, 1.782175f, 0.027082f, 1.920712f, 0.125440f, 2.483721f, 0.001839f, 1.131693f, 0.082746f, 0.839650f, 0.003609f, 0.728404f, +0.687030f, 6.823463f, 0.003676f, 4.086449f, 0.735085f, 6.621307f, 0.048172f, 7.745151f, 0.737371f, 9.951831f, 0.003529f, 4.921566f, 0.887725f, 6.140102f, 0.012636f, 5.781284f, +0.125768f, 1.482223f, 0.000147f, 0.739746f, 0.066993f, 0.716060f, 0.000957f, 0.698013f, 0.019509f, 0.312440f, 0.000020f, 0.128764f, 0.080693f, 0.662292f, 0.000250f, 0.519668f, +0.125075f, 1.052550f, 0.000807f, 0.757980f, 0.080956f, 0.617872f, 0.006396f, 0.869076f, 0.170315f, 1.947656f, 0.000983f, 1.158207f, 0.120475f, 0.706053f, 0.002067f, 0.799392f, +0.059851f, 0.743461f, 0.002160f, 0.462672f, 0.037702f, 0.424743f, 0.016667f, 0.516281f, 0.053233f, 0.898569f, 0.001718f, 0.461769f, 0.037527f, 0.324636f, 0.003603f, 0.317628f, +0.138483f, 1.172542f, 0.001631f, 0.791987f, 0.133237f, 1.023133f, 0.019221f, 1.349790f, 0.202882f, 2.334338f, 0.002137f, 1.302003f, 0.261028f, 1.539169f, 0.008179f, 1.634493f, +0.398574f, 3.495274f, 0.000304f, 1.289604f, 0.236762f, 1.883047f, 0.002212f, 1.357004f, 0.042408f, 0.505374f, 0.000029f, 0.153974f, 0.276038f, 1.685815f, 0.000560f, 0.977896f, +0.576997f, 3.613065f, 0.002434f, 1.923520f, 0.416481f, 2.365239f, 0.021518f, 2.459466f, 0.538932f, 4.585889f, 0.002033f, 2.016060f, 0.599919f, 2.616150f, 0.006732f, 2.189732f, +0.193164f, 1.785413f, 0.004559f, 0.821409f, 0.135694f, 1.137498f, 0.039226f, 1.022155f, 0.117845f, 1.480164f, 0.002488f, 0.562328f, 0.130734f, 0.841529f, 0.008209f, 0.608692f, +0.882808f, 5.561946f, 0.006800f, 2.777295f, 0.947188f, 5.412206f, 0.089357f, 5.278548f, 0.887140f, 7.595216f, 0.006112f, 3.131803f, 1.796173f, 7.880921f, 0.036805f, 6.186995f, +0.146804f, 2.057506f, 0.000068f, 1.516155f, 0.095602f, 1.215201f, 0.000539f, 1.749023f, 0.019766f, 0.376457f, 0.000008f, 0.229074f, 0.110692f, 1.080406f, 0.000136f, 1.251691f, +0.108744f, 1.088268f, 0.000277f, 1.157135f, 0.086050f, 0.781020f, 0.002683f, 1.622017f, 0.128530f, 1.747937f, 0.000293f, 1.534734f, 0.123095f, 0.857907f, 0.000834f, 1.434154f, +0.004173f, 0.061639f, 0.000059f, 0.056637f, 0.003213f, 0.043052f, 0.000561f, 0.077266f, 0.003221f, 0.064665f, 0.000041f, 0.049065f, 0.003075f, 0.031630f, 0.000116f, 0.045694f, +0.163763f, 1.648948f, 0.000761f, 1.644484f, 0.192625f, 1.759064f, 0.010966f, 3.426487f, 0.208250f, 2.849460f, 0.000866f, 2.346628f, 0.362757f, 2.543751f, 0.004485f, 3.988455f, +0.134323f, 2.374616f, 0.000421f, 1.532717f, 0.092189f, 1.478086f, 0.003540f, 1.863431f, 0.019994f, 0.480319f, 0.000056f, 0.256010f, 0.072954f, 0.898172f, 0.000609f, 0.911456f, +0.348514f, 4.399373f, 0.006044f, 4.097370f, 0.290649f, 3.327489f, 0.061732f, 6.053072f, 0.455391f, 7.811659f, 0.007063f, 6.007817f, 0.284169f, 2.498132f, 0.013109f, 3.657944f, +0.115536f, 2.152773f, 0.011210f, 1.732657f, 0.093773f, 1.584663f, 0.111438f, 2.491128f, 0.098606f, 2.496745f, 0.008557f, 1.659386f, 0.061322f, 0.795731f, 0.015828f, 1.006904f, +0.270335f, 3.433455f, 0.008560f, 2.999301f, 0.335119f, 3.860160f, 0.129966f, 6.586261f, 0.380043f, 6.559177f, 0.010763f, 4.731481f, 0.431342f, 3.815216f, 0.036335f, 5.239808f, +0.005384f, 0.081143f, 0.000037f, 0.059070f, 0.003323f, 0.045417f, 0.000281f, 0.064578f, 0.001094f, 0.022404f, 0.000007f, 0.013468f, 0.004266f, 0.044772f, 0.000078f, 0.051242f, +0.004929f, 0.053046f, 0.000188f, 0.055720f, 0.003696f, 0.036078f, 0.001728f, 0.074020f, 0.008792f, 0.128570f, 0.000300f, 0.111522f, 0.005863f, 0.043940f, 0.000595f, 0.072566f, +0.004770f, 0.075767f, 0.001019f, 0.068777f, 0.003481f, 0.050152f, 0.009107f, 0.088919f, 0.005557f, 0.119948f, 0.001062f, 0.089912f, 0.003693f, 0.040854f, 0.002099f, 0.058305f, +0.007236f, 0.078348f, 0.000504f, 0.077190f, 0.008066f, 0.079207f, 0.006886f, 0.152422f, 0.013886f, 0.204306f, 0.000866f, 0.166218f, 0.016842f, 0.126999f, 0.003123f, 0.196719f, +0.231101f, 2.591637f, 0.001043f, 1.394751f, 0.159052f, 1.617668f, 0.008793f, 1.700422f, 0.032208f, 0.490824f, 0.000130f, 0.218126f, 0.197642f, 1.543547f, 0.002373f, 1.306020f, +0.307991f, 2.466266f, 0.007689f, 1.915174f, 0.257570f, 1.870571f, 0.078754f, 2.837184f, 0.376806f, 4.100223f, 0.008413f, 2.629268f, 0.395433f, 2.205179f, 0.026262f, 2.692276f, +0.208500f, 2.464440f, 0.029124f, 1.653814f, 0.169697f, 1.819137f, 0.290313f, 2.384397f, 0.166613f, 2.676142f, 0.020815f, 1.482985f, 0.174255f, 1.434385f, 0.064751f, 1.513358f, +0.624770f, 5.033631f, 0.028480f, 3.666267f, 0.776651f, 5.674976f, 0.433604f, 8.073310f, 0.822368f, 9.003568f, 0.033528f, 5.415224f, 1.569710f, 8.807420f, 0.190351f, 10.085530f, +0.549140f, 9.972235f, 0.000045f, 4.505501f, 0.263275f, 4.336078f, 0.000262f, 3.826419f, 0.054915f, 1.355157f, 0.000004f, 0.505591f, 0.272876f, 3.450985f, 0.000059f, 2.451326f, +0.428330f, 5.554156f, 0.000193f, 3.620882f, 0.249531f, 2.934553f, 0.001375f, 3.736656f, 0.376014f, 6.625692f, 0.000151f, 3.566864f, 0.319536f, 2.885539f, 0.000382f, 2.957540f, +0.014126f, 0.270385f, 0.000036f, 0.152328f, 0.008009f, 0.139033f, 0.000247f, 0.152989f, 0.008100f, 0.210678f, 0.000018f, 0.098011f, 0.006860f, 0.091440f, 0.000046f, 0.080991f, +0.535391f, 6.985035f, 0.000440f, 4.271095f, 0.463624f, 5.485809f, 0.004664f, 6.551733f, 0.505664f, 8.964940f, 0.000371f, 4.526652f, 0.781583f, 7.101348f, 0.001708f, 6.826827f, +0.885485f, 20.282860f, 0.000491f, 8.026864f, 0.447412f, 9.294653f, 0.003036f, 7.184470f, 0.097893f, 3.047116f, 0.000049f, 0.995783f, 0.316945f, 5.055918f, 0.000467f, 3.145749f, +2.419245f, 39.569210f, 0.007413f, 22.595390f, 1.485339f, 22.033360f, 0.055746f, 24.574680f, 2.347837f, 52.183490f, 0.006435f, 24.606770f, 1.299992f, 14.807660f, 0.010597f, 13.294020f, +0.689321f, 16.642160f, 0.011819f, 8.212438f, 0.411889f, 9.018737f, 0.086493f, 8.692666f, 0.436951f, 14.335370f, 0.006700f, 5.841579f, 0.241116f, 4.053988f, 0.010997f, 3.145229f, +1.557547f, 25.631690f, 0.008715f, 13.728220f, 1.421462f, 21.215280f, 0.097411f, 22.193740f, 1.626279f, 36.367940f, 0.008138f, 16.084760f, 1.637817f, 18.770240f, 0.024379f, 15.805710f, +0.251498f, 4.911180f, 0.000307f, 2.192050f, 0.114268f, 2.023739f, 0.001707f, 1.764266f, 0.037953f, 1.007123f, 0.000041f, 0.371198f, 0.131318f, 1.785845f, 0.000426f, 1.253187f, +0.242458f, 3.380782f, 0.001636f, 2.177346f, 0.133859f, 1.692798f, 0.011060f, 2.129415f, 0.321190f, 6.085970f, 0.001938f, 3.236676f, 0.190057f, 1.845582f, 0.003411f, 1.868750f, +0.201652f, 4.150429f, 0.007611f, 2.309954f, 0.108349f, 2.022524f, 0.050087f, 2.198614f, 0.174482f, 4.880103f, 0.005890f, 2.242841f, 0.102895f, 1.474867f, 0.010331f, 1.290537f, +0.295416f, 4.144506f, 0.003639f, 2.503557f, 0.242434f, 3.084672f, 0.036574f, 3.639474f, 0.421041f, 8.026960f, 0.004638f, 4.004008f, 0.453153f, 4.427436f, 0.014849f, 4.204792f, +0.923837f, 13.423790f, 0.000737f, 4.429409f, 0.468091f, 6.168614f, 0.004573f, 3.975604f, 0.095627f, 1.888209f, 0.000068f, 0.514493f, 0.520688f, 5.268965f, 0.001105f, 2.733402f, +1.296470f, 13.451520f, 0.005719f, 6.404539f, 0.798209f, 7.511095f, 0.043126f, 6.984970f, 1.178055f, 16.609720f, 0.004648f, 6.530371f, 1.096990f, 7.926473f, 0.012873f, 5.933403f, +0.754354f, 11.553000f, 0.018619f, 4.753473f, 0.452004f, 6.278259f, 0.136640f, 5.045457f, 0.447715f, 9.317705f, 0.009883f, 3.165807f, 0.415488f, 4.431460f, 0.027281f, 2.866624f, +2.182854f, 22.787270f, 0.017583f, 10.176140f, 1.997687f, 18.913520f, 0.197078f, 16.497120f, 2.133996f, 30.272540f, 0.015374f, 11.163460f, 3.614335f, 26.276300f, 0.077448f, 18.448560f, +0.130699f, 2.501222f, 0.000018f, 1.720467f, 0.082594f, 1.433532f, 0.000141f, 1.925956f, 0.013365f, 0.347561f, 0.000002f, 0.197417f, 0.091530f, 1.219871f, 0.000034f, 1.319215f, +0.110428f, 1.508993f, 0.000085f, 1.497709f, 0.084796f, 1.050901f, 0.000799f, 2.037261f, 0.099125f, 1.840696f, 0.000068f, 1.508625f, 0.116099f, 1.104861f, 0.000238f, 1.724070f, +0.004267f, 0.086065f, 0.000018f, 0.073819f, 0.003189f, 0.058333f, 0.000168f, 0.097723f, 0.002502f, 0.068572f, 0.000010f, 0.048567f, 0.002920f, 0.041019f, 0.000033f, 0.055314f, +0.168551f, 2.317394f, 0.000237f, 2.157319f, 0.192388f, 2.398958f, 0.003312f, 4.361962f, 0.162781f, 3.041308f, 0.000205f, 2.337942f, 0.346774f, 3.320346f, 0.001297f, 4.859652f, +0.104678f, 2.526819f, 0.000099f, 1.522420f, 0.069716f, 1.526261f, 0.000810f, 1.796114f, 0.011833f, 0.388164f, 0.000010f, 0.193123f, 0.052804f, 0.887679f, 0.000133f, 0.840861f, +0.309788f, 5.339641f, 0.001625f, 4.642139f, 0.250704f, 3.919095f, 0.016103f, 6.654828f, 0.307421f, 7.200611f, 0.001442f, 5.169333f, 0.234604f, 2.816128f, 0.003273f, 3.849159f, +0.103414f, 2.631111f, 0.003035f, 1.976720f, 0.081450f, 1.879428f, 0.029272f, 2.757888f, 0.067031f, 2.317500f, 0.001759f, 1.437755f, 0.050980f, 0.903281f, 0.003979f, 1.066932f, +0.243550f, 4.223709f, 0.002332f, 3.444090f, 0.292976f, 4.608037f, 0.034361f, 7.339075f, 0.260030f, 6.127974f, 0.002227f, 4.126259f, 0.360930f, 4.359108f, 0.009194f, 5.588375f, +0.071270f, 1.466652f, 0.000149f, 0.996633f, 0.042682f, 0.796611f, 0.001091f, 1.057303f, 0.010998f, 0.307543f, 0.000021f, 0.172573f, 0.052445f, 0.751616f, 0.000291f, 0.802993f, +0.074425f, 1.093624f, 0.000859f, 1.072314f, 0.054160f, 0.721783f, 0.007658f, 1.382310f, 0.100815f, 2.013086f, 0.001041f, 1.629954f, 0.082220f, 0.841386f, 0.002525f, 1.297050f, +0.072520f, 1.572963f, 0.004685f, 1.332823f, 0.051361f, 1.010345f, 0.040634f, 1.672125f, 0.064163f, 1.891195f, 0.003707f, 1.323273f, 0.052151f, 0.787752f, 0.008962f, 1.049424f, +0.110733f, 1.637139f, 0.002334f, 1.505616f, 0.119780f, 1.606099f, 0.030926f, 2.884999f, 0.161380f, 3.242243f, 0.003043f, 2.462255f, 0.239386f, 2.464770f, 0.013425f, 3.563791f, +0.210403f, 3.221828f, 0.000287f, 1.618515f, 0.140520f, 1.951486f, 0.002349f, 1.914806f, 0.022270f, 0.463403f, 0.000027f, 0.192235f, 0.167127f, 1.782230f, 0.000607f, 1.407621f, +0.319837f, 3.497103f, 0.002415f, 2.534945f, 0.259558f, 2.573895f, 0.024000f, 3.644146f, 0.297176f, 4.415510f, 0.002007f, 2.643018f, 0.381400f, 2.904211f, 0.007660f, 3.309754f, +0.218030f, 3.518895f, 0.009210f, 2.204279f, 0.172200f, 2.520586f, 0.089090f, 3.083944f, 0.132320f, 2.902032f, 0.004999f, 1.501141f, 0.169243f, 1.902260f, 0.019018f, 1.873429f, +0.657587f, 7.234214f, 0.009065f, 4.918423f, 0.793243f, 7.914473f, 0.133930f, 10.509970f, 0.657361f, 9.827193f, 0.008105f, 5.517254f, 1.534505f, 11.756400f, 0.056274f, 12.566560f, +0.926036f, 10.149180f, 0.000072f, 5.127266f, 0.450189f, 4.474811f, 0.000429f, 4.415446f, 0.081864f, 1.219223f, 0.000006f, 0.508624f, 0.457169f, 3.489379f, 0.000095f, 2.771473f, +0.718636f, 5.623942f, 0.000309f, 4.099601f, 0.424517f, 3.013034f, 0.002236f, 4.289925f, 0.557686f, 5.930744f, 0.000215f, 3.570006f, 0.532618f, 2.902796f, 0.000609f, 3.326785f, +0.017405f, 0.201052f, 0.000042f, 0.126651f, 0.010006f, 0.104830f, 0.000295f, 0.128982f, 0.008822f, 0.138484f, 0.000019f, 0.072038f, 0.008397f, 0.067550f, 0.000054f, 0.066902f, +0.797411f, 6.278744f, 0.000626f, 4.292872f, 0.700191f, 5.000165f, 0.006735f, 6.677352f, 0.665777f, 7.123718f, 0.000468f, 4.021989f, 1.156520f, 6.341790f, 0.002416f, 6.817018f, +1.296869f, 17.928230f, 0.000687f, 7.933385f, 0.664450f, 8.330684f, 0.004312f, 7.200235f, 0.126743f, 2.380960f, 0.000060f, 0.870026f, 0.461175f, 4.439917f, 0.000650f, 3.088898f, +3.525166f, 34.797660f, 0.010330f, 22.218610f, 2.194647f, 19.647740f, 0.078765f, 24.503290f, 3.024286f, 40.567750f, 0.007926f, 21.389810f, 1.881946f, 12.937370f, 0.014670f, 12.987340f, +0.737607f, 10.747470f, 0.012094f, 5.930250f, 0.446913f, 5.905837f, 0.089744f, 6.364923f, 0.413325f, 8.183900f, 0.006061f, 3.728947f, 0.256328f, 2.601031f, 0.011180f, 2.256420f, +2.014756f, 20.010200f, 0.010780f, 11.983750f, 1.864472f, 16.794310f, 0.122184f, 19.644830f, 1.859650f, 25.098500f, 0.008899f, 12.412180f, 2.104812f, 14.558300f, 0.029960f, 13.707530f, +0.569054f, 6.706524f, 0.000664f, 3.347084f, 0.262171f, 2.802241f, 0.003745f, 2.731615f, 0.075913f, 1.215764f, 0.000079f, 0.501046f, 0.295196f, 2.422826f, 0.000916f, 1.901073f, +0.545808f, 4.593178f, 0.003521f, 3.307715f, 0.305555f, 2.332065f, 0.024141f, 3.280200f, 0.639176f, 7.309389f, 0.003688f, 4.346653f, 0.425065f, 2.491129f, 0.007294f, 2.820451f, +0.333357f, 4.140882f, 0.012032f, 2.576960f, 0.181623f, 2.046129f, 0.080289f, 2.487096f, 0.254984f, 4.304116f, 0.008231f, 2.211861f, 0.168992f, 1.461906f, 0.016226f, 1.430348f, +0.590362f, 4.998623f, 0.006954f, 3.376289f, 0.491266f, 3.772472f, 0.070872f, 4.976913f, 0.743814f, 8.558227f, 0.007836f, 4.773447f, 0.899698f, 5.305138f, 0.028192f, 5.633696f, +1.503064f, 13.181060f, 0.001146f, 4.863237f, 0.772240f, 6.141892f, 0.007214f, 4.426110f, 0.137537f, 1.639005f, 0.000094f, 0.499361f, 0.841640f, 5.140050f, 0.001708f, 2.981604f, +2.098597f, 13.141080f, 0.008853f, 6.996037f, 1.310156f, 7.440505f, 0.067691f, 7.736921f, 1.685728f, 14.344230f, 0.006360f, 6.306046f, 1.764153f, 7.693191f, 0.019797f, 6.439244f, +0.896696f, 8.288160f, 0.021165f, 3.813107f, 0.544819f, 4.567116f, 0.157496f, 4.104005f, 0.470465f, 5.909184f, 0.009932f, 2.244954f, 0.490678f, 3.158473f, 0.030809f, 2.284575f, +3.136700f, 19.762120f, 0.024161f, 9.867994f, 2.910818f, 16.632330f, 0.274605f, 16.221580f, 2.710797f, 23.208400f, 0.018675f, 9.569727f, 5.159926f, 22.639780f, 0.105732f, 17.773580f, +0.023662f, 0.331634f, 0.000011f, 0.244378f, 0.020993f, 0.266847f, 0.000118f, 0.384070f, 0.003637f, 0.069274f, 0.000001f, 0.042153f, 0.026728f, 0.260876f, 0.000033f, 0.302235f, +0.034661f, 0.346877f, 0.000088f, 0.368828f, 0.037367f, 0.339155f, 0.001165f, 0.704355f, 0.046771f, 0.636063f, 0.000106f, 0.558480f, 0.058777f, 0.409647f, 0.000398f, 0.684802f, +0.000591f, 0.008730f, 0.000008f, 0.008022f, 0.000620f, 0.008307f, 0.000108f, 0.014909f, 0.000521f, 0.010456f, 0.000007f, 0.007933f, 0.000652f, 0.006711f, 0.000025f, 0.009695f, +0.032625f, 0.328505f, 0.000152f, 0.327616f, 0.052281f, 0.477434f, 0.002976f, 0.929995f, 0.047365f, 0.648085f, 0.000197f, 0.533721f, 0.108263f, 0.759171f, 0.001339f, 1.190336f, +0.025524f, 0.451229f, 0.000080f, 0.291250f, 0.023866f, 0.382648f, 0.000917f, 0.482407f, 0.004337f, 0.104200f, 0.000012f, 0.055539f, 0.020767f, 0.255678f, 0.000173f, 0.259459f, +0.130962f, 1.653165f, 0.002271f, 1.539680f, 0.148796f, 1.703485f, 0.031603f, 3.098829f, 0.195364f, 3.351223f, 0.003030f, 2.577370f, 0.159967f, 1.406275f, 0.007380f, 2.059170f, +0.019291f, 0.359449f, 0.001872f, 0.289302f, 0.021331f, 0.360472f, 0.025349f, 0.566671f, 0.018797f, 0.475935f, 0.001631f, 0.316316f, 0.015339f, 0.199038f, 0.003959f, 0.251859f, +0.063493f, 0.806403f, 0.002010f, 0.704435f, 0.107230f, 1.235158f, 0.041586f, 2.107444f, 0.101903f, 1.758753f, 0.002886f, 1.268681f, 0.151765f, 1.342362f, 0.012784f, 1.843596f, +0.001305f, 0.019666f, 0.000009f, 0.014316f, 0.001097f, 0.014996f, 0.000093f, 0.021323f, 0.000303f, 0.006199f, 0.000002f, 0.003726f, 0.001549f, 0.016255f, 0.000028f, 0.018604f, +0.002362f, 0.025423f, 0.000090f, 0.026705f, 0.002414f, 0.023557f, 0.001129f, 0.048331f, 0.004811f, 0.070349f, 0.000164f, 0.061021f, 0.004210f, 0.031548f, 0.000428f, 0.052101f, +0.001016f, 0.016135f, 0.000217f, 0.014647f, 0.001010f, 0.014550f, 0.002642f, 0.025798f, 0.001351f, 0.029162f, 0.000258f, 0.021860f, 0.001178f, 0.013033f, 0.000669f, 0.018601f, +0.002168f, 0.023469f, 0.000151f, 0.023123f, 0.003292f, 0.032325f, 0.002810f, 0.062204f, 0.004749f, 0.069870f, 0.000296f, 0.056845f, 0.007558f, 0.056991f, 0.001402f, 0.088278f, +0.040133f, 0.450065f, 0.000181f, 0.242213f, 0.037630f, 0.382725f, 0.002080f, 0.402304f, 0.006386f, 0.097311f, 0.000026f, 0.043246f, 0.051417f, 0.401560f, 0.000617f, 0.339766f, +0.105769f, 0.846959f, 0.002641f, 0.657704f, 0.120507f, 0.875171f, 0.036846f, 1.327414f, 0.147732f, 1.607551f, 0.003299f, 1.030842f, 0.203435f, 1.134478f, 0.013511f, 1.385070f, +0.031816f, 0.376057f, 0.004444f, 0.252361f, 0.035278f, 0.378179f, 0.060353f, 0.495691f, 0.029025f, 0.466208f, 0.003626f, 0.258349f, 0.039834f, 0.327893f, 0.014802f, 0.345945f, +0.134103f, 1.080436f, 0.006113f, 0.786941f, 0.227112f, 1.659504f, 0.126797f, 2.360836f, 0.201520f, 2.206313f, 0.008216f, 1.326994f, 0.504739f, 2.832020f, 0.061207f, 3.242996f, +0.104756f, 1.902333f, 0.000009f, 0.859483f, 0.068423f, 1.126906f, 0.000068f, 0.994450f, 0.011960f, 0.295133f, 0.000001f, 0.110110f, 0.077981f, 0.986205f, 0.000017f, 0.700527f, +0.161583f, 2.095241f, 0.000073f, 1.365936f, 0.128244f, 1.508184f, 0.000706f, 1.920417f, 0.161940f, 2.853526f, 0.000065f, 1.536163f, 0.180578f, 1.630694f, 0.000216f, 1.671384f, +0.002368f, 0.045322f, 0.000006f, 0.025533f, 0.001829f, 0.031750f, 0.000056f, 0.034937f, 0.001550f, 0.040317f, 0.000003f, 0.018756f, 0.001723f, 0.022961f, 0.000012f, 0.020338f, +0.126236f, 1.646948f, 0.000104f, 1.007049f, 0.148927f, 1.762172f, 0.001498f, 2.104573f, 0.136116f, 2.413200f, 0.000100f, 1.218493f, 0.276068f, 2.508314f, 0.000603f, 2.411348f, +0.199141f, 4.561515f, 0.000110f, 1.805202f, 0.137083f, 2.847800f, 0.000930f, 2.201258f, 0.025134f, 0.782354f, 0.000012f, 0.255670f, 0.106781f, 1.703372f, 0.000157f, 1.059824f, +1.075924f, 17.597830f, 0.003297f, 10.048970f, 0.899961f, 13.349920f, 0.033776f, 14.889700f, 1.192077f, 26.495340f, 0.003267f, 12.493700f, 0.866108f, 9.865471f, 0.007060f, 8.857022f, +0.136219f, 3.288704f, 0.002336f, 1.622883f, 0.110890f, 2.428048f, 0.023286f, 2.340262f, 0.098579f, 3.234139f, 0.001512f, 1.317893f, 0.071379f, 1.200127f, 0.003256f, 0.931102f, +0.432950f, 7.124826f, 0.002422f, 3.816023f, 0.538305f, 8.034192f, 0.036889f, 8.404732f, 0.516091f, 11.541180f, 0.002583f, 5.104417f, 0.682012f, 7.816214f, 0.010152f, 6.581739f, +0.072139f, 1.408709f, 0.000088f, 0.628761f, 0.044654f, 0.790836f, 0.000667f, 0.689439f, 0.012428f, 0.329802f, 0.000014f, 0.121556f, 0.056427f, 0.767377f, 0.000183f, 0.538494f, +0.137529f, 1.917672f, 0.000928f, 1.235050f, 0.103443f, 1.308154f, 0.008547f, 1.645561f, 0.207995f, 3.941139f, 0.001255f, 2.095999f, 0.161500f, 1.568268f, 0.002898f, 1.587954f, +0.050824f, 1.046077f, 0.001918f, 0.582202f, 0.037204f, 0.694482f, 0.017199f, 0.754946f, 0.050206f, 1.404218f, 0.001695f, 0.645363f, 0.038850f, 0.556869f, 0.003901f, 0.487272f, +0.104734f, 1.469350f, 0.001290f, 0.887585f, 0.117096f, 1.489903f, 0.017665f, 1.757873f, 0.170417f, 3.248915f, 0.001877f, 1.620624f, 0.240673f, 2.351444f, 0.007886f, 2.233196f, +0.189877f, 2.759002f, 0.000151f, 0.910380f, 0.131070f, 1.727273f, 0.001280f, 1.113209f, 0.022439f, 0.443059f, 0.000016f, 0.120723f, 0.160319f, 1.622303f, 0.000340f, 0.841609f, +0.526940f, 5.467265f, 0.002325f, 2.603074f, 0.441989f, 4.159091f, 0.023880f, 3.867762f, 0.546637f, 7.707185f, 0.002157f, 3.030200f, 0.667930f, 4.826235f, 0.007838f, 3.612704f, +0.136235f, 2.086444f, 0.003363f, 0.858466f, 0.111212f, 1.544713f, 0.033619f, 1.241393f, 0.092310f, 1.921126f, 0.002038f, 0.652727f, 0.112409f, 1.198916f, 0.007381f, 0.775555f, +0.554522f, 5.788772f, 0.004467f, 2.585099f, 0.691382f, 6.545804f, 0.068207f, 5.709508f, 0.618903f, 8.779660f, 0.004459f, 3.237633f, 1.375474f, 9.999726f, 0.029473f, 7.020796f, +0.026591f, 0.508872f, 0.000004f, 0.350028f, 0.022893f, 0.397338f, 0.000039f, 0.533825f, 0.003104f, 0.080728f, 0.000000f, 0.045854f, 0.027897f, 0.371792f, 0.000010f, 0.402070f, +0.044428f, 0.607107f, 0.000034f, 0.602567f, 0.046478f, 0.576018f, 0.000438f, 1.116660f, 0.045530f, 0.845463f, 0.000031f, 0.692937f, 0.069974f, 0.665909f, 0.000143f, 1.039112f, +0.000763f, 0.015386f, 0.000003f, 0.013196f, 0.000777f, 0.014207f, 0.000041f, 0.023800f, 0.000511f, 0.013995f, 0.000002f, 0.009912f, 0.000782f, 0.010985f, 0.000009f, 0.014814f, +0.042384f, 0.582738f, 0.000060f, 0.542485f, 0.065909f, 0.821849f, 0.001135f, 1.494347f, 0.046732f, 0.873108f, 0.000059f, 0.671184f, 0.130632f, 1.250795f, 0.000488f, 1.830661f, +0.025107f, 0.606060f, 0.000024f, 0.365154f, 0.022781f, 0.498732f, 0.000265f, 0.586911f, 0.003240f, 0.106290f, 0.000003f, 0.052882f, 0.018973f, 0.318954f, 0.000048f, 0.302131f, +0.146936f, 2.532652f, 0.000771f, 2.201819f, 0.162002f, 2.532478f, 0.010406f, 4.300280f, 0.166468f, 3.899128f, 0.000781f, 2.799192f, 0.166698f, 2.000993f, 0.002326f, 2.735011f, +0.021795f, 0.554518f, 0.000640f, 0.416603f, 0.023386f, 0.539634f, 0.008405f, 0.791863f, 0.016128f, 0.557611f, 0.000423f, 0.345937f, 0.016095f, 0.285187f, 0.001256f, 0.336855f, +0.072202f, 1.252139f, 0.000691f, 1.021018f, 0.118328f, 1.861107f, 0.013878f, 2.964126f, 0.088007f, 2.074008f, 0.000754f, 1.396529f, 0.160292f, 1.935914f, 0.004083f, 2.481842f, +0.021802f, 0.448667f, 0.000046f, 0.304883f, 0.017789f, 0.332002f, 0.000455f, 0.440649f, 0.003841f, 0.107408f, 0.000007f, 0.060270f, 0.024034f, 0.344448f, 0.000133f, 0.367992f, +0.045023f, 0.661587f, 0.000520f, 0.648696f, 0.044637f, 0.594870f, 0.006312f, 1.139255f, 0.069627f, 1.390324f, 0.000719f, 1.125717f, 0.074512f, 0.762507f, 0.002288f, 1.175454f, +0.019494f, 0.422816f, 0.001259f, 0.358266f, 0.018809f, 0.369997f, 0.014881f, 0.612347f, 0.019690f, 0.580368f, 0.001138f, 0.406085f, 0.021000f, 0.317214f, 0.003609f, 0.422584f, +0.041869f, 0.619013f, 0.000883f, 0.569283f, 0.061702f, 0.827339f, 0.015931f, 1.486129f, 0.069662f, 1.399570f, 0.001313f, 1.062875f, 0.135595f, 1.396113f, 0.007604f, 2.018628f, +0.046120f, 0.706222f, 0.000063f, 0.354777f, 0.041964f, 0.582775f, 0.000702f, 0.571821f, 0.005573f, 0.115967f, 0.000007f, 0.048107f, 0.054880f, 0.585238f, 0.000199f, 0.462226f, +0.138640f, 1.515894f, 0.001047f, 1.098826f, 0.153282f, 1.520015f, 0.014173f, 2.152052f, 0.147065f, 2.185125f, 0.000993f, 1.307963f, 0.247669f, 1.885899f, 0.004974f, 2.149245f, +0.041994f, 0.677767f, 0.001774f, 0.424561f, 0.045186f, 0.661412f, 0.023378f, 0.809239f, 0.029096f, 0.638133f, 0.001099f, 0.330088f, 0.048833f, 0.548875f, 0.005488f, 0.540557f, +0.178160f, 1.959960f, 0.002456f, 1.332545f, 0.292792f, 2.921288f, 0.049434f, 3.879303f, 0.203327f, 3.039626f, 0.002507f, 1.706529f, 0.622807f, 4.771557f, 0.022840f, 5.100374f, +0.250596f, 2.746484f, 0.000019f, 1.387497f, 0.165973f, 1.649748f, 0.000158f, 1.627861f, 0.025291f, 0.376673f, 0.000002f, 0.157137f, 0.185333f, 1.414569f, 0.000038f, 1.123535f, +0.384571f, 3.009600f, 0.000165f, 2.193864f, 0.309499f, 2.196689f, 0.001630f, 3.127622f, 0.340716f, 3.623364f, 0.000131f, 2.181081f, 0.426986f, 2.327096f, 0.000489f, 2.666997f, +0.004139f, 0.047807f, 0.000010f, 0.030116f, 0.003241f, 0.033960f, 0.000096f, 0.041784f, 0.002395f, 0.037594f, 0.000005f, 0.019556f, 0.002991f, 0.024062f, 0.000019f, 0.023831f, +0.266714f, 2.100082f, 0.000209f, 1.435857f, 0.319063f, 2.278474f, 0.003069f, 3.042735f, 0.254230f, 2.720225f, 0.000179f, 1.535815f, 0.579490f, 3.177642f, 0.001211f, 3.415762f, +0.413741f, 5.719648f, 0.000219f, 2.530990f, 0.288796f, 3.620838f, 0.001874f, 3.129501f, 0.046163f, 0.867199f, 0.000022f, 0.316883f, 0.220408f, 2.121957f, 0.000311f, 1.476268f, +2.223992f, 21.953500f, 0.006517f, 14.017500f, 1.886318f, 16.887400f, 0.067699f, 21.060790f, 2.178268f, 29.219270f, 0.005709f, 15.406190f, 1.778651f, 12.227270f, 0.013865f, 12.274500f, +0.206772f, 3.012820f, 0.003390f, 1.662418f, 0.170682f, 2.255512f, 0.034274f, 2.430843f, 0.132280f, 2.619161f, 0.001940f, 1.193406f, 0.107645f, 1.092302f, 0.004695f, 0.947582f, +0.794459f, 7.890426f, 0.004251f, 4.725434f, 1.001616f, 9.022103f, 0.065638f, 10.553440f, 0.837173f, 11.298780f, 0.004006f, 5.587686f, 1.243347f, 8.599821f, 0.017698f, 8.097261f, +0.231548f, 2.728884f, 0.000270f, 1.361928f, 0.145334f, 1.553422f, 0.002076f, 1.514271f, 0.035265f, 0.564770f, 0.000037f, 0.232755f, 0.179940f, 1.476860f, 0.000558f, 1.158820f, +0.439187f, 3.695920f, 0.002833f, 2.661567f, 0.334962f, 2.556503f, 0.026465f, 3.595887f, 0.587171f, 6.714677f, 0.003388f, 3.992997f, 0.512382f, 3.002861f, 0.008793f, 3.399833f, +0.119188f, 1.480524f, 0.004302f, 0.921362f, 0.088469f, 0.996672f, 0.039109f, 1.211468f, 0.104081f, 1.756878f, 0.003360f, 0.902849f, 0.090515f, 0.783018f, 0.008691f, 0.766115f, +0.296909f, 2.513941f, 0.003497f, 1.698026f, 0.336603f, 2.584801f, 0.048560f, 3.410053f, 0.427075f, 4.913864f, 0.004499f, 2.740763f, 0.677846f, 3.996972f, 0.021240f, 4.244512f, +0.438235f, 3.843079f, 0.000334f, 1.417929f, 0.306745f, 2.439651f, 0.002866f, 1.758117f, 0.045781f, 0.545562f, 0.000031f, 0.166218f, 0.367608f, 2.245051f, 0.000746f, 1.302293f, +1.209985f, 7.576733f, 0.005104f, 4.033694f, 1.029130f, 5.844531f, 0.053171f, 6.077367f, 1.109617f, 9.441974f, 0.004187f, 4.150904f, 1.523761f, 6.644879f, 0.017100f, 5.561801f, +0.229726f, 2.123354f, 0.005422f, 0.976885f, 0.190157f, 1.594053f, 0.054971f, 1.432414f, 0.137602f, 1.728330f, 0.002905f, 0.656609f, 0.188317f, 1.212191f, 0.011824f, 0.876798f, +1.130366f, 7.121635f, 0.008707f, 3.556109f, 1.429084f, 8.165742f, 0.134819f, 7.964084f, 1.115265f, 9.548301f, 0.007683f, 3.937136f, 2.785604f, 12.222170f, 0.057080f, 9.595131f, +0.098398f, 1.379080f, 0.000045f, 1.016230f, 0.066474f, 0.844950f, 0.000375f, 1.216125f, 0.012500f, 0.238077f, 0.000005f, 0.144870f, 0.079897f, 0.779829f, 0.000098f, 0.903461f, +0.074060f, 0.741164f, 0.000189f, 0.788066f, 0.060795f, 0.551792f, 0.001895f, 1.145957f, 0.082592f, 1.123205f, 0.000188f, 0.986202f, 0.090278f, 0.629191f, 0.000611f, 1.051812f, +0.002023f, 0.029887f, 0.000029f, 0.027462f, 0.001616f, 0.021655f, 0.000282f, 0.038864f, 0.001474f, 0.029584f, 0.000019f, 0.022447f, 0.001605f, 0.016516f, 0.000061f, 0.023859f, +0.109778f, 1.105370f, 0.000510f, 1.102377f, 0.133952f, 1.223254f, 0.007625f, 2.382781f, 0.131716f, 1.802261f, 0.000548f, 1.484223f, 0.261867f, 1.836281f, 0.003238f, 2.879183f, +0.106025f, 1.874356f, 0.000332f, 1.209820f, 0.075487f, 1.210300f, 0.002899f, 1.525831f, 0.014891f, 0.357720f, 0.000042f, 0.190665f, 0.062012f, 0.763453f, 0.000517f, 0.774744f, +0.279517f, 3.528415f, 0.004847f, 3.286200f, 0.241820f, 2.768471f, 0.051361f, 5.036155f, 0.344610f, 5.911351f, 0.005345f, 4.546321f, 0.245431f, 2.157586f, 0.011322f, 3.159293f, +0.065972f, 1.229247f, 0.006401f, 0.989358f, 0.055546f, 0.938668f, 0.066010f, 1.475609f, 0.053125f, 1.345146f, 0.004610f, 0.894011f, 0.037707f, 0.489295f, 0.009733f, 0.619146f, +0.213409f, 2.710455f, 0.006758f, 2.367723f, 0.274438f, 3.161191f, 0.106432f, 5.393669f, 0.283073f, 4.885566f, 0.008017f, 3.524217f, 0.366688f, 3.243352f, 0.030888f, 4.454410f, +0.003764f, 0.056728f, 0.000026f, 0.041297f, 0.002410f, 0.032939f, 0.000204f, 0.046834f, 0.000722f, 0.014778f, 0.000004f, 0.008884f, 0.003211f, 0.033707f, 0.000059f, 0.038578f, +0.003502f, 0.037682f, 0.000134f, 0.039581f, 0.002724f, 0.026586f, 0.001274f, 0.054546f, 0.005893f, 0.086173f, 0.000201f, 0.074747f, 0.004485f, 0.033613f, 0.000455f, 0.055510f, +0.002412f, 0.038319f, 0.000515f, 0.034784f, 0.001826f, 0.026312f, 0.004778f, 0.046651f, 0.002652f, 0.057237f, 0.000507f, 0.042904f, 0.002011f, 0.022250f, 0.001143f, 0.031754f, +0.005059f, 0.054781f, 0.000353f, 0.053971f, 0.005850f, 0.057451f, 0.004995f, 0.110556f, 0.009160f, 0.134784f, 0.000571f, 0.109656f, 0.012681f, 0.095624f, 0.002352f, 0.148119f, +0.196148f, 2.199672f, 0.000885f, 1.183806f, 0.140042f, 1.424320f, 0.007742f, 1.497183f, 0.025793f, 0.393065f, 0.000104f, 0.174681f, 0.180645f, 1.410807f, 0.002169f, 1.193707f, +0.265614f, 2.126933f, 0.006631f, 1.651666f, 0.230432f, 1.673488f, 0.070457f, 2.538258f, 0.306610f, 3.336384f, 0.006846f, 2.139456f, 0.367241f, 2.047961f, 0.024389f, 2.500331f, +0.128018f, 1.513157f, 0.017882f, 1.015436f, 0.108087f, 1.158686f, 0.184913f, 1.518724f, 0.096523f, 1.550349f, 0.012058f, 0.859126f, 0.115216f, 0.948409f, 0.042813f, 1.000625f, +0.530342f, 4.272847f, 0.024175f, 3.112147f, 0.683905f, 4.997288f, 0.381824f, 7.109221f, 0.658653f, 7.211161f, 0.026853f, 4.337175f, 1.434893f, 8.050978f, 0.174002f, 9.219319f, +0.353632f, 6.421863f, 0.000029f, 2.901427f, 0.175878f, 2.896677f, 0.000175f, 2.556204f, 0.033367f, 0.823404f, 0.000002f, 0.307201f, 0.189233f, 2.393181f, 0.000041f, 1.699940f, +0.280271f, 3.634266f, 0.000126f, 2.369261f, 0.169379f, 1.991934f, 0.000933f, 2.536391f, 0.232144f, 4.090576f, 0.000093f, 2.202114f, 0.225155f, 2.033244f, 0.000269f, 2.083979f, +0.006581f, 0.125960f, 0.000017f, 0.070963f, 0.003871f, 0.067190f, 0.000119f, 0.073934f, 0.003560f, 0.092603f, 0.000008f, 0.043080f, 0.003441f, 0.045872f, 0.000023f, 0.040631f, +0.344819f, 4.498723f, 0.000283f, 2.750806f, 0.309757f, 3.665185f, 0.003116f, 4.377351f, 0.307282f, 5.447819f, 0.000226f, 2.750758f, 0.542075f, 4.925219f, 0.001184f, 4.734822f, +0.671521f, 15.381840f, 0.000372f, 6.087302f, 0.351982f, 7.312174f, 0.002389f, 5.652077f, 0.070047f, 2.180331f, 0.000035f, 0.712522f, 0.258837f, 4.128981f, 0.000382f, 2.569017f, +1.864185f, 30.490640f, 0.005712f, 17.411210f, 1.187324f, 17.612630f, 0.044561f, 19.644070f, 1.706993f, 37.939960f, 0.004678f, 17.890330f, 1.078733f, 12.287390f, 0.008794f, 11.031370f, +0.378166f, 9.129998f, 0.006484f, 4.505397f, 0.234410f, 5.132644f, 0.049224f, 4.947074f, 0.226177f, 7.420350f, 0.003468f, 3.023750f, 0.142446f, 2.395010f, 0.006497f, 1.858135f, +1.181333f, 19.440540f, 0.006610f, 10.412270f, 1.118410f, 16.692230f, 0.076643f, 17.462080f, 1.163806f, 26.025820f, 0.005824f, 11.510660f, 1.337706f, 15.330800f, 0.019911f, 12.909490f, +0.168929f, 3.298788f, 0.000206f, 1.472377f, 0.079621f, 1.410125f, 0.001189f, 1.229326f, 0.024053f, 0.638272f, 0.000026f, 0.235250f, 0.094985f, 1.291744f, 0.000308f, 0.906459f, +0.165476f, 2.307363f, 0.001116f, 1.486025f, 0.094772f, 1.198501f, 0.007830f, 1.507626f, 0.206831f, 3.919071f, 0.001248f, 2.084263f, 0.139684f, 1.356426f, 0.002507f, 1.373453f, +0.097983f, 2.016711f, 0.003698f, 1.122416f, 0.054615f, 1.019480f, 0.025247f, 1.108240f, 0.079994f, 2.237352f, 0.002700f, 1.028262f, 0.053840f, 0.771734f, 0.005406f, 0.675282f, +0.198452f, 2.784156f, 0.002444f, 1.681815f, 0.168946f, 2.149633f, 0.025487f, 2.536260f, 0.266870f, 5.087758f, 0.002940f, 2.537875f, 0.327816f, 3.202854f, 0.010742f, 3.041791f, +0.753354f, 10.946590f, 0.000601f, 3.612017f, 0.395976f, 5.218264f, 0.003868f, 3.363114f, 0.073577f, 1.452809f, 0.000052f, 0.395857f, 0.457241f, 4.626934f, 0.000970f, 2.400333f, +1.074228f, 11.145650f, 0.004739f, 5.306669f, 0.686097f, 6.456124f, 0.037069f, 6.003896f, 0.920989f, 12.985270f, 0.003634f, 5.105362f, 0.978815f, 7.072584f, 0.011487f, 5.294220f, +0.445001f, 6.815232f, 0.010984f, 2.804123f, 0.276607f, 3.842021f, 0.083618f, 3.087600f, 0.249197f, 5.186203f, 0.005501f, 1.762077f, 0.263942f, 2.815120f, 0.017331f, 1.821045f, +1.780250f, 18.584400f, 0.014340f, 8.299260f, 1.690122f, 16.001590f, 0.166736f, 13.957210f, 1.642118f, 23.294840f, 0.011830f, 8.590324f, 3.174305f, 23.077270f, 0.068019f, 16.202530f, +0.112643f, 2.155673f, 0.000016f, 1.482782f, 0.073844f, 1.281659f, 0.000126f, 1.721915f, 0.010868f, 0.282629f, 0.000001f, 0.160535f, 0.084949f, 1.132162f, 0.000031f, 1.224364f, +0.096703f, 1.321442f, 0.000074f, 1.311560f, 0.077032f, 0.954679f, 0.000726f, 1.850726f, 0.081903f, 1.520890f, 0.000056f, 1.246513f, 0.109485f, 1.041915f, 0.000224f, 1.625847f, +0.002660f, 0.053659f, 0.000011f, 0.046023f, 0.002062f, 0.037728f, 0.000109f, 0.063204f, 0.001472f, 0.040338f, 0.000006f, 0.028570f, 0.001961f, 0.027540f, 0.000022f, 0.037138f, +0.145283f, 1.997482f, 0.000204f, 1.859504f, 0.172026f, 2.145063f, 0.002962f, 3.900311f, 0.132386f, 2.473420f, 0.000166f, 1.901390f, 0.321880f, 3.081984f, 0.001204f, 4.510785f, +0.106242f, 2.564575f, 0.000101f, 1.545168f, 0.073402f, 1.606957f, 0.000852f, 1.891078f, 0.011332f, 0.371716f, 0.000010f, 0.184940f, 0.057713f, 0.970200f, 0.000146f, 0.919029f, +0.319474f, 5.506598f, 0.001675f, 4.787287f, 0.268205f, 4.192679f, 0.017227f, 7.119386f, 0.299130f, 7.006406f, 0.001403f, 5.029912f, 0.260538f, 3.127430f, 0.003635f, 4.274656f, +0.075928f, 1.931801f, 0.002228f, 1.451337f, 0.062037f, 1.431474f, 0.022295f, 2.100556f, 0.046436f, 1.605453f, 0.001219f, 0.996008f, 0.040307f, 0.714184f, 0.003146f, 0.843575f, +0.247218f, 4.287334f, 0.002367f, 3.495971f, 0.308503f, 4.852257f, 0.036182f, 7.728036f, 0.249041f, 5.869010f, 0.002133f, 3.951886f, 0.394530f, 4.764913f, 0.010050f, 6.108617f, +0.064067f, 1.318432f, 0.000134f, 0.895914f, 0.039803f, 0.742868f, 0.001018f, 0.985972f, 0.009328f, 0.260850f, 0.000017f, 0.146372f, 0.050769f, 0.727597f, 0.000282f, 0.777332f, +0.067980f, 0.998916f, 0.000785f, 0.979452f, 0.051319f, 0.683915f, 0.007256f, 1.309787f, 0.086884f, 1.734913f, 0.000897f, 1.404724f, 0.080873f, 0.827600f, 0.002484f, 1.275798f, +0.047160f, 1.022896f, 0.003046f, 0.866733f, 0.034648f, 0.681581f, 0.027412f, 1.128018f, 0.039369f, 1.160389f, 0.002275f, 0.811927f, 0.036521f, 0.551654f, 0.006276f, 0.734900f, +0.099554f, 1.471867f, 0.002099f, 1.353621f, 0.111713f, 1.497924f, 0.028843f, 2.690687f, 0.136895f, 2.750320f, 0.002581f, 2.088674f, 0.231764f, 2.386291f, 0.012997f, 3.450319f, +0.229625f, 3.516160f, 0.000313f, 1.766375f, 0.159088f, 2.209358f, 0.002660f, 2.167831f, 0.022932f, 0.477177f, 0.000028f, 0.197949f, 0.196415f, 2.094566f, 0.000713f, 1.654306f, +0.354671f, 3.877973f, 0.002678f, 2.811026f, 0.298583f, 2.960885f, 0.027609f, 4.192051f, 0.310932f, 4.619892f, 0.002100f, 2.765356f, 0.455450f, 3.468075f, 0.009147f, 3.952356f, +0.172133f, 2.778143f, 0.007271f, 1.740262f, 0.141032f, 2.064354f, 0.072964f, 2.525743f, 0.098566f, 2.161748f, 0.003724f, 1.118212f, 0.143888f, 1.617268f, 0.016169f, 1.592757f, +0.717747f, 7.896047f, 0.009894f, 5.368392f, 0.898172f, 8.961379f, 0.151645f, 11.900200f, 0.676982f, 10.120510f, 0.008347f, 5.681932f, 1.803643f, 13.818370f, 0.066144f, 14.770620f, +0.540862f, 5.927737f, 0.000042f, 2.994635f, 0.272764f, 2.711236f, 0.000260f, 2.675267f, 0.045113f, 0.671886f, 0.000003f, 0.280292f, 0.287541f, 2.194675f, 0.000059f, 1.743142f, +0.426478f, 3.337560f, 0.000183f, 2.432932f, 0.261347f, 1.854927f, 0.001377f, 2.641025f, 0.312271f, 3.320871f, 0.000120f, 1.998996f, 0.340384f, 1.855106f, 0.000389f, 2.126067f, +0.007354f, 0.084947f, 0.000018f, 0.053512f, 0.004386f, 0.045947f, 0.000129f, 0.056533f, 0.003517f, 0.055207f, 0.000008f, 0.028718f, 0.003821f, 0.030735f, 0.000024f, 0.030440f, +0.465792f, 3.667610f, 0.000366f, 2.507600f, 0.424288f, 3.029905f, 0.004081f, 4.046216f, 0.366939f, 3.926193f, 0.000258f, 2.216694f, 0.727491f, 3.989203f, 0.001520f, 4.288138f, +0.892000f, 12.331220f, 0.000473f, 5.456662f, 0.474095f, 5.944066f, 0.003077f, 5.137474f, 0.082252f, 1.545167f, 0.000039f, 0.564619f, 0.341584f, 3.288573f, 0.000481f, 2.287895f, +2.463646f, 24.319170f, 0.007219f, 15.528010f, 1.591102f, 14.244450f, 0.057104f, 17.764690f, 1.994234f, 26.750640f, 0.005227f, 14.104580f, 1.416348f, 9.736629f, 0.011041f, 9.774239f, +0.367008f, 5.347572f, 0.006017f, 2.950690f, 0.230679f, 3.048361f, 0.046322f, 3.285324f, 0.194042f, 3.842072f, 0.002845f, 1.750618f, 0.137344f, 1.393671f, 0.005990f, 1.209023f, +1.385936f, 13.764870f, 0.007416f, 8.243534f, 1.330488f, 11.984430f, 0.087190f, 14.018560f, 1.206998f, 16.290080f, 0.005776f, 8.056075f, 1.559187f, 10.784380f, 0.022193f, 10.154160f, +0.346666f, 4.085599f, 0.000404f, 2.039036f, 0.165683f, 1.770917f, 0.002367f, 1.726284f, 0.043635f, 0.698815f, 0.000046f, 0.287998f, 0.193657f, 1.589441f, 0.000601f, 1.247156f, +0.337853f, 2.843162f, 0.002179f, 2.047465f, 0.196206f, 1.497488f, 0.015502f, 2.106314f, 0.373305f, 4.268979f, 0.002154f, 2.538621f, 0.283340f, 1.660537f, 0.004862f, 1.880056f, +0.146909f, 1.824875f, 0.005303f, 1.135659f, 0.083032f, 0.935422f, 0.036705f, 1.137018f, 0.106025f, 1.789694f, 0.003423f, 0.919714f, 0.080200f, 0.693783f, 0.007701f, 0.678806f, +0.359691f, 3.045515f, 0.004237f, 2.057075f, 0.310500f, 2.384354f, 0.044794f, 3.145610f, 0.427592f, 4.919815f, 0.004505f, 2.744082f, 0.590298f, 3.480736f, 0.018497f, 3.696305f, +1.111658f, 9.748637f, 0.000848f, 3.596823f, 0.592489f, 4.712271f, 0.005535f, 3.395864f, 0.095977f, 1.143743f, 0.000065f, 0.348468f, 0.670323f, 4.093784f, 0.001360f, 2.374693f, +1.577077f, 9.875405f, 0.006653f, 5.257458f, 1.021365f, 5.800435f, 0.052770f, 6.031514f, 1.195270f, 10.170810f, 0.004510f, 4.471317f, 1.427657f, 6.225787f, 0.016021f, 5.211019f, +0.479757f, 4.434388f, 0.011324f, 2.040115f, 0.302386f, 2.534849f, 0.087414f, 2.277812f, 0.237497f, 2.983031f, 0.005014f, 1.133281f, 0.282707f, 1.819771f, 0.017751f, 1.316270f, +2.320164f, 14.617710f, 0.017872f, 7.299190f, 2.233548f, 12.762430f, 0.210712f, 12.447250f, 1.891897f, 16.197410f, 0.013034f, 6.678823f, 4.110108f, 18.033580f, 0.084220f, 14.157440f, +}; + +static const float acceptor_me2x3acc6[64] = { +0.198561f, 0.337610f, 0.053207f, 0.494507f, 0.281041f, 0.889447f, 0.497835f, 1.051663f, 0.054833f, 0.146701f, 0.059791f, 0.204920f, 0.431595f, 1.165403f, 0.729493f, 1.225165f, +0.318682f, 0.805716f, 0.125296f, 1.247968f, 0.425639f, 2.003059f, 1.106270f, 2.504460f, 0.277875f, 1.105458f, 0.444579f, 1.632886f, 0.703515f, 2.824722f, 1.744707f, 3.140203f, +0.121459f, 0.355438f, 0.052579f, 0.416660f, 0.260773f, 1.420445f, 0.746255f, 1.344131f, 0.122075f, 0.562122f, 0.215047f, 0.628406f, 0.355410f, 1.651741f, 0.970475f, 1.389698f, +0.534367f, 0.995770f, 0.131584f, 1.612177f, 0.696320f, 2.415218f, 1.133477f, 3.156525f, 0.518371f, 1.519946f, 0.519427f, 2.346789f, 1.001111f, 2.962646f, 1.554947f, 3.442660f, +}; + +static const float acceptor_me2x3acc7[256] = { +0.081108f, 0.167573f, 0.002337f, 0.363544f, 0.096275f, 0.397918f, 0.186669f, 0.465951f, 0.001415f, 0.004990f, 0.001895f, 0.012787f, 0.191144f, 0.781838f, 0.312855f, 0.859362f, +0.106486f, 0.277527f, 0.002589f, 0.530254f, 0.178124f, 0.928697f, 0.291412f, 0.957738f, 0.070281f, 0.312724f, 0.079420f, 0.705780f, 0.291511f, 1.504128f, 0.402592f, 1.456027f, +0.003287f, 0.010233f, 0.000151f, 0.019997f, 0.005449f, 0.033928f, 0.016796f, 0.035788f, 0.001596f, 0.008479f, 0.003397f, 0.019573f, 0.011741f, 0.072355f, 0.030554f, 0.071640f, +0.136216f, 0.300112f, 0.003885f, 0.664942f, 0.346218f, 1.525973f, 0.664408f, 1.824904f, 0.115029f, 0.432688f, 0.152476f, 1.132412f, 0.449239f, 1.959528f, 0.727757f, 2.199667f, +0.157231f, 0.313885f, 0.004443f, 0.562003f, 0.229863f, 0.918001f, 0.437029f, 0.887163f, 0.003917f, 0.013349f, 0.005144f, 0.028233f, 0.465016f, 1.837885f, 0.746333f, 1.667212f, +0.267623f, 0.673953f, 0.006381f, 1.062730f, 0.551359f, 2.777670f, 0.884509f, 2.364105f, 0.252278f, 1.084667f, 0.279548f, 2.020313f, 0.919431f, 4.583978f, 1.245120f, 3.662190f, +0.094987f, 0.285687f, 0.004267f, 0.460769f, 0.193895f, 1.166641f, 0.586098f, 1.015600f, 0.065845f, 0.338115f, 0.137479f, 0.644149f, 0.425748f, 2.535123f, 1.086372f, 2.071556f, +0.326828f, 0.695776f, 0.009140f, 1.272283f, 1.023115f, 4.357276f, 1.925271f, 4.300530f, 0.394195f, 1.432757f, 0.512374f, 3.094677f, 1.352704f, 5.701262f, 2.148795f, 5.281901f, +0.057108f, 0.111893f, 0.001336f, 0.257086f, 0.061805f, 0.242256f, 0.097290f, 0.300431f, 0.001612f, 0.005392f, 0.001753f, 0.014634f, 0.151666f, 0.588321f, 0.201536f, 0.684852f, +0.105920f, 0.261792f, 0.002091f, 0.529736f, 0.161543f, 0.798747f, 0.214563f, 0.872378f, 0.113136f, 0.477410f, 0.103795f, 1.141098f, 0.326767f, 1.598953f, 0.366378f, 1.639244f, +0.038181f, 0.112707f, 0.001420f, 0.233266f, 0.057697f, 0.340719f, 0.144395f, 0.380619f, 0.029990f, 0.151144f, 0.051842f, 0.369505f, 0.153674f, 0.898096f, 0.324659f, 0.941737f, +0.187401f, 0.391559f, 0.004339f, 0.918799f, 0.434288f, 1.815277f, 0.676619f, 2.299108f, 0.256113f, 0.913623f, 0.275617f, 2.532323f, 0.696500f, 2.881136f, 0.916035f, 3.425251f, +0.232940f, 0.409618f, 0.005813f, 0.875147f, 0.306761f, 1.079138f, 0.515071f, 1.244432f, 0.005656f, 0.016981f, 0.006560f, 0.042855f, 0.677246f, 2.357764f, 0.959925f, 2.552155f, +0.388069f, 0.860830f, 0.008171f, 1.619737f, 0.720186f, 3.195905f, 1.020324f, 3.245741f, 0.356594f, 1.350495f, 0.348960f, 3.001574f, 1.310623f, 5.755779f, 1.567457f, 5.487020f, +0.197520f, 0.523291f, 0.007836f, 1.007094f, 0.363197f, 1.924930f, 0.969550f, 1.999559f, 0.133470f, 0.603706f, 0.246104f, 1.372401f, 0.870313f, 4.564836f, 1.961226f, 4.450991f, +0.385616f, 0.723116f, 0.009524f, 1.577815f, 1.087389f, 4.079232f, 1.807083f, 4.804181f, 0.453372f, 1.451507f, 0.520424f, 3.741071f, 1.568960f, 5.824824f, 2.201048f, 6.439262f, +}; + +static const float acceptor_me2x3acc8[64] = { +0.134444f, 0.409251f, 0.002027f, 0.474269f, 0.184336f, 0.805301f, 0.161375f, 0.751628f, 0.001443f, 0.007759f, 0.001694f, 0.010525f, 0.386007f, 1.386879f, 0.409270f, 1.281481f, +0.372889f, 1.094436f, 0.005800f, 1.222804f, 0.718837f, 3.027880f, 0.649183f, 2.724678f, 0.308629f, 1.600430f, 0.373846f, 2.093096f, 0.975473f, 3.379250f, 1.066943f, 3.010408f, +0.089765f, 0.290835f, 0.001698f, 0.279494f, 0.240649f, 1.118979f, 0.264289f, 0.866080f, 0.068014f, 0.389342f, 0.100188f, 0.437969f, 0.484599f, 1.853180f, 0.644566f, 1.419979f, +0.379547f, 1.332811f, 0.007810f, 1.355863f, 1.060978f, 5.346963f, 1.267546f, 4.380911f, 0.311496f, 1.932612f, 0.499147f, 2.301325f, 0.956094f, 3.962763f, 1.383397f, 3.214281f, +}; + +static const float acceptor_me2x3acc9[256] = { +0.080864f, 1.061148f, 0.000011f, 0.632647f, 0.047418f, 0.576001f, 0.000076f, 0.661114f, 0.009049f, 0.167492f, 0.000001f, 0.080486f, 0.051563f, 0.472722f, 0.000019f, 0.445638f, +0.091072f, 0.893180f, 0.000061f, 0.745645f, 0.064861f, 0.588840f, 0.000540f, 0.946364f, 0.088873f, 1.229428f, 0.000052f, 0.827251f, 0.086646f, 0.593677f, 0.000166f, 0.783673f, +0.001797f, 0.027297f, 0.000007f, 0.019437f, 0.001261f, 0.017732f, 0.000064f, 0.024308f, 0.001179f, 0.025278f, 0.000004f, 0.014508f, 0.001114f, 0.011825f, 0.000013f, 0.013314f, +0.101349f, 0.983407f, 0.000137f, 0.783197f, 0.107646f, 0.966884f, 0.001807f, 1.482449f, 0.105833f, 1.448493f, 0.000126f, 0.929812f, 0.191886f, 1.300784f, 0.000743f, 1.638076f, +0.154788f, 2.479552f, 0.000105f, 1.241938f, 0.092410f, 1.370311f, 0.000774f, 1.321338f, 0.018062f, 0.408120f, 0.000011f, 0.164761f, 0.066491f, 0.744129f, 0.000128f, 0.589341f, +0.610440f, 7.308212f, 0.002132f, 5.125611f, 0.442626f, 4.905333f, 0.019136f, 6.623243f, 0.621187f, 10.489910f, 0.001904f, 5.929898f, 0.391247f, 3.272414f, 0.003899f, 3.629058f, +0.099005f, 1.836332f, 0.002115f, 1.098519f, 0.070736f, 1.214508f, 0.018706f, 1.398699f, 0.067780f, 1.773278f, 0.001270f, 0.855015f, 0.041357f, 0.535914f, 0.002521f, 0.506924f, +0.339500f, 4.021317f, 0.002391f, 2.690590f, 0.367127f, 4.025388f, 0.032003f, 5.185070f, 0.369690f, 6.176573f, 0.002284f, 3.330946f, 0.433020f, 3.583319f, 0.008701f, 3.791018f, +0.054050f, 0.613302f, 0.000071f, 0.393464f, 0.030405f, 0.319364f, 0.000496f, 0.394443f, 0.008783f, 0.140572f, 0.000010f, 0.072689f, 0.036114f, 0.286286f, 0.000136f, 0.290417f, +0.078085f, 0.662187f, 0.000531f, 0.594866f, 0.053349f, 0.418797f, 0.004490f, 0.724286f, 0.110652f, 1.323586f, 0.000660f, 0.958366f, 0.077845f, 0.461199f, 0.001510f, 0.655115f, +0.033487f, 0.439955f, 0.001393f, 0.337108f, 0.022544f, 0.274172f, 0.011605f, 0.404438f, 0.031925f, 0.591623f, 0.001165f, 0.365381f, 0.021758f, 0.199711f, 0.002582f, 0.241966f, +0.079155f, 0.664122f, 0.001085f, 0.569156f, 0.080653f, 0.626402f, 0.013686f, 1.033485f, 0.120029f, 1.420490f, 0.001444f, 0.981210f, 0.157035f, 0.920483f, 0.006143f, 1.247354f, +0.260466f, 2.581281f, 0.000283f, 1.096237f, 0.154217f, 1.414753f, 0.002073f, 1.156691f, 0.027955f, 0.390769f, 0.000027f, 0.133761f, 0.180139f, 1.247216f, 0.000558f, 0.837533f, +0.515311f, 3.816698f, 0.002889f, 2.269680f, 0.370563f, 2.540647f, 0.025710f, 2.908632f, 0.482302f, 5.038710f, 0.002372f, 2.415110f, 0.531751f, 2.751541f, 0.008505f, 2.587283f, +0.170667f, 1.958368f, 0.005852f, 0.993328f, 0.120930f, 1.284526f, 0.051320f, 1.254322f, 0.107464f, 1.739365f, 0.003232f, 0.711099f, 0.114782f, 0.920173f, 0.011229f, 0.738005f, +0.770290f, 5.644597f, 0.008706f, 3.202243f, 0.826094f, 5.603657f, 0.115564f, 6.120130f, 0.771476f, 7.974125f, 0.007649f, 3.646240f, 1.581806f, 8.098064f, 0.051009f, 7.264300f, +}; + +#endif diff --git a/splice_site_new.cpp b/splice_site_new.cpp new file mode 100644 index 0000000..ae12a47 --- /dev/null +++ b/splice_site_new.cpp @@ -0,0 +1,1157 @@ +/* + * Copyright 2013, Daehwan Kim + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "edit.h" +#include "splice_site.h" +#include "aligner_report.h" +#include "aligner_result.h" + +#if defined(NEW_PROB_MODEL) + +#include "splice_site_mem.h" + +#else + +float donor_prob[4][donor_len] = { + {0.340f, 0.604f, 0.092f, 0.001f, 0.001f, 0.526f, 0.713f, 0.071f, 0.160f}, + {0.363f, 0.129f, 0.033f, 0.001f, 0.001f, 0.028f, 0.076f, 0.055f, 0.165f}, + {0.183f, 0.125f, 0.803f, 1.000f, 0.001f, 0.419f, 0.118f, 0.814f, 0.209f}, + {0.114f, 0.142f, 0.073f, 0.001f, 1.000f, 0.025f, 0.093f, 0.059f, 0.462f} +}; + +float acceptor_prob[4][acceptor_len] = { + {0.090f, 0.084f, 0.075f, 0.068f, 0.076f, 0.080f, 0.097f, 0.092f, 0.076f, 0.078f, 0.237f, 0.042f, 1.000f, 0.001f, 0.239f}, + {0.310f, 0.310f, 0.307f, 0.293f, 0.326f, 0.330f, 0.373f, 0.385f, 0.410f, 0.352f, 0.309f, 0.708f, 0.001f, 0.001f, 0.138f}, + {0.125f, 0.115f, 0.106f, 0.104f, 0.110f, 0.113f, 0.113f, 0.085f, 0.066f, 0.064f, 0.212f, 0.003f, 0.001f, 1.000f, 0.520f}, + {0.463f, 0.440f, 0.470f, 0.494f, 0.471f, 0.463f, 0.408f, 0.429f, 0.445f, 0.504f, 0.240f, 0.246f, 0.001f, 0.001f, 0.104f} +}; + +float donor_prob_sum[1 << (donor_len << 1)]; +float acceptor_prob_sum1[1 << (acceptor_len1 << 1)]; +float acceptor_prob_sum2[1 << (acceptor_len2 << 1)]; + +#endif + +void init_junction_prob() +{ +#if !defined(NEW_PROB_MODEL) + for(size_t i = 0; i < donor_len; i++) { + ASSERT_ONLY(float sum = 0.0f); + for(size_t j = 0; j < 4; j++) { + float prob = donor_prob[j][i]; + assert_gt(prob, 0.0f); + ASSERT_ONLY(sum += prob); + donor_prob[j][i] = log(prob / background_prob[j]); + } + assert_range(0.9f, 1.05f, sum); + } + for(size_t i = 0; i < acceptor_len; i++) { + ASSERT_ONLY(float sum = 0.0f); + for(size_t j = 0; j < 4; j++) { + float prob = acceptor_prob[j][i]; + assert_gt(prob, 0.0f); + ASSERT_ONLY(sum += prob); + acceptor_prob[j][i] = log(prob / background_prob[j]); + } + assert_range(0.9f, 1.05f, sum); + } + + const size_t donor_elms = 1 << (donor_len << 1); + for(size_t i = 0; i < donor_elms; i++) { + float sum = 0.0f; + for(size_t j = 0; j < donor_len; j++) { + int base = (i >> (j << 1)) & 0x3; + sum += donor_prob[base][donor_len - j - 1]; + } + donor_prob_sum[i] = exp(-sum); + } + + const size_t acceptor_elms1 = 1 << (acceptor_len1 << 1); + for(size_t i = 0; i < acceptor_elms1; i++) { + float sum = 0.0f; + for(size_t j = 0; j < acceptor_len1; j++) { + int base = (i >> (j << 1)) & 0x3; + sum += acceptor_prob[base][acceptor_len1 - j - 1]; + } + acceptor_prob_sum1[i] = exp(-sum); + } + + const size_t acceptor_elms2 = 1 << (acceptor_len2 << 1); + for(size_t i = 0; i < acceptor_elms2; i++) { + float sum = 0.0f; + for(size_t j = 0; j < acceptor_len2; j++) { + int base = (i >> (j << 1)) & 0x3; + sum += acceptor_prob[base][acceptor_len - j - 1]; + } + acceptor_prob_sum2[i] = exp(-sum); + } +#endif +} + +ostream& operator<<(ostream& out, const SpliceSite& s) +{ + out << s.ref() << "\t" + << s.left() << "\t" + << s.right() << "\t" + << (s.fw() ? "+" : "-") << endl; + return out; +} + +#if defined(SPLIT_DB) + +static const uint64_t ref_segment_size = 1 << 24; + +SpliceSiteDB::SpliceSiteDB( + const BitPairReference& refs, + const EList& refnames, + bool threadSafe, + bool write, + bool read) : +_numRefs(refs.numRefs()), +_refnames(refnames), +_write(write), +_read(read), +_threadSafe(threadSafe), +_empty(true) +{ + assert_gt(_numRefs, 0); + assert_eq(_numRefs, _refnames.size()); + for(uint64_t i = 0; i < _numRefs; i++) { + uint64_t reflen = refs.approxLen(i); + assert_gt(reflen, 0); + uint64_t numsegs = (reflen + ref_segment_size - 1) / ref_segment_size; + assert_gt(numsegs, 0); + + _fwIndex.expand(); + _bwIndex.expand(); + for(uint64_t j = 0; j < numsegs; j++) { + _fwIndex.back().push_back(new RedBlack(16 << 10, CA_CAT)); + _bwIndex.back().push_back(new RedBlack(16 << 10, CA_CAT)); + } + + _pool.expand(); + _pool.back().resize(numsegs); + _spliceSites.expand(); + _spliceSites.back().resize(numsegs); + + _mutex.expand(); + for(uint64_t j = 0; j < numsegs; j++) { + _mutex.back().push_back(MUTEX_T()); + } + } + + donorstr.resize(donor_exonic_len + donor_intronic_len); + acceptorstr.resize(acceptor_intronic_len + acceptor_exonic_len); +} + +SpliceSiteDB::~SpliceSiteDB() { + assert_eq(_fwIndex.size(), _bwIndex.size()); + assert_eq(_fwIndex.size(), _pool.size()); + for(uint64_t i = 0; i < _numRefs; i++) { + assert_eq(_fwIndex[i].size(), _bwIndex[i].size()); + for(uint64_t j = 0; j < _fwIndex[i].size(); j++) { + delete _fwIndex[i][j]; + delete _bwIndex[i][j]; + } + + _fwIndex[i].clear(); + _bwIndex[i].clear(); + + ELList& pool = _pool[i]; + for(size_t j = 0; j < pool.size(); j++) { + for(size_t k = 0; k < pool[j].size(); k++) { + delete pool[j][k]; + } + } + } +} + +#if 0 +size_t SpliceSiteDB::size(uint64_t ref) const { + if(!_read) return 0; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + assert_lt(ref, _fwIndex.size()); + assert_eq(_fwIndex.size(), _bwIndex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + return _fwIndex.size(); +} + +bool SpliceSiteDB::empty(uint64_t ref) const { + return size(ref) == 0; +} +#endif + +bool SpliceSiteDB::addSpliceSite( + const Read& rd, + const AlnRes& rs, + uint32_t minAnchorLen) +{ + if(!_write) return false; + if(rs.trimmed5p(true) + rs.trimmed3p(true) > 0) return false; + + _empty = false; + + Coord coord = rs.refcoord(); + uint64_t ref = coord.ref(); + assert_lt(ref, _numRefs); + const EList& edits = rs.ned(); + if(!coord.orient()) { + Edit::invertPoss(const_cast&>(edits), rd.length(), false); + } + SpliceSitePos ssp; + uint32_t refoff = coord.off(); + uint32_t leftAnchorLen = 0, rightAnchorLen = 0; + size_t eidx = 0; + size_t last_eidx = 0; + for(size_t i = 0; i < rd.length(); i++, refoff++) { + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + refoff++; + } else if(edits[eidx].isRefGap()) { + assert_gt(refoff, 0); + refoff--; + } + if(edits[eidx].isSpliced()) { + assert_gt(refoff, 0); + if(ssp.inited()) { + assert(edits[last_eidx].isSpliced()); + assert_lt(edits[last_eidx].pos, edits[eidx].pos); + rightAnchorLen = edits[eidx].pos - edits[last_eidx].pos; + if(leftAnchorLen >= minAnchorLen && rightAnchorLen >= minAnchorLen) { + bool added = false; + uint64_t ref_seg = ssp.left() / ref_segment_size; + uint64_t ref_seg2 = ssp.right() / ref_segment_size; + assert_leq(ref_seg, ref_seg2); + assert_lt(ref, _mutex.size()); + assert_lt(ref_seg, _mutex[ref].size()); + assert_lt(ref_seg2, _mutex[ref].size()); + ThreadSafe t(&_mutex[ref][ref_seg], _threadSafe && _write); + ThreadSafe t2(&_mutex[ref][ref_seg2], _threadSafe && _write && ref_seg != ref_seg2); + assert_lt(ref, _fwIndex.size()); + assert_lt(ref_seg, _fwIndex[ref].size()); + assert(_fwIndex[ref][ref_seg] != NULL); + Node *cur = _fwIndex[ref][ref_seg]->add(pool(ref, ref_seg), ssp, &added); + if(added) { + assert_lt(ref, _spliceSites.size()); + assert_lt(ref_seg, _spliceSites[ref].size()); + _spliceSites[ref][ref_seg].expand(); + _spliceSites[ref][ref_seg].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.fw(), ssp.canonical()); + _spliceSites[ref][ref_seg].back()._readid = rd.rdid; + assert(cur != NULL); + cur->payload = _spliceSites[ref][ref_seg].size() - 1; + + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.fw(), ssp.canonical()); + assert_lt(ref, _bwIndex.size()); + assert_lt(ref_seg2, _bwIndex[ref].size()); + assert(_bwIndex[ref][ref_seg2] != NULL); + cur = _bwIndex[ref][ref_seg2]->add(pool(ref, ref_seg2), rssp, &added); + assert(added); + assert(cur != NULL); + if(ref_seg != ref_seg2) { + _spliceSites[ref][ref_seg2].expand(); + _spliceSites[ref][ref_seg2].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.fw(), ssp.canonical()); + _spliceSites[ref][ref_seg2].back()._readid = rd.rdid; + } + cur->payload = _spliceSites[ref][ref_seg2].size() - 1; + + } else { + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + assert_lt(ref_seg, _spliceSites[ref].size()); + assert_lt(cur->payload, _spliceSites[ref][ref_seg].size()); + if(rd.rdid < _spliceSites[ref][ref_seg][cur->payload]._readid) { + _spliceSites[ref][ref_seg][cur->payload]._readid = rd.rdid; + } + if(ref_seg != ref_seg2) { + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.fw(), ssp.canonical()); + cur = _bwIndex[ref][ref_seg2]->add(pool(ref, ref_seg2), rssp, &added); + assert(cur != NULL); + assert(!added); + if(rd.rdid < _spliceSites[ref][ref_seg2][cur->payload]._readid) { + _spliceSites[ref][ref_seg2][cur->payload]._readid = rd.rdid; + } + } + } + } + leftAnchorLen = rightAnchorLen; + rightAnchorLen = 0; + } else { + leftAnchorLen = edits[eidx].pos; + } + bool fw = (edits[eidx].splDir == EDIT_SPL_FW || edits[eidx].splDir == EDIT_SPL_UNKNOWN); + bool canonical = (edits[eidx].splDir != EDIT_SPL_UNKNOWN); + ssp.init(coord.ref(), refoff - 1, refoff + edits[eidx].splLen, fw, canonical); + refoff += edits[eidx].splLen; + last_eidx = eidx; + } + eidx++; + } + } + if(ssp.inited()) { + assert(edits[last_eidx].isSpliced()); + assert_lt(edits[last_eidx].pos, rd.length()); + rightAnchorLen = rd.length() - edits[last_eidx].pos; + if(leftAnchorLen >= minAnchorLen && rightAnchorLen >= minAnchorLen) { + bool added = false; + uint64_t ref_seg = ssp.left() / ref_segment_size; + uint64_t ref_seg2 = ssp.right() / ref_segment_size; + assert_leq(ref_seg, ref_seg2); + assert_lt(ref, _mutex.size()); + assert_lt(ref_seg, _mutex[ref].size()); + assert_lt(ref_seg2, _mutex[ref].size()); + ThreadSafe t(&_mutex[ref][ref_seg], _threadSafe && _write); + ThreadSafe t2(&_mutex[ref][ref_seg2], _threadSafe && _write && ref_seg != ref_seg2); + assert_lt(ref, _fwIndex.size()); + assert_lt(ref_seg, _fwIndex[ref].size()); + assert(_fwIndex[ref][ref_seg] != NULL); + Node *cur = _fwIndex[ref][ref_seg]->add(pool(ref, ref_seg), ssp, &added); + if(added) { + assert_lt(ref, _spliceSites.size()); + assert_lt(ref_seg, _spliceSites[ref].size()); + _spliceSites[ref][ref_seg].expand(); + _spliceSites[ref][ref_seg].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.fw(), ssp.canonical()); + _spliceSites[ref][ref_seg].back()._readid = rd.rdid; + assert(cur != NULL); + cur->payload = _spliceSites[ref][ref_seg].size() - 1; + + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.fw(), ssp.canonical()); + assert_lt(ref, _bwIndex.size()); + assert_lt(ref_seg2, _bwIndex[ref].size()); + assert(_bwIndex[ref][ref_seg2] != NULL); + cur = _bwIndex[ref][ref_seg2]->add(pool(ref, ref_seg2), rssp, &added); + assert(added); + assert(cur != NULL); + if(ref_seg != ref_seg2) { + _spliceSites[ref][ref_seg2].expand(); + _spliceSites[ref][ref_seg2].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.fw(), ssp.canonical()); + _spliceSites[ref][ref_seg2].back()._readid = rd.rdid; + } + cur->payload = _spliceSites[ref][ref_seg2].size() - 1; + + } else { + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + assert_lt(ref_seg, _spliceSites[ref].size()); + assert_lt(cur->payload, _spliceSites[ref][ref_seg].size()); + if(rd.rdid < _spliceSites[ref][ref_seg][cur->payload]._readid) { + _spliceSites[ref][ref_seg][cur->payload]._readid = rd.rdid; + } + if(ref_seg != ref_seg2) { + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.fw(), ssp.canonical()); + cur = _bwIndex[ref][ref_seg2]->add(pool(ref, ref_seg2), rssp, &added); + assert(cur != NULL); + assert(!added); + if(rd.rdid < _spliceSites[ref][ref_seg2][cur->payload]._readid) { + _spliceSites[ref][ref_seg2][cur->payload]._readid = rd.rdid; + } + } + } + } + } + if(!coord.orient()) { + Edit::invertPoss(const_cast&>(edits), rd.length(), false); + } + + return true; +} + +bool SpliceSiteDB::getSpliceSite(SpliceSite& ss) const +{ + if(!_read) return false; + + uint64_t ref = ss.ref(); + uint64_t ref_seg = ss.left() / ref_segment_size; + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + assert_lt(ref_seg, _mutex[ref].size()); + ThreadSafe t(const_cast(&_mutex[ref][ref_seg]), _threadSafe && _write); + + assert_lt(ref, _fwIndex.size()); + assert_lt(ref_seg, _fwIndex[ref].size()); + assert(_fwIndex[ref][ref_seg] != NULL); + const Node *cur = _fwIndex[ref][ref_seg]->lookup(ss); + if(cur == NULL) return false; + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + assert_lt(ref_seg, _spliceSites[ref].size()); + ss = _spliceSites[ref][ref_seg][cur->payload]; + return true; +} + +void SpliceSiteDB::getLeftSpliceSites(uint32_t ref, uint32_t left, uint32_t range, EList& spliceSites) const +{ + if(!_read) return; + spliceSites.clear(); + assert_lt(ref, _numRefs); + assert_gt(range, 0); + assert_geq(left + 1, range); + uint32_t begin = left + 1 - range, end = left; + for(uint32_t i = begin / ref_segment_size; i <= end / ref_segment_size; i++) { + assert_lt(ref, _mutex.size()); + assert_lt(i, _mutex[ref].size()); + ThreadSafe t(const_cast(&_mutex[ref][i]), _threadSafe && _write); + assert_lt(ref, _bwIndex.size()); + assert_lt(i, _bwIndex[ref].size()); + assert(_bwIndex[ref][i] != NULL); + const Node *cur = _bwIndex[ref][i]->root(); + if(cur != NULL) getSpliceSites_recur(cur, _spliceSites[ref][i], ref, begin, end, spliceSites); + } +} + +void SpliceSiteDB::getRightSpliceSites(uint32_t ref, uint32_t right, uint32_t range, EList& spliceSites) const +{ + if(!_read) return; + spliceSites.clear(); + assert_lt(ref, _numRefs); + assert_gt(range, 0); + assert_gt(right + range, range); + uint32_t begin = right, end = right + range - 1; + for(uint32_t i = begin / ref_segment_size; i <= end / ref_segment_size; i++) { + assert_lt(ref, _mutex.size()); + assert_lt(i, _mutex[ref].size()); + ThreadSafe t(const_cast(&_mutex[ref][i]), _threadSafe && _write); + assert_lt(ref, _fwIndex.size()); + assert_lt(i, _fwIndex[ref].size()); + assert(_fwIndex[ref][i] != NULL); + const Node *cur = _fwIndex[ref][i]->root(); + if(cur != NULL) getSpliceSites_recur(cur, _spliceSites[ref][i], ref, begin, end, spliceSites); + } + +} + +void SpliceSiteDB::getSpliceSites_recur( + const RedBlackNode *node, + const EList& spliceSites_db, + uint32_t ref, + uint32_t left, + uint32_t right, + EList& spliceSites) const +{ + assert(node != NULL); + bool goleft = true, goright = true; + if((node->key.ref() > ref) || + (node->key.ref() == ref && node->key.left() > right)) { + goright = false; + } + + if((node->key.ref() < ref) || + (node->key.ref() == ref && node->key.left() < left)) { + goleft = false; + } + + if(goleft && node->left != NULL) { + getSpliceSites_recur( + node->left, + spliceSites_db, + ref, + left, + right, + spliceSites); + } + + if(node->key.ref() == ref && + node->key.left() >= left && node->key.left() <= right) { + assert_lt(node->payload, spliceSites_db.size()); +#ifndef NDEBUG + const SpliceSite& ss = spliceSites_db[node->payload]; + assert_eq(ss.ref(), node->key.ref()); + assert(ss.left() == node->key.left() || + ss.right() == node->key.left()); +#endif + spliceSites.push_back(spliceSites_db[node->payload]); + } + + if(goright && node->right != NULL) { + getSpliceSites_recur( + node->right, + spliceSites_db, + ref, + left, + right, + spliceSites); + } +} + +void SpliceSiteDB::print(ofstream& out) +{ + EList ss_list; + for(uint64_t i = 0; i < _fwIndex.size(); i++) { + for(uint64_t j = 0; j < _fwIndex[i].size(); j++) { + assert(_fwIndex[i][j] != NULL); + const Node *root = _fwIndex[i][j]->root(); + if(root != NULL) print_recur(root, out, ss_list); + } + } + print_impl(out, ss_list); +} + +void SpliceSiteDB::print_recur( + const RedBlackNode *node, + ofstream& out, + EList& ss_list) +{ + if(node == NULL) return; + print_recur(node->left, out, ss_list); + print_impl(out, ss_list, &(node->key)); + print_recur(node->right, out, ss_list); +} + +void SpliceSiteDB::print_impl( + ofstream& out, + EList& ss_list, + const SpliceSitePos* ss) +{ + size_t i = 0; + while(i < ss_list.size()) { + const SpliceSitePos& tmp_ss = ss_list[i]; + bool do_print = true; + if(ss != NULL) { + if(tmp_ss.ref() == ss->ref()) { + assert_leq(tmp_ss.left(), ss->left()); + if(ss->left() < tmp_ss.left() + 10) { + do_print = false; + if((int)ss->left() - (int)tmp_ss.left() == (int)ss->right() - (int)tmp_ss.right()) { + if(!tmp_ss.canonical() && ss->canonical()) { + ss_list.erase(i); + ss_list.push_back(*ss); + } + return; + } + } + } + } + + if(!do_print) { + i++; + continue; + } + + assert_lt(tmp_ss.ref(), _refnames.size()); + out << _refnames[tmp_ss.ref()] << "\t" + << tmp_ss.left() << "\t" + << tmp_ss.right() << "\t" + << (tmp_ss.canonical() ? (tmp_ss.fw() ? "+" : "-") : ".") << endl; + + ss_list.erase(i); + } + + if(ss != NULL) ss_list.push_back(*ss); +} + +void SpliceSiteDB::read(ifstream& in, bool novel) +{ + _empty = false; + assert_eq(_numRefs, _refnames.size()); + while(!in.eof()) { + string refname; + uint32_t left = 0, right = 0; + char fw = 0; + in >> refname >> left >> right >> fw; + uint32_t ref = 0; + for(; ref < _refnames.size(); ref++) { + if(_refnames[ref] == refname) break; + } + if(ref >= _numRefs) continue; + uint64_t ref_seg = left / ref_segment_size; + assert_lt(ref, _spliceSites.size()); + assert_lt(ref_seg, _spliceSites[ref].size()); + + _spliceSites[ref][ref_seg].expand(); + _spliceSites[ref][ref_seg].back().init(ref, left, right, fw == '+' || fw == '.', fw != '.'); + _spliceSites[ref][ref_seg].back()._fromfile = true; + assert_gt(_spliceSites[ref][ref_seg].size(), 0); + + bool added = false; + assert_lt(ref, _fwIndex.size()); + assert_lt(ref_seg, _fwIndex[ref].size()); + assert(_fwIndex[ref][ref_seg] != NULL); + Node *cur = _fwIndex[ref][ref_seg]->add(pool(ref, ref_seg), _spliceSites[ref][ref_seg].back(), &added); + assert(added); + assert(cur != NULL); + cur->payload = _spliceSites[ref][ref_seg].size() - 1; + + added = false; + uint64_t ref_seg2 = right / ref_segment_size; + SpliceSitePos rssp(ref, right, left, fw == '+' || fw == '.', fw != '.'); + assert_lt(ref, _bwIndex.size()); + assert_lt(ref_seg2, _bwIndex.size()); + assert(_bwIndex[ref][ref_seg2] != NULL); + cur = _bwIndex[ref][ref_seg2]->add(pool(ref, ref_seg2), rssp, &added); + assert(added); + assert(cur != NULL); + if(ref_seg != ref_seg2) { + _spliceSites[ref][ref_seg2].expand(); + _spliceSites[ref][ref_seg2].back().init(ref, left, right, fw == '+' || fw == '.', fw != '.'); + _spliceSites[ref][ref_seg2].back()._fromfile = true; + } + cur->payload = _spliceSites[ref][ref_seg2].size() - 1; + } +} + +Pool& SpliceSiteDB::pool(uint64_t ref, uint64_t ref_seg) { + assert_lt(ref, _numRefs); + assert_lt(ref, _pool.size()); + assert_lt(ref_seg, _pool[ref].size()); + if(_pool[ref][ref_seg].size() <= 0 || _pool[ref][ref_seg].back()->full()) { + _pool[ref][ref_seg].push_back(new Pool(1 << 18 /* 256KB */, 16 << 10 /* 16KB */, CA_CAT)); + } + assert(_pool[ref][ref_seg].back() != NULL); + return *_pool[ref][ref_seg].back(); +} + +#else + +SpliceSiteDB::SpliceSiteDB( + const BitPairReference& refs, + const EList& refnames, + bool threadSafe, + bool write, + bool read) : +_numRefs(refs.numRefs()), +_refnames(refnames), +_write(write), +_read(read), +_threadSafe(threadSafe), +_empty(true) +{ + assert_gt(_numRefs, 0); + assert_eq(_numRefs, _refnames.size()); + for(uint64_t i = 0; i < _numRefs; i++) { + _fwIndex.push_back(new RedBlack(16 << 10, CA_CAT)); + _bwIndex.push_back(new RedBlack(16 << 10, CA_CAT)); + _pool.expand(); + _spliceSites.expand(); + _mutex.push_back(MUTEX_T()); + } + + donorstr.resize(donor_exonic_len + donor_intronic_len); + acceptorstr.resize(acceptor_intronic_len + acceptor_exonic_len); +} + +SpliceSiteDB::~SpliceSiteDB() { + assert_eq(_fwIndex.size(), _bwIndex.size()); + assert_eq(_fwIndex.size(), _pool.size()); + for(uint64_t i = 0; i < _numRefs; i++) { + delete _fwIndex[i]; + delete _bwIndex[i]; + + EList& pool = _pool[i]; + for(size_t j = 0; j < pool.size(); j++) { + delete pool[j]; + } + } +} + +size_t SpliceSiteDB::size(uint64_t ref) const { + if(!_read) return 0; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + assert_lt(ref, _fwIndex.size()); + assert_eq(_fwIndex.size(), _bwIndex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + return _fwIndex.size(); +} + +bool SpliceSiteDB::empty(uint64_t ref) const { + return size(ref) == 0; +} + +bool SpliceSiteDB::addSpliceSite( + const Read& rd, + const AlnRes& rs, + uint32_t minAnchorLen) +{ + if(!_write) return false; + if(rs.trimmed5p(true) + rs.trimmed3p(true) > 0) return false; + + _empty = false; + + Coord coord = rs.refcoord(); + uint64_t ref = coord.ref(); + assert_lt(ref, _numRefs); + const EList& edits = rs.ned(); + if(!coord.orient()) { + Edit::invertPoss(const_cast&>(edits), rd.length(), false); + } + SpliceSitePos ssp; + uint32_t refoff = coord.off(); + uint32_t leftAnchorLen = 0, rightAnchorLen = 0; + size_t eidx = 0; + size_t last_eidx = 0; + uint32_t mm = 0; + for(size_t i = 0; i < rd.length(); i++, refoff++) { + while(eidx < edits.size() && edits[eidx].pos == i) { + if(edits[eidx].isReadGap()) { + refoff++; + } else if(edits[eidx].isRefGap()) { + assert_gt(refoff, 0); + refoff--; + } + if(edits[eidx].isGap() || edits[eidx].isMismatch()) mm++; + if(edits[eidx].isSpliced()) { + assert_gt(refoff, 0); + if(ssp.inited()) { + assert(edits[last_eidx].isSpliced()); + assert_lt(edits[last_eidx].pos, edits[eidx].pos); + rightAnchorLen = edits[eidx].pos - edits[last_eidx].pos; + uint32_t minLeftAnchorLen = minAnchorLen + mm * 2 + (edits[eidx].splDir == EDIT_SPL_UNKNOWN ? 6 : 0); + uint32_t mm2 = 0; + for(size_t j = eidx + 1; j < edits.size(); j++) { + if(edits[j].isGap() || edits[j].isMismatch()) mm2++; + } + uint32_t minRightAnchorLen = minAnchorLen + mm2 * 2 + (edits[eidx].splDir == EDIT_SPL_UNKNOWN ? 6 : 0); + if(leftAnchorLen >= minLeftAnchorLen && rightAnchorLen >= minRightAnchorLen) { + bool added = false; + assert_lt(ref, _mutex.size()); + ThreadSafe t(&_mutex[ref], _threadSafe && _write); + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + Node *cur = _fwIndex[ref]->add(pool(ref), ssp, &added); + if(added) { + assert_lt(ref, _spliceSites.size()); + _spliceSites[ref].expand(); + _spliceSites[ref].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.fw(), ssp.canonical()); + _spliceSites[ref].back()._readid = rd.rdid; + _spliceSites[ref].back()._leftext = leftAnchorLen; + _spliceSites[ref].back()._rightext = rightAnchorLen; + _spliceSites[ref].back()._numreads = 1; + assert(cur != NULL); + cur->payload = _spliceSites[ref].size() - 1; + + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.fw(), ssp.canonical()); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + cur = _bwIndex[ref]->add(pool(ref), rssp, &added); + assert(added); + assert(cur != NULL); + cur->payload = _spliceSites[ref].size() - 1; + assert_eq(_fwIndex[ref]->size(), _bwIndex[ref]->size()); + } else { + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + assert_lt(cur->payload, _spliceSites[ref].size()); + if(leftAnchorLen > _spliceSites[ref][cur->payload]._leftext) _spliceSites[ref][cur->payload]._leftext = leftAnchorLen; + if(rightAnchorLen > _spliceSites[ref][cur->payload]._rightext) _spliceSites[ref][cur->payload]._rightext = rightAnchorLen; + _spliceSites[ref][cur->payload]._numreads += 1; + if(rd.rdid < _spliceSites[ref][cur->payload]._readid) { + _spliceSites[ref][cur->payload]._readid = rd.rdid; + } + } + } + leftAnchorLen = rightAnchorLen; + rightAnchorLen = 0; + } else { + leftAnchorLen = edits[eidx].pos; + } + bool fw = (edits[eidx].splDir == EDIT_SPL_FW || edits[eidx].splDir == EDIT_SPL_UNKNOWN); + bool canonical = (edits[eidx].splDir != EDIT_SPL_UNKNOWN); + ssp.init(coord.ref(), refoff - 1, refoff + edits[eidx].splLen, fw, canonical); + refoff += edits[eidx].splLen; + last_eidx = eidx; + } + eidx++; + } + } + if(ssp.inited()) { + assert(edits[last_eidx].isSpliced()); + assert_lt(edits[last_eidx].pos, rd.length()); + rightAnchorLen = rd.length() - edits[last_eidx].pos; + uint32_t minLeftAnchorLen = minAnchorLen + mm * 2 + (edits[last_eidx].splDir == EDIT_SPL_UNKNOWN ? 6 : 0); + uint32_t mm2 = 0; + for(size_t j = last_eidx + 1; j < edits.size(); j++) { + if(edits[j].isGap() || edits[j].isMismatch()) mm2++; + } + uint32_t minRightAnchorLen = minAnchorLen + mm2 * 2 + (edits[last_eidx].splDir == EDIT_SPL_UNKNOWN ? 6 : 0); + if(leftAnchorLen >= minLeftAnchorLen && rightAnchorLen >= minRightAnchorLen) { + bool added = false; + assert_lt(ref, _mutex.size()); + ThreadSafe t(&_mutex[ref], _threadSafe && _write); + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + Node *cur = _fwIndex[ref]->add(pool(ref), ssp, &added); + if(added) { + assert_lt(ref, _spliceSites.size()); + _spliceSites[ref].expand(); + _spliceSites[ref].back().init(ssp.ref(), ssp.left(), ssp.right(), ssp.fw(), ssp.canonical()); + _spliceSites[ref].back()._readid = rd.rdid; + _spliceSites[ref].back()._leftext = leftAnchorLen; + _spliceSites[ref].back()._rightext = rightAnchorLen; + _spliceSites[ref].back()._numreads = 1; + assert(cur != NULL); + cur->payload = _spliceSites[ref].size() - 1; + + SpliceSitePos rssp(ssp.ref(), ssp.right(), ssp.left(), ssp.fw(), ssp.canonical()); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + cur = _bwIndex[ref]->add(pool(ref), rssp, &added); + assert(added); + assert(cur != NULL); + cur->payload = _spliceSites[ref].size() - 1; + assert_eq(_fwIndex[ref]->size(), _bwIndex[ref]->size()); + } else { + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + assert_lt(cur->payload, _spliceSites[ref].size()); + if(leftAnchorLen > _spliceSites[ref][cur->payload]._leftext) _spliceSites[ref][cur->payload]._leftext = leftAnchorLen; + if(rightAnchorLen > _spliceSites[ref][cur->payload]._rightext) _spliceSites[ref][cur->payload]._rightext = rightAnchorLen; + _spliceSites[ref][cur->payload]._numreads += 1; + if(rd.rdid < _spliceSites[ref][cur->payload]._readid) { + _spliceSites[ref][cur->payload]._readid = rd.rdid; + } + } + } + } + if(!coord.orient()) { + Edit::invertPoss(const_cast&>(edits), rd.length(), false); + } + + return true; +} + +bool SpliceSiteDB::getSpliceSite(SpliceSite& ss) const +{ + if(!_read) return false; + + uint64_t ref = ss.ref(); + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + const Node *cur = _fwIndex[ref]->lookup(ss); + if(cur == NULL) return false; + assert(cur != NULL); + assert_lt(ref, _spliceSites.size()); + ss = _spliceSites[ref][cur->payload]; + return true; +} + +void SpliceSiteDB::getLeftSpliceSites(uint32_t ref, uint32_t left, uint32_t range, EList& spliceSites) const +{ + if(!_read) return; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + assert_gt(range, 0); + assert_geq(left + 1, range); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + const Node *cur = _bwIndex[ref]->root(); + if(cur != NULL) getSpliceSites_recur(cur, ref, left + 1 - range, left, spliceSites); +} + +void SpliceSiteDB::getRightSpliceSites(uint32_t ref, uint32_t right, uint32_t range, EList& spliceSites) const +{ + if(!_read) return; + + assert_lt(ref, _numRefs); + assert_lt(ref, _mutex.size()); + ThreadSafe t(const_cast(&_mutex[ref]), _threadSafe && _write); + assert_gt(range, 0); + assert_gt(right + range, range); + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + const Node *cur = _fwIndex[ref]->root(); + if(cur != NULL) getSpliceSites_recur(cur, ref, right, right + range - 1, spliceSites); + +} + +void SpliceSiteDB::getSpliceSites_recur( + const RedBlackNode *node, + uint32_t ref, + uint32_t left, + uint32_t right, + EList& spliceSites) const +{ + assert(node != NULL); + bool goleft = true, goright = true; + if((node->key.ref() > ref) || + (node->key.ref() == ref && node->key.left() > right)) { + goright = false; + } + + if((node->key.ref() < ref) || + (node->key.ref() == ref && node->key.left() < left)) { + goleft = false; + } + + if(goleft && node->left != NULL) { + getSpliceSites_recur( + node->left, + ref, + left, + right, + spliceSites); + } + + if(node->key.ref() == ref && + node->key.left() >= left && node->key.left() <= right) { + assert_lt(ref, _spliceSites.size()); + assert_lt(node->payload, _spliceSites[ref].size()); +#ifndef NDEBUG + const SpliceSite& ss = _spliceSites[ref][node->payload]; + assert_eq(ss.ref(), node->key.ref()); + assert(ss.left() == node->key.left() || + ss.right() == node->key.left()); +#endif + spliceSites.push_back(_spliceSites[ref][node->payload]); + } + + if(goright && node->right != NULL) { + getSpliceSites_recur( + node->right, + ref, + left, + right, + spliceSites); + } +} + +void calculate_splicesite_read_dist_impl(const RedBlackNode *node, + const EList &spliceSites, + EList& splicesite_read_dist) { + if(node == NULL) return; + calculate_splicesite_read_dist_impl(node->left, spliceSites, splicesite_read_dist); + assert_lt(node->payload, spliceSites.size()); + const SpliceSite& ss = spliceSites[node->payload]; + if(ss.numreads() < splicesite_read_dist.size()) + splicesite_read_dist[ss.numreads()] += 1; + else + splicesite_read_dist.back() += 1; + calculate_splicesite_read_dist_impl(node->right, spliceSites, splicesite_read_dist); +} + +uint32_t calculate_splicesite_read_dist(const EList* >& fwIndex, + const ELList &spliceSites, + EList& splicesite_read_dist) { + for(size_t i = 0; i < fwIndex.size(); i++) { + assert(fwIndex[i] != NULL); + const RedBlackNode *root = fwIndex[i]->root(); + assert_lt(i, spliceSites.size()); + if(root != NULL) calculate_splicesite_read_dist_impl(root, spliceSites[i], splicesite_read_dist); + } + + for(size_t i = 1; i < splicesite_read_dist.size(); i++) { + splicesite_read_dist[i] += splicesite_read_dist[i-1]; + } + + for(size_t i = 0; i < splicesite_read_dist.size(); i++) { + float cmf_i = float(splicesite_read_dist[i]) / splicesite_read_dist.back(); + if(cmf_i > 0.7) + return i; + } + + return 0; +} + +void SpliceSiteDB::print(ofstream& out) +{ + EList splicesite_read_dist; + for(size_t i = 0; i < 100; i++) { + splicesite_read_dist.push_back(0); + } + uint32_t numreads_cutoff = calculate_splicesite_read_dist(_fwIndex, _spliceSites, splicesite_read_dist); + + EList ss_list; + for(size_t i = 0; i < _fwIndex.size(); i++) { + assert(_fwIndex[i] != NULL); + const Node *root = _fwIndex[i]->root(); + if(root != NULL) print_recur(root, out, numreads_cutoff, ss_list); + } + print_impl(out, ss_list); +} + +void SpliceSiteDB::print_recur( + const RedBlackNode *node, + ofstream& out, + const uint32_t numreads_cutoff, + EList& ss_list) +{ + if(node == NULL) return; + print_recur(node->left, out, numreads_cutoff, ss_list); + const SpliceSitePos& ssp = node->key; + assert_lt(ssp.ref(), _spliceSites.size()); + assert_lt(node->payload, _spliceSites[ssp.ref()].size()); + const SpliceSite& ss = _spliceSites[ssp.ref()][node->payload]; + if(ss.numreads() >= numreads_cutoff) print_impl(out, ss_list, &ss); + print_recur(node->right, out, numreads_cutoff, ss_list); +} + +void SpliceSiteDB::print_impl( + ofstream& out, + EList& ss_list, + const SpliceSite* ss) +{ + size_t i = 0; + while(i < ss_list.size()) { + const SpliceSite& tmp_ss = ss_list[i]; + bool do_print = true; + if(ss != NULL) { + if(tmp_ss.ref() == ss->ref()) { + assert_leq(tmp_ss.left(), ss->left()); + if(ss->left() < tmp_ss.left() + 10) { + do_print = false; + if(abs(((int)ss->left() - (int)tmp_ss.left()) - ((int)ss->right() - (int)tmp_ss.right())) <= 10) { + if(tmp_ss.numreads() < ss->numreads()) { + ss_list.erase(i); + ss_list.push_back(*ss); + } + return; + } + } + } + } + + if(!do_print) { + i++; + continue; + } + + assert_lt(tmp_ss.ref(), _refnames.size()); + out << _refnames[tmp_ss.ref()] << "\t" + << tmp_ss.left() << "\t" + << tmp_ss.right() << "\t" + << (tmp_ss.canonical() ? (tmp_ss.fw() ? "+" : "-") : ".") << endl; + + ss_list.erase(i); + } + + if(ss != NULL) ss_list.push_back(*ss); +} + +void SpliceSiteDB::read(ifstream& in, bool novel) +{ + _empty = false; + assert_eq(_numRefs, _refnames.size()); + while(!in.eof()) { + string refname; + uint32_t left = 0, right = 0; + char fw = 0; + in >> refname >> left >> right >> fw; + uint32_t ref = 0; + for(; ref < _refnames.size(); ref++) { + if(_refnames[ref] == refname) break; + } + if(ref >= _numRefs) continue; + assert_lt(ref, _spliceSites.size()); + _spliceSites[ref].expand(); + _spliceSites[ref].back().init(ref, left, right, fw == '+' || fw == '.', fw != '.'); + _spliceSites[ref].back()._fromfile = true; + assert_gt(_spliceSites[ref].size(), 0); + + bool added = false; + assert_lt(ref, _fwIndex.size()); + assert(_fwIndex[ref] != NULL); + Node *cur = _fwIndex[ref]->add(pool(ref), _spliceSites[ref].back(), &added); + assert(added); + assert(cur != NULL); + cur->payload = _spliceSites[ref].size() - 1; + + added = false; + SpliceSitePos rssp(ref, right, left, fw == '+' || fw == '.', fw != '.'); + assert_lt(ref, _bwIndex.size()); + assert(_bwIndex[ref] != NULL); + cur = _bwIndex[ref]->add(pool(ref), rssp, &added); + assert(added); + assert(cur != NULL); + cur->payload = _spliceSites[ref].size() - 1; + } +} + +Pool& SpliceSiteDB::pool(uint64_t ref) { + assert_lt(ref, _numRefs); + assert_lt(ref, _pool.size()); + EList& pool = _pool[ref]; + if(pool.size() <= 0 || pool.back()->full()) { + pool.push_back(new Pool(1 << 20 /* 1MB */, 16 << 10 /* 16KB */, CA_CAT)); + } + assert(pool.back() != NULL); + return *pool.back(); +} + +#endif + +float SpliceSiteDB::probscore( + int64_t donor_seq, + int64_t acceptor_seq) +{ + float probscore = 0.0f; +#if defined(NEW_PROB_MODEL) + float donor_probscore = 0.0f; + assert_leq(donor_seq, 0x3ffff); + int64_t donor_exonic_seq = (donor_seq >> 4) & (~0xff); + int64_t donor_intronic_seq = donor_seq & 0xff; + int64_t donor_rest_seq = donor_exonic_seq | donor_intronic_seq; + int donor_seq3 = (donor_seq >> 10) & 0x3; + int donor_seq4 = (donor_seq >> 8) & 0x3; + donor_probscore = donor_cons1[donor_seq3] * donor_cons2[donor_seq4] / (background_bp_prob[donor_seq3] * background_bp_prob[donor_seq4]) * donor_me2x5[donor_rest_seq]; + + float acceptor_probscore = 0.0f; + assert_leq(acceptor_seq, 0x3fffffffffff); + int64_t acceptor_intronic_seq = (acceptor_seq >> 4) & (~0x3f); + int64_t acceptor_exonic_seq = acceptor_seq & 0x3f; + int64_t acceptor_rest_seq = acceptor_intronic_seq | acceptor_exonic_seq; + int acceptor_seq18 = (acceptor_seq >> 8) & 0x3; + int acceptor_seq19 = (acceptor_seq >> 6) & 0x3; + acceptor_probscore = acceptor_cons1[acceptor_seq18] * acceptor_cons2[acceptor_seq19] / (background_bp_prob[acceptor_seq18] * background_bp_prob[acceptor_seq19]); + + int64_t acceptor_seq1 = acceptor_rest_seq >> 28 & 0x3fff; // [0, 7] + acceptor_probscore *= acceptor_me2x3acc1[acceptor_seq1]; + int64_t acceptor_seq2 = (acceptor_rest_seq >> 14) & 0x3fff; // [7, 7] + acceptor_probscore *= acceptor_me2x3acc2[acceptor_seq2]; + int64_t acceptor_seq3 = acceptor_rest_seq & 0x3fff; // [14, 7] + acceptor_probscore *= acceptor_me2x3acc3[acceptor_seq3]; + int64_t acceptor_seq4 = (acceptor_rest_seq >> 20) & 0x3fff; // [4, 7] + acceptor_probscore *= acceptor_me2x3acc4[acceptor_seq4]; + int64_t acceptor_seq5 = (acceptor_rest_seq >> 6) & 0x3fff; // [11, 7] + acceptor_probscore *= acceptor_me2x3acc5[acceptor_seq5]; + int64_t acceptor_seq6 = acceptor_seq1 & 0x3f; // [4, 3] + acceptor_probscore /= acceptor_me2x3acc6[acceptor_seq6]; + int64_t acceptor_seq7 = acceptor_seq4 & 0xff; // [7, 4] + acceptor_probscore /= acceptor_me2x3acc7[acceptor_seq7]; + int64_t acceptor_seq8 = acceptor_seq2 & 0x3f; // [11, 3] + acceptor_probscore /= acceptor_me2x3acc8[acceptor_seq8]; + int64_t acceptor_seq9 = acceptor_seq5 & 0xff; // [14, 4] + acceptor_probscore /= acceptor_me2x3acc9[acceptor_seq9]; + + donor_probscore /= (1.0f + donor_probscore); + acceptor_probscore /= (1.0f + acceptor_probscore); + probscore = (donor_probscore + acceptor_probscore) / 2.0; + +#else + assert_lt(donor_seq, (int)(1 << (donor_len << 1))); + probscore = donor_prob_sum[donor_seq]; + + int acceptor_seq1 = acceptor_seq >> (acceptor_len2 << 1); + assert_lt(acceptor_seq1, (int)(1 << (acceptor_len1 << 1))); + probscore *= acceptor_prob_sum1[acceptor_seq1]; + + int acceptor_seq2 = acceptor_seq % (1 << (acceptor_len2 << 1)); + probscore *= acceptor_prob_sum2[acceptor_seq2]; + + probscore = 1.0 / (1.0 + probscore); +#endif + return probscore; +} + diff --git a/spliced_aligner.h b/spliced_aligner.h new file mode 100644 index 0000000..0217bf5 --- /dev/null +++ b/spliced_aligner.h @@ -0,0 +1,2054 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +#ifndef SPLICED_ALIGNER_H_ +#define SPLICED_ALIGNER_H_ + +#include "hi_aligner.h" + +/** + * With a hierarchical indexing, SplicedAligner provides several alignment strategies + * , which enable effective alignment of RNA-seq reads + */ +template +class SplicedAligner : public HI_Aligner { + +public: + /** + * Initialize with index. + */ + SplicedAligner( + const GFM& gfm, + bool anchorStop, + uint64_t threads_rids_mindist = 0) : + HI_Aligner(gfm, + anchorStop, + threads_rids_mindist) + { + } + + ~SplicedAligner() { + } + + /** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ + virtual + void hybridSearch( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink); + + /** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ + virtual + int64_t hybridSearch_recur( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + const GenomeHit& hit, + index_t hitoff, + index_t hitlen, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink, + bool alignMate = false, + index_t dep = 0); +}; + +/** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ +template +void SplicedAligner::hybridSearch( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + bool fw, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink) +{ + assert_lt(rdi, 2); + assert(this->_rds[rdi] != NULL); + him.localatts++; + + const ReportingParams& rp = sink.reportingParams(); + + // before further alignment using local search, extend the partial alignments directly + // by comparing with the corresponding genomic sequences + // this extension is performed without any mismatches allowed + for(index_t hi = 0; hi < this->_genomeHits.size(); hi++) { + GenomeHit& genomeHit = this->_genomeHits[hi]; + index_t leftext = (index_t)INDEX_MAX, rightext = (index_t)INDEX_MAX; + genomeHit.extend( + *(this->_rds[rdi]), + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + INDEX_MAX, + tpol, + gpol, + leftext, + rightext); + } + + // for the candidate alignments, examine the longest (best) one first + this->_genomeHits_done.resize(this->_genomeHits.size()); + this->_genomeHits_done.fill(false); + for(size_t hi = 0; hi < this->_genomeHits.size(); hi++) { + index_t hj = 0; + for(; hj < this->_genomeHits.size(); hj++) { + if(!this->_genomeHits_done[hj]) break; + } + if(hj >= this->_genomeHits.size()) break; + for(index_t hk = hj + 1; hk < this->_genomeHits.size(); hk++) { + if(this->_genomeHits_done[hk]) continue; + GenomeHit& genomeHit_j = this->_genomeHits[hj]; + GenomeHit& genomeHit_k = this->_genomeHits[hk]; + if(genomeHit_k.hitcount() > genomeHit_j.hitcount() || + (genomeHit_k.hitcount() == genomeHit_j.hitcount() && genomeHit_k.len() > genomeHit_j.len())) { + hj = hk; + } + } + + // given a candidate partial alignment, extend it bidirectionally + him.anchoratts++; + GenomeHit& genomeHit = this->_genomeHits[hj]; + + int64_t maxsc = std::numeric_limits::min(); + maxsc = hybridSearch_recur(sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + genomeHit, + genomeHit.rdoff(), + genomeHit.len(), + wlm, + prm, + swm, + him, + rnd, + sink); + + if(rp.bowtie2_dp == 2 || (rp.bowtie2_dp == 1 && maxsc < this->_minsc[rdi])) { + const Read& rd = *this->_rds[rdi]; + // Initialize the aligner with a new read + swa.initRead(rd.patFw, // fw version of query + rd.patRc, // rc version of query + rd.qual, // fw version of qualities + rd.qualRev, // rc version of qualities + 0, // off of first char in 'rd' to consider + rd.length(), // off of last char (excl) in 'rd' to consider + sc); // scoring scheme + + bool found = genomeHit.len() >= rd.length(); + if(!found) { + DynProgFramer dpframe(false); // trimToRef + size_t tlen = ref.approxLen(genomeHit.ref()); + size_t readGaps = 10, refGaps = 10, nceil = 0, maxhalf = 10; + index_t refoff = genomeHit.refoff() > genomeHit.rdoff() ? genomeHit.refoff() - genomeHit.rdoff() : 0; + DPRect rect; + dpframe.frameSeedExtensionRect(refoff, // ref offset implied by seed hit assuming no gaps + rd.length(), // length of read sequence used in DP table + tlen, // length of reference + readGaps, // max # of read gaps permitted in opp mate alignment + refGaps, // max # of ref gaps permitted in opp mate alignment + (size_t)nceil, // # Ns permitted + maxhalf, // max width in either direction + rect); // DP rectangle + assert(rect.repOk()); + + size_t cminlen = 2000, cpow2 = 4, nwindow = 10, nsInLeftShift = 0; + swa.initRef(fw, // whether to align forward or revcomp read + genomeHit.ref(), // reference aligned against + rect, // DP rectangle + ref, // Reference strings + tlen, // length of reference sequence + sc, // scoring scheme + this->_minsc[rdi], // minimum score permitted + true, // use 8-bit SSE if possible? + cminlen, // minimum length for using checkpointing scheme + cpow2, // interval b/t checkpointed diags; 1 << this + false, // triangular mini-fills? + true, // this is a seed extension - not finding a mate + nwindow, + nsInLeftShift); + + // Now fill the dynamic programming matrix and return true iff + // there is at least one valid alignment + TAlScore bestCell = std::numeric_limits::min(); + found = swa.align(rnd, bestCell); + if(found) { + SwResult res; + res.reset(); + res.alres.init_raw_edits(&(this->_rawEdits)); + found = swa.nextAlignment(res, this->_minsc[rdi], rnd); + if(found) { + if(!fw) res.alres.invertEdits(); + + const Coord& coord = res.alres.refcoord(); + assert_geq(genomeHit._joinedOff + coord.off(), genomeHit.refoff()); + index_t joinedOff = genomeHit._joinedOff + coord.off() - genomeHit.refoff(); + genomeHit.init(fw, + 0, // rdoff + rd.length(), + 0, // trim5 + 0, // trim3 + coord.ref(), + coord.off(), + joinedOff, + this->_sharedVars, + genomeHit.repeat(), // repeat? + &res.alres.ned(), + NULL, + res.alres.score().score()); + + genomeHit.replace_edits_with_alts(rd, + altdb.alts(), + ssdb, + sc, + this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + (index_t)tpol.minAnchorLen(), + (index_t)tpol.minAnchorLen_noncan(), + ref); + + } + } + } + + if(found) { + hybridSearch_recur(sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + genomeHit, + genomeHit.rdoff(), + genomeHit.len(), + wlm, + prm, + swm, + him, + rnd, + sink); + } + } + this->_genomeHits_done[hj] = true; + } +} + + +/** + * Given a partial alignment of a read, try to further extend + * the alignment bidirectionally using a combination of + * local search, extension, and global search + */ +template +int64_t SplicedAligner::hybridSearch_recur( + const Scoring& sc, + const PairedEndPolicy& pepol, // paired-end policy + const TranscriptomePolicy& tpol, + const GraphPolicy& gpol, + const GFM& gfm, + const ALTDB& altdb, + const RepeatDB& repeatdb, + const BitPairReference& ref, + SwAligner& swa, + SpliceSiteDB& ssdb, + index_t rdi, + const GenomeHit& hit, + index_t hitoff, + index_t hitlen, + WalkMetrics& wlm, + PerReadMetrics& prm, + SwMetrics& swm, + HIMetrics& him, + RandomSource& rnd, + AlnSinkWrap& sink, + bool alignMate, + index_t dep) +{ + const ReportingParams& rp = sink.reportingParams(); + int64_t maxsc = numeric_limits::min(); + him.localsearchrecur++; + assert_lt(rdi, 2); + assert(this->_rds[rdi] != NULL); + const Read& rd = *(this->_rds[rdi]); + index_t rdlen = (index_t)rd.length(); + + TAlScore cushion = 0; + if(tpol.no_spliced_alignment()) { + cushion = alignMate ? rdlen * 0.03 * sc.mm(255) : 0; + } + + if(hit.score() + cushion < this->_minsc[rdi]) return maxsc; + if(dep >= 128) return maxsc; + + // if it's already examined, just return + if(hitoff == hit.rdoff() - hit.trim5() && hitlen == hit.len() + hit.trim5() + hit.trim3()) { + if(this->isSearched(hit, rdi)) return maxsc; + this->addSearched(hit, rdi); + } + + // for effective use of memory allocation and deallocation + if(this->_coords.size() <= dep) { + this->_coords.expand(); + assert_leq(this->_local_genomeHits.size(), dep); + this->_local_genomeHits.expand(); + assert_leq(this->_spliceSites.size(), dep); + this->_spliceSites.expand(); + } + EList& coords = this->_coords[dep]; + EList& spliceSites = this->_spliceSites[dep]; + + // daehwan - for debugging purposes +#if 0 + cout << rd.name << "\t" + << (hit.fw() ? "+" : "-") << "\t" + << hitoff << "\t" + << hitoff + hitlen << "\t" + << "( " << hit.rdoff() << "\t" + << hit.rdoff() + hit.len() << " )" << "\t" + << hit.refoff() << "\t" + << hit.getRightOff() << "\t" + << hit.score() << "\t" + << "dep: " << dep << "\t"; + Edit::print(cout, hit.edits()); + cout << endl; +#endif + + assert_leq(hitoff + hitlen, rdlen); + // if this is a full alignment, report it + if(hitoff == 0 && hitlen == rdlen) { + if(!this->redundant(sink, rdi, hit)) { + bool another_spliced = false; + if(!ssdb.empty()) { + int64_t best_score = hit.score(); + this->_local_genomeHits[dep].clear(); + this->_anchors_added.clear(); + + this->_local_genomeHits[dep].expand(); + this->_local_genomeHits[dep].back() = hit; + this->_anchors_added.push_back(0); + + index_t fragoff = 0, fraglen = 0, left = 0, right = 0; + hit.getLeft(fragoff, fraglen, left); + const index_t minMatchLen = (index_t)this->_minK; + index_t min_left_anchor = rdlen, min_right_anchor = rdlen; + // make use of a list of known or novel splice sites to further align the read + if(fraglen >= minMatchLen && + left >= minMatchLen && + hit.trim5() == 0 && + !hit.repeat() && + !tpol.no_spliced_alignment()) { + spliceSites.clear(); + ssdb.getLeftSpliceSites(hit.ref(), left + minMatchLen, minMatchLen, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(!ss._fromfile && ss._readid + this->_thread_rids_mindist > rd.rdid) continue; + if(left + fraglen - 1 < ss.right()) continue; + index_t frag2off = ss.left() - (ss.right() - left); + if(frag2off + 1 < hitoff) continue; + GenomeHit tempHit; + if(fragoff + ss.right() < left + 1) continue; + index_t readoff = fragoff + ss.right() - left - 1; + index_t joinedOff = 0; + bool success = gfm.textOffToJoined(hit.ref(), ss.left(), joinedOff); + if(!success) { + continue; + } +#ifndef NDEBUG + index_t debug_tid = 0, debug_toff = 0, debug_tlen = 0; + bool debug_straddled = false; + gfm.joinedToTextOff(1, // qlen + joinedOff, + debug_tid, + debug_toff, + debug_tlen, + false, + debug_straddled); + assert_eq(hit.ref(), debug_tid); + assert_eq(ss.left(), debug_toff); +#endif + tempHit.init(hit.fw(), + readoff + 1, // rdoff + 0, // len + 0, // trim5 + 0, // trim3 + hit.ref(), + ss.left() + 1, + joinedOff + 1, + this->_sharedVars, + gfm.repeat()); + index_t leftext = readoff + 1, rightext = 0; + tempHit.extend(rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + if(tempHit.len() <= 0) + continue; + if(!tempHit.compatibleWith( + hit, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + tpol.no_spliced_alignment())) + continue; + int64_t minsc = max(this->_minsc[rdi], best_score); + bool combined = tempHit.combineWith( + hit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + 1, + 1, + gpol.maxAltsTried(), + &ss, + tpol.no_spliced_alignment()); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + index_t leftAnchorLen = 0, nedits = 0; + tempHit.getLeftAnchor(leftAnchorLen, nedits); + if(combined && + tempHit.score() >= minsc && + nedits <= leftAnchorLen / 4) { // prevent (short) anchors from having many mismatches + if(this->isSearched(tempHit, rdi)) continue; + if(!this->redundant(sink, rdi, tempHit)) { + another_spliced = true; + if(tempHit.score() > best_score) + best_score = tempHit.score(); + this->_local_genomeHits[dep].expand(); + this->_local_genomeHits[dep].back() = tempHit; + this->_anchors_added.push_back(1); + index_t temp_fragoff = 0, temp_fraglen = 0, temp_left = 0; + tempHit.getLeft(temp_fragoff, temp_fraglen, temp_left); + if(temp_fraglen < min_left_anchor) + min_left_anchor = temp_fraglen; + } + } + } + } + + size_t num_local_genomeHits = this->_local_genomeHits[dep].size(); + for(size_t i = 0; i < num_local_genomeHits; i++) { + this->_local_genomeHits[dep][i].getRight(fragoff, fraglen, right); + if(this->_local_genomeHits[dep][i].score() < best_score) continue; + // make use of a list of known or novel splice sites to further align the read + if(fraglen >= minMatchLen && + this->_local_genomeHits[dep][i].trim3() == 0 && + !hit.repeat() && + !tpol.no_spliced_alignment()) { + spliceSites.clear(); + assert_gt(fraglen, 0); + ssdb.getRightSpliceSites(this->_local_genomeHits[dep][i].ref(), right + fraglen - minMatchLen, minMatchLen, spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const GenomeHit& canHit = this->_local_genomeHits[dep][i]; + const SpliceSite& ss = spliceSites[si]; + if(!ss._fromfile && ss._readid + this->_thread_rids_mindist > rd.rdid) continue; + if(right > ss.left()) continue; + GenomeHit tempHit; + index_t readoff = fragoff + ss.left() - right + 1; + if(readoff >= rdlen) + continue; + index_t joinedOff = 0; + bool success = gfm.textOffToJoined(canHit.ref(), ss.right(), joinedOff); + if(!success) { + continue; + } +#ifndef NDEBUG + index_t debug_tid = 0, debug_toff = 0, debug_tlen = 0; + bool debug_straddled = false; + gfm.joinedToTextOff(1, // qlen + joinedOff, + debug_tid, + debug_toff, + debug_tlen, + false, + debug_straddled); + assert_eq(canHit.ref(), debug_tid); + assert_eq(ss.right(), debug_toff); +#endif + tempHit.init(canHit.fw(), + readoff, + 0, // len + 0, // trim5 + 0, // trim3 + canHit.ref(), + ss.right(), + joinedOff, + this->_sharedVars, + gfm.repeat()); + index_t leftext = 0, rightext = rdlen - readoff; + tempHit.extend(rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + if(tempHit.len() <= 0) + continue; + if(!canHit.compatibleWith(tempHit, (index_t)tpol.minIntronLen(), (index_t)tpol.maxIntronLen(), tpol.no_spliced_alignment())) continue; + GenomeHit combinedHit = canHit; + int64_t minsc = max(this->_minsc[rdi], best_score); + bool combined = combinedHit.combineWith( + tempHit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + 1, + 1, + gpol.maxAltsTried(), + &ss, + tpol.no_spliced_alignment()); + if(rdi == 0) minsc = max(minsc, sink.bestUnp1()); + else minsc = max(minsc, sink.bestUnp2()); + index_t rightAnchorLen = 0, nedits = 0; + combinedHit.getRightAnchor(rightAnchorLen, nedits); + if(combined && + combinedHit.score() >= minsc && + nedits <= rightAnchorLen / 4) { // prevent (short) anchors from having many mismatches + if(this->isSearched(combinedHit, rdi)) continue; + if(!this->redundant(sink, rdi, combinedHit)) { + another_spliced = true; + if(combinedHit.score() > best_score) + best_score = tempHit.score(); + this->_local_genomeHits[dep].expand(); + this->_local_genomeHits[dep].back() = combinedHit; + this->_anchors_added.push_back(this->_anchors_added[i] + 1); + + index_t temp_fragoff = 0, temp_fraglen = 0, temp_right = 0; + combinedHit.getLeft(temp_fragoff, temp_fraglen, temp_right); + if(temp_fraglen < min_right_anchor) + min_right_anchor = temp_fraglen; + } + } + } + } + } + + assert_eq(this->_local_genomeHits[dep].size(), this->_anchors_added.size()); + for(size_t i = 0; i < this->_local_genomeHits[dep].size(); i++) { + const GenomeHit& canHit = this->_local_genomeHits[dep][i]; + if(!rp.secondary && canHit.score() < best_score) continue; + // if(min(min_left_anchor, min_right_anchor) <= this->_minK_local) { + + // daehwan - for debugging purposes + // if(this->_anchors_added[i] < this->_anchors_added.back()) continue; + + //} + if(i > 0 && !this->isSearched(canHit, rdi)) { + this->addSearched(canHit, rdi); + } + if(!this->redundant(sink, rdi, canHit)) { + this->reportHit(sc, pepol, tpol, gpol, gfm, altdb, repeatdb, ref, ssdb, sink, rdi, canHit, alignMate); + maxsc = max(maxsc, canHit.score()); + } + } + } + else { + this->reportHit(sc, pepol, tpol, gpol, gfm, altdb, repeatdb, ref, ssdb, sink, rdi, hit, alignMate); + maxsc = max(maxsc, hit.score()); + } + return maxsc; + } + } else if(hitoff > 0 && (hitoff + hitlen == rdlen || hitoff + hitoff < rdlen - hitlen)) { + // Decide which side to extend first (left or right) + if(!ssdb.empty()) { + // extend the partial alignment in the left direction + index_t fragoff = 0, fraglen = 0, left = 0; + hit.getLeft(fragoff, fraglen, left); + const index_t minMatchLen = (index_t)this->_minK_local; + // make use of a list of known or novel splice sites to further align the read + if(fraglen >= minMatchLen && + left >= minMatchLen && + !hit.repeat() && + !tpol.no_spliced_alignment()) { + spliceSites.clear(); + ssdb.getLeftSpliceSites(hit.ref(), left + minMatchLen, minMatchLen + min(minMatchLen, fragoff), spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(!ss._fromfile && ss._readid + this->_thread_rids_mindist > rd.rdid) continue; + if(left + fraglen - 1 < ss.right()) continue; + if(fragoff + ss.right() < left + 1) continue; + index_t readoff = fragoff + ss.right() - left - 1; + index_t joinedOff = 0; + bool success = gfm.textOffToJoined(hit.ref(), ss.left(), joinedOff); + if(!success) { + continue; + } +#ifndef NDEBUG + index_t debug_tid = 0, debug_toff = 0, debug_tlen = 0; + bool debug_straddled = false; + gfm.joinedToTextOff(1, // qlen + joinedOff, + debug_tid, + debug_toff, + debug_tlen, + false, + debug_straddled); + assert_eq(hit.ref(), debug_tid); + assert_eq(ss.left(), debug_toff); +#endif + GenomeHit tempHit; + tempHit.init(hit.fw(), + readoff + 1, // rdoff + 0, // len + 0, // trim5 + 0, // trim3 + hit.ref(), + ss.left() + 1, + joinedOff + 1, + this->_sharedVars, + gfm.repeat()); + index_t leftext = readoff + 1, rightext = 0; + tempHit.extend(rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + if(tempHit.len() <= 0) + continue; + if(!tempHit.compatibleWith(hit, (index_t)tpol.minIntronLen(), (index_t)tpol.maxIntronLen(), tpol.no_spliced_alignment())) continue; + int64_t minsc = this->_minsc[rdi]; + bool combined = tempHit.combineWith( + hit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + 1, + 1, + gpol.maxAltsTried(), + &ss, + tpol.no_spliced_alignment()); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(combined && + tempHit.score() >= minsc && + // soft-clipping might be better + tempHit.score() + sc.sc(0) * hit.rdoff() >= hit.score()) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } + + bool use_localindex = true; + if(hitoff == hit.rdoff() && hitoff <= this->_minK) { + index_t leftext = (index_t)INDEX_MAX, rightext = (index_t)0; + GenomeHit tempHit = hit; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext, + 1); + if(tempHit.rdoff() == 0) { + use_localindex = false; + } + } + + // Choose a local index based on the genomic location of the partial alignment + const HGFM* hGFM = (const HGFM*)(&gfm); + const LocalGFM* lGFM = hGFM->getLocalGFM(hit.ref(), hit.refoff()); + assert_leq(lGFM->_localOffset, hit.refoff()); + bool success = false, first = true; + index_t count = 0; + // Use at most two local indexes + const index_t max_count = 2; + int64_t prev_score = hit.score(); + this->_local_genomeHits[dep].clear(); + while(!success && count++ < max_count && use_localindex) { + if(him.localindexatts >= this->max_localindexatts) break; + if(first) { + first = false; + } else { + lGFM = hGFM->prevLocalGFM(lGFM); + if(lGFM == NULL || lGFM->empty()) break; + } + // local index search + index_t extlen = 0; + local_index_t top = (local_index_t)INDEX_MAX, bot = (local_index_t)INDEX_MAX; + local_index_t node_top = (local_index_t)INDEX_MAX, node_bot = (local_index_t)INDEX_MAX; + index_t extoff = hitoff - 1; + if(extoff > 0) extoff -= 1; + if(extoff < tpol.minAnchorLen()) { + extoff = tpol.minAnchorLen(); + } + index_t nelt = (index_t)INDEX_MAX; + index_t max_nelt = std::max(5, extlen); + bool no_extension = false; + bool uniqueStop= false; + index_t minUniqueLen = (index_t)this->_minK_local; + for(; extoff < rdlen; extoff++) { + extlen = 0; + uniqueStop = true; + him.localindexatts++; + this->_local_node_iedge_count.clear(); + nelt = this->localGFMSearch( + *lGFM, // BWT index + rd, // read to align + sc, // scoring scheme + sink.reportingParams(), + hit.fw(), + extoff, + extlen, + top, + bot, + node_top, + node_bot, + this->_local_node_iedge_count, + rnd, + uniqueStop, + minUniqueLen); + if(extoff + 1 - extlen >= hitoff) { + no_extension = true; + break; + } + if(nelt <= max_nelt) break; + } + assert_leq(node_top, node_bot); + assert_eq(nelt, (index_t)(node_bot - node_top)); + assert_leq(extlen, extoff + 1); + if(nelt > 0 && + nelt <= max_nelt && + extlen >= tpol.minAnchorLen() && + !no_extension) { + assert_leq(nelt, max_nelt); + coords.clear(); + bool straddled = false; + // get genomic locations for this local search + this->getGenomeCoords_local( + *lGFM, + altdb, + ref, + rnd, + top, + bot, + node_top, + node_bot, + this->_local_node_iedge_count, + hit.fw(), + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled? + straddled); + assert_leq(coords.size(), nelt); + coords.sort(); + for(int ri = (int)coords.size() - 1; ri >= 0; ri--) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + (index_t)coord.ref(), + (index_t)coord.off(), + (index_t)coord.joinedOff(), + this->_sharedVars, + gfm.repeat()); + if(!tempHit.adjustWithALT(*this->_rds[rdi], gfm, altdb, ref, gpol)) continue; + // check if the partial alignment is compatible with the new alignment using the local index + if(!tempHit.compatibleWith(hit, (index_t)tpol.minIntronLen(), (index_t)tpol.maxIntronLen(), tpol.no_spliced_alignment())) { + if(count == 1) continue; + else break; + } + if(uniqueStop) { + assert_eq(coords.size(), 1); + index_t leftext = (index_t)INDEX_MAX, rightext = (index_t)0; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + } + // combine the partial alignment and the new alignment + int64_t minsc = this->_minsc[rdi]; + bool combined = tempHit.combineWith( + hit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + tpol.minAnchorLen(), + tpol.minAnchorLen_noncan(), + gpol.maxAltsTried(), + NULL, // splice sites + tpol.no_spliced_alignment()); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(combined && tempHit.score() >= minsc) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + if(tempHit.score() >= prev_score - sc.mmpMax) { + // extend the new partial alignment recursively + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } else { + this->_local_genomeHits[dep].push_back(tempHit); + } + } + } + } + if(maxsc >= prev_score - sc.mmpMax) success = true; + if(!success && + (him.localindexatts >= this->max_localindexatts || count == max_count || hGFM->prevLocalGFM(lGFM) == NULL)) { + for(index_t ti = 0; ti < this->_local_genomeHits[dep].size(); ti++) { + GenomeHit& tempHit = this->_local_genomeHits[dep][ti]; + int64_t minsc = this->_minsc[rdi]; + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(tempHit.score() >= minsc) { + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } // while(!success && count++ < 2) + + if(!success) { + if(hitoff > this->_minK && + him.localindexatts < this->max_localindexatts) { + index_t extlen = 0; + index_t top = (index_t)INDEX_MAX, bot = (index_t)INDEX_MAX; + index_t node_top = (index_t)INDEX_MAX, node_bot = (index_t)INDEX_MAX; + this->_node_iedge_count.clear(); + index_t extoff = hitoff - 1; + bool uniqueStop = true; + // perform global search for long introns + index_t nelt = this->globalGFMSearch( + gfm, // GFM index + rd, // read to align + sc, // scoring scheme + sink.reportingParams(), + hit.fw(), + extoff, + extlen, + top, + bot, + node_top, + node_bot, + this->_node_iedge_count, + rnd, + uniqueStop); + if(nelt > 0 && nelt <= 5 && extlen >= this->_minK) { + coords.clear(); + bool straddled = false; + this->getGenomeCoords( + gfm, + altdb, + ref, + rnd, + top, + bot, + node_top, + node_bot, + this->_node_iedge_count, + hit.fw(), + bot - top, + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled? + straddled); + assert_leq(coords.size(), nelt); + if(coords.size() > 1) coords.sort(); + for(int ri = (int)coords.size() - 1; ri >= 0; ri--) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + (index_t)coord.ref(), + (index_t)coord.off(), + (index_t)coord.joinedOff(), + this->_sharedVars, + gfm.repeat()); + if(!tempHit.adjustWithALT(*this->_rds[rdi], gfm, altdb, ref, gpol)) continue; + if(!tempHit.compatibleWith(hit, (index_t)tpol.minIntronLen(), (index_t)tpol.maxIntronLen(), tpol.no_spliced_alignment())) continue; + if(uniqueStop) { + assert_eq(coords.size(), 1); + index_t leftext = (index_t)INDEX_MAX, rightext = (index_t)0; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + } + int64_t minsc = this->_minsc[rdi]; + bool combined = tempHit.combineWith( + hit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + tpol.minAnchorLen(), + tpol.minAnchorLen_noncan(), + gpol.maxAltsTried(), + NULL, // splice sites + tpol.no_spliced_alignment()); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(combined && tempHit.score() >= minsc) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } + GenomeHit tempHit = hit; + index_t trimMax = (index_t)((tempHit.score() - max(maxsc, this->_minsc[rdi])) / sc.sc(0)); + if(tempHit.rdoff() < trimMax) { + index_t trim5 = tempHit.rdoff(); + GenomeHit trimedHit = tempHit; + trimedHit.trim5(trim5, + rd, + ssdb, + sc, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + tpol.minAnchorLen(), + tpol.minAnchorLen_noncan(), + ref); + assert_leq(trimedHit.len() + trimedHit.trim5() + trimedHit.trim3(), rdlen); + int64_t tmp_score = trimedHit.score(); + if(tmp_score > maxsc && tmp_score >= this->_minsc[rdi]) { + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + trimedHit, + 0, + trimedHit.len() + trimedHit.trim5() + trimedHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + // return maxsc; + } + } + // extend the partial alignment directly comparing with the corresponding genomic sequence + // with mismatches or a gap allowed + int64_t minsc = this->_minsc[rdi]; + assert_geq(tempHit.score(), minsc); + index_t mm = (index_t)((tempHit.score() - minsc) / sc.mmpMax); + index_t leftext = (index_t)INDEX_MAX, rightext = (index_t)0; + index_t num_mismatch_allowed = 1; + if(hitoff <= this->_minK_local) { + num_mismatch_allowed = min(tempHit.rdoff(), mm); + } + him.localextatts++; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext, + num_mismatch_allowed); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(tempHit.score() >= minsc && leftext >= min((index_t)this->_minK_local, hit.rdoff())) { + assert_eq(tempHit.trim5(), 0); + assert_leq(tempHit.rdoff() + tempHit.len() + tempHit.trim3(), rdlen); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff(), + tempHit.len() + tempHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } else if(hitoff > this->_minK_local) { + // skip some bases of a read + index_t jumplen = hitoff > this->_minK ? (index_t)this->_minK : (index_t)this->_minK_local; + assert_leq(hitoff, hit.rdoff()); + int64_t expected_score = hit.score() - (hit.rdoff() - hitoff) / jumplen * sc.mmpMax - sc.mmpMax; + if(expected_score >= minsc) { + assert_lt(hitlen + jumplen, rdlen); + assert_eq(hit.trim5(), 0); + assert_leq(hitoff + hitlen, rdlen); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + hit, + hitoff - jumplen, + hitlen + jumplen, + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } else { + // extend the partial alignment in the right direction + assert_lt(hitoff + hitlen, rdlen); + if(!ssdb.empty()) { + index_t fragoff = 0, fraglen = 0, right = 0; + hit.getRight(fragoff, fraglen, right); + const index_t minMatchLen = (index_t)this->_minK_local; + // make use of a list of known or novel splice sites to further align the read + if(fraglen >= minMatchLen && + !hit.repeat() && + !tpol.no_spliced_alignment()) { + spliceSites.clear(); + assert_gt(fraglen, 0); + assert_leq(fragoff + fraglen, rdlen); + index_t right_unmapped_len = rdlen - fragoff - fraglen; + ssdb.getRightSpliceSites(hit.ref(), right + fraglen - minMatchLen, minMatchLen + min(minMatchLen, right_unmapped_len), spliceSites); + for(size_t si = 0; si < spliceSites.size(); si++) { + const SpliceSite& ss = spliceSites[si]; + if(!ss._fromfile && ss._readid + this->_thread_rids_mindist > rd.rdid) continue; + if(right > ss.left()) continue; + GenomeHit tempHit; + assert_leq(right, ss.left()); + index_t readoff = fragoff + ss.left() - right + 1; + if(readoff >= rdlen) + continue; + index_t joinedOff = 0; + bool success = gfm.textOffToJoined(hit.ref(), ss.right(), joinedOff); + if(!success) { + continue; + } +#ifndef NDEBUG + index_t debug_tid = 0, debug_toff = 0, debug_tlen = 0; + bool debug_straddled = false; + gfm.joinedToTextOff(1, // qlen + joinedOff, + debug_tid, + debug_toff, + debug_tlen, + false, + debug_straddled); + assert_eq(hit.ref(), debug_tid); + assert_eq(ss.right(), debug_toff); +#endif + tempHit.init(hit.fw(), + readoff, + 0, // len + 0, // trim5 + 0, // trim3 + hit.ref(), + ss.right(), + joinedOff, + this->_sharedVars, + gfm.repeat()); + index_t leftext = 0, rightext = rdlen - readoff; + tempHit.extend(rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + if(tempHit.len() <= 0) + continue; + if(!hit.compatibleWith(tempHit, (index_t)tpol.minIntronLen(), (index_t)tpol.maxIntronLen(), tpol.no_spliced_alignment())) continue; + GenomeHit combinedHit = hit; + int64_t minsc = this->_minsc[rdi]; + bool combined = combinedHit.combineWith( + tempHit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + 1, + 1, + gpol.maxAltsTried(), + &ss, + tpol.no_spliced_alignment()); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(combined && combinedHit.score() >= minsc && + // soft-clipping might be better + combinedHit.score() + sc.sc(0) * (rdlen - hit.rdoff() - hit.len() - hit.trim5()) >= hit.score()) { + assert_leq(combinedHit.trim5(), combinedHit.rdoff()); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + combinedHit, + combinedHit.rdoff() - combinedHit.trim5(), + combinedHit.len() + combinedHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } + + bool use_localindex = true; + if(hit.len() == hitlen && hitoff + hitlen + this->_minK > rdlen) { + index_t leftext = (index_t)0, rightext = (index_t)INDEX_MAX; + GenomeHit tempHit = hit; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext, + 1); + if(tempHit.rdoff() + tempHit.len()== rdlen) { + use_localindex = false; + } + } + + // Choose a local index based on the genomic location of the partial alignment + const HGFM* hGFM = (const HGFM*)(&gfm); + const LocalGFM* lGFM = hGFM->getLocalGFM(hit.ref(), hit.refoff()); + bool success = false, first = true; + index_t count = 0; + // Use at most two local indexes + const index_t max_count = 2; + int64_t prev_score = hit.score(); + this->_local_genomeHits[dep].clear(); + while(!success && count++ < max_count && use_localindex) { + if(him.localindexatts >= this->max_localindexatts) break; + if(first) { + first = false; + } else { + lGFM = hGFM->nextLocalGFM(lGFM); + if(lGFM == NULL || lGFM->empty()) break; + } + // local index search + index_t extlen = 0; + local_index_t top = (local_index_t)INDEX_MAX, bot = (local_index_t)INDEX_MAX; + local_index_t node_top = (local_index_t)INDEX_MAX, node_bot = (local_index_t)INDEX_MAX; + index_t extoff = hitoff + hitlen + (index_t)this->_minK_local; + if(extoff + 1 < rdlen) extoff += 1; + if(extoff >= rdlen) { + extoff = rdlen - 1; + } + index_t nelt = (index_t)INDEX_MAX; + index_t max_nelt = std::max(5, extlen); + bool no_extension = false; + bool uniqueStop; + index_t minUniqueLen = (index_t)this->_minK_local; + index_t maxHitLen = max(extoff - hitoff - hitlen, (index_t)this->_minK_local); + for(; maxHitLen < extoff + 1 && extoff < rdlen;) { + extlen = 0; + uniqueStop = false; + him.localindexatts++; + this->_local_node_iedge_count.clear(); + nelt = this->localGFMSearch( + *lGFM, // GFM index + rd, // read to align + sc, // scoring scheme + sink.reportingParams(), + hit.fw(), + extoff, + extlen, + top, + bot, + node_top, + node_bot, + this->_local_node_iedge_count, + rnd, + uniqueStop, + minUniqueLen, + maxHitLen); + if(extoff < hitoff + hitlen) { + no_extension = true; + break; + } + if(nelt <= max_nelt) break; + if(extoff + 1 < rdlen) extoff++; + else { + if(extlen < maxHitLen) break; + else maxHitLen++; + } + } + assert_leq(node_top, node_bot); + assert_eq(nelt, (index_t)(node_bot - node_top)); + assert_leq(extlen, extoff + 1); + assert_leq(extoff, rdlen); + if(nelt > 0 && + nelt <= max_nelt && + extlen >= tpol.minAnchorLen() && + !no_extension) { + assert_leq(nelt, max_nelt); + coords.clear(); + bool straddled = false; + // get genomic locations for this local search + this->getGenomeCoords_local( + *lGFM, + altdb, + ref, + rnd, + top, + bot, + node_top, + node_bot, + this->_local_node_iedge_count, + hit.fw(), + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled? + straddled); + assert_leq(coords.size(), nelt); + if(coords.size() > 1) coords.sort(); + for(index_t ri = 0; ri < coords.size(); ri++) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + (index_t)coord.ref(), + (index_t)coord.off(), + (index_t)coord.joinedOff(), + this->_sharedVars, + gfm.repeat()); + if(!tempHit.adjustWithALT(*this->_rds[rdi], gfm, altdb, ref, gpol)) continue; + // check if the partial alignment is compatible with the new alignment using the local index + if(!hit.compatibleWith(tempHit, (index_t)tpol.minIntronLen(), (index_t)tpol.maxIntronLen(), tpol.no_spliced_alignment())) { + if(count == 1) continue; + else break; + } + index_t leftext = (index_t)0, rightext = (index_t)INDEX_MAX; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + GenomeHit combinedHit = hit; + int64_t minsc = this->_minsc[rdi]; + // combine the partial alignment and the new alignment + bool combined = combinedHit.combineWith( + tempHit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + tpol.minAnchorLen(), + tpol.minAnchorLen_noncan(), + gpol.maxAltsTried(), + NULL, // splice sites + tpol.no_spliced_alignment()); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(combined && combinedHit.score() >= minsc) { + assert_leq(combinedHit.trim5(), combinedHit.rdoff()); + if(combinedHit.score() >= prev_score - sc.mmpMax) { + // extend the new partial alignment recursively + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + combinedHit, + combinedHit.rdoff() - combinedHit.trim5(), + combinedHit.len() + combinedHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } else { + this->_local_genomeHits[dep].push_back(combinedHit); + } + } + } + } + // int64_t minsc = (rdi == 0 ? sink.bestUnp1() : sink.bestUnp2()); + if(maxsc >= prev_score - sc.mmpMax) success = true; + if(!success && + (him.localindexatts >= this->max_localindexatts || count == max_count || hGFM->nextLocalGFM(lGFM) == NULL) ) { + for(index_t ti = 0; ti < this->_local_genomeHits[dep].size(); ti++) { + GenomeHit& tempHit = this->_local_genomeHits[dep][ti]; + int64_t minsc = this->_minsc[rdi]; + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(tempHit.score() >= minsc) { + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff() - tempHit.trim5(), + tempHit.len() + tempHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } // while(!success && count++ < 2) + + if(!success) { + // perform global search for long introns + if(hitoff + hitlen + this->_minK + 1 < rdlen && + him.localindexatts < this->max_localindexatts) { + index_t extlen = 0; + index_t top = (index_t)INDEX_MAX, bot = (index_t)INDEX_MAX; + index_t node_top = (index_t)INDEX_MAX, node_bot = (index_t)INDEX_MAX; + this->_node_iedge_count.clear(); + index_t extoff = hitoff + hitlen + (index_t)this->_minK + 1; + bool uniqueStop = true; + index_t nelt = this->globalGFMSearch( + gfm, // GFM index + rd, // read to align + sc, // scoring scheme + sink.reportingParams(), + hit.fw(), + extoff, + extlen, + top, + bot, + node_top, + node_bot, + this->_node_iedge_count, + rnd, + uniqueStop); + if(nelt > 0 && nelt <= 5 && extlen >= this->_minK) { + coords.clear(); + bool straddled = false; + this->getGenomeCoords( + gfm, + altdb, + ref, + rnd, + top, + bot, + node_top, + node_bot, + this->_node_iedge_count, + hit.fw(), + bot - top, + extoff + 1 - extlen, + extlen, + coords, + wlm, + prm, + him, + true, // reject straddled + straddled); + assert_leq(coords.size(), nelt); + coords.sort(); + for(index_t ri = 0; ri < coords.size(); ri++) { + const Coord& coord = coords[ri]; + GenomeHit tempHit; + tempHit.init(coord.orient(), + extoff + 1 - extlen, + extlen, + 0, // trim5 + 0, // trim3 + (index_t)coord.ref(), + (index_t)coord.off(), + (index_t)coord.joinedOff(), + this->_sharedVars, + gfm.repeat()); + if(!tempHit.adjustWithALT(*this->_rds[rdi], gfm, altdb, ref, gpol)) continue; + if(!hit.compatibleWith(tempHit, (index_t)tpol.minIntronLen(), (index_t)tpol.maxIntronLen(), tpol.no_spliced_alignment())) continue; + index_t leftext = (index_t)0, rightext = (index_t)INDEX_MAX; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext); + GenomeHit combinedHit = hit; + int64_t minsc = this->_minsc[rdi]; + bool combined = combinedHit.combineWith( + tempHit, + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + sc, + minsc, + rnd, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + tpol.minAnchorLen(), + tpol.minAnchorLen_noncan(), + gpol.maxAltsTried(), + NULL, // splice sites + tpol.no_spliced_alignment()); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + if(combined && combinedHit.score() >= minsc) { + assert_leq(combinedHit.trim5(), combinedHit.rdoff()); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + combinedHit, + combinedHit.rdoff() - combinedHit.trim5(), + combinedHit.len() + combinedHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } + GenomeHit tempHit = hit; + assert(tempHit.trim5() == 0 || hitoff == 0); + index_t trimLen = rdlen - hitoff - tempHit.len() - tempHit.trim5(); + index_t trimMax = (index_t)((tempHit.score() - max(maxsc, this->_minsc[rdi])) / sc.sc(0)); + if(trimLen < trimMax) { + index_t trim3 = rdlen - hitoff - tempHit.len() - tempHit.trim5(); + GenomeHit trimedHit = tempHit; + trimedHit.trim3(trim3, + rd, + ssdb, + sc, + (index_t)this->_minK_local, + (index_t)tpol.minIntronLen(), + (index_t)tpol.maxIntronLen(), + tpol.minAnchorLen(), + tpol.minAnchorLen_noncan(), + ref); + assert_leq(trimedHit.trim5(), trimedHit.rdoff()); + assert_leq(trimedHit.len() + trimedHit.trim5() + trimedHit.trim3(), rdlen); + int64_t tmp_score = trimedHit.score(); + if(tmp_score > maxsc && tmp_score >= this->_minsc[rdi]) { + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + trimedHit, + trimedHit.rdoff() - trimedHit.trim5(), + trimedHit.len() + trimedHit.trim5() + trimedHit.trim3(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + // return maxsc; + } + } + // extend the partial alignment directly comparing with the corresponding genomic sequence + // with mismatches or a gap allowed + int64_t minsc = this->_minsc[rdi]; + assert_geq(tempHit.score(), minsc); + index_t leftext = (index_t)0, rightext = (index_t)INDEX_MAX; + index_t mm = (index_t)((tempHit.score() - minsc) / sc.mmpMax); + index_t num_mismatch_allowed = 1; + if(rdlen - hitoff - hitlen <= this->_minK_local) { + num_mismatch_allowed = min(rdlen - tempHit.rdoff() - tempHit.len(), mm); + } + him.localextatts++; + tempHit.extend( + rd, + gfm, + ref, + altdb, + repeatdb, + ssdb, + swa, + swm, + prm, + sc, + this->_minsc[rdi], + rnd, + (index_t)this->_minK_local, + tpol, + gpol, + leftext, + rightext, + num_mismatch_allowed); + if(!rp.secondary) { + if(rdi == 0) minsc = max(minsc, sink.bestUnp1() - cushion); + else minsc = max(minsc, sink.bestUnp2() - cushion); + } + + if(tempHit.score() >= minsc && rightext >= min((index_t)this->_minK_local, rdlen - hit.len() - hit.rdoff())) { + assert_eq(tempHit.trim3(), 0); + assert_leq(tempHit.trim5(), tempHit.rdoff()); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + tempHit, + tempHit.rdoff() - tempHit.trim5(), + tempHit.len() + tempHit.trim5(), + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } else if(hitoff + hitlen + this->_minK_local < rdlen) { + // skip some bases of a read + index_t jumplen = hitoff + hitlen + this->_minK < rdlen ? (index_t)this->_minK : (index_t)this->_minK_local; + assert_lt(hitoff + hitlen + jumplen, rdlen); + assert_leq(hit.len(), hitlen); + int64_t expected_score = hit.score() - (hitlen - hit.len()) / jumplen * sc.mmpMax - sc.mmpMax; + if(expected_score >= minsc) { + assert_eq(hit.trim3(), 0); + int64_t tmp_maxsc = hybridSearch_recur( + sc, + pepol, + tpol, + gpol, + gfm, + altdb, + repeatdb, + ref, + swa, + ssdb, + rdi, + hit, + hitoff, + hitlen + jumplen, + wlm, + prm, + swm, + him, + rnd, + sink, + alignMate, + dep + 1); + maxsc = max(maxsc, tmp_maxsc); + } + } + } + } + + return maxsc; +} + +#endif /*SPLICED_ALIGNER_H_*/ diff --git a/sse_util.cpp b/sse_util.cpp new file mode 100644 index 0000000..d6310cf --- /dev/null +++ b/sse_util.cpp @@ -0,0 +1,33 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "sse_util.h" +#include "aligner_swsse.h" +#include "limit.h" + +/** + * Given a column of filled-in cells, save the checkpointed cells in cs_. + */ +void Checkpointer::commitCol( + __m128i *pvH, + __m128i *pvE, + __m128i *pvF, + size_t coli) +{ +} diff --git a/sse_util.h b/sse_util.h new file mode 100644 index 0000000..b5781f1 --- /dev/null +++ b/sse_util.h @@ -0,0 +1,574 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SSE_UTIL_H_ +#define SSE_UTIL_H_ + +#include "assert_helpers.h" +#include "ds.h" +#include "limit.h" +#include +#include + +class EList_m128i { +public: + + /** + * Allocate initial default of S elements. + */ + explicit EList_m128i(int cat = 0) : + cat_(cat), last_alloc_(NULL), list_(NULL), sz_(0), cur_(0) + { + assert_geq(cat, 0); + } + + /** + * Destructor. + */ + ~EList_m128i() { free(); } + + /** + * Return number of elements. + */ + inline size_t size() const { return cur_; } + + /** + * Return number of elements allocated. + */ + inline size_t capacity() const { return sz_; } + + /** + * Ensure that there is sufficient capacity to expand to include + * 'thresh' more elements without having to expand. + */ + inline void ensure(size_t thresh) { + if(list_ == NULL) lazyInit(); + expandCopy(cur_ + thresh); + } + + /** + * Ensure that there is sufficient capacity to include 'newsz' elements. + * If there isn't enough capacity right now, expand capacity to exactly + * equal 'newsz'. + */ + inline void reserveExact(size_t newsz) { + if(list_ == NULL) lazyInitExact(newsz); + expandCopyExact(newsz); + } + + /** + * Return true iff there are no elements. + */ + inline bool empty() const { return cur_ == 0; } + + /** + * Return true iff list hasn't been initialized yet. + */ + inline bool null() const { return list_ == NULL; } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. + */ + void resize(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) { + expandCopy(sz); + } + cur_ = sz; + } + + /** + * Zero out contents of vector. + */ + void zero() { + if(cur_ > 0) { + memset(list_, 0, cur_ * sizeof(__m128i)); + } + } + + /** + * If size is less than requested size, resize up to at least sz + * and set cur_ to requested sz. Do not copy the elements over. + */ + void resizeNoCopy(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInit(); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) { + expandNoCopy(sz); + } + cur_ = sz; + } + + /** + * If size is less than requested size, resize up to exactly sz and set + * cur_ to requested sz. + */ + void resizeExact(size_t sz) { + if(sz > 0 && list_ == NULL) lazyInitExact(sz); + if(sz <= cur_) { + cur_ = sz; + return; + } + if(sz_ < sz) expandCopyExact(sz); + cur_ = sz; + } + + /** + * Make the stack empty. + */ + void clear() { + cur_ = 0; // re-use stack memory + // Don't clear heap; re-use it + } + + /** + * Return a reference to the ith element. + */ + inline __m128i& operator[](size_t i) { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline __m128i operator[](size_t i) const { + assert_lt(i, cur_); + return list_[i]; + } + + /** + * Return a reference to the ith element. + */ + inline __m128i& get(size_t i) { + return operator[](i); + } + + /** + * Return a reference to the ith element. + */ + inline __m128i get(size_t i) const { + return operator[](i); + } + + /** + * Return a pointer to the beginning of the buffer. + */ + __m128i *ptr() { return list_; } + + /** + * Return a const pointer to the beginning of the buffer. + */ + const __m128i *ptr() const { return list_; } + + /** + * Return memory category. + */ + int cat() const { return cat_; } + +private: + + /** + * Initialize memory for EList. + */ + void lazyInit() { + assert(list_ == NULL); + list_ = alloc(sz_); + } + + /** + * Initialize exactly the prescribed number of elements for EList. + */ + void lazyInitExact(size_t sz) { + assert_gt(sz, 0); + assert(list_ == NULL); + sz_ = sz; + list_ = alloc(sz); + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + __m128i *alloc(size_t sz) { + __m128i* last_alloc_; + try { + last_alloc_ = new __m128i[sz + 2]; + } catch(std::bad_alloc& e) { + std::cerr << "Error: Out of memory allocating " << sz << " __m128i's for DP matrix: '" << e.what() << "'" << std::endl; + throw e; + } + __m128i* tmp = last_alloc_; + size_t tmpint = (size_t)tmp; + // Align it! + if((tmpint & 0xf) != 0) { + tmpint += 15; + tmpint &= (~0xf); + tmp = reinterpret_cast<__m128i*>(tmpint); + } + assert_eq(0, (tmpint & 0xf)); // should be 16-byte aligned + assert(tmp != NULL); + gMemTally.add(cat_, sz); + return tmp; + } + + /** + * Allocate a T array of length sz_ and store in list_. Also, + * tally into the global memory tally. + */ + void free() { + if(list_ != NULL) { + delete[] last_alloc_; + gMemTally.del(cat_, sz_); + list_ = NULL; + sz_ = cur_ = 0; + } + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. Size + * increases quadratically with number of expansions. Copy old contents + * into new buffer using operator=. + */ + void expandCopy(size_t thresh) { + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + expandCopyExact(newsz); + } + + /** + * Expand the list_ buffer until it has exactly 'newsz' elements. Copy + * old contents into new buffer using operator=. + */ + void expandCopyExact(size_t newsz) { + if(newsz <= sz_) return; + __m128i* tmp = alloc(newsz); + assert(tmp != NULL); + size_t cur = cur_; + if(list_ != NULL) { + for(size_t i = 0; i < cur_; i++) { + // Note: operator= is used + tmp[i] = list_[i]; + } + free(); + } + list_ = tmp; + sz_ = newsz; + cur_ = cur; + } + + /** + * Expand the list_ buffer until it has at least 'thresh' elements. + * Size increases quadratically with number of expansions. Don't copy old + * contents into the new buffer. + */ + void expandNoCopy(size_t thresh) { + assert(list_ != NULL); + if(thresh <= sz_) return; + size_t newsz = (sz_ * 2)+1; + while(newsz < thresh) newsz *= 2; + expandNoCopyExact(newsz); + } + + /** + * Expand the list_ buffer until it has exactly 'newsz' elements. Don't + * copy old contents into the new buffer. + */ + void expandNoCopyExact(size_t newsz) { + assert(list_ != NULL); + assert_gt(newsz, 0); + free(); + __m128i* tmp = alloc(newsz); + assert(tmp != NULL); + list_ = tmp; + sz_ = newsz; + assert_gt(sz_, 0); + } + + int cat_; // memory category, for accounting purposes + __m128i* last_alloc_; // what new[] originally returns + __m128i *list_; // list ptr, aligned version of what new[] returns + size_t sz_; // capacity + size_t cur_; // occupancy (AKA size) +}; + +struct CpQuad { + CpQuad() { reset(); } + + void reset() { sc[0] = sc[1] = sc[2] = sc[3] = 0; } + + bool operator==(const CpQuad& o) const { + return sc[0] == o.sc[0] && + sc[1] == o.sc[1] && + sc[2] == o.sc[2] && + sc[3] == o.sc[3]; + } + + int16_t sc[4]; +}; + +/** + * Encapsulates a collection of checkpoints. Assumes the scheme is to + * checkpoint adjacent pairs of anti-diagonals. + */ +class Checkpointer { + +public: + + Checkpointer() { reset(); } + + /** + * Set the checkpointer up for a new rectangle. + */ + void init( + size_t nrow, // # of rows + size_t ncol, // # of columns + size_t perpow2, // checkpoint every 1 << perpow2 diags (& next) + int64_t perfectScore, // what is a perfect score? for sanity checks + bool is8, // 8-bit? + bool doTri, // triangle shaped? + bool local, // is alignment local? for sanity checks + bool debug) // gather debug checkpoints? + { + assert_gt(perpow2, 0); + nrow_ = nrow; + ncol_ = ncol; + perpow2_ = perpow2; + per_ = 1 << perpow2; + lomask_ = ~(0xffffffff << perpow2); + perf_ = perfectScore; + local_ = local; + ndiag_ = (ncol + nrow - 1 + 1) / per_; + locol_ = MAX_SIZE_T; + hicol_ = MIN_SIZE_T; +// debug_ = debug; + debug_ = true; + commitMap_.clear(); + firstCommit_ = true; + size_t perword = (is8 ? 16 : 8); + is8_ = is8; + niter_ = ((nrow_ + perword - 1) / perword); + if(doTri) { + // Save a pair of anti-diagonals every per_ anti-diagonals for + // backtrace purposes + qdiag1s_.resize(ndiag_ * nrow_); + qdiag2s_.resize(ndiag_ * nrow_); + } else { + // Save every per_ columns and rows for backtrace purposes + qrows_.resize((nrow_ / per_) * ncol_); + qcols_.resize((ncol_ / per_) * (niter_ << 2)); + } + if(debug_) { + // Save all columns for debug purposes + qcolsD_.resize(ncol_ * (niter_ << 2)); + } + } + + /** + * Return true iff we've been collecting debug cells. + */ + bool debug() const { return debug_; } + + /** + * Check whether the given score matches the saved score at row, col, hef. + */ + int64_t debugCell(size_t row, size_t col, int hef) const { + assert(debug_); + const __m128i* ptr = qcolsD_.ptr() + hef; + // Fast forward to appropriate column + ptr += ((col * niter_) << 2); + size_t mod = row % niter_; // which m128i + size_t div = row / niter_; // offset into m128i + // Fast forward to appropriate word + ptr += (mod << 2); + // Extract score + int16_t sc = (is8_ ? ((uint8_t*)ptr)[div] : ((int16_t*)ptr)[div]); + int64_t asc = MIN_I64; + // Convert score + if(is8_) { + if(local_) { + asc = sc; + } else { + if(sc == 0) asc = MIN_I64; + else asc = sc - 0xff; + } + } else { + if(local_) { + asc = sc + 0x8000; + } else { + if(sc != MIN_I16) asc = sc - 0x7fff; + } + } + return asc; + } + + /** + * Return true iff the given row/col is checkpointed. + */ + bool isCheckpointed(size_t row, size_t col) const { + assert_leq(col, hicol_); + assert_geq(col, locol_); + size_t mod = (row + col) & lomask_; + assert_lt(mod, per_); + return mod >= per_ - 2; + } + + /** + * Return the checkpointed H, E, or F score from the given cell. + */ + inline int64_t scoreTriangle(size_t row, size_t col, int hef) const { + assert(isCheckpointed(row, col)); + bool diag1 = ((row + col) & lomask_) == per_ - 2; + size_t off = (row + col) >> perpow2_; + if(diag1) { + if(qdiag1s_[off * nrow_ + row].sc[hef] == MIN_I16) { + return MIN_I64; + } else { + return qdiag1s_[off * nrow_ + row].sc[hef]; + } + } else { + if(qdiag2s_[off * nrow_ + row].sc[hef] == MIN_I16) { + return MIN_I64; + } else { + return qdiag2s_[off * nrow_ + row].sc[hef]; + } + } + } + + /** + * Return the checkpointed H, E, or F score from the given cell. + */ + inline int64_t scoreSquare(size_t row, size_t col, int hef) const { + // Is it in a checkpointed row? Note that checkpointed rows don't + // necessarily have the horizontal contributions calculated, so we want + // to use the column info in that case. + if((row & lomask_) == lomask_ && hef != 1) { + int64_t sc = qrows_[(row >> perpow2_) * ncol_ + col].sc[hef]; + if(sc == MIN_I16) return MIN_I64; + return sc; + } + hef--; + if(hef == -1) hef = 2; + // It must be in a checkpointed column + assert_eq(lomask_, (col & lomask_)); + // Fast forward to appropriate column + const __m128i* ptr = qcols_.ptr() + hef; + ptr += (((col >> perpow2_) * niter_) << 2); + size_t mod = row % niter_; // which m128i + size_t div = row / niter_; // offset into m128i + // Fast forward to appropriate word + ptr += (mod << 2); + // Extract score + int16_t sc = (is8_ ? ((uint8_t*)ptr)[div] : ((int16_t*)ptr)[div]); + int64_t asc = MIN_I64; + // Convert score + if(is8_) { + if(local_) { + asc = sc; + } else { + if(sc == 0) asc = MIN_I64; + else asc = sc - 0xff; + } + } else { + if(local_) { + asc = sc + 0x8000; + } else { + if(sc != MIN_I16) asc = sc - 0x7fff; + } + } + return asc; + } + + /** + * Given a column of filled-in cells, save the checkpointed cells in cs_. + */ + void commitCol(__m128i *pvH, __m128i *pvE, __m128i *pvF, size_t coli); + + /** + * Reset the state of the Checkpointer. + */ + void reset() { + perpow2_ = per_ = lomask_ = nrow_ = ncol_ = 0; + local_ = false; + niter_ = ndiag_ = locol_ = hicol_ = 0; + perf_ = 0; + firstCommit_ = true; + is8_ = debug_ = false; + } + + /** + * Return true iff the Checkpointer has been initialized. + */ + bool inited() const { + return nrow_ > 0; + } + + size_t per() const { return per_; } + size_t perpow2() const { return perpow2_; } + size_t lomask() const { return lomask_; } + size_t locol() const { return locol_; } + size_t hicol() const { return hicol_; } + size_t nrow() const { return nrow_; } + size_t ncol() const { return ncol_; } + + const CpQuad* qdiag1sPtr() const { return qdiag1s_.ptr(); } + const CpQuad* qdiag2sPtr() const { return qdiag2s_.ptr(); } + + size_t perpow2_; // 1 << perpow2_ - 2 is the # of uncheckpointed + // anti-diags between checkpointed anti-diag pairs + size_t per_; // 1 << perpow2_ + size_t lomask_; // mask for extracting low bits + size_t nrow_; // # rows in current rectangle + size_t ncol_; // # cols in current rectangle + int64_t perf_; // perfect score + bool local_; // local alignment? + + size_t ndiag_; // # of double-diags + + size_t locol_; // leftmost column committed + size_t hicol_; // rightmost column committed + + // Map for committing scores from vector columns to checkpointed diagonals + EList commitMap_; + bool firstCommit_; + + EList qdiag1s_; // checkpoint H/E/F values for diagonal 1 + EList qdiag2s_; // checkpoint H/E/F values for diagonal 2 + + EList qrows_; // checkpoint H/E/F values for rows + + // We store columns in this way to reduce overhead of populating them + bool is8_; // true -> fill used 8-bit cells + size_t niter_; // # __m128i words per column + EList_m128i qcols_; // checkpoint E/F/H values for select columns + + bool debug_; // get debug checkpoints? (i.e. fill qcolsD_?) + EList_m128i qcolsD_; // checkpoint E/F/H values for all columns (debug) +}; + +#endif diff --git a/sstring.cpp b/sstring.cpp new file mode 100644 index 0000000..3b26587 --- /dev/null +++ b/sstring.cpp @@ -0,0 +1,202 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifdef MAIN_SSTRING + +#include +#include +#include "ds.h" +#include "sstring.h" + +using namespace std; + +int main(void) { + cerr << "Test inter-class comparison operators..."; + { + SString s(2); + s.set('a', 0); + s.set('b', 1); + assert(sstr_eq(s, (const char *)"ab")); + assert(!sstr_neq(s, (const char *)"ab")); + assert(!sstr_lt(s, (const char *)"ab")); + assert(!sstr_gt(s, (const char *)"ab")); + assert(sstr_leq(s, (const char *)"ab")); + assert(sstr_geq(s, (const char *)"ab")); + + SStringExpandable s2; + s2.append('a'); + s2.append('b'); + assert(sstr_eq(s, s2)); + assert(sstr_eq(s2, (const char *)"ab")); + assert(!sstr_neq(s, s2)); + assert(!sstr_neq(s2, (const char *)"ab")); + assert(!sstr_lt(s, s2)); + assert(!sstr_lt(s2, (const char *)"ab")); + assert(!sstr_gt(s, s2)); + assert(!sstr_gt(s2, (const char *)"ab")); + assert(sstr_leq(s, s2)); + assert(sstr_leq(s2, (const char *)"ab")); + assert(sstr_geq(s, s2)); + assert(sstr_geq(s2, (const char *)"ab")); + + SStringFixed s3; + s3.append('a'); + s3.append('b'); + assert(sstr_eq(s, s3)); + assert(sstr_eq(s2, s3)); + assert(sstr_eq(s3, (const char *)"ab")); + assert(!sstr_neq(s, s3)); + assert(!sstr_neq(s2, s3)); + assert(!sstr_neq(s3, (const char *)"ab")); + assert(!sstr_lt(s, s3)); + assert(!sstr_lt(s2, s3)); + assert(!sstr_lt(s3, (const char *)"ab")); + assert(!sstr_gt(s, s3)); + assert(!sstr_gt(s2, s3)); + assert(!sstr_gt(s3, (const char *)"ab")); + assert(sstr_geq(s, s3)); + assert(sstr_geq(s2, s3)); + assert(sstr_geq(s3, (const char *)"ab")); + assert(sstr_leq(s, s3)); + assert(sstr_leq(s2, s3)); + assert(sstr_leq(s3, (const char *)"ab")); + } + cerr << "PASSED" << endl; + + cerr << "Test flag for whether to consider end-of-word < other chars ..."; + { + SString ss("String"); + SString sl("String1"); + assert(sstr_lt(ss, sl)); + assert(sstr_gt(ss, sl, false)); + assert(sstr_leq(ss, sl)); + assert(sstr_geq(ss, sl, false)); + } + cerr << "PASSED" << endl; + + cerr << "Test toZBuf and toZBufXForm ..."; + { + SString s(10); + for(int i = 0; i < 10; i++) { + s[i] = (uint32_t)i; + } + assert(strcmp(s.toZBufXForm("0123456789"), "0123456789") == 0); + } + cerr << "PASSED" << endl; + + cerr << "Test S2bDnaString ..."; + { + const char *str = + "ACGTACGTAC" "ACGTACGTAC" "ACGTACGTAC" + "ACGTACGTAC" "ACGTACGTAC" "ACGTACGTAC"; + const char *gs = + "GGGGGGGGGG" "GGGGGGGGGG" "GGGGGGGGGG" + "GGGGGGGGGG" "GGGGGGGGGG" "GGGGGGGGGG"; + for(size_t i = 0; i < 60; i++) { + S2bDnaString s(str, i, true); + S2bDnaString sr; + BTDnaString s2(str, i, true); + assert(sstr_eq(s, s2)); + if(i >= 10) { + BTDnaString s3; + s.windowGetDna(s3, true, false, 3, 4); + assert(sstr_eq(s3.toZBuf(), (const char*)"TACG")); + s.windowGetDna(s3, false, false, 3, 4); + assert(sstr_eq(s3.toZBuf(), (const char*)"CGTA")); + assert_eq('A', s.toChar(0)); + assert_eq('G', s.toChar(2)); + assert_eq('A', s.toChar(4)); + assert_eq('G', s.toChar(6)); + assert_eq('A', s.toChar(8)); + + s.reverseWindow(1, 8); + s2.reverseWindow(1, 8); + + assert_eq('A', s.toChar(1)); + assert_eq('T', s.toChar(2)); + assert_eq('G', s.toChar(3)); + assert_eq('C', s.toChar(4)); + assert_eq('A', s.toChar(5)); + assert_eq('T', s.toChar(6)); + assert_eq('G', s.toChar(7)); + assert_eq('C', s.toChar(8)); + assert(sstr_eq(s, s2)); + + s.reverseWindow(1, 8); + s2.reverseWindow(1, 8); + assert(sstr_eq(s, s2)); + } + if(i > 1) { + s.reverse(); + sr.installReverseChars(str, i); + s2.reverse(); + assert(sstr_eq(s, s2)); + assert(sstr_eq(sr, s2)); + s.reverse(); + sr.reverse(); + assert(sstr_neq(s, s2)); + assert(sstr_neq(sr, s2)); + s.fill(2); + s2.reverse(); + assert(sstr_leq(s, gs)); + assert(sstr_gt(s, s2)); + assert(sstr_gt(s, sr)); + s2.fill(2); + sr.fill(2); + assert(sstr_eq(s, s2)); + assert(sstr_eq(s, sr)); + } + } + S2bDnaString s(str, true); + S2bDnaString sr; + BTDnaString s2(str, true); + assert(sstr_eq(s2.toZBuf(), str)); + assert(sstr_eq(s, s2)); + s.reverse(); + sr.installReverseChars(str); + s2.reverse(); + assert(sstr_eq(s, s2)); + assert(sstr_eq(sr, s2)); + s.reverse(); + sr.reverse(); + assert(sstr_neq(s, s2)); + assert(sstr_neq(sr, s2)); + } + cerr << "PASSED" << endl; + + cerr << "Test operator=() ..."; + { + S2bDnaString s; + s.installChars(string("gtcagtca")); + assert(sstr_eq(s.toZBuf(), (const char *)"GTCAGTCA")); + } + cerr << "PASSED" << endl; + + cerr << "Conversions from string ..."; + { + SStringExpandable se(string("hello")); + EList > sel; + sel.push_back(SStringExpandable(string("hello"))); + } + cerr << "PASSED" << endl; + + cerr << "PASSED" << endl; +} + +#endif /*def MAIN_SSTRING*/ diff --git a/sstring.h b/sstring.h new file mode 100644 index 0000000..c907901 --- /dev/null +++ b/sstring.h @@ -0,0 +1,3454 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef SSTRING_H_ +#define SSTRING_H_ + +#include +#include +#include "assert_helpers.h" +#include "alphabet.h" +#include "random_source.h" + +/** + * Four kinds of strings defined here: + * + * SString: + * A fixed-length string using heap memory with size set at construction time + * or when install() member is called. + * + * S2bDnaString: + * Like SString, but stores a list uint32_t words where each word is divided + * into 16 2-bit slots interpreted as holding one A/C/G/T nucleotide each. + * + * TODO: S3bDnaString allowing N. S4bDnaString allowing nucleotide masks. + * + * SStringExpandable: + * A string using heap memory where the size of the backing store is + * automatically resized as needed. Supports operations like append, insert, + * erase, etc. + * + * SStringFixed: + * A fixed-length string using stack memory where size is set at compile + * time. + * + * All string classes have some extra facilities that make it easy to print the + * string, including when the string uses an encoded alphabet. See toZBuf() + * and toZBufXForm(). + * + * Global lt, eq, and gt template functions are supplied. They are capable of + * doing lexicographical comparisons between any of the three categories of + * strings defined here. + */ + +template +class Class_sstr_len { +public: + static inline size_t sstr_len(const T& s) { + return s.length(); + } +}; + +template +class Class_sstr_len { +public: + static inline size_t sstr_len(const char s[N]) { + return strlen(s); + } +}; + +template<> +class Class_sstr_len { +public: + static inline size_t sstr_len(const char *s) { + return strlen(s); + } +}; + +template<> +class Class_sstr_len { +public: + static inline size_t sstr_len(const unsigned char *s) { + return strlen((const char *)s); + } +}; + +template +static inline bool sstr_eq(const T1& s1, const T2& s2) { + size_t len1 = Class_sstr_len::sstr_len(s1); + size_t len2 = Class_sstr_len::sstr_len(s2); + if(len1 != len2) return false; + for(size_t i = 0; i < len1; i++) { + if(s1[i] != s2[i]) return false; + } + return true; +} + +template +static inline bool sstr_neq(const T1& s1, const T2& s2) { + return !sstr_eq(s1, s2); +} + +/** + * Return true iff the given suffix of s1 is equal to the given suffix of s2 up + * to upto characters. + */ +template +static inline bool sstr_suf_upto_eq( + const T1& s1, size_t suf1, + const T2& s2, size_t suf2, + size_t upto, + bool endlt = true) +{ + assert_leq(suf1, Class_sstr_len::sstr_len(s1)); + assert_leq(suf2, Class_sstr_len::sstr_len(s2)); + size_t len1 = Class_sstr_len::sstr_len(s1) - suf1; + size_t len2 = Class_sstr_len::sstr_len(s2) - suf2; + if(len1 > upto) len1 = upto; + if(len2 > upto) len2 = upto; + if(len1 != len2) return false; + for(size_t i = 0; i < len1; i++) { + if(s1[suf1+i] != s2[suf2+i]) { + return false; + } + } + return true; +} + +/** + * Return true iff the given suffix of s1 is equal to the given suffix of s2 up + * to upto characters. + */ +template +static inline bool sstr_suf_upto_neq( + const T1& s1, size_t suf1, + const T2& s2, size_t suf2, + size_t upto, + bool endlt = true) +{ + return !sstr_suf_upto_eq(s1, suf1, s2, suf2, upto, endlt); +} + +/** + * Return true iff s1 is less than s2. + */ +template +static inline bool sstr_lt(const T1& s1, const T2& s2, bool endlt = true) { + size_t len1 = Class_sstr_len::sstr_len(s1); + size_t len2 = Class_sstr_len::sstr_len(s2); + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] < s2[i]) { + return true; + } else if(s1[i] > s2[i]) { + return false; + } + } + if(len1 == len2) return false; + return (len1 < len2) == endlt; +} + +/** + * Return true iff the given suffix of s1 is less than the given suffix of s2. + */ +template +static inline bool sstr_suf_lt( + const T1& s1, size_t suf1, + const T2& s2, size_t suf2, + bool endlt = true) +{ + assert_leq(suf1, Class_sstr_len::sstr_len(s1)); + assert_leq(suf2, Class_sstr_len::sstr_len(s2)); + size_t len1 = Class_sstr_len::sstr_len(s1) - suf1; + size_t len2 = Class_sstr_len::sstr_len(s2) - suf2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[suf1+i] < s2[suf2+i]) { + return true; + } else if(s1[suf1+i] > s2[suf2+i]) { + return false; + } + } + if(len1 == len2) return false; + return (len1 < len2) == endlt; +} + +/** + * Return true iff the given suffix of s1 is less than the given suffix of s2. + * Treat s1 and s2 as though they have lengths len1/len2. + */ +template +static inline bool sstr_suf_lt( + const T1& s1, size_t suf1, size_t len1, + const T2& s2, size_t suf2, size_t len2, + bool endlt = true) +{ + assert_leq(suf1, len1); + assert_leq(suf2, len2); + size_t left1 = len1 - suf1; + size_t left2 = len2 - suf2; + size_t minleft = (left1 < left2 ? left1 : left2); + for(size_t i = 0; i < minleft; i++) { + if(s1[suf1+i] < s2[suf2+i]) { + return true; + } else if(s1[suf1+i] > s2[suf2+i]) { + return false; + } + } + if(left1 == left2) return false; + return (left1 < left2) == endlt; +} + +/** + * Return true iff the given suffix of s1 is less than the given suffix of s2 + * up to upto characters. + */ +template +static inline bool sstr_suf_upto_lt( + const T1& s1, size_t suf1, + const T2& s2, size_t suf2, + size_t upto, + bool endlt = true) +{ + assert_leq(suf1, Class_sstr_len::sstr_len(s1)); + assert_leq(suf2, Class_sstr_len::sstr_len(s2)); + size_t len1 = Class_sstr_len::sstr_len(s1) - suf1; + size_t len2 = Class_sstr_len::sstr_len(s2) - suf2; + if(len1 > upto) len1 = upto; + if(len2 > upto) len2 = upto; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[suf1+i] < s2[suf2+i]) { + return true; + } else if(s1[suf1+i] > s2[suf2+i]) { + return false; + } + } + if(len1 == len2) return false; + return (len1 < len2) == endlt; +} + +/** + * Return true iff the given prefix of s1 is less than the given prefix of s2. + */ +template +static inline bool sstr_pre_lt( + const T1& s1, size_t pre1, + const T2& s2, size_t pre2, + bool endlt = true) +{ + assert_leq(pre1, Class_sstr_len::sstr_len(s1)); + assert_leq(pre2, Class_sstr_len::sstr_len(s2)); + size_t len1 = pre1; + size_t len2 = pre2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] < s2[i]) { + return true; + } else if(s1[i] > s2[i]) { + return false; + } + } + if(len1 == len2) return false; + return (len1 < len2) == endlt; +} + +/** + * Return true iff s1 is less than or equal to s2. + */ +template +static inline bool sstr_leq(const T1& s1, const T2& s2, bool endlt = true) { + size_t len1 = Class_sstr_len::sstr_len(s1); + size_t len2 = Class_sstr_len::sstr_len(s2); + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] < s2[i]) { + return true; + } else if(s1[i] > s2[i]) { + return false; + } + } + if(len1 == len2) return true; + return (len1 < len2) == endlt; +} + +/** + * Return true iff the given suffix of s1 is less than or equal to the given + * suffix of s2. + */ +template +static inline bool sstr_suf_leq( + const T1& s1, size_t suf1, + const T2& s2, size_t suf2, + bool endlt = true) +{ + assert_leq(suf1, Class_sstr_len::sstr_len(s1)); + assert_leq(suf2, Class_sstr_len::sstr_len(s2)); + size_t len1 = Class_sstr_len::sstr_len(s1) - suf1; + size_t len2 = Class_sstr_len::sstr_len(s2) - suf2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[suf1+i] < s2[suf2+i]) { + return true; + } else if(s1[suf1+i] > s2[suf2+i]) { + return false; + } + } + if(len1 == len2) return true; + return (len1 < len2) == endlt; +} + +/** + * Return true iff the given prefix of s1 is less than or equal to the given + * prefix of s2. + */ +template +static inline bool sstr_pre_leq( + const T1& s1, size_t pre1, + const T2& s2, size_t pre2, + bool endlt = true) +{ + assert_leq(pre1, Class_sstr_len::sstr_len(s1)); + assert_leq(pre2, Class_sstr_len::sstr_len(s2)); + size_t len1 = pre1; + size_t len2 = pre2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] < s2[i]) { + return true; + } else if(s1[i] > s2[i]) { + return false; + } + } + if(len1 == len2) return true; + return (len1 < len2) == endlt; +} + +/** + * Return true iff s1 is greater than s2. + */ +template +static inline bool sstr_gt(const T1& s1, const T2& s2, bool endlt = true) { + size_t len1 = Class_sstr_len::sstr_len(s1); + size_t len2 = Class_sstr_len::sstr_len(s2); + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] > s2[i]) { + return true; + } else if(s1[i] < s2[i]) { + return false; + } + } + if(len1 == len2) return false; + return (len1 > len2) == endlt; +} + +/** + * Return true iff the given suffix of s1 is greater than the given suffix of + * s2. + */ +template +static inline bool sstr_suf_gt( + const T1& s1, size_t suf1, + const T2& s2, size_t suf2, + bool endlt = true) +{ + assert_leq(suf1, Class_sstr_len::sstr_len(s1)); + assert_leq(suf2, Class_sstr_len::sstr_len(s2)); + size_t len1 = Class_sstr_len::sstr_len(s1) - suf1; + size_t len2 = Class_sstr_len::sstr_len(s2) - suf2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[suf1+i] > s2[suf2+i]) { + return true; + } else if(s1[suf1+i] < s2[suf2+i]) { + return false; + } + } + if(len1 == len2) return false; + return (len1 > len2) == endlt; +} + +/** + * Return true iff the given prefix of s1 is greater than the given prefix of + * s2. + */ +template +static inline bool sstr_pre_gt( + const T1& s1, size_t pre1, + const T2& s2, size_t pre2, + bool endlt = true) +{ + assert_leq(pre1, Class_sstr_len::sstr_len(s1)); + assert_leq(pre2, Class_sstr_len::sstr_len(s2)); + size_t len1 = pre1; + size_t len2 = pre2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] > s2[i]) { + return true; + } else if(s1[i] < s2[i]) { + return false; + } + } + if(len1 == len2) return false; + return (len1 > len2) == endlt; +} + +/** + * Return true iff s1 is greater than or equal to s2. + */ +template +static inline bool sstr_geq(const T1& s1, const T2& s2, bool endlt = true) { + size_t len1 = Class_sstr_len::sstr_len(s1); + size_t len2 = Class_sstr_len::sstr_len(s2); + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] > s2[i]) { + return true; + } else if(s1[i] < s2[i]) { + return false; + } + } + if(len1 == len2) return true; + return (len1 > len2) == endlt; +} + +/** + * Return true iff the given suffix of s1 is greater than or equal to the given + * suffix of s2. + */ +template +static inline bool sstr_suf_geq( + const T1& s1, size_t suf1, + const T2& s2, size_t suf2, + bool endlt = true) +{ + assert_leq(suf1, Class_sstr_len::sstr_len(s1)); + assert_leq(suf2, Class_sstr_len::sstr_len(s2)); + size_t len1 = Class_sstr_len::sstr_len(s1) - suf1; + size_t len2 = Class_sstr_len::sstr_len(s2) - suf2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[suf1+i] > s2[suf2+i]) { + return true; + } else if(s1[suf1+i] < s2[suf2+i]) { + return false; + } + } + if(len1 == len2) return true; + return (len1 > len2) == endlt; +} + +/** + * Return true iff the given prefix of s1 is greater than or equal to the given + * prefix of s2. + */ +template +static inline bool sstr_pre_geq( + const T1& s1, size_t pre1, + const T2& s2, size_t pre2, + bool endlt = true) +{ + assert_leq(pre1, Class_sstr_len::sstr_len(s1)); + assert_leq(pre2, Class_sstr_len::sstr_len(s2)); + size_t len1 = pre1; + size_t len2 = pre2; + size_t minlen = (len1 < len2 ? len1 : len2); + for(size_t i = 0; i < minlen; i++) { + if(s1[i] > s2[i]) { + return true; + } else if(s1[i] < s2[i]) { + return false; + } + } + if(len1 == len2) return true; + return (len1 > len2) == endlt; +} + +template +static inline const char * sstr_to_cstr(const T& s) { + return s.toZBuf(); +} + +template<> +inline const char * sstr_to_cstr >( + const std::basic_string& s) +{ + return s.c_str(); +} + +/** + * Simple string class with backing memory whose size is managed by the user + * using the constructor and install() member function. No behind-the-scenes + * reallocation or copying takes place. + */ +template +class SString { + +public: + + explicit SString() : + cs_(NULL), + printcs_(NULL), + len_(0) + { } + + explicit SString(size_t sz) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + resize(sz); + } + + /** + * Create an SStringExpandable from another SStringExpandable. + */ + SString(const SString& o) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + *this = o; + } + + /** + * Create an SStringExpandable from a std::basic_string of the + * appropriate type. + */ + explicit SString(const std::basic_string& str) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + install(str.c_str(), str.length()); + } + + /** + * Create an SStringExpandable from an array and size. + */ + explicit SString(const T* b, size_t sz) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + install(b, sz); + } + + /** + * Create an SStringExpandable from a zero-terminated array. + */ + explicit SString(const T* b) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + install(b, strlen(b)); + } + + /** + * Destroy the expandable string object. + */ + virtual ~SString() { + if(cs_ != NULL) { + delete[] cs_; + cs_ = NULL; + } + if(printcs_ != NULL) { + delete[] printcs_; + printcs_ = NULL; + } + len_ = 0; + } + + /** + * Assignment to other SString. + */ + SString& operator=(const SString& o) { + install(o.cs_, o.len_); + return *this; + } + + /** + * Assignment to other SString. + */ + SString& operator=(const std::basic_string& o) { + install(o); + return *this; + } + + /** + * Resizes the string without preserving its contents. + */ + void resize(size_t sz) { + if(cs_ != NULL) { + delete cs_; + cs_ = NULL; + } + if(printcs_ != NULL) { + delete printcs_; + printcs_ = NULL; + } + if(sz != 0) { + cs_ = new T[sz+1]; + } + len_ = sz; + } + + /** + * Return ith character from the left of either the forward or the + * reverse version of the read. + */ + T windowGet( + size_t i, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_lt(i, len); + assert_leq(len, len_ - depth); + return fw ? cs_[depth+i] : cs_[depth+len-i-1]; + } + + /** + * Return ith character from the left of either the forward or the + * reverse-complement version of the read. + */ + void windowGet( + T& ret, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_leq(len, len_ - depth); + ret.resize(len); + for(size_t i = 0; i < len; i++) { + ret.set(fw ? cs_[depth+i] : cs_[depth+len-i-1], i); + } + } + + /** + * Set character at index 'idx' to 'c'. + */ + inline void set(int c, size_t idx) { + assert_lt(idx, len_); + cs_[idx] = c; + } + + /** + * Retrieve constant version of element i. + */ + inline const T& operator[](size_t i) const { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Retrieve mutable version of element i. + */ + inline T& operator[](size_t i) { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Retrieve constant version of element i. + */ + inline const T& get(size_t i) const { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. memcpy is used, not + * operator=. + */ + virtual void install(const T* b, size_t sz) { + if(sz == 0) return; + resize(sz); + memcpy(cs_, b, sz * sizeof(T)); + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. memcpy is used, not + * operator=. + */ + virtual void install(const std::basic_string& b) { + size_t sz = b.length(); + if(sz == 0) return; + resize(sz); + memcpy(cs_, b.c_str(), sz * sizeof(T)); + } + + /** + * Copy all bytes from zero-terminated buffer 'b' into this string. + */ + void install(const T* b) { + install(b, strlen(b)); + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const char* b, size_t sz) { + if(sz == 0) return; + resize(sz); + for(size_t i = 0; i < sz; i++) { + cs_[i] = b[sz-i-1]; + } + len_ = sz; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const SString& b) { + installReverse(b.cs_, b.len_); + } + + /** + * Return true iff the two strings are equal. + */ + bool operator==(const SString& o) { + return sstr_eq(*this, o); + } + + /** + * Return true iff the two strings are not equal. + */ + bool operator!=(const SString& o) { + return sstr_neq(*this, o); + } + + /** + * Return true iff this string is less than given string. + */ + bool operator<(const SString& o) { + return sstr_lt(*this, o); + } + + /** + * Return true iff this string is greater than given string. + */ + bool operator>(const SString& o) { + return sstr_gt(*this, o); + } + + /** + * Return true iff this string is less than or equal to given string. + */ + bool operator<=(const SString& o) { + return sstr_leq(*this, o); + } + + /** + * Return true iff this string is greater than or equal to given string. + */ + bool operator>=(const SString& o) { + return sstr_geq(*this, o); + } + + /** + * Reverse the buffer in place. + */ + void reverse() { + for(size_t i = 0; i < (len_ >> 1); i++) { + T tmp = get(i); + set(get(len_-i-1), i); + set(tmp, len_-i-1); + } + } + + /** + * Reverse the buffer in place. + */ + void reverseComplement(int* rcmap) { + size_t mid = len_ >> 1; + for(size_t i = 0; i < (len_ >> 1); i++) { + T tmp = get(i); + set(rcmap[get(len_-i-1)], i); + set(rcmap[tmp], len_-i-1); + } + if (len_ % 2) { + set(rcmap[get(mid)], mid); + } + } + + /** + * Reverse a substring of the buffer in place. + */ + void reverseWindow(size_t off, size_t len) { + assert_leq(off, len_); + assert_leq(off + len, len_); + size_t mid = len >> 1; + for(size_t i = 0; i < mid; i++) { + T tmp = get(off+i); + set(get(off+len-i-1), off+i); + set(tmp, off+len-i-1); + } + } + + /** + * Set the first len elements of the buffer to el. + */ + void fill(size_t len, const T& el) { + assert_leq(len, len_); + for(size_t i = 0; i < len; i++) { + set(el, i); + } + } + + /** + * Set all elements of the buffer to el. + */ + void fill(const T& el) { + fill(len_, el); + } + + /** + * Return the length of the string. + */ + inline size_t length() const { return len_; } + + /** + * Clear the buffer. + */ + void clear() { len_ = 0; } + + /** + * Return true iff the buffer is empty. + */ + inline bool empty() const { return len_ == 0; } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + const char* toZBufXForm(const char *xform) const { + ASSERT_ONLY(size_t xformElts = strlen(xform)); + // Lazily allocate space for print buffer + if(printcs_ == NULL) { + const_cast(printcs_) = new char[len_+1]; + } + char* printcs = const_cast(printcs_); + assert(printcs != NULL); + for(size_t i = 0; i < len_; i++) { + assert_lt(cs_[i], (int)xformElts); + printcs[i] = xform[cs_[i]]; + } + printcs[len_] = 0; + return printcs_; + } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + virtual const T* toZBuf() const { + const_cast(cs_)[len_] = 0; + return cs_; + } + + /** + * Return a const version of the raw buffer. + */ + const T* buf() const { return cs_; } + + /** + * Return a writeable version of the raw buffer. + */ + T* wbuf() { return cs_; } + +protected: + + T *cs_; // +1 so that we have the option of dropping in a terminating "\0" + char *printcs_; // +1 so that we have the option of dropping in a terminating "\0" + size_t len_; // # elements +}; + +/** + * Simple string class with backing memory whose size is managed by the user + * using the constructor and install() member function. No behind-the-scenes + * reallocation or copying takes place. + */ +class S2bDnaString { + +public: + + explicit S2bDnaString() : + cs_(NULL), + printcs_(NULL), + len_(0) + { } + + explicit S2bDnaString(size_t sz) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + resize(sz); + } + + /** + * Copy another object of the same class. + */ + S2bDnaString(const S2bDnaString& o) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + *this = o; + } + + /** + * Create an SStringExpandable from a std::basic_string of the + * appropriate type. + */ + explicit S2bDnaString( + const std::basic_string& str, + bool chars = false, + bool colors = false) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + if(chars) { + if(colors) { + installColors(str.c_str(), str.length()); + } else { + installChars(str.c_str(), str.length()); + } + } else { + install(str.c_str(), str.length()); + } + } + + /** + * Create an SStringExpandable from an array and size. + */ + explicit S2bDnaString( + const char* b, + size_t sz, + bool chars = false, + bool colors = false) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + if(chars) { + if(colors) { + installColors(b, sz); + } else { + installChars(b, sz); + } + } else { + install(b, sz); + } + } + + /** + * Create an SStringFixed from a zero-terminated string. + */ + explicit S2bDnaString( + const char* b, + bool chars = false, + bool colors = false) : + cs_(NULL), + printcs_(NULL), + len_(0) + { + if(chars) { + if(colors) { + installColors(b, strlen(b)); + } else { + installChars(b, strlen(b)); + } + } else { + install(b, strlen(b)); + } + } + + /** + * Destroy the expandable string object. + */ + virtual ~S2bDnaString() { + if(cs_ != NULL) { + delete[] cs_; + cs_ = NULL; + } + if(printcs_ != NULL) { + delete[] printcs_; + printcs_ = NULL; + } + len_ = 0; + } + + /** + * Assignment to other SString. + */ + template + S2bDnaString& operator=(const T& o) { + install(o.c_str(), o.length()); + return *this; + } + + /** + * Assignment from a std::basic_string + */ + template + S2bDnaString& operator=(const std::basic_string& o) { + install(o); + return *this; + } + + /** + * Resizes the string without preserving its contents. + */ + void resize(size_t sz) { + if(cs_ != NULL) { + delete cs_; + cs_ = NULL; + } + if(printcs_ != NULL) { + delete printcs_; + printcs_ = NULL; + } + len_ = sz; + if(sz != 0) { + cs_ = new uint32_t[nwords()]; + } + } + + /** + * Return DNA character corresponding to element 'idx'. + */ + char toChar(size_t idx) const { + int c = (int)get(idx); + assert_range(0, 3, c); + return "ACGT"[c]; + } + + /** + * Return color character corresponding to element 'idx'. + */ + char toColor(size_t idx) const { + int c = (int)get(idx); + assert_range(0, 3, c); + return "0123"[c]; + } + + /** + * Return ith character from the left of either the forward or the + * reverse version of the read. + */ + char windowGet( + size_t i, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_lt(i, len); + assert_leq(len, len_ - depth); + return fw ? get(depth+i) : get(depth+len-i-1); + } + + /** + * Return ith character from the left of either the forward or the + * reverse-complement version of the read. + */ + template + void windowGet( + T& ret, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_leq(len, len_ - depth); + ret.resize(len); + for(size_t i = 0; i < len; i++) { + ret.set((fw ? get(depth+i) : get(depth+len-i-1)), i); + } + } + + /** + * Return length in 32-bit words. + */ + size_t nwords() const { + return (len_ + 15) >> 4; + } + + /** + * Set character at index 'idx' to 'c'. + */ + void set(int c, size_t idx) { + assert_lt(idx, len_); + assert_range(0, 3, c); + size_t word = idx >> 4; + size_t bpoff = (idx & 15) << 1; + cs_[word] = cs_[word] & ~(uint32_t)(3 << bpoff); + cs_[word] = cs_[word] | (uint32_t)(c << bpoff); + } + + /** + * Set character at index 'idx' to DNA char 'c'. + */ + void setChar(int c, size_t idx) { + assert_in(toupper(c), "ACGT"); + int bp = asc2dna[c]; + set(bp, idx); + } + + /** + * Set character at index 'idx' to color char 'c'. + */ + void setColor(int c, size_t idx) { + assert_in(toupper(c), "0123"); + int co = asc2col[c]; + set(co, idx); + } + + /** + * Set the ith 32-bit word to given word. + */ + void setWord(uint32_t w, size_t i) { + assert_lt(i, nwords()); + cs_[i] = w; + } + + /** + * Retrieve constant version of element i. + */ + char operator[](size_t i) const { + assert_lt(i, len_); + return get(i); + } + + /** + * Retrieve constant version of element i. + */ + char get(size_t i) const { + assert_lt(i, len_); + size_t word = i >> 4; + size_t bpoff = (i & 15) << 1; + return (char)((cs_[word] >> bpoff) & 3); + } + + /** + * Copy packed words from string 'b' into this packed string. + */ + void install(const uint32_t* b, size_t sz) { + if(sz == 0) return; + resize(sz); + memcpy(cs_, b, sizeof(uint32_t)*nwords()); + } + + /** + * Copy 'sz' DNA characters encoded as integers from buffer 'b' into this + * packed string. + */ + void install(const char* b, size_t sz) { + if(sz == 0) return; + resize(sz); + size_t wordi = 0; + for(size_t i = 0; i < sz; i += 16) { + uint32_t word = 0; + for(int j = 0; j < 16 && (size_t)(i+j) < sz; j++) { + uint32_t bp = (int)b[i+j]; + uint32_t shift = (uint32_t)j << 1; + assert_range(0, 3, (int)bp); + word |= (bp << shift); + } + cs_[wordi++] = word; + } + } + + /** + * Copy 'sz' DNA characters from buffer 'b' into this packed string. + */ + void installChars(const char* b, size_t sz) { + if(sz == 0) return; + resize(sz); + size_t wordi = 0; + for(size_t i = 0; i < sz; i += 16) { + uint32_t word = 0; + for(int j = 0; j < 16 && (size_t)(i+j) < sz; j++) { + char c = b[i+j]; + assert_in(toupper(c), "ACGT"); + int bp = asc2dna[(int)c]; + assert_range(0, 3, (int)bp); + uint32_t shift = (uint32_t)j << 1; + word |= (bp << shift); + } + cs_[wordi++] = word; + } + } + + /** + * Copy 'sz' color characters from buffer 'b' into this packed string. + */ + void installColors(const char* b, size_t sz) { + if(sz == 0) return; + resize(sz); + size_t wordi = 0; + for(size_t i = 0; i < sz; i += 16) { + uint32_t word = 0; + for(int j = 0; j < 16 && (size_t)(i+j) < sz; j++) { + char c = b[i+j]; + assert_in(c, "0123"); + int bp = asc2col[(int)c]; + assert_range(0, 3, (int)bp); + uint32_t shift = (uint32_t)j << 1; + word |= (bp << shift); + } + cs_[wordi++] = word; + } + } + + /** + * Copy 'sz' DNA characters from buffer 'b' into this packed string. + */ + void install(const char* b) { + install(b, strlen(b)); + } + + /** + * Copy 'sz' DNA characters from buffer 'b' into this packed string. + */ + void installChars(const char* b) { + installChars(b, strlen(b)); + } + + /** + * Copy 'sz' DNA characters from buffer 'b' into this packed string. + */ + void installColors(const char* b) { + installColors(b, strlen(b)); + } + + /** + * Copy 'sz' DNA characters from buffer 'b' into this packed string. + */ + void install(const std::basic_string& b) { + install(b.c_str(), b.length()); + } + + /** + * Copy 'sz' DNA characters from buffer 'b' into this packed string. + */ + void installChars(const std::basic_string& b) { + installChars(b.c_str(), b.length()); + } + + /** + * Copy 'sz' DNA characters from buffer 'b' into this packed string. + */ + void installColors(const std::basic_string& b) { + installColors(b.c_str(), b.length()); + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const char* b, size_t sz) { + resize(sz); + if(sz == 0) return; + size_t wordi = 0; + size_t bpi = 0; + cs_[0] = 0; + for(size_t i =sz; i > 0; i--) { + assert_range(0, 3, (int)b[i-1]); + cs_[wordi] |= ((int)b[i-1] << (bpi<<1)); + if(bpi == 15) { + wordi++; + cs_[wordi] = 0; + bpi = 0; + } else bpi++; + } + } + + /** + * Copy all chars from buffer of DNA characters 'b' into this string, + * reversing them in the process. + */ + void installReverse(const char* b) { + installReverse(b, strlen(b)); + } + + /** + * Copy 'sz' bytes from buffer of DNA characters 'b' into this string, + * reversing them in the process. + */ + void installReverseChars(const char* b, size_t sz) { + resize(sz); + if(sz == 0) return; + size_t wordi = 0; + size_t bpi = 0; + cs_[0] = 0; + for(size_t i =sz; i > 0; i--) { + char c = b[i-1]; + assert_in(toupper(c), "ACGT"); + int bp = asc2dna[(int)c]; + assert_range(0, 3, bp); + cs_[wordi] |= (bp << (bpi<<1)); + if(bpi == 15) { + wordi++; + cs_[wordi] = 0; + bpi = 0; + } else bpi++; + } + } + + /** + * Copy all chars from buffer of DNA characters 'b' into this string, + * reversing them in the process. + */ + void installReverseChars(const char* b) { + installReverseChars(b, strlen(b)); + } + + /** + * Copy 'sz' bytes from buffer of color characters 'b' into this string, + * reversing them in the process. + */ + void installReverseColors(const char* b, size_t sz) { + resize(sz); + if(sz == 0) return; + size_t wordi = 0; + size_t bpi = 0; + cs_[0] = 0; + for(size_t i =sz; i > 0; i--) { + char c = b[i-1]; + assert_in(c, "0123"); + int bp = asc2col[(int)c]; + assert_range(0, 3, bp); + cs_[wordi] |= (bp << (bpi<<1)); + if(bpi == 15) { + wordi++; + cs_[wordi] = 0; + bpi = 0; + } else bpi++; + } + } + + /** + * Copy all chars from buffer of color characters 'b' into this string, + * reversing them in the process. + */ + void installReverseColors(const char* b) { + installReverseColors(b, strlen(b)); + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const S2bDnaString& b) { + resize(b.len_); + if(b.len_ == 0) return; + size_t wordi = 0; + size_t bpi = 0; + size_t wordb = b.nwords()-1; + size_t bpb = (b.len_-1) & 15; + cs_[0] = 0; + for(size_t i = b.len_; i > 0; i--) { + int bbp = (int)((b[wordb] >> (bpb << 1)) & 3); + assert_range(0, 3, bbp); + cs_[wordi] |= (bbp << (bpi << 1)); + if(bpi == 15) { + wordi++; + cs_[wordi] = 0; + bpi = 0; + } else bpi++; + if(bpb == 0) { + wordb--; + bpi = 15; + } else bpi--; + } + } + + /** + * Return true iff the two strings are equal. + */ + bool operator==(const S2bDnaString& o) { + return sstr_eq(*this, o); + } + + /** + * Return true iff the two strings are not equal. + */ + bool operator!=(const S2bDnaString& o) { + return sstr_neq(*this, o); + } + + /** + * Return true iff this string is less than given string. + */ + bool operator<(const S2bDnaString& o) { + return sstr_lt(*this, o); + } + + /** + * Return true iff this string is greater than given string. + */ + bool operator>(const S2bDnaString& o) { + return sstr_gt(*this, o); + } + + /** + * Return true iff this string is less than or equal to given string. + */ + bool operator<=(const S2bDnaString& o) { + return sstr_leq(*this, o); + } + + /** + * Return true iff this string is greater than or equal to given string. + */ + bool operator>=(const S2bDnaString& o) { + return sstr_geq(*this, o); + } + + /** + * Reverse the 2-bit encoded DNA string in-place. + */ + void reverse() { + if(len_ <= 1) return; + size_t wordf = nwords()-1; + size_t bpf = (len_-1) & 15; + size_t wordi = 0; + size_t bpi = 0; + while(wordf > wordi || (wordf == wordi && bpf > bpi)) { + int f = (cs_[wordf] >> (bpf << 1)) & 3; + int i = (cs_[wordi] >> (bpi << 1)) & 3; + cs_[wordf] &= ~(uint32_t)(3 << (bpf << 1)); + cs_[wordi] &= ~(uint32_t)(3 << (bpi << 1)); + cs_[wordf] |= (uint32_t)(i << (bpf << 1)); + cs_[wordi] |= (uint32_t)(f << (bpi << 1)); + if(bpf == 0) { + bpf = 15; + wordf--; + } else bpf--; + if(bpi == 15) { + bpi = 0; + wordi++; + } else bpi++; + } + } + + /** + * Reverse a substring of the buffer in place. + */ + void reverseWindow(size_t off, size_t len) { + assert_leq(off, len_); + assert_leq(off+len, len_); + if(len <= 1) return; + size_t wordf = (off+len-1) >> 4; + size_t bpf = (off+len-1) & 15; + size_t wordi = (off ) >> 4; + size_t bpi = (off ) & 15; + while(wordf > wordi || (wordf == wordi && bpf > bpi)) { + int f = (cs_[wordf] >> (bpf << 1)) & 3; + int i = (cs_[wordi] >> (bpi << 1)) & 3; + cs_[wordf] &= ~(uint32_t)(3 << (bpf << 1)); + cs_[wordi] &= ~(uint32_t)(3 << (bpi << 1)); + cs_[wordf] |= (uint32_t)(i << (bpf << 1)); + cs_[wordi] |= (uint32_t)(f << (bpi << 1)); + if(bpf == 0) { + bpf = 15; + wordf--; + } else bpf--; + if(bpi == 15) { + bpi = 0; + wordi++; + } else bpi++; + } + } + + + /** + * Set the first len elements of the buffer to el. + */ + void fill(size_t len, char el) { + assert_leq(len, len_); + assert_range(0, 3, (int)el); + size_t word = 0; + if(len > 32) { + // Copy el throughout block + uint32_t bl = (uint32_t)el; + bl |= (bl << 2); + bl |= (bl << 4); + bl |= (bl << 8); + bl |= (bl << 16); + // Fill with blocks + size_t blen = len >> 4; + for(; word < blen; word++) { + cs_[word] = bl; + } + len = len & 15; + } + size_t bp = 0; + for(size_t i = 0; i < len; i++) { + cs_[word] &= ~(uint32_t)(3 << (bp << 1)); + cs_[word] |= (uint32_t)(el << (bp << 1)); + if(bp == 15) { + word++; + bp = 0; + } else bp++; + } + } + + /** + * Set all elements of the buffer to el. + */ + void fill(char el) { + fill(len_, el); + } + + /** + * Return the ith character in the window defined by fw, color, depth and + * len. + */ + char windowGetDna( + size_t i, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_lt(i, len); + assert_leq(len, len_ - depth); + if(fw) { + return get(depth+i); + } else { + return + color ? + get(depth+len-i-1) : + compDna(get(depth+len-i-1)); + } + } + + /** + * Fill the given DNA buffer with the substring specified by fw, + * color, depth and len. + */ + template + void windowGetDna( + T& buf, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_leq(len, len_ - depth); + buf.resize(len); + for(size_t i = 0; i < len; i++) { + buf.set( + (fw ? + get(depth+i) : + (color ? + get(depth+len-i-1) : + compDna(get(depth+len-i-1)))), i); + } + } + + /** + * Return the length of the string. + */ + inline size_t length() const { return len_; } + + /** + * Clear the buffer. + */ + void clear() { len_ = 0; } + + /** + * Return true iff the buffer is empty. + */ + inline bool empty() const { return len_ == 0; } + + /** + * Return a const version of the raw buffer. + */ + const uint32_t* buf() const { return cs_; } + + /** + * Return a writeable version of the raw buffer. + */ + uint32_t* wbuf() { return cs_; } + + /** + * Note: the size of the string once it's stored in the print buffer is 4 + * times as large as the string as stored in compact 2-bit-per-char words. + */ + const char* toZBuf() const { + if(printcs_ == NULL) { + const_cast(printcs_) = new char[len_+1]; + } + char *printcs = const_cast(printcs_); + size_t word = 0, bp = 0; + for(size_t i = 0; i < len_; i++) { + int c = (cs_[word] >> (bp << 1)) & 3; + printcs[i] = "ACGT"[c]; + if(bp == 15) { + word++; + bp = 0; + } else bp++; + } + printcs[len_] = '\0'; + return printcs_; + } + +protected: + + uint32_t *cs_; // 2-bit packed words + char *printcs_; + size_t len_; // # elements +}; + +/** + * Simple string class with backing memory that automatically expands as needed. + */ +template +class SStringExpandable { + +public: + + explicit SStringExpandable() : + cs_(NULL), + printcs_(NULL), + len_(0), + sz_(0) + { } + + explicit SStringExpandable(size_t sz) : + cs_(NULL), + printcs_(NULL), + len_(0), + sz_(0) + { + expandNoCopy(sz); + } + + /** + * Create an SStringExpandable from another SStringExpandable. + */ + SStringExpandable(const SStringExpandable& o) : + cs_(NULL), + printcs_(NULL), + len_(0), + sz_(0) + { + *this = o; + } + + /** + * Create an SStringExpandable from a std::basic_string of the + * appropriate type. + */ + explicit SStringExpandable(const std::basic_string& str) : + cs_(NULL), + printcs_(NULL), + len_(0), + sz_(0) + { + install(str.c_str(), str.length()); + } + + /** + * Create an SStringExpandable from an array and size. + */ + explicit SStringExpandable(const T* b, size_t sz) : + cs_(NULL), + printcs_(NULL), + len_(0), + sz_(0) + { + install(b, sz); + } + + /** + * Create an SStringExpandable from a zero-terminated array. + */ + explicit SStringExpandable(const T* b) : + cs_(NULL), + printcs_(NULL), + len_(0), + sz_(0) + { + install(b, strlen(b)); + } + + /** + * Destroy the expandable string object. + */ + virtual ~SStringExpandable() { + if(cs_ != NULL) { + delete[] cs_; + cs_ = NULL; + } + if(printcs_ != NULL) { + delete[] printcs_; + printcs_ = NULL; + } + sz_ = len_ = 0; + } + + /** + * Return ith character from the left of either the forward or the + * reverse-complement version of the read. + */ + T windowGet( + size_t i, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_lt(i, len); + assert_leq(len, len_ - depth); + return fw ? cs_[depth+i] : cs_[depth+len-i-1]; + } + + /** + * Return ith character from the left of either the forward or the + * reverse-complement version of the read. + */ + void windowGet( + T& ret, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_leq(len, len_ - depth); + for(size_t i = 0; i < len; i++) { + ret.append(fw ? cs_[depth+i] : cs_[depth+len-i-1]); + } + } + + /** + * Assignment to other SStringFixed. + */ + SStringExpandable& operator=(const SStringExpandable& o) { + install(o.cs_, o.len_); + return *this; + } + + /** + * Assignment from a std::basic_string + */ + SStringExpandable& operator=(const std::basic_string& o) { + install(o.c_str(), o.length()); + return *this; + } + + /** + * Insert char c before position 'idx'; slide subsequent chars down. + */ + void insert(const T& c, size_t idx) { + assert_lt(idx, len_); + if(sz_ < len_ + 1) expandCopy((len_ + 1 + S) * M); + len_++; + // Move everyone down by 1 + // len_ is the *new* length + for(size_t i = len_; i > idx+1; i--) { + cs_[i-1] = cs_[i-2]; + } + cs_[idx] = c; + } + + /** + * Set character at index 'idx' to 'c'. + */ + void set(int c, size_t idx) { + assert_lt(idx, len_); + cs_[idx] = c; + } + + /** + * Append char c. + */ + void append(const T& c) { + if(sz_ < len_ + 1) expandCopy((len_ + 1 + S) * M); + cs_[len_++] = c; + } + + /** + * Delete char at position 'idx'; slide subsequent chars up. + */ + void remove(size_t idx) { + assert_lt(idx, len_); + assert_gt(len_, 0); + for(size_t i = idx; i < len_-1; i++) { + cs_[i] = cs_[i+1]; + } + len_--; + } + + /** + * Retrieve constant version of element i. + */ + const T& operator[](size_t i) const { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Retrieve mutable version of element i. + */ + T& operator[](size_t i) { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Retrieve constant version of element i. + */ + const T& get(size_t i) const { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + virtual void install(const T* b, size_t sz) { + if(sz_ < sz) expandNoCopy((sz + S) * M); + memcpy(cs_, b, sz * sizeof(T)); + len_ = sz; + } + + + /** + * Copy all bytes from zero-terminated buffer 'b' into this string. + */ + void install(const T* b) { install(b, strlen(b)); } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const char* b, size_t sz) { + if(sz_ < sz) expandNoCopy((sz + S) * M); + for(size_t i = 0; i < sz; i++) { + cs_[i] = b[sz-i-1]; + } + len_ = sz; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const SStringExpandable& b) { + if(sz_ < b.len_) expandNoCopy((b.len_ + S) * M); + for(size_t i = 0; i < b.len_; i++) { + cs_[i] = b.cs_[b.len_ - i - 1]; + } + len_ = b.len_; + } + + /** + * Return true iff the two strings are equal. + */ + bool operator==(const SStringExpandable& o) { + return sstr_eq(*this, o); + } + + /** + * Return true iff the two strings are not equal. + */ + bool operator!=(const SStringExpandable& o) { + return sstr_neq(*this, o); + } + + /** + * Return true iff this string is less than given string. + */ + bool operator<(const SStringExpandable& o) { + return sstr_lt(*this, o); + } + + /** + * Return true iff this string is greater than given string. + */ + bool operator>(const SStringExpandable& o) { + return sstr_gt(*this, o); + } + + /** + * Return true iff this string is less than or equal to given string. + */ + bool operator<=(const SStringExpandable& o) { + return sstr_leq(*this, o); + } + + /** + * Return true iff this string is greater than or equal to given string. + */ + bool operator>=(const SStringExpandable& o) { + return sstr_geq(*this, o); + } + + /** + * Reverse the buffer in place. + */ + void reverse() { + for(size_t i = 0; i < (len_ >> 1); i++) { + T tmp = get(i); + set(get(len_-i-1), i); + set(tmp, len_-i-1); + } + } + + /** + * Reverse a substring of the buffer in place. + */ + void reverseWindow(size_t off, size_t len) { + assert_leq(off, len_); + assert_leq(off + len, len_); + size_t mid = len >> 1; + for(size_t i = 0; i < mid; i++) { + T tmp = get(off+i); + set(get(off+len-i-1), off+i); + set(tmp, off+len-i-1); + } + } + + /** + * Simply resize the buffer. If the buffer is resized to be + * longer, the newly-added elements will contain garbage and should + * be initialized immediately. + */ + void resize(size_t len) { + if(sz_ < len) expandCopy((len + S) * M); + len_ = len; + } + + /** + * Simply resize the buffer. If the buffer is resized to be + * longer, new elements will be initialized with 'el'. + */ + void resize(size_t len, const T& el) { + if(sz_ < len) expandCopy((len + S) * M); + if(len > len_) { + for(size_t i = len_; i < len; i++) { + cs_[i] = el; + } + } + len_ = len; + } + + /** + * Set the first len elements of the buffer to el. + */ + void fill(size_t len, const T& el) { + assert_leq(len, len_); + for(size_t i = 0; i < len; i++) { + cs_[i] = el; + } + } + + /** + * Set all elements of the buffer to el. + */ + void fill(const T& el) { + fill(len_, el); + } + + /** + * Trim len characters from the beginning of the string. + */ + void trimBegin(size_t len) { + assert_leq(len, len_); + if(len == len_) { + len_ = 0; return; + } + for(size_t i = 0; i < len_-len; i++) { + cs_[i] = cs_[i+len]; + } + len_ -= len; + } + + /** + * Trim len characters from the end of the string. + */ + void trimEnd(size_t len) { + if(len >= len_) len_ = 0; + else len_ -= len; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + void append(const T* b, size_t sz) { + if(sz_ < len_ + sz) expandCopy((len_ + sz + S) * M); + memcpy(cs_ + len_, b, sz * sizeof(T)); + len_ += sz; + } + + /** + * Copy bytes from zero-terminated buffer 'b' into this string. + */ + void append(const T* b) { + append(b, strlen(b)); + } + + /** + * Return the length of the string. + */ + size_t length() const { return len_; } + + /** + * Clear the buffer. + */ + void clear() { len_ = 0; } + + /** + * Return true iff the buffer is empty. + */ + bool empty() const { return len_ == 0; } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + const char* toZBufXForm(const char *xform) const { + ASSERT_ONLY(size_t xformElts = strlen(xform)); + if(empty()) { + const_cast(zero_) = 0; + return &zero_; + } + char* printcs = const_cast(printcs_); + // Lazily allocate space for print buffer + for(size_t i = 0; i < len_; i++) { + assert_lt(cs_[i], (int)xformElts); + printcs[i] = xform[(int)cs_[i]]; + } + printcs[len_] = 0; + return printcs_; + } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + virtual const T* toZBuf() const { + if(empty()) { + const_cast(zeroT_) = 0; + return &zeroT_; + } + assert_leq(len_, sz_); + const_cast(cs_)[len_] = 0; + return cs_; + } + + /** + * Return true iff this DNA string matches the given nucleotide + * character string. + */ + bool eq(const char *str) const { + const char *self = toZBuf(); + return strcmp(str, self) == 0; + } + + /** + * Return a const version of the raw buffer. + */ + const T* buf() const { return cs_; } + + /** + * Return a writeable version of the raw buffer. + */ + T* wbuf() { return cs_; } + +protected: + /** + * Allocate new, bigger buffer and copy old contents into it. If + * requested size can be accommodated by current buffer, do nothing. + */ + void expandCopy(size_t sz) { + if(sz_ >= sz) return; // done! + T *tmp = new T[sz + 1]; + char *ptmp = new char[sz + 1]; + if(cs_ != NULL) { + memcpy(tmp, cs_, sizeof(T)*len_); + delete[] cs_; + } + if(printcs_ != NULL) { + memcpy(ptmp, printcs_, sizeof(char)*len_); + delete[] printcs_; + } + cs_ = tmp; + printcs_ = ptmp; + sz_ = sz; + } + + /** + * Allocate new, bigger buffer. If requested size can be + * accommodated by current buffer, do nothing. + */ + void expandNoCopy(size_t sz) { + if(sz_ >= sz) return; // done! + if(cs_ != NULL) delete[] cs_; + if(printcs_ != NULL) delete[] printcs_; + cs_ = new T[sz + 1]; + printcs_ = new char[sz + 1]; + sz_ = sz; + } + + T *cs_; // +1 so that we have the option of dropping in a terminating "\0" + char *printcs_; // +1 so that we have the option of dropping in a terminating "\0" + char zero_; // 0 terminator for empty string + T zeroT_; // 0 terminator for empty string + size_t len_; // # filled-in elements + size_t sz_; // size capacity of cs_ +}; + +/** + * Simple string class with in-object storage. + * + * All copies induced by, e.g., operator=, the copy constructor, + * install() and append(), are shallow (using memcpy/sizeof). If deep + * copies are needed, use a different class. + * + * Reading from an uninitialized element results in an assert as long + * as NDEBUG is not defined. If NDEBUG is defined, the result is + * undefined. + */ +template +class SStringFixed { +public: + explicit SStringFixed() : len_(0) { } + + /** + * Create an SStringFixed from another SStringFixed. + */ + SStringFixed(const SStringFixed& o) { + *this = o; + } + + /** + * Create an SStringFixed from another SStringFixed. + */ + explicit SStringFixed(const std::basic_string& str) { + install(str.c_str(), str.length()); + } + + /** + * Create an SStringFixed from an array and size. + */ + explicit SStringFixed(const T* b, size_t sz) { + install(b, sz); + } + + /** + * Create an SStringFixed from a zero-terminated string. + */ + explicit SStringFixed(const T* b) { + install(b, strlen(b)); + } + + virtual ~SStringFixed() { } // C++ needs this + + /** + * Retrieve constant version of element i. + */ + inline const T& operator[](size_t i) const { + return get(i); + } + + /** + * Retrieve mutable version of element i. + */ + inline T& operator[](size_t i) { + return get(i); + } + + /** + * Retrieve constant version of element i. + */ + inline const T& get(size_t i) const { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Retrieve mutable version of element i. + */ + inline T& get(size_t i) { + assert_lt(i, len_); + return cs_[i]; + } + + /** + * Return ith character from the left of either the forward or the + * reverse-complement version of the read. + */ + T windowGet( + size_t i, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_lt(i, len); + assert_leq(len, len_ - depth); + return fw ? cs_[depth+i] : cs_[depth+len-i-1]; + } + + /** + * Return ith character from the left of either the forward or the + * reverse-complement version of the read. + */ + void windowGet( + T& ret, + bool fw, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = len_; + assert_leq(len, len_ - depth); + for(size_t i = 0; i < len; i++) { + ret.append(fw ? cs_[depth+i] : cs_[depth+len-i-1]); + } + } + + /** + * Assignment to other SStringFixed. + */ + SStringFixed& operator=(const SStringFixed& o) { + install(o.cs_, o.len_); + return *this; + } + + /** + * Assignment from a std::basic_string + */ + SStringFixed& operator=(const std::basic_string& o) { + install(o); + return *this; + } + + /** + * Insert char c before position 'idx'; slide subsequent chars down. + */ + void insert(const T& c, size_t idx) { + assert_lt(len_, S); + assert_lt(idx, len_); + // Move everyone down by 1 + for(int i = len_; i > idx; i--) { + cs_[i] = cs_[i-1]; + } + cs_[idx] = c; + len_++; + } + + /** + * Set character at index 'idx' to 'c'. + */ + void set(int c, size_t idx) { + assert_lt(idx, len_); + cs_[idx] = c; + } + + /** + * Append char c. + */ + void append(const T& c) { + assert_lt(len_, S); + cs_[len_++] = c; + } + + /** + * Delete char at position 'idx'; slide subsequent chars up. + */ + void remove(size_t idx) { + assert_lt(idx, len_); + assert_gt(len_, 0); + for(size_t i = idx; i < len_-1; i++) { + cs_[i] = cs_[i+1]; + } + len_--; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + virtual void install(const T* b, size_t sz) { + assert_leq(sz, S); + memcpy(cs_, b, sz * sizeof(T)); + len_ = sz; + } + + /** + * Copy all bytes from zero-terminated buffer 'b' into this string. + */ + void install(const T* b) { install(b, strlen(b)); } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const char* b, size_t sz) { + assert_leq(sz, S); + for(size_t i = 0; i < sz; i++) { + cs_[i] = b[sz-i-1]; + } + len_ = sz; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reversing them + * in the process. + */ + void installReverse(const SStringFixed& b) { + assert_leq(b.len_, S); + for(size_t i = 0; i < b.len_; i++) { + cs_[i] = b.cs_[b.len_ - i - 1]; + } + len_ = b.len_; + } + + /** + * Return true iff the two strings are equal. + */ + bool operator==(const SStringFixed& o) { + return sstr_eq(*this, o); + } + + /** + * Return true iff the two strings are not equal. + */ + bool operator!=(const SStringFixed& o) { + return sstr_neq(*this, o); + } + + /** + * Return true iff this string is less than given string. + */ + bool operator<(const SStringFixed& o) { + return sstr_lt(*this, o); + } + + /** + * Return true iff this string is greater than given string. + */ + bool operator>(const SStringFixed& o) { + return sstr_gt(*this, o); + } + + /** + * Return true iff this string is less than or equal to given string. + */ + bool operator<=(const SStringFixed& o) { + return sstr_leq(*this, o); + } + + /** + * Return true iff this string is greater than or equal to given string. + */ + bool operator>=(const SStringFixed& o) { + return sstr_geq(*this, o); + } + + /** + * Reverse the buffer in place. + */ + void reverse() { + for(size_t i = 0; i < (len_ >> 1); i++) { + T tmp = get(i); + set(get(len_-i-1), i); + set(tmp, len_-i-1); + } + } + + /** + * Reverse a substring of the buffer in place. + */ + void reverseWindow(size_t off, size_t len) { + assert_leq(off, len_); + assert_leq(off + len, len_); + size_t mid = len >> 1; + for(size_t i = 0; i < mid; i++) { + T tmp = get(off+i); + set(get(off+len-i-1), off+i); + set(tmp, off+len-i-1); + } + } + + /** + * Simply resize the buffer. If the buffer is resized to be + * longer, the newly-added elements will contain garbage and should + * be initialized immediately. + */ + void resize(size_t len) { + assert_lt(len, S); + len_ = len; + } + + /** + * Simply resize the buffer. If the buffer is resized to be + * longer, new elements will be initialized with 'el'. + */ + void resize(size_t len, const T& el) { + assert_lt(len, S); + if(len > len_) { + for(size_t i = len_; i < len; i++) { + cs_[i] = el; + } + } + len_ = len; + } + + /** + * Set the first len elements of the buffer to el. + */ + void fill(size_t len, const T& el) { + assert_leq(len, len_); + for(size_t i = 0; i < len; i++) { + cs_[i] = el; + } + } + + /** + * Set all elements of the buffer to el. + */ + void fill(const T& el) { + fill(len_, el); + } + + /** + * Trim len characters from the beginning of the string. + */ + void trimBegin(size_t len) { + assert_leq(len, len_); + if(len == len_) { + len_ = 0; return; + } + for(size_t i = 0; i < len_-len; i++) { + cs_[i] = cs_[i+len]; + } + len_ -= len; + } + + /** + * Trim len characters from the end of the string. + */ + void trimEnd(size_t len) { + if(len >= len_) len_ = 0; + else len_ -= len; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + void append(const T* b, size_t sz) { + assert_leq(sz + len_, S); + memcpy(cs_ + len_, b, sz * sizeof(T)); + len_ += sz; + } + + /** + * Copy bytes from zero-terminated buffer 'b' into this string. + */ + void append(const T* b) { + append(b, strlen(b)); + } + + /** + * Return the length of the string. + */ + size_t length() const { return len_; } + + /** + * Clear the buffer. + */ + void clear() { len_ = 0; } + + /** + * Return true iff the buffer is empty. + */ + bool empty() const { return len_ == 0; } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + virtual const T* toZBuf() const { + const_cast(cs_)[len_] = 0; + return cs_; + } + + /** + * Return true iff this DNA string matches the given nucleotide + * character string. + */ + bool eq(const char *str) const { + const char *self = toZBuf(); + return strcmp(str, self) == 0; + } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + const char* toZBufXForm(const char *xform) const { + ASSERT_ONLY(size_t xformElts = strlen(xform)); + char* printcs = const_cast(printcs_); + for(size_t i = 0; i < len_; i++) { + assert_lt(cs_[i], (int)xformElts); + printcs[i] = xform[cs_[i]]; + } + printcs[len_] = 0; + return printcs_; + } + + /** + * Return a const version of the raw buffer. + */ + const T* buf() const { return cs_; } + + /** + * Return a writeable version of the raw buffer. + */ + T* wbuf() { return cs_; } + +protected: + T cs_[S+1]; // +1 so that we have the option of dropping in a terminating "\0" + char printcs_[S+1]; // +1 so that we have the option of dropping in a terminating "\0" + size_t len_; +}; + +// +// Stream put operators +// + +template +std::ostream& operator<< (std::ostream& os, const SStringExpandable& str) { + os << str.toZBuf(); + return os; +} + +template +std::ostream& operator<< (std::ostream& os, const SStringFixed& str) { + os << str.toZBuf(); + return os; +} + +extern uint8_t asc2dna[]; +extern uint8_t asc2col[]; + +extern uint8_t asc2dna_3N[2][256]; + + + +/** + * Encapsulates a fixed-length DNA string with characters encoded as + * chars. Only capable of encoding A, C, G, T and N. The length is + * specified via the template parameter S. + */ +template +class SDnaStringFixed : public SStringFixed { +public: + + explicit SDnaStringFixed() : SStringFixed() { } + + /** + * Create an SStringFixed from another SStringFixed. + */ + SDnaStringFixed(const SDnaStringFixed& o) : + SStringFixed(o) { } + + /** + * Create an SStringFixed from a C++ basic_string. + */ + explicit SDnaStringFixed(const std::basic_string& str) : + SStringFixed(str) { } + + /** + * Create an SStringFixed from an array and size. + */ + explicit SDnaStringFixed(const char* b, size_t sz) : + SStringFixed(b, sz) { } + + /** + * Create an SStringFixed from a zero-terminated string. + */ + explicit SDnaStringFixed( + const char* b, + bool chars = false, + bool colors = false) : + SStringFixed() + { + if(chars) { + if(colors) { + installColors(b, strlen(b)); + } else { + installChars(b, strlen(b)); + } + } else { + install(b, strlen(b)); + } + } + + virtual ~SDnaStringFixed() { } // C++ needs this + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reverse- + * complementing them in the process, assuming an encoding where + * 0=A, 1=C, 2=G, 3=T, 4=N. + */ + void installReverseComp(const char* b, size_t sz) { + assert_leq(sz, S); + for(size_t i = 0; i < sz; i++) { + this->cs_[i] = (b[sz-i-1] == 4 ? 4 : b[sz-i-1] ^ 3); + } + this->len_ = sz; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reverse- + * complementing them in the process, assuming an encoding where + * 0=A, 1=C, 2=G, 3=T, 4=N. + */ + void installReverseComp(const SDnaStringFixed& b) { + assert_leq(b.len_, S); + for(size_t i = 0; i < b.len_; i++) { + this->cs_[i] = (b.cs_[b.len_-i-1] == 4 ? 4 : b.cs_[b.len_-i-1] ^ 3); + } + this->len_ = b.len_; + } + + /** + * Either reverse or reverse-complement (depending on "color") this + * DNA buffer in-place. + */ + void reverseComp(bool color = false) { + if(color) { + this->reverse(); + } else { + for(size_t i = 0; i < (this->len_ >> 1); i++) { + char tmp1 = (this->cs_[i] == 4 ? 4 : this->cs_[i] ^ 3); + char tmp2 = (this->cs_[this->len_-i-1] == 4 ? 4 : this->cs_[this->len_-i-1] ^ 3); + this->cs_[i] = tmp2; + this->cs_[this->len_-i-1] = tmp1; + } + // Do middle element iff there are an odd number + if((this->len_ & 1) != 0) { + char tmp = this->cs_[this->len_ >> 1]; + tmp = (tmp == 4 ? 4 : tmp ^ 3); + this->cs_[this->len_ >> 1] = tmp; + } + } + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + virtual void install(const char* b, size_t sz) { + assert_leq(sz, S); + memcpy(this->cs_, b, sz); +#ifndef NDEBUG + for(size_t i = 0; i < sz; i++) { + assert_leq(this->cs_[i], 4); + assert_geq(this->cs_[i], 0); + } +#endif + this->len_ = sz; + } + + /** + * Copy buffer 'b' of ASCII DNA characters into normal DNA + * characters. + */ + virtual void installChars(const char* b, size_t sz) { + assert_leq(sz, S); + for(size_t i = 0; i < sz; i++) { + assert_in(toupper(b[i]), "ACGTN-"); + this->cs_[i] = asc2dna[(int)b[i]]; + assert_geq(this->cs_[i], 0); + assert_leq(this->cs_[i], 4); + } + this->len_ = sz; + } + + /** + * Copy buffer 'b' of ASCII color characters into normal DNA + * characters. + */ + virtual void installColors(const char* b, size_t sz) { + assert_leq(sz, S); + for(size_t i = 0; i < sz; i++) { + assert_in(b[i], "0123."); + this->cs_[i] = asc2col[(int)b[i]]; + assert_geq(this->cs_[i], 0); + assert_leq(this->cs_[i], 4); + } + this->len_ = sz; + } + + /** + * Copy C++ string of ASCII DNA characters into normal DNA + * characters. + */ + virtual void installChars(const std::basic_string& str) { + installChars(str.c_str(), str.length()); + } + + /** + * Copy C++ string of ASCII color characters into normal DNA + * characters. + */ + virtual void installColors(const std::basic_string& str) { + installColors(str.c_str(), str.length()); + } + + /** + * Set DNA character at index 'idx' to 'c'. + */ + void set(int c, size_t idx) { + assert_lt(idx, this->len_); + assert_leq(c, 4); + assert_geq(c, 0); + this->cs_[idx] = c; + } + + /** + * Append DNA char c. + */ + void append(const char& c) { + assert_lt(this->len_, S); + assert_leq(c, 4); + assert_geq(c, 0); + this->cs_[this->len_++] = c; + } + + /** + * Set DNA character at index 'idx' to 'c'. + */ + void setChar(char c, size_t idx) { + assert_lt(idx, this->len_); + assert_in(toupper(c), "ACGTN"); + this->cs_[idx] = asc2dna[(int)c]; + } + + /** + * Append DNA character. + */ + void appendChar(char c) { + assert_lt(this->len_, S); + assert_in(toupper(c), "ACGTN"); + this->cs_[this->len_++] = asc2dna[(int)c]; + } + + /** + * Return DNA character corresponding to element 'idx'. + */ + char toChar(size_t idx) const { + assert_geq((int)this->cs_[idx], 0); + assert_leq((int)this->cs_[idx], 4); + return "ACGTN"[(int)this->cs_[idx]]; + } + + /** + * Retrieve constant version of element i. + */ + const char& operator[](size_t i) const { + return this->get(i); + } + + /** + * Retrieve constant version of element i. + */ + const char& get(size_t i) const { + assert_lt(i, this->len_); + assert_leq(this->cs_[i], 4); + assert_geq(this->cs_[i], 0); + return this->cs_[i]; + } + + /** + * Return the ith character in the window defined by fw, color, + * depth and len. + */ + char windowGetDna( + size_t i, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = this->len_; + assert_lt(i, len); + assert_leq(len, this->len_ - depth); + if(fw) return this->cs_[depth+i]; + else return color ? this->cs_[depth+len-i-1] : + compDna(this->cs_[depth+len-i-1]); + } + + /** + * Fill the given DNA buffer with the substring specified by fw, + * color, depth and len. + */ + void windowGetDna( + SDnaStringFixed& buf, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = this->len_; + assert_leq(len, this->len_ - depth); + for(size_t i = 0; i < len; i++) { + buf.append(fw ? this->cs_[depth+i] : + (color ? this->cs_[depth+len-i-1] : + compDna(this->cs_[depth+len-i-1]))); + } + } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + virtual const char* toZBuf() const { return this->toZBufXForm("ACGTN"); } +}; + +/** + * Encapsulates a fixed-length DNA string with characters encoded as + * chars. Only capable of encoding A, C, G, T and N. The length is + * specified via the template parameter S. + */ + +template +class SDnaStringExpandable : public SStringExpandable { +public: + + explicit SDnaStringExpandable() : SStringExpandable() { } + + /** + * Create an SStringFixed from another SStringFixed. + */ + SDnaStringExpandable(const SDnaStringExpandable& o) : + SStringExpandable(o) { } + + /** + * Create an SStringFixed from a C++ basic_string. + */ + explicit SDnaStringExpandable( + const std::basic_string& str, + bool chars = false, + bool colors = false) : + SStringExpandable() + { + if(chars) { + if(colors) { + installColors(str); + } else { + installChars(str); + } + } else { + install(str); + } + } + + /** + * Create an SStringFixed from an array and size. + */ + explicit SDnaStringExpandable( + const char* b, + size_t sz, + bool chars = false, + bool colors = false) : + SStringExpandable() + { + if(chars) { + if(colors) { + installColors(b, sz); + } else { + installChars(b, sz); + } + } else { + install(b, sz); + } + } + + /** + * Create an SStringFixed from a zero-terminated string. + */ + explicit SDnaStringExpandable( + const char* b, + bool chars = false, + bool colors = false) : + SStringExpandable() + { + install(b, chars, colors); + } + + virtual ~SDnaStringExpandable() { } // C++ needs this + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reverse- + * complementing them in the process, assuming an encoding where + * 0=A, 1=C, 2=G, 3=T, 4=N. + */ + void installReverseComp(const char* b, size_t sz) { + if(this->sz_ < sz) this->expandCopy((sz + S) * M); + for(size_t i = 0; i < sz; i++) { + this->cs_[i] = (b[sz-i-1] == 4 ? 4 : b[sz-i-1] ^ 3); + } + this->len_ = sz; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reverse- + * complementing them in the process, assuming an encoding where + * 0=A, 1=C, 2=G, 3=T, 4=N. + */ + void installReverseComp(const SDnaStringExpandable& b) { + if(this->sz_ < b.len_) this->expandCopy((b.len_ + S) * M); + for(size_t i = 0; i < b.len_; i++) { + this->cs_[i] = (b.cs_[b.len_-i-1] == 4 ? 4 : b.cs_[b.len_-i-1] ^ 3); + } + this->len_ = b.len_; + } + + /** + * Either reverse or reverse-complement (depending on "color") this + * DNA buffer in-place. + */ + void reverseComp(bool color = false) { + if(color) { + this->reverse(); + } else { + for(size_t i = 0; i < (this->len_ >> 1); i++) { + char tmp1 = (this->cs_[i] == 4 ? 4 : this->cs_[i] ^ 3); + char tmp2 = (this->cs_[this->len_-i-1] == 4 ? 4 : this->cs_[this->len_-i-1] ^ 3); + this->cs_[i] = tmp2; + this->cs_[this->len_-i-1] = tmp1; + } + // Do middle element iff there are an odd number + if((this->len_ & 1) != 0) { + char tmp = this->cs_[this->len_ >> 1]; + tmp = (tmp == 4 ? 4 : tmp ^ 3); + this->cs_[this->len_ >> 1] = tmp; + } + } + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + virtual void install( + const char* b, + bool chars = false, + bool colors = false) + { + if(chars) { + if(colors) { + installColors(b, strlen(b)); + } else { + installChars(b, strlen(b)); + } + } else { + install(b, strlen(b)); + } + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + virtual void install(const char* b, size_t sz) { + if(this->sz_ < sz) this->expandCopy((sz + S) * M); + memcpy(this->cs_, b, sz); +#ifndef NDEBUG + for(size_t i = 0; i < sz; i++) { + assert_range(0, 4, (int)this->cs_[i]); + } +#endif + this->len_ = sz; + } + + /** + * Copy buffer 'b' of ASCII DNA characters into normal DNA + * characters. + */ + virtual void installChars(const char* b, size_t sz) { + if(this->sz_ < sz) this->expandCopy((sz + S) * M); + for(size_t i = 0; i < sz; i++) { + assert_in(toupper(b[i]), "ACGTN-"); + this->cs_[i] = asc2dna[(int)b[i]]; + assert_range(0, 4, (int)this->cs_[i]); + } + this->len_ = sz; + } + + /** + * Copy buffer 'b' of ASCII color characters into normal DNA + * characters. + */ + virtual void installColors(const char* b, size_t sz) { + if(this->sz_ < sz) this->expandCopy((sz + S) * M); + for(size_t i = 0; i < sz; i++) { + assert_in(b[i], "0123."); + this->cs_[i] = asc2col[(int)b[i]]; + assert_range(0, 4, (int)this->cs_[i]); + } + this->len_ = sz; + } + + /** + * Copy C++ string of ASCII DNA characters into normal DNA + * characters. + */ + virtual void installChars(const std::basic_string& str) { + installChars(str.c_str(), str.length()); + } + + /** + * Copy C++ string of ASCII color characters into normal DNA + * characters. + */ + virtual void installColors(const std::basic_string& str) { + installColors(str.c_str(), str.length()); + } + + /** + * Set DNA character at index 'idx' to 'c'. + */ + void set(int c, size_t idx) { + assert_lt(idx, this->len_); + assert_range(0, 4, c); + this->cs_[idx] = c; + } + + /** + * Append DNA char c. + */ + void append(const char& c) { + if(this->sz_ < this->len_ + 1) { + this->expandCopy((this->len_ + 1 + S) * M); + } + assert_range(0, 4, (int)c); + this->cs_[this->len_++] = c; + } + + /** + * Set DNA character at index 'idx' to 'c'. + */ + void setChar(char c, size_t idx) { + assert_lt(idx, this->len_); + assert_in(toupper(c), "ACGTN"); + this->cs_[idx] = asc2dna[(int)c]; + } + + /** + * Append DNA character. + */ + void appendChar(char c) { + if(this->sz_ < this->len_ + 1) { + this->expandCopy((this->len_ + 1 + S) * M); + } + assert_in(toupper(c), "ACGTN"); + this->cs_[this->len_++] = asc2dna[(int)c]; + } + + /** + * Return DNA character corresponding to element 'idx'. + */ + char toChar(size_t idx) const { + assert_range(0, 4, (int)this->cs_[idx]); + return "ACGTN"[(int)this->cs_[idx]]; + } + + /** + * Retrieve constant version of element i. + */ + inline const char& operator[](size_t i) const { + return this->get(i); + } + + /** + * Retrieve constant version of element i. + */ + inline const char& get(size_t i) const { + assert_lt(i, this->len_); + assert_range(0, 4, (int)this->cs_[i]); + return this->cs_[i]; + } + + /** + * Return the ith character in the window defined by fw, color, + * depth and len. + */ + char windowGetDna( + size_t i, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = this->len_; + assert_lt(i, len); + assert_leq(len, this->len_ - depth); + if(fw) return this->cs_[depth+i]; + else return color ? this->cs_[depth+len-i-1] : + compDna(this->cs_[depth+len-i-1]); + } + + /** + * Fill the given DNA buffer with the substring specified by fw, + * color, depth and len. + */ + void windowGetDna( + SDnaStringExpandable& buf, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = this->len_; + assert_leq(len, this->len_ - depth); + for(size_t i = 0; i < len; i++) { + buf.append(fw ? this->cs_[depth+i] : + (color ? this->cs_[depth+len-i-1] : + compDna(this->cs_[depth+len-i-1]))); + } + } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + virtual const char* toZBuf() const { return this->toZBufXForm("ACGTN"); } +}; + +/** + * Encapsulates an expandable DNA string with characters encoded as + * char-sized masks. Encodes A, C, G, T, and all IUPAC, as well as the + * empty mask indicating "matches nothing." + */ +template +class SDnaMaskString : public SStringExpandable { +public: + + explicit SDnaMaskString() : SStringExpandable() { } + + /** + * Create an SStringFixed from another SStringFixed. + */ + SDnaMaskString(const SDnaMaskString& o) : + SStringExpandable(o) { } + + /** + * Create an SStringFixed from a C++ basic_string. + */ + explicit SDnaMaskString(const std::basic_string& str) : + SStringExpandable(str) { } + + /** + * Create an SStringFixed from an array and size. + */ + explicit SDnaMaskString(const char* b, size_t sz) : + SStringExpandable(b, sz) { } + + /** + * Create an SStringFixed from a zero-terminated string. + */ + explicit SDnaMaskString(const char* b, bool chars = false) : + SStringExpandable() + { + if(chars) { + installChars(b, strlen(b)); + } else { + install(b, strlen(b)); + } + } + + virtual ~SDnaMaskString() { } // C++ needs this + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reverse- + * complementing them in the process, assuming an encoding where + * 0=A, 1=C, 2=G, 3=T, 4=N. + */ + void installReverseComp(const char* b, size_t sz) { + while(this->sz_ < sz) { + this->expandNoCopy((sz + S) * M); + } + for(size_t i = 0; i < sz; i++) { + this->cs_[i] = maskcomp[(int)b[sz-i-1]]; + } + this->len_ = sz; + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string, reverse- + * complementing them in the process, assuming an encoding where + * 0=A, 1=C, 2=G, 3=T, 4=N. + */ + void installReverseComp(const SDnaMaskString& b) { + while(this->sz_ < b.len_) { + this->expandNoCopy((b.len_ + S) * M); + } + for(size_t i = 0; i < b.len_; i++) { + this->cs_[i] = maskcomp[(int)b.cs_[b.len_-i-1]]; + } + this->len_ = b.len_; + } + + /** + * Either reverse or reverse-complement (depending on "color") this + * DNA buffer in-place. + */ + void reverseComp(bool color = false) { + if(color) { + this->reverse(); + } else { + for(size_t i = 0; i < (this->len_ >> 1); i++) { + char tmp1 = maskcomp[(int)this->cs_[i]]; + char tmp2 = maskcomp[(int)this->cs_[this->len_-i-1]]; + this->cs_[i] = tmp2; + this->cs_[this->len_-i-1] = tmp1; + } + // Do middle element iff there are an odd number + if((this->len_ & 1) != 0) { + char tmp = this->cs_[this->len_ >> 1]; + tmp = maskcomp[(int)tmp]; + this->cs_[this->len_ >> 1] = tmp; + } + } + } + + /** + * Copy 'sz' bytes from buffer 'b' into this string. + */ + virtual void install(const char* b, size_t sz) { + while(this->sz_ < sz) { + this->expandNoCopy((sz + S) * M); + } + memcpy(this->cs_, b, sz); +#ifndef NDEBUG + for(size_t i = 0; i < sz; i++) { + assert_range((int)this->cs_[i], 0, 15); + } +#endif + this->len_ = sz; + } + + /** + * Copy buffer 'b' of ASCII DNA characters into DNA masks. + */ + virtual void installChars(const char* b, size_t sz) { + while(this->sz_ < sz) { + this->expandNoCopy((sz + S) * M); + } + for(size_t i = 0; i < sz; i++) { + assert_in(b[i], iupacs); + this->cs_[i] = asc2dnamask[(int)b[i]]; + assert_range((int)this->cs_[i], 0, 15); + } + this->len_ = sz; + } + + /** + * Copy C++ string of ASCII DNA characters into normal DNA + * characters. + */ + virtual void installChars(const std::basic_string& str) { + installChars(str.c_str(), str.length()); + } + + /** + * Set DNA character at index 'idx' to 'c'. + */ + void set(int c, size_t idx) { + assert_lt(idx, this->len_); + assert_range(c, 0, 15); + this->cs_[idx] = c; + } + + /** + * Append DNA char c. + */ + void append(const char& c) { + while(this->sz_ < this->len_+1) { + this->expandNoCopy((this->len_ + 1 + S) * M); + } + assert_range((int)c, 0, 15); + this->cs_[this->len_++] = c; + } + + /** + * Set DNA character at index 'idx' to 'c'. + */ + void setChar(char c, size_t idx) { + assert_lt(idx, this->len_); + assert_in(toupper(c), iupacs); + this->cs_[idx] = asc2dnamask[(int)c]; + } + + /** + * Append DNA character. + */ + void appendChar(char c) { + while(this->sz_ < this->len_+1) { + expandNoCopy((this->len_ + 1 + S) * M); + } + assert_in(toupper(c), iupacs); + this->cs_[this->len_++] = asc2dnamask[(int)c]; + } + + /** + * Return DNA character corresponding to element 'idx'. + */ + char toChar(size_t idx) const { + assert_range((int)this->cs_[idx], 0, 15); + return mask2iupac[(int)this->cs_[idx]]; + } + + /** + * Retrieve constant version of element i. + */ + const char& operator[](size_t i) const { + return this->get(i); + } + + /** + * Retrieve mutable version of element i. + */ + char& operator[](size_t i) { + return this->get(i); + } + + /** + * Retrieve constant version of element i. + */ + const char& get(size_t i) const { + assert_lt(i, this->len_); + assert_range((int)this->cs_[i], 0, 15); + return this->cs_[i]; + } + + /** + * Retrieve mutable version of element i. + */ + char& get(size_t i) { + assert_lt(i, this->len_); + assert_range((int)this->cs_[i], 0, 15); + return this->cs_[i]; + } + + /** + * Return the ith character in the window defined by fw, color, + * depth and len. + */ + char windowGetDna( + size_t i, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = this->len_; + assert_lt(i, len); + assert_leq(len, this->len_ - depth); + if(fw) return this->cs_[depth+i]; + else return color ? this->cs_[depth+len-i-1] : + maskcomp[this->cs_[depth+len-i-1]]; + } + + /** + * Fill the given DNA buffer with the substring specified by fw, + * color, depth and len. + */ + void windowGetDna( + SDnaStringFixed& buf, + bool fw, + bool color, + size_t depth = 0, + size_t len = 0) const + { + if(len == 0) len = this->len_; + assert_leq(len, this->len_ - depth); + for(size_t i = 0; i < len; i++) { + buf.append(fw ? this->cs_[depth+i] : + (color ? this->cs_[depth+len-i-1] : + maskcomp[this->cs_[depth+len-i-1]])); + } + } + + /** + * Sample a random substring of the given length from this DNA + * string and install the result in 'dst'. + */ + template + void randSubstr( + RandomSource& rnd, // pseudo-random generator + T& dst, // put sampled substring here + size_t len, // length of substring to extract + bool watson = true, // true -> possibly extract from Watson strand + bool crick = true) // true -> possibly extract from Crick strand + { + assert(watson || crick); + assert_geq(this->len_, len); + size_t poss = this->len_ - len + 1; + assert_gt(poss, 0); + uint32_t rndoff = (uint32_t)(rnd.nextU32() % poss); + bool fw; + if (watson && !crick) fw = true; + else if(!watson && crick) fw = false; + else { + fw = rnd.nextBool(); + } + if(fw) { + // Install Watson substring + for(size_t i = 0; i < len; i++) { + dst[i] = this->cs_[i + rndoff]; + } + } else { + // Install Crick substring + for(size_t i = 0; i < len; i++) { + dst[i] = maskcomp[(int)this->cs_[i + rndoff + (len - i - 1)]]; + } + } + } + + /** + * Put a terminator in the 'len_'th element and then return a + * pointer to the buffer. Useful for printing. + */ + virtual const char* toZBuf() const { return this->toZBufXForm(iupacs); } +}; + +typedef SStringExpandable BTString; +typedef SDnaStringExpandable<1024, 2> BTDnaString; +typedef SDnaMaskString<32, 2> BTDnaMask; + +#endif /* SSTRING_H_ */ diff --git a/str_util.h b/str_util.h new file mode 100644 index 0000000..48dae17 --- /dev/null +++ b/str_util.h @@ -0,0 +1,47 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef STR_UTIL_H_ +#define STR_UTIL_H_ + +#include + +/** + * Given a string, return an int hash for it. + */ +static inline int +hash_string(const std::string& s) { + int ret = 0; + int a = 63689; + int b = 378551; + for(size_t i = 0; i < s.length(); i++) { + ret = (ret * a) + (int)s[i]; + if(a == 0) { + a += b; + } else { + a *= b; + } + if(a == 0) { + a += b; + } + } + return ret; +} + +#endif /* STR_UTIL_H_ */ diff --git a/third_party/cpuid.h b/third_party/cpuid.h new file mode 100644 index 0000000..6a9688f --- /dev/null +++ b/third_party/cpuid.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 3, or (at your option) any + * later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Under Section 7 of GPL version 3, you are granted additional + * permissions described in the GCC Runtime Library Exception, version + * 3.1, as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License and + * a copy of the GCC Runtime Library Exception along with this program; + * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + * . + */ + +/* %ecx */ +#define bit_SSE3 (1 << 0) +#define bit_PCLMUL (1 << 1) +#define bit_SSSE3 (1 << 9) +#define bit_FMA (1 << 12) +#define bit_CMPXCHG16B (1 << 13) +#define bit_SSE4_1 (1 << 19) +#define bit_SSE4_2 (1 << 20) +#define bit_MOVBE (1 << 22) +#define bit_POPCNT (1 << 23) +#define bit_AES (1 << 25) +#define bit_XSAVE (1 << 26) +#define bit_OSXSAVE (1 << 27) +#define bit_AVX (1 << 28) +#define bit_F16C (1 << 29) +#define bit_RDRND (1 << 30) + +/* %edx */ +#define bit_CMPXCHG8B (1 << 8) +#define bit_CMOV (1 << 15) +#define bit_MMX (1 << 23) +#define bit_FXSAVE (1 << 24) +#define bit_SSE (1 << 25) +#define bit_SSE2 (1 << 26) + +/* Extended Features */ +/* %ecx */ +#define bit_LAHF_LM (1 << 0) +#define bit_ABM (1 << 5) +#define bit_SSE4a (1 << 6) +#define bit_XOP (1 << 11) +#define bit_LWP (1 << 15) +#define bit_FMA4 (1 << 16) +#define bit_TBM (1 << 21) + +/* %edx */ +#define bit_LM (1 << 29) +#define bit_3DNOWP (1 << 30) +#define bit_3DNOW (1 << 31) + +/* Extended Features (%eax == 7) */ +#define bit_FSGSBASE (1 << 0) +#define bit_BMI (1 << 3) + +#if defined(__i386__) && defined(__PIC__) +/* %ebx may be the PIC register. */ +#if __GNUC__ >= 3 +#define __cpuid(level, a, b, c, d) \ + __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchg{l}\t{%%}ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level)) + +#define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchg{l}\t{%%}ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +#else +/* Host GCCs older than 3.0 weren't supporting Intel asm syntax + nor alternatives in i386 code. */ +#define __cpuid(level, a, b, c, d) \ + __asm__ ("xchgl\t%%ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchgl\t%%ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level)) + +#define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("xchgl\t%%ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchgl\t%%ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +#endif +#else +#define __cpuid(level, a, b, c, d) \ + __asm__ ("cpuid\n\t" \ + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ + : "0" (level)) + +#define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("cpuid\n\t" \ + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +#endif + +/* Return highest supported input value for cpuid instruction. ext can + be either 0x0 or 0x8000000 to return highest supported value for + basic or extended cpuid information. Function returns 0 if cpuid + is not supported or whatever cpuid returns in eax register. If sig + pointer is non-null, then first four bytes of the signature + (as found in ebx register) are returned in location pointed by sig. */ + +static __inline unsigned int +__get_cpuid_max (unsigned int __ext, unsigned int *__sig) +{ + unsigned int __eax, __ebx, __ecx, __edx; + +#ifndef __x86_64__ +#if __GNUC__ >= 3 + /* See if we can use cpuid. On AMD64 we always can. */ + __asm__ ("pushf{l|d}\n\t" + "pushf{l|d}\n\t" + "pop{l}\t%0\n\t" + "mov{l}\t{%0, %1|%1, %0}\n\t" + "xor{l}\t{%2, %0|%0, %2}\n\t" + "push{l}\t%0\n\t" + "popf{l|d}\n\t" + "pushf{l|d}\n\t" + "pop{l}\t%0\n\t" + "popf{l|d}\n\t" + : "=&r" (__eax), "=&r" (__ebx) + : "i" (0x00200000)); +#else +/* Host GCCs older than 3.0 weren't supporting Intel asm syntax + nor alternatives in i386 code. */ + __asm__ ("pushfl\n\t" + "pushfl\n\t" + "popl\t%0\n\t" + "movl\t%0, %1\n\t" + "xorl\t%2, %0\n\t" + "pushl\t%0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl\t%0\n\t" + "popfl\n\t" + : "=&r" (__eax), "=&r" (__ebx) + : "i" (0x00200000)); +#endif + + if (!((__eax ^ __ebx) & 0x00200000)) + return 0; +#endif + + /* Host supports cpuid. Return highest supported cpuid input value. */ + __cpuid (__ext, __eax, __ebx, __ecx, __edx); + + if (__sig) + *__sig = __ebx; + + return __eax; +} + +/* Return cpuid data for requested cpuid level, as found in returned + eax, ebx, ecx and edx registers. The function checks if cpuid is + supported and returns 1 for valid cpuid information or 0 for + unsupported cpuid level. All pointers are required to be non-null. */ + +static __inline int +__get_cpuid (unsigned int __level, + unsigned int *__eax, unsigned int *__ebx, + unsigned int *__ecx, unsigned int *__edx) +{ + unsigned int __ext = __level & 0x80000000; + + if (__get_cpuid_max (__ext, 0) < __level) + return 0; + + __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx); + return 1; +} diff --git a/threading.h b/threading.h new file mode 100644 index 0000000..fca4086 --- /dev/null +++ b/threading.h @@ -0,0 +1,57 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef THREADING_H_ +#define THREADING_H_ + +#include +#include "tinythread.h" +#include "fast_mutex.h" + +#ifdef NO_SPINLOCK +# define MUTEX_T tthread::mutex +#else +# define MUTEX_T tthread::fast_mutex +#endif /* NO_SPINLOCK */ + + +/** + * Wrap a lock; obtain lock upon construction, release upon destruction. + */ +class ThreadSafe { +public: + ThreadSafe(MUTEX_T* ptr_mutex, bool locked = true) { + if(locked) { + this->ptr_mutex = ptr_mutex; + ptr_mutex->lock(); + } + else + this->ptr_mutex = NULL; + } + + ~ThreadSafe() { + if (ptr_mutex != NULL) + ptr_mutex->unlock(); + } + +private: + MUTEX_T *ptr_mutex; +}; + +#endif diff --git a/timer.h b/timer.h new file mode 100644 index 0000000..5d0c844 --- /dev/null +++ b/timer.h @@ -0,0 +1,87 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef TIMER_H_ +#define TIMER_H_ + +#include +#include +#include +#include + +using namespace std; + +/** + * Use time() call to keep track of elapsed time between creation and + * destruction. If verbose is true, Timer will print a message showing + * elapsed time to the given output stream upon destruction. + */ +class Timer { +public: + Timer(ostream& out = cout, const char *msg = "", bool verbose = true) : + _t(time(0)), _out(out), _msg(msg), _verbose(verbose) { } + + /// Optionally print message + ~Timer() { + if(_verbose) write(_out); + } + + /// Return elapsed time since Timer object was created + time_t elapsed() const { + return time(0) - _t; + } + + void write(ostream& out) { + time_t passed = elapsed(); + // Print the message supplied at construction time followed + // by time elapsed formatted HH:MM:SS + time_t hours = (passed / 60) / 60; + time_t minutes = (passed / 60) % 60; + time_t seconds = (passed % 60); + std::ostringstream oss; + oss << _msg << setfill ('0') << setw (2) << hours << ":" + << setfill ('0') << setw (2) << minutes << ":" + << setfill ('0') << setw (2) << seconds << endl; + out << oss.str().c_str(); + } + +private: + time_t _t; + ostream& _out; + const char *_msg; + bool _verbose; +}; + +static inline void logTime(std::ostream& os, bool nl = true) { + struct tm *current; + time_t now; + time(&now); + current = localtime(&now); + std::ostringstream oss; + oss << setfill('0') << setw(2) + << current->tm_hour << ":" + << setfill('0') << setw(2) + << current->tm_min << ":" + << setfill('0') << setw(2) + << current->tm_sec; + if(nl) oss << std::endl; + os << oss.str().c_str(); +} + +#endif /*TIMER_H_*/ diff --git a/tinythread.cpp b/tinythread.cpp new file mode 100644 index 0000000..9a4f9df --- /dev/null +++ b/tinythread.cpp @@ -0,0 +1,320 @@ +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include +#include "tinythread.h" + +#if defined(_TTHREAD_POSIX_) + #include + #include +#elif defined(_TTHREAD_WIN32_) + #include +#endif + + +namespace tthread { + +//------------------------------------------------------------------------------ +// condition_variable +//------------------------------------------------------------------------------ +// NOTE 1: The Win32 implementation of the condition_variable class is based on +// the corresponding implementation in GLFW, which in turn is based on a +// description by Douglas C. Schmidt and Irfan Pyarali: +// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html +// +// NOTE 2: Windows Vista actually has native support for condition variables +// (InitializeConditionVariable, WakeConditionVariable, etc), but we want to +// be portable with pre-Vista Windows versions, so TinyThread++ does not use +// Vista condition variables. +//------------------------------------------------------------------------------ + +#if defined(_TTHREAD_WIN32_) + #define _CONDITION_EVENT_ONE 0 + #define _CONDITION_EVENT_ALL 1 +#endif + +#if defined(_TTHREAD_WIN32_) +condition_variable::condition_variable() : mWaitersCount(0) +{ + mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); + mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); + InitializeCriticalSection(&mWaitersCountLock); +} +#endif + +#if defined(_TTHREAD_WIN32_) +condition_variable::~condition_variable() +{ + CloseHandle(mEvents[_CONDITION_EVENT_ONE]); + CloseHandle(mEvents[_CONDITION_EVENT_ALL]); + DeleteCriticalSection(&mWaitersCountLock); +} +#endif + +#if defined(_TTHREAD_WIN32_) +void condition_variable::_wait() +{ + // Wait for either event to become signaled due to notify_one() or + // notify_all() being called + int result = WaitForMultipleObjects(2, mEvents, FALSE, INFINITE); + + // Check if we are the last waiter + EnterCriticalSection(&mWaitersCountLock); + -- mWaitersCount; + bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && + (mWaitersCount == 0); + LeaveCriticalSection(&mWaitersCountLock); + + // If we are the last waiter to be notified to stop waiting, reset the event + if(lastWaiter) + ResetEvent(mEvents[_CONDITION_EVENT_ALL]); +} +#endif + +#if defined(_TTHREAD_WIN32_) +void condition_variable::notify_one() +{ + // Are there any waiters? + EnterCriticalSection(&mWaitersCountLock); + bool haveWaiters = (mWaitersCount > 0); + LeaveCriticalSection(&mWaitersCountLock); + + // If we have any waiting threads, send them a signal + if(haveWaiters) + SetEvent(mEvents[_CONDITION_EVENT_ONE]); +} +#endif + +#if defined(_TTHREAD_WIN32_) +void condition_variable::notify_all() +{ + // Are there any waiters? + EnterCriticalSection(&mWaitersCountLock); + bool haveWaiters = (mWaitersCount > 0); + LeaveCriticalSection(&mWaitersCountLock); + + // If we have any waiting threads, send them a signal + if(haveWaiters) + SetEvent(mEvents[_CONDITION_EVENT_ALL]); +} +#endif + + +//------------------------------------------------------------------------------ +// POSIX pthread_t to unique thread::id mapping logic. +// Note: Here we use a global thread safe std::map to convert instances of +// pthread_t to small thread identifier numbers (unique within one process). +// This method should be portable across different POSIX implementations. +//------------------------------------------------------------------------------ + +#if defined(_TTHREAD_POSIX_) +static thread::id _pthread_t_to_ID(const pthread_t &aHandle) +{ + static mutex idMapLock; + static std::map idMap; + static unsigned long int idCount(1); + + lock_guard guard(idMapLock); + if(idMap.find(aHandle) == idMap.end()) + idMap[aHandle] = idCount ++; + return thread::id(idMap[aHandle]); +} +#endif // _TTHREAD_POSIX_ + + +//------------------------------------------------------------------------------ +// thread +//------------------------------------------------------------------------------ + +/// Information to pass to the new thread (what to run). +struct _thread_start_info { + void (*mFunction)(void *); ///< Pointer to the function to be executed. + void * mArg; ///< Function argument for the thread function. + thread * mThread; ///< Pointer to the thread object. +}; + +// Thread wrapper function. +#if defined(_TTHREAD_WIN32_) +unsigned WINAPI thread::wrapper_function(void * aArg) +#elif defined(_TTHREAD_POSIX_) +void * thread::wrapper_function(void * aArg) +#endif +{ + // Get thread startup information + _thread_start_info * ti = (_thread_start_info *) aArg; + + try + { + // Call the actual client thread function + ti->mFunction(ti->mArg); + } + catch(...) + { + // Uncaught exceptions will terminate the application (default behavior + // according to C++11) + std::terminate(); + } + + // The thread is no longer executing + lock_guard guard(ti->mThread->mDataMutex); + ti->mThread->mNotAThread = true; + + // The thread is responsible for freeing the startup information + delete ti; + + return 0; +} + +thread::thread(void (*aFunction)(void *), void * aArg) +{ + // Serialize access to this thread structure + lock_guard guard(mDataMutex); + + // Fill out the thread startup information (passed to the thread wrapper, + // which will eventually free it) + _thread_start_info * ti = new _thread_start_info; + ti->mFunction = aFunction; + ti->mArg = aArg; + ti->mThread = this; + + // The thread is now alive + mNotAThread = false; + + // Create the thread +#if defined(_TTHREAD_WIN32_) + mHandle = (HANDLE) _beginthreadex(0, 0, wrapper_function, (void *) ti, 0, &mWin32ThreadID); +#elif defined(_TTHREAD_POSIX_) + int err = 0; + pthread_attr_t stackSizeAttribute; + size_t stackSize = 0; + + err = pthread_attr_init(&stackSizeAttribute); + if(err) throw "Error: pthread_attr_init"; + + err = pthread_attr_getstacksize(&stackSizeAttribute, &stackSize); + if(err) throw "Error: pthread_attr_getstacksize"; + + size_t REQUIRED_STACK_SIZE = 4 * 1024 * 1024; + if(stackSize < REQUIRED_STACK_SIZE) { + err = pthread_attr_setstacksize(&stackSizeAttribute, REQUIRED_STACK_SIZE); + if(err) throw "Error: pthread_attr_setstacksize"; + } + err = pthread_attr_getstacksize(&stackSizeAttribute, &stackSize); + + if(pthread_create(&mHandle, &stackSizeAttribute, wrapper_function, (void *) ti) != 0) + mHandle = 0; +#endif + + // Did we fail to create the thread? + if(!mHandle) + { + mNotAThread = true; + delete ti; + } +} + +thread::~thread() +{ + if(joinable()) + std::terminate(); +} + +void thread::join() +{ + if(joinable()) + { +#if defined(_TTHREAD_WIN32_) + WaitForSingleObject(mHandle, INFINITE); + CloseHandle(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_join(mHandle, NULL); +#endif + } +} + +bool thread::joinable() const +{ + mDataMutex.lock(); + bool result = !mNotAThread; + mDataMutex.unlock(); + return result; +} + +void thread::detach() +{ + mDataMutex.lock(); + if(!mNotAThread) + { +#if defined(_TTHREAD_WIN32_) + CloseHandle(mHandle); +#elif defined(_TTHREAD_POSIX_) + pthread_detach(mHandle); +#endif + mNotAThread = true; + } + mDataMutex.unlock(); +} + +thread::id thread::get_id() const +{ + if(!joinable()) + return id(); +#if defined(_TTHREAD_WIN32_) + return id((unsigned long int) mWin32ThreadID); +#elif defined(_TTHREAD_POSIX_) + return _pthread_t_to_ID(mHandle); +#endif +} + +unsigned thread::hardware_concurrency() +{ +#if defined(_TTHREAD_WIN32_) + SYSTEM_INFO si; + GetSystemInfo(&si); + return (int) si.dwNumberOfProcessors; +#elif defined(_SC_NPROCESSORS_ONLN) + return (int) sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_SC_NPROC_ONLN) + return (int) sysconf(_SC_NPROC_ONLN); +#else + // The standard requires this function to return zero if the number of + // hardware cores could not be determined. + return 0; +#endif +} + + +//------------------------------------------------------------------------------ +// this_thread +//------------------------------------------------------------------------------ + +thread::id this_thread::get_id() +{ +#if defined(_TTHREAD_WIN32_) + return thread::id((unsigned long int) GetCurrentThreadId()); +#elif defined(_TTHREAD_POSIX_) + return _pthread_t_to_ID(pthread_self()); +#endif +} + +} diff --git a/tinythread.h b/tinythread.h new file mode 100644 index 0000000..aed7b58 --- /dev/null +++ b/tinythread.h @@ -0,0 +1,714 @@ +/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2010-2012 Marcus Geelnard + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef _TINYTHREAD_H_ +#define _TINYTHREAD_H_ + +/// @file +/// @mainpage TinyThread++ API Reference +/// +/// @section intro_sec Introduction +/// TinyThread++ is a minimal, portable implementation of basic threading +/// classes for C++. +/// +/// They closely mimic the functionality and naming of the C++11 standard, and +/// should be easily replaceable with the corresponding std:: variants. +/// +/// @section port_sec Portability +/// The Win32 variant uses the native Win32 API for implementing the thread +/// classes, while for other systems, the POSIX threads API (pthread) is used. +/// +/// @section class_sec Classes +/// In order to mimic the threading API of the C++11 standard, subsets of +/// several classes are provided. The fundamental classes are: +/// @li tthread::thread +/// @li tthread::mutex +/// @li tthread::recursive_mutex +/// @li tthread::condition_variable +/// @li tthread::lock_guard +/// @li tthread::fast_mutex +/// +/// @section misc_sec Miscellaneous +/// The following special keywords are available: #thread_local. +/// +/// For more detailed information (including additional classes), browse the +/// different sections of this documentation. A good place to start is: +/// tinythread.h. + +// Which platform are we on? +#if !defined(_TTHREAD_PLATFORM_DEFINED_) + #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define _TTHREAD_WIN32_ + #else + #define _TTHREAD_POSIX_ + #endif + #define _TTHREAD_PLATFORM_DEFINED_ +#endif + +// Platform specific includes +#if defined(_TTHREAD_WIN32_) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif + #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif +#else + #include + #include + #include + #include +#endif + +// Generic includes +#include + +/// TinyThread++ version (major number). +#define TINYTHREAD_VERSION_MAJOR 1 +/// TinyThread++ version (minor number). +#define TINYTHREAD_VERSION_MINOR 1 +/// TinyThread++ version (full version). +#define TINYTHREAD_VERSION (TINYTHREAD_VERSION_MAJOR * 100 + TINYTHREAD_VERSION_MINOR) + +// Do we have a fully featured C++11 compiler? +#if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L)) + #define _TTHREAD_CPP11_ +#endif + +// ...at least partial C++11? +#if defined(_TTHREAD_CPP11_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) + #define _TTHREAD_CPP11_PARTIAL_ +#endif + +// Macro for disabling assignments of objects. +#ifdef _TTHREAD_CPP11_PARTIAL_ + #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ + name(const name&) = delete; \ + name& operator=(const name&) = delete; +#else + #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ + name(const name&); \ + name& operator=(const name&); +#endif + +/// @def thread_local +/// Thread local storage keyword. +/// A variable that is declared with the @c thread_local keyword makes the +/// value of the variable local to each thread (known as thread-local storage, +/// or TLS). Example usage: +/// @code +/// // This variable is local to each thread. +/// thread_local int variable; +/// @endcode +/// @note The @c thread_local keyword is a macro that maps to the corresponding +/// compiler directive (e.g. @c __declspec(thread)). While the C++11 standard +/// allows for non-trivial types (e.g. classes with constructors and +/// destructors) to be declared with the @c thread_local keyword, most pre-C++11 +/// compilers only allow for trivial types (e.g. @c int). So, to guarantee +/// portable code, only use trivial types for thread local storage. +/// @note This directive is currently not supported on Mac OS X (it will give +/// a compiler error), since compile-time TLS is not supported in the Mac OS X +/// executable format. Also, some older versions of MinGW (before GCC 4.x) do +/// not support this directive. +/// @hideinitializer + +#if !defined(_TTHREAD_CPP11_) && !defined(thread_local) + #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) + #define thread_local __thread + #else + #define thread_local __declspec(thread) + #endif +#endif + + +/// Main name space for TinyThread++. +/// This namespace is more or less equivalent to the @c std namespace for the +/// C++11 thread classes. For instance, the tthread::mutex class corresponds to +/// the std::mutex class. +namespace tthread { + +/// Mutex class. +/// This is a mutual exclusion object for synchronizing access to shared +/// memory areas for several threads. The mutex is non-recursive (i.e. a +/// program may deadlock if the thread that owns a mutex object calls lock() +/// on that object). +/// @see recursive_mutex +class mutex { + public: + /// Constructor. + mutex() +#if defined(_TTHREAD_WIN32_) + : mAlreadyLocked(false) +#endif + { +#if defined(_TTHREAD_WIN32_) + InitializeCriticalSection(&mHandle); +#else + pthread_mutex_init(&mHandle, NULL); +#endif + } + + /// Destructor. + ~mutex() + { +#if defined(_TTHREAD_WIN32_) + DeleteCriticalSection(&mHandle); +#else + pthread_mutex_destroy(&mHandle); +#endif + } + + /// Lock the mutex. + /// The method will block the calling thread until a lock on the mutex can + /// be obtained. The mutex remains locked until @c unlock() is called. + /// @see lock_guard + inline void lock() + { +#if defined(_TTHREAD_WIN32_) + EnterCriticalSection(&mHandle); + while(mAlreadyLocked) Sleep(1000); // Simulate deadlock... + mAlreadyLocked = true; +#else + pthread_mutex_lock(&mHandle); +#endif + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() + { +#if defined(_TTHREAD_WIN32_) + bool ret = (TryEnterCriticalSection(&mHandle) ? true : false); + if(ret && mAlreadyLocked) + { + LeaveCriticalSection(&mHandle); + ret = false; + } + return ret; +#else + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; +#endif + } + + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() + { +#if defined(_TTHREAD_WIN32_) + mAlreadyLocked = false; + LeaveCriticalSection(&mHandle); +#else + pthread_mutex_unlock(&mHandle); +#endif + } + + _TTHREAD_DISABLE_ASSIGNMENT(mutex) + + private: +#if defined(_TTHREAD_WIN32_) + CRITICAL_SECTION mHandle; + bool mAlreadyLocked; +#else + pthread_mutex_t mHandle; +#endif + + friend class condition_variable; +}; + +/// Recursive mutex class. +/// This is a mutual exclusion object for synchronizing access to shared +/// memory areas for several threads. The mutex is recursive (i.e. a thread +/// may lock the mutex several times, as long as it unlocks the mutex the same +/// number of times). +/// @see mutex +class recursive_mutex { + public: + /// Constructor. + recursive_mutex() + { +#if defined(_TTHREAD_WIN32_) + InitializeCriticalSection(&mHandle); +#else + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mHandle, &attr); +#endif + } + + /// Destructor. + ~recursive_mutex() + { +#if defined(_TTHREAD_WIN32_) + DeleteCriticalSection(&mHandle); +#else + pthread_mutex_destroy(&mHandle); +#endif + } + + /// Lock the mutex. + /// The method will block the calling thread until a lock on the mutex can + /// be obtained. The mutex remains locked until @c unlock() is called. + /// @see lock_guard + inline void lock() + { +#if defined(_TTHREAD_WIN32_) + EnterCriticalSection(&mHandle); +#else + pthread_mutex_lock(&mHandle); +#endif + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() + { +#if defined(_TTHREAD_WIN32_) + return TryEnterCriticalSection(&mHandle) ? true : false; +#else + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; +#endif + } + + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() + { +#if defined(_TTHREAD_WIN32_) + LeaveCriticalSection(&mHandle); +#else + pthread_mutex_unlock(&mHandle); +#endif + } + + _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex) + + private: +#if defined(_TTHREAD_WIN32_) + CRITICAL_SECTION mHandle; +#else + pthread_mutex_t mHandle; +#endif + + friend class condition_variable; +}; + +/// Lock guard class. +/// The constructor locks the mutex, and the destructor unlocks the mutex, so +/// the mutex will automatically be unlocked when the lock guard goes out of +/// scope. Example usage: +/// @code +/// mutex m; +/// int counter; +/// +/// void increment() +/// { +/// lock_guard guard(m); +/// ++ counter; +/// } +/// @endcode + +template +class lock_guard { + public: + typedef T mutex_type; + + lock_guard() : mMutex(0) {} + + /// The constructor locks the mutex. + explicit lock_guard(mutex_type &aMutex) + { + mMutex = &aMutex; + mMutex->lock(); + } + + /// The destructor unlocks the mutex. + ~lock_guard() + { + if(mMutex) + mMutex->unlock(); + } + + private: + mutex_type * mMutex; +}; + +/// Condition variable class. +/// This is a signalling object for synchronizing the execution flow for +/// several threads. Example usage: +/// @code +/// // Shared data and associated mutex and condition variable objects +/// int count; +/// mutex m; +/// condition_variable cond; +/// +/// // Wait for the counter to reach a certain number +/// void wait_counter(int targetCount) +/// { +/// lock_guard guard(m); +/// while(count < targetCount) +/// cond.wait(m); +/// } +/// +/// // Increment the counter, and notify waiting threads +/// void increment() +/// { +/// lock_guard guard(m); +/// ++ count; +/// cond.notify_all(); +/// } +/// @endcode +class condition_variable { + public: + /// Constructor. +#if defined(_TTHREAD_WIN32_) + condition_variable(); +#else + condition_variable() + { + pthread_cond_init(&mHandle, NULL); + } +#endif + + /// Destructor. +#if defined(_TTHREAD_WIN32_) + ~condition_variable(); +#else + ~condition_variable() + { + pthread_cond_destroy(&mHandle); + } +#endif + + /// Wait for the condition. + /// The function will block the calling thread until the condition variable + /// is woken by @c notify_one(), @c notify_all() or a spurious wake up. + /// @param[in] aMutex A mutex that will be unlocked when the wait operation + /// starts, an locked again as soon as the wait operation is finished. + template + inline void wait(_mutexT &aMutex) + { +#if defined(_TTHREAD_WIN32_) + // Increment number of waiters + EnterCriticalSection(&mWaitersCountLock); + ++ mWaitersCount; + LeaveCriticalSection(&mWaitersCountLock); + + // Release the mutex while waiting for the condition (will decrease + // the number of waiters when done)... + aMutex.unlock(); + _wait(); + aMutex.lock(); +#else + pthread_cond_wait(&mHandle, &aMutex.mHandle); +#endif + } + + /// Notify one thread that is waiting for the condition. + /// If at least one thread is blocked waiting for this condition variable, + /// one will be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. +#if defined(_TTHREAD_WIN32_) + void notify_one(); +#else + inline void notify_one() + { + pthread_cond_signal(&mHandle); + } +#endif + + /// Notify all threads that are waiting for the condition. + /// All threads that are blocked waiting for this condition variable will + /// be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. +#if defined(_TTHREAD_WIN32_) + void notify_all(); +#else + inline void notify_all() + { + pthread_cond_broadcast(&mHandle); + } +#endif + + _TTHREAD_DISABLE_ASSIGNMENT(condition_variable) + + private: +#if defined(_TTHREAD_WIN32_) + void _wait(); + HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs. + unsigned int mWaitersCount; ///< Count of the number of waiters. + CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount. +#else + pthread_cond_t mHandle; +#endif +}; + + +/// Thread class. +class thread { + public: +#if defined(_TTHREAD_WIN32_) + typedef HANDLE native_handle_type; +#else + typedef pthread_t native_handle_type; +#endif + + class id; + + /// Default constructor. + /// Construct a @c thread object without an associated thread of execution + /// (i.e. non-joinable). + thread() : mHandle(0), mNotAThread(true) +#if defined(_TTHREAD_WIN32_) + , mWin32ThreadID(0) +#endif + {} + + /// Thread starting constructor. + /// Construct a @c thread object with a new thread of execution. + /// @param[in] aFunction A function pointer to a function of type: + /// void fun(void * arg) + /// @param[in] aArg Argument to the thread function. + /// @note This constructor is not fully compatible with the standard C++ + /// thread class. It is more similar to the pthread_create() (POSIX) and + /// CreateThread() (Windows) functions. + thread(void (*aFunction)(void *), void * aArg); + + /// Destructor. + /// @note If the thread is joinable upon destruction, @c std::terminate() + /// will be called, which terminates the process. It is always wise to do + /// @c join() before deleting a thread object. + ~thread(); + + /// Wait for the thread to finish (join execution flows). + /// After calling @c join(), the thread object is no longer associated with + /// a thread of execution (i.e. it is not joinable, and you may not join + /// with it nor detach from it). + void join(); + + /// Check if the thread is joinable. + /// A thread object is joinable if it has an associated thread of execution. + bool joinable() const; + + /// Detach from the thread. + /// After calling @c detach(), the thread object is no longer assicated with + /// a thread of execution (i.e. it is not joinable). The thread continues + /// execution without the calling thread blocking, and when the thread + /// ends execution, any owned resources are released. + void detach(); + + /// Return the thread ID of a thread object. + id get_id() const; + + /// Get the native handle for this thread. + /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this + /// is a @c pthread_t. + inline native_handle_type native_handle() + { + return mHandle; + } + + /// Determine the number of threads which can possibly execute concurrently. + /// This function is useful for determining the optimal number of threads to + /// use for a task. + /// @return The number of hardware thread contexts in the system. + /// @note If this value is not defined, the function returns zero (0). + static unsigned hardware_concurrency(); + + _TTHREAD_DISABLE_ASSIGNMENT(thread) + + private: + native_handle_type mHandle; ///< Thread handle. + mutable mutex mDataMutex; ///< Serializer for access to the thread private data. + bool mNotAThread; ///< True if this object is not a thread of execution. +#if defined(_TTHREAD_WIN32_) + unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex). +#endif + + // This is the internal thread wrapper function. +#if defined(_TTHREAD_WIN32_) + static unsigned WINAPI wrapper_function(void * aArg); +#else + static void * wrapper_function(void * aArg); +#endif +}; + +/// Thread ID. +/// The thread ID is a unique identifier for each thread. +/// @see thread::get_id() +class thread::id { + public: + /// Default constructor. + /// The default constructed ID is that of thread without a thread of + /// execution. + id() : mId(0) {}; + + id(unsigned long int aId) : mId(aId) {}; + + id(const id& aId) : mId(aId.mId) {}; + + inline id & operator=(const id &aId) + { + mId = aId.mId; + return *this; + } + + inline friend bool operator==(const id &aId1, const id &aId2) + { + return (aId1.mId == aId2.mId); + } + + inline friend bool operator!=(const id &aId1, const id &aId2) + { + return (aId1.mId != aId2.mId); + } + + inline friend bool operator<=(const id &aId1, const id &aId2) + { + return (aId1.mId <= aId2.mId); + } + + inline friend bool operator<(const id &aId1, const id &aId2) + { + return (aId1.mId < aId2.mId); + } + + inline friend bool operator>=(const id &aId1, const id &aId2) + { + return (aId1.mId >= aId2.mId); + } + + inline friend bool operator>(const id &aId1, const id &aId2) + { + return (aId1.mId > aId2.mId); + } + + inline friend std::ostream& operator <<(std::ostream &os, const id &obj) + { + os << obj.mId; + return os; + } + + private: + unsigned long int mId; +}; + + +// Related to - minimal to be able to support chrono. +typedef long long __intmax_t; + +/// Minimal implementation of the @c ratio class. This class provides enough +/// functionality to implement some basic @c chrono classes. +template <__intmax_t N, __intmax_t D = 1> class ratio { + public: + static double _as_double() { return double(N) / double(D); } +}; + +/// Minimal implementation of the @c chrono namespace. +/// The @c chrono namespace provides types for specifying time intervals. +namespace chrono { + /// Duration template class. This class provides enough functionality to + /// implement @c this_thread::sleep_for(). + template > class duration { + private: + _Rep rep_; + public: + typedef _Rep rep; + typedef _Period period; + + /// Construct a duration object with the given duration. + template + explicit duration(const _Rep2& r) : rep_(r) {}; + + /// Return the value of the duration object. + rep count() const + { + return rep_; + } + }; + + // Standard duration types. + typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds. + typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds. + typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds. + typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds. + typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes. + typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours. +} + +/// The namespace @c this_thread provides methods for dealing with the +/// calling thread. +namespace this_thread { + /// Return the thread ID of the calling thread. + thread::id get_id(); + + /// Yield execution to another thread. + /// Offers the operating system the opportunity to schedule another thread + /// that is ready to run on the current processor. + inline void yield() + { +#if defined(_TTHREAD_WIN32_) + Sleep(0); +#else + sched_yield(); +#endif + } + + /// Blocks the calling thread for a period of time. + /// @param[in] aTime Minimum time to put the thread to sleep. + /// Example usage: + /// @code + /// // Sleep for 100 milliseconds + /// this_thread::sleep_for(chrono::milliseconds(100)); + /// @endcode + /// @note Supported duration types are: nanoseconds, microseconds, + /// milliseconds, seconds, minutes and hours. + template void sleep_for(const chrono::duration<_Rep, _Period>& aTime) + { +#if defined(_TTHREAD_WIN32_) + Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5)); +#else + usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5)); +#endif + } +} + +} + +// Define/macro cleanup +#undef _TTHREAD_DISABLE_ASSIGNMENT + +#endif // _TINYTHREAD_H_ diff --git a/tokenize.h b/tokenize.h new file mode 100644 index 0000000..a5e521c --- /dev/null +++ b/tokenize.h @@ -0,0 +1,62 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef TOKENIZE_H_ +#define TOKENIZE_H_ + +#include +#include +#include + +using namespace std; + +/** + * Split string s according to given delimiters. Mostly borrowed + * from C++ Programming HOWTO 7.3. + */ +template +static inline void tokenize( + const string& s, + const string& delims, + T& ss, + size_t max = std::numeric_limits::max()) +{ + //string::size_type lastPos = s.find_first_not_of(delims, 0); + string::size_type lastPos = 0; + string::size_type pos = s.find_first_of(delims, lastPos); + while (string::npos != pos || string::npos != lastPos) { + ss.push_back(s.substr(lastPos, pos - lastPos)); + lastPos = s.find_first_not_of(delims, pos); + pos = s.find_first_of(delims, lastPos); + if(ss.size() == (max - 1)) { + pos = string::npos; + } + } +} + +template +static inline void tokenize(const std::string& s, char delim, T& ss) { + std::string token; + std::istringstream iss(s); + while(getline(iss, token, delim)) { + ss.push_back(token); + } +} + +#endif /*TOKENIZE_H_*/ diff --git a/tp.h b/tp.h new file mode 100644 index 0000000..374950f --- /dev/null +++ b/tp.h @@ -0,0 +1,118 @@ +/* + * Copyright 2015, Daehwan Kim + * + * This file is part of HISAT 2. + * + * HISAT 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT 2. If not, see . + */ + +/* + * tp.h + * + */ + +#ifndef TP_H_ +#define TP_H_ + +#include +#include + +/** + * Encapsulates alignment policy for transcriptome + */ +class TranscriptomePolicy { + +public: + + TranscriptomePolicy() { reset(); } + + TranscriptomePolicy( + size_t minIntronLen, + size_t maxIntronLen, + uint32_t minAnchorLen = 7, + uint32_t minAnchorLen_noncan = 14, + bool no_spliced_alignment = false, + bool transcriptome_mapping_only = false, + bool transcriptome_assembly = false, + bool xs_only = false, + bool avoid_pseudogene = false) + { + init(minIntronLen, + maxIntronLen, + minAnchorLen, + minAnchorLen_noncan, + no_spliced_alignment, + transcriptome_mapping_only, + transcriptome_assembly, + xs_only, + avoid_pseudogene); + } + + /** + */ + void reset() { + init(false, false, false); + } + + /** + */ + void init( + size_t minIntronLen, + size_t maxIntronLen, + uint32_t minAnchorLen = 7, + uint32_t minAnchorLen_noncan = 14, + bool no_spliced_alignment = false, + bool transcriptome_mapping_only = false, + bool transcriptome_assembly = false, + bool xs_only = false, + bool avoid_pseudogene = false) + { + minIntronLen_ = minIntronLen; + maxIntronLen_ = maxIntronLen; + minAnchorLen_ = minAnchorLen; + minAnchorLen_noncan_ = minAnchorLen_noncan; + no_spliced_alignment_ = no_spliced_alignment; + transcriptome_mapping_only_ = transcriptome_mapping_only; + transcriptome_assembly_ = transcriptome_assembly; + xs_only_ = xs_only; + avoid_pseudogene_ = avoid_pseudogene; + } + + size_t minIntronLen() const { return minIntronLen_; } + size_t maxIntronLen() const { return maxIntronLen_; } + uint32_t minAnchorLen() const { return minAnchorLen_; } + uint32_t minAnchorLen_noncan() const { return minAnchorLen_noncan_; } + bool no_spliced_alignment() const { return no_spliced_alignment_; } + bool transcriptome_mapping_only() const { return transcriptome_mapping_only_; } + bool transcriptome_assembly() const { return transcriptome_assembly_; } + bool xs_only() const { return xs_only_; } + bool avoid_pseudogene() const { return avoid_pseudogene_; } + +private: + size_t minIntronLen_; + size_t maxIntronLen_; + + // Minimum anchor length required for canonical splice sites + uint32_t minAnchorLen_; + // Minimum anchor length required for non-canonical splice sites + uint32_t minAnchorLen_noncan_; + + bool no_spliced_alignment_; + bool transcriptome_mapping_only_; + bool transcriptome_assembly_; + bool xs_only_; + bool avoid_pseudogene_; +}; + +#endif /*ndef TP_H_*/ diff --git a/unique.cpp b/unique.cpp new file mode 100644 index 0000000..c470473 --- /dev/null +++ b/unique.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#include "unique.h" + +using namespace std; + +// There is no valid second-best alignment and the best alignment has a +// perfect score. +const TMapq unp_nosec_perf = 44; + +// There is no valid second-best alignment. We stratify the alignment +// score of the best alignment into 10 bins. +const TMapq unp_nosec[11] = { + 43, 42, 41, 36, 32, 27, 20, 11, 4, 1, 0 +}; + +// The best alignment has a perfect score, and we stratify the distance +// between best and second-best alignment scores into 10 bins. +const TMapq unp_sec_perf[11] = { + 2, 16, 23, 30, 31, 32, 34, 36, 38, 40, 42 +}; + +// The best alignment has a non-perfect score, and we stratify both by best +// alignment score (specifically, the maximum score minus the best "best") +// and by the distance between the best and second-best alignment scores +// ("difference"). Each is stratified into 10 bins. Each row is a +// difference (smaller elts = smaller differences) and each column is a +// best score (smaller elts = higher best alignment scores). +const TMapq unp_sec[11][11] = { + { 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0}, + { 20, 14, 7, 3, 2, 1, 0, 0, 0, 0, 0}, + { 20, 16, 10, 6, 3, 1, 0, 0, 0, 0, 0}, + { 20, 17, 13, 9, 3, 1, 1, 0, 0, 0, 0}, + { 21, 19, 15, 9, 5, 2, 2, 0, 0, 0, 0}, + { 22, 21, 16, 11, 10, 5, 0, 0, 0, 0, 0}, + { 23, 22, 19, 16, 11, 0, 0, 0, 0, 0, 0}, + { 24, 25, 21, 30, 0, 0, 0, 0, 0, 0, 0}, + { 30, 26, 29, 0, 0, 0, 0, 0, 0, 0, 0}, + { 30, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +// +// Paired mapping quality: +// + +// There is no valid second-best alignment and the best alignment has a +// perfect score. +const TMapq pair_nosec_perf = 44; diff --git a/unique.h b/unique.h new file mode 100644 index 0000000..187e88e --- /dev/null +++ b/unique.h @@ -0,0 +1,531 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +/* + * unique.h + * + * Encapsulates objects and routines for determining whether and to + * what extend the best alignment for a read is "unique." In the + * simplest scenario, uniqueness is determined by whether we found only + * one alignment. More complex scenarios might assign a uniqueness + * score based that is a function of (of a summarized version of): all + * the alignments found and their scores. + * + * Since mapping quality is related to uniqueness, objects and + * routings for calculating mapping quality are also included here. + */ + +#ifndef UNIQUE_H_ +#define UNIQUE_H_ + +#include +#include "aligner_result.h" +#include "simple_func.h" +#include "util.h" +#include "scoring.h" + +typedef int64_t TMapq; + +/** + * Class that returns yes-or-no answers to the question of whether a + */ +class Uniqueness { +public: + + /** + * Given an AlnSetSumm, determine if the best alignment is "unique" + * according to some definition. + */ + static bool bestIsUnique( + const AlnSetSumm& s, + const AlnFlags& flags, + bool mate1, + size_t rdlen, + size_t ordlen, + char *inps) + { + assert(!s.empty()); + return !VALID_AL_SCORE(s.secbest(mate1)); + } +}; + +/** + * Collection of routines for calculating mapping quality. + */ +class Mapq { + +public: + + virtual ~Mapq() { } + + virtual TMapq mapq( + const AlnSetSumm& s, + const AlnFlags& flags, + bool mate1, + size_t rdlen, + size_t ordlen, + char *inps) const = 0; +}; + +extern const TMapq unp_nosec_perf; +extern const TMapq unp_nosec[11]; +extern const TMapq unp_sec_perf[11]; +extern const TMapq unp_sec[11][11]; +extern const TMapq pair_nosec_perf; + +/** + * V3 of the MAPQ calculator + */ +class BowtieMapq3 : public Mapq { + +public: + + BowtieMapq3( + const SimpleFunc& scoreMin, + const Scoring& sc) : + scoreMin_(scoreMin), + sc_(sc) + { } + + virtual ~BowtieMapq3() { } + + /** + * Given an AlnSetSumm, return a mapping quality calculated. + */ + virtual TMapq mapq( + const AlnSetSumm& s, + const AlnFlags& flags, + bool mate1, + size_t rdlen, + size_t ordlen, + char *inps) // put string representation of inputs here + const + { + if(s.paired()) { + return pair_nosec_perf; + } else { + bool hasSecbest = VALID_AL_SCORE(s.secbest(mate1)); + if(!flags.canMax() && !s.exhausted(mate1) && !hasSecbest) { + return 255; + } + TAlScore scMax = (TAlScore)sc_.perfectScore(rdlen); + TAlScore scMin = scoreMin_.f((float)rdlen); + assert_geq(scMax, scMin); + TAlScore best = scMax - s.best(mate1).score(); // best score (lower=better) + size_t best_bin = (size_t)((double)best * (10.0 / (double)(scMax - scMin)) + 0.5); + assert_geq(best_bin, 0); + assert_lt(best_bin, 11); + if(hasSecbest) { + assert_geq(s.best(mate1).score(), s.secbest(mate1).score()); + size_t diff = s.best(mate1).score() - s.secbest(mate1).score(); + size_t diff_bin = (size_t)((double)diff * (10.0 / (double)(scMax - scMin)) + 0.5); + assert_geq(diff_bin, 0); + assert_lt(diff_bin, 11); + // A valid second-best alignment was found + if(best == scMax) { + // Best alignment has perfect score + return unp_sec_perf[best_bin]; + } else { + // Best alignment has less than perfect score + return unp_sec[diff_bin][best_bin]; + } + } else { + // No valid second-best alignment was found + if(best == scMax) { + // Best alignment has perfect score + return unp_nosec_perf; + } else { + // Best alignment has less than perfect score + return unp_nosec[best_bin]; + } + } + } + } + +protected: + + SimpleFunc scoreMin_; + const Scoring& sc_; +}; + +/** + * V2 of the MAPQ calculator + */ +class BowtieMapq2 : public Mapq { + +public: + + BowtieMapq2( + const SimpleFunc& scoreMin, + const Scoring& sc) : + scoreMin_(scoreMin), + sc_(sc) + { } + + virtual ~BowtieMapq2() { } + + /** + * Given an AlnSetSumm, return a mapping quality calculated. + */ + virtual TMapq mapq( + const AlnSetSumm& s, + const AlnFlags& flags, + bool mate1, + size_t rdlen, + size_t ordlen, + char *inps) // put string representation of inputs here + const + { + // Did the read have a second-best alignment? + bool hasSecbest = s.paired() ? + VALID_AL_SCORE(s.secbestPaired()) : + VALID_AL_SCORE(s.secbest(mate1)); + + // for hisat + bool equalSecbest = false; + if(hasSecbest) { + if(s.paired()) { + assert_geq(s.bestPaired(), s.secbestPaired()); + equalSecbest = s.bestPaired() == s.secbestPaired(); + } else { + assert_geq(s.best(mate1), s.secbest(mate1)); + equalSecbest = s.best(mate1) == s.secbest(mate1); + } + } + + // This corresponds to a scenario where we found one and only one + // alignment but didn't really look for a second one + if(!flags.canMax() && + !s.exhausted(mate1) && + (!hasSecbest || !equalSecbest)) { + return 60; + } + // scPer = score of a perfect match + TAlScore scPer = (TAlScore)sc_.perfectScore(rdlen); + if(s.paired()) { + scPer += (TAlScore)sc_.perfectScore(ordlen); + } + // scMin = score of a just barely valid match + TAlScore scMin = scoreMin_.f((float)rdlen); + if(s.paired()) { + scMin += scoreMin_.f((float)ordlen); + } + TAlScore secbest = scMin-1; + TAlScore diff = (scPer - scMin); // scores can vary by up to this much + TMapq ret = 0; + TAlScore best = s.paired() ? + s.bestPaired().score() : s.best(mate1).score(); + // best score but normalized so that 0 = worst valid score + TAlScore bestOver = best - scMin; + if(sc_.monotone) { + // End-to-end alignment + if(!hasSecbest) { + if (bestOver >= diff * (double)0.8f) ret = 42; + else if(bestOver >= diff * (double)0.7f) ret = 40; + else if(bestOver >= diff * (double)0.6f) ret = 24; + else if(bestOver >= diff * (double)0.5f) ret = 23; + else if(bestOver >= diff * (double)0.4f) ret = 8; + else if(bestOver >= diff * (double)0.3f) ret = 3; + else ret = 0; + } else { + secbest = s.paired() ? + s.secbestPaired().score() : s.secbest(mate1).score(); + TAlScore bestdiff = abs(abs(static_cast(best))-abs(static_cast(secbest))); + if(bestdiff >= diff * (double)0.9f) { + if(bestOver == diff) { + ret = 39; + } else { + ret = 33; + } + } else if(bestdiff >= diff * (double)0.8f) { + if(bestOver == diff) { + ret = 38; + } else { + ret = 27; + } + } else if(bestdiff >= diff * (double)0.7f) { + if(bestOver == diff) { + ret = 37; + } else { + ret = 26; + } + } else if(bestdiff >= diff * (double)0.6f) { + if(bestOver == diff) { + ret = 36; + } else { + ret = 22; + } + } else if(bestdiff >= diff * (double)0.5f) { + // Top third is still pretty good + if (bestOver == diff) { + ret = 35; + } else if(bestOver >= diff * (double)0.84f) { + ret = 25; + } else if(bestOver >= diff * (double)0.68f) { + ret = 16; + } else { + ret = 5; + } + } else if(bestdiff >= diff * (double)0.4f) { + // Top third is still pretty good + if (bestOver == diff) { + ret = 34; + } else if(bestOver >= diff * (double)0.84f) { + ret = 21; + } else if(bestOver >= diff * (double)0.68f) { + ret = 14; + } else { + ret = 4; + } + } else if(bestdiff >= diff * (double)0.3f) { + // Top third is still pretty good + if (bestOver == diff) { + ret = 32; + } else if(bestOver >= diff * (double)0.88f) { + ret = 18; + } else if(bestOver >= diff * (double)0.67f) { + ret = 15; + } else { + ret = 3; + } + } else if(bestdiff >= diff * (double)0.2f) { + // Top third is still pretty good + if (bestOver == diff) { + ret = 31; + } else if(bestOver >= diff * (double)0.88f) { + ret = 17; + } else if(bestOver >= diff * (double)0.67f) { + ret = 11; + } else { + ret = 0; + } + } else if(bestdiff >= diff * (double)0.1f) { + // Top third is still pretty good + if (bestOver == diff) { + ret = 30; + } else if(bestOver >= diff * (double)0.88f) { + ret = 12; + } else if(bestOver >= diff * (double)0.67f) { + ret = 7; + } else { + ret = 0; + } + } else if(bestdiff > 0) { + // Top third is still pretty good + if(bestOver >= diff * (double)0.67f) { + ret = 6; + } else { + ret = 2; + } + } else { + assert_eq(bestdiff, 0); + // Top third is still pretty good + if(bestOver >= diff * (double)0.67f) { + ret = 1; + } else { + ret = 0; + } + } + } + } else { + // Local alignment + if(!hasSecbest) { + if (bestOver >= diff * (double)0.8f) ret = 44; + else if(bestOver >= diff * (double)0.7f) ret = 42; + else if(bestOver >= diff * (double)0.6f) ret = 41; + else if(bestOver >= diff * (double)0.5f) ret = 36; + else if(bestOver >= diff * (double)0.4f) ret = 28; + else if(bestOver >= diff * (double)0.3f) ret = 24; + else ret = 22; + } else { + secbest = s.paired() ? + s.secbestPaired().score() : s.secbest(mate1).score(); + TAlScore bestdiff = abs(abs(static_cast(best))-abs(static_cast(secbest))); + if (bestdiff >= diff * (double)0.9f) ret = 40; + else if(bestdiff >= diff * (double)0.8f) ret = 39; + else if(bestdiff >= diff * (double)0.7f) ret = 38; + else if(bestdiff >= diff * (double)0.6f) ret = 37; + else if(bestdiff >= diff * (double)0.5f) { + if (bestOver == diff) ret = 35; + else if(bestOver >= diff * (double)0.50f) ret = 25; + else ret = 20; + } else if(bestdiff >= diff * (double)0.4f) { + if (bestOver == diff) ret = 34; + else if(bestOver >= diff * (double)0.50f) ret = 21; + else ret = 19; + } else if(bestdiff >= diff * (double)0.3f) { + if (bestOver == diff) ret = 33; + else if(bestOver >= diff * (double)0.5f) ret = 18; + else ret = 16; + } else if(bestdiff >= diff * (double)0.2f) { + if (bestOver == diff) ret = 32; + else if(bestOver >= diff * (double)0.5f) ret = 17; + else ret = 12; + } else if(bestdiff >= diff * (double)0.1f) { + if (bestOver == diff) ret = 31; + else if(bestOver >= diff * (double)0.5f) ret = 14; + else ret = 9; + } else if(bestdiff > 0) { + if(bestOver >= diff * (double)0.5f) ret = 11; + else ret = 2; + } else { + assert_eq(bestdiff, 0); + if(bestOver >= diff * (double)0.5f) ret = 1; + else ret = 0; + } + } + } + // Note: modifications to inps must be synchronized + //if(inps != NULL) { + // inps = itoa10(best, inps); + // *inps++ = ','; + // inps = itoa10(secbest, inps); + // *inps++ = ','; + // inps = itoa10(ret, inps); + //} + return ret; + } + +protected: + + SimpleFunc scoreMin_; + const Scoring& sc_; +}; + +/** + * TODO: Do BowtieMapq on a per-thread basis prior to the mutex'ed output + * function. + * + * topCoeff :: top_coeff + * botCoeff :: bot_coeff + * mx :: mapqMax + * horiz :: mapqHorizon (sort of) + * + * sc1 <- tab$sc1 + * sc2 <- tab$sc2 + * mapq <- rep(mx, length(sc1)) + * diff_top <- ifelse(sc1 != best & sc2 != best, abs(best - abs(pmax(sc1, sc2))), 0) + * mapq <- mapq - diff_top * top_coeff + * diff_bot <- ifelse(sc2 != horiz, abs(abs(sc2) - abs(horiz)), 0) + * mapq <- mapq - diff_bot * bot_coeff + * mapq <- round(pmax(0, pmin(mx, mapq))) + * tab$mapq <- mapq + */ +class BowtieMapq : public Mapq { + +public: + + BowtieMapq( + const SimpleFunc& scoreMin, + const Scoring& sc) : + scoreMin_(scoreMin), + sc_(sc) + { } + + virtual ~BowtieMapq() { } + + /** + * Given an AlnSetSumm, return a mapping quality calculated. + */ + virtual TMapq mapq( + const AlnSetSumm& s, + const AlnFlags& flags, + bool mate1, + size_t rdlen, + size_t ordlen, + char *inps) // put string representation of inputs here + const + { + bool hasSecbest = VALID_AL_SCORE(s.secbest(mate1)); + if(!flags.canMax() && !s.exhausted(mate1) && !hasSecbest) { + return 255; + } + TAlScore scPer = (TAlScore)sc_.perfectScore(rdlen); + TAlScore scMin = scoreMin_.f((float)rdlen); + TAlScore secbest = scMin-1; + TAlScore diff = (scPer - scMin); + float sixth_2 = (float)(scPer - diff * (double)0.1666f * 2); + float sixth_3 = (float)(scPer - diff * (double)0.1666f * 3); + TMapq ret = 0; + TAlScore best = s.best(mate1).score(); + if(!hasSecbest) { + // Top third? + if(best >= sixth_2) { + ret = 37; + } + // Otherwise in top half? + else if(best >= sixth_3) { + ret = 25; + } + // Otherwise has no second-best? + else { + ret = 10; + } + } else { + secbest = s.secbest(mate1).score(); + TAlScore bestdiff = abs(abs(static_cast(best))-abs(static_cast(secbest))); + if(bestdiff >= diff * 0.1666 * 5) { + ret = 6; + } else if(bestdiff >= diff * 0.1666 * 4) { + ret = 5; + } else if(bestdiff >= diff * 0.1666 * 3) { + ret = 4; + } else if(bestdiff >= diff * 0.1666 * 2) { + ret = 3; + } else if(bestdiff >= diff * 0.1666 * 1) { + ret = 2; + } else { + ret = 1; + } + } + // Note: modifications to inps must be synchronized + //if(inps != NULL) { + // inps = itoa10(best, inps); + // *inps++ = ','; + // inps = itoa10(secbest, inps); + // *inps++ = ','; + // inps = itoa10(ret, inps); + //} + return ret; + } + +protected: + + SimpleFunc scoreMin_; + const Scoring& sc_; +}; + +/** + * Create and return new MAPQ calculating object. + */ +static inline Mapq *new_mapq( + int version, + const SimpleFunc& scoreMin, + const Scoring& sc) +{ + if(version == 3) { + return new BowtieMapq3(scoreMin, sc); + } else if(version == 2) { + return new BowtieMapq2(scoreMin, sc); + } else { + return new BowtieMapq(scoreMin, sc); + } +} + +#endif /*ndef UNIQUE_H_*/ diff --git a/util.h b/util.h new file mode 100644 index 0000000..f9c792c --- /dev/null +++ b/util.h @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef UTIL_H_ +#define UTIL_H_ + +#include +#include + +/** + * C++ version char* style "itoa": + */ +template +char* itoa10(const T& value, char* result) { + // Check that base is valid + char* out = result; + T quotient = value; + if(std::numeric_limits::is_signed) { + if(quotient <= 0) quotient = 0-quotient; + } + // Now write each digit from most to least significant + do { + *out = "0123456789"[quotient % 10]; + ++out; + quotient /= 10; + } while (quotient > 0); + // Only apply negative sign for base 10 + if(std::numeric_limits::is_signed) { + // Avoid compiler warning in cases where T is unsigned + if (value <= 0 && value != 0) *out++ = '-'; + } + reverse( result, out ); + *out = 0; // terminator + return out; +} + +#endif /*ndef UTIL_H_*/ diff --git a/utility_3n.cpp b/utility_3n.cpp new file mode 100644 index 0000000..17d3782 --- /dev/null +++ b/utility_3n.cpp @@ -0,0 +1,80 @@ +/* + * Copyright 2021, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#include +#include "utility_3n.h" +#include "alphabet.h" + +void getConversion(char usrInputFrom, char usrInputTo, char& convertFrom, char& convertTo) { + if ((usrInputFrom == 'A' && usrInputTo == 'T') || + (usrInputFrom == 'A' && usrInputTo == 'C') || + (usrInputFrom == 'C' && usrInputTo == 'G') || + (usrInputFrom == 'C' && usrInputTo == 'T') || + (usrInputFrom == 'G' && usrInputTo == 'A') || + (usrInputFrom == 'T' && usrInputTo == 'G')) { + convertFrom = usrInputFrom; + convertTo = usrInputTo; + return; + } + if ((usrInputFrom == 'C' && usrInputTo == 'A') || + (usrInputFrom == 'G' && usrInputTo == 'C') || + (usrInputFrom == 'T' && usrInputTo == 'A') || + (usrInputFrom == 'T' && usrInputTo == 'C') || + (usrInputFrom == 'A' && usrInputTo == 'G') || + (usrInputFrom == 'G' && usrInputTo == 'T')) { + convertFrom = usrInputTo; + convertTo = usrInputFrom; + return; + } + cerr << "Un-identified --base-change type: " << usrInputFrom << "," << usrInputTo << endl; + throw 1; +} + +bool fileExist (string name) { + return ( access( name.c_str(), F_OK ) != -1 ); +} + +void ConvertMatrix3N:: convertMatrix() { + restoreNormal(); + for (int i = 0; i < 4; i++) { + char base = allBase[i]; + char lowerBase = allBaseLower[i]; + if (convertFrom == base) { + asc2dna[base] = charToInt(convertTo); + asc2dna[lowerBase] = charToInt(convertTo); + } else if (complement(convertFrom) == base) { + asc2dnacomp[base] = convertTo; + asc2dnacomp[lowerBase] = convertTo; + dnacomp[i] = charToInt(convertTo); + } + } +} + +void ConvertMatrix3N::restoreNormal() { + for (int i = 0; i < 4; i++) { + char base = allBase[i]; + char lowerBase = allBaseLower[i]; + asc2dna[base] = charToInt(base); + asc2dna[lowerBase] = charToInt(base); + asc2dnacomp[base] = complement(base); + asc2dnacomp[lowerBase] = complement(base); + dnacomp[i] = charToInt(complement(base)); + } +} + diff --git a/utility_3n.h b/utility_3n.h new file mode 100644 index 0000000..06f5533 --- /dev/null +++ b/utility_3n.h @@ -0,0 +1,113 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#ifndef HISAT2_UTILITY_3N_H +#define HISAT2_UTILITY_3N_H + +#include + + +using namespace std; + +/** + * this is the class to convert asc2dna, asc2dnacomp, and dnacomp matrix for hisat-3n conversion. + * always save the conversion as convertFrom and convertTo. + * this class is to convert matrix for hisat2-build with (--3N) or hisat2-repeat with (--3N). + * hisat2 with (--base-change C,T) will not use this class. + */ +class ConvertMatrix3N { + char convertFrom = 'A'; + char convertTo = 'A'; + string allBase = "ACGT"; + string allBaseLower = "acgt"; + + /** + * helper function to convert character to int presentation. + */ + int charToInt(char inputChar) { return allBase.find(inputChar); } + + /** + * return the complement nucleotide + */ + int complement(char inputChar) { return allBase[3-charToInt(inputChar)]; } + + /** + * convert asc2dna, asc2dnacomp, and dnacomp matrix according to convertFrom and convertTo variable. + * always restore the matrix to original (4 letter) matrix. + */ + void convertMatrix() ; +public: + ConvertMatrix3N(){ + + }; + + /** + * save the conversion information then convert the matrix. + */ + void convert(char from, char to) { + convertFrom = from; + convertTo = to; + convertMatrix(); + } + + /** + * change convertFrom and convertTO to it's complement nucleotide, then convert the matrix. + */ + void inverseConversion() { + convertFrom = complement(convertFrom); + convertTo = complement(convertTo); + convertMatrix(); + } + + /** + * restore the asc2dna, asc2dnacomp, and dnacomp matrix to original (4 letter). + * do not change the convertFrom and convertTO variable. + */ + void restoreNormal() ; + + /** + * convert the matrix according to the convertFrom and convertTo variable. + */ + void restoreConversion() { + convertMatrix(); + } +}; + +/** + * the simple data structure to store cigar information. + */ +class Cigar { + int len; + char label; +public: + Cigar() { } + + Cigar(int inputLen, char inputLabel): len(inputLen), label(inputLabel) { + } + + int& getLen() { return len; } + + char& getLabel() { return label; } +}; + +extern void getConversion(char usrInputFrom, char usrInputTo, char& convertFrom, char& convertTo); +extern bool fileExist (string name); + + +#endif //HISAT2_UTILITY_3N_H diff --git a/utility_3n_table.h b/utility_3n_table.h new file mode 100644 index 0000000..33a086e --- /dev/null +++ b/utility_3n_table.h @@ -0,0 +1,327 @@ +/* + * Copyright 2020, Yun (Leo) Zhang + * + * This file is part of HISAT-3N. + * + * HISAT-3N is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * HISAT-3N is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HISAT-3N. If not, see . + */ + +#ifndef UTILITY_3N_TABLE_H +#define UTILITY_3N_TABLE_H + +#include +#include +#include + +using namespace std; + +/** + * return complement of input base. + */ +char asc2dnacomp[] = { + /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'-', 0, 0, + /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 64 */ 0,'T','V','G','H', 0, 0,'C','D', 0, 0,'M', 0,'K','N', 0, + /* A B C D G H K M N */ + /* 80 */ 0, 0,'Y','S','A', 0,'B','W', 0,'R', 0, 0, 0, 0, 0, 0, + /* R S T V W Y */ + /* 96 */ 0,'T','V','G','H', 0, 0,'C','D', 0, 0,'M', 0,'K','N', 0, + /* a b c d g h k m n */ + /* 112 */ 0, 0,'Y','S','A', 0,'B','W', 0,'R', 0, 0, 0, 0, 0, 0, + /* r s t v w y */ + /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** + * the simple data structure to bind quality score and position (on reference) together. + */ +class PosQuality { +public: + int readPos; // 0-based + int refPos; // 0-based + char qual; + bool converted; + bool remove; + + PosQuality(int& inputPos) { + readPos = inputPos; + refPos = inputPos; + remove = true; + } + + void setQual (char& inputQual, bool inputConverted) { + qual = inputQual; + converted = inputConverted; + remove = false; + } +}; + +/** + * the base class for string we need to search. + */ +class string_search { +public: + int start; + string s; + int stringLen; + + void initialize() { + start = 0; + stringLen = 0; + s.clear(); + } + + void loadString(string intputString) { + s = intputString; + stringLen = s.size(); + start = 0; + } +}; + + +/** + * to store CIGAR string and search segments in it. + */ +class CIGAR : public string_search{ +public: + + bool getNextSegment(int& len, char& symbol) { + if (start == stringLen) { + return false; + } + len = 0; + int currentIndex = start; + while (true) { + if (isalpha(s[currentIndex])) { + len = stoi(s.substr(start, currentIndex-start)); + symbol = s[currentIndex]; + start = currentIndex+1; + return true; + } + currentIndex++; + } + } +}; + +/** + * to store MD tag and search segments in it. + */ +class MD_tag : public string_search { +public: + + bool getNextSegment(string& seg) { + if (start >= stringLen) { + return false; + } + seg.clear(); + int currentIndex = start; + bool deletion = false; + + while (true) { + if (currentIndex >= stringLen) { + start = currentIndex + 1; + return !seg.empty(); + } + if (seg.empty() && s[currentIndex] == '0') { + currentIndex++; + continue; + } + if (isalpha(s[currentIndex])) { + if (seg.empty()) { + seg = s[currentIndex]; + start = currentIndex+1; + return true; + } else { + if (deletion) { + seg += s[currentIndex]; + //currentIndex++; + } else { + start = currentIndex; + return true; + } + } + } else if (s[currentIndex] == '^') { + if (seg.empty()) { + seg = s[currentIndex]; + deletion = true; + } else { + start = currentIndex; + return true; + } + } else { // number + if (seg.empty()) { + seg = s[currentIndex]; + } else { + if (deletion || isalpha(seg.back())) { + start = currentIndex; + return true; + } else { + seg += s[currentIndex]; + } + } + } + currentIndex++; + } + } +}; + +/** + * simple safe queue + */ +template +class SafeQueue { +private: + mutex mutex_; + queue queue_; + + string getReadName(string* line){ + int startPosition = 0; + int endPosition; + + endPosition = line->find("\t", startPosition); + string readName = line->substr(startPosition, endPosition - startPosition); + return readName; + } + +public: + void pop() { + mutex_.lock(); + queue_.pop(); + mutex_.unlock(); + } + + T front() { + mutex_.lock(); + T value = queue_.front(); + mutex_.unlock(); + return value; + } + + int size() { + mutex_.lock(); + int s = queue_.size(); + mutex_.unlock(); + return s; + } + + /** + * return true if the queue is not empty and pop front and get value. + * return false if the queue is empty. + */ + bool popFront(T& value) { + mutex_.lock(); + bool isEmpty = queue_.empty(); + if (!isEmpty) { + value = queue_.front(); + queue_.pop(); + } + mutex_.unlock(); + return !isEmpty; + } + + void push(T value) { + mutex_.lock(); + queue_.push(value); + mutex_.unlock(); + } + + bool empty() { + mutex_.lock(); + bool check = queue_.empty(); + mutex_.unlock(); + return check; + } +}; + +/** + * store one chromosome and it's stream position + */ +class ChromosomeFilePosition { +public: + string chromosome; + streampos linePos; + ChromosomeFilePosition(string inputChromosome, streampos inputPos) { + chromosome = inputChromosome; + linePos = inputPos; + } + + bool operator < (const ChromosomeFilePosition& in) const{ + return chromosome < in.chromosome; + } +}; + +/** + * store all chromosome and it's stream position + */ +class ChromosomeFilePositions { +public: + vector pos; + + /** + * input the chromosome name and it's streamPos, if it is not in pos, add it. + */ + void append (string &chromosome, streampos& linePos) { + pos.push_back(ChromosomeFilePosition(chromosome, linePos)); + } + + /** + * make binary search on pos for target chromosome name + */ + int findChromosome(string &targetChromosome, int start, int end) { + if (start <= end) { + int middle = (start + end) / 2; + if (pos[middle].chromosome == targetChromosome) { + return middle; + } + if (pos[middle].chromosome > targetChromosome) { + return findChromosome(targetChromosome, start, middle-1); + } + return findChromosome(targetChromosome, middle+1, end); + } + else + { + // cannot find the chromosome! throw! + cerr << "Cannot find the chromosome: " << targetChromosome << " in reference file." << endl; + throw 1; + } + } + + /** + * given targetChromosome name, return its streampos + */ + streampos getChromosomePosInRefFile(string &targetChromosome) + { + int index = findChromosome(targetChromosome, 0, pos.size()-1); + assert(pos[index].chromosome == targetChromosome); + return pos[index].linePos; + } + + /** + * sort the pos by chromosome name + */ + void sort() + { + std::sort(pos.begin(), pos.end()); + } +}; +#endif //UTILITY_3N_TABLE_H diff --git a/word_io.h b/word_io.h new file mode 100644 index 0000000..54a5823 --- /dev/null +++ b/word_io.h @@ -0,0 +1,393 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef WORD_IO_H_ +#define WORD_IO_H_ + +#include +#include +#include +#include +#include "assert_helpers.h" +#include "endian_swap.h" + +/** + * Write a 32-bit unsigned to an output stream being careful to + * re-endianize if caller-requested endianness differs from current + * host. + */ +static inline void writeU32(std::ostream& out, uint32_t x, bool toBigEndian) { + uint32_t y = endianizeU32(x, toBigEndian); + out.write((const char*)&y, 4); +} + +/** + * Write a 32-bit unsigned to an output stream using the native + * endianness. + */ +static inline void writeU32(std::ostream& out, uint32_t x) { + out.write((const char*)&x, 4); +} + +/** + * Write a 32-bit signed int to an output stream being careful to + * re-endianize if caller-requested endianness differs from current + * host. + */ +static inline void writeI32(std::ostream& out, int32_t x, bool toBigEndian) { + int32_t y = endianizeI32(x, toBigEndian); + out.write((const char*)&y, 4); +} + +/** + * Write a 32-bit unsigned to an output stream using the native + * endianness. + */ +static inline void writeI32(std::ostream& out, int32_t x) { + out.write((const char*)&x, 4); +} + +/** + * Write a 16-bit unsigned to an output stream being careful to + * re-endianize if caller-requested endianness differs from current + * host. + */ +static inline void writeU16(std::ostream& out, uint16_t x, bool toBigEndian) { + uint16_t y = endianizeU16(x, toBigEndian); + out.write((const char*)&y, 2); +} + +/** + * Write a 16-bit unsigned to an output stream using the native + * endianness. + */ +static inline void writeU16(std::ostream& out, uint16_t x) { + out.write((const char*)&x, 2); +} + +/** + * Write a 16-bit signed int to an output stream being careful to + * re-endianize if caller-requested endianness differs from current + * host. + */ +static inline void writeI16(std::ostream& out, int16_t x, bool toBigEndian) { + int16_t y = endianizeI16(x, toBigEndian); + out.write((const char*)&y, 2); +} + +/** + * Write a 16-bit unsigned to an output stream using the native + * endianness. + */ +static inline void writeI16(std::ostream& out, int16_t x) { + out.write((const char*)&x, 2); +} + +/** + * Write a 8-bit unsigned to an output stream. + */ +static inline void writeU8(std::ostream& out, uint8_t x) { + out.write((const char*)&x, 1); +} + +/** + * Read a 32-bit unsigned from an input stream, inverting endianness + * if necessary. + */ +static inline uint32_t readU32(std::istream& in, bool swap) { + uint32_t x; + in.read((char *)&x, 4); + assert_eq(4, in.gcount()); + if(swap) { + return endianSwapU32(x); + } else { + return x; + } +} + +/** + * Read a 32-bit unsigned from a file descriptor, optionally inverting + * endianness. + */ +#ifdef BOWTIE_MM +static inline uint32_t readU32(int in, bool swap) { + uint32_t x; + if(read(in, (void *)&x, 4) != 4) { + assert(false); + } + if(swap) { + return endianSwapU32(x); + } else { + return x; + } +} +#endif + +/** + * Read a 32-bit unsigned from a FILE*, optionally inverting + * endianness. + */ +static inline uint32_t readU32(FILE* in, bool swap) { + uint32_t x; + if(fread((void *)&x, 1, 4, in) != 4) { + assert(false); + } + if(swap) { + return endianSwapU32(x); + } else { + return x; + } +} + + +/** + * Read a 32-bit signed from an input stream, inverting endianness + * if necessary. + */ +static inline int32_t readI32(std::istream& in, bool swap) { + int32_t x; + in.read((char *)&x, 4); + assert_eq(4, in.gcount()); + if(swap) { + return endianSwapI32(x); + } else { + return x; + } +} + +/** + * Read a 32-bit unsigned from a file descriptor, optionally inverting + * endianness. + */ +#ifdef BOWTIE_MM +static inline uint32_t readI32(int in, bool swap) { + int32_t x; + if(read(in, (void *)&x, 4) != 4) { + assert(false); + } + if(swap) { + return endianSwapI32(x); + } else { + return x; + } +} +#endif + +/** + * Read a 32-bit unsigned from a FILE*, optionally inverting + * endianness. + */ +static inline uint32_t readI32(FILE* in, bool swap) { + int32_t x; + if(fread((void *)&x, 1, 4, in) != 4) { + assert(false); + } + if(swap) { + return endianSwapI32(x); + } else { + return x; + } +} + + +/** + * Read a 16-bit unsigned from an input stream, inverting endianness + * if necessary. + */ +static inline uint16_t readU16(std::istream& in, bool swap) { + uint16_t x; + in.read((char *)&x, 2); + assert_eq(2, in.gcount()); + if(swap) { + return endianSwapU16(x); + } else { + return x; + } +} + +/** + * Read a 16-bit unsigned from a file descriptor, optionally inverting + * endianness. + */ +#ifdef BOWTIE_MM +static inline uint16_t readU16(int in, bool swap) { + uint16_t x; + if(read(in, (void *)&x, 2) != 2) { + assert(false); + } + if(swap) { + return endianSwapU16(x); + } else { + return x; + } +} +#endif + +/** + * Read a 16-bit unsigned from a FILE*, optionally inverting + * endianness. + */ +static inline uint16_t readU16(FILE* in, bool swap) { + uint16_t x; + if(fread((void *)&x, 1, 2, in) != 2) { + assert(false); + } + if(swap) { + return endianSwapU32(x); + } else { + return x; + } +} + + +/** + * Read a 16-bit signed from an input stream, inverting endianness + * if necessary. + */ +static inline int32_t readI16(std::istream& in, bool swap) { + int16_t x; + in.read((char *)&x, 2); + assert_eq(2, in.gcount()); + if(swap) { + return endianSwapI16(x); + } else { + return x; + } +} + +/** + * Read a 16-bit unsigned from a file descriptor, optionally inverting + * endianness. + */ +#ifdef BOWTIE_MM +static inline uint16_t readI16(int in, bool swap) { + int16_t x; + if(read(in, (void *)&x, 2) != 2) { + assert(false); + } + if(swap) { + return endianSwapI16(x); + } else { + return x; + } +} +#endif + +/** + * Read a 16-bit unsigned from a FILE*, optionally inverting + * endianness. + */ +static inline uint16_t readI16(FILE* in, bool swap) { + int16_t x; + if(fread((void *)&x, 1, 2, in) != 2) { + assert(false); + } + if(swap) { + return endianSwapI16(x); + } else { + return x; + } +} + +/** + * Read a 8-bit unsigned from an input stream + */ +static inline uint8_t readU8(std::istream& in) { + uint8_t x; + in.read((char *)&x, 1); + assert_eq(1, in.gcount()); + return x; +} + +template +void writeIndex(std::ostream& out, index_t x, bool toBigEndian) { + index_t y = endianizeIndex(x, toBigEndian); + out.write((const char*)&y, sizeof(index_t)); +} + +/** + * Read a unsigned from an input stream, inverting endianness + * if necessary. + */ +template +static inline index_t readIndex(std::istream& in, bool swap) { + index_t x; + in.read((char *)&x, sizeof(index_t)); + assert_eq(sizeof(index_t), in.gcount()); + if(swap) { + return endianSwapIndex(x); + } else { + return x; + } +} + +/** + * Read a unsigned from a file descriptor, optionally inverting + * endianness. + */ +#ifdef BOWTIE_MM +template +static inline index_t readIndex(int in, bool swap) { + index_t x; + if(read(in, (void *)&x, sizeof(index_t)) != sizeof(index_t)) { + assert(false); + } + if(swap) { + if(sizeof(index_t) == 8) { + assert(false); + return 0; + } else if(sizeof(index_t) == 4) { + return endianSwapU32(x); + } else { + assert_eq(sizeof(index_t), 2); + return endianSwapU16(x); + } + } else { + return x; + } +} +#endif + +/** + * Read a unsigned from a FILE*, optionally inverting + * endianness. + */ +template +static inline index_t readIndex(FILE* in, bool swap) { + index_t x; + if(fread((void *)&x, 1, sizeof(index_t), in) != sizeof(index_t)) { + assert(false); + } + if(swap) { + if(sizeof(index_t) == 8) { + assert(false); + return 0; + } else if(sizeof(index_t) == 4) { + return endianSwapU32(x); + } else { + assert_eq(sizeof(index_t), 2); + return endianSwapU16(x); + } + } else { + return x; + } +} + + +#endif /*WORD_IO_H_*/ diff --git a/zbox.h b/zbox.h new file mode 100644 index 0000000..6ef1456 --- /dev/null +++ b/zbox.h @@ -0,0 +1,97 @@ +/* + * Copyright 2011, Ben Langmead + * + * This file is part of Bowtie 2. + * + * Bowtie 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Bowtie 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bowtie 2. If not, see . + */ + +#ifndef ZBOX_H_ +#define ZBOX_H_ + +#include "btypes.h" + +/** + * Fill z with Z-box information for s. String z will not be resized + * and will only be filled up to its size cap. This is the linear-time + * algorithm from Gusfield. An optional sanity-check uses a naive + * algorithm to double-check results. + */ +template +void calcZ(const T& s, + TIndexOffU off, + EList& z, + bool verbose = false, + bool sanityCheck = false) +{ + size_t lCur = 0, rCur = 0; + size_t zlen = z.size(); + size_t slen = s.length(); + assert_gt(zlen, 0); + assert_eq(z[0], 0); + //assert_leq(zlen, slen); + for (size_t k = 1; k < zlen && k+off < slen; k++) { + assert_lt(lCur, k); + assert(z[lCur] == 0 || z[lCur] == rCur - lCur + 1); + if(k > rCur) { + // compare starting at k with prefix starting at 0 + size_t ki = k; + while(off+ki < s.length() && s[off+ki] == s[off+ki-k]) ki++; + z[k] = (TIndexOffU)(ki - k); + assert_lt(off+z[k], slen); + if(z[k] > 0) { + lCur = k; + rCur = k + z[k] - 1; + } + } else { + // position k is contained in a Z-box + size_t betaLen = rCur - k + 1; + size_t kPrime = k - lCur; + assert_eq(s[off+k], s[off+kPrime]); + if(z[kPrime] < betaLen) { + z[k] = z[kPrime]; + assert_lt(off+z[k], slen); + // lCur, rCur unchanged + } else if (z[kPrime] > 0) { + int q = 0; + while (off+q+rCur+1 < s.length() && s[off+q+rCur+1] == s[off+betaLen+q]) q++; + z[k] = (TIndexOffU)(betaLen + q); + assert_lt(off+z[k], slen); + rCur = rCur + q; + assert_geq(k, lCur); + lCur = k; + } else { + z[k] = 0; + assert_lt(off+z[k], slen); + // lCur, rCur unchanged + } + } + } +#ifndef NDEBUG + if(sanityCheck) { + // Recalculate Z-boxes using naive quadratic-time algorithm and + // compare to linear-time result + assert_eq(0, z[0]); + for(size_t i = 1; i < z.size(); i++) { + size_t j; + for(j = i; off+j < s.length(); j++) { + if(s[off+j] != s[off+j-i]) break; + } + assert_eq(j-i, z[i]); + } + } +#endif +} + +#endif /*ZBOX_H_*/

    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

    PjTY)n_Im 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­h%2j?phdhSbamFRhk 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